From 5a730d6ec3c8608bf4e3fed4ad86662aa56e9724 Mon Sep 17 00:00:00 2001 From: Sebastian Ramacher Date: Sun, 22 Sep 2019 23:19:10 +0200 Subject: [PATCH] New upstream version 24.0.1+dfsg1 --- .clang-format | 107 + .git-blame-ignore-revs | 1 + .travis.yml | 2 +- AUTHORS | 288 +- CI/before-deploy-osx.sh | 8 + CI/before-script-linux.sh | 9 +- CI/before-script-osx.sh | 5 + CI/check-format.sh | 11 + CI/install-dependencies-linux.sh | 13 +- CI/install-dependencies-osx.sh | 4 +- CI/install-qt-win.cmd | 2 +- CI/install-script-win.cmd | 12 +- CMakeLists.txt | 2 +- UI/CMakeLists.txt | 10 + UI/adv-audio-control.cpp | 177 +- UI/adv-audio-control.hpp | 44 +- UI/api-interface.cpp | 158 +- UI/audio-encoders.cpp | 77 +- UI/audio-encoders.hpp | 2 +- UI/auth-base.cpp | 3 +- UI/auth-base.hpp | 15 +- UI/auth-mixer.cpp | 114 +- UI/auth-mixer.hpp | 4 +- UI/auth-oauth.cpp | 81 +- UI/auth-oauth.hpp | 21 +- UI/auth-restream.cpp | 122 +- UI/auth-restream.hpp | 10 +- UI/auth-twitch.cpp | 154 +- UI/auth-twitch.hpp | 10 +- UI/clickable-label.hpp | 2 +- UI/crash-report.cpp | 8 +- UI/data/locale.ini | 5 +- UI/data/locale/af-ZA.ini | 22 +- UI/data/locale/ar-SA.ini | 16 +- UI/data/locale/az-AZ.ini | 150 + UI/data/locale/bg-BG.ini | 61 +- UI/data/locale/bn-BD.ini | 7 +- UI/data/locale/ca-ES.ini | 37 +- UI/data/locale/cs-CZ.ini | 45 +- UI/data/locale/da-DK.ini | 43 +- UI/data/locale/de-DE.ini | 325 +- UI/data/locale/el-GR.ini | 16 +- UI/data/locale/en-US.ini | 44 +- UI/data/locale/es-ES.ini | 53 +- UI/data/locale/et-EE.ini | 4 +- UI/data/locale/eu-ES.ini | 44 +- UI/data/locale/fa-IR.ini | 7 +- UI/data/locale/fi-FI.ini | 27 +- UI/data/locale/fil-PH.ini | 12 +- UI/data/locale/fr-FR.ini | 43 +- UI/data/locale/gd-GB.ini | 13 +- UI/data/locale/gl-ES.ini | 715 ++++- UI/data/locale/he-IL.ini | 63 +- UI/data/locale/hi-IN.ini | 61 + UI/data/locale/hr-HR.ini | 9 +- UI/data/locale/hu-HU.ini | 43 +- UI/data/locale/it-IT.ini | 51 +- UI/data/locale/ja-JP.ini | 49 +- UI/data/locale/ka-GE.ini | 56 +- UI/data/locale/ko-KR.ini | 41 +- UI/data/locale/ku-TR.ini | 3 +- UI/data/locale/lt-LT.ini | 4 +- UI/data/locale/mn-MN.ini | 3 +- UI/data/locale/ms-MY.ini | 4 +- UI/data/locale/nb-NO.ini | 21 +- UI/data/locale/nl-NL.ini | 40 +- UI/data/locale/nn-NO.ini | 8 +- UI/data/locale/pa-IN.ini | 3 +- UI/data/locale/pl-PL.ini | 41 +- UI/data/locale/pt-BR.ini | 49 +- UI/data/locale/pt-PT.ini | 95 +- UI/data/locale/ro-RO.ini | 137 +- UI/data/locale/ru-RU.ini | 70 +- UI/data/locale/sk-SK.ini | 61 +- UI/data/locale/sl-SI.ini | 783 ++++- UI/data/locale/sq-AL.ini | 3 +- UI/data/locale/sr-CS.ini | 13 +- UI/data/locale/sr-SP.ini | 13 +- UI/data/locale/sv-SE.ini | 133 +- UI/data/locale/ta-IN.ini | 5 +- UI/data/locale/th-TH.ini | 75 + UI/data/locale/tl-PH.ini | 12 +- UI/data/locale/tr-TR.ini | 39 +- UI/data/locale/uk-UA.ini | 52 +- UI/data/locale/ur-PK.ini | 3 +- UI/data/locale/vi-VN.ini | 38 +- UI/data/locale/zh-CN.ini | 53 +- UI/data/locale/zh-TW.ini | 127 +- UI/data/themes/Acri.qss | 26 +- UI/data/themes/Dark.qss | 38 +- UI/data/themes/Dark/media-pause.svg | 3 + UI/data/themes/Rachni.qss | 19 +- UI/data/themes/System.qss | 4 + UI/display-helpers.hpp | 22 +- UI/double-slider.cpp | 8 +- UI/double-slider.hpp | 4 +- UI/focus-list.hpp | 3 +- UI/forms/OBSBasic.ui | 198 +- UI/forms/OBSBasicSettings.ui | 102 +- UI/forms/OBSExtraBrowsers.ui | 98 + UI/forms/images/media-pause.svg | 3 + UI/forms/obs.qrc | 1 + .../decklink-output-ui/DecklinkOutputUI.cpp | 42 +- .../decklink-output-ui/DecklinkOutputUI.h | 2 +- .../decklink-output-ui/decklink-ui-main.cpp | 131 +- .../decklink-output-ui/forms/output.ui | 2 +- .../auto-scene-switcher-nix.cpp | 90 +- .../auto-scene-switcher-win.cpp | 2 +- .../frontend-tools/auto-scene-switcher.cpp | 84 +- .../frontend-tools/captions-handler.cpp | 31 +- .../frontend-tools/captions-handler.hpp | 28 +- .../frontend-tools/captions-mssapi-stream.cpp | 46 +- .../frontend-tools/captions-mssapi-stream.hpp | 31 +- .../frontend-tools/captions-mssapi.cpp | 32 +- .../frontend-tools/captions-mssapi.hpp | 12 +- .../frontend-tools/captions.cpp | 119 +- .../frontend-tools/data/locale/af-ZA.ini | 7 + .../frontend-tools/data/locale/ar-SA.ini | 1 + .../frontend-tools/data/locale/ca-ES.ini | 1 + .../frontend-tools/data/locale/cs-CZ.ini | 1 + .../frontend-tools/data/locale/da-DK.ini | 1 + .../frontend-tools/data/locale/de-DE.ini | 13 +- .../frontend-tools/data/locale/en-US.ini | 1 + .../frontend-tools/data/locale/es-ES.ini | 1 + .../frontend-tools/data/locale/eu-ES.ini | 1 + .../frontend-tools/data/locale/fr-FR.ini | 1 + .../frontend-tools/data/locale/gl-ES.ini | 43 + .../frontend-tools/data/locale/hu-HU.ini | 1 + .../frontend-tools/data/locale/it-IT.ini | 1 + .../frontend-tools/data/locale/ja-JP.ini | 1 + .../frontend-tools/data/locale/ka-GE.ini | 1 + .../frontend-tools/data/locale/ko-KR.ini | 1 + .../frontend-tools/data/locale/nl-NL.ini | 1 + .../frontend-tools/data/locale/pl-PL.ini | 1 + .../frontend-tools/data/locale/pt-BR.ini | 1 + .../frontend-tools/data/locale/ro-RO.ini | 4 +- .../frontend-tools/data/locale/ru-RU.ini | 1 + .../frontend-tools/data/locale/sl-SI.ini | 43 + .../frontend-tools/data/locale/sv-SE.ini | 1 + .../frontend-tools/data/locale/th-TH.ini | 5 + .../frontend-tools/data/locale/tr-TR.ini | 1 + .../frontend-tools/data/locale/uk-UA.ini | 1 + .../frontend-tools/data/locale/zh-CN.ini | 1 + .../frontend-tools/data/locale/zh-TW.ini | 1 + .../data/scripts/pause-scene.lua | 44 + .../frontend-tools/forms/output-timer.ui | 444 +-- .../frontend-tools/output-timer.cpp | 121 +- .../frontend-tools/output-timer.hpp | 4 + .../frontend-tools/scripts.cpp | 90 +- UI/horizontal-scroll-area.hpp | 3 +- UI/hotkey-edit.cpp | 168 +- UI/hotkey-edit.hpp | 28 +- UI/menu-button.hpp | 2 +- UI/obf.c | 11 +- UI/obs-app.cpp | 732 +++-- UI/obs-app.hpp | 99 +- UI/obs-frontend-api/obs-frontend-api.cpp | 180 +- UI/obs-frontend-api/obs-frontend-api.h | 44 +- UI/obs-frontend-api/obs-frontend-internal.hpp | 150 +- UI/platform-osx.mm | 20 +- UI/platform-windows.cpp | 50 +- UI/platform-x11.cpp | 4 +- UI/platform.hpp | 1 + UI/properties-view.cpp | 712 ++--- UI/properties-view.hpp | 62 +- UI/properties-view.moc.hpp | 34 +- UI/qt-display.cpp | 36 +- UI/qt-display.hpp | 10 +- UI/qt-wrappers.cpp | 120 +- UI/qt-wrappers.hpp | 63 +- UI/record-button.cpp | 19 + UI/record-button.hpp | 12 + UI/remote-text.cpp | 64 +- UI/remote-text.hpp | 54 +- UI/slider-absoluteset-style.cpp | 15 +- UI/slider-absoluteset-style.hpp | 12 +- UI/slider-ignorewheel.cpp | 2 +- UI/slider-ignorewheel.hpp | 3 +- UI/source-label.cpp | 6 +- UI/source-label.hpp | 11 +- UI/source-tree.cpp | 315 +- UI/source-tree.hpp | 25 +- UI/sparkle-updater.mm | 25 +- UI/vertical-scroll-area.hpp | 3 +- UI/visibility-item-widget.cpp | 89 +- UI/visibility-item-widget.hpp | 6 +- UI/volume-control.cpp | 400 +-- UI/volume-control.hpp | 158 +- UI/win-update/update-window.cpp | 7 +- UI/win-update/update-window.hpp | 6 +- UI/win-update/updater/hash.cpp | 8 +- UI/win-update/updater/http.cpp | 209 +- UI/win-update/updater/patch.cpp | 65 +- UI/win-update/updater/resource.h | 20 +- UI/win-update/updater/updater.cpp | 474 ++- UI/win-update/updater/updater.hpp | 77 +- UI/win-update/win-update-helpers.hpp | 35 +- UI/win-update/win-update.cpp | 282 +- UI/window-basic-about.cpp | 39 +- UI/window-basic-adv-audio.cpp | 40 +- UI/window-basic-adv-audio.hpp | 2 +- UI/window-basic-auto-config-test.cpp | 329 +- UI/window-basic-auto-config.cpp | 227 +- UI/window-basic-auto-config.hpp | 14 +- UI/window-basic-filters.cpp | 314 +- UI/window-basic-filters.hpp | 4 +- UI/window-basic-interaction.cpp | 101 +- UI/window-basic-interaction.hpp | 15 +- UI/window-basic-main-browser.cpp | 24 +- UI/window-basic-main-dropfiles.cpp | 82 +- UI/window-basic-main-outputs.cpp | 748 ++--- UI/window-basic-main-outputs.hpp | 50 +- UI/window-basic-main-profiles.cpp | 210 +- UI/window-basic-main-scene-collections.cpp | 151 +- UI/window-basic-main-transitions.cpp | 310 +- UI/window-basic-main.cpp | 2811 +++++++++-------- UI/window-basic-main.hpp | 256 +- UI/window-basic-preview.cpp | 803 +++-- UI/window-basic-preview.hpp | 109 +- UI/window-basic-properties.cpp | 170 +- UI/window-basic-properties.hpp | 27 +- UI/window-basic-settings-stream.cpp | 105 +- UI/window-basic-settings.cpp | 2033 ++++++------ UI/window-basic-settings.hpp | 105 +- UI/window-basic-source-select.cpp | 80 +- UI/window-basic-stats.cpp | 162 +- UI/window-basic-status-bar.cpp | 143 +- UI/window-basic-status-bar.hpp | 2 +- UI/window-basic-transform.cpp | 140 +- UI/window-basic-transform.hpp | 16 +- UI/window-dock-browser.cpp | 20 + UI/window-dock-browser.hpp | 23 + UI/window-dock.cpp | 10 +- UI/window-extra-browsers.cpp | 562 ++++ UI/window-extra-browsers.hpp | 95 + UI/window-log-reply.cpp | 3 +- UI/window-main.hpp | 8 +- UI/window-namedialog.cpp | 12 +- UI/window-namedialog.hpp | 6 +- UI/window-projector.cpp | 275 +- UI/window-projector.hpp | 38 +- UI/window-remux.cpp | 347 +- UI/window-remux.hpp | 44 +- appveyor.yml | 6 +- azure-pipelines.yml | 4 +- deps/file-updater/file-updater/file-updater.c | 90 +- deps/file-updater/file-updater/file-updater.h | 23 +- deps/glad/.clang-format | 3 + deps/ipc-util/ipc-util/pipe-windows.c | 40 +- deps/ipc-util/ipc-util/pipe-windows.h | 20 +- deps/ipc-util/ipc-util/pipe.h | 4 +- deps/json11/.clang-format | 3 + deps/libff/libff/ff-audio-decoder.c | 39 +- deps/libff/libff/ff-callbacks.c | 9 +- deps/libff/libff/ff-callbacks.h | 10 +- deps/libff/libff/ff-circular-queue.c | 7 +- deps/libff/libff/ff-circular-queue.h | 2 +- deps/libff/libff/ff-clock.c | 23 +- deps/libff/libff/ff-clock.h | 4 +- deps/libff/libff/ff-decoder.c | 79 +- deps/libff/libff/ff-decoder.h | 19 +- deps/libff/libff/ff-demuxer.c | 148 +- deps/libff/libff/ff-demuxer.h | 17 +- deps/libff/libff/ff-packet-queue.c | 5 +- deps/libff/libff/ff-packet-queue.h | 6 +- deps/libff/libff/ff-timer.c | 22 +- deps/libff/libff/ff-timer.h | 4 +- deps/libff/libff/ff-util.c | 115 +- deps/libff/libff/ff-util.h | 26 +- deps/libff/libff/ff-video-decoder.c | 31 +- deps/media-playback/CMakeLists.txt | 1 + .../media-playback/closest-format.h | 9 + deps/media-playback/media-playback/decode.c | 235 +- deps/media-playback/media-playback/decode.h | 40 +- deps/media-playback/media-playback/media.c | 174 +- deps/obs-scripting/obs-scripting-callback.h | 18 +- deps/obs-scripting/obs-scripting-internal.h | 5 +- deps/obs-scripting/obs-scripting-logging.c | 20 +- .../obs-scripting-lua-frontend.c | 24 +- deps/obs-scripting/obs-scripting-lua-source.c | 229 +- deps/obs-scripting/obs-scripting-lua.c | 169 +- deps/obs-scripting/obs-scripting-lua.h | 87 +- .../obs-scripting-python-frontend.c | 20 +- .../obs-scripting-python-import.c | 16 +- .../obs-scripting-python-import.h | 201 +- deps/obs-scripting/obs-scripting-python.c | 266 +- deps/obs-scripting/obs-scripting-python.h | 75 +- deps/obs-scripting/obs-scripting.c | 21 +- deps/obs-scripting/obs-scripting.h | 11 +- deps/obs-scripting/obslua/CMakeLists.txt | 13 +- deps/obs-scripting/obspython/CMakeLists.txt | 13 +- deps/w32-pthreads/.clang-format | 3 + docs/sphinx/reference-frontend-api.rst | 24 + docs/sphinx/reference-outputs.rst | 43 +- docs/sphinx/reference-scenes.rst | 11 + formatcode.sh | 31 + libobs-d3d11/d3d11-duplicator.cpp | 64 +- libobs-d3d11/d3d11-indexbuffer.cpp | 30 +- libobs-d3d11/d3d11-rebuild.cpp | 157 +- libobs-d3d11/d3d11-samplerstate.cpp | 38 +- libobs-d3d11/d3d11-shader.cpp | 130 +- libobs-d3d11/d3d11-shaderprocessor.cpp | 80 +- libobs-d3d11/d3d11-shaderprocessor.hpp | 8 +- libobs-d3d11/d3d11-stagesurf.cpp | 52 +- libobs-d3d11/d3d11-subsystem.cpp | 1027 +++--- libobs-d3d11/d3d11-subsystem.hpp | 674 ++-- libobs-d3d11/d3d11-texture2d.cpp | 166 +- libobs-d3d11/d3d11-vertexbuffer.cpp | 65 +- libobs-d3d11/d3d11-zstencilbuffer.cpp | 34 +- libobs-opengl/gl-cocoa.m | 124 +- libobs-opengl/gl-helpers.c | 51 +- libobs-opengl/gl-helpers.h | 74 +- libobs-opengl/gl-indexbuffer.c | 25 +- libobs-opengl/gl-shader.c | 210 +- libobs-opengl/gl-shaderparser.c | 211 +- libobs-opengl/gl-shaderparser.h | 28 +- libobs-opengl/gl-stagesurf.c | 41 +- libobs-opengl/gl-subsystem.c | 464 ++- libobs-opengl/gl-subsystem.h | 580 ++-- libobs-opengl/gl-texture2d.c | 92 +- libobs-opengl/gl-texturecube.c | 52 +- libobs-opengl/gl-vertexbuffer.c | 75 +- libobs-opengl/gl-windows.c | 120 +- libobs-opengl/gl-x11.c | 176 +- libobs-opengl/gl-zstencil.c | 24 +- libobs/CMakeLists.txt | 2 +- .../osx/coreaudio-enum-devices.c | 60 +- .../audio-monitoring/osx/coreaudio-output.c | 107 +- libobs/audio-monitoring/osx/mac-helpers.h | 6 +- .../pulse/pulseaudio-enum-devices.c | 9 +- .../pulse/pulseaudio-output.c | 210 +- .../pulse/pulseaudio-wrapper.c | 50 +- .../pulse/pulseaudio-wrapper.h | 13 +- .../win32/wasapi-enum-devices.c | 39 +- libobs/audio-monitoring/win32/wasapi-output.c | 191 +- libobs/audio-monitoring/win32/wasapi-output.h | 16 +- libobs/callback/calldata.c | 31 +- libobs/callback/calldata.h | 56 +- libobs/callback/decl.c | 41 +- libobs/callback/decl.h | 10 +- libobs/callback/proc.c | 22 +- libobs/callback/proc.h | 6 +- libobs/callback/signal.c | 79 +- libobs/callback/signal.h | 25 +- libobs/data/area.effect | 154 +- libobs/data/bicubic_scale.effect | 166 +- libobs/data/bilinear_lowres_scale.effect | 49 +- libobs/data/default.effect | 17 - libobs/data/format_conversion.effect | 727 +++-- libobs/data/lanczos_scale.effect | 214 +- libobs/graphics/axisang.c | 6 +- libobs/graphics/axisang.h | 6 +- libobs/graphics/bounds.c | 65 +- libobs/graphics/bounds.h | 65 +- libobs/graphics/device-exports.h | 144 +- libobs/graphics/effect-parser.c | 575 ++-- libobs/graphics/effect-parser.h | 59 +- libobs/graphics/effect.c | 105 +- libobs/graphics/effect.h | 13 +- libobs/graphics/graphics-ffmpeg.c | 113 +- libobs/graphics/graphics-imports.c | 36 +- libobs/graphics/graphics-internal.h | 303 +- libobs/graphics/graphics-magick.c | 37 +- libobs/graphics/graphics.c | 619 ++-- libobs/graphics/graphics.h | 464 +-- libobs/graphics/image-file.c | 75 +- libobs/graphics/image-file.h | 4 +- libobs/graphics/input.h | 228 +- libobs/graphics/libnsgif/.clang-format | 3 + libobs/graphics/math-defs.h | 16 +- libobs/graphics/math-extra.c | 39 +- libobs/graphics/math-extra.h | 10 +- libobs/graphics/matrix3.c | 17 +- libobs/graphics/matrix3.h | 28 +- libobs/graphics/matrix4.c | 65 +- libobs/graphics/matrix4.h | 35 +- libobs/graphics/plane.c | 26 +- libobs/graphics/plane.h | 36 +- libobs/graphics/quat.c | 66 +- libobs/graphics/quat.h | 44 +- libobs/graphics/shader-parser.c | 150 +- libobs/graphics/shader-parser.h | 75 +- libobs/graphics/texture-render.c | 22 +- libobs/graphics/vec2.h | 52 +- libobs/graphics/vec3.c | 8 +- libobs/graphics/vec3.h | 50 +- libobs/graphics/vec4.c | 2 +- libobs/graphics/vec4.h | 66 +- libobs/libobs.pc.in | 6 +- libobs/media-io/audio-io.c | 131 +- libobs/media-io/audio-io.h | 109 +- libobs/media-io/audio-resampler-ffmpeg.c | 144 +- libobs/media-io/audio-resampler.h | 15 +- libobs/media-io/format-conversion.c | 300 +- libobs/media-io/format-conversion.h | 48 +- libobs/media-io/frame-rate.h | 12 +- libobs/media-io/media-remux.c | 59 +- libobs/media-io/media-remux.h | 8 +- libobs/media-io/video-fourcc.c | 42 +- libobs/media-io/video-frame.c | 145 +- libobs/media-io/video-frame.h | 15 +- libobs/media-io/video-io.c | 154 +- libobs/media-io/video-io.h | 133 +- libobs/media-io/video-matrices.c | 154 +- libobs/media-io/video-scaler-ffmpeg.c | 137 +- libobs/media-io/video-scaler.h | 17 +- libobs/obs-audio-controls.c | 308 +- libobs/obs-audio-controls.h | 28 +- libobs/obs-audio.c | 138 +- libobs/obs-avc.c | 65 +- libobs/obs-avc.h | 45 +- libobs/obs-cocoa.c | 1702 ++++++---- libobs/obs-config.h | 39 +- libobs/obs-data.c | 562 ++-- libobs/obs-data.h | 217 +- libobs/obs-defs.h | 40 +- libobs/obs-display.c | 42 +- libobs/obs-encoder.c | 530 ++-- libobs/obs-encoder.h | 53 +- libobs/obs-ffmpeg-compat.h | 16 +- libobs/obs-hotkey-name-map.c | 57 +- libobs/obs-hotkey.c | 468 +-- libobs/obs-hotkey.h | 162 +- libobs/obs-hotkeys.h | 1 - libobs/obs-interaction.h | 44 +- libobs/obs-internal.h | 1018 +++--- libobs/obs-module.c | 242 +- libobs/obs-module.h | 69 +- libobs/obs-nix.c | 1044 +++--- libobs/obs-output-delay.c | 34 +- libobs/obs-output.c | 834 +++-- libobs/obs-output.h | 17 +- libobs/obs-properties.c | 517 +-- libobs/obs-properties.h | 262 +- libobs/obs-scene.c | 736 ++--- libobs/obs-scene.h | 82 +- libobs/obs-service.c | 103 +- libobs/obs-service.h | 6 +- libobs/obs-source-deinterlace.c | 198 +- libobs/obs-source-transition.c | 190 +- libobs/obs-source.c | 1853 ++++++----- libobs/obs-source.h | 78 +- libobs/obs-ui.h | 11 +- libobs/obs-video-gpu-encode.c | 57 +- libobs/obs-video.c | 680 ++-- libobs/obs-view.c | 23 +- libobs/obs-win-crash-handler.c | 273 +- libobs/obs-windows.c | 512 +-- libobs/obs.c | 1039 +++--- libobs/obs.h | 684 ++-- libobs/obs.hpp | 177 +- libobs/util/AlignedNew.hpp | 8 +- libobs/util/apple/cfstring-utils.h | 4 +- libobs/util/array-serializer.c | 6 +- libobs/util/array-serializer.h | 2 +- libobs/util/base.c | 19 +- libobs/util/base.h | 12 +- libobs/util/bmem.c | 12 +- libobs/util/bmem.h | 4 +- libobs/util/c99defs.h | 2 +- libobs/util/cf-lexer.c | 394 +-- libobs/util/cf-lexer.h | 29 +- libobs/util/cf-parser.c | 15 +- libobs/util/cf-parser.h | 72 +- libobs/util/circlebuf.h | 82 +- libobs/util/config-file.c | 166 +- libobs/util/config-file.h | 69 +- libobs/util/crc32.c | 17 +- libobs/util/darray.h | 195 +- libobs/util/dstr.c | 103 +- libobs/util/dstr.h | 71 +- libobs/util/dstr.hpp | 23 +- libobs/util/file-serializer.c | 32 +- libobs/util/file-serializer.h | 3 +- libobs/util/lexer.c | 40 +- libobs/util/lexer.h | 42 +- libobs/util/pipe-posix.c | 9 +- libobs/util/pipe-windows.c | 28 +- libobs/util/pipe.h | 8 +- libobs/util/platform-cocoa.m | 113 +- libobs/util/platform-nix-dbus.c | 85 +- libobs/util/platform-nix.c | 106 +- libobs/util/platform-windows.c | 185 +- libobs/util/platform.c | 106 +- libobs/util/platform.h | 37 +- libobs/util/profiler.c | 283 +- libobs/util/profiler.h | 57 +- libobs/util/profiler.hpp | 15 +- libobs/util/serializer.h | 30 +- libobs/util/text-lookup.c | 46 +- libobs/util/text-lookup.h | 2 +- libobs/util/threading-posix.c | 45 +- libobs/util/threading-posix.h | 4 +- libobs/util/threading-windows.c | 30 +- libobs/util/threading-windows.h | 12 +- libobs/util/threading.h | 21 +- libobs/util/utf8.c | 51 +- libobs/util/utf8.h | 6 +- libobs/util/util.hpp | 64 +- libobs/util/vc/vc_inttypes.h | 350 +- libobs/util/vc/vc_stdbool.h | 2 +- libobs/util/vc/vc_stdint.h | 79 +- libobs/util/windows/CoTaskMemPtr.hpp | 20 +- libobs/util/windows/ComPtr.hpp | 60 +- libobs/util/windows/HRError.hpp | 5 +- libobs/util/windows/WinHandle.hpp | 13 +- libobs/util/windows/win-registry.h | 6 +- .../coreaudio-encoder/data/locale/de-DE.ini | 2 +- .../coreaudio-encoder/data/locale/gl-ES.ini | 6 +- .../coreaudio-encoder/data/locale/sl-SI.ini | 6 + plugins/coreaudio-encoder/encoder.cpp | 758 ++--- plugins/coreaudio-encoder/windows-imports.h | 573 ++-- plugins/decklink/DecklinkBase.cpp | 8 +- plugins/decklink/DecklinkBase.h | 16 +- plugins/decklink/DecklinkInput.cpp | 35 +- plugins/decklink/DecklinkInput.hpp | 18 +- plugins/decklink/DecklinkOutput.cpp | 17 +- plugins/decklink/DecklinkOutput.hpp | 6 +- plugins/decklink/audio-repack.c | 30 +- plugins/decklink/audio-repack.h | 19 +- plugins/decklink/audio-repack.hpp | 9 +- plugins/decklink/const.h | 80 +- plugins/decklink/data/locale/ar-SA.ini | 2 + plugins/decklink/data/locale/de-DE.ini | 16 +- plugins/decklink/data/locale/gl-ES.ini | 23 +- plugins/decklink/data/locale/ro-RO.ini | 8 +- plugins/decklink/data/locale/sl-SI.ini | 21 + plugins/decklink/data/locale/uk-UA.ini | 2 + .../decklink/decklink-device-discovery.cpp | 12 +- .../decklink/decklink-device-discovery.hpp | 19 +- plugins/decklink/decklink-device-instance.cpp | 187 +- plugins/decklink/decklink-device-instance.hpp | 95 +- plugins/decklink/decklink-device-mode.cpp | 10 +- plugins/decklink/decklink-device-mode.hpp | 10 +- plugins/decklink/decklink-device.cpp | 68 +- plugins/decklink/decklink-device.hpp | 51 +- plugins/decklink/decklink-devices.cpp | 6 +- plugins/decklink/decklink-output.cpp | 64 +- plugins/decklink/decklink-source.cpp | 197 +- .../decklink/linux/decklink-sdk/.clang-format | 3 + plugins/decklink/linux/platform.cpp | 2 +- .../decklink/mac/decklink-sdk/.clang-format | 3 + plugins/decklink/mac/platform.cpp | 2 +- plugins/decklink/platform.hpp | 2 +- plugins/decklink/util.cpp | 60 +- plugins/decklink/win/platform.cpp | 8 +- plugins/image-source/color-source.c | 45 +- plugins/image-source/data/locale/es-ES.ini | 4 +- plugins/image-source/data/locale/gl-ES.ini | 32 +- plugins/image-source/data/locale/ro-RO.ini | 1 + plugins/image-source/data/locale/sl-SI.ini | 32 +- plugins/image-source/image-source.c | 73 +- plugins/image-source/obs-slideshow.c | 197 +- plugins/linux-alsa/alsa-input.c | 217 +- plugins/linux-alsa/data/locale/bg-BG.ini | 3 + plugins/linux-alsa/data/locale/gl-ES.ini | 2 +- plugins/linux-alsa/data/locale/sl-SI.ini | 2 + plugins/linux-alsa/linux-alsa.c | 1 - plugins/linux-capture/data/locale/de-DE.ini | 8 +- plugins/linux-capture/data/locale/gl-ES.ini | 17 +- plugins/linux-capture/data/locale/ro-RO.ini | 2 +- plugins/linux-capture/data/locale/sl-SI.ini | 2 +- plugins/linux-capture/xcompcap-helper.cpp | 439 ++- plugins/linux-capture/xcompcap-helper.hpp | 86 +- plugins/linux-capture/xcompcap-main.cpp | 396 +-- plugins/linux-capture/xcompcap-main.hpp | 7 +- plugins/linux-capture/xcomposite-main.cpp | 47 +- plugins/linux-capture/xcursor-xcb.c | 30 +- plugins/linux-capture/xcursor-xcb.h | 14 +- plugins/linux-capture/xcursor.c | 39 +- plugins/linux-capture/xhelpers.c | 31 +- plugins/linux-capture/xhelpers.h | 19 +- plugins/linux-capture/xshm-input.c | 170 +- plugins/linux-jack/data/locale/de-DE.ini | 4 +- plugins/linux-jack/jack-input.c | 34 +- plugins/linux-jack/jack-wrapper.c | 77 +- plugins/linux-jack/jack-wrapper.h | 4 +- .../linux-pulseaudio/data/locale/gl-ES.ini | 4 +- .../linux-pulseaudio/data/locale/ka-GE.ini | 2 +- plugins/linux-pulseaudio/pulse-input.c | 213 +- plugins/linux-pulseaudio/pulse-wrapper.c | 29 +- plugins/linux-pulseaudio/pulse-wrapper.h | 4 +- plugins/linux-v4l2/data/locale/ar-SA.ini | 1 + plugins/linux-v4l2/data/locale/ca-ES.ini | 1 + plugins/linux-v4l2/data/locale/cs-CZ.ini | 1 + plugins/linux-v4l2/data/locale/da-DK.ini | 1 + plugins/linux-v4l2/data/locale/de-DE.ini | 3 +- plugins/linux-v4l2/data/locale/en-US.ini | 1 + plugins/linux-v4l2/data/locale/es-ES.ini | 1 + plugins/linux-v4l2/data/locale/eu-ES.ini | 1 + plugins/linux-v4l2/data/locale/fi-FI.ini | 1 + plugins/linux-v4l2/data/locale/fr-FR.ini | 1 + plugins/linux-v4l2/data/locale/gl-ES.ini | 10 +- plugins/linux-v4l2/data/locale/hu-HU.ini | 1 + plugins/linux-v4l2/data/locale/it-IT.ini | 1 + plugins/linux-v4l2/data/locale/ja-JP.ini | 1 + plugins/linux-v4l2/data/locale/ka-GE.ini | 5 +- plugins/linux-v4l2/data/locale/ko-KR.ini | 1 + plugins/linux-v4l2/data/locale/nl-NL.ini | 1 + plugins/linux-v4l2/data/locale/pl-PL.ini | 1 + plugins/linux-v4l2/data/locale/pt-BR.ini | 1 + plugins/linux-v4l2/data/locale/ro-RO.ini | 4 + plugins/linux-v4l2/data/locale/ru-RU.ini | 1 + plugins/linux-v4l2/data/locale/sv-SE.ini | 1 + plugins/linux-v4l2/data/locale/tr-TR.ini | 1 + plugins/linux-v4l2/data/locale/uk-UA.ini | 1 + plugins/linux-v4l2/data/locale/zh-CN.ini | 1 + plugins/linux-v4l2/data/locale/zh-TW.ini | 1 + plugins/linux-v4l2/v4l2-helpers.c | 39 +- plugins/linux-v4l2/v4l2-helpers.h | 100 +- plugins/linux-v4l2/v4l2-input.c | 280 +- plugins/linux-v4l2/v4l2-udev.c | 31 +- plugins/mac-avcapture/av-capture.mm | 981 +++--- plugins/mac-avcapture/data/locale/gl-ES.ini | 12 +- plugins/mac-avcapture/data/locale/ka-GE.ini | 2 +- plugins/mac-avcapture/left-right.hpp | 10 +- plugins/mac-avcapture/scope-guard.hpp | 41 +- plugins/mac-capture/audio-device-enum.c | 66 +- plugins/mac-capture/audio-device-enum.h | 4 +- plugins/mac-capture/data/locale/gl-ES.ini | 22 +- plugins/mac-capture/data/locale/ka-GE.ini | 2 +- plugins/mac-capture/data/locale/ro-RO.ini | 2 +- plugins/mac-capture/data/locale/sl-SI.ini | 2 +- plugins/mac-capture/mac-audio.c | 343 +- plugins/mac-capture/mac-display-capture.m | 212 +- plugins/mac-capture/mac-window-capture.m | 89 +- plugins/mac-capture/window-utils.h | 6 +- plugins/mac-capture/window-utils.m | 94 +- plugins/mac-syphon/data/locale/de-DE.ini | 4 +- plugins/mac-syphon/data/locale/gl-ES.ini | 13 +- plugins/mac-syphon/data/locale/sl-SI.ini | 2 +- plugins/mac-syphon/syphon.m | 453 ++- plugins/mac-vth264/data/locale/bg-BG.ini | 12 + plugins/mac-vth264/data/locale/de-DE.ini | 10 +- plugins/mac-vth264/data/locale/gl-ES.ini | 10 +- plugins/mac-vth264/encoder.c | 428 ++- plugins/obs-ffmpeg/CMakeLists.txt | 16 + plugins/obs-ffmpeg/closest-pixel-format.h | 91 +- plugins/obs-ffmpeg/data/locale/bg-BG.ini | 2 - plugins/obs-ffmpeg/data/locale/ca-ES.ini | 4 +- plugins/obs-ffmpeg/data/locale/cs-CZ.ini | 4 +- plugins/obs-ffmpeg/data/locale/da-DK.ini | 4 +- plugins/obs-ffmpeg/data/locale/de-DE.ini | 36 +- plugins/obs-ffmpeg/data/locale/el-GR.ini | 2 - plugins/obs-ffmpeg/data/locale/en-US.ini | 4 +- plugins/obs-ffmpeg/data/locale/es-ES.ini | 4 +- plugins/obs-ffmpeg/data/locale/eu-ES.ini | 4 +- plugins/obs-ffmpeg/data/locale/fa-IR.ini | 2 - plugins/obs-ffmpeg/data/locale/fi-FI.ini | 2 - plugins/obs-ffmpeg/data/locale/fil-PH.ini | 1 - plugins/obs-ffmpeg/data/locale/fr-FR.ini | 4 +- plugins/obs-ffmpeg/data/locale/gd-GB.ini | 2 - plugins/obs-ffmpeg/data/locale/gl-ES.ini | 45 +- plugins/obs-ffmpeg/data/locale/hu-HU.ini | 4 +- plugins/obs-ffmpeg/data/locale/it-IT.ini | 4 +- plugins/obs-ffmpeg/data/locale/ja-JP.ini | 4 +- plugins/obs-ffmpeg/data/locale/ka-GE.ini | 4 +- plugins/obs-ffmpeg/data/locale/ko-KR.ini | 4 +- plugins/obs-ffmpeg/data/locale/nb-NO.ini | 2 - plugins/obs-ffmpeg/data/locale/nl-NL.ini | 4 +- plugins/obs-ffmpeg/data/locale/pl-PL.ini | 4 +- plugins/obs-ffmpeg/data/locale/pt-BR.ini | 4 +- plugins/obs-ffmpeg/data/locale/pt-PT.ini | 1 - plugins/obs-ffmpeg/data/locale/ro-RO.ini | 4 +- plugins/obs-ffmpeg/data/locale/ru-RU.ini | 4 +- plugins/obs-ffmpeg/data/locale/sk-SK.ini | 2 - plugins/obs-ffmpeg/data/locale/sl-SI.ini | 55 +- plugins/obs-ffmpeg/data/locale/sr-CS.ini | 2 - plugins/obs-ffmpeg/data/locale/sr-SP.ini | 2 - plugins/obs-ffmpeg/data/locale/sv-SE.ini | 4 +- plugins/obs-ffmpeg/data/locale/tl-PH.ini | 1 - plugins/obs-ffmpeg/data/locale/tr-TR.ini | 3 +- plugins/obs-ffmpeg/data/locale/uk-UA.ini | 4 +- plugins/obs-ffmpeg/data/locale/zh-CN.ini | 4 +- plugins/obs-ffmpeg/data/locale/zh-TW.ini | 4 +- plugins/obs-ffmpeg/external/.clang-format | 3 + .../obs-ffmpeg/{ => external}/dynlink_cuda.h | 0 .../obs-ffmpeg/{ => external}/nvEncodeAPI.h | 0 plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c | 128 +- plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.h | 16 +- plugins/obs-ffmpeg/jim-nvenc-helpers.c | 81 +- plugins/obs-ffmpeg/jim-nvenc.c | 307 +- plugins/obs-ffmpeg/jim-nvenc.h | 5 +- .../obs-ffmpeg/obs-ffmpeg-audio-encoders.c | 205 +- plugins/obs-ffmpeg/obs-ffmpeg-compat.h | 16 +- plugins/obs-ffmpeg/obs-ffmpeg-config.h.in | 17 + plugins/obs-ffmpeg/obs-ffmpeg-formats.h | 121 +- plugins/obs-ffmpeg/obs-ffmpeg-logging.c | 138 + plugins/obs-ffmpeg/obs-ffmpeg-mux.c | 229 +- plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c | 203 +- plugins/obs-ffmpeg/obs-ffmpeg-output.c | 516 ++- plugins/obs-ffmpeg/obs-ffmpeg-source.c | 178 +- plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c | 205 +- plugins/obs-ffmpeg/obs-ffmpeg.c | 175 +- plugins/obs-filters/async-delay-filter.c | 86 +- plugins/obs-filters/chroma-key-filter.c | 155 +- plugins/obs-filters/color-correction-filter.c | 223 +- plugins/obs-filters/color-grade-filter.c | 50 +- plugins/obs-filters/color-key-filter.c | 133 +- plugins/obs-filters/compressor-filter.c | 129 +- plugins/obs-filters/crop-filter.c | 110 +- plugins/obs-filters/data/locale/bg-BG.ini | 32 + plugins/obs-filters/data/locale/de-DE.ini | 50 +- plugins/obs-filters/data/locale/en-US.ini | 40 +- plugins/obs-filters/data/locale/gl-ES.ini | 83 +- plugins/obs-filters/data/locale/ja-JP.ini | 4 +- plugins/obs-filters/data/locale/ka-GE.ini | 2 +- plugins/obs-filters/data/locale/nl-NL.ini | 5 + plugins/obs-filters/data/locale/ro-RO.ini | 11 +- plugins/obs-filters/data/locale/sl-SI.ini | 97 + plugins/obs-filters/data/locale/sv-SE.ini | 2 +- plugins/obs-filters/expander-filter.c | 186 +- plugins/obs-filters/gain-filter.c | 21 +- plugins/obs-filters/gpu-delay.c | 64 +- plugins/obs-filters/invert-audio-polarity.c | 6 +- plugins/obs-filters/limiter-filter.c | 70 +- plugins/obs-filters/luma-key-filter.c | 85 +- plugins/obs-filters/mask-filter.c | 90 +- plugins/obs-filters/noise-gate-filter.c | 60 +- plugins/obs-filters/noise-suppress-filter.c | 71 +- plugins/obs-filters/scale-filter.c | 189 +- plugins/obs-filters/scroll-filter.c | 126 +- plugins/obs-filters/sharpness-filter.c | 29 +- plugins/obs-libfdk/data/locale/bg-BG.ini | 4 + plugins/obs-libfdk/data/locale/de-DE.ini | 4 +- plugins/obs-libfdk/data/locale/gl-ES.ini | 4 +- plugins/obs-libfdk/data/locale/sl-SI.ini | 4 +- plugins/obs-libfdk/obs-libfdk.c | 102 +- plugins/obs-outputs/data/locale/de-DE.ini | 14 +- plugins/obs-outputs/data/locale/fa-IR.ini | 4 + plugins/obs-outputs/data/locale/gl-ES.ini | 15 +- plugins/obs-outputs/data/locale/sl-SI.ini | 13 +- plugins/obs-outputs/flv-mux.c | 79 +- plugins/obs-outputs/flv-mux.h | 6 +- plugins/obs-outputs/flv-output.c | 85 +- plugins/obs-outputs/ftl-stream.c | 365 +-- plugins/obs-outputs/librtmp/.clang-format | 3 + plugins/obs-outputs/net-if.c | 77 +- plugins/obs-outputs/net-if.h | 54 +- plugins/obs-outputs/null-output.c | 20 +- plugins/obs-outputs/rtmp-helpers.h | 13 +- plugins/obs-outputs/rtmp-stream.c | 559 +++- plugins/obs-outputs/rtmp-stream.h | 116 +- plugins/obs-outputs/rtmp-windows.c | 166 +- plugins/obs-text/data/locale/ar-SA.ini | 4 + plugins/obs-text/data/locale/bg-BG.ini | 35 + plugins/obs-text/data/locale/de-DE.ini | 6 +- plugins/obs-text/data/locale/gl-ES.ini | 38 + plugins/obs-text/data/locale/ro-RO.ini | 12 +- plugins/obs-text/data/locale/sl-SI.ini | 38 + plugins/obs-text/gdiplus/obs-text.cpp | 325 +- plugins/obs-transitions/data/locale/ca-ES.ini | 4 +- plugins/obs-transitions/data/locale/cs-CZ.ini | 4 +- plugins/obs-transitions/data/locale/da-DK.ini | 4 +- plugins/obs-transitions/data/locale/de-DE.ini | 8 +- plugins/obs-transitions/data/locale/el-GR.ini | 2 - plugins/obs-transitions/data/locale/en-US.ini | 4 +- plugins/obs-transitions/data/locale/es-ES.ini | 8 +- plugins/obs-transitions/data/locale/eu-ES.ini | 4 +- plugins/obs-transitions/data/locale/fi-FI.ini | 2 - .../obs-transitions/data/locale/fil-PH.ini | 2 - plugins/obs-transitions/data/locale/fr-FR.ini | 4 +- plugins/obs-transitions/data/locale/gl-ES.ini | 58 + plugins/obs-transitions/data/locale/he-IL.ini | 1 - plugins/obs-transitions/data/locale/hr-HR.ini | 1 - plugins/obs-transitions/data/locale/hu-HU.ini | 4 +- plugins/obs-transitions/data/locale/it-IT.ini | 4 +- plugins/obs-transitions/data/locale/ja-JP.ini | 4 +- plugins/obs-transitions/data/locale/ka-GE.ini | 4 +- plugins/obs-transitions/data/locale/ko-KR.ini | 4 +- plugins/obs-transitions/data/locale/nb-NO.ini | 2 - plugins/obs-transitions/data/locale/nl-NL.ini | 4 +- plugins/obs-transitions/data/locale/pl-PL.ini | 4 +- plugins/obs-transitions/data/locale/pt-BR.ini | 4 +- plugins/obs-transitions/data/locale/pt-PT.ini | 2 - plugins/obs-transitions/data/locale/ro-RO.ini | 2 - plugins/obs-transitions/data/locale/ru-RU.ini | 4 +- plugins/obs-transitions/data/locale/sk-SK.ini | 1 - plugins/obs-transitions/data/locale/sl-SI.ini | 66 + plugins/obs-transitions/data/locale/sr-CS.ini | 2 - plugins/obs-transitions/data/locale/sr-SP.ini | 2 - plugins/obs-transitions/data/locale/sv-SE.ini | 4 +- plugins/obs-transitions/data/locale/tl-PH.ini | 2 - plugins/obs-transitions/data/locale/tr-TR.ini | 3 +- plugins/obs-transitions/data/locale/uk-UA.ini | 4 +- plugins/obs-transitions/data/locale/zh-CN.ini | 4 +- plugins/obs-transitions/data/locale/zh-TW.ini | 4 +- plugins/obs-transitions/transition-cut.c | 9 +- .../transition-fade-to-color.c | 50 +- plugins/obs-transitions/transition-fade.c | 13 +- .../obs-transitions/transition-luma-wipe.c | 50 +- plugins/obs-transitions/transition-slide.c | 32 +- plugins/obs-transitions/transition-stinger.c | 142 +- plugins/obs-transitions/transition-swipe.c | 29 +- plugins/obs-x264/data/locale/ar-SA.ini | 4 +- plugins/obs-x264/data/locale/de-DE.ini | 8 +- plugins/obs-x264/data/locale/gl-ES.ini | 11 +- plugins/obs-x264/data/locale/sl-SI.ini | 15 +- plugins/obs-x264/obs-x264.c | 368 +-- plugins/rtmp-services/data/locale/bg-BG.ini | 9 + plugins/rtmp-services/data/locale/de-DE.ini | 2 +- plugins/rtmp-services/data/locale/fa-IR.ini | 11 + plugins/rtmp-services/data/locale/gl-ES.ini | 7 +- plugins/rtmp-services/data/locale/sl-SI.ini | 9 +- plugins/rtmp-services/data/package.json | 4 +- plugins/rtmp-services/data/services.json | 262 +- plugins/rtmp-services/rtmp-common.c | 159 +- plugins/rtmp-services/rtmp-custom.c | 31 +- plugins/rtmp-services/rtmp-services-main.c | 16 +- plugins/rtmp-services/twitch.c | 15 +- plugins/text-freetype2/data/locale/de-DE.ini | 2 +- plugins/text-freetype2/data/locale/gl-ES.ini | 4 +- plugins/text-freetype2/data/locale/sl-SI.ini | 19 +- plugins/text-freetype2/find-font-cocoa.m | 34 +- plugins/text-freetype2/find-font-iconv.c | 132 +- plugins/text-freetype2/find-font-unix.c | 37 +- plugins/text-freetype2/find-font-windows.c | 142 +- plugins/text-freetype2/find-font.c | 105 +- plugins/text-freetype2/find-font.h | 17 +- plugins/text-freetype2/obs-convenience.c | 20 +- plugins/text-freetype2/obs-convenience.h | 20 +- plugins/text-freetype2/text-freetype2.c | 120 +- plugins/text-freetype2/text-freetype2.h | 6 +- plugins/text-freetype2/text-functionality.c | 137 +- plugins/vlc-video/data/locale/de-DE.ini | 2 +- plugins/vlc-video/data/locale/es-ES.ini | 2 +- plugins/vlc-video/data/locale/gl-ES.ini | 18 + plugins/vlc-video/data/locale/ko-KR.ini | 2 +- plugins/vlc-video/data/locale/ro-RO.ini | 4 +- plugins/vlc-video/data/locale/sl-SI.ini | 18 + plugins/vlc-video/vlc-video-plugin.c | 41 +- plugins/vlc-video/vlc-video-plugin.h | 246 +- plugins/vlc-video/vlc-video-source.c | 243 +- test/osx/test.mm | 85 +- test/test-input/sync-async-source.c | 49 +- test/test-input/sync-audio-buffering.c | 77 +- test/test-input/sync-pair-aud.c | 31 +- test/test-input/sync-pair-vid.c | 22 +- test/test-input/test-filter.c | 14 +- test/test-input/test-random.c | 40 +- test/test-input/test-sinewave.c | 25 +- test/win/test.cpp | 52 +- 842 files changed, 42245 insertions(+), 33385 deletions(-) create mode 100644 .clang-format create mode 100644 .git-blame-ignore-revs create mode 100755 CI/check-format.sh create mode 100644 UI/data/locale/az-AZ.ini create mode 100644 UI/data/themes/Dark/media-pause.svg create mode 100644 UI/forms/OBSExtraBrowsers.ui create mode 100644 UI/forms/images/media-pause.svg create mode 100644 UI/frontend-plugins/frontend-tools/data/locale/af-ZA.ini create mode 100644 UI/frontend-plugins/frontend-tools/data/locale/gl-ES.ini create mode 100644 UI/frontend-plugins/frontend-tools/data/locale/sl-SI.ini create mode 100644 UI/frontend-plugins/frontend-tools/data/scripts/pause-scene.lua create mode 100644 UI/record-button.cpp create mode 100644 UI/record-button.hpp create mode 100644 UI/window-dock-browser.cpp create mode 100644 UI/window-dock-browser.hpp create mode 100644 UI/window-extra-browsers.cpp create mode 100644 UI/window-extra-browsers.hpp create mode 100644 deps/glad/.clang-format create mode 100644 deps/json11/.clang-format create mode 100644 deps/w32-pthreads/.clang-format create mode 100755 formatcode.sh create mode 100644 libobs/graphics/libnsgif/.clang-format create mode 100644 plugins/coreaudio-encoder/data/locale/sl-SI.ini create mode 100644 plugins/decklink/linux/decklink-sdk/.clang-format create mode 100644 plugins/decklink/mac/decklink-sdk/.clang-format create mode 100644 plugins/linux-alsa/data/locale/bg-BG.ini create mode 100644 plugins/linux-alsa/data/locale/sl-SI.ini create mode 100644 plugins/mac-vth264/data/locale/bg-BG.ini create mode 100644 plugins/obs-ffmpeg/external/.clang-format rename plugins/obs-ffmpeg/{ => external}/dynlink_cuda.h (100%) rename plugins/obs-ffmpeg/{ => external}/nvEncodeAPI.h (100%) create mode 100644 plugins/obs-ffmpeg/obs-ffmpeg-config.h.in create mode 100644 plugins/obs-ffmpeg/obs-ffmpeg-logging.c create mode 100644 plugins/obs-libfdk/data/locale/bg-BG.ini create mode 100644 plugins/obs-outputs/data/locale/fa-IR.ini create mode 100644 plugins/obs-outputs/librtmp/.clang-format create mode 100644 plugins/obs-text/data/locale/bg-BG.ini create mode 100644 plugins/obs-text/data/locale/gl-ES.ini create mode 100644 plugins/obs-text/data/locale/sl-SI.ini create mode 100644 plugins/obs-transitions/data/locale/sl-SI.ini create mode 100644 plugins/rtmp-services/data/locale/bg-BG.ini create mode 100644 plugins/rtmp-services/data/locale/fa-IR.ini create mode 100644 plugins/vlc-video/data/locale/gl-ES.ini create mode 100644 plugins/vlc-video/data/locale/sl-SI.ini diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..c9dfc48 --- /dev/null +++ b/.clang-format @@ -0,0 +1,107 @@ +# please use clang-format version 8 or later + +Standard: Cpp11 +AccessModifierOffset: -8 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +#AllowAllArgumentsOnNextLine: false # requires clang-format 9 +#AllowAllConstructorInitializersOnNextLine: false # requires clang-format 9 +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: false +#AllowShortLambdasOnASingleLine: Inline # requires clang-format 9 +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakStringLiterals: false # apparently unpredictable +ColumnLimit: 80 +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 8 +ContinuationIndentWidth: 8 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +FixNamespaceComments: false +ForEachMacros: + - 'json_object_foreach' + - 'json_object_foreach_safe' + - 'json_array_foreach' +IncludeBlocks: Preserve +IndentCaseLabels: false +IndentPPDirectives: None +IndentWidth: 8 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +#ObjCBinPackProtocolList: Auto # requires clang-format 7 +ObjCBlockIndentWidth: 8 +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true + +PenaltyBreakAssignment: 10 +PenaltyBreakBeforeFirstCallParameter: 30 +PenaltyBreakComment: 10 +PenaltyBreakFirstLessLess: 0 +PenaltyBreakString: 10 +PenaltyExcessCharacter: 100 +PenaltyReturnTypeOnItsOwnLine: 60 + +PointerAlignment: Right +ReflowComments: false +SortIncludes: false +SortUsingDeclarations: false +SpaceAfterCStyleCast: false +#SpaceAfterLogicalNot: false # requires clang-format 9 +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +#SpaceBeforeCtorInitializerColon: true # requires clang-format 7 +#SpaceBeforeInheritanceColon: true # requires clang-format 7 +SpaceBeforeParens: ControlStatements +#SpaceBeforeRangeBasedForLoopColon: true # requires clang-format 7 +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +#StatementMacros: # requires clang-format 8 +# - 'Q_OBJECT' +TabWidth: 8 +#TypenameMacros: # requires clang-format 9 +# - 'DARRAY' +UseTab: ForContinuationAndIndentation +--- +Language: ObjC diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..e94d209 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1 @@ +f53df7da64d2dfc542c24656720b2f47c8957164 diff --git a/.travis.yml b/.travis.yml index 939917e..adf5abe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ matrix: osx_image: xcode9.4 env: - CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake - - CEF_BUILD_VERSION=3.3282.1726.gc8368c8 + - CEF_BUILD_VERSION=3770 before_install: "./CI/install-dependencies-osx.sh" before_script: "./CI/before-script-osx.sh" before_deploy: "./CI/before-deploy-osx.sh" diff --git a/AUTHORS b/AUTHORS index e0167d4..2a68ab9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -271,6 +271,7 @@ wayne wang Translators: Afrikaans: - Samuel Nthoroane (Samuel_Nthoroane) + - speedytechdev Albanian: - Albin Pllana (albinnpllanaa) - Aredio Vani (aredio.vani) @@ -283,15 +284,16 @@ Arabic: - BWU Wheelman (Wheelman) - Saleh Luxmaroc (salehoukiki) - معتصم دعنا (rozana-media) - - Hani Sweileh (hno.sweileh) - Mustafa2018 - - Tensai - - Vainock (ivo.lemmert) + - Hani Sweileh (hno.sweileh) + - Vainock - Mnsor The-Ghost (mnsor1722011) + - Tensai - FC Barcelona HD (kurdnews) - Ndalabo Taema (hake_bsowq) - dodgepong - chaironeko + - Hadi Gamer (hadigamer3131) Azerbaijani: - Shahin Farzaliyev (Khan27) Basque: @@ -301,38 +303,40 @@ Basque: - txaro (txaro) - EG Gamer (eggamer131) - etxondoko - - Vainock (ivo.lemmert) + - Vainock - dodgepong Bengali: - shamuntohamd + - Vainock - Gol D. Ace (goldace) - - Vainock (ivo.lemmert) - Nurul Huda (nurulhuda859) - Md Arafat (zonoiko) Bulgarian: - j3dy - - kalmarin - - Zakxaev68 - - Seyhan Halil (yildirim17) - Dremski + - Zakxaev68 + - kalmarin + - Seyhan Halil (yildirim17) - Martin Georgiev (DivideByNone) - Viktor Kitov (viktorkitov) - Stanislav_Evtimov - Stoyan Stoyanov (sstoyanov) + - Vainock - Gol D. Ace (goldace) - - Vainock (ivo.lemmert) - Ivan (SKDown) - Warchamp7 + - dodgepong Catalan: - Jaime Muñoz Martín (jmmartin_5) - jmontane - - Nil Campamà (Soifam) - Benet R. i Camps (BennyBeat) (BennyBeat) + - Nil Campamà (Soifam) - Aleix Vidal i Gaya (leixet) - Gol D. Ace (goldace) - - Vainock (ivo.lemmert) - - Pere O. (gotrunks) + - Vainock - Aniol Pagès (aniolpages) + - Pere O. (gotrunks) + - dodgepong Chinese Simplified: - Bob Liu (Akagi201) - AlexGuo1998 (AlexGuo1998) @@ -341,6 +345,7 @@ Chinese Simplified: - Gol D. Ace (goldace) - Licardo (Licardo) - AthlonHD (AthlonHD) + - Forbidden (cptbl00dra1n) - Hexcolyte (Hexcolyte) - Sasasu (Sasasu) - cai_miao @@ -348,56 +353,58 @@ Chinese Simplified: - David Kuo (s50407s) - 鲜童 (xiananjyzy) - Opportunity (OpportunityLiu) - - Forbidden (cptbl00dra1n) - yunluzhang - - Inku Xuan (inkuxuan) - copyliu + - Inku Xuan (inkuxuan) - Bing Feng (fengbing123) - - pan93412 - - WeiYuanStudio + - Yi-Jyun Pan (pan93412) + - fangzheng (fangzheng) + - Vainock - 科技小白堂 (lipeng0820) + - WeiYuanStudio - Richard Stanway (r1ch) - WaterOtaku - dodgepong - MarsYoung - sorayuki - cylin - - Vainock (ivo.lemmert) + - Bob Wei (BobWaver) - 赵杭灵 (h1679083640) + - FaZe Fakay (fazefakay) - wordlessWind (wordlesswind) - OYYZ - - FaZe Fakay (fazefakay) - - Bob Wei (BobWaver) + - Martinzzz Chinese Traditional: - TzeKei Lee (chikei) + - Yi-Jyun Pan (pan93412) - dodgepong - Julian_Lai - - Chien-Yu Lin (u900011) - - pan93412 + - Florid (u900011) - David Kuo (s50407s) - Michael Yeh (hinet60613) - You-Ruei Tzeng (e222et) - myjourney in Steemit (myjourney) - craftwar + - louis921222 - Gol D. Ace (goldace) - - Inndy.Lin (inndy) - Han-Jen Cheng (notexist) + - Inndy.Lin (inndy) - Watson Tsai (ashaneba) - Meng Hao Li (GazCore) + - Vainock - abc0922001 - Thomas (thomassth) - - louis921222 - ak-47root - - Jimmy Huang (f56112000) + - fangzheng (fangzheng) - cai_miao - Append Huang (append) + - Jimmy Huang (f56112000) - 曹恩逢 (nelson22768384) - - Vainock (ivo.lemmert) - xixiaofan (Hs0) - - tomoe-musashi + - JackYeah - FaZe Fakay (fazefakay) - chaironeko - - JackYeah + - tomoe-musashi Croatian: - medicmomcilo - srdjan_m @@ -406,7 +413,7 @@ Croatian: - Gol D. Ace (goldace) - Wildrage - Maky (the.real.maky) - - Vainock (ivo.lemmert) + - Vainock - dodgepong Czech: - Jirka 'Venty' Michel (VentyCZ) @@ -414,8 +421,8 @@ Czech: - Sawanyo - Kiznoh - Gol D. Ace (goldace) + - Vainock - Erik Bročko (ericek111) - - Vainock (ivo.lemmert) - dodgepong Danish: - NCAA (NCAA) @@ -424,14 +431,15 @@ Danish: - MaltahlGaming (maltahlgaming) - Gol D. Ace (goldace) - Anders Urban (minikaliffen) + - Vainock - Richard Stanway (r1ch) - Johan Keller Jensen (JKeller) - Christian Henriksen (cnhenriksen) - - Vainock (ivo.lemmert) - Marque Ziqulr (lugtelort) - HeroGamers (Fido2603) - - Nicolai (Nicolai9852) + - Nicolai Skødt Holmgaard (Nicolai9852) - Daniel Aundal (aundal) + - dodgepong Dutch: - Eric Bataille (ThoNohT) - Michel Snippe (michelsnippe) @@ -443,19 +451,21 @@ Dutch: - Danny (Dkamps18) - Gol D. Ace (goldace) - Albakham (albakham) - - Jasper J (JassieJ) + - Kjetil Verstrepen (kjetilv) - Bond-009 + - Jasper J (JassieJ) - b__dm - F_Producktions + - Jennifer Falco (JenTheBluePanda) - Harm van den Hoek (harm27) + - Vainock - markpc - JorRy - - Julian Meijboom (julianmeijboom) - Bo Alsemgeest (bo.alsemgeest.wausie) + - Julian Meijboom (julianmeijboom) - andymidside - JustMaffie (JustMaffie) - RyyzQ - - Vainock (ivo.lemmert) Estonian: - MartinEwing - AndresTraks @@ -466,8 +476,9 @@ Filipino: - nyakayed (nyakayed) - Loyd Stephen Jayme (loydjayme25) - Gol D. Ace (goldace) - - Vainock (ivo.lemmert) + - Vainock - Raylir + - vinzruzell Finnish: - Arkkis (j) - Jarska @@ -475,14 +486,15 @@ Finnish: - Pyscowicz (Pyscowicz) - Gol D. Ace (goldace) - Obama (Obama44) + - Vainock - Tero Keso (tero.keso) - - Vainock (ivo.lemmert) - - chaironeko + - Arttu Ylhävuori (arttu.ylhavuori) - Ville Närhi (daimaah) + - chaironeko French: - radzaquiel - - pkviet - Stéphane Lepin (Palakis) + - pkviet - Yberion - Tocram2 (tocram2) - DoK_- @@ -502,38 +514,42 @@ French: - Theguiguix - Gabriel Dugny (Gabigabigo) - McGuygnol + - Vainock - Yolopix - - GANGAT Naeem (zboggum) + - Aime23 - kyllian (tardigradeus) + - GANGAT Naeem (zboggum) - BaguetteDePain_ - Richard Stanway (r1ch) - - Mathieu Hautebas (matteyeux) + - SkytAsul (skytasul) - Zalki + - Mathieu Hautebas (matteyeux) - dodgepong - - 🌠 DarK | #Hello 🌠 (DarKTV_FR) - - Vainock (ivo.lemmert) - - illusdidi - Adrien “GameZone Tv” de Decker (redcraft007) - - Warchamp7 - - Albakham (albakham) + - illusdidi + - 🌠 DarK | #Hello 🌠 (DarKTV_FR) - SkylixX - chaironeko - - Camille Nury (kamsdu30) - Alexis Brandner (Alexinfos) + - Warchamp7 + - Albakham (albakham) + - Camille Nury (kamsdu30) - tburette Galician: + - mbouzada - Xesús M. Mosquera Carregal (xesusmosquera) + - Iváns (Ivans_translator) - Gol D. Ace (goldace) + - Vainock - chaironeko - - Vainock (ivo.lemmert) Georgian: - georgianizator - EduCare Razmik Badalyan (badalyanrazmik) + - Vainock - Gol D. Ace (goldace) - - Vainock (ivo.lemmert) German: - Gol D. Ace (goldace) - - Vainock (ivo.lemmert) + - Vainock - Michael Fabian Dirks (Xaymar) - dodgepong - Dennis Giebert (Isegrim) (isegrimderwolf) @@ -541,22 +557,24 @@ German: - Gregor Bigalke (gregtcltk) - Sven Kirschbaum (fallobst22) (fallobst22) - Manuel (ElectronicWar) - - eZ_KrieG3R | Der Fabse (fabian.schwarz.26.06.1998) - Palana - Tim (robske_110) (robske110) - Jonas Otto (jottosmail) - mdod - Jonathan (macburgerjunior) - - Prince_of_Raop - Enderdrache LP (enderdrachelp) + - Prince_of_Raop - Robin Hielscher (Jack0r) - - lebaston100.de - Richard Stanway (r1ch) - Patrick Frings (Ragnos) + - lebaston100.de - WurstOnAir - BoJustus - AndreLeonardo (andreleonardoyt) - Tiim + - Hadi Gamer (hadigamer3131) + - Lord Aidan (BadSideofBright) + - Glocker | Felix L. (Haard22) Greek: - Scourgemcdak - Mepharees @@ -565,37 +583,38 @@ Greek: - George T. (tzikas97) - Alex Kalles (alexakis1997) - iosifidis + - Warmaster + - Vainock - Gol D. Ace (goldace) - - Vainock (ivo.lemmert) - dodgepong - Themis T. (Deminho) - chaironeko Hebrew: - amirsher - lonelywolf11 + - djsavta - Chemi (Chemi) - epic_ziver_D (epic_ziver_D) - - Uri Ben Yossef (uribenyossef) - Gol D. Ace (goldace) - Light1c3 - ghsi - yair (5shekel) + - Vainock - TheOver (upmeboost) - - djsavta - אפיק רוזנר (afikr333) - - Vainock (ivo.lemmert) - Tal Machani (talmachani) Hindi: + - Saswata Banerjee (azure.saswata) - SneakyFish5 - shamuntohamd Hungarian: - Gige - Gol D. Ace (goldace) + - Vainock - Adam Liszkai (adamos42) - abydosan (abydoshun) - dodgepong - vargag159 - - Vainock (ivo.lemmert) Italian: - Manfre#9262 (manfre) - LordShadow95 @@ -611,58 +630,60 @@ Italian: - Edoardo “OfficialDJMela” Macrì (agersforum) - Martazza (Martazza) - Gol D. Ace (goldace) + - Alessandro Sarto (alesarto03) - gianni morandi (strabbioboy) - Fisherozzo - - Alessandro Sarto (alesarto03) - - Sergio Beneduce (sbeneduce) + - Vainock - Albakham (albakham) + - Sergio Beneduce (sbeneduce) - Andrea-M3 - SkyLion - - Vainock (ivo.lemmert) - - Federico Tensi (habby1337) - Silpheel + - Federico Tensi (habby1337) - Alessandro Iepure (alessandro_iepure) - riccardotornesello Japanese: - shousa - Kenta Takumi (kenta0644) - dodgepong - - SplatRT + - Bhanu Victor DiCara (SplatRT) + - 森の子リスのミーコの大冒険 (Phroneris) + - CKK COBALT (CKKCOBALT) - Gol D. Ace (goldace) - 神成フィルム (kami00nari) - - ato lash (hal_shu_sato) + - Vainock - Noi (Noi_noel2647) - - CKK COBALT (CKKCOBALT) + - ato lash (hal_shu_sato) - Yuki Yu (Yukiyu) - chaironeko - - Bob Liu (Akagi201) - Alex Shafer (enzanki-ars) - - Vainock (ivo.lemmert) + - Bob Liu (Akagi201) Khmer: - បងមាន តែអូន (cheaiphone267) Korean: - ynetwork (ynetwork) - Gol D. Ace (goldace) + - Vainock - RedditRook - Jong Kwon Choi (dailypro) + - Russell (crimeroyal) - antome Kurdish: - Omer Kurdish (OmerKurd) Lithuanian: - Justas Vilimas (tyntas) - xNaii (lyrikas5) - - Vainock (ivo.lemmert) - Gol D. Ace (goldace) + - Vainock Malay: - amsyar ZeRo (amsyarminer555) - WeingHong - Gol D. Ace (goldace) - dodgepong - - Vainock (ivo.lemmert) + - Vainock Mongolian: - begjan - - Vainock (ivo.lemmert) -Nigerian Pidgin: + - Vainock Norwegian Bokmal: - Taesh (magnusmbratteng) - Imre Kristoffer Eilertsen (DandelionSprout) @@ -679,15 +700,18 @@ Norwegian Bokmal: - Sander Skjegstad (r530er) - Gol D. Ace (goldace) - Legend27 - - Vainock (ivo.lemmert) + - Vainock - chaironeko - Mats Andreassen (MatsA) Norwegian Nynorsk: - Imre Kristoffer Eilertsen (DandelionSprout) + - morden Persian: - MZ MAXIMUM (mahdigamermax) - Alireza Firouzi (pikhoshorg) - peymanr34 + - Berrely + - Gol D. Ace (goldace) Pirate English: - Matt Gajownik (WizardCM) - Uaiquqjwnsns @@ -696,10 +720,11 @@ Pirate English: - Emu-Phoenix - Coen (Trigstur) - Charlie W. (wallichc) - - Vainock (ivo.lemmert) + - Vainock - chaironeko - Gol D. Ace (goldace) - ncb + - Berrely Polish: - grocal (grocal) - Michał Durak (micechal) @@ -712,23 +737,26 @@ Polish: - Daniel Wieczorek (Kennyluz) - Albakham (albakham) - popek069 + - Vainock - sebek1pan - Mateusz (Silesianek) - - Julia Drewniak (ewagsi) - dodgepong - - Vainock (ivo.lemmert) - - Patryk Kunda (ner.i.ol) + - Julia Drewniak (ewagsi) - Michał Lewczak (michal200507) + - Patryk Kunda (ner.i.ol) Portuguese: - André Biscaia (LazP) - Ev1lbl0w - dodgepong + - Manuela Silva (mansil) - joaofvieira - Tomás Antunes (tomasantunes) - joaoboia - Albakham (albakham) - alexandre433 - Gol D. Ace (goldace) + - Gabriell (gabriellpt04) + - Vainock Portuguese, Brazilian: - Shaolin (admshao) - Ramon Mendes (rbrgameplays) @@ -736,16 +764,15 @@ Portuguese, Brazilian: - TFSThiagoBR98 - CaioWzy - clr0dr1g - - aalonsomb - - André Gama (ToeOficial) - - Gol D. Ace (goldace) - Emanoel Lopes (emanoelopes) + - André Gama (ToeOficial) + - aalonsomb + - Gol D. Ace (goldace) - mizifih + - Vainock - DevilLorde - - flor.com (florretardada) - - Vainock (ivo.lemmert) - - dodgepong - Esdras Tarsis (esdrastarsis) + - dodgepong - Ramon Gonzalez (ramon200000) Punjabi: - manjotsingh0202 @@ -759,9 +786,9 @@ Romanian: - Skellytone - Mihai G (babasghenciu) - Gol D. Ace (goldace) + - Vainock - dodgepong - chaironeko - - Vainock (ivo.lemmert) Russian: - Alek Nirov (dectanova) - Pavel (Shevalie) @@ -769,56 +796,62 @@ Russian: - VNGXR - Gol D. Ace (goldace) - Bugo (Bugo) - - Andy (anry025) - - Strange Grey Cat (StrangeGreyCat) - - Yaroslav (MrYadro) - Andrei Stepanov (adem4ik) + - Yaroslav (MrYadro) + - Andy (anry025) + - Artem4ik + - Strange Grey Cat (StrangeGreyCat) - fromgate (fromgate) - - Vlad (KoTmaxHo) + - Vainock - Runoff Screen (glebpozbnakov62) - - Mixaill - - Vainock (ivo.lemmert) + - Vlad (KoTmaxHo) + - Әлмәт Ак Арыслан (19082004amir) - Sergei Fug1t1v3 (fug) + - Mixaill - Walt Gee (vovanych) + - Sirboys - Serge Sklyarov (sergesklyarov) - - Yuri Mihaqlov (yurijmi) - - MUHADDIS MEDIA (muhaddismedia) - - TR1D - - Sigge Stjärnholm (Kladdy) - - SandoBY - Kuji Kitamura (KujiKita) + - TR1D + - Yuri Mihaqlov (yurijmi) + - Vladimir (jeffors) + - MUHADDIS MEDIA (muhaddismedia) + - SandoBY + - Sigge Stjärnholm (Kladdy) Scottish Gaelic: - GunChleoc - - Vainock (ivo.lemmert) + - Vainock Serbian (Cyrillic): - medicmomcilo - Acamicamacaraca - Gol D. Ace (goldace) - - dodgepong + - Vainock - LittleGirl_WithPonyTail (alexs1320) - - Vainock (ivo.lemmert) + - dodgepong Serbian (Latin): - medicmomcilo - LittleGirl_WithPonyTail (alexs1320) - Gol D. Ace (goldace) - Rale Sarcevic (ralesarcevic) + - Vainock - dodgepong - - Vainock (ivo.lemmert) Slovak: - Luki (luki1412) - - Ján M (longmoped) - Erik Bročko (ericek111) + - Ján M (longmoped) - Anton Lokaj (anlo) - LoLLy Nka (lollynka279) - Gol D. Ace (goldace) - - Vainock (ivo.lemmert) + - Vainock + - dodgepong Slovenian: + - Peter Klofutar (peter.klofutar) - kristjan.krusic (krusic22) - MG lolenstine (mglolenstine) - - Grimpy + - BirdCute + - Vainock - Gol D. Ace (goldace) - ArcaneWater - - Vainock (ivo.lemmert) - dodgepong Southern Sotho: - Samuel Nthoroane (Samuel_Nthoroane) @@ -827,30 +860,31 @@ Spanish: - Jaime Martinez Rincon (mrjaime1999) - Marcos Vidal Martinez (M4RK22) - Jaime Muñoz Martín (jmmartin_5) + - Monsteer - EG Gamer (eggamer131) - Dalia Sofía Magallón Páramo (SweetSofiMC) - Gol D. Ace (goldace) - - Monsteer - Pilar G. (TheMadnessLady) - Maximiliano Schtroumpftech Pena-Roig (som2tokmynam) - Carlos Plata (carlosesgenial33) - Ruben Deig Ramos (rdeigramos) - Marcos Vidal (markitos.maki22) - - eskaidom (sergiomalagonmartin) - Alex E. D. B. (alexedb) + - Skiddome (sergiomalagonmartin) - Santiago Pereyra (SannttVIII) - - Eleazar Córcoles (MtrElee3) - eemiroj + - Eleazar (MtrElee3) - Ray (Ipsumry) + - Vainock - makiza1 (micosil_2) - Sigge Stjärnholm (Kladdy) - - henrycontreras - - Vainock (ivo.lemmert) - chaironeko - - dodgepong + - Jaire (corpi.98) + - henrycontreras - amssusgameplays (willifake052) - - Rodrigo Ipince (ipince) + - dodgepong - David Sonico (davidsubsonico) + - Rodrigo Ipince (ipince) Swedish: - Anton R (FirePhoenix) - Sigge Stjärnholm (Kladdy) @@ -859,12 +893,15 @@ Swedish: - Gustav Ekner (ekner) - Gol D. Ace (goldace) - Jonatan Nyberg (sweuser) + - ArvidTheSwe + - 0x9fff00 + - Vainock - Henrik Mattsson-Mårn (rchk) - chaironeko - - Vainock (ivo.lemmert) - Jonas Svensson (jonassanojj99) - TacticalKebab - Hannes Blåman (thebluis) + - dodgepong Tagalog: - dandalion - philiparniebinag @@ -872,19 +909,20 @@ Tagalog: - jbeguna04 - Red Dayao (steemitph) - Gol D. Ace (goldace) - - Vainock (ivo.lemmert) + - Vainock - Raylir Tamil: - anto27 - Gol D. Ace (goldace) - - Vainock (ivo.lemmert) + - Vainock Thai: + - Nawin Somprasong (thaipirch98) - sakuhanachan* (sakuhanachanloli) - ธีรภัทร์ โยชนา (Gataro) - Sakia Normal Human (arcanaarcana5) - 盛凤阁 (execzero) - nongnoobjung (kitcharuk_4) - - Vainock (ivo.lemmert) + - Vainock - dodgepong - Gol D. Ace (goldace) Turkish: @@ -892,48 +930,50 @@ Turkish: - omer.karagoz (mrkaragoz) - Cemal Dursun (cmldrs) - Savas Tokmak (Laserist) + - LeDoomerDoge (DoomerDoge) - Murat Karagöz (anemon_1994) - - BruhSoundeffect2 (DoomerDoge) - gecebekcisi1 - Gol D. Ace (goldace) - Umut kılıç (kilic190787) - berkcan uçan (ibnehayati) + - Vainock - Khedi + - Mustafa Arslan (mstfaa) - mustafaa - - Richard Stanway (r1ch) - Hydroboost (Hydroboost) - - Vainock (ivo.lemmert) + - Richard Stanway (r1ch) - Türker Yıldırım (turkeryildirim) + - Alican Gultekin (Vitaefinis) - chaironeko - basakbk - - Alican Gultekin (Vitaefinis) Ukrainian: - SuslikV - Юрій (Devinit) - Andy (anry025) - - Sergey (LegionAnon) + - Vainock - L1Q - - Gol D. Ace (goldace) - - Vainock (ivo.lemmert) - - Maksym Tymoshyk (maximillian_) - NoPressure - - powerdef + - Gol D. Ace (goldace) + - Maksym Tymoshyk (maximillian_) - geimfis + - powerdef - បងមាន តែអូន (cheaiphone267) + - dodgepong Urdu (Pakistan): - Rana Awais (ehtisham) - tahirsada - shamuntohamd + - Gol D. Ace (goldace) Vietnamese: - Johnny “max20091” Utah (boostyourprogram) - Hưng Nguyễn (hoyostudio) - ngoisaosang (ngoisaosang) - Drake Strike (phjtieudoc) + - IoeCmcomc (hopdaigia2004) - Gol D. Ace (goldace) - - IoeCmcomc (Ioe2015) (hopdaigia2004) - BIGO - 지혜 (parkjihye96) - Hà Phi Hùng (haphihungcom) - - Vainock (ivo.lemmert) + - Vainock - Vũ Hải Tây (tayngungo1999) - - NCAA (NCAA) - dodgepong + - NCAA (NCAA) diff --git a/CI/before-deploy-osx.sh b/CI/before-deploy-osx.sh index 2c1fd69..4bb6188 100755 --- a/CI/before-deploy-osx.sh +++ b/CI/before-deploy-osx.sh @@ -40,10 +40,18 @@ sudo install_name_tool -change \ @rpath/Frameworks/Chromium\ Embedded\ Framework.framework/Chromium\ Embedded\ Framework \ ../../Frameworks/Chromium\ Embedded\ Framework.framework/Chromium\ Embedded\ Framework \ OBS.app/Contents/Resources/obs-plugins/obs-browser.so +sudo install_name_tool -change \ + @executable_path/../Frameworks/Chromium\ Embedded\ Framework.framework/Chromium\ Embedded\ Framework \ + ../../Frameworks/Chromium\ Embedded\ Framework.framework/Chromium\ Embedded\ Framework \ + OBS.app/Contents/Resources/obs-plugins/obs-browser.so sudo install_name_tool -change \ @rpath/Frameworks/Chromium\ Embedded\ Framework.framework/Chromium\ Embedded\ Framework \ ../../Frameworks/Chromium\ Embedded\ Framework.framework/Chromium\ Embedded\ Framework \ OBS.app/Contents/Resources/obs-plugins/obs-browser-page +sudo install_name_tool -change \ + @executable_path/../Frameworks/Chromium\ Embedded\ Framework.framework/Chromium\ Embedded\ Framework \ + ../../Frameworks/Chromium\ Embedded\ Framework.framework/Chromium\ Embedded\ Framework \ + OBS.app/Contents/Resources/obs-plugins/obs-browser-page # Package app hr "Generating .pkg" diff --git a/CI/before-script-linux.sh b/CI/before-script-linux.sh index 88ba09f..e89ddb5 100755 --- a/CI/before-script-linux.sh +++ b/CI/before-script-linux.sh @@ -1,6 +1,11 @@ -#!/bin/sh -set -ex +#!/bin/bash +./formatcode.sh +if ! ./CI/check-format.sh; then + exit 1 +fi + +set -ex ccache -s || echo "CCache is not available." mkdir build && cd build cmake .. diff --git a/CI/before-script-osx.sh b/CI/before-script-osx.sh index 50a9a19..331259a 100755 --- a/CI/before-script-osx.sh +++ b/CI/before-script-osx.sh @@ -3,6 +3,11 @@ export PATH=/usr/local/opt/ccache/libexec:$PATH git fetch --tags +./formatcode.sh +if ! ./CI/check-format.sh; then + exit 1 +fi + mkdir build cd build cmake -DENABLE_SPARKLE_UPDATER=ON \ diff --git a/CI/check-format.sh b/CI/check-format.sh new file mode 100755 index 0000000..7642c19 --- /dev/null +++ b/CI/check-format.sh @@ -0,0 +1,11 @@ +#!/bin/bash +dirty=$(git ls-files --modified) + +set +x +if [[ $dirty ]]; then + echo "=================================" + echo "Files were not formatted properly" + echo "$dirty" + echo "=================================" + exit 1 +fi \ No newline at end of file diff --git a/CI/install-dependencies-linux.sh b/CI/install-dependencies-linux.sh index 4ab0219..391c181 100755 --- a/CI/install-dependencies-linux.sh +++ b/CI/install-dependencies-linux.sh @@ -3,6 +3,16 @@ set -ex sudo add-apt-repository ppa:jonathonf/ffmpeg-3 -y curl -L https://packagecloud.io/github/git-lfs/gpgkey | sudo apt-key add - + +# gets us newer clang +sudo bash -c "cat >> /etc/apt/sources.list" << LLVMAPT +# 3.8 +deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-8 main +deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial-8 main +LLVMAPT + +wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add - + sudo apt-get -qq update sudo apt-get install -y \ build-essential \ @@ -42,4 +52,5 @@ sudo apt-get install -y \ python3-dev \ qtbase5-dev \ libqt5svg5-dev \ - swig + swig \ + clang-format-8 diff --git a/CI/install-dependencies-osx.sh b/CI/install-dependencies-osx.sh index 24b8018..c37d588 100755 --- a/CI/install-dependencies-osx.sh +++ b/CI/install-dependencies-osx.sh @@ -12,6 +12,8 @@ set -v if [[ $TRAVIS ]]; then git fetch --unshallow +else + /bin/bash -c "sudo xcode-select -s /Applications/Xcode_9.4.1.app/Contents/Developer" fi # Leave obs-studio folder @@ -26,7 +28,7 @@ sudo installer -pkg ./Packages.pkg -target / brew update #Base OBS Deps and ccache -brew install jack speexdsp ccache mbedtls +brew install jack speexdsp ccache mbedtls clang-format brew install https://gist.githubusercontent.com/DDRBoxman/b3956fab6073335a4bf151db0dcbd4ad/raw/ed1342a8a86793ea8c10d8b4d712a654da121ace/qt.rb brew install https://gist.githubusercontent.com/DDRBoxman/4cada55c51803a2f963fa40ce55c9d3e/raw/572c67e908bfbc1bcb8c476ea77ea3935133f5b5/swig.rb diff --git a/CI/install-qt-win.cmd b/CI/install-qt-win.cmd index 46e14e8..e3dd99b 100644 --- a/CI/install-qt-win.cmd +++ b/CI/install-qt-win.cmd @@ -1,4 +1,4 @@ -curl -kLO https://cdn-fastly.obsproject.com/downloads/Qt_5.10.1.7z -f --retry 5 -C - +if exist Qt_5.10.1.7z (curl -kLO https://cdn-fastly.obsproject.com/downloads/Qt_5.10.1.7z -f --retry 5 -z Qt_5.10.1.7z) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/Qt_5.10.1.7z -f --retry 5 -C -) 7z x Qt_5.10.1.7z -oQt mv Qt C:\QtDep dir C:\QtDep \ No newline at end of file diff --git a/CI/install-script-win.cmd b/CI/install-script-win.cmd index a3051c3..196e0ee 100644 --- a/CI/install-script-win.cmd +++ b/CI/install-script-win.cmd @@ -1,18 +1,18 @@ if exist dependencies2017.zip (curl -kLO https://cdn-fastly.obsproject.com/downloads/dependencies2017.zip -f --retry 5 -z dependencies2017.zip) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/dependencies2017.zip -f --retry 5 -C -) if exist vlc.zip (curl -kLO https://cdn-fastly.obsproject.com/downloads/vlc.zip -f --retry 5 -z vlc.zip) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/vlc.zip -f --retry 5 -C -) -if exist cef_binary_%CEF_VERSION%_windows32.zip (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows32.zip -f --retry 5 -z cef_binary_%CEF_VERSION%_windows32.zip) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows32.zip -f --retry 5 -C -) -if exist cef_binary_%CEF_VERSION%_windows64.zip (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows64.zip -f --retry 5 -z cef_binary_%CEF_VERSION%_windows64.zip) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows64.zip -f --retry 5 -C -) +if exist cef_binary_%CEF_VERSION%_windows32_minimal.zip (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows32_minimal.zip -f --retry 5 -z cef_binary_%CEF_VERSION%_windows32_minimal.zip) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows32_minimal.zip -f --retry 5 -C -) +if exist cef_binary_%CEF_VERSION%_windows64_minimal.zip (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows64_minimal.zip -f --retry 5 -z cef_binary_%CEF_VERSION%_windows64_minimal.zip) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows64_minimal.zip -f --retry 5 -C -) 7z x dependencies2017.zip -odependencies2017 7z x vlc.zip -ovlc -7z x cef_binary_%CEF_VERSION%_windows32.zip -oCEF_32 -7z x cef_binary_%CEF_VERSION%_windows64.zip -oCEF_64 +7z x cef_binary_%CEF_VERSION%_windows32_minimal.zip -oCEF_32 +7z x cef_binary_%CEF_VERSION%_windows64_minimal.zip -oCEF_64 set DepsPath32=%CD%\dependencies2017\win32 set DepsPath64=%CD%\dependencies2017\win64 set VLCPath=%CD%\vlc set QTDIR32=C:\QtDep\5.10.1\msvc2017 set QTDIR64=C:\QtDep\5.10.1\msvc2017_64 -set CEF_32=%CD%\CEF_32\cef_binary_%CEF_VERSION%_windows32 -set CEF_64=%CD%\CEF_64\cef_binary_%CEF_VERSION%_windows64 +set CEF_32=%CD%\CEF_32\cef_binary_%CEF_VERSION%_windows32_minimal +set CEF_64=%CD%\CEF_64\cef_binary_%CEF_VERSION%_windows64_minimal set build_config=RelWithDebInfo mkdir build build32 build64 if "%TWITCH-CLIENTID%"=="$(twitch_clientid)" ( diff --git a/CMakeLists.txt b/CMakeLists.txt index 47dadab..71f302b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ endif() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") set(ENABLE_SCRIPTING TRUE CACHE BOOL "Enables scripting") -set(SCRIPTING_ENABLED OFF CACHE BOOL "Interal global cmake variable" FORCE) +set(SCRIPTING_ENABLED OFF CACHE BOOL "Internal global cmake variable" FORCE) include(ObsHelpers) include(ObsCpack) diff --git a/UI/CMakeLists.txt b/UI/CMakeLists.txt index ac54110..a33f9e1 100644 --- a/UI/CMakeLists.txt +++ b/UI/CMakeLists.txt @@ -146,10 +146,14 @@ if(BROWSER_AVAILABLE_INTERNAL) list(APPEND obs_PLATFORM_SOURCES obf.c auth-oauth.cpp + window-dock-browser.cpp + window-extra-browsers.cpp ) list(APPEND obs_PLATFORM_HEADERS obf.h auth-oauth.hpp + window-dock-browser.hpp + window-extra-browsers.hpp ) if(TWITCH_ENABLED) @@ -192,6 +196,9 @@ if(MSVC) ../deps/libff/libff/ff-util.c PROPERTIES COMPILE_FLAGS -Dinline=__inline ) + set(obs_PLATFORM_LIBRARIES + ${obs_PLATFORM_LIBRARIES} + w32-pthreads) endif() set(obs_SOURCES @@ -235,6 +242,7 @@ set(obs_SOURCES slider-ignorewheel.cpp combobox-ignorewheel.cpp spinbox-ignorewheel.cpp + record-button.cpp volume-control.cpp adv-audio-control.cpp item-widget-helpers.cpp @@ -289,6 +297,7 @@ set(obs_HEADERS focus-list.hpp menu-button.hpp mute-checkbox.hpp + record-button.hpp volume-control.hpp adv-audio-control.hpp item-widget-helpers.hpp @@ -322,6 +331,7 @@ set(obs_UI forms/OBSBasicSettings.ui forms/OBSBasicSourceSelect.ui forms/OBSBasicInteraction.ui + forms/OBSExtraBrowsers.ui forms/OBSUpdate.ui forms/OBSRemux.ui forms/OBSAbout.ui) diff --git a/UI/adv-audio-control.cpp b/UI/adv-audio-control.cpp index db97504..6182a37 100644 --- a/UI/adv-audio-control.cpp +++ b/UI/adv-audio-control.cpp @@ -26,34 +26,34 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) uint32_t flags = obs_source_get_flags(source); uint32_t mixers = obs_source_get_audio_mixers(source); - forceMonoContainer = new QWidget(); - mixerContainer = new QWidget(); - balanceContainer = new QWidget(); - labelL = new QLabel(); - labelR = new QLabel(); - nameLabel = new QLabel(); - volume = new QDoubleSpinBox(); - forceMono = new QCheckBox(); - balance = new BalanceSlider(); + forceMonoContainer = new QWidget(); + mixerContainer = new QWidget(); + balanceContainer = new QWidget(); + labelL = new QLabel(); + labelR = new QLabel(); + nameLabel = new QLabel(); + volume = new QDoubleSpinBox(); + forceMono = new QCheckBox(); + balance = new BalanceSlider(); #if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO - monitoringType = new QComboBox(); + monitoringType = new QComboBox(); #endif - syncOffset = new QSpinBox(); - mixer1 = new QCheckBox(); - mixer2 = new QCheckBox(); - mixer3 = new QCheckBox(); - mixer4 = new QCheckBox(); - mixer5 = new QCheckBox(); - mixer6 = new QCheckBox(); + syncOffset = new QSpinBox(); + mixer1 = new QCheckBox(); + mixer2 = new QCheckBox(); + mixer3 = new QCheckBox(); + mixer4 = new QCheckBox(); + mixer5 = new QCheckBox(); + mixer6 = new QCheckBox(); volChangedSignal.Connect(handler, "volume", OBSSourceVolumeChanged, - this); + this); syncOffsetSignal.Connect(handler, "audio_sync", OBSSourceSyncChanged, - this); + this); flagsSignal.Connect(handler, "update_flags", OBSSourceFlagsChanged, - this); + this); mixersSignal.Connect(handler, "audio_mixers", OBSSourceMixersChanged, - this); + this); hlayout = new QHBoxLayout(); hlayout->setContentsMargins(0, 0, 0, 0); @@ -64,15 +64,14 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) hlayout = new QHBoxLayout(); hlayout->setContentsMargins(0, 0, 0, 0); balanceContainer->setLayout(hlayout); - balanceContainer->setMinimumWidth(100); + balanceContainer->setFixedWidth(150); labelL->setText("L"); labelR->setText("R"); - nameLabel->setMinimumWidth(170); nameLabel->setText(QT_UTF8(sourceName)); - nameLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + nameLabel->setAlignment(Qt::AlignVCenter); volume->setMinimum(MIN_DB - 0.1); volume->setMaximum(MAX_DB); @@ -80,6 +79,7 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) volume->setDecimals(1); volume->setSuffix(" dB"); volume->setValue(obs_mul_to_db(vol)); + volume->setFixedWidth(100); if (volume->value() < MIN_DB) volume->setSpecialValueText("-inf dB"); @@ -87,8 +87,8 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) forceMono->setChecked((flags & OBS_SOURCE_FLAG_FORCE_MONO) != 0); forceMonoContainer->layout()->addWidget(forceMono); - forceMonoContainer->layout()->setAlignment(forceMono, - Qt::AlignHCenter | Qt::AlignVCenter); + forceMonoContainer->layout()->setAlignment(forceMono, Qt::AlignVCenter); + forceMonoContainer->setFixedWidth(50); balance->setOrientation(Qt::Horizontal); balance->setMinimum(0); @@ -96,10 +96,10 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) balance->setTickPosition(QSlider::TicksAbove); balance->setTickInterval(50); - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); - const char *speakers = config_get_string(main->Config(), "Audio", - "ChannelSetup"); + const char *speakers = + config_get_string(main->Config(), "Audio", "ChannelSetup"); if (strcmp(speakers, "Mono") == 0) balance->setEnabled(false); @@ -112,36 +112,38 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) int64_t cur_sync = obs_source_get_sync_offset(source); syncOffset->setMinimum(-950); syncOffset->setMaximum(20000); + syncOffset->setSuffix(" ms"); syncOffset->setValue(int(cur_sync / NSEC_PER_MSEC)); + syncOffset->setFixedWidth(100); int idx; #if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.None"), - (int)OBS_MONITORING_TYPE_NONE); + (int)OBS_MONITORING_TYPE_NONE); monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.MonitorOnly"), - (int)OBS_MONITORING_TYPE_MONITOR_ONLY); + (int)OBS_MONITORING_TYPE_MONITOR_ONLY); monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.Both"), - (int)OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT); + (int)OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT); int mt = (int)obs_source_get_monitoring_type(source); idx = monitoringType->findData(mt); monitoringType->setCurrentIndex(idx); #endif mixer1->setText("1"); - mixer1->setChecked(mixers & (1<<0)); + mixer1->setChecked(mixers & (1 << 0)); mixer2->setText("2"); - mixer2->setChecked(mixers & (1<<1)); + mixer2->setChecked(mixers & (1 << 1)); mixer3->setText("3"); - mixer3->setChecked(mixers & (1<<2)); + mixer3->setChecked(mixers & (1 << 2)); mixer4->setText("4"); - mixer4->setChecked(mixers & (1<<3)); + mixer4->setChecked(mixers & (1 << 3)); mixer5->setText("5"); - mixer5->setChecked(mixers & (1<<4)); + mixer5->setChecked(mixers & (1 << 4)); mixer6->setText("6"); - mixer6->setChecked(mixers & (1<<5)); + mixer6->setChecked(mixers & (1 << 5)); speaker_layout sl = obs_source_get_speaker_layout(source); - + if (sl == SPEAKERS_STEREO) { balanceContainer->layout()->addWidget(labelL); balanceContainer->layout()->addWidget(balance); @@ -156,32 +158,32 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) mixerContainer->layout()->addWidget(mixer5); mixerContainer->layout()->addWidget(mixer6); - QWidget::connect(volume, SIGNAL(valueChanged(double)), - this, SLOT(volumeChanged(double))); - QWidget::connect(forceMono, SIGNAL(clicked(bool)), - this, SLOT(downmixMonoChanged(bool))); - QWidget::connect(balance, SIGNAL(valueChanged(int)), - this, SLOT(balanceChanged(int))); - QWidget::connect(balance, SIGNAL(doubleClicked()), - this, SLOT(ResetBalance())); - QWidget::connect(syncOffset, SIGNAL(valueChanged(int)), - this, SLOT(syncOffsetChanged(int))); + QWidget::connect(volume, SIGNAL(valueChanged(double)), this, + SLOT(volumeChanged(double))); + QWidget::connect(forceMono, SIGNAL(clicked(bool)), this, + SLOT(downmixMonoChanged(bool))); + QWidget::connect(balance, SIGNAL(valueChanged(int)), this, + SLOT(balanceChanged(int))); + QWidget::connect(balance, SIGNAL(doubleClicked()), this, + SLOT(ResetBalance())); + QWidget::connect(syncOffset, SIGNAL(valueChanged(int)), this, + SLOT(syncOffsetChanged(int))); #if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO - QWidget::connect(monitoringType, SIGNAL(currentIndexChanged(int)), - this, SLOT(monitoringTypeChanged(int))); + QWidget::connect(monitoringType, SIGNAL(currentIndexChanged(int)), this, + SLOT(monitoringTypeChanged(int))); #endif - QWidget::connect(mixer1, SIGNAL(clicked(bool)), - this, SLOT(mixer1Changed(bool))); - QWidget::connect(mixer2, SIGNAL(clicked(bool)), - this, SLOT(mixer2Changed(bool))); - QWidget::connect(mixer3, SIGNAL(clicked(bool)), - this, SLOT(mixer3Changed(bool))); - QWidget::connect(mixer4, SIGNAL(clicked(bool)), - this, SLOT(mixer4Changed(bool))); - QWidget::connect(mixer5, SIGNAL(clicked(bool)), - this, SLOT(mixer5Changed(bool))); - QWidget::connect(mixer6, SIGNAL(clicked(bool)), - this, SLOT(mixer6Changed(bool))); + QWidget::connect(mixer1, SIGNAL(clicked(bool)), this, + SLOT(mixer1Changed(bool))); + QWidget::connect(mixer2, SIGNAL(clicked(bool)), this, + SLOT(mixer2Changed(bool))); + QWidget::connect(mixer3, SIGNAL(clicked(bool)), this, + SLOT(mixer3Changed(bool))); + QWidget::connect(mixer4, SIGNAL(clicked(bool)), this, + SLOT(mixer4Changed(bool))); + QWidget::connect(mixer5, SIGNAL(clicked(bool)), this, + SLOT(mixer5Changed(bool))); + QWidget::connect(mixer6, SIGNAL(clicked(bool)), this, + SLOT(mixer6Changed(bool))); setObjectName(sourceName); } @@ -213,8 +215,8 @@ void OBSAdvAudioCtrl::ShowAudioControl(QGridLayout *layout) layout->addWidget(monitoringType, lastRow, idx++); #endif layout->addWidget(mixerContainer, lastRow, idx++); - layout->layout()->setAlignment(mixerContainer, - Qt::AlignHCenter | Qt::AlignVCenter); + layout->layout()->setAlignment(mixerContainer, Qt::AlignVCenter); + layout->setHorizontalSpacing(15); } /* ------------------------------------------------------------------------- */ @@ -223,30 +225,30 @@ void OBSAdvAudioCtrl::ShowAudioControl(QGridLayout *layout) void OBSAdvAudioCtrl::OBSSourceFlagsChanged(void *param, calldata_t *calldata) { uint32_t flags = (uint32_t)calldata_int(calldata, "flags"); - QMetaObject::invokeMethod(reinterpret_cast(param), - "SourceFlagsChanged", Q_ARG(uint32_t, flags)); - + QMetaObject::invokeMethod(reinterpret_cast(param), + "SourceFlagsChanged", Q_ARG(uint32_t, flags)); } void OBSAdvAudioCtrl::OBSSourceVolumeChanged(void *param, calldata_t *calldata) { float volume = (float)calldata_float(calldata, "volume"); - QMetaObject::invokeMethod(reinterpret_cast(param), - "SourceVolumeChanged", Q_ARG(float, volume)); + QMetaObject::invokeMethod(reinterpret_cast(param), + "SourceVolumeChanged", Q_ARG(float, volume)); } void OBSAdvAudioCtrl::OBSSourceSyncChanged(void *param, calldata_t *calldata) { int64_t offset = calldata_int(calldata, "offset"); - QMetaObject::invokeMethod(reinterpret_cast(param), - "SourceSyncChanged", Q_ARG(int64_t, offset)); + QMetaObject::invokeMethod(reinterpret_cast(param), + "SourceSyncChanged", Q_ARG(int64_t, offset)); } void OBSAdvAudioCtrl::OBSSourceMixersChanged(void *param, calldata_t *calldata) { uint32_t mixers = (uint32_t)calldata_int(calldata, "mixers"); - QMetaObject::invokeMethod(reinterpret_cast(param), - "SourceMixersChanged", Q_ARG(uint32_t, mixers)); + QMetaObject::invokeMethod(reinterpret_cast(param), + "SourceMixersChanged", + Q_ARG(uint32_t, mixers)); } /* ------------------------------------------------------------------------- */ @@ -279,12 +281,12 @@ void OBSAdvAudioCtrl::SourceSyncChanged(int64_t offset) void OBSAdvAudioCtrl::SourceMixersChanged(uint32_t mixers) { - setCheckboxState(mixer1, mixers & (1<<0)); - setCheckboxState(mixer2, mixers & (1<<1)); - setCheckboxState(mixer3, mixers & (1<<2)); - setCheckboxState(mixer4, mixers & (1<<3)); - setCheckboxState(mixer5, mixers & (1<<4)); - setCheckboxState(mixer6, mixers & (1<<5)); + setCheckboxState(mixer1, mixers & (1 << 0)); + setCheckboxState(mixer2, mixers & (1 << 1)); + setCheckboxState(mixer3, mixers & (1 << 2)); + setCheckboxState(mixer4, mixers & (1 << 3)); + setCheckboxState(mixer5, mixers & (1 << 4)); + setCheckboxState(mixer6, mixers & (1 << 5)); } /* ------------------------------------------------------------------------- */ @@ -335,14 +337,13 @@ void OBSAdvAudioCtrl::ResetBalance() balance->setValue(50); } - void OBSAdvAudioCtrl::syncOffsetChanged(int milliseconds) { int64_t cur_val = obs_source_get_sync_offset(source); if (cur_val / NSEC_PER_MSEC != milliseconds) - obs_source_set_sync_offset(source, - int64_t(milliseconds) * NSEC_PER_MSEC); + obs_source_set_sync_offset(source, int64_t(milliseconds) * + NSEC_PER_MSEC); } void OBSAdvAudioCtrl::monitoringTypeChanged(int index) @@ -365,17 +366,19 @@ void OBSAdvAudioCtrl::monitoringTypeChanged(int index) } blog(LOG_INFO, "User changed audio monitoring for source '%s' to: %s", - obs_source_get_name(source), type); + obs_source_get_name(source), type); } static inline void setMixer(obs_source_t *source, const int mixerIdx, - const bool checked) + const bool checked) { uint32_t mixers = obs_source_get_audio_mixers(source); uint32_t new_mixers = mixers; - if (checked) new_mixers |= (1< forceMonoContainer; - QPointer mixerContainer; - QPointer balanceContainer; + QPointer forceMonoContainer; + QPointer mixerContainer; + QPointer balanceContainer; - QPointer nameLabel; + QPointer nameLabel; QPointer volume; - QPointer forceMono; - QPointerbalance; - QPointer labelL; - QPointer labelR; - QPointer syncOffset; - QPointer monitoringType; - QPointer mixer1; - QPointer mixer2; - QPointer mixer3; - QPointer mixer4; - QPointer mixer5; - QPointer mixer6; + QPointer forceMono; + QPointer balance; + QPointer labelL; + QPointer labelR; + QPointer syncOffset; + QPointer monitoringType; + QPointer mixer1; + QPointer mixer2; + QPointer mixer3; + QPointer mixer4; + QPointer mixer5; + QPointer mixer6; - OBSSignal volChangedSignal; - OBSSignal syncOffsetSignal; - OBSSignal flagsSignal; - OBSSignal mixersSignal; + OBSSignal volChangedSignal; + OBSSignal syncOffsetSignal; + OBSSignal flagsSignal; + OBSSignal mixersSignal; static void OBSSourceFlagsChanged(void *param, calldata_t *calldata); static void OBSSourceVolumeChanged(void *param, calldata_t *calldata); @@ -51,7 +51,7 @@ public: OBSAdvAudioCtrl(QGridLayout *layout, obs_source_t *source_); virtual ~OBSAdvAudioCtrl(); - inline obs_source_t *GetSource() const {return source;} + inline obs_source_t *GetSource() const { return source; } void ShowAudioControl(QGridLayout *layout); public slots: diff --git a/UI/api-interface.cpp b/UI/api-interface.cpp index c69b3ef..0d928ac 100644 --- a/UI/api-interface.cpp +++ b/UI/api-interface.cpp @@ -11,17 +11,17 @@ using namespace std; Q_DECLARE_METATYPE(OBSScene); Q_DECLARE_METATYPE(OBSSource); -template -static T GetOBSRef(QListWidgetItem *item) +template static T GetOBSRef(QListWidgetItem *item) { return item->data(static_cast(QtDataRole::OBSRef)).value(); } -void EnumProfiles(function &&cb); -void EnumSceneCollections(function &&cb); +void EnumProfiles(function &&cb); +void EnumSceneCollections(function &&cb); extern volatile bool streaming_active; extern volatile bool recording_active; +extern volatile bool recording_paused; extern volatile bool replaybuf_active; /* ------------------------------------------------------------------------- */ @@ -30,18 +30,18 @@ template struct OBSStudioCallback { T callback; void *private_data; - inline OBSStudioCallback(T cb, void *p) : - callback(cb), private_data(p) - {} + inline OBSStudioCallback(T cb, void *p) : callback(cb), private_data(p) + { + } }; -template inline size_t GetCallbackIdx( - vector> &callbacks, - T callback, void *private_data) +template +inline size_t GetCallbackIdx(vector> &callbacks, + T callback, void *private_data) { for (size_t i = 0; i < callbacks.size(); i++) { OBSStudioCallback curCB = callbacks[i]; - if (curCB.callback == callback && + if (curCB.callback == callback && curCB.private_data == private_data) return i; } @@ -59,21 +59,21 @@ struct OBSStudioAPI : obs_frontend_callbacks { void *obs_frontend_get_main_window(void) override { - return (void*)main; + return (void *)main; } void *obs_frontend_get_main_window_handle(void) override { - return (void*)main->winId(); + return (void *)main->winId(); } void *obs_frontend_get_system_tray(void) override { - return (void*)main->trayIcon.data(); + return (void *)main->trayIcon.data(); } void obs_frontend_get_scenes( - struct obs_frontend_source_list *sources) override + struct obs_frontend_source_list *sources) override { for (int i = 0; i < main->ui->scenes->count(); i++) { QListWidgetItem *item = main->ui->scenes->item(i); @@ -101,23 +101,23 @@ struct OBSStudioAPI : obs_frontend_callbacks { void obs_frontend_set_current_scene(obs_source_t *scene) override { if (main->IsPreviewProgramMode()) { - QMetaObject::invokeMethod(main, "TransitionToScene", - WaitConnection(), - Q_ARG(OBSSource, OBSSource(scene))); + QMetaObject::invokeMethod( + main, "TransitionToScene", WaitConnection(), + Q_ARG(OBSSource, OBSSource(scene))); } else { - QMetaObject::invokeMethod(main, "SetCurrentScene", - WaitConnection(), - Q_ARG(OBSSource, OBSSource(scene)), - Q_ARG(bool, false)); + QMetaObject::invokeMethod( + main, "SetCurrentScene", WaitConnection(), + Q_ARG(OBSSource, OBSSource(scene)), + Q_ARG(bool, false)); } } void obs_frontend_get_transitions( - struct obs_frontend_source_list *sources) override + struct obs_frontend_source_list *sources) override { for (int i = 0; i < main->ui->transitions->count(); i++) { OBSSource tr = main->ui->transitions->itemData(i) - .value(); + .value(); obs_source_addref(tr); da_push_back(sources->sources, &tr); @@ -132,11 +132,12 @@ struct OBSStudioAPI : obs_frontend_callbacks { return tr; } - void obs_frontend_set_current_transition( - obs_source_t *transition) override + void + obs_frontend_set_current_transition(obs_source_t *transition) override { QMetaObject::invokeMethod(main, "SetTransition", - Q_ARG(OBSSource, OBSSource(transition))); + Q_ARG(OBSSource, + OBSSource(transition))); } int obs_frontend_get_transition_duration(void) override @@ -146,15 +147,14 @@ struct OBSStudioAPI : obs_frontend_callbacks { void obs_frontend_set_transition_duration(int duration) override { - QMetaObject::invokeMethod(main->ui->transitionDuration, "setValue", - Q_ARG(int, duration)); + QMetaObject::invokeMethod(main->ui->transitionDuration, + "setValue", Q_ARG(int, duration)); } void obs_frontend_get_scene_collections( - std::vector &strings) override + std::vector &strings) override { - auto addCollection = [&](const char *name, const char *) - { + auto addCollection = [&](const char *name, const char *) { strings.emplace_back(name); return true; }; @@ -164,15 +164,15 @@ struct OBSStudioAPI : obs_frontend_callbacks { char *obs_frontend_get_current_scene_collection(void) override { - const char *cur_name = config_get_string(App()->GlobalConfig(), - "Basic", "SceneCollection"); + const char *cur_name = config_get_string( + App()->GlobalConfig(), "Basic", "SceneCollection"); return bstrdup(cur_name); } void obs_frontend_set_current_scene_collection( - const char *collection) override + const char *collection) override { - QList menuActions = + QList menuActions = main->ui->sceneCollectionMenu->actions(); QString qstrCollection = QT_UTF8(collection); @@ -189,24 +189,21 @@ struct OBSStudioAPI : obs_frontend_callbacks { } } - bool obs_frontend_add_scene_collection( - const char *name) override + bool obs_frontend_add_scene_collection(const char *name) override { bool success = false; - QMetaObject::invokeMethod(main, - "AddSceneCollection", - WaitConnection(), - Q_RETURN_ARG(bool, success), - Q_ARG(bool, true), - Q_ARG(QString, QT_UTF8(name))); + QMetaObject::invokeMethod(main, "AddSceneCollection", + WaitConnection(), + Q_RETURN_ARG(bool, success), + Q_ARG(bool, true), + Q_ARG(QString, QT_UTF8(name))); return success; } - void obs_frontend_get_profiles( - std::vector &strings) override + void + obs_frontend_get_profiles(std::vector &strings) override { - auto addProfile = [&](const char *name, const char *) - { + auto addProfile = [&](const char *name, const char *) { strings.emplace_back(name); return true; }; @@ -217,14 +214,13 @@ struct OBSStudioAPI : obs_frontend_callbacks { char *obs_frontend_get_current_profile(void) override { const char *name = config_get_string(App()->GlobalConfig(), - "Basic", "Profile"); + "Basic", "Profile"); return bstrdup(name); } void obs_frontend_set_current_profile(const char *profile) override { - QList menuActions = - main->ui->profileMenu->actions(); + QList menuActions = main->ui->profileMenu->actions(); QString qstrProfile = QT_UTF8(profile); for (int i = 0; i < menuActions.count(); i++) { @@ -270,6 +266,17 @@ struct OBSStudioAPI : obs_frontend_callbacks { return os_atomic_load_bool(&recording_active); } + void obs_frontend_recording_pause(bool pause) override + { + QMetaObject::invokeMethod(main, pause ? "PauseRecording" + : "UnpauseRecording"); + } + + bool obs_frontend_recording_paused(void) override + { + return os_atomic_load_bool(&recording_paused); + } + void obs_frontend_replay_buffer_start(void) override { QMetaObject::invokeMethod(main, "StartReplayBuffer"); @@ -293,16 +300,16 @@ struct OBSStudioAPI : obs_frontend_callbacks { void *obs_frontend_add_tools_menu_qaction(const char *name) override { main->ui->menuTools->setEnabled(true); - return (void*)main->ui->menuTools->addAction(QT_UTF8(name)); + return (void *)main->ui->menuTools->addAction(QT_UTF8(name)); } void obs_frontend_add_tools_menu_item(const char *name, - obs_frontend_cb callback, void *private_data) override + obs_frontend_cb callback, + void *private_data) override { main->ui->menuTools->setEnabled(true); - auto func = [private_data, callback] () - { + auto func = [private_data, callback]() { callback(private_data); }; @@ -312,11 +319,11 @@ struct OBSStudioAPI : obs_frontend_callbacks { void *obs_frontend_add_dock(void *dock) override { - return (void*)main->AddDockWidget((QDockWidget *)dock); + return (void *)main->AddDockWidget((QDockWidget *)dock); } void obs_frontend_add_event_callback(obs_frontend_event_cb callback, - void *private_data) override + void *private_data) override { size_t idx = GetCallbackIdx(callbacks, callback, private_data); if (idx == (size_t)-1) @@ -324,7 +331,7 @@ struct OBSStudioAPI : obs_frontend_callbacks { } void obs_frontend_remove_event_callback(obs_frontend_event_cb callback, - void *private_data) override + void *private_data) override { size_t idx = GetCallbackIdx(callbacks, callback, private_data); if (idx == (size_t)-1) @@ -364,10 +371,7 @@ struct OBSStudioAPI : obs_frontend_callbacks { return App()->GlobalConfig(); } - void obs_frontend_save(void) override - { - main->SaveProject(); - } + void obs_frontend_save(void) override { main->SaveProject(); } void obs_frontend_defer_save_begin(void) override { @@ -380,19 +384,19 @@ struct OBSStudioAPI : obs_frontend_callbacks { } void obs_frontend_add_save_callback(obs_frontend_save_cb callback, - void *private_data) override + void *private_data) override { - size_t idx = GetCallbackIdx(saveCallbacks, callback, - private_data); + size_t idx = + GetCallbackIdx(saveCallbacks, callback, private_data); if (idx == (size_t)-1) saveCallbacks.emplace_back(callback, private_data); } void obs_frontend_remove_save_callback(obs_frontend_save_cb callback, - void *private_data) override + void *private_data) override { - size_t idx = GetCallbackIdx(saveCallbacks, callback, - private_data); + size_t idx = + GetCallbackIdx(saveCallbacks, callback, private_data); if (idx == (size_t)-1) return; @@ -400,19 +404,19 @@ struct OBSStudioAPI : obs_frontend_callbacks { } void obs_frontend_add_preload_callback(obs_frontend_save_cb callback, - void *private_data) override + void *private_data) override { size_t idx = GetCallbackIdx(preloadCallbacks, callback, - private_data); + private_data); if (idx == (size_t)-1) preloadCallbacks.emplace_back(callback, private_data); } void obs_frontend_remove_preload_callback(obs_frontend_save_cb callback, - void *private_data) override + void *private_data) override { size_t idx = GetCallbackIdx(preloadCallbacks, callback, - private_data); + private_data); if (idx == (size_t)-1) return; @@ -420,7 +424,7 @@ struct OBSStudioAPI : obs_frontend_callbacks { } void obs_frontend_push_ui_translation( - obs_frontend_translate_ui_cb translate) override + obs_frontend_translate_ui_cb translate) override { App()->PushUITranslation(translate); } @@ -483,12 +487,14 @@ struct OBSStudioAPI : obs_frontend_callbacks { return source; } - void obs_frontend_set_current_preview_scene(obs_source_t *scene) override + void + obs_frontend_set_current_preview_scene(obs_source_t *scene) override { if (main->IsPreviewProgramMode()) { QMetaObject::invokeMethod(main, "SetCurrentScene", - Q_ARG(OBSSource, OBSSource(scene)), - Q_ARG(bool, false)); + Q_ARG(OBSSource, + OBSSource(scene)), + Q_ARG(bool, false)); } } diff --git a/UI/audio-encoders.cpp b/UI/audio-encoders.cpp index 1e0805d..bc94f8e 100644 --- a/UI/audio-encoders.cpp +++ b/UI/audio-encoders.cpp @@ -32,7 +32,7 @@ static const char *EncoderName(const char *id) return NullToEmpty(obs_encoder_get_display_name(id)); } -static map bitrateMap; +static map bitrateMap; static once_flag populateBitrateMap; static void HandleIntProperty(obs_property_t *prop, const char *id) @@ -48,10 +48,11 @@ static void HandleListProperty(obs_property_t *prop, const char *id) { obs_combo_format format = obs_property_list_format(prop); if (format != OBS_COMBO_FORMAT_INT) { - blog(LOG_ERROR, "Encoder '%s' (%s) returned bitrate " - "OBS_PROPERTY_LIST property of unhandled " - "format %d", - EncoderName(id), id, static_cast(format)); + blog(LOG_ERROR, + "Encoder '%s' (%s) returned bitrate " + "OBS_PROPERTY_LIST property of unhandled " + "format %d", + EncoderName(id), id, static_cast(format)); return; } @@ -60,38 +61,35 @@ static void HandleListProperty(obs_property_t *prop, const char *id) if (obs_property_list_item_disabled(prop, i)) continue; - int bitrate = static_cast( - obs_property_list_item_int(prop, i)); + int bitrate = + static_cast(obs_property_list_item_int(prop, i)); bitrateMap[bitrate] = id; } } -static void HandleSampleRate(obs_property_t* prop, const char *id) +static void HandleSampleRate(obs_property_t *prop, const char *id) { - auto ReleaseData = [](obs_data_t *data) - { - obs_data_release(data); - }; + auto ReleaseData = [](obs_data_t *data) { obs_data_release(data); }; std::unique_ptr data{ - obs_encoder_defaults(id), - ReleaseData}; + obs_encoder_defaults(id), ReleaseData}; if (!data) { - blog(LOG_ERROR, "Failed to get defaults for encoder '%s' (%s) " - "while populating bitrate map", - EncoderName(id), id); + blog(LOG_ERROR, + "Failed to get defaults for encoder '%s' (%s) " + "while populating bitrate map", + EncoderName(id), id); return; } - auto main = reinterpret_cast(App()->GetMainWindow()); + auto main = reinterpret_cast(App()->GetMainWindow()); if (!main) { blog(LOG_ERROR, "Failed to get main window while populating " "bitrate map"); return; } - uint32_t sampleRate = config_get_uint(main->Config(), "Audio", - "SampleRate"); + uint32_t sampleRate = + config_get_uint(main->Config(), "Audio", "SampleRate"); obs_data_set_int(data.get(), "samplerate", sampleRate); @@ -100,23 +98,22 @@ static void HandleSampleRate(obs_property_t* prop, const char *id) static void HandleEncoderProperties(const char *id) { - auto DestroyProperties = [](obs_properties_t *props) - { + auto DestroyProperties = [](obs_properties_t *props) { obs_properties_destroy(props); }; std::unique_ptr props{ - obs_get_encoder_properties(id), - DestroyProperties}; + obs_get_encoder_properties(id), DestroyProperties}; if (!props) { - blog(LOG_ERROR, "Failed to get properties for encoder " - "'%s' (%s)", - EncoderName(id), id); + blog(LOG_ERROR, + "Failed to get properties for encoder " + "'%s' (%s)", + EncoderName(id), id); return; } - obs_property_t *samplerate = obs_properties_get(props.get(), - "samplerate"); + obs_property_t *samplerate = + obs_properties_get(props.get(), "samplerate"); if (samplerate) HandleSampleRate(samplerate, id); @@ -130,12 +127,14 @@ static void HandleEncoderProperties(const char *id) case OBS_PROPERTY_LIST: return HandleListProperty(bitrate, id); - default: break; + default: + break; } - blog(LOG_ERROR, "Encoder '%s' (%s) returned bitrate property " - "of unhandled type %d", EncoderName(id), id, - static_cast(type)); + blog(LOG_ERROR, + "Encoder '%s' (%s) returned bitrate property " + "of unhandled type %d", + EncoderName(id), id, static_cast(type)); } static const char *GetCodec(const char *id) @@ -146,8 +145,7 @@ static const char *GetCodec(const char *id) static const string aac_ = "AAC"; static void PopulateBitrateMap() { - call_once(populateBitrateMap, []() - { + call_once(populateBitrateMap, []() { struct obs_audio_info aoi; obs_get_audio_info(&aoi); uint32_t output_channels = get_audio_channels(aoi.speakers); @@ -156,13 +154,12 @@ static void PopulateBitrateMap() const char *id = nullptr; for (size_t i = 0; obs_enum_encoder_types(i, &id); i++) { - auto Compare = [=](const string &val) - { + auto Compare = [=](const string &val) { return val == NullToEmpty(id); }; if (find_if(begin(encoders), end(encoders), Compare) != - end(encoders)) + end(encoders)) continue; if (aac_ != GetCodec(id)) @@ -198,11 +195,11 @@ static void PopulateBitrateMap() << entry.second << ')'; blog(LOG_DEBUG, "AAC encoder bitrate mapping:%s", - ss.str().c_str()); + ss.str().c_str()); }); } -const map &GetAACEncoderBitrateMap() +const map &GetAACEncoderBitrateMap() { PopulateBitrateMap(); return bitrateMap; diff --git a/UI/audio-encoders.hpp b/UI/audio-encoders.hpp index 7bbde42..e1aba65 100644 --- a/UI/audio-encoders.hpp +++ b/UI/audio-encoders.hpp @@ -4,6 +4,6 @@ #include -const std::map &GetAACEncoderBitrateMap(); +const std::map &GetAACEncoderBitrateMap(); const char *GetAACEncoderForBitrate(int bitrate); int FindClosestAvailableAACBitrate(int bitrate); diff --git a/UI/auth-base.cpp b/UI/auth-base.cpp index 6a6bcfc..89c30e2 100644 --- a/UI/auth-base.cpp +++ b/UI/auth-base.cpp @@ -43,7 +43,8 @@ void Auth::Load() { OBSBasic *main = OBSBasic::Get(); const char *typeStr = config_get_string(main->Config(), "Auth", "Type"); - if (!typeStr) typeStr = ""; + if (!typeStr) + typeStr = ""; main->auth = Create(typeStr); if (main->auth) { diff --git a/UI/auth-base.hpp b/UI/auth-base.hpp index 8e04ec1..f683ce1 100644 --- a/UI/auth-base.hpp +++ b/UI/auth-base.hpp @@ -8,8 +8,8 @@ class Auth : public QObject { Q_OBJECT protected: - virtual void SaveInternal()=0; - virtual bool LoadInternal()=0; + virtual void SaveInternal() = 0; + virtual bool LoadInternal() = 0; bool firstLoad = true; @@ -19,13 +19,14 @@ protected: ErrorInfo(std::string message_, std::string error_) : message(message_), error(error_) - {} + { + } }; public: enum class Type { None, - OAuth_StreamKey + OAuth_StreamKey, }; struct Def { @@ -33,13 +34,13 @@ public: Type type; }; - typedef std::function ()> create_cb; + typedef std::function()> create_cb; inline Auth(const Def &d) : def(d) {} virtual ~Auth() {} - inline Type type() const {return def.type;} - inline const char *service() const {return def.service.c_str();} + inline Type type() const { return def.type; } + inline const char *service() const { return def.service.c_str(); } virtual void LoadUI() {} diff --git a/UI/auth-mixer.cpp b/UI/auth-mixer.cpp index dc2cb5b..c30cbcd 100644 --- a/UI/auth-mixer.cpp +++ b/UI/auth-mixer.cpp @@ -7,9 +7,9 @@ #include #include +#include "window-dock-browser.hpp" #include "window-basic-main.hpp" #include "remote-text.hpp" -#include "window-dock.hpp" #include @@ -20,30 +20,18 @@ using namespace json11; -#include -extern QCef *cef; -extern QCefCookieManager *panel_cookies; - /* ------------------------------------------------------------------------- */ -#define MIXER_AUTH_URL \ - "https://obsproject.com/app-auth/mixer?action=redirect" -#define MIXER_TOKEN_URL \ - "https://obsproject.com/app-auth/mixer-token" +#define MIXER_AUTH_URL "https://obsproject.com/app-auth/mixer?action=redirect" +#define MIXER_TOKEN_URL "https://obsproject.com/app-auth/mixer-token" #define MIXER_SCOPE_VERSION 1 -static Auth::Def mixerDef = { - "Mixer", - Auth::Type::OAuth_StreamKey -}; +static Auth::Def mixerDef = {"Mixer", Auth::Type::OAuth_StreamKey}; /* ------------------------------------------------------------------------- */ -MixerAuth::MixerAuth(const Def &d) - : OAuthStreamKey(d) -{ -} +MixerAuth::MixerAuth(const Def &d) : OAuthStreamKey(d) {} bool MixerAuth::GetChannelInfo(bool allow_retry) try { @@ -71,23 +59,16 @@ try { bool success; if (id.empty()) { - auto func = [&] () { + auto func = [&]() { success = GetRemoteFile( - "https://mixer.com/api/v1/users/current", - output, - error, - nullptr, - "application/json", - nullptr, - headers, - nullptr, - 5); + "https://mixer.com/api/v1/users/current", + output, error, nullptr, "application/json", + nullptr, headers, nullptr, 5); }; ExecThreadedWithoutBlocking( - func, - QTStr("Auth.LoadingChannel.Title"), - QTStr("Auth.LoadingChannel.Text").arg(service())); + func, QTStr("Auth.LoadingChannel.Title"), + QTStr("Auth.LoadingChannel.Text").arg(service())); if (!success || output.empty()) throw ErrorInfo("Failed to get user info from remote", error); @@ -98,11 +79,12 @@ try { error = json["error"].string_value(); if (!error.empty()) - throw ErrorInfo(error, - json["error_description"].string_value()); + throw ErrorInfo( + error, + json["error_description"].string_value()); - id = std::to_string(json["channel"]["id"].int_value()); - name = json["channel"]["token"].string_value(); + id = std::to_string(json["channel"]["id"].int_value()); + name = json["channel"]["token"].string_value(); } /* ------------------ */ @@ -114,23 +96,15 @@ try { output.clear(); - auto func = [&] () { - success = GetRemoteFile( - url.c_str(), - output, - error, - nullptr, - "application/json", - nullptr, - headers, - nullptr, - 5); + auto func = [&]() { + success = GetRemoteFile(url.c_str(), output, error, nullptr, + "application/json", nullptr, headers, + nullptr, 5); }; ExecThreadedWithoutBlocking( - func, - QTStr("Auth.LoadingChannel.Title"), - QTStr("Auth.LoadingChannel.Text").arg(service())); + func, QTStr("Auth.LoadingChannel.Title"), + QTStr("Auth.LoadingChannel.Text").arg(service())); if (!success || output.empty()) throw ErrorInfo("Failed to get stream key from remote", error); @@ -140,7 +114,8 @@ try { error = json["error"].string_value(); if (!error.empty()) - throw ErrorInfo(error, json["error_description"].string_value()); + throw ErrorInfo(error, + json["error_description"].string_value()); std::string key_suffix = json["streamKey"].string_value(); @@ -161,14 +136,13 @@ try { } catch (ErrorInfo info) { QString title = QTStr("Auth.ChannelFailure.Title"); QString text = QTStr("Auth.ChannelFailure.Text") - .arg(service(), info.message.c_str(), info.error.c_str()); + .arg(service(), info.message.c_str(), + info.error.c_str()); QMessageBox::warning(OBSBasic::Get(), title, text); - blog(LOG_WARNING, "%s: %s: %s", - __FUNCTION__, - info.message.c_str(), - info.error.c_str()); + blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(), + info.error.c_str()); return false; } @@ -179,15 +153,13 @@ void MixerAuth::SaveInternal() config_set_string(main->Config(), service(), "Id", id.c_str()); if (uiLoaded) { config_set_string(main->Config(), service(), "DockState", - main->saveState().toBase64().constData()); + main->saveState().toBase64().constData()); } OAuthStreamKey::SaveInternal(); } -static inline std::string get_config_str( - OBSBasic *main, - const char *section, - const char *name) +static inline std::string get_config_str(OBSBasic *main, const char *section, + const char *name) { const char *val = config_get_string(main->Config(), section, name); return val ? val : ""; @@ -205,13 +177,6 @@ bool MixerAuth::LoadInternal() return OAuthStreamKey::LoadInternal(); } -class MixerChat : public OBSDock { -public: - inline MixerChat() : OBSDock() {} - - QScopedPointer widget; -}; - void MixerAuth::LoadUI() { if (!cef) @@ -231,7 +196,7 @@ void MixerAuth::LoadUI() QSize size = main->frameSize(); QPoint pos = main->pos(); - chat.reset(new MixerChat()); + chat.reset(new BrowserDock()); chat->setObjectName("mixerChat"); chat->resize(300, 600); chat->setMinimumSize(200, 300); @@ -239,7 +204,7 @@ void MixerAuth::LoadUI() chat->setAllowedAreas(Qt::AllDockWidgetAreas); QCefWidget *browser = cef->create_widget(nullptr, url, panel_cookies); - chat->setWidget(browser); + chat->SetWidget(browser); main->addDockWidget(Qt::RightDockWidgetArea, chat.data()); chatMenu.reset(main->AddDockWidget(chat.data())); @@ -252,8 +217,8 @@ void MixerAuth::LoadUI() if (firstLoad) { chat->setVisible(true); } else { - const char *dockStateStr = config_get_string(main->Config(), - service(), "DockState"); + const char *dockStateStr = config_get_string( + main->Config(), service(), "DockState"); QByteArray dockState = QByteArray::fromBase64(QByteArray(dockStateStr)); main->restoreState(dockState); @@ -301,7 +266,7 @@ std::shared_ptr MixerAuth::Login(QWidget *parent) deobfuscate_str(&client_id[0], MIXER_HASH); if (!auth->GetToken(MIXER_TOKEN_URL, client_id, MIXER_SCOPE_VERSION, - QT_TO_UTF8(login.GetCode()))) { + QT_TO_UTF8(login.GetCode()))) { return nullptr; } @@ -328,9 +293,6 @@ static void DeleteCookies() void RegisterMixerAuth() { - OAuth::RegisterOAuth( - mixerDef, - CreateMixerAuth, - MixerAuth::Login, - DeleteCookies); + OAuth::RegisterOAuth(mixerDef, CreateMixerAuth, MixerAuth::Login, + DeleteCookies); } diff --git a/UI/auth-mixer.hpp b/UI/auth-mixer.hpp index 29a6e33..19f3037 100644 --- a/UI/auth-mixer.hpp +++ b/UI/auth-mixer.hpp @@ -2,12 +2,12 @@ #include "auth-oauth.hpp" -class MixerChat; +class BrowserDock; class MixerAuth : public OAuthStreamKey { Q_OBJECT - QSharedPointer chat; + QSharedPointer chat; QSharedPointer chatMenu; bool uiLoaded = false; diff --git a/UI/auth-oauth.cpp b/UI/auth-oauth.cpp index 976bca4..a27c49c 100644 --- a/UI/auth-oauth.cpp +++ b/UI/auth-oauth.cpp @@ -23,8 +23,7 @@ extern QCefCookieManager *panel_cookies; /* ------------------------------------------------------------------------- */ OAuthLogin::OAuthLogin(QWidget *parent, const std::string &url, bool token) - : QDialog (parent), - get_token (token) + : QDialog(parent), get_token(token) { if (!cef) { return; @@ -46,14 +45,13 @@ OAuthLogin::OAuthLogin(QWidget *parent, const std::string &url, bool token) return; } - connect(cefWidget, SIGNAL(titleChanged(const QString &)), - this, SLOT(setWindowTitle(const QString &))); - connect(cefWidget, SIGNAL(urlChanged(const QString &)), - this, SLOT(urlChanged(const QString &))); + connect(cefWidget, SIGNAL(titleChanged(const QString &)), this, + SLOT(setWindowTitle(const QString &))); + connect(cefWidget, SIGNAL(urlChanged(const QString &)), this, + SLOT(urlChanged(const QString &))); QPushButton *close = new QPushButton(QTStr("Cancel")); - connect(close, &QAbstractButton::clicked, - this, &QDialog::reject); + connect(close, &QAbstractButton::clicked, this, &QDialog::reject); QHBoxLayout *bottomLayout = new QHBoxLayout(); bottomLayout->addStretch(); @@ -111,7 +109,7 @@ struct OAuthInfo { static std::vector loginCBs; void OAuth::RegisterOAuth(const Def &d, create_cb create, login_cb login, - delete_cookies_cb delete_cookies) + delete_cookies_cb delete_cookies) { OAuthInfo info = {d, login, delete_cookies}; loginCBs.push_back(info); @@ -142,16 +140,14 @@ void OAuth::SaveInternal() { OBSBasic *main = OBSBasic::Get(); config_set_string(main->Config(), service(), "RefreshToken", - refresh_token.c_str()); + refresh_token.c_str()); config_set_string(main->Config(), service(), "Token", token.c_str()); config_set_uint(main->Config(), service(), "ExpireTime", expire_time); config_set_int(main->Config(), service(), "ScopeVer", currentScopeVer); } -static inline std::string get_config_str( - OBSBasic *main, - const char *section, - const char *name) +static inline std::string get_config_str(OBSBasic *main, const char *section, + const char *name) { const char *val = config_get_string(main->Config(), section, name); return val ? val : ""; @@ -163,11 +159,9 @@ bool OAuth::LoadInternal() refresh_token = get_config_str(main, service(), "RefreshToken"); token = get_config_str(main, service(), "Token"); expire_time = config_get_uint(main->Config(), service(), "ExpireTime"); - currentScopeVer = (int)config_get_int(main->Config(), service(), - "ScopeVer"); - return implicit - ? !token.empty() - : !refresh_token.empty(); + currentScopeVer = + (int)config_get_int(main->Config(), service(), "ScopeVer"); + return implicit ? !token.empty() : !refresh_token.empty(); } bool OAuth::TokenExpired() @@ -180,7 +174,7 @@ bool OAuth::TokenExpired() } bool OAuth::GetToken(const char *url, const std::string &client_id, - int scope_ver, const std::string &auth_code, bool retry) + int scope_ver, const std::string &auth_code, bool retry) try { std::string output; std::string error; @@ -191,8 +185,8 @@ try { return true; } else { QString title = QTStr("Auth.InvalidScope.Title"); - QString text = QTStr("Auth.InvalidScope.Text") - .arg(service()); + QString text = + QTStr("Auth.InvalidScope.Text").arg(service()); QMessageBox::warning(OBSBasic::Get(), title, text); } @@ -216,23 +210,15 @@ try { bool success = false; - auto func = [&] () { - success = GetRemoteFile( - url, - output, - error, - nullptr, - "application/x-www-form-urlencoded", - post_data.c_str(), - std::vector(), - nullptr, - 5); + auto func = [&]() { + success = GetRemoteFile(url, output, error, nullptr, + "application/x-www-form-urlencoded", + post_data.c_str(), + std::vector(), nullptr, 5); }; - ExecThreadedWithoutBlocking( - func, - QTStr("Auth.Authing.Title"), - QTStr("Auth.Authing.Text").arg(service())); + ExecThreadedWithoutBlocking(func, QTStr("Auth.Authing.Title"), + QTStr("Auth.Authing.Text").arg(service())); if (!success || output.empty()) throw ErrorInfo("Failed to get token from remote", error); @@ -250,13 +236,14 @@ try { } } if (!error.empty()) - throw ErrorInfo(error, json["error_description"].string_value()); + throw ErrorInfo(error, + json["error_description"].string_value()); /* -------------------------- */ /* success! */ expire_time = (uint64_t)time(nullptr) + json["expires_in"].int_value(); - token = json["access_token"].string_value(); + token = json["access_token"].string_value(); if (token.empty()) throw ErrorInfo("Failed to get token from remote", error); @@ -264,26 +251,26 @@ try { refresh_token = json["refresh_token"].string_value(); if (refresh_token.empty()) throw ErrorInfo("Failed to get refresh token from " - "remote", error); + "remote", + error); currentScopeVer = scope_ver; } return true; -} catch (ErrorInfo info) { +} catch (ErrorInfo &info) { if (!retry) { QString title = QTStr("Auth.AuthFailure.Title"); QString text = QTStr("Auth.AuthFailure.Text") - .arg(service(), info.message.c_str(), info.error.c_str()); + .arg(service(), info.message.c_str(), + info.error.c_str()); QMessageBox::warning(OBSBasic::Get(), title, text); } - blog(LOG_WARNING, "%s: %s: %s", - __FUNCTION__, - info.message.c_str(), - info.error.c_str()); + blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(), + info.error.c_str()); return false; } @@ -301,7 +288,7 @@ void OAuthStreamKey::OnStreamConfig() if (bwtest && strcmp(this->service(), "Twitch") == 0) obs_data_set_string(settings, "key", - (key_ + "?bandwidthtest=true").c_str()); + (key_ + "?bandwidthtest=true").c_str()); else obs_data_set_string(settings, "key", key_.c_str()); diff --git a/UI/auth-oauth.hpp b/UI/auth-oauth.hpp index 7cf035c..7cf7dc4 100644 --- a/UI/auth-oauth.hpp +++ b/UI/auth-oauth.hpp @@ -20,8 +20,8 @@ public: OAuthLogin(QWidget *parent, const std::string &url, bool token); ~OAuthLogin(); - inline QString GetCode() const {return code;} - inline bool LoadFail() const {return fail;} + inline QString GetCode() const { return code; } + inline bool LoadFail() const { return fail; } virtual int exec() override; @@ -35,15 +35,16 @@ class OAuth : public Auth { public: inline OAuth(const Def &d) : Auth(d) {} - typedef std::function (QWidget *)> login_cb; + typedef std::function(QWidget *)> login_cb; typedef std::function delete_cookies_cb; static std::shared_ptr Login(QWidget *parent, - const std::string &service); + const std::string &service); static void DeleteCookies(const std::string &service); static void RegisterOAuth(const Def &d, create_cb create, - login_cb login, delete_cookies_cb delete_cookies); + login_cb login, + delete_cookies_cb delete_cookies); protected: std::string refresh_token; @@ -55,12 +56,12 @@ protected: virtual void SaveInternal() override; virtual bool LoadInternal() override; - virtual bool RetryLogin()=0; + virtual bool RetryLogin() = 0; bool TokenExpired(); bool GetToken(const char *url, const std::string &client_id, - int scope_ver, - const std::string &auth_code = std::string(), - bool retry = false); + int scope_ver, + const std::string &auth_code = std::string(), + bool retry = false); }; class OAuthStreamKey : public OAuth { @@ -72,7 +73,7 @@ protected: public: inline OAuthStreamKey(const Def &d) : OAuth(d) {} - inline const std::string &key() const {return key_;} + inline const std::string &key() const { return key_; } virtual void OnStreamConfig() override; }; diff --git a/UI/auth-restream.cpp b/UI/auth-restream.cpp index f10e8cb..ee6c8b0 100644 --- a/UI/auth-restream.cpp +++ b/UI/auth-restream.cpp @@ -9,36 +9,27 @@ #include #include +#include "window-dock-browser.hpp" #include "window-basic-main.hpp" #include "remote-text.hpp" #include "ui-config.h" #include "obf.h" -#include using namespace json11; -extern QCef *cef; -extern QCefCookieManager *panel_cookies; - /* ------------------------------------------------------------------------- */ -#define RESTREAM_AUTH_URL "https://obsproject.com/app-auth/restream?action=redirect" +#define RESTREAM_AUTH_URL \ + "https://obsproject.com/app-auth/restream?action=redirect" #define RESTREAM_TOKEN_URL "https://obsproject.com/app-auth/restream-token" #define RESTREAM_STREAMKEY_URL "https://api.restream.io/v2/user/streamKey" #define RESTREAM_SCOPE_VERSION 1 - -static Auth::Def restreamDef = { - "Restream", - Auth::Type::OAuth_StreamKey -}; +static Auth::Def restreamDef = {"Restream", Auth::Type::OAuth_StreamKey}; /* ------------------------------------------------------------------------- */ -RestreamAuth::RestreamAuth(const Def &d) - : OAuthStreamKey(d) -{ -} +RestreamAuth::RestreamAuth(const Def &d) : OAuthStreamKey(d) {} bool RestreamAuth::GetChannelInfo() try { @@ -65,23 +56,15 @@ try { Json json; bool success; - auto func = [&] () { - success = GetRemoteFile( - RESTREAM_STREAMKEY_URL, - output, - error, - nullptr, - "application/json", - nullptr, - headers, - nullptr, - 5); + auto func = [&]() { + success = GetRemoteFile(RESTREAM_STREAMKEY_URL, output, error, + nullptr, "application/json", nullptr, + headers, nullptr, 5); }; ExecThreadedWithoutBlocking( - func, - QTStr("Auth.LoadingChannel.Title"), - QTStr("Auth.LoadingChannel.Text").arg(service())); + func, QTStr("Auth.LoadingChannel.Title"), + QTStr("Auth.LoadingChannel.Text").arg(service())); if (!success || output.empty()) throw ErrorInfo("Failed to get stream key from remote", error); @@ -91,7 +74,8 @@ try { error = json["error"].string_value(); if (!error.empty()) - throw ErrorInfo(error, json["error_description"].string_value()); + throw ErrorInfo(error, + json["error_description"].string_value()); key_ = json["streamKey"].string_value(); @@ -99,14 +83,13 @@ try { } catch (ErrorInfo info) { QString title = QTStr("Auth.ChannelFailure.Title"); QString text = QTStr("Auth.ChannelFailure.Text") - .arg(service(), info.message.c_str(), info.error.c_str()); + .arg(service(), info.message.c_str(), + info.error.c_str()); QMessageBox::warning(OBSBasic::Get(), title, text); - blog(LOG_WARNING, "%s: %s: %s", - __FUNCTION__, - info.message.c_str(), - info.error.c_str()); + blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(), + info.error.c_str()); return false; } @@ -114,14 +97,12 @@ void RestreamAuth::SaveInternal() { OBSBasic *main = OBSBasic::Get(); config_set_string(main->Config(), service(), "DockState", - main->saveState().toBase64().constData()); + main->saveState().toBase64().constData()); OAuthStreamKey::SaveInternal(); } -static inline std::string get_config_str( - OBSBasic *main, - const char *section, - const char *name) +static inline std::string get_config_str(OBSBasic *main, const char *section, + const char *name) { const char *val = config_get_string(main->Config(), section, name); return val ? val : ""; @@ -133,13 +114,6 @@ bool RestreamAuth::LoadInternal() return OAuthStreamKey::LoadInternal(); } -class RestreamWidget : public QDockWidget { -public: - inline RestreamWidget() : QDockWidget() {} - - QScopedPointer widget; -}; - void RestreamAuth::LoadUI() { if (uiLoaded) @@ -161,7 +135,7 @@ void RestreamAuth::LoadUI() QSize size = main->frameSize(); QPoint pos = main->pos(); - chat.reset(new RestreamWidget()); + chat.reset(new BrowserDock()); chat->setObjectName("restreamChat"); chat->resize(420, 600); chat->setMinimumSize(200, 300); @@ -169,7 +143,7 @@ void RestreamAuth::LoadUI() chat->setAllowedAreas(Qt::AllDockWidgetAreas); browser = cef->create_widget(nullptr, url, panel_cookies); - chat->setWidget(browser); + chat->SetWidget(browser); main->addDockWidget(Qt::RightDockWidgetArea, chat.data()); chatMenu.reset(main->AddDockWidget(chat.data())); @@ -178,7 +152,7 @@ void RestreamAuth::LoadUI() url = "https://restream.io/titles/embed"; - info.reset(new RestreamWidget()); + info.reset(new BrowserDock()); info->setObjectName("restreamInfo"); info->resize(410, 600); info->setMinimumSize(200, 150); @@ -186,25 +160,45 @@ void RestreamAuth::LoadUI() info->setAllowedAreas(Qt::AllDockWidgetAreas); browser = cef->create_widget(nullptr, url, panel_cookies); - info->setWidget(browser); + info->SetWidget(browser); - main->addDockWidget(Qt::RightDockWidgetArea, info.data()); + main->addDockWidget(Qt::LeftDockWidgetArea, info.data()); infoMenu.reset(main->AddDockWidget(info.data())); /* ----------------------------------- */ + url = "https://restream.io/channel/embed"; + + channels.reset(new BrowserDock()); + channels->setObjectName("restreamChannel"); + channels->resize(410, 600); + channels->setMinimumSize(410, 300); + channels->setWindowTitle(QTStr("RestreamAuth.Channels")); + channels->setAllowedAreas(Qt::AllDockWidgetAreas); + + browser = cef->create_widget(nullptr, url, panel_cookies); + channels->SetWidget(browser); + + main->addDockWidget(Qt::LeftDockWidgetArea, channels.data()); + channelMenu.reset(main->AddDockWidget(channels.data())); + + /* ----------------------------------- */ + chat->setFloating(true); info->setFloating(true); - chat->move(pos.x() + size.width() - chat->width() - 50, pos.y() + 50); - info->move(pos.x() + 40, pos.y() + 50); + channels->setFloating(true); + + chat->move(pos.x() + size.width() - chat->width() - 30, pos.y() + 60); + info->move(pos.x() + 20, pos.y() + 60); + channels->move(pos.x() + 20 + info->width() + 10, pos.y() + 60); if (firstLoad) { chat->setVisible(true); info->setVisible(true); - } - else { - const char *dockStateStr = config_get_string(main->Config(), - service(), "DockState"); + channels->setVisible(true); + } else { + const char *dockStateStr = config_get_string( + main->Config(), service(), "DockState"); QByteArray dockState = QByteArray::fromBase64(QByteArray(dockStateStr)); main->restoreState(dockState); @@ -227,8 +221,7 @@ bool RestreamAuth::RetryLogin() std::string client_id = RESTREAM_CLIENTID; deobfuscate_str(&client_id[0], RESTREAM_HASH); - return GetToken(RESTREAM_TOKEN_URL, client_id, - RESTREAM_SCOPE_VERSION, + return GetToken(RESTREAM_TOKEN_URL, client_id, RESTREAM_SCOPE_VERSION, QT_TO_UTF8(login.GetCode()), true); } @@ -248,8 +241,8 @@ std::shared_ptr RestreamAuth::Login(QWidget *parent) deobfuscate_str(&client_id[0], RESTREAM_HASH); if (!auth->GetToken(RESTREAM_TOKEN_URL, client_id, - RESTREAM_SCOPE_VERSION, - QT_TO_UTF8(login.GetCode()))) { + RESTREAM_SCOPE_VERSION, + QT_TO_UTF8(login.GetCode()))) { return nullptr; } @@ -275,9 +268,6 @@ static void DeleteCookies() void RegisterRestreamAuth() { - OAuth::RegisterOAuth( - restreamDef, - CreateRestreamAuth, - RestreamAuth::Login, - DeleteCookies); + OAuth::RegisterOAuth(restreamDef, CreateRestreamAuth, + RestreamAuth::Login, DeleteCookies); } diff --git a/UI/auth-restream.hpp b/UI/auth-restream.hpp index 5e66fb0..65e52ff 100644 --- a/UI/auth-restream.hpp +++ b/UI/auth-restream.hpp @@ -2,15 +2,19 @@ #include "auth-oauth.hpp" -class RestreamWidget; +class BrowserDock; class RestreamAuth : public OAuthStreamKey { Q_OBJECT - QSharedPointer chat; - QSharedPointer info; + QSharedPointer chat; + QSharedPointer info; + QSharedPointer channels; + QSharedPointer chatMenu; QSharedPointer infoMenu; + QSharedPointer channelMenu; + bool uiLoaded = false; virtual bool RetryLogin() override; diff --git a/UI/auth-twitch.cpp b/UI/auth-twitch.cpp index 3206c32..3cd8b79 100644 --- a/UI/auth-twitch.cpp +++ b/UI/auth-twitch.cpp @@ -7,9 +7,9 @@ #include #include +#include "window-dock-browser.hpp" #include "window-basic-main.hpp" #include "remote-text.hpp" -#include "window-dock.hpp" #include @@ -18,41 +18,30 @@ using namespace json11; -#include -extern QCef *cef; -extern QCefCookieManager *panel_cookies; - /* ------------------------------------------------------------------------- */ -#define TWITCH_AUTH_URL \ - "https://obsproject.com/app-auth/twitch?action=redirect" -#define TWITCH_TOKEN_URL \ - "https://obsproject.com/app-auth/twitch-token" -#define ACCEPT_HEADER \ - "Accept: application/vnd.twitchtv.v5+json" +#define TWITCH_AUTH_URL "https://obsproject.com/app-auth/twitch?action=redirect" +#define TWITCH_TOKEN_URL "https://obsproject.com/app-auth/twitch-token" +#define ACCEPT_HEADER "Accept: application/vnd.twitchtv.v5+json" #define TWITCH_SCOPE_VERSION 1 -static Auth::Def twitchDef = { - "Twitch", - Auth::Type::OAuth_StreamKey -}; +static Auth::Def twitchDef = {"Twitch", Auth::Type::OAuth_StreamKey}; /* ------------------------------------------------------------------------- */ -TwitchAuth::TwitchAuth(const Def &d) - : OAuthStreamKey(d) +TwitchAuth::TwitchAuth(const Def &d) : OAuthStreamKey(d) { if (!cef) return; cef->add_popup_whitelist_url( - "https://twitch.tv/popout/frankerfacez/chat?ffz-settings", - this); + "https://twitch.tv/popout/frankerfacez/chat?ffz-settings", + this); uiLoadTimer.setSingleShot(true); uiLoadTimer.setInterval(500); - connect(&uiLoadTimer, &QTimer::timeout, - this, &TwitchAuth::TryLoadSecondaryUIPanes); + connect(&uiLoadTimer, &QTimer::timeout, this, + &TwitchAuth::TryLoadSecondaryUIPanes); } bool TwitchAuth::GetChannelInfo() @@ -82,33 +71,25 @@ try { bool success = false; - auto func = [&] () { - success = GetRemoteFile( - "https://api.twitch.tv/kraken/channel", - output, - error, - &error_code, - "application/json", - nullptr, - headers, - nullptr, - 5); + auto func = [&]() { + success = GetRemoteFile("https://api.twitch.tv/kraken/channel", + output, error, &error_code, + "application/json", nullptr, headers, + nullptr, 5); }; ExecThreadedWithoutBlocking( - func, - QTStr("Auth.LoadingChannel.Title"), - QTStr("Auth.LoadingChannel.Text").arg(service())); + func, QTStr("Auth.LoadingChannel.Title"), + QTStr("Auth.LoadingChannel.Text").arg(service())); if (error_code == 403) { OBSMessageBox::warning(OBSBasic::Get(), - Str("TwitchAuth.TwoFactorFail.Title"), - Str("TwitchAuth.TwoFactorFail.Text"), - true); - blog(LOG_WARNING, "%s: %s", - __FUNCTION__, - "Got 403 from Twitch, user probably does not " - "have two-factor authentication enabled on " - "their account"); + Str("TwitchAuth.TwoFactorFail.Title"), + Str("TwitchAuth.TwoFactorFail.Text"), + true); + blog(LOG_WARNING, "%s: %s", __FUNCTION__, + "Got 403 from Twitch, user probably does not " + "have two-factor authentication enabled on " + "their account"); return false; } @@ -125,10 +106,10 @@ try { if (RetryLogin()) { return GetChannelInfo(); } - throw ErrorInfo(error, - json["message"].string_value()); + throw ErrorInfo(error, json["message"].string_value()); } - throw ErrorInfo(error, json["error_description"].string_value()); + throw ErrorInfo(error, + json["error_description"].string_value()); } name = json["name"].string_value(); @@ -138,14 +119,13 @@ try { } catch (ErrorInfo info) { QString title = QTStr("Auth.ChannelFailure.Title"); QString text = QTStr("Auth.ChannelFailure.Text") - .arg(service(), info.message.c_str(), info.error.c_str()); + .arg(service(), info.message.c_str(), + info.error.c_str()); QMessageBox::warning(OBSBasic::Get(), title, text); - blog(LOG_WARNING, "%s: %s: %s", - __FUNCTION__, - info.message.c_str(), - info.error.c_str()); + blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(), + info.error.c_str()); return false; } @@ -155,15 +135,13 @@ void TwitchAuth::SaveInternal() config_set_string(main->Config(), service(), "Name", name.c_str()); if (uiLoaded) { config_set_string(main->Config(), service(), "DockState", - main->saveState().toBase64().constData()); + main->saveState().toBase64().constData()); } OAuthStreamKey::SaveInternal(); } -static inline std::string get_config_str( - OBSBasic *main, - const char *section, - const char *name) +static inline std::string get_config_str(OBSBasic *main, const char *section, + const char *name) { const char *val = config_get_string(main->Config(), section, name); return val ? val : ""; @@ -180,19 +158,6 @@ bool TwitchAuth::LoadInternal() return OAuthStreamKey::LoadInternal(); } -class TwitchWidget : public OBSDock { -public: - inline TwitchWidget() : OBSDock() {} - - QScopedPointer widget; - - inline void SetWidget(QCefWidget *widget_) - { - setWidget(widget_); - widget.reset(widget_); - } -}; - static const char *ffz_script = "\ var ffz = document.createElement('script');\ ffz.setAttribute('src','https://cdn.frankerfacez.com/script/script.min.js');\ @@ -240,7 +205,7 @@ void TwitchAuth::LoadUI() QSize size = main->frameSize(); QPoint pos = main->pos(); - chat.reset(new TwitchWidget()); + chat.reset(new BrowserDock()); chat->setObjectName("twitchChat"); chat->resize(300, 600); chat->setMinimumSize(200, 300); @@ -266,8 +231,8 @@ void TwitchAuth::LoadUI() if (firstLoad) { chat->setVisible(true); } else { - const char *dockStateStr = config_get_string(main->Config(), - service(), "DockState"); + const char *dockStateStr = config_get_string( + main->Config(), service(), "DockState"); QByteArray dockState = QByteArray::fromBase64(QByteArray(dockStateStr)); main->restoreState(dockState); @@ -304,7 +269,7 @@ void TwitchAuth::LoadSecondaryUIPanes() url += name; url += "/dashboard/live/stream-info"; - info.reset(new TwitchWidget()); + info.reset(new BrowserDock()); info->setObjectName("twitchInfo"); info->resize(300, 650); info->setMinimumSize(200, 300); @@ -324,7 +289,7 @@ void TwitchAuth::LoadSecondaryUIPanes() url += name; url += "/dashboard/live/stats"; - stat.reset(new TwitchWidget()); + stat.reset(new BrowserDock()); stat->setObjectName("twitchStats"); stat->resize(200, 250); stat->setMinimumSize(200, 150); @@ -344,7 +309,7 @@ void TwitchAuth::LoadSecondaryUIPanes() url += name; url += "/dashboard/live/activity-feed"; - feed.reset(new TwitchWidget()); + feed.reset(new BrowserDock()); feed->setObjectName("twitchFeed"); feed->resize(300, 650); feed->setMinimumSize(200, 300); @@ -367,8 +332,8 @@ void TwitchAuth::LoadSecondaryUIPanes() QSize statSize = stat->frameSize(); info->move(pos.x() + 50, pos.y() + 50); - stat->move(pos.x() + size.width() / 2 - statSize.width() / 2, - pos.y() + size.height() / 2 - statSize.height() / 2); + stat->move(pos.x() + size.width() / 2 - statSize.width() / 2, + pos.y() + size.height() / 2 - statSize.height() / 2); feed->move(pos.x() + 100, pos.y() + 100); if (firstLoad) { @@ -376,15 +341,15 @@ void TwitchAuth::LoadSecondaryUIPanes() stat->setVisible(false); feed->setVisible(false); } else { - uint32_t lastVersion = config_get_int(App()->GlobalConfig(), "General", - "LastVersion"); + uint32_t lastVersion = config_get_int(App()->GlobalConfig(), + "General", "LastVersion"); if (lastVersion <= MAKE_SEMANTIC_VERSION(23, 0, 2)) { feed->setVisible(false); } - const char *dockStateStr = config_get_string(main->Config(), - service(), "DockState"); + const char *dockStateStr = config_get_string( + main->Config(), service(), "DockState"); QByteArray dockState = QByteArray::fromBase64(QByteArray(dockStateStr)); main->restoreState(dockState); @@ -405,21 +370,21 @@ void TwitchAuth::TryLoadSecondaryUIPanes() { QPointer this_ = this; - auto cb = [this_] (bool found) - { + auto cb = [this_](bool found) { if (!this_) { return; } if (!found) { - QMetaObject::invokeMethod(&this_->uiLoadTimer, - "start"); + QMetaObject::invokeMethod(&this_->uiLoadTimer, "start"); } else { - QMetaObject::invokeMethod(this_, "LoadSecondaryUIPanes"); + QMetaObject::invokeMethod(this_, + "LoadSecondaryUIPanes"); } }; - panel_cookies->CheckForCookie("https://www.twitch.tv", "auth-token", cb); + panel_cookies->CheckForCookie("https://www.twitch.tv", "auth-token", + cb); } bool TwitchAuth::RetryLogin() @@ -429,7 +394,8 @@ bool TwitchAuth::RetryLogin() return false; } - std::shared_ptr auth = std::make_shared(twitchDef); + std::shared_ptr auth = + std::make_shared(twitchDef); std::string client_id = TWITCH_CLIENTID; deobfuscate_str(&client_id[0], TWITCH_HASH); @@ -444,13 +410,14 @@ std::shared_ptr TwitchAuth::Login(QWidget *parent) return nullptr; } - std::shared_ptr auth = std::make_shared(twitchDef); + std::shared_ptr auth = + std::make_shared(twitchDef); std::string client_id = TWITCH_CLIENTID; deobfuscate_str(&client_id[0], TWITCH_HASH); if (!auth->GetToken(TWITCH_TOKEN_URL, client_id, TWITCH_SCOPE_VERSION, - QT_TO_UTF8(login.GetCode()))) { + QT_TO_UTF8(login.GetCode()))) { return nullptr; } @@ -475,9 +442,6 @@ static void DeleteCookies() void RegisterTwitchAuth() { - OAuth::RegisterOAuth( - twitchDef, - CreateTwitchAuth, - TwitchAuth::Login, - DeleteCookies); + OAuth::RegisterOAuth(twitchDef, CreateTwitchAuth, TwitchAuth::Login, + DeleteCookies); } diff --git a/UI/auth-twitch.hpp b/UI/auth-twitch.hpp index 76698d1..cc4079b 100644 --- a/UI/auth-twitch.hpp +++ b/UI/auth-twitch.hpp @@ -7,17 +7,17 @@ #include "auth-oauth.hpp" -class TwitchWidget; +class BrowserDock; class TwitchAuth : public OAuthStreamKey { Q_OBJECT friend class TwitchLogin; - QSharedPointer chat; - QSharedPointer info; - QSharedPointer stat; - QSharedPointer feed; + QSharedPointer chat; + QSharedPointer info; + QSharedPointer stat; + QSharedPointer feed; QSharedPointer chatMenu; QSharedPointer infoMenu; QSharedPointer statMenu; diff --git a/UI/clickable-label.hpp b/UI/clickable-label.hpp index 3c76a8b..5338315 100644 --- a/UI/clickable-label.hpp +++ b/UI/clickable-label.hpp @@ -4,7 +4,7 @@ #include class ClickableLabel : public QLabel { - Q_OBJECT + Q_OBJECT public: inline ClickableLabel(QWidget *parent = 0) : QLabel(parent) {} diff --git a/UI/crash-report.cpp b/UI/crash-report.cpp index 6a94692..8c8e0a0 100644 --- a/UI/crash-report.cpp +++ b/UI/crash-report.cpp @@ -32,10 +32,10 @@ OBSCrashReport::OBSCrashReport(QWidget *parent, const char *text) setLayout(mainLayout); - QWidget::connect(copyButton, SIGNAL(clicked()), - this, SLOT(CopyClicked())); - QWidget::connect(exitButton, SIGNAL(clicked()), - this, SLOT(ExitClicked())); + QWidget::connect(copyButton, SIGNAL(clicked()), this, + SLOT(CopyClicked())); + QWidget::connect(exitButton, SIGNAL(clicked()), this, + SLOT(ExitClicked())); resize(800, 600); setWindowTitle("Oops, OBS has crashed!"); diff --git a/UI/data/locale.ini b/UI/data/locale.ini index 6068f13..d1fcf71 100644 --- a/UI/data/locale.ini +++ b/UI/data/locale.ini @@ -68,7 +68,7 @@ Name=Türkçe Name=简体中文 [zh-TW] -Name=正體中文(臺灣) +Name=繁體中文 [bg-BG] Name=Български @@ -162,3 +162,6 @@ Name=کوردی [pa-IN] Name=ਪੰਜਾਬੀ + +[az-Az] +Name=Azərbaycanca diff --git a/UI/data/locale/af-ZA.ini b/UI/data/locale/af-ZA.ini index 91a1316..94a1488 100644 --- a/UI/data/locale/af-ZA.ini +++ b/UI/data/locale/af-ZA.ini @@ -1,17 +1,23 @@ +Language="Engels" -OK="OK" -Apply="Pas veranderinge toe" -Cancel="Kanselleer" +OK="Ok" Close="Maak toe" Save="Stoor" -Discard="Gooi weg" -Disable="Deaktiveer" Yes="Ja" No="Nee" -Add="Voeg by" -Remove="Verwyder" -Rename="Hernoem" +Name="Naam" +New="Nuwe" +Left="Links" +Top="Bo" + + + + + + + + diff --git a/UI/data/locale/ar-SA.ini b/UI/data/locale/ar-SA.ini index e18f7c1..a1c2701 100644 --- a/UI/data/locale/ar-SA.ini +++ b/UI/data/locale/ar-SA.ini @@ -23,7 +23,7 @@ Settings="إعدادات" Display="شاشة العرض" Name="الاسم" Exit="خروج" -Mixer="مختلط" +Mixer="مِكْسَر الصوت" Browse="استعراض" Mono="صوت أحادي القناة \"مونو\"" Stereo="صوت ثنائي القناة \"ستيريو\"" @@ -84,13 +84,12 @@ DoNotShowAgain="عدم الإظهار مرة أخرى" Default="(الافتراضي)" Calculating="جاري حساب الوقت..." -AlreadyRunning.Title="البرنامج قيد التشغيل بالفعل" -AlreadyRunning.Text="أوبس قيد التشغيل بالفعل! إلا إذا كنت تريد القيام بذلك، يرجى إيقاف أية مثيلات موجودة من للبرنامج قبل محاولة تشغيله من جديد. إذا كان لديك أوبس تعيين لتقليل إلى علبة النظام، يرجى التحقق لمعرفة ما إذا كان لا يزال قيد التشغيل هناك." AlreadyRunning.LaunchAnyway="إطلاق على أي حال" DockCloseWarning.Title="إغلاق إطار قابل للإرساء" DockCloseWarning.Text="لقد قمت بإغلاق إطار قابل للإرساء. إذا كنت ترغب في إظهاره مرة أخرى، استخدم قائمة عرض ← أرصفة من شريط القوائم." + Auth.Authing.Title="جاري المصادقة..." Auth.Authing.Text="جارٍ المصادقة مع %1, الرجاء الانتظار..." Auth.AuthFailure.Title="فشل المصادقة" @@ -105,6 +104,8 @@ Auth.Chat="الدردشة" Auth.StreamInfo="معلومات البث" TwitchAuth.Stats="إحصائيات Twitch" TwitchAuth.TwoFactorFail.Title="لم نتمكن من الاستعلام عن مفتاح البث" +TwitchAuth.TwoFactorFail.Text="OBS غير قادر على الربط بحسابك التويتش. الرجاء التأكد من اعداد المصادقة الثنائية في إعدادات أمان تويتش لأنه أحد المتطلبات للتمكن من البث." +RestreamAuth.Channels="قنوات Restream" Copy.Filters="نسخ الفلتر" Paste.Filters="لصق الفلتر" @@ -137,7 +138,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="إما 60 أو 30، ولكن يف Basic.AutoConfig.VideoPage.CanvasExplanation="ملاحظة: قرار قاعدة (قاعدة) ليس بالضرورة يكون بنفس دقة البث أو التسجيل. قد يتم تصغير حجم تدفق البث/ دقة التسجيل أقل من دقة القاعدة لتقليل استخدام الموارد أو متطلبات معدل البت." Basic.AutoConfig.StreamPage="معلومات البث" Basic.AutoConfig.StreamPage.SubTitle="من فضلك ادخل معلومات الخادم أو السيرفر" -Basic.AutoConfig.StreamPage.ConnectAccount="تسجيل الدخول إلى قناتك (اختياري)" +Basic.AutoConfig.StreamPage.ConnectAccount="ربط الحساب (مستحسن)" Basic.AutoConfig.StreamPage.DisconnectAccount="إلغاء ربط الحساب" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="إلغاء ربط الحساب؟" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="هذا التغيير سيتم تطبيقه مباشرة. هل أنت متأكد من أنك تريد إلغاء ربط حسابك؟" @@ -238,6 +239,9 @@ ConfirmStart.Text="هل انت متأكد انك تريد بدء البث ؟" ConfirmStop.Title="ايقاف البث؟" ConfirmStop.Text="هل أنت متأكد انك تريد ايقاف البث؟" +ConfirmStopRecord.Title="إيقاف التسجيل؟" +ConfirmStopRecord.Text="هل متأكد أنك تريد إيقاف التسجيل ؟" + ConfirmBWTest.Title="بدء فحص سرعة التدفق؟" ConfirmBWTest.Text="OBS لديك معد في وضع فحص تدفق السرعة. هذا الوضع يسمح لك بفحص الشبكة بدون ان تظهر في بث مباشر على قناتك. بمجرد انتهاء الفحص يجب عليك تعطيله لكي يستطيع مشاهدوك من رؤية البث.\n\nهل تريد الاستمرار ؟" @@ -253,6 +257,8 @@ Output.StartRecordingFailed="فشل في بدء التسجيل" Output.StartReplayFailed="فشل بدء التخزين المؤقت للإعادة" Output.StartFailedGeneric="فشل بدء الإخراج. الرجاء مراجعة السجل للتفاصيل.\n\nملاحظة: اذا كنت تستخدم مُرَمِز NVENC أو مُرَمِز AMD, تأكد من أن تعريف بطاقة الشاشة لديك محدَّث." +Output.ReplayBuffer.PauseWarning.Title="لا يمكن حفظ الإعادات اثناء التوقف المؤقت" +Output.ReplayBuffer.PauseWarning.Text="تحذير: لا يمكن حفظ الإعادات اثناء توقيف التسجيل مؤقتاً." Output.ConnectFail.Title="فشل في الاتصال" Output.ConnectFail.BadPath="مسار أو رابط الاتصال غير صالح. الرجاء التحقق من الإعدادات للتحقق من كونه صالح." @@ -290,6 +296,7 @@ Remux.OBSRecording="تسجيل OBS" Remux.FinishedTitle="انتهت عملية تحويل الصيغة" Remux.Finished="تسجيل عملية تحويل الصيغة" Remux.FinishedError="عملية التحويل قد تكون غير مكتملة" +Remux.SelectTarget="حدد الملف الوُّجهة..." Remux.FileExistsTitle="الملف الهدف موجود" Remux.FileExists="الملفات التالية موجودة فعليا. هل ترغب في استبدالها؟" Remux.ExitUnfinishedTitle="تقدم عملية التحويل" @@ -523,7 +530,6 @@ Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="عتاد (NVENC)" Basic.Settings.Output.VideoBitrate="معدل البت للفيديو" Basic.Settings.Output.AudioBitrate="معدل البت للصوت" Basic.Settings.Output.Reconnect="إعادة الاتصال تلقائياً" -Basic.Settings.Output.RetryDelay="إعادة محاولة تأخير (ثوان)" Basic.Settings.Output.MaxRetries="أقصى عدد للمحاولات" diff --git a/UI/data/locale/az-AZ.ini b/UI/data/locale/az-AZ.ini new file mode 100644 index 0000000..4781071 --- /dev/null +++ b/UI/data/locale/az-AZ.ini @@ -0,0 +1,150 @@ + +Language="Azərbaycanca" +Region="Azərbaycan" + +OK="Oldu" +Apply="Tətbiq et" +Cancel="İmtina" +Close="Bağla" +Save="Saxla" +Discard="Ləğv et" +Disable="Sıradan çıxart" +Yes="Bəli" +No="Xeyr" +Add="Əlavə et" +Remove="Çıxart" +Rename="Yenidən adlandır" +Interact="Qarşılıqlı təsir" +Filters="Filtrlər" +Properties="Xüsusiyyətlər" +MoveUp="Yuxarı Köçür" +MoveDown="Aşağı Köçür" +Settings="Tənzimləmələr" +Display="Ekran" +Name="Ad" +Exit="Çıxış" +Browse="Gözdən keçir" +Mono="Mono" +Stereo="Stereo" +DroppedFrames="Buraxılan Kadrlar %1 (%2%)" +StudioProgramProjector="Tam Ekran Projektoru (Proqram)" +PreviewProjector="Tam Ekran Projektoru (Önbaxış)" +SceneProjector="Tam Ekran Projektoru (Səhnə)" +SourceProjector="Tam Ekran Projektoru (Mənbə)" +StudioProgramWindow="Pəncərəli Projektor (Proqram)" +PreviewWindow="Pəncərəli Projektor (Önbaxış)" +SceneWindow="Pəncərəli Projektor (Səhnə)" +SourceWindow="Pəncərəli Projektor (Mənbə)" +MultiviewProjector="Çoxlu baxış (Tam ekran)" +MultiviewWindowed="Çoxlu baxış (Pəncərəli)" +Clear="Təmizlə" +Revert="Geri qaytar" +Show="Göstər" +Hide="Gizlət" +UnhideAll="Hamısını Göstər" +Untitled="Adsız" +New="Yeni" +Duplicate="Çoxalt" +Enable="Fəallaşdır" +DisableOSXVSync="OSX V-Sync-i sıradan çıxart" +ResetOSXVSyncOnExit="OSX V-Sync-i Çıxışda Sıfırla" +HighResourceUsage="Kodlama həddindən artıq yükləndi! Video tənzimləmələrini azaltmağı və ya daha sürətli kodlama ön tənzimini istifadə etməyi düşünün." + + + + +TwitchAuth.Feed="Twitch Fəaliyyət Axını" + +Copy.Filters="Filtrləri Kopyala" +Paste.Filters="Filtrləri Yapışdır" + +BrowserPanelInit.Title="Səyyah Başladılır..." + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/UI/data/locale/bg-BG.ini b/UI/data/locale/bg-BG.ini index 317e1fa..82c2138 100644 --- a/UI/data/locale/bg-BG.ini +++ b/UI/data/locale/bg-BG.ini @@ -23,7 +23,7 @@ Settings="Настройки" Display="Дисплей" Name="Име" Exit="Изход" -Mixer="Миксер" +Mixer="Звуков смесител" Browse="Преглед" Mono="Моно" Stereo="Стерео" @@ -68,7 +68,7 @@ Copy="Копиране" Paste="Постави" PasteReference="Постави (препратка)" PasteDuplicate="Постави (дубликат)" -RemuxRecordings="Конвертиране на запаиси" +RemuxRecordings="Ремултиплексирани записи" Next="Напред" Back="Назад" Defaults="По подразбиране" @@ -80,17 +80,25 @@ StudioMode.Program="Програмен Изглед" ShowInMultiview="Покажи във Множествен изглед" VerticalLayout="Вертикално разположение" Group="Група" +DoNotShowAgain="Без ново показване" +Default="(По подразбиране)" +Calculating="Калкулира се..." AlreadyRunning.Title="OBS вече се изпълнява" AlreadyRunning.Text="OBS вече е включен! Освен ако не е по желание, моля изключете другите работещи инстанции на OBS преди да включите нова. Ако сте настроили OBS да се минимизира във системната табла, моля проверете дали все още е включен там." AlreadyRunning.LaunchAnyway="Включи въпреки това" + Auth.Chat="Чат" +Auth.StreamInfo="Информация за потока" +TwitchAuth.Stats="Статистика за Twitch" +RestreamAuth.Channels="Канали Restream" Copy.Filters="Копирай Филтъри" Paste.Filters="Постави Филтъри" +BrowserPanelInit.Title="Установяване на първонач. състояние на браузъра..." BandwidthTest.Region="Регион" BandwidthTest.Region.US="САЩ" @@ -146,6 +154,7 @@ Basic.AutoConfig.TestPage.Result.Footer="За да ползвате тези н Basic.Stats="Статистика" Basic.Stats.CPUUsage="Използване на централния процесор" +Basic.Stats.HDDSpaceAvailable="Свободно място на диска" Basic.Stats.MemoryUsage="Използване на паметта" Basic.Stats.AverageTimeToRender="Средно време за рендиране на кадър" Basic.Stats.SkippedFrames="Изпуснати кадри заради забавяне във кодирането" @@ -160,6 +169,7 @@ Basic.Stats.Status.Inactive="Неактивно" Basic.Stats.DroppedFrames="Изпуснати Кадри (Мрежа)" Basic.Stats.MegabytesSent="Общо количество изпратени данни" Basic.Stats.Bitrate="Битрейт" +Basic.Stats.DiskFullIn="Дискът е пълен за (около)" Updater.Title="Има нова актуализация" @@ -207,6 +217,9 @@ ConfirmStart.Text="Сигурни ли сте че искате да започ ConfirmStop.Title="Спри излъчването?" ConfirmStop.Text="Сигурни ли сте че искате да спрете предаването?" +ConfirmStopRecord.Title="Спирате ли записването?" +ConfirmStopRecord.Text="Наистина ли искате да спрете записването?" + ConfirmExit.Title="Изход от OBS?" ConfirmExit.Text="OBS във момента е активен. Всички предавания/записи ще бъдат изключени. Сигурни ли сте че искате да излезнете от програмата?" @@ -247,18 +260,21 @@ LogReturnDialog.ErrorUploadingLog="Грешка при качването на \ Remux.SourceFile="OBS запис" Remux.TargetFile="Целеви файл" -Remux.Remux="Конвертиране" +Remux.Remux="Ремултиплексиране" +Remux.Stop="Стоп на ремултиплексирането" Remux.ClearFinished="Изчисти готовите елементи" Remux.ClearAll="Изчисти всички елементи" Remux.OBSRecording="OBS запис" -Remux.FinishedTitle="Конвертирането завърши" -Remux.Finished="Записът е конвертиран" -Remux.FinishedError="Записът е конвертиран, но файлът може да бъде незавършен" +Remux.FinishedTitle="Ремултиплексирането завърши" +Remux.Finished="Записването е ремултиплексирано" +Remux.FinishedError="Записването е ремултиплексирано, но файлът може да е непълен" +Remux.SelectRecording="Избиране на OBS запис..." +Remux.SelectTarget="Изберете целеви файл..." Remux.FileExistsTitle="Целевите файлове съществуват" Remux.FileExists="Следните целеви файлове вече съществуват. Желаете ли да ги замените?" -Remux.ExitUnfinishedTitle="Конвертиране в ход" -Remux.ExitUnfinished="Конвертирането не е завършено все още, ако го спрете сега файлът може да бъде неизползваем.\nСигурни ли сте, че искате да спрете конвертирането?" -Remux.HelpText="Пуснете файловете чрез влачене в този прозорец, за да ги преобразувате или изберете празна \"OBS Recording\" клетка, за да отворите прозореца за търсене на файл." +Remux.ExitUnfinishedTitle="Ремултиплексира се" +Remux.ExitUnfinished="Конвертирането не е завършено все още, ако го спрете сега файлът може да бъде неизползваем.\nНаистина ли искате да спрете ремултиплексирането?" +Remux.HelpText="Пуснете файловете чрез провлачване в този прозорец, за да ги ремултиплексирате или изберете празната клетка \"OBS запис\" за избор на файл." UpdateAvailable="Има нова актуализация" UpdateAvailable.Text="Версия %1.%2.%3 е налична. Щракнете тук, за да изтеглите" @@ -415,7 +431,7 @@ Basic.MainMenu.File="Файл (&F)" Basic.MainMenu.File.Export="Експортиране (&E)" Basic.MainMenu.File.Import="Импортиране (&I)" Basic.MainMenu.File.ShowRecordings="Покажи Записите (&R)" -Basic.MainMenu.File.Remux="Прекодиране на Записите (&M)" +Basic.MainMenu.File.Remux="Ремултиплексирани записи" Basic.MainMenu.File.Settings="Настройки (&S)" Basic.MainMenu.File.ShowSettingsFolder="Покажи папката с Настройки" Basic.MainMenu.File.ShowProfileFolder="Покажи папката със Профили" @@ -545,7 +561,6 @@ Basic.Settings.Output.Mode.Simple="Опростен" Basic.Settings.Output.Mode.Adv="Допълнителни настройки" Basic.Settings.Output.Mode.FFmpeg="FFmpeg изходен формат" Basic.Settings.Output.UseReplayBuffer="Включване на Буферa за Повторение" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Максимално време на повторение (Секунди)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Максимална Памет (Мегабайти)" Basic.Settings.Output.ReplayBuffer.Estimate="Приблизително използвана памет: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Не може да се определи използваната памет. Моля нстройте максималния лимит за паметта." @@ -572,7 +587,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Програмно (x264 н Basic.Settings.Output.VideoBitrate="Видео битрейт" Basic.Settings.Output.AudioBitrate="Аудио битрейт" Basic.Settings.Output.Reconnect="Автоматично повторно свързване" -Basic.Settings.Output.RetryDelay="Отлагане на повторно свързване (секунди)" Basic.Settings.Output.MaxRetries="Максимален брой повторни опити" Basic.Settings.Output.Advanced="Включи Допълнителни Настройки за Енкодера" Basic.Settings.Output.CustomEncoderSettings="Допълнителни Настройки на Енкодера" @@ -641,11 +655,12 @@ Basic.Settings.Video.DisableAero="Изключи Aero режима" Basic.Settings.Video.DownscaleFilter.Bilinear="Двулинеен (Най-бърз, но замазан след усъразмеряване)" Basic.Settings.Video.DownscaleFilter.Bicubic="Двукубичен (Изострено при усъразмеряване, 16 семпли)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Изострено при усъразмеряване, 32 семпли)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Изострено при усъразмеряване, 36 семпли)" Basic.Settings.Audio="Аудио" Basic.Settings.Audio.SampleRate="Честота на дискретизацията" Basic.Settings.Audio.Channels="Канали" +Basic.Settings.Audio.Meters="Измерватели" Basic.Settings.Audio.MeterDecayRate.Fast="Бързо" Basic.Settings.Audio.MeterDecayRate.Medium="Средно (ТИП I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Бавно (Type II PPM)" @@ -653,9 +668,10 @@ Basic.Settings.Audio.PeakMeterType="Тип на връхната точка" Basic.Settings.Audio.PeakMeterType.SamplePeak="Образец на върха" Basic.Settings.Audio.PeakMeterType.TruePeak="Истински връх (По-високо използване на CPU)" Basic.Settings.Audio.MultiChannelWarning.Enabled="ПРЕДУПРЕЖДЕНИЕ: Включен е Surround sound." -Basic.Settings.Audio.MultichannelWarning="Ако предавате, проверете дали вашата услуга за стрийминг поддържа едновременно приемане на съраунд звук и възпроизвеждане на съраунд звук. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast са примери, при които съраунд звукът е напълно поддържан. Въпреки че, Facebook Live и YouTube Live подържат и приемат съраунд, Facebook Live пемиксира към стерео звук, а YouTube Live възпроизвежда само два канала.\n\nЗвуковите филтъри на OBS подържат съраунд звук, въпреки това VST поддръжката не е гарантирана." +Basic.Settings.Audio.MultichannelWarning="Ако предавате, проверете дали вашата услуга за стрийминг поддържа едновременно приемане на съраунд звук и възпроизвеждане на съраунд звук. Facebook 360 Live, Mixer RTMP, Smashcast са примери, при които съраунд звукът е напълно поддържан. Въпреки че, Facebook Live и YouTube Live подържат и приемат съраунд, Facebook Live пемиксира към стерео звук, а YouTube Live възпроизвежда само два канала.\n\nЗвуковите филтъри на OBS подържат съраунд звук, въпреки това VST поддръжката не е гарантирана." Basic.Settings.Audio.MultichannelWarning.Title="Включи записването на съраунд звук?" Basic.Settings.Audio.MultichannelWarning.Confirm="Сигурни ли сте че искате да включите записването на съраунд звук?" +Basic.Settings.Audio.Devices="Устройства" Basic.Settings.Audio.EnablePushToMute="Включи Натисни-за-да-заглуши" Basic.Settings.Audio.PushToMuteDelay="Натисни-за-да-заглуши забавяне" Basic.Settings.Audio.EnablePushToTalk="Включи Натисни-за-говорене" @@ -673,12 +689,15 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Свободен" Basic.Settings.Advanced.FormatWarning="Предупреждение: Цветните формати освен NV12 се ползват главно при записи и не са препоръчани при предаване. Предаването може да упражни завишено ползване на Процесора поради прекодиране на форматите." Basic.Settings.Advanced.Audio.BufferingTime="Време за буфериране на звук" Basic.Settings.Advanced.Video.ColorFormat="Формат на цвета" +Basic.Settings.Advanced.Video.ColorSpace="Цветово пространство" +Basic.Settings.Advanced.Video.ColorRange="Цветови обхват" Basic.Settings.Advanced.Video.ColorRange.Partial="Частично" Basic.Settings.Advanced.Video.ColorRange.Full="Пълен" +Basic.Settings.Advanced.Audio.MonitoringDevice="Устройство за наблюдение" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="По подразбиране" Basic.Settings.Advanced.Audio.DisableAudioDucking="Изключи намалянето на звука при разговори" Basic.Settings.Advanced.StreamDelay="Забавяне на Предаването" -Basic.Settings.Advanced.StreamDelay.Duration="Продължителност (секунди)" +Basic.Settings.Advanced.StreamDelay.Duration="Времетраене" Basic.Settings.Advanced.StreamDelay.Preserve="Запази точката на прекъсване (увеличете забавянето) при повторно свързване" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Приблизително използвана памет: %1 MB" Basic.Settings.Advanced.Network="Мрежа" @@ -691,9 +710,10 @@ Basic.Settings.Advanced.AutoRemux.MP4="(запиши като .mkv)" Basic.AdvAudio="Допълнителни Звукови Характеристики" Basic.AdvAudio.Name="Име" -Basic.AdvAudio.Mono="Премиксирай към Mono звук" +Basic.AdvAudio.Volume="Сила на звука" +Basic.AdvAudio.Mono="Моно" Basic.AdvAudio.Balance="Баланс" -Basic.AdvAudio.SyncOffset="Забавяне (мс)" +Basic.AdvAudio.SyncOffset="Синхронизиращо разклонение" Basic.AdvAudio.Monitoring="Звуков Мониториниг " Basic.AdvAudio.Monitoring.None="Мониторът Изключен" Basic.AdvAudio.Monitoring.MonitorOnly="Само на Монитора (заглуши изхода)" @@ -746,6 +766,7 @@ Hotkeys.AppleKeypadSubtract="- (Клавиатура)" Hotkeys.AppleKeypadDecimal=". (Клавиатура)" Hotkeys.AppleKeypadEqual="= (Клавиатура)" Hotkeys.MouseButton="Мишка %1" +Hotkeys.Escape="Esc" Mute="Заглуши" Unmute="Включи звука" @@ -757,6 +778,7 @@ SceneItemHide="Скрии '%1'" OutputWarnings.NoTracksSelected="Трябва да изберете поне една писта за звук" OutputWarnings.MultiTrackRecording="Предупреждение: Някои формати (като FLV) не подържат множествен брой на писти при запис" +OutputWarnings.MP4Recording="Предупреждение: Записи запаметени в MP4/MOV не могат да се възстановят, ако записът във файла не е приключил (в случай на спиране на програмата или при спиране на тока и т.н.). Ако искате да записвате на множество звукови писти ползвайте формат MKV и ремултиплексирайте записа в MP4/MOV след като приключи (от Файл->Ремултиплексирани записи)" FinalScene.Title="Изтрий Сцената" FinalScene.Text="Трябва да има поне една сцена във наличност." @@ -771,13 +793,16 @@ CustomColor="Различен цвят" BrowserSource.EnableHardwareAcceleration="Позволи ускорение, чрез браузър" About="За програмата" -About.Info="OBS Studio е програма за видео запис и живи предавания с отворен код, разпространяваща се безплатно." +About.Info="OBS Studio е програма за видеозапис и видеопредаване на живо с отворен код, разпространяваща се безплатно." +About.Donate="Направете принос" About.GetInvolved="Включете се" About.Authors="Автори" About.License="Лиценз" +About.Contribute="Подкрепете проекта OBS" ResizeOutputSizeOfSource="Преоразмеряване изх. видео (по размер на източника)" ResizeOutputSizeOfSource.Text="Базата и изходната резолюция ще бъдат преоразмерени до размера на текущия източник." ResizeOutputSizeOfSource.Continue="Желаете ли да продължите?" +PreviewTransition="Предварителен преглед на прехода" diff --git a/UI/data/locale/bn-BD.ini b/UI/data/locale/bn-BD.ini index 4c41702..2cdcb8b 100644 --- a/UI/data/locale/bn-BD.ini +++ b/UI/data/locale/bn-BD.ini @@ -23,7 +23,6 @@ Settings="সেটিংস" Display="প্রদর্শন" Name="নাম" Exit="প্রস্থান করুন" -Mixer="মিক্সার" Browse="ব্রাউজ" Mono="মোনো" Stereo="স্টিরিও" @@ -65,6 +64,7 @@ Export="ডাটা এক্সপোর্ট" + Basic.AutoConfig.VideoPage="ভিডিও সেটিংস" @@ -116,6 +116,7 @@ ConfirmStop.Title="স্রোত বন্ধ করতে?" ConfirmStop.Text="আপনি কি নিশ্চিত যে আপনি ধারা সূচনা করতে চান?" + ConfirmExit.Title="OBS প্রস্থান করুন?" ConfirmExit.Text="OBS বর্তমানে সক্রিয় আছে। সব নদী/রেকর্ডিং বন্ধ হয়ে যাবে। আপনি কি নিশ্চিত যে আপনি প্রস্থান করতে চান?" @@ -416,7 +417,6 @@ Basic.Settings.Output.Mode.Simple="সাধারণ" Basic.Settings.Output.Mode.Adv="অ্যাডভান্সড" Basic.Settings.Output.Mode.FFmpeg="FFmpeg উত্পাদন" Basic.Settings.Output.UseReplayBuffer="রিপ্লে বাফার সক্রিয় করা হবে" -Basic.Settings.Output.ReplayBuffer.SecondsMax="সর্বোচ্চ রিপ্লে সময় (সেকেন্ড)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="সর্বোচ্চ স্মৃতি (মেগাবাইট)" Basic.Settings.Output.ReplayBuffer.Estimate="ব্যবহার করা: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="স্মৃতি ব্যবহার অনুমান করতে পারে না। অনুগ্রহ করে স্মৃতি সর্বোচ্চ সীমা নির্ধারণ করুন." @@ -465,7 +465,7 @@ Basic.Settings.Video.DisableAero="এরো নিষ্ক্রিয় ক Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (সবচেয়ে দ্রুত, কিন্তু ঘোলাটে হলে স্কেল)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (Sharpened স্কেল, 16 নমুনা)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Sharpened স্কেল, 32 নমুনা)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Sharpened স্কেল, 36 নমুনা)" Basic.Settings.Audio="অডিও" Basic.Settings.Audio.SampleRate="নমুনা হার" @@ -489,7 +489,6 @@ Basic.Settings.Advanced.Video.ColorRange.Partial="আংশিক" Basic.Settings.Advanced.Video.ColorRange.Full="পূর্ণ" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="পূর্ব-নির্ধারিত" Basic.Settings.Advanced.StreamDelay="স্ট্রিম বিলম্ব" -Basic.Settings.Advanced.StreamDelay.Duration="দৈর্ঘ্য (সেকেন্ড)" Basic.Settings.Advanced.StreamDelay.Preserve="বিরোধিতায় লিপ্ত পয়েন্ট (বাড়তে দেরি) সংরক্ষণের সময় পুনরায় সংযোগ করা হচ্ছে" Basic.AdvAudio.AudioTracks="ট্র্যাক" diff --git a/UI/data/locale/ca-ES.ini b/UI/data/locale/ca-ES.ini index 6642e91..10ff008 100644 --- a/UI/data/locale/ca-ES.ini +++ b/UI/data/locale/ca-ES.ini @@ -23,7 +23,7 @@ Settings="Configuració" Display="Pantalla" Name="Nom" Exit="Surt" -Mixer="Mesclador" +Mixer="Mesclador d'àudio" Browse="Navega" Mono="Mono" Stereo="Estèreo" @@ -91,6 +91,8 @@ AlreadyRunning.LaunchAnyway="Executa de totes maneres" DockCloseWarning.Title="Tancament de la finestra acoblada" DockCloseWarning.Text="Heu tancat una finestra acoblada. Si voleu que es mostri novament, utilitzeu l'opció Visualitza → Acoblador de la barra de menús." +ExtraBrowsers.Info="Afegiu contingut inserint un nom i l'URL i feu clic al botó Aplica o Tanca per obrir. Podeu afegir o suprimir contingut en qualsevol moment." + Auth.Authing.Title="S'està autenticant..." Auth.Authing.Text="S'està autenticant amb %1, espereu..." Auth.AuthFailure.Title="Error d'autenticació" @@ -107,6 +109,7 @@ TwitchAuth.Stats="Estat del Twitch" TwitchAuth.Feed="Activitat del mur del Twitch" TwitchAuth.TwoFactorFail.Title="No s'ha pogut consultar la clau de la transmissió" TwitchAuth.TwoFactorFail.Text="L'OBS no ha pogut connectar amb el vostre compte del Twitch. Assegureu-vos que l'autenticació en 2 passos està habilitada a les opcions de seguretat del Twitch, atès que és un requeriment per retransmetre." +RestreamAuth.Channels="Canals al Restream" Copy.Filters="Copia els filtres" Paste.Filters="Enganxa els filtres" @@ -139,7 +142,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 o 30, però utilitza l'alta res Basic.AutoConfig.VideoPage.CanvasExplanation="La resolució del llenç (base) no és necessàriament la mateixa que la resolució de la transmissió o enregistrament. La resolució actual pot ser reduïda del llenç per reduir l'ús dels recursos o de la tassa de bits." Basic.AutoConfig.StreamPage="Informació de la transmissió" Basic.AutoConfig.StreamPage.SubTitle="Introduïu informació sobre la seva transmissió" -Basic.AutoConfig.StreamPage.ConnectAccount="Connecta un compte (opcional)" +Basic.AutoConfig.StreamPage.ConnectAccount="Connecteu-vos a un compte (recomanat)" Basic.AutoConfig.StreamPage.DisconnectAccount="Desconnecta el compte" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Voleu desconnectar el compte?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Aquest canvi s'aplicarà immediatament. Segur que voleu desconnectar el compte?" @@ -240,6 +243,9 @@ ConfirmStart.Text="Està segur que desitja iniciar la transmissió?" ConfirmStop.Title="Atura la transmissió?" ConfirmStop.Text="Està segur que desitja aturar la transmissió?" +ConfirmStopRecord.Title="Voleu aturar l'enregistrament?" +ConfirmStopRecord.Text="Segur que voleu aturar l'enregistrament?" + ConfirmBWTest.Title="Test d'amplada de banda" ConfirmBWTest.Text="Heu configurat l'OBS en mode Test d'amplada de banda. Aquest mode us permet analitzar la connexió sense cap retransmissió en directe. Una vegada finalitzada l'anàlisi, inhabiliteu aquest mode perquè el públic pugui veure la retransmissió.\n\nVoleu continuar?" @@ -255,6 +261,8 @@ Output.StartRecordingFailed="No s'ha pogut iniciar la gravació" Output.StartReplayFailed="No s'ha pogut iniciar la memòria intermèdia de reproducció" Output.StartFailedGeneric="Error en iniciar la sortida. Comproveu el registre per més detalls.\n\nAvís: Si utilitzeu els codificadors NVENC o AMD, assegureu-vos que els controladors de vídeo estan actualitzats." +Output.ReplayBuffer.PauseWarning.Title="No es poden desar les repeticions mentre estigui en pausa" +Output.ReplayBuffer.PauseWarning.Text="Advertència: No es poden desar les repeticions mentre la gravació estigui en pausa." Output.ConnectFail.Title="Error en connectar" Output.ConnectFail.BadPath="Ruta o adreça URL no vàlida. Si us plau, comproveu la configuració per confirmar que són vàlids." @@ -444,6 +452,8 @@ Basic.Main.StartRecording="Inicia l'enregistrament" Basic.Main.StartReplayBuffer="Inicia la reproducció de la memòria intermèdia" Basic.Main.StartStreaming="Inicia la transmissió" Basic.Main.StopRecording="Atura l'enregistrament" +Basic.Main.PauseRecording="Pausa la gravació" +Basic.Main.UnpauseRecording="Reprèn la gravació" Basic.Main.StoppingRecording="Aturant l'enregistrament..." Basic.Main.StopReplayBuffer="Atura la reproducció de la memòria intermèdia" Basic.Main.StoppingReplayBuffer="S'està aturant la reproducció de la memòria intermèdia..." @@ -544,6 +554,7 @@ Basic.Settings.General.EnableAutoUpdates="Comprova si hi ha actualitzacions auto Basic.Settings.General.OpenStatsOnStartup="Obre el diàleg d'estadístiques a l'inici" Basic.Settings.General.WarnBeforeStartingStream="Mostra diàleg de confirmació quan s'iniciï una transmissió" Basic.Settings.General.WarnBeforeStoppingStream="Mostra diàleg de confirmació quan s'aturi una transmissió" +Basic.Settings.General.WarnBeforeStoppingRecord="Mostra un missatge de confirmació en aturar un enregistrament" Basic.Settings.General.Projectors="Projectors" Basic.Settings.General.HideProjectorCursor="Amaga el cursor sobre projectors" Basic.Settings.General.ProjectorAlwaysOnTop="Projectors sempre en la part superior" @@ -591,12 +602,15 @@ Basic.Settings.Output.Encoder="Codificador" Basic.Settings.Output.SelectDirectory="Seleccioneu el directori de gravació" Basic.Settings.Output.SelectFile="Seleccioni l'arxiu de gravació" Basic.Settings.Output.EnforceBitrate="Forçar límits de tassa de bits al servei d'streaming" +Basic.Settings.Output.DynamicBitrate="Canvia dinàmicament la ràtio per manegar la saturació" +Basic.Settings.Output.DynamicBitrate.Beta="Canvia dinàmicament la ràtio per manegar la saturació (Beta)" +Basic.Settings.Output.DynamicBitrate.TT="En comptes de perdre fotogrames per reduir la saturació, canvia dinàmicament la ràtio al vol.\n\nTingueu en compte que això pot incrementar el retard per als espectadors si hi ha cap saturació important.\nEn baixar la ràtio, pot trigar uns minuts a restaurar el valor original.\n\nActualment només suportat per a RTMP." Basic.Settings.Output.Mode="Mode de sortida" Basic.Settings.Output.Mode.Simple="Simple" Basic.Settings.Output.Mode.Adv="Avançat" Basic.Settings.Output.Mode.FFmpeg="Sortida FFmpeg" Basic.Settings.Output.UseReplayBuffer="Activa la reproducció de la memòria intermèdia" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Temps de reproducció màxim (segons)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Temps màxim de repetició" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memòria màxima (MB)" Basic.Settings.Output.ReplayBuffer.Estimate="Ús aproximat de memòria: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="No es pot estimar l'ús de memòria. Establiu el límit màxim de memòria." @@ -611,6 +625,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Qualitat molt elevada, mida de Basic.Settings.Output.Simple.RecordingQuality.Lossless="Qualitat sense pèrdues, mida de l'arxiu molt gran" Basic.Settings.Output.Simple.Warn.VideoBitrate="ADVERTÈNCIA: La transmissió del vídeo s'establirà a %1, que és el límit superior per al servei de streaming actual. Si està segur que vol anar per sobre de %1, activi les opcions avançades del codificador i desactivi \"Forçar límits de tassa de bits al servei d'streaming\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="ADVERTÈNCIA: La transmissió d'àudio s'establirà a %1, que és el límit superior per al servei de streaming actual. Si està segur que vol anar per sobre de %1, activi les opcions avançades del codificador i desactivi \"Forçar límits de tassa de bits al servei d'streaming\"." +Basic.Settings.Output.Simple.Warn.CannotPause="Atenció: No es poden pausar els enregistraments si la qualitat està configurada a «Mateixa que en directe»." Basic.Settings.Output.Simple.Warn.Encoder="Advertiment: Gravar amb un software codificador en una qualitat diferent que el directe requerirà ús de CPU addicional si el directe i la gravació es fan a la vegada." Basic.Settings.Output.Simple.Warn.Lossless="Advertiment: La qualitat sense pèrdues genera mides d'arxiu gegantines! La qualitat sense pèrdues pot utilitzar un total de 7 gigabytes d'espai de disc per minut a alta resolució i FPS. Aquesta qualitat no és recomanable per a enregistraments llargs llevat que tingui una gran quantitat d'espai de disc disponible." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Esteu segur que voleu utilitzar qualitat sense pèrdues?" @@ -623,7 +638,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Programari (preconfiguraci Basic.Settings.Output.VideoBitrate="Bitrate de vídeo" Basic.Settings.Output.AudioBitrate="Bitrate d'àudio" Basic.Settings.Output.Reconnect="Torna a connectar automàticament" -Basic.Settings.Output.RetryDelay="Retard de tornar a provar (segons)" Basic.Settings.Output.MaxRetries="Nombre màxim de reintents" Basic.Settings.Output.Advanced="Activar configuració de codificador avançada" Basic.Settings.Output.EncoderPreset="Valors predefinits del codificador" @@ -694,7 +708,8 @@ Basic.Settings.Video.DisableAero="Desactiva l'Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilineal (més ràpida, però borrós si s'escala)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (escalat accentuat, 16 mostres)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (escalat accentuat, 32 mostres)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (escalat accentuat, 36 mostres)" +Basic.Settings.Video.DownscaleFilter.Area="Àrea (suma ponderada, 4/6/9 mostres)" Basic.Settings.Audio="Àudio" Basic.Settings.Audio.SampleRate="Frequència de mostreig" @@ -708,7 +723,7 @@ Basic.Settings.Audio.PeakMeterType="Tipus de mesurador de pics" Basic.Settings.Audio.PeakMeterType.SamplePeak="Pic de mostra" Basic.Settings.Audio.PeakMeterType.TruePeak="True Peak (ús elevat de la CPU)" Basic.Settings.Audio.MultiChannelWarning.Enabled="ATENCIÓ: El so envoltant està habilitat." -Basic.Settings.Audio.MultichannelWarning="Si esteu retransmetent, verifiqueu que el servei triat suporta el so envoltant, tant a la reproducció d'entrada com de sortida. El Twitch, el Facebook 360 Live, el Mixer RTMP i el Smashcast són exemples on està completament suportat. Encara que el Facebook Live i el YouTube Live accepten l'entrada de so envoltant, el Facebook Live la converteix a estèreo i el YouTube Live la reprodueix només en 2 canals.\n\nEls filtres d'àudio de l'OBS són compatibles amb el so envoltant, encara que no es garanteix la compatibilitat amb connectors VST." +Basic.Settings.Audio.MultichannelWarning="Si esteu retransmetent, verifiqueu que el servei triat suporta el so envoltant, tant a la reproducció d'entrada com de sortida. El Facebook 360 Live, el Mixer RTMP i el Smashcast són exemples on està completament suportat. Encara que el Facebook Live i el YouTube Live accepten l'entrada de so envoltant, el Facebook Live la converteix a estèreo i el YouTube Live la reprodueix només en 2 canals.\n\nEls filtres d'àudio de l'OBS són compatibles amb el so envoltant, encara que no es garanteix la compatibilitat amb connectors VST." Basic.Settings.Audio.MultichannelWarning.Title="Voleu habilitar el so envoltant?" Basic.Settings.Audio.MultichannelWarning.Confirm="Segur que voleu habilitar el so envoltant?" Basic.Settings.Audio.Devices="Dispositius" @@ -743,23 +758,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositiu de monitorització" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Per defecte" Basic.Settings.Advanced.Audio.DisableAudioDucking="Desactiva la reducció d'àudio de Windows" Basic.Settings.Advanced.StreamDelay="Retard del directe" -Basic.Settings.Advanced.StreamDelay.Duration="Durada (en segons)" +Basic.Settings.Advanced.StreamDelay.Duration="Durada" Basic.Settings.Advanced.StreamDelay.Preserve="Preservar el punt de tall (augmenta retard) quan s'estigui reconnectant" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Ús de memòria estimat: %1 MB" Basic.Settings.Advanced.Network="Xarxa" Basic.Settings.Advanced.Network.BindToIP="Enllaçar amb" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Activa el nou codi de xarxa" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Mode de baixa latència" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Comportament del focus amb les dreceres" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="No inhabilitis les dreceres" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Inhabilita les tecles de drecera quan la finestra principal estigui en primer pla" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Inhabilita les dreceres si la pantalla principal no és el focus" Basic.Settings.Advanced.AutoRemux="Converteix automàticament a mp4" Basic.Settings.Advanced.AutoRemux.MP4="(enregistra com a mkv)" Basic.AdvAudio="&Propietats avançades d'àudio" Basic.AdvAudio.Name="Nom" Basic.AdvAudio.Volume="Volum" -Basic.AdvAudio.Mono="Mescla a Mono" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Balanç" -Basic.AdvAudio.SyncOffset="Correcció de sincronització (ms)" +Basic.AdvAudio.SyncOffset="Correcció de sincronització" Basic.AdvAudio.Monitoring="Monitorització d'àudio" Basic.AdvAudio.Monitoring.None="Monitorització desactivada" Basic.AdvAudio.Monitoring.MonitorOnly="Només monitorizació (silencia la sortida)" @@ -825,6 +843,7 @@ SceneItemHide="Amaga «%1»" OutputWarnings.NoTracksSelected="Heu de seleccionar almenys una cançó" OutputWarnings.MultiTrackRecording="Advertiment: Alguns formats (com FLV) no suporten múltiples cançons per gravació" OutputWarnings.MP4Recording="Advertència: els enregistraments creats en MP4/MOV no es podran recuperar si el fitxer no es pot finalitzar (p. ex. degut a un mal funcionament del sistema o interrupcions, etc.) Si voleu enregistrar diverses pistes d'àudio, considereu utilitzar el format MKV i convertir l'enregistrament a MP4/MOV després d'haver finalitzat (Fitxer → Conversió de gravació)" +OutputWarnings.CannotPause="Advertència: les gravacions no es poden aturar si el codificador de gravació està configurat a «(Utilitza el codificador de flux)»" FinalScene.Title="Supressió de l'escena" FinalScene.Text="Cal que hi hagi almenys una escena." diff --git a/UI/data/locale/cs-CZ.ini b/UI/data/locale/cs-CZ.ini index f0a4aca..ce1c9d5 100644 --- a/UI/data/locale/cs-CZ.ini +++ b/UI/data/locale/cs-CZ.ini @@ -23,7 +23,7 @@ Settings="Nastavení" Display="Obrazovka" Name="Název" Exit="Ukončit" -Mixer="Směšovač" +Mixer="Směšovač zvuku" Browse="Procházet" Mono="Mono" Stereo="Stereo" @@ -91,6 +91,10 @@ AlreadyRunning.LaunchAnyway="Spustit tak či tak" DockCloseWarning.Title="Zavření dokovatelného okna" DockCloseWarning.Text="Právě jste zavřeli dokovatelné okno. Pokud byste ho chtěli zobrazit znovu, tak použijte menu Zobrazit → Doky." +ExtraBrowsers="Vlastní doky prohlížeče" +ExtraBrowsers.Info="Přidejte doky zadáním názvu a URL a poté klikněte Použít nebo Zavřít pro otevření doků. Doky můžete přidat či odebrat kdykoliv." +ExtraBrowsers.DockName="Název doku" + Auth.Authing.Title="Přihlašování ..." Auth.Authing.Text="Přihlašování ke službě %1 ..." Auth.AuthFailure.Title="Přihlášení se nezdařilo" @@ -107,6 +111,7 @@ TwitchAuth.Stats="Statistiky služby Twitch" TwitchAuth.Feed="Informační kanál služby Twitch" TwitchAuth.TwoFactorFail.Title="Nepovedlo se získat vysílací klíč" TwitchAuth.TwoFactorFail.Text="OBS se nemohl připojit k vašemu Twitch účtu. Zkontrolujte, zda máte nastaveno dvoufázové ověření ve vašem nastavení bezpečnosti, jelikož je to pro vysílání nutné." +RestreamAuth.Channels="Restream kanály" Copy.Filters="Kopírovat filtry" Paste.Filters="Vložit filtry" @@ -139,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 nebo 30, ale preferuji vyšší Basic.AutoConfig.VideoPage.CanvasExplanation="Poznámka: Základní rozlišení není nutně stejné jako rozlišení, ve kterém budete vysílat či nahrávat. Vaše opravdové rozlišení může být několikrát zmenšeno oproti základnímu rozlišení, aby bylo sníženo využití prostředků nebo požadavků na bitrate." Basic.AutoConfig.StreamPage="Informace o vysílání" Basic.AutoConfig.StreamPage.SubTitle="Prosím zadejte své informace o vysílání" -Basic.AutoConfig.StreamPage.ConnectAccount="Připojit účet (volitelné)" +Basic.AutoConfig.StreamPage.ConnectAccount="Připojit účet (doporučeno)" Basic.AutoConfig.StreamPage.DisconnectAccount="Odpojit účet" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Odpojení účtu" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Tato změna proběhne okamžitě. Opravdu si přejete odpojit účet ?" @@ -240,11 +245,14 @@ ConfirmStart.Text="Opravdu si přejete začít vysílat ?" ConfirmStop.Title="Zastavit vysílání ?" ConfirmStop.Text="Opravdu si přejete zastavit vysílání ?" +ConfirmStopRecord.Title="Zastavit nahrávání?" +ConfirmStopRecord.Text="Opravdu si přejete zastavit nahrávání ?" + ConfirmBWTest.Title="Spuštění testu rychlosti připojení" ConfirmBWTest.Text="Nastavili jste OBS do režimu testování připojení. Tento režim vám umožňuje otestovat vaše připojení bez toho, abyste vysílali. Poté co skončíte s testováním jej budete muset vypnout, aby vaše vysílání viděli vaši diváci.\n\nChcete začít s testováním ?" ConfirmExit.Title="Ukončit OBS ?" -ConfirmExit.Text="Ukončením budou všechna vysílání/záznamy zastavena. Jste si jisti skončit ?" +ConfirmExit.Text="OBS je stále aktivní. Ukončením budou všechna vysílání/záznamy zastavena. Jste si jisti skončit ?" ConfirmRemove.Title="Potvrzení odebrání" ConfirmRemove.Text="Opravdu si přejete odebrat '$1'?" @@ -255,6 +263,8 @@ Output.StartRecordingFailed="Chyba při spouštění nahrávání" Output.StartReplayFailed="Chyba při spouštění nahrávání do paměti" Output.StartFailedGeneric="Nastala chyba při začátku nahrávání. Zkontrolujte, prosím, textový záznam pro další podrobnosti.\n\nPoznámka: Pokud používáte enkodér NVENC či AMD, zkontrolujte zda používáte aktuální verzi grafického ovladače." +Output.ReplayBuffer.PauseWarning.Title="Při pozastavení nelze ukládat záznamy" +Output.ReplayBuffer.PauseWarning.Text="Varování: Záznamy nelze ukládat, pokud je nahrávání pozastaveno." Output.ConnectFail.Title="Spojení se nezdařilo" Output.ConnectFail.BadPath="Chybná cesta nebo adresa připojení. Zkontrolujte, prosím, správnost svých nastavení." @@ -444,6 +454,8 @@ Basic.Main.StartRecording="Začít nahrávat" Basic.Main.StartReplayBuffer="Spustit záznam do paměti" Basic.Main.StartStreaming="Začít vysílat" Basic.Main.StopRecording="Zastavit nahrávání" +Basic.Main.PauseRecording="Pozastavit nahrávání" +Basic.Main.UnpauseRecording="Pokračovat v nahrávání" Basic.Main.StoppingRecording="Zastavuji nahrávání..." Basic.Main.StopReplayBuffer="Zastavit záznam do paměti" Basic.Main.StoppingReplayBuffer="Zastavuji záznam do paměti..." @@ -502,6 +514,7 @@ Basic.MainMenu.View.Toolbars="Liš&ty nástrojů" Basic.MainMenu.View.Docks="Doky" Basic.MainMenu.View.Docks.ResetUI="Resetovat rozhraní" Basic.MainMenu.View.Docks.LockUI="Zamknout rozhraní" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Vlastní doky prohlížeče..." Basic.MainMenu.View.Toolbars.Listboxes="Seznamy (&L)" Basic.MainMenu.View.SceneTransitions="Pře&chody scény" Basic.MainMenu.View.StatusBar="&Stavový řádek" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="Automaticky kontrolovat aktualizace p Basic.Settings.General.OpenStatsOnStartup="Otevřít okno statistik při spuštění" Basic.Settings.General.WarnBeforeStartingStream="Vyžadovat potvrzení pro spuštění vysílání" Basic.Settings.General.WarnBeforeStoppingStream="Vyžadovat potvrzení pro ukončení vysílání" +Basic.Settings.General.WarnBeforeStoppingRecord="Vyžadovat potvrzení pro ukončení nahrávání" Basic.Settings.General.Projectors="Projektory" Basic.Settings.General.HideProjectorCursor="Skrýt kurzor přes projektor" Basic.Settings.General.ProjectorAlwaysOnTop="Zobrazovat projektory tak, aby vždy byly navrchu" @@ -591,12 +605,15 @@ Basic.Settings.Output.Encoder="Enkodér" Basic.Settings.Output.SelectDirectory="Vyberte složku pro nahrávání" Basic.Settings.Output.SelectFile="Vyberte soubor pro nahrávání" Basic.Settings.Output.EnforceBitrate="Vynutit omezení bitratu streamovací služby" +Basic.Settings.Output.DynamicBitrate="Dynamicky měnit bitrate v závislosti na zahlcení sítě" +Basic.Settings.Output.DynamicBitrate.Beta="Dynamicky měnit bitrate v závislosti na zahlcení sítě (Beta)" +Basic.Settings.Output.DynamicBitrate.TT="Místo zahazování snímků, pro snížení zahlcení sítě, bude průběžně měněn bitrate.\n\nMějte na vědomí, že se může zvýšit odezva pro diváky, pokud dojde k náhlému zahlcení sítě.\nPo snížení bitratu to může trvat pár minut, než se zase navýší.\n\nZatím je podporováno pouze RTMP." Basic.Settings.Output.Mode="Režim výstupu" Basic.Settings.Output.Mode.Simple="Jednoduché" Basic.Settings.Output.Mode.Adv="Rozšířené" Basic.Settings.Output.Mode.FFmpeg="Výstup FFmpeg" Basic.Settings.Output.UseReplayBuffer="Povolit záznam do paměti" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximální čas záznamu (s)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximální čas na opakování" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximální využití paměti (MB)" Basic.Settings.Output.ReplayBuffer.Estimate="Přibližné využití paměti: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Nedokáži odhadnout využití paměti. Nastavte, prosím, maximální využití paměti." @@ -611,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Nerozeznatelný pokles kvality Basic.Settings.Output.Simple.RecordingQuality.Lossless="Lossless, obrovské soubory" Basic.Settings.Output.Simple.Warn.VideoBitrate="Varování: Bitrate videa bude nastaven %1, což je maximum, které tato streamovací služba umožňuje. Pokud si jste jisti, že chcete tento limit překročit, povolte rožšířené možnosti enkodéru a odškrtněte \"Vynutit omezení bitratu streamovací služby\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Varování: Bitrate zvuku bude nastaven %1, což je maximum, které tato streamovací služba umožňuje. Pokud si jste jisti, že chcete tento limit překročit, povolte rožšířené možnosti enkodéru a odškrtněte \"Vynutit omezení bitratu streamovací služby\"." +Basic.Settings.Output.Simple.Warn.CannotPause="Varování: Nahrávání není možné pozastavit, pokud je nahrávací kvalita nastavena na \"Stejná jako vysílaná\"." Basic.Settings.Output.Simple.Warn.Encoder="Varování: Nahrávání se softwarovým enkodérem v jiné kvalitě než je vysílaná bude CPU využívat více, pokud budete vysílat a nahrávat současně." Basic.Settings.Output.Simple.Warn.Lossless="Varování: Při použití této kvality budou výsledné nahrávky obrovské! Při použití vysokého rozlišení a snímkování mohou využít až 7 GB diskového prostoru za minutu nahrávky. Tato kvalita není doporučena pro dlouhé nahrávky, pokud nemáte opravdu velký volný prostor na disku." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Opravdu chcete použít tuto kvalitu ?" @@ -623,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softwarový (x264 předvolb Basic.Settings.Output.VideoBitrate="Bitrate videa" Basic.Settings.Output.AudioBitrate="Bitrate zvuku" Basic.Settings.Output.Reconnect="Automaticky obnovit spojení" -Basic.Settings.Output.RetryDelay="Čas do pokusu (vteřiny)" +Basic.Settings.Output.RetryDelay="Doba opakování" Basic.Settings.Output.MaxRetries="Maximální počet pokusů" Basic.Settings.Output.Advanced="Povolit rozšířené nastavení enkodéru" Basic.Settings.Output.EncoderPreset="Předvolba enkodéru" @@ -688,13 +706,14 @@ Basic.Settings.Video.FPSFraction="Dílčí hodnota FPS" Basic.Settings.Video.Numerator="Čitatel" Basic.Settings.Video.Denominator="Jmenovatel" Basic.Settings.Video.Renderer="Vykreslovač" -Basic.Settings.Video.InvalidResolution="Chybná hodnota rozlišení. Správný formát je [width]x[height] (např. 1920x1080)" +Basic.Settings.Video.InvalidResolution="Chybná hodnota rozlišení. Správný formát je [šířka]x[výška] (např. 1920x1080)" Basic.Settings.Video.CurrentlyActive="Obrazový výstup je zapnutý. Pro změnu nastavení vypněte všechny výstupy." Basic.Settings.Video.DisableAero="Zakázat Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilineární (Nejrychlejší, ale rozmazané při škálování)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bikubické (Ostré při škálování, 16 vzorků)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Ostré při škálování, 32 vzorků)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Ostré při škálování, 36 vzorků)" +Basic.Settings.Video.DownscaleFilter.Area="Oblast (vážený součet, 4/6/9 vzorků)" Basic.Settings.Audio="Zvuk" Basic.Settings.Audio.SampleRate="Vzorkovací frekvence" @@ -708,7 +727,7 @@ Basic.Settings.Audio.PeakMeterType="Typ měřiče špičky" Basic.Settings.Audio.PeakMeterType.SamplePeak="Špička vzorky" Basic.Settings.Audio.PeakMeterType.TruePeak="Pravá špička (Vyšší využití CPU)" Basic.Settings.Audio.MultiChannelWarning.Enabled="VAROVÁNÍ: Prostorový zvuk je zapnut." -Basic.Settings.Audio.MultichannelWarning="Předtím než začnete vysílat si zkontrolujte, zda vaše vysílací služba podporuje příjem a přehrávání prostorového zvuku. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast jsou příklady služeb, které jej plně podporují. I když Facebook Live a YouTube Live oba podporují příjem prostorového zvuku, Facebook Live jej převede na stereo a YouTube Live přehrává pouze dva kanály.\n\nOBS filtry zvuku jej plně podporují, ale podpora u pluginu VST není garantována." +Basic.Settings.Audio.MultichannelWarning="Předtím než začnete vysílat si zkontrolujte, zda vaše vysílací služba podporuje příjem a přehrávání prostorového zvuku. Facebook 360 Live, Mixer RTMP, Smashcast jsou příklady služeb, které jej plně podporují. I když Facebook Live a YouTube Live oba podporují příjem prostorového zvuku, Facebook Live jej převede na stereo a YouTube Live přehrává pouze dva kanály.\n\nOBS filtry zvuku jej plně podporují, ale podpora u pluginu VST není garantována." Basic.Settings.Audio.MultichannelWarning.Title="Povolit prostorový zvuk?" Basic.Settings.Audio.MultichannelWarning.Confirm="Jste si jisti, že chcete povolit prostorový zvuk?" Basic.Settings.Audio.Devices="Zařízení" @@ -743,23 +762,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Sledovací zařízení" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Výchozí" Basic.Settings.Advanced.Audio.DisableAudioDucking="Zakázat Windows výchozí utlumování zvuku" Basic.Settings.Advanced.StreamDelay="Zpoždění vysílání" -Basic.Settings.Advanced.StreamDelay.Duration="Délka (vteřiny)" +Basic.Settings.Advanced.StreamDelay.Duration="Délka" Basic.Settings.Advanced.StreamDelay.Preserve="Zachovat zpoždění při obnovení spojení (zvýšení zpoždění)" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Přibližné využití paměti: %1 MB" Basic.Settings.Advanced.Network="Síť" Basic.Settings.Advanced.Network.BindToIP="Svázat s adresou" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Použít nový síťový kód" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Režim nízké odezvy" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Chování klávesových zkratek" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Nikdy nezakazovat klávesové zkratky" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Zakázat klávesové zkratky, když je hlavní okno aktivní" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Zakázat klávesové zkratky, když je hlavní okno neaktivní" Basic.Settings.Advanced.AutoRemux="Automaticky převést do mp4" Basic.Settings.Advanced.AutoRemux.MP4="(nahrávat jako mkv)" Basic.AdvAudio="Rozšířené vlastnosti zvuku" Basic.AdvAudio.Name="Název" Basic.AdvAudio.Volume="Hlasitost" -Basic.AdvAudio.Mono="Převést na Mono" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Vyvážení" -Basic.AdvAudio.SyncOffset="Zpoždění synchronizace (ms)" +Basic.AdvAudio.SyncOffset="Zpoždění synchronizace" Basic.AdvAudio.Monitoring="Monitorování zvuku" Basic.AdvAudio.Monitoring.None="Monitorování vypnuto" Basic.AdvAudio.Monitoring.MonitorOnly="Pouhé monitorování (ztlumit výstup)" @@ -825,6 +847,7 @@ SceneItemHide="Skrýt '%1'" OutputWarnings.NoTracksSelected="Musíte vybrat alespoň jednu stopu" OutputWarnings.MultiTrackRecording="Varování: Některé formáty (např. FLV) nepodporují více zvukových stop na nahrávku" OutputWarnings.MP4Recording="Varování: Nahrávky uložené v MP4/MOV nebude možné obnovit, pokud soubor nemohl být dokončen (např. po BSOD, výpadku napájení atp.). Pokud chcete nahrávat více zvukových stop, promyslete použití MKV a poté převedení do MP4/MOV (Soubor → Převést nahrávky)" +OutputWarnings.CannotPause="Varování: Nahrávání není možné pozastavit, pokud je kodér pro nahrávání nastaven na \"(Použít enkodér vysílání)\"" FinalScene.Title="Odstranění scény" FinalScene.Text="Musí existovat alespoň jedna scéna, proto tuto není možno odstranit." diff --git a/UI/data/locale/da-DK.ini b/UI/data/locale/da-DK.ini index 5460cfa..979344d 100644 --- a/UI/data/locale/da-DK.ini +++ b/UI/data/locale/da-DK.ini @@ -23,7 +23,7 @@ Settings="Indstillinger" Display="Skærm" Name="Navn" Exit="Afslut" -Mixer="Mixer" +Mixer="Lydmixer" Browse="Gennemse" Mono="Mono" Stereo="Stereo" @@ -91,6 +91,10 @@ AlreadyRunning.LaunchAnyway="Start alligevel" DockCloseWarning.Title="Lukker dokbart vindue" DockCloseWarning.Text="Du har netop lukket et dokbart vindue. Hvis du vil vise det igen, skal du benytte menuen Vis → Doks på menulinjen." +ExtraBrowsers="Tilpassede Browserdokker" +ExtraBrowsers.Info="Tilføj en dok ved at give den et navn og URL, og klik derefter på Anvend/Luk for at åbne den. Du kan tilføje/fjerne dokker efter behov." +ExtraBrowsers.DockName="Doknavn" + Auth.Authing.Title="Godkender..." Auth.Authing.Text="Godkender med %1, afvent venligst..." Auth.AuthFailure.Title="Godkendelsesfejl" @@ -107,6 +111,7 @@ TwitchAuth.Stats="Twitch-statistikker" TwitchAuth.Feed="Twitch-aktivitetsfeed" TwitchAuth.TwoFactorFail.Title="Stream-nøgle kunne ikke forespørges" TwitchAuth.TwoFactorFail.Text="OBS kunne ikke forbinde til din Twitch-konto. Tjek, at tofaktorgodkendelse er opsat i dine Twitch-sikkerhedsindstillinger, da dette er nødvendigt for at streame." +RestreamAuth.Channels="Restream Kanaler" Copy.Filters="Kopiér filtre" Paste.Filters="Indsæt filtre" @@ -139,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Enten 60 eller 30, men foretræk h Basic.AutoConfig.VideoPage.CanvasExplanation="Bemærk: Lærredets (basis-) opløsning er ikke nødvendigvis identisk med den opløsning, du vil streame med eller optage i. Din aktuelle stream-/optagelsesopløsning kan blive nedskaleret fra lærredsopløsningen for at reducere ressourceforbrug eller bit-hastighedskrav." Basic.AutoConfig.StreamPage="Streamoplysninger" Basic.AutoConfig.StreamPage.SubTitle="Angiv dine streamoplysninger" -Basic.AutoConfig.StreamPage.ConnectAccount="Forbind konto (valfrit)" +Basic.AutoConfig.StreamPage.ConnectAccount="Forbind konto (anbefalet)" Basic.AutoConfig.StreamPage.DisconnectAccount="Afbryd konto" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Afbryde konto?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Denne ændring effektueres straks. Sikker på, at du vil afbryde din konto?" @@ -240,6 +245,9 @@ ConfirmStart.Text="Sikker på, at du vil starte streamen?" ConfirmStop.Title="Stop stream?" ConfirmStop.Text="Sikker på, at du vil stoppe streamen?" +ConfirmStopRecord.Title="Stop optagelse?" +ConfirmStopRecord.Text="Sikker på, at du vil stoppe optagelsen?" + ConfirmBWTest.Title="Start båndbreddetest?" ConfirmBWTest.Text="Du har OBS opsat i tilstanden båndbreddetest. Denne tilstand muliggør netværksaftestning, uden at din kanal er online. Når aftestningen er gennemført, så deaktivér tilstanden, så seerne vil kunne se din stream.\n\nVil du fortsætte?" @@ -255,6 +263,8 @@ Output.StartRecordingFailed="Mislykkedes at starte optagelse" Output.StartReplayFailed="Mislykkedes at starte genafspilnings-buffer" Output.StartFailedGeneric="Start af output mislykkedes. Tjek loggen for oplysninger.\n\nBemærk: Benytter du NVENC- eller AMD-encodere, så sørg for at dine videodrivere er opdaterede." +Output.ReplayBuffer.PauseWarning.Title="Kan ikke gemme genafspilninger under pause" +Output.ReplayBuffer.PauseWarning.Text="Advarsel: Genafspilninger kan ikke gemmes, mens optagelsen er pauset." Output.ConnectFail.Title="Mislykkedes at forbinde" Output.ConnectFail.BadPath="Ugyldig sti eller forbindelses-URL. Tjek dine indstillinger for at bekræfte, at de er gyldige." @@ -444,6 +454,8 @@ Basic.Main.StartRecording="Start optagelse" Basic.Main.StartReplayBuffer="Start Genafspilnings-buffer" Basic.Main.StartStreaming="Start streaming" Basic.Main.StopRecording="Stop optagelse" +Basic.Main.PauseRecording="Sæt optagelse på pause" +Basic.Main.UnpauseRecording="Genoptag optagelse" Basic.Main.StoppingRecording="Stopper optagelse..." Basic.Main.StopReplayBuffer="Stop Genafspilnings-buffer" Basic.Main.StoppingReplayBuffer="Stopper Genafspilnings-buffer..." @@ -502,6 +514,7 @@ Basic.MainMenu.View.Toolbars="Værk&tøjslinjer" Basic.MainMenu.View.Docks="Dok'er" Basic.MainMenu.View.Docks.ResetUI="Nulstil UI" Basic.MainMenu.View.Docks.LockUI="Lås UI" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Tilpassede Browserdokker..." Basic.MainMenu.View.Toolbars.Listboxes="&Listebokse" Basic.MainMenu.View.SceneTransitions="S&ceneovergange" Basic.MainMenu.View.StatusBar="&Statusbjælke" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="Søg automatisk efter opdateringer ved Basic.Settings.General.OpenStatsOnStartup="Åbn statistikdialogen ved opstart" Basic.Settings.General.WarnBeforeStartingStream="Vis bekræftelsesdialog ved opstart af stream" Basic.Settings.General.WarnBeforeStoppingStream="Vis bekræftelsesdialog ved afslutning af stream" +Basic.Settings.General.WarnBeforeStoppingRecord="Vis bekræftelsesdialog ved stop af optagelse" Basic.Settings.General.Projectors="Projektorer" Basic.Settings.General.HideProjectorCursor="Skjul markør over projektorer" Basic.Settings.General.ProjectorAlwaysOnTop="Projektorer altid øverst" @@ -591,12 +605,15 @@ Basic.Settings.Output.Encoder="Encoder" Basic.Settings.Output.SelectDirectory="Vælg optagelsesmappe" Basic.Settings.Output.SelectFile="Vælg optagelsesfil" Basic.Settings.Output.EnforceBitrate="Håndhæv streamingtjenestes bit-hastighedsbegrænsninger" +Basic.Settings.Output.DynamicBitrate="Skift bithastighed dynamisk for at håndtere overbelastning" +Basic.Settings.Output.DynamicBitrate.Beta="Skift bithastighed dynamisk for at håndtere overbelastning (Beta)" +Basic.Settings.Output.DynamicBitrate.TT="I stedet for at droppe billeder for at reducere overbelastning, ændrer dette dynamisk bithastigheden løbende.\n\nBemærk at dette kan øge forsinkelsen, som seerne oplever, hvis der opstår betydelig pludselig overbelastning.\nNår bithastigheden falder, kan det tage op til et par få minutter for at gendanne den.\n\nKun RTMP understøttet pt." Basic.Settings.Output.Mode="Outputtilstand" Basic.Settings.Output.Mode.Simple="Simpel" Basic.Settings.Output.Mode.Adv="Avanceret" Basic.Settings.Output.Mode.FFmpeg="FFmpeg-output" Basic.Settings.Output.UseReplayBuffer="Aktivér Genafspilnings-buffer" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksimal genafspilningstid (sek.)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Maks. genafspilningstid" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maksimal hukommelse (MB)" Basic.Settings.Output.ReplayBuffer.Estimate="Estimeret hukommelsesforbrug: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Ikke kan estimere hukommelsesforbrug. Angiv en maks. hukommelsesgrænse." @@ -611,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Synlig identisk kvalitet, stor Basic.Settings.Output.Simple.RecordingQuality.Lossless="Tabsfri kvalitet, enorm stor filstørrelse" Basic.Settings.Output.Simple.Warn.VideoBitrate="Advarsel: Videostreamingbit-hastigheden sættes til %1, som er den øvre grænse for den aktuelle streamingtjeneste. Er du sikker på, at du vil at gå over %1, så aktivér avancerede encoder-valg og afmarkér \"Gennemtving streamingtjenestes bit-hastighedsbegrænsninger\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Advarsel: Audiostreamingbit-hastigheden sættes til %1, som er den øvre grænse for den aktuelle streamingtjeneste. Er du sikker på, at du vil at gå over %1, så aktivér avancerede encoder-valg og afmarkér \"Gennemtving streamingtjenestes bit-hastighedsbegrænsninger\"." +Basic.Settings.Output.Simple.Warn.CannotPause="Advarsel: Optagelser kan ikke pauses, hvis optagekvaliteten er sat til \"Samme som strream\"." Basic.Settings.Output.Simple.Warn.Encoder="Advarsel: Optagelse med en software-encoder i en anden kvalitet end den streamede vil medføre ekstra CPU-forbrug, hvis du streamer og optager samtidigt." Basic.Settings.Output.Simple.Warn.Lossless="Advarsel: Tabsfri kvalitet genererer gevaldigt store filstørrelser! Tabsfri kvalitet kan forbruge op til 7 GB diskplads pr. minut ved høje opløsninger og billedhastigheder. Tabsfri tilstand anbefales ikke til lange optagelser, medmindre du har masser af tilgængelig diskplads." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Sikker på, at du vil benytte tabsfri kvalitet?" @@ -623,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 lavt, forval Basic.Settings.Output.VideoBitrate="Videobit-hastighed" Basic.Settings.Output.AudioBitrate="Audiobit-hastighed" Basic.Settings.Output.Reconnect="Automatisk gentilslutning" -Basic.Settings.Output.RetryDelay="Forsøg igen-forsinkelse (sek.)" +Basic.Settings.Output.RetryDelay="Prøv igen-forsinkelse" Basic.Settings.Output.MaxRetries="Maks. antal forsøg" Basic.Settings.Output.Advanced="Aktivér avancerede Encoder-indstillinger" Basic.Settings.Output.EncoderPreset="Encoder-forvalg" @@ -688,13 +706,14 @@ Basic.Settings.Video.FPSFraction="Fraktioneret FPS-værdi" Basic.Settings.Video.Numerator="Tæller" Basic.Settings.Video.Denominator="Nævner" Basic.Settings.Video.Renderer="Gengiver" -Basic.Settings.Video.InvalidResolution="Ugyldig opløsningsværdi. Skal være [width]x[height] (f.eks. 1.920x1.080)" +Basic.Settings.Video.InvalidResolution="Ugyldig opløsning. Skal være [bredde]x[højde] (dvs. 1.920x1.080)" Basic.Settings.Video.CurrentlyActive="Videooutput erpt. aktivt. Afbryd evt. outputs fra for at ændre videoindstillinger." Basic.Settings.Video.DisableAero="Deaktivér Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinær (hurtigst, men sløret ved skalering)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bikubisk (skarp skalering, 16 samples)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (skarp skalering, 32 samples)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (skarp skalering, 36 samples)" +Basic.Settings.Video.DownscaleFilter.Area="Område (vægtet sum, 4/6/9 eksempler)" Basic.Settings.Audio="Lyd" Basic.Settings.Audio.SampleRate="Samplingshastighed" @@ -708,7 +727,7 @@ Basic.Settings.Audio.PeakMeterType="Peak Meter-type" Basic.Settings.Audio.PeakMeterType.SamplePeak="Samplingsspidsværdi" Basic.Settings.Audio.PeakMeterType.TruePeak="Sand spidsværdi (højere CPU-belastning)" Basic.Settings.Audio.MultiChannelWarning.Enabled="ADVARSEL: Surround Sound-lyd er aktiveret." -Basic.Settings.Audio.MultichannelWarning="Tjek ifm. streaming om din streamingtjeneste understøtter både Surround Sound-input og -afspilning. Twitch, Facebook 360 Live, Mixer RTMP og Smashcast er eksempler, hvor surroundlyd understøttes fuldt ud. Selvom Facebook Live og YouTube Live begge accepterer surround input, nedmikser Facebook Live til stereo, og YouTube Live afspiller kun to kanaler.\n\nOBS-lydfiltre er kompatible med surroundlyd, dog er VST-pluginsupport ikke garanteret." +Basic.Settings.Audio.MultichannelWarning="Tjek ifm. streaming om din streamingtjeneste understøtter både Surround Sound-input og -afspilning. Facebook 360 Live, Mixer RTMP og Smashcast er eksempler, hvor surroundlyd understøttes fuldt ud. Selvom Facebook Live og YouTube Live begge accepterer surround input, nedmikser Facebook Live til stereo, og YouTube Live afspiller kun to kanaler.\n\nOBS-lydfiltre er kompatible med surroundlyd, dog er VST-pluginsupport ikke garanteret." Basic.Settings.Audio.MultichannelWarning.Title="Aktivér Surround Sound-lyd?" Basic.Settings.Audio.MultichannelWarning.Confirm="Sikker på, at du vil aktivere Surround Sound-lyd?" Basic.Settings.Audio.Devices="Enheder" @@ -743,23 +762,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Moniteringsenhed" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Standard" Basic.Settings.Advanced.Audio.DisableAudioDucking="Deaktivér Windows-lyddæmpning" Basic.Settings.Advanced.StreamDelay="Streamforsinkelse" -Basic.Settings.Advanced.StreamDelay.Duration="Varighed (sek.)" +Basic.Settings.Advanced.StreamDelay.Duration="Varighed" Basic.Settings.Advanced.StreamDelay.Preserve="Bevar afskæringspunkt (forøg forsinkelse) ved gentilslutning" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Estimeret hukommelsesforbrug: %1 MB" Basic.Settings.Advanced.Network="Netværk" Basic.Settings.Advanced.Network.BindToIP="Bind til IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Aktivér ny netværkskode" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Lav forsinkelsestilstand" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Genvejstast-fokusadfærd" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Deaktivér aldrig genvejstaster" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Deaktivér genvejstaster, når hovedvinduet er i fokus" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Deaktivér genvejstaster, når vindue ikke er i fokus" Basic.Settings.Advanced.AutoRemux="Remux automatisk til mp4" Basic.Settings.Advanced.AutoRemux.MP4="(optag som mkv)" Basic.AdvAudio="Avancerede lydegenskaber" Basic.AdvAudio.Name="Navn" Basic.AdvAudio.Volume="Lydstyrke" -Basic.AdvAudio.Mono="Nedmix til Mono" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Balance" -Basic.AdvAudio.SyncOffset="Synkr-forskydning (ms)" +Basic.AdvAudio.SyncOffset="Synk-forskydning" Basic.AdvAudio.Monitoring="Lydovervågning" Basic.AdvAudio.Monitoring.None="Overvågning Fra" Basic.AdvAudio.Monitoring.MonitorOnly="Kun overvågning (gør output tavs)" @@ -825,6 +847,7 @@ SceneItemHide="Skjul '%1'" OutputWarnings.NoTracksSelected="Du skal vælge minimum ét spor" OutputWarnings.MultiTrackRecording="Advarsel: Visse formater (såsom FLV) understøtter ikke flere spor pr. optagelse" OutputWarnings.MP4Recording="Advarsel: MP4-/MOV-optagelser vil ikke kunne genoprettes, såfremt filen ikke kan færdiggøres (grundet f.eks. BSOD'er, strømafbrydelse mv.). Vil du optage flere lydspor, så overvej at benytte MKV, og remuxe optagelsen til MP4, efter at den er færdiggjort (Fil → Remux optagelser)" +OutputWarnings.CannotPause="Advarsel: Optagelser kan ikke pauses, hvis optagelsesencoderen er sat til \"(Brug strreamenccoder)\"" FinalScene.Title="Slet scene" FinalScene.Text="Mindst én scene kræves." diff --git a/UI/data/locale/de-DE.ini b/UI/data/locale/de-DE.ini index 273602d..32e7ec0 100644 --- a/UI/data/locale/de-DE.ini +++ b/UI/data/locale/de-DE.ini @@ -23,11 +23,11 @@ Settings="Einstellungen" Display="Bildschirm" Name="Name" Exit="Beenden" -Mixer="Mixer" +Mixer="Audio‐Mixer" Browse="Durchsuchen" Mono="Mono" Stereo="Stereo" -DroppedFrames="Ausgelassene Frames %1 (%2 %)" +DroppedFrames="Ausgelassene Frames %1 (%2 %)" StudioProgramProjector="Vollbildprojektor (Programm)" PreviewProjector="Vollbildprojektor (Vorschau)" SceneProjector="Vollbildprojektor (Szene)" @@ -47,8 +47,8 @@ Untitled="Unbenannt" New="Neu" Duplicate="Duplizieren" Enable="Aktivieren" -DisableOSXVSync="OSX V-Sync deaktivieren" -ResetOSXVSyncOnExit="OSX V-Sync beim Beenden zurücksetzen" +DisableOSXVSync="OSX V‐Sync deaktivieren" +ResetOSXVSyncOnExit="OSX V‐Sync beim Beenden zurücksetzen" HighResourceUsage="Kodierung überlastet! Erwägen Sie Ihre Videoeinstellungen zu verringern oder benutzen Sie eine schnellere Kodierervoreinstellung." Transition="Übergang" QuickTransitions="Schnellübergänge" @@ -61,7 +61,7 @@ Hours="Stunde(n)" Minutes="Minute(n)" Seconds="Sekunde(n)" Deprecated="Veraltet" -ReplayBuffer="Replay-Puffer" +ReplayBuffer="Replay‐Puffer" Import="Importieren" Export="Exportieren" Copy="Kopieren" @@ -82,37 +82,42 @@ VerticalLayout="Vertikales Layout" Group="Gruppe" DoNotShowAgain="Nicht nochmal anzeigen" Default="(Standard)" -Calculating="Berechne …" +Calculating="Berechne …" AlreadyRunning.Title="OBS wird bereits ausgeführt" -AlreadyRunning.Text="OBS wird bereits ausgeführt! Bitte beenden Sie alle vorhandenen OBS-Instanzen, bevor Sie eine neue Instanz starten, außer Sie tun dies absichtlich. Wenn Sie OBS so eingestellt haben, dass es sich zum Infobereich minimiert, überprüfen Sie bitte, ob es dort läuft." +AlreadyRunning.Text="OBS wird bereits ausgeführt! Bitte beenden Sie alle vorhandenen OBS‐Instanzen, bevor Sie eine neue Instanz starten, außer Sie tun dies absichtlich. Wenn Sie OBS so eingestellt haben, dass es sich zum Benachrichtigungsbereich minimiert, überprüfen Sie bitte, ob es dort läuft." AlreadyRunning.LaunchAnyway="Trotzdem starten" DockCloseWarning.Title="Dockbares Fenster schließen" DockCloseWarning.Text="Sie haben gerade ein dockbares Fenster geschlossen. Wenn Sie es erneut anzeigen möchten, verwenden Sie das Menü „Ansicht” → „Docks” in der Menüleiste." -Auth.Authing.Title="Authentifizierung …" -Auth.Authing.Text="Authentifizierung mit %1, bitte warten …" +ExtraBrowsers="Benutzerdefinierte Browser‐Docks" +ExtraBrowsers.Info="Fügen Sie Docks hinzu, indem Sie ihnen einen Namen und eine URL geben und dann auf „Anwenden“ oder „Schließen“ klicken, um diese zu öffnen. Sie können jederzeit Docks hinzufügen oder entfernen." +ExtraBrowsers.DockName="Dock‐Name" + +Auth.Authing.Title="Authentifizierung …" +Auth.Authing.Text="Authentifizierung mit %1, bitte warten …" Auth.AuthFailure.Title="Authentifizierungsfehler" Auth.AuthFailure.Text="Fehler beim Authentifizieren mit %1:\n\n%2: %3" Auth.InvalidScope.Title="Authentifizierung erforderlich" Auth.InvalidScope.Text="Die Authentifizierungsanforderungen für %1 haben sich geändert. Einige Funktionen sind möglicherweise nicht verfügbar." -Auth.LoadingChannel.Title="Kanalinformationen werden geladen …" -Auth.LoadingChannel.Text="Kanalinformationen werden für %1 geladen, bitte warten …" +Auth.LoadingChannel.Title="Kanalinformationen werden geladen …" +Auth.LoadingChannel.Text="Kanalinformationen werden für %1 geladen, bitte warten …" Auth.ChannelFailure.Title="Fehler beim Laden des Kanals" Auth.ChannelFailure.Text="Fehler beim Laden der Kanalinformationen für %1\n\n%2: %3" Auth.Chat="Chat" Auth.StreamInfo="Streaminformation" -TwitchAuth.Stats="Twitch-Statistiken" -TwitchAuth.Feed="Twitch-Aktivitätsfeed" +TwitchAuth.Stats="Twitch‐Statistiken" +TwitchAuth.Feed="Twitch‐Aktivitätsfeed" TwitchAuth.TwoFactorFail.Title="Streamschlüssel konnte nicht abgefragt werden" -TwitchAuth.TwoFactorFail.Text="OBS konnte sich nicht mit Ihrem Twitch-Konto verbinden. Bitte stellen Sie sicher, dass die Zwei-Faktor-Authentifizierung in Ihren Twitch-Sicherheitseinstellungen eingerichtet ist, da diese für das Sreamen benötigt wird." +TwitchAuth.TwoFactorFail.Text="OBS konnte sich nicht mit Ihrem Twitch‐Konto verbinden. Bitte stellen Sie sicher, dass die Zwei‐Faktor‐Authentifizierung in Ihren Twitch‐Sicherheitseinstellungen eingerichtet ist, da diese für das Sreamen benötigt wird." +RestreamAuth.Channels="Restream‐Kanäle" Copy.Filters="Filter kopieren" Paste.Filters="Filter einfügen" -BrowserPanelInit.Title="Initialisiere Browser …" -BrowserPanelInit.Text="Initialisiere Browser, bitte warten …" +BrowserPanelInit.Title="Initialisiere Browser …" +BrowserPanelInit.Text="Initialisiere Browser, bitte warten …" BandwidthTest.Region="Region" BandwidthTest.Region.US="USA" @@ -120,7 +125,7 @@ BandwidthTest.Region.EU="Europa" BandwidthTest.Region.Asia="Asien" BandwidthTest.Region.Other="Andere" -Basic.FirstStartup.RunWizard="Möchten Sie den Autokonfigurationsassistent ausführen? Sie können Ihre Einstellungen auch manuell konfigurieren, indem Sie die „Einstellungen“-Schaltfläche im Hauptfenster anklicken." +Basic.FirstStartup.RunWizard="Möchten Sie den Autokonfigurationsassistent ausführen? Sie können Ihre Einstellungen auch manuell konfigurieren, indem Sie die „Einstellungen“‐Schaltfläche im Hauptfenster anklicken." Basic.FirstStartup.RunWizard.NoClicked="Wenn Sie sich umentscheiden, können Sie den Autokonfigurationsassistent jederzeit aus dem Menü „Werkzeuge“ erneut ausführen." Basic.AutoConfig="Autokonfigurationsassistent" @@ -131,49 +136,49 @@ Basic.AutoConfig.StartPage.PrioritizeStreaming="Für das Streamen optimieren, Au Basic.AutoConfig.StartPage.PrioritizeRecording="Für das Aufnehmen optimieren, Streamen ist zweitrangig" Basic.AutoConfig.VideoPage="Videoeinstellungen" Basic.AutoConfig.VideoPage.SubTitle="Geben Sie die gewünschten Videoeinstellungen an, die Sie verwenden möchten" -Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Aktuelle verwenden (%1×%2)" -Basic.AutoConfig.VideoPage.BaseResolution.Display="Bildschirm %1 (%2×%3)" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Aktuelle verwenden (%1 × %2)" +Basic.AutoConfig.VideoPage.BaseResolution.Display="Bildschirm %1 (%2 × %3)" Basic.AutoConfig.VideoPage.FPS.UseCurrent="Aktuelle verwenden (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="Entweder 60 oder 30, aber wenn möglich 60 bevorzugen" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Entweder 60 oder 30, aber hohe Auflösung bevorzugen" -Basic.AutoConfig.VideoPage.CanvasExplanation="Hinweis: Die Basis-(Leinwand-)Auflösung ist nicht unbedingt die gleiche Auflösung, mit der Sie streamen oder aufnehmen. Ihre tatsächliche Stream-/Aufnahmeauflösung kann ausgehend von der Leinwandauflösung herunterskaliert werden, um die Ressourcennutzung oder die Bitratenanforderungen zu reduzieren." +Basic.AutoConfig.VideoPage.CanvasExplanation="Hinweis: Die Basis‐(Leinwand‐)Auflösung ist nicht unbedingt die gleiche Auflösung, mit der Sie streamen oder aufnehmen. Ihre tatsächliche Stream‐/Aufnahmeauflösung kann ausgehend von der Leinwandauflösung herunterskaliert werden, um die Ressourcennutzung oder die Bitratenanforderungen zu reduzieren." Basic.AutoConfig.StreamPage="Streaminformationen" Basic.AutoConfig.StreamPage.SubTitle="Bitte geben Sie Ihre Streaminformationen ein" -Basic.AutoConfig.StreamPage.ConnectAccount="Konto verbinden (optional)" +Basic.AutoConfig.StreamPage.ConnectAccount="Konto verbinden (empfohlen)" Basic.AutoConfig.StreamPage.DisconnectAccount="Konto trennen" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Konto trennen?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Diese Änderung wird sofort angewendet. Sind Sie sicher, dass Sie Ihr Konto trennen möchten?" Basic.AutoConfig.StreamPage.UseStreamKey="Streamschlüssel verwenden" Basic.AutoConfig.StreamPage.Service="Plattform" -Basic.AutoConfig.StreamPage.Service.ShowAll="Alle anzeigen …" -Basic.AutoConfig.StreamPage.Service.Custom="Benutzerdefiniert …" +Basic.AutoConfig.StreamPage.Service.ShowAll="Alle anzeigen …" +Basic.AutoConfig.StreamPage.Service.Custom="Benutzerdefiniert …" Basic.AutoConfig.StreamPage.Server="Server" Basic.AutoConfig.StreamPage.StreamKey="Streamschlüssel" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Link)" Basic.AutoConfig.StreamPage.PerformBandwidthTest="Bitrate mit Bandbreitentest schätzen (kann einige Minuten dauern)" Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Hardwarekodierung bevorzugen" -Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Hardwarekodierung beseitigt die meiste CPU-Auslastung, kann aber mehr Bitrate erfordern, um das gleiche Maß an Qualität zu erhalten." +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Hardwarekodierung beseitigt die meiste CPU‐Auslastung, kann aber mehr Bitrate erfordern, um das gleiche Maß an Qualität zu erhalten." Basic.AutoConfig.StreamPage.StreamWarning.Title="Streamwarnung" -Basic.AutoConfig.StreamPage.StreamWarning.Text="Der Bandbreitentest streamt randomisierte Videodaten ohne Ton zu Ihrem Kanal. Wenn Sie in der Lage sind, empfiehlt es sich, vorübergehend das Speichern von Videos zu deaktivieren und den Stream privat zu schalten, bis der Test abgeschlossen ist. Fortfahren?" +Basic.AutoConfig.StreamPage.StreamWarning.Text="Der Bandbreitentest streamt zufällige Videodaten ohne Ton zu Ihrem Kanal. Wenn Sie in der Lage sind, empfiehlt es sich, das Speichern von Videos vorrübergehend zu deaktivieren und den Stream privat zu schalten, bis der Test abgeschlossen ist. Fortfahren?" Basic.AutoConfig.TestPage="Endergebnisse" Basic.AutoConfig.TestPage.SubTitle.Testing="Das Programm führt nun eine Reihe von Tests durch, um die besten Einstellungen für Ihr System zu finden" Basic.AutoConfig.TestPage.SubTitle.Complete="Tests abgeschlossen" -Basic.AutoConfig.TestPage.TestingBandwidth="Führe Bandbreitentests durch, dies kann einige Minuten dauern …" -Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Verbinde zu: %1 …" +Basic.AutoConfig.TestPage.TestingBandwidth="Führe Bandbreitentests durch, dies kann einige Minuten dauern …" +Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Verbinde zu: %1 …" Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Keine Verbindung zu den Servern möglich, bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut." Basic.AutoConfig.TestPage.TestingBandwidth.Server="Teste Bandbreite für: %1" -Basic.AutoConfig.TestPage.TestingStreamEncoder="Teste Streamkodierer, dies kann einige Minuten dauern …" -Basic.AutoConfig.TestPage.TestingRecordingEncoder="Teste Aufnahmekodierer, dies kann einige Minuten dauern …" -Basic.AutoConfig.TestPage.TestingRes="Teste Auflösungen, dies kann einige Minuten dauern …" +Basic.AutoConfig.TestPage.TestingStreamEncoder="Teste Streamkodierer, dies kann einige Minuten dauern …" +Basic.AutoConfig.TestPage.TestingRecordingEncoder="Teste Aufnahmekodierer, dies kann einige Minuten dauern …" +Basic.AutoConfig.TestPage.TestingRes="Teste Auflösungen, dies kann einige Minuten dauern …" Basic.AutoConfig.TestPage.TestingRes.Fail="Fehler beim Starten des Kodierers" -Basic.AutoConfig.TestPage.TestingRes.Resolution="Teste Auflösung %1×%2 mit %3 FPS …" +Basic.AutoConfig.TestPage.TestingRes.Resolution="Teste Auflösung %1 × %2 mit %3 FPS …" Basic.AutoConfig.TestPage.Result.StreamingEncoder="Streamkodierer" Basic.AutoConfig.TestPage.Result.RecordingEncoder="Aufnahmekodierer" Basic.AutoConfig.TestPage.Result.Header="Das Programm hat festgestellt, dass diese geschätzten Einstellungen für Sie am besten sind:" Basic.AutoConfig.TestPage.Result.Footer="Um den Assistenten neu zu konfigurieren und es erneut zu versuchen, klicken Sie auf „Zurück“. Um die Einstellungen selbst anzupassen, klicken Sie auf „Abbrechen“ und öffnen Sie die Einstellungen." Basic.Stats="Statistiken" -Basic.Stats.CPUUsage="CPU-Auslastung" +Basic.Stats.CPUUsage="CPU‐Auslastung" Basic.Stats.HDDSpaceAvailable="Speicherplatz verfügbar" Basic.Stats.MemoryUsage="Speicherauslastung" Basic.Stats.AverageTimeToRender="Durchschnittliche Zeit, um Frame zu rendern" @@ -192,11 +197,11 @@ Basic.Stats.Bitrate="Bitrate" Basic.Stats.DiskFullIn="Datenträger voll in ugf." ResetUIWarning.Title="Sind Sie sicher, dass Sie die Benutzeroberfläche zurücksetzen möchten?" -ResetUIWarning.Text="Das Zurücksetzen der Benutzeroberfläche wird zusätzliche Docks ausblenden. Sie müssen diese Docks im „Ansicht“-Menü wieder aktivieren, wenn sie sichtbar sein sollen.\n\nSind Sie sicher, dass Sie die Benutzeroberfläche zurücksetzen möchten?" +ResetUIWarning.Text="Das Zurücksetzen der Benutzeroberfläche wird zusätzliche Docks ausblenden. Sie müssen diese Docks im „Ansicht“‐Menü wieder aktivieren, wenn sie sichtbar sein sollen.\n\nSind Sie sicher, dass Sie die Benutzeroberfläche zurücksetzen möchten?" Updater.Title="Neues Update verfügbar" Updater.Text="Es ist ein neues Update verfügbar:" -Updater.UpdateNow="Jetzt updaten" +Updater.UpdateNow="Jetzt aktualisieren" Updater.RemindMeLater="Später erinnern" Updater.Skip="Version überspringen" Updater.Running.Title="Programm derzeit aktiv" @@ -205,14 +210,14 @@ Updater.NoUpdatesAvailable.Title="Keine Updates verfügbar" Updater.NoUpdatesAvailable.Text="Zurzeit sind keine Updates verfügbar" Updater.FailedToLaunch="Konnte den Updater nicht starten" Updater.GameCaptureActive.Title="Spielaufnahme aktiv" -Updater.GameCaptureActive.Text="Die Spielaufnahmen-Hook-Bibliothek wird zurzeit verwendet. Bitte schließen Sie alle derzeit aufgenommenen Programme und Spiele (oder starten Sie Windows neu) und versuchen Sie es erneut." +Updater.GameCaptureActive.Text="Die Spielaufnahmen‐Hook‐Bibliothek wird zurzeit verwendet. Bitte schließen Sie alle derzeit aufgenommenen Programme und Spiele (oder starten Sie Windows neu) und versuchen Sie es erneut." -QuickTransitions.SwapScenes="Vorschau-/Ausgabeszene nach Übergang tauschen" -QuickTransitions.SwapScenesTT="Vertauscht die Vorschau- und Ausgabeszenen nach dem Übergang (falls die ursprüngliche Ausgabeszene noch vorhanden ist).\nEventuelle Änderungen an der originalen Ausgabeszene werden nicht rückgängig gemacht." +QuickTransitions.SwapScenes="Vorschau‐/Ausgabeszene nach Übergang tauschen" +QuickTransitions.SwapScenesTT="Vertauscht die Vorschau‐ und Ausgabeszenen nach dem Übergang (falls die ursprüngliche Ausgabeszene noch vorhanden ist).\nEventuelle Änderungen an der originalen Ausgabeszene werden nicht rückgängig gemacht." QuickTransitions.DuplicateScene="Szene duplizieren" QuickTransitions.DuplicateSceneTT="Ermöglicht das Bearbeiten von Transformationen und der Sichtbarkeit von Quellen, ohne die Ausgabe zu verändern, wenn dieselbe Szene bearbeitet wird.\nAktivieren Sie „Szene duplizieren“, um die Eigenschaften von Quellen zu bearbeiten, ohne die Ausgabe zu verändern.\nDas Ändern dieses Wertes wird die derzeitige Ausgabeszene zurücksetzen (falls sie noch existiert)." QuickTransitions.EditProperties="Quellen duplizieren" -QuickTransitions.EditPropertiesTT="Ermöglicht das Bearbeiten der Eigenschaften von Quellen, ohne die Ausgabe zu verändern, wenn dieselbe Szene bearbeitet wird.\nDies kann nur verwendet werden, wenn „Szene duplizieren“ aktiviert ist.\nBestimmte Quellen (wie Aufnahme- oder Medienquellen) unterstützen dies nicht und können nicht separat bearbeitet werden.\nDas Ändern dieses Wertes wird die derzeitige Ausgabeszene zurücksetzen (falls sie noch existiert).\n\nWarnung: Da Quellen dupliziert werden, könnte dies zusätzliche System- oder Videoressourcen verbrauchen." +QuickTransitions.EditPropertiesTT="Ermöglicht das Bearbeiten der Eigenschaften von Quellen, ohne die Ausgabe zu verändern, wenn dieselbe Szene bearbeitet wird.\nDies kann nur verwendet werden, wenn „Szene duplizieren“ aktiviert ist.\nBestimmte Quellen (wie Aufnahme‐ oder Medienquellen) unterstützen dies nicht und können nicht separat bearbeitet werden.\nDas Ändern dieses Wertes wird die derzeitige Ausgabeszene zurücksetzen (falls sie noch existiert).\n\nWarnung: Da Quellen dupliziert werden, könnte dies zusätzliche System‐ oder Videoressourcen verbrauchen." QuickTransitions.HotkeyName="Schnellübergang: %1" Basic.AddTransition="Konfigurierbaren Übergang hinzufügen" @@ -220,7 +225,7 @@ Basic.RemoveTransition="Konfigurierbaren Übergang entfernen" Basic.TransitionProperties="Übergangseigenschaften" Basic.SceneTransitions="Szenenübergänge" Basic.TransitionDuration="Dauer" -Basic.TogglePreviewProgramMode="Studio-Modus" +Basic.TogglePreviewProgramMode="Studio‐Modus" TransitionNameDlg.Text="Bitte geben Sie den Namen des Übergangs ein" TransitionNameDlg.Title="Übergangsname" @@ -240,6 +245,9 @@ ConfirmStart.Text="Sind Sie sicher, dass Sie den Stream starten möchten?" ConfirmStop.Title="Stream stoppen?" ConfirmStop.Text="Sind Sie sicher, dass Sie den Stream stoppen möchten?" +ConfirmStopRecord.Title="Aufnahme stoppen?" +ConfirmStopRecord.Text="Sind Sie sicher, dass Sie die Aufnahme stoppen möchten?" + ConfirmBWTest.Title="Bandbreitentest starten?" ConfirmBWTest.Text="Sie haben OBS im Bandbreitentestmodus konfiguriert. In diesem Modus können Sie Netzwerktests durchführen, ohne dass Ihr Kanal live geschaltet wird. Sobald Sie fertig mit dem Testen sind, müssen Sie ihn deaktivieren, damit die Zuschauer Ihren Stream sehen können.\n\nMöchten Sie fortfahren?" @@ -252,12 +260,14 @@ ConfirmRemove.TextMultiple="Sind Sie sicher, dass Sie %1 Elemente löschen möch Output.StartStreamFailed="Fehler beim Starten des Streams" Output.StartRecordingFailed="Fehler beim Starten der Aufnahme" -Output.StartReplayFailed="Fehler beim Starten des Replaypuffers" -Output.StartFailedGeneric="Start der Ausgabe fehlgeschlagen. Bitte überprüfen Sie die Protokolldatei für Details.\n\nHinweis: Wenn Sie die NVENC- oder AMD-Kodierer verwenden, stellen Sie sicher, dass Ihre Videotreiber aktuell sind." +Output.StartReplayFailed="Fehler beim Starten des Replay‐Puffers" +Output.StartFailedGeneric="Start der Ausgabe fehlgeschlagen. Bitte überprüfen Sie die Protokolldatei für Details.\n\nHinweis: Wenn Sie die NVENC‐ oder AMD‐Kodierer verwenden, stellen Sie sicher, dass Ihre Videotreiber aktuell sind." +Output.ReplayBuffer.PauseWarning.Title="Kann beim Pausieren keine Replays speichern" +Output.ReplayBuffer.PauseWarning.Text="Warnung: Replays können beim Pausieren der Aufnahme nicht gespeichert werden." Output.ConnectFail.Title="Verbindung fehlgeschlagen" -Output.ConnectFail.BadPath="Ungültiger Pfad oder Verbindungs-URL. Bitte überprüfen Sie Ihre Einstellungen und stellen Sie sicher, dass diese korrekt sind." +Output.ConnectFail.BadPath="Ungültiger Pfad oder Verbindungs‐URL. Bitte überprüfen Sie Ihre Einstellungen und stellen Sie sicher, dass diese korrekt sind." Output.ConnectFail.ConnectFailed="Verbindung zum Server fehlgeschlagen" Output.ConnectFail.InvalidStream="Konnte nicht auf den angegebenen Kanal oder Streamschlüssel zugreifen. Bitte überprüfen Sie den eingegebenen Streamschlüssel. Wenn er richtig ist, kann es ein Problem beim Verbinden mit dem Server gegeben haben." Output.ConnectFail.Error="Ein unerwarteter Fehler ist beim Verbindungsversuch zum Server aufgetreten. Mehr Informationen finden Sie in der Protokolldatei." @@ -274,7 +284,7 @@ Output.RecordError.Title="Aufnahmefehler" Output.RecordError.Msg="Während der Aufnahme ist ein unbekannter Fehler aufgetreten." Output.RecordError.EncodeErrorMsg="Ein Kodierungsfehler ist beim Aufnehmen aufgetreten." Output.ReplayBuffer.NoHotkey.Title="Kein Hotkey festgelegt" -Output.ReplayBuffer.NoHotkey.Msg="Kein „Replay speichern“-Hotkey für Replaypuffer festgelegt. Legen Sie bitte den „Speichern“-Hotkey fest, der zum Speichern der Replayaufnahmen verwendet werden soll." +Output.ReplayBuffer.NoHotkey.Msg="Kein „Replay speichern“‐Hotkey für den Replay‐Puffer festgelegt. Legen Sie bitte den Speichern‐Hotkey fest, der zum Speichern der Replay‐Aufnahmen verwendet werden soll." Output.BadPath.Title="Ungültiger Dateipfad" Output.BadPath.Text="Der konfigurierte Ausgabepfad ist ungültig. Bitte überprüfen Sie Ihre Einstellungen und stellen Sie sicher, dass ein gültiger Pfad angegeben wurde." @@ -283,29 +293,29 @@ LogReturnDialog="Protokoll erfolgreich hochgeladen" LogReturnDialog.CopyURL="URL kopieren" LogReturnDialog.ErrorUploadingLog="Fehler beim Hochladen der Protokolldatei" -Remux.SourceFile="OBS-Aufnahme" +Remux.SourceFile="OBS‐Aufnahme" Remux.TargetFile="Zieldatei" Remux.Remux="Remuxen" Remux.Stop="Remuxen stoppen" Remux.ClearFinished="Fertiggestellte Objekte entfernen" Remux.ClearAll="Alle Objekte entfernen" -Remux.OBSRecording="OBS-Aufnahme" +Remux.OBSRecording="OBS‐Aufnahme" Remux.FinishedTitle="Remuxen beendet" Remux.Finished="Aufnahme remuxed" Remux.FinishedError="Aufnahme remuxed, aber die Datei könnte unvollständig sein" -Remux.SelectRecording="OBS-Aufnahme auswählen …" +Remux.SelectRecording="OBS‐Aufnahme auswählen …" Remux.SelectTarget="Zieldatei auswählen" Remux.FileExistsTitle="Zieldateien existieren bereits" Remux.FileExists="Die folgenden Zieldateien existieren bereits. Möchten Sie diese ersetzen?" Remux.ExitUnfinishedTitle="Remuxen in Bearbeitung" Remux.ExitUnfinished="Das Remuxen ist noch nicht beendet. Wenn Sie jetzt stoppen, kann die Zieldatei unbrauchbar werden.\nSind Sie sicher, dass Sie das Remuxen beenden möchten?" -Remux.HelpText="Legen Sie Dateien in diesem Fenster ab, um sie zu remuxen oder wählen Sie eine leere „OBS-Aufnahme“-Zelle aus, um nach einer Datei zu suchen." +Remux.HelpText="Legen Sie Dateien in diesem Fenster ab, um sie zu remuxen oder wählen Sie eine leere „OBS‐Aufnahme“‐Zelle aus, um nach einer Datei zu suchen." UpdateAvailable="Neues Update verfügbar" UpdateAvailable.Text="Version %1.%2.%3 ist nun verfügbar. Hier klicken zum Herunterladen" -Basic.DesktopDevice1="Desktop-Audio" -Basic.DesktopDevice2="Desktop-Audio 2" +Basic.DesktopDevice1="Desktop‐Audio" +Basic.DesktopDevice2="Desktop‐Audio 2" Basic.AuxDevice1="Mic/Aux" Basic.AuxDevice2="Mic/Aux 2" Basic.AuxDevice3="Mic/Aux 3" @@ -383,35 +393,35 @@ Basic.PropertiesWindow.AddEditableListFiles="Dateien zu „%1“ hinzufügen" Basic.PropertiesWindow.AddEditableListEntry="Eintrag zu „%1“ hinzufügen" Basic.PropertiesWindow.EditEditableListEntry="Eintrag aus „%1“ bearbeiten" -Basic.PropertiesView.FPS.Simple="Einfache FPS-Werte" -Basic.PropertiesView.FPS.Rational="Rationale FPS-Werte" -Basic.PropertiesView.FPS.ValidFPSRanges="Gültige FPS-Bereiche:" +Basic.PropertiesView.FPS.Simple="Einfache FPS‐Werte" +Basic.PropertiesView.FPS.Rational="Rationale FPS‐Werte" +Basic.PropertiesView.FPS.ValidFPSRanges="Gültige FPS‐Bereiche:" Basic.InteractionWindow="Mit „%1“ interagieren" Basic.StatusBar.Reconnecting="Verbindung getrennt; Verbindungsversuch %1 in %2 Sekunde(n)" Basic.StatusBar.AttemptingReconnect="Versuche die Verbindung wiederherzustellen … (Versuch %1)" Basic.StatusBar.ReconnectSuccessful="Wiederverbinden erfolgreich" -Basic.StatusBar.Delay="Verzögerung (%1 s)" -Basic.StatusBar.DelayStartingIn="Verzögerung (starte in %1 s)" -Basic.StatusBar.DelayStoppingIn="Verzögerung (stoppe in %1 s)" -Basic.StatusBar.DelayStartingStoppingIn="Verzögerung (stoppe in %1 s, beginne in %2 s)" +Basic.StatusBar.Delay="Verzögerung (%1 s)" +Basic.StatusBar.DelayStartingIn="Verzögerung (starte in %1 s)" +Basic.StatusBar.DelayStoppingIn="Verzögerung (stoppe in %1 s)" +Basic.StatusBar.DelayStartingStoppingIn="Verzögerung (stoppe in %1 s, starte in %2 s)" Basic.Filters="Filter" -Basic.Filters.AsyncFilters="Audio-/Videofilter" +Basic.Filters.AsyncFilters="Audio‐/Videofilter" Basic.Filters.AudioFilters="Audiofilter" Basic.Filters.EffectFilters="Effektfilter" Basic.Filters.Title="Filter für „%1“" Basic.Filters.AddFilter.Title="Filtername" Basic.Filters.AddFilter.Text="Bitte geben Sie einen Namen für den Filter ein" -Basic.TransformWindow="Szenen-Elementtransformation" +Basic.TransformWindow="Szenen‐Elementtransformation" Basic.TransformWindow.Position="Position" Basic.TransformWindow.Rotation="Drehung" Basic.TransformWindow.Size="Größe" Basic.TransformWindow.Alignment="Ausrichtung" -Basic.TransformWindow.BoundsType="Bounding Box Typ" -Basic.TransformWindow.BoundsAlignment="Ausrichtung in Bounding Box" +Basic.TransformWindow.BoundsType="Begrenzungsrahmentyp" +Basic.TransformWindow.BoundsAlignment="Ausrichtung in Begrenzungsrahmen" Basic.TransformWindow.Bounds="BoundingBox Größe" Basic.TransformWindow.Crop="Zuschneiden" @@ -425,31 +435,33 @@ Basic.TransformWindow.Alignment.BottomLeft="Unten links" Basic.TransformWindow.Alignment.BottomCenter="Unten in der Mitte" Basic.TransformWindow.Alignment.BottomRight="Unten rechts" -Basic.TransformWindow.BoundsType.None="Keine Grenzen" +Basic.TransformWindow.BoundsType.None="Keine Begrenzungen" Basic.TransformWindow.BoundsType.MaxOnly="Nur maximale Größe" Basic.TransformWindow.BoundsType.ScaleInner="Auf innere Begrenzungen skalieren" Basic.TransformWindow.BoundsType.ScaleOuter="Auf äußere Begrenzungen skalieren" -Basic.TransformWindow.BoundsType.ScaleToWidth="Auf die Breite der Begrenzungen skalieren" -Basic.TransformWindow.BoundsType.ScaleToHeight="Auf die Höhe der Begrenzungen skalieren" -Basic.TransformWindow.BoundsType.Stretch="Bis zu den Begrenzungen strecken" +Basic.TransformWindow.BoundsType.ScaleToWidth="Auf Breite der Begrenzungen skalieren" +Basic.TransformWindow.BoundsType.ScaleToHeight="Auf Höhe der Begrenzungen skalieren" +Basic.TransformWindow.BoundsType.Stretch="Bis zu Begrenzungen strecken" Basic.Main.AddSourceHelp.Title="Quelle konnte nicht hinzugefügt werden" -Basic.Main.AddSourceHelp.Text="Sie müssen mindestens 1 Szene besitzen, um eine Quelle hinzuzufügen." +Basic.Main.AddSourceHelp.Text="Sie müssen mindestens eine Szene besitzen, um eine Quelle hinzuzufügen." Basic.Main.Scenes="Szenen" Basic.Main.Sources="Quellen" Basic.Main.Controls="Steuerung" -Basic.Main.Connecting="Verbinden …" +Basic.Main.Connecting="Verbinde …" Basic.Main.StartRecording="Aufnahme starten" -Basic.Main.StartReplayBuffer="Replaypuffer starten" +Basic.Main.StartReplayBuffer="Replay‐Puffer starten" Basic.Main.StartStreaming="Streaming starten" Basic.Main.StopRecording="Aufnahme stoppen" +Basic.Main.PauseRecording="Aufnahme pausieren" +Basic.Main.UnpauseRecording="Aufnahme fortsetzen" Basic.Main.StoppingRecording="Stoppe Aufnahme ..." -Basic.Main.StopReplayBuffer="Replaypuffer stoppen" -Basic.Main.StoppingReplayBuffer="Stoppe Replaypuffer …" -Basic.Main.StopStreaming="Streaming stoppen" -Basic.Main.StoppingStreaming="Stoppe Stream …" -Basic.Main.ForceStopStreaming="Streaming stoppen (Verzögerung missachten)" +Basic.Main.StopReplayBuffer="Replay‐Puffer stoppen" +Basic.Main.StoppingReplayBuffer="Stoppe Replay‐Puffer …" +Basic.Main.StopStreaming="Stream stoppen" +Basic.Main.StoppingStreaming="Stoppe Stream …" +Basic.Main.ForceStopStreaming="Stream stoppen (Verzögerung missachten)" Basic.Main.Group="Gruppe %1" Basic.Main.GroupItems="Ausgewählte Elemente gruppieren" Basic.Main.Ungroup="Gruppierung aufheben" @@ -460,7 +472,7 @@ Basic.MainMenu.File.Import="&Importieren" Basic.MainMenu.File.ShowRecordings="Aufnahmen anzeigen (&R)" Basic.MainMenu.File.Remux="Aufnahmen re&muxen" Basic.MainMenu.File.Settings="Ein&stellungen" -Basic.MainMenu.File.ShowSettingsFolder="Einstellungenordner anzeigen" +Basic.MainMenu.File.ShowSettingsFolder="Einstellungsordner anzeigen" Basic.MainMenu.File.ShowProfileFolder="Profilordner anzeigen" Basic.MainMenu.AlwaysOnTop="Immer im Vordergrund (&A)" Basic.MainMenu.File.Exit="Beenden (&X)" @@ -473,10 +485,10 @@ Basic.MainMenu.Edit.RedoAction="$1 Wiede&rherstellen" Basic.MainMenu.Edit.LockPreview="Vorschau sperren (&L)" Basic.MainMenu.Edit.Scale="Vorschau&skalierung" Basic.MainMenu.Edit.Scale.Window="An Fenstergröße anpassen" -Basic.MainMenu.Edit.Scale.Canvas="Leinwand (%1×%2)" -Basic.MainMenu.Edit.Scale.Output="Ausgabe (%1×%2)" +Basic.MainMenu.Edit.Scale.Canvas="Leinwand (%1 × %2)" +Basic.MainMenu.Edit.Scale.Output="Ausgabe (%1 × %2)" Basic.MainMenu.Edit.Transform="&Transformieren" -Basic.MainMenu.Edit.Transform.EditTransform="Transformation b&earbeiten …" +Basic.MainMenu.Edit.Transform.EditTransform="Transformation b&earbeiten …" Basic.MainMenu.Edit.Transform.CopyTransform="Transformation kopieren" Basic.MainMenu.Edit.Transform.PasteTransform="Transformation einfügen" Basic.MainMenu.Edit.Transform.ResetTransform="Transformation zu&rücksetzen" @@ -502,10 +514,11 @@ Basic.MainMenu.View.Toolbars="Werkzeugleisten (&T)" Basic.MainMenu.View.Docks="Docks" Basic.MainMenu.View.Docks.ResetUI="GUI zurücksetzen" Basic.MainMenu.View.Docks.LockUI="GUI sperren" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Benutzerdefinierte Browser‐Docks …" Basic.MainMenu.View.Toolbars.Listboxes="&Listenfelder" -Basic.MainMenu.View.SceneTransitions="Szenenübergänge (&c)" +Basic.MainMenu.View.SceneTransitions="Szenenübergänge (&C)" Basic.MainMenu.View.StatusBar="&Statusleiste" -Basic.MainMenu.View.Fullscreen.Interface="Vollbildbenutzeroberfläche" +Basic.MainMenu.View.Fullscreen.Interface="Vollbild" Basic.MainMenu.SceneCollection="&Szenensammlung" Basic.MainMenu.Profile="&Profil" @@ -521,17 +534,17 @@ Basic.MainMenu.Tools="Werkzeuge (&T)" Basic.MainMenu.Help="&Hilfe" Basic.MainMenu.Help.HelpPortal="Hilfe&portal" Basic.MainMenu.Help.Website="&Webseite besuchen" -Basic.MainMenu.Help.Discord="Unserem &Discord-Server beitreten" +Basic.MainMenu.Help.Discord="&Discord‐Server beitreten" Basic.MainMenu.Help.Logs="Protoko&lldateien" Basic.MainMenu.Help.Logs.ShowLogs="Protokolldateien anzeigen (&S)" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Aktuelle Protokolldatei hochladen (&C)" -Basic.MainMenu.Help.Logs.UploadLastLog="Neuste Protoko&lldatei hochladen" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Derzeitige Protokolldatei hochladen (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Letzte Protoko&lldatei hochladen" Basic.MainMenu.Help.Logs.ViewCurrentLog="Aktuelles Protokoll anzeigen (&V)" Basic.MainMenu.Help.CheckForUpdates="Nach Updates suchen" Basic.MainMenu.Help.CrashLogs="Abstu&rzberichte" Basic.MainMenu.Help.CrashLogs.ShowLogs="Ab&sturzberichte anzeigen" Basic.MainMenu.Help.CrashLogs.UploadLastLog="Neusten Absturzbericht hoch&laden" -Basic.MainMenu.Help.About="Über OBS Studio (&A)" +Basic.MainMenu.Help.About="Über (&A)" Basic.Settings.ProgramRestart="Das Programm muss neugestartet werden, damit die Änderungen wirksam werden." Basic.Settings.ConfirmTitle="Änderungen bestätigen" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="Beim Start nach Updates suchen" Basic.Settings.General.OpenStatsOnStartup="Statistikenfenster beim Start öffnen" Basic.Settings.General.WarnBeforeStartingStream="Bestätigungsdialog beim Streamstart anzeigen" Basic.Settings.General.WarnBeforeStoppingStream="Bestätigungsdialog beim Streamstop anzeigen" +Basic.Settings.General.WarnBeforeStoppingRecord="Bestätigungsdialog beim Aufnahmestopp anzeigen" Basic.Settings.General.Projectors="Projektoren" Basic.Settings.General.HideProjectorCursor="Mauszeiger über Projektoren verstecken" Basic.Settings.General.ProjectorAlwaysOnTop="Projektoren immer im Vordergrund anzeigen" @@ -554,8 +568,8 @@ Basic.Settings.General.SourceSnapping="Quellen an anderen Quellen ausrichten" Basic.Settings.General.SnapDistance="Ausrichtungsempfindlichkeit" Basic.Settings.General.RecordWhenStreaming="Stream automatisch aufnehmen" Basic.Settings.General.KeepRecordingWhenStreamStops="Weiter aufnehmen, wenn der Stream stoppt" -Basic.Settings.General.ReplayBufferWhileStreaming="Replaypuffer automatisch beim Streamen starten" -Basic.Settings.General.KeepReplayBufferStreamStops="Replaypuffer weiter aktiv lassen, wenn der Stream stoppt" +Basic.Settings.General.ReplayBufferWhileStreaming="Replay‐Puffer automatisch beim Streamen starten" +Basic.Settings.General.KeepReplayBufferStreamStops="Replay‐Puffer weiter aktiv lassen, wenn der Stream stoppt" Basic.Settings.General.SysTray="Infobereich" Basic.Settings.General.SysTrayWhenStarted="Beim Start zum Infobereich minimieren" Basic.Settings.General.SystemTrayHideMinimize="Immer zum Infobereich anstatt zur Taskleiste minimieren" @@ -564,9 +578,9 @@ Basic.Settings.General.Preview="Vorschau" Basic.Settings.General.OverflowHidden="Überlauf verstecken" Basic.Settings.General.OverflowAlwaysVisible="Überlauf immer anzeigen" Basic.Settings.General.OverflowSelectionHidden="Überlauf trotz unsichtbarer Quelle anzeigen" -Basic.Settings.General.SwitchOnDoubleClick="Übergang zur Szene beim Doppelklicken" -Basic.Settings.General.StudioPortraitLayout="Porträt/Vertikales Layout aktivieren" -Basic.Settings.General.TogglePreviewProgramLabels="Vorschau-/Programmbeschriftung anzeigen" +Basic.Settings.General.SwitchOnDoubleClick="Übergang zur Szene beim Doppelklick" +Basic.Settings.General.StudioPortraitLayout="Porträt‐/Vertikales Layout aktivieren" +Basic.Settings.General.TogglePreviewProgramLabels="Vorschau‐/Programmbeschriftung anzeigen" Basic.Settings.General.Multiview="Multiview" Basic.Settings.General.Multiview.MouseSwitch="Klicken, um zwischen den Szenen umzuschalten" Basic.Settings.General.Multiview.DrawSourceNames="Szenennamen anzeigen" @@ -591,50 +605,54 @@ Basic.Settings.Output.Encoder="Kodierer" Basic.Settings.Output.SelectDirectory="Aufnahmeordner auswählen" Basic.Settings.Output.SelectFile="Aufnahmedatei auswählen" Basic.Settings.Output.EnforceBitrate="Bitratenlimit des Streamingdienstes erzwingen" +Basic.Settings.Output.DynamicBitrate="Bitrate dynamisch verändern, um Überlastung zu kontrollieren" +Basic.Settings.Output.DynamicBitrate.Beta="Bitrate dynamisch verändern, um Überlastung zu kontrollieren (Beta)" +Basic.Settings.Output.DynamicBitrate.TT="Anstatt Frames wegfallen zu lassen, um Überlastung zu verringern, wird die Bitrate dynamisch verändert.\n\nBeachten Sie, dass dies die Verzögerung zu den Zuschauern bei erheblich unerwartet hoher Überlastung erhöhen kann.\nWenn die Bitrate fällt, kann der Wiederherstellungsvorgang ein paar Minuten dauern.\n\nDerzeit nur für RTMP unterstützt." Basic.Settings.Output.Mode="Ausgabemodus" Basic.Settings.Output.Mode.Simple="Einfach" Basic.Settings.Output.Mode.Adv="Erweitert" -Basic.Settings.Output.Mode.FFmpeg="FFmpeg-Ausgabe" -Basic.Settings.Output.UseReplayBuffer="Replaypuffer aktivieren" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximale Replayzeit (Sekunden)" -Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximale Speichernutzung (RAM) in Megabyte" -Basic.Settings.Output.ReplayBuffer.Estimate="Geschätzte Speichernutzung (RAM): %1 MB" -Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Speichernutzung kann nicht geschätzt werden. Stellen Sie bitte die maximale Speichergrenze ein." -Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Hinweis: Achten Sie darauf, einen Hotkey für den Replaypuffer im Abschnitt „Hotkeys“ festzulegen)" -Basic.Settings.Output.ReplayBuffer.Prefix="Replaypuffer-Dateiname-Präfix" +Basic.Settings.Output.Mode.FFmpeg="FFmpeg‐Ausgabe" +Basic.Settings.Output.UseReplayBuffer="Replay‐Puffer aktivieren" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximale Replay‐Zeit" +Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximale RAM‐Nutzung in MB" +Basic.Settings.Output.ReplayBuffer.Estimate="Geschätzte RAM‐Nutzung: %1 MB" +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="RAM‐Nutzung kann nicht geschätzt werden. Stellen Sie diese bitte ein." +Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Hinweis: Achten Sie darauf, einen Hotkey für den Replay‐Puffer im Abschnitt Hotkeys festzulegen)" +Basic.Settings.Output.ReplayBuffer.Prefix="Replay‐Puffer‐Dateinamen‐Präfix" Basic.Settings.Output.ReplayBuffer.Suffix="Suffix" Basic.Settings.Output.Simple.SavePath="Aufnahmepfad" Basic.Settings.Output.Simple.RecordingQuality="Aufnahmequalität" -Basic.Settings.Output.Simple.RecordingQuality.Stream="Gleiche wie Stream" +Basic.Settings.Output.Simple.RecordingQuality.Stream="Gleich wie Stream" Basic.Settings.Output.Simple.RecordingQuality.Small="Hohe Qualität, mittelgroße Dateien" Basic.Settings.Output.Simple.RecordingQuality.HQ="Ununterscheidbare Qualität, große Dateien" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Verlustfreie Qualität, enorm große Dateien" Basic.Settings.Output.Simple.Warn.VideoBitrate="Warnung: Die Videobitrate beim Streamen wird auf %1 festgelegt, was der Obergrenze des aktuellen Streamingdienstes entspricht. Falls Sie sicher sind, dass Sie %1 überschreiten wollen, deaktivieren Sie „Bitratenlimit des Streamingdienstes erzwingen“ in den erweiterten Kodierereinstellungen." Basic.Settings.Output.Simple.Warn.AudioBitrate="Warnung: Die Audiobitrate beim Streamen wird auf %1 festgelegt, was der Obergrenze des aktuellen Streamingdienstes entspricht. Falls Sie sicher sind, dass Sie %1 überschreiten wollen, deaktivieren Sie „Bitratenlimit des Streamingdienstes erzwingen“ in den erweiterten Kodierereinstellungen." -Basic.Settings.Output.Simple.Warn.Encoder="Warnung: Mit einem Software-Kodierer in einer anderen Qualität als der des Streams aufzunehmen erfordert zusätzliche CPU-Auslastung, wenn Sie gleichzeitig streamen und aufnehmen." -Basic.Settings.Output.Simple.Warn.Lossless="Warnung: Verlustfreie Qualität erzeugt enorm große Dateien! Verlustfreie Qualität kann mehr als 7 Gigabyte Speicherplatz pro Minute bei hohen Auflösungen und Frameraten in Anspruch nehmen. Verlustfrei ist für lange Aufnahmen nicht empfohlen, es sei denn, Sie haben eine sehr große Menge an Speicherplatz zur Verfügung." +Basic.Settings.Output.Simple.Warn.CannotPause="Warnung: Aufnahmen können nicht pausiert werden, wenn die Aufnahmequalität „Gleich wie Stream” ist." +Basic.Settings.Output.Simple.Warn.Encoder="Warnung: Mit einem Software‐Kodierer in einer anderen Qualität als der des Streams aufzunehmen erfordert zusätzliche CPU‐Auslastung, wenn Sie gleichzeitig streamen und aufnehmen." +Basic.Settings.Output.Simple.Warn.Lossless="Warnung: Verlustfreie Qualität erzeugt enorm große Dateien! Bei dieser Einstellung kann mehr als 7 Gigabyte Speicherplatz pro Minute bei hohen Auflösungen und Frameraten in Anspruch genommen werden. Sie ist für lange Aufnahmen daher nicht empfohlen, es sei denn, Sie haben eine sehr große Menge an Speicherplatz zur Verfügung." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Sind Sie sicher, dass Sie verlustfreie Qualität verwenden möchten?" -Basic.Settings.Output.Simple.Warn.Lossless.Title="Verlustfreie Qualitäts-Warnung" +Basic.Settings.Output.Simple.Warn.Lossless.Title="Warnung zur verlustfreien Qualität" Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)" Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)" -Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 niedrige CPU-Auslastungsvoreinstellung, erhöht die Dateigröße)" +Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 niedrige CPU‐Auslastungsvoreinstellung, erhöht die Dateigröße)" Basic.Settings.Output.VideoBitrate="Videobitrate" Basic.Settings.Output.AudioBitrate="Audiobitrate" Basic.Settings.Output.Reconnect="Automatisch wiederverbinden" -Basic.Settings.Output.RetryDelay="Wiederverbindungsverzögerung (Sekunden)" +Basic.Settings.Output.RetryDelay="Wiederholungsverzögerung" Basic.Settings.Output.MaxRetries="Maximale Wiederholungsversuche" Basic.Settings.Output.Advanced="Erweiterte Kodierereinstellungen aktivieren" Basic.Settings.Output.EncoderPreset="Kodierervoreinstellung" -Basic.Settings.Output.CustomEncoderSettings="Benutzerdefinierte Kodierer-Einstellungen" +Basic.Settings.Output.CustomEncoderSettings="Benutzerdefinierte Kodierereinstellungen" Basic.Settings.Output.CustomMuxerSettings="Benutzerdefinierte Muxereinstellungen" Basic.Settings.Output.NoSpaceFileName="Dateinamen ohne Leerzeichen generieren" Basic.Settings.Output.Adv.Rescale="Ausgabe umskalieren" Basic.Settings.Output.Adv.AudioTrack="Audiospur" Basic.Settings.Output.Adv.Streaming="Streaming" -Basic.Settings.Output.Adv.ApplyServiceSettings="Streamingdienst-Kodierereinstellungen erzwingen" +Basic.Settings.Output.Adv.ApplyServiceSettings="Streamingdienst‐Kodierereinstellungen erzwingen" Basic.Settings.Output.Adv.Audio.Track1="Spur 1" Basic.Settings.Output.Adv.Audio.Track2="Spur 2" Basic.Settings.Output.Adv.Audio.Track3="Spur 3" @@ -647,54 +665,55 @@ Basic.Settings.Output.Adv.Recording.Type="Art" Basic.Settings.Output.Adv.Recording.Type.Standard="Normal" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Benutzerdefinierte Ausgabe (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Streamkodierer verwenden)" -Basic.Settings.Output.Adv.Recording.Filename="Dateinameformatierung" -Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Überschreiben, wenn die Datei vorhanden ist" -Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg-Ausgabetyp" +Basic.Settings.Output.Adv.Recording.Filename="Dateinamenformatierung" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Überschreiben, wenn Datei vorhanden" +Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg‐Ausgabetyp" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Ausgabe zu URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Ausgabe in Datei" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Häufige Aufnahmeformate" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Alle Dateien" Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Dateipfad oder URL" -Basic.Settings.Output.Adv.FFmpeg.Format="Container-Format" +Basic.Settings.Output.Adv.FFmpeg.Format="Container‐Format" Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Audio" Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Video" Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Standardformat" -Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Container-Formatbeschreibung" -Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Audio-/Videocodec wird aus Dateipfad oder URL gebildet" +Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Container‐Formatbeschreibung" +Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Audio‐/Videocodec wird aus Dateipfad oder URL gebildet" Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Standardkodierer" Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Kodierer deaktivieren" Basic.Settings.Output.Adv.FFmpeg.VEncoder="Videokodierer" Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Videokodierereinstellungen (falls angegeben)" Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audiokodierer" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audiokodierereinstellungen (falls angegeben)" -Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer-Einstellungen (falls angegeben)" +Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer‐Einstellungen (falls angegeben)" Basic.Settings.Output.Adv.FFmpeg.GOPSize="Keyframeintervall (Frames)" Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Zeige alle Codecs (auch wenn möglicherweise inkompatibel)" -FilenameFormatting.completer="%DD. %MM. %CCYY %hh-%mm-%ss\n%DD. %MM. %YY %hh-%mm-%ss\n%d. %m. %Y %H-%M-%S\n%d. %m. %y %H-%M-%S" +FilenameFormatting.completer="%DD. %MM. %CCYY %hh‐%mm‐%ss\n%DD. %MM. %YY %hh‐%mm‐%ss\n%d. %m. %Y %H‐%M‐%S\n%d. %m. %y %H‐%M‐%S" -FilenameFormatting.TT="%CCYY Jahr, vier Ziffern\n%YY Jahr, letzte zwei Ziffern (00–99)\n%MM Monat als Dezimalzahl (01–12)\n%DD Tag des Monats, mit Nullen aufgefüllt (01–31)\n%hh Stunden im 24-Stunden-Format (00–23)\n%mm Minute (00–59)\n%ss Sekunde (00–61)\n%% Ein %-Zeichen\n%a Abgekürzter Wochentagsname\n%A Voller Wochentagsname\n%b Abgekürzer Monatsname\n%B Voller Monatsname\n%d Tag des Monats, mit Nullen aufgefüllt (01–31)\n%H Stunden im 24-Stunden-Format (00–23)\n%I Stunden im 12-Stunden-Format (01–12)\n%m Monat als Dezimalzahl (01–12)\n%M Minute (00–59)\n%p Vormittags- oder nachmittags-Angabe\n%S Sekunde (00–61)\n%y Jahr, letzte zwei Ziffern (00–99)\n%Y Jahr\n%z ISO-8601-Verschiebung von UTC oder Zeitzone\n%Z Zeitzonenname oder Abkürzung" +FilenameFormatting.TT="%CCYY Jahr, vier Ziffern\n%YY Jahr, letzte zwei Ziffern (00–99)\n%MM Monat als Dezimalzahl (01–12)\n%DD Tag des Monats mit Nullen aufgefüllt (01–31)\n%hh Stunden im 24‐Stunden‐Format (00–23)\n%mm Minute (00–59)\n%ss Sekunde (00–61)\n%% Ein %‐Zeichen\n%a Abgekürzter Wochentagsname (Englisch)\n%A Voller Wochentagsname (Englisch)\n%b Abgekürzer Monatsname (Englisch)\n%B Voller Monatsname (Englisch)\n%d Tag des Monats, mit Nullen aufgefüllt (01–31)\n%H Stunden im 24‐Stunden‐Format (00–23)\n%I Stunden im 12‐Stunden‐Format (01–12)\n%m Monat als Dezimalzahl (01–12)\n%M Minute (00–59)\n%p Vormittags‐ oder nachmittags‐Angabe\n%S Sekunde (00–61)\n%y Jahr, letzte zwei Ziffern (00–99)\n%Y Jahr\n%z ISO‐8601‐Verschiebung von UTC oder Zeitzone\n%Z Zeitzonenname oder Abkürzung" Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Grafikkarte" -Basic.Settings.Video.BaseResolution="Basis-(Leinwand-)Auflösung" +Basic.Settings.Video.BaseResolution="Basis‐(Leinwand‐)Auflösung" Basic.Settings.Video.ScaledResolution="(Skalierte) Ausgabeauflösung" Basic.Settings.Video.DownscaleFilter="Skalierungsfilter" Basic.Settings.Video.DisableAeroWindows="Aero deaktivieren (nur Windows)" Basic.Settings.Video.FPS="FPS" -Basic.Settings.Video.FPSCommon="Übliche FPS-Werte" -Basic.Settings.Video.FPSInteger="Ganzzahl-FPS-Wert" -Basic.Settings.Video.FPSFraction="Bruch-FPS-Wert" +Basic.Settings.Video.FPSCommon="Übliche FPS‐Werte" +Basic.Settings.Video.FPSInteger="Ganzzahl‐FPS‐Wert" +Basic.Settings.Video.FPSFraction="Bruch‐FPS‐Wert" Basic.Settings.Video.Numerator="Zähler" Basic.Settings.Video.Denominator="Nenner" Basic.Settings.Video.Renderer="Renderer" -Basic.Settings.Video.InvalidResolution="Ungültige Auflösung. Korrekte Formatierung: [Breite]x[Höhe] (z. B. 1920x1080)" +Basic.Settings.Video.InvalidResolution="Ungültige Auflösung. Korrekte Formatierung: [Breite] × [Höhe] (z. B. 1920 × 1080)" Basic.Settings.Video.CurrentlyActive="Videoausgabe ist derzeit aktiv. Bitte schalten Sie alle Ausgaben ab, um die Videoeinstellungen zu ändern." Basic.Settings.Video.DisableAero="Aero deaktivieren" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (am schnellsten, aber Unscharf bei Skalierung)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (geschärfte Skalierung, 16 Stichproben)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (geschärfte Skalierung, 32 Stichproben)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (geschärfte Skalierung, 36 Stichproben)" +Basic.Settings.Video.DownscaleFilter.Area="Bereich (gewichtete Summe, 4/6/9 Stichproben)" Basic.Settings.Audio="Audio" Basic.Settings.Audio.SampleRate="Abtastrate" @@ -706,22 +725,22 @@ Basic.Settings.Audio.MeterDecayRate.Medium="Mittel (Type I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Langsam (Type II PPM)" Basic.Settings.Audio.PeakMeterType="Spitzenmessertyp" Basic.Settings.Audio.PeakMeterType.SamplePeak="Sample Peak" -Basic.Settings.Audio.PeakMeterType.TruePeak="True Peak (höhere CPU-Auslastung)" -Basic.Settings.Audio.MultiChannelWarning.Enabled="WARNUNG: Surround-Sound-Audio ist aktiviert." -Basic.Settings.Audio.MultichannelWarning="Überprüfen Sie beim Streaming, ob Ihr Streamingdienst sowohl die Einspeisung von Surround-Sound als auch die Surround-Sound-Wiedergabe unterstützt. Twitch, Facebook 360 Live, Mixer RTMP und Smashcast sind Beispiele, bei denen Surround-Sound voll unterstützt wird. Obwohl Facebook Live und YouTube Live beide die Surround-Einspeisung akzeptieren, wird Facebook Live auf Stereo heruntergemischt und YouTube Live spielt nur zwei Kanäle ab.\n\nOBS-Audiofilter sind mit Surround-Sound kompatibel, obwohl die VST-Pluginunterstützung nicht garantiert ist." -Basic.Settings.Audio.MultichannelWarning.Title="Surround-Sound-Audio aktivieren?" -Basic.Settings.Audio.MultichannelWarning.Confirm="Sind Sie sicher, dass Sie Surround-Sound-Audio wirklich aktivieren möchten?" +Basic.Settings.Audio.PeakMeterType.TruePeak="True Peak (höhere CPU‐Auslastung)" +Basic.Settings.Audio.MultiChannelWarning.Enabled="WARNUNG: Surround‐Sound‐Audio ist aktiviert." +Basic.Settings.Audio.MultichannelWarning="Überprüfen Sie beim Streaming, ob Ihr Streamingdienst sowohl die Einspeisung von Surround‐Sound als auch die Surround‐Sound‐Wiedergabe unterstützt. Facebook 360 Live, Mixer RTMP und Smashcast sind Beispiele, bei denen Surround‐Sound voll unterstützt wird. Obwohl Facebook Live und YouTube Live beide die Surround‐Einspeisung akzeptieren, wird Facebook Live auf Stereo heruntergemischt und YouTube Live spielt nur zwei Kanäle ab.\n\nOBS‐Audiofilter sind mit Surround‐Sound kompatibel, obwohl die VST‐Pluginunterstützung nicht garantiert ist." +Basic.Settings.Audio.MultichannelWarning.Title="Surround‐Sound‐Audio aktivieren?" +Basic.Settings.Audio.MultichannelWarning.Confirm="Sind Sie sicher, dass Sie Surround‐Sound‐Audio wirklich aktivieren möchten?" Basic.Settings.Audio.Devices="Geräte" -Basic.Settings.Audio.DesktopDevice="Desktop-Audio" -Basic.Settings.Audio.DesktopDevice2="Desktop-Audio 2" +Basic.Settings.Audio.DesktopDevice="Desktop‐Audio" +Basic.Settings.Audio.DesktopDevice2="Desktop‐Audio 2" Basic.Settings.Audio.AuxDevice="Mikrofon/Audiogerät" Basic.Settings.Audio.AuxDevice2="Mikrofon/Audiogerät 2" Basic.Settings.Audio.AuxDevice3="Mikrofon/Audiogerät 3" Basic.Settings.Audio.AuxDevice4="Mikrofon/Audiogerät 4" -Basic.Settings.Audio.EnablePushToMute="Push-To-Mute aktivieren" -Basic.Settings.Audio.PushToMuteDelay="Push-To-Mute-Verzögerung" -Basic.Settings.Audio.EnablePushToTalk="Push-To-Talk aktivieren" -Basic.Settings.Audio.PushToTalkDelay="Push-To-Talk-Verzögerung" +Basic.Settings.Audio.EnablePushToMute="Push‐To‐Mute aktivieren" +Basic.Settings.Audio.PushToMuteDelay="Push‐To‐Mute‐Verzögerung" +Basic.Settings.Audio.EnablePushToTalk="Push‐To‐Talk aktivieren" +Basic.Settings.Audio.PushToTalkDelay="Push‐To‐Talk‐Verzögerung" Basic.Settings.Audio.UnknownAudioDevice="[Gerät nicht angeschlossen oder nicht verfügbar]" Basic.Settings.Audio.Disabled="Deaktiviert" @@ -732,35 +751,38 @@ Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Höher als normal" Basic.Settings.Advanced.General.ProcessPriority.Normal="Normal" Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Niedriger als normal" Basic.Settings.Advanced.General.ProcessPriority.Idle="Niedrig" -Basic.Settings.Advanced.FormatWarning="Warnung: Andere Farbformate als NV12 sind in erster Linie für die Aufnahme bestimmt und sind für Streaming nicht zu empfehlen. Die erforderliche Farbformatkonvertierung kann eine erhöhte CPU-Auslastung hervorrufen." +Basic.Settings.Advanced.FormatWarning="Warnung: Andere Farbformate als NV12 sind in erster Linie für die Aufnahme bestimmt und sind für Streaming nicht zu empfehlen. Die erforderliche Farbformatkonvertierung kann eine erhöhte CPU‐Auslastung hervorrufen." Basic.Settings.Advanced.Audio.BufferingTime="Audiopufferungszeit" Basic.Settings.Advanced.Video.ColorFormat="Farbformat" Basic.Settings.Advanced.Video.ColorSpace="Farbraum" Basic.Settings.Advanced.Video.ColorRange="Farbbereich" Basic.Settings.Advanced.Video.ColorRange.Partial="Begrenzt" Basic.Settings.Advanced.Video.ColorRange.Full="Voll" -Basic.Settings.Advanced.Audio.MonitoringDevice="Monitoring-Gerät" +Basic.Settings.Advanced.Audio.MonitoringDevice="Monitoring‐Gerät" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Standard" -Basic.Settings.Advanced.Audio.DisableAudioDucking="Windows-Audioducking deaktivieren" +Basic.Settings.Advanced.Audio.DisableAudioDucking="Windows‐Audioducking deaktivieren" Basic.Settings.Advanced.StreamDelay="Streamverzögerung" -Basic.Settings.Advanced.StreamDelay.Duration="Dauer (Sekunden)" +Basic.Settings.Advanced.StreamDelay.Duration="Dauer" Basic.Settings.Advanced.StreamDelay.Preserve="Lückenloses Wiederverbinden (erhöht Verzögerung, um Videoverlust zu vermeiden)" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Geschätzte Speichernutzung: %1 MB" Basic.Settings.Advanced.Network="Netzwerk" Basic.Settings.Advanced.Network.BindToIP="Interface" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Neuen Netzwerkcode aktivieren" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Niedriger Latenzmodus" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Hotkeyfokusverhalten" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Hotkeys nie deaktivieren" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Hotkeys deaktivieren, wenn das Hauptfenster im Fokus ist" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Hotkeys deaktivieren, wenn Hauptfenster nicht im Fokus" Basic.Settings.Advanced.AutoRemux="Automatisch zu mp4 remuxen" Basic.Settings.Advanced.AutoRemux.MP4="(als mkv aufnehmen)" Basic.AdvAudio="Erweiterte Audioeigenschaften" Basic.AdvAudio.Name="Name" Basic.AdvAudio.Volume="Lautstärke" -Basic.AdvAudio.Mono="Heruntermischen zu Mono" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Balance" -Basic.AdvAudio.SyncOffset="Sync-Verschiebung (ms)" -Basic.AdvAudio.Monitoring="Audio-Monitoring" +Basic.AdvAudio.SyncOffset="Synchronisationsausgleich" +Basic.AdvAudio.Monitoring="Audio‐Monitoring" Basic.AdvAudio.Monitoring.None="Monitor aus" Basic.AdvAudio.Monitoring.MonitorOnly="Nur Monitor (Ausgabe stummschalten)" Basic.AdvAudio.Monitoring.Both="Monitor und Ausgabe" @@ -775,16 +797,16 @@ Basic.Hotkeys.SelectScene="Zu Szene wechseln" Basic.SystemTray.Show="Anzeigen" Basic.SystemTray.Hide="Ausblenden" -Basic.SystemTray.Message.Reconnecting="Verbindung verloren. Verbinde erneut …" +Basic.SystemTray.Message.Reconnecting="Verbindung verloren. Verbinde erneut …" Hotkeys.Insert="Einfügen" Hotkeys.Delete="Entfernen" Hotkeys.Home="Pos1" Hotkeys.End="Ende" -Hotkeys.PageUp="Bild-auf" -Hotkeys.PageDown="Bild-ab" -Hotkeys.NumLock="Num-Taste" -Hotkeys.ScrollLock="Rollen-Taste" +Hotkeys.PageUp="Bild‐auf" +Hotkeys.PageDown="Bild‐ab" +Hotkeys.NumLock="Num‐Taste" +Hotkeys.ScrollLock="Rollen‐Taste" Hotkeys.CapsLock="Feststelltaste" Hotkeys.Backspace="Rücktaste" Hotkeys.Tab="Tabulator" @@ -816,39 +838,40 @@ Hotkeys.Escape="Esc" Mute="Stumm" Unmute="Stumm aus" -Push-to-mute="Push-To-Mute" -Push-to-talk="Push-To-Talk" +Push-to-mute="Push‐To‐Mute" +Push-to-talk="Push‐To‐Talk" SceneItemShow="„%1“ anzeigen" SceneItemHide="„%1“ verstecken" OutputWarnings.NoTracksSelected="Sie müssen mindestens eine Spur auswählen" -OutputWarnings.MultiTrackRecording="Warnung: Bestimmte Formate (z. B. FLV) unterstüzen nicht mehrere Spuren pro Aufnahme" -OutputWarnings.MP4Recording="Warnung: Aufnahmen, die in MP4/MOV gespeichert werden, sind nicht wiederherstellbar, wenn die Datei nicht abgeschlossen werden konnte (z. B. als Folge von BSODs, Stromausfällen, etc.). Wenn Sie mehrere Audiospuren aufnehmen möchten, sollten Sie MKV verwenden und die Aufnahme zu MP4/MOV remuxen, nachdem sie fertig ist (Datei → Aufnahmen remuxen)." +OutputWarnings.MultiTrackRecording="Warnung: Bestimmte Formate (wie FLV) unterstützen nicht mehrere Spuren pro Aufnahme" +OutputWarnings.MP4Recording="Warnung: Aufnahmen, die in MP4/MOV gespeichert werden, sind nicht wiederherstellbar, wenn die Datei nicht abgeschlossen werden konnte (z. B. als Folge von BSODs, Stromausfällen, etc.). Wenn Sie mehrere Audiospuren aufnehmen möchten, sollten Sie MKV verwenden und die Aufnahme zu MP4/MOV remuxen, nachdem sie fertig ist (Datei → Aufnahmen remuxen)." +OutputWarnings.CannotPause="Warnung: Aufnahmen können nicht pausiert werden, wenn der Aufnahmekodierer auf „(Streamkodierer verwenden)” gesetzt ist" FinalScene.Title="Szene löschen" FinalScene.Text="Es muss mindestens eine Szene vorhanden sein." NoSources.Title="Keine Quellen" NoSources.Text="Offenbar haben Sie noch keine Videoquellen hinzugefügt, sodass nur ein leerer Bildschirm ausgegeben wird. Sind Sie sicher, dass Sie das wollen?" -NoSources.Text.AddSource="Sie können jederzeit Quellen hinzufügen, indem Sie auf das +-Symbol unter dem Quellenfeld im Hauptfenster klicken." -NoSources.Label="Sie haben bis jetzt keine Quellen hinzugefügt.\nKlicken Sie auf das +-Symbol oder\nrechtsklicken Sie hier, um eine hinzuzufügen." +NoSources.Text.AddSource="Sie können jederzeit Quellen hinzufügen, indem Sie auf das +‐Symbol unter dem Quellenfeld im Hauptfenster klicken." +NoSources.Label="Sie haben bis jetzt keine Quellen hinzugefügt.\nKlicken Sie auf das +‐Symbol oder\nrechtsklicken Sie hier, um eine hinzuzufügen." ChangeBG="Farbe auswählen" CustomColor="Benutzerdefinierte Farbe" -BrowserSource.EnableHardwareAcceleration="Browser-Hardwarebeschleunigung aktivieren" +BrowserSource.EnableHardwareAcceleration="Browser‐Hardwarebeschleunigung aktivieren" About="Über OBS Studio" -About.Info="OBS Studio ist eine freie und Open-Source-Videoaufnahme- und Livestreaming-Software." +About.Info="OBS Studio ist eine freie und Open‐Source‐Videoaufnahme‐ und Livestreaming‐Software." About.Donate="Beitrag leisten" About.GetInvolved="Mitwirken" About.Authors="Autoren" About.License="Lizenzvereinbarung" -About.Contribute="Das OBS-Projekt unterstützen" +About.Contribute="Das OBS‐Projekt unterstützen" ResizeOutputSizeOfSource="Ausgabeauflösung anpassen (Quellgröße)" -ResizeOutputSizeOfSource.Text="Die Basis- und Ausgabeauflösung wird auf die Größe der aktuellen Quelle geändert." +ResizeOutputSizeOfSource.Text="Die Basis‐ und Ausgabeauflösung wird auf die Größe der aktuellen Quelle geändert." ResizeOutputSizeOfSource.Continue="Möchten Sie fortfahren?" PreviewTransition="Übergangsvorschau" diff --git a/UI/data/locale/el-GR.ini b/UI/data/locale/el-GR.ini index cfbce15..d661b54 100644 --- a/UI/data/locale/el-GR.ini +++ b/UI/data/locale/el-GR.ini @@ -5,7 +5,7 @@ Region="Ελλάδα" OK="ΟΚ" Apply="Εφαρμογή" Cancel="Ακύρωση" -Close="Κλείσιμο" +Close="Κλείσε" Save="Αποθήκευση" Discard="Απόρριψη" Disable="Απενεργοποίηση" @@ -23,7 +23,6 @@ Settings="Ρυθμίσεις" Display="Οθόνη" Name="Όνομα" Exit="Έξοδος" -Mixer="Μίκτης" Browse="Αναζήτηση" Mono="Μονοφωνικό" Stereo="Στερεοφωνικό" @@ -54,7 +53,7 @@ Transition="Μετάβαση" QuickTransitions="Γρήγορες Μεταβάσεις" Left="Αριστερά" Right="Δεξιά" -Top="Επάνω" +Top="Πάνω" Bottom="Κάτω" Reset="Επαναφορά" Hours="Ώρες" @@ -87,6 +86,7 @@ AlreadyRunning.LaunchAnyway="Εκκίνηση ούτως ή άλλως" + Copy.Filters="Αντιγραφή Φίλτρων" Paste.Filters="Επικόλληση Φίλτρων" @@ -208,6 +208,7 @@ ConfirmStop.Title="Τερματισμός Ροής;" ConfirmStop.Text="Είστε σίγουροι οτι θέλετε να διακόψετε τη ροή;" + ConfirmExit.Title="Έξοδος από το OBS;" ConfirmExit.Text="Το OBS είναι προσωρινά ενεργό. Όλες οι ροές/καταγραφές θα τερματιστούν. Είστε σίγουροι ότι επιθυμείτε να το κλείσετε;" @@ -542,7 +543,6 @@ Basic.Settings.Output.Mode.Simple="Απλό" Basic.Settings.Output.Mode.Adv="Για Προχωρημένους" Basic.Settings.Output.Mode.FFmpeg="Έξοδος FFmpeg" Basic.Settings.Output.UseReplayBuffer="Ενεργοποίηση Επανάληψης Προσωρινής Μνήμης" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Μέγιστος Χρόνος Επανάληψης (Δευτερόλεπτα)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Μέγιστη Μνήμη (Megabytes)" Basic.Settings.Output.ReplayBuffer.Estimate="Εκτιμώμενη χρήση μνήμης: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Δεν είναι δυνατή η εκτίμηση της χρήσης μνήμης. Ορίστε μέγιστο όριο μνήμης." @@ -569,7 +569,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Λογισμικό (προ Basic.Settings.Output.VideoBitrate="Ρυθμός Μετάδοσης Bit του Βίντεο" Basic.Settings.Output.AudioBitrate="Ρυθμός Μετάδοσης Bit του Ήχου" Basic.Settings.Output.Reconnect="Αυτόματη Επανασύνδεση" -Basic.Settings.Output.RetryDelay="Καθυστέρηση Επανάληψης (δευτερόλεπτα)" Basic.Settings.Output.MaxRetries="Μέγιστος Αριθμός Επαναλήψεων" Basic.Settings.Output.Advanced="Ενεργοποίηση Ρυθμίσεων Κωδικοποιητή Για Προχωρημένους" Basic.Settings.Output.CustomEncoderSettings="Προσαρμοσμένες Ρυθμίσεις Κωδικοποιητή" @@ -638,7 +637,7 @@ Basic.Settings.Video.DisableAero="Απενεργοποίηση του Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Διγραμμικό (Πιο γρήγορο, αλλά θολό στην κλιμάκωση)" Basic.Settings.Video.DownscaleFilter.Bicubic="Δικυβικό (Οξυμμένη κλιμάκωση, 16 δείγματα)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Οξυμμένη κλιμάκωση, 32 δείγματα)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Οξυμμένη κλιμάκωση, 36 δείγματα)" Basic.Settings.Audio="Ήχος" Basic.Settings.Audio.SampleRate="Ρυθμός Δειγματοληψίας" @@ -650,7 +649,7 @@ Basic.Settings.Audio.PeakMeterType="Τύπος Μέτρησης Αιχμής" Basic.Settings.Audio.PeakMeterType.SamplePeak="Δείγμα Αιχμής" Basic.Settings.Audio.PeakMeterType.TruePeak="Πραγματική Αιχμή (Υψηλότερη χρήση της CPU)" Basic.Settings.Audio.MultiChannelWarning.Enabled="Προειδοποίηση: Ο ήχος Surround είναι ενεργοποιημένος." -Basic.Settings.Audio.MultichannelWarning="Κατά τη ροή, ελέγξτε αν η υπηρεσία ροής υποστηρίζει ήχο surround και ήχο surround αναπαραγωγής. Το Twitch, το Facebook 360 Live, το Mixer RTMP καί το Smashcast αποτελούν παραδείγματα όπου ο surround ήχος υποστηρίζεται πλήρως. Αν και το Facebook Live και το YouTube Live αποδέχονται τον ήχο surround, το Facebook Live τον υποβιβάζει σε stereo, και το YouTube Live παίζει μόνο σε δύο κανάλια.\n\nΤα φίλτρα ήχου του OBS είναι συμβατά με ήχο surround, αν καί δεν είναι εγγυημένη η υποστήριξη για plugins VST." +Basic.Settings.Audio.MultichannelWarning="Κατά τη ροή, ελέγξτε αν η υπηρεσία ροής υποστηρίζει ήχο surround και ήχο surround αναπαραγωγής. Το Facebook 360 Live, το Mixer RTMP καί το Smashcast αποτελούν παραδείγματα όπου ο surround ήχος υποστηρίζεται πλήρως. Αν και το Facebook Live και το YouTube Live αποδέχονται τον ήχο surround, το Facebook Live τον υποβιβάζει σε stereo, και το YouTube Live παίζει μόνο σε δύο κανάλια.\n\nΤα φίλτρα ήχου του OBS είναι συμβατά με ήχο surround, αν καί δεν είναι εγγυημένη η υποστήριξη για plugins VST." Basic.Settings.Audio.MultichannelWarning.Title="Ενεργοποίηση ήχου surround;" Basic.Settings.Audio.MultichannelWarning.Confirm="Είστε βέβαιοι ότι θέλετε να ενεργοποιήσετε τον ήχο surround;" Basic.Settings.Audio.EnablePushToMute="Ενεργοποίηση της Πίεσης-για-σίγαση" @@ -674,7 +673,6 @@ Basic.Settings.Advanced.Video.ColorRange.Full="Πλήρες" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Προεπιλεγμένη" Basic.Settings.Advanced.Audio.DisableAudioDucking="Απενεργοποίηση Σίγασης Ήχου Windows" Basic.Settings.Advanced.StreamDelay="Καθυστέρηση Ροής" -Basic.Settings.Advanced.StreamDelay.Duration="Διάρκεια (δευτερόλεπτα)" Basic.Settings.Advanced.StreamDelay.Preserve="Διατήρηση σημείου αποκοπής (αύξηση καθυστέρησης) κατά την επανασύνδεση" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Εκτιμώμενη Χρήση Μνήμης: %1 MB" Basic.Settings.Advanced.Network="Δίκτυο" @@ -687,9 +685,7 @@ Basic.Settings.Advanced.AutoRemux.MP4="(καταγραφή ως mkv)" Basic.AdvAudio="Ιδιότητες Ήχου για Προχωρημένους" Basic.AdvAudio.Name="Όνομα" -Basic.AdvAudio.Mono="Υποβίβαση σε Μονοφωνικό" Basic.AdvAudio.Balance="Εξισορρόπηση" -Basic.AdvAudio.SyncOffset="Μετατόπιση Συγχρονισμού (ms)" Basic.AdvAudio.Monitoring="Ηχητική Παρακολούθηση" Basic.AdvAudio.Monitoring.None="Τερματισμός Παρακολούθησης" Basic.AdvAudio.Monitoring.MonitorOnly="Παρακολούθηση Μόνο (σίγαση εξόδου)" diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini index 2400d1f..096c860 100644 --- a/UI/data/locale/en-US.ini +++ b/UI/data/locale/en-US.ini @@ -28,7 +28,7 @@ Settings="Settings" Display="Display" Name="Name" Exit="Exit" -Mixer="Mixer" +Mixer="Audio Mixer" Browse="Browse" Mono="Mono" Stereo="Stereo" @@ -98,6 +98,11 @@ AlreadyRunning.LaunchAnyway="Launch Anyway" DockCloseWarning.Title="Closing Dockable Window" DockCloseWarning.Text="You just closed a dockable window. If you'd like to show it again, use the View → Docks menu on the menu bar." +# extra browser panels dialog +ExtraBrowsers="Custom Browser Docks" +ExtraBrowsers.Info="Add docks by giving them a name and URL, then click Apply or Close to open the docks. You can add or remove docks at any time." +ExtraBrowsers.DockName="Dock Name" + # Auth Auth.Authing.Title="Authenticating..." Auth.Authing.Text="Authenticating with %1, please wait..." @@ -115,6 +120,7 @@ TwitchAuth.Stats="Twitch Stats" TwitchAuth.Feed="Twitch Activity Feed" TwitchAuth.TwoFactorFail.Title="Could not query stream key" TwitchAuth.TwoFactorFail.Text="OBS was unable to connect to your Twitch account. Please make sure two-factor authentication is set up in your Twitch security settings as this is required to stream." +RestreamAuth.Channels="Restream Channels" # copy filters Copy.Filters="Copy Filters" @@ -152,7 +158,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Either 60 or 30, but prefer high r Basic.AutoConfig.VideoPage.CanvasExplanation="Note: The canvas (base) resolution is not necessarily the same as the resolution you will stream or record with. Your actual stream/recording resolution may be scaled down from the canvas resolution to reduce resource usage or bitrate requirements." Basic.AutoConfig.StreamPage="Stream Information" Basic.AutoConfig.StreamPage.SubTitle="Please enter your stream information" -Basic.AutoConfig.StreamPage.ConnectAccount="Connect Account (optional)" +Basic.AutoConfig.StreamPage.ConnectAccount="Connect Account (recommended)" Basic.AutoConfig.StreamPage.DisconnectAccount="Disconnect Account" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Disconnect Account?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="This change will apply immediately. Are you sure you want to disconnect your account?" @@ -262,6 +268,10 @@ ConfirmStart.Text="Are you sure you want to start the stream?" ConfirmStop.Title="Stop Stream?" ConfirmStop.Text="Are you sure you want to stop the stream?" +# confirm stop record dialog box +ConfirmStopRecord.Title="Stop Recording?" +ConfirmStopRecord.Text="Are you sure you want to stop recording?" + # confirm bandwidth test dialog box ConfirmBWTest.Title="Start Bandwidth Test?" ConfirmBWTest.Text="You have OBS configured in bandwidth test mode. This mode allows for network testing without your channel going live. Once you are done testing, you will need to disable it in order for viewers to be able to see your stream.\n\nDo you want to continue?" @@ -281,6 +291,9 @@ Output.StartRecordingFailed="Failed to start recording" Output.StartReplayFailed="Failed to start replay buffer" Output.StartFailedGeneric="Starting the output failed. Please check the log for details.\n\nNote: If you are using the NVENC or AMD encoders, make sure your video drivers are up to date." +# replay buffer + pause warning message +Output.ReplayBuffer.PauseWarning.Title="Cannot save replays while paused" +Output.ReplayBuffer.PauseWarning.Text="Warning: Replays cannot be saved while recording is paused." # output connect messages Output.ConnectFail.Title="Failed to connect" @@ -501,6 +514,8 @@ Basic.Main.StartRecording="Start Recording" Basic.Main.StartReplayBuffer="Start Replay Buffer" Basic.Main.StartStreaming="Start Streaming" Basic.Main.StopRecording="Stop Recording" +Basic.Main.PauseRecording="Pause Recording" +Basic.Main.UnpauseRecording="Unpause Recording" Basic.Main.StoppingRecording="Stopping Recording..." Basic.Main.StopReplayBuffer="Stop Replay Buffer" Basic.Main.StoppingReplayBuffer="Stopping Replay Buffer..." @@ -562,6 +577,7 @@ Basic.MainMenu.View.Toolbars="&Toolbars" Basic.MainMenu.View.Docks="Docks" Basic.MainMenu.View.Docks.ResetUI="Reset UI" Basic.MainMenu.View.Docks.LockUI="Lock UI" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Custom Browser Docks..." Basic.MainMenu.View.Toolbars.Listboxes="&Listboxes" Basic.MainMenu.View.SceneTransitions="S&cene Transitions" Basic.MainMenu.View.StatusBar="&Status Bar" @@ -609,6 +625,7 @@ Basic.Settings.General.EnableAutoUpdates="Automatically check for updates on sta Basic.Settings.General.OpenStatsOnStartup="Open stats dialog on startup" Basic.Settings.General.WarnBeforeStartingStream="Show confirmation dialog when starting streams" Basic.Settings.General.WarnBeforeStoppingStream="Show confirmation dialog when stopping streams" +Basic.Settings.General.WarnBeforeStoppingRecord="Show confirmation dialog when stopping recording" Basic.Settings.General.Projectors="Projectors" Basic.Settings.General.HideProjectorCursor="Hide cursor over projectors" Basic.Settings.General.ProjectorAlwaysOnTop="Make projectors always on top" @@ -658,12 +675,15 @@ Basic.Settings.Output.Encoder="Encoder" Basic.Settings.Output.SelectDirectory="Select Recording Directory" Basic.Settings.Output.SelectFile="Select Recording File" Basic.Settings.Output.EnforceBitrate="Enforce streaming service bitrate limits" +Basic.Settings.Output.DynamicBitrate="Dynamically change bitrate to manage congestion" +Basic.Settings.Output.DynamicBitrate.Beta="Dynamically change bitrate to manage congestion (Beta)" +Basic.Settings.Output.DynamicBitrate.TT="Instead of dropping frames to reduce congestion, dynamically changes bitrate on the fly.\n\nNote that this can increase delay to viewers if there is significant sudden congestion.\nWhen the bitrate drops, it can take up to a few minutes to restore.\n\nCurrently only supported for RTMP." Basic.Settings.Output.Mode="Output Mode" Basic.Settings.Output.Mode.Simple="Simple" Basic.Settings.Output.Mode.Adv="Advanced" Basic.Settings.Output.Mode.FFmpeg="FFmpeg Output" Basic.Settings.Output.UseReplayBuffer="Enable Replay Buffer" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximum Replay Time (Seconds)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximum Replay Time" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximum Memory (Megabytes)" Basic.Settings.Output.ReplayBuffer.Estimate="Estimated memory usage: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Cannot estimate memory usage. Please set maximum memory limit." @@ -678,6 +698,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Indistinguishable Quality, Lar Basic.Settings.Output.Simple.RecordingQuality.Lossless="Lossless Quality, Tremendously Large File Size" Basic.Settings.Output.Simple.Warn.VideoBitrate="Warning: The streaming video bitrate will be set to %1, which is the upper limit for the current streaming service. If you're sure you want to go above %1, enable advanced encoder options and uncheck \"Enforce streaming service bitrate limits\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Warning: The streaming audio bitrate will be set to %1, which is the upper limit for the current streaming service. If you're sure you want to go above %1, enable advanced encoder options and uncheck \"Enforce streaming service bitrate limits\"." +Basic.Settings.Output.Simple.Warn.CannotPause="Warning: Recordings cannot be paused if the recording quality is set to \"Same as stream\"." Basic.Settings.Output.Simple.Warn.Encoder="Warning: Recording with a software encoder at a different quality than the stream will require extra CPU usage if you stream and record at the same time." Basic.Settings.Output.Simple.Warn.Lossless="Warning: Lossless quality generates tremendously large file sizes! Lossless quality can use upward of 7 gigabytes of disk space per minute at high resolutions and framerates. Lossless is not recommended for long recordings unless you have a very large amount of disk space available." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Are you sure you want to use lossless quality?" @@ -690,7 +711,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 low CPU usag Basic.Settings.Output.VideoBitrate="Video Bitrate" Basic.Settings.Output.AudioBitrate="Audio Bitrate" Basic.Settings.Output.Reconnect="Automatically Reconnect" -Basic.Settings.Output.RetryDelay="Retry Delay (seconds)" +Basic.Settings.Output.RetryDelay="Retry Delay" Basic.Settings.Output.MaxRetries="Maximum Retries" Basic.Settings.Output.Advanced="Enable Advanced Encoder Settings" Basic.Settings.Output.EncoderPreset="Encoder Preset" @@ -767,7 +788,8 @@ Basic.Settings.Video.DisableAero="Disable Aero" # scale filters Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (Fastest, but blurry if scaling)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (Sharpened scaling, 16 samples)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Sharpened scaling, 32 samples)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Sharpened scaling, 36 samples)" +Basic.Settings.Video.DownscaleFilter.Area="Area (Weighted sum, 4/6/9 samples)" # basic mode 'audio' settings Basic.Settings.Audio="Audio" @@ -782,7 +804,7 @@ Basic.Settings.Audio.PeakMeterType="Peak Meter Type" Basic.Settings.Audio.PeakMeterType.SamplePeak="Sample Peak" Basic.Settings.Audio.PeakMeterType.TruePeak="True Peak (Higher CPU usage)" Basic.Settings.Audio.MultiChannelWarning.Enabled="WARNING: Surround sound audio is enabled." -Basic.Settings.Audio.MultichannelWarning="If streaming, check to see if your streaming service supports both surround sound ingest and surround sound playback. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast are examples where surround sound is fully supported. Although Facebook Live and YouTube Live both accept surround ingest, Facebook Live downmixes to stereo, and YouTube Live plays only two channels.\n\nOBS audio filters are compatible with surround sound, though VST plugin support isn't guaranteed." +Basic.Settings.Audio.MultichannelWarning="If streaming, check to see if your streaming service supports both surround sound ingest and surround sound playback. Facebook 360 Live, Mixer RTMP, Smashcast are examples where surround sound is fully supported. Although Facebook Live and YouTube Live both accept surround ingest, Facebook Live downmixes to stereo, and YouTube Live plays only two channels.\n\nOBS audio filters are compatible with surround sound, though VST plugin support isn't guaranteed." Basic.Settings.Audio.MultichannelWarning.Title="Enable surround sound audio?" Basic.Settings.Audio.MultichannelWarning.Confirm="Are you sure you want to enable surround sound audio?" Basic.Settings.Audio.Devices="Devices" @@ -818,14 +840,17 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Monitoring Device" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Default" Basic.Settings.Advanced.Audio.DisableAudioDucking="Disable Windows audio ducking" Basic.Settings.Advanced.StreamDelay="Stream Delay" -Basic.Settings.Advanced.StreamDelay.Duration="Duration (seconds)" +Basic.Settings.Advanced.StreamDelay.Duration="Duration" Basic.Settings.Advanced.StreamDelay.Preserve="Preserve cutoff point (increase delay) when reconnecting" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Estimated Memory Usage: %1 MB" Basic.Settings.Advanced.Network="Network" Basic.Settings.Advanced.Network.BindToIP="Bind to IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Enable new networking code" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Low latency mode" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Hotkey Focus Behavior" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Never disable hotkeys" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Disable hotkeys when main window is in focus" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Disable hotkeys when main window is not in focus" Basic.Settings.Advanced.AutoRemux="Automatically remux to mp4" Basic.Settings.Advanced.AutoRemux.MP4="(record as mkv)" @@ -833,9 +858,9 @@ Basic.Settings.Advanced.AutoRemux.MP4="(record as mkv)" Basic.AdvAudio="Advanced Audio Properties" Basic.AdvAudio.Name="Name" Basic.AdvAudio.Volume="Volume" -Basic.AdvAudio.Mono="Downmix to Mono" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Balance" -Basic.AdvAudio.SyncOffset="Sync Offset (ms)" +Basic.AdvAudio.SyncOffset="Sync Offset" Basic.AdvAudio.Monitoring="Audio Monitoring" Basic.AdvAudio.Monitoring.None="Monitor Off" Basic.AdvAudio.Monitoring.MonitorOnly="Monitor Only (mute output)" @@ -909,6 +934,7 @@ SceneItemHide="Hide '%1'" OutputWarnings.NoTracksSelected="You must select at least one track" OutputWarnings.MultiTrackRecording="Warning: Certain formats (such as FLV) do not support multiple tracks per recording" OutputWarnings.MP4Recording="Warning: Recordings saved to MP4/MOV will be unrecoverable if the file cannot be finalized (e.g. as a result of BSODs, power losses, etc.). If you want to record multiple audio tracks consider using MKV and remux the recording to MP4/MOV after it is finished (File → Remux Recordings)" +OutputWarnings.CannotPause="Warning: Recordings cannot be paused if the recording encoder is set to \"(Use stream encoder)\"" # deleting final scene FinalScene.Title="Delete Scene" diff --git a/UI/data/locale/es-ES.ini b/UI/data/locale/es-ES.ini index 9640af6..1dd5427 100644 --- a/UI/data/locale/es-ES.ini +++ b/UI/data/locale/es-ES.ini @@ -23,7 +23,7 @@ Settings="Ajustes" Display="Pantalla" Name="Nombre" Exit="Salir" -Mixer="Mezclador" +Mixer="Mezclador de audio" Browse="Examinar" Mono="Mono" Stereo="Estéreo" @@ -89,7 +89,11 @@ AlreadyRunning.Text="¡OBS ya se está ejecutando! A no ser que quieras hacer es AlreadyRunning.LaunchAnyway="Lanzar de todas maneras" DockCloseWarning.Title="Cerrando ventana acoplable" -DockCloseWarning.Text="Acabas de cerrar una ventana acoplable. Si quieres mostrarla de nuevo, usa Vista → Acoplar en la barra de menús." +DockCloseWarning.Text="Acabas de cerrar una ventana acoplable. Si quieres mostrarla de nuevo, usa Vista → Paneles en la barra de menús." + +ExtraBrowsers="Paneles de navegador personalizados" +ExtraBrowsers.Info="Añade paneles dándoles un nombre y una URL, luego haz clic en Aplicar o Cerrar para abrir los paneles. Puedes añadir o eliminar los paneles en cualquier momento." +ExtraBrowsers.DockName="Nombre del Panel" Auth.Authing.Title="Autentificando..." Auth.Authing.Text="Autentificando con %1, por favor espera..." @@ -107,6 +111,7 @@ TwitchAuth.Stats="Estadísticas de Twitch" TwitchAuth.Feed="Fuente de actividades de Twitch" TwitchAuth.TwoFactorFail.Title="No se pudo obtener la clave de transmisión" TwitchAuth.TwoFactorFail.Text="OBS no pudo conectarse a su cuenta de Twitch. Por favor, asegúrese de que la autenticación en dos pasos está configurada en su configuración de seguridad Configuración de seguridad de Twitch ya que esto es necesario para transmitir." +RestreamAuth.Channels="Canales Restream" Copy.Filters="Copiar filtros" Paste.Filters="Pegar filtros" @@ -139,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 o 30, pero usar alta resolució Basic.AutoConfig.VideoPage.CanvasExplanation="Nota: La resolución del lienzo (base) no es necesariamente la misma que la resolución de la transmisión o grabación. La resolución actual puede ser reducida del lienzo para reducir el uso de los recursos o del bitrate." Basic.AutoConfig.StreamPage="Información de servicio de Stream" Basic.AutoConfig.StreamPage.SubTitle="Por favor, introduce información sobre tu servicio de stream" -Basic.AutoConfig.StreamPage.ConnectAccount="Conectar cuenta (opcional)" +Basic.AutoConfig.StreamPage.ConnectAccount="Conectar cuenta (recomendado)" Basic.AutoConfig.StreamPage.DisconnectAccount="Desconectar cuenta" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="¿Desconectar cuenta?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Este cambio se aplicará inmediatamente. ¿Está seguro de que desea desconectar su cuenta?" @@ -191,8 +196,8 @@ Basic.Stats.MegabytesSent="Salida de datos total" Basic.Stats.Bitrate="Bitrate" Basic.Stats.DiskFullIn="Disco lleno en (aprox.)" -ResetUIWarning.Title="¿Está seguro de que desea restablecer la interfáz?" -ResetUIWarning.Text="Restablecer la interfaz ocultará los docks adicionales. Necesitarás eliminar estos docks del menú de vista si quieres que sean visibles.\n\n¿Estás seguro de que quieres restablecer la interfaz?" +ResetUIWarning.Title="¿Está seguro de que desea restablecer la interfaz?" +ResetUIWarning.Text="Restablecer la interfaz ocultará los paneles adicionales. Necesitarás desocultar estos paneles del menú de vista si quieres que sean visibles.\n\n¿Estás seguro de que quieres restablecer la interfaz?" Updater.Title="Nueva actualización disponible" Updater.Text="Hay una nueva versión disponible:" @@ -240,6 +245,9 @@ ConfirmStart.Text="¿Está seguro que desea iniciar la transmisión?" ConfirmStop.Title="¿Parar Transmisión?" ConfirmStop.Text="¿Está seguro que desea parar la transmisión?" +ConfirmStopRecord.Title="¿Detener la grabación?" +ConfirmStopRecord.Text="¿Estás seguro de que deseas parar la grabación?" + ConfirmBWTest.Title="¿Iniciar prueba de ancho de banda?" ConfirmBWTest.Text="Tienes OBS configurado en modo de prueba de ancho de banda. Este modo permite pruebas de red sin que tu canal esté en vivo. Una vez que hayas terminado de probar, necesitarás desactivarlo para que los espectadores puedan ver tu stream.\n\n¿Quieres continuar?" @@ -255,6 +263,8 @@ Output.StartRecordingFailed="No se pudo iniciar grabación" Output.StartReplayFailed="No se pudo iniciar el buffer de replay" Output.StartFailedGeneric="No se pudo iniciar la salida. Por favor compruebe los logs para mas detalles. \n\nNota: Si estas usando los codificadores de NVENC o AMD, asegúrate que tus drivers de vídeo están actualizados." +Output.ReplayBuffer.PauseWarning.Title="No se pueden guardar repeticiones mientras está pausado" +Output.ReplayBuffer.PauseWarning.Text="Advertencia: No se pueden guardar repeticiones mientras la grabación está pausada." Output.ConnectFail.Title="Error al conectarse" Output.ConnectFail.BadPath="URL ruta de acceso o conexión no válida. Por favor, compruebe su configuración para confirmar que está correcta." @@ -291,7 +301,7 @@ Remux.ClearFinished="Borrar los elementos finalizados" Remux.ClearAll="Borrar todos los elementos" Remux.OBSRecording="Grabación OBS" Remux.FinishedTitle="Conversión finalizada" -Remux.Finished="Grabando conversión" +Remux.Finished="Grabación convertida" Remux.FinishedError="Grabación convertida, pero el archivo podría estar incompleto" Remux.SelectRecording="Seleccione grabación de OBS..." Remux.SelectTarget="Seleccione archivo de destino..." @@ -444,6 +454,8 @@ Basic.Main.StartRecording="Iniciar grabación" Basic.Main.StartReplayBuffer="Iniciar la reproducción del búfer" Basic.Main.StartStreaming="Iniciar Transmisión" Basic.Main.StopRecording="Detener grabación" +Basic.Main.PauseRecording="Pausar la grabación" +Basic.Main.UnpauseRecording="Reanudar la grabación" Basic.Main.StoppingRecording="Deteniendo la grabación..." Basic.Main.StopReplayBuffer="Detener la reproducción del búfer" Basic.Main.StoppingReplayBuffer="Deteniendo la reproducción del búfer..." @@ -499,9 +511,10 @@ Basic.MainMenu.Edit.AdvAudio="Propiedades de &Audio avanzadas" Basic.MainMenu.View="&Vista" Basic.MainMenu.View.Toolbars="Barra de Herramien&tas" -Basic.MainMenu.View.Docks="Acoplar" +Basic.MainMenu.View.Docks="Paneles" Basic.MainMenu.View.Docks.ResetUI="Reestablecer Interfaz de Usuario" Basic.MainMenu.View.Docks.LockUI="Bloquear Interfaz de Usuario" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Paneles de navegador personalizados..." Basic.MainMenu.View.Toolbars.Listboxes="Cuadro de &Lista" Basic.MainMenu.View.SceneTransitions="Transi&ción de Escenas" Basic.MainMenu.View.StatusBar="Barra de E&stado" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="Comprobar actualizaciones automáticam Basic.Settings.General.OpenStatsOnStartup="Abrir dialogo de estadísticas al inicio" Basic.Settings.General.WarnBeforeStartingStream="Mostrar diálogo de confirmación cuando se inicia una transmisión" Basic.Settings.General.WarnBeforeStoppingStream="Mostrar diálogo de confirmación cuando se para una transmisión" +Basic.Settings.General.WarnBeforeStoppingRecord="Mostrar diálogo de confirmación al detener la grabación" Basic.Settings.General.Projectors="Proyectores" Basic.Settings.General.HideProjectorCursor="Ocultar el cursor sobre proyectores" Basic.Settings.General.ProjectorAlwaysOnTop="Proyectores siempre en la parte superior" @@ -591,12 +605,15 @@ Basic.Settings.Output.Encoder="Codificador" Basic.Settings.Output.SelectDirectory="Seleccione Directorio de grabación" Basic.Settings.Output.SelectFile="Seleccione archivo de grabación" Basic.Settings.Output.EnforceBitrate="Aplicar los límites de bitrate del servicio de streaming" +Basic.Settings.Output.DynamicBitrate="Cambia dinámicamente la tasa de bits para gestionar la congestión" +Basic.Settings.Output.DynamicBitrate.Beta="Cambia dinámicamente la tasa de bits para gestionar la congestión (Beta)" +Basic.Settings.Output.DynamicBitrate.TT="En lugar de saltar fotogramas para reducir la congestión, cambia dinámicamente el bitrate sobre la marcha.\n\nTen en cuenta que esto puede aumentar el retardo de la transmisión si hay una congestión repentina significativa.\nCuando el bitrate baja, puede tardar unos minutos en restaurarse.\n\nActualmente sólo es compatible con RTMP." Basic.Settings.Output.Mode="Modo de salida" Basic.Settings.Output.Mode.Simple="Sencillo" Basic.Settings.Output.Mode.Adv="Avanzado" Basic.Settings.Output.Mode.FFmpeg="Salida de FFmpeg" Basic.Settings.Output.UseReplayBuffer="Activar la reproducción del búfer" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Tiempo de reproducción máximo (segundos)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Tiempo Máximo para Repeticiones" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memoria máxima (MB)" Basic.Settings.Output.ReplayBuffer.Estimate="Uso estimado de memoria: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="No se puede estimar el uso de memoria. Establezca el límite máximo de memoria." @@ -611,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Tamaño de archivo grande, cal Basic.Settings.Output.Simple.RecordingQuality.Lossless="Tamaño del archivo sin pérdida de calidad, tremendamente grande" Basic.Settings.Output.Simple.Warn.VideoBitrate="ADVERTENCIA: El streaming de vídeo se establecerá a %1, que es el límite superior para el servicio de streaming actual. Si estás seguro que quieres ir por encima de %1, active las opciones avanzadas del codificador y desactive \"Forzar limites de bitrate en el servicio de streaming\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="ADVERTENCIA: El streaming de audio se establecerá a %1, que es el límite superior para el servicio de streaming actual. Si estás seguro que quieres ir por encima de %1, active las opciones avanzadas del codificador y desactive \"Forzar limites de bitrate en el servicio de streaming\"." +Basic.Settings.Output.Simple.Warn.CannotPause="Advertencia: Las grabaciones no se pueden pausar si la calidad de grabación se establece en \"Igual al stream\"." Basic.Settings.Output.Simple.Warn.Encoder="ADVERTENCIA: Grabar con un codificador de software de una calidad diferente a la de la transmisión requerirá un uso adicional de la CPU si transmite y graba al mismo tiempo." Basic.Settings.Output.Simple.Warn.Lossless="ADVERTENCIA: ¡La calidad sin perdidas genera tamaños de archivo muy grandes! La calidad sin pérdidas puede utilizar más de 7 gigabytes de espacio en disco por minuto en alta resolución y con alta tasa de fotogramas. La calidad sin pérdidas no se recomienda para grabaciones largas, a menos que tenga una gran cantidad de espacio en disco disponible." Basic.Settings.Output.Simple.Warn.Lossless.Msg="¿Confirma que desea utilizar calidad sin perdidas?" @@ -623,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 bajo uso de Basic.Settings.Output.VideoBitrate="Bitrate de vídeo" Basic.Settings.Output.AudioBitrate="Bitrate de audio" Basic.Settings.Output.Reconnect="Reconectar automáticamente" -Basic.Settings.Output.RetryDelay="Retardo al re-intentar (segundos)" +Basic.Settings.Output.RetryDelay="Retraso para reintentar" Basic.Settings.Output.MaxRetries="Reintentos máximos" Basic.Settings.Output.Advanced="Habilitar la configuración de codificador avanzada" Basic.Settings.Output.EncoderPreset="Preajuste del codificador" @@ -694,13 +712,14 @@ Basic.Settings.Video.DisableAero="Deshabilitar Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilineal (más rápido, pero borroso si se escala la imagen)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicúbico (Escalado fino, 16 muestras)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Escalado fino, 32 muestras)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Escalado fino, 36 muestras)" +Basic.Settings.Video.DownscaleFilter.Area="Área (Suma ponderada, 4/6/9 muestras)" Basic.Settings.Audio="Audio" Basic.Settings.Audio.SampleRate="Frecuencia de muestreo" Basic.Settings.Audio.Channels="Canales" Basic.Settings.Audio.Meters="Medidores" -Basic.Settings.Audio.MeterDecayRate="Velocidad de descomposición" +Basic.Settings.Audio.MeterDecayRate="Velocidad de decaimiento" Basic.Settings.Audio.MeterDecayRate.Fast="Rápida" Basic.Settings.Audio.MeterDecayRate.Medium="Media (PPM de tipo I)" Basic.Settings.Audio.MeterDecayRate.Slow="Lenta (PPM de tipo II)" @@ -708,7 +727,7 @@ Basic.Settings.Audio.PeakMeterType="Tipo de medidor de pico" Basic.Settings.Audio.PeakMeterType.SamplePeak="Pico de muestra" Basic.Settings.Audio.PeakMeterType.TruePeak="True Peak (mayor uso de CPU)" Basic.Settings.Audio.MultiChannelWarning.Enabled="ADVERTENCIA: el audio de sonido envolvente está habilitado." -Basic.Settings.Audio.MultichannelWarning="Si se está transmitiendo, compruebe si su servicio de transmisión admite la ingesta de sonido envolvente y la reproducción de sonido envolvente. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast son ejemplos en los que el sonido envolvente es totalmente compatible. Aunque Facebook Live y YouTube Live aceptan la ingesta surround, Facebook Live mezcla a estéreo y YouTube Live solo reproduce dos canales.\n\nLos filtros de audio OBS son compatibles con sonido envolvente, aunque no se garantiza el soporte de complementos VST." +Basic.Settings.Audio.MultichannelWarning="Si se está transmitiendo, compruebe si su servicio de transmisión admite la ingesta de sonido envolvente y la reproducción de sonido envolvente. Facebook 360 Live, Mixer RTMP, Smashcast son ejemplos en los que el sonido envolvente es totalmente compatible. Aunque Facebook Live y YouTube Live aceptan la ingesta surround, Facebook Live mezcla a estéreo y YouTube Live solo reproduce dos canales.\n\nLos filtros de audio OBS son compatibles con sonido envolvente, aunque no se garantiza el soporte de complementos VST." Basic.Settings.Audio.MultichannelWarning.Title="¿Habilitar el audio de sonido envolvente?" Basic.Settings.Audio.MultichannelWarning.Confirm="¿Seguro que quiere habilitar el audio de sonido envolvente?" Basic.Settings.Audio.Devices="Dispositivos" @@ -743,23 +762,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositivo de monitorización d Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Por defecto" Basic.Settings.Advanced.Audio.DisableAudioDucking="Desactivar reducción de audio de Windows" Basic.Settings.Advanced.StreamDelay="Retardo de la transmisión" -Basic.Settings.Advanced.StreamDelay.Duration="Duración (segundos)" +Basic.Settings.Advanced.StreamDelay.Duration="Duración" Basic.Settings.Advanced.StreamDelay.Preserve="Preservar el punto de corte (aumento de retardo) al volver a conectar" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Uso estimado de memoria: %1 MB" Basic.Settings.Advanced.Network="Red" Basic.Settings.Advanced.Network.BindToIP="Enlazar con IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Habilitar el nuevo código de red" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Modo de baja latencia" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Comportamiento de las teclas rápidas" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Nunca desactivar las teclas rápidas" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Deshabilitar teclas de acceso rápido cuando la ventana principal se encuentre activa" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Deshabilitar teclas rápidas cuando la ventana principal no esté en primer plano" Basic.Settings.Advanced.AutoRemux="Convertir automáticamente a mp4" Basic.Settings.Advanced.AutoRemux.MP4="(grabar como mkv)" Basic.AdvAudio="Propiedades de Audio avanzadas" Basic.AdvAudio.Name="Nombre" Basic.AdvAudio.Volume="Volumen" -Basic.AdvAudio.Mono="Remezclar a Mono" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Balance" -Basic.AdvAudio.SyncOffset="Sincronización Offset (ms)" +Basic.AdvAudio.SyncOffset="Intervalo de sincronización" Basic.AdvAudio.Monitoring="Monitorización de audio" Basic.AdvAudio.Monitoring.None="Monitorización desactivada" Basic.AdvAudio.Monitoring.MonitorOnly="Solo monitorización (silenciar la salida)" @@ -825,6 +847,7 @@ SceneItemHide="Ocultar '%1'" OutputWarnings.NoTracksSelected="Debe seleccionar al menos una pista" OutputWarnings.MultiTrackRecording="ADVERTENCIA: Ciertos formatos (como FLV) no admiten varias pistas por grabación" OutputWarnings.MP4Recording="Advertencia: Las grabaciones guardadas en MP4/MOV serán irrecuperables si el archivo no puede finalizarse (e.g. como resultado de BSODs, cortes eléctricos, etc.). Si quieres grabar múltiples pistas de audio considera usar MKV y convierte la grabación a MP4/MOV después de finalizar (Archivo → Convertir Grabaciones)" +OutputWarnings.CannotPause="Advertencia: Las grabaciones no se pueden pausar si el codificador de grabación se establece en \"(Usar codificador de transmisión)\"" FinalScene.Title="Eliminar escena" FinalScene.Text="Debe haber al menos una escena." diff --git a/UI/data/locale/et-EE.ini b/UI/data/locale/et-EE.ini index a3460e5..e983f8d 100644 --- a/UI/data/locale/et-EE.ini +++ b/UI/data/locale/et-EE.ini @@ -23,7 +23,6 @@ Settings="Sätted" Display="Kuva" Name="Nimi" Exit="Välju" -Mixer="Mikser" Browse="Sirvi" Mono="Mono" Stereo="Stereo" @@ -71,6 +70,7 @@ AlreadyRunning.Title="OBS juba töötab" + BandwidthTest.Region.US="Ameerika Ühendriigid" BandwidthTest.Region.EU="Euroopa" BandwidthTest.Region.Asia="Aasia" @@ -133,6 +133,7 @@ ConfirmStop.Title="Lõpetada voogedastus?" ConfirmStop.Text="Kas soovid kindlasti voogedastust lõpetada?" + ConfirmExit.Title="Kas väljuda OBS-ist?" ConfirmExit.Text="OBS on hetkel aktiivne. Kõik voogedastused ja salvestused peatatakse. Kas soovid kindlasti väljuda?" @@ -430,7 +431,6 @@ Basic.Settings.Advanced.Video.ColorRange.Partial="Osaline" Basic.Settings.Advanced.Video.ColorRange.Full="Täielik" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Vaikeseade" Basic.Settings.Advanced.StreamDelay="Voogedastuse Viivitus" -Basic.Settings.Advanced.StreamDelay.Duration="Kestvus (sekundit)" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Hinnanguline mälu hõivatus: %1 MB" Basic.Settings.Advanced.Network="Võrk" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Madal-viivitus režiim" diff --git a/UI/data/locale/eu-ES.ini b/UI/data/locale/eu-ES.ini index 4c3ea08..220d072 100644 --- a/UI/data/locale/eu-ES.ini +++ b/UI/data/locale/eu-ES.ini @@ -23,7 +23,7 @@ Settings="Ezarpenak" Display="Pantaila" Name="Izena" Exit="Irten" -Mixer="Nahastailea" +Mixer="Audio nahastailea" Browse="Arakatu" Mono="Monoa" Stereo="Estereoa" @@ -91,6 +91,10 @@ AlreadyRunning.LaunchAnyway="Abiarazi hala ere" DockCloseWarning.Title="Leiho moldagarria ixten" DockCloseWarning.Text="Leiho moldagarri bat itxi berri duzu. Berriro bistaratu nahi baduzu, erabili menu barrako Ikusi → Leiho moldagarriak menua." +ExtraBrowsers="Nabigatzailearen atrake pertsonalizatuak" +ExtraBrowsers.Info="Gehitu atrakeak izena eta URLa emanda, orduan egin klik Aplikatu-n edo Itxi atrakeak irekitzeko. Edozein unean gehitu edo kendu ditzakezu atrakeak." +ExtraBrowsers.DockName="Atrakearen izena" + Auth.Authing.Title="Egiaztatzen..." Auth.Authing.Text="%1(r) ekin egiaztatzen, itxaron..." Auth.AuthFailure.Title="Autentifikazioak huts egin du" @@ -107,6 +111,7 @@ TwitchAuth.Stats="Twitch-estatistikak" TwitchAuth.Feed="Twich aktibitateen jarioa" TwitchAuth.TwoFactorFail.Title="Ezin izan da transmisioaren gakoa galdetu" TwitchAuth.TwoFactorFail.Text="OBS-ek ez du lortu konektatzea zure Twitch kontuarekin. Egiazta ezazu bi urratsetako identifikazioa ezarrita dagoela zure Twitch-eko segurtasun ezarpenetan transmisiorako beharrezkoa da eta." +RestreamAuth.Channels="Bir-trasmisio kanalak" Copy.Filters="Kopiatu iragazkiak" Paste.Filters="Itsatsi iragazkiak" @@ -139,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Izan daiteke 60 edo 30, baina nahi Basic.AutoConfig.VideoPage.CanvasExplanation="Oharra: grabaziorako erabiliko duzun bereizmena ez du zertan oihalaren (oinarriaren) bereizmen berdina. Uneko transmisioaren/grabazioaren bereizmena behera eskalatu daiteke txikiagotzeko baliabideen erabilera edo bit emariaren eskakizuna." Basic.AutoConfig.StreamPage="Transmisioaren informazioa" Basic.AutoConfig.StreamPage.SubTitle="Sartu transmisioaren informazioa" -Basic.AutoConfig.StreamPage.ConnectAccount="Konektatu kontua (aukerazkoa)" +Basic.AutoConfig.StreamPage.ConnectAccount="Konektatu kontua (gomendatua)" Basic.AutoConfig.StreamPage.DisconnectAccount="Deskonektatu kontua" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Kontua deskonektatu?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Aldaketa hau berehalakoan aplika daiteke. Ziur zaude kontua deskonektatu nahi duzula?" @@ -240,6 +245,9 @@ ConfirmStart.Text="Ziur zaude transmisioa hasi nahi duzula?" ConfirmStop.Title="Gelditu transmisioa?" ConfirmStop.Text="Ziur zaude transmisioa gelditu nahi duzula?" +ConfirmStopRecord.Title="Gelditu grabazioa?" +ConfirmStopRecord.Text="Ziur zaude grabazioa gelditu nahi duzula?" + ConfirmBWTest.Title="Banda zabaleraren azterketa hasi?" ConfirmBWTest.Text="OBS banda zabalera azterketa moduan duzu konfiguratua. Modu honek sareko azterketak egiteko aukera ematen du zure kanala aktibatu gabe. Behin azterketa egin ondoren, desaktibatu behar duzu ikusleek zure transmisioa ikus dezaten.\n\nJarraitu nahi duzu?" @@ -255,6 +263,8 @@ Output.StartRecordingFailed="Huts egin du grabazioak" Output.StartReplayFailed="Huts egin du erreprodukzio bufferrak" Output.StartFailedGeneric="Huts egin du irteeraren abioak. Begiratu erregistroa zehaztasunak ikusteko.\n\nOharra: NVENC edo AMD kodetzaileak erabiltzen ari bazara segurtatu haien kontrolatzaileak eguneratuta daudela." +Output.ReplayBuffer.PauseWarning.Title="Ezin dira errepikapenak dauden pausatuta dagoenean" +Output.ReplayBuffer.PauseWarning.Text="Kontuz: errepikapenak ezin dira gorde grabaketa pausatuta dagoenean." Output.ConnectFail.Title="Huts egin du konektatzean" Output.ConnectFail.BadPath="Helburu edo konexio-URL okerra. Egiaztatu zure ezarpenak baliozkoak direla baieztatzeko." @@ -444,6 +454,8 @@ Basic.Main.StartRecording="Hasi grabazioa" Basic.Main.StartReplayBuffer="Abiatu erreprodukzio bufferra" Basic.Main.StartStreaming="Hasi transmisioa" Basic.Main.StopRecording="Gelditu grabazioa" +Basic.Main.PauseRecording="Pausatu grabazioa" +Basic.Main.UnpauseRecording="Amaitu grabazioaren pausa" Basic.Main.StoppingRecording="Grabazioa gelditzen..." Basic.Main.StopReplayBuffer="Gelditu erreprodukzio bufferra" Basic.Main.StoppingReplayBuffer="Erreprodukzio bufferra gelditzen..." @@ -502,6 +514,7 @@ Basic.MainMenu.View.Toolbars="&Tresna barrak" Basic.MainMenu.View.Docks="Leiho moldagarriak" Basic.MainMenu.View.Docks.ResetUI="Berrabiarazi erabiltzaile-interfazea" Basic.MainMenu.View.Docks.LockUI="Blokeatu erabiltzaile-interfazea" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Nabigatzailearen atrake pertsonalizatuak..." Basic.MainMenu.View.Toolbars.Listboxes="Zerrenda-kutxak (&L)" Basic.MainMenu.View.SceneTransitions="Eszenen trantsizioak (&C)" Basic.MainMenu.View.StatusBar="Egoera-barra (&S)" @@ -542,8 +555,9 @@ Basic.Settings.General.Theme="Gaia" Basic.Settings.General.Language="Hizkuntza" Basic.Settings.General.EnableAutoUpdates="Abiaraztean begiratu automatikoki eguneraketarik ba ote dagoen" Basic.Settings.General.OpenStatsOnStartup="Ireki estatistikak abiatzean" -Basic.Settings.General.WarnBeforeStartingStream="Erakutsi baieztapen elkarrizketa transmisioak hasterakoan" -Basic.Settings.General.WarnBeforeStoppingStream="Erakutsi baieztapen elkarrizketa transmisioak gelditzerakoan" +Basic.Settings.General.WarnBeforeStartingStream="Erakutsi berrespen elkarrizketa transmisioak hasterakoan" +Basic.Settings.General.WarnBeforeStoppingStream="Erakutsi berrespen elkarrizketa transmisioak gelditzerakoan" +Basic.Settings.General.WarnBeforeStoppingRecord="Erakutsi berrespen elkarrizketa grabazioa gelditzerakoan" Basic.Settings.General.Projectors="Proiektoreak" Basic.Settings.General.HideProjectorCursor="Ezkutatu kurtsorea proiekzioetan" Basic.Settings.General.ProjectorAlwaysOnTop="Proiektoreak beti gainean" @@ -591,12 +605,14 @@ Basic.Settings.Output.Encoder="Kodetzailea" Basic.Settings.Output.SelectDirectory="Hautatu grabazioaren karpeta" Basic.Settings.Output.SelectFile="Hautatu grabazioaren fitxategia" Basic.Settings.Output.EnforceBitrate="Behartu transmisio zerbitzuaren bit-tasaren mugak" +Basic.Settings.Output.DynamicBitrate="Aldatu bit-emaria dinamikoki pilaketa kudeatzeko" +Basic.Settings.Output.DynamicBitrate.Beta="Aldatu bit-emaria dinamikoki pilaketa kudeatzeko (Beta)" Basic.Settings.Output.Mode="Irteera-modua" Basic.Settings.Output.Mode.Simple="Sinplea" Basic.Settings.Output.Mode.Adv="Aurreratua" Basic.Settings.Output.Mode.FFmpeg="FFmpeg irteera" Basic.Settings.Output.UseReplayBuffer="Gaitu erreprodukzio bufferra" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Erreprodukzioaren gehienezko denbora (segundotan)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Erantzuteko gehienezko epea" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Gehienezko memoria (megabytetan)" Basic.Settings.Output.ReplayBuffer.Estimate="Ustezko memoria erabilera: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Ezin da kalkulatu memoria erabilera. Ezarri gehienezko memoria." @@ -611,6 +627,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Bereizigabeko kalitatea. Fitxa Basic.Settings.Output.Simple.RecordingQuality.Lossless="Galerarik gabeko kalitatea. Fitxategi-tamaina izugarri handia" Basic.Settings.Output.Simple.Warn.VideoBitrate="Kontuz: transmisioaren bideoaren bit-tasa %1 ean ezarriko da; hau izango da oraingo transmisio zerbitzuaren goiko muga. Seguru bazaude %1 aren gainetik nahi duzula, gaitu kodetze aukera aurreratuak eta desautatu \"Behartu transmisio zerbitzuaren bit-tasaren mugak\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Kontuz: transmisioaren audioaren bit-tasa %1 ean ezarriko da; hau izango da oraingo transmisio zerbitzuaren goiko muga. Seguru bazaude %1 aren gainetik nahi duzula, gaitu kodetze aukera aurreratuak eta desautatu \"Behartu transmisio zerbitzuaren bit-tasaren mugak\"." +Basic.Settings.Output.Simple.Warn.CannotPause="Kontuz: Grabazioa ezin da pausatu grabazioaren kalitatearen konfigurazioa \"jarioaren berdina\" bada." Basic.Settings.Output.Simple.Warn.Encoder="Oharra: Transmisioak duen kalitatea ez bestelako kalitate batez grabatzeak PUZ-ren aparteko erabilera eskatzen du une berean transmititzen eta grabatzen baduzu." Basic.Settings.Output.Simple.Warn.Lossless="Oharra: Galerarik gabeko kalitateak neurri izugarri handiko fitxategiak sortzen ditu! Galerarik gabeko kalitateak minutuko 7 gigabytetik gorako tokia erabili dezake diskoan bereizmen eta fotograma-emari handietan. Galerarik gabeko kalitatea ez dago gomendatua grabazio luzeetarako disko toki eskuragarri oso handi bat ez baduzu." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Ziur zaude galerarik gabeko kalitatea erabili nahi duzula?" @@ -623,7 +640,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softwarea (x264 PUZ erabilp Basic.Settings.Output.VideoBitrate="Bideo bit-emaria" Basic.Settings.Output.AudioBitrate="Audio bit-emaria" Basic.Settings.Output.Reconnect="Automatikoki birkonektatu" -Basic.Settings.Output.RetryDelay="Saiakera-atzerapena (segundoak)" +Basic.Settings.Output.RetryDelay="Berriro saiatzeko atzerapena" Basic.Settings.Output.MaxRetries="Gehienezko saiakerak" Basic.Settings.Output.Advanced="Gaitu Kodetzaile aurreratuaren ezarpenak" Basic.Settings.Output.EncoderPreset="Aurrez ezarritako kodetzea" @@ -694,7 +711,8 @@ Basic.Settings.Video.DisableAero="Ezgaitu Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilineala (Azkarrena, baina lausoa eskalatuz gero)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bikubikoa (enfokatutako eskalatzea, 16 lagin)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (eskalatze zorrotza, 32 lagin)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (eskalatze zorrotza, 36 lagin)" +Basic.Settings.Video.DownscaleFilter.Area="Area (Batura ponderatua, 4/6/9 lagin)" Basic.Settings.Audio="Audioa" Basic.Settings.Audio.SampleRate="Lagin-maiztasuna" @@ -708,7 +726,7 @@ Basic.Settings.Audio.PeakMeterType="Gailurren neurgailu mota" Basic.Settings.Audio.PeakMeterType.SamplePeak="Lagin-gailurra" Basic.Settings.Audio.PeakMeterType.TruePeak="Benetako gailurra (CPUaren erabilera handiagoa)" Basic.Settings.Audio.MultiChannelWarning.Enabled="Kontu: soinu inguratzailea aktibatuta dago." -Basic.Settings.Audio.MultichannelWarning="Transmititzen ari bazara, begiratu ea zure transmisio zerbitzuak onartzen duen soinu inguratzailea sarrerako soinuan zein irteerakoan. Twitch, Facebook 360 LIve, Mixer RTMP, Samashcast esate baterako guztiz onartzen dute soinu inguratzailea. Facebook Live eta Youtube Live sarrerako soinu inguratzailea onartzen badute ere, Facebook Livek estereo bihurtzen du, eta Youtube Livek bakarrik bi kanal erreproduzitzen ditu.\n\nOBS audio iragazkiak soinu inguratzailearekin bateragarriak badira ere, ezin da bermatu VST pluginaren bateragarritasuna." +Basic.Settings.Audio.MultichannelWarning="Transmititzen ari bazara, begiratu ea zure transmisio zerbitzuak onartzen duen soinu inguratzailea sarrerako soinuan zein irteerakoan. Facebook 360 LIve, Mixer RTMP, Samashcast esate baterako guztiz onartzen dute soinu inguratzailea. Facebook Live eta Youtube Live sarrerako soinu inguratzailea onartzen badute ere, Facebook Livek estereo bihurtzen du, eta Youtube Livek bakarrik bi kanal erreproduzitzen ditu.\n\nOBS audio iragazkiak soinu inguratzailearekin bateragarriak badira ere, ezin da bermatu VST pluginaren bateragarritasuna." Basic.Settings.Audio.MultichannelWarning.Title="Nahi duzu soinu inguratzailea aktibatzea?" Basic.Settings.Audio.MultichannelWarning.Confirm="Seguru zaude soinu inguratzailea aktibatu nahi duzula?" Basic.Settings.Audio.Devices="Gailuak" @@ -743,23 +761,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Monitorizazio gailua" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Lehenetsia" Basic.Settings.Advanced.Audio.DisableAudioDucking="Ezgaitu Windows audio ducking" Basic.Settings.Advanced.StreamDelay="Transmisio-atzerapena" -Basic.Settings.Advanced.StreamDelay.Duration="Iraupena (segundoak)" +Basic.Settings.Advanced.StreamDelay.Duration="Iraupena" Basic.Settings.Advanced.StreamDelay.Preserve="Mantendu ebaketa puntua (handitu atzerapena) birkonektatzean" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Estimatutako memoria erabilpena: %1 MB" Basic.Settings.Advanced.Network="Sarea" Basic.Settings.Advanced.Network.BindToIP="IP bidez lotu" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Gaitu sare kode berria" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Latentzia txikiko modua" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Laster tekletan fokuratutako portaera" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Ez desaktibatu laster-teklak inoiz" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Ezgaitu laster-teklak leiho nagusia fokuan dagoenean" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Desaktibatu laster-teklak leiho nagusia fokuan ez dagoenean" Basic.Settings.Advanced.AutoRemux="Bihurtu automatikoki mp4-ra" Basic.Settings.Advanced.AutoRemux.MP4="(grabatu mkv bezala)" Basic.AdvAudio="Audio propietate aurreratuak" Basic.AdvAudio.Name="Izena" Basic.AdvAudio.Volume="Bolumena" -Basic.AdvAudio.Mono="Nahasketa monora murriztu" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Balantzea" -Basic.AdvAudio.SyncOffset="Sinkronizazioaren desplazamendua (ms)" +Basic.AdvAudio.SyncOffset="Sinkronizazioaren desplazamendua" Basic.AdvAudio.Monitoring="Adioaren monitorizazioa" Basic.AdvAudio.Monitoring.None="Ez monitorizatu" Basic.AdvAudio.Monitoring.MonitorOnly="Monitorea bakarrik (irteera mututua)" @@ -825,6 +846,7 @@ SceneItemHide="Ezkutatu '%1'" OutputWarnings.NoTracksSelected="Gutxienez pista bat hautatu behar duzu" OutputWarnings.MultiTrackRecording="Oharra: Zenbait formatuk (esaterako FLV-k) ez ditu pista anitzak onartzen grabazioan" OutputWarnings.MP4Recording="Kontuz: MP4 formatuz gordetako grabazioak izan daitezke berreskuraezinak fitxategia ezin bada bukatu (esate baterako BSODs-ren emaitza bat, energia etenak eta abar). Hainbat audio pista grabatu nahi baduzu erabil dezakezu MKV formatua eta mp4 bihurtu grabazioa bukatu ondoren (Fitxategia->Bihurtu grabazioak)" +OutputWarnings.CannotPause="Kontuz: Grabazioak ezin dira pausatu grabazioaren kodetzailea \"(Erabili transmisioaren kodetzailea)\" konfigurazioa badu" FinalScene.Title="Ezabatu eszena" FinalScene.Text="Gutxienez eszena bat egon behar du." diff --git a/UI/data/locale/fa-IR.ini b/UI/data/locale/fa-IR.ini index 210ddaf..3d41b91 100644 --- a/UI/data/locale/fa-IR.ini +++ b/UI/data/locale/fa-IR.ini @@ -23,7 +23,7 @@ Settings="تنظیمات" Display="صفحه نمایش" Name="نام" Exit="خروج" -Mixer="میکسر" +Mixer="میکسرِسدا" Browse="تغییر" Mono="مونو" Stereo="استریو" @@ -61,10 +61,13 @@ Hours="ساعت" Minutes="دقیقه" Seconds="ثانیه" Deprecated="منسوخ شده" +ReplayBuffer="بازپخشِ فوری" Import="وارد کردن" Export="خروجی گرفتن" Copy="کپی" Paste="جای گذاری" +PasteReference="چسبا (مرجع)" +PasteDuplicate="چسبا (تکرار)" Next="بعدی" Back="قبلی" Defaults="پیش فرض ها" @@ -81,6 +84,7 @@ AlreadyRunning.Text="OBS از قبل در حال اجراست! در صورتی AlreadyRunning.LaunchAnyway="در هر حال اجرا کن" + Auth.Chat="چت" Auth.StreamInfo="اطلاعات پخش زنده" TwitchAuth.Stats="وضعیت توییچ" @@ -162,6 +166,7 @@ ConfirmStop.Title="قطع استریم؟" ConfirmStop.Text="آیا مطمئنید که می‌خواهید استریم را قطع کنید؟" + ConfirmExit.Title="خروج از OBS؟" ConfirmExit.Text="OBS در حال حاظر فعال است. تمامی استریم/ضبط ها قطع خاموش خواهند شد. آیا مطمئنید که می‌خواهید خارج شوید؟" diff --git a/UI/data/locale/fi-FI.ini b/UI/data/locale/fi-FI.ini index 5e2d700..9ada516 100644 --- a/UI/data/locale/fi-FI.ini +++ b/UI/data/locale/fi-FI.ini @@ -23,7 +23,7 @@ Settings="Asetukset" Display="Monitori" Name="Nimi" Exit="Poistu" -Mixer="Mikseri" +Mixer="Äänimikseri" Browse="Selaa" Mono="Mono" Stereo="Stereo" @@ -91,6 +91,7 @@ AlreadyRunning.LaunchAnyway="Käynnistä joka tapauksessa" DockCloseWarning.Title="Telakoitu ikkuna suljettu" DockCloseWarning.Text="Suljit juuri telakoidun ikkunan. Jos haluat sen takaisin näkyviin, löydät sen Näkymät → Telakat -valikosta työkaluriviltä." + Auth.Authing.Title="Todennetaan..." Auth.Authing.Text="Todennetaan %1, ole hyvä ja odota..." Auth.AuthFailure.Title="Varmennusvirhe" @@ -105,6 +106,8 @@ Auth.Chat="Chat" Auth.StreamInfo="Lähetyksen tiedot" TwitchAuth.Stats="Twitch-tilastot" TwitchAuth.Feed="Twitch tapahtumasyöte" +TwitchAuth.TwoFactorFail.Title="Striimiavainta ei saatu noudettua" +TwitchAuth.TwoFactorFail.Text="OBS ei pystynyt yhdistämään Twitch-tiliin. Varmista että kaksivaiheinen tunnistus on käytössä Twitchin turvallisuusasetuksissa, koska se vaaditaan lähetystä varten." Copy.Filters="Kopioi suodattimet" Paste.Filters="Liitä suodattimet" @@ -137,7 +140,6 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Joko 60 tai 30, mutta suositaan su Basic.AutoConfig.VideoPage.CanvasExplanation="Huomautus: Piirtoalueen resoluutio ei välttämättä ole sama kuin resoluutio jolla lähetetään tai tallennetaan. Lähetyksen/tallennuksen resoluutio saatetaan skaalata piirtoalueesta pienemmäksi resurssien käytön vähentämiseksi tai bitrate vaatimusten vuoksi." Basic.AutoConfig.StreamPage="Lähetyksen tiedot" Basic.AutoConfig.StreamPage.SubTitle="Ole hyvä ja syötä lähetyksen tiedot" -Basic.AutoConfig.StreamPage.ConnectAccount="Yhdistä tili (valinnainen)" Basic.AutoConfig.StreamPage.DisconnectAccount="Katkaise yhteys tiliin" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Katkaise yhteys tiliin?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Tämä muutos tulee voimaan välittömästi. Oletko varma että haluat katkaista yhteyden tiliin?" @@ -238,6 +240,7 @@ ConfirmStart.Text="Haluatko varmasti aloittaa lähetyksen?" ConfirmStop.Title="Pysäytä lähetys?" ConfirmStop.Text="Haluatko varmasti pysäyttää lähetyksen?" + ConfirmBWTest.Title="Aloita kaistan nopeustesti?" ConfirmBWTest.Text="OBS on asetettu kaistan nopeustestitilaan. Tämä tila antaa sinun testata verkkoa ilman että kanava menee Live-tilaan. Kun olet valmis testauksen kanssa, sinun täytyy ottaa se pois käytöstä, jotta muut voivat nähdä lähetyksesi.\n\nHaluatko jatkaa?" @@ -253,6 +256,8 @@ Output.StartRecordingFailed="Tallennuksen aloittaminen epäonnistui" Output.StartReplayFailed="Toistopuskurin käynnistäminen epäonnistui" Output.StartFailedGeneric="Ulostulon käynnistäminen epäonnistui. Tarkista loki lisätietoja varten.\n\nHuomio: Jos käytät NVENC tai AMD -enkoodereita, varmista, että näytönohjaimen ajurit on päivitetty ajantasalle." +Output.ReplayBuffer.PauseWarning.Title="Uusintoja ei voi tallentaa pysäytettynä" +Output.ReplayBuffer.PauseWarning.Text="Varoitus: Uusintoja ei voi tallentaa kun tallennus on pysäytetty." Output.ConnectFail.Title="Yhdistäminen epäonnistui" Output.ConnectFail.BadPath="Viallinen polku tai yhteysosoite. Tarkista, että asetuksesi ovat kunnossa." @@ -261,6 +266,8 @@ Output.ConnectFail.InvalidStream="Kanavaa tai lähetysavainta ei voida käyttä Output.ConnectFail.Error="Odottamaton virhe ilmeni palvelimeen yhdistäessä. Lisää tietoa saat lokitiedostosta." Output.ConnectFail.Disconnected="Yhteys palvelimeen katkaistiin." +Output.StreamEncodeError.Title="Enkoodausvirhe" +Output.StreamEncodeError.Msg="Lähetyksen aikana tapahtui enkoodausvirhe." Output.RecordFail.Title="Tallennuksen aloittaminen epäonnistui" Output.RecordFail.Unsupported="Ulostulon muoto ei ole tuettu tai se ei tue useampaa kuin yhtä ääniraitaa. Tarkista asetuksesi ja yritä uudelleen." @@ -268,6 +275,7 @@ Output.RecordNoSpace.Title="Liian vähän levytilaa" Output.RecordNoSpace.Msg="Levytilaa ei ole riittävästi tallennuksen jatkamiseen." Output.RecordError.Title="Tallennusvirhe" Output.RecordError.Msg="Tallennuksen aikana tapahtui määrittelemätön virhe." +Output.RecordError.EncodeErrorMsg="Tallennuksen aikana tapahtui enkoodausvirhe." Output.ReplayBuffer.NoHotkey.Title="Pikanäppäintä ei ole asetettu!" Output.ReplayBuffer.NoHotkey.Msg="Tallennuksen pikanäppäintä ei ole asetettu toistopuskurille. Aseta \"Tallenna\"-pikanäppäin tallentaaksesi uusinnat." @@ -439,6 +447,8 @@ Basic.Main.StartRecording="Aloita tallennus" Basic.Main.StartReplayBuffer="Käynnistä toistopuskuri" Basic.Main.StartStreaming="Aloita lähetys" Basic.Main.StopRecording="Pysäytä tallennus" +Basic.Main.PauseRecording="Pysäytä tallennus" +Basic.Main.UnpauseRecording="Jatka tallennusta" Basic.Main.StoppingRecording="Pysäytetään tallennusta..." Basic.Main.StopReplayBuffer="Pysäytä toistopuskuri" Basic.Main.StoppingReplayBuffer="Pysäytetään toistopuskuri..." @@ -591,7 +601,6 @@ Basic.Settings.Output.Mode.Simple="Yksinkertainen" Basic.Settings.Output.Mode.Adv="Kehittynyt" Basic.Settings.Output.Mode.FFmpeg="FFmpeg ulostulo" Basic.Settings.Output.UseReplayBuffer="Ota toistopuskuri käyttöön" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Uusinnan pisin aika (Sekunteina)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Muistiraja (Megatavuja)" Basic.Settings.Output.ReplayBuffer.Estimate="Arvioitu muistinkäyttö: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Muistin käyttöä ei voida arvioida. Valitse muistiraja." @@ -606,6 +615,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Erottamaton laatu, suuri tiedo Basic.Settings.Output.Simple.RecordingQuality.Lossless="Häviötön laatu, valtava tiedostokoko" Basic.Settings.Output.Simple.Warn.VideoBitrate="Varoitus: Kuvan bitrate asetetaan arvoon %1, joka on yläraja valitsemassasi palvelussa. Jos haluat varmasti mennä %1:n yli, poista valinta lisäasetuksista kohdasta \"Rajoita bitrate lähetyspalvelun suosituksiin\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Varoitus: Äänen bitrate asetetaan arvoon %1, joka on yläraja valitsemassasi palvelussa. Jos haluat varmasti mennä %1:n yli, poista valinta lisäasetuksista kohdasta \"Rajoita bitrate lähetyspalvelun suosituksiin\"." +Basic.Settings.Output.Simple.Warn.CannotPause="Varoitus: Tallennusta ei voi pysäyttää jos laatu on asetettu \"Sama kuin lähetyksessä\"." Basic.Settings.Output.Simple.Warn.Encoder="Varoitus: Tallentaminen lähetyksestä eroavalla laadulla vaatii prosessorilta lisätyötä jos lähetät ja tallennat samanaikaisesti." Basic.Settings.Output.Simple.Warn.Lossless="Varoitus: Häviötön laatu luo järjettömän kokoisia tiedostoja! Häviötön laatu saattaa käyttää jopa 7 gigatavua levytilastasi minuutissa, mikäli käytät suuria resoluutioita ja korkeita FPS-arvoja. Häviötöntä pakkausta ei suositella pitkiin tallennuksiin ellei sinulla ole todella paljon tallennustilaa käytettävissäsi." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Haluatko varmasti käyttää häviötöntä laatua?" @@ -618,7 +628,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Ohjelmistopohjainen (x264 m Basic.Settings.Output.VideoBitrate="Kuvan bitrate" Basic.Settings.Output.AudioBitrate="Äänen bitrate" Basic.Settings.Output.Reconnect="Automaattinen uudelleenyhdistys" -Basic.Settings.Output.RetryDelay="Uudelleenyrityksen viive (sekunteja)" Basic.Settings.Output.MaxRetries="Uudelleenyhdistyksien määrä" Basic.Settings.Output.Advanced="Käytä enkooderin lisäasetuksia" Basic.Settings.Output.EncoderPreset="Enkooderin esiasetus" @@ -689,7 +698,7 @@ Basic.Settings.Video.DisableAero="Poista Aero käytöstä" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (nopein, mutta epätarkka skaalattaessa)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (Terävöity skaalaus, 16 näytettä)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Terävöity skaalaus, 32 näytettä)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Terävöity skaalaus, 36 näytettä)" Basic.Settings.Audio="Ääni" Basic.Settings.Audio.SampleRate="Näytteenottotaajuus" @@ -703,7 +712,7 @@ Basic.Settings.Audio.PeakMeterType="Huippuarvo-mittarin tyyppi" Basic.Settings.Audio.PeakMeterType.SamplePeak="Huippuarvon näyte" Basic.Settings.Audio.PeakMeterType.TruePeak="Todellinen huippuarvo (Korkeampi CPU:n käyttö)" Basic.Settings.Audio.MultiChannelWarning.Enabled="VAROITUS: Monikanavaääni on käytössä." -Basic.Settings.Audio.MultichannelWarning="Varmista lähettäessä että palvelu tukee sekä monikanavaäänen lähettämistä, että toistamista. Twitch, Facebook 360 Live, Mixer RTMP ja Smashcast ovat esimerkkejä palveluista joissa monikanavaääni on täysin tuettu. Vaikka Facebook Live ja YouTube Live hyväksyvät monikanavaäänen lähettämisen, Facebook Live miksaa äänen stereoksi ja YouTube Live toistaa vain kaksi kanavaa.\n\nOBS:n äänisuodattimet tukevat monikanavaääntä, mutta VST-liitännäiset eivät välttämättä tue." +Basic.Settings.Audio.MultichannelWarning="Varmista lähettäessä että palvelu tukee sekä monikanavaäänen lähettämistä, että toistamista. Facebook 360 Live, Mixer RTMP ja Smashcast ovat esimerkkejä palveluista joissa monikanavaääni on täysin tuettu. Vaikka Facebook Live ja YouTube Live hyväksyvät monikanavaäänen lähettämisen, Facebook Live miksaa äänen stereoksi ja YouTube Live toistaa vain kaksi kanavaa.\n\nOBS:n äänisuodattimet tukevat monikanavaääntä, mutta VST-liitännäiset eivät välttämättä tue." Basic.Settings.Audio.MultichannelWarning.Title="Käytä monikanava-ääntä?" Basic.Settings.Audio.MultichannelWarning.Confirm="Haluatko varmasti käyttää monikanavaista ääntä?" Basic.Settings.Audio.Devices="Laitteet" @@ -738,7 +747,6 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Äänen monitorointilaite" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Oletusarvo" Basic.Settings.Advanced.Audio.DisableAudioDucking="Poista Windowsin äänien hiljennys käytöstä (Audio Ducking)" Basic.Settings.Advanced.StreamDelay="Lähetyksen viive" -Basic.Settings.Advanced.StreamDelay.Duration="Kesto (sekunteina)" Basic.Settings.Advanced.StreamDelay.Preserve="Säilytä katkaisupiste (lisää viivettä) uudelleenyhdistettäessä" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Arvioitu muistinkäyttö: %1 MB" Basic.Settings.Advanced.Network="Verkko" @@ -751,9 +759,8 @@ Basic.Settings.Advanced.AutoRemux.MP4="(tallenna mkv-muotoon)" Basic.AdvAudio="Äänen lisäominaisuudet" Basic.AdvAudio.Name="Nimi" -Basic.AdvAudio.Mono="Miksaa yksikanavaiseksi" +Basic.AdvAudio.Volume="Äänenvoimakkuus" Basic.AdvAudio.Balance="Balanssi" -Basic.AdvAudio.SyncOffset="Synkronoinnin viivästys (ms)" Basic.AdvAudio.Monitoring="Äänen monitorointi" Basic.AdvAudio.Monitoring.None="Monitorointi pois" Basic.AdvAudio.Monitoring.MonitorOnly="Vain monitorointi (hiljennä ulostulo)" @@ -819,6 +826,7 @@ SceneItemHide="Piilota '%1'" OutputWarnings.NoTracksSelected="Sinun täytyy valita ainakin yksi raita" OutputWarnings.MultiTrackRecording="Varoitus: Jotkin muodot (kuten FLV), eivät tue useampaa raitaa per tallennus" OutputWarnings.MP4Recording="Varoitus: MP4/MOV-muotoon tallentaessa tiedostoista tulee lukukelvottomia, mikäli niitä ei voi viimeistellä. (esim. johtuen BSOD:sta, sähkökatkosta jne.) Jos haluat tallentaa useampaa ääniraitaa, kannattaa käyttää MKV-muotoa ja muuntaa jälkikäteen MP4/MOV-muotoon. (Tiedosto → Muunna tallenteita)" +OutputWarnings.CannotPause="Varoitus: Tallennusta ei voi pysäyttää jos tallennusenkooderi on asetettu \"(Käytä lähetysenkooderia)\"" FinalScene.Title="Poista skene" FinalScene.Text="Ainakin yksi skene pitää olla olemassa." @@ -845,4 +853,5 @@ ResizeOutputSizeOfSource="Muuta ulostulon kokoa (lähteen kokoon)" ResizeOutputSizeOfSource.Text="Piirtoalueen ja ulostulon resoluutio muutetaan valitun lähteen kokoiseksi." ResizeOutputSizeOfSource.Continue="Haluatko jatkaa?" +PreviewTransition="Esikatsele siirtymä" diff --git a/UI/data/locale/fil-PH.ini b/UI/data/locale/fil-PH.ini index e71fbe5..69e4439 100644 --- a/UI/data/locale/fil-PH.ini +++ b/UI/data/locale/fil-PH.ini @@ -21,7 +21,6 @@ Settings="Mga pagtatakda" Display="Ipamalas" Name="Pangalan" Exit="Labasan" -Mixer="Panghalo" Browse="Supling" Mono="Mono" Stereo="Stereo" @@ -85,6 +84,7 @@ AlreadyRunning.LaunchAnyway="Maglunsad parin" + Copy.Filters="Kopyahin ang mga panala" Paste.Filters="I-paste ang mga panala" @@ -205,6 +205,7 @@ ConfirmStop.Title="Itigil ba ang Steam?" ConfirmStop.Text="Sigurado ka itigil ang pag i-stream?" + ConfirmExit.Title="Lumabas sa OBS?" ConfirmExit.Text="Ang OBS ay kasulukuyang aktibo. Lahat ng streams/recordings ay magsasara. Sigurado ka ba gusto mong mag exit?" @@ -520,7 +521,6 @@ Basic.Settings.Output.Mode.Simple="Simple" Basic.Settings.Output.Mode.Adv="Pagsulong" Basic.Settings.Output.Mode.FFmpeg="FFmpeg Awput" Basic.Settings.Output.UseReplayBuffer="Simulan ang pag replay ng buffer" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Pinakamataas na oras ng replay (segundos)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Pinakamataas na memorya (Megabytes)" Basic.Settings.Output.ReplayBuffer.Estimate="Ang na estimang nagamit na memorya: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Hindi ma-estima ang nagamit na memorya. Pakilagay ng pinakamataas na limitasyon ng memorya." @@ -547,7 +547,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 mababang pre Basic.Settings.Output.VideoBitrate="Bitrate ng Video" Basic.Settings.Output.AudioBitrate="Bitrate ng Audio" Basic.Settings.Output.Reconnect="Awtomatikong mag-reconnect" -Basic.Settings.Output.RetryDelay="Retry Delay (segundo)" Basic.Settings.Output.MaxRetries="Pinakamataas na Retries" Basic.Settings.Output.Advanced="Paganahin ang Mga Setting ng Advanced Encoder" Basic.Settings.Output.CustomEncoderSettings="Mga Setting ng Custom Encoder" @@ -617,7 +616,7 @@ Basic.Settings.Video.DisableAero="Hindi paganahin ang Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (Pinakamabilis, pero malabo pag mag i-scaling)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (Sharpened scaling, 16 mga halimbawa)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Sharpened scaling, 32 mga halimbawa)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Sharpened scaling, 36 mga halimbawa)" Basic.Settings.Audio="Tunog" Basic.Settings.Audio.SampleRate="Halimbawa ng Antas" @@ -626,7 +625,7 @@ Basic.Settings.Audio.MeterDecayRate.Fast="Pabilisin" Basic.Settings.Audio.MeterDecayRate.Medium="Katamtaman (Tipo I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Mabagal (Tipo II PPM)" Basic.Settings.Audio.MultiChannelWarning.Enabled="Babala: Ang Surround sound audio ay naka andar." -Basic.Settings.Audio.MultichannelWarning="Kung nag streaming, paki tignan kung ang iyong streaming service ay parehong supportado ang surround sound ingest at surround sound playback. Twitch, Facebook, 360 Live, Mixer RTMP, Smashcast ay ang mga halimbawa kung saan ang surround sound ay ganap na suportado, pati YouTube Live umaandar lamang sa dawalang channels.\n\nOBS audio filters ay kompatibol lamang sa surround sound, pero hindi siguradong supportado ang VST plugin." +Basic.Settings.Audio.MultichannelWarning="Kung nag streaming, paki tignan kung ang iyong streaming service ay parehong supportado ang surround sound ingest at surround sound playback. Facebook, 360 Live, Mixer RTMP, Smashcast ay ang mga halimbawa kung saan ang surround sound ay ganap na suportado, pati YouTube Live umaandar lamang sa dawalang channels.\n\nOBS audio filters ay kompatibol lamang sa surround sound, pero hindi siguradong supportado ang VST plugin." Basic.Settings.Audio.MultichannelWarning.Title="Paganahin ang surround sound audio?" Basic.Settings.Audio.MultichannelWarning.Confirm="Sigurado ka ba gusto mong paganahin ang surround sound audio?" Basic.Settings.Audio.EnablePushToMute="Paganahin ang Push-to-mute" @@ -650,7 +649,6 @@ Basic.Settings.Advanced.Video.ColorRange.Full="Buo" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="I-Default" Basic.Settings.Advanced.Audio.DisableAudioDucking="Huwag paganahin ang Windows audio ducking" Basic.Settings.Advanced.StreamDelay="Ang Antala ng Stream" -Basic.Settings.Advanced.StreamDelay.Duration="Ang Katagalan (segundo)" Basic.Settings.Advanced.StreamDelay.Preserve="Ingatang ang cutoff point (pataas ng antala) kapang kumokonekta" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Ang na estimang nagamit na memorya: %1 MB" Basic.Settings.Advanced.Network="Network" @@ -660,8 +658,6 @@ Basic.Settings.Advanced.Network.EnableLowLatencyMode="Mababang latency mode" Basic.AdvAudio="Ang aria-arian ng Advanced Audio" Basic.AdvAudio.Name="Pangalan" -Basic.AdvAudio.Mono="Downmix ito sa Mono" -Basic.AdvAudio.SyncOffset="Ang Sync Offset (ms)" Basic.AdvAudio.Monitoring="Ang subaybay ng Audio" Basic.AdvAudio.Monitoring.None="I-Off ang Monitor" Basic.AdvAudio.Monitoring.MonitorOnly="Monitor lamang (i-mute ang output)" diff --git a/UI/data/locale/fr-FR.ini b/UI/data/locale/fr-FR.ini index 74dce7b..7947bb3 100644 --- a/UI/data/locale/fr-FR.ini +++ b/UI/data/locale/fr-FR.ini @@ -20,10 +20,10 @@ Properties="Propriétés" MoveUp="Déplacer vers le haut" MoveDown="Déplacer vers le bas" Settings="Paramètres" -Display="Affichage" +Display="Moniteur" Name="Nom" Exit="Quitter OBS" -Mixer="Mixeur audio" +Mixer="Mélangeur audio" Browse="Parcourir" Mono="Mono" Stereo="Stéréo" @@ -91,6 +91,10 @@ AlreadyRunning.LaunchAnyway="Démarrer tout de même" DockCloseWarning.Title="Fermer une fenêtre dockable" DockCloseWarning.Text="Vous venez de fermer une fenêtre dockable. Si vous souhaitez l'afficher à nouveau, utilisez le menu Afficher → Docks dans la barre de menus." +ExtraBrowsers="Docks Internet personnalisés" +ExtraBrowsers.Info="Ajoutez des docks en leur donnant un nom et une URL, puis cliquez sur Appliquer or Fermer pour les ouvrir. Vous pouvez en ajouter d'autres ou en supprimer plus tard à votre guise." +ExtraBrowsers.DockName="Nom du dock" + Auth.Authing.Title="Connexion en cours ..." Auth.Authing.Text="Connexion sur %1 en cours, veuillez patienter ..." Auth.AuthFailure.Title="Échec d'authentification" @@ -107,6 +111,7 @@ TwitchAuth.Stats="Statistiques de Twitch" TwitchAuth.Feed="Flux d'activité Twitch" TwitchAuth.TwoFactorFail.Title="Impossible de trouver la clé de stream" TwitchAuth.TwoFactorFail.Text="OBS n'a pas pu se connecter à votre compte Twitch. Veuillez vous assurer que l'authentification à deux facteurs est configurée dans vos paramètres de sécurité Twitch car cela est nécessaire pour lancer un stream." +RestreamAuth.Channels="Chaînes Restream" Copy.Filters="Copier les filtres" Paste.Filters="Coller les filtres" @@ -139,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 ou 30, mais favoriser une réso Basic.AutoConfig.VideoPage.CanvasExplanation="Remarque : la résolution (de base) du canevas n'est pas nécessairement la même que la résolution avec laquelle vous allez diffuser (stream) ou enregistrer. La résolution actuelle de stream/enregistrement peut être réduite à partir de la résolution du canevas afin de diminuer l'utilisation des ressources et de la bande passante." Basic.AutoConfig.StreamPage="Informations de flux" Basic.AutoConfig.StreamPage.SubTitle="Entrez vos informations de stream" -Basic.AutoConfig.StreamPage.ConnectAccount="Connecter un compte (optionnel)" +Basic.AutoConfig.StreamPage.ConnectAccount="Lier un compte (recommandé)" Basic.AutoConfig.StreamPage.DisconnectAccount="Déconnecter le compte" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Déconnecter le compte ?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Cette modification s'appliquera immédiatement. Êtes-vous sûr de vouloir déconnecter votre compte ?" @@ -240,6 +245,9 @@ ConfirmStart.Text="Êtes-vous sûr de vouloir démarrer le stream ?" ConfirmStop.Title="Arrêter le stream ?" ConfirmStop.Text="Êtes-vous sûr de vouloir arrêter le stream ?" +ConfirmStopRecord.Title="Arrêter l'enregistrement ?" +ConfirmStopRecord.Text="Êtes-vous certain de vouloir arrêter l'enregistrement ?" + ConfirmBWTest.Title="Démarrer le test de bande passante ?" ConfirmBWTest.Text="Vous avez configuré OBS en mode \"test de bande passante\". Ce mode permet de tester le réseau sans que votre chaîne ne soit en direct. Une fois que vous aurez effectué les tests, vous devrez le désactiver afin que les spectateurs puissent voir votre stream.\n\nVoulez-vous continuer ?" @@ -255,6 +263,8 @@ Output.StartRecordingFailed="Impossible de démarrer l'enregistrement" Output.StartReplayFailed="Impossible de démarrer le tampon de relecture" Output.StartFailedGeneric="Le démarrage de la sortie a échoué. Veuillez consulter le journal pour plus de détails.\n\nRemarque : si vous utilisez les encodeurs NVENC ou AMD, assurez-vous que vos pilotes vidéo soient à jour." +Output.ReplayBuffer.PauseWarning.Title="Impossible d'enregistrer des replays quand l'enregistrement est en pause" +Output.ReplayBuffer.PauseWarning.Text="Attention : les replays ne peuvent pas être enregistrés lorsque l'enregistrement est en pause." Output.ConnectFail.Title="Échec de la connexion" Output.ConnectFail.BadPath="Adresse de connexion ou chemin invalide. Veuillez vérifier vos paramètres afin de confirmer leur validité." @@ -444,6 +454,8 @@ Basic.Main.StartRecording="Démarrer l'enregistrement" Basic.Main.StartReplayBuffer="Démarrer le tampon de relecture" Basic.Main.StartStreaming="Commencer le streaming" Basic.Main.StopRecording="Arrêter l'enregistrement" +Basic.Main.PauseRecording="Mettre en pause l'enregistrement" +Basic.Main.UnpauseRecording="Reprendre l'enregistrement" Basic.Main.StoppingRecording="Arrêt de l'enregistrement..." Basic.Main.StopReplayBuffer="Arrêter le tampon de relecture" Basic.Main.StoppingReplayBuffer="Arrêt du tampon de relecture..." @@ -502,6 +514,7 @@ Basic.MainMenu.View.Toolbars="Barres d'ou&tils" Basic.MainMenu.View.Docks="Docks" Basic.MainMenu.View.Docks.ResetUI="Réinitialiser l'Interface" Basic.MainMenu.View.Docks.LockUI="Verrouiller l'Interface" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Docks Internet personnalisés..." Basic.MainMenu.View.Toolbars.Listboxes="&Listes" Basic.MainMenu.View.SceneTransitions="Transition de s&cènes" Basic.MainMenu.View.StatusBar="Barre d'état (&S)" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="Vérifier automatiquement les mises à Basic.Settings.General.OpenStatsOnStartup="Ouvrir la boîte de dialogue des statistiques au démarrage" Basic.Settings.General.WarnBeforeStartingStream="Afficher une boîte de dialogue de confirmation au démarrage d'un stream" Basic.Settings.General.WarnBeforeStoppingStream="Afficher une boîte de dialogue de confirmation à l'arrêt d'un stream" +Basic.Settings.General.WarnBeforeStoppingRecord="Demander confirmation avant d'arrêter un enregistrement" Basic.Settings.General.Projectors="Projecteurs" Basic.Settings.General.HideProjectorCursor="Cacher le curseur sur les projecteurs" Basic.Settings.General.ProjectorAlwaysOnTop="Projecteurs toujours au premier plan" @@ -591,12 +605,15 @@ Basic.Settings.Output.Encoder="Encodeur" Basic.Settings.Output.SelectDirectory="Sélectionnez le répertoire d'enregistrement" Basic.Settings.Output.SelectFile="Sélectionnez le fichier cible" Basic.Settings.Output.EnforceBitrate="Imposer les limites de débit du service de streaming" +Basic.Settings.Output.DynamicBitrate="Ajuster dynamiquement le débit de streaming en cas de congestion réseau" +Basic.Settings.Output.DynamicBitrate.Beta="Ajuster dynamiquement le débit de streaming en cas de congestion réseau (Beta)" +Basic.Settings.Output.DynamicBitrate.TT="Ajuste automatiquement le débit de streaming pour éviter les pertes d'images en cas de congestion ou de surcharge réseau.\n\nCela peut augmenter le délai entre vous et vos spectateurs si la congestion est significative.\nQuand le débit est réduit automatiquement, plusieurs minutes peuvent s'écouler avant qu'il ne revienne à la normale.\n\nN'est supporté que pour RTMP pour l'instant." Basic.Settings.Output.Mode="Mode de Sortie" Basic.Settings.Output.Mode.Simple="Simple" Basic.Settings.Output.Mode.Adv="Avancé" Basic.Settings.Output.Mode.FFmpeg="Sortie FFmpeg" Basic.Settings.Output.UseReplayBuffer="Activer le tampon de relecture" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Temps de relecture maximal (secondes)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Durée maximale d'un replay" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Mémoire maximum (mégaoctets)" Basic.Settings.Output.ReplayBuffer.Estimate="Estimation de la mémoire utilisée : %1 Mo" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Impossible d'estimer l'utilisation de la mémoire. Veuillez définir une limite de mémoire maximale." @@ -611,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Qualité indistinguable, grand Basic.Settings.Output.Simple.RecordingQuality.Lossless="Qualité sans perte, énorme taille de fichier" Basic.Settings.Output.Simple.Warn.VideoBitrate="Attention: le débit vidéo de streaming va être fixé à %1, qui est la limite maximale pour le service de streaming actuel. Si vous êtes surs de vouloir aller au delà de %1, activez les options avancées de l'encodeur & décochez \"Imposer les limites de débit du service de streaming\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Attention: le débit audio de streaming va être fixé à %1, qui est la limite maximale pour le service de streaming actuel. Si vous êtes surs de vouloir aller au delà de %1, activez les options avancées de l'encodeur & décochez \"Imposer les limites de débit du service de streaming\"." +Basic.Settings.Output.Simple.Warn.CannotPause="Attention : l'enregistrement ne peut pas être mis en pause si la qualité d'enregistrement est configurée sur \"Identique au stream\"." Basic.Settings.Output.Simple.Warn.Encoder="Attention : enregistrer via un encodeur logiciel avec une qualité autre que celle du stream sollicitera encore plus le CPU si vous streamez et enregistrez simultanément." Basic.Settings.Output.Simple.Warn.Lossless="Attention: la qualité sans perte génère des fichiers de taille énorme ! Elle peut utiliser jusqu'à 7 gigaoctets d'espace disque par minute pour de hautes résolutions et fréquences d'image. Cette qualité n'est pas recommandée pour de longs enregistrements à moins d'avoir énormément d'espace disque disponible." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Êtes-vous certain de vouloir utiliser la qualité sans perte ?" @@ -623,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Logiciel (pré-réglage x26 Basic.Settings.Output.VideoBitrate="Débit vidéo" Basic.Settings.Output.AudioBitrate="Débit audio" Basic.Settings.Output.Reconnect="Reconnexion automatique" -Basic.Settings.Output.RetryDelay="Délai avant la tentative de reconnexion (en secondes)" +Basic.Settings.Output.RetryDelay="Délai avant nouvelle tentative" Basic.Settings.Output.MaxRetries="Nombres de tentatives maximales" Basic.Settings.Output.Advanced="Activer les paramètres avancés d'encodage" Basic.Settings.Output.EncoderPreset="Pré-réglage d'encodeur" @@ -694,7 +712,8 @@ Basic.Settings.Video.DisableAero="Désactiver Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinéaire (plus rapide, mais flou en cas de mise à l'échelle)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubique (mise à l'échelle avec netteté accentuée, 16 échantillons)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (mise à l'échelle avec netteté accentuée, 32 échantillons)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (mise à l'échelle avec netteté accentuée, 36 échantillons)" +Basic.Settings.Video.DownscaleFilter.Area="Zone (somme pondérée, 4/6/9 échantillons)" Basic.Settings.Audio="Audio" Basic.Settings.Audio.SampleRate="Fréquence d'échantillonnage" @@ -708,7 +727,7 @@ Basic.Settings.Audio.PeakMeterType="Type de crête-mètre" Basic.Settings.Audio.PeakMeterType.SamplePeak="Pic d'échantillon audio" Basic.Settings.Audio.PeakMeterType.TruePeak="Crête exacte (plus grande utilisation du CPU)" Basic.Settings.Audio.MultiChannelWarning.Enabled="ATTENTION : le son multicanal est activé." -Basic.Settings.Audio.MultichannelWarning="Pour de besoins de diffusion, vérifiez que votre service de diffusion supporte l'intégration et la lecture du son multicanal. Twitch, Facebook 360 Live, Mixer RTMP ou Smashcast sont des exemples de services où le son multicanal est entièrement supporté. Bien que Facebook Live et YouTube Live acceptent l'intégration de son multicanal, Facebook Live transcode en stéréo, et YouTube Live ne lit que deux canaux.\n\nLes filtres audio d'OBS sont compatibles avec le son multicanal, toutefois le support des plugins VST n'est pas garanti." +Basic.Settings.Audio.MultichannelWarning="Pour de besoins de diffusion, vérifiez que votre service de diffusion supporte l'intégration et la lecture du son multicanal. Facebook 360 Live, Mixer RTMP ou Smashcast sont des exemples de services où le son multicanal est entièrement supporté. Bien que Facebook Live et YouTube Live acceptent l'intégration de son multicanal, Facebook Live transcode en stéréo, et YouTube Live ne lit que deux canaux.\n\nLes filtres audio d'OBS sont compatibles avec le son multicanal, toutefois le support des plugins VST n'est pas garanti." Basic.Settings.Audio.MultichannelWarning.Title="Activer le son multicanal ?" Basic.Settings.Audio.MultichannelWarning.Confirm="Êtes vous sûr de vouloir activer le son multicanal ?" Basic.Settings.Audio.Devices="Périphériques" @@ -743,23 +762,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Périphérique de Monitoring Aud Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Par défaut" Basic.Settings.Advanced.Audio.DisableAudioDucking="Désactiver l'atténuation audio de Windows (ducking)" Basic.Settings.Advanced.StreamDelay="Retard du stream" -Basic.Settings.Advanced.StreamDelay.Duration="Durée (en secondes)" +Basic.Settings.Advanced.StreamDelay.Duration="Durée" Basic.Settings.Advanced.StreamDelay.Preserve="Préserver le point de coupure (augmente le retard) lors d'une reconnexion" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Utilisation estimée de la mémoire : %1 Mo" Basic.Settings.Advanced.Network="Carte réseau (adresse IP source du flux)" Basic.Settings.Advanced.Network.BindToIP="Lier à :" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Activer le nouveau code réseau" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Mode faible latence" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Comportement selon le focus" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Ne jamais désactiver les raccourcis clavier" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Désactiver les raccourcis clavier lorsque la fenêtre principale est au premier plan" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Désactiver les raccourcis clavier quand la fenêtre principale est en arrière-plan" Basic.Settings.Advanced.AutoRemux="Convertir automatiquement en MP4" Basic.Settings.Advanced.AutoRemux.MP4="(enregistrer en MKV)" Basic.AdvAudio="Propriétés Audio Avancées" Basic.AdvAudio.Name="Nom" Basic.AdvAudio.Volume="Volume" -Basic.AdvAudio.Mono="Convertir en mono" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Balance" -Basic.AdvAudio.SyncOffset="Décalage de la synchronisation (ms)" +Basic.AdvAudio.SyncOffset="Décalage de synchronisation" Basic.AdvAudio.Monitoring="Monitoring Audio" Basic.AdvAudio.Monitoring.None="Monitoring Désactivé" Basic.AdvAudio.Monitoring.MonitorOnly="Monitoring uniquement (couper la sortie)" @@ -825,6 +847,7 @@ SceneItemHide="Cacher '%1'" OutputWarnings.NoTracksSelected="Vous devez sélectionner au moins une piste" OutputWarnings.MultiTrackRecording="Attention : Certains formats (comme FLV) ne supportent pas les pistes multiples pour un même enregistrement" OutputWarnings.MP4Recording="Avertissement : les enregistrements sauvegardés en MP4/MOV seront irrécupérables si le fichier ne peut pas être finalisé (ex. : à cause des BSOD, pannes de l'alimentation, etc...). Si vous voulez enregistrer plusieurs pistes audio, pensez à utiliser le format MKV et à convertir l'enregistrement en MP4/MOV après avoir terminé (Fichier → Convertir un enregistrement)" +OutputWarnings.CannotPause="Attention : l'enregistrement ne peut pas être mis en pause si l'encodeur d'enregistrement est configuré sur \"(Utiliser le même encodeur que pour le stream)\"" FinalScene.Title="Supprimer la scène" FinalScene.Text="Il doit y avoir au moins une scène." diff --git a/UI/data/locale/gd-GB.ini b/UI/data/locale/gd-GB.ini index 301e4e1..76181cf 100644 --- a/UI/data/locale/gd-GB.ini +++ b/UI/data/locale/gd-GB.ini @@ -23,7 +23,6 @@ Settings="Roghainnean" Display="Uidheam-taisbeanaidh" Name="Ainm" Exit="Fàg an-seo" -Mixer="Measgadair" Browse="Rùraich" Mono="Mono" Stereo="Stereo" @@ -89,6 +88,7 @@ AlreadyRunning.LaunchAnyway="Cuir gu dol e co-dhiù" DockCloseWarning.Title="A’ dùnadh uinneag doca" DockCloseWarning.Text="Tha thu air uinneag doca a dhùnadh. Nam gu toigh leat a sealltainn a-rithist, cleachd clàr-taice “Seall” → “Docaichean” air bàr a’ chlàir-thaice." + Auth.Authing.Title="’Gad dhearbhadh…" Auth.Authing.Text="’Gad dhearbhadh le %1, fuirich greiseag…" Auth.AuthFailure.Title="Dh’fhàillig an dearbhadh" @@ -134,7 +134,6 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="An dà chuid 60 no 30 ach b’ fhe Basic.AutoConfig.VideoPage.CanvasExplanation="An aire: Cha bhi dùmhlachd-bhreacaidh bhunasach (a’ chanabhais) co-ionnan ris an dùmhlachd-bhreacaidh a thèid a chlàradh no a shruthadh an-còmhnaidh. Dh’fhaoidte gun dèid an dùmhlachd-bhreacaidh air sruthadh no clàradh ìsleachadh o dhùmhlachd-bhreacaidh a’ chanabhais airson freagairt ri feumalachdan cleachdaidh no reat bhiotaichean." Basic.AutoConfig.StreamPage="Fiosrachadh an t-sruthaidh" Basic.AutoConfig.StreamPage.SubTitle="Cuid a-steach fiosrachadh an t-sruthaidh agad" -Basic.AutoConfig.StreamPage.ConnectAccount="Dèan ceangal ri cunntas (roghainneil)" Basic.AutoConfig.StreamPage.DisconnectAccount="Bris an ceangal ris a’ chunntas" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="A bheil thu airson an ceangal ris a’ chunntas a bhriseadh?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Thèid an t-atharradh seo a chur an sàs sa bhad. A bheil thu cinnteach gu bheil thu airson an ceangal ris a’ chunntas agad a bhriseadh?" @@ -234,6 +233,7 @@ ConfirmStop.Title="A bheil thu airson stad a chur air an t-sruthadh?" ConfirmStop.Text="A bheil thu cinnteach gu bheil thu airson stad a chur air an t-sruthadh?" + ConfirmExit.Title="A bheil thu airson OBS fhàgail?" ConfirmExit.Text="Tha OBS gnìomhach an-dràsta. Thèid gach sruthadh no clàradh a chur gu crìch. A bheil thu cinnteach gu bheil thu airson fhàgail?" @@ -577,7 +577,6 @@ Basic.Settings.Output.Mode.Simple="Simplidh" Basic.Settings.Output.Mode.Adv="Adhartach" Basic.Settings.Output.Mode.FFmpeg="Às-chur FFmpeg" Basic.Settings.Output.UseReplayBuffer="Cuir an comas bufair ath-chluiche" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Ùine as motha nan ath-chluichean (diog)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="A’ chuimhne as motha (meaga-baidht)" Basic.Settings.Output.ReplayBuffer.Estimate="Tuairmse air cleachdadh na cuimhne: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Chan urrainn dhuinn tuairmse a dhèanamh air cleachdadh na cuimhne. Suidhich crìoch as motha na cuimhne." @@ -604,7 +603,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Bathar-bog (ro-shuidheachad Basic.Settings.Output.VideoBitrate="Reat bhiotaichean a’ video" Basic.Settings.Output.AudioBitrate="Reat bhiotaichean na fuaime" Basic.Settings.Output.Reconnect="Ath-cheangail gu fèin-obrachail" -Basic.Settings.Output.RetryDelay="Dàil na feuchainn a-rithist (diog)" Basic.Settings.Output.MaxRetries="Oidhirpean as motha" Basic.Settings.Output.Advanced="Cuir an comas roghainnean adhartach an inneil-chòdachaidh" Basic.Settings.Output.EncoderPreset="Ro-sheata an inneil-chòdachaidh" @@ -675,7 +673,7 @@ Basic.Settings.Video.DisableAero="Cuir à comas Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Dà-loidhneach (as luaithe ach sgleò air le sgèilachadh)" Basic.Settings.Video.DownscaleFilter.Bicubic="Dà-chiùbach (sgèileachadh geuraichte, 16 sampallan)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (sgèileachadh geuraichte, 32 sampall)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (sgèileachadh geuraichte, 36 sampall)" Basic.Settings.Audio="Fuaim" Basic.Settings.Audio.SampleRate="Reat shampallan" @@ -687,7 +685,7 @@ Basic.Settings.Audio.PeakMeterType="Seòrsa a’ mheidheadair-bharran" Basic.Settings.Audio.PeakMeterType.SamplePeak="Ball-sampaill de bharr" Basic.Settings.Audio.PeakMeterType.TruePeak="Barr fìrinneach (cleachdadh nas àirde a’ CPU)" Basic.Settings.Audio.MultiChannelWarning.Enabled="RABHADH: Tha fuaim cuairteachaidh an comas." -Basic.Settings.Audio.MultichannelWarning="Ma tha thu a’ dèanamh sruthadh, dearbh gun doir an t-seirbheis sruthaidh agad taic an dà chuid ri ion-chur is cluich fuaime cuairteachaidh. Mar eisimpleir, cuiridh Twitch, Facebook 360 Live, Mixer RTMP is Smashcast làn-taic ri fuaim cuairteachaidh. Ged a ghabhas Facebook Live is youTube Live ri sruthan fuaime cuairteachaidh, nì Facebook Live measgachadh sìos stereo dheth agus cha chluich YouTube live ach dà sheanail.\n\nTha criathragan fuaime OBS co-chòrdail ri fuaim cuairteachaidh ged nach doir sinn barantas gun obraich plugain VST." +Basic.Settings.Audio.MultichannelWarning="Ma tha thu a’ dèanamh sruthadh, dearbh gun doir an t-seirbheis sruthaidh agad taic an dà chuid ri ion-chur is cluich fuaime cuairteachaidh. Mar eisimpleir, cuiridh Facebook 360 Live, Mixer RTMP is Smashcast làn-taic ri fuaim cuairteachaidh. Ged a ghabhas Facebook Live is youTube Live ri sruthan fuaime cuairteachaidh, nì Facebook Live measgachadh sìos stereo dheth agus cha chluich YouTube live ach dà sheanail.\n\nTha criathragan fuaime OBS co-chòrdail ri fuaim cuairteachaidh ged nach doir sinn barantas gun obraich plugain VST." Basic.Settings.Audio.MultichannelWarning.Title="A bheil thu airson fuaim cuairteachaidh a chur an comas?" Basic.Settings.Audio.MultichannelWarning.Confirm="A bheil thu cinnteach gu bheil thu airson fuaim cuairteachaidh a chur an comas?" Basic.Settings.Audio.EnablePushToMute="Cuir an comas brùth-airson-mùchadh" @@ -712,7 +710,6 @@ Basic.Settings.Advanced.Video.ColorRange.Full="Làn" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Tùsail" Basic.Settings.Advanced.Audio.DisableAudioDucking="Cuir à comas tumadh fuaime Windows" Basic.Settings.Advanced.StreamDelay="Dàil an t-sruthaidh" -Basic.Settings.Advanced.StreamDelay.Duration="Faide (diog)" Basic.Settings.Advanced.StreamDelay.Preserve="Glèidh puing a’ ghearraidh (meudaich an dàil) nuair a nithear ath-cheangal" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Tuairmse air cleachdadh na cuimhne: %1 MB" Basic.Settings.Advanced.Network="Lìonra" @@ -725,9 +722,7 @@ Basic.Settings.Advanced.AutoRemux.MP4="(clàraich mar mkv)" Basic.AdvAudio="Roghainnean adhartach na fuaime" Basic.AdvAudio.Name="Ainm" -Basic.AdvAudio.Mono="Measgaich sìos gu mono" Basic.AdvAudio.Balance="Balans" -Basic.AdvAudio.SyncOffset="Frìth-àireamh an t-sioncronachaidh (ms)" Basic.AdvAudio.Monitoring="Sgrùdadh fuaime" Basic.AdvAudio.Monitoring.None="Gun sgrùdadh" Basic.AdvAudio.Monitoring.MonitorOnly="Sgrùdadh a-mhàin (mùch an t-às-chur)" diff --git a/UI/data/locale/gl-ES.ini b/UI/data/locale/gl-ES.ini index 7792f47..c70584f 100644 --- a/UI/data/locale/gl-ES.ini +++ b/UI/data/locale/gl-ES.ini @@ -7,64 +7,227 @@ Apply="Aplicar" Cancel="Cancelar" Close="Pechar" Save="Gardar" -Discard="Descartar" +Discard="Desbotar" Disable="Desactivar" Yes="Si" No="Non" Add="Engadir" -Remove="Eliminar" +Remove="Retirar" Rename="Renomear" Interact="Interactuar" Filters="Filtros" Properties="Propiedades" -MoveUp="Subir" -MoveDown="Baixar" +MoveUp="Mover cara arriba" +MoveDown="Mover cara abaixo" Settings="Axustes" Display="Pantalla" Name="Nome" Exit="Saír" -Mixer="Mesturador" -Browse="Explorar" +Mixer="Mesturador de son" +Browse="Examinar" Mono="Mono" Stereo="Estéreo" DroppedFrames="Fotogramas perdidos %1 (%2%)" +StudioProgramProjector="Proxector de pantalla completa (programa)" PreviewProjector="Proxector de pantalla completa (vista previa)" SceneProjector="Proxector de pantalla completa (escena)" SourceProjector="Proxector de pantalla completa (fonte)" -Revert="Anular" -Show="Mostrar" +StudioProgramWindow="Proxector de xanelas (programa)" +PreviewWindow="Proxector de xanelas (vista previa)" +SceneWindow="Proxector de xanelas (escena)" +SourceWindow="Proxector de xanelas (fonte)" +MultiviewProjector="Vista múltiple (pantalla completa)" +MultiviewWindowed="Vista múltiple (en xanelas)" +Clear="Limpar" +Revert="Reverter" +Show="Amosar" Hide="Agochar" +UnhideAll="Amosar todo" Untitled="Sen título" New="Novo" Duplicate="Duplicar" Enable="Activar" DisableOSXVSync="Desactivar V-Sync en OSX" +ResetOSXVSyncOnExit="Restablecer V-Sync en OSX ao saír" +HighResourceUsage="Codificación sobrecargada! Considere rexeitar a configuración de vídeo ou usar un preaxuste de codificación máis rápido." Transition="Transición" QuickTransitions="Transicións rápidas" Left="Esquerda" Right="Dereita" Top="Arriba" Bottom="Abaixo" +Reset="Restablecer" +Hours="Horas" +Minutes="Minutos" +Seconds="Segundos" +Deprecated="Obsoleto" +ReplayBuffer="Memoria temporal de reprodución" +Import="Importar" +Export="Exportar" +Copy="Copiar" +Paste="Pegar" +PasteReference="Pegar (referencia)" +PasteDuplicate="Pegar (duplicado)" +RemuxRecordings="Gravacións de conversións" +Next="Seguinte" +Back="Atrás" +Defaults="Predeterminados" +HideMixer="Agochar no mesturador" +TransitionOverride="Substitución da transición" +None="Ningunha" +StudioMode.Preview="Vista previa" +StudioMode.Program="Programa" +ShowInMultiview="Amosar en vista múltiple" +VerticalLayout="Disposición vertical" +Group="Grupo" +DoNotShowAgain="Non volver amosar" +Default="(Predeterminado)" +Calculating="Calculando..." +AlreadyRunning.Title="OBS xa está en execución" +AlreadyRunning.Text="OBS xa está en execución. A non ser que quixese facer isto, apague as instancias existentes de OBS antes de tentar executar unha nova instancia. Se ten OBS configurado para minimizar na bandexa do sistema, comprobe se aínda está en execución alí." +AlreadyRunning.LaunchAnyway="Iniciar de todos os xeitos" +DockCloseWarning.Title="Pechar a xanela ancorábel" +DockCloseWarning.Text="Acaba de pechar unha xanela ancorábel. Se quere amosalo de novo, use o menú Ver → Docas na barra de menú." +ExtraBrowsers="Docas personalizadas do navegador" +ExtraBrowsers.Info="Engada docas dándolles un nome e URL, após prema en Aplicar ou en Pechar para abrir as docas. Pode engadir ou retirar docas en calquera momento." +ExtraBrowsers.DockName="Nome da doca" +Auth.Authing.Title="Autenticando..." +Auth.Authing.Text="Autenticando con %1, agarde..." +Auth.AuthFailure.Title="Produciuse un fallo de autenticación" +Auth.AuthFailure.Text="Produciuse un fallo de autenticación con %1:\n\n%2: %3" +Auth.InvalidScope.Title="É necesaria a autenticación" +Auth.InvalidScope.Text="Cambiaron os requisitos de autenticación para %1. É posíbel que algunhas funcións non estean dispoñíbeis." +Auth.LoadingChannel.Title="Cargando a información da canle..." +Auth.LoadingChannel.Text="Cargando a información da canle para %1, agarde..." +Auth.ChannelFailure.Title="Produciuse un fallo ao cargar a canle" +Auth.ChannelFailure.Text="Produciuse un fallo ao cargar a información da canle para %1\n\n%2: %3" +Auth.Chat="Conversa" +Auth.StreamInfo="Información da emisión" +TwitchAuth.Stats="Estatísticas do Twitch" +TwitchAuth.Feed="Fonte de actividades do Twitch" +TwitchAuth.TwoFactorFail.Title="Non foi posíbel consultar a clave da emisión" +TwitchAuth.TwoFactorFail.Text="OBS non foi quen de conectarse á súa conta Twitch. Asegúrese de que a autenticación de dous factores estea configurada na súa Configuración de seguranza do Twitch porque é necesaria para facer a emisión." +RestreamAuth.Channels="Volver facer emisión nas canles" +Copy.Filters="Copiar os filtros" +Paste.Filters="Pegar filtros" +BrowserPanelInit.Title="Inicializando o navegador..." +BrowserPanelInit.Text="Inicializando o navegador, agarde..." +BandwidthTest.Region="Zona" +BandwidthTest.Region.US="Estados Unidos" +BandwidthTest.Region.EU="Europa" +BandwidthTest.Region.Asia="Asia" +BandwidthTest.Region.Other="Outra" +Basic.FirstStartup.RunWizard="Quere executar o asistente de configuración automática? Tamén pode configurar manualmente os seus axustes premendo no botón Axustes na xanela principal." +Basic.FirstStartup.RunWizard.NoClicked="Se cambia de opinión, pode executar o asistente de configuración automática de novo dende o menú Ferramentas." +Basic.AutoConfig="Asistente de configuración automática" +Basic.AutoConfig.ApplySettings="Aplicar os axustes" +Basic.AutoConfig.StartPage="Información de uso" +Basic.AutoConfig.StartPage.SubTitle="Especifique para que quere empregar o programa" +Basic.AutoConfig.StartPage.PrioritizeStreaming="Optimizar para distribución de emisións, a gravación é secundaria" +Basic.AutoConfig.StartPage.PrioritizeRecording="Optimizar só para gravar, non imos facer distribución de emisións" +Basic.AutoConfig.VideoPage="Axustes de vídeo" +Basic.AutoConfig.VideoPage.SubTitle="Especifique os axustes de vídeo que quere empregar" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Usar a actual (%1x%2)" +Basic.AutoConfig.VideoPage.BaseResolution.Display="Pantalla %1 (%2x%3)" +Basic.AutoConfig.VideoPage.FPS.UseCurrent="Usar a actual (%1)" +Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 ou 30, pero prefírese 60 cando é posíbel" +Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 ou 30, pero prefírese alta resolución" +Basic.AutoConfig.VideoPage.CanvasExplanation="Nota: a resolución do lenzo (base) non é necesariamente a mesma que a resolución coa que se vai emitir ou gravar. A resolución real da emisión/gravación pode reducirse a partires da resolución do lenzo para atenuar o consumo de recursos ou os requirimentos da taxa de bits." +Basic.AutoConfig.StreamPage="Información da emisión" +Basic.AutoConfig.StreamPage.SubTitle="Insira a información da súa emisión" +Basic.AutoConfig.StreamPage.ConnectAccount="Conectar a conta (recomendado)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Desconectar a conta" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Desconectar a conta?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Este cambio aplicarase de inmediato. Está seguro de que quere desconectar a súa conta?" +Basic.AutoConfig.StreamPage.UseStreamKey="Usar a clave da emisión" +Basic.AutoConfig.StreamPage.Service="Servizo" +Basic.AutoConfig.StreamPage.Service.ShowAll="Amosar todo..." +Basic.AutoConfig.StreamPage.Service.Custom="Personalizado..." +Basic.AutoConfig.StreamPage.Server="Servidor" +Basic.AutoConfig.StreamPage.StreamKey="Clave da emisión" +Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Ligazón)" +Basic.AutoConfig.StreamPage.PerformBandwidthTest="Estimar a taxa de bits coa proba de largo de banda (pode levar uns minutos)" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Prefírese a codificación por hardware" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="A codificación por hardware elimina a maior parte do uso da CPU, pero pode requirir unha maior taxa de bits para obter o mesmo nivel de calidade." +Basic.AutoConfig.StreamPage.StreamWarning.Title="Aviso da emisión" +Basic.AutoConfig.StreamPage.StreamWarning.Text="A proba de largo de banda está a piques de emitir datos de vídeo ao chou sen son á súa canle. Se é posíbel, recoméndase desactivar temporalmente o gardado dos vídeos das emisións e estabelecer a emisión coma privada até que remate a proba. Continuar?" +Basic.AutoConfig.TestPage="Resultados finais" +Basic.AutoConfig.TestPage.SubTitle.Testing="O programa está executando agora un conxunto de probas para estimar os axustes ideais" +Basic.AutoConfig.TestPage.SubTitle.Complete="Proba completa" +Basic.AutoConfig.TestPage.TestingBandwidth="Realizando a proba de largo de banda, isto pode levar uns minutos..." +Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Conectando a: %1..." +Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Produciuse un fallo ao conectarse a calquera servidor, comprobe a conexión a Internet e ténteo de novo." +Basic.AutoConfig.TestPage.TestingBandwidth.Server="Probando o largo de banda para: %1" +Basic.AutoConfig.TestPage.TestingStreamEncoder="Probando o codificador da emisión, isto pode levar un minuto..." +Basic.AutoConfig.TestPage.TestingRecordingEncoder="Probando o codificador da gravación, isto pode levar un minuto..." +Basic.AutoConfig.TestPage.TestingRes="Probando as resolucións, isto pode levar uns minutos..." +Basic.AutoConfig.TestPage.TestingRes.Fail="Produciuse un erro ao iniciar o codificador" +Basic.AutoConfig.TestPage.TestingRes.Resolution="Probando %1x%2 %3 FPS..." +Basic.AutoConfig.TestPage.Result.StreamingEncoder="Codificador da emisión" +Basic.AutoConfig.TestPage.Result.RecordingEncoder="Codificador da gravación" +Basic.AutoConfig.TestPage.Result.Header="O programa determinou que estes axustes estimados son os máis idóneos para vostede:" +Basic.AutoConfig.TestPage.Result.Footer="Para usar estes axustes, prema en Aplicar os axustes. Para volver configurar o asistente e téntalo de novo, prema en Atrás. Para configurar manualmente os axustes, prema en Cancelar e abra Axustes." +Basic.Stats="Estatísticas" +Basic.Stats.CPUUsage="Uso da CPU" +Basic.Stats.HDDSpaceAvailable="Dispoñíbel espazo no disco" +Basic.Stats.MemoryUsage="Uso da memoria" +Basic.Stats.AverageTimeToRender="Tempo de media para xerar os cadros" +Basic.Stats.SkippedFrames="Fotogramas omitidos pola demora na codificación" +Basic.Stats.MissedFrames="Fotogramas perdidos pola demora na xeración" +Basic.Stats.Output.Stream="Emisión" +Basic.Stats.Output.Recording="Gravando" +Basic.Stats.Status="Estado" +Basic.Stats.Status.Recording="Gravando" +Basic.Stats.Status.Live="EN DIRECTO" +Basic.Stats.Status.Reconnecting="Volvendo conectar" +Basic.Stats.Status.Inactive="Inactivo" +Basic.Stats.DroppedFrames="Fotogramas perdidos (rede)" +Basic.Stats.MegabytesSent="Saída total de datos" +Basic.Stats.Bitrate="Taxa de bits" +Basic.Stats.DiskFullIn="Disco cheo en (aprox.)" +ResetUIWarning.Title="Confirma que quere restabelecer a interface de usuario?" +ResetUIWarning.Text="Se restabelece a interface de usuario agochará as docas adicionais. Deberá agochar estas docas no menú Ver se quere que sexan visíbeis.\n\nConfirma que quere restabelecer a interface de usuario?" +Updater.Title="Dispoñíbel unha nova actualización" +Updater.Text="Hai unha nova actualización dispoñíbel:" +Updater.UpdateNow="Actualizar agora" +Updater.RemindMeLater="Lembrarmo máis tarde" +Updater.Skip="Omitir a versión" +Updater.Running.Title="Programa activo actualmente" +Updater.Running.Text="As saídas están activas neste momento. Peche todas as saídas activas antes de tentar actualizar" +Updater.NoUpdatesAvailable.Title="Non hai actualizacións dispoñíbeis" +Updater.NoUpdatesAvailable.Text="Non hai actualizacións dispoñíbeis actualmente" +Updater.FailedToLaunch="Produciuse un fallo ao iniciar o actualizador" +Updater.GameCaptureActive.Title="Captura de xogo activa" +Updater.GameCaptureActive.Text="A biblioteca de captura de xogos está activa neste momento. Peche todos os xogos/programas que estean a se capturar (ou reinicie Windows) e ténteo de novo." -Basic.AddTransition="Engadir transición configurable" -Basic.RemoveTransition="Eliminar transición configurable" +QuickTransitions.SwapScenes="Cambiar as escenas Vista previa/Programa após a transición" +QuickTransitions.SwapScenesTT="Intercambia as escenas de vista previa e saída após a transición (se aínda existe a escena orixinal da saída).\nIsto non desfará os cambios que puidesen terse feito na escena orixinal de saída." +QuickTransitions.DuplicateScene="Escena duplicada" +QuickTransitions.DuplicateSceneTT="Ao editar a mesma escena, permite editar a transformación/visibilidade das fontes sen modificar a saída.\nPara editar as propiedades das fontes sen modificar a saída, active «Fontes duplicadas».\nCambiar este valor restablecerá a escena de saída actual (se aínda existe)." +QuickTransitions.EditProperties="Fontes duplicadas" +QuickTransitions.EditPropertiesTT="Ao editar a mesma escena, permite editar as propiedades das fontes sen modificar a saída.\nIsto só se pode empregar se está activada a opción «Escena duplicada».\nAlgunhas fontes (como as de captura ou as multimedia) non admiten isto e non se poden editar por separado.\nCambiar este valor restablecerá a escena de saída actual (se aínda existe).\n\nAviso: dado que as fontes se duplicarán, isto pode requirir recursos adicionais do sistema ou de vídeo." +QuickTransitions.HotkeyName="Transición rápida: %1" + +Basic.AddTransition="Engadir transición configurábel" +Basic.RemoveTransition="Eliminar transición configurábel" Basic.TransitionProperties="Propiedades da transición" Basic.SceneTransitions="Transicións de escena" Basic.TransitionDuration="Duración" Basic.TogglePreviewProgramMode="Modo de estudio" +TransitionNameDlg.Text="Insira o nome da transición" TransitionNameDlg.Title="Nome da transición" TitleBar.Profile="Perfil" @@ -73,52 +236,86 @@ TitleBar.Scenes="Escenas" NameExists.Title="O nome xa existe" NameExists.Text="O nome xa está en uso." -NoNameEntered.Title="Por favor, insire un nome válido" -NoNameEntered.Text="Non podes empregar nomes baleiros." +NoNameEntered.Title="Insira un nome válido" +NoNameEntered.Text="Non é posíbel empregar nomes baleiros." -ConfirmStart.Title="Iniciar transmisión?" +ConfirmStart.Title="Comezar a emisión?" +ConfirmStart.Text="Confirma que quere iniciar a emisión?" -ConfirmStop.Title="Deter transmisión?" -ConfirmStop.Text="Tes a certeza de querer deter a transmisión?" +ConfirmStop.Title="Deter a emisión?" +ConfirmStop.Text="Confirma que quere deter a emisión?" +ConfirmStopRecord.Title="Deter a gravación?" +ConfirmStopRecord.Text="Confirma que quere deter a gravación?" -ConfirmExit.Title="Saír de OBS?" +ConfirmBWTest.Title="Iniciar a proba do largo de banda?" +ConfirmBWTest.Text="Ten o OBS configurado no modo de proba de largo de banda. Este modo permite probar a rede sen que a súa canle entre en directo. Unha vez rematada a proba, terá que desactivalo para que os espectadores poidan ver a súa emisión.\n\nQuere continuar?" -ConfirmRemove.Title="Confirmar a eliminación" -ConfirmRemove.Text="Tes a certeza de querer eliminar '$1'?" +ConfirmExit.Title="Saír do OBS?" +ConfirmExit.Text="OBS está activo neste momento. Deteranse todas as emisións/gravacións. Confirma que quere saír?" +ConfirmRemove.Title="Confirmar a retirada" +ConfirmRemove.Text="Confirma que quere retirar «$1»?" +ConfirmRemove.TextMultiple="Confirma que quere retirar %1 elementos?" +Output.StartStreamFailed="Produciuse un fallo ao iniciar a emisión" +Output.StartRecordingFailed="Produciuse un fallo ao iniciar a gravación" +Output.StartReplayFailed="Produciuse un fallo ao iniciar a reprodución da memoria temporal" +Output.StartFailedGeneric="Produciuse un fallo na saída. Comprobe o rexistro para ver os detalles.\n\nNota: Se está a usar codificadores NVENC ou AMD, asegúrese de que os controladores de vídeo estean actualizados." -Output.ConnectFail.Title="Erro ao se conectar" -Output.ConnectFail.BadPath="Camiño ou URL de conexión non válidos. Por favor, comproba a configuración para confirmar de que son correctos." -Output.ConnectFail.ConnectFailed="Erro ao conectar co servidor" +Output.ReplayBuffer.PauseWarning.Title="Non é posíbel gardar as reproducións mentres estea en pausa" +Output.ReplayBuffer.PauseWarning.Text="Aviso: non é posíbel gardar as reproducións mentres a gravación estea en pausa." + +Output.ConnectFail.Title="Produciuse un erro ao se conectar" +Output.ConnectFail.BadPath="Ruta ou URL de conexión non válidos. Comprobe os axustes para confirmar que son correctos." +Output.ConnectFail.ConnectFailed="Produciuse un fallo ao conectar co servidor" +Output.ConnectFail.InvalidStream="Non foi posíbel acceder á canle ou clave da emisión especificada, faga a dobre comprobación da clave da emisión. Se é correcta, pode haber un problema na conexión ao servidor." Output.ConnectFail.Error="Produciuse un erro inesperado ao tentar conectar co servidor. Máis información no ficheiro de rexistro." Output.ConnectFail.Disconnected="Desconectado do servidor." +Output.StreamEncodeError.Title="Produciuse un erro de codificación" +Output.StreamEncodeError.Msg="Produciuse un erro de codificación durante a emisión." -Output.RecordFail.Title="Erro ao iniciar a gravación" +Output.RecordFail.Title="Produciuse un erro ao iniciar a gravación" +Output.RecordFail.Unsupported="O formato de saída non é compatíbel ou non admite máis dunha pista de son. Verifique a súa configuración e ténteo de novo." +Output.RecordNoSpace.Title="Non hai espazo abondo no disco" +Output.RecordNoSpace.Msg="Non hai espazo abondo no disco para continuar coa gravación." +Output.RecordError.Title="Produciuse un erro de gravación" +Output.RecordError.Msg="Produciuse un erro non especificado durante a gravación." +Output.RecordError.EncodeErrorMsg="Produciuse un erro de codificación durante a gravación." +Output.ReplayBuffer.NoHotkey.Title="Non hai estabelecida ningunha tecla rápida!" +Output.ReplayBuffer.NoHotkey.Msg="Non hai estabelecida ningunha tecla rápida para a memoria temporal de reprodución. Estabeleza a tecla rápida «Gardar» para utilizala para gardar as gravacións de reproducións." -Output.BadPath.Title="Camiño do ficheiro incorrecto" -Output.BadPath.Text="O camiño de ficheiros establecido non é válido. Por favor, comproba a configuración para confirmar que se estableceu un camiño válido." +Output.BadPath.Title="Ruta do ficheiro incorrecta" +Output.BadPath.Text="A ruta dos ficheiros establecida non é válida. Comprobe os axustes para confirmar que foi estabelecida unha ruta válida." -LogReturnDialog="Carga de rexistro satisfactoria" -LogReturnDialog.CopyURL="Copiar URL" -LogReturnDialog.ErrorUploadingLog="Erro ao cargar o ficheiro de rexistro" +LogReturnDialog="Carga satisfactoria do rexistro" +LogReturnDialog.CopyURL="Copiar o URL" +LogReturnDialog.ErrorUploadingLog="Produciuse un erro ao cargar o ficheiro de rexistro" Remux.SourceFile="Gravación OBS" Remux.TargetFile="Ficheiro de destino" Remux.Remux="Converter" +Remux.Stop="Deter a conversión" +Remux.ClearFinished="Limpar os elementos rematados" +Remux.ClearAll="Limpar todos os elementos" +Remux.OBSRecording="Gravación OBS" Remux.FinishedTitle="Conversión rematada" -Remux.Finished="Gravando conversión" +Remux.Finished="Gravando a conversión" Remux.FinishedError="Gravación convertida, mais o ficheiro podería estar incompleto" -Remux.ExitUnfinishedTitle="Conversión en marcha" -Remux.ExitUnfinished="A conversión non rematou, detela agora podería provocar que o ficheiro final fose inutilizable.\nTes a certeza de querer deter a conversión?" +Remux.SelectRecording="Seleccionar a gravación OBS..." +Remux.SelectTarget="Seleccionar o ficheiro de destino..." +Remux.FileExistsTitle="Xa existen ficheiros de destino" +Remux.FileExists="Os ficheiros de destino seguintes xa existen. Quere substituílos?" +Remux.ExitUnfinishedTitle="Conversión en proceso" +Remux.ExitUnfinished="A conversión aínda non rematou, detela agora podería provocar que o ficheiro final fose inutilizábel.\nConfirma que quere deter a conversión?" +Remux.HelpText="Solte os ficheiros para converter nesta xanela ou seleccione unha cela «Gravación OBS» baleira para buscar un ficheiro." -UpdateAvailable="Nova actualización dispoñible" -UpdateAvailable.Text="Versión %1.%2.%3 xa dispoñible. Preme aquí para descargala" +UpdateAvailable="Hai dispoñíbel unha nova actualización" +UpdateAvailable.Text="A versión %1.%2.%3 xa está dispoñíbel. Prema aquí para descargala" -Basic.DesktopDevice1="Audio do escritorio" -Basic.DesktopDevice2="Audio do escritorio 2" +Basic.DesktopDevice1="Son do escritorio" +Basic.DesktopDevice2="Son do escritorio 2" Basic.AuxDevice1="Mic/Aux" Basic.AuxDevice2="Mic/Aux 2" Basic.AuxDevice3="Mic/Aux 3" @@ -127,70 +324,106 @@ Basic.AuxDevice4="Mic/Aux 4" Basic.Scene="Escena" Basic.DisplayCapture="Captura de pantalla" -Basic.Main.PreviewConextMenu.Enable="Habilitar vista previa" +Basic.Main.PreviewConextMenu.Enable="Activar a vista previa" +Basic.Main.Preview.Disable="Desactivar a vista previa" +ScaleFiltering="Filtrado de escala" +ScaleFiltering.Point="Punto" +ScaleFiltering.Bilinear="Bilineal" +ScaleFiltering.Bicubic="Bicúbico" +ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Área" +Deinterlacing="Desentrelazado" +Deinterlacing.Discard="Desbotar" +Deinterlacing.Retro="Retroactivo" +Deinterlacing.Blend="Mestura" +Deinterlacing.Blend2x="Mestura 2x" +Deinterlacing.Linear="Lineal" +Deinterlacing.Linear2x="Lineal 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Primeiro o campo superior" +Deinterlacing.BottomFieldFirst="Primeiro o campo inferior" +VolControl.SliderUnmuted="Potenciómetro de volume para «%1»: %2" +VolControl.SliderMuted="Potenciómetro de volume para «%1»: %2 (actualmente silenciado)" +VolControl.Mute="Silenciar «%1»" +VolControl.Properties="Propiedades para «%1»" Basic.Main.AddSceneDlg.Title="Engadir escena" -Basic.Main.AddSceneDlg.Text="Por favor, insire un nome para a escena" +Basic.Main.AddSceneDlg.Text="Insira un nome para a escena" Basic.Main.DefaultSceneName.Text="Escena %1" Basic.Main.AddSceneCollection.Title="Engadir colección de escenas" -Basic.Main.AddSceneCollection.Text="Por favor, insire o nome da colección de escenas" +Basic.Main.AddSceneCollection.Text="Insira o nome da colección de escenas" -Basic.Main.RenameSceneCollection.Title="Renomear colección de escenas" +Basic.Main.RenameSceneCollection.Title="Renomear a colección de escenas" AddProfile.Title="Engadir perfil" -AddProfile.Text="Por favor, insire o nome do perfil" +AddProfile.Text="Insira o nome do perfil" -RenameProfile.Title="Renomear perfil" +RenameProfile.Title="Renomear o perfil" + +Basic.Main.MixerRename.Title="Renomear a fonte de son" +Basic.Main.MixerRename.Text="Insira un nome para a fonte de son" - -Basic.Main.PreviewDisabled="A vista previa está actualmente deshabilitada" +Basic.Main.PreviewDisabled="A vista previa está desactivada actualmente" Basic.SourceSelect="Crear/seleccionar fonte" Basic.SourceSelect.CreateNew="Crear nova" Basic.SourceSelect.AddExisting="Engadir existente" +Basic.SourceSelect.AddVisible="Facer visíbel a fonte" -Basic.PropertiesWindow="Propiedades para '%1'" +Basic.PropertiesWindow="Propiedades para «%1»" +Basic.PropertiesWindow.AutoSelectFormat="%1 (seleccionar automaticamente: %2)" Basic.PropertiesWindow.SelectColor="Seleccionar cor" -Basic.PropertiesWindow.SelectFont="Seleccionar fonte" +Basic.PropertiesWindow.SelectFont="Seleccionar o tipo de letra" Basic.PropertiesWindow.ConfirmTitle="Axustes cambiados" -Basic.PropertiesWindow.Confirm="Hai cambios sen gardar. Queres conservalos?" -Basic.PropertiesWindow.NoProperties="Ningunha propiedade dispoñible" +Basic.PropertiesWindow.Confirm="Hai cambios sen gardar. Quere conservalos?" +Basic.PropertiesWindow.NoProperties="Non hai ningunha propiedade dispoñíbel" Basic.PropertiesWindow.AddFiles="Engadir ficheiros" -Basic.PropertiesWindow.AddURL="Engadir camiño/URL" -Basic.PropertiesWindow.AddEditableListFiles="Engadir ficheiros a '%1'" -Basic.PropertiesWindow.AddEditableListEntry="Engadir entrada a '%1'" -Basic.PropertiesWindow.EditEditableListEntry="Egnadir entrada desde '%1'" +Basic.PropertiesWindow.AddDir="Engadir directorio" +Basic.PropertiesWindow.AddURL="Engadir ruta/URL" +Basic.PropertiesWindow.AddEditableListDir="Engadir directorio a «%1»" +Basic.PropertiesWindow.AddEditableListFiles="Engadir ficheiros a «%1»" +Basic.PropertiesWindow.AddEditableListEntry="Engadir entrada a «%1»" +Basic.PropertiesWindow.EditEditableListEntry="Editar entrada dende «%1»" +Basic.PropertiesView.FPS.Simple="Valores FPS sinxelos" +Basic.PropertiesView.FPS.Rational="Valores racionais FPS" +Basic.PropertiesView.FPS.ValidFPSRanges="Intervalos FPS válidos:" -Basic.InteractionWindow="Interactuando con '%1'" +Basic.InteractionWindow="Interactuando con «%1»" Basic.StatusBar.Reconnecting="Desconectado, reconectando en %2 segundo(s) (tentativa número %1)" Basic.StatusBar.AttemptingReconnect="Tentando reconectar... (tentativa número %1)" Basic.StatusBar.ReconnectSuccessful="Reconexión satisfactoria" +Basic.StatusBar.Delay="Atraso (%1 seg)" +Basic.StatusBar.DelayStartingIn="Atraso (iniciando en %1 seg)" +Basic.StatusBar.DelayStoppingIn="Atraso (detendo en %1 seg)" +Basic.StatusBar.DelayStartingStoppingIn="Atraso (detendo en %1 seg, iniciando en %2 seg)" Basic.Filters="Filtros" -Basic.Filters.AsyncFilters="Filtros de audio/vídeo" -Basic.Filters.AudioFilters="Filtros de audio" +Basic.Filters.AsyncFilters="Filtros de son/vídeo" +Basic.Filters.AudioFilters="Filtros de son" Basic.Filters.EffectFilters="Filtros de efectos" -Basic.Filters.Title="Filtros para '%1'" +Basic.Filters.Title="Filtros para «%1»" Basic.Filters.AddFilter.Title="Nome do filtro" -Basic.Filters.AddFilter.Text="Especifica, por favor, o nome do filtro" +Basic.Filters.AddFilter.Text="Especifique o nome do filtro" Basic.TransformWindow="Axustes de escena" Basic.TransformWindow.Position="Posición" Basic.TransformWindow.Rotation="Rotación" Basic.TransformWindow.Size="Tamaño" Basic.TransformWindow.Alignment="Aliñamento" -Basic.TransformWindow.BoundsType="Tipo de caixa dependente" -Basic.TransformWindow.BoundsAlignment="Aliñamento na caixa dependente" -Basic.TransformWindow.Bounds="Tamaño da caixa dependente" +Basic.TransformWindow.BoundsType="Tipo de caixa contedora" +Basic.TransformWindow.BoundsAlignment="Aliñamento na caixa contedora" +Basic.TransformWindow.Bounds="Tamaño da caixa contedora" +Basic.TransformWindow.Crop="Recortar" Basic.TransformWindow.Alignment.TopLeft="Arriba á esquerda" Basic.TransformWindow.Alignment.TopCenter="Arriba no centro" @@ -210,23 +443,38 @@ Basic.TransformWindow.BoundsType.ScaleToWidth="Escalar á largura dos límites" Basic.TransformWindow.BoundsType.ScaleToHeight="Escalar á altura dos límites" Basic.TransformWindow.BoundsType.Stretch="Estricar ata os límites" -Basic.Main.AddSourceHelp.Title="Non se pode engadir a fonte" -Basic.Main.AddSourceHelp.Text="Tes que ter cando menos 1 escena para engadir unha fonte." +Basic.Main.AddSourceHelp.Title="Non é posíbel engadir a fonte" +Basic.Main.AddSourceHelp.Text="Ten que ter cando menos 1 escena para engadir unha fonte." Basic.Main.Scenes="Escenas" Basic.Main.Sources="Fontes" -Basic.Main.Connecting="A conectar..." -Basic.Main.StartRecording="Iniciar gravación" -Basic.Main.StartStreaming="Iniciar retransmisión" -Basic.Main.StopRecording="Deter gravación" -Basic.Main.StopStreaming="Deter retransmisión" +Basic.Main.Controls="Controis" +Basic.Main.Connecting="Conectando..." +Basic.Main.StartRecording="Iniciar a gravación" +Basic.Main.StartReplayBuffer="Iniciar a reprodución da memoria temporal" +Basic.Main.StartStreaming="Comezar a emisión" +Basic.Main.StopRecording="Deter a gravación" +Basic.Main.PauseRecording="Pór en pausa a gravación" +Basic.Main.UnpauseRecording="Reiniciar a gravación" +Basic.Main.StoppingRecording="Detendo a gravación..." +Basic.Main.StopReplayBuffer="Deter a reprodución da memoria temporal" +Basic.Main.StoppingReplayBuffer="Detendo a reprodución da memoria temporal..." +Basic.Main.StopStreaming="Deter a emisión" +Basic.Main.StoppingStreaming="Detendo a emisión..." +Basic.Main.ForceStopStreaming="Deter a emisión (desbotar o atraso)" +Basic.Main.Group="Grupo %1" +Basic.Main.GroupItems="Agrupar os elementos seleccionados" +Basic.Main.Ungroup="Desagrupar" Basic.MainMenu.File="&Ficheiro" Basic.MainMenu.File.Export="&Exportar" Basic.MainMenu.File.Import="&Importar" -Basic.MainMenu.File.ShowRecordings="Most&rar gravacións" -Basic.MainMenu.File.Remux="Conversións gardadas (&M)" +Basic.MainMenu.File.ShowRecordings="Amosa&r as gravacións" +Basic.MainMenu.File.Remux="Gravacións de conversións (&M)" Basic.MainMenu.File.Settings="Axu&stes" +Basic.MainMenu.File.ShowSettingsFolder="Amosar o cartafol dos axustes" +Basic.MainMenu.File.ShowProfileFolder="Amosar o cartafol deo perfil" +Basic.MainMenu.AlwaysOnTop="Sempre enriba" Basic.MainMenu.File.Exit="Saír (&X)" Basic.MainMenu.Edit="&Editar" @@ -234,146 +482,342 @@ Basic.MainMenu.Edit.Undo="Desfacer (&U)" Basic.MainMenu.Edit.Redo="&Refacer" Basic.MainMenu.Edit.UndoAction="Desfacer $1 (&U)" Basic.MainMenu.Edit.RedoAction="&Refacer $1" +Basic.MainMenu.Edit.LockPreview="Vista previa do b&loqueo" +Basic.MainMenu.Edit.Scale="E&scalado da vista previa" +Basic.MainMenu.Edit.Scale.Window="Escalar á xanela" +Basic.MainMenu.Edit.Scale.Canvas="Lenzo (%1x%2)" +Basic.MainMenu.Edit.Scale.Output="Saída (%1x%2)" Basic.MainMenu.Edit.Transform="&Transformar" -Basic.MainMenu.Edit.Transform.EditTransform="&Editar transformación..." -Basic.MainMenu.Edit.Transform.ResetTransform="&Restablecer transformación" -Basic.MainMenu.Edit.Transform.Rotate90CW="Rotar 90 graos no sentido das agullas" -Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotar 90 graos contra o sentido das agullas" +Basic.MainMenu.Edit.Transform.EditTransform="&Editar a transformación..." +Basic.MainMenu.Edit.Transform.CopyTransform="Copiar a transformación" +Basic.MainMenu.Edit.Transform.PasteTransform="Pegar a transformación" +Basic.MainMenu.Edit.Transform.ResetTransform="&Restabelecer a transformación" +Basic.MainMenu.Edit.Transform.Rotate90CW="Rotar 90 graos no sentido das agullas do reloxo" +Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotar 90 graos contra o sentido das agullas do relox" Basic.MainMenu.Edit.Transform.Rotate180="Rotar 180 graos" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Virar &horizontalmente" -Basic.MainMenu.Edit.Transform.FlipVertical="Virar &verticalmente" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Inverter &horizontalmente" +Basic.MainMenu.Edit.Transform.FlipVertical="Inverter &verticalmente" Basic.MainMenu.Edit.Transform.FitToScreen="Axustar á pantalla (&F)" Basic.MainMenu.Edit.Transform.StretchToScreen="E&stricar á pantalla" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centrar na pantalla" +Basic.MainMenu.Edit.Transform.VerticalCenter="Centrar verticalmente" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Centrar horizontalmente" Basic.MainMenu.Edit.Order="&Ordenar" Basic.MainMenu.Edit.Order.MoveUp="S&ubir" Basic.MainMenu.Edit.Order.MoveDown="Baixar (&D)" Basic.MainMenu.Edit.Order.MoveToTop="Levar para a cima (&T)" Basic.MainMenu.Edit.Order.MoveToBottom="Levar para a&baixo" -Basic.MainMenu.Edit.AdvAudio="Propiedades de audio &avanzadas" +Basic.MainMenu.Edit.AdvAudio="Propiedades &avanzadas de son" +Basic.MainMenu.View="&Ver" +Basic.MainMenu.View.Toolbars="Barras de ferramentas (&T)" +Basic.MainMenu.View.Docks="Docas" +Basic.MainMenu.View.Docks.ResetUI="Restabelecer a interface de usuario" +Basic.MainMenu.View.Docks.LockUI="Bloquear a interface de usuario" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Docas personalizadas do navegador..." +Basic.MainMenu.View.Toolbars.Listboxes="Caixas de &listas" +Basic.MainMenu.View.SceneTransitions="Transicións de e&scena" +Basic.MainMenu.View.StatusBar="Barra de e&stado" +Basic.MainMenu.View.Fullscreen.Interface="Interface de pantalla completa" Basic.MainMenu.SceneCollection="Colección de e&scenas" Basic.MainMenu.Profile="&Perfil" +Basic.MainMenu.Profile.Import="Importar perfil" +Basic.MainMenu.Profile.Export="Exportar perfil" +Basic.MainMenu.SceneCollection.Import="Importar colección de escenas" +Basic.MainMenu.SceneCollection.Export="Exportar colección de escenas" +Basic.MainMenu.Profile.Exists="O perfil xa existe" +Basic.MainMenu.SceneCollection.Exists="A colección de escenas xa existe" +Basic.MainMenu.Tools="Ferramen&tas" Basic.MainMenu.Help="Axuda (&H)" +Basic.MainMenu.Help.HelpPortal="&Portal de axuda" Basic.MainMenu.Help.Website="Visitar sitio &web" +Basic.MainMenu.Help.Discord="Unirse ao servidor de &Discord" Basic.MainMenu.Help.Logs="Ficheiros de rexistro (&L)" -Basic.MainMenu.Help.Logs.ShowLogs="Mostrar ficheiro&s de rexistro" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Subir fi&cheiro de rexistro actual" -Basic.MainMenu.Help.Logs.UploadLastLog="Subir o ú<imo ficheiro de rexistro" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Ver rexistro actual" +Basic.MainMenu.Help.Logs.ShowLogs="Amo&sar os ficheiros de rexistro" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Enviar o ficheiro de rexistro a&ctual" +Basic.MainMenu.Help.Logs.UploadLastLog="Enviar o ú<imo ficheiro de rexistro" +Basic.MainMenu.Help.Logs.ViewCurrentLog="&Ver o rexistro actual" Basic.MainMenu.Help.CheckForUpdates="Comprobar se hai actualizacións" +Basic.MainMenu.Help.CrashLogs="Info&rmes de fallos" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Amo&sar os informes de fallos" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Enviar o ú<imo informe de fallo" +Basic.MainMenu.Help.About="Sobre (&A)" Basic.Settings.ProgramRestart="Debe reiniciarse o programa para que se aplique a nova configuración." -Basic.Settings.ConfirmTitle="Confirmar cambios" -Basic.Settings.Confirm="Hai cambios sen gardar. Desexas gardalos?" +Basic.Settings.ConfirmTitle="Confirmar os cambios" +Basic.Settings.Confirm="Hai cambios sen gardar. Quere gardalos?" Basic.Settings.General="Xeral" Basic.Settings.General.Theme="Tema" Basic.Settings.General.Language="Idioma" +Basic.Settings.General.EnableAutoUpdates="Comprobar automaticamente no inicio se hai actualizacións" +Basic.Settings.General.OpenStatsOnStartup="Abrir o diálogo de estatísticas ao iniciar" +Basic.Settings.General.WarnBeforeStartingStream="Amosar o diálogo de confirmación ao iniciar as emisións" +Basic.Settings.General.WarnBeforeStoppingStream="Amosar o diálogo de confirmación ao deter as emisións" +Basic.Settings.General.WarnBeforeStoppingRecord="Amosar o diálogo de confirmación ao deter a gravación" +Basic.Settings.General.Projectors="Proxectores" +Basic.Settings.General.HideProjectorCursor="Agochar o cursor nos proxectores" +Basic.Settings.General.ProjectorAlwaysOnTop="Poñer os proxectores sempre na parte superior" +Basic.Settings.General.Snapping="Axuste do aliñamento da fonte" +Basic.Settings.General.ScreenSnapping="Axustar as fontes ao bordo da pantalla" +Basic.Settings.General.CenterSnapping="Axustar as fontes ao centro horizontal e vertical" +Basic.Settings.General.SourceSnapping="Axustar as fontes a outras fontes" +Basic.Settings.General.SnapDistance="Axustar a sensibilidade" +Basic.Settings.General.RecordWhenStreaming="Gravar automáticamente cando se está a emitir" +Basic.Settings.General.KeepRecordingWhenStreamStops="Seguir gravando cando se detén a emisión" +Basic.Settings.General.ReplayBufferWhileStreaming="Iniciar automáticamente a memoria temporal de reprodución cando se está a emitir" +Basic.Settings.General.KeepReplayBufferStreamStops="Manter a memoria temporal de reprodución activa cando se detén a emisión" +Basic.Settings.General.SysTray="Área de notificación" +Basic.Settings.General.SysTrayWhenStarted="Minimizar á área de notificación cando se inicia" +Basic.Settings.General.SystemTrayHideMinimize="Minimizar sempre na área de notificación no canto de na barra de tarefas" +Basic.Settings.General.SaveProjectors="Gardar os proxectores ao saír" +Basic.Settings.General.Preview="Vista previa" +Basic.Settings.General.OverflowHidden="Agochar o desbordamento" +Basic.Settings.General.OverflowAlwaysVisible="Desbordamento sempre visíbel" +Basic.Settings.General.OverflowSelectionHidden="Amosar o desbordamento incluso cando a fonte sexa invisíbel" +Basic.Settings.General.SwitchOnDoubleClick="Transición á escena cando faga dobre clic" +Basic.Settings.General.StudioPortraitLayout="Activar a disposición de retrato/vertical" +Basic.Settings.General.TogglePreviewProgramLabels="Amosar as etiquetas de vista previa/programa" +Basic.Settings.General.Multiview="Vista múltiple" +Basic.Settings.General.Multiview.MouseSwitch="Prema para cambiar entre escenas" +Basic.Settings.General.Multiview.DrawSourceNames="Amosar o nome das esceas" +Basic.Settings.General.Multiview.DrawSafeAreas="Debuxar áreas seguras (EBU R 95)" +Basic.Settings.General.MultiviewLayout="Disposición de vista múltiple" +Basic.Settings.General.MultiviewLayout.Horizontal.Top="Horizontal, arriba (8 escenas)" +Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Horizontal, abaixo (8 escenas)" +Basic.Settings.General.MultiviewLayout.Vertical.Left="Vertical, esquerda (8 escenas)" +Basic.Settings.General.MultiviewLayout.Vertical.Right="Vertical, dereita (8 escenas)" +Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Horizontal, arriba (24 escenas)" -Basic.Settings.Stream="Reprodución" -Basic.Settings.Stream.StreamType="Tipo de retransmisión" +Basic.Settings.Stream="Emisión" +Basic.Settings.Stream.StreamType="Tipo de emisión" +Basic.Settings.Stream.Custom.UseAuthentication="Usar a autenticación" +Basic.Settings.Stream.Custom.Username="Nome de usuario" +Basic.Settings.Stream.Custom.Password="Contrasinal" +Basic.Settings.Stream.BandwidthTestMode="Activar o modo de proba de largo de banda" Basic.Settings.Output="Saída" Basic.Settings.Output.Format="Formato de gravación" Basic.Settings.Output.Encoder="Codificador" -Basic.Settings.Output.SelectDirectory="Seleccionar directorio de gravación" -Basic.Settings.Output.SelectFile="Seleccionar ficheiro de gravación" +Basic.Settings.Output.SelectDirectory="Seleccionar o directorio de gravación" +Basic.Settings.Output.SelectFile="Seleccionar o ficheiro de gravación" +Basic.Settings.Output.EnforceBitrate="Aplicar os límites de taxa de bits do servizo de emisión" +Basic.Settings.Output.DynamicBitrate="Cambiar dinamicamente a taxa de bits para xestionar a conxestión" +Basic.Settings.Output.DynamicBitrate.Beta="Cambiar dinamicamente a taxa de bits para xestionar a conxestión (beta)" +Basic.Settings.Output.DynamicBitrate.TT="No canto de deixar perder cadros para reducir a conxestión, cambia dinamicamente a taxa de bits.\n\nTeña en conta que isto pode aumentar o atraso para os espectadores se hai unha conxestión súbita importante.\n\n Cando a taxa de bits cae, pode tardar uns minutos en restaurarse.\n\nActualmente só é compatible con RTMP." Basic.Settings.Output.Mode="Modo de saída" Basic.Settings.Output.Mode.Simple="Sinxelo" Basic.Settings.Output.Mode.Adv="Avanzado" Basic.Settings.Output.Mode.FFmpeg="Saída de FFmpeg" -Basic.Settings.Output.Simple.SavePath="Camiño da gravación" -Basic.Settings.Output.VideoBitrate="Velocidade de bits de vídeo" -Basic.Settings.Output.AudioBitrate="Velocidade de bits de audio" -Basic.Settings.Output.Reconnect="Reconectar automaticamente" -Basic.Settings.Output.RetryDelay="Retardo da nova tentativa (segundos)" +Basic.Settings.Output.UseReplayBuffer="Activar a reprodución da memoria temporal" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Tempo máximo de reprodución" +Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memoria máxima (megabytes)" +Basic.Settings.Output.ReplayBuffer.Estimate="Uso estimado da memoria: %1 MB" +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Non é posíbel estimar o uso de memoria. Estabeleza o límite máximo de memoria." +Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Nota: Asegúrese de establecer unha tecla rápida para a memoria temporal de reprodución na sección de teclas rápidas)" +Basic.Settings.Output.ReplayBuffer.Prefix="Prefixo do nome de ficheiro de reprodución da memoria temporal" +Basic.Settings.Output.ReplayBuffer.Suffix="Sufixo" +Basic.Settings.Output.Simple.SavePath="Ruta da gravación" +Basic.Settings.Output.Simple.RecordingQuality="Calidade da gravación" +Basic.Settings.Output.Simple.RecordingQuality.Stream="A mesma da emisión" +Basic.Settings.Output.Simple.RecordingQuality.Small="Alta calidade, tamaño medio do ficheiro" +Basic.Settings.Output.Simple.RecordingQuality.HQ="Calidade indistinguíbel, tamaño de ficheiro grande" +Basic.Settings.Output.Simple.RecordingQuality.Lossless="Calidade sen perda, tamaño inmenso de ficheiro" +Basic.Settings.Output.Simple.Warn.VideoBitrate="Aviso: A taxa de bits do vídeo en emisión estabelecerase en %1, que é o límite superior para o servizo de emisión actual. Se está seguro de que quere superar %1, active as opcións avanzadas do codificador e desmarque «Aplicar os límites de taxa de bits do servizo de emisión»." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Aviso: A taxa de bits do son en emisión estabelecerase en %1, que é o límite superior para o servizo deemisión actual. Se está seguro de que quere superar %1, active as opcións avanzadas do codificador e desmarque «Aplicar os límites de taxa de bits do servizo de emisión»." +Basic.Settings.Output.Simple.Warn.CannotPause="Aviso: Non é posíbel deter as gravacións se a calidade da gravación está estabelecida como «A mesma da emisión»." +Basic.Settings.Output.Simple.Warn.Encoder="Aviso: a gravación cun codificador de software cunha calidade diferente á da emisión requirirá un uso de CPU adicional se se emite e grava ao mesmo tempo." +Basic.Settings.Output.Simple.Warn.Lossless="Aviso: A calidade sen perda xera tamaños de ficheiro inmensamente grandes. A calidade sen perdas pode empregar á alza de 7 xigabytes de espazo de disco por minuto a altas resolucións e taxa de cadros. Non se recomenda «sen perdas» para gravacións longas a menos que dispoña dunha cantidade moi grande de espazo no disco." +Basic.Settings.Output.Simple.Warn.Lossless.Msg="Confirma que quere empregar unha calidade sen perda?" +Basic.Settings.Output.Simple.Warn.Lossless.Title="Aviso de calidade sen perda!" +Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)" +Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 preaxustado o uso de CPU baixo, aumenta o tamaño do ficheiro)" +Basic.Settings.Output.VideoBitrate="Taxa de bits de vídeo" +Basic.Settings.Output.AudioBitrate="Taxa de bits de son" +Basic.Settings.Output.Reconnect="Volver conectar automaticamente" +Basic.Settings.Output.RetryDelay="Atraso dos novos intentos" Basic.Settings.Output.MaxRetries="Número máximo de tentativas" -Basic.Settings.Output.Advanced="Activar a configuración do codificador avanzada" -Basic.Settings.Output.CustomEncoderSettings="Axustes do codificador personalizados" +Basic.Settings.Output.Advanced="Activar os axustes avanzados do codificador" +Basic.Settings.Output.EncoderPreset="Preaxuste do codificador" +Basic.Settings.Output.CustomEncoderSettings="Axustes personalizados do codificador" +Basic.Settings.Output.CustomMuxerSettings="Axustes personalizados do Muxer" +Basic.Settings.Output.NoSpaceFileName="Xerar o nome do ficheiro sen espazos" -Basic.Settings.Output.Adv.Rescale="Cambiar a escala de saída" -Basic.Settings.Output.Adv.AudioTrack="Pista de audio" -Basic.Settings.Output.Adv.Streaming="En tempo real" -Basic.Settings.Output.Adv.ApplyServiceSettings="Aplicar axustes de codificador de servizo en tempo real (streaming)" +Basic.Settings.Output.Adv.Rescale="Cambiar a escala da saída" +Basic.Settings.Output.Adv.AudioTrack="Pista de son" +Basic.Settings.Output.Adv.Streaming="Emisión" +Basic.Settings.Output.Adv.ApplyServiceSettings="Aplicar os axustes de codificador do servizo de emisión" Basic.Settings.Output.Adv.Audio.Track1="Pista 1" Basic.Settings.Output.Adv.Audio.Track2="Pista 2" Basic.Settings.Output.Adv.Audio.Track3="Pista 3" Basic.Settings.Output.Adv.Audio.Track4="Pista 4" +Basic.Settings.Output.Adv.Audio.Track5="Pista 5" +Basic.Settings.Output.Adv.Audio.Track6="Pista 6" Basic.Settings.Output.Adv.Recording="Gravando" Basic.Settings.Output.Adv.Recording.Type="Tipo" Basic.Settings.Output.Adv.Recording.Type.Standard="Estándar" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Saída personalizada (FFmpeg)" -Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Utilizar fluxo do codificador)" +Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Empregar o codificador da emisión)" +Basic.Settings.Output.Adv.Recording.Filename="Formato do nome de ficheiro" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Sobrescribir se existe o ficheiro" +Basic.Settings.Output.Adv.FFmpeg.Type="Tipo de saída FFmpeg" +Basic.Settings.Output.Adv.FFmpeg.Type.URL="Saída a URL" +Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Saída a ficheiro" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Formatos comúns de gravación" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Todos os ficheiros" -Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Camiño do ficheiro ou URL" +Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Ruta ou URL do ficheiro" Basic.Settings.Output.Adv.FFmpeg.Format="Formato do contedor" -Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Audio" +Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Son" Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Vídeo" -Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Formato predefinido" +Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Formato predeterminado" Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Descrición do formato do contedor" -Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Codificador predefinido" -Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Desactivar codificador" +Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Códec de son/vídeo suposto a partires da ruta do ficheiro ou do URL" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Codificador predeterminado" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Desactivar o codificador" Basic.Settings.Output.Adv.FFmpeg.VEncoder="Codificador de vídeo" Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Axustes do codificador de vídeo (se existe)" -Basic.Settings.Output.Adv.FFmpeg.AEncoder="Codificador de audio" -Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Axustes do codificador de audio (se existe)" +Basic.Settings.Output.Adv.FFmpeg.AEncoder="Codificador de son" +Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Axustes do codificador de son (se existe)" +Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Axustes do Muxer (se existe)" +Basic.Settings.Output.Adv.FFmpeg.GOPSize="Intervalo de fotogramas clave (en fotogramas)" +Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Amosar todos os códecs (aínda que poidan ser incompatíbeis)" +FilenameFormatting.completer="%DD-%MM-%CCYY %hh-%mm-%ss\n%DD-%MM-%YY %hh-%mm-%ss\n%d-%m-%Y %H-%M-%S\n%d-%m-%y %H-%M-%S\n%a %d-%m-%Y %H-%M-%S\n%A %d-%m-%Y %H-%M-%S\n%d-%b-%Y %H-%M-%S\n%d-%B-%Y %H-%M-%S\n%d-%m-%Y %I-%M-%S-%p\n%d-%m-%Y %H-%M-%S-%z\n%d-%m-%Y %H-%M-%S-%Z\n%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" +FilenameFormatting.TT="%CCYY Ano, catro díxitos\n%YY Ano, dous últimos díxitos (00-99)\n%MM Mes como número decimal (01-12)\n%DD Día do mes, recheo co cero (01-31)\n%hh Hora en formato 24h (00-23)\n%mm Minuto (00-59)\n%ss Segundo (00-61)\n%% Un signo %\n%a Nome abreviado do día da semana\n%A Nome completo do día da semana\n%b Nome abreviado do mes\n%B Nome completo do mes\n%d Día do mes, recheo co cero (01-31)\n%H Hora en formato 24h (00-23)\n%I Hora en formato 12h (01-12)\n%m Mes como número decimal (01-12)\n%M Minuto (00-59)\n%p Designación AM ou PM\n%S Segundo (00-61)\n%y Ano, dous últimos díxitos (00-99)\n%Y Ano\n%z Desviación ISO 8601 de UTC no fuso horario\n%Z Fuso horario ou abreviatura\n" Basic.Settings.Video="Vídeo" Basic.Settings.Video.Adapter="Adaptador de vídeo" +Basic.Settings.Video.BaseResolution="Resolución da base (lenzo)" +Basic.Settings.Video.ScaledResolution="Resolución de saída (escalada)" Basic.Settings.Video.DownscaleFilter="Filtro de redución" Basic.Settings.Video.DisableAeroWindows="Desactivar Aero (só Windows)" Basic.Settings.Video.FPS="FPS" Basic.Settings.Video.FPSCommon="Valores comúns de FPS" Basic.Settings.Video.FPSInteger="Valor enteiro de FPS" -Basic.Settings.Video.FPSFraction="Valor fraccional de FPS" +Basic.Settings.Video.FPSFraction="Valor fraccionario de FPS" Basic.Settings.Video.Numerator="Numerador" Basic.Settings.Video.Denominator="Denominador" -Basic.Settings.Video.Renderer="Procesador" +Basic.Settings.Video.Renderer="Xerador" Basic.Settings.Video.InvalidResolution="Valor da resolución non válido. Debe ser [width] x [height] (por exemplo, 1920 x 1080)" -Basic.Settings.Video.CurrentlyActive="A saída de vídeo está actualmente activa. Por favor, apaga calquera saída para cambiar a configuración de vídeo." +Basic.Settings.Video.CurrentlyActive="A saída de vídeo está activa neste momento. Apaga calquera saída para cambiar a configuración de vídeo." +Basic.Settings.Video.DisableAero="Desactivar Aero" -Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (máis rápido, pero borroso de se escalar a imaxe)" -Basic.Settings.Video.DownscaleFilter.Bicubic="Bicúbico (escalamento fino, 16 mostras)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (escalamento fino, 32 mostras)" +Basic.Settings.Video.DownscaleFilter.Bilinear="Bilineal (máis rápido, mais borroso ao se escalar a imaxe)" +Basic.Settings.Video.DownscaleFilter.Bicubic="Bicúbico (escalado fino, 16 mostraxes)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (escalado fino, 36 mostraxes)" +Basic.Settings.Video.DownscaleFilter.Area="Superficie (suma ponderada, 4/6/9 mostraxes)" -Basic.Settings.Audio="Audio" -Basic.Settings.Audio.SampleRate="Intervalo da mostra" +Basic.Settings.Audio="Son" +Basic.Settings.Audio.SampleRate="Frecuencia da mostraxe" Basic.Settings.Audio.Channels="Canles" +Basic.Settings.Audio.Meters="Medidores" +Basic.Settings.Audio.MeterDecayRate="Taxa de decaemento" +Basic.Settings.Audio.MeterDecayRate.Fast="Rápido" +Basic.Settings.Audio.MeterDecayRate.Medium="Medio (tipo I PPM)" +Basic.Settings.Audio.MeterDecayRate.Slow="Lento (tipo II PPM)" +Basic.Settings.Audio.PeakMeterType="Tipo de medidor de pico" +Basic.Settings.Audio.PeakMeterType.SamplePeak="Pico da mostraxe" +Basic.Settings.Audio.PeakMeterType.TruePeak="Pico verdadeiro (maior uso de CPU)" +Basic.Settings.Audio.MultiChannelWarning.Enabled="AVISO: O son envolvente está activado." +Basic.Settings.Audio.MultichannelWarning="Se se emite, comprobe se o servizo de emisión admite a inxección e a reprodución de son envolvente. Facebook 360 Live, Mixer RTMP, Smashcast son exemplos onde o son envolvente é totalmente compatíbel. Aínda que Facebook Live e YouTube Live aceptan a inxección de son envolvente, Facebook Live remestura a estéreo e YouTube Live reproduce só dúas canles.\n\nOs filtros de son do OBS son compatíbeis co son envolvente, aínda que non está garantida a compatibilidade co engadido VST." +Basic.Settings.Audio.MultichannelWarning.Title="Activar o son envolvente?" +Basic.Settings.Audio.MultichannelWarning.Confirm="Confirma que quere activar o son envolvente?" +Basic.Settings.Audio.Devices="Dispositivos" +Basic.Settings.Audio.DesktopDevice="Son do escritorio" +Basic.Settings.Audio.DesktopDevice2="Son do escritorio 2" +Basic.Settings.Audio.AuxDevice="Son micro/auxiliar" +Basic.Settings.Audio.AuxDevice2="Son micro/auxiliar 2" +Basic.Settings.Audio.AuxDevice3="Son micro/auxiliar 3" +Basic.Settings.Audio.AuxDevice4="Son micro/auxiliar 4" +Basic.Settings.Audio.EnablePushToMute="Activar Premer para silenciar" +Basic.Settings.Audio.PushToMuteDelay="Atraso de Premer para falar" +Basic.Settings.Audio.EnablePushToTalk="Activar Premer para falar" +Basic.Settings.Audio.PushToTalkDelay="Atraso de Premer para falar" +Basic.Settings.Audio.UnknownAudioDevice="[Dispositivo sen conectar ou non dispoñíbel]" +Basic.Settings.Audio.Disabled="Desactivado" Basic.Settings.Advanced="Avanzado" -Basic.Settings.Advanced.Audio.BufferingTime="Tempo do búfer de audio" +Basic.Settings.Advanced.General.ProcessPriority="Prioridade do proceso" +Basic.Settings.Advanced.General.ProcessPriority.High="Alta" +Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Por riba do normal" +Basic.Settings.Advanced.General.ProcessPriority.Normal="Normal" +Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Por baixo do normal" +Basic.Settings.Advanced.General.ProcessPriority.Idle="Inactivo" +Basic.Settings.Advanced.FormatWarning="Aviso: Os formatos de cor distintos de NV12 están destinados principalmente á gravación e non se recomendan durante unha emisión. A emisión pode sufrir un maior uso da CPU debido á conversión do formato da cor." +Basic.Settings.Advanced.Audio.BufferingTime="Tempo da memoria temporal de son" Basic.Settings.Advanced.Video.ColorFormat="Formato da cor" +Basic.Settings.Advanced.Video.ColorSpace="Espazo de cor" +Basic.Settings.Advanced.Video.ColorRange="Gama de cores" Basic.Settings.Advanced.Video.ColorRange.Partial="Parcial" -Basic.Settings.Advanced.Video.ColorRange.Full="Completo" +Basic.Settings.Advanced.Video.ColorRange.Full="Total" +Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositivo de monitorización" +Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Predeterminado" +Basic.Settings.Advanced.Audio.DisableAudioDucking="Desactivar a atenuación de son en Windows" +Basic.Settings.Advanced.StreamDelay="Atraso da emisión" +Basic.Settings.Advanced.StreamDelay.Duration="Duración" +Basic.Settings.Advanced.StreamDelay.Preserve="Preservar o punto de corte (aumento do atraso) ao volver conectar" +Basic.Settings.Advanced.StreamDelay.MemoryUsage="Uso estimado da memoria: %1 MB" +Basic.Settings.Advanced.Network="Rede" +Basic.Settings.Advanced.Network.BindToIP="Ligar co IP" +Basic.Settings.Advanced.Network.EnableNewSocketLoop="Activar o novo código de rede" +Basic.Settings.Advanced.Network.EnableLowLatencyMode="Modo de baixa latencia" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Comportamento das teclas rápidas en foco" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Non desactivar nunca as teclas rápidas" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Desactivar as teclas rápidas cando a xanela principal estea en foco" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Desactivar as teclas rápidas cando a xanela principal non estea en foco" +Basic.Settings.Advanced.AutoRemux="Converter automaticamente a mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(gravar como mkv)" -Basic.AdvAudio="Propiedades de audio avanzadas" +Basic.AdvAudio="Propiedades de son avanzadas" Basic.AdvAudio.Name="Nome" -Basic.AdvAudio.Mono="Remesturar a mono" -Basic.AdvAudio.SyncOffset="Sincronización Offset (ms)" +Basic.AdvAudio.Volume="Volume" +Basic.AdvAudio.Mono="Mono" +Basic.AdvAudio.Balance="Balance" +Basic.AdvAudio.SyncOffset="Desprazamento da sincronización" +Basic.AdvAudio.Monitoring="Monitorización do son" +Basic.AdvAudio.Monitoring.None="Monitor apagado" +Basic.AdvAudio.Monitoring.MonitorOnly="Só o monitor (silenciar a saída)" +Basic.AdvAudio.Monitoring.Both="Monitor e saída" Basic.AdvAudio.AudioTracks="Pistas" +Basic.Settings.Hotkeys="Teclas rápidas" +Basic.Settings.Hotkeys.Pair="As combinacións de teclas compartidas con «%1» actúan como conmutadores" +Basic.Settings.Hotkeys.Filter="Filtro" +Basic.Hotkeys.SelectScene="Cambiar á escena" +Basic.SystemTray.Show="Amosar" +Basic.SystemTray.Hide="Agochar" +Basic.SystemTray.Message.Reconnecting="Sen conexión, reconectando..." Hotkeys.Insert="Inserir" Hotkeys.Delete="Eliminar" Hotkeys.Home="Inicio" -Hotkeys.NumLock="BLOQ NÚM" -Hotkeys.ScrollLock="BLOQ DESPR" -Hotkeys.CapsLock="BLOQ MAIÚS" +Hotkeys.End="Fin" +Hotkeys.PageUp="Re Páx" +Hotkeys.PageDown="Av Páx" +Hotkeys.NumLock="Block Num" +Hotkeys.ScrollLock="Bloq Despr" +Hotkeys.CapsLock="Bloq Maiús" Hotkeys.Backspace="Retroceso" -Hotkeys.Tab="Tabulación" +Hotkeys.Tab="Tab" Hotkeys.Print="Imprimir" +Hotkeys.Pause="Pausa" +Hotkeys.Left="Esquerda" +Hotkeys.Right="Dereita" +Hotkeys.Up="Arriba" +Hotkeys.Down="Abaixo" Hotkeys.Windows="Windows" +Hotkeys.Super="Súper" Hotkeys.Menu="Menú" Hotkeys.Space="Espazo" Hotkeys.NumpadNum="Teclado numérico %1" @@ -390,20 +834,45 @@ Hotkeys.AppleKeypadSubtract="- (teclado numérico)" Hotkeys.AppleKeypadDecimal=". (teclado numérico)" Hotkeys.AppleKeypadEqual="= (teclado numérico)" Hotkeys.MouseButton="Rato %1" +Hotkeys.Escape="Esc" Mute="Silenciar" Unmute="Activar son" +Push-to-mute="Premer para silenciar" +Push-to-talk="Premer para falar" -SceneItemShow="Mostrar '%1'" -SceneItemHide="Agochar '%1'" +SceneItemShow="Amosar «%1»" +SceneItemHide="Agochar «%1»" -OutputWarnings.NoTracksSelected="Debes seleccionar, cando menos, unha pista" +OutputWarnings.NoTracksSelected="Debe seleccionar, cando menos, unha pista" OutputWarnings.MultiTrackRecording="Aviso: certos formatos (caso de FLV) non admiten múltiples pistas para gravar" +OutputWarnings.MP4Recording="Aviso: as gravacións gardadas en MP4/MOV non serán recuperábeis se non se pode rematar o ficheiro (por exemplo, como resultado de BSOD, perdas de enerxía, etc.). Se quere gravar varias pistas de son, considere empregar MKV e converter a gravación a MP4/MOV unha vez rematada (Ficheiro → Gravacións de conversións)" +OutputWarnings.CannotPause="Aviso: Non é posíbel deter as gravacións se está estabelecido o codificador da gravación «(Utilizar o codificador da emisión)»" +FinalScene.Title="Eliminar escena" +FinalScene.Text="Debe haber polo menos unha escena." +NoSources.Title="Non hai fontes" +NoSources.Text="Parece que aínda non engadiu ningunha fonte de vídeo, polo que a saída será unha pantalla en branco. É iso o que quere facer?" +NoSources.Text.AddSource="Pode engadir fontes premendo na icona + baixo a caixa Fontes na xanela principal en calquera momento." +NoSources.Label="Non ten ningunha fonte.\nPrema no botón + de embaixo,\nou prema co botón dereito do rato para engadir unha." +ChangeBG="Establecer a cor" +CustomColor="Cor personalizada" +BrowserSource.EnableHardwareAcceleration="Activar a aceleración do hardware de fontes no navegador" +About="Sobre" +About.Info="OBS Studio é un software libre para gravación e emisión ao vivo." +About.Donate="Fai a túa achega" +About.GetInvolved="Colabora" +About.Authors="Autoría" +About.License="Licenza" +About.Contribute="Apoia o Proxecto OBS" +ResizeOutputSizeOfSource="Axustar o tamaño da saída (tamaño da fonte)" +ResizeOutputSizeOfSource.Text="As resolucións de base e saída redimensionaranse ao tamaño da fonte actual." +ResizeOutputSizeOfSource.Continue="Quere continuar?" +PreviewTransition="Vista previa da transición" diff --git a/UI/data/locale/he-IL.ini b/UI/data/locale/he-IL.ini index 5cf71f4..d503d56 100644 --- a/UI/data/locale/he-IL.ini +++ b/UI/data/locale/he-IL.ini @@ -23,7 +23,7 @@ Settings="הגדרות" Display="תצוגה" Name="שם" Exit="יציאה" -Mixer="מיקסר" +Mixer="מערבל שמע" Browse="עיון" Mono="מונו" Stereo="סטריאו" @@ -78,22 +78,46 @@ None="ללא" StudioMode.Preview="תצוגה מקדימה" StudioMode.Program="תוכנה" ShowInMultiview="הראה בתצוגה מרובה" +VerticalLayout="פריסה אנכית" Group="קבוצה" +DoNotShowAgain="אל תציג שוב" +Default="(ברירת מחדל)" +Calculating="מחשב..." AlreadyRunning.Title="OBS פועל כבר" AlreadyRunning.Text="OBS פועל כבר! אלא אם התכוונת לעשות את זה, אנא סגור כל מופע קיים לפני נסיון להפעיל מופע חדש. אנא בדוק אם קיים מופע הגדר ממוזער במגש המערכת." AlreadyRunning.LaunchAnyway="הפעל בכל מקרה" +DockCloseWarning.Title="סגירת חלון ניתן להצמדה" +DockCloseWarning.Text="סגרת עכשיו חלון הניתן להצמדה. אם ברצונך להציג אותו שוב, השתמש בתפריט תצוגה -> הצמדות בשורת התפריט." +ExtraBrowsers="חלונות הצמדה מותאמים אישית של דפדפן" +ExtraBrowsers.Info="הוסף חלונות הצמדה על ידי שם ו-URL, ואז לחץ אישור או סגור כדי לפתוח את חלונות ההצמדה. תוכל להוסיף או להסיר חלונות הצמדה בכל זמן." +ExtraBrowsers.DockName="שם חלון ההצמדה" + +Auth.Authing.Title="מאמת..." +Auth.Authing.Text="מאמת עם %1, אנא המתן..." Auth.AuthFailure.Title="האימות נכשל" +Auth.AuthFailure.Text="נכשל באימות עם %1:\n\n%2: %3" Auth.InvalidScope.Title="דרושה הזדהות" +Auth.InvalidScope.Text="דרישות האימות עבור %1 השתנו. חלק מהתכונות לא יהיו זמינות." +Auth.LoadingChannel.Title="טוען מידע על הערוץ..." +Auth.LoadingChannel.Text="טוען מידע על הערוץ עבור %1, אנא המתן..." Auth.ChannelFailure.Title="נכשל בטעינת הערוצים" +Auth.ChannelFailure.Text="נכשל בטעינת המידע עבור %1\n\n%2: %3" Auth.Chat="צ'אט" Auth.StreamInfo="מידע על הזרם" +TwitchAuth.Stats="סטטיסטיקות Twitch" +TwitchAuth.Feed="אירועי Twitch אחרונים" +TwitchAuth.TwoFactorFail.Title="לא ניתן לשלוף מפתח שידור" +TwitchAuth.TwoFactorFail.Text="OBS לא הצליחה להתחבר לחשבון ה-Twitch שלך. אנא ודא/י כי אימות דו-שלבי מוגדר ב-הגדרות האבטחה שלך ב-Twitch מכיוון וזוהי דרישה לשידור." +RestreamAuth.Channels="ערוצי Restream" Copy.Filters="העתק מסננים" Paste.Filters="הדבק מסננים" +BrowserPanelInit.Title="מאתחל דפדפן..." +BrowserPanelInit.Text="מאתחל דפדפן, אנא המתן..." BandwidthTest.Region="אזור" BandwidthTest.Region.US="ארצות הברית" @@ -120,13 +144,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 או 30, אבל העדף רזו Basic.AutoConfig.VideoPage.CanvasExplanation="הערה: רזוליית הבד (בסיס) הוא לא בהכרח זהה לרזולוצי ההזרמה או הקלטה. ייתכן שרזולוציית הזרמה/הקלטה תוקטן בכדי להפחית את דרישות קצב הנתונים או המשאבים." Basic.AutoConfig.StreamPage="מידע על הזרם" Basic.AutoConfig.StreamPage.SubTitle="אנא הזן את פרטי הזרם" -Basic.AutoConfig.StreamPage.ConnectAccount="התחבר לחשבון (אופציונלי)" +Basic.AutoConfig.StreamPage.ConnectAccount="התחבר לחשבון (מומלץ)" Basic.AutoConfig.StreamPage.DisconnectAccount="נתק את חשבון" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="נתק את חשבון?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="שינוי זה יחול באופן מיידי. האם אתה בטוח שברצונך לנתק את החשבון שלך?" Basic.AutoConfig.StreamPage.UseStreamKey="השתמש במפתח הזרמת נתונים" Basic.AutoConfig.StreamPage.Service="שירות" Basic.AutoConfig.StreamPage.Service.ShowAll="הצג הכל..." +Basic.AutoConfig.StreamPage.Service.Custom="מותאם אישית..." Basic.AutoConfig.StreamPage.Server="שרת" Basic.AutoConfig.StreamPage.StreamKey="מפתח הזרמת נתונים" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(קישור)" @@ -154,6 +179,7 @@ Basic.AutoConfig.TestPage.Result.Footer="כדי להשתמש בהגדרות אל Basic.Stats="סטטיסטיקות" Basic.Stats.CPUUsage="שימוש במעבד" +Basic.Stats.HDDSpaceAvailable="שטח דיסק פנוי" Basic.Stats.MemoryUsage="שימוש בזיכרון" Basic.Stats.AverageTimeToRender="הזמן הממוצע לעיבוד מסגרת" Basic.Stats.SkippedFrames="המערכת דילגה על מסגרות עקב השהית קידוד" @@ -168,7 +194,10 @@ Basic.Stats.Status.Inactive="לא פעיל" Basic.Stats.DroppedFrames="השמטת מסגרות (רשת)" Basic.Stats.MegabytesSent="פלט נתונים כולל" Basic.Stats.Bitrate="קצב נתונים" +Basic.Stats.DiskFullIn="דיסק מלא בעוד (לערך)" +ResetUIWarning.Title="האם את/ה בטוח/ה שברצונך לאפס את התצוגה?" +ResetUIWarning.Text="איפוס התצוגה יחביא חלונות הצמדה נוספים. תוכל לחשוף את חלונות ההצמדה מתפריט התצוגה אם ברצונך להציג אותם.\n\nהאם את/ה בטוח/ה שברצונך לאפס את התצוגה?" Updater.Title="עידכון חדש זמין" Updater.Text="יש עדכון חדש זמין:" @@ -181,6 +210,7 @@ Updater.NoUpdatesAvailable.Title="אין עדכונים זמינים" Updater.NoUpdatesAvailable.Text="אין עדכונים זמינים כעת" Updater.FailedToLaunch="נכשלה הפעלת העידכון" Updater.GameCaptureActive.Title="לכידת משחק פעיל" +Updater.GameCaptureActive.Text="ספריית לכידת משחק נמצאת בשימוש כרגע. יש לסגור משחקים/תוכנות בלכידה (או לבצע הפעלה מחדש ל-Windows) ולנסות שוב." QuickTransitions.SwapScenes="החלף סצינות תצוגה מקדימה/פלט לאחר המעבר" QuickTransitions.SwapScenesTT="החלף הסצינות של התצוגה המקדימה ושל הפלט לאחר המעבר (באם הסצינה המקורית של הפלט עדיין קיימת). \n פעולה זו לא תבטל כל שינוי שייתכן ובוצע לסצינה המקורית של הפלט." @@ -215,6 +245,11 @@ ConfirmStart.Text="האם אתה בטוח שברצונך להפעיל את הז ConfirmStop.Title="עצור את הזרמת הנתונים?" ConfirmStop.Text="האם אתה בטוח שברצונך להפסיק את הזרמת הנתונים?" +ConfirmStopRecord.Title="עצור הקלטה?" +ConfirmStopRecord.Text="האם את/ה בטוח/ה שברצונך לעצור את ההקלטה?" + +ConfirmBWTest.Title="האם ברצונך להתחיל בדיקת רוחב פס?" +ConfirmBWTest.Text="הגדרת את OBS למצב בדיקת רוחב פס. מצב זה מאפשר בדיקת רשת בלי שהערוץ שלך ישדר. כאשר תסיים את הבדיקה, עליך לבטל מצב זה על מנת שצופיך יוכלו לצפות בשידור.\n\nהאם ברצונך להמשיך?" ConfirmExit.Title="יציאה מ-OBS?" ConfirmExit.Text="תוכנת OBS פעילה כעת. כל הזרמת נתונים/הקלטות ייסגרו. האם אתה בטוח שאתה רוצה לצאת?" @@ -228,6 +263,8 @@ Output.StartRecordingFailed="נכשלה הפעלת הקלטה" Output.StartReplayFailed="נכשלה הפעלת מאגר החוזר" Output.StartFailedGeneric="הפלט נכשל. בבקשה בדוק את הרישומים עבור. \n\nNote: אם אתה משתמש בNVNEC או AMD מקודדים, הקפד שמנהלי ההתקן של הכרטיס מסך מעודכנים." +Output.ReplayBuffer.PauseWarning.Title="לא ניתן לשמור הילוכים חוזרים בזמן השהיה" +Output.ReplayBuffer.PauseWarning.Text="אזהרה: הילוכים חוזרים לא ניתנים לשמירה כאשר ההקלטה מושהית." Output.ConnectFail.Title="ההתחברות נכשלה" Output.ConnectFail.BadPath="URL לא חוקי של נתיב או חיבור. נא בדוק את ההגדרות שלך כדי לוודא כי הם נכונים." @@ -236,6 +273,8 @@ Output.ConnectFail.InvalidStream="לא ניתן להתחבר לערוץ שצוי Output.ConnectFail.Error="אירעה שגיאה בלתי צפויה בעת ניסיון להתחבר לשרת. מידע נוסף בקובץ יומן הרישום." Output.ConnectFail.Disconnected="התנתקת מהשרת." +Output.StreamEncodeError.Title="שגיאת קידוד" +Output.StreamEncodeError.Msg="התרחשה שגיאת מקודד בזמן שידור." Output.RecordFail.Title="התחלת ההקלטה נכשלה" Output.RecordFail.Unsupported="תבנית הפלט לא נתמכת או לא תומכת ביותר מרצועת שמע אחת. נא בדוק את ההגדרות ונסה שוב." @@ -243,6 +282,7 @@ Output.RecordNoSpace.Title="אין די שטח דיסק" Output.RecordNoSpace.Msg="אין די שטח דיסק כדי להמשיך הקלטה." Output.RecordError.Title="שגיאה הקלטה" Output.RecordError.Msg="אירעה שגיאה לא מוגדרת בזמן ההקלטה." +Output.RecordError.EncodeErrorMsg="התרחשה שגיאת מקודד בזמן הקלטה." Output.ReplayBuffer.NoHotkey.Title="אין מקש קיצור שנבחר!" Output.ReplayBuffer.NoHotkey.Msg="אין hotkey שמור למאגר החוזר. בבקשה הגדר את \"שמור\" hotkey לשימוש עבור שמירת מאגר חוזר להקלטות." @@ -256,12 +296,20 @@ LogReturnDialog.ErrorUploadingLog="עידכון קובץ יומן נכשל" Remux.SourceFile="הקלטת OBS" Remux.TargetFile="קובץ היעד" Remux.Remux="המרה" +Remux.Stop="עצור המרה" +Remux.ClearFinished="רוקן פריטים שהסתיימו" +Remux.ClearAll="רוקן את כל הפריטים" Remux.OBSRecording="הקלטת OBS" Remux.FinishedTitle="המרה הסתיימה" Remux.Finished="הקלטה הומרה" Remux.FinishedError="הקלטה הומרה, אבל הקובץ עשוי להיות לא שלם" +Remux.SelectRecording="בחר הקלטת OBS..." +Remux.SelectTarget="בחר קובץ יעד..." +Remux.FileExistsTitle="קבצי יעד קיימים כבר" +Remux.FileExists="קבצי היעד שלהלן כבר קיימים. האם ברצונך להחליפם?" Remux.ExitUnfinishedTitle="המרה בתהליך" Remux.ExitUnfinished="ההמרה לא הסתיימה, עצירה עכשיו עלולה להפוך את קובץ היעד לא שמיש. \n אתה בטוח שאתה רוצה לעצור את ההמרה?" +Remux.HelpText="גרור קבצים להמרה לחלון זה, או בחר בתא \"הקלטת OBS\" בכדי לבחור קובץ ידנית." UpdateAvailable="עידכון חדש זמין" UpdateAvailable.Text="גירסה %1.%2.%3 זמין כעת. לחץ כאן כדי להוריד" @@ -278,12 +326,14 @@ Basic.DisplayCapture="הצג לכידת מסך" Basic.Main.PreviewConextMenu.Enable="אפשר תצוגה מקדימה" +Basic.Main.Preview.Disable="בטל תצוגה מקדימה" ScaleFiltering="מסנן קנה מידה" ScaleFiltering.Point="נקודה" ScaleFiltering.Bilinear="ביליניארי" ScaleFiltering.Bicubic="ביקיוביק" ScaleFiltering.Lanczos="לנזוס" +ScaleFiltering.Area="אזור" Deinterlacing="ביטול שזירה" Deinterlacing.Discard="אל תשמור" @@ -535,7 +585,6 @@ Basic.Settings.Output.Mode.Simple="פשוט" Basic.Settings.Output.Mode.Adv="מתקדם" Basic.Settings.Output.Mode.FFmpeg="פלט FFmpeg" Basic.Settings.Output.UseReplayBuffer="הפעלת מאגר החוזר" -Basic.Settings.Output.ReplayBuffer.SecondsMax="זמן החוזר המרבי (בשניות)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="זיכרון מרבי (מגה-בתים)" Basic.Settings.Output.ReplayBuffer.Estimate="הערך שימוש בזיכרון: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="אין אפשרות להעריך את השימוש בזיכרון. נא הגדר מגבלת זיכרון מירבי." @@ -562,7 +611,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="תוכנה (x 264 השימ Basic.Settings.Output.VideoBitrate="קצב סיביות וידאו" Basic.Settings.Output.AudioBitrate="קצב סיביות שמע" Basic.Settings.Output.Reconnect="חיבור מחדש באופן אוטומטי" -Basic.Settings.Output.RetryDelay="נסה שנית השהייה (שניות)" Basic.Settings.Output.MaxRetries="מרב נסינות" Basic.Settings.Output.Advanced="אפשר הגדרות מקודד מתקדמות" Basic.Settings.Output.CustomEncoderSettings="הגדרות מקודד מותאמות אישית" @@ -632,7 +680,7 @@ Basic.Settings.Video.DisableAero="בטל את ממשק Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="דו-ליניארי (מהיר ביותר, מטושטש בשינוי קנה מידה)" Basic.Settings.Video.DownscaleFilter.Bicubic="ממוצע משוקלל (חד בשינוי קנה המידה, 16 דגימות)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (חד בשינוי קנה המידה, 32 דגימות)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (חד בשינוי קנה המידה, 36 דגימות)" Basic.Settings.Audio="אודיו" Basic.Settings.Audio.SampleRate="קצב דגימה" @@ -641,7 +689,6 @@ Basic.Settings.Audio.MeterDecayRate.Fast="מהיר" Basic.Settings.Audio.MeterDecayRate.Medium="בינוני (סוג I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="איטי (סוג II PPM)" Basic.Settings.Audio.MultiChannelWarning.Enabled="אזהרה: שמע צליל היקפי מאופשר." -Basic.Settings.Audio.MultichannelWarning="אם הזרימה, בדוק את הזרמת השירות תומך בסראונד סאונד להבלע ואת היקפי הסראונד פלייבק. טוויץ',פייסבוק,360 Liev, מיקסר RTMP, Smashcast דוגמאות לאיפה שסראונד סאונד הוא נתמך. למרות פייסבוק לייב ויוטיוב לייב שניהם מאפשרים סראונד להבלע, פייסבוק לייב משנה לסטריאו ויוטיוב לייב מפעיל בשני ערוצים. \n\nOBS Studio מסנן עם הסראונד סאונד, למרות תמיכת תוסף VST אינו מאובטח." Basic.Settings.Audio.MultichannelWarning.Title="האם להפעיל שמע צליל היקפי?" Basic.Settings.Audio.MultichannelWarning.Confirm="אתה בטוח שאתה רוצה לאפשר קול שמע מקיף?" Basic.Settings.Audio.EnablePushToMute="אפשר לחץ-להשתקה" @@ -665,7 +712,7 @@ Basic.Settings.Advanced.Video.ColorRange.Full="מלא" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="ברירת מחדל" Basic.Settings.Advanced.Audio.DisableAudioDucking="בטל צימוד השמע של Windows" Basic.Settings.Advanced.StreamDelay="השהיית זרם נתונים" -Basic.Settings.Advanced.StreamDelay.Duration="משך זמן (בשניות)" +Basic.Settings.Advanced.StreamDelay.Duration="משך זמן" Basic.Settings.Advanced.StreamDelay.Preserve="שמר נקודת חיתוך (השהייה מוגדלת) בעת חיבור מחדש" Basic.Settings.Advanced.StreamDelay.MemoryUsage="שימוש זיכרון משוער: %1 MB" Basic.Settings.Advanced.Network="רשת" @@ -675,9 +722,7 @@ Basic.Settings.Advanced.Network.EnableLowLatencyMode="מצב השהיה נמוך Basic.AdvAudio="מאפייני קול מתקדמים" Basic.AdvAudio.Name="שם" -Basic.AdvAudio.Mono="הפוך למונו" Basic.AdvAudio.Balance="איזון" -Basic.AdvAudio.SyncOffset="היסט סינכרון (מילישניות)" Basic.AdvAudio.Monitoring="ניטור אודיו" Basic.AdvAudio.Monitoring.None="בטל ניתור" Basic.AdvAudio.Monitoring.MonitorOnly="ניתור בלבד (השתק פלט)" diff --git a/UI/data/locale/hi-IN.ini b/UI/data/locale/hi-IN.ini index 481828e..292c0db 100644 --- a/UI/data/locale/hi-IN.ini +++ b/UI/data/locale/hi-IN.ini @@ -8,46 +8,102 @@ Cancel="रद्द करें" Close="बंद करें" Save="सहेजें" Discard="छोड़ें" +Disable="अक्षम" Yes="हां" No="नहीं" Add="जोड़ें" Remove="निकालें" Rename="नाम बदलें" Interact="बातचीत" +Filters="फिल्टर" +Properties="विशेषताएं" MoveUp="ऊपर ले जाएँ" MoveDown="नीचे ले जाएँ" Settings="सेटिंग्स" Display="प्रदर्शन" Name="नाम" Exit="निकास" +Mixer="मिक्सर" +Browse="ब्राउज करें" +Mono="मोनो" +Stereo="स्टीरियो" +DroppedFrames="हटाए गए फ़्रेम %1 (%2%)" +StudioProgramProjector="फुलस्क्रीन प्रोजेक्टर (कार्यक्रम)" +PreviewProjector="फुलस्क्रीन प्रोजेक्टर (प्राभ्यास)" +SceneProjector="फुलस्क्रीन प्रोजेक्टर (दृश्य)" +SourceProjector="फुलस्क्रीन प्रोजेक्टर (स्रोत)" +StudioProgramWindow="विंडो प्रोजेक्टर (कार्यक्रम)" +PreviewWindow="विंडो प्रोजेक्टर (प्राभ्यास)" +SceneWindow="विंडो प्रोजेक्टर (दृश्य)" +SourceWindow="विंडो प्रोजेक्टर (स्रोत)" +MultiviewProjector="मल्टीव्यू (फुलस्क्रीन)" +MultiviewWindowed="मल्टीव्यू (विंडो)" Clear="साफ़ करें" Revert="पहले जैसा करें" Show="दिखाएँ" Hide="छुपायें" UnhideAll="कुछ ना छिपाएं" +Untitled="अनामांकित" New="नया" Duplicate="दोहरा" +Enable="सक्षम करें" +DisableOSXVSync="OSX V-Sync अक्षम करें" +Transition="संक्रमण" +QuickTransitions="त्वरित संक्रमण" Left="बाएं" Right="दाएँ" Top="शीर्ष" Bottom="नीचे" +Reset="रीसेट" Hours="घंटे" Minutes="मिनट" Seconds="सेकंड" +Deprecated="पदावनत" +ReplayBuffer="फिर से बफर चलाएं" +Import="आयात" +Export="निर्यात करें" Copy="प्रतिलिपि" Paste="चिपकाएँ" Next="अगले" Back="वापस" +VerticalLayout="लंबरूप लेआउट" +Group="एकत्रित करना" +DoNotShowAgain="फिर से मत दिखाना" +Default="(डिफ़ॉल्ट)" +Calculating="गणना जारी है" + +AlreadyRunning.Title="OBS चल रहा है" +AlreadyRunning.Text="OBS पहले से ही चल रहा है! अगर आप ऐसा नहीं करना चाहते हैं, कृपया एक नया उदाहरण चलाने की कोशिश करने से पहले OBS के किसी भी मौजूदा उदाहरण को बंद कर दें। यदि आपके पास सिस्टम ट्रे को कम करने के लिए OBS सेट है, तो कृपया जांचें कि क्या यह अभी भी वहां चल रहा है।" +AlreadyRunning.LaunchAnyway="फिर भी लॉन्च करें" +BandwidthTest.Region="क्षेत्र" +BandwidthTest.Region.US="संयुक्त राज्य अमेरिका" +BandwidthTest.Region.EU="यूरोप" BandwidthTest.Region.Asia="एशिया" +BandwidthTest.Region.Other="अन्य" +Basic.FirstStartup.RunWizard.NoClicked="यदि आप अपनी पसंद बदलते हैं, तो आप किसी भी समय टूल मेनू से ऑटो-कॉन्फ़िगरेशन विज़ार्ड चला सकते हैं।" +Basic.AutoConfig="ऑटो-कॉन्फ़िगरेशन विज़ार्ड" +Basic.AutoConfig.ApplySettings="सेटिंग लागू करें" +Basic.AutoConfig.StartPage="उपयोग की जानकारी" +Basic.AutoConfig.StartPage.SubTitle="किस प्रोग्राम के लिए उपयोग करना चाहते हैं निर्दिष्ट करें" +Basic.AutoConfig.StartPage.PrioritizeStreaming="स्ट्रीमिंग के लिए ऑप्टिमाइज़ करना, रिकॉर्डिंग अप्रधान है" +Basic.AutoConfig.StartPage.PrioritizeRecording="केवल रिकॉर्डिंग के लिए ऑप्टिमाइज़ करें, मैं स्ट्रीमिंग नहीं करूंगा" +Basic.AutoConfig.StreamPage.Service="सेवा" +Basic.AutoConfig.StreamPage.Service.ShowAll="सब दिखाओ" +Basic.AutoConfig.StreamPage.Service.Custom="अनुकूलित करें" +Basic.AutoConfig.StreamPage.Server="सर्वर" +Basic.AutoConfig.StreamPage.StreamKey="स्ट्रीमिंग चाबी" +Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(लिंक)" +Basic.Stats.CPUUsage="सि पि यु का उपयोग" +Basic.Stats.HDDSpaceAvailable="डिस्क में जगह उपलब्ध है" @@ -98,9 +154,14 @@ BandwidthTest.Region.Asia="एशिया" +Basic.Main.PauseRecording="रिकॉर्डिंग रोकें" +Basic.MainMenu.View="दृश्य" +Basic.MainMenu.View.Toolbars="टूलबार" +Basic.MainMenu.View.Docks="डॉक" + diff --git a/UI/data/locale/hr-HR.ini b/UI/data/locale/hr-HR.ini index 168b819..bc71f24 100644 --- a/UI/data/locale/hr-HR.ini +++ b/UI/data/locale/hr-HR.ini @@ -23,7 +23,6 @@ Settings="Postavke" Display="Zaslon" Name="Ime" Exit="Izlaz" -Mixer="Mikseta" Browse="Pretraži" Mono="Mono" Stereo="Stereo" @@ -84,6 +83,7 @@ AlreadyRunning.Text="OBS je već pokrenut! Osim ako si mislio da biste to učini AlreadyRunning.LaunchAnyway="Svejedno pokreni" + Auth.Authing.Title="Autentikacija..." Auth.Authing.Text="Autentikacija na %1, molimo pričekajte..." Auth.AuthFailure.Title="Greška kod autentikacije" @@ -175,6 +175,7 @@ ConfirmStop.Title="Zaustavi stream?" ConfirmStop.Text="Jeste li sigurni da želite zaustaviti stream?" + ConfirmExit.Title="Napustiti OBS?" ConfirmExit.Text="OBS je trenutačno aktivan. Svi streamovi/snimanja bit će ugašeni. Jeste li sigurni da želite izaći?" @@ -486,7 +487,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softverski (x264 niska upot Basic.Settings.Output.VideoBitrate="Protok videa" Basic.Settings.Output.AudioBitrate="Protok zvuka" Basic.Settings.Output.Reconnect="Automatski poveži ponovo" -Basic.Settings.Output.RetryDelay="Pauza pre ponovnog pokušaja (sekunde)" Basic.Settings.Output.MaxRetries="Maksimalan broj ponovnih pokušaja" Basic.Settings.Output.Advanced="Omogući napredna podešavanja kompresora" Basic.Settings.Output.CustomEncoderSettings="Prilagođena enkoder podešavanja" @@ -552,7 +552,7 @@ Basic.Settings.Video.DisableAero="Onemogući Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (najbrže, ali mutno pri skaliranju)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (oštrije skaliranje, 16 uzoraka)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (oštrije skaliranje, 32 uzorka)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (oštrije skaliranje, 36 uzorka)" Basic.Settings.Audio="Zvuk" Basic.Settings.Audio.SampleRate="Protok" @@ -575,7 +575,6 @@ Basic.Settings.Advanced.Video.ColorFormat="Format boja" Basic.Settings.Advanced.Video.ColorRange.Partial="Delimično" Basic.Settings.Advanced.Video.ColorRange.Full="Potpuno" Basic.Settings.Advanced.StreamDelay="Odlaganje strima" -Basic.Settings.Advanced.StreamDelay.Duration="Trajanje (sekunde)" Basic.Settings.Advanced.StreamDelay.Preserve="Očuvaj tačku prekidanja (povećava odlaganje) kada se ponovo povezuje" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Procenjena upotreba memorije: %1 MB" Basic.Settings.Advanced.Network="Mreža" @@ -583,8 +582,6 @@ Basic.Settings.Advanced.Network.BindToIP="Veži se za IP" Basic.AdvAudio="Napredna podešavanja zvuka" Basic.AdvAudio.Name="Ime" -Basic.AdvAudio.Mono="Spoji u mono" -Basic.AdvAudio.SyncOffset="Razlika u sinhronizaciji (ms)" Basic.AdvAudio.AudioTracks="Izvori" Basic.Settings.Hotkeys="Prečice" diff --git a/UI/data/locale/hu-HU.ini b/UI/data/locale/hu-HU.ini index cdb851d..40aeba1 100644 --- a/UI/data/locale/hu-HU.ini +++ b/UI/data/locale/hu-HU.ini @@ -23,7 +23,7 @@ Settings="Beállítások" Display="Kijelző" Name="Név" Exit="Kilépés" -Mixer="Keverő" +Mixer="Hangkeverő" Browse="Tallózás" Mono="Mono" Stereo="Sztereó" @@ -91,6 +91,10 @@ AlreadyRunning.LaunchAnyway="Indítás mégis" DockCloseWarning.Title="Dokkolható ablak bezárása" DockCloseWarning.Text="Most zárt be egy dokkolható ablakot. Ha szeretné újra felfedni, akkor használja a Nézet -> Dokkolás menüt." +ExtraBrowsers="Egyedi tallózó dokkoló" +ExtraBrowsers.Info="Dokkolók hozzáadása egy név és URL megadásával, utána kattintson az Alkalmaz vagy Bezárás gombra a szerkesztéshez. Bármikor tud hozzáadni vagy eltávolítani dokkolókat." +ExtraBrowsers.DockName="Dokkoló neve" + Auth.Authing.Title="Hitelesítés..." Auth.Authing.Text="Hitelesítés %1 platformmal, kérjük várjon..." Auth.AuthFailure.Title="Hitelesítési hiba" @@ -107,6 +111,7 @@ TwitchAuth.Stats="Twitch statisztika" TwitchAuth.Feed="Twitch Tevékenységnapló" TwitchAuth.TwoFactorFail.Title="Nem lehetett a stream kulcsot lekérni" TwitchAuth.TwoFactorFail.Text="Az OBS nem tudott kapcsolódni a Twitch felhasználódhoz. Kérem ellenőrizze, hogy a kétfaktoros authentikációja be van állítva a Twitch biztonsági beállítások között, hiszen az szükséges az adáshoz." +RestreamAuth.Channels="Restream Csatornák" Copy.Filters="Szűrők másolása" Paste.Filters="Szűrők beillesztése" @@ -139,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 vagy 30, de inkább nagyobb fel Basic.AutoConfig.VideoPage.CanvasExplanation="Megjegyzés: A vászon (alap) felbontása nem feltétlenül ugyanaz, mint a stream vagy felvétel felbontása. A tényleges stream/felvétel felbontása esetlegesen lefele lesz skálázva az erőforrások leterheltsége vagy a bitsebesség követelmények elérése érdekében." Basic.AutoConfig.StreamPage="Stream információ" Basic.AutoConfig.StreamPage.SubTitle="Adja meg a stream információit" -Basic.AutoConfig.StreamPage.ConnectAccount="Felhasználó csatlakoztatása (Opcionális)" +Basic.AutoConfig.StreamPage.ConnectAccount="Felhasználó hozzákapcsolás (Ajánlott)" Basic.AutoConfig.StreamPage.DisconnectAccount="Felhasználó szétkapcsolása" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Felhasználó szétkapcsolása?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Ez a változtatás azonnal érvénybe lép. Biztosan megszakítja a kapcsolatot a fiókjával?" @@ -240,10 +245,13 @@ ConfirmStart.Text="Biztos benne, hogy elindítja a streamet?" ConfirmStop.Title="Stream megállítása?" ConfirmStop.Text="Biztos benne, hogy leállítja a streamet?" +ConfirmStopRecord.Title="Felvétel leállítása?" +ConfirmStopRecord.Text="Biztosan le kívánja állítani a felvételt?" + ConfirmBWTest.Title="Sávszélesség teszt indítása?" ConfirmBWTest.Text="Az OBS sávszélességteszt módra van konfigurálva. Ez a mód hálózattesztelésre van, anélkül működik, hogy élő adást kezdeményezne. Amint a vizsgálat lezajlott, úgy kikapcsolásra van szükség, hogy az adás a nézők számára is megjelenjen.\n\nSzeretné folytatni?" -ConfirmExit.Title="Kilép a programból?" +ConfirmExit.Title="Kilép az OBS-ből?" ConfirmExit.Text="Az OBS jelenleg aktív. Minden stream és/vagy felvétel le fog állni. Biztosan kilép?" ConfirmRemove.Title="Eltávolítás megerősítése" @@ -255,6 +263,8 @@ Output.StartRecordingFailed="Felvétel indítása sikertelen" Output.StartReplayFailed="Visszajátszás puffer indítása sikertelen" Output.StartFailedGeneric="Kimenet indítása sikertelen. Kérem ellenőrizze az eseménynaplóban a részleteket.\n\nMegjegyzés: NVENC vagy AMD kódoló használata esetén, győződjön meg róla, hogy az illesztőprogramok naprakészek!" +Output.ReplayBuffer.PauseWarning.Title="Szünet esetén nem lehet visszajátszást menteni" +Output.ReplayBuffer.PauseWarning.Text="Figyelmeztetés: Visszajátszást nem lehet menteni, amíg a felvétel szünetel." Output.ConnectFail.Title="Csatlakozás sikertelen" Output.ConnectFail.BadPath="Érvénytelen elérési út vagy kapcsolati URL cím. Kérem, ellenőrizze a beállításokat és győződjön meg az érvényességükről." @@ -444,6 +454,8 @@ Basic.Main.StartRecording="Felvétel indítása" Basic.Main.StartReplayBuffer="Visszajátszás puffer indítása" Basic.Main.StartStreaming="Stream indítása" Basic.Main.StopRecording="Felvétel leállítása" +Basic.Main.PauseRecording="Felvétel szüneteltetése" +Basic.Main.UnpauseRecording="Felvétel folytatása" Basic.Main.StoppingRecording="Felvétel leállítása..." Basic.Main.StopReplayBuffer="Visszajátszás puffer megállítása" Basic.Main.StoppingReplayBuffer="Visszajátszás puffer leáll..." @@ -502,6 +514,7 @@ Basic.MainMenu.View.Toolbars="Eszköz&tárak" Basic.MainMenu.View.Docks="Dokkolás" Basic.MainMenu.View.Docks.ResetUI="Felület újraindítása" Basic.MainMenu.View.Docks.LockUI="Felület zárása" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Egyedi tallózó dokkoló..." Basic.MainMenu.View.Toolbars.Listboxes="Gombsor (&L)" Basic.MainMenu.View.SceneTransitions="Jelenet átmenetek (&C)" Basic.MainMenu.View.StatusBar="Állapot&sor" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="Indításkor a frissítések automatik Basic.Settings.General.OpenStatsOnStartup="Statisztikai párbeszédpanel megnyitása indításkor" Basic.Settings.General.WarnBeforeStartingStream="Megerősítő párbeszédpanel megjelenítése stream indításakor" Basic.Settings.General.WarnBeforeStoppingStream="Megerősítő párbeszédpanel megjelenítése stream leállításakor" +Basic.Settings.General.WarnBeforeStoppingRecord="Megerősítő párbeszédpanel megjelenítése felvétel leállításakor" Basic.Settings.General.Projectors="Projektorok" Basic.Settings.General.HideProjectorCursor="Projektor nézetben a kurzor elrejtése" Basic.Settings.General.ProjectorAlwaysOnTop="Projektorok mindig legfelül" @@ -591,12 +605,15 @@ Basic.Settings.Output.Encoder="Kódoló" Basic.Settings.Output.SelectDirectory="Felvételi könyvtár kiválasztása" Basic.Settings.Output.SelectFile="Felvétel fájljának kiválasztása" Basic.Settings.Output.EnforceBitrate="Stream kiszolgáló bitsebesség korlátainak kényszerítése" +Basic.Settings.Output.DynamicBitrate="Dinamikus bitráta változtatás a hálózati terheléssel való megbirkózás érdekében" +Basic.Settings.Output.DynamicBitrate.Beta="Dinamikus bitráta változtatás a hálózati terheléssel való megbirkózás érdekében (Béta)" +Basic.Settings.Output.DynamicBitrate.TT="Hálózati terhelés esetén a képkockák eldobása helyett, dinamikusan változik a bitráta menet közben.\n\nTartsa észben, hogy ez növelheti a késleltetést ön és a nézők között, hogyha hirtelen megnövekszik a terhelés.\nAmikor a bitráta lezuhan, akár percekig is eltarthat, amíg helyreáll.\n\nAktuálisan csak RTMP használata esetén támogatott." Basic.Settings.Output.Mode="Kimeneti mód" Basic.Settings.Output.Mode.Simple="Egyszerű" Basic.Settings.Output.Mode.Adv="Haladó" Basic.Settings.Output.Mode.FFmpeg="FFmpeg kimenet" Basic.Settings.Output.UseReplayBuffer="Visszajátszás puffer engedélyezése" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximális visszajátszási idő (Másodperc)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximális Visszajátszási Idő" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximális memória (Megabájt)" Basic.Settings.Output.ReplayBuffer.Estimate="Becsült memóriaigény: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Nem lehet megbecsülni a memóriaigényt. Kérem állítson be egy maximális memória limitet." @@ -611,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Megkülönböztethetetlen min Basic.Settings.Output.Simple.RecordingQuality.Lossless="Veszteségmentes minőség, hatalmas fájlméret" Basic.Settings.Output.Simple.Warn.VideoBitrate="Figyelem: Az adás videó bitsebessége %1 értéken áll, ami a kiválasztott kiszolgáló felső határértéke. Amennyiben túl kívánja lépni a megadott %1 értéket, úgy engedélyezze a haladó kódolási opciókat és törölje a \"stream kiszolgáló bitsebesség korlátainak kényszerítése\" opciót." Basic.Settings.Output.Simple.Warn.AudioBitrate="Figyelem: Az adás audio bitsebessége %1 értéken áll, ami a kiválasztott kiszolgáló felső határértéke. Amennyiben túl kívánja lépni a megadott %1 értéket, úgy engedélyezze a haladó kódolási opciókat és törölje a \"stream kiszolgáló bitsebesség korlátainak kényszerítése\" opciót." +Basic.Settings.Output.Simple.Warn.CannotPause="Figyelmeztetés: A felvételeket nem lehet szüneteltetni, ha a felvétel minősége \"Ugyanaz mint a stream\"-re van állítva." Basic.Settings.Output.Simple.Warn.Encoder="Figyelem: A streamtől eltérő minőséggel történő rögzítés, további CPU erőforrásokat igényel, ha egyidejűleg használja mindkettőt." Basic.Settings.Output.Simple.Warn.Lossless="Figyelem: A veszteségmentes minőséggel történő felvétel hatalmas fájlméretet generál. Ezzel a minőséggel percenként akár 7 gigabájt adatot is generálhat nagy felbontáson és képkockasebességen. Ez az eljárás nem ajánlott hosszú felvételekhez, kivéve ha hatalmas lemezterület áll rendelkezésre." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Biztos benne, hogy veszteségmentes minőséget kíván használni?" @@ -623,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Szoftveres (x264 alacsony C Basic.Settings.Output.VideoBitrate="Videó bitsebesség" Basic.Settings.Output.AudioBitrate="Audio bitsebesség" Basic.Settings.Output.Reconnect="Automatikus újracsatlakozás" -Basic.Settings.Output.RetryDelay="Újrapróbálkozás késleltetése (másodperc)" +Basic.Settings.Output.RetryDelay="Újrapróbálási késleltetés" Basic.Settings.Output.MaxRetries="Újrapróbálkozások maximális száma" Basic.Settings.Output.Advanced="Speciális kódoló beállítások engedélyezése" Basic.Settings.Output.EncoderPreset="Kódoló készlet" @@ -694,7 +712,8 @@ Basic.Settings.Video.DisableAero="Aero kikapcsolása" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilineáris (leggyorsabb, homályos lehet méretezésnél)" Basic.Settings.Video.DownscaleFilter.Bicubic="Kettős köbös (élesített méretezés, 16 minta)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (élesített méretezés, 32 minta)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (élesített méretezés, 36 minta)" +Basic.Settings.Video.DownscaleFilter.Area="Terület (Átlagolt, 4/6/9 minta)" Basic.Settings.Audio="Hang" Basic.Settings.Audio.SampleRate="Mintavételezés" @@ -708,7 +727,7 @@ Basic.Settings.Audio.PeakMeterType="Csúcsmérték Típus" Basic.Settings.Audio.PeakMeterType.SamplePeak="Csúcsminta" Basic.Settings.Audio.PeakMeterType.TruePeak="Valós Csúcs (Magasabb CPU használat)" Basic.Settings.Audio.MultiChannelWarning.Enabled="Figyelmeztetés: Surround sound hang engedélyezve van." -Basic.Settings.Audio.MultichannelWarning="Ha közvetít, ellenőrizze, hogy a stream szolgáltatója támogatja mind a surround sound kezelést, mind pedig a surround sound lejátszást. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast a legjobb példa, hogy mely platformokon van teljes támogatás. Ellenben a Facebook Live és a YouTube Live minden elfogadja a térhangzású hangot, a Facebook Live lekeveri stereora és a YouTube Live csak két csatornát játszik le.\n\nOBS audio szűrők kompatibilisek a térhangzású hanggal, viszont a VST bővítmények támogatása nem garantált." +Basic.Settings.Audio.MultichannelWarning="Ha közvetít, ellenőrizze, hogy a stream szolgáltatója támogatja mind a surround sound kezelést, mind pedig a surround sound lejátszást. Facebook 360 Live, Mixer RTMP, Smashcast a legjobb példa, hogy mely platformokon van teljes támogatás. Ellenben a Facebook Live és a YouTube Live minden elfogadja a térhangzású hangot, a Facebook Live lekeveri stereora és a YouTube Live csak két csatornát játszik le.\n\nOBS audio szűrők kompatibilisek a térhangzású hanggal, viszont a VST bővítmények támogatása nem garantált." Basic.Settings.Audio.MultichannelWarning.Title="Engedélyezi a surround hangzást?" Basic.Settings.Audio.MultichannelWarning.Confirm="Biztos benne, hogy engedélyezi a surround hangzást?" Basic.Settings.Audio.Devices="Eszközök" @@ -743,23 +762,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Hangfigyelő eszköz" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Alapértelmezett" Basic.Settings.Advanced.Audio.DisableAudioDucking="Windows hangerőcsökkentés lekapcsolása" Basic.Settings.Advanced.StreamDelay="Stream késleltetés" -Basic.Settings.Advanced.StreamDelay.Duration="Időtartam (másodperc)" +Basic.Settings.Advanced.StreamDelay.Duration="Időtartam" Basic.Settings.Advanced.StreamDelay.Preserve="Töréspont megőrzése (Késleltetés növeléssel) újrakapcsolódás esetén" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Becsült memóriahasználat: %1 MB" Basic.Settings.Advanced.Network="Hálózat" Basic.Settings.Advanced.Network.BindToIP="IP-hez rendelés" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Új hálózatkezelő kód engedélyezése" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Alacsony késleltetésű mód" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Gyorsbillentyű Fókuszműködés" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Sohase tiltson le billentyűparancsot" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Gyorsbillentyűk letiltása, ha a fő ablak fókuszban van" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Gyorsbillentyűk letiltása, ha a fő ablak nincs fókuszban" Basic.Settings.Advanced.AutoRemux="Automatikus remux MP4-re" Basic.Settings.Advanced.AutoRemux.MP4="(mkv-ként mentés)" Basic.AdvAudio="Speciális hangtulajdonságok" Basic.AdvAudio.Name="Név" Basic.AdvAudio.Volume="Hangerő" -Basic.AdvAudio.Mono="Monora lekeverés" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Egyensúly" -Basic.AdvAudio.SyncOffset="Szinkron eltolás (ms)" +Basic.AdvAudio.SyncOffset="Szinkron eltolás" Basic.AdvAudio.Monitoring="Hangfigyelés" Basic.AdvAudio.Monitoring.None="Figyelés kikapcsolása" Basic.AdvAudio.Monitoring.MonitorOnly="Csak figyelés (kimenet némítása)" @@ -825,6 +847,7 @@ SceneItemHide="Elrejti '%1'" OutputWarnings.NoTracksSelected="Ki kell jelölnie legalább egy sávot!" OutputWarnings.MultiTrackRecording="Figyelem: Bizonyos formátumok (mint az FLV) nem támogatják a több sávot felvételenként" OutputWarnings.MP4Recording="Figyelem: Az MP4/MOV-ban mentett állományok javíthatatlanok, ha a fájl nem kerül lezárásra (pl: BSOD vagy áramkimaradás esetén, stb.). Ha mindenképpen több hangsávval kíván felvételt készíteni, akkor használja az MKV állományt és remuxolja a felvételt MP4/MOV-ba, miután elkészült. (Fájl -> Felvételek remuxolása)" +OutputWarnings.CannotPause="Figyelmeztetés: A felvételeket nem lehet szüneteltetni, ha a felvétel kódolója: \"(Stream kódolójának használatára)\" van állítva." FinalScene.Title="Jelenet törlése" FinalScene.Text="Legalább egy jelenetnek lennie kell." diff --git a/UI/data/locale/it-IT.ini b/UI/data/locale/it-IT.ini index 3845148..5e35f35 100644 --- a/UI/data/locale/it-IT.ini +++ b/UI/data/locale/it-IT.ini @@ -23,7 +23,7 @@ Settings="Impostazioni" Display="Schermo" Name="Nome" Exit="Esci" -Mixer="Mixer" +Mixer="Mixer audio" Browse="Sfoglia" Mono="Mono" Stereo="Stereo" @@ -91,6 +91,10 @@ AlreadyRunning.LaunchAnyway="Avvia comunque" DockCloseWarning.Title="Hai chiuso la finestra di un pannello" DockCloseWarning.Text="Hai appena chiuso la finestra di un pannello. Se vuoi mostrarlo di nuovo, vai sul menù Visualizza → Pannelli, nella barra multifunzione in alto." +ExtraBrowsers="Pannelli Browser Personalizzati" +ExtraBrowsers.Info="Aggiungi pannelli dando loro un nome e un URL, quindi clicca su Applica o Chiudi per aprire i pannelli. Puoi aggiungere o rimuovere pannelli in qualsiasi momento." +ExtraBrowsers.DockName="Nome del Pannello" + Auth.Authing.Title="Accesso in corso..." Auth.Authing.Text="Accesso in corso con %1, attendi..." Auth.AuthFailure.Title="Accesso fallito" @@ -107,6 +111,7 @@ TwitchAuth.Stats="Statistiche di Twitch" TwitchAuth.Feed="Feed attività di Twitch" TwitchAuth.TwoFactorFail.Title="Impossibile interrogare il codice della diretta" TwitchAuth.TwoFactorFail.Text="OBS non è stato in grado di connettersi al tuo account di Twitch. Assicurati che l'autenticazione a due fattori sia impostata nelle tue impostazioni di sicurezza di Twitch perché è necessaria per lo stream." +RestreamAuth.Channels="Ripristina i Canali" Copy.Filters="Copia i filtri" Paste.Filters="Incolla i filtri" @@ -139,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 o 30, ma preferisco un'alta ris Basic.AutoConfig.VideoPage.CanvasExplanation="Nota: la risoluzione (di base) dell'inquadratura non sarà necessariamente la stessa risoluzione per le dirette o per le registrazioni. La risoluzione delle dirette/registrazioni effettiva potrebbe essere scalata dalla risoluzione dell'inquadratura per ridurre le risorse utilizzate o i requisiti di velocità in bit." Basic.AutoConfig.StreamPage="Informazioni per le dirette" Basic.AutoConfig.StreamPage.SubTitle="Per favore inserisci le informazioni per le dirette" -Basic.AutoConfig.StreamPage.ConnectAccount="Collega l'account (facoltativo)" +Basic.AutoConfig.StreamPage.ConnectAccount="Connetti account (consigliato)" Basic.AutoConfig.StreamPage.DisconnectAccount="Disconnetti l'account" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Vuoi disconnettere l'account?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Questa modifica verrà applicata immediatamente. Sei sicuro di voler disconnettere il tuo account?" @@ -240,6 +245,9 @@ ConfirmStart.Text="Sei sicuro di voler avviare una diretta?" ConfirmStop.Title="Vuoi interrompere la diretta?" ConfirmStop.Text="Sei sicuro di voler interrompere questa diretta?" +ConfirmStopRecord.Title="Interrompere la registrazione?" +ConfirmStopRecord.Text="Sei sicuro di voler interrompere la registrazione?" + ConfirmBWTest.Title="Vuoi avviare il test della larghezza di banda?" ConfirmBWTest.Text="Hai configurato OBS in modalità di test di larghezza di banda. Questa modalità ti permette di eseguire i test della rete senza dover avviare una diretta. Quando hai finito di eseguire i test, ricordati di disattivare la modalità per permettere ai tuoi spettatori di guardare la diretta.\n\nVuoi continuare?" @@ -255,6 +263,8 @@ Output.StartRecordingFailed="Impossibile avviare la registrazione" Output.StartReplayFailed="Impossibile avviare il buffer di replay" Output.StartFailedGeneric="Impossibile creare il file di uscita. Controlla il log per i dettagli.\n\nNota: se utilizzi la codifica NVENC o AMD, assicurati che i driver video siano aggiornati all'ultima versione." +Output.ReplayBuffer.PauseWarning.Title="Impossibile salvare i replay in pausa" +Output.ReplayBuffer.PauseWarning.Text="Attenzione: i Replay non possono essere salvati mentre la registrazione è in pausa." Output.ConnectFail.Title="Impossibile connettersi" Output.ConnectFail.BadPath="Percorso o URL di connessione non valido. Controlla le tue impostazioni per confermare che siano valide." @@ -444,6 +454,8 @@ Basic.Main.StartRecording="Avvia la registrazione" Basic.Main.StartReplayBuffer="Avvia il buffer di replay" Basic.Main.StartStreaming="Avvia la diretta" Basic.Main.StopRecording="Termina la registrazione" +Basic.Main.PauseRecording="Registrazione in pausa" +Basic.Main.UnpauseRecording="Riprendi la registrazione" Basic.Main.StoppingRecording="Terminazione della registrazione in corso..." Basic.Main.StopReplayBuffer="Termina il buffer di replay" Basic.Main.StoppingReplayBuffer="Terminazione del buffer di replay in corso..." @@ -479,7 +491,7 @@ Basic.MainMenu.Edit.Transform="&Trasforma" Basic.MainMenu.Edit.Transform.EditTransform="Modifica &e trasforma..." Basic.MainMenu.Edit.Transform.CopyTransform="Copia e trasforma" Basic.MainMenu.Edit.Transform.PasteTransform="Incolla e trasforma" -Basic.MainMenu.Edit.Transform.ResetTransform="&Ripristina e trasforma" +Basic.MainMenu.Edit.Transform.ResetTransform="&Ripristina la trasformazione originale" Basic.MainMenu.Edit.Transform.Rotate90CW="Ruota di 90 gradi in senso orario" Basic.MainMenu.Edit.Transform.Rotate90CCW="Ruota di 90 gradi in senso antiorario" Basic.MainMenu.Edit.Transform.Rotate180="Ruota di 180 gradi" @@ -490,18 +502,19 @@ Basic.MainMenu.Edit.Transform.StretchToScreen="Allunga per riempire lo &schermo" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centra nello schermo" Basic.MainMenu.Edit.Transform.VerticalCenter="Centra verticalmente" Basic.MainMenu.Edit.Transform.HorizontalCenter="Centra orizzontalmente" -Basic.MainMenu.Edit.Order="&Ordine" +Basic.MainMenu.Edit.Order="&Ordina" Basic.MainMenu.Edit.Order.MoveUp="Sposta s&u" Basic.MainMenu.Edit.Order.MoveDown="Sposta giù (&D)" Basic.MainMenu.Edit.Order.MoveToTop="Spos&ta in cima" Basic.MainMenu.Edit.Order.MoveToBottom="Sposta in fondo (&B)" -Basic.MainMenu.Edit.AdvAudio="Proprietà audio &avanzate" +Basic.MainMenu.Edit.AdvAudio="Proprietà &audio avanzate" Basic.MainMenu.View="&Visualizza" Basic.MainMenu.View.Toolbars="Barre degli s&trumenti" Basic.MainMenu.View.Docks="Pannelli" Basic.MainMenu.View.Docks.ResetUI="Ripristina l'interfaccia" Basic.MainMenu.View.Docks.LockUI="Blocca l'interfaccia" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Pannelli Browser Personalizzati..." Basic.MainMenu.View.Toolbars.Listboxes="Pu&lsanti di navigazione" Basic.MainMenu.View.SceneTransitions="Transizioni di s&cena" Basic.MainMenu.View.StatusBar="Barra di &stato" @@ -523,8 +536,8 @@ Basic.MainMenu.Help.HelpPortal="&Portale di assistenza" Basic.MainMenu.Help.Website="Visita il sito &web" Basic.MainMenu.Help.Discord="Unisciti al server di &Discord" Basic.MainMenu.Help.Logs="File di &log" -Basic.MainMenu.Help.Logs.ShowLogs="Vi&sualizza i file di Log" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Carica file di log &corrente" +Basic.MainMenu.Help.Logs.ShowLogs="Mo&stra i file di log" +Basic.MainMenu.Help.Logs.UploadCurrentLog="&Carica il file di log attuale" Basic.MainMenu.Help.Logs.UploadLastLog="Carica &l'ultimo file di log" Basic.MainMenu.Help.Logs.ViewCurrentLog="&Visualizza il file di log attuale" Basic.MainMenu.Help.CheckForUpdates="Controlla gli aggiornamenti" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="Controlla automaticamente gli aggiorna Basic.Settings.General.OpenStatsOnStartup="Apri la finestra delle statistiche all'avvio" Basic.Settings.General.WarnBeforeStartingStream="Mostra una finestra di conferma quando avvii una diretta" Basic.Settings.General.WarnBeforeStoppingStream="Mostra una finestra di conferma quando vuoi terminare una diretta" +Basic.Settings.General.WarnBeforeStoppingRecord="Mostra finestra di conferma quando si interrompe la registrazione" Basic.Settings.General.Projectors="Proiettori" Basic.Settings.General.HideProjectorCursor="Nascondi il cursore sopra i proiettori" Basic.Settings.General.ProjectorAlwaysOnTop="I proiettori devono essere sempre in primo piano?" @@ -591,12 +605,15 @@ Basic.Settings.Output.Encoder="Codifica" Basic.Settings.Output.SelectDirectory="Seleziona la cartella di registrazione" Basic.Settings.Output.SelectFile="Seleziona il file di registrazione" Basic.Settings.Output.EnforceBitrate="Non superare i limiti di velocità in bit del servizio di dirette" +Basic.Settings.Output.DynamicBitrate="Cambia in modo dinamico il bitrate per gestire la congestione" +Basic.Settings.Output.DynamicBitrate.Beta="Cambia in modo dinamico il bitrate per gestire la congestione (Beta)" +Basic.Settings.Output.DynamicBitrate.TT="Invece di saltare fotogrammi per ridurre la congestione, cambia dinamicamente il bitrate al volo.\n\nNota che questo potrebbe aumentare il ritardo agli spettatori se c'è una significante congestione improvvisa.\nQuando il bitrate diminuisce, potrebbero volerci fino ad alcuni minuti per ripristinarlo.\n\nAttualmente è solo supportato per RTMP." Basic.Settings.Output.Mode="Modalità di uscita" Basic.Settings.Output.Mode.Simple="Semplice" Basic.Settings.Output.Mode.Adv="Avanzate" Basic.Settings.Output.Mode.FFmpeg="Uscita FFmpeg" Basic.Settings.Output.UseReplayBuffer="Attiva il buffer di replay" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Tempo massimo di replay (in secondi)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Tempo massimo di Replay" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memoria massima (in megabyte)" Basic.Settings.Output.ReplayBuffer.Estimate="Uso della memoria stimato: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Impossibile stimare la memoria utilizzata. Imposta un limite massimo di memoria." @@ -611,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Qualità indistinguibile, dime Basic.Settings.Output.Simple.RecordingQuality.Lossless="Senza perdita di qualità (lossless), dimensioni dei file enormi" Basic.Settings.Output.Simple.Warn.VideoBitrate="Attenzione: la velocità in bit video della diretta verrà impostata a %1, che è il limite più alto per il servizio di dirette attuale. Se sei sicuro di voler superare il valore %1, attiva le impostazioni avanzate della codifica e deseleziona «Non superare i limiti di velocità in bit del servizio di dirette»." Basic.Settings.Output.Simple.Warn.AudioBitrate="Attenzione: la velocità in bit audio della diretta verrà impostata a %1, che è il limite più alto per il servizio di dirette attuale. Se sei sicuro di voler superare il valore %1, attiva le impostazioni avanzate della codifica e deseleziona «Non superare i limiti di velocità in bit del servizio di dirette»." +Basic.Settings.Output.Simple.Warn.CannotPause="Attenzione: Le registrazioni non possono essere sospese se la qualità di registrazione è impostata su \"Lo stesso del flusso\"." Basic.Settings.Output.Simple.Warn.Encoder="Attenzione: registrare con una codifica software a una qualità diversa dalla diretta richiederà un utilizzo aggiuntivo della CPU se esegui dirette e registri allo stesso tempo." Basic.Settings.Output.Simple.Warn.Lossless="Attenzione: la qualità lossless genera file estremamente grandi! Può occupare fino a 7 gigabyte di spazio al minuto con alte risoluzioni e framerate. Non è consigliata per lunghe registrazioni a meno che tu non abbia molto spazio disponibile sul disco rigido." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Sei sicuro di volere utilizzare la qualità lossless?" @@ -623,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264, preset con Basic.Settings.Output.VideoBitrate="Velocità in bit video" Basic.Settings.Output.AudioBitrate="Velocità in bit audio" Basic.Settings.Output.Reconnect="Riconnessione automatica" -Basic.Settings.Output.RetryDelay="Ritardo dei tentativi (in secondi)" +Basic.Settings.Output.RetryDelay="Ritardo dei tentativi" Basic.Settings.Output.MaxRetries="Tentativi massimi" Basic.Settings.Output.Advanced="Attiva le impostazioni avanzate di codifica" Basic.Settings.Output.EncoderPreset="Preset della codifica" @@ -694,7 +712,8 @@ Basic.Settings.Video.DisableAero="Disattiva Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilineare (il più veloce, ma sfocato se ridimensionato)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubica (scalatura accentuata, 16 campioni)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (scalatura accentuata, 32 campioni)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (scalatura accentuata, 36 campioni)" +Basic.Settings.Video.DownscaleFilter.Area="Area (importo peso, 4/6/9 campioni)" Basic.Settings.Audio="Audio" Basic.Settings.Audio.SampleRate="Frequenza di campionamento" @@ -708,7 +727,7 @@ Basic.Settings.Audio.PeakMeterType="Tipo di misuratore di picco" Basic.Settings.Audio.PeakMeterType.SamplePeak="Picco a campionamento" Basic.Settings.Audio.PeakMeterType.TruePeak="Picco esatto (alto utilizzo della CPU)" Basic.Settings.Audio.MultiChannelWarning.Enabled="ATTENZIONE: L'audio surround è attivato." -Basic.Settings.Audio.MultichannelWarning="Se stai effettuando le modifiche per le dirette, controlla che il servizio di dirette offra l'integrazione e la riproduzione di audio surround. Twitch, Facebook 360 Live, Mixer RTMP e Smashcast sono esempi di servizi che offrono l'audio surround. Le dirette su Facebook e YouTube accettano l'audio surround, ma Facebook lo converte in stereo e YouTube riproduce solo due canali.\n\nI filtri audio di OBS sono compatibili con l'audio surround, ma il supporto al plugin VST non è garantito." +Basic.Settings.Audio.MultichannelWarning="Se stai effettuando le modifiche per le dirette, controlla che il servizio di dirette offra l'integrazione e la riproduzione di audio surround. Facebook 360 Live, Mixer RTMP e Smashcast sono esempi di servizi che offrono l'audio surround. Le dirette su Facebook e YouTube accettano l'audio surround, ma Facebook lo converte in stereo e YouTube riproduce solo due canali.\n\nI filtri audio di OBS sono compatibili con l'audio surround, ma il supporto al plugin VST non è garantito." Basic.Settings.Audio.MultichannelWarning.Title="Vuoi attivare l'audio surround?" Basic.Settings.Audio.MultichannelWarning.Confirm="Sei sicuro di voler attivare l'audio surround?" Basic.Settings.Audio.Devices="Dispositivi" @@ -743,23 +762,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositivo di monitoraggio" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Predefinito" Basic.Settings.Advanced.Audio.DisableAudioDucking="Disattiva la riduzione del volume di Windows" Basic.Settings.Advanced.StreamDelay="Ritardo delle dirette" -Basic.Settings.Advanced.StreamDelay.Duration="Durata (in secondi)" +Basic.Settings.Advanced.StreamDelay.Duration="Durata" Basic.Settings.Advanced.StreamDelay.Preserve="Mantieni il punto di taglio (aumenta il ritardo) durante la riconnessione" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Utilizzo della memoria stimato: %1 MB" Basic.Settings.Advanced.Network="Rete" Basic.Settings.Advanced.Network.BindToIP="Associa all'indirizzo IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Attiva il nuovo codice di rete" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Modalità a bassa latenza" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Comportamento Focus Scorciatoie" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Non disabilitare mai le scorciatoie" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Disattiva le scorciatoie quando la finestra principale è in primo piano" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Disattiva le scorciatoie quando la finestra principale non è in primo piano" Basic.Settings.Advanced.AutoRemux="Converti automaticamente in MP4" Basic.Settings.Advanced.AutoRemux.MP4="(registra in MKV)" Basic.AdvAudio="Proprietà audio avanzate" Basic.AdvAudio.Name="Nome" Basic.AdvAudio.Volume="Volume" -Basic.AdvAudio.Mono="Trasforma in mono" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Bilanciamento" -Basic.AdvAudio.SyncOffset="Ritardo per la sincronizzazione (ms)" +Basic.AdvAudio.SyncOffset="Ritardo per la sincronizzazione" Basic.AdvAudio.Monitoring="Monitoraggio audio" Basic.AdvAudio.Monitoring.None="Disattivato" Basic.AdvAudio.Monitoring.MonitorOnly="Solo monitoraggio (uscita audio nel file disattivata)" @@ -825,6 +847,7 @@ SceneItemHide="Nascondi «%1»" OutputWarnings.NoTracksSelected="Devi selezionare almeno una traccia" OutputWarnings.MultiTrackRecording="Attenzione: alcuni formati (come FLV) supportano solo una traccia" OutputWarnings.MP4Recording="Attenzione: le registrazioni salvate in MP4/MOV non saranno recuperabili se il file non può essere completato (ad es. a seguito di un BSOD, perdite di corrente, ecc.). Se desideri registrare più tracce audio, consigliamo l'utilizzo di MKV e, una volta terminato, eseguire la conversione della registrazione in MP4/MOV (File → Converti le registrazioni)" +OutputWarnings.CannotPause="Attenzione: Le registrazioni non possono essere sospese se il codificatore di registrazione è impostato su \"(Utilizza codifica flusso)\"" FinalScene.Title="Eliminazione della scena" FinalScene.Text="Deve esserci almeno una scena." diff --git a/UI/data/locale/ja-JP.ini b/UI/data/locale/ja-JP.ini index adf76fb..81b4b53 100644 --- a/UI/data/locale/ja-JP.ini +++ b/UI/data/locale/ja-JP.ini @@ -23,7 +23,7 @@ Settings="設定" Display="ディスプレイ" Name="名称" Exit="終了" -Mixer="ミキサー" +Mixer="音声ミキサー" Browse="参照" Mono="モノラル" Stereo="ステレオ" @@ -91,6 +91,10 @@ AlreadyRunning.LaunchAnyway="とにかく起動する" DockCloseWarning.Title="ドッキング可能ウィンドウを閉じる" DockCloseWarning.Text="ドッキング可能なウィンドウを閉じました。もう一度表示したい場合は、メニューバーの表示 → ドックメニューを使用してください。" +ExtraBrowsers="カスタムブラウザドック" +ExtraBrowsers.Info="名前とURLを指定してドックを追加し、「適用」または「閉じる」をクリックすることでドックが開きます。 ドックはいつでも追加または削除できます。" +ExtraBrowsers.DockName="ドック名" + Auth.Authing.Title="認証中..." Auth.Authing.Text="%1で認証中、お待ちください..." Auth.AuthFailure.Title="認証失敗" @@ -107,6 +111,7 @@ TwitchAuth.Stats="Twitch統計" TwitchAuth.Feed="Twitch アクティビティフィード" TwitchAuth.TwoFactorFail.Title="ストリームキーを照会できませんでした" TwitchAuth.TwoFactorFail.Text="OBSはあなたのTwitchアカウントに接続できませんでした。 これは配信に必要なので、Twitchセキュリティ設定で2要素認証が設定されていることを確認してください。" +RestreamAuth.Channels="Restream Channels" Copy.Filters="フィルタをコピーする" Paste.Filters="フィルタを貼り付ける" @@ -139,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60または30のいずれか、高 Basic.AutoConfig.VideoPage.CanvasExplanation="注: キャンバス (基本) 解像度は配信や録画の解像度と必ずしも同じではありません。 実際の配信/録画の解像度はリソース使用量やビットレート要求を減らすためにキャンバス解像度から縮小されたものを使用できます。" Basic.AutoConfig.StreamPage="配信情報" Basic.AutoConfig.StreamPage.SubTitle="配信情報を入力してください" -Basic.AutoConfig.StreamPage.ConnectAccount="アカウント接続 (オプション)" +Basic.AutoConfig.StreamPage.ConnectAccount="アカウント接続 (推奨)" Basic.AutoConfig.StreamPage.DisconnectAccount="アカウントを切断" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="アカウントを切断しますか?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="この変更はすぐに適用されます。 アカウントを切断してもよろしいですか?" @@ -189,7 +194,7 @@ Basic.Stats.Status.Inactive="非アクティブ" Basic.Stats.DroppedFrames="ドロップフレーム (ネットワーク)" Basic.Stats.MegabytesSent="出力データの合計" Basic.Stats.Bitrate="ビットレート" -Basic.Stats.DiskFullIn="ディスクがいっぱいになるまで後(約)" +Basic.Stats.DiskFullIn="ディスク空き容量残り時間(約)" ResetUIWarning.Title="UIをリセットしてもよろしいですか?" ResetUIWarning.Text="UIをリセットすると追加のドックは非表示になります。表示したい場合表示メニューからこれらのドックを表示する必要があります。\n\nUIをリセットしてもよろしいですか?" @@ -240,6 +245,9 @@ ConfirmStart.Text="配信を開始しますか?" ConfirmStop.Title="配信を停止しますか?" ConfirmStop.Text="配信を停止しますか?" +ConfirmStopRecord.Title="録画停止?" +ConfirmStopRecord.Text="録画を停止しますか?" + ConfirmBWTest.Title="帯域幅テストを開始しますか?" ConfirmBWTest.Text="OBSが帯域幅テストモードに設定されています。 このモードではチャンネルを配信中にしなくてもネットワークテストが可能です。 テストが終了したら、視聴者があなたの配信を見ることができるようにするために無効にする必要があります。\n\n続行しますか?" @@ -255,6 +263,8 @@ Output.StartRecordingFailed="録画開始に失敗しました" Output.StartReplayFailed="リプレイバッファの開始に失敗しました" Output.StartFailedGeneric="出力開始に失敗しました。詳細はログを確認してください。\n\n注: NVENCまたはAMDエンコーダを使用している場合は、ビデオドライバが最新のものであるかを確認してください。" +Output.ReplayBuffer.PauseWarning.Title="一時停止中はリプレイを保存できません" +Output.ReplayBuffer.PauseWarning.Text="警告:録画の一時停止中はリプレイを保存できません。" Output.ConnectFail.Title="接続失敗" Output.ConnectFail.BadPath="パスかURLが無効です。再確認して下さい。" @@ -337,8 +347,8 @@ Deinterlacing.Yadif2x="Yadif 2x" Deinterlacing.TopFieldFirst="トップフィールドが先" Deinterlacing.BottomFieldFirst="ボトムフィールドが先" -VolControl.SliderUnmuted="'%1' の音量スライダー: %2" -VolControl.SliderMuted="'%1' の音量スライダー: %2 (現在ミュート)" +VolControl.SliderUnmuted="「%1」の音量スライダー: %2" +VolControl.SliderMuted="「%1」の音量スライダー: %2 (現在ミュート)" VolControl.Mute="'%1' をミュート" VolControl.Properties="'%1' のプロパティ" @@ -444,6 +454,8 @@ Basic.Main.StartRecording="録画開始" Basic.Main.StartReplayBuffer="リプレイバッファ開始" Basic.Main.StartStreaming="配信開始" Basic.Main.StopRecording="録画終了" +Basic.Main.PauseRecording="録画一時停止" +Basic.Main.UnpauseRecording="録画再開" Basic.Main.StoppingRecording="録画停止処理中..." Basic.Main.StopReplayBuffer="リプレイバッファ停止" Basic.Main.StoppingReplayBuffer="リプレイバッファ停止処理中..." @@ -502,6 +514,7 @@ Basic.MainMenu.View.Toolbars="ツールバー(&T)" Basic.MainMenu.View.Docks="ドック" Basic.MainMenu.View.Docks.ResetUI="UIをリセット" Basic.MainMenu.View.Docks.LockUI="UIをロック" +Basic.MainMenu.View.Docks.CustomBrowserDocks="カスタムブラウザドック..." Basic.MainMenu.View.Toolbars.Listboxes="リストボックス(&L)" Basic.MainMenu.View.SceneTransitions="シーントランジション(&C)" Basic.MainMenu.View.StatusBar="ステータスバー(&S)" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="起動時に自動的に更新を確 Basic.Settings.General.OpenStatsOnStartup="起動時に統計ダイアログを開く" Basic.Settings.General.WarnBeforeStartingStream="配信を開始するときに確認ダイアログを表示する" Basic.Settings.General.WarnBeforeStoppingStream="配信を停止するときに確認ダイアログを表示する" +Basic.Settings.General.WarnBeforeStoppingRecord="録画を停止するときに確認ダイアログを表示する" Basic.Settings.General.Projectors="プロジェクター" Basic.Settings.General.HideProjectorCursor="プロジェクター上のカーソルを非表示にする" Basic.Settings.General.ProjectorAlwaysOnTop="プロジェクターを常に手前に表示させる" @@ -591,12 +605,15 @@ Basic.Settings.Output.Encoder="エンコーダ" Basic.Settings.Output.SelectDirectory="録画ディレクトリを選択" Basic.Settings.Output.SelectFile="録画ファイルを選択" Basic.Settings.Output.EnforceBitrate="配信サービスのビットレートを制限する" +Basic.Settings.Output.DynamicBitrate="輻輳を管理するためにビットレートを動的に変更する" +Basic.Settings.Output.DynamicBitrate.Beta="輻輳を管理するためにビットレートを動的に変更する (ベータ版)" +Basic.Settings.Output.DynamicBitrate.TT="フレームをドロップして輻輳を減らす代わりに、ビットレートを動的に変更します。\n\n突然の大幅な輻輳が発生した場合には視聴者の遅延が増大する可能性があることに注意してください。\nビットレートが低下すると、復元に数分かかることがあります。\n\n現時点ではRTMPでのみサポートされています。" Basic.Settings.Output.Mode="出力モード" Basic.Settings.Output.Mode.Simple="基本" Basic.Settings.Output.Mode.Adv="詳細" Basic.Settings.Output.Mode.FFmpeg="FFmpeg の出力" Basic.Settings.Output.UseReplayBuffer="リプレイバッファを有効にする" -Basic.Settings.Output.ReplayBuffer.SecondsMax="最大リプレイ時間 (秒)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="最大リプレイ時間" Basic.Settings.Output.ReplayBuffer.MegabytesMax="最大メモリ (メガバイト)" Basic.Settings.Output.ReplayBuffer.Estimate="概算メモリ使用量: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="メモリ使用量を見積もることができません。 最大メモリ制限を設定してください。" @@ -611,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="超高品質、ファイルサ Basic.Settings.Output.Simple.RecordingQuality.Lossless="無損失品質、ファイルサイズ特大" Basic.Settings.Output.Simple.Warn.VideoBitrate="警告: 配信の映像ビットレートは %1 に設定され、これは現在の配信サービスの上限です。 %1 より大きい値に設定する場合、高度なエンコーダオプションを有効にして「配信サービスのビットレートを制限する」のチェックをオフにしてください。" Basic.Settings.Output.Simple.Warn.AudioBitrate="警告: 配信の音声ビットレートは %1 に設定され、これは現在の配信サービスの上限です。 %1 より大きい値に設定する場合、高度なエンコーダオプションを有効にして「配信サービスのビットレートを制限する」のチェックをオフにしてください。" +Basic.Settings.Output.Simple.Warn.CannotPause="警告:録画品質が「配信と同品質」に設定されている場合は録画を一時停止することはできません。" Basic.Settings.Output.Simple.Warn.Encoder="警告: 配信と録画を同時に行う場合に配信と異なる品質でソフトウェアエンコーダで録画する場合にはさらなるCPU 使用率が必要になります。" Basic.Settings.Output.Simple.Warn.Lossless="警告: 無損失品質は途方もなく大きなファイルサイズになります!無損失品質は高解像度と高フレーム レートで 1 分あたり7 ギガバイト以上のディスク容量を使用します。 非常に大量のディスクの空き容量がない場合の長時間録画には無損失設定の使用はお勧めしません。" Basic.Settings.Output.Simple.Warn.Lossless.Msg="無損失品質を使用してもよろしいですか?" @@ -623,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="ソフトウェア (x264 CP Basic.Settings.Output.VideoBitrate="映像ビットレート" Basic.Settings.Output.AudioBitrate="音声ビットレート" Basic.Settings.Output.Reconnect="自動的に再接続" -Basic.Settings.Output.RetryDelay="再試行の遅延 (秒)" +Basic.Settings.Output.RetryDelay="再試行の遅延" Basic.Settings.Output.MaxRetries="最大再試行回数" Basic.Settings.Output.Advanced="高度なエンコーダの設定を有効にする" Basic.Settings.Output.EncoderPreset="エンコーダプリセット" @@ -673,7 +691,7 @@ Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="すべてのコーデック FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" -FilenameFormatting.TT="%CCYY 年, 4桁\n%YY 年, 下2桁 (00-99)\n%MM 月 数値 (01-12)\n%DD 日, 0埋め (01-31)\n%hh 時 24時間形式 (00-23)\n%mm 分 (00-59)\n%ss 秒 (00-61)\n%% A % 記号\n%a 曜日 省略名\n%A 曜日 完全名\n%b 月 省略名\n%B 月 完全名\n%d 日, 0埋め (01-31)\n%H 時 24時間形式 (00-23)\n%I 時 12時間形式 (01-12)\n%m 月 数値 (01-12)\n%M 分 (00-59)\n%p 午前または午後の指定\n%S 秒 (00-61)\n%y 年, 下2桁 (00-99)\n%Y 年\n%z ISO 8601 UTCからのオフセット\n%Z タイムゾーン名または略称\n" +FilenameFormatting.TT="%CCYY 年, 4桁\n%YY 年, 下2桁 (00-99)\n%MM 月, 数値 (01-12)\n%DD 日, 0埋め (01-31)\n%hh 時, 24時間形式 (00-23)\n%mm 分 (00-59)\n%ss 秒 (00-61)\n%% % (パーセント) 記号そのもの\n%a 曜日, 略記\n%A 曜日, 完全名\n%b 月, 略記\n%B 月, 完全名\n%d 日, 0埋め (01-31)\n%H 時, 24時間形式 (00-23)\n%I 時, 12時間形式 (01-12)\n%m 月, 数値 (01-12)\n%M 分 (00-59)\n%p 午前または午後の指定\n%S 秒 (00-61)\n%y 年, 下2桁 (00-99)\n%Y 年\n%z UTCからのISO 8601式オフセット\n%Z タイムゾーンの名称または略称\n" Basic.Settings.Video="映像" Basic.Settings.Video.Adapter="ビデオアダプター" @@ -694,7 +712,8 @@ Basic.Settings.Video.DisableAero="Aeroを無効にする" Basic.Settings.Video.DownscaleFilter.Bilinear="バイリニア (スケーリングする場合ぼやけているが最速)" Basic.Settings.Video.DownscaleFilter.Bicubic="バイキュービック (先鋭化スケーリング、16 のサンプル)" -Basic.Settings.Video.DownscaleFilter.Lanczos="ランチョス (先鋭化スケーリング、32 のサンプル)" +Basic.Settings.Video.DownscaleFilter.Lanczos="ランチョス (先鋭化スケーリング、36 のサンプル)" +Basic.Settings.Video.DownscaleFilter.Area="面積 (加重合計, 4/6/9 サンプル)" Basic.Settings.Audio="音声" Basic.Settings.Audio.SampleRate="サンプリングレート" @@ -708,7 +727,7 @@ Basic.Settings.Audio.PeakMeterType="ピークメーターの種類" Basic.Settings.Audio.PeakMeterType.SamplePeak="サンプル ピーク" Basic.Settings.Audio.PeakMeterType.TruePeak="真のピーク (CPU使用率高い)" Basic.Settings.Audio.MultiChannelWarning.Enabled="警告: サラウンド音声が有効です。" -Basic.Settings.Audio.MultichannelWarning="配信する場合、配信サービスがサラウンド音声の取り込みと再生の両方をサポートしているかどうかを確認してください。Twitch、Facebook 360 Live、Mixer RTMP、Smashcastは、サラウンド音声が完全にサポートされている例です。しかしFacebook LiveとYouTube Liveはどちらもサラウンド取り込みを受信しますが、Facebook Liveはステレオにダウンミックスし、YouTube Liveは2チャンネルのみしか再生できません。\n\nVSTプラグインのサポートは保証されていませんが、OBS音声フィルタはサラウンド音声と互換性があります。" +Basic.Settings.Audio.MultichannelWarning="配信する場合、配信サービスがサラウンド音声の取り込みと再生の両方をサポートしているかどうかを確認してください。Facebook 360 Live、Mixer RTMP、Smashcastは、サラウンド音声が完全にサポートされている例です。しかしFacebook LiveとYouTube Liveはどちらもサラウンド取り込みを受信しますが、Facebook Liveはステレオにダウンミックスし、YouTube Liveは2チャンネルのみしか再生できません。\n\nVSTプラグインのサポートは保証されていませんが、OBS音声フィルタはサラウンド音声と互換性があります。" Basic.Settings.Audio.MultichannelWarning.Title="サラウンド音声を有効にしますか?" Basic.Settings.Audio.MultichannelWarning.Confirm="サラウンド音声を有効にしてもよろしいですか?" Basic.Settings.Audio.Devices="デバイス" @@ -743,23 +762,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="モニタリングデバイス" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="既定" Basic.Settings.Advanced.Audio.DisableAudioDucking="Windowsの音量を自動で下げる機能を無効にする" Basic.Settings.Advanced.StreamDelay="遅延配信" -Basic.Settings.Advanced.StreamDelay.Duration="継続時間 (秒)" +Basic.Settings.Advanced.StreamDelay.Duration="期間" Basic.Settings.Advanced.StreamDelay.Preserve="再接続時にカットオフポイントを保持する (増加遅延)" Basic.Settings.Advanced.StreamDelay.MemoryUsage="概算メモリ使用量: %1 MB" Basic.Settings.Advanced.Network="ネットワーク" Basic.Settings.Advanced.Network.BindToIP="IP選択" Basic.Settings.Advanced.Network.EnableNewSocketLoop="新しいネットワークコードを有効にする" Basic.Settings.Advanced.Network.EnableLowLatencyMode="低遅延モード" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="ホットキーフォーカスの動作" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="ホットキーを無効にしない" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="メインウィンドウにフォーカスがあるときはホットキーを無効にする" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="メインウィンドウにフォーカスがないときはホットキーを無効にする" Basic.Settings.Advanced.AutoRemux="自動的にmp4に再多重化" Basic.Settings.Advanced.AutoRemux.MP4="(mkvとして録画)" Basic.AdvAudio="オーディオの詳細プロパティ" Basic.AdvAudio.Name="名称" Basic.AdvAudio.Volume="音量" -Basic.AdvAudio.Mono="モノラルにダウンミックス" +Basic.AdvAudio.Mono="モノラル" Basic.AdvAudio.Balance="バランス" -Basic.AdvAudio.SyncOffset="同期オフセット (ミリ秒)" +Basic.AdvAudio.SyncOffset="同期オフセット" Basic.AdvAudio.Monitoring="音声モニタリング" Basic.AdvAudio.Monitoring.None="モニターオフ" Basic.AdvAudio.Monitoring.MonitorOnly="モニターのみ (出力はミュート)" @@ -825,6 +847,7 @@ SceneItemHide="'%1' を非表示" OutputWarnings.NoTracksSelected="少なくとも 1 つのトラックを選択する必要があります" OutputWarnings.MultiTrackRecording="警告: 特定のフォーマット (FLVなど) は1つの録画で複数のトラックをサポートしていません" OutputWarnings.MP4Recording="警告: (例えば、ブルースクリーン、電力損失などの結果として)ファイルをファイナライズ出来ない場合はMP4/MOVに保存された録画は回復不能になります。 複数の音声トラックを録画する場合はMKVの利用を検討して録画の終了後にMP4/MOVに再多重化してください。(ファイル → 録画の再多重化)" +OutputWarnings.CannotPause="警告:録画エンコーダが「(ストリームエンコーダを使用)」に設定されている場合は録画を一時停止することはできません。" FinalScene.Title="シーンを削除する" FinalScene.Text="1つ以上のシーンが必要です。" diff --git a/UI/data/locale/ka-GE.ini b/UI/data/locale/ka-GE.ini index c06dc9c..721d8c3 100644 --- a/UI/data/locale/ka-GE.ini +++ b/UI/data/locale/ka-GE.ini @@ -23,7 +23,7 @@ Settings="პარამეტრები" Display="ეკრანი" Name="სახელი" Exit="გასვლა" -Mixer="მიქშერი" +Mixer="ხმის მიქშერი" Browse="მოძიება" Mono="მონო" Stereo="სტერეო" @@ -91,6 +91,10 @@ AlreadyRunning.LaunchAnyway="მაინც გაშვება" DockCloseWarning.Title="იერსახის ნაწილის დამალვა" DockCloseWarning.Text="თქვენ ახლახან დამალეთ იერსახის ნაწილი. თუ გსურთ მისი კვლავ გამოჩენა, მენიუს ზოლიდან გამოიყენეთ ხედი → იერსახის ნაწილები." +ExtraBrowsers="ბრაუზერის მორგებული ნაწილები" +ExtraBrowsers.Info="დაამატეთ იერსახის ცალკეული ნაწილები სახელისა და URL-ბმულის მითითებით, შემდეგ კი დაწკაპეთ მიღებასა და დახურვაზე, მათ განსათავსებლად. იერსახის ნაწილების დამატება და მოცილება, ნებისმიერ დროს შეგიძლიათ." +ExtraBrowsers.DockName="ნაწილის სახელი" + Auth.Authing.Title="ანგარიშზე შესვლა..." Auth.Authing.Text="მიმდინარეობს შესვლა %1-ზე, გთხოვთ, მოითმინოთ..." Auth.AuthFailure.Title="შესვლა ვერ მოხერხდა" @@ -106,6 +110,8 @@ Auth.StreamInfo="ნაკადის მონაცემები" TwitchAuth.Stats="Twitch-ის სტატისტიკა" TwitchAuth.Feed="Twitch მოქმედებების არხი" TwitchAuth.TwoFactorFail.Title="ნაკადის გასაღების მოთხოვნა ვერ მოხერხდა" +TwitchAuth.TwoFactorFail.Text="OBS ვერ უკავშირდება თქვენს Twitch-ანგარიშს. გთხოვთ გადაამოწმოთ, ნამდვილად ჩართული გაქვთ თუ არა ორსაფეხურიანი დადასტურება შესვლისას, თქვენი Twitch-ის უსაფრთხოების პარამეტრებიდან, რაც მოითხოვება ნაკადის გასაშვებად." +RestreamAuth.Channels="Restream‐არხები" Copy.Filters="ფილტრების ასლი" Paste.Filters="ფილტრების ჩასმა" @@ -138,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 ან 30, თუმცა უ Basic.AutoConfig.VideoPage.CanvasExplanation="შენიშვნა: ეკრანის ფონის (ძირითადი) გაფართოება არაა აუცილებელი გაშვებული ნაკადის ან გადაღებული ვიდეოს გაფართოებას ემთხვეოდეს. ცალკეული ნაკადის/ვიდეოს ზომები შეიძლება შემცირდეს, რესურსების მოხმარების ან ბიტური სიხშირის შესამცირებლად." Basic.AutoConfig.StreamPage="ნაკადის მონაცემები" Basic.AutoConfig.StreamPage.SubTitle="გთხოვთ მიუთითოთ ნაკადის მონაცემები" -Basic.AutoConfig.StreamPage.ConnectAccount="ანგარიშის დაკავშირება (არასავალდებულო)" +Basic.AutoConfig.StreamPage.ConnectAccount="ანგარიშთან დაკავშირება (სასურველია)" Basic.AutoConfig.StreamPage.DisconnectAccount="ანგარიშიდან გამოერთება" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="გსურთ ანგარიშიდან გამოერთება?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="ცვლილება დაუყოვნებლივ აისახება. ნამდვილად გსურთ, ანგარიშიდან გამოერთება?" @@ -239,6 +245,9 @@ ConfirmStart.Text="ნამდვილად გსურთ პირდა ConfirmStop.Title="შეწყდეს ნაკადი?" ConfirmStop.Text="ნამდვილად გსურთ პირდაპირი ეთერის შეწყვეტა?" +ConfirmStopRecord.Title="შეწყდეს ჩაწერა?" +ConfirmStopRecord.Text="ნამდვილად გსურთ ჩაწერის შეწყვეტა?" + ConfirmBWTest.Title="შემოწმდეს ქსელის გამტარუნარიანობა?" ConfirmBWTest.Text="OBS-ისთვის მითითებული გაქვთ ქსელის გამტარუნარიანობის რეჟიმი. ეს რეჟიმი საშუალებას გაძლევთ, შეამოწმოთ ქსელის მუშაობა, თქვენს არხზე პირდაპირ ეთერში გასვლის გარეშე. შემოწმების დასრულებისთანავე, საჭიროა მისი გათიშვა, რომ მაყურებლებმა შეძლონ გაშვებული ნაკადის ხილვა\n\nგსურთ, განაგრძოთ?" @@ -254,6 +263,8 @@ Output.StartRecordingFailed="ჩაწერის დაწყება ვე Output.StartReplayFailed="გადახვევის ჩართვა ვერ მოხერხდა" Output.StartFailedGeneric="სიგნალის გაშვება ვერ მოხერხდა. გთხოვთ, შეამოწმეთ აღრიცხვის ფაილი, დამატებითი ინფორმაციისთვის.\n\nშენიშვნა: თუ იყენებთ NVENC ან AMD დამშიფრავებს, დარწმუნდით რომ თქვენი ვიდეოდაფის პროგრამა განახლებულია." +Output.ReplayBuffer.PauseWarning.Title="როცა შეჩერებულია, გადასახვევი მასალა ვერ შეინახება" +Output.ReplayBuffer.PauseWarning.Text="შენიშვნა: უკან გადასახვევი მასალა ვერ შეინახება, როცა ჩაწერა შეჩერებულია." Output.ConnectFail.Title="დაკავშირება ვერ მოხერხდა" Output.ConnectFail.BadPath="არამართებული მისამართი ან დასაკავშირებელი URL ბმული. გთხოვთ, გადაამოწმოთ თქვენი პარამეტრების სისწორე." @@ -322,7 +333,7 @@ ScaleFiltering.Point="წერტილოვანი" ScaleFiltering.Bilinear="ორხაზოვანი" ScaleFiltering.Bicubic="ბიკუბური" ScaleFiltering.Lanczos="Lanczos" -ScaleFiltering.Area="სივრცე" +ScaleFiltering.Area="სივრცითი" Deinterlacing="Deinterlacing" Deinterlacing.Discard="გაუქმება" @@ -443,7 +454,9 @@ Basic.Main.StartRecording="ჩაწერის დაწყება" Basic.Main.StartReplayBuffer="გადახვევის ჩართვა" Basic.Main.StartStreaming="ნაკადის გაშვება" Basic.Main.StopRecording="ჩაწერის შეწყვეტა" -Basic.Main.StoppingRecording="ჩაწერის შეწყვეტა..." +Basic.Main.PauseRecording="ჩანაწერის შეჩერება" +Basic.Main.UnpauseRecording="ჩანაწერის გაგრძელება" +Basic.Main.StoppingRecording="ჩაწერა წყდება..." Basic.Main.StopReplayBuffer="გადახვევის გამორთვა" Basic.Main.StoppingReplayBuffer="გადახვევა გამოირთვება..." Basic.Main.StopStreaming="ნაკადის შეწყვეტა" @@ -456,7 +469,7 @@ Basic.Main.Ungroup="განჯგუფება" Basic.MainMenu.File="ფაილი (&F)" Basic.MainMenu.File.Export="შენახვა (&E)" Basic.MainMenu.File.Import="შემოტანა (&I)" -Basic.MainMenu.File.ShowRecordings="ჩანაწერების ჩვენება (&R)" +Basic.MainMenu.File.ShowRecordings="ჩანაწერების ნახვა (&R)" Basic.MainMenu.File.Remux="ჩანაწერების გადაფუთვა (&M)" Basic.MainMenu.File.Settings="პარამეტრები (&S)" Basic.MainMenu.File.ShowSettingsFolder="პარამეტრების საქაღალდის ჩვენება" @@ -479,8 +492,8 @@ Basic.MainMenu.Edit.Transform.EditTransform="გარდაქმნის ჩ Basic.MainMenu.Edit.Transform.CopyTransform="გარდაქმნის ასლი" Basic.MainMenu.Edit.Transform.PasteTransform="გარდაქმნის ჩასმა" Basic.MainMenu.Edit.Transform.ResetTransform="გარდაქმნის გაუქმება (&R)" -Basic.MainMenu.Edit.Transform.Rotate90CW="მობრუნება 90 გრადუსით საათის ისრის მიმართ." -Basic.MainMenu.Edit.Transform.Rotate90CCW="მობრუნება 90 გრადუსით საათის ისრის საწ. მიმართ." +Basic.MainMenu.Edit.Transform.Rotate90CW="მობრუნება 90 გრადუსით საათის მიმართ." +Basic.MainMenu.Edit.Transform.Rotate90CCW="მობრუნება 90 გრადუსით საათის საპირ." Basic.MainMenu.Edit.Transform.Rotate180="მობრუნება 180 გრადუსით" Basic.MainMenu.Edit.Transform.FlipHorizontal="თარაზულად შეტრიალება (&H)" Basic.MainMenu.Edit.Transform.FlipVertical="შვეულად შეტრიალება (&V)" @@ -501,6 +514,7 @@ Basic.MainMenu.View.Toolbars="ხელსაწყოები (&T)" Basic.MainMenu.View.Docks="იერსახის ნაწილები" Basic.MainMenu.View.Docks.ResetUI="იერსახის აღდგენა" Basic.MainMenu.View.Docks.LockUI="იერსახის ჩაკეტვა" +Basic.MainMenu.View.Docks.CustomBrowserDocks="ბრაუზერის მორგებული ნაწილები..." Basic.MainMenu.View.Toolbars.Listboxes="სიები (&L)" Basic.MainMenu.View.SceneTransitions="სცენებს შორის გადასვლები (&C)" Basic.MainMenu.View.StatusBar="მდგომარეობის ზოლი (&S)" @@ -543,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="განახლებებზე Basic.Settings.General.OpenStatsOnStartup="სტატისტიკის ფანჯრის გახსნა ჩართვისას" Basic.Settings.General.WarnBeforeStartingStream="დადასტურების ფანჯრის ჩვენება ნაკადის გაშვებისას" Basic.Settings.General.WarnBeforeStoppingStream="დადასტურების ფანჯრის ჩვენება ნაკადის შეწყვეტისას" +Basic.Settings.General.WarnBeforeStoppingRecord="დადასტურების ფანჯრის ჩვენება ჩაწერის შეწყვეტისას" Basic.Settings.General.Projectors="გამოსახულების ჩვენება" Basic.Settings.General.HideProjectorCursor="მაჩვენებლის დამალვა ჩვენებებზე" Basic.Settings.General.ProjectorAlwaysOnTop="მიღებული გამოსახულებების სხვა ფანჯრების ზემოთ დატოვება" @@ -590,12 +605,15 @@ Basic.Settings.Output.Encoder="დამშიფრავი" Basic.Settings.Output.SelectDirectory="საქაღალდის არჩევა ჩანაწერისთვის" Basic.Settings.Output.SelectFile="ფაილის არჩევა ჩანაწერისთვის" Basic.Settings.Output.EnforceBitrate="ნაკადის გაშვების მომსახურების ბიტური სიხშირის ზღვრების დადგენა" +Basic.Settings.Output.DynamicBitrate="ბიტური სიხშირის ცვალებადობა, ქსელის გადატვირთულობის ასარიდებლად" +Basic.Settings.Output.DynamicBitrate.Beta="ბიტური სიხშირის ცვალებადობა, ქსელის გადატვირთულობის ასარიდებლად (საცდელი)" +Basic.Settings.Output.DynamicBitrate.TT="ქსელის გადატვირთულობის შესამცირებლად კადრების გამოტოვების ნაცვლად, მიმდინარე ბიტური სიხშირის ცვალებადობა.\n\nგაითვალისწინეთ, რომ შედეგად შესაძლოა გაიზარდოს დაყოვნება მაყურებლებისთვის, დატვირთვის უეცარი მატებისას.\nბიტური სიხშირის ვარდნის შემდეგ, აღდგენა რამდენიმე წუთს გასტანს.\n\nამჟამად მხარდაჭერილია მხოლოდ RTMP." Basic.Settings.Output.Mode="გამოტანის რეჟიმი" Basic.Settings.Output.Mode.Simple="მარტივი" Basic.Settings.Output.Mode.Adv="გაფართოებული" Basic.Settings.Output.Mode.FFmpeg="FFmpeg-გამოტანა" Basic.Settings.Output.UseReplayBuffer="გადახვევის შესაძლებლობა" -Basic.Settings.Output.ReplayBuffer.SecondsMax="გადახვევის დასაშვები დრო (წამი)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="გადახვევის დასაშვები დრო" Basic.Settings.Output.ReplayBuffer.MegabytesMax="მეხსიერების დასაშვები მოცულობა (მეგაბაიტებში)" Basic.Settings.Output.ReplayBuffer.Estimate="მეხსიერების მიახლოებითი მოხმარება: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="შეუძლებელია მეხსიერების მიახლოებითი მოხმარების დადგენა. გთხოვთ, მიუთითოთ მეხსიერების დასაშვები ზღვარი." @@ -610,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="განუსაზღვრ Basic.Settings.Output.Simple.RecordingQuality.Lossless="უდანაკარგო ხარისხი, მეტისმეტად დიდი ზომის ფაილი" Basic.Settings.Output.Simple.Warn.VideoBitrate="გაფრთხილება: ვიდეონაკადის ბიტურ სიხშირედ მიეთითება %1, რაც წარმოადგენს უმაღლეს დაშვებულ ზღვარს, ნაკადის გაშვების მოცემული მომსახურებისთვის. თუ ნამდვილად გსურთ %1 ბიტურ სიხშირეზე მეტის მიღება, ჩართეთ დაშიფვრის გაფართოებული პარამეტრები და მოხსენით მონიშვნა \"ნაკადის გაშვების მომსახურების ბიტური სიხშირის ზღვრების დადგენას\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="გაფრთხილება: ხმოვანი ნაკადის ბიტურ სიხშირედ მიეთითება %1, რაც წარმოადგენს უმაღლეს დაშვებულ ზღვარს, ნაკადის გაშვების მოცემული მომსახურებისთვის. თუ ნამდვილად გსურთ %1 ბიტურ სიხშირეზე მეტის მიღება, ჩართეთ დაშიფვრის გაფართოებული პარამეტრები და მოხსენით მონიშვნა \"ნაკადის გაშვების მომსახურების ბიტური სიხშირის ზღვრების დადგენას\"." +Basic.Settings.Output.Simple.Warn.CannotPause="შენიშვნა: ჩანაწერის შეჩერება შეუძლებელია, თუ ჩაწერის ხარისხად მითითებულია „გაშვებული ნაკადის შესაბამისი“." Basic.Settings.Output.Simple.Warn.Encoder="გაფრთხილება: გაშვებული ნაკადისგან განსხვავებულ ხარისხში ჩანაწერის დაშიფვრა, ზრდის პროცესორის დატვირთვას, როცა ნაკადის გაშვება და ჩაწერა, ერთდროულად მიმდინარეობს." Basic.Settings.Output.Simple.Warn.Lossless="გაფრთხილება: უდანაკარგო ხარისხის მითითების შემთხვევაში, შეიქმნება მეტისმეტად დიდი ზომის ფაილები! უდანაკარგო ხარისხის ვიდეოს თითოეული წუთის მოცულობამ დისკზე, შესაძლოა 7 გიგაბაიტს გადააჭარბოს, მაღალი გარჩევადობისა და კადრის სიხშირის პირობებში. ხანგრძლივი ჩანაწერებისთვის, უდანაკარგოს არჩევა არაა მიზანშეწონილი, თუ არ გაქვთ საკმარისად დიდი მოცულობის თავისუფალი ადგილი დისკზე." Basic.Settings.Output.Simple.Warn.Lossless.Msg="ნამდვილად გსურთ უდანაკარგო ხარისხის მითითება?" @@ -622,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="პროგრამულ Basic.Settings.Output.VideoBitrate="ვიდეოს ბიტური სიხშირე" Basic.Settings.Output.AudioBitrate="ხმის ბიტური სიხშირე" Basic.Settings.Output.Reconnect="ხელახლა დაკავშირება ავტომატურად" -Basic.Settings.Output.RetryDelay="გამეორების დაყოვნება (წამი)" +Basic.Settings.Output.RetryDelay="დაყოვნება გამეორებისას" Basic.Settings.Output.MaxRetries="გამეორების დასაშვები რაოდენობა" Basic.Settings.Output.Advanced="დამშიფრავის გაფართოებული პარამეტრების ჩართვა" Basic.Settings.Output.EncoderPreset="დამშიფრავის მზა პარამეტრები" @@ -693,7 +712,8 @@ Basic.Settings.Video.DisableAero="Aero გაფორმების გათ Basic.Settings.Video.DownscaleFilter.Bilinear="ორხაზოვანი (უსწრაფესი, მაგრამ ბუნდოვანი მასშტაბირება)" Basic.Settings.Video.DownscaleFilter.Bicubic="ბიკუბური (მკვეთრი მასშტაბირება, 16 შერჩევა)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (მკვეთრი მასშტაბირება, 32 შერჩევა)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (მკვეთრი მასშტაბირება, 36 შერჩევა)" +Basic.Settings.Video.DownscaleFilter.Area="სივრცე (შეწონილი ჯამი, 4/6/9 შერჩევა)" Basic.Settings.Audio="ხმა" Basic.Settings.Audio.SampleRate="სიხშირე" @@ -707,7 +727,7 @@ Basic.Settings.Audio.PeakMeterType="ხმის სიმაღლის მზ Basic.Settings.Audio.PeakMeterType.SamplePeak="უბრალო" Basic.Settings.Audio.PeakMeterType.TruePeak="ზუსტი (პროცესორის მაღალი მოხმარებით)" Basic.Settings.Audio.MultiChannelWarning.Enabled="ყურადღება: ჩართულია მოცულობითი ხმა." -Basic.Settings.Audio.MultichannelWarning="ნაკადის გაშვებისას გადაამოწმეთ, მომსახურების მომწოდებელი, იძლევა თუ არა მოცულობითი ხმოვანი სიგნალის როგორც მიღების, ასევე მოსმენის შესაძლებლობას. მაგალითად მომსახურებებზე, როგორიცაა Twitch, Facebook 360 Live, Mixer RTMP და Smashcast, სრულადაა მხარდაჭერილი მოცულობითი ხმოვანი სიგნალი. ხოლო Facebook Live და YouTube Live, მიუხედავად იმისა, რომ ორივე იღებს მოცულობით ხმოვან სიგნალს, Facebook Live გარდაქმნის მას სტერეო-სიგნალად, ხოლო YouTube Live უშვებს მხოლოდ ორი არხით.\n\nOBS-ის ხმოვანი ფილტრები თავსებადია მოცულობით ხმოვან სიგნალთან, მაგრამ VST-მოდულის მხარდაჭერა, შესაძლოა არ იყოს უზრუნველყოფილი." +Basic.Settings.Audio.MultichannelWarning="ნაკადის გაშვებისას გადაამოწმეთ, მომსახურების მომწოდებელი, იძლევა თუ არა მოცულობითი ხმოვანი სიგნალის როგორც მიღების, ასევე მოსმენის შესაძლებლობას. მაგალითად მომსახურებებზე, როგორიცაა Facebook 360 Live, Mixer RTMP და Smashcast, სრულადაა მხარდაჭერილი მოცულობითი ხმოვანი სიგნალი. ხოლო Facebook Live და YouTube Live, მიუხედავად იმისა, რომ ორივე იღებს მოცულობით ხმოვან სიგნალს, Facebook Live გარდაქმნის მას სტერეო-სიგნალად, ხოლო YouTube Live უშვებს მხოლოდ ორი არხით.\n\nOBS-ის ხმოვანი ფილტრები თავსებადია მოცულობით ხმოვან სიგნალთან, მაგრამ VST-მოდულის მხარდაჭერა, შესაძლოა არ იყოს უზრუნველყოფილი." Basic.Settings.Audio.MultichannelWarning.Title="ჩაირთოს მოცულობითი ხმოვანი სიგნალი?" Basic.Settings.Audio.MultichannelWarning.Confirm="ნამდვილად გსურთ, ჩართოთ მოცულობითი ხმოვანი სიგნალი?" Basic.Settings.Audio.Devices="მოწყობილობები" @@ -724,7 +744,7 @@ Basic.Settings.Audio.PushToTalkDelay="დაჭერით საუბრი Basic.Settings.Audio.UnknownAudioDevice="[მოწყობილობა არაა დაკავშირებული ან მიუწვდომელია]" Basic.Settings.Audio.Disabled="გამორთული" -Basic.Settings.Advanced="დამატებით" +Basic.Settings.Advanced="დამატებითი" Basic.Settings.Advanced.General.ProcessPriority="უპირატესობა დამუშავებისას" Basic.Settings.Advanced.General.ProcessPriority.High="მაღალი" Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="საშუალოზე მაღალი" @@ -742,23 +762,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="მოსასმენი მ Basic.Settings.Advanced.Audio.MonitoringDevice.Default="ნაგულისხმევი" Basic.Settings.Advanced.Audio.DisableAudioDucking="Windows-ის მიერ ხმის დონის დადაბლების არიდება" Basic.Settings.Advanced.StreamDelay="ნაკადის დაყოვნება" -Basic.Settings.Advanced.StreamDelay.Duration="ხანგრძლივობა (წამი)" +Basic.Settings.Advanced.StreamDelay.Duration="ხანგრძლივობა" Basic.Settings.Advanced.StreamDelay.Preserve="მოსაჭრელი წერტილის მომარაგება (დაყოვნების გაზრდა) ხელახლა დაკავშირებისას" Basic.Settings.Advanced.StreamDelay.MemoryUsage="მეხსიერების მიახლოებითი მოხმარება: %1 MB" Basic.Settings.Advanced.Network="ქსელი" Basic.Settings.Advanced.Network.BindToIP="დაკავშირება IP-მისამართზე" Basic.Settings.Advanced.Network.EnableNewSocketLoop="ქსელის ახალი კოდის ჩართვა" Basic.Settings.Advanced.Network.EnableLowLatencyMode="დაყოვნების შემცირება" -Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="სწრაფი ღილაკების გათიშვა, მთავარ ფანჯარაზე გადასვლისას" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="სწრაფი ღილაკების მოქმედება" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="არასდროს გაითიშოს" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="გაითიშოს, მთავარ ფანჯარაზე გადასვლისას" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="გაითიშოს, მთავარი ფანჯრიდან გადასვლისას" Basic.Settings.Advanced.AutoRemux="თვითშეფუთვა mp4-ფაილად" Basic.Settings.Advanced.AutoRemux.MP4="(ჩაწერა mkv-ფაილად)" Basic.AdvAudio="ხმის გაფართოებული პარამეტრები" Basic.AdvAudio.Name="სახელი" Basic.AdvAudio.Volume="ხმის დონე" -Basic.AdvAudio.Mono="ერთ არხში გაერთიანება" +Basic.AdvAudio.Mono="მონო" Basic.AdvAudio.Balance="წონასწორობა" -Basic.AdvAudio.SyncOffset="სინქრონიზაციის გასწორება (მწ)" +Basic.AdvAudio.SyncOffset="სინქრონიზაციის გასწორება" Basic.AdvAudio.Monitoring="ხმის მოსმენა" Basic.AdvAudio.Monitoring.None="მოსმენის გარეშე" Basic.AdvAudio.Monitoring.MonitorOnly="მხოლოდ მოსმენა (უხმო გამოტანა)" @@ -824,6 +847,7 @@ SceneItemHide="დაიმალოს „%1“" OutputWarnings.NoTracksSelected="უნდა მიუთითოთ ერთი ხმოვანი ბილიკი მაინც" OutputWarnings.MultiTrackRecording="გაფრთხილება: ცალკეული სახის ფაილებში (როგორიცაა FLV), არაა მხარდაჭერილი რამდენიმე ბილიკი, თითოეული ჩაწერისას" OutputWarnings.MP4Recording="გაფრთხილება: MP4/MOV სახით შენახული ჩანაწერები ვეღარ აღდგება, მუშაობის შეწყვეტის შემთხვევაში (მაგ. ლურჯი ეკრანის ამოგდებისას, ძაბვის ვარდნისას და ა.შ.). თუ გსურთ რამდენიმე ხმოვანი ფაილის ჩაწერა, სასურველია ამისთვის გამოიყენოთ MKV და დასრულების შემდეგ გადაფუთოთ MP4/MOV-ფაილად. (ფაილი → ჩანაწერების გადაფუთვა)" +OutputWarnings.CannotPause="შენიშვნა: ჩანაწერის შეჩერება შეუძლებელია, თუ ჩაწერისთვის მითითებულია „(გაშვებული ნაკადის დამშიფრავის გამოყენება)“" FinalScene.Title="სცენის წაშლა" FinalScene.Text="აუცილებელია სულ მცირე ერთ სცენა." diff --git a/UI/data/locale/ko-KR.ini b/UI/data/locale/ko-KR.ini index 3d579f6..ab2e8f7 100644 --- a/UI/data/locale/ko-KR.ini +++ b/UI/data/locale/ko-KR.ini @@ -23,7 +23,7 @@ Settings="설정" Display="디스플레이" Name="이름" Exit="끝내기" -Mixer="믹서" +Mixer="오디오 믹서" Browse="찾아보기" Mono="모노" Stereo="스테레오" @@ -91,6 +91,10 @@ AlreadyRunning.LaunchAnyway="경고를 무시하고 실행" DockCloseWarning.Title="도킹 가능한 창을 닫는 중입니다" DockCloseWarning.Text="도킹 가능한 창을 닫았습니다. 이 창을 다시 보려면 상단 메뉴에서 보기 -> 독을 확인하세요." +ExtraBrowsers="사용자 임의 브라우저 독" +ExtraBrowsers.Info="이름과 URL을 부여하여 독을 추가할 수 있으며, 작업 후 적용 혹은 닫기 단추를 누르면 됩니다. 언제든지 독을 추가하거나 제거할 수 있습니다." +ExtraBrowsers.DockName="독 이름" + Auth.Authing.Title="인증 처리 중..." Auth.Authing.Text="%1 인증 처리 중, 잠시만 기다려 주세요..." Auth.AuthFailure.Title="인증 실패" @@ -107,6 +111,7 @@ TwitchAuth.Stats="트위치 통계" TwitchAuth.Feed="트위치 활동 피드" TwitchAuth.TwoFactorFail.Title="스트림 키를 질의할 수 없었습니다" TwitchAuth.TwoFactorFail.Text="OBS가 사용자의 트위치 계정에 접속할 수 없었습니다. 트위치 보안 설정 에서 이중 인증을 거쳐야 방송이 가능합니다." +RestreamAuth.Channels="Restream 채널" Copy.Filters="필터를 복사" Paste.Filters="필터를 붙여넣기" @@ -139,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 혹은 30, 하지만 높은 해 Basic.AutoConfig.VideoPage.CanvasExplanation="참고: 캔버스 (기본) 해상도는 방송 혹은 녹화하려는 해상도와 반드시 같을 필요는 없습니다. 실제 방송/녹화 해상도는 Pc 사양을 낮추거나 비트레이트 제한에 맞추기 위해 이 캔버스 해상도를 기준으로 축소할 수 있습니다." Basic.AutoConfig.StreamPage="방송 정보" Basic.AutoConfig.StreamPage.SubTitle="방송 정보를 입력하세요" -Basic.AutoConfig.StreamPage.ConnectAccount="계정 연결 (필수 아님)" +Basic.AutoConfig.StreamPage.ConnectAccount="계정 연결 (권장)" Basic.AutoConfig.StreamPage.DisconnectAccount="계정 연결끊기" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="해당 계정과 연결을 끊겠습니까?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="이 변경 사항은 즉시 적용됩니다. 정말로 계정과 연결을 중단하겠습니까?" @@ -240,6 +245,9 @@ ConfirmStart.Text="정말로 방송을 시작할까요?" ConfirmStop.Title="방송 중지?" ConfirmStop.Text="정말로 방송을 중단할까요?" +ConfirmStopRecord.Title="녹화를 중단할까요?" +ConfirmStopRecord.Text="정말로 녹화를 중단하시겠습니까?" + ConfirmBWTest.Title="대역폭을 점검하겠습니까?" ConfirmBWTest.Text="OBS가 대역폭 시험 상태입니다. 방송을 송출하지 않고 네트워크를 점검할 수 있습니다. 시험을 종료해야 시청자가 방송을 볼 수 있습니다.\n\n계속하겠습니까?" @@ -255,6 +263,8 @@ Output.StartRecordingFailed="녹화를 시작하지 못했습니다" Output.StartReplayFailed="리플레이 버퍼를 시작하지 못했습니다" Output.StartFailedGeneric="출력을 시작하지 못했습니다. 기록 파일을 확인하십시오.\n\n참고: NVENC 혹은 AMD 인코더를 사용하고 있다면 드라이버를 최신 버전으로 유지하십시오." +Output.ReplayBuffer.PauseWarning.Title="일시정지 상태에서는 리플레이를 저장할 수 없습니다" +Output.ReplayBuffer.PauseWarning.Text="경고: 녹화가 일시정지되어 있는 상태에서는 리플레이를 저장할 수 없습니다." Output.ConnectFail.Title="연결에 실패했음" Output.ConnectFail.BadPath="잘못된 경로 혹은 연결 주소입니다. 유효한 값인지 설정을 확인하시기 바랍니다. " @@ -444,6 +454,8 @@ Basic.Main.StartRecording="녹화 시작" Basic.Main.StartReplayBuffer="리플레이 버퍼 시작" Basic.Main.StartStreaming="방송 시작" Basic.Main.StopRecording="녹화 중단" +Basic.Main.PauseRecording="녹화 일시정지" +Basic.Main.UnpauseRecording="녹화 일시정지 해제" Basic.Main.StoppingRecording="녹화를 중단합니다...." Basic.Main.StopReplayBuffer="리플레이 버퍼 중단" Basic.Main.StoppingReplayBuffer="리플레이 버퍼를 멈추고 있습니다..," @@ -502,6 +514,7 @@ Basic.MainMenu.View.Toolbars="도구 모음(&T)" Basic.MainMenu.View.Docks="독" Basic.MainMenu.View.Docks.ResetUI="사용자 인터페이스 초기화" Basic.MainMenu.View.Docks.LockUI="사용자 인터페이스 잠금" +Basic.MainMenu.View.Docks.CustomBrowserDocks="사용자 임의 브라우저 독..." Basic.MainMenu.View.Toolbars.Listboxes="목록 상자(&L)" Basic.MainMenu.View.SceneTransitions="장면 전환(&C)" Basic.MainMenu.View.StatusBar="상태 표시줄(&S)" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="프로그램을 시작할 때 자동 Basic.Settings.General.OpenStatsOnStartup="시작 시 통계 창을 열기" Basic.Settings.General.WarnBeforeStartingStream="방송을 시작할 때 확인 대화 상자 표시" Basic.Settings.General.WarnBeforeStoppingStream="방송을 중단할 때 확인 대화 상자 표시" +Basic.Settings.General.WarnBeforeStoppingRecord="녹화를 중단할 때 확인 대화 상자 표시" Basic.Settings.General.Projectors="프로젝터" Basic.Settings.General.HideProjectorCursor="프로젝터 위 커서 숨기기" Basic.Settings.General.ProjectorAlwaysOnTop="프로젝터를 항상 위로" @@ -591,12 +605,15 @@ Basic.Settings.Output.Encoder="인코더" Basic.Settings.Output.SelectDirectory="녹화 경로 선택" Basic.Settings.Output.SelectFile="녹화 파일 선택" Basic.Settings.Output.EnforceBitrate="방송 서비스의 비트레이트 제한 적용" +Basic.Settings.Output.DynamicBitrate="네트워크 혼잡 상태를 관리하기 위해서 비트레이트를 유동적으로 변경합니다" +Basic.Settings.Output.DynamicBitrate.Beta="네트워크 혼잡 상태를 관리하기 위해서 비트레이트를 유동적으로 변경합니다 (베타)" +Basic.Settings.Output.DynamicBitrate.TT="혼잡을 줄이기 위해 프레임을 떨어뜨리는 대신 적용 중인 비트레이트를 유동적으로 조절합니다.\n\n중대한 혼잡 상태가 급작스럽게 발생할 때 시청자들이 접하는 화면이 어느정도 지체될 수 있습니다.\n비트레이트가 감소하면 복구하는데 수 분이 걸릴 수 있습니다.\n\n이 기능은 현재 RTMP에서만 지원합니다." Basic.Settings.Output.Mode="출력 방식" Basic.Settings.Output.Mode.Simple="단순" Basic.Settings.Output.Mode.Adv="고급" Basic.Settings.Output.Mode.FFmpeg="FFmpeg 출력" Basic.Settings.Output.UseReplayBuffer="리플레이 버퍼 활성화" -Basic.Settings.Output.ReplayBuffer.SecondsMax="최대 리플레이 시간 (초 단위)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="최대 리플레이 시간" Basic.Settings.Output.ReplayBuffer.MegabytesMax="최대 메모리 (메가바이트 단위)" Basic.Settings.Output.ReplayBuffer.Estimate="예상되는 메모리 사용량: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="메모리 사용량을 계산할 수 없습니다. 최대 메모리 사용량을 설정하세요." @@ -611,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="무손실 상태와 비교하 Basic.Settings.Output.Simple.RecordingQuality.Lossless="무손실 품질, 아주 큰 파일 크기" Basic.Settings.Output.Simple.Warn.VideoBitrate="경고: 비디오 비트레이트가 선택한 스트리밍 서비스의 상한선인 %1으로 적용됩니다. %1이상으로 설정하려면 인코더 설정을 고급으로 전환한 다음 \"방송 서비스의 비트레이트 제한 적용\" 설정을 끄십시오." Basic.Settings.Output.Simple.Warn.AudioBitrate="경고: 오디오 비트레이트가 선택한 스트리밍 서비스의 상한선인 %1으로 적용됩니다. %1이상으로 설정하려면 인코더 설정을 고급으로 전환한 다음 \"방송 서비스의 비트레이트 제한 적용\" 설정을 끄십시오." +Basic.Settings.Output.Simple.Warn.CannotPause="경고: 녹화 품질이 \"방송과 동일\"로 설정되어 있으면 녹화를 일시정지할 수 없습니다." Basic.Settings.Output.Simple.Warn.Encoder="경고: 방송과 녹화를 동시에 진행할 때 다음을 주의하십시오. 소프트웨어 인코더로 방송과 다른 품질로 녹화하면 더 많은 CPU 부담이 발생합니다." Basic.Settings.Output.Simple.Warn.Lossless="경고: 무손실 품질로 녹화하면 파일 크기가 엄청나게 커집니다! 해당 설정은 높은 해상도 및 프레임에서 분당 7기가바이트 이상 필요합니다. 따라서 디스크에 아주 큰 공간을 확보하지 않는 이상 장시간 녹화에는 추천하지 않습니다." Basic.Settings.Output.Simple.Warn.Lossless.Msg="정말로 무손실 품질로 녹화하겠습니까?" @@ -623,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="소프트웨어 (x264 CPU Basic.Settings.Output.VideoBitrate="비디오 비트레이트" Basic.Settings.Output.AudioBitrate="오디오 비트레이트" Basic.Settings.Output.Reconnect="자동으로 다시 연결" -Basic.Settings.Output.RetryDelay="재접속 간격 (초 단위)" +Basic.Settings.Output.RetryDelay="재시도 지연" Basic.Settings.Output.MaxRetries="최대 재시도 횟수" Basic.Settings.Output.Advanced="고급 인코더 설정 활성화" Basic.Settings.Output.EncoderPreset="인코더 사전설정" @@ -694,7 +712,8 @@ Basic.Settings.Video.DisableAero="에어로 테마 끄기" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (가장 빠르지만 크기가 변경 시 영상이 흐려짐 )" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (영상 크기 변경을 좀 더 날카롭게 처리, 16 샘플)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (영상 크기 변경을 좀 더 날카롭게 처리, 32 샘플)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (영상 크기 변경을 좀 더 날카롭게 처리, 36 샘플)" +Basic.Settings.Video.DownscaleFilter.Area="영역 (가중치 합, 4/6/9 견본)" Basic.Settings.Audio="오디오" Basic.Settings.Audio.SampleRate="샘플 레이트" @@ -708,7 +727,7 @@ Basic.Settings.Audio.PeakMeterType="피크 미터 형식" Basic.Settings.Audio.PeakMeterType.SamplePeak="샘플 피크" Basic.Settings.Audio.PeakMeterType.TruePeak="트루 피크 (더 높은 CPU 자원 요구)" Basic.Settings.Audio.MultiChannelWarning.Enabled="경고: 서라운드 음향이 켜져 있습니다." -Basic.Settings.Audio.MultichannelWarning="방송 중이라면 서비스에서 서라운드 음향에 대한 입력 및 재생을 지원하는지 확인하세요. 트위치, 페이스북 360 라이브, Mixer RTMP, Smashcast 는 해당 기능을 사용할 수 있습니다. 페이스북 Live와 유튜브 Live 서비스는 입력은 할 수 있지만 스테레오로 전환하며 유튜브 Live는 오로지 2채널로만 재생합니다.\n\nOBS 오디오 필터는 서라운드 음향을 지원하지만 VST 플러그인 지원은 보장하지 않습니다." +Basic.Settings.Audio.MultichannelWarning="방송 중이라면 서비스에서 서라운드 음향에 대한 입력 및 재생을 지원하는지 확인하세요. 페이스북 360 라이브, Mixer RTMP, Smashcast 는 해당 기능을 사용할 수 있습니다. 페이스북 Live와 유튜브 Live 서비스는 입력은 할 수 있지만 스테레오로 전환하며 유튜브 Live는 오로지 2채널로만 재생합니다.\n\nOBS 오디오 필터는 서라운드 음향을 지원하지만 VST 플러그인 지원은 보장하지 않습니다." Basic.Settings.Audio.MultichannelWarning.Title="서라운드 음향을 활성화할까요?" Basic.Settings.Audio.MultichannelWarning.Confirm="정말로 서라운드 음향을 사용하겠습니까?" Basic.Settings.Audio.Devices="장치" @@ -743,23 +762,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="감시 장치" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="기본값" Basic.Settings.Advanced.Audio.DisableAudioDucking="윈도우 오디오 더킹 비활성화" Basic.Settings.Advanced.StreamDelay="방송 지연" -Basic.Settings.Advanced.StreamDelay.Duration="기간 (초)" +Basic.Settings.Advanced.StreamDelay.Duration="지속 시간" Basic.Settings.Advanced.StreamDelay.Preserve="재접속 시 잘려나간 지점 보관 (지연시간 증가)" Basic.Settings.Advanced.StreamDelay.MemoryUsage="예상되는 메모리 사용량: %1 MB" Basic.Settings.Advanced.Network="네트워크" Basic.Settings.Advanced.Network.BindToIP="IP에 고정" Basic.Settings.Advanced.Network.EnableNewSocketLoop="새로운 네트워크 코드 활성화" Basic.Settings.Advanced.Network.EnableLowLatencyMode="짧은 지연시간 방식 사용" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="단축키 작동 방식" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="단축키를 절대로 비활성화하지 말 것" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="주요 창을 초점으로 둘 때 단축키를 비활성화" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="주요 창을 보고있지 않으면 단축키를 비활성화" Basic.Settings.Advanced.AutoRemux="mp4 형식으로 재다중화" Basic.Settings.Advanced.AutoRemux.MP4="(녹화는 mkv 형식)" Basic.AdvAudio="오디오 고급 설정" Basic.AdvAudio.Name="이름" Basic.AdvAudio.Volume="음량" -Basic.AdvAudio.Mono="모노로 강제 송출" +Basic.AdvAudio.Mono="모노" Basic.AdvAudio.Balance="균형" -Basic.AdvAudio.SyncOffset="싱크 오프셋 (ms)" +Basic.AdvAudio.SyncOffset="싱크 오프셋" Basic.AdvAudio.Monitoring="오디오 모니터링" Basic.AdvAudio.Monitoring.None="모니터링 끔" Basic.AdvAudio.Monitoring.MonitorOnly="모니터링만 (출력은 제거)" @@ -825,6 +847,7 @@ SceneItemHide="'%1' 숨기기" OutputWarnings.NoTracksSelected="최소 하나의 트랙을 선택해야 합니다" OutputWarnings.MultiTrackRecording="경고: 일부 형식(예를 들어 FLV)은 녹화 하나에 여러 개의 트랙을 지원하지 않습니다" OutputWarnings.MP4Recording="경고: MP4로 녹화를 하면 파일이 마무리가 되지 않았을 때 (예를 들어, 컴퓨터가 급작스럽게 꺼지거나 블루 스크린 오류가 일어나는 경우) 복구할 수 없습니다. 여러 개의 오디오 트랙을 녹음하고 싶다면 MKV 확장자로 녹화 한 뒤 재다중화 작업을 통해 MP4/MOV로 변환하십시오. (파일 → 재다중화 녹화)" +OutputWarnings.CannotPause="경고: 녹화 인코더가 \"(스트림 인코더 사용)\"으로 설정되어 있으면 녹화를 일시정지할 수 없습니다." FinalScene.Title="장면 삭제" FinalScene.Text="적어도 하나의 장면은 존재해야 합니다." diff --git a/UI/data/locale/ku-TR.ini b/UI/data/locale/ku-TR.ini index e7bbcf3..1ba98da 100644 --- a/UI/data/locale/ku-TR.ini +++ b/UI/data/locale/ku-TR.ini @@ -23,7 +23,6 @@ Settings="ڕێکخستنەکان" Display="پیشاندراو" Name="ناو" Exit="ده‌رچوون" -Mixer="میکسەر" Browse="هێنان" Mono="یەک بڵندگۆ" Stereo="دوو بڵندگۆ" @@ -55,6 +54,7 @@ StudioMode.Preview="پێشبینین" + Auth.Chat="گفتوگۆکردن" Copy.Filters="لەبەرگرتنەوەی فلتەرەکان" @@ -89,6 +89,7 @@ Basic.TogglePreviewProgramMode="شێوازی ستۆدیۆ" + ConfirmExit.Title="ده‌رچوون لە OBS" diff --git a/UI/data/locale/lt-LT.ini b/UI/data/locale/lt-LT.ini index 50ba99e..c93b799 100644 --- a/UI/data/locale/lt-LT.ini +++ b/UI/data/locale/lt-LT.ini @@ -23,7 +23,6 @@ Settings="Nustatymai" Display="Ekranas" Name="Vardas" Exit="Išeiti" -Mixer="Mikseris" Browse="Naršyti" Mono="Mono" Stereo="Stereo" @@ -66,6 +65,7 @@ Import="Importuoti" + QuickTransitions.SwapScenes="Sukeisti Peržiūros/Išvesties scenas po Perėjimo" QuickTransitions.SwapScenesTT="Sukeičia peržiūros ir išvesties scenas po perėjimo įvykdymo (jei originali išvesties scena vis dar egzistuoja).\nTai neatšauks jokių pakeitimų kurie galima buvo atlikti originalioje išvesties scenoje." QuickTransitions.DuplicateScene="Dubliuoti Sceną" @@ -98,6 +98,7 @@ ConfirmStop.Title="Stabdyti transliaciją?" ConfirmStop.Text="Ar esate įsitikinęs, kad norite stabdyti transliavimą?" + ConfirmExit.Title="Išeiti iš OBS?" ConfirmExit.Text="OBS metu yra aktyvus. Visos transliacijos/įrašymai bus išjungti. Ar tikrai norite išeiti?" @@ -294,7 +295,6 @@ Basic.Settings.Advanced.Video.ColorRange.Partial="Dalinis" Basic.Settings.Advanced.Video.ColorRange.Full="Pilnas" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Numatytas" Basic.Settings.Advanced.StreamDelay="Srauto Vėlavimas" -Basic.Settings.Advanced.StreamDelay.Duration="Trukmė (sekundėmis)" Basic.Settings.Advanced.StreamDelay.Preserve="Išsaugoti apkarpymo tašką (padidina vėlavimą) įrašinėjant" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Numatomas atminties naudojimas: %1 MB" Basic.Settings.Advanced.Network="Tinklas" diff --git a/UI/data/locale/mn-MN.ini b/UI/data/locale/mn-MN.ini index 8659336..33ef3c4 100644 --- a/UI/data/locale/mn-MN.ini +++ b/UI/data/locale/mn-MN.ini @@ -23,7 +23,6 @@ Settings="Тохиргоо" Display="Харагдах байдал" Name="Нэр" Exit="Гарах" -Mixer="Холигч" Browse="Хайх" Mono="Моно" Stereo="Стерео" @@ -66,6 +65,7 @@ AlreadyRunning.LaunchAnyway="Юутай ч эхлүүл" + BandwidthTest.Region="Бүс нутаг" BandwidthTest.Region.US="Нэгдсэн Улс" BandwidthTest.Region.EU="Европ" @@ -119,6 +119,7 @@ ConfirmStart.Title="Цацаж эхлэх үү?" ConfirmStop.Title="Цацалтыг зогсоох?" + ConfirmExit.Title="OBS-ийг хаах" ConfirmRemove.Title="Хасалтыг батлах" diff --git a/UI/data/locale/ms-MY.ini b/UI/data/locale/ms-MY.ini index 23d88ba..a53cc23 100644 --- a/UI/data/locale/ms-MY.ini +++ b/UI/data/locale/ms-MY.ini @@ -23,7 +23,6 @@ Settings="Tetapan" Display="Paparan" Name="Nama" Exit="Keluar" -Mixer="Pengadun suara" Browse="Cari" Mono="Mono" Stereo="Stereo" @@ -66,6 +65,7 @@ Back="Kembali" + BandwidthTest.Region.EU="Eropah" BandwidthTest.Region.Asia="Asia" BandwidthTest.Region.Other="Lain-lain" @@ -121,6 +121,7 @@ ConfirmStop.Title="Berhenti 'Stream'?" ConfirmStop.Text="Adakah anda pasti anda mahu menghentikan 'stream'?" + ConfirmExit.Title="Tutup OBS?" ConfirmExit.Text="OBS kini sedang aktif. Semua 'stream'/rakaman akan ditutup. Adakah anda pasti anda mahu tutup(OBS)?" @@ -367,7 +368,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (Preset x264: peng Basic.Settings.Output.VideoBitrate="Nilai Bit Video" Basic.Settings.Output.AudioBitrate="Nilai Bit Audio" Basic.Settings.Output.Reconnect="Sambung semula secara automatik" -Basic.Settings.Output.RetryDelay="Kelewatan Percubaan (saat)" Basic.Settings.Output.MaxRetries="Cubaan Maksimum" Basic.Settings.Output.Adv.AudioTrack="Trek Audio" diff --git a/UI/data/locale/nb-NO.ini b/UI/data/locale/nb-NO.ini index 94fdd8c..85a8e8a 100644 --- a/UI/data/locale/nb-NO.ini +++ b/UI/data/locale/nb-NO.ini @@ -23,7 +23,7 @@ Settings="Innstillinger" Display="Skjerm" Name="Navn" Exit="Avslutt" -Mixer="Mikser" +Mixer="Lydmikser" Browse="Bla gjennom" Mono="Mono" Stereo="Stereo" @@ -91,6 +91,7 @@ AlreadyRunning.LaunchAnyway="Start uansett" DockCloseWarning.Title="Lukker festbart vindu" DockCloseWarning.Text="Du stengte nettopp et festbart vindu. Hvis du vil vise det igjen, kan du gå til Vis → Festede elementer i menylinjen." + Auth.Authing.Title="Autentiserer..." Auth.Authing.Text="Autentiserer med %1, vennligst vent..." Auth.AuthFailure.Title="Autentiseringsfeil" @@ -139,7 +140,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 eller 30, men foretrekk høy op Basic.AutoConfig.VideoPage.CanvasExplanation="NB: Oppløsningen på lerretet er ikke nødvendigvis den samme oppløsningen som du vil kringkaste eller ta opp med. Den faktiske kringkastings- eller opptaks-oppløsningen kan bli nedskalert fra størrelsen på lerretet for å redusere ressursbruken eller bitfrekvensen." Basic.AutoConfig.StreamPage="Strømmens informasjon" Basic.AutoConfig.StreamPage.SubTitle="Vennligst skriv inn strømmens informasjon" -Basic.AutoConfig.StreamPage.ConnectAccount="Koble til med konto (valgfritt)" +Basic.AutoConfig.StreamPage.ConnectAccount="Koble til med konto (anbefalt)" Basic.AutoConfig.StreamPage.DisconnectAccount="Koble fra kontoen" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Vil du koble fra kontoen?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Endringen vil bli benyttet umiddelbart. Er du sikker på at du vil koble fra kontoen din?" @@ -240,6 +241,8 @@ ConfirmStart.Text="Er du sikker på at du vil begynne å sende?" ConfirmStop.Title="Vil du avslutte sendingen?" ConfirmStop.Text="Er du sikker på at du vil avslutte sendingen?" +ConfirmStopRecord.Title="Vil du stoppe opptaket?" + ConfirmBWTest.Title="Start bredbåndstest?" ConfirmBWTest.Text="Du har konfigurert OBS i bredbåndstest-modus. Denne modusen tillater nettverkstesting uten at din kanal går live. Du må deaktivere modusen når du er ferdig å teste for at seere vil kunne se din strøm. \n\nVil du fortsette?" @@ -444,6 +447,8 @@ Basic.Main.StartRecording="Start Opptak" Basic.Main.StartReplayBuffer="Start omspillingsbuffer" Basic.Main.StartStreaming="Start Strømming" Basic.Main.StopRecording="Stopp Opptak" +Basic.Main.PauseRecording="Sett opptaket på pause" +Basic.Main.UnpauseRecording="Fortsett opptaket" Basic.Main.StoppingRecording="Stanser innspilling…" Basic.Main.StopReplayBuffer="Stopp omspillingsbufferen" Basic.Main.StoppingReplayBuffer="Stopper omspillingsbufferen..." @@ -596,7 +601,6 @@ Basic.Settings.Output.Mode.Simple="Enkel" Basic.Settings.Output.Mode.Adv="Avansert" Basic.Settings.Output.Mode.FFmpeg="FFmpeg-utgang" Basic.Settings.Output.UseReplayBuffer="Aktiver omspillingsbufferen" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksimal omspillingstid (i sekunder)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maksimal minnebruk (Megabytes)" Basic.Settings.Output.ReplayBuffer.Estimate="Anslått minnebruk: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Kan ikke beregne minnebruk. Vennligst sett maksimalt minnebrukgrense." @@ -623,7 +627,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Programvare (Forhåndsinnst Basic.Settings.Output.VideoBitrate="Bilde-bitfrekvens" Basic.Settings.Output.AudioBitrate="Lyd-bitfrekvens" Basic.Settings.Output.Reconnect="Koble automatisk til på nytt" -Basic.Settings.Output.RetryDelay="Opphold mellom tilkoblingsforsøk (sekunder)" Basic.Settings.Output.MaxRetries="Høyst antall tilkoblingsforsøk" Basic.Settings.Output.Advanced="Aktiver avanserte koderinnstillinger" Basic.Settings.Output.EncoderPreset="Kodingsinstillinger" @@ -694,7 +697,7 @@ Basic.Settings.Video.DisableAero="Skru av Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilineær (raskest, men uskarp ved skalering)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bikubisk (skjerpet skalering, 16 prøver)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (skjerpet skalering, 32 prøver)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (skjerpet skalering, 36 prøver)" Basic.Settings.Audio="Lyd" Basic.Settings.Audio.SampleRate="Samplingsfrekvens" @@ -708,7 +711,7 @@ Basic.Settings.Audio.PeakMeterType="Toppunktmålertype" Basic.Settings.Audio.PeakMeterType.SamplePeak="Samplingstoppunkt" Basic.Settings.Audio.PeakMeterType.TruePeak="Ekte toppunkt (Høyere CPU-bruk)" Basic.Settings.Audio.MultiChannelWarning.Enabled="Advarsel: Surroundlyd er aktivert." -Basic.Settings.Audio.MultichannelWarning="Hvis du strømmer, sjekk om strømmetjenesten din støtter både surround-lydinnføring og surround-lydavspilling. Twitch, Facebook 360 Live, Mixer RTMP, og Smashcast er eksempler hvor surroundlyd er full støttet. Selv om Facebook Live og YouTube Live begge støtter surround-innføring, nedmikser Facebook Live det ned til Stereo, og YouTube Live spiller bare av to kanaler.\n\nOBS-lydfiltre er kompatible med surroundlyd, selv om VST-tilleggsstøtte ikke er garantert." +Basic.Settings.Audio.MultichannelWarning="Hvis du strømmer, sjekk om strømmetjenesten din støtter både surround-lydinnføring og surround-lydavspilling. Facebook 360 Live, Mixer RTMP, og Smashcast er eksempler hvor surroundlyd er full støttet. Selv om Facebook Live og YouTube Live begge støtter surround-innføring, nedmikser Facebook Live det ned til Stereo, og YouTube Live spiller bare av to kanaler.\n\nOBS-lydfiltre er kompatible med surroundlyd, selv om VST-tilleggsstøtte ikke er garantert." Basic.Settings.Audio.MultichannelWarning.Title="Vil du aktivere surround-lyd?" Basic.Settings.Audio.MultichannelWarning.Confirm="Er du sikker på at du vil aktivere surround-lyd?" Basic.Settings.Audio.Devices="Enheter" @@ -743,7 +746,7 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Lydenhet for overvåking" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Standard" Basic.Settings.Advanced.Audio.DisableAudioDucking="Deaktiver Windows-lyddukking" Basic.Settings.Advanced.StreamDelay="Direktesendingsforsinkelse" -Basic.Settings.Advanced.StreamDelay.Duration="Varighet (sekunder)" +Basic.Settings.Advanced.StreamDelay.Duration="Varighet" Basic.Settings.Advanced.StreamDelay.Preserve="Bevar avkuttingspunktet (øk forsinkelse) ved tilbakekobling" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Anslått minnebruk: %1 MB" Basic.Settings.Advanced.Network="Nettverk" @@ -757,9 +760,9 @@ Basic.Settings.Advanced.AutoRemux.MP4="(Gjør opptak som MKV)" Basic.AdvAudio="Avanserte lydinnstillinger" Basic.AdvAudio.Name="Navn" Basic.AdvAudio.Volume="Volum" -Basic.AdvAudio.Mono="Nedmiks til mono" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Balanse" -Basic.AdvAudio.SyncOffset="Synkroniseringsforskyvning (ms)" +Basic.AdvAudio.SyncOffset="Synkroniser avvik" Basic.AdvAudio.Monitoring="Hør på kilde" Basic.AdvAudio.Monitoring.None="Ikke hør kilden" Basic.AdvAudio.Monitoring.MonitorOnly="Kun hør kilden (Demp utdataen)" diff --git a/UI/data/locale/nl-NL.ini b/UI/data/locale/nl-NL.ini index 922d7ec..38661fa 100644 --- a/UI/data/locale/nl-NL.ini +++ b/UI/data/locale/nl-NL.ini @@ -23,7 +23,7 @@ Settings="Instellingen" Display="Beeldscherm" Name="Naam" Exit="Afsluiten" -Mixer="Mixer" +Mixer="Audio Mixer" Browse="Bladeren" Mono="Mono" Stereo="Stereo" @@ -91,6 +91,10 @@ AlreadyRunning.LaunchAnyway="Toch Starten" DockCloseWarning.Title="Dokbaar Venster Sluiten" DockCloseWarning.Text="Je hebt net een dokbaar venster gesloten. Als je het opnieuw wilt zien, gebruik dan het menu Beeld → Docks in de menubalk." +ExtraBrowsers="Aangepaste Browser Docks" +ExtraBrowsers.Info="Voeg docks toe door ze een naam en URL te geven, klik vervolgens op Toepassen of Sluiten om de docks te openen. U kunt op elk moment docks toevoegen of verwijderen." +ExtraBrowsers.DockName="Dock Naam" + Auth.Authing.Title="Authenticeren..." Auth.Authing.Text="Authenticeren met %1, even geduld a.u.b..." Auth.AuthFailure.Title="Verificatiefout" @@ -107,6 +111,7 @@ TwitchAuth.Stats="Twitch statistieken" TwitchAuth.Feed="Twitch activiteitenfeed" TwitchAuth.TwoFactorFail.Title="Kon stream key niet opvragen" TwitchAuth.TwoFactorFail.Text="OBS kon geen verbinding maken met uw Twitch account. Zorg ervoor dat er twee-factor authenticatie is ingesteld in uw Twitch beveiligingsinstellingen, omdat dit nodig is om te streamen." +RestreamAuth.Channels="Restream Kanalen" Copy.Filters="Kopieer Filters" Paste.Filters="Plak filters" @@ -139,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 of 30, maar geef de voorkeur aa Basic.AutoConfig.VideoPage.CanvasExplanation="Let op: de basisresolutie (canvas) hoeft niet gelijk te zijn als de resolutie waarmee je streamt of opneemt. Je stream/opnameresolutie kan omlaag bijgeschaald worden vanaf de basisresolutie om de belasting op de computer of de benodigde bitrate te verlagen." Basic.AutoConfig.StreamPage="Stream-informatie" Basic.AutoConfig.StreamPage.SubTitle="Voer alstublieft uw stream-informatie in" -Basic.AutoConfig.StreamPage.ConnectAccount="Account verbinden (optioneel)" +Basic.AutoConfig.StreamPage.ConnectAccount="Verbind Account (aanbevolen)" Basic.AutoConfig.StreamPage.DisconnectAccount="Account loskoppelen" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Account loskoppelen?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Deze wijziging zal onmiddellijk van toepassing zijn. Weet u zeker dat u uw account wilt loskoppelen?" @@ -240,6 +245,9 @@ ConfirmStart.Text="Weet je zeker dat je de stream wil starten?" ConfirmStop.Title="Stop de Stream?" ConfirmStop.Text="Weet je zeker dat je de stream wil stoppen?" +ConfirmStopRecord.Title="Opname Stoppen?" +ConfirmStopRecord.Text="Bent u zeker dat u de opname wilt stoppen?" + ConfirmBWTest.Title="Bandbreedte test starten?" ConfirmBWTest.Text="U heeft OBS geconfigureerd in bandbreedte test modus. Deze modus maakt het mogelijk om netwerk te testen zonder live te gaan. Zodra u klaar bent met testen, moet u deze uitschakelen om de kijkers in staat te stellen uw stream te zien.\n\nWilt u doorgaan?" @@ -255,6 +263,8 @@ Output.StartRecordingFailed="Het starten van de opname is mislukt" Output.StartReplayFailed="Het starten van de replay buffer is mislukt" Output.StartFailedGeneric="Het starten van de uitvoer is mislukt. Controleer de logbestanden voor meer informatie.\n\nLet op: Als je gebruik maakt van de NVENC of AMD encoders, controleer of de drivers up to date zijn." +Output.ReplayBuffer.PauseWarning.Title="Herhalingen kunnen niet worden opgeslagen tijdens het pauzeren" +Output.ReplayBuffer.PauseWarning.Text="Waarschuwing: Herhalingen kunnen niet worden opgeslagen tijdens het pauzeren van de opname." Output.ConnectFail.Title="Kan geen verbinding maken" Output.ConnectFail.BadPath="Ongeldig pad of verbindings-url. Controleer a.u.b. of je instellingen geldig zijn." @@ -444,6 +454,8 @@ Basic.Main.StartRecording="Opname Starten" Basic.Main.StartReplayBuffer="Start Replay Buffer" Basic.Main.StartStreaming="Stream Starten" Basic.Main.StopRecording="Opname Stoppen" +Basic.Main.PauseRecording="Opname pauzeren" +Basic.Main.UnpauseRecording="Opname vervolgen" Basic.Main.StoppingRecording="Opname Stoppen..." Basic.Main.StopReplayBuffer="Stop Replay Buffer" Basic.Main.StoppingReplayBuffer="Replay Buffer aan het stoppen..." @@ -502,6 +514,7 @@ Basic.MainMenu.View.Toolbars="Werkbalken (&T)" Basic.MainMenu.View.Docks="Docks" Basic.MainMenu.View.Docks.ResetUI="Herstel UI" Basic.MainMenu.View.Docks.LockUI="Zet UI Vast" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Aangepaste Browser Docks..." Basic.MainMenu.View.Toolbars.Listboxes="&Lijsten" Basic.MainMenu.View.SceneTransitions="S&cène-overgangen" Basic.MainMenu.View.StatusBar="&Statusbalk" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="Automatisch controleren op updates tij Basic.Settings.General.OpenStatsOnStartup="Open statistieken bij het opstarten" Basic.Settings.General.WarnBeforeStartingStream="Laat bevestigingsvenster zien bij het starten van streams" Basic.Settings.General.WarnBeforeStoppingStream="Laat bevestiginsvenster zien bij het stoppen van streams" +Basic.Settings.General.WarnBeforeStoppingRecord="Laat bevestigingsvenster zien bij het stoppen van opnames" Basic.Settings.General.Projectors="Projectoren" Basic.Settings.General.HideProjectorCursor="Verberg cursor boven projectors" Basic.Settings.General.ProjectorAlwaysOnTop="Houd projectoren altijd bovenaan" @@ -591,12 +605,15 @@ Basic.Settings.Output.Encoder="Encoder" Basic.Settings.Output.SelectDirectory="Selecteer Opnamemap" Basic.Settings.Output.SelectFile="Selecteer Opnamebestand" Basic.Settings.Output.EnforceBitrate="Forceer bandbreedtelimieten van streaming dienst" +Basic.Settings.Output.DynamicBitrate="Dynamisch wijzigen van de bitrate om congestie te beheren" +Basic.Settings.Output.DynamicBitrate.Beta="Dynamisch wijzigen van de bitrate om congestie te beheren (Beta)" +Basic.Settings.Output.DynamicBitrate.TT="In plaats van frames te laten vallen om congestie te verminderen, verandert de bitrate dynamisch à la minute.\n\nMerk op dat dit de vertraging voor kijkers kan verhogen als er significante plotselinge congestie optreedt.\nAls de bitrate daalt, kan het tot een paar minuten duren om het te herstellen.\n\nMomenteel wordt het alleen ondersteund voor RTMP." Basic.Settings.Output.Mode="Uitvoermodus" Basic.Settings.Output.Mode.Simple="Simpel" Basic.Settings.Output.Mode.Adv="Geavanceerd" Basic.Settings.Output.Mode.FFmpeg="FFmpeg-uitvoer" Basic.Settings.Output.UseReplayBuffer="Replay Buffer Inschakelen" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximale Replay-tijd (Seconden)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximale herhalingstijd" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximale hoeveelheid geheugen (Megabytes)" Basic.Settings.Output.ReplayBuffer.Estimate="Geschat geheugengebruik: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Kan geheugengebruik niet inschatten. Stel een limiet in op het geheugengebruik." @@ -611,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Ononderscheidbare Kwaliteit, G Basic.Settings.Output.Simple.RecordingQuality.Lossless="Lossless Kwaliteit, Enorm Grote Bestandsgrootte" Basic.Settings.Output.Simple.Warn.VideoBitrate="Waaschuwing: De video bitrate zal worden ingesteld op %1, dit is de bovengrens van de huidige streaming dienst. Als je zeker weet dat je hoger wil gaan dan %1, schakel dan de geavanceerde encoder-opties in en vink de optie \"Forceer bandbreedtelimieten van streaming dienst\" uit." Basic.Settings.Output.Simple.Warn.AudioBitrate="Waaschuwing: De audio bitrate zal worden ingesteld op %1, dit is de bovengrens van de huidige streaming dienst. Als je zeker weet dat je hoger wil gaan dan %1, schakel dan de geavanceerde encoder-opties in en vink de optie \"Forceer bandbreedtelimieten van streaming dienst\" uit." +Basic.Settings.Output.Simple.Warn.CannotPause="Waarschuwing: Opnames kunnen niet worden onderbroken als de opnamekwaliteit is ingesteld op \"Hetzelfde als stream\"." Basic.Settings.Output.Simple.Warn.Encoder="Waarschuwing: Opname met een software-encoder op een andere kwaliteit dan de stream vergt extra cpu-gebruik als je zowel aan het streamen en aan het opnemen bent." Basic.Settings.Output.Simple.Warn.Lossless="Waarschuwing: Lossless kwaliteit genereert erg grote bestanden! Lossless kwaliteit kan tot wel 7 GB aan schijfruimte per minuut gebruiken bij hoge resoluties en framerates. Lossless kwaliteit is niet aanbevolen voor lange opnames tenzij er een grote hoeveelheid schijfruimte beschikbaar is." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Weet je zeker dat je lossless kwaliteit wilt gebruiken?" @@ -623,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 laag cpu geb Basic.Settings.Output.VideoBitrate="Video Bitrate" Basic.Settings.Output.AudioBitrate="Audio Bitrate" Basic.Settings.Output.Reconnect="Automatisch Opnieuw Verbinden" -Basic.Settings.Output.RetryDelay="Opnieuw proberen na (seconden)" +Basic.Settings.Output.RetryDelay="Vertraging nieuwe poging" Basic.Settings.Output.MaxRetries="Maximaal aantal pogingen" Basic.Settings.Output.Advanced="Geavanceerde Encoderinstellingen Inschakelen" Basic.Settings.Output.EncoderPreset="Encoder Preset" @@ -694,7 +712,7 @@ Basic.Settings.Video.DisableAero="Aero uitschakelen" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (Snelste, maar wazig bij schalen)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (Scherper schalen, 16 samples)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Scherper schalen, 32 samples)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Scherper schalen, 36 samples)" Basic.Settings.Audio="Audio" Basic.Settings.Audio.SampleRate="Sample Rate" @@ -708,7 +726,7 @@ Basic.Settings.Audio.PeakMeterType="Piek Meter Type" Basic.Settings.Audio.PeakMeterType.SamplePeak="Sample piek" Basic.Settings.Audio.PeakMeterType.TruePeak="True piek (hogere CPU-gebruik)" Basic.Settings.Audio.MultiChannelWarning.Enabled="Waarschuwing: Surround sound audio is ingeschakeld." -Basic.Settings.Audio.MultichannelWarning="Als je streamt, controleer dan of je streaming service zowel surround sound ingest als surround sound afspelen ondersteunt. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast zijn voorbeelden waar surround sound volledig ondersteund is. Alhoewel Facebook Live en Youtube Live beide surround ingest ondersteunen, downmixt Facebook Live het naar stereo, terwijl Youtube Live slechts twee kanalen afspeelt.\n\nOBS audio filters kunnen overweg met surround sound, maar ondersteuning bij VST plugins is niet gegarandeerd." +Basic.Settings.Audio.MultichannelWarning="Als je streamt, controleer dan of je streaming service zowel surround sound ingest als surround sound afspelen ondersteunt. Facebook 360 Live, Mixer RTMP, Smashcast zijn voorbeelden waar surround sound volledig ondersteund is. Alhoewel Facebook Live en Youtube Live beide surround ingest ondersteunen, downmixt Facebook Live het naar stereo, terwijl Youtube Live slechts twee kanalen afspeelt.\n\nOBS audio filters kunnen overweg met surround sound, maar ondersteuning bij VST plugins is niet gegarandeerd." Basic.Settings.Audio.MultichannelWarning.Title="Surround sound audio inschakelen?" Basic.Settings.Audio.MultichannelWarning.Confirm="Weet je zeker dat je surround sound audio wil inschakelen?" Basic.Settings.Audio.Devices="Apparaten" @@ -743,23 +761,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Monitoring apparaat" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Standaard" Basic.Settings.Advanced.Audio.DisableAudioDucking="Schakel Windows audio ducking uit" Basic.Settings.Advanced.StreamDelay="Streamvertraging" -Basic.Settings.Advanced.StreamDelay.Duration="Duur (seconden)" +Basic.Settings.Advanced.StreamDelay.Duration="Duur" Basic.Settings.Advanced.StreamDelay.Preserve="Hervat op het eindpunt (verhoog vertraging) bij opnieuw verbinden" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Geschat Geheugengebruik: %1 MB" Basic.Settings.Advanced.Network="Netwerk" Basic.Settings.Advanced.Network.BindToIP="Bind aan IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Schakel nieuwe netwerkcode in" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Lage latency modus" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Sneltoets Focus Gedrag" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Nooit sneltoetsen uitschakelen" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Hotkeys uitschakelen wanneer hoofdvenster in focus is" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Schakel sneltoetsen uit wanneer hoofdvenster niet in focus is" Basic.Settings.Advanced.AutoRemux="Remux automatisch naar mp4" Basic.Settings.Advanced.AutoRemux.MP4="(neem op als mvk)" Basic.AdvAudio="Geavanceerde Audioinstellingen" Basic.AdvAudio.Name="Naam" Basic.AdvAudio.Volume="Volume" -Basic.AdvAudio.Mono="Downmixen naar Mono" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Balans" -Basic.AdvAudio.SyncOffset="Sync Offset (ms)" +Basic.AdvAudio.SyncOffset="Sync Offset" Basic.AdvAudio.Monitoring="Audio monitoring" Basic.AdvAudio.Monitoring.None="Niet monitoren" Basic.AdvAudio.Monitoring.MonitorOnly="Alleen monitoren (uitvoer gedempt)" @@ -825,6 +846,7 @@ SceneItemHide="Verberg '%1'" OutputWarnings.NoTracksSelected="Selecteer a.u.b. ten minste een track" OutputWarnings.MultiTrackRecording="Waarschuwing: Sommige formaten (zoals FLV) bieden geen ondersteuning voor meerdere tracks per opname" OutputWarnings.MP4Recording="Waarschuwing: Opnames opgeslagen als MP4/MOV zijn niet te herstellen als de opname niet correct afgerond kan worden (bijvoorbeeld door BSOD's, stroomuitval). Als je wil opnemen met meerdere audiotracks gebruik dan bij voorkeur MKV en remux de opname naar MP4/MOV (Bestand → Remux opnames)" +OutputWarnings.CannotPause="Waarschuwing: Opnames kunnen niet worden gepauzeerd als de opname encoder is ingesteld op \"(Gebruik stream encoder)\"" FinalScene.Title="Verwijder scène" FinalScene.Text="Er moet tenminste één scène zijn." diff --git a/UI/data/locale/nn-NO.ini b/UI/data/locale/nn-NO.ini index cd9915b..eb2bef9 100644 --- a/UI/data/locale/nn-NO.ini +++ b/UI/data/locale/nn-NO.ini @@ -23,21 +23,25 @@ Settings="Innstillingar" Display="Skjerm" Name="Namn" Exit="Avslutt" -Mixer="Blandar" Browse="Bla gjennom" Mono="Mono" Stereo="Stereo" DroppedFrames="Slopne bilete %1 (%2%)" StudioProgramProjector="Fullskjermframvisar (program)" PreviewProjector="Fullskjermframvisar (førehandsvising)" +SceneProjector="Fullskjermframvisar (Scene)" +SourceProjector="Fullskjermframvisar (Kjelde)" MultiviewProjector="Fleirvising (Fullskjerm)" MultiviewWindowed="Fleirvising (i vindauge)" Clear="Tøm" Show="Vis" Hide="Skjul" +UnhideAll="Vis alle" Untitled="Utan namn" New="Ny" Enable="Aktiver" +DisableOSXVSync="Slå av OSX V-Sync" +ResetOSXVSyncOnExit="Tilbakestill OSX V-Sync når du avsluttar" Left="Venstre" Right="Høgre" Top="Topp" @@ -62,6 +66,7 @@ StudioMode.Program="Program" + BandwidthTest.Region="Region" BandwidthTest.Region.EU="Europa" BandwidthTest.Region.Asia="Asia" @@ -109,6 +114,7 @@ ConfirmStart.Title="Starting av straum?" ConfirmStop.Title="Stoppe straumen?" + ConfirmExit.Title="Avslutt OBS?" diff --git a/UI/data/locale/pa-IN.ini b/UI/data/locale/pa-IN.ini index 241c83d..388adf4 100644 --- a/UI/data/locale/pa-IN.ini +++ b/UI/data/locale/pa-IN.ini @@ -21,7 +21,6 @@ Settings="ਸੈਟਿੰਗ" Display="ਸਕ੍ਰੀਨ" Name="ਨਾਮ" Exit="ਬੰਦ ਕਰੋ" -Mixer="ਆਡੀਓ ਮਿਲਾਓ" Browse="ਖੋਜ ਕਰੋ" @@ -113,6 +112,8 @@ Browse="ਖੋਜ ਕਰੋ" + + diff --git a/UI/data/locale/pl-PL.ini b/UI/data/locale/pl-PL.ini index 66b30b0..f098a82 100644 --- a/UI/data/locale/pl-PL.ini +++ b/UI/data/locale/pl-PL.ini @@ -23,7 +23,7 @@ Settings="Ustawienia" Display="Ekran" Name="Nazwa" Exit="Wyjście" -Mixer="Mikser" +Mixer="Mikser dźwięku" Browse="Przeglądaj" Mono="Mono" Stereo="Stereo" @@ -91,6 +91,10 @@ AlreadyRunning.LaunchAnyway="Uruchom mimo to" DockCloseWarning.Title="Zamykanie dokowalnego okna" DockCloseWarning.Text="Zostało zamknięte dokowalne okno/panel. Jeżeli chcesz ponownie je pokazać, wybierz Widok → Panele z głównego menu." +ExtraBrowsers="Panele przeglądarki" +ExtraBrowsers.Info="Dodaj panele określając ich nazwę oraz adres URL a następnie kliknij Zastosuj lub Zamknij by otworzyć je. Panele można dodawać i usuwać w każdej chwili." +ExtraBrowsers.DockName="Nazwa panelu" + Auth.Authing.Title="Uwierzytelnianie..." Auth.Authing.Text="Proszę czekać. Trwa uwierzytelnianie w %1..." Auth.AuthFailure.Title="Błąd uwierzytelnienia" @@ -107,6 +111,7 @@ TwitchAuth.Stats="Statystyki Twitch" TwitchAuth.Feed="Lista aktywności Twitch" TwitchAuth.TwoFactorFail.Title="Nie można pobrać klucza strumienia" TwitchAuth.TwoFactorFail.Text="Powiązanie Twojego konta Twitch w OBS nie udało się. Sprawdź, czy masz włączone uwierzytelnianie dwuskładnikowe w ustawieniach bezpieczeństwa Twitcha. Wymagane jest to do streamowania przez tę platformę." +RestreamAuth.Channels="Kanały Restream" Copy.Filters="Kopiuj filtry" Paste.Filters="Wklej filtry" @@ -139,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 lub 30 ale preferuj większą r Basic.AutoConfig.VideoPage.CanvasExplanation="Rozdzielczość bazowa niekoniecznie musi być rozdzielczością wynikowego nagrania lub streamu. Ta druga może być efektem skalowania w dół w celu zmniejszenia wymagań poziomu przepływności lub dostępności zasobów potrzebnych do kompresji." Basic.AutoConfig.StreamPage="Informacja o streamie" Basic.AutoConfig.StreamPage.SubTitle="Podaj informacje o streamie" -Basic.AutoConfig.StreamPage.ConnectAccount="Połącz konto (opcjonalne)" +Basic.AutoConfig.StreamPage.ConnectAccount="Podłącz konto (zalecane)" Basic.AutoConfig.StreamPage.DisconnectAccount="Odłącz konto" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Odłączyć konto?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Ta zmiana zostanie zastosowana natychmiast. Czy na pewno chcesz odłączyć konto?" @@ -240,6 +245,9 @@ ConfirmStart.Text="Czy na pewno chcesz uruchomić streamowanie?" ConfirmStop.Title="Zatrzymać streamowanie?" ConfirmStop.Text="Czy na pewno chcesz uruchomić streamowanie?" +ConfirmStopRecord.Title="Zatrzymać nagrywanie?" +ConfirmStopRecord.Text="Czy na pewno chcesz zatrzymać nagrywanie?" + ConfirmBWTest.Title="Nadawanie w trybie testu przepustowości" ConfirmBWTest.Text="OBS skonfigurowany jest w trybie testu przepustowości. Tryb ten pozwala na test połączenia sieciowego bez streamowania \"na żywo\". Po zakończeniu testów wyłącz tryb, aby móc streamować \"na żywo\".\n\nCzy chcesz kontynuować?" @@ -255,6 +263,8 @@ Output.StartRecordingFailed="Nie udało się rozpocząć nagrywania" Output.StartReplayFailed="Nie udało się rozpocząć nagrywania powtórek" Output.StartFailedGeneric="Nie udało się uruchomić wyjścia. Sprawdź szczegóły w plikach dziennika.\n\nUwaga: Sprawdź, czy posiadasz aktualne sterowniki karty graficznej, jeżeli używasz enkodera NVENC lub AMD." +Output.ReplayBuffer.PauseWarning.Title="Nie można zapisać powtórek podczas pauzy nagrywania" +Output.ReplayBuffer.PauseWarning.Text="Ostrzeżenie: Powtórki nie mogą być zapisane, gdy nagrywanie jest spauzowane." Output.ConnectFail.Title="Nie udało się połączyć" Output.ConnectFail.BadPath="Nieprawidłowa ścieżka lub adres URL połączenia. Sprawdź poprawność ustawień." @@ -444,6 +454,8 @@ Basic.Main.StartRecording="Rozpocznij nagrywanie" Basic.Main.StartReplayBuffer="Rozpocznij nagrywanie powtórek" Basic.Main.StartStreaming="Rozpocznij stream" Basic.Main.StopRecording="Zatrzymaj nagrywanie" +Basic.Main.PauseRecording="Pauzuj nagrywanie" +Basic.Main.UnpauseRecording="Wznów nagrywanie" Basic.Main.StoppingRecording="Zatrzymywanie nagrywania..." Basic.Main.StopReplayBuffer="Zatrzymaj nagrywanie powtórek" Basic.Main.StoppingReplayBuffer="Zatrzymywanie nagrywania powtórek..." @@ -502,6 +514,7 @@ Basic.MainMenu.View.Toolbars="Paski narzędzi (&T)" Basic.MainMenu.View.Docks="Panele" Basic.MainMenu.View.Docks.ResetUI="Przywróć domyślny interfejs" Basic.MainMenu.View.Docks.LockUI="Zablokuj interfejs" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Panele przeglądarki..." Basic.MainMenu.View.Toolbars.Listboxes="Panele kontrolne &list elementów" Basic.MainMenu.View.SceneTransitions="Efekty przejś&cia scen" Basic.MainMenu.View.StatusBar="Pasek &stanu" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="Automatycznie sprawdzaj dostępność Basic.Settings.General.OpenStatsOnStartup="Otwórz statystyki przy starcie aplikacji" Basic.Settings.General.WarnBeforeStartingStream="Pokaż komunikat potwierdzenia uruchomienia streamowania" Basic.Settings.General.WarnBeforeStoppingStream="Pokaż komunikat potwierdzenia zatrzymania streamowania" +Basic.Settings.General.WarnBeforeStoppingRecord="Pokaż komunikat potwierdzenia zatrzymania nagrywania" Basic.Settings.General.Projectors="Projektory" Basic.Settings.General.HideProjectorCursor="Ukryj kursor podglądu na pełnym ekranie" Basic.Settings.General.ProjectorAlwaysOnTop="Podgląd na pełnym ekranie zawsze na wierzchu" @@ -591,12 +605,15 @@ Basic.Settings.Output.Encoder="Enkoder" Basic.Settings.Output.SelectDirectory="Wybierz katalog nagrywania" Basic.Settings.Output.SelectFile="Wybierz plik nagrania" Basic.Settings.Output.EnforceBitrate="Wymuś limity przepływności wybranego serwisu" +Basic.Settings.Output.DynamicBitrate="Dynamicznie zmień bitrate by zapobiec zapychaniu łącza" +Basic.Settings.Output.DynamicBitrate.Beta="Dynamicznie zmień bitrate by zapobiec zapychaniu łącza (beta)" +Basic.Settings.Output.DynamicBitrate.TT="Zamiast odrzucać klatki przy zapchanym łączu dynamicznie zmienia bitrate enkodowania.\n\nW przypadku dużego i nagłego przytkania łącza zwiększa to opóźnienie streamu dla oglądających.\nPo zmniejszeniu bitrate, jego powrót do normalnych wartości może potrwać kilka minut.\n\nMechanizm obsługiwany jest obecnie jedynie przy protokole RTMP." Basic.Settings.Output.Mode="Tryb wyjścia" Basic.Settings.Output.Mode.Simple="Proste" Basic.Settings.Output.Mode.Adv="Zaawansowane" Basic.Settings.Output.Mode.FFmpeg="Wyjście FFmpeg" Basic.Settings.Output.UseReplayBuffer="Włącz nagrywanie powtórek" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksymalny czas nagrania (w sekundach)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksymalny czas nagrania" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maksymalna ilość pamięci (w megabajtach)" Basic.Settings.Output.ReplayBuffer.Estimate="Szacowane użycie pamięci: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Nie można oszacować użycia pamięci. Należy ustawić limit maksymalnej pamięci." @@ -611,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Jakość nie do odróżnienia, Basic.Settings.Output.Simple.RecordingQuality.Lossless="Jakość bezstratna, ogromna wielkość pliku" Basic.Settings.Output.Simple.Warn.VideoBitrate="Ostrzeżenie: Przepływność (bitrate) obrazu ustawiona jest na wartość %1. Jest to górna granica wartości dozwolonych dla wybranej usługi streamingowej. Aby ustawić wartość przepływności większą niż %1 przejdź do zaawansowanych ustawień dekoder i odznacz opcję \"Wymuś limity przepływności wybranego serwisu\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Ostrzeżenie: Przepływność (bitrate) dźwięku ustawiona jest na wartość %1. Jest to górna granica wartości dozwolonych dla wybranej usługi streamingowej. Aby ustawić wartość przepływności większą niż %1, przejdź do zaawansowanych ustawień dekoder i odznacz opcję \"Wymuś limity przepływności wybranego serwisu\"." +Basic.Settings.Output.Simple.Warn.CannotPause="Ostrzeżenie: Nagrywanie nie może być spauzowane, gdy jakość nagrywania ustawiona jest na \"Taka sama jak stream\"." Basic.Settings.Output.Simple.Warn.Encoder="Ostrzeżenie: Nagrywanie przy użyciu enkodera programowego z jakością inną niż stream wymagać będzie dodatkowej mocy procesora w przypadku jednoczesnego streamowania i nagrywania." Basic.Settings.Output.Simple.Warn.Lossless="Ostrzeżenie: Jakość bezstratna generuje bardzo duże pliki! Przy dużych rozdzielczościach i szybkości klatek rozmiar pliku może sięgać 7GB na minutę nagrania. Jakość ta nie jest zalecana w przypadku długich nagrań, chyba że masz bardzo dużo wolnego miejsca na dysku." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Czy na pewno chcesz użyć bezstratnej jakości?" @@ -623,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Programowy (x264 ustawienia Basic.Settings.Output.VideoBitrate="Bitrate obrazu" Basic.Settings.Output.AudioBitrate="Bitrate dźwięku" Basic.Settings.Output.Reconnect="Ponowne łączenie" -Basic.Settings.Output.RetryDelay="Ponów połączenie (w sekundach)" +Basic.Settings.Output.RetryDelay="Próbuj połączyć co" Basic.Settings.Output.MaxRetries="Maksymalna liczba ponownych prób" Basic.Settings.Output.Advanced="Włącz zaawansowane ustawienia enkodera" Basic.Settings.Output.EncoderPreset="Ustawienia enkodera" @@ -694,7 +712,8 @@ Basic.Settings.Video.DisableAero="Wyłącz Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (najszybsze, obraz rozmazany w przypadku skalowania)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (skalowanie ostrzejsze, 16 próbek)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (skalowanie ostrzejsze, 32 próbki)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (skalowanie ostrzejsze, 36 próbki)" +Basic.Settings.Video.DownscaleFilter.Area="Area (suma ważona, 4/6/9 próbek)" Basic.Settings.Audio="Dźwięk" Basic.Settings.Audio.SampleRate="Częstotliwość próbkowania" @@ -708,7 +727,7 @@ Basic.Settings.Audio.PeakMeterType="Typ szczytowego poziomu paska audio" Basic.Settings.Audio.PeakMeterType.SamplePeak="Poziom szczytowy próbkowany" Basic.Settings.Audio.PeakMeterType.TruePeak="Rzeczywisty szczytowy poziom (większe użycie procesora)" Basic.Settings.Audio.MultiChannelWarning.Enabled="Uwaga: Dźwięk przestrzenny jest włączony." -Basic.Settings.Audio.MultichannelWarning="W przypadku streamowania sprawdź, czy docelowa usługa obsługuje wielokanałowe wejście oraz odtwarzanie dźwięku surround. Twitch, Facebook, 360 Live, Mixer RTMP, Smashcast to przykłady usług obsługujących dźwięk wielokanałowy. O ile Facebook Live i Youtube Live obsługują wejście dźwięku wielokanałowego, to w przypadku odtwarzania Facebook miksuje kanału do stereo a Youtube Live odtwarza tylko dwa kanały.\n\nFiltry dźwiękowe OBS są w pełni kompatybilne z dźwiękiem kanałowym, natomiast wsparcie pluginów VST nie jest gwarantowane." +Basic.Settings.Audio.MultichannelWarning="W przypadku streamowania sprawdź, czy docelowa usługa obsługuje wielokanałowe wejście oraz odtwarzanie dźwięku surround. Facebook, 360 Live, Mixer RTMP, Smashcast to przykłady usług obsługujących dźwięk wielokanałowy. O ile Facebook Live i Youtube Live obsługują wejście dźwięku wielokanałowego, to w przypadku odtwarzania Facebook miksuje kanału do stereo a Youtube Live odtwarza tylko dwa kanały.\n\nFiltry dźwiękowe OBS są w pełni kompatybilne z dźwiękiem kanałowym, natomiast wsparcie pluginów VST nie jest gwarantowane." Basic.Settings.Audio.MultichannelWarning.Title="Włączyć dźwięk przestrzenny?" Basic.Settings.Audio.MultichannelWarning.Confirm="Czy na pewno chcesz włączyć dźwięk przestrzenny?" Basic.Settings.Audio.Devices="Urządzenia" @@ -743,23 +762,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Urządzenie do monitorowania aud Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Domyślne" Basic.Settings.Advanced.Audio.DisableAudioDucking="Wyłącz systemowe obniżanie głośności innych źródeł dźwięków" Basic.Settings.Advanced.StreamDelay="Opóźnienie streamu" -Basic.Settings.Advanced.StreamDelay.Duration="Czas trwania (s)" +Basic.Settings.Advanced.StreamDelay.Duration="Opóźnienie" Basic.Settings.Advanced.StreamDelay.Preserve="Zachowuj punkt przerwania (zwiększ opóźnienie) podczas ponownego łączenia" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Szacowane zużycie pamięci: %1 MB" Basic.Settings.Advanced.Network="Sieć" Basic.Settings.Advanced.Network.BindToIP="Przypisane IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Aktywuj nowy kod sieciowy" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Tryb niskich opóźnień" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Skróty klawiszowe w aktywnym oknie" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Nigdy nie deaktywuj skrótów klawiszowych" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Wyłącz skróty klawiszowe, gdy główne okno programu jest aktywne na pierwszym planie" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Deaktywuj skróty klawiszowe, gdy okno nie jest aktywne na pierwszym planie" Basic.Settings.Advanced.AutoRemux="Automatycznie przepakuj (remux) do mp4" Basic.Settings.Advanced.AutoRemux.MP4="(nagrywaj jako mkv)" Basic.AdvAudio="Zaawansowane ustawienia dźwięku" Basic.AdvAudio.Name="Nazwa" Basic.AdvAudio.Volume="Głośność" -Basic.AdvAudio.Mono="Downmix do Mono" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Balans" -Basic.AdvAudio.SyncOffset="Przesunięcie dźwięku (ms)" +Basic.AdvAudio.SyncOffset="Przesunięcie dźwięku" Basic.AdvAudio.Monitoring="Monitorowanie urządzenia audio" Basic.AdvAudio.Monitoring.None="Wyłączone" Basic.AdvAudio.Monitoring.MonitorOnly="Tylko monitorowanie (wyjście wyłączone)" @@ -825,6 +847,7 @@ SceneItemHide="Ukryj '%1'" OutputWarnings.NoTracksSelected="Musisz wybrać przynajmniej jedną ścieżkę" OutputWarnings.MultiTrackRecording="Ostrzeżenie: Pewne formaty plików (np. FLV) nie obsługują wielu ścieżek dźwiękowych" OutputWarnings.MP4Recording="Ostrzeżenie: Nagrania zapisanego w formacie MP4/MOV nie będzie można odzyskać, jeśli plik nie zostanie zakończony poprawnie (np. w wyniku BSOD, braku prądu, itp.). Jeśli chcesz nagrać wiele ścieżek audio należy rozważyć użycie formatu MKV i remux nagrania do MP4/MOV po zakończeniu (Plik → Przepakuj nagrania)." +OutputWarnings.CannotPause="Ostrzeżenie: Nagrywanie nie może być spauzowane, gdy enkoder nagrywania ustawiony jest na \"(użyj enkodera streamu)\"" FinalScene.Title="Usuń scenę" FinalScene.Text="Musi być co najmniej jedna scena." diff --git a/UI/data/locale/pt-BR.ini b/UI/data/locale/pt-BR.ini index 3dad406..e30f8c3 100644 --- a/UI/data/locale/pt-BR.ini +++ b/UI/data/locale/pt-BR.ini @@ -1,6 +1,6 @@ Language="Português" -Region="Brasil" +Region="Estados Unidos" OK="Ok" Apply="Aplicar" @@ -23,7 +23,7 @@ Settings="Configurações" Display="Monitor" Name="Nome" Exit="Sair" -Mixer="Mixer" +Mixer="Mixer de Áudio" Browse="Localizar" Mono="Mono" Stereo="Estéreo" @@ -89,7 +89,11 @@ AlreadyRunning.Text="OBS já está em execução! A menos que você tenha a inte AlreadyRunning.LaunchAnyway="Executar mesmo assim" DockCloseWarning.Title="Fechar janela ancorável" -DockCloseWarning.Text="Você acabou de fechar uma janela ancorável. Se você gostaria de abri-la novamente, use o menu Mostrar → Âncoras." +DockCloseWarning.Text="Você acabou de fechar uma janela ancorável. Se você gostaria de abri-la novamente, use o menu Mostrar → Docas." + +ExtraBrowsers="Docas para Navegador Personalizado" +ExtraBrowsers.Info="Adicione docas dando-lhes um nome e URL, então clique em Aplicar ou Fechar para abrir as docas. Você pode adicionar ou remover as docas a qualquer momento." +ExtraBrowsers.DockName="Nome da Doca" Auth.Authing.Title="Autenticando..." Auth.Authing.Text="Autenticando com a(o) %1, aguarde..." @@ -107,6 +111,7 @@ TwitchAuth.Stats="Estatísticas da Twitch" TwitchAuth.Feed="Feed de Atividade do Twitch" TwitchAuth.TwoFactorFail.Title="Não foi possível consultar a chave de transmissão" TwitchAuth.TwoFactorFail.Text="O OBS não foi capaz de se conectar à sua conta do Twitch. Por favor, certifique-se de que a autenticação de dois fatores está configurada em suas Configurações de segurança do Twitch pois isso é necessário para transmitir." +RestreamAuth.Channels="Canais de reatribuição" Copy.Filters="Copiar Filtros" Paste.Filters="Colar Filtros" @@ -139,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 ou 30, mas prefiro alta resolu Basic.AutoConfig.VideoPage.CanvasExplanation="Nota: A resolução da tela (base) não é necessariamente a mesma resolução que você transmitirá ou gravará. Sua resolução final da transmissão/gravação pode ser redimencionada da resolução da tela para reduzir o uso de recursos ou bitrate necessário." Basic.AutoConfig.StreamPage="Informações da transmissão" Basic.AutoConfig.StreamPage.SubTitle="Por favor, digite suas informações para a transmissão" -Basic.AutoConfig.StreamPage.ConnectAccount="Conectar Conta (opcional)" +Basic.AutoConfig.StreamPage.ConnectAccount="Conectar Conta (recomendado)" Basic.AutoConfig.StreamPage.DisconnectAccount="Desconectar conta" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Desconectar conta?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Esta mudança será aplicada imediatamente. Tem certeza de que deseja desconectar sua conta?" @@ -192,7 +197,7 @@ Basic.Stats.Bitrate="Taxa de bits" Basic.Stats.DiskFullIn="Disco completo em (aprox.)" ResetUIWarning.Title="Tem certeza de que deseja redefinir a interface do usuário?" -ResetUIWarning.Text="Redefinir a interface irá ocultar as âncoras adicionais. Você precisará mostra-las indo no menu de visualização se quiser que elas se tornem visíveis novamente.\n\nTem certeza de que deseja redefinir a interface do usuário?" +ResetUIWarning.Text="Redefinir a interface irá ocultar as docas adicionais. Você precisará mostra-las indo no menu de visualização se quiser que elas se tornem visíveis novamente.\n\nTem certeza de que deseja redefinir a interface do usuário?" Updater.Title="Nova atualização disponível" Updater.Text="Há uma nova atualização disponível:" @@ -240,6 +245,9 @@ ConfirmStart.Text="Deseja mesmo iniciar a transmissão?" ConfirmStop.Title="Interromper transmissão?" ConfirmStop.Text="Deseja mesmo interromper a transmissão?" +ConfirmStopRecord.Title="Parar Gravação?" +ConfirmStopRecord.Text="Tem certeza que deseja parar a gravação?" + ConfirmBWTest.Title="Iniciar teste de largura de banda?" ConfirmBWTest.Text="Você com o OBS configurado no modo de teste de largura de banda. Este modo permite o teste de rede sem que o seu canal entre em funcionamento. Uma vez terminado o teste, você precisará desativá-lo para que os espectadores possam ver sua transmissão.\n\nVocê quer continuar?" @@ -255,6 +263,8 @@ Output.StartRecordingFailed="Falha ao iniciar a gravação" Output.StartReplayFailed="Falha ao iniciar o buffer de repetição" Output.StartFailedGeneric="Impossível criar o arquivo de saída. Verifique o registro para mais detalhes do erro.\n\nAviso: se estiver utilizando os codificadores NVENC ou AMD, certifique-se de que os seus drivers estão atualizados." +Output.ReplayBuffer.PauseWarning.Title="Não é possível salvar replays enquanto pausado" +Output.ReplayBuffer.PauseWarning.Text="Aviso: Replays não podem ser salvos enquanto a gravação estiver pausada." Output.ConnectFail.Title="Falha ao conectar" Output.ConnectFail.BadPath="Caminho ou URL inválida. Por favor, verifique suas configurações para confirmar que estão válidas." @@ -444,6 +454,8 @@ Basic.Main.StartRecording="Iniciar gravação" Basic.Main.StartReplayBuffer="Iniciar Buffer do Replay" Basic.Main.StartStreaming="Iniciar transmissão" Basic.Main.StopRecording="Parar Gravação" +Basic.Main.PauseRecording="Pausar Gravação" +Basic.Main.UnpauseRecording="Continuar Gravação" Basic.Main.StoppingRecording="Parando de Gravar..." Basic.Main.StopReplayBuffer="Parar Buffer do Replay" Basic.Main.StoppingReplayBuffer="Parando Buffer do Replay..." @@ -499,9 +511,10 @@ Basic.MainMenu.Edit.AdvAudio="Propried&ades de áudio avançadas" Basic.MainMenu.View="Mostrar (&V)" Basic.MainMenu.View.Toolbars="Barras de Ferramen&tas" -Basic.MainMenu.View.Docks="Ancorar" +Basic.MainMenu.View.Docks="Docas" Basic.MainMenu.View.Docks.ResetUI="Redefinir IU" Basic.MainMenu.View.Docks.LockUI="Travar IU" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Docas para Navegador Personalizado..." Basic.MainMenu.View.Toolbars.Listboxes="Caixa de &Listagem" Basic.MainMenu.View.SceneTransitions="Transições de &Cena" Basic.MainMenu.View.StatusBar="Barra de &Status" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="Buscar novas atualizações ao iniciar Basic.Settings.General.OpenStatsOnStartup="Abrir janela de estatísticas na inicialização" Basic.Settings.General.WarnBeforeStartingStream="Mostrar diálogo de confirmação quando iniciar transmissões" Basic.Settings.General.WarnBeforeStoppingStream="Mostrar diálogo de confirmação quando terminar transmissões" +Basic.Settings.General.WarnBeforeStoppingRecord="Mostrar diálogo de confirmação ao parar a gravação" Basic.Settings.General.Projectors="Projetores" Basic.Settings.General.HideProjectorCursor="Ocultar o cursor sobre projetores" Basic.Settings.General.ProjectorAlwaysOnTop="Colocar projetores sempre no topo" @@ -591,12 +605,15 @@ Basic.Settings.Output.Encoder="Encoder" Basic.Settings.Output.SelectDirectory="Selecione o diretório de gravação" Basic.Settings.Output.SelectFile="Selecione o arquivo de gravação" Basic.Settings.Output.EnforceBitrate="Impor limites de bitrate do serviço de transmissão" +Basic.Settings.Output.DynamicBitrate="Alterar taxa de bits dinamicamente para gerenciar o congestionamento" +Basic.Settings.Output.DynamicBitrate.Beta="Alterar taxa de bits dinamicamente para gerenciar o congestionamento (Beta)" +Basic.Settings.Output.DynamicBitrate.TT="Em vez de derrubar os quadros para reduzir o congestionamento, mudanças dinâmicas na taxa de bits durante o processo.\n\nNote que isso pode aumentar o atraso para os espectadores se houver um congestionamento repentino significativo.\nQuando a taxa de bits cair, pode levar até alguns minutos para restaurar.\n\nAtualmente suportado apenas para RTMP." Basic.Settings.Output.Mode="Modo de Saída" Basic.Settings.Output.Mode.Simple="Simples" Basic.Settings.Output.Mode.Adv="Avançado" Basic.Settings.Output.Mode.FFmpeg="Saída de FFmpeg" Basic.Settings.Output.UseReplayBuffer="Habilitar Buffer de Repetição" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Tempo de Replay máximo (Segundos)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Tempo máximo de repetição" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memória Máxima (Megabytes)" Basic.Settings.Output.ReplayBuffer.Estimate="Uso de memória estimado: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Impossível estimar o uso de memória. Por favor, defina o limite máximo de memória." @@ -611,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Qualidade indistinguível, Tam Basic.Settings.Output.Simple.RecordingQuality.Lossless="Qualidade Lossless, tremendamente grande" Basic.Settings.Output.Simple.Warn.VideoBitrate="Aviso: O bitrate de vídeo da transmissão será definido para %1, que é o limite superior para o serviço de transmissão atual. Se você tem certeza que quer ir acima de %1, habilite opções de codificação avançadas e desmarque \"Impor limites de bitrate do serviço de transmissão\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Aviso: O bitrate de áudio da transmissão será definido para %1, que é o limite superior para o serviço de transmissão atual. Se você tem certeza que quer ir acima de %1, habilite opções de codificação avançadas e desmarque \"Impor limites de bitrate do serviço de transmissão\"." +Basic.Settings.Output.Simple.Warn.CannotPause="Aviso: Gravações não podem ser pausadas se a qualidade da gravação estiver definida como \"A mesma da transmissão\"." Basic.Settings.Output.Simple.Warn.Encoder="Aviso: Gravar com um codificador de software em uma qualidade diferente do que a stream vai exigir mais da CPU se você transmitir e gravar ao mesmo tempo." Basic.Settings.Output.Simple.Warn.Lossless="Aviso: Qualidade Lossless gera arquivos muito grandes! A qualidade Lossless pode usar mais de 7 gigabytes de espaço em disco por minuto em altas resoluções e framerates. Lossless não é recomendada para gravações longas, a menos que se tenha uma grande quantidade de espaço em disco disponível." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Tem certeza que deseja usar qualidade lossless?" @@ -623,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (preset x264 de ba Basic.Settings.Output.VideoBitrate="Taxa de Bits do Vídeo" Basic.Settings.Output.AudioBitrate="Taxa de Bits do Áudio" Basic.Settings.Output.Reconnect="Reconectar automaticamente" -Basic.Settings.Output.RetryDelay="Espera para reconectar-se (segundos)" +Basic.Settings.Output.RetryDelay="Atraso de repetição" Basic.Settings.Output.MaxRetries="Número Máximo de Tentativas" Basic.Settings.Output.Advanced="Ativar as configurações avançadas do encoder" Basic.Settings.Output.EncoderPreset="Padrão de Codificação" @@ -694,7 +712,8 @@ Basic.Settings.Video.DisableAero="Desativar Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear(rápido, mas embaçado se redimensionando)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicúbico (escalamento nítido, 16 amostras)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (escalamento nítido, 32 amostras)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (escalamento nítido, 36 amostras)" +Basic.Settings.Video.DownscaleFilter.Area="Área (soma ponderada, 4/6/9 amostras)" Basic.Settings.Audio="Áudio" Basic.Settings.Audio.SampleRate="Taxa de Amostragem" @@ -708,7 +727,7 @@ Basic.Settings.Audio.PeakMeterType="Tipo do medidor de pico" Basic.Settings.Audio.PeakMeterType.SamplePeak="Exemplo de pico" Basic.Settings.Audio.PeakMeterType.TruePeak="True Peak (Uso elevado de CPU)" Basic.Settings.Audio.MultiChannelWarning.Enabled="AVISO: Áudio Surround está habilitado." -Basic.Settings.Audio.MultichannelWarning="Antes de transmitir, verifique se o seu serviço de transmissão suporta tanto receber como reproduzir som surround. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast são exemplos onde o som surround é totalmente suportado. Embora o Facebook Live e o YouTube Live ambos aceitem receber som surround, o Facebook Live transformará para estéreo e o YouTube Live reproduz apenas dois canais.\n\nOs filtros de áudio do OBS são compatíveis com o som surround, embora o suporte do plugin VST não seja garantido." +Basic.Settings.Audio.MultichannelWarning="Antes de transmitir, verifique se o seu serviço de transmissão suporta tanto receber como reproduzir som surround. Facebook 360 Live, Mixer RTMP, Smashcast são exemplos onde o som surround é totalmente suportado. Embora o Facebook Live e o YouTube Live ambos aceitem receber som surround, o Facebook Live transformará para estéreo e o YouTube Live reproduz apenas dois canais.\n\nOs filtros de áudio do OBS são compatíveis com o som surround, embora o suporte do plugin VST não seja garantido." Basic.Settings.Audio.MultichannelWarning.Title="Ativar o som surround?" Basic.Settings.Audio.MultichannelWarning.Confirm="Você tem certeza de que deseja habilitar o som surround?" Basic.Settings.Audio.Devices="Dispositivos" @@ -743,23 +762,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositivo de monitoramento" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Padrão" Basic.Settings.Advanced.Audio.DisableAudioDucking="Desativar a Oscilação de Áudio do Windows" Basic.Settings.Advanced.StreamDelay="Atraso da transmissão" -Basic.Settings.Advanced.StreamDelay.Duration="Duração (segundos)" +Basic.Settings.Advanced.StreamDelay.Duration="Duração" Basic.Settings.Advanced.StreamDelay.Preserve="Preservar o ponto de corte (aumento de atraso) quando reconectar" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Uso de memória estimado: %1 MB" Basic.Settings.Advanced.Network="Rede" Basic.Settings.Advanced.Network.BindToIP="Transmitir pelo IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Habilitar o novo código de rede" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Modo de baixa latência" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Comportamento de Foco de tecla de atalho" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Nunca desativar teclas de atalho" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Desativar teclas de atalho quando a janela principal estiver em foco" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Desativar teclas de atalho quando a janela principal não estiver em foco" Basic.Settings.Advanced.AutoRemux="Converter automaticamente para mp4" Basic.Settings.Advanced.AutoRemux.MP4="(gravar como mkv)" Basic.AdvAudio="Propriedades de áudio avançadas" Basic.AdvAudio.Name="Nome" Basic.AdvAudio.Volume="Volume" -Basic.AdvAudio.Mono="Downmix para Mono" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Balanço" -Basic.AdvAudio.SyncOffset="Atraso de sincronização (ms)" +Basic.AdvAudio.SyncOffset="Sincronizar Offset" Basic.AdvAudio.Monitoring="Monitoramento de Áudio" Basic.AdvAudio.Monitoring.None="Não monitorar" Basic.AdvAudio.Monitoring.MonitorOnly="Apenas monitorar (saída muda)" @@ -825,6 +847,7 @@ SceneItemHide="Ocultar '%1'" OutputWarnings.NoTracksSelected="Você deve selecionar pelo menos uma faixa" OutputWarnings.MultiTrackRecording="Aviso: Alguns formatos (como FLV) não suportam várias faixas por gravação" OutputWarnings.MP4Recording="Atenção: as gravações salvas em MP4/MOV não serão recuperáveis se o arquivo não puder ser concluído (por exemplo, como resultado de um BSOD, perdas de energia, etc.). Se você quiser gravar várias faixas de áudio, aconselhamos utilizar o MKV e, uma vez terminado, converter a gravação para MP4/MOV (Arquivo → Converter gravações)" +OutputWarnings.CannotPause="Aviso: As gravações não podem ser pausadas se o codificador de gravação estiver definido para \"(Utilizar o codificador da transmissão)\"" FinalScene.Title="Excluir cena" FinalScene.Text="É preciso haver pelo menos uma cena." diff --git a/UI/data/locale/pt-PT.ini b/UI/data/locale/pt-PT.ini index 2386f3c..408e27b 100644 --- a/UI/data/locale/pt-PT.ini +++ b/UI/data/locale/pt-PT.ini @@ -19,12 +19,12 @@ Filters="Filtros" Properties="Propriedades" MoveUp="Mover para Cima" MoveDown="Mover para Baixo" -Settings="Definições" +Settings="Configurações" Display="Ecrã" Name="Nome" Exit="Sair" -Mixer="Misturador" -Browse="Localizar" +Mixer="Misturador de Áudio" +Browse="Explorar" Mono="Mono" Stereo="Estéreo" DroppedFrames="Quadros Perdidos %1 (%2%)" @@ -47,14 +47,14 @@ Untitled="Sem título" New="Novo" Duplicate="Duplicar" Enable="Ativar" -DisableOSXVSync="Desabilitar o OSX V-Sync" -ResetOSXVSyncOnExit="Redefinir o OSX V-Sync na saída" +DisableOSXVSync="Desativar OSX V-Sync" +ResetOSXVSyncOnExit="Redefinir OSX V-Sync ao Sair" HighResourceUsage="Codificação sobrecarregado! Considere diminuir a configurações de vídeo ou usar uma predefinição mais rápido de codificação." Transition="Transição" -QuickTransitions="Transições rápidas" +QuickTransitions="Transições Rápidas" Left="Esquerda" Right="Direita" -Top="Cima" +Top="Topo" Bottom="Baixo" Reset="Repor" Hours="Horas" @@ -72,7 +72,7 @@ RemuxRecordings="Remux de gravações" Next="Continuar" Back="Anterior" Defaults="Predefinições" -HideMixer="Esconder no Mixer" +HideMixer="Ocultar no Misturador" TransitionOverride="Substituir Transição" None="Nenhum" StudioMode.Preview="Pré-visualização" @@ -80,7 +80,9 @@ StudioMode.Program="Programa" ShowInMultiview="Mostrar no Multiview" VerticalLayout="Vista Vertical" Group="Grupo" -DoNotShowAgain="Não mostrar novamente" +DoNotShowAgain="Não voltar a mostrar" +Default="(Predefinição)" +Calculating="A calcular..." AlreadyRunning.Title="O OBS já está em execução" AlreadyRunning.Text="O OBS já está em execução! Tem de desligar a instância existente do OBS antes de iniciar uma nova. Se o OBS estiver definido para correr na bandeja do sistema, por favor verifique se está aberto lá." @@ -89,17 +91,18 @@ AlreadyRunning.LaunchAnyway="Executar de qualquer modo" DockCloseWarning.Title="Janela Fechar dockável" DockCloseWarning.Text="Acabaste de fechar uma janela acoplável. Se você quiser mostrá-la novamente, use o menu Exibir → Docks na barra de menus." -Auth.Authing.Title="Autenticação..." -Auth.Authing.Text="Autenticando com %1, por favor espere..." -Auth.AuthFailure.Title="Falha na autenticação" -Auth.AuthFailure.Text="Falha na autenticação com %1:\n\n%2: %3" + +Auth.Authing.Title="A autenticar..." +Auth.Authing.Text="A autenticar com %1, por favor, aguarde..." +Auth.AuthFailure.Title="Falha na Autenticação" +Auth.AuthFailure.Text="Falhou a autenticação com %1:\n\n%2: %3" Auth.InvalidScope.Title="Autenticação Necessária" Auth.InvalidScope.Text="Os requisitos de autenticação para %1 mudaram. Algumas funcionalidades podem não estar disponíveis." Auth.LoadingChannel.Title="Carregando informação do canal..." Auth.LoadingChannel.Text="A carregar informação do canal para %1, por favor espere..." Auth.ChannelFailure.Title="Erro ao carregar canal" Auth.ChannelFailure.Text="Erro ao carregar informaões do canal do %1\n\n%2: %3" -Auth.Chat="Chat" +Auth.Chat="Conversação" Auth.StreamInfo="Informação da Transmissão" TwitchAuth.Stats="Estatísticas da Twitch" TwitchAuth.Feed="Alimentação de atividade de Twitch" @@ -114,28 +117,27 @@ BandwidthTest.Region="Região" BandwidthTest.Region.US="Estados Unidos" BandwidthTest.Region.EU="Europa" BandwidthTest.Region.Asia="Ásia" -BandwidthTest.Region.Other="Outro" +BandwidthTest.Region.Other="Outra" Basic.FirstStartup.RunWizard="Gostaria de executar o assistente de configuração automática? Pode também definir as suas configurações na janela principal." Basic.FirstStartup.RunWizard.NoClicked="Se muder de ideias pode correr o assistente de configuração automática a qualquer momento no menu Ferramentas." Basic.AutoConfig="Assistente de Configuração Automática" -Basic.AutoConfig.ApplySettings="Aplicar definições" -Basic.AutoConfig.StartPage="Informação de utilização" +Basic.AutoConfig.ApplySettings="Aplicar Configurações" +Basic.AutoConfig.StartPage="Informação de Utilização" Basic.AutoConfig.StartPage.SubTitle="Especifique qual vai ser a utilização do programa" Basic.AutoConfig.StartPage.PrioritizeStreaming="Otimizar para transmissão, gravação é secundária" Basic.AutoConfig.StartPage.PrioritizeRecording="Otimizar para gravação, a transmissão é secundária" -Basic.AutoConfig.VideoPage="Definições de video" +Basic.AutoConfig.VideoPage="Definições de Video" Basic.AutoConfig.VideoPage.SubTitle="Especifique as definições de video que pretende" Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Usar atual (%1x%2)" Basic.AutoConfig.VideoPage.BaseResolution.Display="Monitor %1 (%2x%3)" -Basic.AutoConfig.VideoPage.FPS.UseCurrent="Usar atual (%1)" +Basic.AutoConfig.VideoPage.FPS.UseCurrent="Utilizar atual (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 ou 30, com prioridade a 60" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 ou 30, com prioridade a alta resolução" Basic.AutoConfig.VideoPage.CanvasExplanation="Nota: A resolução base do canvas não é necessariamente a mesma que resolução da gravação ou stream. A resolução da gravação/stream pode ser reduzida para diminuir o uso de recursos e os requisitos de bitrate." Basic.AutoConfig.StreamPage="Informação de Transmissão" Basic.AutoConfig.StreamPage.SubTitle="Por favor introduza a informação necessária" -Basic.AutoConfig.StreamPage.ConnectAccount="Conectar Conta (opcional)" Basic.AutoConfig.StreamPage.DisconnectAccount="Desconectar Conta" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Desconectar Conta?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Esta alteração será aplicada imediatamente. De certeza que queres desconectar a tua conta?" @@ -145,7 +147,7 @@ Basic.AutoConfig.StreamPage.Service.ShowAll="Mostrar Tudo..." Basic.AutoConfig.StreamPage.Service.Custom="Personalizado..." Basic.AutoConfig.StreamPage.Server="Servidor" Basic.AutoConfig.StreamPage.StreamKey="Chave de Transmissão" -Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Link)" +Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Hiperligação)" Basic.AutoConfig.StreamPage.PerformBandwidthTest="Estimar bitrate com teste de largura de banda (pode demorar alguns minutos)" Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Preferir codificação de hardware" Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="A Codificação de Hardware elimina maior parte da utilização do CPU mas pode precisar de uma bitrate maior para obter o mesmo nível de qualidade." @@ -168,7 +170,7 @@ Basic.AutoConfig.TestPage.Result.RecordingEncoder="Codificador de Gravação" Basic.AutoConfig.TestPage.Result.Header="O programa determinou que estas definições são as mais ideais para si:" Basic.AutoConfig.TestPage.Result.Footer="Para utilizar estas definições, carregue em Aplicar Definições. Para reconfigurar o assistente e tentar novamente, carregue em Voltar. Para configurar manualmente as definições, carregue em Cancelar e abra as Definições." -Basic.Stats="Estados" +Basic.Stats="Estatísticas" Basic.Stats.CPUUsage="Utilização de CPU" Basic.Stats.HDDSpaceAvailable="Espaço em disco disponível" Basic.Stats.MemoryUsage="Utilização de Memória" @@ -178,22 +180,22 @@ Basic.Stats.MissedFrames="Frames perdidas devido ao lag de renderização" Basic.Stats.Output.Stream="Transmissão" Basic.Stats.Output.Recording="Gravação" Basic.Stats.Status="Estado" -Basic.Stats.Status.Recording="A Gravar" -Basic.Stats.Status.Live="Ao Vivo" -Basic.Stats.Status.Reconnecting="A Reconectar" +Basic.Stats.Status.Recording="Gravação" +Basic.Stats.Status.Live="LIVE" +Basic.Stats.Status.Reconnecting="A religar" Basic.Stats.Status.Inactive="Inactivo" Basic.Stats.DroppedFrames="Frames perdidas (Rede)" -Basic.Stats.MegabytesSent="Total saída de dados" -Basic.Stats.Bitrate="Taxa de Bits" +Basic.Stats.MegabytesSent="Total Dados de Saída" +Basic.Stats.Bitrate="Taxa de bits" -ResetUIWarning.Title="De certeza que queres reiniciar a interface?" -ResetUIWarning.Text="Reiniciar a interface irá esconder docks adicionais. Vais ter de as ativar outra vez a partir no menu ver se quiseres torná-las visíveis.\n\nDe certeza que queres reiniciar a interface?" +ResetUIWarning.Title="Tem a certeza que deseja reiniciar a interface?" +ResetUIWarning.Text="Ao reiniciar a interface irá ocultar as \"docks\" adicionais. Terá de as ativar novamente no menu de visualização se quiser torná-las visíveis.\n\nTem a certeza que deseja reiniciar a interface?" -Updater.Title="Nova atualização disponível" -Updater.Text="Existe uma nova atualização disponível:" +Updater.Title="Disponível nova atualização" +Updater.Text="Está disponível uma nova atualização:" Updater.UpdateNow="Atualizar Agora" Updater.RemindMeLater="Lembrar-me mais tarde" -Updater.Skip="Saltar Versão" +Updater.Skip="Ignorar Versão" Updater.Running.Title="Programa atualmente ativo" Updater.Running.Text="Existem Outputs ativos atualmente, por favor desligar quaisquer Outputs ativos antes de começar a atualização" Updater.NoUpdatesAvailable.Title="Nenhuma atualização disponível" @@ -235,6 +237,9 @@ ConfirmStart.Text="Tem a certeza que quer começar a transmissão?" ConfirmStop.Title="Parar a transmissão?" ConfirmStop.Text="Tem a certeza que quer parar a transmissão?" +ConfirmStopRecord.Title="Parar gravação?" +ConfirmStopRecord.Text="Tem a certeza que deseja parar a gravação?" + ConfirmBWTest.Title="Iniciar teste de largura de banda?" ConfirmBWTest.Text="Você tem o OBS configurado no modo de teste de largura de banda. Este modo permite o teste de rede sem que o seu canal entre em funcionamento. Uma vez terminado o teste, você precisará desativá-lo para que os espectadores possam ver sua transmissão.\n\nVocê quer continuar?" @@ -258,6 +263,7 @@ Output.ConnectFail.InvalidStream="Não foi possível acessar o canal especificad Output.ConnectFail.Error="Ocurreu um erro inesperado ao ligar-se ao servidor. Mais informação no ficheiro Log." Output.ConnectFail.Disconnected="Desligado do servidor." +Output.StreamEncodeError.Title="Erro de codificação" Output.RecordFail.Title="Não foi possível iniciar a gravação" Output.RecordFail.Unsupported="O formato de saída ou não é suportado ou não suporta mais do que uma faixa de áudio. Por favor, verifique as suas definições e tente novamente." @@ -308,6 +314,7 @@ Basic.DisplayCapture="Captura de Ecrã" Basic.Main.PreviewConextMenu.Enable="Ativar pré-visualização" +Basic.Main.Preview.Disable="Desativar Pré-visualização" ScaleFiltering="Filtragem de escala" ScaleFiltering.Point="Ponto" @@ -435,6 +442,7 @@ Basic.Main.StartRecording="Começar Gravação" Basic.Main.StartReplayBuffer="Iniciar Replay Buffer" Basic.Main.StartStreaming="Iniciar transmissão" Basic.Main.StopRecording="Parar Gravação" +Basic.Main.PauseRecording="Pausar Gravação" Basic.Main.StoppingRecording="A parar gravação..." Basic.Main.StopReplayBuffer="Parar Replay Buffer" Basic.Main.StoppingReplayBuffer="A Parar Replay Buffer..." @@ -479,6 +487,8 @@ Basic.MainMenu.Edit.Transform.FlipVertical="Inverter &Verticalmente" Basic.MainMenu.Edit.Transform.FitToScreen="Escalar ao ecrã (&F)" Basic.MainMenu.Edit.Transform.StretchToScreen="E&sticar ao ecrã" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centrar ao ecrã" +Basic.MainMenu.Edit.Transform.VerticalCenter="Centrar Verticalmente" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Centrar Horizontalmente" Basic.MainMenu.Edit.Order="&Ordem" Basic.MainMenu.Edit.Order.MoveUp="Mover para Cima (&U)" Basic.MainMenu.Edit.Order.MoveDown="Mover para Baixo (&D)" @@ -585,7 +595,6 @@ Basic.Settings.Output.Mode.Simple="Simples" Basic.Settings.Output.Mode.Adv="Avançado" Basic.Settings.Output.Mode.FFmpeg="Saída FFmpeg" Basic.Settings.Output.UseReplayBuffer="Ativar Replay Buffer" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Tempo Máximo de Replay (Segundos)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memória Máxima (Megabytes)" Basic.Settings.Output.ReplayBuffer.Estimate="Utilização estimada de memória: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Não é possível estimar a utilização de memória. Defina o limite máximo de memória." @@ -612,7 +621,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 baixa utiliz Basic.Settings.Output.VideoBitrate="Bitrate de Vídeo" Basic.Settings.Output.AudioBitrate="Bitrate de Áudio" Basic.Settings.Output.Reconnect="Religar Automaticamente" -Basic.Settings.Output.RetryDelay="Atraso de Tentatica de Religação (segundos)" Basic.Settings.Output.MaxRetries="Número Máximo de Tentativas de Religação" Basic.Settings.Output.Advanced="Ativar definições avançadas de codificação" Basic.Settings.Output.EncoderPreset="Predefinição do codificador" @@ -683,11 +691,12 @@ Basic.Settings.Video.DisableAero="Desativar Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (mais rápido, mas desfocada se escalar)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicúbico (escalamento nítido, 16 amostras)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (escalamento nítido, 32 amostras)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (escalamento nítido, 36 amostras)" Basic.Settings.Audio="Áudio" Basic.Settings.Audio.SampleRate="Frequência de Samplagem" Basic.Settings.Audio.Channels="Canias" +Basic.Settings.Audio.Meters="Medidores" Basic.Settings.Audio.MeterDecayRate.Fast="Rápido" Basic.Settings.Audio.MeterDecayRate.Medium="Médio (Tipo I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Lento (Tipo II PPM)" @@ -695,9 +704,14 @@ Basic.Settings.Audio.PeakMeterType="Tipo de Medidor de Pico" Basic.Settings.Audio.PeakMeterType.SamplePeak="Pico Pré-definido" Basic.Settings.Audio.PeakMeterType.TruePeak="Pico Verdadeiro (Maior Uso da CPU)" Basic.Settings.Audio.MultiChannelWarning.Enabled="AVISO: O som surround está ativo." -Basic.Settings.Audio.MultichannelWarning="Se transmitir, verifique se o seu serviço de transmissão suporta tanto ingestão de áudio surround como playback de áudio surround. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast são exemplos onde o áudio surround é totalmente suportado. Embora o Facebook Live e o YouTube Live aceitem os dois ingestão de áudio surround, o Facebook Live transforma-o em stereo, e o YouTube Live só toca dois canais.\n\nOs filtros de áudio do OBS são compatíveis com áudio surround, embora não esteja garantido o suporte para plugins VST." +Basic.Settings.Audio.MultichannelWarning="Se transmitir, verifique se o seu serviço de transmissão suporta tanto ingestão de áudio surround como playback de áudio surround. Facebook 360 Live, Mixer RTMP, Smashcast são exemplos onde o áudio surround é totalmente suportado. Embora o Facebook Live e o YouTube Live aceitem os dois ingestão de áudio surround, o Facebook Live transforma-o em stereo, e o YouTube Live só toca dois canais.\n\nOs filtros de áudio do OBS são compatíveis com áudio surround, embora não esteja garantido o suporte para plugins VST." Basic.Settings.Audio.MultichannelWarning.Title="Ativar audio surround?" Basic.Settings.Audio.MultichannelWarning.Confirm="Tem a certeza que quer ativar audio surround?" +Basic.Settings.Audio.Devices="Dispositivos" +Basic.Settings.Audio.AuxDevice="Áudio Mic./Auxiliar" +Basic.Settings.Audio.AuxDevice2="Áudio Mic./Auxiliar 2" +Basic.Settings.Audio.AuxDevice3="Áudio Mic./Auxiliar 3" +Basic.Settings.Audio.AuxDevice4="Áudio Mic./Auxiliar 4" Basic.Settings.Audio.EnablePushToMute="Ativar o push-to-mute" Basic.Settings.Audio.PushToMuteDelay="Atrado do push-to-mute" Basic.Settings.Audio.EnablePushToTalk="Ativar o push-to-talk" @@ -715,12 +729,14 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Inativo" Basic.Settings.Advanced.FormatWarning="Aviso: Formatos de cor diferentes de NV12 destinam-se principalmente a gravação e não são recomendados durante a transmissão. A transmissão pode incorrer numa maior utilização do processador devido à conversão do formato de cor." Basic.Settings.Advanced.Audio.BufferingTime="Tempo de carregamento do áudio" Basic.Settings.Advanced.Video.ColorFormat="Formato de cor" +Basic.Settings.Advanced.Video.ColorSpace="Espaço de Cor" Basic.Settings.Advanced.Video.ColorRange.Partial="Parcial" Basic.Settings.Advanced.Video.ColorRange.Full="Total" +Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositivo de Monitorização" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Predefinição" Basic.Settings.Advanced.Audio.DisableAudioDucking="Desativar o ducking de audio do Windows" Basic.Settings.Advanced.StreamDelay="Atraso na trasmissão" -Basic.Settings.Advanced.StreamDelay.Duration="Duração (segundos)" +Basic.Settings.Advanced.StreamDelay.Duration="Duração" Basic.Settings.Advanced.StreamDelay.Preserve="Preservar o ponto de corte (aumentar atraso) quando reconectar" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Utilização estimada de memória: %1 MB" Basic.Settings.Advanced.Network="Rede" @@ -733,9 +749,9 @@ Basic.Settings.Advanced.AutoRemux.MP4="(gravar como mkv)" Basic.AdvAudio="Propriedades avançadas de áudio" Basic.AdvAudio.Name="Nome" -Basic.AdvAudio.Mono="Diminuir para mono" +Basic.AdvAudio.Volume="Volume" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Equilíbrio" -Basic.AdvAudio.SyncOffset="Atraso de sincronização (ms)" Basic.AdvAudio.Monitoring="Monitorização de Áudio" Basic.AdvAudio.Monitoring.None="Monitor Desligado" Basic.AdvAudio.Monitoring.MonitorOnly="Único Monitor (saída muda)" @@ -788,6 +804,7 @@ Hotkeys.AppleKeypadSubtract="+ (Keypad)" Hotkeys.AppleKeypadDecimal=". (Keypad)" Hotkeys.AppleKeypadEqual="= (Keypad)" Hotkeys.MouseButton="Rato %1" +Hotkeys.Escape="Esc" Mute="Silenciar" Unmute="Tirar de silencioso" diff --git a/UI/data/locale/ro-RO.ini b/UI/data/locale/ro-RO.ini index 7035bf3..f8f28d0 100644 --- a/UI/data/locale/ro-RO.ini +++ b/UI/data/locale/ro-RO.ini @@ -23,20 +23,21 @@ Settings="Setări" Display="Display" Name="Nume" Exit="Ieși" -Mixer="Mixer" +Mixer="Mixer audio" Browse="Răsfoiește" Mono="Mono" Stereo="Stereo" DroppedFrames="Cadre pierdute %1 (%2%)" -StudioProgramProjector="Proiector în fereastră (Program)" +StudioProgramProjector="Proiector pe tot ecranul (Program)" PreviewProjector="Proiector pe tot ecranul (Previzualizare)" SceneProjector="Proiector pe tot ecranul (Scenă)" SourceProjector="Proiector pe tot ecranul (Sursă)" StudioProgramWindow="Proiector în fereastră (Program)" -PreviewWindow="Proiector pe tot ecranul (Previzualizare)" -SceneWindow="Proiector în fereastră (Program)" -SourceWindow="Proiector în fereastră (Sursa)" -MultiviewProjector="Vedere multipla (Pe tot ecranul)" +PreviewWindow="Proiector în fereastră (Previzualizare)" +SceneWindow="Proiector în fereastră (Scenă)" +SourceWindow="Proiector în fereastră (Sursă)" +MultiviewProjector="Vizualizare multiplă (Ecran complet)" +MultiviewWindowed="Vizualizare multiplă (În fereastră)" Clear="Șterge" Revert="Inversează" Show="Afișează" @@ -59,7 +60,7 @@ Reset="Resetează" Hours="Ore" Minutes="Minute" Seconds="Secunde" -Deprecated="Obsolet" +Deprecated="Perimat" ReplayBuffer="Reluare Buffer" Import="Importă" Export="Exportă" @@ -67,11 +68,11 @@ Copy="Copiază" Paste="Lipește" PasteReference="Lipește (Referință)" PasteDuplicate="Lipește (Duplicare)" -RemuxRecordings="Înregistrări Remux" +RemuxRecordings="Remuxează înregistrări" Next="Următorul" Back="Înapoi" Defaults="Valori implicite" -HideMixer="Ascunde în Mixer" +HideMixer="Ascunde în mixer" TransitionOverride="Suprascrierea tranziției" None="Fără" StudioMode.Preview="Previzualizare" @@ -79,11 +80,14 @@ StudioMode.Program="Program" ShowInMultiview="Afișează în vizualizarea multiplă" VerticalLayout="Aranjament vertical" Group="Grup" -DoNotShowAgain="Nu afișa iar" +DoNotShowAgain="Nu afișa din nou" +Default="(Implicit)" +Calculating="Se calculează..." + +AlreadyRunning.Title="OBS rulează deja" +AlreadyRunning.Text="OBS rulează deja! Dacă nu intenționezi să faci acest lucru, te rugăm să închizi toate instanțele OBS existente înainte de a încerca să rulezi o nouă instanță. Dacă ai OBS-ul setat să se minimizeze în bara de sistem, te rugam să verifici dacă rulează acolo." +AlreadyRunning.LaunchAnyway="Lansează oricum" -AlreadyRunning.Title="OBS ruleaza deja" -AlreadyRunning.Text="OBS rulează deja! În cazul în care ați încercat sa faceți acest lucru, vă rugăm să închideți toate instanțele OBS înainte de a porni una noua. Dacă aveți OBS-ul setat pentru a se minimiza in system tray vă rugam sa verificați daca inca ruleaza acolo." -AlreadyRunning.LaunchAnyway="Lansați Oricum" Auth.Authing.Title="Se autentifică..." @@ -98,6 +102,8 @@ Auth.Chat="Chat" Auth.StreamInfo="Informații privind transmisiunea" TwitchAuth.Stats="Statistici Twitch" TwitchAuth.Feed="Fluxul activității Twitch" +TwitchAuth.TwoFactorFail.Title="Nu se poate interoga cheia de transmisiune" +TwitchAuth.TwoFactorFail.Text="OBS nu a putut să se conecteze la contul tău Twitch. Te rugăm să te asiguri că autentificarea cu doi factori este configurată în setările de securitate din Twitch, deoarece acest lucru este necesar pentru a transmite." Copy.Filters="Copiază filtrele" Paste.Filters="Lipește filtrele" @@ -112,7 +118,7 @@ BandwidthTest.Region.Asia="Asia" BandwidthTest.Region.Other="Alta" Basic.FirstStartup.RunWizard="Vrei să rulezi asistentul de configurare automată? Poți, de asemenea, să configurezi setările manual dând clic pe butonul Setări din fereastra principală." -Basic.FirstStartup.RunWizard.NoClicked="Dacă vă răzgândiți, puteți rula auto-configuratorul oricând din meniul Instrumente." +Basic.FirstStartup.RunWizard.NoClicked="Dacă te răzgândești, poți rula asistentul de configurare automată oricând din meniul Unelte." Basic.AutoConfig="Asistentul de configurare automată" Basic.AutoConfig.ApplySettings="Aplică setările" @@ -130,11 +136,11 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Fie 60 sau 30, însă prefer rezol Basic.AutoConfig.VideoPage.CanvasExplanation="Notă: Rezoluția (de bază) a planșei nu este neapărat aceeași cu rezoluția cu care vei transmite sau înregistra. Rezoluția efectivă de transmisiune/înregistrare poate fi scalată în jos de la rezoluția planșei pentru a reduce necesarul de resurse sau de rată de biți." Basic.AutoConfig.StreamPage="Informații privind transmisiunea" Basic.AutoConfig.StreamPage.SubTitle="Te rugăm să introduci informațiile pentru transmisiune" -Basic.AutoConfig.StreamPage.ConnectAccount="Conectează un cont (opțional)" +Basic.AutoConfig.StreamPage.ConnectAccount="Conectează un cont (recomandat)" Basic.AutoConfig.StreamPage.DisconnectAccount="Deconectează contul" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Deconectezi contul?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Această modificare se va aplica imediat. Ești sigur că vrei să deconectezi contul?" -Basic.AutoConfig.StreamPage.UseStreamKey="Folosește cheia de transmisiune" +Basic.AutoConfig.StreamPage.UseStreamKey="Folosește o cheie de transmisiune" Basic.AutoConfig.StreamPage.Service="Serviciu" Basic.AutoConfig.StreamPage.Service.ShowAll="Afișează toate..." Basic.AutoConfig.StreamPage.Service.Custom="Personalizat..." @@ -143,8 +149,8 @@ Basic.AutoConfig.StreamPage.StreamKey="Cheie de transmisiune" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Link)" Basic.AutoConfig.StreamPage.PerformBandwidthTest="Estimează rata de biți cu o testare a lățimii de bandă (poate dura câteva minute)" Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Preferă codificarea hardware" -Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Codificarea hardware elimină cea mai mare parte a utilizării CPU, însă ar putea avea nevoie de o rată de biți mai mare pentru a obține același nivel de calitate." -Basic.AutoConfig.StreamPage.StreamWarning.Title="Avertizare transmisie" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Codificarea hardware elimină cea mai mare parte a utilizării CPU, însă poate necesita o rată de biți mai mare pentru a obține același nivel de calitate." +Basic.AutoConfig.StreamPage.StreamWarning.Title="Avertisment privind transmisiunea" Basic.AutoConfig.StreamPage.StreamWarning.Text="Testarea lățimii de bandă este pe cale să transmită date video aleatorii fără audio către canalul tău. Dacă ai posibilitatea, este recomandat să oprești temporar salvarea videoclipurilor transmisiunilor și să setezi transmisiunea pe privat până la încheierea testării. Continui?" Basic.AutoConfig.TestPage="Rezultate finale" Basic.AutoConfig.TestPage.SubTitle.Testing="Programul rulează acum o serie de teste pentru identificarea setărilor ideale" @@ -170,17 +176,18 @@ Basic.Stats.MemoryUsage="Utilizarea memoriei" Basic.Stats.AverageTimeToRender="Timpul mediu de redare a cadrului" Basic.Stats.SkippedFrames="Cadre sărite din pricina întârzierilor de codificare" Basic.Stats.MissedFrames="Cadre sărite din pricina întârzierii de redare" -Basic.Stats.Output.Stream="Transmisie" +Basic.Stats.Output.Stream="Transmisiune" Basic.Stats.Output.Recording="Înregistrare" Basic.Stats.Status="Stare" -Basic.Stats.Status.Recording="Înregistrare" -Basic.Stats.Status.Live="ÎN DIRECT" -Basic.Stats.Status.Reconnecting="Reconectare" +Basic.Stats.Status.Recording="Se înregistrează" +Basic.Stats.Status.Live="LIVE" +Basic.Stats.Status.Reconnecting="Se reconectează" Basic.Stats.Status.Inactive="Inactiv" Basic.Stats.DroppedFrames="Cadre pierdute (Rețea)" Basic.Stats.MegabytesSent="Date transmise în total" Basic.Stats.Bitrate="Rată de biți" +ResetUIWarning.Title="Sigur vrei să resetezi UI-ul?" Updater.Title="Actualizare nouă disponibilă" Updater.Text="Există o nouă actualizare disponibilă:" @@ -221,9 +228,12 @@ NoNameEntered.Text="Nu poți folosi nume necompletate." ConfirmStart.Title="Începi transmisiunea?" ConfirmStart.Text="Sigur vrei să pornești transmisiunea?" -ConfirmStop.Title="Oprești streamul?" +ConfirmStop.Title="Oprești transmisiunea?" ConfirmStop.Text="Sigur vrei să oprești transmisiunea?" +ConfirmStopRecord.Title="Oprești înregistrarea?" +ConfirmStopRecord.Text="Sigur vrei să oprești înregistrarea?" + ConfirmBWTest.Title="Începi testarea pentru lățimea de bandă?" ConfirmBWTest.Text="Ai configurat OBS în modul de testare a lățimii de bandă. Acest mod permite testarea rețelei fără să transmiți live pe canal. Odată ce ai terminat testarea, va trebui să îl dezactivezi pentru ca spectatorii să îți poată vedea transmisiunea.\n\nVrei să continui?" @@ -232,26 +242,29 @@ ConfirmExit.Text="OBS este în prezent activ. Toate transmisiunile/înregistrăr ConfirmRemove.Title="Confirmă eliminarea" ConfirmRemove.Text="Sigur vrei să elimini „$1”?" -ConfirmRemove.TextMultiple="Sigur doriți sa eliminați %1 obiecte?" +ConfirmRemove.TextMultiple="Sigur vrei să elimini %1 elemente?" Output.StartStreamFailed="Pornirea transmisiunii a eșuat" Output.StartRecordingFailed="Pornirea înregistrării a eșuat" -Output.ConnectFail.Title="Eșec la conectare" +Output.ConnectFail.Title="Conectarea a eșuat" Output.ConnectFail.BadPath="URL-ul conexiunii sau calea este invalidă. Te rugăm să verifici setările pentru a confirma că acestea sunt valide." Output.ConnectFail.ConnectFailed="Nu se poate conecta la server" Output.ConnectFail.InvalidStream="Nu a putut fi accesat canalul sau cheia de transmisiune specificată, te rugăm să verifici cheia de transmisiune. Dacă aceasta este corectă, poate fi o problemă cu conectarea la server." Output.ConnectFail.Error="Eroare neașteptată la încercarea de a conecta la server. Mai multe informaţii în fişierul jurnal." Output.ConnectFail.Disconnected="Deconectat de la server." +Output.StreamEncodeError.Title="Eroare privind codificarea" +Output.StreamEncodeError.Msg="A apărut o eroare de codificare în timpul transmisiunii." Output.RecordFail.Title="Eșec la pornirea înregistrării" Output.RecordFail.Unsupported="Formatul de ieşire este fie nesuportat, fie nu suportă mai mult de o pistă audio. Te rugăm să verifici setările şi să încerci din nou." Output.RecordNoSpace.Title="Spațiu insuficient pe disc" Output.RecordNoSpace.Msg="Nu există spațiu suficient pe disc pentru a continua înregistrarea." -Output.RecordError.Title="Eroare de înregistrare" +Output.RecordError.Title="Eroare privind înregistrarea" Output.RecordError.Msg="S-a produs o eroare nespecificată în timpul înregistrării." +Output.RecordError.EncodeErrorMsg="A apărut o eroare de codificare în timpul înregistrării." Output.ReplayBuffer.NoHotkey.Title="Nicio tastă rapidă setată!" Output.BadPath.Title="Calea fișierului greșită" @@ -263,19 +276,20 @@ LogReturnDialog.ErrorUploadingLog="Eroare la încărcarea fișierului jurnal" Remux.SourceFile="Înregistrare OBS" Remux.TargetFile="Fișier țintă" -Remux.Remux="Remux" +Remux.Remux="Remuxează" Remux.Stop="Oprește remuxarea" Remux.ClearFinished="Șterge elementele finalizate" Remux.ClearAll="Șterge toate elementele" Remux.OBSRecording="Înregistrare OBS" -Remux.FinishedTitle="Remuxing încheiat" +Remux.FinishedTitle="Remuxare încheiată" Remux.Finished="Înregistrare remuxată" Remux.FinishedError="Înregistrare remuxată, însă fișierul poate fi incomplet" Remux.SelectRecording="Selectează înregistrarea OBS..." -Remux.FileExistsTitle="Fișierele țintă există deja" -Remux.FileExists="Fișierele deja exista. Vreți să le înlocuiți?" -Remux.ExitUnfinishedTitle="Remuxing în desfășurare" -Remux.ExitUnfinished="Remuxingul nu este încheiat, oprirea în acest moment poate face fișierul țintă inutilizabil.\nSigur vrei să oprești remuxingul?" +Remux.SelectTarget="Selectează fișierul țintă..." +Remux.FileExistsTitle="Fișierele țintă există" +Remux.FileExists="Următoarele fișiere țintă există deja. Vrei să le înlocuiești?" +Remux.ExitUnfinishedTitle="Remuxare în desfășurare" +Remux.ExitUnfinished="Remuxarea nu este încheiată, oprirea în acest moment poate face fișierul țintă inutilizabil.\nSigur vrei să oprești remuxarea?" Remux.HelpText="Plasează fișierele în această fereastră pentru a remuxa ori selectează o celulă „Înregistrare OBS” goală pentru a răsfoi un fișier." UpdateAvailable="Actualizare nouă disponibilă" @@ -293,11 +307,14 @@ Basic.DisplayCapture="Captură de display" Basic.Main.PreviewConextMenu.Enable="Activează previzualizarea" +Basic.Main.Preview.Disable="Dezactivează previzualizarea" +ScaleFiltering="Filtrare scalară" ScaleFiltering.Point="Punct" -ScaleFiltering.Bilinear="Biliniar" -ScaleFiltering.Bicubic="Bicubic" +ScaleFiltering.Bilinear="Bilineară" +ScaleFiltering.Bicubic="Bicubică" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Zonă" Deinterlacing="Deîntrețesere" Deinterlacing.Discard="Înlătură" @@ -329,6 +346,7 @@ AddProfile.Text="Te rugăm să introduci numele profilului" RenameProfile.Title="Redenumește profilul" +Basic.Main.MixerRename.Title="Redenumește sursa audio" Basic.Main.MixerRename.Text="Te rugăm să introduci numele sursei audio" @@ -414,6 +432,8 @@ Basic.Main.Connecting="Se conectează..." Basic.Main.StartRecording="Pornește înregistrarea" Basic.Main.StartStreaming="Pornește transmisiunea" Basic.Main.StopRecording="Oprește înregistrarea" +Basic.Main.PauseRecording="Pune pe pauză înregistrarea" +Basic.Main.UnpauseRecording="Scoate de pe pauză înregistrarea" Basic.Main.StoppingRecording="Se oprește înregistrarea..." Basic.Main.StopStreaming="Oprește transmisiunea" Basic.Main.StoppingStreaming="Se oprește transmisiunea..." @@ -425,12 +445,12 @@ Basic.MainMenu.File="&Fișier" Basic.MainMenu.File.Export="&Exportă" Basic.MainMenu.File.Import="&Importă" Basic.MainMenu.File.ShowRecordings="Afișează în®istrările" -Basic.MainMenu.File.Remux="Înregistrări re&mux" +Basic.MainMenu.File.Remux="Re&muxează înregistrări" Basic.MainMenu.File.Settings="&Setări" Basic.MainMenu.File.ShowSettingsFolder="Afișează folderul cu setări" Basic.MainMenu.File.ShowProfileFolder="Afișează folderul cu profiluri" Basic.MainMenu.AlwaysOnTop="Întotde&auna deasupra" -Basic.MainMenu.File.Exit="Ieșire (&X)" +Basic.MainMenu.File.Exit="Ieși (&X)" Basic.MainMenu.Edit="&Editare" Basic.MainMenu.Edit.Undo="An&ulează acțiunea" @@ -455,7 +475,7 @@ Basic.MainMenu.Edit.Transform.FitToScreen="Potrivește pe ecran (&F)" Basic.MainMenu.Edit.Transform.StretchToScreen="Întinde pe ecran (&S)" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centrează pe ecran" Basic.MainMenu.Edit.Order="&Ordonare" -Basic.MainMenu.Edit.Order.MoveUp="M&ută sus" +Basic.MainMenu.Edit.Order.MoveUp="Mută s&us" Basic.MainMenu.Edit.Order.MoveDown="Mută jos (&D)" Basic.MainMenu.Edit.Order.MoveToTop="Mu&tă în vârf" Basic.MainMenu.Edit.Order.MoveToBottom="Mută la fund (&B)" @@ -488,7 +508,7 @@ Basic.MainMenu.Help.Website="Vizitează site-ul &web" Basic.MainMenu.Help.Discord="Alătură-te serverului de &Discord" Basic.MainMenu.Help.Logs="Fișiere jurna&l" Basic.MainMenu.Help.Logs.ShowLogs="Afișează fișierele jurnal (&S)" -Basic.MainMenu.Help.Logs.UploadCurrentLog="În&carcă actualul fişier jurnal" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Încarcă a&ctualul fișier jurnal" Basic.MainMenu.Help.Logs.UploadLastLog="Încarcă u<imul fișier jurnal" Basic.MainMenu.Help.Logs.ViewCurrentLog="&Vezi log-ul actual" Basic.MainMenu.Help.CheckForUpdates="Caută actualizări" @@ -524,11 +544,22 @@ Basic.Settings.General.SystemTrayHideMinimize="Întotdeauna minimizează în bar Basic.Settings.General.SaveProjectors="Salvează proiectoarele la ieșire" Basic.Settings.General.Preview="Previzualizare" Basic.Settings.General.SwitchOnDoubleClick="Efectuează tranziția către scenă la dublu clic" +Basic.Settings.General.StudioPortraitLayout="Activează aranjamentul de tip portret/vertical" +Basic.Settings.General.Multiview="Vizualizare multiplă" Basic.Settings.General.Multiview.MouseSwitch="Efectuează clic pentru a comuta între scene" Basic.Settings.General.Multiview.DrawSourceNames="Afișează numele scenelor" +Basic.Settings.General.MultiviewLayout="Aranjament pentru vizualizare multiplă" +Basic.Settings.General.MultiviewLayout.Horizontal.Top="Orizontal, sus (8 scene)" +Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Orizontal, jos (8 scene)" +Basic.Settings.General.MultiviewLayout.Vertical.Left="Vertical, stânga (8 scene)" +Basic.Settings.General.MultiviewLayout.Vertical.Right="Vertical, dreapta (8 scene)" +Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Orizontal, sus (24 de scene)" Basic.Settings.Stream="Transmisiune" Basic.Settings.Stream.StreamType="Tipul transmisiunii" +Basic.Settings.Stream.Custom.UseAuthentication="Folosește autentificarea" +Basic.Settings.Stream.Custom.Username="Nume de utilizator" +Basic.Settings.Stream.Custom.Password="Parolă" Basic.Settings.Stream.BandwidthTestMode="Activează modul de testare a lățimii de bandă" Basic.Settings.Output="Ieșire" @@ -552,6 +583,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Calitate imposibil de distins, Basic.Settings.Output.Simple.RecordingQuality.Lossless="Calitate lossless, dimensiune extrem de mare pentru fișiere" Basic.Settings.Output.Simple.Warn.VideoBitrate="Avertisment: Rata de biți a transmisiei video va fi setată la %1, care este limita superioară pentru serviciul de transmisiune actual. Dacă ești sigur că vrei să depășești %1, activează opțiunile avansate ale codificatorului și debifează „Impune limitele ratei de biți pentru serviciul de transmisiune”." Basic.Settings.Output.Simple.Warn.AudioBitrate="Avertisment: Rata de biți a transmisiei audio va fi setată la %1, care este limita superioară pentru serviciul de transmisiune actual. Dacă ești sigur că vrei să depășești %1, activează opțiunile avansate ale codificatorului și debifează „Impune limitele ratei de biți pentru serviciul de transmisiune”." +Basic.Settings.Output.Simple.Warn.CannotPause="Avertisment: Înregistrările nu pot fi puse pe pauză dacă calitatea de înregistrare este setată pe „La fel cu cea a streamului”." Basic.Settings.Output.Simple.Warn.Encoder="Avertisment: Înregistrarea cu un codificator software la o calitate diferită de cea a transmisiunii va necesita o utilizare CPU crescută dacă transmiți şi înregistrezi în același timp." Basic.Settings.Output.Simple.Warn.Lossless="Avertisment: Calitatea lossless generează dimensiuni extrem de mari de fișiere! Calitatea lossless poate folosi până la 7GB spațiu de disc per minut la frecvențe de cadre și rezoluții ridicate. Lossless nu este recomandat pentru înregistrări lungi decât dacă ai o cantitate foarte mare de spațiu disponibil pe disc." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Sigur vrei să folosești calitatea lossless?" @@ -564,7 +596,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (presetare x264 cu Basic.Settings.Output.VideoBitrate="Rată de biți video" Basic.Settings.Output.AudioBitrate="Rată de biți audio" Basic.Settings.Output.Reconnect="Reconectare automată" -Basic.Settings.Output.RetryDelay="Întârziere pentru reîncercare (secunde)" Basic.Settings.Output.MaxRetries="Reîncercări maxime" Basic.Settings.Output.Advanced="Activează setările avansate ale codificatorului" Basic.Settings.Output.EncoderPreset="Presetare pentru codificator" @@ -634,7 +665,8 @@ Basic.Settings.Video.DisableAero="Dezactivează Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Biliniar (Cel mai rapid, dar neclar în cazul scalării)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (Scalare ascuțită, 16 mostre)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Scalare ascuțită, 32 de mostre)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Scalare ascuțită, 36 de mostre)" +Basic.Settings.Video.DownscaleFilter.Area="Zonă (Sumă ponderată, 4/6/9 mostre)" Basic.Settings.Audio="Audio" Basic.Settings.Audio.SampleRate="Rată de eșantionare" @@ -642,8 +674,16 @@ Basic.Settings.Audio.Channels="Canale" Basic.Settings.Audio.MeterDecayRate.Fast="Rapidă" Basic.Settings.Audio.MeterDecayRate.Medium="Medie (Type I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Lentă (Type II PPM)" +Basic.Settings.Audio.MultiChannelWarning.Enabled="AVERTISMENT: Sunetul audio cu sunet surround este activat." +Basic.Settings.Audio.MultichannelWarning.Title="Activezi sistemul audio cu sunet surround?" +Basic.Settings.Audio.MultichannelWarning.Confirm="Sigur vrei să activezi sistemul audio cu sunet surround?" +Basic.Settings.Audio.Devices="Dispozitive" Basic.Settings.Audio.DesktopDevice="Audio desktop" Basic.Settings.Audio.DesktopDevice2="Audio desktop 2" +Basic.Settings.Audio.AuxDevice="Audio microfon/auxiliar" +Basic.Settings.Audio.AuxDevice2="Audio microfon/auxiliar 2" +Basic.Settings.Audio.AuxDevice3="Audio microfon/auxiliar 3" +Basic.Settings.Audio.AuxDevice4="Audio microfon/auxiliar 4" Basic.Settings.Audio.EnablePushToMute="Activează push-to-mute" Basic.Settings.Audio.PushToMuteDelay="Întârziere la push-to-mute" Basic.Settings.Audio.EnablePushToTalk="Activează push-to-talk" @@ -661,26 +701,30 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Inactiv" Basic.Settings.Advanced.FormatWarning="Atentie: Formatele de culori diferite de NV12 sunt facute pentru inregistrare si nu sunt recomandate in cazul streaming-ului. Streaming-ul e posibil sa ceara mai multe resurse CPU datorita conversiei formatului culorii." Basic.Settings.Advanced.Audio.BufferingTime="Timp pentru zona tampon audio" Basic.Settings.Advanced.Video.ColorFormat="Format de culori" +Basic.Settings.Advanced.Video.ColorSpace="Spațiu de culori" +Basic.Settings.Advanced.Video.ColorRange="Gamă de culori" Basic.Settings.Advanced.Video.ColorRange.Partial="Parțială" Basic.Settings.Advanced.Video.ColorRange.Full="Completă" +Basic.Settings.Advanced.Audio.MonitoringDevice="Dispozitiv de monitorizare" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Implicit" Basic.Settings.Advanced.StreamDelay="Întârziere pentru transmisiune" -Basic.Settings.Advanced.StreamDelay.Duration="Durată (secunde)" Basic.Settings.Advanced.StreamDelay.Preserve="Păstrează punctul de tăiere (crește întârzierea) la reconectare" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Utilizare estimată a memoriei: %1 MB" Basic.Settings.Advanced.Network="Rețea" Basic.Settings.Advanced.Network.BindToIP="Leagă de IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Activează noul cod pentru rețea" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Mod de latență redusă" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Comportamentul focalizării pentru tastele rapide" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Nu dezactiva niciodată tastele rapide" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Dezactivează tastele rapide când fereastra principală este în prim-plan" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Dezactivează tastele rapide când fereastra principală nu este focalizată" Basic.Settings.Advanced.AutoRemux="Remuxează automat în mp4" Basic.Settings.Advanced.AutoRemux.MP4="(înregistrează ca mkv)" Basic.AdvAudio="Proprietăți audio avansate" Basic.AdvAudio.Name="Nume" -Basic.AdvAudio.Mono="Transformă în mono" +Basic.AdvAudio.Volume="Volum" Basic.AdvAudio.Balance="Balans" -Basic.AdvAudio.SyncOffset="Decalajul sincronizării (ms)" Basic.AdvAudio.Monitoring="Monitorizare audio" Basic.AdvAudio.Monitoring.None="Monitorizare dezactivată" Basic.AdvAudio.Monitoring.MonitorOnly="Numai monitorizare (amuțește ieșirea)" @@ -733,6 +777,7 @@ Hotkeys.AppleKeypadSubtract="- (Tastatură numerică)" Hotkeys.AppleKeypadDecimal=". (Tastatură numerică)" Hotkeys.AppleKeypadEqual="= (Tastatură numerică)" Hotkeys.MouseButton="Mouse %1" +Hotkeys.Escape="Esc" Mute="Pune pe mut" Unmute="Scoate de pe mut" @@ -744,12 +789,17 @@ SceneItemHide="Ascunde '%1'" OutputWarnings.NoTracksSelected="Trebuie să selectezi cel puțin o pistă" OutputWarnings.MultiTrackRecording="Atenție: Anumite formate (precum FLV) nu suportă multiple piste per înregistrare" +OutputWarnings.CannotPause="Avertisment: Înregistrările nu pot fi puse pe pauză dacă codificatorul de înregistrare este setat pe „(Folosește codificatorul de transmisiune)”" FinalScene.Title="Șterge scena" FinalScene.Text="Trebuie să existe cel puțin o scenă." +NoSources.Title="Nicio sursă" +NoSources.Text="Se pare că nu ai adăugat încă nicio sursă video, așa că se va afișa doar un ecran negru. Sigur vrei să faci asta?" +NoSources.Label="Nu ai nicio sursă. Dă clic pe\nbutonul + de mai jos sau\nclic dreapta aici pentru a adăuga una." ChangeBG="Setează culoarea" +CustomColor="Culoare personalizată" BrowserSource.EnableHardwareAcceleration="Activează accelerarea hardware pentru Browser Source" @@ -762,4 +812,5 @@ About.License="Licență" About.Contribute="Sprijină proiectul OBS" +PreviewTransition="Previzualizează tranziția" diff --git a/UI/data/locale/ru-RU.ini b/UI/data/locale/ru-RU.ini index 61e686c..9f408e9 100644 --- a/UI/data/locale/ru-RU.ini +++ b/UI/data/locale/ru-RU.ini @@ -23,7 +23,7 @@ Settings="Настройки" Display="Экран" Name="Название" Exit="Выход" -Mixer="Микшер" +Mixer="Аудио микшер" Browse="Обзор" Mono="Моно" Stereo="Стерео" @@ -91,6 +91,10 @@ AlreadyRunning.LaunchAnyway="Запустить в любом случае" DockCloseWarning.Title="Закрытие закрепляемого окна" DockCloseWarning.Text="Вы только что закрыли закрепляемое окно. Если вы хотите показать его снова, используйте меню Вид → Док-панели в строке меню." +ExtraBrowsers="Пользовательские доки браузера" +ExtraBrowsers.Info="Добавьте док-панели, указав имя или ссылку, затем нажмите Принять или Закрыть, чтобы открыть док-панели. Вы можете добавлять или удалять док-панели когда угодно." +ExtraBrowsers.DockName="Название дока" + Auth.Authing.Title="Аутентификация..." Auth.Authing.Text="Аутентификация с %1, пожалуйста подождите..." Auth.AuthFailure.Title="Ошибка аутентификации" @@ -106,7 +110,8 @@ Auth.StreamInfo="Информация о трансляции" TwitchAuth.Stats="Статистика Twitch" TwitchAuth.Feed="Лента активности Twitch" TwitchAuth.TwoFactorFail.Title="Не удалось запросить ключ трансляции" -TwitchAuth.TwoFactorFail.Text="Невозможно подключиться к учётной записи Twitch. Пожалуйста, убедитесь, что в настройках безопасности включена и настроена двухфакторная аутентификация." +TwitchAuth.TwoFactorFail.Text="OBS не смогло подключиться к вашему Twitch аккаунту. Пожалуйста, проверьте что двуфакторная аутентификация включена в Настройках безопасности Twitch она требуется для начала прямой трансляции." +RestreamAuth.Channels="Restream каналы" Copy.Filters="Копировать фильтры" Paste.Filters="Вставить фильтры" @@ -139,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 или 30, но предпоч Basic.AutoConfig.VideoPage.CanvasExplanation="Примечание: Разрешение холста (базовое), не обязательно должно совпадать с разрешением трансляции или записи. Реальное разрешение вашей трансляции/записи может быть снижено для уменьшения использования ресурсов или битрейта." Basic.AutoConfig.StreamPage="Информация о трансляции" Basic.AutoConfig.StreamPage.SubTitle="Пожалуйста, введите вашу информацию о трансляциях" -Basic.AutoConfig.StreamPage.ConnectAccount="Подключить аккаунт (необязательно)" +Basic.AutoConfig.StreamPage.ConnectAccount="Подключить аккаунт (рекомендуется)" Basic.AutoConfig.StreamPage.DisconnectAccount="Отключить аккаунт" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Отключить аккаунт?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Это изменение вступит в силу немедленно. Вы уверены, что хотите отключить ваш аккаунт?" @@ -178,7 +183,7 @@ Basic.Stats.HDDSpaceAvailable="Доступно места на диске" Basic.Stats.MemoryUsage="Использование памяти" Basic.Stats.AverageTimeToRender="Среднее время рендеринга кадра" Basic.Stats.SkippedFrames="Пропущенные кадры из-за задержки кодирования" -Basic.Stats.MissedFrames="Кадры, пропущенные из-за отставания рендеринга" +Basic.Stats.MissedFrames="Пропущенные кадры из-за отставания рендеринга" Basic.Stats.Output.Stream="Трансляция" Basic.Stats.Output.Recording="Запись" Basic.Stats.Status="Статус" @@ -210,9 +215,9 @@ Updater.GameCaptureActive.Text="Библиотека захвата игр уж QuickTransitions.SwapScenes="Менять местами сцены предпросмотра и вывода после перехода" QuickTransitions.SwapScenesTT="Меняет местами сцены предпросмотра и вывода после перехода (если оригинальная выходная сцена до сих пор существует).\nЭто не отменяет никаких изменений, которые возможно были сделаны в оригинальной выходной сцене." QuickTransitions.DuplicateScene="Дублировать сцену" -QuickTransitions.DuplicateSceneTT="При редактировании одной и той же сцены, функция позволяет трансформировать редактирования/видимости источников без изменения выхода.\nДля редактирования свойств источников без изменения выходного сигнала, включить \"дублировать источники'.\nИзменение этого параметра приведет к сбросу выходного сигнала в сцене (если оно еще существует)." +QuickTransitions.DuplicateSceneTT="При редактировании одной и той же сцены, функция позволяет трансформировать редактирования/видимости источников без изменения выхода.\nДля редактирования свойств источников без изменения выходного сигнала, включить \"дублировать источники'.\nИзменение этого параметра приведёт к сбросу выходного сигнала в сцене (если оно ещё существует)." QuickTransitions.EditProperties="Дублировать источники" -QuickTransitions.EditPropertiesTT="При редактировании одной и той же сцены, функция позволяет редактировать свойства источников без изменения выхода.\nЭто может только использоваться, если \"Повторяющиеся Сцены\" включен.\nНекоторые источники (такие как захват или медиа-источники) не поддерживаются и не могут быть отредактированы отдельно.\nИзменение этого параметра приведет к сбросу выходного сигнала в сцене (если оно еще существует).\n\nПредупреждение: поскольку источники будут дублироваться, это может потребовать дополнительных системных ресурсов или видео." +QuickTransitions.EditPropertiesTT="При редактировании одной и той же сцены, функция позволяет редактировать свойства источников без изменения выхода.\nЭто может только использоваться, если параметр \"Повторяющиеся Сцены\" включён.\nНекоторые источники (такие как захват или медиа-источники) не поддерживаются и не могут быть отредактированы отдельно.\nИзменение этого параметра приведёт к сбросу выходного сигнала в сцене (если оно ещё существует).\n\nПредупреждение: поскольку источники будут дублироваться, это может потребовать дополнительных системных ресурсов или видео." QuickTransitions.HotkeyName="Быстрый переход: %1" Basic.AddTransition="Добавить настраиваемый переход" @@ -240,6 +245,9 @@ ConfirmStart.Text="Вы уверены, что хотите начать тра ConfirmStop.Title="Остановить трансляцию?" ConfirmStop.Text="Вы уверены, что хотите остановить трансляцию?" +ConfirmStopRecord.Title="Остановить запись?" +ConfirmStopRecord.Text="Вы уверены, что хотите остановить запись?" + ConfirmBWTest.Title="Начать тест пропускной способности?" ConfirmBWTest.Text="Вы настроили OBS в режиме тестирования пропускной способности. Этот режим позволяет тестировать сеть без выхода вашего канала в эфир. После того, как вы закончите тестирование, вам необходимо выключить эту функцию для того чтобы зрители могли видеть вашу трансляцию.\n\nВы хотите продолжить?" @@ -253,15 +261,17 @@ ConfirmRemove.TextMultiple="Вы уверены, что вы хотите уда Output.StartStreamFailed="Не удалось запустить вещание" Output.StartRecordingFailed="Не удалось начать запись" Output.StartReplayFailed="Не удалось запустить воспроизведение из буфера" -Output.StartFailedGeneric="Сбой вывода. Подробности отражены в журнале.\n\nПримечание: Если вы используете кодировщики NVENC или AMD, убедитесь что у вас установлена последняя версия видеорайвера." +Output.StartFailedGeneric="Сбой вывода. Подробности отражены в журнале.\n\nПримечание: Если вы используете кодировщики NVENC или AMD, убедитесь что у вас установлена последняя версия видеодрайвера." +Output.ReplayBuffer.PauseWarning.Title="Не удаётся сохранить повторы во время паузы" +Output.ReplayBuffer.PauseWarning.Text="Предупреждение: Повторы не могут быть сохранены во время приостановления записи." Output.ConnectFail.Title="Не удалось подключиться" Output.ConnectFail.BadPath="Неверный путь или URL соединения. Пожалуйста, проверьте настройки, чтобы подтвердить, что они являются действительными." Output.ConnectFail.ConnectFailed="Не удалось подключиться к серверу" Output.ConnectFail.InvalidStream="Не удалось получить доступ к указанному ключу канала или стрима, пожалуйста, перепроверьте ключ. Если он правильный, проблема может быть с подключением к серверу." Output.ConnectFail.Error="Произошла непредвиденная ошибка при попытке подключиться к серверу. Более подробная информация в лог-файле." -Output.ConnectFail.Disconnected="Отключен от сервера." +Output.ConnectFail.Disconnected="Отключён от сервера." Output.StreamEncodeError.Title="Ошибка кодирования" Output.StreamEncodeError.Msg="Произошла ошибка кодировщика во время трансляции." @@ -444,6 +454,8 @@ Basic.Main.StartRecording="Начать запись" Basic.Main.StartReplayBuffer="Запустить повтор" Basic.Main.StartStreaming="Запустить трансляцию" Basic.Main.StopRecording="Остановить запись" +Basic.Main.PauseRecording="Приостановить запись" +Basic.Main.UnpauseRecording="Возобновить запись" Basic.Main.StoppingRecording="Остановка записи..." Basic.Main.StopReplayBuffer="Остановить повтор" Basic.Main.StoppingReplayBuffer="Остановка повтора..." @@ -502,6 +514,7 @@ Basic.MainMenu.View.Toolbars="Панель инструментов (&T)" Basic.MainMenu.View.Docks="Док-панели" Basic.MainMenu.View.Docks.ResetUI="Сбросить интерфейс" Basic.MainMenu.View.Docks.LockUI="Зафиксировать интерфейс" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Пользовательские доки браузера..." Basic.MainMenu.View.Toolbars.Listboxes="Списки (&L)" Basic.MainMenu.View.SceneTransitions="Сцена переходов (&C)" Basic.MainMenu.View.StatusBar="Строка состояния (&S)" @@ -534,8 +547,8 @@ Basic.MainMenu.Help.CrashLogs.UploadLastLog="Загрузить последни Basic.MainMenu.Help.About="О программе (&A)" Basic.Settings.ProgramRestart="Для изменения этих параметров требуется перезапустить программу." -Basic.Settings.ConfirmTitle="Подтверждить Изменения" -Basic.Settings.Confirm="У вас есть несохраненные изменения. Сохранить изменения?" +Basic.Settings.ConfirmTitle="Подтверждение изменений" +Basic.Settings.Confirm="У вас есть несохранённые изменения. Сохранить изменения?" Basic.Settings.General="Общие" Basic.Settings.General.Theme="Тема" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="Проверять наличие об Basic.Settings.General.OpenStatsOnStartup="Открывать окно статистики при запуске" Basic.Settings.General.WarnBeforeStartingStream="Показывать окно подтверждения при запуске трансляции" Basic.Settings.General.WarnBeforeStoppingStream="Показывать окно подтверждения при остановке трансляции" +Basic.Settings.General.WarnBeforeStoppingRecord="Показывать окно подтверждения при остановке записи" Basic.Settings.General.Projectors="Проекторы" Basic.Settings.General.HideProjectorCursor="Скрыть курсор за проекторы" Basic.Settings.General.ProjectorAlwaysOnTop="Показывать проекторы поверх всех окон" @@ -591,12 +605,15 @@ Basic.Settings.Output.Encoder="Кодировщик" Basic.Settings.Output.SelectDirectory="Выбрать каталог записи" Basic.Settings.Output.SelectFile="Выбрать файл записи" Basic.Settings.Output.EnforceBitrate="Следовать ограничениям битрейта, накладываемые потоковой службой" +Basic.Settings.Output.DynamicBitrate="Динамически изменять битрейт для управления перегрузкой сети" +Basic.Settings.Output.DynamicBitrate.Beta="Динамически изменять битрейт для управления перегрузкой сети (бета)" +Basic.Settings.Output.DynamicBitrate.TT="Вместо пропуска кадров, будет задействовано динамическое изменение битрейта на лету, чтобы уменьшить перегрузку сети.\n\nОбратите внимание, что это может увеличить задержку для зрителей, в случае внезапного забивания канала.\nПосле уменьшения битрейта может потребоваться несколько минут для его восстановления.\n\nВ настоящее время поддерживается только для RTMP." Basic.Settings.Output.Mode="Режим вывода" Basic.Settings.Output.Mode.Simple="Простой" Basic.Settings.Output.Mode.Adv="Расширенный" Basic.Settings.Output.Mode.FFmpeg="Вывод FFmpeg" Basic.Settings.Output.UseReplayBuffer="Включить Буфер повтора" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Максимальное время повтора (секунд)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Максимальное время повтора" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Максимальный объем памяти (МБ)" Basic.Settings.Output.ReplayBuffer.Estimate="Предполагаемое использование памяти: %1 МБ" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Невозможно оценить использование памяти. Пожалуйста, установите максимальный объем памяти." @@ -611,8 +628,9 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Неотличимое кач Basic.Settings.Output.Simple.RecordingQuality.Lossless="Без потери качества, чрезвычайно большой размер файла" Basic.Settings.Output.Simple.Warn.VideoBitrate="Предупреждение: битрейт видео при вещании будет установлен на %1, что является максимумом для текущей потоковой службы. Если вы уверены, что хотите получить битрейт больше %1, включите дополнительные настройки кодировщика и снимите флажок с \"Принудительно использовать ограничения битрейта потоковой службы\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Предупреждение: битрейт аудио при вещании будет установлен на %1, что является максимумом для текущей потоковой службы. Если вы уверены, что хотите получить битрейт больше %1, включите дополнительные настройки кодировщика и снимите флажок с \"Принудительно использовать ограничения битрейта потоковой службы\"." +Basic.Settings.Output.Simple.Warn.CannotPause="Предупреждение: Записи не могут быть приостановлены, если качество записи установлено на \"То же самое как поток\"." Basic.Settings.Output.Simple.Warn.Encoder="Предупреждение: Запись с программным кодировщиком в качестве, отличным от качества трансляции, потребует дополнительной нагрузки на ЦП, если записывать и транслировать одновременно." -Basic.Settings.Output.Simple.Warn.Lossless="Предупреждение: Качество без потерь создает чрезвычайно большие файлы! Такое качество может использовать свыше 7 гигабайт дискового пространства в минуту при высоком разрешении и частоте кадров. Оно не рекомендуется для долгой записи, если у Вас нет очень много места на диске." +Basic.Settings.Output.Simple.Warn.Lossless="Предупреждение: Качество без потерь создаёт чрезвычайно большие файлы! Такое качество может использовать свыше 7 гигабайт дискового пространства в минуту при высоком разрешении и частоте кадров. Оно не рекомендуется для долгой записи, если у Вас нет очень много места на диске." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Вы уверены, что хотите записывать без потери качества?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Предупреждение о качестве без потерь!" Basic.Settings.Output.Simple.Encoder.Software="Программный (x264)" @@ -623,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Программный (x26 Basic.Settings.Output.VideoBitrate="Битрейт видео" Basic.Settings.Output.AudioBitrate="Битрейт аудио" Basic.Settings.Output.Reconnect="Автопереподключение" -Basic.Settings.Output.RetryDelay="Переподключиться через (секунд)" +Basic.Settings.Output.RetryDelay="Задержка повтора" Basic.Settings.Output.MaxRetries="Количество попыток подключиться" Basic.Settings.Output.Advanced="Включить дополнительные настройки кодировщика" Basic.Settings.Output.EncoderPreset="Предустановка кодировщика" @@ -671,8 +689,9 @@ Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Настройки мульти Basic.Settings.Output.Adv.FFmpeg.GOPSize="Интервал ключевых кадров (кадры)" Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Показать все кодеки (даже потенциально несовместимые)" +FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" -FilenameFormatting.TT="%CCYY Год, четыре знака\n%YY Год, последние два знака (00-99)\n%MM Месяц в числовом значении (01-12)\n%DD День месяца, ноль не опускается (01-31)\n%hh Час в 24-часовом формате (00-23)\n%mm Минута (00-59)\n%ss Секунда (00-61)\n%% Знак '%'\n%a Сокращенное название дня недели\n%A Полное название дня недели\n%b Сокращенное название месяца\n%B Полное название месяца\n%d День месяца, ноль не опускается (01-31)\n%H Час в 24 часовом формате (00-23)\n%I Час в 12 часовом формате (01-12)\n%m Месяц в числовом значении (01-12)\n%M Минута (00-59)\n%p Обозначение AM или PM\n%S Секунда (00-61)\n%y Год, последние два знака (00-99)\n%Y Год\n%z ISO 8601 смещение от UTC или\n название или сокращение часового пояса\n%Z Название или сокращение часового пояса\n" +FilenameFormatting.TT="%CCYY Год, четыре знака\n%YY Год, последние два знака (00-99)\n%MM Месяц в числовом значении (01-12)\n%DD День месяца, ноль не опускается (01-31)\n%hh Час в 24-часовом формате (00-23)\n%mm Минута (00-59)\n%ss Секунда (00-61)\n%% Знак '%'\n%a Сокращенное название дня недели\n%A Полное название дня недели\n%b Сокращённое название месяца\n%B Полное название месяца\n%d День месяца, ноль не опускается (01-31)\n%H Час в 24 часовом формате (00-23)\n%I Час в 12 часовом формате (01-12)\n%m Месяц в числовом значении (01-12)\n%M Минута (00-59)\n%p Обозначение AM или PM\n%S Секунда (00-61)\n%y Год, последние два знака (00-99)\n%Y Год\n%z ISO 8601 смещение от UTC или\n название или сокращение часового пояса\n%Z Название или сокращение часового пояса\n" Basic.Settings.Video="Видео" Basic.Settings.Video.Adapter="Видеоадаптер" @@ -693,7 +712,8 @@ Basic.Settings.Video.DisableAero="Отключить Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Билинейный (самый быстрый, но размытый при масштабировании)" Basic.Settings.Video.DownscaleFilter.Bicubic="Бикубический (чёткое масштабирование, 16 выборок)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Метод Ланцоша (Чёткое масштабирование, 32 выборки)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Метод Ланцоша (Чёткое масштабирование, 36 выборок)" +Basic.Settings.Video.DownscaleFilter.Area="Область (взвешенная сумма, 4/6/9 выборок)" Basic.Settings.Audio="Аудио" Basic.Settings.Audio.SampleRate="Частота дискретизации" @@ -704,12 +724,12 @@ Basic.Settings.Audio.MeterDecayRate.Fast="Быстро" Basic.Settings.Audio.MeterDecayRate.Medium="Средне (PPM типа I)" Basic.Settings.Audio.MeterDecayRate.Slow="Медленно (PPM типа II)" Basic.Settings.Audio.PeakMeterType="Тип измерителя пиков" -Basic.Settings.Audio.PeakMeterType.SamplePeak="Упрощенный" +Basic.Settings.Audio.PeakMeterType.SamplePeak="Упрощённый" Basic.Settings.Audio.PeakMeterType.TruePeak="Точный (Повышенное использование ЦП)" Basic.Settings.Audio.MultiChannelWarning.Enabled="ВНИМАНИЕ: Объемный звук включен." -Basic.Settings.Audio.MultichannelWarning="При запуске стрима проверьте, поддерживает ли ваш сервис потокового вещания объемный звук (как запись, так и воспроизведение). Twitch, Facebook 360 Live, Mixer RTMP, Smashcast — примеры сервисов, полностью поддерживающих объемное звучание. Несмотря на то, что Facebook Live и Youtube Live принимают объёмный звук, Facebook Live микширует его в стерео, а Youtube Live воспроизводит только два канала.\n\nЗвуковые фильтры OBS совместимы с объемным звучанием, хотя поддержка плагинов VST не гарантируется." +Basic.Settings.Audio.MultichannelWarning="При запуске стрима проверьте, поддерживает ли ваш сервис потокового вещания объёмный звук (как запись, так и воспроизведение). Facebook 360 Live, Mixer RTMP, Smashcast — примеры сервисов, полностью поддерживающих объёмное звучание. Несмотря на то, что Facebook Live и Youtube Live принимают объёмный звук, Facebook Live микширует его в стерео, а Youtube Live воспроизводит только два канала.\n\nЗвуковые фильтры OBS совместимы с объёмным звучанием, хотя поддержка плагинов VST не гарантируется." Basic.Settings.Audio.MultichannelWarning.Title="Включить объемный звук?" -Basic.Settings.Audio.MultichannelWarning.Confirm="Хотите включить объемный звук?" +Basic.Settings.Audio.MultichannelWarning.Confirm="Хотите включить объёмный звук?" Basic.Settings.Audio.Devices="Устройства" Basic.Settings.Audio.DesktopDevice="Аудио с рабочего стола" Basic.Settings.Audio.DesktopDevice2="Аудио с рабочего стола 2" @@ -742,23 +762,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Устройство просл Basic.Settings.Advanced.Audio.MonitoringDevice.Default="По умолчанию" Basic.Settings.Advanced.Audio.DisableAudioDucking="Отключить приглушение звуков Windows" Basic.Settings.Advanced.StreamDelay="Задержка потока" -Basic.Settings.Advanced.StreamDelay.Duration="Продолжительность (секунд)" +Basic.Settings.Advanced.StreamDelay.Duration="Длительность" Basic.Settings.Advanced.StreamDelay.Preserve="Сохранить точку отсечки (увеличить задержку) при переподключении" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Предполагаемое использование памяти: %1 МБ" Basic.Settings.Advanced.Network="Сеть" Basic.Settings.Advanced.Network.BindToIP="Привязать к IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Включить новый сетевой код" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Режим низкой задержки" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Поведение фокуса горячих клавиш" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Никогда не отключать горячие клавиши" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Отключить горячие клавиши, если главное окно находится в фокусе" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Отключать горячие клавиши, когда главное окно вне фокуса" Basic.Settings.Advanced.AutoRemux="Автоматически ремультиплексировать в mp4" Basic.Settings.Advanced.AutoRemux.MP4="(записывать как mkv)" Basic.AdvAudio="Расширенные свойства аудио" Basic.AdvAudio.Name="Название" Basic.AdvAudio.Volume="Громкость" -Basic.AdvAudio.Mono="Объединение в один канал" +Basic.AdvAudio.Mono="Моно" Basic.AdvAudio.Balance="Баланс" -Basic.AdvAudio.SyncOffset="Смещение синхронизации (мс)" +Basic.AdvAudio.SyncOffset="Смещение синхронизации" Basic.AdvAudio.Monitoring="Аудио прослушивание" Basic.AdvAudio.Monitoring.None="Выключить прослушивание" Basic.AdvAudio.Monitoring.MonitorOnly="Только прослушивание (заглушить вывод)" @@ -823,13 +846,14 @@ SceneItemHide="Скрыть '%1'" OutputWarnings.NoTracksSelected="Вы должны выбрать хотя бы одну звуковую дорожку" OutputWarnings.MultiTrackRecording="Предупреждение: Некоторые форматы (такие как FLV) не поддерживают множественные звуковые дорожки" -OutputWarnings.MP4Recording="Внимание: Записи, сохраненные в MP4/MOV будут нечитаемы если файл не будет завершен (например, в результате BSOD'а, потери напряжения в сети и т.д.). Если вы хотите записывать несколько аудио дорожек, рассмотрите использование MKV и последующее ремультиплексирование в MP4/MOV после завершения записи (Файл → Ремультиплексирование записей)" +OutputWarnings.MP4Recording="Внимание: Записи, сохранённые в MP4/MOV будут нечитаемы, если файл не будет завершён (например, в результате BSOD'а, потери напряжения в сети и т.д.). Если вы хотите записывать несколько аудио дорожек, рассмотрите использование MKV и последующее ремультиплексирование в MP4/MOV после завершения записи (Файл → Ремультиплексирование записей)" +OutputWarnings.CannotPause="Предупреждение: Записи не могут быть приостановлены, если кодировщик записи установлен на \"(Использовать кодировщик потока)\"" FinalScene.Title="Удалить сцену" FinalScene.Text="Здесь должна быть по крайней мере одна сцена." NoSources.Title="Нет источников" -NoSources.Text="Похоже, вы еще не добавили ни одного источника. Вы будете выводить только пустой экран. Вы уверены, что хотите этого?" +NoSources.Text="Похоже, вы ещё не добавили ни одного источника. Вы будете выводить только пустой экран. Вы уверены, что хотите этого?" NoSources.Text.AddSource="Вы можете добавить источники, нажав иконку + под окном Источники в главном окне в любое время." NoSources.Label="У вас нет источников.\nНажмите кнопку + ниже,\nили нажмите правой кнопкой здесь, чтобы добавить его." diff --git a/UI/data/locale/sk-SK.ini b/UI/data/locale/sk-SK.ini index acabb1d..cd74837 100644 --- a/UI/data/locale/sk-SK.ini +++ b/UI/data/locale/sk-SK.ini @@ -23,7 +23,6 @@ Settings="Nastavenia" Display="Monitor" Name="Meno" Exit="Ukončiť" -Mixer="Zmiešavač" Browse="Prehľadávať" Mono="Mono" Stereo="Stereo" @@ -61,7 +60,7 @@ Hours="Hodín" Minutes="Minúty" Seconds="Sekundy" Deprecated="Zastaralé" -ReplayBuffer="Medzipamäť znovuprehratia" +ReplayBuffer="Záznam do pamäte" Import="Importovať" Export="Exportovať" Copy="Kopírovať" @@ -91,6 +90,8 @@ AlreadyRunning.LaunchAnyway="Napriek tomu spustiť" DockCloseWarning.Title="Zatvorenie dokovateľného okna" DockCloseWarning.Text="Práve ste zatvorili dokovateľné okno. Ak ho chcete znovu zobraziť, použite menu Zobraziť → Doky." +ExtraBrowsers.DockName="Názov doku" + Auth.Authing.Title="Autentifikácia..." Auth.Authing.Text="Prebieha overovanie so službou %1, čakajte..." Auth.AuthFailure.Title="Overenie zlyhalo" @@ -105,6 +106,9 @@ Auth.Chat="Chat" Auth.StreamInfo="Informácie o vysielaní" TwitchAuth.Stats="Twitch štatistiky" TwitchAuth.Feed="Kanál aktivít v službe Twitch" +TwitchAuth.TwoFactorFail.Title="Nemožno získať vysielací kľúč" +TwitchAuth.TwoFactorFail.Text="OBS sa nedokáže pripojiť k vášmu Twitch účtu. Prosím, uistite sa, že máte v bezpečnostných nastaveniach služby Twitch nastavené dvojfaktorové overenie, ktoré je nutné pre vysielanie." +RestreamAuth.Channels="Kanály Restream" Copy.Filters="Kopírovať filtre" Paste.Filters="Vložiť filtre" @@ -134,10 +138,9 @@ Basic.AutoConfig.VideoPage.BaseResolution.Display="Monitor %1 (%2x%3)" Basic.AutoConfig.VideoPage.FPS.UseCurrent="Použiť aktuálne (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 alebo 30, ale radšej 60, ak je to možné" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 alebo 30, ale radšej vysoké rozlíšenie" -Basic.AutoConfig.VideoPage.CanvasExplanation="Poznámka: rozlíšenie (základné) plátna nie je nevyhnutne rovnaké ako rozlíšenie v ktorom budete streamovať alebo nahrávať. Skutočné streamovacie/nahrávacie rozlíšenie môže byť zmenšené preto aby sa znížilo používanie dát alebo zdrojov." +Basic.AutoConfig.VideoPage.CanvasExplanation="Poznámka: rozlíšenie (základné) plátna nie je nevyhnutne rovnaké ako rozlíšenie, v ktorom budete vysielať alebo nahrávať. Skutočné vysielacie/nahrávacie rozlíšenie môže byť zmenšené preto, aby sa znížilo používanie dát alebo zdrojov." Basic.AutoConfig.StreamPage="Informácie o streame" Basic.AutoConfig.StreamPage.SubTitle="Prosím, zadajte svoje údaje o vysielaní" -Basic.AutoConfig.StreamPage.ConnectAccount="Prepojiť účet (voliteľné)" Basic.AutoConfig.StreamPage.DisconnectAccount="Odpojiť účet" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Odpojiť účet?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Táto zmena sa uplatní okamžite. Naozaj chcete odpojiť svoj účet?" @@ -150,7 +153,7 @@ Basic.AutoConfig.StreamPage.StreamKey="Streamovací kľúč" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Odkaz)" Basic.AutoConfig.StreamPage.PerformBandwidthTest="Odhadnúť bitrate pomocou testu rýchlosti pripojenia (môže to trvať pár minút)" Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Preferovať hardvérové enkódovanie" -Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Hardwarové enkódovanie eliminuje väčšinu využitia CPU, ale na dosiahnutie rovnakej kvality videa môže vyžadovať väčší bitrate." +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Hardvérové kódovanie eliminuje väčšinu využitia CPU, ale na dosiahnutie rovnakej kvality videa môže vyžadovať väčší bitrate." Basic.AutoConfig.StreamPage.StreamWarning.Title="Upozornenie o streame" Basic.AutoConfig.StreamPage.StreamWarning.Text="Test rýchlosti pripojenia vysiela obraz bez zvuku s náhodnými dátami. Odporúčame dočasne zakázať záznam vysielaní a nastaviť živý prenos ako súkromný, kým sa celý test nedokončí. Pokračovať?" Basic.AutoConfig.TestPage="Konečné výsledky" @@ -238,6 +241,9 @@ ConfirmStart.Text="Naozaj chcete spustiť stream?" ConfirmStop.Title="Zastaviť stream?" ConfirmStop.Text="Naozaj chcete zastaviť stream?" +ConfirmStopRecord.Title="Zastaviť nahrávanie?" +ConfirmStopRecord.Text="Naozaj si želáte zastaviť nahrávanie?" + ConfirmBWTest.Title="Spustiť test šírky pásma siete?" ConfirmBWTest.Text="Vaše OBS je nakonfigurované pre režim testovania šírky pásma. Toto umožní zistiť parametre vašej siete bez spustenia živého vysielania na vašom kanáli. Po dokončení testovania musíte tento režim zakázať, ináč diváci neuvidia vami prenášaný obsah.\n\nNaozaj si želáte pokračovať?" @@ -250,9 +256,11 @@ ConfirmRemove.TextMultiple="Naozaj si prajete odstrániť %1 položiek?" Output.StartStreamFailed="Nepodarilo sa spustiť streamovanie" Output.StartRecordingFailed="Nepodarilo sa spustiť nahrávanie" -Output.StartReplayFailed="Nepodarilo sa spustiť medzipamäť znovunahrávania" +Output.StartReplayFailed="Nepodarilo sa spustiť záznam do pamäte" Output.StartFailedGeneric="Nastala chyba pri spúšťaní nahrávania. Podrobnosti nájdete v textovom logu.\n\nPoznámka: Ak používate NVENC alebo AMD enkodér, uistite sa, že používate najnovšiu verziu grafického ovládača." +Output.ReplayBuffer.PauseWarning.Title="Nemožno ukladať záznamy pri zapauzovaní" +Output.ReplayBuffer.PauseWarning.Text="Upozornenie: Záznamy nemôžu byť ukladané, keď je pozastavené nahrávanie." Output.ConnectFail.Title="Spojenie sa nepodarilo" Output.ConnectFail.BadPath="Neplatná cesta alebo URL. Prosím, skontrolujte, či sú vaše nastavenia správne." @@ -272,7 +280,7 @@ Output.RecordError.Title="Chyba nahrávania" Output.RecordError.Msg="Pri nahrávaní došlo k nešpecifikovanej chybe." Output.RecordError.EncodeErrorMsg="Nastala chyba pri kódovaní počas nahrávania." Output.ReplayBuffer.NoHotkey.Title="Nepriradená žiadna klávesová skratka!" -Output.ReplayBuffer.NoHotkey.Msg="Nie je nastavená žiadna klávesová skratka pre uloženie záznamu. Nastavte ju, prosím, aby ste mohli ukladať záznam." +Output.ReplayBuffer.NoHotkey.Msg="Nie je nastavená žiadna klávesová skratka pre uloženie záznamu v pamäti. Nastavte ju, prosím, aby ste mohli ukladať záznam." Output.BadPath.Title="Nesprávna cesta k súboru" Output.BadPath.Text="Nastavená cesta k výstupnému súboru je chybná. Prosím, skontrolujte správnosť nastavenej cesty." @@ -439,12 +447,14 @@ Basic.Main.Sources="Zdroje" Basic.Main.Controls="Ovládacie prvky" Basic.Main.Connecting="Pripájanie..." Basic.Main.StartRecording="Spustiť nahrávanie" -Basic.Main.StartReplayBuffer="Spustiť Replay Buffer" +Basic.Main.StartReplayBuffer="Spustiť záznam do pamäte" Basic.Main.StartStreaming="Spustiť stream" Basic.Main.StopRecording="Ukončiť nahrávanie" +Basic.Main.PauseRecording="Pozastaviť nahrávanie" +Basic.Main.UnpauseRecording="Pokračovať v nahrávaní" Basic.Main.StoppingRecording="Zastavenie nahrávania..." -Basic.Main.StopReplayBuffer="Zastaviť Replay Buffer" -Basic.Main.StoppingReplayBuffer="Zastavujem Replay Buffer..." +Basic.Main.StopReplayBuffer="Zastaviť záznam do pamäte" +Basic.Main.StoppingReplayBuffer="Zastavujem záznam do pamäte..." Basic.Main.StopStreaming="Ukončiť stream" Basic.Main.StoppingStreaming="Zastavenie streamu..." Basic.Main.ForceStopStreaming="Zastaviť vysielanie (bez oneskorenia)" @@ -542,6 +552,7 @@ Basic.Settings.General.EnableAutoUpdates="Automaticky kontrolovať aktualizácie Basic.Settings.General.OpenStatsOnStartup="Otvoriť dialógové okno štatistík po štarte" Basic.Settings.General.WarnBeforeStartingStream="Ukáž potvrďovacie okno pri začatí vysielania" Basic.Settings.General.WarnBeforeStoppingStream="Ukáž potvrďovacie okno pri zastavení vysielania" +Basic.Settings.General.WarnBeforeStoppingRecord="Ukáž potvrdzovacie okno pri zastavení nahrávania" Basic.Settings.General.Projectors="Projektory" Basic.Settings.General.HideProjectorCursor="Skryť kurzor pred náhľadmi" Basic.Settings.General.ProjectorAlwaysOnTop="Náhľady vždy navrchu" @@ -552,8 +563,8 @@ Basic.Settings.General.SourceSnapping="Prichytávať zdroje k iným zdrojom" Basic.Settings.General.SnapDistance="Prichytávať citlivosť" Basic.Settings.General.RecordWhenStreaming="Automaticky nahrávať pri vysielaní" Basic.Settings.General.KeepRecordingWhenStreamStops="Nahrávať aj po ukončení vysielania" -Basic.Settings.General.ReplayBufferWhileStreaming="Automaticky zapnúť záznam do pamäti pri začatí vysielania" -Basic.Settings.General.KeepReplayBufferStreamStops="Ponechať záznam do pamäti aktívny i po zastavení vysielania" +Basic.Settings.General.ReplayBufferWhileStreaming="Automaticky zapnúť záznam do pamäte pri začatí vysielania" +Basic.Settings.General.KeepReplayBufferStreamStops="Ponechať záznam do pamäte aktívny i po zastavení vysielania" Basic.Settings.General.SysTray="Systémová lišta" Basic.Settings.General.SysTrayWhenStarted="Minimalizovať do systémovej lišty pri spustení" Basic.Settings.General.SystemTrayHideMinimize="Vždy minimalizovať do systémovej lišty namiesto panela úloh" @@ -593,23 +604,24 @@ Basic.Settings.Output.Mode="Režim výstupu" Basic.Settings.Output.Mode.Simple="Jednoduchý" Basic.Settings.Output.Mode.Adv="Rozšírené" Basic.Settings.Output.Mode.FFmpeg="Výstup FFmpeg" -Basic.Settings.Output.UseReplayBuffer="Zapnúť záznam do pamäti" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximálny čas záznamu (v sekundách)" +Basic.Settings.Output.UseReplayBuffer="Zapnúť záznam do pamäte" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximálny čas záznamu" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximálna pamäť (v megabajtoch)" Basic.Settings.Output.ReplayBuffer.Estimate="Odhadované využitie pamäte: %1 MB" -Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Nemôžem odhadnúť použivanie pamäte. Prosím nastavte maximálny limit pamäte." -Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Poznámka: Uistite sa, že ste nastavili klávesovú skratku pre záznam do pamäte, v sekcii klávesových skratiek)" +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Nemožno odhadnúť využitie pamäte. Prosím, nastavte maximálny pamäťový limit." +Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Poznámka: Uistite sa, že ste nastavili klávesovú skratku pre záznam do pamäte v sekcii klávesových skratiek)" Basic.Settings.Output.ReplayBuffer.Prefix="Predpona názvu súboru záznamu do pamäte" Basic.Settings.Output.ReplayBuffer.Suffix="Prípona" Basic.Settings.Output.Simple.SavePath="Nahrávacia cesta" Basic.Settings.Output.Simple.RecordingQuality="Kvalita nahrávania" -Basic.Settings.Output.Simple.RecordingQuality.Stream="Rovnaká ako pre stream" +Basic.Settings.Output.Simple.RecordingQuality.Stream="Rovnaká ako pre vysielanie" Basic.Settings.Output.Simple.RecordingQuality.Small="Vysoká kvalita, stredná veľkosť súboru" Basic.Settings.Output.Simple.RecordingQuality.HQ="Nerozoznateľná kvalita, veľká veľkosť súboru" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Bezstratová kvalita, ohromne veľké súbory" Basic.Settings.Output.Simple.Warn.VideoBitrate="Upozornenie: Dátový tok vysielaného obrazu bude nastavený na %1, čo je horná hranica pre súčasnú vysielaciu službu. Ak ste si istý, že chcete vysielať nad %1, v rozšírených nastaveniach enkodéra zakážte \"Vynútiť limit dátového toku vysielacou službou\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Upozornenie: Dátový tok vysielaného zvuku bude nastavený na %1, čo je horná hranica pre súčasnú vysielaciu službu. Ak ste si istý, že chcete vysielať nad %1, v rozšírených nastaveniach enkodéra zakážte \"Vynútiť limit dátového toku vysielacou službou\"." -Basic.Settings.Output.Simple.Warn.Encoder="Upozornenie: Nahrávanie softvérovým enkodérom s rozdielnou kvalitou než vysielanie spôsobí zvýšenú záťaž CPU pri nahrávaní a vysielaní zároveň." +Basic.Settings.Output.Simple.Warn.CannotPause="Upozornenie: Nahrávanie nemôže byť pozastavené, ak je kvalita nahrávania nastavená na \"Rovnaké ako pre vysielanie\"." +Basic.Settings.Output.Simple.Warn.Encoder="Upozornenie: Nahrávanie softvérovým kodérom s rozdielnou kvalitou než vysielanie spôsobí zvýšenú záťaž CPU pri nahrávaní a vysielaní zároveň." Basic.Settings.Output.Simple.Warn.Lossless="Varovanie: Bezstratová kvalita generuje ohromne veľké súbory! Bezstratová kvalita môže použiť až 7 gigabajtov za minútu na disku pri vysokých rozlíšeniach a snímkoch za sekundu. Bezstratová kvalita nie je odporúčaná pre dlhé nahrávky pokiaľ nemáte veľmi veľa priestoru na disku." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Ste si istí, že chcete použiť bezstratovú kvalitu?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Varovanie bezstratovej kvality!" @@ -621,7 +633,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softvérový (x264, nízke Basic.Settings.Output.VideoBitrate="Bitrate videa" Basic.Settings.Output.AudioBitrate="Bitrate zvuku" Basic.Settings.Output.Reconnect="Automaticky znovupripájať" -Basic.Settings.Output.RetryDelay="Čas medzi pokusmi (sekundy)" +Basic.Settings.Output.RetryDelay="Oneskorenie opakovania" Basic.Settings.Output.MaxRetries="Maximálny počet pokusov" Basic.Settings.Output.Advanced="Povoliť pokročilé nastavenia enkodéra" Basic.Settings.Output.EncoderPreset="Predvoľba kodéra" @@ -692,7 +704,7 @@ Basic.Settings.Video.DisableAero="Vypnúť Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilineárne (Najrýchlejšie, ale rozmazané pri škálovaní)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bikubické (ostrejšie pri škálovaní, 16 vzoriek)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczosov (ostrejšie pri škálovaní, 32 vzoriek)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczosov (ostrejšie pri škálovaní, 36 vzoriek)" Basic.Settings.Audio="Zvuk" Basic.Settings.Audio.SampleRate="Vzorkovacia frekvencia" @@ -706,7 +718,7 @@ Basic.Settings.Audio.PeakMeterType="Typ merača špičiek" Basic.Settings.Audio.PeakMeterType.SamplePeak="Špička vzorky" Basic.Settings.Audio.PeakMeterType.TruePeak="Pravý Špička (Vyššie využitie CPU)" Basic.Settings.Audio.MultiChannelWarning.Enabled="VAROVANIE: Priestorový zvuk je zapnutý." -Basic.Settings.Audio.MultichannelWarning="Ak vysielate, uistite sa že vaša vysielacia služba podporuje prijímanie a aj prehrávanie priestorového zvuku. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast sú príklady služieb ktoré priestorový zvuk plne podporujú. Avšak Facebook Live a YouTube Live podporujú prijímanie priestorového zvuku, Facebook Live ho prevádza do stereo zvuku a YouTub Live prehráva iba 2 kanály.\n\nOBS zvukové filtre sú kompatibilné s priestorovým zvukom, no podpora u VST pluginu nie je garantovaná." +Basic.Settings.Audio.MultichannelWarning="Ak vysielate, uistite sa že vaša vysielacia služba podporuje prijímanie a aj prehrávanie priestorového zvuku. Facebook 360 Live, Mixer RTMP, Smashcast sú príklady služieb ktoré priestorový zvuk plne podporujú. Avšak Facebook Live a YouTube Live podporujú prijímanie priestorového zvuku, Facebook Live ho prevádza do stereo zvuku a YouTub Live prehráva iba 2 kanály.\n\nOBS zvukové filtre sú kompatibilné s priestorovým zvukom, no podpora u VST pluginu nie je garantovaná." Basic.Settings.Audio.MultichannelWarning.Title="Povoliť priestorový zvuk?" Basic.Settings.Audio.MultichannelWarning.Confirm="Naozaj si želáte povoliť priestorový zvuk?" Basic.Settings.Audio.Devices="Zariadenia" @@ -741,7 +753,7 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Monitorovacie zariadenie" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Predvolené" Basic.Settings.Advanced.Audio.DisableAudioDucking="Vypnúť zvukové utišovanie Windowsu" Basic.Settings.Advanced.StreamDelay="Oneskorenie vysielania" -Basic.Settings.Advanced.StreamDelay.Duration="Trvanie (sekundy)" +Basic.Settings.Advanced.StreamDelay.Duration="Trvanie" Basic.Settings.Advanced.StreamDelay.Preserve="Zachovať bod prerušenia (zväčšiť oneskorenie) pri znovupripojení" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Odhadované využitie pamäte: %1 MB" Basic.Settings.Advanced.Network="Sieť" @@ -755,9 +767,9 @@ Basic.Settings.Advanced.AutoRemux.MP4="(nahrať ako mkv)" Basic.AdvAudio="Pokročilé nastavenia zvuku" Basic.AdvAudio.Name="Názov" Basic.AdvAudio.Volume="Hlasitosť" -Basic.AdvAudio.Mono="Previesť na Mono" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Vyváženie" -Basic.AdvAudio.SyncOffset="Oneskorenie synchronizácie (ms)" +Basic.AdvAudio.SyncOffset="Oneskorenie synchronizácie" Basic.AdvAudio.Monitoring="Monitorovanie zvuku" Basic.AdvAudio.Monitoring.None="Vypnuté monitorovanie" Basic.AdvAudio.Monitoring.MonitorOnly="Iba monitorovanie (žiaden výstup)" @@ -823,6 +835,7 @@ SceneItemHide="Skry '%1'" OutputWarnings.NoTracksSelected="Musíte vybrať aspoň jednu zvukovú stopu" OutputWarnings.MultiTrackRecording="Varovanie: Niektoré formáty (ako FLV) nepodporujú nahrávanie viacerých stôp" OutputWarnings.MP4Recording="Upozornenie: Nahrávky uložené v MP4/MOV nebude možné obnoviť, ak súbor nebude korektne ukončený (napr. po BSOD, výpadku napájania atp.). Ak chcete nahrávať viacero zvukových stôp, skúste použiť MKV a po dokončení súbor previesť do MP4/MOV (Súbor -> Previesť nahrávky)" +OutputWarnings.CannotPause="Upozornenie: Nahrávanie nemôže byť pozastavené, ak je kvalita nahrávania nastavená na \"Rovnaké ako pre vysielanie\"" FinalScene.Title="Odstrániť scénu" FinalScene.Text="Musí existovať aspoň jedna scéna." diff --git a/UI/data/locale/sl-SI.ini b/UI/data/locale/sl-SI.ini index ce0ee11..6b98e42 100644 --- a/UI/data/locale/sl-SI.ini +++ b/UI/data/locale/sl-SI.ini @@ -1,9 +1,9 @@ -Language="slovenščina" +Language="Slovenščina" Region="Slovenija" OK="V redu" -Apply="Potrdi" +Apply="Uporabi" Cancel="Prekliči" Close="Zapri" Save="Shrani" @@ -18,26 +18,26 @@ Interact="Interaktivno" Filters="Filtri" Properties="Lastnosti" MoveUp="Premakni gor" -MoveDown="Premakni Dol" +MoveDown="Premakni dol" Settings="Nastavitve" Display="Zaslon" Name="Ime" Exit="Izhod" -Mixer="Mešalnik" +Mixer="Mešalec zvoka" Browse="Prebrskaj" Mono="Mono" Stereo="Stereo" DroppedFrames="Izpuščene sličice %1 (%2 %)" -StudioProgramProjector="Celozaslonski predogled (Program)" -PreviewProjector="Celozaslonski predogled (Predogled)" -SceneProjector="Celozaslonski predogled (Scena)" -SourceProjector="Celozaslonski predogled (Vir)" -StudioProgramWindow="Predogled v oknu (Program)" -PreviewWindow="Predogled v oknu (Predogled)" -SceneWindow="Predogled v oknu (Scena)" -SourceWindow="Predogled v oknu (Vir)" -MultiviewProjector="Večdelni pogled (Celozaslonsko)" -MultiviewWindowed="Večdelni pogled (V oknu)" +StudioProgramProjector="Celozaslonski projektor (program)" +PreviewProjector="Celozaslonski projektor (predogled)" +SceneProjector="Celozaslonski projektor (prizor)" +SourceProjector="Celozaslonski projektor (vir)" +StudioProgramWindow="Projektor v oknu (program)" +PreviewWindow="Projektor v oknu (predogled)" +SceneWindow="Projektor v oknu (prizor)" +SourceWindow="Projektor v oknu (vir)" +MultiviewProjector="Več pogledov (celozaslonsko)" +MultiviewWindowed="Več pogledov (v oknu)" Clear="Počisti" Revert="Povrni" Show="Prikaži" @@ -49,7 +49,7 @@ Duplicate="Podvoji" Enable="Omogoči" DisableOSXVSync="Onemogoči OSX V-Sync" ResetOSXVSyncOnExit="Ponastavi OSX V-Sync ob izhodu" -HighResourceUsage="Preobremenjeno kodiranje! Zmanjšajte video nastavitve ali uporabite hitrejše kodirne prednastavitve." +HighResourceUsage="Kodiranje je preobremenjeno! Razmislite o znižanju nastavitev slike ali uporabi prednastavitve s hitrejšim kodiranjem." Transition="Prehod" QuickTransitions="Hitri prehodi" Left="Levo" @@ -57,39 +57,67 @@ Right="Desno" Top="Zgoraj" Bottom="Spodaj" Reset="Ponastavi" -Hours="Ure" -Minutes="Minute" -Seconds="Sekunde" +Hours="urah" +Minutes="minutah" +Seconds="sekundah" Deprecated="Zastarelo" -ReplayBuffer="Ponovitev medpomnilnika" +ReplayBuffer="Medpomn. za pon. predv." Import="Uvozi" Export="Izvozi" Copy="Kopiraj" Paste="Prilepi" -PasteReference="Prilepi (Referenca)" -PasteDuplicate="Prilepi (Dvojnika)" -RemuxRecordings="Nadaljuj snemanje" +PasteReference="Prilepi (referenco)" +PasteDuplicate="Prilepi (dvojnika)" +RemuxRecordings="Ponovno zvij posnetke" Next="Naprej" Back="Nazaj" Defaults="Privzeto" -HideMixer="Skrij v mešalnik" -TransitionOverride="Vsili prehod" -None="Nič" +HideMixer="Skrij v mešalniku" +TransitionOverride="Preglasi prehod" +None="Brez" StudioMode.Preview="Predogled" StudioMode.Program="Program" -ShowInMultiview="Pokaži v večdelnem pogledu" +ShowInMultiview="Prikaži v več pogledih" VerticalLayout="Navpična razporeditev" Group="Skupina" +DoNotShowAgain="Ne prikaži ponovno" +Default="(privzeto)" +Calculating="Izračunavanje …" -AlreadyRunning.Title="OBS že obratuje" -AlreadyRunning.Text="OBS je že v izvajanju! Razen če ste imeli namen zagnati dve aplikaciji naenkrat, zaustavite vse OBS aplikacije v teku, tudi v sistemski vrstici." +AlreadyRunning.Title="OBS se že izvaja" +AlreadyRunning.Text="OBS se že izvaja! Razen če ste imeli namen zagnati več primerkov, pred zagonom novega primerka OBS-a zaustavite vse obstoječe. Če imate OBS nastavljen, da se skrči v sistemsko vrstico, preverite, če se tam še izvaja." AlreadyRunning.LaunchAnyway="Vseeno zaženi" +DockCloseWarning.Title="Zapiranje sidrnega okna" +DockCloseWarning.Text="Pravkar ste zaprli sidrno okno. Če bi ga radi zopet prikazali, v menijski vrstici uporabite meni Pogled → Sidrišča." +ExtraBrowsers="Brskalnikova sidrišča po meri …" +ExtraBrowsers.Info="Dodajte sidrišča tako, da jim dodate ime in URL, in nato kliknite Uporabi ali Zapri, da jih odprete. Sidrišča lahko dodate ali odstranite kadarkoli." +ExtraBrowsers.DockName="Ime sidrišča" -Copy.Filters="Kopiraj Filtre" -Paste.Filters="Prilepi Filtre" +Auth.Authing.Title="Overjanje …" +Auth.Authing.Text="Overjanje preko storitve %1. Prosimo, počakajte …" +Auth.AuthFailure.Title="Neuspešna prijava" +Auth.AuthFailure.Text="Overitev s/z %1 je spodletela:\n\n%2: %3" +Auth.InvalidScope.Title="Potrebna je overitev" +Auth.InvalidScope.Text="Overitvene zahteve za %1 so se spremenile. Nekatere značilnosti morda ne bodo na voljo." +Auth.LoadingChannel.Title="Nalaganje informacij o kanalu …" +Auth.LoadingChannel.Text="Nalaganje informacij o kanalu za %1. Prosimo, počakajte …" +Auth.ChannelFailure.Title="Nalaganje kanala neuspešno" +Auth.ChannelFailure.Text="Nalaganje informacij o kanalu za %1 je spodletelo\n\n%2: %3" +Auth.Chat="Klepet" +Auth.StreamInfo="Informacije o pretoku" +TwitchAuth.Stats="Statistika Twitcha" +TwitchAuth.Feed="Vir dejavnosti na Twitchu" +TwitchAuth.TwoFactorFail.Title="Ni bilo mogoče poizvedeti za ključ pretoka" +TwitchAuth.TwoFactorFail.Text="OBS se ni mogel povezati z računom Twitch. Prepričajte se, da je v vaših varnostnih nastavitvah Twitcha nastavljeno dvostopenjsko overjanje, ker je to zahtevano za pretakanje." +RestreamAuth.Channels="Kanali Restream" +Copy.Filters="Kopiraj filtre" +Paste.Filters="Prilepi filtre" + +BrowserPanelInit.Title="Zaganjanje brskalnika …" +BrowserPanelInit.Text="Zaganjanje brskalnika, počakajte …" BandwidthTest.Region="Območje" BandwidthTest.Region.US="Združene države Amerike" @@ -97,41 +125,113 @@ BandwidthTest.Region.EU="Evropa" BandwidthTest.Region.Asia="Azija" BandwidthTest.Region.Other="Drugo" -Basic.FirstStartup.RunWizard="Želite zagnati čarovnika za samodejno konfiguracijo? Svoje nastavitve lahko tudi spremenite tako, da kliknete gumb Nastavitve v glavnem oknu." +Basic.FirstStartup.RunWizard="Želite zagnati čarovnika za samodejno nastavitev? Svoje nastavitve lahko tudi spremenite tako, da kliknete gumb Nastavitve v glavnem oknu." +Basic.FirstStartup.RunWizard.NoClicked="Če si premislite, lahko iz menija Orodja kadarkoli znova zaženete čarovnika za samodejno nastavitev." +Basic.AutoConfig="Čarovnik za samodejno nastavitev" +Basic.AutoConfig.ApplySettings="Uporabi nastavitve" +Basic.AutoConfig.StartPage="Informacije o uporabi" +Basic.AutoConfig.StartPage.SubTitle="Navedite, za kaj želite program uporabljati" +Basic.AutoConfig.StartPage.PrioritizeStreaming="Optimiziraj za pretakanje - snemanje je drugotnega pomena" +Basic.AutoConfig.StartPage.PrioritizeRecording="Optimiziraj samo za snemanje - ne bom pretakal" +Basic.AutoConfig.VideoPage="Nastavitve slike" +Basic.AutoConfig.VideoPage.SubTitle="Navedite želene nastavitve slike" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Uporabi trenutno (%1x%2)" +Basic.AutoConfig.VideoPage.BaseResolution.Display="Zaslon %1 (%2x%3)" +Basic.AutoConfig.VideoPage.FPS.UseCurrent="Uporabi trenutno (%1)" +Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 ali 30, vendar uporabi raje 60, če je možno" +Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 ali 30, vendar uporabi raje višjo ločljivost" +Basic.AutoConfig.VideoPage.CanvasExplanation="Opomba: ločljivost platna (osnovna ločljivost) ni nujno enaka ločljivosti, s katero boste pretakali ali snemali. Dejanska ločljivost pretakanja/snemanja je lahko nižja od ločljivosti platna, da se zmanjša poraba virov ali bitna hitrost." +Basic.AutoConfig.StreamPage="Podatki o pretakanju" +Basic.AutoConfig.StreamPage.SubTitle="Vnesite podatke o pretakanju" +Basic.AutoConfig.StreamPage.ConnectAccount="Poveži račun (priporočljivo)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Odklopi račun" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Odklopi račun?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Ta sprememba bo začela veljati takoj. Ali res želite odklopiti račun?" +Basic.AutoConfig.StreamPage.UseStreamKey="Uporabi ključ pretoka" +Basic.AutoConfig.StreamPage.Service="Storitev" +Basic.AutoConfig.StreamPage.Service.ShowAll="Prikaži vse …" +Basic.AutoConfig.StreamPage.Service.Custom="Po meri …" +Basic.AutoConfig.StreamPage.Server="Strežnik" +Basic.AutoConfig.StreamPage.StreamKey="Ključ pretoka" +Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(povezava)" +Basic.AutoConfig.StreamPage.PerformBandwidthTest="Oceni bitno hitrost s preizkusom pasovne širine (lahko traja nekaj minut)" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Daj prednost strojnemu kodiranju" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Strojno kodiranje večinoma odpravi uporabo CPE-ja, vendar pa za isto raven kakovosti lahko zahteva večjo bitno hitrost." +Basic.AutoConfig.StreamPage.StreamWarning.Title="Opozorilo o pretakanju" +Basic.AutoConfig.StreamPage.StreamWarning.Text="Preizkus pasovne širine bo pretakal naključne slikovne podatke brez zvoka v vaš kanal. Če je možno, je priporočljivo začasno izklopiti shranjevanje videoposnetkov pretokov in pretok nastaviti na zaseben, dokler se preizkus ne konča. Nadaljuj?" +Basic.AutoConfig.TestPage="Končni rezultat" +Basic.AutoConfig.TestPage.SubTitle.Testing="Program trenutno izvaja množico preizkusov, da lahko oceni, katere nastavitve so najprimernejše" +Basic.AutoConfig.TestPage.SubTitle.Complete="Preizkušanje je končano" +Basic.AutoConfig.TestPage.TestingBandwidth="Izvajanje preizkusa pasovne širine. To lahko traja nekaj minut …" +Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Povezovanje na: %1 …" +Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Povezava s strežniki je spodletela. Preverite internetno povezavo in poizkusite znova." +Basic.AutoConfig.TestPage.TestingBandwidth.Server="Preizkušanje pasovne širine za: " +Basic.AutoConfig.TestPage.TestingStreamEncoder="Preizkušanje pretočnega kodirnika. To lahko traja nekaj minut …" +Basic.AutoConfig.TestPage.TestingRecordingEncoder="Preizkušanje snemalnega kodirnika. To lahko traja nekaj minut …" +Basic.AutoConfig.TestPage.TestingRes="Preizkušanje ločljivosti. To lahko traja nekaj minut …" +Basic.AutoConfig.TestPage.TestingRes.Fail="Zagon kodirnika je spodletel" +Basic.AutoConfig.TestPage.TestingRes.Resolution="Preizkušanje %1x%2 %3 sl./s …" +Basic.AutoConfig.TestPage.Result.StreamingEncoder="Pretočni kodirnik" +Basic.AutoConfig.TestPage.Result.RecordingEncoder="Snemalni kodirnik" +Basic.AutoConfig.TestPage.Result.Header="Program je ocenil, da so te nastavitve najprimernejše za vas:" +Basic.AutoConfig.TestPage.Result.Footer="Za uporabo teh nastavitev kliknite 'Uporabi nastavitve'. Za ponovno nastavitev čarovnika in vnovičen poizkus kliknite 'Nazaj'. Za ročno nastavitev kliknite 'Prekliči' in odprite nastavitve." -Basic.Stats.MemoryUsage="Poraba Pomnilnika" -Basic.Stats.AverageTimeToRender="Povprečen čas za izdelavo slike" -Basic.Stats.SkippedFrames="Preskočene slike zaradi kodirnega zastoja" -Basic.Stats.MissedFrames="Izgubljene slike zaradi kodirnega zastoja" +Basic.Stats="Statistika" +Basic.Stats.CPUUsage="Poraba CPE-ja" +Basic.Stats.HDDSpaceAvailable="Razpoložljiv prostor na disku" +Basic.Stats.MemoryUsage="Poraba pomnilnika" +Basic.Stats.AverageTimeToRender="Povprečen čas za izris sličice" +Basic.Stats.SkippedFrames="Preskočene sličice zaradi zakasnitve kodiranja" +Basic.Stats.MissedFrames="Zgrešene sličice zaradi zakasnitve izrisovanja" Basic.Stats.Output.Stream="Pretok" Basic.Stats.Output.Recording="Snemanje" Basic.Stats.Status="Stanje" Basic.Stats.Status.Recording="Snemanje" Basic.Stats.Status.Live="V ŽIVO" Basic.Stats.Status.Reconnecting="Ponovno vzpostavljanje povezave" -Basic.Stats.Status.Inactive="Neaktiven" +Basic.Stats.Status.Inactive="Nedejavno" Basic.Stats.DroppedFrames="Izpuščanje sličic (omrežje)" -Basic.Stats.MegabytesSent="Skupni podatkovni izhod" +Basic.Stats.MegabytesSent="Skupni izhodni podatki" Basic.Stats.Bitrate="Bitna hitrost" +Basic.Stats.DiskFullIn="Disk bo poln v (pribl.)" +ResetUIWarning.Title="Ali res želite ponastaviti uporabniški vmesnik?" +ResetUIWarning.Text="Ponastavitev uporabniškega vmesnika bo skrila dodatna sidrišča. Če jih želite prikazati, lahko to storite v meniju 'Pogled'.\n\nAli res želite ponastaviti uporabniški vmesnik?" -Updater.Title="Na Voljo So Nove Posodobitve" -Updater.Text="Nova Posodobitev Je Na Voljo:" +Updater.Title="Na voljo so nove posodobitve" +Updater.Text="Na voljo je nova posodobitev:" Updater.UpdateNow="Posodobi zdaj" Updater.RemindMeLater="Opomni me kasneje" Updater.Skip="Preskoči različico" -Updater.Running.Title="Program je trenutno aktiven" -Updater.Running.Text="Izhodi so trenutno v uporabi, prosimo ugasnite izhode pred posodabljanjem" +Updater.Running.Title="Program je trenutno dejaven" +Updater.Running.Text="Izhodi so trenutno v uporabi. Prosimo, da pred poizkusom posodobitve izklopite dejavne izhode" Updater.NoUpdatesAvailable.Title="Na voljo ni nobenih posodobitev" Updater.NoUpdatesAvailable.Text="Na voljo ni novih posodobitev" -Updater.FailedToLaunch="Zagon posodobitve je spodletel" -Updater.GameCaptureActive.Title="Zajem Igre aktiven" +Updater.FailedToLaunch="Zagon posodobilnika je spodletel" +Updater.GameCaptureActive.Title="Zajemanje igre je dejavno" Updater.GameCaptureActive.Text="Knjižnica za zajem Igre je trenutno v uporabi. Prosimo zaprite vse programe, ki so bili snemani (ali ponovno zaženite Windows) in poskusite ponovno." +QuickTransitions.SwapScenes="Zamenjaj predogled/izhodne prizore po prehodu" +QuickTransitions.SwapScenesTT="Zamenja predogled in izhodne prizore po prehodu (če izhodni izvirni prizor še obstaja).\nTo ne bo razveljavilo morebitnih sprememb izhodnega izvirnega prizora." +QuickTransitions.DuplicateScene="Podvoji prizor" +QuickTransitions.DuplicateSceneTT="Med urejanjem istega prizora omogoča urejanje preoblike/vidnosti virov brez spreminjanja izhoda.\nZa urejanje lastnosti virov brez spreminjanja izhoda omogočite 'Podvoji vire'.\nSprememba te vrednosti bo ponastavila trenutni izhodni prizor (če še obstaja)." +QuickTransitions.EditProperties="Podvoji vire" +QuickTransitions.EditPropertiesTT="Med urejanjem istega prizora omogoča urejanje lastnosti virov brez spreminjanja izhoda.\nTo lahko uporabite samo, če je 'Podvoji prizor' omogočeno.\nDoločeni viri (kot je zajem ali vir predstavnosti) tega ne podpirajo in jih ni mogoče ločeno urejati.\nSprememba te vrednosti bo ponastavila izhodni prizor (če še obstaja).\n\nOpozorilo: ker bodo viri podvojeni, lahko to zahteva dodatne sistemske ali slikovne vire." +QuickTransitions.HotkeyName="Hiter prehod: %1" +Basic.AddTransition="Dodaj nastavljiv prehod" +Basic.RemoveTransition="Odstrani nastavljiv prehod" +Basic.TransitionProperties="Lastnosti prehoda" +Basic.SceneTransitions="Prehodi prizorov" +Basic.TransitionDuration="Trajanje" +Basic.TogglePreviewProgramMode="Studijski način" +TransitionNameDlg.Text="Vnesite ime prehoda" +TransitionNameDlg.Title="Ime prehoda" +TitleBar.Profile="Profil" +TitleBar.Scenes="Prizori" NameExists.Title="Ime že obstaja" NameExists.Text="Ime je že v uporabi." @@ -139,211 +239,640 @@ NameExists.Text="Ime je že v uporabi." NoNameEntered.Title="Prosim vnesite veljavno ime" NoNameEntered.Text="Praznega imena ne morete uporabiti." +ConfirmStart.Title="Začni pretakati?" +ConfirmStart.Text="Ali res da želite začeti pretakati?" +ConfirmStop.Title="Prenehaj pretakati?" +ConfirmStop.Text="Ali res da želite prenehati pretakati?" +ConfirmStopRecord.Title="Prenehaj snemati?" +ConfirmStopRecord.Text="Ali res želite prenehati snemati?" + +ConfirmBWTest.Title="Zaženi preizkus pasovne širine?" +ConfirmBWTest.Text="OBS imate nastavljen v načinu preizkusa pasovne širine. Ta način omogoča preizkušanje omrežja brez pretakanja v živo. Ko končate s preizkusom, ga boste morali onemogočiti, da si bodo gledalci lahko ogledali vaš pretok.\n\nŽelite nadaljevati?" ConfirmExit.Title="Zapusti OBS?" +ConfirmExit.Text="OBS je trenutno dejaven. Vsi pretoki/snemanja bodo ustavljeni. Ali res želite končati?" ConfirmRemove.Title="Potrdite odstranitev" -ConfirmRemove.Text="Ali ste prepričani, da želite odstraniti '$ 1'?" +ConfirmRemove.Text="Ali res želite odstraniti '$1'?" +ConfirmRemove.TextMultiple="Ali res želite odstraniti %1 predmetov?" +Output.StartStreamFailed="Zagon pretakanja je spodletel" +Output.StartRecordingFailed="Zagon snemanja je spodletel" +Output.StartReplayFailed="Zagon medpomnilnika za ponovno predvajanje je spodletel" +Output.StartFailedGeneric="Zagon izhoda je spodletel. Za podrobnosti preverite dnevnik.\n\nOpomba: če uporabljate kodirnik NVENC ali AMD, se prepričajte, da so vaši grafični gonilniki posodobljeni." +Output.ReplayBuffer.PauseWarning.Title="Ponovnih predvajanj ni mogoče shraniti med premorom" +Output.ReplayBuffer.PauseWarning.Text="Opozorilo: ponovnih predvajanj ni mogoče shraniti, ko je snemanje v premoru." Output.ConnectFail.Title="Povezava ni uspela" Output.ConnectFail.BadPath="Neveljavna pot ali URL povezava. Prosimo, preverite vaše nastavitve za potrditev, da so veljavne." -Output.ConnectFail.ConnectFailed="Ni uspelo povezati s strežnikom" -Output.ConnectFail.Error="Med poskusom povezave s strežnikom je prišlo do nepričakovane napake. Več informacij v log datoteko." -Output.ConnectFail.Disconnected="Odklopiti od strežnika." +Output.ConnectFail.ConnectFailed="Povezava s strežnikom je spodletela" +Output.ConnectFail.InvalidStream="Dostop do navedenega kanala ali ključa pretoka ni mogoč. Preverite ključ pretoka. Če je pravilen, so težave lahko pri povezovanju na strežnik." +Output.ConnectFail.Error="Med poizkusom povezave s strežnikom je prišlo do nepričakovane napake. Več informacij je v dnevniški datoteki." +Output.ConnectFail.Disconnected="Povezava s strežnikom je prekinjena." +Output.StreamEncodeError.Title="Napaka pri kodiranju" +Output.StreamEncodeError.Msg="Med pretakanjem se je pojavila napaka kodirnika." +Output.RecordFail.Title="Zagon snemanja je spodletel" +Output.RecordFail.Unsupported="Izhodna oblika bodisi ni podprta bodisi ne podpira več kot ene zvočne sledi. Preverite nastavitve in poizkusite znova." +Output.RecordNoSpace.Title="Premalo prostora na disku" +Output.RecordNoSpace.Msg="Za nadaljevanje snemanja na disku ni dovolj prostora." +Output.RecordError.Title="Napaka pri snemanju" +Output.RecordError.Msg="Med snemanjem se je pojavila nedoločena napaka." +Output.RecordError.EncodeErrorMsg="Med snemanjem se je pojavila napaka kodirnika." +Output.ReplayBuffer.NoHotkey.Title="Hitra tipka ni nastavljena!" +Output.ReplayBuffer.NoHotkey.Msg="Hitra tipka za shranjevanje za medpomnilnik ponovnega predvajanja ni nastavljena. Nastavite hitro tipko \"Shrani\" za uporabo pri shranjevanju posnetkov ponovnega predvajanja." Output.BadPath.Title="Nepravilna pot do datoteke" -Output.BadPath.Text="Pot izhodne konfiguracije ni veljavna. Prosimo, preverite vaše nastavitve, da je določena veljavna pot datoteke." +Output.BadPath.Text="Nastavljena pot do datoteke ni veljavna. Preverite, da je nastavljena veljavna pot do datoteke." -LogReturnDialog="Dnevnik uspešno naložen" +LogReturnDialog="Dnevnik je bil uspešno poslan" LogReturnDialog.CopyURL="Kopiraj URL" -LogReturnDialog.ErrorUploadingLog="Napaka pri nalaganju dnevnika" +LogReturnDialog.ErrorUploadingLog="Napaka pri pošiljanju dnevniške datoteke" +Remux.SourceFile="Posnetek OBS" +Remux.TargetFile="Ciljna datoteka" +Remux.Remux="Pon. zvij" +Remux.Stop="Ustavi pon. zvijanje" +Remux.ClearFinished="Počisti dokončane predmete" +Remux.ClearAll="Počisti vse predmete" +Remux.OBSRecording="Posnetek OBS" +Remux.FinishedTitle="Ponovno zvijanje je končano" +Remux.Finished="Posnetek je bil ponovno zvit" +Remux.FinishedError="Posnetek je bil ponovno zvit, vendar je datoteka lahko nedokončana" +Remux.SelectRecording="Izberite posnetek OBS …" +Remux.SelectTarget="Izberite ciljno datoteko …" +Remux.FileExistsTitle="Ciljne datoteke že obstajajo" +Remux.FileExists="Naslednje ciljne datoteke že obstajajo. Ali jih želite zamenjati?" +Remux.ExitUnfinishedTitle="Ponovno zvijanje je v teku" +Remux.ExitUnfinished="Ponovno zvijanje še ni končano. Takojšnja ustavitev lahko povzroči neuporabnost ciljne datoteke.\nAli res želite ustaviti ponovno zvijanje?" +Remux.HelpText="Za ponovno zvijanje v to okno spustite datoteke ali izberite prazno celico \"Posnetek OBS\", da poiščete datoteko." UpdateAvailable="Nova posodobitev je na voljo" -UpdateAvailable.Text="Verzija %1.%2.%3 je sedaj na voljo. Klikni tukaj za prenos" +UpdateAvailable.Text="Različica %1.%2.%3 je sedaj na voljo. Kliknite tukaj za prenos" -Basic.DesktopDevice1="Namizni Zvok" -Basic.DesktopDevice2="Namizni Zvok 2" -Basic.AuxDevice1="Mic/Aux" -Basic.AuxDevice2="Mic/Aux 2" -Basic.AuxDevice3="Mic/Aux 3" -Basic.AuxDevice4="Mic/Aux 4" +Basic.DesktopDevice1="Namizni zvok" +Basic.DesktopDevice2="Namizni zvok 2" +Basic.AuxDevice1="Mikrofon/Pomožni vhod" +Basic.AuxDevice2="Mikrofon/Pomožni vhod 2" +Basic.AuxDevice3="Mikrofon/Pomožni vhod 3" +Basic.AuxDevice4="Mikrofon/Pomožni vhod 4" -Basic.Scene="Scena" +Basic.Scene="Prizor" Basic.DisplayCapture="Zajemanje zaslona" +Basic.Main.PreviewConextMenu.Enable="Omogoči predogled" + +Basic.Main.Preview.Disable="Onemogoči predogled" + +ScaleFiltering="Filtriranje sprem. velikosti" +ScaleFiltering.Point="Točkovno" +ScaleFiltering.Bilinear="Dvovrstno" +ScaleFiltering.Bicubic="Dvoprostor." +ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Območje" + +Deinterlacing="Razpletanje" +Deinterlacing.Discard="Opusti" +Deinterlacing.Retro="Povratno" +Deinterlacing.Blend="Premešaj" +Deinterlacing.Blend2x="Premešaj 2x" +Deinterlacing.Linear="Premočrtno" +Deinterlacing.Linear2x="Premočrtno 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Najprej zgornje polje" +Deinterlacing.BottomFieldFirst="Najprej spodnje polje" + +VolControl.SliderUnmuted="Drsnik glasnosti za '%1': %2" +VolControl.SliderMuted="Drsnik glasnosti za '%1': %2 (trenutno je utišano)" +VolControl.Mute="Utišaj '%1'" +VolControl.Properties="Lastnosti za '%1'" + +Basic.Main.AddSceneDlg.Title="Dodaj prizor" +Basic.Main.AddSceneDlg.Text="Vnesite ime prizora" + +Basic.Main.DefaultSceneName.Text="%1. prizor" + +Basic.Main.AddSceneCollection.Title="Dodaj zbirko prizorov" +Basic.Main.AddSceneCollection.Text="Vnesite ime zbirke prizorov" + +Basic.Main.RenameSceneCollection.Title="Preimenuj zbirko prizorov" + +AddProfile.Title="Dodaj profil" +AddProfile.Text="Vnesite ime profila" + +RenameProfile.Title="Preimenuj profil" + +Basic.Main.MixerRename.Title="Preimenuj zvočni vir" +Basic.Main.MixerRename.Text="Vnesite ime zvočnega vira" +Basic.Main.PreviewDisabled="Predogled je trenutno onemogočen" +Basic.SourceSelect="Ustvarite/izberite vir" +Basic.SourceSelect.CreateNew="Ustvari novega" +Basic.SourceSelect.AddExisting="Dodaj obstoječega" +Basic.SourceSelect.AddVisible="Prikaži vir" - -Basic.Main.AddSceneDlg.Title="Dodaj seceno" -Basic.Main.AddSceneDlg.Text="Prosimo, vnesite ime scene" - -Basic.Main.DefaultSceneName.Text="Scena %1" - - - - - - - - -Basic.SourceSelect="Ustvarite / Izberite Vir" -Basic.SourceSelect.CreateNew="Ustvari novo" -Basic.SourceSelect.AddExisting="Dodaj obstoječo" - -Basic.PropertiesWindow="Lastnosti za \"%1\"" +Basic.PropertiesWindow="Lastnosti za '%1'" +Basic.PropertiesWindow.AutoSelectFormat="%1 (samodejno izberi: %2)" Basic.PropertiesWindow.SelectColor="Izberi barvo" Basic.PropertiesWindow.SelectFont="Izberi pisavo" +Basic.PropertiesWindow.ConfirmTitle="Nastavitve so se spremenile" +Basic.PropertiesWindow.Confirm="Obstajajo neshranjene spremembe. Ali jih želite obdržati?" +Basic.PropertiesWindow.NoProperties="Lastnosti niso na voljo" +Basic.PropertiesWindow.AddFiles="Dodaj datoteke" +Basic.PropertiesWindow.AddDir="Dodaj mapo" +Basic.PropertiesWindow.AddURL="Dodaj pot/URL" +Basic.PropertiesWindow.AddEditableListDir="Dodaj mapo na '%1'" +Basic.PropertiesWindow.AddEditableListFiles="Dodaj datoteke na '%1'" +Basic.PropertiesWindow.AddEditableListEntry="Dodaj vnos na '%1'" +Basic.PropertiesWindow.EditEditableListEntry="Uredi vnos s/z '%1'" +Basic.PropertiesView.FPS.Simple="Preproste vrednosti sl./s" +Basic.PropertiesView.FPS.Rational="Racionalne vrednosti sl./s" +Basic.PropertiesView.FPS.ValidFPSRanges="Veljavni razpon sl./s:" Basic.InteractionWindow="V stiku z '%1'" +Basic.StatusBar.Reconnecting="Povezava je bila prekinjena. Ponovno povezava čez %2 sekund (%1. poizkus)" +Basic.StatusBar.AttemptingReconnect="Poizkušanje ponovne povezave … (%1. poizkus)" Basic.StatusBar.ReconnectSuccessful="Ponovna povezava uspešna" +Basic.StatusBar.Delay="Zakasnitev (%1 s)" +Basic.StatusBar.DelayStartingIn="Zakasnitev (začetek čez %1 s)" +Basic.StatusBar.DelayStoppingIn="Zakasnitev (konec čez %1 s)" +Basic.StatusBar.DelayStartingStoppingIn="Zakasnitev (začetek čez %1 s, konec čez %2 s)" +Basic.Filters="Filtri" +Basic.Filters.AsyncFilters="Zvočni/slikovni filtri" +Basic.Filters.AudioFilters="Zvočni filtri" +Basic.Filters.EffectFilters="Filtri učinkov" +Basic.Filters.Title="Filtri za '%1'" +Basic.Filters.AddFilter.Title="Ime filtra" +Basic.Filters.AddFilter.Text="Navedite ime filtra" -Basic.TransformWindow="Transformacija stvari na sceni" +Basic.TransformWindow="Preoblika predmetov v prizoru" Basic.TransformWindow.Position="Položaj" -Basic.TransformWindow.Rotation="Rotacija" +Basic.TransformWindow.Rotation="Zasuk" Basic.TransformWindow.Size="Velikost" -Basic.TransformWindow.Alignment="Pozicijski poravnava" -Basic.TransformWindow.BoundsType="Vrsta prostorskega obsega" -Basic.TransformWindow.BoundsAlignment="Postavitev v prostorskem obsegu" -Basic.TransformWindow.Bounds="Velikost prostorskega obsega" +Basic.TransformWindow.Alignment="Poravnava položaja" +Basic.TransformWindow.BoundsType="Vrsta okvirja" +Basic.TransformWindow.BoundsAlignment="Poravnava v okvirju" +Basic.TransformWindow.Bounds="Velikost okvirja" +Basic.TransformWindow.Crop="Obreži" Basic.TransformWindow.Alignment.TopLeft="Zgoraj levo" -Basic.TransformWindow.Alignment.TopCenter="Zgoraj na sredini" +Basic.TransformWindow.Alignment.TopCenter="Zgoraj na sredino" Basic.TransformWindow.Alignment.TopRight="Zgoraj desno" Basic.TransformWindow.Alignment.CenterLeft="Na sredini levo" Basic.TransformWindow.Alignment.Center="Sredina" Basic.TransformWindow.Alignment.CenterRight="Na sredini desno" Basic.TransformWindow.Alignment.BottomLeft="Spodaj levo" -Basic.TransformWindow.Alignment.BottomCenter="Spodaj na sredini" +Basic.TransformWindow.Alignment.BottomCenter="Spodaj na sredino" Basic.TransformWindow.Alignment.BottomRight="Spodaj desno" -Basic.TransformWindow.BoundsType.None="Brez mej" +Basic.TransformWindow.BoundsType.None="Neomejeno" Basic.TransformWindow.BoundsType.MaxOnly="Samo največja velikost" Basic.TransformWindow.BoundsType.ScaleInner="Prilagodi notranji meji" Basic.TransformWindow.BoundsType.ScaleOuter="Prilagodi zunanji meji" Basic.TransformWindow.BoundsType.ScaleToWidth="Prilagodi širini meje" Basic.TransformWindow.BoundsType.ScaleToHeight="Prilagodi višini meje" -Basic.TransformWindow.BoundsType.Stretch="Razpotegni do meje" +Basic.TransformWindow.BoundsType.Stretch="Raztegni do meje" Basic.Main.AddSourceHelp.Title="Ni mogoče dodati vira" -Basic.Main.AddSourceHelp.Text="Potrebujete vsaj 1 sceno, da lahko dodate vir." +Basic.Main.AddSourceHelp.Text="Potrebujete vsaj 1 prizor, da lahko dodate vir." -Basic.Main.Scenes="Scene" +Basic.Main.Scenes="Prizori" Basic.Main.Sources="Viri" -Basic.Main.Connecting="Povezovanje..." +Basic.Main.Controls="Nadzorne tipke" +Basic.Main.Connecting="Povezovanje …" Basic.Main.StartRecording="Začni snemati" -Basic.Main.StartStreaming="Začni oddajati" +Basic.Main.StartReplayBuffer="Zaženi medpomnilnik za pon. predv." +Basic.Main.StartStreaming="Začni pretakati" Basic.Main.StopRecording="Prenehaj snemati" -Basic.Main.StopStreaming="Prenehaj oddajati" +Basic.Main.PauseRecording="Premor snemanja" +Basic.Main.UnpauseRecording="Nadaljuj snemanje" +Basic.Main.StoppingRecording="Ustavljanje snemanja …" +Basic.Main.StopReplayBuffer="Ustavi medpomnilnik za pon. predv." +Basic.Main.StoppingReplayBuffer="Ustavljanje medp. za pon. predv. …" +Basic.Main.StopStreaming="Prenehaj pretakati" +Basic.Main.StoppingStreaming="Ustavljanje pretoka …" +Basic.Main.ForceStopStreaming="Prenehaj pretakati (zavrzi zakasnitev)" +Basic.Main.Group="%1. skupina" +Basic.Main.GroupItems="Združi izbrane predmete" +Basic.Main.Ungroup="Razdruži" Basic.MainMenu.File="Datoteka (&F)" Basic.MainMenu.File.Export="Izvozi (&E)" -Basic.MainMenu.File.Import="Uvoz (&I)" -Basic.MainMenu.File.ShowRecordings="Pokaži Posnetke (&R)" +Basic.MainMenu.File.Import="Uvoz&i" +Basic.MainMenu.File.ShowRecordings="P&rikaži posnetke" +Basic.MainMenu.File.Remux="Ponovno zvij posnetke (&M)" Basic.MainMenu.File.Settings="Na&stavitve" +Basic.MainMenu.File.ShowSettingsFolder="Prikaži mapo z nastavitvami" +Basic.MainMenu.File.ShowProfileFolder="Prikaži mapo s profili" +Basic.MainMenu.AlwaysOnTop="Vedno n&a vrhu" Basic.MainMenu.File.Exit="Izhod (&X)" -Basic.MainMenu.Edit="Spr&emeni" +Basic.MainMenu.Edit="Ur&edi" Basic.MainMenu.Edit.Undo="Razveljavi (&U)" Basic.MainMenu.Edit.Redo="Uveljavi (&R)" Basic.MainMenu.Edit.UndoAction="Razveljavi $1 (&U)" Basic.MainMenu.Edit.RedoAction="Uveljavi $1 (&R)" +Basic.MainMenu.Edit.LockPreview="Zak&leni predogled" +Basic.MainMenu.Edit.Scale="&Spremeni velikost predogleda" +Basic.MainMenu.Edit.Scale.Window="Prilagodi oknu" +Basic.MainMenu.Edit.Scale.Canvas="Platno (%1x%2)" +Basic.MainMenu.Edit.Scale.Output="Izhod (%1x%2)" Basic.MainMenu.Edit.Transform="Preoblikuj (&T)" -Basic.MainMenu.Edit.Transform.EditTransform="Ur&edi preoblikovanje..." -Basic.MainMenu.Edit.Transform.ResetTransform="Ponostavi p&reoblikovanje" -Basic.MainMenu.Edit.Transform.Rotate90CW="Zasukati za 90 stopinj v desno" -Basic.MainMenu.Edit.Transform.Rotate90CCW="Zasukati za 90 stopinj v levo" -Basic.MainMenu.Edit.Transform.Rotate180="Zavrti 180 stopin" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Zrcali Vodoravno (&H)" -Basic.MainMenu.Edit.Transform.FlipVertical="Zrcali Na&vpično" +Basic.MainMenu.Edit.Transform.EditTransform="Ur&edi preobliko …" +Basic.MainMenu.Edit.Transform.CopyTransform="Kopiraj preobliko" +Basic.MainMenu.Edit.Transform.PasteTransform="Prilepi preobliko" +Basic.MainMenu.Edit.Transform.ResetTransform="Ponastavi p&reobliko" +Basic.MainMenu.Edit.Transform.Rotate90CW="Zasukaj za 90 stopinj v desno" +Basic.MainMenu.Edit.Transform.Rotate90CCW="Zasukaj za 90 stopinj v levo" +Basic.MainMenu.Edit.Transform.Rotate180="Zasukaj za 180 stopinj" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Zrcali vodoravno (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="Zrcali na&vpično" Basic.MainMenu.Edit.Transform.FitToScreen="Prilagodi zaslonu (&F)" -Basic.MainMenu.Edit.Transform.StretchToScreen="Prilagodi za&slonu" -Basic.MainMenu.Edit.Transform.CenterToScreen="&Centriraj na zaslon" +Basic.MainMenu.Edit.Transform.StretchToScreen="Raztegni na veliko&st zaslona" +Basic.MainMenu.Edit.Transform.CenterToScreen="Usredini na zaslon (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="Usredini navpično" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Usredini vodoravno" Basic.MainMenu.Edit.Order="Zap&oredje" -Basic.MainMenu.Edit.Order.MoveUp="Premakni Gor (&U)" -Basic.MainMenu.Edit.Order.MoveDown="Premakni &Dol" -Basic.MainMenu.Edit.Order.MoveToTop="Premakni na Vrh (&T)" -Basic.MainMenu.Edit.Order.MoveToBottom="Premakni na Dno (&B)" +Basic.MainMenu.Edit.Order.MoveUp="Premakni gor (&U)" +Basic.MainMenu.Edit.Order.MoveDown="Premakni &dol" +Basic.MainMenu.Edit.Order.MoveToTop="Premakni na vrh (&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="Premakni na dno (&B)" +Basic.MainMenu.Edit.AdvAudio="N&apredne lastnosti zvoka" +Basic.MainMenu.View="Pogled (&V)" +Basic.MainMenu.View.Toolbars="Orodne vrs&tice" +Basic.MainMenu.View.Docks="Sidrišča" +Basic.MainMenu.View.Docks.ResetUI="Ponastavi up. vmesnik" +Basic.MainMenu.View.Docks.LockUI="Zakleni up. vmesnik" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Brskalnikova sidrišča po meri …" +Basic.MainMenu.View.Toolbars.Listboxes="Vrstice seznamov (&L)" +Basic.MainMenu.View.SceneTransitions="Prehodi prizorov (&C)" +Basic.MainMenu.View.StatusBar="Vr&stica stanja" +Basic.MainMenu.View.Fullscreen.Interface="Celozaslonski vmesnik" +Basic.MainMenu.SceneCollection="Zbirka prizorov (&S)" +Basic.MainMenu.Profile="&Profil" +Basic.MainMenu.Profile.Import="Uvozi profil" +Basic.MainMenu.Profile.Export="Izvozi profil" +Basic.MainMenu.SceneCollection.Import="Uvozi zbirko prizorov" +Basic.MainMenu.SceneCollection.Export="Izvozi zbirko prizorov" +Basic.MainMenu.Profile.Exists="Profil že obstaja" +Basic.MainMenu.SceneCollection.Exists="Zbirka prizorov že obstaja" +Basic.MainMenu.Tools="Orodja (&T)" Basic.MainMenu.Help="Pomoč (&H)" -Basic.MainMenu.Help.Logs="Dnevniki (&L)" -Basic.MainMenu.Help.Logs.ShowLogs="Pokaži Zapi&snik" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Naloži Trenutni dnevnik (&C)" -Basic.MainMenu.Help.Logs.UploadLastLog="Na&loži Zadni dnevnik" +Basic.MainMenu.Help.HelpPortal="&Portal za pomoč" +Basic.MainMenu.Help.Website="Obišči spletno mesto (&W)" +Basic.MainMenu.Help.Discord="Pridruži se strežniku &Discord" +Basic.MainMenu.Help.Logs="Dnevniške datoteke (&L)" +Basic.MainMenu.Help.Logs.ShowLogs="Prikaži dnevniške datoteke (&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Pošlji trenutno dnevniško datoteko (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Poš&lji zadnjo dnevniško datoteko" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Pokaži trenutni dne&vnik" Basic.MainMenu.Help.CheckForUpdates="Preveri za posodobitve" +Basic.MainMenu.Help.CrashLogs="Po&ročila o zrušitvi" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Prikaži poročila o zrušitvi (&S)" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Poš&lji zadnje poročilo o zrušitvi" +Basic.MainMenu.Help.About="O progr&amu" Basic.Settings.ProgramRestart="Program je treba ponovno zagnati, da se te nastavitve uveljavijo." Basic.Settings.ConfirmTitle="Potrdi spremembe" -Basic.Settings.Confirm="Imate neshranjene spremembe. Shranim spremembe?" +Basic.Settings.Confirm="Imate neshranjene spremembe. Shrani spremembe?" Basic.Settings.General="Splošno" +Basic.Settings.General.Theme="Tema" +Basic.Settings.General.Language="Jezik" +Basic.Settings.General.EnableAutoUpdates="Ob zagonu samodejno preveri za posodobitve" +Basic.Settings.General.OpenStatsOnStartup="Ob zagonu odpri pogovorno okno s statistiko" +Basic.Settings.General.WarnBeforeStartingStream="Prikaži potrditveno okno ob zagonu pretokov" +Basic.Settings.General.WarnBeforeStoppingStream="Prikaži potrditveno okno ob končanju pretokov" +Basic.Settings.General.WarnBeforeStoppingRecord="Prikaži potrditveno okno ob končanju snemanja" +Basic.Settings.General.Projectors="Projektorji" +Basic.Settings.General.HideProjectorCursor="Skrij kazalec nad projektorji" +Basic.Settings.General.ProjectorAlwaysOnTop="Projektorje prikaži vedno na vrhu" +Basic.Settings.General.Snapping="Pripenjanje virov ob poravnavi" +Basic.Settings.General.ScreenSnapping="Pripni vire na rob zaslona" +Basic.Settings.General.CenterSnapping="Pripni vire na vodoravno in navpično sredino" +Basic.Settings.General.SourceSnapping="Pripni vire na druge vire" +Basic.Settings.General.SnapDistance="Občutljivost pripenjanja" +Basic.Settings.General.RecordWhenStreaming="Samodejno snemaj med pretakanjem" +Basic.Settings.General.KeepRecordingWhenStreamStops="Obdrži posnetek, ko se pretok ustavi" +Basic.Settings.General.ReplayBufferWhileStreaming="Med pretakanjem samodejno zaženi medpomnilnik za ponovno predvajanje" +Basic.Settings.General.KeepReplayBufferStreamStops="Medpomnilnik za ponovno predvajanje naj bo še naprej dejaven, ko se pretok ustavi" +Basic.Settings.General.SysTray="Sistemska vrstica" +Basic.Settings.General.SysTrayWhenStarted="Skrči v sistemsko vrstico ob zagonu" +Basic.Settings.General.SystemTrayHideMinimize="Vedno skrči v sistemsko vrstico namesto v opravilno" +Basic.Settings.General.SaveProjectors="Shrani projektorje on izhodu" +Basic.Settings.General.Preview="Predogled" +Basic.Settings.General.OverflowHidden="Skrij prekoračitev" +Basic.Settings.General.OverflowAlwaysVisible="Prekoračitev je vedno vidna" +Basic.Settings.General.OverflowSelectionHidden="Prikaži prekoračitev, tudi ko je vir neviden" +Basic.Settings.General.SwitchOnDoubleClick="Ob dvokliku izvedi prehod na prizor" +Basic.Settings.General.StudioPortraitLayout="Omogoči pokončno/navpično razporeditev" +Basic.Settings.General.TogglePreviewProgramLabels="Prikaži oznake za predogled/program" +Basic.Settings.General.Multiview="Več pogledov" +Basic.Settings.General.Multiview.MouseSwitch="Klik preklopi med prizori" +Basic.Settings.General.Multiview.DrawSourceNames="Prikaži imena prizorov" +Basic.Settings.General.Multiview.DrawSafeAreas="Nariši varna območja (EBU R 95)" +Basic.Settings.General.MultiviewLayout="Razporeditev več pogledov" +Basic.Settings.General.MultiviewLayout.Horizontal.Top="Vodoravno zgoraj (8 prizorov)" +Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Vodoravno spodaj (8 prizorov)" +Basic.Settings.General.MultiviewLayout.Vertical.Left="Vodoravno levo (8 prizorov)" +Basic.Settings.General.MultiviewLayout.Vertical.Right="Vodoravno desno (8 prizorov)" +Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Vodoravno zgoraj (24 prizorov)" Basic.Settings.Stream="Pretok" Basic.Settings.Stream.StreamType="Vrsta pretoka" +Basic.Settings.Stream.Custom.UseAuthentication="Uporabi overitev" +Basic.Settings.Stream.Custom.Username="Uporabniško ime" +Basic.Settings.Stream.Custom.Password="Geslo" +Basic.Settings.Stream.BandwidthTestMode="Omogoči način preverjanja pasovne širine" -Basic.Settings.Output="Izhodišče" -Basic.Settings.Output.Mode="Vrsta izhodišča" -Basic.Settings.Output.VideoBitrate="Bitrate Videa" -Basic.Settings.Output.AudioBitrate="Bitrate zvoka" +Basic.Settings.Output="Izhod" +Basic.Settings.Output.Format="Oblika posnetkov" +Basic.Settings.Output.Encoder="Kodirnik" +Basic.Settings.Output.SelectDirectory="Izberite mapo za posnetke" +Basic.Settings.Output.SelectFile="Izberite datoteko posnetka" +Basic.Settings.Output.EnforceBitrate="Vsili omejitve bitne hitrosti storitve pretakanja" +Basic.Settings.Output.DynamicBitrate="Dinamično spreminjaj bitno hitrost za odpravo zastojev" +Basic.Settings.Output.DynamicBitrate.Beta="Dinamično spreminjaj bitno hitrost za odpravo zastojev (beta)" +Basic.Settings.Output.DynamicBitrate.TT="Namesto izpuščanja sličic za odpravo zastojev sproti dinamično spreminja bitno hitrost.\n\nUpoštevajte, da to lahko poveča zakasnitve pri gledalcih, če pride do nenadnega znatnega zastoja.\nKo se bitna hitrost zniža, lahko obnovitev traja nekaj minut.\n\nTrenutno podprto samo za RMTP." +Basic.Settings.Output.Mode="Način izhoda" +Basic.Settings.Output.Mode.Simple="Preprost" +Basic.Settings.Output.Mode.Adv="Napreden" +Basic.Settings.Output.Mode.FFmpeg="Izhod FFmpeg" +Basic.Settings.Output.UseReplayBuffer="Omogoči medpomnilnik za pon. predv." +Basic.Settings.Output.ReplayBuffer.SecondsMax="Najdaljši čas ponovnega predvajanja" +Basic.Settings.Output.ReplayBuffer.MegabytesMax="Največja količina pomnilnika (MB)" +Basic.Settings.Output.ReplayBuffer.Estimate="Ocenjena poraba pomnilnika: %1 MB" +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Porabe pomnilnika ni mogoče oceniti. Nastavite zgornjo omejitev porabe." +Basic.Settings.Output.ReplayBuffer.HotkeyMessage="Opomba: prepričajte se, da v odseku za hitre tipke nastavite hitro tipko za medpomnilnik ponovnega predvajanja" +Basic.Settings.Output.ReplayBuffer.Prefix="Predpona imena dat. medp. za pon. predv." +Basic.Settings.Output.ReplayBuffer.Suffix="Pripona" +Basic.Settings.Output.Simple.SavePath="Pot za snemanje" +Basic.Settings.Output.Simple.RecordingQuality="Kakovost posnetkov" +Basic.Settings.Output.Simple.RecordingQuality.Stream="Enaka kot pri pretakanju" +Basic.Settings.Output.Simple.RecordingQuality.Small="Visoka kakovost, srednja velikost datoteke" +Basic.Settings.Output.Simple.RecordingQuality.HQ="Nerazločljiva kakovost, zelo velika velikost datoteke" +Basic.Settings.Output.Simple.RecordingQuality.Lossless="Brezizgubna kakovost, izjemno velika velikost datoteke" +Basic.Settings.Output.Simple.Warn.VideoBitrate="Opozorilo: slikovna bitna hitrost pretoka bo nastavljena na %1, ki je zgornja meja trenutne storitve pretakanja. Če ste prepričani, da želite iti čez %1, omogočite napredne možnosti kodirnika in odznačite \"Vsili omejitve bitne hitrosti storitve pretakanja\"." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Opozorilo: bitna hitrost zvočnega pretoka bo nastavljena na %1, ki je zgornja meja trenutne storitve pretakanja. Če ste prepričani, da želite iti čez %1, omogočite napredne možnosti kodirnika in odznačite \"Vsili omejitve bitne hitrosti storitve pretakanja\"." +Basic.Settings.Output.Simple.Warn.CannotPause="Opozorilo: posnetkov ni mogoče začasno ustaviti, če je kakovost posnetka nastavljena na \"Enaka kot pri pretakanju\"." +Basic.Settings.Output.Simple.Warn.Encoder="Opozorilo: snemanje s programskim kodirnikom pri drugačni kakovosti kot pri pretakanju zahteva dodatno porabo CPE-ja, če pretakate in snemate istočasno." +Basic.Settings.Output.Simple.Warn.Lossless="Opozorilo: brezizgubna kakovost ustvari izjemno velike velikosti datotek! Brezizgubna kakovost lahko porabi več kot 7 GB prostora na disku na minuto pri visokih ločljivostih in hitrostih sličic. Brezizgubna kakovost ni priporočljiva za dolge posnetke, razen če imate na voljo veliko prostora na disku." +Basic.Settings.Output.Simple.Warn.Lossless.Msg="Ali res želite uporabiti brezizgubno kakovost?" +Basic.Settings.Output.Simple.Warn.Lossless.Title="Opozorilo o brezizgubni kakovosti!" +Basic.Settings.Output.Simple.Encoder.Software="Programski (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Strojni (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Strojni (AMD)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Strojni (NVENC)" +Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Programski (prednastavitev x264 s nizko porabo CPE-ja, poveča velikost datoteke)" +Basic.Settings.Output.VideoBitrate="Bitna hitrost slike" +Basic.Settings.Output.AudioBitrate="Bitna hitrost zvoka" Basic.Settings.Output.Reconnect="Samodejno ponovno poveži" -Basic.Settings.Output.RetryDelay="Premor med ponovnim poskusom (sekund)" -Basic.Settings.Output.MaxRetries="Število ponovnih poskusov" +Basic.Settings.Output.RetryDelay="Zakasn. pon. poizkusa" +Basic.Settings.Output.MaxRetries="Število ponovnih poizkusov" Basic.Settings.Output.Advanced="Omogoči napredne nastavitve kodiranja" +Basic.Settings.Output.EncoderPreset="Prednastavitev kodirnika" +Basic.Settings.Output.CustomEncoderSettings="Nastavitve po meri za kodirnik" +Basic.Settings.Output.CustomMuxerSettings="Nastavitve po meri za zvijalnik" +Basic.Settings.Output.NoSpaceFileName="Ustvari ime datoteke brez presledkov" +Basic.Settings.Output.Adv.Rescale="Spremeni velikost izhoda" +Basic.Settings.Output.Adv.AudioTrack="Zvočna sled" +Basic.Settings.Output.Adv.Streaming="Pretakanje" +Basic.Settings.Output.Adv.ApplyServiceSettings="Vsili nastavitve kodirnika storitve za pretakanje" +Basic.Settings.Output.Adv.Audio.Track1="1. sled" +Basic.Settings.Output.Adv.Audio.Track2="2. sled" +Basic.Settings.Output.Adv.Audio.Track3="3. sled" +Basic.Settings.Output.Adv.Audio.Track4="4. sled" +Basic.Settings.Output.Adv.Audio.Track5="5. sled" +Basic.Settings.Output.Adv.Audio.Track6="6. sled" +Basic.Settings.Output.Adv.Recording="Snemanje" +Basic.Settings.Output.Adv.Recording.Type="Vrsta" +Basic.Settings.Output.Adv.Recording.Type.Standard="Običajno" +Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Izhod po meri (FFmpeg)" +Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(uporabi pretočni kodirnik)" +Basic.Settings.Output.Adv.Recording.Filename="Oblika imena datoteke" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Prepiši, če datoteka že obstaja" +Basic.Settings.Output.Adv.FFmpeg.Type="Vrsta izhoda FFmpeg" +Basic.Settings.Output.Adv.FFmpeg.Type.URL="Odvajaj v URL" +Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Odvajaj v datoteko" +Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Pogoste oblike posnetkov" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Vse datoteke" +Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Pot do datoteke ali URL" +Basic.Settings.Output.Adv.FFmpeg.Format="Oblika vsebnika" +Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Zvok" +Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Slika" +Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Privzeta oblika" +Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Opis oblike vsebnika" +Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Zvočni/slikovni kodek se ugane iz poti datoteke ali URL-ja" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Privzeti kodirnik" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Onemogoči kodirnik" +Basic.Settings.Output.Adv.FFmpeg.VEncoder="Slikovni kodirnik" +Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Nastavitve slikovnega kodirnika (če obstaja)" +Basic.Settings.Output.Adv.FFmpeg.AEncoder="Zvočni kodirnik" +Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Nastavitve zvočnega kodirnika (če obstaja)" +Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Nastavitve zvijalnika (če obstaja)" +Basic.Settings.Output.Adv.FFmpeg.GOPSize="Razmik med ključnimi sličicami (sličic)" +Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Prikaže vse kodeke (tudi če so mogoče nezdružljivi)" +FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" +FilenameFormatting.TT="%CCYY leto - štiri številke\n%YY zadnji dve številki leta (00-99)\n%MM mesec kot desetiško število (01-12)\n%DD dan v mesecu z dvema številkama (01-31)\n%hh ura v 24-urni obliki (00-23)\n%mm minute (00-59)\n%ss sekunde (00-61)\n%% znak %\n%a skrajšano ime dneva v tednu\n%A ime dneva v tednu\n%b skrajšano ime meseca\n%B polno ime meseca\n%d dan v mesecu z dvema številkama (01-31)\n%H ura v 24-urni obliki (00-23)\n%I ura v 12-urni obliki (01-12)\n%m mesec kot desetiško število (01-12)\n%M minute (00-59)\n%p označbi AM ali PM\n%S sekunde (00-61)\n%y zadnji dve številki leta (00-99)\n%Y leto\n%z zamik ISO 8601 od UTC-ja v časovnem pasu\n%Z ime ali okrajšava časovnega pasu\n" -Basic.Settings.Video="Video" +Basic.Settings.Video="Slika" Basic.Settings.Video.Adapter="Grafična kartica" +Basic.Settings.Video.BaseResolution="Osnovna ločljivost" +Basic.Settings.Video.ScaledResolution="Izhodna ločljivost" Basic.Settings.Video.DownscaleFilter="Pomanjševalni filter" Basic.Settings.Video.DisableAeroWindows="Onemogoči Aero (samo Windows)" -Basic.Settings.Video.FPS="FPS" -Basic.Settings.Video.FPSCommon="Pogoste FPS vrednosti" -Basic.Settings.Video.FPSInteger="Cela števila FPS" -Basic.Settings.Video.FPSFraction="Decimalne FPS vrednosti" +Basic.Settings.Video.FPS="sl./s" +Basic.Settings.Video.FPSCommon="Pogoste vrednosti sl./s" +Basic.Settings.Video.FPSInteger="Cela števila sl./s" +Basic.Settings.Video.FPSFraction="Decimalne vrednosti sl./s" Basic.Settings.Video.Numerator="Števec" Basic.Settings.Video.Denominator="Imenovalec" -Basic.Settings.Video.Renderer="Rendanje" -Basic.Settings.Video.InvalidResolution="Neveljavna vrednost ločljivost. Biti mora [širina] x [višina] (npr. 1920x1080)" -Basic.Settings.Video.CurrentlyActive="Video izhod je trenutno aktiven. Prosimo, izklopite kakšen koli izhod za spreminjanje nastavitev." +Basic.Settings.Video.Renderer="Izrisovalnik" +Basic.Settings.Video.InvalidResolution="Neveljavna vrednost ločljivosti. Biti mora [širina] x [višina] (npr. 1920 x 1080)" +Basic.Settings.Video.CurrentlyActive="Slikovni izhod je trenutno dejaven. Prosimo, izklopite vse izhode za spreminjanje nastavitev slike." +Basic.Settings.Video.DisableAero="Onemogoči Aero" +Basic.Settings.Video.DownscaleFilter.Bilinear="Dvovrsten (najhitrejši, vendar ob znižanju ločljivosti povzroči megleno sliko)" +Basic.Settings.Video.DownscaleFilter.Bicubic="Dvoprostorninski (izostreno spreminjanje ločljivosti, 16 vzorcev)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (izostreno spreminjanje ločljivosti, 36 vzorcev)" +Basic.Settings.Video.DownscaleFilter.Area="Območje (utežena vsota, 4/6/9 vzorcev)" Basic.Settings.Audio="Zvok" -Basic.Settings.Audio.SampleRate="Sample Rate" +Basic.Settings.Audio.SampleRate="Hitrost vzorčenja" Basic.Settings.Audio.Channels="Kanali" +Basic.Settings.Audio.Meters="Merilci" +Basic.Settings.Audio.MeterDecayRate="Hitrost razkroja" +Basic.Settings.Audio.MeterDecayRate.Fast="Hitra" +Basic.Settings.Audio.MeterDecayRate.Medium="Srednja (vrsta I PPM)" +Basic.Settings.Audio.MeterDecayRate.Slow="Počasna (vrsta II PPM)" +Basic.Settings.Audio.PeakMeterType="Vrsta merilca najvišjih točk" +Basic.Settings.Audio.PeakMeterType.SamplePeak="Primer najvišje točke" +Basic.Settings.Audio.PeakMeterType.TruePeak="Resnična najvišja točka (večja poraba CPE-ja)" +Basic.Settings.Audio.MultiChannelWarning.Enabled="OPOZORILO: prostorski zvok je omogočen." +Basic.Settings.Audio.MultichannelWarning="Če pretakate, preverite, ali storitev pretakanja podpira tako snemanje kot predvajanje prostorskega zvoka. Facebook 360 Live, Mixer RTMP in Smashcast so primeri, kjer je prostorski zvok v celoti podprt. Čeprav Facebook Live in YouTube Live podpirata snemanje prostorskega zvoka, ga Facebook Live premeša na stereo, YouTube Live pa predvaja samo dva kanala.\n\nFiltri OBS Studio so združljivi s prostorskim zvokom, čeprav podpora za vtičnik VST ni zajamčena." +Basic.Settings.Audio.MultichannelWarning.Title="Omogoči prostorski zvok?" +Basic.Settings.Audio.MultichannelWarning.Confirm="Ali res želite omogočiti prostorski zvok?" +Basic.Settings.Audio.Devices="Naprave" +Basic.Settings.Audio.DesktopDevice="Namizni zvok" +Basic.Settings.Audio.DesktopDevice2="Namizni zvok 2" +Basic.Settings.Audio.AuxDevice="Mikrofon/Dodatni zvok" +Basic.Settings.Audio.AuxDevice2="Mikrofon/Dodatni zvok 2" +Basic.Settings.Audio.AuxDevice3="Mikrofon/Dodatni zvok 3" +Basic.Settings.Audio.AuxDevice4="Mikrofon/Dodatni zvok 4" +Basic.Settings.Audio.EnablePushToMute="Omogoči 'Pritisni in utišaj'" +Basic.Settings.Audio.PushToMuteDelay="Zakasn. funk. 'Pritisni in utišaj'" +Basic.Settings.Audio.EnablePushToTalk="Omogoči 'Pritisni in govori'" +Basic.Settings.Audio.PushToTalkDelay="Zakasn. funk. 'Pritisni in govori'" +Basic.Settings.Audio.UnknownAudioDevice="[naprava ni povezana ali ni na voljo]" +Basic.Settings.Audio.Disabled="Onemogočeno" +Basic.Settings.Advanced="Napredno" +Basic.Settings.Advanced.General.ProcessPriority="Prednost opravila" +Basic.Settings.Advanced.General.ProcessPriority.High="Visoka" +Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Nad običajno" +Basic.Settings.Advanced.General.ProcessPriority.Normal="Običajna" +Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Pod običajno" +Basic.Settings.Advanced.General.ProcessPriority.Idle="Nedejavno" +Basic.Settings.Advanced.FormatWarning="Opozorilo: barvne oblike razen NV12 so v glavnem namenjene snemanju in niso priporočljive za pretakanje. Pretakanje lahko poveča porabo CPE-ja zaradi pretvarjanja barvne oblike." +Basic.Settings.Advanced.Audio.BufferingTime="Čas medpomnenja zvoka" +Basic.Settings.Advanced.Video.ColorFormat="Barvna oblika" +Basic.Settings.Advanced.Video.ColorSpace="Barvni prostor" +Basic.Settings.Advanced.Video.ColorRange="Barvni razpon" Basic.Settings.Advanced.Video.ColorRange.Partial="Delno" Basic.Settings.Advanced.Video.ColorRange.Full="Celotno" +Basic.Settings.Advanced.Audio.MonitoringDevice="Nadzorna naprava" +Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Privzeto" +Basic.Settings.Advanced.Audio.DisableAudioDucking="Onemogoči zmanjšanje glasnosti zvoka sistema Windows" +Basic.Settings.Advanced.StreamDelay="Zakasnitev pretoka" +Basic.Settings.Advanced.StreamDelay.Duration="Trajanje" +Basic.Settings.Advanced.StreamDelay.Preserve="Ohrani točko prekinitve (povečaj zakasnitev) ob ponovni povezavi" +Basic.Settings.Advanced.StreamDelay.MemoryUsage="Ocenjena poraba pomnilnika: %1 MB" +Basic.Settings.Advanced.Network="Omrežje" +Basic.Settings.Advanced.Network.BindToIP="Veži na IP" +Basic.Settings.Advanced.Network.EnableNewSocketLoop="Omogoči novo omrežno kodo" +Basic.Settings.Advanced.Network.EnableLowLatencyMode="Način nizke zakasnitve" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Vedenje hitrih tipk ob osredotočanju" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Nikoli ne onemogoči hitrih tipk" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Onemogoči hitre tipke, ko je glavno okno v žarišču" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Onemogoči hitre tipke, ko glavno okno ni v žarišču" +Basic.Settings.Advanced.AutoRemux="Samodejno ponovno zvij v mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(posnemi kot mkv)" +Basic.AdvAudio="Napredne lastnosti zvoka" +Basic.AdvAudio.Name="Ime" +Basic.AdvAudio.Volume="Glasnost" +Basic.AdvAudio.Mono="Mono" +Basic.AdvAudio.Balance="Ravnovesje" +Basic.AdvAudio.SyncOffset="Zamik sinhronizacije" +Basic.AdvAudio.Monitoring="Nadzor zvoka" +Basic.AdvAudio.Monitoring.None="Nadzor je izklopljen" +Basic.AdvAudio.Monitoring.MonitorOnly="Samo nadziraj (utišaj izhod)" +Basic.AdvAudio.Monitoring.Both="Nadzor in izhod" +Basic.AdvAudio.AudioTracks="Sledi" +Basic.Settings.Hotkeys="Hitre tipke" +Basic.Settings.Hotkeys.Pair="Kombinacije tipk, deljene s/z '%1', delujejo kot preklopniki" +Basic.Settings.Hotkeys.Filter="Filter" +Basic.Hotkeys.SelectScene="Preklopi na prizor" +Basic.SystemTray.Show="Prikaži" +Basic.SystemTray.Hide="Skrij" +Basic.SystemTray.Message.Reconnecting="Povezava je bila prekinjena. Ponovno povezovanje …" +Hotkeys.Insert="Vstavi" +Hotkeys.Delete="Izbriši" +Hotkeys.Home="Domov" +Hotkeys.End="Ustavi" +Hotkeys.PageUp="Stran gor" +Hotkeys.PageDown="Stran dol" +Hotkeys.NumLock="Num Lock" +Hotkeys.ScrollLock="Scroll Lock" +Hotkeys.CapsLock="Caps Lock" +Hotkeys.Backspace="Vračalka" +Hotkeys.Tab="Zamik." +Hotkeys.Print="Natisni" +Hotkeys.Pause="Premor" +Hotkeys.Left="Levo" +Hotkeys.Right="Desno" +Hotkeys.Up="Gor" +Hotkeys.Down="Dol" +Hotkeys.Windows="Okna" +Hotkeys.Super="Super" +Hotkeys.Menu="Meni" +Hotkeys.Space="Presledek" +Hotkeys.NumpadNum="Tipka številč. %1" +Hotkeys.NumpadMultiply="Tipka * na številč." +Hotkeys.NumpadDivide="Tipka / na številč." +Hotkeys.NumpadAdd="Tipka + na številč." +Hotkeys.NumpadSubtract="Tipka - na številč." +Hotkeys.NumpadDecimal="Tipka . na številč." +Hotkeys.AppleKeypadNum="%1 (številčnica)" +Hotkeys.AppleKeypadMultiply="* (številčnica)" +Hotkeys.AppleKeypadDivide="/ (številčnica)" +Hotkeys.AppleKeypadAdd="+ (številčnica)" +Hotkeys.AppleKeypadSubtract="- (številčnica)" +Hotkeys.AppleKeypadDecimal=". (številčnica)" +Hotkeys.AppleKeypadEqual="= (številčnica)" +Hotkeys.MouseButton="Miška %1" +Hotkeys.Escape="Esc" +Mute="Utišaj" +Unmute="Vklopi zvok" +Push-to-mute="Pritisni in utišaj" +Push-to-talk="Pritisni in govori" +SceneItemShow="Prikaži '%1'" +SceneItemHide="Skrij '%1'" +OutputWarnings.NoTracksSelected="Izbrati morate vsaj eno sled" +OutputWarnings.MultiTrackRecording="Opozorilo: določene oblike (kot je flv) ne podpirajo več sledi na posnetek" +OutputWarnings.MP4Recording="Opozorilo: posnetkov, shranjenih v mp4/mov, ne bo mogoče obnoviti, če datoteka ni dokončana (npr. kot posledica \"modrega zaslona smrti\", izgube napajanja itd.). Če želite posneti več zvočnih sledi, razmislite o uporabi mkv-ja in po dokončanju posnetka njegovim ponovnim zvijanjem v mp4/mov (Datoteka → Ponovno zvij posnetke)." +OutputWarnings.CannotPause="Opozorilo: posnetkov ni mogoče začasno ustaviti, če je snemalni kodirnik nastavljen na \"(uporabi pretočni kodirnik)\"" +FinalScene.Title="Izbriši prizor" +FinalScene.Text="Obstajati mora vsaj en prizor." +NoSources.Title="Ni virov" +NoSources.Text="Videti je, da še niste dodali nobenega slikovnega vira, tako da boste odvajali samo prazen zaslon. Ali res želite to storiti?" +NoSources.Text.AddSource="Vire lahko kadarkoli dodate s klikom na ikono + pod poljem Viri v glavnem oknu." +NoSources.Label="Nimate virov.\nKliknite na spodnji gumb\nali tukaj z desno tipko na miški, da enega dodate." +ChangeBG="Nastavi barvo" +CustomColor="Barva po meri" +BrowserSource.EnableHardwareAcceleration="Omogoči strojno pospeševanje brskalnika" +About="O programu" +About.Info="OBS Studio je prosta in odprtokodna programska oprema za snemanje videoposnetkov in pretakanje v živo." +About.Donate="Prispevaj" +About.GetInvolved="Pridruži se" +About.Authors="Avtorji" +About.License="Licenca" +About.Contribute="Podprite projekt OBS" +ResizeOutputSizeOfSource="Spremeni velikost izhoda (vira)" +ResizeOutputSizeOfSource.Text="Osnovna in izhodna ločljivost bosta spremenjeni na ločljivost trenutnega vira." +ResizeOutputSizeOfSource.Continue="Želite nadaljevati?" +PreviewTransition="Predogled prehoda" diff --git a/UI/data/locale/sq-AL.ini b/UI/data/locale/sq-AL.ini index 3c0e51d..19d0c4d 100644 --- a/UI/data/locale/sq-AL.ini +++ b/UI/data/locale/sq-AL.ini @@ -23,7 +23,6 @@ Settings="Cilësimet" Display="Ekrani" Name="Emri" Exit="Dil" -Mixer="Mikser" Browse="Shfleto" Mono="Mono" Stereo="Stereo" @@ -87,6 +86,7 @@ AlreadyRunning.LaunchAnyway="Filloje ne nje menyre" + Copy.Filters="Kopjo Filterat" Paste.Filters="Ngjit Filterat" @@ -216,5 +216,6 @@ Basic.AutoConfig.TestPage.TestingBandwidth.Server="Duke testuar bandwithin per: + diff --git a/UI/data/locale/sr-CS.ini b/UI/data/locale/sr-CS.ini index 9e80ef1..0771524 100644 --- a/UI/data/locale/sr-CS.ini +++ b/UI/data/locale/sr-CS.ini @@ -23,7 +23,6 @@ Settings="Podešavanja" Display="Ekran" Name="Ime" Exit="Izlaz" -Mixer="Mikseta" Browse="Pretraži" Mono="Mono" Stereo="Stereo" @@ -89,6 +88,7 @@ AlreadyRunning.Text="OBS je već pokrenut! Osim ako zaista želite da uradite ov AlreadyRunning.LaunchAnyway="Pokreni bez obzira na sve" + Auth.Authing.Title="Provera autentičnosti.." Auth.Authing.Text="Provera autentičnosti pomoću %1, molim sačekajte.." Auth.AuthFailure.Title="Nije moguće utvrditi autentičnost" @@ -134,7 +134,6 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Ili 60 ili 30, sa akcentom na viso Basic.AutoConfig.VideoPage.CanvasExplanation="Napomena: Osnovna rezolucija nije nužno ista kao rezolucija kojom ćete strimovati ili kojom ćete snimati. Vaša stvarna rezolucija kojom strimujete/snimate može biti skalirana u odnosu na osnovnu kako bi se smanjila upotreba resursa ili optimizovao protok." Basic.AutoConfig.StreamPage="Informacije o strimovanju" Basic.AutoConfig.StreamPage.SubTitle="Molimo unesite Vaše informacije o strimovanju" -Basic.AutoConfig.StreamPage.ConnectAccount="Poveži nalog (opciono)" Basic.AutoConfig.StreamPage.DisconnectAccount="Diskonektuj nalog" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Diskonektuj nalog?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Ova promena će biti primenjena odmah. Da li ste sigurni da želite da diskonektujete Vaš nalog?" @@ -235,6 +234,7 @@ ConfirmStop.Title="Zaustavi strim?" ConfirmStop.Text="Da li ste sigurni da želite da zaustavite strimovanje?" + ConfirmExit.Title="Izađite iz OBS programa?" ConfirmExit.Text="OBS je trenutno aktivan. Svi strimovi/snimanja će biti ugašeni. Da li ste sigurni da želite da izađete iz programa?" @@ -577,7 +577,6 @@ Basic.Settings.Output.Mode.Simple="Jednostavno" Basic.Settings.Output.Mode.Adv="Napredno" Basic.Settings.Output.Mode.FFmpeg="FFmpeg izlaz" Basic.Settings.Output.UseReplayBuffer="Uključi bafer ponovnog prikazivanja" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksimalno vreme ponovnog prikazivanja (sekunde)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maksimalna memorija (MB)" Basic.Settings.Output.ReplayBuffer.Estimate="Procenjena iskorišćenost memorije: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Nemoguće je proceniti iskorišćenost memorije. Molimo podesite maksimalnu granicu memorije." @@ -604,7 +603,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softverski (x264 niska upot Basic.Settings.Output.VideoBitrate="Protok videa" Basic.Settings.Output.AudioBitrate="Protok zvuka" Basic.Settings.Output.Reconnect="Automatski poveži ponovo" -Basic.Settings.Output.RetryDelay="Kašnjenje ponovnog pokušaja (sekunde)" Basic.Settings.Output.MaxRetries="Maksimalan broj ponovnih pokušaja" Basic.Settings.Output.Advanced="Omogući napredna podešavanja kompresora" Basic.Settings.Output.EncoderPreset="Predefinisano podešavanje enkodera" @@ -675,7 +673,7 @@ Basic.Settings.Video.DisableAero="Onemogući Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (najbrže, ali mutno pri skaliranju)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (oštrije skaliranje, 16 uzoraka)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (oštrije skaliranje, 32 uzorka)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (oštrije skaliranje, 36 uzorka)" Basic.Settings.Audio="Zvuk" Basic.Settings.Audio.SampleRate="Protok" @@ -687,7 +685,7 @@ Basic.Settings.Audio.PeakMeterType="Tip merača vrha" Basic.Settings.Audio.PeakMeterType.SamplePeak="Vrh uzorka" Basic.Settings.Audio.PeakMeterType.TruePeak="Pravi vrh (Veća upotreba procesora)" Basic.Settings.Audio.MultiChannelWarning.Enabled="UPOZORENJE: Zvuk okruženja je uključen." -Basic.Settings.Audio.MultichannelWarning="Ako je strim u toku, proverite da li vaša striming usluga podržava integraciju i plejbek zvuka okruženja. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast su primeri gde je zvuk okruženja u potpunosti podržan. Iako i Facebook Live i YouTube Live podržavaju integraciju okruženja, Facebook Live miksuje kao stereo, a YouTube Live reprodukuje samo dva kanala.\n\nOBS zvučni filteri su kompatibilni sa zvukom okruženja, mada podrška za VST priključke nije zagarantovana." +Basic.Settings.Audio.MultichannelWarning="Ako je strim u toku, proverite da li vaša striming usluga podržava integraciju i plejbek zvuka okruženja. Facebook 360 Live, Mixer RTMP, Smashcast su primeri gde je zvuk okruženja u potpunosti podržan. Iako i Facebook Live i YouTube Live podržavaju integraciju okruženja, Facebook Live miksuje kao stereo, a YouTube Live reprodukuje samo dva kanala.\n\nOBS zvučni filteri su kompatibilni sa zvukom okruženja, mada podrška za VST priključke nije zagarantovana." Basic.Settings.Audio.MultichannelWarning.Title="Da li želite da uključite zvuk okruženja?" Basic.Settings.Audio.MultichannelWarning.Confirm="Da li ste sigurni da želite da uključite zvuk okruženja?" Basic.Settings.Audio.Devices="Uređaji" @@ -713,7 +711,6 @@ Basic.Settings.Advanced.Video.ColorRange.Full="Potpuno" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Podrazumevano" Basic.Settings.Advanced.Audio.DisableAudioDucking="Isključi Windows audio ducking" Basic.Settings.Advanced.StreamDelay="Kašnjenje strimovanja" -Basic.Settings.Advanced.StreamDelay.Duration="Trajanje (sekunde)" Basic.Settings.Advanced.StreamDelay.Preserve="Sačuvaj tačku prekida (povećaj kašnjenje) prilikom ponovnog povezivanja" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Procenjena upotreba memorije: %1 MB" Basic.Settings.Advanced.Network="Mreža" @@ -726,9 +723,7 @@ Basic.Settings.Advanced.AutoRemux.MP4="(snimi kao mkv)" Basic.AdvAudio="Napredna podešavanja zvuka" Basic.AdvAudio.Name="Ime" -Basic.AdvAudio.Mono="Spoji u mono" Basic.AdvAudio.Balance="Balans" -Basic.AdvAudio.SyncOffset="Razlika u sinhronizaciji (ms)" Basic.AdvAudio.Monitoring="Audio nadzor" Basic.AdvAudio.Monitoring.None="Isključi nadzor" Basic.AdvAudio.Monitoring.MonitorOnly="Samo nadzor (izlaz bez zvuka)" diff --git a/UI/data/locale/sr-SP.ini b/UI/data/locale/sr-SP.ini index 5f94565..1e6dfe4 100644 --- a/UI/data/locale/sr-SP.ini +++ b/UI/data/locale/sr-SP.ini @@ -23,7 +23,6 @@ Settings="Подешавања" Display="Екран" Name="Име" Exit="Изађи" -Mixer="Миксета" Browse="Прегледај" Mono="Моно" Stereo="Стерео" @@ -86,6 +85,7 @@ AlreadyRunning.Text="OBS je већ покренут! Осим ако заист AlreadyRunning.LaunchAnyway="Свеједно покрени" + Auth.Authing.Title="Потврда идентитета" Auth.Authing.Text="Потврда идентитета помоћу %1-а, сачекајте…" Auth.AuthFailure.Title="Грешка при потврди идентитета" @@ -131,7 +131,6 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Или 60 или 30, са акце Basic.AutoConfig.VideoPage.CanvasExplanation="Напомена: основна резолуција није нужно иста као резолуција којом ћете стримовати или којом ћете снимати. Ваша стварна резолуција којом стримујете/снимате може бити скалирана у односу на основну како би се смањила употреба ресурса или оптимизовао проток." Basic.AutoConfig.StreamPage="Информације о стримовању" Basic.AutoConfig.StreamPage.SubTitle="Молимо унесите ваше информације о стримовању" -Basic.AutoConfig.StreamPage.ConnectAccount="Повежи налог (опционо)" Basic.AutoConfig.StreamPage.DisconnectAccount="Дисконектуј налог" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Дисконектуј налог?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Ова промена ће бити примењена одмах. Да ли сте сигурни да желите да дисконектујете Ваш налог?" @@ -231,6 +230,7 @@ ConfirmStop.Title="Заустави стрим?" ConfirmStop.Text="Да ли сте сигурни да желите да зауставите стримовање?" + ConfirmExit.Title="Изађите из OBS програма?" ConfirmExit.Text="OBS је тренутно активан. Сви стримови/снимања ће бити угашени. Да ли сте сигурни да желите да изађете из програма?" @@ -573,7 +573,6 @@ Basic.Settings.Output.Mode.Simple="Једноставно" Basic.Settings.Output.Mode.Adv="Напредно" Basic.Settings.Output.Mode.FFmpeg="FFmpeg излаз" Basic.Settings.Output.UseReplayBuffer="Укључи бафер поновног приказивања" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Максимално време поновног приказивања (секунде)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Максимална меморија (мегабајти)" Basic.Settings.Output.ReplayBuffer.Estimate="Процењена искоришћеност меморије: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Немогуће је проценити искоришћеност меморије. Молимо подесите максималну границу меморије." @@ -600,7 +599,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Софтверски (x264 Basic.Settings.Output.VideoBitrate="Проток видеа" Basic.Settings.Output.AudioBitrate="Проток звука" Basic.Settings.Output.Reconnect="Аутоматски повежи поново" -Basic.Settings.Output.RetryDelay="Кашњење поновног покушаја (секунде)" Basic.Settings.Output.MaxRetries="Максималан број поновних покушаја" Basic.Settings.Output.Advanced="Омогући напредна подешавања компресора" Basic.Settings.Output.EncoderPreset="Предефинисано подешавање енкодера" @@ -671,7 +669,7 @@ Basic.Settings.Video.DisableAero="Онемогући Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (најбрже, али мутно при скалирању)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (оштрије скалирање, 16 узорака)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (оштрије скалирање, 32 узорка)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (оштрије скалирање, 36 узорка)" Basic.Settings.Audio="Звук" Basic.Settings.Audio.SampleRate="Проток" @@ -683,7 +681,7 @@ Basic.Settings.Audio.PeakMeterType="Тип мерача врха" Basic.Settings.Audio.PeakMeterType.SamplePeak="Врх узорка" Basic.Settings.Audio.PeakMeterType.TruePeak="Прави врх (већа употреба процесора)" Basic.Settings.Audio.MultiChannelWarning.Enabled="УПОЗОРЕЊЕ: Звук окружења је укључен." -Basic.Settings.Audio.MultichannelWarning="Ако је стрим у току, проверите да ли ваша стриминг услуга подржава интеграцију и плејбек звука окружења. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast су примери где је звук окружења у потпуности подржан. Иако и Facebook Live i YouTube Live подржавају интеграцију окружења, Facebook Live миксује као стерео, а YouTube Live репродукује само два канала. \n\nOBS звучни филтери су компатибилни са звуком окружења, мада подршка за VST прикључке није загарантована." +Basic.Settings.Audio.MultichannelWarning="Ако је стрим у току, проверите да ли ваша стриминг услуга подржава интеграцију и плејбек звука окружења. Facebook 360 Live, Mixer RTMP, Smashcast су примери где је звук окружења у потпуности подржан. Иако и Facebook Live i YouTube Live подржавају интеграцију окружења, Facebook Live миксује као стерео, а YouTube Live репродукује само два канала. \n\nOBS звучни филтери су компатибилни са звуком окружења, мада подршка за VST прикључке није загарантована." Basic.Settings.Audio.MultichannelWarning.Title="Да ли желите да укључите звук окружења?" Basic.Settings.Audio.MultichannelWarning.Confirm="Да ли сте сигурни да желите да укључите звук окружења?" Basic.Settings.Audio.EnablePushToMute="Омогући стисни-за-мутирање" @@ -707,7 +705,6 @@ Basic.Settings.Advanced.Video.ColorRange.Full="Потпуно" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Подразумевано" Basic.Settings.Advanced.Audio.DisableAudioDucking="Искључи Windows audio ducking" Basic.Settings.Advanced.StreamDelay="Кашњење стримовања" -Basic.Settings.Advanced.StreamDelay.Duration="Трајање (секунде)" Basic.Settings.Advanced.StreamDelay.Preserve="Сачувај тачку прекида (повећај кашњење) приликом поновног повезивања" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Процењена употреба меморије: %1 MB" Basic.Settings.Advanced.Network="Мрежа" @@ -720,9 +717,7 @@ Basic.Settings.Advanced.AutoRemux.MP4="(сними као mkv)" Basic.AdvAudio="Напредна подешавања звука" Basic.AdvAudio.Name="Име" -Basic.AdvAudio.Mono="Споји у моно" Basic.AdvAudio.Balance="Баланс" -Basic.AdvAudio.SyncOffset="Разлика у синхронизацији (ms)" Basic.AdvAudio.Monitoring="Аудио надзор" Basic.AdvAudio.Monitoring.None="Искључи надзор" Basic.AdvAudio.Monitoring.MonitorOnly="Само надзор (излаз без звука)" diff --git a/UI/data/locale/sv-SE.ini b/UI/data/locale/sv-SE.ini index 7439dc0..c548b8d 100644 --- a/UI/data/locale/sv-SE.ini +++ b/UI/data/locale/sv-SE.ini @@ -7,13 +7,13 @@ Apply="Verkställ" Cancel="Avbryt" Close="Stäng" Save="Spara" -Discard="Radera" +Discard="Ignorera" Disable="Inaktivera" Yes="Ja" No="Nej" Add="Lägg till" Remove="Ta bort" -Rename="Ändra namn" +Rename="Byt namn" Interact="Interagera" Filters="Filter" Properties="Egenskaper" @@ -23,7 +23,7 @@ Settings="Inställningar" Display="Bildskärm" Name="Namn" Exit="Avsluta" -Mixer="Mixer" +Mixer="Ljudmixer" Browse="Bläddra" Mono="Mono" Stereo="Stereo" @@ -39,7 +39,7 @@ SourceWindow="Fönsterprojektor (källa)" MultiviewProjector="Multivy (helskärm)" MultiviewWindowed="Multivy (fönster)" Clear="Rensa" -Revert="Återgå" +Revert="Nollställ" Show="Visa" Hide="Dölj" UnhideAll="Visa alla" @@ -67,7 +67,7 @@ Export="Exportera" Copy="Kopiera" Paste="Klistra in" PasteReference="Klistra in (referens)" -PasteDuplicate="Klistra in (duplicera)" +PasteDuplicate="Klistra in (dubblett)" RemuxRecordings="Remuxa inspelningar" Next="Nästa" Back="Tillbaka" @@ -91,6 +91,10 @@ AlreadyRunning.LaunchAnyway="Kör ändå" DockCloseWarning.Title="Stäng flytande fönster" DockCloseWarning.Text="Du stängde precis ett flytande fönster. Om du vill visa det igen, använd Visa → Flytande fönster i menyfältet." +ExtraBrowsers="Anpassade flytande webbläsarfönster" +ExtraBrowsers.Info="Lägg till flytande fönster genom att ge dem ett namn och en webbadress, klicka sedan på Verkställ eller Stäng för att öppna fönstren. Du kan lägga till eller ta bort flytande fönster när som helst." +ExtraBrowsers.DockName="Namn på flytande fönster" + Auth.Authing.Title="Autentiserar..." Auth.Authing.Text="Autentiserar med %1, var god vänta..." Auth.AuthFailure.Title="Autentiseringsfel" @@ -107,6 +111,7 @@ TwitchAuth.Stats="Twitch-statistik" TwitchAuth.Feed="Aktivitetsflöde för Twitch" TwitchAuth.TwoFactorFail.Title="Kunde inte efterfråga strömnyckel" TwitchAuth.TwoFactorFail.Text="OBS kunde inte ansluta till ditt Twitch-konto. Se till att tvåfaktorsautentiseringen har ställts in i säkerhetsinställningarna på Twitch då detta är nödvändigt för att kunna strömma." +RestreamAuth.Channels="Restream-kanaler" Copy.Filters="Kopiera filter" Paste.Filters="Klistra in filter" @@ -139,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Antingen 60 eller 30, men föredra Basic.AutoConfig.VideoPage.CanvasExplanation="OBS: Kanvasens (grundens) upplösning är nödvändigtvis samma som upplösningen upp kommer att strömma eller spela in med. Din riktiga upplösning för strömning/inspelning kan skalas ned från kanvasupplösningen för att reducera användning av resurser eller krav på bithastighet." Basic.AutoConfig.StreamPage="Ströminformation" Basic.AutoConfig.StreamPage.SubTitle="Var god ange din ströminformation" -Basic.AutoConfig.StreamPage.ConnectAccount="Anslut konto (valfritt)" +Basic.AutoConfig.StreamPage.ConnectAccount="Anslut konto (rekommenderas)" Basic.AutoConfig.StreamPage.DisconnectAccount="Koppla från konto" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Koppla från konto?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Denna ändring kommer tillämpas direkt. Är du säker på att du vill koppla från ditt konto?" @@ -157,7 +162,7 @@ Basic.AutoConfig.StreamPage.StreamWarning.Title="Strömvarning" Basic.AutoConfig.StreamPage.StreamWarning.Text="Bandbreddstestet kommer att strömma slumpad videodata utan ljud till din kanal. Om det fungerar, är det rekommenderat det att tillfälligt inaktivera att spara videor av strömmar och ändra strömmen till privat tills testet är färdigt. Fortsätta?" Basic.AutoConfig.TestPage="Slutgiltiga resultat" Basic.AutoConfig.TestPage.SubTitle.Testing="Programmet utför nu en grupp tester för att uppskatta de mest idealiska inställningarna" -Basic.AutoConfig.TestPage.SubTitle.Complete="Testet slutfört" +Basic.AutoConfig.TestPage.SubTitle.Complete="Testet slutfördes" Basic.AutoConfig.TestPage.TestingBandwidth="Utför bandbreddstest, detta kan ta några minuter..." Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Ansluter till: %1..." Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Misslyckades att ansluta till någon server, kontrollera din Internetanslutning och försök igen." @@ -213,7 +218,7 @@ QuickTransitions.DuplicateScene="Duplicera scen" QuickTransitions.DuplicateSceneTT="När du redigerar samma scen kan du redigera transformering/synligheten för källor utan att modifiera utmatningen.\nFör att redigera egenskaper för källor utan att modifiera utmatningen aktiverar du 'Duplicera källor'.\nNär detta värde ändras kommer den aktuella utmatningsscenen återställas (om den fortfarande finns)." QuickTransitions.EditProperties="Duplicera källor" QuickTransitions.EditPropertiesTT="När du redigerar samma scen kan du redigera egenskaperna för källor utan att modifiera utmatningen.\nDetta fungerar endast om 'Duplicera scen' är aktiverad.\nVissa källor (som mediakällor) stöder inte detta och kan inte redigeras separat.\nNär detta värde ändras kommer den aktuella utmatningsscenen återställas (om den fortfarande finns).\n\nVarning: Eftersom källor kommer att dupliceras kan detta kräva extra system- eller videoresurser." -QuickTransitions.HotkeyName="Snabba övergång: %1" +QuickTransitions.HotkeyName="Snabb övergång: %1" Basic.AddTransition="Lägg till konfigurerbar övergång" Basic.RemoveTransition="Ta bort konfigurerbar övergång" @@ -240,6 +245,9 @@ ConfirmStart.Text="Är du säker på att du vill börja strömma?" ConfirmStop.Title="Sluta strömma?" ConfirmStop.Text="Är du säker på att du vill sluta strömma?" +ConfirmStopRecord.Title="Stoppa inspelning?" +ConfirmStopRecord.Text="Är du säker på att du vill stoppa inspelningen?" + ConfirmBWTest.Title="Starta bandbreddstest?" ConfirmBWTest.Text="Du har konfigurerat OBS i testläge för bandbredd. Detta läge låter dig testa nätverket utan att din kanal direktsänder. När du har testat färdigt behöver du inaktivera den för att att tittare ska kunna se din ström.\n\nVill du fortsätta?" @@ -255,10 +263,12 @@ Output.StartRecordingFailed="Misslyckades att starta inspelning" Output.StartReplayFailed="Misslyckades att starta reprisbuffert" Output.StartFailedGeneric="Misslyckades att starta utmatningen. Kolla loggen för detaljer.\n\nOBS: Om du använder kodarna NVENC eller AMD, se till att dina grafikdrivrutiner är uppdaterade." +Output.ReplayBuffer.PauseWarning.Title="Kan inte spara repriser under pausning" +Output.ReplayBuffer.PauseWarning.Text="Varning: Repriser kan inte sparas när inspelningen är pausad." -Output.ConnectFail.Title="Anslutning misslyckades" +Output.ConnectFail.Title="Misslyckades att ansluta" Output.ConnectFail.BadPath="Ogiltig sökväg eller anslutnings-URL. Kontrollera att dina inställningar är korrekta." -Output.ConnectFail.ConnectFailed="Kunde inte ansluta till servern" +Output.ConnectFail.ConnectFailed="Misslyckades att ansluta till server" Output.ConnectFail.InvalidStream="Kunde inte komma åt den valda kanalen eller strömnyckeln, var god dubbelkolla din strömnyckel. Om den stämmer kan det finnas något anslutningsproblem till servern." Output.ConnectFail.Error="Ett oväntat fel uppstod vid anslutning till servern. Se loggfilen för ytterligare information." Output.ConnectFail.Disconnected="Nedkopplad från servern." @@ -266,7 +276,7 @@ Output.ConnectFail.Disconnected="Nedkopplad från servern." Output.StreamEncodeError.Title="Kodningsfel" Output.StreamEncodeError.Msg="Ett kodarfel uppstod under strömmande." -Output.RecordFail.Title="Det gick inte att starta inspelningen" +Output.RecordFail.Title="Misslyckades att starta inspelning" Output.RecordFail.Unsupported="Antingen stöds inte utdataformatet eller så har det inte stöd för mer än ett ljudspår. Kontrollera dina inställningar och försök igen." Output.RecordNoSpace.Title="Otillräckligt diskutrymme" Output.RecordNoSpace.Msg="Det finns inte tillräckligt med diskutrymme för att fortsätta inspelningen." @@ -444,6 +454,8 @@ Basic.Main.StartRecording="Börja spela in" Basic.Main.StartReplayBuffer="Starta reprisbuffert" Basic.Main.StartStreaming="Börja strömma" Basic.Main.StopRecording="Sluta spela in" +Basic.Main.PauseRecording="Pausa inspelning" +Basic.Main.UnpauseRecording="Återuppta inspelning" Basic.Main.StoppingRecording="Slutar spela in..." Basic.Main.StopReplayBuffer="Stoppa reprisbuffert" Basic.Main.StoppingReplayBuffer="Stoppar reprisbuffert..." @@ -454,54 +466,55 @@ Basic.Main.Group="Grupp %1" Basic.Main.GroupItems="Gruppera markerade föremål" Basic.Main.Ungroup="Avgruppera" -Basic.MainMenu.File="Arkiv (&F)" +Basic.MainMenu.File="&Arkiv" Basic.MainMenu.File.Export="&Exportera" Basic.MainMenu.File.Import="&Importera" -Basic.MainMenu.File.ShowRecordings="Visa inspelninga&r" +Basic.MainMenu.File.ShowRecordings="&Visa inspelningar" Basic.MainMenu.File.Remux="Re&muxa inspelningar" -Basic.MainMenu.File.Settings="In&ställningar" +Basic.MainMenu.File.Settings="&Inställningar" Basic.MainMenu.File.ShowSettingsFolder="Visa inställningsmapp" Basic.MainMenu.File.ShowProfileFolder="Visa profilmapp" Basic.MainMenu.AlwaysOnTop="&Alltid överst" -Basic.MainMenu.File.Exit="Avsluta (&X)" +Basic.MainMenu.File.Exit="Avsl&uta" -Basic.MainMenu.Edit="R&edigera" -Basic.MainMenu.Edit.Undo="Ångra (&U)" -Basic.MainMenu.Edit.Redo="Gö&r om" -Basic.MainMenu.Edit.UndoAction="Ångra $1 (&U)" -Basic.MainMenu.Edit.RedoAction="Gö&r om $1" +Basic.MainMenu.Edit="&Redigera" +Basic.MainMenu.Edit.Undo="&Ångra" +Basic.MainMenu.Edit.Redo="&Gör om" +Basic.MainMenu.Edit.UndoAction="&Ångra $1" +Basic.MainMenu.Edit.RedoAction="&Gör om $1" Basic.MainMenu.Edit.LockPreview="&Lås förhandsvisning" -Basic.MainMenu.Edit.Scale="Förhandsvisa &skalning" +Basic.MainMenu.Edit.Scale="&Förhandsvisa skalning" Basic.MainMenu.Edit.Scale.Window="Skala till fönster" Basic.MainMenu.Edit.Scale.Canvas="Kanvas (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Utmatning (%1x%2)" -Basic.MainMenu.Edit.Transform="Omvandla (&T)" -Basic.MainMenu.Edit.Transform.EditTransform="R&edigera omvandling..." -Basic.MainMenu.Edit.Transform.CopyTransform="Kopiera transformering" -Basic.MainMenu.Edit.Transform.PasteTransform="Klistra in transformering" -Basic.MainMenu.Edit.Transform.ResetTransform="Åte&rställ omvandling" +Basic.MainMenu.Edit.Transform="O&mvandla" +Basic.MainMenu.Edit.Transform.EditTransform="&Redigera omvandling..." +Basic.MainMenu.Edit.Transform.CopyTransform="Kopiera omvandling" +Basic.MainMenu.Edit.Transform.PasteTransform="Klistra in omvandling" +Basic.MainMenu.Edit.Transform.ResetTransform="&Återställ omvandling" Basic.MainMenu.Edit.Transform.Rotate90CW="Rotera 90 grader medsols" Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotera 90 grader motsols" Basic.MainMenu.Edit.Transform.Rotate180="Rotera 180 grader" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Spegelvänd vågrätt (&H)" -Basic.MainMenu.Edit.Transform.FlipVertical="Spegel&vänd lodrätt" -Basic.MainMenu.Edit.Transform.FitToScreen="Anpassa till skärmen (&F)" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Spegelvänd &horisontalt" +Basic.MainMenu.Edit.Transform.FlipVertical="Spegel&vänd vertikalt" +Basic.MainMenu.Edit.Transform.FitToScreen="&Anpassa till skärmen" Basic.MainMenu.Edit.Transform.StretchToScreen="Anpa&ssa storlek till skärmen" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centrera på skärmen" Basic.MainMenu.Edit.Transform.VerticalCenter="Centrera vertikalt" Basic.MainMenu.Edit.Transform.HorizontalCenter="Centrera horisontalt" Basic.MainMenu.Edit.Order="&Ordning" Basic.MainMenu.Edit.Order.MoveUp="Flytta &upp" -Basic.MainMenu.Edit.Order.MoveDown="Flytta ne&d" -Basic.MainMenu.Edit.Order.MoveToTop="Lägg övers&t" -Basic.MainMenu.Edit.Order.MoveToBottom="Lägg underst (&B)" +Basic.MainMenu.Edit.Order.MoveDown="Flytta &ned" +Basic.MainMenu.Edit.Order.MoveToTop="Flytta längst u&pp" +Basic.MainMenu.Edit.Order.MoveToBottom="Flytta längst ne&d" Basic.MainMenu.Edit.AdvAudio="&Avancerade ljudinställningar" Basic.MainMenu.View="&Visa" -Basic.MainMenu.View.Toolbars="Verk&tygsfält" +Basic.MainMenu.View.Toolbars="&Verktygsfält" Basic.MainMenu.View.Docks="Flytande fönster" Basic.MainMenu.View.Docks.ResetUI="Återställ gränssnitt" Basic.MainMenu.View.Docks.LockUI="Lås gränssnitt" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Anpassade flytande webbläsarfönster..." Basic.MainMenu.View.Toolbars.Listboxes="&Listrutor" Basic.MainMenu.View.SceneTransitions="S&cenövergångar" Basic.MainMenu.View.StatusBar="&Statusfält" @@ -516,22 +529,22 @@ Basic.MainMenu.SceneCollection.Export="Exportera scensamling" Basic.MainMenu.Profile.Exists="Profilen finns redan" Basic.MainMenu.SceneCollection.Exists="Scensamlingen finns redan" -Basic.MainMenu.Tools="Verk&tyg" +Basic.MainMenu.Tools="&Verktyg" Basic.MainMenu.Help="&Hjälp" Basic.MainMenu.Help.HelpPortal="Hjälp&portal" Basic.MainMenu.Help.Website="Besök &webbplats" Basic.MainMenu.Help.Discord="Anslut till &Discord-servern" Basic.MainMenu.Help.Logs="&Loggfiler" -Basic.MainMenu.Help.Logs.ShowLogs="Vi&sa loggfiler" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Ladda upp aktuell loggfil (&C)" -Basic.MainMenu.Help.Logs.UploadLastLog="&Ladda upp senaste loggfil" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Visa Aktuell Logg" +Basic.MainMenu.Help.Logs.ShowLogs="&Visa loggfiler" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Ladda upp &aktuell loggfil" +Basic.MainMenu.Help.Logs.UploadLastLog="Ladda upp &senaste loggfil" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Visa aktuell &logg" Basic.MainMenu.Help.CheckForUpdates="Sök efter uppdateringar" -Basic.MainMenu.Help.CrashLogs="Krasch&rapporter" -Basic.MainMenu.Help.CrashLogs.ShowLogs="Vi&sa kraschrapporter" +Basic.MainMenu.Help.CrashLogs="&Kraschrapporter" +Basic.MainMenu.Help.CrashLogs.ShowLogs="&Visa kraschrapporter" Basic.MainMenu.Help.CrashLogs.UploadLastLog="&Ladda upp senaste kraschrapport" -Basic.MainMenu.Help.About="Om (&A)" +Basic.MainMenu.Help.About="&Om" Basic.Settings.ProgramRestart="Du måste starta om programmet för att ändringarna ska träda i kraft." Basic.Settings.ConfirmTitle="Bekräfta ändringar" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="Sök efter uppdateringar automatiskt v Basic.Settings.General.OpenStatsOnStartup="Öppna statistikfönstret vid uppstart" Basic.Settings.General.WarnBeforeStartingStream="Visa bekräftelsedialog när ström startas" Basic.Settings.General.WarnBeforeStoppingStream="Visa bekräftelsedialog när ström stoppas" +Basic.Settings.General.WarnBeforeStoppingRecord="Visa bekräftelsedialog när inspelning stoppas" Basic.Settings.General.Projectors="Projektorer" Basic.Settings.General.HideProjectorCursor="Dölj pekaren över projektorer" Basic.Settings.General.ProjectorAlwaysOnTop="Lägg alltid projektorer överst" @@ -591,12 +605,15 @@ Basic.Settings.Output.Encoder="Kodare" Basic.Settings.Output.SelectDirectory="Välj inspelningsplats" Basic.Settings.Output.SelectFile="Välj inspelningsfil" Basic.Settings.Output.EnforceBitrate="Tvinga gränser för streamens bit-rate" +Basic.Settings.Output.DynamicBitrate="Ändra bithastigheten dynamiskt för att hantera överbelastning" +Basic.Settings.Output.DynamicBitrate.Beta="Ändra bithastigheten dynamiskt för att hantera överbelastning (beta)" +Basic.Settings.Output.DynamicBitrate.TT="Istället för att kasta bildrutor för att reducera överbelastning kommer bithastigheten ändras dynamiskt.\n\nObservera att detta kan öka fördröjningen för tittare om en avsevärd belastning uppstår.\nNär bithastigheten sjunker kan det ta ett par minuter att återställas.\n\nStöds för närvarande endast för RTMP." Basic.Settings.Output.Mode="Utmatningsläge" Basic.Settings.Output.Mode.Simple="Simpel" Basic.Settings.Output.Mode.Adv="Avancerat" Basic.Settings.Output.Mode.FFmpeg="FFmpeg-utmatning" Basic.Settings.Output.UseReplayBuffer="Aktivera reprisbuffert" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximal repristid (sekunder)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximal repristid" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximalt minne (Megabyte)" Basic.Settings.Output.ReplayBuffer.Estimate="Uppskattad minnesanvändning: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Kan inte uppskatta minnesanvändningen. Ange maximal minnesgräns." @@ -611,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Oskiljbar kvalitet, stor filst Basic.Settings.Output.Simple.RecordingQuality.Lossless="Förlustfri kvalitet, oerhört stor filstorlek" Basic.Settings.Output.Simple.Warn.VideoBitrate="Varning: Streamens videobit-rate kommer att sättas till %1, vilket är den övre gränsen för den nuvarande streaming-tjänsten. Om du är säker på att du vill gå över %1, aktivera \"avancerade kodarinställningar\" och avaktivera \"Tvinga streaming-tjänstens bit-rategränser\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Varning: Streamens ljudbit-rate kommer att sättas till %1, vilket är den övre gränsen för den nuvarande streaming-tjänsten. Om du är säker på att du vill gå över %1, aktivera \"avancerade kodarinställningar\" och avaktivera \"Tvinga streaming-tjänstens bit-rategränser\"." +Basic.Settings.Output.Simple.Warn.CannotPause="Varning: Inspelningar kan inte pausas om inspelningskvaliteten är \"Samma som ström\"." Basic.Settings.Output.Simple.Warn.Encoder="Varning: Inspelning med en mjukvaru-kodare i annan kvalitet än streamen kräver mer CPU-använding om du streamar och spelar in samtidigt." Basic.Settings.Output.Simple.Warn.Lossless="Varning: Förlustfri kvalitet generar oerhört stora filstorlekar! Förlustfri kvalitet kan använda upp till 7 gigabyte hårddiskutrymme per minut vid höga upplösningar och bildfrekvenser. Detta rekommenderas inte för långa inspelningar såvida du har riktigt mycket hårddiskutrymme tillgängligt." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Är du säker på att du vill använda förlustfri kvalitet?" @@ -623,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Mjukvaru-kodek (x264-förin Basic.Settings.Output.VideoBitrate="Bithastighet för video" Basic.Settings.Output.AudioBitrate="Bithastighet för ljud" Basic.Settings.Output.Reconnect="Automatisk återanslutning" -Basic.Settings.Output.RetryDelay="Återanslutningsfördröjning (sek)" +Basic.Settings.Output.RetryDelay="Fördröjning för nästa försök" Basic.Settings.Output.MaxRetries="Maximalt antal försök" Basic.Settings.Output.Advanced="Aktivera avancerade kodarinställningar" Basic.Settings.Output.EncoderPreset="Förinställning för kodare" @@ -680,21 +698,22 @@ Basic.Settings.Video.Adapter="Grafikkort" Basic.Settings.Video.BaseResolution="Grundupplösning (kanvas)" Basic.Settings.Video.ScaledResolution="Utdataupplösning (skalad)" Basic.Settings.Video.DownscaleFilter="Nedskalningsfilter" -Basic.Settings.Video.DisableAeroWindows="Avaktivera Aero (endast Windows)" -Basic.Settings.Video.FPS="FPS" +Basic.Settings.Video.DisableAeroWindows="Inaktivera Aero (endast Windows)" +Basic.Settings.Video.FPS="Bildfrekvens" Basic.Settings.Video.FPSCommon="Vanliga bildhastighetsvärden" -Basic.Settings.Video.FPSInteger="Heltals-bildhastighetsvärde" -Basic.Settings.Video.FPSFraction="Decimaltals-bildhastighetsvärde" +Basic.Settings.Video.FPSInteger="Bildfrekvensvärde (heltal)" +Basic.Settings.Video.FPSFraction="Bildfrekvensvärde (decimaltal)" Basic.Settings.Video.Numerator="Täljare" Basic.Settings.Video.Denominator="Nämnare" -Basic.Settings.Video.Renderer="Renderare:" -Basic.Settings.Video.InvalidResolution="Ogiltig upplösning. Måste anges som [bredd]x[höjd] (t.ex 1920x1080)" +Basic.Settings.Video.Renderer="Renderare" +Basic.Settings.Video.InvalidResolution="Ogiltigt upplösningsvärde. Måste vara [bredd]x[höjd] (t.ex. 1920x1080)" Basic.Settings.Video.CurrentlyActive="Videoutmatning är aktiv. Stoppa alla utmatningar för att kunna ändra videoinställningar." Basic.Settings.Video.DisableAero="Inaktivera Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinjär (snabbast, men suddigt om skalad)" -Basic.Settings.Video.DownscaleFilter.Bicubic="Bikubisk (Vässd skalning, 16 prover)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Vässd skalning, 32 prover)" +Basic.Settings.Video.DownscaleFilter.Bicubic="Bikubisk (skarpare skalning, 16 samplingar)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (skarpare skalning, 36 samplingar)" +Basic.Settings.Video.DownscaleFilter.Area="Area (viktad summa, 4/6/9 samplingar)" Basic.Settings.Audio="Ljud" Basic.Settings.Audio.SampleRate="Samplingsfrekvens" @@ -708,7 +727,7 @@ Basic.Settings.Audio.PeakMeterType="Typ av maxpunktsmätare" Basic.Settings.Audio.PeakMeterType.SamplePeak="Samplingsmaxpunkt" Basic.Settings.Audio.PeakMeterType.TruePeak="Sann maxpunkt (högre CPU-användning)" Basic.Settings.Audio.MultiChannelWarning.Enabled="VARNING: Surroundljud är aktiverat." -Basic.Settings.Audio.MultichannelWarning="Om du strömmar, se till att kolla om din strömtjänst stöder både inmatning och uppspelning av surroundljud. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast är några exempel på tjänster som har fullt stöd. Fastän Facebook Live och YouTube Live stöder inmatning för surroundljud mixar Facebook Live ned till stereo och YouTube Live spelar upp i bara två kanaler.\n\nLjudfiltren i OBS är kompatibla med surroundljud, fast stöd för VST-insticksmodulen garanteras inte." +Basic.Settings.Audio.MultichannelWarning="Om du strömmar, se till att kolla om din strömtjänst stöder både inmatning och uppspelning av surroundljud. Facebook 360 Live, Mixer RTMP, Smashcast är några exempel på tjänster som har fullt stöd. Fastän Facebook Live och YouTube Live stöder inmatning för surroundljud mixar Facebook Live ned till stereo och YouTube Live spelar upp i bara två kanaler.\n\nLjudfiltren i OBS är kompatibla med surroundljud, fast stöd för VST-insticksmodulen garanteras inte." Basic.Settings.Audio.MultichannelWarning.Title="Aktivera surroundljud?" Basic.Settings.Audio.MultichannelWarning.Confirm="Är du säker på att du vill aktivera surroundljud?" Basic.Settings.Audio.Devices="Enheter" @@ -743,23 +762,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="Uppspelningsenhet" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Standard" Basic.Settings.Advanced.Audio.DisableAudioDucking="Inaktivera audio ducking i Windows" Basic.Settings.Advanced.StreamDelay="Strömfördröjning" -Basic.Settings.Advanced.StreamDelay.Duration="Varaktighet (sekunder)" +Basic.Settings.Advanced.StreamDelay.Duration="Varaktighet" Basic.Settings.Advanced.StreamDelay.Preserve="Behåll stoppunkten (öka fördröjningen) vid återanslutning" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Uppskattad minnesanvändning: %1 MB" Basic.Settings.Advanced.Network="Nätverk" Basic.Settings.Advanced.Network.BindToIP="Bind till IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Aktivera ny nätverkskod" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Låg latens-läge" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Fokusbeteende för kortkommando" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Inaktivera aldrig kortkommandon" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Inaktivera kortkommandon när fokus ligger i huvudfönstret" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Inaktivera kortkommandon när huvudfönstret inte har fokus" Basic.Settings.Advanced.AutoRemux="Remuxa automatiskt till mp4" Basic.Settings.Advanced.AutoRemux.MP4="(spela in som mkv)" Basic.AdvAudio="Avancerade ljudinställningar" Basic.AdvAudio.Name="Namn" Basic.AdvAudio.Volume="Volym" -Basic.AdvAudio.Mono="Nedmixa till mono" +Basic.AdvAudio.Mono="Mono" Basic.AdvAudio.Balance="Balans" -Basic.AdvAudio.SyncOffset="Sync Offset (ms)" +Basic.AdvAudio.SyncOffset="Synkroniseringsavvikelse" Basic.AdvAudio.Monitoring="Ljuduppspelning" Basic.AdvAudio.Monitoring.None="Monitor av" Basic.AdvAudio.Monitoring.MonitorOnly="Endast monitor (tysta utgång)" @@ -825,6 +847,7 @@ SceneItemHide="Dölj \"%1\"" OutputWarnings.NoTracksSelected="Du måste välja minst ett spår" OutputWarnings.MultiTrackRecording="Varning: En del format (t.ex. FLV) stöder inte flera spår för varje inspelning" OutputWarnings.MP4Recording="Varning: Inspelningar som sparas i MP4/MOV kommer inte kunna återhämtas om filen inte slutförs (t.ex. p.g.a. blåskärmar, strömavbrott, etc.). Om du vill spela in flera ljudspår, överväg att använda MKV och remuxa inspelningen till MP4/MOV när den är färdig (Arkiv → Remuxa inspelningar)" +OutputWarnings.CannotPause="Varning: Inspelningar kan inte pausas om inspelningskodaren är \"(Använd strömkodare)\"" FinalScene.Title="Radera scen" FinalScene.Text="Det måste finnas minst en scen." diff --git a/UI/data/locale/ta-IN.ini b/UI/data/locale/ta-IN.ini index a766569..61c7594 100644 --- a/UI/data/locale/ta-IN.ini +++ b/UI/data/locale/ta-IN.ini @@ -23,7 +23,6 @@ Settings="அமைப்புகள்" Display="காட்சித்திரை" Name="பெயர்" Exit="வெளியேறு" -Mixer="ஒலி கலவை" Browse="உலாவு" Mono="ஒற்றை ஒலி" Stereo="பல ஒலி" @@ -89,6 +88,7 @@ AlreadyRunning.LaunchAnyway="எப்படியும் தொடங்க DockCloseWarning.Title="நகரக்கூடிய சாளரத்தை மூடு" DockCloseWarning.Text="நீங்கள் ஒரு நகர்த்தக்கூடிய சாளரத்தை மூடியுள்ளீர்கள். நீங்கள் அதை மீண்டும் காண்பிக்க விரும்பினால், மெனு பட்டியில் காட்சி → டாக்ஸ் மெனுவைப் பயன்படுத்தவும்." + Auth.Authing.Title="அங்கீகரிக்கிறது..." Auth.Authing.Text="%1, உடன் அங்கீகரிக்கிறது, தயவுசெய்து காத்திருக்கவும்..." Auth.AuthFailure.Title="அங்கீகரிப்பு தோல்வி" @@ -135,7 +135,6 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="ஒன்று 60 அல்லத Basic.AutoConfig.VideoPage.CanvasExplanation="குறிப்பு: சுற்றளவு (அடிப்படை) தெளிவுதிறனானது நேரலை அல்லது பதிவுக்கான தெளிவுதிறனுக்கு சமமாக இருக்கவேண்டிய அவசியம் இல்லை. உங்கள் உண்மையான நேரலை அல்லது பதிவுக்கான தெளிவுதிறன் சுற்றளவு தெளிவுதிறனிலிருந்து ஆதார பயன்பாடு அல்லது பிட்ரேட் தேவைகளுக்கு குறைக்கப்பட்டு இருக்கலாம்." Basic.AutoConfig.StreamPage="அலை தகவல்" Basic.AutoConfig.StreamPage.SubTitle="உங்கள் அலை தகவலை உள்ளிடவும்" -Basic.AutoConfig.StreamPage.ConnectAccount="இணைய கணக்கு (விருப்ப)" Basic.AutoConfig.StreamPage.DisconnectAccount="கணக்கைத் துண்டிக்கவும்" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="கணக்கைத் துண்டிக்கவா?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="இந்த மாற்றம் உடனடியாக பொருந்தும். உங்கள் கணக்கு துண்டிக்க விரும்புகிறீர்களா?" @@ -235,6 +234,7 @@ ConfirmStop.Title="அலை நிறுத்த?" ConfirmStop.Text="அலை நிறுத்த நீங்கள் உறுதியாக இருக்கிறீர்களா?" + ConfirmExit.Title="OBS ஐ வெளியேற்றவா?" ConfirmExit.Text="OBS தற்போது செயலில் உள்ளது. அனைத்து அலைகள் / பதிவுகள் மூடப்படும். நிச்சயமாக வெளியேற விரும்புகிறீர்களா?" @@ -557,7 +557,6 @@ Basic.Settings.Output.Simple.Encoder.Software="மென்பொருள் (x Basic.Settings.Output.Simple.Encoder.Hardware.QSV="வன்பொருள் (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="வன்பொருள் (AMD)" Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="வன்பொருள் (NVENC)" -Basic.Settings.Output.RetryDelay="தாமதம் (நொடிகளில்) மீண்டும் முயற்சிக்கவும்" Basic.Settings.Output.MaxRetries="அதிகபட்ச முயற்சிகள்" Basic.Settings.Output.Advanced="மேம்பட்ட குறியாக்கி அமைப்புகளை இயக்கு" Basic.Settings.Output.CustomEncoderSettings="விருப்ப குறியாக்கி அமைப்புகள்" diff --git a/UI/data/locale/th-TH.ini b/UI/data/locale/th-TH.ini index 83af19c..335fe22 100644 --- a/UI/data/locale/th-TH.ini +++ b/UI/data/locale/th-TH.ini @@ -14,6 +14,7 @@ No="ไม่" Add="เพิ่ม" Remove="ลบ" Rename="เปลี่ยนชื่อ" +Interact="การโต้ตอบ" Filters="ฟิลเตอร์" Properties="คุณสมบัติ" MoveUp="เลื่อนขึ้น" @@ -25,14 +26,29 @@ Exit="ออก" Browse="เปิดหา" Mono="โมโน" Stereo="สเตอริโอ" +DroppedFrames="เฟรมลดลง %1 (%2%)" +StudioProgramProjector="แสดงผลแบบเต็มจอ (ตัวอย่าง)" PreviewProjector="แสดงผลแบบเต็มจอ (ตัวอย่าง)" +SceneProjector="แสดงผลแบบเต็มจอ (ฉาก)" +SourceProjector="แสดงผลแบบเต็มจอ (ทรัพยากร)" +StudioProgramWindow="แสดงผลแบบหน้าต่าง (โปรแกรม)" +PreviewWindow="แสดงผลแบบหน้าต่าง (ตัวอย่าง)" +SceneWindow="แสดงผลแบบหน้าต่าง (ฉาก)" +SourceWindow="แสดงผลแบบหน้าต่าง (ทรัพยากร)" +MultiviewProjector="แสดงผลหลายหน้าจอ (เต็มจอ)" +MultiviewWindowed="แสดงผลหลายหน้าจอ (หน้าต่าง)" Clear="ล้าง" Revert="กลับค่าเดิม" Show="แสดง" Hide="ซ่อน" +UnhideAll="ยกเลิกการซ่อนทั้งหมด" Untitled="ไม่มีชื่อ" New="ใหม่" +Duplicate="ทำสำเนา" Enable="เปิดใช้งาน" +DisableOSXVSync="ไม่ใช้ OSX V-Sync" +ResetOSXVSyncOnExit="คืนค่า OSX V-Sync เมื่อออก" +HighResourceUsage="การเข้ารหัสเกินขีดจำกัด! โปรดปรับลดการกำหนดค่าวีดีโอ หรือใช้รูปแบบการเข้ารหัสอื่นที่เร็วขึ้น" Transition="เปลี่ยนภาพ" QuickTransitions="ช่วงการเปลี่ยนภาพอย่างรวดเร็ว" Left="ซ้าย" @@ -44,6 +60,7 @@ Hours="ชั่วโมง" Minutes="นาที" Seconds="วินาที" Deprecated="ไม่ใช้งาน" +ReplayBuffer="รีเพลย์บัพเฟอร์" Import="นําเข้า" Export="ส่งออก" Copy="คัดลอก" @@ -53,18 +70,41 @@ PasteDuplicate="วาง (ซ้ำ)" Next="ถัดไป" Back="กลับ" Defaults="ค่ามาตรฐาน" +HideMixer="ซ่อนในมิกซ์เซอร์" +TransitionOverride="แทนที่การสลับฉาก" None="ไม่มี" StudioMode.Preview="แสดงตัวอย่าง" StudioMode.Program="โปรแกรม" +ShowInMultiview="แสดงในการแสดงผลหลายหน้าจอ" +VerticalLayout="เค้าโครงแนวตั้ง" Group="กลุ่ม" +DoNotShowAgain="ไม่ต้องแสดงอีก" +Default="(ค่าเริ่มต้น)" +Calculating="กำลังคำนวณ..." AlreadyRunning.Title="OBS กำลังทำงานอยู่" +AlreadyRunning.LaunchAnyway="ยังไงก็จะเปิด" + +DockCloseWarning.Title="ปิดหน้าต่างเครื่องมือ" +DockCloseWarning.Text="คุณกำลังจะปิดหน้าต่างเครื่องมือ ถ้าคุณต้องการให้มันแสดงอีกครั้ง ให้ไปที่แถบเมนูแล้วเลือกเมนู มุมมอง → หน้าต่างเครื่องมือ" +Auth.Authing.Title="การตรวจสอบสิทธิ์" +Auth.Authing.Text="กำลังตรวจสอบสิทธิ์ไปยัง %1, โปรดรอสักครู่..." +Auth.AuthFailure.Title="การตรวจสอบล้มเหลว" +Auth.InvalidScope.Title="จำเป็นต้องมีการตรวจสอบสิทธิ์" +Auth.LoadingChannel.Title="กำลังโหลดรายละเอียดของช่อง..." +Auth.LoadingChannel.Text="กำลังโหลดรายละเอียดของช่องสำหรับ %1, โปรดรอสักครู่..." +Auth.ChannelFailure.Title="ไม่สามารถโหลดช่อง" +Auth.ChannelFailure.Text="ไม่สามารถโหลดรายละเอียดของช่องสำหรับ %1\n\n%2: %3" +Auth.Chat="ห้องสนทนา" +Auth.StreamInfo="รายละเอียดการสตรีม" Copy.Filters="คัดลอก Filters" Paste.Filters="วาง Filters" +BrowserPanelInit.Title="กำลังเริ่มต้นเบราว์เซอร์..." +BrowserPanelInit.Text="กำลังเริ่มต้นเบราว์เซอร์, โปรดรอสักครู่..." BandwidthTest.Region="ภูมิภาค" BandwidthTest.Region.US="สหรัฐอเมริกา" @@ -73,6 +113,7 @@ BandwidthTest.Region.Asia="เอเชีย" BandwidthTest.Region.Other="อื่นๆ" Basic.FirstStartup.RunWizard="คุณต้องการเรียกใช้ตัวช่วยสร้างการกำหนดค่าอัตโนมัติ นอกจากนี้คุณด้วยตนเองสามารถกำหนดค่าการตั้งค่า โดยคลิกปุ่มการตั้งค่าในหน้าต่างหลัก" +Basic.FirstStartup.RunWizard.NoClicked="ถ้าคุณเปลี่ยนใจ คุณสามารถเรียกใช้ตัวช่วยการกำหนดค่าอัตโนมัติได้ตลอดเวลาจากแถบเมนู เครื่องมือ" Basic.AutoConfig="การปรับแต่งอัตโนมัติ" Basic.AutoConfig.ApplySettings="ใช้การตั้งค่า" @@ -80,12 +121,28 @@ Basic.AutoConfig.StartPage="ข้อมูลการใช้งาน" Basic.AutoConfig.StartPage.SubTitle="ระบุสิ่งที่คุณต้องการใช้โปรแกรมสำหรับ" Basic.AutoConfig.StartPage.PrioritizeStreaming="เพิ่มประสิทธิภาพสำหรับการสตรีม บันทึกเป็นรอง" Basic.AutoConfig.StartPage.PrioritizeRecording="เพิ่มประสิทธิภาพสำหรับการบันทึก ฉันจะไม่สามารถส่งข้อมูล Steam" +Basic.AutoConfig.VideoPage="กำหนดค่าวีดีโอ" +Basic.AutoConfig.VideoPage.SubTitle="กำหนดการตั้งค่าวีดีโอที่คุณต้องการใช้งาน" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="ใช้ค่าปัจจุบัน (%1x%2)" +Basic.AutoConfig.VideoPage.BaseResolution.Display="จอภาพ %1 (%2x%3)" +Basic.AutoConfig.VideoPage.FPS.UseCurrent="ใช้ค่าปัจจุบัน (%1)" +Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="เลือก 60 หรือ 30, ถ้าเป็นไปได้เลือก 60" +Basic.AutoConfig.VideoPage.FPS.PreferHighRes="เลือก 60 หรือ 30, ต้องการความละเอียดสูง" +Basic.AutoConfig.VideoPage.CanvasExplanation="หมายเหตุ: ความละเอียดของพื้นที่หลัก ไม่จำเป็นต้องเหมือนกับความละเอียดที่คุณจะสตรีม หรือบันทึก การสตรีมหรือการบันทึกจริง อาจจะลดขนาดลงจากความละเอียดของพื้นที่หลัก เพื่อลดการใช้ทรัพยากร หรือความต้องการของบิตเรต" +Basic.AutoConfig.StreamPage="รายละเอียดการสตรีม" Basic.AutoConfig.StreamPage.SubTitle="กรุณากรอกข้อมูลสตรีม" +Basic.AutoConfig.StreamPage.DisconnectAccount="ตัดการเชื่อมต่อบัญชี" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="ตัดการเชื่อมต่อบัญชี?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="การเปลี่ยนแปลงนี้จะมีผลทันที คุณแน่ใจหรือไม่ว่าต้องการตัดการเชื่อมต่อบัญชีของคุณ?" +Basic.AutoConfig.StreamPage.UseStreamKey="ใช้รหัสสตรีม" Basic.AutoConfig.StreamPage.Service="บริการ" Basic.AutoConfig.StreamPage.Service.ShowAll="แสดงทั้งหมด..." +Basic.AutoConfig.StreamPage.Service.Custom="กำหนดเอง..." Basic.AutoConfig.StreamPage.Server="เซิร์ฟเวอร์" Basic.AutoConfig.StreamPage.StreamKey="รหัสสตรีม" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(เชื่อมโยง)" +Basic.AutoConfig.StreamPage.PerformBandwidthTest="ทดสอบการประเมินค่าบิตเรตกับแบนด์วิดท์ (อาจใช้เวลาสักพัก)" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding="กำหนดการเข้ารหัสด้วยฮาร์ดแวร์" Basic.Stats="สถานะ" Basic.Stats.CPUUsage="การใช้ CPU" @@ -102,15 +159,33 @@ Updater.UpdateNow="อัปเดตเดี๋ยวนี้" Updater.RemindMeLater="เตือนฉันในภายหลัง" Updater.Skip="ข้ามรุ่น" +QuickTransitions.EditProperties="ทำสำเนาทรัพยากร" +QuickTransitions.HotkeyName="สลับฉากอย่างรวดเร็ว: %1" +Basic.AddTransition="เพิ่มรูปแบบการสลับฉาก" +Basic.RemoveTransition="ลบรูปแบบการสลับฉาก" +Basic.TransitionProperties="กำหนดค่ารูปแบบการสลับฉาก" +Basic.SceneTransitions="รูปแบบการสลับฉาก" +Basic.TransitionDuration="ระยะเวลา" +Basic.TogglePreviewProgramMode="โหมดสตูดิโอ" +TransitionNameDlg.Text="โปรดกำหนดชื่อสำหรับรูปแบบการสลับฉาก" +TransitionNameDlg.Title="ชื่อรูปแบบการสลับฉาก" TitleBar.Profile="โปรไฟล์" +TitleBar.Scenes="ฉาก" NameExists.Title="มีผู้ใช้นี้ในระบบแล้ว" +NameExists.Text="ชื่อนี้ถูกใช้แล้ว" NoNameEntered.Title="กรุณาใส่ชื่อให้ถูกต้อง" +NoNameEntered.Text="คุณจำเป็นต้องกำหนดชื่อ" +ConfirmStart.Title="เริ่มทำการสตรีม?" +ConfirmStart.Text="คุณแน่ใจไหมว่าต้องการเริ่มการสตรีม?" + +ConfirmStop.Title="หยุดการสครีม?" +ConfirmStop.Text="คุณแน่ใจไหมว่าต้องการที่จะหยุดการสตรีม?" diff --git a/UI/data/locale/tl-PH.ini b/UI/data/locale/tl-PH.ini index 2067ffd..f2f1d24 100644 --- a/UI/data/locale/tl-PH.ini +++ b/UI/data/locale/tl-PH.ini @@ -23,7 +23,6 @@ Settings="Mga Setting" Display="Ipakita" Name="Pangalan" Exit="Lumabas" -Mixer="Mixer" Browse="Browse" Mono="Mono" Stereo="Stereo" @@ -85,6 +84,7 @@ AlreadyRunning.LaunchAnyway="Ilunsad pa rin" + Copy.Filters="Kopyahin ang mga Panala" Paste.Filters="I-paste ang mga Panala" @@ -206,6 +206,7 @@ ConfirmStop.Title="Itigil ang pag-stream?" ConfirmStop.Text="Sigurado ka bang gusto mong itigil ang pag-stream?" + ConfirmExit.Title="Lumabas sa OBS?" ConfirmExit.Text="Ang OBS ang kasalukuyang aktibo. Ang lahat ng pag-stream/pagrerekord ay magsasara. Sigurado ka bang gusto mong lumabas?" @@ -518,7 +519,6 @@ Basic.Settings.Output.Mode.Simple="Payak" Basic.Settings.Output.Mode.Adv="Mas Mahusay" Basic.Settings.Output.Mode.FFmpeg="FFmpeg Output" Basic.Settings.Output.UseReplayBuffer="Paganahin ang Replay Buffer" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Pinakamataas na Oras ng Replay (Segundo)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Pinakamataas na Memorya (Megabytes)" Basic.Settings.Output.ReplayBuffer.Estimate="Tantiyang gamit sa memorya: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Hindi matantiya ang gamit sa memorya. Mangyari lamang mag-takda ng pinakamataas na limitasyon sa memorya." @@ -545,7 +545,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 mababa ang n Basic.Settings.Output.VideoBitrate="Video Bitrate" Basic.Settings.Output.AudioBitrate="Audio Bitrate" Basic.Settings.Output.Reconnect="Pakusa Makipagkonek muli" -Basic.Settings.Output.RetryDelay="Subukan muling Maantala (Mga segundo)" Basic.Settings.Output.MaxRetries="Pinakamaraming Retries" Basic.Settings.Output.Advanced="Paganahin Pauna ang Enkoder Settings" Basic.Settings.Output.CustomEncoderSettings="Pasadyang enkoder Mga setting" @@ -615,7 +614,7 @@ Basic.Settings.Video.DisableAero="Huwag paganahin ang Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (Pinakamabilis, ngunit hindi malinaw pag nag-scale)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (Matalas na pag-scale, 16 na mga halimbawa)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Pinatalas na pag-scale, 32 na mga halimbawa)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Pinatalas na pag-scale, 36 na mga halimbawa)" Basic.Settings.Audio="Audio" Basic.Settings.Audio.SampleRate="Sample Rate" @@ -624,7 +623,7 @@ Basic.Settings.Audio.MeterDecayRate.Fast="Mabilis" Basic.Settings.Audio.MeterDecayRate.Medium="Medium (Type I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Mabagal (Type II PPM)" Basic.Settings.Audio.MultiChannelWarning.Enabled="BABALA: Naka-enable ang surround sound audio." -Basic.Settings.Audio.MultichannelWarning="Kung nagsi-stream, tingnan kung ang streaming service ay sinusuportahan ang parehong surround sound ingest pat ang surround sound playback. Ang Twitch, Facebook 360 Live, Mixer RTMP, Smashcast ay mga halimbawa kung saan ang surround sound ay sinusuportahan ng buo. Kahit na ang Facebook Live at YouTube live ay parehong tumatanggap ng surround ingest, ang Facebook Live ay nagda-downmix sa stereo, at ang YouTube Live ay nagpapakita lamang ng dalawang channel. \n\nAng OBS audio na mga filter ay akma sa surround sound, pero ang suporta sa VST plugin ay hindi garantisado." +Basic.Settings.Audio.MultichannelWarning="Kung nagsi-stream, tingnan kung ang streaming service ay sinusuportahan ang parehong surround sound ingest pat ang surround sound playback. Ang Facebook 360 Live, Mixer RTMP, Smashcast ay mga halimbawa kung saan ang surround sound ay sinusuportahan ng buo. Kahit na ang Facebook Live at YouTube live ay parehong tumatanggap ng surround ingest, ang Facebook Live ay nagda-downmix sa stereo, at ang YouTube Live ay nagpapakita lamang ng dalawang channel. \n\nAng OBS audio na mga filter ay akma sa surround sound, pero ang suporta sa VST plugin ay hindi garantisado." Basic.Settings.Audio.MultichannelWarning.Title="Mapapagana ba ang tunog ng palibot ng audio?" Basic.Settings.Audio.MultichannelWarning.Confirm="Sigurado ka ba na gusto mong paganahin ang tunog ng palibot ng audio?" Basic.Settings.Audio.EnablePushToMute="Paganahin Itulak-para-ma-i-mute" @@ -648,7 +647,6 @@ Basic.Settings.Advanced.Video.ColorRange.Full="Buo" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Default" Basic.Settings.Advanced.Audio.DisableAudioDucking="Huwag paganahin ang audio ducking ng Windows" Basic.Settings.Advanced.StreamDelay="Antala sa Pag-stream" -Basic.Settings.Advanced.StreamDelay.Duration="Bilis (segundo)" Basic.Settings.Advanced.StreamDelay.Preserve="Balikan kung saan huling pinutol (dagadagan ang antala) pagka konekta muli" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Tantiyang Gamit sa Memorya: %1 MB" Basic.Settings.Advanced.Network="Network" @@ -658,8 +656,6 @@ Basic.Settings.Advanced.Network.EnableLowLatencyMode="Mode para sa low latency" Basic.AdvAudio="Pinahusay na mga Katangian ng Audio" Basic.AdvAudio.Name="Pangalan" -Basic.AdvAudio.Mono="I-downmix para maging Mono" -Basic.AdvAudio.SyncOffset="Sync Offset (ms)" Basic.AdvAudio.Monitoring="Pagsubaybay sa Audio" Basic.AdvAudio.Monitoring.None="Naka-off ang Monitor" Basic.AdvAudio.Monitoring.MonitorOnly="Monitor Lamang (naka-mute na output)" diff --git a/UI/data/locale/tr-TR.ini b/UI/data/locale/tr-TR.ini index 227ab87..825a477 100644 --- a/UI/data/locale/tr-TR.ini +++ b/UI/data/locale/tr-TR.ini @@ -23,7 +23,6 @@ Settings="Ayarlar" Display="Ekran" Name="İsim" Exit="Çıkış" -Mixer="Karıştırıcı" Browse="Gözat" Mono="Mono" Stereo="Stereo" @@ -91,6 +90,9 @@ AlreadyRunning.LaunchAnyway="Yine de Başlat" DockCloseWarning.Title="Yuvalanabilir Pencere Kapatma" DockCloseWarning.Text="Az önce yuvalanabilir bir pencere kapattınız. Eğer tekrardan göstermek istiyorsanız, Menü çubuğundan Görüntüle → Paneller menüsünü kullanın." +ExtraBrowsers.Info="Onlara isim ve URL vererek yuva ekleyin, ardından yuvaları açmak için Uygulaya ve Kapata tıklayın. Herhangi bir zaman yuva ekleyebilir ya da kaldırabilirsiniz." +ExtraBrowsers.DockName="Yuva Adı" + Auth.Authing.Title="Kimlik doğrulanıyor..." Auth.Authing.Text="%1 ile doğrulanıyor, lütfen bekleyin..." Auth.AuthFailure.Title="Kimlik Doğrulaması Başarısız" @@ -107,6 +109,7 @@ TwitchAuth.Stats="Twitch İstatistikleri" TwitchAuth.Feed="Twitch Etkinlik akışı" TwitchAuth.TwoFactorFail.Title="Yayın anahtarı sorgulanamadı" TwitchAuth.TwoFactorFail.Text="OBS Twitch hesabına bağlanamadı. Lütfen iki-faktörlü doğrulamanın Twitch güvenlik ayarlarında ayarlandığından emin olun Bu yayın yapmanız için gereklidir." +RestreamAuth.Channels="Restream Kanalları" Copy.Filters="Filtreleri Kopyala" Paste.Filters="Filtreleri Yapıştır" @@ -139,7 +142,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 ya da 30, ama yüksek çözün Basic.AutoConfig.VideoPage.CanvasExplanation="Not: Tuval (taban) çözünürlüğü yayın veya kayıt yapacağınız çözünürlük ile aynı olmak zorunda değildir. Gerçek yayın/kayıt çözünürlüğünüz kaynak kullanımı ve bit hızı gereksinimlerini düşürmek için tuval çözünürlüğünüzden aşağıya boyutlandırılabilir." Basic.AutoConfig.StreamPage="Yayın Bilgisi" Basic.AutoConfig.StreamPage.SubTitle="Lütfen yayın bilginizi girin" -Basic.AutoConfig.StreamPage.ConnectAccount="Hesabı Bağla (isteğe bağlı)" +Basic.AutoConfig.StreamPage.ConnectAccount="Hesap Bağla (önerilir)" Basic.AutoConfig.StreamPage.DisconnectAccount="Hesap Bağlantısını Kes" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Hesap Bağlantısı Kesilsin Mi?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Bu değişiklik hemen uygulanacaktır. Hesabınızın bağlantısını kesmek istediğinize emin misiniz?" @@ -189,6 +192,7 @@ Basic.Stats.Status.Inactive="Etkin değil" Basic.Stats.DroppedFrames="Atlanan Kareler (Ağ)" Basic.Stats.MegabytesSent="Toplam Veri Çıkışı" Basic.Stats.Bitrate="Bit Hızı" +Basic.Stats.DiskFullIn="Disk dolacak (yaklaşık)" ResetUIWarning.Title="Kullanıcı arayüzünü sıfırlamak istediğinize emin misiniz?" ResetUIWarning.Text="Kullanıcı arayüzünü sıfırlamak, ek panelleri gizleyecektir. Panellerin görünmelerini istiyorsanız, bu panelleri görünüm menüsünden etkinleştirebilirsiniz.\n\nKullanıcı arayüzünü sıfırlamak istediğinize emin misiniz?" @@ -239,6 +243,9 @@ ConfirmStart.Text="Yayını gerçekten başlatmak istiyor musunuz?" ConfirmStop.Title="Yayın Durdurulsun Mu?" ConfirmStop.Text="Yayını gerçekten durdurmak istiyor musunuz?" +ConfirmStopRecord.Title="Kaydı Durdur?" +ConfirmStopRecord.Text="Kaydı durdurmak istediğinizden emin misiniz?" + ConfirmBWTest.Title="Bant genişliği testini başlat?" ConfirmBWTest.Text="OBS'i bant genişliği test modunda yapılandırdınız. Bu mod, kanalınız yayına girmeden ağ testi yapmanıza olanak sağlar. Test tamamlandıktan sonra, izleyicilerin yayını görebilmesi için bu modu devre dışı bırakmanız gerekecektir.\n\nDevam etmek istiyor musunuz?" @@ -254,6 +261,8 @@ Output.StartRecordingFailed="Kayıt başlatılamadı" Output.StartReplayFailed="Tekrar oynatma arabelleği başlatılamadı" Output.StartFailedGeneric="Çıkışı başlatma başarısız oldu. Detaylar için lütfen günlüğe bakın: \n\nNVENC veya AMD kodlayıcılarını kullanıyorsanız, video sürücülerinin güncel olduğundan emin olun." +Output.ReplayBuffer.PauseWarning.Title="Durdurulduğunda tekrarlar kaydedilemez" +Output.ReplayBuffer.PauseWarning.Text="Dikkat: Kayıt durdurulmuşken tekrarlar kaydedilemez." Output.ConnectFail.Title="Bağlantı kurulamadı" Output.ConnectFail.BadPath="Bağlantı adresiniz geçersiz. Ayarlarınızı kontrol edin ve geçerli bir adres giriniz." @@ -443,6 +452,8 @@ Basic.Main.StartRecording="Kaydı Başlat" Basic.Main.StartReplayBuffer="Tekrar Oynatma Arabelleğini Başlat" Basic.Main.StartStreaming="Yayını Başlat" Basic.Main.StopRecording="Kaydı Durdur" +Basic.Main.PauseRecording="Kaydı Duraklat" +Basic.Main.UnpauseRecording="Kaydı Devam Ettir" Basic.Main.StoppingRecording="Kayıt Durduruluyor..." Basic.Main.StopReplayBuffer="Tekrar Oynatma Arabelleğini Durdur" Basic.Main.StoppingReplayBuffer="Tekrar Oynatma Arabelleği Durduruluyor..." @@ -501,6 +512,7 @@ Basic.MainMenu.View.Toolbars="Araç Çubukları (&T)" Basic.MainMenu.View.Docks="Paneller" Basic.MainMenu.View.Docks.ResetUI="Arayüzü Sıfırla" Basic.MainMenu.View.Docks.LockUI="Arayüzü Kilitle" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Özel Tarayıcı Yuvaları..." Basic.MainMenu.View.Toolbars.Listboxes="&Liste Kutuları" Basic.MainMenu.View.SceneTransitions="Sahne Geçişleri (&C)" Basic.MainMenu.View.StatusBar="Durum Çubuğu (&S)" @@ -542,7 +554,8 @@ Basic.Settings.General.Language="Dil" Basic.Settings.General.EnableAutoUpdates="Başlangıçta güncellemeleri otomatik olarak denetle" Basic.Settings.General.OpenStatsOnStartup="Başlangıçta istatistikler iletişim kutusunu aç" Basic.Settings.General.WarnBeforeStartingStream="Yayın başlatırken onay iletişim kutusunu göster" -Basic.Settings.General.WarnBeforeStoppingStream="Yayın durduğunda onay iletişim kutusunu göster" +Basic.Settings.General.WarnBeforeStoppingStream="Yayın durdulacağı zaman onay kutusunu göster" +Basic.Settings.General.WarnBeforeStoppingRecord="Kaydı durdururken onay kutusunu göster" Basic.Settings.General.Projectors="Projektörler" Basic.Settings.General.HideProjectorCursor="Projektörler üzerinde imleci gizle" Basic.Settings.General.ProjectorAlwaysOnTop="Projektörleri her zaman üstte tut" @@ -590,12 +603,15 @@ Basic.Settings.Output.Encoder="Kodlayıcı" Basic.Settings.Output.SelectDirectory="Kayıt Dizinini Seçin" Basic.Settings.Output.SelectFile="Kayıt Dosyasını Seçin" Basic.Settings.Output.EnforceBitrate="Yayın hizmetini bit hızı sınırlarına zorla" +Basic.Settings.Output.DynamicBitrate="Akışı yönetmek için bit hızını değişkenli bir biçimde değiştir" +Basic.Settings.Output.DynamicBitrate.Beta="Akışı yönetmek için bit hızını değişkenli bir biçimde değiştir (Beta)" +Basic.Settings.Output.DynamicBitrate.TT="Akışı azaltmak için kare hızını düşürmek yerine, bit hızını değişkenli bir biçimde değiştirir.\n\nBunun, eğer ani bir akış olursa izleyiciler için gecikme yaratabileceğini unutmayın.\nEğer bit hızı düşerse, yenilenmesi bir kaç dakika alabilir.\n\nŞu anlık sadece RTMP için destekli." Basic.Settings.Output.Mode="Çıkış modu" Basic.Settings.Output.Mode.Simple="Basit" Basic.Settings.Output.Mode.Adv="Gelişmiş" Basic.Settings.Output.Mode.FFmpeg="FFmpeg Çıkışı" Basic.Settings.Output.UseReplayBuffer="Tekrar Oynatma Arabelleğini Etkinleştir" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksimum Yeniden Oynatma Süresi (Seconds)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksimum Tekrar Süresi" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maksimum Bellek (Megabayt)" Basic.Settings.Output.ReplayBuffer.Estimate="Tahmini bellek kullanımı: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Bellek kullanımını tahmin edemezsin. Lütfen maksimum bellek sınırını ayarlayın." @@ -610,6 +626,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Aynı Kaliteye Yakın, Büyük Basic.Settings.Output.Simple.RecordingQuality.Lossless="Kayıpsız Kalite, Çok Büyük Dosya Boyutu" Basic.Settings.Output.Simple.Warn.VideoBitrate="Uyarı: Yayın video bit hızı %1 olarak ayarlanacak, bu şu anki yayın hizmeti için üst sınırdır. Eğer %1 değerinin üstüne çıkmak istediğinizden eminseniz, gelişmiş kodlayıcı seçeneklerini etkinleştirin ve \"Yayın hizmetini bit hızı sınırlarına zorla\" işaretini kaldırın." Basic.Settings.Output.Simple.Warn.AudioBitrate="Uyarı: Yayın audio bit hızı %1 olarak ayarlanacak, bu şu anki yayın hizmeti için üst sınırdır. Eğer %1 değerinin üstüne çıkmak istediğinizden eminseniz, gelişmiş kodlayıcı seçeneklerini etkinleştirin ve \"Yayın hizmetini bit hızı sınırlarına zorla\" işaretini kaldırın." +Basic.Settings.Output.Simple.Warn.CannotPause="Dikkat: Kayıt kalitesi \"Yayın ile aynı\"ya ayarlanmışken kayıtlar durdurulamaz." Basic.Settings.Output.Simple.Warn.Encoder="Uyarı: Bir yazılım kodlayıcı ile yayın kalitesinden farklı kayıt yapmak eğer aynı anda hem kayıt hem de yayın yapıyorsanız ilave CPU kullanımı gerektirecektir." Basic.Settings.Output.Simple.Warn.Lossless="Uyarı: Kayıpsız kalite muazzam büyük dosya boyutları oluşturur! Kayıpsız kalite, yüksek çözünürlüklerde ve kare hızlarında, dakikada 7 gigabyte'a kadar disk alanı kullanabilir. Kayıpsız, kullanılabilir disk alanınız çok büyük değilse, uzun kayıtlar için tavsiye edilmez." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Kayıpsız kalitede kullanmak istediğinizden emin misiniz?" @@ -622,7 +639,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Yazılım (x264 düşük CP Basic.Settings.Output.VideoBitrate="Video Bit Hızı" Basic.Settings.Output.AudioBitrate="Ses Bit Hızı" Basic.Settings.Output.Reconnect="Otomatik Yeniden Bağlan" -Basic.Settings.Output.RetryDelay="Yeniden Deneme Gecikmesi (saniye)" +Basic.Settings.Output.RetryDelay="Tekrar Gecikmesi" Basic.Settings.Output.MaxRetries="Maksimum Deneme Sayısı" Basic.Settings.Output.Advanced="Gelişmiş Kodlayıcı Ayarlarını Etkinleştir" Basic.Settings.Output.EncoderPreset="Kodlayıcı Hazır Ayarı" @@ -693,11 +710,12 @@ Basic.Settings.Video.DisableAero="Aero'yu Devre Dışı Bırak" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (En hızlı, ancak boyutlandırmada bulanık görüntü)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (Keskinleştirilmiş boyutlandırma, 16 örnek)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Keskinleştirilmiş boyutlandırma, 32 örnek)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Keskinleştirilmiş boyutlandırma, 36 örnek)" Basic.Settings.Audio="Ses" Basic.Settings.Audio.SampleRate="Örnekleme Sıklığı" Basic.Settings.Audio.Channels="Kanallar" +Basic.Settings.Audio.Meters="Metre" Basic.Settings.Audio.MeterDecayRate.Fast="Hızlı" Basic.Settings.Audio.MeterDecayRate.Medium="Orta (Tür I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Yavaş (Tür II PPM)" @@ -705,7 +723,7 @@ Basic.Settings.Audio.PeakMeterType="Tepe Ölçer Türü" Basic.Settings.Audio.PeakMeterType.SamplePeak="Örnek Tepe" Basic.Settings.Audio.PeakMeterType.TruePeak="Gerçek Tepe (Daha yüksek CPU kullanımı)" Basic.Settings.Audio.MultiChannelWarning.Enabled="Uyarı: Surround ses etkin." -Basic.Settings.Audio.MultichannelWarning="Yayın yapılıyorsa, yayın hizmetinizin hem surround ses alınımını hem de surround ses geri oynatımını desteklediğinden emin olun. Twitch, Facebook 360 Live, Karıştırıcı RTMP, Smashcast, surround sesin tam desteklendiği örneklerdir. Facebook Live'ın ve YouTube Live'ın her ikisi de surround alınımını desteklese de, Facebook Live stereo'ya indirger, ve YouTube Live sadece iki kanal oynatır.\n\nOBS ses filtreleri surround sesle uyumludur, ancak VST eklenti desteği kesin değildir." +Basic.Settings.Audio.MultichannelWarning="Yayın yapılıyorsa, yayın hizmetinizin hem surround ses alınımını hem de surround ses geri oynatımını desteklediğinden emin olun. Facebook 360 Live, Karıştırıcı RTMP, Smashcast, surround sesin tam desteklendiği örneklerdir. Facebook Live'ın ve YouTube Live'ın her ikisi de surround alınımını desteklese de, Facebook Live stereo'ya indirger, ve YouTube Live sadece iki kanal oynatır.\n\nOBS ses filtreleri surround sesle uyumludur, ancak VST eklenti desteği kesin değildir." Basic.Settings.Audio.MultichannelWarning.Title="Surround ses etkinleştirilsin mi?" Basic.Settings.Audio.MultichannelWarning.Confirm="Surround sesi etkinleştirmek istediğinize emin misiniz?" Basic.Settings.Audio.Devices="Cihazlar" @@ -740,23 +758,23 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="İzleme Aygıtı" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Varsayılan" Basic.Settings.Advanced.Audio.DisableAudioDucking="Windows ses alçaltmasını devre dışı bırak" Basic.Settings.Advanced.StreamDelay="Yayın Gecikmesi" -Basic.Settings.Advanced.StreamDelay.Duration="Süre (saniye)" +Basic.Settings.Advanced.StreamDelay.Duration="Süre" Basic.Settings.Advanced.StreamDelay.Preserve="Tatbik ederken kesim noktasını (gecikme artışı) koru" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Tahmini Bellek Kullanımı: %1 MB" Basic.Settings.Advanced.Network="Ağ" Basic.Settings.Advanced.Network.BindToIP="IP Bağla" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Yeni ağ kodunu etkinleştir" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Düşük gecike modu" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Kısayol tuşlarını asla devre dışı bırakma" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Ana pencere odaktayken kısayol tuşlarını devre dışı bırak" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Pencere odakta değilken kısayol tuşlarını devre dışı bırak" Basic.Settings.Advanced.AutoRemux="Otomatik olarak mp4'e remux et" Basic.Settings.Advanced.AutoRemux.MP4="(mkv olarak kaydet)" Basic.AdvAudio="Gelişmiş Ses Özellikleri" Basic.AdvAudio.Name="İsim" Basic.AdvAudio.Volume="Ses" -Basic.AdvAudio.Mono="Mono Karıştırmayı Azalt" Basic.AdvAudio.Balance="Denge" -Basic.AdvAudio.SyncOffset="Eşitleme Uzaklığı (ms)" Basic.AdvAudio.Monitoring="Ses İzleme" Basic.AdvAudio.Monitoring.None="Ekran Kapalı" Basic.AdvAudio.Monitoring.MonitorOnly="Sadece Ekran (sessiz çıkış)" @@ -822,6 +840,7 @@ SceneItemHide="'%1' Gizle" OutputWarnings.NoTracksSelected="En az bir ses parçası seçmelisiniz" OutputWarnings.MultiTrackRecording="Uyarı: Bazı biçimler (FLV gibi) kayıt başına birden fazla parçayı desteklemez" OutputWarnings.MP4Recording="Uyarı: MP4/MOV için kaydedilen kayıtları dosya (örneğin BSODs sonucu olarak, güç kayıp, vb.) kesinleşmiş değil varsa geri almanız mümkün olmayacaktır. Kaydetmek istediğiniz birden çok ses parçaları bu bittikten sonra MKV ve MP4/MOV için kayıt remux kullanmayı göz önünde bulundurun (dosya → Remux kayıtları)" +OutputWarnings.CannotPause="Dikkat: Kayıt kodlayıcısı \"(Yayın kodlayıcısını kullan)\"a ayarlanmışken kayıtlar durdurulamaz" FinalScene.Title="Sahneyi Sil" FinalScene.Text="En az bir sahne olması gerekiyor." diff --git a/UI/data/locale/uk-UA.ini b/UI/data/locale/uk-UA.ini index 92ca8d0..f9bde32 100644 --- a/UI/data/locale/uk-UA.ini +++ b/UI/data/locale/uk-UA.ini @@ -23,7 +23,7 @@ Settings="Налаштування" Display="Екран" Name="Ім'я" Exit="Вихід" -Mixer="Мікшер" +Mixer="Мікшер Аудіо" Browse="Огляд" Mono="Моно" Stereo="Стерео" @@ -91,6 +91,10 @@ AlreadyRunning.LaunchAnyway="Все одно запустити" DockCloseWarning.Title="Закриття панелі інтерфейсу" DockCloseWarning.Text="Ви щойно закрили одну з панелей інтерфейсу. Якщо ви бажаєте вивести її знов - використайте опції з головного меню Вид → Панелі інтерфейсу." +ExtraBrowsers="Панелі браузера" +ExtraBrowsers.Info="Додавайте панелі через надання їм назви та URL-адреси. Натисніть Застосувати або Закрити щоб відкрити щойно додані панелі. Список можна редагувати." +ExtraBrowsers.DockName="Назва панелі" + Auth.Authing.Title="Перевірка автентичності..." Auth.Authing.Text="Перевірка автентичності з %1, будь ласка зачекайте..." Auth.AuthFailure.Title="Помилка автентифікації" @@ -106,6 +110,8 @@ Auth.StreamInfo="Інформація про Трансляцію" TwitchAuth.Stats="Статистика Twitch" TwitchAuth.Feed="Стрічка активності Twitch" TwitchAuth.TwoFactorFail.Title="Не вдалося запросити ключ трансляції" +TwitchAuth.TwoFactorFail.Text="OBS не може підключитись до вашого облікового запису Twitch. Будь ласка, переконайтеся, що дворівневу автентифікацію було встановлено у вашому Twitch security settings бо це вимога для здійснення трансляцій." +RestreamAuth.Channels="Канали Restream" Copy.Filters="Копіювати фільтри" Paste.Filters="Вставити фільтри" @@ -138,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 або 30, але краще в Basic.AutoConfig.VideoPage.CanvasExplanation="Примітка: Роздільна здатність (Полотно), не обов'язково повинно дорівнювати роздільної здатності з якою ви плануєте транслювати або записувати. Роздільну здатність фактичної трансляції/запису може бути зменшено від роздільною здатності полотна задля зменшення використання ресурсів або зменшення вимог до бітрейту." Basic.AutoConfig.StreamPage="Інформація про Трансляцію" Basic.AutoConfig.StreamPage.SubTitle="Будь ласка, введіть інформацію щодо вашої Трансляції" -Basic.AutoConfig.StreamPage.ConnectAccount="Підключити обліковий запис (за бажанням)" +Basic.AutoConfig.StreamPage.ConnectAccount="Підключити обліковий запис (рекомендується)" Basic.AutoConfig.StreamPage.DisconnectAccount="Відключити обліковий запис" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Відключити обліковий запис?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Ці зміни буде застосовано негайно. Ви дійсно бажаєте відключити обліковий запис?" @@ -188,6 +194,7 @@ Basic.Stats.Status.Inactive="Неактивно" Basic.Stats.DroppedFrames="Пропущено кадрів (мережа)" Basic.Stats.MegabytesSent="Загалом до Виводу" Basic.Stats.Bitrate="Бітрейт" +Basic.Stats.DiskFullIn="Повний диск через (прибл.)" ResetUIWarning.Title="Ви дійсно бажаєте скинути інтерфейс?" ResetUIWarning.Text="Скидання інтерфейсу користувача приховує всі додаткові вікна. Вам потрібно буде знов увімкнути ці додаткові вікна з меню Вид, якщо ви хочете, щоб вони були видимі.\n\nВи дійсно бажаєте скинути інтерфейс?" @@ -238,6 +245,9 @@ ConfirmStart.Text="Ви впевнені, що хочете почати тра ConfirmStop.Title="Закінчити трансляцію?" ConfirmStop.Text="Ви впевнені, що хочете закінчити трансляцію?" +ConfirmStopRecord.Title="Зупинити запис?" +ConfirmStopRecord.Text="Ви впевнені, що хочете зупинити запис?" + ConfirmBWTest.Title="Почати тест пропускної здатності?" ConfirmBWTest.Text="OBS було настроєно у режимі тестування пропускної здатності. Цей режим дозволяє здійснювати тестування мережі без виводу вашого каналу наживо. Як тільки ви закінчите тестування, вам потрібно буде вимкнути його для того, щоб глядачі змогли побачити вашу трансляцію.\n\nВи бажаєте продовжити?" @@ -253,6 +263,8 @@ Output.StartRecordingFailed="Не вдалося розпочати запис" Output.StartReplayFailed="Не вдалося запустити Буфер Повторів" Output.StartFailedGeneric="Помилка. Вивід не було розпочато. За додатковою інформацією, будь ласка зверніться до файлу журналу.\n\nПримітка: якщо ви використовуєте NVENC або AMD енкодер, перевірте чи оновлений драйвер відео." +Output.ReplayBuffer.PauseWarning.Title="Не можливо зберегти файл Повторів коли запис Призупинено" +Output.ReplayBuffer.PauseWarning.Text="Попередження: Повтори не можуть бути збережені якщо запис Призупинено." Output.ConnectFail.Title="Не вдалося підключитися" Output.ConnectFail.BadPath="Шлях або URL-адреса недосяжні. Будь ласка, перевірте налаштування програмного забезпечення." @@ -261,6 +273,8 @@ Output.ConnectFail.InvalidStream="Немає доступу до вказано Output.ConnectFail.Error="Під час зв'язку з сервером відбулася несподівана помилка. Подробиці знаходяться у лог-файлі." Output.ConnectFail.Disconnected="Від'єднаний від серверу." +Output.StreamEncodeError.Title="Помилка кодування" +Output.StreamEncodeError.Msg="Під час трансляції відбулася помилка у енкодері." Output.RecordFail.Title="Не вдалося розпочати запис" Output.RecordFail.Unsupported="Формат виводу на жаль не підтримується або форматом не підтримується більш однієї звукової доріжки. Будь ласка, перевірте налаштування та повторіть спробу." @@ -268,6 +282,7 @@ Output.RecordNoSpace.Title="Недостатньо простору на дис Output.RecordNoSpace.Msg="На диску недостатньо простору для запису." Output.RecordError.Title="Помилка запису" Output.RecordError.Msg="Під час запису відбулася несподівана помилка." +Output.RecordError.EncodeErrorMsg="Під час запису відбулася помилка у енкодері." Output.ReplayBuffer.NoHotkey.Title="Гарячу клавішу не вказано!" Output.ReplayBuffer.NoHotkey.Msg="Гарячу клавішу для Буферу Повторів не вказано. Будь ласка, встановіть гарячу клавішу на дію \"Зберегти Повтор\", щоб використовувати її для збереження повторів." @@ -439,6 +454,8 @@ Basic.Main.StartRecording="Почати запис" Basic.Main.StartReplayBuffer="Запустити Буфер Повторів" Basic.Main.StartStreaming="Почати трансляцію" Basic.Main.StopRecording="Зупинити запис" +Basic.Main.PauseRecording="Призупинити Запис" +Basic.Main.UnpauseRecording="Продовжити Запис" Basic.Main.StoppingRecording="Запис зупиняється..." Basic.Main.StopReplayBuffer="Зупинити Буфер Повторів" Basic.Main.StoppingReplayBuffer="Буфер Повторів зупиняється..." @@ -465,7 +482,7 @@ Basic.MainMenu.Edit.Undo="Відмінити (&U)" Basic.MainMenu.Edit.Redo="Відновити (&R)" Basic.MainMenu.Edit.UndoAction="Відмінити $1 (&U)" Basic.MainMenu.Edit.RedoAction="Відновити $1 (&R)" -Basic.MainMenu.Edit.LockPreview="Заблокувати вікно Перегляду (&L)" +Basic.MainMenu.Edit.LockPreview="&Заблокувати вікно Перегляду" Basic.MainMenu.Edit.Scale="Масштабувати вікно Перегляду (&S)" Basic.MainMenu.Edit.Scale.Window="В розмір вікна" Basic.MainMenu.Edit.Scale.Canvas="Як Полотно (%1x%2)" @@ -497,6 +514,7 @@ Basic.MainMenu.View.Toolbars="Панелі інструментів (&T)" Basic.MainMenu.View.Docks="Панелі інтерфейсу" Basic.MainMenu.View.Docks.ResetUI="Скинути інтерфейс" Basic.MainMenu.View.Docks.LockUI="Зафіксувати інтерфейс" +Basic.MainMenu.View.Docks.CustomBrowserDocks="Панелі браузера..." Basic.MainMenu.View.Toolbars.Listboxes="У Списках (&L)" Basic.MainMenu.View.SceneTransitions="Відео-переходи між Сценами (&C)" Basic.MainMenu.View.StatusBar="Панель стану (&S)" @@ -539,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="Автоматично перевір Basic.Settings.General.OpenStatsOnStartup="Відкривати вікно статистики під час запуску" Basic.Settings.General.WarnBeforeStartingStream="Показувати підтвердження для початку трансляції" Basic.Settings.General.WarnBeforeStoppingStream="Показувати підтвердження для закінчення трансляції" +Basic.Settings.General.WarnBeforeStoppingRecord="Показувати підтвердження для зупинення запису" Basic.Settings.General.Projectors="Проектор" Basic.Settings.General.HideProjectorCursor="Приховати курсор у режимі Проектор" Basic.Settings.General.ProjectorAlwaysOnTop="Режим Проектор показувати поверх всіх вікон" @@ -586,12 +605,15 @@ Basic.Settings.Output.Encoder="Енкодер" Basic.Settings.Output.SelectDirectory="Вибір каталогу для Запису" Basic.Settings.Output.SelectFile="Вибір файлу для Запису" Basic.Settings.Output.EnforceBitrate="Застосувати примусовий бітрейт з сервісу трансляцій" +Basic.Settings.Output.DynamicBitrate="Змінювати бітрейт підлаштовуючись до низької якості мережі" +Basic.Settings.Output.DynamicBitrate.Beta="Змінювати бітрейт підлаштовуючись до низької якості мережі (Бета)" +Basic.Settings.Output.DynamicBitrate.TT="Замість пропуску кадрів змінює бітрейт, підлаштовуючись до низької якості мережі.\n\nПримітка: з цією опцією, надзвичайно високе несподіване зростання помилок у мережі,\nможе викликати зростання затримки для глядачів. Відновлення бітрейту після\nпадіння може зайняти до кількох хвилин.\n\nЗараз підтримується лише для RTMP з'єднань." Basic.Settings.Output.Mode="Режим виводу" Basic.Settings.Output.Mode.Simple="Простий" Basic.Settings.Output.Mode.Adv="Розширений" Basic.Settings.Output.Mode.FFmpeg="Вивід FFmpeg" Basic.Settings.Output.UseReplayBuffer="Увімкнути Буфер Повторів" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Максимальна тривалість Повтору (у секундах)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Максимальна тривалість Повтору" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Максимальний об'єм пам'яті (у мегабайтах)" Basic.Settings.Output.ReplayBuffer.Estimate="Буде використано пам'яті: %1 МБ" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Не вдалося оцінити об'єм використання пам'яті. Будь ласка, встановіть максимальний об'єм пам'яті для Буферу Повторів вручну." @@ -606,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="Якість майже без Basic.Settings.Output.Simple.RecordingQuality.Lossless="Без втрат якості, надзвичайно великий розмір файлу" Basic.Settings.Output.Simple.Warn.VideoBitrate="Увага! Буде встановлено відео бітрейт трансляції %1, що є верхней межою для обраного сервісу трансляцій. Якщо ви хочете встановити бітрейт вищий за %1, то увімкніть Додаткові Налаштування Енкодера та зніміть прапорець \"Застосувати примусовий бітрейт з сервісу трансляцій\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Увага! Буде встановлено аудіо бітрейт трансляції %1, що є верхней межою для обраного сервісу трансляцій. Якщо ви хочете встановити бітрейт вищий за %1, то увімкніть Додаткові Налаштування Енкодера та зніміть прапорець \"Застосувати примусовий бітрейт з сервісу трансляцій\"." +Basic.Settings.Output.Simple.Warn.CannotPause="Попередження: Запис не може бути Призупинено, якщо якість встановлено у \"Так само як трансляція\"." Basic.Settings.Output.Simple.Warn.Encoder="Попередження: Запис програмним енкодером з якістю не \"Так само як трансляція\", здійснює додаткове навантаження на ЦП при використовуванні трансляції і запису одночасно." Basic.Settings.Output.Simple.Warn.Lossless="Попередження: Відео Без втрат якості генерує надзвичайно великі розміри файлів! Воно може використовувати понад 7 гігабайт дискового простору на хвилину при високих роздільній здатності зображення та частоти кадрів. Відео Без втрат якості не рекомендується для довгого запису, тільки якщо у вас є дуже великий обсяг вільного дискового простору." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Ви впевнені, що ви хочете використовувати якість \"Без втрат якості\"?" @@ -618,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Програмний (x264, Basic.Settings.Output.VideoBitrate="Відео бітрейт" Basic.Settings.Output.AudioBitrate="Аудіо бітрейт" Basic.Settings.Output.Reconnect="Поновити зв'язок автоматично" -Basic.Settings.Output.RetryDelay="Затримка спроби (секунди)" +Basic.Settings.Output.RetryDelay="Затримка перед повторною спробою" Basic.Settings.Output.MaxRetries="Кількість спроб" Basic.Settings.Output.Advanced="Увімкнути Додаткові Налаштування Енкодера" Basic.Settings.Output.EncoderPreset="Шаблон до енкодера" @@ -689,7 +712,8 @@ Basic.Settings.Video.DisableAero="Вимкнути Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Білінійний (найшвидший, але розмито, якщо масштабувати)" Basic.Settings.Video.DownscaleFilter.Bicubic="Бікубічний (чітке масштабування, 16 проб)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Ланцош (чітке масштабування, 32 проби)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Ланцош (чітке масштабування, 36 проб)" +Basic.Settings.Video.DownscaleFilter.Area="Усереднення площ (зважена сума, 4/6/9 проб)" Basic.Settings.Audio="Аудіо" Basic.Settings.Audio.SampleRate="Частота дискретизації" @@ -703,7 +727,7 @@ Basic.Settings.Audio.PeakMeterType="Тип вимірювача пікових Basic.Settings.Audio.PeakMeterType.SamplePeak="З точністю до вибірки" Basic.Settings.Audio.PeakMeterType.TruePeak="Істинно-піковий (більше навантаження на ЦП)" Basic.Settings.Audio.MultiChannelWarning.Enabled="ПОПЕРЕДЖЕННЯ: Увімкнуто об'ємний звук." -Basic.Settings.Audio.MultichannelWarning="Якщо робите трансляції, перевірте чи підтримує ваш сервіс трансляцій об'ємний звук на вході та виході. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast - це приклади сервісів де об'ємний звук цілком підтримується. Навпаки, Facebook Live і YouTube Live обидва підтримують вхідний об'ємний звук, але Facebook Live мікшує його до стерео, а YouTube Live відтворює лише два канали.\n\nАудіо фільтри самої OBS сумісні з об'ємним звуком, хоча підтримку VST плагінами не гарантовано." +Basic.Settings.Audio.MultichannelWarning="Якщо робите трансляції, перевірте чи підтримує ваш сервіс трансляцій об'ємний звук на вході та виході. Facebook 360 Live, Mixer RTMP, Smashcast - це приклади сервісів де об'ємний звук цілком підтримується. Навпаки, Facebook Live і YouTube Live обидва підтримують вхідний об'ємний звук, але Facebook Live мікшує його до стерео, а YouTube Live відтворює лише два канали.\n\nАудіо фільтри самої OBS сумісні з об'ємним звуком, хоча підтримку VST плагінами не гарантовано." Basic.Settings.Audio.MultichannelWarning.Title="Увімкнути об'ємний звук для виводу аудіо?" Basic.Settings.Audio.MultichannelWarning.Confirm="Ви справді бажаєте увімкнути об'ємний звук для виводу аудіо?" Basic.Settings.Audio.Devices="Пристрої" @@ -730,28 +754,34 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Очікування" Basic.Settings.Advanced.FormatWarning="Попередження: Формати кольору, які відрізняються від NV12, в першу чергу призначені для запису, і не рекомендуються для трансляцій. Трансляція може додатково навантажити ЦП через перетворення форматів." Basic.Settings.Advanced.Audio.BufferingTime="Розмір аудіо буфера, (мс)" Basic.Settings.Advanced.Video.ColorFormat="Формат кольору" +Basic.Settings.Advanced.Video.ColorSpace="Колірний простір" +Basic.Settings.Advanced.Video.ColorRange="Колірний діапазон" Basic.Settings.Advanced.Video.ColorRange.Partial="Частковий" Basic.Settings.Advanced.Video.ColorRange.Full="Повний" Basic.Settings.Advanced.Audio.MonitoringDevice="Пристрій Тестування Аудіо (на слух)" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="За замовчанням" Basic.Settings.Advanced.Audio.DisableAudioDucking="Вимкнути у Windows опцію зменшення гучності під час зв'язку" Basic.Settings.Advanced.StreamDelay="Затримка трансляції" -Basic.Settings.Advanced.StreamDelay.Duration="Тривалість (секунди)" +Basic.Settings.Advanced.StreamDelay.Duration="Тривалість" Basic.Settings.Advanced.StreamDelay.Preserve="Зберегати точку роз'єднання (збільшує затримку) під час встановлення нового зв'язку" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Буде використано пам'яті: %1 МБ" Basic.Settings.Advanced.Network="Мережа" Basic.Settings.Advanced.Network.BindToIP="Прив'язати до адаптера (IP)" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Увімкнути новий мережевий код" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Режим з низькою затримкою" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="Гарячі клавіші та фокус" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="Ніколи не відключати гарячі клавіші" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Відключати гарячі клавіші, коли головне вікно знаходиться у фокусі" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="Відключати гарячі клавіші, коли головне вікно не знаходиться у фокусі" Basic.Settings.Advanced.AutoRemux="Запускати автоматичну Ремультиплексацію до .mp4" Basic.Settings.Advanced.AutoRemux.MP4="(записувати як .mkv)" Basic.AdvAudio="Розширені Налаштування Аудіо" Basic.AdvAudio.Name="Назва" -Basic.AdvAudio.Mono="Мікшувати до псевдо-Моно" +Basic.AdvAudio.Volume="Гучність" +Basic.AdvAudio.Mono="Моно" Basic.AdvAudio.Balance="Баланс" -Basic.AdvAudio.SyncOffset="Зсув синхронізації (мс)" +Basic.AdvAudio.SyncOffset="Зсув синхронізації" Basic.AdvAudio.Monitoring="Тестування Аудіо (на слух)" Basic.AdvAudio.Monitoring.None="Тест вимкнено" Basic.AdvAudio.Monitoring.MonitorOnly="Слухати, але не Виводити" @@ -817,6 +847,7 @@ SceneItemHide="Приховати '%1'" OutputWarnings.NoTracksSelected="Ви повинні вибрати хоча б одну аудіо-доріжку" OutputWarnings.MultiTrackRecording="Попередження: Певні формати (наприклад, FLV) не підтримують кілька треків на запис" OutputWarnings.MP4Recording="Попередження: Запис в MP4/MOV може стати невиправно пошкодженим, якщо файл не буде завершено (наприклад, в результаті BSOD, втрати живлення і т.п.). Якщо ви хочете, мати запис декількох звукових доріжок спробуйте використати MKV та зробіть ремультиплексацію запису до MP4/MOV після того, як запис буде закінчено (Файл → Ремультиплексація Записів)" +OutputWarnings.CannotPause="Попередження: Запис не може бути Призупинено, якщо якість встановлено у \"(Використовувати енкодер трансляцій)\"" FinalScene.Title="Видалення сцени" FinalScene.Text="Повинна бути принаймні одна сцена." @@ -843,4 +874,5 @@ ResizeOutputSizeOfSource="Встановити (Вивід) за розміро ResizeOutputSizeOfSource.Text="Параметри: Роздільна здатність (Полотно) та Роздільна здатність (Вивід), буде встановлено у розмір обраного Джерела." ResizeOutputSizeOfSource.Continue="Ви хочете продовжити?" +PreviewTransition="Перегляд Відео-переходу" diff --git a/UI/data/locale/ur-PK.ini b/UI/data/locale/ur-PK.ini index 047a3b5..36264d0 100644 --- a/UI/data/locale/ur-PK.ini +++ b/UI/data/locale/ur-PK.ini @@ -23,7 +23,6 @@ Settings="ترتیبات" Display="ڈسپلے" Name="نام" Exit="بند کریں" -Mixer="مکسر" Browse="براؤز کریں" Mono="مونو" Stereo="سٹیریو" @@ -75,6 +74,7 @@ DoNotShowAgain="دوبارہ مت دکھائیں" AlreadyRunning.LaunchAnyway="ویسے بھی شروع" + Auth.Authing.Title="توثیق کر رہا ہے..." Auth.AuthFailure.Title="تصدیق کی ناکامی" Auth.Chat="گفتگو" @@ -170,5 +170,6 @@ Basic.AutoConfig.VideoPage="ویڈیو سیٹنگز" + diff --git a/UI/data/locale/vi-VN.ini b/UI/data/locale/vi-VN.ini index 8b8b084..27b61ec 100644 --- a/UI/data/locale/vi-VN.ini +++ b/UI/data/locale/vi-VN.ini @@ -23,7 +23,6 @@ Settings="Cài đặt" Display="Hiển thị" Name="Tên" Exit="Thoát" -Mixer="Bộ trộn" Browse="Chọn đường dẫn" Mono="Âm thanh đơn" Stereo="Âm thanh nổi" @@ -72,6 +71,7 @@ RemuxRecordings="Remux video" Next="Tiếp tục" Back="Quay lại" Defaults="Mặc định" +HideMixer="Ẩn trong bộ trộn" TransitionOverride="Ghi đè chuyển tiếp" None="Không có" StudioMode.Preview="Xem trước" @@ -90,15 +90,22 @@ AlreadyRunning.LaunchAnyway="Khởi động luôn" DockCloseWarning.Title="Đóng cửa sổ gắn đế được" DockCloseWarning.Text="Bạn vừa đóng một cửa số gắn đế được. Nếu bạn muốn hiển thị lại lần nữa, sử dụng trình đơn Hiển thị → Thanh đế trên thanh trình đơn." + Auth.Authing.Title="Đang xác thực..." +Auth.Authing.Text="Đang xác thực với %1, chờ lát..." Auth.AuthFailure.Title="Xác thực không thành công" +Auth.AuthFailure.Text="Không xác thực được với %1:\n\n%2: %3" Auth.InvalidScope.Title="Bắt buộc phải xác thực" Auth.LoadingChannel.Title="Đang tải thông tin kênh..." +Auth.LoadingChannel.Text="Đang tải thông tin về kênh cho %1, chờ lát..." Auth.ChannelFailure.Title="Bị lỗi khi nạp kênh" +Auth.ChannelFailure.Text="Không tải được thông tin kênh cho %1\n\n%2: %3" Auth.Chat="Tán gẫu" Auth.StreamInfo="Thông tin luồng phát" TwitchAuth.Stats="Thống kê Twitch" +TwitchAuth.Feed="Bảng tin hoạt động Twitch" TwitchAuth.TwoFactorFail.Title="Không thể truy vấn khóa luồng" +RestreamAuth.Channels="Truyền phát lại kênh" Copy.Filters="Sao chép các bộ lọc" Paste.Filters="Dán các bộ lọc" @@ -128,9 +135,10 @@ Basic.AutoConfig.VideoPage.BaseResolution.Display="Màn hình %1 (%2x%3)" Basic.AutoConfig.VideoPage.FPS.UseCurrent="Sử dụng hiện tại (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 hoặc 30, nhưng ưu tiên chọn 60 khi có thể" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 hoặc 30, nhưng ưu tiên độ phân giải cao" +Basic.AutoConfig.VideoPage.CanvasExplanation="Lưu ý: Độ phân giải tấm vẽ (cơ sở) không nhất thiết phải bằng với độ phân giải bạn sẽ truyền phát hay ghi hình. Độ phân giải truyền phát/ghi hình thực tế có thể bị giảm tỉ lệ từ độ phân giải của tấm vẽ để giảm sử dụng tài nguyên hoặc yêu cầu về tốc độ bit." Basic.AutoConfig.StreamPage="Thông tin stream" Basic.AutoConfig.StreamPage.SubTitle="Vui lòng nhập thông tin máy chủ stream của bạn" -Basic.AutoConfig.StreamPage.ConnectAccount="Kết nối tài khoản (tùy chọn)" +Basic.AutoConfig.StreamPage.ConnectAccount="Kết nối tài khoản (đề xuất)" Basic.AutoConfig.StreamPage.DisconnectAccount="Ngắt kết nối tài khoản" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Ngắt kết nối tài khoản?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Thay đổi này sẽ được áp dụng ngay lập tức. Bạn có chắc là bạn muốn ngắt kết nối tài khoản của bạn?" @@ -226,6 +234,9 @@ ConfirmStart.Text="Bạn có chắc muốn bắt đầu stream?" ConfirmStop.Title="Ngừng Stream?" ConfirmStop.Text="Bạn có chắc muốn dừng stream?" +ConfirmStopRecord.Title="Ngừng ghi hình?" +ConfirmStopRecord.Text="Bạn có chắc bạn muốn dừng ghi hình?" + ConfirmBWTest.Title="Bắt đầu kiểm tra băng thông?" ConfirmExit.Title="Thoát OBS?" @@ -240,6 +251,8 @@ Output.StartRecordingFailed="Không thể bắt đầu quay video" Output.StartReplayFailed="Không thể khởi động replay buffer" Output.StartFailedGeneric="Bắt đầu đầu ra đã thất bại. Vui lòng kiểm tra các bản ghi để biết thêm chi tiết.\n\nGhi chú: nếu bạn đang sử dụng bộ mã hóa NVENC hoặc AMD, hãy chắc chắn rằng các trình điều khiển GPU được cập nhật phiên bản mới nhất." +Output.ReplayBuffer.PauseWarning.Title="Không thể lưu bản phát lại trong khi tạm dừng" +Output.ReplayBuffer.PauseWarning.Text="Cảnh báo: Bản phát lại không thể được lưu trong khi tạm dừng ghi hình." Output.ConnectFail.Title="Không thể kết nối" Output.ConnectFail.BadPath="URL không hợp lệ của đường dẫn hoặc kết nối. Xin vui lòng kiểm tra cài đặt của bạn để xác nhận rằng họ là hợp lệ." @@ -279,6 +292,7 @@ Remux.FinishedTitle="Remuxing đã hoàn thành" Remux.Finished="Ghi remuxed" Remux.FinishedError="Ghi âm remuxed, nhưng các tập tin có thể không đầy đủ" Remux.SelectRecording="Chọn Ghi âm OBS..." +Remux.SelectTarget="Chọn tệp mục tiêu..." Remux.ExitUnfinishedTitle="Remuxing trong tiến trình" Remux.ExitUnfinished="Remuxing không được hoàn tất, dừng bây giờ có thể hiển thị các tập tin mục tiêu không sử dụng được. \nAre bạn có chắc bạn muốn dừng remuxing?" @@ -423,6 +437,7 @@ Basic.Main.StartRecording="Bắt đầu ghi" Basic.Main.StartReplayBuffer="Bắt đầu Replay Buffer" Basic.Main.StartStreaming="Bắt đầu Stream" Basic.Main.StopRecording="Dừng ghi" +Basic.Main.PauseRecording="Tạm dừng ghi hình" Basic.Main.StoppingRecording="Dừng ghi video..." Basic.Main.StopReplayBuffer="Dừng Replay Buffer" Basic.Main.StoppingReplayBuffer="Đang dừng Replay Buffer..." @@ -452,6 +467,7 @@ Basic.MainMenu.Edit.RedoAction="Làm lại $1 (&R)" Basic.MainMenu.Edit.LockPreview="Khóa xem trước (&L)" Basic.MainMenu.Edit.Scale="Xem trước co dãn (&S)" Basic.MainMenu.Edit.Scale.Window="Co dãn cửa sổ" +Basic.MainMenu.Edit.Scale.Canvas="Tấm vẽ (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Đầu ra (%1x%2)" Basic.MainMenu.Edit.Transform="Biến đổi (&T)" Basic.MainMenu.Edit.Transform.EditTransform="Chỉnh sửa biến đổi... (&E)" @@ -507,6 +523,7 @@ Basic.MainMenu.Help.Logs.UploadLastLog="Tải &lên cuối đăng nhập tập t Basic.MainMenu.Help.Logs.ViewCurrentLog="Xem sổ ghi hiện tại (&V)" Basic.MainMenu.Help.CheckForUpdates="Kiểm tra cập nhật mới" Basic.MainMenu.Help.CrashLogs="Sự cố & Báo cáo" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Hiện báo cáo hỏng chương trình (&S)" Basic.MainMenu.Help.About="Giới thiệu (&A)" Basic.Settings.ProgramRestart="Chương trình phải được khởi động lại để những thiết đặt có hiệu lực." @@ -536,10 +553,18 @@ Basic.Settings.General.SystemTrayHideMinimize="Luôn luôn thu nhỏ về khay h Basic.Settings.General.Preview="Xem trước" Basic.Settings.General.StudioPortraitLayout="Bật bố cục theo chiều ngang/dọc" Basic.Settings.General.Multiview="Đa góc nhìn" +Basic.Settings.General.Multiview.DrawSourceNames="Hiện tên cảnh" +Basic.Settings.General.Multiview.DrawSafeAreas="Vẽ khu vực an toàn (EBU R 95)" Basic.Settings.General.MultiviewLayout="Giao diện nhiều lớp" +Basic.Settings.General.MultiviewLayout.Horizontal.Top="Chiều ngang, trên (8 cảnh)" +Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Chiều ngang, dưới (8 cảnh)" +Basic.Settings.General.MultiviewLayout.Vertical.Left="Chiều dọc, trái (8 cảnh)" +Basic.Settings.General.MultiviewLayout.Vertical.Right="Chiều dọc, phải (8 cảnh)" +Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Chiều ngang, trên (24 cảnh)" Basic.Settings.Stream="Stream" Basic.Settings.Stream.StreamType="Kiểu Stream" +Basic.Settings.Stream.Custom.UseAuthentication="Xác thực sử dụng" Basic.Settings.Stream.Custom.Username="Tên đăng nhập" Basic.Settings.Stream.Custom.Password="Mật khẩu" @@ -553,7 +578,6 @@ Basic.Settings.Output.Mode.Simple="Dễ sử dụng" Basic.Settings.Output.Mode.Adv="Nâng cao" Basic.Settings.Output.Mode.FFmpeg="FFmpeg đầu ra" Basic.Settings.Output.UseReplayBuffer="Bật Replay Buffer" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Thời gian phát lại tối đa (Giây)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Bộ nhớ tối đa (Megabyte)" Basic.Settings.Output.ReplayBuffer.Estimate="Ước tính bộ nhớ sử dụng: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Không thể ước tính sử dụng bộ nhớ. Xin vui lòng thiết lập giới hạn bộ nhớ tối đa." @@ -577,7 +601,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Phần mềm (x 264 sử d Basic.Settings.Output.VideoBitrate="Video Bitrate" Basic.Settings.Output.AudioBitrate="Âm thanh Bitrate" Basic.Settings.Output.Reconnect="Tự động kết nối" -Basic.Settings.Output.RetryDelay="Thử lại chậm trễ (giây)" Basic.Settings.Output.MaxRetries="Tối đa Retries" Basic.Settings.Output.Advanced="Kích hoạt tính năng cài đặt mã hóa nâng cao" Basic.Settings.Output.CustomEncoderSettings="Thiết đặt tùy chỉnh mã hóa" @@ -628,7 +651,7 @@ Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Hiển thị tất cả các Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Video Adapter" -Basic.Settings.Video.BaseResolution="Cơ sở (vải) độ phân giải" +Basic.Settings.Video.BaseResolution="Độ phân giải cơ sở (tấm vẽ)" Basic.Settings.Video.ScaledResolution="Độ phân giải (Kích thước) đầu ra" Basic.Settings.Video.DownscaleFilter="Downscale lọc" Basic.Settings.Video.DisableAeroWindows="Vô hiệu hóa hàng không (Windows only)" @@ -645,7 +668,7 @@ Basic.Settings.Video.DisableAero="Vô hiệu hóa Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (nhanh nhất, nhưng mờ nếu rộng)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (Sharpened rộng, 16 mẫu)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Sharpened rộng, 32 mẫu)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Sharpened rộng, 36 mẫu)" Basic.Settings.Audio="Âm thanh" Basic.Settings.Audio.SampleRate="Tỷ lệ mẫu" @@ -672,7 +695,6 @@ Basic.Settings.Advanced.Video.ColorRange.Partial="Một phần" Basic.Settings.Advanced.Video.ColorRange.Full="Đầy đủ" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Mặc định" Basic.Settings.Advanced.StreamDelay="Stream trễ" -Basic.Settings.Advanced.StreamDelay.Duration="Thời gian (giây)" Basic.Settings.Advanced.StreamDelay.Preserve="Giữ điểm cắt (tăng chậm trễ) khi kết nối lại" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Ước tính bộ nhớ sử dụng: %1 MB" Basic.Settings.Advanced.Network="Mạng" @@ -683,9 +705,7 @@ Basic.Settings.Advanced.AutoRemux.MP4="(ghi với định dạng mkv)" Basic.AdvAudio="Thuộc tính âm thanh nâng cao" Basic.AdvAudio.Name="Tên" -Basic.AdvAudio.Mono="Downmix để Mono" Basic.AdvAudio.Balance="Cân bằng" -Basic.AdvAudio.SyncOffset="Bù đắp đồng bộ (ms)" Basic.AdvAudio.Monitoring="Giám sát âm thanh" Basic.AdvAudio.Monitoring.None="Tắt giám sát" Basic.AdvAudio.Monitoring.MonitorOnly="Chỉ giám sát (không âm thanh ra)" diff --git a/UI/data/locale/zh-CN.ini b/UI/data/locale/zh-CN.ini index 0c2920f..1bb88a1 100644 --- a/UI/data/locale/zh-CN.ini +++ b/UI/data/locale/zh-CN.ini @@ -25,8 +25,8 @@ Name="名称" Exit="退出" Mixer="混音器" Browse="浏览" -Mono="单声道​" -Stereo="立体声​​​" +Mono="单声道" +Stereo="立体声" DroppedFrames="丢帧 %1(%2%)" StudioProgramProjector="全屏投影(输出)" PreviewProjector="全屏投影(预览)" @@ -91,6 +91,10 @@ AlreadyRunning.LaunchAnyway="仍然启动" DockCloseWarning.Title="关闭可停靠窗口" DockCloseWarning.Text="您刚关闭了一个可停靠的窗口。如果想要再次显示它,请使用菜单栏上的 查看→停靠部件 菜单。" +ExtraBrowsers="自定义浏览器 Dock" +ExtraBrowsers.Info="通过指定名称和 URL 来添加 Dock(停靠部件),然后选择“应用”或“关闭”来打开这些Dock。你可以在任何时刻添加或删除这些Dock。" +ExtraBrowsers.DockName="Dock 名" + Auth.Authing.Title="正在验证…" Auth.Authing.Text="正在与 %1 进行身份验证,请稍候…" Auth.AuthFailure.Title="身份验证失败" @@ -107,6 +111,7 @@ TwitchAuth.Stats="Twitch 统计" TwitchAuth.Feed="Twitch 活动订阅源" TwitchAuth.TwoFactorFail.Title="无法查询流密钥" TwitchAuth.TwoFactorFail.Text="OBS 无法连接到您的 Twitch 账户。请确保在 Twitch 安全性设置中开启了双重身份验证,只有开启后才能开始推流。" +RestreamAuth.Channels="Restream 频道" Copy.Filters="复制滤镜" Paste.Filters="粘贴滤镜" @@ -139,7 +144,7 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60或30,但优先选择高分辨 Basic.AutoConfig.VideoPage.CanvasExplanation="注意:画布(基础)分辨率并不一定要与推流或录像的分辨率相同。实际推流或录像的分辨率可从画布分辨率缩小,以降低对资源的使用或对比特率的需求。" Basic.AutoConfig.StreamPage="串流资讯" Basic.AutoConfig.StreamPage.SubTitle="请输入你的串流信息" -Basic.AutoConfig.StreamPage.ConnectAccount="连接帐户(可选)" +Basic.AutoConfig.StreamPage.ConnectAccount="连接帐户 (推荐)" Basic.AutoConfig.StreamPage.DisconnectAccount="解除帐户连接" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="解除帐户连接?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="此更改将立即应用。您确定要解除帐户连接吗?" @@ -240,6 +245,9 @@ ConfirmStart.Text="你确定你想要启动串流?" ConfirmStop.Title="停止串流?" ConfirmStop.Text="你确定你想要停止串流?" +ConfirmStopRecord.Title="停止录制?" +ConfirmStopRecord.Text="你确定要停止录制吗?" + ConfirmBWTest.Title="开始带宽测试?" ConfirmBWTest.Text="您已经在带宽测试模式下配置了 OBS。此模式允许在不启用频道的情况下进行网络测试。完成测试后,您需要禁用它,以便观众能够看到您的流。\n\n是否继续?" @@ -255,6 +263,8 @@ Output.StartRecordingFailed="启动录像失败" Output.StartReplayFailed="启动回放缓存失败" Output.StartFailedGeneric="启动输出失败. 请检查日志来了解细节.\n\n注意: 如果你使用的是 NVENC 或 AMD 编码器, 请确保您的视频驱动程序是最新的." +Output.ReplayBuffer.PauseWarning.Title="暂停时无法保存回放" +Output.ReplayBuffer.PauseWarning.Text="警告:在录制暂停时无法保存回放。" Output.ConnectFail.Title="连接失败" Output.ConnectFail.BadPath="无效的路径或URL。请检查您的设置以确认它们是有效的。" @@ -398,12 +408,12 @@ Basic.StatusBar.DelayStoppingIn="延迟 (在 %1 秒后停止)" Basic.StatusBar.DelayStartingStoppingIn="延迟 (在%1 秒后停止,在 %2 秒后开始)" Basic.Filters="滤镜" -Basic.Filters.AsyncFilters="音频/视频滤镜" -Basic.Filters.AudioFilters="音频滤镜" +Basic.Filters.AsyncFilters="音视频滤镜" +Basic.Filters.AudioFilters="滤音器" Basic.Filters.EffectFilters="效果滤镜" Basic.Filters.Title="'%1' 的滤镜" Basic.Filters.AddFilter.Title="滤镜名称" -Basic.Filters.AddFilter.Text="请指定滤镜的名称" +Basic.Filters.AddFilter.Text="请指定滤镜名称" Basic.TransformWindow="场景物体变换" Basic.TransformWindow.Position="位置" @@ -444,6 +454,8 @@ Basic.Main.StartRecording="开始录制" Basic.Main.StartReplayBuffer="开始回放缓存" Basic.Main.StartStreaming="开始推流" Basic.Main.StopRecording="停止录制" +Basic.Main.PauseRecording="暂停录制" +Basic.Main.UnpauseRecording="恢复录制" Basic.Main.StoppingRecording="停止录制..." Basic.Main.StopReplayBuffer="停止回放缓存" Basic.Main.StoppingReplayBuffer="正在停止回放缓存..." @@ -502,6 +514,7 @@ Basic.MainMenu.View.Toolbars="工具栏(&T)" Basic.MainMenu.View.Docks="停靠部件" Basic.MainMenu.View.Docks.ResetUI="重置界面" Basic.MainMenu.View.Docks.LockUI="锁定界面" +Basic.MainMenu.View.Docks.CustomBrowserDocks="自定义浏览器 Dock..." Basic.MainMenu.View.Toolbars.Listboxes="列表框(&L)" Basic.MainMenu.View.SceneTransitions="转场特效(&C)" Basic.MainMenu.View.StatusBar="状态栏(&S)" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="启动时自动检查更新" Basic.Settings.General.OpenStatsOnStartup="在启动时打开统计对话框" Basic.Settings.General.WarnBeforeStartingStream="启动流时显示确认对话框" Basic.Settings.General.WarnBeforeStoppingStream="停止流时显示确认对话框" +Basic.Settings.General.WarnBeforeStoppingRecord="停止录制时显示确认对话框" Basic.Settings.General.Projectors="投影窗口" Basic.Settings.General.HideProjectorCursor="投影窗口中隐藏光标" Basic.Settings.General.ProjectorAlwaysOnTop="使投影窗口置顶" @@ -591,12 +605,15 @@ Basic.Settings.Output.Encoder="编码器" Basic.Settings.Output.SelectDirectory="选择录像目录" Basic.Settings.Output.SelectFile="选择录像文件" Basic.Settings.Output.EnforceBitrate="强制执行流媒体服务比特率限制" +Basic.Settings.Output.DynamicBitrate="动态调整比特率以应对网络拥堵" +Basic.Settings.Output.DynamicBitrate.Beta="动态调整比特率以应对网络拥堵(Beta)" +Basic.Settings.Output.DynamicBitrate.TT="在网络拥堵时快速动态调整比特率,而不是丢弃帧来减缓拥堵。\n\n注意:开启后,若有严重的突发网络拥堵,到观众的延迟可能会增加。\n比特率降低之后,可能需要几分钟时间才能恢复。\n\n当前只支持 RTMP 流。" Basic.Settings.Output.Mode="输出模式" Basic.Settings.Output.Mode.Simple="简单" Basic.Settings.Output.Mode.Adv="高级" Basic.Settings.Output.Mode.FFmpeg="FFmpeg 输出" Basic.Settings.Output.UseReplayBuffer="启用回放缓存" -Basic.Settings.Output.ReplayBuffer.SecondsMax="最大回放时间(秒)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="最长回放时间" Basic.Settings.Output.ReplayBuffer.MegabytesMax="最大内存(MB)" Basic.Settings.Output.ReplayBuffer.Estimate="估计内存使用量:%1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="无法估计内存使用量。请设置最大内存限制。" @@ -611,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="近似无损的质量, 大文 Basic.Settings.Output.Simple.RecordingQuality.Lossless="无损的质量, 非常大的文件大小" Basic.Settings.Output.Simple.Warn.VideoBitrate="警告: 视频比特率将设置为 %1, 这是当前的流媒体服务的上限值. 如果你确定你想要超过 %1, 启用高级的编码器选项并取消选中\"强制流媒体服务比特率限制\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="警告: 音频比特率将设置为 %1, 这是当前的流媒体服务的上限值. 如果你确定你想要超过 %1, 启用高级的编码器选项并取消选中\"强制流媒体服务比特率限制\"." +Basic.Settings.Output.Simple.Warn.CannotPause="警告:当录像质量设为“与串流画质相同”时,无法暂停录制。" Basic.Settings.Output.Simple.Warn.Encoder="警告: 同时传输流和录像, 并使用软件编码器编码与流不同的质量, 将会需要额外的CPU使用." Basic.Settings.Output.Simple.Warn.Lossless="警告:无损质量产生的文件大小非常大!无损质量在高分辨率和帧速率的情况下每分钟可使用超过 7GB 的磁盘空间。无损不适合长时间录像,除非你有很多可用的磁盘空间。" Basic.Settings.Output.Simple.Warn.Lossless.Msg="你确定你想要使用无损质量?" @@ -623,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="软件(x264 低 CPU 使 Basic.Settings.Output.VideoBitrate="视频比特率" Basic.Settings.Output.AudioBitrate="音频比特率" Basic.Settings.Output.Reconnect="自动重连" -Basic.Settings.Output.RetryDelay="重试间隔(秒)" +Basic.Settings.Output.RetryDelay="重试延迟" Basic.Settings.Output.MaxRetries="最大重试次数" Basic.Settings.Output.Advanced="启用高级编码器设置" Basic.Settings.Output.EncoderPreset="编码器预设" @@ -646,7 +664,7 @@ Basic.Settings.Output.Adv.Recording="录像" Basic.Settings.Output.Adv.Recording.Type="类型" Basic.Settings.Output.Adv.Recording.Type.Standard="标准" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="自定义输出 (FFmpeg)" -Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(使用串流编码器)" +Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(使用推流编码器)" Basic.Settings.Output.Adv.Recording.Filename="文件名格式" Basic.Settings.Output.Adv.Recording.OverwriteIfExists="如果文件存在则覆盖" Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg 输出类型" @@ -693,8 +711,9 @@ Basic.Settings.Video.CurrentlyActive="视频输出处于活动状态。请关闭 Basic.Settings.Video.DisableAero="禁用 Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="双直线法(最快, 但如果缩放会模糊)" -Basic.Settings.Video.DownscaleFilter.Bicubic="两次立方(削尖缩放, 16 个样本)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos(削尖缩放, 32个样本)" +Basic.Settings.Video.DownscaleFilter.Bicubic="双立方(锐化缩放, 16 个样本)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos(锐化缩放, 36 个样本)" +Basic.Settings.Video.DownscaleFilter.Area="区域(加权和, 4/6/9个样本)" Basic.Settings.Audio="音频" Basic.Settings.Audio.SampleRate="采样率" @@ -708,7 +727,7 @@ Basic.Settings.Audio.PeakMeterType="峰值计类型" Basic.Settings.Audio.PeakMeterType.SamplePeak="采样峰值" Basic.Settings.Audio.PeakMeterType.TruePeak="真峰值 (更高的的 CPU 使用率)" Basic.Settings.Audio.MultiChannelWarning.Enabled="警告: 已启用环绕声音频。" -Basic.Settings.Audio.MultichannelWarning="如果是串流,请检查你的串流服务是否支持环绕立体声的接收与播放。Twitch、Facebook 360 Live、Mixer RTMP、Smashcast 皆完全支持环绕立体声。虽然 Facebook Live 和 YouTube Live 都支持对环绕立体声的接收,但是 Facebook Live 将把声音混音成立体声,而 YouTube Live 则只播放两个声道。\n\n虽然无法保证 VST 插件对其的支持,但 OBS 的音频滤镜与环绕立体声兼容。" +Basic.Settings.Audio.MultichannelWarning="如果是串流,请检查你的串流服务是否支持环绕立体声的接收与播放。Facebook 360 Live、Mixer RTMP、Smashcast 皆完全支持环绕立体声。虽然 Facebook Live 和 YouTube Live 都支持对环绕立体声的接收,但是 Facebook Live 将把声音混音成立体声,而 YouTube Live 则只播放两个声道。\n\n虽然无法保证 VST 插件对其的支持,但 OBS 的音频滤镜与环绕立体声兼容。" Basic.Settings.Audio.MultichannelWarning.Title="是否启用环绕立体声?" Basic.Settings.Audio.MultichannelWarning.Confirm="确实要启用环绕立体声吗?" Basic.Settings.Audio.Devices="设备" @@ -743,23 +762,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="监听设备" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="默认" Basic.Settings.Advanced.Audio.DisableAudioDucking="禁用 Windows 音频闪避(检测到通信活动时降低其他声音的音量)" Basic.Settings.Advanced.StreamDelay="串流延迟" -Basic.Settings.Advanced.StreamDelay.Duration="延迟时间(秒)" +Basic.Settings.Advanced.StreamDelay.Duration="延迟时间" Basic.Settings.Advanced.StreamDelay.Preserve="重新连接时保持截止点 (增加延迟)" Basic.Settings.Advanced.StreamDelay.MemoryUsage="估计内存使用量:%1 MB" Basic.Settings.Advanced.Network="网络" Basic.Settings.Advanced.Network.BindToIP="绑定到 IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="启用新的网络代码" Basic.Settings.Advanced.Network.EnableLowLatencyMode="低延迟模式" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="热键与窗口焦点" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="任何时候都启用热键" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="当主窗口获得焦点时禁用热键" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="主窗口失去焦点时禁用热键" Basic.Settings.Advanced.AutoRemux="自动封装至 MP4 格式" Basic.Settings.Advanced.AutoRemux.MP4="(录制为 mkv 格式)" Basic.AdvAudio="高级音频属性" Basic.AdvAudio.Name="名称" Basic.AdvAudio.Volume="音量" -Basic.AdvAudio.Mono="混缩为单声道" +Basic.AdvAudio.Mono="单声道​" Basic.AdvAudio.Balance="平衡" -Basic.AdvAudio.SyncOffset="同步偏移 (毫秒)" +Basic.AdvAudio.SyncOffset="同步偏移" Basic.AdvAudio.Monitoring="音频监听" Basic.AdvAudio.Monitoring.None="关闭监听" Basic.AdvAudio.Monitoring.MonitorOnly="仅监听(输出静音)" @@ -825,6 +847,7 @@ SceneItemHide="隐藏“%1”" OutputWarnings.NoTracksSelected="您必须选择至少一个轨道" OutputWarnings.MultiTrackRecording="警告: 某些格式 (如 FLV) 不支持每个录像多个轨道" OutputWarnings.MP4Recording="警告:如果文件无法完成(例如,由于蓝屏BSOD,掉电等),保存到 MP4/MOV 的记录将无法恢复。如果要录制多个音轨,请考虑使用 MKV 录制,并在完成后将录像重新封装为 MP4/MOV(文件→录像转封装)" +OutputWarnings.CannotPause="警告:当录像编码器设为“(使用推流编码器)”时,无法暂停录制。" FinalScene.Title="删除场景" FinalScene.Text="至少要有一个场景." diff --git a/UI/data/locale/zh-TW.ini b/UI/data/locale/zh-TW.ini index 8c8a6f5..c7d4b7e 100644 --- a/UI/data/locale/zh-TW.ini +++ b/UI/data/locale/zh-TW.ini @@ -1,5 +1,5 @@ -Language="正體中文(臺灣)" +Language="繁體中文" Region="臺灣/香港/澳門" OK="確定" @@ -23,55 +23,55 @@ Settings="設定" Display="螢幕" Name="名稱" Exit="離開" -Mixer="混音器" +Mixer="音效混音器" Browse="瀏覽" Mono="單聲道" Stereo="立體聲" -DroppedFrames="影格遺失: %1 (%2%)" -StudioProgramProjector="全屏投影(程式)" +DroppedFrames="拋棄影格數:%1 (%2%)" +StudioProgramProjector="全螢幕投影(程式)" PreviewProjector="全螢幕投影(預覽)" SceneProjector="全螢幕投影(場景)" SourceProjector="全螢幕投影(來源)" -StudioProgramWindow="窗式投影儀(程序)" +StudioProgramWindow="視窗化投影(程式)" PreviewWindow="視窗化投影(預覽)" SceneWindow="視窗化投影(場景)" SourceWindow="視窗化投影(來源)" -MultiviewProjector="多視圖(全屏)" -MultiviewWindowed="多視圖(窗口)" +MultiviewProjector="多檢視畫面(全螢幕)" +MultiviewWindowed="多檢視畫面(視窗)" Clear="清除" Revert="復原" Show="顯示" Hide="隱藏" -UnhideAll="全部取消隱藏" +UnhideAll="全數取消隱藏" Untitled="無標題" New="新增" Duplicate="複製" Enable="啟用" -DisableOSXVSync="關閉OSX垂直同步" -ResetOSXVSyncOnExit="離開時重置OSX垂直同步" -HighResourceUsage="編碼過載!考慮降低影像設定或使用更快的編碼預設。" -Transition="轉場" +DisableOSXVSync="關閉 OSX 垂直同步" +ResetOSXVSyncOnExit="離開時重設 OSX 垂直同步" +HighResourceUsage="編碼過載!請考慮調低影像設定,或使用更快的編碼設定檔。" +Transition="轉場特效" QuickTransitions="快速轉場" Left="左" Right="右" Top="上" Bottom="下" -Reset="重置" -Hours="小時" -Minutes="分鐘" +Reset="重設" +Hours="時" +Minutes="分" Seconds="秒" -Deprecated="不再維護" -ReplayBuffer="重播緩衝" +Deprecated="已經廢棄" +ReplayBuffer="重播緩衝區" Import="匯入" Export="匯出" Copy="複製" Paste="貼上" PasteReference="貼上 (參考)" -PasteDuplicate="貼上 (重複)" -RemuxRecordings="重新封裝錄影" +PasteDuplicate="貼上 (複製)" +RemuxRecordings="重新封裝錄影檔" Next="下一步" -Back="返回" -Defaults="預設" +Back="上一步" +Defaults="預設設定檔" HideMixer="在混合器中隱藏" TransitionOverride="轉換覆蓋" None="無" @@ -85,31 +85,36 @@ Default="(預設)" Calculating="正在計算……" AlreadyRunning.Title="OBS 已在執行中" -AlreadyRunning.Text="OBS 已在執行中!除非這是您的意圖,請在執行新的 OBS 前關閉現存的 OBS 。如果有設定 OBS 最小化到系統工具列,請確認是否仍在該處執行。" -AlreadyRunning.LaunchAnyway="強制啟動" +AlreadyRunning.Text="OBS 已經執行!除非你正要這麼做,否則請在執行新實體前,先關閉現存的 OBS 實體。如果你已將 OBS 設定成最小化到系統工具列,那請檢查 OBS 是否仍在該處執行。" +AlreadyRunning.LaunchAnyway="仍然啟動" DockCloseWarning.Title="關閉停駐視窗" DockCloseWarning.Text="您剛關閉了一個停駐視窗。若想再次顯示,請重新在選單欄的「檢視」->「停駐視窗」選單開啟此視窗。" -Auth.Authing.Title="正在認證中…" +ExtraBrowsers="自訂瀏覽器停駐視窗" +ExtraBrowsers.Info="可透過提供名稱及網址來新增停駐視窗,再按下「套用」或「關閉」開啟停駐視窗。您可隨時新增或移除停駐視窗。" +ExtraBrowsers.DockName="停駐視窗名稱" + +Auth.Authing.Title="正在認證…" Auth.Authing.Text="正在透過 %1 認證,請稍候…" -Auth.AuthFailure.Title="身份驗證失敗" -Auth.AuthFailure.Text="%1 認證失敗:\n\n%2: %3" -Auth.InvalidScope.Title="需要身份驗證" -Auth.InvalidScope.Text="%1 的身份驗證要求已更改。 某些功能可能不可用。" +Auth.AuthFailure.Title="認證失敗" +Auth.AuthFailure.Text="透過 %1 認證失敗:\n\n%2:%3" +Auth.InvalidScope.Title="需要認證" +Auth.InvalidScope.Text="已變更 %1 的認證要求。可能無法使用部份功能。" Auth.LoadingChannel.Title="正在載入頻道資訊…" Auth.LoadingChannel.Text="正在載入 %1 的頻道資訊,請稍候…" Auth.ChannelFailure.Title="讀取頻道資訊失敗" -Auth.ChannelFailure.Text="讀取 %1 頻道失敗\n\n%2: %3" +Auth.ChannelFailure.Text="無法讀取 %1 頻道資訊\n\n%2: %3" Auth.Chat="聊天室" Auth.StreamInfo="實況資訊" -TwitchAuth.Stats="Twitch狀態" +TwitchAuth.Stats="Twitch 狀態" TwitchAuth.Feed="Twitch 活動摘要" TwitchAuth.TwoFactorFail.Title="無法查詢串流金鑰" -TwitchAuth.TwoFactorFail.Text="OBS 無法連線至您的 Twitch 帳號。請確保您已經在 Twitch 安全性設定 中設定串流所需的兩步驟驗證。" +TwitchAuth.TwoFactorFail.Text="OBS 無法連結您的 Twitch 帳號。請確保您已在 Twitch 安全性設定 中設定串流所需的兩步驟驗證。" +RestreamAuth.Channels="Restream 頻道" Copy.Filters="複製過濾器" -Paste.Filters="貼上篩選器" +Paste.Filters="貼上過濾器" BrowserPanelInit.Title="正在初始化瀏覽器…" BrowserPanelInit.Text="正在初始化瀏覽器,請稍候…" @@ -120,15 +125,15 @@ BandwidthTest.Region.EU="歐洲" BandwidthTest.Region.Asia="亞洲" BandwidthTest.Region.Other="其他" -Basic.FirstStartup.RunWizard="您想要運行自動設定精靈嗎? 也可以透過點選主視窗中的設定按鈕來手動設定。" -Basic.FirstStartup.RunWizard.NoClicked="如果你改變主意,可以隨時從工具功能表再次執行自動設定精靈。" +Basic.FirstStartup.RunWizard="是否執行「自動設定精靈」?您亦可藉由按下主視窗的「設定」按鈕手動設定。" +Basic.FirstStartup.RunWizard.NoClicked="若您改變主意,您隨時皆可在「工具」選單重新執行「自動設定精靈」。" Basic.AutoConfig="自動設定精靈" Basic.AutoConfig.ApplySettings="套用設定" -Basic.AutoConfig.StartPage="使用資訊" +Basic.AutoConfig.StartPage="用量資訊" Basic.AutoConfig.StartPage.SubTitle="指定想運用的場合" Basic.AutoConfig.StartPage.PrioritizeStreaming="為串流最佳化,錄影為次要的" -Basic.AutoConfig.StartPage.PrioritizeRecording="僅為錄影最佳化,將不會串流" +Basic.AutoConfig.StartPage.PrioritizeRecording="僅為錄影最佳化,不會用於串流" Basic.AutoConfig.VideoPage="影像設定" Basic.AutoConfig.VideoPage.SubTitle="指定想使用的影像設定" Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="使用現在的 (%1x%2)" @@ -136,26 +141,26 @@ Basic.AutoConfig.VideoPage.BaseResolution.Display="顯示器 %1 (%2x%3)" Basic.AutoConfig.VideoPage.FPS.UseCurrent="使用現在的 (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 或 30,但可能時優先選擇 60" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 或 30,但優先高解析度" -Basic.AutoConfig.VideoPage.CanvasExplanation="注︰ 畫布(來源)解析度並不一定與串流或錄影相同。實際的串流/錄影解析度可以從畫布解析度縮小以減少資源使用或位元率需求。" +Basic.AutoConfig.VideoPage.CanvasExplanation="註:畫布(來源)解析度並不一定與串流或錄影相同。實際的串流 / 錄影解析度,可以從畫布解析度縮小,以減少資源使用或位元率需求。" Basic.AutoConfig.StreamPage="串流資訊" Basic.AutoConfig.StreamPage.SubTitle="請輸入您的串流資訊" -Basic.AutoConfig.StreamPage.ConnectAccount="連結帳號 (選用)" -Basic.AutoConfig.StreamPage.DisconnectAccount="解除帳號連結" -Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="是否要解除帳號連結?" +Basic.AutoConfig.StreamPage.ConnectAccount="連結帳號(建議)" +Basic.AutoConfig.StreamPage.DisconnectAccount="解除連結帳號" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="是否要解除連結帳號?" Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="此變更將立即套用,確定斷開帳號連結?" Basic.AutoConfig.StreamPage.UseStreamKey="使用串流金鑰" Basic.AutoConfig.StreamPage.Service="服務" -Basic.AutoConfig.StreamPage.Service.ShowAll="顯示全部..." +Basic.AutoConfig.StreamPage.Service.ShowAll="全部顯示..." Basic.AutoConfig.StreamPage.Service.Custom="自訂…" Basic.AutoConfig.StreamPage.Server="伺服器" Basic.AutoConfig.StreamPage.StreamKey="串流金鑰" -Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(連結)" -Basic.AutoConfig.StreamPage.PerformBandwidthTest="用頻寬測試估計位元率(可能需要幾分鐘)" +Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(連結)" +Basic.AutoConfig.StreamPage.PerformBandwidthTest="藉由頻寬測試估計位元速率(可能需要幾分鐘)" Basic.AutoConfig.StreamPage.PreferHardwareEncoding="優先使用硬體編碼" Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="硬體編碼去除了大多數的 CPU 使用率,但可能需要更多的位元率以獲得同等的品質。" Basic.AutoConfig.StreamPage.StreamWarning.Title="串流警告" Basic.AutoConfig.StreamPage.StreamWarning.Text="頻寬測試即將串流隨機沒有音訊的影像資料到您的頻道。 如果能的話,建議暫時關閉保存影像串流並設定串流為私密直到完成測試。 要繼續嗎?" -Basic.AutoConfig.TestPage="最後的結果" +Basic.AutoConfig.TestPage="最終結果" Basic.AutoConfig.TestPage.SubTitle.Testing="程式目前正在執行一系列的測試以估計最理想的設定" Basic.AutoConfig.TestPage.SubTitle.Complete="測試完成" Basic.AutoConfig.TestPage.TestingBandwidth="執行頻寬測試,這可能需要幾分鐘..." @@ -240,6 +245,9 @@ ConfirmStart.Text="你確定你想要啟動串流?" ConfirmStop.Title="停止串流?" ConfirmStop.Text="你確定你想要停止串流?" +ConfirmStopRecord.Title="停止錄影?" +ConfirmStopRecord.Text="確定停止錄製?" + ConfirmBWTest.Title="開始頻寬測試?" ConfirmBWTest.Text="你已在頻寬測試模式下配置了 OBS。此模式允許在沒有開始直播的情況下進行網路測試。完成測試後,你要禁用它才可以進行直播。\n\n要繼續嗎?" @@ -255,6 +263,8 @@ Output.StartRecordingFailed="無法開始錄影" Output.StartReplayFailed="無法啟動重播緩衝區" Output.StartFailedGeneric="啟動輸出失敗。 詳情請看 Log 檔。\n\n注意︰ 如果你使用 NVENC 或 AMD 編碼器,請確保您的視頻驅動程式是最新。" +Output.ReplayBuffer.PauseWarning.Title="暫停時,無法儲存檔案。" +Output.ReplayBuffer.PauseWarning.Text="警告:錄影暫停時,將無法儲存重播。" Output.ConnectFail.Title="連線失敗" Output.ConnectFail.BadPath="無效的路徑或 URL。 請確認您的設定是正確的。" @@ -444,6 +454,8 @@ Basic.Main.StartRecording="開始錄製" Basic.Main.StartReplayBuffer="開始重播緩衝" Basic.Main.StartStreaming="開始串流" Basic.Main.StopRecording="停止錄製" +Basic.Main.PauseRecording="暫停錄影" +Basic.Main.UnpauseRecording="繼續錄製" Basic.Main.StoppingRecording="停止錄製..." Basic.Main.StopReplayBuffer="停止重播緩衝" Basic.Main.StoppingReplayBuffer="正在停止重播緩衝..." @@ -451,7 +463,7 @@ Basic.Main.StopStreaming="停止串流" Basic.Main.StoppingStreaming="停止串流..." Basic.Main.ForceStopStreaming="停止實況(丟棄延遲)" Basic.Main.Group="群組 %1" -Basic.Main.GroupItems="群組選取的項目" +Basic.Main.GroupItems="群組選取項目" Basic.Main.Ungroup="取消群組" Basic.MainMenu.File="檔案 (&F)" @@ -502,6 +514,7 @@ Basic.MainMenu.View.Toolbars="工具列(&T)" Basic.MainMenu.View.Docks="停駐視窗" Basic.MainMenu.View.Docks.ResetUI="重設使用者介面" Basic.MainMenu.View.Docks.LockUI="鎖定使用者介面" +Basic.MainMenu.View.Docks.CustomBrowserDocks="自訂瀏覽器停駐視窗…" Basic.MainMenu.View.Toolbars.Listboxes="列表控制項(&L)" Basic.MainMenu.View.SceneTransitions="轉場特效(&c)" Basic.MainMenu.View.StatusBar="狀態列(&S)" @@ -544,6 +557,7 @@ Basic.Settings.General.EnableAutoUpdates="啟動時自動檢查更新" Basic.Settings.General.OpenStatsOnStartup="在啟動時打開狀態對話欄" Basic.Settings.General.WarnBeforeStartingStream="啟動串流時顯示確認對話框" Basic.Settings.General.WarnBeforeStoppingStream="停止串流時顯示確認對話框" +Basic.Settings.General.WarnBeforeStoppingRecord="停止錄影時顯示確認對話框" Basic.Settings.General.Projectors="投影" Basic.Settings.General.HideProjectorCursor="當游標在投影上時隱藏游標" Basic.Settings.General.ProjectorAlwaysOnTop="讓投影總是在最上層" @@ -591,12 +605,15 @@ Basic.Settings.Output.Encoder="編碼器" Basic.Settings.Output.SelectDirectory="選擇錄影資料夾" Basic.Settings.Output.SelectFile="選擇錄影檔案" Basic.Settings.Output.EnforceBitrate="強制設定串流位元率上限" +Basic.Settings.Output.DynamicBitrate="動態調整位元速率以管理堵塞問題" +Basic.Settings.Output.DynamicBitrate.Beta="動態調整位元速率以管理堵塞問題 (Beta)" +Basic.Settings.Output.DynamicBitrate.TT="快速動態變更位元速率而非丟棄影格來緩解堵塞問題。\n\n註:這可能會在突發嚴重堵塞時增加觀看者的延遲。\n位元速率降低後,可能會需要幾分鐘才會恢復。\n\n目前僅支援 RTMP。" Basic.Settings.Output.Mode="輸出模式" Basic.Settings.Output.Mode.Simple="簡易" Basic.Settings.Output.Mode.Adv="進階" Basic.Settings.Output.Mode.FFmpeg="FFmpeg 輸出" Basic.Settings.Output.UseReplayBuffer="啟用重播緩衝" -Basic.Settings.Output.ReplayBuffer.SecondsMax="最大重播時間(秒)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="最大重播時間" Basic.Settings.Output.ReplayBuffer.MegabytesMax="最大記憶體使用量(MB)" Basic.Settings.Output.ReplayBuffer.Estimate="估計記憶體使用量︰ %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="無法預估記憶體使用量。請設定最大記憶體使用量。" @@ -611,6 +628,7 @@ Basic.Settings.Output.Simple.RecordingQuality.HQ="近乎無損畫質,檔案大 Basic.Settings.Output.Simple.RecordingQuality.Lossless="無損畫質,非常大的檔案" Basic.Settings.Output.Simple.Warn.VideoBitrate="警告:串流影像位元率將會被設為 %1,他是目前串流位元率的上限。如果您確定想要超過 %1 的限制,請開啟進階編碼器選項,並取消「強制設定串流位元率上限」。" Basic.Settings.Output.Simple.Warn.AudioBitrate="警告:實況串流位元率將會被設為 %1,他是目前串流位元率的上限。如果您確定想要超過 %1 的限制,請開啟進階編碼器選項,並取消「強制設定串流位元率上限」。" +Basic.Settings.Output.Simple.Warn.CannotPause="警告:如果錄影編碼器畫質設為「(和直播編碼器相同)」,錄影時將無法暫停。" Basic.Settings.Output.Simple.Warn.Encoder="警告:如果錄影與串流同時運作,並使用與串流不同的編碼品質設定將會增加額外的CPU使用量" Basic.Settings.Output.Simple.Warn.Lossless="警告:無損畫質將會產生非常大的檔案!無損畫質在高解析度或高影格率時,可能會每分鐘使用高達 7GB(gigabytes)的容量。除非您擁有非常大量的硬碟空間,否則不建議使用無損畫質錄製長時間的影片。" Basic.Settings.Output.Simple.Warn.Lossless.Msg="你確定你想要使用無損畫質?" @@ -623,7 +641,7 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="軟體編碼( x264 預設 Basic.Settings.Output.VideoBitrate="影像位元率(kbit/s)" Basic.Settings.Output.AudioBitrate="音效位元率(kbit/s)" Basic.Settings.Output.Reconnect="自動重新連線" -Basic.Settings.Output.RetryDelay="重試間隔(秒)" +Basic.Settings.Output.RetryDelay="重試延遲" Basic.Settings.Output.MaxRetries="最大嘗試次數" Basic.Settings.Output.Advanced="啓用進階編碼器設定" Basic.Settings.Output.EncoderPreset="編碼器預設" @@ -694,7 +712,8 @@ Basic.Settings.Video.DisableAero="停用 Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear(快速,但縮放時易模糊)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic(縮放後較銳利,取 16 個樣本數)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos(縮放後最為銳利,取 32 個樣本數)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos(縮放後最為銳利,取 36 個樣本數)" +Basic.Settings.Video.DownscaleFilter.Area="Area (加權總和,4/6/9 個樣本)" Basic.Settings.Audio="音效" Basic.Settings.Audio.SampleRate="取樣頻率" @@ -708,7 +727,7 @@ Basic.Settings.Audio.PeakMeterType="峰值表類型" Basic.Settings.Audio.PeakMeterType.SamplePeak="範例峰值" Basic.Settings.Audio.PeakMeterType.TruePeak="真實峰值(較高的 CPU 用量)" Basic.Settings.Audio.MultiChannelWarning.Enabled="警告: 已啟用環繞聲音訊。" -Basic.Settings.Audio.MultichannelWarning="如果是流媒體,請檢查您的流媒體服務是否同時支持環繞聲攝取和環繞聲播放。 Twitch,Facebook 360 Live,Mixer RTMP,Smashcast都是完全支持環繞聲的例子。 儘管Facebook Live和YouTube Live都接受環繞聲攝取,但是Facebook Live會混音為立體聲,而YouTube Live只播放兩個聲道。\n\n 儘管不支持VST插件,但OBS音頻濾波器與環繞聲兼容。" +Basic.Settings.Audio.MultichannelWarning="如果是流媒體,請檢查您的流媒體服務是否同時支持環繞聲攝取和環繞聲播放。 Facebook 360 Live,Mixer RTMP,Smashcast都是完全支持環繞聲的例子。 儘管Facebook Live和YouTube Live都接受環繞聲攝取,但是Facebook Live會混音為立體聲,而YouTube Live只播放兩個聲道。\n\n 儘管不支持VST插件,但OBS音頻濾波器與環繞聲兼容。" Basic.Settings.Audio.MultichannelWarning.Title="是否啟用環繞聲音訊?" Basic.Settings.Audio.MultichannelWarning.Confirm="確實要啟用環繞聲音訊嗎?" Basic.Settings.Audio.Devices="裝置" @@ -743,23 +762,26 @@ Basic.Settings.Advanced.Audio.MonitoringDevice="監測裝置" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="預設裝置" Basic.Settings.Advanced.Audio.DisableAudioDucking="停用 Windows 雙層次音量自動調整" Basic.Settings.Advanced.StreamDelay="實況延遲" -Basic.Settings.Advanced.StreamDelay.Duration="延遲(秒)" +Basic.Settings.Advanced.StreamDelay.Duration="持續時間" Basic.Settings.Advanced.StreamDelay.Preserve="重新連線時維持截止點 (增加延遲)" Basic.Settings.Advanced.StreamDelay.MemoryUsage="預計記憶體使用率: %1 MB" Basic.Settings.Advanced.Network="網路" Basic.Settings.Advanced.Network.BindToIP="綁定到 IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="啟用新的網路程式碼" Basic.Settings.Advanced.Network.EnableLowLatencyMode="低延遲模式" +Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior="快速鍵焦點行為" +Basic.Settings.Advanced.Hotkeys.NeverDisableHotkeys="永不停用快速鍵" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="當主視窗處於焦點,則停用熱鍵" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysOutOfFocus="僅在焦點不在主視窗時停用快速鍵" Basic.Settings.Advanced.AutoRemux="自動 remux 到 mp4" Basic.Settings.Advanced.AutoRemux.MP4="(錄成 mkv 格式)" Basic.AdvAudio="進階音訊屬性" Basic.AdvAudio.Name="名稱" Basic.AdvAudio.Volume="音量" -Basic.AdvAudio.Mono="混降為單聲道" +Basic.AdvAudio.Mono="單聲道" Basic.AdvAudio.Balance="聲道平衡" -Basic.AdvAudio.SyncOffset="同步位移(ms)" +Basic.AdvAudio.SyncOffset="同步位移" Basic.AdvAudio.Monitoring="音訊監測" Basic.AdvAudio.Monitoring.None="關閉監測" Basic.AdvAudio.Monitoring.MonitorOnly="僅監測(輸出為靜音)" @@ -825,6 +847,7 @@ SceneItemHide="隱藏 「%1」" OutputWarnings.NoTracksSelected="您必須至少選擇一個軌道" OutputWarnings.MultiTrackRecording="警告:某些格式 (例如 FLV) 不支援多個軌道錄製" OutputWarnings.MP4Recording="警告︰ 如果檔案沒有完整儲存(例如由於 BSOD,斷電等中斷),儲存成 MP4/MOV 的檔案將無法復原 。如果想要記錄多個音軌,請考慮儲存成 MKV ,並在完成後重新封裝成 MP4/MOV (檔案 -> 重新封裝)" +OutputWarnings.CannotPause="警告:如果錄影編碼器設為「(使用直播編碼器)」,錄影時將無法暫停。" FinalScene.Title="刪除場景" FinalScene.Text="至少要有一個場景。" diff --git a/UI/data/themes/Acri.qss b/UI/data/themes/Acri.qss index ae2ef8c..2e7aee8 100644 --- a/UI/data/themes/Acri.qss +++ b/UI/data/themes/Acri.qss @@ -42,7 +42,6 @@ QWidget { outline: none; font-family: "Open Sans", "Tahoma", "Arial", sans-serif; font-size: 12px; - overflow: auto; } #menubar { @@ -353,6 +352,10 @@ QToolButton:pressed { qproperty-icon: url(./Dark/down.svg); } +* [themeID="pauseIconSmall"] { + qproperty-icon: url(./Dark/media-pause.svg); +} + /* Tab Widget */ QTabWidget::pane { /* The tab widget frame */ @@ -647,14 +650,6 @@ QSlider::handle:disabled { /* Volume Control */ -/* Old Meters */ -VolumeMeter { - qproperty-bkColor: rgb(8,8,11); - qproperty-magColor:; - qproperty-peakColor:; - qproperty-peakHoldColor: rgb(225,224,225); -} - VolumeMeter { qproperty-backgroundNominalColor: #42740c; @@ -998,3 +993,16 @@ VisibilityCheckBox::indicator:unchecked:hover { * [themeID="revertIcon"] { qproperty-icon: url(./Dark/revert.svg); } + +QPushButton#extraPanelDelete { + background: transparent; + border: none; +} + +QPushButton#extraPanelDelete:hover { + background-color: #2a3a75; +} + +QPushButton#extraPanelDelete:pressed { + background-color: #161f41; +} diff --git a/UI/data/themes/Dark.qss b/UI/data/themes/Dark.qss index 693a556..15a4321 100644 --- a/UI/data/themes/Dark.qss +++ b/UI/data/themes/Dark.qss @@ -142,7 +142,14 @@ QDockWidget::close-button:pressed, QDockWidget::float-button:pressed { QGroupBox { border: 1px solid rgb(31,30,31); /* veryDark */; border-radius: 5px; - padding-top: 16px; + padding-top: 24px; + font-weight: bold; +} + +QGroupBox::title { + subcontrol-origin: margin; + left: 4px; + top: 4px; } @@ -253,6 +260,10 @@ QToolButton:pressed { qproperty-icon: url(./Dark/down.svg); } +* [themeID="pauseIconSmall"] { + qproperty-icon: url(./Dark/media-pause.svg); +} + /* Tab Widget */ @@ -577,6 +588,19 @@ OBSHotkeyLabel[hotkeyPairHover=true] { color: red; } +/* Pause */ +PauseCheckBox { + outline: none; +} + +PauseCheckBox::indicator:checked { + image: url(:/res/images/media-pause.svg); +} + +PauseCheckBox::indicator:unchecked { + image: url(:/res/images/media-play.svg); +} + /* Group Collapse Checkbox */ SourceTreeSubItemCheckBox { @@ -713,3 +737,15 @@ VisibilityCheckBox::indicator:unchecked { * [themeID="revertIcon"] { qproperty-icon: url(./Dark/revert.svg); } + +QPushButton#extraPanelDelete { + background-color: rgb(31, 30, 31); +} + +QPushButton#extraPanelDelete:hover { + background-color: rgb(122,121,122); +} + +QPushButton#extraPanelDelete:pressed { + background-color: rgb(31,30,31); +} diff --git a/UI/data/themes/Dark/media-pause.svg b/UI/data/themes/Dark/media-pause.svg new file mode 100644 index 0000000..6050b94 --- /dev/null +++ b/UI/data/themes/Dark/media-pause.svg @@ -0,0 +1,3 @@ + + + diff --git a/UI/data/themes/Rachni.qss b/UI/data/themes/Rachni.qss index 88bde15..7167bbc 100644 --- a/UI/data/themes/Rachni.qss +++ b/UI/data/themes/Rachni.qss @@ -507,6 +507,10 @@ QToolButton:pressed { qproperty-icon: url(./Dark/down.svg); } +* [themeID="pauseIconSmall"] { + qproperty-icon: url(./Dark/media-pause.svg); +} + /***********************/ /* --- Combo boxes --- */ /***********************/ @@ -952,7 +956,8 @@ QPushButton:checked#recordButton, QPushButton:checked[themeID="replayBufferButton"], QPushButton:checked#modeSwitch, QPushButton:checked#settingsButton, -QPushButton:checked#exitButton { +QPushButton:checked#exitButton, +QPushButton:checked[themeID="pauseIconSmall"] { background-color: rgba(240, 98, 146, 0.5); /* Pink (Secondary) */ border: 1px solid rgba(240, 98, 146, 0.5); /* Pink (Secondary) */ } @@ -1323,3 +1328,15 @@ VisibilityCheckBox::indicator:unchecked:hover { * [themeID="revertIcon"] { qproperty-icon: url(./Dark/revert.svg); } + +QPushButton#extraPanelDelete { + background-color: rgb(35, 38, 41); +} + +QPushButton#extraPanelDelete:hover { + background-color: rgba(145, 76, 103); +} + +QPushButton#extraPanelDelete:pressed { + background-color: rgb(240, 98, 146); +} diff --git a/UI/data/themes/System.qss b/UI/data/themes/System.qss index c68e0c4..0eb01cf 100644 --- a/UI/data/themes/System.qss +++ b/UI/data/themes/System.qss @@ -39,6 +39,10 @@ qproperty-icon: url(:/res/images/down.svg); } +* [themeID="pauseIconSmall"] { + qproperty-icon: url(:/res/images/media-pause.svg); +} + MuteCheckBox { outline: none; } diff --git a/UI/display-helpers.hpp b/UI/display-helpers.hpp index de0592f..5b1b20c 100644 --- a/UI/display-helpers.hpp +++ b/UI/display-helpers.hpp @@ -21,15 +21,15 @@ #define SUPPORTS_FRACTIONAL_SCALING #endif -static inline void GetScaleAndCenterPos( - int baseCX, int baseCY, int windowCX, int windowCY, - int &x, int &y, float &scale) +static inline void GetScaleAndCenterPos(int baseCX, int baseCY, int windowCX, + int windowCY, int &x, int &y, + float &scale) { double windowAspect, baseAspect; int newCX, newCY; windowAspect = double(windowCX) / double(windowCY); - baseAspect = double(baseCX) / double(baseCY); + baseAspect = double(baseCX) / double(baseCY); if (windowAspect > baseAspect) { scale = float(windowCY) / float(baseCY); @@ -41,16 +41,16 @@ static inline void GetScaleAndCenterPos( newCY = int(float(windowCX) / baseAspect); } - x = windowCX/2 - newCX/2; - y = windowCY/2 - newCY/2; + x = windowCX / 2 - newCX / 2; + y = windowCY / 2 - newCY / 2; } -static inline void GetCenterPosFromFixedScale( - int baseCX, int baseCY, int windowCX, int windowCY, - int &x, int &y, float scale) +static inline void GetCenterPosFromFixedScale(int baseCX, int baseCY, + int windowCX, int windowCY, + int &x, int &y, float scale) { - x = (float(windowCX) - float(baseCX)*scale) / 2.0f; - y = (float(windowCY) - float(baseCY)*scale) / 2.0f; + x = (float(windowCX) - float(baseCX) * scale) / 2.0f; + y = (float(windowCY) - float(baseCY) * scale) / 2.0f; } static inline QSize GetPixelSize(QWidget *widget) diff --git a/UI/double-slider.cpp b/UI/double-slider.cpp index 80fa5d6..5020418 100644 --- a/UI/double-slider.cpp +++ b/UI/double-slider.cpp @@ -4,12 +4,12 @@ DoubleSlider::DoubleSlider(QWidget *parent) : SliderIgnoreScroll(parent) { - connect(this, SIGNAL(valueChanged(int)), - this, SLOT(intValChanged(int))); + connect(this, SIGNAL(valueChanged(int)), this, + SLOT(intValChanged(int))); } void DoubleSlider::setDoubleConstraints(double newMin, double newMax, - double newStep, double val) + double newStep, double val) { minVal = newMin; maxVal = newMax; @@ -26,7 +26,7 @@ void DoubleSlider::setDoubleConstraints(double newMin, double newMax, void DoubleSlider::intValChanged(int val) { - emit doubleValChanged((minVal/minStep + val) * minStep); + emit doubleValChanged((minVal / minStep + val) * minStep); } void DoubleSlider::setDoubleVal(double val) diff --git a/UI/double-slider.hpp b/UI/double-slider.hpp index c0ec8e3..728f19f 100644 --- a/UI/double-slider.hpp +++ b/UI/double-slider.hpp @@ -11,8 +11,8 @@ class DoubleSlider : public SliderIgnoreScroll { public: DoubleSlider(QWidget *parent = nullptr); - void setDoubleConstraints(double newMin, double newMax, - double newStep, double val); + void setDoubleConstraints(double newMin, double newMax, double newStep, + double val); signals: void doubleValChanged(double val); diff --git a/UI/focus-list.hpp b/UI/focus-list.hpp index 367d387..b75e329 100644 --- a/UI/focus-list.hpp +++ b/UI/focus-list.hpp @@ -2,8 +2,7 @@ #include -class FocusList : public QListWidget -{ +class FocusList : public QListWidget { Q_OBJECT public: diff --git a/UI/forms/OBSBasic.ui b/UI/forms/OBSBasic.ui index b082729..114b7ab 100644 --- a/UI/forms/OBSBasic.ui +++ b/UI/forms/OBSBasic.ui @@ -40,30 +40,102 @@ - - - - - 0 - 0 - - - - Qt::CustomContextMenu - - - Basic.Main.PreviewDisabled - - - Qt::AlignCenter - - - 2 + + + + + 0 + 0 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + Basic.Main.PreviewDisabled + + + Qt::AlignCenter + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Basic.Main.PreviewConextMenu.Enable + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + @@ -843,7 +915,7 @@ - + :/res/images/add.png:/res/images/add.png @@ -878,7 +950,7 @@ - + :/res/images/list_remove.png:/res/images/list_remove.png @@ -913,7 +985,7 @@ - + :/res/images/configuration21_16.png:/res/images/configuration21_16.png @@ -953,7 +1025,7 @@ Basic.TransitionDuration - ms + ms 2 @@ -1000,7 +1072,7 @@ 8 - + 2 @@ -1037,29 +1109,48 @@ - - - true + + + 2 - - - 0 - 0 - + + 0 - - - 130 - 0 - + + 0 - - Basic.Main.StartRecording + + 0 - - true + + 0 - + + + + true + + + + 0 + 0 + + + + + 130 + 0 + + + + Basic.Main.StartRecording + + + true + + + + @@ -1115,7 +1206,7 @@ - + :/res/images/add.png:/res/images/add.png @@ -1127,7 +1218,7 @@ - + :/res/images/add.png:/res/images/add.png @@ -1139,7 +1230,7 @@ - + :/res/images/list_remove.png:/res/images/list_remove.png @@ -1157,7 +1248,7 @@ - + :/res/images/list_remove.png:/res/images/list_remove.png @@ -1178,7 +1269,7 @@ true - + :/res/images/properties.png:/res/images/properties.png @@ -1190,7 +1281,7 @@ - + :/res/images/up.png:/res/images/up.png @@ -1205,7 +1296,7 @@ true - + :/res/images/up.png:/res/images/up.png @@ -1217,7 +1308,7 @@ - + :/res/images/down.png:/res/images/down.png @@ -1232,7 +1323,7 @@ true - + :/res/images/down.png:/res/images/down.png @@ -1733,6 +1824,11 @@
window-dock.hpp
1 + + RecordButton + QPushButton +
record-button.hpp
+
diff --git a/UI/forms/OBSBasicSettings.ui b/UI/forms/OBSBasicSettings.ui index 328a887..a10e482 100644 --- a/UI/forms/OBSBasicSettings.ui +++ b/UI/forms/OBSBasicSettings.ui @@ -138,7 +138,7 @@ - QFrame::NoFrame + QFrame::NoFrame QFrame::Plain @@ -151,8 +151,8 @@ 0 0 - 808 - 989 + 803 + 977 @@ -291,13 +291,20 @@ + + + Basic.Settings.General.WarnBeforeStoppingRecord + + + + Basic.Settings.General.RecordWhenStreaming - + false @@ -307,14 +314,14 @@ - + Basic.Settings.General.ReplayBufferWhileStreaming - + false @@ -1159,22 +1166,22 @@ - - true - - QFrame::NoFrame + QFrame::NoFrame QFrame::Plain + + true + 0 0 - 747 - 808 + 601 + 631 @@ -3511,7 +3518,7 @@ - sec + s 5 @@ -3608,21 +3615,7 @@ - QFrame::NoFrame - - - QFrame::Plain - - - true - - - - 0 - 0 - 594 - 807 - + QFrame::NoFrame QFrame::Plain @@ -3635,8 +3628,8 @@ 0 0 - 594 - 807 + 555 + 469 @@ -4064,7 +4057,7 @@ - + @@ -4077,7 +4070,7 @@ - + @@ -4451,8 +4444,8 @@ 0 0 - 765 - 993 + 803 + 781 @@ -4895,7 +4888,7 @@
- s + s 1 @@ -4989,6 +4982,9 @@ + + s + 30 @@ -5076,14 +5072,14 @@ - + Basic.Settings.Advanced.Network.EnableNewSocketLoop - + false @@ -5093,7 +5089,7 @@ - + Qt::Horizontal @@ -5101,11 +5097,21 @@ 170 - 20 + 1 + + + + Basic.Settings.Output.DynamicBitrate.TT + + + Basic.Settings.Output.DynamicBitrate.Beta + + +
@@ -5147,17 +5153,23 @@ Basic.Settings.Hotkeys + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + 2 - - + + - Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus + Basic.Settings.Advanced.Hotkeys.HotkeyFocusBehavior - + + + + Qt::Horizontal @@ -5165,7 +5177,7 @@ 170 - 20 + 0 @@ -5246,6 +5258,7 @@ openStatsOnStartup warnBeforeStreamStart warnBeforeStreamStop + warnBeforeRecordStop recordWhenStreaming keepRecordStreamStops replayWhileStreaming @@ -5410,7 +5423,6 @@ enableNewSocketLoop enableLowLatencyMode browserHWAccel - disableFocusHotkeys diff --git a/UI/forms/OBSExtraBrowsers.ui b/UI/forms/OBSExtraBrowsers.ui new file mode 100644 index 0000000..a7d3a27 --- /dev/null +++ b/UI/forms/OBSExtraBrowsers.ui @@ -0,0 +1,98 @@ + + + OBSExtraBrowsers + + + + 0 + 0 + 785 + 353 + + + + ExtraBrowsers + + + + + + ExtraBrowsers.Info + + + true + + + + + + + QAbstractItemView::NoSelection + + + 23 + + + 23 + + + false + + + 23 + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Apply + + + + + + + Close + + + + + + + + + + + close + clicked() + OBSExtraBrowsers + close() + + + 520 + 286 + + + 435 + -19 + + + + + diff --git a/UI/forms/images/media-pause.svg b/UI/forms/images/media-pause.svg new file mode 100644 index 0000000..8e45ee2 --- /dev/null +++ b/UI/forms/images/media-pause.svg @@ -0,0 +1,3 @@ + + + diff --git a/UI/forms/obs.qrc b/UI/forms/obs.qrc index 7c647c7..87e11e3 100644 --- a/UI/forms/obs.qrc +++ b/UI/forms/obs.qrc @@ -1,5 +1,6 @@ + images/media-pause.svg images/mute.svg images/refresh.svg images/no_sources.svg diff --git a/UI/frontend-plugins/decklink-output-ui/DecklinkOutputUI.cpp b/UI/frontend-plugins/decklink-output-ui/DecklinkOutputUI.cpp index 59f25b0..68ec333 100644 --- a/UI/frontend-plugins/decklink-output-ui/DecklinkOutputUI.cpp +++ b/UI/frontend-plugins/decklink-output-ui/DecklinkOutputUI.cpp @@ -5,8 +5,7 @@ #include "decklink-ui-main.h" DecklinkOutputUI::DecklinkOutputUI(QWidget *parent) - : QDialog(parent), - ui(new Ui_Output) + : QDialog(parent), ui(new Ui_Output) { ui->setupUi(this); @@ -20,8 +19,10 @@ DecklinkOutputUI::DecklinkOutputUI(QWidget *parent) connect(ui->startOutput, SIGNAL(released()), this, SLOT(StartOutput())); connect(ui->stopOutput, SIGNAL(released()), this, SLOT(StopOutput())); - connect(ui->startPreviewOutput, SIGNAL(released()), this, SLOT(StartPreviewOutput())); - connect(ui->stopPreviewOutput, SIGNAL(released()), this, SLOT(StopPreviewOutput())); + connect(ui->startPreviewOutput, SIGNAL(released()), this, + SLOT(StartPreviewOutput())); + connect(ui->stopPreviewOutput, SIGNAL(released()), this, + SLOT(StopPreviewOutput())); } void DecklinkOutputUI::ShowHideDialog() @@ -43,25 +44,26 @@ void DecklinkOutputUI::SetupPropertiesView() if (data) obs_data_apply(settings, data); - propertiesView = new OBSPropertiesView(settings, - "decklink_output", - (PropertiesReloadCallback) obs_get_output_properties, - 170); + propertiesView = new OBSPropertiesView( + settings, "decklink_output", + (PropertiesReloadCallback)obs_get_output_properties, 170); ui->propertiesLayout->addWidget(propertiesView); obs_data_release(settings); - connect(propertiesView, SIGNAL(Changed()), this, SLOT(PropertiesChanged())); + connect(propertiesView, SIGNAL(Changed()), this, + SLOT(PropertiesChanged())); } void DecklinkOutputUI::SaveSettings() { - BPtr modulePath = obs_module_get_config_path(obs_current_module(), ""); + BPtr modulePath = + obs_module_get_config_path(obs_current_module(), ""); os_mkdirs(modulePath); - BPtr path = obs_module_get_config_path(obs_current_module(), - "decklinkOutputProps.json"); + BPtr path = obs_module_get_config_path( + obs_current_module(), "decklinkOutputProps.json"); obs_data_t *settings = propertiesView->GetSettings(); if (settings) @@ -79,15 +81,15 @@ void DecklinkOutputUI::SetupPreviewPropertiesView() if (data) obs_data_apply(settings, data); - previewPropertiesView = new OBSPropertiesView(settings, - "decklink_output", - (PropertiesReloadCallback) obs_get_output_properties, - 170); + previewPropertiesView = new OBSPropertiesView( + settings, "decklink_output", + (PropertiesReloadCallback)obs_get_output_properties, 170); ui->previewPropertiesLayout->addWidget(previewPropertiesView); obs_data_release(settings); - connect(previewPropertiesView, SIGNAL(Changed()), this, SLOT(PreviewPropertiesChanged())); + connect(previewPropertiesView, SIGNAL(Changed()), this, + SLOT(PreviewPropertiesChanged())); } void DecklinkOutputUI::SavePreviewSettings() @@ -96,15 +98,14 @@ void DecklinkOutputUI::SavePreviewSettings() os_mkdirs(modulePath); - char *path = obs_module_get_config_path(obs_current_module(), - "decklinkPreviewOutputProps.json"); + char *path = obs_module_get_config_path( + obs_current_module(), "decklinkPreviewOutputProps.json"); obs_data_t *settings = previewPropertiesView->GetSettings(); if (settings) obs_data_save_json_safe(settings, path, "tmp", "bak"); } - void DecklinkOutputUI::StartOutput() { SaveSettings(); @@ -121,7 +122,6 @@ void DecklinkOutputUI::PropertiesChanged() SaveSettings(); } - void DecklinkOutputUI::StartPreviewOutput() { SavePreviewSettings(); diff --git a/UI/frontend-plugins/decklink-output-ui/DecklinkOutputUI.h b/UI/frontend-plugins/decklink-output-ui/DecklinkOutputUI.h index 418e280..c8942e0 100644 --- a/UI/frontend-plugins/decklink-output-ui/DecklinkOutputUI.h +++ b/UI/frontend-plugins/decklink-output-ui/DecklinkOutputUI.h @@ -6,7 +6,7 @@ #include "../../UI/properties-view.hpp" class DecklinkOutputUI : public QDialog { -Q_OBJECT + Q_OBJECT private: OBSPropertiesView *propertiesView; OBSPropertiesView *previewPropertiesView; diff --git a/UI/frontend-plugins/decklink-output-ui/decklink-ui-main.cpp b/UI/frontend-plugins/decklink-output-ui/decklink-ui-main.cpp index 98c2c7b..f9f89b5 100644 --- a/UI/frontend-plugins/decklink-output-ui/decklink-ui-main.cpp +++ b/UI/frontend-plugins/decklink-output-ui/decklink-ui-main.cpp @@ -37,8 +37,8 @@ static struct preview_output context = {0}; OBSData load_settings() { - BPtr path = obs_module_get_config_path(obs_current_module(), - "decklinkOutputProps.json"); + BPtr path = obs_module_get_config_path( + obs_current_module(), "decklinkOutputProps.json"); BPtr jsonData = os_quick_read_utf8_file(path); if (!!jsonData) { obs_data_t *data = obs_data_create_from_json(jsonData); @@ -57,8 +57,9 @@ void output_start() OBSData settings = load_settings(); if (settings != nullptr) { - output = obs_output_create("decklink_output", - "decklink_output", settings, NULL); + output = obs_output_create("decklink_output", + "decklink_output", settings, + NULL); obs_output_start(output); obs_data_release(settings); @@ -77,11 +78,10 @@ void output_stop() } } - OBSData load_preview_settings() { - BPtr path = obs_module_get_config_path(obs_current_module(), - "decklinkPreviewOutputProps.json"); + BPtr path = obs_module_get_config_path( + obs_current_module(), "decklinkPreviewOutputProps.json"); BPtr jsonData = os_quick_read_utf8_file(path); if (!!jsonData) { obs_data_t *data = obs_data_create_from_json(jsonData); @@ -103,8 +103,9 @@ void preview_output_start() OBSData settings = load_preview_settings(); if (settings != nullptr) { - context.output = obs_output_create("decklink_output", - "decklink_preview_output", settings, NULL); + context.output = obs_output_create( + "decklink_output", "decklink_preview_output", + settings, NULL); obs_get_video_info(&context.ovi); @@ -112,11 +113,14 @@ void preview_output_start() uint32_t height = context.ovi.base_height; obs_enter_graphics(); - context.texrender = gs_texrender_create(GS_BGRA, GS_ZS_NONE); - context.stagesurface = gs_stagesurface_create(width, height, GS_BGRA); + context.texrender = + gs_texrender_create(GS_BGRA, GS_ZS_NONE); + context.stagesurface = + gs_stagesurface_create(width, height, GS_BGRA); obs_leave_graphics(); - const video_output_info *mainVOI = video_output_get_info(obs_get_video()); + const video_output_info *mainVOI = + video_output_get_info(obs_get_video()); video_output_info vi = {0}; vi.format = VIDEO_FORMAT_BGRA; @@ -131,15 +135,21 @@ void preview_output_start() video_output_open(&context.video_queue, &vi); - obs_frontend_add_event_callback(on_preview_scene_changed, &context); + obs_frontend_add_event_callback( + on_preview_scene_changed, &context); if (obs_frontend_preview_program_mode_active()) { - context.current_source = obs_frontend_get_current_preview_scene(); + context.current_source = + obs_frontend_get_current_preview_scene(); } else { - context.current_source = obs_frontend_get_current_scene(); + context.current_source = + obs_frontend_get_current_scene(); } - obs_add_main_render_callback(render_preview_source, &context); + obs_add_main_render_callback(render_preview_source, + &context); - obs_output_set_media(context.output, context.video_queue, obs_get_audio()); + obs_output_set_media(context.output, + context.video_queue, + obs_get_audio()); obs_output_start(context.output); preview_output_running = true; @@ -153,8 +163,10 @@ void preview_output_stop() obs_output_stop(context.output); video_output_stop(context.video_queue); - obs_remove_main_render_callback(render_preview_source, &context); - obs_frontend_remove_event_callback(on_preview_scene_changed, &context); + obs_remove_main_render_callback(render_preview_source, + &context); + obs_frontend_remove_event_callback(on_preview_scene_changed, + &context); obs_source_release(context.current_source); @@ -171,33 +183,37 @@ void preview_output_stop() void on_preview_scene_changed(enum obs_frontend_event event, void *param) { - auto ctx = (struct preview_output*)param; + auto ctx = (struct preview_output *)param; switch (event) { - case OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED: - case OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED: - obs_source_release(ctx->current_source); - ctx->current_source = obs_frontend_get_current_preview_scene(); - break; - case OBS_FRONTEND_EVENT_STUDIO_MODE_DISABLED: + case OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED: + case OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED: + obs_source_release(ctx->current_source); + ctx->current_source = obs_frontend_get_current_preview_scene(); + break; + case OBS_FRONTEND_EVENT_STUDIO_MODE_DISABLED: + obs_source_release(ctx->current_source); + ctx->current_source = obs_frontend_get_current_scene(); + break; + case OBS_FRONTEND_EVENT_SCENE_CHANGED: + if (!obs_frontend_preview_program_mode_active()) { obs_source_release(ctx->current_source); ctx->current_source = obs_frontend_get_current_scene(); - break; - case OBS_FRONTEND_EVENT_SCENE_CHANGED: - if (!obs_frontend_preview_program_mode_active()) { - obs_source_release(ctx->current_source); - ctx->current_source = obs_frontend_get_current_scene(); - } - break; - default: - break; + } + break; + default: + break; } } void render_preview_source(void *param, uint32_t cx, uint32_t cy) { - auto ctx = (struct preview_output*)param; + UNUSED_PARAMETER(cx); + UNUSED_PARAMETER(cy); - if (!ctx->current_source) return; + auto ctx = (struct preview_output *)param; + + if (!ctx->current_source) + return; uint32_t width = obs_source_get_base_width(ctx->current_source); uint32_t height = obs_source_get_base_height(ctx->current_source); @@ -209,7 +225,8 @@ void render_preview_source(void *param, uint32_t cx, uint32_t cy) vec4_zero(&background); gs_clear(GS_CLEAR_COLOR, &background, 0.0f, 0); - gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f, 100.0f); + gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f, + 100.0f); gs_blend_state_push(); gs_blend_function(GS_BLEND_ONE, GS_BLEND_ZERO); @@ -220,18 +237,25 @@ void render_preview_source(void *param, uint32_t cx, uint32_t cy) gs_texrender_end(ctx->texrender); struct video_frame output_frame; - if (video_output_lock_frame(ctx->video_queue, &output_frame, 1, os_gettime_ns())) - { - gs_stage_texture(ctx->stagesurface, gs_texrender_get_texture(ctx->texrender)); + if (video_output_lock_frame(ctx->video_queue, &output_frame, 1, + os_gettime_ns())) { + gs_stage_texture( + ctx->stagesurface, + gs_texrender_get_texture(ctx->texrender)); - if (gs_stagesurface_map(ctx->stagesurface, &ctx->video_data, &ctx->video_linesize)) { + if (gs_stagesurface_map(ctx->stagesurface, + &ctx->video_data, + &ctx->video_linesize)) { uint32_t linesize = output_frame.linesize[0]; - for (uint32_t i = 0; i < ctx->ovi.base_height; i++) { + for (uint32_t i = 0; i < ctx->ovi.base_height; + i++) { uint32_t dst_offset = linesize * i; - uint32_t src_offset = ctx->video_linesize * i; - memcpy(output_frame.data[0] + dst_offset, - ctx->video_data + src_offset, - linesize); + uint32_t src_offset = + ctx->video_linesize * i; + memcpy(output_frame.data[0] + + dst_offset, + ctx->video_data + src_offset, + linesize); } gs_stagesurface_unmap(ctx->stagesurface); @@ -245,18 +269,16 @@ void render_preview_source(void *param, uint32_t cx, uint32_t cy) void addOutputUI(void) { - QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction( - obs_module_text("Decklink Output")); + QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction( + obs_module_text("Decklink Output")); - QMainWindow *window = (QMainWindow*)obs_frontend_get_main_window(); + QMainWindow *window = (QMainWindow *)obs_frontend_get_main_window(); obs_frontend_push_ui_translation(obs_module_get_string); doUI = new DecklinkOutputUI(window); obs_frontend_pop_ui_translation(); - auto cb = []() { - doUI->ShowHideDialog(); - }; + auto cb = []() { doUI->ShowHideDialog(); }; action->connect(action, &QAction::triggered, cb); } @@ -271,7 +293,8 @@ static void OBSEvent(enum obs_frontend_event event, void *) OBSData previewSettings = load_preview_settings(); - if (previewSettings && obs_data_get_bool(previewSettings, "auto_start")) + if (previewSettings && + obs_data_get_bool(previewSettings, "auto_start")) preview_output_start(); } } diff --git a/UI/frontend-plugins/decklink-output-ui/forms/output.ui b/UI/frontend-plugins/decklink-output-ui/forms/output.ui index bfaa385..db8de92 100644 --- a/UI/frontend-plugins/decklink-output-ui/forms/output.ui +++ b/UI/frontend-plugins/decklink-output-ui/forms/output.ui @@ -115,7 +115,7 @@ - + Keyer output requires RGB mode in advanced settings. diff --git a/UI/frontend-plugins/frontend-tools/auto-scene-switcher-nix.cpp b/UI/frontend-plugins/frontend-tools/auto-scene-switcher-nix.cpp index 0575196..57d507e 100644 --- a/UI/frontend-plugins/frontend-tools/auto-scene-switcher-nix.cpp +++ b/UI/frontend-plugins/frontend-tools/auto-scene-switcher-nix.cpp @@ -17,7 +17,7 @@ using namespace std; -static Display* xdisplay = 0; +static Display *xdisplay = 0; Display *disp() { @@ -39,31 +39,22 @@ void cleanupDisplay() static bool ewmhIsSupported() { Display *display = disp(); - Atom netSupportingWmCheck = XInternAtom(display, - "_NET_SUPPORTING_WM_CHECK", true); + Atom netSupportingWmCheck = + XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", true); Atom actualType; int format = 0; unsigned long num = 0, bytes = 0; unsigned char *data = NULL; Window ewmh_window = 0; - int status = XGetWindowProperty( - display, - DefaultRootWindow(display), - netSupportingWmCheck, - 0L, - 1L, - false, - XA_WINDOW, - &actualType, - &format, - &num, - &bytes, - &data); + int status = XGetWindowProperty(display, DefaultRootWindow(display), + netSupportingWmCheck, 0L, 1L, false, + XA_WINDOW, &actualType, &format, &num, + &bytes, &data); if (status == Success) { if (num > 0) { - ewmh_window = ((Window*)data)[0]; + ewmh_window = ((Window *)data)[0]; } if (data) { XFree(data); @@ -72,21 +63,12 @@ static bool ewmhIsSupported() } if (ewmh_window) { - status = XGetWindowProperty( - display, - ewmh_window, - netSupportingWmCheck, - 0L, - 1L, - false, - XA_WINDOW, - &actualType, - &format, - &num, - &bytes, - &data); + status = XGetWindowProperty(display, ewmh_window, + netSupportingWmCheck, 0L, 1L, false, + XA_WINDOW, &actualType, &format, + &num, &bytes, &data); if (status != Success || num == 0 || - ewmh_window != ((Window*)data)[0]) { + ewmh_window != ((Window *)data)[0]) { ewmh_window = 0; } if (status == Success && data) { @@ -111,24 +93,15 @@ static std::vector getTopLevelWindows() Atom actualType; int format; unsigned long num, bytes; - Window* data = 0; + Window *data = 0; for (int i = 0; i < ScreenCount(disp()); ++i) { Window rootWin = RootWindow(disp(), i); - int status = XGetWindowProperty( - disp(), - rootWin, - netClList, - 0L, - ~0L, - false, - AnyPropertyType, - &actualType, - &format, - &num, - &bytes, - (uint8_t**)&data); + int status = XGetWindowProperty(disp(), rootWin, netClList, 0L, + ~0L, false, AnyPropertyType, + &actualType, &format, &num, + &bytes, (uint8_t **)&data); if (status != Success) { continue; @@ -147,11 +120,10 @@ static std::string GetWindowTitle(size_t i) { Window w = getTopLevelWindows().at(i); std::string windowTitle; - char* name; + char *name; int status = XFetchName(disp(), w, &name); - if (status >= Success && name != nullptr) - { + if (status >= Success && name != nullptr) { std::string str(name); windowTitle = str; } @@ -165,7 +137,7 @@ void GetWindowList(vector &windows) { windows.resize(0); - for (size_t i = 0; i < getTopLevelWindows().size(); ++i){ + for (size_t i = 0; i < getTopLevelWindows().size(); ++i) { if (GetWindowTitle(i) != "") windows.emplace_back(GetWindowTitle(i)); } @@ -181,24 +153,14 @@ void GetCurrentWindowTitle(string &title) Atom actualType; int format; unsigned long num, bytes; - Window* data = 0; - char* name; + Window *data = 0; + char *name; Window rootWin = RootWindow(disp(), 0); - XGetWindowProperty( - disp(), - rootWin, - active, - 0L, - ~0L, - false, - AnyPropertyType, - &actualType, - &format, - &num, - &bytes, - (uint8_t**)&data); + XGetWindowProperty(disp(), rootWin, active, 0L, ~0L, false, + AnyPropertyType, &actualType, &format, &num, &bytes, + (uint8_t **)&data); int status = XFetchName(disp(), data[0], &name); diff --git a/UI/frontend-plugins/frontend-tools/auto-scene-switcher-win.cpp b/UI/frontend-plugins/frontend-tools/auto-scene-switcher-win.cpp index 6045040..9d25ab3 100644 --- a/UI/frontend-plugins/frontend-tools/auto-scene-switcher-win.cpp +++ b/UI/frontend-plugins/frontend-tools/auto-scene-switcher-win.cpp @@ -32,7 +32,7 @@ static bool WindowValid(HWND window) return false; GetClientRect(window, &rect); - styles = GetWindowLongPtr(window, GWL_STYLE); + styles = GetWindowLongPtr(window, GWL_STYLE); ex_styles = GetWindowLongPtr(window, GWL_EXSTYLE); if (ex_styles & WS_EX_TOOLWINDOW) diff --git a/UI/frontend-plugins/frontend-tools/auto-scene-switcher.cpp b/UI/frontend-plugins/frontend-tools/auto-scene-switcher.cpp index e8429c4..9d87888 100644 --- a/UI/frontend-plugins/frontend-tools/auto-scene-switcher.cpp +++ b/UI/frontend-plugins/frontend-tools/auto-scene-switcher.cpp @@ -69,23 +69,19 @@ struct SwitcherData { } } - inline ~SwitcherData() - { - Stop(); - } + inline ~SwitcherData() { Stop(); } }; static SwitcherData *switcher = nullptr; static inline QString MakeSwitchName(const QString &scene, - const QString &window) + const QString &window) { return QStringLiteral("[") + scene + QStringLiteral("]: ") + window; } SceneSwitcher::SceneSwitcher(QWidget *parent) - : QDialog(parent), - ui(new Ui_SceneSwitcher) + : QDialog(parent), ui(new Ui_SceneSwitcher) { ui->setupUi(this); @@ -95,7 +91,7 @@ SceneSwitcher::SceneSwitcher(QWidget *parent) switcher->Prune(); - BPtr scenes = obs_frontend_get_scene_names(); + BPtr scenes = obs_frontend_get_scene_names(); char **temp = scenes; while (*temp) { const char *name = *temp; @@ -110,7 +106,7 @@ SceneSwitcher::SceneSwitcher(QWidget *parent) ui->noMatchDontSwitch->setChecked(true); ui->noMatchSwitchScene->setCurrentText( - GetWeakSourceName(switcher->nonMatchingScene).c_str()); + GetWeakSourceName(switcher->nonMatchingScene).c_str()); ui->checkInterval->setValue(switcher->interval); vector windows; @@ -121,11 +117,10 @@ SceneSwitcher::SceneSwitcher(QWidget *parent) for (auto &s : switcher->switches) { string sceneName = GetWeakSourceName(s.scene); - QString text = MakeSwitchName(sceneName.c_str(), - s.window.c_str()); + QString text = + MakeSwitchName(sceneName.c_str(), s.window.c_str()); - QListWidgetItem *item = new QListWidgetItem(text, - ui->switches); + QListWidgetItem *item = new QListWidgetItem(text, ui->switches); item->setData(Qt::UserRole, s.window.c_str()); } @@ -137,7 +132,7 @@ SceneSwitcher::SceneSwitcher(QWidget *parent) loading = false; } -void SceneSwitcher::closeEvent(QCloseEvent*) +void SceneSwitcher::closeEvent(QCloseEvent *) { obs_frontend_save(); } @@ -149,8 +144,7 @@ int SceneSwitcher::FindByData(const QString &window) for (int i = 0; i < count; i++) { QListWidgetItem *item = ui->switches->item(i); - QString itemWindow = - item->data(Qt::UserRole).toString(); + QString itemWindow = item->data(Qt::UserRole).toString(); if (itemWindow == window) { idx = i; @@ -206,16 +200,16 @@ void SceneSwitcher::on_add_clicked() if (idx == -1) { try { lock_guard lock(switcher->m); - switcher->switches.emplace_back(source, - windowName.toUtf8().constData()); - - QListWidgetItem *item = new QListWidgetItem(text, - ui->switches); + switcher->switches.emplace_back( + source, windowName.toUtf8().constData()); + + QListWidgetItem *item = + new QListWidgetItem(text, ui->switches); item->setData(Qt::UserRole, v); } catch (const regex_error &) { - QMessageBox::warning(this, - obs_module_text("InvalidRegex.Title"), - obs_module_text("InvalidRegex.Text")); + QMessageBox::warning( + this, obs_module_text("InvalidRegex.Title"), + obs_module_text("InvalidRegex.Text")); } } else { QListWidgetItem *item = ui->switches->item(idx); @@ -274,8 +268,7 @@ void SceneSwitcher::on_startAtLaunch_toggled(bool value) void SceneSwitcher::UpdateNonMatchingScene(const QString &name) { - obs_source_t *scene = obs_get_source_by_name( - name.toUtf8().constData()); + obs_source_t *scene = obs_get_source_by_name(name.toUtf8().constData()); obs_weak_source_t *ws = obs_source_get_weak_source(scene); switcher->nonMatchingScene = ws; @@ -303,8 +296,7 @@ void SceneSwitcher::on_noMatchSwitch_clicked() UpdateNonMatchingScene(ui->noMatchSwitchScene->currentText()); } -void SceneSwitcher::on_noMatchSwitchScene_currentTextChanged( - const QString &text) +void SceneSwitcher::on_noMatchSwitchScene_currentTextChanged(const QString &text) { if (loading) return; @@ -357,13 +349,13 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *) for (SceneSwitch &s : switcher->switches) { obs_data_t *array_obj = obs_data_create(); - obs_source_t *source = obs_weak_source_get_source( - s.scene); + obs_source_t *source = + obs_weak_source_get_source(s.scene); if (source) { const char *n = obs_source_get_name(source); obs_data_set_string(array_obj, "scene", n); obs_data_set_string(array_obj, "window_title", - s.window.c_str()); + s.window.c_str()); obs_data_array_push_back(array, array_obj); obs_source_release(source); } @@ -376,9 +368,9 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *) obs_data_set_int(obj, "interval", switcher->interval); obs_data_set_string(obj, "non_matching_scene", - nonMatchingSceneName.c_str()); + nonMatchingSceneName.c_str()); obs_data_set_bool(obj, "switch_if_not_matching", - switcher->switchIfNotMatching); + switcher->switchIfNotMatching); obs_data_set_bool(obj, "active", switcher->th.joinable()); obs_data_set_array(obj, "switches", array); @@ -389,8 +381,8 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *) } else { switcher->m.lock(); - obs_data_t *obj = obs_data_get_obj(save_data, - "auto-scene-switcher"); + obs_data_t *obj = + obs_data_get_obj(save_data, "auto-scene-switcher"); obs_data_array_t *array = obs_data_get_array(obj, "switches"); size_t count = obs_data_array_count(array); @@ -420,8 +412,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *) obs_data_get_string(array_obj, "window_title"); switcher->switches.emplace_back( - GetWeakSourceByName(scene), - window); + GetWeakSourceByName(scene), window); obs_data_release(array_obj); } @@ -476,18 +467,18 @@ void SwitcherData::Thread() for (SceneSwitch &s : switches) { try { bool matches = regex_match( - title, s.re); + title, s.re); if (matches) { match = true; scene = s.scene; break; } - } catch (const regex_error &) {} + } catch (const regex_error &) { + } } } - if (!match && switchIfNotMatching && - nonMatchingScene) { + if (!match && switchIfNotMatching && nonMatchingScene) { match = true; scene = nonMatchingScene; } @@ -513,7 +504,7 @@ void SwitcherData::Thread() void SwitcherData::Start() { if (!switcher->th.joinable()) - switcher->th = thread([] () {switcher->Thread();}); + switcher->th = thread([]() { switcher->Thread(); }); } void SwitcherData::Stop() @@ -542,17 +533,16 @@ static void OBSEvent(enum obs_frontend_event event, void *) extern "C" void InitSceneSwitcher() { - QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction( - obs_module_text("SceneSwitcher")); + QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction( + obs_module_text("SceneSwitcher")); switcher = new SwitcherData; - auto cb = [] () - { + auto cb = []() { obs_frontend_push_ui_translation(obs_module_get_string); QMainWindow *window = - (QMainWindow*)obs_frontend_get_main_window(); + (QMainWindow *)obs_frontend_get_main_window(); SceneSwitcher ss(window); ss.exec(); diff --git a/UI/frontend-plugins/frontend-tools/captions-handler.cpp b/UI/frontend-plugins/frontend-tools/captions-handler.cpp index ee9a85c..a2e5df7 100644 --- a/UI/frontend-plugins/frontend-tools/captions-handler.cpp +++ b/UI/frontend-plugins/frontend-tools/captions-handler.cpp @@ -1,33 +1,24 @@ #include "captions-handler.hpp" -captions_handler::captions_handler( - captions_cb callback, - enum audio_format format, - uint32_t sample_rate) +captions_handler::captions_handler(captions_cb callback, + enum audio_format format, + uint32_t sample_rate) : cb(callback) { if (!reset_resampler(format, sample_rate)) throw CAPTIONS_ERROR_GENERIC_FAIL; } -bool captions_handler::reset_resampler( - enum audio_format format, - uint32_t sample_rate) +bool captions_handler::reset_resampler(enum audio_format format, + uint32_t sample_rate) try { obs_audio_info ai; if (!obs_get_audio_info(&ai)) throw std::string("Failed to get OBS audio info"); - resample_info src = { - ai.samples_per_sec, - AUDIO_FORMAT_FLOAT_PLANAR, - ai.speakers - }; - resample_info dst = { - sample_rate, - format, - SPEAKERS_MONO - }; + resample_info src = {ai.samples_per_sec, AUDIO_FORMAT_FLOAT_PLANAR, + ai.speakers}; + resample_info dst = {sample_rate, format, SPEAKERS_MONO}; if (!resampler.reset(dst, src)) throw std::string("Failed to create audio resampler"); @@ -46,9 +37,9 @@ void captions_handler::push_audio(const audio_data *audio) uint64_t ts_offset; bool success; - success = audio_resampler_resample(resampler, - out, &frames, &ts_offset, - (const uint8_t *const *)audio->data, audio->frames); + success = audio_resampler_resample(resampler, out, &frames, &ts_offset, + (const uint8_t *const *)audio->data, + audio->frames); if (success) pcm_data(out[0], frames); } diff --git a/UI/frontend-plugins/frontend-tools/captions-handler.hpp b/UI/frontend-plugins/frontend-tools/captions-handler.hpp index a9f17cb..a8fd1b3 100644 --- a/UI/frontend-plugins/frontend-tools/captions-handler.hpp +++ b/UI/frontend-plugins/frontend-tools/captions-handler.hpp @@ -9,10 +9,7 @@ class resampler_obj { audio_resampler_t *resampler = nullptr; public: - inline ~resampler_obj() - { - audio_resampler_destroy(resampler); - } + inline ~resampler_obj() { audio_resampler_destroy(resampler); } inline bool reset(const resample_info &dst, const resample_info &src) { @@ -21,15 +18,15 @@ public: return !!resampler; } - inline operator audio_resampler_t*() {return resampler;} + inline operator audio_resampler_t *() { return resampler; } }; /* ------------------------------------------------------------------------- */ -typedef std::function captions_cb; +typedef std::function captions_cb; -#define captions_error(s) std::string(obs_module_text("Captions.Error." ## s)) -#define CAPTIONS_ERROR_GENERIC_FAIL captions_error("GenericFail") +#define captions_error(s) std::string(obs_module_text("Captions.Error."##s)) +#define CAPTIONS_ERROR_GENERIC_FAIL captions_error("GenericFail") /* ------------------------------------------------------------------------- */ @@ -38,22 +35,17 @@ class captions_handler { resampler_obj resampler; protected: - inline void callback(const std::string &text) - { - cb(text); - } + inline void callback(const std::string &text) { cb(text); } - virtual void pcm_data(const void *data, size_t frames)=0; + virtual void pcm_data(const void *data, size_t frames) = 0; /* always resamples to 1 channel */ bool reset_resampler(enum audio_format format, uint32_t sample_rate); public: /* throw std::string for errors shown to users */ - captions_handler( - captions_cb callback, - enum audio_format format, - uint32_t sample_rate); + captions_handler(captions_cb callback, enum audio_format format, + uint32_t sample_rate); virtual ~captions_handler() {} void push_audio(const audio_data *audio); @@ -62,6 +54,6 @@ public: /* ------------------------------------------------------------------------- */ struct captions_handler_info { - std::string (*name)(void); + std::string (*name)(void); captions_handler *(*create)(captions_cb cb, const std::string &lang); }; diff --git a/UI/frontend-plugins/frontend-tools/captions-mssapi-stream.cpp b/UI/frontend-plugins/frontend-tools/captions-mssapi-stream.cpp index 2861949..74cf550 100644 --- a/UI/frontend-plugins/frontend-tools/captions-mssapi-stream.cpp +++ b/UI/frontend-plugins/frontend-tools/captions-mssapi-stream.cpp @@ -8,16 +8,17 @@ using namespace std; #if 0 -#define debugfunc(format, ...) blog(LOG_DEBUG, "[Captions] %s(" format ")", \ - __FUNCTION__, ##__VA_ARGS__) +#define debugfunc(format, ...) \ + blog(LOG_DEBUG, "[Captions] %s(" format ")", __FUNCTION__, \ + ##__VA_ARGS__) #else #define debugfunc(format, ...) #endif -CaptionStream::CaptionStream(DWORD samplerate_, mssapi_captions *handler_) : - handler(handler_), - samplerate(samplerate_), - event(CreateEvent(nullptr, false, false, nullptr)) +CaptionStream::CaptionStream(DWORD samplerate_, mssapi_captions *handler_) + : handler(handler_), + samplerate(samplerate_), + event(CreateEvent(nullptr, false, false, nullptr)) { buf_info.ulMsMinNotification = 50; buf_info.ulMsBufferSize = 500; @@ -66,15 +67,15 @@ STDMETHODIMP CaptionStream::QueryInterface(REFIID riid, void **ppv) } else if (riid == IID_IStream) { AddRef(); - *ppv = (IStream*)this; + *ppv = (IStream *)this; } else if (riid == IID_ISpStreamFormat) { AddRef(); - *ppv = (ISpStreamFormat*)this; + *ppv = (ISpStreamFormat *)this; } else if (riid == IID_ISpAudio) { AddRef(); - *ppv = (ISpAudio*)this; + *ppv = (ISpAudio *)this; } else { *ppv = nullptr; @@ -134,8 +135,7 @@ STDMETHODIMP CaptionStream::Read(void *data, ULONG bytes, ULONG *read_bytes) return hr; } -STDMETHODIMP CaptionStream::Write(const void *, ULONG bytes, - ULONG*) +STDMETHODIMP CaptionStream::Write(const void *, ULONG bytes, ULONG *) { debugfunc("data, %lu, written_bytes", bytes); UNUSED_PARAMETER(bytes); @@ -146,7 +146,7 @@ STDMETHODIMP CaptionStream::Write(const void *, ULONG bytes, // IStream methods STDMETHODIMP CaptionStream::Seek(LARGE_INTEGER move, DWORD origin, - ULARGE_INTEGER *new_pos) + ULARGE_INTEGER *new_pos) { debugfunc("%lld, %lx, new_pos", move, origin); UNUSED_PARAMETER(move); @@ -170,8 +170,8 @@ STDMETHODIMP CaptionStream::SetSize(ULARGE_INTEGER new_size) } STDMETHODIMP CaptionStream::CopyTo(IStream *stream, ULARGE_INTEGER bytes, - ULARGE_INTEGER *read_bytes, - ULARGE_INTEGER *written_bytes) + ULARGE_INTEGER *read_bytes, + ULARGE_INTEGER *written_bytes) { HRESULT hr; @@ -213,7 +213,7 @@ STDMETHODIMP CaptionStream::Revert(void) } STDMETHODIMP CaptionStream::LockRegion(ULARGE_INTEGER offset, - ULARGE_INTEGER size, DWORD type) + ULARGE_INTEGER size, DWORD type) { debugfunc("%llu, %llu, %ld", offset, size, type); UNUSED_PARAMETER(offset); @@ -224,7 +224,7 @@ STDMETHODIMP CaptionStream::LockRegion(ULARGE_INTEGER offset, } STDMETHODIMP CaptionStream::UnlockRegion(ULARGE_INTEGER offset, - ULARGE_INTEGER size, DWORD type) + ULARGE_INTEGER size, DWORD type) { debugfunc("%llu, %llu, %ld", offset, size, type); UNUSED_PARAMETER(offset); @@ -250,7 +250,7 @@ STDMETHODIMP CaptionStream::Stat(STATSTG *stg, DWORD flag) if (flag == STATFLAG_DEFAULT) { size_t byte_size = (wcslen(stat_name) + 1) * sizeof(wchar_t); - stg->pwcsName = (wchar_t*)CoTaskMemAlloc(byte_size); + stg->pwcsName = (wchar_t *)CoTaskMemAlloc(byte_size); memcpy(stg->pwcsName, stat_name, byte_size); } @@ -267,7 +267,7 @@ STDMETHODIMP CaptionStream::Clone(IStream **stream) // ISpStreamFormat methods STDMETHODIMP CaptionStream::GetFormat(GUID *guid, - WAVEFORMATEX **co_mem_wfex_out) + WAVEFORMATEX **co_mem_wfex_out) { debugfunc("guid, co_mem_wfex_out"); @@ -282,7 +282,7 @@ STDMETHODIMP CaptionStream::GetFormat(GUID *guid, void *wfex = CoTaskMemAlloc(sizeof(format)); memcpy(wfex, &format, sizeof(format)); - *co_mem_wfex_out = (WAVEFORMATEX*)wfex; + *co_mem_wfex_out = (WAVEFORMATEX *)wfex; return S_OK; } @@ -296,7 +296,7 @@ STDMETHODIMP CaptionStream::SetState(SPAUDIOSTATE state_, ULONGLONG) } STDMETHODIMP CaptionStream::SetFormat(REFGUID guid_ref, - const WAVEFORMATEX *wfex) + const WAVEFORMATEX *wfex) { debugfunc("guid, wfex"); if (!wfex) @@ -306,7 +306,7 @@ STDMETHODIMP CaptionStream::SetFormat(REFGUID guid_ref, lock_guard lock(m); memcpy(&format, wfex, sizeof(format)); if (!handler->reset_resampler(AUDIO_FORMAT_16BIT, - wfex->nSamplesPerSec)) + wfex->nSamplesPerSec)) return E_FAIL; /* 50 msec */ @@ -354,7 +354,7 @@ STDMETHODIMP CaptionStream::GetBufferInfo(SPAUDIOBUFFERINFO *buf_info_) } STDMETHODIMP CaptionStream::GetDefaultFormat(GUID *format, - WAVEFORMATEX **co_mem_wfex_out) + WAVEFORMATEX **co_mem_wfex_out) { debugfunc("format, co_mem_wfex_out"); @@ -365,7 +365,7 @@ STDMETHODIMP CaptionStream::GetDefaultFormat(GUID *format, memcpy(wfex, &format, sizeof(format)); *format = SPDFID_WaveFormatEx; - *co_mem_wfex_out = (WAVEFORMATEX*)wfex; + *co_mem_wfex_out = (WAVEFORMATEX *)wfex; return S_OK; } diff --git a/UI/frontend-plugins/frontend-tools/captions-mssapi-stream.hpp b/UI/frontend-plugins/frontend-tools/captions-mssapi-stream.hpp index 3c1ddb4..dd755ad 100644 --- a/UI/frontend-plugins/frontend-tools/captions-mssapi-stream.hpp +++ b/UI/frontend-plugins/frontend-tools/captions-mssapi-stream.hpp @@ -13,10 +13,11 @@ class CircleBuf { circlebuf buf = {}; + public: - inline ~CircleBuf() {circlebuf_free(&buf);} - inline operator circlebuf*() {return &buf;} - inline circlebuf *operator->() {return &buf;} + inline ~CircleBuf() { circlebuf_free(&buf); } + inline operator circlebuf *() { return &buf; } + inline circlebuf *operator->() { return &buf; } }; class mssapi_captions; @@ -54,38 +55,38 @@ public: // ISequentialStream methods STDMETHODIMP Read(void *data, ULONG bytes, ULONG *read_bytes) override; - STDMETHODIMP Write(const void *data, ULONG bytes, ULONG *written_bytes) - override; + STDMETHODIMP Write(const void *data, ULONG bytes, + ULONG *written_bytes) override; // IStream methods STDMETHODIMP Seek(LARGE_INTEGER move, DWORD origin, - ULARGE_INTEGER *new_pos) override; + ULARGE_INTEGER *new_pos) override; STDMETHODIMP SetSize(ULARGE_INTEGER new_size) override; STDMETHODIMP CopyTo(IStream *stream, ULARGE_INTEGER bytes, - ULARGE_INTEGER *read_bytes, - ULARGE_INTEGER *written_bytes) override; + ULARGE_INTEGER *read_bytes, + ULARGE_INTEGER *written_bytes) override; STDMETHODIMP Commit(DWORD commit_flags) override; STDMETHODIMP Revert(void) override; STDMETHODIMP LockRegion(ULARGE_INTEGER offset, ULARGE_INTEGER size, - DWORD type) override; + DWORD type) override; STDMETHODIMP UnlockRegion(ULARGE_INTEGER offset, ULARGE_INTEGER size, - DWORD type) override; + DWORD type) override; STDMETHODIMP Stat(STATSTG *stg, DWORD flags) override; STDMETHODIMP Clone(IStream **stream) override; // ISpStreamFormat methods - STDMETHODIMP GetFormat(GUID *guid, WAVEFORMATEX **co_mem_wfex_out) - override; + STDMETHODIMP GetFormat(GUID *guid, + WAVEFORMATEX **co_mem_wfex_out) override; // ISpAudio methods STDMETHODIMP SetState(SPAUDIOSTATE state, ULONGLONG reserved) override; - STDMETHODIMP SetFormat(REFGUID guid_ref, const WAVEFORMATEX *wfex) - override; + STDMETHODIMP SetFormat(REFGUID guid_ref, + const WAVEFORMATEX *wfex) override; STDMETHODIMP GetStatus(SPAUDIOSTATUS *status) override; STDMETHODIMP SetBufferInfo(const SPAUDIOBUFFERINFO *buf_info) override; STDMETHODIMP GetBufferInfo(SPAUDIOBUFFERINFO *buf_info) override; STDMETHODIMP GetDefaultFormat(GUID *format, - WAVEFORMATEX **co_mem_wfex_out) override; + WAVEFORMATEX **co_mem_wfex_out) override; STDMETHODIMP_(HANDLE) EventHandle(void) override; STDMETHODIMP GetVolumeLevel(ULONG *level) override; STDMETHODIMP SetVolumeLevel(ULONG level) override; diff --git a/UI/frontend-plugins/frontend-tools/captions-mssapi.cpp b/UI/frontend-plugins/frontend-tools/captions-mssapi.cpp index e2cc8c4..edb4b13 100644 --- a/UI/frontend-plugins/frontend-tools/captions-mssapi.cpp +++ b/UI/frontend-plugins/frontend-tools/captions-mssapi.cpp @@ -1,16 +1,13 @@ #include "captions-mssapi.hpp" -#define do_log(type, format, ...) blog(type, "[Captions] " format, \ - ##__VA_ARGS__) +#define do_log(type, format, ...) \ + blog(type, "[Captions] " format, ##__VA_ARGS__) #define error(format, ...) do_log(LOG_ERROR, format, ##__VA_ARGS__) #define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) -mssapi_captions::mssapi_captions( - captions_cb callback, - const std::string &lang) try - : captions_handler(callback, AUDIO_FORMAT_16BIT, 16000) -{ +mssapi_captions::mssapi_captions(captions_cb callback, const std::string &lang) +try : captions_handler(callback, AUDIO_FORMAT_16BIT, 16000) { HRESULT hr; std::wstring wlang; @@ -33,7 +30,7 @@ mssapi_captions::mssapi_captions( throw HRError("SpFindBestToken failed", hr); hr = CoCreateInstance(CLSID_SpInprocRecognizer, nullptr, CLSCTX_ALL, - __uuidof(ISpRecognizer), (void**)&recognizer); + __uuidof(ISpRecognizer), (void **)&recognizer); if (FAILED(hr)) throw HRError("CoCreateInstance for recognizer failed", hr); @@ -50,7 +47,7 @@ mssapi_captions::mssapi_captions( throw HRError("CreateRecoContext failed", hr); ULONGLONG interest = SPFEI(SPEI_RECOGNITION) | - SPFEI(SPEI_END_SR_STREAM); + SPFEI(SPEI_END_SR_STREAM); hr = context->SetInterest(interest, interest); if (FAILED(hr)) throw HRError("SetInterest failed", hr); @@ -80,7 +77,7 @@ mssapi_captions::mssapi_captions( throw HRError("LoadDictation failed", hr); try { - t = std::thread([this] () {main_thread();}); + t = std::thread([this]() { main_thread(); }); } catch (...) { throw "Failed to create thread"; } @@ -133,8 +130,8 @@ try { ISpRecoResult *result = event.RecoResult(); CoTaskMemPtr text; - hr = result->GetText((ULONG)-1, (ULONG)-1, - true, &text, nullptr); + hr = result->GetText((ULONG)-1, (ULONG)-1, true, + &text, nullptr); if (FAILED(hr)) continue; @@ -168,12 +165,7 @@ void mssapi_captions::pcm_data(const void *data, size_t frames) } captions_handler_info mssapi_info = { - [] () -> std::string - { - return "Microsoft Speech-to-Text"; - }, - [] (captions_cb cb, const std::string &lang) -> captions_handler * - { + []() -> std::string { return "Microsoft Speech-to-Text"; }, + [](captions_cb cb, const std::string &lang) -> captions_handler * { return new mssapi_captions(cb, lang); - } -}; + }}; diff --git a/UI/frontend-plugins/frontend-tools/captions-mssapi.hpp b/UI/frontend-plugins/frontend-tools/captions-mssapi.hpp index aee2f1b..f0ea49c 100644 --- a/UI/frontend-plugins/frontend-tools/captions-mssapi.hpp +++ b/UI/frontend-plugins/frontend-tools/captions-mssapi.hpp @@ -27,16 +27,16 @@ class mssapi_captions : public captions_handler { friend class CaptionStream; - ComPtr audio; + ComPtr audio; ComPtr token; ComPtr grammar; - ComPtr recognizer; + ComPtr recognizer; ComPtr context; - HANDLE notify; - WinHandle stop; - std::thread t; - bool started = false; + HANDLE notify; + WinHandle stop; + std::thread t; + bool started = false; void main_thread(); diff --git a/UI/frontend-plugins/frontend-tools/captions.cpp b/UI/frontend-plugins/frontend-tools/captions.cpp index a53c09b..4928e64 100644 --- a/UI/frontend-plugins/frontend-tools/captions.cpp +++ b/UI/frontend-plugins/frontend-tools/captions.cpp @@ -31,8 +31,8 @@ #include "captions-mssapi.hpp" -#define do_log(type, format, ...) blog(type, "[Captions] " format, \ - ##__VA_ARGS__) +#define do_log(type, format, ...) \ + blog(type, "[Captions] " format, ##__VA_ARGS__) #define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) #define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) @@ -48,10 +48,10 @@ struct obs_captions { unique_ptr handler; LANGID lang_id = GetUserDefaultUILanguage(); - std::unordered_map handler_types; + std::unordered_map handler_types; inline void register_handler(const char *id, - captions_handler_info &info) + captions_handler_info &info) { handler_types.emplace(id, info); } @@ -60,7 +60,7 @@ struct obs_captions { void stop(); obs_captions(); - inline ~obs_captions() {stop();} + inline ~obs_captions() { stop(); } }; static obs_captions *captions = nullptr; @@ -74,9 +74,9 @@ struct locale_info { inline locale_info() {} inline locale_info(const locale_info &) = delete; inline locale_info(locale_info &&li) - : name(std::move(li.name)), - id(li.id) - {} + : name(std::move(li.name)), id(li.id) + { + } }; static void get_valid_locale_names(vector &names); @@ -84,16 +84,14 @@ static bool valid_lang(LANGID id); /* ------------------------------------------------------------------------- */ -CaptionsDialog::CaptionsDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui_CaptionsDialog) +CaptionsDialog::CaptionsDialog(QWidget *parent) + : QDialog(parent), ui(new Ui_CaptionsDialog) { ui->setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); - auto cb = [this] (obs_source_t *source) - { + auto cb = [this](obs_source_t *source) { uint32_t caps = obs_source_get_output_flags(source); QString name = obs_source_get_name(source); @@ -111,8 +109,11 @@ CaptionsDialog::CaptionsDialog(QWidget *parent) : ui->source->blockSignals(true); ui->source->addItem(QStringLiteral("")); ui->source->setCurrentIndex(0); - obs_enum_sources([] (void *data, obs_source_t *source) { - return (*static_cast(data))(source);}, &cb); + obs_enum_sources( + [](void *data, obs_source_t *source) { + return (*static_cast(data))(source); + }, + &cb); ui->source->blockSignals(false); for (auto &ht : captions->handler_types) { @@ -232,8 +233,8 @@ static void caption_text(const std::string &text) } } -static void audio_capture(void*, obs_source_t*, - const struct audio_data *audio, bool) +static void audio_capture(void *, obs_source_t *, + const struct audio_data *audio, bool) { captions->handler->push_audio(audio); } @@ -245,14 +246,13 @@ void obs_captions::start() auto pair = handler_types.find(handler_id); if (pair == handler_types.end()) { - warn("Failed to find handler '%s'", - handler_id.c_str()); + warn("Failed to find handler '%s'", handler_id.c_str()); return; } if (!LCIDToLocaleName(lang_id, wname, 256, 0)) { warn("Failed to get locale name: %d", - (int)GetLastError()); + (int)GetLastError()); return; } @@ -271,24 +271,24 @@ void obs_captions::start() } try { - captions_handler *h = pair->second.create(caption_text, - lang_name); + captions_handler *h = + pair->second.create(caption_text, lang_name); handler.reset(h); OBSSource s = OBSGetStrongRef(source); - obs_source_add_audio_capture_callback(s, - audio_capture, nullptr); + obs_source_add_audio_capture_callback(s, audio_capture, + nullptr); } catch (std::string text) { QWidget *window = - (QWidget*)obs_frontend_get_main_window(); + (QWidget *)obs_frontend_get_main_window(); warn("Failed to create handler: %s", text.c_str()); - QMessageBox::warning(window, + QMessageBox::warning( + window, obs_module_text("Captions.Error.GenericFail"), text.c_str()); - } } } @@ -297,8 +297,8 @@ void obs_captions::stop() { OBSSource s = OBSGetStrongRef(source); if (s) - obs_source_remove_audio_capture_callback(s, - audio_capture, nullptr); + obs_source_remove_audio_capture_callback(s, audio_capture, + nullptr); handler.reset(); } @@ -332,42 +332,18 @@ static void get_valid_locale_names(vector &locales) char locale_name[256]; static const LANGID default_locales[] = { - 0x0409, - 0x0401, - 0x0402, - 0x0403, - 0x0404, - 0x0405, - 0x0406, - 0x0407, - 0x0408, - 0x040a, - 0x040b, - 0x040c, - 0x040d, - 0x040e, - 0x040f, - 0x0410, - 0x0411, - 0x0412, - 0x0413, - 0x0414, - 0x0415, - 0x0416, - 0x0417, - 0x0418, - 0x0419, - 0x041a, - 0 - }; + 0x0409, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, + 0x0407, 0x0408, 0x040a, 0x040b, 0x040c, 0x040d, 0x040e, + 0x040f, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, + 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0}; /* ---------------------------------- */ LANGID def_id = GetUserDefaultUILanguage(); LANGID id = def_id; if (valid_lang(id) && get_locale_name(id, locale_name)) { - dstr_copy(cur.name, obs_module_text( - "Captions.CurrentSystemLanguage")); + dstr_copy(cur.name, + obs_module_text("Captions.CurrentSystemLanguage")); dstr_replace(cur.name, "%1", locale_name); cur.id = id; @@ -381,8 +357,7 @@ static void get_valid_locale_names(vector &locales) while (*locale) { id = *locale; - if (id != def_id && - valid_lang(id) && + if (id != def_id && valid_lang(id) && get_locale_name(id, locale_name)) { dstr_copy(cur.name, locale_name); @@ -418,17 +393,17 @@ static void obs_event(enum obs_frontend_event event, void *) FreeCaptions(); } -static void save_caption_data(obs_data_t *save_data, bool saving, void*) +static void save_caption_data(obs_data_t *save_data, bool saving, void *) { if (saving) { obs_data_t *obj = obs_data_create(); obs_data_set_string(obj, "source", - captions->source_name.c_str()); + captions->source_name.c_str()); obs_data_set_bool(obj, "enabled", !!captions->handler); obs_data_set_int(obj, "lang_id", captions->lang_id); obs_data_set_string(obj, "provider", - captions->handler_id.c_str()); + captions->handler_id.c_str()); obs_data_set_obj(save_data, "captions", obj); obs_data_release(obj); @@ -440,15 +415,15 @@ static void save_caption_data(obs_data_t *save_data, bool saving, void*) obj = obs_data_create(); obs_data_set_default_int(obj, "lang_id", - GetUserDefaultUILanguage()); + GetUserDefaultUILanguage()); obs_data_set_default_string(obj, "provider", DEFAULT_HANDLER); bool enabled = obs_data_get_bool(obj, "enabled"); captions->source_name = obs_data_get_string(obj, "source"); captions->lang_id = (int)obs_data_get_int(obj, "lang_id"); captions->handler_id = obs_data_get_string(obj, "provider"); - captions->source = GetWeakSourceByName( - captions->source_name.c_str()); + captions->source = + GetWeakSourceByName(captions->source_name.c_str()); obs_data_release(obj); if (enabled) @@ -458,17 +433,15 @@ static void save_caption_data(obs_data_t *save_data, bool saving, void*) extern "C" void InitCaptions() { - QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction( - obs_module_text("Captions")); + QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction( + obs_module_text("Captions")); captions = new obs_captions; - auto cb = [] () - { + auto cb = []() { obs_frontend_push_ui_translation(obs_module_get_string); - QWidget *window = - (QWidget*)obs_frontend_get_main_window(); + QWidget *window = (QWidget *)obs_frontend_get_main_window(); CaptionsDialog dialog(window); dialog.exec(); diff --git a/UI/frontend-plugins/frontend-tools/data/locale/af-ZA.ini b/UI/frontend-plugins/frontend-tools/data/locale/af-ZA.ini new file mode 100644 index 0000000..052db3b --- /dev/null +++ b/UI/frontend-plugins/frontend-tools/data/locale/af-ZA.ini @@ -0,0 +1,7 @@ +Start="Begin" +Stop="Stop" + + + + + diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ar-SA.ini b/UI/frontend-plugins/frontend-tools/data/locale/ar-SA.ini index 7c74e15..39dbcb4 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/ar-SA.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/ar-SA.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="سيتم إيقاف البث بعد:" OutputTimer.Record.StoppingIn="سيتم إيقاف التسجيل بعد:" OutputTimer.Stream.EnableEverytime="تفعيل مؤقِّت البث في كل مرة" OutputTimer.Record.EnableEverytime="تفعيل مؤقِّت التسجيل في كل مرة" +OutputTimer.Record.PauseTimer="إيقاف المُؤَقِت عندما يكون التسجيل متوقف" Scripts="سكريبتات" LoadedScripts="السكريبتات المحملة" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ca-ES.ini b/UI/frontend-plugins/frontend-tools/data/locale/ca-ES.ini index eded949..438b11a 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/ca-ES.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/ca-ES.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="La transmissió s'aturarà en:" OutputTimer.Record.StoppingIn="La gravació s'aturarà en:" OutputTimer.Stream.EnableEverytime="Activa el temporitzador en cada transmissió" OutputTimer.Record.EnableEverytime="Activa el temporitzador en cada enregistrament" +OutputTimer.Record.PauseTimer="Pausa el temporitzador en pausar l'enregistrament" Scripts="Scripts" LoadedScripts="Scripts carregats" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/cs-CZ.ini b/UI/frontend-plugins/frontend-tools/data/locale/cs-CZ.ini index 6edc823..64dda01 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/cs-CZ.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/cs-CZ.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="Vysílání se zastaví za:" OutputTimer.Record.StoppingIn="Nahrávání se zastaví za:" OutputTimer.Stream.EnableEverytime="Pokaždé povolit časovač vysílání" OutputTimer.Record.EnableEverytime="Pokaždé povolit časovač nahrávání" +OutputTimer.Record.PauseTimer="Pozastavit časovač při pozastavení nahrávání" Scripts="Skripty" LoadedScripts="Načtené skripty" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/da-DK.ini b/UI/frontend-plugins/frontend-tools/data/locale/da-DK.ini index 72eb53f..ac7080b 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/da-DK.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/da-DK.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="Streaming standser om:" OutputTimer.Record.StoppingIn="Optagelse standser om:" OutputTimer.Stream.EnableEverytime="Aktivér streamingtimer hver gang" OutputTimer.Record.EnableEverytime="Aktivér optagetimer hver gang" +OutputTimer.Record.PauseTimer="Sæt timer på pause, når optagelsen er sat på pause" Scripts="Scripts" LoadedScripts="Indlæste scripts" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/de-DE.ini b/UI/frontend-plugins/frontend-tools/data/locale/de-DE.ini index 555c8df..749ccab 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/de-DE.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/de-DE.ini @@ -4,7 +4,7 @@ SceneSwitcher.OnNoMatch.DontSwitch="Nicht wechseln" SceneSwitcher.OnNoMatch.SwitchTo="Wechseln zu:" SceneSwitcher.CheckInterval="Titel des aktiven Fensters überprüfen alle:" SceneSwitcher.ActiveOrNotActive="Szenenwechsler ist:" -InvalidRegex.Title="Ungültiger regulärer Ausdruck" +InvalidRegex.Title="Ungültiger, regulärer Ausdruck" InvalidRegex.Text="Der reguläre Ausdruck, den Sie eingegeben haben, ist ungültig." Active="Aktiv" Inactive="Inaktiv" @@ -24,16 +24,17 @@ OutputTimer.Stream.StoppingIn="Stream stoppt in:" OutputTimer.Record.StoppingIn="Aufnahme stoppt in:" OutputTimer.Stream.EnableEverytime="Streamingtimer jedes Mal aktivieren" OutputTimer.Record.EnableEverytime="Aufnahmetimer jedes Mal aktivieren" +OutputTimer.Record.PauseTimer="Timer beim Pausieren der Aufnahme anhalten" Scripts="Skripte" LoadedScripts="Geladene Skripte" AddScripts="Skripte hinzufügen" RemoveScripts="Skripte entfernen" -ReloadScripts="Skripte neu laden" -PythonSettings="Python-Einstellungen" -PythonSettings.PythonInstallPath32bit="Python-Installationspfad (32bit)" -PythonSettings.PythonInstallPath64bit="Python-Installationspfad (64bit)" -PythonSettings.BrowsePythonPath="Python-Pfad öffnen" +ReloadScripts="Skripte neuladen" +PythonSettings="Python‐Einstellungen" +PythonSettings.PythonInstallPath32bit="Python‐Installationspfad (32bit)" +PythonSettings.PythonInstallPath64bit="Python‐Installationspfad (64bit)" +PythonSettings.BrowsePythonPath="Python‐Pfad öffnen" ScriptLogWindow="Skriptprotokoll" Description="Beschreibung" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/en-US.ini b/UI/frontend-plugins/frontend-tools/data/locale/en-US.ini index c3ab608..3941435 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/en-US.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/en-US.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="Streaming stopping in:" OutputTimer.Record.StoppingIn="Recording stopping in:" OutputTimer.Stream.EnableEverytime="Enable streaming timer every time" OutputTimer.Record.EnableEverytime="Enable recording timer every time" +OutputTimer.Record.PauseTimer="Pause timer when recording is paused" Scripts="Scripts" LoadedScripts="Loaded Scripts" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/es-ES.ini b/UI/frontend-plugins/frontend-tools/data/locale/es-ES.ini index 1b6fef5..4b19980 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/es-ES.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/es-ES.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="Finalizando transmisión en:" OutputTimer.Record.StoppingIn="Finalizando grabación en:" OutputTimer.Stream.EnableEverytime="Activar temporizador en cada transmisión" OutputTimer.Record.EnableEverytime="Activar temporizador en cada grabación" +OutputTimer.Record.PauseTimer="Pausar temporizador cuando la grabación se pause" Scripts="Scripts" LoadedScripts="Scripts Cargados" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/eu-ES.ini b/UI/frontend-plugins/frontend-tools/data/locale/eu-ES.ini index d724168..4c2b9b6 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/eu-ES.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/eu-ES.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="Transmisioa geldituko da: hau barru:" OutputTimer.Record.StoppingIn="Grabazioa geldituko da hau barru:" OutputTimer.Stream.EnableEverytime="Gaitu transmisio tenporizadorea aldiro" OutputTimer.Record.EnableEverytime="Gaitu grabazio tenporizadorea aldiro" +OutputTimer.Record.PauseTimer="Pausatu tenporizadorea grabazioa pausatuta dagoenean" Scripts="Script-ak" LoadedScripts="Kargatutako script-ak" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/fr-FR.ini b/UI/frontend-plugins/frontend-tools/data/locale/fr-FR.ini index 6ebdffd..574b5bc 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/fr-FR.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/fr-FR.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="Arrêt du streaming dans :" OutputTimer.Record.StoppingIn="Arrêt de l'enregistrement dans :" OutputTimer.Stream.EnableEverytime="Démarrer le minuteur automatiquement à chaque stream" OutputTimer.Record.EnableEverytime="Démarrer le minuteur automatiquement à chaque enregistrement" +OutputTimer.Record.PauseTimer="Mettre en pause le minuteur quand l'enregistrement est mis en pause" Scripts="Scripts" LoadedScripts="Scripts chargés" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/gl-ES.ini b/UI/frontend-plugins/frontend-tools/data/locale/gl-ES.ini new file mode 100644 index 0000000..0105bea --- /dev/null +++ b/UI/frontend-plugins/frontend-tools/data/locale/gl-ES.ini @@ -0,0 +1,43 @@ +SceneSwitcher="Conmutador automático de escena" +SceneSwitcher.OnNoMatch="Cando non coincida ningunha xanela:" +SceneSwitcher.OnNoMatch.DontSwitch="Non conmutar" +SceneSwitcher.OnNoMatch.SwitchTo="Cambiar a:" +SceneSwitcher.CheckInterval="Comprobar o título da xanela activa cada:" +SceneSwitcher.ActiveOrNotActive="O conmutador de escena está:" +InvalidRegex.Title="Expresión regular non válida" +InvalidRegex.Text="A expresión regular que introduciu non é válida." +Active="Activo" +Inactive="Inactivo" +Start="Iniciar" +Stop="Parar" + +Captions="Subtítulos (experimental)" +Captions.AudioSource="Fonte de son" +Captions.CurrentSystemLanguage="Idioma actual do sistema (%1)" +Captions.Provider="Fornecedor" +Captions.Error.GenericFail="Produciuse un erro ao iniciar os suntítulos" + +OutputTimer="Temporizador de Saída" +OutputTimer.Stream="Deter a emisión após:" +OutputTimer.Record="Deter a gravación após:" +OutputTimer.Stream.StoppingIn="Detendo a emisión en:" +OutputTimer.Record.StoppingIn="Detendo a gravación en:" +OutputTimer.Stream.EnableEverytime="Activar o temporizador en cada emisión" +OutputTimer.Record.EnableEverytime="Activar o temporizador en cada gravación" +OutputTimer.Record.PauseTimer="Pór en pausa o temporizador ao pór en pausa a gravación" + +Scripts="Scripts" +LoadedScripts="Scripts cargados" +AddScripts="Engadir scripts" +RemoveScripts="Retirar scripts" +ReloadScripts="Volver cargar scripts" +PythonSettings="Axustes de Python" +PythonSettings.PythonInstallPath32bit="Ruta de instalación de Python (32bit)" +PythonSettings.PythonInstallPath64bit="Ruta de instalación de Python (64bit)" +PythonSettings.BrowsePythonPath="Examinar a ruta de Python" +ScriptLogWindow="Rexistro de script" +Description="Descrición" + +FileFilter.ScriptFiles="Ficheiros de scripts" +FileFilter.AllFiles="Todos os ficheiros" + diff --git a/UI/frontend-plugins/frontend-tools/data/locale/hu-HU.ini b/UI/frontend-plugins/frontend-tools/data/locale/hu-HU.ini index b27d52c..73f3387 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/hu-HU.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/hu-HU.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="A stream leáll:" OutputTimer.Record.StoppingIn="Felvétel leáll:" OutputTimer.Stream.EnableEverytime="Stream időzítő indítása minden alkalommal" OutputTimer.Record.EnableEverytime="Felvétel időzítő indítása minden alkalommal" +OutputTimer.Record.PauseTimer="Idő megállítása, ha a felvétel is megáll" Scripts="Szkriptek" LoadedScripts="Betöltött szkriptek" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/it-IT.ini b/UI/frontend-plugins/frontend-tools/data/locale/it-IT.ini index 45e909c..1c4daf6 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/it-IT.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/it-IT.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="La diretta terminerà tra:" OutputTimer.Record.StoppingIn="La registrazione terminerà tra:" OutputTimer.Stream.EnableEverytime="Attiva il conto alla rovescia per le dirette ogni volta" OutputTimer.Record.EnableEverytime="Attiva il conto alla rovescia per le registrazioni ogni volta" +OutputTimer.Record.PauseTimer="Pausa il timer quando la registrazione è in pausa" Scripts="Script" LoadedScripts="Script caricati" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ja-JP.ini b/UI/frontend-plugins/frontend-tools/data/locale/ja-JP.ini index fd035ba..5623a59 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/ja-JP.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/ja-JP.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="配信停止まで:" OutputTimer.Record.StoppingIn="録画停止まで:" OutputTimer.Stream.EnableEverytime="毎回配信タイマーを有効にする" OutputTimer.Record.EnableEverytime="毎回録画タイマーを有効にする" +OutputTimer.Record.PauseTimer="録画が一時停止したときにタイマーを一時停止" Scripts="スクリプト" LoadedScripts="ロードしたスクリプト" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ka-GE.ini b/UI/frontend-plugins/frontend-tools/data/locale/ka-GE.ini index fe12723..708da6c 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/ka-GE.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/ka-GE.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="ნაკადის შეწყვეტის OutputTimer.Record.StoppingIn="ჩაწერის შეწყვეტის დრო:" OutputTimer.Stream.EnableEverytime="ნაკადის წამზომის ჩართვა ყოველ ჯერზე" OutputTimer.Record.EnableEverytime="ჩაწერის წამზომის ჩართვა ყოველ ჯერზე" +OutputTimer.Record.PauseTimer="წამზომის შეჩერება ჩაწერის შეჩერებისას" Scripts="სკრიპტები" LoadedScripts="ჩატვირთული სკრიპტები" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ko-KR.ini b/UI/frontend-plugins/frontend-tools/data/locale/ko-KR.ini index d413be8..35c2d89 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/ko-KR.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/ko-KR.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="방송 중지까지 남은 시간:" OutputTimer.Record.StoppingIn="녹화 중지까지 남은 시간:" OutputTimer.Stream.EnableEverytime="매번 방송 시간 기록기 활성화" OutputTimer.Record.EnableEverytime="매번 녹화 시간 기록기 활성화" +OutputTimer.Record.PauseTimer="녹화가 중지되었을 때 타이머 일시 정지" Scripts="스크립트" LoadedScripts="입력한 스크립트" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/nl-NL.ini b/UI/frontend-plugins/frontend-tools/data/locale/nl-NL.ini index 6c8bd1e..d699608 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/nl-NL.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/nl-NL.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="Stream stopt over:" OutputTimer.Record.StoppingIn="Opname stopt over:" OutputTimer.Stream.EnableEverytime="Schakel streaming timer elke keer in" OutputTimer.Record.EnableEverytime="Schakel opnametimer elke keer in" +OutputTimer.Record.PauseTimer="Pauzeer timer tijdens het pauzeren van de opname" Scripts="Scripts" LoadedScripts="Geladen Scripts" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/pl-PL.ini b/UI/frontend-plugins/frontend-tools/data/locale/pl-PL.ini index 618338a..9c1dd7b 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/pl-PL.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/pl-PL.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="Zatrzymanie streamu za:" OutputTimer.Record.StoppingIn="Zatrzymanie nagrywania za:" OutputTimer.Stream.EnableEverytime="Włącz timer streamu za każdym razem" OutputTimer.Record.EnableEverytime="Włącz timer nagrywania za każdym razem" +OutputTimer.Record.PauseTimer="Zatrzymaj czas, gdy nagrywanie jest spauzowane" Scripts="Skrypty" LoadedScripts="Wczytane skrypty" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/pt-BR.ini b/UI/frontend-plugins/frontend-tools/data/locale/pt-BR.ini index 7056fc4..7bfe68b 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/pt-BR.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/pt-BR.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="A transmissão irá parar em:" OutputTimer.Record.StoppingIn="A gravação irá parar em:" OutputTimer.Stream.EnableEverytime="Ativar o timer streaming o tempo todo" OutputTimer.Record.EnableEverytime="Ativar o timer de gravação o tempo todo" +OutputTimer.Record.PauseTimer="Pausar o temporizador quando a gravação é pausada" Scripts="Scripts" LoadedScripts="Scripts Carregados" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ro-RO.ini b/UI/frontend-plugins/frontend-tools/data/locale/ro-RO.ini index 3e20647..794ce6a 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/ro-RO.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/ro-RO.ini @@ -10,11 +10,11 @@ Start="Pornește" Stop="Oprește" Captions="Subtitrări (experimentale)" -Captions.AudioSource="Sursa audio" +Captions.AudioSource="Sursă audio" Captions.CurrentSystemLanguage="Limba actuală a sistemului (%1)" Captions.Provider="Furnizor" -OutputTimer.Record="Opriți înregistrarea după:" +OutputTimer.Record="Oprește înregistrarea după:" OutputTimer.Stream.StoppingIn="Se oprește transmisiunea în:" OutputTimer.Record.StoppingIn="Înregistrarea se oprește în:" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ru-RU.ini b/UI/frontend-plugins/frontend-tools/data/locale/ru-RU.ini index c3b8be2..58d4ef3 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/ru-RU.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/ru-RU.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="Стрим будет завершён через OutputTimer.Record.StoppingIn="Запись будет завершена через:" OutputTimer.Stream.EnableEverytime="Включать таймер трансляции каждый раз" OutputTimer.Record.EnableEverytime="Включать таймер записи каждый раз" +OutputTimer.Record.PauseTimer="Таймер паузы при приостановке записи" Scripts="Скрипты" LoadedScripts="Загруженные скрипты" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/sl-SI.ini b/UI/frontend-plugins/frontend-tools/data/locale/sl-SI.ini new file mode 100644 index 0000000..17c6ce0 --- /dev/null +++ b/UI/frontend-plugins/frontend-tools/data/locale/sl-SI.ini @@ -0,0 +1,43 @@ +SceneSwitcher="Samodejno preklapljanje prizorov" +SceneSwitcher.OnNoMatch="Ko se nobeno okno ne ujema:" +SceneSwitcher.OnNoMatch.DontSwitch="Ne preklopi" +SceneSwitcher.OnNoMatch.SwitchTo="Preklopi na:" +SceneSwitcher.CheckInterval="Preveri naziv dejavnega okna vsakih:" +SceneSwitcher.ActiveOrNotActive="Preklopnik prizorov je:" +InvalidRegex.Title="Neveljaven regularni izraz" +InvalidRegex.Text="Vneseni regularni izraz ni veljaven." +Active="Dejaven" +Inactive="Nedejaven" +Start="Začni" +Stop="Ustavi" + +Captions="Napisi (preizkusno)" +Captions.AudioSource="Zvočni vir" +Captions.CurrentSystemLanguage="Trenutni jezik sistema (%1)" +Captions.Provider="Ponudnik" +Captions.Error.GenericFail="Zagon napisov je spodletel" + +OutputTimer="Odštevalnik izhoda" +OutputTimer.Stream="Prenehaj pretakati po:" +OutputTimer.Record="Prenehaj snemati po:" +OutputTimer.Stream.StoppingIn="Pretok se bo ustavil čez:" +OutputTimer.Record.StoppingIn="Snemanje se bo ustavilo čez:" +OutputTimer.Stream.EnableEverytime="Vsakič omogoči odštevalnik pretakanja" +OutputTimer.Record.EnableEverytime="Vsakič omogoči odštevalnik snemanja" +OutputTimer.Record.PauseTimer="Premor odštevalnika ob premoru snemanja" + +Scripts="Skripti" +LoadedScripts="Naloženi skripti" +AddScripts="Dodaj skripte" +RemoveScripts="Odstrani skripte" +ReloadScripts="Ponovno naloži skripte" +PythonSettings="Nastavitve Python" +PythonSettings.PythonInstallPath32bit="Namestitvena pot Pythona (32-bitni)" +PythonSettings.PythonInstallPath64bit="Namestitvena pot Pythona (64-bitni)" +PythonSettings.BrowsePythonPath="Prebrskaj pot do Pythona" +ScriptLogWindow="Dnevnik skriptov" +Description="Opis" + +FileFilter.ScriptFiles="Datoteke skriptov" +FileFilter.AllFiles="Vse datoteke" + diff --git a/UI/frontend-plugins/frontend-tools/data/locale/sv-SE.ini b/UI/frontend-plugins/frontend-tools/data/locale/sv-SE.ini index ecf4e3a..c7bdc2b 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/sv-SE.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/sv-SE.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="Streamen stoppas om:" OutputTimer.Record.StoppingIn="Inspelningen stoppas om:" OutputTimer.Stream.EnableEverytime="Aktivera strömtimer varje gång" OutputTimer.Record.EnableEverytime="Aktivera inspelningstimer varje gång" +OutputTimer.Record.PauseTimer="Pausa timer när inspelning pausas" Scripts="Skript" LoadedScripts="Inlästa skript" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/th-TH.ini b/UI/frontend-plugins/frontend-tools/data/locale/th-TH.ini index d53ebb1..e064b3d 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/th-TH.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/th-TH.ini @@ -1,3 +1,8 @@ +SceneSwitcher="สลับฉากอัตโนมัติ" +SceneSwitcher.OnNoMatch="เมื่อหน้าต่างไม่สัมพันธ์กัน:" +SceneSwitcher.OnNoMatch.DontSwitch="ไม่สลับ" +SceneSwitcher.OnNoMatch.SwitchTo="สลับไปยัง:" +SceneSwitcher.CheckInterval="ตรวจสอบหน้าต่างที่ถูกเลือกทุกๆ" Active="ใช้งานอยู่" Inactive="ไม่ใช้งาน" Start="เริ่ม" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/tr-TR.ini b/UI/frontend-plugins/frontend-tools/data/locale/tr-TR.ini index 857edac..7d6e09a 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/tr-TR.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/tr-TR.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="Yayın durduruluyor:" OutputTimer.Record.StoppingIn="Kayıt durduruluyor:" OutputTimer.Stream.EnableEverytime="Her zaman yayın zamanlayıcıyı etkinleştir" OutputTimer.Record.EnableEverytime="Her zaman kayıt zamanlayıcıyı etkinleştir" +OutputTimer.Record.PauseTimer="Kayıt durdurulduğunda sayacı durdur" Scripts="Betikler" LoadedScripts="Yüklü Betikler" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/uk-UA.ini b/UI/frontend-plugins/frontend-tools/data/locale/uk-UA.ini index f445349..a9c49f6 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/uk-UA.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/uk-UA.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="Трансляція припиниться за: OutputTimer.Record.StoppingIn="Запис зупиниться за:" OutputTimer.Stream.EnableEverytime="Щоразу запускається трансляція - вмикати Таймер для Виводу" OutputTimer.Record.EnableEverytime="Щоразу починається запис - вмикати Таймер для Виводу" +OutputTimer.Record.PauseTimer="Призупиняти таймер коли запис Призупинено" Scripts="Скрипти" LoadedScripts="Завантажені скрипти" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/zh-CN.ini b/UI/frontend-plugins/frontend-tools/data/locale/zh-CN.ini index acd3d5f..19ba0f0 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/zh-CN.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/zh-CN.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="串流停止在:" OutputTimer.Record.StoppingIn="录制停止在:" OutputTimer.Stream.EnableEverytime="每次启用流计时器" OutputTimer.Record.EnableEverytime="每次启用录制计时器" +OutputTimer.Record.PauseTimer="暂停录制时暂停计时器" Scripts="脚本" LoadedScripts="已载入脚本" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/zh-TW.ini b/UI/frontend-plugins/frontend-tools/data/locale/zh-TW.ini index b82fd69..9fc8b6d 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/zh-TW.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/zh-TW.ini @@ -24,6 +24,7 @@ OutputTimer.Stream.StoppingIn="串流將在下面時間內停止" OutputTimer.Record.StoppingIn="錄影將在下面時間內停止" OutputTimer.Stream.EnableEverytime="每次都啟動串流計時器" OutputTimer.Record.EnableEverytime="每次都啟動錄影計時器" +OutputTimer.Record.PauseTimer="錄影暫停時,計時器也暫停。" Scripts="腳本" LoadedScripts="已載入腳本" diff --git a/UI/frontend-plugins/frontend-tools/data/scripts/pause-scene.lua b/UI/frontend-plugins/frontend-tools/data/scripts/pause-scene.lua new file mode 100644 index 0000000..4563cdf --- /dev/null +++ b/UI/frontend-plugins/frontend-tools/data/scripts/pause-scene.lua @@ -0,0 +1,44 @@ +obs = obslua +pause_scene = "" + +function on_event(event) + if event == obs.OBS_FRONTEND_EVENT_SCENE_CHANGED then + local scene = obs.obs_frontend_get_current_scene() + local scene_name = obs.obs_source_get_name(scene) + if pause_scene == scene_name then + obs.obs_frontend_recording_pause(true) + else + obs.obs_frontend_recording_pause(false) + end + + obs.obs_source_release(scene); + end +end + +function script_properties() + local props = obs.obs_properties_create() + + local p = obs.obs_properties_add_list(props, "pause_scene", "Pause Scene", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING) + local scenes = obs.obs_frontend_get_scenes() + if scenes ~= nil then + for _, scene in ipairs(scenes) do + local name = obs.obs_source_get_name(scene); + obs.obs_property_list_add_string(p, name, name) + end + end + obs.source_list_release(scenes) + + return props +end + +function script_description() + return "Adds the ability to pause recording when switching to a specific scene" +end + +function script_update(settings) + pause_scene = obs.obs_data_get_string(settings, "pause_scene") +end + +function script_load(settings) + obs.obs_frontend_add_event_callback(on_event) +end diff --git a/UI/frontend-plugins/frontend-tools/forms/output-timer.ui b/UI/frontend-plugins/frontend-tools/forms/output-timer.ui index e56ae42..d96d71e 100644 --- a/UI/frontend-plugins/frontend-tools/forms/output-timer.ui +++ b/UI/frontend-plugins/frontend-tools/forms/output-timer.ui @@ -1,215 +1,237 @@ OutputTimer - - - - 0 - 0 - 600 - 200 - - - - OutputTimer - - - - - - OutputTimer.Stream - - - - - - - 0 - - - 24 - - - 0 - - - - - - - Hours - - - - - - - 59 - - - 0 - - - - - - - Minutes - - - - - - - 0 - - - 59 - - - 30 - - - - - - - Seconds - - - - - - - Start - - - - - - - OutputTimer.Stream.StoppingIn - - - - - - - 00:00:00 - - - - - - - OutputTimer.Record - - - - - - - 0 - - - 24 - - - 0 - - - - - - - Hours - - - - - - - 0 - - - 59 - - - 0 - - - - - - - Minutes - - - - - - - 0 - - - 59 - - - 30 - - - - - - - Seconds - - - - - - - Start - - - - - - - OutputTimer.Record.StoppingIn - - - - - - - 00:00:00 - - - - - - - OutputTimer.Stream.EnableEverytime - - - - - - - OutputTimer.Record.EnableEverytime - - - - - - - QDialogButtonBox::Close - - - - - - - + + + + 0 + 0 + 697 + 240 + + + + OutputTimer + + + + + + Hours + + + + + + + 0 + + + 24 + + + 0 + + + + + + + 0 + + + 59 + + + 30 + + + + + + + Start + + + true + + + + + + + 0 + + + 59 + + + 0 + + + + + + + OutputTimer.Stream + + + + + + + 59 + + + 0 + + + + + + + Start + + + true + + + + + + + OutputTimer.Record.StoppingIn + + + + + + + Seconds + + + + + + + 00:00:00 + + + + + + + Minutes + + + + + + + 0 + + + 24 + + + 0 + + + + + + + 00:00:00 + + + + + + + Minutes + + + + + + + OutputTimer.Record + + + + + + + 0 + + + 59 + + + 30 + + + + + + + OutputTimer.Stream.EnableEverytime + + + + + + + OutputTimer.Stream.StoppingIn + + + + + + + OutputTimer.Record.EnableEverytime + + + + + + + QDialogButtonBox::Close + + + + + + + Hours + + + + + + + Seconds + + + + + + + + 0 + 0 + + + + OutputTimer.Record.PauseTimer + + + true + + + + + + + diff --git a/UI/frontend-plugins/frontend-tools/output-timer.cpp b/UI/frontend-plugins/frontend-tools/output-timer.cpp index c889f4f..f6a86d0 100644 --- a/UI/frontend-plugins/frontend-tools/output-timer.cpp +++ b/UI/frontend-plugins/frontend-tools/output-timer.cpp @@ -13,19 +13,18 @@ using namespace std; OutputTimer *ot; OutputTimer::OutputTimer(QWidget *parent) - : QDialog(parent), - ui(new Ui_OutputTimer) + : QDialog(parent), ui(new Ui_OutputTimer) { ui->setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); QObject::connect(ui->outputTimerStream, SIGNAL(clicked()), this, - SLOT(StreamingTimerButton())); + SLOT(StreamingTimerButton())); QObject::connect(ui->outputTimerRecord, SIGNAL(clicked()), this, - SLOT(RecordingTimerButton())); + SLOT(RecordingTimerButton())); QObject::connect(ui->buttonBox->button(QDialogButtonBox::Close), - SIGNAL(clicked()), this, SLOT(hide())); + SIGNAL(clicked()), this, SLOT(hide())); streamingTimer = new QTimer(this); streamingTimerDisplay = new QTimer(this); @@ -34,7 +33,7 @@ OutputTimer::OutputTimer(QWidget *parent) recordingTimerDisplay = new QTimer(this); } -void OutputTimer::closeEvent(QCloseEvent*) +void OutputTimer::closeEvent(QCloseEvent *) { obs_frontend_save(); } @@ -78,9 +77,7 @@ void OutputTimer::StreamTimerStart() int minutes = ui->streamingTimerMinutes->value(); int seconds = ui->streamingTimerSeconds->value(); - int total = (((hours * 3600) + - (minutes * 60)) + - seconds) * 1000; + int total = (((hours * 3600) + (minutes * 60)) + seconds) * 1000; if (total == 0) total = 1000; @@ -89,16 +86,18 @@ void OutputTimer::StreamTimerStart() streamingTimer->setSingleShot(true); QObject::connect(streamingTimer, SIGNAL(timeout()), - SLOT(EventStopStreaming())); + SLOT(EventStopStreaming())); QObject::connect(streamingTimerDisplay, SIGNAL(timeout()), this, - SLOT(UpdateStreamTimerDisplay())); + SLOT(UpdateStreamTimerDisplay())); streamingTimer->start(); streamingTimerDisplay->start(1000); ui->outputTimerStream->setText(obs_module_text("Stop")); UpdateStreamTimerDisplay(); + + ui->outputTimerStream->setChecked(true); } void OutputTimer::RecordTimerStart() @@ -112,9 +111,7 @@ void OutputTimer::RecordTimerStart() int minutes = ui->recordingTimerMinutes->value(); int seconds = ui->recordingTimerSeconds->value(); - int total = (((hours * 3600) + - (minutes * 60)) + - seconds) * 1000; + int total = (((hours * 3600) + (minutes * 60)) + seconds) * 1000; if (total == 0) total = 1000; @@ -123,16 +120,18 @@ void OutputTimer::RecordTimerStart() recordingTimer->setSingleShot(true); QObject::connect(recordingTimer, SIGNAL(timeout()), - SLOT(EventStopRecording())); + SLOT(EventStopRecording())); QObject::connect(recordingTimerDisplay, SIGNAL(timeout()), this, - SLOT(UpdateRecordTimerDisplay())); + SLOT(UpdateRecordTimerDisplay())); recordingTimer->start(); recordingTimerDisplay->start(1000); ui->outputTimerRecord->setText(obs_module_text("Stop")); UpdateRecordTimerDisplay(); + + ui->outputTimerRecord->setChecked(true); } void OutputTimer::StreamTimerStop() @@ -151,6 +150,7 @@ void OutputTimer::StreamTimerStop() streamingTimerDisplay->stop(); ui->streamTime->setText("00:00:00"); + ui->outputTimerStream->setChecked(false); } void OutputTimer::RecordTimerStop() @@ -169,6 +169,7 @@ void OutputTimer::RecordTimerStop() recordingTimerDisplay->stop(); ui->recordTime->setText("00:00:00"); + ui->outputTimerRecord->setChecked(false); } void OutputTimer::UpdateStreamTimerDisplay() @@ -186,7 +187,13 @@ void OutputTimer::UpdateStreamTimerDisplay() void OutputTimer::UpdateRecordTimerDisplay() { - int remainingTime = recordingTimer->remainingTime() / 1000; + int remainingTime = 0; + + if (obs_frontend_recording_paused() && + ui->pauseRecordTimer->isChecked()) + remainingTime = recordingTimeLeft / 1000; + else + remainingTime = recordingTimer->remainingTime() / 1000; int seconds = remainingTime % 60; int minutes = (remainingTime % 3600) / 60; @@ -197,6 +204,26 @@ void OutputTimer::UpdateRecordTimerDisplay() ui->recordTime->setText(text); } +void OutputTimer::PauseRecordingTimer() +{ + if (!ui->pauseRecordTimer->isChecked()) + return; + + if (recordingTimer->isActive()) { + recordingTimeLeft = recordingTimer->remainingTime(); + recordingTimer->stop(); + } +} + +void OutputTimer::UnpauseRecordingTimer() +{ + if (!ui->pauseRecordTimer->isChecked()) + return; + + if (!recordingTimer->isActive()) + recordingTimer->start(recordingTimeLeft); +} + void OutputTimer::ShowHideDialog() { if (!isVisible()) { @@ -226,60 +253,63 @@ static void SaveOutputTimer(obs_data_t *save_data, bool saving, void *) obs_data_t *obj = obs_data_create(); obs_data_set_int(obj, "streamTimerHours", - ot->ui->streamingTimerHours->value()); + ot->ui->streamingTimerHours->value()); obs_data_set_int(obj, "streamTimerMinutes", - ot->ui->streamingTimerMinutes->value()); + ot->ui->streamingTimerMinutes->value()); obs_data_set_int(obj, "streamTimerSeconds", - ot->ui->streamingTimerSeconds->value()); + ot->ui->streamingTimerSeconds->value()); obs_data_set_int(obj, "recordTimerHours", - ot->ui->recordingTimerHours->value()); + ot->ui->recordingTimerHours->value()); obs_data_set_int(obj, "recordTimerMinutes", - ot->ui->recordingTimerMinutes->value()); + ot->ui->recordingTimerMinutes->value()); obs_data_set_int(obj, "recordTimerSeconds", - ot->ui->recordingTimerSeconds->value()); + ot->ui->recordingTimerSeconds->value()); obs_data_set_bool(obj, "autoStartStreamTimer", - ot->ui->autoStartStreamTimer->isChecked()); + ot->ui->autoStartStreamTimer->isChecked()); obs_data_set_bool(obj, "autoStartRecordTimer", - ot->ui->autoStartRecordTimer->isChecked()); + ot->ui->autoStartRecordTimer->isChecked()); + + obs_data_set_bool(obj, "pauseRecordTimer", + ot->ui->pauseRecordTimer->isChecked()); obs_data_set_obj(save_data, "output-timer", obj); obs_data_release(obj); } else { - obs_data_t *obj = obs_data_get_obj(save_data, - "output-timer"); + obs_data_t *obj = obs_data_get_obj(save_data, "output-timer"); if (!obj) obj = obs_data_create(); ot->ui->streamingTimerHours->setValue( - obs_data_get_int(obj, "streamTimerHours")); + obs_data_get_int(obj, "streamTimerHours")); ot->ui->streamingTimerMinutes->setValue( - obs_data_get_int(obj, "streamTimerMinutes")); + obs_data_get_int(obj, "streamTimerMinutes")); ot->ui->streamingTimerSeconds->setValue( - obs_data_get_int(obj, "streamTimerSeconds")); + obs_data_get_int(obj, "streamTimerSeconds")); ot->ui->recordingTimerHours->setValue( - obs_data_get_int(obj, "recordTimerHours")); + obs_data_get_int(obj, "recordTimerHours")); ot->ui->recordingTimerMinutes->setValue( - obs_data_get_int(obj, "recordTimerMinutes")); + obs_data_get_int(obj, "recordTimerMinutes")); ot->ui->recordingTimerSeconds->setValue( - obs_data_get_int(obj, "recordTimerSeconds")); + obs_data_get_int(obj, "recordTimerSeconds")); ot->ui->autoStartStreamTimer->setChecked( - obs_data_get_bool(obj, "autoStartStreamTimer")); + obs_data_get_bool(obj, "autoStartStreamTimer")); ot->ui->autoStartRecordTimer->setChecked( - obs_data_get_bool(obj, "autoStartRecordTimer")); + obs_data_get_bool(obj, "autoStartRecordTimer")); + + ot->ui->pauseRecordTimer->setChecked( + obs_data_get_bool(obj, "pauseRecordTimer")); obs_data_release(obj); } } -extern "C" void FreeOutputTimer() -{ -} +extern "C" void FreeOutputTimer() {} static void OBSEvent(enum obs_frontend_event event, void *) { @@ -294,24 +324,25 @@ static void OBSEvent(enum obs_frontend_event event, void *) ot->RecordTimerStart(); } else if (event == OBS_FRONTEND_EVENT_RECORDING_STOPPING) { ot->RecordTimerStop(); + } else if (event == OBS_FRONTEND_EVENT_RECORDING_PAUSED) { + ot->PauseRecordingTimer(); + } else if (event == OBS_FRONTEND_EVENT_RECORDING_UNPAUSED) { + ot->UnpauseRecordingTimer(); } } extern "C" void InitOutputTimer() { - QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction( - obs_module_text("OutputTimer")); + QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction( + obs_module_text("OutputTimer")); obs_frontend_push_ui_translation(obs_module_get_string); - QMainWindow *window = (QMainWindow*)obs_frontend_get_main_window(); + QMainWindow *window = (QMainWindow *)obs_frontend_get_main_window(); ot = new OutputTimer(window); - auto cb = [] () - { - ot->ShowHideDialog(); - }; + auto cb = []() { ot->ShowHideDialog(); }; obs_frontend_pop_ui_translation(); diff --git a/UI/frontend-plugins/frontend-tools/output-timer.hpp b/UI/frontend-plugins/frontend-tools/output-timer.hpp index ff3b733..97867b8 100644 --- a/UI/frontend-plugins/frontend-tools/output-timer.hpp +++ b/UI/frontend-plugins/frontend-tools/output-timer.hpp @@ -15,6 +15,8 @@ public: OutputTimer(QWidget *parent); void closeEvent(QCloseEvent *event) override; + void PauseRecordingTimer(); + void UnpauseRecordingTimer(); public slots: void StreamingTimerButton(); @@ -37,4 +39,6 @@ private: QTimer *recordingTimer; QTimer *streamingTimerDisplay; QTimer *recordingTimerDisplay; + + int recordingTimeLeft; }; diff --git a/UI/frontend-plugins/frontend-tools/scripts.cpp b/UI/frontend-plugins/frontend-tools/scripts.cpp index 160032b..de43316 100644 --- a/UI/frontend-plugins/frontend-tools/scripts.cpp +++ b/UI/frontend-plugins/frontend-tools/scripts.cpp @@ -43,7 +43,7 @@ /* ----------------------------------------------------------------- */ -using OBSScript = OBSObj; +using OBSScript = OBSObj; struct ScriptData { std::vector scripts; @@ -92,11 +92,10 @@ ScriptLogWindow::ScriptLogWindow() : QWidget(nullptr) QHBoxLayout *buttonLayout = new QHBoxLayout(); QPushButton *clearButton = new QPushButton(tr("Clear")); - connect(clearButton, &QPushButton::clicked, - this, &ScriptLogWindow::ClearWindow); + connect(clearButton, &QPushButton::clicked, this, + &ScriptLogWindow::ClearWindow); QPushButton *closeButton = new QPushButton(tr("Close")); - connect(closeButton, &QPushButton::clicked, - this, &QDialog::hide); + connect(closeButton, &QPushButton::clicked, this, &QDialog::hide); buttonLayout->addStretch(); buttonLayout->addWidget(clearButton); @@ -112,8 +111,8 @@ ScriptLogWindow::ScriptLogWindow() : QWidget(nullptr) resize(600, 400); config_t *global_config = obs_frontend_get_global_config(); - const char *geom = config_get_string(global_config, - "ScriptLogWindow", "geometry"); + const char *geom = + config_get_string(global_config, "ScriptLogWindow", "geometry"); if (geom != nullptr) { QByteArray ba = QByteArray::fromBase64(QByteArray(geom)); restoreGeometry(ba); @@ -121,16 +120,15 @@ ScriptLogWindow::ScriptLogWindow() : QWidget(nullptr) setWindowTitle(obs_module_text("ScriptLogWindow")); - connect(edit->verticalScrollBar(), &QAbstractSlider::sliderMoved, - this, &ScriptLogWindow::ScrollChanged); + connect(edit->verticalScrollBar(), &QAbstractSlider::sliderMoved, this, + &ScriptLogWindow::ScrollChanged); } ScriptLogWindow::~ScriptLogWindow() { config_t *global_config = obs_frontend_get_global_config(); - config_set_string(global_config, - "ScriptLogWindow", "geometry", - saveGeometry().toBase64().constData()); + config_set_string(global_config, "ScriptLogWindow", "geometry", + saveGeometry().toBase64().constData()); } void ScriptLogWindow::ScrollChanged(int val) @@ -180,17 +178,15 @@ void ScriptLogWindow::Clear() /* ----------------------------------------------------------------- */ -ScriptsTool::ScriptsTool() - : QWidget (nullptr), - ui (new Ui_ScriptsTool) +ScriptsTool::ScriptsTool() : QWidget(nullptr), ui(new Ui_ScriptsTool) { ui->setupUi(this); RefreshLists(); #if PYTHON_UI config_t *config = obs_frontend_get_global_config(); - const char *path = config_get_string(config, "Python", - "Path" ARCH_NAME); + const char *path = + config_get_string(config, "Python", "Path" ARCH_NAME); ui->pythonPath->setText(path); ui->pythonPathLabel->setText(obs_module_text(PYTHONPATH_LABEL_TEXT)); #else @@ -201,7 +197,7 @@ ScriptsTool::ScriptsTool() delete propertiesView; propertiesView = new QWidget(); propertiesView->setSizePolicy(QSizePolicy::Expanding, - QSizePolicy::Expanding); + QSizePolicy::Expanding); ui->propertiesLayout->addWidget(propertiesView); } @@ -217,8 +213,8 @@ void ScriptsTool::RemoveScript(const char *path) const char *script_path = obs_script_get_path(script); if (strcmp(script_path, path) == 0) { - scriptData->scripts.erase( - scriptData->scripts.begin() + i); + scriptData->scripts.erase(scriptData->scripts.begin() + + i); break; } } @@ -323,7 +319,8 @@ void ScriptsTool::on_addScripts_clicked() scriptData->scripts.emplace_back(script); - QListWidgetItem *item = new QListWidgetItem(script_file); + QListWidgetItem *item = + new QListWidgetItem(script_file); item->setData(Qt::UserRole, QString(file)); ui->scripts->addItem(item); @@ -343,8 +340,10 @@ void ScriptsTool::on_removeScripts_clicked() QList items = ui->scripts->selectedItems(); for (QListWidgetItem *item : items) - RemoveScript(item->data(Qt::UserRole).toString() - .toUtf8().constData()); + RemoveScript(item->data(Qt::UserRole) + .toString() + .toUtf8() + .constData()); RefreshLists(); } @@ -352,8 +351,10 @@ void ScriptsTool::on_reloadScripts_clicked() { QList items = ui->scripts->selectedItems(); for (QListWidgetItem *item : items) - ReloadScript(item->data(Qt::UserRole).toString() - .toUtf8().constData()); + ReloadScript(item->data(Qt::UserRole) + .toString() + .toUtf8() + .constData()); on_scripts_currentRowChanged(ui->scripts->currentRow()); } @@ -368,9 +369,7 @@ void ScriptsTool::on_pythonPathBrowse_clicked() { QString curPath = ui->pythonPath->text(); QString newPath = QFileDialog::getExistingDirectory( - this, - ui->pythonPathLabel->text(), - curPath); + this, ui->pythonPathLabel->text(), curPath); if (newPath.isEmpty()) return; @@ -406,14 +405,14 @@ void ScriptsTool::on_scripts_currentRowChanged(int row) if (row == -1) { propertiesView = new QWidget(); propertiesView->setSizePolicy(QSizePolicy::Expanding, - QSizePolicy::Expanding); + QSizePolicy::Expanding); ui->propertiesLayout->addWidget(propertiesView); ui->description->setText(QString()); return; } - QByteArray array = ui->scripts->item(row)->data(Qt::UserRole) - .toString().toUtf8(); + QByteArray array = + ui->scripts->item(row)->data(Qt::UserRole).toString().toUtf8(); const char *path = array.constData(); obs_script_t *script = scriptData->FindScript(path); @@ -425,9 +424,10 @@ void ScriptsTool::on_scripts_currentRowChanged(int row) OBSData settings = obs_script_get_settings(script); obs_data_release(settings); - propertiesView = new OBSPropertiesView(settings, script, - (PropertiesReloadCallback)obs_script_get_properties, - (PropertiesUpdateCallback)obs_script_update); + propertiesView = new OBSPropertiesView( + settings, script, + (PropertiesReloadCallback)obs_script_get_properties, + (PropertiesUpdateCallback)obs_script_update); ui->propertiesLayout->addWidget(propertiesView); ui->description->setText(obs_script_get_description(script)); } @@ -457,8 +457,7 @@ static void obs_event(enum obs_frontend_event event, void *) static void load_script_data(obs_data_t *load_data, bool, void *) { - obs_data_array_t *array = obs_data_get_array(load_data, - "scripts-tool"); + obs_data_array_t *array = obs_data_get_array(load_data, "scripts-tool"); delete scriptData; scriptData = new ScriptData; @@ -509,21 +508,19 @@ static void save_script_data(obs_data_t *save_data, bool saving, void *) } static void script_log(void *, obs_script_t *script, int log_level, - const char *message) + const char *message) { QString qmsg; if (script) { qmsg = QStringLiteral("[%1] %2").arg( - obs_script_get_file(script), - message); + obs_script_get_file(script), message); } else { qmsg = QStringLiteral("[Unknown Script] %1").arg(message); } QMetaObject::invokeMethod(scriptLogWindow, "AddLogMsg", - Q_ARG(int, log_level), - Q_ARG(QString, qmsg)); + Q_ARG(int, log_level), Q_ARG(QString, qmsg)); } extern "C" void InitScripts() @@ -533,13 +530,13 @@ extern "C" void InitScripts() obs_scripting_load(); obs_scripting_set_log_callback(script_log, nullptr); - QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction( - obs_module_text("Scripts")); + QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction( + obs_module_text("Scripts")); #if PYTHON_UI config_t *config = obs_frontend_get_global_config(); - const char *python_path = config_get_string(config, "Python", - "Path" ARCH_NAME); + const char *python_path = + config_get_string(config, "Python", "Path" ARCH_NAME); if (!obs_scripting_python_loaded() && python_path && *python_path) obs_scripting_load_python(python_path); @@ -547,8 +544,7 @@ extern "C" void InitScripts() scriptData = new ScriptData; - auto cb = [] () - { + auto cb = []() { obs_frontend_push_ui_translation(obs_module_get_string); if (!scriptsWindow) { diff --git a/UI/horizontal-scroll-area.hpp b/UI/horizontal-scroll-area.hpp index 8a64c3e..b3b860b 100644 --- a/UI/horizontal-scroll-area.hpp +++ b/UI/horizontal-scroll-area.hpp @@ -8,8 +8,7 @@ class HScrollArea : public QScrollArea { Q_OBJECT public: - inline HScrollArea(QWidget *parent = nullptr) - : QScrollArea(parent) + inline HScrollArea(QWidget *parent = nullptr) : QScrollArea(parent) { setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); } diff --git a/UI/hotkey-edit.cpp b/UI/hotkey-edit.cpp index 30af64a..37e5a7d 100644 --- a/UI/hotkey-edit.cpp +++ b/UI/hotkey-edit.cpp @@ -25,13 +25,13 @@ #include "qt-wrappers.hpp" static inline bool operator!=(const obs_key_combination_t &c1, - const obs_key_combination_t &c2) + const obs_key_combination_t &c2) { return c1.modifiers != c2.modifiers || c1.key != c2.key; } static inline bool operator==(const obs_key_combination_t &c1, - const obs_key_combination_t &c2) + const obs_key_combination_t &c2) { return !(c1 != c2); } @@ -105,32 +105,34 @@ void OBSHotkeyEdit::mousePressEvent(QMouseEvent *event) new_key.key = OBS_KEY_MOUSE3; break; -#define MAP_BUTTON(i, j) case Qt::ExtraButton ## i: \ - new_key.key = OBS_KEY_MOUSE ## j; break; - MAP_BUTTON( 1, 4); - MAP_BUTTON( 2, 5); - MAP_BUTTON( 3, 6); - MAP_BUTTON( 4, 7); - MAP_BUTTON( 5, 8); - MAP_BUTTON( 6, 9); - MAP_BUTTON( 7, 10); - MAP_BUTTON( 8, 11); - MAP_BUTTON( 9, 12); - MAP_BUTTON(10, 13); - MAP_BUTTON(11, 14); - MAP_BUTTON(12, 15); - MAP_BUTTON(13, 16); - MAP_BUTTON(14, 17); - MAP_BUTTON(15, 18); - MAP_BUTTON(16, 19); - MAP_BUTTON(17, 20); - MAP_BUTTON(18, 21); - MAP_BUTTON(19, 22); - MAP_BUTTON(20, 23); - MAP_BUTTON(21, 24); - MAP_BUTTON(22, 25); - MAP_BUTTON(23, 26); - MAP_BUTTON(24, 27); +#define MAP_BUTTON(i, j) \ + case Qt::ExtraButton##i: \ + new_key.key = OBS_KEY_MOUSE##j; \ + break; + MAP_BUTTON(1, 4) + MAP_BUTTON(2, 5) + MAP_BUTTON(3, 6) + MAP_BUTTON(4, 7) + MAP_BUTTON(5, 8) + MAP_BUTTON(6, 9) + MAP_BUTTON(7, 10) + MAP_BUTTON(8, 11) + MAP_BUTTON(9, 12) + MAP_BUTTON(10, 13) + MAP_BUTTON(11, 14) + MAP_BUTTON(12, 15) + MAP_BUTTON(13, 16) + MAP_BUTTON(14, 17) + MAP_BUTTON(15, 18) + MAP_BUTTON(16, 19) + MAP_BUTTON(17, 20) + MAP_BUTTON(18, 21) + MAP_BUTTON(19, 22) + MAP_BUTTON(20, 23) + MAP_BUTTON(21, 24) + MAP_BUTTON(22, 25) + MAP_BUTTON(23, 26) + MAP_BUTTON(24, 27) #undef MAP_BUTTON } @@ -183,13 +185,13 @@ void OBSHotkeyEdit::ClearKey() void OBSHotkeyEdit::InitSignalHandler() { - layoutChanged = {obs_get_signal_handler(), - "hotkey_layout_change", - [](void *this_, calldata_t*) - { - auto edit = static_cast(this_); - QMetaObject::invokeMethod(edit, "ReloadKeyLayout"); - }, this}; + layoutChanged = { + obs_get_signal_handler(), "hotkey_layout_change", + [](void *this_, calldata_t *) { + auto edit = static_cast(this_); + QMetaObject::invokeMethod(edit, "ReloadKeyLayout"); + }, + this}; } void OBSHotkeyEdit::ReloadKeyLayout() @@ -198,7 +200,7 @@ void OBSHotkeyEdit::ReloadKeyLayout() } void OBSHotkeyWidget::SetKeyCombinations( - const std::vector &combos) + const std::vector &combos) { if (combos.empty()) AddEdit({0, OBS_KEY_NONE}); @@ -210,10 +212,8 @@ void OBSHotkeyWidget::SetKeyCombinations( bool OBSHotkeyWidget::Changed() const { return changed || - std::any_of(begin(edits), end(edits), [](OBSHotkeyEdit *edit) - { - return edit->changed; - }); + std::any_of(begin(edits), end(edits), + [](OBSHotkeyEdit *edit) { return edit->changed; }); } void OBSHotkeyWidget::Apply() @@ -230,7 +230,7 @@ void OBSHotkeyWidget::Apply() } void OBSHotkeyWidget::GetCombinations( - std::vector &combinations) const + std::vector &combinations) const { combinations.clear(); for (auto &edit : edits) @@ -249,21 +249,19 @@ void OBSHotkeyWidget::Save(std::vector &combinations) GetCombinations(combinations); Apply(); - auto AtomicUpdate = [&]() - { + auto AtomicUpdate = [&]() { ignoreChangedBindings = true; - obs_hotkey_load_bindings(id, - combinations.data(), combinations.size()); + obs_hotkey_load_bindings(id, combinations.data(), + combinations.size()); ignoreChangedBindings = false; }; using AtomicUpdate_t = decltype(&AtomicUpdate); - obs_hotkey_update_atomic([](void *d) - { - (*static_cast(d))(); - }, static_cast(&AtomicUpdate)); + obs_hotkey_update_atomic( + [](void *d) { (*static_cast(d))(); }, + static_cast(&AtomicUpdate)); } void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx) @@ -285,12 +283,13 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx) clear->setFlat(true); clear->setEnabled(!obs_key_combination_is_empty(combo)); - QObject::connect(edit, &OBSHotkeyEdit::KeyChanged, - [=](obs_key_combination_t new_combo) - { - clear->setEnabled(!obs_key_combination_is_empty(new_combo)); - revert->setEnabled(edit->original != new_combo); - }); + QObject::connect( + edit, &OBSHotkeyEdit::KeyChanged, + [=](obs_key_combination_t new_combo) { + clear->setEnabled( + !obs_key_combination_is_empty(new_combo)); + revert->setEnabled(edit->original != new_combo); + }); auto add = new QPushButton; add->setProperty("themeID", "addIconSmall"); @@ -303,25 +302,18 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx) remove->setFixedSize(24, 24); remove->setFlat(true); - auto CurrentIndex = [&, remove] - { - auto res = std::find(begin(removeButtons), - end(removeButtons), - remove); + auto CurrentIndex = [&, remove] { + auto res = std::find(begin(removeButtons), end(removeButtons), + remove); return std::distance(begin(removeButtons), res); }; - QObject::connect(add, &QPushButton::clicked, - [&, CurrentIndex] - { + QObject::connect(add, &QPushButton::clicked, [&, CurrentIndex] { AddEdit({0, OBS_KEY_NONE}, CurrentIndex() + 1); }); QObject::connect(remove, &QPushButton::clicked, - [&, CurrentIndex] - { - RemoveEdit(CurrentIndex()); - }); + [&, CurrentIndex] { RemoveEdit(CurrentIndex()); }); QHBoxLayout *subLayout = new QHBoxLayout; subLayout->setContentsMargins(0, 4, 0, 0); @@ -346,16 +338,13 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx) layout()->insertLayout(idx, subLayout); - QObject::connect(revert, &QPushButton::clicked, - edit, &OBSHotkeyEdit::ResetKey); - QObject::connect(clear, &QPushButton::clicked, - edit, &OBSHotkeyEdit::ClearKey); + QObject::connect(revert, &QPushButton::clicked, edit, + &OBSHotkeyEdit::ResetKey); + QObject::connect(clear, &QPushButton::clicked, edit, + &OBSHotkeyEdit::ClearKey); QObject::connect(edit, &OBSHotkeyEdit::KeyChanged, - [&](obs_key_combination) - { - emit KeyChanged(); - }); + [&](obs_key_combination) { emit KeyChanged(); }); } void OBSHotkeyWidget::RemoveEdit(size_t idx, bool signal) @@ -384,34 +373,35 @@ void OBSHotkeyWidget::RemoveEdit(size_t idx, bool signal) void OBSHotkeyWidget::BindingsChanged(void *data, calldata_t *param) { - auto widget = static_cast(data); - auto key = static_cast(calldata_ptr(param, "key")); + auto widget = static_cast(data); + auto key = static_cast(calldata_ptr(param, "key")); QMetaObject::invokeMethod(widget, "HandleChangedBindings", - Q_ARG(obs_hotkey_id, obs_hotkey_get_id(key))); + Q_ARG(obs_hotkey_id, obs_hotkey_get_id(key))); } void OBSHotkeyWidget::HandleChangedBindings(obs_hotkey_id id_) { - if (ignoreChangedBindings || id != id_) return; + if (ignoreChangedBindings || id != id_) + return; std::vector bindings; - auto LoadBindings = [&](obs_hotkey_binding_t *binding) - { - if (obs_hotkey_binding_get_hotkey_id(binding) != id) return; + auto LoadBindings = [&](obs_hotkey_binding_t *binding) { + if (obs_hotkey_binding_get_hotkey_id(binding) != id) + return; auto get_combo = obs_hotkey_binding_get_key_combination; bindings.push_back(get_combo(binding)); }; using LoadBindings_t = decltype(&LoadBindings); - obs_enum_hotkey_bindings([](void *data, - size_t, obs_hotkey_binding_t *binding) - { - auto LoadBindings = *static_cast(data); - LoadBindings(binding); - return true; - }, static_cast(&LoadBindings)); + obs_enum_hotkey_bindings( + [](void *data, size_t, obs_hotkey_binding_t *binding) { + auto LoadBindings = *static_cast(data); + LoadBindings(binding); + return true; + }, + static_cast(&LoadBindings)); while (edits.size() > 0) RemoveEdit(edits.size() - 1, false); diff --git a/UI/hotkey-edit.hpp b/UI/hotkey-edit.hpp index e7e7422..198d9ea 100644 --- a/UI/hotkey-edit.hpp +++ b/UI/hotkey-edit.hpp @@ -45,10 +45,8 @@ class OBSHotkeyEdit : public QLineEdit { Q_OBJECT; public: - OBSHotkeyEdit(obs_key_combination_t original, - QWidget *parent=nullptr) - : QLineEdit(parent), - original(original) + OBSHotkeyEdit(obs_key_combination_t original, QWidget *parent = nullptr) + : QLineEdit(parent), original(original) { #ifdef __APPLE__ // disable the input cursor on OSX, focus should be clear @@ -63,9 +61,10 @@ public: obs_key_combination_t original; obs_key_combination_t key; - bool changed = false; + bool changed = false; + protected: - OBSSignal layoutChanged; + OBSSignal layoutChanged; void InitSignalHandler(); @@ -92,15 +91,14 @@ class OBSHotkeyWidget : public QWidget { public: OBSHotkeyWidget(obs_hotkey_id id, std::string name, - const std::vector &combos={}, - QWidget *parent=nullptr) + const std::vector &combos = {}, + QWidget *parent = nullptr) : QWidget(parent), id(id), name(name), bindingsChanged(obs_get_signal_handler(), "hotkey_bindings_changed", - &OBSHotkeyWidget::BindingsChanged, - this) + &OBSHotkeyWidget::BindingsChanged, this) { auto layout = new QVBoxLayout; layout->setSpacing(0); @@ -110,7 +108,7 @@ public: SetKeyCombinations(combos); } - void SetKeyCombinations(const std::vector&); + void SetKeyCombinations(const std::vector &); obs_hotkey_id id; std::string name; @@ -129,7 +127,7 @@ public: } void Apply(); - void GetCombinations(std::vector&) const; + void GetCombinations(std::vector &) const; void Save(); void Save(std::vector &combinations); @@ -137,8 +135,8 @@ public: void leaveEvent(QEvent *event) override; private: - void AddEdit(obs_key_combination combo, int idx=-1); - void RemoveEdit(size_t idx, bool signal=true); + void AddEdit(obs_key_combination combo, int idx = -1); + void RemoveEdit(size_t idx, bool signal = true); static void BindingsChanged(void *data, calldata_t *param); @@ -150,7 +148,7 @@ private: QVBoxLayout *layout() const { - return dynamic_cast(QWidget::layout()); + return dynamic_cast(QWidget::layout()); } private slots: diff --git a/UI/menu-button.hpp b/UI/menu-button.hpp index b34258d..ab1c149 100644 --- a/UI/menu-button.hpp +++ b/UI/menu-button.hpp @@ -16,7 +16,7 @@ public: } explicit inline MenuButton(const QString &text, - QWidget *parent = nullptr) + QWidget *parent = nullptr) : QPushButton(text, parent) { } diff --git a/UI/obf.c b/UI/obf.c index 0ca8cc5..a5bf6fe 100644 --- a/UI/obf.c +++ b/UI/obf.c @@ -1,21 +1,20 @@ #include "obf.h" #include -#define LOWER_HALFBYTE(x) ((x) & 0xF) +#define LOWER_HALFBYTE(x) ((x)&0xF) #define UPPER_HALFBYTE(x) (((x) >> 4) & 0xF) void deobfuscate_str(char *str, uint64_t val) { - uint8_t *dec_val = (uint8_t*)&val; + uint8_t *dec_val = (uint8_t *)&val; int i = 0; while (*str != 0) { int pos = i / 2; bool bottom = (i % 2) == 0; - uint8_t *ch = (uint8_t*)str; - uint8_t xor = bottom ? - LOWER_HALFBYTE(dec_val[pos]) : - UPPER_HALFBYTE(dec_val[pos]); + uint8_t *ch = (uint8_t *)str; + uint8_t xor = bottom ? LOWER_HALFBYTE(dec_val[pos]) + : UPPER_HALFBYTE(dec_val[pos]); *ch ^= xor; diff --git a/UI/obs-app.cpp b/UI/obs-app.cpp index a2c7ab4..46967e6 100644 --- a/UI/obs-app.cpp +++ b/UI/obs-app.cpp @@ -91,10 +91,11 @@ extern "C" __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; QObject *CreateShortcutFilter() { - return new OBSEventFilter([](QObject *obj, QEvent *event) - { - auto mouse_event = [](QMouseEvent &event) - { + return new OBSEventFilter([](QObject *obj, QEvent *event) { + auto mouse_event = [](QMouseEvent &event) { + if (!App()->HotkeysEnabledInFocus()) + return true; + obs_key_combination_t hotkey = {0, OBS_KEY_NONE}; bool pressed = event.type() == QEvent::MouseButtonPress; @@ -110,45 +111,49 @@ QObject *CreateShortcutFilter() hotkey.key = OBS_KEY_MOUSE3; break; -#define MAP_BUTTON(i, j) case Qt::ExtraButton ## i: \ - hotkey.key = OBS_KEY_MOUSE ## j; break; - MAP_BUTTON( 1, 4); - MAP_BUTTON( 2, 5); - MAP_BUTTON( 3, 6); - MAP_BUTTON( 4, 7); - MAP_BUTTON( 5, 8); - MAP_BUTTON( 6, 9); - MAP_BUTTON( 7, 10); - MAP_BUTTON( 8, 11); - MAP_BUTTON( 9, 12); - MAP_BUTTON(10, 13); - MAP_BUTTON(11, 14); - MAP_BUTTON(12, 15); - MAP_BUTTON(13, 16); - MAP_BUTTON(14, 17); - MAP_BUTTON(15, 18); - MAP_BUTTON(16, 19); - MAP_BUTTON(17, 20); - MAP_BUTTON(18, 21); - MAP_BUTTON(19, 22); - MAP_BUTTON(20, 23); - MAP_BUTTON(21, 24); - MAP_BUTTON(22, 25); - MAP_BUTTON(23, 26); - MAP_BUTTON(24, 27); +#define MAP_BUTTON(i, j) \ + case Qt::ExtraButton##i: \ + hotkey.key = OBS_KEY_MOUSE##j; \ + break; + MAP_BUTTON(1, 4); + MAP_BUTTON(2, 5); + MAP_BUTTON(3, 6); + MAP_BUTTON(4, 7); + MAP_BUTTON(5, 8); + MAP_BUTTON(6, 9); + MAP_BUTTON(7, 10); + MAP_BUTTON(8, 11); + MAP_BUTTON(9, 12); + MAP_BUTTON(10, 13); + MAP_BUTTON(11, 14); + MAP_BUTTON(12, 15); + MAP_BUTTON(13, 16); + MAP_BUTTON(14, 17); + MAP_BUTTON(15, 18); + MAP_BUTTON(16, 19); + MAP_BUTTON(17, 20); + MAP_BUTTON(18, 21); + MAP_BUTTON(19, 22); + MAP_BUTTON(20, 23); + MAP_BUTTON(21, 24); + MAP_BUTTON(22, 25); + MAP_BUTTON(23, 26); + MAP_BUTTON(24, 27); #undef MAP_BUTTON } hotkey.modifiers = TranslateQtKeyboardEventModifiers( - event.modifiers()); + event.modifiers()); obs_hotkey_inject_event(hotkey, pressed); return true; }; - auto key_event = [&](QKeyEvent *event) - { - QDialog *dialog = qobject_cast(obj); + auto key_event = [&](QKeyEvent *event) { + if (!App()->HotkeysEnabledInFocus()) + return true; + + QDialog *dialog = qobject_cast(obj); obs_key_combination_t hotkey = {0, OBS_KEY_NONE}; bool pressed = event->type() == QEvent::KeyPress; @@ -180,7 +185,7 @@ QObject *CreateShortcutFilter() } hotkey.modifiers = TranslateQtKeyboardEventModifiers( - event->modifiers()); + event->modifiers()); obs_hotkey_inject_event(hotkey, pressed); return true; @@ -189,13 +194,13 @@ QObject *CreateShortcutFilter() switch (event->type()) { case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: - return mouse_event(*static_cast(event)); + return mouse_event(*static_cast(event)); /*case QEvent::MouseButtonDblClick: case QEvent::Wheel:*/ case QEvent::KeyPress: case QEvent::KeyRelease: - return key_event(static_cast(event)); + return key_event(static_cast(event)); default: return false; @@ -207,8 +212,8 @@ string CurrentTimeString() { using namespace std::chrono; - struct tm tstruct; - char buf[80]; + struct tm tstruct; + char buf[80]; auto tp = system_clock::now(); auto now = system_clock::to_time_t(tp); @@ -216,14 +221,12 @@ string CurrentTimeString() size_t written = strftime(buf, sizeof(buf), "%X", &tstruct); if (ratio_less::value && - written && (sizeof(buf) - written) > 5) { - auto tp_secs = - time_point_cast(tp); - auto millis = - duration_cast(tp - tp_secs).count(); + written && (sizeof(buf) - written) > 5) { + auto tp_secs = time_point_cast(tp); + auto millis = duration_cast(tp - tp_secs).count(); snprintf(buf + written, sizeof(buf) - written, ".%03u", - static_cast(millis)); + static_cast(millis)); } return buf; @@ -231,16 +234,16 @@ string CurrentTimeString() string CurrentDateTimeString() { - time_t now = time(0); - struct tm tstruct; - char buf[80]; + time_t now = time(0); + struct tm tstruct; + char buf[80]; tstruct = *localtime(&now); strftime(buf, sizeof(buf), "%Y-%m-%d, %X", &tstruct); return buf; } static inline void LogString(fstream &logFile, const char *timeString, - char *str) + char *str) { logFile << timeString << str << endl; } @@ -283,7 +286,7 @@ static inline int sum_chars(const char *str) } static inline bool too_many_repeated_entries(fstream &logFile, const char *msg, - const char *output_str) + const char *output_str) { static mutex log_mutex; static const char *last_msg_ptr = nullptr; @@ -307,10 +310,10 @@ static inline bool too_many_repeated_entries(fstream &logFile, const char *msg, } if (rep_count > MAX_REPEATED_LINES) { - logFile << CurrentTimeString() << - ": Last log entry repeated for " << - to_string(rep_count - MAX_REPEATED_LINES) << - " more lines" << endl; + logFile << CurrentTimeString() + << ": Last log entry repeated for " + << to_string(rep_count - MAX_REPEATED_LINES) + << " more lines" << endl; } last_msg_ptr = msg; @@ -323,7 +326,7 @@ static inline bool too_many_repeated_entries(fstream &logFile, const char *msg, static void do_log(int log_level, const char *msg, va_list args, void *param) { - fstream &logFile = *static_cast(param); + fstream &logFile = *static_cast(param); char str[4096]; #ifndef _WIN32 @@ -344,7 +347,7 @@ static void do_log(int log_level, const char *msg, va_list args, void *param) wide_buf.reserve(wNum + 1); wide_buf.resize(wNum - 1); MultiByteToWideChar(CP_UTF8, 0, str, -1, &wide_buf[0], - wNum); + wNum); wide_buf.push_back('\n'); OutputDebugStringW(wide_buf.c_str()); @@ -372,88 +375,91 @@ static void do_log(int log_level, const char *msg, va_list args, void *param) bool OBSApp::InitGlobalConfigDefaults() { config_set_default_string(globalConfig, "General", "Language", - DEFAULT_LANG); + DEFAULT_LANG); config_set_default_uint(globalConfig, "General", "MaxLogs", 10); config_set_default_int(globalConfig, "General", "InfoIncrement", -1); config_set_default_string(globalConfig, "General", "ProcessPriority", - "Normal"); + "Normal"); config_set_default_bool(globalConfig, "General", "EnableAutoUpdates", - true); + true); #if _WIN32 config_set_default_string(globalConfig, "Video", "Renderer", - "Direct3D 11"); + "Direct3D 11"); #else config_set_default_string(globalConfig, "Video", "Renderer", "OpenGL"); #endif config_set_default_bool(globalConfig, "BasicWindow", "PreviewEnabled", - true); + true); config_set_default_bool(globalConfig, "BasicWindow", - "PreviewProgramMode", false); + "PreviewProgramMode", false); config_set_default_bool(globalConfig, "BasicWindow", - "SceneDuplicationMode", true); + "SceneDuplicationMode", true); + config_set_default_bool(globalConfig, "BasicWindow", "SwapScenesMode", + true); + config_set_default_bool(globalConfig, "BasicWindow", "SnappingEnabled", + true); + config_set_default_bool(globalConfig, "BasicWindow", "ScreenSnapping", + true); + config_set_default_bool(globalConfig, "BasicWindow", "SourceSnapping", + true); + config_set_default_bool(globalConfig, "BasicWindow", "CenterSnapping", + false); + config_set_default_double(globalConfig, "BasicWindow", "SnapDistance", + 10.0); config_set_default_bool(globalConfig, "BasicWindow", - "SwapScenesMode", true); + "RecordWhenStreaming", false); config_set_default_bool(globalConfig, "BasicWindow", - "SnappingEnabled", true); + "KeepRecordingWhenStreamStops", false); + config_set_default_bool(globalConfig, "BasicWindow", "SysTrayEnabled", + true); config_set_default_bool(globalConfig, "BasicWindow", - "ScreenSnapping", true); + "SysTrayWhenStarted", false); + config_set_default_bool(globalConfig, "BasicWindow", "SaveProjectors", + false); + config_set_default_bool(globalConfig, "BasicWindow", "ShowTransitions", + true); config_set_default_bool(globalConfig, "BasicWindow", - "SourceSnapping", true); - config_set_default_bool(globalConfig, "BasicWindow", - "CenterSnapping", false); - config_set_default_double(globalConfig, "BasicWindow", - "SnapDistance", 10.0); - config_set_default_bool(globalConfig, "BasicWindow", - "RecordWhenStreaming", false); - config_set_default_bool(globalConfig, "BasicWindow", - "KeepRecordingWhenStreamStops", false); - config_set_default_bool(globalConfig, "BasicWindow", - "SysTrayEnabled", true); - config_set_default_bool(globalConfig, "BasicWindow", - "SysTrayWhenStarted", false); - config_set_default_bool(globalConfig, "BasicWindow", - "SaveProjectors", false); - config_set_default_bool(globalConfig, "BasicWindow", - "ShowTransitions", true); - config_set_default_bool(globalConfig, "BasicWindow", - "ShowListboxToolbars", true); - config_set_default_bool(globalConfig, "BasicWindow", - "ShowStatusBar", true); - config_set_default_bool(globalConfig, "BasicWindow", - "StudioModeLabels", true); + "ShowListboxToolbars", true); + config_set_default_bool(globalConfig, "BasicWindow", "ShowStatusBar", + true); + config_set_default_bool(globalConfig, "BasicWindow", "StudioModeLabels", + true); if (!config_get_bool(globalConfig, "General", "Pre21Defaults")) { config_set_default_string(globalConfig, "General", - "CurrentTheme", DEFAULT_THEME); + "CurrentTheme", DEFAULT_THEME); } - config_set_default_bool(globalConfig, "BasicWindow", - "VerticalVolControl", false); + config_set_default_string(globalConfig, "General", "HotkeyFocusType", + "NeverDisableHotkeys"); config_set_default_bool(globalConfig, "BasicWindow", - "MultiviewMouseSwitch", true); + "VerticalVolControl", false); config_set_default_bool(globalConfig, "BasicWindow", - "MultiviewDrawNames", true); + "MultiviewMouseSwitch", true); config_set_default_bool(globalConfig, "BasicWindow", - "MultiviewDrawAreas", true); + "MultiviewDrawNames", true); + + config_set_default_bool(globalConfig, "BasicWindow", + "MultiviewDrawAreas", true); #ifdef _WIN32 uint32_t winver = GetWindowsVersion(); config_set_default_bool(globalConfig, "Audio", "DisableAudioDucking", - true); + true); config_set_default_bool(globalConfig, "General", "BrowserHWAccel", - winver > 0x601); + winver > 0x601); #endif #ifdef __APPLE__ config_set_default_bool(globalConfig, "Video", "DisableOSXVSync", true); config_set_default_bool(globalConfig, "Video", "ResetOSXVSyncOnExit", - true); + true); #endif return true; } @@ -550,8 +556,8 @@ static string GetProfileDirFromName(const char *name) if (config.Open(path, CONFIG_OPEN_EXISTING) != 0) continue; - const char *curName = config_get_string(config, "General", - "Name"); + const char *curName = + config_get_string(config, "General", "Name"); if (astrcmpi(curName, name) == 0) { outputPath = ent.path; break; @@ -621,28 +627,32 @@ bool OBSApp::UpdatePre22MultiviewLayout(const char *layout) return false; if (astrcmpi(layout, "horizontaltop") == 0) { - config_set_int(globalConfig, "BasicWindow", "MultiviewLayout", + config_set_int( + globalConfig, "BasicWindow", "MultiviewLayout", static_cast( MultiviewLayout::HORIZONTAL_TOP_8_SCENES)); return true; } if (astrcmpi(layout, "horizontalbottom") == 0) { - config_set_int(globalConfig, "BasicWindow", "MultiviewLayout", + config_set_int( + globalConfig, "BasicWindow", "MultiviewLayout", static_cast( MultiviewLayout::HORIZONTAL_BOTTOM_8_SCENES)); return true; } if (astrcmpi(layout, "verticalleft") == 0) { - config_set_int(globalConfig, "BasicWindow", "MultiviewLayout", + config_set_int( + globalConfig, "BasicWindow", "MultiviewLayout", static_cast( MultiviewLayout::VERTICAL_LEFT_8_SCENES)); return true; } if (astrcmpi(layout, "verticalright") == 0) { - config_set_int(globalConfig, "BasicWindow", "MultiviewLayout", + config_set_int( + globalConfig, "BasicWindow", "MultiviewLayout", static_cast( MultiviewLayout::VERTICAL_RIGHT_8_SCENES)); return true; @@ -656,8 +666,7 @@ bool OBSApp::InitGlobalConfig() char path[512]; bool changed = false; - int len = GetConfigPath(path, sizeof(path), - "obs-studio/global.ini"); + int len = GetConfigPath(path, sizeof(path), "obs-studio/global.ini"); if (len <= 0) { return false; } @@ -670,35 +679,36 @@ bool OBSApp::InitGlobalConfig() if (!opt_starting_collection.empty()) { string path = GetSceneCollectionFileFromName( - opt_starting_collection.c_str()); + opt_starting_collection.c_str()); if (!path.empty()) { - config_set_string(globalConfig, - "Basic", "SceneCollection", - opt_starting_collection.c_str()); - config_set_string(globalConfig, - "Basic", "SceneCollectionFile", - path.c_str()); + config_set_string(globalConfig, "Basic", + "SceneCollection", + opt_starting_collection.c_str()); + config_set_string(globalConfig, "Basic", + "SceneCollectionFile", path.c_str()); changed = true; } } if (!opt_starting_profile.empty()) { - string path = GetProfileDirFromName( - opt_starting_profile.c_str()); + string path = + GetProfileDirFromName(opt_starting_profile.c_str()); if (!path.empty()) { config_set_string(globalConfig, "Basic", "Profile", - opt_starting_profile.c_str()); + opt_starting_profile.c_str()); config_set_string(globalConfig, "Basic", "ProfileDir", - path.c_str()); + path.c_str()); changed = true; } } + uint32_t lastVersion = + config_get_int(globalConfig, "General", "LastVersion"); + if (!config_has_user_value(globalConfig, "General", "Pre19Defaults")) { - uint32_t lastVersion = config_get_int(globalConfig, "General", - "LastVersion"); bool useOldDefaults = lastVersion && - lastVersion < MAKE_SEMANTIC_VERSION(19, 0, 0); + lastVersion < + MAKE_SEMANTIC_VERSION(19, 0, 0); config_set_bool(globalConfig, "General", "Pre19Defaults", useOldDefaults); @@ -706,10 +716,9 @@ bool OBSApp::InitGlobalConfig() } if (!config_has_user_value(globalConfig, "General", "Pre21Defaults")) { - uint32_t lastVersion = config_get_int(globalConfig, "General", - "LastVersion"); bool useOldDefaults = lastVersion && - lastVersion < MAKE_SEMANTIC_VERSION(21, 0, 0); + lastVersion < + MAKE_SEMANTIC_VERSION(21, 0, 0); config_set_bool(globalConfig, "General", "Pre21Defaults", useOldDefaults); @@ -717,10 +726,9 @@ bool OBSApp::InitGlobalConfig() } if (!config_has_user_value(globalConfig, "General", "Pre23Defaults")) { - uint32_t lastVersion = config_get_int(globalConfig, "General", - "LastVersion"); bool useOldDefaults = lastVersion && - lastVersion < MAKE_SEMANTIC_VERSION(23, 0, 0); + lastVersion < + MAKE_SEMANTIC_VERSION(23, 0, 0); config_set_bool(globalConfig, "General", "Pre23Defaults", useOldDefaults); @@ -728,12 +736,22 @@ bool OBSApp::InitGlobalConfig() } if (config_has_user_value(globalConfig, "BasicWindow", - "MultiviewLayout")) { - const char *layout = config_get_string(globalConfig, - "BasicWindow", "MultiviewLayout"); + "MultiviewLayout")) { + const char *layout = config_get_string( + globalConfig, "BasicWindow", "MultiviewLayout"); changed |= UpdatePre22MultiviewLayout(layout); } + if (lastVersion && lastVersion < MAKE_SEMANTIC_VERSION(24, 0, 0)) { + bool disableHotkeysInFocus = config_get_bool( + globalConfig, "General", "DisableHotkeysInFocus"); + if (disableHotkeysInFocus) + config_set_string(globalConfig, "General", + "HotkeyFocusType", + "DisableHotkeysInFocus"); + changed = true; + } + if (changed) config_save_safe(globalConfig, "tmp", nullptr); @@ -743,8 +761,8 @@ bool OBSApp::InitGlobalConfig() bool OBSApp::InitLocale() { ProfileScope("OBSApp::InitLocale"); - const char *lang = config_get_string(globalConfig, "General", - "Language"); + const char *lang = + config_get_string(globalConfig, "General", "Language"); locale = lang; @@ -757,12 +775,12 @@ bool OBSApp::InitLocale() textLookup = text_lookup_create(englishPath.c_str()); if (!textLookup) { OBSErrorBox(NULL, "Failed to create locale from file '%s'", - englishPath.c_str()); + englishPath.c_str()); return false; } - bool userLocale = config_has_user_value(globalConfig, "General", - "Language"); + bool userLocale = + config_has_user_value(globalConfig, "General", "Language"); bool defaultLang = astrcmpi(lang, DEFAULT_LANG) == 0; if (userLocale && defaultLang) @@ -784,7 +802,7 @@ bool OBSApp::InitLocale() continue; blog(LOG_INFO, "Using preferred locale '%s'", - locale_.c_str()); + locale_.c_str()); locale = locale_; return true; } @@ -799,27 +817,26 @@ bool OBSApp::InitLocale() if (GetDataFilePath(file.str().c_str(), path)) { if (!text_lookup_add(textLookup, path.c_str())) blog(LOG_ERROR, "Failed to add locale file '%s'", - path.c_str()); + path.c_str()); } else { blog(LOG_ERROR, "Could not find locale file '%s'", - file.str().c_str()); + file.str().c_str()); } return true; } -void OBSApp::AddExtraThemeColor(QPalette &pal, int group, - const char *name, uint32_t color) +void OBSApp::AddExtraThemeColor(QPalette &pal, int group, const char *name, + uint32_t color) { std::function func; -#define DEF_PALETTE_ASSIGN(name) \ - do { \ - func = [&] (QPalette::ColorGroup group) \ - { \ - pal.setColor(group, QPalette::name, \ - QColor::fromRgb(color)); \ - }; \ +#define DEF_PALETTE_ASSIGN(name) \ + do { \ + func = [&](QPalette::ColorGroup group) { \ + pal.setColor(group, QPalette::name, \ + QColor::fromRgb(color)); \ + }; \ } while (false) if (astrcmpi(name, "alternateBase") == 0) { @@ -853,7 +870,7 @@ void OBSApp::AddExtraThemeColor(QPalette &pal, int group, } else if (astrcmpi(name, "shadow") == 0) { DEF_PALETTE_ASSIGN(Shadow); } else if (astrcmpi(name, "text") == 0 || - astrcmpi(name, "foreground") == 0) { + astrcmpi(name, "foreground") == 0) { DEF_PALETTE_ASSIGN(Text); } else if (astrcmpi(name, "toolTipBase") == 0) { DEF_PALETTE_ASSIGN(ToolTipBase); @@ -862,7 +879,7 @@ void OBSApp::AddExtraThemeColor(QPalette &pal, int group, } else if (astrcmpi(name, "windowText") == 0) { DEF_PALETTE_ASSIGN(WindowText); } else if (astrcmpi(name, "window") == 0 || - astrcmpi(name, "background") == 0) { + astrcmpi(name, "background") == 0) { DEF_PALETTE_ASSIGN(Window); } else { return; @@ -885,9 +902,9 @@ void OBSApp::AddExtraThemeColor(QPalette &pal, int group, struct CFParser { cf_parser cfp = {}; - inline ~CFParser() {cf_parser_free(&cfp);} - inline operator cf_parser*() {return &cfp;} - inline cf_parser *operator->() {return &cfp;} + inline ~CFParser() { cf_parser_free(&cfp); } + inline operator cf_parser *() { return &cfp; } + inline cf_parser *operator->() { return &cfp; } }; void OBSApp::ParseExtraThemeData(const char *path) @@ -900,16 +917,19 @@ void OBSApp::ParseExtraThemeData(const char *path) cf_parser_parse(cfp, data, path); while (cf_go_to_token(cfp, "OBSTheme", nullptr)) { - if (!cf_next_token(cfp)) return; + if (!cf_next_token(cfp)) + return; int group = -1; if (cf_token_is(cfp, ":")) { ret = cf_next_token_should_be(cfp, ":", nullptr, - nullptr); - if (ret != PARSE_SUCCESS) continue; + nullptr); + if (ret != PARSE_SUCCESS) + continue; - if (!cf_next_token(cfp)) return; + if (!cf_next_token(cfp)) + return; if (cf_token_is(cfp, "disabled")) { group = QPalette::Disabled; @@ -921,27 +941,31 @@ void OBSApp::ParseExtraThemeData(const char *path) continue; } - if (!cf_next_token(cfp)) return; + if (!cf_next_token(cfp)) + return; } - if (!cf_token_is(cfp, "{")) continue; + if (!cf_token_is(cfp, "{")) + continue; for (;;) { - if (!cf_next_token(cfp)) return; + if (!cf_next_token(cfp)) + return; ret = cf_token_is_type(cfp, CFTOKEN_NAME, "name", - nullptr); + nullptr); if (ret != PARSE_SUCCESS) break; DStr name; dstr_copy_strref(name, &cfp->cur_token->str); - ret = cf_next_token_should_be(cfp, ":", ";", - nullptr); - if (ret != PARSE_SUCCESS) continue; + ret = cf_next_token_should_be(cfp, ":", ";", nullptr); + if (ret != PARSE_SUCCESS) + continue; - if (!cf_next_token(cfp)) return; + if (!cf_next_token(cfp)) + return; const char *array; uint32_t color = 0; @@ -952,25 +976,31 @@ void OBSApp::ParseExtraThemeData(const char *path) } else if (cf_token_is(cfp, "rgb")) { ret = cf_next_token_should_be(cfp, "(", ";", - nullptr); - if (ret != PARSE_SUCCESS) continue; - if (!cf_next_token(cfp)) return; + nullptr); + if (ret != PARSE_SUCCESS) + continue; + if (!cf_next_token(cfp)) + return; array = cfp->cur_token->str.array; color |= strtol(array, nullptr, 10) << 16; ret = cf_next_token_should_be(cfp, ",", ";", - nullptr); - if (ret != PARSE_SUCCESS) continue; - if (!cf_next_token(cfp)) return; + nullptr); + if (ret != PARSE_SUCCESS) + continue; + if (!cf_next_token(cfp)) + return; array = cfp->cur_token->str.array; color |= strtol(array, nullptr, 10) << 8; ret = cf_next_token_should_be(cfp, ",", ";", - nullptr); - if (ret != PARSE_SUCCESS) continue; - if (!cf_next_token(cfp)) return; + nullptr); + if (ret != PARSE_SUCCESS) + continue; + if (!cf_next_token(cfp)) + return; array = cfp->cur_token->str.array; color |= strtol(array, nullptr, 10); @@ -982,13 +1012,15 @@ void OBSApp::ParseExtraThemeData(const char *path) color = 0; } - if (!cf_go_to_token(cfp, ";", nullptr)) return; + if (!cf_go_to_token(cfp, ";", nullptr)) + return; AddExtraThemeColor(pal, group, name->array, color); } ret = cf_token_should_be(cfp, "}", "}", nullptr); - if (ret != PARSE_SUCCESS) continue; + if (ret != PARSE_SUCCESS) + continue; } setPalette(pal); @@ -1003,8 +1035,7 @@ bool OBSApp::SetTheme(std::string name, std::string path) char userDir[512]; name = "themes/" + name + ".qss"; string temp = "obs-studio/" + name; - int ret = GetConfigPath(userDir, sizeof(userDir), - temp.c_str()); + int ret = GetConfigPath(userDir, sizeof(userDir), temp.c_str()); if (ret > 0 && QFile::exists(userDir)) { path = string(userDir); @@ -1027,13 +1058,12 @@ bool OBSApp::InitTheme() { defaultPalette = palette(); - const char *themeName = config_get_string(globalConfig, "General", - "CurrentTheme"); + const char *themeName = + config_get_string(globalConfig, "General", "CurrentTheme"); if (!themeName) { /* Use deprecated "Theme" value if available */ - themeName = config_get_string(globalConfig, - "General", "Theme"); + themeName = config_get_string(globalConfig, "General", "Theme"); if (!themeName) themeName = DEFAULT_THEME; if (!themeName) @@ -1047,8 +1077,7 @@ bool OBSApp::InitTheme() } OBSApp::OBSApp(int &argc, char **argv, profiler_name_store_t *store) - : QApplication(argc, argv), - profilerNameStore(store) + : QApplication(argc, argv), profilerNameStore(store) { sleepInhibitor = os_inhibit_sleep_create("OBS Video/audio"); @@ -1058,17 +1087,17 @@ OBSApp::OBSApp(int &argc, char **argv, profiler_name_store_t *store) OBSApp::~OBSApp() { #ifdef _WIN32 - bool disableAudioDucking = config_get_bool(globalConfig, "Audio", - "DisableAudioDucking"); + bool disableAudioDucking = + config_get_bool(globalConfig, "Audio", "DisableAudioDucking"); if (disableAudioDucking) DisableAudioDucking(false); #endif #ifdef __APPLE__ - bool vsyncDiabled = config_get_bool(globalConfig, "Video", - "DisableOSXVSync"); - bool resetVSync = config_get_bool(globalConfig, "Video", - "ResetOSXVSyncOnExit"); + bool vsyncDiabled = + config_get_bool(globalConfig, "Video", "DisableOSXVSync"); + bool resetVSync = + config_get_bool(globalConfig, "Video", "ResetOSXVSyncOnExit"); if (vsyncDiabled && resetVSync) EnableOSXVSync(true); #endif @@ -1174,31 +1203,31 @@ void OBSApp::AppInit() throw "Failed to load theme"; config_set_default_string(globalConfig, "Basic", "Profile", - Str("Untitled")); + Str("Untitled")); config_set_default_string(globalConfig, "Basic", "ProfileDir", - Str("Untitled")); + Str("Untitled")); config_set_default_string(globalConfig, "Basic", "SceneCollection", - Str("Untitled")); + Str("Untitled")); config_set_default_string(globalConfig, "Basic", "SceneCollectionFile", - Str("Untitled")); + Str("Untitled")); if (!config_has_user_value(globalConfig, "Basic", "Profile")) { config_set_string(globalConfig, "Basic", "Profile", - Str("Untitled")); + Str("Untitled")); config_set_string(globalConfig, "Basic", "ProfileDir", - Str("Untitled")); + Str("Untitled")); } if (!config_has_user_value(globalConfig, "Basic", "SceneCollection")) { - config_set_string(globalConfig, "Basic", - "SceneCollection", Str("Untitled")); - config_set_string(globalConfig, "Basic", - "SceneCollectionFile", Str("Untitled")); + config_set_string(globalConfig, "Basic", "SceneCollection", + Str("Untitled")); + config_set_string(globalConfig, "Basic", "SceneCollectionFile", + Str("Untitled")); } #ifdef _WIN32 - bool disableAudioDucking = config_get_bool(globalConfig, "Audio", - "DisableAudioDucking"); + bool disableAudioDucking = + config_get_bool(globalConfig, "Audio", "DisableAudioDucking"); if (disableAudioDucking) DisableAudioDucking(true); #endif @@ -1208,8 +1237,7 @@ void OBSApp::AppInit() EnableOSXVSync(false); #endif - enableHotkeysInFocus = !config_get_bool(globalConfig, "General", - "DisableHotkeysInFocus"); + UpdateHotkeyFocusSetting(false); move_basic_to_profiles(); move_basic_to_scene_collections(); @@ -1220,11 +1248,10 @@ void OBSApp::AppInit() const char *OBSApp::GetRenderModule() const { - const char *renderer = config_get_string(globalConfig, "Video", - "Renderer"); + const char *renderer = + config_get_string(globalConfig, "Video", "Renderer"); - return (astrcmpi(renderer, "Direct3D 11") == 0) ? - DL_D3D11 : DL_OPENGL; + return (astrcmpi(renderer, "Direct3D 11") == 0) ? DL_D3D11 : DL_OPENGL; } static bool StartupOBS(const char *locale, profiler_name_store_t *store) @@ -1240,13 +1267,33 @@ static bool StartupOBS(const char *locale, profiler_name_store_t *store) inline void OBSApp::ResetHotkeyState(bool inFocus) { obs_hotkey_enable_background_press( - inFocus || enableHotkeysInFocus); + (inFocus && enableHotkeysInFocus) || + (!inFocus && enableHotkeysOutOfFocus)); } -void OBSApp::EnableInFocusHotkeys(bool enable) +void OBSApp::UpdateHotkeyFocusSetting(bool resetState) { - enableHotkeysInFocus = enable; - ResetHotkeyState(applicationState() != Qt::ApplicationActive); + enableHotkeysInFocus = true; + enableHotkeysOutOfFocus = true; + + const char *hotkeyFocusType = + config_get_string(globalConfig, "General", "HotkeyFocusType"); + + if (astrcmpi(hotkeyFocusType, "DisableHotkeysInFocus") == 0) { + enableHotkeysInFocus = false; + } else if (astrcmpi(hotkeyFocusType, "DisableHotkeysOutOfFocus") == 0) { + enableHotkeysOutOfFocus = false; + } + + if (resetState) + ResetHotkeyState(applicationState() == Qt::ApplicationActive); +} + +void OBSApp::DisableHotkeys() +{ + enableHotkeysInFocus = false; + enableHotkeysOutOfFocus = false; + ResetHotkeyState(applicationState() == Qt::ApplicationActive); } Q_DECLARE_METATYPE(VoidFunc) @@ -1268,22 +1315,22 @@ bool OBSApp::OBSInit() return false; #ifdef _WIN32 - bool browserHWAccel = config_get_bool(globalConfig, "General", - "BrowserHWAccel"); + bool browserHWAccel = + config_get_bool(globalConfig, "General", "BrowserHWAccel"); obs_data_t *settings = obs_data_create(); obs_data_set_bool(settings, "BrowserHWAccel", browserHWAccel); obs_apply_private_data(settings); obs_data_release(settings); - blog(LOG_INFO, "Current Date/Time: %s", CurrentDateTimeString().c_str()); + blog(LOG_INFO, "Current Date/Time: %s", + CurrentDateTimeString().c_str()); blog(LOG_INFO, "Browser Hardware Acceleration: %s", - browserHWAccel ? "true" : "false"); + browserHWAccel ? "true" : "false"); #endif - blog(LOG_INFO, "Portable mode: %s", - portable_mode ? "true" : "false"); + blog(LOG_INFO, "Portable mode: %s", portable_mode ? "true" : "false"); setQuitOnLastWindowClosed(false); @@ -1295,12 +1342,10 @@ bool OBSApp::OBSInit() mainWindow->OBSInit(); connect(this, &QGuiApplication::applicationStateChanged, - [this](Qt::ApplicationState state) - { - ResetHotkeyState( - state != Qt::ApplicationActive); - }); - ResetHotkeyState(applicationState() != Qt::ApplicationActive); + [this](Qt::ApplicationState state) { + ResetHotkeyState(state == Qt::ApplicationActive); + }); + ResetHotkeyState(applicationState() == Qt::ApplicationActive); return true; } @@ -1311,15 +1356,14 @@ string OBSApp::GetVersionString() const #ifdef HAVE_OBSCONFIG_H ver << OBS_VERSION; #else - ver << LIBOBS_API_MAJOR_VER << "." << - LIBOBS_API_MINOR_VER << "." << - LIBOBS_API_PATCH_VER; + ver << LIBOBS_API_MAJOR_VER << "." << LIBOBS_API_MINOR_VER << "." + << LIBOBS_API_PATCH_VER; #endif ver << " ("; #ifdef _WIN32 - if (sizeof(void*) == 8) + if (sizeof(void *) == 8) ver << "64-bit, "; else ver << "32-bit, "; @@ -1342,13 +1386,13 @@ bool OBSApp::IsPortableMode() } #ifdef __APPLE__ -#define INPUT_AUDIO_SOURCE "coreaudio_input_capture" +#define INPUT_AUDIO_SOURCE "coreaudio_input_capture" #define OUTPUT_AUDIO_SOURCE "coreaudio_output_capture" #elif _WIN32 -#define INPUT_AUDIO_SOURCE "wasapi_input_capture" +#define INPUT_AUDIO_SOURCE "wasapi_input_capture" #define OUTPUT_AUDIO_SOURCE "wasapi_output_capture" #else -#define INPUT_AUDIO_SOURCE "pulse_input_capture" +#define INPUT_AUDIO_SOURCE "pulse_input_capture" #define OUTPUT_AUDIO_SOURCE "pulse_output_capture" #endif @@ -1388,7 +1432,7 @@ bool OBSApp::TranslateString(const char *lookupVal, const char **out) const } QString OBSTranslator::translate(const char *context, const char *sourceText, - const char *disambiguation, int n) const + const char *disambiguation, int n) const { const char *out = nullptr; if (!App()->TranslateString(sourceText, &out)) @@ -1425,26 +1469,37 @@ static bool expect_token(lexer *lex, const char *str, base_token_type type) static uint64_t convert_log_name(bool has_prefix, const char *name) { - BaseLexer lex; - string year, month, day, hour, minute, second; + BaseLexer lex; + string year, month, day, hour, minute, second; lexer_start(lex, name); if (has_prefix) { string temp; - if (!get_token(lex, temp, BASETOKEN_ALPHA)) return 0; + if (!get_token(lex, temp, BASETOKEN_ALPHA)) + return 0; } - if (!get_token(lex, year, BASETOKEN_DIGIT)) return 0; - if (!expect_token(lex, "-", BASETOKEN_OTHER)) return 0; - if (!get_token(lex, month, BASETOKEN_DIGIT)) return 0; - if (!expect_token(lex, "-", BASETOKEN_OTHER)) return 0; - if (!get_token(lex, day, BASETOKEN_DIGIT)) return 0; - if (!get_token(lex, hour, BASETOKEN_DIGIT)) return 0; - if (!expect_token(lex, "-", BASETOKEN_OTHER)) return 0; - if (!get_token(lex, minute, BASETOKEN_DIGIT)) return 0; - if (!expect_token(lex, "-", BASETOKEN_OTHER)) return 0; - if (!get_token(lex, second, BASETOKEN_DIGIT)) return 0; + if (!get_token(lex, year, BASETOKEN_DIGIT)) + return 0; + if (!expect_token(lex, "-", BASETOKEN_OTHER)) + return 0; + if (!get_token(lex, month, BASETOKEN_DIGIT)) + return 0; + if (!expect_token(lex, "-", BASETOKEN_OTHER)) + return 0; + if (!get_token(lex, day, BASETOKEN_DIGIT)) + return 0; + if (!get_token(lex, hour, BASETOKEN_DIGIT)) + return 0; + if (!expect_token(lex, "-", BASETOKEN_OTHER)) + return 0; + if (!get_token(lex, minute, BASETOKEN_DIGIT)) + return 0; + if (!expect_token(lex, "-", BASETOKEN_OTHER)) + return 0; + if (!get_token(lex, second, BASETOKEN_DIGIT)) + return 0; stringstream timestring; timestring << year << month << day << hour << minute << second; @@ -1453,13 +1508,13 @@ static uint64_t convert_log_name(bool has_prefix, const char *name) static void delete_oldest_file(bool has_prefix, const char *location) { - BPtr logDir(GetConfigPathPtr(location)); - string oldestLog; - uint64_t oldest_ts = (uint64_t)-1; + BPtr logDir(GetConfigPathPtr(location)); + string oldestLog; + uint64_t oldest_ts = (uint64_t)-1; struct os_dirent *entry; unsigned int maxLogs = (unsigned int)config_get_uint( - App()->GlobalConfig(), "General", "MaxLogs"); + App()->GlobalConfig(), "General", "MaxLogs"); os_dir_t *dir = os_opendir(logDir); if (dir) { @@ -1469,8 +1524,8 @@ static void delete_oldest_file(bool has_prefix, const char *location) if (entry->directory || *entry->d_name == '.') continue; - uint64_t ts = convert_log_name(has_prefix, - entry->d_name); + uint64_t ts = + convert_log_name(has_prefix, entry->d_name); if (ts) { if (ts < oldest_ts) { @@ -1494,20 +1549,20 @@ static void delete_oldest_file(bool has_prefix, const char *location) } static void get_last_log(bool has_prefix, const char *subdir_to_use, - std::string &last) + std::string &last) { - BPtr logDir(GetConfigPathPtr(subdir_to_use)); + BPtr logDir(GetConfigPathPtr(subdir_to_use)); struct os_dirent *entry; - os_dir_t *dir = os_opendir(logDir); - uint64_t highest_ts = 0; + os_dir_t *dir = os_opendir(logDir); + uint64_t highest_ts = 0; if (dir) { while ((entry = os_readdir(dir)) != NULL) { if (entry->directory || *entry->d_name == '.') continue; - uint64_t ts = convert_log_name(has_prefix, - entry->d_name); + uint64_t ts = + convert_log_name(has_prefix, entry->d_name); if (ts > highest_ts) { last = entry->d_name; @@ -1521,35 +1576,30 @@ static void get_last_log(bool has_prefix, const char *subdir_to_use, string GenerateTimeDateFilename(const char *extension, bool noSpace) { - time_t now = time(0); - char file[256] = {}; + time_t now = time(0); + char file[256] = {}; struct tm *cur_time; cur_time = localtime(&now); snprintf(file, sizeof(file), "%d-%02d-%02d%c%02d-%02d-%02d.%s", - cur_time->tm_year+1900, - cur_time->tm_mon+1, - cur_time->tm_mday, - noSpace ? '_' : ' ', - cur_time->tm_hour, - cur_time->tm_min, - cur_time->tm_sec, - extension); + cur_time->tm_year + 1900, cur_time->tm_mon + 1, + cur_time->tm_mday, noSpace ? '_' : ' ', cur_time->tm_hour, + cur_time->tm_min, cur_time->tm_sec, extension); return string(file); } string GenerateSpecifiedFilename(const char *extension, bool noSpace, - const char *format) + const char *format) { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); bool autoRemux = config_get_bool(main->Config(), "Video", "AutoRemux"); if ((strcmp(extension, "mp4") == 0) && autoRemux) extension = "mkv"; - BPtr filename = os_generate_formatted_filename(extension, - !noSpace, format); + BPtr filename = + os_generate_formatted_filename(extension, !noSpace, format); remuxFilename = string(filename); remuxAfterRecord = autoRemux; @@ -1597,11 +1647,9 @@ static void create_log_file(fstream &logFile) #ifdef _WIN32 BPtr wpath; os_utf8_to_wcs_ptr(path, 0, &wpath); - logFile.open(wpath, - ios_base::in | ios_base::out | ios_base::trunc); + logFile.open(wpath, ios_base::in | ios_base::out | ios_base::trunc); #else - logFile.open(path, - ios_base::in | ios_base::out | ios_base::trunc); + logFile.open(path, ios_base::in | ios_base::out | ios_base::trunc); #endif if (logFile.is_open()) { @@ -1612,23 +1660,20 @@ static void create_log_file(fstream &logFile) } } -static auto ProfilerNameStoreRelease = [](profiler_name_store_t *store) -{ +static auto ProfilerNameStoreRelease = [](profiler_name_store_t *store) { profiler_name_store_free(store); }; -using ProfilerNameStore = - std::unique_ptr; +using ProfilerNameStore = std::unique_ptr; ProfilerNameStore CreateNameStore() { return ProfilerNameStore{profiler_name_store_create(), - ProfilerNameStoreRelease}; + ProfilerNameStoreRelease}; } -static auto SnapshotRelease = [](profiler_snapshot_t *snap) -{ +static auto SnapshotRelease = [](profiler_snapshot_t *snap) { profile_snapshot_free(snap); }; @@ -1659,11 +1704,10 @@ static void SaveProfilerData(const ProfilerSnapshot &snap) BPtr path = GetConfigPathPtr(dst.str().c_str()); if (!profiler_snapshot_dump_csv_gz(snap.get(), path)) blog(LOG_WARNING, "Could not save profiler data to '%s'", - static_cast(path)); + static_cast(path)); } -static auto ProfilerFree = [](void *) -{ +static auto ProfilerFree = [](void *) { profiler_stop(); auto snap = GetSnapshot(); @@ -1683,9 +1727,8 @@ static int run_program(fstream &logFile, int argc, char *argv[]) auto profilerNameStore = CreateNameStore(); - std::unique_ptr - prof_release(static_cast(&ProfilerFree), - ProfilerFree); + std::unique_ptr prof_release( + static_cast(&ProfilerFree), ProfilerFree); profiler_start(); profile_register_root(run_program_init, 0); @@ -1722,13 +1765,13 @@ static int run_program(fstream &logFile, int argc, char *argv[]) if (!multi) { QMessageBox::StandardButtons buttons( - QMessageBox::Yes | QMessageBox::Cancel); + QMessageBox::Yes | QMessageBox::Cancel); QMessageBox mb(QMessageBox::Question, - QTStr("AlreadyRunning.Title"), - QTStr("AlreadyRunning.Text"), buttons, - nullptr); + QTStr("AlreadyRunning.Title"), + QTStr("AlreadyRunning.Text"), buttons, + nullptr); mb.setButtonText(QMessageBox::Yes, - QTStr("AlreadyRunning.LaunchAnyway")); + QTStr("AlreadyRunning.LaunchAnyway")); mb.setButtonText(QMessageBox::Cancel, QTStr("Cancel")); mb.setDefaultButton(QMessageBox::Cancel); @@ -1747,17 +1790,17 @@ static int run_program(fstream &logFile, int argc, char *argv[]) if (multi) { blog(LOG_INFO, "User enabled --multi flag and is now " - "running multiple instances of OBS."); + "running multiple instances of OBS."); } else { blog(LOG_WARNING, "================================"); blog(LOG_WARNING, "Warning: OBS is already running!"); blog(LOG_WARNING, "================================"); blog(LOG_WARNING, "User is now running multiple " - "instances of OBS!"); + "instances of OBS!"); } /* --------------------------------------- */ -run: + run: #endif if (!created_log) { @@ -1771,7 +1814,8 @@ run: for (int i = 2; i < argc; ++i) { stor << " " << argv[i]; } - blog(LOG_INFO, "Command Line Arguments: %s", stor.str().c_str()); + blog(LOG_INFO, "Command Line Arguments: %s", + stor.str().c_str()); } if (!program.OBSInit()) @@ -1793,9 +1837,9 @@ run: #ifdef _WIN32 -#define CRASH_MESSAGE \ +#define CRASH_MESSAGE \ "Woops, OBS has crashed!\n\nWould you like to copy the crash log " \ - "to the clipboard? (Crash logs will still be saved to the " \ + "to the clipboard? (Crash logs will still be saved to the " \ "%appdata%\\obs-studio\\crashes directory)" static void main_crash_handler(const char *format, va_list args, void *param) @@ -1818,16 +1862,16 @@ static void main_crash_handler(const char *format, va_list args, void *param) BPtr wpath; os_utf8_to_wcs_ptr(path, 0, &wpath); file.open(wpath, ios_base::in | ios_base::out | ios_base::trunc | - ios_base::binary); + ios_base::binary); #else - file.open(path, ios_base::in | ios_base::out | ios_base::trunc | - ios_base::binary); + file.open(path, ios_base::in | ios_base::out | ios_base::trunc | + ios_base::binary); #endif file << text; file.close(); int ret = MessageBoxA(NULL, CRASH_MESSAGE, "OBS has crashed!", - MB_YESNO | MB_ICONERROR | MB_TASKMODAL); + MB_YESNO | MB_ICONERROR | MB_TASKMODAL); if (ret == IDYES) { size_t len = strlen(text); @@ -1863,8 +1907,8 @@ static void load_debug_privilege(void) tp.Privileges[0].Luid = val; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - AdjustTokenPrivileges(token, false, &tp, - sizeof(tp), NULL, NULL); + AdjustTokenPrivileges(token, false, &tp, sizeof(tp), NULL, + NULL); } CloseHandle(token); @@ -1982,17 +2026,17 @@ bool GetClosestUnusedFileName(std::string &path, const char *extension) bool WindowPositionValid(QRect rect) { - for (QScreen* screen: QGuiApplication::screens()) { + for (QScreen *screen : QGuiApplication::screens()) { if (screen->availableGeometry().intersects(rect)) return true; } return false; } -static inline bool arg_is(const char *arg, - const char *long_form, const char *short_form) +static inline bool arg_is(const char *arg, const char *long_form, + const char *short_form) { - return (long_form && strcmp(arg, long_form) == 0) || + return (long_form && strcmp(arg, long_form) == 0) || (short_form && strcmp(arg, short_form) == 0); } @@ -2100,8 +2144,8 @@ static bool update_reconnect(ConfigFile &config) if (!mode) return false; - const char *section = (strcmp(mode, "Advanced") == 0) ? - "AdvOut" : "SimpleOutput"; + const char *section = (strcmp(mode, "Advanced") == 0) ? "AdvOut" + : "SimpleOutput"; if (move_reconnect_settings(config, section)) { config_remove_value(config, "SimpleOutput", "Reconnect"); @@ -2179,7 +2223,7 @@ static void upgrade_settings(void) while (ent) { if (ent->directory && strcmp(ent->d_name, ".") != 0 && - strcmp(ent->d_name, "..") != 0) { + strcmp(ent->d_name, "..") != 0) { strcat(path, "/"); strcat(path, ent->d_name); strcat(path, "/basic.ini"); @@ -2192,16 +2236,15 @@ static void upgrade_settings(void) if (update_ffmpeg_output(config) || update_reconnect(config)) { config_save_safe(config, "tmp", - nullptr); + nullptr); } } - if (config) { - const char *sEnc = config_get_string(config, - "AdvOut", "Encoder"); - const char *rEnc = config_get_string(config, - "AdvOut", "RecEncoder"); + const char *sEnc = config_get_string( + config, "AdvOut", "Encoder"); + const char *rEnc = config_get_string( + config, "AdvOut", "RecEncoder"); /* replace "cbr" option with "rate_control" for * each profile's encoder data */ @@ -2227,10 +2270,11 @@ static void upgrade_settings(void) os_closedir(dir); } -void ctrlc_handler (int s) { +void ctrlc_handler(int s) +{ UNUSED_PARAMETER(s); - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); main->close(); } @@ -2247,7 +2291,6 @@ int main(int argc, char *argv[]) sigaction(SIGINT, &sig_handler, NULL); - /* Block SIGPIPE in all threads, this can happen if a thread calls write on a closed pipe. */ sigset_t sigpipe_mask; @@ -2301,13 +2344,16 @@ int main(int argc, char *argv[]) opt_start_replaybuffer = true; } else if (arg_is(argv[i], "--collection", nullptr)) { - if (++i < argc) opt_starting_collection = argv[i]; + if (++i < argc) + opt_starting_collection = argv[i]; } else if (arg_is(argv[i], "--profile", nullptr)) { - if (++i < argc) opt_starting_profile = argv[i]; + if (++i < argc) + opt_starting_profile = argv[i]; } else if (arg_is(argv[i], "--scene", nullptr)) { - if (++i < argc) opt_starting_scene = argv[i]; + if (++i < argc) + opt_starting_scene = argv[i]; } else if (arg_is(argv[i], "--minimize-to-tray", nullptr)) { opt_minimize_tray = true; @@ -2319,30 +2365,30 @@ int main(int argc, char *argv[]) opt_allow_opengl = true; } else if (arg_is(argv[i], "--help", "-h")) { - std::cout << - "--help, -h: Get list of available commands.\n\n" << - "--startstreaming: Automatically start streaming.\n" << - "--startrecording: Automatically start recording.\n" << - "--startreplaybuffer: Start replay buffer.\n\n" << - "--collection : Use specific scene collection." - << "\n" << - "--profile : Use specific profile.\n" << - "--scene : Start with specific scene.\n\n" << - "--studio-mode: Enable studio mode.\n" << - "--minimize-to-tray: Minimize to system tray.\n" << - "--portable, -p: Use portable mode.\n" << - "--multi, -m: Don't warn when launching multiple instances.\n\n" << - "--verbose: Make log more verbose.\n" << - "--always-on-top: Start in 'always on top' mode.\n\n" << - "--unfiltered_log: Make log unfiltered.\n\n" << - "--allow-opengl: Allow OpenGL on Windows.\n\n" << - "--version, -V: Get current version.\n"; + std::cout + << "--help, -h: Get list of available commands.\n\n" + << "--startstreaming: Automatically start streaming.\n" + << "--startrecording: Automatically start recording.\n" + << "--startreplaybuffer: Start replay buffer.\n\n" + << "--collection : Use specific scene collection." + << "\n" + << "--profile : Use specific profile.\n" + << "--scene : Start with specific scene.\n\n" + << "--studio-mode: Enable studio mode.\n" + << "--minimize-to-tray: Minimize to system tray.\n" + << "--portable, -p: Use portable mode.\n" + << "--multi, -m: Don't warn when launching multiple instances.\n\n" + << "--verbose: Make log more verbose.\n" + << "--always-on-top: Start in 'always on top' mode.\n\n" + << "--unfiltered_log: Make log unfiltered.\n\n" + << "--allow-opengl: Allow OpenGL on Windows.\n\n" + << "--version, -V: Get current version.\n"; exit(0); } else if (arg_is(argv[i], "--version", "-V")) { - std::cout << "OBS Studio - " << - App()->GetVersionString() << "\n"; + std::cout << "OBS Studio - " + << App()->GetVersionString() << "\n"; exit(0); } } diff --git a/UI/obs-app.hpp b/UI/obs-app.hpp index 2815331..b550ea8 100644 --- a/UI/obs-app.hpp +++ b/UI/obs-app.hpp @@ -36,48 +36,51 @@ std::string CurrentTimeString(); std::string CurrentDateTimeString(); -std::string GenerateTimeDateFilename(const char *extension, bool noSpace=false); +std::string GenerateTimeDateFilename(const char *extension, + bool noSpace = false); std::string GenerateSpecifiedFilename(const char *extension, bool noSpace, - const char *format); + const char *format); QObject *CreateShortcutFilter(); struct BaseLexer { lexer lex; + public: - inline BaseLexer() {lexer_init(&lex);} - inline ~BaseLexer() {lexer_free(&lex);} - operator lexer*() {return &lex;} + inline BaseLexer() { lexer_init(&lex); } + inline ~BaseLexer() { lexer_free(&lex); } + operator lexer *() { return &lex; } }; class OBSTranslator : public QTranslator { Q_OBJECT public: - virtual bool isEmpty() const override {return false;} + virtual bool isEmpty() const override { return false; } virtual QString translate(const char *context, const char *sourceText, - const char *disambiguation, int n) const override; + const char *disambiguation, + int n) const override; }; -typedef std::function VoidFunc; +typedef std::function VoidFunc; class OBSApp : public QApplication { Q_OBJECT private: - std::string locale; - std::string theme; - ConfigFile globalConfig; - TextLookup textLookup; - OBSContext obsContext; - QPointer mainWindow; - profiler_name_store_t *profilerNameStore = nullptr; + std::string locale; + std::string theme; + ConfigFile globalConfig; + TextLookup textLookup; + OBSContext obsContext; + QPointer mainWindow; + profiler_name_store_t *profilerNameStore = nullptr; - os_inhibit_t *sleepInhibitor = nullptr; - int sleepInhibitRefs = 0; - - bool enableHotkeysInFocus = true; + os_inhibit_t *sleepInhibitor = nullptr; + int sleepInhibitRefs = 0; + bool enableHotkeysInFocus = true; + bool enableHotkeysOutOfFocus = true; std::deque translatorHooks; @@ -93,8 +96,8 @@ private: QPalette defaultPalette; void ParseExtraThemeData(const char *path); - void AddExtraThemeColor(QPalette &pal, int group, - const char *name, uint32_t color); + void AddExtraThemeColor(QPalette &pal, int group, const char *name, + uint32_t color); public: OBSApp(int &argc, char **argv, profiler_name_store_t *store); @@ -103,21 +106,24 @@ public: void AppInit(); bool OBSInit(); - void EnableInFocusHotkeys(bool enable); + void UpdateHotkeyFocusSetting(bool reset = true); + void DisableHotkeys(); - inline QMainWindow *GetMainWindow() const {return mainWindow.data();} - - inline config_t *GlobalConfig() const {return globalConfig;} - - inline const char *GetLocale() const + inline bool HotkeysEnabledInFocus() const { - return locale.c_str(); + return enableHotkeysInFocus; } - inline const char *GetTheme() const {return theme.c_str();} + inline QMainWindow *GetMainWindow() const { return mainWindow.data(); } + + inline config_t *GlobalConfig() const { return globalConfig; } + + inline const char *GetLocale() const { return locale.c_str(); } + + inline const char *GetTheme() const { return theme.c_str(); } bool SetTheme(std::string name, std::string path = ""); - inline lookup_t *GetTextLookup() const {return textLookup;} + inline lookup_t *GetTextLookup() const { return textLookup; } inline const char *GetString(const char *lookupVal) const { @@ -146,15 +152,18 @@ public: inline void IncrementSleepInhibition() { - if (!sleepInhibitor) return; + if (!sleepInhibitor) + return; if (sleepInhibitRefs++ == 0) os_inhibit_sleep_set_active(sleepInhibitor, true); } inline void DecrementSleepInhibition() { - if (!sleepInhibitor) return; - if (sleepInhibitRefs == 0) return; + if (!sleepInhibitor) + return; + if (sleepInhibitRefs == 0) + return; if (--sleepInhibitRefs == 0) os_inhibit_sleep_set_active(sleepInhibitor, false); } @@ -164,10 +173,7 @@ public: translatorHooks.emplace_front(cb); } - inline void PopUITranslation() - { - translatorHooks.pop_front(); - } + inline void PopUITranslation() { translatorHooks.pop_front(); } public slots: void Exec(VoidFunc func); @@ -182,12 +188,21 @@ char *GetConfigPathPtr(const char *name); int GetProgramDataPath(char *path, size_t size, const char *name); char *GetProgramDataPathPtr(const char *name); -inline OBSApp *App() {return static_cast(qApp);} +inline OBSApp *App() +{ + return static_cast(qApp); +} -inline config_t *GetGlobalConfig() {return App()->GlobalConfig();} +inline config_t *GetGlobalConfig() +{ + return App()->GlobalConfig(); +} std::vector> GetLocaleNames(); -inline const char *Str(const char *lookup) {return App()->GetString(lookup);} +inline const char *Str(const char *lookup) +{ + return App()->GetString(lookup); +} #define QTStr(lookupVal) QString::fromUtf8(Str(lookupVal)) bool GetFileSafeName(const char *name, std::string &file); @@ -197,8 +212,8 @@ bool WindowPositionValid(QRect rect); static inline int GetProfilePath(char *path, size_t size, const char *file) { - OBSMainWindow *window = reinterpret_cast( - App()->GetMainWindow()); + OBSMainWindow *window = + reinterpret_cast(App()->GetMainWindow()); return window->GetProfilePath(path, size, file); } diff --git a/UI/obs-frontend-api/obs-frontend-api.cpp b/UI/obs-frontend-api/obs-frontend-api.cpp index 3fe84f4..c5fafeb 100644 --- a/UI/obs-frontend-api/obs-frontend-api.cpp +++ b/UI/obs-frontend-api/obs-frontend-api.cpp @@ -14,7 +14,7 @@ static inline bool callbacks_valid_(const char *func_name) { if (!c) { blog(LOG_WARNING, "Tried to call %s with no callbacks!", - func_name); + func_name); return false; } @@ -26,7 +26,7 @@ static inline bool callbacks_valid_(const char *func_name) static char **convert_string_list(vector &strings) { size_t size = 0; - size_t string_data_offset = (strings.size() + 1) * sizeof(char*); + size_t string_data_offset = (strings.size() + 1) * sizeof(char *); uint8_t *out; char **ptr_list; char *string_data; @@ -39,9 +39,9 @@ static char **convert_string_list(vector &strings) if (!size) return 0; - out = (uint8_t*)bmalloc(size); - ptr_list = (char**)out; - string_data = (char*)(out + string_data_offset); + out = (uint8_t *)bmalloc(size); + ptr_list = (char **)out; + string_data = (char *)(out + string_data_offset); for (auto &str : strings) { *ptr_list = string_data; @@ -52,30 +52,27 @@ static char **convert_string_list(vector &strings) } *ptr_list = nullptr; - return (char**)out; + return (char **)out; } /* ------------------------------------------------------------------------- */ void *obs_frontend_get_main_window(void) { - return !!callbacks_valid() - ? c->obs_frontend_get_main_window() - : nullptr; + return !!callbacks_valid() ? c->obs_frontend_get_main_window() + : nullptr; } void *obs_frontend_get_main_window_handle(void) { - return !!callbacks_valid() - ? c->obs_frontend_get_main_window_handle() - : nullptr; + return !!callbacks_valid() ? c->obs_frontend_get_main_window_handle() + : nullptr; } void *obs_frontend_get_system_tray(void) { - return !!callbacks_valid() - ? c->obs_frontend_get_system_tray() - : nullptr; + return !!callbacks_valid() ? c->obs_frontend_get_system_tray() + : nullptr; } char **obs_frontend_get_scene_names(void) @@ -99,31 +96,32 @@ char **obs_frontend_get_scene_names(void) void obs_frontend_get_scenes(struct obs_frontend_source_list *sources) { - if (callbacks_valid()) c->obs_frontend_get_scenes(sources); + if (callbacks_valid()) + c->obs_frontend_get_scenes(sources); } obs_source_t *obs_frontend_get_current_scene(void) { - return !!callbacks_valid() - ? c->obs_frontend_get_current_scene() - : nullptr; + return !!callbacks_valid() ? c->obs_frontend_get_current_scene() + : nullptr; } void obs_frontend_set_current_scene(obs_source_t *scene) { - if (callbacks_valid()) c->obs_frontend_set_current_scene(scene); + if (callbacks_valid()) + c->obs_frontend_set_current_scene(scene); } void obs_frontend_get_transitions(struct obs_frontend_source_list *sources) { - if (callbacks_valid()) c->obs_frontend_get_transitions(sources); + if (callbacks_valid()) + c->obs_frontend_get_transitions(sources); } obs_source_t *obs_frontend_get_current_transition(void) { - return !!callbacks_valid() - ? c->obs_frontend_get_current_transition() - : nullptr; + return !!callbacks_valid() ? c->obs_frontend_get_current_transition() + : nullptr; } void obs_frontend_set_current_transition(obs_source_t *transition) @@ -134,9 +132,8 @@ void obs_frontend_set_current_transition(obs_source_t *transition) int obs_frontend_get_transition_duration(void) { - return !!callbacks_valid() - ? c->obs_frontend_get_transition_duration() - : 0; + return !!callbacks_valid() ? c->obs_frontend_get_transition_duration() + : 0; } void obs_frontend_set_transition_duration(int duration) @@ -158,8 +155,8 @@ char **obs_frontend_get_scene_collections(void) char *obs_frontend_get_current_scene_collection(void) { return !!callbacks_valid() - ? c->obs_frontend_get_current_scene_collection() - : nullptr; + ? c->obs_frontend_get_current_scene_collection() + : nullptr; } void obs_frontend_set_current_scene_collection(const char *collection) @@ -170,9 +167,8 @@ void obs_frontend_set_current_scene_collection(const char *collection) bool obs_frontend_add_scene_collection(const char *name) { - return callbacks_valid() - ? c->obs_frontend_add_scene_collection(name) - : false; + return callbacks_valid() ? c->obs_frontend_add_scene_collection(name) + : false; } char **obs_frontend_get_profiles(void) @@ -187,9 +183,8 @@ char **obs_frontend_get_profiles(void) char *obs_frontend_get_current_profile(void) { - return !!callbacks_valid() - ? c->obs_frontend_get_current_profile() - : nullptr; + return !!callbacks_valid() ? c->obs_frontend_get_current_profile() + : nullptr; } void obs_frontend_set_current_profile(const char *profile) @@ -200,91 +195,103 @@ void obs_frontend_set_current_profile(const char *profile) void obs_frontend_streaming_start(void) { - if (callbacks_valid()) c->obs_frontend_streaming_start(); + if (callbacks_valid()) + c->obs_frontend_streaming_start(); } void obs_frontend_streaming_stop(void) { - if (callbacks_valid()) c->obs_frontend_streaming_stop(); + if (callbacks_valid()) + c->obs_frontend_streaming_stop(); } bool obs_frontend_streaming_active(void) { - return !!callbacks_valid() - ? c->obs_frontend_streaming_active() - : false; + return !!callbacks_valid() ? c->obs_frontend_streaming_active() : false; } void obs_frontend_recording_start(void) { - if (callbacks_valid()) c->obs_frontend_recording_start(); + if (callbacks_valid()) + c->obs_frontend_recording_start(); } void obs_frontend_recording_stop(void) { - if (callbacks_valid()) c->obs_frontend_recording_stop(); + if (callbacks_valid()) + c->obs_frontend_recording_stop(); } bool obs_frontend_recording_active(void) { - return !!callbacks_valid() - ? c->obs_frontend_recording_active() - : false; + return !!callbacks_valid() ? c->obs_frontend_recording_active() : false; +} + +void obs_frontend_recording_pause(bool pause) +{ + if (!!callbacks_valid()) + c->obs_frontend_recording_pause(pause); +} + +bool obs_frontend_recording_paused(void) +{ + return !!callbacks_valid() ? c->obs_frontend_recording_paused() : false; } void obs_frontend_replay_buffer_start(void) { - if (callbacks_valid()) c->obs_frontend_replay_buffer_start(); + if (callbacks_valid()) + c->obs_frontend_replay_buffer_start(); } void obs_frontend_replay_buffer_save(void) { - if (callbacks_valid()) c->obs_frontend_replay_buffer_save(); + if (callbacks_valid()) + c->obs_frontend_replay_buffer_save(); } void obs_frontend_replay_buffer_stop(void) { - if (callbacks_valid()) c->obs_frontend_replay_buffer_stop(); + if (callbacks_valid()) + c->obs_frontend_replay_buffer_stop(); } bool obs_frontend_replay_buffer_active(void) { - return !!callbacks_valid() - ? c->obs_frontend_replay_buffer_active() - : false; + return !!callbacks_valid() ? c->obs_frontend_replay_buffer_active() + : false; } void *obs_frontend_add_tools_menu_qaction(const char *name) { return !!callbacks_valid() - ? c->obs_frontend_add_tools_menu_qaction(name) - : nullptr; + ? c->obs_frontend_add_tools_menu_qaction(name) + : nullptr; } void obs_frontend_add_tools_menu_item(const char *name, - obs_frontend_cb callback, void *private_data) + obs_frontend_cb callback, + void *private_data) { if (callbacks_valid()) c->obs_frontend_add_tools_menu_item(name, callback, - private_data); + private_data); } void *obs_frontend_add_dock(void *dock) { - return !!callbacks_valid() - ? c->obs_frontend_add_dock(dock) - : nullptr; + return !!callbacks_valid() ? c->obs_frontend_add_dock(dock) : nullptr; } void obs_frontend_add_event_callback(obs_frontend_event_cb callback, - void *private_data) + void *private_data) { if (callbacks_valid()) c->obs_frontend_add_event_callback(callback, private_data); } void obs_frontend_remove_event_callback(obs_frontend_event_cb callback, - void *private_data) + void *private_data) { if (callbacks_valid()) c->obs_frontend_remove_event_callback(callback, private_data); @@ -292,37 +299,32 @@ void obs_frontend_remove_event_callback(obs_frontend_event_cb callback, obs_output_t *obs_frontend_get_streaming_output(void) { - return !!callbacks_valid() - ? c->obs_frontend_get_streaming_output() - : nullptr; + return !!callbacks_valid() ? c->obs_frontend_get_streaming_output() + : nullptr; } obs_output_t *obs_frontend_get_recording_output(void) { - return !!callbacks_valid() - ? c->obs_frontend_get_recording_output() - : nullptr; + return !!callbacks_valid() ? c->obs_frontend_get_recording_output() + : nullptr; } obs_output_t *obs_frontend_get_replay_buffer_output(void) { - return !!callbacks_valid() - ? c->obs_frontend_get_replay_buffer_output() - : nullptr; + return !!callbacks_valid() ? c->obs_frontend_get_replay_buffer_output() + : nullptr; } config_t *obs_frontend_get_profile_config(void) { - return !!callbacks_valid() - ? c->obs_frontend_get_profile_config() - : nullptr; + return !!callbacks_valid() ? c->obs_frontend_get_profile_config() + : nullptr; } config_t *obs_frontend_get_global_config(void) { - return !!callbacks_valid() - ? c->obs_frontend_get_global_config() - : nullptr; + return !!callbacks_valid() ? c->obs_frontend_get_global_config() + : nullptr; } void obs_frontend_save(void) @@ -344,28 +346,28 @@ void obs_frontend_defer_save_end(void) } void obs_frontend_add_save_callback(obs_frontend_save_cb callback, - void *private_data) + void *private_data) { if (callbacks_valid()) c->obs_frontend_add_save_callback(callback, private_data); } void obs_frontend_remove_save_callback(obs_frontend_save_cb callback, - void *private_data) + void *private_data) { if (callbacks_valid()) c->obs_frontend_remove_save_callback(callback, private_data); } void obs_frontend_add_preload_callback(obs_frontend_save_cb callback, - void *private_data) + void *private_data) { if (callbacks_valid()) c->obs_frontend_add_preload_callback(callback, private_data); } void obs_frontend_remove_preload_callback(obs_frontend_save_cb callback, - void *private_data) + void *private_data) { if (callbacks_valid()) c->obs_frontend_remove_preload_callback(callback, private_data); @@ -389,11 +391,10 @@ void obs_frontend_set_streaming_service(obs_service_t *service) c->obs_frontend_set_streaming_service(service); } -obs_service_t* obs_frontend_get_streaming_service(void) +obs_service_t *obs_frontend_get_streaming_service(void) { - return !!callbacks_valid() - ? c->obs_frontend_get_streaming_service() - : nullptr; + return !!callbacks_valid() ? c->obs_frontend_get_streaming_service() + : nullptr; } void obs_frontend_save_streaming_service(void) @@ -405,8 +406,8 @@ void obs_frontend_save_streaming_service(void) bool obs_frontend_preview_program_mode_active(void) { return !!callbacks_valid() - ? c->obs_frontend_preview_program_mode_active() - : false; + ? c->obs_frontend_preview_program_mode_active() + : false; } void obs_frontend_set_preview_program_mode(bool enable) @@ -429,16 +430,13 @@ void obs_frontend_set_preview_enabled(bool enable) bool obs_frontend_preview_enabled(void) { - return !!callbacks_valid() - ? c->obs_frontend_preview_enabled() - : false; + return !!callbacks_valid() ? c->obs_frontend_preview_enabled() : false; } obs_source_t *obs_frontend_get_current_preview_scene(void) { - return !!callbacks_valid() - ? c->obs_frontend_get_current_preview_scene() - : nullptr; + return !!callbacks_valid() ? c->obs_frontend_get_current_preview_scene() + : nullptr; } void obs_frontend_set_current_preview_scene(obs_source_t *scene) diff --git a/UI/obs-frontend-api/obs-frontend-api.h b/UI/obs-frontend-api/obs-frontend-api.h index 52f0bee..68fa917 100644 --- a/UI/obs-frontend-api/obs-frontend-api.h +++ b/UI/obs-frontend-api/obs-frontend-api.h @@ -43,7 +43,10 @@ enum obs_frontend_event { OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED, OBS_FRONTEND_EVENT_SCENE_COLLECTION_CLEANUP, - OBS_FRONTEND_EVENT_FINISHED_LOADING + OBS_FRONTEND_EVENT_FINISHED_LOADING, + + OBS_FRONTEND_EVENT_RECORDING_PAUSED, + OBS_FRONTEND_EVENT_RECORDING_UNPAUSED, }; /* ------------------------------------------------------------------------- */ @@ -51,11 +54,11 @@ enum obs_frontend_event { #ifndef SWIG struct obs_frontend_source_list { - DARRAY(obs_source_t*) sources; + DARRAY(obs_source_t *) sources; }; -static inline void obs_frontend_source_list_free( - struct obs_frontend_source_list *source_list) +static inline void +obs_frontend_source_list_free(struct obs_frontend_source_list *source_list) { size_t num = source_list->sources.num; for (size_t i = 0; i < num; i++) @@ -89,8 +92,8 @@ EXPORT void obs_frontend_get_scenes(struct obs_frontend_source_list *sources); EXPORT obs_source_t *obs_frontend_get_current_scene(void); EXPORT void obs_frontend_set_current_scene(obs_source_t *scene); -EXPORT void obs_frontend_get_transitions( - struct obs_frontend_source_list *sources); +EXPORT void +obs_frontend_get_transitions(struct obs_frontend_source_list *sources); EXPORT obs_source_t *obs_frontend_get_current_transition(void); EXPORT void obs_frontend_set_current_transition(obs_source_t *transition); EXPORT int obs_frontend_get_transition_duration(void); @@ -109,37 +112,38 @@ typedef void (*obs_frontend_cb)(void *private_data); EXPORT void *obs_frontend_add_tools_menu_qaction(const char *name); EXPORT void obs_frontend_add_tools_menu_item(const char *name, - obs_frontend_cb callback, void *private_data); + obs_frontend_cb callback, + void *private_data); /* takes QDockWidget and returns QAction */ EXPORT void *obs_frontend_add_dock(void *dock); typedef void (*obs_frontend_event_cb)(enum obs_frontend_event event, - void *private_data); + void *private_data); EXPORT void obs_frontend_add_event_callback(obs_frontend_event_cb callback, - void *private_data); + void *private_data); EXPORT void obs_frontend_remove_event_callback(obs_frontend_event_cb callback, - void *private_data); + void *private_data); typedef void (*obs_frontend_save_cb)(obs_data_t *save_data, bool saving, - void *private_data); + void *private_data); EXPORT void obs_frontend_add_save_callback(obs_frontend_save_cb callback, - void *private_data); + void *private_data); EXPORT void obs_frontend_remove_save_callback(obs_frontend_save_cb callback, - void *private_data); + void *private_data); EXPORT void obs_frontend_add_preload_callback(obs_frontend_save_cb callback, - void *private_data); + void *private_data); EXPORT void obs_frontend_remove_preload_callback(obs_frontend_save_cb callback, - void *private_data); + void *private_data); typedef bool (*obs_frontend_translate_ui_cb)(const char *text, - const char **out); + const char **out); -EXPORT void obs_frontend_push_ui_translation( - obs_frontend_translate_ui_cb translate); +EXPORT void +obs_frontend_push_ui_translation(obs_frontend_translate_ui_cb translate); EXPORT void obs_frontend_pop_ui_translation(void); #endif //!SWIG @@ -151,6 +155,8 @@ EXPORT bool obs_frontend_streaming_active(void); EXPORT void obs_frontend_recording_start(void); EXPORT void obs_frontend_recording_stop(void); EXPORT bool obs_frontend_recording_active(void); +EXPORT void obs_frontend_recording_pause(bool pause); +EXPORT bool obs_frontend_recording_paused(void); EXPORT void obs_frontend_replay_buffer_start(void); EXPORT void obs_frontend_replay_buffer_save(void); @@ -169,7 +175,7 @@ EXPORT config_t *obs_frontend_get_profile_config(void); EXPORT config_t *obs_frontend_get_global_config(void); EXPORT void obs_frontend_set_streaming_service(obs_service_t *service); -EXPORT obs_service_t* obs_frontend_get_streaming_service(void); +EXPORT obs_service_t *obs_frontend_get_streaming_service(void); EXPORT void obs_frontend_save_streaming_service(void); EXPORT bool obs_frontend_preview_program_mode_active(void); diff --git a/UI/obs-frontend-api/obs-frontend-internal.hpp b/UI/obs-frontend-api/obs-frontend-internal.hpp index 3ed9283..80051ca 100644 --- a/UI/obs-frontend-api/obs-frontend-internal.hpp +++ b/UI/obs-frontend-api/obs-frontend-internal.hpp @@ -7,103 +7,113 @@ struct obs_frontend_callbacks { virtual ~obs_frontend_callbacks() {} - virtual void *obs_frontend_get_main_window(void)=0; - virtual void *obs_frontend_get_main_window_handle(void)=0; - virtual void *obs_frontend_get_system_tray(void)=0; + virtual void *obs_frontend_get_main_window(void) = 0; + virtual void *obs_frontend_get_main_window_handle(void) = 0; + virtual void *obs_frontend_get_system_tray(void) = 0; - virtual void obs_frontend_get_scenes( - struct obs_frontend_source_list *sources)=0; - virtual obs_source_t *obs_frontend_get_current_scene(void)=0; - virtual void obs_frontend_set_current_scene(obs_source_t *scene)=0; + virtual void + obs_frontend_get_scenes(struct obs_frontend_source_list *sources) = 0; + virtual obs_source_t *obs_frontend_get_current_scene(void) = 0; + virtual void obs_frontend_set_current_scene(obs_source_t *scene) = 0; virtual void obs_frontend_get_transitions( - struct obs_frontend_source_list *sources)=0; - virtual obs_source_t *obs_frontend_get_current_transition(void)=0; - virtual void obs_frontend_set_current_transition( - obs_source_t *transition)=0; - virtual int obs_frontend_get_transition_duration(void)=0; - virtual void obs_frontend_set_transition_duration(int duration)=0; + struct obs_frontend_source_list *sources) = 0; + virtual obs_source_t *obs_frontend_get_current_transition(void) = 0; + virtual void + obs_frontend_set_current_transition(obs_source_t *transition) = 0; + virtual int obs_frontend_get_transition_duration(void) = 0; + virtual void obs_frontend_set_transition_duration(int duration) = 0; virtual void obs_frontend_get_scene_collections( - std::vector &strings)=0; - virtual char *obs_frontend_get_current_scene_collection(void)=0; - virtual void obs_frontend_set_current_scene_collection( - const char *collection)=0; - virtual bool obs_frontend_add_scene_collection(const char *name)=0; + std::vector &strings) = 0; + virtual char *obs_frontend_get_current_scene_collection(void) = 0; + virtual void + obs_frontend_set_current_scene_collection(const char *collection) = 0; + virtual bool obs_frontend_add_scene_collection(const char *name) = 0; - virtual void obs_frontend_get_profiles( - std::vector &strings)=0; - virtual char *obs_frontend_get_current_profile(void)=0; - virtual void obs_frontend_set_current_profile(const char *profile)=0; + virtual void + obs_frontend_get_profiles(std::vector &strings) = 0; + virtual char *obs_frontend_get_current_profile(void) = 0; + virtual void obs_frontend_set_current_profile(const char *profile) = 0; - virtual void obs_frontend_streaming_start(void)=0; - virtual void obs_frontend_streaming_stop(void)=0; - virtual bool obs_frontend_streaming_active(void)=0; + virtual void obs_frontend_streaming_start(void) = 0; + virtual void obs_frontend_streaming_stop(void) = 0; + virtual bool obs_frontend_streaming_active(void) = 0; - virtual void obs_frontend_recording_start(void)=0; - virtual void obs_frontend_recording_stop(void)=0; - virtual bool obs_frontend_recording_active(void)=0; + virtual void obs_frontend_recording_start(void) = 0; + virtual void obs_frontend_recording_stop(void) = 0; + virtual bool obs_frontend_recording_active(void) = 0; + virtual void obs_frontend_recording_pause(bool pause) = 0; + virtual bool obs_frontend_recording_paused(void) = 0; - virtual void obs_frontend_replay_buffer_start(void)=0; + virtual void obs_frontend_replay_buffer_start(void) = 0; virtual void obs_frontend_replay_buffer_save(void) = 0; - virtual void obs_frontend_replay_buffer_stop(void)=0; - virtual bool obs_frontend_replay_buffer_active(void)=0; + virtual void obs_frontend_replay_buffer_stop(void) = 0; + virtual bool obs_frontend_replay_buffer_active(void) = 0; - virtual void *obs_frontend_add_tools_menu_qaction(const char *name)=0; + virtual void *obs_frontend_add_tools_menu_qaction(const char *name) = 0; virtual void obs_frontend_add_tools_menu_item(const char *name, - obs_frontend_cb callback, void *private_data)=0; + obs_frontend_cb callback, + void *private_data) = 0; - virtual void *obs_frontend_add_dock(void *dock)=0; + virtual void *obs_frontend_add_dock(void *dock) = 0; - virtual void obs_frontend_add_event_callback( - obs_frontend_event_cb callback, void *private_data)=0; - virtual void obs_frontend_remove_event_callback( - obs_frontend_event_cb callback, void *private_data)=0; + virtual void + obs_frontend_add_event_callback(obs_frontend_event_cb callback, + void *private_data) = 0; + virtual void + obs_frontend_remove_event_callback(obs_frontend_event_cb callback, + void *private_data) = 0; - virtual obs_output_t *obs_frontend_get_streaming_output(void)=0; - virtual obs_output_t *obs_frontend_get_recording_output(void)=0; - virtual obs_output_t *obs_frontend_get_replay_buffer_output(void)=0; + virtual obs_output_t *obs_frontend_get_streaming_output(void) = 0; + virtual obs_output_t *obs_frontend_get_recording_output(void) = 0; + virtual obs_output_t *obs_frontend_get_replay_buffer_output(void) = 0; - virtual config_t *obs_frontend_get_profile_config(void)=0; - virtual config_t *obs_frontend_get_global_config(void)=0; + virtual config_t *obs_frontend_get_profile_config(void) = 0; + virtual config_t *obs_frontend_get_global_config(void) = 0; virtual void obs_frontend_save(void) = 0; virtual void obs_frontend_defer_save_begin(void) = 0; virtual void obs_frontend_defer_save_end(void) = 0; - virtual void obs_frontend_add_save_callback( - obs_frontend_save_cb callback, void *private_data)=0; - virtual void obs_frontend_remove_save_callback( - obs_frontend_save_cb callback, void *private_data)=0; + virtual void + obs_frontend_add_save_callback(obs_frontend_save_cb callback, + void *private_data) = 0; + virtual void + obs_frontend_remove_save_callback(obs_frontend_save_cb callback, + void *private_data) = 0; - virtual void obs_frontend_add_preload_callback( - obs_frontend_save_cb callback, void *private_data)=0; - virtual void obs_frontend_remove_preload_callback( - obs_frontend_save_cb callback, void *private_data)=0; + virtual void + obs_frontend_add_preload_callback(obs_frontend_save_cb callback, + void *private_data) = 0; + virtual void + obs_frontend_remove_preload_callback(obs_frontend_save_cb callback, + void *private_data) = 0; virtual void obs_frontend_push_ui_translation( - obs_frontend_translate_ui_cb translate)=0; - virtual void obs_frontend_pop_ui_translation(void)=0; + obs_frontend_translate_ui_cb translate) = 0; + virtual void obs_frontend_pop_ui_translation(void) = 0; - virtual void obs_frontend_set_streaming_service( - obs_service_t *service)=0; - virtual obs_service_t *obs_frontend_get_streaming_service(void)=0; - virtual void obs_frontend_save_streaming_service()=0; + virtual void + obs_frontend_set_streaming_service(obs_service_t *service) = 0; + virtual obs_service_t *obs_frontend_get_streaming_service(void) = 0; + virtual void obs_frontend_save_streaming_service() = 0; - virtual bool obs_frontend_preview_program_mode_active(void)=0; - virtual void obs_frontend_set_preview_program_mode(bool enable)=0; - virtual void obs_frontend_preview_program_trigger_transition(void)=0; + virtual bool obs_frontend_preview_program_mode_active(void) = 0; + virtual void obs_frontend_set_preview_program_mode(bool enable) = 0; + virtual void obs_frontend_preview_program_trigger_transition(void) = 0; - virtual bool obs_frontend_preview_enabled(void)=0; - virtual void obs_frontend_set_preview_enabled(bool enable)=0; + virtual bool obs_frontend_preview_enabled(void) = 0; + virtual void obs_frontend_set_preview_enabled(bool enable) = 0; - virtual obs_source_t *obs_frontend_get_current_preview_scene(void)=0; - virtual void obs_frontend_set_current_preview_scene(obs_source_t *scene)=0; + virtual obs_source_t *obs_frontend_get_current_preview_scene(void) = 0; + virtual void + obs_frontend_set_current_preview_scene(obs_source_t *scene) = 0; - virtual void on_load(obs_data_t *settings)=0; - virtual void on_preload(obs_data_t *settings)=0; - virtual void on_save(obs_data_t *settings)=0; - virtual void on_event(enum obs_frontend_event event)=0; + virtual void on_load(obs_data_t *settings) = 0; + virtual void on_preload(obs_data_t *settings) = 0; + virtual void on_save(obs_data_t *settings) = 0; + virtual void on_event(enum obs_frontend_event event) = 0; }; -EXPORT void obs_frontend_set_callbacks_internal( - obs_frontend_callbacks *callbacks); +EXPORT void +obs_frontend_set_callbacks_internal(obs_frontend_callbacks *callbacks); diff --git a/UI/platform-osx.mm b/UI/platform-osx.mm index 37e7c0a..bc400f5 100644 --- a/UI/platform-osx.mm +++ b/UI/platform-osx.mm @@ -58,7 +58,7 @@ bool InitApplicationBundle() throw "Could not change working directory to " "bundle path"; - } catch (const char* error) { + } catch (const char *error) { blog(LOG_ERROR, "InitBundle: %s", error); return false; } @@ -77,7 +77,7 @@ string GetDefaultVideoSavePath() appropriateForURL:nil create:true error:nil]; - + if (!url) return getenv("HOME"); @@ -97,7 +97,7 @@ vector GetPreferredLocales() return locale.first; if (!lang_match.size() && - locale.first.substr(0, 2) == lang.substr(0, 2)) + locale.first.substr(0, 2) == lang.substr(0, 2)) lang_match = locale.first; } @@ -150,12 +150,13 @@ void EnableOSXVSync(bool enable) if (!initialized) { void *quartzCore = dlopen("/System/Library/Frameworks/" - "QuartzCore.framework/QuartzCore", RTLD_LAZY); + "QuartzCore.framework/QuartzCore", + RTLD_LAZY); if (quartzCore) { - set_debug_options = (set_int_t)dlsym(quartzCore, - "CGSSetDebugOptions"); - deferred_updates = (set_int_t)dlsym(quartzCore, - "CGSDeferredUpdates"); + set_debug_options = (set_int_t)dlsym( + quartzCore, "CGSSetDebugOptions"); + deferred_updates = (set_int_t)dlsym( + quartzCore, "CGSDeferredUpdates"); valid = set_debug_options && deferred_updates; } @@ -174,5 +175,6 @@ void EnableOSXDockIcon(bool enable) if (enable) [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; else - [NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited]; + [NSApp setActivationPolicy: + NSApplicationActivationPolicyProhibited]; } diff --git a/UI/platform-windows.cpp b/UI/platform-windows.cpp index 9074018..292bc28 100644 --- a/UI/platform-windows.cpp +++ b/UI/platform-windows.cpp @@ -37,8 +37,8 @@ using namespace std; #include #include -static inline bool check_path(const char* data, const char *path, - string &output) +static inline bool check_path(const char *data, const char *path, + string &output) { ostringstream str; str << path << data; @@ -65,10 +65,10 @@ bool InitApplicationBundle() string GetDefaultVideoSavePath() { wchar_t path_utf16[MAX_PATH]; - char path_utf8[MAX_PATH] = {}; + char path_utf8[MAX_PATH] = {}; SHGetFolderPathW(NULL, CSIDL_MYVIDEO, NULL, SHGFP_TYPE_CURRENT, - path_utf16); + path_utf16); os_wcs_to_utf8(path_utf16, wcslen(path_utf16), path_utf8, MAX_PATH); return string(path_utf8); @@ -79,18 +79,18 @@ static vector GetUserPreferredLocales() vector result; ULONG num, length = 0; - if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num, - nullptr, &length)) + if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num, nullptr, + &length)) return result; vector buffer(length); if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num, - &buffer.front(), &length)) + &buffer.front(), &length)) return result; result.reserve(num); auto start = begin(buffer); - auto end_ = end(buffer); + auto end_ = end(buffer); decltype(start) separator; while ((separator = find(start, end_, 0)) != end_) { if (result.size() == num) @@ -162,7 +162,7 @@ uint32_t GetWindowsVersion() void SetAeroEnabled(bool enable) { - static HRESULT (WINAPI *func)(UINT) = nullptr; + static HRESULT(WINAPI * func)(UINT) = nullptr; static bool failed = false; if (!func) { @@ -176,8 +176,8 @@ void SetAeroEnabled(bool enable) return; } - func = reinterpret_cast(GetProcAddress(dwm, - "DwmEnableComposition")); + func = reinterpret_cast( + GetProcAddress(dwm, "DwmEnableComposition")); if (!func) { failed = true; return; @@ -197,7 +197,7 @@ void SetAlwaysOnTop(QWidget *window, bool enable) { HWND hwnd = (HWND)window->winId(); SetWindowPos(hwnd, enable ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); } void SetProcessPriority(const char *priority) @@ -208,11 +208,13 @@ void SetProcessPriority(const char *priority) if (strcmp(priority, "High") == 0) SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); else if (strcmp(priority, "AboveNormal") == 0) - SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); + SetPriorityClass(GetCurrentProcess(), + ABOVE_NORMAL_PRIORITY_CLASS); else if (strcmp(priority, "Normal") == 0) SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); else if (strcmp(priority, "BelowNormal") == 0) - SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS); + SetPriorityClass(GetCurrentProcess(), + BELOW_NORMAL_PRIORITY_CLASS); else if (strcmp(priority, "Idle") == 0) SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); } @@ -227,16 +229,16 @@ void SetWin32DropStyle(QWidget *window) bool DisableAudioDucking(bool disable) { - ComPtr devEmum; - ComPtr device; + ComPtr devEmum; + ComPtr device; ComPtr sessionManager2; - ComPtr sessionControl; + ComPtr sessionControl; ComPtr sessionControl2; - HRESULT result = CoCreateInstance(__uuidof(MMDeviceEnumerator), - nullptr, CLSCTX_INPROC_SERVER, - __uuidof(IMMDeviceEnumerator), - (void **)&devEmum); + HRESULT result = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, + CLSCTX_INPROC_SERVER, + __uuidof(IMMDeviceEnumerator), + (void **)&devEmum); if (FAILED(result)) return false; @@ -245,13 +247,13 @@ bool DisableAudioDucking(bool disable) return false; result = device->Activate(__uuidof(IAudioSessionManager2), - CLSCTX_INPROC_SERVER, nullptr, - (void **)&sessionManager2); + CLSCTX_INPROC_SERVER, nullptr, + (void **)&sessionManager2); if (FAILED(result)) return false; result = sessionManager2->GetAudioSessionControl(nullptr, 0, - &sessionControl); + &sessionControl); if (FAILED(result)) return false; diff --git a/UI/platform-x11.cpp b/UI/platform-x11.cpp index c6b02b9..3219f6d 100644 --- a/UI/platform-x11.cpp +++ b/UI/platform-x11.cpp @@ -29,8 +29,8 @@ #include "platform.hpp" using namespace std; -static inline bool check_path(const char* data, const char *path, - string &output) +static inline bool check_path(const char *data, const char *path, + string &output) { ostringstream str; str << path << data; diff --git a/UI/platform.hpp b/UI/platform.hpp index 4da23b3..99a90de 100644 --- a/UI/platform.hpp +++ b/UI/platform.hpp @@ -48,6 +48,7 @@ struct RunOnceMutexData; class RunOnceMutex { RunOnceMutexData *data = nullptr; + public: RunOnceMutex(RunOnceMutexData *data_) : data(data_) {} RunOnceMutex(const RunOnceMutex &rom) = delete; diff --git a/UI/properties-view.cpp b/UI/properties-view.cpp index a1f9ba8..313a2e1 100644 --- a/UI/properties-view.cpp +++ b/UI/properties-view.cpp @@ -37,23 +37,18 @@ using namespace std; static inline QColor color_from_int(long long val) { - return QColor( val & 0xff, - (val >> 8) & 0xff, - (val >> 16) & 0xff, + return QColor(val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff, (val >> 24) & 0xff); } static inline long long color_to_int(QColor color) { - auto shift = [&](unsigned val, int shift) - { + auto shift = [&](unsigned val, int shift) { return ((val & 0xff) << shift); }; - return shift(color.red(), 0) | - shift(color.green(), 8) | - shift(color.blue(), 16) | - shift(color.alpha(), 24); + return shift(color.red(), 0) | shift(color.green(), 8) | + shift(color.blue(), 16) | shift(color.alpha(), 24); } namespace { @@ -68,16 +63,11 @@ struct frame_rate_tag { frame_rate_tag() = default; - explicit frame_rate_tag(tag_type type) - : type(type) - {} + explicit frame_rate_tag(tag_type type) : type(type) {} - explicit frame_rate_tag(const char *val) - : type(USER), - val(val) - {} + explicit frame_rate_tag(const char *val) : type(USER), val(val) {} - static frame_rate_tag simple() { return frame_rate_tag{SIMPLE}; } + static frame_rate_tag simple() { return frame_rate_tag{SIMPLE}; } static frame_rate_tag rational() { return frame_rate_tag{RATIONAL}; } }; @@ -96,7 +86,7 @@ void OBSPropertiesView::ReloadProperties() if (obj) { properties.reset(reloadCallback(obj)); } else { - properties.reset(reloadCallback((void*)type.c_str())); + properties.reset(reloadCallback((void *)type.c_str())); obs_properties_apply_settings(properties.get(), settings); } @@ -181,28 +171,30 @@ void OBSPropertiesView::GetScrollPos(int &h, int &v) } OBSPropertiesView::OBSPropertiesView(OBSData settings_, void *obj_, - PropertiesReloadCallback reloadCallback, - PropertiesUpdateCallback callback_, int minSize_) - : VScrollArea (nullptr), - properties (nullptr, obs_properties_destroy), - settings (settings_), - obj (obj_), - reloadCallback (reloadCallback), - callback (callback_), - minSize (minSize_) + PropertiesReloadCallback reloadCallback, + PropertiesUpdateCallback callback_, + int minSize_) + : VScrollArea(nullptr), + properties(nullptr, obs_properties_destroy), + settings(settings_), + obj(obj_), + reloadCallback(reloadCallback), + callback(callback_), + minSize(minSize_) { setFrameShape(QFrame::NoFrame); ReloadProperties(); } OBSPropertiesView::OBSPropertiesView(OBSData settings_, const char *type_, - PropertiesReloadCallback reloadCallback_, int minSize_) - : VScrollArea (nullptr), - properties (nullptr, obs_properties_destroy), - settings (settings_), - type (type_), - reloadCallback (reloadCallback_), - minSize (minSize_) + PropertiesReloadCallback reloadCallback_, + int minSize_) + : VScrollArea(nullptr), + properties(nullptr, obs_properties_destroy), + settings(settings_), + type(type_), + reloadCallback(reloadCallback_), + minSize(minSize_) { setFrameShape(QFrame::NoFrame); ReloadProperties(); @@ -215,7 +207,7 @@ void OBSPropertiesView::resizeEvent(QResizeEvent *event) } QWidget *OBSPropertiesView::NewWidget(obs_property_t *prop, QWidget *widget, - const char *signal) + const char *signal) { const char *long_desc = obs_property_long_description(prop); @@ -231,7 +223,7 @@ QWidget *OBSPropertiesView::AddCheckbox(obs_property_t *prop) { const char *name = obs_property_name(prop); const char *desc = obs_property_description(prop); - bool val = obs_data_get_bool(settings, name); + bool val = obs_data_get_bool(settings, name); QCheckBox *checkbox = new QCheckBox(QT_UTF8(desc)); checkbox->setCheckState(val ? Qt::Checked : Qt::Unchecked); @@ -239,11 +231,11 @@ QWidget *OBSPropertiesView::AddCheckbox(obs_property_t *prop) } QWidget *OBSPropertiesView::AddText(obs_property_t *prop, QFormLayout *layout, - QLabel *&label) + QLabel *&label) { - const char *name = obs_property_name(prop); - const char *val = obs_data_get_string(settings, name); - obs_text_type type = obs_property_text_type(prop); + const char *name = obs_property_name(prop); + const char *val = obs_data_get_string(settings, name); + obs_text_type type = obs_property_text_type(prop); if (type == OBS_TEXT_MULTILINE) { QPlainTextEdit *edit = new QPlainTextEdit(QT_UTF8(val)); @@ -263,10 +255,9 @@ QWidget *OBSPropertiesView::AddText(obs_property_t *prop, QFormLayout *layout, subLayout->addWidget(show); WidgetInfo *info = new WidgetInfo(this, prop, edit); - connect(show, &QAbstractButton::toggled, - info, &WidgetInfo::TogglePasswordText); - connect(show, &QAbstractButton::toggled, [=](bool hide) - { + connect(show, &QAbstractButton::toggled, info, + &WidgetInfo::TogglePasswordText); + connect(show, &QAbstractButton::toggled, [=](bool hide) { show->setText(hide ? QTStr("Hide") : QTStr("Show")); }); children.emplace_back(info); @@ -276,8 +267,8 @@ QWidget *OBSPropertiesView::AddText(obs_property_t *prop, QFormLayout *layout, edit->setToolTip(QT_UTF8(obs_property_long_description(prop))); - connect(edit, SIGNAL(textEdited(const QString &)), - info, SLOT(ControlChanged())); + connect(edit, SIGNAL(textEdited(const QString &)), info, + SLOT(ControlChanged())); return nullptr; } @@ -290,13 +281,13 @@ QWidget *OBSPropertiesView::AddText(obs_property_t *prop, QFormLayout *layout, } void OBSPropertiesView::AddPath(obs_property_t *prop, QFormLayout *layout, - QLabel **label) + QLabel **label) { - const char *name = obs_property_name(prop); - const char *val = obs_data_get_string(settings, name); - QLayout *subLayout = new QHBoxLayout(); - QLineEdit *edit = new QLineEdit(); - QPushButton *button = new QPushButton(QTStr("Browse")); + const char *name = obs_property_name(prop); + const char *val = obs_data_get_string(settings, name); + QLayout *subLayout = new QHBoxLayout(); + QLineEdit *edit = new QLineEdit(); + QPushButton *button = new QPushButton(QTStr("Browse")); if (!obs_property_enabled(prop)) { edit->setEnabled(false); @@ -320,14 +311,14 @@ void OBSPropertiesView::AddPath(obs_property_t *prop, QFormLayout *layout, } void OBSPropertiesView::AddInt(obs_property_t *prop, QFormLayout *layout, - QLabel **label) + QLabel **label) { obs_number_type type = obs_property_int_type(prop); QLayout *subLayout = new QHBoxLayout(); const char *name = obs_property_name(prop); - int val = (int)obs_data_get_int(settings, name); - QSpinBox *spin = new SpinBoxIgnoreScroll(); + int val = (int)obs_data_get_int(settings, name); + QSpinBox *spin = new SpinBoxIgnoreScroll(); if (!obs_property_enabled(prop)) spin->setEnabled(false); @@ -356,10 +347,10 @@ void OBSPropertiesView::AddInt(obs_property_t *prop, QFormLayout *layout, slider->setOrientation(Qt::Horizontal); subLayout->addWidget(slider); - connect(slider, SIGNAL(valueChanged(int)), - spin, SLOT(setValue(int))); - connect(spin, SIGNAL(valueChanged(int)), - slider, SLOT(setValue(int))); + connect(slider, SIGNAL(valueChanged(int)), spin, + SLOT(setValue(int))); + connect(spin, SIGNAL(valueChanged(int)), slider, + SLOT(setValue(int))); } connect(spin, SIGNAL(valueChanged(int)), info, SLOT(ControlChanged())); @@ -371,13 +362,13 @@ void OBSPropertiesView::AddInt(obs_property_t *prop, QFormLayout *layout, } void OBSPropertiesView::AddFloat(obs_property_t *prop, QFormLayout *layout, - QLabel **label) + QLabel **label) { obs_number_type type = obs_property_float_type(prop); QLayout *subLayout = new QHBoxLayout(); - const char *name = obs_property_name(prop); - double val = obs_data_get_double(settings, name); + const char *name = obs_property_name(prop); + double val = obs_data_get_double(settings, name); QDoubleSpinBox *spin = new QDoubleSpinBox(); if (!obs_property_enabled(prop)) @@ -404,14 +395,14 @@ void OBSPropertiesView::AddFloat(obs_property_t *prop, QFormLayout *layout, slider->setOrientation(Qt::Horizontal); subLayout->addWidget(slider); - connect(slider, SIGNAL(doubleValChanged(double)), - spin, SLOT(setValue(double))); - connect(spin, SIGNAL(valueChanged(double)), - slider, SLOT(setDoubleVal(double))); + connect(slider, SIGNAL(doubleValChanged(double)), spin, + SLOT(setValue(double))); + connect(spin, SIGNAL(valueChanged(double)), slider, + SLOT(setDoubleVal(double))); } connect(spin, SIGNAL(valueChanged(double)), info, - SLOT(ControlChanged())); + SLOT(ControlChanged())); subLayout->addWidget(spin); @@ -420,7 +411,7 @@ void OBSPropertiesView::AddFloat(obs_property_t *prop, QFormLayout *layout, } static void AddComboItem(QComboBox *combo, obs_property_t *prop, - obs_combo_format format, size_t idx) + obs_combo_format format, size_t idx) { const char *name = obs_property_list_item_name(prop, idx); QVariant var; @@ -447,7 +438,7 @@ static void AddComboItem(QComboBox *combo, obs_property_t *prop, return; QStandardItemModel *model = - dynamic_cast(combo->model()); + dynamic_cast(combo->model()); if (!model) return; @@ -455,11 +446,11 @@ static void AddComboItem(QComboBox *combo, obs_property_t *prop, item->setFlags(Qt::NoItemFlags); } -template +template static string from_obs_data(obs_data_t *data, const char *name, - obs_combo_format format) + obs_combo_format format) { switch (format) { case OBS_COMBO_FORMAT_INT: @@ -474,28 +465,29 @@ static string from_obs_data(obs_data_t *data, const char *name, } static string from_obs_data(obs_data_t *data, const char *name, - obs_combo_format format) + obs_combo_format format) { return from_obs_data(data, name, format); + obs_data_get_string>(data, name, format); } static string from_obs_data_autoselect(obs_data_t *data, const char *name, - obs_combo_format format) + obs_combo_format format) { return from_obs_data(data, name, format); + obs_data_get_autoselect_double, + obs_data_get_autoselect_string>(data, name, + format); } QWidget *OBSPropertiesView::AddList(obs_property_t *prop, bool &warning) { - const char *name = obs_property_name(prop); - QComboBox *combo = new ComboBoxIgnoreScroll(); - obs_combo_type type = obs_property_list_type(prop); + const char *name = obs_property_name(prop); + QComboBox *combo = new ComboBoxIgnoreScroll(); + obs_combo_type type = obs_property_list_type(prop); obs_combo_format format = obs_property_list_format(prop); - size_t count = obs_property_list_item_count(prop); - int idx = -1; + size_t count = obs_property_list_item_count(prop); + int idx = -1; for (size_t i = 0; i < count; i++) AddComboItem(combo, prop, format, i); @@ -509,7 +501,7 @@ QWidget *OBSPropertiesView::AddList(obs_property_t *prop, bool &warning) string value = from_obs_data(settings, name, format); if (format == OBS_COMBO_FORMAT_STRING && - type == OBS_COMBO_TYPE_EDITABLE) { + type == OBS_COMBO_TYPE_EDITABLE) { combo->lineEdit()->setText(QT_UTF8(value.c_str())); } else { idx = combo->findData(QByteArray(value.c_str())); @@ -517,34 +509,33 @@ QWidget *OBSPropertiesView::AddList(obs_property_t *prop, bool &warning) if (type == OBS_COMBO_TYPE_EDITABLE) return NewWidget(prop, combo, - SIGNAL(editTextChanged(const QString &))); + SIGNAL(editTextChanged(const QString &))); if (idx != -1) combo->setCurrentIndex(idx); - + if (obs_data_has_autoselect_value(settings, name)) { string autoselect = from_obs_data_autoselect(settings, name, format); int id = combo->findData(QT_UTF8(autoselect.c_str())); if (id != -1 && id != idx) { - QString actual = combo->itemText(id); + QString actual = combo->itemText(id); QString selected = combo->itemText(idx); QString combined = QTStr( "Basic.PropertiesWindow.AutoSelectFormat"); combo->setItemText(idx, - combined.arg(selected).arg(actual)); + combined.arg(selected).arg(actual)); } } - QAbstractItemModel *model = combo->model(); warning = idx != -1 && - model->flags(model->index(idx, 0)) == Qt::NoItemFlags; + model->flags(model->index(idx, 0)) == Qt::NoItemFlags; WidgetInfo *info = new WidgetInfo(this, prop, combo); connect(combo, SIGNAL(currentIndexChanged(int)), info, - SLOT(ControlChanged())); + SLOT(ControlChanged())); children.emplace_back(info); /* trigger a settings update if the index was not found */ @@ -554,9 +545,8 @@ QWidget *OBSPropertiesView::AddList(obs_property_t *prop, bool &warning) return combo; } -static void NewButton(QLayout *layout, WidgetInfo *info, - const char *themeIcon, - void (WidgetInfo::*method)()) +static void NewButton(QLayout *layout, WidgetInfo *info, const char *themeIcon, + void (WidgetInfo::*method)()) { QPushButton *button = new QPushButton(); button->setProperty("themeID", themeIcon); @@ -570,12 +560,12 @@ static void NewButton(QLayout *layout, WidgetInfo *info, } void OBSPropertiesView::AddEditableList(obs_property_t *prop, - QFormLayout *layout, QLabel *&label) + QFormLayout *layout, QLabel *&label) { - const char *name = obs_property_name(prop); + const char *name = obs_property_name(prop); obs_data_array_t *array = obs_data_get_array(settings, name); - QListWidget *list = new QListWidget(); - size_t count = obs_data_array_count(array); + QListWidget *list = new QListWidget(); + size_t count = obs_data_array_count(array); if (!obs_property_enabled(prop)) list->setEnabled(false); @@ -588,25 +578,24 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop, obs_data_t *item = obs_data_array_item(array, i); list->addItem(QT_UTF8(obs_data_get_string(item, "value"))); list->setItemSelected(list->item((int)i), - obs_data_get_bool(item, "selected")); + obs_data_get_bool(item, "selected")); list->setItemHidden(list->item((int)i), - obs_data_get_bool(item, "hidden")); + obs_data_get_bool(item, "hidden")); obs_data_release(item); } WidgetInfo *info = new WidgetInfo(this, prop, list); QVBoxLayout *sideLayout = new QVBoxLayout(); - NewButton(sideLayout, info, "addIconSmall", - &WidgetInfo::EditListAdd); + NewButton(sideLayout, info, "addIconSmall", &WidgetInfo::EditListAdd); NewButton(sideLayout, info, "removeIconSmall", - &WidgetInfo::EditListRemove); + &WidgetInfo::EditListRemove); NewButton(sideLayout, info, "configIconSmall", - &WidgetInfo::EditListEdit); + &WidgetInfo::EditListEdit); NewButton(sideLayout, info, "upArrowIconSmall", - &WidgetInfo::EditListUp); + &WidgetInfo::EditListUp); NewButton(sideLayout, info, "downArrowIconSmall", - &WidgetInfo::EditListDown); + &WidgetInfo::EditListDown); sideLayout->addStretch(0); QHBoxLayout *subLayout = new QHBoxLayout(); @@ -632,13 +621,13 @@ QWidget *OBSPropertiesView::AddButton(obs_property_t *prop) } void OBSPropertiesView::AddColor(obs_property_t *prop, QFormLayout *layout, - QLabel *&label) + QLabel *&label) { - QPushButton *button = new QPushButton; - QLabel *colorLabel = new QLabel; - const char *name = obs_property_name(prop); - long long val = obs_data_get_int(settings, name); - QColor color = color_from_int(val); + QPushButton *button = new QPushButton; + QLabel *colorLabel = new QLabel; + const char *name = obs_property_name(prop); + long long val = obs_data_get_int(settings, name); + QColor color = color_from_int(val); if (!obs_property_enabled(prop)) { button->setEnabled(false); @@ -657,8 +646,10 @@ void OBSPropertiesView::AddColor(obs_property_t *prop, QFormLayout *layout, colorLabel->setPalette(palette); colorLabel->setStyleSheet( QString("background-color :%1; color: %2;") - .arg(palette.color(QPalette::Window).name(QColor::HexArgb)) - .arg(palette.color(QPalette::WindowText).name(QColor::HexArgb))); + .arg(palette.color(QPalette::Window) + .name(QColor::HexArgb)) + .arg(palette.color(QPalette::WindowText) + .name(QColor::HexArgb))); colorLabel->setAutoFillBackground(true); colorLabel->setAlignment(Qt::AlignCenter); colorLabel->setToolTip(QT_UTF8(obs_property_long_description(prop))); @@ -679,10 +670,10 @@ void OBSPropertiesView::AddColor(obs_property_t *prop, QFormLayout *layout, static void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false) { - const char *face = obs_data_get_string(font_obj, "face"); + const char *face = obs_data_get_string(font_obj, "face"); const char *style = obs_data_get_string(font_obj, "style"); - int size = (int)obs_data_get_int(font_obj, "size"); - uint32_t flags = (uint32_t)obs_data_get_int(font_obj, "flags"); + int size = (int)obs_data_get_int(font_obj, "size"); + uint32_t flags = (uint32_t)obs_data_get_int(font_obj, "flags"); if (face) { font.setFamily(face); @@ -692,28 +683,34 @@ static void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false) if (size) { if (limit) { int max_size = font.pointSize(); - if (max_size < 28) max_size = 28; - if (size > max_size) size = max_size; + if (max_size < 28) + max_size = 28; + if (size > max_size) + size = max_size; } font.setPointSize(size); } - if (flags & OBS_FONT_BOLD) font.setBold(true); - if (flags & OBS_FONT_ITALIC) font.setItalic(true); - if (flags & OBS_FONT_UNDERLINE) font.setUnderline(true); - if (flags & OBS_FONT_STRIKEOUT) font.setStrikeOut(true); + if (flags & OBS_FONT_BOLD) + font.setBold(true); + if (flags & OBS_FONT_ITALIC) + font.setItalic(true); + if (flags & OBS_FONT_UNDERLINE) + font.setUnderline(true); + if (flags & OBS_FONT_STRIKEOUT) + font.setStrikeOut(true); } void OBSPropertiesView::AddFont(obs_property_t *prop, QFormLayout *layout, - QLabel *&label) + QLabel *&label) { - const char *name = obs_property_name(prop); - obs_data_t *font_obj = obs_data_get_obj(settings, name); - const char *face = obs_data_get_string(font_obj, "face"); - const char *style = obs_data_get_string(font_obj, "style"); - QPushButton *button = new QPushButton; - QLabel *fontLabel = new QLabel; - QFont font; + const char *name = obs_property_name(prop); + obs_data_t *font_obj = obs_data_get_obj(settings, name); + const char *face = obs_data_get_string(font_obj, "face"); + const char *style = obs_data_get_string(font_obj, "style"); + QPushButton *button = new QPushButton; + QLabel *fontLabel = new QLabel; + QFont font; if (!obs_property_enabled(prop)) { button->setEnabled(false); @@ -751,35 +748,26 @@ void OBSPropertiesView::AddFont(obs_property_t *prop, QFormLayout *layout, namespace std { -template <> -struct default_delete { - void operator()(obs_data_t *data) - { - obs_data_release(data); - } +template<> struct default_delete { + void operator()(obs_data_t *data) { obs_data_release(data); } }; -template <> -struct default_delete { - void operator()(obs_data_item_t *item) - { - obs_data_item_release(&item); - } +template<> struct default_delete { + void operator()(obs_data_item_t *item) { obs_data_item_release(&item); } }; } -template -static double make_epsilon(T val) +template static double make_epsilon(T val) { return val * 0.00001; } static bool matches_range(media_frames_per_second &match, - media_frames_per_second fps, - const frame_rate_range_t &pair) + media_frames_per_second fps, + const frame_rate_range_t &pair) { - auto val = media_frames_per_second_to_frame_interval(fps); + auto val = media_frames_per_second_to_frame_interval(fps); auto max_ = media_frames_per_second_to_frame_interval(pair.first); auto min_ = media_frames_per_second_to_frame_interval(pair.second); @@ -792,8 +780,9 @@ static bool matches_range(media_frames_per_second &match, } static bool matches_ranges(media_frames_per_second &best_match, - media_frames_per_second fps, - const frame_rate_ranges_t &fps_ranges, bool exact=false) + media_frames_per_second fps, + const frame_rate_ranges_t &fps_ranges, + bool exact = false) { auto convert_fn = media_frames_per_second_to_frame_interval; auto val = convert_fn(fps); @@ -830,7 +819,6 @@ static bool matches_ranges(media_frames_per_second &best_match, match = true; continue; } - } return match; @@ -845,19 +833,13 @@ static media_frames_per_second make_fps(uint32_t num, uint32_t den) } static const common_frame_rate common_fps[] = { - {"60", {60, 1}}, - {"59.94", {60000, 1001}}, - {"50", {50, 1}}, - {"48", {48, 1}}, - {"30", {30, 1}}, - {"29.97", {30000, 1001}}, - {"25", {25, 1}}, - {"24", {24, 1}}, - {"23.976", {24000, 1001}}, + {"60", {60, 1}}, {"59.94", {60000, 1001}}, {"50", {50, 1}}, + {"48", {48, 1}}, {"30", {30, 1}}, {"29.97", {30000, 1001}}, + {"25", {25, 1}}, {"24", {24, 1}}, {"23.976", {24000, 1001}}, }; static void UpdateSimpleFPSSelection(OBSFrameRatePropertyWidget *fpsProps, - const media_frames_per_second *current_fps) + const media_frames_per_second *current_fps) { if (!current_fps || !media_frames_per_second_is_valid(*current_fps)) { fpsProps->simpleFPS->setCurrentIndex(0); @@ -883,14 +865,13 @@ static void UpdateSimpleFPSSelection(OBSFrameRatePropertyWidget *fpsProps, } static void AddFPSRanges(vector &items, - const frame_rate_ranges_t &ranges) + const frame_rate_ranges_t &ranges) { - auto InsertFPS = [&](media_frames_per_second fps) - { + auto InsertFPS = [&](media_frames_per_second fps) { auto fps_val = media_frames_per_second_to_fps(fps); auto end_ = end(items); - auto i = begin(items); + auto i = begin(items); for (; i != end_; i++) { auto i_fps_val = media_frames_per_second_to_fps(i->fps); if (fabsl(i_fps_val - fps_val) < 0.01) @@ -911,8 +892,9 @@ static void AddFPSRanges(vector &items, } } -static QWidget *CreateSimpleFPSValues(OBSFrameRatePropertyWidget *fpsProps, - bool &selected, const media_frames_per_second *current_fps) +static QWidget * +CreateSimpleFPSValues(OBSFrameRatePropertyWidget *fpsProps, bool &selected, + const media_frames_per_second *current_fps) { auto widget = new QWidget{}; widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -921,7 +903,7 @@ static QWidget *CreateSimpleFPSValues(OBSFrameRatePropertyWidget *fpsProps, layout->setContentsMargins(0, 0, 0, 0); auto items = vector{}; - items.reserve(sizeof(common_fps)/sizeof(common_frame_rate)); + items.reserve(sizeof(common_fps) / sizeof(common_frame_rate)); auto combo = fpsProps->simpleFPS = new ComboBoxIgnoreScroll{}; @@ -938,10 +920,11 @@ static QWidget *CreateSimpleFPSValues(OBSFrameRatePropertyWidget *fpsProps, for (const auto &item : items) { auto var = QVariant::fromValue(item.fps); - auto name = item.fps_name ? - QString(item.fps_name) : - QString("%1") - .arg(media_frames_per_second_to_fps(item.fps)); + auto name = item.fps_name + ? QString(item.fps_name) + : QString("%1").arg( + media_frames_per_second_to_fps( + item.fps)); combo->addItem(name, var); bool select = current_fps && *current_fps == item.fps; @@ -958,7 +941,7 @@ static QWidget *CreateSimpleFPSValues(OBSFrameRatePropertyWidget *fpsProps, } static void UpdateRationalFPSWidgets(OBSFrameRatePropertyWidget *fpsProps, - const media_frames_per_second *current_fps) + const media_frames_per_second *current_fps) { if (!current_fps || !media_frames_per_second_is_valid(*current_fps)) { fpsProps->numEdit->setValue(0); @@ -979,7 +962,7 @@ static void UpdateRationalFPSWidgets(OBSFrameRatePropertyWidget *fpsProps, media_frames_per_second match{}; if (!matches_range(match, *current_fps, - fpsProps->fps_ranges[idx])) + fpsProps->fps_ranges[idx])) continue; combo->setCurrentIndex(i); @@ -991,7 +974,8 @@ static void UpdateRationalFPSWidgets(OBSFrameRatePropertyWidget *fpsProps, } static QWidget *CreateRationalFPS(OBSFrameRatePropertyWidget *fpsProps, - bool &selected, const media_frames_per_second *current_fps) + bool &selected, + const media_frames_per_second *current_fps) { auto widget = new QWidget{}; widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -1007,12 +991,12 @@ static QWidget *CreateRationalFPS(OBSFrameRatePropertyWidget *fpsProps, auto convert_fps = media_frames_per_second_to_fps; //auto convert_fi = media_frames_per_second_to_frame_interval; - for (size_t i = 0; i < fpsProps->fps_ranges.size(); i++) { + for (size_t i = 0; i < fpsProps->fps_ranges.size(); i++) { auto &pair = fpsProps->fps_ranges[i]; combo->addItem(QString{"%1 - %2"} - .arg(convert_fps(pair.first)) - .arg(convert_fps(pair.second)), - QVariant::fromValue(i)); + .arg(convert_fps(pair.first)) + .arg(convert_fps(pair.second)), + QVariant::fromValue(i)); media_frames_per_second match; if (!current_fps || !matches_range(match, *current_fps, pair)) @@ -1043,12 +1027,12 @@ static QWidget *CreateRationalFPS(OBSFrameRatePropertyWidget *fpsProps, return widget; } -static OBSFrameRatePropertyWidget *CreateFrameRateWidget(obs_property_t *prop, - bool &warning, const char *option, - media_frames_per_second *current_fps, - frame_rate_ranges_t &fps_ranges) +static OBSFrameRatePropertyWidget * +CreateFrameRateWidget(obs_property_t *prop, bool &warning, const char *option, + media_frames_per_second *current_fps, + frame_rate_ranges_t &fps_ranges) { - auto widget = new OBSFrameRatePropertyWidget{}; + auto widget = new OBSFrameRatePropertyWidget{}; auto hlayout = new QHBoxLayout{}; hlayout->setContentsMargins(0, 0, 0, 0); @@ -1056,9 +1040,9 @@ static OBSFrameRatePropertyWidget *CreateFrameRateWidget(obs_property_t *prop, auto combo = widget->modeSelect = new ComboBoxIgnoreScroll{}; combo->addItem(QTStr("Basic.PropertiesView.FPS.Simple"), - QVariant::fromValue(frame_rate_tag::simple())); + QVariant::fromValue(frame_rate_tag::simple())); combo->addItem(QTStr("Basic.PropertiesView.FPS.Rational"), - QVariant::fromValue(frame_rate_tag::rational())); + QVariant::fromValue(frame_rate_tag::rational())); combo->setToolTip(QT_UTF8(obs_property_long_description(prop))); @@ -1084,8 +1068,7 @@ static OBSFrameRatePropertyWidget *CreateFrameRateWidget(obs_property_t *prop, auto stack = widget->modeDisplay = new QStackedWidget{}; bool match_found = option_found; - auto AddWidget = [&](decltype(CreateRationalFPS) func) - { + auto AddWidget = [&](decltype(CreateRationalFPS) func) { bool selected = false; stack->addWidget(func(widget, selected, current_fps)); @@ -1106,7 +1089,7 @@ static OBSFrameRatePropertyWidget *CreateFrameRateWidget(obs_property_t *prop, stack->setCurrentIndex(stack->count() - 1); else if (!match_found) { int idx = current_fps ? 1 : 0; // Rational for "unsupported" - // Simple as default + // Simple as default stack->setCurrentIndex(idx); combo->setCurrentIndex(idx); warning = true; @@ -1116,7 +1099,7 @@ static OBSFrameRatePropertyWidget *CreateFrameRateWidget(obs_property_t *prop, auto label_area = widget->labels = new QWidget{}; label_area->setSizePolicy(QSizePolicy::Expanding, - QSizePolicy::Expanding); + QSizePolicy::Expanding); auto vlayout = new QVBoxLayout{}; vlayout->setContentsMargins(0, 0, 0, 0); @@ -1149,16 +1132,14 @@ static OBSFrameRatePropertyWidget *CreateFrameRateWidget(obs_property_t *prop, static void UpdateMinMaxLabels(OBSFrameRatePropertyWidget *w) { - auto Hide = [&](bool hide) - { + auto Hide = [&](bool hide) { w->minLabel->setHidden(hide); w->maxLabel->setHidden(hide); }; auto variant = w->modeSelect->currentData(); if (!variant.canConvert() || - variant.value().type != - frame_rate_tag::RATIONAL) { + variant.value().type != frame_rate_tag::RATIONAL) { Hide(true); return; } @@ -1181,11 +1162,11 @@ static void UpdateMinMaxLabels(OBSFrameRatePropertyWidget *w) auto max = w->fps_ranges[idx].second; w->minLabel->setText(QString("Min FPS: %1/%2") - .arg(min.numerator) - .arg(min.denominator)); + .arg(min.numerator) + .arg(min.denominator)); w->maxLabel->setText(QString("Max FPS: %1/%2") - .arg(max.numerator) - .arg(max.denominator)); + .arg(max.numerator) + .arg(max.denominator)); } static void UpdateFPSLabels(OBSFrameRatePropertyWidget *w) @@ -1198,9 +1179,8 @@ static void UpdateFPSLabels(OBSFrameRatePropertyWidget *w) media_frames_per_second fps{}; media_frames_per_second *valid_fps = nullptr; if (obs_data_item_get_autoselect_frames_per_second(obj.get(), &fps, - nullptr) || - obs_data_item_get_frames_per_second(obj.get(), &fps, - nullptr)) + nullptr) || + obs_data_item_get_frames_per_second(obj.get(), &fps, nullptr)) valid_fps = &fps; const char *option = nullptr; @@ -1211,7 +1191,7 @@ static void UpdateFPSLabels(OBSFrameRatePropertyWidget *w) w->timePerFrame->setHidden(true); if (!option) w->warningLabel->setStyleSheet( - "QLabel { color: red; }"); + "QLabel { color: red; }"); return; } @@ -1229,14 +1209,15 @@ static void UpdateFPSLabels(OBSFrameRatePropertyWidget *w) auto convert_to_frame_interval = media_frames_per_second_to_frame_interval; - w->currentFPS->setText(QString("FPS: %1") - .arg(convert_to_fps(*valid_fps))); - w->timePerFrame->setText(QString("Frame Interval: %1 ms") + w->currentFPS->setText( + QString("FPS: %1").arg(convert_to_fps(*valid_fps))); + w->timePerFrame->setText( + QString("Frame Interval: %1 ms") .arg(convert_to_frame_interval(*valid_fps) * 1000)); } void OBSPropertiesView::AddFrameRate(obs_property_t *prop, bool &warning, - QFormLayout *layout, QLabel *&label) + QFormLayout *layout, QLabel *&label) { const char *name = obs_property_name(prop); bool enabled = obs_property_enabled(prop); @@ -1255,12 +1236,12 @@ void OBSPropertiesView::AddFrameRate(obs_property_t *prop, bool &warning, fps_ranges.reserve(num); for (size_t i = 0; i < num; i++) fps_ranges.emplace_back( - obs_property_frame_rate_fps_range_min(prop, i), - obs_property_frame_rate_fps_range_max(prop, i)); + obs_property_frame_rate_fps_range_min(prop, i), + obs_property_frame_rate_fps_range_max(prop, i)); auto widget = CreateFrameRateWidget(prop, warning, option, valid_fps, - fps_ranges); - auto info = new WidgetInfo(this, prop, widget); + fps_ranges); + auto info = new WidgetInfo(this, prop, widget); widget->setToolTip(QT_UTF8(obs_property_long_description(prop))); @@ -1289,10 +1270,8 @@ void OBSPropertiesView::AddFrameRate(obs_property_t *prop, bool &warning, combo->setToolTip(QT_UTF8(obs_property_long_description(prop))); auto comboIndexChanged = static_cast( - &QComboBox::currentIndexChanged); - connect(combo, comboIndexChanged, stack, - [=](int index) - { + &QComboBox::currentIndexChanged); + connect(combo, comboIndexChanged, stack, [=](int index) { bool out_of_bounds = index >= stack->count(); auto idx = out_of_bounds ? stack->count() - 1 : index; stack->setCurrentIndex(idx); @@ -1304,34 +1283,30 @@ void OBSPropertiesView::AddFrameRate(obs_property_t *prop, bool &warning, emit info->ControlChanged(); }); - connect(widget->simpleFPS, comboIndexChanged, [=](int) - { + connect(widget->simpleFPS, comboIndexChanged, [=](int) { if (widget->updating) return; emit info->ControlChanged(); }); - connect(widget->fpsRange, comboIndexChanged, [=](int) - { + connect(widget->fpsRange, comboIndexChanged, [=](int) { if (widget->updating) return; UpdateFPSLabels(widget); }); - auto sbValueChanged = static_cast( - &QSpinBox::valueChanged); - connect(widget->numEdit, sbValueChanged, [=](int) - { + auto sbValueChanged = + static_cast(&QSpinBox::valueChanged); + connect(widget->numEdit, sbValueChanged, [=](int) { if (widget->updating) return; emit info->ControlChanged(); }); - connect(widget->denEdit, sbValueChanged, [=](int) - { + connect(widget->denEdit, sbValueChanged, [=](int) { if (widget->updating) return; @@ -1367,28 +1342,28 @@ void OBSPropertiesView::AddGroup(obs_property_t *prop, QFormLayout *layout) // Insert into UI layout->setWidget(layout->rowCount(), - QFormLayout::ItemRole::SpanningRole, groupBox); + QFormLayout::ItemRole::SpanningRole, groupBox); // Register Group Widget WidgetInfo *info = new WidgetInfo(this, prop, groupBox); children.emplace_back(info); // Signals - connect(groupBox, SIGNAL(toggled()), info, SLOT(ControlChanged())); + connect(groupBox, SIGNAL(toggled(bool)), info, SLOT(ControlChanged())); } void OBSPropertiesView::AddProperty(obs_property_t *property, - QFormLayout *layout) + QFormLayout *layout) { - const char *name = obs_property_name(property); - obs_property_type type = obs_property_get_type(property); + const char *name = obs_property_name(property); + obs_property_type type = obs_property_get_type(property); if (!obs_property_visible(property)) return; - QLabel *label = nullptr; + QLabel *label = nullptr; QWidget *widget = nullptr; - bool warning = false; + bool warning = false; switch (type) { case OBS_PROPERTY_INVALID: @@ -1433,10 +1408,8 @@ void OBSPropertiesView::AddProperty(obs_property_t *property, if (widget && !obs_property_enabled(property)) widget->setEnabled(false); - if (!label && - type != OBS_PROPERTY_BOOL && - type != OBS_PROPERTY_BUTTON && - type != OBS_PROPERTY_GROUP) + if (!label && type != OBS_PROPERTY_BOOL && + type != OBS_PROPERTY_BUTTON && type != OBS_PROPERTY_GROUP) label = new QLabel(QT_UTF8(obs_property_description(property))); if (warning && label) //TODO: select color based on background color @@ -1466,8 +1439,9 @@ void OBSPropertiesView::SignalChanged() } static bool FrameRateChangedVariant(const QVariant &variant, - media_frames_per_second &fps, obs_data_item_t *&obj, - const media_frames_per_second *valid_fps) + media_frames_per_second &fps, + obs_data_item_t *&obj, + const media_frames_per_second *valid_fps) { if (!variant.canConvert()) return false; @@ -1481,11 +1455,12 @@ static bool FrameRateChangedVariant(const QVariant &variant, } static bool FrameRateChangedCommon(OBSFrameRatePropertyWidget *w, - obs_data_item_t *&obj, const media_frames_per_second *valid_fps) + obs_data_item_t *&obj, + const media_frames_per_second *valid_fps) { media_frames_per_second fps{}; if (!FrameRateChangedVariant(w->simpleFPS->currentData(), fps, obj, - valid_fps)) + valid_fps)) return false; UpdateRationalFPSWidgets(w, &fps); @@ -1493,14 +1468,15 @@ static bool FrameRateChangedCommon(OBSFrameRatePropertyWidget *w, } static bool FrameRateChangedRational(OBSFrameRatePropertyWidget *w, - obs_data_item_t *&obj, const media_frames_per_second *valid_fps) + obs_data_item_t *&obj, + const media_frames_per_second *valid_fps) { auto num = w->numEdit->value(); auto den = w->denEdit->value(); auto fps = make_fps(num, den); if (valid_fps && media_frames_per_second_is_valid(fps) && - fps == *valid_fps) + fps == *valid_fps) return false; obs_data_item_set_frames_per_second(&obj, fps, nullptr); @@ -1509,9 +1485,9 @@ static bool FrameRateChangedRational(OBSFrameRatePropertyWidget *w, } static bool FrameRateChanged(QWidget *widget, const char *name, - OBSData &settings) + OBSData &settings) { - auto w = qobject_cast(widget); + auto w = qobject_cast(widget); if (!w) return false; @@ -1519,12 +1495,9 @@ static bool FrameRateChanged(QWidget *widget, const char *name, if (!variant.canConvert()) return false; - auto StopUpdating = [&](void*) - { - w->updating = false; - }; + auto StopUpdating = [&](void *) { w->updating = false; }; unique_ptr signalGuard( - static_cast(w), StopUpdating); + static_cast(w), StopUpdating); w->updating = true; if (!obs_data_has_user_value(settings, name)) @@ -1532,12 +1505,11 @@ static bool FrameRateChanged(QWidget *widget, const char *name, unique_ptr obj{obs_data_item_byname(settings, name)}; auto obj_ptr = obj.get(); - auto CheckObj = [&]() - { + auto CheckObj = [&]() { if (!obj_ptr) obj.release(); }; - + const char *option = nullptr; obs_data_item_get_frames_per_second(obj.get(), nullptr, &option); @@ -1573,64 +1545,64 @@ static bool FrameRateChanged(QWidget *widget, const char *name, void WidgetInfo::BoolChanged(const char *setting) { - QCheckBox *checkbox = static_cast(widget); + QCheckBox *checkbox = static_cast(widget); obs_data_set_bool(view->settings, setting, - checkbox->checkState() == Qt::Checked); + checkbox->checkState() == Qt::Checked); } void WidgetInfo::IntChanged(const char *setting) { - QSpinBox *spin = static_cast(widget); + QSpinBox *spin = static_cast(widget); obs_data_set_int(view->settings, setting, spin->value()); } void WidgetInfo::FloatChanged(const char *setting) { - QDoubleSpinBox *spin = static_cast(widget); + QDoubleSpinBox *spin = static_cast(widget); obs_data_set_double(view->settings, setting, spin->value()); } void WidgetInfo::TextChanged(const char *setting) { - obs_text_type type = obs_property_text_type(property); + obs_text_type type = obs_property_text_type(property); if (type == OBS_TEXT_MULTILINE) { - QPlainTextEdit *edit = static_cast(widget); + QPlainTextEdit *edit = static_cast(widget); obs_data_set_string(view->settings, setting, - QT_TO_UTF8(edit->toPlainText())); + QT_TO_UTF8(edit->toPlainText())); return; } - QLineEdit *edit = static_cast(widget); + QLineEdit *edit = static_cast(widget); obs_data_set_string(view->settings, setting, QT_TO_UTF8(edit->text())); } bool WidgetInfo::PathChanged(const char *setting) { - const char *desc = obs_property_description(property); - obs_path_type type = obs_property_path_type(property); - const char *filter = obs_property_path_filter(property); - const char *default_path = obs_property_path_default_path(property); - QString path; + const char *desc = obs_property_description(property); + obs_path_type type = obs_property_path_type(property); + const char *filter = obs_property_path_filter(property); + const char *default_path = obs_property_path_default_path(property); + QString path; if (type == OBS_PATH_DIRECTORY) - path = QFileDialog::getExistingDirectory(view, - QT_UTF8(desc), QT_UTF8(default_path), - QFileDialog::ShowDirsOnly | + path = QFileDialog::getExistingDirectory( + view, QT_UTF8(desc), QT_UTF8(default_path), + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); else if (type == OBS_PATH_FILE) - path = QFileDialog::getOpenFileName(view, - QT_UTF8(desc), QT_UTF8(default_path), - QT_UTF8(filter)); + path = QFileDialog::getOpenFileName(view, QT_UTF8(desc), + QT_UTF8(default_path), + QT_UTF8(filter)); else if (type == OBS_PATH_FILE_SAVE) - path = QFileDialog::getSaveFileName(view, - QT_UTF8(desc), QT_UTF8(default_path), - QT_UTF8(filter)); + path = QFileDialog::getSaveFileName(view, QT_UTF8(desc), + QT_UTF8(default_path), + QT_UTF8(filter)); if (path.isEmpty()) return false; - QLineEdit *edit = static_cast(widget); + QLineEdit *edit = static_cast(widget); edit->setText(path); obs_data_set_string(view->settings, setting, QT_TO_UTF8(path)); return true; @@ -1638,10 +1610,10 @@ bool WidgetInfo::PathChanged(const char *setting) void WidgetInfo::ListChanged(const char *setting) { - QComboBox *combo = static_cast(widget); + QComboBox *combo = static_cast(widget); obs_combo_format format = obs_property_list_format(property); - obs_combo_type type = obs_property_list_type(property); - QVariant data; + obs_combo_type type = obs_property_list_type(property); + QVariant data; if (type == OBS_COMBO_TYPE_EDITABLE) { data = combo->currentText().toUtf8(); @@ -1658,15 +1630,15 @@ void WidgetInfo::ListChanged(const char *setting) return; case OBS_COMBO_FORMAT_INT: obs_data_set_int(view->settings, setting, - data.value()); + data.value()); break; case OBS_COMBO_FORMAT_FLOAT: obs_data_set_double(view->settings, setting, - data.value()); + data.value()); break; case OBS_COMBO_FORMAT_STRING: obs_data_set_string(view->settings, setting, - data.toByteArray().constData()); + data.toByteArray().constData()); break; } } @@ -1674,8 +1646,8 @@ void WidgetInfo::ListChanged(const char *setting) bool WidgetInfo::ColorChanged(const char *setting) { const char *desc = obs_property_description(property); - long long val = obs_data_get_int(view->settings, setting); - QColor color = color_from_int(val); + long long val = obs_data_get_int(view->settings, setting); + QColor color = color_from_int(val); QColorDialog::ColorDialogOptions options = 0; @@ -1693,14 +1665,15 @@ bool WidgetInfo::ColorChanged(const char *setting) if (!color.isValid()) return false; - QLabel *label = static_cast(widget); + QLabel *label = static_cast(widget); label->setText(color.name(QColor::HexArgb)); QPalette palette = QPalette(color); label->setPalette(palette); - label->setStyleSheet( - QString("background-color :%1; color: %2;") - .arg(palette.color(QPalette::Window).name(QColor::HexArgb)) - .arg(palette.color(QPalette::WindowText).name(QColor::HexArgb))); + label->setStyleSheet(QString("background-color :%1; color: %2;") + .arg(palette.color(QPalette::Window) + .name(QColor::HexArgb)) + .arg(palette.color(QPalette::WindowText) + .name(QColor::HexArgb))); obs_data_set_int(view->settings, setting, color_to_int(color)); @@ -1710,9 +1683,9 @@ bool WidgetInfo::ColorChanged(const char *setting) bool WidgetInfo::FontChanged(const char *setting) { obs_data_t *font_obj = obs_data_get_obj(view->settings, setting); - bool success; - uint32_t flags; - QFont font; + bool success; + uint32_t flags; + QFont font; QFontDialog::FontDialogOptions options; @@ -1722,10 +1695,12 @@ bool WidgetInfo::FontChanged(const char *setting) if (!font_obj) { QFont initial; - font = QFontDialog::getFont(&success, initial, view, "Pick a Font", options); + font = QFontDialog::getFont(&success, initial, view, + "Pick a Font", options); } else { MakeQFont(font_obj, font); - font = QFontDialog::getFont(&success, font, view, "Pick a Font", options); + font = QFontDialog::getFont(&success, font, view, "Pick a Font", + options); obs_data_release(font_obj); } @@ -1737,13 +1712,13 @@ bool WidgetInfo::FontChanged(const char *setting) obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family())); obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName())); obs_data_set_int(font_obj, "size", font.pointSize()); - flags = font.bold() ? OBS_FONT_BOLD : 0; + flags = font.bold() ? OBS_FONT_BOLD : 0; flags |= font.italic() ? OBS_FONT_ITALIC : 0; flags |= font.underline() ? OBS_FONT_UNDERLINE : 0; flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0; obs_data_set_int(font_obj, "flags", flags); - QLabel *label = static_cast(widget); + QLabel *label = static_cast(widget); QFont labelFont; MakeQFont(font_obj, labelFont, true); label->setFont(labelFont); @@ -1756,26 +1731,25 @@ bool WidgetInfo::FontChanged(const char *setting) void WidgetInfo::GroupChanged(const char *setting) { - QGroupBox *groupbox = static_cast(widget); + QGroupBox *groupbox = static_cast(widget); obs_data_set_bool(view->settings, setting, - groupbox->isCheckable() ? groupbox->isChecked() : true); + groupbox->isCheckable() ? groupbox->isChecked() + : true); } void WidgetInfo::EditableListChanged() { const char *setting = obs_property_name(property); - QListWidget *list = reinterpret_cast(widget); + QListWidget *list = reinterpret_cast(widget); obs_data_array *array = obs_data_array_create(); for (int i = 0; i < list->count(); i++) { QListWidgetItem *item = list->item(i); obs_data_t *arrayItem = obs_data_create(); obs_data_set_string(arrayItem, "value", - QT_TO_UTF8(item->text())); - obs_data_set_bool(arrayItem, "selected", - item->isSelected()); - obs_data_set_bool(arrayItem, "hidden", - item->isHidden()); + QT_TO_UTF8(item->text())); + obs_data_set_bool(arrayItem, "selected", item->isSelected()); + obs_data_set_bool(arrayItem, "hidden", item->isHidden()); obs_data_array_push_back(array, arrayItem); obs_data_release(arrayItem); } @@ -1790,29 +1764,42 @@ void WidgetInfo::ButtonClicked() { if (obs_property_button_clicked(property, view->obj)) { QMetaObject::invokeMethod(view, "RefreshProperties", - Qt::QueuedConnection); + Qt::QueuedConnection); } } void WidgetInfo::TogglePasswordText(bool show) { - reinterpret_cast(widget)->setEchoMode( - show ? QLineEdit::Normal : QLineEdit::Password); + reinterpret_cast(widget)->setEchoMode( + show ? QLineEdit::Normal : QLineEdit::Password); } void WidgetInfo::ControlChanged() { - const char *setting = obs_property_name(property); - obs_property_type type = obs_property_get_type(property); + const char *setting = obs_property_name(property); + obs_property_type type = obs_property_get_type(property); switch (type) { - case OBS_PROPERTY_INVALID: return; - case OBS_PROPERTY_BOOL: BoolChanged(setting); break; - case OBS_PROPERTY_INT: IntChanged(setting); break; - case OBS_PROPERTY_FLOAT: FloatChanged(setting); break; - case OBS_PROPERTY_TEXT: TextChanged(setting); break; - case OBS_PROPERTY_LIST: ListChanged(setting); break; - case OBS_PROPERTY_BUTTON: ButtonClicked(); return; + case OBS_PROPERTY_INVALID: + return; + case OBS_PROPERTY_BOOL: + BoolChanged(setting); + break; + case OBS_PROPERTY_INT: + IntChanged(setting); + break; + case OBS_PROPERTY_FLOAT: + FloatChanged(setting); + break; + case OBS_PROPERTY_TEXT: + TextChanged(setting); + break; + case OBS_PROPERTY_LIST: + ListChanged(setting); + break; + case OBS_PROPERTY_BUTTON: + ButtonClicked(); + return; case OBS_PROPERTY_COLOR: if (!ColorChanged(setting)) return; @@ -1825,12 +1812,15 @@ void WidgetInfo::ControlChanged() if (!PathChanged(setting)) return; break; - case OBS_PROPERTY_EDITABLE_LIST: break; + case OBS_PROPERTY_EDITABLE_LIST: + break; case OBS_PROPERTY_FRAME_RATE: if (!FrameRateChanged(widget, setting, view->settings)) return; break; - case OBS_PROPERTY_GROUP: GroupChanged(setting); return; + case OBS_PROPERTY_GROUP: + GroupChanged(setting); + return; } if (view->callback && !view->deferUpdate) @@ -1841,7 +1831,7 @@ void WidgetInfo::ControlChanged() if (obs_property_modified(property, view->settings)) { view->lastFocused = setting; QMetaObject::invokeMethod(view, "RefreshProperties", - Qt::QueuedConnection); + Qt::QueuedConnection); } } @@ -1858,8 +1848,8 @@ class EditableItemDialog : public QDialog { curPath = default_path; QString path = QFileDialog::getOpenFileName( - App()->GetMainWindow(), QTStr("Browse"), - curPath, filter); + App()->GetMainWindow(), QTStr("Browse"), curPath, + filter); if (path.isEmpty()) return; @@ -1867,12 +1857,12 @@ class EditableItemDialog : public QDialog { } public: - EditableItemDialog(QWidget *parent, const QString &text, - bool browse, const char *filter_ = nullptr, - const char *default_path_ = nullptr) - : QDialog (parent), - filter (QT_UTF8(filter_)), - default_path (QT_UTF8(default_path_)) + EditableItemDialog(QWidget *parent, const QString &text, bool browse, + const char *filter_ = nullptr, + const char *default_path_ = nullptr) + : QDialog(parent), + filter(QT_UTF8(filter_)), + default_path(QT_UTF8(default_path_)) { QHBoxLayout *topLayout = new QHBoxLayout(); QVBoxLayout *mainLayout = new QVBoxLayout(); @@ -1890,12 +1880,11 @@ public: topLayout->setAlignment(browseButton, Qt::AlignVCenter); connect(browseButton, &QPushButton::clicked, this, - &EditableItemDialog::BrowseClicked); + &EditableItemDialog::BrowseClicked); } QDialogButtonBox::StandardButtons buttons = - QDialogButtonBox::Ok | - QDialogButtonBox::Cancel; + QDialogButtonBox::Ok | QDialogButtonBox::Cancel; QDialogButtonBox *buttonBox = new QDialogButtonBox(buttons); buttonBox->setCenterButtons(true); @@ -1910,13 +1899,13 @@ public: connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); } - inline QString GetText() const {return edit->text();} + inline QString GetText() const { return edit->text(); } }; void WidgetInfo::EditListAdd() { - enum obs_editable_list_type type = obs_property_editable_list_type( - property); + enum obs_editable_list_type type = + obs_property_editable_list_type(property); if (type == OBS_EDITABLE_LIST_TYPE_STRINGS) { EditListAddText(); @@ -1929,20 +1918,19 @@ void WidgetInfo::EditListAdd() QAction *action; action = new QAction(QTStr("Basic.PropertiesWindow.AddFiles"), this); - connect(action, &QAction::triggered, - this, &WidgetInfo::EditListAddFiles); + connect(action, &QAction::triggered, this, + &WidgetInfo::EditListAddFiles); popup.addAction(action); action = new QAction(QTStr("Basic.PropertiesWindow.AddDir"), this); - connect(action, &QAction::triggered, - this, &WidgetInfo::EditListAddDir); + connect(action, &QAction::triggered, this, &WidgetInfo::EditListAddDir); popup.addAction(action); if (type == OBS_EDITABLE_LIST_TYPE_FILES_AND_URLS) { action = new QAction(QTStr("Basic.PropertiesWindow.AddURL"), - this); - connect(action, &QAction::triggered, - this, &WidgetInfo::EditListAddText); + this); + connect(action, &QAction::triggered, this, + &WidgetInfo::EditListAddText); popup.addAction(action); } @@ -1951,12 +1939,12 @@ void WidgetInfo::EditListAdd() void WidgetInfo::EditListAddText() { - QListWidget *list = reinterpret_cast(widget); + QListWidget *list = reinterpret_cast(widget); const char *desc = obs_property_description(property); EditableItemDialog dialog(widget->window(), QString(), false); - auto title = QTStr("Basic.PropertiesWindow.AddEditableListEntry").arg( - QT_UTF8(desc)); + auto title = QTStr("Basic.PropertiesWindow.AddEditableListEntry") + .arg(QT_UTF8(desc)); dialog.setWindowTitle(title); if (dialog.exec() == QDialog::Rejected) return; @@ -1971,18 +1959,18 @@ void WidgetInfo::EditListAddText() void WidgetInfo::EditListAddFiles() { - QListWidget *list = reinterpret_cast(widget); + QListWidget *list = reinterpret_cast(widget); const char *desc = obs_property_description(property); const char *filter = obs_property_editable_list_filter(property); const char *default_path = obs_property_editable_list_default_path(property); QString title = QTStr("Basic.PropertiesWindow.AddEditableListFiles") - .arg(QT_UTF8(desc)); + .arg(QT_UTF8(desc)); QStringList files = QFileDialog::getOpenFileNames( - App()->GetMainWindow(), title, QT_UTF8(default_path), - QT_UTF8(filter)); + App()->GetMainWindow(), title, QT_UTF8(default_path), + QT_UTF8(filter)); if (files.count() == 0) return; @@ -1993,16 +1981,16 @@ void WidgetInfo::EditListAddFiles() void WidgetInfo::EditListAddDir() { - QListWidget *list = reinterpret_cast(widget); + QListWidget *list = reinterpret_cast(widget); const char *desc = obs_property_description(property); const char *default_path = obs_property_editable_list_default_path(property); QString title = QTStr("Basic.PropertiesWindow.AddEditableListDir") - .arg(QT_UTF8(desc)); + .arg(QT_UTF8(desc)); QString dir = QFileDialog::getExistingDirectory( - App()->GetMainWindow(), title, QT_UTF8(default_path)); + App()->GetMainWindow(), title, QT_UTF8(default_path)); if (dir.isEmpty()) return; @@ -2013,8 +2001,8 @@ void WidgetInfo::EditListAddDir() void WidgetInfo::EditListRemove() { - QListWidget *list = reinterpret_cast(widget); - QList items = list->selectedItems(); + QListWidget *list = reinterpret_cast(widget); + QList items = list->selectedItems(); for (QListWidgetItem *item : items) delete item; @@ -2023,12 +2011,12 @@ void WidgetInfo::EditListRemove() void WidgetInfo::EditListEdit() { - QListWidget *list = reinterpret_cast(widget); - enum obs_editable_list_type type = obs_property_editable_list_type( - property); + QListWidget *list = reinterpret_cast(widget); + enum obs_editable_list_type type = + obs_property_editable_list_type(property); const char *desc = obs_property_description(property); const char *filter = obs_property_editable_list_filter(property); - QList selectedItems = list->selectedItems(); + QList selectedItems = list->selectedItems(); if (!selectedItems.count()) return; @@ -2041,11 +2029,10 @@ void WidgetInfo::EditListEdit() if (pathDir.exists()) path = QFileDialog::getExistingDirectory( - App()->GetMainWindow(), - QTStr("Browse"), + App()->GetMainWindow(), QTStr("Browse"), item->text(), QFileDialog::ShowDirsOnly | - QFileDialog::DontResolveSymlinks); + QFileDialog::DontResolveSymlinks); else path = QFileDialog::getOpenFileName( App()->GetMainWindow(), QTStr("Browse"), @@ -2060,9 +2047,10 @@ void WidgetInfo::EditListEdit() } EditableItemDialog dialog(widget->window(), item->text(), - type != OBS_EDITABLE_LIST_TYPE_STRINGS, filter); - auto title = QTStr("Basic.PropertiesWindow.EditEditableListEntry").arg( - QT_UTF8(desc)); + type != OBS_EDITABLE_LIST_TYPE_STRINGS, + filter); + auto title = QTStr("Basic.PropertiesWindow.EditEditableListEntry") + .arg(QT_UTF8(desc)); dialog.setWindowTitle(title); if (dialog.exec() == QDialog::Rejected) return; @@ -2077,7 +2065,7 @@ void WidgetInfo::EditListEdit() void WidgetInfo::EditListUp() { - QListWidget *list = reinterpret_cast(widget); + QListWidget *list = reinterpret_cast(widget); int lastItemRow = -1; for (int i = 0; i < list->count(); i++) { @@ -2102,7 +2090,7 @@ void WidgetInfo::EditListUp() void WidgetInfo::EditListDown() { - QListWidget *list = reinterpret_cast(widget); + QListWidget *list = reinterpret_cast(widget); int lastItemRow = list->count(); for (int i = list->count() - 1; i >= 0; i--) { diff --git a/UI/properties-view.hpp b/UI/properties-view.hpp index ee9d255..892c454 100644 --- a/UI/properties-view.hpp +++ b/UI/properties-view.hpp @@ -10,8 +10,7 @@ class OBSPropertiesView; class QLabel; typedef obs_properties_t *(*PropertiesReloadCallback)(void *obj); -typedef void (*PropertiesUpdateCallback)(void *obj, - obs_data_t *settings); +typedef void (*PropertiesUpdateCallback)(void *obj, obs_data_t *settings); /* ------------------------------------------------------------------------- */ @@ -22,8 +21,8 @@ class WidgetInfo : public QObject { private: OBSPropertiesView *view; - obs_property_t *property; - QWidget *widget; + obs_property_t *property; + QWidget *widget; void BoolChanged(const char *setting); void IntChanged(const char *setting); @@ -41,9 +40,10 @@ private: public: inline WidgetInfo(OBSPropertiesView *view_, obs_property_t *prop, - QWidget *widget_) + QWidget *widget_) : view(view_), property(prop), widget(widget_) - {} + { + } public slots: @@ -72,37 +72,38 @@ class OBSPropertiesView : public VScrollArea { std::unique_ptr; private: - QWidget *widget = nullptr; - properties_t properties; - OBSData settings; - void *obj = nullptr; - std::string type; - PropertiesReloadCallback reloadCallback; - PropertiesUpdateCallback callback = nullptr; - int minSize; + QWidget *widget = nullptr; + properties_t properties; + OBSData settings; + void *obj = nullptr; + std::string type; + PropertiesReloadCallback reloadCallback; + PropertiesUpdateCallback callback = nullptr; + int minSize; std::vector> children; - std::string lastFocused; - QWidget *lastWidget = nullptr; - bool deferUpdate; + std::string lastFocused; + QWidget *lastWidget = nullptr; + bool deferUpdate; QWidget *NewWidget(obs_property_t *prop, QWidget *widget, - const char *signal); + const char *signal); QWidget *AddCheckbox(obs_property_t *prop); QWidget *AddText(obs_property_t *prop, QFormLayout *layout, - QLabel *&label); + QLabel *&label); void AddPath(obs_property_t *prop, QFormLayout *layout, QLabel **label); void AddInt(obs_property_t *prop, QFormLayout *layout, QLabel **label); void AddFloat(obs_property_t *prop, QFormLayout *layout, - QLabel**label); + QLabel **label); QWidget *AddList(obs_property_t *prop, bool &warning); void AddEditableList(obs_property_t *prop, QFormLayout *layout, - QLabel *&label); + QLabel *&label); QWidget *AddButton(obs_property_t *prop); - void AddColor(obs_property_t *prop, QFormLayout *layout, QLabel *&label); + void AddColor(obs_property_t *prop, QFormLayout *layout, + QLabel *&label); void AddFont(obs_property_t *prop, QFormLayout *layout, QLabel *&label); void AddFrameRate(obs_property_t *prop, bool &warning, - QFormLayout *layout, QLabel *&label); + QFormLayout *layout, QLabel *&label); void AddGroup(obs_property_t *prop, QFormLayout *layout); @@ -125,15 +126,14 @@ signals: public: OBSPropertiesView(OBSData settings, void *obj, - PropertiesReloadCallback reloadCallback, - PropertiesUpdateCallback callback, - int minSize = 0); + PropertiesReloadCallback reloadCallback, + PropertiesUpdateCallback callback, int minSize = 0); OBSPropertiesView(OBSData settings, const char *type, - PropertiesReloadCallback reloadCallback, - int minSize = 0); + PropertiesReloadCallback reloadCallback, + int minSize = 0); - inline obs_data_t *GetSettings() const {return settings;} + inline obs_data_t *GetSettings() const { return settings; } - inline void UpdateSettings() {callback(obj, settings);} - inline bool DeferUpdate() const {return deferUpdate;} + inline void UpdateSettings() { callback(obj, settings); } + inline bool DeferUpdate() const { return deferUpdate; } }; diff --git a/UI/properties-view.moc.hpp b/UI/properties-view.moc.hpp index 8703613..a5cf36d 100644 --- a/UI/properties-view.moc.hpp +++ b/UI/properties-view.moc.hpp @@ -15,13 +15,13 @@ #endif static bool operator!=(const media_frames_per_second &a, - const media_frames_per_second &b) + const media_frames_per_second &b) { return a.numerator != b.numerator || a.denominator != b.denominator; } static bool operator==(const media_frames_per_second &a, - const media_frames_per_second &b) + const media_frames_per_second &b) { return !(a != b); } @@ -36,27 +36,27 @@ class OBSFrameRatePropertyWidget : public QWidget { public: frame_rate_ranges_t fps_ranges; - QComboBox *modeSelect = nullptr; - QStackedWidget *modeDisplay = nullptr; + QComboBox *modeSelect = nullptr; + QStackedWidget *modeDisplay = nullptr; - QWidget *labels = nullptr; - QLabel *currentFPS = nullptr; - QLabel *timePerFrame = nullptr; - QLabel *minLabel = nullptr; - QLabel *maxLabel = nullptr; + QWidget *labels = nullptr; + QLabel *currentFPS = nullptr; + QLabel *timePerFrame = nullptr; + QLabel *minLabel = nullptr; + QLabel *maxLabel = nullptr; - QComboBox *simpleFPS = nullptr; + QComboBox *simpleFPS = nullptr; - QComboBox *fpsRange = nullptr; - QSpinBox *numEdit = nullptr; - QSpinBox *denEdit = nullptr; + QComboBox *fpsRange = nullptr; + QSpinBox *numEdit = nullptr; + QSpinBox *denEdit = nullptr; - bool updating = false; + bool updating = false; - const char *name = nullptr; - obs_data_t *settings = nullptr; + const char *name = nullptr; + obs_data_t *settings = nullptr; - QLabel *warningLabel = nullptr; + QLabel *warningLabel = nullptr; OBSFrameRatePropertyWidget() = default; }; diff --git a/UI/qt-display.cpp b/UI/qt-display.cpp index f2ca597..988068a 100644 --- a/UI/qt-display.cpp +++ b/UI/qt-display.cpp @@ -6,25 +6,20 @@ #include #include -static inline long long color_to_int(QColor color) +static inline long long color_to_int(const QColor &color) { - auto shift = [&](unsigned val, int shift) - { + auto shift = [&](unsigned val, int shift) { return ((val & 0xff) << shift); }; - return shift(color.red(), 0) | - shift(color.green(), 8) | - shift(color.blue(), 16) | - shift(color.alpha(), 24); + return shift(color.red(), 0) | shift(color.green(), 8) | + shift(color.blue(), 16) | shift(color.alpha(), 24); } static inline QColor rgba_to_color(uint32_t rgba) { - return QColor::fromRgb(rgba & 0xFF, - (rgba >> 8) & 0xFF, - (rgba >> 16) & 0xFF, - (rgba >> 24) & 0xFF); + return QColor::fromRgb(rgba & 0xFF, (rgba >> 8) & 0xFF, + (rgba >> 16) & 0xFF, (rgba >> 24) & 0xFF); } OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags) @@ -37,8 +32,7 @@ OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags) setAttribute(Qt::WA_DontCreateNativeAncestors); setAttribute(Qt::WA_NativeWindow); - auto windowVisible = [this] (bool visible) - { + auto windowVisible = [this](bool visible) { if (!visible) return; @@ -46,12 +40,12 @@ OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags) CreateDisplay(); } else { QSize size = GetPixelSize(this); - obs_display_resize(display, size.width(), size.height()); + obs_display_resize(display, size.width(), + size.height()); } }; - auto sizeChanged = [this] (QScreen*) - { + auto sizeChanged = [this](QScreen *) { CreateDisplay(); QSize size = GetPixelSize(this); @@ -89,11 +83,11 @@ void OBSQTDisplay::CreateDisplay() QSize size = GetPixelSize(this); - gs_init_data info = {}; - info.cx = size.width(); - info.cy = size.height(); - info.format = GS_RGBA; - info.zsformat = GS_ZS_NONE; + gs_init_data info = {}; + info.cx = size.width(); + info.cy = size.height(); + info.format = GS_RGBA; + info.zsformat = GS_ZS_NONE; QTToGSWindow(winId(), info.window); diff --git a/UI/qt-display.hpp b/UI/qt-display.hpp index de4fdac..a2e5a3e 100644 --- a/UI/qt-display.hpp +++ b/UI/qt-display.hpp @@ -7,9 +7,9 @@ class OBSQTDisplay : public QWidget { Q_OBJECT - Q_PROPERTY(QColor displayBackgroundColor MEMBER backgroundColor - READ GetDisplayBackgroundColor - WRITE SetDisplayBackgroundColor) + Q_PROPERTY(QColor displayBackgroundColor MEMBER backgroundColor READ + GetDisplayBackgroundColor WRITE + SetDisplayBackgroundColor) OBSDisplay display; @@ -24,11 +24,11 @@ signals: public: OBSQTDisplay(QWidget *parent = nullptr, - Qt::WindowFlags flags = nullptr); + Qt::WindowFlags flags = nullptr); virtual QPaintEngine *paintEngine() const override; - inline obs_display_t *GetDisplay() const {return display;} + inline obs_display_t *GetDisplay() const { return display; } uint32_t backgroundColor = GREY_COLOR_BACKGROUND; diff --git a/UI/qt-wrappers.cpp b/UI/qt-wrappers.cpp index 5d8a9cb..5916e89 100644 --- a/UI/qt-wrappers.cpp +++ b/UI/qt-wrappers.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #if !defined(_WIN32) && !defined(__APPLE__) #include @@ -45,20 +46,17 @@ void OBSErrorBox(QWidget *parent, const char *msg, ...) va_end(args); } -QMessageBox::StandardButton OBSMessageBox::question( - QWidget *parent, - const QString &title, - const QString &text, - QMessageBox::StandardButtons buttons, - QMessageBox::StandardButton defaultButton) +QMessageBox::StandardButton +OBSMessageBox::question(QWidget *parent, const QString &title, + const QString &text, + QMessageBox::StandardButtons buttons, + QMessageBox::StandardButton defaultButton) { - QMessageBox mb(QMessageBox::Question, - title, text, buttons, - parent); + QMessageBox mb(QMessageBox::Question, title, text, buttons, parent); mb.setDefaultButton(defaultButton); - if (buttons & QMessageBox::Ok) \ + if (buttons & QMessageBox::Ok) mb.setButtonText(QMessageBox::Ok, QTStr("OK")); -#define translate_button(x) \ +#define translate_button(x) \ if (buttons & QMessageBox::x) \ mb.setButtonText(QMessageBox::x, QTStr(#x)); translate_button(Open); @@ -78,41 +76,31 @@ QMessageBox::StandardButton OBSMessageBox::question( return (QMessageBox::StandardButton)mb.exec(); } -void OBSMessageBox::information( - QWidget *parent, - const QString &title, - const QString &text) +void OBSMessageBox::information(QWidget *parent, const QString &title, + const QString &text) { - QMessageBox mb(QMessageBox::Information, - title, text, QMessageBox::Ok, - parent); + QMessageBox mb(QMessageBox::Information, title, text, QMessageBox::Ok, + parent); mb.setButtonText(QMessageBox::Ok, QTStr("OK")); mb.exec(); } -void OBSMessageBox::warning( - QWidget *parent, - const QString &title, - const QString &text, - bool enableRichText) +void OBSMessageBox::warning(QWidget *parent, const QString &title, + const QString &text, bool enableRichText) { - QMessageBox mb(QMessageBox::Warning, - title, text, QMessageBox::Ok, - parent); + QMessageBox mb(QMessageBox::Warning, title, text, QMessageBox::Ok, + parent); if (enableRichText) mb.setTextFormat(Qt::RichText); mb.setButtonText(QMessageBox::Ok, QTStr("OK")); mb.exec(); } -void OBSMessageBox::critical( - QWidget *parent, - const QString &title, - const QString &text) +void OBSMessageBox::critical(QWidget *parent, const QString &title, + const QString &text) { - QMessageBox mb(QMessageBox::Critical, - title, text, QMessageBox::Ok, - parent); + QMessageBox mb(QMessageBox::Critical, title, text, QMessageBox::Ok, + parent); mb.setButtonText(QMessageBox::Ok, QTStr("OK")); mb.exec(); } @@ -156,13 +144,13 @@ uint32_t TranslateQtKeyboardEventModifiers(Qt::KeyboardModifiers mods) } QDataStream &operator<<(QDataStream &out, - const std::vector> &) + const std::vector> &) { return out; } QDataStream &operator>>(QDataStream &in, - std::vector> &) + std::vector> &) { return in; } @@ -186,7 +174,7 @@ QDataStream &operator>>(QDataStream &in, OBSScene &scene) QDataStream &operator<<(QDataStream &out, const OBSSceneItem &si) { - obs_scene_t *scene = obs_sceneitem_get_scene(si); + obs_scene_t *scene = obs_sceneitem_get_scene(si); obs_source_t *source = obs_sceneitem_get_source(si); return out << QString(obs_source_get_name(obs_scene_get_source(scene))) << QString(obs_source_get_name(source)); @@ -234,15 +222,12 @@ void DeleteLayout(QLayout *layout) class QuickThread : public QThread { public: - explicit inline QuickThread(std::function func_) - : func(func_) - {} + explicit inline QuickThread(std::function func_) : func(func_) + { + } private: - virtual void run() override - { - func(); - } + virtual void run() override { func(); } std::function func; }; @@ -258,11 +243,10 @@ void ExecuteFuncSafeBlock(std::function func) { QEventLoop eventLoop; - auto wait = [&] () - { + auto wait = [&]() { func(); QMetaObject::invokeMethod(&eventLoop, "quit", - Qt::QueuedConnection); + Qt::QueuedConnection); }; os_atomic_inc_long(&insideEventLoop); @@ -273,10 +257,8 @@ void ExecuteFuncSafeBlock(std::function func) os_atomic_dec_long(&insideEventLoop); } -void ExecuteFuncSafeBlockMsgBox( - std::function func, - const QString &title, - const QString &text) +void ExecuteFuncSafeBlockMsgBox(std::function func, + const QString &title, const QString &text) { QMessageBox dlg; dlg.setWindowFlags(dlg.windowFlags() & ~Qt::WindowCloseButtonHint); @@ -284,8 +266,7 @@ void ExecuteFuncSafeBlockMsgBox( dlg.setText(text); dlg.setStandardButtons(0); - auto wait = [&] () - { + auto wait = [&]() { func(); QMetaObject::invokeMethod(&dlg, "accept", Qt::QueuedConnection); }; @@ -305,13 +286,40 @@ void EnableThreadedMessageBoxes(bool enable) enable_message_boxes = enable; } -void ExecThreadedWithoutBlocking( - std::function func, - const QString &title, - const QString &text) +void ExecThreadedWithoutBlocking(std::function func, + const QString &title, const QString &text) { if (!enable_message_boxes) ExecuteFuncSafeBlock(func); else ExecuteFuncSafeBlockMsgBox(func, title, text); } + +bool LineEditCanceled(QEvent *event) +{ + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = reinterpret_cast(event); + return keyEvent->key() == Qt::Key_Escape; + } + + return false; +} + +bool LineEditChanged(QEvent *event) +{ + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = reinterpret_cast(event); + + switch (keyEvent->key()) { + case Qt::Key_Tab: + case Qt::Key_Backtab: + case Qt::Key_Enter: + case Qt::Key_Return: + return true; + } + } else if (event->type() == QEvent::FocusOut) { + return true; + } + + return false; +} diff --git a/UI/qt-wrappers.hpp b/UI/qt-wrappers.hpp index ab30109..b0e20a0 100644 --- a/UI/qt-wrappers.hpp +++ b/UI/qt-wrappers.hpp @@ -38,25 +38,19 @@ struct gs_window; class OBSMessageBox { public: - static QMessageBox::StandardButton question( - QWidget *parent, - const QString &title, - const QString &text, - QMessageBox::StandardButtons buttons = QMessageBox::StandardButtons( QMessageBox::Yes | QMessageBox::No ), - QMessageBox::StandardButton defaultButton = QMessageBox::NoButton); - static void information( - QWidget *parent, - const QString &title, - const QString &text); - static void warning( - QWidget *parent, - const QString &title, - const QString &text, - bool enableRichText = false); - static void critical( - QWidget *parent, - const QString &title, - const QString &text); + static QMessageBox::StandardButton + question(QWidget *parent, const QString &title, const QString &text, + QMessageBox::StandardButtons buttons = + QMessageBox::StandardButtons(QMessageBox::Yes | + QMessageBox::No), + QMessageBox::StandardButton defaultButton = + QMessageBox::NoButton); + static void information(QWidget *parent, const QString &title, + const QString &text); + static void warning(QWidget *parent, const QString &title, + const QString &text, bool enableRichText = false); + static void critical(QWidget *parent, const QString &title, + const QString &text); }; void OBSErrorBox(QWidget *parent, const char *msg, ...); @@ -65,10 +59,11 @@ void QTToGSWindow(WId windowId, gs_window &gswindow); uint32_t TranslateQtKeyboardEventModifiers(Qt::KeyboardModifiers mods); -QDataStream &operator<<(QDataStream &out, - const std::vector> &signal_vec); +QDataStream & +operator<<(QDataStream &out, + const std::vector> &signal_vec); QDataStream &operator>>(QDataStream &in, - std::vector> &signal_vec); + std::vector> &signal_vec); QDataStream &operator<<(QDataStream &out, const OBSScene &scene); QDataStream &operator>>(QDataStream &in, OBSScene &scene); QDataStream &operator<<(QDataStream &out, const OBSSceneItem &si); @@ -77,18 +72,14 @@ QDataStream &operator>>(QDataStream &in, OBSSceneItem &si); QThread *CreateQThread(std::function func); void ExecuteFuncSafeBlock(std::function func); -void ExecuteFuncSafeBlockMsgBox( - std::function func, - const QString &title, - const QString &text); +void ExecuteFuncSafeBlockMsgBox(std::function func, + const QString &title, const QString &text); /* allows executing without message boxes if starting up, otherwise with a * message box */ void EnableThreadedMessageBoxes(bool enable); -void ExecThreadedWithoutBlocking( - std::function func, - const QString &title, - const QString &text); +void ExecThreadedWithoutBlocking(std::function func, + const QString &title, const QString &text); class SignalBlocker { QWidget *widget; @@ -100,10 +91,7 @@ public: blocked = widget->blockSignals(true); } - inline ~SignalBlocker() - { - widget->blockSignals(blocked); - } + inline ~SignalBlocker() { widget->blockSignals(blocked); } }; void DeleteLayout(QLayout *layout); @@ -111,6 +99,9 @@ void DeleteLayout(QLayout *layout); static inline Qt::ConnectionType WaitConnection() { return QThread::currentThread() == qApp->thread() - ? Qt::DirectConnection - : Qt::BlockingQueuedConnection; + ? Qt::DirectConnection + : Qt::BlockingQueuedConnection; } + +bool LineEditCanceled(QEvent *event); +bool LineEditChanged(QEvent *event); diff --git a/UI/record-button.cpp b/UI/record-button.cpp new file mode 100644 index 0000000..021f5b8 --- /dev/null +++ b/UI/record-button.cpp @@ -0,0 +1,19 @@ +#include "record-button.hpp" +#include "window-basic-main.hpp" + +void RecordButton::resizeEvent(QResizeEvent *event) +{ + OBSBasic *main = OBSBasic::Get(); + if (!main->pause) + return; + + QSize pauseSize = main->pause->size(); + int height = main->ui->recordButton->size().height(); + + if (pauseSize.height() != height || pauseSize.width() != height) { + main->pause->setMinimumSize(height, height); + main->pause->setMaximumSize(height, height); + } + + event->accept(); +} diff --git a/UI/record-button.hpp b/UI/record-button.hpp new file mode 100644 index 0000000..c1782aa --- /dev/null +++ b/UI/record-button.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include + +class RecordButton : public QPushButton { + Q_OBJECT + +public: + inline RecordButton(QWidget *parent = nullptr) : QPushButton(parent) {} + + virtual void resizeEvent(QResizeEvent *event) override; +}; diff --git a/UI/remote-text.cpp b/UI/remote-text.cpp index 41525c9..1a6fcde 100644 --- a/UI/remote-text.cpp +++ b/UI/remote-text.cpp @@ -22,7 +22,7 @@ using namespace std; -static auto curl_deleter = [] (CURL *curl) {curl_easy_cleanup(curl);}; +static auto curl_deleter = [](CURL *curl) { curl_easy_cleanup(curl); }; using Curl = unique_ptr; static size_t string_write(char *ptr, size_t size, size_t nmemb, string &str) @@ -53,12 +53,11 @@ void RemoteTextThread::run() struct curl_slist *header = nullptr; string str; - header = curl_slist_append(header, - versionString.c_str()); + header = curl_slist_append(header, versionString.c_str()); if (!contentTypeString.empty()) { header = curl_slist_append(header, - contentTypeString.c_str()); + contentTypeString.c_str()); } for (std::string &h : extraHeaders) @@ -66,18 +65,15 @@ void RemoteTextThread::run() curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str()); curl_easy_setopt(curl.get(), CURLOPT_ACCEPT_ENCODING, ""); - curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, - header); - curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER, - error); + curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header); + curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER, error); curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, - string_write); - curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, - &str); + string_write); + curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &str); if (timeoutSec) curl_easy_setopt(curl.get(), CURLOPT_TIMEOUT, - timeoutSec); + timeoutSec); #if LIBCURL_VERSION_NUM >= 0x072400 // A lot of servers don't yet support ALPN @@ -86,7 +82,7 @@ void RemoteTextThread::run() if (!postData.empty()) { curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS, - postData.c_str()); + postData.c_str()); } code = curl_easy_perform(curl.get()); @@ -101,7 +97,7 @@ void RemoteTextThread::run() } static size_t header_write(char *ptr, size_t size, size_t nmemb, - vector &list) + vector &list) { string str; @@ -118,16 +114,10 @@ static size_t header_write(char *ptr, size_t size, size_t nmemb, return total; } -bool GetRemoteFile( - const char *url, - std::string &str, - std::string &error, - long *responseCode, - const char *contentType, - const char *postData, - std::vector extraHeaders, - std::string *signature, - int timeoutSec) +bool GetRemoteFile(const char *url, std::string &str, std::string &error, + long *responseCode, const char *contentType, + const char *postData, std::vector extraHeaders, + std::string *signature, int timeoutSec) { vector header_in_list; char error_in[CURL_ERROR_SIZE]; @@ -148,12 +138,11 @@ bool GetRemoteFile( if (curl) { struct curl_slist *header = nullptr; - header = curl_slist_append(header, - versionString.c_str()); + header = curl_slist_append(header, versionString.c_str()); if (!contentTypeString.empty()) { header = curl_slist_append(header, - contentTypeString.c_str()); + contentTypeString.c_str()); } for (std::string &h : extraHeaders) @@ -161,24 +150,21 @@ bool GetRemoteFile( curl_easy_setopt(curl.get(), CURLOPT_URL, url); curl_easy_setopt(curl.get(), CURLOPT_ACCEPT_ENCODING, ""); - curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, - header); - curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER, - error_in); + curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header); + curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER, error_in); curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, - string_write); - curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, - &str); + string_write); + curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &str); if (signature) { curl_easy_setopt(curl.get(), CURLOPT_HEADERFUNCTION, - header_write); + header_write); curl_easy_setopt(curl.get(), CURLOPT_HEADERDATA, - &header_in_list); + &header_in_list); } if (timeoutSec) curl_easy_setopt(curl.get(), CURLOPT_TIMEOUT, - timeoutSec); + timeoutSec); #if LIBCURL_VERSION_NUM >= 0x072400 // A lot of servers don't yet support ALPN @@ -187,13 +173,13 @@ bool GetRemoteFile( if (postData) { curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS, - postData); + postData); } code = curl_easy_perform(curl.get()); if (responseCode) curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE, - responseCode); + responseCode); if (code != CURLE_OK) { error = error_in; diff --git a/UI/remote-text.hpp b/UI/remote-text.hpp index d5663e1..91c9561 100644 --- a/UI/remote-text.hpp +++ b/UI/remote-text.hpp @@ -38,38 +38,34 @@ signals: void Result(const QString &text, const QString &error); public: - inline RemoteTextThread( - std::string url_, - std::string contentType_ = std::string(), - std::string postData_ = std::string(), - int timeoutSec_ = 0) - : url (url_), - contentType (contentType_), - postData (postData_), - timeoutSec (timeoutSec_) - {} + inline RemoteTextThread(std::string url_, + std::string contentType_ = std::string(), + std::string postData_ = std::string(), + int timeoutSec_ = 0) + : url(url_), + contentType(contentType_), + postData(postData_), + timeoutSec(timeoutSec_) + { + } - inline RemoteTextThread( - std::string url_, - std::vector &&extraHeaders_, - std::string contentType_ = std::string(), - std::string postData_ = std::string(), - int timeoutSec_ = 0) - : url (url_), - contentType (contentType_), - postData (postData_), - extraHeaders (std::move(extraHeaders_)), - timeoutSec (timeoutSec_) - {} + inline RemoteTextThread(std::string url_, + std::vector &&extraHeaders_, + std::string contentType_ = std::string(), + std::string postData_ = std::string(), + int timeoutSec_ = 0) + : url(url_), + contentType(contentType_), + postData(postData_), + extraHeaders(std::move(extraHeaders_)), + timeoutSec(timeoutSec_) + { + } }; bool GetRemoteFile( - const char *url, - std::string &str, - std::string &error, - long *responseCode = nullptr, - const char *contentType = nullptr, + const char *url, std::string &str, std::string &error, + long *responseCode = nullptr, const char *contentType = nullptr, const char *postData = nullptr, std::vector extraHeaders = std::vector(), - std::string *signature = nullptr, - int timeoutSec = 0); + std::string *signature = nullptr, int timeoutSec = 0); diff --git a/UI/slider-absoluteset-style.cpp b/UI/slider-absoluteset-style.cpp index 064f89a..3417604 100644 --- a/UI/slider-absoluteset-style.cpp +++ b/UI/slider-absoluteset-style.cpp @@ -1,19 +1,20 @@ #include "slider-absoluteset-style.hpp" -SliderAbsoluteSetStyle::SliderAbsoluteSetStyle(const QString& baseStyle) - :QProxyStyle(baseStyle) +SliderAbsoluteSetStyle::SliderAbsoluteSetStyle(const QString &baseStyle) + : QProxyStyle(baseStyle) { } -SliderAbsoluteSetStyle::SliderAbsoluteSetStyle(QStyle* baseStyle) - :QProxyStyle(baseStyle) +SliderAbsoluteSetStyle::SliderAbsoluteSetStyle(QStyle *baseStyle) + : QProxyStyle(baseStyle) { } int SliderAbsoluteSetStyle::styleHint(QStyle::StyleHint hint, - const QStyleOption* option = 0, const QWidget* widget = 0, - QStyleHintReturn* returnData = 0) const + const QStyleOption *option = 0, + const QWidget *widget = 0, + QStyleHintReturn *returnData = 0) const { - if(hint == QStyle::SH_Slider_AbsoluteSetButtons) + if (hint == QStyle::SH_Slider_AbsoluteSetButtons) return (Qt::LeftButton | Qt::MidButton); return QProxyStyle::styleHint(hint, option, widget, returnData); } diff --git a/UI/slider-absoluteset-style.hpp b/UI/slider-absoluteset-style.hpp index d275ad2..63b4e68 100644 --- a/UI/slider-absoluteset-style.hpp +++ b/UI/slider-absoluteset-style.hpp @@ -2,11 +2,11 @@ #include -class SliderAbsoluteSetStyle : public QProxyStyle -{ +class SliderAbsoluteSetStyle : public QProxyStyle { public: - SliderAbsoluteSetStyle(const QString& baseStyle); - SliderAbsoluteSetStyle(QStyle* baseStyle = Q_NULLPTR); - int styleHint(QStyle::StyleHint hint, const QStyleOption* option, - const QWidget* widget, QStyleHintReturn* returnData) const; + SliderAbsoluteSetStyle(const QString &baseStyle); + SliderAbsoluteSetStyle(QStyle *baseStyle = Q_NULLPTR); + int styleHint(QStyle::StyleHint hint, const QStyleOption *option, + const QWidget *widget, + QStyleHintReturn *returnData) const; }; diff --git a/UI/slider-ignorewheel.cpp b/UI/slider-ignorewheel.cpp index f2708e9..8203c81 100644 --- a/UI/slider-ignorewheel.cpp +++ b/UI/slider-ignorewheel.cpp @@ -6,7 +6,7 @@ SliderIgnoreScroll::SliderIgnoreScroll(QWidget *parent) : QSlider(parent) } SliderIgnoreScroll::SliderIgnoreScroll(Qt::Orientation orientation, - QWidget *parent) + QWidget *parent) : QSlider(parent) { setFocusPolicy(Qt::StrongFocus); diff --git a/UI/slider-ignorewheel.hpp b/UI/slider-ignorewheel.hpp index 7778c90..f5c7e5d 100644 --- a/UI/slider-ignorewheel.hpp +++ b/UI/slider-ignorewheel.hpp @@ -9,7 +9,8 @@ class SliderIgnoreScroll : public QSlider { public: SliderIgnoreScroll(QWidget *parent = nullptr); - SliderIgnoreScroll(Qt::Orientation orientation, QWidget *parent = nullptr); + SliderIgnoreScroll(Qt::Orientation orientation, + QWidget *parent = nullptr); protected: virtual void wheelEvent(QWheelEvent *event) override; diff --git a/UI/source-label.cpp b/UI/source-label.cpp index a707f7d..fc83a98 100644 --- a/UI/source-label.cpp +++ b/UI/source-label.cpp @@ -19,7 +19,7 @@ void OBSSourceLabel::SourceRenamed(void *data, calldata_t *params) { - auto &label = *static_cast(data); + auto &label = *static_cast(data); const char *name = calldata_string(params, "new_name"); label.setText(name); @@ -29,13 +29,13 @@ void OBSSourceLabel::SourceRenamed(void *data, calldata_t *params) void OBSSourceLabel::SourceRemoved(void *data, calldata_t *) { - auto &label = *static_cast(data); + auto &label = *static_cast(data); emit label.Removed(); } void OBSSourceLabel::SourceDestroyed(void *data, calldata_t *) { - auto &label = *static_cast(data); + auto &label = *static_cast(data); emit label.Destroyed(); label.destroyedSignal.Disconnect(); diff --git a/UI/source-label.hpp b/UI/source-label.hpp index 6bba24e..4a629b8 100644 --- a/UI/source-label.hpp +++ b/UI/source-label.hpp @@ -28,17 +28,18 @@ public: OBSSignal removedSignal; OBSSignal destroyedSignal; - OBSSourceLabel(const obs_source_t *source, QWidget *parent=nullptr, - Qt::WindowFlags f=0) + OBSSourceLabel(const obs_source_t *source, QWidget *parent = nullptr, + Qt::WindowFlags f = 0) : QLabel(obs_source_get_name(source), parent, f), renamedSignal(obs_source_get_signal_handler(source), "rename", - &OBSSourceLabel::SourceRenamed, this), + &OBSSourceLabel::SourceRenamed, this), removedSignal(obs_source_get_signal_handler(source), "remove", - &OBSSourceLabel::SourceRemoved, this), + &OBSSourceLabel::SourceRemoved, this), destroyedSignal(obs_source_get_signal_handler(source), "destroy", &OBSSourceLabel::SourceDestroyed, this) - {} + { + } protected: static void SourceRenamed(void *data, calldata_t *params); diff --git a/UI/source-tree.cpp b/UI/source-tree.cpp index e46ad54..4032f3a 100644 --- a/UI/source-tree.cpp +++ b/UI/source-tree.cpp @@ -25,15 +25,14 @@ static inline OBSScene GetCurrentScene() { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); return main->GetCurrentScene(); } /* ========================================================================= */ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_) - : tree (tree_), - sceneitem (sceneitem_) + : tree(tree_), sceneitem(sceneitem_) { setAttribute(Qt::WA_TranslucentBackground); setMouseTracking(true); @@ -98,14 +97,12 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_) /* --------------------------------------------------------- */ - auto setItemVisible = [this] (bool checked) - { + auto setItemVisible = [this](bool checked) { SignalBlocker sourcesSignalBlocker(this); obs_sceneitem_set_visible(sceneitem, checked); }; - auto setItemLocked = [this] (bool checked) - { + auto setItemLocked = [this](bool checked) { SignalBlocker sourcesSignalBlocker(this); obs_sceneitem_set_locked(sceneitem, checked); }; @@ -130,6 +127,7 @@ void SourceTreeItem::DisconnectSignals() itemRemoveSignal.Disconnect(); deselectSignal.Disconnect(); visibleSignal.Disconnect(); + lockedSignal.Disconnect(); renameSignal.Disconnect(); removeSignal.Disconnect(); } @@ -149,47 +147,58 @@ void SourceTreeItem::ReconnectSignals() /* --------------------------------------------------------- */ - auto removeItem = [] (void *data, calldata_t *cd) - { - SourceTreeItem *this_ = reinterpret_cast(data); + auto removeItem = [](void *data, calldata_t *cd) { + SourceTreeItem *this_ = + reinterpret_cast(data); obs_sceneitem_t *curItem = - (obs_sceneitem_t*)calldata_ptr(cd, "item"); + (obs_sceneitem_t *)calldata_ptr(cd, "item"); if (curItem == this_->sceneitem) { - QMetaObject::invokeMethod(this_->tree, - "Remove", - Q_ARG(OBSSceneItem, curItem)); + QMetaObject::invokeMethod(this_->tree, "Remove", + Q_ARG(OBSSceneItem, curItem)); curItem = nullptr; } if (!curItem) QMetaObject::invokeMethod(this_, "Clear"); }; - auto itemVisible = [] (void *data, calldata_t *cd) - { - SourceTreeItem *this_ = reinterpret_cast(data); + auto itemVisible = [](void *data, calldata_t *cd) { + SourceTreeItem *this_ = + reinterpret_cast(data); obs_sceneitem_t *curItem = - (obs_sceneitem_t*)calldata_ptr(cd, "item"); + (obs_sceneitem_t *)calldata_ptr(cd, "item"); bool visible = calldata_bool(cd, "visible"); if (curItem == this_->sceneitem) QMetaObject::invokeMethod(this_, "VisibilityChanged", - Q_ARG(bool, visible)); + Q_ARG(bool, visible)); }; - auto itemDeselect = [] (void *data, calldata_t *cd) - { - SourceTreeItem *this_ = reinterpret_cast(data); + auto itemLocked = [](void *data, calldata_t *cd) { + SourceTreeItem *this_ = + reinterpret_cast(data); obs_sceneitem_t *curItem = - (obs_sceneitem_t*)calldata_ptr(cd, "item"); + (obs_sceneitem_t *)calldata_ptr(cd, "item"); + bool locked = calldata_bool(cd, "locked"); + + if (curItem == this_->sceneitem) + QMetaObject::invokeMethod(this_, "LockedChanged", + Q_ARG(bool, locked)); + }; + + auto itemDeselect = [](void *data, calldata_t *cd) { + SourceTreeItem *this_ = + reinterpret_cast(data); + obs_sceneitem_t *curItem = + (obs_sceneitem_t *)calldata_ptr(cd, "item"); if (curItem == this_->sceneitem) QMetaObject::invokeMethod(this_, "Deselect"); }; - auto reorderGroup = [] (void *data, calldata_t*) - { - SourceTreeItem *this_ = reinterpret_cast(data); + auto reorderGroup = [](void *data, calldata_t *) { + SourceTreeItem *this_ = + reinterpret_cast(data); QMetaObject::invokeMethod(this_->tree, "ReorderItems"); }; @@ -200,33 +209,34 @@ void SourceTreeItem::ReconnectSignals() sceneRemoveSignal.Connect(signal, "remove", removeItem, this); itemRemoveSignal.Connect(signal, "item_remove", removeItem, this); visibleSignal.Connect(signal, "item_visible", itemVisible, this); + lockedSignal.Connect(signal, "item_locked", itemLocked, this); if (obs_sceneitem_is_group(sceneitem)) { obs_source_t *source = obs_sceneitem_get_source(sceneitem); signal = obs_source_get_signal_handler(source); groupReorderSignal.Connect(signal, "reorder", reorderGroup, - this); + this); } if (scene != GetCurrentScene()) deselectSignal.Connect(signal, "item_deselect", itemDeselect, - this); + this); /* --------------------------------------------------------- */ - auto renamed = [] (void *data, calldata_t *cd) - { - SourceTreeItem *this_ = reinterpret_cast(data); + auto renamed = [](void *data, calldata_t *cd) { + SourceTreeItem *this_ = + reinterpret_cast(data); const char *name = calldata_string(cd, "new_name"); QMetaObject::invokeMethod(this_, "Renamed", - Q_ARG(QString, QT_UTF8(name))); + Q_ARG(QString, QT_UTF8(name))); }; - auto removeSource = [] (void *data, calldata_t *) - { - SourceTreeItem *this_ = reinterpret_cast(data); + auto removeSource = [](void *data, calldata_t *) { + SourceTreeItem *this_ = + reinterpret_cast(data); this_->DisconnectSignals(); this_->sceneitem = nullptr; }; @@ -246,13 +256,34 @@ void SourceTreeItem::mouseDoubleClickEvent(QMouseEvent *event) } else { obs_source_t *source = obs_sceneitem_get_source(sceneitem); OBSBasic *main = - reinterpret_cast(App()->GetMainWindow()); + reinterpret_cast(App()->GetMainWindow()); if (source) { main->CreatePropertiesWindow(source); } } } +void SourceTreeItem::enterEvent(QEvent *event) +{ + QWidget::enterEvent(event); + + OBSBasicPreview *preview = OBSBasicPreview::Get(); + + std::lock_guard lock(preview->selectMutex); + preview->hoveredPreviewItems.clear(); + preview->hoveredPreviewItems.push_back(sceneitem); +} + +void SourceTreeItem::leaveEvent(QEvent *event) +{ + QWidget::leaveEvent(event); + + OBSBasicPreview *preview = OBSBasicPreview::Get(); + + std::lock_guard lock(preview->selectMutex); + preview->hoveredPreviewItems.clear(); +} + bool SourceTreeItem::IsEditing() { return editor != nullptr; @@ -275,7 +306,7 @@ void SourceTreeItem::ExitEditMode(bool save) if (!editor) return; - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); std::string newName = QT_TO_UTF8(editor->text()); @@ -294,9 +325,8 @@ void SourceTreeItem::ExitEditMode(bool save) return; if (newName.empty()) { - OBSMessageBox::information(main, - QTStr("NoNameEntered.Title"), - QTStr("NoNameEntered.Text")); + OBSMessageBox::information(main, QTStr("NoNameEntered.Title"), + QTStr("NoNameEntered.Text")); return; } @@ -310,15 +340,13 @@ void SourceTreeItem::ExitEditMode(bool save) /* ----------------------------------------- */ /* check for existing source */ - obs_source_t *existingSource = - obs_get_source_by_name(newName.c_str()); + obs_source_t *existingSource = obs_get_source_by_name(newName.c_str()); obs_source_release(existingSource); bool exists = !!existingSource; if (exists) { - OBSMessageBox::information(main, - QTStr("NameExists.Title"), - QTStr("NameExists.Text")); + OBSMessageBox::information(main, QTStr("NameExists.Title"), + QTStr("NameExists.Text")); return; } @@ -335,28 +363,16 @@ bool SourceTreeItem::eventFilter(QObject *object, QEvent *event) if (editor != object) return false; - if (event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); - - switch (keyEvent->key()) { - case Qt::Key_Escape: - QMetaObject::invokeMethod(this, "ExitEditMode", - Qt::QueuedConnection, - Q_ARG(bool, false)); - return true; - case Qt::Key_Tab: - case Qt::Key_Backtab: - case Qt::Key_Enter: - case Qt::Key_Return: - QMetaObject::invokeMethod(this, "ExitEditMode", - Qt::QueuedConnection, - Q_ARG(bool, true)); - return true; - } - } else if (event->type() == QEvent::FocusOut) { + if (LineEditCanceled(event)) { QMetaObject::invokeMethod(this, "ExitEditMode", - Qt::QueuedConnection, - Q_ARG(bool, true)); + Qt::QueuedConnection, + Q_ARG(bool, false)); + return true; + } + if (LineEditChanged(event)) { + QMetaObject::invokeMethod(this, "ExitEditMode", + Qt::QueuedConnection, + Q_ARG(bool, true)); return true; } @@ -368,6 +384,11 @@ void SourceTreeItem::VisibilityChanged(bool visible) vis->setChecked(visible); } +void SourceTreeItem::LockedChanged(bool locked) +{ + lock->setChecked(locked); +} + void SourceTreeItem::Renamed(const QString &name) { label->setText(name); @@ -386,14 +407,14 @@ void SourceTreeItem::Update(bool force) if (obs_sceneitem_is_group(sceneitem)) { newType = Type::Group; - /* ------------------------------------------------- */ - /* if it's a group sub-item */ + /* ------------------------------------------------- */ + /* if it's a group sub-item */ } else if (itemScene != scene) { newType = Type::SubItem; - /* ------------------------------------------------- */ - /* if it's a regular item */ + /* ------------------------------------------------- */ + /* if it's a regular item */ } else { newType = Type::Item; @@ -429,9 +450,8 @@ void SourceTreeItem::Update(bool force) } else if (type == Type::Group) { expand = new SourceTreeSubItemCheckBox(); - expand->setSizePolicy( - QSizePolicy::Maximum, - QSizePolicy::Maximum); + expand->setSizePolicy(QSizePolicy::Maximum, + QSizePolicy::Maximum); expand->setMaximumSize(10, 16); expand->setMinimumSize(10, 0); #ifdef __APPLE__ @@ -439,14 +459,15 @@ void SourceTreeItem::Update(bool force) #endif boxLayout->insertWidget(0, expand); - obs_data_t *data = obs_sceneitem_get_private_settings(sceneitem); + obs_data_t *data = + obs_sceneitem_get_private_settings(sceneitem); expand->blockSignals(true); expand->setChecked(obs_data_get_bool(data, "collapsed")); expand->blockSignals(false); obs_data_release(data); - connect(expand, &QPushButton::toggled, - this, &SourceTreeItem::ExpandClicked); + connect(expand, &QPushButton::toggled, this, + &SourceTreeItem::ExpandClicked); } else { spacer = new QSpacerItem(3, 1); @@ -498,10 +519,10 @@ void SourceTreeModel::Clear() hasGroups = false; } -static bool enumItem(obs_scene_t*, obs_sceneitem_t *item, void *ptr) +static bool enumItem(obs_scene_t *, obs_sceneitem_t *item, void *ptr) { QVector &items = - *reinterpret_cast*>(ptr); + *reinterpret_cast *>(ptr); if (obs_sceneitem_is_group(item)) { obs_data_t *data = obs_sceneitem_get_private_settings(item); @@ -537,14 +558,15 @@ void SourceTreeModel::SceneChanged() bool select = obs_sceneitem_selected(items[i]); QModelIndex index = createIndex(i, 0); - st->selectionModel()->select(index, select - ? QItemSelectionModel::Select - : QItemSelectionModel::Deselect); + st->selectionModel()->select( + index, select ? QItemSelectionModel::Select + : QItemSelectionModel::Deselect); } } /* moves a scene item index (blame linux distros for using older Qt builds) */ -static inline void MoveItem(QVector &items, int oldIdx, int newIdx) +static inline void MoveItem(QVector &items, int oldIdx, + int newIdx) { OBSSceneItem item = items[oldIdx]; items.remove(oldIdx); @@ -618,7 +640,7 @@ void SourceTreeModel::ReorderItems() /* move items */ beginMoveRows(QModelIndex(), idx1Old, idx1Old + count - 1, - QModelIndex(), idx1New + count); + QModelIndex(), idx1New + count); for (i = 0; i < count; i++) { int to = idx1New + count; if (to > idx1Old) @@ -690,8 +712,7 @@ OBSSceneItem SourceTreeModel::Get(int idx) } SourceTreeModel::SourceTreeModel(SourceTree *st_) - : QAbstractListModel (st_), - st (st_) + : QAbstractListModel(st_), st(st_) { obs_frontend_add_event_callback(OBSFrontendEvent, this); } @@ -725,8 +746,7 @@ Qt::ItemFlags SourceTreeModel::flags(const QModelIndex &index) const obs_sceneitem_t *item = items[index.row()]; bool is_group = obs_sceneitem_is_group(item); - return QAbstractListModel::flags(index) | - Qt::ItemIsEditable | + return QAbstractListModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | (is_group ? Qt::ItemIsDropEnabled : Qt::NoItemFlags); } @@ -756,8 +776,8 @@ QString SourceTreeModel::GetNewGroupName() void SourceTreeModel::AddGroup() { QString name = GetNewGroupName(); - obs_sceneitem_t *group = obs_scene_add_group(GetCurrentScene(), - QT_TO_UTF8(name)); + obs_sceneitem_t *group = + obs_scene_add_group(GetCurrentScene(), QT_TO_UTF8(name)); if (!group) return; @@ -769,7 +789,7 @@ void SourceTreeModel::AddGroup() UpdateGroupState(true); QMetaObject::invokeMethod(st, "Edit", Qt::QueuedConnection, - Q_ARG(int, 0)); + Q_ARG(int, 0)); } void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices) @@ -788,8 +808,7 @@ void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices) } obs_sceneitem_t *item = obs_scene_insert_group( - scene, QT_TO_UTF8(name), - item_order.data(), item_order.size()); + scene, QT_TO_UTF8(name), item_order.data(), item_order.size()); if (!item) { return; } @@ -808,7 +827,7 @@ void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices) int toIdx = newIdx + i + 1; if (fromIdx != toIdx) { beginMoveRows(QModelIndex(), fromIdx, fromIdx, - QModelIndex(), toIdx); + QModelIndex(), toIdx); MoveItem(items, fromIdx, toIdx); endMoveRows(); } @@ -820,7 +839,7 @@ void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices) obs_sceneitem_select(item, true); QMetaObject::invokeMethod(st, "Edit", Qt::QueuedConnection, - Q_ARG(int, newIdx)); + Q_ARG(int, newIdx)); } void SourceTreeModel::UngroupSelectedGroups(QModelIndexList &indices) @@ -910,20 +929,20 @@ SourceTree::SourceTree(QWidget *parent_) : QListView(parent_) SourceTreeModel *stm_ = new SourceTreeModel(this); setModel(stm_); setStyleSheet(QString( - "*[bgColor=\"1\"]{background-color:rgba(255,68,68,33%);}" \ - "*[bgColor=\"2\"]{background-color:rgba(255,255,68,33%);}" \ - "*[bgColor=\"3\"]{background-color:rgba(68,255,68,33%);}" \ - "*[bgColor=\"4\"]{background-color:rgba(68,255,255,33%);}" \ - "*[bgColor=\"5\"]{background-color:rgba(68,68,255,33%);}" \ - "*[bgColor=\"6\"]{background-color:rgba(255,68,255,33%);}" \ - "*[bgColor=\"7\"]{background-color:rgba(68,68,68,33%);}" \ + "*[bgColor=\"1\"]{background-color:rgba(255,68,68,33%);}" + "*[bgColor=\"2\"]{background-color:rgba(255,255,68,33%);}" + "*[bgColor=\"3\"]{background-color:rgba(68,255,68,33%);}" + "*[bgColor=\"4\"]{background-color:rgba(68,255,255,33%);}" + "*[bgColor=\"5\"]{background-color:rgba(68,68,255,33%);}" + "*[bgColor=\"6\"]{background-color:rgba(255,68,255,33%);}" + "*[bgColor=\"7\"]{background-color:rgba(68,68,68,33%);}" "*[bgColor=\"8\"]{background-color:rgba(255,255,255,33%);}")); setMouseTracking(true); UpdateNoSourcesMessage(); - connect(App(), &OBSApp::StyleChanged, - this, &SourceTree::UpdateNoSourcesMessage); + connect(App(), &OBSApp::StyleChanged, this, + &SourceTree::UpdateNoSourcesMessage); } void SourceTree::ResetWidgets() @@ -975,9 +994,9 @@ void SourceTree::SelectItem(obs_sceneitem_t *sceneitem, bool select) QModelIndex index = stm->createIndex(i, 0); if (index.isValid()) - selectionModel()->select(index, select - ? QItemSelectionModel::Select - : QItemSelectionModel::Deselect); + selectionModel()->select( + index, select ? QItemSelectionModel::Select + : QItemSelectionModel::Deselect); } Q_DECLARE_METATYPE(OBSSceneItem); @@ -1021,9 +1040,9 @@ void SourceTree::dropEvent(QDropEvent *event) obs_sceneitem_t *dropItem = items[row]; /* item being dropped on */ bool itemIsGroup = obs_sceneitem_is_group(dropItem); - obs_sceneitem_t *dropGroup = itemIsGroup - ? dropItem - : obs_sceneitem_get_group(scene, dropItem); + obs_sceneitem_t *dropGroup = + itemIsGroup ? dropItem + : obs_sceneitem_get_group(scene, dropItem); /* not a group if moving above the group */ if (indicator == QAbstractItemView::AboveItem && itemIsGroup) @@ -1037,7 +1056,8 @@ void SourceTree::dropEvent(QDropEvent *event) bool dropOnCollapsed = false; if (dropGroup) { - obs_data_t *data = obs_sceneitem_get_private_settings(dropGroup); + obs_data_t *data = + obs_sceneitem_get_private_settings(dropGroup); dropOnCollapsed = obs_data_get_bool(data, "collapsed"); obs_data_release(data); } @@ -1067,9 +1087,12 @@ void SourceTree::dropEvent(QDropEvent *event) /* if dropping a group, detect if it's */ /* below another group */ - obs_sceneitem_t *itemBelow = row == stm->items.count() - ? nullptr - : stm->items[row]; + obs_sceneitem_t *itemBelow; + if (row == stm->items.count()) + itemBelow = nullptr; + else + itemBelow = stm->items[row]; + if (hasGroups) { if (!itemBelow || obs_sceneitem_get_group(scene, itemBelow) != dropGroup) { @@ -1112,8 +1135,8 @@ void SourceTree::dropEvent(QDropEvent *event) for (int j = items.size() - 1; j >= 0; j--) { obs_sceneitem_t *subitem = items[j]; obs_sceneitem_t *subitemGroup = - obs_sceneitem_get_group(scene, - subitem); + obs_sceneitem_get_group( + scene, subitem); if (subitemGroup == item) { QModelIndex idx = @@ -1148,7 +1171,7 @@ void SourceTree::dropEvent(QDropEvent *event) if (itemTo != from) { stm->beginMoveRows(QModelIndex(), from, from, - QModelIndex(), to); + QModelIndex(), to); MoveItem(items, from, itemTo); stm->endMoveRows(); } @@ -1167,8 +1190,7 @@ void SourceTree::dropEvent(QDropEvent *event) obs_sceneitem_t *lastGroup = nullptr; int insertCollapsedIdx = 0; - auto insertCollapsed = [&] (obs_sceneitem_t *item) - { + auto insertCollapsed = [&](obs_sceneitem_t *item) { struct obs_sceneitem_order_info info; info.group = lastGroup; info.item = item; @@ -1178,25 +1200,23 @@ void SourceTree::dropEvent(QDropEvent *event) using insertCollapsed_t = decltype(insertCollapsed); - auto preInsertCollapsed = [] (obs_scene_t *, obs_sceneitem_t *item, - void *param) - { + auto preInsertCollapsed = [](obs_scene_t *, obs_sceneitem_t *item, + void *param) { (*reinterpret_cast(param))(item); return true; }; - auto insertLastGroup = [&] () - { - obs_data_t *data = obs_sceneitem_get_private_settings(lastGroup); + auto insertLastGroup = [&]() { + obs_data_t *data = + obs_sceneitem_get_private_settings(lastGroup); bool collapsed = obs_data_get_bool(data, "collapsed"); obs_data_release(data); if (collapsed) { insertCollapsedIdx = 0; - obs_sceneitem_group_enum_items( - lastGroup, - preInsertCollapsed, - &insertCollapsed); + obs_sceneitem_group_enum_items(lastGroup, + preInsertCollapsed, + &insertCollapsed); } struct obs_sceneitem_order_info info; @@ -1205,8 +1225,7 @@ void SourceTree::dropEvent(QDropEvent *event) orderList.insert(0, info); }; - auto updateScene = [&] () - { + auto updateScene = [&]() { struct obs_sceneitem_order_info info; for (int i = 0; i < items.size(); i++) { @@ -1241,14 +1260,13 @@ void SourceTree::dropEvent(QDropEvent *event) insertLastGroup(); } - obs_scene_reorder_items2(scene, - orderList.data(), orderList.size()); + obs_scene_reorder_items2(scene, orderList.data(), + orderList.size()); }; using updateScene_t = decltype(updateScene); - auto preUpdateScene = [] (void *data, obs_scene_t *) - { + auto preUpdateScene = [](void *data, obs_scene_t *) { (*reinterpret_cast(data))(); }; @@ -1283,21 +1301,27 @@ void SourceTree::mouseMoveEvent(QMouseEvent *event) SourceTreeItem *item = qobject_cast(childAt(pos)); OBSBasicPreview *preview = OBSBasicPreview::Get(); - preview->hoveredListItem = !!item ? item->sceneitem : nullptr; QListView::mouseMoveEvent(event); + + std::lock_guard lock(preview->selectMutex); + preview->hoveredPreviewItems.clear(); + if (item) + preview->hoveredPreviewItems.push_back(item->sceneitem); } void SourceTree::leaveEvent(QEvent *event) { OBSBasicPreview *preview = OBSBasicPreview::Get(); - preview->hoveredListItem = nullptr; + QListView::leaveEvent(event); + + std::lock_guard lock(preview->selectMutex); + preview->hoveredPreviewItems.clear(); } -void SourceTree::selectionChanged( - const QItemSelection &selected, - const QItemSelection &deselected) +void SourceTree::selectionChanged(const QItemSelection &selected, + const QItemSelection &deselected) { { SignalBlocker sourcesSignalBlocker(this); @@ -1406,7 +1430,7 @@ bool SourceTree::GroupedItemsSelected() const void SourceTree::Remove(OBSSceneItem item) { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); GetStm()->Remove(item); main->SaveProject(); @@ -1415,9 +1439,9 @@ void SourceTree::Remove(OBSSceneItem item) obs_source_t *sceneSource = obs_scene_get_source(scene); obs_source_t *itemSource = obs_sceneitem_get_source(item); blog(LOG_INFO, "User Removed source '%s' (%s) from scene '%s'", - obs_source_get_name(itemSource), - obs_source_get_id(itemSource), - obs_source_get_name(sceneSource)); + obs_source_get_name(itemSource), + obs_source_get_id(itemSource), + obs_source_get_name(sceneSource)); } } @@ -1446,9 +1470,8 @@ void SourceTree::UpdateNoSourcesMessage() QColor color = palette().text().color(); bool lightTheme = (color.redF() < 0.5); - QString file = lightTheme - ? ":res/images/no_sources.svg" - : darkPath.c_str(); + QString file = lightTheme ? ":res/images/no_sources.svg" + : darkPath.c_str(); iconNoSources.load(file); QTextOption opt(Qt::AlignHCenter); diff --git a/UI/source-tree.hpp b/UI/source-tree.hpp index 46577d2..d613e61 100644 --- a/UI/source-tree.hpp +++ b/UI/source-tree.hpp @@ -30,6 +30,8 @@ class SourceTreeItem : public QWidget { friend class SourceTreeModel; void mouseDoubleClickEvent(QMouseEvent *event) override; + void enterEvent(QEvent *event) override; + void leaveEvent(QEvent *event) override; virtual bool eventFilter(QObject *object, QEvent *event) override; @@ -68,10 +70,11 @@ private: OBSSignal groupReorderSignal; OBSSignal deselectSignal; OBSSignal visibleSignal; + OBSSignal lockedSignal; OBSSignal renameSignal; OBSSignal removeSignal; - virtual void paintEvent(QPaintEvent* event) override; + virtual void paintEvent(QPaintEvent *event) override; private slots: void Clear(); @@ -80,6 +83,7 @@ private slots: void ExitEditMode(bool save); void VisibilityChanged(bool visible); + void LockedChanged(bool locked); void Renamed(const QString &name); void ExpandClicked(bool checked); @@ -121,7 +125,8 @@ public: ~SourceTreeModel(); virtual int rowCount(const QModelIndex &parent) const override; - virtual QVariant data(const QModelIndex &index, int role) const override; + virtual QVariant data(const QModelIndex &index, + int role) const override; virtual Qt::ItemFlags flags(const QModelIndex &index) const override; virtual Qt::DropActions supportedDropActions() const override; @@ -159,12 +164,12 @@ public: explicit SourceTree(QWidget *parent = nullptr); - inline bool IgnoreReorder() const {return ignoreReorder;} - inline void Clear() {GetStm()->Clear();} + inline bool IgnoreReorder() const { return ignoreReorder; } + inline void Clear() { GetStm()->Clear(); } - inline void Add(obs_sceneitem_t *item) {GetStm()->Add(item);} - inline OBSSceneItem Get(int idx) {return GetStm()->Get(idx);} - inline QString GetNewGroupName() {return GetStm()->GetNewGroupName();} + inline void Add(obs_sceneitem_t *item) { GetStm()->Add(item); } + inline OBSSceneItem Get(int idx) { return GetStm()->Get(idx); } + inline QString GetNewGroupName() { return GetStm()->GetNewGroupName(); } void SelectItem(obs_sceneitem_t *sceneitem, bool select); @@ -173,7 +178,7 @@ public: bool GroupedItemsSelected() const; public slots: - inline void ReorderItems() {GetStm()->ReorderItems();} + inline void ReorderItems() { GetStm()->ReorderItems(); } void Remove(OBSSceneItem item); void GroupSelectedItems(); void UngroupSelectedGroups(); @@ -187,5 +192,7 @@ protected: virtual void leaveEvent(QEvent *event) override; virtual void paintEvent(QPaintEvent *event) override; - virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override; + virtual void + selectionChanged(const QItemSelection &selected, + const QItemSelection &deselected) override; }; diff --git a/UI/sparkle-updater.mm b/UI/sparkle-updater.mm index 1baab8d..932a3a7 100644 --- a/UI/sparkle-updater.mm +++ b/UI/sparkle-updater.mm @@ -6,15 +6,13 @@ static inline bool equali(NSString *a, NSString *b) return a && b && [a caseInsensitiveCompare:b] == NSOrderedSame; } -@interface OBSSparkleUpdateDelegate : - NSObject -{ +@interface OBSSparkleUpdateDelegate + : NSObject { } @property (nonatomic) bool updateToUndeployed; @end -@implementation OBSSparkleUpdateDelegate -{ +@implementation OBSSparkleUpdateDelegate { } @synthesize updateToUndeployed; @@ -50,11 +48,11 @@ static inline bool equali(NSString *a, NSString *b) item = mpkg; NSMutableDictionary *dict = [NSMutableDictionary - dictionaryWithDictionary:item.propertiesDictionary]; + dictionaryWithDictionary:item.propertiesDictionary]; NSString *build = [host objectForInfoDictionaryKey:@"CFBundleVersion"]; NSString *url = dict[@"sparkle:releaseNotesLink"]; - dict[@"sparkle:releaseNotesLink"] = [url stringByAppendingFormat:@"#%@", - build]; + dict[@"sparkle:releaseNotesLink"] = + [url stringByAppendingFormat:@"#%@", build]; return [[SUAppcastItem alloc] initWithDictionary:dict]; } @@ -62,9 +60,9 @@ static inline bool equali(NSString *a, NSString *b) - (SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SUUpdater *)updater { - SUAppcastItem *selected = - [self bestValidUpdateWithDeltasInAppcast:appcast - forUpdater:updater]; + SUAppcastItem *selected = [self + bestValidUpdateWithDeltasInAppcast:appcast + forUpdater:updater]; NSBundle *host = updater.hostBundle; NSString *build = [host objectForInfoDictionaryKey:@"CFBundleVersion"]; @@ -91,8 +89,8 @@ static inline bool equali(NSString *a, NSString *b) return NSOrderedSame; } -- (id ) - versionComparatorForUpdater:(SUUpdater *)__unused updater +- (id)versionComparatorForUpdater:(SUUpdater *)__unused + updater { return self; } @@ -141,4 +139,3 @@ void trigger_sparkle_update() { [updater checkForUpdates:nil]; } - diff --git a/UI/vertical-scroll-area.hpp b/UI/vertical-scroll-area.hpp index 15fc72a..6c2f63d 100644 --- a/UI/vertical-scroll-area.hpp +++ b/UI/vertical-scroll-area.hpp @@ -8,8 +8,7 @@ class VScrollArea : public QScrollArea { Q_OBJECT public: - inline VScrollArea(QWidget *parent = nullptr) - : QScrollArea(parent) + inline VScrollArea(QWidget *parent = nullptr) : QScrollArea(parent) { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); } diff --git a/UI/visibility-item-widget.cpp b/UI/visibility-item-widget.cpp index ba1ecbf..c05ed09 100644 --- a/UI/visibility-item-widget.cpp +++ b/UI/visibility-item-widget.cpp @@ -10,11 +10,11 @@ #include VisibilityItemWidget::VisibilityItemWidget(obs_source_t *source_) - : source (source_), - enabledSignal (obs_source_get_signal_handler(source), "enable", - OBSSourceEnabled, this), - renamedSignal (obs_source_get_signal_handler(source), "rename", - OBSSourceRenamed, this) + : source(source_), + enabledSignal(obs_source_get_signal_handler(source), "enable", + OBSSourceEnabled, this), + renamedSignal(obs_source_get_signal_handler(source), "rename", + OBSSourceRenamed, this) { const char *name = obs_source_get_name(source); bool enabled = obs_source_enabled(source); @@ -38,15 +38,15 @@ VisibilityItemWidget::VisibilityItemWidget(obs_source_t *source_) setLayout(itemLayout); setStyleSheet("background-color: rgba(255, 255, 255, 0);"); - connect(vis, SIGNAL(clicked(bool)), - this, SLOT(VisibilityClicked(bool))); + connect(vis, SIGNAL(clicked(bool)), this, + SLOT(VisibilityClicked(bool))); } VisibilityItemWidget::VisibilityItemWidget(obs_sceneitem_t *item_) - : item (item_), - source (obs_sceneitem_get_source(item)), - renamedSignal (obs_source_get_signal_handler(source), "rename", - OBSSourceRenamed, this) + : item(item_), + source(obs_sceneitem_get_source(item)), + renamedSignal(obs_source_get_signal_handler(source), "rename", + OBSSourceRenamed, this) { const char *name = obs_source_get_name(source); bool enabled = obs_sceneitem_visible(item); @@ -90,16 +90,15 @@ VisibilityItemWidget::VisibilityItemWidget(obs_sceneitem_t *item_) signal_handler_t *signal = obs_source_get_signal_handler(sceneSource); signal_handler_connect(signal, "remove", OBSSceneRemove, this); - signal_handler_connect(signal, "item_remove", OBSSceneItemRemove, - this); + signal_handler_connect(signal, "item_remove", OBSSceneItemRemove, this); signal_handler_connect(signal, "item_visible", OBSSceneItemVisible, - this); + this); + signal_handler_connect(signal, "item_locked", OBSSceneItemLocked, this); - connect(vis, SIGNAL(clicked(bool)), - this, SLOT(VisibilityClicked(bool))); + connect(vis, SIGNAL(clicked(bool)), this, + SLOT(VisibilityClicked(bool))); - connect(lock, SIGNAL(clicked(bool)), - this, SLOT(LockClicked(bool))); + connect(lock, SIGNAL(clicked(bool)), this, SLOT(LockClicked(bool))); } VisibilityItemWidget::~VisibilityItemWidget() @@ -118,9 +117,11 @@ void VisibilityItemWidget::DisconnectItemSignals() signal_handler_disconnect(signal, "remove", OBSSceneRemove, this); signal_handler_disconnect(signal, "item_remove", OBSSceneItemRemove, - this); + this); signal_handler_disconnect(signal, "item_visible", OBSSceneItemVisible, - this); + this); + signal_handler_disconnect(signal, "item_locked", OBSSceneItemLocked, + this); sceneRemoved = true; } @@ -128,7 +129,7 @@ void VisibilityItemWidget::DisconnectItemSignals() void VisibilityItemWidget::OBSSceneRemove(void *param, calldata_t *data) { VisibilityItemWidget *window = - reinterpret_cast(param); + reinterpret_cast(param); window->DisconnectItemSignals(); @@ -138,8 +139,8 @@ void VisibilityItemWidget::OBSSceneRemove(void *param, calldata_t *data) void VisibilityItemWidget::OBSSceneItemRemove(void *param, calldata_t *data) { VisibilityItemWidget *window = - reinterpret_cast(param); - obs_sceneitem_t *item = (obs_sceneitem_t*)calldata_ptr(data, "item"); + reinterpret_cast(param); + obs_sceneitem_t *item = (obs_sceneitem_t *)calldata_ptr(data, "item"); if (item == window->item) window->DisconnectItemSignals(); @@ -148,45 +149,47 @@ void VisibilityItemWidget::OBSSceneItemRemove(void *param, calldata_t *data) void VisibilityItemWidget::OBSSceneItemVisible(void *param, calldata_t *data) { VisibilityItemWidget *window = - reinterpret_cast(param); - obs_sceneitem_t *curItem = (obs_sceneitem_t*)calldata_ptr(data, "item"); + reinterpret_cast(param); + obs_sceneitem_t *curItem = + (obs_sceneitem_t *)calldata_ptr(data, "item"); bool enabled = calldata_bool(data, "visible"); if (window->item == curItem) QMetaObject::invokeMethod(window, "SourceEnabled", - Q_ARG(bool, enabled)); + Q_ARG(bool, enabled)); } void VisibilityItemWidget::OBSSceneItemLocked(void *param, calldata_t *data) { VisibilityItemWidget *window = - reinterpret_cast(param); - obs_sceneitem_t *curItem = (obs_sceneitem_t*)calldata_ptr(data, "item"); + reinterpret_cast(param); + obs_sceneitem_t *curItem = + (obs_sceneitem_t *)calldata_ptr(data, "item"); bool locked = calldata_bool(data, "locked"); if (window->item == curItem) QMetaObject::invokeMethod(window, "SourceLocked", - Q_ARG(bool, locked)); + Q_ARG(bool, locked)); } void VisibilityItemWidget::OBSSourceEnabled(void *param, calldata_t *data) { VisibilityItemWidget *window = - reinterpret_cast(param); + reinterpret_cast(param); bool enabled = calldata_bool(data, "enabled"); QMetaObject::invokeMethod(window, "SourceEnabled", - Q_ARG(bool, enabled)); + Q_ARG(bool, enabled)); } void VisibilityItemWidget::OBSSourceRenamed(void *param, calldata_t *data) { VisibilityItemWidget *window = - reinterpret_cast(param); + reinterpret_cast(param); const char *name = calldata_string(data, "new_name"); QMetaObject::invokeMethod(window, "SourceRenamed", - Q_ARG(QString, QT_UTF8(name))); + Q_ARG(QString, QT_UTF8(name))); } void VisibilityItemWidget::VisibilityClicked(bool visible) @@ -221,8 +224,8 @@ void VisibilityItemWidget::SourceRenamed(QString name) label->setText(name); } -void VisibilityItemWidget::SetColor(const QColor &color, - bool active_, bool selected_) +void VisibilityItemWidget::SetColor(const QColor &color, bool active_, + bool selected_) { /* Do not update unless the state has actually changed */ if (active_ == active && selected_ == selected) @@ -244,19 +247,19 @@ VisibilityItemDelegate::VisibilityItemDelegate(QObject *parent) } void VisibilityItemDelegate::paint(QPainter *painter, - const QStyleOptionViewItem &option, - const QModelIndex &index) const + const QStyleOptionViewItem &option, + const QModelIndex &index) const { QStyledItemDelegate::paint(painter, option, index); QObject *parentObj = parent(); - QListWidget *list = qobject_cast(parentObj); + QListWidget *list = qobject_cast(parentObj); if (!list) return; QListWidgetItem *item = list->item(index.row()); VisibilityItemWidget *widget = - qobject_cast(list->itemWidget(item)); + qobject_cast(list->itemWidget(item)); if (!widget) return; @@ -265,8 +268,8 @@ void VisibilityItemDelegate::paint(QPainter *painter, QPalette palette = list->palette(); #if defined(_WIN32) || defined(__APPLE__) - QPalette::ColorGroup group = active ? - QPalette::Active : QPalette::Inactive; + QPalette::ColorGroup group = active ? QPalette::Active + : QPalette::Inactive; #else QPalette::ColorGroup group = QPalette::Active; #endif @@ -288,7 +291,7 @@ void VisibilityItemDelegate::paint(QPainter *painter, } void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item, - obs_source_t *source) + obs_source_t *source) { VisibilityItemWidget *baseWidget = new VisibilityItemWidget(source); @@ -297,7 +300,7 @@ void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item, } void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item, - obs_sceneitem_t *sceneItem) + obs_sceneitem_t *sceneItem) { VisibilityItemWidget *baseWidget = new VisibilityItemWidget(sceneItem); diff --git a/UI/visibility-item-widget.hpp b/UI/visibility-item-widget.hpp index 80c46db..659f200 100644 --- a/UI/visibility-item-widget.hpp +++ b/UI/visibility-item-widget.hpp @@ -61,10 +61,10 @@ public: VisibilityItemDelegate(QObject *parent = nullptr); void paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const override; + const QModelIndex &index) const override; }; void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item, - obs_source_t *source); + obs_source_t *source); void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item, - obs_sceneitem_t *sceneItem); + obs_sceneitem_t *sceneItem); diff --git a/UI/volume-control.cpp b/UI/volume-control.cpp index 91f1032..35fdb0c 100644 --- a/UI/volume-control.cpp +++ b/UI/volume-control.cpp @@ -21,35 +21,35 @@ QWeakPointer VolumeMeter::updateTimer; void VolControl::OBSVolumeChanged(void *data, float db) { Q_UNUSED(db); - VolControl *volControl = static_cast(data); + VolControl *volControl = static_cast(data); QMetaObject::invokeMethod(volControl, "VolumeChanged"); } void VolControl::OBSVolumeLevel(void *data, - const float magnitude[MAX_AUDIO_CHANNELS], - const float peak[MAX_AUDIO_CHANNELS], - const float inputPeak[MAX_AUDIO_CHANNELS]) + const float magnitude[MAX_AUDIO_CHANNELS], + const float peak[MAX_AUDIO_CHANNELS], + const float inputPeak[MAX_AUDIO_CHANNELS]) { - VolControl *volControl = static_cast(data); + VolControl *volControl = static_cast(data); volControl->volMeter->setLevels(magnitude, peak, inputPeak); } void VolControl::OBSVolumeMuted(void *data, calldata_t *calldata) { - VolControl *volControl = static_cast(data); + VolControl *volControl = static_cast(data); bool muted = calldata_bool(calldata, "muted"); QMetaObject::invokeMethod(volControl, "VolumeMuted", - Q_ARG(bool, muted)); + Q_ARG(bool, muted)); } void VolControl::VolumeChanged() { slider->blockSignals(true); - slider->setValue((int) (obs_fader_get_deflection(obs_fader) * - FADER_PRECISION)); + slider->setValue( + (int)(obs_fader_get_deflection(obs_fader) * FADER_PRECISION)); slider->blockSignals(false); updateText(); @@ -74,14 +74,19 @@ void VolControl::SliderChanged(int vol) void VolControl::updateText() { - QString db = QString::number(obs_fader_get_db(obs_fader), 'f', 1) - .append(" dB"); - volLabel->setText(db); + QString text; + float db = obs_fader_get_db(obs_fader); + + if (db < -96.0f) + text = "-inf dB"; + else + text = QString::number(db, 'f', 1).append(" dB"); + + volLabel->setText(text); bool muted = obs_source_muted(source); - const char *accTextLookup = muted - ? "VolControl.SliderMuted" - : "VolControl.SliderUnmuted"; + const char *accTextLookup = muted ? "VolControl.SliderMuted" + : "VolControl.SliderUnmuted"; QString sourceName = obs_source_get_name(source); QString accText = QTStr(accTextLookup).arg(sourceName, db); @@ -115,16 +120,16 @@ void VolControl::setPeakMeterType(enum obs_peak_meter_type peakMeterType) } VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical) - : source (std::move(source_)), - levelTotal (0.0f), - levelCount (0.0f), - obs_fader (obs_fader_create(OBS_FADER_LOG)), - obs_volmeter (obs_volmeter_create(OBS_FADER_LOG)), - vertical (vertical) + : source(std::move(source_)), + levelTotal(0.0f), + levelCount(0.0f), + obs_fader(obs_fader_create(OBS_FADER_LOG)), + obs_volmeter(obs_volmeter_create(OBS_FADER_LOG)), + vertical(vertical) { nameLabel = new QLabel(); - volLabel = new QLabel(); - mute = new MuteCheckBox(); + volLabel = new QLabel(); + mute = new MuteCheckBox(); QString sourceName = obs_source_get_name(source); setObjectName(sourceName); @@ -134,15 +139,15 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical) config->setProperty("themeID", "configIconSmall"); config->setFlat(true); config->setSizePolicy(QSizePolicy::Maximum, - QSizePolicy::Maximum); + QSizePolicy::Maximum); config->setMaximumSize(22, 22); config->setAutoDefault(false); - config->setAccessibleName(QTStr("VolControl.Properties") - .arg(sourceName)); + config->setAccessibleName( + QTStr("VolControl.Properties").arg(sourceName)); - connect(config, &QAbstractButton::clicked, - this, &VolControl::EmitConfigClicked); + connect(config, &QAbstractButton::clicked, this, + &VolControl::EmitConfigClicked); } QVBoxLayout *mainLayout = new QVBoxLayout; @@ -153,10 +158,10 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical) QHBoxLayout *nameLayout = new QHBoxLayout; QHBoxLayout *controlLayout = new QHBoxLayout; QHBoxLayout *volLayout = new QHBoxLayout; - QHBoxLayout *meterLayout = new QHBoxLayout; + QHBoxLayout *meterLayout = new QHBoxLayout; - volMeter = new VolumeMeter(nullptr, obs_volmeter, true); - slider = new SliderIgnoreScroll(Qt::Vertical); + volMeter = new VolumeMeter(nullptr, obs_volmeter, true); + slider = new SliderIgnoreScroll(Qt::Vertical); nameLayout->setAlignment(Qt::AlignCenter); meterLayout->setAlignment(Qt::AlignCenter); @@ -195,18 +200,18 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical) setMaximumWidth(110); } else { - QHBoxLayout *volLayout = new QHBoxLayout; + QHBoxLayout *volLayout = new QHBoxLayout; QHBoxLayout *textLayout = new QHBoxLayout; - QHBoxLayout *botLayout = new QHBoxLayout; + QHBoxLayout *botLayout = new QHBoxLayout; - volMeter = new VolumeMeter(nullptr, obs_volmeter, false); - slider = new SliderIgnoreScroll(Qt::Horizontal); + volMeter = new VolumeMeter(nullptr, obs_volmeter, false); + slider = new SliderIgnoreScroll(Qt::Horizontal); textLayout->setContentsMargins(0, 0, 0, 0); textLayout->addWidget(nameLabel); textLayout->addWidget(volLabel); textLayout->setAlignment(nameLabel, Qt::AlignLeft); - textLayout->setAlignment(volLabel, Qt::AlignRight); + textLayout->setAlignment(volLabel, Qt::AlignRight); volLayout->addWidget(slider); volLayout->addWidget(mute); @@ -229,7 +234,7 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical) setLayout(mainLayout); QFont font = nameLabel->font(); - font.setPointSize(font.pointSize()-1); + font.setPointSize(font.pointSize() - 1); nameLabel->setText(sourceName); nameLabel->setFont(font); @@ -244,13 +249,13 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical) obs_fader_add_callback(obs_fader, OBSVolumeChanged, this); obs_volmeter_add_callback(obs_volmeter, OBSVolumeLevel, this); - signal_handler_connect(obs_source_get_signal_handler(source), - "mute", OBSVolumeMuted, this); + signal_handler_connect(obs_source_get_signal_handler(source), "mute", + OBSVolumeMuted, this); - QWidget::connect(slider, SIGNAL(valueChanged(int)), - this, SLOT(SliderChanged(int))); - QWidget::connect(mute, SIGNAL(clicked(bool)), - this, SLOT(SetMuted(bool))); + QWidget::connect(slider, SIGNAL(valueChanged(int)), this, + SLOT(SliderChanged(int))); + QWidget::connect(mute, SIGNAL(clicked(bool)), this, + SLOT(SetMuted(bool))); obs_fader_attach_source(obs_fader, source); obs_volmeter_attach_source(obs_volmeter, source); @@ -276,8 +281,8 @@ VolControl::~VolControl() obs_fader_remove_callback(obs_fader, OBSVolumeChanged, this); obs_volmeter_remove_callback(obs_volmeter, OBSVolumeLevel, this); - signal_handler_disconnect(obs_source_get_signal_handler(source), - "mute", OBSVolumeMuted, this); + signal_handler_disconnect(obs_source_get_signal_handler(source), "mute", + OBSVolumeMuted, this); obs_fader_destroy(obs_fader); obs_volmeter_destroy(obs_volmeter); @@ -509,6 +514,7 @@ void VolumeMeter::setPeakMeterType(enum obs_peak_meter_type peakMeterType) void VolumeMeter::mousePressEvent(QMouseEvent *event) { setFocus(Qt::MouseFocusReason); + event->accept(); } void VolumeMeter::wheelEvent(QWheelEvent *event) @@ -517,34 +523,33 @@ void VolumeMeter::wheelEvent(QWheelEvent *event) } VolumeMeter::VolumeMeter(QWidget *parent, obs_volmeter_t *obs_volmeter, - bool vertical) - : QWidget(parent), obs_volmeter(obs_volmeter), - vertical(vertical) + bool vertical) + : QWidget(parent), obs_volmeter(obs_volmeter), vertical(vertical) { // Use a font that can be rendered small. tickFont = QFont("Arial"); tickFont.setPixelSize(7); // Default meter color settings, they only show if // there is no stylesheet, do not remove. - backgroundNominalColor.setRgb(0x26, 0x7f, 0x26); // Dark green - backgroundWarningColor.setRgb(0x7f, 0x7f, 0x26); // Dark yellow - backgroundErrorColor.setRgb(0x7f, 0x26, 0x26); // Dark red - foregroundNominalColor.setRgb(0x4c, 0xff, 0x4c); // Bright green - foregroundWarningColor.setRgb(0xff, 0xff, 0x4c); // Bright yellow - foregroundErrorColor.setRgb(0xff, 0x4c, 0x4c); // Bright red - clipColor.setRgb(0xff, 0xff, 0xff); // Bright white - magnitudeColor.setRgb(0x00, 0x00, 0x00); // Black - majorTickColor.setRgb(0xff, 0xff, 0xff); // Black - minorTickColor.setRgb(0xcc, 0xcc, 0xcc); // Black - minimumLevel = -60.0; // -60 dB - warningLevel = -20.0; // -20 dB - errorLevel = -9.0; // -9 dB - clipLevel = -0.5; // -0.5 dB - minimumInputLevel = -50.0; // -50 dB - peakDecayRate = 11.76; // 20 dB / 1.7 sec - magnitudeIntegrationTime = 0.3; // 99% in 300 ms - peakHoldDuration = 20.0; // 20 seconds - inputPeakHoldDuration = 1.0; // 1 second + backgroundNominalColor.setRgb(0x26, 0x7f, 0x26); // Dark green + backgroundWarningColor.setRgb(0x7f, 0x7f, 0x26); // Dark yellow + backgroundErrorColor.setRgb(0x7f, 0x26, 0x26); // Dark red + foregroundNominalColor.setRgb(0x4c, 0xff, 0x4c); // Bright green + foregroundWarningColor.setRgb(0xff, 0xff, 0x4c); // Bright yellow + foregroundErrorColor.setRgb(0xff, 0x4c, 0x4c); // Bright red + clipColor.setRgb(0xff, 0xff, 0xff); // Bright white + magnitudeColor.setRgb(0x00, 0x00, 0x00); // Black + majorTickColor.setRgb(0xff, 0xff, 0xff); // Black + minorTickColor.setRgb(0xcc, 0xcc, 0xcc); // Black + minimumLevel = -60.0; // -60 dB + warningLevel = -20.0; // -20 dB + errorLevel = -9.0; // -9 dB + clipLevel = -0.5; // -0.5 dB + minimumInputLevel = -50.0; // -50 dB + peakDecayRate = 11.76; // 20 dB / 1.7 sec + magnitudeIntegrationTime = 0.3; // 99% in 300 ms + peakHoldDuration = 20.0; // 20 seconds + inputPeakHoldDuration = 1.0; // 1 second channels = (int)audio_output_get_channels(obs_get_audio()); @@ -566,8 +571,8 @@ VolumeMeter::~VolumeMeter() } void VolumeMeter::setLevels(const float magnitude[MAX_AUDIO_CHANNELS], - const float peak[MAX_AUDIO_CHANNELS], - const float inputPeak[MAX_AUDIO_CHANNELS]) + const float peak[MAX_AUDIO_CHANNELS], + const float inputPeak[MAX_AUDIO_CHANNELS]) { uint64_t ts = os_gettime_ns(); QMutexLocker locker(&dataMutex); @@ -632,11 +637,12 @@ inline bool VolumeMeter::detectIdle(uint64_t ts) } } -inline void VolumeMeter::calculateBallisticsForChannel(int channelNr, - uint64_t ts, qreal timeSinceLastRedraw) +inline void +VolumeMeter::calculateBallisticsForChannel(int channelNr, uint64_t ts, + qreal timeSinceLastRedraw) { if (currentPeak[channelNr] >= displayPeak[channelNr] || - isnan(displayPeak[channelNr])) { + isnan(displayPeak[channelNr])) { // Attack of peak is immediate. displayPeak[channelNr] = currentPeak[channelNr]; } else { @@ -645,11 +651,11 @@ inline void VolumeMeter::calculateBallisticsForChannel(int channelNr, // 24 dB / 2.8 seconds for Slow Profile (Type II PPM) float decay = float(peakDecayRate * timeSinceLastRedraw); displayPeak[channelNr] = CLAMP(displayPeak[channelNr] - decay, - currentPeak[channelNr], 0); + currentPeak[channelNr], 0); } if (currentPeak[channelNr] >= displayPeakHold[channelNr] || - !isfinite(displayPeakHold[channelNr])) { + !isfinite(displayPeakHold[channelNr])) { // Attack of peak-hold is immediate, but keep track // when it was last updated. displayPeakHold[channelNr] = currentPeak[channelNr]; @@ -657,8 +663,10 @@ inline void VolumeMeter::calculateBallisticsForChannel(int channelNr, } else { // The peak and hold falls back to peak // after 20 seconds. - qreal timeSinceLastPeak = (uint64_t)(ts - - displayPeakHoldLastUpdateTime[channelNr]) * 0.000000001; + qreal timeSinceLastPeak = + (uint64_t)(ts - + displayPeakHoldLastUpdateTime[channelNr]) * + 0.000000001; if (timeSinceLastPeak > peakHoldDuration) { displayPeakHold[channelNr] = currentPeak[channelNr]; displayPeakHoldLastUpdateTime[channelNr] = ts; @@ -666,21 +674,22 @@ inline void VolumeMeter::calculateBallisticsForChannel(int channelNr, } if (currentInputPeak[channelNr] >= displayInputPeakHold[channelNr] || - !isfinite(displayInputPeakHold[channelNr])) { + !isfinite(displayInputPeakHold[channelNr])) { // Attack of peak-hold is immediate, but keep track // when it was last updated. displayInputPeakHold[channelNr] = currentInputPeak[channelNr]; displayInputPeakHoldLastUpdateTime[channelNr] = ts; } else { // The peak and hold falls back to peak after 1 second. - qreal timeSinceLastPeak = (uint64_t)(ts - - displayInputPeakHoldLastUpdateTime[channelNr]) * + qreal timeSinceLastPeak = + (uint64_t)( + ts - + displayInputPeakHoldLastUpdateTime[channelNr]) * 0.000000001; if (timeSinceLastPeak > inputPeakHoldDuration) { displayInputPeakHold[channelNr] = currentInputPeak[channelNr]; - displayInputPeakHoldLastUpdateTime[channelNr] = - ts; + displayInputPeakHoldLastUpdateTime[channelNr] = ts; } } @@ -692,27 +701,29 @@ inline void VolumeMeter::calculateBallisticsForChannel(int channelNr, // A VU meter will integrate to the new value to 99% in 300 ms. // The calculation here is very simplified and is more accurate // with higher frame-rate. - float attack = float((currentMagnitude[channelNr] - - displayMagnitude[channelNr]) * - (timeSinceLastRedraw / - magnitudeIntegrationTime) * 0.99); - displayMagnitude[channelNr] = CLAMP(displayMagnitude[channelNr] - + attack, (float)minimumLevel, 0); + float attack = + float((currentMagnitude[channelNr] - + displayMagnitude[channelNr]) * + (timeSinceLastRedraw / magnitudeIntegrationTime) * + 0.99); + displayMagnitude[channelNr] = + CLAMP(displayMagnitude[channelNr] + attack, + (float)minimumLevel, 0); } } inline void VolumeMeter::calculateBallistics(uint64_t ts, - qreal timeSinceLastRedraw) + qreal timeSinceLastRedraw) { QMutexLocker locker(&dataMutex); for (int channelNr = 0; channelNr < MAX_AUDIO_CHANNELS; channelNr++) calculateBallisticsForChannel(channelNr, ts, - timeSinceLastRedraw); + timeSinceLastRedraw); } void VolumeMeter::paintInputMeter(QPainter &painter, int x, int y, int width, - int height, float peakHold) + int height, float peakHold) { QMutexLocker locker(&dataMutex); QColor color; @@ -732,7 +743,7 @@ void VolumeMeter::paintInputMeter(QPainter &painter, int x, int y, int width, } void VolumeMeter::paintHTicks(QPainter &painter, int x, int y, int width, - int height) + int height) { qreal scale = width / minimumLevel; @@ -740,7 +751,7 @@ void VolumeMeter::paintHTicks(QPainter &painter, int x, int y, int width, painter.setPen(majorTickColor); // Draw major tick lines and numeric indicators. - for (int i = 0; i >= minimumLevel; i-= 5) { + for (int i = 0; i >= minimumLevel; i -= 5) { int position = int(x + width - (i * scale) - 1); QString str = QString::number(i); @@ -768,7 +779,7 @@ void VolumeMeter::paintVTicks(QPainter &painter, int x, int y, int height) painter.setPen(majorTickColor); // Draw major tick lines and numeric indicators. - for (int i = 0; i >= minimumLevel; i-= 5) { + for (int i = 0; i >= minimumLevel; i -= 5) { int position = y + int((i * scale) - 1); QString str = QString::number(i); @@ -798,22 +809,23 @@ void VolumeMeter::ClipEnding() } void VolumeMeter::paintHMeter(QPainter &painter, int x, int y, int width, - int height, float magnitude, float peak, float peakHold) + int height, float magnitude, float peak, + float peakHold) { qreal scale = width / minimumLevel; QMutexLocker locker(&dataMutex); - int minimumPosition = x + 0; - int maximumPosition = x + width; - int magnitudePosition = int(x + width - (magnitude * scale)); - int peakPosition = int(x + width - (peak * scale)); - int peakHoldPosition = int(x + width - (peakHold * scale)); - int warningPosition = int(x + width - (warningLevel * scale)); - int errorPosition = int(x + width - (errorLevel * scale)); + int minimumPosition = x + 0; + int maximumPosition = x + width; + int magnitudePosition = int(x + width - (magnitude * scale)); + int peakPosition = int(x + width - (peak * scale)); + int peakHoldPosition = int(x + width - (peakHold * scale)); + int warningPosition = int(x + width - (warningLevel * scale)); + int errorPosition = int(x + width - (errorLevel * scale)); - int nominalLength = warningPosition - minimumPosition; - int warningLength = errorPosition - warningPosition; - int errorLength = maximumPosition - errorPosition; + int nominalLength = warningPosition - minimumPosition; + int warningLength = errorPosition - warningPosition; + int errorLength = maximumPosition - errorPosition; locker.unlock(); if (clipping) { @@ -822,87 +834,89 @@ void VolumeMeter::paintHMeter(QPainter &painter, int x, int y, int width, if (peakPosition < minimumPosition) { painter.fillRect(minimumPosition, y, nominalLength, height, - backgroundNominalColor); + backgroundNominalColor); painter.fillRect(warningPosition, y, warningLength, height, - backgroundWarningColor); + backgroundWarningColor); painter.fillRect(errorPosition, y, errorLength, height, - backgroundErrorColor); + backgroundErrorColor); } else if (peakPosition < warningPosition) { - painter.fillRect(minimumPosition, y, peakPosition - - minimumPosition, height, - foregroundNominalColor); - painter.fillRect(peakPosition, y, warningPosition - - peakPosition, height, backgroundNominalColor); + painter.fillRect(minimumPosition, y, + peakPosition - minimumPosition, height, + foregroundNominalColor); + painter.fillRect(peakPosition, y, + warningPosition - peakPosition, height, + backgroundNominalColor); painter.fillRect(warningPosition, y, warningLength, height, - backgroundWarningColor); + backgroundWarningColor); painter.fillRect(errorPosition, y, errorLength, height, - backgroundErrorColor); + backgroundErrorColor); } else if (peakPosition < errorPosition) { painter.fillRect(minimumPosition, y, nominalLength, height, - foregroundNominalColor); + foregroundNominalColor); painter.fillRect(warningPosition, y, - peakPosition - warningPosition, height, - foregroundWarningColor); - painter.fillRect(peakPosition, y, errorPosition - - peakPosition, height, backgroundWarningColor); + peakPosition - warningPosition, height, + foregroundWarningColor); + painter.fillRect(peakPosition, y, errorPosition - peakPosition, + height, backgroundWarningColor); painter.fillRect(errorPosition, y, errorLength, height, - backgroundErrorColor); + backgroundErrorColor); } else if (peakPosition < maximumPosition) { painter.fillRect(minimumPosition, y, nominalLength, height, - foregroundNominalColor); + foregroundNominalColor); painter.fillRect(warningPosition, y, warningLength, height, - foregroundWarningColor); + foregroundWarningColor); painter.fillRect(errorPosition, y, peakPosition - errorPosition, - height, foregroundErrorColor); + height, foregroundErrorColor); painter.fillRect(peakPosition, y, - maximumPosition - peakPosition, height, - backgroundErrorColor); + maximumPosition - peakPosition, height, + backgroundErrorColor); } else { if (!clipping) { QTimer::singleShot(CLIP_FLASH_DURATION_MS, this, - SLOT(ClipEnding())); + SLOT(ClipEnding())); clipping = true; } int end = errorLength + warningLength + nominalLength; painter.fillRect(minimumPosition, y, end, height, - QBrush(foregroundErrorColor)); + QBrush(foregroundErrorColor)); } if (peakHoldPosition - 3 < minimumPosition) - ;// Peak-hold below minimum, no drawing. + ; // Peak-hold below minimum, no drawing. else if (peakHoldPosition < warningPosition) painter.fillRect(peakHoldPosition - 3, y, 3, height, - foregroundNominalColor); + foregroundNominalColor); else if (peakHoldPosition < errorPosition) painter.fillRect(peakHoldPosition - 3, y, 3, height, - foregroundWarningColor); + foregroundWarningColor); else painter.fillRect(peakHoldPosition - 3, y, 3, height, - foregroundErrorColor); + foregroundErrorColor); if (magnitudePosition - 3 >= minimumPosition) painter.fillRect(magnitudePosition - 3, y, 3, height, - magnitudeColor); + magnitudeColor); } void VolumeMeter::paintVMeter(QPainter &painter, int x, int y, int width, - int height, float magnitude, float peak, float peakHold) + int height, float magnitude, float peak, + float peakHold) { qreal scale = height / minimumLevel; QMutexLocker locker(&dataMutex); - int minimumPosition = y + 0; - int maximumPosition = y + height; - int magnitudePosition = int(y + height - (magnitude * scale)); - int peakPosition = int(y + height - (peak * scale)); - int peakHoldPosition = int(y + height - (peakHold * scale)); - int warningPosition = int(y + height - (warningLevel * scale)); - int errorPosition = int(y + height - (errorLevel * scale)); + int minimumPosition = y + 0; + int maximumPosition = y + height; + int magnitudePosition = int(y + height - (magnitude * scale)); + int peakPosition = int(y + height - (peak * scale)); + int peakHoldPosition = int(y + height - (peakHold * scale)); + int warningPosition = int(y + height - (warningLevel * scale)); + int errorPosition = int(y + height - (errorLevel * scale)); - int nominalLength = warningPosition - minimumPosition; - int warningLength = errorPosition - warningPosition; - int errorLength = maximumPosition - errorPosition; + int nominalLength = warningPosition - minimumPosition; + int warningLength = errorPosition - warningPosition; + int errorLength = maximumPosition - errorPosition; locker.unlock(); if (clipping) { @@ -911,65 +925,71 @@ void VolumeMeter::paintVMeter(QPainter &painter, int x, int y, int width, if (peakPosition < minimumPosition) { painter.fillRect(x, minimumPosition, width, nominalLength, - backgroundNominalColor); + backgroundNominalColor); painter.fillRect(x, warningPosition, width, warningLength, - backgroundWarningColor); + backgroundWarningColor); painter.fillRect(x, errorPosition, width, errorLength, - backgroundErrorColor); + backgroundErrorColor); } else if (peakPosition < warningPosition) { - painter.fillRect(x, minimumPosition, width, peakPosition - - minimumPosition, foregroundNominalColor); - painter.fillRect(x, peakPosition, width, warningPosition - - peakPosition, backgroundNominalColor); + painter.fillRect(x, minimumPosition, width, + peakPosition - minimumPosition, + foregroundNominalColor); + painter.fillRect(x, peakPosition, width, + warningPosition - peakPosition, + backgroundNominalColor); painter.fillRect(x, warningPosition, width, warningLength, - backgroundWarningColor); + backgroundWarningColor); painter.fillRect(x, errorPosition, width, errorLength, - backgroundErrorColor); + backgroundErrorColor); } else if (peakPosition < errorPosition) { - painter.fillRect(x,minimumPosition, width, nominalLength, - foregroundNominalColor); - painter.fillRect(x, warningPosition, width, peakPosition - - warningPosition, foregroundWarningColor); - painter.fillRect(x, peakPosition, width, errorPosition - - peakPosition, backgroundWarningColor); + painter.fillRect(x, minimumPosition, width, nominalLength, + foregroundNominalColor); + painter.fillRect(x, warningPosition, width, + peakPosition - warningPosition, + foregroundWarningColor); + painter.fillRect(x, peakPosition, width, + errorPosition - peakPosition, + backgroundWarningColor); painter.fillRect(x, errorPosition, width, errorLength, - backgroundErrorColor); + backgroundErrorColor); } else if (peakPosition < maximumPosition) { painter.fillRect(x, minimumPosition, width, nominalLength, - foregroundNominalColor); + foregroundNominalColor); painter.fillRect(x, warningPosition, width, warningLength, - foregroundWarningColor); - painter.fillRect(x, errorPosition, width, peakPosition - - errorPosition, foregroundErrorColor); - painter.fillRect(x, peakPosition, width, maximumPosition - - peakPosition, backgroundErrorColor); + foregroundWarningColor); + painter.fillRect(x, errorPosition, width, + peakPosition - errorPosition, + foregroundErrorColor); + painter.fillRect(x, peakPosition, width, + maximumPosition - peakPosition, + backgroundErrorColor); } else { if (!clipping) { QTimer::singleShot(CLIP_FLASH_DURATION_MS, this, - SLOT(ClipEnding())); + SLOT(ClipEnding())); clipping = true; } int end = errorLength + warningLength + nominalLength; painter.fillRect(x, minimumPosition, width, end, - QBrush(foregroundErrorColor)); + QBrush(foregroundErrorColor)); } if (peakHoldPosition - 3 < minimumPosition) - ;// Peak-hold below minimum, no drawing. + ; // Peak-hold below minimum, no drawing. else if (peakHoldPosition < warningPosition) painter.fillRect(x, peakHoldPosition - 3, width, 3, - foregroundNominalColor); + foregroundNominalColor); else if (peakHoldPosition < errorPosition) painter.fillRect(x, peakHoldPosition - 3, width, 3, - foregroundWarningColor); + foregroundWarningColor); else painter.fillRect(x, peakHoldPosition - 3, width, 3, - foregroundErrorColor); + foregroundErrorColor); if (magnitudePosition - 3 >= minimumPosition) painter.fillRect(x, magnitudePosition - 3, width, 3, - magnitudeColor); + magnitudeColor); } void VolumeMeter::paintEvent(QPaintEvent *event) @@ -978,7 +998,7 @@ void VolumeMeter::paintEvent(QPaintEvent *event) qreal timeSinceLastRedraw = (ts - lastRedrawTime) * 0.000000001; const QRect rect = event->region().boundingRect(); - int width = rect.width(); + int width = rect.width(); int height = rect.height(); handleChannelCofigurationChange(); @@ -992,7 +1012,7 @@ void VolumeMeter::paintEvent(QPaintEvent *event) else tickPaintCacheSize = QSize(width, 9); if (tickPaintCache == nullptr || - tickPaintCache->size() != tickPaintCacheSize) { + tickPaintCache->size() != tickPaintCacheSize) { delete tickPaintCache; tickPaintCache = new QPixmap(tickPaintCacheSize); @@ -1004,11 +1024,11 @@ void VolumeMeter::paintEvent(QPaintEvent *event) tickPainter.translate(0, height); tickPainter.scale(1, -1); paintVTicks(tickPainter, 0, 11, - tickPaintCacheSize.height() - 11); + tickPaintCacheSize.height() - 11); } else { paintHTicks(tickPainter, 6, 0, - tickPaintCacheSize.width() - 6, - tickPaintCacheSize.height()); + tickPaintCacheSize.width() - 6, + tickPaintCacheSize.height()); } tickPainter.end(); } @@ -1020,29 +1040,29 @@ void VolumeMeter::paintEvent(QPaintEvent *event) painter.translate(0, height); painter.scale(1, -1); painter.drawPixmap(displayNrAudioChannels * 4 - 1, 7, - *tickPaintCache); + *tickPaintCache); } else { painter.drawPixmap(0, height - 9, *tickPaintCache); } for (int channelNr = 0; channelNr < displayNrAudioChannels; - channelNr++) { + channelNr++) { - int channelNrFixed = (displayNrAudioChannels == 1 && - channels > 2) - ? 2 - : channelNr; + int channelNrFixed = + (displayNrAudioChannels == 1 && channels > 2) + ? 2 + : channelNr; if (vertical) paintVMeter(painter, channelNr * 4, 8, 3, height - 10, - displayMagnitude[channelNrFixed], - displayPeak[channelNrFixed], - displayPeakHold[channelNrFixed]); + displayMagnitude[channelNrFixed], + displayPeak[channelNrFixed], + displayPeakHold[channelNrFixed]); else paintHMeter(painter, 5, channelNr * 4, width - 5, 3, - displayMagnitude[channelNrFixed], - displayPeak[channelNrFixed], - displayPeakHold[channelNrFixed]); + displayMagnitude[channelNrFixed], + displayPeak[channelNrFixed], + displayPeakHold[channelNrFixed]); if (idle) continue; @@ -1071,7 +1091,7 @@ void VolumeMeterTimer::RemoveVolControl(VolumeMeter *meter) volumeMeters.removeOne(meter); } -void VolumeMeterTimer::timerEvent(QTimerEvent*) +void VolumeMeterTimer::timerEvent(QTimerEvent *) { for (VolumeMeter *meter : volumeMeters) meter->update(); diff --git a/UI/volume-control.hpp b/UI/volume-control.hpp index e24ef5c..b357fe1 100644 --- a/UI/volume-control.hpp +++ b/UI/volume-control.hpp @@ -11,74 +11,55 @@ class QPushButton; class VolumeMeterTimer; -class VolumeMeter : public QWidget -{ +class VolumeMeter : public QWidget { Q_OBJECT - Q_PROPERTY(QColor backgroundNominalColor - READ getBackgroundNominalColor - WRITE setBackgroundNominalColor DESIGNABLE true) - Q_PROPERTY(QColor backgroundWarningColor - READ getBackgroundWarningColor - WRITE setBackgroundWarningColor DESIGNABLE true) - Q_PROPERTY(QColor backgroundErrorColor - READ getBackgroundErrorColor - WRITE setBackgroundErrorColor DESIGNABLE true) - Q_PROPERTY(QColor foregroundNominalColor - READ getForegroundNominalColor - WRITE setForegroundNominalColor DESIGNABLE true) - Q_PROPERTY(QColor foregroundWarningColor - READ getForegroundWarningColor - WRITE setForegroundWarningColor DESIGNABLE true) - Q_PROPERTY(QColor foregroundErrorColor - READ getForegroundErrorColor - WRITE setForegroundErrorColor DESIGNABLE true) - Q_PROPERTY(QColor clipColor - READ getClipColor - WRITE setClipColor DESIGNABLE true) - Q_PROPERTY(QColor magnitudeColor - READ getMagnitudeColor - WRITE setMagnitudeColor DESIGNABLE true) - Q_PROPERTY(QColor majorTickColor - READ getMajorTickColor - WRITE setMajorTickColor DESIGNABLE true) - Q_PROPERTY(QColor minorTickColor - READ getMinorTickColor - WRITE setMinorTickColor DESIGNABLE true) + Q_PROPERTY(QColor backgroundNominalColor READ getBackgroundNominalColor + WRITE setBackgroundNominalColor DESIGNABLE true) + Q_PROPERTY(QColor backgroundWarningColor READ getBackgroundWarningColor + WRITE setBackgroundWarningColor DESIGNABLE true) + Q_PROPERTY(QColor backgroundErrorColor READ getBackgroundErrorColor + WRITE setBackgroundErrorColor DESIGNABLE true) + Q_PROPERTY(QColor foregroundNominalColor READ getForegroundNominalColor + WRITE setForegroundNominalColor DESIGNABLE true) + Q_PROPERTY(QColor foregroundWarningColor READ getForegroundWarningColor + WRITE setForegroundWarningColor DESIGNABLE true) + Q_PROPERTY(QColor foregroundErrorColor READ getForegroundErrorColor + WRITE setForegroundErrorColor DESIGNABLE true) + Q_PROPERTY(QColor clipColor READ getClipColor WRITE setClipColor + DESIGNABLE true) + Q_PROPERTY(QColor magnitudeColor READ getMagnitudeColor WRITE + setMagnitudeColor DESIGNABLE true) + Q_PROPERTY(QColor majorTickColor READ getMajorTickColor WRITE + setMajorTickColor DESIGNABLE true) + Q_PROPERTY(QColor minorTickColor READ getMinorTickColor WRITE + setMinorTickColor DESIGNABLE true) // Levels are denoted in dBFS. - Q_PROPERTY(qreal minimumLevel - READ getMinimumLevel - WRITE setMinimumLevel DESIGNABLE true) - Q_PROPERTY(qreal warningLevel - READ getWarningLevel - WRITE setWarningLevel DESIGNABLE true) - Q_PROPERTY(qreal errorLevel - READ getErrorLevel - WRITE setErrorLevel DESIGNABLE true) - Q_PROPERTY(qreal clipLevel - READ getClipLevel - WRITE setClipLevel DESIGNABLE true) - Q_PROPERTY(qreal minimumInputLevel - READ getMinimumInputLevel - WRITE setMinimumInputLevel DESIGNABLE true) + Q_PROPERTY(qreal minimumLevel READ getMinimumLevel WRITE setMinimumLevel + DESIGNABLE true) + Q_PROPERTY(qreal warningLevel READ getWarningLevel WRITE setWarningLevel + DESIGNABLE true) + Q_PROPERTY(qreal errorLevel READ getErrorLevel WRITE setErrorLevel + DESIGNABLE true) + Q_PROPERTY(qreal clipLevel READ getClipLevel WRITE setClipLevel + DESIGNABLE true) + Q_PROPERTY(qreal minimumInputLevel READ getMinimumInputLevel WRITE + setMinimumInputLevel DESIGNABLE true) // Rates are denoted in dB/second. - Q_PROPERTY(qreal peakDecayRate - READ getPeakDecayRate - WRITE setPeakDecayRate DESIGNABLE true) + Q_PROPERTY(qreal peakDecayRate READ getPeakDecayRate WRITE + setPeakDecayRate DESIGNABLE true) // Time in seconds for the VU meter to integrate over. - Q_PROPERTY(qreal magnitudeIntegrationTime - READ getMagnitudeIntegrationTime - WRITE setMagnitudeIntegrationTime DESIGNABLE true) + Q_PROPERTY( + qreal magnitudeIntegrationTime READ getMagnitudeIntegrationTime + WRITE setMagnitudeIntegrationTime DESIGNABLE true) // Duration is denoted in seconds. - Q_PROPERTY(qreal peakHoldDuration - READ getPeakHoldDuration - WRITE setPeakHoldDuration DESIGNABLE true) - Q_PROPERTY(qreal inputPeakHoldDuration - READ getInputPeakHoldDuration - WRITE setInputPeakHoldDuration DESIGNABLE true) + Q_PROPERTY(qreal peakHoldDuration READ getPeakHoldDuration WRITE + setPeakHoldDuration DESIGNABLE true) + Q_PROPERTY(qreal inputPeakHoldDuration READ getInputPeakHoldDuration + WRITE setInputPeakHoldDuration DESIGNABLE true) private slots: void ClipEnding(); @@ -92,18 +73,18 @@ private: inline void handleChannelCofigurationChange(); inline bool detectIdle(uint64_t ts); inline void calculateBallistics(uint64_t ts, - qreal timeSinceLastRedraw=0.0); - inline void calculateBallisticsForChannel(int channelNr, - uint64_t ts, qreal timeSinceLastRedraw); + qreal timeSinceLastRedraw = 0.0); + inline void calculateBallisticsForChannel(int channelNr, uint64_t ts, + qreal timeSinceLastRedraw); void paintInputMeter(QPainter &painter, int x, int y, int width, - int height, float peakHold); + int height, float peakHold); void paintHMeter(QPainter &painter, int x, int y, int width, int height, - float magnitude, float peak, float peakHold); + float magnitude, float peak, float peakHold); void paintHTicks(QPainter &painter, int x, int y, int width, - int height); + int height); void paintVMeter(QPainter &painter, int x, int y, int width, int height, - float magnitude, float peak, float peakHold); + float magnitude, float peak, float peakHold); void paintVTicks(QPainter &painter, int x, int y, int height); QMutex dataMutex; @@ -150,14 +131,13 @@ private: public: explicit VolumeMeter(QWidget *parent = nullptr, - obs_volmeter_t *obs_volmeter = nullptr, - bool vertical = false); + obs_volmeter_t *obs_volmeter = nullptr, + bool vertical = false); ~VolumeMeter(); - void setLevels( - const float magnitude[MAX_AUDIO_CHANNELS], - const float peak[MAX_AUDIO_CHANNELS], - const float inputPeak[MAX_AUDIO_CHANNELS]); + void setLevels(const float magnitude[MAX_AUDIO_CHANNELS], + const float peak[MAX_AUDIO_CHANNELS], + const float inputPeak[MAX_AUDIO_CHANNELS]); QColor getBackgroundNominalColor() const; void setBackgroundNominalColor(QColor c); @@ -216,7 +196,7 @@ public: protected: void timerEvent(QTimerEvent *event) override; - QList volumeMeters; + QList volumeMeters; }; class QLabel; @@ -228,23 +208,23 @@ class VolControl : public QWidget { private: OBSSource source; - QLabel *nameLabel; - QLabel *volLabel; - VolumeMeter *volMeter; - QSlider *slider; - MuteCheckBox *mute; - QPushButton *config = nullptr; - float levelTotal; - float levelCount; - obs_fader_t *obs_fader; - obs_volmeter_t *obs_volmeter; - bool vertical; + QLabel *nameLabel; + QLabel *volLabel; + VolumeMeter *volMeter; + QSlider *slider; + MuteCheckBox *mute; + QPushButton *config = nullptr; + float levelTotal; + float levelCount; + obs_fader_t *obs_fader; + obs_volmeter_t *obs_volmeter; + bool vertical; static void OBSVolumeChanged(void *param, float db); static void OBSVolumeLevel(void *data, - const float magnitude[MAX_AUDIO_CHANNELS], - const float peak[MAX_AUDIO_CHANNELS], - const float inputPeak[MAX_AUDIO_CHANNELS]); + const float magnitude[MAX_AUDIO_CHANNELS], + const float peak[MAX_AUDIO_CHANNELS], + const float inputPeak[MAX_AUDIO_CHANNELS]); static void OBSVolumeMuted(void *data, calldata_t *calldata); void EmitConfigClicked(); @@ -262,10 +242,10 @@ signals: public: explicit VolControl(OBSSource source, bool showConfig = false, - bool vertical = false); + bool vertical = false); ~VolControl(); - inline obs_source_t *GetSource() const {return source;} + inline obs_source_t *GetSource() const { return source; } QString GetName() const; void SetName(const QString &newName); diff --git a/UI/win-update/update-window.cpp b/UI/win-update/update-window.cpp index 9c2dcf7..5a868bc 100644 --- a/UI/win-update/update-window.cpp +++ b/UI/win-update/update-window.cpp @@ -2,10 +2,9 @@ #include "obs-app.hpp" OBSUpdate::OBSUpdate(QWidget *parent, bool manualUpdate, const QString &text) - : QDialog (parent, Qt::WindowSystemMenuHint | - Qt::WindowTitleHint | - Qt::WindowCloseButtonHint), - ui (new Ui_OBSUpdate) + : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | + Qt::WindowCloseButtonHint), + ui(new Ui_OBSUpdate) { ui->setupUi(this); ui->text->setHtml(text); diff --git a/UI/win-update/update-window.hpp b/UI/win-update/update-window.hpp index 361e730..8c26976 100644 --- a/UI/win-update/update-window.hpp +++ b/UI/win-update/update-window.hpp @@ -9,11 +9,7 @@ class OBSUpdate : public QDialog { Q_OBJECT public: - enum ReturnVal { - No, - Yes, - Skip - }; + enum ReturnVal { No, Yes, Skip }; OBSUpdate(QWidget *parent, bool manualUpdate, const QString &text); diff --git a/UI/win-update/updater/hash.cpp b/UI/win-update/updater/hash.cpp index 73863a5..936d84b 100644 --- a/UI/win-update/updater/hash.cpp +++ b/UI/win-update/updater/hash.cpp @@ -26,7 +26,7 @@ void HashToString(const uint8_t *in, wchar_t *out) const wchar_t alphabet[] = L"0123456789abcdef"; for (int i = 0; i != BLAKE2_HASH_LENGTH; ++i) { - out[2 * i] = alphabet[in[i] / 16]; + out[2 * i] = alphabet[in[i] / 16]; out[2 * i + 1] = alphabet[in[i] % 16]; } @@ -35,7 +35,7 @@ void HashToString(const uint8_t *in, wchar_t *out) void StringToHash(const wchar_t *in, BYTE *out) { - int temp; + unsigned int temp; for (int i = 0; i < BLAKE2_HASH_LENGTH; i++) { swscanf_s(in + i * 2, L"%02x", &temp); @@ -50,7 +50,7 @@ bool CalculateFileHash(const wchar_t *path, BYTE *hash) return false; WinHandle handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, - nullptr, OPEN_EXISTING, 0, nullptr); + nullptr, OPEN_EXISTING, 0, nullptr); if (handle == INVALID_HANDLE_VALUE) return false; @@ -60,7 +60,7 @@ bool CalculateFileHash(const wchar_t *path, BYTE *hash) for (;;) { DWORD read = 0; if (!ReadFile(handle, buf.data(), (DWORD)buf.size(), &read, - nullptr)) + nullptr)) return false; if (!read) diff --git a/UI/win-update/updater/http.cpp b/UI/win-update/updater/http.cpp index 04ef58a..ce10916 100644 --- a/UI/win-update/updater/http.cpp +++ b/UI/win-update/updater/http.cpp @@ -20,7 +20,7 @@ using namespace std; -#define MAX_BUF_SIZE 262144 +#define MAX_BUF_SIZE 262144 #define READ_BUF_SIZE 32768 /* ------------------------------------------------------------------------ */ @@ -36,8 +36,8 @@ public: inflateEnd(&strm); } - inline operator z_stream*() {return &strm;} - inline z_stream *operator->() {return &strm;} + inline operator z_stream *() { return &strm; } + inline z_stream *operator->() { return &strm; } inline bool inflate() { @@ -50,14 +50,15 @@ public: /* ------------------------------------------------------------------------ */ static bool ReadZippedHTTPData(string &responseBuf, z_stream *strm, - string &zipBuf, const uint8_t *buffer, DWORD outSize) + string &zipBuf, const uint8_t *buffer, + DWORD outSize) { strm->avail_in = outSize; - strm->next_in = buffer; + strm->next_in = buffer; do { strm->avail_out = (uInt)zipBuf.size(); - strm->next_out = (Bytef *)zipBuf.data(); + strm->next_out = (Bytef *)zipBuf.data(); int zret = inflate(strm, Z_NO_FLUSH); if (zret != Z_STREAM_END && zret != Z_OK) @@ -65,7 +66,7 @@ static bool ReadZippedHTTPData(string &responseBuf, z_stream *strm, try { responseBuf.append(zipBuf.data(), - zipBuf.size() - strm->avail_out); + zipBuf.size() - strm->avail_out); } catch (...) { return false; } @@ -75,7 +76,7 @@ static bool ReadZippedHTTPData(string &responseBuf, z_stream *strm, } static bool ReadHTTPData(string &responseBuf, const uint8_t *buffer, - DWORD outSize) + DWORD outSize) { try { responseBuf.append((const char *)buffer, outSize); @@ -85,19 +86,16 @@ static bool ReadHTTPData(string &responseBuf, const uint8_t *buffer, return true; } -bool HTTPPostData(const wchar_t *url, - const BYTE * data, - int dataLen, - const wchar_t *extraHeaders, - int * responseCode, - string & responseBuf) +bool HTTPPostData(const wchar_t *url, const BYTE *data, int dataLen, + const wchar_t *extraHeaders, int *responseCode, + string &responseBuf) { - HttpHandle hSession; - HttpHandle hConnect; - HttpHandle hRequest; - string zipBuf; + HttpHandle hSession; + HttpHandle hConnect; + HttpHandle hRequest; + string zipBuf; URL_COMPONENTS urlComponents = {}; - bool secure = false; + bool secure = false; wchar_t hostName[256]; wchar_t path[1024]; @@ -113,10 +111,10 @@ bool HTTPPostData(const wchar_t *url, urlComponents.dwStructSize = sizeof(urlComponents); - urlComponents.lpszHostName = hostName; + urlComponents.lpszHostName = hostName; urlComponents.dwHostNameLength = _countof(hostName); - urlComponents.lpszUrlPath = path; + urlComponents.lpszUrlPath = path; urlComponents.dwUrlPathLength = _countof(path); WinHttpCrackUrl(url, 0, 0, &urlComponents); @@ -128,22 +126,21 @@ bool HTTPPostData(const wchar_t *url, * connect to server */ hSession = WinHttpOpen(L"OBS Studio Updater/2.1", - WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, - WINHTTP_NO_PROXY_NAME, - WINHTTP_NO_PROXY_BYPASS, - 0); + WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, + WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, + 0); if (!hSession) { *responseCode = -1; return false; } WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS, - (LPVOID)&tlsProtocols, sizeof(tlsProtocols)); + (LPVOID)&tlsProtocols, sizeof(tlsProtocols)); hConnect = WinHttpConnect(hSession, hostName, - secure - ? INTERNET_DEFAULT_HTTPS_PORT - : INTERNET_DEFAULT_HTTP_PORT, 0); + secure ? INTERNET_DEFAULT_HTTPS_PORT + : INTERNET_DEFAULT_HTTP_PORT, + 0); if (!hConnect) { *responseCode = -2; return false; @@ -152,24 +149,19 @@ bool HTTPPostData(const wchar_t *url, /* -------------------------------------- * * request data */ - hRequest = WinHttpOpenRequest(hConnect, - L"POST", - path, - nullptr, - WINHTTP_NO_REFERER, - acceptTypes, - secure - ? WINHTTP_FLAG_SECURE | - WINHTTP_FLAG_REFRESH - : WINHTTP_FLAG_REFRESH); + hRequest = WinHttpOpenRequest(hConnect, L"POST", path, nullptr, + WINHTTP_NO_REFERER, acceptTypes, + secure ? WINHTTP_FLAG_SECURE | + WINHTTP_FLAG_REFRESH + : WINHTTP_FLAG_REFRESH); if (!hRequest) { *responseCode = -3; return false; } bool bResults = !!WinHttpSendRequest(hRequest, extraHeaders, - extraHeaders ? -1 : 0, - (void *)data, dataLen, dataLen, 0); + extraHeaders ? -1 : 0, + (void *)data, dataLen, dataLen, 0); /* -------------------------------------- * * end request */ @@ -185,18 +177,15 @@ bool HTTPPostData(const wchar_t *url, * get headers */ wchar_t encoding[64]; - DWORD encodingLen; + DWORD encodingLen; wchar_t statusCode[8]; - DWORD statusCodeLen; + DWORD statusCodeLen; statusCodeLen = sizeof(statusCode); - if (!WinHttpQueryHeaders(hRequest, - WINHTTP_QUERY_STATUS_CODE, - WINHTTP_HEADER_NAME_BY_INDEX, - &statusCode, - &statusCodeLen, - WINHTTP_NO_HEADER_INDEX)) { + if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE, + WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, + &statusCodeLen, WINHTTP_NO_HEADER_INDEX)) { *responseCode = -4; return false; } else { @@ -204,12 +193,9 @@ bool HTTPPostData(const wchar_t *url, } encodingLen = sizeof(encoding); - if (!WinHttpQueryHeaders(hRequest, - WINHTTP_QUERY_CONTENT_ENCODING, - WINHTTP_HEADER_NAME_BY_INDEX, - encoding, - &encodingLen, - WINHTTP_NO_HEADER_INDEX)) { + if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_ENCODING, + WINHTTP_HEADER_NAME_BY_INDEX, encoding, + &encodingLen, WINHTTP_NO_HEADER_INDEX)) { encoding[0] = 0; if (GetLastError() != ERROR_WINHTTP_HEADER_NOT_FOUND) { *responseCode = -5; @@ -238,11 +224,11 @@ bool HTTPPostData(const wchar_t *url, bool gzip = wcscmp(encoding, L"gzip") == 0; if (gzip) { - strm->zalloc = Z_NULL; - strm->zfree = Z_NULL; - strm->opaque = Z_NULL; + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; strm->avail_in = 0; - strm->next_in = Z_NULL; + strm->next_in = Z_NULL; if (!strm.inflate()) return false; @@ -278,7 +264,7 @@ bool HTTPPostData(const wchar_t *url, dwSize = std::min(dwSize, (DWORD)sizeof(buffer)); if (!WinHttpReadData(hRequest, (void *)buffer, dwSize, - &outSize)) { + &outSize)) { *responseCode = -9; return false; } @@ -311,25 +297,23 @@ bool HTTPPostData(const wchar_t *url, /* ------------------------------------------------------------------------ */ static bool ReadHTTPZippedFile(z_stream *strm, HANDLE updateFile, - string &zipBuf, const uint8_t *buffer, DWORD outSize, - int *responseCode) + string &zipBuf, const uint8_t *buffer, + DWORD outSize, int *responseCode) { strm->avail_in = outSize; - strm->next_in = buffer; + strm->next_in = buffer; do { strm->avail_out = (uInt)zipBuf.size(); - strm->next_out = (Bytef *)zipBuf.data(); + strm->next_out = (Bytef *)zipBuf.data(); int zret = inflate(strm, Z_NO_FLUSH); if (zret != Z_STREAM_END && zret != Z_OK) return false; DWORD written; - if (!WriteFile(updateFile, - zipBuf.data(), - MAX_BUF_SIZE - strm->avail_out, - &written, + if (!WriteFile(updateFile, zipBuf.data(), + MAX_BUF_SIZE - strm->avail_out, &written, nullptr)) { *responseCode = -10; return false; @@ -346,7 +330,7 @@ static bool ReadHTTPZippedFile(z_stream *strm, HANDLE updateFile, } static bool ReadHTTPFile(HANDLE updateFile, const uint8_t *buffer, - DWORD outSize, int *responseCode) + DWORD outSize, int *responseCode) { DWORD written; if (!WriteFile(updateFile, buffer, outSize, &written, nullptr)) { @@ -363,20 +347,18 @@ static bool ReadHTTPFile(HANDLE updateFile, const uint8_t *buffer, return true; } -bool HTTPGetFile(HINTERNET hConnect, - const wchar_t *url, - const wchar_t *outputPath, - const wchar_t *extraHeaders, - int * responseCode) +bool HTTPGetFile(HINTERNET hConnect, const wchar_t *url, + const wchar_t *outputPath, const wchar_t *extraHeaders, + int *responseCode) { HttpHandle hRequest; const wchar_t *acceptTypes[] = {L"*/*", nullptr}; URL_COMPONENTS urlComponents = {}; - bool secure = false; + bool secure = false; - string zipBuf; + string zipBuf; wchar_t hostName[256]; wchar_t path[1024]; @@ -385,10 +367,10 @@ bool HTTPGetFile(HINTERNET hConnect, urlComponents.dwStructSize = sizeof(urlComponents); - urlComponents.lpszHostName = hostName; + urlComponents.lpszHostName = hostName; urlComponents.dwHostNameLength = _countof(hostName); - urlComponents.lpszUrlPath = path; + urlComponents.lpszUrlPath = path; urlComponents.dwUrlPathLength = _countof(path); WinHttpCrackUrl(url, 0, 0, &urlComponents); @@ -399,23 +381,19 @@ bool HTTPGetFile(HINTERNET hConnect, /* -------------------------------------- * * request data */ - hRequest = WinHttpOpenRequest(hConnect, - L"GET", - path, - nullptr, - WINHTTP_NO_REFERER, - acceptTypes, - secure - ? WINHTTP_FLAG_SECURE | - WINHTTP_FLAG_REFRESH - : WINHTTP_FLAG_REFRESH); + hRequest = WinHttpOpenRequest(hConnect, L"GET", path, nullptr, + WINHTTP_NO_REFERER, acceptTypes, + secure ? WINHTTP_FLAG_SECURE | + WINHTTP_FLAG_REFRESH + : WINHTTP_FLAG_REFRESH); if (!hRequest) { *responseCode = -3; return false; } bool bResults = !!WinHttpSendRequest(hRequest, extraHeaders, - extraHeaders ? -1 : 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); + extraHeaders ? -1 : 0, + WINHTTP_NO_REQUEST_DATA, 0, 0, 0); /* -------------------------------------- * * end request */ @@ -431,18 +409,15 @@ bool HTTPGetFile(HINTERNET hConnect, * get headers */ wchar_t encoding[64]; - DWORD encodingLen; + DWORD encodingLen; wchar_t statusCode[8]; - DWORD statusCodeLen; + DWORD statusCodeLen; statusCodeLen = sizeof(statusCode); - if (!WinHttpQueryHeaders(hRequest, - WINHTTP_QUERY_STATUS_CODE, - WINHTTP_HEADER_NAME_BY_INDEX, - &statusCode, - &statusCodeLen, - WINHTTP_NO_HEADER_INDEX)) { + if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE, + WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, + &statusCodeLen, WINHTTP_NO_HEADER_INDEX)) { *responseCode = -4; return false; } else { @@ -450,12 +425,9 @@ bool HTTPGetFile(HINTERNET hConnect, } encodingLen = sizeof(encoding); - if (!WinHttpQueryHeaders(hRequest, - WINHTTP_QUERY_CONTENT_ENCODING, - WINHTTP_HEADER_NAME_BY_INDEX, - encoding, - &encodingLen, - WINHTTP_NO_HEADER_INDEX)) { + if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_ENCODING, + WINHTTP_HEADER_NAME_BY_INDEX, encoding, + &encodingLen, WINHTTP_NO_HEADER_INDEX)) { encoding[0] = 0; if (GetLastError() != ERROR_WINHTTP_HEADER_NOT_FOUND) { *responseCode = -5; @@ -472,11 +444,11 @@ bool HTTPGetFile(HINTERNET hConnect, bool gzip = wcscmp(encoding, L"gzip") == 0; if (gzip) { - strm->zalloc = Z_NULL; - strm->zfree = Z_NULL; - strm->opaque = Z_NULL; + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; strm->avail_in = 0; - strm->next_in = Z_NULL; + strm->next_in = Z_NULL; if (!strm.inflate()) return false; @@ -498,12 +470,12 @@ bool HTTPGetFile(HINTERNET hConnect, if (!bResults || *responseCode != 200) return true; - BYTE buffer[READ_BUF_SIZE]; + BYTE buffer[READ_BUF_SIZE]; DWORD dwSize, outSize; - int lastPosition = 0; + int lastPosition = 0; - WinHandle updateFile = CreateFile(outputPath, GENERIC_WRITE, 0, - nullptr, CREATE_ALWAYS, 0, nullptr); + WinHandle updateFile = CreateFile(outputPath, GENERIC_WRITE, 0, nullptr, + CREATE_ALWAYS, 0, nullptr); if (!updateFile.Valid()) { *responseCode = -7; return false; @@ -520,7 +492,7 @@ bool HTTPGetFile(HINTERNET hConnect, dwSize = std::min(dwSize, (DWORD)sizeof(buffer)); if (!WinHttpReadData(hRequest, (void *)buffer, dwSize, - &outSize)) { + &outSize)) { *responseCode = -9; return false; } else { @@ -529,21 +501,22 @@ bool HTTPGetFile(HINTERNET hConnect, if (gzip) { if (!ReadHTTPZippedFile(strm, updateFile, - zipBuf, buffer, - outSize, responseCode)) + zipBuf, buffer, outSize, + responseCode)) return false; } else { - if (!ReadHTTPFile(updateFile, buffer, - outSize, responseCode)) + if (!ReadHTTPFile(updateFile, buffer, outSize, + responseCode)) return false; } int position = (int)(((float)completedFileSize / - (float)totalFileSize) * 100.0f); + (float)totalFileSize) * + 100.0f); if (position > lastPosition) { lastPosition = position; SendDlgItemMessage(hwndMain, IDC_PROGRESS, - PBM_SETPOS, position, 0); + PBM_SETPOS, position, 0); } } diff --git a/UI/win-update/updater/patch.cpp b/UI/win-update/updater/patch.cpp index 0593e04..b42c95f 100644 --- a/UI/win-update/updater/patch.cpp +++ b/UI/win-update/updater/patch.cpp @@ -20,16 +20,16 @@ #include #ifdef _MSC_VER -# define restrict __restrict -# include -# undef restrict +#define restrict __restrict +#include +#undef restrict #else -# include +#include #endif using namespace std; -#define MAX_BUF_SIZE 262144 +#define MAX_BUF_SIZE 262144 #define READ_BUF_SIZE 32768 /* ------------------------------------------------------------------------ */ @@ -48,10 +48,7 @@ public: inline bool init_decoder() { - lzma_ret ret = lzma_stream_decoder( - &strm, - 200 * 1024 * 1024, - 0); + lzma_ret ret = lzma_stream_decoder(&strm, 200 * 1024 * 1024, 0); initialized = (ret == LZMA_OK); return initialized; } @@ -82,7 +79,7 @@ public: struct bspatch_stream { void *opaque; int (*read)(const struct bspatch_stream *stream, void *buffer, - int length); + int length); }; /* ------------------------------------------------------------------------ */ @@ -116,7 +113,7 @@ static int64_t offtin(const uint8_t *buf) /* ------------------------------------------------------------------------ */ static int bspatch(const uint8_t *old, int64_t oldsize, uint8_t *newp, - int64_t newsize, struct bspatch_stream *stream) + int64_t newsize, struct bspatch_stream *stream) { uint8_t buf[8]; int64_t oldpos, newpos; @@ -169,9 +166,9 @@ static int bspatch(const uint8_t *old, int64_t oldsize, uint8_t *newp, /* ------------------------------------------------------------------------ */ struct patch_data { - HANDLE h; - lzma_stream *strm; - uint8_t buf[READ_BUF_SIZE]; + HANDLE h; + lzma_stream *strm; + uint8_t buf[READ_BUF_SIZE]; }; static int read_lzma(const struct bspatch_stream *stream, void *buffer, int len) @@ -179,24 +176,24 @@ static int read_lzma(const struct bspatch_stream *stream, void *buffer, int len) if (!len) return 0; - patch_data *data = (patch_data*)stream->opaque; - HANDLE h = data->h; - lzma_stream *strm = data->strm; + patch_data *data = (patch_data *)stream->opaque; + HANDLE h = data->h; + lzma_stream *strm = data->strm; strm->avail_out = (size_t)len; - strm->next_out = (uint8_t *)buffer; + strm->next_out = (uint8_t *)buffer; for (;;) { if (strm->avail_in == 0) { DWORD read_size; if (!ReadFile(h, data->buf, READ_BUF_SIZE, &read_size, - nullptr)) + nullptr)) return -1; if (read_size == 0) return -1; strm->avail_in = (size_t)read_size; - strm->next_in = data->buf; + strm->next_in = data->buf; } lzma_ret ret = lzma_code(strm, LZMA_RUN); @@ -213,25 +210,25 @@ static int read_lzma(const struct bspatch_stream *stream, void *buffer, int len) int ApplyPatch(const wchar_t *patchFile, const wchar_t *targetFile) try { - uint8_t header[24]; - int64_t newsize; + uint8_t header[24]; + int64_t newsize; struct bspatch_stream stream; - bool success; + bool success; - WinHandle hPatch; - WinHandle hTarget; + WinHandle hPatch; + WinHandle hTarget; LZMAStream strm; /* --------------------------------- * * open patch and file to patch */ - hPatch = CreateFile(patchFile, GENERIC_READ, 0, nullptr, - OPEN_EXISTING, 0, nullptr); + hPatch = CreateFile(patchFile, GENERIC_READ, 0, nullptr, OPEN_EXISTING, + 0, nullptr); if (!hPatch.Valid()) throw int(GetLastError()); hTarget = CreateFile(targetFile, GENERIC_READ, 0, nullptr, - OPEN_EXISTING, 0, nullptr); + OPEN_EXISTING, 0, nullptr); if (!hTarget.Valid()) throw int(GetLastError()); @@ -289,14 +286,14 @@ try { throw int(-10); patch_data data; - data.h = hPatch; + data.h = hPatch; data.strm = strm.get(); - stream.read = read_lzma; + stream.read = read_lzma; stream.opaque = &data; int ret = bspatch(oldData.data(), oldData.size(), newData.data(), - newData.size(), &stream); + newData.size(), &stream); if (ret != 0) throw int(-9); @@ -305,14 +302,14 @@ try { hTarget = nullptr; hTarget = CreateFile(targetFile, GENERIC_WRITE, 0, nullptr, - CREATE_ALWAYS, 0, nullptr); + CREATE_ALWAYS, 0, nullptr); if (!hTarget.Valid()) throw int(GetLastError()); DWORD written; - success = !!WriteFile(hTarget, newData.data(), (DWORD)newsize, - &written, nullptr); + success = !!WriteFile(hTarget, newData.data(), (DWORD)newsize, &written, + nullptr); if (!success || written != newsize) throw int(GetLastError()); diff --git a/UI/win-update/updater/resource.h b/UI/win-update/updater/resource.h index 9b34eb0..28ba1d5 100644 --- a/UI/win-update/updater/resource.h +++ b/UI/win-update/updater/resource.h @@ -2,20 +2,20 @@ // Microsoft Visual C++ generated include file. // Used by updater.rc // -#define IDD_UPDATEDIALOG 101 -#define IDI_ICON1 103 -#define IDC_PROGRESS 1001 -#define IDC_STATUS 1002 -#define IDCBUTTON 1004 -#define IDC_BUTTON 1004 +#define IDD_UPDATEDIALOG 101 +#define IDI_ICON1 103 +#define IDC_PROGRESS 1001 +#define IDC_STATUS 1002 +#define IDCBUTTON 1004 +#define IDC_BUTTON 1004 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 104 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1005 -#define _APS_NEXT_SYMED_VALUE 101 +#define _APS_NEXT_RESOURCE_VALUE 104 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1005 +#define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/UI/win-update/updater/updater.cpp b/UI/win-update/updater/updater.cpp index 56d3812..66670f4 100644 --- a/UI/win-update/updater/updater.cpp +++ b/UI/win-update/updater/updater.cpp @@ -29,21 +29,21 @@ using namespace std; /* ----------------------------------------------------------------------- */ -HANDLE cancelRequested = nullptr; -HANDLE updateThread = nullptr; -HINSTANCE hinstMain = nullptr; -HWND hwndMain = nullptr; -HCRYPTPROV hProvider = 0; +HANDLE cancelRequested = nullptr; +HANDLE updateThread = nullptr; +HINSTANCE hinstMain = nullptr; +HWND hwndMain = nullptr; +HCRYPTPROV hProvider = 0; -static bool bExiting = false; +static bool bExiting = false; static bool updateFailed = false; -static bool is32bit = false; +static bool is32bit = false; static bool downloadThreadFailure = false; -int totalFileSize = 0; +int totalFileSize = 0; int completedFileSize = 0; -static int completedUpdates = 0; +static int completedUpdates = 0; struct LastError { DWORD code; @@ -65,9 +65,8 @@ static inline bool HasVS2017Redist2() wchar_t path[MAX_PATH]; WIN32_FIND_DATAW wfd; HANDLE handle; - int folder = (is32bit && is_64bit_windows()) - ? CSIDL_SYSTEMX86 - : CSIDL_SYSTEM; + int folder = (is32bit && is_64bit_windows()) ? CSIDL_SYSTEMX86 + : CSIDL_SYSTEM; SHGetFolderPathW(NULL, folder, NULL, SHGFP_TYPE_CURRENT, base); @@ -97,7 +96,8 @@ static bool HasVS2017Redist() PVOID old = nullptr; bool redirect = !!Wow64DisableWow64FsRedirection(&old); bool success = HasVS2017Redist2(); - if (redirect) Wow64RevertWow64FsRedirection(old); + if (redirect) + Wow64RevertWow64FsRedirection(old); return success; } @@ -135,16 +135,16 @@ try { WinHandle hDest; hSrc = CreateFile(src, GENERIC_READ, 0, nullptr, OPEN_EXISTING, - FILE_FLAG_SEQUENTIAL_SCAN, nullptr); + FILE_FLAG_SEQUENTIAL_SCAN, nullptr); if (!hSrc.Valid()) throw LastError(); - hDest = CreateFile(dest, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, - 0, nullptr); + hDest = CreateFile(dest, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, + nullptr); if (!hDest.Valid()) throw LastError(); - BYTE buf[65536]; + BYTE buf[65536]; DWORD read, wrote; for (;;) { @@ -182,10 +182,7 @@ static bool IsSafeFilename(const wchar_t *path) return false; while (*p) { - if (!isalnum(*p) && - *p != '.' && - *p != '/' && - *p != '_' && + if (!isalnum(*p) && *p != '.' && *p != '/' && *p != '_' && *p != '-') return false; p++; @@ -199,7 +196,7 @@ static string QuickReadFile(const wchar_t *path) string data; WinHandle handle = CreateFileW(path, GENERIC_READ, 0, nullptr, - OPEN_EXISTING, 0, nullptr); + OPEN_EXISTING, 0, nullptr); if (!handle.Valid()) { return string(); } @@ -213,11 +210,7 @@ static string QuickReadFile(const wchar_t *path) data.resize((size_t)size.QuadPart); DWORD read; - if (!ReadFile(handle, - &data[0], - (DWORD)data.size(), - &read, - nullptr)) { + if (!ReadFile(handle, &data[0], (DWORD)data.size(), &read, nullptr)) { return string(); } if (read != size.QuadPart) { @@ -244,28 +237,28 @@ struct update_t { wstring tempPath; wstring previousFile; wstring basename; - string packageName; + string packageName; - DWORD fileSize = 0; - BYTE hash[BLAKE2_HASH_LENGTH]; - BYTE downloadhash[BLAKE2_HASH_LENGTH]; - BYTE my_hash[BLAKE2_HASH_LENGTH]; - state_t state = STATE_INVALID; - bool has_hash = false; - bool patchable = false; + DWORD fileSize = 0; + BYTE hash[BLAKE2_HASH_LENGTH]; + BYTE downloadhash[BLAKE2_HASH_LENGTH]; + BYTE my_hash[BLAKE2_HASH_LENGTH]; + state_t state = STATE_INVALID; + bool has_hash = false; + bool patchable = false; inline update_t() {} inline update_t(const update_t &from) - : sourceURL(from.sourceURL), - outputPath(from.outputPath), - tempPath(from.tempPath), - previousFile(from.previousFile), - basename(from.basename), - packageName(from.packageName), - fileSize(from.fileSize), - state(from.state), - has_hash(from.has_hash), - patchable(from.patchable) + : sourceURL(from.sourceURL), + outputPath(from.outputPath), + tempPath(from.tempPath), + previousFile(from.previousFile), + basename(from.basename), + packageName(from.packageName), + fileSize(from.fileSize), + state(from.state), + has_hash(from.has_hash), + patchable(from.patchable) { memcpy(hash, from.hash, sizeof(hash)); memcpy(downloadhash, from.downloadhash, sizeof(downloadhash)); @@ -273,16 +266,16 @@ struct update_t { } inline update_t(update_t &&from) - : sourceURL(std::move(from.sourceURL)), - outputPath(std::move(from.outputPath)), - tempPath(std::move(from.tempPath)), - previousFile(std::move(from.previousFile)), - basename(std::move(from.basename)), - packageName(std::move(from.packageName)), - fileSize(from.fileSize), - state(from.state), - has_hash(from.has_hash), - patchable(from.patchable) + : sourceURL(std::move(from.sourceURL)), + outputPath(std::move(from.outputPath)), + tempPath(std::move(from.tempPath)), + previousFile(std::move(from.previousFile)), + basename(std::move(from.basename)), + packageName(std::move(from.packageName)), + fileSize(from.fileSize), + state(from.state), + has_hash(from.has_hash), + patchable(from.patchable) { from.state = STATE_INVALID; @@ -293,12 +286,11 @@ struct update_t { void CleanPartialUpdate() { - if (state == STATE_INSTALL_FAILED || - state == STATE_INSTALLED) { + if (state == STATE_INSTALL_FAILED || state == STATE_INSTALLED) { if (!previousFile.empty()) { DeleteFile(outputPath.c_str()); MyCopyFile(previousFile.c_str(), - outputPath.c_str()); + outputPath.c_str()); DeleteFile(previousFile.c_str()); } else { DeleteFile(outputPath.c_str()); @@ -310,16 +302,16 @@ struct update_t { inline update_t &operator=(const update_t &from) { - sourceURL = from.sourceURL; - outputPath = from.outputPath; - tempPath = from.tempPath; - previousFile = from.previousFile; - basename = from.basename; - packageName = from.packageName; - fileSize = from.fileSize; - state = from.state; - has_hash = from.has_hash; - patchable = from.patchable; + sourceURL = from.sourceURL; + outputPath = from.outputPath; + tempPath = from.tempPath; + previousFile = from.previousFile; + basename = from.basename; + packageName = from.packageName; + fileSize = from.fileSize; + state = from.state; + has_hash = from.has_hash; + patchable = from.patchable; memcpy(hash, from.hash, sizeof(hash)); memcpy(downloadhash, from.downloadhash, sizeof(downloadhash)); @@ -345,10 +337,9 @@ bool DownloadWorkerThread() const DWORD tlsProtocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2; HttpHandle hSession = WinHttpOpen(L"OBS Studio Updater/2.1", - WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, - WINHTTP_NO_PROXY_NAME, - WINHTTP_NO_PROXY_BYPASS, - 0); + WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, + WINHTTP_NO_PROXY_NAME, + WINHTTP_NO_PROXY_BYPASS, 0); if (!hSession) { downloadThreadFailure = true; Status(L"Update failed: Couldn't open obsproject.com"); @@ -356,10 +347,11 @@ bool DownloadWorkerThread() } WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS, - (LPVOID)&tlsProtocols, sizeof(tlsProtocols)); + (LPVOID)&tlsProtocols, sizeof(tlsProtocols)); - HttpHandle hConnect = WinHttpConnect(hSession, L"cdn-fastly.obsproject.com", - INTERNET_DEFAULT_HTTPS_PORT, 0); + HttpHandle hConnect = WinHttpConnect(hSession, + L"cdn-fastly.obsproject.com", + INTERNET_DEFAULT_HTTPS_PORT, 0); if (!hConnect) { downloadThreadFailure = true; Status(L"Update failed: Couldn't connect to cdn-fastly.obsproject.com"); @@ -395,18 +387,16 @@ bool DownloadWorkerThread() Status(L"Downloading %s", update.outputPath.c_str()); - if (!HTTPGetFile(hConnect, - update.sourceURL.c_str(), - update.tempPath.c_str(), - L"Accept-Encoding: gzip", - &responseCode)) { + if (!HTTPGetFile(hConnect, update.sourceURL.c_str(), + update.tempPath.c_str(), + L"Accept-Encoding: gzip", + &responseCode)) { downloadThreadFailure = true; DeleteFile(update.tempPath.c_str()); Status(L"Update failed: Could not download " L"%s (error code %d)", - update.outputPath.c_str(), - responseCode); + update.outputPath.c_str(), responseCode); return 1; } @@ -415,19 +405,18 @@ bool DownloadWorkerThread() DeleteFile(update.tempPath.c_str()); Status(L"Update failed: Could not download " L"%s (error code %d)", - update.outputPath.c_str(), - responseCode); + update.outputPath.c_str(), responseCode); return 1; } BYTE downloadHash[BLAKE2_HASH_LENGTH]; if (!CalculateFileHash(update.tempPath.c_str(), - downloadHash)) { + downloadHash)) { downloadThreadFailure = true; DeleteFile(update.tempPath.c_str()); Status(L"Update failed: Couldn't verify " - L"integrity of %s", - update.outputPath.c_str()); + L"integrity of %s", + update.outputPath.c_str()); return 1; } @@ -435,8 +424,8 @@ bool DownloadWorkerThread() downloadThreadFailure = true; DeleteFile(update.tempPath.c_str()); Status(L"Update failed: Integrity check " - L"failed on %s", - update.outputPath.c_str()); + L"failed on %s", + update.outputPath.c_str()); return 1; } @@ -479,9 +468,9 @@ try { /* ----------------------------------------------------------------------- */ -#define WAITIFOBS_SUCCESS 0 +#define WAITIFOBS_SUCCESS 0 #define WAITIFOBS_WRONG_PROCESS 1 -#define WAITIFOBS_CANCELLED 2 +#define WAITIFOBS_CANCELLED 2 static inline DWORD WaitIfOBS(DWORD id, const wchar_t *expected) { @@ -489,11 +478,9 @@ static inline DWORD WaitIfOBS(DWORD id, const wchar_t *expected) wchar_t *name; *path = 0; - WinHandle proc = OpenProcess( - PROCESS_QUERY_INFORMATION | - PROCESS_VM_READ | - SYNCHRONIZE, - false, id); + WinHandle proc = OpenProcess(PROCESS_QUERY_INFORMATION | + PROCESS_VM_READ | SYNCHRONIZE, + false, id); if (!proc.Valid()) return WAITIFOBS_WRONG_PROCESS; @@ -559,13 +546,13 @@ static inline bool UTF8ToWide(wchar_t *wide, int wideSize, const char *utf8) static inline bool WideToUTF8(char *utf8, int utf8Size, const wchar_t *wide) { return !!WideCharToMultiByte(CP_UTF8, 0, wide, -1, utf8, utf8Size, - nullptr, nullptr); + nullptr, nullptr); } static inline bool FileExists(const wchar_t *path) { WIN32_FIND_DATAW wfd; - HANDLE hFind; + HANDLE hFind; hFind = FindFirstFileW(path, &wfd); if (hFind != INVALID_HANDLE_VALUE) @@ -578,13 +565,15 @@ static bool NonCorePackageInstalled(const char *name) { if (is32bit) { if (strcmp(name, "obs-browser") == 0) { - return FileExists(L"obs-plugins\\32bit\\obs-browser.dll"); + return FileExists( + L"obs-plugins\\32bit\\obs-browser.dll"); } else if (strcmp(name, "realsense") == 0) { return FileExists(L"obs-plugins\\32bit\\win-ivcam.dll"); } } else { if (strcmp(name, "obs-browser") == 0) { - return FileExists(L"obs-plugins\\64bit\\obs-browser.dll"); + return FileExists( + L"obs-plugins\\64bit\\obs-browser.dll"); } else if (strcmp(name, "realsense") == 0) { return FileExists(L"obs-plugins\\64bit\\win-ivcam.dll"); } @@ -625,11 +614,11 @@ static inline bool has_str(const char *file, const char *str) #define UPDATE_URL L"https://cdn-fastly.obsproject.com/update_studio" static bool AddPackageUpdateFiles(json_t *root, size_t idx, - const wchar_t *tempPath) + const wchar_t *tempPath) { json_t *package = json_array_get(root, idx); - json_t *name = json_object_get(package, "name"); - json_t *files = json_object_get(package, "files"); + json_t *name = json_object_get(package, "name"); + json_t *files = json_object_get(package, "files"); bool isWin64 = is_64bit_windows(); @@ -650,10 +639,10 @@ static bool AddPackageUpdateFiles(json_t *root, size_t idx, return true; for (size_t j = 0; j < fileCount; j++) { - json_t *file = json_array_get(files, j); + json_t *file = json_array_get(files, j); json_t *fileName = json_object_get(file, "name"); - json_t *hash = json_object_get(file, "hash"); - json_t *size = json_object_get(file, "size"); + json_t *hash = json_object_get(file, "hash"); + json_t *size = json_object_get(file, "size"); if (!json_is_string(fileName)) continue; @@ -664,7 +653,7 @@ static bool AddPackageUpdateFiles(json_t *root, size_t idx, const char *fileUTF8 = json_string_value(fileName); const char *hashUTF8 = json_string_value(hash); - int fileSize = (int)json_integer_value(size); + int fileSize = (int)json_integer_value(size); if (strlen(hashUTF8) != BLAKE2_HASH_LENGTH * 2) continue; @@ -674,7 +663,7 @@ static bool AddPackageUpdateFiles(json_t *root, size_t idx, /* ignore update files of opposite arch to reduce download */ - if (( is32bit && has_str(fileUTF8, "/64bit/")) || + if ((is32bit && has_str(fileUTF8, "/64bit/")) || (!is32bit && has_str(fileUTF8, "/32bit/"))) continue; @@ -694,20 +683,21 @@ static bool AddPackageUpdateFiles(json_t *root, size_t idx, if (!IsSafeFilename(updateFileName)) { Status(L"Update failed: Unsafe path '%s' found in " - L"manifest", updateFileName); + L"manifest", + updateFileName); return false; } StringCbPrintf(sourceURL, sizeof(sourceURL), L"%s/%s/%s", - UPDATE_URL, wPackageName, updateFileName); - StringCbPrintf(tempFilePath, sizeof(tempFilePath), - L"%s\\%s", tempPath, updateHashStr); + UPDATE_URL, wPackageName, updateFileName); + StringCbPrintf(tempFilePath, sizeof(tempFilePath), L"%s\\%s", + tempPath, updateHashStr); /* Check file hash */ - BYTE existingHash[BLAKE2_HASH_LENGTH]; + BYTE existingHash[BLAKE2_HASH_LENGTH]; wchar_t fileHashStr[BLAKE2_HASH_STR_LENGTH]; - bool has_hash; + bool has_hash; /* We don't really care if this fails, it's just to avoid * wasting bandwidth by downloading unmodified files */ @@ -725,14 +715,14 @@ static bool AddPackageUpdateFiles(json_t *root, size_t idx, /* Add update file */ update_t update; - update.fileSize = fileSize; - update.basename = updateFileName; - update.outputPath = updateFileName; - update.tempPath = tempFilePath; - update.sourceURL = sourceURL; - update.packageName = packageName; - update.state = STATE_PENDING_DOWNLOAD; - update.patchable = false; + update.fileSize = fileSize; + update.basename = updateFileName; + update.outputPath = updateFileName; + update.tempPath = tempFilePath; + update.sourceURL = sourceURL; + update.packageName = packageName; + update.state = STATE_PENDING_DOWNLOAD; + update.patchable = false; StringToHash(updateHashStr, update.downloadhash); memcpy(update.hash, update.downloadhash, sizeof(update.hash)); @@ -750,8 +740,7 @@ static bool AddPackageUpdateFiles(json_t *root, size_t idx, } static void UpdateWithPatchIfAvailable(const char *name, const char *hash, - const char *source, - int size) + const char *source, int size) { wchar_t widePatchableFilename[MAX_PATH]; wchar_t widePatchHash[MAX_PATH]; @@ -791,7 +780,7 @@ static void UpdateWithPatchIfAvailable(const char *name, const char *hash, * patchable, and re-calculate download size */ totalFileSize -= (update.fileSize - size); update.sourceURL = sourceURL; - update.fileSize = size; + update.fileSize = size; update.patchable = true; break; } @@ -812,10 +801,10 @@ static bool UpdateFile(update_t &file) if (attribs != INVALID_FILE_ATTRIBUTES) { wchar_t *curFileName = nullptr; - wchar_t baseName[MAX_PATH]; + wchar_t baseName[MAX_PATH]; StringCbCopy(baseName, sizeof(baseName), - file.outputPath.c_str()); + file.outputPath.c_str()); curFileName = wcsrchr(baseName, '/'); if (curFileName) { @@ -825,12 +814,10 @@ static bool UpdateFile(update_t &file) curFileName = baseName; /* Backup the existing file in case a rollback is needed */ - StringCbCopy(oldFileRenamedPath, - sizeof(oldFileRenamedPath), - file.outputPath.c_str()); - StringCbCat(oldFileRenamedPath, - sizeof(oldFileRenamedPath), - L".old"); + StringCbCopy(oldFileRenamedPath, sizeof(oldFileRenamedPath), + file.outputPath.c_str()); + StringCbCat(oldFileRenamedPath, sizeof(oldFileRenamedPath), + L".old"); if (!MyCopyFile(file.outputPath.c_str(), oldFileRenamedPath)) { int is_sharing_violation = @@ -849,19 +836,18 @@ static bool UpdateFile(update_t &file) file.previousFile = oldFileRenamedPath; - int error_code; + int error_code; bool installed_ok; if (file.patchable) { - error_code = ApplyPatch( - file.tempPath.c_str(), - file.outputPath.c_str()); + error_code = ApplyPatch(file.tempPath.c_str(), + file.outputPath.c_str()); installed_ok = (error_code == 0); if (installed_ok) { BYTE patchedFileHash[BLAKE2_HASH_LENGTH]; if (!CalculateFileHash(file.outputPath.c_str(), - patchedFileHash)) { + patchedFileHash)) { Status(L"Update failed: Couldn't " L"verify integrity of patched %s", curFileName); @@ -871,7 +857,7 @@ static bool UpdateFile(update_t &file) } if (memcmp(file.hash, patchedFileHash, - BLAKE2_HASH_LENGTH) != 0) { + BLAKE2_HASH_LENGTH) != 0) { Status(L"Update failed: Integrity " L"check of patched " L"%s failed", @@ -882,9 +868,8 @@ static bool UpdateFile(update_t &file) } } } else { - installed_ok = MyCopyFile( - file.tempPath.c_str(), - file.outputPath.c_str()); + installed_ok = MyCopyFile(file.tempPath.c_str(), + file.outputPath.c_str()); error_code = GetLastError(); } @@ -900,8 +885,7 @@ static bool UpdateFile(update_t &file) else Status(L"Update failed: Couldn't update %s " L"(error %d)", - curFileName, - GetLastError()); + curFileName, GetLastError()); file.state = STATE_INSTALL_FAILED; return false; @@ -913,7 +897,7 @@ static bool UpdateFile(update_t &file) /* Uh oh, we thought we could patch something but it's * no longer there! */ Status(L"Update failed: Source file %s not found", - file.outputPath.c_str()); + file.outputPath.c_str()); return false; } @@ -923,13 +907,11 @@ static bool UpdateFile(update_t &file) file.previousFile = L""; - bool success = !!MyCopyFile( - file.tempPath.c_str(), - file.outputPath.c_str()); + bool success = !!MyCopyFile(file.tempPath.c_str(), + file.outputPath.c_str()); if (!success) { Status(L"Update failed: Couldn't install %s (error %d)", - file.outputPath.c_str(), - GetLastError()); + file.outputPath.c_str(), GetLastError()); file.state = STATE_INSTALL_FAILED; return false; } @@ -944,8 +926,7 @@ static wchar_t tempPath[MAX_PATH] = {}; #define PATCH_MANIFEST_URL \ L"https://obsproject.com/update_studio/getpatchmanifest" -#define HASH_NULL \ - L"0000000000000000000000000000000000000000" +#define HASH_NULL L"0000000000000000000000000000000000000000" static bool UpdateVS2017Redists(json_t *root) { @@ -955,20 +936,20 @@ static bool UpdateVS2017Redists(json_t *root) const DWORD tlsProtocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2; HttpHandle hSession = WinHttpOpen(L"OBS Studio Updater/2.1", - WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, - WINHTTP_NO_PROXY_NAME, - WINHTTP_NO_PROXY_BYPASS, - 0); + WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, + WINHTTP_NO_PROXY_NAME, + WINHTTP_NO_PROXY_BYPASS, 0); if (!hSession) { Status(L"Update failed: Couldn't open obsproject.com"); return false; } WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS, - (LPVOID)&tlsProtocols, sizeof(tlsProtocols)); + (LPVOID)&tlsProtocols, sizeof(tlsProtocols)); - HttpHandle hConnect = WinHttpConnect(hSession, L"cdn-fastly.obsproject.com", - INTERNET_DEFAULT_HTTPS_PORT, 0); + HttpHandle hConnect = WinHttpConnect(hSession, + L"cdn-fastly.obsproject.com", + INTERNET_DEFAULT_HTTPS_PORT, 0); if (!hConnect) { Status(L"Update failed: Couldn't connect to cdn-fastly.obsproject.com"); return false; @@ -986,9 +967,8 @@ static bool UpdateVS2017Redists(json_t *root) Status(L"Downloading %s", L"Visual C++ 2017 Redistributable"); - const wchar_t *file = (is32bit) - ? L"vc2017redist_x86.exe" - : L"vc2017redist_x64.exe"; + const wchar_t *file = (is32bit) ? L"vc2017redist_x86.exe" + : L"vc2017redist_x64.exe"; wstring sourceURL; sourceURL += L"https://cdn-fastly.obsproject.com/downloads/"; @@ -999,26 +979,21 @@ static bool UpdateVS2017Redists(json_t *root) destPath += L"\\"; destPath += file; - if (!HTTPGetFile(hConnect, - sourceURL.c_str(), - destPath.c_str(), - L"Accept-Encoding: gzip", - &responseCode)) { + if (!HTTPGetFile(hConnect, sourceURL.c_str(), destPath.c_str(), + L"Accept-Encoding: gzip", &responseCode)) { DeleteFile(destPath.c_str()); Status(L"Update failed: Could not download " L"%s (error code %d)", - L"Visual C++ 2017 Redistributable", - responseCode); + L"Visual C++ 2017 Redistributable", responseCode); return false; } /* ------------------------------------------ * * Get expected hash */ - json_t *redistJson = json_object_get(root, is32bit - ? "vc2017_redist_x86" - : "vc2017_redist_x64"); + json_t *redistJson = json_object_get( + root, is32bit ? "vc2017_redist_x86" : "vc2017_redist_x64"); if (!redistJson) { Status(L"Update failed: Could not parse VC2017 redist json"); return false; @@ -1045,7 +1020,7 @@ static bool UpdateVS2017Redists(json_t *root) if (!CalculateFileHash(destPath.c_str(), downloadHash)) { DeleteFile(destPath.c_str()); Status(L"Update failed: Couldn't verify integrity of %s", - L"Visual C++ 2017 Redistributable"); + L"Visual C++ 2017 Redistributable"); return false; } @@ -1056,7 +1031,7 @@ static bool UpdateVS2017Redists(json_t *root) if (wcscmp(expectedHashWide, downloadHashWide) != 0) { DeleteFile(destPath.c_str()); Status(L"Update failed: Couldn't verify integrity of %s", - L"Visual C++ 2017 Redistributable"); + L"Visual C++ 2017 Redistributable"); return false; } @@ -1065,15 +1040,15 @@ static bool UpdateVS2017Redists(json_t *root) wchar_t commandline[MAX_PATH + MAX_PATH]; StringCbPrintf(commandline, sizeof(commandline), - L"%s /install /quiet /norestart", destPath.c_str()); + L"%s /install /quiet /norestart", destPath.c_str()); PROCESS_INFORMATION pi = {}; STARTUPINFO si = {}; si.cb = sizeof(si); - bool success = !!CreateProcessW(destPath.c_str(), commandline, - nullptr, nullptr, false, CREATE_NO_WINDOW, - nullptr, nullptr, &si, &pi); + bool success = !!CreateProcessW(destPath.c_str(), commandline, nullptr, + nullptr, false, CREATE_NO_WINDOW, + nullptr, nullptr, &si, &pi); if (success) { Status(L"Installing %s...", L"Visual C++ 2017 Redistributable"); @@ -1083,8 +1058,7 @@ static bool UpdateVS2017Redists(json_t *root) } else { Status(L"Update failed: Could not execute " L"%s (error code %d)", - L"Visual C++ 2017 Redistributable", - (int)GetLastError()); + L"Visual C++ 2017 Redistributable", (int)GetLastError()); } DeleteFile(destPath.c_str()); @@ -1102,8 +1076,8 @@ static bool Update(wchar_t *cmdLine) /* ------------------------------------- * * Check to make sure OBS isn't running */ - HANDLE hObsUpdateMutex = OpenMutexW(SYNCHRONIZE, false, - L"OBSStudioUpdateMutex"); + HANDLE hObsUpdateMutex = + OpenMutexW(SYNCHRONIZE, false, L"OBSStudioUpdateMutex"); if (hObsUpdateMutex) { HANDLE hWait[2]; hWait[0] = hObsUpdateMutex; @@ -1128,7 +1102,7 @@ static bool Update(wchar_t *cmdLine) CryptProvider hProvider; if (!CryptAcquireContext(&hProvider, nullptr, MS_ENH_RSA_AES_PROV, - PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { + PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { SetDlgItemTextW(hwndMain, IDC_STATUS, L"Update failed: CryptAcquireContext failure"); return false; @@ -1179,18 +1153,18 @@ static bool Update(wchar_t *cmdLine) } else { CoTaskMemPtr pOut; HRESULT hr = SHGetKnownFolderPath(FOLDERID_RoamingAppData, - KF_FLAG_DEFAULT, nullptr, &pOut); + KF_FLAG_DEFAULT, nullptr, + &pOut); if (hr != S_OK) { Status(L"Update failed: Could not determine AppData " - L"location"); + L"location"); return false; } StringCbCopy(lpAppDataPath, sizeof(lpAppDataPath), pOut); } - StringCbCat(lpAppDataPath, sizeof(lpAppDataPath), - L"\\obs-studio"); + StringCbCat(lpAppDataPath, sizeof(lpAppDataPath), L"\\obs-studio"); /* ------------------------------------- * * Get download path */ @@ -1199,18 +1173,18 @@ static bool Update(wchar_t *cmdLine) wchar_t tempDirName[MAX_PATH]; manifestPath[0] = 0; - tempDirName[0] = 0; + tempDirName[0] = 0; StringCbPrintf(manifestPath, sizeof(manifestPath), - L"%s\\updates\\manifest.json", lpAppDataPath); + L"%s\\updates\\manifest.json", lpAppDataPath); if (!GetTempPathW(_countof(tempDirName), tempDirName)) { Status(L"Update failed: Failed to get temp path: %ld", - GetLastError()); + GetLastError()); return false; } if (!GetTempFileNameW(tempDirName, L"obs-studio", 0, tempPath)) { Status(L"Update failed: Failed to create temp dir name: %ld", - GetLastError()); + GetLastError()); return false; } @@ -1233,7 +1207,8 @@ static bool Update(wchar_t *cmdLine) if (!root) { Status(L"Update failed: Couldn't parse update " - L"manifest: %S", error.text); + L"manifest: %S", + error.text); return false; } } @@ -1284,8 +1259,8 @@ static bool Update(wchar_t *cmdLine) for (update_t &update : updates) { wchar_t whash_string[BLAKE2_HASH_STR_LENGTH]; - char hash_string[BLAKE2_HASH_STR_LENGTH]; - char outputPath[MAX_PATH]; + char hash_string[BLAKE2_HASH_STR_LENGTH]; + char outputPath[MAX_PATH]; if (!update.has_hash) continue; @@ -1319,23 +1294,22 @@ static bool Update(wchar_t *cmdLine) if (json_array_size(files) > 0) { char *post_body = json_dumps(files, JSON_COMPACT); - int responseCode; + int responseCode; int len = (int)strlen(post_body); uLong compressSize = compressBound(len); string compressedJson; compressedJson.resize(compressSize); - compress2((Bytef*)&compressedJson[0], &compressSize, - (const Bytef*)post_body, len, - Z_BEST_COMPRESSION); + compress2((Bytef *)&compressedJson[0], &compressSize, + (const Bytef *)post_body, len, Z_BEST_COMPRESSION); compressedJson.resize(compressSize); bool success = !!HTTPPostData(PATCH_MANIFEST_URL, - (BYTE *)&compressedJson[0], - (int)compressedJson.size(), - L"Accept-Encoding: gzip", &responseCode, - newManifest); + (BYTE *)&compressedJson[0], + (int)compressedJson.size(), + L"Accept-Encoding: gzip", + &responseCode, newManifest); free(post_body); if (!success) @@ -1343,8 +1317,8 @@ static bool Update(wchar_t *cmdLine) if (responseCode != 200) { Status(L"Update failed: HTTP/%d while trying to " - L"download patch manifest", - responseCode); + L"download patch manifest", + responseCode); return false; } } else { @@ -1358,7 +1332,7 @@ static bool Update(wchar_t *cmdLine) root = json_loads(newManifest.c_str(), 0, &error); if (!root) { Status(L"Update failed: Couldn't parse patch manifest: %S", - error.text); + error.text); return false; } @@ -1377,10 +1351,10 @@ static bool Update(wchar_t *cmdLine) return false; } - json_t *name_json = json_object_get(patch, "name"); - json_t *hash_json = json_object_get(patch, "hash"); + json_t *name_json = json_object_get(patch, "name"); + json_t *hash_json = json_object_get(patch, "hash"); json_t *source_json = json_object_get(patch, "source"); - json_t *size_json = json_object_get(patch, "size"); + json_t *size_json = json_object_get(patch, "size"); if (!json_is_string(name_json)) continue; @@ -1391,10 +1365,10 @@ static bool Update(wchar_t *cmdLine) if (!json_is_integer(size_json)) continue; - const char *name = json_string_value(name_json); - const char *hash = json_string_value(hash_json); + const char *name = json_string_value(name_json); + const char *hash = json_string_value(hash_json); const char *source = json_string_value(source_json); - int size = (int)json_integer_value(size_json); + int size = (int)json_integer_value(size_json); UpdateWithPatchIfAvailable(name, hash, source, size); } @@ -1416,8 +1390,7 @@ static bool Update(wchar_t *cmdLine) int updatesInstalled = 0; int lastPosition = 0; - SendDlgItemMessage(hwndMain, IDC_PROGRESS, - PBM_SETPOS, 0, 0); + SendDlgItemMessage(hwndMain, IDC_PROGRESS, PBM_SETPOS, 0, 0); for (update_t &update : updates) { if (!UpdateFile(update)) { @@ -1425,11 +1398,12 @@ static bool Update(wchar_t *cmdLine) } else { updatesInstalled++; int position = (int)(((float)updatesInstalled / - (float)completedUpdates) * 100.0f); + (float)completedUpdates) * + 100.0f); if (position > lastPosition) { lastPosition = position; SendDlgItemMessage(hwndMain, IDC_PROGRESS, - PBM_SETPOS, position, 0); + PBM_SETPOS, position, 0); } } } @@ -1445,8 +1419,7 @@ static bool Update(wchar_t *cmdLine) DeleteFile(update.tempPath.c_str()); } - SendDlgItemMessage(hwndMain, IDC_PROGRESS, - PBM_SETPOS, 100, 0); + SendDlgItemMessage(hwndMain, IDC_PROGRESS, PBM_SETPOS, 100, 0); Status(L"Update complete."); SetDlgItemText(hwndMain, IDC_BUTTON, L"Launch OBS"); @@ -1508,15 +1481,13 @@ static void LaunchOBS() GetCurrentDirectory(_countof(cwd) - 1, cwd); StringCbCopy(obsPath, sizeof(obsPath), cwd); - StringCbCat(obsPath, sizeof(obsPath), is32bit - ? L"\\bin\\32bit" - : L"\\bin\\64bit"); + StringCbCat(obsPath, sizeof(obsPath), + is32bit ? L"\\bin\\32bit" : L"\\bin\\64bit"); SetCurrentDirectory(obsPath); StringCbCopy(newCwd, sizeof(newCwd), obsPath); - StringCbCat(obsPath, sizeof(obsPath), is32bit - ? L"\\obs32.exe" - : L"\\obs64.exe"); + StringCbCat(obsPath, sizeof(obsPath), + is32bit ? L"\\obs32.exe" : L"\\obs64.exe"); if (!FileExists(obsPath)) { StringCbCopy(obsPath, sizeof(obsPath), cwd); @@ -1536,21 +1507,21 @@ static void LaunchOBS() ZeroMemory(&execInfo, sizeof(execInfo)); - execInfo.cbSize = sizeof(execInfo); - execInfo.lpFile = obsPath; + execInfo.cbSize = sizeof(execInfo); + execInfo.lpFile = obsPath; execInfo.lpDirectory = newCwd; - execInfo.nShow = SW_SHOWNORMAL; + execInfo.nShow = SW_SHOWNORMAL; ShellExecuteEx(&execInfo); } -static INT_PTR CALLBACK UpdateDialogProc(HWND hwnd, UINT message, - WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK UpdateDialogProc(HWND hwnd, UINT message, WPARAM wParam, + LPARAM lParam) { switch (message) { case WM_INITDIALOG: { - static HICON hMainIcon = LoadIcon(hinstMain, - MAKEINTRESOURCE(IDI_ICON1)); + static HICON hMainIcon = + LoadIcon(hinstMain, MAKEINTRESOURCE(IDI_ICON1)); SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hMainIcon); SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hMainIcon); return true; @@ -1559,8 +1530,8 @@ static INT_PTR CALLBACK UpdateDialogProc(HWND hwnd, UINT message, case WM_COMMAND: if (LOWORD(wParam) == IDC_BUTTON) { if (HIWORD(wParam) == BN_CLICKED) { - DWORD result = WaitForSingleObject( - updateThread, 0); + DWORD result = + WaitForSingleObject(updateThread, 0); if (result == WAIT_OBJECT_0) { if (updateFailed) PostQuitMessage(0); @@ -1593,15 +1564,15 @@ static void RestartAsAdmin(LPWSTR lpCmdLine) GetCurrentDirectoryW(_countof(cwd) - 1, cwd); SHELLEXECUTEINFO shExInfo = {0}; - shExInfo.cbSize = sizeof(shExInfo); - shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS; - shExInfo.hwnd = 0; - shExInfo.lpVerb = L"runas"; /* Operation to perform */ - shExInfo.lpFile = myPath; /* Application to start */ - shExInfo.lpParameters = lpCmdLine; /* Additional parameters */ - shExInfo.lpDirectory = cwd; - shExInfo.nShow = SW_NORMAL; - shExInfo.hInstApp = 0; + shExInfo.cbSize = sizeof(shExInfo); + shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS; + shExInfo.hwnd = 0; + shExInfo.lpVerb = L"runas"; /* Operation to perform */ + shExInfo.lpFile = myPath; /* Application to start */ + shExInfo.lpParameters = lpCmdLine; /* Additional parameters */ + shExInfo.lpDirectory = cwd; + shExInfo.nShow = SW_NORMAL; + shExInfo.hInstApp = 0; /* annoyingly the actual elevated updater will disappear behind other * windows :( */ @@ -1627,7 +1598,8 @@ static bool HasElevation() BOOL success; success = AllocateAndInitializeSid(&sia, 2, SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid); + DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, + 0, 0, &sid); if (success && sid) { CheckTokenMembership(nullptr, sid, &elevated); FreeSid(sid); @@ -1641,8 +1613,8 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int) INITCOMMONCONTROLSEX icce; if (!HasElevation()) { - HANDLE hLowMutex = CreateMutexW(nullptr, true, - L"OBSUpdaterRunningAsNonAdminUser"); + HANDLE hLowMutex = CreateMutexW( + nullptr, true, L"OBSUpdaterRunningAsNonAdminUser"); RestartAsAdmin(lpCmdLine); @@ -1669,13 +1641,13 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int) hinstMain = hInstance; icce.dwSize = sizeof(icce); - icce.dwICC = ICC_PROGRESS_CLASS; + icce.dwICC = ICC_PROGRESS_CLASS; InitCommonControlsEx(&icce); hwndMain = CreateDialog(hInstance, - MAKEINTRESOURCE(IDD_UPDATEDIALOG), nullptr, - UpdateDialogProc); + MAKEINTRESOURCE(IDD_UPDATEDIALOG), + nullptr, UpdateDialogProc); if (!hwndMain) { return -1; } @@ -1684,8 +1656,8 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int) SetForegroundWindow(hwndMain); cancelRequested = CreateEvent(nullptr, true, false, nullptr); - updateThread = CreateThread(nullptr, 0, UpdateThread, - lpCmdLine, 0, nullptr); + updateThread = CreateThread(nullptr, 0, UpdateThread, lpCmdLine, + 0, nullptr); MSG msg; while (GetMessage(&msg, nullptr, 0, 0)) { @@ -1697,8 +1669,8 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int) /* there is no non-elevated process waiting for us if UAC is * disabled */ - WinHandle hMutex = OpenMutex(SYNCHRONIZE, false, - L"OBSUpdaterRunningAsNonAdminUser"); + WinHandle hMutex = OpenMutex( + SYNCHRONIZE, false, L"OBSUpdaterRunningAsNonAdminUser"); if (msg.wParam == 1 && !hMutex) { LaunchOBS(); } diff --git a/UI/win-update/updater/updater.hpp b/UI/win-update/updater/updater.hpp index cc5a59c..1297ce6 100644 --- a/UI/win-update/updater/updater.hpp +++ b/UI/win-update/updater/updater.hpp @@ -45,53 +45,44 @@ #define BLAKE2_HASH_STR_LENGTH ((BLAKE2_HASH_LENGTH * 2) + 1) #if defined _M_IX86 -#pragma comment(linker, \ - "/manifestdependency:\"type='win32' " \ - "name='Microsoft.Windows.Common-Controls' " \ - "version='6.0.0.0' " \ - "processorArchitecture='x86' " \ - "publicKeyToken='6595b64144ccf1df' " \ - "language='*'\"") +#pragma comment(linker, "/manifestdependency:\"type='win32' " \ + "name='Microsoft.Windows.Common-Controls' " \ + "version='6.0.0.0' " \ + "processorArchitecture='x86' " \ + "publicKeyToken='6595b64144ccf1df' " \ + "language='*'\"") #elif defined _M_IA64 -#pragma comment(linker, \ - "/manifestdependency:\"type='win32' " \ - "name='Microsoft.Windows.Common-Controls' " \ - "version='6.0.0.0' " \ - "processorArchitecture='ia64' " \ - "publicKeyToken='6595b64144ccf1df' " \ - "language='*'\"") +#pragma comment(linker, "/manifestdependency:\"type='win32' " \ + "name='Microsoft.Windows.Common-Controls' " \ + "version='6.0.0.0' " \ + "processorArchitecture='ia64' " \ + "publicKeyToken='6595b64144ccf1df' " \ + "language='*'\"") #elif defined _M_X64 -#pragma comment(linker, \ - "/manifestdependency:\"type='win32' " \ - "name='Microsoft.Windows.Common-Controls' " \ - "version='6.0.0.0' " \ - "processorArchitecture='amd64' " \ - "publicKeyToken='6595b64144ccf1df' " \ - "language='*'\"") +#pragma comment(linker, "/manifestdependency:\"type='win32' " \ + "name='Microsoft.Windows.Common-Controls' " \ + "version='6.0.0.0' " \ + "processorArchitecture='amd64' " \ + "publicKeyToken='6595b64144ccf1df' " \ + "language='*'\"") #else -#pragma comment(linker, \ - "/manifestdependency:\"type='win32' " \ - "name='Microsoft.Windows.Common-Controls' " \ - "version='6.0.0.0' processorArchitecture='*' " \ - "publicKeyToken='6595b64144ccf1df' " \ - "language='*'\"") +#pragma comment(linker, "/manifestdependency:\"type='win32' " \ + "name='Microsoft.Windows.Common-Controls' " \ + "version='6.0.0.0' processorArchitecture='*' " \ + "publicKeyToken='6595b64144ccf1df' " \ + "language='*'\"") #endif #include #include #include "resource.h" -bool HTTPGetFile(HINTERNET hConnect, - const wchar_t *url, - const wchar_t *outputPath, - const wchar_t *extraHeaders, - int * responseCode); -bool HTTPPostData(const wchar_t *url, - const BYTE * data, - int dataLen, - const wchar_t *extraHeaders, - int * responseCode, - std::string & response); +bool HTTPGetFile(HINTERNET hConnect, const wchar_t *url, + const wchar_t *outputPath, const wchar_t *extraHeaders, + int *responseCode); +bool HTTPPostData(const wchar_t *url, const BYTE *data, int dataLen, + const wchar_t *extraHeaders, int *responseCode, + std::string &response); void HashToString(const BYTE *in, wchar_t *out); void StringToHash(const wchar_t *in, BYTE *out); @@ -100,17 +91,17 @@ bool CalculateFileHash(const wchar_t *path, BYTE *hash); int ApplyPatch(LPCTSTR patchFile, LPCTSTR targetFile); -extern HWND hwndMain; +extern HWND hwndMain; extern HCRYPTPROV hProvider; -extern int totalFileSize; -extern int completedFileSize; -extern HANDLE cancelRequested; +extern int totalFileSize; +extern int completedFileSize; +extern HANDLE cancelRequested; #pragma pack(push, r1, 1) typedef struct { BLOBHEADER blobheader; - RSAPUBKEY rsapubkey; + RSAPUBKEY rsapubkey; } PUBLICKEYHEADER; #pragma pack(pop, r1) diff --git a/UI/win-update/win-update-helpers.hpp b/UI/win-update/win-update-helpers.hpp index 51ea16a..ef6aa59 100644 --- a/UI/win-update/win-update-helpers.hpp +++ b/UI/win-update/win-update-helpers.hpp @@ -23,9 +23,9 @@ public: freefunc(handle); } - inline T *operator&() {return &handle;} - inline operator T() const {return handle;} - inline T get() const {return handle;} + inline T *operator&() { return &handle; } + inline operator T() const { return handle; } + inline T get() const { return handle; } inline CustomHandle &operator=(T in) { @@ -35,7 +35,7 @@ public: return *this; } - inline bool operator!() const {return !handle;} + inline bool operator!() const { return !handle; } }; void FreeProvider(HCRYPTPROV prov); @@ -43,8 +43,8 @@ void FreeHash(HCRYPTHASH hash); void FreeKey(HCRYPTKEY key); using CryptProvider = CustomHandle; -using CryptHash = CustomHandle; -using CryptKey = CustomHandle; +using CryptHash = CustomHandle; +using CryptKey = CustomHandle; /* ------------------------------------------------------------------------ */ @@ -58,13 +58,13 @@ public: LocalFree(ptr); } - inline T **operator&() {return &ptr;} - inline operator T() const {return ptr;} - inline T *get() const {return ptr;} + inline T **operator&() { return &ptr; } + inline operator T() const { return ptr; } + inline T *get() const { return ptr; } - inline bool operator!() const {return !ptr;} + inline bool operator!() const { return !ptr; } - inline T *operator->() {return ptr;} + inline T *operator->() { return ptr; } }; /* ------------------------------------------------------------------------ */ @@ -76,9 +76,10 @@ public: inline Json() : json(nullptr) {} explicit inline Json(json_t *json_) : json(json_) {} inline Json(const Json &from) : json(json_incref(from.json)) {} - inline Json(Json &&from) : json(from.json) {from.json = nullptr;} + inline Json(Json &&from) : json(from.json) { from.json = nullptr; } - inline ~Json() { + inline ~Json() + { if (json) json_decref(json); } @@ -106,12 +107,12 @@ public: return *this; } - inline operator json_t *() const {return json;} + inline operator json_t *() const { return json; } - inline bool operator!() const {return !json;} + inline bool operator!() const { return !json; } inline const char *GetString(const char *name, - const char *def = nullptr) const + const char *def = nullptr) const { json_t *obj(json_object_get(json, name)); if (!obj) @@ -130,7 +131,7 @@ public: return json_object_get(json, name); } - inline json_t *get() const {return json;} + inline json_t *get() const { return json; } }; /* ------------------------------------------------------------------------ */ diff --git a/UI/win-update/win-update.cpp b/UI/win-update/win-update.cpp index 34d2157..00d891e 100644 --- a/UI/win-update/win-update.cpp +++ b/UI/win-update/win-update.cpp @@ -42,7 +42,7 @@ static __declspec(thread) HCRYPTPROV provider = 0; typedef struct { BLOBHEADER blobheader; - RSAPUBKEY rsapubkey; + RSAPUBKEY rsapubkey; } PUBLICKEYHEADER; #pragma pack(pop, r1) @@ -120,8 +120,7 @@ static const unsigned char obs_pub[] = { 0x42, 0x61, 0x35, 0x66, 0x37, 0x4c, 0x6f, 0x4b, 0x38, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x51, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, - 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a -}; + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a}; static const unsigned int obs_pub_len = 800; /* ------------------------------------------------------------------------ */ @@ -132,27 +131,22 @@ try { if (os_utf8_to_wcs_ptr(file, 0, &w_file) == 0) return false; - WinHandle handle = CreateFileW( - w_file, - GENERIC_WRITE, - 0, - nullptr, - CREATE_ALWAYS, - FILE_FLAG_WRITE_THROUGH, - nullptr); + WinHandle handle = CreateFileW(w_file, GENERIC_WRITE, 0, nullptr, + CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, + nullptr); if (handle == INVALID_HANDLE_VALUE) - throw strprintf("Failed to open file '%s': %lu", - file, GetLastError()); + throw strprintf("Failed to open file '%s': %lu", file, + GetLastError()); DWORD written; if (!WriteFile(handle, data, (DWORD)size, &written, nullptr)) - throw strprintf("Failed to write file '%s': %lu", - file, GetLastError()); + throw strprintf("Failed to write file '%s': %lu", file, + GetLastError()); return true; -} catch (string text) { +} catch (string &text) { blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str()); return false; } @@ -163,30 +157,24 @@ try { if (os_utf8_to_wcs_ptr(file, 0, &w_file) == 0) return false; - WinHandle handle = CreateFileW( - w_file, - GENERIC_READ, - FILE_SHARE_READ, - nullptr, - OPEN_EXISTING, - 0, - nullptr); + WinHandle handle = CreateFileW(w_file, GENERIC_READ, FILE_SHARE_READ, + nullptr, OPEN_EXISTING, 0, nullptr); if (handle == INVALID_HANDLE_VALUE) - throw strprintf("Failed to open file '%s': %lu", - file, GetLastError()); + throw strprintf("Failed to open file '%s': %lu", file, + GetLastError()); DWORD size = GetFileSize(handle, nullptr); data.resize(size); DWORD read; if (!ReadFile(handle, &data[0], size, &read, nullptr)) - throw strprintf("Failed to write file '%s': %lu", - file, GetLastError()); + throw strprintf("Failed to write file '%s': %lu", file, + GetLastError()); return true; -} catch (string text) { +} catch (string &text) { blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str()); return false; } @@ -196,7 +184,7 @@ static void HashToString(const uint8_t *in, char *out) const char alphabet[] = "0123456789abcdef"; for (int i = 0; i != BLAKE2_HASH_LENGTH; ++i) { - out[2 * i] = alphabet[in[i] / 16]; + out[2 * i] = alphabet[in[i] / 16]; out[2 * i + 1] = alphabet[in[i] % 16]; } @@ -214,10 +202,10 @@ try { return false; WinHandle handle = CreateFileW(w_path, GENERIC_READ, FILE_SHARE_READ, - nullptr, OPEN_EXISTING, 0, nullptr); + nullptr, OPEN_EXISTING, 0, nullptr); if (handle == INVALID_HANDLE_VALUE) - throw strprintf("Failed to open file '%s': %lu", - path, GetLastError()); + throw strprintf("Failed to open file '%s': %lu", path, + GetLastError()); vector buf; buf.resize(65536); @@ -225,9 +213,9 @@ try { for (;;) { DWORD read = 0; if (!ReadFile(handle, buf.data(), (DWORD)buf.size(), &read, - nullptr)) - throw strprintf("Failed to read file '%s': %lu", - path, GetLastError()); + nullptr)) + throw strprintf("Failed to read file '%s': %lu", path, + GetLastError()); if (!read) break; @@ -241,7 +229,7 @@ try { return true; -} catch (string text) { +} catch (string &text) { blog(LOG_DEBUG, "%s: %s", __FUNCTION__, text.c_str()); return false; } @@ -249,19 +237,19 @@ try { /* ------------------------------------------------------------------------ */ static bool VerifyDigitalSignature(uint8_t *buf, size_t len, uint8_t *sig, - size_t sigLen) + size_t sigLen) { /* ASN of PEM public key */ - BYTE binaryKey[1024]; + BYTE binaryKey[1024]; DWORD binaryKeyLen = sizeof(binaryKey); /* Windows X509 public key info from ASN */ LocalPtr publicPBLOB; - DWORD iPBLOBSize; + DWORD iPBLOBSize; /* RSA BLOB info from X509 public key */ LocalPtr rsaPublicBLOB; - DWORD rsaPublicBLOBSize; + DWORD rsaPublicBLOBSize; /* Handle to public key */ CryptKey keyOut; @@ -272,41 +260,26 @@ static bool VerifyDigitalSignature(uint8_t *buf, size_t len, uint8_t *sig, /* Signature in little-endian format */ vector reversedSig; - if (!CryptStringToBinaryA((LPCSTR)obs_pub, - obs_pub_len, - CRYPT_STRING_BASE64HEADER, - binaryKey, - &binaryKeyLen, - nullptr, - nullptr)) + if (!CryptStringToBinaryA((LPCSTR)obs_pub, obs_pub_len, + CRYPT_STRING_BASE64HEADER, binaryKey, + &binaryKeyLen, nullptr, nullptr)) return false; - if (!CryptDecodeObjectEx(X509_ASN_ENCODING, - X509_PUBLIC_KEY_INFO, - binaryKey, - binaryKeyLen, - CRYPT_ENCODE_ALLOC_FLAG, - nullptr, - &publicPBLOB, - &iPBLOBSize)) + if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, + binaryKey, binaryKeyLen, + CRYPT_ENCODE_ALLOC_FLAG, nullptr, &publicPBLOB, + &iPBLOBSize)) return false; - if (!CryptDecodeObjectEx(X509_ASN_ENCODING, - RSA_CSP_PUBLICKEYBLOB, - publicPBLOB->PublicKey.pbData, - publicPBLOB->PublicKey.cbData, - CRYPT_ENCODE_ALLOC_FLAG, - nullptr, - &rsaPublicBLOB, - &rsaPublicBLOBSize)) + if (!CryptDecodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB, + publicPBLOB->PublicKey.pbData, + publicPBLOB->PublicKey.cbData, + CRYPT_ENCODE_ALLOC_FLAG, nullptr, + &rsaPublicBLOB, &rsaPublicBLOBSize)) return false; - if (!CryptImportKey(provider, - (const BYTE *)rsaPublicBLOB.get(), - rsaPublicBLOBSize, - 0, - 0, - &keyOut)) + if (!CryptImportKey(provider, (const BYTE *)rsaPublicBLOB.get(), + rsaPublicBLOBSize, 0, 0, &keyOut)) return false; if (!CryptCreateHash(provider, CALG_SHA_512, 0, 0, &hash)) @@ -321,19 +294,15 @@ static bool VerifyDigitalSignature(uint8_t *buf, size_t len, uint8_t *sig, for (size_t i = 0; i < sigLen; i++) reversedSig[i] = sig[sigLen - i - 1]; - if (!CryptVerifySignature(hash, - reversedSig.data(), - (DWORD)sigLen, - keyOut, - nullptr, - 0)) + if (!CryptVerifySignature(hash, reversedSig.data(), (DWORD)sigLen, + keyOut, nullptr, 0)) return false; return true; } static inline void HexToByteArray(const char *hexStr, size_t hexLen, - vector &out) + vector &out) { char ptr[3]; @@ -347,7 +316,7 @@ static inline void HexToByteArray(const char *hexStr, size_t hexLen, } static bool CheckDataSignature(const string &data, const char *name, - const char *hexSig, size_t sigLen) + const char *hexSig, size_t sigLen) try { if (sigLen == 0 || sigLen > 0xFFFF || (sigLen & 1) != 0) throw strprintf("Missing or invalid signature for %s", name); @@ -357,15 +326,13 @@ try { signature.reserve(sigLen); HexToByteArray(hexSig, sigLen, signature); - if (!VerifyDigitalSignature((uint8_t*)data.data(), - data.size(), - signature.data(), - signature.size())) + if (!VerifyDigitalSignature((uint8_t *)data.data(), data.size(), + signature.data(), signature.size())) throw strprintf("Signature check failed for %s", name); return true; -} catch (string text) { +} catch (string &text) { blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str()); return false; } @@ -374,12 +341,12 @@ try { static bool FetchUpdaterModule(const char *url) try { - long responseCode; - uint8_t updateFileHash[BLAKE2_HASH_LENGTH]; + long responseCode; + uint8_t updateFileHash[BLAKE2_HASH_LENGTH]; vector extraHeaders; - BPtr updateFilePath = GetConfigPathPtr( - "obs-studio\\updates\\updater.exe"); + BPtr updateFilePath = + GetConfigPathPtr("obs-studio\\updates\\updater.exe"); if (CalculateFileHash(updateFilePath, updateFileHash)) { char hashString[BLAKE2_HASH_STR_LENGTH]; @@ -394,8 +361,8 @@ try { string error; string data; - bool success = GetRemoteFile(url, data, error, &responseCode, - nullptr, nullptr, extraHeaders, &signature); + bool success = GetRemoteFile(url, data, error, &responseCode, nullptr, + nullptr, extraHeaders, &signature); if (!success || (responseCode != 200 && responseCode != 304)) { if (responseCode == 404) @@ -407,7 +374,7 @@ try { /* A new file must be digitally signed */ if (responseCode == 200) { bool valid = CheckDataSignature(data, url, signature.data(), - signature.size()); + signature.size()); if (!valid) throw string("Invalid updater module signature"); @@ -417,7 +384,7 @@ try { return true; -} catch (string text) { +} catch (string &text) { blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str()); return false; } @@ -425,7 +392,7 @@ try { /* ------------------------------------------------------------------------ */ static bool ParseUpdateManifest(const char *manifest, bool *updatesAvailable, - string ¬es_str, int &updateVer) + string ¬es_str, int &updateVer) try { json_error_t error; @@ -442,10 +409,8 @@ try { int patch = root.GetInt("version_patch"); if (major == 0) - throw strprintf("Invalid version number: %d.%d.%d", - major, - minor, - patch); + throw strprintf("Invalid version number: %d.%d.%d", major, + minor, patch); json_t *notes = json_object_get(root, "notes"); if (!json_is_string(notes)) @@ -465,7 +430,7 @@ try { return true; -} catch (string text) { +} catch (string &text) { blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str()); return false; } @@ -491,8 +456,8 @@ string GetProgramGUID() /* NOTE: this is an arbitrary random number that we use to count the * number of unique OBS installations and is not associated with any * kind of identifiable information */ - const char *pguid = config_get_string(GetGlobalConfig(), - "General", "InstallGUID"); + const char *pguid = + config_get_string(GetGlobalConfig(), "General", "InstallGUID"); string guid; if (pguid) guid = pguid; @@ -501,9 +466,8 @@ string GetProgramGUID() GenerateGUID(guid); if (!guid.empty()) - config_set_string(GetGlobalConfig(), - "General", "InstallGUID", - guid.c_str()); + config_set_string(GetGlobalConfig(), "General", + "InstallGUID", guid.c_str()); } return guid; @@ -516,13 +480,12 @@ void AutoUpdateThread::infoMsg(const QString &title, const QString &text) void AutoUpdateThread::info(const QString &title, const QString &text) { - QMetaObject::invokeMethod(this, "infoMsg", - Qt::BlockingQueuedConnection, - Q_ARG(QString, title), - Q_ARG(QString, text)); + QMetaObject::invokeMethod(this, "infoMsg", Qt::BlockingQueuedConnection, + Q_ARG(QString, title), Q_ARG(QString, text)); } -int AutoUpdateThread::queryUpdateSlot(bool localManualUpdate, const QString &text) +int AutoUpdateThread::queryUpdateSlot(bool localManualUpdate, + const QString &text) { OBSUpdate updateDlg(App()->GetMainWindow(), localManualUpdate, text); return updateDlg.exec(); @@ -533,17 +496,17 @@ int AutoUpdateThread::queryUpdate(bool localManualUpdate, const char *text_utf8) int ret = OBSUpdate::No; QString text = text_utf8; QMetaObject::invokeMethod(this, "queryUpdateSlot", - Qt::BlockingQueuedConnection, - Q_RETURN_ARG(int, ret), - Q_ARG(bool, localManualUpdate), - Q_ARG(QString, text)); + Qt::BlockingQueuedConnection, + Q_RETURN_ARG(int, ret), + Q_ARG(bool, localManualUpdate), + Q_ARG(QString, text)); return ret; } static bool IsFileInUse(const wstring &file) { WinHandle f = CreateFile(file.c_str(), GENERIC_WRITE, 0, nullptr, - OPEN_EXISTING, 0, nullptr); + OPEN_EXISTING, 0, nullptr); if (!f.Valid()) { int err = GetLastError(); if (err == ERROR_SHARING_VIOLATION || @@ -557,35 +520,33 @@ static bool IsFileInUse(const wstring &file) static bool IsGameCaptureInUse() { wstring path = L"..\\..\\data\\obs-plugins\\win-capture\\graphics-hook"; - return IsFileInUse(path + L"32.dll") || - IsFileInUse(path + L"64.dll"); + return IsFileInUse(path + L"32.dll") || IsFileInUse(path + L"64.dll"); } void AutoUpdateThread::run() try { - long responseCode; + long responseCode; vector extraHeaders; - string text; - string error; - string signature; - CryptProvider localProvider; - BYTE manifestHash[BLAKE2_HASH_LENGTH]; - bool updatesAvailable = false; - bool success; + string text; + string error; + string signature; + CryptProvider localProvider; + BYTE manifestHash[BLAKE2_HASH_LENGTH]; + bool updatesAvailable = false; + bool success; struct FinishedTrigger { inline ~FinishedTrigger() { QMetaObject::invokeMethod(App()->GetMainWindow(), - "updateCheckFinished"); + "updateCheckFinished"); } } finishedTrigger; - BPtr manifestPath = GetConfigPathPtr( - "obs-studio\\updates\\manifest.json"); + BPtr manifestPath = + GetConfigPathPtr("obs-studio\\updates\\manifest.json"); - auto ActiveOrGameCaptureLocked = [this] () - { + auto ActiveOrGameCaptureLocked = [this]() { if (obs_video_active()) { if (manualUpdate) info(QTStr("Updater.Running.Title"), @@ -611,11 +572,8 @@ try { /* ----------------------------------- * * create signature provider */ - if (!CryptAcquireContext(&localProvider, - nullptr, - MS_ENH_RSA_AES_PROV, - PROV_RSA_AES, - CRYPT_VERIFYCONTEXT)) + if (!CryptAcquireContext(&localProvider, nullptr, MS_ENH_RSA_AES_PROV, + PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) throw strprintf("CryptAcquireContext failed: %lu", GetLastError()); @@ -647,13 +605,14 @@ try { * get manifest from server */ success = GetRemoteFile(WIN_MANIFEST_URL, text, error, &responseCode, - nullptr, nullptr, extraHeaders, &signature); + nullptr, nullptr, extraHeaders, &signature); if (!success || (responseCode != 200 && responseCode != 304)) { if (responseCode == 404) return; - throw strprintf("Failed to fetch manifest file: %s", error.c_str()); + throw strprintf("Failed to fetch manifest file: %s", + error.c_str()); } /* ----------------------------------- * @@ -661,8 +620,8 @@ try { /* a new file must be digitally signed */ if (responseCode == 200) { - success = CheckDataSignature(text, "manifest", - signature.data(), signature.size()); + success = CheckDataSignature(text, "manifest", signature.data(), + signature.size()); if (!success) throw string("Invalid manifest signature"); } @@ -687,7 +646,7 @@ try { int updateVer = 0; success = ParseUpdateManifest(text.c_str(), &updatesAvailable, notes, - updateVer); + updateVer); if (!success) throw string("Failed to parse manifest"); @@ -702,7 +661,7 @@ try { * skip this version if set to skip */ int skipUpdateVer = config_get_int(GetGlobalConfig(), "General", - "SkipUpdateVersion"); + "SkipUpdateVersion"); if (!manualUpdate && updateVer == skipUpdateVer) return; @@ -727,13 +686,13 @@ try { if (!manualUpdate) { long long t = (long long)time(nullptr); config_set_int(GetGlobalConfig(), "General", - "LastUpdateCheck", t); + "LastUpdateCheck", t); } return; } else if (queryResult == OBSUpdate::Skip) { config_set_int(GetGlobalConfig(), "General", - "SkipUpdateVersion", updateVer); + "SkipUpdateVersion", updateVer); return; } @@ -749,8 +708,8 @@ try { /* ----------------------------------- * * execute updater */ - BPtr updateFilePath = GetConfigPathPtr( - "obs-studio\\updates\\updater.exe"); + BPtr updateFilePath = + GetConfigPathPtr("obs-studio\\updates\\updater.exe"); BPtr wUpdateFilePath; size_t size = os_utf8_to_wcs_ptr(updateFilePath, 0, &wUpdateFilePath); @@ -773,7 +732,7 @@ try { execInfo.lpParameters = UPDATE_ARG_SUFFIX; execInfo.lpDirectory = cwd; - execInfo.nShow = SW_SHOWNORMAL; + execInfo.nShow = SW_SHOWNORMAL; if (!ShellExecuteEx(&execInfo)) { QString msg = QTStr("Updater.FailedToLaunch"); @@ -787,11 +746,11 @@ try { config_set_int(GetGlobalConfig(), "General", "LastUpdateCheck", 0); config_set_int(GetGlobalConfig(), "General", "SkipUpdateVersion", 0); config_set_string(GetGlobalConfig(), "General", "InstallGUID", - guid.c_str()); + guid.c_str()); QMetaObject::invokeMethod(App()->GetMainWindow(), "close"); -} catch (string text) { +} catch (string &text) { blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str()); } @@ -799,26 +758,23 @@ try { void WhatsNewInfoThread::run() try { - long responseCode; + long responseCode; vector extraHeaders; - string text; - string error; - string signature; - CryptProvider localProvider; - BYTE whatsnewHash[BLAKE2_HASH_LENGTH]; - bool success; + string text; + string error; + string signature; + CryptProvider localProvider; + BYTE whatsnewHash[BLAKE2_HASH_LENGTH]; + bool success; - BPtr whatsnewPath = GetConfigPathPtr( - "obs-studio\\updates\\whatsnew.json"); + BPtr whatsnewPath = + GetConfigPathPtr("obs-studio\\updates\\whatsnew.json"); /* ----------------------------------- * * create signature provider */ - if (!CryptAcquireContext(&localProvider, - nullptr, - MS_ENH_RSA_AES_PROV, - PROV_RSA_AES, - CRYPT_VERIFYCONTEXT)) + if (!CryptAcquireContext(&localProvider, nullptr, MS_ENH_RSA_AES_PROV, + PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) throw strprintf("CryptAcquireContext failed: %lu", GetLastError()); @@ -851,7 +807,7 @@ try { * get json from server */ success = GetRemoteFile(WIN_WHATSNEW_URL, text, error, &responseCode, - nullptr, nullptr, extraHeaders, &signature); + nullptr, nullptr, extraHeaders, &signature); if (!success || (responseCode != 200 && responseCode != 304)) { if (responseCode == 404) @@ -865,8 +821,8 @@ try { * verify file signature */ if (responseCode == 200) { - success = CheckDataSignature(text, "whatsnew", - signature.data(), signature.size()); + success = CheckDataSignature(text, "whatsnew", signature.data(), + signature.size()); if (!success) throw string("Invalid whatsnew signature"); } @@ -889,6 +845,6 @@ try { emit Result(QString::fromUtf8(text.c_str())); -} catch (string text) { +} catch (string &text) { blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str()); } diff --git a/UI/window-basic-about.cpp b/UI/window-basic-about.cpp index eb9ca7b..73d9bdb 100644 --- a/UI/window-basic-about.cpp +++ b/UI/window-basic-about.cpp @@ -9,9 +9,7 @@ using namespace json11; -OBSAbout::OBSAbout(QWidget *parent) - : QDialog(parent), - ui(new Ui::OBSAbout) +OBSAbout::OBSAbout(QWidget *parent) : QDialog(parent), ui(new Ui::OBSAbout) { ui->setupUi(this); @@ -20,29 +18,30 @@ OBSAbout::OBSAbout(QWidget *parent) QString bitness; QString ver; - if(sizeof(void*) == 4) + if (sizeof(void *) == 4) bitness = " (32 bit)"; - else if(sizeof(void*) == 8) + else if (sizeof(void *) == 8) bitness = " (64 bit)"; #ifdef HAVE_OBSCONFIG_H - ver += OBS_VERSION; + ver += OBS_VERSION; #else - ver += LIBOBS_API_MAJOR_VER + "." + - LIBOBS_API_MINOR_VER + "." + - LIBOBS_API_PATCH_VER; + ver += LIBOBS_API_MAJOR_VER + "." + LIBOBS_API_MINOR_VER + "." + + LIBOBS_API_PATCH_VER; #endif ui->version->setText(ver + bitness); ui->contribute->setText(QTStr("About.Contribute")); - ui->donate->setText("  " + - QTStr("About.Donate") + ""); + ui->donate->setText( + "  " + + QTStr("About.Donate") + ""); ui->donate->setTextInteractionFlags(Qt::TextBrowserInteraction); ui->donate->setOpenExternalLinks(true); - ui->getInvolved->setText("  " + - QTStr("About.GetInvolved") + ""); + ui->getInvolved->setText( + "  " + + QTStr("About.GetInvolved") + ""); ui->getInvolved->setTextInteractionFlags(Qt::TextBrowserInteraction); ui->getInvolved->setOpenExternalLinks(true); @@ -66,12 +65,14 @@ OBSAbout::OBSAbout(QWidget *parent) OBSBasic *main = OBSBasic::Get(); if (main->patronJson.empty() && !main->patronJsonThread) { RemoteTextThread *thread = new RemoteTextThread( - "https://obsproject.com/patreon/about-box.json", - "application/json"); - QObject::connect(thread, &RemoteTextThread::Result, - main, &OBSBasic::UpdatePatronJson); - QObject::connect(thread, SIGNAL(Result(const QString &, const QString &)), - this, SLOT(ShowAbout())); + "https://obsproject.com/patreon/about-box.json", + "application/json"); + QObject::connect(thread, &RemoteTextThread::Result, main, + &OBSBasic::UpdatePatronJson); + QObject::connect( + thread, + SIGNAL(Result(const QString &, const QString &)), this, + SLOT(ShowAbout())); main->patronJsonThread.reset(thread); thread->start(); } else { diff --git a/UI/window-basic-adv-audio.cpp b/UI/window-basic-adv-audio.cpp index 03b4233..5824cfd 100644 --- a/UI/window-basic-adv-audio.cpp +++ b/UI/window-basic-adv-audio.cpp @@ -16,9 +16,9 @@ Q_DECLARE_METATYPE(OBSSource); OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent) : QDialog(parent), sourceAddedSignal(obs_get_signal_handler(), "source_activate", - OBSSourceAdded, this), + OBSSourceAdded, this), sourceRemovedSignal(obs_get_signal_handler(), "source_deactivate", - OBSSourceRemoved, this) + OBSSourceRemoved, this) { QScrollArea *scrollArea; QVBoxLayout *vlayout; @@ -29,33 +29,33 @@ OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent) mainLayout = new QGridLayout; mainLayout->setContentsMargins(0, 0, 0, 0); label = new QLabel(QTStr("Basic.AdvAudio.Name")); - label->setAlignment(Qt::AlignHCenter); + label->setStyleSheet("font-weight: bold;"); mainLayout->addWidget(label, 0, idx++); label = new QLabel(QTStr("Basic.AdvAudio.Volume")); - label->setAlignment(Qt::AlignHCenter); + label->setStyleSheet("font-weight: bold;"); mainLayout->addWidget(label, 0, idx++); label = new QLabel(QTStr("Basic.AdvAudio.Mono")); - label->setAlignment(Qt::AlignHCenter); + label->setStyleSheet("font-weight: bold;"); mainLayout->addWidget(label, 0, idx++); label = new QLabel(QTStr("Basic.AdvAudio.Balance")); - label->setAlignment(Qt::AlignHCenter); + label->setStyleSheet("font-weight: bold;"); mainLayout->addWidget(label, 0, idx++); label = new QLabel(QTStr("Basic.AdvAudio.SyncOffset")); - label->setAlignment(Qt::AlignHCenter); + label->setStyleSheet("font-weight: bold;"); mainLayout->addWidget(label, 0, idx++); #if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO label = new QLabel(QTStr("Basic.AdvAudio.Monitoring")); - label->setAlignment(Qt::AlignHCenter); + label->setStyleSheet("font-weight: bold;"); mainLayout->addWidget(label, 0, idx++); #endif label = new QLabel(QTStr("Basic.AdvAudio.AudioTracks")); - label->setAlignment(Qt::AlignHCenter); + label->setStyleSheet("font-weight: bold;"); mainLayout->addWidget(label, 0, idx++); controlArea = new QWidget; controlArea->setLayout(mainLayout); controlArea->setSizePolicy(QSizePolicy::Preferred, - QSizePolicy::Preferred); + QSizePolicy::Preferred); vlayout = new QVBoxLayout; vlayout->addWidget(controlArea); @@ -80,14 +80,14 @@ OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent) vlayout->addLayout(buttonLayout); setLayout(vlayout); - connect(closeButton, &QPushButton::clicked, [this] () {close();}); + connect(closeButton, &QPushButton::clicked, [this]() { close(); }); installEventFilter(CreateShortcutFilter()); /* enum user scene/sources */ obs_enum_sources(EnumSources, this); - resize(1000, 340); + resize(1100, 340); setWindowTitle(QTStr("Basic.AdvAudio")); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setSizeGripEnabled(true); @@ -97,7 +97,7 @@ OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent) OBSBasicAdvAudio::~OBSBasicAdvAudio() { - OBSBasic *main = reinterpret_cast(parent()); + OBSBasic *main = reinterpret_cast(parent()); for (size_t i = 0; i < controls.size(); ++i) delete controls[i]; @@ -107,7 +107,7 @@ OBSBasicAdvAudio::~OBSBasicAdvAudio() bool OBSBasicAdvAudio::EnumSources(void *param, obs_source_t *source) { - OBSBasicAdvAudio *dialog = reinterpret_cast(param); + OBSBasicAdvAudio *dialog = reinterpret_cast(param); uint32_t flags = obs_source_get_output_flags(source); if ((flags & OBS_SOURCE_AUDIO) != 0 && obs_source_active(source)) @@ -118,18 +118,18 @@ bool OBSBasicAdvAudio::EnumSources(void *param, obs_source_t *source) void OBSBasicAdvAudio::OBSSourceAdded(void *param, calldata_t *calldata) { - OBSSource source((obs_source_t*)calldata_ptr(calldata, "source")); + OBSSource source((obs_source_t *)calldata_ptr(calldata, "source")); - QMetaObject::invokeMethod(reinterpret_cast(param), - "SourceAdded", Q_ARG(OBSSource, source)); + QMetaObject::invokeMethod(reinterpret_cast(param), + "SourceAdded", Q_ARG(OBSSource, source)); } void OBSBasicAdvAudio::OBSSourceRemoved(void *param, calldata_t *calldata) { - OBSSource source((obs_source_t*)calldata_ptr(calldata, "source")); + OBSSource source((obs_source_t *)calldata_ptr(calldata, "source")); - QMetaObject::invokeMethod(reinterpret_cast(param), - "SourceRemoved", Q_ARG(OBSSource, source)); + QMetaObject::invokeMethod(reinterpret_cast(param), + "SourceRemoved", Q_ARG(OBSSource, source)); } inline void OBSBasicAdvAudio::AddAudioSource(obs_source_t *source) diff --git a/UI/window-basic-adv-audio.hpp b/UI/window-basic-adv-audio.hpp index 3ec60c7..77b520f 100644 --- a/UI/window-basic-adv-audio.hpp +++ b/UI/window-basic-adv-audio.hpp @@ -18,7 +18,7 @@ private: OBSSignal sourceAddedSignal; OBSSignal sourceRemovedSignal; - std::vector controls; + std::vector controls; inline void AddAudioSource(obs_source_t *source); diff --git a/UI/window-basic-auto-config-test.cpp b/UI/window-basic-auto-config-test.cpp index d4ba22c..e62acd3 100644 --- a/UI/window-basic-auto-config-test.cpp +++ b/UI/window-basic-auto-config-test.cpp @@ -15,7 +15,7 @@ #include "ui_AutoConfigTestPage.h" -#define wiz reinterpret_cast(wizard()) +#define wiz reinterpret_cast(wizard()) using namespace std; @@ -31,17 +31,14 @@ class TestMode { gs_eparam_t *randomvals[3] = { gs_effect_get_param_by_name(solid, "randomvals1"), gs_effect_get_param_by_name(solid, "randomvals2"), - gs_effect_get_param_by_name(solid, "randomvals3") - }; + gs_effect_get_param_by_name(solid, "randomvals3")}; struct vec4 r; for (int i = 0; i < 3; i++) { - vec4_set(&r, - rand_float(true) * 100.0f, - rand_float(true) * 100.0f, - rand_float(true) * 50000.0f + 10000.0f, - 0.0f); + vec4_set(&r, rand_float(true) * 100.0f, + rand_float(true) * 100.0f, + rand_float(true) * 50000.0f + 10000.0f, 0.0f); gs_effect_set_vec4(randomvals[i], &r); } @@ -86,37 +83,37 @@ public: /* ------------------------------------------------------------------------- */ -#define TEST_STR(x) "Basic.AutoConfig.TestPage." x -#define SUBTITLE_TESTING TEST_STR("Subtitle.Testing") -#define SUBTITLE_COMPLETE TEST_STR("Subtitle.Complete") -#define TEST_BW TEST_STR("TestingBandwidth") -#define TEST_BW_CONNECTING TEST_STR("TestingBandwidth.Connecting") -#define TEST_BW_CONNECT_FAIL TEST_STR("TestingBandwidth.ConnectFailed") -#define TEST_BW_SERVER TEST_STR("TestingBandwidth.Server") -#define TEST_RES TEST_STR("TestingRes") -#define TEST_RES_VAL TEST_STR("TestingRes.Resolution") -#define TEST_RES_FAIL TEST_STR("TestingRes.Fail") -#define TEST_SE TEST_STR("TestingStreamEncoder") -#define TEST_RE TEST_STR("TestingRecordingEncoder") -#define TEST_RESULT_SE TEST_STR("Result.StreamingEncoder") -#define TEST_RESULT_RE TEST_STR("Result.RecordingEncoder") +#define TEST_STR(x) "Basic.AutoConfig.TestPage." x +#define SUBTITLE_TESTING TEST_STR("Subtitle.Testing") +#define SUBTITLE_COMPLETE TEST_STR("Subtitle.Complete") +#define TEST_BW TEST_STR("TestingBandwidth") +#define TEST_BW_CONNECTING TEST_STR("TestingBandwidth.Connecting") +#define TEST_BW_CONNECT_FAIL TEST_STR("TestingBandwidth.ConnectFailed") +#define TEST_BW_SERVER TEST_STR("TestingBandwidth.Server") +#define TEST_RES TEST_STR("TestingRes") +#define TEST_RES_VAL TEST_STR("TestingRes.Resolution") +#define TEST_RES_FAIL TEST_STR("TestingRes.Fail") +#define TEST_SE TEST_STR("TestingStreamEncoder") +#define TEST_RE TEST_STR("TestingRecordingEncoder") +#define TEST_RESULT_SE TEST_STR("Result.StreamingEncoder") +#define TEST_RESULT_RE TEST_STR("Result.RecordingEncoder") void AutoConfigTestPage::StartBandwidthStage() { ui->progressLabel->setText(QTStr(TEST_BW)); - testThread = std::thread([this] () {TestBandwidthThread();}); + testThread = std::thread([this]() { TestBandwidthThread(); }); } void AutoConfigTestPage::StartStreamEncoderStage() { ui->progressLabel->setText(QTStr(TEST_SE)); - testThread = std::thread([this] () {TestStreamEncoderThread();}); + testThread = std::thread([this]() { TestStreamEncoderThread(); }); } void AutoConfigTestPage::StartRecordingEncoderStage() { ui->progressLabel->setText(QTStr(TEST_RE)); - testThread = std::thread([this] () {TestRecordingEncoderThread();}); + testThread = std::thread([this]() { TestRecordingEncoderThread(); }); } void AutoConfigTestPage::GetServers(std::vector &servers) @@ -176,21 +173,20 @@ void AutoConfigTestPage::TestBandwidthThread() */ QMetaObject::invokeMethod(this, "UpdateMessage", - Q_ARG(QString, QStringLiteral(""))); + Q_ARG(QString, QStringLiteral(""))); /* -----------------------------------*/ /* create obs objects */ - const char *serverType = wiz->customServer - ? "rtmp_custom" - : "rtmp_common"; + const char *serverType = wiz->customServer ? "rtmp_custom" + : "rtmp_common"; - OBSEncoder vencoder = obs_video_encoder_create("obs_x264", - "test_x264", nullptr, nullptr); - OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac", - "test_aac", nullptr, 0, nullptr); - OBSService service = obs_service_create(serverType, - "test_service", nullptr, nullptr); + OBSEncoder vencoder = obs_video_encoder_create("obs_x264", "test_x264", + nullptr, nullptr); + OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac", "test_aac", + nullptr, 0, nullptr); + OBSService service = obs_service_create(serverType, "test_service", + nullptr, nullptr); obs_encoder_release(vencoder); obs_encoder_release(aencoder); obs_service_release(service); @@ -218,14 +214,17 @@ void AutoConfigTestPage::TestBandwidthThread() if (wiz->service == AutoConfig::Service::Twitch) { string_depad_key(key); key += "?bandwidthtest"; - } - else if(wiz->serviceName == "Restream.io" || wiz->serviceName == "Restream.io - RTMP") { + } else if (wiz->serviceName == "Restream.io" || + wiz->serviceName == "Restream.io - RTMP") { string_depad_key(key); key += "?test=true"; + } else if (wiz->serviceName == "Restream.io - FTL") { + string_depad_key(key); + key += "?test"; } obs_data_set_string(service_settings, "service", - wiz->serviceName.c_str()); + wiz->serviceName.c_str()); obs_data_set_string(service_settings, "key", key.c_str()); obs_data_set_int(vencoder_settings, "bitrate", wiz->startingBitrate); @@ -235,9 +234,9 @@ void AutoConfigTestPage::TestBandwidthThread() obs_data_set_int(aencoder_settings, "bitrate", 32); - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); - const char *bind_ip = config_get_string(main->Config(), "Output", - "BindIP"); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + const char *bind_ip = + config_get_string(main->Config(), "Output", "BindIP"); obs_data_set_string(output_settings, "bind_ip", bind_ip); /* -----------------------------------*/ @@ -251,12 +250,12 @@ void AutoConfigTestPage::TestBandwidthThread() /* just use the first server if it only has one alternate server, * or if using Mixer or Restream due to their "auto" servers */ - if (servers.size() < 3 || wiz->serviceName == "Mixer.com - FTL" || - wiz->serviceName.substr(0, 11)=="Restream.io") { + if (servers.size() < 3 || wiz->serviceName == "Mixer.com - FTL" || + wiz->serviceName.substr(0, 11) == "Restream.io") { servers.resize(1); } else if (wiz->service == AutoConfig::Service::Twitch && - wiz->twitchAuto) { + wiz->twitchAuto) { /* if using Twitch and "Auto" is available, test 3 closest * server */ servers.erase(servers.begin() + 1); @@ -267,8 +266,8 @@ void AutoConfigTestPage::TestBandwidthThread() /* apply service settings */ obs_service_update(service, service_settings); - obs_service_apply_encoder_settings(service, - vencoder_settings, aencoder_settings); + obs_service_apply_encoder_settings(service, vencoder_settings, + aencoder_settings); /* -----------------------------------*/ /* create output */ @@ -277,18 +276,17 @@ void AutoConfigTestPage::TestBandwidthThread() if (!output_type) output_type = "rtmp_output"; - OBSOutput output = obs_output_create(output_type, - "test_stream", nullptr, nullptr); + OBSOutput output = + obs_output_create(output_type, "test_stream", nullptr, nullptr); obs_output_release(output); obs_output_update(output, output_settings); - const char *audio_codec = - obs_output_get_supported_audio_codecs(output); + const char *audio_codec = obs_output_get_supported_audio_codecs(output); if (strcmp(audio_codec, "aac") != 0) { const char *id = FindAudioEncoderFromCodec(audio_codec); - aencoder = obs_audio_encoder_create(id, - "test_audio", nullptr, 0, nullptr); + aencoder = obs_audio_encoder_create(id, "test_audio", nullptr, + 0, nullptr); obs_encoder_release(aencoder); } @@ -308,16 +306,14 @@ void AutoConfigTestPage::TestBandwidthThread() /* -----------------------------------*/ /* connect signals */ - auto on_started = [&] () - { + auto on_started = [&]() { unique_lock lock(m); connected = true; stopped = false; cv.notify_one(); }; - auto on_stopped = [&] () - { + auto on_stopped = [&]() { unique_lock lock(m); connected = false; stopped = true; @@ -327,17 +323,15 @@ void AutoConfigTestPage::TestBandwidthThread() using on_started_t = decltype(on_started); using on_stopped_t = decltype(on_stopped); - auto pre_on_started = [] (void *data, calldata_t *) - { + auto pre_on_started = [](void *data, calldata_t *) { on_started_t &on_started = - *reinterpret_cast(data); + *reinterpret_cast(data); on_started(); }; - auto pre_on_stopped = [] (void *data, calldata_t *) - { + auto pre_on_stopped = [](void *data, calldata_t *) { on_stopped_t &on_stopped = - *reinterpret_cast(data); + *reinterpret_cast(data); on_stopped(); }; @@ -358,12 +352,13 @@ void AutoConfigTestPage::TestBandwidthThread() int per = int((i + 1) * 100 / servers.size()); QMetaObject::invokeMethod(this, "Progress", Q_ARG(int, per)); - QMetaObject::invokeMethod(this, "UpdateMessage", - Q_ARG(QString, QTStr(TEST_BW_CONNECTING) - .arg(server.name.c_str()))); + QMetaObject::invokeMethod( + this, "UpdateMessage", + Q_ARG(QString, QTStr(TEST_BW_CONNECTING) + .arg(server.name.c_str()))); obs_data_set_string(service_settings, "server", - server.address.c_str()); + server.address.c_str()); obs_service_update(service, service_settings); if (!obs_output_start(output)) @@ -385,9 +380,10 @@ void AutoConfigTestPage::TestBandwidthThread() if (!connected) continue; - QMetaObject::invokeMethod(this, "UpdateMessage", - Q_ARG(QString, QTStr(TEST_BW_SERVER) - .arg(server.name.c_str()))); + QMetaObject::invokeMethod( + this, "UpdateMessage", + Q_ARG(QString, + QTStr(TEST_BW_SERVER).arg(server.name.c_str()))); /* ignore first 2.5 seconds due to possible buffering skewing * the result */ @@ -418,10 +414,10 @@ void AutoConfigTestPage::TestBandwidthThread() uint64_t total_time = os_gettime_ns() - t_start; - int total_bytes = (int)obs_output_get_total_bytes(output) - - start_bytes; - uint64_t bitrate = (uint64_t)total_bytes * 8 - * 1000000000 / total_time / 1000; + int total_bytes = + (int)obs_output_get_total_bytes(output) - start_bytes; + uint64_t bitrate = (uint64_t)total_bytes * 8 * 1000000000 / + total_time / 1000; if (obs_output_get_frames_dropped(output) || (int)bitrate < (wiz->startingBitrate * 75 / 100)) { @@ -436,7 +432,8 @@ void AutoConfigTestPage::TestBandwidthThread() if (!success) { QMetaObject::invokeMethod(this, "Failure", - Q_ARG(QString, QTStr(TEST_BW_CONNECT_FAIL))); + Q_ARG(QString, + QTStr(TEST_BW_CONNECT_FAIL))); return; } @@ -480,7 +477,8 @@ static long double EstimateMinBitrate(int cx, int cy, int fps_num, int fps_den) return EstimateBitrateVal(cx, cy, fps_num, fps_den) / val; } -static long double EstimateUpperBitrate(int cx, int cy, int fps_num, int fps_den) +static long double EstimateUpperBitrate(int cx, int cy, int fps_num, + int fps_den) { long double val = EstimateBitrateVal(1280, 720, 30, 1) / 3000.0l; return EstimateBitrateVal(cx, cy, fps_num, fps_den) / val; @@ -520,17 +518,17 @@ bool AutoConfigTestPage::TestSoftwareEncoding() { TestMode testMode; QMetaObject::invokeMethod(this, "UpdateMessage", - Q_ARG(QString, QStringLiteral(""))); + Q_ARG(QString, QStringLiteral(""))); /* -----------------------------------*/ /* create obs objects */ - OBSEncoder vencoder = obs_video_encoder_create("obs_x264", - "test_x264", nullptr, nullptr); - OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac", - "test_aac", nullptr, 0, nullptr); - OBSOutput output = obs_output_create("null_output", - "null", nullptr, nullptr); + OBSEncoder vencoder = obs_video_encoder_create("obs_x264", "test_x264", + nullptr, nullptr); + OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac", "test_aac", + nullptr, 0, nullptr); + OBSOutput output = + obs_output_create("null_output", "null", nullptr, nullptr); obs_output_release(output); obs_encoder_release(vencoder); obs_encoder_release(aencoder); @@ -547,7 +545,7 @@ bool AutoConfigTestPage::TestSoftwareEncoding() if (wiz->type != AutoConfig::Type::Recording) { obs_data_set_int(vencoder_settings, "keyint_sec", 2); obs_data_set_int(vencoder_settings, "bitrate", - wiz->idealBitrate); + wiz->idealBitrate); obs_data_set_string(vencoder_settings, "rate_control", "CBR"); obs_data_set_string(vencoder_settings, "profile", "main"); obs_data_set_string(vencoder_settings, "preset", "veryfast"); @@ -573,18 +571,16 @@ bool AutoConfigTestPage::TestSoftwareEncoding() /* -----------------------------------*/ /* connect signals */ - auto on_stopped = [&] () - { + auto on_stopped = [&]() { unique_lock lock(m); cv.notify_one(); }; using on_stopped_t = decltype(on_stopped); - auto pre_on_stopped = [] (void *data, calldata_t *) - { + auto pre_on_stopped = [](void *data, calldata_t *) { on_stopped_t &on_stopped = - *reinterpret_cast(data); + *reinterpret_cast(data); on_stopped(); }; @@ -628,9 +624,8 @@ bool AutoConfigTestPage::TestSoftwareEncoding() int i = 0; int count = 1; - auto testRes = [&] (long double div, int fps_num, int fps_den, - bool force) - { + auto testRes = [&](long double div, int fps_num, int fps_den, + bool force) { int per = ++i * 100 / count; QMetaObject::invokeMethod(this, "Progress", Q_ARG(int, per)); @@ -669,13 +664,13 @@ bool AutoConfigTestPage::TestSoftwareEncoding() QString cxStr = QString::number(cx); QString cyStr = QString::number(cy); - QString fpsStr = (fps_den > 1) - ? QString::number(fps, 'f', 2) - : QString::number(fps, 'g', 2); + QString fpsStr = (fps_den > 1) ? QString::number(fps, 'f', 2) + : QString::number(fps, 'g', 2); - QMetaObject::invokeMethod(this, "UpdateMessage", - Q_ARG(QString, QTStr(TEST_RES_VAL) - .arg(cxStr, cyStr, fpsStr))); + QMetaObject::invokeMethod( + this, "UpdateMessage", + Q_ARG(QString, + QTStr(TEST_RES_VAL).arg(cxStr, cyStr, fpsStr))); unique_lock ul(m); if (cancel) @@ -683,7 +678,8 @@ bool AutoConfigTestPage::TestSoftwareEncoding() if (!obs_output_start(output)) { QMetaObject::invokeMethod(this, "Failure", - Q_ARG(QString, QTStr(TEST_RES_FAIL))); + Q_ARG(QString, + QTStr(TEST_RES_FAIL))); return false; } @@ -692,8 +688,8 @@ bool AutoConfigTestPage::TestSoftwareEncoding() obs_output_stop(output); cv.wait(ul); - int skipped = (int)video_output_get_skipped_frames( - obs_get_video()); + int skipped = + (int)video_output_get_skipped_frames(obs_get_video()); if (force || skipped <= 10) results.emplace_back(cx, cy, fps_num, fps_den); @@ -702,23 +698,38 @@ bool AutoConfigTestPage::TestSoftwareEncoding() if (wiz->specificFPSNum && wiz->specificFPSDen) { count = 5; - if (!testRes(1.0, 0, 0, false)) return false; - if (!testRes(1.5, 0, 0, false)) return false; - if (!testRes(1.0 / 0.6, 0, 0, false)) return false; - if (!testRes(2.0, 0, 0, false)) return false; - if (!testRes(2.25, 0, 0, true)) return false; + if (!testRes(1.0, 0, 0, false)) + return false; + if (!testRes(1.5, 0, 0, false)) + return false; + if (!testRes(1.0 / 0.6, 0, 0, false)) + return false; + if (!testRes(2.0, 0, 0, false)) + return false; + if (!testRes(2.25, 0, 0, true)) + return false; } else { count = 10; - if (!testRes(1.0, 60, 1, false)) return false; - if (!testRes(1.0, 30, 1, false)) return false; - if (!testRes(1.5, 60, 1, false)) return false; - if (!testRes(1.5, 30, 1, false)) return false; - if (!testRes(1.0 / 0.6, 60, 1, false)) return false; - if (!testRes(1.0 / 0.6, 30, 1, false)) return false; - if (!testRes(2.0, 60, 1, false)) return false; - if (!testRes(2.0, 30, 1, false)) return false; - if (!testRes(2.25, 60, 1, false)) return false; - if (!testRes(2.25, 30, 1, true)) return false; + if (!testRes(1.0, 60, 1, false)) + return false; + if (!testRes(1.0, 30, 1, false)) + return false; + if (!testRes(1.5, 60, 1, false)) + return false; + if (!testRes(1.5, 30, 1, false)) + return false; + if (!testRes(1.0 / 0.6, 60, 1, false)) + return false; + if (!testRes(1.0 / 0.6, 30, 1, false)) + return false; + if (!testRes(2.0, 60, 1, false)) + return false; + if (!testRes(2.0, 30, 1, false)) + return false; + if (!testRes(2.25, 60, 1, false)) + return false; + if (!testRes(2.25, 30, 1, true)) + return false; } /* -----------------------------------*/ @@ -744,7 +755,7 @@ bool AutoConfigTestPage::TestSoftwareEncoding() wiz->idealFPSDen = result.fps_den; long double fUpperBitrate = EstimateUpperBitrate( - result.cx, result.cy, result.fps_num, result.fps_den); + result.cx, result.cy, result.fps_num, result.fps_den); int upperBitrate = int(floor(fUpperBitrate / 50.0l) * 50.0l); @@ -776,9 +787,8 @@ void AutoConfigTestPage::FindIdealHardwareResolution() maxDataRate = 1280 * 720 * 30 + 1000; } - auto testRes = [&] (long double div, int fps_num, int fps_den, - bool force) - { + auto testRes = [&](long double div, int fps_num, int fps_den, + bool force) { if (results.size() >= 3) return; @@ -805,7 +815,8 @@ void AutoConfigTestPage::FindIdealHardwareResolution() * ratio, so increase the minimum bitrate estimate for them. * NVENC currently is the exception because of the improvements * its made to its quality in recent generations. */ - if (!nvenc) minBitrate = minBitrate * 114 / 100; + if (!nvenc) + minBitrate = minBitrate * 114 / 100; if (wiz->type == AutoConfig::Type::Recording) force = true; @@ -919,9 +930,9 @@ void AutoConfigTestPage::TestRecordingEncoderThread() #define ENCODER_TEXT(x) "Basic.Settings.Output.Simple.Encoder." x #define ENCODER_SOFTWARE ENCODER_TEXT("Software") -#define ENCODER_NVENC ENCODER_TEXT("Hardware.NVENC") -#define ENCODER_QSV ENCODER_TEXT("Hardware.QSV") -#define ENCODER_AMD ENCODER_TEXT("Hardware.AMD") +#define ENCODER_NVENC ENCODER_TEXT("Hardware.NVENC") +#define ENCODER_QSV ENCODER_TEXT("Hardware.QSV") +#define ENCODER_AMD ENCODER_TEXT("Hardware.AMD") #define QUALITY_SAME "Basic.Settings.Output.Simple.RecordingQuality.Stream" #define QUALITY_HIGH "Basic.Settings.Output.Simple.RecordingQuality.Small" @@ -933,8 +944,7 @@ void AutoConfigTestPage::FinalizeResults() QFormLayout *form = results; - auto encName = [] (AutoConfig::Encoder enc) -> QString - { + auto encName = [](AutoConfig::Encoder enc) -> QString { switch (enc) { case AutoConfig::Encoder::x264: return QTStr(ENCODER_SOFTWARE); @@ -951,18 +961,16 @@ void AutoConfigTestPage::FinalizeResults() return QTStr(ENCODER_SOFTWARE); }; - auto newLabel = [this] (const char *str) -> QLabel * - { + auto newLabel = [this](const char *str) -> QLabel * { return new QLabel(QTStr(str), this); }; if (wiz->type != AutoConfig::Type::Recording) { - const char *serverType = wiz->customServer - ? "rtmp_custom" - : "rtmp_common"; + const char *serverType = wiz->customServer ? "rtmp_custom" + : "rtmp_common"; - OBSService service = obs_service_create(serverType, - "temp_service", nullptr, nullptr); + OBSService service = obs_service_create( + serverType, "temp_service", nullptr, nullptr); obs_service_release(service); OBSData service_settings = obs_data_create(); @@ -971,44 +979,45 @@ void AutoConfigTestPage::FinalizeResults() obs_data_release(vencoder_settings); obs_data_set_int(vencoder_settings, "bitrate", - wiz->idealBitrate); + wiz->idealBitrate); obs_data_set_string(service_settings, "service", - wiz->serviceName.c_str()); + wiz->serviceName.c_str()); obs_service_update(service, service_settings); - obs_service_apply_encoder_settings(service, - vencoder_settings, nullptr); + obs_service_apply_encoder_settings(service, vencoder_settings, + nullptr); - wiz->idealBitrate = (int)obs_data_get_int(vencoder_settings, - "bitrate"); + wiz->idealBitrate = + (int)obs_data_get_int(vencoder_settings, "bitrate"); if (!wiz->customServer) form->addRow( newLabel("Basic.AutoConfig.StreamPage.Service"), new QLabel(wiz->serviceName.c_str(), - ui->finishPage)); + ui->finishPage)); form->addRow(newLabel("Basic.AutoConfig.StreamPage.Server"), - new QLabel(wiz->serverName.c_str(), ui->finishPage)); + new QLabel(wiz->serverName.c_str(), + ui->finishPage)); form->addRow(newLabel("Basic.Settings.Output.VideoBitrate"), - new QLabel(QString::number(wiz->idealBitrate), - ui->finishPage)); + new QLabel(QString::number(wiz->idealBitrate), + ui->finishPage)); form->addRow(newLabel(TEST_RESULT_SE), - new QLabel(encName(wiz->streamingEncoder), - ui->finishPage)); + new QLabel(encName(wiz->streamingEncoder), + ui->finishPage)); } - QString baseRes = QString("%1x%2").arg( - QString::number(wiz->baseResolutionCX), - QString::number(wiz->baseResolutionCY)); - QString scaleRes = QString("%1x%2").arg( - QString::number(wiz->idealResolutionCX), - QString::number(wiz->idealResolutionCY)); + QString baseRes = + QString("%1x%2").arg(QString::number(wiz->baseResolutionCX), + QString::number(wiz->baseResolutionCY)); + QString scaleRes = + QString("%1x%2").arg(QString::number(wiz->idealResolutionCX), + QString::number(wiz->idealResolutionCY)); if (wiz->recordingEncoder != AutoConfig::Encoder::Stream || wiz->recordingQuality != AutoConfig::Quality::Stream) form->addRow(newLabel(TEST_RESULT_RE), - new QLabel(encName(wiz->recordingEncoder), - ui->finishPage)); + new QLabel(encName(wiz->recordingEncoder), + ui->finishPage)); QString recQuality; @@ -1022,21 +1031,20 @@ void AutoConfigTestPage::FinalizeResults() } form->addRow(newLabel("Basic.Settings.Output.Simple.RecordingQuality"), - new QLabel(recQuality, ui->finishPage)); + new QLabel(recQuality, ui->finishPage)); long double fps = (long double)wiz->idealFPSNum / (long double)wiz->idealFPSDen; - QString fpsStr = (wiz->idealFPSDen > 1) - ? QString::number(fps, 'f', 2) - : QString::number(fps, 'g', 2); + QString fpsStr = (wiz->idealFPSDen > 1) ? QString::number(fps, 'f', 2) + : QString::number(fps, 'g', 2); form->addRow(newLabel("Basic.Settings.Video.BaseResolution"), - new QLabel(baseRes, ui->finishPage)); + new QLabel(baseRes, ui->finishPage)); form->addRow(newLabel("Basic.Settings.Video.ScaledResolution"), - new QLabel(scaleRes, ui->finishPage)); + new QLabel(scaleRes, ui->finishPage)); form->addRow(newLabel("Basic.Settings.Video.FPS"), - new QLabel(fpsStr, ui->finishPage)); + new QLabel(fpsStr, ui->finishPage)); } #define STARTING_SEPARATOR \ @@ -1103,8 +1111,7 @@ void AutoConfigTestPage::Progress(int percentage) } AutoConfigTestPage::AutoConfigTestPage(QWidget *parent) - : QWizardPage (parent), - ui (new Ui_AutoConfigTestPage) + : QWizardPage(parent), ui(new Ui_AutoConfigTestPage) { ui->setupUi(this); setTitle(QTStr("Basic.AutoConfig.TestPage")); diff --git a/UI/window-basic-auto-config.cpp b/UI/window-basic-auto-config.cpp index b3cc2b3..a72768c 100644 --- a/UI/window-basic-auto-config.cpp +++ b/UI/window-basic-auto-config.cpp @@ -20,10 +20,10 @@ struct QCef; struct QCefCookieManager; -extern QCef *cef; +extern QCef *cef; extern QCefCookieManager *panel_cookies; -#define wiz reinterpret_cast(wizard()) +#define wiz reinterpret_cast(wizard()) /* ------------------------------------------------------------------------- */ @@ -33,12 +33,12 @@ static OBSData OpenServiceSettings(std::string &type) { char serviceJsonPath[512]; int ret = GetProfilePath(serviceJsonPath, sizeof(serviceJsonPath), - SERVICE_PATH); + SERVICE_PATH); if (ret <= 0) return OBSData(); - OBSData data = obs_data_create_from_json_file_safe(serviceJsonPath, - "bak"); + OBSData data = + obs_data_create_from_json_file_safe(serviceJsonPath, "bak"); obs_data_release(data); obs_data_set_default_string(data, "type", "rtmp_common"); @@ -51,7 +51,7 @@ static OBSData OpenServiceSettings(std::string &type) } static void GetServiceInfo(std::string &type, std::string &service, - std::string &server, std::string &key) + std::string &server, std::string &key) { OBSData settings = OpenServiceSettings(type); @@ -63,8 +63,7 @@ static void GetServiceInfo(std::string &type, std::string &service, /* ------------------------------------------------------------------------- */ AutoConfigStartPage::AutoConfigStartPage(QWidget *parent) - : QWizardPage (parent), - ui (new Ui_AutoConfigStartPage) + : QWizardPage(parent), ui(new Ui_AutoConfigStartPage) { ui->setupUi(this); setTitle(QTStr("Basic.AutoConfig.StartPage")); @@ -93,16 +92,15 @@ void AutoConfigStartPage::on_prioritizeRecording_clicked() /* ------------------------------------------------------------------------- */ -#define RES_TEXT(x) "Basic.AutoConfig.VideoPage." x -#define RES_USE_CURRENT RES_TEXT("BaseResolution.UseCurrent") -#define RES_USE_DISPLAY RES_TEXT("BaseResolution.Display") -#define FPS_USE_CURRENT RES_TEXT("FPS.UseCurrent") -#define FPS_PREFER_HIGH_FPS RES_TEXT("FPS.PreferHighFPS") -#define FPS_PREFER_HIGH_RES RES_TEXT("FPS.PreferHighRes") +#define RES_TEXT(x) "Basic.AutoConfig.VideoPage." x +#define RES_USE_CURRENT RES_TEXT("BaseResolution.UseCurrent") +#define RES_USE_DISPLAY RES_TEXT("BaseResolution.Display") +#define FPS_USE_CURRENT RES_TEXT("FPS.UseCurrent") +#define FPS_PREFER_HIGH_FPS RES_TEXT("FPS.PreferHighFPS") +#define FPS_PREFER_HIGH_RES RES_TEXT("FPS.PreferHighRes") AutoConfigVideoPage::AutoConfigVideoPage(QWidget *parent) - : QWizardPage (parent), - ui (new Ui_AutoConfigVideoPage) + : QWizardPage(parent), ui(new Ui_AutoConfigVideoPage) { ui->setupUi(this); @@ -115,16 +113,15 @@ AutoConfigVideoPage::AutoConfigVideoPage(QWidget *parent) long double fpsVal = (long double)ovi.fps_num / (long double)ovi.fps_den; - QString fpsStr = (ovi.fps_den > 1) - ? QString::number(fpsVal, 'f', 2) - : QString::number(fpsVal, 'g', 2); + QString fpsStr = (ovi.fps_den > 1) ? QString::number(fpsVal, 'f', 2) + : QString::number(fpsVal, 'g', 2); ui->fps->addItem(QTStr(FPS_PREFER_HIGH_FPS), - (int)AutoConfig::FPSType::PreferHighFPS); + (int)AutoConfig::FPSType::PreferHighFPS); ui->fps->addItem(QTStr(FPS_PREFER_HIGH_RES), - (int)AutoConfig::FPSType::PreferHighRes); + (int)AutoConfig::FPSType::PreferHighRes); ui->fps->addItem(QTStr(FPS_USE_CURRENT).arg(fpsStr), - (int)AutoConfig::FPSType::UseCurrent); + (int)AutoConfig::FPSType::UseCurrent); ui->fps->addItem(QStringLiteral("30"), (int)AutoConfig::FPSType::fps30); ui->fps->addItem(QStringLiteral("60"), (int)AutoConfig::FPSType::fps60); ui->fps->setCurrentIndex(0); @@ -134,9 +131,9 @@ AutoConfigVideoPage::AutoConfigVideoPage(QWidget *parent) int encRes = int(ovi.base_width << 16) | int(ovi.base_height); ui->canvasRes->addItem(QTStr(RES_USE_CURRENT).arg(cxStr, cyStr), - (int)encRes); + (int)encRes); - QList screens = QGuiApplication::screens(); + QList screens = QGuiApplication::screens(); for (int i = 0; i < screens.size(); i++) { QScreen *screen = screens[i]; QSize as = screen->size(); @@ -144,19 +141,17 @@ AutoConfigVideoPage::AutoConfigVideoPage(QWidget *parent) encRes = int(as.width() << 16) | int(as.height()); QString str = QTStr(RES_USE_DISPLAY) - .arg(QString::number(i + 1), - QString::number(as.width()), - QString::number(as.height())); + .arg(QString::number(i + 1), + QString::number(as.width()), + QString::number(as.height())); ui->canvasRes->addItem(str, encRes); } - auto addRes = [&] (int cx, int cy) - { + auto addRes = [&](int cx, int cy) { encRes = (cx << 16) | cy; - QString str = QString("%1x%2").arg( - QString::number(cx), - QString::number(cy)); + QString str = QString("%1x%2").arg(QString::number(cx), + QString::number(cy)); ui->canvasRes->addItem(str, encRes); }; @@ -174,8 +169,8 @@ AutoConfigVideoPage::~AutoConfigVideoPage() int AutoConfigVideoPage::nextId() const { return wiz->type == AutoConfig::Type::Recording - ? AutoConfig::TestPage - : AutoConfig::StreamPage; + ? AutoConfig::TestPage + : AutoConfig::StreamPage; } bool AutoConfigVideoPage::validatePage() @@ -223,12 +218,11 @@ bool AutoConfigVideoPage::validatePage() enum class ListOpt : int { ShowAll = 1, - Custom + Custom, }; AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent) - : QWizardPage (parent), - ui (new Ui_AutoConfigStreamPage) + : QWizardPage(parent), ui(new Ui_AutoConfigStreamPage) { ui->setupUi(this); ui->bitrateLabel->setVisible(false); @@ -255,29 +249,29 @@ AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent) LoadServices(false); - connect(ui->service, SIGNAL(currentIndexChanged(int)), - this, SLOT(ServiceChanged())); - connect(ui->customServer, SIGNAL(textChanged(const QString &)), - this, SLOT(ServiceChanged())); - connect(ui->doBandwidthTest, SIGNAL(toggled(bool)), - this, SLOT(ServiceChanged())); + connect(ui->service, SIGNAL(currentIndexChanged(int)), this, + SLOT(ServiceChanged())); + connect(ui->customServer, SIGNAL(textChanged(const QString &)), this, + SLOT(ServiceChanged())); + connect(ui->doBandwidthTest, SIGNAL(toggled(bool)), this, + SLOT(ServiceChanged())); - connect(ui->service, SIGNAL(currentIndexChanged(int)), - this, SLOT(UpdateServerList())); + connect(ui->service, SIGNAL(currentIndexChanged(int)), this, + SLOT(UpdateServerList())); - connect(ui->service, SIGNAL(currentIndexChanged(int)), - this, SLOT(UpdateKeyLink())); + connect(ui->service, SIGNAL(currentIndexChanged(int)), this, + SLOT(UpdateKeyLink())); - connect(ui->key, SIGNAL(textChanged(const QString &)), - this, SLOT(UpdateCompleted())); - connect(ui->regionUS, SIGNAL(toggled(bool)), - this, SLOT(UpdateCompleted())); - connect(ui->regionEU, SIGNAL(toggled(bool)), - this, SLOT(UpdateCompleted())); - connect(ui->regionAsia, SIGNAL(toggled(bool)), - this, SLOT(UpdateCompleted())); - connect(ui->regionOther, SIGNAL(toggled(bool)), - this, SLOT(UpdateCompleted())); + connect(ui->key, SIGNAL(textChanged(const QString &)), this, + SLOT(UpdateCompleted())); + connect(ui->regionUS, SIGNAL(toggled(bool)), this, + SLOT(UpdateCompleted())); + connect(ui->regionEU, SIGNAL(toggled(bool)), this, + SLOT(UpdateCompleted())); + connect(ui->regionAsia, SIGNAL(toggled(bool)), this, + SLOT(UpdateCompleted())); + connect(ui->regionOther, SIGNAL(toggled(bool)), this, + SLOT(UpdateCompleted())); } AutoConfigStreamPage::~AutoConfigStreamPage() @@ -307,17 +301,16 @@ bool AutoConfigStreamPage::validatePage() wiz->customServer = IsCustom(); - const char *serverType = wiz->customServer - ? "rtmp_custom" - : "rtmp_common"; + const char *serverType = wiz->customServer ? "rtmp_custom" + : "rtmp_common"; if (!wiz->customServer) { obs_data_set_string(service_settings, "service", - QT_TO_UTF8(ui->service->currentText())); + QT_TO_UTF8(ui->service->currentText())); } OBSService service = obs_service_create(serverType, "temp_service", - service_settings, nullptr); + service_settings, nullptr); obs_service_release(service); int bitrate = 10000; @@ -365,9 +358,8 @@ bool AutoConfigStreamPage::validatePage() if (wiz->service != AutoConfig::Service::Twitch && wiz->bandwidthTest) { QMessageBox::StandardButton button; #define WARNING_TEXT(x) QTStr("Basic.AutoConfig.StreamPage.StreamWarning." x) - button = OBSMessageBox::question(this, - WARNING_TEXT("Title"), - WARNING_TEXT("Text")); + button = OBSMessageBox::question(this, WARNING_TEXT("Title"), + WARNING_TEXT("Text")); #undef WARNING_TEXT if (button == QMessageBox::No) @@ -391,7 +383,7 @@ void AutoConfigStreamPage::on_show_clicked() void AutoConfigStreamPage::OnOAuthStreamKeyConnected() { #ifdef BROWSER_AVAILABLE - OAuthStreamKey *a = reinterpret_cast(auth.get()); + OAuthStreamKey *a = reinterpret_cast(auth.get()); if (a) { bool validKey = !a->key().empty(); @@ -440,9 +432,8 @@ void AutoConfigStreamPage::on_disconnectAccount_clicked() { QMessageBox::StandardButton button; - button = OBSMessageBox::question(this, - QTStr(DISCONNECT_COMFIRM_TITLE), - QTStr(DISCONNECT_COMFIRM_TEXT)); + button = OBSMessageBox::question(this, QTStr(DISCONNECT_COMFIRM_TITLE), + QTStr(DISCONNECT_COMFIRM_TEXT)); if (button == QMessageBox::No) { return; @@ -479,14 +470,13 @@ static inline bool is_auth_service(const std::string &service) void AutoConfigStreamPage::ServiceChanged() { - bool showMore = - ui->service->currentData().toInt() == (int)ListOpt::ShowAll; + bool showMore = ui->service->currentData().toInt() == + (int)ListOpt::ShowAll; if (showMore) return; std::string service = QT_TO_UTF8(ui->service->currentText()); - bool regionBased = service == "Twitch" || - service == "Smashcast"; + bool regionBased = service == "Twitch" || service == "Smashcast"; bool testBandwidth = ui->doBandwidthTest->isChecked(); bool custom = IsCustom(); @@ -496,9 +486,8 @@ void AutoConfigStreamPage::ServiceChanged() if (cef) { if (lastService != service.c_str()) { bool can_auth = is_auth_service(service); - int page = can_auth - ? (int)Section::Connect - : (int)Section::StreamKey; + int page = can_auth ? (int)Section::Connect + : (int)Section::StreamKey; ui->stackedWidget->setCurrentIndex(page); ui->streamKeyWidget->setVisible(true); @@ -525,7 +514,7 @@ void AutoConfigStreamPage::ServiceChanged() if (custom) { ui->streamkeyPageLayout->insertRow(1, ui->serverLabel, - ui->serverStackedWidget); + ui->serverStackedWidget); ui->region->setVisible(false); ui->serverStackedWidget->setCurrentIndex(1); @@ -533,8 +522,8 @@ void AutoConfigStreamPage::ServiceChanged() ui->serverLabel->setVisible(true); } else { if (!testBandwidth) - ui->streamkeyPageLayout->insertRow(2, ui->serverLabel, - ui->serverStackedWidget); + ui->streamkeyPageLayout->insertRow( + 2, ui->serverLabel, ui->serverStackedWidget); ui->region->setVisible(regionBased && testBandwidth); ui->serverStackedWidget->setCurrentIndex(0); @@ -574,16 +563,32 @@ void AutoConfigStreamPage::UpdateKeyLink() text += " "; - text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite"); + text += QTStr( + "Basic.AutoConfig.StreamPage.StreamKey.LinkToSite"); text += ""; } else if (serviceName == "YouTube / YouTube Gaming") { text += " "; - text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite"); + text += QTStr( + "Basic.AutoConfig.StreamPage.StreamKey.LinkToSite"); text += ""; isYoutube = true; + } else if (serviceName.startsWith("Restream.io")) { + text += " "; + text += QTStr( + "Basic.AutoConfig.StreamPage.StreamKey.LinkToSite"); + text += ""; + } else if (serviceName == "Facebook Live") { + text += " "; + text += QTStr( + "Basic.AutoConfig.StreamPage.StreamKey.LinkToSite"); + text += ""; } if (isYoutube) { @@ -632,9 +637,9 @@ void AutoConfigStreamPage::LoadServices(bool showAll) QVariant((int)ListOpt::ShowAll)); } - ui->service->insertItem(0, - QTStr("Basic.AutoConfig.StreamPage.Service.Custom"), - QVariant((int)ListOpt::Custom)); + ui->service->insertItem( + 0, QTStr("Basic.AutoConfig.StreamPage.Service.Custom"), + QVariant((int)ListOpt::Custom)); if (!lastService.isEmpty()) { int idx = ui->service->findText(lastService); @@ -650,8 +655,8 @@ void AutoConfigStreamPage::LoadServices(bool showAll) void AutoConfigStreamPage::UpdateServerList() { QString serviceName = ui->service->currentText(); - bool showMore = - ui->service->currentData().toInt() == (int)ListOpt::ShowAll; + bool showMore = ui->service->currentData().toInt() == + (int)ListOpt::ShowAll; if (showMore) { LoadServices(true); @@ -706,8 +711,7 @@ void AutoConfigStreamPage::UpdateCompleted() /* ------------------------------------------------------------------------- */ -AutoConfig::AutoConfig(QWidget *parent) - : QWizard(parent) +AutoConfig::AutoConfig(QWidget *parent) : QWizard(parent) { EnableThreadedMessageBoxes(true); @@ -718,7 +722,7 @@ AutoConfig::AutoConfig(QWidget *parent) proc_handler_call(ph, "twitch_ingests_refresh", &cd); calldata_free(&cd); - OBSBasic *main = reinterpret_cast(parent); + OBSBasic *main = reinterpret_cast(parent); main->EnableOutputs(false); installEventFilter(CreateShortcutFilter()); @@ -805,14 +809,15 @@ AutoConfig::AutoConfig(QWidget *parent) } else { streamPage->ui->customServer->setText(server.c_str()); int idx = streamPage->ui->service->findData( - QVariant((int)ListOpt::Custom)); + QVariant((int)ListOpt::Custom)); streamPage->ui->service->setCurrentIndex(idx); } if (!key.empty()) streamPage->ui->key->setText(key.c_str()); - int bitrate = config_get_int(main->Config(), "SimpleOutput", "VBitrate"); + int bitrate = + config_get_int(main->Config(), "SimpleOutput", "VBitrate"); streamPage->ui->bitrate->setValue(bitrate); streamPage->ServiceChanged(); @@ -825,13 +830,13 @@ AutoConfig::AutoConfig(QWidget *parent) * bitrate ratio that if NVENC is available, it makes sense to * just always prefer hardware encoding by default */ bool preferHardware = nvencAvailable || - os_get_physical_cores() <= 4; + os_get_physical_cores() <= 4; streamPage->ui->preferHardware->setChecked(preferHardware); } setOptions(0); setButtonText(QWizard::FinishButton, - QTStr("Basic.AutoConfig.ApplySettings")); + QTStr("Basic.AutoConfig.ApplySettings")); setButtonText(QWizard::BackButton, QTStr("Back")); setButtonText(QWizard::NextButton, QTStr("Next")); setButtonText(QWizard::CancelButton, QTStr("Cancel")); @@ -839,7 +844,7 @@ AutoConfig::AutoConfig(QWidget *parent) AutoConfig::~AutoConfig() { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); main->EnableOutputs(true); EnableThreadedMessageBoxes(false); } @@ -879,13 +884,13 @@ bool AutoConfig::CanTestServer(const char *server) if (strcmp(server, "Default") == 0) { return true; } else if (astrcmp_n(server, "US-West:", 8) == 0 || - astrcmp_n(server, "US-East:", 8) == 0) { + astrcmp_n(server, "US-East:", 8) == 0) { return regionUS; } else if (astrcmp_n(server, "EU-", 3) == 0) { return regionEU; } else if (astrcmp_n(server, "South Korea:", 12) == 0 || - astrcmp_n(server, "Asia:", 5) == 0 || - astrcmp_n(server, "China:", 6) == 0) { + astrcmp_n(server, "Asia:", 5) == 0 || + astrcmp_n(server, "China:", 6) == 0) { return regionAsia; } else if (regionOther) { return true; @@ -924,14 +929,12 @@ inline const char *AutoConfig::GetEncoderId(Encoder enc) void AutoConfig::SaveStreamSettings() { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); /* ---------------------------------- */ /* save service */ - const char *service_id = customServer - ? "rtmp_custom" - : "rtmp_common"; + const char *service_id = customServer ? "rtmp_custom" : "rtmp_common"; obs_service_t *oldService = main->GetService(); OBSData hotkeyData = obs_hotkeys_save_service(oldService); @@ -945,8 +948,8 @@ void AutoConfig::SaveStreamSettings() obs_data_set_string(settings, "server", server.c_str()); obs_data_set_string(settings, "key", key.c_str()); - OBSService newService = obs_service_create(service_id, - "default_service", settings, hotkeyData); + OBSService newService = obs_service_create( + service_id, "default_service", settings, hotkeyData); obs_service_release(newService); if (!newService) @@ -962,26 +965,26 @@ void AutoConfig::SaveStreamSettings() /* save stream settings */ config_set_int(main->Config(), "SimpleOutput", "VBitrate", - idealBitrate); + idealBitrate); config_set_string(main->Config(), "SimpleOutput", "StreamEncoder", - GetEncoderId(streamingEncoder)); + GetEncoderId(streamingEncoder)); config_remove_value(main->Config(), "SimpleOutput", "UseAdvanced"); } void AutoConfig::SaveSettings() { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); if (recordingEncoder != Encoder::Stream) config_set_string(main->Config(), "SimpleOutput", "RecEncoder", - GetEncoderId(recordingEncoder)); + GetEncoderId(recordingEncoder)); - const char *quality = recordingQuality == Quality::High - ? "Small" - : "Stream"; + const char *quality = recordingQuality == Quality::High ? "Small" + : "Stream"; config_set_string(main->Config(), "Output", "Mode", "Simple"); - config_set_string(main->Config(), "SimpleOutput", "RecQuality", quality); + config_set_string(main->Config(), "SimpleOutput", "RecQuality", + quality); config_set_int(main->Config(), "Video", "BaseCX", baseResolutionCX); config_set_int(main->Config(), "Video", "BaseCY", baseResolutionCY); config_set_int(main->Config(), "Video", "OutputCX", idealResolutionCX); @@ -990,7 +993,7 @@ void AutoConfig::SaveSettings() if (fpsType != FPSType::UseCurrent) { config_set_uint(main->Config(), "Video", "FPSType", 0); config_set_string(main->Config(), "Video", "FPSCommon", - std::to_string(idealFPSNum).c_str()); + std::to_string(idealFPSNum).c_str()); } main->ResetVideo(); diff --git a/UI/window-basic-auto-config.hpp b/UI/window-basic-auto-config.hpp index 9426a75..97e4df3 100644 --- a/UI/window-basic-auto-config.hpp +++ b/UI/window-basic-auto-config.hpp @@ -32,13 +32,13 @@ class AutoConfig : public QWizard { enum class Type { Invalid, Streaming, - Recording + Recording, }; enum class Service { Twitch, Smashcast, - Other + Other, }; enum class Encoder { @@ -46,12 +46,12 @@ class AutoConfig : public QWizard { NVENC, QSV, AMD, - Stream + Stream, }; enum class Quality { Stream, - High + High, }; enum class FPSType : int { @@ -59,7 +59,7 @@ class AutoConfig : public QWizard { PreferHighRes, UseCurrent, fps30, - fps60 + fps60, }; static inline const char *GetEncoderId(Encoder enc); @@ -119,7 +119,7 @@ public: StartPage, VideoPage, StreamPage, - TestPage + TestPage, }; }; @@ -216,7 +216,7 @@ class AutoConfigTestPage : public QWizardPage { BandwidthTest, StreamEncoder, RecordingEncoder, - Finished + Finished, }; Stage stage = Stage::Starting; diff --git a/UI/window-basic-filters.cpp b/UI/window-basic-filters.cpp index fa2ef99..4299e4f 100644 --- a/UI/window-basic-filters.cpp +++ b/UI/window-basic-filters.cpp @@ -36,45 +36,39 @@ using namespace std; Q_DECLARE_METATYPE(OBSSource); OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_) - : QDialog (parent), - ui (new Ui::OBSBasicFilters), - source (source_), - addSignal (obs_source_get_signal_handler(source), - "filter_add", - OBSBasicFilters::OBSSourceFilterAdded, - this), - removeSignal (obs_source_get_signal_handler(source), - "filter_remove", - OBSBasicFilters::OBSSourceFilterRemoved, - this), - reorderSignal (obs_source_get_signal_handler(source), - "reorder_filters", - OBSBasicFilters::OBSSourceReordered, - this), - removeSourceSignal (obs_source_get_signal_handler(source), - "remove", - OBSBasicFilters::SourceRemoved, this), - renameSourceSignal (obs_source_get_signal_handler(source), - "rename", - OBSBasicFilters::SourceRenamed, this), - noPreviewMargin (13) + : QDialog(parent), + ui(new Ui::OBSBasicFilters), + source(source_), + addSignal(obs_source_get_signal_handler(source), "filter_add", + OBSBasicFilters::OBSSourceFilterAdded, this), + removeSignal(obs_source_get_signal_handler(source), "filter_remove", + OBSBasicFilters::OBSSourceFilterRemoved, this), + reorderSignal(obs_source_get_signal_handler(source), + "reorder_filters", OBSBasicFilters::OBSSourceReordered, + this), + removeSourceSignal(obs_source_get_signal_handler(source), "remove", + OBSBasicFilters::SourceRemoved, this), + renameSourceSignal(obs_source_get_signal_handler(source), "rename", + OBSBasicFilters::SourceRenamed, this), + noPreviewMargin(13) { - main = reinterpret_cast(parent); + main = reinterpret_cast(parent); ui->setupUi(this); UpdateFilters(); ui->asyncFilters->setItemDelegate( - new VisibilityItemDelegate(ui->asyncFilters)); + new VisibilityItemDelegate(ui->asyncFilters)); ui->effectFilters->setItemDelegate( - new VisibilityItemDelegate(ui->effectFilters)); + new VisibilityItemDelegate(ui->effectFilters)); const char *name = obs_source_get_name(source); setWindowTitle(QTStr("Basic.Filters.Title").arg(QT_UTF8(name))); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); #ifndef QT_NO_SHORTCUT - ui->actionRemoveFilter->setShortcut(QApplication::translate("OBSBasicFilters", "Del", nullptr)); + ui->actionRemoveFilter->setShortcut( + QApplication::translate("OBSBasicFilters", "Del", nullptr)); #endif // QT_NO_SHORTCUT addAction(ui->actionRemoveFilter); @@ -84,33 +78,33 @@ OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_) installEventFilter(CreateShortcutFilter()); connect(ui->asyncFilters->itemDelegate(), - SIGNAL(closeEditor(QWidget*, - QAbstractItemDelegate::EndEditHint)), - this, - SLOT(AsyncFilterNameEdited(QWidget*, - QAbstractItemDelegate::EndEditHint))); + SIGNAL(closeEditor(QWidget *, + QAbstractItemDelegate::EndEditHint)), + this, + SLOT(AsyncFilterNameEdited( + QWidget *, QAbstractItemDelegate::EndEditHint))); connect(ui->effectFilters->itemDelegate(), - SIGNAL(closeEditor(QWidget*, - QAbstractItemDelegate::EndEditHint)), - this, - SLOT(EffectFilterNameEdited(QWidget*, - QAbstractItemDelegate::EndEditHint))); + SIGNAL(closeEditor(QWidget *, + QAbstractItemDelegate::EndEditHint)), + this, + SLOT(EffectFilterNameEdited( + QWidget *, QAbstractItemDelegate::EndEditHint))); QPushButton *close = ui->buttonBox->button(QDialogButtonBox::Close); connect(close, SIGNAL(clicked()), this, SLOT(close())); close->setDefault(true); - ui->buttonBox->button(QDialogButtonBox::Reset)->setText( - QTStr("Defaults")); + ui->buttonBox->button(QDialogButtonBox::Reset) + ->setText(QTStr("Defaults")); connect(ui->buttonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked()), this, SLOT(ResetFilters())); uint32_t caps = obs_source_get_output_flags(source); - bool audio = (caps & OBS_SOURCE_AUDIO) != 0; + bool audio = (caps & OBS_SOURCE_AUDIO) != 0; bool audioOnly = (caps & OBS_SOURCE_VIDEO) == 0; - bool async = (caps & OBS_SOURCE_ASYNC) != 0; + bool async = (caps & OBS_SOURCE_ASYNC) != 0; if (!async && !audio) { ui->asyncWidget->setVisible(false); @@ -124,22 +118,22 @@ OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_) if (audioOnly || (audio && !async)) ui->asyncLabel->setText(QTStr("Basic.Filters.AudioFilters")); - auto addDrawCallback = [this] () - { + auto addDrawCallback = [this]() { obs_display_add_draw_callback(ui->preview->GetDisplay(), - OBSBasicFilters::DrawPreview, this); + OBSBasicFilters::DrawPreview, + this); }; enum obs_source_type type = obs_source_get_type(source); bool drawable_type = type == OBS_SOURCE_TYPE_INPUT || - type == OBS_SOURCE_TYPE_SCENE; + type == OBS_SOURCE_TYPE_SCENE; if ((caps & OBS_SOURCE_VIDEO) != 0) { ui->rightLayout->setContentsMargins(0, 0, 0, 0); ui->preview->show(); if (drawable_type) connect(ui->preview, &OBSQTDisplay::DisplayCreated, - addDrawCallback); + addDrawCallback); } else { ui->rightLayout->setContentsMargins(0, noPreviewMargin, 0, 0); ui->rightContainerLayout->insertStretch(1); @@ -187,14 +181,14 @@ void OBSBasicFilters::UpdatePropertiesView(int row, bool async) obs_data_t *settings = obs_source_get_settings(filter); - view = new OBSPropertiesView(settings, filter, - (PropertiesReloadCallback)obs_source_properties, - (PropertiesUpdateCallback)obs_source_update); + view = new OBSPropertiesView( + settings, filter, + (PropertiesReloadCallback)obs_source_properties, + (PropertiesUpdateCallback)obs_source_update); updatePropertiesSignal.Connect(obs_source_get_signal_handler(filter), - "update_properties", - OBSBasicFilters::UpdateProperties, - this); + "update_properties", + OBSBasicFilters::UpdateProperties, this); obs_data_release(settings); @@ -206,8 +200,8 @@ void OBSBasicFilters::UpdatePropertiesView(int row, bool async) void OBSBasicFilters::UpdateProperties(void *data, calldata_t *) { - QMetaObject::invokeMethod(static_cast(data)->view, - "ReloadProperties"); + QMetaObject::invokeMethod(static_cast(data)->view, + "ReloadProperties"); } void OBSBasicFilters::AddFilter(OBSSource filter) @@ -252,7 +246,7 @@ void OBSBasicFilters::RemoveFilter(OBSSource filter) const char *filterId = obs_source_get_id(filter); blog(LOG_INFO, "User removed filter '%s' (%s) from source '%s'", - filterName, filterId, sourceName); + filterName, filterId, sourceName); main->SaveProject(); } @@ -265,8 +259,8 @@ struct FilterOrderInfo { inline FilterOrderInfo(OBSBasicFilters *window_) : window(window_) {} }; -void OBSBasicFilters::ReorderFilter(QListWidget *list, - obs_source_t *filter, size_t idx) +void OBSBasicFilters::ReorderFilter(QListWidget *list, obs_source_t *filter, + size_t idx) { int count = list->count(); @@ -280,10 +274,10 @@ void OBSBasicFilters::ReorderFilter(QListWidget *list, bool sel = (list->currentRow() == i); listItem = TakeListItem(list, i); - if (listItem) { + if (listItem) { list->insertItem((int)idx, listItem); - SetupVisibilityItem(list, - listItem, filterItem); + SetupVisibilityItem(list, listItem, + filterItem); if (sel) list->setCurrentRow((int)idx); @@ -299,27 +293,28 @@ void OBSBasicFilters::ReorderFilters() { FilterOrderInfo info(this); - obs_source_enum_filters(source, - [] (obs_source_t*, obs_source_t *filter, void *p) - { - FilterOrderInfo *info = - reinterpret_cast(p); - uint32_t flags; - bool async; + obs_source_enum_filters( + source, + [](obs_source_t *, obs_source_t *filter, void *p) { + FilterOrderInfo *info = + reinterpret_cast(p); + uint32_t flags; + bool async; - flags = obs_source_get_output_flags(filter); - async = (flags & OBS_SOURCE_ASYNC) != 0; + flags = obs_source_get_output_flags(filter); + async = (flags & OBS_SOURCE_ASYNC) != 0; - if (async) { - info->window->ReorderFilter( - info->window->ui->asyncFilters, - filter, info->asyncIdx++); - } else { - info->window->ReorderFilter( - info->window->ui->effectFilters, - filter, info->effectIdx++); - } - }, &info); + if (async) { + info->window->ReorderFilter( + info->window->ui->asyncFilters, filter, + info->asyncIdx++); + } else { + info->window->ReorderFilter( + info->window->ui->effectFilters, filter, + info->effectIdx++); + } + }, + &info); } void OBSBasicFilters::UpdateFilters() @@ -330,33 +325,34 @@ void OBSBasicFilters::UpdateFilters() ClearListItems(ui->effectFilters); ClearListItems(ui->asyncFilters); - obs_source_enum_filters(source, - [] (obs_source_t*, obs_source_t *filter, void *p) - { - OBSBasicFilters *window = - reinterpret_cast(p); + obs_source_enum_filters( + source, + [](obs_source_t *, obs_source_t *filter, void *p) { + OBSBasicFilters *window = + reinterpret_cast(p); - window->AddFilter(filter); - }, this); + window->AddFilter(filter); + }, + this); main->SaveProject(); } static bool filter_compatible(bool async, uint32_t sourceFlags, - uint32_t filterFlags) + uint32_t filterFlags) { bool filterVideo = (filterFlags & OBS_SOURCE_VIDEO) != 0; bool filterAsync = (filterFlags & OBS_SOURCE_ASYNC) != 0; bool filterAudio = (filterFlags & OBS_SOURCE_AUDIO) != 0; - bool audio = (sourceFlags & OBS_SOURCE_AUDIO) != 0; - bool audioOnly = (sourceFlags & OBS_SOURCE_VIDEO) == 0; + bool audio = (sourceFlags & OBS_SOURCE_AUDIO) != 0; + bool audioOnly = (sourceFlags & OBS_SOURCE_VIDEO) == 0; bool asyncSource = (sourceFlags & OBS_SOURCE_ASYNC) != 0; if (async && ((audioOnly && filterVideo) || (!audio && !asyncSource))) return false; return (async && (filterAudio || filterAsync)) || - (!async && !filterAudio && !filterAsync); + (!async && !filterAudio && !filterAsync); } QMenu *OBSBasicFilters::CreateAddFilterPopupMenu(bool async) @@ -372,7 +368,8 @@ QMenu *OBSBasicFilters::CreateAddFilterPopupMenu(bool async) inline FilterInfo(const char *type_, const char *name_) : type(type_), name(name_) - {} + { + } }; vector types; @@ -396,17 +393,17 @@ QMenu *OBSBasicFilters::CreateAddFilterPopupMenu(bool async) QMenu *popup = new QMenu(QTStr("Add"), this); for (FilterInfo &type : types) { - uint32_t filterFlags = obs_get_source_output_flags( - type.type.c_str()); + uint32_t filterFlags = + obs_get_source_output_flags(type.type.c_str()); if (!filter_compatible(async, sourceFlags, filterFlags)) continue; - QAction *popupItem = new QAction(QT_UTF8(type.name.c_str()), - this); + QAction *popupItem = + new QAction(QT_UTF8(type.name.c_str()), this); popupItem->setData(QT_UTF8(type.type.c_str())); - connect(popupItem, SIGNAL(triggered(bool)), - this, SLOT(AddFilterFromAction())); + connect(popupItem, SIGNAL(triggered(bool)), this, + SLOT(AddFilterFromAction())); popup->addAction(popupItem); foundValues = true; @@ -426,40 +423,40 @@ void OBSBasicFilters::AddNewFilter(const char *id) obs_source_t *existing_filter; string name = obs_source_get_display_name(id); - bool success = NameDialog::AskForName(this, - QTStr("Basic.Filters.AddFilter.Title"), - QTStr("Basic.FIlters.AddFilter.Text"), name, - QT_UTF8(name.c_str())); + bool success = NameDialog::AskForName( + this, QTStr("Basic.Filters.AddFilter.Title"), + QTStr("Basic.FIlters.AddFilter.Text"), name, + QT_UTF8(name.c_str())); if (!success) return; if (name.empty()) { OBSMessageBox::warning(this, - QTStr("NoNameEntered.Title"), - QTStr("NoNameEntered.Text")); + QTStr("NoNameEntered.Title"), + QTStr("NoNameEntered.Text")); AddNewFilter(id); return; } - existing_filter = obs_source_get_filter_by_name(source, - name.c_str()); + existing_filter = + obs_source_get_filter_by_name(source, name.c_str()); if (existing_filter) { - OBSMessageBox::warning(this, - QTStr("NameExists.Title"), - QTStr("NameExists.Text")); + OBSMessageBox::warning(this, QTStr("NameExists.Title"), + QTStr("NameExists.Text")); obs_source_release(existing_filter); AddNewFilter(id); return; } - obs_source_t *filter = obs_source_create(id, name.c_str(), - nullptr, nullptr); + obs_source_t *filter = + obs_source_create(id, name.c_str(), nullptr, nullptr); if (filter) { const char *sourceName = obs_source_get_name(source); - blog(LOG_INFO, "User added filter '%s' (%s) " - "to source '%s'", - name.c_str(), id, sourceName); + blog(LOG_INFO, + "User added filter '%s' (%s) " + "to source '%s'", + name.c_str(), id, sourceName); obs_source_filter_add(source, filter); obs_source_release(filter); @@ -469,7 +466,7 @@ void OBSBasicFilters::AddNewFilter(const char *id) void OBSBasicFilters::AddFilterFromAction() { - QAction *action = qobject_cast(sender()); + QAction *action = qobject_cast(sender()); if (!action) return; @@ -482,8 +479,8 @@ void OBSBasicFilters::closeEvent(QCloseEvent *event) if (!event->isAccepted()) return; - obs_display_remove_draw_callback (ui->preview->GetDisplay(), - OBSBasicFilters::DrawPreview, this); + obs_display_remove_draw_callback(ui->preview->GetDisplay(), + OBSBasicFilters::DrawPreview, this); main->SaveProject(); } @@ -492,26 +489,26 @@ void OBSBasicFilters::closeEvent(QCloseEvent *event) void OBSBasicFilters::OBSSourceFilterAdded(void *param, calldata_t *data) { - OBSBasicFilters *window = reinterpret_cast(param); - obs_source_t *filter = (obs_source_t*)calldata_ptr(data, "filter"); + OBSBasicFilters *window = reinterpret_cast(param); + obs_source_t *filter = (obs_source_t *)calldata_ptr(data, "filter"); QMetaObject::invokeMethod(window, "AddFilter", - Q_ARG(OBSSource, OBSSource(filter))); + Q_ARG(OBSSource, OBSSource(filter))); } void OBSBasicFilters::OBSSourceFilterRemoved(void *param, calldata_t *data) { - OBSBasicFilters *window = reinterpret_cast(param); - obs_source_t *filter = (obs_source_t*)calldata_ptr(data, "filter"); + OBSBasicFilters *window = reinterpret_cast(param); + obs_source_t *filter = (obs_source_t *)calldata_ptr(data, "filter"); QMetaObject::invokeMethod(window, "RemoveFilter", - Q_ARG(OBSSource, OBSSource(filter))); + Q_ARG(OBSSource, OBSSource(filter))); } void OBSBasicFilters::OBSSourceReordered(void *param, calldata_t *data) { - QMetaObject::invokeMethod(reinterpret_cast(param), - "ReorderFilters"); + QMetaObject::invokeMethod(reinterpret_cast(param), + "ReorderFilters"); UNUSED_PARAMETER(data); } @@ -520,8 +517,8 @@ void OBSBasicFilters::SourceRemoved(void *param, calldata_t *data) { UNUSED_PARAMETER(data); - QMetaObject::invokeMethod(static_cast(param), - "close"); + QMetaObject::invokeMethod(static_cast(param), + "close"); } void OBSBasicFilters::SourceRenamed(void *param, calldata_t *data) @@ -529,13 +526,13 @@ void OBSBasicFilters::SourceRenamed(void *param, calldata_t *data) const char *name = calldata_string(data, "new_name"); QString title = QTStr("Basic.Filters.Title").arg(QT_UTF8(name)); - QMetaObject::invokeMethod(static_cast(param), - "setWindowTitle", Q_ARG(QString, title)); + QMetaObject::invokeMethod(static_cast(param), + "setWindowTitle", Q_ARG(QString, title)); } void OBSBasicFilters::DrawPreview(void *data, uint32_t cx, uint32_t cy) { - OBSBasicFilters *window = static_cast(data); + OBSBasicFilters *window = static_cast(data); if (!window->source) return; @@ -543,8 +540,8 @@ void OBSBasicFilters::DrawPreview(void *data, uint32_t cx, uint32_t cy) uint32_t sourceCX = max(obs_source_get_width(window->source), 1u); uint32_t sourceCY = max(obs_source_get_height(window->source), 1u); - int x, y; - int newCX, newCY; + int x, y; + int newCX, newCY; float scale; GetScaleAndCenterPos(sourceCX, sourceCY, cx, cy, x, y, scale); @@ -567,15 +564,15 @@ void OBSBasicFilters::DrawPreview(void *data, uint32_t cx, uint32_t cy) static bool QueryRemove(QWidget *parent, obs_source_t *source) { - const char *name = obs_source_get_name(source); + const char *name = obs_source_get_name(source); QString text = QTStr("ConfirmRemove.Text"); text.replace("$1", QT_UTF8(name)); QMessageBox remove_source(parent); remove_source.setText(text); - QAbstractButton *Yes = remove_source.addButton(QTStr("Yes"), - QMessageBox::YesRole); + QAbstractButton *Yes = + remove_source.addButton(QTStr("Yes"), QMessageBox::YesRole); remove_source.addButton(QTStr("No"), QMessageBox::NoRole); remove_source.setIcon(QMessageBox::Question); remove_source.setWindowTitle(QTStr("ConfirmRemove.Title")); @@ -612,7 +609,7 @@ void OBSBasicFilters::on_moveAsyncFilterDown_clicked() OBSSource filter = GetFilter(ui->asyncFilters->currentRow(), true); if (filter) obs_source_filter_set_order(source, filter, - OBS_ORDER_MOVE_DOWN); + OBS_ORDER_MOVE_DOWN); } void OBSBasicFilters::on_asyncFilters_GotFocus() @@ -654,7 +651,7 @@ void OBSBasicFilters::on_moveEffectFilterDown_clicked() OBSSource filter = GetFilter(ui->effectFilters->currentRow(), false); if (filter) obs_source_filter_set_order(source, filter, - OBS_ORDER_MOVE_DOWN); + OBS_ORDER_MOVE_DOWN); } void OBSBasicFilters::on_effectFilters_GotFocus() @@ -704,11 +701,11 @@ void OBSBasicFilters::CustomContextMenu(const QPoint &pos, bool async) popup.addMenu(addMenu); if (item) { - const char *renameSlot = async ? - SLOT(RenameAsyncFilter()) : SLOT(RenameEffectFilter()); - const char *removeSlot = async ? - SLOT(on_removeAsyncFilter_clicked()) : - SLOT(on_removeEffectFilter_clicked()); + const char *renameSlot = async ? SLOT(RenameAsyncFilter()) + : SLOT(RenameEffectFilter()); + const char *removeSlot = + async ? SLOT(on_removeAsyncFilter_clicked()) + : SLOT(on_removeEffectFilter_clicked()); popup.addSeparator(); popup.addAction(QTStr("Rename"), this, renameSlot); @@ -721,9 +718,9 @@ void OBSBasicFilters::CustomContextMenu(const QPoint &pos, bool async) void OBSBasicFilters::EditItem(QListWidgetItem *item, bool async) { Qt::ItemFlags flags = item->flags(); - OBSSource filter = item->data(Qt::UserRole).value(); - const char *name = obs_source_get_name(filter); - QListWidget *list = async ? ui->asyncFilters : ui->effectFilters; + OBSSource filter = item->data(Qt::UserRole).value(); + const char *name = obs_source_get_name(filter); + QListWidget *list = async ? ui->asyncFilters : ui->effectFilters; item->setText(QT_UTF8(name)); item->setFlags(flags | Qt::ItemIsEditable); @@ -733,13 +730,13 @@ void OBSBasicFilters::EditItem(QListWidgetItem *item, bool async) } void OBSBasicFilters::on_asyncFilters_customContextMenuRequested( - const QPoint &pos) + const QPoint &pos) { CustomContextMenu(pos, true); } void OBSBasicFilters::on_effectFilters_customContextMenuRequested( - const QPoint &pos) + const QPoint &pos) { CustomContextMenu(pos, false); } @@ -758,7 +755,7 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list) { QListWidgetItem *listItem = list->currentItem(); OBSSource filter = listItem->data(Qt::UserRole).value(); - QLineEdit *edit = qobject_cast(editor); + QLineEdit *edit = qobject_cast(editor); string name = QT_TO_UTF8(edit->text().trimmed()); const char *prevName = obs_source_get_name(filter); @@ -766,28 +763,29 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list) obs_source_t *foundFilter = nullptr; if (!sameName) - foundFilter = obs_source_get_filter_by_name(source, - name.c_str()); + foundFilter = + obs_source_get_filter_by_name(source, name.c_str()); if (foundFilter || name.empty() || sameName) { listItem->setText(QT_UTF8(prevName)); if (foundFilter) { OBSMessageBox::information(window(), - QTStr("NameExists.Title"), - QTStr("NameExists.Text")); + QTStr("NameExists.Title"), + QTStr("NameExists.Text")); obs_source_release(foundFilter); } else if (name.empty()) { OBSMessageBox::information(window(), - QTStr("NoNameEntered.Title"), - QTStr("NoNameEntered.Text")); + QTStr("NoNameEntered.Title"), + QTStr("NoNameEntered.Text")); } } else { const char *sourceName = obs_source_get_name(source); - blog(LOG_INFO, "User renamed filter '%s' on source '%s' to '%s'", - prevName, sourceName, name.c_str()); + blog(LOG_INFO, + "User renamed filter '%s' on source '%s' to '%s'", + prevName, sourceName, name.c_str()); listItem->setText(QT_UTF8(name.c_str())); obs_source_set_name(filter, name.c_str()); @@ -797,15 +795,15 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list) SetupVisibilityItem(list, listItem, filter); } -void OBSBasicFilters::AsyncFilterNameEdited(QWidget *editor, - QAbstractItemDelegate::EndEditHint endHint) +void OBSBasicFilters::AsyncFilterNameEdited( + QWidget *editor, QAbstractItemDelegate::EndEditHint endHint) { FilterNameEdited(editor, ui->asyncFilters); UNUSED_PARAMETER(endHint); } -void OBSBasicFilters::EffectFilterNameEdited(QWidget *editor, - QAbstractItemDelegate::EndEditHint endHint) +void OBSBasicFilters::EffectFilterNameEdited( + QWidget *editor, QAbstractItemDelegate::EndEditHint endHint) { FilterNameEdited(editor, ui->effectFilters); UNUSED_PARAMETER(endHint); diff --git a/UI/window-basic-filters.hpp b/UI/window-basic-filters.hpp index 5ab28a0..19860e6 100644 --- a/UI/window-basic-filters.hpp +++ b/UI/window-basic-filters.hpp @@ -105,9 +105,9 @@ private slots: void on_actionMoveDown_triggered(); void AsyncFilterNameEdited(QWidget *editor, - QAbstractItemDelegate::EndEditHint endHint); + QAbstractItemDelegate::EndEditHint endHint); void EffectFilterNameEdited(QWidget *editor, - QAbstractItemDelegate::EndEditHint endHint); + QAbstractItemDelegate::EndEditHint endHint); public: OBSBasicFilters(QWidget *parent, OBSSource source_); diff --git a/UI/window-basic-interaction.cpp b/UI/window-basic-interaction.cpp index a0265fc..8b37b4d 100644 --- a/UI/window-basic-interaction.cpp +++ b/UI/window-basic-interaction.cpp @@ -29,20 +29,20 @@ using namespace std; OBSBasicInteraction::OBSBasicInteraction(QWidget *parent, OBSSource source_) - : QDialog (parent), - main (qobject_cast(parent)), - ui (new Ui::OBSBasicInteraction), - source (source_), - removedSignal (obs_source_get_signal_handler(source), "remove", - OBSBasicInteraction::SourceRemoved, this), - renamedSignal (obs_source_get_signal_handler(source), "rename", - OBSBasicInteraction::SourceRenamed, this), - eventFilter (BuildEventFilter()) + : QDialog(parent), + main(qobject_cast(parent)), + ui(new Ui::OBSBasicInteraction), + source(source_), + removedSignal(obs_source_get_signal_handler(source), "remove", + OBSBasicInteraction::SourceRemoved, this), + renamedSignal(obs_source_get_signal_handler(source), "rename", + OBSBasicInteraction::SourceRenamed, this), + eventFilter(BuildEventFilter()) { int cx = (int)config_get_int(App()->GlobalConfig(), "InteractionWindow", - "cx"); + "cx"); int cy = (int)config_get_int(App()->GlobalConfig(), "InteractionWindow", - "cy"); + "cy"); ui->setupUi(this); @@ -59,10 +59,10 @@ OBSBasicInteraction::OBSBasicInteraction(QWidget *parent, OBSSource source_) const char *name = obs_source_get_name(source); setWindowTitle(QTStr("Basic.InteractionWindow").arg(QT_UTF8(name))); - auto addDrawCallback = [this] () - { + auto addDrawCallback = [this]() { obs_display_add_draw_callback(ui->preview->GetDisplay(), - OBSBasicInteraction::DrawPreview, this); + OBSBasicInteraction::DrawPreview, + this); }; connect(ui->preview, &OBSQTDisplay::DisplayCreated, addDrawCallback); @@ -77,34 +77,32 @@ OBSBasicInteraction::~OBSBasicInteraction() OBSEventFilter *OBSBasicInteraction::BuildEventFilter() { - return new OBSEventFilter( - [this](QObject *obj, QEvent *event) - { + return new OBSEventFilter([this](QObject *obj, QEvent *event) { UNUSED_PARAMETER(obj); - switch(event->type()) { + switch (event->type()) { case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: return this->HandleMouseClickEvent( - static_cast(event)); + static_cast(event)); case QEvent::MouseMove: case QEvent::Enter: case QEvent::Leave: return this->HandleMouseMoveEvent( - static_cast(event)); + static_cast(event)); case QEvent::Wheel: return this->HandleMouseWheelEvent( - static_cast(event)); + static_cast(event)); case QEvent::FocusIn: case QEvent::FocusOut: return this->HandleFocusEvent( - static_cast(event)); + static_cast(event)); case QEvent::KeyPress: case QEvent::KeyRelease: return this->HandleKeyEvent( - static_cast(event)); + static_cast(event)); default: return false; } @@ -113,8 +111,8 @@ OBSEventFilter *OBSBasicInteraction::BuildEventFilter() void OBSBasicInteraction::SourceRemoved(void *data, calldata_t *params) { - QMetaObject::invokeMethod(static_cast(data), - "close"); + QMetaObject::invokeMethod(static_cast(data), + "close"); UNUSED_PARAMETER(params); } @@ -124,13 +122,13 @@ void OBSBasicInteraction::SourceRenamed(void *data, calldata_t *params) const char *name = calldata_string(params, "new_name"); QString title = QTStr("Basic.InteractionWindow").arg(QT_UTF8(name)); - QMetaObject::invokeMethod(static_cast(data), - "setWindowTitle", Q_ARG(QString, title)); + QMetaObject::invokeMethod(static_cast(data), + "setWindowTitle", Q_ARG(QString, title)); } void OBSBasicInteraction::DrawPreview(void *data, uint32_t cx, uint32_t cy) { - OBSBasicInteraction *window = static_cast(data); + OBSBasicInteraction *window = static_cast(data); if (!window->source) return; @@ -138,8 +136,8 @@ void OBSBasicInteraction::DrawPreview(void *data, uint32_t cx, uint32_t cy) uint32_t sourceCX = max(obs_source_get_width(window->source), 1u); uint32_t sourceCY = max(obs_source_get_height(window->source), 1u); - int x, y; - int newCX, newCY; + int x, y; + int newCX, newCY; float scale; GetScaleAndCenterPos(sourceCX, sourceCY, cx, cy, x, y, scale); @@ -149,8 +147,7 @@ void OBSBasicInteraction::DrawPreview(void *data, uint32_t cx, uint32_t cy) gs_viewport_push(); gs_projection_push(); - gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY), - -100.0f, 100.0f); + gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY), -100.0f, 100.0f); gs_set_viewport(x, y, newCX, newCY); obs_source_video_render(window->source); @@ -165,15 +162,18 @@ void OBSBasicInteraction::closeEvent(QCloseEvent *event) return; config_set_int(App()->GlobalConfig(), "InteractionWindow", "cx", - width()); + width()); config_set_int(App()->GlobalConfig(), "InteractionWindow", "cy", - height()); + height()); obs_display_remove_draw_callback(ui->preview->GetDisplay(), - OBSBasicInteraction::DrawPreview, this); + OBSBasicInteraction::DrawPreview, + this); } -static int TranslateQtKeyboardEventModifiers(QInputEvent *event, bool mouseEvent) { +static int TranslateQtKeyboardEventModifiers(QInputEvent *event, + bool mouseEvent) +{ int obsModifiers = INTERACT_NONE; if (event->modifiers().testFlag(Qt::ShiftModifier)) @@ -200,8 +200,7 @@ static int TranslateQtKeyboardEventModifiers(QInputEvent *event, bool mouseEvent return obsModifiers; } -static int TranslateQtMouseEventModifiers( - QMouseEvent *event) +static int TranslateQtMouseEventModifiers(QMouseEvent *event) { int modifiers = TranslateQtKeyboardEventModifiers(event, true); @@ -215,19 +214,19 @@ static int TranslateQtMouseEventModifiers( return modifiers; } -bool OBSBasicInteraction::GetSourceRelativeXY( - int mouseX, int mouseY, int &relX, int &relY) +bool OBSBasicInteraction::GetSourceRelativeXY(int mouseX, int mouseY, int &relX, + int &relY) { QSize size = GetPixelSize(ui->preview); uint32_t sourceCX = max(obs_source_get_width(source), 1u); uint32_t sourceCY = max(obs_source_get_height(source), 1u); - int x, y; + int x, y; float scale; - GetScaleAndCenterPos(sourceCX, sourceCY, size.width(), size.height(), - x, y, scale); + GetScaleAndCenterPos(sourceCX, sourceCY, size.width(), size.height(), x, + y, scale); if (x > 0) { relX = int(float(mouseX - x) / scale); @@ -246,8 +245,7 @@ bool OBSBasicInteraction::GetSourceRelativeXY( return true; } -bool OBSBasicInteraction::HandleMouseClickEvent( - QMouseEvent *event) +bool OBSBasicInteraction::HandleMouseClickEvent(QMouseEvent *event) { bool mouseUp = event->type() == QEvent::MouseButtonRelease; int clickCount = 1; @@ -271,8 +269,7 @@ bool OBSBasicInteraction::HandleMouseClickEvent( button = MOUSE_RIGHT; break; default: - blog(LOG_WARNING, "unknown button type %d", - event->button()); + blog(LOG_WARNING, "unknown button type %d", event->button()); return false; } @@ -281,11 +278,11 @@ bool OBSBasicInteraction::HandleMouseClickEvent( // clickCount = 2; bool insideSource = GetSourceRelativeXY(event->x(), event->y(), - mouseEvent.x, mouseEvent.y); + mouseEvent.x, mouseEvent.y); if (mouseUp || insideSource) obs_source_send_mouse_click(source, &mouseEvent, button, - mouseUp, clickCount); + mouseUp, clickCount); return true; } @@ -299,7 +296,7 @@ bool OBSBasicInteraction::HandleMouseMoveEvent(QMouseEvent *event) if (!mouseLeave) { mouseEvent.modifiers = TranslateQtMouseEventModifiers(event); mouseLeave = !GetSourceRelativeXY(event->x(), event->y(), - mouseEvent.x, mouseEvent.y); + mouseEvent.x, mouseEvent.y); } obs_source_send_mouse_move(source, &mouseEvent, mouseLeave); @@ -329,9 +326,9 @@ bool OBSBasicInteraction::HandleMouseWheelEvent(QWheelEvent *event) } if (GetSourceRelativeXY(event->x(), event->y(), mouseEvent.x, - mouseEvent.y)) + mouseEvent.y)) obs_source_send_mouse_wheel(source, &mouseEvent, xDelta, - yDelta); + yDelta); return true; } diff --git a/UI/window-basic-interaction.hpp b/UI/window-basic-interaction.hpp index d02725e..1788deb 100644 --- a/UI/window-basic-interaction.hpp +++ b/UI/window-basic-interaction.hpp @@ -35,12 +35,12 @@ class OBSBasicInteraction : public QDialog { Q_OBJECT private: - OBSBasic *main; + OBSBasic *main; std::unique_ptr ui; - OBSSource source; - OBSSignal removedSignal; - OBSSignal renamedSignal; + OBSSource source; + OBSSignal removedSignal; + OBSSignal renamedSignal; std::unique_ptr eventFilter; static void SourceRemoved(void *data, calldata_t *params); @@ -69,13 +69,10 @@ protected: typedef std::function EventFilterFunc; -class OBSEventFilter : public QObject -{ +class OBSEventFilter : public QObject { Q_OBJECT public: - OBSEventFilter(EventFilterFunc filter_) - : filter(filter_) - {} + OBSEventFilter(EventFilterFunc filter_) : filter(filter_) {} protected: bool eventFilter(QObject *obj, QEvent *event) diff --git a/UI/window-basic-main-browser.cpp b/UI/window-basic-main-browser.cpp index c29fe07..0434a67 100644 --- a/UI/window-basic-main-browser.cpp +++ b/UI/window-basic-main-browser.cpp @@ -30,7 +30,7 @@ struct QCef; struct QCefCookieManager; -extern QCef *cef; +extern QCef *cef; extern QCefCookieManager *panel_cookies; static std::string GenId() @@ -52,7 +52,8 @@ void CheckExistingCookieId() if (config_has_user_value(main->Config(), "Panels", "CookieId")) return; - config_set_string(main->Config(), "Panels", "CookieId", GenId().c_str()); + config_set_string(main->Config(), "Panels", "CookieId", + GenId().c_str()); } #ifdef BROWSER_AVAILABLE @@ -66,8 +67,8 @@ static void InitPanelCookieManager() CheckExistingCookieId(); OBSBasic *main = OBSBasic::Get(); - const char *cookie_id = config_get_string(main->Config(), - "Panels", "CookieId"); + const char *cookie_id = + config_get_string(main->Config(), "Panels", "CookieId"); std::string sub_path; sub_path += "obs_profile_cookies/"; @@ -102,8 +103,8 @@ void DuplicateCurrentCookieProfile(ConfigFile &config) #ifdef BROWSER_AVAILABLE if (cef) { OBSBasic *main = OBSBasic::Get(); - std::string cookie_id = config_get_string(main->Config(), - "Panels", "CookieId"); + std::string cookie_id = + config_get_string(main->Config(), "Panels", "CookieId"); std::string src_path; src_path += "obs_profile_cookies/"; @@ -136,9 +137,9 @@ void DuplicateCurrentCookieProfile(ConfigFile &config) } config_set_string(config, "Panels", "CookieId", - cookie_id.c_str()); + cookie_id.c_str()); config_set_string(main->Config(), "Panels", "CookieId", - new_id.c_str()); + new_id.c_str()); } #else UNUSED_PARAMETER(config); @@ -155,10 +156,9 @@ void OBSBasic::InitBrowserPanelSafeBlock() return; } - ExecThreadedWithoutBlocking( - [] {cef->wait_for_browser_init();}, - QTStr("BrowserPanelInit.Title"), - QTStr("BrowserPanelInit.Text")); + ExecThreadedWithoutBlocking([] { cef->wait_for_browser_init(); }, + QTStr("BrowserPanelInit.Title"), + QTStr("BrowserPanelInit.Text")); InitPanelCookieManager(); #endif } diff --git a/UI/window-basic-main-dropfiles.cpp b/UI/window-basic-main-dropfiles.cpp index 50dd3d3..9ba74f0 100644 --- a/UI/window-basic-main-dropfiles.cpp +++ b/UI/window-basic-main-dropfiles.cpp @@ -11,34 +11,29 @@ using namespace std; -static const char *textExtensions[] = { - "txt", "log", nullptr -}; +static const char *textExtensions[] = {"txt", "log", nullptr}; -static const char *imageExtensions[] = { - "bmp", "tga", "png", "jpg", "jpeg", "gif", nullptr -}; +static const char *imageExtensions[] = {"bmp", "tga", "png", "jpg", + "jpeg", "gif", nullptr}; -static const char *htmlExtensions[] = { - "htm", "html", nullptr -}; +static const char *htmlExtensions[] = {"htm", "html", nullptr}; static const char *mediaExtensions[] = { - "3ga", "669", "a52", "aac", "ac3", "adt", "adts", "aif", "aifc", - "aiff", "amb", "amr", "aob", "ape", "au", "awb", "caf", "dts", - "flac", "it", "kar", "m4a", "m4b", "m4p", "m5p", "mid", "mka", - "mlp", "mod", "mpa", "mp1", "mp2", "mp3", "mpc", "mpga", "mus", - "oga", "ogg", "oma", "opus", "qcp", "ra", "rmi", "s3m", "sid", - "spx", "tak", "thd", "tta", "voc", "vqf", "w64", "wav", "wma", - "wv", "xa", "xm", "3g2", "3gp", "3gp2", "3gpp", "amv", "asf", "avi", - "bik", "crf", "divx", "drc", "dv", "evo", "f4v", "flv", "gvi", - "gxf", "iso", "m1v", "m2v", "m2t", "m2ts", "m4v", "mkv", "mov", - "mp2", "mp2v", "mp4", "mp4v", "mpe", "mpeg", "mpeg1", "mpeg2", - "mpeg4", "mpg", "mpv2", "mts", "mtv", "mxf", "mxg", "nsv", "nuv", - "ogg", "ogm", "ogv", "ogx", "ps", "rec", "rm", "rmvb", "rpl", "thp", - "tod", "ts", "tts", "txd", "vob", "vro", "webm", "wm", "wmv", "wtv", - nullptr -}; + "3ga", "669", "a52", "aac", "ac3", "adt", "adts", "aif", + "aifc", "aiff", "amb", "amr", "aob", "ape", "au", "awb", + "caf", "dts", "flac", "it", "kar", "m4a", "m4b", "m4p", + "m5p", "mid", "mka", "mlp", "mod", "mpa", "mp1", "mp2", + "mp3", "mpc", "mpga", "mus", "oga", "ogg", "oma", "opus", + "qcp", "ra", "rmi", "s3m", "sid", "spx", "tak", "thd", + "tta", "voc", "vqf", "w64", "wav", "wma", "wv", "xa", + "xm", "3g2", "3gp", "3gp2", "3gpp", "amv", "asf", "avi", + "bik", "crf", "divx", "drc", "dv", "evo", "f4v", "flv", + "gvi", "gxf", "iso", "m1v", "m2v", "m2t", "m2ts", "m4v", + "mkv", "mov", "mp2", "mp2v", "mp4", "mp4v", "mpe", "mpeg", + "mpeg1", "mpeg2", "mpeg4", "mpg", "mpv2", "mts", "mtv", "mxf", + "mxg", "nsv", "nuv", "ogg", "ogm", "ogv", "ogx", "ps", + "rec", "rm", "rmvb", "rpl", "thp", "tod", "ts", "tts", + "txd", "vob", "vro", "webm", "wm", "wmv", "wtv", nullptr}; static string GenerateSourceName(const char *base) { @@ -50,7 +45,7 @@ static string GenerateSourceName(const char *base) if (inc) { name += " ("; - name += to_string(inc+1); + name += to_string(inc + 1); name += ")"; } @@ -62,7 +57,7 @@ static string GenerateSourceName(const char *base) void OBSBasic::AddDropSource(const char *data, DropType image) { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); obs_data_t *settings = obs_data_create(); obs_source_t *source = nullptr; const char *type = nullptr; @@ -115,8 +110,8 @@ void OBSBasic::AddDropSource(const char *data, DropType image) if (name.isEmpty()) name = obs_source_get_display_name(type); source = obs_source_create(type, - GenerateSourceName(QT_TO_UTF8(name)).c_str(), - settings, nullptr); + GenerateSourceName(QT_TO_UTF8(name)).c_str(), + settings, nullptr); if (source) { OBSScene scene = main->GetCurrentScene(); obs_scene_add(scene, source); @@ -143,7 +138,7 @@ void OBSBasic::dragMoveEvent(QDragMoveEvent *event) void OBSBasic::dropEvent(QDropEvent *event) { - const QMimeData* mimeData = event->mimeData(); + const QMimeData *mimeData = event->mimeData(); if (mimeData->hasUrls()) { QList urls = mimeData->urls(); @@ -162,20 +157,20 @@ void OBSBasic::dropEvent(QDropEvent *event) const char **cmp; -#define CHECK_SUFFIX(extensions, type) \ -cmp = extensions; \ -while (*cmp) { \ - if (strcmp(*cmp, suffix) == 0) { \ - AddDropSource(QT_TO_UTF8(file), type); \ - found = true; \ - break; \ - } \ -\ - cmp++; \ -} \ -\ -if (found) \ - continue; +#define CHECK_SUFFIX(extensions, type) \ + cmp = extensions; \ + while (*cmp) { \ + if (strcmp(*cmp, suffix) == 0) { \ + AddDropSource(QT_TO_UTF8(file), type); \ + found = true; \ + break; \ + } \ + \ + cmp++; \ + } \ + \ + if (found) \ + continue; CHECK_SUFFIX(textExtensions, DropType_Text); CHECK_SUFFIX(htmlExtensions, DropType_Html); @@ -188,4 +183,3 @@ if (found) \ AddDropSource(QT_TO_UTF8(mimeData->text()), DropType_RawText); } } - diff --git a/UI/window-basic-main-outputs.cpp b/UI/window-basic-main-outputs.cpp index 6b3e46f..6ee726b 100644 --- a/UI/window-basic-main-outputs.cpp +++ b/UI/window-basic-main-outputs.cpp @@ -12,38 +12,39 @@ extern bool EncoderAvailable(const char *encoder); volatile bool streaming_active = false; volatile bool recording_active = false; +volatile bool recording_paused = false; volatile bool replaybuf_active = false; static void OBSStreamStarting(void *data, calldata_t *params) { - BasicOutputHandler *output = static_cast(data); - obs_output_t *obj = (obs_output_t*)calldata_ptr(params, "output"); + BasicOutputHandler *output = static_cast(data); + obs_output_t *obj = (obs_output_t *)calldata_ptr(params, "output"); int sec = (int)obs_output_get_active_delay(obj); if (sec == 0) return; output->delayActive = true; - QMetaObject::invokeMethod(output->main, - "StreamDelayStarting", Q_ARG(int, sec)); + QMetaObject::invokeMethod(output->main, "StreamDelayStarting", + Q_ARG(int, sec)); } static void OBSStreamStopping(void *data, calldata_t *params) { - BasicOutputHandler *output = static_cast(data); - obs_output_t *obj = (obs_output_t*)calldata_ptr(params, "output"); + BasicOutputHandler *output = static_cast(data); + obs_output_t *obj = (obs_output_t *)calldata_ptr(params, "output"); int sec = (int)obs_output_get_active_delay(obj); if (sec == 0) QMetaObject::invokeMethod(output->main, "StreamStopping"); else - QMetaObject::invokeMethod(output->main, - "StreamDelayStopping", Q_ARG(int, sec)); + QMetaObject::invokeMethod(output->main, "StreamDelayStopping", + Q_ARG(int, sec)); } static void OBSStartStreaming(void *data, calldata_t *params) { - BasicOutputHandler *output = static_cast(data); + BasicOutputHandler *output = static_cast(data); output->streamingActive = true; os_atomic_set_bool(&streaming_active, true); QMetaObject::invokeMethod(output->main, "StreamingStart"); @@ -53,7 +54,7 @@ static void OBSStartStreaming(void *data, calldata_t *params) static void OBSStopStreaming(void *data, calldata_t *params) { - BasicOutputHandler *output = static_cast(data); + BasicOutputHandler *output = static_cast(data); int code = (int)calldata_int(params, "code"); const char *last_error = calldata_string(params, "last_error"); @@ -62,14 +63,14 @@ static void OBSStopStreaming(void *data, calldata_t *params) output->streamingActive = false; output->delayActive = false; os_atomic_set_bool(&streaming_active, false); - QMetaObject::invokeMethod(output->main, - "StreamingStop", Q_ARG(int, code), - Q_ARG(QString, arg_last_error)); + QMetaObject::invokeMethod(output->main, "StreamingStop", + Q_ARG(int, code), + Q_ARG(QString, arg_last_error)); } static void OBSStartRecording(void *data, calldata_t *params) { - BasicOutputHandler *output = static_cast(data); + BasicOutputHandler *output = static_cast(data); output->recordingActive = true; os_atomic_set_bool(&recording_active, true); @@ -80,7 +81,7 @@ static void OBSStartRecording(void *data, calldata_t *params) static void OBSStopRecording(void *data, calldata_t *params) { - BasicOutputHandler *output = static_cast(data); + BasicOutputHandler *output = static_cast(data); int code = (int)calldata_int(params, "code"); const char *last_error = calldata_string(params, "last_error"); @@ -88,16 +89,17 @@ static void OBSStopRecording(void *data, calldata_t *params) output->recordingActive = false; os_atomic_set_bool(&recording_active, false); - QMetaObject::invokeMethod(output->main, - "RecordingStop", Q_ARG(int, code), - Q_ARG(QString, arg_last_error)); + os_atomic_set_bool(&recording_paused, false); + QMetaObject::invokeMethod(output->main, "RecordingStop", + Q_ARG(int, code), + Q_ARG(QString, arg_last_error)); UNUSED_PARAMETER(params); } static void OBSRecordStopping(void *data, calldata_t *params) { - BasicOutputHandler *output = static_cast(data); + BasicOutputHandler *output = static_cast(data); QMetaObject::invokeMethod(output->main, "RecordStopping"); UNUSED_PARAMETER(params); @@ -105,7 +107,7 @@ static void OBSRecordStopping(void *data, calldata_t *params) static void OBSStartReplayBuffer(void *data, calldata_t *params) { - BasicOutputHandler *output = static_cast(data); + BasicOutputHandler *output = static_cast(data); output->replayBufferActive = true; os_atomic_set_bool(&replaybuf_active, true); @@ -116,20 +118,20 @@ static void OBSStartReplayBuffer(void *data, calldata_t *params) static void OBSStopReplayBuffer(void *data, calldata_t *params) { - BasicOutputHandler *output = static_cast(data); + BasicOutputHandler *output = static_cast(data); int code = (int)calldata_int(params, "code"); output->replayBufferActive = false; os_atomic_set_bool(&replaybuf_active, false); - QMetaObject::invokeMethod(output->main, - "ReplayBufferStop", Q_ARG(int, code)); + QMetaObject::invokeMethod(output->main, "ReplayBufferStop", + Q_ARG(int, code)); UNUSED_PARAMETER(params); } static void OBSReplayBufferStopping(void *data, calldata_t *params) { - BasicOutputHandler *output = static_cast(data); + BasicOutputHandler *output = static_cast(data); QMetaObject::invokeMethod(output->main, "ReplayBufferStopping"); UNUSED_PARAMETER(params); @@ -168,7 +170,7 @@ static void FindBestFilename(string &strPath, bool noSpace) /* ------------------------------------------------------------------------ */ static bool CreateAACEncoder(OBSEncoder &res, string &id, int bitrate, - const char *name, size_t idx) + const char *name, size_t idx) { const char *id_ = GetAACEncoderForBitrate(bitrate); if (!id_) { @@ -194,20 +196,20 @@ static bool CreateAACEncoder(OBSEncoder &res, string &id, int bitrate, /* ------------------------------------------------------------------------ */ struct SimpleOutput : BasicOutputHandler { - OBSEncoder aacStreaming; - OBSEncoder h264Streaming; - OBSEncoder aacRecording; - OBSEncoder h264Recording; + OBSEncoder aacStreaming; + OBSEncoder h264Streaming; + OBSEncoder aacRecording; + OBSEncoder h264Recording; - string aacRecEncID; - string aacStreamEncID; + string aacRecEncID; + string aacStreamEncID; - string videoEncoder; - string videoQuality; - bool usingRecordingPreset = false; - bool recordingConfigured = false; - bool ffmpegOutput = false; - bool lowCPUx264 = false; + string videoEncoder; + string videoQuality; + bool usingRecordingPreset = false; + bool recordingConfigured = false; + bool ffmpegOutput = false; + bool lowCPUx264 = false; SimpleOutput(OBSBasic *main_); @@ -247,8 +249,8 @@ struct SimpleOutput : BasicOutputHandler { void SimpleOutput::LoadRecordingPreset_Lossless() { - fileOutput = obs_output_create("ffmpeg_output", - "simple_ffmpeg_output", nullptr, nullptr); + fileOutput = obs_output_create("ffmpeg_output", "simple_ffmpeg_output", + nullptr, nullptr); if (!fileOutput) throw "Failed to create recording FFmpeg output " "(simple output)"; @@ -267,8 +269,8 @@ void SimpleOutput::LoadRecordingPreset_Lossless() void SimpleOutput::LoadRecordingPreset_h264(const char *encoderId) { - h264Recording = obs_video_encoder_create(encoderId, - "simple_h264_recording", nullptr, nullptr); + h264Recording = obs_video_encoder_create( + encoderId, "simple_h264_recording", nullptr, nullptr); if (!h264Recording) throw "Failed to create h264 recording encoder (simple output)"; obs_encoder_release(h264Recording); @@ -276,8 +278,8 @@ void SimpleOutput::LoadRecordingPreset_h264(const char *encoderId) void SimpleOutput::LoadStreamingPreset_h264(const char *encoderId) { - h264Streaming = obs_video_encoder_create(encoderId, - "simple_h264_stream", nullptr, nullptr); + h264Streaming = obs_video_encoder_create( + encoderId, "simple_h264_stream", nullptr, nullptr); if (!h264Streaming) throw "Failed to create h264 streaming encoder (simple output)"; obs_encoder_release(h264Streaming); @@ -285,10 +287,10 @@ void SimpleOutput::LoadStreamingPreset_h264(const char *encoderId) void SimpleOutput::LoadRecordingPreset() { - const char *quality = config_get_string(main->Config(), "SimpleOutput", - "RecQuality"); - const char *encoder = config_get_string(main->Config(), "SimpleOutput", - "RecEncoder"); + const char *quality = + config_get_string(main->Config(), "SimpleOutput", "RecQuality"); + const char *encoder = + config_get_string(main->Config(), "SimpleOutput", "RecEncoder"); videoEncoder = encoder; videoQuality = quality; @@ -320,14 +322,14 @@ void SimpleOutput::LoadRecordingPreset() LoadRecordingPreset_h264("amd_amf_h264"); } else if (strcmp(encoder, SIMPLE_ENCODER_NVENC) == 0) { const char *id = EncoderAvailable("jim_nvenc") - ? "jim_nvenc" - : "ffmpeg_nvenc"; + ? "jim_nvenc" + : "ffmpeg_nvenc"; LoadRecordingPreset_h264(id); } usingRecordingPreset = true; if (!CreateAACEncoder(aacRecording, aacRecEncID, 192, - "simple_aac_recording", 0)) + "simple_aac_recording", 0)) throw "Failed to create aac recording encoder " "(simple output)"; } @@ -336,7 +338,7 @@ void SimpleOutput::LoadRecordingPreset() SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_) { const char *encoder = config_get_string(main->Config(), "SimpleOutput", - "StreamEncoder"); + "StreamEncoder"); if (strcmp(encoder, SIMPLE_ENCODER_QSV) == 0) { LoadStreamingPreset_h264("obs_qsv11"); @@ -345,9 +347,8 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_) LoadStreamingPreset_h264("amd_amf_h264"); } else if (strcmp(encoder, SIMPLE_ENCODER_NVENC) == 0) { - const char *id = EncoderAvailable("jim_nvenc") - ? "jim_nvenc" - : "ffmpeg_nvenc"; + const char *id = EncoderAvailable("jim_nvenc") ? "jim_nvenc" + : "ffmpeg_nvenc"; LoadStreamingPreset_h264(id); } else { @@ -355,20 +356,21 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_) } if (!CreateAACEncoder(aacStreaming, aacStreamEncID, GetAudioBitrate(), - "simple_aac", 0)) + "simple_aac", 0)) throw "Failed to create aac streaming encoder (simple output)"; LoadRecordingPreset(); if (!ffmpegOutput) { bool useReplayBuffer = config_get_bool(main->Config(), - "SimpleOutput", "RecRB"); + "SimpleOutput", "RecRB"); if (useReplayBuffer) { - const char *str = config_get_string(main->Config(), - "Hotkeys", "ReplayBuffer"); + const char *str = config_get_string( + main->Config(), "Hotkeys", "ReplayBuffer"); obs_data_t *hotkey = obs_data_create_from_json(str); replayBuffer = obs_output_create("replay_buffer", - Str("ReplayBuffer"), nullptr, hotkey); + Str("ReplayBuffer"), + nullptr, hotkey); obs_data_release(hotkey); if (!replayBuffer) @@ -380,15 +382,16 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_) obs_output_get_signal_handler(replayBuffer); startReplayBuffer.Connect(signal, "start", - OBSStartReplayBuffer, this); + OBSStartReplayBuffer, this); stopReplayBuffer.Connect(signal, "stop", - OBSStopReplayBuffer, this); + OBSStopReplayBuffer, this); replayBufferStopping.Connect(signal, "stopping", - OBSReplayBufferStopping, this); + OBSReplayBufferStopping, + this); } - fileOutput = obs_output_create("ffmpeg_muxer", - "simple_file_output", nullptr, nullptr); + fileOutput = obs_output_create( + "ffmpeg_muxer", "simple_file_output", nullptr, nullptr); if (!fileOutput) throw "Failed to create recording output " "(simple output)"; @@ -396,17 +399,17 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_) } startRecording.Connect(obs_output_get_signal_handler(fileOutput), - "start", OBSStartRecording, this); - stopRecording.Connect(obs_output_get_signal_handler(fileOutput), - "stop", OBSStopRecording, this); + "start", OBSStartRecording, this); + stopRecording.Connect(obs_output_get_signal_handler(fileOutput), "stop", + OBSStopRecording, this); recordStopping.Connect(obs_output_get_signal_handler(fileOutput), - "stopping", OBSRecordStopping, this); + "stopping", OBSRecordStopping, this); } int SimpleOutput::GetAudioBitrate() const { int bitrate = (int)config_get_uint(main->Config(), "SimpleOutput", - "ABitrate"); + "ABitrate"); return FindClosestAvailableAACBitrate(bitrate); } @@ -414,19 +417,19 @@ int SimpleOutput::GetAudioBitrate() const void SimpleOutput::Update() { obs_data_t *h264Settings = obs_data_create(); - obs_data_t *aacSettings = obs_data_create(); + obs_data_t *aacSettings = obs_data_create(); - int videoBitrate = config_get_uint(main->Config(), "SimpleOutput", - "VBitrate"); + int videoBitrate = + config_get_uint(main->Config(), "SimpleOutput", "VBitrate"); int audioBitrate = GetAudioBitrate(); - bool advanced = config_get_bool(main->Config(), "SimpleOutput", - "UseAdvanced"); + bool advanced = + config_get_bool(main->Config(), "SimpleOutput", "UseAdvanced"); bool enforceBitrate = config_get_bool(main->Config(), "SimpleOutput", - "EnforceBitrate"); - const char *custom = config_get_string(main->Config(), - "SimpleOutput", "x264Settings"); + "EnforceBitrate"); + const char *custom = config_get_string(main->Config(), "SimpleOutput", + "x264Settings"); const char *encoder = config_get_string(main->Config(), "SimpleOutput", - "StreamEncoder"); + "StreamEncoder"); const char *presetType; const char *preset; @@ -457,8 +460,8 @@ void SimpleOutput::Update() obs_data_set_string(aacSettings, "rate_control", "CBR"); obs_data_set_int(aacSettings, "bitrate", audioBitrate); - obs_service_apply_encoder_settings(main->GetService(), - h264Settings, aacSettings); + obs_service_apply_encoder_settings(main->GetService(), h264Settings, + aacSettings); if (advanced && !enforceBitrate) { obs_data_set_int(h264Settings, "bitrate", videoBitrate); @@ -470,10 +473,10 @@ void SimpleOutput::Update() if (format != VIDEO_FORMAT_NV12 && format != VIDEO_FORMAT_I420) obs_encoder_set_preferred_video_format(h264Streaming, - VIDEO_FORMAT_NV12); + VIDEO_FORMAT_NV12); obs_encoder_update(h264Streaming, h264Settings); - obs_encoder_update(aacStreaming, aacSettings); + obs_encoder_update(aacStreaming, aacSettings); obs_data_release(h264Settings); obs_data_release(aacSettings); @@ -518,7 +521,7 @@ void SimpleOutput::UpdateRecordingSettings_x264_crf(int crf) obs_data_set_string(settings, "rate_control", "CRF"); obs_data_set_string(settings, "profile", "high"); obs_data_set_string(settings, "preset", - lowCPUx264 ? "ultrafast" : "veryfast"); + lowCPUx264 ? "ultrafast" : "veryfast"); obs_encoder_update(h264Recording, settings); @@ -580,7 +583,7 @@ void SimpleOutput::UpdateRecordingSettings_nvenc(int cqp) } void SimpleOutput::UpdateStreamingSettings_amd(obs_data_t *settings, - int bitrate) + int bitrate) { // Static Properties obs_data_set_int(settings, "Usage", 0); @@ -646,15 +649,15 @@ inline void SimpleOutput::SetupOutputs() { SimpleOutput::Update(); obs_encoder_set_video(h264Streaming, obs_get_video()); - obs_encoder_set_audio(aacStreaming, obs_get_audio()); + obs_encoder_set_audio(aacStreaming, obs_get_audio()); if (usingRecordingPreset) { if (ffmpegOutput) { obs_output_set_media(fileOutput, obs_get_video(), - obs_get_audio()); + obs_get_audio()); } else { obs_encoder_set_video(h264Recording, obs_get_video()); - obs_encoder_set_audio(aacRecording, obs_get_audio()); + obs_encoder_set_audio(aacRecording, obs_get_audio()); } } } @@ -696,59 +699,61 @@ bool SimpleOutput::StartStreaming(obs_service_t *service) startStreaming.Disconnect(); stopStreaming.Disconnect(); - streamOutput = obs_output_create(type, "simple_stream", - nullptr, nullptr); + streamOutput = obs_output_create(type, "simple_stream", nullptr, + nullptr); if (!streamOutput) { - blog(LOG_WARNING, "Creation of stream output type '%s' " - "failed!", type); + blog(LOG_WARNING, + "Creation of stream output type '%s' " + "failed!", + type); return false; } obs_output_release(streamOutput); streamDelayStarting.Connect( - obs_output_get_signal_handler(streamOutput), - "starting", OBSStreamStarting, this); + obs_output_get_signal_handler(streamOutput), "starting", + OBSStreamStarting, this); streamStopping.Connect( - obs_output_get_signal_handler(streamOutput), - "stopping", OBSStreamStopping, this); + obs_output_get_signal_handler(streamOutput), "stopping", + OBSStreamStopping, this); startStreaming.Connect( - obs_output_get_signal_handler(streamOutput), - "start", OBSStartStreaming, this); + obs_output_get_signal_handler(streamOutput), "start", + OBSStartStreaming, this); stopStreaming.Connect( - obs_output_get_signal_handler(streamOutput), - "stop", OBSStopStreaming, this); + obs_output_get_signal_handler(streamOutput), "stop", + OBSStopStreaming, this); - bool isEncoded = obs_output_get_flags(streamOutput) - & OBS_OUTPUT_ENCODED; + bool isEncoded = obs_output_get_flags(streamOutput) & + OBS_OUTPUT_ENCODED; if (isEncoded) { const char *codec = obs_output_get_supported_audio_codecs( - streamOutput); + streamOutput); if (!codec) { blog(LOG_WARNING, "Failed to load audio codec"); return false; } if (strcmp(codec, "aac") != 0) { - const char *id = FindAudioEncoderFromCodec( - codec); + const char *id = + FindAudioEncoderFromCodec(codec); int audioBitrate = GetAudioBitrate(); obs_data_t *settings = obs_data_create(); obs_data_set_int(settings, "bitrate", - audioBitrate); + audioBitrate); - aacStreaming = obs_audio_encoder_create(id, - "alt_audio_enc", nullptr, 0, - nullptr); + aacStreaming = obs_audio_encoder_create( + id, "alt_audio_enc", nullptr, 0, + nullptr); obs_encoder_release(aacStreaming); if (!aacStreaming) return false; obs_encoder_update(aacStreaming, settings); obs_encoder_set_audio(aacStreaming, - obs_get_audio()); + obs_get_audio()); obs_data_release(settings); } @@ -763,31 +768,32 @@ bool SimpleOutput::StartStreaming(obs_service_t *service) /* --------------------- */ - bool reconnect = config_get_bool(main->Config(), "Output", - "Reconnect"); - int retryDelay = config_get_uint(main->Config(), "Output", - "RetryDelay"); - int maxRetries = config_get_uint(main->Config(), "Output", - "MaxRetries"); - bool useDelay = config_get_bool(main->Config(), "Output", - "DelayEnable"); - int delaySec = config_get_int(main->Config(), "Output", - "DelaySec"); - bool preserveDelay = config_get_bool(main->Config(), "Output", - "DelayPreserve"); - const char *bindIP = config_get_string(main->Config(), "Output", - "BindIP"); + bool reconnect = config_get_bool(main->Config(), "Output", "Reconnect"); + int retryDelay = + config_get_uint(main->Config(), "Output", "RetryDelay"); + int maxRetries = + config_get_uint(main->Config(), "Output", "MaxRetries"); + bool useDelay = + config_get_bool(main->Config(), "Output", "DelayEnable"); + int delaySec = config_get_int(main->Config(), "Output", "DelaySec"); + bool preserveDelay = + config_get_bool(main->Config(), "Output", "DelayPreserve"); + const char *bindIP = + config_get_string(main->Config(), "Output", "BindIP"); bool enableNewSocketLoop = config_get_bool(main->Config(), "Output", - "NewSocketLoopEnable"); - bool enableLowLatencyMode = config_get_bool(main->Config(), "Output", - "LowLatencyEnable"); + "NewSocketLoopEnable"); + bool enableLowLatencyMode = + config_get_bool(main->Config(), "Output", "LowLatencyEnable"); + bool enableDynBitrate = + config_get_bool(main->Config(), "Output", "DynamicBitrate"); obs_data_t *settings = obs_data_create(); obs_data_set_string(settings, "bind_ip", bindIP); obs_data_set_bool(settings, "new_socket_loop_enabled", - enableNewSocketLoop); + enableNewSocketLoop); obs_data_set_bool(settings, "low_latency_mode_enabled", - enableLowLatencyMode); + enableLowLatencyMode); + obs_data_set_bool(settings, "dyn_bitrate", enableDynBitrate); obs_output_update(streamOutput, settings); obs_data_release(settings); @@ -795,10 +801,9 @@ bool SimpleOutput::StartStreaming(obs_service_t *service) maxRetries = 0; obs_output_set_delay(streamOutput, useDelay ? delaySec : 0, - preserveDelay ? OBS_OUTPUT_DELAY_PRESERVE : 0); + preserveDelay ? OBS_OUTPUT_DELAY_PRESERVE : 0); - obs_output_set_reconnect_settings(streamOutput, maxRetries, - retryDelay); + obs_output_set_reconnect_settings(streamOutput, maxRetries, retryDelay); if (obs_output_start(streamOutput)) { return true; @@ -812,8 +817,7 @@ bool SimpleOutput::StartStreaming(obs_service_t *service) lastError = string(); blog(LOG_WARNING, "Stream output type '%s' failed to start!%s%s", type, - hasLastError ? " Last Error: " : "", - hasLastError ? error : ""); + hasLastError ? " Last Error: " : "", hasLastError ? error : ""); return false; } @@ -871,37 +875,37 @@ void SimpleOutput::UpdateRecording() bool SimpleOutput::ConfigureRecording(bool updateReplayBuffer) { - const char *path = config_get_string(main->Config(), - "SimpleOutput", "FilePath"); - const char *format = config_get_string(main->Config(), - "SimpleOutput", "RecFormat"); + const char *path = + config_get_string(main->Config(), "SimpleOutput", "FilePath"); + const char *format = + config_get_string(main->Config(), "SimpleOutput", "RecFormat"); const char *mux = config_get_string(main->Config(), "SimpleOutput", - "MuxerCustom"); + "MuxerCustom"); bool noSpace = config_get_bool(main->Config(), "SimpleOutput", - "FileNameWithoutSpace"); + "FileNameWithoutSpace"); const char *filenameFormat = config_get_string(main->Config(), "Output", - "FilenameFormatting"); - bool overwriteIfExists = config_get_bool(main->Config(), "Output", - "OverwriteIfExists"); + "FilenameFormatting"); + bool overwriteIfExists = + config_get_bool(main->Config(), "Output", "OverwriteIfExists"); const char *rbPrefix = config_get_string(main->Config(), "SimpleOutput", - "RecRBPrefix"); + "RecRBPrefix"); const char *rbSuffix = config_get_string(main->Config(), "SimpleOutput", - "RecRBSuffix"); - int rbTime = config_get_int(main->Config(), "SimpleOutput", - "RecRBTime"); - int rbSize = config_get_int(main->Config(), "SimpleOutput", - "RecRBSize"); + "RecRBSuffix"); + int rbTime = + config_get_int(main->Config(), "SimpleOutput", "RecRBTime"); + int rbSize = + config_get_int(main->Config(), "SimpleOutput", "RecRBSize"); os_dir_t *dir = path && path[0] ? os_opendir(path) : nullptr; if (!dir) { if (main->isVisible()) OBSMessageBox::warning(main, - QTStr("Output.BadPath.Title"), - QTStr("Output.BadPath.Text")); + QTStr("Output.BadPath.Title"), + QTStr("Output.BadPath.Text")); else main->SysTrayNotify(QTStr("Output.BadPath.Text"), - QSystemTrayIcon::Warning); + QSystemTrayIcon::Warning); return false; } @@ -915,7 +919,7 @@ bool SimpleOutput::ConfigureRecording(bool updateReplayBuffer) strPath += "/"; strPath += GenerateSpecifiedFilename(ffmpegOutput ? "avi" : format, - noSpace, filenameFormat); + noSpace, filenameFormat); ensure_directory_exists(strPath); if (!overwriteIfExists) FindBestFilename(strPath, noSpace); @@ -946,10 +950,10 @@ bool SimpleOutput::ConfigureRecording(bool updateReplayBuffer) obs_data_set_bool(settings, "allow_spaces", !noSpace); obs_data_set_int(settings, "max_time_sec", rbTime); obs_data_set_int(settings, "max_size_mb", - usingRecordingPreset ? rbSize : 0); + usingRecordingPreset ? rbSize : 0); } else { obs_data_set_string(settings, ffmpegOutput ? "url" : "path", - strPath.c_str()); + strPath.c_str()); } obs_data_set_string(settings, "muxer_settings", mux); @@ -968,7 +972,7 @@ bool SimpleOutput::StartRecording() UpdateRecording(); if (!ConfigureRecording(false)) return false; - if (!obs_output_start(fileOutput)) { + if (!obs_output_start(fileOutput)) { QString error_reason; const char *error = obs_output_get_last_error(fileOutput); if (error) @@ -976,8 +980,8 @@ bool SimpleOutput::StartRecording() else error_reason = QTStr("Output.StartFailedGeneric"); QMessageBox::critical(main, - QTStr("Output.StartRecordingFailed"), - error_reason); + QTStr("Output.StartRecordingFailed"), + error_reason); return false; } @@ -990,9 +994,8 @@ bool SimpleOutput::StartReplayBuffer() if (!ConfigureRecording(true)) return false; if (!obs_output_start(replayBuffer)) { - QMessageBox::critical(main, - QTStr("Output.StartReplayFailed"), - QTStr("Output.StartFailedGeneric")); + QMessageBox::critical(main, QTStr("Output.StartReplayFailed"), + QTStr("Output.StartFailedGeneric")); return false; } @@ -1041,18 +1044,17 @@ bool SimpleOutput::ReplayBufferActive() const /* ------------------------------------------------------------------------ */ struct AdvancedOutput : BasicOutputHandler { - OBSEncoder aacTrack[MAX_AUDIO_MIXES]; - OBSEncoder h264Streaming; - OBSEncoder h264Recording; + OBSEncoder streamAudioEnc; + OBSEncoder aacTrack[MAX_AUDIO_MIXES]; + OBSEncoder h264Streaming; + OBSEncoder h264Recording; - OBSEncoder streamAudioEnc; + bool ffmpegOutput; + bool ffmpegRecording; + bool useStreamEncoder; + bool usesBitrate = false; - bool ffmpegOutput; - bool ffmpegRecording; - bool useStreamEncoder; - bool usesBitrate = false; - - string aacEncoderID[MAX_AUDIO_MIXES]; + string aacEncoderID[MAX_AUDIO_MIXES]; AdvancedOutput(OBSBasic *main_); @@ -1099,7 +1101,7 @@ static OBSData GetDataFromJsonFile(const char *jsonFile) } static void ApplyEncoderDefaults(OBSData &settings, - const obs_encoder_t *encoder) + const obs_encoder_t *encoder) { OBSData dataRet = obs_encoder_get_defaults(encoder); obs_data_release(dataRet); @@ -1111,15 +1113,16 @@ static void ApplyEncoderDefaults(OBSData &settings, AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_) { - const char *recType = config_get_string(main->Config(), "AdvOut", - "RecType"); - const char *streamEncoder = config_get_string(main->Config(), "AdvOut", - "Encoder"); - const char *recordEncoder = config_get_string(main->Config(), "AdvOut", - "RecEncoder"); + const char *recType = + config_get_string(main->Config(), "AdvOut", "RecType"); + const char *streamEncoder = + config_get_string(main->Config(), "AdvOut", "Encoder"); + const char *recordEncoder = + config_get_string(main->Config(), "AdvOut", "RecEncoder"); ffmpegOutput = astrcmpi(recType, "FFmpeg") == 0; - ffmpegRecording = ffmpegOutput && + ffmpegRecording = + ffmpegOutput && config_get_bool(main->Config(), "AdvOut", "FFOutputToFile"); useStreamEncoder = astrcmpi(recordEncoder, "none") == 0; @@ -1127,60 +1130,61 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_) OBSData recordEncSettings = GetDataFromJsonFile("recordEncoder.json"); const char *rate_control = obs_data_get_string( - useStreamEncoder ? streamEncSettings : recordEncSettings, - "rate_control"); + useStreamEncoder ? streamEncSettings : recordEncSettings, + "rate_control"); if (!rate_control) rate_control = ""; usesBitrate = astrcmpi(rate_control, "CBR") == 0 || - astrcmpi(rate_control, "VBR") == 0 || - astrcmpi(rate_control, "ABR") == 0; + astrcmpi(rate_control, "VBR") == 0 || + astrcmpi(rate_control, "ABR") == 0; if (ffmpegOutput) { - fileOutput = obs_output_create("ffmpeg_output", - "adv_ffmpeg_output", nullptr, nullptr); + fileOutput = obs_output_create( + "ffmpeg_output", "adv_ffmpeg_output", nullptr, nullptr); if (!fileOutput) throw "Failed to create recording FFmpeg output " "(advanced output)"; obs_output_release(fileOutput); } else { - bool useReplayBuffer = config_get_bool(main->Config(), - "AdvOut", "RecRB"); + bool useReplayBuffer = + config_get_bool(main->Config(), "AdvOut", "RecRB"); if (useReplayBuffer) { - const char *str = config_get_string(main->Config(), - "Hotkeys", "ReplayBuffer"); + const char *str = config_get_string( + main->Config(), "Hotkeys", "ReplayBuffer"); obs_data_t *hotkey = obs_data_create_from_json(str); replayBuffer = obs_output_create("replay_buffer", - Str("ReplayBuffer"), nullptr, hotkey); + Str("ReplayBuffer"), + nullptr, hotkey); obs_data_release(hotkey); if (!replayBuffer) throw "Failed to create replay buffer output " - "(simple output)"; + "(simple output)"; obs_output_release(replayBuffer); signal_handler_t *signal = - obs_output_get_signal_handler( - replayBuffer); + obs_output_get_signal_handler(replayBuffer); startReplayBuffer.Connect(signal, "start", - OBSStartReplayBuffer, this); + OBSStartReplayBuffer, this); stopReplayBuffer.Connect(signal, "stop", - OBSStopReplayBuffer, this); + OBSStopReplayBuffer, this); replayBufferStopping.Connect(signal, "stopping", - OBSReplayBufferStopping, this); + OBSReplayBufferStopping, + this); } - fileOutput = obs_output_create("ffmpeg_muxer", - "adv_file_output", nullptr, nullptr); + fileOutput = obs_output_create( + "ffmpeg_muxer", "adv_file_output", nullptr, nullptr); if (!fileOutput) throw "Failed to create recording output " "(advanced output)"; obs_output_release(fileOutput); if (!useStreamEncoder) { - h264Recording = obs_video_encoder_create(recordEncoder, - "recording_h264", recordEncSettings, - nullptr); + h264Recording = obs_video_encoder_create( + recordEncoder, "recording_h264", + recordEncSettings, nullptr); if (!h264Recording) throw "Failed to create recording h264 " "encoder (advanced output)"; @@ -1188,8 +1192,8 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_) } } - h264Streaming = obs_video_encoder_create(streamEncoder, - "streaming_h264", streamEncSettings, nullptr); + h264Streaming = obs_video_encoder_create( + streamEncoder, "streaming_h264", streamEncSettings, nullptr); if (!h264Streaming) throw "Failed to create streaming h264 encoder " "(advanced output)"; @@ -1200,37 +1204,52 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_) sprintf(name, "adv_aac%d", i); if (!CreateAACEncoder(aacTrack[i], aacEncoderID[i], - GetAudioBitrate(i), name, i)) + GetAudioBitrate(i), name, i)) throw "Failed to create audio encoder " "(advanced output)"; } + std::string id; + int streamTrack = + config_get_int(main->Config(), "AdvOut", "TrackIndex") - 1; + if (!CreateAACEncoder(streamAudioEnc, id, GetAudioBitrate(streamTrack), + "avc_aac_stream", streamTrack)) + throw "Failed to create streaming audio encoder " + "(advanced output)"; + startRecording.Connect(obs_output_get_signal_handler(fileOutput), - "start", OBSStartRecording, this); - stopRecording.Connect(obs_output_get_signal_handler(fileOutput), - "stop", OBSStopRecording, this); + "start", OBSStartRecording, this); + stopRecording.Connect(obs_output_get_signal_handler(fileOutput), "stop", + OBSStopRecording, this); recordStopping.Connect(obs_output_get_signal_handler(fileOutput), - "stopping", OBSRecordStopping, this); + "stopping", OBSRecordStopping, this); } void AdvancedOutput::UpdateStreamSettings() { bool applyServiceSettings = config_get_bool(main->Config(), "AdvOut", - "ApplyServiceSettings"); + "ApplyServiceSettings"); + bool dynBitrate = + config_get_bool(main->Config(), "Output", "DynamicBitrate"); + const char *streamEncoder = + config_get_string(main->Config(), "AdvOut", "Encoder"); OBSData settings = GetDataFromJsonFile("streamEncoder.json"); ApplyEncoderDefaults(settings, h264Streaming); if (applyServiceSettings) - obs_service_apply_encoder_settings(main->GetService(), - settings, nullptr); + obs_service_apply_encoder_settings(main->GetService(), settings, + nullptr); + + if (dynBitrate && astrcmpi(streamEncoder, "jim_nvenc") == 0) + obs_data_set_bool(settings, "lookahead", false); video_t *video = obs_get_video(); enum video_format format = video_output_get_format(video); if (format != VIDEO_FORMAT_NV12 && format != VIDEO_FORMAT_I420) obs_encoder_set_preferred_video_format(h264Streaming, - VIDEO_FORMAT_NV12); + VIDEO_FORMAT_NV12); obs_encoder_update(h264Streaming, settings); } @@ -1251,10 +1270,11 @@ void AdvancedOutput::Update() inline void AdvancedOutput::SetupStreaming() { - bool rescale = config_get_bool(main->Config(), "AdvOut", - "Rescale"); - const char *rescaleRes = config_get_string(main->Config(), "AdvOut", - "RescaleRes"); + bool rescale = config_get_bool(main->Config(), "AdvOut", "Rescale"); + const char *rescaleRes = + config_get_string(main->Config(), "AdvOut", "RescaleRes"); + int streamTrack = + config_get_int(main->Config(), "AdvOut", "TrackIndex") - 1; uint32_t caps = obs_encoder_get_caps(h264Streaming); unsigned int cx = 0; unsigned int cy = 0; @@ -1270,31 +1290,34 @@ inline void AdvancedOutput::SetupStreaming() } } + obs_output_set_audio_encoder(streamOutput, streamAudioEnc, streamTrack); obs_encoder_set_scaled_size(h264Streaming, cx, cy); obs_encoder_set_video(h264Streaming, obs_get_video()); } inline void AdvancedOutput::SetupRecording() { - const char *path = config_get_string(main->Config(), "AdvOut", - "RecFilePath"); - const char *mux = config_get_string(main->Config(), "AdvOut", - "RecMuxerCustom"); - bool rescale = config_get_bool(main->Config(), "AdvOut", - "RecRescale"); - const char *rescaleRes = config_get_string(main->Config(), "AdvOut", - "RecRescaleRes"); + const char *path = + config_get_string(main->Config(), "AdvOut", "RecFilePath"); + const char *mux = + config_get_string(main->Config(), "AdvOut", "RecMuxerCustom"); + bool rescale = config_get_bool(main->Config(), "AdvOut", "RecRescale"); + const char *rescaleRes = + config_get_string(main->Config(), "AdvOut", "RecRescaleRes"); int tracks = config_get_int(main->Config(), "AdvOut", "RecTracks"); obs_data_t *settings = obs_data_create(); unsigned int cx = 0; unsigned int cy = 0; int idx = 0; + if (tracks == 0) + tracks = config_get_int(main->Config(), "AdvOut", "TrackIndex"); + if (useStreamEncoder) { obs_output_set_video_encoder(fileOutput, h264Streaming); if (replayBuffer) obs_output_set_video_encoder(replayBuffer, - h264Streaming); + h264Streaming); } else { uint32_t caps = obs_encoder_get_caps(h264Recording); if ((caps & OBS_ENCODER_CAP_PASS_TEXTURE) != 0) { @@ -1313,16 +1336,16 @@ inline void AdvancedOutput::SetupRecording() obs_output_set_video_encoder(fileOutput, h264Recording); if (replayBuffer) obs_output_set_video_encoder(replayBuffer, - h264Recording); + h264Recording); } for (int i = 0; i < MAX_AUDIO_MIXES; i++) { - if ((tracks & (1<Config(), "AdvOut", "FFURL"); - int vBitrate = config_get_int(main->Config(), "AdvOut", - "FFVBitrate"); - int gopSize = config_get_int(main->Config(), "AdvOut", - "FFVGOPSize"); - bool rescale = config_get_bool(main->Config(), "AdvOut", - "FFRescale"); - const char *rescaleRes = config_get_string(main->Config(), "AdvOut", - "FFRescaleRes"); - const char *formatName = config_get_string(main->Config(), "AdvOut", - "FFFormat"); - const char *mimeType = config_get_string(main->Config(), "AdvOut", - "FFFormatMimeType"); - const char *muxCustom = config_get_string(main->Config(), "AdvOut", - "FFMCustom"); - const char *vEncoder = config_get_string(main->Config(), "AdvOut", - "FFVEncoder"); - int vEncoderId = config_get_int(main->Config(), "AdvOut", - "FFVEncoderId"); - const char *vEncCustom = config_get_string(main->Config(), "AdvOut", - "FFVCustom"); - int aBitrate = config_get_int(main->Config(), "AdvOut", - "FFABitrate"); - int aMixes = config_get_int(main->Config(), "AdvOut", - "FFAudioMixes"); - const char *aEncoder = config_get_string(main->Config(), "AdvOut", - "FFAEncoder"); - int aEncoderId = config_get_int(main->Config(), "AdvOut", - "FFAEncoderId"); - const char *aEncCustom = config_get_string(main->Config(), "AdvOut", - "FFACustom"); + int vBitrate = config_get_int(main->Config(), "AdvOut", "FFVBitrate"); + int gopSize = config_get_int(main->Config(), "AdvOut", "FFVGOPSize"); + bool rescale = config_get_bool(main->Config(), "AdvOut", "FFRescale"); + const char *rescaleRes = + config_get_string(main->Config(), "AdvOut", "FFRescaleRes"); + const char *formatName = + config_get_string(main->Config(), "AdvOut", "FFFormat"); + const char *mimeType = + config_get_string(main->Config(), "AdvOut", "FFFormatMimeType"); + const char *muxCustom = + config_get_string(main->Config(), "AdvOut", "FFMCustom"); + const char *vEncoder = + config_get_string(main->Config(), "AdvOut", "FFVEncoder"); + int vEncoderId = + config_get_int(main->Config(), "AdvOut", "FFVEncoderId"); + const char *vEncCustom = + config_get_string(main->Config(), "AdvOut", "FFVCustom"); + int aBitrate = config_get_int(main->Config(), "AdvOut", "FFABitrate"); + int aMixes = config_get_int(main->Config(), "AdvOut", "FFAudioMixes"); + const char *aEncoder = + config_get_string(main->Config(), "AdvOut", "FFAEncoder"); + int aEncoderId = + config_get_int(main->Config(), "AdvOut", "FFAEncoderId"); + const char *aEncCustom = + config_get_string(main->Config(), "AdvOut", "FFACustom"); obs_data_t *settings = obs_data_create(); obs_data_set_string(settings, "url", url); @@ -1403,7 +1421,7 @@ inline void AdvancedOutput::SetupFFmpeg() } static inline void SetEncoderName(obs_encoder_t *encoder, const char *name, - const char *defaultName) + const char *defaultName) { obs_encoder_set_name(encoder, (name && *name) ? name : defaultName); } @@ -1411,9 +1429,9 @@ static inline void SetEncoderName(obs_encoder_t *encoder, const char *name, inline void AdvancedOutput::UpdateAudioSettings() { bool applyServiceSettings = config_get_bool(main->Config(), "AdvOut", - "ApplyServiceSettings"); - int streamTrackIndex = config_get_int(main->Config(), "AdvOut", - "TrackIndex"); + "ApplyServiceSettings"); + int streamTrackIndex = + config_get_int(main->Config(), "AdvOut", "TrackIndex"); obs_data_t *settings[MAX_AUDIO_MIXES]; for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { @@ -1426,7 +1444,7 @@ inline void AdvancedOutput::UpdateAudioSettings() cfg_name += to_string((int)i + 1); cfg_name += "Name"; const char *name = config_get_string(main->Config(), "AdvOut", - cfg_name.c_str()); + cfg_name.c_str()); string def_name = "Track"; def_name += to_string((int)i + 1); @@ -1434,11 +1452,18 @@ inline void AdvancedOutput::UpdateAudioSettings() } for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { - if (applyServiceSettings && (int)(i + 1) == streamTrackIndex) - obs_service_apply_encoder_settings(main->GetService(), - nullptr, settings[i]); - obs_encoder_update(aacTrack[i], settings[i]); + + if ((int)(i + 1) == streamTrackIndex) { + if (applyServiceSettings) { + obs_service_apply_encoder_settings( + main->GetService(), nullptr, + settings[i]); + } + + obs_encoder_update(streamAudioEnc, settings[i]); + } + obs_data_release(settings[i]); } } @@ -1450,6 +1475,7 @@ void AdvancedOutput::SetupOutputs() obs_encoder_set_video(h264Recording, obs_get_video()); for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) obs_encoder_set_audio(aacTrack[i], obs_get_audio()); + obs_encoder_set_audio(streamAudioEnc, obs_get_audio()); SetupStreaming(); @@ -1462,9 +1488,8 @@ void AdvancedOutput::SetupOutputs() int AdvancedOutput::GetAudioBitrate(size_t i) const { static const char *names[] = { - "Track1Bitrate", "Track2Bitrate", - "Track3Bitrate", "Track4Bitrate", - "Track5Bitrate", "Track6Bitrate", + "Track1Bitrate", "Track2Bitrate", "Track3Bitrate", + "Track4Bitrate", "Track5Bitrate", "Track6Bitrate", }; int bitrate = (int)config_get_uint(main->Config(), "AdvOut", names[i]); return FindClosestAvailableAACBitrate(bitrate); @@ -1472,6 +1497,9 @@ int AdvancedOutput::GetAudioBitrate(size_t i) const bool AdvancedOutput::StartStreaming(obs_service_t *service) { + int streamTrack = + config_get_int(main->Config(), "AdvOut", "TrackIndex") - 1; + if (!useStreamEncoder || (!ffmpegOutput && !obs_output_active(fileOutput))) { UpdateStreamSettings(); @@ -1488,9 +1516,6 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service) /* --------------------- */ - int trackIndex = config_get_int(main->Config(), "AdvOut", - "TrackIndex"); - const char *type = obs_service_get_output_type(service); if (!type) type = "rtmp_output"; @@ -1502,64 +1527,62 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service) startStreaming.Disconnect(); stopStreaming.Disconnect(); - streamOutput = obs_output_create(type, "adv_stream", - nullptr, nullptr); + streamOutput = + obs_output_create(type, "adv_stream", nullptr, nullptr); if (!streamOutput) { - blog(LOG_WARNING, "Creation of stream output type '%s' " - "failed!", type); + blog(LOG_WARNING, + "Creation of stream output type '%s' " + "failed!", + type); return false; } obs_output_release(streamOutput); streamDelayStarting.Connect( - obs_output_get_signal_handler(streamOutput), - "starting", OBSStreamStarting, this); + obs_output_get_signal_handler(streamOutput), "starting", + OBSStreamStarting, this); streamStopping.Connect( - obs_output_get_signal_handler(streamOutput), - "stopping", OBSStreamStopping, this); + obs_output_get_signal_handler(streamOutput), "stopping", + OBSStreamStopping, this); startStreaming.Connect( - obs_output_get_signal_handler(streamOutput), - "start", OBSStartStreaming, this); + obs_output_get_signal_handler(streamOutput), "start", + OBSStartStreaming, this); stopStreaming.Connect( - obs_output_get_signal_handler(streamOutput), - "stop", OBSStopStreaming, this); + obs_output_get_signal_handler(streamOutput), "stop", + OBSStopStreaming, this); - bool isEncoded = obs_output_get_flags(streamOutput) - & OBS_OUTPUT_ENCODED; + bool isEncoded = obs_output_get_flags(streamOutput) & + OBS_OUTPUT_ENCODED; if (isEncoded) { const char *codec = obs_output_get_supported_audio_codecs( - streamOutput); + streamOutput); if (!codec) { blog(LOG_WARNING, "Failed to load audio codec"); return false; } - if (strcmp(codec, "aac") == 0) { - streamAudioEnc = aacTrack[trackIndex - 1]; - } else { - obs_data_t *settings = obs_data_create(); + if (strcmp(codec, "aac") != 0) { + OBSData settings = obs_encoder_get_settings( + streamAudioEnc); + obs_data_release(settings); + const char *id = FindAudioEncoderFromCodec(codec); - int audioBitrate = - GetAudioBitrate(trackIndex - 1); - - obs_data_set_int(settings, "bitrate", - audioBitrate); - streamAudioEnc = obs_audio_encoder_create(id, - "alt_audio_enc", nullptr, - trackIndex - 1, nullptr); + + streamAudioEnc = obs_audio_encoder_create( + id, "alt_audio_enc", nullptr, + streamTrack, nullptr); if (!streamAudioEnc) return false; + obs_encoder_release(streamAudioEnc); obs_encoder_update(streamAudioEnc, settings); obs_encoder_set_audio(streamAudioEnc, - obs_get_audio()); - - obs_data_release(settings); + obs_get_audio()); } } @@ -1576,25 +1599,27 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service) bool reconnect = config_get_bool(main->Config(), "Output", "Reconnect"); int retryDelay = config_get_int(main->Config(), "Output", "RetryDelay"); int maxRetries = config_get_int(main->Config(), "Output", "MaxRetries"); - bool useDelay = config_get_bool(main->Config(), "Output", - "DelayEnable"); - int delaySec = config_get_int(main->Config(), "Output", - "DelaySec"); - bool preserveDelay = config_get_bool(main->Config(), "Output", - "DelayPreserve"); - const char *bindIP = config_get_string(main->Config(), "Output", - "BindIP"); + bool useDelay = + config_get_bool(main->Config(), "Output", "DelayEnable"); + int delaySec = config_get_int(main->Config(), "Output", "DelaySec"); + bool preserveDelay = + config_get_bool(main->Config(), "Output", "DelayPreserve"); + const char *bindIP = + config_get_string(main->Config(), "Output", "BindIP"); bool enableNewSocketLoop = config_get_bool(main->Config(), "Output", - "NewSocketLoopEnable"); - bool enableLowLatencyMode = config_get_bool(main->Config(), "Output", - "LowLatencyEnable"); + "NewSocketLoopEnable"); + bool enableLowLatencyMode = + config_get_bool(main->Config(), "Output", "LowLatencyEnable"); + bool enableDynBitrate = + config_get_bool(main->Config(), "Output", "DynamicBitrate"); obs_data_t *settings = obs_data_create(); obs_data_set_string(settings, "bind_ip", bindIP); obs_data_set_bool(settings, "new_socket_loop_enabled", - enableNewSocketLoop); + enableNewSocketLoop); obs_data_set_bool(settings, "low_latency_mode_enabled", - enableLowLatencyMode); + enableLowLatencyMode); + obs_data_set_bool(settings, "dyn_bitrate", enableDynBitrate); obs_output_update(streamOutput, settings); obs_data_release(settings); @@ -1602,10 +1627,9 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service) maxRetries = 0; obs_output_set_delay(streamOutput, useDelay ? delaySec : 0, - preserveDelay ? OBS_OUTPUT_DELAY_PRESERVE : 0); + preserveDelay ? OBS_OUTPUT_DELAY_PRESERVE : 0); - obs_output_set_reconnect_settings(streamOutput, maxRetries, - retryDelay); + obs_output_set_reconnect_settings(streamOutput, maxRetries, retryDelay); if (obs_output_start(streamOutput)) { return true; @@ -1619,8 +1643,7 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service) lastError = string(); blog(LOG_WARNING, "Stream output type '%s' failed to start!%s%s", type, - hasLastError ? " Last Error: " : "", - hasLastError ? error : ""); + hasLastError ? " Last Error: " : "", hasLastError ? error : ""); return false; } @@ -1647,28 +1670,31 @@ bool AdvancedOutput::StartRecording() if (!ffmpegOutput || ffmpegRecording) { path = config_get_string(main->Config(), "AdvOut", - ffmpegRecording ? "FFFilePath" : "RecFilePath"); + ffmpegRecording ? "FFFilePath" + : "RecFilePath"); recFormat = config_get_string(main->Config(), "AdvOut", - ffmpegRecording ? "FFExtension" : "RecFormat"); + ffmpegRecording ? "FFExtension" + : "RecFormat"); filenameFormat = config_get_string(main->Config(), "Output", - "FilenameFormatting"); + "FilenameFormatting"); overwriteIfExists = config_get_bool(main->Config(), "Output", - "OverwriteIfExists"); + "OverwriteIfExists"); noSpace = config_get_bool(main->Config(), "AdvOut", - ffmpegRecording ? - "FFFileNameWithoutSpace" : - "RecFileNameWithoutSpace"); + ffmpegRecording + ? "FFFileNameWithoutSpace" + : "RecFileNameWithoutSpace"); os_dir_t *dir = path && path[0] ? os_opendir(path) : nullptr; if (!dir) { if (main->isVisible()) - OBSMessageBox::warning(main, - QTStr("Output.BadPath.Title"), - QTStr("Output.BadPath.Text")); + OBSMessageBox::warning( + main, QTStr("Output.BadPath.Title"), + QTStr("Output.BadPath.Text")); else - main->SysTrayNotify(QTStr("Output.BadPath.Text"), - QSystemTrayIcon::Warning); + main->SysTrayNotify( + QTStr("Output.BadPath.Text"), + QSystemTrayIcon::Warning); return false; } @@ -1682,15 +1708,14 @@ bool AdvancedOutput::StartRecording() strPath += "/"; strPath += GenerateSpecifiedFilename(recFormat, noSpace, - filenameFormat); + filenameFormat); ensure_directory_exists(strPath); if (!overwriteIfExists) FindBestFilename(strPath, noSpace); obs_data_t *settings = obs_data_create(); - obs_data_set_string(settings, - ffmpegRecording ? "url" : "path", - strPath.c_str()); + obs_data_set_string(settings, ffmpegRecording ? "url" : "path", + strPath.c_str()); obs_output_update(fileOutput, settings); @@ -1705,8 +1730,8 @@ bool AdvancedOutput::StartRecording() else error_reason = QTStr("Output.StartFailedGeneric"); QMessageBox::critical(main, - QTStr("Output.StartRecordingFailed"), - error_reason); + QTStr("Output.StartRecordingFailed"), + error_reason); return false; } @@ -1739,36 +1764,37 @@ bool AdvancedOutput::StartReplayBuffer() if (!ffmpegOutput || ffmpegRecording) { path = config_get_string(main->Config(), "AdvOut", - ffmpegRecording ? "FFFilePath" : "RecFilePath"); + ffmpegRecording ? "FFFilePath" + : "RecFilePath"); recFormat = config_get_string(main->Config(), "AdvOut", - ffmpegRecording ? "FFExtension" : "RecFormat"); + ffmpegRecording ? "FFExtension" + : "RecFormat"); filenameFormat = config_get_string(main->Config(), "Output", - "FilenameFormatting"); + "FilenameFormatting"); overwriteIfExists = config_get_bool(main->Config(), "Output", - "OverwriteIfExists"); + "OverwriteIfExists"); noSpace = config_get_bool(main->Config(), "AdvOut", - ffmpegRecording ? - "FFFileNameWithoutSpace" : - "RecFileNameWithoutSpace"); + ffmpegRecording + ? "FFFileNameWithoutSpace" + : "RecFileNameWithoutSpace"); rbPrefix = config_get_string(main->Config(), "SimpleOutput", - "RecRBPrefix"); + "RecRBPrefix"); rbSuffix = config_get_string(main->Config(), "SimpleOutput", - "RecRBSuffix"); - rbTime = config_get_int(main->Config(), "AdvOut", - "RecRBTime"); - rbSize = config_get_int(main->Config(), "AdvOut", - "RecRBSize"); + "RecRBSuffix"); + rbTime = config_get_int(main->Config(), "AdvOut", "RecRBTime"); + rbSize = config_get_int(main->Config(), "AdvOut", "RecRBSize"); os_dir_t *dir = path && path[0] ? os_opendir(path) : nullptr; if (!dir) { if (main->isVisible()) - OBSMessageBox::warning(main, - QTStr("Output.BadPath.Title"), - QTStr("Output.BadPath.Text")); + OBSMessageBox::warning( + main, QTStr("Output.BadPath.Title"), + QTStr("Output.BadPath.Text")); else - main->SysTrayNotify(QTStr("Output.BadPath.Text"), - QSystemTrayIcon::Warning); + main->SysTrayNotify( + QTStr("Output.BadPath.Text"), + QSystemTrayIcon::Warning); return false; } @@ -1782,7 +1808,7 @@ bool AdvancedOutput::StartReplayBuffer() strPath += "/"; strPath += GenerateSpecifiedFilename(recFormat, noSpace, - filenameFormat); + filenameFormat); ensure_directory_exists(strPath); if (!overwriteIfExists) FindBestFilename(strPath, noSpace); @@ -1812,7 +1838,7 @@ bool AdvancedOutput::StartReplayBuffer() obs_data_set_bool(settings, "allow_spaces", !noSpace); obs_data_set_int(settings, "max_time_sec", rbTime); obs_data_set_int(settings, "max_size_mb", - usesBitrate ? 0 : rbSize); + usesBitrate ? 0 : rbSize); obs_output_update(replayBuffer, settings); @@ -1821,8 +1847,8 @@ bool AdvancedOutput::StartReplayBuffer() if (!obs_output_start(replayBuffer)) { QMessageBox::critical(main, - QTStr("Output.StartRecordingFailed"), - QTStr("Output.StartFailedGeneric")); + QTStr("Output.StartRecordingFailed"), + QTStr("Output.StartFailedGeneric")); return false; } diff --git a/UI/window-basic-main-outputs.hpp b/UI/window-basic-main-outputs.hpp index c053d0b..b5aae77 100644 --- a/UI/window-basic-main-outputs.hpp +++ b/UI/window-basic-main-outputs.hpp @@ -5,49 +5,49 @@ class OBSBasic; struct BasicOutputHandler { - OBSOutput fileOutput; - OBSOutput streamOutput; - OBSOutput replayBuffer; - bool streamingActive = false; - bool recordingActive = false; - bool delayActive = false; - bool replayBufferActive = false; - OBSBasic *main; + OBSOutput fileOutput; + OBSOutput streamOutput; + OBSOutput replayBuffer; + bool streamingActive = false; + bool recordingActive = false; + bool delayActive = false; + bool replayBufferActive = false; + OBSBasic *main; - std::string outputType; - std::string lastError; + std::string outputType; + std::string lastError; - OBSSignal startRecording; - OBSSignal stopRecording; - OBSSignal startReplayBuffer; - OBSSignal stopReplayBuffer; - OBSSignal startStreaming; - OBSSignal stopStreaming; - OBSSignal streamDelayStarting; - OBSSignal streamStopping; - OBSSignal recordStopping; - OBSSignal replayBufferStopping; + OBSSignal startRecording; + OBSSignal stopRecording; + OBSSignal startReplayBuffer; + OBSSignal stopReplayBuffer; + OBSSignal startStreaming; + OBSSignal stopStreaming; + OBSSignal streamDelayStarting; + OBSSignal streamStopping; + OBSSignal recordStopping; + OBSSignal replayBufferStopping; inline BasicOutputHandler(OBSBasic *main_) : main(main_) {} - virtual ~BasicOutputHandler() {}; + virtual ~BasicOutputHandler(){}; virtual bool StartStreaming(obs_service_t *service) = 0; virtual bool StartRecording() = 0; - virtual bool StartReplayBuffer() {return false;} + virtual bool StartReplayBuffer() { return false; } virtual void StopStreaming(bool force = false) = 0; virtual void StopRecording(bool force = false) = 0; - virtual void StopReplayBuffer(bool force = false) {(void)force;} + virtual void StopReplayBuffer(bool force = false) { (void)force; } virtual bool StreamingActive() const = 0; virtual bool RecordingActive() const = 0; - virtual bool ReplayBufferActive() const {return false;} + virtual bool ReplayBufferActive() const { return false; } virtual void Update() = 0; inline bool Active() const { return streamingActive || recordingActive || delayActive || - replayBufferActive; + replayBufferActive; } }; diff --git a/UI/window-basic-main-profiles.cpp b/UI/window-basic-main-profiles.cpp index aa512d5..c0d3fd8 100644 --- a/UI/window-basic-main-profiles.cpp +++ b/UI/window-basic-main-profiles.cpp @@ -30,13 +30,13 @@ extern void DuplicateCurrentCookieProfile(ConfigFile &config); extern void CheckExistingCookieId(); extern void DeleteCookies(); -void EnumProfiles(std::function &&cb) +void EnumProfiles(std::function &&cb) { char path[512]; os_glob_t *glob; int ret = GetConfigPath(path, sizeof(path), - "obs-studio/basic/profiles/*"); + "obs-studio/basic/profiles/*"); if (ret <= 0) { blog(LOG_WARNING, "Failed to get profiles config path"); return; @@ -54,8 +54,7 @@ void EnumProfiles(std::function &&cb) if (!glob->gl_pathv[i].directory) continue; - if (strcmp(dirName, ".") == 0 || - strcmp(dirName, "..") == 0) + if (strcmp(dirName, ".") == 0 || strcmp(dirName, "..") == 0) continue; std::string file = filePath; @@ -80,8 +79,7 @@ void EnumProfiles(std::function &&cb) static bool ProfileExists(const char *findName) { bool found = false; - auto func = [&](const char *name, const char*) - { + auto func = [&](const char *name, const char *) { if (strcmp(name, findName) == 0) { found = true; return false; @@ -94,28 +92,28 @@ static bool ProfileExists(const char *findName) } static bool GetProfileName(QWidget *parent, std::string &name, - std::string &file, const char *title, const char *text, - const char *oldName = nullptr) + std::string &file, const char *title, + const char *text, const char *oldName = nullptr) { char path[512]; int ret; for (;;) { - bool success = NameDialog::AskForName(parent, title, text, - name, QT_UTF8(oldName)); + bool success = NameDialog::AskForName(parent, title, text, name, + QT_UTF8(oldName)); if (!success) { return false; } if (name.empty()) { OBSMessageBox::warning(parent, - QTStr("NoNameEntered.Title"), - QTStr("NoNameEntered.Text")); + QTStr("NoNameEntered.Title"), + QTStr("NoNameEntered.Text")); continue; } if (ProfileExists(name.c_str())) { OBSMessageBox::warning(parent, - QTStr("NameExists.Title"), - QTStr("NameExists.Text")); + QTStr("NameExists.Title"), + QTStr("NameExists.Text")); continue; } break; @@ -123,7 +121,7 @@ static bool GetProfileName(QWidget *parent, std::string &name, if (!GetFileSafeName(name.c_str(), file)) { blog(LOG_WARNING, "Failed to create safe file name for '%s'", - name.c_str()); + name.c_str()); return false; } @@ -137,7 +135,7 @@ static bool GetProfileName(QWidget *parent, std::string &name, if (!GetClosestUnusedFileName(file, nullptr)) { blog(LOG_WARNING, "Failed to get closest file name for %s", - file.c_str()); + file.c_str()); return false; } @@ -170,13 +168,14 @@ static bool CopyProfile(const char *fromPartial, const char *to) if (glob->gl_pathv[i].directory) continue; - ret = snprintf(path, sizeof(path), "%s/%s", - to, strrchr(filePath, '/') + 1); + ret = snprintf(path, sizeof(path), "%s/%s", to, + strrchr(filePath, '/') + 1); if (ret > 0) { if (os_copyfile(filePath, path) != 0) { - blog(LOG_WARNING, "CopyProfile: Failed to " - "copy file %s to %s", - filePath, path); + blog(LOG_WARNING, + "CopyProfile: Failed to " + "copy file %s to %s", + filePath, path); } } } @@ -187,7 +186,7 @@ static bool CopyProfile(const char *fromPartial, const char *to) } bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text, - const char *init_text, bool rename) + const char *init_text, bool rename) { std::string newName; std::string newDir; @@ -197,12 +196,12 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text, if (!GetProfileName(this, newName, newDir, title, text, init_text)) return false; - std::string curDir = config_get_string(App()->GlobalConfig(), - "Basic", "ProfileDir"); + std::string curDir = + config_get_string(App()->GlobalConfig(), "Basic", "ProfileDir"); char baseDir[512]; int ret = GetConfigPath(baseDir, sizeof(baseDir), - "obs-studio/basic/profiles/"); + "obs-studio/basic/profiles/"); if (ret <= 0) { blog(LOG_WARNING, "Failed to get profiles config path"); return false; @@ -213,7 +212,7 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text, if (os_mkdir(newPath.c_str()) < 0) { blog(LOG_WARNING, "Failed to create profile directory '%s'", - newDir.c_str()); + newDir.c_str()); return false; } @@ -224,14 +223,14 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text, if (config.Open(newPath.c_str(), CONFIG_OPEN_ALWAYS) != 0) { blog(LOG_ERROR, "Failed to open new config file '%s'", - newDir.c_str()); + newDir.c_str()); return false; } config_set_string(App()->GlobalConfig(), "Basic", "Profile", - newName.c_str()); + newName.c_str()); config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", - newDir.c_str()); + newDir.c_str()); Auth::Save(); if (create_new) { @@ -253,7 +252,7 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text, ResetProfileData(); blog(LOG_INFO, "Created profile '%s' (%s, %s)", newName.c_str(), - create_new ? "clean" : "duplicate", newDir.c_str()); + create_new ? "clean" : "duplicate", newDir.c_str()); blog(LOG_INFO, "------------------------------------------------"); config_save_safe(App()->GlobalConfig(), "tmp", nullptr); @@ -280,14 +279,14 @@ void OBSBasic::DeleteProfile(const char *profileName, const char *profileDir) ret = snprintf(profilePath, 512, "%s/%s/*", basePath, profileDir); if (ret <= 0) { blog(LOG_WARNING, "Failed to get path for profile dir '%s'", - profileDir); + profileDir); return; } os_glob_t *glob; if (os_glob(profilePath, 0, &glob) != 0) { blog(LOG_WARNING, "Failed to glob profile dir '%s'", - profileDir); + profileDir); return; } @@ -305,21 +304,20 @@ void OBSBasic::DeleteProfile(const char *profileName, const char *profileDir) ret = snprintf(profilePath, 512, "%s/%s", basePath, profileDir); if (ret <= 0) { blog(LOG_WARNING, "Failed to get path for profile dir '%s'", - profileDir); + profileDir); return; } os_rmdir(profilePath); blog(LOG_INFO, "------------------------------------------------"); - blog(LOG_INFO, "Removed profile '%s' (%s)", - profileName, profileDir); + blog(LOG_INFO, "Removed profile '%s' (%s)", profileName, profileDir); blog(LOG_INFO, "------------------------------------------------"); } void OBSBasic::RefreshProfiles() { - QList menuActions = ui->profileMenu->actions(); + QList menuActions = ui->profileMenu->actions(); int count = 0; for (int i = 0; i < menuActions.count(); i++) { @@ -328,17 +326,16 @@ void OBSBasic::RefreshProfiles() delete menuActions[i]; } - const char *curName = config_get_string(App()->GlobalConfig(), - "Basic", "Profile"); + const char *curName = + config_get_string(App()->GlobalConfig(), "Basic", "Profile"); - auto addProfile = [&](const char *name, const char *path) - { + auto addProfile = [&](const char *name, const char *path) { std::string file = strrchr(path, '/') + 1; QAction *action = new QAction(QT_UTF8(name), this); action->setProperty("file_name", QT_UTF8(path)); - connect(action, &QAction::triggered, - this, &OBSBasic::ChangeProfile); + connect(action, &QAction::triggered, this, + &OBSBasic::ChangeProfile); action->setCheckable(true); action->setChecked(strcmp(name, curName) == 0); @@ -364,15 +361,15 @@ void OBSBasic::ResetProfileData() /* load audio monitoring */ #if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO - const char *device_name = config_get_string(basicConfig, "Audio", - "MonitoringDeviceName"); - const char *device_id = config_get_string(basicConfig, "Audio", - "MonitoringDeviceId"); + const char *device_name = + config_get_string(basicConfig, "Audio", "MonitoringDeviceName"); + const char *device_id = + config_get_string(basicConfig, "Audio", "MonitoringDeviceId"); obs_set_audio_monitoring_device(device_name, device_id); blog(LOG_INFO, "Audio monitoring device:\n\tname: %s\n\tid: %s", - device_name, device_id); + device_name, device_id); #endif } @@ -388,14 +385,15 @@ void OBSBasic::on_actionDupProfile_triggered() void OBSBasic::on_actionRenameProfile_triggered() { - std::string curDir = config_get_string(App()->GlobalConfig(), - "Basic", "ProfileDir"); - std::string curName = config_get_string(App()->GlobalConfig(), - "Basic", "Profile"); + std::string curDir = + config_get_string(App()->GlobalConfig(), "Basic", "ProfileDir"); + std::string curName = + config_get_string(App()->GlobalConfig(), "Basic", "Profile"); /* Duplicate and delete in case there are any issues in the process */ bool success = AddProfile(false, Str("RenameProfile.Title"), - Str("AddProfile.Text"), curName.c_str(), true); + Str("AddProfile.Text"), curName.c_str(), + true); if (success) { DeleteProfile(curName.c_str(), curDir.c_str()); RefreshProfiles(); @@ -413,13 +411,12 @@ void OBSBasic::on_actionRemoveProfile_triggered() std::string newPath; ConfigFile config; - std::string oldDir = config_get_string(App()->GlobalConfig(), - "Basic", "ProfileDir"); - std::string oldName = config_get_string(App()->GlobalConfig(), - "Basic", "Profile"); + std::string oldDir = + config_get_string(App()->GlobalConfig(), "Basic", "ProfileDir"); + std::string oldName = + config_get_string(App()->GlobalConfig(), "Basic", "Profile"); - auto cb = [&](const char *name, const char *filePath) - { + auto cb = [&](const char *name, const char *filePath) { if (strcmp(oldName.c_str(), name) != 0) { newName = name; newPath = filePath; @@ -438,8 +435,8 @@ void OBSBasic::on_actionRemoveProfile_triggered() QString text = QTStr("ConfirmRemove.Text"); text.replace("$1", QT_UTF8(oldName.c_str())); - QMessageBox::StandardButton button = OBSMessageBox::question(this, - QTStr("ConfirmRemove.Title"), text); + QMessageBox::StandardButton button = OBSMessageBox::question( + this, QTStr("ConfirmRemove.Title"), text); if (button == QMessageBox::No) return; @@ -448,7 +445,7 @@ void OBSBasic::on_actionRemoveProfile_triggered() if (config.Open(newPath.c_str(), CONFIG_OPEN_ALWAYS) != 0) { blog(LOG_ERROR, "ChangeProfile: Failed to load file '%s'", - newPath.c_str()); + newPath.c_str()); return; } @@ -457,9 +454,8 @@ void OBSBasic::on_actionRemoveProfile_triggered() const char *newDir = strrchr(newPath.c_str(), '/') + 1; config_set_string(App()->GlobalConfig(), "Basic", "Profile", - newName.c_str()); - config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", - newDir); + newName.c_str()); + config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", newDir); Auth::Save(); auth.reset(); @@ -474,8 +470,8 @@ void OBSBasic::on_actionRemoveProfile_triggered() RefreshProfiles(); config_save_safe(App()->GlobalConfig(), "tmp", nullptr); - blog(LOG_INFO, "Switched to profile '%s' (%s)", - newName.c_str(), newDir); + blog(LOG_INFO, "Switched to profile '%s' (%s)", newName.c_str(), + newDir); blog(LOG_INFO, "------------------------------------------------"); UpdateTitleBar(); @@ -501,11 +497,8 @@ void OBSBasic::on_actionImportProfile_triggered() } QString dir = QFileDialog::getExistingDirectory( - this, - QTStr("Basic.MainMenu.Profile.Import"), - home, - QFileDialog::ShowDirsOnly | - QFileDialog::DontResolveSymlinks); + this, QTStr("Basic.MainMenu.Profile.Import"), home, + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if (!dir.isEmpty() && !dir.isNull()) { QString inputPath = QString::fromUtf8(path); @@ -517,18 +510,18 @@ void OBSBasic::on_actionImportProfile_triggered() if (!folder.exists()) { folder.mkpath(profileDir); QFile::copy(dir + "/basic.ini", - profileDir + "/basic.ini"); + profileDir + "/basic.ini"); QFile::copy(dir + "/service.json", - profileDir + "/service.json"); + profileDir + "/service.json"); QFile::copy(dir + "/streamEncoder.json", - profileDir + "/streamEncoder.json"); + profileDir + "/streamEncoder.json"); QFile::copy(dir + "/recordEncoder.json", - profileDir + "/recordEncoder.json"); + profileDir + "/recordEncoder.json"); RefreshProfiles(); } else { - OBSMessageBox::warning(this, - QTStr("Basic.MainMenu.Profile.Import"), - QTStr("Basic.MainMenu.Profile.Exists")); + OBSMessageBox::warning( + this, QTStr("Basic.MainMenu.Profile.Import"), + QTStr("Basic.MainMenu.Profile.Exists")); } } } @@ -539,9 +532,8 @@ void OBSBasic::on_actionExportProfile_triggered() QString home = QDir::homePath(); - QString currentProfile = - QString::fromUtf8(config_get_string(App()->GlobalConfig(), - "Basic", "ProfileDir")); + QString currentProfile = QString::fromUtf8(config_get_string( + App()->GlobalConfig(), "Basic", "ProfileDir")); int ret = GetConfigPath(path, 512, "obs-studio/basic/profiles/"); if (ret <= 0) { @@ -550,11 +542,8 @@ void OBSBasic::on_actionExportProfile_triggered() } QString dir = QFileDialog::getExistingDirectory( - this, - QTStr("Basic.MainMenu.Profile.Export"), - home, - QFileDialog::ShowDirsOnly | - QFileDialog::DontResolveSymlinks); + this, QTStr("Basic.MainMenu.Profile.Export"), home, + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if (!dir.isEmpty() && !dir.isNull()) { QString outputDir = dir + "/" + currentProfile; @@ -571,26 +560,28 @@ void OBSBasic::on_actionExportProfile_triggered() QFile::remove(outputDir + "/service.json"); if (QFile::exists(outputDir + "/streamEncoder.json")) - QFile::remove(outputDir + "/streamEncoder.json"); + QFile::remove(outputDir + + "/streamEncoder.json"); if (QFile::exists(outputDir + "/recordEncoder.json")) - QFile::remove(outputDir + "/recordEncoder.json"); + QFile::remove(outputDir + + "/recordEncoder.json"); } QFile::copy(inputPath + currentProfile + "/basic.ini", - outputDir + "/basic.ini"); + outputDir + "/basic.ini"); QFile::copy(inputPath + currentProfile + "/service.json", - outputDir + "/service.json"); + outputDir + "/service.json"); QFile::copy(inputPath + currentProfile + "/streamEncoder.json", - outputDir + "/streamEncoder.json"); + outputDir + "/streamEncoder.json"); QFile::copy(inputPath + currentProfile + "/recordEncoder.json", - outputDir + "/recordEncoder.json"); + outputDir + "/recordEncoder.json"); } } void OBSBasic::ChangeProfile() { - QAction *action = reinterpret_cast(sender()); + QAction *action = reinterpret_cast(sender()); ConfigFile config; std::string path; @@ -601,8 +592,8 @@ void OBSBasic::ChangeProfile() if (path.empty()) return; - const char *oldName = config_get_string(App()->GlobalConfig(), - "Basic", "Profile"); + const char *oldName = + config_get_string(App()->GlobalConfig(), "Basic", "Profile"); if (action->text().compare(QT_UTF8(oldName)) == 0) { action->setChecked(true); return; @@ -613,7 +604,7 @@ void OBSBasic::ChangeProfile() if (config.Open(path.c_str(), CONFIG_OPEN_ALWAYS) != 0) { blog(LOG_ERROR, "ChangeProfile: Failed to load file '%s'", - path.c_str()); + path.c_str()); return; } @@ -623,8 +614,7 @@ void OBSBasic::ChangeProfile() const char *newDir = strrchr(path.c_str(), '/') + 1; config_set_string(App()->GlobalConfig(), "Basic", "Profile", newName); - config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", - newDir); + config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", newDir); Auth::Save(); auth.reset(); @@ -642,8 +632,7 @@ void OBSBasic::ChangeProfile() CheckForSimpleModeX264Fallback(); - blog(LOG_INFO, "Switched to profile '%s' (%s)", - newName, newDir); + blog(LOG_INFO, "Switched to profile '%s' (%s)", newName, newDir); blog(LOG_INFO, "------------------------------------------------"); if (api) @@ -652,10 +641,10 @@ void OBSBasic::ChangeProfile() void OBSBasic::CheckForSimpleModeX264Fallback() { - const char *curStreamEncoder = config_get_string(basicConfig, - "SimpleOutput", "StreamEncoder"); - const char *curRecEncoder = config_get_string(basicConfig, - "SimpleOutput", "RecEncoder"); + const char *curStreamEncoder = + config_get_string(basicConfig, "SimpleOutput", "StreamEncoder"); + const char *curRecEncoder = + config_get_string(basicConfig, "SimpleOutput", "RecEncoder"); bool qsv_supported = false; bool amd_supported = false; bool nve_supported = false; @@ -672,8 +661,7 @@ void OBSBasic::CheckForSimpleModeX264Fallback() nve_supported = true; } - auto CheckEncoder = [&] (const char *&name) - { + auto CheckEncoder = [&](const char *&name) { if (strcmp(name, SIMPLE_ENCODER_QSV) == 0) { if (!qsv_supported) { changed = true; @@ -698,13 +686,11 @@ void OBSBasic::CheckForSimpleModeX264Fallback() }; if (!CheckEncoder(curStreamEncoder)) - config_set_string(basicConfig, - "SimpleOutput", "StreamEncoder", - curStreamEncoder); + config_set_string(basicConfig, "SimpleOutput", "StreamEncoder", + curStreamEncoder); if (!CheckEncoder(curRecEncoder)) - config_set_string(basicConfig, - "SimpleOutput", "RecEncoder", - curRecEncoder); + config_set_string(basicConfig, "SimpleOutput", "RecEncoder", + curRecEncoder); if (changed) config_save_safe(basicConfig, "tmp", nullptr); } diff --git a/UI/window-basic-main-scene-collections.cpp b/UI/window-basic-main-scene-collections.cpp index 84da0f3..cceef02 100644 --- a/UI/window-basic-main-scene-collections.cpp +++ b/UI/window-basic-main-scene-collections.cpp @@ -28,16 +28,16 @@ using namespace std; -void EnumSceneCollections(std::function &&cb) +void EnumSceneCollections(std::function &&cb) { char path[512]; os_glob_t *glob; int ret = GetConfigPath(path, sizeof(path), - "obs-studio/basic/scenes/*.json"); + "obs-studio/basic/scenes/*.json"); if (ret <= 0) { blog(LOG_WARNING, "Failed to get config path for scene " - "collections"); + "collections"); return; } @@ -52,8 +52,8 @@ void EnumSceneCollections(std::function &&cb) if (glob->gl_pathv[i].directory) continue; - obs_data_t *data = obs_data_create_from_json_file_safe(filePath, - "bak"); + obs_data_t *data = + obs_data_create_from_json_file_safe(filePath, "bak"); std::string name = obs_data_get_string(data, "name"); /* if no name found, use the file name as the name @@ -75,8 +75,7 @@ void EnumSceneCollections(std::function &&cb) static bool SceneCollectionExists(const char *findName) { bool found = false; - auto func = [&](const char *name, const char*) - { + auto func = [&](const char *name, const char *) { if (strcmp(name, findName) == 0) { found = true; return false; @@ -90,7 +89,8 @@ static bool SceneCollectionExists(const char *findName) } static bool GetSceneCollectionName(QWidget *parent, std::string &name, - std::string &file, const char *oldName = nullptr) + std::string &file, + const char *oldName = nullptr) { bool rename = oldName != nullptr; const char *title; @@ -101,28 +101,28 @@ static bool GetSceneCollectionName(QWidget *parent, std::string &name, if (rename) { title = Str("Basic.Main.RenameSceneCollection.Title"); - text = Str("Basic.Main.AddSceneCollection.Text"); + text = Str("Basic.Main.AddSceneCollection.Text"); } else { title = Str("Basic.Main.AddSceneCollection.Title"); - text = Str("Basic.Main.AddSceneCollection.Text"); + text = Str("Basic.Main.AddSceneCollection.Text"); } for (;;) { - bool success = NameDialog::AskForName(parent, title, text, - name, QT_UTF8(oldName)); + bool success = NameDialog::AskForName(parent, title, text, name, + QT_UTF8(oldName)); if (!success) { return false; } if (name.empty()) { OBSMessageBox::warning(parent, - QTStr("NoNameEntered.Title"), - QTStr("NoNameEntered.Text")); + QTStr("NoNameEntered.Title"), + QTStr("NoNameEntered.Text")); continue; } if (SceneCollectionExists(name.c_str())) { OBSMessageBox::warning(parent, - QTStr("NameExists.Title"), - QTStr("NameExists.Text")); + QTStr("NameExists.Title"), + QTStr("NameExists.Text")); continue; } break; @@ -130,7 +130,7 @@ static bool GetSceneCollectionName(QWidget *parent, std::string &name, if (!GetFileSafeName(name.c_str(), file)) { blog(LOG_WARNING, "Failed to create safe file name for '%s'", - name.c_str()); + name.c_str()); return false; } @@ -145,7 +145,7 @@ static bool GetSceneCollectionName(QWidget *parent, std::string &name, if (!GetClosestUnusedFileName(file, "json")) { blog(LOG_WARNING, "Failed to get closest file name for %s", - file.c_str()); + file.c_str()); return false; } @@ -171,9 +171,9 @@ bool OBSBasic::AddSceneCollection(bool create_new, const QString &qname) SaveProjectNow(); config_set_string(App()->GlobalConfig(), "Basic", "SceneCollection", - name.c_str()); + name.c_str()); config_set_string(App()->GlobalConfig(), "Basic", "SceneCollectionFile", - file.c_str()); + file.c_str()); if (create_new) { CreateDefaultScene(false); } @@ -181,8 +181,7 @@ bool OBSBasic::AddSceneCollection(bool create_new, const QString &qname) RefreshSceneCollections(); blog(LOG_INFO, "Added scene collection '%s' (%s, %s.json)", - name.c_str(), create_new ? "clean" : "duplicate", - file.c_str()); + name.c_str(), create_new ? "clean" : "duplicate", file.c_str()); blog(LOG_INFO, "------------------------------------------------"); UpdateTitleBar(); @@ -197,7 +196,7 @@ bool OBSBasic::AddSceneCollection(bool create_new, const QString &qname) void OBSBasic::RefreshSceneCollections() { - QList menuActions = ui->sceneCollectionMenu->actions(); + QList menuActions = ui->sceneCollectionMenu->actions(); int count = 0; for (int i = 0; i < menuActions.count(); i++) { @@ -206,18 +205,17 @@ void OBSBasic::RefreshSceneCollections() delete menuActions[i]; } - const char *cur_name = config_get_string(App()->GlobalConfig(), - "Basic", "SceneCollection"); + const char *cur_name = config_get_string(App()->GlobalConfig(), "Basic", + "SceneCollection"); - auto addCollection = [&](const char *name, const char *path) - { + auto addCollection = [&](const char *name, const char *path) { std::string file = strrchr(path, '/') + 1; file.erase(file.size() - 5, 5); QAction *action = new QAction(QT_UTF8(name), this); action->setProperty("file_name", QT_UTF8(path)); - connect(action, &QAction::triggered, - this, &OBSBasic::ChangeSceneCollection); + connect(action, &QAction::triggered, this, + &OBSBasic::ChangeSceneCollection); action->setCheckable(true); action->setChecked(strcmp(name, cur_name) == 0); @@ -243,7 +241,7 @@ void OBSBasic::RefreshSceneCollections() ui->actionRemoveSceneCollection->setEnabled(count > 1); - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); main->ui->actionPasteFilters->setEnabled(false); main->ui->actionPasteRef->setEnabled(false); @@ -265,19 +263,19 @@ void OBSBasic::on_actionRenameSceneCollection_triggered() std::string name; std::string file; - std::string oldFile = config_get_string(App()->GlobalConfig(), - "Basic", "SceneCollectionFile"); - const char *oldName = config_get_string(App()->GlobalConfig(), - "Basic", "SceneCollection"); + std::string oldFile = config_get_string(App()->GlobalConfig(), "Basic", + "SceneCollectionFile"); + const char *oldName = config_get_string(App()->GlobalConfig(), "Basic", + "SceneCollection"); bool success = GetSceneCollectionName(this, name, file, oldName); if (!success) return; config_set_string(App()->GlobalConfig(), "Basic", "SceneCollection", - name.c_str()); + name.c_str()); config_set_string(App()->GlobalConfig(), "Basic", "SceneCollectionFile", - file.c_str()); + file.c_str()); SaveProjectNow(); char path[512]; @@ -295,7 +293,7 @@ void OBSBasic::on_actionRenameSceneCollection_triggered() blog(LOG_INFO, "------------------------------------------------"); blog(LOG_INFO, "Renamed scene collection to '%s' (%s.json)", - name.c_str(), file.c_str()); + name.c_str(), file.c_str()); blog(LOG_INFO, "------------------------------------------------"); UpdateTitleBar(); @@ -312,13 +310,12 @@ void OBSBasic::on_actionRemoveSceneCollection_triggered() std::string newName; std::string newPath; - std::string oldFile = config_get_string(App()->GlobalConfig(), - "Basic", "SceneCollectionFile"); - std::string oldName = config_get_string(App()->GlobalConfig(), - "Basic", "SceneCollection"); + std::string oldFile = config_get_string(App()->GlobalConfig(), "Basic", + "SceneCollectionFile"); + std::string oldName = config_get_string(App()->GlobalConfig(), "Basic", + "SceneCollection"); - auto cb = [&](const char *name, const char *filePath) - { + auto cb = [&](const char *name, const char *filePath) { if (strcmp(oldName.c_str(), name) != 0) { newName = name; newPath = filePath; @@ -337,8 +334,8 @@ void OBSBasic::on_actionRemoveSceneCollection_triggered() QString text = QTStr("ConfirmRemove.Text"); text.replace("$1", QT_UTF8(oldName.c_str())); - QMessageBox::StandardButton button = OBSMessageBox::question(this, - QTStr("ConfirmRemove.Title"), text); + QMessageBox::StandardButton button = OBSMessageBox::question( + this, QTStr("ConfirmRemove.Title"), text); if (button == QMessageBox::No) return; @@ -358,13 +355,13 @@ void OBSBasic::on_actionRemoveSceneCollection_triggered() Load(newPath.c_str()); RefreshSceneCollections(); - const char *newFile = config_get_string(App()->GlobalConfig(), - "Basic", "SceneCollectionFile"); + const char *newFile = config_get_string(App()->GlobalConfig(), "Basic", + "SceneCollectionFile"); - blog(LOG_INFO, "Removed scene collection '%s' (%s.json), " - "switched to '%s' (%s.json)", - oldName.c_str(), oldFile.c_str(), - newName.c_str(), newFile); + blog(LOG_INFO, + "Removed scene collection '%s' (%s.json), " + "switched to '%s' (%s.json)", + oldName.c_str(), oldFile.c_str(), newName.c_str(), newFile); blog(LOG_INFO, "------------------------------------------------"); UpdateTitleBar(); @@ -388,10 +385,8 @@ void OBSBasic::on_actionImportSceneCollection_triggered() } QString qfilePath = QFileDialog::getOpenFileName( - this, - QTStr("Basic.MainMenu.SceneCollection.Import"), - qhome, - "JSON Files (*.json)"); + this, QTStr("Basic.MainMenu.SceneCollection.Import"), qhome, + "JSON Files (*.json)"); QFileInfo finfo(qfilePath); QString qfilename = finfo.fileName(); @@ -416,23 +411,25 @@ void OBSBasic::on_actionImportSceneCollection_triggered() obs_data_set_string(scenedata, "name", name.c_str()); if (!GetFileSafeName(name.c_str(), file)) { - blog(LOG_WARNING, "Failed to create " - "safe file name for '%s'", - name.c_str()); + blog(LOG_WARNING, + "Failed to create " + "safe file name for '%s'", + name.c_str()); return; } string filePath = path + file; if (!GetClosestUnusedFileName(filePath, "json")) { - blog(LOG_WARNING, "Failed to get " - "closest file name for %s", - file.c_str()); + blog(LOG_WARNING, + "Failed to get " + "closest file name for %s", + file.c_str()); return; } - obs_data_save_json_safe(scenedata, filePath.c_str(), - "tmp", "bak"); + obs_data_save_json_safe(scenedata, filePath.c_str(), "tmp", + "bak"); RefreshSceneCollections(); } } @@ -445,8 +442,8 @@ void OBSBasic::on_actionExportSceneCollection_triggered() QString home = QDir::homePath(); - QString currentFile = QT_UTF8(config_get_string(App()->GlobalConfig(), - "Basic", "SceneCollectionFile")); + QString currentFile = QT_UTF8(config_get_string( + App()->GlobalConfig(), "Basic", "SceneCollectionFile")); int ret = GetConfigPath(path, 512, "obs-studio/basic/scenes/"); if (ret <= 0) { @@ -455,10 +452,8 @@ void OBSBasic::on_actionExportSceneCollection_triggered() } QString exportFile = QFileDialog::getSaveFileName( - this, - QTStr("Basic.MainMenu.SceneCollection.Export"), - home + "/" + currentFile, - "JSON Files (*.json)"); + this, QTStr("Basic.MainMenu.SceneCollection.Export"), + home + "/" + currentFile, "JSON Files (*.json)"); string file = QT_TO_UTF8(exportFile); @@ -472,7 +467,7 @@ void OBSBasic::on_actionExportSceneCollection_triggered() void OBSBasic::ChangeSceneCollection() { - QAction *action = reinterpret_cast(sender()); + QAction *action = reinterpret_cast(sender()); std::string fileName; if (!action) @@ -482,8 +477,8 @@ void OBSBasic::ChangeSceneCollection() if (fileName.empty()) return; - const char *oldName = config_get_string(App()->GlobalConfig(), - "Basic", "SceneCollection"); + const char *oldName = config_get_string(App()->GlobalConfig(), "Basic", + "SceneCollection"); if (action->text().compare(QT_UTF8(oldName)) == 0) { action->setChecked(true); return; @@ -494,13 +489,13 @@ void OBSBasic::ChangeSceneCollection() Load(fileName.c_str()); RefreshSceneCollections(); - const char *newName = config_get_string(App()->GlobalConfig(), - "Basic", "SceneCollection"); - const char *newFile = config_get_string(App()->GlobalConfig(), - "Basic", "SceneCollectionFile"); + const char *newName = config_get_string(App()->GlobalConfig(), "Basic", + "SceneCollection"); + const char *newFile = config_get_string(App()->GlobalConfig(), "Basic", + "SceneCollectionFile"); - blog(LOG_INFO, "Switched to scene collection '%s' (%s.json)", - newName, newFile); + blog(LOG_INFO, "Switched to scene collection '%s' (%s.json)", newName, + newFile); blog(LOG_INFO, "------------------------------------------------"); UpdateTitleBar(); diff --git a/UI/window-basic-main-transitions.cpp b/UI/window-basic-main-transitions.cpp index daec936..a3ca9be 100644 --- a/UI/window-basic-main-transitions.cpp +++ b/UI/window-basic-main-transitions.cpp @@ -54,8 +54,8 @@ void OBSBasic::InitDefaultTransitions() if (!obs_is_source_configurable(id)) { const char *name = obs_source_get_display_name(id); - obs_source_t *tr = obs_source_create_private( - id, name, NULL); + obs_source_t *tr = + obs_source_create_private(id, name, NULL); InitTransition(tr); transitions.emplace_back(tr); @@ -68,7 +68,7 @@ void OBSBasic::InitDefaultTransitions() for (OBSSource &tr : transitions) { ui->transitions->addItem(QT_UTF8(obs_source_get_name(tr)), - QVariant::fromValue(OBSSource(tr))); + QVariant::fromValue(OBSSource(tr))); } } @@ -79,33 +79,33 @@ void OBSBasic::AddQuickTransitionHotkey(QuickTransition *qt) dstr_printf(hotkeyId, "OBSBasic.QuickTransition.%d", qt->id); hotkeyName = QTStr("QuickTransitions.HotkeyName") - .arg(MakeQuickTransitionText(qt)); + .arg(MakeQuickTransitionText(qt)); - auto quickTransition = [] (void *data, obs_hotkey_id, obs_hotkey_t*, - bool pressed) - { + auto quickTransition = [](void *data, obs_hotkey_id, obs_hotkey_t *, + bool pressed) { int id = (int)(uintptr_t)data; OBSBasic *main = - reinterpret_cast(App()->GetMainWindow()); + reinterpret_cast(App()->GetMainWindow()); if (pressed) QMetaObject::invokeMethod(main, - "TriggerQuickTransition", - Qt::QueuedConnection, - Q_ARG(int, id)); + "TriggerQuickTransition", + Qt::QueuedConnection, + Q_ARG(int, id)); }; qt->hotkey = obs_hotkey_register_frontend(hotkeyId->array, - QT_TO_UTF8(hotkeyName), quickTransition, - (void*)(uintptr_t)qt->id); + QT_TO_UTF8(hotkeyName), + quickTransition, + (void *)(uintptr_t)qt->id); } void QuickTransition::SourceRenamed(void *param, calldata_t *data) { - QuickTransition *qt = reinterpret_cast(param); + QuickTransition *qt = reinterpret_cast(param); QString hotkeyName = QTStr("QuickTransitions.HotkeyName") - .arg(MakeQuickTransitionText(qt)); + .arg(MakeQuickTransitionText(qt)); obs_hotkey_set_description(qt->hotkey, QT_TO_UTF8(hotkeyName)); @@ -135,23 +135,23 @@ void OBSBasic::RemoveQuickTransitionHotkey(QuickTransition *qt) void OBSBasic::InitTransition(obs_source_t *transition) { - auto onTransitionStop = [] (void *data, calldata_t*) { - OBSBasic *window = (OBSBasic*)data; + auto onTransitionStop = [](void *data, calldata_t *) { + OBSBasic *window = (OBSBasic *)data; QMetaObject::invokeMethod(window, "TransitionStopped", - Qt::QueuedConnection); + Qt::QueuedConnection); }; - auto onTransitionFullStop = [] (void *data, calldata_t*) { - OBSBasic *window = (OBSBasic*)data; + auto onTransitionFullStop = [](void *data, calldata_t *) { + OBSBasic *window = (OBSBasic *)data; QMetaObject::invokeMethod(window, "TransitionFullyStopped", - Qt::QueuedConnection); + Qt::QueuedConnection); }; signal_handler_t *handler = obs_source_get_signal_handler(transition); signal_handler_connect(handler, "transition_video_stop", - onTransitionStop, this); - signal_handler_connect(handler, "transition_stop", - onTransitionFullStop, this); + onTransitionStop, this); + signal_handler_connect(handler, "transition_stop", onTransitionFullStop, + this); } static inline OBSSource GetTransitionComboItem(QComboBox *combo, int idx) @@ -163,12 +163,12 @@ void OBSBasic::CreateDefaultQuickTransitions() { /* non-configurable transitions are always available, so add them * to the "default quick transitions" list */ - quickTransitions.emplace_back( - GetTransitionComboItem(ui->transitions, 0), - 300, quickTransitionIdCounter++); - quickTransitions.emplace_back( - GetTransitionComboItem(ui->transitions, 1), - 300, quickTransitionIdCounter++); + quickTransitions.emplace_back(GetTransitionComboItem(ui->transitions, + 0), + 300, quickTransitionIdCounter++); + quickTransitions.emplace_back(GetTransitionComboItem(ui->transitions, + 1), + 300, quickTransitionIdCounter++); } void OBSBasic::LoadQuickTransitions(obs_data_array_t *array) @@ -188,13 +188,14 @@ void OBSBasic::LoadQuickTransitions(obs_data_array_t *array) obs_source_t *source = FindTransition(name); if (source) { quickTransitions.emplace_back(source, duration, - id); + id); if (quickTransitionIdCounter <= id) quickTransitionIdCounter = id + 1; int idx = (int)quickTransitions.size() - 1; - AddQuickTransitionHotkey(&quickTransitions[idx]); + AddQuickTransitionHotkey( + &quickTransitions[idx]); obs_hotkey_load(quickTransitions[idx].hotkey, hotkeys); } @@ -214,7 +215,7 @@ obs_data_array_t *OBSBasic::SaveQuickTransitions() obs_data_array_t *hotkeys = obs_hotkey_save(qt.hotkey); obs_data_set_string(data, "name", - obs_source_get_name(qt.source)); + obs_source_get_name(qt.source)); obs_data_set_int(data, "duration", qt.duration); obs_data_set_array(data, "hotkeys", hotkeys); obs_data_set_int(data, "id", qt.id); @@ -231,8 +232,7 @@ obs_data_array_t *OBSBasic::SaveQuickTransitions() obs_source_t *OBSBasic::FindTransition(const char *name) { for (int i = 0; i < ui->transitions->count(); i++) { - OBSSource tr = ui->transitions->itemData(i) - .value(); + OBSSource tr = ui->transitions->itemData(i).value(); const char *trName = obs_source_get_name(tr); if (strcmp(trName, name) == 0) @@ -292,7 +292,7 @@ void OBSBasic::TransitionFullyStopped() } void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct, - bool quickTransition) + bool quickTransition) { obs_scene_t *scene = obs_scene_from_source(source); bool usingPreviewProgram = IsPreviewProgramMode(); @@ -317,10 +317,10 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct, } if (usingPreviewProgram && sceneDuplicationMode) { - scene = obs_scene_duplicate(scene, NULL, - editPropertiesMode ? - OBS_SCENE_DUP_PRIVATE_COPY : - OBS_SCENE_DUP_PRIVATE_REFS); + scene = obs_scene_duplicate( + scene, NULL, + editPropertiesMode ? OBS_SCENE_DUP_PRIVATE_COPY + : OBS_SCENE_DUP_PRIVATE_REFS); source = obs_scene_get_source(scene); } @@ -342,8 +342,8 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct, OBSData data = obs_source_get_private_settings(source); obs_data_release(data); - const char *trOverrideName = obs_data_get_string(data, - "transition"); + const char *trOverrideName = + obs_data_get_string(data, "transition"); int duration = ui->transitionDuration->value(); if (trOverrideName && *trOverrideName && !quickTransition) { @@ -351,18 +351,18 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct, if (trOverride) { transition = trOverride; - obs_data_set_default_int(data, - "transition_duration", 300); + obs_data_set_default_int( + data, "transition_duration", 300); - duration = (int)obs_data_get_int(data, - "transition_duration"); + duration = (int)obs_data_get_int( + data, "transition_duration"); OverrideTransition(trOverride); overridingTransition = true; } } - bool success = obs_transition_start(transition, - OBS_TRANSITION_MODE_AUTO, duration, source); + bool success = obs_transition_start( + transition, OBS_TRANSITION_MODE_AUTO, duration, source); if (!success) TransitionFullyStopped(); } @@ -432,12 +432,12 @@ void OBSBasic::on_transitions_currentIndexChanged(int) void OBSBasic::AddTransition() { - QAction *action = reinterpret_cast(sender()); + QAction *action = reinterpret_cast(sender()); QString idStr = action->property("id").toString(); string name; - QString placeHolderText = QT_UTF8( - obs_source_get_display_name(QT_TO_UTF8(idStr))); + QString placeHolderText = + QT_UTF8(obs_source_get_display_name(QT_TO_UTF8(idStr))); QString format = placeHolderText + " (%1)"; obs_source_t *source = nullptr; int i = 1; @@ -447,40 +447,41 @@ void OBSBasic::AddTransition() } bool accepted = NameDialog::AskForName(this, - QTStr("TransitionNameDlg.Title"), - QTStr("TransitionNameDlg.Text"), - name, placeHolderText); + QTStr("TransitionNameDlg.Title"), + QTStr("TransitionNameDlg.Text"), + name, placeHolderText); if (accepted) { if (name.empty()) { OBSMessageBox::warning(this, - QTStr("NoNameEntered.Title"), - QTStr("NoNameEntered.Text")); + QTStr("NoNameEntered.Title"), + QTStr("NoNameEntered.Text")); AddTransition(); return; } source = FindTransition(name.c_str()); if (source) { - OBSMessageBox::warning(this, - QTStr("NameExists.Title"), - QTStr("NameExists.Text")); + OBSMessageBox::warning(this, QTStr("NameExists.Title"), + QTStr("NameExists.Text")); AddTransition(); return; } source = obs_source_create_private(QT_TO_UTF8(idStr), - name.c_str(), NULL); + name.c_str(), NULL); InitTransition(source); - ui->transitions->addItem(QT_UTF8(name.c_str()), - QVariant::fromValue(OBSSource(source))); + ui->transitions->addItem( + QT_UTF8(name.c_str()), + QVariant::fromValue(OBSSource(source))); ui->transitions->setCurrentIndex(ui->transitions->count() - 1); CreatePropertiesWindow(source); obs_source_release(source); if (api) - api->on_event(OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED); + api->on_event( + OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED); ClearQuickTransitionWidgets(); RefreshQuickTransitions(); @@ -500,8 +501,8 @@ void OBSBasic::on_transitionAdd_clicked() QAction *action = new QAction(name, this); action->setProperty("id", id); - connect(action, SIGNAL(triggered()), - this, SLOT(AddTransition())); + connect(action, SIGNAL(triggered()), this, + SLOT(AddTransition())); menu.addAction(action); foundConfigurableTransitions = true; @@ -529,7 +530,8 @@ void OBSBasic::on_transitionRemove_clicked() if (qt.button) qt.button->deleteLater(); RemoveQuickTransitionHotkey(&qt); - quickTransitions.erase(quickTransitions.begin() + i - 1); + quickTransitions.erase(quickTransitions.begin() + i - + 1); } } @@ -544,7 +546,7 @@ void OBSBasic::on_transitionRemove_clicked() void OBSBasic::RenameTransition() { - QAction *action = reinterpret_cast(sender()); + QAction *action = reinterpret_cast(sender()); QVariant variant = action->property("transition"); obs_source_t *transition = variant.value(); @@ -553,24 +555,23 @@ void OBSBasic::RenameTransition() obs_source_t *source = nullptr; bool accepted = NameDialog::AskForName(this, - QTStr("TransitionNameDlg.Title"), - QTStr("TransitionNameDlg.Text"), - name, placeHolderText); + QTStr("TransitionNameDlg.Title"), + QTStr("TransitionNameDlg.Text"), + name, placeHolderText); if (accepted) { if (name.empty()) { OBSMessageBox::warning(this, - QTStr("NoNameEntered.Title"), - QTStr("NoNameEntered.Text")); + QTStr("NoNameEntered.Title"), + QTStr("NoNameEntered.Text")); RenameTransition(); return; } source = FindTransition(name.c_str()); if (source) { - OBSMessageBox::warning(this, - QTStr("NameExists.Title"), - QTStr("NameExists.Text")); + OBSMessageBox::warning(this, QTStr("NameExists.Title"), + QTStr("NameExists.Text")); RenameTransition(); return; @@ -579,10 +580,12 @@ void OBSBasic::RenameTransition() obs_source_set_name(transition, name.c_str()); int idx = ui->transitions->findData(variant); if (idx != -1) { - ui->transitions->setItemText(idx, QT_UTF8(name.c_str())); + ui->transitions->setItemText(idx, + QT_UTF8(name.c_str())); if (api) - api->on_event(OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED); + api->on_event( + OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED); ClearQuickTransitionWidgets(); RefreshQuickTransitions(); @@ -597,9 +600,7 @@ void OBSBasic::on_transitionProps_clicked() if (!obs_source_configurable(source)) return; - auto properties = [&] () { - CreatePropertiesWindow(source); - }; + auto properties = [&]() { CreatePropertiesWindow(source); }; QMenu menu(this); @@ -643,8 +644,7 @@ void OBSBasic::SetCurrentScene(obs_scene_t *scene, bool force, bool direct) SetCurrentScene(source, force, direct); } -template -static T GetOBSRef(QListWidgetItem *item) +template static T GetOBSRef(QListWidgetItem *item) { return item->data(static_cast(QtDataRole::OBSRef)).value(); } @@ -679,7 +679,8 @@ void OBSBasic::SetCurrentScene(OBSSource scene, bool force, bool direct) ui->scenes->setCurrentItem(item); ui->scenes->blockSignals(false); if (api) - api->on_event(OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED); + api->on_event( + OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED); break; } } @@ -689,8 +690,8 @@ void OBSBasic::SetCurrentScene(OBSSource scene, bool force, bool direct) bool userSwitched = (!force && !disableSaving); blog(LOG_INFO, "%s to scene '%s'", - userSwitched ? "User switched" : "Switched", - obs_source_get_name(scene)); + userSwitched ? "User switched" : "Switched", + obs_source_get_name(scene)); } void OBSBasic::CreateProgramDisplay() @@ -698,8 +699,8 @@ void OBSBasic::CreateProgramDisplay() program = new OBSQTDisplay(); program->setContextMenuPolicy(Qt::CustomContextMenu); - connect(program.data(), &QWidget::customContextMenuRequested, - this, &OBSBasic::on_program_customContextMenuRequested); + connect(program.data(), &QWidget::customContextMenuRequested, this, + &OBSBasic::on_program_customContextMenuRequested); auto displayResize = [this]() { struct obs_video_info ovi; @@ -708,13 +709,11 @@ void OBSBasic::CreateProgramDisplay() ResizeProgram(ovi.base_width, ovi.base_height); }; - connect(program.data(), &OBSQTDisplay::DisplayResized, - displayResize); + connect(program.data(), &OBSQTDisplay::DisplayResized, displayResize); - auto addDisplay = [this] (OBSQTDisplay *window) - { + auto addDisplay = [this](OBSQTDisplay *window) { obs_display_add_draw_callback(window->GetDisplay(), - OBSBasic::RenderProgram, this); + OBSBasic::RenderProgram, this); struct obs_video_info ovi; if (obs_get_video_info(&ovi)) @@ -723,8 +722,7 @@ void OBSBasic::CreateProgramDisplay() connect(program.data(), &OBSQTDisplay::DisplayCreated, addDisplay); - program->setSizePolicy(QSizePolicy::Expanding, - QSizePolicy::Expanding); + program->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); } void OBSBasic::TransitionClicked() @@ -771,16 +769,16 @@ void OBSBasic::CreateProgramOptions() programOptions->setLayout(layout); - auto onAdd = [this] () { + auto onAdd = [this]() { QScopedPointer menu(CreateTransitionMenu(this, nullptr)); menu->exec(QCursor::pos()); }; - auto onConfig = [this] () { + auto onConfig = [this]() { QMenu menu(this); QAction *action; - auto toggleEditProperties = [this] () { + auto toggleEditProperties = [this]() { editPropertiesMode = !editPropertiesMode; OBSSource actualScene = OBSGetStrongRef(programScene); @@ -788,11 +786,11 @@ void OBSBasic::CreateProgramOptions() TransitionToScene(actualScene, true); }; - auto toggleSwapScenesMode = [this] () { + auto toggleSwapScenesMode = [this]() { swapScenesMode = !swapScenesMode; }; - auto toggleSceneDuplication = [this] () { + auto toggleSceneDuplication = [this]() { sceneDuplicationMode = !sceneDuplicationMode; OBSSource actualScene = OBSGetStrongRef(programScene); @@ -800,20 +798,22 @@ void OBSBasic::CreateProgramOptions() TransitionToScene(actualScene, true); }; - auto showToolTip = [&] () { + auto showToolTip = [&]() { QAction *act = menu.activeAction(); QToolTip::showText(QCursor::pos(), act->toolTip(), - &menu, menu.actionGeometry(act)); + &menu, menu.actionGeometry(act)); }; - action = menu.addAction(QTStr("QuickTransitions.DuplicateScene")); + action = menu.addAction( + QTStr("QuickTransitions.DuplicateScene")); action->setToolTip(QTStr("QuickTransitions.DuplicateSceneTT")); action->setCheckable(true); action->setChecked(sceneDuplicationMode); connect(action, &QAction::triggered, toggleSceneDuplication); connect(action, &QAction::hovered, showToolTip); - action = menu.addAction(QTStr("QuickTransitions.EditProperties")); + action = menu.addAction( + QTStr("QuickTransitions.EditProperties")); action->setToolTip(QTStr("QuickTransitions.EditPropertiesTT")); action->setCheckable(true); action->setChecked(editPropertiesMode); @@ -831,8 +831,8 @@ void OBSBasic::CreateProgramOptions() menu.exec(QCursor::pos()); }; - connect(transitionButton.data(), &QAbstractButton::clicked, - this, &OBSBasic::TransitionClicked); + connect(transitionButton.data(), &QAbstractButton::clicked, this, + &OBSBasic::TransitionClicked); connect(addQuickTransition, &QAbstractButton::clicked, onAdd); connect(configTransitions, &QAbstractButton::clicked, onConfig); } @@ -868,8 +868,7 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu() duration->setSingleStep(50); duration->setValue(curDuration); - auto setTransition = [this] (QAction *action) - { + auto setTransition = [this](QAction *action) { int idx = action->property("transition_index").toInt(); OBSSource scene = GetCurrentSceneSource(); OBSData data = obs_source_get_private_settings(scene); @@ -886,8 +885,7 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu() obs_data_set_string(data, "transition", name); }; - auto setDuration = [this] (int duration) - { + auto setDuration = [this](int duration) { OBSSource scene = GetCurrentSceneSource(); OBSData data = obs_source_get_private_settings(scene); obs_data_release(data); @@ -895,8 +893,8 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu() obs_data_set_int(data, "transition_duration", duration); }; - connect(duration, (void (QSpinBox::*)(int))&QSpinBox::valueChanged, - setDuration); + connect(duration, (void (QSpinBox::*)(int)) & QSpinBox::valueChanged, + setDuration); for (int i = -1; i < ui->transitions->count(); i++) { const char *name = ""; @@ -918,7 +916,7 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu() action->setChecked(match); connect(action, &QAction::triggered, - std::bind(setTransition, action)); + std::bind(setTransition, action)); } QWidgetAction *durationAction = new QWidgetAction(menu); @@ -937,8 +935,8 @@ QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt) if (qt) { action = menu->addAction(QTStr("Remove")); action->setProperty("id", qt->id); - connect(action, &QAction::triggered, - this, &OBSBasic::QuickTransitionRemoveClicked); + connect(action, &QAction::triggered, this, + &OBSBasic::QuickTransitionRemoveClicked); menu->addSeparator(); } @@ -953,8 +951,9 @@ QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt) duration->setValue(qt ? qt->duration : 300); if (qt) { - connect(duration, (void (QSpinBox::*)(int))&QSpinBox::valueChanged, - this, &OBSBasic::QuickTransitionChangeDuration); + connect(duration, + (void (QSpinBox::*)(int)) & QSpinBox::valueChanged, + this, &OBSBasic::QuickTransitionChangeDuration); } for (int i = 0; i < ui->transitions->count(); i++) { @@ -966,12 +965,13 @@ QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt) if (qt) { action->setProperty("id", qt->id); connect(action, &QAction::triggered, this, - &OBSBasic::QuickTransitionChange); + &OBSBasic::QuickTransitionChange); } else { - action->setProperty("duration", - QVariant::fromValue(duration)); + action->setProperty( + "duration", + QVariant::fromValue(duration)); connect(action, &QAction::triggered, this, - &OBSBasic::AddQuickTransition); + &OBSBasic::AddQuickTransition); } } @@ -1004,11 +1004,11 @@ void OBSBasic::AddQuickTransitionId(int id) /* --------------------------------- */ button->setMenu(buttonMenu); - connect(button, &QAbstractButton::clicked, - this, &OBSBasic::QuickTransitionClicked); + connect(button, &QAbstractButton::clicked, this, + &OBSBasic::QuickTransitionClicked); QVBoxLayout *programLayout = - reinterpret_cast(programOptions->layout()); + reinterpret_cast(programOptions->layout()); int idx = 3; for (;; idx++) { @@ -1027,7 +1027,7 @@ void OBSBasic::AddQuickTransitionId(int id) void OBSBasic::AddQuickTransition() { int trIdx = sender()->property("transition_index").toInt(); - QSpinBox *duration = sender()->property("duration").value(); + QSpinBox *duration = sender()->property("duration").value(); OBSSource transition = GetTransitionComboItem(ui->transitions, trIdx); int id = quickTransitionIdCounter++; @@ -1048,7 +1048,7 @@ void OBSBasic::ClearQuickTransitions() return; QVBoxLayout *programLayout = - reinterpret_cast(programOptions->layout()); + reinterpret_cast(programOptions->layout()); for (int idx = 0;; idx++) { QLayoutItem *item = programLayout->itemAt(idx); @@ -1118,7 +1118,7 @@ void OBSBasic::ClearQuickTransitionWidgets() return; QVBoxLayout *programLayout = - reinterpret_cast(programOptions->layout()); + reinterpret_cast(programOptions->layout()); for (int idx = 0;; idx++) { QLayoutItem *item = programLayout->itemAt(idx); @@ -1152,7 +1152,7 @@ void OBSBasic::DisableQuickTransitionWidgets() return; QVBoxLayout *programLayout = - reinterpret_cast(programOptions->layout()); + reinterpret_cast(programOptions->layout()); for (int idx = 0;; idx++) { QLayoutItem *item = programLayout->itemAt(idx); @@ -1173,7 +1173,7 @@ void OBSBasic::EnableQuickTransitionWidgets() return; QVBoxLayout *programLayout = - reinterpret_cast(programOptions->layout()); + reinterpret_cast(programOptions->layout()); for (int idx = 0;; idx++) { QLayoutItem *item = programLayout->itemAt(idx); @@ -1209,10 +1209,11 @@ void OBSBasic::SetPreviewProgramMode(bool enabled) obs_scene_t *dup; if (sceneDuplicationMode) { - dup = obs_scene_duplicate(curScene, nullptr, - editPropertiesMode ? - OBS_SCENE_DUP_PRIVATE_COPY : - OBS_SCENE_DUP_PRIVATE_REFS); + dup = obs_scene_duplicate( + curScene, nullptr, + editPropertiesMode + ? OBS_SCENE_DUP_PRIVATE_COPY + : OBS_SCENE_DUP_PRIVATE_REFS); } else { dup = curScene; obs_scene_addref(dup); @@ -1235,7 +1236,7 @@ void OBSBasic::SetPreviewProgramMode(bool enabled) programLabel = new QLabel(QTStr("StudioMode.Program")); programLabel->setSizePolicy(QSizePolicy::Preferred, - QSizePolicy::Preferred); + QSizePolicy::Preferred); programLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); programLabel->setProperty("themeID", "previewProgramLabels"); @@ -1248,8 +1249,8 @@ void OBSBasic::SetPreviewProgramMode(bool enabled) programLayout->addWidget(programLabel); programLayout->addWidget(program); - bool labels = config_get_bool(GetGlobalConfig(), - "BasicWindow", "StudioModeLabels"); + bool labels = config_get_bool(GetGlobalConfig(), "BasicWindow", + "StudioModeLabels"); programLabel->setHidden(!labels); @@ -1257,14 +1258,15 @@ void OBSBasic::SetPreviewProgramMode(bool enabled) ui->previewLayout->addWidget(programOptions); ui->previewLayout->addWidget(programWidget); - ui->previewLayout->setAlignment(programOptions, Qt::AlignCenter); + ui->previewLayout->setAlignment(programOptions, + Qt::AlignCenter); if (api) api->on_event(OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED); blog(LOG_INFO, "Switched to Preview/Program mode"); blog(LOG_INFO, "-----------------------------" - "-------------------"); + "-------------------"); } else { OBSSource actualProgramScene = OBSGetStrongRef(programScene); if (!actualProgramScene) @@ -1299,7 +1301,7 @@ void OBSBasic::SetPreviewProgramMode(bool enabled) blog(LOG_INFO, "Switched to regular Preview mode"); blog(LOG_INFO, "-----------------------------" - "-------------------"); + "-------------------"); } ResetUI(); @@ -1310,7 +1312,7 @@ void OBSBasic::RenderProgram(void *data, uint32_t cx, uint32_t cy) { GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "RenderProgram"); - OBSBasic *window = static_cast(data); + OBSBasic *window = static_cast(data); obs_video_info ovi; obs_get_video_info(&ovi); @@ -1324,13 +1326,11 @@ void OBSBasic::RenderProgram(void *data, uint32_t cx, uint32_t cy) /* --------------------------------------- */ gs_ortho(0.0f, float(ovi.base_width), 0.0f, float(ovi.base_height), - -100.0f, 100.0f); - gs_set_viewport(window->programX, window->programY, - window->programCX, window->programCY); + -100.0f, 100.0f); + gs_set_viewport(window->programX, window->programY, window->programCX, + window->programCY); - window->DrawBackdrop(float(ovi.base_width), float(ovi.base_height)); - - obs_render_main_texture(); + obs_render_main_texture_src_color_only(); gs_load_vertexbuffer(nullptr); /* --------------------------------------- */ @@ -1351,9 +1351,9 @@ void OBSBasic::ResizeProgram(uint32_t cx, uint32_t cy) /* resize program panel to fix to the top section of the window */ targetSize = GetPixelSize(program); GetScaleAndCenterPos(int(cx), int(cy), - targetSize.width() - PREVIEW_EDGE_SIZE * 2, - targetSize.height() - PREVIEW_EDGE_SIZE * 2, - programX, programY, programScale); + targetSize.width() - PREVIEW_EDGE_SIZE * 2, + targetSize.height() - PREVIEW_EDGE_SIZE * 2, + programX, programY, programScale); programX += float(PREVIEW_EDGE_SIZE); programY += float(PREVIEW_EDGE_SIZE); @@ -1371,7 +1371,8 @@ obs_data_array_t *OBSBasic::SaveTransitions() obs_data_t *sourceData = obs_data_create(); obs_data_t *settings = obs_source_get_settings(tr); - obs_data_set_string(sourceData, "name", obs_source_get_name(tr)); + obs_data_set_string(sourceData, "name", + obs_source_get_name(tr)); obs_data_set_string(sourceData, "id", obs_obj_get_id(tr)); obs_data_set_obj(sourceData, "settings", settings); @@ -1394,14 +1395,15 @@ void OBSBasic::LoadTransitions(obs_data_array_t *transitions) const char *id = obs_data_get_string(item, "id"); obs_data_t *settings = obs_data_get_obj(item, "settings"); - obs_source_t *source = obs_source_create_private(id, name, - settings); + obs_source_t *source = + obs_source_create_private(id, name, settings); if (!obs_obj_invalid(source)) { InitTransition(source); - ui->transitions->addItem(QT_UTF8(name), - QVariant::fromValue(OBSSource(source))); + ui->transitions->addItem( + QT_UTF8(name), + QVariant::fromValue(OBSSource(source))); ui->transitions->setCurrentIndex( - ui->transitions->count() - 1); + ui->transitions->count() - 1); } obs_data_release(settings); diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index 33a17d8..712c41e 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -83,15 +83,14 @@ using namespace std; struct QCef; struct QCefCookieManager; -QCef *cef = nullptr; +QCef *cef = nullptr; QCefCookieManager *panel_cookies = nullptr; void DestroyPanelCookieManager(); namespace { -template -struct SignalContainer { +template struct SignalContainer { OBSRef ref; vector> handlers; }; @@ -106,17 +105,15 @@ Q_DECLARE_METATYPE(OBSSource); Q_DECLARE_METATYPE(obs_order_movement); Q_DECLARE_METATYPE(SignalContainer); -template -static T GetOBSRef(QListWidgetItem *item) +template static T GetOBSRef(QListWidgetItem *item) { return item->data(static_cast(QtDataRole::OBSRef)).value(); } -template -static void SetOBSRef(QListWidgetItem *item, T &&val) +template static void SetOBSRef(QListWidgetItem *item, T &&val) { item->setData(static_cast(QtDataRole::OBSRef), - QVariant::fromValue(val)); + QVariant::fromValue(val)); } static void AddExtraModulePaths() @@ -124,29 +121,31 @@ static void AddExtraModulePaths() char base_module_dir[512]; #if defined(_WIN32) || defined(__APPLE__) int ret = GetProgramDataPath(base_module_dir, sizeof(base_module_dir), - "obs-studio/plugins/%module%"); + "obs-studio/plugins/%module%"); #else int ret = GetConfigPath(base_module_dir, sizeof(base_module_dir), - "obs-studio/plugins/%module%"); + "obs-studio/plugins/%module%"); #endif if (ret <= 0) return; - string path = (char*)base_module_dir; + string path = base_module_dir; #if defined(__APPLE__) obs_add_module_path((path + "/bin").c_str(), (path + "/data").c_str()); - BPtr config_bin = os_get_config_path_ptr("obs-studio/plugins/%module%/bin"); - BPtr config_data = os_get_config_path_ptr("obs-studio/plugins/%module%/data"); + BPtr config_bin = + os_get_config_path_ptr("obs-studio/plugins/%module%/bin"); + BPtr config_data = + os_get_config_path_ptr("obs-studio/plugins/%module%/data"); obs_add_module_path(config_bin, config_data); #elif ARCH_BITS == 64 obs_add_module_path((path + "/bin/64bit").c_str(), - (path + "/data").c_str()); + (path + "/data").c_str()); #else obs_add_module_path((path + "/bin/32bit").c_str(), - (path + "/data").c_str()); + (path + "/data").c_str()); #endif } @@ -156,14 +155,13 @@ static int CountVideoSources() { int count = 0; - auto countSources = [] (void *param, obs_source_t *source) - { + auto countSources = [](void *param, obs_source_t *source) { if (!source) return true; uint32_t flags = obs_source_get_output_flags(source); if ((flags & OBS_SOURCE_VIDEO) != 0) - (*reinterpret_cast(param))++; + (*reinterpret_cast(param))++; return true; }; @@ -174,23 +172,20 @@ static int CountVideoSources() void assignDockToggle(QDockWidget *dock, QAction *action) { - auto handleWindowToggle = [action] (bool vis) - { + auto handleWindowToggle = [action](bool vis) { action->blockSignals(true); action->setChecked(vis); action->blockSignals(false); }; - auto handleMenuToggle = [dock] (bool check) - { + auto handleMenuToggle = [dock](bool check) { dock->blockSignals(true); dock->setVisible(check); dock->blockSignals(false); }; dock->connect(dock->toggleViewAction(), &QAction::toggled, - handleWindowToggle); - dock->connect(action, &QAction::toggled, - handleMenuToggle); + handleWindowToggle); + dock->connect(action, &QAction::toggled, handleMenuToggle); } extern void RegisterTwitchAuth(); @@ -198,8 +193,7 @@ extern void RegisterMixerAuth(); extern void RegisterRestreamAuth(); OBSBasic::OBSBasic(QWidget *parent) - : OBSMainWindow (parent), - ui (new Ui::OBSBasic) + : OBSMainWindow(parent), ui(new Ui::OBSBasic) { setAttribute(Qt::WA_NativeWindow); @@ -218,7 +212,7 @@ OBSBasic::OBSBasic(QWidget *parent) api = InitializeAPIInterface(this); ui->setupUi(this); - ui->previewDisabledLabel->setVisible(false); + ui->previewDisabledWidget->setVisible(false); startingDockLayout = saveState(); @@ -235,23 +229,22 @@ OBSBasic::OBSBasic(QWidget *parent) char styleSheetPath[512]; int ret = GetProfilePath(styleSheetPath, sizeof(styleSheetPath), - "stylesheet.qss"); + "stylesheet.qss"); if (ret > 0) { if (QFile::exists(styleSheetPath)) { - QString path = QString("file:///") + - QT_UTF8(styleSheetPath); + QString path = + QString("file:///") + QT_UTF8(styleSheetPath); App()->setStyleSheet(path); } } - qRegisterMetaType ("OBSScene"); + qRegisterMetaType("OBSScene"); qRegisterMetaType("OBSSceneItem"); - qRegisterMetaType ("OBSSource"); + qRegisterMetaType("OBSSource"); qRegisterMetaType("obs_hotkey_id"); - qRegisterMetaTypeStreamOperators< - std::vector>>( - "std::vector>"); + qRegisterMetaTypeStreamOperators>>( + "std::vector>"); qRegisterMetaTypeStreamOperators("OBSScene"); qRegisterMetaTypeStreamOperators("OBSSceneItem"); @@ -282,18 +275,22 @@ OBSBasic::OBSBasic(QWidget *parent) UpdateTitleBar(); connect(ui->scenes->itemDelegate(), - SIGNAL(closeEditor(QWidget*, - QAbstractItemDelegate::EndEditHint)), - this, - SLOT(SceneNameEdited(QWidget*, - QAbstractItemDelegate::EndEditHint))); + SIGNAL(closeEditor(QWidget *, + QAbstractItemDelegate::EndEditHint)), + this, + SLOT(SceneNameEdited(QWidget *, + QAbstractItemDelegate::EndEditHint))); cpuUsageInfo = os_cpu_usage_info_start(); cpuUsageTimer = new QTimer(this); - connect(cpuUsageTimer.data(), SIGNAL(timeout()), - ui->statusbar, SLOT(UpdateCPUUsage())); + connect(cpuUsageTimer.data(), SIGNAL(timeout()), ui->statusbar, + SLOT(UpdateCPUUsage())); cpuUsageTimer->start(3000); + diskFullTimer = new QTimer(this); + connect(diskFullTimer, SIGNAL(timeout()), this, + SLOT(CheckDiskSpaceRemaining())); + QAction *renameScene = new QAction(ui->scenesDock); renameScene->setShortcutContext(Qt::WidgetWithChildrenShortcut); connect(renameScene, SIGNAL(triggered()), this, SLOT(EditSceneName())); @@ -302,7 +299,7 @@ OBSBasic::OBSBasic(QWidget *parent) QAction *renameSource = new QAction(ui->sourcesDock); renameSource->setShortcutContext(Qt::WidgetWithChildrenShortcut); connect(renameSource, SIGNAL(triggered()), this, - SLOT(EditSceneItemName())); + SLOT(EditSceneItemName())); ui->sourcesDock->addAction(renameSource); #ifdef __APPLE__ @@ -319,8 +316,7 @@ OBSBasic::OBSBasic(QWidget *parent) renameSource->setShortcut({Qt::Key_F2}); #endif - auto addNudge = [this](const QKeySequence &seq, const char *s) - { + auto addNudge = [this](const QKeySequence &seq, const char *s) { QAction *nudge = new QAction(ui->preview); nudge->setShortcut(seq); nudge->setShortcutContext(Qt::WidgetShortcut); @@ -352,24 +348,24 @@ OBSBasic::OBSBasic(QWidget *parent) //restore parent window geometry const char *geometry = config_get_string(App()->GlobalConfig(), - "BasicWindow", "geometry"); + "BasicWindow", "geometry"); if (geometry != NULL) { - QByteArray byteArray = QByteArray::fromBase64( - QByteArray(geometry)); + QByteArray byteArray = + QByteArray::fromBase64(QByteArray(geometry)); restoreGeometry(byteArray); QRect windowGeometry = normalGeometry(); if (!WindowPositionValid(windowGeometry)) { QRect rect = App()->desktop()->geometry(); - setGeometry(QStyle::alignedRect( - Qt::LeftToRight, - Qt::AlignCenter, - size(), rect)); + setGeometry(QStyle::alignedRect(Qt::LeftToRight, + Qt::AlignCenter, size(), + rect)); } curPos = pos(); } else { - QRect desktopRect = QGuiApplication::primaryScreen()->geometry(); + QRect desktopRect = + QGuiApplication::primaryScreen()->geometry(); QSize adjSize = desktopRect.size() / 2 - size() / 2; curPos = QPoint(adjSize.width(), adjSize.height()); } @@ -382,17 +378,24 @@ OBSBasic::OBSBasic(QWidget *parent) ui->previewLabel->setProperty("themeID", "previewProgramLabels"); - bool labels = config_get_bool(GetGlobalConfig(), - "BasicWindow", "StudioModeLabels"); + bool labels = config_get_bool(GetGlobalConfig(), "BasicWindow", + "StudioModeLabels"); if (!previewProgramMode) ui->previewLabel->setHidden(true); else ui->previewLabel->setHidden(!labels); + + ui->previewDisabledWidget->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui->previewDisabledWidget, + SIGNAL(customContextMenuRequested(const QPoint &)), this, + SLOT(PreviewDisabledMenu(const QPoint &))); + connect(ui->enablePreviewButton, SIGNAL(clicked()), this, + SLOT(TogglePreview())); } static void SaveAudioDevice(const char *name, int channel, obs_data_t *parent, - vector &audioSources) + vector &audioSources) { obs_source_t *source = obs_get_output_source(channel); if (!source) @@ -409,10 +412,11 @@ static void SaveAudioDevice(const char *name, int channel, obs_data_t *parent, } static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder, - obs_data_array_t *quickTransitionData, int transitionDuration, - obs_data_array_t *transitions, - OBSScene &scene, OBSSource &curProgramScene, - obs_data_array_t *savedProjectorList) + obs_data_array_t *quickTransitionData, + int transitionDuration, + obs_data_array_t *transitions, + OBSScene &scene, OBSSource &curProgramScene, + obs_data_array_t *savedProjectorList) { obs_data_t *saveData = obs_data_create(); @@ -421,49 +425,49 @@ static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder, SaveAudioDevice(DESKTOP_AUDIO_1, 1, saveData, audioSources); SaveAudioDevice(DESKTOP_AUDIO_2, 2, saveData, audioSources); - SaveAudioDevice(AUX_AUDIO_1, 3, saveData, audioSources); - SaveAudioDevice(AUX_AUDIO_2, 4, saveData, audioSources); - SaveAudioDevice(AUX_AUDIO_3, 5, saveData, audioSources); - SaveAudioDevice(AUX_AUDIO_4, 6, saveData, audioSources); + SaveAudioDevice(AUX_AUDIO_1, 3, saveData, audioSources); + SaveAudioDevice(AUX_AUDIO_2, 4, saveData, audioSources); + SaveAudioDevice(AUX_AUDIO_3, 5, saveData, audioSources); + SaveAudioDevice(AUX_AUDIO_4, 6, saveData, audioSources); /* -------------------------------- */ /* save non-group sources */ - auto FilterAudioSources = [&](obs_source_t *source) - { + auto FilterAudioSources = [&](obs_source_t *source) { if (obs_source_is_group(source)) return false; return find(begin(audioSources), end(audioSources), source) == - end(audioSources); + end(audioSources); }; using FilterAudioSources_t = decltype(FilterAudioSources); obs_data_array_t *sourcesArray = obs_save_sources_filtered( - [](void *data, obs_source_t *source) - { - return (*static_cast(data))(source); - }, static_cast(&FilterAudioSources)); + [](void *data, obs_source_t *source) { + return (*static_cast(data))( + source); + }, + static_cast(&FilterAudioSources)); /* -------------------------------- */ /* save group sources separately */ /* saving separately ensures they won't be loaded in older versions */ obs_data_array_t *groupsArray = obs_save_sources_filtered( - [](void*, obs_source_t *source) - { - return obs_source_is_group(source); - }, nullptr); + [](void *, obs_source_t *source) { + return obs_source_is_group(source); + }, + nullptr); /* -------------------------------- */ obs_source_t *transition = obs_get_output_source(0); obs_source_t *currentScene = obs_scene_get_source(scene); - const char *sceneName = obs_source_get_name(currentScene); - const char *programName = obs_source_get_name(curProgramScene); + const char *sceneName = obs_source_get_name(currentScene); + const char *programName = obs_source_get_name(curProgramScene); - const char *sceneCollection = config_get_string(App()->GlobalConfig(), - "Basic", "SceneCollection"); + const char *sceneCollection = config_get_string( + App()->GlobalConfig(), "Basic", "SceneCollection"); obs_data_set_string(saveData, "current_scene", sceneName); obs_data_set_string(saveData, "current_program_scene", programName); @@ -478,7 +482,7 @@ static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder, obs_data_array_release(groupsArray); obs_data_set_string(saveData, "current_transition", - obs_source_get_name(transition)); + obs_source_get_name(transition)); obs_data_set_int(saveData, "transition_duration", transitionDuration); obs_source_release(transition); @@ -489,7 +493,7 @@ void OBSBasic::copyActionsDynamicProperties() { // Themes need the QAction dynamic properties for (QAction *x : ui->scenesToolbar->actions()) { - QWidget* temp = ui->scenesToolbar->widgetForAction(x); + QWidget *temp = ui->scenesToolbar->widgetForAction(x); for (QByteArray &y : x->dynamicPropertyNames()) { temp->setProperty(y, x->property(y)); @@ -497,7 +501,7 @@ void OBSBasic::copyActionsDynamicProperties() } for (QAction *x : ui->sourcesToolbar->actions()) { - QWidget* temp = ui->sourcesToolbar->widgetForAction(x); + QWidget *temp = ui->sourcesToolbar->widgetForAction(x); for (QByteArray &y : x->dynamicPropertyNames()) { temp->setProperty(y, x->property(y)); @@ -507,8 +511,8 @@ void OBSBasic::copyActionsDynamicProperties() void OBSBasic::UpdateVolumeControlsDecayRate() { - double meterDecayRate = config_get_double(basicConfig, "Audio", - "MeterDecayRate"); + double meterDecayRate = + config_get_double(basicConfig, "Audio", "MeterDecayRate"); for (size_t i = 0; i < volumes.size(); i++) { volumes[i]->SetMeterDecayRate(meterDecayRate); @@ -517,8 +521,8 @@ void OBSBasic::UpdateVolumeControlsDecayRate() void OBSBasic::UpdateVolumeControlsPeakMeterType() { - uint32_t peakMeterTypeIdx = config_get_uint(basicConfig, "Audio", - "PeakMeterType"); + uint32_t peakMeterTypeIdx = + config_get_uint(basicConfig, "Audio", "PeakMeterType"); enum obs_peak_meter_type peakMeterType; switch (peakMeterTypeIdx) { @@ -553,7 +557,7 @@ obs_data_array_t *OBSBasic::SaveSceneListOrder() for (int i = 0; i < ui->scenes->count(); i++) { obs_data_t *data = obs_data_create(); obs_data_set_string(data, "name", - QT_TO_UTF8(ui->scenes->item(i)->text())); + QT_TO_UTF8(ui->scenes->item(i)->text())); obs_data_array_push_back(sceneOrder, data); obs_data_release(data); } @@ -584,9 +588,9 @@ obs_data_array_t *OBSBasic::SaveProjectors() } obs_data_set_int(data, "monitor", projector->GetMonitor()); obs_data_set_int(data, "type", static_cast(type)); - obs_data_set_string(data, "geometry", - projector->saveGeometry().toBase64() - .constData()); + obs_data_set_string( + data, "geometry", + projector->saveGeometry().toBase64().constData()); obs_data_array_push_back(savedProjectors, data); obs_data_release(data); }; @@ -611,19 +615,19 @@ void OBSBasic::Save(const char *file) obs_data_array_t *transitions = SaveTransitions(); obs_data_array_t *quickTrData = SaveQuickTransitions(); obs_data_array_t *savedProjectorList = SaveProjectors(); - obs_data_t *saveData = GenerateSaveData(sceneOrder, quickTrData, - ui->transitionDuration->value(), transitions, - scene, curProgramScene, savedProjectorList); + obs_data_t *saveData = GenerateSaveData( + sceneOrder, quickTrData, ui->transitionDuration->value(), + transitions, scene, curProgramScene, savedProjectorList); obs_data_set_bool(saveData, "preview_locked", ui->preview->Locked()); obs_data_set_bool(saveData, "scaling_enabled", - ui->preview->IsFixedScaling()); + ui->preview->IsFixedScaling()); obs_data_set_int(saveData, "scaling_level", - ui->preview->GetScalingLevel()); + ui->preview->GetScalingLevel()); obs_data_set_double(saveData, "scaling_off_x", - ui->preview->GetScrollX()); + ui->preview->GetScrollX()); obs_data_set_double(saveData, "scaling_off_y", - ui->preview->GetScrollY()); + ui->preview->GetScrollY()); if (api) { obs_data_t *moduleObj = obs_data_create(); @@ -691,14 +695,14 @@ static inline bool HasAudioDevices(const char *source_id) void OBSBasic::CreateFirstRunSources() { bool hasDesktopAudio = HasAudioDevices(App()->OutputAudioSource()); - bool hasInputAudio = HasAudioDevices(App()->InputAudioSource()); + bool hasInputAudio = HasAudioDevices(App()->InputAudioSource()); if (hasDesktopAudio) ResetAudioDevice(App()->OutputAudioSource(), "default", - Str("Basic.DesktopDevice1"), 1); + Str("Basic.DesktopDevice1"), 1); if (hasInputAudio) ResetAudioDevice(App()->InputAudioSource(), "default", - Str("Basic.AuxDevice1"), 3); + Str("Basic.AuxDevice1"), 3); } void OBSBasic::CreateDefaultScene(bool firstStart) @@ -711,7 +715,7 @@ void OBSBasic::CreateDefaultScene(bool firstStart) ui->transitionDuration->setValue(300); SetTransition(fadeTransition); - obs_scene_t *scene = obs_scene_create(Str("Basic.Scene")); + obs_scene_t *scene = obs_scene_create(Str("Basic.Scene")); if (firstStart) CreateFirstRunSources(); @@ -765,10 +769,10 @@ void OBSBasic::LoadSavedProjectors(obs_data_array_t *array) SavedProjectorInfo *info = new SavedProjectorInfo(); info->monitor = obs_data_get_int(data, "monitor"); - info->type = static_cast(obs_data_get_int(data, - "type")); - info->geometry = std::string( - obs_data_get_string(data, "geometry")); + info->type = static_cast( + obs_data_get_int(data, "type")); + info->geometry = + std::string(obs_data_get_string(data, "geometry")); info->name = std::string(obs_data_get_string(data, "name")); savedProjectorsArray.emplace_back(info); @@ -776,7 +780,7 @@ void OBSBasic::LoadSavedProjectors(obs_data_array_t *array) } } -static void LogFilter(obs_source_t*, obs_source_t *filter, void *v_val) +static void LogFilter(obs_source_t *, obs_source_t *filter, void *v_val) { const char *name = obs_source_get_name(filter); const char *id = obs_source_get_id(filter); @@ -789,7 +793,7 @@ static void LogFilter(obs_source_t*, obs_source_t *filter, void *v_val) blog(LOG_INFO, "%s- filter: '%s' (%s)", indent.c_str(), name, id); } -static bool LogSceneItem(obs_scene_t*, obs_sceneitem_t *item, void *v_val) +static bool LogSceneItem(obs_scene_t *, obs_sceneitem_t *item, void *v_val) { obs_source_t *source = obs_sceneitem_get_source(item); const char *name = obs_source_get_name(source); @@ -808,15 +812,17 @@ static bool LogSceneItem(obs_scene_t*, obs_sceneitem_t *item, void *v_val) if (monitoring_type != OBS_MONITORING_TYPE_NONE) { const char *type = (monitoring_type == OBS_MONITORING_TYPE_MONITOR_ONLY) - ? "monitor only" - : "monitor and output"; + ? "monitor only" + : "monitor and output"; blog(LOG_INFO, " %s- monitoring: %s", indent.c_str(), type); } int child_indent = 1 + indent_count; - obs_source_enum_filters(source, LogFilter, (void*)(intptr_t)child_indent); + obs_source_enum_filters(source, LogFilter, + (void *)(intptr_t)child_indent); if (obs_sceneitem_is_group(item)) - obs_sceneitem_group_enum_items(item, LogSceneItem, (void*)(intptr_t)child_indent); + obs_sceneitem_group_enum_items(item, LogSceneItem, + (void *)(intptr_t)child_indent); return true; } @@ -833,8 +839,8 @@ void OBSBasic::LogScenes() const char *name = obs_source_get_name(source); blog(LOG_INFO, "- scene '%s':", name); - obs_scene_enum_items(scene, LogSceneItem, (void*)(intptr_t)1); - obs_source_enum_filters(source, LogFilter, (void*)(intptr_t)1); + obs_scene_enum_items(scene, LogSceneItem, (void *)(intptr_t)1); + obs_source_enum_filters(source, LogFilter, (void *)(intptr_t)1); } blog(LOG_INFO, "------------------------------------------------"); @@ -861,15 +867,14 @@ void OBSBasic::Load(const char *file) api->on_preload(modulesObj); obs_data_array_t *sceneOrder = obs_data_get_array(data, "scene_order"); - obs_data_array_t *sources = obs_data_get_array(data, "sources"); - obs_data_array_t *groups = obs_data_get_array(data, "groups"); - obs_data_array_t *transitions= obs_data_get_array(data, "transitions"); - const char *sceneName = obs_data_get_string(data, - "current_scene"); - const char *programSceneName = obs_data_get_string(data, - "current_program_scene"); - const char *transitionName = obs_data_get_string(data, - "current_transition"); + obs_data_array_t *sources = obs_data_get_array(data, "sources"); + obs_data_array_t *groups = obs_data_get_array(data, "groups"); + obs_data_array_t *transitions = obs_data_get_array(data, "transitions"); + const char *sceneName = obs_data_get_string(data, "current_scene"); + const char *programSceneName = + obs_data_get_string(data, "current_program_scene"); + const char *transitionName = + obs_data_get_string(data, "current_transition"); if (!opt_starting_scene.empty()) { programSceneName = opt_starting_scene.c_str(); @@ -885,24 +890,24 @@ void OBSBasic::Load(const char *file) transitionName = obs_source_get_name(fadeTransition); const char *curSceneCollection = config_get_string( - App()->GlobalConfig(), "Basic", "SceneCollection"); + App()->GlobalConfig(), "Basic", "SceneCollection"); obs_data_set_default_string(data, "name", curSceneCollection); - const char *name = obs_data_get_string(data, "name"); - obs_source_t *curScene; - obs_source_t *curProgramScene; - obs_source_t *curTransition; + const char *name = obs_data_get_string(data, "name"); + obs_source_t *curScene; + obs_source_t *curProgramScene; + obs_source_t *curTransition; if (!name || !*name) name = curSceneCollection; LoadAudioDevice(DESKTOP_AUDIO_1, 1, data); LoadAudioDevice(DESKTOP_AUDIO_2, 2, data); - LoadAudioDevice(AUX_AUDIO_1, 3, data); - LoadAudioDevice(AUX_AUDIO_2, 4, data); - LoadAudioDevice(AUX_AUDIO_3, 5, data); - LoadAudioDevice(AUX_AUDIO_4, 6, data); + LoadAudioDevice(AUX_AUDIO_1, 3, data); + LoadAudioDevice(AUX_AUDIO_2, 4, data); + LoadAudioDevice(AUX_AUDIO_3, 5, data); + LoadAudioDevice(AUX_AUDIO_4, 6, data); if (!sources) { sources = groups; @@ -935,8 +940,8 @@ retryScene: * fall back to original settings */ if (!opt_starting_scene.empty() && (!curScene || !curProgramScene)) { sceneName = obs_data_get_string(data, "current_scene"); - programSceneName = obs_data_get_string(data, - "current_program_scene"); + programSceneName = + obs_data_get_string(data, "current_program_scene"); obs_source_release(curScene); obs_source_release(curProgramScene); opt_starting_scene.clear(); @@ -961,11 +966,11 @@ retryScene: /* ------------------- */ bool projectorSave = config_get_bool(GetGlobalConfig(), "BasicWindow", - "SaveProjectors"); + "SaveProjectors"); if (projectorSave) { - obs_data_array_t *savedProjectors = obs_data_get_array(data, - "saved_projectors"); + obs_data_array_t *savedProjectors = + obs_data_get_array(data, "saved_projectors"); if (savedProjectors) { LoadSavedProjectors(savedProjectors); @@ -982,12 +987,12 @@ retryScene: file_base.erase(file_base.size() - 5, 5); config_set_string(App()->GlobalConfig(), "Basic", "SceneCollection", - name); + name); config_set_string(App()->GlobalConfig(), "Basic", "SceneCollectionFile", - file_base.c_str()); + file_base.c_str()); - obs_data_array_t *quickTransitionData = obs_data_get_array(data, - "quick_transitions"); + obs_data_array_t *quickTransitionData = + obs_data_get_array(data, "quick_transitions"); LoadQuickTransitions(quickTransitionData); obs_data_array_release(quickTransitionData); @@ -1024,20 +1029,21 @@ retryScene: if (opt_start_streaming) { blog(LOG_INFO, "Starting stream due to command line parameter"); QMetaObject::invokeMethod(this, "StartStreaming", - Qt::QueuedConnection); + Qt::QueuedConnection); opt_start_streaming = false; } if (opt_start_recording) { - blog(LOG_INFO, "Starting recording due to command line parameter"); + blog(LOG_INFO, + "Starting recording due to command line parameter"); QMetaObject::invokeMethod(this, "StartRecording", - Qt::QueuedConnection); + Qt::QueuedConnection); opt_start_recording = false; } if (opt_start_replaybuffer) { QMetaObject::invokeMethod(this, "StartReplayBuffer", - Qt::QueuedConnection); + Qt::QueuedConnection); opt_start_replaybuffer = false; } @@ -1063,11 +1069,11 @@ void OBSBasic::SaveService() char serviceJsonPath[512]; int ret = GetProfilePath(serviceJsonPath, sizeof(serviceJsonPath), - SERVICE_PATH); + SERVICE_PATH); if (ret <= 0) return; - obs_data_t *data = obs_data_create(); + obs_data_t *data = obs_data_create(); obs_data_t *settings = obs_service_get_settings(service); obs_data_set_string(data, "type", obs_service_get_type(service)); @@ -1086,12 +1092,12 @@ bool OBSBasic::LoadService() char serviceJsonPath[512]; int ret = GetProfilePath(serviceJsonPath, sizeof(serviceJsonPath), - SERVICE_PATH); + SERVICE_PATH); if (ret <= 0) return false; - obs_data_t *data = obs_data_create_from_json_file_safe(serviceJsonPath, - "bak"); + obs_data_t *data = + obs_data_create_from_json_file_safe(serviceJsonPath, "bak"); obs_data_set_default_string(data, "type", "rtmp_common"); type = obs_data_get_string(data, "type"); @@ -1100,7 +1106,7 @@ bool OBSBasic::LoadService() obs_data_t *hotkey_data = obs_data_get_obj(data, "hotkeys"); service = obs_service_create(type, "default_service", settings, - hotkey_data); + hotkey_data); obs_service_release(service); obs_data_release(hotkey_data); @@ -1118,7 +1124,7 @@ bool OBSBasic::InitService() return true; service = obs_service_create("rtmp_common", "default_service", nullptr, - nullptr); + nullptr); if (!service) return false; obs_service_release(service); @@ -1126,31 +1132,19 @@ bool OBSBasic::InitService() return true; } -static const double scaled_vals[] = -{ - 1.0, - 1.25, - (1.0/0.75), - 1.5, - (1.0/0.6), - 1.75, - 2.0, - 2.25, - 2.5, - 2.75, - 3.0, - 0.0 -}; +static const double scaled_vals[] = {1.0, 1.25, (1.0 / 0.75), 1.5, + (1.0 / 0.6), 1.75, 2.0, 2.25, + 2.5, 2.75, 3.0, 0.0}; extern void CheckExistingCookieId(); bool OBSBasic::InitBasicConfigDefaults() { - QList screens = QGuiApplication::screens(); + QList screens = QGuiApplication::screens(); if (!screens.size()) { OBSErrorBox(NULL, "There appears to be no monitors. Er, this " - "technically shouldn't be possible."); + "technically shouldn't be possible."); return false; } @@ -1159,8 +1153,8 @@ bool OBSBasic::InitBasicConfigDefaults() uint32_t cx = primaryScreen->size().width(); uint32_t cy = primaryScreen->size().height(); - bool oldResolutionDefaults = config_get_bool(App()->GlobalConfig(), - "General", "Pre19Defaults"); + bool oldResolutionDefaults = config_get_bool( + App()->GlobalConfig(), "General", "Pre19Defaults"); /* use 1920x1080 for new default base res if main monitor is above * 1920x1080, but don't apply for people from older builds -- only to @@ -1178,9 +1172,9 @@ bool OBSBasic::InitBasicConfigDefaults() !config_has_user_value(basicConfig, "AdvOut", "Pre22.1Settings")) { int track = (int)config_get_int(basicConfig, "AdvOut", - "FFAudioTrack"); + "FFAudioTrack"); config_set_int(basicConfig, "AdvOut", "FFAudioMixes", - 1LL << (track - 1)); + 1LL << (track - 1)); config_set_bool(basicConfig, "AdvOut", "Pre22.1Settings", true); changed = true; } @@ -1190,8 +1184,8 @@ bool OBSBasic::InitBasicConfigDefaults() if (config_has_user_value(basicConfig, "AdvOut", "RecTrackIndex") && !config_has_user_value(basicConfig, "AdvOut", "RecTracks")) { - uint64_t track = config_get_uint(basicConfig, "AdvOut", - "RecTrackIndex"); + uint64_t track = + config_get_uint(basicConfig, "AdvOut", "RecTrackIndex"); track = 1ULL << (track - 1); config_set_uint(basicConfig, "AdvOut", "RecTracks", track); config_remove_value(basicConfig, "AdvOut", "RecTrackIndex"); @@ -1208,72 +1202,66 @@ bool OBSBasic::InitBasicConfigDefaults() config_set_default_string(basicConfig, "Output", "Mode", "Simple"); config_set_default_string(basicConfig, "SimpleOutput", "FilePath", - GetDefaultVideoSavePath().c_str()); + GetDefaultVideoSavePath().c_str()); config_set_default_string(basicConfig, "SimpleOutput", "RecFormat", - "flv"); - config_set_default_uint (basicConfig, "SimpleOutput", "VBitrate", - 2500); - config_set_default_uint (basicConfig, "SimpleOutput", "ABitrate", 160); - config_set_default_bool (basicConfig, "SimpleOutput", "UseAdvanced", - false); - config_set_default_bool (basicConfig, "SimpleOutput", "EnforceBitrate", - true); + "mkv"); + config_set_default_uint(basicConfig, "SimpleOutput", "VBitrate", 2500); + config_set_default_uint(basicConfig, "SimpleOutput", "ABitrate", 160); + config_set_default_bool(basicConfig, "SimpleOutput", "UseAdvanced", + false); + config_set_default_bool(basicConfig, "SimpleOutput", "EnforceBitrate", + true); config_set_default_string(basicConfig, "SimpleOutput", "Preset", - "veryfast"); + "veryfast"); config_set_default_string(basicConfig, "SimpleOutput", "NVENCPreset", - "hq"); + "hq"); config_set_default_string(basicConfig, "SimpleOutput", "RecQuality", - "Stream"); + "Stream"); config_set_default_bool(basicConfig, "SimpleOutput", "RecRB", false); config_set_default_int(basicConfig, "SimpleOutput", "RecRBTime", 20); config_set_default_int(basicConfig, "SimpleOutput", "RecRBSize", 512); config_set_default_string(basicConfig, "SimpleOutput", "RecRBPrefix", - "Replay"); + "Replay"); - config_set_default_bool (basicConfig, "AdvOut", "ApplyServiceSettings", - true); - config_set_default_bool (basicConfig, "AdvOut", "UseRescale", false); - config_set_default_uint (basicConfig, "AdvOut", "TrackIndex", 1); + config_set_default_bool(basicConfig, "AdvOut", "ApplyServiceSettings", + true); + config_set_default_bool(basicConfig, "AdvOut", "UseRescale", false); + config_set_default_uint(basicConfig, "AdvOut", "TrackIndex", 1); config_set_default_string(basicConfig, "AdvOut", "Encoder", "obs_x264"); config_set_default_string(basicConfig, "AdvOut", "RecType", "Standard"); config_set_default_string(basicConfig, "AdvOut", "RecFilePath", - GetDefaultVideoSavePath().c_str()); - config_set_default_string(basicConfig, "AdvOut", "RecFormat", "flv"); - config_set_default_bool (basicConfig, "AdvOut", "RecUseRescale", - false); - config_set_default_uint (basicConfig, "AdvOut", "RecTracks", (1<<0)); - config_set_default_string(basicConfig, "AdvOut", "RecEncoder", - "none"); + GetDefaultVideoSavePath().c_str()); + config_set_default_string(basicConfig, "AdvOut", "RecFormat", "mkv"); + config_set_default_bool(basicConfig, "AdvOut", "RecUseRescale", false); + config_set_default_uint(basicConfig, "AdvOut", "RecTracks", (1 << 0)); + config_set_default_string(basicConfig, "AdvOut", "RecEncoder", "none"); - config_set_default_bool (basicConfig, "AdvOut", "FFOutputToFile", - true); + config_set_default_bool(basicConfig, "AdvOut", "FFOutputToFile", true); config_set_default_string(basicConfig, "AdvOut", "FFFilePath", - GetDefaultVideoSavePath().c_str()); + GetDefaultVideoSavePath().c_str()); config_set_default_string(basicConfig, "AdvOut", "FFExtension", "mp4"); - config_set_default_uint (basicConfig, "AdvOut", "FFVBitrate", 2500); - config_set_default_uint (basicConfig, "AdvOut", "FFVGOPSize", 250); - config_set_default_bool (basicConfig, "AdvOut", "FFUseRescale", - false); - config_set_default_bool (basicConfig, "AdvOut", "FFIgnoreCompat", - false); - config_set_default_uint (basicConfig, "AdvOut", "FFABitrate", 160); - config_set_default_uint (basicConfig, "AdvOut", "FFAudioMixes", 1); + config_set_default_uint(basicConfig, "AdvOut", "FFVBitrate", 2500); + config_set_default_uint(basicConfig, "AdvOut", "FFVGOPSize", 250); + config_set_default_bool(basicConfig, "AdvOut", "FFUseRescale", false); + config_set_default_bool(basicConfig, "AdvOut", "FFIgnoreCompat", false); + config_set_default_uint(basicConfig, "AdvOut", "FFABitrate", 160); + config_set_default_uint(basicConfig, "AdvOut", "FFAudioMixes", 1); - config_set_default_uint (basicConfig, "AdvOut", "Track1Bitrate", 160); - config_set_default_uint (basicConfig, "AdvOut", "Track2Bitrate", 160); - config_set_default_uint (basicConfig, "AdvOut", "Track3Bitrate", 160); - config_set_default_uint (basicConfig, "AdvOut", "Track4Bitrate", 160); - config_set_default_uint (basicConfig, "AdvOut", "Track5Bitrate", 160); - config_set_default_uint (basicConfig, "AdvOut", "Track6Bitrate", 160); + config_set_default_uint(basicConfig, "AdvOut", "Track1Bitrate", 160); + config_set_default_uint(basicConfig, "AdvOut", "Track2Bitrate", 160); + config_set_default_uint(basicConfig, "AdvOut", "Track3Bitrate", 160); + config_set_default_uint(basicConfig, "AdvOut", "Track4Bitrate", 160); + config_set_default_uint(basicConfig, "AdvOut", "Track5Bitrate", 160); + config_set_default_uint(basicConfig, "AdvOut", "Track6Bitrate", 160); - config_set_default_bool (basicConfig, "AdvOut", "RecRB", false); - config_set_default_uint (basicConfig, "AdvOut", "RecRBTime", 20); - config_set_default_int (basicConfig, "AdvOut", "RecRBSize", 512); + config_set_default_bool(basicConfig, "AdvOut", "RecRB", false); + config_set_default_uint(basicConfig, "AdvOut", "RecRBTime", 20); + config_set_default_int(basicConfig, "AdvOut", "RecRBSize", 512); - config_set_default_uint (basicConfig, "Video", "BaseCX", cx); - config_set_default_uint (basicConfig, "Video", "BaseCY", cy); + config_set_default_uint(basicConfig, "Video", "BaseCX", cx); + config_set_default_uint(basicConfig, "Video", "BaseCY", cy); /* don't allow BaseCX/BaseCY to be susceptible to defaults changing */ if (!config_has_user_value(basicConfig, "Video", "BaseCX") || @@ -1284,21 +1272,21 @@ bool OBSBasic::InitBasicConfigDefaults() } config_set_default_string(basicConfig, "Output", "FilenameFormatting", - "%CCYY-%MM-%DD %hh-%mm-%ss"); + "%CCYY-%MM-%DD %hh-%mm-%ss"); - config_set_default_bool (basicConfig, "Output", "DelayEnable", false); - config_set_default_uint (basicConfig, "Output", "DelaySec", 20); - config_set_default_bool (basicConfig, "Output", "DelayPreserve", true); + config_set_default_bool(basicConfig, "Output", "DelayEnable", false); + config_set_default_uint(basicConfig, "Output", "DelaySec", 20); + config_set_default_bool(basicConfig, "Output", "DelayPreserve", true); - config_set_default_bool (basicConfig, "Output", "Reconnect", true); - config_set_default_uint (basicConfig, "Output", "RetryDelay", 10); - config_set_default_uint (basicConfig, "Output", "MaxRetries", 20); + config_set_default_bool(basicConfig, "Output", "Reconnect", true); + config_set_default_uint(basicConfig, "Output", "RetryDelay", 10); + config_set_default_uint(basicConfig, "Output", "MaxRetries", 20); config_set_default_string(basicConfig, "Output", "BindIP", "default"); - config_set_default_bool (basicConfig, "Output", "NewSocketLoopEnable", - false); - config_set_default_bool (basicConfig, "Output", "LowLatencyEnable", - false); + config_set_default_bool(basicConfig, "Output", "NewSocketLoopEnable", + false); + config_set_default_bool(basicConfig, "Output", "LowLatencyEnable", + false); int i = 0; uint32_t scale_cx = cx; @@ -1312,8 +1300,8 @@ bool OBSBasic::InitBasicConfigDefaults() scale_cy = uint32_t(double(cy) / scale); } - config_set_default_uint (basicConfig, "Video", "OutputCX", scale_cx); - config_set_default_uint (basicConfig, "Video", "OutputCY", scale_cy); + config_set_default_uint(basicConfig, "Video", "OutputCX", scale_cx); + config_set_default_uint(basicConfig, "Video", "OutputCY", scale_cy); /* don't allow OutputCX/OutputCY to be susceptible to defaults * changing */ @@ -1324,28 +1312,29 @@ bool OBSBasic::InitBasicConfigDefaults() config_save_safe(basicConfig, "tmp", nullptr); } - config_set_default_uint (basicConfig, "Video", "FPSType", 0); + config_set_default_uint(basicConfig, "Video", "FPSType", 0); config_set_default_string(basicConfig, "Video", "FPSCommon", "30"); - config_set_default_uint (basicConfig, "Video", "FPSInt", 30); - config_set_default_uint (basicConfig, "Video", "FPSNum", 30); - config_set_default_uint (basicConfig, "Video", "FPSDen", 1); + config_set_default_uint(basicConfig, "Video", "FPSInt", 30); + config_set_default_uint(basicConfig, "Video", "FPSNum", 30); + config_set_default_uint(basicConfig, "Video", "FPSDen", 1); config_set_default_string(basicConfig, "Video", "ScaleType", "bicubic"); config_set_default_string(basicConfig, "Video", "ColorFormat", "NV12"); config_set_default_string(basicConfig, "Video", "ColorSpace", "601"); config_set_default_string(basicConfig, "Video", "ColorRange", - "Partial"); + "Partial"); config_set_default_string(basicConfig, "Audio", "MonitoringDeviceId", - "default"); - config_set_default_string(basicConfig, "Audio", "MonitoringDeviceName", - Str("Basic.Settings.Advanced.Audio.MonitoringDevice" - ".Default")); - config_set_default_uint (basicConfig, "Audio", "SampleRate", 44100); + "default"); + config_set_default_string( + basicConfig, "Audio", "MonitoringDeviceName", + Str("Basic.Settings.Advanced.Audio.MonitoringDevice" + ".Default")); + config_set_default_uint(basicConfig, "Audio", "SampleRate", 44100); config_set_default_string(basicConfig, "Audio", "ChannelSetup", - "Stereo"); + "Stereo"); config_set_default_double(basicConfig, "Audio", "MeterDecayRate", - VOLUME_METER_DECAY_FAST); - config_set_default_uint (basicConfig, "Audio", "PeakMeterType", 0); + VOLUME_METER_DECAY_FAST); + config_set_default_uint(basicConfig, "Audio", "PeakMeterType", 0); CheckExistingCookieId(); @@ -1356,14 +1345,16 @@ extern bool EncoderAvailable(const char *encoder); void OBSBasic::InitBasicConfigDefaults2() { - bool oldEncDefaults = config_get_bool(App()->GlobalConfig(), - "General", "Pre23Defaults"); + bool oldEncDefaults = config_get_bool(App()->GlobalConfig(), "General", + "Pre23Defaults"); bool useNV = EncoderAvailable("ffmpeg_nvenc") && !oldEncDefaults; config_set_default_string(basicConfig, "SimpleOutput", "StreamEncoder", - useNV ? SIMPLE_ENCODER_NVENC : SIMPLE_ENCODER_X264); + useNV ? SIMPLE_ENCODER_NVENC + : SIMPLE_ENCODER_X264); config_set_default_string(basicConfig, "SimpleOutput", "RecEncoder", - useNV ? SIMPLE_ENCODER_NVENC : SIMPLE_ENCODER_X264); + useNV ? SIMPLE_ENCODER_NVENC + : SIMPLE_ENCODER_X264); } bool OBSBasic::InitBasicConfig() @@ -1397,7 +1388,7 @@ bool OBSBasic::InitBasicConfig() if (config_get_string(basicConfig, "General", "Name") == nullptr) { const char *curName = config_get_string(App()->GlobalConfig(), - "Basic", "Profile"); + "Basic", "Profile"); config_set_string(basicConfig, "General", "Name", curName); basicConfig.SaveSafe("tmp"); @@ -1412,15 +1403,22 @@ void OBSBasic::InitOBSCallbacks() signalHandlers.reserve(signalHandlers.size() + 6); signalHandlers.emplace_back(obs_get_signal_handler(), "source_create", - OBSBasic::SourceCreated, this); + OBSBasic::SourceCreated, this); signalHandlers.emplace_back(obs_get_signal_handler(), "source_remove", - OBSBasic::SourceRemoved, this); + OBSBasic::SourceRemoved, this); signalHandlers.emplace_back(obs_get_signal_handler(), "source_activate", - OBSBasic::SourceActivated, this); - signalHandlers.emplace_back(obs_get_signal_handler(), "source_deactivate", - OBSBasic::SourceDeactivated, this); + OBSBasic::SourceActivated, this); + signalHandlers.emplace_back(obs_get_signal_handler(), + "source_deactivate", + OBSBasic::SourceDeactivated, this); + signalHandlers.emplace_back(obs_get_signal_handler(), + "source_audio_activate", + OBSBasic::SourceAudioActivated, this); + signalHandlers.emplace_back(obs_get_signal_handler(), + "source_audio_deactivate", + OBSBasic::SourceAudioDeactivated, this); signalHandlers.emplace_back(obs_get_signal_handler(), "source_rename", - OBSBasic::SourceRenamed, this); + OBSBasic::SourceRenamed, this); } void OBSBasic::InitPrimitives() @@ -1458,7 +1456,7 @@ void OBSBasic::InitPrimitives() boxBottom = gs_render_save(); gs_render_start(true); - for (int i = 0; i <= 360; i += (360/20)) { + for (int i = 0; i <= 360; i += (360 / 20)) { float pos = RAD(float(i)); gs_vertex2f(cosf(pos), sinf(pos)); } @@ -1484,47 +1482,45 @@ void OBSBasic::ResetOutputs() if (!outputHandler || !outputHandler->Active()) { outputHandler.reset(); - outputHandler.reset(advOut ? - CreateAdvancedOutputHandler(this) : - CreateSimpleOutputHandler(this)); + outputHandler.reset(advOut ? CreateAdvancedOutputHandler(this) + : CreateSimpleOutputHandler(this)); delete replayBufferButton; if (outputHandler->replayBuffer) { replayBufferButton = new QPushButton( - QTStr("Basic.Main.StartReplayBuffer"), - this); + QTStr("Basic.Main.StartReplayBuffer"), this); replayBufferButton->setCheckable(true); connect(replayBufferButton.data(), - &QPushButton::clicked, - this, - &OBSBasic::ReplayBufferClicked); + &QPushButton::clicked, this, + &OBSBasic::ReplayBufferClicked); - replayBufferButton->setProperty("themeID", "replayBufferButton"); + replayBufferButton->setProperty("themeID", + "replayBufferButton"); ui->buttonsVLayout->insertWidget(2, replayBufferButton); } if (sysTrayReplayBuffer) sysTrayReplayBuffer->setEnabled( - !!outputHandler->replayBuffer); + !!outputHandler->replayBuffer); } else { outputHandler->Update(); } } static void AddProjectorMenuMonitors(QMenu *parent, QObject *target, - const char *slot); + const char *slot); #define STARTUP_SEPARATOR \ "==== Startup complete ===============================================" #define SHUTDOWN_SEPARATOR \ "==== Shutting down ==================================================" -#define UNSUPPORTED_ERROR \ +#define UNSUPPORTED_ERROR \ "Failed to initialize video:\n\nRequired graphics API functionality " \ "not found. Your GPU may not be supported." -#define UNKNOWN_ERROR \ +#define UNKNOWN_ERROR \ "Failed to initialize video. Your GPU may not be supported, " \ "or your graphics drivers may need to be updated." @@ -1532,8 +1528,8 @@ void OBSBasic::OBSInit() { ProfileScope("OBSBasic::OBSInit"); - const char *sceneCollection = config_get_string(App()->GlobalConfig(), - "Basic", "SceneCollectionFile"); + const char *sceneCollection = config_get_string( + App()->GlobalConfig(), "Basic", "SceneCollectionFile"); char savePath[512]; char fileName[512]; int ret; @@ -1542,7 +1538,7 @@ void OBSBasic::OBSInit() throw "Failed to get scene collection name"; ret = snprintf(fileName, 512, "obs-studio/basic/scenes/%s.json", - sceneCollection); + sceneCollection); if (ret <= 0) throw "Failed to create scene collection file name"; @@ -1571,15 +1567,15 @@ void OBSBasic::OBSInit() /* load audio monitoring */ #if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO - const char *device_name = config_get_string(basicConfig, "Audio", - "MonitoringDeviceName"); - const char *device_id = config_get_string(basicConfig, "Audio", - "MonitoringDeviceId"); + const char *device_name = + config_get_string(basicConfig, "Audio", "MonitoringDeviceName"); + const char *device_id = + config_get_string(basicConfig, "Audio", "MonitoringDeviceId"); obs_set_audio_monitoring_device(device_name, device_id); blog(LOG_INFO, "Audio monitoring device:\n\tname: %s\n\tid: %s", - device_name, device_id); + device_name, device_id); #endif InitOBSCallbacks(); @@ -1611,29 +1607,30 @@ void OBSBasic::OBSInit() InitPrimitives(); - sceneDuplicationMode = config_get_bool(App()->GlobalConfig(), - "BasicWindow", "SceneDuplicationMode"); - swapScenesMode = config_get_bool(App()->GlobalConfig(), - "BasicWindow", "SwapScenesMode"); - editPropertiesMode = config_get_bool(App()->GlobalConfig(), - "BasicWindow", "EditPropertiesMode"); + sceneDuplicationMode = config_get_bool( + App()->GlobalConfig(), "BasicWindow", "SceneDuplicationMode"); + swapScenesMode = config_get_bool(App()->GlobalConfig(), "BasicWindow", + "SwapScenesMode"); + editPropertiesMode = config_get_bool( + App()->GlobalConfig(), "BasicWindow", "EditPropertiesMode"); if (!opt_studio_mode) { SetPreviewProgramMode(config_get_bool(App()->GlobalConfig(), - "BasicWindow", "PreviewProgramMode")); + "BasicWindow", + "PreviewProgramMode")); } else { SetPreviewProgramMode(true); opt_studio_mode = false; } -#define SET_VISIBILITY(name, control) \ - do { \ - if (config_has_user_value(App()->GlobalConfig(), \ - "BasicWindow", name)) { \ +#define SET_VISIBILITY(name, control) \ + do { \ + if (config_has_user_value(App()->GlobalConfig(), \ + "BasicWindow", name)) { \ bool visible = config_get_bool(App()->GlobalConfig(), \ - "BasicWindow", name); \ - ui->control->setChecked(visible); \ - } \ + "BasicWindow", name); \ + ui->control->setChecked(visible); \ + } \ } while (false) SET_VISIBILITY("ShowListboxToolbars", toggleListboxToolbars); @@ -1650,19 +1647,19 @@ void OBSBasic::OBSInit() TimedCheckForUpdates(); loaded = true; - previewEnabled = config_get_bool(App()->GlobalConfig(), - "BasicWindow", "PreviewEnabled"); + previewEnabled = config_get_bool(App()->GlobalConfig(), "BasicWindow", + "PreviewEnabled"); if (!previewEnabled && !IsPreviewProgramMode()) QMetaObject::invokeMethod(this, "EnablePreviewDisplay", - Qt::QueuedConnection, - Q_ARG(bool, previewEnabled)); + Qt::QueuedConnection, + Q_ARG(bool, previewEnabled)); #ifdef _WIN32 uint32_t winVer = GetWindowsVersion(); if (winVer > 0 && winVer < 0x602) { - bool disableAero = config_get_bool(basicConfig, "Video", - "DisableAero"); + bool disableAero = + config_get_bool(basicConfig, "Video", "DisableAero"); SetAeroEnabled(!disableAero); } #endif @@ -1671,10 +1668,9 @@ void OBSBasic::OBSInit() RefreshProfiles(); disableSaving--; - auto addDisplay = [this] (OBSQTDisplay *window) - { + auto addDisplay = [this](OBSQTDisplay *window) { obs_display_add_draw_callback(window->GetDisplay(), - OBSBasic::RenderMain, this); + OBSBasic::RenderMain, this); struct obs_video_info ovi; if (obs_get_video_info(&ovi)) @@ -1689,7 +1685,7 @@ void OBSBasic::OBSInit() #endif bool alwaysOnTop = config_get_bool(App()->GlobalConfig(), "BasicWindow", - "AlwaysOnTop"); + "AlwaysOnTop"); if (alwaysOnTop || opt_always_on_top) { SetAlwaysOnTop(this, true); ui->actionAlwaysOnTop->setChecked(true); @@ -1703,8 +1699,25 @@ void OBSBasic::OBSInit() OBSBasicStats *statsDlg = new OBSBasicStats(statsDock, false); statsDock->setWidget(statsDlg); - const char *dockStateStr = config_get_string(App()->GlobalConfig(), - "BasicWindow", "DockState"); + /* ----------------------------- */ + /* add custom browser docks */ + +#ifdef BROWSER_AVAILABLE + if (cef) { + QAction *action = new QAction(QTStr("Basic.MainMenu." + "View.Docks." + "CustomBrowserDocks")); + ui->viewMenuDocks->insertAction(ui->toggleScenes, action); + connect(action, &QAction::triggered, this, + &OBSBasic::ManageExtraBrowserDocks); + ui->viewMenuDocks->insertSeparator(ui->toggleScenes); + + LoadExtraBrowserDocks(); + } +#endif + + const char *dockStateStr = config_get_string( + App()->GlobalConfig(), "BasicWindow", "DockState"); if (!dockStateStr) { on_resetUI_triggered(); } else { @@ -1714,22 +1727,22 @@ void OBSBasic::OBSInit() on_resetUI_triggered(); } - bool pre23Defaults = config_get_bool(App()->GlobalConfig(), - "General", "Pre23Defaults"); + bool pre23Defaults = config_get_bool(App()->GlobalConfig(), "General", + "Pre23Defaults"); if (pre23Defaults) { - bool resetDockLock23 = config_get_bool(App()->GlobalConfig(), - "General", "ResetDockLock23"); + bool resetDockLock23 = config_get_bool( + App()->GlobalConfig(), "General", "ResetDockLock23"); if (!resetDockLock23) { - config_set_bool(App()->GlobalConfig(), - "General", "ResetDockLock23", true); + config_set_bool(App()->GlobalConfig(), "General", + "ResetDockLock23", true); config_remove_value(App()->GlobalConfig(), - "BasicWindow", "DocksLocked"); + "BasicWindow", "DocksLocked"); config_save_safe(App()->GlobalConfig(), "tmp", nullptr); } } - bool docksLocked = config_get_bool(App()->GlobalConfig(), - "BasicWindow", "DocksLocked"); + bool docksLocked = config_get_bool(App()->GlobalConfig(), "BasicWindow", + "DocksLocked"); on_lockUI_toggled(docksLocked); ui->lockUI->blockSignals(true); ui->lockUI->setChecked(docksLocked); @@ -1743,9 +1756,9 @@ void OBSBasic::OBSInit() fullscreenInterface = true; bool has_last_version = config_has_user_value(App()->GlobalConfig(), - "General", "LastVersion"); - bool first_run = config_get_bool(App()->GlobalConfig(), "General", - "FirstRun"); + "General", "LastVersion"); + bool first_run = + config_get_bool(App()->GlobalConfig(), "General", "FirstRun"); if (!first_run) { config_set_bool(App()->GlobalConfig(), "General", "FirstRun", @@ -1757,23 +1770,22 @@ void OBSBasic::OBSInit() QString msg; msg = QTStr("Basic.FirstStartup.RunWizard"); - QMessageBox::StandardButton button = - OBSMessageBox::question(this, QTStr("Basic.AutoConfig"), - msg); + QMessageBox::StandardButton button = OBSMessageBox::question( + this, QTStr("Basic.AutoConfig"), msg); if (button == QMessageBox::Yes) { QMetaObject::invokeMethod(this, - "on_autoConfigure_triggered", - Qt::QueuedConnection); + "on_autoConfigure_triggered", + Qt::QueuedConnection); } else { msg = QTStr("Basic.FirstStartup.RunWizard.NoClicked"); - OBSMessageBox::information(this, - QTStr("Basic.AutoConfig"), msg); + OBSMessageBox::information( + this, QTStr("Basic.AutoConfig"), msg); } } ToggleMixerLayout(config_get_bool(App()->GlobalConfig(), "BasicWindow", - "VerticalVolControl")); + "VerticalVolControl")); if (config_get_bool(basicConfig, "General", "OpenStatsOnStartup")) on_stats_triggered(); @@ -1788,11 +1800,11 @@ void OBSBasic::OBSInit() multiviewProjectorMenu = new QMenu(QTStr("MultiviewProjector")); ui->viewMenu->addMenu(multiviewProjectorMenu); AddProjectorMenuMonitors(multiviewProjectorMenu, this, - SLOT(OpenMultiviewProjector())); + SLOT(OpenMultiviewProjector())); connect(ui->viewMenu->menuAction(), &QAction::hovered, this, - &OBSBasic::UpdateMultiviewProjectorMenu); - ui->viewMenu->addAction(QTStr("MultiviewWindowed"), - this, SLOT(OpenMultiviewWindow())); + &OBSBasic::UpdateMultiviewProjectorMenu); + ui->viewMenu->addAction(QTStr("MultiviewWindowed"), this, + SLOT(OpenMultiviewWindow())); #if !defined(_WIN32) && !defined(__APPLE__) delete ui->actionShowCrashLogs; @@ -1809,8 +1821,7 @@ void OBSBasic::OBSInit() #ifdef __APPLE__ QMetaObject::invokeMethod(this, "DeferredSysTrayLoad", - Qt::QueuedConnection, - Q_ARG(int, 10)); + Qt::QueuedConnection, Q_ARG(int, 10)); #endif } @@ -1824,8 +1835,8 @@ void OBSBasic::OnFirstLoad() if (cef) { WhatsNewInfoThread *wnit = new WhatsNewInfoThread(); if (wnit) { - connect(wnit, &WhatsNewInfoThread::Result, - this, &OBSBasic::ReceivedIntroJson); + connect(wnit, &WhatsNewInfoThread::Result, this, + &OBSBasic::ReceivedIntroJson); } if (wnit) { introCheckThread.reset(wnit); @@ -1841,8 +1852,8 @@ void OBSBasic::DeferredSysTrayLoad(int requeueCount) { if (--requeueCount > 0) { QMetaObject::invokeMethod(this, "DeferredSysTrayLoad", - Qt::QueuedConnection, - Q_ARG(int, requeueCount)); + Qt::QueuedConnection, + Q_ARG(int, requeueCount)); return; } @@ -1882,8 +1893,7 @@ void OBSBasic::ReceivedIntroJson(const QString &text) rc == OBS_RELEASE_CANDIDATE) { #else if (major == LIBOBS_API_MAJOR_VER && - minor == LIBOBS_API_MINOR_VER && - rc == 0) { + minor == LIBOBS_API_MINOR_VER && rc == 0) { #endif info_url = url; info_increment = increment; @@ -1897,10 +1907,10 @@ void OBSBasic::ReceivedIntroJson(const QString &text) #if OBS_RELEASE_CANDIDATE > 0 uint32_t lastVersion = config_get_int(App()->GlobalConfig(), "General", - "LastRCVersion"); + "LastRCVersion"); #else - uint32_t lastVersion = config_get_int(App()->GlobalConfig(), "General", - "LastVersion"); + uint32_t lastVersion = + config_get_int(App()->GlobalConfig(), "General", "LastVersion"); #endif int current_version_increment = -1; @@ -1911,19 +1921,18 @@ void OBSBasic::ReceivedIntroJson(const QString &text) if ((lastVersion & ~0xFFFF) < (LIBOBS_API_VER & ~0xFFFF)) { #endif config_set_int(App()->GlobalConfig(), "General", - "InfoIncrement", -1); + "InfoIncrement", -1); } else { current_version_increment = config_get_int( - App()->GlobalConfig(), "General", - "InfoIncrement"); + App()->GlobalConfig(), "General", "InfoIncrement"); } if (info_increment <= current_version_increment) { return; } - config_set_int(App()->GlobalConfig(), "General", - "InfoIncrement", info_increment); + config_set_int(App()->GlobalConfig(), "General", "InfoIncrement", + info_increment); /* Don't show What's New dialog for new users */ #if !defined(OBS_RELEASE_CANDIDATE) || OBS_RELEASE_CANDIDATE == 0 @@ -1932,7 +1941,7 @@ void OBSBasic::ReceivedIntroJson(const QString &text) } #endif cef->init_browser(); - ExecuteFuncSafeBlock([] {cef->wait_for_browser_init();}); + ExecuteFuncSafeBlock([] { cef->wait_for_browser_init(); }); QDialog *dlg = new QDialog(this); dlg->setAttribute(Qt::WA_DeleteOnClose, true); @@ -1948,12 +1957,11 @@ void OBSBasic::ReceivedIntroJson(const QString &text) return; } - connect(cefWidget, SIGNAL(titleChanged(const QString &)), - dlg, SLOT(setWindowTitle(const QString &))); + connect(cefWidget, SIGNAL(titleChanged(const QString &)), dlg, + SLOT(setWindowTitle(const QString &))); QPushButton *close = new QPushButton(QTStr("Close")); - connect(close, &QAbstractButton::clicked, - dlg, &QDialog::accept); + connect(close, &QAbstractButton::clicked, dlg, &QDialog::accept); QHBoxLayout *bottomLayout = new QHBoxLayout(); bottomLayout->addStretch(); @@ -1977,7 +1985,7 @@ void OBSBasic::UpdateMultiviewProjectorMenu() { multiviewProjectorMenu->clear(); AddProjectorMenuMonitors(multiviewProjectorMenu, this, - SLOT(OpenMultiviewProjector())); + SLOT(OpenMultiviewProjector())); } void OBSBasic::InitHotkeys() @@ -1985,52 +1993,53 @@ void OBSBasic::InitHotkeys() ProfileScope("OBSBasic::InitHotkeys"); struct obs_hotkeys_translations t = {}; - t.insert = Str("Hotkeys.Insert"); - t.del = Str("Hotkeys.Delete"); - t.home = Str("Hotkeys.Home"); - t.end = Str("Hotkeys.End"); - t.page_up = Str("Hotkeys.PageUp"); - t.page_down = Str("Hotkeys.PageDown"); - t.num_lock = Str("Hotkeys.NumLock"); - t.scroll_lock = Str("Hotkeys.ScrollLock"); - t.caps_lock = Str("Hotkeys.CapsLock"); - t.backspace = Str("Hotkeys.Backspace"); - t.tab = Str("Hotkeys.Tab"); - t.print = Str("Hotkeys.Print"); - t.pause = Str("Hotkeys.Pause"); - t.left = Str("Hotkeys.Left"); - t.right = Str("Hotkeys.Right"); - t.up = Str("Hotkeys.Up"); - t.down = Str("Hotkeys.Down"); + t.insert = Str("Hotkeys.Insert"); + t.del = Str("Hotkeys.Delete"); + t.home = Str("Hotkeys.Home"); + t.end = Str("Hotkeys.End"); + t.page_up = Str("Hotkeys.PageUp"); + t.page_down = Str("Hotkeys.PageDown"); + t.num_lock = Str("Hotkeys.NumLock"); + t.scroll_lock = Str("Hotkeys.ScrollLock"); + t.caps_lock = Str("Hotkeys.CapsLock"); + t.backspace = Str("Hotkeys.Backspace"); + t.tab = Str("Hotkeys.Tab"); + t.print = Str("Hotkeys.Print"); + t.pause = Str("Hotkeys.Pause"); + t.left = Str("Hotkeys.Left"); + t.right = Str("Hotkeys.Right"); + t.up = Str("Hotkeys.Up"); + t.down = Str("Hotkeys.Down"); #ifdef _WIN32 - t.meta = Str("Hotkeys.Windows"); + t.meta = Str("Hotkeys.Windows"); #else - t.meta = Str("Hotkeys.Super"); + t.meta = Str("Hotkeys.Super"); #endif - t.menu = Str("Hotkeys.Menu"); - t.space = Str("Hotkeys.Space"); - t.numpad_num = Str("Hotkeys.NumpadNum"); - t.numpad_multiply = Str("Hotkeys.NumpadMultiply"); - t.numpad_divide = Str("Hotkeys.NumpadDivide"); - t.numpad_plus = Str("Hotkeys.NumpadAdd"); - t.numpad_minus = Str("Hotkeys.NumpadSubtract"); - t.numpad_decimal = Str("Hotkeys.NumpadDecimal"); - t.apple_keypad_num = Str("Hotkeys.AppleKeypadNum"); - t.apple_keypad_multiply = Str("Hotkeys.AppleKeypadMultiply"); - t.apple_keypad_divide = Str("Hotkeys.AppleKeypadDivide"); - t.apple_keypad_plus = Str("Hotkeys.AppleKeypadAdd"); - t.apple_keypad_minus = Str("Hotkeys.AppleKeypadSubtract"); - t.apple_keypad_decimal = Str("Hotkeys.AppleKeypadDecimal"); - t.apple_keypad_equal = Str("Hotkeys.AppleKeypadEqual"); - t.mouse_num = Str("Hotkeys.MouseButton"); - t.escape = Str("Hotkeys.Escape"); + t.menu = Str("Hotkeys.Menu"); + t.space = Str("Hotkeys.Space"); + t.numpad_num = Str("Hotkeys.NumpadNum"); + t.numpad_multiply = Str("Hotkeys.NumpadMultiply"); + t.numpad_divide = Str("Hotkeys.NumpadDivide"); + t.numpad_plus = Str("Hotkeys.NumpadAdd"); + t.numpad_minus = Str("Hotkeys.NumpadSubtract"); + t.numpad_decimal = Str("Hotkeys.NumpadDecimal"); + t.apple_keypad_num = Str("Hotkeys.AppleKeypadNum"); + t.apple_keypad_multiply = Str("Hotkeys.AppleKeypadMultiply"); + t.apple_keypad_divide = Str("Hotkeys.AppleKeypadDivide"); + t.apple_keypad_plus = Str("Hotkeys.AppleKeypadAdd"); + t.apple_keypad_minus = Str("Hotkeys.AppleKeypadSubtract"); + t.apple_keypad_decimal = Str("Hotkeys.AppleKeypadDecimal"); + t.apple_keypad_equal = Str("Hotkeys.AppleKeypadEqual"); + t.mouse_num = Str("Hotkeys.MouseButton"); + t.escape = Str("Hotkeys.Escape"); obs_hotkeys_set_translations(&t); obs_hotkeys_set_audio_hotkeys_translations(Str("Mute"), Str("Unmute"), - Str("Push-to-mute"), Str("Push-to-talk")); + Str("Push-to-mute"), + Str("Push-to-talk")); - obs_hotkeys_set_sceneitem_hotkeys_translations( - Str("SceneItemShow"), Str("SceneItemHide")); + obs_hotkeys_set_sceneitem_hotkeys_translations(Str("SceneItemShow"), + Str("SceneItemHide")); obs_hotkey_enable_callback_rerouting(true); obs_hotkey_set_callback_routing_func(OBSBasic::HotkeyTriggered, this); @@ -2043,19 +2052,19 @@ void OBSBasic::ProcessHotkey(obs_hotkey_id id, bool pressed) void OBSBasic::HotkeyTriggered(void *data, obs_hotkey_id id, bool pressed) { - OBSBasic &basic = *static_cast(data); + OBSBasic &basic = *static_cast(data); QMetaObject::invokeMethod(&basic, "ProcessHotkey", - Q_ARG(obs_hotkey_id, id), Q_ARG(bool, pressed)); + Q_ARG(obs_hotkey_id, id), + Q_ARG(bool, pressed)); } void OBSBasic::CreateHotkeys() { ProfileScope("OBSBasic::CreateHotkeys"); - auto LoadHotkeyData = [&](const char *name) -> OBSData - { - const char *info = config_get_string(basicConfig, - "Hotkeys", name); + auto LoadHotkeyData = [&](const char *name) -> OBSData { + const char *info = + config_get_string(basicConfig, "Hotkeys", name); if (!info) return {}; @@ -2068,8 +2077,7 @@ void OBSBasic::CreateHotkeys() return res; }; - auto LoadHotkey = [&](obs_hotkey_id id, const char *name) - { + auto LoadHotkey = [&](obs_hotkey_id id, const char *name) { obs_data_array_t *array = obs_data_get_array(LoadHotkeyData(name), "bindings"); @@ -2078,8 +2086,7 @@ void OBSBasic::CreateHotkeys() }; auto LoadHotkeyPair = [&](obs_hotkey_pair_id id, const char *name0, - const char *name1) - { + const char *name1) { obs_data_array_t *array0 = obs_data_get_array(LoadHotkeyData(name0), "bindings"); obs_data_array_t *array1 = @@ -2090,117 +2097,116 @@ void OBSBasic::CreateHotkeys() obs_data_array_release(array1); }; -#define MAKE_CALLBACK(pred, method, log_action) \ - [](void *data, obs_hotkey_pair_id, obs_hotkey_t*, bool pressed) \ - { \ - OBSBasic &basic = *static_cast(data); \ - if ((pred) && pressed) { \ - blog(LOG_INFO, log_action " due to hotkey"); \ - method(); \ - return true; \ - } \ - return false; \ +#define MAKE_CALLBACK(pred, method, log_action) \ + [](void *data, obs_hotkey_pair_id, obs_hotkey_t *, bool pressed) { \ + OBSBasic &basic = *static_cast(data); \ + if ((pred) && pressed) { \ + blog(LOG_INFO, log_action " due to hotkey"); \ + method(); \ + return true; \ + } \ + return false; \ } streamingHotkeys = obs_hotkey_pair_register_frontend( - "OBSBasic.StartStreaming", - Str("Basic.Main.StartStreaming"), - "OBSBasic.StopStreaming", - Str("Basic.Main.StopStreaming"), - MAKE_CALLBACK(!basic.outputHandler->StreamingActive() && - basic.ui->streamButton->isEnabled(), - basic.StartStreaming, "Starting stream"), - MAKE_CALLBACK(basic.outputHandler->StreamingActive() && - basic.ui->streamButton->isEnabled(), - basic.StopStreaming, "Stopping stream"), - this, this); - LoadHotkeyPair(streamingHotkeys, - "OBSBasic.StartStreaming", "OBSBasic.StopStreaming"); + "OBSBasic.StartStreaming", Str("Basic.Main.StartStreaming"), + "OBSBasic.StopStreaming", Str("Basic.Main.StopStreaming"), + MAKE_CALLBACK(!basic.outputHandler->StreamingActive() && + basic.ui->streamButton->isEnabled(), + basic.StartStreaming, "Starting stream"), + MAKE_CALLBACK(basic.outputHandler->StreamingActive() && + basic.ui->streamButton->isEnabled(), + basic.StopStreaming, "Stopping stream"), + this, this); + LoadHotkeyPair(streamingHotkeys, "OBSBasic.StartStreaming", + "OBSBasic.StopStreaming"); - auto cb = [] (void *data, obs_hotkey_id, obs_hotkey_t*, bool pressed) - { - OBSBasic &basic = *static_cast(data); + auto cb = [](void *data, obs_hotkey_id, obs_hotkey_t *, bool pressed) { + OBSBasic &basic = *static_cast(data); if (basic.outputHandler->StreamingActive() && pressed) { basic.ForceStopStreaming(); } }; forceStreamingStopHotkey = obs_hotkey_register_frontend( - "OBSBasic.ForceStopStreaming", - Str("Basic.Main.ForceStopStreaming"), - cb, this); - LoadHotkey(forceStreamingStopHotkey, - "OBSBasic.ForceStopStreaming"); + "OBSBasic.ForceStopStreaming", + Str("Basic.Main.ForceStopStreaming"), cb, this); + LoadHotkey(forceStreamingStopHotkey, "OBSBasic.ForceStopStreaming"); recordingHotkeys = obs_hotkey_pair_register_frontend( - "OBSBasic.StartRecording", - Str("Basic.Main.StartRecording"), - "OBSBasic.StopRecording", - Str("Basic.Main.StopRecording"), - MAKE_CALLBACK(!basic.outputHandler->RecordingActive() && - !basic.ui->recordButton->isChecked(), - basic.StartRecording, "Starting recording"), - MAKE_CALLBACK(basic.outputHandler->RecordingActive() && - basic.ui->recordButton->isChecked(), - basic.StopRecording, "Stopping recording"), - this, this); - LoadHotkeyPair(recordingHotkeys, - "OBSBasic.StartRecording", "OBSBasic.StopRecording"); + "OBSBasic.StartRecording", Str("Basic.Main.StartRecording"), + "OBSBasic.StopRecording", Str("Basic.Main.StopRecording"), + MAKE_CALLBACK(!basic.outputHandler->RecordingActive() && + !basic.ui->recordButton->isChecked(), + basic.StartRecording, "Starting recording"), + MAKE_CALLBACK(basic.outputHandler->RecordingActive() && + basic.ui->recordButton->isChecked(), + basic.StopRecording, "Stopping recording"), + this, this); + LoadHotkeyPair(recordingHotkeys, "OBSBasic.StartRecording", + "OBSBasic.StopRecording"); + + pauseHotkeys = obs_hotkey_pair_register_frontend( + "OBSBasic.PauseRecording", Str("Basic.Main.PauseRecording"), + "OBSBasic.UnpauseRecording", Str("Basic.Main.UnpauseRecording"), + MAKE_CALLBACK(basic.pause && !basic.pause->isChecked(), + basic.PauseRecording, "Pausing recording"), + MAKE_CALLBACK(basic.pause && basic.pause->isChecked(), + basic.UnpauseRecording, "Unpausing recording"), + this, this); + LoadHotkeyPair(pauseHotkeys, "OBSBasic.PauseRecording", + "OBSBasic.UnpauseRecording"); replayBufHotkeys = obs_hotkey_pair_register_frontend( - "OBSBasic.StartReplayBuffer", - Str("Basic.Main.StartReplayBuffer"), - "OBSBasic.StopReplayBuffer", - Str("Basic.Main.StopReplayBuffer"), - MAKE_CALLBACK(!basic.outputHandler->ReplayBufferActive(), - basic.StartReplayBuffer, "Starting replay buffer"), - MAKE_CALLBACK(basic.outputHandler->ReplayBufferActive(), - basic.StopReplayBuffer, "Stopping replay buffer"), - this, this); - LoadHotkeyPair(replayBufHotkeys, - "OBSBasic.StartReplayBuffer", "OBSBasic.StopReplayBuffer"); + "OBSBasic.StartReplayBuffer", + Str("Basic.Main.StartReplayBuffer"), + "OBSBasic.StopReplayBuffer", Str("Basic.Main.StopReplayBuffer"), + MAKE_CALLBACK(!basic.outputHandler->ReplayBufferActive(), + basic.StartReplayBuffer, + "Starting replay buffer"), + MAKE_CALLBACK(basic.outputHandler->ReplayBufferActive(), + basic.StopReplayBuffer, "Stopping replay buffer"), + this, this); + LoadHotkeyPair(replayBufHotkeys, "OBSBasic.StartReplayBuffer", + "OBSBasic.StopReplayBuffer"); togglePreviewHotkeys = obs_hotkey_pair_register_frontend( - "OBSBasic.EnablePreview", - Str("Basic.Main.PreviewConextMenu.Enable"), - "OBSBasic.DisablePreview", - Str("Basic.Main.Preview.Disable"), - MAKE_CALLBACK(!basic.previewEnabled, - basic.EnablePreview, "Enabling preview"), - MAKE_CALLBACK(basic.previewEnabled, - basic.DisablePreview, "Disabling preview"), - this, this); - LoadHotkeyPair(togglePreviewHotkeys, - "OBSBasic.EnablePreview", "OBSBasic.DisablePreview"); + "OBSBasic.EnablePreview", + Str("Basic.Main.PreviewConextMenu.Enable"), + "OBSBasic.DisablePreview", Str("Basic.Main.Preview.Disable"), + MAKE_CALLBACK(!basic.previewEnabled, basic.EnablePreview, + "Enabling preview"), + MAKE_CALLBACK(basic.previewEnabled, basic.DisablePreview, + "Disabling preview"), + this, this); + LoadHotkeyPair(togglePreviewHotkeys, "OBSBasic.EnablePreview", + "OBSBasic.DisablePreview"); #undef MAKE_CALLBACK - auto togglePreviewProgram = [] (void *data, obs_hotkey_id, - obs_hotkey_t*, bool pressed) - { + auto togglePreviewProgram = [](void *data, obs_hotkey_id, + obs_hotkey_t *, bool pressed) { if (pressed) - QMetaObject::invokeMethod(static_cast(data), - "on_modeSwitch_clicked", - Qt::QueuedConnection); + QMetaObject::invokeMethod(static_cast(data), + "on_modeSwitch_clicked", + Qt::QueuedConnection); }; togglePreviewProgramHotkey = obs_hotkey_register_frontend( - "OBSBasic.TogglePreviewProgram", - Str("Basic.TogglePreviewProgramMode"), - togglePreviewProgram, this); + "OBSBasic.TogglePreviewProgram", + Str("Basic.TogglePreviewProgramMode"), togglePreviewProgram, + this); LoadHotkey(togglePreviewProgramHotkey, "OBSBasic.TogglePreviewProgram"); - auto transition = [] (void *data, obs_hotkey_id, obs_hotkey_t*, - bool pressed) - { + auto transition = [](void *data, obs_hotkey_id, obs_hotkey_t *, + bool pressed) { if (pressed) - QMetaObject::invokeMethod(static_cast(data), - "TransitionClicked", - Qt::QueuedConnection); + QMetaObject::invokeMethod(static_cast(data), + "TransitionClicked", + Qt::QueuedConnection); }; transitionHotkey = obs_hotkey_register_frontend( - "OBSBasic.Transition", - Str("Transition"), transition, this); + "OBSBasic.Transition", Str("Transition"), transition, this); LoadHotkey(transitionHotkey, "OBSBasic.Transition"); } @@ -2208,6 +2214,7 @@ void OBSBasic::ClearHotkeys() { obs_hotkey_pair_unregister(streamingHotkeys); obs_hotkey_pair_unregister(recordingHotkeys); + obs_hotkey_pair_unregister(pauseHotkeys); obs_hotkey_pair_unregister(replayBufHotkeys); obs_hotkey_pair_unregister(togglePreviewHotkeys); obs_hotkey_unregister(forceStreamingStopHotkey); @@ -2272,7 +2279,7 @@ OBSBasic::~OBSBasic() delete about; obs_display_remove_draw_callback(ui->preview->GetDisplay(), - OBSBasic::RenderMain, this); + OBSBasic::RenderMain, this); obs_enter_graphics(); gs_vertexbuffer_destroy(box); @@ -2293,10 +2300,10 @@ OBSBasic::~OBSBasic() QApplication::sendPostedEvents(this); config_set_int(App()->GlobalConfig(), "General", "LastVersion", - LIBOBS_API_VER); + LIBOBS_API_VER); #if OBS_RELEASE_CANDIDATE > 0 config_set_int(App()->GlobalConfig(), "General", "LastRCVersion", - OBS_RELEASE_CANDIDATE_VER); + OBS_RELEASE_CANDIDATE_VER); #endif bool alwaysOnTop = IsAlwaysOnTop(this); @@ -2307,21 +2314,21 @@ OBSBasic::~OBSBasic() alwaysOnTop); config_set_bool(App()->GlobalConfig(), "BasicWindow", "SceneDuplicationMode", sceneDuplicationMode); - config_set_bool(App()->GlobalConfig(), "BasicWindow", - "SwapScenesMode", swapScenesMode); + config_set_bool(App()->GlobalConfig(), "BasicWindow", "SwapScenesMode", + swapScenesMode); config_set_bool(App()->GlobalConfig(), "BasicWindow", "EditPropertiesMode", editPropertiesMode); config_set_bool(App()->GlobalConfig(), "BasicWindow", "PreviewProgramMode", IsPreviewProgramMode()); - config_set_bool(App()->GlobalConfig(), "BasicWindow", - "DocksLocked", ui->lockUI->isChecked()); + config_set_bool(App()->GlobalConfig(), "BasicWindow", "DocksLocked", + ui->lockUI->isChecked()); config_save_safe(App()->GlobalConfig(), "tmp", nullptr); #ifdef _WIN32 uint32_t winVer = GetWindowsVersion(); if (winVer > 0 && winVer < 0x602) { - bool disableAero = config_get_bool(basicConfig, "Video", - "DisableAero"); + bool disableAero = + config_get_bool(basicConfig, "Video", "DisableAero"); if (disableAero) { SetAeroEnabled(true); } @@ -2351,7 +2358,7 @@ void OBSBasic::SaveProject() projectChanged = true; QMetaObject::invokeMethod(this, "SaveProjectDeferred", - Qt::QueuedConnection); + Qt::QueuedConnection); } void OBSBasic::SaveProjectDeferred() @@ -2364,8 +2371,8 @@ void OBSBasic::SaveProjectDeferred() projectChanged = false; - const char *sceneCollection = config_get_string(App()->GlobalConfig(), - "Basic", "SceneCollectionFile"); + const char *sceneCollection = config_get_string( + App()->GlobalConfig(), "Basic", "SceneCollectionFile"); char savePath[512]; char fileName[512]; int ret; @@ -2374,7 +2381,7 @@ void OBSBasic::SaveProjectDeferred() return; ret = snprintf(fileName, 512, "obs-studio/basic/scenes/%s.json", - sceneCollection); + sceneCollection); if (ret <= 0) return; @@ -2422,8 +2429,9 @@ void OBSBasic::UpdatePreviewScalingMenu() ui->actionScaleWindow->setChecked(false); ui->actionScaleCanvas->setChecked(scalingAmount == 1.0f); - ui->actionScaleOutput->setChecked( - scalingAmount == float(ovi.output_width) / float(ovi.base_width)); + ui->actionScaleOutput->setChecked(scalingAmount == + float(ovi.output_width) / + float(ovi.base_width)); } void OBSBasic::CreateInteractionWindow(obs_source_t *source) @@ -2460,27 +2468,28 @@ void OBSBasic::CreateFiltersWindow(obs_source_t *source) void OBSBasic::AddScene(OBSSource source) { - const char *name = obs_source_get_name(source); + const char *name = obs_source_get_name(source); obs_scene_t *scene = obs_scene_from_source(source); QListWidgetItem *item = new QListWidgetItem(QT_UTF8(name)); SetOBSRef(item, OBSScene(scene)); ui->scenes->addItem(item); - obs_hotkey_register_source(source, "OBSBasic.SelectScene", - Str("Basic.Hotkeys.SelectScene"), - [](void *data, - obs_hotkey_id, obs_hotkey_t*, bool pressed) - { - OBSBasic *main = - reinterpret_cast(App()->GetMainWindow()); + obs_hotkey_register_source( + source, "OBSBasic.SelectScene", + Str("Basic.Hotkeys.SelectScene"), + [](void *data, obs_hotkey_id, obs_hotkey_t *, bool pressed) { + OBSBasic *main = reinterpret_cast( + App()->GetMainWindow()); - auto potential_source = static_cast(data); - auto source = obs_source_get_ref(potential_source); - if (source && pressed) - main->SetCurrentScene(source); - obs_source_release(source); - }, static_cast(source)); + auto potential_source = + static_cast(data); + auto source = obs_source_get_ref(potential_source); + if (source && pressed) + main->SetCurrentScene(source); + obs_source_release(source); + }, + static_cast(source)); signal_handler_t *handler = obs_source_get_signal_handler(source); @@ -2488,41 +2497,42 @@ void OBSBasic::AddScene(OBSSource source) container.ref = scene; container.handlers.assign({ std::make_shared(handler, "item_add", - OBSBasic::SceneItemAdded, this), + OBSBasic::SceneItemAdded, this), std::make_shared(handler, "item_select", - OBSBasic::SceneItemSelected, this), + OBSBasic::SceneItemSelected, this), std::make_shared(handler, "item_deselect", - OBSBasic::SceneItemDeselected, this), + OBSBasic::SceneItemDeselected, + this), std::make_shared(handler, "reorder", - OBSBasic::SceneReordered, this), + OBSBasic::SceneReordered, this), }); item->setData(static_cast(QtDataRole::OBSSignals), - QVariant::fromValue(container)); + QVariant::fromValue(container)); /* if the scene already has items (a duplicated scene) add them */ - auto addSceneItem = [this] (obs_sceneitem_t *item) - { + auto addSceneItem = [this](obs_sceneitem_t *item) { AddSceneItem(item); }; using addSceneItem_t = decltype(addSceneItem); - obs_scene_enum_items(scene, - [] (obs_scene_t*, obs_sceneitem_t *item, void *param) - { - addSceneItem_t *func; - func = reinterpret_cast(param); - (*func)(item); - return true; - }, &addSceneItem); + obs_scene_enum_items( + scene, + [](obs_scene_t *, obs_sceneitem_t *item, void *param) { + addSceneItem_t *func; + func = reinterpret_cast(param); + (*func)(item); + return true; + }, + &addSceneItem); SaveProject(); if (!disableSaving) { obs_source_t *source = obs_scene_get_source(scene); blog(LOG_INFO, "User added scene '%s'", - obs_source_get_name(source)); + obs_source_get_name(source)); OBSProjector::UpdateMultiviewProjectors(); } @@ -2558,7 +2568,7 @@ void OBSBasic::RemoveScene(OBSSource source) if (!disableSaving) { blog(LOG_INFO, "User Removed scene '%s'", - obs_source_get_name(source)); + obs_source_get_name(source)); OBSProjector::UpdateMultiviewProjectors(); } @@ -2570,7 +2580,7 @@ void OBSBasic::RemoveScene(OBSSource source) static bool select_one(obs_scene_t *scene, obs_sceneitem_t *item, void *param) { obs_sceneitem_t *selectedItem = - reinterpret_cast(param); + reinterpret_cast(param); if (obs_sceneitem_is_group(item)) obs_sceneitem_group_enum_items(item, select_one, param); @@ -2582,7 +2592,7 @@ static bool select_one(obs_scene_t *scene, obs_sceneitem_t *item, void *param) void OBSBasic::AddSceneItem(OBSSceneItem item) { - obs_scene_t *scene = obs_sceneitem_get_scene(item); + obs_scene_t *scene = obs_sceneitem_get_scene(item); if (GetCurrentScene() == scene) ui->sources->Add(item); @@ -2593,11 +2603,12 @@ void OBSBasic::AddSceneItem(OBSSceneItem item) obs_source_t *sceneSource = obs_scene_get_source(scene); obs_source_t *itemSource = obs_sceneitem_get_source(item); blog(LOG_INFO, "User added source '%s' (%s) to scene '%s'", - obs_source_get_name(itemSource), - obs_source_get_id(itemSource), - obs_source_get_name(sceneSource)); - - obs_scene_enum_items(scene, select_one, (obs_sceneitem_t*)item); + obs_source_get_name(itemSource), + obs_source_get_id(itemSource), + obs_source_get_name(sceneSource)); + + obs_scene_enum_items(scene, select_one, + (obs_sceneitem_t *)item); } } @@ -2610,7 +2621,7 @@ void OBSBasic::UpdateSceneSelection(OBSSource source) if (!scene) return; - QList items = + QList items = ui->scenes->findItems(QT_UTF8(name), Qt::MatchExactly); if (items.count()) { @@ -2621,15 +2632,16 @@ void OBSBasic::UpdateSceneSelection(OBSSource source) OBSScene curScene = GetOBSRef(ui->scenes->currentItem()); if (api && scene != curScene) - api->on_event(OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED); + api->on_event( + OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED); } } } static void RenameListValues(QListWidget *listWidget, const QString &newName, - const QString &prevName) + const QString &prevName) { - QList items = + QList items = listWidget->findItems(prevName, Qt::MatchExactly); for (int i = 0; i < items.count(); i++) @@ -2637,9 +2649,9 @@ static void RenameListValues(QListWidget *listWidget, const QString &newName, } void OBSBasic::RenameSources(OBSSource source, QString newName, - QString prevName) + QString prevName) { - RenameListValues(ui->scenes, newName, prevName); + RenameListValues(ui->scenes, newName, prevName); for (size_t i = 0; i < volumes.size(); i++) { if (volumes[i]->GetName().compare(prevName) == 0) @@ -2683,8 +2695,8 @@ static inline void SetSourceMixerHidden(obs_source_t *source, bool hidden) void OBSBasic::GetAudioSourceFilters() { - QAction *action = reinterpret_cast(sender()); - VolControl *vol = action->property("volControl").value(); + QAction *action = reinterpret_cast(sender()); + VolControl *vol = action->property("volControl").value(); obs_source_t *source = vol->GetSource(); CreateFiltersWindow(source); @@ -2692,8 +2704,8 @@ void OBSBasic::GetAudioSourceFilters() void OBSBasic::GetAudioSourceProperties() { - QAction *action = reinterpret_cast(sender()); - VolControl *vol = action->property("volControl").value(); + QAction *action = reinterpret_cast(sender()); + VolControl *vol = action->property("volControl").value(); obs_source_t *source = vol->GetSource(); CreatePropertiesWindow(source); @@ -2701,8 +2713,8 @@ void OBSBasic::GetAudioSourceProperties() void OBSBasic::HideAudioControl() { - QAction *action = reinterpret_cast(sender()); - VolControl *vol = action->property("volControl").value(); + QAction *action = reinterpret_cast(sender()); + VolControl *vol = action->property("volControl").value(); obs_source_t *source = vol->GetSource(); if (!SourceMixerHidden(source)) { @@ -2713,7 +2725,7 @@ void OBSBasic::HideAudioControl() void OBSBasic::UnhideAllAudioControls() { - auto UnhideAudioMixer = [this] (obs_source_t *source) /* -- */ + auto UnhideAudioMixer = [this](obs_source_t *source) /* -- */ { if (!obs_source_active(source)) return true; @@ -2727,10 +2739,8 @@ void OBSBasic::UnhideAllAudioControls() using UnhideAudioMixer_t = decltype(UnhideAudioMixer); - auto PreEnum = [] (void *data, obs_source_t *source) -> bool /* -- */ - { - return (*reinterpret_cast(data))(source); - }; + auto PreEnum = [](void *data, obs_source_t *source) -> bool /* -- */ + { return (*reinterpret_cast(data))(source); }; obs_enum_sources(PreEnum, &UnhideAudioMixer); } @@ -2751,26 +2761,25 @@ void OBSBasic::ToggleHideMixer() void OBSBasic::MixerRenameSource() { - QAction *action = reinterpret_cast(sender()); - VolControl *vol = action->property("volControl").value(); + QAction *action = reinterpret_cast(sender()); + VolControl *vol = action->property("volControl").value(); OBSSource source = vol->GetSource(); const char *prevName = obs_source_get_name(source); for (;;) { string name; - bool accepted = NameDialog::AskForName(this, - QTStr("Basic.Main.MixerRename.Title"), - QTStr("Basic.Main.MixerRename.Text"), - name, - QT_UTF8(prevName)); + bool accepted = NameDialog::AskForName( + this, QTStr("Basic.Main.MixerRename.Title"), + QTStr("Basic.Main.MixerRename.Text"), name, + QT_UTF8(prevName)); if (!accepted) return; if (name.empty()) { OBSMessageBox::warning(this, - QTStr("NoNameEntered.Title"), - QTStr("NoNameEntered.Text")); + QTStr("NoNameEntered.Title"), + QTStr("NoNameEntered.Text")); continue; } @@ -2778,9 +2787,8 @@ void OBSBasic::MixerRenameSource() obs_source_release(sourceTest); if (sourceTest) { - OBSMessageBox::warning(this, - QTStr("NameExists.Title"), - QTStr("NameExists.Text")); + OBSMessageBox::warning(this, QTStr("NameExists.Title"), + QTStr("NameExists.Text")); continue; } @@ -2791,7 +2799,7 @@ void OBSBasic::MixerRenameSource() void OBSBasic::VolControlContextMenu() { - VolControl *vol = reinterpret_cast(sender()); + VolControl *vol = reinterpret_cast(sender()); /* ------------------- */ @@ -2808,60 +2816,52 @@ void OBSBasic::VolControlContextMenu() QAction toggleControlLayoutAction(QTStr("VerticalLayout"), this); toggleControlLayoutAction.setCheckable(true); - toggleControlLayoutAction.setChecked(config_get_bool(GetGlobalConfig(), - "BasicWindow", "VerticalVolControl")); + toggleControlLayoutAction.setChecked(config_get_bool( + GetGlobalConfig(), "BasicWindow", "VerticalVolControl")); /* ------------------- */ - connect(&hideAction, &QAction::triggered, - this, &OBSBasic::HideAudioControl, - Qt::DirectConnection); - connect(&unhideAllAction, &QAction::triggered, - this, &OBSBasic::UnhideAllAudioControls, - Qt::DirectConnection); - connect(&mixerRenameAction, &QAction::triggered, - this, &OBSBasic::MixerRenameSource, - Qt::DirectConnection); + connect(&hideAction, &QAction::triggered, this, + &OBSBasic::HideAudioControl, Qt::DirectConnection); + connect(&unhideAllAction, &QAction::triggered, this, + &OBSBasic::UnhideAllAudioControls, Qt::DirectConnection); + connect(&mixerRenameAction, &QAction::triggered, this, + &OBSBasic::MixerRenameSource, Qt::DirectConnection); - connect(©FiltersAction, &QAction::triggered, - this, &OBSBasic::AudioMixerCopyFilters, - Qt::DirectConnection); - connect(&pasteFiltersAction, &QAction::triggered, - this, &OBSBasic::AudioMixerPasteFilters, - Qt::DirectConnection); + connect(©FiltersAction, &QAction::triggered, this, + &OBSBasic::AudioMixerCopyFilters, Qt::DirectConnection); + connect(&pasteFiltersAction, &QAction::triggered, this, + &OBSBasic::AudioMixerPasteFilters, Qt::DirectConnection); - connect(&filtersAction, &QAction::triggered, - this, &OBSBasic::GetAudioSourceFilters, - Qt::DirectConnection); - connect(&propertiesAction, &QAction::triggered, - this, &OBSBasic::GetAudioSourceProperties, - Qt::DirectConnection); - connect(&advPropAction, &QAction::triggered, - this, &OBSBasic::on_actionAdvAudioProperties_triggered, - Qt::DirectConnection); + connect(&filtersAction, &QAction::triggered, this, + &OBSBasic::GetAudioSourceFilters, Qt::DirectConnection); + connect(&propertiesAction, &QAction::triggered, this, + &OBSBasic::GetAudioSourceProperties, Qt::DirectConnection); + connect(&advPropAction, &QAction::triggered, this, + &OBSBasic::on_actionAdvAudioProperties_triggered, + Qt::DirectConnection); /* ------------------- */ connect(&toggleControlLayoutAction, &QAction::changed, this, - &OBSBasic::ToggleVolControlLayout, - Qt::DirectConnection); + &OBSBasic::ToggleVolControlLayout, Qt::DirectConnection); /* ------------------- */ hideAction.setProperty("volControl", - QVariant::fromValue(vol)); + QVariant::fromValue(vol)); mixerRenameAction.setProperty("volControl", - QVariant::fromValue(vol)); + QVariant::fromValue(vol)); copyFiltersAction.setProperty("volControl", - QVariant::fromValue(vol)); + QVariant::fromValue(vol)); pasteFiltersAction.setProperty("volControl", - QVariant::fromValue(vol)); + QVariant::fromValue(vol)); filtersAction.setProperty("volControl", - QVariant::fromValue(vol)); + QVariant::fromValue(vol)); propertiesAction.setProperty("volControl", - QVariant::fromValue(vol)); + QVariant::fromValue(vol)); /* ------------------- */ @@ -2904,24 +2904,22 @@ void OBSBasic::StackedMixerAreaContextMenuRequested() QAction toggleControlLayoutAction(QTStr("VerticalLayout"), this); toggleControlLayoutAction.setCheckable(true); - toggleControlLayoutAction.setChecked(config_get_bool(GetGlobalConfig(), - "BasicWindow", "VerticalVolControl")); + toggleControlLayoutAction.setChecked(config_get_bool( + GetGlobalConfig(), "BasicWindow", "VerticalVolControl")); /* ------------------- */ - connect(&unhideAllAction, &QAction::triggered, - this, &OBSBasic::UnhideAllAudioControls, - Qt::DirectConnection); + connect(&unhideAllAction, &QAction::triggered, this, + &OBSBasic::UnhideAllAudioControls, Qt::DirectConnection); - connect(&advPropAction, &QAction::triggered, - this, &OBSBasic::on_actionAdvAudioProperties_triggered, - Qt::DirectConnection); + connect(&advPropAction, &QAction::triggered, this, + &OBSBasic::on_actionAdvAudioProperties_triggered, + Qt::DirectConnection); /* ------------------- */ connect(&toggleControlLayoutAction, &QAction::changed, this, - &OBSBasic::ToggleVolControlLayout, - Qt::DirectConnection); + &OBSBasic::ToggleVolControlLayout, Qt::DirectConnection); /* ------------------- */ @@ -2948,7 +2946,7 @@ void OBSBasic::ToggleMixerLayout(bool vertical) void OBSBasic::ToggleVolControlLayout() { bool vertical = !config_get_bool(GetGlobalConfig(), "BasicWindow", - "VerticalVolControl"); + "VerticalVolControl"); config_set_bool(GetGlobalConfig(), "BasicWindow", "VerticalVolControl", vertical); ToggleMixerLayout(vertical); @@ -2969,17 +2967,19 @@ void OBSBasic::ActivateAudioSource(OBSSource source) { if (SourceMixerHidden(source)) return; + if (!obs_source_audio_active(source)) + return; bool vertical = config_get_bool(GetGlobalConfig(), "BasicWindow", - "VerticalVolControl"); + "VerticalVolControl"); VolControl *vol = new VolControl(source, true, vertical); - double meterDecayRate = config_get_double(basicConfig, "Audio", - "MeterDecayRate"); + double meterDecayRate = + config_get_double(basicConfig, "Audio", "MeterDecayRate"); vol->SetMeterDecayRate(meterDecayRate); - uint32_t peakMeterTypeIdx = config_get_uint(basicConfig, "Audio", - "PeakMeterType"); + uint32_t peakMeterTypeIdx = + config_get_uint(basicConfig, "Audio", "PeakMeterType"); enum obs_peak_meter_type peakMeterType; switch (peakMeterTypeIdx) { @@ -2998,10 +2998,10 @@ void OBSBasic::ActivateAudioSource(OBSSource source) vol->setContextMenuPolicy(Qt::CustomContextMenu); - connect(vol, &QWidget::customContextMenuRequested, - this, &OBSBasic::VolControlContextMenu); - connect(vol, &VolControl::ConfigClicked, - this, &OBSBasic::VolControlContextMenu); + connect(vol, &QWidget::customContextMenuRequested, this, + &OBSBasic::VolControlContextMenu); + connect(vol, &VolControl::ConfigClicked, this, + &OBSBasic::VolControlContextMenu); InsertQObjectByName(volumes, vol); @@ -3032,21 +3032,21 @@ bool OBSBasic::QueryRemoveSource(obs_source_t *source) if (count == 1) { OBSMessageBox::information(this, - QTStr("FinalScene.Title"), - QTStr("FinalScene.Text")); + QTStr("FinalScene.Title"), + QTStr("FinalScene.Text")); return false; } } - const char *name = obs_source_get_name(source); + const char *name = obs_source_get_name(source); QString text = QTStr("ConfirmRemove.Text"); text.replace("$1", QT_UTF8(name)); QMessageBox remove_source(this); remove_source.setText(text); - QAbstractButton *Yes = remove_source.addButton(QTStr("Yes"), - QMessageBox::YesRole); + QAbstractButton *Yes = + remove_source.addButton(QTStr("Yes"), QMessageBox::YesRole); remove_source.addButton(QTStr("No"), QMessageBox::NoRole); remove_source.setIcon(QMessageBox::Question); remove_source.setWindowTitle(QTStr("ConfirmRemove.Title")); @@ -3055,7 +3055,7 @@ bool OBSBasic::QueryRemoveSource(obs_source_t *source) return Yes == remove_source.clickedButton(); } -#define UPDATE_CHECK_INTERVAL (60*60*24*4) /* 4 days */ +#define UPDATE_CHECK_INTERVAL (60 * 60 * 24 * 4) /* 4 days */ #ifdef UPDATE_SPARKLE void init_sparkle_updater(bool update_to_undeployed); @@ -3065,25 +3065,25 @@ void trigger_sparkle_update(); void OBSBasic::TimedCheckForUpdates() { if (!config_get_bool(App()->GlobalConfig(), "General", - "EnableAutoUpdates")) + "EnableAutoUpdates")) return; #ifdef UPDATE_SPARKLE init_sparkle_updater(config_get_bool(App()->GlobalConfig(), "General", - "UpdateToUndeployed")); + "UpdateToUndeployed")); #elif _WIN32 long long lastUpdate = config_get_int(App()->GlobalConfig(), "General", - "LastUpdateCheck"); - uint32_t lastVersion = config_get_int(App()->GlobalConfig(), "General", - "LastVersion"); + "LastUpdateCheck"); + uint32_t lastVersion = + config_get_int(App()->GlobalConfig(), "General", "LastVersion"); if (lastVersion < LIBOBS_API_VER) { lastUpdate = 0; config_set_int(App()->GlobalConfig(), "General", - "LastUpdateCheck", 0); + "LastUpdateCheck", 0); } - long long t = (long long)time(nullptr); + long long t = (long long)time(nullptr); long long secs = t - lastUpdate; if (secs > UPDATE_CHECK_INTERVAL) @@ -3134,33 +3134,31 @@ void OBSBasic::DuplicateSelectedScene() for (;;) { string name; - bool accepted = NameDialog::AskForName(this, - QTStr("Basic.Main.AddSceneDlg.Title"), - QTStr("Basic.Main.AddSceneDlg.Text"), - name, - placeHolderText); + bool accepted = NameDialog::AskForName( + this, QTStr("Basic.Main.AddSceneDlg.Title"), + QTStr("Basic.Main.AddSceneDlg.Text"), name, + placeHolderText); if (!accepted) return; if (name.empty()) { OBSMessageBox::warning(this, - QTStr("NoNameEntered.Title"), - QTStr("NoNameEntered.Text")); + QTStr("NoNameEntered.Title"), + QTStr("NoNameEntered.Text")); continue; } obs_source_t *source = obs_get_source_by_name(name.c_str()); if (source) { - OBSMessageBox::warning(this, - QTStr("NameExists.Title"), - QTStr("NameExists.Text")); + OBSMessageBox::warning(this, QTStr("NameExists.Title"), + QTStr("NameExists.Text")); obs_source_release(source); continue; } - obs_scene_t *scene = obs_scene_duplicate(curScene, - name.c_str(), OBS_SCENE_DUP_REFS); + obs_scene_t *scene = obs_scene_duplicate(curScene, name.c_str(), + OBS_SCENE_DUP_REFS); source = obs_scene_get_source(scene); SetCurrentScene(source, true); obs_scene_release(scene); @@ -3178,7 +3176,8 @@ void OBSBasic::RemoveSelectedScene() obs_source_remove(source); if (api) - api->on_event(OBS_FRONTEND_EVENT_SCENE_LIST_CHANGED); + api->on_event( + OBS_FRONTEND_EVENT_SCENE_LIST_CHANGED); } } } @@ -3206,102 +3205,119 @@ void OBSBasic::ReorderSources(OBSScene scene) void OBSBasic::SceneReordered(void *data, calldata_t *params) { - OBSBasic *window = static_cast(data); + OBSBasic *window = static_cast(data); - obs_scene_t *scene = (obs_scene_t*)calldata_ptr(params, "scene"); + obs_scene_t *scene = (obs_scene_t *)calldata_ptr(params, "scene"); QMetaObject::invokeMethod(window, "ReorderSources", - Q_ARG(OBSScene, OBSScene(scene))); + Q_ARG(OBSScene, OBSScene(scene))); } void OBSBasic::SceneItemAdded(void *data, calldata_t *params) { - OBSBasic *window = static_cast(data); + OBSBasic *window = static_cast(data); - obs_sceneitem_t *item = (obs_sceneitem_t*)calldata_ptr(params, "item"); + obs_sceneitem_t *item = (obs_sceneitem_t *)calldata_ptr(params, "item"); QMetaObject::invokeMethod(window, "AddSceneItem", - Q_ARG(OBSSceneItem, OBSSceneItem(item))); + Q_ARG(OBSSceneItem, OBSSceneItem(item))); } void OBSBasic::SceneItemSelected(void *data, calldata_t *params) { - OBSBasic *window = static_cast(data); + OBSBasic *window = static_cast(data); - obs_scene_t *scene = (obs_scene_t*)calldata_ptr(params, "scene"); - obs_sceneitem_t *item = (obs_sceneitem_t*)calldata_ptr(params, "item"); + obs_scene_t *scene = (obs_scene_t *)calldata_ptr(params, "scene"); + obs_sceneitem_t *item = (obs_sceneitem_t *)calldata_ptr(params, "item"); QMetaObject::invokeMethod(window, "SelectSceneItem", - Q_ARG(OBSScene, scene), Q_ARG(OBSSceneItem, item), - Q_ARG(bool, true)); + Q_ARG(OBSScene, scene), + Q_ARG(OBSSceneItem, item), Q_ARG(bool, true)); } void OBSBasic::SceneItemDeselected(void *data, calldata_t *params) { - OBSBasic *window = static_cast(data); + OBSBasic *window = static_cast(data); - obs_scene_t *scene = (obs_scene_t*)calldata_ptr(params, "scene"); - obs_sceneitem_t *item = (obs_sceneitem_t*)calldata_ptr(params, "item"); + obs_scene_t *scene = (obs_scene_t *)calldata_ptr(params, "scene"); + obs_sceneitem_t *item = (obs_sceneitem_t *)calldata_ptr(params, "item"); QMetaObject::invokeMethod(window, "SelectSceneItem", - Q_ARG(OBSScene, scene), Q_ARG(OBSSceneItem, item), - Q_ARG(bool, false)); - + Q_ARG(OBSScene, scene), + Q_ARG(OBSSceneItem, item), + Q_ARG(bool, false)); } void OBSBasic::SourceCreated(void *data, calldata_t *params) { - obs_source_t *source = (obs_source_t*)calldata_ptr(params, "source"); + obs_source_t *source = (obs_source_t *)calldata_ptr(params, "source"); if (obs_scene_from_source(source) != NULL) - QMetaObject::invokeMethod(static_cast(data), - "AddScene", WaitConnection(), - Q_ARG(OBSSource, OBSSource(source))); + QMetaObject::invokeMethod(static_cast(data), + "AddScene", WaitConnection(), + Q_ARG(OBSSource, OBSSource(source))); } void OBSBasic::SourceRemoved(void *data, calldata_t *params) { - obs_source_t *source = (obs_source_t*)calldata_ptr(params, "source"); + obs_source_t *source = (obs_source_t *)calldata_ptr(params, "source"); if (obs_scene_from_source(source) != NULL) - QMetaObject::invokeMethod(static_cast(data), - "RemoveScene", - Q_ARG(OBSSource, OBSSource(source))); + QMetaObject::invokeMethod(static_cast(data), + "RemoveScene", + Q_ARG(OBSSource, OBSSource(source))); } void OBSBasic::SourceActivated(void *data, calldata_t *params) { - obs_source_t *source = (obs_source_t*)calldata_ptr(params, "source"); - uint32_t flags = obs_source_get_output_flags(source); + obs_source_t *source = (obs_source_t *)calldata_ptr(params, "source"); + uint32_t flags = obs_source_get_output_flags(source); if (flags & OBS_SOURCE_AUDIO) - QMetaObject::invokeMethod(static_cast(data), - "ActivateAudioSource", - Q_ARG(OBSSource, OBSSource(source))); + QMetaObject::invokeMethod(static_cast(data), + "ActivateAudioSource", + Q_ARG(OBSSource, OBSSource(source))); } void OBSBasic::SourceDeactivated(void *data, calldata_t *params) { - obs_source_t *source = (obs_source_t*)calldata_ptr(params, "source"); - uint32_t flags = obs_source_get_output_flags(source); + obs_source_t *source = (obs_source_t *)calldata_ptr(params, "source"); + uint32_t flags = obs_source_get_output_flags(source); if (flags & OBS_SOURCE_AUDIO) - QMetaObject::invokeMethod(static_cast(data), - "DeactivateAudioSource", - Q_ARG(OBSSource, OBSSource(source))); + QMetaObject::invokeMethod(static_cast(data), + "DeactivateAudioSource", + Q_ARG(OBSSource, OBSSource(source))); +} + +void OBSBasic::SourceAudioActivated(void *data, calldata_t *params) +{ + obs_source_t *source = (obs_source_t *)calldata_ptr(params, "source"); + + if (obs_source_active(source)) + QMetaObject::invokeMethod(static_cast(data), + "ActivateAudioSource", + Q_ARG(OBSSource, OBSSource(source))); +} + +void OBSBasic::SourceAudioDeactivated(void *data, calldata_t *params) +{ + obs_source_t *source = (obs_source_t *)calldata_ptr(params, "source"); + QMetaObject::invokeMethod(static_cast(data), + "DeactivateAudioSource", + Q_ARG(OBSSource, OBSSource(source))); } void OBSBasic::SourceRenamed(void *data, calldata_t *params) { - obs_source_t *source = (obs_source_t*)calldata_ptr(params, "source"); - const char *newName = calldata_string(params, "new_name"); + obs_source_t *source = (obs_source_t *)calldata_ptr(params, "source"); + const char *newName = calldata_string(params, "new_name"); const char *prevName = calldata_string(params, "prev_name"); - QMetaObject::invokeMethod(static_cast(data), - "RenameSources", - Q_ARG(OBSSource, source), - Q_ARG(QString, QT_UTF8(newName)), - Q_ARG(QString, QT_UTF8(prevName))); + QMetaObject::invokeMethod(static_cast(data), + "RenameSources", Q_ARG(OBSSource, source), + Q_ARG(QString, QT_UTF8(newName)), + Q_ARG(QString, QT_UTF8(prevName))); blog(LOG_INFO, "Source '%s' renamed to '%s'", prevName, newName); } @@ -3313,9 +3329,9 @@ void OBSBasic::DrawBackdrop(float cx, float cy) GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "DrawBackdrop"); - gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID); - gs_eparam_t *color = gs_effect_get_param_by_name(solid, "color"); - gs_technique_t *tech = gs_effect_get_technique(solid, "Solid"); + gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID); + gs_eparam_t *color = gs_effect_get_param_by_name(solid, "color"); + gs_technique_t *tech = gs_effect_get_technique(solid, "Solid"); vec4 colorVal; vec4_set(&colorVal, 0.0f, 0.0f, 0.0f, 1.0f); @@ -3343,7 +3359,7 @@ void OBSBasic::RenderMain(void *data, uint32_t cx, uint32_t cy) { GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "RenderMain"); - OBSBasic *window = static_cast(data); + OBSBasic *window = static_cast(data); obs_video_info ovi; obs_get_video_info(&ovi); @@ -3357,40 +3373,38 @@ void OBSBasic::RenderMain(void *data, uint32_t cx, uint32_t cy) obs_display_t *display = window->ui->preview->GetDisplay(); uint32_t width, height; obs_display_size(display, &width, &height); - float right = float(width) - window->previewX; + float right = float(width) - window->previewX; float bottom = float(height) - window->previewY; - gs_ortho(-window->previewX, right, - -window->previewY, bottom, - -100.0f, 100.0f); + gs_ortho(-window->previewX, right, -window->previewY, bottom, -100.0f, + 100.0f); window->ui->preview->DrawOverflow(); /* --------------------------------------- */ gs_ortho(0.0f, float(ovi.base_width), 0.0f, float(ovi.base_height), - -100.0f, 100.0f); - gs_set_viewport(window->previewX, window->previewY, - window->previewCX, window->previewCY); - - window->DrawBackdrop(float(ovi.base_width), float(ovi.base_height)); + -100.0f, 100.0f); + gs_set_viewport(window->previewX, window->previewY, window->previewCX, + window->previewCY); if (window->IsPreviewProgramMode()) { + window->DrawBackdrop(float(ovi.base_width), + float(ovi.base_height)); + OBSScene scene = window->GetCurrentScene(); obs_source_t *source = obs_scene_get_source(scene); if (source) obs_source_video_render(source); } else { - obs_render_main_texture(); + obs_render_main_texture_src_color_only(); } gs_load_vertexbuffer(nullptr); /* --------------------------------------- */ - - gs_ortho(-window->previewX, right, - -window->previewY, bottom, - -100.0f, 100.0f); + gs_ortho(-window->previewX, right, -window->previewY, bottom, -100.0f, + 100.0f); gs_reset_viewport(); window->ui->preview->DrawSceneEditing(); @@ -3411,8 +3425,8 @@ void OBSBasic::RenderMain(void *data, uint32_t cx, uint32_t cy) obs_service_t *OBSBasic::GetService() { if (!service) { - service = obs_service_create("rtmp_common", NULL, NULL, - nullptr); + service = + obs_service_create("rtmp_common", NULL, NULL, nullptr); obs_service_release(service); } return service; @@ -3456,13 +3470,15 @@ static inline int AttemptToResetVideo(struct obs_video_info *ovi) static inline enum obs_scale_type GetScaleType(ConfigFile &basicConfig) { - const char *scaleTypeStr = config_get_string(basicConfig, - "Video", "ScaleType"); + const char *scaleTypeStr = + config_get_string(basicConfig, "Video", "ScaleType"); if (astrcmpi(scaleTypeStr, "bilinear") == 0) return OBS_SCALE_BILINEAR; else if (astrcmpi(scaleTypeStr, "lanczos") == 0) return OBS_SCALE_LANCZOS; + else if (astrcmpi(scaleTypeStr, "area") == 0) + return OBS_SCALE_AREA; else return OBS_SCALE_BICUBIC; } @@ -3489,11 +3505,11 @@ static inline enum video_format GetVideoFormatFromName(const char *name) void OBSBasic::ResetUI() { - bool studioPortraitLayout = config_get_bool(GetGlobalConfig(), - "BasicWindow", "StudioPortraitLayout"); + bool studioPortraitLayout = config_get_bool( + GetGlobalConfig(), "BasicWindow", "StudioPortraitLayout"); - bool labels = config_get_bool(GetGlobalConfig(), - "BasicWindow", "StudioModeLabels"); + bool labels = config_get_bool(GetGlobalConfig(), "BasicWindow", + "StudioModeLabels"); if (studioPortraitLayout) ui->previewLayout->setDirection(QBoxLayout::TopToBottom); @@ -3519,31 +3535,31 @@ int OBSBasic::ResetVideo() GetConfigFPS(ovi.fps_num, ovi.fps_den); - const char *colorFormat = config_get_string(basicConfig, "Video", - "ColorFormat"); - const char *colorSpace = config_get_string(basicConfig, "Video", - "ColorSpace"); - const char *colorRange = config_get_string(basicConfig, "Video", - "ColorRange"); + const char *colorFormat = + config_get_string(basicConfig, "Video", "ColorFormat"); + const char *colorSpace = + config_get_string(basicConfig, "Video", "ColorSpace"); + const char *colorRange = + config_get_string(basicConfig, "Video", "ColorRange"); ovi.graphics_module = App()->GetRenderModule(); - ovi.base_width = (uint32_t)config_get_uint(basicConfig, - "Video", "BaseCX"); - ovi.base_height = (uint32_t)config_get_uint(basicConfig, - "Video", "BaseCY"); - ovi.output_width = (uint32_t)config_get_uint(basicConfig, - "Video", "OutputCX"); - ovi.output_height = (uint32_t)config_get_uint(basicConfig, - "Video", "OutputCY"); - ovi.output_format = GetVideoFormatFromName(colorFormat); - ovi.colorspace = astrcmpi(colorSpace, "601") == 0 ? - VIDEO_CS_601 : VIDEO_CS_709; - ovi.range = astrcmpi(colorRange, "Full") == 0 ? - VIDEO_RANGE_FULL : VIDEO_RANGE_PARTIAL; - ovi.adapter = config_get_uint(App()->GlobalConfig(), - "Video", "AdapterIdx"); + ovi.base_width = + (uint32_t)config_get_uint(basicConfig, "Video", "BaseCX"); + ovi.base_height = + (uint32_t)config_get_uint(basicConfig, "Video", "BaseCY"); + ovi.output_width = + (uint32_t)config_get_uint(basicConfig, "Video", "OutputCX"); + ovi.output_height = + (uint32_t)config_get_uint(basicConfig, "Video", "OutputCY"); + ovi.output_format = GetVideoFormatFromName(colorFormat); + ovi.colorspace = astrcmpi(colorSpace, "601") == 0 ? VIDEO_CS_601 + : VIDEO_CS_709; + ovi.range = astrcmpi(colorRange, "Full") == 0 ? VIDEO_RANGE_FULL + : VIDEO_RANGE_PARTIAL; + ovi.adapter = + config_get_uint(App()->GlobalConfig(), "Video", "AdapterIdx"); ovi.gpu_conversion = true; - ovi.scale_type = GetScaleType(basicConfig); + ovi.scale_type = GetScaleType(basicConfig); if (ovi.base_width == 0 || ovi.base_height == 0) { ovi.base_width = 1920; @@ -3565,17 +3581,17 @@ int OBSBasic::ResetVideo() if (IS_WIN32 && ret != OBS_VIDEO_SUCCESS) { if (ret == OBS_VIDEO_CURRENTLY_ACTIVE) { blog(LOG_WARNING, "Tried to reset when " - "already active"); + "already active"); return ret; } /* Try OpenGL if DirectX fails on windows */ if (astrcmpi(ovi.graphics_module, DL_OPENGL) != 0) { - blog(LOG_WARNING, "Failed to initialize obs video (%d) " - "with graphics_module='%s', retrying " - "with graphics_module='%s'", - ret, ovi.graphics_module, - DL_OPENGL); + blog(LOG_WARNING, + "Failed to initialize obs video (%d) " + "with graphics_module='%s', retrying " + "with graphics_module='%s'", + ret, ovi.graphics_module, DL_OPENGL); ovi.graphics_module = DL_OPENGL; ret = AttemptToResetVideo(&ovi); } @@ -3598,11 +3614,11 @@ bool OBSBasic::ResetAudio() ProfileScope("OBSBasic::ResetAudio"); struct obs_audio_info ai; - ai.samples_per_sec = config_get_uint(basicConfig, "Audio", - "SampleRate"); + ai.samples_per_sec = + config_get_uint(basicConfig, "Audio", "SampleRate"); - const char *channelSetupStr = config_get_string(basicConfig, - "Audio", "ChannelSetup"); + const char *channelSetupStr = + config_get_string(basicConfig, "Audio", "ChannelSetup"); if (strcmp(channelSetupStr, "Mono") == 0) ai.speakers = SPEAKERS_MONO; @@ -3623,7 +3639,7 @@ bool OBSBasic::ResetAudio() } void OBSBasic::ResetAudioDevice(const char *sourceId, const char *deviceId, - const char *deviceDesc, int channel) + const char *deviceDesc, int channel) { bool disable = deviceId && strcmp(deviceId, "disabled") == 0; obs_source_t *source; @@ -3635,11 +3651,11 @@ void OBSBasic::ResetAudioDevice(const char *sourceId, const char *deviceId, obs_set_output_source(channel, nullptr); } else { settings = obs_source_get_settings(source); - const char *oldId = obs_data_get_string(settings, - "device_id"); + const char *oldId = + obs_data_get_string(settings, "device_id"); if (strcmp(oldId, deviceId) != 0) { obs_data_set_string(settings, "device_id", - deviceId); + deviceId); obs_source_update(source, settings); } obs_data_release(settings); @@ -3651,7 +3667,7 @@ void OBSBasic::ResetAudioDevice(const char *sourceId, const char *deviceId, settings = obs_data_create(); obs_data_set_string(settings, "device_id", deviceId); source = obs_source_create(sourceId, deviceDesc, settings, - nullptr); + nullptr); obs_data_release(settings); obs_set_output_source(channel, source); @@ -3661,7 +3677,7 @@ void OBSBasic::ResetAudioDevice(const char *sourceId, const char *deviceId, void OBSBasic::ResizePreview(uint32_t cx, uint32_t cy) { - QSize targetSize; + QSize targetSize; bool isFixedScaling; obs_video_info ovi; @@ -3673,18 +3689,20 @@ void OBSBasic::ResizePreview(uint32_t cx, uint32_t cy) if (isFixedScaling) { previewScale = ui->preview->GetScalingAmount(); - GetCenterPosFromFixedScale(int(cx), int(cy), - targetSize.width() - PREVIEW_EDGE_SIZE * 2, - targetSize.height() - PREVIEW_EDGE_SIZE * 2, - previewX, previewY, previewScale); + GetCenterPosFromFixedScale( + int(cx), int(cy), + targetSize.width() - PREVIEW_EDGE_SIZE * 2, + targetSize.height() - PREVIEW_EDGE_SIZE * 2, previewX, + previewY, previewScale); previewX += ui->preview->GetScrollX(); previewY += ui->preview->GetScrollY(); } else { GetScaleAndCenterPos(int(cx), int(cy), - targetSize.width() - PREVIEW_EDGE_SIZE * 2, - targetSize.height() - PREVIEW_EDGE_SIZE * 2, - previewX, previewY, previewScale); + targetSize.width() - PREVIEW_EDGE_SIZE * 2, + targetSize.height() - + PREVIEW_EDGE_SIZE * 2, + previewX, previewY, previewScale); } previewX += float(PREVIEW_EDGE_SIZE); @@ -3693,7 +3711,7 @@ void OBSBasic::ResizePreview(uint32_t cx, uint32_t cy) void OBSBasic::CloseDialogs() { - QList childDialogs = this->findChildren(); + QList childDialogs = this->findChildren(); if (!childDialogs.isEmpty()) { for (int i = 0; i < childDialogs.size(); ++i) { childDialogs.at(i)->close(); @@ -3709,8 +3727,10 @@ void OBSBasic::CloseDialogs() projector.clear(); } - if (!stats.isNull()) stats->close(); //call close to save Stats geometry - if (!remux.isNull()) remux->close(); + if (!stats.isNull()) + stats->close(); //call close to save Stats geometry + if (!remux.isNull()) + remux->close(); } void OBSBasic::EnumDialogs() @@ -3720,7 +3740,7 @@ void OBSBasic::EnumDialogs() visMsgBoxes.clear(); /* fill list of Visible dialogs and Modal dialogs */ - QList dialogs = findChildren(); + QList dialogs = findChildren(); for (QDialog *dialog : dialogs) { if (dialog->isVisible()) visDialogs.append(dialog); @@ -3729,7 +3749,7 @@ void OBSBasic::EnumDialogs() } /* fill list of Visible message boxes */ - QList msgBoxes = findChildren(); + QList msgBoxes = findChildren(); for (QMessageBox *msgbox : msgBoxes) { if (msgbox->isVisible()) visMsgBoxes.append(msgbox); @@ -3758,8 +3778,7 @@ void OBSBasic::ClearSceneData() swapScene = nullptr; programScene = nullptr; - auto cb = [](void *unused, obs_source_t *source) - { + auto cb = [](void *unused, obs_source_t *source) { obs_source_remove(source); UNUSED_PARAMETER(unused); return true; @@ -3788,16 +3807,16 @@ void OBSBasic::closeEvent(QCloseEvent *event) } if (isVisible()) - config_set_string(App()->GlobalConfig(), - "BasicWindow", "geometry", - saveGeometry().toBase64().constData()); + config_set_string(App()->GlobalConfig(), "BasicWindow", + "geometry", + saveGeometry().toBase64().constData()); if (outputHandler && outputHandler->Active()) { SetShowing(true); QMessageBox::StandardButton button = OBSMessageBox::question( - this, QTStr("ConfirmExit.Title"), - QTStr("ConfirmExit.Text")); + this, QTStr("ConfirmExit.Title"), + QTStr("ConfirmExit.Text")); if (button == QMessageBox::No) { event->ignore(); @@ -3824,9 +3843,15 @@ void OBSBasic::closeEvent(QCloseEvent *event) SaveProjectNow(); auth.reset(); - config_set_string(App()->GlobalConfig(), - "BasicWindow", "DockState", - saveState().toBase64().constData()); + delete extraBrowsers; + + config_set_string(App()->GlobalConfig(), "BasicWindow", "DockState", + saveState().toBase64().constData()); + +#ifdef BROWSER_AVAILABLE + SaveExtraBrowserDocks(); + ClearExtraBrowserDocks(); +#endif if (api) api->on_event(OBS_FRONTEND_EVENT_EXIT); @@ -3842,11 +3867,8 @@ void OBSBasic::closeEvent(QCloseEvent *event) void OBSBasic::changeEvent(QEvent *event) { - if (event->type() == QEvent::WindowStateChange && - isMinimized() && - trayIcon && - trayIcon->isVisible() && - sysTrayMinimizeToTray()) { + if (event->type() == QEvent::WindowStateChange && isMinimized() && + trayIcon && trayIcon->isVisible() && sysTrayMinimizeToTray()) { ToggleShowHide(); } @@ -3856,12 +3878,16 @@ void OBSBasic::on_actionShow_Recordings_triggered() { const char *mode = config_get_string(basicConfig, "Output", "Mode"); const char *type = config_get_string(basicConfig, "AdvOut", "RecType"); - const char *adv_path = strcmp(type, "Standard") ? - config_get_string(basicConfig, "AdvOut", "FFFilePath") : - config_get_string(basicConfig, "AdvOut", "RecFilePath"); - const char *path = strcmp(mode, "Advanced") ? - config_get_string(basicConfig, "SimpleOutput", "FilePath") : - adv_path; + const char *adv_path = + strcmp(type, "Standard") + ? config_get_string(basicConfig, "AdvOut", "FFFilePath") + : config_get_string(basicConfig, "AdvOut", + "RecFilePath"); + const char *path = strcmp(mode, "Advanced") + ? config_get_string(basicConfig, + "SimpleOutput", + "FilePath") + : adv_path; QDesktopServices::openUrl(QUrl::fromLocalFile(path)); } @@ -3874,9 +3900,12 @@ void OBSBasic::on_actionRemux_triggered() } const char *mode = config_get_string(basicConfig, "Output", "Mode"); - const char *path = strcmp(mode, "Advanced") ? - config_get_string(basicConfig, "SimpleOutput", "FilePath") : - config_get_string(basicConfig, "AdvOut", "RecFilePath"); + const char *path = strcmp(mode, "Advanced") + ? config_get_string(basicConfig, + "SimpleOutput", + "FilePath") + : config_get_string(basicConfig, "AdvOut", + "RecFilePath"); OBSRemux *remuxDlg; remuxDlg = new OBSRemux(path, this); @@ -3893,7 +3922,7 @@ void OBSBasic::on_action_Settings_triggered() * once per second until we've exit any known sub-loops. */ if (os_atomic_load_long(&insideEventLoop) != 0) { QTimer::singleShot(1000, this, - SLOT(on_action_Settings_triggered())); + SLOT(on_action_Settings_triggered())); return; } @@ -3921,8 +3950,8 @@ void OBSBasic::on_actionAdvAudioProperties_triggered() advAudioWindow->show(); advAudioWindow->setAttribute(Qt::WA_DeleteOnClose, true); - connect(advAudioWindow, SIGNAL(destroyed()), - this, SLOT(on_advAudioProps_destroyed())); + connect(advAudioWindow, SIGNAL(destroyed()), this, + SLOT(on_advAudioProps_destroyed())); } void OBSBasic::on_advAudioProps_clicked() @@ -3936,7 +3965,7 @@ void OBSBasic::on_advAudioProps_destroyed() } void OBSBasic::on_scenes_currentItemChanged(QListWidgetItem *current, - QListWidgetItem *prev) + QListWidgetItem *prev) { obs_source_t *source = NULL; @@ -3961,7 +3990,7 @@ void OBSBasic::on_scenes_currentItemChanged(QListWidgetItem *current, void OBSBasic::EditSceneName() { QListWidgetItem *item = ui->scenes->currentItem(); - Qt::ItemFlags flags = item->flags(); + Qt::ItemFlags flags = item->flags(); item->setFlags(flags | Qt::ItemIsEditable); ui->scenes->editItem(item); @@ -3969,19 +3998,19 @@ void OBSBasic::EditSceneName() } static void AddProjectorMenuMonitors(QMenu *parent, QObject *target, - const char *slot) + const char *slot) { QAction *action; - QList screens = QGuiApplication::screens(); + QList screens = QGuiApplication::screens(); for (int i = 0; i < screens.size(); i++) { QRect screenGeometry = screens[i]->geometry(); - QString str = QString("%1 %2: %3x%4 @ %5,%6"). - arg(QTStr("Display"), - QString::number(i + 1), - QString::number(screenGeometry.width()), - QString::number(screenGeometry.height()), - QString::number(screenGeometry.x()), - QString::number(screenGeometry.y())); + QString str = + QString("%1 %2: %3x%4 @ %5,%6") + .arg(QTStr("Display"), QString::number(i + 1), + QString::number(screenGeometry.width()), + QString::number(screenGeometry.height()), + QString::number(screenGeometry.x()), + QString::number(screenGeometry.y())); action = parent->addAction(str, target, slot); action->setProperty("monitor", i); @@ -3994,31 +4023,30 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos) QMenu popup(this); QMenu order(QTStr("Basic.MainMenu.Edit.Order"), this); - popup.addAction(QTStr("Add"), - this, SLOT(on_actionAddScene_triggered())); + popup.addAction(QTStr("Add"), this, + SLOT(on_actionAddScene_triggered())); if (item) { - QAction *pasteFilters = new QAction( - QTStr("Paste.Filters"), this); + QAction *pasteFilters = + new QAction(QTStr("Paste.Filters"), this); pasteFilters->setEnabled(copyFiltersString); connect(pasteFilters, SIGNAL(triggered()), this, - SLOT(ScenePasteFilters())); + SLOT(ScenePasteFilters())); popup.addSeparator(); - popup.addAction(QTStr("Duplicate"), - this, SLOT(DuplicateSelectedScene())); - popup.addAction(QTStr("Copy.Filters"), - this, SLOT(SceneCopyFilters())); + popup.addAction(QTStr("Duplicate"), this, + SLOT(DuplicateSelectedScene())); + popup.addAction(QTStr("Copy.Filters"), this, + SLOT(SceneCopyFilters())); popup.addAction(pasteFilters); popup.addSeparator(); - popup.addAction(QTStr("Rename"), - this, SLOT(EditSceneName())); - popup.addAction(QTStr("Remove"), - this, SLOT(RemoveSelectedScene())); + popup.addAction(QTStr("Rename"), this, SLOT(EditSceneName())); + popup.addAction(QTStr("Remove"), this, + SLOT(RemoveSelectedScene())); popup.addSeparator(); - order.addAction(QTStr("Basic.MainMenu.Edit.Order.MoveUp"), - this, SLOT(on_actionSceneUp_triggered())); + order.addAction(QTStr("Basic.MainMenu.Edit.Order.MoveUp"), this, + SLOT(on_actionSceneUp_triggered())); order.addAction(QTStr("Basic.MainMenu.Edit.Order.MoveDown"), this, SLOT(on_actionSceneDown_triggered())); order.addSeparator(); @@ -4033,12 +4061,11 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos) delete sceneProjectorMenu; sceneProjectorMenu = new QMenu(QTStr("SceneProjector")); AddProjectorMenuMonitors(sceneProjectorMenu, this, - SLOT(OpenSceneProjector())); + SLOT(OpenSceneProjector())); popup.addMenu(sceneProjectorMenu); QAction *sceneWindow = popup.addAction( - QTStr("SceneWindow"), - this, SLOT(OpenSceneWindow())); + QTStr("SceneWindow"), this, SLOT(OpenSceneWindow())); popup.addAction(sceneWindow); popup.addSeparator(); @@ -4053,31 +4080,28 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos) /* ---------------------- */ - QAction *multiviewAction = popup.addAction( - QTStr("ShowInMultiview")); + QAction *multiviewAction = + popup.addAction(QTStr("ShowInMultiview")); OBSSource source = GetCurrentSceneSource(); OBSData data = obs_source_get_private_settings(source); obs_data_release(data); - obs_data_set_default_bool(data, "show_in_multiview", - true); + obs_data_set_default_bool(data, "show_in_multiview", true); bool show = obs_data_get_bool(data, "show_in_multiview"); multiviewAction->setCheckable(true); multiviewAction->setChecked(show); - auto showInMultiview = [] (OBSData data) - { - bool show = obs_data_get_bool(data, - "show_in_multiview"); - obs_data_set_bool(data, "show_in_multiview", - !show); + auto showInMultiview = [](OBSData data) { + bool show = + obs_data_get_bool(data, "show_in_multiview"); + obs_data_set_bool(data, "show_in_multiview", !show); OBSProjector::UpdateMultiviewProjectors(); }; connect(multiviewAction, &QAction::triggered, - std::bind(showInMultiview, data)); + std::bind(showInMultiview, data)); } popup.exec(QCursor::pos()); @@ -4096,26 +4120,23 @@ void OBSBasic::on_actionAddScene_triggered() placeHolderText = format.arg(++i); } - bool accepted = NameDialog::AskForName(this, - QTStr("Basic.Main.AddSceneDlg.Title"), - QTStr("Basic.Main.AddSceneDlg.Text"), - name, - placeHolderText); + bool accepted = NameDialog::AskForName( + this, QTStr("Basic.Main.AddSceneDlg.Title"), + QTStr("Basic.Main.AddSceneDlg.Text"), name, placeHolderText); if (accepted) { if (name.empty()) { OBSMessageBox::warning(this, - QTStr("NoNameEntered.Title"), - QTStr("NoNameEntered.Text")); + QTStr("NoNameEntered.Title"), + QTStr("NoNameEntered.Text")); on_actionAddScene_triggered(); return; } obs_source_t *source = obs_get_source_by_name(name.c_str()); if (source) { - OBSMessageBox::warning(this, - QTStr("NameExists.Title"), - QTStr("NameExists.Text")); + OBSMessageBox::warning(this, QTStr("NameExists.Title"), + QTStr("NameExists.Text")); obs_source_release(source); on_actionAddScene_triggered(); @@ -4131,7 +4152,7 @@ void OBSBasic::on_actionAddScene_triggered() void OBSBasic::on_actionRemoveScene_triggered() { - OBSScene scene = GetCurrentScene(); + OBSScene scene = GetCurrentScene(); obs_source_t *source = obs_scene_get_source(scene); if (source && QueryRemoveSource(source)) @@ -4178,7 +4199,7 @@ void OBSBasic::MoveSceneToTop() void OBSBasic::MoveSceneToBottom() { ChangeSceneIndex(false, ui->scenes->count() - 1, - ui->scenes->count() - 1); + ui->scenes->count() - 1); } void OBSBasic::EditSceneItemName() @@ -4189,7 +4210,7 @@ void OBSBasic::EditSceneItemName() void OBSBasic::SetDeinterlacingMode() { - QAction *action = reinterpret_cast(sender()); + QAction *action = reinterpret_cast(sender()); obs_deinterlace_mode mode = (obs_deinterlace_mode)action->property("mode").toInt(); OBSSceneItem sceneItem = GetCurrentSceneItem(); @@ -4200,7 +4221,7 @@ void OBSBasic::SetDeinterlacingMode() void OBSBasic::SetDeinterlacingOrder() { - QAction *action = reinterpret_cast(sender()); + QAction *action = reinterpret_cast(sender()); obs_deinterlace_field_order order = (obs_deinterlace_field_order)action->property("order").toInt(); OBSSceneItem sceneItem = GetCurrentSceneItem(); @@ -4217,34 +4238,34 @@ QMenu *OBSBasic::AddDeinterlacingMenu(QMenu *menu, obs_source_t *source) obs_source_get_deinterlace_field_order(source); QAction *action; -#define ADD_MODE(name, mode) \ - action = menu->addAction(QTStr("" name), this, \ - SLOT(SetDeinterlacingMode())); \ - action->setProperty("mode", (int)mode); \ - action->setCheckable(true); \ +#define ADD_MODE(name, mode) \ + action = menu->addAction(QTStr("" name), this, \ + SLOT(SetDeinterlacingMode())); \ + action->setProperty("mode", (int)mode); \ + action->setCheckable(true); \ action->setChecked(deinterlaceMode == mode); - ADD_MODE("Disable", OBS_DEINTERLACE_MODE_DISABLE); - ADD_MODE("Deinterlacing.Discard", OBS_DEINTERLACE_MODE_DISCARD); - ADD_MODE("Deinterlacing.Retro", OBS_DEINTERLACE_MODE_RETRO); - ADD_MODE("Deinterlacing.Blend", OBS_DEINTERLACE_MODE_BLEND); - ADD_MODE("Deinterlacing.Blend2x", OBS_DEINTERLACE_MODE_BLEND_2X); - ADD_MODE("Deinterlacing.Linear", OBS_DEINTERLACE_MODE_LINEAR); + ADD_MODE("Disable", OBS_DEINTERLACE_MODE_DISABLE); + ADD_MODE("Deinterlacing.Discard", OBS_DEINTERLACE_MODE_DISCARD); + ADD_MODE("Deinterlacing.Retro", OBS_DEINTERLACE_MODE_RETRO); + ADD_MODE("Deinterlacing.Blend", OBS_DEINTERLACE_MODE_BLEND); + ADD_MODE("Deinterlacing.Blend2x", OBS_DEINTERLACE_MODE_BLEND_2X); + ADD_MODE("Deinterlacing.Linear", OBS_DEINTERLACE_MODE_LINEAR); ADD_MODE("Deinterlacing.Linear2x", OBS_DEINTERLACE_MODE_LINEAR_2X); - ADD_MODE("Deinterlacing.Yadif", OBS_DEINTERLACE_MODE_YADIF); - ADD_MODE("Deinterlacing.Yadif2x", OBS_DEINTERLACE_MODE_YADIF_2X); + ADD_MODE("Deinterlacing.Yadif", OBS_DEINTERLACE_MODE_YADIF); + ADD_MODE("Deinterlacing.Yadif2x", OBS_DEINTERLACE_MODE_YADIF_2X); #undef ADD_MODE menu->addSeparator(); -#define ADD_ORDER(name, order) \ +#define ADD_ORDER(name, order) \ action = menu->addAction(QTStr("Deinterlacing." name), this, \ - SLOT(SetDeinterlacingOrder())); \ - action->setProperty("order", (int)order); \ - action->setCheckable(true); \ + SLOT(SetDeinterlacingOrder())); \ + action->setProperty("order", (int)order); \ + action->setCheckable(true); \ action->setChecked(deinterlaceOrder == order); - ADD_ORDER("TopFieldFirst", OBS_DEINTERLACE_FIELD_ORDER_TOP); + ADD_ORDER("TopFieldFirst", OBS_DEINTERLACE_FIELD_ORDER_TOP); ADD_ORDER("BottomFieldFirst", OBS_DEINTERLACE_FIELD_ORDER_BOTTOM); #undef ADD_ORDER @@ -4253,7 +4274,7 @@ QMenu *OBSBasic::AddDeinterlacingMenu(QMenu *menu, obs_source_t *source) void OBSBasic::SetScaleFilter() { - QAction *action = reinterpret_cast(sender()); + QAction *action = reinterpret_cast(sender()); obs_scale_type mode = (obs_scale_type)action->property("mode").toInt(); OBSSceneItem sceneItem = GetCurrentSceneItem(); @@ -4265,37 +4286,39 @@ QMenu *OBSBasic::AddScaleFilteringMenu(QMenu *menu, obs_sceneitem_t *item) obs_scale_type scaleFilter = obs_sceneitem_get_scale_filter(item); QAction *action; -#define ADD_MODE(name, mode) \ - action = menu->addAction(QTStr("" name), this, \ - SLOT(SetScaleFilter())); \ - action->setProperty("mode", (int)mode); \ - action->setCheckable(true); \ +#define ADD_MODE(name, mode) \ + action = \ + menu->addAction(QTStr("" name), this, SLOT(SetScaleFilter())); \ + action->setProperty("mode", (int)mode); \ + action->setCheckable(true); \ action->setChecked(scaleFilter == mode); - ADD_MODE("Disable", OBS_SCALE_DISABLE); - ADD_MODE("ScaleFiltering.Point", OBS_SCALE_POINT); + ADD_MODE("Disable", OBS_SCALE_DISABLE); + ADD_MODE("ScaleFiltering.Point", OBS_SCALE_POINT); ADD_MODE("ScaleFiltering.Bilinear", OBS_SCALE_BILINEAR); - ADD_MODE("ScaleFiltering.Bicubic", OBS_SCALE_BICUBIC); - ADD_MODE("ScaleFiltering.Lanczos", OBS_SCALE_LANCZOS); - ADD_MODE("ScaleFiltering.Area", OBS_SCALE_AREA); + ADD_MODE("ScaleFiltering.Bicubic", OBS_SCALE_BICUBIC); + ADD_MODE("ScaleFiltering.Lanczos", OBS_SCALE_LANCZOS); + ADD_MODE("ScaleFiltering.Area", OBS_SCALE_AREA); #undef ADD_MODE return menu; } -QMenu *OBSBasic::AddBackgroundColorMenu(QMenu *menu, QWidgetAction *widgetAction, - ColorSelect *select, obs_sceneitem_t *item) +QMenu *OBSBasic::AddBackgroundColorMenu(QMenu *menu, + QWidgetAction *widgetAction, + ColorSelect *select, + obs_sceneitem_t *item) { QAction *action; menu->setStyleSheet(QString( - "*[bgColor=\"1\"]{background-color:rgba(255,68,68,33%);}" \ - "*[bgColor=\"2\"]{background-color:rgba(255,255,68,33%);}" \ - "*[bgColor=\"3\"]{background-color:rgba(68,255,68,33%);}" \ - "*[bgColor=\"4\"]{background-color:rgba(68,255,255,33%);}" \ - "*[bgColor=\"5\"]{background-color:rgba(68,68,255,33%);}" \ - "*[bgColor=\"6\"]{background-color:rgba(255,68,255,33%);}" \ - "*[bgColor=\"7\"]{background-color:rgba(68,68,68,33%);}" \ + "*[bgColor=\"1\"]{background-color:rgba(255,68,68,33%);}" + "*[bgColor=\"2\"]{background-color:rgba(255,255,68,33%);}" + "*[bgColor=\"3\"]{background-color:rgba(68,255,68,33%);}" + "*[bgColor=\"4\"]{background-color:rgba(68,255,255,33%);}" + "*[bgColor=\"5\"]{background-color:rgba(68,68,255,33%);}" + "*[bgColor=\"6\"]{background-color:rgba(255,68,255,33%);}" + "*[bgColor=\"7\"]{background-color:rgba(68,68,68,33%);}" "*[bgColor=\"8\"]{background-color:rgba(255,255,255,33%);}")); obs_data_t *privData = obs_sceneitem_get_private_settings(item); @@ -4304,14 +4327,13 @@ QMenu *OBSBasic::AddBackgroundColorMenu(QMenu *menu, QWidgetAction *widgetAction obs_data_set_default_int(privData, "color-preset", 0); int preset = obs_data_get_int(privData, "color-preset"); - action = menu->addAction(QTStr("Clear"), this, - + SLOT(ColorChange())); + action = menu->addAction(QTStr("Clear"), this, +SLOT(ColorChange())); action->setCheckable(true); action->setProperty("bgColor", 0); action->setChecked(preset == 0); action = menu->addAction(QTStr("CustomColor"), this, - + SLOT(ColorChange())); + +SLOT(ColorChange())); action->setCheckable(true); action->setProperty("bgColor", 1); action->setChecked(preset == 1); @@ -4323,8 +4345,8 @@ QMenu *OBSBasic::AddBackgroundColorMenu(QMenu *menu, QWidgetAction *widgetAction for (int i = 1; i < 9; i++) { stringstream button; button << "preset" << i; - QPushButton *colorButton = select->findChild( - button.str().c_str()); + QPushButton *colorButton = + select->findChild(button.str().c_str()); if (preset == i + 1) colorButton->setStyleSheet("border: 2px solid black"); @@ -4339,8 +4361,7 @@ QMenu *OBSBasic::AddBackgroundColorMenu(QMenu *menu, QWidgetAction *widgetAction } ColorSelect::ColorSelect(QWidget *parent) - : QWidget(parent), - ui(new Ui::ColorSelect) + : QWidget(parent), ui(new Ui::ColorSelect) { ui->setupUi(this); } @@ -4358,11 +4379,11 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) if (preview) { QAction *action = popup.addAction( - QTStr("Basic.Main.PreviewConextMenu.Enable"), - this, SLOT(TogglePreview())); + QTStr("Basic.Main.PreviewConextMenu.Enable"), this, + SLOT(TogglePreview())); action->setCheckable(true); action->setChecked( - obs_display_enabled(ui->preview->GetDisplay())); + obs_display_enabled(ui->preview->GetDisplay())); if (IsPreviewProgramMode()) action->setEnabled(false); @@ -4371,13 +4392,13 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) previewProjectorSource = new QMenu(QTStr("PreviewProjector")); AddProjectorMenuMonitors(previewProjectorSource, this, - SLOT(OpenPreviewProjector())); + SLOT(OpenPreviewProjector())); popup.addMenu(previewProjectorSource); - QAction *previewWindow = popup.addAction( - QTStr("PreviewWindow"), - this, SLOT(OpenPreviewWindow())); + QAction *previewWindow = + popup.addAction(QTStr("PreviewWindow"), this, + SLOT(OpenPreviewWindow())); popup.addAction(previewWindow); @@ -4393,13 +4414,13 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) if (ui->sources->MultipleBaseSelected()) { popup.addSeparator(); - popup.addAction(QTStr("Basic.Main.GroupItems"), - ui->sources, SLOT(GroupSelectedItems())); + popup.addAction(QTStr("Basic.Main.GroupItems"), ui->sources, + SLOT(GroupSelectedItems())); } else if (ui->sources->GroupsSelected()) { popup.addSeparator(); - popup.addAction(QTStr("Basic.Main.Ungroup"), - ui->sources, SLOT(UngroupSelectedGroups())); + popup.addAction(QTStr("Basic.Main.Ungroup"), ui->sources, + SLOT(UngroupSelectedGroups())); } popup.addSeparator(); @@ -4421,16 +4442,15 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) obs_source_t *source = obs_sceneitem_get_source(sceneItem); uint32_t flags = obs_source_get_output_flags(source); bool isAsyncVideo = (flags & OBS_SOURCE_ASYNC_VIDEO) == - OBS_SOURCE_ASYNC_VIDEO; - bool hasAudio = (flags & OBS_SOURCE_AUDIO) == - OBS_SOURCE_AUDIO; + OBS_SOURCE_ASYNC_VIDEO; + bool hasAudio = (flags & OBS_SOURCE_AUDIO) == OBS_SOURCE_AUDIO; QAction *action; colorMenu = new QMenu(QTStr("ChangeBG")); colorWidgetAction = new QWidgetAction(colorMenu); colorSelect = new ColorSelect(colorMenu); - popup.addMenu(AddBackgroundColorMenu(colorMenu, - colorWidgetAction, colorSelect, sceneItem)); + popup.addMenu(AddBackgroundColorMenu( + colorMenu, colorWidgetAction, colorSelect, sceneItem)); popup.addAction(QTStr("Rename"), this, SLOT(EditSceneItemName())); popup.addAction(QTStr("Remove"), this, @@ -4441,33 +4461,33 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) sourceProjector = new QMenu(QTStr("SourceProjector")); AddProjectorMenuMonitors(sourceProjector, this, - SLOT(OpenSourceProjector())); + SLOT(OpenSourceProjector())); QAction *sourceWindow = popup.addAction( - QTStr("SourceWindow"), - this, SLOT(OpenSourceWindow())); + QTStr("SourceWindow"), this, SLOT(OpenSourceWindow())); popup.addAction(sourceWindow); popup.addSeparator(); if (hasAudio) { - QAction *actionHideMixer = popup.addAction( - QTStr("HideMixer"), - this, SLOT(ToggleHideMixer())); + QAction *actionHideMixer = + popup.addAction(QTStr("HideMixer"), this, + SLOT(ToggleHideMixer())); actionHideMixer->setCheckable(true); actionHideMixer->setChecked(SourceMixerHidden(source)); } if (isAsyncVideo) { deinterlaceMenu = new QMenu(QTStr("Deinterlacing")); - popup.addMenu(AddDeinterlacingMenu(deinterlaceMenu, source)); + popup.addMenu( + AddDeinterlacingMenu(deinterlaceMenu, source)); popup.addSeparator(); } - QAction *resizeOutput = popup.addAction( - QTStr("ResizeOutputSizeOfSource"), this, - SLOT(ResizeOutputSizeOfSource())); + QAction *resizeOutput = + popup.addAction(QTStr("ResizeOutputSizeOfSource"), this, + SLOT(ResizeOutputSizeOfSource())); int width = obs_source_get_width(source); int height = obs_source_get_height(source); @@ -4478,7 +4498,8 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) resizeOutput->setEnabled(false); scaleFilteringMenu = new QMenu(QTStr("ScaleFiltering")); - popup.addMenu(AddScaleFilteringMenu(scaleFilteringMenu, sceneItem)); + popup.addMenu( + AddScaleFilteringMenu(scaleFilteringMenu, sceneItem)); popup.addSeparator(); popup.addMenu(sourceProjector); @@ -4486,13 +4507,12 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) popup.addSeparator(); action = popup.addAction(QTStr("Interact"), this, - SLOT(on_actionInteract_triggered())); + SLOT(on_actionInteract_triggered())); action->setEnabled(obs_source_get_output_flags(source) & - OBS_SOURCE_INTERACTION); + OBS_SOURCE_INTERACTION); - popup.addAction(QTStr("Filters"), this, - SLOT(OpenFilters())); + popup.addAction(QTStr("Filters"), this, SLOT(OpenFilters())); popup.addAction(QTStr("Properties"), this, SLOT(on_actionSourceProperties_triggered())); @@ -4519,8 +4539,9 @@ void OBSBasic::on_scenes_itemDoubleClicked(QListWidgetItem *witem) return; if (IsPreviewProgramMode()) { - bool doubleClickSwitch = config_get_bool(App()->GlobalConfig(), - "BasicWindow", "TransitionOnDoubleClick"); + bool doubleClickSwitch = + config_get_bool(App()->GlobalConfig(), "BasicWindow", + "TransitionOnDoubleClick"); if (doubleClickSwitch) { OBSScene scene = GetCurrentScene(); @@ -4551,26 +4572,24 @@ QMenu *OBSBasic::CreateAddSourcePopupMenu() QMenu *popup = new QMenu(QTStr("Add"), this); QMenu *deprecated = new QMenu(QTStr("Deprecated"), popup); - auto getActionAfter = [] (QMenu *menu, const QString &name) - { - QList actions = menu->actions(); + auto getActionAfter = [](QMenu *menu, const QString &name) { + QList actions = menu->actions(); for (QAction *menuAction : actions) { if (menuAction->text().compare(name) >= 0) return menuAction; } - return (QAction*)nullptr; + return (QAction *)nullptr; }; - auto addSource = [this, getActionAfter] (QMenu *popup, - const char *type, const char *name) - { + auto addSource = [this, getActionAfter](QMenu *popup, const char *type, + const char *name) { QString qname = QT_UTF8(name); QAction *popupItem = new QAction(qname, this); popupItem->setData(QT_UTF8(type)); - connect(popupItem, SIGNAL(triggered(bool)), - this, SLOT(AddSourceFromAction())); + connect(popupItem, SIGNAL(triggered(bool)), this, + SLOT(AddSourceFromAction())); QAction *after = getActionAfter(popup, qname); popup->insertAction(after, popupItem); @@ -4597,8 +4616,8 @@ QMenu *OBSBasic::CreateAddSourcePopupMenu() popup->addSeparator(); QAction *addGroup = new QAction(QTStr("Group"), this); addGroup->setData(QT_UTF8("group")); - connect(addGroup, SIGNAL(triggered(bool)), - this, SLOT(AddSourceFromAction())); + connect(addGroup, SIGNAL(triggered(bool)), this, + SLOT(AddSourceFromAction())); popup->addAction(addGroup); if (!foundDeprecated) { @@ -4620,7 +4639,7 @@ QMenu *OBSBasic::CreateAddSourcePopupMenu() void OBSBasic::AddSourceFromAction() { - QAction *action = qobject_cast(sender()); + QAction *action = qobject_cast(sender()); if (!action) return; @@ -4631,9 +4650,9 @@ void OBSBasic::AddSourcePopupMenu(const QPoint &pos) { if (!GetCurrentScene()) { // Tell the user he needs a scene first (help beginners). - OBSMessageBox::information(this, - QTStr("Basic.Main.AddSourceHelp.Title"), - QTStr("Basic.Main.AddSourceHelp.Text")); + OBSMessageBox::information( + this, QTStr("Basic.Main.AddSourceHelp.Title"), + QTStr("Basic.Main.AddSourceHelp.Text")); return; } @@ -4650,7 +4669,7 @@ void OBSBasic::on_actionAddSource_triggered() static bool remove_items(obs_scene_t *, obs_sceneitem_t *item, void *param) { vector &items = - *reinterpret_cast*>(param); + *reinterpret_cast *>(param); if (obs_sceneitem_selected(item)) { items.emplace_back(item); @@ -4669,15 +4688,14 @@ void OBSBasic::on_actionRemoveSource_triggered() if (!items.size()) return; - auto removeMultiple = [this] (size_t count) - { + auto removeMultiple = [this](size_t count) { QString text = QTStr("ConfirmRemove.TextMultiple") - .arg(QString::number(count)); + .arg(QString::number(count)); QMessageBox remove_items(this); remove_items.setText(text); - QAbstractButton *Yes = remove_items.addButton(QTStr("Yes"), - QMessageBox::YesRole); + QAbstractButton *Yes = remove_items.addButton( + QTStr("Yes"), QMessageBox::YesRole); remove_items.addButton(QTStr("No"), QMessageBox::NoRole); remove_items.setIcon(QMessageBox::Question); remove_items.setWindowTitle(QTStr("ConfirmRemove.Title")); @@ -4760,7 +4778,7 @@ static BPtr ReadLogFile(const char *subdir, const char *log) if (GetConfigPath(logDir, sizeof(logDir), subdir) <= 0) return nullptr; - string path = (char*)logDir; + string path = logDir; path += "/"; path += log; @@ -4784,22 +4802,21 @@ void OBSBasic::UploadLog(const char *subdir, const char *file) ui->menuLogFiles->setEnabled(false); stringstream ss; - ss << "OBS " << App()->GetVersionString() - << " log file uploaded at " << CurrentDateTimeString() - << "\n\n" << fileString; - + ss << "OBS " << App()->GetVersionString() << " log file uploaded at " + << CurrentDateTimeString() << "\n\n" + << fileString; if (logUploadThread) { logUploadThread->wait(); } - RemoteTextThread *thread = new RemoteTextThread( - "https://obsproject.com/logs/upload", - "text/plain", ss.str().c_str()); + RemoteTextThread *thread = + new RemoteTextThread("https://obsproject.com/logs/upload", + "text/plain", ss.str().c_str()); logUploadThread.reset(thread); - connect(thread, &RemoteTextThread::Result, - this, &OBSBasic::logUploadFinished); + connect(thread, &RemoteTextThread::Result, this, + &OBSBasic::logUploadFinished); logUploadThread->start(); } @@ -4829,9 +4846,9 @@ void OBSBasic::on_actionViewCurrentLog_triggered() if (GetConfigPath(logDir, sizeof(logDir), "obs-studio/logs") <= 0) return; - const char* log = App()->GetCurrentLog(); + const char *log = App()->GetCurrentLog(); - string path = (char*)logDir; + string path = logDir; path += "/"; path += log; @@ -4864,9 +4881,9 @@ void OBSBasic::logUploadFinished(const QString &text, const QString &error) ui->menuLogFiles->setEnabled(true); if (text.isEmpty()) { - OBSMessageBox::critical(this, - QTStr("LogReturnDialog.ErrorUploadingLog"), - error); + OBSMessageBox::critical( + this, QTStr("LogReturnDialog.ErrorUploadingLog"), + error); return; } @@ -4880,26 +4897,26 @@ void OBSBasic::logUploadFinished(const QString &text, const QString &error) } static void RenameListItem(OBSBasic *parent, QListWidget *listWidget, - obs_source_t *source, const string &name) + obs_source_t *source, const string &name) { const char *prevName = obs_source_get_name(source); if (name == prevName) return; - obs_source_t *foundSource = obs_get_source_by_name(name.c_str()); - QListWidgetItem *listItem = listWidget->currentItem(); + obs_source_t *foundSource = obs_get_source_by_name(name.c_str()); + QListWidgetItem *listItem = listWidget->currentItem(); if (foundSource || name.empty()) { listItem->setText(QT_UTF8(prevName)); if (foundSource) { OBSMessageBox::warning(parent, - QTStr("NameExists.Title"), - QTStr("NameExists.Text")); + QTStr("NameExists.Title"), + QTStr("NameExists.Text")); } else if (name.empty()) { OBSMessageBox::warning(parent, - QTStr("NoNameEntered.Title"), - QTStr("NoNameEntered.Text")); + QTStr("NoNameEntered.Title"), + QTStr("NoNameEntered.Text")); } obs_source_release(foundSource); @@ -4910,11 +4927,11 @@ static void RenameListItem(OBSBasic *parent, QListWidget *listWidget, } void OBSBasic::SceneNameEdited(QWidget *editor, - QAbstractItemDelegate::EndEditHint endHint) + QAbstractItemDelegate::EndEditHint endHint) { - OBSScene scene = GetCurrentScene(); - QLineEdit *edit = qobject_cast(editor); - string text = QT_TO_UTF8(edit->text().trimmed()); + OBSScene scene = GetCurrentScene(); + QLineEdit *edit = qobject_cast(editor); + string text = QT_TO_UTF8(edit->text().trimmed()); if (!scene) return; @@ -4978,9 +4995,10 @@ void OBSBasic::StartStreaming() } if (!outputHandler->StartStreaming(service)) { - QString message = !outputHandler->lastError.empty() - ? QTStr(outputHandler->lastError.c_str()) - : QTStr("Output.StartFailedGeneric"); + QString message = + !outputHandler->lastError.empty() + ? QTStr(outputHandler->lastError.c_str()) + : QTStr("Output.StartFailedGeneric"); ui->streamButton->setText(QTStr("Basic.Main.StartStreaming")); ui->streamButton->setEnabled(true); ui->streamButton->setChecked(false); @@ -4991,17 +5009,17 @@ void OBSBasic::StartStreaming() } QMessageBox::critical(this, QTStr("Output.StartStreamFailed"), - message); + message); return; } - bool recordWhenStreaming = config_get_bool(GetGlobalConfig(), - "BasicWindow", "RecordWhenStreaming"); + bool recordWhenStreaming = config_get_bool( + GetGlobalConfig(), "BasicWindow", "RecordWhenStreaming"); if (recordWhenStreaming) StartRecording(); - bool replayBufferWhileStreaming = config_get_bool(GetGlobalConfig(), - "BasicWindow", "ReplayBufferWhileStreaming"); + bool replayBufferWhileStreaming = config_get_bool( + GetGlobalConfig(), "BasicWindow", "ReplayBufferWhileStreaming"); if (replayBufferWhileStreaming) StartReplayBuffer(); } @@ -5010,7 +5028,7 @@ void OBSBasic::StartStreaming() static inline void UpdateProcessPriority() { const char *priority = config_get_string(App()->GlobalConfig(), - "General", "ProcessPriority"); + "General", "ProcessPriority"); if (priority && strcmp(priority, "Normal") != 0) SetProcessPriority(priority); } @@ -5018,13 +5036,17 @@ static inline void UpdateProcessPriority() static inline void ClearProcessPriority() { const char *priority = config_get_string(App()->GlobalConfig(), - "General", "ProcessPriority"); + "General", "ProcessPriority"); if (priority && strcmp(priority, "Normal") != 0) SetProcessPriority("Normal"); } #else -#define UpdateProcessPriority() do {} while(false) -#define ClearProcessPriority() do {} while(false) +#define UpdateProcessPriority() \ + do { \ + } while (false) +#define ClearProcessPriority() \ + do { \ + } while (false) #endif inline void OBSBasic::OnActivate() @@ -5036,8 +5058,9 @@ inline void OBSBasic::OnActivate() UpdateProcessPriority(); if (trayIcon) - trayIcon->setIcon(QIcon::fromTheme("obs-tray-active", - QIcon(":/res/images/tray_active.png"))); + trayIcon->setIcon(QIcon::fromTheme( + "obs-tray-active", + QIcon(":/res/images/tray_active.png"))); } } @@ -5050,8 +5073,8 @@ inline void OBSBasic::OnDeactivate() ClearProcessPriority(); if (trayIcon) - trayIcon->setIcon(QIcon::fromTheme("obs-tray", - QIcon(":/res/images/obs.png"))); + trayIcon->setIcon(QIcon::fromTheme( + "obs-tray", QIcon(":/res/images/obs.png"))); } } @@ -5064,17 +5087,19 @@ void OBSBasic::StopStreaming() OnDeactivate(); - bool recordWhenStreaming = config_get_bool(GetGlobalConfig(), - "BasicWindow", "RecordWhenStreaming"); - bool keepRecordingWhenStreamStops = config_get_bool(GetGlobalConfig(), - "BasicWindow", "KeepRecordingWhenStreamStops"); + bool recordWhenStreaming = config_get_bool( + GetGlobalConfig(), "BasicWindow", "RecordWhenStreaming"); + bool keepRecordingWhenStreamStops = + config_get_bool(GetGlobalConfig(), "BasicWindow", + "KeepRecordingWhenStreamStops"); if (recordWhenStreaming && !keepRecordingWhenStreamStops) StopRecording(); - bool replayBufferWhileStreaming = config_get_bool(GetGlobalConfig(), - "BasicWindow", "ReplayBufferWhileStreaming"); - bool keepReplayBufferStreamStops = config_get_bool(GetGlobalConfig(), - "BasicWindow", "KeepReplayBufferStreamStops"); + bool replayBufferWhileStreaming = config_get_bool( + GetGlobalConfig(), "BasicWindow", "ReplayBufferWhileStreaming"); + bool keepReplayBufferStreamStops = + config_get_bool(GetGlobalConfig(), "BasicWindow", + "KeepReplayBufferStreamStops"); if (replayBufferWhileStreaming && !keepReplayBufferStreamStops) StopReplayBuffer(); } @@ -5088,17 +5113,19 @@ void OBSBasic::ForceStopStreaming() OnDeactivate(); - bool recordWhenStreaming = config_get_bool(GetGlobalConfig(), - "BasicWindow", "RecordWhenStreaming"); - bool keepRecordingWhenStreamStops = config_get_bool(GetGlobalConfig(), - "BasicWindow", "KeepRecordingWhenStreamStops"); + bool recordWhenStreaming = config_get_bool( + GetGlobalConfig(), "BasicWindow", "RecordWhenStreaming"); + bool keepRecordingWhenStreamStops = + config_get_bool(GetGlobalConfig(), "BasicWindow", + "KeepRecordingWhenStreamStops"); if (recordWhenStreaming && !keepRecordingWhenStreamStops) StopRecording(); - bool replayBufferWhileStreaming = config_get_bool(GetGlobalConfig(), - "BasicWindow", "ReplayBufferWhileStreaming"); - bool keepReplayBufferStreamStops = config_get_bool(GetGlobalConfig(), - "BasicWindow", "KeepReplayBufferStreamStops"); + bool replayBufferWhileStreaming = config_get_bool( + GetGlobalConfig(), "BasicWindow", "ReplayBufferWhileStreaming"); + bool keepReplayBufferStreamStops = + config_get_bool(GetGlobalConfig(), "BasicWindow", + "KeepReplayBufferStreamStops"); if (replayBufferWhileStreaming && !keepReplayBufferStreamStops) StopReplayBuffer(); } @@ -5118,10 +5145,10 @@ void OBSBasic::StreamDelayStarting(int sec) startStreamMenu->deleteLater(); startStreamMenu = new QMenu(); - startStreamMenu->addAction(QTStr("Basic.Main.StopStreaming"), - this, SLOT(StopStreaming())); - startStreamMenu->addAction(QTStr("Basic.Main.ForceStopStreaming"), - this, SLOT(ForceStopStreaming())); + startStreamMenu->addAction(QTStr("Basic.Main.StopStreaming"), this, + SLOT(StopStreaming())); + startStreamMenu->addAction(QTStr("Basic.Main.ForceStopStreaming"), this, + SLOT(ForceStopStreaming())); ui->streamButton->setMenu(startStreamMenu); ui->statusbar->StreamDelayStarting(sec); @@ -5144,10 +5171,10 @@ void OBSBasic::StreamDelayStopping(int sec) startStreamMenu->deleteLater(); startStreamMenu = new QMenu(); - startStreamMenu->addAction(QTStr("Basic.Main.StartStreaming"), - this, SLOT(StartStreaming())); - startStreamMenu->addAction(QTStr("Basic.Main.ForceStopStreaming"), - this, SLOT(ForceStopStreaming())); + startStreamMenu->addAction(QTStr("Basic.Main.StartStreaming"), this, + SLOT(StartStreaming())); + startStreamMenu->addAction(QTStr("Basic.Main.ForceStopStreaming"), this, + SLOT(ForceStopStreaming())); ui->streamButton->setMenu(startStreamMenu); ui->statusbar->StreamDelayStopping(sec); @@ -5228,7 +5255,7 @@ void OBSBasic::StreamingStop(int code, QString last_error) if (use_last_error && !last_error.isEmpty()) dstr_printf(errorMessage, "%s\n\n%s", errorDescription, - QT_TO_UTF8(last_error)); + QT_TO_UTF8(last_error)); else dstr_copy(errorMessage, errorDescription); @@ -5252,17 +5279,18 @@ void OBSBasic::StreamingStop(int code, QString last_error) blog(LOG_INFO, STREAMING_STOP); if (encode_error) { - OBSMessageBox::information(this, - QTStr("Output.StreamEncodeError.Title"), - QTStr("Output.StreamEncodeError.Msg")); + OBSMessageBox::information( + this, QTStr("Output.StreamEncodeError.Title"), + QTStr("Output.StreamEncodeError.Msg")); } else if (code != OBS_OUTPUT_SUCCESS && isVisible()) { OBSMessageBox::information(this, - QTStr("Output.ConnectFail.Title"), - QT_UTF8(errorMessage)); + QTStr("Output.ConnectFail.Title"), + QT_UTF8(errorMessage)); } else if (code != OBS_OUTPUT_SUCCESS && !isVisible()) { - SysTrayNotify(QT_UTF8(errorDescription), QSystemTrayIcon::Warning); + SysTrayNotify(QT_UTF8(errorDescription), + QSystemTrayIcon::Warning); } if (!startStreamMenu.isNull()) { @@ -5277,14 +5305,16 @@ void OBSBasic::AutoRemux() const char *mode = config_get_string(basicConfig, "Output", "Mode"); bool advanced = astrcmpi(mode, "Advanced") == 0; - const char *path = !advanced - ? config_get_string(basicConfig, "SimpleOutput", "FilePath") - : config_get_string(basicConfig, "AdvOut", "RecFilePath"); + const char *path = !advanced ? config_get_string(basicConfig, + "SimpleOutput", + "FilePath") + : config_get_string(basicConfig, "AdvOut", + "RecFilePath"); /* do not save if using FFmpeg output in advanced output mode */ if (advanced) { - const char *type = config_get_string(basicConfig, "AdvOut", - "RecType"); + const char *type = + config_get_string(basicConfig, "AdvOut", "RecType"); if (astrcmpi(type, "FFmpeg") == 0) { return; } @@ -5320,6 +5350,12 @@ void OBSBasic::StartRecording() if (disableOutputsRef) return; + if (LowDiskSpace()) { + DiskSpaceMessage(); + ui->recordButton->setChecked(false); + return; + } + if (api) api->on_event(OBS_FRONTEND_EVENT_RECORDING_STARTING); @@ -5364,7 +5400,11 @@ void OBSBasic::RecordingStart() if (api) api->on_event(OBS_FRONTEND_EVENT_RECORDING_STARTED); + if (!diskFullTimer->isActive()) + diskFullTimer->start(1000); + OnActivate(); + UpdatePause(); blog(LOG_INFO, RECORDING_START); } @@ -5381,19 +5421,18 @@ void OBSBasic::RecordingStop(int code, QString last_error) blog(LOG_INFO, RECORDING_STOP); if (code == OBS_OUTPUT_UNSUPPORTED && isVisible()) { - OBSMessageBox::critical(this, - QTStr("Output.RecordFail.Title"), - QTStr("Output.RecordFail.Unsupported")); + OBSMessageBox::critical(this, QTStr("Output.RecordFail.Title"), + QTStr("Output.RecordFail.Unsupported")); } else if (code == OBS_OUTPUT_ENCODE_ERROR && isVisible()) { - OBSMessageBox::warning(this, - QTStr("Output.RecordError.Title"), - QTStr("Output.RecordError.EncodeErrorMsg")); + OBSMessageBox::warning( + this, QTStr("Output.RecordError.Title"), + QTStr("Output.RecordError.EncodeErrorMsg")); } else if (code == OBS_OUTPUT_NO_SPACE && isVisible()) { OBSMessageBox::warning(this, - QTStr("Output.RecordNoSpace.Title"), - QTStr("Output.RecordNoSpace.Msg")); + QTStr("Output.RecordNoSpace.Title"), + QTStr("Output.RecordNoSpace.Msg")); } else if (code != OBS_OUTPUT_SUCCESS && isVisible()) { @@ -5405,38 +5444,75 @@ void OBSBasic::RecordingStop(int code, QString last_error) if (use_last_error && !last_error.isEmpty()) dstr_printf(errorMessage, "%s\n\n%s", errorDescription, - QT_TO_UTF8(last_error)); + QT_TO_UTF8(last_error)); else dstr_copy(errorMessage, errorDescription); - OBSMessageBox::critical(this, - QTStr("Output.RecordError.Title"), - QT_UTF8(errorMessage)); + OBSMessageBox::critical(this, QTStr("Output.RecordError.Title"), + QT_UTF8(errorMessage)); } else if (code == OBS_OUTPUT_UNSUPPORTED && !isVisible()) { SysTrayNotify(QTStr("Output.RecordFail.Unsupported"), - QSystemTrayIcon::Warning); + QSystemTrayIcon::Warning); } else if (code == OBS_OUTPUT_NO_SPACE && !isVisible()) { SysTrayNotify(QTStr("Output.RecordNoSpace.Msg"), - QSystemTrayIcon::Warning); + QSystemTrayIcon::Warning); } else if (code != OBS_OUTPUT_SUCCESS && !isVisible()) { SysTrayNotify(QTStr("Output.RecordError.Msg"), - QSystemTrayIcon::Warning); + QSystemTrayIcon::Warning); } if (api) api->on_event(OBS_FRONTEND_EVENT_RECORDING_STOPPED); + if (diskFullTimer->isActive()) + diskFullTimer->stop(); + if (remuxAfterRecord) AutoRemux(); OnDeactivate(); + UpdatePause(false); } #define RP_NO_HOTKEY_TITLE QTStr("Output.ReplayBuffer.NoHotkey.Title") -#define RP_NO_HOTKEY_TEXT QTStr("Output.ReplayBuffer.NoHotkey.Msg") +#define RP_NO_HOTKEY_TEXT QTStr("Output.ReplayBuffer.NoHotkey.Msg") + +extern volatile bool recording_paused; +extern volatile bool replaybuf_active; + +void OBSBasic::ShowReplayBufferPauseWarning() +{ + auto msgBox = []() { + QMessageBox msgbox(App()->GetMainWindow()); + msgbox.setWindowTitle(QTStr("Output.ReplayBuffer." + "PauseWarning.Title")); + msgbox.setText(QTStr("Output.ReplayBuffer." + "PauseWarning.Text")); + msgbox.setIcon(QMessageBox::Icon::Information); + msgbox.addButton(QMessageBox::Ok); + + QCheckBox *cb = new QCheckBox(QTStr("DoNotShowAgain")); + msgbox.setCheckBox(cb); + + msgbox.exec(); + + if (cb->isChecked()) { + config_set_bool(App()->GlobalConfig(), "General", + "WarnedAboutReplayBufferPausing", true); + config_save_safe(App()->GlobalConfig(), "tmp", nullptr); + } + }; + + bool warned = config_get_bool(App()->GlobalConfig(), "General", + "WarnedAboutReplayBufferPausing"); + if (!warned) { + QMetaObject::invokeMethod(App(), "Exec", Qt::QueuedConnection, + Q_ARG(VoidFunc, msgBox)); + } +} void OBSBasic::StartReplayBuffer() { @@ -5452,18 +5528,23 @@ void OBSBasic::StartReplayBuffer() return; } + if (LowDiskSpace()) { + DiskSpaceMessage(); + replayBufferButton->setChecked(false); + return; + } + obs_output_t *output = outputHandler->replayBuffer; obs_data_t *hotkeys = obs_hotkeys_save_output(output); - obs_data_array_t *bindings = obs_data_get_array(hotkeys, - "ReplayBuffer.Save"); + obs_data_array_t *bindings = + obs_data_get_array(hotkeys, "ReplayBuffer.Save"); size_t count = obs_data_array_count(bindings); obs_data_array_release(bindings); obs_data_release(hotkeys); if (!count) { - OBSMessageBox::information(this, - RP_NO_HOTKEY_TITLE, - RP_NO_HOTKEY_TEXT); + OBSMessageBox::information(this, RP_NO_HOTKEY_TITLE, + RP_NO_HOTKEY_TEXT); replayBufferButton->setChecked(false); return; } @@ -5472,8 +5553,12 @@ void OBSBasic::StartReplayBuffer() api->on_event(OBS_FRONTEND_EVENT_REPLAY_BUFFER_STARTING); SaveProject(); - if (!outputHandler->StartReplayBuffer()) + + if (!outputHandler->StartReplayBuffer()) { replayBufferButton->setChecked(false); + } else if (os_atomic_load_bool(&recording_paused)) { + ShowReplayBufferPauseWarning(); + } } void OBSBasic::ReplayBufferStopping() @@ -5532,8 +5617,8 @@ void OBSBasic::ReplayBufferSave() return; calldata_t cd = {0}; - proc_handler_t *ph = obs_output_get_proc_handler( - outputHandler->replayBuffer); + proc_handler_t *ph = + obs_output_get_proc_handler(outputHandler->replayBuffer); proc_handler_call(ph, "save", &cd); calldata_free(&cd); } @@ -5552,31 +5637,29 @@ void OBSBasic::ReplayBufferStop(int code) blog(LOG_INFO, REPLAY_BUFFER_STOP); if (code == OBS_OUTPUT_UNSUPPORTED && isVisible()) { - OBSMessageBox::critical(this, - QTStr("Output.RecordFail.Title"), - QTStr("Output.RecordFail.Unsupported")); + OBSMessageBox::critical(this, QTStr("Output.RecordFail.Title"), + QTStr("Output.RecordFail.Unsupported")); } else if (code == OBS_OUTPUT_NO_SPACE && isVisible()) { OBSMessageBox::warning(this, - QTStr("Output.RecordNoSpace.Title"), - QTStr("Output.RecordNoSpace.Msg")); + QTStr("Output.RecordNoSpace.Title"), + QTStr("Output.RecordNoSpace.Msg")); } else if (code != OBS_OUTPUT_SUCCESS && isVisible()) { - OBSMessageBox::critical(this, - QTStr("Output.RecordError.Title"), - QTStr("Output.RecordError.Msg")); + OBSMessageBox::critical(this, QTStr("Output.RecordError.Title"), + QTStr("Output.RecordError.Msg")); } else if (code == OBS_OUTPUT_UNSUPPORTED && !isVisible()) { SysTrayNotify(QTStr("Output.RecordFail.Unsupported"), - QSystemTrayIcon::Warning); + QSystemTrayIcon::Warning); } else if (code == OBS_OUTPUT_NO_SPACE && !isVisible()) { SysTrayNotify(QTStr("Output.RecordNoSpace.Msg"), - QSystemTrayIcon::Warning); + QSystemTrayIcon::Warning); } else if (code != OBS_OUTPUT_SUCCESS && !isVisible()) { SysTrayNotify(QTStr("Output.RecordError.Msg"), - QSystemTrayIcon::Warning); + QSystemTrayIcon::Warning); } if (api) @@ -5596,8 +5679,8 @@ bool OBSBasic::NoSourcesConfirmation() QMessageBox messageBox(this); messageBox.setWindowTitle(QTStr("NoSources.Title")); messageBox.setText(msg); - QAbstractButton *Yes = messageBox.addButton(QTStr("Yes"), - QMessageBox::YesRole); + QAbstractButton *Yes = messageBox.addButton( + QTStr("Yes"), QMessageBox::YesRole); messageBox.addButton(QTStr("No"), QMessageBox::NoRole); messageBox.setIcon(QMessageBox::Question); messageBox.exec(); @@ -5613,13 +5696,13 @@ void OBSBasic::on_streamButton_clicked() { if (outputHandler->StreamingActive()) { bool confirm = config_get_bool(GetGlobalConfig(), "BasicWindow", - "WarnBeforeStoppingStream"); + "WarnBeforeStoppingStream"); if (confirm && isVisible()) { QMessageBox::StandardButton button = - OBSMessageBox::question(this, - QTStr("ConfirmStop.Title"), - QTStr("ConfirmStop.Text")); + OBSMessageBox::question( + this, QTStr("ConfirmStop.Title"), + QTStr("ConfirmStop.Text")); if (button == QMessageBox::No) { ui->streamButton->setChecked(true); @@ -5635,7 +5718,7 @@ void OBSBasic::on_streamButton_clicked() } bool confirm = config_get_bool(GetGlobalConfig(), "BasicWindow", - "WarnBeforeStartingStream"); + "WarnBeforeStartingStream"); obs_data_t *settings = obs_service_get_settings(service); bool bwtest = obs_data_get_bool(settings, "bwtest"); @@ -5643,9 +5726,9 @@ void OBSBasic::on_streamButton_clicked() if (bwtest && isVisible()) { QMessageBox::StandardButton button = - OBSMessageBox::question(this, - QTStr("ConfirmBWTest.Title"), - QTStr("ConfirmBWTest.Text")); + OBSMessageBox::question( + this, QTStr("ConfirmBWTest.Title"), + QTStr("ConfirmBWTest.Text")); if (button == QMessageBox::No) { ui->streamButton->setChecked(false); @@ -5653,9 +5736,9 @@ void OBSBasic::on_streamButton_clicked() } } else if (confirm && isVisible()) { QMessageBox::StandardButton button = - OBSMessageBox::question(this, - QTStr("ConfirmStart.Title"), - QTStr("ConfirmStart.Text")); + OBSMessageBox::question( + this, QTStr("ConfirmStart.Title"), + QTStr("ConfirmStart.Text")); if (button == QMessageBox::No) { ui->streamButton->setChecked(false); @@ -5670,6 +5753,20 @@ void OBSBasic::on_streamButton_clicked() void OBSBasic::on_recordButton_clicked() { if (outputHandler->RecordingActive()) { + bool confirm = config_get_bool(GetGlobalConfig(), "BasicWindow", + "WarnBeforeStoppingRecord"); + + if (confirm && isVisible()) { + QMessageBox::StandardButton button = + OBSMessageBox::question( + this, QTStr("ConfirmStopRecord.Title"), + QTStr("ConfirmStopRecord.Text")); + + if (button == QMessageBox::No) { + ui->recordButton->setChecked(true); + return; + } + } StopRecording(); } else { if (!NoSourcesConfirmation()) { @@ -5738,46 +5835,43 @@ void OBSBasic::on_preview_customContextMenuRequested(const QPoint &pos) UNUSED_PARAMETER(pos); } -void OBSBasic::on_program_customContextMenuRequested(const QPoint&) +void OBSBasic::on_program_customContextMenuRequested(const QPoint &) { QMenu popup(this); QPointer studioProgramProjector; - studioProgramProjector = new QMenu( - QTStr("StudioProgramProjector")); + studioProgramProjector = new QMenu(QTStr("StudioProgramProjector")); AddProjectorMenuMonitors(studioProgramProjector, this, - SLOT(OpenStudioProgramProjector())); + SLOT(OpenStudioProgramProjector())); popup.addMenu(studioProgramProjector); - QAction *studioProgramWindow = popup.addAction( - QTStr("StudioProgramWindow"), - this, SLOT(OpenStudioProgramWindow())); + QAction *studioProgramWindow = + popup.addAction(QTStr("StudioProgramWindow"), this, + SLOT(OpenStudioProgramWindow())); popup.addAction(studioProgramWindow); popup.exec(QCursor::pos()); } -void OBSBasic::on_previewDisabledLabel_customContextMenuRequested( - const QPoint &pos) +void OBSBasic::PreviewDisabledMenu(const QPoint &pos) { QMenu popup(this); delete previewProjectorMain; - QAction *action = popup.addAction( - QTStr("Basic.Main.PreviewConextMenu.Enable"), - this, SLOT(TogglePreview())); + QAction *action = + popup.addAction(QTStr("Basic.Main.PreviewConextMenu.Enable"), + this, SLOT(TogglePreview())); action->setCheckable(true); action->setChecked(obs_display_enabled(ui->preview->GetDisplay())); previewProjectorMain = new QMenu(QTStr("PreviewProjector")); AddProjectorMenuMonitors(previewProjectorMain, this, - SLOT(OpenPreviewProjector())); + SLOT(OpenPreviewProjector())); - QAction *previewWindow = popup.addAction( - QTStr("PreviewWindow"), - this, SLOT(OpenPreviewWindow())); + QAction *previewWindow = popup.addAction(QTStr("PreviewWindow"), this, + SLOT(OpenPreviewWindow())); popup.addMenu(previewProjectorMain); popup.addAction(previewWindow); @@ -5797,7 +5891,7 @@ void OBSBasic::on_actionAlwaysOnTop_triggered() #endif QMetaObject::invokeMethod(this, "ToggleAlwaysOnTop", - Qt::QueuedConnection); + Qt::QueuedConnection); } void OBSBasic::ToggleAlwaysOnTop() @@ -5899,8 +5993,7 @@ static obs_sceneitem_crop copiedCropInfo; void OBSBasic::on_actionCopyTransform_triggered() { - auto func = [](obs_scene_t *scene, obs_sceneitem_t *item, void *param) - { + auto func = [](obs_scene_t *scene, obs_sceneitem_t *item, void *param) { if (!obs_sceneitem_selected(item)) return true; @@ -5920,8 +6013,7 @@ void OBSBasic::on_actionCopyTransform_triggered() void OBSBasic::on_actionPasteTransform_triggered() { - auto func = [](obs_scene_t *scene, obs_sceneitem_t *item, void *param) - { + auto func = [](obs_scene_t *scene, obs_sceneitem_t *item, void *param) { if (!obs_sceneitem_selected(item)) return true; @@ -5980,8 +6072,7 @@ static void GetItemBox(obs_sceneitem_t *item, vec3 &tl, vec3 &br) vec3_set(&tl, M_INFINITE, M_INFINITE, 0.0f); vec3_set(&br, -M_INFINITE, -M_INFINITE, 0.0f); - auto GetMinPos = [&] (float x, float y) - { + auto GetMinPos = [&](float x, float y) { vec3 pos; vec3_set(&pos, x, y, 0.0f); vec3_transform(&pos, &pos, &boxTransform); @@ -6015,21 +6106,23 @@ static void SetItemTL(obs_sceneitem_t *item, const vec3 &tl) } static bool RotateSelectedSources(obs_scene_t *scene, obs_sceneitem_t *item, - void *param) + void *param) { if (obs_sceneitem_is_group(item)) obs_sceneitem_group_enum_items(item, RotateSelectedSources, - param); + param); if (!obs_sceneitem_selected(item)) return true; - float rot = *reinterpret_cast(param); + float rot = *reinterpret_cast(param); vec3 tl = GetItemTL(item); rot += obs_sceneitem_get_rot(item); - if (rot >= 360.0f) rot -= 360.0f; - else if (rot <= -360.0f) rot += 360.0f; + if (rot >= 360.0f) + rot -= 360.0f; + else if (rot <= -360.0f) + rot += 360.0f; obs_sceneitem_set_rot(item, rot); obs_sceneitem_force_update_transform(item); @@ -6059,13 +6152,13 @@ void OBSBasic::on_actionRotate180_triggered() } static bool MultiplySelectedItemScale(obs_scene_t *scene, obs_sceneitem_t *item, - void *param) + void *param) { - vec2 &mul = *reinterpret_cast(param); + vec2 &mul = *reinterpret_cast(param); if (obs_sceneitem_is_group(item)) obs_sceneitem_group_enum_items(item, MultiplySelectedItemScale, - param); + param); if (!obs_sceneitem_selected(item)) return true; @@ -6089,7 +6182,7 @@ void OBSBasic::on_actionFlipHorizontal_triggered() vec2 scale; vec2_set(&scale, -1.0f, 1.0f); obs_scene_enum_items(GetCurrentScene(), MultiplySelectedItemScale, - &scale); + &scale); } void OBSBasic::on_actionFlipVertical_triggered() @@ -6097,17 +6190,18 @@ void OBSBasic::on_actionFlipVertical_triggered() vec2 scale; vec2_set(&scale, 1.0f, -1.0f); obs_scene_enum_items(GetCurrentScene(), MultiplySelectedItemScale, - &scale); + &scale); } static bool CenterAlignSelectedItems(obs_scene_t *scene, obs_sceneitem_t *item, - void *param) + void *param) { - obs_bounds_type boundsType = *reinterpret_cast(param); + obs_bounds_type boundsType = + *reinterpret_cast(param); if (obs_sceneitem_is_group(item)) obs_sceneitem_group_enum_items(item, CenterAlignSelectedItems, - param); + param); if (!obs_sceneitem_selected(item)) return true; @@ -6120,8 +6214,8 @@ static bool CenterAlignSelectedItems(obs_scene_t *scene, obs_sceneitem_t *item, itemInfo.alignment = OBS_ALIGN_LEFT | OBS_ALIGN_TOP; itemInfo.rot = 0.0f; - vec2_set(&itemInfo.bounds, - float(ovi.base_width), float(ovi.base_height)); + vec2_set(&itemInfo.bounds, float(ovi.base_width), + float(ovi.base_height)); itemInfo.bounds_type = boundsType; itemInfo.bounds_alignment = OBS_ALIGN_CENTER; @@ -6135,25 +6229,25 @@ void OBSBasic::on_actionFitToScreen_triggered() { obs_bounds_type boundsType = OBS_BOUNDS_SCALE_INNER; obs_scene_enum_items(GetCurrentScene(), CenterAlignSelectedItems, - &boundsType); + &boundsType); } void OBSBasic::on_actionStretchToScreen_triggered() { obs_bounds_type boundsType = OBS_BOUNDS_STRETCH; obs_scene_enum_items(GetCurrentScene(), CenterAlignSelectedItems, - &boundsType); + &boundsType); } enum class CenterType { Scene, Vertical, - Horizontal + Horizontal, }; static bool center_to_scene(obs_scene_t *, obs_sceneitem_t *item, void *param) { - CenterType centerType = *reinterpret_cast(param); + CenterType centerType = *reinterpret_cast(param); vec3 tl, br, itemCenter, screenCenter, offset; obs_video_info ovi; @@ -6161,7 +6255,7 @@ static bool center_to_scene(obs_scene_t *, obs_sceneitem_t *item, void *param) if (obs_sceneitem_is_group(item)) obs_sceneitem_group_enum_items(item, center_to_scene, - ¢erType); + ¢erType); if (!obs_sceneitem_selected(item)) return true; @@ -6170,13 +6264,13 @@ static bool center_to_scene(obs_scene_t *, obs_sceneitem_t *item, void *param) if (centerType == CenterType::Scene) vec3_set(&screenCenter, float(ovi.base_width), - float(ovi.base_height), 0.0f); + float(ovi.base_height), 0.0f); else if (centerType == CenterType::Vertical) vec3_set(&screenCenter, float(oti.bounds.x), - float(ovi.base_height), 0.0f); + float(ovi.base_height), 0.0f); else if (centerType == CenterType::Horizontal) vec3_set(&screenCenter, float(ovi.base_width), - float(oti.bounds.y), 0.0f); + float(oti.bounds.y), 0.0f); vec3_mulf(&screenCenter, &screenCenter, 0.5f); @@ -6220,7 +6314,7 @@ void OBSBasic::EnablePreviewDisplay(bool enable) { obs_display_set_enabled(ui->preview->GetDisplay(), enable); ui->preview->setVisible(enable); - ui->previewDisabledLabel->setVisible(!enable); + ui->previewDisabledWidget->setVisible(!enable); } void OBSBasic::TogglePreview() @@ -6247,12 +6341,12 @@ void OBSBasic::DisablePreview() EnablePreviewDisplay(false); } -static bool nudge_callback(obs_scene_t*, obs_sceneitem_t *item, void *param) +static bool nudge_callback(obs_scene_t *, obs_sceneitem_t *item, void *param) { if (obs_sceneitem_locked(item)) return true; - struct vec2 &offset = *reinterpret_cast(param); + struct vec2 &offset = *reinterpret_cast(param); struct vec2 pos; if (!obs_sceneitem_selected(item)) { @@ -6269,7 +6363,7 @@ static bool nudge_callback(obs_scene_t*, obs_sceneitem_t *item, void *param) struct vec2 new_offset; vec2_set(&new_offset, offset3.x, offset3.y); obs_sceneitem_group_enum_items(item, nudge_callback, - &new_offset); + &new_offset); } return true; @@ -6290,29 +6384,49 @@ void OBSBasic::Nudge(int dist, MoveDir dir) vec2_set(&offset, 0.0f, 0.0f); switch (dir) { - case MoveDir::Up: offset.y = (float)-dist; break; - case MoveDir::Down: offset.y = (float) dist; break; - case MoveDir::Left: offset.x = (float)-dist; break; - case MoveDir::Right: offset.x = (float) dist; break; + case MoveDir::Up: + offset.y = (float)-dist; + break; + case MoveDir::Down: + offset.y = (float)dist; + break; + case MoveDir::Left: + offset.x = (float)-dist; + break; + case MoveDir::Right: + offset.x = (float)dist; + break; } obs_scene_enum_items(GetCurrentScene(), nudge_callback, &offset); } -void OBSBasic::NudgeUp() {Nudge(1, MoveDir::Up);} -void OBSBasic::NudgeDown() {Nudge(1, MoveDir::Down);} -void OBSBasic::NudgeLeft() {Nudge(1, MoveDir::Left);} -void OBSBasic::NudgeRight() {Nudge(1, MoveDir::Right);} +void OBSBasic::NudgeUp() +{ + Nudge(1, MoveDir::Up); +} +void OBSBasic::NudgeDown() +{ + Nudge(1, MoveDir::Down); +} +void OBSBasic::NudgeLeft() +{ + Nudge(1, MoveDir::Left); +} +void OBSBasic::NudgeRight() +{ + Nudge(1, MoveDir::Right); +} OBSProjector *OBSBasic::OpenProjector(obs_source_t *source, int monitor, - QString title, ProjectorType type) + QString title, ProjectorType type) { /* seriously? 10 monitors? */ if (monitor > 9 || monitor > QGuiApplication::screens().size() - 1) return nullptr; - OBSProjector *projector = new OBSProjector(nullptr, source, monitor, - title, type); + OBSProjector *projector = + new OBSProjector(nullptr, source, monitor, title, type); if (monitor < 0) { for (auto &projPtr : windowProjectors) { @@ -6354,7 +6468,7 @@ void OBSBasic::OpenSourceProjector() return; OpenProjector(obs_sceneitem_get_source(item), monitor, nullptr, - ProjectorType::Source); + ProjectorType::Source); } void OBSBasic::OpenMultiviewProjector() @@ -6371,19 +6485,19 @@ void OBSBasic::OpenSceneProjector() return; OpenProjector(obs_scene_get_source(scene), monitor, nullptr, - ProjectorType::Scene); + ProjectorType::Scene); } void OBSBasic::OpenStudioProgramWindow() { OpenProjector(nullptr, -1, QTStr("StudioProgramWindow"), - ProjectorType::StudioProgram); + ProjectorType::StudioProgram); } void OBSBasic::OpenPreviewWindow() { OpenProjector(nullptr, -1, QTStr("PreviewWindow"), - ProjectorType::Preview); + ProjectorType::Preview); } void OBSBasic::OpenSourceWindow() @@ -6396,13 +6510,13 @@ void OBSBasic::OpenSourceWindow() QString title = QString::fromUtf8(obs_source_get_name(source)); OpenProjector(obs_sceneitem_get_source(item), -1, title, - ProjectorType::Source); + ProjectorType::Source); } void OBSBasic::OpenMultiviewWindow() { OpenProjector(nullptr, -1, QTStr("MultiviewWindowed"), - ProjectorType::Multiview); + ProjectorType::Multiview); } void OBSBasic::OpenSceneWindow() @@ -6415,7 +6529,7 @@ void OBSBasic::OpenSceneWindow() QString title = QString::fromUtf8(obs_source_get_name(source)); OpenProjector(obs_scene_get_source(scene), -1, title, - ProjectorType::Scene); + ProjectorType::Scene); } void OBSBasic::OpenSavedProjectors() @@ -6425,52 +6539,52 @@ void OBSBasic::OpenSavedProjectors() switch (info->type) { case ProjectorType::Source: case ProjectorType::Scene: { - OBSSource source = obs_get_source_by_name( - info->name.c_str()); + OBSSource source = + obs_get_source_by_name(info->name.c_str()); if (!source) continue; QString title = nullptr; if (info->monitor < 0) title = QString::fromUtf8( - obs_source_get_name(source)); + obs_source_get_name(source)); projector = OpenProjector(source, info->monitor, title, - info->type); + info->type); obs_source_release(source); break; } case ProjectorType::Preview: { projector = OpenProjector(nullptr, info->monitor, - QTStr("PreviewWindow"), - ProjectorType::Preview); + QTStr("PreviewWindow"), + ProjectorType::Preview); break; } case ProjectorType::StudioProgram: { projector = OpenProjector(nullptr, info->monitor, - QTStr("StudioProgramWindow"), - ProjectorType::StudioProgram); + QTStr("StudioProgramWindow"), + ProjectorType::StudioProgram); break; } case ProjectorType::Multiview: { projector = OpenProjector(nullptr, info->monitor, - QTStr("MultiviewWindowed"), - ProjectorType::Multiview); + QTStr("MultiviewWindowed"), + ProjectorType::Multiview); break; } } if (projector && !info->geometry.empty() && info->monitor < 0) { QByteArray byteArray = QByteArray::fromBase64( - QByteArray(info->geometry.c_str())); + QByteArray(info->geometry.c_str())); projector->restoreGeometry(byteArray); if (!WindowPositionValid(projector->normalGeometry())) { QRect rect = App()->desktop()->geometry(); projector->setGeometry(QStyle::alignedRect( - Qt::LeftToRight, - Qt::AlignCenter, size(), rect)); + Qt::LeftToRight, Qt::AlignCenter, + size(), rect)); } } } @@ -6490,10 +6604,10 @@ void OBSBasic::UpdateTitleBar() { stringstream name; - const char *profile = config_get_string(App()->GlobalConfig(), - "Basic", "Profile"); - const char *sceneCollection = config_get_string(App()->GlobalConfig(), - "Basic", "SceneCollection"); + const char *profile = + config_get_string(App()->GlobalConfig(), "Basic", "Profile"); + const char *sceneCollection = config_get_string( + App()->GlobalConfig(), "Basic", "SceneCollection"); name << "OBS "; if (previewProgramMode) @@ -6512,8 +6626,8 @@ void OBSBasic::UpdateTitleBar() int OBSBasic::GetProfilePath(char *path, size_t size, const char *file) const { char profiles_path[512]; - const char *profile = config_get_string(App()->GlobalConfig(), - "Basic", "ProfileDir"); + const char *profile = + config_get_string(App()->GlobalConfig(), "Basic", "ProfileDir"); int ret; if (!profile) @@ -6536,7 +6650,7 @@ int OBSBasic::GetProfilePath(char *path, size_t size, const char *file) const void OBSBasic::on_resetUI_triggered() { /* prune deleted extra docks */ - for (int i = extraDocks.size() - 1; i >= 0 ; i--) { + for (int i = extraDocks.size() - 1; i >= 0; i--) { if (!extraDocks[i]) { extraDocks.removeAt(i); } @@ -6544,23 +6658,21 @@ void OBSBasic::on_resetUI_triggered() if (extraDocks.size()) { QMessageBox::StandardButton button = QMessageBox::question( - this, - QTStr("ResetUIWarning.Title"), - QTStr("ResetUIWarning.Text")); + this, QTStr("ResetUIWarning.Title"), + QTStr("ResetUIWarning.Text")); if (button == QMessageBox::No) return; } /* undock/hide/center extra docks */ - for (int i = extraDocks.size() - 1; i >= 0 ; i--) { + for (int i = extraDocks.size() - 1; i >= 0; i--) { if (extraDocks[i]) { extraDocks[i]->setVisible(true); extraDocks[i]->setFloating(true); - extraDocks[i]->move( - frameGeometry().topLeft() + - rect().center() - - extraDocks[i]->rect().center()); + extraDocks[i]->move(frameGeometry().topLeft() + + rect().center() - + extraDocks[i]->rect().center()); extraDocks[i]->setVisible(false); } } @@ -6578,21 +6690,11 @@ void OBSBasic::on_resetUI_triggered() int mixerSize = cx - (cx22_5 * 2 + cx5 * 2); - QList docks { - ui->scenesDock, - ui->sourcesDock, - ui->mixerDock, - ui->transitionsDock, - ui->controlsDock - }; + QList docks{ui->scenesDock, ui->sourcesDock, + ui->mixerDock, ui->transitionsDock, + ui->controlsDock}; - QList sizes { - cx22_5, - cx22_5, - mixerSize, - cx5, - cx5 - }; + QList sizes{cx22_5, cx22_5, mixerSize, cx5, cx5}; ui->scenesDock->setVisible(true); ui->sourcesDock->setVisible(true); @@ -6609,9 +6711,9 @@ void OBSBasic::on_resetUI_triggered() void OBSBasic::on_lockUI_toggled(bool lock) { - QDockWidget::DockWidgetFeatures features = lock - ? QDockWidget::NoDockWidgetFeatures - : QDockWidget::AllDockWidgetFeatures; + QDockWidget::DockWidgetFeatures features = + lock ? QDockWidget::NoDockWidgetFeatures + : QDockWidget::AllDockWidgetFeatures; QDockWidget::DockWidgetFeatures mainFeatures = features; mainFeatures &= ~QDockWidget::QDockWidget::DockWidgetClosable; @@ -6623,7 +6725,7 @@ void OBSBasic::on_lockUI_toggled(bool lock) ui->controlsDock->setFeatures(mainFeatures); statsDock->setFeatures(features); - for (int i = extraDocks.size() - 1; i >= 0 ; i--) { + for (int i = extraDocks.size() - 1; i >= 0; i--) { if (!extraDocks[i]) { extraDocks.removeAt(i); } else { @@ -6645,8 +6747,8 @@ void OBSBasic::on_toggleStatusBar_toggled(bool visible) { ui->statusbar->setVisible(visible); - config_set_bool(App()->GlobalConfig(), "BasicWindow", - "ShowStatusBar", visible); + config_set_bool(App()->GlobalConfig(), "BasicWindow", "ShowStatusBar", + visible); } void OBSBasic::on_actionLockPreview_triggered() @@ -6672,7 +6774,7 @@ void OBSBasic::on_scalingMenu_aboutToShow() QString::number(ovi.output_height)); action->setText(text); action->setVisible(!(ovi.output_width == ovi.base_width && - ovi.output_height == ovi.base_height)); + ovi.output_height == ovi.base_height)); UpdatePreviewScalingMenu(); } @@ -6699,8 +6801,8 @@ void OBSBasic::on_actionScaleOutput_triggered() ui->preview->SetFixedScaling(true); float scalingAmount = float(ovi.output_width) / float(ovi.base_width); // log base ZOOM_SENSITIVITY of x = log(x) / log(ZOOM_SENSITIVITY) - int32_t approxScalingLevel = int32_t( - round(log(scalingAmount) / log(ZOOM_SENSITIVITY))); + int32_t approxScalingLevel = + int32_t(round(log(scalingAmount) / log(ZOOM_SENSITIVITY))); ui->preview->SetScalingLevel(approxScalingLevel); ui->preview->SetScalingAmount(scalingAmount); emit ui->preview->DisplayResized(); @@ -6709,9 +6811,9 @@ void OBSBasic::on_actionScaleOutput_triggered() void OBSBasic::SetShowing(bool showing) { if (!showing && isVisible()) { - config_set_string(App()->GlobalConfig(), - "BasicWindow", "geometry", - saveGeometry().toBase64().constData()); + config_set_string(App()->GlobalConfig(), "BasicWindow", + "geometry", + saveGeometry().toBase64().constData()); /* hide all visible child dialogs */ visDlgPositions.clear(); @@ -6766,7 +6868,7 @@ void OBSBasic::SetShowing(bool showing) * bar. */ if (sysTrayMinimizeToTray()) { Qt::WindowStates state; - state = windowState() & ~Qt::WindowMinimized; + state = windowState() & ~Qt::WindowMinimized; state |= Qt::WindowActive; setWindowState(state); } @@ -6787,28 +6889,27 @@ void OBSBasic::ToggleShowHide() void OBSBasic::SystemTrayInit() { - trayIcon.reset(new QSystemTrayIcon(QIcon::fromTheme("obs-tray", - QIcon(":/res/images/obs.png")), this)); + trayIcon.reset(new QSystemTrayIcon( + QIcon::fromTheme("obs-tray", QIcon(":/res/images/obs.png")), + this)); trayIcon->setToolTip("OBS Studio"); - showHide = new QAction(QTStr("Basic.SystemTray.Show"), - trayIcon.data()); + showHide = new QAction(QTStr("Basic.SystemTray.Show"), trayIcon.data()); sysTrayStream = new QAction(QTStr("Basic.Main.StartStreaming"), - trayIcon.data()); + trayIcon.data()); sysTrayRecord = new QAction(QTStr("Basic.Main.StartRecording"), - trayIcon.data()); + trayIcon.data()); sysTrayReplayBuffer = new QAction(QTStr("Basic.Main.StartReplayBuffer"), - trayIcon.data()); - exit = new QAction(QTStr("Exit"), - trayIcon.data()); + trayIcon.data()); + exit = new QAction(QTStr("Exit"), trayIcon.data()); trayMenu = new QMenu; previewProjector = new QMenu(QTStr("PreviewProjector")); studioProgramProjector = new QMenu(QTStr("StudioProgramProjector")); AddProjectorMenuMonitors(previewProjector, this, - SLOT(OpenPreviewProjector())); + SLOT(OpenPreviewProjector())); AddProjectorMenuMonitors(studioProgramProjector, this, - SLOT(OpenStudioProgramProjector())); + SLOT(OpenStudioProgramProjector())); trayMenu->addAction(showHide); trayMenu->addMenu(previewProjector); trayMenu->addMenu(studioProgramProjector); @@ -6823,19 +6924,16 @@ void OBSBasic::SystemTrayInit() sysTrayReplayBuffer->setEnabled(false); connect(trayIcon.data(), - SIGNAL(activated(QSystemTrayIcon::ActivationReason)), - this, - SLOT(IconActivated(QSystemTrayIcon::ActivationReason))); - connect(showHide, SIGNAL(triggered()), - this, SLOT(ToggleShowHide())); - connect(sysTrayStream, SIGNAL(triggered()), - this, SLOT(on_streamButton_clicked())); - connect(sysTrayRecord, SIGNAL(triggered()), - this, SLOT(on_recordButton_clicked())); - connect(sysTrayReplayBuffer.data(), &QAction::triggered, - this, &OBSBasic::ReplayBufferClicked); - connect(exit, SIGNAL(triggered()), - this, SLOT(close())); + SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, + SLOT(IconActivated(QSystemTrayIcon::ActivationReason))); + connect(showHide, SIGNAL(triggered()), this, SLOT(ToggleShowHide())); + connect(sysTrayStream, SIGNAL(triggered()), this, + SLOT(on_streamButton_clicked())); + connect(sysTrayRecord, SIGNAL(triggered()), this, + SLOT(on_recordButton_clicked())); + connect(sysTrayReplayBuffer.data(), &QAction::triggered, this, + &OBSBasic::ReplayBufferClicked); + connect(exit, SIGNAL(triggered()), this, SLOT(close())); } void OBSBasic::IconActivated(QSystemTrayIcon::ActivationReason reason) @@ -6844,20 +6942,20 @@ void OBSBasic::IconActivated(QSystemTrayIcon::ActivationReason reason) previewProjector->clear(); studioProgramProjector->clear(); AddProjectorMenuMonitors(previewProjector, this, - SLOT(OpenPreviewProjector())); + SLOT(OpenPreviewProjector())); AddProjectorMenuMonitors(studioProgramProjector, this, - SLOT(OpenStudioProgramProjector())); + SLOT(OpenStudioProgramProjector())); if (reason == QSystemTrayIcon::Trigger) ToggleShowHide(); } void OBSBasic::SysTrayNotify(const QString &text, - QSystemTrayIcon::MessageIcon n) + QSystemTrayIcon::MessageIcon n) { if (trayIcon && QSystemTrayIcon::supportsMessages()) { QSystemTrayIcon::MessageIcon icon = - QSystemTrayIcon::MessageIcon(n); + QSystemTrayIcon::MessageIcon(n); trayIcon->showMessage("OBS Studio", text, icon, 10000); } } @@ -6869,18 +6967,18 @@ void OBSBasic::SystemTray(bool firstStarted) if (!trayIcon && !firstStarted) return; - bool sysTrayWhenStarted = config_get_bool(GetGlobalConfig(), - "BasicWindow", "SysTrayWhenStarted"); - bool sysTrayEnabled = config_get_bool(GetGlobalConfig(), - "BasicWindow", "SysTrayEnabled"); + bool sysTrayWhenStarted = config_get_bool( + GetGlobalConfig(), "BasicWindow", "SysTrayWhenStarted"); + bool sysTrayEnabled = config_get_bool(GetGlobalConfig(), "BasicWindow", + "SysTrayEnabled"); if (firstStarted) SystemTrayInit(); if (!sysTrayWhenStarted && !sysTrayEnabled) { trayIcon->hide(); - } else if ((sysTrayWhenStarted && sysTrayEnabled) - || opt_minimize_tray) { + } else if ((sysTrayWhenStarted && sysTrayEnabled) || + opt_minimize_tray) { trayIcon->show(); if (firstStarted) { QTimer::singleShot(50, this, SLOT(hide())); @@ -6907,8 +7005,8 @@ void OBSBasic::SystemTray(bool firstStarted) bool OBSBasic::sysTrayMinimizeToTray() { - return config_get_bool(GetGlobalConfig(), - "BasicWindow", "SysTrayMinimizeToTray"); + return config_get_bool(GetGlobalConfig(), "BasicWindow", + "SysTrayMinimizeToTray"); } void OBSBasic::on_actionCopySource_triggered() @@ -6952,8 +7050,8 @@ void OBSBasic::on_actionPasteDup_triggered() void OBSBasic::AudioMixerCopyFilters() { - QAction *action = reinterpret_cast(sender()); - VolControl *vol = action->property("volControl").value(); + QAction *action = reinterpret_cast(sender()); + VolControl *vol = action->property("volControl").value(); obs_source_t *source = vol->GetSource(); copyFiltersString = obs_source_get_name(source); @@ -6961,8 +7059,8 @@ void OBSBasic::AudioMixerCopyFilters() void OBSBasic::AudioMixerPasteFilters() { - QAction *action = reinterpret_cast(sender()); - VolControl *vol = action->property("volControl").value(); + QAction *action = reinterpret_cast(sender()); + VolControl *vol = action->property("volControl").value(); obs_source_t *dstSource = vol->GetSource(); OBSSource source = obs_get_source_by_name(copyFiltersString); @@ -7021,24 +7119,22 @@ void OBSBasic::on_actionPasteFilters_triggered() } static void ConfirmColor(SourceTree *sources, const QColor &color, - QModelIndexList selectedItems) + QModelIndexList selectedItems) { for (int x = 0; x < selectedItems.count(); x++) { - SourceTreeItem *treeItem = sources - ->GetItemWidget(selectedItems[x].row()); - treeItem->setStyleSheet("background: " - + color.name(QColor::HexArgb)); + SourceTreeItem *treeItem = + sources->GetItemWidget(selectedItems[x].row()); + treeItem->setStyleSheet("background: " + + color.name(QColor::HexArgb)); treeItem->style()->unpolish(treeItem); treeItem->style()->polish(treeItem); - OBSSceneItem sceneItem = sources->Get( - selectedItems[x].row()); + OBSSceneItem sceneItem = sources->Get(selectedItems[x].row()); obs_data_t *privData = obs_sceneitem_get_private_settings(sceneItem); obs_data_set_int(privData, "color-preset", 1); obs_data_set_string(privData, "color", - QT_TO_UTF8(color.name( - QColor::HexArgb))); + QT_TO_UTF8(color.name(QColor::HexArgb))); obs_data_release(privData); } } @@ -7047,8 +7143,8 @@ void OBSBasic::ColorChange() { QModelIndexList selectedItems = ui->sources->selectionModel()->selectedIndexes(); - QAction *action = qobject_cast(sender()); - QPushButton *colorButton = qobject_cast(sender()); + QAction *action = qobject_cast(sender()); + QPushButton *colorButton = qobject_cast(sender()); if (selectedItems.count() == 0) return; @@ -7057,15 +7153,15 @@ void OBSBasic::ColorChange() int preset = colorButton->property("bgColor").value(); for (int x = 0; x < selectedItems.count(); x++) { - SourceTreeItem *treeItem = ui->sources - ->GetItemWidget(selectedItems[x].row()); + SourceTreeItem *treeItem = ui->sources->GetItemWidget( + selectedItems[x].row()); treeItem->setStyleSheet(""); treeItem->setProperty("bgColor", preset); treeItem->style()->unpolish(treeItem); treeItem->style()->polish(treeItem); - OBSSceneItem sceneItem = ui->sources->Get( - selectedItems[x].row()); + OBSSceneItem sceneItem = + ui->sources->Get(selectedItems[x].row()); obs_data_t *privData = obs_sceneitem_get_private_settings(sceneItem); obs_data_set_int(privData, "color-preset", preset + 1); @@ -7076,8 +7172,10 @@ void OBSBasic::ColorChange() for (int i = 1; i < 9; i++) { stringstream button; button << "preset" << i; - QPushButton *cButton = colorButton->parentWidget() - ->findChild(button.str().c_str()); + QPushButton *cButton = + colorButton->parentWidget() + ->findChild( + button.str().c_str()); cButton->setStyleSheet("border: 1px solid black"); } @@ -7090,24 +7188,25 @@ void OBSBasic::ColorChange() SourceTreeItem *curTreeItem = GetItemWidgetFromSceneItem(curSceneItem); obs_data_t *curPrivData = - obs_sceneitem_get_private_settings(curSceneItem); + obs_sceneitem_get_private_settings( + curSceneItem); - int oldPreset = obs_data_get_int( - curPrivData, "color-preset"); + int oldPreset = + obs_data_get_int(curPrivData, "color-preset"); const QString oldSheet = curTreeItem->styleSheet(); auto liveChangeColor = [=](const QColor &color) { if (color.isValid()) { curTreeItem->setStyleSheet( - "background: " - + color.name(QColor::HexArgb)); + "background: " + + color.name(QColor::HexArgb)); } }; auto changedColor = [=](const QColor &color) { if (color.isValid()) { ConfirmColor(ui->sources, color, - selectedItems); + selectedItems); } }; @@ -7122,7 +7221,7 @@ void OBSBasic::ColorChange() } else { curTreeItem->setStyleSheet(""); curTreeItem->setProperty("bgColor", - oldPreset - 1); + oldPreset - 1); } curTreeItem->style()->unpolish(curTreeItem); @@ -7132,31 +7231,30 @@ void OBSBasic::ColorChange() QColorDialog::ColorDialogOptions options = QColorDialog::ShowAlphaChannel; - const char *oldColor = obs_data_get_string(curPrivData, - "color"); + const char *oldColor = + obs_data_get_string(curPrivData, "color"); const char *customColor = *oldColor != 0 ? oldColor - : "#55FF0000"; + : "#55FF0000"; #ifdef __APPLE__ options |= QColorDialog::DontUseNativeDialog; #endif QColorDialog *colorDialog = new QColorDialog(this); colorDialog->setOptions(options); - colorDialog->setCurrentColor( - QColor(customColor)); + colorDialog->setCurrentColor(QColor(customColor)); connect(colorDialog, &QColorDialog::currentColorChanged, - liveChangeColor); + liveChangeColor); connect(colorDialog, &QColorDialog::colorSelected, - changedColor); - connect(colorDialog, &QColorDialog::rejected, - rejected); + changedColor); + connect(colorDialog, &QColorDialog::rejected, rejected); colorDialog->open(); obs_data_release(curPrivData); } else { for (int x = 0; x < selectedItems.count(); x++) { - SourceTreeItem *treeItem = ui->sources - ->GetItemWidget(selectedItems[x].row()); + SourceTreeItem *treeItem = + ui->sources->GetItemWidget( + selectedItems[x].row()); treeItem->setStyleSheet("background: none"); treeItem->setProperty("bgColor", preset); treeItem->style()->unpolish(treeItem); @@ -7168,7 +7266,7 @@ void OBSBasic::ColorChange() obs_sceneitem_get_private_settings( sceneItem); obs_data_set_int(privData, "color-preset", - preset); + preset); obs_data_set_string(privData, "color", ""); obs_data_release(privData); } @@ -7176,8 +7274,7 @@ void OBSBasic::ColorChange() } } -SourceTreeItem *OBSBasic::GetItemWidgetFromSceneItem( - obs_sceneitem_t *sceneItem) +SourceTreeItem *OBSBasic::GetItemWidgetFromSceneItem(obs_sceneitem_t *sceneItem) { int i = 0; SourceTreeItem *treeItem = ui->sources->GetItemWidget(i); @@ -7188,7 +7285,7 @@ SourceTreeItem *OBSBasic::GetItemWidgetFromSceneItem( treeItem = ui->sources->GetItemWidget(i); item = ui->sources->Get(i); } - if(treeItem) + if (treeItem) return treeItem; return nullptr; @@ -7229,15 +7326,14 @@ void OBSBasic::on_actionShowAbout_triggered() void OBSBasic::ResizeOutputSizeOfSource() { - if (ui->streamButton->isChecked() || ui->recordButton->isChecked() || - (replayBufferButton && replayBufferButton->isChecked())) + if (obs_video_active()) return; QMessageBox resize_output(this); - resize_output.setText(QTStr("ResizeOutputSizeOfSource.Text") + - "\n\n" + QTStr("ResizeOutputSizeOfSource.Continue")); - QAbstractButton *Yes = resize_output.addButton(QTStr("Yes"), - QMessageBox::YesRole); + resize_output.setText(QTStr("ResizeOutputSizeOfSource.Text") + "\n\n" + + QTStr("ResizeOutputSizeOfSource.Continue")); + QAbstractButton *Yes = + resize_output.addButton(QTStr("Yes"), QMessageBox::YesRole); resize_output.addButton(QTStr("No"), QMessageBox::NoRole); resize_output.setIcon(QMessageBox::Warning); resize_output.setWindowTitle(QTStr("ResizeOutputSizeOfSource")); @@ -7268,14 +7364,14 @@ QAction *OBSBasic::AddDockWidget(QDockWidget *dock) extraDocks.push_back(dock); bool lock = ui->lockUI->isChecked(); - QDockWidget::DockWidgetFeatures features = lock - ? QDockWidget::NoDockWidgetFeatures - : QDockWidget::AllDockWidgetFeatures; + QDockWidget::DockWidgetFeatures features = + lock ? QDockWidget::NoDockWidgetFeatures + : QDockWidget::AllDockWidgetFeatures; dock->setFeatures(features); /* prune deleted docks */ - for (int i = extraDocks.size() - 1; i >= 0 ; i--) { + for (int i = extraDocks.size() - 1; i >= 0; i--) { if (!extraDocks[i]) { extraDocks.removeAt(i); } @@ -7286,7 +7382,7 @@ QAction *OBSBasic::AddDockWidget(QDockWidget *dock) OBSBasic *OBSBasic::Get() { - return reinterpret_cast(App()->GetMainWindow()); + return reinterpret_cast(App()->GetMainWindow()); } bool OBSBasic::StreamingActive() @@ -7316,10 +7412,10 @@ SceneRenameDelegate::SceneRenameDelegate(QObject *parent) } void SceneRenameDelegate::setEditorData(QWidget *editor, - const QModelIndex &index) const + const QModelIndex &index) const { QStyledItemDelegate::setEditorData(editor, index); - QLineEdit *lineEdit = qobject_cast(editor); + QLineEdit *lineEdit = qobject_cast(editor); if (lineEdit) lineEdit->selectAll(); } @@ -7329,7 +7425,7 @@ bool SceneRenameDelegate::eventFilter(QObject *editor, QEvent *event) if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast(event); if (keyEvent->key() == Qt::Key_Escape) { - QLineEdit *lineEdit = qobject_cast(editor); + QLineEdit *lineEdit = qobject_cast(editor); if (lineEdit) lineEdit->undo(); } @@ -7345,3 +7441,144 @@ void OBSBasic::UpdatePatronJson(const QString &text, const QString &error) patronJson = QT_TO_UTF8(text); } + +void OBSBasic::PauseRecording() +{ + if (!pause || !outputHandler || !outputHandler->fileOutput) + return; + + obs_output_t *output = outputHandler->fileOutput; + + if (obs_output_pause(output, true)) { + pause->setAccessibleName(QTStr("Basic.Main.UnpauseRecording")); + pause->setToolTip(QTStr("Basic.Main.UnpauseRecording")); + pause->blockSignals(true); + pause->setChecked(true); + pause->blockSignals(false); + os_atomic_set_bool(&recording_paused, true); + + if (api) + api->on_event(OBS_FRONTEND_EVENT_RECORDING_PAUSED); + + if (os_atomic_load_bool(&replaybuf_active)) + ShowReplayBufferPauseWarning(); + } +} + +void OBSBasic::UnpauseRecording() +{ + if (!pause || !outputHandler || !outputHandler->fileOutput) + return; + + obs_output_t *output = outputHandler->fileOutput; + + if (obs_output_pause(output, false)) { + pause->setAccessibleName(QTStr("Basic.Main.PauseRecording")); + pause->setToolTip(QTStr("Basic.Main.PauseRecording")); + pause->blockSignals(true); + pause->setChecked(false); + pause->blockSignals(false); + os_atomic_set_bool(&recording_paused, false); + + if (api) + api->on_event(OBS_FRONTEND_EVENT_RECORDING_UNPAUSED); + } +} + +void OBSBasic::PauseToggled() +{ + if (!pause || !outputHandler || !outputHandler->fileOutput) + return; + + obs_output_t *output = outputHandler->fileOutput; + bool enable = !obs_output_paused(output); + + if (enable) + PauseRecording(); + else + UnpauseRecording(); +} + +void OBSBasic::UpdatePause(bool activate) +{ + if (!activate || !outputHandler || !outputHandler->RecordingActive()) { + pause.reset(); + return; + } + + const char *mode = config_get_string(basicConfig, "Output", "Mode"); + bool adv = astrcmpi(mode, "Advanced") == 0; + bool shared; + + if (adv) { + const char *recType = + config_get_string(basicConfig, "AdvOut", "RecType"); + + if (astrcmpi(recType, "FFmpeg") == 0) { + shared = config_get_bool(basicConfig, "AdvOut", + "FFOutputToFile"); + } else { + const char *recordEncoder = config_get_string( + basicConfig, "AdvOut", "RecEncoder"); + shared = astrcmpi(recordEncoder, "none") == 0; + } + } else { + const char *quality = config_get_string( + basicConfig, "SimpleOutput", "RecQuality"); + shared = strcmp(quality, "Stream") == 0; + } + + if (!shared) { + pause.reset(new QPushButton()); + pause->setAccessibleName(QTStr("Basic.Main.PauseRecording")); + pause->setToolTip(QTStr("Basic.Main.PauseRecording")); + pause->setCheckable(true); + pause->setChecked(false); + pause->setProperty("themeID", + QVariant(QStringLiteral("pauseIconSmall"))); + connect(pause.data(), &QAbstractButton::clicked, this, + &OBSBasic::PauseToggled); + ui->recordingLayout->addWidget(pause.data()); + } else { + pause.reset(); + } +} + +#define MBYTE (1024ULL * 1024ULL) +#define MBYTES_LEFT_STOP_REC 50ULL +#define MAX_BYTES_LEFT (MBYTES_LEFT_STOP_REC * MBYTE) + +void OBSBasic::DiskSpaceMessage() +{ + blog(LOG_ERROR, "Recording stopped because of low disk space"); + + OBSMessageBox::critical(this, QTStr("Output.RecordNoSpace.Title"), + QTStr("Output.RecordNoSpace.Msg")); +} + +bool OBSBasic::LowDiskSpace() +{ + const char *mode = config_get_string(Config(), "Output", "Mode"); + const char *path = + strcmp(mode, "Advanced") + ? config_get_string(Config(), "SimpleOutput", + "FilePath") + : config_get_string(Config(), "AdvOut", "RecFilePath"); + + uint64_t num_bytes = os_get_free_disk_space(path); + + if (num_bytes < (MAX_BYTES_LEFT)) + return true; + else + return false; +} + +void OBSBasic::CheckDiskSpaceRemaining() +{ + if (LowDiskSpace()) { + StopRecording(); + StopReplayBuffer(); + + DiskSpaceMessage(); + } +} diff --git a/UI/window-basic-main.hpp b/UI/window-basic-main.hpp index 8641f53..a75eb47 100644 --- a/UI/window-basic-main.hpp +++ b/UI/window-basic-main.hpp @@ -53,16 +53,16 @@ class OBSBasicStats; #define DESKTOP_AUDIO_1 Str("DesktopAudioDevice1") #define DESKTOP_AUDIO_2 Str("DesktopAudioDevice2") -#define AUX_AUDIO_1 Str("AuxAudioDevice1") -#define AUX_AUDIO_2 Str("AuxAudioDevice2") -#define AUX_AUDIO_3 Str("AuxAudioDevice3") -#define AUX_AUDIO_4 Str("AuxAudioDevice4") +#define AUX_AUDIO_1 Str("AuxAudioDevice1") +#define AUX_AUDIO_2 Str("AuxAudioDevice2") +#define AUX_AUDIO_3 Str("AuxAudioDevice3") +#define AUX_AUDIO_4 Str("AuxAudioDevice4") -#define SIMPLE_ENCODER_X264 "x264" -#define SIMPLE_ENCODER_X264_LOWCPU "x264_lowcpu" -#define SIMPLE_ENCODER_QSV "qsv" -#define SIMPLE_ENCODER_NVENC "nvenc" -#define SIMPLE_ENCODER_AMD "amd" +#define SIMPLE_ENCODER_X264 "x264" +#define SIMPLE_ENCODER_X264_LOWCPU "x264_lowcpu" +#define SIMPLE_ENCODER_QSV "qsv" +#define SIMPLE_ENCODER_NVENC "nvenc" +#define SIMPLE_ENCODER_AMD "amd" #define PREVIEW_EDGE_SIZE 10 @@ -89,13 +89,14 @@ struct QuickTransition { inline QuickTransition() {} inline QuickTransition(OBSSource source_, int duration_, int id_) - : source (source_), - duration (duration_), - id (id_), - renamedSignal (std::make_shared( - obs_source_get_signal_handler(source), - "rename", SourceRenamed, this)) - {} + : source(source_), + duration(duration_), + id(id_), + renamedSignal(std::make_shared( + obs_source_get_signal_handler(source), "rename", + SourceRenamed, this)) + { + } private: static void SourceRenamed(void *param, calldata_t *data); @@ -122,21 +123,19 @@ class OBSBasic : public OBSMainWindow { friend class Auth; friend class AutoConfig; friend class AutoConfigStreamPage; + friend class RecordButton; + friend class ExtraBrowsersModel; + friend class ExtraBrowsersDelegate; friend struct OBSStudioAPI; - enum class MoveDir { - Up, - Down, - Left, - Right - }; + enum class MoveDir { Up, Down, Left, Right }; enum DropType { DropType_RawText, DropType_Text, DropType_Image, DropType_Media, - DropType_Html + DropType_Html, }; private: @@ -144,7 +143,7 @@ private: std::shared_ptr auth; - std::vector volumes; + std::vector volumes; std::vector signalHandlers; @@ -172,7 +171,9 @@ private: QPointer statsDock; QPointer about; - QPointer cpuUsageTimer; + QPointer cpuUsageTimer; + QPointer diskFullTimer; + os_cpu_usage_info_t *cpuUsageInfo = nullptr; OBSService service; @@ -188,48 +189,50 @@ private: gs_vertbuffer_t *boxBottom = nullptr; gs_vertbuffer_t *circle = nullptr; - bool sceneChanging = false; - bool ignoreSelectionUpdate = false; + bool sceneChanging = false; + bool ignoreSelectionUpdate = false; - int previewX = 0, previewY = 0; - int previewCX = 0, previewCY = 0; - float previewScale = 0.0f; + int previewX = 0, previewY = 0; + int previewCX = 0, previewCY = 0; + float previewScale = 0.0f; - ConfigFile basicConfig; + ConfigFile basicConfig; - std::vector savedProjectorsArray; + std::vector savedProjectorsArray; QPointer projectors[10]; QList> windowProjectors; QPointer stats; QPointer remux; + QPointer extraBrowsers; QPointer startStreamMenu; QPointer transitionButton; QPointer replayBufferButton; + QScopedPointer pause; QScopedPointer trayIcon; - QPointer sysTrayStream; - QPointer sysTrayRecord; - QPointer sysTrayReplayBuffer; - QPointer showHide; - QPointer exit; - QPointer trayMenu; - QPointer previewProjector; - QPointer studioProgramProjector; - QPointer multiviewProjectorMenu; - QPointer previewProjectorSource; - QPointer previewProjectorMain; - QPointer sceneProjectorMenu; - QPointer sourceProjector; - QPointer scaleFilteringMenu; - QPointer colorMenu; - QPointer colorWidgetAction; - QPointer colorSelect; - QPointer deinterlaceMenu; - QPointer perSceneTransitionMenu; - QPointer shortcutFilter; + QPointer sysTrayStream; + QPointer sysTrayRecord; + QPointer sysTrayReplayBuffer; + QPointer showHide; + QPointer exit; + QPointer trayMenu; + QPointer previewProjector; + QPointer studioProgramProjector; + QPointer multiviewProjectorMenu; + QPointer previewProjectorSource; + QPointer previewProjectorMain; + QPointer sceneProjectorMenu; + QPointer sourceProjector; + QPointer scaleFilteringMenu; + QPointer colorMenu; + QPointer colorWidgetAction; + QPointer colorSelect; + QPointer deinterlaceMenu; + QPointer perSceneTransitionMenu; + QPointer shortcutFilter; QPointer programWidget; QPointer programLayout; @@ -238,47 +241,47 @@ private: QScopedPointer patronJsonThread; std::string patronJson; - void UpdateMultiviewProjectorMenu(); + void UpdateMultiviewProjectorMenu(); - void DrawBackdrop(float cx, float cy); + void DrawBackdrop(float cx, float cy); - void SetupEncoders(); + void SetupEncoders(); - void CreateFirstRunSources(); - void CreateDefaultScene(bool firstStart); + void CreateFirstRunSources(); + void CreateDefaultScene(bool firstStart); - void UpdateVolumeControlsDecayRate(); - void UpdateVolumeControlsPeakMeterType(); - void ClearVolumeControls(); + void UpdateVolumeControlsDecayRate(); + void UpdateVolumeControlsPeakMeterType(); + void ClearVolumeControls(); - void UploadLog(const char *subdir, const char *file); + void UploadLog(const char *subdir, const char *file); - void Save(const char *file); - void Load(const char *file); + void Save(const char *file); + void Load(const char *file); - void InitHotkeys(); - void CreateHotkeys(); - void ClearHotkeys(); + void InitHotkeys(); + void CreateHotkeys(); + void ClearHotkeys(); - bool InitService(); + bool InitService(); - bool InitBasicConfigDefaults(); - void InitBasicConfigDefaults2(); - bool InitBasicConfig(); + bool InitBasicConfigDefaults(); + void InitBasicConfigDefaults2(); + bool InitBasicConfig(); - void InitOBSCallbacks(); + void InitOBSCallbacks(); - void InitPrimitives(); + void InitPrimitives(); - void OnFirstLoad(); + void OnFirstLoad(); - OBSSceneItem GetSceneItem(QListWidgetItem *item); - OBSSceneItem GetCurrentSceneItem(); + OBSSceneItem GetSceneItem(QListWidgetItem *item); + OBSSceneItem GetCurrentSceneItem(); - bool QueryRemoveSource(obs_source_t *source); + bool QueryRemoveSource(obs_source_t *source); - void TimedCheckForUpdates(); - void CheckForUpdates(bool manualUpdate); + void TimedCheckForUpdates(); + void CheckForUpdates(bool manualUpdate); void GetFPSCommon(uint32_t &num, uint32_t &den) const; void GetFPSInteger(uint32_t &num, uint32_t &den) const; @@ -293,8 +296,8 @@ private: void ChangeSceneIndex(bool relative, int idx, int invalidIdx); void TempFileOutput(const char *path, int vBitrate, int aBitrate); - void TempStreamOutput(const char *url, const char *key, - int vBitrate, int aBitrate); + void TempStreamOutput(const char *url, const char *key, int vBitrate, + int aBitrate); void CloseDialogs(); void ClearSceneData(); @@ -302,7 +305,7 @@ private: void Nudge(int dist, MoveDir dir); OBSProjector *OpenProjector(obs_source_t *source, int monitor, - QString title, ProjectorType type); + QString title, ProjectorType type); void GetAudioSourceFilters(); void GetAudioSourceProperties(); @@ -327,8 +330,8 @@ private: int GetTopSelectedSourceItem(); - obs_hotkey_pair_id streamingHotkeys, recordingHotkeys, - replayBufHotkeys, togglePreviewHotkeys; + obs_hotkey_pair_id streamingHotkeys, recordingHotkeys, pauseHotkeys, + replayBufHotkeys, togglePreviewHotkeys; obs_hotkey_id forceStreamingStopHotkey; void InitDefaultTransitions(); @@ -368,7 +371,7 @@ private: void SetPreviewProgramMode(bool enabled); void ResizeProgram(uint32_t cx, uint32_t cy); void SetCurrentScene(obs_scene_t *scene, bool force = false, - bool direct = false); + bool direct = false); static void RenderProgram(void *data, uint32_t cx, uint32_t cy); std::vector quickTransitions; @@ -386,8 +389,8 @@ private: int quickTransitionIdCounter = 1; bool overridingTransition = false; - int programX = 0, programY = 0; - int programCX = 0, programCY = 0; + int programX = 0, programY = 0; + int programCX = 0, programCY = 0; float programScale = 0.0f; int disableOutputsRef = 0; @@ -407,9 +410,9 @@ private: void EnumDialogs(); - QList visDialogs; - QList modalDialogs; - QList visMsgBoxes; + QList visDialogs; + QList modalDialogs; + QList visMsgBoxes; QList visDlgPositions; @@ -422,6 +425,19 @@ private: bool NoSourcesConfirmation(); +#ifdef BROWSER_AVAILABLE + QList> extraBrowserDocks; + QList> extraBrowserDockActions; + QStringList extraBrowserDockTargets; + + void ClearExtraBrowserDocks(); + void LoadExtraBrowserDocks(); + void SaveExtraBrowserDocks(); + void ManageExtraBrowserDocks(); + void AddExtraBrowserDock(const QString &title, const QString &url, + bool firstCreate); +#endif + public slots: void DeferSaveBegin(); void DeferSaveEnd(); @@ -444,6 +460,7 @@ public slots: void RecordStopping(); void RecordingStop(int code, QString last_error); + void ShowReplayBufferPauseWarning(); void StartReplayBuffer(); void StopReplayBuffer(); @@ -457,18 +474,21 @@ public slots: void SetTransition(OBSSource transition); void TransitionToScene(OBSScene scene, bool force = false, - bool direct = false); + bool direct = false); void TransitionToScene(OBSSource scene, bool force = false, - bool direct = false, bool quickTransition = false); + bool direct = false, + bool quickTransition = false); void SetCurrentScene(OBSSource scene, bool force = false, - bool direct = false); + bool direct = false); - bool AddSceneCollection( - bool create_new, - const QString &name = QString()); + bool AddSceneCollection(bool create_new, + const QString &name = QString()); void UpdatePatronJson(const QString &text, const QString &error); + void PauseRecording(); + void UnpauseRecording(); + private slots: void AddSceneItem(OBSSceneItem item); void AddScene(OBSSource source); @@ -538,6 +558,8 @@ private slots: void SceneCopyFilters(); void ScenePasteFilters(); + void CheckDiskSpaceRemaining(); + private: /* OBS Callbacks */ static void SceneReordered(void *data, calldata_t *params); @@ -548,6 +570,8 @@ private: static void SourceRemoved(void *data, calldata_t *params); static void SourceActivated(void *data, calldata_t *params); static void SourceDeactivated(void *data, calldata_t *params); + static void SourceAudioActivated(void *data, calldata_t *params); + static void SourceAudioDeactivated(void *data, calldata_t *params); static void SourceRenamed(void *data, calldata_t *params); static void RenderMain(void *data, uint32_t cx, uint32_t cy); @@ -562,6 +586,11 @@ private: void AutoRemux(); + void UpdatePause(bool activate = true); + + bool LowDiskSpace(); + void DiskSpaceMessage(); + public: OBSSource GetProgramSource(); OBSScene GetCurrentScene(); @@ -575,7 +604,7 @@ public: } obs_service_t *GetService(); - void SetService(obs_service_t *service); + void SetService(obs_service_t *service); int GetTransitionDuration(); @@ -588,29 +617,26 @@ public: bool Active() const; void ResetUI(); - int ResetVideo(); + int ResetVideo(); bool ResetAudio(); void ResetOutputs(); void ResetAudioDevice(const char *sourceId, const char *deviceId, - const char *deviceDesc, int channel); + const char *deviceDesc, int channel); void NewProject(); void LoadProject(); inline void GetDisplayRect(int &x, int &y, int &cx, int &cy) { - x = previewX; - y = previewY; + x = previewX; + y = previewY; cx = previewCX; cy = previewCY; } - inline bool SavingDisabled() const - { - return disableSaving; - } + inline bool SavingDisabled() const { return disableSaving; } inline double GetCPUUsage() const { @@ -620,7 +646,7 @@ public: void SaveService(); bool LoadService(); - inline Auth *GetAuth() {return auth.get();} + inline Auth *GetAuth() { return auth.get(); } inline void EnableOutputs(bool enable) { @@ -635,7 +661,8 @@ public: QMenu *AddDeinterlacingMenu(QMenu *menu, obs_source_t *source); QMenu *AddScaleFilteringMenu(QMenu *menu, obs_sceneitem_t *item); QMenu *AddBackgroundColorMenu(QMenu *menu, QWidgetAction *widgetAction, - ColorSelect *select, obs_sceneitem_t *item); + ColorSelect *select, + obs_sceneitem_t *item); void CreateSourcePopupMenu(int idx, bool preview); void UpdateTitleBar(); @@ -691,7 +718,7 @@ private slots: void on_actionHorizontalCenter_triggered(); void on_scenes_currentItemChanged(QListWidgetItem *current, - QListWidgetItem *prev); + QListWidgetItem *prev); void on_scenes_customContextMenuRequested(const QPoint &pos); void on_actionAddScene_triggered(); void on_actionRemoveScene_triggered(); @@ -728,8 +755,7 @@ private slots: void on_preview_customContextMenuRequested(const QPoint &pos); void on_program_customContextMenuRequested(const QPoint &pos); - void on_previewDisabledLabel_customContextMenuRequested( - const QPoint &pos); + void PreviewDisabledMenu(const QPoint &pos); void on_actionNewSceneCollection_triggered(); void on_actionDupSceneCollection_triggered(); @@ -766,6 +792,8 @@ private slots: void on_resetUI_triggered(); void on_lockUI_toggled(bool lock); + void PauseToggled(); + void logUploadFinished(const QString &text, const QString &error); void updateCheckFinished(); @@ -779,7 +807,7 @@ private slots: void EditSceneItemName(); void SceneNameEdited(QWidget *editor, - QAbstractItemDelegate::EndEditHint endHint); + QAbstractItemDelegate::EndEditHint endHint); void OpenSceneFilters(); void OpenFilters(); @@ -825,8 +853,8 @@ public: virtual config_t *Config() const override; - virtual int GetProfilePath(char *path, size_t size, const char *file) - const override; + virtual int GetProfilePath(char *path, size_t size, + const char *file) const override; static void InitBrowserPanelSafeBlock(); @@ -839,8 +867,8 @@ class SceneRenameDelegate : public QStyledItemDelegate { public: SceneRenameDelegate(QObject *parent); - virtual void setEditorData(QWidget *editor, const QModelIndex &index) - const override; + virtual void setEditorData(QWidget *editor, + const QModelIndex &index) const override; protected: virtual bool eventFilter(QObject *editor, QEvent *event) override; diff --git a/UI/window-basic-preview.cpp b/UI/window-basic-preview.cpp index 2d9fa59..ebda31a 100644 --- a/UI/window-basic-preview.cpp +++ b/UI/window-basic-preview.cpp @@ -11,7 +11,7 @@ #include "obs-app.hpp" #include "platform.hpp" -#define HANDLE_RADIUS 4.0f +#define HANDLE_RADIUS 4.0f #define HANDLE_SEL_RADIUS (HANDLE_RADIUS * 1.5f) #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) #define SUPPORTS_FRACTIONAL_SCALING @@ -28,16 +28,19 @@ OBSBasicPreview::OBSBasicPreview(QWidget *parent, Qt::WindowFlags flags) OBSBasicPreview::~OBSBasicPreview() { - if (overflow) { - obs_enter_graphics(); + obs_enter_graphics(); + + if (overflow) gs_texture_destroy(overflow); - obs_leave_graphics(); - } + if (rectFill) + gs_vertexbuffer_destroy(rectFill); + + obs_leave_graphics(); } vec2 OBSBasicPreview::GetMouseEventPos(QMouseEvent *event) { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); #ifdef SUPPORTS_FRACTIONAL_SCALING float pixelRatio = main->devicePixelRatioF(); #else @@ -46,28 +49,44 @@ vec2 OBSBasicPreview::GetMouseEventPos(QMouseEvent *event) float scale = pixelRatio / main->previewScale; vec2 pos; vec2_set(&pos, - (float(event->x()) - main->previewX / pixelRatio) * scale, - (float(event->y()) - main->previewY / pixelRatio) * scale); + (float(event->x()) - main->previewX / pixelRatio) * scale, + (float(event->y()) - main->previewY / pixelRatio) * scale); return pos; } struct SceneFindData { - const vec2 &pos; + const vec2 &pos; OBSSceneItem item; - bool selectBelow; + bool selectBelow; obs_sceneitem_t *group = nullptr; SceneFindData(const SceneFindData &) = delete; SceneFindData(SceneFindData &&) = delete; - SceneFindData& operator=(const SceneFindData &) = delete; - SceneFindData& operator=(SceneFindData &&) = delete; + SceneFindData &operator=(const SceneFindData &) = delete; + SceneFindData &operator=(SceneFindData &&) = delete; inline SceneFindData(const vec2 &pos_, bool selectBelow_) - : pos (pos_), - selectBelow (selectBelow_) - {} + : pos(pos_), selectBelow(selectBelow_) + { + } +}; + +struct SceneFindBoxData { + const vec2 &startPos; + const vec2 &pos; + std::vector sceneItems; + + SceneFindBoxData(const SceneFindData &) = delete; + SceneFindBoxData(SceneFindData &&) = delete; + SceneFindBoxData &operator=(const SceneFindData &) = delete; + SceneFindBoxData &operator=(SceneFindData &&) = delete; + + inline SceneFindBoxData(const vec2 &startPos_, const vec2 &pos_) + : startPos(startPos_), pos(pos_) + { + } }; static bool SceneItemHasVideo(obs_sceneitem_t *item) @@ -77,21 +96,21 @@ static bool SceneItemHasVideo(obs_sceneitem_t *item) return (flags & OBS_SOURCE_VIDEO) != 0; } -static bool CloseFloat(float a, float b, float epsilon=0.01) +static bool CloseFloat(float a, float b, float epsilon = 0.01) { using std::abs; - return abs(a-b) <= epsilon; + return abs(a - b) <= epsilon; } static bool FindItemAtPos(obs_scene_t *scene, obs_sceneitem_t *item, - void *param) + void *param) { - SceneFindData *data = reinterpret_cast(param); - matrix4 transform; - matrix4 invTransform; - vec3 transformedPos; - vec3 pos3; - vec3 pos3_; + SceneFindData *data = reinterpret_cast(param); + matrix4 transform; + matrix4 invTransform; + vec3 transformedPos; + vec3 pos3; + vec3 pos3_; if (!SceneItemHasVideo(item)) return true; @@ -147,54 +166,50 @@ static inline vec2 GetOBSScreenSize() vec3 OBSBasicPreview::GetSnapOffset(const vec3 &tl, const vec3 &br) { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); vec2 screenSize = GetOBSScreenSize(); vec3 clampOffset; vec3_zero(&clampOffset); - const bool snap = config_get_bool(GetGlobalConfig(), - "BasicWindow", "SnappingEnabled"); + const bool snap = config_get_bool(GetGlobalConfig(), "BasicWindow", + "SnappingEnabled"); if (snap == false) return clampOffset; - const bool screenSnap = config_get_bool(GetGlobalConfig(), - "BasicWindow", "ScreenSnapping"); - const bool centerSnap = config_get_bool(GetGlobalConfig(), - "BasicWindow", "CenterSnapping"); + const bool screenSnap = config_get_bool( + GetGlobalConfig(), "BasicWindow", "ScreenSnapping"); + const bool centerSnap = config_get_bool( + GetGlobalConfig(), "BasicWindow", "CenterSnapping"); const float clampDist = config_get_double(GetGlobalConfig(), - "BasicWindow", "SnapDistance") / main->previewScale; + "BasicWindow", + "SnapDistance") / + main->previewScale; const float centerX = br.x - (br.x - tl.x) / 2.0f; const float centerY = br.y - (br.y - tl.y) / 2.0f; // Left screen edge. - if (screenSnap && - fabsf(tl.x) < clampDist) + if (screenSnap && fabsf(tl.x) < clampDist) clampOffset.x = -tl.x; // Right screen edge. - if (screenSnap && - fabsf(clampOffset.x) < EPSILON && + if (screenSnap && fabsf(clampOffset.x) < EPSILON && fabsf(screenSize.x - br.x) < clampDist) clampOffset.x = screenSize.x - br.x; // Horizontal center. - if (centerSnap && - fabsf(screenSize.x - (br.x - tl.x)) > clampDist && + if (centerSnap && fabsf(screenSize.x - (br.x - tl.x)) > clampDist && fabsf(screenSize.x / 2.0f - centerX) < clampDist) clampOffset.x = screenSize.x / 2.0f - centerX; // Top screen edge. - if (screenSnap && - fabsf(tl.y) < clampDist) + if (screenSnap && fabsf(tl.y) < clampDist) clampOffset.y = -tl.y; // Bottom screen edge. - if (screenSnap && - fabsf(clampOffset.y) < EPSILON && + if (screenSnap && fabsf(clampOffset.y) < EPSILON && fabsf(screenSize.y - br.y) < clampDist) clampOffset.y = screenSize.y - br.y; // Vertical center. - if (centerSnap && - fabsf(screenSize.y - (br.y - tl.y)) > clampDist && + if (centerSnap && fabsf(screenSize.y - (br.y - tl.y)) > clampDist && fabsf(screenSize.y / 2.0f - centerY) < clampDist) clampOffset.y = screenSize.y / 2.0f - centerY; @@ -203,7 +218,7 @@ vec3 OBSBasicPreview::GetSnapOffset(const vec3 &tl, const vec3 &br) OBSSceneItem OBSBasicPreview::GetItemAtPos(const vec2 &pos, bool selectBelow) { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); if (!scene) @@ -215,12 +230,12 @@ OBSSceneItem OBSBasicPreview::GetItemAtPos(const vec2 &pos, bool selectBelow) } static bool CheckItemSelected(obs_scene_t *scene, obs_sceneitem_t *item, - void *param) + void *param) { - SceneFindData *data = reinterpret_cast(param); - matrix4 transform; - vec3 transformedPos; - vec3 pos3; + SceneFindData *data = reinterpret_cast(param); + matrix4 transform; + vec3 transformedPos; + vec3 pos3; if (!SceneItemHasVideo(item)) return true; @@ -240,7 +255,8 @@ static bool CheckItemSelected(obs_scene_t *scene, obs_sceneitem_t *item, if (data->group) { matrix4 parent_transform; - obs_sceneitem_get_draw_transform(data->group, &parent_transform); + obs_sceneitem_get_draw_transform(data->group, + &parent_transform); matrix4_mul(&transform, &transform, &parent_transform); } @@ -261,7 +277,7 @@ static bool CheckItemSelected(obs_scene_t *scene, obs_sceneitem_t *item, bool OBSBasicPreview::SelectedAtPos(const vec2 &pos) { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); if (!scene) @@ -273,46 +289,45 @@ bool OBSBasicPreview::SelectedAtPos(const vec2 &pos) } struct HandleFindData { - const vec2 &pos; - const float radius; - matrix4 parent_xform; + const vec2 &pos; + const float radius; + matrix4 parent_xform; OBSSceneItem item; - ItemHandle handle = ItemHandle::None; + ItemHandle handle = ItemHandle::None; HandleFindData(const HandleFindData &) = delete; HandleFindData(HandleFindData &&) = delete; - HandleFindData& operator=(const HandleFindData &) = delete; - HandleFindData& operator=(HandleFindData &&) = delete; + HandleFindData &operator=(const HandleFindData &) = delete; + HandleFindData &operator=(HandleFindData &&) = delete; inline HandleFindData(const vec2 &pos_, float scale) - : pos (pos_), - radius (HANDLE_SEL_RADIUS / scale) + : pos(pos_), radius(HANDLE_SEL_RADIUS / scale) { matrix4_identity(&parent_xform); } inline HandleFindData(const HandleFindData &hfd, - obs_sceneitem_t *parent) - : pos (hfd.pos), - radius (hfd.radius), - item (hfd.item), - handle (hfd.handle) + obs_sceneitem_t *parent) + : pos(hfd.pos), + radius(hfd.radius), + item(hfd.item), + handle(hfd.handle) { obs_sceneitem_get_draw_transform(parent, &parent_xform); } }; static bool FindHandleAtPos(obs_scene_t *scene, obs_sceneitem_t *item, - void *param) + void *param) { - HandleFindData &data = *reinterpret_cast(param); + HandleFindData &data = *reinterpret_cast(param); if (!obs_sceneitem_selected(item)) { if (obs_sceneitem_is_group(item)) { HandleFindData newData(data, item); obs_sceneitem_group_enum_items(item, FindHandleAtPos, - &newData); + &newData); data.item = newData.item; data.handle = newData.handle; } @@ -320,16 +335,15 @@ static bool FindHandleAtPos(obs_scene_t *scene, obs_sceneitem_t *item, return true; } - matrix4 transform; - vec3 pos3; - float closestHandle = data.radius; + matrix4 transform; + vec3 pos3; + float closestHandle = data.radius; vec3_set(&pos3, data.pos.x, data.pos.y, 0.0f); obs_sceneitem_get_box_transform(item, &transform); - auto TestHandle = [&] (float x, float y, ItemHandle handle) - { + auto TestHandle = [&](float x, float y, ItemHandle handle) { vec3 handlePos = GetTransformedPos(x, y, transform); vec3_transform(&handlePos, &handlePos, &data.parent_xform); @@ -337,8 +351,8 @@ static bool FindHandleAtPos(obs_scene_t *scene, obs_sceneitem_t *item, if (dist < data.radius) { if (dist < closestHandle) { closestHandle = dist; - data.handle = handle; - data.item = item; + data.handle = handle; + data.item = item; } } }; @@ -370,10 +384,12 @@ static vec2 GetItemSize(obs_sceneitem_t *item) obs_sceneitem_get_scale(item, &scale); obs_sceneitem_get_crop(item, &crop); - size.x = float(obs_source_get_width(source) - - crop.left - crop.right) * scale.x; - size.y = float(obs_source_get_height(source) - - crop.top - crop.bottom) * scale.y; + size.x = float(obs_source_get_width(source) - crop.left - + crop.right) * + scale.x; + size.y = float(obs_source_get_height(source) - crop.top - + crop.bottom) * + scale.y; } return size; @@ -381,7 +397,7 @@ static vec2 GetItemSize(obs_sceneitem_t *item) void OBSBasicPreview::GetStretchHandleData(const vec2 &pos) { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); if (!scene) @@ -397,13 +413,13 @@ void OBSBasicPreview::GetStretchHandleData(const vec2 &pos) HandleFindData data(scaled_pos, scale); obs_scene_enum_items(scene, FindHandleAtPos, &data); - stretchItem = std::move(data.item); - stretchHandle = data.handle; + stretchItem = std::move(data.item); + stretchHandle = data.handle; if (stretchHandle != ItemHandle::None) { matrix4 boxTransform; - vec3 itemUL; - float itemRot; + vec3 itemUL; + float itemRot; stretchItemSize = GetItemSize(stretchItem); @@ -413,32 +429,31 @@ void OBSBasicPreview::GetStretchHandleData(const vec2 &pos) /* build the item space conversion matrices */ matrix4_identity(&itemToScreen); - matrix4_rotate_aa4f(&itemToScreen, &itemToScreen, - 0.0f, 0.0f, 1.0f, RAD(itemRot)); - matrix4_translate3f(&itemToScreen, &itemToScreen, - itemUL.x, itemUL.y, 0.0f); + matrix4_rotate_aa4f(&itemToScreen, &itemToScreen, 0.0f, 0.0f, + 1.0f, RAD(itemRot)); + matrix4_translate3f(&itemToScreen, &itemToScreen, itemUL.x, + itemUL.y, 0.0f); matrix4_identity(&screenToItem); - matrix4_translate3f(&screenToItem, &screenToItem, - -itemUL.x, -itemUL.y, 0.0f); - matrix4_rotate_aa4f(&screenToItem, &screenToItem, - 0.0f, 0.0f, 1.0f, RAD(-itemRot)); + matrix4_translate3f(&screenToItem, &screenToItem, -itemUL.x, + -itemUL.y, 0.0f); + matrix4_rotate_aa4f(&screenToItem, &screenToItem, 0.0f, 0.0f, + 1.0f, RAD(-itemRot)); obs_sceneitem_get_crop(stretchItem, &startCrop); obs_sceneitem_get_pos(stretchItem, &startItemPos); obs_source_t *source = obs_sceneitem_get_source(stretchItem); cropSize.x = float(obs_source_get_width(source) - - startCrop.left - startCrop.right); + startCrop.left - startCrop.right); cropSize.y = float(obs_source_get_height(source) - - startCrop.top - startCrop.bottom); + startCrop.top - startCrop.bottom); stretchGroup = obs_sceneitem_get_group(scene, stretchItem); if (stretchGroup) { obs_sceneitem_get_draw_transform(stretchGroup, - &invGroupTransform); - matrix4_inv(&invGroupTransform, - &invGroupTransform); + &invGroupTransform); + matrix4_inv(&invGroupTransform, &invGroupTransform); obs_sceneitem_defer_group_resize_begin(stretchGroup); } } @@ -480,8 +495,8 @@ void OBSBasicPreview::keyReleaseEvent(QKeyEvent *event) void OBSBasicPreview::wheelEvent(QWheelEvent *event) { - if (scrollMode && IsFixedScaling() - && event->orientation() == Qt::Vertical) { + if (scrollMode && IsFixedScaling() && + event->orientation() == Qt::Vertical) { if (event->delta() > 0) SetScalingLevel(scalingLevel + 1); else if (event->delta() < 0) @@ -512,7 +527,7 @@ void OBSBasicPreview::mousePressEvent(QMouseEvent *event) return; } - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); #ifdef SUPPORTS_FRACTIONAL_SCALING float pixelRatio = main->devicePixelRatioF(); #else @@ -522,6 +537,8 @@ void OBSBasicPreview::mousePressEvent(QMouseEvent *event) float y = float(event->y()) - main->previewY / pixelRatio; Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers(); bool altDown = (modifiers & Qt::AltModifier); + bool shiftDown = (modifiers & Qt::ShiftModifier); + bool ctrlDown = (modifiers & Qt::ControlModifier); OBSQTDisplay::mousePressEvent(event); @@ -532,9 +549,25 @@ void OBSBasicPreview::mousePressEvent(QMouseEvent *event) if (event->button() == Qt::LeftButton) mouseDown = true; + { + std::lock_guard lock(selectMutex); + selectedItems.clear(); + } + if (altDown) cropping = true; + if (altDown || shiftDown || ctrlDown) { + vec2 s; + SceneFindBoxData data(s, s); + + obs_scene_enum_items(main->GetCurrentScene(), FindSelected, + &data); + + std::lock_guard lock(selectMutex); + selectedItems = data.sceneItems; + } + vec2_set(&startPos, x, y); GetStretchHandleData(startPos); @@ -544,12 +577,14 @@ void OBSBasicPreview::mousePressEvent(QMouseEvent *event) mouseOverItems = SelectedAtPos(startPos); vec2_zero(&lastMoveOffset); + + mousePos = startPos; } static bool select_one(obs_scene_t *scene, obs_sceneitem_t *item, void *param) { obs_sceneitem_t *selectedItem = - reinterpret_cast(param); + reinterpret_cast(param); if (obs_sceneitem_is_group(item)) obs_sceneitem_group_enum_items(item, select_one, param); @@ -561,12 +596,12 @@ static bool select_one(obs_scene_t *scene, obs_sceneitem_t *item, void *param) void OBSBasicPreview::DoSelect(const vec2 &pos) { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); - OBSScene scene = main->GetCurrentScene(); - OBSSceneItem item = GetItemAtPos(pos, true); + OBSScene scene = main->GetCurrentScene(); + OBSSceneItem item = GetItemAtPos(pos, true); - obs_scene_enum_items(scene, select_one, (obs_sceneitem_t*)item); + obs_scene_enum_items(scene, select_one, (obs_sceneitem_t *)item); } void OBSBasicPreview::DoCtrlSelect(const vec2 &pos) @@ -605,18 +640,54 @@ void OBSBasicPreview::mouseReleaseEvent(QMouseEvent *event) if (!mouseMoved) ProcessClick(pos); + if (selectionBox) { + Qt::KeyboardModifiers modifiers = + QGuiApplication::keyboardModifiers(); + + bool altDown = modifiers & Qt::AltModifier; + bool shiftDown = modifiers & Qt::ShiftModifier; + bool ctrlDown = modifiers & Qt::ControlModifier; + + std::lock_guard lock(selectMutex); + if (altDown || ctrlDown || shiftDown) { + for (int i = 0; i < selectedItems.size(); i++) { + obs_sceneitem_select(selectedItems[i], + true); + } + } + + for (int i = 0; i < hoveredPreviewItems.size(); i++) { + bool select = true; + obs_sceneitem_t *item = hoveredPreviewItems[i]; + + if (altDown) { + select = false; + } else if (ctrlDown) { + select = !obs_sceneitem_selected(item); + } + + obs_sceneitem_select(hoveredPreviewItems[i], + select); + } + } + if (stretchGroup) { obs_sceneitem_defer_group_resize_end(stretchGroup); } - stretchItem = nullptr; + stretchItem = nullptr; stretchGroup = nullptr; - mouseDown = false; - mouseMoved = false; - cropping = false; + mouseDown = false; + mouseMoved = false; + cropping = false; + selectionBox = false; OBSSceneItem item = GetItemAtPos(pos, true); - hoveredPreviewItem = item; + + std::lock_guard lock(selectMutex); + hoveredPreviewItems.clear(); + hoveredPreviewItems.push_back(item); + selectedItems.clear(); } } @@ -626,13 +697,13 @@ struct SelectedItemBounds { }; static bool AddItemBounds(obs_scene_t *scene, obs_sceneitem_t *item, - void *param) + void *param) { - SelectedItemBounds *data = reinterpret_cast(param); + SelectedItemBounds *data = + reinterpret_cast(param); vec3 t[4]; - auto add_bounds = [data, &t] () - { + auto add_bounds = [data, &t]() { for (const vec3 &v : t) { if (data->first) { vec3_copy(&data->tl, &v); @@ -686,9 +757,9 @@ struct OffsetData { }; static bool GetSourceSnapOffset(obs_scene_t *scene, obs_sceneitem_t *item, - void *param) + void *param) { - OffsetData *data = reinterpret_cast(param); + OffsetData *data = reinterpret_cast(param); if (obs_sceneitem_selected(item)) return true; @@ -696,12 +767,10 @@ static bool GetSourceSnapOffset(obs_scene_t *scene, obs_sceneitem_t *item, matrix4 boxTransform; obs_sceneitem_get_box_transform(item, &boxTransform); - vec3 t[4] = { - GetTransformedPos(0.0f, 0.0f, boxTransform), - GetTransformedPos(1.0f, 0.0f, boxTransform), - GetTransformedPos(0.0f, 1.0f, boxTransform), - GetTransformedPos(1.0f, 1.0f, boxTransform) - }; + vec3 t[4] = {GetTransformedPos(0.0f, 0.0f, boxTransform), + GetTransformedPos(1.0f, 0.0f, boxTransform), + GetTransformedPos(0.0f, 1.0f, boxTransform), + GetTransformedPos(1.0f, 1.0f, boxTransform)}; bool first = true; vec3 tl, br; @@ -719,15 +788,15 @@ static bool GetSourceSnapOffset(obs_scene_t *scene, obs_sceneitem_t *item, } // Snap to other source edges -#define EDGE_SNAP(l, r, x, y) \ - do { \ - double dist = fabsf(l.x - data->r.x); \ - if (dist < data->clampDist && \ - fabsf(data->offset.x) < EPSILON && \ - data->tl.y < br.y && \ - data->br.y > tl.y && \ - (fabsf(data->offset.x) > dist || data->offset.x < EPSILON)) \ - data->offset.x = l.x - data->r.x; \ +#define EDGE_SNAP(l, r, x, y) \ + do { \ + double dist = fabsf(l.x - data->r.x); \ + if (dist < data->clampDist && \ + fabsf(data->offset.x) < EPSILON && data->tl.y < br.y && \ + data->br.y > tl.y && \ + (fabsf(data->offset.x) > dist || \ + data->offset.x < EPSILON)) \ + data->offset.x = l.x - data->r.x; \ } while (false) EDGE_SNAP(tl, br, x, y); @@ -742,7 +811,7 @@ static bool GetSourceSnapOffset(obs_scene_t *scene, obs_sceneitem_t *item, void OBSBasicPreview::SnapItemMovement(vec2 &offset) { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); SelectedItemBounds data; @@ -755,10 +824,10 @@ void OBSBasicPreview::SnapItemMovement(vec2 &offset) vec3 snapOffset = GetSnapOffset(data.tl, data.br); - const bool snap = config_get_bool(GetGlobalConfig(), - "BasicWindow", "SnappingEnabled"); - const bool sourcesSnap = config_get_bool(GetGlobalConfig(), - "BasicWindow", "SourceSnapping"); + const bool snap = config_get_bool(GetGlobalConfig(), "BasicWindow", + "SnappingEnabled"); + const bool sourcesSnap = config_get_bool( + GetGlobalConfig(), "BasicWindow", "SourceSnapping"); if (snap == false) return; if (sourcesSnap == false) { @@ -768,7 +837,9 @@ void OBSBasicPreview::SnapItemMovement(vec2 &offset) } const float clampDist = config_get_double(GetGlobalConfig(), - "BasicWindow", "SnapDistance") / main->previewScale; + "BasicWindow", + "SnapDistance") / + main->previewScale; OffsetData offsetData; offsetData.clampDist = clampDist; @@ -794,7 +865,7 @@ static bool move_items(obs_scene_t *scene, obs_sceneitem_t *item, void *param) return true; bool selected = obs_sceneitem_selected(item); - vec2 *offset = reinterpret_cast(param); + vec2 *offset = reinterpret_cast(param); if (obs_sceneitem_is_group(item) && !selected) { matrix4 transform; @@ -822,7 +893,7 @@ static bool move_items(obs_scene_t *scene, obs_sceneitem_t *item, void *param) void OBSBasicPreview::MoveItems(const vec2 &pos) { Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers(); - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); vec2 offset, moveOffset; @@ -837,6 +908,191 @@ void OBSBasicPreview::MoveItems(const vec2 &pos) obs_scene_enum_items(scene, move_items, &moveOffset); } +static bool CounterClockwise(float x1, float x2, float x3, float y1, float y2, + float y3) +{ + return (y3 - y1) * (x2 - x1) > (y2 - y1) * (x3 - x1); +} + +static bool IntersectLine(float x1, float x2, float x3, float x4, float y1, + float y2, float y3, float y4) +{ + bool a = CounterClockwise(x1, x2, x3, y1, y2, y3); + bool b = CounterClockwise(x1, x2, x4, y1, y2, y4); + bool c = CounterClockwise(x3, x4, x1, y3, y4, y1); + bool d = CounterClockwise(x3, x4, x2, y3, y4, y2); + + return (a != b) && (c != d); +} + +static bool IntersectBox(matrix4 transform, float x1, float x2, float y1, + float y2) +{ + float x3, x4, y3, y4; + + x3 = transform.t.x; + y3 = transform.t.y; + x4 = x3 + transform.x.x; + y4 = y3 + transform.x.y; + + if (IntersectLine(x1, x1, x3, x4, y1, y2, y3, y4) || + IntersectLine(x1, x2, x3, x4, y1, y1, y3, y4) || + IntersectLine(x2, x2, x3, x4, y1, y2, y3, y4) || + IntersectLine(x1, x2, x3, x4, y2, y2, y3, y4)) + return true; + + x4 = x3 + transform.y.x; + y4 = y3 + transform.y.y; + + if (IntersectLine(x1, x1, x3, x4, y1, y2, y3, y4) || + IntersectLine(x1, x2, x3, x4, y1, y1, y3, y4) || + IntersectLine(x2, x2, x3, x4, y1, y2, y3, y4) || + IntersectLine(x1, x2, x3, x4, y2, y2, y3, y4)) + return true; + + x3 = transform.t.x + transform.x.x; + y3 = transform.t.y + transform.x.y; + x4 = x3 + transform.y.x; + y4 = y3 + transform.y.y; + + if (IntersectLine(x1, x1, x3, x4, y1, y2, y3, y4) || + IntersectLine(x1, x2, x3, x4, y1, y1, y3, y4) || + IntersectLine(x2, x2, x3, x4, y1, y2, y3, y4) || + IntersectLine(x1, x2, x3, x4, y2, y2, y3, y4)) + return true; + + x3 = transform.t.x + transform.y.x; + y3 = transform.t.y + transform.y.y; + x4 = x3 + transform.x.x; + y4 = y3 + transform.x.y; + + if (IntersectLine(x1, x1, x3, x4, y1, y2, y3, y4) || + IntersectLine(x1, x2, x3, x4, y1, y1, y3, y4) || + IntersectLine(x2, x2, x3, x4, y1, y2, y3, y4) || + IntersectLine(x1, x2, x3, x4, y2, y2, y3, y4)) + return true; + + return false; +} +#undef PI + +bool OBSBasicPreview::FindSelected(obs_scene_t *scene, obs_sceneitem_t *item, + void *param) +{ + SceneFindBoxData *data = reinterpret_cast(param); + + if (obs_sceneitem_selected(item)) + data->sceneItems.push_back(item); + + UNUSED_PARAMETER(scene); + return true; +} + +static bool FindItemsInBox(obs_scene_t *scene, obs_sceneitem_t *item, + void *param) +{ + SceneFindBoxData *data = reinterpret_cast(param); + matrix4 transform; + matrix4 invTransform; + vec3 transformedPos; + vec3 pos3; + vec3 pos3_; + + float x1 = std::min(data->startPos.x, data->pos.x); + float x2 = std::max(data->startPos.x, data->pos.x); + float y1 = std::min(data->startPos.y, data->pos.y); + float y2 = std::max(data->startPos.y, data->pos.y); + + if (!SceneItemHasVideo(item)) + return true; + if (obs_sceneitem_locked(item)) + return true; + if (!obs_sceneitem_visible(item)) + return true; + + vec3_set(&pos3, data->pos.x, data->pos.y, 0.0f); + + obs_sceneitem_get_box_transform(item, &transform); + + matrix4_inv(&invTransform, &transform); + vec3_transform(&transformedPos, &pos3, &invTransform); + vec3_transform(&pos3_, &transformedPos, &transform); + + if (CloseFloat(pos3.x, pos3_.x) && CloseFloat(pos3.y, pos3_.y) && + transformedPos.x >= 0.0f && transformedPos.x <= 1.0f && + transformedPos.y >= 0.0f && transformedPos.y <= 1.0f) { + + data->sceneItems.push_back(item); + return true; + } + + if (transform.t.x > x1 && transform.t.x < x2 && transform.t.y > y1 && + transform.t.y < y2) { + + data->sceneItems.push_back(item); + return true; + } + + if (transform.t.x + transform.x.x > x1 && + transform.t.x + transform.x.x < x2 && + transform.t.y + transform.x.y > y1 && + transform.t.y + transform.x.y < y2) { + + data->sceneItems.push_back(item); + return true; + } + + if (transform.t.x + transform.y.x > x1 && + transform.t.x + transform.y.x < x2 && + transform.t.y + transform.y.y > y1 && + transform.t.y + transform.y.y < y2) { + + data->sceneItems.push_back(item); + return true; + } + + if (transform.t.x + transform.x.x + transform.y.x > x1 && + transform.t.x + transform.x.x + transform.y.x < x2 && + transform.t.y + transform.x.y + transform.y.y > y1 && + transform.t.y + transform.x.y + transform.y.y < y2) { + + data->sceneItems.push_back(item); + return true; + } + + if (transform.t.x + 0.5 * (transform.x.x + transform.y.x) > x1 && + transform.t.x + 0.5 * (transform.x.x + transform.y.x) < x2 && + transform.t.y + 0.5 * (transform.x.y + transform.y.y) > y1 && + transform.t.y + 0.5 * (transform.x.y + transform.y.y) < y2) { + + data->sceneItems.push_back(item); + return true; + } + + if (IntersectBox(transform, x1, x2, y1, y2)) { + data->sceneItems.push_back(item); + return true; + } + + UNUSED_PARAMETER(scene); + return true; +} + +void OBSBasicPreview::BoxItems(const vec2 &startPos, const vec2 &pos) +{ + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + + OBSScene scene = main->GetCurrentScene(); + if (!scene) + return; + + SceneFindBoxData data(startPos, pos); + obs_scene_enum_items(scene, FindItemsInBox, &data); + + std::lock_guard lock(selectMutex); + hoveredPreviewItems = data.sceneItems; +} + vec3 OBSBasicPreview::CalculateStretchPos(const vec3 &tl, const vec3 &br) { uint32_t alignment = obs_sceneitem_get_alignment(stretchItem); @@ -862,14 +1118,14 @@ vec3 OBSBasicPreview::CalculateStretchPos(const vec3 &tl, const vec3 &br) } void OBSBasicPreview::ClampAspect(vec3 &tl, vec3 &br, vec2 &size, - const vec2 &baseSize) + const vec2 &baseSize) { - float baseAspect = baseSize.x / baseSize.y; - float aspect = size.x / size.y; + float baseAspect = baseSize.x / baseSize.y; + float aspect = size.x / size.y; uint32_t stretchFlags = (uint32_t)stretchHandle; - if (stretchHandle == ItemHandle::TopLeft || - stretchHandle == ItemHandle::TopRight || + if (stretchHandle == ItemHandle::TopLeft || + stretchHandle == ItemHandle::TopRight || stretchHandle == ItemHandle::BottomLeft || stretchHandle == ItemHandle::BottomRight) { if (aspect < baseAspect) { @@ -887,7 +1143,7 @@ void OBSBasicPreview::ClampAspect(vec3 &tl, vec3 &br, vec2 &size, } } else if (stretchHandle == ItemHandle::TopCenter || - stretchHandle == ItemHandle::BottomCenter) { + stretchHandle == ItemHandle::BottomCenter) { if ((size.y >= 0.0f && size.x >= 0.0f) || (size.y <= 0.0f && size.x <= 0.0f)) size.x = size.y * baseAspect; @@ -895,7 +1151,7 @@ void OBSBasicPreview::ClampAspect(vec3 &tl, vec3 &br, vec2 &size, size.x = size.y * baseAspect * -1.0f; } else if (stretchHandle == ItemHandle::CenterLeft || - stretchHandle == ItemHandle::CenterRight) { + stretchHandle == ItemHandle::CenterRight) { if ((size.y >= 0.0f && size.x >= 0.0f) || (size.y <= 0.0f && size.x <= 0.0f)) size.y = size.x / baseAspect; @@ -920,12 +1176,12 @@ void OBSBasicPreview::ClampAspect(vec3 &tl, vec3 &br, vec2 &size, void OBSBasicPreview::SnapStretchingToScreen(vec3 &tl, vec3 &br) { uint32_t stretchFlags = (uint32_t)stretchHandle; - vec3 newTL = GetTransformedPos(tl.x, tl.y, itemToScreen); - vec3 newTR = GetTransformedPos(br.x, tl.y, itemToScreen); - vec3 newBL = GetTransformedPos(tl.x, br.y, itemToScreen); - vec3 newBR = GetTransformedPos(br.x, br.y, itemToScreen); - vec3 boundingTL; - vec3 boundingBR; + vec3 newTL = GetTransformedPos(tl.x, tl.y, itemToScreen); + vec3 newTR = GetTransformedPos(br.x, tl.y, itemToScreen); + vec3 newBL = GetTransformedPos(tl.x, br.y, itemToScreen); + vec3 newBR = GetTransformedPos(br.x, br.y, itemToScreen); + vec3 boundingTL; + vec3 boundingBR; vec3_copy(&boundingTL, &newTL); vec3_min(&boundingTL, &boundingTL, &newTR); @@ -984,14 +1240,12 @@ void OBSBasicPreview::CropItem(const vec2 &pos) vec2 max_tl; vec2 max_br; - vec2_set(&max_tl, - float(-crop.left) * scale.x, - float(-crop.top) * scale.y); - vec2_set(&max_br, - stretchItemSize.x + crop.right * scale.x, - stretchItemSize.y + crop.bottom * scale.y); + vec2_set(&max_tl, float(-crop.left) * scale.x, + float(-crop.top) * scale.y); + vec2_set(&max_br, stretchItemSize.x + crop.right * scale.x, + stretchItemSize.y + crop.bottom * scale.y); - typedef std::function minmax_func_t; + typedef std::function minmax_func_t; minmax_func_t min_x = scale.x < 0.0f ? maxfunc : minfunc; minmax_func_t min_y = scale.y < 0.0f ? maxfunc : minfunc; @@ -1021,8 +1275,8 @@ void OBSBasicPreview::CropItem(const vec2 &pos) pos3.y = br.y = max_y(pos3.y, minY); } -#define ALIGN_X (ITEM_LEFT|ITEM_RIGHT) -#define ALIGN_Y (ITEM_TOP|ITEM_BOTTOM) +#define ALIGN_X (ITEM_LEFT | ITEM_RIGHT) +#define ALIGN_Y (ITEM_TOP | ITEM_BOTTOM) vec3 newPos; vec3_zero(&newPos); @@ -1049,12 +1303,14 @@ void OBSBasicPreview::CropItem(const vec2 &pos) if (stretchFlags & ITEM_LEFT) crop.left += int(std::round(tl.x / scale.x)); else if (stretchFlags & ITEM_RIGHT) - crop.right += int(std::round((stretchItemSize.x - br.x) / scale.x)); + crop.right += + int(std::round((stretchItemSize.x - br.x) / scale.x)); if (stretchFlags & ITEM_TOP) crop.top += int(std::round(tl.y / scale.y)); else if (stretchFlags & ITEM_BOTTOM) - crop.bottom += int(std::round((stretchItemSize.y - br.y) / scale.y)); + crop.bottom += + int(std::round((stretchItemSize.y - br.y) / scale.y)); vec3_transform(&newPos, &newPos, &itemToScreen); newPos.x = std::round(newPos.x); @@ -1075,7 +1331,7 @@ void OBSBasicPreview::CropItem(const vec2 &pos) obs_sceneitem_defer_update_begin(stretchItem); obs_sceneitem_set_crop(stretchItem, &crop); if (boundsType == OBS_BOUNDS_NONE) - obs_sceneitem_set_pos(stretchItem, (vec2*)&newPos); + obs_sceneitem_set_pos(stretchItem, (vec2 *)&newPos); obs_sceneitem_defer_update_end(stretchItem); } @@ -1109,19 +1365,20 @@ void OBSBasicPreview::StretchItem(const vec2 &pos) obs_source_t *source = obs_sceneitem_get_source(stretchItem); vec2 baseSize; - vec2_set(&baseSize, - float(obs_source_get_width(source)), - float(obs_source_get_height(source))); + vec2_set(&baseSize, float(obs_source_get_width(source)), + float(obs_source_get_height(source))); vec2 size; - vec2_set(&size,br. x - tl.x, br.y - tl.y); + vec2_set(&size, br.x - tl.x, br.y - tl.y); if (boundsType != OBS_BOUNDS_NONE) { if (shiftDown) ClampAspect(tl, br, size, baseSize); - if (tl.x > br.x) std::swap(tl.x, br.x); - if (tl.y > br.y) std::swap(tl.y, br.y); + if (tl.x > br.x) + std::swap(tl.x, br.x); + if (tl.y > br.y) + std::swap(tl.y, br.y); vec2_abs(&size, &size); @@ -1163,8 +1420,6 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event) return; if (mouseDown) { - hoveredPreviewItem = nullptr; - vec2 pos = GetMouseEventPos(event); if (!mouseMoved && !mouseOverItems && @@ -1177,16 +1432,18 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event) pos.y = std::round(pos.y); if (stretchHandle != ItemHandle::None) { - OBSBasic *main = reinterpret_cast( - App()->GetMainWindow()); + selectionBox = false; + + OBSBasic *main = reinterpret_cast( + App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); - obs_sceneitem_t *group = obs_sceneitem_get_group( - scene, stretchItem); + obs_sceneitem_t *group = + obs_sceneitem_get_group(scene, stretchItem); if (group) { vec3 group_pos; vec3_set(&group_pos, pos.x, pos.y, 0.0f); vec3_transform(&group_pos, &group_pos, - &invGroupTransform); + &invGroupTransform); pos.x = group_pos.x; pos.y = group_pos.y; } @@ -1197,23 +1454,32 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event) StretchItem(pos); } else if (mouseOverItems) { + selectionBox = false; MoveItems(pos); + } else { + selectionBox = true; + if (!mouseMoved) + DoSelect(startPos); + BoxItems(startPos, pos); } mouseMoved = true; + mousePos = pos; } else { vec2 pos = GetMouseEventPos(event); OBSSceneItem item = GetItemAtPos(pos, true); - hoveredPreviewItem = item; + std::lock_guard lock(selectMutex); + hoveredPreviewItems.clear(); + hoveredPreviewItems.push_back(item); } } -void OBSBasicPreview::leaveEvent(QEvent *event) +void OBSBasicPreview::leaveEvent(QEvent *) { - hoveredPreviewItem = nullptr; - - UNUSED_PARAMETER(event); + std::lock_guard lock(selectMutex); + if (!selectionBox) + hoveredPreviewItems.clear(); } static void DrawSquareAtPos(float x, float y) @@ -1230,13 +1496,13 @@ static void DrawSquareAtPos(float x, float y) gs_matrix_translate(&pos); gs_matrix_translate3f(-HANDLE_RADIUS, -HANDLE_RADIUS, 0.0f); - gs_matrix_scale3f(HANDLE_RADIUS*2, HANDLE_RADIUS*2, 1.0f); + gs_matrix_scale3f(HANDLE_RADIUS * 2, HANDLE_RADIUS * 2, 1.0f); gs_draw(GS_TRISTRIP, 0, 0); gs_matrix_pop(); } static void DrawLine(float x1, float y1, float x2, float y2, float thickness, - vec2 scale) + vec2 scale) { float ySide = (y1 == y2) ? (y1 < 0.5f ? 1.0f : -1.0f) : 0.0f; float xSide = (x1 == x2) ? (x1 < 0.5f ? 1.0f : -1.0f) : 0.0f; @@ -1245,9 +1511,9 @@ static void DrawLine(float x1, float y1, float x2, float y2, float thickness, gs_vertex2f(x1, y1); gs_vertex2f(x1 + (xSide * (thickness / scale.x)), - y1 + (ySide * (thickness / scale.y))); + y1 + (ySide * (thickness / scale.y))); gs_vertex2f(x2 + (xSide * (thickness / scale.x)), - y2 + (ySide * (thickness / scale.y))); + y2 + (ySide * (thickness / scale.y))); gs_vertex2f(x2, y2); gs_vertex2f(x1, y1); @@ -1292,14 +1558,12 @@ static void DrawRect(float thickness, vec2 scale) static inline bool crop_enabled(const obs_sceneitem_crop *crop) { - return crop->left > 0 || - crop->top > 0 || - crop->right > 0 || + return crop->left > 0 || crop->top > 0 || crop->right > 0 || crop->bottom > 0; } bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene, - obs_sceneitem_t *item, void *param) + obs_sceneitem_t *item, void *param) { if (obs_sceneitem_locked(item)) return true; @@ -1308,7 +1572,7 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene, return true; bool select = config_get_bool(GetGlobalConfig(), "BasicWindow", - "OverflowSelectionHidden"); + "OverflowSelectionHidden"); if (!select && !obs_sceneitem_visible(item)) return true; @@ -1319,17 +1583,18 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene, gs_matrix_push(); gs_matrix_mul(&mat); - obs_sceneitem_group_enum_items(item, DrawSelectedOverflow, param); + obs_sceneitem_group_enum_items(item, DrawSelectedOverflow, + param); gs_matrix_pop(); } bool always = config_get_bool(GetGlobalConfig(), "BasicWindow", - "OverflowAlwaysVisible"); + "OverflowAlwaysVisible"); if (!always && !obs_sceneitem_selected(item)) return true; - OBSBasicPreview *prev = reinterpret_cast(param); + OBSBasicPreview *prev = reinterpret_cast(param); matrix4 boxTransform; matrix4 invBoxTransform; @@ -1343,14 +1608,13 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene, {{{1.f, 1.f, 0.f}}}, }; - bool visible = std::all_of(std::begin(bounds), std::end(bounds), - [&](const vec3 &b) - { - vec3 pos; - vec3_transform(&pos, &b, &boxTransform); - vec3_transform(&pos, &pos, &invBoxTransform); - return CloseFloat(pos.x, b.x) && CloseFloat(pos.y, b.y); - }); + bool visible = std::all_of( + std::begin(bounds), std::end(bounds), [&](const vec3 &b) { + vec3 pos; + vec3_transform(&pos, &b, &boxTransform); + vec3_transform(&pos, &pos, &invBoxTransform); + return CloseFloat(pos.x, b.x) && CloseFloat(pos.y, b.y); + }); if (!visible) return true; @@ -1360,9 +1624,9 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene, obs_transform_info info; obs_sceneitem_get_info(item, &info); - gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_REPEAT); - gs_eparam_t *image = gs_effect_get_param_by_name(solid, "image"); - gs_eparam_t *scale = gs_effect_get_param_by_name(solid, "scale"); + gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_REPEAT); + gs_eparam_t *image = gs_effect_get_param_by_name(solid, "image"); + gs_eparam_t *scale = gs_effect_get_param_by_name(solid, "scale"); vec2 s; vec2_set(&s, boxTransform.x.x / 96, boxTransform.y.y / 96); @@ -1389,7 +1653,7 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene, } bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene, - obs_sceneitem_t *item, void *param) + obs_sceneitem_t *item, void *param) { if (obs_sceneitem_locked(item)) return true; @@ -1407,11 +1671,20 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene, gs_matrix_pop(); } - OBSBasicPreview *prev = reinterpret_cast(param); + OBSBasicPreview *prev = reinterpret_cast(param); OBSBasic *main = OBSBasic::Get(); - bool hovered = prev->hoveredPreviewItem == item || - prev->hoveredListItem == item; + bool hovered = false; + { + std::lock_guard lock(prev->selectMutex); + for (int i = 0; i < prev->hoveredPreviewItems.size(); i++) { + if (prev->hoveredPreviewItems[i] == item) { + hovered = true; + break; + } + } + } + bool selected = obs_sceneitem_selected(item); if (!selected && !hovered) @@ -1437,14 +1710,13 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene, vec4_set(&green, 0.0f, 1.0f, 0.0f, 1.0f); vec4_set(&blue, 0.0f, 0.5f, 1.0f, 1.0f); - bool visible = std::all_of(std::begin(bounds), std::end(bounds), - [&](const vec3 &b) - { - vec3 pos; - vec3_transform(&pos, &b, &boxTransform); - vec3_transform(&pos, &pos, &invBoxTransform); - return CloseFloat(pos.x, b.x) && CloseFloat(pos.y, b.y); - }); + bool visible = std::all_of( + std::begin(bounds), std::end(bounds), [&](const vec3 &b) { + vec3 pos; + vec3_transform(&pos, &b, &boxTransform); + vec3_transform(&pos, &pos, &invBoxTransform); + return CloseFloat(pos.x, b.x) && CloseFloat(pos.y, b.y); + }); if (!visible) return true; @@ -1471,17 +1743,17 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene, gs_eparam_t *colParam = gs_effect_get_param_by_name(eff, "color"); if (info.bounds_type == OBS_BOUNDS_NONE && crop_enabled(&crop)) { -#define DRAW_SIDE(side, x1, y1, x2, y2) \ - if (hovered && !selected) \ - gs_effect_set_vec4(colParam, &blue); \ - else if (crop.side > 0) \ - gs_effect_set_vec4(colParam, &green); \ - DrawLine(x1, y1, x2, y2, HANDLE_RADIUS / 2, boxScale); \ - gs_effect_set_vec4(colParam, &red); +#define DRAW_SIDE(side, x1, y1, x2, y2) \ + if (hovered && !selected) \ + gs_effect_set_vec4(colParam, &blue); \ + else if (crop.side > 0) \ + gs_effect_set_vec4(colParam, &green); \ + DrawLine(x1, y1, x2, y2, HANDLE_RADIUS / 2, boxScale); \ + gs_effect_set_vec4(colParam, &red); - DRAW_SIDE(left, 0.0f, 0.0f, 0.0f, 1.0f); - DRAW_SIDE(top, 0.0f, 0.0f, 1.0f, 0.0f); - DRAW_SIDE(right, 1.0f, 0.0f, 1.0f, 1.0f); + DRAW_SIDE(left, 0.0f, 0.0f, 0.0f, 1.0f); + DRAW_SIDE(top, 0.0f, 0.0f, 1.0f, 0.0f); + DRAW_SIDE(right, 1.0f, 0.0f, 1.0f, 1.0f); DRAW_SIDE(bottom, 0.0f, 1.0f, 1.0f, 1.0f); #undef DRAW_SIDE } else { @@ -1516,13 +1788,51 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene, return true; } +bool OBSBasicPreview::DrawSelectionBox(float x1, float y1, float x2, float y2, + gs_vertbuffer_t *rectFill) +{ + x1 = std::round(x1); + x2 = std::round(x2); + y1 = std::round(y1); + y2 = std::round(y2); + + gs_effect_t *eff = gs_get_effect(); + gs_eparam_t *colParam = gs_effect_get_param_by_name(eff, "color"); + + vec4 fillColor; + vec4_set(&fillColor, 0.7f, 0.7f, 0.7f, 0.5f); + + vec4 borderColor; + vec4_set(&borderColor, 1.0f, 1.0f, 1.0f, 1.0f); + + vec2 scale; + vec2_set(&scale, std::abs(x2 - x1), std::abs(y2 - y1)); + + gs_matrix_push(); + gs_matrix_identity(); + + gs_matrix_translate3f(x1, y1, 0.0f); + gs_matrix_scale3f(x2 - x1, y2 - y1, 1.0f); + + gs_effect_set_vec4(colParam, &fillColor); + gs_load_vertexbuffer(rectFill); + gs_draw(GS_TRISTRIP, 0, 0); + + gs_effect_set_vec4(colParam, &borderColor); + DrawRect(HANDLE_RADIUS / 2, scale); + + gs_matrix_pop(); + + return true; +} + void OBSBasicPreview::DrawOverflow() { if (locked) return; bool hidden = config_get_bool(GetGlobalConfig(), "BasicWindow", - "OverflowHidden"); + "OverflowHidden"); if (hidden) return; @@ -1535,7 +1845,7 @@ void OBSBasicPreview::DrawOverflow() overflow = gs_texture_create_from_file(path.c_str()); } - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); @@ -1558,10 +1868,10 @@ void OBSBasicPreview::DrawSceneEditing() GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "DrawSceneEditing"); - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); - gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID); - gs_technique_t *tech = gs_effect_get_technique(solid, "Solid"); + gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID); + gs_technique_t *tech = gs_effect_get_technique(solid, "Solid"); vec4 color; vec4_set(&color, 1.0f, 0.0f, 0.0f, 1.0f); @@ -1579,6 +1889,26 @@ void OBSBasicPreview::DrawSceneEditing() gs_matrix_pop(); } + if (selectionBox) { + if (!rectFill) { + gs_render_start(true); + + gs_vertex2f(0.0f, 0.0f); + gs_vertex2f(1.0f, 0.0f); + gs_vertex2f(1.0f, 1.0f); + gs_vertex2f(1.0f, 1.0f); + gs_vertex2f(0.0f, 0.0f); + gs_vertex2f(0.0f, 1.0f); + + rectFill = gs_render_save(); + } + + DrawSelectionBox(startPos.x * main->previewScale, + startPos.y * main->previewScale, + mousePos.x * main->previewScale, + mousePos.y * main->previewScale, rectFill); + } + gs_load_vertexbuffer(nullptr); gs_technique_end_pass(tech); @@ -1592,13 +1922,16 @@ void OBSBasicPreview::ResetScrollingOffset() vec2_zero(&scrollingOffset); } -void OBSBasicPreview::SetScalingLevel(int32_t newScalingLevelVal) { - float newScalingAmountVal = pow(ZOOM_SENSITIVITY, float(newScalingLevelVal)); +void OBSBasicPreview::SetScalingLevel(int32_t newScalingLevelVal) +{ + float newScalingAmountVal = + pow(ZOOM_SENSITIVITY, float(newScalingLevelVal)); scalingLevel = newScalingLevelVal; SetScalingAmount(newScalingAmountVal); } -void OBSBasicPreview::SetScalingAmount(float newScalingAmountVal) { +void OBSBasicPreview::SetScalingAmount(float newScalingAmountVal) +{ scrollingOffset.x *= newScalingAmountVal / scalingAmount; scrollingOffset.y *= newScalingAmountVal / scalingAmount; scalingAmount = newScalingAmountVal; diff --git a/UI/window-basic-preview.hpp b/UI/window-basic-preview.hpp index e285456..2473f62 100644 --- a/UI/window-basic-preview.hpp +++ b/UI/window-basic-preview.hpp @@ -3,72 +3,84 @@ #include #include #include +#include +#include +#include #include "qt-display.hpp" #include "obs-app.hpp" class OBSBasic; class QMouseEvent; -#define ITEM_LEFT (1<<0) -#define ITEM_RIGHT (1<<1) -#define ITEM_TOP (1<<2) -#define ITEM_BOTTOM (1<<3) +#define ITEM_LEFT (1 << 0) +#define ITEM_RIGHT (1 << 1) +#define ITEM_TOP (1 << 2) +#define ITEM_BOTTOM (1 << 3) #define ZOOM_SENSITIVITY 1.125f enum class ItemHandle : uint32_t { - None = 0, - TopLeft = ITEM_TOP | ITEM_LEFT, - TopCenter = ITEM_TOP, - TopRight = ITEM_TOP | ITEM_RIGHT, - CenterLeft = ITEM_LEFT, - CenterRight = ITEM_RIGHT, - BottomLeft = ITEM_BOTTOM | ITEM_LEFT, + None = 0, + TopLeft = ITEM_TOP | ITEM_LEFT, + TopCenter = ITEM_TOP, + TopRight = ITEM_TOP | ITEM_RIGHT, + CenterLeft = ITEM_LEFT, + CenterRight = ITEM_RIGHT, + BottomLeft = ITEM_BOTTOM | ITEM_LEFT, BottomCenter = ITEM_BOTTOM, - BottomRight = ITEM_BOTTOM | ITEM_RIGHT + BottomRight = ITEM_BOTTOM | ITEM_RIGHT, }; class OBSBasicPreview : public OBSQTDisplay { Q_OBJECT friend class SourceTree; + friend class SourceTreeItem; private: obs_sceneitem_crop startCrop; - vec2 startItemPos; - vec2 cropSize; + vec2 startItemPos; + vec2 cropSize; OBSSceneItem stretchGroup; OBSSceneItem stretchItem; - ItemHandle stretchHandle = ItemHandle::None; - vec2 stretchItemSize; - matrix4 screenToItem; - matrix4 itemToScreen; - matrix4 invGroupTransform; + ItemHandle stretchHandle = ItemHandle::None; + vec2 stretchItemSize; + matrix4 screenToItem; + matrix4 itemToScreen; + matrix4 invGroupTransform; gs_texture_t *overflow = nullptr; + gs_vertbuffer_t *rectFill = nullptr; - vec2 startPos; - vec2 lastMoveOffset; - vec2 scrollingFrom; - vec2 scrollingOffset; - bool mouseDown = false; - bool mouseMoved = false; - bool mouseOverItems = false; - bool cropping = false; - bool locked = false; - bool scrollMode = false; - bool fixedScaling = false; - int32_t scalingLevel = 0; - float scalingAmount = 1.0f; + vec2 startPos; + vec2 mousePos; + vec2 lastMoveOffset; + vec2 scrollingFrom; + vec2 scrollingOffset; + bool mouseDown = false; + bool mouseMoved = false; + bool mouseOverItems = false; + bool cropping = false; + bool locked = false; + bool scrollMode = false; + bool fixedScaling = false; + bool selectionBox = false; + int32_t scalingLevel = 0; + float scalingAmount = 1.0f; - obs_sceneitem_t *hoveredPreviewItem = nullptr; - obs_sceneitem_t *hoveredListItem = nullptr; + std::vector hoveredPreviewItems; + std::vector selectedItems; + std::mutex selectMutex; static vec2 GetMouseEventPos(QMouseEvent *event); + static bool FindSelected(obs_scene_t *scene, obs_sceneitem_t *item, + void *param); static bool DrawSelectedOverflow(obs_scene_t *scene, - obs_sceneitem_t *item, void *param); + obs_sceneitem_t *item, void *param); static bool DrawSelectedItem(obs_scene_t *scene, obs_sceneitem_t *item, - void *param); + void *param); + static bool DrawSelectionBox(float x1, float y1, float x2, float y2, + gs_vertbuffer_t *box); static OBSSceneItem GetItemAtPos(const vec2 &pos, bool selectBelow); static bool SelectedAtPos(const vec2 &pos); @@ -88,6 +100,7 @@ private: static void SnapItemMovement(vec2 &offset); void MoveItems(const vec2 &pos); + void BoxItems(const vec2 &startPos, const vec2 &pos); void ProcessClick(const vec2 &pos); @@ -110,11 +123,14 @@ public: void DrawOverflow(); void DrawSceneEditing(); - inline void SetLocked(bool newLockedVal) {locked = newLockedVal;} - inline void ToggleLocked() {locked = !locked;} - inline bool Locked() const {return locked;} + inline void SetLocked(bool newLockedVal) { locked = newLockedVal; } + inline void ToggleLocked() { locked = !locked; } + inline bool Locked() const { return locked; } - inline void SetFixedScaling(bool newFixedScalingVal) { fixedScaling = newFixedScalingVal; } + inline void SetFixedScaling(bool newFixedScalingVal) + { + fixedScaling = newFixedScalingVal; + } inline bool IsFixedScaling() const { return fixedScaling; } void SetScalingLevel(int32_t newScalingLevelVal); @@ -123,14 +139,17 @@ public: inline float GetScalingAmount() const { return scalingAmount; } void ResetScrollingOffset(); - inline void SetScrollingOffset(float x, float y) {vec2_set(&scrollingOffset, x, y);} - inline float GetScrollX() const {return scrollingOffset.x;} - inline float GetScrollY() const {return scrollingOffset.y;} + inline void SetScrollingOffset(float x, float y) + { + vec2_set(&scrollingOffset, x, y); + } + inline float GetScrollX() const { return scrollingOffset.x; } + inline float GetScrollY() const { return scrollingOffset.y; } /* use libobs allocator for alignment because the matrices itemToScreen * and screenToItem may contain SSE data, which will cause SSE * instructions to crash if the data is not aligned to at least a 16 * byte boundary. */ - static inline void* operator new(size_t size) {return bmalloc(size);} - static inline void operator delete(void* ptr) {bfree(ptr);} + static inline void *operator new(size_t size) { return bmalloc(size); } + static inline void operator delete(void *ptr) { bfree(ptr); } }; diff --git a/UI/window-basic-properties.cpp b/UI/window-basic-properties.cpp index 3864abd..689534d 100644 --- a/UI/window-basic-properties.cpp +++ b/UI/window-basic-properties.cpp @@ -29,39 +29,38 @@ using namespace std; -static void CreateTransitionScene(OBSSource scene, char *text, uint32_t color); +static void CreateTransitionScene(OBSSource scene, const char *text, + uint32_t color); OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_) - : QDialog (parent), - preview (new OBSQTDisplay(this)), - main (qobject_cast(parent)), - acceptClicked (false), - source (source_), - removedSignal (obs_source_get_signal_handler(source), - "remove", OBSBasicProperties::SourceRemoved, - this), - renamedSignal (obs_source_get_signal_handler(source), - "rename", OBSBasicProperties::SourceRenamed, - this), - oldSettings (obs_data_create()), - buttonBox (new QDialogButtonBox(this)) + : QDialog(parent), + preview(new OBSQTDisplay(this)), + main(qobject_cast(parent)), + acceptClicked(false), + source(source_), + removedSignal(obs_source_get_signal_handler(source), "remove", + OBSBasicProperties::SourceRemoved, this), + renamedSignal(obs_source_get_signal_handler(source), "rename", + OBSBasicProperties::SourceRenamed, this), + oldSettings(obs_data_create()), + buttonBox(new QDialogButtonBox(this)) { int cx = (int)config_get_int(App()->GlobalConfig(), "PropertiesWindow", - "cx"); + "cx"); int cy = (int)config_get_int(App()->GlobalConfig(), "PropertiesWindow", - "cy"); + "cy"); enum obs_source_type type = obs_source_get_type(source); buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setStandardButtons(QDialogButtonBox::Ok | - QDialogButtonBox::Cancel | - QDialogButtonBox::RestoreDefaults); + QDialogButtonBox::Cancel | + QDialogButtonBox::RestoreDefaults); buttonBox->button(QDialogButtonBox::Ok)->setText(QTStr("OK")); buttonBox->button(QDialogButtonBox::Cancel)->setText(QTStr("Cancel")); - buttonBox->button(QDialogButtonBox::RestoreDefaults)-> - setText(QTStr("Defaults")); + buttonBox->button(QDialogButtonBox::RestoreDefaults) + ->setText(QTStr("Defaults")); if (cx > 400 && cy > 400) resize(cx, cy); @@ -79,14 +78,15 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_) obs_data_apply(oldSettings, settings); obs_data_release(settings); - view = new OBSPropertiesView(settings, source, - (PropertiesReloadCallback)obs_source_properties, - (PropertiesUpdateCallback)obs_source_update); + view = new OBSPropertiesView( + settings, source, + (PropertiesReloadCallback)obs_source_properties, + (PropertiesUpdateCallback)obs_source_update); view->setMinimumHeight(150); preview->setMinimumSize(20, 150); - preview->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, - QSizePolicy::Expanding)); + preview->setSizePolicy( + QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); // Create a QSplitter to keep a unified workflow here. windowSplitter = new QSplitter(Qt::Orientation::Vertical, this); @@ -102,8 +102,8 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_) if (type == OBS_SOURCE_TYPE_TRANSITION) { AddPreviewButton(); - connect(view, SIGNAL(PropertiesRefreshed()), - this, SLOT(AddPreviewButton())); + connect(view, SIGNAL(PropertiesRefreshed()), this, + SLOT(AddPreviewButton())); } layout()->addWidget(buttonBox); @@ -118,35 +118,35 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_) obs_source_inc_showing(source); updatePropertiesSignal.Connect(obs_source_get_signal_handler(source), - "update_properties", - OBSBasicProperties::UpdateProperties, - this); + "update_properties", + OBSBasicProperties::UpdateProperties, + this); - auto addDrawCallback = [this] () - { + auto addDrawCallback = [this]() { obs_display_add_draw_callback(preview->GetDisplay(), - OBSBasicProperties::DrawPreview, this); + OBSBasicProperties::DrawPreview, + this); }; - auto addTransitionDrawCallback = [this] () - { - obs_display_add_draw_callback(preview->GetDisplay(), + auto addTransitionDrawCallback = [this]() { + obs_display_add_draw_callback( + preview->GetDisplay(), OBSBasicProperties::DrawTransitionPreview, this); }; uint32_t caps = obs_source_get_output_flags(source); bool drawable_type = type == OBS_SOURCE_TYPE_INPUT || - type == OBS_SOURCE_TYPE_SCENE; + type == OBS_SOURCE_TYPE_SCENE; bool drawable_preview = (caps & OBS_SOURCE_VIDEO) != 0; if (drawable_preview && drawable_type) { preview->show(); connect(preview.data(), &OBSQTDisplay::DisplayCreated, - addDrawCallback); + addDrawCallback); } else if (type == OBS_SOURCE_TYPE_TRANSITION) { - sourceA = obs_source_create_private("scene", "sourceA", - nullptr); - sourceB = obs_source_create_private("scene", "sourceB", - nullptr); + sourceA = + obs_source_create_private("scene", "sourceA", nullptr); + sourceB = + obs_source_create_private("scene", "sourceB", nullptr); obs_source_release(sourceA); obs_source_release(sourceB); @@ -166,7 +166,7 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_) obs_data_t *settings = obs_source_get_settings(source); sourceClone = obs_source_create_private( - obs_source_get_id(source), "clone", settings); + obs_source_get_id(source), "clone", settings); obs_source_release(sourceClone); obs_source_inc_active(sourceClone); @@ -174,8 +174,7 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_) obs_data_release(settings); - auto updateCallback = [=]() - { + auto updateCallback = [=]() { obs_data_t *settings = obs_source_get_settings(source); obs_source_update(sourceClone, settings); @@ -210,15 +209,14 @@ OBSBasicProperties::~OBSBasicProperties() void OBSBasicProperties::AddPreviewButton() { - QPushButton *playButton = new QPushButton( - QTStr("PreviewTransition"), this); + QPushButton *playButton = + new QPushButton(QTStr("PreviewTransition"), this); VScrollArea *area = view; area->widget()->layout()->addWidget(playButton); playButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - auto play = [=] () - { + auto play = [=]() { OBSSource start; OBSSource end; @@ -231,9 +229,8 @@ void OBSBasicProperties::AddPreviewButton() } obs_transition_set(sourceClone, start); - obs_transition_start(sourceClone, - OBS_TRANSITION_MODE_AUTO, - main->GetTransitionDuration(), end); + obs_transition_start(sourceClone, OBS_TRANSITION_MODE_AUTO, + main->GetTransitionDuration(), end); direction = !direction; start = nullptr; @@ -273,8 +270,8 @@ static obs_source_t *CreateLabel(const char *name, size_t h) const char *text_source_id = "text_ft2_source"; #endif - obs_source_t *txtSource = obs_source_create_private(text_source_id, - name, settings); + obs_source_t *txtSource = + obs_source_create_private(text_source_id, name, settings); obs_data_release(font); obs_data_release(settings); @@ -282,28 +279,29 @@ static obs_source_t *CreateLabel(const char *name, size_t h) return txtSource; } -static void CreateTransitionScene(OBSSource scene, char *text, uint32_t color) +static void CreateTransitionScene(OBSSource scene, const char *text, + uint32_t color) { obs_data_t *settings = obs_data_create(); obs_data_set_int(settings, "width", obs_source_get_width(scene)); obs_data_set_int(settings, "height", obs_source_get_height(scene)); obs_data_set_int(settings, "color", color); - obs_source_t *colorBG = obs_source_create_private("color_source", - "background", settings); + obs_source_t *colorBG = obs_source_create_private( + "color_source", "background", settings); obs_scene_add(obs_scene_from_source(scene), colorBG); obs_source_t *label = CreateLabel(text, obs_source_get_height(scene)); - obs_sceneitem_t *item = obs_scene_add(obs_scene_from_source(scene), - label); + obs_sceneitem_t *item = + obs_scene_add(obs_scene_from_source(scene), label); vec2 size; vec2_set(&size, obs_source_get_width(scene), #ifdef _WIN32 - obs_source_get_height(scene)); + obs_source_get_height(scene)); #else - obs_source_get_height(scene) * 0.8); + obs_source_get_height(scene) * 0.8); #endif obs_sceneitem_set_bounds(item, &size); @@ -316,8 +314,8 @@ static void CreateTransitionScene(OBSSource scene, char *text, uint32_t color) void OBSBasicProperties::SourceRemoved(void *data, calldata_t *params) { - QMetaObject::invokeMethod(static_cast(data), - "close"); + QMetaObject::invokeMethod(static_cast(data), + "close"); UNUSED_PARAMETER(params); } @@ -327,14 +325,14 @@ void OBSBasicProperties::SourceRenamed(void *data, calldata_t *params) const char *name = calldata_string(params, "new_name"); QString title = QTStr("Basic.PropertiesWindow").arg(QT_UTF8(name)); - QMetaObject::invokeMethod(static_cast(data), - "setWindowTitle", Q_ARG(QString, title)); + QMetaObject::invokeMethod(static_cast(data), + "setWindowTitle", Q_ARG(QString, title)); } void OBSBasicProperties::UpdateProperties(void *data, calldata_t *) { - QMetaObject::invokeMethod(static_cast(data)->view, - "ReloadProperties"); + QMetaObject::invokeMethod(static_cast(data)->view, + "ReloadProperties"); } void OBSBasicProperties::on_buttonBox_clicked(QAbstractButton *button) @@ -374,7 +372,7 @@ void OBSBasicProperties::on_buttonBox_clicked(QAbstractButton *button) void OBSBasicProperties::DrawPreview(void *data, uint32_t cx, uint32_t cy) { - OBSBasicProperties *window = static_cast(data); + OBSBasicProperties *window = static_cast(data); if (!window->source) return; @@ -382,8 +380,8 @@ void OBSBasicProperties::DrawPreview(void *data, uint32_t cx, uint32_t cy) uint32_t sourceCX = max(obs_source_get_width(window->source), 1u); uint32_t sourceCY = max(obs_source_get_height(window->source), 1u); - int x, y; - int newCX, newCY; + int x, y; + int newCX, newCY; float scale; GetScaleAndCenterPos(sourceCX, sourceCY, cx, cy, x, y, scale); @@ -393,8 +391,7 @@ void OBSBasicProperties::DrawPreview(void *data, uint32_t cx, uint32_t cy) gs_viewport_push(); gs_projection_push(); - gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY), - -100.0f, 100.0f); + gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY), -100.0f, 100.0f); gs_set_viewport(x, y, newCX, newCY); obs_source_video_render(window->source); @@ -404,9 +401,9 @@ void OBSBasicProperties::DrawPreview(void *data, uint32_t cx, uint32_t cy) } void OBSBasicProperties::DrawTransitionPreview(void *data, uint32_t cx, - uint32_t cy) + uint32_t cy) { - OBSBasicProperties *window = static_cast(data); + OBSBasicProperties *window = static_cast(data); if (!window->source) return; @@ -414,8 +411,8 @@ void OBSBasicProperties::DrawTransitionPreview(void *data, uint32_t cx, uint32_t sourceCX = max(obs_source_get_width(window->source), 1u); uint32_t sourceCY = max(obs_source_get_height(window->source), 1u); - int x, y; - int newCX, newCY; + int x, y; + int newCX, newCY; float scale; GetScaleAndCenterPos(sourceCX, sourceCY, cx, cy, x, y, scale); @@ -425,8 +422,7 @@ void OBSBasicProperties::DrawTransitionPreview(void *data, uint32_t cx, gs_viewport_push(); gs_projection_push(); - gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY), - -100.0f, 100.0f); + gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY), -100.0f, 100.0f); gs_set_viewport(x, y, newCX, newCY); obs_source_video_render(window->sourceClone); @@ -438,13 +434,14 @@ void OBSBasicProperties::DrawTransitionPreview(void *data, uint32_t cx, void OBSBasicProperties::Cleanup() { config_set_int(App()->GlobalConfig(), "PropertiesWindow", "cx", - width()); + width()); config_set_int(App()->GlobalConfig(), "PropertiesWindow", "cy", - height()); + height()); obs_display_remove_draw_callback(preview->GetDisplay(), - OBSBasicProperties::DrawPreview, this); - obs_display_remove_draw_callback(preview->GetDisplay(), + OBSBasicProperties::DrawPreview, this); + obs_display_remove_draw_callback( + preview->GetDisplay(), OBSBasicProperties::DrawTransitionPreview, this); } @@ -497,11 +494,10 @@ bool OBSBasicProperties::ConfirmQuit() { QMessageBox::StandardButton button; - button = OBSMessageBox::question(this, - QTStr("Basic.PropertiesWindow.ConfirmTitle"), - QTStr("Basic.PropertiesWindow.Confirm"), - QMessageBox::Save | QMessageBox::Discard | - QMessageBox::Cancel); + button = OBSMessageBox::question( + this, QTStr("Basic.PropertiesWindow.ConfirmTitle"), + QTStr("Basic.PropertiesWindow.Confirm"), + QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); switch (button) { case QMessageBox::Save: diff --git a/UI/window-basic-properties.hpp b/UI/window-basic-properties.hpp index 69a9771..3f64cdd 100644 --- a/UI/window-basic-properties.hpp +++ b/UI/window-basic-properties.hpp @@ -33,32 +33,31 @@ class OBSBasicProperties : public QDialog { private: QPointer preview; - OBSBasic *main; - bool acceptClicked; + OBSBasic *main; + bool acceptClicked; - OBSSource source; - OBSSignal removedSignal; - OBSSignal renamedSignal; - OBSSignal updatePropertiesSignal; - OBSData oldSettings; + OBSSource source; + OBSSignal removedSignal; + OBSSignal renamedSignal; + OBSSignal updatePropertiesSignal; + OBSData oldSettings; OBSPropertiesView *view; QDialogButtonBox *buttonBox; QSplitter *windowSplitter; - OBSSource sourceA; - OBSSource sourceB; - OBSSource sourceClone; - bool direction = true; + OBSSource sourceA; + OBSSource sourceB; + OBSSource sourceClone; + bool direction = true; static void SourceRemoved(void *data, calldata_t *params); static void SourceRenamed(void *data, calldata_t *params); static void UpdateProperties(void *data, calldata_t *params); static void DrawPreview(void *data, uint32_t cx, uint32_t cy); - static void DrawTransitionPreview(void *data, uint32_t cx, - uint32_t cy); + static void DrawTransitionPreview(void *data, uint32_t cx, uint32_t cy); void UpdateCallback(void *obj, obs_data_t *settings); bool ConfirmQuit(); - int CheckSettings(); + int CheckSettings(); void Cleanup(); private slots: diff --git a/UI/window-basic-settings-stream.cpp b/UI/window-basic-settings-stream.cpp index 6986244..f095084 100644 --- a/UI/window-basic-settings-stream.cpp +++ b/UI/window-basic-settings-stream.cpp @@ -14,7 +14,7 @@ struct QCef; struct QCefCookieManager; -extern QCef *cef; +extern QCef *cef; extern QCefCookieManager *panel_cookies; enum class ListOpt : int { @@ -54,10 +54,10 @@ void OBSBasicSettings::InitStreamPage() LoadServices(false); - connect(ui->service, SIGNAL(currentIndexChanged(int)), - this, SLOT(UpdateServerList())); - connect(ui->service, SIGNAL(currentIndexChanged(int)), - this, SLOT(UpdateKeyLink())); + connect(ui->service, SIGNAL(currentIndexChanged(int)), this, + SLOT(UpdateServerList())); + connect(ui->service, SIGNAL(currentIndexChanged(int)), this, + SLOT(UpdateKeyLink())); } void OBSBasicSettings::LoadStream1Settings() @@ -78,8 +78,10 @@ void OBSBasicSettings::LoadStream1Settings() ui->customServer->setText(server); bool use_auth = obs_data_get_bool(settings, "use_auth"); - const char *username = obs_data_get_string(settings, "username"); - const char *password = obs_data_get_string(settings, "password"); + const char *username = + obs_data_get_string(settings, "username"); + const char *password = + obs_data_get_string(settings, "password"); ui->authUsername->setText(QT_UTF8(username)); ui->authPw->setText(QT_UTF8(password)); ui->useAuth->setChecked(use_auth); @@ -126,9 +128,7 @@ void OBSBasicSettings::LoadStream1Settings() void OBSBasicSettings::SaveStream1Settings() { bool customServer = IsCustomService(); - const char *service_id = customServer - ? "rtmp_custom" - : "rtmp_common"; + const char *service_id = customServer ? "rtmp_custom" : "rtmp_common"; obs_service_t *oldService = main->GetService(); OBSData hotkeyData = obs_hotkeys_save_service(oldService); @@ -139,27 +139,30 @@ void OBSBasicSettings::SaveStream1Settings() if (!customServer) { obs_data_set_string(settings, "service", - QT_TO_UTF8(ui->service->currentText())); - obs_data_set_string(settings, "server", - QT_TO_UTF8(ui->server->currentData().toString())); + QT_TO_UTF8(ui->service->currentText())); + obs_data_set_string( + settings, "server", + QT_TO_UTF8(ui->server->currentData().toString())); } else { obs_data_set_string(settings, "server", - QT_TO_UTF8(ui->customServer->text())); + QT_TO_UTF8(ui->customServer->text())); obs_data_set_bool(settings, "use_auth", - ui->useAuth->isChecked()); + ui->useAuth->isChecked()); if (ui->useAuth->isChecked()) { - obs_data_set_string(settings, "username", - QT_TO_UTF8(ui->authUsername->text())); + obs_data_set_string( + settings, "username", + QT_TO_UTF8(ui->authUsername->text())); obs_data_set_string(settings, "password", - QT_TO_UTF8(ui->authPw->text())); + QT_TO_UTF8(ui->authPw->text())); } } - obs_data_set_bool(settings, "bwtest", ui->bandwidthTestEnable->isChecked()); + obs_data_set_bool(settings, "bwtest", + ui->bandwidthTestEnable->isChecked()); obs_data_set_string(settings, "key", QT_TO_UTF8(ui->key->text())); - OBSService newService = obs_service_create(service_id, - "default_service", settings, hotkeyData); + OBSService newService = obs_service_create( + service_id, "default_service", settings, hotkeyData); obs_service_release(newService); if (!newService) @@ -185,13 +188,29 @@ void OBSBasicSettings::UpdateKeyLink() text += " "; - text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite"); + text += QTStr( + "Basic.AutoConfig.StreamPage.StreamKey.LinkToSite"); text += ""; } else if (serviceName == "YouTube / YouTube Gaming") { text += " "; - text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite"); + text += QTStr( + "Basic.AutoConfig.StreamPage.StreamKey.LinkToSite"); + text += ""; + } else if (serviceName.startsWith("Restream.io")) { + text += " "; + text += QTStr( + "Basic.AutoConfig.StreamPage.StreamKey.LinkToSite"); + text += ""; + } else if (serviceName == "Facebook Live") { + text += " "; + text += QTStr( + "Basic.AutoConfig.StreamPage.StreamKey.LinkToSite"); text += ""; } @@ -234,9 +253,9 @@ void OBSBasicSettings::LoadServices(bool showAll) QVariant((int)ListOpt::ShowAll)); } - ui->service->insertItem(0, - QTStr("Basic.AutoConfig.StreamPage.Service.Custom"), - QVariant((int)ListOpt::Custom)); + ui->service->insertItem( + 0, QTStr("Basic.AutoConfig.StreamPage.Service.Custom"), + QVariant((int)ListOpt::Custom)); if (!lastService.isEmpty()) { int idx = ui->service->findText(lastService); @@ -256,8 +275,8 @@ static inline bool is_auth_service(const std::string &service) void OBSBasicSettings::on_service_currentIndexChanged(int) { - bool showMore = - ui->service->currentData().toInt() == (int)ListOpt::ShowAll; + bool showMore = ui->service->currentData().toInt() == + (int)ListOpt::ShowAll; if (showMore) return; @@ -273,8 +292,8 @@ void OBSBasicSettings::on_service_currentIndexChanged(int) QString key = ui->key->text(); bool can_auth = is_auth_service(service); int page = can_auth && (!loading || key.isEmpty()) - ? (int)Section::Connect - : (int)Section::StreamKey; + ? (int)Section::Connect + : (int)Section::StreamKey; ui->streamStackWidget->setCurrentIndex(page); ui->streamKeyWidget->setVisible(true); @@ -296,7 +315,7 @@ void OBSBasicSettings::on_service_currentIndexChanged(int) if (custom) { ui->streamkeyPageLayout->insertRow(1, ui->serverLabel, - ui->serverStackedWidget); + ui->serverStackedWidget); ui->serverStackedWidget->setCurrentIndex(1); ui->serverStackedWidget->setVisible(true); @@ -320,8 +339,8 @@ void OBSBasicSettings::on_service_currentIndexChanged(int) void OBSBasicSettings::UpdateServerList() { QString serviceName = ui->service->currentText(); - bool showMore = - ui->service->currentData().toInt() == (int)ListOpt::ShowAll; + bool showMore = ui->service->currentData().toInt() == + (int)ListOpt::ShowAll; if (showMore) { LoadServices(true); @@ -386,17 +405,18 @@ OBSService OBSBasicSettings::SpawnTempService() if (!custom) { obs_data_set_string(settings, "service", - QT_TO_UTF8(ui->service->currentText())); - obs_data_set_string(settings, "server", - QT_TO_UTF8(ui->server->currentData().toString())); + QT_TO_UTF8(ui->service->currentText())); + obs_data_set_string( + settings, "server", + QT_TO_UTF8(ui->server->currentData().toString())); } else { obs_data_set_string(settings, "server", - QT_TO_UTF8(ui->customServer->text())); + QT_TO_UTF8(ui->customServer->text())); } obs_data_set_string(settings, "key", QT_TO_UTF8(ui->key->text())); - OBSService newService = obs_service_create(service_id, - "temp_service", settings, nullptr); + OBSService newService = obs_service_create(service_id, "temp_service", + settings, nullptr); obs_service_release(newService); return newService; @@ -405,7 +425,7 @@ OBSService OBSBasicSettings::SpawnTempService() void OBSBasicSettings::OnOAuthStreamKeyConnected() { #ifdef BROWSER_AVAILABLE - OAuthStreamKey *a = reinterpret_cast(auth.get()); + OAuthStreamKey *a = reinterpret_cast(auth.get()); if (a) { bool validKey = !a->key().empty(); @@ -461,9 +481,8 @@ void OBSBasicSettings::on_disconnectAccount_clicked() { QMessageBox::StandardButton button; - button = OBSMessageBox::question(this, - QTStr(DISCONNECT_COMFIRM_TITLE), - QTStr(DISCONNECT_COMFIRM_TEXT)); + button = OBSMessageBox::question(this, QTStr(DISCONNECT_COMFIRM_TITLE), + QTStr(DISCONNECT_COMFIRM_TEXT)); if (button == QMessageBox::No) { return; diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp index b66f65e..4d10e72 100644 --- a/UI/window-basic-settings.cpp +++ b/UI/window-basic-settings.cpp @@ -65,8 +65,10 @@ struct FormatDesc { inline FormatDesc() = default; inline FormatDesc(const char *name, const char *mimeType, - const ff_format_desc *desc = nullptr) - : name(name), mimeType(mimeType), desc(desc) {} + const ff_format_desc *desc = nullptr) + : name(name), mimeType(mimeType), desc(desc) + { + } bool operator==(const FormatDesc &f) const { @@ -154,12 +156,12 @@ static inline bool SetComboByValue(QComboBox *combo, const char *name) } static inline bool SetInvalidValue(QComboBox *combo, const char *name, - const char *data = nullptr) + const char *data = nullptr) { combo->insertItem(0, name, data); QStandardItemModel *model = - dynamic_cast(combo->model()); + dynamic_cast(combo->model()); if (!model) return false; @@ -182,7 +184,7 @@ static inline QString GetComboData(QComboBox *combo) static int FindEncoder(QComboBox *combo, const char *name, int id) { CodecDesc codecDesc(name, id); - for(int i = 0; i < combo->count(); i++) { + for (int i = 0; i < combo->count(); i++) { QVariant v = combo->itemData(i); if (!v.isNull()) { if (codecDesc == v.value()) { @@ -195,7 +197,7 @@ static int FindEncoder(QComboBox *combo, const char *name, int id) } static CodecDesc GetDefaultCodecDesc(const ff_format_desc *formatDesc, - ff_codec_type codecType) + ff_codec_type codecType) { int id = 0; switch (codecType) { @@ -210,7 +212,7 @@ static CodecDesc GetDefaultCodecDesc(const ff_format_desc *formatDesc, } return CodecDesc(ff_format_desc_get_default_name(formatDesc, codecType), - id); + id); } #ifdef _WIN32 @@ -220,7 +222,7 @@ void OBSBasicSettings::ToggleDisableAero(bool checked) } #endif -static void PopulateAACBitrates(initializer_list boxes) +static void PopulateAACBitrates(initializer_list boxes) { auto &bitrateMap = GetAACEncoderBitrateMap(); if (bitrateMap.empty()) @@ -229,7 +231,7 @@ static void PopulateAACBitrates(initializer_list boxes) vector> pairs; for (auto &entry : bitrateMap) pairs.emplace_back(QString::number(entry.first), - obs_encoder_get_display_name(entry.second)); + obs_encoder_get_display_name(entry.second)); for (auto box : boxes) { QString currentText = box->currentText(); @@ -238,23 +240,23 @@ static void PopulateAACBitrates(initializer_list boxes) for (auto &pair : pairs) { box->addItem(pair.first); box->setItemData(box->count() - 1, pair.second, - Qt::ToolTipRole); + Qt::ToolTipRole); } box->setCurrentText(currentText); } } -void RestrictResetBitrates(initializer_list boxes, - int maxbitrate); +void RestrictResetBitrates(initializer_list boxes, int maxbitrate); void OBSBasicSettings::HookWidget(QWidget *widget, const char *signal, - const char *slot) + const char *slot) { QObject::connect(widget, signal, this, slot); widget->setProperty("changed", QVariant(false)); } +/* clang-format off */ #define COMBO_CHANGED SIGNAL(currentIndexChanged(int)) #define EDIT_CHANGED SIGNAL(textChanged(const QString &)) #define CBEDIT_CHANGED SIGNAL(editTextChanged(const QString &)) @@ -273,11 +275,12 @@ void OBSBasicSettings::HookWidget(QWidget *widget, const char *signal, #define VIDEO_CHANGED SLOT(VideoChanged()) #define ADV_CHANGED SLOT(AdvancedChanged()) #define ADV_RESTART SLOT(AdvancedChangedRestart()) +/* clang-format on */ OBSBasicSettings::OBSBasicSettings(QWidget *parent) - : QDialog (parent), - main (qobject_cast(parent)), - ui (new Ui::OBSBasicSettings) + : QDialog(parent), + main(qobject_cast(parent)), + ui(new Ui::OBSBasicSettings) { string path; @@ -289,19 +292,21 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) main->EnableOutputs(false); - PopulateAACBitrates({ui->simpleOutputABitrate, - ui->advOutTrack1Bitrate, ui->advOutTrack2Bitrate, - ui->advOutTrack3Bitrate, ui->advOutTrack4Bitrate, - ui->advOutTrack5Bitrate, ui->advOutTrack6Bitrate}); + PopulateAACBitrates({ui->simpleOutputABitrate, ui->advOutTrack1Bitrate, + ui->advOutTrack2Bitrate, ui->advOutTrack3Bitrate, + ui->advOutTrack4Bitrate, ui->advOutTrack5Bitrate, + ui->advOutTrack6Bitrate}); ui->listWidget->setAttribute(Qt::WA_MacShowFocusRect, false); + /* clang-format off */ HookWidget(ui->language, COMBO_CHANGED, GENERAL_CHANGED); HookWidget(ui->theme, COMBO_CHANGED, GENERAL_CHANGED); HookWidget(ui->enableAutoUpdates, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->openStatsOnStartup, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->warnBeforeStreamStart,CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->warnBeforeStreamStop, CHECK_CHANGED, GENERAL_CHANGED); + HookWidget(ui->warnBeforeRecordStop, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->hideProjectorCursor, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->projectorAlwaysOnTop, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->recordWhenStreaming, CHECK_CHANGED, GENERAL_CHANGED); @@ -459,8 +464,20 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) HookWidget(ui->bindToIP, COMBO_CHANGED, ADV_CHANGED); HookWidget(ui->enableNewSocketLoop, CHECK_CHANGED, ADV_CHANGED); HookWidget(ui->enableLowLatencyMode, CHECK_CHANGED, ADV_CHANGED); - HookWidget(ui->disableFocusHotkeys, CHECK_CHANGED, ADV_CHANGED); + HookWidget(ui->hotkeyFocusType, COMBO_CHANGED, ADV_CHANGED); HookWidget(ui->autoRemux, CHECK_CHANGED, ADV_CHANGED); + HookWidget(ui->dynBitrate, CHECK_CHANGED, ADV_CHANGED); + /* clang-format on */ + +#define ADD_HOTKEY_FOCUS_TYPE(s) \ + ui->hotkeyFocusType->addItem( \ + QTStr("Basic.Settings.Advanced.Hotkeys." s), s) + + ADD_HOTKEY_FOCUS_TYPE("NeverDisableHotkeys"); + ADD_HOTKEY_FOCUS_TYPE("DisableHotkeysInFocus"); + ADD_HOTKEY_FOCUS_TYPE("DisableHotkeysOutOfFocus"); + +#undef ADD_HOTKEY_FOCUS_TYPE ui->simpleOutputVBitrate->setSingleStep(50); ui->simpleOutputVBitrate->setSuffix(" Kbps"); @@ -482,30 +499,29 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) uint32_t winVer = GetWindowsVersion(); if (winVer > 0 && winVer < 0x602) { toggleAero = new QCheckBox( - QTStr("Basic.Settings.Video.DisableAero"), - this); - QFormLayout *videoLayout = - reinterpret_cast(ui->videoPage->layout()); + QTStr("Basic.Settings.Video.DisableAero"), this); + QFormLayout *videoLayout = reinterpret_cast( + ui->videoPage->layout()); videoLayout->addRow(nullptr, toggleAero); HookWidget(toggleAero, CHECK_CHANGED, VIDEO_CHANGED); - connect(toggleAero, &QAbstractButton::toggled, - this, &OBSBasicSettings::ToggleDisableAero); + connect(toggleAero, &QAbstractButton::toggled, this, + &OBSBasicSettings::ToggleDisableAero); } -#define PROCESS_PRIORITY(val) \ - {"Basic.Settings.Advanced.General.ProcessPriority." ## val , val} +#define PROCESS_PRIORITY(val) \ + { \ + "Basic.Settings.Advanced.General.ProcessPriority."##val, val \ + } static struct ProcessPriority { const char *name; const char *val; - } processPriorities[] = { - PROCESS_PRIORITY("High"), - PROCESS_PRIORITY("AboveNormal"), - PROCESS_PRIORITY("Normal"), - PROCESS_PRIORITY("BelowNormal"), - PROCESS_PRIORITY("Idle") - }; + } processPriorities[] = {PROCESS_PRIORITY("High"), + PROCESS_PRIORITY("AboveNormal"), + PROCESS_PRIORITY("Normal"), + PROCESS_PRIORITY("BelowNormal"), + PROCESS_PRIORITY("Idle")}; #undef PROCESS_PRIORITY for (ProcessPriority pri : processPriorities) @@ -549,26 +565,26 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) ui->resetOSXVSync = nullptr; #endif - connect(ui->streamDelaySec, SIGNAL(valueChanged(int)), - this, SLOT(UpdateStreamDelayEstimate())); - connect(ui->outputMode, SIGNAL(currentIndexChanged(int)), - this, SLOT(UpdateStreamDelayEstimate())); - connect(ui->simpleOutputVBitrate, SIGNAL(valueChanged(int)), - this, SLOT(UpdateStreamDelayEstimate())); + connect(ui->streamDelaySec, SIGNAL(valueChanged(int)), this, + SLOT(UpdateStreamDelayEstimate())); + connect(ui->outputMode, SIGNAL(currentIndexChanged(int)), this, + SLOT(UpdateStreamDelayEstimate())); + connect(ui->simpleOutputVBitrate, SIGNAL(valueChanged(int)), this, + SLOT(UpdateStreamDelayEstimate())); connect(ui->simpleOutputABitrate, SIGNAL(currentIndexChanged(int)), - this, SLOT(UpdateStreamDelayEstimate())); - connect(ui->advOutTrack1Bitrate, SIGNAL(currentIndexChanged(int)), - this, SLOT(UpdateStreamDelayEstimate())); - connect(ui->advOutTrack2Bitrate, SIGNAL(currentIndexChanged(int)), - this, SLOT(UpdateStreamDelayEstimate())); - connect(ui->advOutTrack3Bitrate, SIGNAL(currentIndexChanged(int)), - this, SLOT(UpdateStreamDelayEstimate())); - connect(ui->advOutTrack4Bitrate, SIGNAL(currentIndexChanged(int)), - this, SLOT(UpdateStreamDelayEstimate())); - connect(ui->advOutTrack5Bitrate, SIGNAL(currentIndexChanged(int)), - this, SLOT(UpdateStreamDelayEstimate())); - connect(ui->advOutTrack6Bitrate, SIGNAL(currentIndexChanged(int)), - this, SLOT(UpdateStreamDelayEstimate())); + this, SLOT(UpdateStreamDelayEstimate())); + connect(ui->advOutTrack1Bitrate, SIGNAL(currentIndexChanged(int)), this, + SLOT(UpdateStreamDelayEstimate())); + connect(ui->advOutTrack2Bitrate, SIGNAL(currentIndexChanged(int)), this, + SLOT(UpdateStreamDelayEstimate())); + connect(ui->advOutTrack3Bitrate, SIGNAL(currentIndexChanged(int)), this, + SLOT(UpdateStreamDelayEstimate())); + connect(ui->advOutTrack4Bitrate, SIGNAL(currentIndexChanged(int)), this, + SLOT(UpdateStreamDelayEstimate())); + connect(ui->advOutTrack5Bitrate, SIGNAL(currentIndexChanged(int)), this, + SLOT(UpdateStreamDelayEstimate())); + connect(ui->advOutTrack6Bitrate, SIGNAL(currentIndexChanged(int)), this, + SLOT(UpdateStreamDelayEstimate())); //Apply button disabled until change. EnableApplyButton(false); @@ -582,11 +598,10 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) LoadColorRanges(); LoadFormats(); - auto ReloadAudioSources = [](void *data, calldata_t *param) - { - auto settings = static_cast(data); - auto source = static_cast(calldata_ptr(param, - "source")); + auto ReloadAudioSources = [](void *data, calldata_t *param) { + auto settings = static_cast(data); + auto source = static_cast( + calldata_ptr(param, "source")); if (!source) return; @@ -595,31 +610,31 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) return; QMetaObject::invokeMethod(settings, "ReloadAudioSources", - Qt::QueuedConnection); + Qt::QueuedConnection); }; sourceCreated.Connect(obs_get_signal_handler(), "source_create", - ReloadAudioSources, this); + ReloadAudioSources, this); channelChanged.Connect(obs_get_signal_handler(), "channel_change", - ReloadAudioSources, this); + ReloadAudioSources, this); - auto ReloadHotkeys = [](void *data, calldata_t*) - { - auto settings = static_cast(data); + auto ReloadHotkeys = [](void *data, calldata_t *) { + auto settings = static_cast(data); QMetaObject::invokeMethod(settings, "ReloadHotkeys"); }; hotkeyRegistered.Connect(obs_get_signal_handler(), "hotkey_register", - ReloadHotkeys, this); + ReloadHotkeys, this); - auto ReloadHotkeysIgnore = [](void *data, calldata_t *param) - { - auto settings = static_cast(data); - auto key = static_cast( - calldata_ptr(param,"key")); + auto ReloadHotkeysIgnore = [](void *data, calldata_t *param) { + auto settings = static_cast(data); + auto key = + static_cast(calldata_ptr(param, "key")); QMetaObject::invokeMethod(settings, "ReloadHotkeys", - Q_ARG(obs_hotkey_id, obs_hotkey_get_id(key))); + Q_ARG(obs_hotkey_id, + obs_hotkey_get_id(key))); }; hotkeyUnregistered.Connect(obs_get_signal_handler(), - "hotkey_unregister", ReloadHotkeysIgnore, this); + "hotkey_unregister", ReloadHotkeysIgnore, + this); FillSimpleRecordingValues(); FillSimpleStreamingValues(); @@ -627,72 +642,72 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) FillAudioMonitoringDevices(); #endif - connect(ui->channelSetup, SIGNAL(currentIndexChanged(int)), - this, SLOT(SurroundWarning(int))); - connect(ui->channelSetup, SIGNAL(currentIndexChanged(int)), - this, SLOT(SpeakerLayoutChanged(int))); - connect(ui->simpleOutRecQuality, SIGNAL(currentIndexChanged(int)), - this, SLOT(SimpleRecordingQualityChanged())); - connect(ui->simpleOutRecQuality, SIGNAL(currentIndexChanged(int)), - this, SLOT(SimpleRecordingQualityLosslessWarning(int))); - connect(ui->simpleOutRecFormat, SIGNAL(currentIndexChanged(int)), - this, SLOT(SimpleRecordingEncoderChanged())); - connect(ui->simpleOutStrEncoder, SIGNAL(currentIndexChanged(int)), - this, SLOT(SimpleStreamingEncoderChanged())); - connect(ui->simpleOutStrEncoder, SIGNAL(currentIndexChanged(int)), - this, SLOT(SimpleRecordingEncoderChanged())); - connect(ui->simpleOutRecEncoder, SIGNAL(currentIndexChanged(int)), - this, SLOT(SimpleRecordingEncoderChanged())); - connect(ui->simpleOutputVBitrate, SIGNAL(valueChanged(int)), - this, SLOT(SimpleRecordingEncoderChanged())); + connect(ui->channelSetup, SIGNAL(currentIndexChanged(int)), this, + SLOT(SurroundWarning(int))); + connect(ui->channelSetup, SIGNAL(currentIndexChanged(int)), this, + SLOT(SpeakerLayoutChanged(int))); + connect(ui->simpleOutRecQuality, SIGNAL(currentIndexChanged(int)), this, + SLOT(SimpleRecordingQualityChanged())); + connect(ui->simpleOutRecQuality, SIGNAL(currentIndexChanged(int)), this, + SLOT(SimpleRecordingQualityLosslessWarning(int))); + connect(ui->simpleOutRecFormat, SIGNAL(currentIndexChanged(int)), this, + SLOT(SimpleRecordingEncoderChanged())); + connect(ui->simpleOutStrEncoder, SIGNAL(currentIndexChanged(int)), this, + SLOT(SimpleStreamingEncoderChanged())); + connect(ui->simpleOutStrEncoder, SIGNAL(currentIndexChanged(int)), this, + SLOT(SimpleRecordingEncoderChanged())); + connect(ui->simpleOutRecEncoder, SIGNAL(currentIndexChanged(int)), this, + SLOT(SimpleRecordingEncoderChanged())); + connect(ui->simpleOutputVBitrate, SIGNAL(valueChanged(int)), this, + SLOT(SimpleRecordingEncoderChanged())); connect(ui->simpleOutputABitrate, SIGNAL(currentIndexChanged(int)), - this, SLOT(SimpleRecordingEncoderChanged())); - connect(ui->simpleOutAdvanced, SIGNAL(toggled(bool)), - this, SLOT(SimpleRecordingEncoderChanged())); - connect(ui->simpleOutEnforce, SIGNAL(toggled(bool)), - this, SLOT(SimpleRecordingEncoderChanged())); - connect(ui->simpleReplayBuf, SIGNAL(toggled(bool)), - this, SLOT(SimpleReplayBufferChanged())); - connect(ui->simpleOutputVBitrate, SIGNAL(valueChanged(int)), - this, SLOT(SimpleReplayBufferChanged())); + this, SLOT(SimpleRecordingEncoderChanged())); + connect(ui->simpleOutAdvanced, SIGNAL(toggled(bool)), this, + SLOT(SimpleRecordingEncoderChanged())); + connect(ui->simpleOutEnforce, SIGNAL(toggled(bool)), this, + SLOT(SimpleRecordingEncoderChanged())); + connect(ui->simpleReplayBuf, SIGNAL(toggled(bool)), this, + SLOT(SimpleReplayBufferChanged())); + connect(ui->simpleOutputVBitrate, SIGNAL(valueChanged(int)), this, + SLOT(SimpleReplayBufferChanged())); connect(ui->simpleOutputABitrate, SIGNAL(currentIndexChanged(int)), - this, SLOT(SimpleReplayBufferChanged())); - connect(ui->simpleRBSecMax, SIGNAL(valueChanged(int)), - this, SLOT(SimpleReplayBufferChanged())); - connect(ui->advReplayBuf, SIGNAL(toggled(bool)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->advOutRecTrack1, SIGNAL(toggled(bool)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->advOutRecTrack2, SIGNAL(toggled(bool)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->advOutRecTrack3, SIGNAL(toggled(bool)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->advOutRecTrack4, SIGNAL(toggled(bool)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->advOutRecTrack5, SIGNAL(toggled(bool)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->advOutRecTrack6, SIGNAL(toggled(bool)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->advOutTrack1Bitrate, SIGNAL(currentIndexChanged(int)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->advOutTrack2Bitrate, SIGNAL(currentIndexChanged(int)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->advOutTrack3Bitrate, SIGNAL(currentIndexChanged(int)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->advOutTrack4Bitrate, SIGNAL(currentIndexChanged(int)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->advOutTrack5Bitrate, SIGNAL(currentIndexChanged(int)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->advOutTrack6Bitrate, SIGNAL(currentIndexChanged(int)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->advOutRecType, SIGNAL(currentIndexChanged(int)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->advOutRecEncoder, SIGNAL(currentIndexChanged(int)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->advRBSecMax, SIGNAL(valueChanged(int)), - this, SLOT(AdvReplayBufferChanged())); - connect(ui->listWidget, SIGNAL(currentRowChanged(int)), - this, SLOT(SimpleRecordingEncoderChanged())); + this, SLOT(SimpleReplayBufferChanged())); + connect(ui->simpleRBSecMax, SIGNAL(valueChanged(int)), this, + SLOT(SimpleReplayBufferChanged())); + connect(ui->advReplayBuf, SIGNAL(toggled(bool)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->advOutRecTrack1, SIGNAL(toggled(bool)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->advOutRecTrack2, SIGNAL(toggled(bool)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->advOutRecTrack3, SIGNAL(toggled(bool)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->advOutRecTrack4, SIGNAL(toggled(bool)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->advOutRecTrack5, SIGNAL(toggled(bool)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->advOutRecTrack6, SIGNAL(toggled(bool)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->advOutTrack1Bitrate, SIGNAL(currentIndexChanged(int)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->advOutTrack2Bitrate, SIGNAL(currentIndexChanged(int)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->advOutTrack3Bitrate, SIGNAL(currentIndexChanged(int)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->advOutTrack4Bitrate, SIGNAL(currentIndexChanged(int)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->advOutTrack5Bitrate, SIGNAL(currentIndexChanged(int)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->advOutTrack6Bitrate, SIGNAL(currentIndexChanged(int)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->advOutRecType, SIGNAL(currentIndexChanged(int)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->advOutRecEncoder, SIGNAL(currentIndexChanged(int)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->advRBSecMax, SIGNAL(valueChanged(int)), this, + SLOT(AdvReplayBufferChanged())); + connect(ui->listWidget, SIGNAL(currentRowChanged(int)), this, + SLOT(SimpleRecordingEncoderChanged())); // Get Bind to IP Addresses obs_properties_t *ppts = obs_get_output_properties("rtmp_output"); @@ -712,20 +727,22 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) LoadSettings(false); // Add warning checks to advanced output recording section controls - connect(ui->advOutRecTrack1, SIGNAL(clicked()), - this, SLOT(AdvOutRecCheckWarnings())); - connect(ui->advOutRecTrack2, SIGNAL(clicked()), - this, SLOT(AdvOutRecCheckWarnings())); - connect(ui->advOutRecTrack3, SIGNAL(clicked()), - this, SLOT(AdvOutRecCheckWarnings())); - connect(ui->advOutRecTrack4, SIGNAL(clicked()), - this, SLOT(AdvOutRecCheckWarnings())); - connect(ui->advOutRecTrack5, SIGNAL(clicked()), - this, SLOT(AdvOutRecCheckWarnings())); - connect(ui->advOutRecTrack6, SIGNAL(clicked()), - this, SLOT(AdvOutRecCheckWarnings())); - connect(ui->advOutRecFormat, SIGNAL(currentIndexChanged(int)), - this, SLOT(AdvOutRecCheckWarnings())); + connect(ui->advOutRecTrack1, SIGNAL(clicked()), this, + SLOT(AdvOutRecCheckWarnings())); + connect(ui->advOutRecTrack2, SIGNAL(clicked()), this, + SLOT(AdvOutRecCheckWarnings())); + connect(ui->advOutRecTrack3, SIGNAL(clicked()), this, + SLOT(AdvOutRecCheckWarnings())); + connect(ui->advOutRecTrack4, SIGNAL(clicked()), this, + SLOT(AdvOutRecCheckWarnings())); + connect(ui->advOutRecTrack5, SIGNAL(clicked()), this, + SLOT(AdvOutRecCheckWarnings())); + connect(ui->advOutRecTrack6, SIGNAL(clicked()), this, + SLOT(AdvOutRecCheckWarnings())); + connect(ui->advOutRecFormat, SIGNAL(currentIndexChanged(int)), this, + SLOT(AdvOutRecCheckWarnings())); + connect(ui->advOutRecEncoder, SIGNAL(currentIndexChanged(int)), this, + SLOT(AdvOutRecCheckWarnings())); AdvOutRecCheckWarnings(); ui->buttonBox->button(QDialogButtonBox::Apply)->setIcon(QIcon()); @@ -736,59 +753,60 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) UpdateAutomaticReplayBufferCheckboxes(); - App()->EnableInFocusHotkeys(false); + App()->DisableHotkeys(); } OBSBasicSettings::~OBSBasicSettings() { - bool disableHotkeysInFocus = config_get_bool(App()->GlobalConfig(), - "General", "DisableHotkeysInFocus"); delete ui->filenameFormatting->completer(); main->EnableOutputs(true); - App()->EnableInFocusHotkeys(!disableHotkeysInFocus); + + App()->UpdateHotkeyFocusSetting(); EnableThreadedMessageBoxes(false); } void OBSBasicSettings::SaveCombo(QComboBox *widget, const char *section, - const char *value) + const char *value) { if (WidgetChanged(widget)) config_set_string(main->Config(), section, value, - QT_TO_UTF8(widget->currentText())); + QT_TO_UTF8(widget->currentText())); } void OBSBasicSettings::SaveComboData(QComboBox *widget, const char *section, - const char *value) + const char *value) { if (WidgetChanged(widget)) { QString str = GetComboData(widget); config_set_string(main->Config(), section, value, - QT_TO_UTF8(str)); + QT_TO_UTF8(str)); } } void OBSBasicSettings::SaveCheckBox(QAbstractButton *widget, - const char *section, const char *value, bool invert) + const char *section, const char *value, + bool invert) { if (WidgetChanged(widget)) { bool checked = widget->isChecked(); - if (invert) checked = !checked; + if (invert) + checked = !checked; config_set_bool(main->Config(), section, value, checked); } } void OBSBasicSettings::SaveEdit(QLineEdit *widget, const char *section, - const char *value) + const char *value) { if (WidgetChanged(widget)) config_set_string(main->Config(), section, value, - QT_TO_UTF8(widget->text())); + QT_TO_UTF8(widget->text())); } void OBSBasicSettings::SaveSpinBox(QSpinBox *widget, const char *section, - const char *value) + const char *value) { if (WidgetChanged(widget)) config_set_int(main->Config(), section, value, widget->value()); @@ -799,8 +817,8 @@ void OBSBasicSettings::SaveSpinBox(QSpinBox *widget, const char *section, void OBSBasicSettings::LoadEncoderTypes() { - const char *type; - size_t idx = 0; + const char *type; + size_t idx = 0; ui->advOutRecEncoder->addItem(TEXT_USE_STREAM_ENC, "none"); @@ -812,12 +830,12 @@ void OBSBasicSettings::LoadEncoderTypes() if (obs_get_encoder_type(type) != OBS_ENCODER_VIDEO) continue; - const char* streaming_codecs[] = { + const char *streaming_codecs[] = { "h264", //"hevc", }; bool is_streaming_codec = false; - for (const char* test_codec : streaming_codecs) { + for (const char *test_codec : streaming_codecs) { if (strcmp(codec, test_codec) == 0) { is_streaming_codec = true; break; @@ -836,7 +854,7 @@ void OBSBasicSettings::LoadEncoderTypes() } #define CS_PARTIAL_STR QTStr("Basic.Settings.Advanced.Video.ColorRange.Partial") -#define CS_FULL_STR QTStr("Basic.Settings.Advanced.Video.ColorRange.Full") +#define CS_FULL_STR QTStr("Basic.Settings.Advanced.Video.ColorRange.Full") void OBSBasicSettings::LoadColorRanges() { @@ -846,10 +864,8 @@ void OBSBasicSettings::LoadColorRanges() #define AV_FORMAT_DEFAULT_STR \ QTStr("Basic.Settings.Output.Adv.FFmpeg.FormatDefault") -#define AUDIO_STR \ - QTStr("Basic.Settings.Output.Adv.FFmpeg.FormatAudio") -#define VIDEO_STR \ - QTStr("Basic.Settings.Output.Adv.FFmpeg.FormatVideo") +#define AUDIO_STR QTStr("Basic.Settings.Output.Adv.FFmpeg.FormatAudio") +#define VIDEO_STR QTStr("Basic.Settings.Output.Adv.FFmpeg.FormatVideo") void OBSBasicSettings::LoadFormats() { @@ -858,20 +874,19 @@ void OBSBasicSettings::LoadFormats() formats.reset(ff_format_supported()); const ff_format_desc *format = formats.get(); - while(format != nullptr) { + while (format != nullptr) { bool audio = ff_format_desc_has_audio(format); bool video = ff_format_desc_has_video(format); FormatDesc formatDesc(ff_format_desc_name(format), - ff_format_desc_mime_type(format), - format); + ff_format_desc_mime_type(format), format); if (audio || video) { QString itemText(ff_format_desc_name(format)); if (audio ^ video) itemText += QString(" (%1)").arg( - audio ? AUDIO_STR : VIDEO_STR); + audio ? AUDIO_STR : VIDEO_STR); - ui->advOutFFFormat->addItem(itemText, - qVariantFromValue(formatDesc)); + ui->advOutFFFormat->addItem( + itemText, qVariantFromValue(formatDesc)); } format = ff_format_desc_next(format); @@ -889,10 +904,10 @@ static void AddCodec(QComboBox *combo, const ff_codec_desc *codec_desc) QString itemText(ff_codec_desc_name(codec_desc)); if (ff_codec_desc_is_alias(codec_desc)) itemText += QString(" (%1)").arg( - ff_codec_desc_base_name(codec_desc)); + ff_codec_desc_base_name(codec_desc)); CodecDesc cd(ff_codec_desc_name(codec_desc), - ff_codec_desc_id(codec_desc)); + ff_codec_desc_id(codec_desc)); combo->addItem(itemText, qVariantFromValue(cd)); } @@ -901,7 +916,7 @@ static void AddCodec(QComboBox *combo, const ff_codec_desc *codec_desc) QTStr("Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault") static void AddDefaultCodec(QComboBox *combo, const ff_format_desc *formatDesc, - ff_codec_type codecType) + ff_codec_type codecType) { CodecDesc cd = GetDefaultCodecDesc(formatDesc, codecType); @@ -910,7 +925,7 @@ static void AddDefaultCodec(QComboBox *combo, const ff_format_desc *formatDesc, combo->removeItem(existingIdx); combo->addItem(QString("%1 (%2)").arg(cd.name, AV_ENCODER_DEFAULT_STR), - qVariantFromValue(cd)); + qVariantFromValue(cd)); } #define AV_ENCODER_DISABLE_STR \ @@ -927,12 +942,12 @@ void OBSBasicSettings::ReloadCodecs(const ff_format_desc *formatDesc) return; bool ignore_compatability = ui->advOutFFIgnoreCompat->isChecked(); - OBSFFCodecDesc codecDescs(ff_codec_supported(formatDesc, - ignore_compatability)); + OBSFFCodecDesc codecDescs( + ff_codec_supported(formatDesc, ignore_compatability)); const ff_codec_desc *codec = codecDescs.get(); - while(codec != nullptr) { + while (codec != nullptr) { switch (ff_codec_desc_type(codec)) { case FF_CODEC_AUDIO: AddCodec(ui->advOutFFAEncoder, codec); @@ -976,7 +991,7 @@ void OBSBasicSettings::LoadLanguageList() int idx = ui->language->count(); ui->language->addItem(QT_UTF8(locale.second.c_str()), - QT_UTF8(locale.first.c_str())); + QT_UTF8(locale.first.c_str())); if (locale.first == currentLang) ui->language->setCurrentIndex(idx); @@ -995,7 +1010,7 @@ void OBSBasicSettings::LoadThemeList() string themeDir; char userThemeDir[512]; int ret = GetConfigPath(userThemeDir, sizeof(userThemeDir), - "obs-studio/themes/"); + "obs-studio/themes/"); GetDataFilePath("themes/", themeDir); /* Check user dir first. */ @@ -1004,7 +1019,7 @@ void OBSBasicSettings::LoadThemeList() QDir::Files); while (it.hasNext()) { it.next(); - QString name = it.fileName().section(".",0,0); + QString name = it.fileName().section(".", 0, 0); ui->theme->addItem(name); uniqueSet.insert(name); } @@ -1017,10 +1032,10 @@ void OBSBasicSettings::LoadThemeList() /* Check shipped themes. */ QDirIterator uIt(QString(themeDir.c_str()), QStringList() << "*.qss", - QDir::Files); + QDir::Files); while (uIt.hasNext()) { uIt.next(); - QString name = uIt.fileName().section(".",0,0); + QString name = uIt.fileName().section(".", 0, 0); if (name == DEFAULT_THEME) name = defaultTheme; @@ -1047,137 +1062,142 @@ void OBSBasicSettings::LoadGeneralSettings() LoadThemeList(); #if defined(_WIN32) || defined(__APPLE__) - bool enableAutoUpdates = config_get_bool(GetGlobalConfig(), - "General", "EnableAutoUpdates"); + bool enableAutoUpdates = config_get_bool(GetGlobalConfig(), "General", + "EnableAutoUpdates"); ui->enableAutoUpdates->setChecked(enableAutoUpdates); #endif - bool openStatsOnStartup = config_get_bool(main->Config(), - "General", "OpenStatsOnStartup"); + bool openStatsOnStartup = config_get_bool(main->Config(), "General", + "OpenStatsOnStartup"); ui->openStatsOnStartup->setChecked(openStatsOnStartup); - bool recordWhenStreaming = config_get_bool(GetGlobalConfig(), - "BasicWindow", "RecordWhenStreaming"); + bool recordWhenStreaming = config_get_bool( + GetGlobalConfig(), "BasicWindow", "RecordWhenStreaming"); ui->recordWhenStreaming->setChecked(recordWhenStreaming); - bool keepRecordStreamStops = config_get_bool(GetGlobalConfig(), - "BasicWindow", "KeepRecordingWhenStreamStops"); + bool keepRecordStreamStops = + config_get_bool(GetGlobalConfig(), "BasicWindow", + "KeepRecordingWhenStreamStops"); ui->keepRecordStreamStops->setChecked(keepRecordStreamStops); - bool replayWhileStreaming = config_get_bool(GetGlobalConfig(), - "BasicWindow", "ReplayBufferWhileStreaming"); + bool replayWhileStreaming = config_get_bool( + GetGlobalConfig(), "BasicWindow", "ReplayBufferWhileStreaming"); ui->replayWhileStreaming->setChecked(replayWhileStreaming); - bool keepReplayStreamStops = config_get_bool(GetGlobalConfig(), - "BasicWindow", "KeepReplayBufferStreamStops"); + bool keepReplayStreamStops = + config_get_bool(GetGlobalConfig(), "BasicWindow", + "KeepReplayBufferStreamStops"); ui->keepReplayStreamStops->setChecked(keepReplayStreamStops); - bool systemTrayEnabled = config_get_bool(GetGlobalConfig(), - "BasicWindow", "SysTrayEnabled"); + bool systemTrayEnabled = config_get_bool( + GetGlobalConfig(), "BasicWindow", "SysTrayEnabled"); ui->systemTrayEnabled->setChecked(systemTrayEnabled); - bool systemTrayWhenStarted = config_get_bool(GetGlobalConfig(), - "BasicWindow", "SysTrayWhenStarted"); + bool systemTrayWhenStarted = config_get_bool( + GetGlobalConfig(), "BasicWindow", "SysTrayWhenStarted"); ui->systemTrayWhenStarted->setChecked(systemTrayWhenStarted); - bool systemTrayAlways = config_get_bool(GetGlobalConfig(), - "BasicWindow", "SysTrayMinimizeToTray"); + bool systemTrayAlways = config_get_bool( + GetGlobalConfig(), "BasicWindow", "SysTrayMinimizeToTray"); ui->systemTrayAlways->setChecked(systemTrayAlways); - bool saveProjectors = config_get_bool(GetGlobalConfig(), - "BasicWindow", "SaveProjectors"); + bool saveProjectors = config_get_bool(GetGlobalConfig(), "BasicWindow", + "SaveProjectors"); ui->saveProjectors->setChecked(saveProjectors); - bool snappingEnabled = config_get_bool(GetGlobalConfig(), - "BasicWindow", "SnappingEnabled"); + bool snappingEnabled = config_get_bool(GetGlobalConfig(), "BasicWindow", + "SnappingEnabled"); ui->snappingEnabled->setChecked(snappingEnabled); - bool screenSnapping = config_get_bool(GetGlobalConfig(), - "BasicWindow", "ScreenSnapping"); + bool screenSnapping = config_get_bool(GetGlobalConfig(), "BasicWindow", + "ScreenSnapping"); ui->screenSnapping->setChecked(screenSnapping); - bool centerSnapping = config_get_bool(GetGlobalConfig(), - "BasicWindow", "CenterSnapping"); + bool centerSnapping = config_get_bool(GetGlobalConfig(), "BasicWindow", + "CenterSnapping"); ui->centerSnapping->setChecked(centerSnapping); - bool sourceSnapping = config_get_bool(GetGlobalConfig(), - "BasicWindow", "SourceSnapping"); + bool sourceSnapping = config_get_bool(GetGlobalConfig(), "BasicWindow", + "SourceSnapping"); ui->sourceSnapping->setChecked(sourceSnapping); double snapDistance = config_get_double(GetGlobalConfig(), - "BasicWindow", "SnapDistance"); + "BasicWindow", "SnapDistance"); ui->snapDistance->setValue(snapDistance); - bool warnBeforeStreamStart = config_get_bool(GetGlobalConfig(), - "BasicWindow", "WarnBeforeStartingStream"); + bool warnBeforeStreamStart = config_get_bool( + GetGlobalConfig(), "BasicWindow", "WarnBeforeStartingStream"); ui->warnBeforeStreamStart->setChecked(warnBeforeStreamStart); - bool warnBeforeStreamStop = config_get_bool(GetGlobalConfig(), - "BasicWindow", "WarnBeforeStoppingStream"); + bool warnBeforeStreamStop = config_get_bool( + GetGlobalConfig(), "BasicWindow", "WarnBeforeStoppingStream"); ui->warnBeforeStreamStop->setChecked(warnBeforeStreamStop); - bool hideProjectorCursor = config_get_bool(GetGlobalConfig(), - "BasicWindow", "HideProjectorCursor"); + bool warnBeforeRecordStop = config_get_bool( + GetGlobalConfig(), "BasicWindow", "WarnBeforeStoppingRecord"); + ui->warnBeforeRecordStop->setChecked(warnBeforeRecordStop); + + bool hideProjectorCursor = config_get_bool( + GetGlobalConfig(), "BasicWindow", "HideProjectorCursor"); ui->hideProjectorCursor->setChecked(hideProjectorCursor); - bool projectorAlwaysOnTop = config_get_bool(GetGlobalConfig(), - "BasicWindow", "ProjectorAlwaysOnTop"); + bool projectorAlwaysOnTop = config_get_bool( + GetGlobalConfig(), "BasicWindow", "ProjectorAlwaysOnTop"); ui->projectorAlwaysOnTop->setChecked(projectorAlwaysOnTop); - bool overflowHide = config_get_bool(GetGlobalConfig(), - "BasicWindow", "OverflowHidden"); + bool overflowHide = config_get_bool(GetGlobalConfig(), "BasicWindow", + "OverflowHidden"); ui->overflowHide->setChecked(overflowHide); - bool overflowAlwaysVisible = config_get_bool(GetGlobalConfig(), - "BasicWindow", "OverflowAlwaysVisible"); + bool overflowAlwaysVisible = config_get_bool( + GetGlobalConfig(), "BasicWindow", "OverflowAlwaysVisible"); ui->overflowAlwaysVisible->setChecked(overflowAlwaysVisible); - bool overflowSelectionHide = config_get_bool(GetGlobalConfig(), - "BasicWindow", "OverflowSelectionHidden"); + bool overflowSelectionHide = config_get_bool( + GetGlobalConfig(), "BasicWindow", "OverflowSelectionHidden"); ui->overflowSelectionHide->setChecked(overflowSelectionHide); - bool doubleClickSwitch = config_get_bool(GetGlobalConfig(), - "BasicWindow", "TransitionOnDoubleClick"); + bool doubleClickSwitch = config_get_bool( + GetGlobalConfig(), "BasicWindow", "TransitionOnDoubleClick"); ui->doubleClickSwitch->setChecked(doubleClickSwitch); - bool studioPortraitLayout = config_get_bool(GetGlobalConfig(), - "BasicWindow", "StudioPortraitLayout"); + bool studioPortraitLayout = config_get_bool( + GetGlobalConfig(), "BasicWindow", "StudioPortraitLayout"); ui->studioPortraitLayout->setChecked(studioPortraitLayout); - bool prevProgLabels = config_get_bool(GetGlobalConfig(), - "BasicWindow", "StudioModeLabels"); + bool prevProgLabels = config_get_bool(GetGlobalConfig(), "BasicWindow", + "StudioModeLabels"); ui->prevProgLabelToggle->setChecked(prevProgLabels); - bool multiviewMouseSwitch = config_get_bool(GetGlobalConfig(), - "BasicWindow", "MultiviewMouseSwitch"); + bool multiviewMouseSwitch = config_get_bool( + GetGlobalConfig(), "BasicWindow", "MultiviewMouseSwitch"); ui->multiviewMouseSwitch->setChecked(multiviewMouseSwitch); - bool multiviewDrawNames = config_get_bool(GetGlobalConfig(), - "BasicWindow", "MultiviewDrawNames"); + bool multiviewDrawNames = config_get_bool( + GetGlobalConfig(), "BasicWindow", "MultiviewDrawNames"); ui->multiviewDrawNames->setChecked(multiviewDrawNames); - bool multiviewDrawAreas = config_get_bool(GetGlobalConfig(), - "BasicWindow", "MultiviewDrawAreas"); + bool multiviewDrawAreas = config_get_bool( + GetGlobalConfig(), "BasicWindow", "MultiviewDrawAreas"); ui->multiviewDrawAreas->setChecked(multiviewDrawAreas); - ui->multiviewLayout->addItem(QTStr( - "Basic.Settings.General.MultiviewLayout.Horizontal.Top"), - static_cast(MultiviewLayout::HORIZONTAL_TOP_8_SCENES)); - ui->multiviewLayout->addItem(QTStr( - "Basic.Settings.General.MultiviewLayout.Horizontal.Bottom"), - static_cast(MultiviewLayout::HORIZONTAL_BOTTOM_8_SCENES)); - ui->multiviewLayout->addItem(QTStr( - "Basic.Settings.General.MultiviewLayout.Vertical.Left"), - static_cast(MultiviewLayout::VERTICAL_LEFT_8_SCENES)); - ui->multiviewLayout->addItem(QTStr( - "Basic.Settings.General.MultiviewLayout.Vertical.Right"), - static_cast(MultiviewLayout::VERTICAL_RIGHT_8_SCENES)); - ui->multiviewLayout->addItem(QTStr( - "Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top"), - static_cast(MultiviewLayout::HORIZONTAL_TOP_24_SCENES)); + ui->multiviewLayout->addItem( + QTStr("Basic.Settings.General.MultiviewLayout.Horizontal.Top"), + static_cast(MultiviewLayout::HORIZONTAL_TOP_8_SCENES)); + ui->multiviewLayout->addItem( + QTStr("Basic.Settings.General.MultiviewLayout.Horizontal.Bottom"), + static_cast(MultiviewLayout::HORIZONTAL_BOTTOM_8_SCENES)); + ui->multiviewLayout->addItem( + QTStr("Basic.Settings.General.MultiviewLayout.Vertical.Left"), + static_cast(MultiviewLayout::VERTICAL_LEFT_8_SCENES)); + ui->multiviewLayout->addItem( + QTStr("Basic.Settings.General.MultiviewLayout.Vertical.Right"), + static_cast(MultiviewLayout::VERTICAL_RIGHT_8_SCENES)); + ui->multiviewLayout->addItem( + QTStr("Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top"), + static_cast(MultiviewLayout::HORIZONTAL_TOP_24_SCENES)); - ui->multiviewLayout->setCurrentIndex( - config_get_int(GetGlobalConfig(), "BasicWindow", - "MultiviewLayout")); + ui->multiviewLayout->setCurrentIndex(config_get_int( + GetGlobalConfig(), "BasicWindow", "MultiviewLayout")); loading = false; } @@ -1185,8 +1205,8 @@ void OBSBasicSettings::LoadGeneralSettings() void OBSBasicSettings::LoadRendererList() { #ifdef _WIN32 - const char *renderer = config_get_string(GetGlobalConfig(), "Video", - "Renderer"); + const char *renderer = + config_get_string(GetGlobalConfig(), "Video", "Renderer"); ui->renderer->addItem(QT_UTF8("Direct3D 11")); if (opt_allow_opengl || strcmp(renderer, "OpenGL") == 0) @@ -1216,22 +1236,10 @@ static string ResString(uint32_t cx, uint32_t cy) } /* some nice default output resolution vals */ -static const double vals[] = -{ - 1.0, - 1.25, - (1.0/0.75), - 1.5, - (1.0/0.6), - 1.75, - 2.0, - 2.25, - 2.5, - 2.75, - 3.0 -}; +static const double vals[] = {1.0, 1.25, (1.0 / 0.75), 1.5, (1.0 / 0.6), 1.75, + 2.0, 2.25, 2.5, 2.75, 3.0}; -static const size_t numVals = sizeof(vals)/sizeof(double); +static const size_t numVals = sizeof(vals) / sizeof(double); void OBSBasicSettings::ResetDownscales(uint32_t cx, uint32_t cy) { @@ -1260,8 +1268,8 @@ void OBSBasicSettings::ResetDownscales(uint32_t cx, uint32_t cy) out_cy = cy; oldOutputRes = ui->baseResolution->lineEdit()->text(); } else { - oldOutputRes = QString::number(out_cx) + "x" + - QString::number(out_cy); + oldOutputRes = + QString::number(out_cx) + "x" + QString::number(out_cy); } for (size_t idx = 0; idx < numVals; idx++) { @@ -1296,7 +1304,7 @@ void OBSBasicSettings::ResetDownscales(uint32_t cx, uint32_t cy) string res = ResString(cx, cy); - float baseAspect = float(cx) / float(cy); + float baseAspect = float(cx) / float(cy); float outputAspect = float(out_cx) / float(out_cy); bool closeAspect = close_float(baseAspect, outputAspect, 0.01f); @@ -1327,24 +1335,29 @@ void OBSBasicSettings::ResetDownscales(uint32_t cx, uint32_t cy) void OBSBasicSettings::LoadDownscaleFilters() { ui->downscaleFilter->addItem( - QTStr("Basic.Settings.Video.DownscaleFilter.Bilinear"), - QT_UTF8("bilinear")); + QTStr("Basic.Settings.Video.DownscaleFilter.Bilinear"), + QT_UTF8("bilinear")); ui->downscaleFilter->addItem( - QTStr("Basic.Settings.Video.DownscaleFilter.Bicubic"), - QT_UTF8("bicubic")); + QTStr("Basic.Settings.Video.DownscaleFilter.Area"), + QT_UTF8("area")); ui->downscaleFilter->addItem( - QTStr("Basic.Settings.Video.DownscaleFilter.Lanczos"), - QT_UTF8("lanczos")); + QTStr("Basic.Settings.Video.DownscaleFilter.Bicubic"), + QT_UTF8("bicubic")); + ui->downscaleFilter->addItem( + QTStr("Basic.Settings.Video.DownscaleFilter.Lanczos"), + QT_UTF8("lanczos")); - const char *scaleType = config_get_string(main->Config(), - "Video", "ScaleType"); + const char *scaleType = + config_get_string(main->Config(), "Video", "ScaleType"); if (astrcmpi(scaleType, "bilinear") == 0) ui->downscaleFilter->setCurrentIndex(0); else if (astrcmpi(scaleType, "lanczos") == 0) - ui->downscaleFilter->setCurrentIndex(2); - else + ui->downscaleFilter->setCurrentIndex(3); + else if (astrcmpi(scaleType, "area") == 0) ui->downscaleFilter->setCurrentIndex(1); + else + ui->downscaleFilter->setCurrentIndex(2); } void OBSBasicSettings::LoadResolutionLists() @@ -1356,14 +1369,13 @@ void OBSBasicSettings::LoadResolutionLists() ui->baseResolution->clear(); - auto addRes = [this] (int cx, int cy) - { + auto addRes = [this](int cx, int cy) { QString res = ResString(cx, cy).c_str(); if (ui->baseResolution->findText(res) == -1) ui->baseResolution->addItem(res); }; - for (QScreen* screen: QGuiApplication::screens()) { + for (QScreen *screen : QGuiApplication::screens()) { QSize as = screen->size(); addRes(as.width(), as.height()); } @@ -1383,11 +1395,12 @@ void OBSBasicSettings::LoadResolutionLists() static inline void LoadFPSCommon(OBSBasic *main, Ui::OBSBasicSettings *ui) { - const char *val = config_get_string(main->Config(), "Video", - "FPSCommon"); + const char *val = + config_get_string(main->Config(), "Video", "FPSCommon"); int idx = ui->fpsCommon->findText(val); - if (idx == -1) idx = 4; + if (idx == -1) + idx = 4; ui->fpsCommon->setCurrentIndex(idx); } @@ -1412,9 +1425,9 @@ void OBSBasicSettings::LoadFPSData() LoadFPSInteger(main, ui.get()); LoadFPSFraction(main, ui.get()); - uint32_t fpsType = config_get_uint(main->Config(), "Video", - "FPSType"); - if (fpsType > 2) fpsType = 0; + uint32_t fpsType = config_get_uint(main->Config(), "Video", "FPSType"); + if (fpsType > 2) + fpsType = 0; ui->fpsType->setCurrentIndex(fpsType); ui->fpsTypes->setCurrentIndex(fpsType); @@ -1427,7 +1440,7 @@ void OBSBasicSettings::LoadVideoSettings() if (obs_video_active()) { ui->videoPage->setEnabled(false); ui->videoMsg->setText( - QTStr("Basic.Settings.Video.CurrentlyActive")); + QTStr("Basic.Settings.Video.CurrentlyActive")); } LoadResolutionLists(); @@ -1436,8 +1449,8 @@ void OBSBasicSettings::LoadVideoSettings() #ifdef _WIN32 if (toggleAero) { - bool disableAero = config_get_bool(main->Config(), "Video", - "DisableAero"); + bool disableAero = + config_get_bool(main->Config(), "Video", "DisableAero"); toggleAero->setChecked(disableAero); aeroWasDisabled = disableAero; @@ -1449,14 +1462,8 @@ void OBSBasicSettings::LoadVideoSettings() static inline bool IsSurround(const char *speakers) { - static const char *surroundLayouts[] = { - "2.1", - "4.0", - "4.1", - "5.1", - "7.1", - nullptr - }; + static const char *surroundLayouts[] = {"2.1", "4.0", "4.1", + "5.1", "7.1", nullptr}; if (!speakers || !*speakers) return false; @@ -1473,44 +1480,44 @@ static inline bool IsSurround(const char *speakers) void OBSBasicSettings::LoadSimpleOutputSettings() { - const char *path = config_get_string(main->Config(), "SimpleOutput", - "FilePath"); + const char *path = + config_get_string(main->Config(), "SimpleOutput", "FilePath"); bool noSpace = config_get_bool(main->Config(), "SimpleOutput", - "FileNameWithoutSpace"); - const char *format = config_get_string(main->Config(), "SimpleOutput", - "RecFormat"); - int videoBitrate = config_get_uint(main->Config(), "SimpleOutput", - "VBitrate"); - const char *streamEnc = config_get_string(main->Config(), "SimpleOutput", - "StreamEncoder"); - int audioBitrate = config_get_uint(main->Config(), "SimpleOutput", - "ABitrate"); - bool advanced = config_get_bool(main->Config(), "SimpleOutput", - "UseAdvanced"); + "FileNameWithoutSpace"); + const char *format = + config_get_string(main->Config(), "SimpleOutput", "RecFormat"); + int videoBitrate = + config_get_uint(main->Config(), "SimpleOutput", "VBitrate"); + const char *streamEnc = config_get_string( + main->Config(), "SimpleOutput", "StreamEncoder"); + int audioBitrate = + config_get_uint(main->Config(), "SimpleOutput", "ABitrate"); + bool advanced = + config_get_bool(main->Config(), "SimpleOutput", "UseAdvanced"); bool enforceBitrate = config_get_bool(main->Config(), "SimpleOutput", - "EnforceBitrate"); - const char *preset = config_get_string(main->Config(), "SimpleOutput", - "Preset"); - const char *qsvPreset = config_get_string(main->Config(), "SimpleOutput", - "QSVPreset"); + "EnforceBitrate"); + const char *preset = + config_get_string(main->Config(), "SimpleOutput", "Preset"); + const char *qsvPreset = + config_get_string(main->Config(), "SimpleOutput", "QSVPreset"); const char *nvPreset = config_get_string(main->Config(), "SimpleOutput", - "NVENCPreset"); - const char* amdPreset = config_get_string(main->Config(), "SimpleOutput", - "AMDPreset"); + "NVENCPreset"); + const char *amdPreset = + config_get_string(main->Config(), "SimpleOutput", "AMDPreset"); const char *custom = config_get_string(main->Config(), "SimpleOutput", - "x264Settings"); - const char *recQual = config_get_string(main->Config(), "SimpleOutput", - "RecQuality"); - const char *recEnc = config_get_string(main->Config(), "SimpleOutput", - "RecEncoder"); - const char *muxCustom = config_get_string(main->Config(), - "SimpleOutput", "MuxerCustom"); - bool replayBuf = config_get_bool(main->Config(), "SimpleOutput", - "RecRB"); - int rbTime = config_get_int(main->Config(), "SimpleOutput", - "RecRBTime"); - int rbSize = config_get_int(main->Config(), "SimpleOutput", - "RecRBSize"); + "x264Settings"); + const char *recQual = + config_get_string(main->Config(), "SimpleOutput", "RecQuality"); + const char *recEnc = + config_get_string(main->Config(), "SimpleOutput", "RecEncoder"); + const char *muxCustom = config_get_string( + main->Config(), "SimpleOutput", "MuxerCustom"); + bool replayBuf = + config_get_bool(main->Config(), "SimpleOutput", "RecRB"); + int rbTime = + config_get_int(main->Config(), "SimpleOutput", "RecRBTime"); + int rbSize = + config_get_int(main->Config(), "SimpleOutput", "RecRBSize"); curPreset = preset; curQSVPreset = qsvPreset; @@ -1526,30 +1533,33 @@ void OBSBasicSettings::LoadSimpleOutputSettings() int idx = ui->simpleOutRecFormat->findText(format); ui->simpleOutRecFormat->setCurrentIndex(idx); - const char *speakers = config_get_string(main->Config(), "Audio", - "ChannelSetup"); + const char *speakers = + config_get_string(main->Config(), "Audio", "ChannelSetup"); // restrict list of bitrates when multichannel is OFF if (!IsSurround(speakers)) RestrictResetBitrates({ui->simpleOutputABitrate}, 320); SetComboByName(ui->simpleOutputABitrate, - std::to_string(audioBitrate).c_str()); + std::to_string(audioBitrate).c_str()); ui->simpleOutAdvanced->setChecked(advanced); ui->simpleOutEnforce->setChecked(enforceBitrate); ui->simpleOutCustom->setText(custom); idx = ui->simpleOutRecQuality->findData(QString(recQual)); - if (idx == -1) idx = 0; + if (idx == -1) + idx = 0; ui->simpleOutRecQuality->setCurrentIndex(idx); idx = ui->simpleOutStrEncoder->findData(QString(streamEnc)); - if (idx == -1) idx = 0; + if (idx == -1) + idx = 0; ui->simpleOutStrEncoder->setCurrentIndex(idx); idx = ui->simpleOutRecEncoder->findData(QString(recEnc)); - if (idx == -1) idx = 0; + if (idx == -1) + idx = 0; ui->simpleOutRecEncoder->setCurrentIndex(idx); ui->simpleOutMuxCustom->setText(muxCustom); @@ -1563,22 +1573,20 @@ void OBSBasicSettings::LoadSimpleOutputSettings() void OBSBasicSettings::LoadAdvOutputStreamingSettings() { - bool rescale = config_get_bool(main->Config(), "AdvOut", - "Rescale"); - const char *rescaleRes = config_get_string(main->Config(), "AdvOut", - "RescaleRes"); - int trackIndex = config_get_int(main->Config(), "AdvOut", - "TrackIndex"); + bool rescale = config_get_bool(main->Config(), "AdvOut", "Rescale"); + const char *rescaleRes = + config_get_string(main->Config(), "AdvOut", "RescaleRes"); + int trackIndex = config_get_int(main->Config(), "AdvOut", "TrackIndex"); bool applyServiceSettings = config_get_bool(main->Config(), "AdvOut", - "ApplyServiceSettings"); + "ApplyServiceSettings"); ui->advOutApplyService->setChecked(applyServiceSettings); ui->advOutUseRescale->setChecked(rescale); ui->advOutRescale->setEnabled(rescale); ui->advOutRescale->setCurrentText(rescaleRes); - QStringList specList = QTStr("FilenameFormatting.completer").split( - QRegularExpression("\n")); + QStringList specList = QTStr("FilenameFormatting.completer") + .split(QRegularExpression("\n")); QCompleter *specCompleter = new QCompleter(specList); specCompleter->setCaseSensitivity(Qt::CaseSensitive); specCompleter->setFilterMode(Qt::MatchContains); @@ -1586,17 +1594,30 @@ void OBSBasicSettings::LoadAdvOutputStreamingSettings() ui->filenameFormatting->setToolTip(QTStr("FilenameFormatting.TT")); switch (trackIndex) { - case 1: ui->advOutTrack1->setChecked(true); break; - case 2: ui->advOutTrack2->setChecked(true); break; - case 3: ui->advOutTrack3->setChecked(true); break; - case 4: ui->advOutTrack4->setChecked(true); break; - case 5: ui->advOutTrack5->setChecked(true); break; - case 6: ui->advOutTrack6->setChecked(true); break; + case 1: + ui->advOutTrack1->setChecked(true); + break; + case 2: + ui->advOutTrack2->setChecked(true); + break; + case 3: + ui->advOutTrack3->setChecked(true); + break; + case 4: + ui->advOutTrack4->setChecked(true); + break; + case 5: + ui->advOutTrack5->setChecked(true); + break; + case 6: + ui->advOutTrack6->setChecked(true); + break; } } -OBSPropertiesView *OBSBasicSettings::CreateEncoderPropertyView( - const char *encoder, const char *path, bool changed) +OBSPropertiesView * +OBSBasicSettings::CreateEncoderPropertyView(const char *encoder, + const char *path, bool changed) { obs_data_t *settings = obs_encoder_defaults(encoder); OBSPropertiesView *view; @@ -1604,18 +1625,18 @@ OBSPropertiesView *OBSBasicSettings::CreateEncoderPropertyView( if (path) { char encoderJsonPath[512]; int ret = GetProfilePath(encoderJsonPath, - sizeof(encoderJsonPath), path); + sizeof(encoderJsonPath), path); if (ret > 0) { obs_data_t *data = obs_data_create_from_json_file_safe( - encoderJsonPath, "bak"); + encoderJsonPath, "bak"); obs_data_apply(settings, data); obs_data_release(data); } } - view = new OBSPropertiesView(settings, encoder, - (PropertiesReloadCallback)obs_get_encoder_properties, - 170); + view = new OBSPropertiesView( + settings, encoder, + (PropertiesReloadCallback)obs_get_encoder_properties, 170); view->setFrameShape(QFrame::StyledPanel); view->setProperty("changed", QVariant(changed)); QObject::connect(view, SIGNAL(Changed()), this, SLOT(OutputsChanged())); @@ -1626,18 +1647,18 @@ OBSPropertiesView *OBSBasicSettings::CreateEncoderPropertyView( void OBSBasicSettings::LoadAdvOutputStreamingEncoderProperties() { - const char *type = config_get_string(main->Config(), "AdvOut", - "Encoder"); + const char *type = + config_get_string(main->Config(), "AdvOut", "Encoder"); delete streamEncoderProps; - streamEncoderProps = CreateEncoderPropertyView(type, - "streamEncoder.json"); + streamEncoderProps = + CreateEncoderPropertyView(type, "streamEncoder.json"); ui->advOutputStreamTab->layout()->addWidget(streamEncoderProps); - connect(streamEncoderProps, SIGNAL(Changed()), - this, SLOT(UpdateStreamDelayEstimate())); - connect(streamEncoderProps, SIGNAL(Changed()), - this, SLOT(AdvReplayBufferChanged())); + connect(streamEncoderProps, SIGNAL(Changed()), this, + SLOT(UpdateStreamDelayEstimate())); + connect(streamEncoderProps, SIGNAL(Changed()), this, + SLOT(AdvReplayBufferChanged())); curAdvStreamEncoder = type; @@ -1647,7 +1668,7 @@ void OBSBasicSettings::LoadAdvOutputStreamingEncoderProperties() const char *name = obs_encoder_get_display_name(type); ui->advOutEncoder->insertItem(0, QT_UTF8(name), - QT_UTF8(type)); + QT_UTF8(type)); SetComboByValue(ui->advOutEncoder, type); } } @@ -1657,20 +1678,19 @@ void OBSBasicSettings::LoadAdvOutputStreamingEncoderProperties() void OBSBasicSettings::LoadAdvOutputRecordingSettings() { - const char *type = config_get_string(main->Config(), "AdvOut", - "RecType"); - const char *format = config_get_string(main->Config(), "AdvOut", - "RecFormat"); - const char *path = config_get_string(main->Config(), "AdvOut", - "RecFilePath"); + const char *type = + config_get_string(main->Config(), "AdvOut", "RecType"); + const char *format = + config_get_string(main->Config(), "AdvOut", "RecFormat"); + const char *path = + config_get_string(main->Config(), "AdvOut", "RecFilePath"); bool noSpace = config_get_bool(main->Config(), "AdvOut", - "RecFileNameWithoutSpace"); - bool rescale = config_get_bool(main->Config(), "AdvOut", - "RecRescale"); - const char *rescaleRes = config_get_string(main->Config(), "AdvOut", - "RecRescaleRes"); - const char *muxCustom = config_get_string(main->Config(), "AdvOut", - "RecMuxerCustom"); + "RecFileNameWithoutSpace"); + bool rescale = config_get_bool(main->Config(), "AdvOut", "RecRescale"); + const char *rescaleRes = + config_get_string(main->Config(), "AdvOut", "RecRescaleRes"); + const char *muxCustom = + config_get_string(main->Config(), "AdvOut", "RecMuxerCustom"); int tracks = config_get_int(main->Config(), "AdvOut", "RecTracks"); int typeIndex = (astrcmpi(type, "FFmpeg") == 0) ? 1 : 0; @@ -1684,28 +1704,28 @@ void OBSBasicSettings::LoadAdvOutputRecordingSettings() int idx = ui->advOutRecFormat->findText(format); ui->advOutRecFormat->setCurrentIndex(idx); - ui->advOutRecTrack1->setChecked(tracks & (1<<0)); - ui->advOutRecTrack2->setChecked(tracks & (1<<1)); - ui->advOutRecTrack3->setChecked(tracks & (1<<2)); - ui->advOutRecTrack4->setChecked(tracks & (1<<3)); - ui->advOutRecTrack5->setChecked(tracks & (1<<4)); - ui->advOutRecTrack6->setChecked(tracks & (1<<5)); + ui->advOutRecTrack1->setChecked(tracks & (1 << 0)); + ui->advOutRecTrack2->setChecked(tracks & (1 << 1)); + ui->advOutRecTrack3->setChecked(tracks & (1 << 2)); + ui->advOutRecTrack4->setChecked(tracks & (1 << 3)); + ui->advOutRecTrack5->setChecked(tracks & (1 << 4)); + ui->advOutRecTrack6->setChecked(tracks & (1 << 5)); } void OBSBasicSettings::LoadAdvOutputRecordingEncoderProperties() { - const char *type = config_get_string(main->Config(), "AdvOut", - "RecEncoder"); + const char *type = + config_get_string(main->Config(), "AdvOut", "RecEncoder"); delete recordEncoderProps; recordEncoderProps = nullptr; if (astrcmpi(type, "none") != 0) { - recordEncoderProps = CreateEncoderPropertyView(type, - "recordEncoder.json"); + recordEncoderProps = + CreateEncoderPropertyView(type, "recordEncoder.json"); ui->advOutRecStandard->layout()->addWidget(recordEncoderProps); - connect(recordEncoderProps, SIGNAL(Changed()), - this, SLOT(AdvReplayBufferChanged())); + connect(recordEncoderProps, SIGNAL(Changed()), this, + SLOT(AdvReplayBufferChanged())); } curAdvRecordEncoder = type; @@ -1716,18 +1736,18 @@ void OBSBasicSettings::LoadAdvOutputRecordingEncoderProperties() const char *name = obs_encoder_get_display_name(type); ui->advOutRecEncoder->insertItem(1, QT_UTF8(name), - QT_UTF8(type)); + QT_UTF8(type)); SetComboByValue(ui->advOutRecEncoder, type); } } } static void SelectFormat(QComboBox *combo, const char *name, - const char *mimeType) + const char *mimeType) { FormatDesc formatDesc(name, mimeType); - for(int i = 0; i < combo->count(); i++) { + for (int i = 0; i < combo->count(); i++) { QVariant v = combo->itemData(i); if (!v.isNull()) { if (formatDesc == v.value()) { @@ -1749,45 +1769,43 @@ static void SelectEncoder(QComboBox *combo, const char *name, int id) void OBSBasicSettings::LoadAdvOutputFFmpegSettings() { - bool saveFile = config_get_bool(main->Config(), "AdvOut", - "FFOutputToFile"); - const char *path = config_get_string(main->Config(), "AdvOut", - "FFFilePath"); + bool saveFile = + config_get_bool(main->Config(), "AdvOut", "FFOutputToFile"); + const char *path = + config_get_string(main->Config(), "AdvOut", "FFFilePath"); bool noSpace = config_get_bool(main->Config(), "AdvOut", - "FFFileNameWithoutSpace"); + "FFFileNameWithoutSpace"); const char *url = config_get_string(main->Config(), "AdvOut", "FFURL"); - const char *format = config_get_string(main->Config(), "AdvOut", - "FFFormat"); - const char *mimeType = config_get_string(main->Config(), "AdvOut", - "FFFormatMimeType"); - const char *muxCustom = config_get_string(main->Config(), "AdvOut", - "FFMCustom"); - int videoBitrate = config_get_int(main->Config(), "AdvOut", - "FFVBitrate"); - int gopSize = config_get_int(main->Config(), "AdvOut", - "FFVGOPSize"); - bool rescale = config_get_bool(main->Config(), "AdvOut", - "FFRescale"); - bool codecCompat = config_get_bool(main->Config(), "AdvOut", - "FFIgnoreCompat"); - const char *rescaleRes = config_get_string(main->Config(), "AdvOut", - "FFRescaleRes"); - const char *vEncoder = config_get_string(main->Config(), "AdvOut", - "FFVEncoder"); - int vEncoderId = config_get_int(main->Config(), "AdvOut", - "FFVEncoderId"); - const char *vEncCustom = config_get_string(main->Config(), "AdvOut", - "FFVCustom"); - int audioBitrate = config_get_int(main->Config(), "AdvOut", - "FFABitrate"); - int audioMixes = config_get_int(main->Config(), "AdvOut", - "FFAudioMixes"); - const char *aEncoder = config_get_string(main->Config(), "AdvOut", - "FFAEncoder"); - int aEncoderId = config_get_int(main->Config(), "AdvOut", - "FFAEncoderId"); - const char *aEncCustom = config_get_string(main->Config(), "AdvOut", - "FFACustom"); + const char *format = + config_get_string(main->Config(), "AdvOut", "FFFormat"); + const char *mimeType = + config_get_string(main->Config(), "AdvOut", "FFFormatMimeType"); + const char *muxCustom = + config_get_string(main->Config(), "AdvOut", "FFMCustom"); + int videoBitrate = + config_get_int(main->Config(), "AdvOut", "FFVBitrate"); + int gopSize = config_get_int(main->Config(), "AdvOut", "FFVGOPSize"); + bool rescale = config_get_bool(main->Config(), "AdvOut", "FFRescale"); + bool codecCompat = + config_get_bool(main->Config(), "AdvOut", "FFIgnoreCompat"); + const char *rescaleRes = + config_get_string(main->Config(), "AdvOut", "FFRescaleRes"); + const char *vEncoder = + config_get_string(main->Config(), "AdvOut", "FFVEncoder"); + int vEncoderId = + config_get_int(main->Config(), "AdvOut", "FFVEncoderId"); + const char *vEncCustom = + config_get_string(main->Config(), "AdvOut", "FFVCustom"); + int audioBitrate = + config_get_int(main->Config(), "AdvOut", "FFABitrate"); + int audioMixes = + config_get_int(main->Config(), "AdvOut", "FFAudioMixes"); + const char *aEncoder = + config_get_string(main->Config(), "AdvOut", "FFAEncoder"); + int aEncoderId = + config_get_int(main->Config(), "AdvOut", "FFAEncoderId"); + const char *aEncCustom = + config_get_string(main->Config(), "AdvOut", "FFACustom"); ui->advOutFFType->setCurrentIndex(saveFile ? 0 : 1); ui->advOutFFRecPath->setText(QT_UTF8(path)); @@ -1817,30 +1835,30 @@ void OBSBasicSettings::LoadAdvOutputFFmpegSettings() void OBSBasicSettings::LoadAdvOutputAudioSettings() { - int track1Bitrate = config_get_uint(main->Config(), "AdvOut", - "Track1Bitrate"); - int track2Bitrate = config_get_uint(main->Config(), "AdvOut", - "Track2Bitrate"); - int track3Bitrate = config_get_uint(main->Config(), "AdvOut", - "Track3Bitrate"); - int track4Bitrate = config_get_uint(main->Config(), "AdvOut", - "Track4Bitrate"); - int track5Bitrate = config_get_uint(main->Config(), "AdvOut", - "Track5Bitrate"); - int track6Bitrate = config_get_uint(main->Config(), "AdvOut", - "Track6Bitrate"); - const char *name1 = config_get_string(main->Config(), "AdvOut", - "Track1Name"); - const char *name2 = config_get_string(main->Config(), "AdvOut", - "Track2Name"); - const char *name3 = config_get_string(main->Config(), "AdvOut", - "Track3Name"); - const char *name4 = config_get_string(main->Config(), "AdvOut", - "Track4Name"); - const char *name5 = config_get_string(main->Config(), "AdvOut", - "Track5Name"); - const char *name6 = config_get_string(main->Config(), "AdvOut", - "Track6Name"); + int track1Bitrate = + config_get_uint(main->Config(), "AdvOut", "Track1Bitrate"); + int track2Bitrate = + config_get_uint(main->Config(), "AdvOut", "Track2Bitrate"); + int track3Bitrate = + config_get_uint(main->Config(), "AdvOut", "Track3Bitrate"); + int track4Bitrate = + config_get_uint(main->Config(), "AdvOut", "Track4Bitrate"); + int track5Bitrate = + config_get_uint(main->Config(), "AdvOut", "Track5Bitrate"); + int track6Bitrate = + config_get_uint(main->Config(), "AdvOut", "Track6Bitrate"); + const char *name1 = + config_get_string(main->Config(), "AdvOut", "Track1Name"); + const char *name2 = + config_get_string(main->Config(), "AdvOut", "Track2Name"); + const char *name3 = + config_get_string(main->Config(), "AdvOut", "Track3Name"); + const char *name4 = + config_get_string(main->Config(), "AdvOut", "Track4Name"); + const char *name5 = + config_get_string(main->Config(), "AdvOut", "Track5Name"); + const char *name6 = + config_get_string(main->Config(), "AdvOut", "Track6Name"); track1Bitrate = FindClosestAvailableAACBitrate(track1Bitrate); track2Bitrate = FindClosestAvailableAACBitrate(track2Bitrate); @@ -1850,31 +1868,30 @@ void OBSBasicSettings::LoadAdvOutputAudioSettings() track6Bitrate = FindClosestAvailableAACBitrate(track6Bitrate); // restrict list of bitrates when multichannel is OFF - const char *speakers = config_get_string(main->Config(), "Audio", - "ChannelSetup"); + const char *speakers = + config_get_string(main->Config(), "Audio", "ChannelSetup"); // restrict list of bitrates when multichannel is OFF if (!IsSurround(speakers)) { - RestrictResetBitrates({ui->advOutTrack1Bitrate, - ui->advOutTrack2Bitrate, - ui->advOutTrack3Bitrate, - ui->advOutTrack4Bitrate, - ui->advOutTrack5Bitrate, - ui->advOutTrack6Bitrate}, 320); + RestrictResetBitrates( + {ui->advOutTrack1Bitrate, ui->advOutTrack2Bitrate, + ui->advOutTrack3Bitrate, ui->advOutTrack4Bitrate, + ui->advOutTrack5Bitrate, ui->advOutTrack6Bitrate}, + 320); } SetComboByName(ui->advOutTrack1Bitrate, - std::to_string(track1Bitrate).c_str()); + std::to_string(track1Bitrate).c_str()); SetComboByName(ui->advOutTrack2Bitrate, - std::to_string(track2Bitrate).c_str()); + std::to_string(track2Bitrate).c_str()); SetComboByName(ui->advOutTrack3Bitrate, - std::to_string(track3Bitrate).c_str()); + std::to_string(track3Bitrate).c_str()); SetComboByName(ui->advOutTrack4Bitrate, - std::to_string(track4Bitrate).c_str()); + std::to_string(track4Bitrate).c_str()); SetComboByName(ui->advOutTrack5Bitrate, - std::to_string(track5Bitrate).c_str()); + std::to_string(track5Bitrate).c_str()); SetComboByName(ui->advOutTrack6Bitrate, - std::to_string(track6Bitrate).c_str()); + std::to_string(track6Bitrate).c_str()); ui->advOutTrack1Name->setText(name1); ui->advOutTrack2Name->setText(name2); @@ -1916,12 +1933,11 @@ void OBSBasicSettings::LoadOutputSettings() loading = false; } -void OBSBasicSettings::SetAdvOutputFFmpegEnablement( - ff_codec_type encoderType, bool enabled, - bool enableEncoder) +void OBSBasicSettings::SetAdvOutputFFmpegEnablement(ff_codec_type encoderType, + bool enabled, + bool enableEncoder) { - bool rescale = config_get_bool(main->Config(), "AdvOut", - "FFRescale"); + bool rescale = config_get_bool(main->Config(), "AdvOut", "FFRescale"); switch (encoderType) { case FF_CODEC_VIDEO: @@ -1948,13 +1964,13 @@ void OBSBasicSettings::SetAdvOutputFFmpegEnablement( } static inline void LoadListValue(QComboBox *widget, const char *text, - const char *val) + const char *val) { widget->addItem(QT_UTF8(text), QT_UTF8(val)); } void OBSBasicSettings::LoadListValues(QComboBox *widget, obs_property_t *prop, - int index) + int index) { size_t count = obs_property_list_item_count(prop); @@ -1972,7 +1988,7 @@ void OBSBasicSettings::LoadListValues(QComboBox *widget, obs_property_t *prop, for (size_t i = 0; i < count; i++) { const char *name = obs_property_list_item_name(prop, i); - const char *val = obs_property_list_item_string(prop, i); + const char *val = obs_property_list_item_string(prop, i); LoadListValue(widget, name, val); } @@ -1983,9 +1999,9 @@ void OBSBasicSettings::LoadListValues(QComboBox *widget, obs_property_t *prop, widget->setCurrentIndex(idx); } else { widget->insertItem(0, - QTStr("Basic.Settings.Audio." - "UnknownAudioDevice"), - var); + QTStr("Basic.Settings.Audio." + "UnknownAudioDevice"), + var); widget->setCurrentIndex(0); } } @@ -1998,15 +2014,15 @@ void OBSBasicSettings::LoadListValues(QComboBox *widget, obs_property_t *prop, void OBSBasicSettings::LoadAudioDevices() { - const char *input_id = App()->InputAudioSource(); + const char *input_id = App()->InputAudioSource(); const char *output_id = App()->OutputAudioSource(); obs_properties_t *input_props = obs_get_source_properties(input_id); obs_properties_t *output_props = obs_get_source_properties(output_id); if (input_props) { - obs_property_t *inputs = obs_properties_get(input_props, - "device_id"); + obs_property_t *inputs = + obs_properties_get(input_props, "device_id"); LoadListValues(ui->auxAudioDevice1, inputs, 3); LoadListValues(ui->auxAudioDevice2, inputs, 4); LoadListValues(ui->auxAudioDevice3, inputs, 5); @@ -2015,8 +2031,8 @@ void OBSBasicSettings::LoadAudioDevices() } if (output_props) { - obs_property_t *outputs = obs_properties_get(output_props, - "device_id"); + obs_property_t *outputs = + obs_properties_get(output_props, "device_id"); LoadListValues(ui->desktopAudioDevice1, outputs, 1); LoadListValues(ui->desktopAudioDevice2, outputs, 2); obs_properties_destroy(output_props); @@ -2044,11 +2060,10 @@ void OBSBasicSettings::LoadAudioSources() ui->audioSourceLayout->addRow(widget); const char *enablePtm = Str("Basic.Settings.Audio.EnablePushToMute"); - const char *ptmDelay = Str("Basic.Settings.Audio.PushToMuteDelay"); + const char *ptmDelay = Str("Basic.Settings.Audio.PushToMuteDelay"); const char *enablePtt = Str("Basic.Settings.Audio.EnablePushToTalk"); - const char *pttDelay = Str("Basic.Settings.Audio.PushToTalkDelay"); - auto AddSource = [&](obs_source_t *source) - { + const char *pttDelay = Str("Basic.Settings.Audio.PushToTalkDelay"); + auto AddSource = [&](obs_source_t *source) { if (!(obs_source_get_output_flags(source) & OBS_SOURCE_AUDIO)) return true; @@ -2079,72 +2094,79 @@ void OBSBasicSettings::LoadAudioSources() pttSB->setValue(obs_source_get_push_to_talk_delay(source)); form->addRow(pttDelay, pttSB); - HookWidget(ptmCB, CHECK_CHANGED, AUDIO_CHANGED); + HookWidget(ptmCB, CHECK_CHANGED, AUDIO_CHANGED); HookWidget(ptmSB, SCROLL_CHANGED, AUDIO_CHANGED); - HookWidget(pttCB, CHECK_CHANGED, AUDIO_CHANGED); + HookWidget(pttCB, CHECK_CHANGED, AUDIO_CHANGED); HookWidget(pttSB, SCROLL_CHANGED, AUDIO_CHANGED); audioSourceSignals.reserve(audioSourceSignals.size() + 4); auto handler = obs_source_get_signal_handler(source); - audioSourceSignals.emplace_back(handler, "push_to_mute_changed", - [](void *data, calldata_t *param) - { - QMetaObject::invokeMethod(static_cast(data), - "setCheckedSilently", - Q_ARG(bool, calldata_bool(param, "enabled"))); - }, ptmCB); - audioSourceSignals.emplace_back(handler, "push_to_mute_delay", - [](void *data, calldata_t *param) - { - QMetaObject::invokeMethod(static_cast(data), - "setValueSilently", - Q_ARG(int, calldata_int(param, "delay"))); - }, ptmSB); - audioSourceSignals.emplace_back(handler, "push_to_talk_changed", - [](void *data, calldata_t *param) - { - QMetaObject::invokeMethod(static_cast(data), - "setCheckedSilently", - Q_ARG(bool, calldata_bool(param, "enabled"))); - }, pttCB); - audioSourceSignals.emplace_back(handler, "push_to_talk_delay", - [](void *data, calldata_t *param) - { - QMetaObject::invokeMethod(static_cast(data), - "setValueSilently", - Q_ARG(int, calldata_int(param, "delay"))); - }, pttSB); + audioSourceSignals.emplace_back( + handler, "push_to_mute_changed", + [](void *data, calldata_t *param) { + QMetaObject::invokeMethod( + static_cast(data), + "setCheckedSilently", + Q_ARG(bool, + calldata_bool(param, "enabled"))); + }, + ptmCB); + audioSourceSignals.emplace_back( + handler, "push_to_mute_delay", + [](void *data, calldata_t *param) { + QMetaObject::invokeMethod( + static_cast(data), + "setValueSilently", + Q_ARG(int, + calldata_int(param, "delay"))); + }, + ptmSB); + audioSourceSignals.emplace_back( + handler, "push_to_talk_changed", + [](void *data, calldata_t *param) { + QMetaObject::invokeMethod( + static_cast(data), + "setCheckedSilently", + Q_ARG(bool, + calldata_bool(param, "enabled"))); + }, + pttCB); + audioSourceSignals.emplace_back( + handler, "push_to_talk_delay", + [](void *data, calldata_t *param) { + QMetaObject::invokeMethod( + static_cast(data), + "setValueSilently", + Q_ARG(int, + calldata_int(param, "delay"))); + }, + pttSB); - audioSources.emplace_back(OBSGetWeakRef(source), - ptmCB, pttSB, pttCB, pttSB); + audioSources.emplace_back(OBSGetWeakRef(source), ptmCB, pttSB, + pttCB, pttSB); auto label = new OBSSourceLabel(source); label->setMinimumSize(QSize(170, 0)); - label->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter); + label->setAlignment(Qt::AlignRight | Qt::AlignTrailing | + Qt::AlignVCenter); connect(label, &OBSSourceLabel::Removed, - [=]() - { - LoadAudioSources(); - }); + [=]() { LoadAudioSources(); }); connect(label, &OBSSourceLabel::Destroyed, - [=]() - { - LoadAudioSources(); - }); + [=]() { LoadAudioSources(); }); layout->addRow(label, form); return true; }; using AddSource_t = decltype(AddSource); - obs_enum_sources([](void *data, obs_source_t *source) - { - auto &AddSource = *static_cast(data); - AddSource(source); - return true; - }, static_cast(&AddSource)); - + obs_enum_sources( + [](void *data, obs_source_t *source) { + auto &AddSource = *static_cast(data); + AddSource(source); + return true; + }, + static_cast(&AddSource)); if (layout->rowCount() == 0) ui->audioHotkeysGroupBox->hide(); @@ -2154,14 +2176,14 @@ void OBSBasicSettings::LoadAudioSources() void OBSBasicSettings::LoadAudioSettings() { - uint32_t sampleRate = config_get_uint(main->Config(), "Audio", - "SampleRate"); - const char *speakers = config_get_string(main->Config(), "Audio", - "ChannelSetup"); - double meterDecayRate = config_get_double(main->Config(), "Audio", - "MeterDecayRate"); - uint32_t peakMeterTypeIdx = config_get_uint(main->Config(), "Audio", - "PeakMeterType"); + uint32_t sampleRate = + config_get_uint(main->Config(), "Audio", "SampleRate"); + const char *speakers = + config_get_string(main->Config(), "Audio", "ChannelSetup"); + double meterDecayRate = + config_get_double(main->Config(), "Audio", "MeterDecayRate"); + uint32_t peakMeterTypeIdx = + config_get_uint(main->Config(), "Audio", "PeakMeterType"); loading = true; @@ -2207,48 +2229,44 @@ void OBSBasicSettings::LoadAudioSettings() void OBSBasicSettings::LoadAdvancedSettings() { - const char *videoColorFormat = config_get_string(main->Config(), - "Video", "ColorFormat"); - const char *videoColorSpace = config_get_string(main->Config(), - "Video", "ColorSpace"); - const char *videoColorRange = config_get_string(main->Config(), - "Video", "ColorRange"); + const char *videoColorFormat = + config_get_string(main->Config(), "Video", "ColorFormat"); + const char *videoColorSpace = + config_get_string(main->Config(), "Video", "ColorSpace"); + const char *videoColorRange = + config_get_string(main->Config(), "Video", "ColorRange"); #if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO const char *monDevName = config_get_string(main->Config(), "Audio", - "MonitoringDeviceName"); + "MonitoringDeviceName"); const char *monDevId = config_get_string(main->Config(), "Audio", - "MonitoringDeviceId"); + "MonitoringDeviceId"); #endif - bool enableDelay = config_get_bool(main->Config(), "Output", - "DelayEnable"); - int delaySec = config_get_int(main->Config(), "Output", - "DelaySec"); - bool preserveDelay = config_get_bool(main->Config(), "Output", - "DelayPreserve"); - bool reconnect = config_get_bool(main->Config(), "Output", - "Reconnect"); - int retryDelay = config_get_int(main->Config(), "Output", - "RetryDelay"); - int maxRetries = config_get_int(main->Config(), "Output", - "MaxRetries"); + bool enableDelay = + config_get_bool(main->Config(), "Output", "DelayEnable"); + int delaySec = config_get_int(main->Config(), "Output", "DelaySec"); + bool preserveDelay = + config_get_bool(main->Config(), "Output", "DelayPreserve"); + bool reconnect = config_get_bool(main->Config(), "Output", "Reconnect"); + int retryDelay = config_get_int(main->Config(), "Output", "RetryDelay"); + int maxRetries = config_get_int(main->Config(), "Output", "MaxRetries"); const char *filename = config_get_string(main->Config(), "Output", - "FilenameFormatting"); - bool overwriteIfExists = config_get_bool(main->Config(), "Output", - "OverwriteIfExists"); - const char *bindIP = config_get_string(main->Config(), "Output", - "BindIP"); + "FilenameFormatting"); + bool overwriteIfExists = + config_get_bool(main->Config(), "Output", "OverwriteIfExists"); + const char *bindIP = + config_get_string(main->Config(), "Output", "BindIP"); const char *rbPrefix = config_get_string(main->Config(), "SimpleOutput", - "RecRBPrefix"); + "RecRBPrefix"); const char *rbSuffix = config_get_string(main->Config(), "SimpleOutput", - "RecRBSuffix"); - bool replayBuf = config_get_bool(main->Config(), "AdvOut", - "RecRB"); - int rbTime = config_get_int(main->Config(), "AdvOut", - "RecRBTime"); - int rbSize = config_get_int(main->Config(), "AdvOut", - "RecRBSize"); - bool autoRemux = config_get_bool(main->Config(), "Video", - "AutoRemux"); + "RecRBSuffix"); + bool replayBuf = config_get_bool(main->Config(), "AdvOut", "RecRB"); + int rbTime = config_get_int(main->Config(), "AdvOut", "RecRBTime"); + int rbSize = config_get_int(main->Config(), "AdvOut", "RecRBSize"); + bool autoRemux = config_get_bool(main->Config(), "Video", "AutoRemux"); + const char *hotkeyFocusType = config_get_string( + App()->GlobalConfig(), "General", "HotkeyFocusType"); + bool dynBitrate = + config_get_bool(main->Config(), "Output", "DynamicBitrate"); loading = true; @@ -2276,7 +2294,7 @@ void OBSBasicSettings::LoadAdvancedSettings() ui->streamDelayPreserve->setChecked(preserveDelay); ui->streamDelayEnable->setChecked(enableDelay); ui->autoRemux->setChecked(autoRemux); - + ui->dynBitrate->setChecked(dynBitrate); SetComboByName(ui->colorFormat, videoColorFormat); SetComboByName(ui->colorSpace, videoColorSpace); @@ -2290,24 +2308,24 @@ void OBSBasicSettings::LoadAdvancedSettings() } #ifdef __APPLE__ - bool disableOSXVSync = config_get_bool(App()->GlobalConfig(), - "Video", "DisableOSXVSync"); - bool resetOSXVSync = config_get_bool(App()->GlobalConfig(), - "Video", "ResetOSXVSyncOnExit"); + bool disableOSXVSync = config_get_bool(App()->GlobalConfig(), "Video", + "DisableOSXVSync"); + bool resetOSXVSync = config_get_bool(App()->GlobalConfig(), "Video", + "ResetOSXVSyncOnExit"); ui->disableOSXVSync->setChecked(disableOSXVSync); ui->resetOSXVSync->setChecked(resetOSXVSync); ui->resetOSXVSync->setEnabled(disableOSXVSync); #elif _WIN32 - bool disableAudioDucking = config_get_bool(App()->GlobalConfig(), - "Audio", "DisableAudioDucking"); + bool disableAudioDucking = config_get_bool( + App()->GlobalConfig(), "Audio", "DisableAudioDucking"); ui->disableAudioDucking->setChecked(disableAudioDucking); - const char *processPriority = config_get_string(App()->GlobalConfig(), - "General", "ProcessPriority"); + const char *processPriority = config_get_string( + App()->GlobalConfig(), "General", "ProcessPriority"); bool enableNewSocketLoop = config_get_bool(main->Config(), "Output", - "NewSocketLoopEnable"); - bool enableLowLatencyMode = config_get_bool(main->Config(), "Output", - "LowLatencyEnable"); + "NewSocketLoopEnable"); + bool enableLowLatencyMode = + config_get_bool(main->Config(), "Output", "LowLatencyEnable"); int idx = ui->processPriority->findData(processPriority); if (idx == -1) @@ -2317,23 +2335,22 @@ void OBSBasicSettings::LoadAdvancedSettings() ui->enableNewSocketLoop->setChecked(enableNewSocketLoop); ui->enableLowLatencyMode->setChecked(enableLowLatencyMode); - bool browserHWAccel = config_get_bool(App()->GlobalConfig(), - "General", "BrowserHWAccel"); + bool browserHWAccel = config_get_bool(App()->GlobalConfig(), "General", + "BrowserHWAccel"); ui->browserHWAccel->setChecked(browserHWAccel); #endif - bool disableFocusHotkeys = config_get_bool(App()->GlobalConfig(), - "General", "DisableHotkeysInFocus"); - ui->disableFocusHotkeys->setChecked(disableFocusHotkeys); + SetComboByValue(ui->hotkeyFocusType, hotkeyFocusType); loading = false; } #define TRUNCATE_TEXT_LENGTH 80 -template -static inline void LayoutHotkey(obs_hotkey_id id, obs_hotkey_t *key, Func &&fun, - const map> &keys) +template +static inline void +LayoutHotkey(obs_hotkey_id id, obs_hotkey_t *key, Func &&fun, + const map> &keys) { auto *label = new OBSHotkeyLabel; QString text = QT_UTF8(obs_hotkey_get_description(key)); @@ -2353,7 +2370,7 @@ static inline void LayoutHotkey(obs_hotkey_id id, obs_hotkey_t *key, Func &&fun, hw = new OBSHotkeyWidget(id, obs_hotkey_get_name(key)); else hw = new OBSHotkeyWidget(id, obs_hotkey_get_name(key), - combos->second); + combos->second); hw->label = label; label->widget = hw; @@ -2361,13 +2378,13 @@ static inline void LayoutHotkey(obs_hotkey_id id, obs_hotkey_t *key, Func &&fun, fun(key, label, hw); } -template +template static QLabel *makeLabel(T &t, Func &&getName) { return new QLabel(getName(t)); } -template +template static QLabel *makeLabel(const OBSSource &source, Func &&) { OBSSourceLabel *label = new OBSSourceLabel(source); @@ -2385,30 +2402,26 @@ static QLabel *makeLabel(const OBSSource &source, Func &&) return label; } -template -static inline void AddHotkeys(QFormLayout &layout, - Func &&getName, std::vector< - std::tuple, QPointer> - > &hotkeys) +template +static inline void AddHotkeys( + QFormLayout &layout, Func &&getName, + std::vector, QPointer>> &hotkeys) { if (hotkeys.empty()) return; layout.setItem(layout.rowCount(), QFormLayout::SpanningRole, - new QSpacerItem(0, 10)); + new QSpacerItem(0, 10)); - using tuple_type = - std::tuple, QPointer>; + using tuple_type = std::tuple, QPointer>; stable_sort(begin(hotkeys), end(hotkeys), - [&](const tuple_type &a, const tuple_type &b) - { - const auto &o_a = get<0>(a); - const auto &o_b = get<0>(b); - return o_a != o_b && - string(getName(o_a)) < - getName(o_b); - }); + [&](const tuple_type &a, const tuple_type &b) { + const auto &o_a = get<0>(a); + const auto &o_b = get<0>(b); + return o_a != o_b && + string(getName(o_a)) < getName(o_b); + }); string prevName; for (const auto &hotkey : hotkeys) { @@ -2417,8 +2430,8 @@ static inline void AddHotkeys(QFormLayout &layout, if (prevName != name) { prevName = name; layout.setItem(layout.rowCount(), - QFormLayout::SpanningRole, - new QSpacerItem(0, 10)); + QFormLayout::SpanningRole, + new QSpacerItem(0, 10)); layout.addRow(makeLabel(o, getName)); } @@ -2435,22 +2448,24 @@ void OBSBasicSettings::LoadHotkeySettings(obs_hotkey_id ignoreKey) using keys_t = map>; keys_t keys; - obs_enum_hotkey_bindings([](void *data, - size_t, obs_hotkey_binding_t *binding) - { - auto &keys = *static_cast(data); + obs_enum_hotkey_bindings( + [](void *data, size_t, obs_hotkey_binding_t *binding) { + auto &keys = *static_cast(data); - keys[obs_hotkey_binding_get_hotkey_id(binding)].emplace_back( - obs_hotkey_binding_get_key_combination(binding)); + keys[obs_hotkey_binding_get_hotkey_id(binding)] + .emplace_back( + obs_hotkey_binding_get_key_combination( + binding)); - return true; - }, &keys); + return true; + }, + &keys); auto layout = new QFormLayout(); layout->setVerticalSpacing(0); layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); - layout->setLabelAlignment( - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + layout->setLabelAlignment(Qt::AlignRight | Qt::AlignTrailing | + Qt::AlignVCenter); auto widget = new QWidget(); widget->setLayout(layout); @@ -2476,11 +2491,11 @@ void OBSBasicSettings::LoadHotkeySettings(obs_hotkey_id ignoreKey) auto label = layout->itemAt(i, QFormLayout::LabelRole); if (label) { OBSHotkeyLabel *item = - qobject_cast( - label->widget()); - if(item) { - if (item->text().toLower() - .contains(text.toLower())) + qobject_cast( + label->widget()); + if (item) { + if (item->text().toLower().contains( + text.toLower())) setRowVisible(i, true, label); else setRowVisible(i, false, label); @@ -2489,8 +2504,7 @@ void OBSBasicSettings::LoadHotkeySettings(obs_hotkey_id ignoreKey) } }; - connect(filter, &QLineEdit::textChanged, - this, searchFunction); + connect(filter, &QLineEdit::textChanged, this, searchFunction); filterLayout->addWidget(filterLabel, 0, 0); filterLayout->addWidget(filter, 0, 1); @@ -2507,21 +2521,20 @@ void OBSBasicSettings::LoadHotkeySettings(obs_hotkey_id ignoreKey) using sources_elem_t = tuple, QPointer>; vector encoders; - vector outputs; + vector outputs; vector services; - vector scenes; - vector sources; + vector scenes; + vector sources; vector pairIds; - map> pairLabels; + map> pairLabels; using std::move; auto HandleEncoder = [&](void *registerer, OBSHotkeyLabel *label, - OBSHotkeyWidget *hw) - { + OBSHotkeyWidget *hw) { auto weak_encoder = - static_cast(registerer); + static_cast(registerer); auto encoder = OBSGetStrongRef(weak_encoder); if (!encoder) @@ -2532,9 +2545,8 @@ void OBSBasicSettings::LoadHotkeySettings(obs_hotkey_id ignoreKey) }; auto HandleOutput = [&](void *registerer, OBSHotkeyLabel *label, - OBSHotkeyWidget *hw) - { - auto weak_output = static_cast(registerer); + OBSHotkeyWidget *hw) { + auto weak_output = static_cast(registerer); auto output = OBSGetStrongRef(weak_output); if (!output) @@ -2545,10 +2557,9 @@ void OBSBasicSettings::LoadHotkeySettings(obs_hotkey_id ignoreKey) }; auto HandleService = [&](void *registerer, OBSHotkeyLabel *label, - OBSHotkeyWidget *hw) - { + OBSHotkeyWidget *hw) { auto weak_service = - static_cast(registerer); + static_cast(registerer); auto service = OBSGetStrongRef(weak_service); if (!service) @@ -2559,9 +2570,8 @@ void OBSBasicSettings::LoadHotkeySettings(obs_hotkey_id ignoreKey) }; auto HandleSource = [&](void *registerer, OBSHotkeyLabel *label, - OBSHotkeyWidget *hw) - { - auto weak_source = static_cast(registerer); + OBSHotkeyWidget *hw) { + auto weak_source = static_cast(registerer); auto source = OBSGetStrongRef(weak_source); if (!source) @@ -2576,15 +2586,14 @@ void OBSBasicSettings::LoadHotkeySettings(obs_hotkey_id ignoreKey) }; auto RegisterHotkey = [&](obs_hotkey_t *key, OBSHotkeyLabel *label, - OBSHotkeyWidget *hw) - { + OBSHotkeyWidget *hw) { auto registerer_type = obs_hotkey_get_registerer_type(key); - void *registerer = obs_hotkey_get_registerer(key); + void *registerer = obs_hotkey_get_registerer(key); obs_hotkey_id partner = obs_hotkey_get_pair_partner_id(key); if (partner != OBS_INVALID_HOTKEY_ID) { pairLabels.emplace(obs_hotkey_get_id(key), - make_pair(partner, label)); + make_pair(partner, label)); pairIds.push_back(obs_hotkey_get_id(key)); } @@ -2616,21 +2625,22 @@ void OBSBasicSettings::LoadHotkeySettings(obs_hotkey_id ignoreKey) break; } - hotkeys.emplace_back(registerer_type == - OBS_HOTKEY_REGISTERER_FRONTEND, hw); - connect(hw, &OBSHotkeyWidget::KeyChanged, - this, &OBSBasicSettings::HotkeysChanged); + hotkeys.emplace_back( + registerer_type == OBS_HOTKEY_REGISTERER_FRONTEND, hw); + connect(hw, &OBSHotkeyWidget::KeyChanged, this, + &OBSBasicSettings::HotkeysChanged); }; auto data = make_tuple(RegisterHotkey, std::move(keys), ignoreKey); using data_t = decltype(data); - obs_enum_hotkeys([](void *data, obs_hotkey_id id, obs_hotkey_t *key) - { - data_t &d = *static_cast(data); - if (id != get<2>(d)) - LayoutHotkey(id, key, get<0>(d), get<1>(d)); - return true; - }, &data); + obs_enum_hotkeys( + [](void *data, obs_hotkey_id id, obs_hotkey_t *key) { + data_t &d = *static_cast(data); + if (id != get<2>(d)) + LayoutHotkey(id, key, get<0>(d), get<1>(d)); + return true; + }, + &data); for (auto keyId : pairIds) { auto data1 = pairLabels.find(keyId); @@ -2654,9 +2664,10 @@ void OBSBasicSettings::LoadHotkeySettings(obs_hotkey_id ignoreKey) auto name2 = label2->text(); auto Update = [&](OBSHotkeyLabel *label, const QString &name, - OBSHotkeyLabel *other, const QString &otherName) - { - QString string = other->property("fullName").value(); + OBSHotkeyLabel *other, + const QString &otherName) { + QString string = + other->property("fullName").value(); if (string.isEmpty() || string.isNull()) string = otherName; @@ -2702,7 +2713,7 @@ void OBSBasicSettings::SaveGeneralSettings() if (WidgetChanged(ui->language)) config_set_string(GetGlobalConfig(), "General", "Language", - language.c_str()); + language.c_str()); int themeIndex = ui->theme->currentIndex(); QString themeData = ui->theme->itemText(themeIndex); @@ -2728,8 +2739,7 @@ void OBSBasicSettings::SaveGeneralSettings() ui->enableAutoUpdates->isChecked()); #endif if (WidgetChanged(ui->openStatsOnStartup)) - config_set_bool(main->Config(), "General", - "OpenStatsOnStartup", + config_set_bool(main->Config(), "General", "OpenStatsOnStartup", ui->openStatsOnStartup->isChecked()); if (WidgetChanged(ui->snappingEnabled)) config_set_bool(GetGlobalConfig(), "BasicWindow", @@ -2749,20 +2759,19 @@ void OBSBasicSettings::SaveGeneralSettings() ui->sourceSnapping->isChecked()); if (WidgetChanged(ui->snapDistance)) config_set_double(GetGlobalConfig(), "BasicWindow", - "SnapDistance", - ui->snapDistance->value()); + "SnapDistance", ui->snapDistance->value()); if (WidgetChanged(ui->overflowAlwaysVisible)) config_set_bool(GetGlobalConfig(), "BasicWindow", - "OverflowAlwaysVisible", - ui->overflowAlwaysVisible->isChecked()); + "OverflowAlwaysVisible", + ui->overflowAlwaysVisible->isChecked()); if (WidgetChanged(ui->overflowHide)) config_set_bool(GetGlobalConfig(), "BasicWindow", - "OverflowHidden", - ui->overflowHide->isChecked()); + "OverflowHidden", + ui->overflowHide->isChecked()); if (WidgetChanged(ui->overflowSelectionHide)) config_set_bool(GetGlobalConfig(), "BasicWindow", - "OverflowSelectionHidden", - ui->overflowSelectionHide->isChecked()); + "OverflowSelectionHidden", + ui->overflowSelectionHide->isChecked()); if (WidgetChanged(ui->doubleClickSwitch)) config_set_bool(GetGlobalConfig(), "BasicWindow", "TransitionOnDoubleClick", @@ -2774,9 +2783,11 @@ void OBSBasicSettings::SaveGeneralSettings() config_set_bool(GetGlobalConfig(), "BasicWindow", "WarnBeforeStoppingStream", ui->warnBeforeStreamStop->isChecked()); - config_set_bool(GetGlobalConfig(), "BasicWindow", - "HideProjectorCursor", + "WarnBeforeStoppingRecord", + ui->warnBeforeRecordStop->isChecked()); + + config_set_bool(GetGlobalConfig(), "BasicWindow", "HideProjectorCursor", ui->hideProjectorCursor->isChecked()); config_set_bool(GetGlobalConfig(), "BasicWindow", "ProjectorAlwaysOnTop", @@ -2793,12 +2804,12 @@ void OBSBasicSettings::SaveGeneralSettings() if (WidgetChanged(ui->replayWhileStreaming)) config_set_bool(GetGlobalConfig(), "BasicWindow", - "ReplayBufferWhileStreaming", - ui->replayWhileStreaming->isChecked()); + "ReplayBufferWhileStreaming", + ui->replayWhileStreaming->isChecked()); if (WidgetChanged(ui->keepReplayStreamStops)) config_set_bool(GetGlobalConfig(), "BasicWindow", - "KeepReplayBufferStreamStops", - ui->keepReplayStreamStops->isChecked()); + "KeepReplayBufferStreamStops", + ui->keepReplayStreamStops->isChecked()); if (WidgetChanged(ui->systemTrayEnabled)) config_set_bool(GetGlobalConfig(), "BasicWindow", @@ -2811,8 +2822,8 @@ void OBSBasicSettings::SaveGeneralSettings() ui->systemTrayWhenStarted->isChecked()); if (WidgetChanged(ui->systemTrayAlways)) - config_set_bool(GetGlobalConfig(), - "BasicWindow", "SysTrayMinimizeToTray", + config_set_bool(GetGlobalConfig(), "BasicWindow", + "SysTrayMinimizeToTray", ui->systemTrayAlways->isChecked()); if (WidgetChanged(ui->saveProjectors)) @@ -2860,8 +2871,8 @@ void OBSBasicSettings::SaveGeneralSettings() if (WidgetChanged(ui->multiviewLayout)) { config_set_int(GetGlobalConfig(), "BasicWindow", - "MultiviewLayout", - ui->multiviewLayout->currentData().toInt()); + "MultiviewLayout", + ui->multiviewLayout->currentData().toInt()); multiviewChanged = true; } @@ -2871,9 +2882,9 @@ void OBSBasicSettings::SaveGeneralSettings() void OBSBasicSettings::SaveVideoSettings() { - QString baseResolution = ui->baseResolution->currentText(); + QString baseResolution = ui->baseResolution->currentText(); QString outputResolution = ui->outputResolution->currentText(); - int fpsType = ui->fpsType->currentIndex(); + int fpsType = ui->fpsType->currentIndex(); uint32_t cx = 0, cy = 0; /* ------------------- */ @@ -2909,18 +2920,18 @@ void OBSBasicSettings::SaveVideoSettings() void OBSBasicSettings::SaveAdvancedSettings() { - QString lastMonitoringDevice = config_get_string(main->Config(), - "Audio", "MonitoringDeviceId"); + QString lastMonitoringDevice = config_get_string( + main->Config(), "Audio", "MonitoringDeviceId"); #ifdef _WIN32 if (WidgetChanged(ui->renderer)) config_set_string(App()->GlobalConfig(), "Video", "Renderer", - QT_TO_UTF8(ui->renderer->currentText())); + QT_TO_UTF8(ui->renderer->currentText())); std::string priority = QT_TO_UTF8(ui->processPriority->currentData().toString()); config_set_string(App()->GlobalConfig(), "General", "ProcessPriority", - priority.c_str()); + priority.c_str()); if (main->Active()) SetProcessPriority(priority.c_str()); @@ -2928,24 +2939,26 @@ void OBSBasicSettings::SaveAdvancedSettings() SaveCheckBox(ui->enableLowLatencyMode, "Output", "LowLatencyEnable"); bool browserHWAccel = ui->browserHWAccel->isChecked(); - config_set_bool(App()->GlobalConfig(), "General", - "BrowserHWAccel", browserHWAccel); + config_set_bool(App()->GlobalConfig(), "General", "BrowserHWAccel", + browserHWAccel); #endif - bool disableFocusHotkeys = ui->disableFocusHotkeys->isChecked(); - config_set_bool(App()->GlobalConfig(), "General", - "DisableHotkeysInFocus", disableFocusHotkeys); + if (WidgetChanged(ui->hotkeyFocusType)) { + QString str = GetComboData(ui->hotkeyFocusType); + config_set_string(App()->GlobalConfig(), "General", + "HotkeyFocusType", QT_TO_UTF8(str)); + } #ifdef __APPLE__ if (WidgetChanged(ui->disableOSXVSync)) { bool disable = ui->disableOSXVSync->isChecked(); - config_set_bool(App()->GlobalConfig(), - "Video", "DisableOSXVSync", disable); + config_set_bool(App()->GlobalConfig(), "Video", + "DisableOSXVSync", disable); EnableOSXVSync(!disable); } if (WidgetChanged(ui->resetOSXVSync)) - config_set_bool(App()->GlobalConfig(), - "Video", "ResetOSXVSyncOnExit", + config_set_bool(App()->GlobalConfig(), "Video", + "ResetOSXVSyncOnExit", ui->resetOSXVSync->isChecked()); #endif @@ -2960,8 +2973,8 @@ void OBSBasicSettings::SaveAdvancedSettings() #ifdef _WIN32 if (WidgetChanged(ui->disableAudioDucking)) { bool disable = ui->disableAudioDucking->isChecked(); - config_set_bool(App()->GlobalConfig(), - "Audio", "DisableAudioDucking", disable); + config_set_bool(App()->GlobalConfig(), "Audio", + "DisableAudioDucking", disable); DisableAudioDucking(disable); } #endif @@ -2978,18 +2991,19 @@ void OBSBasicSettings::SaveAdvancedSettings() SaveSpinBox(ui->reconnectMaxRetries, "Output", "MaxRetries"); SaveComboData(ui->bindToIP, "Output", "BindIP"); SaveCheckBox(ui->autoRemux, "Video", "AutoRemux"); + SaveCheckBox(ui->dynBitrate, "Output", "DynamicBitrate"); #if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO QString newDevice = ui->monitoringDevice->currentData().toString(); if (lastMonitoringDevice != newDevice) { obs_set_audio_monitoring_device( - QT_TO_UTF8(ui->monitoringDevice->currentText()), - QT_TO_UTF8(newDevice)); + QT_TO_UTF8(ui->monitoringDevice->currentText()), + QT_TO_UTF8(newDevice)); blog(LOG_INFO, "Audio monitoring device:\n\tname: %s\n\tid: %s", - QT_TO_UTF8(ui->monitoringDevice->currentText()), - QT_TO_UTF8(newDevice)); + QT_TO_UTF8(ui->monitoringDevice->currentText()), + QT_TO_UTF8(newDevice)); } #endif } @@ -3021,27 +3035,30 @@ static void WriteJsonData(OBSPropertiesView *view, const char *path) if (ret > 0) { obs_data_t *settings = view->GetSettings(); if (settings) { - obs_data_save_json_safe(settings, full_path, - "tmp", "bak"); + obs_data_save_json_safe(settings, full_path, "tmp", + "bak"); } } } static void SaveTrackIndex(config_t *config, const char *section, - const char *name, - QAbstractButton *check1, - QAbstractButton *check2, - QAbstractButton *check3, - QAbstractButton *check4, - QAbstractButton *check5, - QAbstractButton *check6) + const char *name, QAbstractButton *check1, + QAbstractButton *check2, QAbstractButton *check3, + QAbstractButton *check4, QAbstractButton *check5, + QAbstractButton *check6) { - if (check1->isChecked()) config_set_int(config, section, name, 1); - else if (check2->isChecked()) config_set_int(config, section, name, 2); - else if (check3->isChecked()) config_set_int(config, section, name, 3); - else if (check4->isChecked()) config_set_int(config, section, name, 4); - else if (check5->isChecked()) config_set_int(config, section, name, 5); - else if (check6->isChecked()) config_set_int(config, section, name, 6); + if (check1->isChecked()) + config_set_int(config, section, name, 1); + else if (check2->isChecked()) + config_set_int(config, section, name, 2); + else if (check3->isChecked()) + config_set_int(config, section, name, 3); + else if (check4->isChecked()) + config_set_int(config, section, name, 4); + else if (check5->isChecked()) + config_set_int(config, section, name, 5); + else if (check6->isChecked()) + config_set_int(config, section, name, 6); } void OBSBasicSettings::SaveFormat(QComboBox *combo) @@ -3050,9 +3067,9 @@ void OBSBasicSettings::SaveFormat(QComboBox *combo) if (!v.isNull()) { FormatDesc desc = v.value(); config_set_string(main->Config(), "AdvOut", "FFFormat", - desc.name); + desc.name); config_set_string(main->Config(), "AdvOut", "FFFormatMimeType", - desc.mimeType); + desc.mimeType); const char *ext = ff_format_desc_extensions(desc.desc); string extStr = ext ? ext : ""; @@ -3062,26 +3079,26 @@ void OBSBasicSettings::SaveFormat(QComboBox *combo) *comma = 0; config_set_string(main->Config(), "AdvOut", "FFExtension", - extStr.c_str()); + extStr.c_str()); } else { config_set_string(main->Config(), "AdvOut", "FFFormat", - nullptr); + nullptr); config_set_string(main->Config(), "AdvOut", "FFFormatMimeType", - nullptr); + nullptr); config_remove_value(main->Config(), "AdvOut", "FFExtension"); } } void OBSBasicSettings::SaveEncoder(QComboBox *combo, const char *section, - const char *value) + const char *value) { QVariant v = combo->currentData(); CodecDesc cd; if (!v.isNull()) cd = v.value(); config_set_int(main->Config(), section, - QT_TO_UTF8(QString("%1Id").arg(value)), cd.id); + QT_TO_UTF8(QString("%1Id").arg(value)), cd.id); if (cd.id != 0) config_set_string(main->Config(), section, value, cd.name); else @@ -3091,7 +3108,7 @@ void OBSBasicSettings::SaveEncoder(QComboBox *combo, const char *section, void OBSBasicSettings::SaveOutputSettings() { config_set_string(main->Config(), "Output", "Mode", - OutputModeFromIdx(ui->outputMode->currentIndex())); + OutputModeFromIdx(ui->outputMode->currentIndex())); QString encoder = ui->simpleOutStrEncoder->currentData().toString(); const char *presetType; @@ -3128,13 +3145,12 @@ void OBSBasicSettings::SaveOutputSettings() SaveComboData(ui->advOutEncoder, "AdvOut", "Encoder"); SaveCheckBox(ui->advOutUseRescale, "AdvOut", "Rescale"); SaveCombo(ui->advOutRescale, "AdvOut", "RescaleRes"); - SaveTrackIndex(main->Config(), "AdvOut", "TrackIndex", - ui->advOutTrack1, ui->advOutTrack2, - ui->advOutTrack3, ui->advOutTrack4, - ui->advOutTrack5, ui->advOutTrack6); + SaveTrackIndex(main->Config(), "AdvOut", "TrackIndex", ui->advOutTrack1, + ui->advOutTrack2, ui->advOutTrack3, ui->advOutTrack4, + ui->advOutTrack5, ui->advOutTrack6); config_set_string(main->Config(), "AdvOut", "RecType", - RecTypeFromIdx(ui->advOutRecType->currentIndex())); + RecTypeFromIdx(ui->advOutRecType->currentIndex())); curAdvRecordEncoder = GetComboData(ui->advOutRecEncoder); @@ -3146,13 +3162,14 @@ void OBSBasicSettings::SaveOutputSettings() SaveCombo(ui->advOutRecRescale, "AdvOut", "RecRescaleRes"); SaveEdit(ui->advOutMuxCustom, "AdvOut", "RecMuxerCustom"); - config_set_int(main->Config(), "AdvOut", "RecTracks", - (ui->advOutRecTrack1->isChecked() ? (1<<0) : 0) | - (ui->advOutRecTrack2->isChecked() ? (1<<1) : 0) | - (ui->advOutRecTrack3->isChecked() ? (1<<2) : 0) | - (ui->advOutRecTrack4->isChecked() ? (1<<3) : 0) | - (ui->advOutRecTrack5->isChecked() ? (1<<4) : 0) | - (ui->advOutRecTrack6->isChecked() ? (1<<5) : 0)); + config_set_int( + main->Config(), "AdvOut", "RecTracks", + (ui->advOutRecTrack1->isChecked() ? (1 << 0) : 0) | + (ui->advOutRecTrack2->isChecked() ? (1 << 1) : 0) | + (ui->advOutRecTrack3->isChecked() ? (1 << 2) : 0) | + (ui->advOutRecTrack4->isChecked() ? (1 << 3) : 0) | + (ui->advOutRecTrack5->isChecked() ? (1 << 4) : 0) | + (ui->advOutRecTrack6->isChecked() ? (1 << 5) : 0)); config_set_bool(main->Config(), "AdvOut", "FFOutputToFile", ui->advOutFFType->currentIndex() == 0 ? true : false); @@ -3171,8 +3188,9 @@ void OBSBasicSettings::SaveOutputSettings() SaveSpinBox(ui->advOutFFABitrate, "AdvOut", "FFABitrate"); SaveEncoder(ui->advOutFFAEncoder, "AdvOut", "FFAEncoder"); SaveEdit(ui->advOutFFACfg, "AdvOut", "FFACustom"); - config_set_int(main->Config(), "AdvOut", "FFAudioMixes", - (ui->advOutFFTrack1->isChecked() ? (1 << 0) : 0) | + config_set_int( + main->Config(), "AdvOut", "FFAudioMixes", + (ui->advOutFFTrack1->isChecked() ? (1 << 0) : 0) | (ui->advOutFFTrack2->isChecked() ? (1 << 1) : 0) | (ui->advOutFFTrack3->isChecked() ? (1 << 2) : 0) | (ui->advOutFFTrack4->isChecked() ? (1 << 3) : 0) | @@ -3202,8 +3220,8 @@ void OBSBasicSettings::SaveOutputSettings() void OBSBasicSettings::SaveAudioSettings() { - QString sampleRateStr = ui->sampleRate->currentText(); - int channelSetupIdx = ui->channelSetup->currentIndex(); + QString sampleRateStr = ui->sampleRate->currentText(); + int channelSetupIdx = ui->channelSetup->currentIndex(); const char *channelSetup; switch (channelSetupIdx) { @@ -3244,7 +3262,7 @@ void OBSBasicSettings::SaveAudioSettings() if (WidgetChanged(ui->channelSetup)) config_set_string(main->Config(), "Audio", "ChannelSetup", - channelSetup); + channelSetup); if (WidgetChanged(ui->meterDecayRate)) { double meterDecayRate; @@ -3263,7 +3281,7 @@ void OBSBasicSettings::SaveAudioSettings() break; } config_set_double(main->Config(), "Audio", "MeterDecayRate", - meterDecayRate); + meterDecayRate); main->UpdateVolumeControlsDecayRate(); } @@ -3277,14 +3295,14 @@ void OBSBasicSettings::SaveAudioSettings() } for (auto &audioSource : audioSources) { - auto source = OBSGetStrongRef(get<0>(audioSource)); + auto source = OBSGetStrongRef(get<0>(audioSource)); if (!source) continue; - auto &ptmCB = get<1>(audioSource); - auto &ptmSB = get<2>(audioSource); - auto &pttCB = get<3>(audioSource); - auto &pttSB = get<4>(audioSource); + auto &ptmCB = get<1>(audioSource); + auto &ptmSB = get<2>(audioSource); + auto &pttCB = get<3>(audioSource); + auto &pttSB = get<4>(audioSource); obs_source_enable_push_to_mute(source, ptmCB->isChecked()); obs_source_set_push_to_mute_delay(source, ptmSB->value()); @@ -3294,27 +3312,21 @@ void OBSBasicSettings::SaveAudioSettings() } auto UpdateAudioDevice = [this](bool input, QComboBox *combo, - const char *name, int index) - { - main->ResetAudioDevice( - input ? App()->InputAudioSource() - : App()->OutputAudioSource(), - QT_TO_UTF8(GetComboData(combo)), - Str(name), index); + const char *name, int index) { + main->ResetAudioDevice(input ? App()->InputAudioSource() + : App()->OutputAudioSource(), + QT_TO_UTF8(GetComboData(combo)), + Str(name), index); }; UpdateAudioDevice(false, ui->desktopAudioDevice1, - "Basic.DesktopDevice1", 1); + "Basic.DesktopDevice1", 1); UpdateAudioDevice(false, ui->desktopAudioDevice2, - "Basic.DesktopDevice2", 2); - UpdateAudioDevice(true, ui->auxAudioDevice1, - "Basic.AuxDevice1", 3); - UpdateAudioDevice(true, ui->auxAudioDevice2, - "Basic.AuxDevice2", 4); - UpdateAudioDevice(true, ui->auxAudioDevice3, - "Basic.AuxDevice3", 5); - UpdateAudioDevice(true, ui->auxAudioDevice4, - "Basic.AuxDevice4", 6); + "Basic.DesktopDevice2", 2); + UpdateAudioDevice(true, ui->auxAudioDevice1, "Basic.AuxDevice1", 3); + UpdateAudioDevice(true, ui->auxAudioDevice2, "Basic.AuxDevice2", 4); + UpdateAudioDevice(true, ui->auxAudioDevice3, "Basic.AuxDevice3", 5); + UpdateAudioDevice(true, ui->auxAudioDevice4, "Basic.AuxDevice4", 6); main->SaveProject(); } @@ -3350,15 +3362,14 @@ void OBSBasicSettings::SaveHotkeySettings() const char *id = obs_obj_get_id(main->outputHandler->replayBuffer); if (strcmp(id, "replay_buffer") == 0) { obs_data_t *hotkeys = obs_hotkeys_save_output( - main->outputHandler->replayBuffer); + main->outputHandler->replayBuffer); config_set_string(config, "Hotkeys", "ReplayBuffer", - obs_data_get_json(hotkeys)); + obs_data_get_json(hotkeys)); obs_data_release(hotkeys); } } -#define MINOR_SEPARATOR \ - "------------------------------------------------" +#define MINOR_SEPARATOR "------------------------------------------------" static void AddChangedVal(std::string &changed, const char *str) { @@ -3417,11 +3428,10 @@ bool OBSBasicSettings::QueryChanges() { QMessageBox::StandardButton button; - button = OBSMessageBox::question(this, - QTStr("Basic.Settings.ConfirmTitle"), - QTStr("Basic.Settings.Confirm"), - QMessageBox::Yes | QMessageBox::No | - QMessageBox::Cancel); + button = OBSMessageBox::question( + this, QTStr("Basic.Settings.ConfirmTitle"), + QTStr("Basic.Settings.Confirm"), + QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); if (button == QMessageBox::Cancel) { return false; @@ -3496,11 +3506,10 @@ void OBSBasicSettings::on_buttonBox_clicked(QAbstractButton *button) void OBSBasicSettings::on_simpleOutputBrowse_clicked() { - QString dir = QFileDialog::getExistingDirectory(this, - QTStr("Basic.Settings.Output.SelectDirectory"), - ui->simpleOutputPath->text(), - QFileDialog::ShowDirsOnly | - QFileDialog::DontResolveSymlinks); + QString dir = QFileDialog::getExistingDirectory( + this, QTStr("Basic.Settings.Output.SelectDirectory"), + ui->simpleOutputPath->text(), + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if (dir.isEmpty()) return; @@ -3509,11 +3518,10 @@ void OBSBasicSettings::on_simpleOutputBrowse_clicked() void OBSBasicSettings::on_advOutRecPathBrowse_clicked() { - QString dir = QFileDialog::getExistingDirectory(this, - QTStr("Basic.Settings.Output.SelectDirectory"), - ui->advOutRecPath->text(), - QFileDialog::ShowDirsOnly | - QFileDialog::DontResolveSymlinks); + QString dir = QFileDialog::getExistingDirectory( + this, QTStr("Basic.Settings.Output.SelectDirectory"), + ui->advOutRecPath->text(), + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if (dir.isEmpty()) return; @@ -3522,11 +3530,10 @@ void OBSBasicSettings::on_advOutRecPathBrowse_clicked() void OBSBasicSettings::on_advOutFFPathBrowse_clicked() { - QString dir = QFileDialog::getExistingDirectory(this, - QTStr("Basic.Settings.Output.SelectDirectory"), - ui->advOutRecPath->text(), - QFileDialog::ShowDirsOnly | - QFileDialog::DontResolveSymlinks); + QString dir = QFileDialog::getExistingDirectory( + this, QTStr("Basic.Settings.Output.SelectDirectory"), + ui->advOutRecPath->text(), + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if (dir.isEmpty()) return; @@ -3541,9 +3548,8 @@ void OBSBasicSettings::on_advOutEncoder_currentIndexChanged(int idx) delete streamEncoderProps; streamEncoderProps = CreateEncoderPropertyView( - QT_TO_UTF8(encoder), - loadSettings ? "streamEncoder.json" : nullptr, - true); + QT_TO_UTF8(encoder), + loadSettings ? "streamEncoder.json" : nullptr, true); ui->advOutputStreamTab->layout()->addWidget(streamEncoderProps); } @@ -3580,12 +3586,11 @@ void OBSBasicSettings::on_advOutRecEncoder_currentIndexChanged(int idx) if (!loading) { recordEncoderProps = CreateEncoderPropertyView( - QT_TO_UTF8(encoder), - loadSettings ? "recordEncoder.json" : nullptr, - true); + QT_TO_UTF8(encoder), + loadSettings ? "recordEncoder.json" : nullptr, true); ui->advOutRecStandard->layout()->addWidget(recordEncoderProps); - connect(recordEncoderProps, SIGNAL(Changed()), - this, SLOT(AdvReplayBufferChanged())); + connect(recordEncoderProps, SIGNAL(Changed()), this, + SLOT(AdvReplayBufferChanged())); } uint32_t caps = obs_get_encoder_caps(QT_TO_UTF8(encoder)); @@ -3604,7 +3609,7 @@ void OBSBasicSettings::on_advOutFFIgnoreCompat_stateChanged(int) { /* Little hack to reload codecs when checked */ on_advOutFFFormat_currentIndexChanged( - ui->advOutFFFormat->currentIndex()); + ui->advOutFFFormat->currentIndex()); } #define DEFAULT_CONTAINER_STR \ @@ -3616,24 +3621,24 @@ void OBSBasicSettings::on_advOutFFFormat_currentIndexChanged(int idx) if (!itemDataVariant.isNull()) { FormatDesc desc = itemDataVariant.value(); - SetAdvOutputFFmpegEnablement(FF_CODEC_AUDIO, - ff_format_desc_has_audio(desc.desc), - false); - SetAdvOutputFFmpegEnablement(FF_CODEC_VIDEO, - ff_format_desc_has_video(desc.desc), - false); + SetAdvOutputFFmpegEnablement( + FF_CODEC_AUDIO, ff_format_desc_has_audio(desc.desc), + false); + SetAdvOutputFFmpegEnablement( + FF_CODEC_VIDEO, ff_format_desc_has_video(desc.desc), + false); ReloadCodecs(desc.desc); - ui->advOutFFFormatDesc->setText(ff_format_desc_long_name( - desc.desc)); + ui->advOutFFFormatDesc->setText( + ff_format_desc_long_name(desc.desc)); CodecDesc defaultAudioCodecDesc = GetDefaultCodecDesc(desc.desc, FF_CODEC_AUDIO); CodecDesc defaultVideoCodecDesc = GetDefaultCodecDesc(desc.desc, FF_CODEC_VIDEO); SelectEncoder(ui->advOutFFAEncoder, defaultAudioCodecDesc.name, - defaultAudioCodecDesc.id); + defaultAudioCodecDesc.id); SelectEncoder(ui->advOutFFVEncoder, defaultVideoCodecDesc.name, - defaultVideoCodecDesc.id); + defaultVideoCodecDesc.id); } else { ReloadCodecs(nullptr); ui->advOutFFFormatDesc->setText(DEFAULT_CONTAINER_STR); @@ -3645,8 +3650,9 @@ void OBSBasicSettings::on_advOutFFAEncoder_currentIndexChanged(int idx) const QVariant itemDataVariant = ui->advOutFFAEncoder->itemData(idx); if (!itemDataVariant.isNull()) { CodecDesc desc = itemDataVariant.value(); - SetAdvOutputFFmpegEnablement(FF_CODEC_AUDIO, - desc.id != 0 || desc.name != nullptr, true); + SetAdvOutputFFmpegEnablement( + FF_CODEC_AUDIO, desc.id != 0 || desc.name != nullptr, + true); } } @@ -3655,8 +3661,9 @@ void OBSBasicSettings::on_advOutFFVEncoder_currentIndexChanged(int idx) const QVariant itemDataVariant = ui->advOutFFVEncoder->itemData(idx); if (!itemDataVariant.isNull()) { CodecDesc desc = itemDataVariant.value(); - SetAdvOutputFFmpegEnablement(FF_CODEC_VIDEO, - desc.id != 0 || desc.name != nullptr, true); + SetAdvOutputFFmpegEnablement( + FF_CODEC_VIDEO, desc.id != 0 || desc.name != nullptr, + true); } } @@ -3673,14 +3680,14 @@ void OBSBasicSettings::on_colorFormat_currentIndexChanged(const QString &text) ui->advancedMsg2->setText(QString()); else ui->advancedMsg2->setText( - QTStr("Basic.Settings.Advanced.FormatWarning")); + QTStr("Basic.Settings.Advanced.FormatWarning")); } #define INVALID_RES_STR "Basic.Settings.Video.InvalidResolution" static bool ValidResolutions(Ui::OBSBasicSettings *ui) { - QString baseRes = ui->baseResolution->lineEdit()->text(); + QString baseRes = ui->baseResolution->lineEdit()->text(); QString outputRes = ui->outputResolution->lineEdit()->text(); uint32_t cx, cy; @@ -3707,15 +3714,12 @@ void OBSBasicSettings::RecalcOutputResPixels(const char *resText) } } - void OBSBasicSettings::on_filenameFormatting_textEdited(const QString &text) { #ifdef __APPLE__ - size_t invalidLocation = - text.toStdString().find_first_of(":"); -#elif _WIN32 - size_t invalidLocation = - text.toStdString().find_first_of("<>:\"|?*"); + size_t invalidLocation = text.toStdString().find_first_of(":"); +#elif _WIN32 + size_t invalidLocation = text.toStdString().find_first_of("<>:\"|?*"); #else size_t invalidLocation = string::npos; UNUSED_PARAMETER(text); @@ -3802,34 +3806,30 @@ void OBSBasicSettings::SpeakerLayoutChanged(int idx) bool surround = IsSurround(speakerLayout.c_str()); if (surround) { - QString warning = - QTStr(MULTI_CHANNEL_WARNING ".Enabled") + - QStringLiteral("\n\n") + - QTStr(MULTI_CHANNEL_WARNING); + QString warning = QTStr(MULTI_CHANNEL_WARNING ".Enabled") + + QStringLiteral("\n\n") + + QTStr(MULTI_CHANNEL_WARNING); /* * Display all bitrates */ ui->audioMsg_2->setText(warning); - PopulateAACBitrates({ui->simpleOutputABitrate, - ui->advOutTrack1Bitrate, - ui->advOutTrack2Bitrate, - ui->advOutTrack3Bitrate, - ui->advOutTrack4Bitrate, - ui->advOutTrack5Bitrate, - ui->advOutTrack6Bitrate}); + PopulateAACBitrates( + {ui->simpleOutputABitrate, ui->advOutTrack1Bitrate, + ui->advOutTrack2Bitrate, ui->advOutTrack3Bitrate, + ui->advOutTrack4Bitrate, ui->advOutTrack5Bitrate, + ui->advOutTrack6Bitrate}); } else { /* * Reset audio bitrate for simple and adv mode, update list of * bitrates and save setting. */ ui->audioMsg_2->setText(QString()); - RestrictResetBitrates({ui->simpleOutputABitrate, - ui->advOutTrack1Bitrate, - ui->advOutTrack2Bitrate, - ui->advOutTrack3Bitrate, - ui->advOutTrack4Bitrate, - ui->advOutTrack5Bitrate, - ui->advOutTrack6Bitrate}, 320); + RestrictResetBitrates( + {ui->simpleOutputABitrate, ui->advOutTrack1Bitrate, + ui->advOutTrack2Bitrate, ui->advOutTrack3Bitrate, + ui->advOutTrack4Bitrate, ui->advOutTrack5Bitrate, + ui->advOutTrack6Bitrate}, + 320); SaveCombo(ui->simpleOutputABitrate, "SimpleOutput", "ABitrate"); SaveCombo(ui->advOutTrack1Bitrate, "AdvOut", "Track1Bitrate"); @@ -3846,23 +3846,23 @@ void OBSBasicSettings::SpeakerLayoutChanged(int idx) * displayed when multichannel OFF */ -void RestrictResetBitrates(initializer_list boxes, int maxbitrate) +void RestrictResetBitrates(initializer_list boxes, int maxbitrate) { for (auto box : boxes) { int idx = box->currentIndex(); int max_bitrate = FindClosestAvailableAACBitrate(maxbitrate); int count = box->count(); - int max_idx = box->findText(QT_UTF8(std::to_string - (max_bitrate).c_str())); + int max_idx = box->findText( + QT_UTF8(std::to_string(max_bitrate).c_str())); for (int i = (count - 1); i > max_idx; i--) box->removeItem(i); if (idx > max_idx) { - int default_bitrate = FindClosestAvailableAACBitrate( - maxbitrate / 2); - int default_idx = box->findText(QT_UTF8(std::to_string - (default_bitrate).c_str())); + int default_bitrate = + FindClosestAvailableAACBitrate(maxbitrate / 2); + int default_idx = box->findText(QT_UTF8( + std::to_string(default_bitrate).c_str())); box->setCurrentIndex(default_idx); box->setProperty("changed", QVariant(true)); @@ -3887,7 +3887,7 @@ void OBSBasicSettings::AdvancedChangedRestart() if (!loading) { advancedChanged = true; ui->advancedMsg->setText( - QTStr("Basic.Settings.ProgramRestart")); + QTStr("Basic.Settings.ProgramRestart")); sender()->setProperty("changed", QVariant(true)); EnableApplyButton(true); } @@ -3917,12 +3917,12 @@ void OBSBasicSettings::HotkeysChanged() if (loading) return; - hotkeysChanged = any_of(begin(hotkeys), end(hotkeys), - [](const pair> &hotkey) - { - const auto &hw = *hotkey.second; - return hw.Changed(); - }); + hotkeysChanged = + any_of(begin(hotkeys), end(hotkeys), + [](const pair> &hotkey) { + const auto &hw = *hotkey.second; + return hw.Changed(); + }); if (hotkeysChanged) EnableApplyButton(true); @@ -3944,20 +3944,14 @@ void OBSBasicSettings::AdvancedChanged() void OBSBasicSettings::AdvOutRecCheckWarnings() { - auto Checked = [](QCheckBox *box) - { - return box->isChecked() ? 1 : 0; - }; + auto Checked = [](QCheckBox *box) { return box->isChecked() ? 1 : 0; }; QString errorMsg; QString warningMsg; uint32_t tracks = - Checked(ui->advOutRecTrack1) + - Checked(ui->advOutRecTrack2) + - Checked(ui->advOutRecTrack3) + - Checked(ui->advOutRecTrack4) + - Checked(ui->advOutRecTrack5) + - Checked(ui->advOutRecTrack6); + Checked(ui->advOutRecTrack1) + Checked(ui->advOutRecTrack2) + + Checked(ui->advOutRecTrack3) + Checked(ui->advOutRecTrack4) + + Checked(ui->advOutRecTrack5) + Checked(ui->advOutRecTrack6); if (tracks == 0) { errorMsg = QTStr("OutputWarnings.NoTracksSelected"); @@ -3966,33 +3960,37 @@ void OBSBasicSettings::AdvOutRecCheckWarnings() warningMsg = QTStr("OutputWarnings.MultiTrackRecording"); } + bool useStreamEncoder = ui->advOutRecEncoder->currentIndex() == 0; + if (useStreamEncoder) { + if (!warningMsg.isEmpty()) + warningMsg += "\n\n"; + warningMsg += QTStr("OutputWarnings.CannotPause"); + } + if (ui->advOutRecFormat->currentText().compare("mp4") == 0 || ui->advOutRecFormat->currentText().compare("mov") == 0) { if (!warningMsg.isEmpty()) warningMsg += "\n\n"; warningMsg += QTStr("OutputWarnings.MP4Recording"); ui->autoRemux->setText( - QTStr("Basic.Settings.Advanced.AutoRemux") - + " " + - QTStr("Basic.Settings.Advanced.AutoRemux.MP4")); + QTStr("Basic.Settings.Advanced.AutoRemux") + " " + + QTStr("Basic.Settings.Advanced.AutoRemux.MP4")); } else { ui->autoRemux->setText( - QTStr("Basic.Settings.Advanced.AutoRemux")); + QTStr("Basic.Settings.Advanced.AutoRemux")); } delete advOutRecWarning; if (!errorMsg.isEmpty() || !warningMsg.isEmpty()) { advOutRecWarning = new QLabel( - errorMsg.isEmpty() ? warningMsg : errorMsg, - this); + errorMsg.isEmpty() ? warningMsg : errorMsg, this); advOutRecWarning->setObjectName( - errorMsg.isEmpty() ? "warningLabel" : - "errorLabel"); + errorMsg.isEmpty() ? "warningLabel" : "errorLabel"); advOutRecWarning->setWordWrap(true); - QFormLayout *formLayout = reinterpret_cast( - ui->advOutRecTopContainer->layout()); + QFormLayout *formLayout = reinterpret_cast( + ui->advOutRecTopContainer->layout()); formLayout->addRow(nullptr, advOutRecWarning); } @@ -4027,12 +4025,24 @@ void OBSBasicSettings::UpdateAdvOutStreamDelayEstimate() QString aBitrateText; switch (trackIndex) { - case 1: aBitrateText = ui->advOutTrack1Bitrate->currentText(); break; - case 2: aBitrateText = ui->advOutTrack2Bitrate->currentText(); break; - case 3: aBitrateText = ui->advOutTrack3Bitrate->currentText(); break; - case 4: aBitrateText = ui->advOutTrack4Bitrate->currentText(); break; - case 5: aBitrateText = ui->advOutTrack5Bitrate->currentText(); break; - case 6: aBitrateText = ui->advOutTrack6Bitrate->currentText(); break; + case 1: + aBitrateText = ui->advOutTrack1Bitrate->currentText(); + break; + case 2: + aBitrateText = ui->advOutTrack2Bitrate->currentText(); + break; + case 3: + aBitrateText = ui->advOutTrack3Bitrate->currentText(); + break; + case 4: + aBitrateText = ui->advOutTrack4Bitrate->currentText(); + break; + case 5: + aBitrateText = ui->advOutTrack5Bitrate->currentText(); + break; + case 6: + aBitrateText = ui->advOutTrack6Bitrate->currentText(); + break; } int seconds = ui->streamDelaySec->value(); @@ -4068,11 +4078,10 @@ bool EncoderAvailable(const char *encoder) void OBSBasicSettings::FillSimpleRecordingValues() { -#define ADD_QUALITY(str) \ - ui->simpleOutRecQuality->addItem( \ - QTStr("Basic.Settings.Output.Simple.RecordingQuality." \ - str), \ - QString(str)); +#define ADD_QUALITY(str) \ + ui->simpleOutRecQuality->addItem( \ + QTStr("Basic.Settings.Output.Simple.RecordingQuality." str), \ + QString(str)); #define ENCODER_STR(str) QTStr("Basic.Settings.Output.Simple.Encoder." str) ADD_QUALITY("Stream"); @@ -4080,44 +4089,35 @@ void OBSBasicSettings::FillSimpleRecordingValues() ADD_QUALITY("HQ"); ADD_QUALITY("Lossless"); - ui->simpleOutRecEncoder->addItem( - ENCODER_STR("Software"), - QString(SIMPLE_ENCODER_X264)); - ui->simpleOutRecEncoder->addItem( - ENCODER_STR("SoftwareLowCPU"), - QString(SIMPLE_ENCODER_X264_LOWCPU)); + ui->simpleOutRecEncoder->addItem(ENCODER_STR("Software"), + QString(SIMPLE_ENCODER_X264)); + ui->simpleOutRecEncoder->addItem(ENCODER_STR("SoftwareLowCPU"), + QString(SIMPLE_ENCODER_X264_LOWCPU)); if (EncoderAvailable("obs_qsv11")) - ui->simpleOutRecEncoder->addItem( - ENCODER_STR("Hardware.QSV"), - QString(SIMPLE_ENCODER_QSV)); + ui->simpleOutRecEncoder->addItem(ENCODER_STR("Hardware.QSV"), + QString(SIMPLE_ENCODER_QSV)); if (EncoderAvailable("ffmpeg_nvenc")) - ui->simpleOutRecEncoder->addItem( - ENCODER_STR("Hardware.NVENC"), - QString(SIMPLE_ENCODER_NVENC)); + ui->simpleOutRecEncoder->addItem(ENCODER_STR("Hardware.NVENC"), + QString(SIMPLE_ENCODER_NVENC)); if (EncoderAvailable("amd_amf_h264")) - ui->simpleOutRecEncoder->addItem( - ENCODER_STR("Hardware.AMD"), - QString(SIMPLE_ENCODER_AMD)); + ui->simpleOutRecEncoder->addItem(ENCODER_STR("Hardware.AMD"), + QString(SIMPLE_ENCODER_AMD)); #undef ADD_QUALITY } void OBSBasicSettings::FillSimpleStreamingValues() { - ui->simpleOutStrEncoder->addItem( - ENCODER_STR("Software"), - QString(SIMPLE_ENCODER_X264)); + ui->simpleOutStrEncoder->addItem(ENCODER_STR("Software"), + QString(SIMPLE_ENCODER_X264)); if (EncoderAvailable("obs_qsv11")) - ui->simpleOutStrEncoder->addItem( - ENCODER_STR("Hardware.QSV"), - QString(SIMPLE_ENCODER_QSV)); + ui->simpleOutStrEncoder->addItem(ENCODER_STR("Hardware.QSV"), + QString(SIMPLE_ENCODER_QSV)); if (EncoderAvailable("ffmpeg_nvenc")) - ui->simpleOutStrEncoder->addItem( - ENCODER_STR("Hardware.NVENC"), - QString(SIMPLE_ENCODER_NVENC)); + ui->simpleOutStrEncoder->addItem(ENCODER_STR("Hardware.NVENC"), + QString(SIMPLE_ENCODER_NVENC)); if (EncoderAvailable("amd_amf_h264")) - ui->simpleOutStrEncoder->addItem( - ENCODER_STR("Hardware.AMD"), - QString(SIMPLE_ENCODER_AMD)); + ui->simpleOutStrEncoder->addItem(ENCODER_STR("Hardware.AMD"), + QString(SIMPLE_ENCODER_AMD)); #undef ENCODER_STR } @@ -4125,15 +4125,15 @@ void OBSBasicSettings::FillAudioMonitoringDevices() { QComboBox *cb = ui->monitoringDevice; - auto enum_devices = [] (void *param, const char *name, const char *id) - { - QComboBox *cb = (QComboBox*)param; + auto enum_devices = [](void *param, const char *name, const char *id) { + QComboBox *cb = (QComboBox *)param; cb->addItem(name, id); return true; }; cb->addItem(QTStr("Basic.Settings.Advanced.Audio.MonitoringDevice" - ".Default"), "default"); + ".Default"), + "default"); obs_enum_audio_monitoring_devices(enum_devices, cb); } @@ -4178,7 +4178,7 @@ void OBSBasicSettings::SimpleStreamingEncoderChanged() size_t num = obs_property_list_item_count(p); for (size_t i = 0; i < num; i++) { const char *name = obs_property_list_item_name(p, i); - const char *val = obs_property_list_item_string(p, i); + const char *val = obs_property_list_item_string(p, i); /* bluray is for ideal bluray disc recording settings, * not streaming */ @@ -4240,8 +4240,8 @@ void OBSBasicSettings::UpdateAutomaticReplayBufferCheckboxes() break; } ui->replayWhileStreaming->setEnabled(state); - ui->keepReplayStreamStops->setEnabled(state && - ui->replayWhileStreaming->isChecked()); + ui->keepReplayStreamStops->setEnabled( + state && ui->replayWhileStreaming->isChecked()); } void OBSBasicSettings::SimpleReplayBufferChanged() @@ -4258,14 +4258,14 @@ void OBSBasicSettings::SimpleReplayBufferChanged() int abitrate = ui->simpleOutputABitrate->currentText().toInt(); int seconds = ui->simpleRBSecMax->value(); - int64_t memMB = int64_t(seconds) * int64_t(vbitrate + abitrate) * - 1000 / 8 / 1024 / 1024; - if (memMB < 1) memMB = 1; + int64_t memMB = int64_t(seconds) * int64_t(vbitrate + abitrate) * 1000 / + 8 / 1024 / 1024; + if (memMB < 1) + memMB = 1; if (streamQuality) ui->simpleRBEstimate->setText( - QTStr(ESTIMATE_STR).arg( - QString::number(int(memMB)))); + QTStr(ESTIMATE_STR).arg(QString::number(int(memMB)))); else ui->simpleRBEstimate->setText(QTStr(ESTIMATE_UNKNOWN_STR)); @@ -4295,10 +4295,11 @@ void OBSBasicSettings::AdvReplayBufferChanged() char encoderJsonPath[512]; int ret = GetProfilePath(encoderJsonPath, - sizeof(encoderJsonPath), "recordEncoder.json"); + sizeof(encoderJsonPath), + "recordEncoder.json"); if (ret > 0) { obs_data_t *data = obs_data_create_from_json_file_safe( - encoderJsonPath, "bak"); + encoderJsonPath, "bak"); obs_data_apply(settings, data); obs_data_release(data); } @@ -4330,14 +4331,14 @@ void OBSBasicSettings::AdvReplayBufferChanged() int seconds = ui->advRBSecMax->value(); - int64_t memMB = int64_t(seconds) * int64_t(vbitrate + abitrate) * - 1000 / 8 / 1024 / 1024; + int64_t memMB = int64_t(seconds) * int64_t(vbitrate + abitrate) * 1000 / + 8 / 1024 / 1024; if (memMB < 1) memMB = 1; bool varRateControl = (astrcmpi(rateControl, "CBR") == 0 || - astrcmpi(rateControl, "VBR") == 0 || - astrcmpi(rateControl, "ABR") == 0); + astrcmpi(rateControl, "VBR") == 0 || + astrcmpi(rateControl, "ABR") == 0); if (vbitrate == 0) varRateControl = false; @@ -4346,12 +4347,12 @@ void OBSBasicSettings::AdvReplayBufferChanged() if (varRateControl) ui->advRBEstimate->setText( - QTStr(ESTIMATE_STR).arg( - QString::number(int(memMB)))); + QTStr(ESTIMATE_STR).arg(QString::number(int(memMB)))); else ui->advRBEstimate->setText(QTStr(ESTIMATE_UNKNOWN_STR)); - ui->advReplayBufferGroupBox->setVisible(!lossless && replayBufferEnabled); + ui->advReplayBufferGroupBox->setVisible(!lossless && + replayBufferEnabled); ui->advReplayBuf->setEnabled(!lossless); UpdateAutomaticReplayBufferCheckboxes(); @@ -4380,24 +4381,25 @@ void OBSBasicSettings::SimpleRecordingEncoderChanged() obs_data_t *videoSettings = obs_data_create(); obs_data_t *audioSettings = obs_data_create(); int oldVBitrate = ui->simpleOutputVBitrate->value(); - int oldABitrate = ui->simpleOutputABitrate->currentText().toInt(); + int oldABitrate = + ui->simpleOutputABitrate->currentText().toInt(); obs_data_set_int(videoSettings, "bitrate", oldVBitrate); obs_data_set_int(audioSettings, "bitrate", oldABitrate); obs_service_apply_encoder_settings(service, videoSettings, - audioSettings); + audioSettings); int newVBitrate = obs_data_get_int(videoSettings, "bitrate"); int newABitrate = obs_data_get_int(audioSettings, "bitrate"); if (newVBitrate < oldVBitrate) warning = SIMPLE_OUTPUT_WARNING("VideoBitrate") - .arg(newVBitrate); + .arg(newVBitrate); if (newABitrate < oldABitrate) { if (!warning.isEmpty()) warning += "\n\n"; warning += SIMPLE_OUTPUT_WARNING("AudioBitrate") - .arg(newABitrate); + .arg(newABitrate); } obs_data_release(videoSettings); @@ -4416,27 +4418,31 @@ void OBSBasicSettings::SimpleRecordingEncoderChanged() QString streamEnc = ui->simpleOutStrEncoder->currentData().toString(); bool x264RecEnc = (enc == SIMPLE_ENCODER_X264 || - enc == SIMPLE_ENCODER_X264_LOWCPU); + enc == SIMPLE_ENCODER_X264_LOWCPU); if (streamEnc == SIMPLE_ENCODER_X264 && x264RecEnc) { if (!warning.isEmpty()) warning += "\n\n"; warning += SIMPLE_OUTPUT_WARNING("Encoder"); } + } else { + if (!warning.isEmpty()) + warning += "\n\n"; + warning += SIMPLE_OUTPUT_WARNING("CannotPause"); } - if (ui->simpleOutRecFormat->currentText().compare("mp4") == 0 || - ui->simpleOutRecFormat->currentText().compare("mov") == 0) { + if (qual != "Lossless" && + (ui->simpleOutRecFormat->currentText().compare("mp4") == 0 || + ui->simpleOutRecFormat->currentText().compare("mov") == 0)) { if (!warning.isEmpty()) warning += "\n\n"; warning += QTStr("OutputWarnings.MP4Recording"); ui->autoRemux->setText( - QTStr("Basic.Settings.Advanced.AutoRemux") - + " " + - QTStr("Basic.Settings.Advanced.AutoRemux.MP4")); + QTStr("Basic.Settings.Advanced.AutoRemux") + " " + + QTStr("Basic.Settings.Advanced.AutoRemux.MP4")); } else { ui->autoRemux->setText( - QTStr("Basic.Settings.Advanced.AutoRemux")); + QTStr("Basic.Settings.Advanced.AutoRemux")); } if (warning.isEmpty()) @@ -4467,21 +4473,21 @@ void OBSBasicSettings::SurroundWarning(int idx) if (surround && !wasSurround) { QMessageBox::StandardButton button; - QString warningString = - QTStr("Basic.Settings.ProgramRestart") + - QStringLiteral("\n\n") + - QTStr(MULTI_CHANNEL_WARNING) + - QStringLiteral("\n\n") + - QTStr(MULTI_CHANNEL_WARNING ".Confirm"); + QString warningString = QTStr("Basic.Settings.ProgramRestart") + + QStringLiteral("\n\n") + + QTStr(MULTI_CHANNEL_WARNING) + + QStringLiteral("\n\n") + + QTStr(MULTI_CHANNEL_WARNING ".Confirm"); - button = OBSMessageBox::question(this, - QTStr(MULTI_CHANNEL_WARNING ".Title"), - warningString); + button = OBSMessageBox::question( + this, QTStr(MULTI_CHANNEL_WARNING ".Title"), + warningString); if (button == QMessageBox::No) { - QMetaObject::invokeMethod(ui->channelSetup, - "setCurrentIndex", Qt::QueuedConnection, - Q_ARG(int, lastChannelSetupIdx)); + QMetaObject::invokeMethod( + ui->channelSetup, "setCurrentIndex", + Qt::QueuedConnection, + Q_ARG(int, lastChannelSetupIdx)); return; } } @@ -4504,19 +4510,19 @@ void OBSBasicSettings::SimpleRecordingQualityLosslessWarning(int idx) if (qual == "Lossless") { QMessageBox::StandardButton button; - QString warningString = - SIMPLE_OUTPUT_WARNING("Lossless") + - QString("\n\n") + - SIMPLE_OUTPUT_WARNING("Lossless.Msg"); + QString warningString = SIMPLE_OUTPUT_WARNING("Lossless") + + QString("\n\n") + + SIMPLE_OUTPUT_WARNING("Lossless.Msg"); - button = OBSMessageBox::question(this, - SIMPLE_OUTPUT_WARNING("Lossless.Title"), - warningString); + button = OBSMessageBox::question( + this, SIMPLE_OUTPUT_WARNING("Lossless.Title"), + warningString); if (button == QMessageBox::No) { - QMetaObject::invokeMethod(ui->simpleOutRecQuality, - "setCurrentIndex", Qt::QueuedConnection, - Q_ARG(int, lastSimpleRecQualityIdx)); + QMetaObject::invokeMethod( + ui->simpleOutRecQuality, "setCurrentIndex", + Qt::QueuedConnection, + Q_ARG(int, lastSimpleRecQualityIdx)); return; } } @@ -4534,6 +4540,41 @@ void OBSBasicSettings::on_disableOSXVSync_clicked() #endif } +QIcon OBSBasicSettings::GetGeneralIcon() const +{ + return generalIcon; +} + +QIcon OBSBasicSettings::GetStreamIcon() const +{ + return streamIcon; +} + +QIcon OBSBasicSettings::GetOutputIcon() const +{ + return outputIcon; +} + +QIcon OBSBasicSettings::GetAudioIcon() const +{ + return audioIcon; +} + +QIcon OBSBasicSettings::GetVideoIcon() const +{ + return videoIcon; +} + +QIcon OBSBasicSettings::GetHotkeysIcon() const +{ + return hotkeysIcon; +} + +QIcon OBSBasicSettings::GetAdvancedIcon() const +{ + return advancedIcon; +} + void OBSBasicSettings::SetGeneralIcon(const QIcon &icon) { ui->listWidget->item(0)->setIcon(icon); diff --git a/UI/window-basic-settings.hpp b/UI/window-basic-settings.hpp index f899da0..0889d47 100644 --- a/UI/window-basic-settings.hpp +++ b/UI/window-basic-settings.hpp @@ -40,9 +40,9 @@ class OBSHotkeyWidget; #include "ui_OBSBasicSettings.h" -#define VOLUME_METER_DECAY_FAST 23.53 -#define VOLUME_METER_DECAY_MEDIUM 11.76 -#define VOLUME_METER_DECAY_SLOW 8.57 +#define VOLUME_METER_DECAY_FAST 23.53 +#define VOLUME_METER_DECAY_MEDIUM 11.76 +#define VOLUME_METER_DECAY_SLOW 8.57 class SilentUpdateCheckBox : public QCheckBox { Q_OBJECT @@ -68,8 +68,7 @@ public slots: } }; -class OBSFFDeleter -{ +class OBSFFDeleter { public: void operator()(const ff_format_desc *format) { @@ -80,27 +79,25 @@ public: ff_codec_desc_free(codec); } }; -using OBSFFCodecDesc = std::unique_ptr; -using OBSFFFormatDesc = std::unique_ptr; +using OBSFFCodecDesc = std::unique_ptr; +using OBSFFFormatDesc = std::unique_ptr; class OBSBasicSettings : public QDialog { Q_OBJECT - Q_PROPERTY(QIcon generalIcon WRITE SetGeneralIcon - NOTIFY SetGeneralIcon) - Q_PROPERTY(QIcon streamIcon WRITE SetStreamIcon - NOTIFY SetStreamIcon) - Q_PROPERTY(QIcon outputIcon WRITE SetOutputIcon - NOTIFY SetOutputIcon) - Q_PROPERTY(QIcon audioIcon WRITE SetAudioIcon - NOTIFY SetAudioIcon) - Q_PROPERTY(QIcon videoIcon WRITE SetVideoIcon - NOTIFY SetVideoIcon) - Q_PROPERTY(QIcon hotkeysIcon WRITE SetHotkeysIcon - NOTIFY SetHotkeysIcon) - Q_PROPERTY(QIcon advancedIcon WRITE SetAdvancedIcon - NOTIFY SetAdvancedIcon) + Q_PROPERTY(QIcon generalIcon READ GetGeneralIcon WRITE SetGeneralIcon + DESIGNABLE true) + Q_PROPERTY(QIcon streamIcon READ GetStreamIcon WRITE SetStreamIcon + DESIGNABLE true) + Q_PROPERTY(QIcon outputIcon READ GetOutputIcon WRITE SetOutputIcon + DESIGNABLE true) + Q_PROPERTY(QIcon audioIcon READ GetAudioIcon WRITE SetAudioIcon + DESIGNABLE true) + Q_PROPERTY(QIcon videoIcon READ GetVideoIcon WRITE SetVideoIcon + DESIGNABLE true) + Q_PROPERTY(QIcon hotkeysIcon READ GetHotkeysIcon WRITE SetHotkeysIcon + DESIGNABLE true) + Q_PROPERTY(QIcon advancedIcon READ GetAdvancedIcon WRITE SetAdvancedIcon + DESIGNABLE true) private: OBSBasic *main; @@ -116,7 +113,7 @@ private: bool videoChanged = false; bool hotkeysChanged = false; bool advancedChanged = false; - int pageIndex = 0; + int pageIndex = 0; bool loading = true; std::string savedTheme; @@ -141,9 +138,9 @@ private: QString curAdvRecordEncoder; using AudioSource_t = - std::tuple, QPointer, - QPointer, QPointer>; + std::tuple, + QPointer, QPointer, + QPointer>; std::vector audioSources; std::vector audioSourceSignals; OBSSignal sourceCreated; @@ -157,24 +154,24 @@ private: uint32_t outputCY = 0; void SaveCombo(QComboBox *widget, const char *section, - const char *value); + const char *value); void SaveComboData(QComboBox *widget, const char *section, - const char *value); + const char *value); void SaveCheckBox(QAbstractButton *widget, const char *section, - const char *value, bool invert = false); + const char *value, bool invert = false); void SaveEdit(QLineEdit *widget, const char *section, - const char *value); + const char *value); void SaveSpinBox(QSpinBox *widget, const char *section, - const char *value); + const char *value); void SaveFormat(QComboBox *combo); void SaveEncoder(QComboBox *combo, const char *section, - const char *value); + const char *value); inline bool Changed() const { return generalChanged || outputsChanged || stream1Changed || - audioChanged || videoChanged || advancedChanged || - hotkeysChanged; + audioChanged || videoChanged || advancedChanged || + hotkeysChanged; } inline void EnableApplyButton(bool en) @@ -187,10 +184,10 @@ private: generalChanged = false; stream1Changed = false; outputsChanged = false; - audioChanged = false; - videoChanged = false; + audioChanged = false; + videoChanged = false; hotkeysChanged = false; - advancedChanged= false; + advancedChanged = false; EnableApplyButton(false); } @@ -214,12 +211,14 @@ private: void LoadOutputSettings(); void LoadAudioSettings(); void LoadVideoSettings(); - void LoadHotkeySettings(obs_hotkey_id ignoreKey=OBS_INVALID_HOTKEY_ID); + void + LoadHotkeySettings(obs_hotkey_id ignoreKey = OBS_INVALID_HOTKEY_ID); void LoadAdvancedSettings(); void LoadSettings(bool changedOnly); OBSPropertiesView *CreateEncoderPropertyView(const char *encoder, - const char *path, bool changed = false); + const char *path, + bool changed = false); /* general */ void LoadLanguageList(); @@ -241,8 +240,8 @@ private slots: void on_disconnectAccount_clicked(); void on_useStreamKey_clicked(); void on_useAuth_toggled(); -private: +private: /* output */ void LoadSimpleOutputSettings(); void LoadAdvOutputStreamingSettings(); @@ -251,9 +250,9 @@ private: void LoadAdvOutputRecordingEncoderProperties(); void LoadAdvOutputFFmpegSettings(); void LoadAdvOutputAudioSettings(); - void SetAdvOutputFFmpegEnablement( - ff_codec_type encoderType, bool enabled, - bool enableEncode = false); + void SetAdvOutputFFmpegEnablement(ff_codec_type encoderType, + bool enabled, + bool enableEncode = false); /* audio */ void LoadListValues(QComboBox *widget, obs_property_t *prop, int index); @@ -285,6 +284,22 @@ private: void RecalcOutputResPixels(const char *resText); + QIcon generalIcon; + QIcon streamIcon; + QIcon outputIcon; + QIcon audioIcon; + QIcon videoIcon; + QIcon hotkeysIcon; + QIcon advancedIcon; + + QIcon GetGeneralIcon() const; + QIcon GetStreamIcon() const; + QIcon GetOutputIcon() const; + QIcon GetAudioIcon() const; + QIcon GetVideoIcon() const; + QIcon GetHotkeysIcon() const; + QIcon GetAdvancedIcon() const; + private slots: void on_theme_activated(int idx); @@ -323,7 +338,7 @@ private slots: void VideoChangedResolution(); void VideoChangedRestart(); void HotkeysChanged(); - void ReloadHotkeys(obs_hotkey_id ignoreKey=OBS_INVALID_HOTKEY_ID); + void ReloadHotkeys(obs_hotkey_id ignoreKey = OBS_INVALID_HOTKEY_ID); void AdvancedChanged(); void AdvancedChangedRestart(); diff --git a/UI/window-basic-source-select.cpp b/UI/window-basic-source-select.cpp index 171dc64..b7dba97 100644 --- a/UI/window-basic-source-select.cpp +++ b/UI/window-basic-source-select.cpp @@ -28,9 +28,10 @@ struct AddSourceData { bool OBSBasicSourceSelect::EnumSources(void *data, obs_source_t *source) { - OBSBasicSourceSelect *window = static_cast(data); + OBSBasicSourceSelect *window = + static_cast(data); const char *name = obs_source_get_name(source); - const char *id = obs_source_get_id(source); + const char *id = obs_source_get_id(source); if (strcmp(id, window->id) == 0) window->ui->sourceList->addItem(QT_UTF8(name)); @@ -40,13 +41,14 @@ bool OBSBasicSourceSelect::EnumSources(void *data, obs_source_t *source) bool OBSBasicSourceSelect::EnumGroups(void *data, obs_source_t *source) { - OBSBasicSourceSelect *window = static_cast(data); + OBSBasicSourceSelect *window = + static_cast(data); const char *name = obs_source_get_name(source); - const char *id = obs_source_get_id(source); + const char *id = obs_source_get_id(source); if (strcmp(id, window->id) == 0) { - OBSBasic *main = reinterpret_cast( - App()->GetMainWindow()); + OBSBasic *main = + reinterpret_cast(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); obs_sceneitem_t *existing = obs_scene_get_group(scene, name); @@ -59,25 +61,27 @@ bool OBSBasicSourceSelect::EnumGroups(void *data, obs_source_t *source) void OBSBasicSourceSelect::OBSSourceAdded(void *data, calldata_t *calldata) { - OBSBasicSourceSelect *window = static_cast(data); - obs_source_t *source = (obs_source_t*)calldata_ptr(calldata, "source"); + OBSBasicSourceSelect *window = + static_cast(data); + obs_source_t *source = (obs_source_t *)calldata_ptr(calldata, "source"); QMetaObject::invokeMethod(window, "SourceAdded", - Q_ARG(OBSSource, source)); + Q_ARG(OBSSource, source)); } void OBSBasicSourceSelect::OBSSourceRemoved(void *data, calldata_t *calldata) { - OBSBasicSourceSelect *window = static_cast(data); - obs_source_t *source = (obs_source_t*)calldata_ptr(calldata, "source"); + OBSBasicSourceSelect *window = + static_cast(data); + obs_source_t *source = (obs_source_t *)calldata_ptr(calldata, "source"); QMetaObject::invokeMethod(window, "SourceRemoved", - Q_ARG(OBSSource, source)); + Q_ARG(OBSSource, source)); } void OBSBasicSourceSelect::SourceAdded(OBSSource source) { - const char *name = obs_source_get_name(source); + const char *name = obs_source_get_name(source); const char *sourceId = obs_source_get_id(source); if (strcmp(sourceId, id) != 0) @@ -88,13 +92,13 @@ void OBSBasicSourceSelect::SourceAdded(OBSSource source) void OBSBasicSourceSelect::SourceRemoved(OBSSource source) { - const char *name = obs_source_get_name(source); + const char *name = obs_source_get_name(source); const char *sourceId = obs_source_get_id(source); if (strcmp(sourceId, id) != 0) return; - QList items = + QList items = ui->sourceList->findItems(name, Qt::MatchFixedString); if (!items.count()) @@ -120,8 +124,8 @@ static char *get_new_source_name(const char *name) dstr_copy(&new_name, name); for (;;) { - obs_source_t *existing_source = obs_get_source_by_name( - new_name.array); + obs_source_t *existing_source = + obs_get_source_by_name(new_name.array); if (!existing_source) break; @@ -135,7 +139,7 @@ static char *get_new_source_name(const char *name) static void AddExisting(const char *name, bool visible, bool duplicate) { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); if (!scene) return; @@ -166,19 +170,18 @@ static void AddExisting(const char *name, bool visible, bool duplicate) } bool AddNew(QWidget *parent, const char *id, const char *name, - const bool visible, OBSSource &newSource) + const bool visible, OBSSource &newSource) { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); - OBSScene scene = main->GetCurrentScene(); - bool success = false; + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSScene scene = main->GetCurrentScene(); + bool success = false; if (!scene) return false; obs_source_t *source = obs_get_source_by_name(name); if (source) { - OBSMessageBox::information(parent, - QTStr("NameExists.Title"), - QTStr("NameExists.Text")); + OBSMessageBox::information(parent, QTStr("NameExists.Title"), + QTStr("NameExists.Text")); } else { source = obs_source_create(id, name, NULL, nullptr); @@ -194,6 +197,14 @@ bool AddNew(QWidget *parent, const char *id, const char *name, newSource = source; + /* set monitoring if source monitors by default */ + uint32_t flags = obs_source_get_output_flags(source); + if ((flags & OBS_SOURCE_MONITOR_BY_DEFAULT) != 0) { + obs_source_set_monitoring_type( + source, + OBS_MONITORING_TYPE_MONITOR_ONLY); + } + success = true; } } @@ -216,13 +227,13 @@ void OBSBasicSourceSelect::on_buttonBox_accepted() } else { if (ui->sourceName->text().isEmpty()) { OBSMessageBox::warning(this, - QTStr("NoNameEntered.Title"), - QTStr("NoNameEntered.Text")); + QTStr("NoNameEntered.Title"), + QTStr("NoNameEntered.Text")); return; } if (!AddNew(this, id, QT_TO_UTF8(ui->sourceName->text()), - visible, newSource)) + visible, newSource)) return; } @@ -243,16 +254,13 @@ static inline const char *GetSourceDisplayName(const char *id) Q_DECLARE_METATYPE(OBSScene); -template -static inline T GetOBSRef(QListWidgetItem *item) +template static inline T GetOBSRef(QListWidgetItem *item) { return item->data(static_cast(QtDataRole::OBSRef)).value(); } OBSBasicSourceSelect::OBSBasicSourceSelect(OBSBasic *parent, const char *id_) - : QDialog (parent), - ui (new Ui::OBSBasicSourceSelect), - id (id_) + : QDialog(parent), ui(new Ui::OBSBasicSourceSelect), id(id_) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); @@ -271,14 +279,14 @@ OBSBasicSourceSelect::OBSBasicSourceSelect(OBSBasic *parent, const char *id_) } ui->sourceName->setText(text); - ui->sourceName->setFocus(); //Fixes deselect of text. + ui->sourceName->setFocus(); //Fixes deselect of text. ui->sourceName->selectAll(); installEventFilter(CreateShortcutFilter()); if (strcmp(id_, "scene") == 0) { - OBSBasic *main = reinterpret_cast( - App()->GetMainWindow()); + OBSBasic *main = + reinterpret_cast(App()->GetMainWindow()); OBSSource curSceneSource = main->GetCurrentSceneSource(); ui->selectExisting->setChecked(true); diff --git a/UI/window-basic-stats.cpp b/UI/window-basic-stats.cpp index 0258067..7f6e2ca 100644 --- a/UI/window-basic-stats.cpp +++ b/UI/window-basic-stats.cpp @@ -45,10 +45,10 @@ void OBSBasicStats::OBSFrontendEvent(enum obs_frontend_event event, void *ptr) } OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable) - : QWidget (parent), - cpu_info (os_cpu_usage_info_start()), - timer (this), - recTimeLeft (this) + : QWidget(parent), + cpu_info(os_cpu_usage_info_start()), + timer(this), + recTimeLeft(this) { QVBoxLayout *mainLayout = new QVBoxLayout(); QGridLayout *topLayout = new QGridLayout(); @@ -58,15 +58,13 @@ OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable) int row = 0; - auto newStatBare = [&] (QString name, QWidget *label, int col) - { + auto newStatBare = [&](QString name, QWidget *label, int col) { QLabel *typeLabel = new QLabel(name, this); topLayout->addWidget(typeLabel, row, col); topLayout->addWidget(label, row++, col + 1); }; - auto newStat = [&] (const char *strLoc, QWidget *label, int col) - { + auto newStat = [&](const char *strLoc, QWidget *label, int col) { std::string str = "Basic.Stats."; str += strLoc; newStatBare(QTStr(str.c_str()), label, col); @@ -97,20 +95,19 @@ OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable) /* --------------------------------------------- */ QPushButton *closeButton = nullptr; - if(closeable) + if (closeable) closeButton = new QPushButton(QTStr("Close")); QPushButton *resetButton = new QPushButton(QTStr("Reset")); QHBoxLayout *buttonLayout = new QHBoxLayout; buttonLayout->addStretch(); buttonLayout->addWidget(resetButton); - if(closeable) + if (closeable) buttonLayout->addWidget(closeButton); /* --------------------------------------------- */ int col = 0; - auto addOutputCol = [&] (const char *loc) - { + auto addOutputCol = [&](const char *loc) { QLabel *label = new QLabel(QTStr(loc), this); label->setStyleSheet("font-weight: bold"); outputLayout->addWidget(label, 0, col++); @@ -148,10 +145,10 @@ OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable) setLayout(mainLayout); /* --------------------------------------------- */ - if(closeable) + if (closeable) connect(closeButton, &QPushButton::clicked, - [this] () {close();}); - connect(resetButton, &QPushButton::clicked, [this] () {Reset();}); + [this]() { close(); }); + connect(resetButton, &QPushButton::clicked, [this]() { Reset(); }); delete shortcutFilter; shortcutFilter = CreateShortcutFilter(); @@ -165,7 +162,8 @@ OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable) setWindowModality(Qt::NonModal); setAttribute(Qt::WA_DeleteOnClose, true); - QObject::connect(&timer, &QTimer::timeout, this, &OBSBasicStats::Update); + QObject::connect(&timer, &QTimer::timeout, this, + &OBSBasicStats::Update); timer.setInterval(TIMER_INTERVAL); if (isVisible()) @@ -174,25 +172,24 @@ OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable) Update(); QObject::connect(&recTimeLeft, &QTimer::timeout, this, - &OBSBasicStats::RecordingTimeLeft); + &OBSBasicStats::RecordingTimeLeft); recTimeLeft.setInterval(REC_TIME_LEFT_INTERVAL); - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); - const char *geometry = config_get_string(main->Config(), - "Stats", "geometry"); + const char *geometry = + config_get_string(main->Config(), "Stats", "geometry"); if (geometry != NULL) { - QByteArray byteArray = QByteArray::fromBase64( - QByteArray(geometry)); + QByteArray byteArray = + QByteArray::fromBase64(QByteArray(geometry)); restoreGeometry(byteArray); QRect windowGeometry = normalGeometry(); if (!WindowPositionValid(windowGeometry)) { QRect rect = App()->desktop()->geometry(); - setGeometry(QStyle::alignedRect( - Qt::LeftToRight, - Qt::AlignCenter, - size(), rect)); + setGeometry(QStyle::alignedRect(Qt::LeftToRight, + Qt::AlignCenter, size(), + rect)); } } @@ -201,11 +198,10 @@ OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable) void OBSBasicStats::closeEvent(QCloseEvent *event) { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); if (isVisible()) { - config_set_string(main->Config(), - "Stats", "geometry", - saveGeometry().toBase64().constData()); + config_set_string(main->Config(), "Stats", "geometry", + saveGeometry().toBase64().constData()); config_save_safe(main->Config(), "tmp", nullptr); } @@ -254,15 +250,15 @@ static uint32_t first_lagged = 0xFFFFFFFF; void OBSBasicStats::InitializeValues() { video_t *video = obs_get_video(); - first_encoded = video_output_get_total_frames(video); - first_skipped = video_output_get_skipped_frames(video); + first_encoded = video_output_get_total_frames(video); + first_skipped = video_output_get_skipped_frames(video); first_rendered = obs_get_total_frames(); - first_lagged = obs_get_lagged_frames(); + first_lagged = obs_get_lagged_frames(); } void OBSBasicStats::Update() { - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); /* TODO: Un-hardcode */ @@ -302,9 +298,12 @@ void OBSBasicStats::Update() /* ------------------ */ const char *mode = config_get_string(main->Config(), "Output", "Mode"); - const char *path = strcmp(mode, "Advanced") ? - config_get_string(main->Config(), "SimpleOutput", "FilePath") : - config_get_string(main->Config(), "AdvOut", "RecFilePath"); + const char *path = strcmp(mode, "Advanced") + ? config_get_string(main->Config(), + "SimpleOutput", + "FilePath") + : config_get_string(main->Config(), "AdvOut", + "RecFilePath"); #define MBYTE (1024ULL * 1024ULL) #define GBYTE (1024ULL * 1024ULL * 1024ULL) @@ -370,14 +369,14 @@ void OBSBasicStats::Update() total_skipped -= first_skipped; num = total_encoded - ? (long double)total_skipped / (long double)total_encoded - : 0.0l; + ? (long double)total_skipped / (long double)total_encoded + : 0.0l; num *= 100.0l; - str = QString("%1 / %2 (%3%)").arg( - QString::number(total_skipped), - QString::number(total_encoded), - QString::number(num, 'f', 1)); + str = QString("%1 / %2 (%3%)") + .arg(QString::number(total_skipped), + QString::number(total_encoded), + QString::number(num, 'f', 1)); skippedFrames->setText(str); if (num > 5.0l) @@ -390,24 +389,24 @@ void OBSBasicStats::Update() /* ------------------ */ uint32_t total_rendered = obs_get_total_frames(); - uint32_t total_lagged = obs_get_lagged_frames(); + uint32_t total_lagged = obs_get_lagged_frames(); if (total_rendered < first_rendered || total_lagged < first_lagged) { first_rendered = total_rendered; - first_lagged = total_lagged; + first_lagged = total_lagged; } total_rendered -= first_rendered; - total_lagged -= first_lagged; + total_lagged -= first_lagged; num = total_rendered - ? (long double)total_lagged / (long double)total_rendered - : 0.0l; + ? (long double)total_lagged / (long double)total_rendered + : 0.0l; num *= 100.0l; - str = QString("%1 / %2 (%3%)").arg( - QString::number(total_lagged), - QString::number(total_rendered), - QString::number(num, 'f', 1)); + str = QString("%1 / %2 (%3%)") + .arg(QString::number(total_lagged), + QString::number(total_rendered), + QString::number(num, 'f', 1)); missedFrames->setText(str); if (num > 5.0l) @@ -444,21 +443,21 @@ void OBSBasicStats::ResetRecTimeLeft() void OBSBasicStats::RecordingTimeLeft() { - long double averageBitrate = accumulate(bitrates.begin(), - bitrates.end(), 0.0) / - (long double)bitrates.size(); + long double averageBitrate = + accumulate(bitrates.begin(), bitrates.end(), 0.0) / + (long double)bitrates.size(); long double bytesPerSec = (averageBitrate / 8.0l) * 1000.0l; long double secondsUntilFull = (long double)num_bytes / bytesPerSec; bitrates.clear(); int totalMinutes = (int)secondsUntilFull / 60; - int minutes = totalMinutes % 60; - int hours = totalMinutes / 60; + int minutes = totalMinutes % 60; + int hours = totalMinutes / 60; QString text; - text.sprintf("%d %s, %d %s", hours, QT_TO_UTF8(QTStr("Hours")), - minutes, QT_TO_UTF8(QTStr("Minutes"))); + text.sprintf("%d %s, %d %s", hours, QT_TO_UTF8(QTStr("Hours")), minutes, + QT_TO_UTF8(QTStr("Minutes"))); recordTimeLeft->setText(text); recordTimeLeft->setMinimumWidth(recordTimeLeft->width()); } @@ -467,10 +466,10 @@ void OBSBasicStats::Reset() { timer.start(); - first_encoded = 0xFFFFFFFF; - first_skipped = 0xFFFFFFFF; + first_encoded = 0xFFFFFFFF; + first_skipped = 0xFFFFFFFF; first_rendered = 0xFFFFFFFF; - first_lagged = 0xFFFFFFFF; + first_lagged = 0xFFFFFFFF; OBSOutput strOutput = obs_frontend_get_streaming_output(); OBSOutput recOutput = obs_frontend_get_recording_output(); @@ -494,8 +493,8 @@ void OBSBasicStats::OutputLabels::Update(obs_output_t *output, bool rec) lastBytesSent = 0; uint64_t bitsBetween = (bytesSent - lastBytesSent) * 8; - long double timePassed = (long double)(curTime - lastBytesSentTime) / - 1000000000.0l; + long double timePassed = + (long double)(curTime - lastBytesSentTime) / 1000000000.0l; kbps = (long double)bitsBetween / timePassed / 1000.0l; if (timePassed < 0.01l) @@ -509,9 +508,9 @@ void OBSBasicStats::OutputLabels::Update(obs_output_t *output, bool rec) str = QTStr("Basic.Stats.Status.Recording"); } else { if (active) { - bool reconnecting = output - ? obs_output_reconnecting(output) - : false; + bool reconnecting = + output ? obs_output_reconnecting(output) + : false; if (reconnecting) { str = QTStr("Basic.Stats.Status.Reconnecting"); @@ -529,30 +528,29 @@ void OBSBasicStats::OutputLabels::Update(obs_output_t *output, bool rec) long double num = (long double)totalBytes / (1024.0l * 1024.0l); megabytesSent->setText( - QString("%1 MB").arg(QString::number(num, 'f', 1))); - bitrate->setText( - QString("%1 kb/s").arg(QString::number(kbps, 'f', 0))); + QString("%1 MB").arg(QString::number(num, 'f', 1))); + bitrate->setText(QString("%1 kb/s").arg(QString::number(kbps, 'f', 0))); if (!rec) { int total = output ? obs_output_get_total_frames(output) : 0; - int dropped = output ? obs_output_get_frames_dropped(output) : 0; + int dropped = output ? obs_output_get_frames_dropped(output) + : 0; if (total < first_total || dropped < first_dropped) { - first_total = 0; + first_total = 0; first_dropped = 0; } - total -= first_total; + total -= first_total; dropped -= first_dropped; - num = total - ? (long double)dropped / (long double)total * 100.0l - : 0.0l; + num = total ? (long double)dropped / (long double)total * 100.0l + : 0.0l; - str = QString("%1 / %2 (%3%)").arg( - QString::number(dropped), - QString::number(total), - QString::number(num, 'f', 1)); + str = QString("%1 / %2 (%3%)") + .arg(QString::number(dropped), + QString::number(total), + QString::number(num, 'f', 1)); droppedFrames->setText(str); if (num > 5.0l) @@ -563,7 +561,7 @@ void OBSBasicStats::OutputLabels::Update(obs_output_t *output, bool rec) setThemeID(droppedFrames, ""); } - lastBytesSent = bytesSent; + lastBytesSent = bytesSent; lastBytesSentTime = curTime; } @@ -572,7 +570,7 @@ void OBSBasicStats::OutputLabels::Reset(obs_output_t *output) if (!output) return; - first_total = obs_output_get_total_frames(output); + first_total = obs_output_get_total_frames(output); first_dropped = obs_output_get_frames_dropped(output); } diff --git a/UI/window-basic-status-bar.cpp b/UI/window-basic-status-bar.cpp index e10e0d8..74dde3a 100644 --- a/UI/window-basic-status-bar.cpp +++ b/UI/window-basic-status-bar.cpp @@ -8,16 +8,16 @@ #include "window-basic-main-outputs.hpp" OBSBasicStatusBar::OBSBasicStatusBar(QWidget *parent) - : QStatusBar (parent), - delayInfo (new QLabel), - droppedFrames (new QLabel), - streamTime (new QLabel), - recordTime (new QLabel), - cpuUsage (new QLabel), - transparentPixmap (20, 20), - greenPixmap (20, 20), - grayPixmap (20, 20), - redPixmap (20, 20) + : QStatusBar(parent), + delayInfo(new QLabel), + droppedFrames(new QLabel), + streamTime(new QLabel), + recordTime(new QLabel), + cpuUsage(new QLabel), + transparentPixmap(20, 20), + greenPixmap(20, 20), + grayPixmap(20, 20), + redPixmap(20, 20) { streamTime->setText(QString("LIVE: 00:00:00")); recordTime->setText(QString("REC: 00:00:00")); @@ -74,11 +74,11 @@ void OBSBasicStatusBar::Activate() { if (!active) { refreshTimer = new QTimer(this); - connect(refreshTimer, SIGNAL(timeout()), - this, SLOT(UpdateStatusBar())); + connect(refreshTimer, SIGNAL(timeout()), this, + SLOT(UpdateStatusBar())); int skipped = video_output_get_skipped_frames(obs_get_video()); - int total = video_output_get_total_frames(obs_get_video()); + int total = video_output_get_total_frames(obs_get_video()); totalStreamSeconds = 0; totalRecordSeconds = 0; @@ -97,7 +97,7 @@ void OBSBasicStatusBar::Activate() void OBSBasicStatusBar::Deactivate() { - OBSBasic *main = qobject_cast(parent()); + OBSBasic *main = qobject_cast(parent()); if (!main) return; @@ -145,7 +145,7 @@ void OBSBasicStatusBar::UpdateDelayMsg() } else if (delaySecStarting && delaySecStopping) { msg = QTStr("Basic.StatusBar.DelayStartingStoppingIn"); msg = msg.arg(QString::number(delaySecStopping), - QString::number(delaySecStarting)); + QString::number(delaySecStarting)); } else { msg = QTStr("Basic.StatusBar.Delay"); msg = msg.arg(QString::number(delaySecTotal)); @@ -165,7 +165,7 @@ void OBSBasicStatusBar::UpdateBandwidth() if (++bitrateUpdateSeconds < BITRATE_UPDATE_SECONDS) return; - uint64_t bytesSent = obs_output_get_total_bytes(streamOutput); + uint64_t bytesSent = obs_output_get_total_bytes(streamOutput); uint64_t bytesSentTime = os_gettime_ns(); if (bytesSent < lastBytesSent) @@ -173,28 +173,27 @@ void OBSBasicStatusBar::UpdateBandwidth() if (bytesSent == 0) lastBytesSent = 0; - uint64_t bitsBetween = (bytesSent - lastBytesSent) * 8; + uint64_t bitsBetween = (bytesSent - lastBytesSent) * 8; - double timePassed = double(bytesSentTime - lastBytesSentTime) / - 1000000000.0; + double timePassed = + double(bytesSentTime - lastBytesSentTime) / 1000000000.0; double kbitsPerSec = double(bitsBetween) / timePassed / 1000.0; QString text; - text += QString("kb/s: ") + - QString::number(kbitsPerSec, 'f', 0); + text += QString("kb/s: ") + QString::number(kbitsPerSec, 'f', 0); kbps->setText(text); kbps->setMinimumWidth(kbps->width()); - lastBytesSent = bytesSent; - lastBytesSentTime = bytesSentTime; + lastBytesSent = bytesSent; + lastBytesSentTime = bytesSentTime; bitrateUpdateSeconds = 0; } void OBSBasicStatusBar::UpdateCPUUsage() { - OBSBasic *main = qobject_cast(parent()); + OBSBasic *main = qobject_cast(parent()); if (!main) return; @@ -211,10 +210,10 @@ void OBSBasicStatusBar::UpdateStreamTime() { totalStreamSeconds++; - int seconds = totalStreamSeconds % 60; + int seconds = totalStreamSeconds % 60; int totalMinutes = totalStreamSeconds / 60; - int minutes = totalMinutes % 60; - int hours = totalMinutes / 60; + int minutes = totalMinutes % 60; + int hours = totalMinutes / 60; QString text; text.sprintf("LIVE: %02d:%02d:%02d", hours, minutes, seconds); @@ -223,8 +222,8 @@ void OBSBasicStatusBar::UpdateStreamTime() if (reconnectTimeout > 0) { QString msg = QTStr("Basic.StatusBar.Reconnecting") - .arg(QString::number(retries), - QString::number(reconnectTimeout)); + .arg(QString::number(retries), + QString::number(reconnectTimeout)); showMessage(msg); reconnectTimeout--; @@ -242,17 +241,28 @@ void OBSBasicStatusBar::UpdateStreamTime() } } +extern volatile bool recording_paused; + void OBSBasicStatusBar::UpdateRecordTime() { - totalRecordSeconds++; + bool paused = os_atomic_load_bool(&recording_paused); - int seconds = totalRecordSeconds % 60; - int totalMinutes = totalRecordSeconds / 60; - int minutes = totalMinutes % 60; - int hours = totalMinutes / 60; + if (!paused) + totalRecordSeconds++; QString text; - text.sprintf("REC: %02d:%02d:%02d", hours, minutes, seconds); + + if (paused) { + text = QStringLiteral("REC: PAUSED"); + } else { + int seconds = totalRecordSeconds % 60; + int totalMinutes = totalRecordSeconds / 60; + int minutes = totalMinutes % 60; + int hours = totalMinutes / 60; + + text.sprintf("REC: %02d:%02d:%02d", hours, minutes, seconds); + } + recordTime->setText(text); recordTime->setMinimumWidth(recordTime->width()); } @@ -263,8 +273,8 @@ void OBSBasicStatusBar::UpdateDroppedFrames() return; int totalDropped = obs_output_get_frames_dropped(streamOutput); - int totalFrames = obs_output_get_total_frames(streamOutput); - double percent = (double)totalDropped / (double)totalFrames * 100.0; + int totalFrames = obs_output_get_total_frames(streamOutput); + double percent = (double)totalDropped / (double)totalFrames * 100.0; if (!totalFrames) return; @@ -293,11 +303,13 @@ void OBSBasicStatusBar::UpdateDroppedFrames() QPixmap pixmap(20, 20); float red = avgCongestion * 2.0f; - if (red > 1.0f) red = 1.0f; + if (red > 1.0f) + red = 1.0f; red *= 255.0; float green = (1.0f - avgCongestion) * 2.0f; - if (green > 1.0f) green = 1.0f; + if (green > 1.0f) + green = 1.0f; green *= 255.0; pixmap.fill(QColor(int(red), int(green), 0)); @@ -310,17 +322,18 @@ void OBSBasicStatusBar::UpdateDroppedFrames() void OBSBasicStatusBar::OBSOutputReconnect(void *data, calldata_t *params) { OBSBasicStatusBar *statusBar = - reinterpret_cast(data); + reinterpret_cast(data); int seconds = (int)calldata_int(params, "timeout_sec"); QMetaObject::invokeMethod(statusBar, "Reconnect", Q_ARG(int, seconds)); UNUSED_PARAMETER(params); } -void OBSBasicStatusBar::OBSOutputReconnectSuccess(void *data, calldata_t *params) +void OBSBasicStatusBar::OBSOutputReconnectSuccess(void *data, + calldata_t *params) { OBSBasicStatusBar *statusBar = - reinterpret_cast(data); + reinterpret_cast(data); QMetaObject::invokeMethod(statusBar, "ReconnectSuccess"); UNUSED_PARAMETER(params); @@ -328,12 +341,12 @@ void OBSBasicStatusBar::OBSOutputReconnectSuccess(void *data, calldata_t *params void OBSBasicStatusBar::Reconnect(int seconds) { - OBSBasic *main = qobject_cast(parent()); + OBSBasic *main = qobject_cast(parent()); if (!retries) main->SysTrayNotify( - QTStr("Basic.SystemTray.Message.Reconnecting"), - QSystemTrayIcon::Warning); + QTStr("Basic.SystemTray.Message.Reconnecting"), + QSystemTrayIcon::Warning); reconnectTimeout = seconds; @@ -347,18 +360,18 @@ void OBSBasicStatusBar::Reconnect(int seconds) void OBSBasicStatusBar::ReconnectClear() { - retries = 0; - reconnectTimeout = 0; + retries = 0; + reconnectTimeout = 0; bitrateUpdateSeconds = -1; - lastBytesSent = 0; - lastBytesSentTime = os_gettime_ns(); - delaySecTotal = 0; + lastBytesSent = 0; + lastBytesSentTime = os_gettime_ns(); + delaySecTotal = 0; UpdateDelayMsg(); } void OBSBasicStatusBar::ReconnectSuccess() { - OBSBasic *main = qobject_cast(parent()); + OBSBasic *main = qobject_cast(parent()); QString msg = QTStr("Basic.StatusBar.ReconnectSuccessful"); showMessage(msg, 4000); @@ -373,7 +386,7 @@ void OBSBasicStatusBar::ReconnectSuccess() void OBSBasicStatusBar::UpdateStatusBar() { - OBSBasic *main = qobject_cast(parent()); + OBSBasic *main = qobject_cast(parent()); UpdateBandwidth(); @@ -386,10 +399,10 @@ void OBSBasicStatusBar::UpdateStatusBar() UpdateDroppedFrames(); int skipped = video_output_get_skipped_frames(obs_get_video()); - int total = video_output_get_total_frames(obs_get_video()); + int total = video_output_get_total_frames(obs_get_video()); skipped -= startSkippedFrameCount; - total -= startTotalFrameCount; + total -= startTotalFrameCount; int diff = skipped - lastSkippedFrameCount; double percentage = double(skipped) / double(total) * 100.0; @@ -398,7 +411,7 @@ void OBSBasicStatusBar::UpdateStatusBar() showMessage(QTStr("HighResourceUsage"), 4000); if (!main->isVisible() && overloadedNotify) { main->SysTrayNotify(QTStr("HighResourceUsage"), - QSystemTrayIcon::Warning); + QSystemTrayIcon::Warning); overloadedNotify = false; } } @@ -408,7 +421,7 @@ void OBSBasicStatusBar::UpdateStatusBar() void OBSBasicStatusBar::StreamDelayStarting(int sec) { - OBSBasic *main = qobject_cast(parent()); + OBSBasic *main = qobject_cast(parent()); if (!main || !main->outputHandler) return; @@ -430,12 +443,13 @@ void OBSBasicStatusBar::StreamStarted(obs_output_t *output) streamOutput = output; signal_handler_connect(obs_output_get_signal_handler(streamOutput), - "reconnect", OBSOutputReconnect, this); + "reconnect", OBSOutputReconnect, this); signal_handler_connect(obs_output_get_signal_handler(streamOutput), - "reconnect_success", OBSOutputReconnectSuccess, this); + "reconnect_success", OBSOutputReconnectSuccess, + this); - retries = 0; - lastBytesSent = 0; + retries = 0; + lastBytesSent = 0; lastBytesSentTime = os_gettime_ns(); Activate(); } @@ -444,12 +458,11 @@ void OBSBasicStatusBar::StreamStopped() { if (streamOutput) { signal_handler_disconnect( - obs_output_get_signal_handler(streamOutput), - "reconnect", OBSOutputReconnect, this); + obs_output_get_signal_handler(streamOutput), + "reconnect", OBSOutputReconnect, this); signal_handler_disconnect( - obs_output_get_signal_handler(streamOutput), - "reconnect_success", OBSOutputReconnectSuccess, - this); + obs_output_get_signal_handler(streamOutput), + "reconnect_success", OBSOutputReconnectSuccess, this); ReconnectClear(); streamOutput = nullptr; diff --git a/UI/window-basic-status-bar.hpp b/UI/window-basic-status-bar.hpp index 2da33c3..972bf87 100644 --- a/UI/window-basic-status-bar.hpp +++ b/UI/window-basic-status-bar.hpp @@ -39,7 +39,7 @@ private: int startTotalFrameCount = 0; int lastSkippedFrameCount = 0; - int bitrateUpdateSeconds = 0; + int bitrateUpdateSeconds = 0; uint64_t lastBytesSent = 0; uint64_t lastBytesSentTime = 0; diff --git a/UI/window-basic-transform.cpp b/UI/window-basic-transform.cpp index 7501d27..7c1d61d 100644 --- a/UI/window-basic-transform.cpp +++ b/UI/window-basic-transform.cpp @@ -6,7 +6,7 @@ Q_DECLARE_METATYPE(OBSSceneItem); static bool find_sel(obs_scene_t *, obs_sceneitem_t *item, void *param) { - OBSSceneItem &dst = *reinterpret_cast(param); + OBSSceneItem &dst = *reinterpret_cast(param); if (obs_sceneitem_selected(item)) { dst = item; @@ -30,38 +30,36 @@ static OBSSceneItem FindASelectedItem(OBSScene scene) } void OBSBasicTransform::HookWidget(QWidget *widget, const char *signal, - const char *slot) + const char *slot) { QObject::connect(widget, signal, this, slot); } -#define COMBO_CHANGED SIGNAL(currentIndexChanged(int)) +#define COMBO_CHANGED SIGNAL(currentIndexChanged(int)) #define ISCROLL_CHANGED SIGNAL(valueChanged(int)) #define DSCROLL_CHANGED SIGNAL(valueChanged(double)) OBSBasicTransform::OBSBasicTransform(OBSBasic *parent) - : QDialog (parent), - ui (new Ui::OBSBasicTransform), - main (parent) + : QDialog(parent), ui(new Ui::OBSBasicTransform), main(parent) { ui->setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); - HookWidget(ui->positionX, DSCROLL_CHANGED, SLOT(OnControlChanged())); - HookWidget(ui->positionY, DSCROLL_CHANGED, SLOT(OnControlChanged())); - HookWidget(ui->rotation, DSCROLL_CHANGED, SLOT(OnControlChanged())); - HookWidget(ui->sizeX, DSCROLL_CHANGED, SLOT(OnControlChanged())); - HookWidget(ui->sizeY, DSCROLL_CHANGED, SLOT(OnControlChanged())); - HookWidget(ui->align, COMBO_CHANGED, SLOT(OnControlChanged())); - HookWidget(ui->boundsType, COMBO_CHANGED, SLOT(OnBoundsType(int))); - HookWidget(ui->boundsAlign, COMBO_CHANGED, SLOT(OnControlChanged())); - HookWidget(ui->boundsWidth, DSCROLL_CHANGED, SLOT(OnControlChanged())); + HookWidget(ui->positionX, DSCROLL_CHANGED, SLOT(OnControlChanged())); + HookWidget(ui->positionY, DSCROLL_CHANGED, SLOT(OnControlChanged())); + HookWidget(ui->rotation, DSCROLL_CHANGED, SLOT(OnControlChanged())); + HookWidget(ui->sizeX, DSCROLL_CHANGED, SLOT(OnControlChanged())); + HookWidget(ui->sizeY, DSCROLL_CHANGED, SLOT(OnControlChanged())); + HookWidget(ui->align, COMBO_CHANGED, SLOT(OnControlChanged())); + HookWidget(ui->boundsType, COMBO_CHANGED, SLOT(OnBoundsType(int))); + HookWidget(ui->boundsAlign, COMBO_CHANGED, SLOT(OnControlChanged())); + HookWidget(ui->boundsWidth, DSCROLL_CHANGED, SLOT(OnControlChanged())); HookWidget(ui->boundsHeight, DSCROLL_CHANGED, SLOT(OnControlChanged())); - HookWidget(ui->cropLeft, ISCROLL_CHANGED, SLOT(OnCropChanged())); - HookWidget(ui->cropRight, ISCROLL_CHANGED, SLOT(OnCropChanged())); - HookWidget(ui->cropTop, ISCROLL_CHANGED, SLOT(OnCropChanged())); - HookWidget(ui->cropBottom, ISCROLL_CHANGED, SLOT(OnCropChanged())); + HookWidget(ui->cropLeft, ISCROLL_CHANGED, SLOT(OnCropChanged())); + HookWidget(ui->cropRight, ISCROLL_CHANGED, SLOT(OnCropChanged())); + HookWidget(ui->cropTop, ISCROLL_CHANGED, SLOT(OnCropChanged())); + HookWidget(ui->cropBottom, ISCROLL_CHANGED, SLOT(OnCropChanged())); ui->buttonBox->button(QDialogButtonBox::Close)->setDefault(true); @@ -76,7 +74,7 @@ OBSBasicTransform::OBSBasicTransform(OBSBasic *parent) SetItem(item); channelChangedSignal.Connect(obs_get_signal_handler(), "channel_change", - OBSChannelChanged, this); + OBSChannelChanged, this); } void OBSBasicTransform::SetScene(OBSScene scene) @@ -88,23 +86,24 @@ void OBSBasicTransform::SetScene(OBSScene scene) if (scene) { OBSSource source = obs_scene_get_source(scene); - signal_handler_t *signal = obs_source_get_signal_handler(source); + signal_handler_t *signal = + obs_source_get_signal_handler(source); transformSignal.Connect(signal, "item_transform", - OBSSceneItemTransform, this); - removeSignal.Connect(signal, "item_remove", - OBSSceneItemRemoved, this); - selectSignal.Connect(signal, "item_select", - OBSSceneItemSelect, this); + OBSSceneItemTransform, this); + removeSignal.Connect(signal, "item_remove", OBSSceneItemRemoved, + this); + selectSignal.Connect(signal, "item_select", OBSSceneItemSelect, + this); deselectSignal.Connect(signal, "item_deselect", - OBSSceneItemDeselect, this); + OBSSceneItemDeselect, this); } } void OBSBasicTransform::SetItem(OBSSceneItem newItem) { QMetaObject::invokeMethod(this, "SetItemQt", - Q_ARG(OBSSceneItem, OBSSceneItem(newItem))); + Q_ARG(OBSSceneItem, OBSSceneItem(newItem))); } void OBSBasicTransform::SetItemQt(OBSSceneItem newItem) @@ -118,9 +117,10 @@ void OBSBasicTransform::SetItemQt(OBSSceneItem newItem) void OBSBasicTransform::OBSChannelChanged(void *param, calldata_t *data) { - OBSBasicTransform *window = reinterpret_cast(param); + OBSBasicTransform *window = + reinterpret_cast(param); uint32_t channel = (uint32_t)calldata_int(data, "channel"); - OBSSource source = (obs_source_t*)calldata_ptr(data, "source"); + OBSSource source = (obs_source_t *)calldata_ptr(data, "source"); if (channel == 0) { OBSScene scene = obs_scene_from_source(source); @@ -135,8 +135,9 @@ void OBSBasicTransform::OBSChannelChanged(void *param, calldata_t *data) void OBSBasicTransform::OBSSceneItemTransform(void *param, calldata_t *data) { - OBSBasicTransform *window = reinterpret_cast(param); - OBSSceneItem item = (obs_sceneitem_t*)calldata_ptr(data, "item"); + OBSBasicTransform *window = + reinterpret_cast(param); + OBSSceneItem item = (obs_sceneitem_t *)calldata_ptr(data, "item"); if (item == window->item && !window->ignoreTransformSignal) QMetaObject::invokeMethod(window, "RefreshControls"); @@ -144,9 +145,10 @@ void OBSBasicTransform::OBSSceneItemTransform(void *param, calldata_t *data) void OBSBasicTransform::OBSSceneItemRemoved(void *param, calldata_t *data) { - OBSBasicTransform *window = reinterpret_cast(param); - OBSScene scene = (obs_scene_t*)calldata_ptr(data, "scene"); - OBSSceneItem item = (obs_sceneitem_t*)calldata_ptr(data, "item"); + OBSBasicTransform *window = + reinterpret_cast(param); + OBSScene scene = (obs_scene_t *)calldata_ptr(data, "scene"); + OBSSceneItem item = (obs_sceneitem_t *)calldata_ptr(data, "item"); if (item == window->item) window->SetItem(FindASelectedItem(scene)); @@ -154,8 +156,9 @@ void OBSBasicTransform::OBSSceneItemRemoved(void *param, calldata_t *data) void OBSBasicTransform::OBSSceneItemSelect(void *param, calldata_t *data) { - OBSBasicTransform *window = reinterpret_cast(param); - OBSSceneItem item = (obs_sceneitem_t*)calldata_ptr(data, "item"); + OBSBasicTransform *window = + reinterpret_cast(param); + OBSSceneItem item = (obs_sceneitem_t *)calldata_ptr(data, "item"); if (item != window->item) window->SetItem(item); @@ -163,25 +166,24 @@ void OBSBasicTransform::OBSSceneItemSelect(void *param, calldata_t *data) void OBSBasicTransform::OBSSceneItemDeselect(void *param, calldata_t *data) { - OBSBasicTransform *window = reinterpret_cast(param); - OBSScene scene = (obs_scene_t*)calldata_ptr(data, "scene"); - OBSSceneItem item = (obs_sceneitem_t*)calldata_ptr(data, "item"); + OBSBasicTransform *window = + reinterpret_cast(param); + OBSScene scene = (obs_scene_t *)calldata_ptr(data, "scene"); + OBSSceneItem item = (obs_sceneitem_t *)calldata_ptr(data, "item"); if (item == window->item) window->SetItem(FindASelectedItem(scene)); } -static const uint32_t listToAlign[] = { - OBS_ALIGN_TOP | OBS_ALIGN_LEFT, - OBS_ALIGN_TOP, - OBS_ALIGN_TOP | OBS_ALIGN_RIGHT, - OBS_ALIGN_LEFT, - OBS_ALIGN_CENTER, - OBS_ALIGN_RIGHT, - OBS_ALIGN_BOTTOM | OBS_ALIGN_LEFT, - OBS_ALIGN_BOTTOM, - OBS_ALIGN_BOTTOM | OBS_ALIGN_RIGHT -}; +static const uint32_t listToAlign[] = {OBS_ALIGN_TOP | OBS_ALIGN_LEFT, + OBS_ALIGN_TOP, + OBS_ALIGN_TOP | OBS_ALIGN_RIGHT, + OBS_ALIGN_LEFT, + OBS_ALIGN_CENTER, + OBS_ALIGN_RIGHT, + OBS_ALIGN_BOTTOM | OBS_ALIGN_LEFT, + OBS_ALIGN_BOTTOM, + OBS_ALIGN_BOTTOM | OBS_ALIGN_RIGHT}; static int AlignToList(uint32_t align) { @@ -207,10 +209,10 @@ void OBSBasicTransform::RefreshControls() obs_sceneitem_get_crop(item, &crop); obs_source_t *source = obs_sceneitem_get_source(item); - float width = float(obs_source_get_width(source)); + float width = float(obs_source_get_width(source)); float height = float(obs_source_get_height(source)); - int alignIndex = AlignToList(osi.alignment); + int alignIndex = AlignToList(osi.alignment); int boundsAlignIndex = AlignToList(osi.bounds_alignment); ignoreItemChange = true; @@ -238,8 +240,8 @@ void OBSBasicTransform::OnBoundsType(int index) if (index == -1) return; - obs_bounds_type type = (obs_bounds_type)index; - bool enable = (type != OBS_BOUNDS_NONE); + obs_bounds_type type = (obs_bounds_type)index; + bool enable = (type != OBS_BOUNDS_NONE); ui->boundsAlign->setEnabled(enable); ui->boundsWidth->setEnabled(enable); @@ -249,7 +251,7 @@ void OBSBasicTransform::OnBoundsType(int index) obs_bounds_type lastType = obs_sceneitem_get_bounds_type(item); if (lastType == OBS_BOUNDS_NONE) { OBSSource source = obs_sceneitem_get_source(item); - int width = (int)obs_source_get_width(source); + int width = (int)obs_source_get_width(source); int height = (int)obs_source_get_height(source); ui->boundsWidth->setValue(width); @@ -266,21 +268,21 @@ void OBSBasicTransform::OnControlChanged() return; obs_source_t *source = obs_sceneitem_get_source(item); - double width = double(obs_source_get_width(source)); + double width = double(obs_source_get_width(source)); double height = double(obs_source_get_height(source)); obs_transform_info oti; - oti.pos.x = float(ui->positionX->value()); - oti.pos.y = float(ui->positionY->value()); - oti.rot = float(ui->rotation->value()); - oti.scale.x = float(ui->sizeX->value() / width); - oti.scale.y = float(ui->sizeY->value() / height); - oti.alignment = listToAlign[ui->align->currentIndex()]; + oti.pos.x = float(ui->positionX->value()); + oti.pos.y = float(ui->positionY->value()); + oti.rot = float(ui->rotation->value()); + oti.scale.x = float(ui->sizeX->value() / width); + oti.scale.y = float(ui->sizeY->value() / height); + oti.alignment = listToAlign[ui->align->currentIndex()]; - oti.bounds_type = (obs_bounds_type)ui->boundsType->currentIndex(); + oti.bounds_type = (obs_bounds_type)ui->boundsType->currentIndex(); oti.bounds_alignment = listToAlign[ui->boundsAlign->currentIndex()]; - oti.bounds.x = float(ui->boundsWidth->value()); - oti.bounds.y = float(ui->boundsHeight->value()); + oti.bounds.x = float(ui->boundsWidth->value()); + oti.bounds.y = float(ui->boundsHeight->value()); ignoreTransformSignal = true; obs_sceneitem_set_info(item, &oti); @@ -293,9 +295,9 @@ void OBSBasicTransform::OnCropChanged() return; obs_sceneitem_crop crop; - crop.left = uint32_t(ui->cropLeft->value()); - crop.right = uint32_t(ui->cropRight->value()); - crop.top = uint32_t(ui->cropTop->value()); + crop.left = uint32_t(ui->cropLeft->value()); + crop.right = uint32_t(ui->cropRight->value()); + crop.top = uint32_t(ui->cropTop->value()); crop.bottom = uint32_t(ui->cropBottom->value()); ignoreTransformSignal = true; diff --git a/UI/window-basic-transform.hpp b/UI/window-basic-transform.hpp index c86a244..bc0528d 100644 --- a/UI/window-basic-transform.hpp +++ b/UI/window-basic-transform.hpp @@ -13,16 +13,16 @@ class OBSBasicTransform : public QDialog { private: std::unique_ptr ui; - OBSBasic *main; + OBSBasic *main; OBSSceneItem item; - OBSSignal channelChangedSignal; - OBSSignal transformSignal; - OBSSignal removeSignal; - OBSSignal selectSignal; - OBSSignal deselectSignal; + OBSSignal channelChangedSignal; + OBSSignal transformSignal; + OBSSignal removeSignal; + OBSSignal selectSignal; + OBSSignal deselectSignal; - bool ignoreTransformSignal = false; - bool ignoreItemChange = false; + bool ignoreTransformSignal = false; + bool ignoreItemChange = false; void HookWidget(QWidget *widget, const char *signal, const char *slot); diff --git a/UI/window-dock-browser.cpp b/UI/window-dock-browser.cpp new file mode 100644 index 0000000..7ae55e7 --- /dev/null +++ b/UI/window-dock-browser.cpp @@ -0,0 +1,20 @@ +#include "window-dock-browser.hpp" +#include + +void BrowserDock::closeEvent(QCloseEvent *event) +{ + OBSDock::closeEvent(event); + + if (!event->isAccepted()) { + return; + } + + static int panel_version = -1; + if (panel_version == -1) { + panel_version = obs_browser_qcef_version(); + } + + if (panel_version >= 2 && !!cefWidget) { + cefWidget->closeBrowser(); + } +} diff --git a/UI/window-dock-browser.hpp b/UI/window-dock-browser.hpp new file mode 100644 index 0000000..47e52cb --- /dev/null +++ b/UI/window-dock-browser.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include "window-dock.hpp" +#include + +#include +extern QCef *cef; +extern QCefCookieManager *panel_cookies; + +class BrowserDock : public OBSDock { +public: + inline BrowserDock() : OBSDock() {} + + QScopedPointer cefWidget; + + inline void SetWidget(QCefWidget *widget_) + { + setWidget(widget_); + cefWidget.reset(widget_); + } + + void closeEvent(QCloseEvent *event) override; +}; diff --git a/UI/window-dock.cpp b/UI/window-dock.cpp index 840c4f7..ed8e928 100644 --- a/UI/window-dock.cpp +++ b/UI/window-dock.cpp @@ -6,8 +6,7 @@ void OBSDock::closeEvent(QCloseEvent *event) { - auto msgBox = [] () - { + auto msgBox = []() { QMessageBox msgbox(App()->GetMainWindow()); msgbox.setWindowTitle(QTStr("DockCloseWarning.Title")); msgbox.setText(QTStr("DockCloseWarning.Text")); @@ -27,11 +26,10 @@ void OBSDock::closeEvent(QCloseEvent *event) }; bool warned = config_get_bool(App()->GlobalConfig(), "General", - "WarnedAboutClosingDocks"); + "WarnedAboutClosingDocks"); if (!warned) { - QMetaObject::invokeMethod(App(), "Exec", - Qt::QueuedConnection, - Q_ARG(VoidFunc, msgBox)); + QMetaObject::invokeMethod(App(), "Exec", Qt::QueuedConnection, + Q_ARG(VoidFunc, msgBox)); } QDockWidget::closeEvent(event); diff --git a/UI/window-extra-browsers.cpp b/UI/window-extra-browsers.cpp new file mode 100644 index 0000000..f6ff2d5 --- /dev/null +++ b/UI/window-extra-browsers.cpp @@ -0,0 +1,562 @@ +#include "window-extra-browsers.hpp" +#include "window-dock-browser.hpp" +#include "window-basic-main.hpp" +#include "qt-wrappers.hpp" + +#include +#include + +#include + +#include "ui_OBSExtraBrowsers.h" + +using namespace json11; + +#define OBJ_NAME_SUFFIX "_extraBrowser" + +enum class Column : int { + Title, + Url, + Delete, + + Count, +}; + +/* ------------------------------------------------------------------------- */ + +void ExtraBrowsersModel::Reset() +{ + items.clear(); + + OBSBasic *main = OBSBasic::Get(); + + for (int i = 0; i < main->extraBrowserDocks.size(); i++) { + BrowserDock *dock = reinterpret_cast( + main->extraBrowserDocks[i].data()); + + Item item; + item.prevIdx = i; + item.title = dock->windowTitle(); + item.url = main->extraBrowserDockTargets[i]; + items.push_back(item); + } +} + +int ExtraBrowsersModel::rowCount(const QModelIndex &) const +{ + int count = items.size() + 1; + return count; +} + +int ExtraBrowsersModel::columnCount(const QModelIndex &) const +{ + return (int)Column::Count; +} + +QVariant ExtraBrowsersModel::data(const QModelIndex &index, int role) const +{ + int column = index.column(); + int idx = index.row(); + int count = items.size(); + bool validRole = role == Qt::DisplayRole || + role == Qt::AccessibleTextRole; + + if (!validRole) + return QVariant(); + + if (idx >= 0 && idx < count) { + switch (column) { + case (int)Column::Title: + return items[idx].title; + case (int)Column::Url: + return items[idx].url; + } + } else if (idx == count) { + switch (column) { + case (int)Column::Title: + return newTitle; + case (int)Column::Url: + return newURL; + } + } + + return QVariant(); +} + +QVariant ExtraBrowsersModel::headerData(int section, + Qt::Orientation orientation, + int role) const +{ + bool validRole = role == Qt::DisplayRole || + role == Qt::AccessibleTextRole; + + if (validRole && orientation == Qt::Orientation::Horizontal) { + switch (section) { + case (int)Column::Title: + return QTStr("ExtraBrowsers.DockName"); + case (int)Column::Url: + return QStringLiteral("URL"); + } + } + + return QVariant(); +} + +Qt::ItemFlags ExtraBrowsersModel::flags(const QModelIndex &index) const +{ + Qt::ItemFlags flags = QAbstractTableModel::flags(index); + + if (index.column() != (int)Column::Delete) + flags |= Qt::ItemIsEditable; + + return flags; +} + +class DelButton : public QPushButton { +public: + inline DelButton(QModelIndex index_) : QPushButton(), index(index_) {} + + QPersistentModelIndex index; +}; + +class EditWidget : public QLineEdit { +public: + inline EditWidget(QWidget *parent, QModelIndex index_) + : QLineEdit(parent), index(index_) + { + } + + QPersistentModelIndex index; +}; + +void ExtraBrowsersModel::AddDeleteButton(int idx) +{ + QTableView *widget = reinterpret_cast(parent()); + + QModelIndex index = createIndex(idx, (int)Column::Delete, nullptr); + + QPushButton *del = new DelButton(index); + del->setProperty("themeID", "trashIcon"); + del->setObjectName("extraPanelDelete"); + del->setFixedSize(QSize(20, 20)); + connect(del, &QPushButton::clicked, this, + &ExtraBrowsersModel::DeleteItem); + + widget->setIndexWidget(index, del); + widget->setRowHeight(idx, 20); + widget->setColumnWidth(idx, 20); +} + +void ExtraBrowsersModel::CheckToAdd() +{ + if (newTitle.isEmpty() || newURL.isEmpty()) + return; + + int idx = items.size() + 1; + beginInsertRows(QModelIndex(), idx, idx); + + Item item; + item.prevIdx = -1; + item.title = newTitle; + item.url = newURL; + items.push_back(item); + + newTitle = ""; + newURL = ""; + + endInsertRows(); + + AddDeleteButton(idx - 1); +} + +void ExtraBrowsersModel::UpdateItem(Item &item) +{ + int idx = item.prevIdx; + + OBSBasic *main = OBSBasic::Get(); + BrowserDock *dock = reinterpret_cast( + main->extraBrowserDocks[idx].data()); + dock->setWindowTitle(item.title); + dock->setObjectName(item.title + OBJ_NAME_SUFFIX); + main->extraBrowserDockActions[idx]->setText(item.title); + + if (main->extraBrowserDockTargets[idx] != item.url) { + dock->cefWidget->setURL(QT_TO_UTF8(item.url)); + main->extraBrowserDockTargets[idx] = item.url; + } +} + +void ExtraBrowsersModel::DeleteItem() +{ + QTableView *widget = reinterpret_cast(parent()); + + DelButton *del = reinterpret_cast(sender()); + int row = del->index.row(); + + /* there's some sort of internal bug in Qt and deleting certain index + * widgets or "editors" that can cause a crash inside Qt if the widget + * is not manually removed, at least on 5.7 */ + widget->setIndexWidget(del->index, nullptr); + del->deleteLater(); + + /* --------- */ + + beginRemoveRows(QModelIndex(), row, row); + + int prevIdx = items[row].prevIdx; + items.removeAt(row); + + if (prevIdx != -1) { + int i = 0; + for (; i < deleted.size() && deleted[i] < prevIdx; i++) + ; + deleted.insert(i, prevIdx); + } + + endRemoveRows(); +} + +void ExtraBrowsersModel::Apply() +{ + OBSBasic *main = OBSBasic::Get(); + + for (Item &item : items) { + if (item.prevIdx != -1) { + UpdateItem(item); + } else { + main->AddExtraBrowserDock(item.title, item.url, true); + } + } + + for (int i = deleted.size() - 1; i >= 0; i--) { + int idx = deleted[i]; + main->extraBrowserDockActions.removeAt(idx); + main->extraBrowserDockTargets.removeAt(idx); + main->extraBrowserDocks.removeAt(idx); + } + + deleted.clear(); + + Reset(); +} + +void ExtraBrowsersModel::TabSelection(bool forward) +{ + QListView *widget = reinterpret_cast(parent()); + QItemSelectionModel *selModel = widget->selectionModel(); + + QModelIndex sel = selModel->currentIndex(); + int row = sel.row(); + int col = sel.column(); + + switch (sel.column()) { + case (int)Column::Title: + if (!forward) { + if (row == 0) { + return; + } + + row -= 1; + } + + col += 1; + break; + + case (int)Column::Url: + if (forward) { + if (row == items.size()) { + return; + } + + row += 1; + } + + col -= 1; + } + + sel = createIndex(row, col, nullptr); + selModel->setCurrentIndex(sel, QItemSelectionModel::Clear); +} + +void ExtraBrowsersModel::Init() +{ + for (int i = 0; i < items.count(); i++) + AddDeleteButton(i); +} + +/* ------------------------------------------------------------------------- */ + +QWidget *ExtraBrowsersDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem &, + const QModelIndex &index) const +{ + QLineEdit *text = new EditWidget(parent, index); + text->installEventFilter(const_cast(this)); + text->setSizePolicy(QSizePolicy(QSizePolicy::Policy::Expanding, + QSizePolicy::Policy::Expanding, + QSizePolicy::ControlType::LineEdit)); + return text; +} + +void ExtraBrowsersDelegate::setEditorData(QWidget *editor, + const QModelIndex &index) const +{ + QLineEdit *text = reinterpret_cast(editor); + text->blockSignals(true); + text->setText(index.data().toString()); + text->blockSignals(false); +} + +bool ExtraBrowsersDelegate::eventFilter(QObject *object, QEvent *event) +{ + QLineEdit *edit = qobject_cast(object); + if (!edit) + return false; + + if (LineEditCanceled(event)) { + RevertText(edit); + } + if (LineEditChanged(event)) { + UpdateText(edit); + + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Tab) { + model->TabSelection(true); + } else if (keyEvent->key() == Qt::Key_Backtab) { + model->TabSelection(false); + } + } + return true; + } + + return false; +} + +bool ExtraBrowsersDelegate::ValidName(const QString &name) const +{ + for (auto &item : model->items) { + if (name.compare(item.title, Qt::CaseInsensitive) == 0) { + return false; + } + } + return true; +} + +void ExtraBrowsersDelegate::RevertText(QLineEdit *edit_) +{ + EditWidget *edit = reinterpret_cast(edit_); + int row = edit->index.row(); + int col = edit->index.column(); + bool newItem = (row == model->items.size()); + + QString oldText; + if (col == (int)Column::Title) { + oldText = newItem ? model->newTitle : model->items[row].title; + } else { + oldText = newItem ? model->newURL : model->items[row].url; + } + + edit->setText(oldText); +} + +bool ExtraBrowsersDelegate::UpdateText(QLineEdit *edit_) +{ + EditWidget *edit = reinterpret_cast(edit_); + int row = edit->index.row(); + int col = edit->index.column(); + bool newItem = (row == model->items.size()); + + QString text = edit->text().trimmed(); + + if (!newItem && text.isEmpty()) { + return false; + } + + if (col == (int)Column::Title) { + QString oldText = newItem ? model->newTitle + : model->items[row].title; + bool same = oldText.compare(text, Qt::CaseInsensitive) == 0; + + if (!same && !ValidName(text)) { + edit->setText(oldText); + return false; + } + } + + if (!newItem) { + /* if edited existing item, update it*/ + switch (col) { + case (int)Column::Title: + model->items[row].title = text; + break; + case (int)Column::Url: + model->items[row].url = text; + break; + } + } else { + /* if both new values filled out, create new one */ + switch (col) { + case (int)Column::Title: + model->newTitle = text; + break; + case (int)Column::Url: + model->newURL = text; + break; + } + + model->CheckToAdd(); + } + + emit commitData(edit); + return true; +} + +/* ------------------------------------------------------------------------- */ + +OBSExtraBrowsers::OBSExtraBrowsers(QWidget *parent) + : QDialog(parent), ui(new Ui::OBSExtraBrowsers) +{ + ui->setupUi(this); + + setAttribute(Qt::WA_DeleteOnClose, true); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + + model = new ExtraBrowsersModel(ui->table); + + ui->table->setModel(model); + ui->table->setItemDelegateForColumn((int)Column::Title, + new ExtraBrowsersDelegate(model)); + ui->table->setItemDelegateForColumn((int)Column::Url, + new ExtraBrowsersDelegate(model)); + ui->table->horizontalHeader()->setSectionResizeMode( + QHeaderView::ResizeMode::Stretch); + ui->table->horizontalHeader()->setSectionResizeMode( + (int)Column::Delete, QHeaderView::ResizeMode::Fixed); + ui->table->setEditTriggers( + QAbstractItemView::EditTrigger::CurrentChanged); +} + +OBSExtraBrowsers::~OBSExtraBrowsers() +{ + delete ui; +} + +void OBSExtraBrowsers::closeEvent(QCloseEvent *event) +{ + QDialog::closeEvent(event); + model->Apply(); +} + +void OBSExtraBrowsers::on_apply_clicked() +{ + model->Apply(); +} + +/* ------------------------------------------------------------------------- */ + +void OBSBasic::ClearExtraBrowserDocks() +{ + extraBrowserDockTargets.clear(); + extraBrowserDockActions.clear(); + extraBrowserDocks.clear(); +} + +void OBSBasic::LoadExtraBrowserDocks() +{ + const char *jsonStr = config_get_string( + App()->GlobalConfig(), "BasicWindow", "ExtraBrowserDocks"); + + std::string err; + Json json = Json::parse(jsonStr, err); + if (!err.empty()) + return; + + Json::array array = json.array_items(); + for (Json &item : array) { + std::string title = item["title"].string_value(); + std::string url = item["url"].string_value(); + + AddExtraBrowserDock(title.c_str(), url.c_str(), false); + } +} + +void OBSBasic::SaveExtraBrowserDocks() +{ + Json::array array; + for (int i = 0; i < extraBrowserDocks.size(); i++) { + QAction *action = extraBrowserDockActions[i].data(); + QString url = extraBrowserDockTargets[i]; + Json::object obj{ + {"title", QT_TO_UTF8(action->text())}, + {"url", QT_TO_UTF8(url)}, + }; + array.push_back(obj); + } + + std::string output = Json(array).dump(); + config_set_string(App()->GlobalConfig(), "BasicWindow", + "ExtraBrowserDocks", output.c_str()); +} + +void OBSBasic::ManageExtraBrowserDocks() +{ + if (!extraBrowsers.isNull()) { + extraBrowsers->show(); + extraBrowsers->raise(); + return; + } + + extraBrowsers = new OBSExtraBrowsers(this); + extraBrowsers->show(); +} + +void OBSBasic::AddExtraBrowserDock(const QString &title, const QString &url, + bool firstCreate) +{ + static int panel_version = -1; + if (panel_version == -1) { + panel_version = obs_browser_qcef_version(); + } + + BrowserDock *dock = new BrowserDock(); + dock->setObjectName(title + OBJ_NAME_SUFFIX); + dock->resize(460, 600); + dock->setMinimumSize(150, 150); + dock->setWindowTitle(title); + dock->setAllowedAreas(Qt::AllDockWidgetAreas); + + QCefWidget *browser = + cef->create_widget(nullptr, QT_TO_UTF8(url), nullptr); + if (browser && panel_version >= 1) + browser->allowAllPopups(true); + + dock->SetWidget(browser); + + addDockWidget(Qt::RightDockWidgetArea, dock); + + if (firstCreate) { + dock->setFloating(true); + + QPoint curPos = pos(); + QSize wSizeD2 = size() / 2; + QSize dSizeD2 = dock->size() / 2; + + curPos.setX(curPos.x() + wSizeD2.width() - dSizeD2.width()); + curPos.setY(curPos.y() + wSizeD2.height() - dSizeD2.height()); + + dock->move(curPos); + dock->setVisible(true); + } + + QAction *action = AddDockWidget(dock); + if (firstCreate) { + action->blockSignals(true); + action->setChecked(true); + action->blockSignals(false); + } + + extraBrowserDocks.push_back(QSharedPointer(dock)); + extraBrowserDockActions.push_back(QSharedPointer(action)); + extraBrowserDockTargets.push_back(url); +} diff --git a/UI/window-extra-browsers.hpp b/UI/window-extra-browsers.hpp new file mode 100644 index 0000000..cdfb14b --- /dev/null +++ b/UI/window-extra-browsers.hpp @@ -0,0 +1,95 @@ +#pragma once + +#include +#include +#include +#include + +class Ui_OBSExtraBrowsers; +class ExtraBrowsersModel; + +class QCefWidget; + +class OBSExtraBrowsers : public QDialog { + Q_OBJECT + + Ui_OBSExtraBrowsers *ui; + ExtraBrowsersModel *model; + +public: + OBSExtraBrowsers(QWidget *parent); + ~OBSExtraBrowsers(); + + void closeEvent(QCloseEvent *event) override; + +public slots: + void on_apply_clicked(); +}; + +class ExtraBrowsersModel : public QAbstractTableModel { + Q_OBJECT + +public: + inline ExtraBrowsersModel(QObject *parent = nullptr) + : QAbstractTableModel(parent) + { + Reset(); + QMetaObject::invokeMethod(this, "Init", Qt::QueuedConnection); + } + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int + columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role) const override; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + + struct Item { + int prevIdx; + QString title; + QString url; + }; + + void TabSelection(bool forward); + + void AddDeleteButton(int idx); + void Reset(); + void CheckToAdd(); + void UpdateItem(Item &item); + void DeleteItem(); + void Apply(); + + QVector items; + QVector deleted; + + QString newTitle; + QString newURL; + +public slots: + void Init(); +}; + +class ExtraBrowsersDelegate : public QStyledItemDelegate { + Q_OBJECT + +public: + inline ExtraBrowsersDelegate(ExtraBrowsersModel *model_) + : QStyledItemDelegate(nullptr), model(model_) + { + } + + QWidget *createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + + void setEditorData(QWidget *editor, + const QModelIndex &index) const override; + + bool eventFilter(QObject *object, QEvent *event) override; + void RevertText(QLineEdit *edit); + bool UpdateText(QLineEdit *edit); + bool ValidName(const QString &text) const; + + ExtraBrowsersModel *model; +}; diff --git a/UI/window-log-reply.cpp b/UI/window-log-reply.cpp index 5f74a6d..7be665e 100644 --- a/UI/window-log-reply.cpp +++ b/UI/window-log-reply.cpp @@ -20,8 +20,7 @@ #include "obs-app.hpp" OBSLogReply::OBSLogReply(QWidget *parent, const QString &url) - : QDialog (parent), - ui (new Ui::OBSLogReply) + : QDialog(parent), ui(new Ui::OBSLogReply) { ui->setupUi(this); ui->urlEdit->setText(url); diff --git a/UI/window-main.hpp b/UI/window-main.hpp index ec24988..5b39da6 100644 --- a/UI/window-main.hpp +++ b/UI/window-main.hpp @@ -10,9 +10,9 @@ class OBSMainWindow : public QMainWindow { public: inline OBSMainWindow(QWidget *parent) : QMainWindow(parent) {} - virtual config_t *Config() const=0; - virtual void OBSInit()=0; + virtual config_t *Config() const = 0; + virtual void OBSInit() = 0; - virtual int GetProfilePath(char *path, size_t size, const char *file) - const=0; + virtual int GetProfilePath(char *path, size_t size, + const char *file) const = 0; }; diff --git a/UI/window-namedialog.cpp b/UI/window-namedialog.cpp index 18b2fee..395e659 100644 --- a/UI/window-namedialog.cpp +++ b/UI/window-namedialog.cpp @@ -23,8 +23,7 @@ using namespace std; NameDialog::NameDialog(QWidget *parent) - : QDialog (parent), - ui (new Ui::NameDialog) + : QDialog(parent), ui(new Ui::NameDialog) { ui->setupUi(this); @@ -37,15 +36,16 @@ static bool IsWhitespace(char ch) } bool NameDialog::AskForName(QWidget *parent, const QString &title, - const QString &text, string &str, const QString &placeHolder, - int maxSize) + const QString &text, string &str, + const QString &placeHolder, int maxSize) { if (maxSize <= 0 || maxSize > 32767) - maxSize = 256; + maxSize = 170; NameDialog dialog(parent); dialog.setWindowTitle(title); - dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint); + dialog.setWindowFlags(dialog.windowFlags() & + ~Qt::WindowContextHelpButtonHint); dialog.ui->label->setText(text); dialog.ui->userText->setMaxLength(maxSize); dialog.ui->userText->setText(placeHolder); diff --git a/UI/window-namedialog.hpp b/UI/window-namedialog.hpp index 8bce854..0b33da2 100644 --- a/UI/window-namedialog.hpp +++ b/UI/window-namedialog.hpp @@ -33,7 +33,7 @@ public: NameDialog(QWidget *parent); static bool AskForName(QWidget *parent, const QString &title, - const QString &text, std::string &str, - const QString &placeHolder = QString(""), - int maxSize = 256); + const QString &text, std::string &str, + const QString &placeHolder = QString(""), + int maxSize = 170); }; diff --git a/UI/window-projector.cpp b/UI/window-projector.cpp index 294c31d..6dd74ab 100644 --- a/UI/window-projector.cpp +++ b/UI/window-projector.cpp @@ -12,26 +12,25 @@ static QList windowedProjectors; static QList multiviewProjectors; static bool updatingMultiview = false, drawLabel, drawSafeArea, mouseSwitching, - transitionOnDoubleClick; + transitionOnDoubleClick; static MultiviewLayout multiviewLayout; static size_t maxSrcs, numSrcs; OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor, - QString title, ProjectorType type_) - : OBSQTDisplay (widget, - Qt::Window), - source (source_), - removedSignal (obs_source_get_signal_handler(source), - "remove", OBSSourceRemoved, this) + QString title, ProjectorType type_) + : OBSQTDisplay(widget, Qt::Window), + source(source_), + removedSignal(obs_source_get_signal_handler(source), "remove", + OBSSourceRemoved, this) { projectorTitle = std::move(title); - savedMonitor = monitor; - isWindow = savedMonitor < 0; - type = type_; + savedMonitor = monitor; + isWindow = savedMonitor < 0; + type = type_; if (isWindow) { - setWindowIcon(QIcon::fromTheme("obs", - QIcon(":/res/images/obs.png"))); + setWindowIcon( + QIcon::fromTheme("obs", QIcon(":/res/images/obs.png"))); UpdateProjectorTitle(projectorTitle); windowedProjectors.push_back(this); @@ -39,7 +38,7 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor, resize(480, 270); } else { setWindowFlags(Qt::FramelessWindowHint | - Qt::X11BypassWindowManagerHint); + Qt::X11BypassWindowManagerHint); QScreen *screen = QGuiApplication::screens()[savedMonitor]; setGeometry(screen->geometry()); @@ -48,11 +47,11 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor, action->setShortcut(Qt::Key_Escape); addAction(action); connect(action, SIGNAL(triggered()), this, - SLOT(EscapeTriggered())); + SLOT(EscapeTriggered())); } - SetAlwaysOnTop(this, config_get_bool(GetGlobalConfig(), - "BasicWindow", "ProjectorAlwaysOnTop")); + SetAlwaysOnTop(this, config_get_bool(GetGlobalConfig(), "BasicWindow", + "ProjectorAlwaysOnTop")); setAttribute(Qt::WA_DeleteOnClose, true); @@ -61,18 +60,18 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor, installEventFilter(CreateShortcutFilter()); - auto addDrawCallback = [this] () - { + auto addDrawCallback = [this]() { bool isMultiview = type == ProjectorType::Multiview; - obs_display_add_draw_callback(GetDisplay(), - isMultiview ? OBSRenderMultiview : OBSRender, - this); + obs_display_add_draw_callback( + GetDisplay(), + isMultiview ? OBSRenderMultiview : OBSRender, this); + obs_display_set_background_color(GetDisplay(), 0x000000); }; connect(this, &OBSQTDisplay::DisplayCreated, addDrawCallback); - bool hideCursor = config_get_bool(GetGlobalConfig(), - "BasicWindow", "HideProjectorCursor"); + bool hideCursor = config_get_bool(GetGlobalConfig(), "BasicWindow", + "HideProjectorCursor"); if (hideCursor && !isWindow && type != ProjectorType::Multiview) { QPixmap empty(16, 16); empty.fill(Qt::transparent); @@ -96,7 +95,7 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor, gs_vertex2f(graphicsSafePercentage, graphicsSafePercentage); gs_vertex2f(graphicsSafePercentage, 1 - graphicsSafePercentage); gs_vertex2f(1 - graphicsSafePercentage, - 1 - graphicsSafePercentage); + 1 - graphicsSafePercentage); gs_vertex2f(1 - graphicsSafePercentage, graphicsSafePercentage); gs_vertex2f(graphicsSafePercentage, graphicsSafePercentage); graphicsSafeMargin = gs_render_save(); @@ -105,11 +104,11 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor, gs_render_start(true); gs_vertex2f(fourByThreeSafePercentage, graphicsSafePercentage); gs_vertex2f(1 - fourByThreeSafePercentage, - graphicsSafePercentage); - gs_vertex2f(1 - fourByThreeSafePercentage, 1 - - graphicsSafePercentage); + graphicsSafePercentage); + gs_vertex2f(1 - fourByThreeSafePercentage, + 1 - graphicsSafePercentage); gs_vertex2f(fourByThreeSafePercentage, - 1 - graphicsSafePercentage); + 1 - graphicsSafePercentage); gs_vertex2f(fourByThreeSafePercentage, graphicsSafePercentage); fourByThreeSafeMargin = gs_render_save(); @@ -154,8 +153,9 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor, OBSProjector::~OBSProjector() { bool isMultiview = type == ProjectorType::Multiview; - obs_display_remove_draw_callback(GetDisplay(), - isMultiview ? OBSRenderMultiview : OBSRender, this); + obs_display_remove_draw_callback( + GetDisplay(), isMultiview ? OBSRenderMultiview : OBSRender, + this); if (source) obs_source_dec_showing(source); @@ -189,7 +189,7 @@ OBSProjector::~OBSProjector() static OBSSource CreateLabel(const char *name, size_t h) { obs_data_t *settings = obs_data_create(); - obs_data_t *font = obs_data_create(); + obs_data_t *font = obs_data_create(); std::string text; text += " "; @@ -216,8 +216,8 @@ static OBSSource CreateLabel(const char *name, size_t h) const char *text_source_id = "text_ft2_source"; #endif - OBSSource txtSource = obs_source_create_private(text_source_id, name, - settings); + OBSSource txtSource = + obs_source_create_private(text_source_id, name, settings); obs_source_release(txtSource); obs_data_release(font); @@ -245,7 +245,7 @@ static inline uint32_t labelOffset(obs_source_t *label, uint32_t cx) } static inline void startRegion(int vX, int vY, int vCX, int vCY, float oL, - float oR, float oT, float oB) + float oR, float oT, float oB) { gs_projection_push(); gs_viewport_push(); @@ -266,10 +266,10 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) if (updatingMultiview || !window->ready) return; - OBSBasic *main = (OBSBasic *)obs_frontend_get_main_window(); - uint32_t targetCX, targetCY; - int x, y; - float scale; + OBSBasic *main = (OBSBasic *)obs_frontend_get_main_window(); + uint32_t targetCX, targetCY; + int x, y; + float scale; targetCX = (uint32_t)window->fw; targetCY = (uint32_t)window->fh; @@ -281,8 +281,7 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) bool studioMode = main->IsPreviewProgramMode(); auto renderVB = [&](gs_vertbuffer_t *vb, int cx, int cy, - uint32_t colorVal) - { + uint32_t colorVal) { if (!vb) return; @@ -303,18 +302,15 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) gs_matrix_pop(); }; - auto drawBox = [&](float cx, float cy, uint32_t colorVal) - { + auto drawBox = [&](float cx, float cy, uint32_t colorVal) { gs_effect_set_color(window->color, colorVal); while (gs_effect_loop(window->solid, "Solid")) gs_draw_sprite(nullptr, 0, (uint32_t)cx, (uint32_t)cy); }; - auto setRegion = [&](float bx, float by, float cx, - float cy) - { - float vX = int(x + bx * scale); - float vY = int(y + by * scale); + auto setRegion = [&](float bx, float by, float cx, float cy) { + float vX = int(x + bx * scale); + float vY = int(y + by * scale); float vCX = int(cx * scale); float vCY = int(cy * scale); @@ -326,23 +322,22 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) startRegion(vX, vY, vCX, vCY, oL, oR, oT, oB); }; - auto calcBaseSource = [&](size_t i) - { + auto calcBaseSource = [&](size_t i) { switch (multiviewLayout) { case MultiviewLayout::HORIZONTAL_TOP_24_SCENES: window->sourceX = (i % 6) * window->scenesCX; - window->sourceY = window->pvwprgCY + - (i / 6) * window->scenesCY; + window->sourceY = + window->pvwprgCY + (i / 6) * window->scenesCY; break; case MultiviewLayout::VERTICAL_LEFT_8_SCENES: window->sourceX = window->pvwprgCX; - window->sourceY = (i / 2 ) * window->scenesCY; + window->sourceY = (i / 2) * window->scenesCY; if (i % 2 != 0) window->sourceX += window->scenesCX; break; case MultiviewLayout::VERTICAL_RIGHT_8_SCENES: window->sourceX = 0; - window->sourceY = (i / 2 ) * window->scenesCY; + window->sourceY = (i / 2) * window->scenesCY; if (i % 2 != 0) window->sourceX = window->scenesCX; break; @@ -351,8 +346,8 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) window->sourceX = (float(i) * window->scenesCX); window->sourceY = 0; } else { - window->sourceX = (float(i - 4) * - window->scenesCX); + window->sourceX = + (float(i - 4) * window->scenesCX); window->sourceY = window->scenesCY; } break; @@ -361,22 +356,21 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) window->sourceX = (float(i) * window->scenesCX); window->sourceY = window->pvwprgCY; } else { - window->sourceX = (float(i - 4) * - window->scenesCX); - window->sourceY = window->pvwprgCY + - window->scenesCY; + window->sourceX = + (float(i - 4) * window->scenesCX); + window->sourceY = + window->pvwprgCY + window->scenesCY; } } window->siX = window->sourceX + window->thickness; window->siY = window->sourceY + window->thickness; }; - auto calcPreviewProgram = [&](bool program) - { + auto calcPreviewProgram = [&](bool program) { switch (multiviewLayout) { case MultiviewLayout::HORIZONTAL_TOP_24_SCENES: - window->sourceX = window->thickness + - window->pvwprgCX / 2; + window->sourceX = + window->thickness + window->pvwprgCX / 2; window->sourceY = window->thickness; window->labelX = window->offset + window->pvwprgCX / 2; window->labelY = window->pvwprgCY * 0.85f; @@ -428,8 +422,7 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) }; auto paintAreaWithColor = [&](float tx, float ty, float cx, float cy, - uint32_t color) - { + uint32_t color) { gs_matrix_push(); gs_matrix_translate3f(tx, ty, 0.0f); drawBox(cx, cy, color); @@ -438,7 +431,7 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) // Define the whole usable region for the multiview startRegion(x, y, targetCX * scale, targetCY * scale, 0.0f, window->fw, - 0.0f, window->fh); + 0.0f, window->fh); // Change the background color to highlight all sources drawBox(window->fw, window->fh, outerColor); @@ -453,11 +446,11 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) if (i >= numSrcs) { // Just paint the background and continue paintAreaWithColor(window->sourceX, window->sourceY, - window->scenesCX, window->scenesCY, - outerColor); + window->scenesCX, window->scenesCY, + outerColor); paintAreaWithColor(window->siX, window->siY, - window->siCX, window->siCY, - backgroundColor); + window->siCX, window->siCY, + backgroundColor); continue; } @@ -472,9 +465,10 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) // Paint the background paintAreaWithColor(window->sourceX, window->sourceY, - window->scenesCX, window->scenesCY, colorVal); + window->scenesCX, window->scenesCY, + colorVal); paintAreaWithColor(window->siX, window->siY, window->siCX, - window->siCY, backgroundColor); + window->siCY, backgroundColor); /* ----------- */ @@ -500,13 +494,14 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) window->offset = labelOffset(label, window->scenesCX); gs_matrix_push(); - gs_matrix_translate3f(window->sourceX + window->offset, - (window->scenesCY * 0.85f) + window->sourceY, - 0.0f); + gs_matrix_translate3f( + window->sourceX + window->offset, + (window->scenesCY * 0.85f) + window->sourceY, 0.0f); gs_matrix_scale3f(window->ppiScaleX, window->ppiScaleY, 1.0f); drawBox(obs_source_get_width(label), - obs_source_get_height(label) + - int(window->sourceY * 0.015f), labelColor); + obs_source_get_height(label) + + int(window->sourceY * 0.015f), + labelColor); obs_source_video_render(label); gs_matrix_pop(); } @@ -520,25 +515,25 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) // Paint the background paintAreaWithColor(window->sourceX, window->sourceY, window->ppiCX, - window->ppiCY, backgroundColor); + window->ppiCY, backgroundColor); // Scale and Draw the preview gs_matrix_push(); gs_matrix_translate3f(window->sourceX, window->sourceY, 0.0f); gs_matrix_scale3f(window->ppiScaleX, window->ppiScaleY, 1.0f); setRegion(window->sourceX, window->sourceY, window->ppiCX, - window->ppiCY); + window->ppiCY); if (studioMode) obs_source_video_render(previewSrc); else obs_render_main_texture(); if (drawSafeArea) { renderVB(window->actionSafeMargin, targetCX, targetCY, - outerColor); + outerColor); renderVB(window->graphicsSafeMargin, targetCX, targetCY, - outerColor); + outerColor); renderVB(window->fourByThreeSafeMargin, targetCX, targetCY, - outerColor); + outerColor); renderVB(window->leftLine, targetCX, targetCY, outerColor); renderVB(window->topLine, targetCX, targetCY, outerColor); renderVB(window->rightLine, targetCX, targetCY, outerColor); @@ -554,8 +549,9 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) gs_matrix_translate3f(window->labelX, window->labelY, 0.0f); gs_matrix_scale3f(window->ppiScaleX, window->ppiScaleY, 1.0f); drawBox(obs_source_get_width(previewLabel), - obs_source_get_height(previewLabel) + - int(window->pvwprgCX * 0.015f), labelColor); + obs_source_get_height(previewLabel) + + int(window->pvwprgCX * 0.015f), + labelColor); obs_source_video_render(previewLabel); gs_matrix_pop(); } @@ -568,14 +564,14 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) calcPreviewProgram(true); paintAreaWithColor(window->sourceX, window->sourceY, window->ppiCX, - window->ppiCY, backgroundColor); + window->ppiCY, backgroundColor); // Scale and Draw the program gs_matrix_push(); gs_matrix_translate3f(window->sourceX, window->sourceY, 0.0f); gs_matrix_scale3f(window->ppiScaleX, window->ppiScaleY, 1.0f); setRegion(window->sourceX, window->sourceY, window->ppiCX, - window->ppiCY); + window->ppiCY); obs_render_main_texture(); endRegion(); gs_matrix_pop(); @@ -588,8 +584,9 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) gs_matrix_translate3f(window->labelX, window->labelY, 0.0f); gs_matrix_scale3f(window->ppiScaleX, window->ppiScaleY, 1.0f); drawBox(obs_source_get_width(programLabel), - obs_source_get_height(programLabel) + - int(window->pvwprgCX * 0.015f), labelColor); + obs_source_get_height(programLabel) + + int(window->pvwprgCX * 0.015f), + labelColor); obs_source_video_render(programLabel); gs_matrix_pop(); } @@ -598,13 +595,15 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) if (multiviewLayout == MultiviewLayout::HORIZONTAL_TOP_24_SCENES) { // Just paint the background for now paintAreaWithColor(window->thickness, window->thickness, - window->siCX, window->siCY * 2 + - window->thicknessx2, backgroundColor); - paintAreaWithColor(window->thickness + 2.5 * ( - window->thicknessx2 + window->ppiCX), - window->thickness, window->siCX, - window->siCY * 2 + window->thicknessx2, - backgroundColor); + window->siCX, + window->siCY * 2 + window->thicknessx2, + backgroundColor); + paintAreaWithColor( + window->thickness + + 2.5 * (window->thicknessx2 + window->ppiCX), + window->thickness, window->siCX, + window->siCY * 2 + window->thicknessx2, + backgroundColor); } endRegion(); @@ -612,19 +611,19 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy) { - OBSProjector *window = reinterpret_cast(data); + OBSProjector *window = reinterpret_cast(data); if (!window->ready) return; - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); OBSSource source = window->source; uint32_t targetCX; uint32_t targetCY; - int x, y; - int newCX, newCY; - float scale; + int x, y; + int newCX, newCY; + float scale; if (source) { targetCX = std::max(obs_source_get_width(source), 1u); @@ -642,7 +641,7 @@ void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy) newCY = int(scale * float(targetCY)); startRegion(x, y, newCX, newCY, 0.0f, float(targetCX), 0.0f, - float(targetCY)); + float(targetCY)); if (window->type == ProjectorType::Preview && main->IsPreviewProgramMode()) { @@ -666,7 +665,7 @@ void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy) void OBSProjector::OBSSourceRemoved(void *data, calldata_t *params) { - OBSProjector *window = reinterpret_cast(data); + OBSProjector *window = reinterpret_cast(data); window->deleteLater(); @@ -679,12 +678,12 @@ static int getSourceByPosition(int x, int y, float ratio) QWidget *rec = QApplication::activeWindow(); if (!rec) return pos; - int cx = rec->width(); - int cy = rec->height(); - int minX = 0; - int minY = 0; - int maxX = cx; - int maxY = cy; + int cx = rec->width(); + int cy = rec->height(); + int minX = 0; + int minY = 0; + int maxX = cx; + int maxY = cy; switch (multiviewLayout) { case MultiviewLayout::HORIZONTAL_TOP_24_SCENES: @@ -796,7 +795,7 @@ void OBSProjector::mouseDoubleClickEvent(QMouseEvent *event) if (!transitionOnDoubleClick) return; - OBSBasic *main = (OBSBasic*)obs_frontend_get_main_window(); + OBSBasic *main = (OBSBasic *)obs_frontend_get_main_window(); if (!main->IsPreviewProgramMode()) return; @@ -834,7 +833,7 @@ void OBSProjector::mousePressEvent(QMouseEvent *event) if (!src) return; - OBSBasic *main = (OBSBasic*)obs_frontend_get_main_window(); + OBSBasic *main = (OBSBasic *)obs_frontend_get_main_window(); if (main->GetCurrentSceneSource() != src) main->SetCurrentScene(src, false); } @@ -853,60 +852,60 @@ void OBSProjector::UpdateMultiview() struct obs_video_info ovi; obs_get_video_info(&ovi); - uint32_t w = ovi.base_width; - uint32_t h = ovi.base_height; - fw = float(w); - fh = float(h); - ratio = fw / fh; + uint32_t w = ovi.base_width; + uint32_t h = ovi.base_height; + fw = float(w); + fh = float(h); + ratio = fw / fh; struct obs_frontend_source_list scenes = {}; obs_frontend_get_scenes(&scenes); - multiviewLabels.emplace_back(CreateLabel(Str("StudioMode.Preview"), - h / 2)); - multiviewLabels.emplace_back(CreateLabel(Str("StudioMode.Program"), - h / 2)); + multiviewLabels.emplace_back( + CreateLabel(Str("StudioMode.Preview"), h / 2)); + multiviewLabels.emplace_back( + CreateLabel(Str("StudioMode.Program"), h / 2)); multiviewLayout = static_cast(config_get_int( - GetGlobalConfig(), "BasicWindow", "MultiviewLayout")); + GetGlobalConfig(), "BasicWindow", "MultiviewLayout")); - drawLabel = config_get_bool(GetGlobalConfig(), - "BasicWindow", "MultiviewDrawNames"); + drawLabel = config_get_bool(GetGlobalConfig(), "BasicWindow", + "MultiviewDrawNames"); drawSafeArea = config_get_bool(GetGlobalConfig(), "BasicWindow", - "MultiviewDrawAreas"); + "MultiviewDrawAreas"); mouseSwitching = config_get_bool(GetGlobalConfig(), "BasicWindow", - "MultiviewMouseSwitch"); + "MultiviewMouseSwitch"); - transitionOnDoubleClick = config_get_bool(GetGlobalConfig(), - "BasicWindow", "TransitionOnDoubleClick"); + transitionOnDoubleClick = config_get_bool( + GetGlobalConfig(), "BasicWindow", "TransitionOnDoubleClick"); - switch(multiviewLayout) { + switch (multiviewLayout) { case MultiviewLayout::HORIZONTAL_TOP_24_SCENES: - pvwprgCX = fw / 3; - pvwprgCY = fh / 3; + pvwprgCX = fw / 3; + pvwprgCY = fh / 3; maxSrcs = 24; break; default: - pvwprgCX = fw / 2; - pvwprgCY = fh / 2; + pvwprgCX = fw / 2; + pvwprgCY = fh / 2; maxSrcs = 8; } - ppiCX = pvwprgCX - thicknessx2; - ppiCY = pvwprgCY - thicknessx2; + ppiCX = pvwprgCX - thicknessx2; + ppiCY = pvwprgCY - thicknessx2; ppiScaleX = (pvwprgCX - thicknessx2) / fw; ppiScaleY = (pvwprgCY - thicknessx2) / fh; scenesCX = pvwprgCX / 2; scenesCY = pvwprgCY / 2; - siCX = scenesCX - thicknessx2; - siCY = scenesCY - thicknessx2; - siScaleX = (scenesCX - thicknessx2) / fw; - siScaleY = (scenesCY - thicknessx2) / fh; + siCX = scenesCX - thicknessx2; + siCY = scenesCY - thicknessx2; + siScaleX = (scenesCX - thicknessx2) / fw; + siScaleY = (scenesCY - thicknessx2) / fh; numSrcs = 0; size_t i = 0; @@ -926,7 +925,7 @@ void OBSProjector::UpdateMultiview() obs_source_inc_showing(src); std::string name = std::to_string(numSrcs) + " - " + - obs_source_get_name(src); + obs_source_get_name(src); multiviewLabels.emplace_back(CreateLabel(name.c_str(), h / 3)); } diff --git a/UI/window-projector.hpp b/UI/window-projector.hpp index 1ec629d..7ff9336 100644 --- a/UI/window-projector.hpp +++ b/UI/window-projector.hpp @@ -8,7 +8,7 @@ enum class ProjectorType { Scene, Preview, StudioProgram, - Multiview + Multiview, }; class QMouseEvent; @@ -18,7 +18,7 @@ enum class MultiviewLayout : uint8_t { HORIZONTAL_BOTTOM_8_SCENES = 1, VERTICAL_LEFT_8_SCENES = 2, VERTICAL_RIGHT_8_SCENES = 3, - HORIZONTAL_TOP_24_SCENES = 4 + HORIZONTAL_TOP_24_SCENES = 4, }; class OBSProjector : public OBSQTDisplay { @@ -41,34 +41,34 @@ private: ProjectorType type = ProjectorType::Source; std::vector multiviewScenes; std::vector multiviewLabels; - gs_vertbuffer_t *actionSafeMargin = nullptr; - gs_vertbuffer_t *graphicsSafeMargin = nullptr; + gs_vertbuffer_t *actionSafeMargin = nullptr; + gs_vertbuffer_t *graphicsSafeMargin = nullptr; gs_vertbuffer_t *fourByThreeSafeMargin = nullptr; - gs_vertbuffer_t *leftLine = nullptr; - gs_vertbuffer_t *topLine = nullptr; - gs_vertbuffer_t *rightLine = nullptr; + gs_vertbuffer_t *leftLine = nullptr; + gs_vertbuffer_t *topLine = nullptr; + gs_vertbuffer_t *rightLine = nullptr; gs_effect_t *solid = nullptr; gs_eparam_t *color = nullptr; // Multiview position helpers float thickness = 4; - float offset, thicknessx2 = thickness * 2, pvwprgCX, - pvwprgCY, sourceX, sourceY, labelX, labelY, scenesCX, scenesCY, - ppiCX, ppiCY, siX, siY, siCX, siCY, ppiScaleX, ppiScaleY, - siScaleX, siScaleY, fw, fh, ratio; + float offset, thicknessx2 = thickness * 2, pvwprgCX, pvwprgCY, sourceX, + sourceY, labelX, labelY, scenesCX, scenesCY, ppiCX, ppiCY, + siX, siY, siCX, siCY, ppiScaleX, ppiScaleY, siScaleX, + siScaleY, fw, fh, ratio; - float lineLength = 0.1f; + float lineLength = 0.1f; // Rec. ITU-R BT.1848-1 / EBU R 95 - float actionSafePercentage = 0.035f; // 3.5% - float graphicsSafePercentage = 0.05f; // 5.0% + float actionSafePercentage = 0.035f; // 3.5% + float graphicsSafePercentage = 0.05f; // 5.0% float fourByThreeSafePercentage = 0.1625f; // 16.25% bool ready = false; // argb colors - static const uint32_t outerColor = 0xFFD0D0D0; - static const uint32_t labelColor = 0xD91F1F1F; + static const uint32_t outerColor = 0xFFD0D0D0; + static const uint32_t labelColor = 0xD91F1F1F; static const uint32_t backgroundColor = 0xFF000000; - static const uint32_t previewColor = 0xFF00D000; - static const uint32_t programColor = 0xFFD00000; + static const uint32_t previewColor = 0xFF00D000; + static const uint32_t programColor = 0xFFD00000; void UpdateMultiview(); void UpdateProjectorTitle(QString name); @@ -78,7 +78,7 @@ private slots: public: OBSProjector(QWidget *widget, obs_source_t *source_, int monitor, - QString title, ProjectorType type_); + QString title, ProjectorType type_); ~OBSProjector(); OBSSource GetSource(); diff --git a/UI/window-remux.cpp b/UI/window-remux.cpp index f6fa08b..674cf30 100644 --- a/UI/window-remux.cpp +++ b/UI/window-remux.cpp @@ -48,33 +48,29 @@ enum RemuxEntryColumn { Count }; -enum RemuxEntryRole { - EntryStateRole = Qt::UserRole, - NewPathsToProcessRole -}; +enum RemuxEntryRole { EntryStateRole = Qt::UserRole, NewPathsToProcessRole }; /********************************************************** Delegate - Presents cells in the grid. **********************************************************/ -RemuxEntryPathItemDelegate::RemuxEntryPathItemDelegate(bool isOutput, - const QString &defaultPath) - : QStyledItemDelegate(), - isOutput(isOutput), - defaultPath(defaultPath) +RemuxEntryPathItemDelegate::RemuxEntryPathItemDelegate( + bool isOutput, const QString &defaultPath) + : QStyledItemDelegate(), isOutput(isOutput), defaultPath(defaultPath) { } -QWidget *RemuxEntryPathItemDelegate::createEditor(QWidget *parent, - const QStyleOptionViewItem & /* option */, - const QModelIndex &index) const +QWidget *RemuxEntryPathItemDelegate::createEditor( + QWidget *parent, const QStyleOptionViewItem & /* option */, + const QModelIndex &index) const { - RemuxEntryState state = index.model() + RemuxEntryState state = + index.model() ->index(index.row(), RemuxEntryColumn::State) .data(RemuxEntryRole::EntryStateRole) .value(); if (state == RemuxEntryState::Pending || - state == RemuxEntryState::InProgress) { + state == RemuxEntryState::InProgress) { // Never allow modification of rows that are // in progress. return Q_NULLPTR; @@ -88,22 +84,20 @@ QWidget *RemuxEntryPathItemDelegate::createEditor(QWidget *parent, return Q_NULLPTR; } else { QSizePolicy buttonSizePolicy( - QSizePolicy::Policy::Minimum, - QSizePolicy::Policy::Expanding, - QSizePolicy::ControlType::PushButton); + QSizePolicy::Policy::Minimum, + QSizePolicy::Policy::Expanding, + QSizePolicy::ControlType::PushButton); QWidget *container = new QWidget(parent); - auto browseCallback = [this, container]() - { + auto browseCallback = [this, container]() { const_cast(this) - ->handleBrowse(container); + ->handleBrowse(container); }; - auto clearCallback = [this, container]() - { + auto clearCallback = [this, container]() { const_cast(this) - ->handleClear(container); + ->handleClear(container); }; QHBoxLayout *layout = new QHBoxLayout(); @@ -112,10 +106,10 @@ QWidget *RemuxEntryPathItemDelegate::createEditor(QWidget *parent, QLineEdit *text = new QLineEdit(); text->setObjectName(QStringLiteral("text")); - text->setSizePolicy(QSizePolicy( - QSizePolicy::Policy::Expanding, - QSizePolicy::Policy::Expanding, - QSizePolicy::ControlType::LineEdit)); + text->setSizePolicy( + QSizePolicy(QSizePolicy::Policy::Expanding, + QSizePolicy::Policy::Expanding, + QSizePolicy::ControlType::LineEdit)); layout->addWidget(text); QToolButton *browseButton = new QToolButton(); @@ -124,7 +118,7 @@ QWidget *RemuxEntryPathItemDelegate::createEditor(QWidget *parent, layout->addWidget(browseButton); container->connect(browseButton, &QToolButton::clicked, - browseCallback); + browseCallback); // The "clear" button is not shown in output cells // or the insertion point's input cell. @@ -134,9 +128,8 @@ QWidget *RemuxEntryPathItemDelegate::createEditor(QWidget *parent, clearButton->setSizePolicy(buttonSizePolicy); layout->addWidget(clearButton); - container->connect(clearButton, - &QToolButton::clicked, - clearCallback); + container->connect(clearButton, &QToolButton::clicked, + clearCallback); } container->setLayout(layout); @@ -146,17 +139,18 @@ QWidget *RemuxEntryPathItemDelegate::createEditor(QWidget *parent, } void RemuxEntryPathItemDelegate::setEditorData(QWidget *editor, - const QModelIndex &index) const + const QModelIndex &index) const { QLineEdit *text = editor->findChild(); text->setText(index.data().toString()); - QObject::connect(text, SIGNAL(textEdited(QString)), this, SLOT(updateText())); + QObject::connect(text, SIGNAL(textEdited(QString)), this, + SLOT(updateText())); editor->setProperty(PATH_LIST_PROP, QVariant()); } void RemuxEntryPathItemDelegate::setModelData(QWidget *editor, - QAbstractItemModel *model, - const QModelIndex &index) const + QAbstractItemModel *model, + const QModelIndex &index) const { // We use the PATH_LIST_PROP property to pass a list of // path strings from the editor widget into the model's @@ -167,14 +161,14 @@ void RemuxEntryPathItemDelegate::setModelData(QWidget *editor, // as normal text data in the default role. QVariant pathListProp = editor->property(PATH_LIST_PROP); if (pathListProp.isValid()) { - QStringList list = editor->property(PATH_LIST_PROP) - .toStringList(); + QStringList list = + editor->property(PATH_LIST_PROP).toStringList(); if (isOutput) { if (list.size() > 0) model->setData(index, list); } else model->setData(index, list, - RemuxEntryRole::NewPathsToProcessRole); + RemuxEntryRole::NewPathsToProcessRole); } else { QLineEdit *lineEdit = editor->findChild(); model->setData(index, lineEdit->text()); @@ -182,10 +176,11 @@ void RemuxEntryPathItemDelegate::setModelData(QWidget *editor, } void RemuxEntryPathItemDelegate::paint(QPainter *painter, - const QStyleOptionViewItem &option, - const QModelIndex &index) const + const QStyleOptionViewItem &option, + const QModelIndex &index) const { - RemuxEntryState state = index.model() + RemuxEntryState state = + index.model() ->index(index.row(), RemuxEntryColumn::State) .data(RemuxEntryRole::EntryStateRole) .value(); @@ -195,24 +190,22 @@ void RemuxEntryPathItemDelegate::paint(QPainter *painter, if (isOutput) { if (state != Ready) { - QColor background = localOption.palette - .color(QPalette::ColorGroup::Disabled, - QPalette::ColorRole::Background); + QColor background = localOption.palette.color( + QPalette::ColorGroup::Disabled, + QPalette::ColorRole::Background); localOption.backgroundBrush = QBrush(background); } } QApplication::style()->drawControl(QStyle::CE_ItemViewItem, - &localOption, painter); + &localOption, painter); } void RemuxEntryPathItemDelegate::handleBrowse(QWidget *container) { - QString OutputPattern = - "(*.mp4 *.flv *.mov *.mkv *.ts *.m3u8)"; - QString InputPattern = - "(*.flv *.mov *.mkv *.ts *.m3u8)"; + QString OutputPattern = "(*.mp4 *.flv *.mov *.mkv *.ts *.m3u8)"; + QString InputPattern = "(*.flv *.mov *.mkv *.ts *.m3u8)"; QLineEdit *text = container->findChild(); @@ -223,21 +216,19 @@ void RemuxEntryPathItemDelegate::handleBrowse(QWidget *container) bool isSet = false; if (isOutput) { QString newPath = QFileDialog::getSaveFileName( - container, QTStr("Remux.SelectTarget"), - currentPath, OutputPattern); + container, QTStr("Remux.SelectTarget"), currentPath, + OutputPattern); if (!newPath.isEmpty()) { container->setProperty(PATH_LIST_PROP, - QStringList() << newPath); + QStringList() << newPath); isSet = true; } } else { QStringList paths = QFileDialog::getOpenFileNames( - container, - QTStr("Remux.SelectRecording"), - currentPath, - QTStr("Remux.OBSRecording") - + QString(" ") + InputPattern); + container, QTStr("Remux.SelectRecording"), currentPath, + QTStr("Remux.OBSRecording") + QString(" ") + + InputPattern); if (!paths.empty()) { container->setProperty(PATH_LIST_PROP, paths); @@ -258,8 +249,9 @@ void RemuxEntryPathItemDelegate::handleClear(QWidget *container) emit commitData(container); } -void RemuxEntryPathItemDelegate::updateText() { - QLineEdit *lineEdit = dynamic_cast(sender()); +void RemuxEntryPathItemDelegate::updateText() +{ + QLineEdit *lineEdit = dynamic_cast(sender()); QWidget *editor = lineEdit->parentWidget(); emit commitData(editor); } @@ -294,7 +286,7 @@ QVariant RemuxQueueModel::data(const QModelIndex &index, int role) const break; } } else if (role == Qt::DecorationRole && - index.column() == RemuxEntryColumn::State) { + index.column() == RemuxEntryColumn::State) { result = getIcon(queue[index.row()].state); } else if (role == RemuxEntryRole::EntryStateRole) { result = queue[index.row()].state; @@ -304,12 +296,12 @@ QVariant RemuxQueueModel::data(const QModelIndex &index, int role) const } QVariant RemuxQueueModel::headerData(int section, Qt::Orientation orientation, - int role) const + int role) const { QVariant result = QVariant(); if (role == Qt::DisplayRole && - orientation == Qt::Orientation::Horizontal) { + orientation == Qt::Orientation::Horizontal) { switch (section) { case RemuxEntryColumn::State: result = QString(); @@ -333,7 +325,7 @@ Qt::ItemFlags RemuxQueueModel::flags(const QModelIndex &index) const if (index.column() == RemuxEntryColumn::InputPath) { flags |= Qt::ItemIsEditable; } else if (index.column() == RemuxEntryColumn::OutputPath && - index.row() != queue.length()) { + index.row() != queue.length()) { flags |= Qt::ItemIsEditable; } @@ -341,7 +333,7 @@ Qt::ItemFlags RemuxQueueModel::flags(const QModelIndex &index) const } bool RemuxQueueModel::setData(const QModelIndex &index, const QVariant &value, - int role) + int role) { bool success = false; @@ -356,7 +348,8 @@ bool RemuxQueueModel::setData(const QModelIndex &index, const QVariant &value, endRemoveRows(); } } else { - if (pathList.size() > 1 && index.row() < queue.length()) { + if (pathList.size() > 1 && + index.row() < queue.length()) { queue[index.row()].sourcePath = pathList[0]; checkInputPath(index.row()); @@ -394,7 +387,7 @@ bool RemuxQueueModel::setData(const QModelIndex &index, const QVariant &value, entry.sourcePath = path; beginInsertRows(QModelIndex(), queue.length() + 1, - queue.length() + 1); + queue.length() + 1); queue.append(entry); endInsertRows(); @@ -414,12 +407,14 @@ bool RemuxQueueModel::setData(const QModelIndex &index, const QVariant &value, } else { switch (index.column()) { case RemuxEntryColumn::InputPath: - queue[index.row()].sourcePath = value.toString(); + queue[index.row()].sourcePath = + value.toString(); checkInputPath(index.row()); success = true; break; case RemuxEntryColumn::OutputPath: - queue[index.row()].targetPath = value.toString(); + queue[index.row()].targetPath = + value.toString(); emit dataChanged(index, index); success = true; break; @@ -437,23 +432,19 @@ QVariant RemuxQueueModel::getIcon(RemuxEntryState state) switch (state) { case RemuxEntryState::Complete: - icon = style->standardIcon( - QStyle::SP_DialogApplyButton); + icon = style->standardIcon(QStyle::SP_DialogApplyButton); break; case RemuxEntryState::InProgress: - icon = style->standardIcon( - QStyle::SP_ArrowRight); + icon = style->standardIcon(QStyle::SP_ArrowRight); break; case RemuxEntryState::Error: - icon = style->standardIcon( - QStyle::SP_DialogCancelButton); + icon = style->standardIcon(QStyle::SP_DialogCancelButton); break; case RemuxEntryState::InvalidPath: - icon = style->standardIcon( - QStyle::SP_MessageBoxWarning); + icon = style->standardIcon(QStyle::SP_MessageBoxWarning); break; default: @@ -477,8 +468,8 @@ void RemuxQueueModel::checkInputPath(int row) entry.state = RemuxEntryState::InvalidPath; if (entry.state == RemuxEntryState::Ready) - entry.targetPath = fileInfo.path() + QDir::separator() - + fileInfo.completeBaseName() + ".mp4"; + entry.targetPath = fileInfo.path() + QDir::separator() + + fileInfo.completeBaseName() + ".mp4"; } if (entry.state == RemuxEntryState::Ready && isProcessing) @@ -564,7 +555,7 @@ void RemuxQueueModel::beginProcessing() isProcessing = true; emit dataChanged(index(0, RemuxEntryColumn::State), - index(queue.length(), RemuxEntryColumn::State)); + index(queue.length(), RemuxEntryColumn::State)); } void RemuxQueueModel::endProcessing() @@ -585,7 +576,7 @@ void RemuxQueueModel::endProcessing() isProcessing = false; emit dataChanged(index(0, RemuxEntryColumn::State), - index(queue.length(), RemuxEntryColumn::State)); + index(queue.length(), RemuxEntryColumn::State)); } bool RemuxQueueModel::beginNextEntry(QString &inputPath, QString &outputPath) @@ -600,8 +591,8 @@ bool RemuxQueueModel::beginNextEntry(QString &inputPath, QString &outputPath) inputPath = entry.sourcePath; outputPath = entry.targetPath; - QModelIndex index = this->index(row, - RemuxEntryColumn::State); + QModelIndex index = + this->index(row, RemuxEntryColumn::State); emit dataChanged(index, index); anyStarted = true; @@ -622,8 +613,8 @@ void RemuxQueueModel::finishEntry(bool success) else entry.state = RemuxEntryState::Error; - QModelIndex index = this->index(row, - RemuxEntryColumn::State); + QModelIndex index = + this->index(row, RemuxEntryColumn::State); emit dataChanged(index, index); break; @@ -636,12 +627,12 @@ void RemuxQueueModel::finishEntry(bool success) **********************************************************/ OBSRemux::OBSRemux(const char *path, QWidget *parent, bool autoRemux_) - : QDialog (parent), + : QDialog(parent), queueModel(new RemuxQueueModel), - worker (new RemuxWorker()), - ui (new Ui::OBSRemux), - recPath (path), - autoRemux (autoRemux_) + worker(new RemuxWorker()), + ui(new Ui::OBSRemux), + recPath(path), + autoRemux(autoRemux_) { setAcceptDrops(true); @@ -650,10 +641,9 @@ OBSRemux::OBSRemux(const char *path, QWidget *parent, bool autoRemux_) ui->setupUi(this); ui->progressBar->setVisible(false); - ui->buttonBox->button(QDialogButtonBox::Ok)-> - setEnabled(false); - ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)-> - setEnabled(false); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + ui->buttonBox->button(QDialogButtonBox::RestoreDefaults) + ->setEnabled(false); if (autoRemux) { resize(280, 40); @@ -667,66 +657,63 @@ OBSRemux::OBSRemux(const char *path, QWidget *parent, bool autoRemux_) ui->progressBar->setValue(0); ui->tableView->setModel(queueModel); - ui->tableView->setItemDelegateForColumn(RemuxEntryColumn::InputPath, - new RemuxEntryPathItemDelegate(false, recPath)); - ui->tableView->setItemDelegateForColumn(RemuxEntryColumn::OutputPath, - new RemuxEntryPathItemDelegate(true, recPath)); + ui->tableView->setItemDelegateForColumn( + RemuxEntryColumn::InputPath, + new RemuxEntryPathItemDelegate(false, recPath)); + ui->tableView->setItemDelegateForColumn( + RemuxEntryColumn::OutputPath, + new RemuxEntryPathItemDelegate(true, recPath)); ui->tableView->horizontalHeader()->setSectionResizeMode( - QHeaderView::ResizeMode::Stretch); + QHeaderView::ResizeMode::Stretch); ui->tableView->horizontalHeader()->setSectionResizeMode( - RemuxEntryColumn::State, - QHeaderView::ResizeMode::Fixed); + RemuxEntryColumn::State, QHeaderView::ResizeMode::Fixed); ui->tableView->setEditTriggers( - QAbstractItemView::EditTrigger::CurrentChanged); + QAbstractItemView::EditTrigger::CurrentChanged); installEventFilter(CreateShortcutFilter()); - ui->buttonBox->button(QDialogButtonBox::Ok)-> - setText(QTStr("Remux.Remux")); - ui->buttonBox->button(QDialogButtonBox::Reset)-> - setText(QTStr("Remux.ClearFinished")); - ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)-> - setText(QTStr("Remux.ClearAll")); - ui->buttonBox->button(QDialogButtonBox::Reset)-> - setDisabled(true); + ui->buttonBox->button(QDialogButtonBox::Ok) + ->setText(QTStr("Remux.Remux")); + ui->buttonBox->button(QDialogButtonBox::Reset) + ->setText(QTStr("Remux.ClearFinished")); + ui->buttonBox->button(QDialogButtonBox::RestoreDefaults) + ->setText(QTStr("Remux.ClearAll")); + ui->buttonBox->button(QDialogButtonBox::Reset)->setDisabled(true); - connect(ui->buttonBox->button(QDialogButtonBox::Ok), - SIGNAL(clicked()), this, SLOT(beginRemux())); + connect(ui->buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), + this, SLOT(beginRemux())); connect(ui->buttonBox->button(QDialogButtonBox::Reset), - SIGNAL(clicked()), this, SLOT(clearFinished())); + SIGNAL(clicked()), this, SLOT(clearFinished())); connect(ui->buttonBox->button(QDialogButtonBox::RestoreDefaults), - SIGNAL(clicked()), this, SLOT(clearAll())); + SIGNAL(clicked()), this, SLOT(clearAll())); connect(ui->buttonBox->button(QDialogButtonBox::Close), - SIGNAL(clicked()), this, SLOT(close())); + SIGNAL(clicked()), this, SLOT(close())); worker->moveToThread(&remuxer); remuxer.start(); //gcc-4.8 can't use QPointer below RemuxWorker *worker_ = worker; - connect(worker_, &RemuxWorker::updateProgress, - this, &OBSRemux::updateProgress); + connect(worker_, &RemuxWorker::updateProgress, this, + &OBSRemux::updateProgress); connect(&remuxer, &QThread::finished, worker_, &QObject::deleteLater); - connect(worker_, &RemuxWorker::remuxFinished, - this, &OBSRemux::remuxFinished); + connect(worker_, &RemuxWorker::remuxFinished, this, + &OBSRemux::remuxFinished); connect(this, &OBSRemux::remux, worker_, &RemuxWorker::remux); // Guessing the GCC bug mentioned above would also affect // QPointer? Unsure. RemuxQueueModel *queueModel_ = queueModel; connect(queueModel_, - SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, - SLOT(rowCountChanged(const QModelIndex &, int, int))); - connect(queueModel_, - SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, - SLOT(rowCountChanged(const QModelIndex &, int, int))); + SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, + SLOT(rowCountChanged(const QModelIndex &, int, int))); + connect(queueModel_, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, SLOT(rowCountChanged(const QModelIndex &, int, int))); QModelIndex index = queueModel->createIndex(0, 1); - QMetaObject::invokeMethod(ui->tableView, - "setCurrentIndex", Qt::QueuedConnection, - Q_ARG(const QModelIndex &, index)); + QMetaObject::invokeMethod(ui->tableView, "setCurrentIndex", + Qt::QueuedConnection, + Q_ARG(const QModelIndex &, index)); } bool OBSRemux::stopRemux() @@ -741,12 +728,10 @@ bool OBSRemux::stopRemux() bool exit = false; - if (QMessageBox::critical(nullptr, - QTStr("Remux.ExitUnfinishedTitle"), - QTStr("Remux.ExitUnfinished"), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::No) == - QMessageBox::Yes) { + if (QMessageBox::critical(nullptr, QTStr("Remux.ExitUnfinishedTitle"), + QTStr("Remux.ExitUnfinished"), + QMessageBox::Yes | QMessageBox::No, + QMessageBox::No) == QMessageBox::Yes) { exit = true; } @@ -774,19 +759,17 @@ void OBSRemux::rowCountChanged(const QModelIndex &, int, int) // There must be more than one row, since there will always be // at least one row for the empty insertion point. if (queueModel->rowCount() > 1) { - ui->buttonBox->button(QDialogButtonBox::Ok)-> - setEnabled(true); - ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)-> - setEnabled(true); - ui->buttonBox->button(QDialogButtonBox::Reset)-> - setEnabled(queueModel->canClearFinished()); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); + ui->buttonBox->button(QDialogButtonBox::RestoreDefaults) + ->setEnabled(true); + ui->buttonBox->button(QDialogButtonBox::Reset) + ->setEnabled(queueModel->canClearFinished()); } else { - ui->buttonBox->button(QDialogButtonBox::Ok)-> - setEnabled(false); - ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)-> - setEnabled(false); - ui->buttonBox->button(QDialogButtonBox::Reset)-> - setEnabled(false); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + ui->buttonBox->button(QDialogButtonBox::RestoreDefaults) + ->setEnabled(false); + ui->buttonBox->button(QDialogButtonBox::Reset) + ->setEnabled(false); } } @@ -799,17 +782,16 @@ void OBSRemux::dropEvent(QDropEvent *ev) if (fileInfo.isDir()) { QStringList directoryFilter; - directoryFilter << - "*.flv" << - "*.mp4" << - "*.mov" << - "*.mkv" << - "*.ts" << - "*.m3u8"; + directoryFilter << "*.flv" + << "*.mp4" + << "*.mov" + << "*.mkv" + << "*.ts" + << "*.m3u8"; QDirIterator dirIter(fileInfo.absoluteFilePath(), - directoryFilter, QDir::Files, - QDirIterator::Subdirectories); + directoryFilter, QDir::Files, + QDirIterator::Subdirectories); while (dirIter.hasNext()) { urlList.append(dirIter.next()); @@ -821,14 +803,15 @@ void OBSRemux::dropEvent(QDropEvent *ev) if (urlList.empty()) { QMessageBox::information(nullptr, - QTStr("Remux.NoFilesAddedTitle"), - QTStr("Remux.NoFilesAdded"), QMessageBox::Ok); + QTStr("Remux.NoFilesAddedTitle"), + QTStr("Remux.NoFilesAdded"), + QMessageBox::Ok); } else if (!autoRemux) { - QModelIndex insertIndex = queueModel->index( - queueModel->rowCount() - 1, - RemuxEntryColumn::InputPath); + QModelIndex insertIndex = + queueModel->index(queueModel->rowCount() - 1, + RemuxEntryColumn::InputPath); queueModel->setData(insertIndex, urlList, - RemuxEntryRole::NewPathsToProcessRole); + RemuxEntryRole::NewPathsToProcessRole); } } @@ -856,8 +839,8 @@ void OBSRemux::beginRemux() message += fileInfo.canonicalFilePath() + "\n"; if (OBSMessageBox::question(this, - QTStr("Remux.FileExistsTitle"), message) - != QMessageBox::Yes) + QTStr("Remux.FileExistsTitle"), + message) != QMessageBox::Yes) proceedWithRemux = false; } @@ -868,8 +851,8 @@ void OBSRemux::beginRemux() queueModel->beginProcessing(); ui->progressBar->setVisible(true); - ui->buttonBox->button(QDialogButtonBox::Ok)-> - setText(QTStr("Remux.Stop")); + ui->buttonBox->button(QDialogButtonBox::Ok) + ->setText(QTStr("Remux.Stop")); setAcceptDrops(false); remuxNextEntry(); @@ -895,20 +878,20 @@ void OBSRemux::remuxNextEntry() queueModel->endProcessing(); if (!autoRemux) { - OBSMessageBox::information(this, - QTStr("Remux.FinishedTitle"), - queueModel->checkForErrors() + OBSMessageBox::information( + this, QTStr("Remux.FinishedTitle"), + queueModel->checkForErrors() ? QTStr("Remux.FinishedError") : QTStr("Remux.Finished")); } ui->progressBar->setVisible(autoRemux); - ui->buttonBox->button(QDialogButtonBox::Ok)-> - setText(QTStr("Remux.Remux")); - ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)-> - setEnabled(true); - ui->buttonBox->button(QDialogButtonBox::Reset)-> - setEnabled(queueModel->canClearFinished()); + ui->buttonBox->button(QDialogButtonBox::Ok) + ->setText(QTStr("Remux.Remux")); + ui->buttonBox->button(QDialogButtonBox::RestoreDefaults) + ->setEnabled(true); + ui->buttonBox->button(QDialogButtonBox::Reset) + ->setEnabled(queueModel->canClearFinished()); setAcceptDrops(true); } } @@ -936,8 +919,7 @@ void OBSRemux::updateProgress(float percent) void OBSRemux::remuxFinished(bool success) { - ui->buttonBox->button(QDialogButtonBox::Ok)-> - setEnabled(true); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); queueModel->finishEntry(success); @@ -976,9 +958,8 @@ void RemuxWorker::remux(const QString &source, const QString &target) { isWorking = true; - auto callback = [](void *data, float percent) - { - RemuxWorker *rw = static_cast(data); + auto callback = [](void *data, float percent) { + RemuxWorker *rw = static_cast(data); QMutexLocker lock(&rw->updateMutex); @@ -991,12 +972,10 @@ void RemuxWorker::remux(const QString &source, const QString &target) bool success = false; media_remux_job_t mr_job = nullptr; - if (media_remux_job_create(&mr_job, - QT_TO_UTF8(source), - QT_TO_UTF8(target))) { + if (media_remux_job_create(&mr_job, QT_TO_UTF8(source), + QT_TO_UTF8(target))) { - success = media_remux_job_process(mr_job, callback, - this); + success = media_remux_job_process(mr_job, callback, this); media_remux_job_destroy(mr_job); diff --git a/UI/window-remux.hpp b/UI/window-remux.hpp index c98d45a..2f469b3 100644 --- a/UI/window-remux.hpp +++ b/UI/window-remux.hpp @@ -31,8 +31,7 @@ class RemuxQueueModel; class RemuxWorker; -enum RemuxEntryState -{ +enum RemuxEntryState { Empty, Ready, Pending, @@ -62,7 +61,7 @@ class OBSRemux : public QDialog { public: explicit OBSRemux(const char *recPath, QWidget *parent = nullptr, - bool autoRemux = false); + bool autoRemux = false); virtual ~OBSRemux() override; using job_t = std::shared_ptr; @@ -70,8 +69,8 @@ public: void AutoRemux(QString inFile, QString outFile); protected: - void dropEvent(QDropEvent *ev); - void dragEnterEvent(QDragEnterEvent *ev); + virtual void dropEvent(QDropEvent *ev) override; + virtual void dragEnterEvent(QDragEnterEvent *ev) override; void remuxNextEntry(); @@ -97,17 +96,17 @@ class RemuxQueueModel : public QAbstractTableModel { public: RemuxQueueModel(QObject *parent = 0) - : QAbstractTableModel(parent) - , isProcessing(false) {} + : QAbstractTableModel(parent), isProcessing(false) + { + } int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; + int role = Qt::DisplayRole) const; Qt::ItemFlags flags(const QModelIndex &index) const; - bool setData(const QModelIndex &index, const QVariant &value, - int role); + bool setData(const QModelIndex &index, const QVariant &value, int role); QFileInfoList checkForOverwrites() const; bool checkForErrors() const; @@ -122,8 +121,7 @@ public: bool autoRemux = false; private: - struct RemuxQueueEntry - { + struct RemuxQueueEntry { RemuxEntryState state; QString sourcePath; @@ -148,9 +146,8 @@ class RemuxWorker : public QObject { float lastProgress; void UpdateProgress(float percent); - explicit RemuxWorker() - : isWorking(false) { } - virtual ~RemuxWorker() {}; + explicit RemuxWorker() : isWorking(false) {} + virtual ~RemuxWorker(){}; private slots: void remux(const QString &source, const QString &target); @@ -169,17 +166,16 @@ public: RemuxEntryPathItemDelegate(bool isOutput, const QString &defaultPath); virtual QWidget *createEditor(QWidget *parent, - const QStyleOptionViewItem & /* option */, - const QModelIndex &index) const override; + const QStyleOptionViewItem & /* option */, + const QModelIndex &index) const override; - virtual void setEditorData(QWidget *editor, const QModelIndex &index) - const override; - virtual void setModelData(QWidget *editor, - QAbstractItemModel *model, - const QModelIndex &index) const override; + virtual void setEditorData(QWidget *editor, + const QModelIndex &index) const override; + virtual void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const override; virtual void paint(QPainter *painter, - const QStyleOptionViewItem &option, - const QModelIndex &index) const override; + const QStyleOptionViewItem &option, + const QModelIndex &index) const override; private: bool isOutput; diff --git a/appveyor.yml b/appveyor.yml index aa698b2..e650672 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,7 +4,7 @@ image: environment: CURL_VERSION: 7.56.1 - CEF_VERSION: 3.3440.1805.gbe070f9 + CEF_VERSION: 75.1.16+g16a67c4+chromium-75.0.3770.100 APPVEYOR_YML_DISABLE_PS_LINUX: true TWITCH-CLIENTID: secure: D3vFGk41HZaJWAZu5slwAHZhB868mGI2aIMS03L2rt4= @@ -43,8 +43,8 @@ test: off cache: - dependencies2017.zip - vlc.zip - - 'cef_binary_%CEF_VERSION%_windows32.zip' - - 'cef_binary_%CEF_VERSION%_windows64.zip' + - 'cef_binary_%CEF_VERSION%_windows32_minimal.zip' + - 'cef_binary_%CEF_VERSION%_windows64_minimal.zip' - Qt_5.10.1.7z notifications: diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 45fcdaf..e4c3e3e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -2,8 +2,8 @@ variables: CMAKE_PREFIX_PATH: /usr/local/opt/qt5/lib/cmake - CEF_BUILD_VERSION: 3.3282.1726.gc8368c8 - CEF_VERSION: 3.3440.1805.gbe070f9 + CEF_BUILD_VERSION: 3770 + CEF_VERSION: 75.1.16+g16a67c4+chromium-75.0.3770.100 TWITCH-CLIENTID: $(twitch_clientid) TWITCH-HASH: $(twitch_hash) MIXER-CLIENTID: $(mixer_clientid) diff --git a/deps/file-updater/file-updater/file-updater.c b/deps/file-updater/file-updater/file-updater.c index b8d649e..5808400 100644 --- a/deps/file-updater/file-updater/file-updater.c +++ b/deps/file-updater/file-updater/file-updater.c @@ -7,9 +7,9 @@ #include "file-updater.h" #define warn(msg, ...) \ - blog(LOG_WARNING, "%s"msg, info->log_prefix, ##__VA_ARGS__) + blog(LOG_WARNING, "%s" msg, info->log_prefix, ##__VA_ARGS__) #define info(msg, ...) \ - blog(LOG_WARNING, "%s"msg, info->log_prefix, ##__VA_ARGS__) + blog(LOG_WARNING, "%s" msg, info->log_prefix, ##__VA_ARGS__) struct update_info { char error[CURL_ERROR_SIZE]; @@ -70,7 +70,7 @@ void update_info_destroy(struct update_info *info) } static size_t http_write(uint8_t *ptr, size_t size, size_t nmemb, - struct update_info *info) + struct update_info *info) { size_t total = size * nmemb; if (total) @@ -80,10 +80,9 @@ static size_t http_write(uint8_t *ptr, size_t size, size_t nmemb, } static size_t http_header(char *buffer, size_t size, size_t nitems, - struct update_info *info) + struct update_info *info) { - if (!strncmp(buffer, "ETag: ", 6)) - { + if (!strncmp(buffer, "ETag: ", 6)) { char *etag = buffer + 6; if (*etag) { char *etag_clean, *p; @@ -105,7 +104,7 @@ static size_t http_header(char *buffer, size_t size, size_t nitems, } static bool do_http_request(struct update_info *info, const char *url, - long *response_code) + long *response_code) { CURLcode code; uint8_t null_terminator = 0; @@ -118,10 +117,12 @@ static bool do_http_request(struct update_info *info, const char *url, curl_easy_setopt(info->curl, CURLOPT_WRITEDATA, info); curl_easy_setopt(info->curl, CURLOPT_FAILONERROR, true); curl_easy_setopt(info->curl, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(info->curl, CURLOPT_ACCEPT_ENCODING, ""); if (!info->remote_url) { // We only care about headers from the main package file - curl_easy_setopt(info->curl, CURLOPT_HEADERFUNCTION, http_header); + curl_easy_setopt(info->curl, CURLOPT_HEADERFUNCTION, + http_header); curl_easy_setopt(info->curl, CURLOPT_HEADERDATA, info); } @@ -133,17 +134,17 @@ static bool do_http_request(struct update_info *info, const char *url, code = curl_easy_perform(info->curl); if (code != CURLE_OK) { warn("Remote update of URL \"%s\" failed: %s", url, - info->error); + info->error); return false; } if (curl_easy_getinfo(info->curl, CURLINFO_RESPONSE_CODE, - response_code) != CURLE_OK) + response_code) != CURLE_OK) return false; if (*response_code >= 400) { warn("Remote update of URL \"%s\" failed: HTTP/%ld", url, - *response_code); + *response_code); return false; } @@ -190,14 +191,14 @@ static bool init_update(struct update_info *info) if (metadata) { const char *etag = obs_data_get_string(metadata, "etag"); if (etag) { - struct dstr if_none_match = { 0 }; + struct dstr if_none_match = {0}; dstr_copy(&if_none_match, "If-None-Match: "); dstr_cat(&if_none_match, etag); info->etag_local = bstrdup(etag); info->header = curl_slist_append(info->header, - if_none_match.array); + if_none_match.array); dstr_free(&if_none_match); } @@ -218,7 +219,7 @@ static void copy_local_to_cache(struct update_info *info, const char *file) { char *local_file_path = get_path(info->local, file); char *cache_file_path = get_path(info->cache, file); - char *temp_file_path = get_path(info->temp, file); + char *temp_file_path = get_path(info->temp, file); os_copyfile(local_file_path, temp_file_path); os_unlink(cache_file_path); @@ -230,8 +231,8 @@ static void copy_local_to_cache(struct update_info *info, const char *file) } static void enum_files(obs_data_t *package, - bool (*enum_func)(void *param, obs_data_t *file), - void *param) + bool (*enum_func)(void *param, obs_data_t *file), + void *param) { obs_data_array_t *array = obs_data_get_array(package, "files"); size_t num; @@ -280,8 +281,7 @@ static bool update_files_to_local(void *param, obs_data_t *local_file) struct update_info *info = param; struct file_update_data data = { .name = obs_data_get_string(local_file, "name"), - .version = (int)obs_data_get_int(local_file, "version") - }; + .version = (int)obs_data_get_int(local_file, "version")}; enum_files(info->cache_package, newer_than_cache, &data); if (data.newer || !data.found) @@ -314,7 +314,7 @@ static int update_local_version(struct update_info *info) } static inline bool do_relative_http_request(struct update_info *info, - const char *url, const char *file) + const char *url, const char *file) { long response_code; char *full_url = get_path(url, file); @@ -324,17 +324,16 @@ static inline bool do_relative_http_request(struct update_info *info, } static inline void write_file_data(struct update_info *info, - const char *base_path, const char *file) + const char *base_path, const char *file) { char *full_path = get_path(base_path, file); - os_quick_write_utf8_file(full_path, - (char*)info->file_data.array, - info->file_data.num - 1, false); + os_quick_write_utf8_file(full_path, (char *)info->file_data.array, + info->file_data.num - 1, false); bfree(full_path); } static inline void replace_file(const char *src_base_path, - const char *dst_base_path, const char *file) + const char *dst_base_path, const char *file) { char *src_path = get_path(src_base_path, file); char *dst_path = get_path(dst_base_path, file); @@ -354,8 +353,7 @@ static bool update_remote_files(void *param, obs_data_t *remote_file) struct file_update_data data = { .name = obs_data_get_string(remote_file, "name"), - .version = (int)obs_data_get_int(remote_file, "version") - }; + .version = (int)obs_data_get_int(remote_file, "version")}; enum_files(info->cache_package, newer_than_cache, &data); if (!data.newer && data.found) @@ -378,7 +376,7 @@ static bool update_remote_files(void *param, obs_data_t *remote_file) if (!confirm) { info("Update file '%s' (version %d) rejected", - data.name, data.version); + data.name, data.version); return true; } } @@ -386,14 +384,14 @@ static bool update_remote_files(void *param, obs_data_t *remote_file) write_file_data(info, info->temp, data.name); replace_file(info->temp, info->cache, data.name); - info("Successfully updated file '%s' (version %d)", - data.name, data.version); + info("Successfully updated file '%s' (version %d)", data.name, + data.version); return true; } static void update_save_metadata(struct update_info *info) { - struct dstr path = { 0 }; + struct dstr path = {0}; if (!info->etag_remote) return; @@ -428,8 +426,8 @@ static void update_remote_version(struct update_info *info, int cur_version) update_save_metadata(info); - info->remote_package = obs_data_create_from_json( - (char*)info->file_data.array); + info->remote_package = + obs_data_create_from_json((char *)info->file_data.array); if (!info->remote_package) { warn("Failed to initialize remote package json"); return; @@ -476,14 +474,12 @@ static void *update_thread(void *data) return NULL; } -update_info_t *update_info_create( - const char *log_prefix, - const char *user_agent, - const char *update_url, - const char *local_dir, - const char *cache_dir, - confirm_file_callback_t confirm_callback, - void *param) +update_info_t *update_info_create(const char *log_prefix, + const char *user_agent, + const char *update_url, const char *local_dir, + const char *cache_dir, + confirm_file_callback_t confirm_callback, + void *param) { struct update_info *info; struct dstr dir = {0}; @@ -493,7 +489,7 @@ update_info_t *update_info_create( if (os_mkdir(cache_dir) < 0) { blog(LOG_WARNING, "%sCould not create cache directory %s", - log_prefix, cache_dir); + log_prefix, cache_dir); return NULL; } @@ -504,7 +500,7 @@ update_info_t *update_info_create( if (os_mkdir(dir.array) < 0) { blog(LOG_WARNING, "%sCould not create temp directory %s", - log_prefix, cache_dir); + log_prefix, cache_dir); dstr_free(&dir); return NULL; } @@ -550,12 +546,10 @@ static void *single_file_thread(void *data) return NULL; } -update_info_t *update_info_create_single( - const char *log_prefix, - const char *user_agent, - const char *file_url, - confirm_file_callback_t confirm_callback, - void *param) +update_info_t * +update_info_create_single(const char *log_prefix, const char *user_agent, + const char *file_url, + confirm_file_callback_t confirm_callback, void *param) { struct update_info *info; diff --git a/deps/file-updater/file-updater/file-updater.h b/deps/file-updater/file-updater/file-updater.h index be07618..e50b126 100644 --- a/deps/file-updater/file-updater/file-updater.h +++ b/deps/file-updater/file-updater/file-updater.h @@ -13,20 +13,15 @@ struct file_download_data { }; typedef bool (*confirm_file_callback_t)(void *param, - struct file_download_data *file); + struct file_download_data *file); -update_info_t *update_info_create( - const char *log_prefix, - const char *user_agent, - const char *update_url, - const char *local_dir, - const char *cache_dir, - confirm_file_callback_t confirm_callback, - void *param); +update_info_t *update_info_create(const char *log_prefix, + const char *user_agent, + const char *update_url, const char *local_dir, + const char *cache_dir, + confirm_file_callback_t confirm_callback, + void *param); update_info_t *update_info_create_single( - const char *log_prefix, - const char *user_agent, - const char *file_url, - confirm_file_callback_t confirm_callback, - void *param); + const char *log_prefix, const char *user_agent, const char *file_url, + confirm_file_callback_t confirm_callback, void *param); void update_info_destroy(update_info_t *info); diff --git a/deps/glad/.clang-format b/deps/glad/.clang-format new file mode 100644 index 0000000..6420a46 --- /dev/null +++ b/deps/glad/.clang-format @@ -0,0 +1,3 @@ +Language: Cpp +SortIncludes: false +DisableFormat: true diff --git a/deps/ipc-util/ipc-util/pipe-windows.c b/deps/ipc-util/ipc-util/pipe-windows.c index db40cc1..c2f8535 100644 --- a/deps/ipc-util/ipc-util/pipe-windows.c +++ b/deps/ipc-util/ipc-util/pipe-windows.c @@ -47,15 +47,14 @@ error: } static inline bool ipc_pipe_internal_create_pipe(ipc_pipe_server_t *pipe, - const char *name) + const char *name) { SECURITY_ATTRIBUTES sa; char new_name[512]; void *sd; const DWORD access = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED; - const DWORD flags = PIPE_TYPE_MESSAGE | - PIPE_READMODE_MESSAGE | - PIPE_WAIT; + const DWORD flags = PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | + PIPE_WAIT; strcpy_s(new_name, sizeof(new_name), "\\\\.\\pipe\\"); strcat_s(new_name, sizeof(new_name), name); @@ -70,14 +69,15 @@ static inline bool ipc_pipe_internal_create_pipe(ipc_pipe_server_t *pipe, sa.bInheritHandle = false; pipe->handle = CreateNamedPipeA(new_name, access, flags, 1, - IPC_PIPE_BUF_SIZE, IPC_PIPE_BUF_SIZE, 0, &sa); + IPC_PIPE_BUF_SIZE, IPC_PIPE_BUF_SIZE, 0, + &sa); free(sd); return pipe->handle != INVALID_HANDLE_VALUE; } static inline void ipc_pipe_internal_ensure_capacity(ipc_pipe_server_t *pipe, - size_t new_size) + size_t new_size) { if (pipe->capacity >= new_size) { return; @@ -88,7 +88,7 @@ static inline void ipc_pipe_internal_ensure_capacity(ipc_pipe_server_t *pipe, } static inline void ipc_pipe_internal_append_bytes(ipc_pipe_server_t *pipe, - uint8_t *bytes, size_t size) + uint8_t *bytes, size_t size) { size_t new_size = pipe->size + size; ipc_pipe_internal_ensure_capacity(pipe, new_size); @@ -118,7 +118,7 @@ static DWORD CALLBACK ipc_pipe_internal_server_thread(LPVOID param) bool success; success = !!ReadFile(pipe->handle, buf, IPC_PIPE_BUF_SIZE, NULL, - &pipe->overlap); + &pipe->overlap); if (!success && !ipc_pipe_internal_io_pending()) { break; } @@ -129,7 +129,7 @@ static DWORD CALLBACK ipc_pipe_internal_server_thread(LPVOID param) } success = !!GetOverlappedResult(pipe->handle, &pipe->overlap, - &bytes, true); + &bytes, true); if (!success || !bytes) { break; } @@ -138,7 +138,7 @@ static DWORD CALLBACK ipc_pipe_internal_server_thread(LPVOID param) if (success) { pipe->read_callback(pipe->param, pipe->read_data, - pipe->size); + pipe->size); pipe->size = 0; } } @@ -147,16 +147,16 @@ static DWORD CALLBACK ipc_pipe_internal_server_thread(LPVOID param) return 0; } -static inline bool ipc_pipe_internal_start_server_thread( - ipc_pipe_server_t *pipe) +static inline bool +ipc_pipe_internal_start_server_thread(ipc_pipe_server_t *pipe) { pipe->thread = CreateThread(NULL, 0, ipc_pipe_internal_server_thread, - pipe, 0, NULL); + pipe, 0, NULL); return pipe->thread != NULL; } -static inline bool ipc_pipe_internal_wait_for_connection( - ipc_pipe_server_t *pipe) +static inline bool +ipc_pipe_internal_wait_for_connection(ipc_pipe_server_t *pipe) { bool success; @@ -166,7 +166,7 @@ static inline bool ipc_pipe_internal_wait_for_connection( } static inline bool ipc_pipe_internal_open_pipe(ipc_pipe_client_t *pipe, - const char *name) + const char *name) { DWORD mode = PIPE_READMODE_MESSAGE; char new_name[512]; @@ -174,8 +174,8 @@ static inline bool ipc_pipe_internal_open_pipe(ipc_pipe_client_t *pipe, strcpy_s(new_name, sizeof(new_name), "\\\\.\\pipe\\"); strcat_s(new_name, sizeof(new_name), name); - pipe->handle = CreateFileA(new_name, GENERIC_READ | GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, 0, NULL); + pipe->handle = CreateFileA(new_name, GENERIC_READ | GENERIC_WRITE, 0, + NULL, OPEN_EXISTING, 0, NULL); if (pipe->handle == INVALID_HANDLE_VALUE) { return false; } @@ -186,7 +186,7 @@ static inline bool ipc_pipe_internal_open_pipe(ipc_pipe_client_t *pipe, /* ------------------------------------------------------------------------- */ bool ipc_pipe_server_start(ipc_pipe_server_t *pipe, const char *name, - ipc_pipe_read_t read_callback, void *param) + ipc_pipe_read_t read_callback, void *param) { pipe->read_callback = read_callback; pipe->param = param; @@ -253,7 +253,7 @@ void ipc_pipe_client_free(ipc_pipe_client_t *pipe) } bool ipc_pipe_client_write(ipc_pipe_client_t *pipe, const void *data, - size_t size) + size_t size) { DWORD bytes; diff --git a/deps/ipc-util/ipc-util/pipe-windows.h b/deps/ipc-util/ipc-util/pipe-windows.h index 683c50a..39e2a17 100644 --- a/deps/ipc-util/ipc-util/pipe-windows.h +++ b/deps/ipc-util/ipc-util/pipe-windows.h @@ -19,21 +19,21 @@ #include struct ipc_pipe_server { - OVERLAPPED overlap; - HANDLE handle; - HANDLE ready_event; - HANDLE thread; + OVERLAPPED overlap; + HANDLE handle; + HANDLE ready_event; + HANDLE thread; - uint8_t *read_data; - size_t size; - size_t capacity; + uint8_t *read_data; + size_t size; + size_t capacity; - ipc_pipe_read_t read_callback; - void *param; + ipc_pipe_read_t read_callback; + void *param; }; struct ipc_pipe_client { - HANDLE handle; + HANDLE handle; }; static inline bool ipc_pipe_client_valid(ipc_pipe_client_t *pipe) diff --git a/deps/ipc-util/ipc-util/pipe.h b/deps/ipc-util/ipc-util/pipe.h index 4f67216..5182d65 100644 --- a/deps/ipc-util/ipc-util/pipe.h +++ b/deps/ipc-util/ipc-util/pipe.h @@ -35,13 +35,13 @@ typedef struct ipc_pipe_client ipc_pipe_client_t; typedef void (*ipc_pipe_read_t)(void *param, uint8_t *data, size_t size); bool ipc_pipe_server_start(ipc_pipe_server_t *pipe, const char *name, - ipc_pipe_read_t read_callback, void *param); + ipc_pipe_read_t read_callback, void *param); void ipc_pipe_server_free(ipc_pipe_server_t *pipe); bool ipc_pipe_client_open(ipc_pipe_client_t *pipe, const char *name); void ipc_pipe_client_free(ipc_pipe_client_t *pipe); bool ipc_pipe_client_write(ipc_pipe_client_t *pipe, const void *data, - size_t size); + size_t size); static inline bool ipc_pipe_client_valid(ipc_pipe_client_t *pipe); #ifdef _WIN32 diff --git a/deps/json11/.clang-format b/deps/json11/.clang-format new file mode 100644 index 0000000..6420a46 --- /dev/null +++ b/deps/json11/.clang-format @@ -0,0 +1,3 @@ +Language: Cpp +SortIncludes: false +DisableFormat: true diff --git a/deps/libff/libff/ff-audio-decoder.c b/deps/libff/libff/ff-audio-decoder.c index 07853c1..cbdb317 100644 --- a/deps/libff/libff/ff-audio-decoder.c +++ b/deps/libff/libff/ff-audio-decoder.c @@ -36,13 +36,13 @@ static inline void shrink_packet(struct ff_packet *packet, int packet_length) int remaining = packet->base.size - packet_length; memmove(packet->base.data, &packet->base.data[packet_length], - remaining); + remaining); av_shrink_packet(&packet->base, remaining); } } static bool handle_reset_packet(struct ff_decoder *decoder, - struct ff_packet *packet) + struct ff_packet *packet) { if (decoder->clock != NULL) ff_clock_release(&decoder->clock); @@ -53,27 +53,29 @@ static bool handle_reset_packet(struct ff_decoder *decoder, } static void drop_late_packets(struct ff_decoder *decoder, - struct ff_packet *packet) + struct ff_packet *packet) { int64_t start_time = ff_clock_start_time(decoder->clock); if (start_time != AV_NOPTS_VALUE) { if (ff_decoder_set_frame_drop_state(decoder, start_time, - packet->base.pts)) + packet->base.pts)) shrink_packet(packet, packet->base.size); } } -static int decode_frame(struct ff_decoder *decoder, - struct ff_packet *packet, AVFrame *frame, bool *frame_complete) +static int decode_frame(struct ff_decoder *decoder, struct ff_packet *packet, + AVFrame *frame, bool *frame_complete) { int packet_length; int ret; while (true) { if (decoder->eof) - ret = packet_queue_get(&decoder->packet_queue, packet, 0); + ret = packet_queue_get(&decoder->packet_queue, packet, + 0); else - ret = packet_queue_get(&decoder->packet_queue, packet, 1); + ret = packet_queue_get(&decoder->packet_queue, packet, + 1); if (ret == FF_PACKET_EMPTY) { return 0; @@ -82,7 +84,7 @@ static int decode_frame(struct ff_decoder *decoder, } if (packet->base.data == - decoder->packet_queue.flush_packet.base.data) { + decoder->packet_queue.flush_packet.base.data) { avcodec_flush_buffers(decoder->codec); continue; } @@ -98,8 +100,8 @@ static int decode_frame(struct ff_decoder *decoder, drop_late_packets(decoder, packet); packet_length = avcodec_decode_audio4(decoder->codec, - frame, &complete, - &packet->base); + frame, &complete, + &packet->base); if (packet_length < 0) break; @@ -112,7 +114,7 @@ static int decode_frame(struct ff_decoder *decoder, *frame_complete = complete != 0; return frame->nb_samples * - av_get_bytes_per_sample(frame->format); + av_get_bytes_per_sample(frame->format); } if (packet->base.data != NULL) @@ -121,7 +123,7 @@ static int decode_frame(struct ff_decoder *decoder, } static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame, - double best_effort_pts) + double best_effort_pts) { struct ff_frame *queue_frame; bool call_initialize; @@ -135,10 +137,11 @@ static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame, queue_frame = ff_circular_queue_peek_write(&decoder->frame_queue); AVCodecContext *codec = decoder->codec; - call_initialize = (queue_frame->frame == NULL - || queue_frame->frame->channels != codec->channels - || queue_frame->frame->sample_rate != codec->sample_rate - || queue_frame->frame->format != codec->sample_fmt); + call_initialize = + (queue_frame->frame == NULL || + queue_frame->frame->channels != codec->channels || + queue_frame->frame->sample_rate != codec->sample_rate || + queue_frame->frame->format != codec->sample_fmt); if (queue_frame->frame != NULL) { //FIXME: this shouldn't happen any more! @@ -183,7 +186,7 @@ void *ff_audio_decoder_thread(void *opaque_audio_decoder) // This function returns a pts scaled to stream // time base double best_effort_pts = - ff_decoder_get_best_effort_pts(decoder, frame); + ff_decoder_get_best_effort_pts(decoder, frame); queue_frame(decoder, frame, best_effort_pts); av_frame_unref(frame); } diff --git a/deps/libff/libff/ff-callbacks.c b/deps/libff/libff/ff-callbacks.c index ac2d3b9..9aa0b79 100644 --- a/deps/libff/libff/ff-callbacks.c +++ b/deps/libff/libff/ff-callbacks.c @@ -16,8 +16,7 @@ #include "ff-callbacks.h" -bool ff_callbacks_frame(struct ff_callbacks *callbacks, - struct ff_frame *frame) +bool ff_callbacks_frame(struct ff_callbacks *callbacks, struct ff_frame *frame) { if (callbacks->frame == NULL) return true; @@ -26,7 +25,7 @@ bool ff_callbacks_frame(struct ff_callbacks *callbacks, } bool ff_callbacks_format(struct ff_callbacks *callbacks, - AVCodecContext *codec_context) + AVCodecContext *codec_context) { if (callbacks->format == NULL) return true; @@ -43,7 +42,7 @@ bool ff_callbacks_initialize(struct ff_callbacks *callbacks) } bool ff_callbacks_frame_initialize(struct ff_frame *frame, - struct ff_callbacks *callbacks) + struct ff_callbacks *callbacks) { if (callbacks->frame_initialize == NULL) return true; @@ -52,7 +51,7 @@ bool ff_callbacks_frame_initialize(struct ff_frame *frame, } bool ff_callbacks_frame_free(struct ff_frame *frame, - struct ff_callbacks *callbacks) + struct ff_callbacks *callbacks) { if (callbacks->frame_free == NULL) return true; diff --git a/deps/libff/libff/ff-callbacks.h b/deps/libff/libff/ff-callbacks.h index d51dca6..cb1234d 100644 --- a/deps/libff/libff/ff-callbacks.h +++ b/deps/libff/libff/ff-callbacks.h @@ -29,7 +29,6 @@ typedef bool (*ff_callback_frame)(struct ff_frame *frame, void *opaque); typedef bool (*ff_callback_format)(AVCodecContext *codec_context, void *opaque); typedef bool (*ff_callback_initialize)(void *opaque); - struct ff_callbacks { ff_callback_frame frame; ff_callback_format format; @@ -39,15 +38,14 @@ struct ff_callbacks { void *opaque; }; -bool ff_callbacks_frame(struct ff_callbacks *callbacks, - struct ff_frame *frame); +bool ff_callbacks_frame(struct ff_callbacks *callbacks, struct ff_frame *frame); bool ff_callbacks_format(struct ff_callbacks *callbacks, - AVCodecContext *codec_context); + AVCodecContext *codec_context); bool ff_callbacks_initialize(struct ff_callbacks *callbacks); bool ff_callbacks_frame_initialize(struct ff_frame *frame, - struct ff_callbacks *callbacks); + struct ff_callbacks *callbacks); bool ff_callbacks_frame_free(struct ff_frame *frame, - struct ff_callbacks *callbacks); + struct ff_callbacks *callbacks); #ifdef __cplusplus } diff --git a/deps/libff/libff/ff-circular-queue.c b/deps/libff/libff/ff-circular-queue.c index 234edc4..1381806 100644 --- a/deps/libff/libff/ff-circular-queue.c +++ b/deps/libff/libff/ff-circular-queue.c @@ -16,8 +16,7 @@ #include "ff-circular-queue.h" -static void *queue_fetch_or_alloc(struct ff_circular_queue *cq, - int index) +static void *queue_fetch_or_alloc(struct ff_circular_queue *cq, int index) { if (cq->slots[index] == NULL) cq->slots[index] = av_mallocz(cq->item_size); @@ -46,7 +45,7 @@ static void queue_wait(struct ff_circular_queue *cq) } bool ff_circular_queue_init(struct ff_circular_queue *cq, int item_size, - int capacity) + int capacity) { memset(cq, 0, sizeof(struct ff_circular_queue)); @@ -136,5 +135,3 @@ void ff_circular_queue_advance_read(struct ff_circular_queue *cq) queue_signal(cq); queue_unlock(cq); } - - diff --git a/deps/libff/libff/ff-circular-queue.h b/deps/libff/libff/ff-circular-queue.h index 74dd90d..f82b916 100644 --- a/deps/libff/libff/ff-circular-queue.h +++ b/deps/libff/libff/ff-circular-queue.h @@ -43,7 +43,7 @@ struct ff_circular_queue { typedef struct ff_circular_queue ff_circular_queue_t; bool ff_circular_queue_init(struct ff_circular_queue *cq, int item_size, - int capacity); + int capacity); void ff_circular_queue_abort(struct ff_circular_queue *cq); void ff_circular_queue_free(struct ff_circular_queue *cq); diff --git a/deps/libff/libff/ff-clock.c b/deps/libff/libff/ff-clock.c index da8aa81..720cbdf 100644 --- a/deps/libff/libff/ff-clock.c +++ b/deps/libff/libff/ff-clock.c @@ -41,7 +41,7 @@ int64_t ff_clock_start_time(struct ff_clock *clock) } bool ff_clock_start(struct ff_clock *clock, enum ff_av_sync_type sync_type, - const bool *abort) + const bool *abort) { bool release = false; bool aborted = false; @@ -57,14 +57,14 @@ bool ff_clock_start(struct ff_clock *clock, enum ff_av_sync_type sync_type, } else { while (!clock->started) { pthread_mutex_lock(&clock->mutex); - int64_t current_time = av_gettime() - + CLOCK_START_CHECK_INTERVAL; + int64_t current_time = + av_gettime() + CLOCK_START_CHECK_INTERVAL; struct timespec sleep_time = { - .tv_sec = current_time / AV_TIME_BASE, - .tv_nsec = (current_time % AV_TIME_BASE) * 1000 - }; + .tv_sec = current_time / AV_TIME_BASE, + .tv_nsec = + (current_time % AV_TIME_BASE) * 1000}; pthread_cond_timedwait(&clock->cond, &clock->mutex, - &sleep_time); + &sleep_time); aborted = *abort; @@ -75,10 +75,11 @@ bool ff_clock_start(struct ff_clock *clock, enum ff_av_sync_type sync_type, pthread_mutex_unlock(&clock->mutex); if (aborted || release) { - av_log(NULL, AV_LOG_ERROR, "could not start " - "slave clock as master clock " - "was never started before " - "being released or aborted"); + av_log(NULL, AV_LOG_ERROR, + "could not start " + "slave clock as master clock " + "was never started before " + "being released or aborted"); break; } } diff --git a/deps/libff/libff/ff-clock.h b/deps/libff/libff/ff-clock.h index 4e4aad1..0135c64 100644 --- a/deps/libff/libff/ff-clock.h +++ b/deps/libff/libff/ff-clock.h @@ -50,7 +50,7 @@ struct ff_clock { typedef struct ff_clock ff_clock_t; -struct ff_clock * ff_clock_init(void); +struct ff_clock *ff_clock_init(void); double ff_get_sync_clock(struct ff_clock *clock); struct ff_clock *ff_clock_retain(struct ff_clock *clock); struct ff_clock *ff_clock_move(struct ff_clock **clock); @@ -58,7 +58,7 @@ void ff_clock_release(struct ff_clock **clock); int64_t ff_clock_start_time(struct ff_clock *clock); bool ff_clock_start(struct ff_clock *clock, enum ff_av_sync_type sync_type, - const bool *abort); + const bool *abort); #ifdef __cplusplus } diff --git a/deps/libff/libff/ff-decoder.c b/deps/libff/libff/ff-decoder.c index 6e9d05d..f621aa8 100644 --- a/deps/libff/libff/ff-decoder.c +++ b/deps/libff/libff/ff-decoder.c @@ -25,8 +25,9 @@ extern void *ff_audio_decoder_thread(void *opaque_audio_decoder); extern void *ff_video_decoder_thread(void *opaque_video_decoder); struct ff_decoder *ff_decoder_init(AVCodecContext *codec_context, - AVStream *stream, unsigned int packet_queue_size, - unsigned int frame_queue_size) + AVStream *stream, + unsigned int packet_queue_size, + unsigned int frame_queue_size) { bool success; @@ -56,12 +57,13 @@ struct ff_decoder *ff_decoder_init(AVCodecContext *codec_context, decoder->first_frame = true; success = ff_timer_init(&decoder->refresh_timer, ff_decoder_refresh, - decoder); + decoder); if (!success) goto fail2; success = ff_circular_queue_init(&decoder->frame_queue, - sizeof(struct ff_frame), frame_queue_size); + sizeof(struct ff_frame), + frame_queue_size); if (!success) goto fail3; @@ -88,14 +90,14 @@ bool ff_decoder_start(struct ff_decoder *decoder) decoder_thread = ff_video_decoder_thread; } else { av_log(NULL, AV_LOG_ERROR, "no decoder found for type %d", - decoder->codec->codec_type); + decoder->codec->codec_type); return false; } ff_decoder_schedule_refresh(decoder, 40); - return (pthread_create(&decoder->decoder_thread, NULL, - decoder_thread, decoder) != 0); + return (pthread_create(&decoder->decoder_thread, NULL, decoder_thread, + decoder) != 0); } void ff_decoder_free(struct ff_decoder *decoder) @@ -139,7 +141,7 @@ void ff_decoder_free(struct ff_decoder *decoder) void ff_decoder_schedule_refresh(struct ff_decoder *decoder, int delay) { - ff_timer_schedule(&decoder->refresh_timer, 1000*delay); + ff_timer_schedule(&decoder->refresh_timer, 1000 * delay); } double ff_decoder_clock(void *opaque) @@ -149,16 +151,16 @@ double ff_decoder_clock(void *opaque) return decoder->current_pts + delta; } -static double get_sync_adjusted_pts_diff(struct ff_clock *clock, - double pts, double pts_diff) +static double get_sync_adjusted_pts_diff(struct ff_clock *clock, double pts, + double pts_diff) { double new_pts_diff = pts_diff; double sync_time = ff_get_sync_clock(clock); double diff = pts - sync_time; double sync_threshold; - sync_threshold = (pts_diff > AV_SYNC_THRESHOLD) - ? pts_diff : AV_SYNC_THRESHOLD; + sync_threshold = (pts_diff > AV_SYNC_THRESHOLD) ? pts_diff + : AV_SYNC_THRESHOLD; if (fabs(diff) < AV_NOSYNC_THRESHOLD) { if (diff <= -sync_threshold) { @@ -183,7 +185,7 @@ void ff_decoder_refresh(void *opaque) if (!decoder->eof || !decoder->finished) { // We expected a frame, but there were none // available - + // Schedule another call as soon as possible ff_decoder_schedule_refresh(decoder, 1); } else { @@ -191,7 +193,7 @@ void ff_decoder_refresh(void *opaque) decoder->refresh_timer.abort = true; // no more refreshes, we are at the eof av_log(NULL, AV_LOG_INFO, - "refresh timer stopping; eof"); + "refresh timer stopping; eof"); return; } } else { @@ -200,12 +202,12 @@ void ff_decoder_refresh(void *opaque) bool late_first_frame = false; frame = ff_circular_queue_peek_read( - &decoder->frame_queue); + &decoder->frame_queue); // Get frame clock and start it if needed ff_clock_t *clock = ff_clock_move(&frame->clock); if (!ff_clock_start(clock, decoder->natural_sync_clock, - &decoder->refresh_timer.abort)) { + &decoder->refresh_timer.abort)) { ff_clock_release(&clock); // Our clock was never started and deleted or @@ -213,7 +215,7 @@ void ff_decoder_refresh(void *opaque) if (decoder->refresh_timer.abort) { av_log(NULL, AV_LOG_INFO, - "refresh timer aborted"); + "refresh timer aborted"); return; } @@ -227,7 +229,7 @@ void ff_decoder_refresh(void *opaque) // Drop this frame as we have no way of timing // it ff_circular_queue_advance_read( - &decoder->frame_queue); + &decoder->frame_queue); return; } @@ -256,17 +258,16 @@ void ff_decoder_refresh(void *opaque) decoder->previous_pts = frame->pts; // if not synced against natural clock - if (clock->sync_type - != decoder->natural_sync_clock) { - pts_diff = get_sync_adjusted_pts_diff(clock, - frame->pts, pts_diff); + if (clock->sync_type != decoder->natural_sync_clock) { + pts_diff = get_sync_adjusted_pts_diff( + clock, frame->pts, pts_diff); } decoder->timer_next_wake += pts_diff; // compute the amount of time until next refresh delay_until_next_wake = decoder->timer_next_wake - - (av_gettime() / 1000000.0L); + (av_gettime() / 1000000.0L); if (delay_until_next_wake < 0.010L) { delay_until_next_wake = 0.010L; } @@ -277,9 +278,9 @@ void ff_decoder_refresh(void *opaque) ff_clock_release(&clock); ff_callbacks_frame(decoder->callbacks, frame); - ff_decoder_schedule_refresh(decoder, - (int)(delay_until_next_wake * 1000 - + 0.5L)); + ff_decoder_schedule_refresh( + decoder, + (int)(delay_until_next_wake * 1000 + 0.5L)); av_frame_free(&frame->frame); @@ -309,7 +310,7 @@ bool ff_decoder_accept(struct ff_decoder *decoder, struct ff_packet *packet) } double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder, - AVFrame *frame) + AVFrame *frame) { // this is how long each frame is added to the amount of repeated frames // according to the codec @@ -328,9 +329,10 @@ double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder, if (decoder->first_frame) { best_effort_pts = decoder->start_pts; } else { - av_log(NULL, AV_LOG_WARNING, "multiple pts < " - "start_pts; setting start pts " - "to 0"); + av_log(NULL, AV_LOG_WARNING, + "multiple pts < " + "start_pts; setting start pts " + "to 0"); decoder->start_pts = 0; } } @@ -347,11 +349,11 @@ double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder, // Update our predicted pts to include the repeated picture count // Our predicted pts clock is based on the codecs time base - estimated_frame_delay = av_frame_get_pkt_duration(frame) - * av_q2d(decoder->codec->time_base); + estimated_frame_delay = av_frame_get_pkt_duration(frame) * + av_q2d(decoder->codec->time_base); // Add repeat frame delay - estimated_frame_delay += frame->repeat_pict - / (1.0L / estimated_frame_delay); + estimated_frame_delay += + frame->repeat_pict / (1.0L / estimated_frame_delay); decoder->predicted_pts += estimated_frame_delay; @@ -359,13 +361,12 @@ double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder, } bool ff_decoder_set_frame_drop_state(struct ff_decoder *decoder, - int64_t start_time, int64_t pts) + int64_t start_time, int64_t pts) { if (pts != AV_NOPTS_VALUE) { - int64_t rescaled_pts = av_rescale_q(pts, - decoder->stream->time_base, AV_TIME_BASE_Q); - int64_t master_clock = av_gettime() - - start_time; + int64_t rescaled_pts = av_rescale_q( + pts, decoder->stream->time_base, AV_TIME_BASE_Q); + int64_t master_clock = av_gettime() - start_time; int64_t diff = master_clock - rescaled_pts; diff --git a/deps/libff/libff/ff-decoder.h b/deps/libff/libff/ff-decoder.h index 0050046..622223b 100644 --- a/deps/libff/libff/ff-decoder.h +++ b/deps/libff/libff/ff-decoder.h @@ -41,11 +41,11 @@ struct ff_decoder { unsigned int packet_queue_size; double timer_next_wake; - double previous_pts; // previous decoded frame's pts - double previous_pts_diff; // previous decoded frame pts delay - double predicted_pts; // predicted pts of next frame - double current_pts; // pts of the most recently dispatched frame - int64_t current_pts_time; // clock time when current_pts was set + double previous_pts; // previous decoded frame's pts + double previous_pts_diff; // previous decoded frame pts delay + double predicted_pts; // predicted pts of next frame + double current_pts; // pts of the most recently dispatched frame + int64_t current_pts_time; // clock time when current_pts was set int64_t start_pts; bool hwaccel_decoder; @@ -62,8 +62,9 @@ struct ff_decoder { typedef struct ff_decoder ff_decoder_t; struct ff_decoder *ff_decoder_init(AVCodecContext *codec_context, - AVStream *stream, unsigned int packet_queue_size, - unsigned int frame_queue_size); + AVStream *stream, + unsigned int packet_queue_size, + unsigned int frame_queue_size); bool ff_decoder_start(struct ff_decoder *decoder); void ff_decoder_free(struct ff_decoder *decoder); @@ -76,10 +77,10 @@ void ff_decoder_schedule_refresh(struct ff_decoder *decoder, int delay); void ff_decoder_refresh(void *opaque); double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder, - AVFrame *frame); + AVFrame *frame); bool ff_decoder_set_frame_drop_state(struct ff_decoder *decoder, - int64_t start_time, int64_t pts); + int64_t start_time, int64_t pts); #ifdef __cplusplus } diff --git a/deps/libff/libff/ff-demuxer.c b/deps/libff/libff/ff-demuxer.c index f027ad4..f271486 100644 --- a/deps/libff/libff/ff-demuxer.c +++ b/deps/libff/libff/ff-demuxer.c @@ -43,7 +43,7 @@ struct ff_demuxer *ff_demuxer_init() avdevice_register_all(); avfilter_register_all(); avformat_network_init(); - + demuxer = av_mallocz(sizeof(struct ff_demuxer)); if (demuxer == NULL) return NULL; @@ -60,7 +60,7 @@ struct ff_demuxer *ff_demuxer_init() } bool ff_demuxer_open(struct ff_demuxer *demuxer, char *input, - char *input_format) + char *input_format) { int ret; @@ -69,7 +69,7 @@ bool ff_demuxer_open(struct ff_demuxer *demuxer, char *input, demuxer->input_format = av_strdup(input_format); ret = pthread_create(&demuxer->demuxer_thread, NULL, demux_thread, - demuxer); + demuxer); return ret == 0; } @@ -100,12 +100,11 @@ void ff_demuxer_free(struct ff_demuxer *demuxer) } void ff_demuxer_set_callbacks(struct ff_callbacks *callbacks, - ff_callback_frame frame, - ff_callback_format format, - ff_callback_initialize initialize, - ff_callback_frame frame_initialize, - ff_callback_frame frame_free, - void *opaque) + ff_callback_frame frame, + ff_callback_format format, + ff_callback_initialize initialize, + ff_callback_frame frame_initialize, + ff_callback_frame frame_free, void *opaque) { callbacks->opaque = opaque; callbacks->frame = frame; @@ -165,19 +164,18 @@ AVHWAccel *find_hwaccel_codec(AVCodecContext *codec_context) while ((hwaccel = av_hwaccel_next(hwaccel)) != NULL) { if (hwaccel->id == codec_context->codec_id && - (hwaccel->pix_fmt == AV_PIX_FMT_VDA_VLD || + (hwaccel->pix_fmt == AV_PIX_FMT_VDA_VLD || hwaccel->pix_fmt == AV_PIX_FMT_DXVA2_VLD || hwaccel->pix_fmt == AV_PIX_FMT_VAAPI_VLD)) { return hwaccel; } - } return NULL; } enum AVPixelFormat get_hwaccel_format(struct AVCodecContext *s, - const enum AVPixelFormat * fmt) + const enum AVPixelFormat *fmt) { (void)s; (void)fmt; @@ -187,25 +185,25 @@ enum AVPixelFormat get_hwaccel_format(struct AVCodecContext *s, } static bool initialize_decoder(struct ff_demuxer *demuxer, - AVCodecContext *codec_context, AVStream *stream, - bool hwaccel_decoder) + AVCodecContext *codec_context, AVStream *stream, + bool hwaccel_decoder) { switch (codec_context->codec_type) { case AVMEDIA_TYPE_AUDIO: demuxer->audio_decoder = ff_decoder_init( - codec_context, stream, - demuxer->options.audio_packet_queue_size, - demuxer->options.audio_frame_queue_size); + codec_context, stream, + demuxer->options.audio_packet_queue_size, + demuxer->options.audio_frame_queue_size); demuxer->audio_decoder->hwaccel_decoder = hwaccel_decoder; demuxer->audio_decoder->frame_drop = - demuxer->options.frame_drop; + demuxer->options.frame_drop; demuxer->audio_decoder->natural_sync_clock = - AV_SYNC_AUDIO_MASTER; + AV_SYNC_AUDIO_MASTER; demuxer->audio_decoder->callbacks = &demuxer->audio_callbacks; if (!ff_callbacks_format(&demuxer->audio_callbacks, - codec_context)) { + codec_context)) { ff_decoder_free(demuxer->audio_decoder); demuxer->audio_decoder = NULL; return false; @@ -216,19 +214,19 @@ static bool initialize_decoder(struct ff_demuxer *demuxer, case AVMEDIA_TYPE_VIDEO: demuxer->video_decoder = ff_decoder_init( - codec_context, stream, - demuxer->options.video_packet_queue_size, - demuxer->options.video_frame_queue_size); + codec_context, stream, + demuxer->options.video_packet_queue_size, + demuxer->options.video_frame_queue_size); demuxer->video_decoder->hwaccel_decoder = hwaccel_decoder; demuxer->video_decoder->frame_drop = - demuxer->options.frame_drop; + demuxer->options.frame_drop; demuxer->video_decoder->natural_sync_clock = - AV_SYNC_VIDEO_MASTER; + AV_SYNC_VIDEO_MASTER; demuxer->video_decoder->callbacks = &demuxer->video_callbacks; if (!ff_callbacks_format(&demuxer->video_callbacks, - codec_context)) { + codec_context)) { ff_decoder_free(demuxer->video_decoder); demuxer->video_decoder = NULL; return false; @@ -240,8 +238,8 @@ static bool initialize_decoder(struct ff_demuxer *demuxer, } } -typedef enum AVPixelFormat (*AVGetFormatCb)( - struct AVCodecContext *s, const enum AVPixelFormat * fmt); +typedef enum AVPixelFormat (*AVGetFormatCb)(struct AVCodecContext *s, + const enum AVPixelFormat *fmt); static bool find_decoder(struct ff_demuxer *demuxer, AVStream *stream) { @@ -258,10 +256,10 @@ static bool find_decoder(struct ff_demuxer *demuxer, AVStream *stream) codec_context->refcounted_frames = 1; // png/tiff decoders have serious issues with multiple threads - if (codec_context->codec_id == AV_CODEC_ID_PNG - || codec_context->codec_id == AV_CODEC_ID_TIFF - || codec_context->codec_id == AV_CODEC_ID_JPEG2000 - || codec_context->codec_id == AV_CODEC_ID_WEBP) + if (codec_context->codec_id == AV_CODEC_ID_PNG || + codec_context->codec_id == AV_CODEC_ID_TIFF || + codec_context->codec_id == AV_CODEC_ID_JPEG2000 || + codec_context->codec_id == AV_CODEC_ID_WEBP) codec_context->thread_count = 1; if (demuxer->options.is_hw_decoding) { @@ -269,24 +267,24 @@ static bool find_decoder(struct ff_demuxer *demuxer, AVStream *stream) if (hwaccel) { AVCodec *codec_vda = - avcodec_find_decoder_by_name(hwaccel->name); + avcodec_find_decoder_by_name(hwaccel->name); if (codec_vda != NULL) { AVGetFormatCb original_get_format = - codec_context->get_format; + codec_context->get_format; codec_context->get_format = get_hwaccel_format; codec_context->opaque = hwaccel; ret = avcodec_open2(codec_context, codec_vda, - &options_dict); + &options_dict); if (ret < 0) { av_log(NULL, AV_LOG_WARNING, - "no hardware decoder found for" - " codec with id %d", - codec_context->codec_id); + "no hardware decoder found for" + " codec with id %d", + codec_context->codec_id); codec_context->get_format = - original_get_format; + original_get_format; codec_context->opaque = NULL; } else { codec = codec_vda; @@ -305,21 +303,23 @@ static bool find_decoder(struct ff_demuxer *demuxer, AVStream *stream) if (!codec) codec = avcodec_find_decoder(codec_context->codec_id); if (codec == NULL) { - av_log(NULL, AV_LOG_WARNING, "no decoder found for" - " codec with id %d", - codec_context->codec_id); + av_log(NULL, AV_LOG_WARNING, + "no decoder found for" + " codec with id %d", + codec_context->codec_id); return false; } if (avcodec_open2(codec_context, codec, &options_dict) < 0) { - av_log(NULL, AV_LOG_WARNING, "unable to open decoder" - " with codec id %d", - codec_context->codec_id); + av_log(NULL, AV_LOG_WARNING, + "unable to open decoder" + " with codec id %d", + codec_context->codec_id); return false; } } return initialize_decoder(demuxer, codec_context, stream, - hwaccel_decoder); + hwaccel_decoder); } void ff_demuxer_flush(struct ff_demuxer *demuxer) @@ -328,14 +328,14 @@ void ff_demuxer_flush(struct ff_demuxer *demuxer) demuxer->video_decoder->stream != NULL) { packet_queue_flush(&demuxer->video_decoder->packet_queue); packet_queue_put_flush_packet( - &demuxer->video_decoder->packet_queue); + &demuxer->video_decoder->packet_queue); } if (demuxer->audio_decoder != NULL && demuxer->audio_decoder->stream != NULL) { packet_queue_flush(&demuxer->audio_decoder->packet_queue); packet_queue_put_flush_packet( - &demuxer->audio_decoder->packet_queue); + &demuxer->audio_decoder->packet_queue); } } @@ -352,18 +352,18 @@ void ff_demuxer_reset(struct ff_demuxer *demuxer) if (demuxer->audio_decoder != NULL) { ff_clock_retain(clock); packet_queue_put(&demuxer->audio_decoder->packet_queue, - &packet); + &packet); } if (demuxer->video_decoder != NULL) { ff_clock_retain(clock); packet_queue_put(&demuxer->video_decoder->packet_queue, - &packet); + &packet); } } static bool open_input(struct ff_demuxer *demuxer, - AVFormatContext **format_context) + AVFormatContext **format_context) { AVInputFormat *input_format = NULL; @@ -377,24 +377,25 @@ static bool open_input(struct ff_demuxer *demuxer, if (demuxer->input_format != NULL) { input_format = av_find_input_format(demuxer->input_format); if (input_format == NULL) - av_log(NULL, AV_LOG_WARNING, "unable to find input " - "format %s", - demuxer->input_format); + av_log(NULL, AV_LOG_WARNING, + "unable to find input " + "format %s", + demuxer->input_format); } - if (avformat_open_input(format_context, demuxer->input, - input_format, &demuxer->options.custom_options) != 0) + if (avformat_open_input(format_context, demuxer->input, input_format, + &demuxer->options.custom_options) != 0) return false; return avformat_find_stream_info(*format_context, NULL) >= 0; } static inline void set_decoder_start_time(struct ff_decoder *decoder, - int64_t start_time) + int64_t start_time) { if (decoder) decoder->start_pts = av_rescale_q(start_time, AV_TIME_BASE_Q, - decoder->stream->time_base); + decoder->stream->time_base); } static bool find_and_initialize_stream_decoders(struct ff_demuxer *demuxer) @@ -415,12 +416,12 @@ static bool find_and_initialize_stream_decoders(struct ff_demuxer *demuxer) audio_stream = format_context->streams[i]; } - int default_stream_index = av_find_default_stream_index( - demuxer->format_context); + int default_stream_index = + av_find_default_stream_index(demuxer->format_context); if (default_stream_index >= 0) { AVStream *stream = - format_context->streams[default_stream_index]; + format_context->streams[default_stream_index]; if (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) demuxer->clock.sync_type = AV_SYNC_AUDIO_MASTER; @@ -452,7 +453,7 @@ static bool find_and_initialize_stream_decoders(struct ff_demuxer *demuxer) } st_start_time = av_rescale_q(st->start_time, st->time_base, - AV_TIME_BASE_Q); + AV_TIME_BASE_Q); start_time = FFMIN(start_time, st_start_time); } @@ -508,18 +509,17 @@ static bool handle_seek(struct ff_demuxer *demuxer) seek_stream = demuxer->audio_decoder->stream; } - if (seek_stream != NULL && demuxer->format_context->duration != AV_NOPTS_VALUE) { - seek_target = av_rescale_q(seek_target, - AV_TIME_BASE_Q, - seek_stream->time_base); + if (seek_stream != NULL && + demuxer->format_context->duration != AV_NOPTS_VALUE) { + seek_target = av_rescale_q(seek_target, AV_TIME_BASE_Q, + seek_stream->time_base); } - ret = av_seek_frame(demuxer->format_context, - 0, seek_target, - demuxer->seek_flags); + ret = av_seek_frame(demuxer->format_context, 0, seek_target, + demuxer->seek_flags); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "unable to seek stream: %s", - av_err2str(ret)); + av_err2str(ret)); demuxer->seek_pos = 0; demuxer->seek_request = false; return false; @@ -551,7 +551,7 @@ static void seek_beginning(struct ff_demuxer *demuxer) static void *demux_thread(void *opaque) { - struct ff_demuxer *demuxer = (struct ff_demuxer *) opaque; + struct ff_demuxer *demuxer = (struct ff_demuxer *)opaque; int result; struct ff_packet packet = {0}; @@ -584,7 +584,7 @@ static void *demux_thread(void *opaque) eof = true; } else if (demuxer->format_context->pb != NULL) { AVIOContext *io_context = - demuxer->format_context->pb; + demuxer->format_context->pb; if (io_context->error == 0) { av_usleep(100 * 1000); // 100ms continue; @@ -603,8 +603,8 @@ static void *demux_thread(void *opaque) continue; } else { av_log(NULL, AV_LOG_ERROR, - "av_read_frame() failed: %s", - av_err2str(result)); + "av_read_frame() failed: %s", + av_err2str(result)); break; } } diff --git a/deps/libff/libff/ff-demuxer.h b/deps/libff/libff/ff-demuxer.h index 55562e4..f6aa109 100644 --- a/deps/libff/libff/ff-demuxer.h +++ b/deps/libff/libff/ff-demuxer.h @@ -31,8 +31,7 @@ extern "C" { #endif -struct ff_demuxer_options -{ +struct ff_demuxer_options { int audio_packet_queue_size; int video_packet_queue_size; int audio_frame_queue_size; @@ -75,16 +74,16 @@ struct ff_demuxer { typedef struct ff_demuxer ff_demuxer_t; struct ff_demuxer *ff_demuxer_init(); -bool ff_demuxer_open(struct ff_demuxer *demuxer, char *input, char *input_format); +bool ff_demuxer_open(struct ff_demuxer *demuxer, char *input, + char *input_format); void ff_demuxer_free(struct ff_demuxer *demuxer); void ff_demuxer_set_callbacks(struct ff_callbacks *callbacks, - ff_callback_frame frame, - ff_callback_format format, - ff_callback_initialize initialize, - ff_callback_frame frame_initialize, - ff_callback_frame frame_free, - void *opaque); + ff_callback_frame frame, + ff_callback_format format, + ff_callback_initialize initialize, + ff_callback_frame frame_initialize, + ff_callback_frame frame_free, void *opaque); void ff_demuxer_flush(struct ff_demuxer *demuxer); diff --git a/deps/libff/libff/ff-packet-queue.c b/deps/libff/libff/ff-packet-queue.c index dd85dd4..40e4666 100644 --- a/deps/libff/libff/ff-packet-queue.c +++ b/deps/libff/libff/ff-packet-queue.c @@ -36,7 +36,6 @@ fail1: pthread_mutex_destroy(&q->mutex); fail: return false; - } void packet_queue_abort(struct ff_packet_queue *q) @@ -93,7 +92,7 @@ int packet_queue_put_flush_packet(struct ff_packet_queue *q) } int packet_queue_get(struct ff_packet_queue *q, struct ff_packet *packet, - bool block) + bool block) { struct ff_packet_list *potential_packet; int return_status; @@ -141,7 +140,7 @@ void packet_queue_flush(struct ff_packet_queue *q) pthread_mutex_lock(&q->mutex); for (packet = q->first_packet; packet != NULL; - packet = q->first_packet) { + packet = q->first_packet) { q->first_packet = packet->next; av_free_packet(&packet->packet.base); if (packet->packet.clock != NULL) diff --git a/deps/libff/libff/ff-packet-queue.h b/deps/libff/libff/ff-packet-queue.h index 981509c..febb189 100644 --- a/deps/libff/libff/ff-packet-queue.h +++ b/deps/libff/libff/ff-packet-queue.h @@ -36,8 +36,8 @@ struct ff_packet { }; struct ff_packet_list { - struct ff_packet packet; - struct ff_packet_list *next; + struct ff_packet packet; + struct ff_packet_list *next; }; struct ff_packet_queue { @@ -59,7 +59,7 @@ void packet_queue_free(struct ff_packet_queue *q); int packet_queue_put(struct ff_packet_queue *q, struct ff_packet *packet); int packet_queue_put_flush_packet(struct ff_packet_queue *q); int packet_queue_get(struct ff_packet_queue *q, struct ff_packet *packet, - bool block); + bool block); void packet_queue_flush(struct ff_packet_queue *q); diff --git a/deps/libff/libff/ff-timer.c b/deps/libff/libff/ff-timer.c index c0b301b..e3ffa34 100644 --- a/deps/libff/libff/ff-timer.c +++ b/deps/libff/libff/ff-timer.c @@ -38,17 +38,16 @@ static void *timer_thread(void *opaque) uint64_t current_time = av_gettime(); if (current_time < timer->next_wake) { struct timespec sleep_time = { - .tv_sec = timer->next_wake / AV_TIME_BASE, - .tv_nsec = (timer->next_wake % AV_TIME_BASE) - * 1000 - }; + .tv_sec = timer->next_wake / AV_TIME_BASE, + .tv_nsec = (timer->next_wake % AV_TIME_BASE) * + 1000}; - ret = pthread_cond_timedwait(&timer->cond, - &timer->mutex, &sleep_time); + ret = pthread_cond_timedwait( + &timer->cond, &timer->mutex, &sleep_time); if (ret != ETIMEDOUT) { // failed to wait, just sleep - av_usleep((unsigned)(timer->next_wake - - current_time)); + av_usleep((unsigned)(timer->next_wake - + current_time)); } pthread_mutex_unlock(&timer->mutex); @@ -78,7 +77,7 @@ static void *timer_thread(void *opaque) } bool ff_timer_init(struct ff_timer *timer, ff_timer_callback callback, - void *opaque) + void *opaque) { memset(timer, 0, sizeof(struct ff_timer)); timer->abort = false; @@ -88,14 +87,15 @@ bool ff_timer_init(struct ff_timer *timer, ff_timer_callback callback, if (pthread_mutexattr_init(&timer->mutexattr) != 0) goto fail; if (pthread_mutexattr_settype(&timer->mutexattr, - PTHREAD_MUTEX_RECURSIVE)) + PTHREAD_MUTEX_RECURSIVE)) goto fail1; if (pthread_mutex_init(&timer->mutex, &timer->mutexattr) != 0) goto fail1; if (pthread_cond_init(&timer->cond, NULL) != 0) goto fail2; - if (pthread_create(&timer->timer_thread, NULL, timer_thread, timer) != 0) + if (pthread_create(&timer->timer_thread, NULL, timer_thread, timer) != + 0) goto fail3; return true; diff --git a/deps/libff/libff/ff-timer.h b/deps/libff/libff/ff-timer.h index b7b24a5..7a6d45f 100644 --- a/deps/libff/libff/ff-timer.h +++ b/deps/libff/libff/ff-timer.h @@ -43,8 +43,8 @@ struct ff_timer { typedef struct ff_timer ff_timer_t; -bool ff_timer_init(struct ff_timer *timer, - ff_timer_callback callback, void *opaque); +bool ff_timer_init(struct ff_timer *timer, ff_timer_callback callback, + void *opaque); void ff_timer_free(struct ff_timer *timer); void ff_timer_schedule(struct ff_timer *timer, uint64_t microseconds); diff --git a/deps/libff/libff/ff-util.c b/deps/libff/libff/ff-util.c index 4db53c0..87ad581 100644 --- a/deps/libff/libff/ff-util.c +++ b/deps/libff/libff/ff-util.c @@ -40,7 +40,7 @@ struct ff_format_desc { const char *extensions; enum AVCodecID audio_codec; enum AVCodecID video_codec; - const struct AVCodecTag * const *codec_tags; + const struct AVCodecTag *const *codec_tags; const struct ff_format_desc *next; }; @@ -56,9 +56,11 @@ struct ff_codec_desc { void ff_init() { +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) av_register_all(); //avdevice_register_all(); avcodec_register_all(); +#endif avformat_network_init(); } @@ -71,7 +73,7 @@ const char *ff_codec_name_from_id(int codec_id) return NULL; } -static bool get_codecs(const AVCodecDescriptor*** descs, unsigned int *size) +static bool get_codecs(const AVCodecDescriptor ***descs, unsigned int *size) { const AVCodecDescriptor *desc = NULL; const AVCodecDescriptor **codecs; @@ -84,8 +86,10 @@ static bool get_codecs(const AVCodecDescriptor*** descs, unsigned int *size) codecs = av_calloc(codec_count, sizeof(AVCodecDescriptor *)); if (codecs == NULL) { - av_log(NULL, AV_LOG_ERROR, "unable to allocate sorted codec " - "array with size %d", codec_count); + av_log(NULL, AV_LOG_ERROR, + "unable to allocate sorted codec " + "array with size %d", + codec_count); return false; } @@ -99,18 +103,37 @@ static bool get_codecs(const AVCodecDescriptor*** descs, unsigned int *size) static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev) { - while ((prev = av_codec_next(prev)) != NULL) { - if (prev->id == id && av_codec_is_encoder(prev)) - return prev; - } +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 9, 100) + const AVCodec *cur = NULL; + void *i = 0; + bool found_prev = false; - return NULL; + while ((cur = av_codec_iterate(&i)) != NULL) { + if (cur->id == id && av_codec_is_encoder(cur)) { + if (!prev) { + return cur; + } else if (!found_prev) { + if (cur == prev) { + found_prev = true; + } + } else { + return cur; + } + } + } +#else + while ((prev = av_codec_next(prev)) != NULL) { + if (prev->id == id && av_codec_is_encoder(prev)) + return prev; + } +#endif + return NULL; } static void add_codec_to_list(const struct ff_format_desc *format_desc, - struct ff_codec_desc **first, struct ff_codec_desc **current, - enum AVCodecID id, const AVCodec *codec, - bool ignore_compatability) + struct ff_codec_desc **first, + struct ff_codec_desc **current, enum AVCodecID id, + const AVCodec *codec, bool ignore_compatability) { if (codec == NULL) codec = avcodec_find_encoder(id); @@ -125,8 +148,8 @@ static void add_codec_to_list(const struct ff_format_desc *format_desc, if (!ignore_compatability) { // Format doesn't support this codec - unsigned int tag = av_codec_get_tag(format_desc->codec_tags, - codec->id); + unsigned int tag = + av_codec_get_tag(format_desc->codec_tags, codec->id); if (tag == 0) return; } @@ -162,18 +185,19 @@ static void add_codec_to_list(const struct ff_format_desc *format_desc, } static void get_codecs_for_id(const struct ff_format_desc *format_desc, - struct ff_codec_desc **first, struct ff_codec_desc **current, - enum AVCodecID id, bool ignore_compatability) + struct ff_codec_desc **first, + struct ff_codec_desc **current, enum AVCodecID id, + bool ignore_compatability) { const AVCodec *codec = NULL; while ((codec = next_codec_for_id(id, codec)) != NULL) - add_codec_to_list(format_desc, first, current, codec->id, - codec, ignore_compatability); + add_codec_to_list(format_desc, first, current, codec->id, codec, + ignore_compatability); } -const struct ff_codec_desc *ff_codec_supported( - const struct ff_format_desc *format_desc, - bool ignore_compatability) +const struct ff_codec_desc * +ff_codec_supported(const struct ff_format_desc *format_desc, + bool ignore_compatability) { const AVCodecDescriptor **codecs; unsigned int size; @@ -184,10 +208,10 @@ const struct ff_codec_desc *ff_codec_supported( if (!get_codecs(&codecs, &size)) return NULL; - for(i = 0; i < size; i++) { + for (i = 0; i < size; i++) { const AVCodecDescriptor *codec = codecs[i]; get_codecs_for_id(format_desc, &first, ¤t, codec->id, - ignore_compatability); + ignore_compatability); } av_free((void *)codecs); @@ -235,8 +259,8 @@ enum ff_codec_type ff_codec_desc_type(const struct ff_codec_desc *codec_desc) return FF_CODEC_UNKNOWN; } -const struct ff_codec_desc *ff_codec_desc_next( - const struct ff_codec_desc *codec_desc) +const struct ff_codec_desc * +ff_codec_desc_next(const struct ff_codec_desc *codec_desc) { if (codec_desc != NULL) return codec_desc->next; @@ -255,7 +279,7 @@ int ff_codec_desc_id(const struct ff_codec_desc *codec_desc) void ff_codec_desc_free(const struct ff_codec_desc *codec_desc) { const struct ff_codec_desc *desc = codec_desc; - while(desc != NULL) { + while (desc != NULL) { const struct ff_codec_desc *next = desc->next; av_free((void *)desc); desc = next; @@ -283,11 +307,17 @@ static inline bool is_output_device(const AVClass *avclass) const struct ff_format_desc *ff_format_supported() { - AVOutputFormat *output_format = NULL; + const AVOutputFormat *output_format = NULL; struct ff_format_desc *desc = NULL; struct ff_format_desc *current = NULL; +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(58, 9, 100) + void *i = 0; + + while ((output_format = av_muxer_iterate(&i)) != NULL) { +#else while ((output_format = av_oformat_next(output_format)) != NULL) { +#endif struct ff_format_desc *d; if (is_output_device(output_format->priv_class)) continue; @@ -377,8 +407,8 @@ int ff_format_desc_video(const struct ff_format_desc *format_desc) return false; } -const struct ff_format_desc *ff_format_desc_next( - const struct ff_format_desc *format_desc) +const struct ff_format_desc * +ff_format_desc_next(const struct ff_format_desc *format_desc) { if (format_desc != NULL) return format_desc->next; @@ -387,7 +417,7 @@ const struct ff_format_desc *ff_format_desc_next( } static const char *get_encoder_name(const struct ff_format_desc *format_desc, - enum AVCodecID codec_id) + enum AVCodecID codec_id) { AVCodec *codec = avcodec_find_encoder(codec_id); if (codec == NULL && codec_id == AV_CODEC_ID_NONE) @@ -398,27 +428,24 @@ static const char *get_encoder_name(const struct ff_format_desc *format_desc, return codec->name; } -const char *ff_format_desc_get_default_name( - const struct ff_format_desc *format_desc, - enum ff_codec_type codec_type) +const char * +ff_format_desc_get_default_name(const struct ff_format_desc *format_desc, + enum ff_codec_type codec_type) { - switch (codec_type) - { - case FF_CODEC_AUDIO: - return get_encoder_name(format_desc, - format_desc->audio_codec); - case FF_CODEC_VIDEO: - return get_encoder_name(format_desc, - format_desc->video_codec); - default: - return NULL; + switch (codec_type) { + case FF_CODEC_AUDIO: + return get_encoder_name(format_desc, format_desc->audio_codec); + case FF_CODEC_VIDEO: + return get_encoder_name(format_desc, format_desc->video_codec); + default: + return NULL; } } void ff_format_desc_free(const struct ff_format_desc *format_desc) { const struct ff_format_desc *desc = format_desc; - while(desc != NULL) { + while (desc != NULL) { const struct ff_format_desc *next = desc->next; av_free((void *)desc); desc = next; diff --git a/deps/libff/libff/ff-util.h b/deps/libff/libff/ff-util.h index ca6875d..f03b3fa 100644 --- a/deps/libff/libff/ff-util.h +++ b/deps/libff/libff/ff-util.h @@ -22,11 +22,7 @@ extern "C" { #endif -enum ff_codec_type { - FF_CODEC_AUDIO, - FF_CODEC_VIDEO, - FF_CODEC_UNKNOWN -}; +enum ff_codec_type { FF_CODEC_AUDIO, FF_CODEC_VIDEO, FF_CODEC_UNKNOWN }; struct ff_format_desc; struct ff_codec_desc; @@ -36,9 +32,9 @@ void ff_init(); const char *ff_codec_name_from_id(int codec_id); // Codec Description -const struct ff_codec_desc *ff_codec_supported( - const struct ff_format_desc *format_desc, - bool ignore_compatability); +const struct ff_codec_desc * +ff_codec_supported(const struct ff_format_desc *format_desc, + bool ignore_compatability); void ff_codec_desc_free(const struct ff_codec_desc *codec_desc); const char *ff_codec_desc_name(const struct ff_codec_desc *codec_desc); const char *ff_codec_desc_long_name(const struct ff_codec_desc *codec_desc); @@ -46,8 +42,8 @@ enum ff_codec_type ff_codec_desc_type(const struct ff_codec_desc *codec_desc); bool ff_codec_desc_is_alias(const struct ff_codec_desc *codec_desc); const char *ff_codec_desc_base_name(const struct ff_codec_desc *codec_desc); int ff_codec_desc_id(const struct ff_codec_desc *codec_desc); -const struct ff_codec_desc *ff_codec_desc_next( - const struct ff_codec_desc *codec_desc); +const struct ff_codec_desc * +ff_codec_desc_next(const struct ff_codec_desc *codec_desc); // Format Description const struct ff_format_desc *ff_format_supported(); @@ -60,11 +56,11 @@ bool ff_format_desc_has_audio(const struct ff_format_desc *format_desc); bool ff_format_desc_has_video(const struct ff_format_desc *format_desc); int ff_format_desc_audio(const struct ff_format_desc *format_desc); int ff_format_desc_video(const struct ff_format_desc *format_desc); -const char *ff_format_desc_get_default_name( - const struct ff_format_desc *format_desc, - enum ff_codec_type codec_type); -const struct ff_format_desc *ff_format_desc_next( - const struct ff_format_desc *format_desc); +const char * +ff_format_desc_get_default_name(const struct ff_format_desc *format_desc, + enum ff_codec_type codec_type); +const struct ff_format_desc * +ff_format_desc_next(const struct ff_format_desc *format_desc); #ifdef __cplusplus } diff --git a/deps/libff/libff/ff-video-decoder.c b/deps/libff/libff/ff-video-decoder.c index 040d232..507e9a6 100644 --- a/deps/libff/libff/ff-video-decoder.c +++ b/deps/libff/libff/ff-video-decoder.c @@ -30,7 +30,7 @@ #include "ff-compat.h" static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame, - double best_effort_pts) + double best_effort_pts) { struct ff_frame *queue_frame; bool call_initialize; @@ -46,10 +46,10 @@ static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame, // Check if we need to communicate a different format has been received // to any callbacks AVCodecContext *codec = decoder->codec; - call_initialize = (queue_frame->frame == NULL - || queue_frame->frame->width != codec->width - || queue_frame->frame->height != codec->height - || queue_frame->frame->format != codec->pix_fmt); + call_initialize = (queue_frame->frame == NULL || + queue_frame->frame->width != codec->width || + queue_frame->frame->height != codec->height || + queue_frame->frame->format != codec->pix_fmt); if (queue_frame->frame != NULL) { // This shouldn't happen any more, the frames are freed in @@ -72,7 +72,7 @@ static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame, void *ff_video_decoder_thread(void *opaque_video_decoder) { - struct ff_decoder *decoder = (struct ff_decoder*)opaque_video_decoder; + struct ff_decoder *decoder = (struct ff_decoder *)opaque_video_decoder; struct ff_packet packet = {0}; int complete; @@ -82,16 +82,19 @@ void *ff_video_decoder_thread(void *opaque_video_decoder) while (!decoder->abort) { if (decoder->eof) - ret = packet_queue_get(&decoder->packet_queue, &packet, 0); + ret = packet_queue_get(&decoder->packet_queue, &packet, + 0); else - ret = packet_queue_get(&decoder->packet_queue, &packet, 1); + ret = packet_queue_get(&decoder->packet_queue, &packet, + 1); if (ret == FF_PACKET_EMPTY || ret == FF_PACKET_FAIL) { // should we just use abort here? break; } - if (packet.base.data == decoder->packet_queue.flush_packet.base.data) { + if (packet.base.data == + decoder->packet_queue.flush_packet.base.data) { avcodec_flush_buffers(decoder->codec); continue; } @@ -116,11 +119,11 @@ void *ff_video_decoder_thread(void *opaque_video_decoder) frame_drop_check &= start_time != AV_NOPTS_VALUE; if (frame_drop_check) - ff_decoder_set_frame_drop_state(decoder, - start_time, packet.base.pts); + ff_decoder_set_frame_drop_state(decoder, start_time, + packet.base.pts); - avcodec_decode_video2(decoder->codec, frame, - &complete, &packet.base); + avcodec_decode_video2(decoder->codec, frame, &complete, + &packet.base); // Did we get an entire video frame? This doesn't guarantee // there is a picture to show for some codecs, but we still want @@ -131,7 +134,7 @@ void *ff_video_decoder_thread(void *opaque_video_decoder) // This function returns a pts scaled to stream // time base double best_effort_pts = - ff_decoder_get_best_effort_pts(decoder, frame); + ff_decoder_get_best_effort_pts(decoder, frame); queue_frame(decoder, frame, best_effort_pts); av_frame_unref(frame); diff --git a/deps/media-playback/CMakeLists.txt b/deps/media-playback/CMakeLists.txt index 3accdd8..d58d121 100644 --- a/deps/media-playback/CMakeLists.txt +++ b/deps/media-playback/CMakeLists.txt @@ -9,6 +9,7 @@ include_directories( ) set(media-playback_HEADERS + media-playback/closest-format.h media-playback/decode.h media-playback/media.h ) diff --git a/deps/media-playback/media-playback/closest-format.h b/deps/media-playback/media-playback/closest-format.h index 8377914..c6f2ea5 100644 --- a/deps/media-playback/media-playback/closest-format.h +++ b/deps/media-playback/media-playback/closest-format.h @@ -61,6 +61,15 @@ static enum AVPixelFormat closest_format(enum AVPixelFormat fmt) case AV_PIX_FMT_YUV420P14LE: return AV_PIX_FMT_YUV420P; + case AV_PIX_FMT_YUVA420P: + return AV_PIX_FMT_YUVA420P; + + case AV_PIX_FMT_YUVA422P: + return AV_PIX_FMT_YUVA422P; + + case AV_PIX_FMT_YUVA444P: + return AV_PIX_FMT_YUVA444P; + case AV_PIX_FMT_RGBA: case AV_PIX_FMT_BGRA: case AV_PIX_FMT_BGR0: diff --git a/deps/media-playback/media-playback/decode.c b/deps/media-playback/media-playback/decode.c index d5327b3..e5a259b 100644 --- a/deps/media-playback/media-playback/decode.c +++ b/deps/media-playback/media-playback/decode.c @@ -17,29 +17,62 @@ #include "decode.h" #include "media.h" -static AVCodec *find_hardware_decoder(enum AVCodecID id) -{ - AVHWAccel *hwa = av_hwaccel_next(NULL); - AVCodec *c = NULL; +#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(58, 4, 100) +#define USE_NEW_HARDWARE_CODEC_METHOD +#endif - while (hwa) { - if (hwa->id == id) { - if (hwa->pix_fmt == AV_PIX_FMT_VDTOOL || - hwa->pix_fmt == AV_PIX_FMT_DXVA2_VLD || - hwa->pix_fmt == AV_PIX_FMT_VAAPI_VLD) { - c = avcodec_find_decoder_by_name(hwa->name); - if (c) - break; - } +#ifdef USE_NEW_HARDWARE_CODEC_METHOD +enum AVHWDeviceType hw_priority[] = { + AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_DXVA2, + AV_HWDEVICE_TYPE_VAAPI, AV_HWDEVICE_TYPE_VDPAU, + AV_HWDEVICE_TYPE_QSV, AV_HWDEVICE_TYPE_NONE, +}; + +static bool has_hw_type(AVCodec *c, enum AVHWDeviceType type, + enum AVPixelFormat *hw_format) +{ + for (int i = 0;; i++) { + const AVCodecHWConfig *config = avcodec_get_hw_config(c, i); + if (!config) { + break; } - hwa = av_hwaccel_next(hwa); + if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && + config->device_type == type) { + *hw_format = config->pix_fmt; + return true; + } } - return c; + return false; } -static int mp_open_codec(struct mp_decode *d) +static void init_hw_decoder(struct mp_decode *d, AVCodecContext *c) +{ + enum AVHWDeviceType *priority = hw_priority; + AVBufferRef *hw_ctx = NULL; + + while (*priority != AV_HWDEVICE_TYPE_NONE) { + if (has_hw_type(d->codec, *priority, &d->hw_format)) { + int ret = av_hwdevice_ctx_create(&hw_ctx, *priority, + NULL, NULL, 0); + if (ret == 0) + break; + } + + priority++; + } + + if (hw_ctx) { + c->hw_device_ctx = av_buffer_ref(hw_ctx); + c->opaque = d; + d->hw_ctx = hw_ctx; + d->hw = true; + } +} +#endif + +static int mp_open_codec(struct mp_decode *d, bool hw) { AVCodecContext *c; int ret; @@ -58,12 +91,17 @@ static int mp_open_codec(struct mp_decode *d) c = d->stream->codec; #endif - if (c->thread_count == 1 && - c->codec_id != AV_CODEC_ID_PNG && + d->hw = false; + +#ifdef USE_NEW_HARDWARE_CODEC_METHOD + if (hw) + init_hw_decoder(d, c); +#endif + + if (c->thread_count == 1 && c->codec_id != AV_CODEC_ID_PNG && c->codec_id != AV_CODEC_ID_TIFF && c->codec_id != AV_CODEC_ID_JPEG2000 && - c->codec_id != AV_CODEC_ID_MPEG4 && - c->codec_id != AV_CODEC_ID_WEBP) + c->codec_id != AV_CODEC_ID_MPEG4 && c->codec_id != AV_CODEC_ID_WEBP) c->thread_count = 0; ret = avcodec_open2(c, d->codec, NULL); @@ -103,45 +141,54 @@ bool mp_decode_init(mp_media_t *m, enum AVMediaType type, bool hw) id = stream->codec->codec_id; #endif - if (hw) { - d->codec = find_hardware_decoder(id); - if (d->codec) { - ret = mp_open_codec(d); - if (ret < 0) - d->codec = NULL; + if (id == AV_CODEC_ID_VP8 || id == AV_CODEC_ID_VP9) { + AVDictionaryEntry *tag = NULL; + tag = av_dict_get(stream->metadata, "alpha_mode", tag, + AV_DICT_IGNORE_SUFFIX); + + if (tag && strcmp(tag->value, "1") == 0) { + char *codec = (id == AV_CODEC_ID_VP8) ? "libvpx" + : "libvpx-vp9"; + d->codec = avcodec_find_decoder_by_name(codec); } } + if (!d->codec) + d->codec = avcodec_find_decoder(id); + if (!d->codec) { - if (id == AV_CODEC_ID_VP8) - d->codec = avcodec_find_decoder_by_name("libvpx"); - else if (id == AV_CODEC_ID_VP9) - d->codec = avcodec_find_decoder_by_name("libvpx-vp9"); - - if (!d->codec) - d->codec = avcodec_find_decoder(id); - if (!d->codec) { - blog(LOG_WARNING, "MP: Failed to find %s codec", - av_get_media_type_string(type)); - return false; - } - - ret = mp_open_codec(d); - if (ret < 0) { - blog(LOG_WARNING, "MP: Failed to open %s decoder: %s", - av_get_media_type_string(type), - av_err2str(ret)); - return false; - } + blog(LOG_WARNING, "MP: Failed to find %s codec", + av_get_media_type_string(type)); + return false; } - d->frame = av_frame_alloc(); - if (!d->frame) { - blog(LOG_WARNING, "MP: Failed to allocate %s frame", - av_get_media_type_string(type)); + ret = mp_open_codec(d, hw); + if (ret < 0) { + blog(LOG_WARNING, "MP: Failed to open %s decoder: %s", + av_get_media_type_string(type), av_err2str(ret)); return false; } + d->sw_frame = av_frame_alloc(); + if (!d->sw_frame) { + blog(LOG_WARNING, "MP: Failed to allocate %s frame", + av_get_media_type_string(type)); + return false; + } + + if (d->hw) { + d->hw_frame = av_frame_alloc(); + if (!d->hw_frame) { + blog(LOG_WARNING, "MP: Failed to allocate %s hw frame", + av_get_media_type_string(type)); + return false; + } + + d->in_frame = d->hw_frame; + } else { + d->in_frame = d->sw_frame; + } + if (d->codec->capabilities & CODEC_CAP_TRUNC) d->decoder->flags |= CODEC_FLAG_TRUNC; return true; @@ -166,6 +213,10 @@ void mp_decode_free(struct mp_decode *d) mp_decode_clear_packets(d); circlebuf_free(&d->packets); + if (d->hw_frame) { + av_frame_unref(d->hw_frame); + av_free(d->hw_frame); + } if (d->decoder) { #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 40, 101) avcodec_free_context(&d->decoder); @@ -173,11 +224,17 @@ void mp_decode_free(struct mp_decode *d) avcodec_close(d->decoder); #endif } - if (d->frame) { - av_frame_unref(d->frame); - av_free(d->frame); + if (d->sw_frame) { + av_frame_unref(d->sw_frame); + av_free(d->sw_frame); } +#ifdef USE_NEW_HARDWARE_CODEC_METHOD + if (d->hw_ctx) { + av_buffer_unref(&d->hw_ctx); + } +#endif + memset(d, 0, sizeof(*d)); } @@ -187,22 +244,22 @@ void mp_decode_push_packet(struct mp_decode *decode, AVPacket *packet) } static inline int64_t get_estimated_duration(struct mp_decode *d, - int64_t last_pts) + int64_t last_pts) { if (last_pts) return d->frame_pts - last_pts; if (d->audio) { - return av_rescale_q(d->frame->nb_samples, - (AVRational){1, d->frame->sample_rate}, - (AVRational){1, 1000000000}); + return av_rescale_q(d->in_frame->nb_samples, + (AVRational){1, d->in_frame->sample_rate}, + (AVRational){1, 1000000000}); } else { if (d->last_duration) return d->last_duration; return av_rescale_q(d->decoder->time_base.num, - d->decoder->time_base, - (AVRational){1, 1000000000}); + d->decoder->time_base, + (AVRational){1, 1000000000}); } } @@ -212,7 +269,7 @@ static int decode_packet(struct mp_decode *d, int *got_frame) *got_frame = 0; #ifdef USE_NEW_FFMPEG_DECODE_API - ret = avcodec_receive_frame(d->decoder, d->frame); + ret = avcodec_receive_frame(d->decoder, d->in_frame); if (ret != 0 && ret != AVERROR(EAGAIN)) { if (ret == AVERROR_EOF) ret = 0; @@ -227,7 +284,7 @@ static int decode_packet(struct mp_decode *d, int *got_frame) return ret; } - ret = avcodec_receive_frame(d->decoder, d->frame); + ret = avcodec_receive_frame(d->decoder, d->in_frame); if (ret != 0 && ret != AVERROR(EAGAIN)) { if (ret == AVERROR_EOF) ret = 0; @@ -243,13 +300,30 @@ static int decode_packet(struct mp_decode *d, int *got_frame) #else if (d->audio) { - ret = avcodec_decode_audio4(d->decoder, - d->frame, got_frame, &d->pkt); + ret = avcodec_decode_audio4(d->decoder, d->in_frame, got_frame, + &d->pkt); } else { - ret = avcodec_decode_video2(d->decoder, - d->frame, got_frame, &d->pkt); + ret = avcodec_decode_video2(d->decoder, d->in_frame, got_frame, + &d->pkt); } #endif + +#ifdef USE_NEW_HARDWARE_CODEC_METHOD + if (*got_frame && d->hw) { + if (d->hw_frame->format != d->hw_format) { + d->frame = d->hw_frame; + return ret; + } + + int err = av_hwframe_transfer_data(d->sw_frame, d->hw_frame, 0); + if (err != 0) { + ret = 0; + *got_frame = false; + } + } +#endif + + d->frame = d->sw_frame; return ret; } @@ -275,7 +349,7 @@ bool mp_decode_next(struct mp_decode *d) } } else { circlebuf_pop_front(&d->packets, &d->orig_pkt, - sizeof(d->orig_pkt)); + sizeof(d->orig_pkt)); d->pkt = d->orig_pkt; d->packet_pending = true; } @@ -290,7 +364,7 @@ bool mp_decode_next(struct mp_decode *d) if (ret < 0) { #ifdef DETAILED_DEBUG_INFO blog(LOG_DEBUG, "MP: decode failed: %s", - av_err2str(ret)); + av_err2str(ret)); #endif if (d->packet_pending) { @@ -322,29 +396,28 @@ bool mp_decode_next(struct mp_decode *d) if (d->frame_ready) { int64_t last_pts = d->frame_pts; - if (d->frame->best_effort_timestamp == AV_NOPTS_VALUE) + if (d->in_frame->best_effort_timestamp == AV_NOPTS_VALUE) d->frame_pts = d->next_pts; else - d->frame_pts = av_rescale_q( - d->frame->best_effort_timestamp, - d->stream->time_base, - (AVRational){1, 1000000000}); + d->frame_pts = + av_rescale_q(d->in_frame->best_effort_timestamp, + d->stream->time_base, + (AVRational){1, 1000000000}); - int64_t duration = d->frame->pkt_duration; + int64_t duration = d->in_frame->pkt_duration; if (!duration) duration = get_estimated_duration(d, last_pts); else - duration = av_rescale_q(duration, - d->stream->time_base, - (AVRational){1, 1000000000}); + duration = av_rescale_q(duration, d->stream->time_base, + (AVRational){1, 1000000000}); if (d->m->speed != 100) { - d->frame_pts = av_rescale_q(d->frame_pts, - (AVRational){1, d->m->speed}, - (AVRational){1, 100}); + d->frame_pts = av_rescale_q( + d->frame_pts, (AVRational){1, d->m->speed}, + (AVRational){1, 100}); duration = av_rescale_q(duration, - (AVRational){1, d->m->speed}, - (AVRational){1, 100}); + (AVRational){1, d->m->speed}, + (AVRational){1, 100}); } d->last_duration = duration; diff --git a/deps/media-playback/media-playback/decode.h b/deps/media-playback/media-playback/decode.h index f596485..9f2fd3c 100644 --- a/deps/media-playback/media-playback/decode.h +++ b/deps/media-playback/media-playback/decode.h @@ -53,29 +53,35 @@ extern "C" { struct mp_media; struct mp_decode { - struct mp_media *m; - AVStream *stream; - bool audio; + struct mp_media *m; + AVStream *stream; + bool audio; - AVCodecContext *decoder; - AVCodec *codec; + AVCodecContext *decoder; + AVBufferRef *hw_ctx; + AVCodec *codec; - int64_t last_duration; - int64_t frame_pts; - int64_t next_pts; - AVFrame *frame; - bool got_first_keyframe; - bool frame_ready; - bool eof; + int64_t last_duration; + int64_t frame_pts; + int64_t next_pts; + AVFrame *in_frame; + AVFrame *sw_frame; + AVFrame *hw_frame; + AVFrame *frame; + enum AVPixelFormat hw_format; + bool got_first_keyframe; + bool frame_ready; + bool eof; + bool hw; - AVPacket orig_pkt; - AVPacket pkt; - bool packet_pending; - struct circlebuf packets; + AVPacket orig_pkt; + AVPacket pkt; + bool packet_pending; + struct circlebuf packets; }; extern bool mp_decode_init(struct mp_media *media, enum AVMediaType type, - bool hw); + bool hw); extern void mp_decode_free(struct mp_decode *decode); extern void mp_decode_clear_packets(struct mp_decode *decode); diff --git a/deps/media-playback/media-playback/media.c b/deps/media-playback/media-playback/media.c index 426380d..35554eb 100644 --- a/deps/media-playback/media-playback/media.c +++ b/deps/media-playback/media-playback/media.c @@ -30,15 +30,30 @@ static int64_t base_sys_ts = 0; static inline enum video_format convert_pixel_format(int f) { switch (f) { - case AV_PIX_FMT_NONE: return VIDEO_FORMAT_NONE; - case AV_PIX_FMT_YUV420P: return VIDEO_FORMAT_I420; - case AV_PIX_FMT_NV12: return VIDEO_FORMAT_NV12; - case AV_PIX_FMT_YUYV422: return VIDEO_FORMAT_YUY2; - case AV_PIX_FMT_YUV444P: return VIDEO_FORMAT_I444; - case AV_PIX_FMT_UYVY422: return VIDEO_FORMAT_UYVY; - case AV_PIX_FMT_RGBA: return VIDEO_FORMAT_RGBA; - case AV_PIX_FMT_BGRA: return VIDEO_FORMAT_BGRA; - case AV_PIX_FMT_BGR0: return VIDEO_FORMAT_BGRX; + case AV_PIX_FMT_NONE: + return VIDEO_FORMAT_NONE; + case AV_PIX_FMT_YUV420P: + return VIDEO_FORMAT_I420; + case AV_PIX_FMT_NV12: + return VIDEO_FORMAT_NV12; + case AV_PIX_FMT_YUYV422: + return VIDEO_FORMAT_YUY2; + case AV_PIX_FMT_YUV444P: + return VIDEO_FORMAT_I444; + case AV_PIX_FMT_UYVY422: + return VIDEO_FORMAT_UYVY; + case AV_PIX_FMT_RGBA: + return VIDEO_FORMAT_RGBA; + case AV_PIX_FMT_BGRA: + return VIDEO_FORMAT_BGRA; + case AV_PIX_FMT_BGR0: + return VIDEO_FORMAT_BGRX; + case AV_PIX_FMT_YUVA420P: + return VIDEO_FORMAT_I40A; + case AV_PIX_FMT_YUVA422P: + return VIDEO_FORMAT_I42A; + case AV_PIX_FMT_YUVA444P: + return VIDEO_FORMAT_YUVA; default:; } @@ -48,14 +63,22 @@ static inline enum video_format convert_pixel_format(int f) static inline enum audio_format convert_sample_format(int f) { switch (f) { - case AV_SAMPLE_FMT_U8: return AUDIO_FORMAT_U8BIT; - case AV_SAMPLE_FMT_S16: return AUDIO_FORMAT_16BIT; - case AV_SAMPLE_FMT_S32: return AUDIO_FORMAT_32BIT; - case AV_SAMPLE_FMT_FLT: return AUDIO_FORMAT_FLOAT; - case AV_SAMPLE_FMT_U8P: return AUDIO_FORMAT_U8BIT_PLANAR; - case AV_SAMPLE_FMT_S16P: return AUDIO_FORMAT_16BIT_PLANAR; - case AV_SAMPLE_FMT_S32P: return AUDIO_FORMAT_32BIT_PLANAR; - case AV_SAMPLE_FMT_FLTP: return AUDIO_FORMAT_FLOAT_PLANAR; + case AV_SAMPLE_FMT_U8: + return AUDIO_FORMAT_U8BIT; + case AV_SAMPLE_FMT_S16: + return AUDIO_FORMAT_16BIT; + case AV_SAMPLE_FMT_S32: + return AUDIO_FORMAT_32BIT; + case AV_SAMPLE_FMT_FLT: + return AUDIO_FORMAT_FLOAT; + case AV_SAMPLE_FMT_U8P: + return AUDIO_FORMAT_U8BIT_PLANAR; + case AV_SAMPLE_FMT_S16P: + return AUDIO_FORMAT_16BIT_PLANAR; + case AV_SAMPLE_FMT_S32P: + return AUDIO_FORMAT_32BIT_PLANAR; + case AV_SAMPLE_FMT_FLTP: + return AUDIO_FORMAT_FLOAT_PLANAR; default:; } @@ -65,15 +88,24 @@ static inline enum audio_format convert_sample_format(int f) static inline enum speaker_layout convert_speaker_layout(uint8_t channels) { switch (channels) { - case 0: return SPEAKERS_UNKNOWN; - case 1: return SPEAKERS_MONO; - case 2: return SPEAKERS_STEREO; - case 3: return SPEAKERS_2POINT1; - case 4: return SPEAKERS_4POINT0; - case 5: return SPEAKERS_4POINT1; - case 6: return SPEAKERS_5POINT1; - case 8: return SPEAKERS_7POINT1; - default: return SPEAKERS_UNKNOWN; + case 0: + return SPEAKERS_UNKNOWN; + case 1: + return SPEAKERS_MONO; + case 2: + return SPEAKERS_STEREO; + case 3: + return SPEAKERS_2POINT1; + case 4: + return SPEAKERS_4POINT0; + case 5: + return SPEAKERS_4POINT1; + case 6: + return SPEAKERS_5POINT1; + case 8: + return SPEAKERS_7POINT1; + default: + return SPEAKERS_UNKNOWN; } } @@ -88,7 +120,7 @@ static inline enum video_range_type convert_color_range(enum AVColorRange r) } static inline struct mp_decode *get_packet_decoder(mp_media_t *media, - AVPacket *pkt) + AVPacket *pkt) { if (media->has_audio && pkt->stream_index == media->a.stream->index) return &media->a; @@ -109,7 +141,7 @@ static int mp_media_next_packet(mp_media_t *media) if (ret < 0) { if (ret != AVERROR_EOF) blog(LOG_WARNING, "MP: av_read_frame failed: %s (%d)", - av_err2str(ret), ret); + av_err2str(ret), ret); return ret; } @@ -160,7 +192,7 @@ static inline int get_sws_range(enum AVColorRange r) return r == AVCOL_RANGE_JPEG ? 1 : 0; } -#define FIXED_1_0 (1<<16) +#define FIXED_1_0 (1 << 16) static bool mp_media_init_scaling(mp_media_t *m) { @@ -168,23 +200,23 @@ static bool mp_media_init_scaling(mp_media_t *m) int range = get_sws_range(m->v.decoder->color_range); const int *coeff = sws_getCoefficients(space); - m->swscale = sws_getCachedContext(NULL, - m->v.decoder->width, m->v.decoder->height, - m->v.decoder->pix_fmt, - m->v.decoder->width, m->v.decoder->height, - m->scale_format, - SWS_FAST_BILINEAR, NULL, NULL, NULL); + m->swscale = sws_getCachedContext(NULL, m->v.decoder->width, + m->v.decoder->height, + m->v.decoder->pix_fmt, + m->v.decoder->width, + m->v.decoder->height, m->scale_format, + SWS_FAST_BILINEAR, NULL, NULL, NULL); if (!m->swscale) { blog(LOG_WARNING, "MP: Failed to initialize scaler"); return false; } sws_setColorspaceDetails(m->swscale, coeff, range, coeff, range, 0, - FIXED_1_0, FIXED_1_0); + FIXED_1_0, FIXED_1_0); int ret = av_image_alloc(m->scale_pic, m->scale_linesizes, - m->v.decoder->width, m->v.decoder->height, - m->scale_format, 1); + m->v.decoder->width, m->v.decoder->height, + m->scale_format, 1); if (ret < 0) { blog(LOG_WARNING, "MP: Failed to create scale pic data"); return false; @@ -250,8 +282,7 @@ static inline int64_t mp_media_get_base_pts(mp_media_t *m) return base_ts; } -static inline bool mp_media_can_play_frame(mp_media_t *m, - struct mp_decode *d) +static inline bool mp_media_can_play_frame(mp_media_t *m, struct mp_decode *d) { return d->frame_ready && d->frame_pts <= m->next_pts_ns; } @@ -277,7 +308,7 @@ static void mp_media_next_audio(mp_media_t *m) audio.format = convert_sample_format(f->format); audio.frames = f->nb_samples; audio.timestamp = m->base_ts + d->frame_pts - m->start_ts + - m->play_sys_ts - base_sys_ts; + m->play_sys_ts - base_sys_ts; if (audio.format == AUDIO_FORMAT_UNKNOWN) return; @@ -308,10 +339,9 @@ static void mp_media_next_video(mp_media_t *m, bool preload) bool flip = false; if (m->swscale) { - int ret = sws_scale(m->swscale, - (const uint8_t *const *)f->data, f->linesize, - 0, f->height, - m->scale_pic, m->scale_linesizes); + int ret = sws_scale(m->swscale, (const uint8_t *const *)f->data, + f->linesize, 0, f->height, m->scale_pic, + m->scale_linesizes); if (ret < 0) return; @@ -334,25 +364,22 @@ static void mp_media_next_video(mp_media_t *m, bool preload) frame->data[0] -= frame->linesize[0] * (f->height - 1); new_format = convert_pixel_format(m->scale_format); - new_space = convert_color_space(f->colorspace); - new_range = m->force_range == VIDEO_RANGE_DEFAULT - ? convert_color_range(f->color_range) - : m->force_range; + new_space = convert_color_space(f->colorspace); + new_range = m->force_range == VIDEO_RANGE_DEFAULT + ? convert_color_range(f->color_range) + : m->force_range; - if (new_format != frame->format || - new_space != m->cur_space || - new_range != m->cur_range) { + if (new_format != frame->format || new_space != m->cur_space || + new_range != m->cur_range) { bool success; frame->format = new_format; frame->full_range = new_range == VIDEO_RANGE_FULL; - success = video_format_get_parameters( - new_space, - new_range, - frame->color_matrix, - frame->color_range_min, - frame->color_range_max); + success = video_format_get_parameters(new_space, new_range, + frame->color_matrix, + frame->color_range_min, + frame->color_range_max); frame->format = new_format; m->cur_space = new_space; @@ -368,7 +395,7 @@ static void mp_media_next_video(mp_media_t *m, bool preload) return; frame->timestamp = m->base_ts + d->frame_pts - m->start_ts + - m->play_sys_ts - base_sys_ts; + m->play_sys_ts - base_sys_ts; frame->width = f->width; frame->height = f->height; frame->flip = flip; @@ -420,14 +447,15 @@ static bool mp_media_reset(mp_media_t *m) } int64_t seek_target = seek_flags == AVSEEK_FLAG_BACKWARD - ? av_rescale_q(seek_pos, AV_TIME_BASE_Q, stream->time_base) - : seek_pos; + ? av_rescale_q(seek_pos, AV_TIME_BASE_Q, + stream->time_base) + : seek_pos; if (m->is_local_file) { int ret = av_seek_frame(m->fmt, 0, seek_target, seek_flags); if (ret < 0) { blog(LOG_WARNING, "MP: Failed to seek: %s", - av_err2str(ret)); + av_err2str(ret)); } } @@ -538,8 +566,10 @@ static bool init_avformat(mp_media_t *m) if (m->format_name && *m->format_name) { format = av_find_input_format(m->format_name); if (!format) - blog(LOG_INFO, "MP: Unable to find input format for " - "'%s'", m->path); + blog(LOG_INFO, + "MP: Unable to find input format for " + "'%s'", + m->path); } AVDictionary *opts = NULL; @@ -551,7 +581,7 @@ static bool init_avformat(mp_media_t *m) m->fmt->interrupt_callback.opaque = m; int ret = avformat_open_input(&m->fmt, m->path, format, - opts ? &opts : NULL); + opts ? &opts : NULL); av_dict_free(&opts); if (ret < 0) { @@ -561,7 +591,7 @@ static bool init_avformat(mp_media_t *m) if (avformat_find_stream_info(m->fmt, NULL) < 0) { blog(LOG_WARNING, "MP: Failed to find stream info for '%s'", - m->path); + m->path); return false; } @@ -569,8 +599,10 @@ static bool init_avformat(mp_media_t *m) m->has_audio = mp_decode_init(m, AVMEDIA_TYPE_AUDIO, m->hw); if (!m->has_video && !m->has_audio) { - blog(LOG_WARNING, "MP: Could not initialize audio or video: " - "'%s'", m->path); + blog(LOG_WARNING, + "MP: Could not initialize audio or video: " + "'%s'", + m->path); return false; } @@ -653,7 +685,7 @@ static void *mp_media_thread_start(void *opaque) } static inline bool mp_media_init_internal(mp_media_t *m, - const struct mp_media_info *info) + const struct mp_media_info *info) { if (pthread_mutex_init(&m->mutex, NULL) != 0) { blog(LOG_WARNING, "MP: Failed to init mutex"); @@ -696,9 +728,11 @@ bool mp_media_init(mp_media_t *media, const struct mp_media_info *info) static bool initialized = false; if (!initialized) { +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) av_register_all(); - avdevice_register_all(); avcodec_register_all(); +#endif + avdevice_register_all(); avformat_network_init(); initialized = true; } diff --git a/deps/obs-scripting/obs-scripting-callback.h b/deps/obs-scripting/obs-scripting-callback.h index ee317f3..81c5fb7 100644 --- a/deps/obs-scripting/obs-scripting-callback.h +++ b/deps/obs-scripting/obs-scripting-callback.h @@ -36,10 +36,8 @@ struct script_callback { bool removed; }; -static inline void *add_script_callback( - struct script_callback **first, - obs_script_t *script, - size_t extra_size) +static inline void *add_script_callback(struct script_callback **first, + obs_script_t *script, size_t extra_size) { struct script_callback *cb = bzalloc(sizeof(*cb) + extra_size); cb->script = script; @@ -47,7 +45,8 @@ static inline void *add_script_callback( struct script_callback *next = *first; cb->next = next; cb->p_prev_next = first; - if (next) next->p_prev_next = &cb->next; + if (next) + next->p_prev_next = &cb->next; *first = cb; return cb; @@ -58,13 +57,15 @@ static inline void remove_script_callback(struct script_callback *cb) cb->removed = true; struct script_callback *next = cb->next; - if (next) next->p_prev_next = cb->p_prev_next; + if (next) + next->p_prev_next = cb->p_prev_next; *cb->p_prev_next = cb->next; pthread_mutex_lock(&detach_mutex); next = detached_callbacks; cb->next = next; - if (next) next->p_prev_next = &cb->next; + if (next) + next->p_prev_next = &cb->next; cb->p_prev_next = &detached_callbacks; detached_callbacks = cb; pthread_mutex_unlock(&detach_mutex); @@ -83,7 +84,8 @@ static inline void free_script_callback(struct script_callback *cb) { pthread_mutex_lock(&detach_mutex); struct script_callback *next = cb->next; - if (next) next->p_prev_next = cb->p_prev_next; + if (next) + next->p_prev_next = cb->p_prev_next; *cb->p_prev_next = cb->next; pthread_mutex_unlock(&detach_mutex); diff --git a/deps/obs-scripting/obs-scripting-internal.h b/deps/obs-scripting/obs-scripting-internal.h index dade53a..89fe2fd 100644 --- a/deps/obs-scripting/obs-scripting-internal.h +++ b/deps/obs-scripting/obs-scripting-internal.h @@ -37,9 +37,10 @@ typedef void (*defer_call_cb)(void *param); extern void defer_call_post(defer_call_cb call, void *cb); -extern void script_log(obs_script_t *script, int level, const char *format, ...); +extern void script_log(obs_script_t *script, int level, const char *format, + ...); extern void script_log_va(obs_script_t *script, int level, const char *format, - va_list args); + va_list args); #define script_error(script, format, ...) \ script_log(script, LOG_ERROR, format, ##__VA_ARGS__) diff --git a/deps/obs-scripting/obs-scripting-logging.c b/deps/obs-scripting/obs-scripting-logging.c index ebae79d..97406c3 100644 --- a/deps/obs-scripting/obs-scripting-logging.c +++ b/deps/obs-scripting/obs-scripting-logging.c @@ -22,7 +22,7 @@ static scripting_log_handler_t callback = NULL; static void *param = NULL; void script_log_va(obs_script_t *script, int level, const char *format, - va_list args) + va_list args) { char msg[2048]; const char *lang = "(Unknown)"; @@ -30,13 +30,19 @@ void script_log_va(obs_script_t *script, int level, const char *format, if (script) { switch (script->type) { - case OBS_SCRIPT_LANG_UNKNOWN: lang = "(Unknown language)"; break; - case OBS_SCRIPT_LANG_LUA: lang = "Lua"; break; - case OBS_SCRIPT_LANG_PYTHON: lang = "Python"; break; + case OBS_SCRIPT_LANG_UNKNOWN: + lang = "(Unknown language)"; + break; + case OBS_SCRIPT_LANG_LUA: + lang = "Lua"; + break; + case OBS_SCRIPT_LANG_PYTHON: + lang = "Python"; + break; } - start_len = snprintf(msg, sizeof(msg), "[%s: %s] ", - lang, script->file.array); + start_len = snprintf(msg, sizeof(msg), "[%s: %s] ", lang, + script->file.array); } else { start_len = snprintf(msg, sizeof(msg), "[Unknown Script] "); } @@ -57,7 +63,7 @@ void script_log(obs_script_t *script, int level, const char *format, ...) } void obs_scripting_set_log_callback(scripting_log_handler_t handler, - void *log_param) + void *log_param) { callback = handler; param = log_param; diff --git a/deps/obs-scripting/obs-scripting-lua-frontend.c b/deps/obs-scripting/obs-scripting-lua-frontend.c index 1053461..7175962 100644 --- a/deps/obs-scripting/obs-scripting-lua-frontend.c +++ b/deps/obs-scripting/obs-scripting-lua-frontend.c @@ -20,12 +20,12 @@ #include "obs-scripting-lua.h" -#define ls_get_libobs_obj(type, lua_index, obs_obj) \ - ls_get_libobs_obj_(script, #type " *", lua_index, obs_obj, \ - NULL, __FUNCTION__, __LINE__) -#define ls_push_libobs_obj(type, obs_obj, ownership) \ - ls_push_libobs_obj_(script, #type " *", obs_obj, ownership, \ - NULL, __FUNCTION__, __LINE__) +#define ls_get_libobs_obj(type, lua_index, obs_obj) \ + ls_get_libobs_obj_(script, #type " *", lua_index, obs_obj, NULL, \ + __FUNCTION__, __LINE__) +#define ls_push_libobs_obj(type, obs_obj, ownership) \ + ls_push_libobs_obj_(script, #type " *", obs_obj, ownership, NULL, \ + __FUNCTION__, __LINE__) #define call_func(func, args, rets) \ call_func_(script, cb->reg_idx, args, rets, #func, "frontend API") @@ -191,7 +191,7 @@ static void frontend_event_callback(enum obs_frontend_event event, void *priv) lua_State *script = cb->script; if (cb->base.removed) { - obs_frontend_remove_event_callback(frontend_event_callback, cb); + obs_frontend_remove_event_callback(frontend_event_callback, cb); return; } @@ -233,7 +233,7 @@ static int add_event_callback(lua_State *script) /* ----------------------------------- */ static void frontend_save_callback(obs_data_t *save_data, bool saving, - void *priv) + void *priv) { struct lua_obs_callback *cb = priv; lua_State *script = cb->script; @@ -285,11 +285,11 @@ void add_lua_frontend_funcs(lua_State *script) { lua_getglobal(script, "obslua"); -#define add_func(name) \ - do { \ +#define add_func(name) \ + do { \ lua_pushstring(script, "obs_frontend_" #name); \ - lua_pushcfunction(script, name); \ - lua_rawset(script, -3); \ + lua_pushcfunction(script, name); \ + lua_rawset(script, -3); \ } while (false) add_func(get_scene_names); diff --git a/deps/obs-scripting/obs-scripting-lua-source.c b/deps/obs-scripting/obs-scripting-lua-source.c index 9865c1e..cdb37dc 100644 --- a/deps/obs-scripting/obs-scripting-lua-source.c +++ b/deps/obs-scripting/obs-scripting-lua-source.c @@ -23,7 +23,7 @@ /* ========================================================================= */ static inline const char *get_table_string_(lua_State *script, int idx, - const char *name, const char *func) + const char *name, const char *func) { const char *str = ""; @@ -38,8 +38,8 @@ static inline const char *get_table_string_(lua_State *script, int idx, return str; } -static inline int get_table_int_(lua_State *script, int idx, - const char *name, const char *func) +static inline int get_table_int_(lua_State *script, int idx, const char *name, + const char *func) { int val = 0; @@ -54,7 +54,8 @@ static inline int get_table_int_(lua_State *script, int idx, } static inline void get_callback_from_table_(lua_State *script, int idx, - const char *name, int *p_reg_idx, const char *func) + const char *name, int *p_reg_idx, + const char *func) { *p_reg_idx = LUA_REFNIL; @@ -77,22 +78,14 @@ static inline void get_callback_from_table_(lua_State *script, int idx, #define get_callback_from_table(script, idx, name, p_reg_idx) \ get_callback_from_table_(script, idx, name, p_reg_idx, __FUNCTION__) -bool ls_get_libobs_obj_(lua_State * script, - const char *type, - int lua_idx, - void * libobs_out, - const char *id, - const char *func, - int line) +bool ls_get_libobs_obj_(lua_State *script, const char *type, int lua_idx, + void *libobs_out, const char *id, const char *func, + int line) { swig_type_info *info = SWIG_TypeQuery(script, type); if (info == NULL) { - warn("%s:%d: SWIG could not find type: %s%s%s", - func, - line, - id ? id : "", - id ? "::" : "", - type); + warn("%s:%d: SWIG could not find type: %s%s%s", func, line, + id ? id : "", id ? "::" : "", type); return false; } @@ -100,37 +93,25 @@ bool ls_get_libobs_obj_(lua_State * script, if (!SWIG_IsOK(ret)) { warn("%s:%d: SWIG failed to convert lua object to obs " "object: %s%s%s", - func, - line, - id ? id : "", - id ? "::" : "", - type); + func, line, id ? id : "", id ? "::" : "", type); return false; } return true; } -#define ls_get_libobs_obj(type, lua_index, obs_obj) \ - ls_get_libobs_obj_(ls->script, #type " *", lua_index, obs_obj, \ - ls->id, __FUNCTION__, __LINE__) +#define ls_get_libobs_obj(type, lua_index, obs_obj) \ + ls_get_libobs_obj_(ls->script, #type " *", lua_index, obs_obj, ls->id, \ + __FUNCTION__, __LINE__) -bool ls_push_libobs_obj_(lua_State * script, - const char *type, - void * libobs_in, - bool ownership, - const char *id, - const char *func, - int line) +bool ls_push_libobs_obj_(lua_State *script, const char *type, void *libobs_in, + bool ownership, const char *id, const char *func, + int line) { swig_type_info *info = SWIG_TypeQuery(script, type); if (info == NULL) { - warn("%s:%d: SWIG could not find type: %s%s%s", - func, - line, - id ? id : "", - id ? "::" : "", - type); + warn("%s:%d: SWIG could not find type: %s%s%s", func, line, + id ? id : "", id ? "::" : "", type); return false; } @@ -138,9 +119,9 @@ bool ls_push_libobs_obj_(lua_State * script, return true; } -#define ls_push_libobs_obj(type, obs_obj, ownership) \ +#define ls_push_libobs_obj(type, obs_obj, ownership) \ ls_push_libobs_obj_(ls->script, #type " *", obs_obj, ownership, \ - ls->id, __FUNCTION__, __LINE__) + ls->id, __FUNCTION__, __LINE__) /* ========================================================================= */ @@ -149,24 +130,24 @@ struct obs_lua_data; struct obs_lua_source { struct obs_lua_script *data; - lua_State * script; + lua_State *script; const char *id; const char *display_name; - int func_create; - int func_destroy; - int func_get_width; - int func_get_height; - int func_get_defaults; - int func_get_properties; - int func_update; - int func_activate; - int func_deactivate; - int func_show; - int func_hide; - int func_video_tick; - int func_video_render; - int func_save; - int func_load; + int func_create; + int func_destroy; + int func_get_width; + int func_get_height; + int func_get_defaults; + int func_get_properties; + int func_update; + int func_activate; + int func_deactivate; + int func_show; + int func_hide; + int func_video_tick; + int func_video_render; + int func_save; + int func_load; pthread_mutex_t definition_mutex; struct obs_lua_data *first_source; @@ -179,29 +160,27 @@ extern pthread_mutex_t lua_source_def_mutex; struct obs_lua_source *first_source_def = NULL; struct obs_lua_data { - obs_source_t * source; + obs_source_t *source; struct obs_lua_source *ls; - int lua_data_ref; + int lua_data_ref; struct obs_lua_data *next; struct obs_lua_data **p_prev_next; }; -#define call_func(name, args, rets) \ - call_func_(ls->script, ls->func_ ## name, args, rets, #name, \ - ls->display_name) -#define have_func(name) \ - (ls->func_ ## name != LUA_REFNIL) +#define call_func(name, args, rets) \ + call_func_(ls->script, ls->func_##name, args, rets, #name, \ + ls->display_name) +#define have_func(name) (ls->func_##name != LUA_REFNIL) #define ls_push_data() \ lua_rawgeti(ls->script, LUA_REGISTRYINDEX, ld->lua_data_ref) -#define ls_pop(count) \ - lua_pop(ls->script, count) -#define lock_script() \ - struct obs_lua_script *__data = ls->data; \ +#define ls_pop(count) lua_pop(ls->script, count) +#define lock_script() \ + struct obs_lua_script *__data = ls->data; \ struct obs_lua_script *__prev_script = current_lua_script; \ - current_lua_script = __data; \ + current_lua_script = __data; \ pthread_mutex_lock(&__data->mutex); -#define unlock_script() \ +#define unlock_script() \ pthread_mutex_unlock(&__data->mutex); \ current_lua_script = __prev_script; @@ -230,9 +209,9 @@ static void *obs_lua_source_create(obs_data_t *settings, obs_source_t *source) int lua_data_ref = luaL_ref(ls->script, LUA_REGISTRYINDEX); if (lua_data_ref != LUA_REFNIL) { - data = bmalloc(sizeof(*data)); - data->source = source; - data->ls = ls; + data = bmalloc(sizeof(*data)); + data->source = source; + data->ls = ls; data->lua_data_ref = lua_data_ref; } @@ -242,7 +221,8 @@ static void *obs_lua_source_create(obs_data_t *settings, obs_source_t *source) struct obs_lua_data *next = ls->first_source; data->next = next; data->p_prev_next = &ls->first_source; - if (next) next->p_prev_next = &data->next; + if (next) + next->p_prev_next = &data->next; ls->first_source = data; } @@ -263,9 +243,9 @@ static void call_destroy(struct obs_lua_data *ld) static void obs_lua_source_destroy(void *data) { - struct obs_lua_data * ld = data; + struct obs_lua_data *ld = data; struct obs_lua_source *ls = ld->ls; - struct obs_lua_data * next; + struct obs_lua_data *next; pthread_mutex_lock(&ls->definition_mutex); if (!ls->script) @@ -280,7 +260,8 @@ static void obs_lua_source_destroy(void *data) fail: next = ld->next; *ld->p_prev_next = next; - if (next) next->p_prev_next = ld->p_prev_next; + if (next) + next->p_prev_next = ld->p_prev_next; bfree(data); pthread_mutex_unlock(&ls->definition_mutex); @@ -288,9 +269,9 @@ fail: static uint32_t obs_lua_source_get_width(void *data) { - struct obs_lua_data * ld = data; - struct obs_lua_source *ls = ld->ls; - uint32_t width = 0; + struct obs_lua_data *ld = data; + struct obs_lua_source *ls = ld->ls; + uint32_t width = 0; pthread_mutex_lock(&ls->definition_mutex); if (!ls->script) @@ -315,9 +296,9 @@ fail: static uint32_t obs_lua_source_get_height(void *data) { - struct obs_lua_data * ld = data; - struct obs_lua_source *ls = ld->ls; - uint32_t height = 0; + struct obs_lua_data *ld = data; + struct obs_lua_source *ls = ld->ls; + uint32_t height = 0; pthread_mutex_lock(&ls->definition_mutex); if (!ls->script) @@ -363,9 +344,9 @@ fail: static obs_properties_t *obs_lua_source_get_properties(void *data) { - struct obs_lua_data * ld = data; - struct obs_lua_source *ls = ld->ls; - obs_properties_t * props = NULL; + struct obs_lua_data *ld = data; + struct obs_lua_source *ls = ld->ls; + obs_properties_t *props = NULL; pthread_mutex_lock(&ls->definition_mutex); if (!ls->script) @@ -390,7 +371,7 @@ fail: static void obs_lua_source_update(void *data, obs_data_t *settings) { - struct obs_lua_data * ld = data; + struct obs_lua_data *ld = data; struct obs_lua_source *ls = ld->ls; pthread_mutex_lock(&ls->definition_mutex); @@ -411,17 +392,17 @@ fail: pthread_mutex_unlock(&ls->definition_mutex); } -#define DEFINE_VOID_DATA_CALLBACK(name) \ - static void obs_lua_source_ ## name(void *data) \ - { \ - struct obs_lua_data * ld = data; \ - struct obs_lua_source *ls = ld->ls; \ - if (!have_func(name)) \ - return; \ - lock_script(); \ - ls_push_data(); \ - call_func(name, 1, 0); \ - unlock_script(); \ +#define DEFINE_VOID_DATA_CALLBACK(name) \ + static void obs_lua_source_##name(void *data) \ + { \ + struct obs_lua_data *ld = data; \ + struct obs_lua_source *ls = ld->ls; \ + if (!have_func(name)) \ + return; \ + lock_script(); \ + ls_push_data(); \ + call_func(name, 1, 0); \ + unlock_script(); \ } DEFINE_VOID_DATA_CALLBACK(activate) DEFINE_VOID_DATA_CALLBACK(deactivate) @@ -431,7 +412,7 @@ DEFINE_VOID_DATA_CALLBACK(hide) static void obs_lua_source_video_tick(void *data, float seconds) { - struct obs_lua_data * ld = data; + struct obs_lua_data *ld = data; struct obs_lua_source *ls = ld->ls; pthread_mutex_lock(&ls->definition_mutex); @@ -454,7 +435,7 @@ fail: static void obs_lua_source_video_render(void *data, gs_effect_t *effect) { - struct obs_lua_data * ld = data; + struct obs_lua_data *ld = data; struct obs_lua_source *ls = ld->ls; pthread_mutex_lock(&ls->definition_mutex); @@ -477,7 +458,7 @@ fail: static void obs_lua_source_save(void *data, obs_data_t *settings) { - struct obs_lua_data * ld = data; + struct obs_lua_data *ld = data; struct obs_lua_source *ls = ld->ls; pthread_mutex_lock(&ls->definition_mutex); @@ -500,7 +481,7 @@ fail: static void obs_lua_source_load(void *data, obs_data_t *settings) { - struct obs_lua_data * ld = data; + struct obs_lua_data *ld = data; struct obs_lua_source *ls = ld->ls; pthread_mutex_lock(&ls->definition_mutex); @@ -523,7 +504,7 @@ fail: static void source_type_unload(struct obs_lua_source *ls) { -#define unref(name) \ +#define unref(name) \ luaL_unref(ls->script, LUA_REGISTRYINDEX, name); \ name = LUA_REFNIL @@ -614,9 +595,9 @@ static int obs_lua_register_source(lua_State *script) v = existing ? existing : &ls; v->script = script; - v->id = id; + v->id = id; - info.id = v->id; + info.id = v->id; info.type = (enum obs_source_type)get_table_int(script, -1, "type"); info.output_flags = get_table_int(script, -1, "output_flags"); @@ -628,16 +609,14 @@ static int obs_lua_register_source(lua_State *script) lua_pop(script, 1); } - if (!v->display_name || - !*v->display_name || - !*info.id || + if (!v->display_name || !*v->display_name || !*info.id || !info.output_flags) goto fail; -#define get_callback(val) \ - do { \ - get_callback_from_table(script, -1, #val, &v->func_ ## val); \ - info.val = obs_lua_source_ ## val; \ +#define get_callback(val) \ + do { \ + get_callback_from_table(script, -1, #val, &v->func_##val); \ + info.val = obs_lua_source_##val; \ } while (false) get_callback(create); @@ -657,16 +636,21 @@ static int obs_lua_register_source(lua_State *script) #undef get_callback get_callback_from_table(script, -1, "get_defaults", - &v->func_get_defaults); + &v->func_get_defaults); if (!existing) { ls.data = current_lua_script; - pthread_mutex_init(&ls.definition_mutex, NULL); - info.type_data = bmemdup(&ls, sizeof(ls)); + pthread_mutexattr_t mutexattr; + pthread_mutexattr_init(&mutexattr); + pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&ls.definition_mutex, &mutexattr); + pthread_mutexattr_destroy(&mutexattr); + + info.type_data = bmemdup(&ls, sizeof(ls)); info.free_type_data = obs_lua_source_free_type_data; - info.get_name = obs_lua_source_get_name; - info.get_defaults2 = obs_lua_source_get_defaults; + info.get_name = obs_lua_source_get_name; + info.get_defaults2 = obs_lua_source_get_defaults; obs_register_source(&info); pthread_mutex_lock(&lua_source_def_mutex); @@ -674,7 +658,8 @@ static int obs_lua_register_source(lua_State *script) struct obs_lua_source *next = first_source_def; v->next = next; - if (next) next->p_prev_next = &v->next; + if (next) + next->p_prev_next = &v->next; v->p_prev_next = &first_source_def; first_source_def = v; @@ -690,15 +675,15 @@ static int obs_lua_register_source(lua_State *script) if (have_func(create)) { obs_source_t *source = ld->source; - obs_data_t *settings = obs_source_get_settings( - source); + obs_data_t *settings = + obs_source_get_settings(source); ls_push_libobs_obj(obs_data_t, settings, false); ls_push_libobs_obj(obs_source_t, source, false); call_func(create, 2, 1); - ld->lua_data_ref = luaL_ref(ls->script, - LUA_REGISTRYINDEX); + ld->lua_data_ref = + luaL_ref(ls->script, LUA_REGISTRYINDEX); obs_data_release(settings); } @@ -727,7 +712,7 @@ void add_lua_source_functions(lua_State *script) } static inline void undef_source_type(struct obs_lua_script *data, - struct obs_lua_source *ls) + struct obs_lua_source *ls) { pthread_mutex_lock(&ls->definition_mutex); pthread_mutex_lock(&data->mutex); diff --git a/deps/obs-scripting/obs-scripting-lua.c b/deps/obs-scripting/obs-scripting-lua.c index 5743e0f..a626555 100644 --- a/deps/obs-scripting/obs-scripting-lua.c +++ b/deps/obs-scripting/obs-scripting-lua.c @@ -26,17 +26,17 @@ /* ========================================================================= */ #if ARCH_BITS == 64 -# define ARCH_DIR "64bit" +#define ARCH_DIR "64bit" #else -# define ARCH_DIR "32bit" +#define ARCH_DIR "32bit" #endif #ifdef __APPLE__ -# define SO_EXT "dylib" +#define SO_EXT "dylib" #elif _WIN32 -# define SO_EXT "dll" +#define SO_EXT "dll" #else -# define SO_EXT "so" +#define SO_EXT "so" #endif static const char *startup_script_template = "\ @@ -59,15 +59,14 @@ static struct obs_lua_script *first_tick_script = NULL; pthread_mutex_t lua_source_def_mutex = PTHREAD_MUTEX_INITIALIZER; -#define ls_get_libobs_obj(type, lua_index, obs_obj) \ - ls_get_libobs_obj_(script, #type " *", lua_index, obs_obj, \ - NULL, __FUNCTION__, __LINE__) -#define ls_push_libobs_obj(type, obs_obj, ownership) \ - ls_push_libobs_obj_(script, #type " *", obs_obj, ownership, \ - NULL, __FUNCTION__, __LINE__) +#define ls_get_libobs_obj(type, lua_index, obs_obj) \ + ls_get_libobs_obj_(script, #type " *", lua_index, obs_obj, NULL, \ + __FUNCTION__, __LINE__) +#define ls_push_libobs_obj(type, obs_obj, ownership) \ + ls_push_libobs_obj_(script, #type " *", obs_obj, ownership, NULL, \ + __FUNCTION__, __LINE__) #define call_func(name, args, rets) \ - call_func_(script, cb->reg_idx, \ - args, rets, #name, __FUNCTION__) + call_func_(script, cb->reg_idx, args, rets, #name, __FUNCTION__) /* ========================================================================= */ @@ -98,7 +97,7 @@ static bool load_lua_script(struct obs_lua_script *data) if (luaL_dostring(script, startup_script) != 0) { script_warn(&data->base, "Error executing startup script 1: %s", - lua_tostring(script, -1)); + lua_tostring(script, -1)); goto fail; } @@ -108,7 +107,7 @@ static bool load_lua_script(struct obs_lua_script *data) if (ret != 0) { script_warn(&data->base, "Error executing startup script 2: %s", - lua_tostring(script, -1)); + lua_tostring(script, -1)); goto fail; } @@ -122,13 +121,13 @@ static bool load_lua_script(struct obs_lua_script *data) if (luaL_loadfile(script, data->base.path.array) != 0) { script_warn(&data->base, "Error loading file: %s", - lua_tostring(script, -1)); + lua_tostring(script, -1)); goto fail; } if (lua_pcall(script, 0, LUA_MULTRET, 0) != 0) { script_warn(&data->base, "Error running file: %s", - lua_tostring(script, -1)); + lua_tostring(script, -1)); goto fail; } @@ -148,7 +147,8 @@ static bool load_lua_script(struct obs_lua_script *data) struct obs_lua_script *next = first_tick_script; data->next_tick = next; data->p_prev_next_tick = &first_tick_script; - if (next) next->p_prev_next_tick = &data->next_tick; + if (next) + next->p_prev_next_tick = &data->next_tick; first_tick_script = data; data->tick = luaL_ref(script, LUA_REGISTRYINDEX); @@ -178,18 +178,20 @@ static bool load_lua_script(struct obs_lua_script *data) if (lua_isfunction(script, -1)) { ls_push_libobs_obj(obs_data_t, data->base.settings, false); if (lua_pcall(script, 1, 0, 0) != 0) { - script_warn(&data->base, "Error calling " - "script_defaults: %s", - lua_tostring(script, -1)); + script_warn(&data->base, + "Error calling " + "script_defaults: %s", + lua_tostring(script, -1)); } } lua_getglobal(script, "script_description"); if (lua_isfunction(script, -1)) { if (lua_pcall(script, 0, 1, 0) != 0) { - script_warn(&data->base, "Error calling " - "script_defaults: %s", - lua_tostring(script, -1)); + script_warn(&data->base, + "Error calling " + "script_defaults: %s", + lua_tostring(script, -1)); } else { const char *desc = lua_tostring(script, -1); dstr_copy(&data->base.desc, desc); @@ -200,9 +202,10 @@ static bool load_lua_script(struct obs_lua_script *data) if (lua_isfunction(script, -1)) { ls_push_libobs_obj(obs_data_t, data->base.settings, false); if (lua_pcall(script, 1, 0, 0) != 0) { - script_warn(&data->base, "Error calling " - "script_load: %s", - lua_tostring(script, -1)); + script_warn(&data->base, + "Error calling " + "script_load: %s", + lua_tostring(script, -1)); } } @@ -248,7 +251,8 @@ static inline void lua_obs_timer_init(struct lua_obs_timer *timer) struct lua_obs_timer *next = first_timer; timer->next = next; timer->p_prev_next = &first_timer; - if (next) next->p_prev_next = &timer->next; + if (next) + next->p_prev_next = &timer->next; first_timer = timer; pthread_mutex_unlock(&timer_mutex); @@ -257,12 +261,13 @@ static inline void lua_obs_timer_init(struct lua_obs_timer *timer) static inline void lua_obs_timer_remove(struct lua_obs_timer *timer) { struct lua_obs_timer *next = timer->next; - if (next) next->p_prev_next = timer->p_prev_next; + if (next) + next->p_prev_next = timer->p_prev_next; *timer->p_prev_next = timer->next; } -static inline struct lua_obs_callback *lua_obs_timer_cb( - struct lua_obs_timer *timer) +static inline struct lua_obs_callback * +lua_obs_timer_cb(struct lua_obs_timer *timer) { return &((struct lua_obs_callback *)timer)[-1]; } @@ -273,7 +278,8 @@ static int timer_remove(lua_State *script) return 0; struct lua_obs_callback *cb = find_lua_obs_callback(script, 1); - if (cb) remove_lua_obs_callback(cb); + if (cb) + remove_lua_obs_callback(cb); return 0; } @@ -304,8 +310,8 @@ static int timer_add(lua_State *script) if (!ms) return 0; - struct lua_obs_callback *cb = add_lua_obs_callback_extra(script, 1, - sizeof(struct lua_obs_timer)); + struct lua_obs_callback *cb = add_lua_obs_callback_extra( + script, 1, sizeof(struct lua_obs_timer)); struct lua_obs_timer *timer = lua_obs_callback_extra_data(cb); timer->interval = (uint64_t)ms * 1000000ULL; @@ -324,7 +330,7 @@ static void obs_lua_main_render_callback(void *priv, uint32_t cx, uint32_t cy) if (cb->base.removed) { obs_remove_main_render_callback(obs_lua_main_render_callback, - cb); + cb); return; } @@ -343,7 +349,8 @@ static int obs_lua_remove_main_render_callback(lua_State *script) return 0; struct lua_obs_callback *cb = find_lua_obs_callback(script, 1); - if (cb) remove_lua_obs_callback(cb); + if (cb) + remove_lua_obs_callback(cb); return 0; } @@ -388,7 +395,8 @@ static int obs_lua_remove_tick_callback(lua_State *script) return 0; struct lua_obs_callback *cb = find_lua_obs_callback(script, 1); - if (cb) remove_lua_obs_callback(cb); + if (cb) + remove_lua_obs_callback(cb); return 0; } @@ -447,15 +455,15 @@ static int obs_lua_signal_handler_disconnect(lua_State *script) const char *cb_signal = calldata_string(&cb->base.extra, "signal"); - if (cb_signal && - strcmp(signal, cb_signal) != 0 && + if (cb_signal && strcmp(signal, cb_signal) != 0 && handler == cb_handler) break; cb = find_next_lua_obs_callback(script, cb, 3); } - if (cb) remove_lua_obs_callback(cb); + if (cb) + remove_lua_obs_callback(cb); return 0; } @@ -465,7 +473,7 @@ static void defer_connect(void *p_cb) signal_handler_t *handler = calldata_ptr(&cb->extra, "handler"); const char *signal = calldata_string(&cb->extra, "signal"); - signal_handler_connect(handler, signal, calldata_signal_callback, cb); + signal_handler_connect(handler, signal, calldata_signal_callback, cb); } static int obs_lua_signal_handler_connect(lua_State *script) @@ -491,7 +499,7 @@ static int obs_lua_signal_handler_connect(lua_State *script) /* -------------------------------------------- */ static void calldata_signal_callback_global(void *priv, const char *signal, - calldata_t *cd) + calldata_t *cd) { struct lua_obs_callback *cb = priv; lua_State *script = cb->script; @@ -530,7 +538,8 @@ static int obs_lua_signal_handler_disconnect_global(lua_State *script) cb = find_next_lua_obs_callback(script, cb, 3); } - if (cb) remove_lua_obs_callback(cb); + if (cb) + remove_lua_obs_callback(cb); return 0; } @@ -539,8 +548,8 @@ static void defer_connect_global(void *p_cb) struct script_callback *cb = p_cb; signal_handler_t *handler = calldata_ptr(&cb->extra, "handler"); - signal_handler_connect_global(handler, - calldata_signal_callback_global, cb); + signal_handler_connect_global(handler, calldata_signal_callback_global, + cb); } static int obs_lua_signal_handler_connect_global(lua_State *script) @@ -581,8 +590,11 @@ static int enum_sources(lua_State *script) /* -------------------------------------------- */ -static bool source_enum_filters_proc(obs_source_t *source, obs_source_t *filter, void *param) +static void source_enum_filters_proc(obs_source_t *source, obs_source_t *filter, + void *param) { + UNUSED_PARAMETER(source); + lua_State *script = param; obs_source_get_ref(filter); @@ -590,7 +602,6 @@ static bool source_enum_filters_proc(obs_source_t *source, obs_source_t *filter, size_t idx = lua_rawlen(script, -2); lua_rawseti(script, -2, (int)idx + 1); - return true; } static int source_enum_filters(lua_State *script) @@ -604,11 +615,10 @@ static int source_enum_filters(lua_State *script) return 1; } - /* -------------------------------------------- */ static bool enum_items_proc(obs_scene_t *scene, obs_sceneitem_t *item, - void *param) + void *param) { lua_State *script = param; @@ -644,7 +654,7 @@ static void on_remove_hotkey(void *p_cb) obs_hotkey_id id = (obs_hotkey_id)calldata_int(&cb->base.extra, "id"); if (id != OBS_INVALID_HOTKEY_ID) - defer_call_post(defer_hotkey_unregister, (void*)(uintptr_t)id); + defer_call_post(defer_hotkey_unregister, (void *)(uintptr_t)id); } static void hotkey_pressed(void *p_cb, bool pressed) @@ -673,8 +683,8 @@ static void defer_hotkey_unpressed(void *p_cb) hotkey_pressed(p_cb, false); } -static void hotkey_callback(void *p_cb, obs_hotkey_id id, - obs_hotkey_t *hotkey, bool pressed) +static void hotkey_callback(void *p_cb, obs_hotkey_id id, obs_hotkey_t *hotkey, + bool pressed) { struct lua_obs_callback *cb = p_cb; @@ -696,7 +706,8 @@ static int hotkey_unregister(lua_State *script) return 0; struct lua_obs_callback *cb = find_lua_obs_callback(script, 1); - if (cb) remove_lua_obs_callback(cb); + if (cb) + remove_lua_obs_callback(cb); return 0; } @@ -727,7 +738,7 @@ static int hotkey_register_frontend(lua_State *script) /* -------------------------------------------- */ static bool button_prop_clicked(obs_properties_t *props, obs_property_t *p, - void *p_cb) + void *p_cb) { struct lua_obs_callback *cb = p_cb; lua_State *script = cb->script; @@ -773,7 +784,7 @@ static int properties_add_button(lua_State *script) struct lua_obs_callback *cb = add_lua_obs_callback(script, 4); p = obs_properties_add_button2(props, name, text, button_prop_clicked, - cb); + cb); if (!p || !ls_push_libobs_obj(obs_property_t, p, false)) return 0; @@ -783,7 +794,7 @@ static int properties_add_button(lua_State *script) /* -------------------------------------------- */ static bool modified_callback(void *p_cb, obs_properties_t *props, - obs_property_t *p, obs_data_t *settings) + obs_property_t *p, obs_data_t *settings) { struct lua_obs_callback *cb = p_cb; lua_State *script = cb->script; @@ -976,11 +987,11 @@ static int lua_script_log(lua_State *script) static void add_hook_functions(lua_State *script) { -#define add_func(name, func) \ - do { \ - lua_pushstring(script, name); \ +#define add_func(name, func) \ + do { \ + lua_pushstring(script, name); \ lua_pushcfunction(script, func); \ - lua_rawset(script, -3); \ + lua_rawset(script, -3); \ } while (false) lua_getglobal(script, "_G"); @@ -1005,31 +1016,24 @@ static void add_hook_functions(lua_State *script) add_func("calldata_source", calldata_source); add_func("calldata_sceneitem", calldata_sceneitem); add_func("obs_add_main_render_callback", - obs_lua_add_main_render_callback); + obs_lua_add_main_render_callback); add_func("obs_remove_main_render_callback", - obs_lua_remove_main_render_callback); - add_func("obs_add_tick_callback", - obs_lua_add_tick_callback); - add_func("obs_remove_tick_callback", - obs_lua_remove_tick_callback); - add_func("signal_handler_connect", - obs_lua_signal_handler_connect); + obs_lua_remove_main_render_callback); + add_func("obs_add_tick_callback", obs_lua_add_tick_callback); + add_func("obs_remove_tick_callback", obs_lua_remove_tick_callback); + add_func("signal_handler_connect", obs_lua_signal_handler_connect); add_func("signal_handler_disconnect", - obs_lua_signal_handler_disconnect); + obs_lua_signal_handler_disconnect); add_func("signal_handler_connect_global", - obs_lua_signal_handler_connect_global); + obs_lua_signal_handler_connect_global); add_func("signal_handler_disconnect_global", - obs_lua_signal_handler_disconnect_global); - add_func("obs_hotkey_unregister", - hotkey_unregister); - add_func("obs_hotkey_register_frontend", - hotkey_register_frontend); - add_func("obs_properties_add_button", - properties_add_button); + obs_lua_signal_handler_disconnect_global); + add_func("obs_hotkey_unregister", hotkey_unregister); + add_func("obs_hotkey_register_frontend", hotkey_register_frontend); + add_func("obs_properties_add_button", properties_add_button); add_func("obs_property_set_modified_callback", - property_set_modified_callback); - add_func("remove_current_callback", - remove_current_callback); + property_set_modified_callback); + add_func("remove_current_callback", remove_current_callback); lua_pop(script, 1); #undef add_func @@ -1166,7 +1170,8 @@ void obs_lua_script_unload(obs_script_t *s) pthread_mutex_lock(&tick_mutex); struct obs_lua_script *next = data->next_tick; - if (next) next->p_prev_next_tick = data->p_prev_next_tick; + if (next) + next->p_prev_next_tick = data->p_prev_next_tick; *data->p_prev_next_tick = next; pthread_mutex_unlock(&tick_mutex); @@ -1258,7 +1263,7 @@ obs_properties_t *obs_lua_script_get_properties(obs_script_t *s) pthread_mutex_lock(&data->mutex); call_func_(script, data->get_properties, 0, 1, "script_properties", - __FUNCTION__); + __FUNCTION__); ls_get_libobs_obj(obs_properties_t, -1, &props); pthread_mutex_unlock(&data->mutex); diff --git a/deps/obs-scripting/obs-scripting-lua.h b/deps/obs-scripting/obs-scripting-lua.h index caa60cf..dda1042 100644 --- a/deps/obs-scripting/obs-scripting-lua.h +++ b/deps/obs-scripting/obs-scripting-lua.h @@ -46,12 +46,11 @@ #include "obs-scripting-internal.h" #include "obs-scripting-callback.h" -#define do_log(level, format, ...) \ - blog(level, "[Lua] " format, ##__VA_ARGS__) +#define do_log(level, format, ...) blog(level, "[Lua] " format, ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) -#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) /* ------------------------------------------------------------ */ @@ -87,15 +86,15 @@ struct obs_lua_script { bool defined_sources; }; -#define lock_callback() \ - struct obs_lua_script *__last_script = current_lua_script; \ - struct lua_obs_callback *__last_callback = current_lua_cb; \ - current_lua_cb = cb; \ +#define lock_callback() \ + struct obs_lua_script *__last_script = current_lua_script; \ + struct lua_obs_callback *__last_callback = current_lua_cb; \ + current_lua_cb = cb; \ current_lua_script = (struct obs_lua_script *)cb->base.script; \ pthread_mutex_lock(¤t_lua_script->mutex); -#define unlock_callback() \ +#define unlock_callback() \ pthread_mutex_unlock(¤t_lua_script->mutex); \ - current_lua_script = __last_script; \ + current_lua_script = __last_script; \ current_lua_cb = __last_callback; /* ------------------------------------------------ */ @@ -107,16 +106,13 @@ struct lua_obs_callback { int reg_idx; }; -static inline struct lua_obs_callback *add_lua_obs_callback_extra( - lua_State *script, - int stack_idx, - size_t extra_size) +static inline struct lua_obs_callback * +add_lua_obs_callback_extra(lua_State *script, int stack_idx, size_t extra_size) { struct obs_lua_script *data = current_lua_script; - struct lua_obs_callback *cb = add_script_callback( - &data->first_callback, - (obs_script_t *)data, - sizeof(*cb) + extra_size); + struct lua_obs_callback *cb = + add_script_callback(&data->first_callback, (obs_script_t *)data, + sizeof(*cb) + extra_size); lua_pushvalue(script, stack_idx); cb->reg_idx = luaL_ref(script, LUA_REGISTRYINDEX); @@ -124,25 +120,26 @@ static inline struct lua_obs_callback *add_lua_obs_callback_extra( return cb; } -static inline struct lua_obs_callback *add_lua_obs_callback( - lua_State *script, int stack_idx) +static inline struct lua_obs_callback *add_lua_obs_callback(lua_State *script, + int stack_idx) { return add_lua_obs_callback_extra(script, stack_idx, 0); } static inline void *lua_obs_callback_extra_data(struct lua_obs_callback *cb) { - return (void*)&cb[1]; + return (void *)&cb[1]; } -static inline struct obs_lua_script *lua_obs_callback_script( - struct lua_obs_callback *cb) +static inline struct obs_lua_script * +lua_obs_callback_script(struct lua_obs_callback *cb) { return (struct obs_lua_script *)cb->base.script; } -static inline struct lua_obs_callback *find_next_lua_obs_callback( - lua_State *script, struct lua_obs_callback *cb, int stack_idx) +static inline struct lua_obs_callback * +find_next_lua_obs_callback(lua_State *script, struct lua_obs_callback *cb, + int stack_idx) { struct obs_lua_script *data = current_lua_script; @@ -163,8 +160,8 @@ static inline struct lua_obs_callback *find_next_lua_obs_callback( return cb; } -static inline struct lua_obs_callback *find_lua_obs_callback( - lua_State *script, int stack_idx) +static inline struct lua_obs_callback *find_lua_obs_callback(lua_State *script, + int stack_idx) { return find_next_lua_obs_callback(script, NULL, stack_idx); } @@ -204,9 +201,8 @@ static int is_function(lua_State *script, int idx) typedef int (*param_cb)(lua_State *script, int idx); -static inline bool verify_args1_(lua_State *script, - param_cb param1_check, - const char *func) +static inline bool verify_args1_(lua_State *script, param_cb param1_check, + const char *func) { if (lua_gettop(script) != 1) { warn("Wrong number of parameters for %s", func); @@ -223,9 +219,9 @@ static inline bool verify_args1_(lua_State *script, #define verify_args1(script, param1_check) \ verify_args1_(script, param1_check, __FUNCTION__) -static inline bool call_func_(lua_State *script, - int reg_idx, int args, int rets, - const char *func, const char *display_name) +static inline bool call_func_(lua_State *script, int reg_idx, int args, + int rets, const char *func, + const char *display_name) { if (reg_idx == LUA_REFNIL) return false; @@ -237,8 +233,7 @@ static inline bool call_func_(lua_State *script, if (lua_pcall(script, args, rets, 0) != 0) { script_warn(&data->base, "Failed to call %s for %s: %s", func, - display_name, - lua_tostring(script, -1)); + display_name, lua_tostring(script, -1)); lua_pop(script, 1); return false; } @@ -246,19 +241,11 @@ static inline bool call_func_(lua_State *script, return true; } -bool ls_get_libobs_obj_(lua_State * script, - const char *type, - int lua_idx, - void * libobs_out, - const char *id, - const char *func, - int line); -bool ls_push_libobs_obj_(lua_State * script, - const char *type, - void * libobs_in, - bool ownership, - const char *id, - const char *func, - int line); +bool ls_get_libobs_obj_(lua_State *script, const char *type, int lua_idx, + void *libobs_out, const char *id, const char *func, + int line); +bool ls_push_libobs_obj_(lua_State *script, const char *type, void *libobs_in, + bool ownership, const char *id, const char *func, + int line); extern void add_lua_source_functions(lua_State *script); diff --git a/deps/obs-scripting/obs-scripting-python-frontend.c b/deps/obs-scripting/obs-scripting-python-frontend.c index 1c70252..ff3be49 100644 --- a/deps/obs-scripting/obs-scripting-python-frontend.c +++ b/deps/obs-scripting/obs-scripting-python-frontend.c @@ -20,12 +20,11 @@ #include "obs-scripting-python.h" -#define libobs_to_py(type, obs_obj, ownership, py_obj) \ - libobs_to_py_(#type " *", obs_obj, ownership, py_obj, \ - NULL, __func__, __LINE__) +#define libobs_to_py(type, obs_obj, ownership, py_obj) \ + libobs_to_py_(#type " *", obs_obj, ownership, py_obj, NULL, __func__, \ + __LINE__) #define py_to_libobs(type, py_obj, libobs_out) \ - py_to_libobs_(#type " *", py_obj, libobs_out, \ - NULL, __func__, __LINE__) + py_to_libobs_(#type " *", py_obj, libobs_out, NULL, __func__, __LINE__) /* ----------------------------------- */ @@ -257,7 +256,7 @@ static PyObject *set_current_profile(PyObject *self, PyObject *args) /* ----------------------------------- */ static void frontend_save_callback(obs_data_t *save_data, bool saving, - void *priv) + void *priv) { struct python_obs_callback *cb = priv; @@ -303,8 +302,10 @@ static PyObject *remove_save_callback(PyObject *self, PyObject *args) if (!py_cb || !PyFunction_Check(py_cb)) return python_none(); - struct python_obs_callback *cb = find_python_obs_callback(script, py_cb); - if (cb) remove_python_obs_callback(cb); + struct python_obs_callback *cb = + find_python_obs_callback(script, py_cb); + if (cb) + remove_python_obs_callback(cb); return python_none(); } @@ -354,8 +355,7 @@ void add_python_frontend_funcs(PyObject *module) DEF_FUNC(add_save_callback), #undef DEF_FUNC - {0} - }; + {0}}; add_functions_to_py_module(module, funcs); } diff --git a/deps/obs-scripting/obs-scripting-python-import.c b/deps/obs-scripting/obs-scripting-python-import.c index fa24c40..5a60681 100644 --- a/deps/obs-scripting/obs-scripting-python-import.c +++ b/deps/obs-scripting/obs-scripting-python-import.c @@ -51,18 +51,18 @@ bool import_python(const char *python_path) lib = os_dlopen(lib_path.array); if (!lib) { blog(LOG_WARNING, "[Python] Could not load library: %s", - lib_path.array); + lib_path.array); goto fail; } -#define IMPORT_FUNC(x) \ - do { \ - Import_##x = os_dlsym(lib, #x); \ - if (!Import_##x) { \ +#define IMPORT_FUNC(x) \ + do { \ + Import_##x = os_dlsym(lib, #x); \ + if (!Import_##x) { \ blog(LOG_WARNING, "[Python] Failed to import: %s", \ - #x); \ - goto fail; \ - } \ + #x); \ + goto fail; \ + } \ } while (false) IMPORT_FUNC(PyType_Ready); diff --git a/deps/obs-scripting/obs-scripting-python-import.h b/deps/obs-scripting/obs-scripting-python-import.h index 941e580..1394b28 100644 --- a/deps/obs-scripting/obs-scripting-python-import.h +++ b/deps/obs-scripting/obs-scripting-python-import.h @@ -32,11 +32,11 @@ #endif #if defined(_WIN32) && defined(_DEBUG) -# undef _DEBUG -# include -# define _DEBUG +#undef _DEBUG +#include +#define _DEBUG #else -# include +#include #endif #ifdef _MSC_VER @@ -64,14 +64,17 @@ PY_EXTERN PyObject *(*Import_PyLong_FromVoidPtr)(void *); PY_EXTERN PyObject *(*Import_PyBool_FromLong)(long); PY_EXTERN PyGILState_STATE (*Import_PyGILState_Ensure)(void); PY_EXTERN PyThreadState *(*Import_PyGILState_GetThisThreadState)(void); -PY_EXTERN void (*Import_PyErr_SetString)(PyObject *exception, const char *string); +PY_EXTERN void (*Import_PyErr_SetString)(PyObject *exception, + const char *string); PY_EXTERN PyObject *(*Import_PyErr_Occurred)(void); PY_EXTERN void (*Import_PyErr_Fetch)(PyObject **, PyObject **, PyObject **); PY_EXTERN void (*Import_PyErr_Restore)(PyObject *, PyObject *, PyObject *); PY_EXTERN void (*Import_PyErr_WriteUnraisable)(PyObject *); -PY_EXTERN int (*Import_PyArg_UnpackTuple)(PyObject *, const char *, Py_ssize_t, Py_ssize_t, ...); +PY_EXTERN int (*Import_PyArg_UnpackTuple)(PyObject *, const char *, Py_ssize_t, + Py_ssize_t, ...); PY_EXTERN PyObject *(*Import_Py_BuildValue)(const char *, ...); -PY_EXTERN int (*Import_PyRun_SimpleStringFlags)(const char *, PyCompilerFlags *); +PY_EXTERN int (*Import_PyRun_SimpleStringFlags)(const char *, + PyCompilerFlags *); PY_EXTERN void (*Import_PyErr_Print)(void); PY_EXTERN void (*Import_Py_SetPythonHome)(wchar_t *); PY_EXTERN void (*Import_Py_Initialize)(void); @@ -82,117 +85,127 @@ PY_EXTERN int (*Import_PyEval_ThreadsInitialized)(void); PY_EXTERN void (*Import_PyEval_ReleaseThread)(PyThreadState *tstate); PY_EXTERN void (*Import_PySys_SetArgv)(int, wchar_t **); PY_EXTERN PyObject *(*Import_PyImport_ImportModule)(const char *name); -PY_EXTERN PyObject *(*Import_PyObject_CallFunctionObjArgs)(PyObject *callable, ...); -PY_EXTERN PyObject (*Import__Py_NotImplementedStruct); +PY_EXTERN PyObject *(*Import_PyObject_CallFunctionObjArgs)(PyObject *callable, + ...); +PY_EXTERN PyObject(*Import__Py_NotImplementedStruct); PY_EXTERN PyObject *(*Import_PyExc_TypeError); PY_EXTERN PyObject *(*Import_PyExc_RuntimeError); PY_EXTERN PyObject *(*Import_PyObject_GetAttr)(PyObject *, PyObject *); PY_EXTERN PyObject *(*Import_PyUnicode_FromString)(const char *u); -PY_EXTERN PyObject *(*Import_PyDict_GetItemString)(PyObject *dp, const char *key); -PY_EXTERN int (*Import_PyDict_SetItemString)(PyObject *dp, const char *key, PyObject *item); -PY_EXTERN PyObject *(*Import_PyCFunction_NewEx)(PyMethodDef *, PyObject *, PyObject *); +PY_EXTERN PyObject *(*Import_PyDict_GetItemString)(PyObject *dp, + const char *key); +PY_EXTERN int (*Import_PyDict_SetItemString)(PyObject *dp, const char *key, + PyObject *item); +PY_EXTERN PyObject *(*Import_PyCFunction_NewEx)(PyMethodDef *, PyObject *, + PyObject *); PY_EXTERN PyObject *(*Import_PyModule_GetDict)(PyObject *); PY_EXTERN PyObject *(*Import_PyModule_GetNameObject)(PyObject *); -PY_EXTERN int (*Import_PyModule_AddObject)(PyObject *, const char *, PyObject *); -PY_EXTERN int (*Import_PyModule_AddStringConstant)(PyObject *, const char *, const char *); +PY_EXTERN int (*Import_PyModule_AddObject)(PyObject *, const char *, + PyObject *); +PY_EXTERN int (*Import_PyModule_AddStringConstant)(PyObject *, const char *, + const char *); PY_EXTERN PyObject *(*Import_PyImport_Import)(PyObject *name); -PY_EXTERN PyObject *(*Import_PyObject_CallObject)(PyObject *callable_object, PyObject *args); -PY_EXTERN struct _longobject (*Import__Py_FalseStruct); -PY_EXTERN struct _longobject (*Import__Py_TrueStruct); +PY_EXTERN PyObject *(*Import_PyObject_CallObject)(PyObject *callable_object, + PyObject *args); +PY_EXTERN struct _longobject(*Import__Py_FalseStruct); +PY_EXTERN struct _longobject(*Import__Py_TrueStruct); PY_EXTERN void (*Import_PyGILState_Release)(PyGILState_STATE); PY_EXTERN int (*Import_PyList_Append)(PyObject *, PyObject *); PY_EXTERN PyObject *(*Import_PySys_GetObject)(const char *); PY_EXTERN PyObject *(*Import_PyImport_ReloadModule)(PyObject *m); PY_EXTERN PyObject *(*Import_PyObject_GetAttrString)(PyObject *, const char *); -PY_EXTERN PyObject *(*Import_PyCapsule_New)(void *pointer, const char *name, PyCapsule_Destructor destructor); -PY_EXTERN void *(*Import_PyCapsule_GetPointer)(PyObject *capsule, const char *name); +PY_EXTERN PyObject *(*Import_PyCapsule_New)(void *pointer, const char *name, + PyCapsule_Destructor destructor); +PY_EXTERN void *(*Import_PyCapsule_GetPointer)(PyObject *capsule, + const char *name); PY_EXTERN int (*Import_PyArg_ParseTuple)(PyObject *, const char *, ...); -PY_EXTERN PyTypeObject (*Import_PyFunction_Type); +PY_EXTERN PyTypeObject(*Import_PyFunction_Type); PY_EXTERN int (*Import_PyObject_SetAttr)(PyObject *, PyObject *, PyObject *); PY_EXTERN PyObject *(*Import__PyObject_New)(PyTypeObject *); -PY_EXTERN void *(*Import_PyCapsule_Import)(const char *name, int no_block); +PY_EXTERN void *(*Import_PyCapsule_Import)(const char *name, int no_block); PY_EXTERN void (*Import_PyErr_Clear)(void); -PY_EXTERN PyObject *(*Import_PyObject_Call)(PyObject *callable_object, PyObject *args, PyObject *kwargs); +PY_EXTERN PyObject *(*Import_PyObject_Call)(PyObject *callable_object, + PyObject *args, PyObject *kwargs); PY_EXTERN PyObject *(*Import_PyList_New)(Py_ssize_t size); PY_EXTERN Py_ssize_t (*Import_PyList_Size)(PyObject *); PY_EXTERN PyObject *(*Import_PyList_GetItem)(PyObject *, Py_ssize_t); PY_EXTERN PyObject *(*Import_PyUnicode_AsUTF8String)(PyObject *unicode); PY_EXTERN PyObject *(*Import_PyLong_FromUnsignedLongLong)(unsigned long long); PY_EXTERN int (*Import_PyArg_VaParse)(PyObject *, const char *, va_list); -PY_EXTERN PyObject (*Import__Py_NoneStruct); +PY_EXTERN PyObject(*Import__Py_NoneStruct); extern bool import_python(const char *python_path); -# ifndef NO_REDEFS -# define PyType_Ready Import_PyType_Ready -# define PyObject_GenericGetAttr Import_PyObject_GenericGetAttr -# define PyObject_IsTrue Import_PyObject_IsTrue -# define Py_DecRef Import_Py_DecRef -# define PyObject_Malloc Import_PyObject_Malloc -# define PyObject_Free Import_PyObject_Free -# define PyObject_Init Import_PyObject_Init -# define PyUnicode_FromFormat Import_PyUnicode_FromFormat -# define PyUnicode_Concat Import_PyUnicode_Concat -# define PyLong_FromVoidPtr Import_PyLong_FromVoidPtr -# define PyBool_FromLong Import_PyBool_FromLong -# define PyGILState_Ensure Import_PyGILState_Ensure -# define PyGILState_GetThisThreadState Import_PyGILState_GetThisThreadState -# define PyErr_SetString Import_PyErr_SetString -# define PyErr_Occurred Import_PyErr_Occurred -# define PyErr_Fetch Import_PyErr_Fetch -# define PyErr_Restore Import_PyErr_Restore -# define PyErr_WriteUnraisable Import_PyErr_WriteUnraisable -# define PyArg_UnpackTuple Import_PyArg_UnpackTuple -# define Py_BuildValue Import_Py_BuildValue -# define PyRun_SimpleStringFlags Import_PyRun_SimpleStringFlags -# define PyErr_Print Import_PyErr_Print -# define Py_SetPythonHome Import_Py_SetPythonHome -# define Py_Initialize Import_Py_Initialize -# define Py_Finalize Import_Py_Finalize -# define Py_IsInitialized Import_Py_IsInitialized -# define PyEval_InitThreads Import_PyEval_InitThreads -# define PyEval_ThreadsInitialized Import_PyEval_ThreadsInitialized -# define PyEval_ReleaseThread Import_PyEval_ReleaseThread -# define PySys_SetArgv Import_PySys_SetArgv -# define PyImport_ImportModule Import_PyImport_ImportModule -# define PyObject_CallFunctionObjArgs Import_PyObject_CallFunctionObjArgs -# define _Py_NotImplementedStruct (*Import__Py_NotImplementedStruct) -# define PyExc_TypeError (*Import_PyExc_TypeError) -# define PyExc_RuntimeError (*Import_PyExc_RuntimeError) -# define PyObject_GetAttr Import_PyObject_GetAttr -# define PyUnicode_FromString Import_PyUnicode_FromString -# define PyDict_GetItemString Import_PyDict_GetItemString -# define PyDict_SetItemString Import_PyDict_SetItemString -# define PyCFunction_NewEx Import_PyCFunction_NewEx -# define PyModule_GetDict Import_PyModule_GetDict -# define PyModule_GetNameObject Import_PyModule_GetNameObject -# define PyModule_AddObject Import_PyModule_AddObject -# define PyModule_AddStringConstant Import_PyModule_AddStringConstant -# define PyImport_Import Import_PyImport_Import -# define PyObject_CallObject Import_PyObject_CallObject -# define _Py_FalseStruct (*Import__Py_FalseStruct) -# define _Py_TrueStruct (*Import__Py_TrueStruct) -# define PyGILState_Release Import_PyGILState_Release -# define PyList_Append Import_PyList_Append -# define PySys_GetObject Import_PySys_GetObject -# define PyImport_ReloadModule Import_PyImport_ReloadModule -# define PyObject_GetAttrString Import_PyObject_GetAttrString -# define PyCapsule_New Import_PyCapsule_New -# define PyCapsule_GetPointer Import_PyCapsule_GetPointer -# define PyArg_ParseTuple Import_PyArg_ParseTuple -# define PyFunction_Type (*Import_PyFunction_Type) -# define PyObject_SetAttr Import_PyObject_SetAttr -# define _PyObject_New Import__PyObject_New -# define PyCapsule_Import Import_PyCapsule_Import -# define PyErr_Clear Import_PyErr_Clear -# define PyObject_Call Import_PyObject_Call -# define PyList_New Import_PyList_New -# define PyList_Size Import_PyList_Size -# define PyList_GetItem Import_PyList_GetItem -# define PyUnicode_AsUTF8String Import_PyUnicode_AsUTF8String -# define PyLong_FromUnsignedLongLong Import_PyLong_FromUnsignedLongLong -# define PyArg_VaParse Import_PyArg_VaParse -# define _Py_NoneStruct (*Import__Py_NoneStruct) -# endif +#ifndef NO_REDEFS +#define PyType_Ready Import_PyType_Ready +#define PyObject_GenericGetAttr Import_PyObject_GenericGetAttr +#define PyObject_IsTrue Import_PyObject_IsTrue +#define Py_DecRef Import_Py_DecRef +#define PyObject_Malloc Import_PyObject_Malloc +#define PyObject_Free Import_PyObject_Free +#define PyObject_Init Import_PyObject_Init +#define PyUnicode_FromFormat Import_PyUnicode_FromFormat +#define PyUnicode_Concat Import_PyUnicode_Concat +#define PyLong_FromVoidPtr Import_PyLong_FromVoidPtr +#define PyBool_FromLong Import_PyBool_FromLong +#define PyGILState_Ensure Import_PyGILState_Ensure +#define PyGILState_GetThisThreadState Import_PyGILState_GetThisThreadState +#define PyErr_SetString Import_PyErr_SetString +#define PyErr_Occurred Import_PyErr_Occurred +#define PyErr_Fetch Import_PyErr_Fetch +#define PyErr_Restore Import_PyErr_Restore +#define PyErr_WriteUnraisable Import_PyErr_WriteUnraisable +#define PyArg_UnpackTuple Import_PyArg_UnpackTuple +#define Py_BuildValue Import_Py_BuildValue +#define PyRun_SimpleStringFlags Import_PyRun_SimpleStringFlags +#define PyErr_Print Import_PyErr_Print +#define Py_SetPythonHome Import_Py_SetPythonHome +#define Py_Initialize Import_Py_Initialize +#define Py_Finalize Import_Py_Finalize +#define Py_IsInitialized Import_Py_IsInitialized +#define PyEval_InitThreads Import_PyEval_InitThreads +#define PyEval_ThreadsInitialized Import_PyEval_ThreadsInitialized +#define PyEval_ReleaseThread Import_PyEval_ReleaseThread +#define PySys_SetArgv Import_PySys_SetArgv +#define PyImport_ImportModule Import_PyImport_ImportModule +#define PyObject_CallFunctionObjArgs Import_PyObject_CallFunctionObjArgs +#define _Py_NotImplementedStruct (*Import__Py_NotImplementedStruct) +#define PyExc_TypeError (*Import_PyExc_TypeError) +#define PyExc_RuntimeError (*Import_PyExc_RuntimeError) +#define PyObject_GetAttr Import_PyObject_GetAttr +#define PyUnicode_FromString Import_PyUnicode_FromString +#define PyDict_GetItemString Import_PyDict_GetItemString +#define PyDict_SetItemString Import_PyDict_SetItemString +#define PyCFunction_NewEx Import_PyCFunction_NewEx +#define PyModule_GetDict Import_PyModule_GetDict +#define PyModule_GetNameObject Import_PyModule_GetNameObject +#define PyModule_AddObject Import_PyModule_AddObject +#define PyModule_AddStringConstant Import_PyModule_AddStringConstant +#define PyImport_Import Import_PyImport_Import +#define PyObject_CallObject Import_PyObject_CallObject +#define _Py_FalseStruct (*Import__Py_FalseStruct) +#define _Py_TrueStruct (*Import__Py_TrueStruct) +#define PyGILState_Release Import_PyGILState_Release +#define PyList_Append Import_PyList_Append +#define PySys_GetObject Import_PySys_GetObject +#define PyImport_ReloadModule Import_PyImport_ReloadModule +#define PyObject_GetAttrString Import_PyObject_GetAttrString +#define PyCapsule_New Import_PyCapsule_New +#define PyCapsule_GetPointer Import_PyCapsule_GetPointer +#define PyArg_ParseTuple Import_PyArg_ParseTuple +#define PyFunction_Type (*Import_PyFunction_Type) +#define PyObject_SetAttr Import_PyObject_SetAttr +#define _PyObject_New Import__PyObject_New +#define PyCapsule_Import Import_PyCapsule_Import +#define PyErr_Clear Import_PyErr_Clear +#define PyObject_Call Import_PyObject_Call +#define PyList_New Import_PyList_New +#define PyList_Size Import_PyList_Size +#define PyList_GetItem Import_PyList_GetItem +#define PyUnicode_AsUTF8String Import_PyUnicode_AsUTF8String +#define PyLong_FromUnsignedLongLong Import_PyLong_FromUnsignedLongLong +#define PyArg_VaParse Import_PyArg_VaParse +#define _Py_NoneStruct (*Import__Py_NoneStruct) +#endif #endif diff --git a/deps/obs-scripting/obs-scripting-python.c b/deps/obs-scripting/obs-scripting-python.c index fc71d06..d02ac80 100644 --- a/deps/obs-scripting/obs-scripting-python.c +++ b/deps/obs-scripting/obs-scripting-python.c @@ -51,7 +51,7 @@ sys.stderr = stderr_logger()\n"; static wchar_t home_path[1024] = {0}; #endif -DARRAY(char*) python_paths; +DARRAY(char *) python_paths; static bool python_loaded = false; static pthread_mutex_t tick_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -63,21 +63,13 @@ struct python_obs_callback *cur_python_cb = NULL; /* -------------------------------------------- */ -bool py_to_libobs_(const char *type, - PyObject * py_in, - void * libobs_out, - const char *id, - const char *func, - int line) +bool py_to_libobs_(const char *type, PyObject *py_in, void *libobs_out, + const char *id, const char *func, int line) { swig_type_info *info = SWIG_TypeQuery(type); if (info == NULL) { - warn("%s:%d: SWIG could not find type: %s%s%s", - func, - line, - id ? id : "", - id ? "::" : "", - type); + warn("%s:%d: SWIG could not find type: %s%s%s", func, line, + id ? id : "", id ? "::" : "", type); return false; } @@ -85,33 +77,21 @@ bool py_to_libobs_(const char *type, if (!SWIG_IsOK(ret)) { warn("%s:%d: SWIG failed to convert python object to obs " "object: %s%s%s", - func, - line, - id ? id : "", - id ? "::" : "", - type); + func, line, id ? id : "", id ? "::" : "", type); return false; } return true; } -bool libobs_to_py_(const char *type, - void * libobs_in, - bool ownership, - PyObject ** py_out, - const char *id, - const char *func, - int line) +bool libobs_to_py_(const char *type, void *libobs_in, bool ownership, + PyObject **py_out, const char *id, const char *func, + int line) { swig_type_info *info = SWIG_TypeQuery(type); if (info == NULL) { - warn("%s:%d: SWIG could not find type: %s%s%s", - func, - line, - id ? id : "", - id ? "::" : "", - type); + warn("%s:%d: SWIG could not find type: %s%s%s", func, line, + id ? id : "", id ? "::" : "", type); return false; } @@ -119,33 +99,27 @@ bool libobs_to_py_(const char *type, if (*py_out == Py_None) { warn("%s:%d: SWIG failed to convert obs object to python " "object: %s%s%s", - func, - line, - id ? id : "", - id ? "::" : "", - type); + func, line, id ? id : "", id ? "::" : "", type); return false; } return true; } - -#define libobs_to_py(type, obs_obj, ownership, py_obj) \ - libobs_to_py_(#type " *", obs_obj, ownership, py_obj, \ - NULL, __func__, __LINE__) +#define libobs_to_py(type, obs_obj, ownership, py_obj) \ + libobs_to_py_(#type " *", obs_obj, ownership, py_obj, NULL, __func__, \ + __LINE__) #define py_to_libobs(type, py_obj, libobs_out) \ - py_to_libobs_(#type " *", py_obj, libobs_out, \ - NULL, __func__, __LINE__) + py_to_libobs_(#type " *", py_obj, libobs_out, NULL, __func__, __LINE__) -#define lock_callback(cb) \ - lock_python(); \ - struct obs_python_script *__last_script = cur_python_script; \ - struct python_obs_callback *__last_cb = cur_python_cb; \ +#define lock_callback(cb) \ + lock_python(); \ + struct obs_python_script *__last_script = cur_python_script; \ + struct python_obs_callback *__last_cb = cur_python_cb; \ cur_python_script = (struct obs_python_script *)cb->base.script; \ cur_python_cb = cb -#define unlock_callback() \ - cur_python_cb = __last_cb; \ +#define unlock_callback() \ + cur_python_cb = __last_cb; \ cur_python_script = __last_script; \ unlock_python() @@ -174,8 +148,7 @@ void add_functions_to_py_module(PyObject *module, PyMethodDef *method_list) static PyObject *py_get_current_script_path(PyObject *self, PyObject *args) { UNUSED_PARAMETER(args); - return PyDict_GetItemString(PyModule_GetDict(self), - "__script_dir__"); + return PyDict_GetItemString(PyModule_GetDict(self), "__script_dir__"); } static void get_defaults(struct obs_python_script *data, PyObject *get_defs) @@ -194,19 +167,19 @@ static void get_defaults(struct obs_python_script *data, PyObject *get_defs) static bool load_python_script(struct obs_python_script *data) { - PyObject *py_file = NULL; - PyObject *py_module = NULL; - PyObject *py_success = NULL; - PyObject *py_tick = NULL; - PyObject *py_load = NULL; + PyObject *py_file = NULL; + PyObject *py_module = NULL; + PyObject *py_success = NULL; + PyObject *py_tick = NULL; + PyObject *py_load = NULL; PyObject *py_defaults = NULL; - bool success = false; - int ret; + bool success = false; + int ret; cur_python_script = data; if (!data->module) { - py_file = PyUnicode_FromString(data->name.array); + py_file = PyUnicode_FromString(data->name.array); py_module = PyImport_Import(py_file); } else { py_module = PyImport_ReloadModule(data->module); @@ -223,7 +196,7 @@ static bool load_python_script(struct obs_python_script *data) goto fail; ret = PyModule_AddStringConstant(py_module, "__script_dir__", - data->dir.array); + data->dir.array); if (py_error() || ret != 0) goto fail; @@ -233,12 +206,9 @@ static bool load_python_script(struct obs_python_script *data) goto fail; static PyMethodDef global_funcs[] = { - {"script_path", - py_get_current_script_path, - METH_NOARGS, + {"script_path", py_get_current_script_path, METH_NOARGS, "Gets the script path"}, - {0} - }; + {0}}; add_functions_to_py_module(py_module, global_funcs); @@ -250,8 +220,8 @@ static bool load_python_script(struct obs_python_script *data) if (!data->save) PyErr_Clear(); - data->get_properties = PyObject_GetAttrString(py_module, - "script_properties"); + data->get_properties = + PyObject_GetAttrString(py_module, "script_properties"); if (!data->get_properties) PyErr_Clear(); @@ -270,7 +240,8 @@ static bool load_python_script(struct obs_python_script *data) PyObject *py_desc = PyUnicode_AsUTF8String(py_ret); if (py_desc) { const char *desc = PyBytes_AS_STRING(py_desc); - if (desc) dstr_copy(&data->base.desc, desc); + if (desc) + dstr_copy(&data->base.desc, desc); Py_DECREF(py_desc); } Py_XDECREF(py_ret); @@ -286,7 +257,8 @@ static bool load_python_script(struct obs_python_script *data) struct obs_python_script *next = first_tick_script; data->next_tick = next; data->p_prev_next_tick = &first_tick_script; - if (next) next->p_prev_next_tick = &data->next_tick; + if (next) + next->p_prev_next_tick = &data->next_tick; first_tick_script = data; data->tick = py_tick; @@ -332,9 +304,9 @@ fail: static void unload_python_script(struct obs_python_script *data) { - PyObject *py_module = data->module; - PyObject *py_func = NULL; - PyObject *py_ret = NULL; + PyObject *py_module = data->module; + PyObject *py_func = NULL; + PyObject *py_ret = NULL; cur_python_script = data; @@ -358,8 +330,8 @@ fail: static void add_to_python_path(const char *path) { PyObject *py_path_str = NULL; - PyObject *py_path = NULL; - int ret; + PyObject *py_path = NULL; + int ret; if (!path || !*path) return; @@ -411,7 +383,8 @@ static inline void python_obs_timer_init(struct python_obs_timer *timer) struct python_obs_timer *next = first_timer; timer->next = next; timer->p_prev_next = &first_timer; - if (next) next->p_prev_next = &timer->next; + if (next) + next->p_prev_next = &timer->next; first_timer = timer; pthread_mutex_unlock(&timer_mutex); @@ -420,12 +393,13 @@ static inline void python_obs_timer_init(struct python_obs_timer *timer) static inline void python_obs_timer_remove(struct python_obs_timer *timer) { struct python_obs_timer *next = timer->next; - if (next) next->p_prev_next = timer->p_prev_next; + if (next) + next->p_prev_next = timer->p_prev_next; *timer->p_prev_next = timer->next; } -static inline struct python_obs_callback *python_obs_timer_cb( - struct python_obs_timer *timer) +static inline struct python_obs_callback * +python_obs_timer_cb(struct python_obs_timer *timer) { return &((struct python_obs_callback *)timer)[-1]; } @@ -440,8 +414,10 @@ static PyObject *timer_remove(PyObject *self, PyObject *args) if (!parse_args(args, "O", &py_cb)) return python_none(); - struct python_obs_callback *cb = find_python_obs_callback(script, py_cb); - if (cb) remove_python_obs_callback(cb); + struct python_obs_callback *cb = + find_python_obs_callback(script, py_cb); + if (cb) + remove_python_obs_callback(cb); return python_none(); } @@ -478,7 +454,7 @@ static PyObject *timer_add(PyObject *self, PyObject *args) return python_none(); struct python_obs_callback *cb = add_python_obs_callback_extra( - script, py_cb, sizeof(struct python_obs_timer)); + script, py_cb, sizeof(struct python_obs_timer)); struct python_obs_timer *timer = python_obs_callback_extra_data(cb); timer->interval = (uint64_t)ms * 1000000ULL; @@ -528,8 +504,10 @@ static PyObject *obs_python_remove_tick_callback(PyObject *self, PyObject *args) if (!py_cb || !PyFunction_Check(py_cb)) return python_none(); - struct python_obs_callback *cb = find_python_obs_callback(script, py_cb); - if (cb) remove_python_obs_callback(cb); + struct python_obs_callback *cb = + find_python_obs_callback(script, py_cb); + if (cb) + remove_python_obs_callback(cb); return python_none(); } @@ -583,8 +561,8 @@ static void calldata_signal_callback(void *priv, calldata_t *cd) unlock_callback(); } -static PyObject *obs_python_signal_handler_disconnect( - PyObject *self, PyObject *args) +static PyObject *obs_python_signal_handler_disconnect(PyObject *self, + PyObject *args) { struct obs_python_script *script = cur_python_script; PyObject *py_sh = NULL; @@ -609,27 +587,28 @@ static PyObject *obs_python_signal_handler_disconnect( if (!py_cb || !PyFunction_Check(py_cb)) return python_none(); - struct python_obs_callback *cb = find_python_obs_callback(script, py_cb); + struct python_obs_callback *cb = + find_python_obs_callback(script, py_cb); while (cb) { signal_handler_t *cb_handler = calldata_ptr(&cb->base.extra, "handler"); const char *cb_signal = calldata_string(&cb->base.extra, "signal"); - if (cb_signal && - strcmp(signal, cb_signal) != 0 && + if (cb_signal && strcmp(signal, cb_signal) != 0 && handler == cb_handler) break; cb = find_next_python_obs_callback(script, cb, py_cb); } - if (cb) remove_python_obs_callback(cb); + if (cb) + remove_python_obs_callback(cb); return python_none(); } -static PyObject *obs_python_signal_handler_connect( - PyObject *self, PyObject *args) +static PyObject *obs_python_signal_handler_connect(PyObject *self, + PyObject *args) { struct obs_python_script *script = cur_python_script; PyObject *py_sh = NULL; @@ -663,7 +642,7 @@ static PyObject *obs_python_signal_handler_connect( /* -------------------------------------------- */ static void calldata_signal_callback_global(void *priv, const char *signal, - calldata_t *cd) + calldata_t *cd) { struct python_obs_callback *cb = priv; @@ -688,8 +667,8 @@ static void calldata_signal_callback_global(void *priv, const char *signal, unlock_callback(); } -static PyObject *obs_python_signal_handler_disconnect_global( - PyObject *self, PyObject *args) +static PyObject *obs_python_signal_handler_disconnect_global(PyObject *self, + PyObject *args) { struct obs_python_script *script = cur_python_script; PyObject *py_sh = NULL; @@ -713,7 +692,8 @@ static PyObject *obs_python_signal_handler_disconnect_global( if (!py_cb || !PyFunction_Check(py_cb)) return python_none(); - struct python_obs_callback *cb = find_python_obs_callback(script, py_cb); + struct python_obs_callback *cb = + find_python_obs_callback(script, py_cb); while (cb) { signal_handler_t *cb_handler = calldata_ptr(&cb->base.extra, "handler"); @@ -724,12 +704,13 @@ static PyObject *obs_python_signal_handler_disconnect_global( cb = find_next_python_obs_callback(script, cb, py_cb); } - if (cb) remove_python_obs_callback(cb); + if (cb) + remove_python_obs_callback(cb); return python_none(); } -static PyObject *obs_python_signal_handler_connect_global( - PyObject *self, PyObject *args) +static PyObject *obs_python_signal_handler_connect_global(PyObject *self, + PyObject *args) { struct obs_python_script *script = cur_python_script; PyObject *py_sh = NULL; @@ -755,8 +736,8 @@ static PyObject *obs_python_signal_handler_connect_global( struct python_obs_callback *cb = add_python_obs_callback(script, py_cb); calldata_set_ptr(&cb->base.extra, "handler", handler); - signal_handler_connect_global(handler, - calldata_signal_callback_global, cb); + signal_handler_connect_global(handler, calldata_signal_callback_global, + cb); return python_none(); } @@ -773,7 +754,7 @@ static void on_remove_hotkey(void *p_cb) obs_hotkey_id id = (obs_hotkey_id)calldata_int(&cb->base.extra, "id"); if (id != OBS_INVALID_HOTKEY_ID) - defer_call_post(defer_hotkey_unregister, (void*)(uintptr_t)id); + defer_call_post(defer_hotkey_unregister, (void *)(uintptr_t)id); } static void hotkey_pressed(void *p_cb, bool pressed) @@ -811,8 +792,8 @@ static inline PyObject *py_invalid_hotkey_id() return PyLong_FromUnsignedLongLong(OBS_INVALID_HOTKEY_ID); } -static void hotkey_callback(void *p_cb, obs_hotkey_id id, - obs_hotkey_t *hotkey, bool pressed) +static void hotkey_callback(void *p_cb, obs_hotkey_id id, obs_hotkey_t *hotkey, + bool pressed) { struct python_obs_callback *cb = p_cb; @@ -844,8 +825,10 @@ static PyObject *hotkey_unregister(PyObject *self, PyObject *args) if (!py_cb || !PyFunction_Check(py_cb)) return python_none(); - struct python_obs_callback *cb = find_python_obs_callback(script, py_cb); - if (cb) remove_python_obs_callback(cb); + struct python_obs_callback *cb = + find_python_obs_callback(script, py_cb); + if (cb) + remove_python_obs_callback(cb); UNUSED_PARAMETER(self); return python_none(); @@ -879,7 +862,7 @@ static PyObject *hotkey_register_frontend(PyObject *self, PyObject *args) /* -------------------------------------------- */ static bool button_prop_clicked(obs_properties_t *props, obs_property_t *p, - void *p_cb) + void *p_cb) { struct python_obs_callback *cb = p_cb; bool ret = false; @@ -931,7 +914,7 @@ static PyObject *properties_add_button(PyObject *self, PyObject *args) struct python_obs_callback *cb = add_python_obs_callback(script, py_cb); p = obs_properties_add_button2(props, name, text, button_prop_clicked, - cb); + cb); if (!p || !libobs_to_py(obs_property_t, p, false, &py_ret)) return python_none(); @@ -943,7 +926,7 @@ static PyObject *properties_add_button(PyObject *self, PyObject *args) /* -------------------------------------------- */ static bool modified_callback(void *p_cb, obs_properties_t *props, - obs_property_t *p, obs_data_t *settings) + obs_property_t *p, obs_data_t *settings) { struct python_obs_callback *cb = p_cb; bool ret = false; @@ -961,8 +944,8 @@ static bool modified_callback(void *p_cb, obs_properties_t *props, libobs_to_py(obs_property_t, p, false, &py_p) && libobs_to_py(obs_data_t, settings, false, &py_settings)) { - PyObject *args = Py_BuildValue("(OOO)", py_props, py_p, - py_settings); + PyObject *args = + Py_BuildValue("(OOO)", py_props, py_p, py_settings); PyObject *py_ret = PyObject_CallObject(cb->func, args); if (!py_error()) ret = py_ret == Py_True; @@ -1017,7 +1000,7 @@ static PyObject *remove_current_callback(PyObject *self, PyObject *args) static PyObject *calldata_source(PyObject *self, PyObject *args) { PyObject *py_ret = NULL; - PyObject *py_cd = NULL; + PyObject *py_cd = NULL; calldata_t *cd; const char *name; @@ -1039,7 +1022,7 @@ fail: static PyObject *calldata_sceneitem(PyObject *self, PyObject *args) { PyObject *py_ret = NULL; - PyObject *py_cd = NULL; + PyObject *py_cd = NULL; calldata_t *cd; const char *name; @@ -1086,7 +1069,7 @@ static PyObject *enum_sources(PyObject *self, PyObject *args) /* -------------------------------------------- */ static bool enum_items_proc(obs_scene_t *scene, obs_sceneitem_t *item, - void *param) + void *param) { PyObject *list = param; PyObject *py_item; @@ -1165,7 +1148,7 @@ static PyObject *sceneitem_list_release(PyObject *self, PyObject *args) struct dstr cur_py_log_chunk = {0}; static PyObject *py_script_log_internal(PyObject *self, PyObject *args, - bool add_endl) + bool add_endl) { static bool calling_self = false; int log_level; @@ -1195,7 +1178,7 @@ static PyObject *py_script_log_internal(PyObject *self, PyObject *args, *endl = 0; if (cur_python_script) script_log(&cur_python_script->base, log_level, "%s", - start); + start); else script_log(NULL, log_level, "%s", start); *endl = '\n'; @@ -1206,7 +1189,8 @@ static PyObject *py_script_log_internal(PyObject *self, PyObject *args, if (start) { size_t len = strlen(start); - if (len) memmove(cur_py_log_chunk.array, start, len); + if (len) + memmove(cur_py_log_chunk.array, start, len); dstr_resize(&cur_py_log_chunk, len); } @@ -1245,31 +1229,26 @@ static void add_hook_functions(PyObject *module) DEF_FUNC("obs_enum_sources", enum_sources), DEF_FUNC("obs_scene_enum_items", scene_enum_items), DEF_FUNC("obs_remove_tick_callback", - obs_python_remove_tick_callback), - DEF_FUNC("obs_add_tick_callback", - obs_python_add_tick_callback), + obs_python_remove_tick_callback), + DEF_FUNC("obs_add_tick_callback", obs_python_add_tick_callback), DEF_FUNC("signal_handler_disconnect", - obs_python_signal_handler_disconnect), + obs_python_signal_handler_disconnect), DEF_FUNC("signal_handler_connect", - obs_python_signal_handler_connect), + obs_python_signal_handler_connect), DEF_FUNC("signal_handler_disconnect_global", - obs_python_signal_handler_disconnect_global), + obs_python_signal_handler_disconnect_global), DEF_FUNC("signal_handler_connect_global", - obs_python_signal_handler_connect_global), - DEF_FUNC("obs_hotkey_unregister", - hotkey_unregister), + obs_python_signal_handler_connect_global), + DEF_FUNC("obs_hotkey_unregister", hotkey_unregister), DEF_FUNC("obs_hotkey_register_frontend", - hotkey_register_frontend), - DEF_FUNC("obs_properties_add_button", - properties_add_button), + hotkey_register_frontend), + DEF_FUNC("obs_properties_add_button", properties_add_button), DEF_FUNC("obs_property_set_modified_callback", - property_set_modified_callback), - DEF_FUNC("remove_current_callback", - remove_current_callback), + property_set_modified_callback), + DEF_FUNC("remove_current_callback", remove_current_callback), #undef DEF_FUNC - {0} - }; + {0}}; add_functions_to_py_module(module, funcs); } @@ -1355,7 +1334,8 @@ void obs_python_script_unload(obs_script_t *s) pthread_mutex_lock(&tick_mutex); struct obs_python_script *next = data->next_tick; - if (next) next->p_prev_next_tick = data->p_prev_next_tick; + if (next) + next->p_prev_next_tick = data->p_prev_next_tick; *data->p_prev_next_tick = next; pthread_mutex_unlock(&tick_mutex); @@ -1520,7 +1500,8 @@ static void python_tick(void *param, float seconds) while (data) { cur_python_script = data; - PyObject *py_ret = PyObject_CallObject(data->tick, args); + PyObject *py_ret = + PyObject_CallObject(data->tick, args); Py_XDECREF(py_ret); py_error(); @@ -1590,7 +1571,6 @@ void obs_python_load(void) pthread_mutex_init(&tick_mutex, NULL); pthread_mutex_init(&timer_mutex, &attr); - } extern void add_python_frontend_funcs(PyObject *module); @@ -1602,12 +1582,12 @@ bool obs_scripting_load_python(const char *python_path) if (python_loaded) return true; - /* Use external python on windows and mac */ + /* Use external python on windows and mac */ #if RUNTIME_LINK -# if 0 +#if 0 struct dstr old_path = {0}; struct dstr new_path = {0}; -# endif +#endif if (!import_python(python_path)) return false; @@ -1615,11 +1595,11 @@ bool obs_scripting_load_python(const char *python_path) if (python_path && *python_path) { os_utf8_to_wcs(python_path, 0, home_path, 1024); Py_SetPythonHome(home_path); -# if 0 +#if 0 dstr_copy(&old_path, getenv("PATH")); _putenv("PYTHONPATH="); _putenv("PATH="); -# endif +#endif } #else UNUSED_PARAMETER(python_path); @@ -1630,12 +1610,12 @@ bool obs_scripting_load_python(const char *python_path) return false; #if 0 -# ifdef _DEBUG +#ifdef _DEBUG if (pythondir && *pythondir) { dstr_printf(&new_path, "PATH=%s", old_path.array); _putenv(new_path.array); } -# endif +#endif bfree(pythondir); dstr_free(&new_path); @@ -1650,7 +1630,7 @@ bool obs_scripting_load_python(const char *python_path) /* Must set arguments for guis to work */ wchar_t *argv[] = {L"", NULL}; - int argc = sizeof(argv) / sizeof(wchar_t*) - 1; + int argc = sizeof(argv) / sizeof(wchar_t *) - 1; PySys_SetArgv(argc, argv); diff --git a/deps/obs-scripting/obs-scripting-python.h b/deps/obs-scripting/obs-scripting-python.h index 15bb286..aaa3fa9 100644 --- a/deps/obs-scripting/obs-scripting-python.h +++ b/deps/obs-scripting/obs-scripting-python.h @@ -55,9 +55,9 @@ #define do_log(level, format, ...) \ blog(level, "[Python] " format, ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) -#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) /* ------------------------------------------------------------ */ @@ -90,43 +90,40 @@ struct python_obs_callback { PyObject *func; }; -static inline struct python_obs_callback *add_python_obs_callback_extra( - struct obs_python_script *script, - PyObject *func, - size_t extra_size) +static inline struct python_obs_callback * +add_python_obs_callback_extra(struct obs_python_script *script, PyObject *func, + size_t extra_size) { struct python_obs_callback *cb = add_script_callback( - &script->first_callback, - (obs_script_t *)script, - sizeof(*cb) + extra_size); + &script->first_callback, (obs_script_t *)script, + sizeof(*cb) + extra_size); Py_XINCREF(func); cb->func = func; return cb; } -static inline struct python_obs_callback *add_python_obs_callback( - struct obs_python_script *script, - PyObject *func) +static inline struct python_obs_callback * +add_python_obs_callback(struct obs_python_script *script, PyObject *func) { return add_python_obs_callback_extra(script, func, 0); } -static inline void *python_obs_callback_extra_data( - struct python_obs_callback *cb) +static inline void * +python_obs_callback_extra_data(struct python_obs_callback *cb) { - return (void*)&cb[1]; + return (void *)&cb[1]; } -static inline struct obs_python_script *python_obs_callback_script( - struct python_obs_callback *cb) +static inline struct obs_python_script * +python_obs_callback_script(struct python_obs_callback *cb) { return (struct obs_python_script *)cb->base.script; } -static inline struct python_obs_callback *find_next_python_obs_callback( - struct obs_python_script *script, - struct python_obs_callback *cb, PyObject *func) +static inline struct python_obs_callback * +find_next_python_obs_callback(struct obs_python_script *script, + struct python_obs_callback *cb, PyObject *func) { cb = cb ? (struct python_obs_callback *)cb->base.next : (struct python_obs_callback *)script->first_callback; @@ -140,9 +137,8 @@ static inline struct python_obs_callback *find_next_python_obs_callback( return cb; } -static inline struct python_obs_callback *find_python_obs_callback( - struct obs_python_script *script, - PyObject *func) +static inline struct python_obs_callback * +find_python_obs_callback(struct obs_python_script *script, PyObject *func) { return find_next_python_obs_callback(script, NULL, func); } @@ -167,7 +163,8 @@ static inline void free_python_obs_callback(struct python_obs_callback *cb) /* ------------------------------------------------------------ */ -static int parse_args_(PyObject *args, const char *func, const char *format, ...) +static int parse_args_(PyObject *args, const char *func, const char *format, + ...) { char new_format[128]; va_list va_args; @@ -197,15 +194,13 @@ static inline bool py_error_(const char *func, int line) #define py_error() py_error_(__FUNCTION__, __LINE__) -#define lock_python() \ - PyGILState_STATE gstate = PyGILState_Ensure() -#define unlock_python() \ - PyGILState_Release(gstate) +#define lock_python() PyGILState_STATE gstate = PyGILState_Ensure() +#define unlock_python() PyGILState_Release(gstate) struct py_source; typedef struct py_source py_source_t; -extern PyObject* py_libobs; +extern PyObject *py_libobs; extern struct python_obs_callback *cur_python_cb; extern struct obs_python_script *cur_python_script; @@ -213,25 +208,17 @@ extern void py_to_obs_source_info(py_source_t *py_info); extern PyObject *py_obs_register_source(PyObject *self, PyObject *args); extern PyObject *py_obs_get_script_config_path(PyObject *self, PyObject *args); extern void add_functions_to_py_module(PyObject *module, - PyMethodDef *method_list); + PyMethodDef *method_list); /* ------------------------------------------------------------ */ /* Warning: the following functions expect python to be locked! */ -extern bool py_to_libobs_(const char *type, - PyObject * py_in, - void * libobs_out, - const char *id, - const char *func, - int line); +extern bool py_to_libobs_(const char *type, PyObject *py_in, void *libobs_out, + const char *id, const char *func, int line); -extern bool libobs_to_py_(const char *type, - void * libobs_in, - bool ownership, - PyObject ** py_out, - const char *id, - const char *func, - int line); +extern bool libobs_to_py_(const char *type, void *libobs_in, bool ownership, + PyObject **py_out, const char *id, const char *func, + int line); extern bool py_call(PyObject *call, PyObject **ret, const char *arg_def, ...); extern bool py_import_script(const char *name); diff --git a/deps/obs-scripting/obs-scripting.c b/deps/obs-scripting/obs-scripting.c index bed24fb..14bdbc0 100644 --- a/deps/obs-scripting/obs-scripting.c +++ b/deps/obs-scripting/obs-scripting.c @@ -27,7 +27,7 @@ #if COMPILE_LUA extern obs_script_t *obs_lua_script_create(const char *path, - obs_data_t *settings); + obs_data_t *settings); extern bool obs_lua_script_load(obs_script_t *s); extern void obs_lua_script_unload(obs_script_t *s); extern void obs_lua_script_destroy(obs_script_t *s); @@ -41,7 +41,7 @@ extern void obs_lua_script_save(obs_script_t *script); #if COMPILE_PYTHON extern obs_script_t *obs_python_script_create(const char *path, - obs_data_t *settings); + obs_data_t *settings); extern bool obs_python_script_load(obs_script_t *s); extern void obs_python_script_unload(obs_script_t *s); extern void obs_python_script_destroy(obs_script_t *s); @@ -49,7 +49,8 @@ extern void obs_python_load(void); extern void obs_python_unload(void); extern obs_properties_t *obs_python_script_get_properties(obs_script_t *script); -extern void obs_python_script_update(obs_script_t *script, obs_data_t *settings); +extern void obs_python_script_update(obs_script_t *script, + obs_data_t *settings); extern void obs_python_script_save(obs_script_t *script); #endif @@ -66,8 +67,7 @@ static const char *supported_formats[] = { #if COMPILE_PYTHON "py", #endif - NULL -}; + NULL}; /* -------------------------------------------- */ @@ -164,7 +164,7 @@ void obs_scripting_unload(void) if (!scripting_loaded) return; - /* ---------------------- */ + /* ---------------------- */ #if COMPILE_LUA obs_lua_unload(); @@ -195,7 +195,7 @@ void obs_scripting_unload(void) pthread_mutex_destroy(&detach_mutex); blog(LOG_INFO, "[Scripting] Total detached callbacks: %d", - total_detached); + total_detached); /* ---------------------- */ @@ -223,11 +223,10 @@ const char **obs_scripting_supported_formats(void) } static inline bool pointer_valid(const void *x, const char *name, - const char *func) + const char *func) { if (!x) { - blog(LOG_WARNING, "obs-scripting: [%s] %s is null", - func, name); + blog(LOG_WARNING, "obs-scripting: [%s] %s is null", func, name); return false; } @@ -256,7 +255,7 @@ obs_script_t *obs_script_create(const char *path, obs_data_t *settings) } else #endif #if COMPILE_PYTHON - if (strcmp(ext, ".py") == 0) { + if (strcmp(ext, ".py") == 0) { script = obs_python_script_create(path, settings); } else #endif diff --git a/deps/obs-scripting/obs-scripting.h b/deps/obs-scripting/obs-scripting.h index d0e0b90..415c313 100644 --- a/deps/obs-scripting/obs-scripting.h +++ b/deps/obs-scripting/obs-scripting.h @@ -39,14 +39,11 @@ EXPORT bool obs_scripting_load(void); EXPORT void obs_scripting_unload(void); EXPORT const char **obs_scripting_supported_formats(void); -typedef void (*scripting_log_handler_t)( - void *p, - obs_script_t *script, - int lvl, - const char *msg); +typedef void (*scripting_log_handler_t)(void *p, obs_script_t *script, int lvl, + const char *msg); -EXPORT void obs_scripting_set_log_callback( - scripting_log_handler_t handler, void *param); +EXPORT void obs_scripting_set_log_callback(scripting_log_handler_t handler, + void *param); EXPORT bool obs_scripting_python_runtime_linked(void); EXPORT bool obs_scripting_python_loaded(void); diff --git a/deps/obs-scripting/obslua/CMakeLists.txt b/deps/obs-scripting/obslua/CMakeLists.txt index eb30a88..d35e153 100644 --- a/deps/obs-scripting/obslua/CMakeLists.txt +++ b/deps/obs-scripting/obslua/CMakeLists.txt @@ -1,6 +1,10 @@ cmake_minimum_required(VERSION 2.8) project(obslua) +if(POLICY CMP0078) + cmake_policy(SET CMP0078 OLD) +endif() + find_package(SWIG 2 REQUIRED) include(${SWIG_USE_FILE}) @@ -16,7 +20,14 @@ endif() include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/libobs") include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -SWIG_ADD_MODULE(obslua lua obslua.i ../cstrcache.cpp ../cstrcache.h) +if(CMAKE_VERSION VERSION_GREATER 3.7.2) + SWIG_ADD_LIBRARY(obslua + LANGUAGE lua + TYPE MODULE + SOURCES obslua.i ../cstrcache.cpp ../cstrcache.h) +else() + SWIG_ADD_MODULE(obslua lua obslua.i ../cstrcache.cpp ../cstrcache.h) +endif() SWIG_LINK_LIBRARIES(obslua obs-scripting libobs ${LUA_LIBRARIES} ${EXTRA_LIBS}) function(install_plugin_bin_swig target additional_target) diff --git a/deps/obs-scripting/obspython/CMakeLists.txt b/deps/obs-scripting/obspython/CMakeLists.txt index f5475e9..57b65bd 100644 --- a/deps/obs-scripting/obspython/CMakeLists.txt +++ b/deps/obs-scripting/obspython/CMakeLists.txt @@ -1,6 +1,10 @@ cmake_minimum_required(VERSION 2.8) project(obspython) +if(POLICY CMP0078) + cmake_policy(SET CMP0078 OLD) +endif() + find_package(SWIG 2 REQUIRED) include(${SWIG_USE_FILE}) @@ -30,7 +34,14 @@ if(WIN32) string(REGEX REPLACE "_d" "" PYTHON_LIBRARIES "${PYTHON_LIBRARIES}") endif() -SWIG_ADD_MODULE(obspython python obspython.i ../cstrcache.cpp ../cstrcache.h) +if(CMAKE_VERSION VERSION_GREATER 3.7.2) + SWIG_ADD_LIBRARY(obspython + LANGUAGE python + TYPE MODULE + SOURCES obspython.i ../cstrcache.cpp ../cstrcache.h) +else() + SWIG_ADD_MODULE(obspython python obspython.i ../cstrcache.cpp ../cstrcache.h) +endif() SWIG_LINK_LIBRARIES(obspython obs-scripting libobs ${PYTHON_LIBRARIES}) function(install_plugin_bin_swig target additional_target) diff --git a/deps/w32-pthreads/.clang-format b/deps/w32-pthreads/.clang-format new file mode 100644 index 0000000..6420a46 --- /dev/null +++ b/deps/w32-pthreads/.clang-format @@ -0,0 +1,3 @@ +Language: Cpp +SortIncludes: false +DisableFormat: true diff --git a/docs/sphinx/reference-frontend-api.rst b/docs/sphinx/reference-frontend-api.rst index 3b5b86d..46df5bd 100644 --- a/docs/sphinx/reference-frontend-api.rst +++ b/docs/sphinx/reference-frontend-api.rst @@ -124,6 +124,18 @@ Structures/Enumerations the program is either about to load a new scene collection, or the program is about to exit. + - **OBS_FRONTEND_FINISHED_LOADING** + + Triggered when the program has finished loading. + + - **OBS_FRONTEND_EVENT_RECORDING_PAUSED** + + Triggered when the recording has been paused. + + - **OBS_FRONTEND_EVENT_RECORDING_UNPAUSED** + + Triggered when the recording has been unpaused. + .. type:: struct obs_frontend_source_list - DARRAY(obs_source_t*) **sources** @@ -402,6 +414,18 @@ Functions --------------------------------------- +.. function:: void obs_frontend_recording_pause(bool pause) + + :pause: *true* to pause recording, *false* to unpause. + +--------------------------------------- + +.. function:: bool obs_frontend_recording_paused(void) + + :return: *true* if recording paused, *false* otherwise. + +--------------------------------------- + .. function:: void obs_frontend_replay_buffer_start(void) Starts replay buffer. diff --git a/docs/sphinx/reference-outputs.rst b/docs/sphinx/reference-outputs.rst index e7c65b6..b0d397d 100644 --- a/docs/sphinx/reference-outputs.rst +++ b/docs/sphinx/reference-outputs.rst @@ -66,6 +66,14 @@ Output Definition Structure (obs_output_info) When this capability flag is used, specifies that this output supports multiple encoded audio tracks simultaneously. + - **OBS_OUTPUT_CAN_PAUSE** - Output supports pausing. + + When this capability flag is used, the output supports pausing. + When an output is paused, raw or encoded audio/video data will be + halted when paused down to the exact point to the closest video + frame. Audio data will be correctly truncated down to the exact + audio sample according to that video frame timing. + .. member:: const char *(*obs_output_info.get_name)(void *type_data) Get the translated name of the output type. @@ -170,13 +178,9 @@ Output Definition Structure (obs_output_info) :return: The properties of the output -.. member:: void (*obs_output_info.pause)(void *data) +.. member:: void (*obs_output_info.unused1)(void *data) - Pauses the output (if the output supports pausing). - - (Author's note: This is currently unimplemented) - - (Optional) + This callback is no longer used. .. member:: uint64_t (*obs_output_info.get_total_bytes)(void *data) @@ -257,6 +261,14 @@ Output Signals | OBS_OUTPUT_NO_SPACE - Ran out of disk space | OBS_OUTPUT_ENCODE_ERROR - Encoder error +**pause** (ptr output) + + Called when the output has been paused. + +**unpause** (ptr output) + + Called when the output has been unpaused. + **starting** (ptr output) Called when the output is starting. @@ -444,11 +456,18 @@ General Output Functions --------------------- -.. function:: void obs_output_pause(obs_output_t *output) +.. function:: bool obs_output_pause(obs_output_t *output, bool pause) Pause an output (if supported by the output). - (Author's Note: Not yet implemented) + :return: *true* if the output was paused successfuly, *false* + otherwise + +--------------------- + +.. function:: bool obs_output_paused(const obs_output_t *output) + + :return: *true* if the output is paused, *false* otherwise --------------------- @@ -808,6 +827,14 @@ Functions used by outputs | OBS_OUTPUT_UNSUPPORTED - The settings, video/audio format, or codecs are unsupported by this output | OBS_OUTPUT_NO_SPACE - Ran out of disk space +--------------------- + +.. function:: uint64_t obs_output_get_pause_offset(obs_output_t *output) + + Returns the current pause offset of the output. Used with raw + outputs to calculate system timestamps when using calculated + timestamps (see FFmpeg output for an example). + .. --------------------------------------------------------------------------- .. _libobs/obs-output.h: https://github.com/jp9000/obs-studio/blob/master/libobs/obs-output.h diff --git a/docs/sphinx/reference-scenes.rst b/docs/sphinx/reference-scenes.rst index 883b67e..250a9c7 100644 --- a/docs/sphinx/reference-scenes.rst +++ b/docs/sphinx/reference-scenes.rst @@ -139,6 +139,10 @@ Scene Signals Called when a scene item's visibility state changes. +**item_locked** (ptr scene, ptr item, bool locked) + + Called when a scene item has been locked or unlocked. + **item_select** (ptr scene, ptr item) **item_deselect** (ptr scene, ptr item) @@ -406,6 +410,13 @@ Scene Item Functions --------------------- +.. function:: bool obs_sceneitem_set_locked(obs_sceneitem_t *item, bool locked) + bool obs_sceneitem_locked(const obs_sceneitem_t *item) + + Sets/gets the locked/unlocked state of the scene item. + +--------------------- + .. function:: void obs_sceneitem_set_crop(obs_sceneitem_t *item, const struct obs_sceneitem_crop *crop) void obs_sceneitem_get_crop(const obs_sceneitem_t *item, struct obs_sceneitem_crop *crop) diff --git a/formatcode.sh b/formatcode.sh new file mode 100755 index 0000000..09f07ee --- /dev/null +++ b/formatcode.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Original source https://github.com/Project-OSRM/osrm-backend/blob/master/scripts/format.sh + +set +x +set -o errexit +set -o pipefail +set -o nounset + +# Runs the Clang Formatter in parallel on the code base. +# Return codes: +# - 1 there are files to be formatted +# - 0 everything looks fine + +# Get CPU count +OS=$(uname) +NPROC=1 +if [[ $OS = "Linux" ]] ; then + NPROC=$(nproc) +elif [[ ${OS} = "Darwin" ]] ; then + NPROC=$(sysctl -n hw.physicalcpu) +fi + +# Discover clang-format +if type clang-format-8 2> /dev/null ; then + CLANG_FORMAT=clang-format-8 +else + CLANG_FORMAT=clang-format +fi + +find . -type d \( -path ./deps -o -path ./cmake -o -path ./plugins/decklink/win -o -path ./plugins/decklink/mac -o -path ./plugins/decklink/linux \) -prune -type f -o -name '*.h' -or -name '*.hpp' -or -name '*.m' -or -name '*.mm' -or -name '*.c' -or -name '*.cpp' \ +| xargs -I{} -P ${NPROC} ${CLANG_FORMAT} -i -style=file -fallback-style=none {} \ No newline at end of file diff --git a/libobs-d3d11/d3d11-duplicator.cpp b/libobs-d3d11/d3d11-duplicator.cpp index 5bebb87..2316626 100644 --- a/libobs-d3d11/d3d11-duplicator.cpp +++ b/libobs-d3d11/d3d11-duplicator.cpp @@ -19,7 +19,7 @@ #include static inline bool get_monitor(gs_device_t *device, int monitor_idx, - IDXGIOutput **dxgiOutput) + IDXGIOutput **dxgiOutput) { HRESULT hr; @@ -44,7 +44,7 @@ void gs_duplicator::Start() throw "Invalid monitor index"; hr = output->QueryInterface(__uuidof(IDXGIOutput1), - (void**)output1.Assign()); + (void **)output1.Assign()); if (FAILED(hr)) throw HRError("Failed to query IDXGIOutput1", hr); @@ -54,11 +54,11 @@ void gs_duplicator::Start() } gs_duplicator::gs_duplicator(gs_device_t *device_, int monitor_idx) - : gs_obj (device_, gs_type::gs_duplicator), - texture (nullptr), - idx (monitor_idx), - refs (1), - updated (false) + : gs_obj(device_, gs_type::gs_duplicator), + texture(nullptr), + idx(monitor_idx), + refs(1), + updated(false) { Start(); } @@ -71,7 +71,8 @@ gs_duplicator::~gs_duplicator() extern "C" { EXPORT bool device_get_duplicator_monitor_info(gs_device_t *device, - int monitor_idx, struct gs_monitor_info *info) + int monitor_idx, + struct gs_monitor_info *info) { DXGI_OUTPUT_DESC desc; HRESULT hr; @@ -86,9 +87,11 @@ EXPORT bool device_get_duplicator_monitor_info(gs_device_t *device, if (FAILED(hr)) throw HRError("GetDesc failed", hr); - } catch (HRError error) { - blog(LOG_ERROR, "device_get_duplicator_monitor_info: " - "%s (%08lX)", error.str, error.hr); + } catch (const HRError &error) { + blog(LOG_ERROR, + "device_get_duplicator_monitor_info: " + "%s (%08lX)", + error.str, error.hr); return false; } @@ -119,7 +122,7 @@ EXPORT bool device_get_duplicator_monitor_info(gs_device_t *device, return true; } -static std::map instances; +static std::map instances; void reset_duplicators(void) { @@ -129,7 +132,7 @@ void reset_duplicators(void) } EXPORT gs_duplicator_t *device_duplicator_create(gs_device_t *device, - int monitor_idx) + int monitor_idx) { gs_duplicator *duplicator = nullptr; @@ -145,13 +148,12 @@ EXPORT gs_duplicator_t *device_duplicator_create(gs_device_t *device, instances[monitor_idx] = duplicator; } catch (const char *error) { - blog(LOG_DEBUG, "device_duplicator_create: %s", - error); + blog(LOG_DEBUG, "device_duplicator_create: %s", error); return nullptr; - } catch (HRError error) { + } catch (const HRError &error) { blog(LOG_DEBUG, "device_duplicator_create: %s (%08lX)", - error.str, error.hr); + error.str, error.hr); return nullptr; } @@ -171,20 +173,17 @@ static inline void copy_texture(gs_duplicator_t *d, ID3D11Texture2D *tex) D3D11_TEXTURE2D_DESC desc; tex->GetDesc(&desc); - if (!d->texture || - d->texture->width != desc.Width || + if (!d->texture || d->texture->width != desc.Width || d->texture->height != desc.Height) { delete d->texture; - d->texture = (gs_texture_2d*)gs_texture_create( - desc.Width, desc.Height, - ConvertDXGITextureFormat(desc.Format), 1, - nullptr, 0); + d->texture = (gs_texture_2d *)gs_texture_create( + desc.Width, desc.Height, + ConvertDXGITextureFormat(desc.Format), 1, nullptr, 0); } if (!!d->texture) - d->device->context->CopyResource(d->texture->texture, - tex); + d->device->context->CopyResource(d->texture->texture, tex); } EXPORT bool gs_duplicator_update_frame(gs_duplicator_t *d) @@ -209,16 +208,20 @@ EXPORT bool gs_duplicator_update_frame(gs_duplicator_t *d) return true; } else if (FAILED(hr)) { - blog(LOG_ERROR, "gs_duplicator_update_frame: Failed to update " - "frame (%08lX)", hr); + blog(LOG_ERROR, + "gs_duplicator_update_frame: Failed to update " + "frame (%08lX)", + hr); return true; } hr = res->QueryInterface(__uuidof(ID3D11Texture2D), - (void**)tex.Assign()); + (void **)tex.Assign()); if (FAILED(hr)) { - blog(LOG_ERROR, "gs_duplicator_update_frame: Failed to query " - "ID3D11Texture2D (%08lX)", hr); + blog(LOG_ERROR, + "gs_duplicator_update_frame: Failed to query " + "ID3D11Texture2D (%08lX)", + hr); d->duplicator->ReleaseFrame(); return true; } @@ -233,5 +236,4 @@ EXPORT gs_texture_t *gs_duplicator_get_texture(gs_duplicator_t *duplicator) { return duplicator->texture; } - } diff --git a/libobs-d3d11/d3d11-indexbuffer.cpp b/libobs-d3d11/d3d11-indexbuffer.cpp index d95139a..8cd48c7 100644 --- a/libobs-d3d11/d3d11-indexbuffer.cpp +++ b/libobs-d3d11/d3d11-indexbuffer.cpp @@ -21,14 +21,14 @@ void gs_index_buffer::InitBuffer() { HRESULT hr; - memset(&bd, 0, sizeof(bd)); + memset(&bd, 0, sizeof(bd)); memset(&srd, 0, sizeof(srd)); - bd.Usage = dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT; + bd.Usage = dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT; bd.CPUAccessFlags = dynamic ? D3D11_CPU_ACCESS_WRITE : 0; - bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - bd.ByteWidth = UINT(indexSize * num); - srd.pSysMem = indices.data; + bd.BindFlags = D3D11_BIND_INDEX_BUFFER; + bd.ByteWidth = UINT(indexSize * num); + srd.pSysMem = indices.data; hr = device->device->CreateBuffer(&bd, &srd, indexBuffer.Assign()); if (FAILED(hr)) @@ -36,16 +36,20 @@ void gs_index_buffer::InitBuffer() } gs_index_buffer::gs_index_buffer(gs_device_t *device, enum gs_index_type type, - void *indices, size_t num, uint32_t flags) - : gs_obj (device, gs_type::gs_index_buffer), - dynamic ((flags & GS_DYNAMIC) != 0), - type (type), - num (num), - indices (indices) + void *indices, size_t num, uint32_t flags) + : gs_obj(device, gs_type::gs_index_buffer), + dynamic((flags & GS_DYNAMIC) != 0), + type(type), + num(num), + indices(indices) { switch (type) { - case GS_UNSIGNED_SHORT: indexSize = 2; break; - case GS_UNSIGNED_LONG: indexSize = 4; break; + case GS_UNSIGNED_SHORT: + indexSize = 2; + break; + case GS_UNSIGNED_LONG: + indexSize = 4; + break; } InitBuffer(); diff --git a/libobs-d3d11/d3d11-rebuild.cpp b/libobs-d3d11/d3d11-rebuild.cpp index 6912cf7..db7dc3d 100644 --- a/libobs-d3d11/d3d11-rebuild.cpp +++ b/libobs-d3d11/d3d11-rebuild.cpp @@ -33,23 +33,23 @@ void gs_index_buffer::Rebuild(ID3D11Device *dev) void gs_texture_2d::RebuildSharedTextureFallback() { - td = {}; - td.Width = 2; - td.Height = 2; - td.MipLevels = 1; - td.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - td.ArraySize = 1; + td = {}; + td.Width = 2; + td.Height = 2; + td.MipLevels = 1; + td.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + td.ArraySize = 1; td.SampleDesc.Count = 1; - td.BindFlags = D3D11_BIND_SHADER_RESOURCE; + td.BindFlags = D3D11_BIND_SHADER_RESOURCE; - width = td.Width; - height = td.Height; + width = td.Width; + height = td.Height; dxgiFormat = td.Format; - levels = 1; + levels = 1; resourceDesc = {}; - resourceDesc.Format = td.Format; - resourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + resourceDesc.Format = td.Format; + resourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; resourceDesc.Texture2D.MipLevels = 1; isShared = false; @@ -60,18 +60,19 @@ void gs_texture_2d::Rebuild(ID3D11Device *dev) HRESULT hr; if (isShared) { hr = dev->OpenSharedResource((HANDLE)(uintptr_t)sharedHandle, - __uuidof(ID3D11Texture2D), (void**)&texture); + __uuidof(ID3D11Texture2D), + (void **)&texture); if (FAILED(hr)) { - blog(LOG_WARNING, "Failed to rebuild shared texture: ", - "0x%08lX", hr); + blog(LOG_WARNING, + "Failed to rebuild shared texture: ", "0x%08lX", + hr); RebuildSharedTextureFallback(); } } if (!isShared) { - hr = dev->CreateTexture2D(&td, - data.size() ? srd.data() : nullptr, - &texture); + hr = dev->CreateTexture2D( + &td, data.size() ? srd.data() : nullptr, &texture); if (FAILED(hr)) throw HRError("Failed to create 2D texture", hr); } @@ -85,7 +86,7 @@ void gs_texture_2d::Rebuild(ID3D11Device *dev) if (isGDICompatible) { hr = texture->QueryInterface(__uuidof(IDXGISurface1), - (void**)&gdiSurface); + (void **)&gdiSurface); if (FAILED(hr)) throw HRError("Failed to create GDI surface", hr); } @@ -172,12 +173,13 @@ void gs_sampler_state::Rebuild(ID3D11Device *dev) void gs_vertex_shader::Rebuild(ID3D11Device *dev) { HRESULT hr; - hr = dev->CreateVertexShader(data.data(), data.size(), nullptr, &shader); + hr = dev->CreateVertexShader(data.data(), data.size(), nullptr, + &shader); if (FAILED(hr)) throw HRError("Failed to create vertex shader", hr); hr = dev->CreateInputLayout(layoutData.data(), (UINT)layoutData.size(), - data.data(), data.size(), &layout); + data.data(), data.size(), &layout); if (FAILED(hr)) throw HRError("Failed to create input layout", hr); @@ -197,9 +199,8 @@ void gs_vertex_shader::Rebuild(ID3D11Device *dev) void gs_pixel_shader::Rebuild(ID3D11Device *dev) { HRESULT hr; - - hr = dev->CreatePixelShader(data.data(), data.size(), nullptr, - &shader); + + hr = dev->CreatePixelShader(data.data(), data.size(), nullptr, &shader); if (FAILED(hr)) throw HRError("Failed to create pixel shader", hr); @@ -224,6 +225,29 @@ void gs_swap_chain::Rebuild(ID3D11Device *dev) Init(); } +void gs_timer::Rebuild(ID3D11Device *dev) +{ + D3D11_QUERY_DESC desc; + desc.Query = D3D11_QUERY_TIMESTAMP; + desc.MiscFlags = 0; + HRESULT hr = dev->CreateQuery(&desc, &query_begin); + if (FAILED(hr)) + throw HRError("Failed to create timer", hr); + hr = dev->CreateQuery(&desc, &query_end); + if (FAILED(hr)) + throw HRError("Failed to create timer", hr); +} + +void gs_timer_range::Rebuild(ID3D11Device *dev) +{ + D3D11_QUERY_DESC desc; + desc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT; + desc.MiscFlags = 0; + HRESULT hr = dev->CreateQuery(&desc, &query_disjoint); + if (FAILED(hr)) + throw HRError("Failed to create timer", hr); +} + void SavedBlendState::Rebuild(ID3D11Device *dev) { HRESULT hr = dev->CreateBlendState(&bd, &state); @@ -245,8 +269,7 @@ void SavedRasterState::Rebuild(ID3D11Device *dev) throw HRError("Failed to create rasterizer state", hr); } -const static D3D_FEATURE_LEVEL featureLevels[] = -{ +const static D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, @@ -267,34 +290,40 @@ try { while (obj) { switch (obj->obj_type) { case gs_type::gs_vertex_buffer: - ((gs_vertex_buffer*)obj)->Release(); + ((gs_vertex_buffer *)obj)->Release(); break; case gs_type::gs_index_buffer: - ((gs_index_buffer*)obj)->Release(); + ((gs_index_buffer *)obj)->Release(); break; case gs_type::gs_texture_2d: - ((gs_texture_2d*)obj)->Release(); + ((gs_texture_2d *)obj)->Release(); break; case gs_type::gs_zstencil_buffer: - ((gs_zstencil_buffer*)obj)->Release(); + ((gs_zstencil_buffer *)obj)->Release(); break; case gs_type::gs_stage_surface: - ((gs_stage_surface*)obj)->Release(); + ((gs_stage_surface *)obj)->Release(); break; case gs_type::gs_sampler_state: - ((gs_sampler_state*)obj)->Release(); + ((gs_sampler_state *)obj)->Release(); break; case gs_type::gs_vertex_shader: - ((gs_vertex_shader*)obj)->Release(); + ((gs_vertex_shader *)obj)->Release(); break; case gs_type::gs_pixel_shader: - ((gs_pixel_shader*)obj)->Release(); + ((gs_pixel_shader *)obj)->Release(); break; case gs_type::gs_duplicator: - ((gs_duplicator*)obj)->Release(); + ((gs_duplicator *)obj)->Release(); break; case gs_type::gs_swap_chain: - ((gs_swap_chain*)obj)->Release(); + ((gs_swap_chain *)obj)->Release(); + break; + case gs_type::gs_timer: + ((gs_timer *)obj)->Release(); + break; + case gs_type::gs_timer_range: + ((gs_timer_range *)obj)->Release(); break; } @@ -320,10 +349,11 @@ try { InitFactory(adpIdx); uint32_t createFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; - hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, - nullptr, createFlags, featureLevels, - sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL), - D3D11_SDK_VERSION, &device, nullptr, &context); + hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, + createFlags, featureLevels, + sizeof(featureLevels) / + sizeof(D3D_FEATURE_LEVEL), + D3D11_SDK_VERSION, &device, nullptr, &context); if (FAILED(hr)) throw HRError("Failed to create device", hr); @@ -333,45 +363,49 @@ try { while (obj) { switch (obj->obj_type) { case gs_type::gs_vertex_buffer: - ((gs_vertex_buffer*)obj)->Rebuild(); + ((gs_vertex_buffer *)obj)->Rebuild(); break; case gs_type::gs_index_buffer: - ((gs_index_buffer*)obj)->Rebuild(dev); + ((gs_index_buffer *)obj)->Rebuild(dev); break; - case gs_type::gs_texture_2d: - { - gs_texture_2d *tex = (gs_texture_2d*)obj; - if (!tex->nv12) { - tex->Rebuild(dev); - } else if (!tex->chroma) { - tex->RebuildNV12_Y(dev); - } + case gs_type::gs_texture_2d: { + gs_texture_2d *tex = (gs_texture_2d *)obj; + if (!tex->nv12) { + tex->Rebuild(dev); + } else if (!tex->chroma) { + tex->RebuildNV12_Y(dev); } - break; + } break; case gs_type::gs_zstencil_buffer: - ((gs_zstencil_buffer*)obj)->Rebuild(dev); + ((gs_zstencil_buffer *)obj)->Rebuild(dev); break; case gs_type::gs_stage_surface: - ((gs_stage_surface*)obj)->Rebuild(dev); + ((gs_stage_surface *)obj)->Rebuild(dev); break; case gs_type::gs_sampler_state: - ((gs_sampler_state*)obj)->Rebuild(dev); + ((gs_sampler_state *)obj)->Rebuild(dev); break; case gs_type::gs_vertex_shader: - ((gs_vertex_shader*)obj)->Rebuild(dev); + ((gs_vertex_shader *)obj)->Rebuild(dev); break; case gs_type::gs_pixel_shader: - ((gs_pixel_shader*)obj)->Rebuild(dev); + ((gs_pixel_shader *)obj)->Rebuild(dev); break; case gs_type::gs_duplicator: try { - ((gs_duplicator*)obj)->Start(); + ((gs_duplicator *)obj)->Start(); } catch (...) { - ((gs_duplicator*)obj)->Release(); + ((gs_duplicator *)obj)->Release(); } break; case gs_type::gs_swap_chain: - ((gs_swap_chain*)obj)->Rebuild(dev); + ((gs_swap_chain *)obj)->Rebuild(dev); + break; + case gs_type::gs_timer: + ((gs_timer *)obj)->Rebuild(dev); + break; + case gs_type::gs_timer_range: + ((gs_timer_range *)obj)->Rebuild(dev); break; } @@ -406,7 +440,6 @@ try { } catch (const char *error) { bcrash("Failed to recreate D3D11: %s", error); -} catch (HRError error) { - bcrash("Failed to recreate D3D11: %s (%08lX)", - error.str, error.hr); +} catch (const HRError &error) { + bcrash("Failed to recreate D3D11: %s (%08lX)", error.str, error.hr); } diff --git a/libobs-d3d11/d3d11-samplerstate.cpp b/libobs-d3d11/d3d11-samplerstate.cpp index 67b4005..520b3ca 100644 --- a/libobs-d3d11/d3d11-samplerstate.cpp +++ b/libobs-d3d11/d3d11-samplerstate.cpp @@ -20,21 +20,26 @@ #include "d3d11-subsystem.hpp" -static inline D3D11_TEXTURE_ADDRESS_MODE ConvertGSAddressMode( - gs_address_mode mode) +static inline D3D11_TEXTURE_ADDRESS_MODE +ConvertGSAddressMode(gs_address_mode mode) { switch (mode) { - case GS_ADDRESS_WRAP: return D3D11_TEXTURE_ADDRESS_WRAP; - case GS_ADDRESS_CLAMP: return D3D11_TEXTURE_ADDRESS_CLAMP; - case GS_ADDRESS_MIRROR: return D3D11_TEXTURE_ADDRESS_MIRROR; - case GS_ADDRESS_BORDER: return D3D11_TEXTURE_ADDRESS_BORDER; - case GS_ADDRESS_MIRRORONCE: return D3D11_TEXTURE_ADDRESS_MIRROR_ONCE; + case GS_ADDRESS_WRAP: + return D3D11_TEXTURE_ADDRESS_WRAP; + case GS_ADDRESS_CLAMP: + return D3D11_TEXTURE_ADDRESS_CLAMP; + case GS_ADDRESS_MIRROR: + return D3D11_TEXTURE_ADDRESS_MIRROR; + case GS_ADDRESS_BORDER: + return D3D11_TEXTURE_ADDRESS_BORDER; + case GS_ADDRESS_MIRRORONCE: + return D3D11_TEXTURE_ADDRESS_MIRROR_ONCE; } return D3D11_TEXTURE_ADDRESS_WRAP; } -static inline D3D11_FILTER ConvertGSFilter( gs_sample_filter filter) +static inline D3D11_FILTER ConvertGSFilter(gs_sample_filter filter) { switch (filter) { case GS_FILTER_POINT: @@ -61,21 +66,20 @@ static inline D3D11_FILTER ConvertGSFilter( gs_sample_filter filter) } gs_sampler_state::gs_sampler_state(gs_device_t *device, - const gs_sampler_info *info) - : gs_obj (device, gs_type::gs_sampler_state), - info (*info) + const gs_sampler_info *info) + : gs_obj(device, gs_type::gs_sampler_state), info(*info) { HRESULT hr; vec4 v4; memset(&sd, 0, sizeof(sd)); - sd.AddressU = ConvertGSAddressMode(info->address_u); - sd.AddressV = ConvertGSAddressMode(info->address_v); - sd.AddressW = ConvertGSAddressMode(info->address_w); + sd.AddressU = ConvertGSAddressMode(info->address_u); + sd.AddressV = ConvertGSAddressMode(info->address_v); + sd.AddressW = ConvertGSAddressMode(info->address_w); sd.ComparisonFunc = D3D11_COMPARISON_ALWAYS; - sd.Filter = ConvertGSFilter(info->filter); - sd.MaxAnisotropy = info->max_anisotropy; - sd.MaxLOD = FLT_MAX; + sd.Filter = ConvertGSFilter(info->filter); + sd.MaxAnisotropy = info->max_anisotropy; + sd.MaxLOD = FLT_MAX; vec4_from_rgba(&v4, info->border_color); memcpy(sd.BorderColor, v4.ptr, sizeof(v4)); diff --git a/libobs-d3d11/d3d11-shader.cpp b/libobs-d3d11/d3d11-shader.cpp index 1a71048..6260ef8 100644 --- a/libobs-d3d11/d3d11-shader.cpp +++ b/libobs-d3d11/d3d11-shader.cpp @@ -23,7 +23,7 @@ #include void gs_vertex_shader::GetBuffersExpected( - const vector &inputs) + const vector &inputs) { for (size_t i = 0; i < inputs.size(); i++) { const D3D11_INPUT_ELEMENT_DESC &input = inputs[i]; @@ -39,17 +39,17 @@ void gs_vertex_shader::GetBuffersExpected( } gs_vertex_shader::gs_vertex_shader(gs_device_t *device, const char *file, - const char *shaderString) - : gs_shader (device, gs_type::gs_vertex_shader, GS_SHADER_VERTEX), - hasNormals (false), - hasColors (false), - hasTangents (false), - nTexUnits (0) + const char *shaderString) + : gs_shader(device, gs_type::gs_vertex_shader, GS_SHADER_VERTEX), + hasNormals(false), + hasColors(false), + hasTangents(false), + nTexUnits(0) { - ShaderProcessor processor(device); + ShaderProcessor processor(device); ComPtr shaderBlob; - string outputString; - HRESULT hr; + string outputString; + HRESULT hr; processor.Process(shaderString, file); processor.BuildString(outputString); @@ -63,29 +63,33 @@ gs_vertex_shader::gs_vertex_shader(gs_device_t *device, const char *file, data.resize(shaderBlob->GetBufferSize()); memcpy(&data[0], shaderBlob->GetBufferPointer(), data.size()); - hr = device->device->CreateVertexShader(data.data(), data.size(), - NULL, shader.Assign()); + hr = device->device->CreateVertexShader(data.data(), data.size(), NULL, + shader.Assign()); if (FAILED(hr)) throw HRError("Failed to create vertex shader", hr); - hr = device->device->CreateInputLayout(layoutData.data(), - (UINT)layoutData.size(), - data.data(), data.size(), layout.Assign()); - if (FAILED(hr)) - throw HRError("Failed to create input layout", hr); + const UINT layoutSize = (UINT)layoutData.size(); + if (layoutSize > 0) { + hr = device->device->CreateInputLayout(layoutData.data(), + (UINT)layoutSize, + data.data(), data.size(), + layout.Assign()); + if (FAILED(hr)) + throw HRError("Failed to create input layout", hr); + } viewProj = gs_shader_get_param_by_name(this, "ViewProj"); - world = gs_shader_get_param_by_name(this, "World"); + world = gs_shader_get_param_by_name(this, "World"); } gs_pixel_shader::gs_pixel_shader(gs_device_t *device, const char *file, - const char *shaderString) + const char *shaderString) : gs_shader(device, gs_type::gs_pixel_shader, GS_SHADER_PIXEL) { - ShaderProcessor processor(device); + ShaderProcessor processor(device); ComPtr shaderBlob; - string outputString; - HRESULT hr; + string outputString; + HRESULT hr; processor.Process(shaderString, file); processor.BuildString(outputString); @@ -98,8 +102,8 @@ gs_pixel_shader::gs_pixel_shader(gs_device_t *device, const char *file, data.resize(shaderBlob->GetBufferSize()); memcpy(&data[0], shaderBlob->GetBufferPointer(), data.size()); - hr = device->device->CreatePixelShader(data.data(), data.size(), - NULL, shader.Assign()); + hr = device->device->CreatePixelShader(data.data(), data.size(), NULL, + shader.Assign()); if (FAILED(hr)) throw HRError("Failed to create pixel shader", hr); } @@ -131,20 +135,28 @@ void gs_shader::BuildConstantBuffer() { for (size_t i = 0; i < params.size(); i++) { gs_shader_param ¶m = params[i]; - size_t size = 0; + size_t size = 0; switch (param.type) { case GS_SHADER_PARAM_BOOL: case GS_SHADER_PARAM_INT: - case GS_SHADER_PARAM_FLOAT: size = sizeof(float); break; + case GS_SHADER_PARAM_FLOAT: + size = sizeof(float); + break; case GS_SHADER_PARAM_INT2: - case GS_SHADER_PARAM_VEC2: size = sizeof(vec2); break; + case GS_SHADER_PARAM_VEC2: + size = sizeof(vec2); + break; case GS_SHADER_PARAM_INT3: - case GS_SHADER_PARAM_VEC3: size = sizeof(float)*3; break; + case GS_SHADER_PARAM_VEC3: + size = sizeof(float) * 3; + break; case GS_SHADER_PARAM_INT4: - case GS_SHADER_PARAM_VEC4: size = sizeof(vec4); break; + case GS_SHADER_PARAM_VEC4: + size = sizeof(vec4); + break; case GS_SHADER_PARAM_MATRIX4X4: - size = sizeof(float)*4*4; + size = sizeof(float) * 4 * 4; break; case GS_SHADER_PARAM_TEXTURE: case GS_SHADER_PARAM_STRING: @@ -164,7 +176,7 @@ void gs_shader::BuildConstantBuffer() constantSize = alignMax; } - param.pos = constantSize; + param.pos = constantSize; constantSize += size; } @@ -173,13 +185,13 @@ void gs_shader::BuildConstantBuffer() if (constantSize) { HRESULT hr; - bd.ByteWidth = (constantSize+15)&0xFFFFFFF0; /* align */ - bd.Usage = D3D11_USAGE_DYNAMIC; - bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + bd.ByteWidth = (constantSize + 15) & 0xFFFFFFF0; /* align */ + bd.Usage = D3D11_USAGE_DYNAMIC; + bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; hr = device->device->CreateBuffer(&bd, NULL, - constants.Assign()); + constants.Assign()); if (FAILED(hr)) throw HRError("Failed to create constant buffer", hr); } @@ -189,7 +201,7 @@ void gs_shader::BuildConstantBuffer() } void gs_shader::Compile(const char *shaderString, const char *file, - const char *target, ID3D10Blob **shader) + const char *target, ID3D10Blob **shader) { ComPtr errorsBlob; HRESULT hr; @@ -198,9 +210,9 @@ void gs_shader::Compile(const char *shaderString, const char *file, throw "No shader string specified"; hr = device->d3dCompile(shaderString, strlen(shaderString), file, NULL, - NULL, "main", target, - D3D10_SHADER_OPTIMIZATION_LEVEL1, 0, - shader, errorsBlob.Assign()); + NULL, "main", target, + D3D10_SHADER_OPTIMIZATION_LEVEL1, 0, shader, + errorsBlob.Assign()); if (FAILED(hr)) { if (errorsBlob != NULL && errorsBlob->GetBufferSize()) throw ShaderError(errorsBlob, hr); @@ -215,18 +227,19 @@ void gs_shader::Compile(const char *shaderString, const char *file, return; hr = device->d3dDisassemble((*shader)->GetBufferPointer(), - (*shader)->GetBufferSize(), 0, nullptr, &asmBlob); + (*shader)->GetBufferSize(), 0, nullptr, + &asmBlob); if (SUCCEEDED(hr) && !!asmBlob && asmBlob->GetBufferSize()) { blog(LOG_INFO, "============================================="); - blog(LOG_INFO, "Disassembly output for shader '%s':\n%s", - file, asmBlob->GetBufferPointer()); + blog(LOG_INFO, "Disassembly output for shader '%s':\n%s", file, + asmBlob->GetBufferPointer()); } #endif } inline void gs_shader::UpdateParam(vector &constData, - gs_shader_param ¶m, bool &upload) + gs_shader_param ¶m, bool &upload) { if (param.type != GS_SHADER_PARAM_TEXTURE) { if (!param.curValue.size()) @@ -235,30 +248,29 @@ inline void gs_shader::UpdateParam(vector &constData, /* padding in case the constant needs to start at a new * register */ if (param.pos > constData.size()) { - uint8_t zero = 0; + uint8_t zero = 0; constData.insert(constData.end(), - param.pos - constData.size(), zero); + param.pos - constData.size(), zero); } - constData.insert(constData.end(), - param.curValue.begin(), - param.curValue.end()); + constData.insert(constData.end(), param.curValue.begin(), + param.curValue.end()); if (param.changed) { upload = true; param.changed = false; } - } else if (param.curValue.size() == sizeof(gs_texture_t*)) { + } else if (param.curValue.size() == sizeof(gs_texture_t *)) { gs_texture_t *tex; - memcpy(&tex, param.curValue.data(), sizeof(gs_texture_t*)); + memcpy(&tex, param.curValue.data(), sizeof(gs_texture_t *)); device_load_texture(device, tex, param.textureID); if (param.nextSampler) { ID3D11SamplerState *state = param.nextSampler->state; device->context->PSSetSamplers(param.textureID, 1, - &state); + &state); param.nextSampler = nullptr; } } @@ -267,7 +279,7 @@ inline void gs_shader::UpdateParam(vector &constData, void gs_shader::UploadParams() { vector constData; - bool upload = false; + bool upload = false; constData.reserve(constantSize); @@ -282,7 +294,7 @@ void gs_shader::UploadParams() HRESULT hr; hr = device->context->Map(constants, 0, D3D11_MAP_WRITE_DISCARD, - 0, &map); + 0, &map); if (FAILED(hr)) throw HRError("Could not lock constant buffer", hr); @@ -324,7 +336,7 @@ gs_sparam_t *gs_shader_get_viewproj_matrix(const gs_shader_t *shader) if (shader->type != GS_SHADER_VERTEX) return NULL; - return static_cast(shader)->viewProj; + return static_cast(shader)->viewProj; } gs_sparam_t *gs_shader_get_world_matrix(const gs_shader_t *shader) @@ -332,11 +344,11 @@ gs_sparam_t *gs_shader_get_world_matrix(const gs_shader_t *shader) if (shader->type != GS_SHADER_VERTEX) return NULL; - return static_cast(shader)->world; + return static_cast(shader)->world; } void gs_shader_get_param_info(const gs_sparam_t *param, - struct gs_shader_param_info *info) + struct gs_shader_param_info *info) { if (!param) return; @@ -346,7 +358,7 @@ void gs_shader_get_param_info(const gs_sparam_t *param, } static inline void shader_setval_inline(gs_shader_param *param, - const void *data, size_t size) + const void *data, size_t size) { assert(param); if (!param) @@ -407,7 +419,7 @@ void gs_shader_set_vec4(gs_sparam_t *param, const struct vec4 *val) void gs_shader_set_texture(gs_sparam_t *param, gs_texture_t *val) { - shader_setval_inline(param, &val, sizeof(gs_texture_t*)); + shader_setval_inline(param, &val, sizeof(gs_texture_t *)); } void gs_shader_set_val(gs_sparam_t *param, const void *val, size_t size) @@ -419,7 +431,7 @@ void gs_shader_set_default(gs_sparam_t *param) { if (param->defaultValue.size()) shader_setval_inline(param, param->defaultValue.data(), - param->defaultValue.size()); + param->defaultValue.size()); } void gs_shader_set_next_sampler(gs_sparam_t *param, gs_samplerstate_t *sampler) diff --git a/libobs-d3d11/d3d11-shaderprocessor.cpp b/libobs-d3d11/d3d11-shaderprocessor.cpp index 7b0b14d..fbbc9d1 100644 --- a/libobs-d3d11/d3d11-shaderprocessor.cpp +++ b/libobs-d3d11/d3d11-shaderprocessor.cpp @@ -21,14 +21,14 @@ #include using namespace std; -static const char *semanticInputNames[] = - {"POSITION", "NORMAL", "COLOR", "TANGENT", "TEXCOORD"}; -static const char *semanticOutputNames[] = - {"SV_Position", "NORMAL", "COLOR", "TANGENT", "TEXCOORD"}; +static const char *semanticInputNames[] = {"POSITION", "NORMAL", "COLOR", + "TANGENT", "TEXCOORD", "VERTEXID"}; +static const char *semanticOutputNames[] = { + "SV_Position", "NORMAL", "COLOR", "TANGENT", "TEXCOORD", "VERTEXID"}; static const char *ConvertSemanticName(const char *name) { - const size_t num = sizeof(semanticInputNames) / sizeof(const char*); + const size_t num = sizeof(semanticInputNames) / sizeof(const char *); for (size_t i = 0; i < num; i++) { if (strcmp(name, semanticInputNames[i]) == 0) return semanticOutputNames[i]; @@ -37,8 +37,7 @@ static const char *ConvertSemanticName(const char *name) throw "Unknown Semantic Name"; } -static void GetSemanticInfo(shader_var *var, const char *&name, - uint32_t &index) +static void GetSemanticInfo(shader_var *var, const char *&name, uint32_t &index) { const char *mapping = var->mapping; const char *indexStr = mapping; @@ -48,12 +47,12 @@ static void GetSemanticInfo(shader_var *var, const char *&name, index = (*indexStr) ? strtol(indexStr, NULL, 10) : 0; string nameStr; - nameStr.assign(mapping, indexStr-mapping); + nameStr.assign(mapping, indexStr - mapping); name = ConvertSemanticName(nameStr.c_str()); } static void AddInputLayoutVar(shader_var *var, - vector &layout) + vector &layout) { D3D11_INPUT_ELEMENT_DESC ied; const char *semanticName; @@ -62,25 +61,31 @@ static void AddInputLayoutVar(shader_var *var, GetSemanticInfo(var, semanticName, semanticIndex); memset(&ied, 0, sizeof(ied)); - ied.SemanticName = semanticName; - ied.SemanticIndex = semanticIndex; + ied.SemanticName = semanticName; + ied.SemanticIndex = semanticIndex; ied.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; if (strcmp(var->mapping, "COLOR") == 0) { ied.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - } else if (strcmp(var->mapping, "POSITION") == 0 || - strcmp(var->mapping, "NORMAL") == 0 || - strcmp(var->mapping, "TANGENT") == 0) { + } else if (strcmp(var->mapping, "POSITION") == 0 || + strcmp(var->mapping, "NORMAL") == 0 || + strcmp(var->mapping, "TANGENT") == 0) { ied.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; } else if (astrcmp_n(var->mapping, "TEXCOORD", 8) == 0) { /* type is always a 'float' type */ switch (var->type[5]) { - case 0: ied.Format = DXGI_FORMAT_R32_FLOAT; break; - case '2': ied.Format = DXGI_FORMAT_R32G32_FLOAT; break; + case 0: + ied.Format = DXGI_FORMAT_R32_FLOAT; + break; + case '2': + ied.Format = DXGI_FORMAT_R32G32_FLOAT; + break; case '3': - case '4': ied.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; break; + case '4': + ied.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + break; } } @@ -88,7 +93,7 @@ static void AddInputLayoutVar(shader_var *var, } static inline bool SetSlot(vector &layout, - const char *name, uint32_t index, uint32_t &slotIdx) + const char *name, uint32_t index, uint32_t &slotIdx) { for (size_t i = 0; i < layout.size(); i++) { D3D11_INPUT_ELEMENT_DESC &input = layout[i]; @@ -103,21 +108,22 @@ static inline bool SetSlot(vector &layout, } static void BuildInputLayoutFromVars(shader_parser *parser, darray *vars, - vector &layout) + vector &layout) { - shader_var *array = (shader_var*)vars->array; + shader_var *array = (shader_var *)vars->array; for (size_t i = 0; i < vars->num; i++) { - shader_var *var = array+i; + shader_var *var = array + i; if (var->mapping) { - AddInputLayoutVar(var, layout); + if (strcmp(var->mapping, "VERTEXID") != 0) + AddInputLayoutVar(var, layout); } else { - shader_struct *st = shader_parser_getstruct(parser, - var->type); + shader_struct *st = + shader_parser_getstruct(parser, var->type); if (st) BuildInputLayoutFromVars(parser, &st->vars.da, - layout); + layout); } } @@ -133,11 +139,11 @@ static void BuildInputLayoutFromVars(shader_parser *parser, darray *vars, SetSlot(layout, "TANGENT", 0, slot); uint32_t index = 0; - while (SetSlot(layout, "TEXCOORD", index++, slot)); + while (SetSlot(layout, "TEXCOORD", index++, slot)) + ; } -void ShaderProcessor::BuildInputLayout( - vector &layout) +void ShaderProcessor::BuildInputLayout(vector &layout) { shader_func *func = shader_parser_getfunc(&parser, "main"); if (!func) @@ -147,11 +153,11 @@ void ShaderProcessor::BuildInputLayout( } gs_shader_param::gs_shader_param(shader_var &var, uint32_t &texCounter) - : name (var.name), - type (get_shader_param_type(var.type)), - textureID (texCounter), - arrayCount (var.array_count), - changed (false) + : name(var.name), + type(get_shader_param_type(var.type)), + textureID(texCounter), + arrayCount(var.array_count), + changed(false) { defaultValue.resize(var.default_val.num); memcpy(defaultValue.data(), var.default_val.array, var.default_val.num); @@ -163,7 +169,7 @@ gs_shader_param::gs_shader_param(shader_var &var, uint32_t &texCounter) } static inline void AddParam(shader_var &var, vector ¶ms, - uint32_t &texCounter) + uint32_t &texCounter) { if (var.var_type != SHADER_VAR_UNIFORM || strcmp(var.type, "sampler") == 0) @@ -181,7 +187,7 @@ void ShaderProcessor::BuildParams(vector ¶ms) } static inline void AddSampler(gs_device_t *device, shader_sampler &sampler, - vector> &samplers) + vector> &samplers) { gs_sampler_info si; shader_sampler_convert(&sampler, &si); @@ -197,6 +203,8 @@ void ShaderProcessor::BuildSamplers(vector> &samplers) void ShaderProcessor::BuildString(string &outputString) { stringstream output; + output << "static const bool obs_glsl_compile = false;\n\n"; + cf_token *token = cf_preprocessor_get_tokens(&parser.cfp.pp); while (token->type != CFTOKEN_NONE) { /* cheaply just replace specific tokens */ @@ -214,6 +222,8 @@ void ShaderProcessor::BuildString(string &outputString) throw "texture_rect is not supported in D3D"; else if (strref_cmp(&token->str, "sampler_state") == 0) output << "SamplerState"; + else if (strref_cmp(&token->str, "VERTEXID") == 0) + output << "SV_VertexID"; else output.write(token->str.array, token->str.len); diff --git a/libobs-d3d11/d3d11-shaderprocessor.hpp b/libobs-d3d11/d3d11-shaderprocessor.hpp index afc939c..6d09d5b 100644 --- a/libobs-d3d11/d3d11-shaderprocessor.hpp +++ b/libobs-d3d11/d3d11-shaderprocessor.hpp @@ -20,8 +20,8 @@ #include struct ShaderParser : shader_parser { - inline ShaderParser() {shader_parser_init(this);} - inline ~ShaderParser() {shader_parser_free(this);} + inline ShaderParser() { shader_parser_init(this); } + inline ~ShaderParser() { shader_parser_free(this); } }; struct ShaderProcessor { @@ -34,7 +34,5 @@ struct ShaderProcessor { void BuildString(string &outputString); void Process(const char *shader_string, const char *file); - inline ShaderProcessor(gs_device_t *device) : device(device) - { - } + inline ShaderProcessor(gs_device_t *device) : device(device) {} }; diff --git a/libobs-d3d11/d3d11-stagesurf.cpp b/libobs-d3d11/d3d11-stagesurf.cpp index efad5df..84e9eef 100644 --- a/libobs-d3d11/d3d11-stagesurf.cpp +++ b/libobs-d3d11/d3d11-stagesurf.cpp @@ -18,24 +18,24 @@ #include "d3d11-subsystem.hpp" gs_stage_surface::gs_stage_surface(gs_device_t *device, uint32_t width, - uint32_t height, gs_color_format colorFormat) - : gs_obj (device, gs_type::gs_stage_surface), - width (width), - height (height), - format (colorFormat), - dxgiFormat (ConvertGSTextureFormat(colorFormat)) + uint32_t height, gs_color_format colorFormat) + : gs_obj(device, gs_type::gs_stage_surface), + width(width), + height(height), + format(colorFormat), + dxgiFormat(ConvertGSTextureFormat(colorFormat)) { HRESULT hr; memset(&td, 0, sizeof(td)); - td.Width = width; - td.Height = height; - td.MipLevels = 1; - td.ArraySize = 1; - td.Format = dxgiFormat; + td.Width = width; + td.Height = height; + td.MipLevels = 1; + td.ArraySize = 1; + td.Format = dxgiFormat; td.SampleDesc.Count = 1; - td.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - td.Usage = D3D11_USAGE_STAGING; + td.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + td.Usage = D3D11_USAGE_STAGING; hr = device->device->CreateTexture2D(&td, NULL, texture.Assign()); if (FAILED(hr)) @@ -43,24 +43,24 @@ gs_stage_surface::gs_stage_surface(gs_device_t *device, uint32_t width, } gs_stage_surface::gs_stage_surface(gs_device_t *device, uint32_t width, - uint32_t height) - : gs_obj (device, gs_type::gs_stage_surface), - width (width), - height (height), - format (GS_UNKNOWN), - dxgiFormat (DXGI_FORMAT_NV12) + uint32_t height) + : gs_obj(device, gs_type::gs_stage_surface), + width(width), + height(height), + format(GS_UNKNOWN), + dxgiFormat(DXGI_FORMAT_NV12) { HRESULT hr; memset(&td, 0, sizeof(td)); - td.Width = width; - td.Height = height; - td.MipLevels = 1; - td.ArraySize = 1; - td.Format = dxgiFormat; + td.Width = width; + td.Height = height; + td.MipLevels = 1; + td.ArraySize = 1; + td.Format = dxgiFormat; td.SampleDesc.Count = 1; - td.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - td.Usage = D3D11_USAGE_STAGING; + td.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + td.Usage = D3D11_USAGE_STAGING; hr = device->device->CreateTexture2D(&td, NULL, texture.Assign()); if (FAILED(hr)) diff --git a/libobs-d3d11/d3d11-subsystem.cpp b/libobs-d3d11/d3d11-subsystem.cpp index 6b7a005..1fd20a9 100644 --- a/libobs-d3d11/d3d11-subsystem.cpp +++ b/libobs-d3d11/d3d11-subsystem.cpp @@ -33,26 +33,27 @@ struct UnsupportedHWError : HRError { #ifdef _MSC_VER /* alignment warning - despite the fact that alignment is already fixed */ -#pragma warning (disable : 4316) +#pragma warning(disable : 4316) #endif static inline void LogD3D11ErrorDetails(HRError error, gs_device_t *device) { if (error.hr == DXGI_ERROR_DEVICE_REMOVED) { HRESULT DeviceRemovedReason = - device->device->GetDeviceRemovedReason(); + device->device->GetDeviceRemovedReason(); blog(LOG_ERROR, " Device Removed Reason: %08lX", - DeviceRemovedReason); + DeviceRemovedReason); } } -static const IID dxgiFactory2 = -{0x50c83a1c, 0xe072, 0x4c48, {0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0}}; +static const IID dxgiFactory2 = {0x50c83a1c, + 0xe072, + 0x4c48, + {0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, + 0xd0}}; - -gs_obj::gs_obj(gs_device_t *device_, gs_type type) : - device (device_), - obj_type (type) +gs_obj::gs_obj(gs_device_t *device_, gs_type type) + : device(device_), obj_type(type) { prev_next = &device->first_obj; next = device->first_obj; @@ -70,40 +71,40 @@ gs_obj::~gs_obj() } static inline void make_swap_desc(DXGI_SWAP_CHAIN_DESC &desc, - const gs_init_data *data) + const gs_init_data *data) { memset(&desc, 0, sizeof(desc)); - desc.BufferCount = data->num_backbuffers; + desc.BufferCount = data->num_backbuffers; desc.BufferDesc.Format = ConvertGSTextureFormat(data->format); - desc.BufferDesc.Width = data->cx; + desc.BufferDesc.Width = data->cx; desc.BufferDesc.Height = data->cy; - desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - desc.OutputWindow = (HWND)data->window.hwnd; - desc.SampleDesc.Count = 1; - desc.Windowed = true; + desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + desc.OutputWindow = (HWND)data->window.hwnd; + desc.SampleDesc.Count = 1; + desc.Windowed = true; } void gs_swap_chain::InitTarget(uint32_t cx, uint32_t cy) { HRESULT hr; - target.width = cx; + target.width = cx; target.height = cy; hr = swap->GetBuffer(0, __uuidof(ID3D11Texture2D), - (void**)target.texture.Assign()); + (void **)target.texture.Assign()); if (FAILED(hr)) throw HRError("Failed to get swap buffer texture", hr); - hr = device->device->CreateRenderTargetView(target.texture, NULL, - target.renderTarget[0].Assign()); + hr = device->device->CreateRenderTargetView( + target.texture, NULL, target.renderTarget[0].Assign()); if (FAILED(hr)) throw HRError("Failed to create swap render target view", hr); } void gs_swap_chain::InitZStencilBuffer(uint32_t cx, uint32_t cy) { - zs.width = cx; + zs.width = cx; zs.height = cy; if (zs.format != GS_ZS_NONE && cx != 0 && cy != 0) { @@ -129,8 +130,10 @@ void gs_swap_chain::Resize(uint32_t cx, uint32_t cy) if (cx == 0 || cy == 0) { GetClientRect(hwnd, &clientRect); - if (cx == 0) cx = clientRect.right; - if (cy == 0) cy = clientRect.bottom; + if (cx == 0) + cx = clientRect.right; + if (cy == 0) + cy = clientRect.bottom; } hr = swap->ResizeBuffers(numBuffers, cx, cy, target.dxgiFormat, 0); @@ -143,29 +146,29 @@ void gs_swap_chain::Resize(uint32_t cx, uint32_t cy) void gs_swap_chain::Init() { - target.device = device; + target.device = device; target.isRenderTarget = true; - target.format = initData.format; - target.dxgiFormat = ConvertGSTextureFormat(initData.format); + target.format = initData.format; + target.dxgiFormat = ConvertGSTextureFormat(initData.format); InitTarget(initData.cx, initData.cy); - zs.device = device; - zs.format = initData.zsformat; + zs.device = device; + zs.format = initData.zsformat; zs.dxgiFormat = ConvertGSZStencilFormat(initData.zsformat); InitZStencilBuffer(initData.cx, initData.cy); } gs_swap_chain::gs_swap_chain(gs_device *device, const gs_init_data *data) - : gs_obj (device, gs_type::gs_swap_chain), - numBuffers (data->num_backbuffers), - hwnd ((HWND)data->window.hwnd), - initData (*data) + : gs_obj(device, gs_type::gs_swap_chain), + numBuffers(data->num_backbuffers), + hwnd((HWND)data->window.hwnd), + initData(*data) { HRESULT hr; make_swap_desc(swapDesc, data); hr = device->factory->CreateSwapChain(device->device, &swapDesc, - swap.Assign()); + swap.Assign()); if (FAILED(hr)) throw HRError("Failed to create swap chain", hr); @@ -186,11 +189,11 @@ void gs_device::InitCompiler() HMODULE module = LoadLibraryA(d3dcompiler); if (module) { d3dCompile = (pD3DCompile)GetProcAddress(module, - "D3DCompile"); + "D3DCompile"); #ifdef DISASSEMBLE_SHADERS d3dDisassemble = (pD3DDisassemble)GetProcAddress( - module, "D3DDisassemble"); + module, "D3DDisassemble"); #endif if (d3dCompile) { return; @@ -203,17 +206,17 @@ void gs_device::InitCompiler() } throw "Could not find any D3DCompiler libraries. Make sure you've " - "installed the " - "DirectX components that OBS Studio requires."; + "installed the " + "DirectX components that OBS Studio requires."; } void gs_device::InitFactory(uint32_t adapterIdx) { HRESULT hr; - IID factoryIID = (GetWinVer() >= 0x602) ? dxgiFactory2 : - __uuidof(IDXGIFactory1); + IID factoryIID = (GetWinVer() >= 0x602) ? dxgiFactory2 + : __uuidof(IDXGIFactory1); - hr = CreateDXGIFactory1(factoryIID, (void**)factory.Assign()); + hr = CreateDXGIFactory1(factoryIID, (void **)factory.Assign()); if (FAILED(hr)) throw UnsupportedHWError("Failed to create DXGIFactory", hr); @@ -222,8 +225,7 @@ void gs_device::InitFactory(uint32_t adapterIdx) throw UnsupportedHWError("Failed to enumerate DXGIAdapter", hr); } -const static D3D_FEATURE_LEVEL featureLevels[] = -{ +const static D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, @@ -232,24 +234,28 @@ const static D3D_FEATURE_LEVEL featureLevels[] = /* ------------------------------------------------------------------------- */ -#define VERT_IN_OUT "\ +#define VERT_IN_OUT \ + "\ struct VertInOut { \ float4 pos : POSITION; \ }; " -#define NV12_Y_PS VERT_IN_OUT "\ +#define NV12_Y_PS \ + VERT_IN_OUT "\ float main(VertInOut vert_in) : TARGET \ { \ return 1.0; \ }" -#define NV12_UV_PS VERT_IN_OUT "\ +#define NV12_UV_PS \ + VERT_IN_OUT "\ float2 main(VertInOut vert_in) : TARGET \ { \ return float2(1.0, 1.0); \ }" -#define NV12_VS VERT_IN_OUT "\ +#define NV12_VS \ + VERT_IN_OUT "\ VertInOut main(VertInOut vert_in) \ { \ VertInOut vert_out; \ @@ -266,23 +272,23 @@ bool gs_device::HasBadNV12Output() try { vec3 points[4]; vec3_set(&points[0], -1.0f, -1.0f, 0.0f); - vec3_set(&points[1], -1.0f, 1.0f, 0.0f); - vec3_set(&points[2], 1.0f, -1.0f, 0.0f); - vec3_set(&points[3], 1.0f, 1.0f, 0.0f); + vec3_set(&points[1], -1.0f, 1.0f, 0.0f); + vec3_set(&points[2], 1.0f, -1.0f, 0.0f); + vec3_set(&points[3], 1.0f, 1.0f, 0.0f); gs_texture_2d nv12_y(this, NV12_CX, NV12_CY, GS_R8, 1, nullptr, - GS_RENDER_TARGET | GS_SHARED_KM_TEX, GS_TEXTURE_2D, - false, true); + GS_RENDER_TARGET | GS_SHARED_KM_TEX, GS_TEXTURE_2D, + false, true); gs_texture_2d nv12_uv(this, nv12_y.texture, - GS_RENDER_TARGET | GS_SHARED_KM_TEX); + GS_RENDER_TARGET | GS_SHARED_KM_TEX); gs_vertex_shader nv12_vs(this, "", NV12_VS); gs_pixel_shader nv12_y_ps(this, "", NV12_Y_PS); gs_pixel_shader nv12_uv_ps(this, "", NV12_UV_PS); gs_stage_surface nv12_stage(this, NV12_CX, NV12_CY); gs_vb_data *vbd = gs_vbdata_create(); - vbd->num = 4; - vbd->points = (vec3*)bmemdup(&points, sizeof(points)); + vbd->num = 4; + vbd->points = (vec3 *)bmemdup(&points, sizeof(points)); gs_vertex_buffer buf(this, vbd, 0); @@ -304,7 +310,7 @@ try { UpdateZStencilState(); context->Draw(4, 0); - device_set_viewport(this, 0, 0, NV12_CX/2, NV12_CY/2); + device_set_viewport(this, 0, 0, NV12_CX / 2, NV12_CY / 2); device_set_render_target(this, &nv12_uv, nullptr); device_load_pixelshader(this, &nv12_uv_ps); UpdateBlendState(); @@ -313,6 +319,7 @@ try { context->Draw(4, 0); device_load_pixelshader(this, nullptr); + device_load_vertexbuffer(this, nullptr); device_load_vertexshader(this, nullptr); device_set_render_target(this, nullptr, nullptr); @@ -335,9 +342,9 @@ try { } return bad_driver; -} catch (HRError error) { - blog(LOG_WARNING, "HasBadNV12Output failed: %s (%08lX)", - error.str, error.hr); +} catch (const HRError &error) { + blog(LOG_WARNING, "HasBadNV12Output failed: %s (%08lX)", error.str, + error.hr); return false; } catch (const char *error) { blog(LOG_WARNING, "HasBadNV12Output failed: %s", error); @@ -358,30 +365,36 @@ void gs_device::InitDevice(uint32_t adapterIdx) //createFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif - adapterName = (adapter->GetDesc(&desc) == S_OK) ? desc.Description : - L""; + adapterName = (adapter->GetDesc(&desc) == S_OK) ? desc.Description + : L""; BPtr adapterNameUTF8; os_wcs_to_utf8_ptr(adapterName.c_str(), 0, &adapterNameUTF8); blog(LOG_INFO, "Loading up D3D11 on adapter %s (%" PRIu32 ")", - adapterNameUTF8.Get(), adapterIdx); + adapterNameUTF8.Get(), adapterIdx); - hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, - NULL, createFlags, featureLevels, - sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL), - D3D11_SDK_VERSION, device.Assign(), - &levelUsed, context.Assign()); + hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, + createFlags, featureLevels, + sizeof(featureLevels) / + sizeof(D3D_FEATURE_LEVEL), + D3D11_SDK_VERSION, device.Assign(), &levelUsed, + context.Assign()); if (FAILED(hr)) throw UnsupportedHWError("Failed to create device", hr); - blog(LOG_INFO, "D3D11 loaded successfully, feature level used: %u", - (unsigned int)levelUsed); + blog(LOG_INFO, "D3D11 loaded successfully, feature level used: %x", + (unsigned int)levelUsed); /* ---------------------------------------- */ /* check for nv12 texture output support */ nv12Supported = false; + /* Intel CopyResource is very slow with NV12 */ + if (desc.VendorId == 0x8086) { + return; + } + ComQIPtr d3d11_1(device); if (!d3d11_1) { return; @@ -389,18 +402,15 @@ void gs_device::InitDevice(uint32_t adapterIdx) /* needs to support extended resource sharing */ D3D11_FEATURE_DATA_D3D11_OPTIONS opts = {}; - hr = d3d11_1->CheckFeatureSupport( - D3D11_FEATURE_D3D11_OPTIONS, - &opts, sizeof(opts)); + hr = d3d11_1->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &opts, + sizeof(opts)); if (FAILED(hr) || !opts.ExtendedResourceSharing) { return; } /* needs to support the actual format */ UINT support = 0; - hr = device->CheckFormatSupport( - DXGI_FORMAT_NV12, - &support); + hr = device->CheckFormatSupport(DXGI_FORMAT_NV12, &support); if (FAILED(hr)) { return; } @@ -422,12 +432,12 @@ void gs_device::InitDevice(uint32_t adapterIdx) } static inline void ConvertStencilSide(D3D11_DEPTH_STENCILOP_DESC &desc, - const StencilSide &side) + const StencilSide &side) { - desc.StencilFunc = ConvertGSDepthTest(side.test); - desc.StencilFailOp = ConvertGSStencilOp(side.fail); + desc.StencilFunc = ConvertGSDepthTest(side.test); + desc.StencilFailOp = ConvertGSStencilOp(side.fail); desc.StencilDepthFailOp = ConvertGSStencilOp(side.zfail); - desc.StencilPassOp = ConvertGSStencilOp(side.zpass); + desc.StencilPassOp = ConvertGSStencilOp(side.zpass); } ID3D11DepthStencilState *gs_device::AddZStencilState() @@ -436,16 +446,18 @@ ID3D11DepthStencilState *gs_device::AddZStencilState() D3D11_DEPTH_STENCIL_DESC dsd; ID3D11DepthStencilState *state; - dsd.DepthEnable = zstencilState.depthEnabled; - dsd.DepthFunc = ConvertGSDepthTest(zstencilState.depthFunc); - dsd.DepthWriteMask = zstencilState.depthWriteEnabled ? - D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; - dsd.StencilEnable = zstencilState.stencilEnabled; - dsd.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; - dsd.StencilWriteMask = zstencilState.stencilWriteEnabled ? - D3D11_DEFAULT_STENCIL_WRITE_MASK : 0; + dsd.DepthEnable = zstencilState.depthEnabled; + dsd.DepthFunc = ConvertGSDepthTest(zstencilState.depthFunc); + dsd.DepthWriteMask = zstencilState.depthWriteEnabled + ? D3D11_DEPTH_WRITE_MASK_ALL + : D3D11_DEPTH_WRITE_MASK_ZERO; + dsd.StencilEnable = zstencilState.stencilEnabled; + dsd.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + dsd.StencilWriteMask = zstencilState.stencilWriteEnabled + ? D3D11_DEFAULT_STENCIL_WRITE_MASK + : 0; ConvertStencilSide(dsd.FrontFace, zstencilState.stencilFront); - ConvertStencilSide(dsd.BackFace, zstencilState.stencilBack); + ConvertStencilSide(dsd.BackFace, zstencilState.stencilBack); SavedZStencilState savedState(zstencilState, dsd); hr = device->CreateDepthStencilState(&dsd, savedState.state.Assign()); @@ -467,10 +479,10 @@ ID3D11RasterizerState *gs_device::AddRasterState() memset(&rd, 0, sizeof(rd)); /* use CCW to convert to a right-handed coordinate system */ rd.FrontCounterClockwise = true; - rd.FillMode = D3D11_FILL_SOLID; - rd.CullMode = ConvertGSCullMode(rasterState.cullMode); - rd.DepthClipEnable = true; - rd.ScissorEnable = rasterState.scissorEnabled; + rd.FillMode = D3D11_FILL_SOLID; + rd.CullMode = ConvertGSCullMode(rasterState.cullMode); + rd.DepthClipEnable = true; + rd.ScissorEnable = rasterState.scissorEnabled; SavedRasterState savedState(rasterState, rd); hr = device->CreateRasterizerState(&rd, savedState.state.Assign()); @@ -491,9 +503,9 @@ ID3D11BlendState *gs_device::AddBlendState() memset(&bd, 0, sizeof(bd)); for (int i = 0; i < 8; i++) { - bd.RenderTarget[i].BlendEnable = blendState.blendEnabled; - bd.RenderTarget[i].BlendOp = D3D11_BLEND_OP_ADD; - bd.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD; + bd.RenderTarget[i].BlendEnable = blendState.blendEnabled; + bd.RenderTarget[i].BlendOp = D3D11_BLEND_OP_ADD; + bd.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD; bd.RenderTarget[i].SrcBlend = ConvertGSBlendType(blendState.srcFactorC); bd.RenderTarget[i].DestBlend = @@ -503,10 +515,16 @@ ID3D11BlendState *gs_device::AddBlendState() bd.RenderTarget[i].DestBlendAlpha = ConvertGSBlendType(blendState.destFactorA); bd.RenderTarget[i].RenderTargetWriteMask = - (blendState.redEnabled ? D3D11_COLOR_WRITE_ENABLE_RED : 0) | - (blendState.greenEnabled ? D3D11_COLOR_WRITE_ENABLE_GREEN : 0) | - (blendState.blueEnabled ? D3D11_COLOR_WRITE_ENABLE_BLUE : 0) | - (blendState.alphaEnabled ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0) ; + (blendState.redEnabled ? D3D11_COLOR_WRITE_ENABLE_RED + : 0) | + (blendState.greenEnabled + ? D3D11_COLOR_WRITE_ENABLE_GREEN + : 0) | + (blendState.blueEnabled ? D3D11_COLOR_WRITE_ENABLE_BLUE + : 0) | + (blendState.alphaEnabled + ? D3D11_COLOR_WRITE_ENABLE_ALPHA + : 0); } SavedBlendState savedState(blendState, bd); @@ -614,11 +632,11 @@ void gs_device::UpdateViewProjMatrix() if (curVertexShader->viewProj) gs_shader_set_matrix4(curVertexShader->viewProj, - &curViewProjMatrix); + &curViewProjMatrix); } gs_device::gs_device(uint32_t adapterIdx) - : curToplogy (D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED) + : curToplogy(D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED) { matrix4_identity(&curProjMatrix); matrix4_identity(&curViewMatrix); @@ -657,19 +675,18 @@ const char *device_preprocessor_name(void) return "_D3D11"; } -static inline void EnumD3DAdapters( - bool (*callback)(void*, const char*, uint32_t), - void *param) +static inline void +EnumD3DAdapters(bool (*callback)(void *, const char *, uint32_t), void *param) { ComPtr factory; ComPtr adapter; HRESULT hr; UINT i; - IID factoryIID = (GetWinVer() >= 0x602) ? dxgiFactory2 : - __uuidof(IDXGIFactory1); + IID factoryIID = (GetWinVer() >= 0x602) ? dxgiFactory2 + : __uuidof(IDXGIFactory1); - hr = CreateDXGIFactory1(factoryIID, (void**)factory.Assign()); + hr = CreateDXGIFactory1(factoryIID, (void **)factory.Assign()); if (FAILED(hr)) throw HRError("Failed to create DXGIFactory", hr); @@ -692,17 +709,17 @@ static inline void EnumD3DAdapters( } } -bool device_enum_adapters( - bool (*callback)(void *param, const char *name, uint32_t id), - void *param) +bool device_enum_adapters(bool (*callback)(void *param, const char *name, + uint32_t id), + void *param) { try { EnumD3DAdapters(callback, param); return true; - } catch (HRError error) { + } catch (const HRError &error) { blog(LOG_WARNING, "Failed enumerating devices: %s (%08lX)", - error.str, error.hr); + error.str, error.hr); return false; } } @@ -718,14 +735,14 @@ static inline void LogAdapterMonitors(IDXGIAdapter1 *adapter) continue; RECT rect = desc.DesktopCoordinates; - blog(LOG_INFO, "\t output %u: " - "pos={%d, %d}, " - "size={%d, %d}, " - "attached=%s", - i, - rect.left, rect.top, - rect.right - rect.left, rect.bottom - rect.top, - desc.AttachedToDesktop ? "true" : "false"); + blog(LOG_INFO, + "\t output %u: " + "pos={%d, %d}, " + "size={%d, %d}, " + "attached=%s", + i, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, + desc.AttachedToDesktop ? "true" : "false"); } } @@ -738,10 +755,10 @@ static inline void LogD3DAdapters() blog(LOG_INFO, "Available Video Adapters: "); - IID factoryIID = (GetWinVer() >= 0x602) ? dxgiFactory2 : - __uuidof(IDXGIFactory1); + IID factoryIID = (GetWinVer() >= 0x602) ? dxgiFactory2 + : __uuidof(IDXGIFactory1); - hr = CreateDXGIFactory1(factoryIID, (void**)factory.Assign()); + hr = CreateDXGIFactory1(factoryIID, (void **)factory.Assign()); if (FAILED(hr)) throw HRError("Failed to create DXGIFactory", hr); @@ -760,9 +777,9 @@ static inline void LogD3DAdapters() os_wcs_to_utf8(desc.Description, 0, name, sizeof(name)); blog(LOG_INFO, "\tAdapter %u: %s", i, name); blog(LOG_INFO, "\t Dedicated VRAM: %u", - desc.DedicatedVideoMemory); + desc.DedicatedVideoMemory); blog(LOG_INFO, "\t Shared VRAM: %u", - desc.SharedSystemMemory); + desc.SharedSystemMemory); LogAdapterMonitors(adapter); } @@ -780,14 +797,14 @@ int device_create(gs_device_t **p_device, uint32_t adapter) device = new gs_device(adapter); - } catch (UnsupportedHWError error) { + } catch (const UnsupportedHWError &error) { blog(LOG_ERROR, "device_create (D3D11): %s (%08lX)", error.str, - error.hr); + error.hr); errorcode = GS_ERROR_NOT_SUPPORTED; - } catch (HRError error) { + } catch (const HRError &error) { blog(LOG_ERROR, "device_create (D3D11): %s (%08lX)", error.str, - error.hr); + error.hr); errorcode = GS_ERROR_FAIL; } @@ -812,16 +829,21 @@ void device_leave_context(gs_device_t *device) UNUSED_PARAMETER(device); } +void *device_get_device_obj(gs_device_t *device) +{ + return (void *)device->device.Get(); +} + gs_swapchain_t *device_swapchain_create(gs_device_t *device, - const struct gs_init_data *data) + const struct gs_init_data *data) { gs_swap_chain *swap = NULL; try { swap = new gs_swap_chain(device, data); - } catch (HRError error) { + } catch (const HRError &error) { blog(LOG_ERROR, "device_swapchain_create (D3D11): %s (%08lX)", - error.str, error.hr); + error.str, error.hr); LogD3D11ErrorDetails(error, device); } @@ -837,7 +859,7 @@ void device_resize(gs_device_t *device, uint32_t cx, uint32_t cy) try { ID3D11RenderTargetView *renderView = NULL; - ID3D11DepthStencilView *depthView = NULL; + ID3D11DepthStencilView *depthView = NULL; int i = device->curRenderSide; device->context->OMSetRenderTargets(1, &renderView, depthView); @@ -846,12 +868,12 @@ void device_resize(gs_device_t *device, uint32_t cx, uint32_t cy) if (device->curRenderTarget) renderView = device->curRenderTarget->renderTarget[i]; if (device->curZStencilBuffer) - depthView = device->curZStencilBuffer->view; + depthView = device->curZStencilBuffer->view; device->context->OMSetRenderTargets(1, &renderView, depthView); - } catch (HRError error) { - blog(LOG_ERROR, "device_resize (D3D11): %s (%08lX)", - error.str, error.hr); + } catch (const HRError &error) { + blog(LOG_ERROR, "device_resize (D3D11): %s (%08lX)", error.str, + error.hr); LogD3D11ErrorDetails(error, device); } } @@ -889,16 +911,19 @@ uint32_t device_get_height(const gs_device_t *device) } gs_texture_t *device_texture_create(gs_device_t *device, uint32_t width, - uint32_t height, enum gs_color_format color_format, - uint32_t levels, const uint8_t **data, uint32_t flags) + uint32_t height, + enum gs_color_format color_format, + uint32_t levels, const uint8_t **data, + uint32_t flags) { gs_texture *texture = NULL; try { texture = new gs_texture_2d(device, width, height, color_format, - levels, data, flags, GS_TEXTURE_2D, false); - } catch (HRError error) { + levels, data, flags, GS_TEXTURE_2D, + false); + } catch (const HRError &error) { blog(LOG_ERROR, "device_texture_create (D3D11): %s (%08lX)", - error.str, error.hr); + error.str, error.hr); LogD3D11ErrorDetails(error, device); } catch (const char *error) { blog(LOG_ERROR, "device_texture_create (D3D11): %s", error); @@ -908,30 +933,33 @@ gs_texture_t *device_texture_create(gs_device_t *device, uint32_t width, } gs_texture_t *device_cubetexture_create(gs_device_t *device, uint32_t size, - enum gs_color_format color_format, uint32_t levels, - const uint8_t **data, uint32_t flags) + enum gs_color_format color_format, + uint32_t levels, const uint8_t **data, + uint32_t flags) { gs_texture *texture = NULL; try { texture = new gs_texture_2d(device, size, size, color_format, - levels, data, flags, GS_TEXTURE_CUBE, false); - } catch (HRError error) { - blog(LOG_ERROR, "device_cubetexture_create (D3D11): %s " - "(%08lX)", - error.str, error.hr); + levels, data, flags, + GS_TEXTURE_CUBE, false); + } catch (const HRError &error) { + blog(LOG_ERROR, + "device_cubetexture_create (D3D11): %s " + "(%08lX)", + error.str, error.hr); LogD3D11ErrorDetails(error, device); } catch (const char *error) { - blog(LOG_ERROR, "device_cubetexture_create (D3D11): %s", - error); + blog(LOG_ERROR, "device_cubetexture_create (D3D11): %s", error); } return texture; } gs_texture_t *device_voltexture_create(gs_device_t *device, uint32_t width, - uint32_t height, uint32_t depth, - enum gs_color_format color_format, uint32_t levels, - const uint8_t **data, uint32_t flags) + uint32_t height, uint32_t depth, + enum gs_color_format color_format, + uint32_t levels, const uint8_t **data, + uint32_t flags) { /* TODO */ UNUSED_PARAMETER(device); @@ -946,15 +974,16 @@ gs_texture_t *device_voltexture_create(gs_device_t *device, uint32_t width, } gs_zstencil_t *device_zstencil_create(gs_device_t *device, uint32_t width, - uint32_t height, enum gs_zstencil_format format) + uint32_t height, + enum gs_zstencil_format format) { gs_zstencil_buffer *zstencil = NULL; try { - zstencil = new gs_zstencil_buffer(device, width, height, - format); - } catch (HRError error) { + zstencil = + new gs_zstencil_buffer(device, width, height, format); + } catch (const HRError &error) { blog(LOG_ERROR, "device_zstencil_create (D3D11): %s (%08lX)", - error.str, error.hr); + error.str, error.hr); LogD3D11ErrorDetails(error, device); } @@ -962,32 +991,36 @@ gs_zstencil_t *device_zstencil_create(gs_device_t *device, uint32_t width, } gs_stagesurf_t *device_stagesurface_create(gs_device_t *device, uint32_t width, - uint32_t height, enum gs_color_format color_format) + uint32_t height, + enum gs_color_format color_format) { gs_stage_surface *surf = NULL; try { surf = new gs_stage_surface(device, width, height, - color_format); - } catch (HRError error) { - blog(LOG_ERROR, "device_stagesurface_create (D3D11): %s " - "(%08lX)", - error.str, error.hr); + color_format); + } catch (const HRError &error) { + blog(LOG_ERROR, + "device_stagesurface_create (D3D11): %s " + "(%08lX)", + error.str, error.hr); LogD3D11ErrorDetails(error, device); } return surf; } -gs_samplerstate_t *device_samplerstate_create(gs_device_t *device, - const struct gs_sampler_info *info) +gs_samplerstate_t * +device_samplerstate_create(gs_device_t *device, + const struct gs_sampler_info *info) { gs_sampler_state *ss = NULL; try { ss = new gs_sampler_state(device, info); - } catch (HRError error) { - blog(LOG_ERROR, "device_samplerstate_create (D3D11): %s " - "(%08lX)", - error.str, error.hr); + } catch (const HRError &error) { + blog(LOG_ERROR, + "device_samplerstate_create (D3D11): %s " + "(%08lX)", + error.str, error.hr); LogD3D11ErrorDetails(error, device); } @@ -995,100 +1028,136 @@ gs_samplerstate_t *device_samplerstate_create(gs_device_t *device, } gs_shader_t *device_vertexshader_create(gs_device_t *device, - const char *shader_string, const char *file, - char **error_string) + const char *shader_string, + const char *file, char **error_string) { gs_vertex_shader *shader = NULL; try { shader = new gs_vertex_shader(device, file, shader_string); - } catch (HRError error) { - blog(LOG_ERROR, "device_vertexshader_create (D3D11): %s " - "(%08lX)", - error.str, error.hr); + } catch (const HRError &error) { + blog(LOG_ERROR, + "device_vertexshader_create (D3D11): %s " + "(%08lX)", + error.str, error.hr); LogD3D11ErrorDetails(error, device); - } catch (ShaderError error) { - const char *buf = (const char*)error.errors->GetBufferPointer(); + } catch (const ShaderError &error) { + const char *buf = + (const char *)error.errors->GetBufferPointer(); if (error_string) *error_string = bstrdup(buf); - blog(LOG_ERROR, "device_vertexshader_create (D3D11): " - "Compile warnings/errors for %s:\n%s", - file, buf); + blog(LOG_ERROR, + "device_vertexshader_create (D3D11): " + "Compile warnings/errors for %s:\n%s", + file, buf); } catch (const char *error) { blog(LOG_ERROR, "device_vertexshader_create (D3D11): %s", - error); + error); } return shader; } gs_shader_t *device_pixelshader_create(gs_device_t *device, - const char *shader_string, const char *file, - char **error_string) + const char *shader_string, + const char *file, char **error_string) { gs_pixel_shader *shader = NULL; try { shader = new gs_pixel_shader(device, file, shader_string); - } catch (HRError error) { - blog(LOG_ERROR, "device_pixelshader_create (D3D11): %s " - "(%08lX)", - error.str, error.hr); + } catch (const HRError &error) { + blog(LOG_ERROR, + "device_pixelshader_create (D3D11): %s " + "(%08lX)", + error.str, error.hr); LogD3D11ErrorDetails(error, device); - } catch (ShaderError error) { - const char *buf = (const char*)error.errors->GetBufferPointer(); + } catch (const ShaderError &error) { + const char *buf = + (const char *)error.errors->GetBufferPointer(); if (error_string) *error_string = bstrdup(buf); - blog(LOG_ERROR, "device_pixelshader_create (D3D11): " - "Compiler warnings/errors for %s:\n%s", - file, buf); + blog(LOG_ERROR, + "device_pixelshader_create (D3D11): " + "Compiler warnings/errors for %s:\n%s", + file, buf); } catch (const char *error) { - blog(LOG_ERROR, "device_pixelshader_create (D3D11): %s", - error); + blog(LOG_ERROR, "device_pixelshader_create (D3D11): %s", error); } return shader; } gs_vertbuffer_t *device_vertexbuffer_create(gs_device_t *device, - struct gs_vb_data *data, uint32_t flags) + struct gs_vb_data *data, + uint32_t flags) { gs_vertex_buffer *buffer = NULL; try { buffer = new gs_vertex_buffer(device, data, flags); - } catch (HRError error) { - blog(LOG_ERROR, "device_vertexbuffer_create (D3D11): %s " - "(%08lX)", - error.str, error.hr); + } catch (const HRError &error) { + blog(LOG_ERROR, + "device_vertexbuffer_create (D3D11): %s " + "(%08lX)", + error.str, error.hr); LogD3D11ErrorDetails(error, device); } catch (const char *error) { blog(LOG_ERROR, "device_vertexbuffer_create (D3D11): %s", - error); + error); } return buffer; } gs_indexbuffer_t *device_indexbuffer_create(gs_device_t *device, - enum gs_index_type type, void *indices, size_t num, - uint32_t flags) + enum gs_index_type type, + void *indices, size_t num, + uint32_t flags) { gs_index_buffer *buffer = NULL; try { buffer = new gs_index_buffer(device, type, indices, num, flags); - } catch (HRError error) { + } catch (const HRError &error) { blog(LOG_ERROR, "device_indexbuffer_create (D3D11): %s (%08lX)", - error.str, error.hr); + error.str, error.hr); LogD3D11ErrorDetails(error, device); } return buffer; } +gs_timer_t *device_timer_create(gs_device_t *device) +{ + gs_timer *timer = NULL; + try { + timer = new gs_timer(device); + } catch (const HRError &error) { + blog(LOG_ERROR, "device_timer_create (D3D11): %s (%08lX)", + error.str, error.hr); + LogD3D11ErrorDetails(error, device); + } + + return timer; +} + +gs_timer_range_t *device_timer_range_create(gs_device_t *device) +{ + gs_timer_range *range = NULL; + try { + range = new gs_timer_range(device); + } catch (const HRError &error) { + blog(LOG_ERROR, "device_timer_range_create (D3D11): %s (%08lX)", + error.str, error.hr); + LogD3D11ErrorDetails(error, device); + } + + return range; +} + enum gs_texture_type device_get_texture_type(const gs_texture_t *texture) { return texture->type; @@ -1100,23 +1169,24 @@ void gs_device::LoadVertexBufferData() curVertexShader == lastVertexShader) return; - vector buffers; + vector buffers; vector strides; vector offsets; if (curVertexBuffer && curVertexShader) { - curVertexBuffer->MakeBufferList(curVertexShader, - buffers, strides); + curVertexBuffer->MakeBufferList(curVertexShader, buffers, + strides); } else { - size_t buffersToClear = curVertexShader - ? curVertexShader->NumBuffersExpected() : 0; + size_t buffersToClear = + curVertexShader ? curVertexShader->NumBuffersExpected() + : 0; buffers.resize(buffersToClear); strides.resize(buffersToClear); } offsets.resize(buffers.size()); - context->IASetVertexBuffers(0, (UINT)buffers.size(), - buffers.data(), strides.data(), offsets.data()); + context->IASetVertexBuffers(0, (UINT)buffers.size(), buffers.data(), + strides.data(), offsets.data()); lastVertexBuffer = curVertexBuffer; lastVertexShader = curVertexShader; @@ -1140,9 +1210,13 @@ void device_load_indexbuffer(gs_device_t *device, gs_indexbuffer_t *indexbuffer) if (indexbuffer) { switch (indexbuffer->indexSize) { - case 2: format = DXGI_FORMAT_R16_UINT; break; + case 2: + format = DXGI_FORMAT_R16_UINT; + break; default: - case 4: format = DXGI_FORMAT_R32_UINT; break; + case 4: + format = DXGI_FORMAT_R32_UINT; + break; } buffer = indexbuffer->indexBuffer; @@ -1170,7 +1244,7 @@ void device_load_texture(gs_device_t *device, gs_texture_t *tex, int unit) } void device_load_samplerstate(gs_device_t *device, - gs_samplerstate_t *samplerstate, int unit) + gs_samplerstate_t *samplerstate, int unit) { ID3D11SamplerState *state = NULL; @@ -1186,25 +1260,25 @@ void device_load_samplerstate(gs_device_t *device, void device_load_vertexshader(gs_device_t *device, gs_shader_t *vertshader) { - ID3D11VertexShader *shader = NULL; - ID3D11InputLayout *layout = NULL; - ID3D11Buffer *constants = NULL; + ID3D11VertexShader *shader = NULL; + ID3D11InputLayout *layout = NULL; + ID3D11Buffer *constants = NULL; if (device->curVertexShader == vertshader) return; - gs_vertex_shader *vs = static_cast(vertshader); + gs_vertex_shader *vs = static_cast(vertshader); if (vertshader) { if (vertshader->type != GS_SHADER_VERTEX) { blog(LOG_ERROR, "device_load_vertexshader (D3D11): " - "Specified shader is not a vertex " - "shader"); + "Specified shader is not a vertex " + "shader"); return; } - shader = vs->shader; - layout = vs->layout; + shader = vs->shader; + layout = vs->layout; constants = vs->constants; } @@ -1217,31 +1291,31 @@ void device_load_vertexshader(gs_device_t *device, gs_shader_t *vertshader) static inline void clear_textures(gs_device_t *device) { ID3D11ShaderResourceView *views[GS_MAX_TEXTURES]; - memset(views, 0, sizeof(views)); + memset(views, 0, sizeof(views)); memset(device->curTextures, 0, sizeof(device->curTextures)); device->context->PSSetShaderResources(0, GS_MAX_TEXTURES, views); } void device_load_pixelshader(gs_device_t *device, gs_shader_t *pixelshader) { - ID3D11PixelShader *shader = NULL; - ID3D11Buffer *constants = NULL; + ID3D11PixelShader *shader = NULL; + ID3D11Buffer *constants = NULL; ID3D11SamplerState *states[GS_MAX_TEXTURES]; if (device->curPixelShader == pixelshader) return; - gs_pixel_shader *ps = static_cast(pixelshader); + gs_pixel_shader *ps = static_cast(pixelshader); if (pixelshader) { if (pixelshader->type != GS_SHADER_PIXEL) { blog(LOG_ERROR, "device_load_pixelshader (D3D11): " - "Specified shader is not a pixel " - "shader"); + "Specified shader is not a pixel " + "shader"); return; } - shader = ps->shader; + shader = ps->shader; constants = ps->constants; ps->GetSamplerStates(states); } else { @@ -1257,7 +1331,7 @@ void device_load_pixelshader(gs_device_t *device, gs_shader_t *pixelshader) for (int i = 0; i < GS_MAX_TEXTURES; i++) if (device->curSamplers[i] && - device->curSamplers[i]->state != states[i]) + device->curSamplers[i]->state != states[i]) device->curSamplers[i] = nullptr; } @@ -1296,7 +1370,7 @@ gs_zstencil_t *device_get_zstencil_target(const gs_device_t *device) } void device_set_render_target(gs_device_t *device, gs_texture_t *tex, - gs_zstencil_t *zstencil) + gs_zstencil_t *zstencil) { if (device->curSwapChain) { if (!tex) @@ -1305,34 +1379,35 @@ void device_set_render_target(gs_device_t *device, gs_texture_t *tex, zstencil = &device->curSwapChain->zs; } - if (device->curRenderTarget == tex && + if (device->curRenderTarget == tex && device->curZStencilBuffer == zstencil) return; if (tex && tex->type != GS_TEXTURE_2D) { blog(LOG_ERROR, "device_set_render_target (D3D11): " - "texture is not a 2D texture"); + "texture is not a 2D texture"); return; } - gs_texture_2d *tex2d = static_cast(tex); + gs_texture_2d *tex2d = static_cast(tex); if (tex2d && !tex2d->renderTarget[0]) { blog(LOG_ERROR, "device_set_render_target (D3D11): " - "texture is not a render target"); + "texture is not a render target"); return; } - ID3D11RenderTargetView *rt = tex2d ? tex2d->renderTarget[0] : nullptr; + ID3D11RenderTargetView *rt = tex2d ? tex2d->renderTarget[0].Get() + : nullptr; - device->curRenderTarget = tex2d; - device->curRenderSide = 0; + device->curRenderTarget = tex2d; + device->curRenderSide = 0; device->curZStencilBuffer = zstencil; - device->context->OMSetRenderTargets(1, &rt, - zstencil ? zstencil->view : nullptr); + device->context->OMSetRenderTargets( + 1, &rt, zstencil ? zstencil->view : nullptr); } void device_set_cube_render_target(gs_device_t *device, gs_texture_t *tex, - int side, gs_zstencil_t *zstencil) + int side, gs_zstencil_t *zstencil) { if (device->curSwapChain) { if (!tex) { @@ -1344,18 +1419,17 @@ void device_set_cube_render_target(gs_device_t *device, gs_texture_t *tex, zstencil = &device->curSwapChain->zs; } - if (device->curRenderTarget == tex && - device->curRenderSide == side && + if (device->curRenderTarget == tex && device->curRenderSide == side && device->curZStencilBuffer == zstencil) return; if (tex->type != GS_TEXTURE_CUBE) { blog(LOG_ERROR, "device_set_cube_render_target (D3D11): " - "texture is not a cube texture"); + "texture is not a cube texture"); return; } - gs_texture_2d *tex2d = static_cast(tex); + gs_texture_2d *tex2d = static_cast(tex); if (!tex2d->renderTarget[side]) { blog(LOG_ERROR, "device_set_cube_render_target (D3D11): " "texture is not a render target"); @@ -1364,24 +1438,23 @@ void device_set_cube_render_target(gs_device_t *device, gs_texture_t *tex, ID3D11RenderTargetView *rt = tex2d->renderTarget[0]; - device->curRenderTarget = tex2d; - device->curRenderSide = side; + device->curRenderTarget = tex2d; + device->curRenderSide = side; device->curZStencilBuffer = zstencil; device->context->OMSetRenderTargets(1, &rt, zstencil->view); } -inline void gs_device::CopyTex(ID3D11Texture2D *dst, - uint32_t dst_x, uint32_t dst_y, - gs_texture_t *src, uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) +inline void gs_device::CopyTex(ID3D11Texture2D *dst, uint32_t dst_x, + uint32_t dst_y, gs_texture_t *src, + uint32_t src_x, uint32_t src_y, uint32_t src_w, + uint32_t src_h) { if (src->type != GS_TEXTURE_2D) throw "Source texture must be a 2D texture"; - gs_texture_2d *tex2d = static_cast(src); + gs_texture_2d *tex2d = static_cast(src); - if (dst_x == 0 && dst_y == 0 && - src_x == 0 && src_y == 0 && + if (dst_x == 0 && dst_y == 0 && src_x == 0 && src_y == 0 && src_w == 0 && src_h == 0) { context->CopyResource(dst, tex2d->texture); } else { @@ -1403,18 +1476,18 @@ inline void gs_device::CopyTex(ID3D11Texture2D *dst, sbox.back = 1; context->CopySubresourceRegion(dst, 0, dst_x, dst_y, 0, - tex2d->texture, 0, &sbox); + tex2d->texture, 0, &sbox); } } -void device_copy_texture_region(gs_device_t *device, - gs_texture_t *dst, uint32_t dst_x, uint32_t dst_y, - gs_texture_t *src, uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) +void device_copy_texture_region(gs_device_t *device, gs_texture_t *dst, + uint32_t dst_x, uint32_t dst_y, + gs_texture_t *src, uint32_t src_x, + uint32_t src_y, uint32_t src_w, uint32_t src_h) { try { - gs_texture_2d *src2d = static_cast(src); - gs_texture_2d *dst2d = static_cast(dst); + gs_texture_2d *src2d = static_cast(src); + gs_texture_2d *dst2d = static_cast(dst); if (!src) throw "Source texture is NULL"; @@ -1429,44 +1502,43 @@ void device_copy_texture_region(gs_device_t *device, /* apparently casting to the same type that the variable * already exists as is supposed to prevent some warning * when used with the conditional operator? */ - uint32_t copyWidth = (uint32_t)src_w ? - (uint32_t)src_w : (src2d->width - src_x); - uint32_t copyHeight = (uint32_t)src_h ? - (uint32_t)src_h : (src2d->height - src_y); + uint32_t copyWidth = (uint32_t)src_w ? (uint32_t)src_w + : (src2d->width - src_x); + uint32_t copyHeight = (uint32_t)src_h ? (uint32_t)src_h + : (src2d->height - src_y); - uint32_t dstWidth = dst2d->width - dst_x; + uint32_t dstWidth = dst2d->width - dst_x; uint32_t dstHeight = dst2d->height - dst_y; if (dstWidth < copyWidth || dstHeight < copyHeight) throw "Destination texture region is not big " "enough to hold the source region"; - if (dst_x == 0 && dst_y == 0 && - src_x == 0 && src_y == 0 && + if (dst_x == 0 && dst_y == 0 && src_x == 0 && src_y == 0 && src_w == 0 && src_h == 0) { - copyWidth = 0; + copyWidth = 0; copyHeight = 0; } - device->CopyTex(dst2d->texture, dst_x, dst_y, - src, src_x, src_y, copyWidth, copyHeight); + device->CopyTex(dst2d->texture, dst_x, dst_y, src, src_x, src_y, + copyWidth, copyHeight); - } catch(const char *error) { + } catch (const char *error) { blog(LOG_ERROR, "device_copy_texture (D3D11): %s", error); } } void device_copy_texture(gs_device_t *device, gs_texture_t *dst, - gs_texture_t *src) + gs_texture_t *src) { device_copy_texture_region(device, dst, 0, 0, src, 0, 0, 0, 0); } void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst, - gs_texture_t *src) + gs_texture_t *src) { try { - gs_texture_2d *src2d = static_cast(src); + gs_texture_2d *src2d = static_cast(src); if (!src) throw "Source texture is NULL"; @@ -1476,8 +1548,7 @@ void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst, throw "Destination surface is NULL"; if (dst->format != GS_UNKNOWN && dst->format != src->format) throw "Source and destination formats do not match"; - if (dst->width != src2d->width || - dst->height != src2d->height) + if (dst->width != src2d->width || dst->height != src2d->height) throw "Source and destination must have the same " "dimensions"; @@ -1494,7 +1565,7 @@ void device_begin_scene(gs_device_t *device) } void device_draw(gs_device_t *device, enum gs_draw_mode draw_mode, - uint32_t start_vert, uint32_t num_verts) + uint32_t start_vert, uint32_t num_verts) { try { if (!device->curVertexShader) @@ -1503,7 +1574,7 @@ void device_draw(gs_device_t *device, enum gs_draw_mode draw_mode, if (!device->curPixelShader) throw "No pixel shader specified"; - if (!device->curVertexBuffer) + if (!device->curVertexBuffer && (num_verts == 0)) throw "No vertex buffer specified"; if (!device->curSwapChain && !device->curRenderTarget) @@ -1525,9 +1596,9 @@ void device_draw(gs_device_t *device, enum gs_draw_mode draw_mode, blog(LOG_ERROR, "device_draw (D3D11): %s", error); return; - } catch (HRError error) { + } catch (const HRError &error) { blog(LOG_ERROR, "device_draw (D3D11): %s (%08lX)", error.str, - error.hr); + error.hr); LogD3D11ErrorDetails(error, device); return; } @@ -1557,10 +1628,12 @@ void device_end_scene(gs_device_t *device) void device_load_swapchain(gs_device_t *device, gs_swapchain_t *swapchain) { - gs_texture_t *target = device->curRenderTarget; - gs_zstencil_t *zs = device->curZStencilBuffer; - bool is_cube = device->curRenderTarget ? - (device->curRenderTarget->type == GS_TEXTURE_CUBE) : false; + gs_texture_t *target = device->curRenderTarget; + gs_zstencil_t *zs = device->curZStencilBuffer; + bool is_cube = + device->curRenderTarget + ? (device->curRenderTarget->type == GS_TEXTURE_CUBE) + : false; if (device->curSwapChain) { if (target == &device->curSwapChain->target) @@ -1573,19 +1646,19 @@ void device_load_swapchain(gs_device_t *device, gs_swapchain_t *swapchain) if (is_cube) device_set_cube_render_target(device, target, - device->curRenderSide, zs); + device->curRenderSide, zs); else device_set_render_target(device, target, zs); } void device_clear(gs_device_t *device, uint32_t clear_flags, - const struct vec4 *color, float depth, uint8_t stencil) + const struct vec4 *color, float depth, uint8_t stencil) { int side = device->curRenderSide; if ((clear_flags & GS_CLEAR_COLOR) != 0 && device->curRenderTarget) device->context->ClearRenderTargetView( - device->curRenderTarget->renderTarget[side], - color->ptr); + device->curRenderTarget->renderTarget[side], + color->ptr); if (device->curZStencilBuffer) { uint32_t flags = 0; @@ -1596,8 +1669,8 @@ void device_clear(gs_device_t *device, uint32_t clear_flags, if (flags && device->curZStencilBuffer->view) device->context->ClearDepthStencilView( - device->curZStencilBuffer->view, - flags, depth, stencil); + device->curZStencilBuffer->view, flags, depth, + stencil); } } @@ -1674,53 +1747,55 @@ void device_enable_stencil_write(gs_device_t *device, bool enable) device->zstencilStateChanged = true; } -void device_enable_color(gs_device_t *device, bool red, bool green, - bool blue, bool alpha) +void device_enable_color(gs_device_t *device, bool red, bool green, bool blue, + bool alpha) { - if (device->blendState.redEnabled == red && + if (device->blendState.redEnabled == red && device->blendState.greenEnabled == green && - device->blendState.blueEnabled == blue && + device->blendState.blueEnabled == blue && device->blendState.alphaEnabled == alpha) return; - device->blendState.redEnabled = red; + device->blendState.redEnabled = red; device->blendState.greenEnabled = green; - device->blendState.blueEnabled = blue; + device->blendState.blueEnabled = blue; device->blendState.alphaEnabled = alpha; - device->blendStateChanged = true; + device->blendStateChanged = true; } void device_blend_function(gs_device_t *device, enum gs_blend_type src, - enum gs_blend_type dest) + enum gs_blend_type dest) { - if (device->blendState.srcFactorC == src && + if (device->blendState.srcFactorC == src && device->blendState.destFactorC == dest && - device->blendState.srcFactorA == src && + device->blendState.srcFactorA == src && device->blendState.destFactorA == dest) return; device->blendState.srcFactorC = src; - device->blendState.destFactorC= dest; + device->blendState.destFactorC = dest; device->blendState.srcFactorA = src; - device->blendState.destFactorA= dest; - device->blendStateChanged = true; + device->blendState.destFactorA = dest; + device->blendStateChanged = true; } void device_blend_function_separate(gs_device_t *device, - enum gs_blend_type src_c, enum gs_blend_type dest_c, - enum gs_blend_type src_a, enum gs_blend_type dest_a) + enum gs_blend_type src_c, + enum gs_blend_type dest_c, + enum gs_blend_type src_a, + enum gs_blend_type dest_a) { - if (device->blendState.srcFactorC == src_c && + if (device->blendState.srcFactorC == src_c && device->blendState.destFactorC == dest_c && - device->blendState.srcFactorA == src_a && + device->blendState.srcFactorA == src_a && device->blendState.destFactorA == dest_a) return; - device->blendState.srcFactorC = src_c; + device->blendState.srcFactorC = src_c; device->blendState.destFactorC = dest_c; - device->blendState.srcFactorA = src_a; + device->blendState.srcFactorA = src_a; device->blendState.destFactorA = dest_a; - device->blendStateChanged = true; + device->blendStateChanged = true; } void device_depth_function(gs_device_t *device, enum gs_depth_test test) @@ -1729,11 +1804,12 @@ void device_depth_function(gs_device_t *device, enum gs_depth_test test) return; device->zstencilState.depthFunc = test; - device->zstencilStateChanged = true; + device->zstencilStateChanged = true; } static inline void update_stencilside_test(gs_device_t *device, - StencilSide &side, gs_depth_test test) + StencilSide &side, + gs_depth_test test) { if (side.test == test) return; @@ -1743,61 +1819,62 @@ static inline void update_stencilside_test(gs_device_t *device, } void device_stencil_function(gs_device_t *device, enum gs_stencil_side side, - enum gs_depth_test test) + enum gs_depth_test test) { int sideVal = (int)side; if (sideVal & GS_STENCIL_FRONT) - update_stencilside_test(device, - device->zstencilState.stencilFront, test); + update_stencilside_test( + device, device->zstencilState.stencilFront, test); if (sideVal & GS_STENCIL_BACK) - update_stencilside_test(device, - device->zstencilState.stencilBack, test); + update_stencilside_test( + device, device->zstencilState.stencilBack, test); } static inline void update_stencilside_op(gs_device_t *device, StencilSide &side, - enum gs_stencil_op_type fail, enum gs_stencil_op_type zfail, - enum gs_stencil_op_type zpass) + enum gs_stencil_op_type fail, + enum gs_stencil_op_type zfail, + enum gs_stencil_op_type zpass) { if (side.fail == fail && side.zfail == zfail && side.zpass == zpass) return; - side.fail = fail; + side.fail = fail; side.zfail = zfail; side.zpass = zpass; device->zstencilStateChanged = true; } void device_stencil_op(gs_device_t *device, enum gs_stencil_side side, - enum gs_stencil_op_type fail, enum gs_stencil_op_type zfail, - enum gs_stencil_op_type zpass) + enum gs_stencil_op_type fail, + enum gs_stencil_op_type zfail, + enum gs_stencil_op_type zpass) { int sideVal = (int)side; if (sideVal & GS_STENCIL_FRONT) update_stencilside_op(device, - device->zstencilState.stencilFront, - fail, zfail, zpass); + device->zstencilState.stencilFront, fail, + zfail, zpass); if (sideVal & GS_STENCIL_BACK) - update_stencilside_op(device, - device->zstencilState.stencilBack, - fail, zfail, zpass); + update_stencilside_op(device, device->zstencilState.stencilBack, + fail, zfail, zpass); } void device_set_viewport(gs_device_t *device, int x, int y, int width, - int height) + int height) { D3D11_VIEWPORT vp; memset(&vp, 0, sizeof(vp)); vp.MaxDepth = 1.0f; vp.TopLeftX = (float)x; vp.TopLeftY = (float)y; - vp.Width = (float)width; - vp.Height = (float)height; + vp.Width = (float)width; + vp.Height = (float)height; device->context->RSSetViewports(1, &vp); - device->viewport.x = x; - device->viewport.y = y; + device->viewport.x = x; + device->viewport.y = y; device->viewport.cx = width; device->viewport.cy = height; } @@ -1814,9 +1891,9 @@ void device_set_scissor_rect(gs_device_t *device, const struct gs_rect *rect) device->rasterState.scissorEnabled = (rect != NULL); if (rect != NULL) { - d3drect.left = rect->x; - d3drect.top = rect->y; - d3drect.right = rect->x + rect->cx; + d3drect.left = rect->x; + d3drect.top = rect->y; + d3drect.right = rect->x + rect->cx; d3drect.bottom = rect->y + rect->cy; device->context->RSSetScissorRects(1, &d3drect); } @@ -1825,54 +1902,54 @@ void device_set_scissor_rect(gs_device_t *device, const struct gs_rect *rect) } void device_ortho(gs_device_t *device, float left, float right, float top, - float bottom, float zNear, float zFar) + float bottom, float zNear, float zFar) { matrix4 *dst = &device->curProjMatrix; - float rml = right-left; - float bmt = bottom-top; - float fmn = zFar-zNear; + float rml = right - left; + float bmt = bottom - top; + float fmn = zFar - zNear; vec4_zero(&dst->x); vec4_zero(&dst->y); vec4_zero(&dst->z); vec4_zero(&dst->t); - dst->x.x = 2.0f / rml; - dst->t.x = (left+right) / -rml; + dst->x.x = 2.0f / rml; + dst->t.x = (left + right) / -rml; - dst->y.y = 2.0f / -bmt; - dst->t.y = (bottom+top) / bmt; + dst->y.y = 2.0f / -bmt; + dst->t.y = (bottom + top) / bmt; - dst->z.z = 1.0f / fmn; - dst->t.z = zNear / -fmn; + dst->z.z = 1.0f / fmn; + dst->t.z = zNear / -fmn; dst->t.w = 1.0f; } void device_frustum(gs_device_t *device, float left, float right, float top, - float bottom, float zNear, float zFar) + float bottom, float zNear, float zFar) { matrix4 *dst = &device->curProjMatrix; - float rml = right-left; - float bmt = bottom-top; - float fmn = zFar-zNear; - float nearx2 = 2.0f*zNear; + float rml = right - left; + float bmt = bottom - top; + float fmn = zFar - zNear; + float nearx2 = 2.0f * zNear; vec4_zero(&dst->x); vec4_zero(&dst->y); vec4_zero(&dst->z); vec4_zero(&dst->t); - dst->x.x = nearx2 / rml; - dst->z.x = (left+right) / -rml; + dst->x.x = nearx2 / rml; + dst->z.x = (left + right) / -rml; - dst->y.y = nearx2 / -bmt; - dst->z.y = (bottom+top) / bmt; + dst->y.y = nearx2 / -bmt; + dst->z.y = (bottom + top) / bmt; - dst->z.z = zFar / fmn; - dst->t.z = (zNear*zFar) / -fmn; + dst->z.z = zFar / fmn; + dst->t.z = (zNear * zFar) / -fmn; dst->z.w = 1.0f; } @@ -1886,14 +1963,11 @@ void device_projection_push(gs_device_t *device) void device_projection_pop(gs_device_t *device) { - if (!device->projStack.size()) + if (device->projStack.empty()) return; - mat4float *mat = device->projStack.data(); - size_t end = device->projStack.size()-1; - - /* XXX - does anyone know a better way of doing this? */ - memcpy(&device->curProjMatrix, mat+end, sizeof(matrix4)); + const mat4float &mat = device->projStack.back(); + memcpy(&device->curProjMatrix, &mat, sizeof(matrix4)); device->projStack.pop_back(); } @@ -1915,7 +1989,7 @@ uint32_t gs_texture_get_width(const gs_texture_t *tex) if (tex->type != GS_TEXTURE_2D) return 0; - return static_cast(tex)->width; + return static_cast(tex)->width; } uint32_t gs_texture_get_height(const gs_texture_t *tex) @@ -1923,7 +1997,7 @@ uint32_t gs_texture_get_height(const gs_texture_t *tex) if (tex->type != GS_TEXTURE_2D) return 0; - return static_cast(tex)->height; + return static_cast(tex)->height; } enum gs_color_format gs_texture_get_color_format(const gs_texture_t *tex) @@ -1931,7 +2005,7 @@ enum gs_color_format gs_texture_get_color_format(const gs_texture_t *tex) if (tex->type != GS_TEXTURE_2D) return GS_UNKNOWN; - return static_cast(tex)->format; + return static_cast(tex)->format; } bool gs_texture_map(gs_texture_t *tex, uint8_t **ptr, uint32_t *linesize) @@ -1941,15 +2015,15 @@ bool gs_texture_map(gs_texture_t *tex, uint8_t **ptr, uint32_t *linesize) if (tex->type != GS_TEXTURE_2D) return false; - gs_texture_2d *tex2d = static_cast(tex); + gs_texture_2d *tex2d = static_cast(tex); D3D11_MAPPED_SUBRESOURCE map; hr = tex2d->device->context->Map(tex2d->texture, 0, - D3D11_MAP_WRITE_DISCARD, 0, &map); + D3D11_MAP_WRITE_DISCARD, 0, &map); if (FAILED(hr)) return false; - *ptr = (uint8_t*)map.pData; + *ptr = (uint8_t *)map.pData; *linesize = map.RowPitch; return true; } @@ -1959,7 +2033,7 @@ void gs_texture_unmap(gs_texture_t *tex) if (tex->type != GS_TEXTURE_2D) return; - gs_texture_2d *tex2d = static_cast(tex); + gs_texture_2d *tex2d = static_cast(tex); tex2d->device->context->Unmap(tex2d->texture, 0); } @@ -1968,11 +2042,10 @@ void *gs_texture_get_obj(gs_texture_t *tex) if (tex->type != GS_TEXTURE_2D) return nullptr; - gs_texture_2d *tex2d = static_cast(tex); + gs_texture_2d *tex2d = static_cast(tex); return tex2d->texture.Get(); } - void gs_cubetexture_destroy(gs_texture_t *cubetex) { delete cubetex; @@ -1983,21 +2056,20 @@ uint32_t gs_cubetexture_get_size(const gs_texture_t *cubetex) if (cubetex->type != GS_TEXTURE_CUBE) return 0; - const gs_texture_2d *tex = static_cast(cubetex); + const gs_texture_2d *tex = static_cast(cubetex); return tex->width; } -enum gs_color_format gs_cubetexture_get_color_format( - const gs_texture_t *cubetex) +enum gs_color_format +gs_cubetexture_get_color_format(const gs_texture_t *cubetex) { if (cubetex->type != GS_TEXTURE_CUBE) return GS_UNKNOWN; - const gs_texture_2d *tex = static_cast(cubetex); + const gs_texture_2d *tex = static_cast(cubetex); return tex->format; } - void gs_voltexture_destroy(gs_texture_t *voltex) { delete voltex; @@ -2031,7 +2103,6 @@ enum gs_color_format gs_voltexture_get_color_format(const gs_texture_t *voltex) return GS_UNKNOWN; } - void gs_stagesurface_destroy(gs_stagesurf_t *stagesurf) { delete stagesurf; @@ -2047,21 +2118,21 @@ uint32_t gs_stagesurface_get_height(const gs_stagesurf_t *stagesurf) return stagesurf->height; } -enum gs_color_format gs_stagesurface_get_color_format( - const gs_stagesurf_t *stagesurf) +enum gs_color_format +gs_stagesurface_get_color_format(const gs_stagesurf_t *stagesurf) { return stagesurf->format; } bool gs_stagesurface_map(gs_stagesurf_t *stagesurf, uint8_t **data, - uint32_t *linesize) + uint32_t *linesize) { D3D11_MAPPED_SUBRESOURCE map; if (FAILED(stagesurf->device->context->Map(stagesurf->texture, 0, - D3D11_MAP_READ, 0, &map))) + D3D11_MAP_READ, 0, &map))) return false; - *data = (uint8_t*)map.pData; + *data = (uint8_t *)map.pData; *linesize = map.RowPitch; return true; } @@ -2071,13 +2142,11 @@ void gs_stagesurface_unmap(gs_stagesurf_t *stagesurf) stagesurf->device->context->Unmap(stagesurf->texture, 0); } - void gs_zstencil_destroy(gs_zstencil_t *zstencil) { delete zstencil; } - void gs_samplerstate_destroy(gs_samplerstate_t *samplerstate) { if (!samplerstate) @@ -2086,13 +2155,12 @@ void gs_samplerstate_destroy(gs_samplerstate_t *samplerstate) if (samplerstate->device) for (int i = 0; i < GS_MAX_TEXTURES; i++) if (samplerstate->device->curSamplers[i] == - samplerstate) + samplerstate) samplerstate->device->curSamplers[i] = nullptr; delete samplerstate; } - void gs_vertexbuffer_destroy(gs_vertbuffer_t *vertbuffer) { if (vertbuffer && vertbuffer->device->lastVertexBuffer == vertbuffer) @@ -2101,38 +2169,38 @@ void gs_vertexbuffer_destroy(gs_vertbuffer_t *vertbuffer) } static inline void gs_vertexbuffer_flush_internal(gs_vertbuffer_t *vertbuffer, - const gs_vb_data *data) + const gs_vb_data *data) { size_t num_tex = data->num_tex < vertbuffer->uvBuffers.size() - ? data->num_tex - : vertbuffer->uvBuffers.size(); + ? data->num_tex + : vertbuffer->uvBuffers.size(); if (!vertbuffer->dynamic) { blog(LOG_ERROR, "gs_vertexbuffer_flush: vertex buffer is " - "not dynamic"); + "not dynamic"); return; } if (data->points) - vertbuffer->FlushBuffer(vertbuffer->vertexBuffer, - data->points, sizeof(vec3)); + vertbuffer->FlushBuffer(vertbuffer->vertexBuffer, data->points, + sizeof(vec3)); if (vertbuffer->normalBuffer && data->normals) - vertbuffer->FlushBuffer(vertbuffer->normalBuffer, - data->normals, sizeof(vec3)); + vertbuffer->FlushBuffer(vertbuffer->normalBuffer, data->normals, + sizeof(vec3)); if (vertbuffer->tangentBuffer && data->tangents) vertbuffer->FlushBuffer(vertbuffer->tangentBuffer, - data->tangents, sizeof(vec3)); + data->tangents, sizeof(vec3)); if (vertbuffer->colorBuffer && data->colors) - vertbuffer->FlushBuffer(vertbuffer->colorBuffer, - data->colors, sizeof(uint32_t)); + vertbuffer->FlushBuffer(vertbuffer->colorBuffer, data->colors, + sizeof(uint32_t)); for (size_t i = 0; i < num_tex; i++) { gs_tvertarray &tv = data->tvarray[i]; - vertbuffer->FlushBuffer(vertbuffer->uvBuffers[i], - tv.array, tv.width*sizeof(float)); + vertbuffer->FlushBuffer(vertbuffer->uvBuffers[i], tv.array, + tv.width * sizeof(float)); } } @@ -2142,7 +2210,7 @@ void gs_vertexbuffer_flush(gs_vertbuffer_t *vertbuffer) } void gs_vertexbuffer_flush_direct(gs_vertbuffer_t *vertbuffer, - const gs_vb_data *data) + const gs_vb_data *data) { gs_vertexbuffer_flush_internal(vertbuffer, data); } @@ -2152,14 +2220,13 @@ struct gs_vb_data *gs_vertexbuffer_get_data(const gs_vertbuffer_t *vertbuffer) return vertbuffer->vbd.data; } - void gs_indexbuffer_destroy(gs_indexbuffer_t *indexbuffer) { delete indexbuffer; } static inline void gs_indexbuffer_flush_internal(gs_indexbuffer_t *indexbuffer, - const void *data) + const void *data) { HRESULT hr; @@ -2167,8 +2234,8 @@ static inline void gs_indexbuffer_flush_internal(gs_indexbuffer_t *indexbuffer, return; D3D11_MAPPED_SUBRESOURCE map; - hr = indexbuffer->device->context->Map(indexbuffer->indexBuffer, 0, - D3D11_MAP_WRITE_DISCARD, 0, &map); + hr = indexbuffer->device->context->Map( + indexbuffer->indexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); if (FAILED(hr)) return; @@ -2183,7 +2250,7 @@ void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer) } void gs_indexbuffer_flush_direct(gs_indexbuffer_t *indexbuffer, - const void *data) + const void *data) { gs_indexbuffer_flush_internal(indexbuffer, data); } @@ -2203,6 +2270,88 @@ enum gs_index_type gs_indexbuffer_get_type(const gs_indexbuffer_t *indexbuffer) return indexbuffer->type; } +void gs_timer_destroy(gs_timer_t *timer) +{ + delete timer; +} + +void gs_timer_begin(gs_timer_t *timer) +{ + timer->device->context->End(timer->query_begin); +} + +void gs_timer_end(gs_timer_t *timer) +{ + timer->device->context->End(timer->query_end); +} + +bool gs_timer_get_data(gs_timer_t *timer, uint64_t *ticks) +{ + uint64_t begin, end; + HRESULT hr_begin, hr_end; + do { + hr_begin = timer->device->context->GetData( + timer->query_begin, &begin, sizeof(begin), 0); + } while (hr_begin == S_FALSE); + do { + hr_end = timer->device->context->GetData(timer->query_end, &end, + sizeof(end), 0); + } while (hr_end == S_FALSE); + + const bool succeeded = SUCCEEDED(hr_begin) && SUCCEEDED(hr_end); + if (succeeded) + *ticks = end - begin; + + return succeeded; +} + +void gs_timer_range_destroy(gs_timer_range_t *range) +{ + delete range; +} + +void gs_timer_range_begin(gs_timer_range_t *range) +{ + range->device->context->Begin(range->query_disjoint); +} + +void gs_timer_range_end(gs_timer_range_t *range) +{ + range->device->context->End(range->query_disjoint); +} + +bool gs_timer_range_get_data(gs_timer_range_t *range, bool *disjoint, + uint64_t *frequency) +{ + D3D11_QUERY_DATA_TIMESTAMP_DISJOINT timestamp_disjoint; + HRESULT hr; + do { + hr = range->device->context->GetData(range->query_disjoint, + ×tamp_disjoint, + sizeof(timestamp_disjoint), + 0); + } while (hr == S_FALSE); + + const bool succeeded = SUCCEEDED(hr); + if (succeeded) { + *disjoint = timestamp_disjoint.Disjoint; + *frequency = timestamp_disjoint.Frequency; + } + + return succeeded; +} + +gs_timer::gs_timer(gs_device_t *device) : gs_obj(device, gs_type::gs_timer) +{ + Rebuild(device->device); +} + +gs_timer_range::gs_timer_range(gs_device_t *device) + : gs_obj(device, gs_type::gs_timer_range) +{ + Rebuild(device->device); +} + extern "C" EXPORT bool device_gdi_texture_available(void) { return true; @@ -2219,11 +2368,13 @@ extern "C" EXPORT bool device_nv12_available(gs_device_t *device) } extern "C" EXPORT void device_debug_marker_begin(gs_device_t *, - const char *markername, const float color[4]) + const char *markername, + const float color[4]) { D3DCOLOR bgra = D3DCOLOR_ARGB((DWORD)(255.0f * color[3]), - (DWORD)(255.0f * color[0]), (DWORD)(255.0f * color[1]), - (DWORD)(255.0f * color[2])); + (DWORD)(255.0f * color[0]), + (DWORD)(255.0f * color[1]), + (DWORD)(255.0f * color[2])); wchar_t wide[64]; os_utf8_to_wcs(markername, 0, wide, _countof(wide)); @@ -2236,17 +2387,17 @@ extern "C" EXPORT void device_debug_marker_end(gs_device_t *) D3DPERF_EndEvent(); } -extern "C" EXPORT gs_texture_t *device_texture_create_gdi(gs_device_t *device, - uint32_t width, uint32_t height) +extern "C" EXPORT gs_texture_t * +device_texture_create_gdi(gs_device_t *device, uint32_t width, uint32_t height) { gs_texture *texture = nullptr; try { - texture = new gs_texture_2d(device, width, height, GS_BGRA, - 1, nullptr, GS_RENDER_TARGET, GS_TEXTURE_2D, - true); - } catch (HRError error) { + texture = new gs_texture_2d(device, width, height, GS_BGRA, 1, + nullptr, GS_RENDER_TARGET, + GS_TEXTURE_2D, true); + } catch (const HRError &error) { blog(LOG_ERROR, "device_texture_create_gdi (D3D11): %s (%08lX)", - error.str, error.hr); + error.str, error.hr); LogD3D11ErrorDetails(error, device); } catch (const char *error) { blog(LOG_ERROR, "device_texture_create_gdi (D3D11): %s", error); @@ -2259,7 +2410,7 @@ static inline bool TextureGDICompatible(gs_texture_2d *tex2d, const char *func) { if (!tex2d->isGDICompatible) { blog(LOG_ERROR, "%s (D3D11): Texture is not GDI compatible", - func); + func); return false; } @@ -2273,7 +2424,7 @@ extern "C" EXPORT void *gs_texture_get_dc(gs_texture_t *tex) if (tex->type != GS_TEXTURE_2D) return nullptr; - gs_texture_2d *tex2d = static_cast(tex); + gs_texture_2d *tex2d = static_cast(tex); if (!TextureGDICompatible(tex2d, "gs_texture_get_dc")) return nullptr; @@ -2289,7 +2440,7 @@ extern "C" EXPORT void gs_texture_release_dc(gs_texture_t *tex) if (tex->type != GS_TEXTURE_2D) return; - gs_texture_2d *tex2d = static_cast(tex); + gs_texture_2d *tex2d = static_cast(tex); if (!TextureGDICompatible(tex2d, "gs_texture_release_dc")) return; @@ -2297,14 +2448,14 @@ extern "C" EXPORT void gs_texture_release_dc(gs_texture_t *tex) } extern "C" EXPORT gs_texture_t *device_texture_open_shared(gs_device_t *device, - uint32_t handle) + uint32_t handle) { gs_texture *texture = nullptr; try { texture = new gs_texture_2d(device, handle); - } catch (HRError error) { + } catch (const HRError &error) { blog(LOG_ERROR, "gs_texture_open_shared (D3D11): %s (%08lX)", - error.str, error.hr); + error.str, error.hr); LogD3D11ErrorDetails(error, device); } catch (const char *error) { blog(LOG_ERROR, "gs_texture_open_shared (D3D11): %s", error); @@ -2347,7 +2498,7 @@ int device_texture_acquire_sync(gs_texture_t *tex, uint64_t key, uint32_t ms) } extern "C" EXPORT int device_texture_release_sync(gs_texture_t *tex, - uint64_t key) + uint64_t key) { gs_texture_2d *tex2d = reinterpret_cast(tex); if (tex->type != GS_TEXTURE_2D) @@ -2369,9 +2520,10 @@ extern "C" EXPORT int device_texture_release_sync(gs_texture_t *tex, return -1; } -extern "C" EXPORT bool device_texture_create_nv12(gs_device_t *device, - gs_texture_t **p_tex_y, gs_texture_t **p_tex_uv, - uint32_t width, uint32_t height, uint32_t flags) +extern "C" EXPORT bool +device_texture_create_nv12(gs_device_t *device, gs_texture_t **p_tex_y, + gs_texture_t **p_tex_uv, uint32_t width, + uint32_t height, uint32_t flags) { if (!device->nv12Supported) return false; @@ -2384,12 +2536,13 @@ extern "C" EXPORT bool device_texture_create_nv12(gs_device_t *device, try { tex_y = new gs_texture_2d(device, width, height, GS_R8, 1, - nullptr, flags, GS_TEXTURE_2D, false, true); + nullptr, flags, GS_TEXTURE_2D, false, + true); tex_uv = new gs_texture_2d(device, tex_y->texture, flags); - } catch (HRError error) { + } catch (const HRError &error) { blog(LOG_ERROR, "gs_texture_create_nv12 (D3D11): %s (%08lX)", - error.str, error.hr); + error.str, error.hr); LogD3D11ErrorDetails(error, device); return false; @@ -2406,16 +2559,18 @@ extern "C" EXPORT bool device_texture_create_nv12(gs_device_t *device, return true; } -extern "C" EXPORT gs_stagesurf_t *device_stagesurface_create_nv12( - gs_device_t *device, uint32_t width, uint32_t height) +extern "C" EXPORT gs_stagesurf_t * +device_stagesurface_create_nv12(gs_device_t *device, uint32_t width, + uint32_t height) { gs_stage_surface *surf = NULL; try { surf = new gs_stage_surface(device, width, height); - } catch (HRError error) { - blog(LOG_ERROR, "device_stagesurface_create (D3D11): %s " - "(%08lX)", - error.str, error.hr); + } catch (const HRError &error) { + blog(LOG_ERROR, + "device_stagesurface_create (D3D11): %s " + "(%08lX)", + error.str, error.hr); LogD3D11ErrorDetails(error, device); } diff --git a/libobs-d3d11/d3d11-subsystem.hpp b/libobs-d3d11/d3d11-subsystem.hpp index d373be5..1ef2e61 100644 --- a/libobs-d3d11/d3d11-subsystem.hpp +++ b/libobs-d3d11/d3d11-subsystem.hpp @@ -62,25 +62,44 @@ static inline uint32_t GetWinVer() static inline DXGI_FORMAT ConvertGSTextureFormat(gs_color_format format) { switch (format) { - case GS_UNKNOWN: return DXGI_FORMAT_UNKNOWN; - case GS_A8: return DXGI_FORMAT_A8_UNORM; - case GS_R8: return DXGI_FORMAT_R8_UNORM; - case GS_RGBA: return DXGI_FORMAT_R8G8B8A8_UNORM; - case GS_BGRX: return DXGI_FORMAT_B8G8R8X8_UNORM; - case GS_BGRA: return DXGI_FORMAT_B8G8R8A8_UNORM; - case GS_R10G10B10A2: return DXGI_FORMAT_R10G10B10A2_UNORM; - case GS_RGBA16: return DXGI_FORMAT_R16G16B16A16_UNORM; - case GS_R16: return DXGI_FORMAT_R16_UNORM; - case GS_RGBA16F: return DXGI_FORMAT_R16G16B16A16_FLOAT; - case GS_RGBA32F: return DXGI_FORMAT_R32G32B32A32_FLOAT; - case GS_RG16F: return DXGI_FORMAT_R16G16_FLOAT; - case GS_RG32F: return DXGI_FORMAT_R32G32_FLOAT; - case GS_R16F: return DXGI_FORMAT_R16_FLOAT; - case GS_R32F: return DXGI_FORMAT_R32_FLOAT; - case GS_DXT1: return DXGI_FORMAT_BC1_UNORM; - case GS_DXT3: return DXGI_FORMAT_BC2_UNORM; - case GS_DXT5: return DXGI_FORMAT_BC3_UNORM; - case GS_R8G8: return DXGI_FORMAT_R8G8_UNORM; + case GS_UNKNOWN: + return DXGI_FORMAT_UNKNOWN; + case GS_A8: + return DXGI_FORMAT_A8_UNORM; + case GS_R8: + return DXGI_FORMAT_R8_UNORM; + case GS_RGBA: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case GS_BGRX: + return DXGI_FORMAT_B8G8R8X8_UNORM; + case GS_BGRA: + return DXGI_FORMAT_B8G8R8A8_UNORM; + case GS_R10G10B10A2: + return DXGI_FORMAT_R10G10B10A2_UNORM; + case GS_RGBA16: + return DXGI_FORMAT_R16G16B16A16_UNORM; + case GS_R16: + return DXGI_FORMAT_R16_UNORM; + case GS_RGBA16F: + return DXGI_FORMAT_R16G16B16A16_FLOAT; + case GS_RGBA32F: + return DXGI_FORMAT_R32G32B32A32_FLOAT; + case GS_RG16F: + return DXGI_FORMAT_R16G16_FLOAT; + case GS_RG32F: + return DXGI_FORMAT_R32G32_FLOAT; + case GS_R16F: + return DXGI_FORMAT_R16_FLOAT; + case GS_R32F: + return DXGI_FORMAT_R32_FLOAT; + case GS_DXT1: + return DXGI_FORMAT_BC1_UNORM; + case GS_DXT3: + return DXGI_FORMAT_BC2_UNORM; + case GS_DXT5: + return DXGI_FORMAT_BC3_UNORM; + case GS_R8G8: + return DXGI_FORMAT_R8G8_UNORM; } return DXGI_FORMAT_UNKNOWN; @@ -89,24 +108,42 @@ static inline DXGI_FORMAT ConvertGSTextureFormat(gs_color_format format) static inline gs_color_format ConvertDXGITextureFormat(DXGI_FORMAT format) { switch ((unsigned long)format) { - case DXGI_FORMAT_A8_UNORM: return GS_A8; - case DXGI_FORMAT_R8_UNORM: return GS_R8; - case DXGI_FORMAT_R8G8_UNORM: return GS_R8G8; - case DXGI_FORMAT_R8G8B8A8_UNORM: return GS_RGBA; - case DXGI_FORMAT_B8G8R8X8_UNORM: return GS_BGRX; - case DXGI_FORMAT_B8G8R8A8_UNORM: return GS_BGRA; - case DXGI_FORMAT_R10G10B10A2_UNORM: return GS_R10G10B10A2; - case DXGI_FORMAT_R16G16B16A16_UNORM: return GS_RGBA16; - case DXGI_FORMAT_R16_UNORM: return GS_R16; - case DXGI_FORMAT_R16G16B16A16_FLOAT: return GS_RGBA16F; - case DXGI_FORMAT_R32G32B32A32_FLOAT: return GS_RGBA32F; - case DXGI_FORMAT_R16G16_FLOAT: return GS_RG16F; - case DXGI_FORMAT_R32G32_FLOAT: return GS_RG32F; - case DXGI_FORMAT_R16_FLOAT: return GS_R16F; - case DXGI_FORMAT_R32_FLOAT: return GS_R32F; - case DXGI_FORMAT_BC1_UNORM: return GS_DXT1; - case DXGI_FORMAT_BC2_UNORM: return GS_DXT3; - case DXGI_FORMAT_BC3_UNORM: return GS_DXT5; + case DXGI_FORMAT_A8_UNORM: + return GS_A8; + case DXGI_FORMAT_R8_UNORM: + return GS_R8; + case DXGI_FORMAT_R8G8_UNORM: + return GS_R8G8; + case DXGI_FORMAT_R8G8B8A8_UNORM: + return GS_RGBA; + case DXGI_FORMAT_B8G8R8X8_UNORM: + return GS_BGRX; + case DXGI_FORMAT_B8G8R8A8_UNORM: + return GS_BGRA; + case DXGI_FORMAT_R10G10B10A2_UNORM: + return GS_R10G10B10A2; + case DXGI_FORMAT_R16G16B16A16_UNORM: + return GS_RGBA16; + case DXGI_FORMAT_R16_UNORM: + return GS_R16; + case DXGI_FORMAT_R16G16B16A16_FLOAT: + return GS_RGBA16F; + case DXGI_FORMAT_R32G32B32A32_FLOAT: + return GS_RGBA32F; + case DXGI_FORMAT_R16G16_FLOAT: + return GS_RG16F; + case DXGI_FORMAT_R32G32_FLOAT: + return GS_RG32F; + case DXGI_FORMAT_R16_FLOAT: + return GS_R16F; + case DXGI_FORMAT_R32_FLOAT: + return GS_R32F; + case DXGI_FORMAT_BC1_UNORM: + return GS_DXT1; + case DXGI_FORMAT_BC2_UNORM: + return GS_DXT3; + case DXGI_FORMAT_BC3_UNORM: + return GS_DXT5; } return GS_UNKNOWN; @@ -115,11 +152,16 @@ static inline gs_color_format ConvertDXGITextureFormat(DXGI_FORMAT format) static inline DXGI_FORMAT ConvertGSZStencilFormat(gs_zstencil_format format) { switch (format) { - case GS_ZS_NONE: return DXGI_FORMAT_UNKNOWN; - case GS_Z16: return DXGI_FORMAT_D16_UNORM; - case GS_Z24_S8: return DXGI_FORMAT_D24_UNORM_S8_UINT; - case GS_Z32F: return DXGI_FORMAT_D32_FLOAT; - case GS_Z32F_S8X24: return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + case GS_ZS_NONE: + return DXGI_FORMAT_UNKNOWN; + case GS_Z16: + return DXGI_FORMAT_D16_UNORM; + case GS_Z24_S8: + return DXGI_FORMAT_D24_UNORM_S8_UINT; + case GS_Z32F: + return DXGI_FORMAT_D32_FLOAT; + case GS_Z32F_S8X24: + return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; } return DXGI_FORMAT_UNKNOWN; @@ -128,14 +170,22 @@ static inline DXGI_FORMAT ConvertGSZStencilFormat(gs_zstencil_format format) static inline D3D11_COMPARISON_FUNC ConvertGSDepthTest(gs_depth_test test) { switch (test) { - case GS_NEVER: return D3D11_COMPARISON_NEVER; - case GS_LESS: return D3D11_COMPARISON_LESS; - case GS_LEQUAL: return D3D11_COMPARISON_LESS_EQUAL; - case GS_EQUAL: return D3D11_COMPARISON_EQUAL; - case GS_GEQUAL: return D3D11_COMPARISON_GREATER_EQUAL; - case GS_GREATER: return D3D11_COMPARISON_GREATER; - case GS_NOTEQUAL: return D3D11_COMPARISON_NOT_EQUAL; - case GS_ALWAYS: return D3D11_COMPARISON_ALWAYS; + case GS_NEVER: + return D3D11_COMPARISON_NEVER; + case GS_LESS: + return D3D11_COMPARISON_LESS; + case GS_LEQUAL: + return D3D11_COMPARISON_LESS_EQUAL; + case GS_EQUAL: + return D3D11_COMPARISON_EQUAL; + case GS_GEQUAL: + return D3D11_COMPARISON_GREATER_EQUAL; + case GS_GREATER: + return D3D11_COMPARISON_GREATER; + case GS_NOTEQUAL: + return D3D11_COMPARISON_NOT_EQUAL; + case GS_ALWAYS: + return D3D11_COMPARISON_ALWAYS; } return D3D11_COMPARISON_NEVER; @@ -144,12 +194,18 @@ static inline D3D11_COMPARISON_FUNC ConvertGSDepthTest(gs_depth_test test) static inline D3D11_STENCIL_OP ConvertGSStencilOp(gs_stencil_op_type op) { switch (op) { - case GS_KEEP: return D3D11_STENCIL_OP_KEEP; - case GS_ZERO: return D3D11_STENCIL_OP_ZERO; - case GS_REPLACE: return D3D11_STENCIL_OP_REPLACE; - case GS_INCR: return D3D11_STENCIL_OP_INCR; - case GS_DECR: return D3D11_STENCIL_OP_DECR; - case GS_INVERT: return D3D11_STENCIL_OP_INVERT; + case GS_KEEP: + return D3D11_STENCIL_OP_KEEP; + case GS_ZERO: + return D3D11_STENCIL_OP_ZERO; + case GS_REPLACE: + return D3D11_STENCIL_OP_REPLACE; + case GS_INCR: + return D3D11_STENCIL_OP_INCR; + case GS_DECR: + return D3D11_STENCIL_OP_DECR; + case GS_INVERT: + return D3D11_STENCIL_OP_INVERT; } return D3D11_STENCIL_OP_KEEP; @@ -158,17 +214,28 @@ static inline D3D11_STENCIL_OP ConvertGSStencilOp(gs_stencil_op_type op) static inline D3D11_BLEND ConvertGSBlendType(gs_blend_type type) { switch (type) { - case GS_BLEND_ZERO: return D3D11_BLEND_ZERO; - case GS_BLEND_ONE: return D3D11_BLEND_ONE; - case GS_BLEND_SRCCOLOR: return D3D11_BLEND_SRC_COLOR; - case GS_BLEND_INVSRCCOLOR: return D3D11_BLEND_INV_SRC_COLOR; - case GS_BLEND_SRCALPHA: return D3D11_BLEND_SRC_ALPHA; - case GS_BLEND_INVSRCALPHA: return D3D11_BLEND_INV_SRC_ALPHA; - case GS_BLEND_DSTCOLOR: return D3D11_BLEND_DEST_COLOR; - case GS_BLEND_INVDSTCOLOR: return D3D11_BLEND_INV_DEST_COLOR; - case GS_BLEND_DSTALPHA: return D3D11_BLEND_DEST_ALPHA; - case GS_BLEND_INVDSTALPHA: return D3D11_BLEND_INV_DEST_ALPHA; - case GS_BLEND_SRCALPHASAT: return D3D11_BLEND_SRC_ALPHA_SAT; + case GS_BLEND_ZERO: + return D3D11_BLEND_ZERO; + case GS_BLEND_ONE: + return D3D11_BLEND_ONE; + case GS_BLEND_SRCCOLOR: + return D3D11_BLEND_SRC_COLOR; + case GS_BLEND_INVSRCCOLOR: + return D3D11_BLEND_INV_SRC_COLOR; + case GS_BLEND_SRCALPHA: + return D3D11_BLEND_SRC_ALPHA; + case GS_BLEND_INVSRCALPHA: + return D3D11_BLEND_INV_SRC_ALPHA; + case GS_BLEND_DSTCOLOR: + return D3D11_BLEND_DEST_COLOR; + case GS_BLEND_INVDSTCOLOR: + return D3D11_BLEND_INV_DEST_COLOR; + case GS_BLEND_DSTALPHA: + return D3D11_BLEND_DEST_ALPHA; + case GS_BLEND_INVDSTALPHA: + return D3D11_BLEND_INV_DEST_ALPHA; + case GS_BLEND_SRCALPHASAT: + return D3D11_BLEND_SRC_ALPHA_SAT; } return D3D11_BLEND_ONE; @@ -177,9 +244,12 @@ static inline D3D11_BLEND ConvertGSBlendType(gs_blend_type type) static inline D3D11_CULL_MODE ConvertGSCullMode(gs_cull_mode mode) { switch (mode) { - case GS_BACK: return D3D11_CULL_BACK; - case GS_FRONT: return D3D11_CULL_FRONT; - case GS_NEITHER: return D3D11_CULL_NONE; + case GS_BACK: + return D3D11_CULL_BACK; + case GS_FRONT: + return D3D11_CULL_FRONT; + case GS_NEITHER: + return D3D11_CULL_NONE; } return D3D11_CULL_BACK; @@ -188,11 +258,16 @@ static inline D3D11_CULL_MODE ConvertGSCullMode(gs_cull_mode mode) static inline D3D11_PRIMITIVE_TOPOLOGY ConvertGSTopology(gs_draw_mode mode) { switch (mode) { - case GS_POINTS: return D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; - case GS_LINES: return D3D11_PRIMITIVE_TOPOLOGY_LINELIST; - case GS_LINESTRIP: return D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP; - case GS_TRIS: return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - case GS_TRISTRIP: return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + case GS_POINTS: + return D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; + case GS_LINES: + return D3D11_PRIMITIVE_TOPOLOGY_LINELIST; + case GS_LINESTRIP: + return D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP; + case GS_TRIS: + return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + case GS_TRISTRIP: + return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; } return D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; @@ -203,7 +278,7 @@ struct VBDataPtr { gs_vb_data *data; inline VBDataPtr(gs_vb_data *data) : data(data) {} - inline ~VBDataPtr() {gs_vbdata_destroy(data);} + inline ~VBDataPtr() { gs_vbdata_destroy(data); } }; enum class gs_type { @@ -217,6 +292,8 @@ enum class gs_type { gs_pixel_shader, gs_duplicator, gs_swap_chain, + gs_timer, + gs_timer_range, }; struct gs_obj { @@ -225,38 +302,32 @@ struct gs_obj { gs_obj *next; gs_obj **prev_next; - inline gs_obj() : - device(nullptr), - next(nullptr), - prev_next(nullptr) - {} + inline gs_obj() : device(nullptr), next(nullptr), prev_next(nullptr) {} gs_obj(gs_device_t *device, gs_type type); virtual ~gs_obj(); }; struct gs_vertex_buffer : gs_obj { - ComPtr vertexBuffer; - ComPtr normalBuffer; - ComPtr colorBuffer; - ComPtr tangentBuffer; + ComPtr vertexBuffer; + ComPtr normalBuffer; + ComPtr colorBuffer; + ComPtr tangentBuffer; vector> uvBuffers; - bool dynamic; - VBDataPtr vbd; - size_t numVerts; + bool dynamic; + VBDataPtr vbd; + size_t numVerts; vector uvSizes; - void FlushBuffer(ID3D11Buffer *buffer, void *array, - size_t elementSize); + void FlushBuffer(ID3D11Buffer *buffer, void *array, size_t elementSize); void MakeBufferList(gs_vertex_shader *shader, - vector &buffers, - vector &strides); + vector &buffers, + vector &strides); - void InitBuffer(const size_t elementSize, - const size_t numVerts, void *array, - ID3D11Buffer **buffer); + void InitBuffer(const size_t elementSize, const size_t numVerts, + void *array, ID3D11Buffer **buffer); void BuildBuffers(); @@ -272,7 +343,7 @@ struct gs_vertex_buffer : gs_obj { void Rebuild(); gs_vertex_buffer(gs_device_t *device, struct gs_vb_data *data, - uint32_t flags); + uint32_t flags); }; /* exception-safe RAII wrapper for index buffer data (NOTE: not copy-safe) */ @@ -280,16 +351,16 @@ struct DataPtr { void *data; inline DataPtr(void *data) : data(data) {} - inline ~DataPtr() {bfree(data);} + inline ~DataPtr() { bfree(data); } }; struct gs_index_buffer : gs_obj { ComPtr indexBuffer; - bool dynamic; - gs_index_type type; - size_t indexSize; - size_t num; - DataPtr indices; + bool dynamic; + gs_index_type type; + size_t indexSize; + size_t num; + DataPtr indices; D3D11_BUFFER_DESC bd = {}; D3D11_SUBRESOURCE_DATA srd = {}; @@ -298,15 +369,40 @@ struct gs_index_buffer : gs_obj { void Rebuild(ID3D11Device *dev); - inline void Release() {indexBuffer.Release();} + inline void Release() { indexBuffer.Release(); } gs_index_buffer(gs_device_t *device, enum gs_index_type type, void *indices, size_t num, uint32_t flags); }; +struct gs_timer : gs_obj { + ComPtr query_begin; + ComPtr query_end; + + void Rebuild(ID3D11Device *dev); + + inline void Release() + { + query_begin.Release(); + query_end.Release(); + } + + gs_timer(gs_device_t *device); +}; + +struct gs_timer_range : gs_obj { + ComPtr query_disjoint; + + void Rebuild(ID3D11Device *dev); + + inline void Release() { query_disjoint.Release(); } + + gs_timer_range(gs_device_t *device); +}; + struct gs_texture : gs_obj { gs_texture_type type; - uint32_t levels; + uint32_t levels; gs_color_format format; ComPtr shaderRes; @@ -315,50 +411,47 @@ struct gs_texture : gs_obj { void Rebuild(ID3D11Device *dev); inline gs_texture(gs_texture_type type, uint32_t levels, - gs_color_format format) - : type (type), - levels (levels), - format (format) + gs_color_format format) + : type(type), levels(levels), format(format) { } inline gs_texture(gs_device *device, gs_type obj_type, - gs_texture_type type) - : gs_obj (device, obj_type), - type (type) + gs_texture_type type) + : gs_obj(device, obj_type), type(type) { } inline gs_texture(gs_device *device, gs_type obj_type, - gs_texture_type type, - uint32_t levels, gs_color_format format) - : gs_obj (device, obj_type), - type (type), - levels (levels), - format (format) + gs_texture_type type, uint32_t levels, + gs_color_format format) + : gs_obj(device, obj_type), + type(type), + levels(levels), + format(format) { } }; struct gs_texture_2d : gs_texture { - ComPtr texture; - ComPtr renderTarget[6]; - ComPtr gdiSurface; + ComPtr texture; + ComPtr renderTarget[6]; + ComPtr gdiSurface; - uint32_t width = 0, height = 0; - uint32_t flags = 0; - DXGI_FORMAT dxgiFormat = DXGI_FORMAT_UNKNOWN; - bool isRenderTarget = false; - bool isGDICompatible = false; - bool isDynamic = false; - bool isShared = false; - bool genMipmaps = false; - uint32_t sharedHandle = GS_INVALID_HANDLE; + uint32_t width = 0, height = 0; + uint32_t flags = 0; + DXGI_FORMAT dxgiFormat = DXGI_FORMAT_UNKNOWN; + bool isRenderTarget = false; + bool isGDICompatible = false; + bool isDynamic = false; + bool isShared = false; + bool genMipmaps = false; + uint32_t sharedHandle = GS_INVALID_HANDLE; - gs_texture_2d *pairedNV12texture = nullptr; - bool nv12 = false; - bool chroma = false; - bool acquired = false; + gs_texture_2d *pairedNV12texture = nullptr; + bool nv12 = false; + bool chroma = false; + bool acquired = false; vector> data; vector srd; @@ -385,29 +478,26 @@ struct gs_texture_2d : gs_texture { shaderRes.Release(); } - inline gs_texture_2d() - : gs_texture (GS_TEXTURE_2D, 0, GS_UNKNOWN) - { - } + inline gs_texture_2d() : gs_texture(GS_TEXTURE_2D, 0, GS_UNKNOWN) {} gs_texture_2d(gs_device_t *device, uint32_t width, uint32_t height, - gs_color_format colorFormat, uint32_t levels, - const uint8_t **data, uint32_t flags, - gs_texture_type type, bool gdiCompatible, - bool nv12 = false); + gs_color_format colorFormat, uint32_t levels, + const uint8_t **data, uint32_t flags, + gs_texture_type type, bool gdiCompatible, + bool nv12 = false); gs_texture_2d(gs_device_t *device, ID3D11Texture2D *nv12, - uint32_t flags); + uint32_t flags); gs_texture_2d(gs_device_t *device, uint32_t handle); }; struct gs_zstencil_buffer : gs_obj { - ComPtr texture; + ComPtr texture; ComPtr view; - uint32_t width, height; + uint32_t width, height; gs_zstencil_format format; - DXGI_FORMAT dxgiFormat; + DXGI_FORMAT dxgiFormat; D3D11_TEXTURE2D_DESC td = {}; D3D11_DEPTH_STENCIL_VIEW_DESC dsvd = {}; @@ -423,62 +513,57 @@ struct gs_zstencil_buffer : gs_obj { } inline gs_zstencil_buffer() - : width (0), - height (0), - dxgiFormat (DXGI_FORMAT_UNKNOWN) + : width(0), height(0), dxgiFormat(DXGI_FORMAT_UNKNOWN) { } gs_zstencil_buffer(gs_device_t *device, uint32_t width, uint32_t height, - gs_zstencil_format format); + gs_zstencil_format format); }; struct gs_stage_surface : gs_obj { ComPtr texture; D3D11_TEXTURE2D_DESC td = {}; - uint32_t width, height; + uint32_t width, height; gs_color_format format; - DXGI_FORMAT dxgiFormat; + DXGI_FORMAT dxgiFormat; void Rebuild(ID3D11Device *dev); - inline void Release() - { - texture.Release(); - } + inline void Release() { texture.Release(); } gs_stage_surface(gs_device_t *device, uint32_t width, uint32_t height, - gs_color_format colorFormat); + gs_color_format colorFormat); gs_stage_surface(gs_device_t *device, uint32_t width, uint32_t height); }; struct gs_sampler_state : gs_obj { ComPtr state; - D3D11_SAMPLER_DESC sd = {}; - gs_sampler_info info; + D3D11_SAMPLER_DESC sd = {}; + gs_sampler_info info; void Rebuild(ID3D11Device *dev); - inline void Release() {state.Release();} + inline void Release() { state.Release(); } gs_sampler_state(gs_device_t *device, const gs_sampler_info *info); }; struct gs_shader_param { - string name; - gs_shader_param_type type; + string name; + gs_shader_param_type type; - uint32_t textureID; - struct gs_sampler_state *nextSampler = nullptr; + uint32_t textureID; + struct gs_sampler_state *nextSampler = nullptr; - int arrayCount; + int arrayCount; - size_t pos; + size_t pos; - vector curValue; - vector defaultValue; - bool changed; + vector curValue; + vector defaultValue; + bool changed; gs_shader_param(shader_var &var, uint32_t &texCounter); }; @@ -488,34 +573,31 @@ struct ShaderError { HRESULT hr; inline ShaderError(const ComPtr &errors, HRESULT hr) - : errors (errors), - hr (hr) + : errors(errors), hr(hr) { } }; struct gs_shader : gs_obj { - gs_shader_type type; + gs_shader_type type; vector params; - ComPtr constants; - size_t constantSize; + ComPtr constants; + size_t constantSize; - D3D11_BUFFER_DESC bd = {}; - vector data; + D3D11_BUFFER_DESC bd = {}; + vector data; inline void UpdateParam(vector &constData, - gs_shader_param ¶m, bool &upload); + gs_shader_param ¶m, bool &upload); void UploadParams(); void BuildConstantBuffer(); void Compile(const char *shaderStr, const char *file, - const char *target, ID3D10Blob **shader); + const char *target, ID3D10Blob **shader); inline gs_shader(gs_device_t *device, gs_type obj_type, - gs_shader_type type) - : gs_obj (device, obj_type), - type (type), - constantSize (0) + gs_shader_type type) + : gs_obj(device, obj_type), type(type), constantSize(0) { } @@ -523,28 +605,27 @@ struct gs_shader : gs_obj { }; struct ShaderSampler { - string name; + string name; gs_sampler_state sampler; inline ShaderSampler(const char *name, gs_device_t *device, - gs_sampler_info *info) - : name (name), - sampler (device, info) + gs_sampler_info *info) + : name(name), sampler(device, info) { } }; struct gs_vertex_shader : gs_shader { ComPtr shader; - ComPtr layout; + ComPtr layout; gs_shader_param *world, *viewProj; vector layoutData; - bool hasNormals; - bool hasColors; - bool hasTangents; + bool hasNormals; + bool hasColors; + bool hasTangents; uint32_t nTexUnits; void Rebuild(ID3D11Device *dev); @@ -558,10 +639,13 @@ struct gs_vertex_shader : gs_shader { inline uint32_t NumBuffersExpected() const { - uint32_t count = nTexUnits+1; - if (hasNormals) count++; - if (hasColors) count++; - if (hasTangents) count++; + uint32_t count = nTexUnits + 1; + if (hasNormals) + count++; + if (hasColors) + count++; + if (hasTangents) + count++; return count; } @@ -569,7 +653,7 @@ struct gs_vertex_shader : gs_shader { void GetBuffersExpected(const vector &inputs); gs_vertex_shader(gs_device_t *device, const char *file, - const char *shaderString); + const char *shaderString); }; struct gs_duplicator : gs_obj { @@ -581,10 +665,7 @@ struct gs_duplicator : gs_obj { void Start(); - inline void Release() - { - duplicator.Release(); - } + inline void Release() { duplicator.Release(); } gs_duplicator(gs_device_t *device, int monitor_idx); ~gs_duplicator(); @@ -616,14 +697,14 @@ struct gs_pixel_shader : gs_shader { }; struct gs_swap_chain : gs_obj { - uint32_t numBuffers; - HWND hwnd; - gs_init_data initData; - DXGI_SWAP_CHAIN_DESC swapDesc = {}; + uint32_t numBuffers; + HWND hwnd; + gs_init_data initData; + DXGI_SWAP_CHAIN_DESC swapDesc = {}; - gs_texture_2d target; - gs_zstencil_buffer zs; - ComPtr swap; + gs_texture_2d target; + gs_zstencil_buffer zs; + ComPtr swap; void InitTarget(uint32_t cx, uint32_t cy); void InitZStencilBuffer(uint32_t cx, uint32_t cy); @@ -643,27 +724,27 @@ struct gs_swap_chain : gs_obj { }; struct BlendState { - bool blendEnabled; + bool blendEnabled; gs_blend_type srcFactorC; gs_blend_type destFactorC; gs_blend_type srcFactorA; gs_blend_type destFactorA; - bool redEnabled; - bool greenEnabled; - bool blueEnabled; - bool alphaEnabled; + bool redEnabled; + bool greenEnabled; + bool blueEnabled; + bool alphaEnabled; inline BlendState() - : blendEnabled (true), - srcFactorC (GS_BLEND_SRCALPHA), - destFactorC (GS_BLEND_INVSRCALPHA), - srcFactorA (GS_BLEND_ONE), - destFactorA (GS_BLEND_INVSRCALPHA), - redEnabled (true), - greenEnabled (true), - blueEnabled (true), - alphaEnabled (true) + : blendEnabled(true), + srcFactorC(GS_BLEND_SRCALPHA), + destFactorC(GS_BLEND_INVSRCALPHA), + srcFactorA(GS_BLEND_ONE), + destFactorA(GS_BLEND_INVSRCALPHA), + redEnabled(true), + greenEnabled(true), + blueEnabled(true), + alphaEnabled(true) { } @@ -675,14 +756,11 @@ struct BlendState { struct SavedBlendState : BlendState { ComPtr state; - D3D11_BLEND_DESC bd; + D3D11_BLEND_DESC bd; void Rebuild(ID3D11Device *dev); - inline void Release() - { - state.Release(); - } + inline void Release() { state.Release(); } inline SavedBlendState(const BlendState &val, D3D11_BLEND_DESC &desc) : BlendState(val), bd(desc) @@ -697,30 +775,27 @@ struct StencilSide { gs_stencil_op_type zpass; inline StencilSide() - : test (GS_ALWAYS), - fail (GS_KEEP), - zfail (GS_KEEP), - zpass (GS_KEEP) + : test(GS_ALWAYS), fail(GS_KEEP), zfail(GS_KEEP), zpass(GS_KEEP) { } }; struct ZStencilState { - bool depthEnabled; - bool depthWriteEnabled; + bool depthEnabled; + bool depthWriteEnabled; gs_depth_test depthFunc; - bool stencilEnabled; - bool stencilWriteEnabled; - StencilSide stencilFront; - StencilSide stencilBack; + bool stencilEnabled; + bool stencilWriteEnabled; + StencilSide stencilFront; + StencilSide stencilBack; inline ZStencilState() - : depthEnabled (true), - depthWriteEnabled (true), - depthFunc (GS_LESS), - stencilEnabled (false), - stencilWriteEnabled (true) + : depthEnabled(true), + depthWriteEnabled(true), + depthFunc(GS_LESS), + stencilEnabled(false), + stencilWriteEnabled(true) { } @@ -732,32 +807,24 @@ struct ZStencilState { struct SavedZStencilState : ZStencilState { ComPtr state; - D3D11_DEPTH_STENCIL_DESC dsd; + D3D11_DEPTH_STENCIL_DESC dsd; void Rebuild(ID3D11Device *dev); - inline void Release() - { - state.Release(); - } + inline void Release() { state.Release(); } inline SavedZStencilState(const ZStencilState &val, - D3D11_DEPTH_STENCIL_DESC desc) - : ZStencilState (val), - dsd (desc) + D3D11_DEPTH_STENCIL_DESC desc) + : ZStencilState(val), dsd(desc) { } }; struct RasterState { gs_cull_mode cullMode; - bool scissorEnabled; + bool scissorEnabled; - inline RasterState() - : cullMode (GS_BACK), - scissorEnabled (false) - { - } + inline RasterState() : cullMode(GS_BACK), scissorEnabled(false) {} inline RasterState(const RasterState &state) { @@ -767,19 +834,15 @@ struct RasterState { struct SavedRasterState : RasterState { ComPtr state; - D3D11_RASTERIZER_DESC rd; + D3D11_RASTERIZER_DESC rd; void Rebuild(ID3D11Device *dev); - inline void Release() - { - state.Release(); - } + inline void Release() { state.Release(); } inline SavedRasterState(const RasterState &val, - D3D11_RASTERIZER_DESC &desc) - : RasterState (val), - rd (desc) + D3D11_RASTERIZER_DESC &desc) + : RasterState(val), rd(desc) { } }; @@ -789,73 +852,72 @@ struct mat4float { }; struct gs_device { - ComPtr factory; - ComPtr adapter; - ComPtr device; + ComPtr factory; + ComPtr adapter; + ComPtr device; ComPtr context; - uint32_t adpIdx = 0; - bool nv12Supported = false; + uint32_t adpIdx = 0; + bool nv12Supported = false; - gs_texture_2d *curRenderTarget = nullptr; - gs_zstencil_buffer *curZStencilBuffer = nullptr; - int curRenderSide = 0; - gs_texture *curTextures[GS_MAX_TEXTURES]; - gs_sampler_state *curSamplers[GS_MAX_TEXTURES]; - gs_vertex_buffer *curVertexBuffer = nullptr; - gs_index_buffer *curIndexBuffer = nullptr; - gs_vertex_shader *curVertexShader = nullptr; - gs_pixel_shader *curPixelShader = nullptr; - gs_swap_chain *curSwapChain = nullptr; + gs_texture_2d *curRenderTarget = nullptr; + gs_zstencil_buffer *curZStencilBuffer = nullptr; + int curRenderSide = 0; + gs_texture *curTextures[GS_MAX_TEXTURES]; + gs_sampler_state *curSamplers[GS_MAX_TEXTURES]; + gs_vertex_buffer *curVertexBuffer = nullptr; + gs_index_buffer *curIndexBuffer = nullptr; + gs_vertex_shader *curVertexShader = nullptr; + gs_pixel_shader *curPixelShader = nullptr; + gs_swap_chain *curSwapChain = nullptr; - gs_vertex_buffer *lastVertexBuffer = nullptr; - gs_vertex_shader *lastVertexShader = nullptr; + gs_vertex_buffer *lastVertexBuffer = nullptr; + gs_vertex_shader *lastVertexShader = nullptr; - bool zstencilStateChanged = true; - bool rasterStateChanged = true; - bool blendStateChanged = true; - ZStencilState zstencilState; - RasterState rasterState; - BlendState blendState; - vector zstencilStates; - vector rasterStates; - vector blendStates; - ID3D11DepthStencilState *curDepthStencilState = nullptr; - ID3D11RasterizerState *curRasterState = nullptr; - ID3D11BlendState *curBlendState = nullptr; - D3D11_PRIMITIVE_TOPOLOGY curToplogy; + bool zstencilStateChanged = true; + bool rasterStateChanged = true; + bool blendStateChanged = true; + ZStencilState zstencilState; + RasterState rasterState; + BlendState blendState; + vector zstencilStates; + vector rasterStates; + vector blendStates; + ID3D11DepthStencilState *curDepthStencilState = nullptr; + ID3D11RasterizerState *curRasterState = nullptr; + ID3D11BlendState *curBlendState = nullptr; + D3D11_PRIMITIVE_TOPOLOGY curToplogy; - pD3DCompile d3dCompile = nullptr; + pD3DCompile d3dCompile = nullptr; #ifdef DISASSEMBLE_SHADERS - pD3DDisassemble d3dDisassemble = nullptr; + pD3DDisassemble d3dDisassemble = nullptr; #endif - gs_rect viewport; + gs_rect viewport; - vector projStack; + vector projStack; - matrix4 curProjMatrix; - matrix4 curViewMatrix; - matrix4 curViewProjMatrix; + matrix4 curProjMatrix; + matrix4 curViewMatrix; + matrix4 curViewProjMatrix; - gs_obj *first_obj = nullptr; + gs_obj *first_obj = nullptr; void InitCompiler(); void InitFactory(uint32_t adapterIdx); void InitDevice(uint32_t adapterIdx); ID3D11DepthStencilState *AddZStencilState(); - ID3D11RasterizerState *AddRasterState(); - ID3D11BlendState *AddBlendState(); + ID3D11RasterizerState *AddRasterState(); + ID3D11BlendState *AddBlendState(); void UpdateZStencilState(); void UpdateRasterState(); void UpdateBlendState(); void LoadVertexBufferData(); - inline void CopyTex(ID3D11Texture2D *dst, - uint32_t dst_x, uint32_t dst_y, - gs_texture_t *src, uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h); + inline void CopyTex(ID3D11Texture2D *dst, uint32_t dst_x, + uint32_t dst_y, gs_texture_t *src, uint32_t src_x, + uint32_t src_y, uint32_t src_w, uint32_t src_h); void UpdateViewProjMatrix(); @@ -868,4 +930,4 @@ struct gs_device { }; extern "C" EXPORT int device_texture_acquire_sync(gs_texture_t *tex, - uint64_t key, uint32_t ms); + uint64_t key, uint32_t ms); diff --git a/libobs-d3d11/d3d11-texture2d.cpp b/libobs-d3d11/d3d11-texture2d.cpp index a3fa205..687f488 100644 --- a/libobs-d3d11/d3d11-texture2d.cpp +++ b/libobs-d3d11/d3d11-texture2d.cpp @@ -20,11 +20,11 @@ void gs_texture_2d::InitSRD(vector &srd) { - uint32_t rowSizeBytes = width * gs_get_format_bpp(format); - uint32_t texSizeBytes = height * rowSizeBytes / 8; - size_t textures = type == GS_TEXTURE_2D ? 1 : 6; + uint32_t rowSizeBytes = width * gs_get_format_bpp(format); + uint32_t texSizeBytes = height * rowSizeBytes / 8; + size_t textures = type == GS_TEXTURE_2D ? 1 : 6; uint32_t actual_levels = levels; - size_t curTex = 0; + size_t curTex = 0; if (!actual_levels) actual_levels = gs_get_total_levels(width, height); @@ -37,8 +37,8 @@ void gs_texture_2d::InitSRD(vector &srd) for (uint32_t j = 0; j < actual_levels; j++) { D3D11_SUBRESOURCE_DATA newSRD; - newSRD.pSysMem = data[curTex++].data(); - newSRD.SysMemPitch = newRowSize; + newSRD.pSysMem = data[curTex++].data(); + newSRD.SysMemPitch = newRowSize; newSRD.SysMemSlicePitch = newTexSize; srd.push_back(newSRD); @@ -78,8 +78,10 @@ void gs_texture_2d::GetSharedHandle(IDXGIResource *dxgi_res) hr = dxgi_res->GetSharedHandle(&handle); if (FAILED(hr)) { - blog(LOG_WARNING, "GetSharedHandle: Failed to " - "get shared handle: %08lX", hr); + blog(LOG_WARNING, + "GetSharedHandle: Failed to " + "get shared handle: %08lX", + hr); } else { sharedHandle = (uint32_t)(uintptr_t)handle; } @@ -90,16 +92,15 @@ void gs_texture_2d::InitTexture(const uint8_t **data) HRESULT hr; memset(&td, 0, sizeof(td)); - td.Width = width; - td.Height = height; - td.MipLevels = genMipmaps ? 0 : levels; - td.ArraySize = type == GS_TEXTURE_CUBE ? 6 : 1; - td.Format = nv12 ? DXGI_FORMAT_NV12 : dxgiFormat; - td.BindFlags = D3D11_BIND_SHADER_RESOURCE; + td.Width = width; + td.Height = height; + td.MipLevels = genMipmaps ? 0 : levels; + td.ArraySize = type == GS_TEXTURE_CUBE ? 6 : 1; + td.Format = nv12 ? DXGI_FORMAT_NV12 : dxgiFormat; + td.BindFlags = D3D11_BIND_SHADER_RESOURCE; td.SampleDesc.Count = 1; - td.CPUAccessFlags = isDynamic ? D3D11_CPU_ACCESS_WRITE : 0; - td.Usage = isDynamic ? D3D11_USAGE_DYNAMIC : - D3D11_USAGE_DEFAULT; + td.CPUAccessFlags = isDynamic ? D3D11_CPU_ACCESS_WRITE : 0; + td.Usage = isDynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT; if (type == GS_TEXTURE_CUBE) td.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE; @@ -121,13 +122,13 @@ void gs_texture_2d::InitTexture(const uint8_t **data) } hr = device->device->CreateTexture2D(&td, data ? srd.data() : NULL, - texture.Assign()); + texture.Assign()); if (FAILED(hr)) throw HRError("Failed to create 2D texture", hr); if (isGDICompatible) { hr = texture->QueryInterface(__uuidof(IDXGISurface1), - (void**)gdiSurface.Assign()); + (void **)gdiSurface.Assign()); if (FAILED(hr)) throw HRError("Failed to create GDI surface", hr); } @@ -138,22 +139,24 @@ void gs_texture_2d::InitTexture(const uint8_t **data) texture->SetEvictionPriority(DXGI_RESOURCE_PRIORITY_MAXIMUM); hr = texture->QueryInterface(__uuidof(IDXGIResource), - (void**)&dxgi_res); + (void **)&dxgi_res); if (FAILED(hr)) { - blog(LOG_WARNING, "InitTexture: Failed to query " - "interface: %08lX", hr); + blog(LOG_WARNING, + "InitTexture: Failed to query " + "interface: %08lX", + hr); } else { GetSharedHandle(dxgi_res); if (flags & GS_SHARED_KM_TEX) { ComPtr km; hr = texture->QueryInterface( - __uuidof(IDXGIKeyedMutex), - (void**)&km); + __uuidof(IDXGIKeyedMutex), + (void **)&km); if (FAILED(hr)) { throw HRError("Failed to query " - "IDXGIKeyedMutex", - hr); + "IDXGIKeyedMutex", + hr); } km->AcquireSync(0, INFINITE); @@ -181,7 +184,7 @@ void gs_texture_2d::InitResourceView() } hr = device->device->CreateShaderResourceView(texture, &resourceDesc, - shaderRes.Assign()); + shaderRes.Assign()); if (FAILED(hr)) throw HRError("Failed to create resource view", hr); } @@ -193,27 +196,28 @@ void gs_texture_2d::InitRenderTargets() D3D11_RENDER_TARGET_VIEW_DESC rtv; rtv.Format = dxgiFormat; rtv.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtv.Texture2D.MipSlice = 0; + rtv.Texture2D.MipSlice = 0; - hr = device->device->CreateRenderTargetView(texture, &rtv, - renderTarget[0].Assign()); + hr = device->device->CreateRenderTargetView( + texture, &rtv, renderTarget[0].Assign()); if (FAILED(hr)) throw HRError("Failed to create render target view", - hr); + hr); } else { D3D11_RENDER_TARGET_VIEW_DESC rtv; rtv.Format = dxgiFormat; rtv.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtv.Texture2DArray.MipSlice = 0; + rtv.Texture2DArray.MipSlice = 0; rtv.Texture2DArray.ArraySize = 1; for (UINT i = 0; i < 6; i++) { rtv.Texture2DArray.FirstArraySlice = i; - hr = device->device->CreateRenderTargetView(texture, - &rtv, renderTarget[i].Assign()); + hr = device->device->CreateRenderTargetView( + texture, &rtv, renderTarget[i].Assign()); if (FAILED(hr)) throw HRError("Failed to create cube render " - "target view", hr); + "target view", + hr); } } } @@ -221,22 +225,22 @@ void gs_texture_2d::InitRenderTargets() #define SHARED_FLAGS (GS_SHARED_TEX | GS_SHARED_KM_TEX) gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t width, - uint32_t height, gs_color_format colorFormat, uint32_t levels, - const uint8_t **data, uint32_t flags_, gs_texture_type type, - bool gdiCompatible, bool nv12_) - : gs_texture (device, gs_type::gs_texture_2d, type, levels, - colorFormat), - width (width), - height (height), - flags (flags_), - dxgiFormat (ConvertGSTextureFormat(format)), - isRenderTarget ((flags_ & GS_RENDER_TARGET) != 0), - isGDICompatible (gdiCompatible), - isDynamic ((flags_ & GS_DYNAMIC) != 0), - isShared ((flags_ & SHARED_FLAGS) != 0), - genMipmaps ((flags_ & GS_BUILD_MIPMAPS) != 0), - sharedHandle (GS_INVALID_HANDLE), - nv12 (nv12_) + uint32_t height, gs_color_format colorFormat, + uint32_t levels, const uint8_t **data, + uint32_t flags_, gs_texture_type type, + bool gdiCompatible, bool nv12_) + : gs_texture(device, gs_type::gs_texture_2d, type, levels, colorFormat), + width(width), + height(height), + flags(flags_), + dxgiFormat(ConvertGSTextureFormat(format)), + isRenderTarget((flags_ & GS_RENDER_TARGET) != 0), + isGDICompatible(gdiCompatible), + isDynamic((flags_ & GS_DYNAMIC) != 0), + isShared((flags_ & SHARED_FLAGS) != 0), + genMipmaps((flags_ & GS_BUILD_MIPMAPS) != 0), + sharedHandle(GS_INVALID_HANDLE), + nv12(nv12_) { InitTexture(data); InitResourceView(); @@ -246,25 +250,25 @@ gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t width, } gs_texture_2d::gs_texture_2d(gs_device_t *device, ID3D11Texture2D *nv12tex, - uint32_t flags_) - : gs_texture (device, gs_type::gs_texture_2d, GS_TEXTURE_2D), - isRenderTarget ((flags_ & GS_RENDER_TARGET) != 0), - isDynamic ((flags_ & GS_DYNAMIC) != 0), - isShared ((flags_ & SHARED_FLAGS) != 0), - genMipmaps ((flags_ & GS_BUILD_MIPMAPS) != 0), - nv12 (true) + uint32_t flags_) + : gs_texture(device, gs_type::gs_texture_2d, GS_TEXTURE_2D), + isRenderTarget((flags_ & GS_RENDER_TARGET) != 0), + isDynamic((flags_ & GS_DYNAMIC) != 0), + isShared((flags_ & SHARED_FLAGS) != 0), + genMipmaps((flags_ & GS_BUILD_MIPMAPS) != 0), + nv12(true), + texture(nv12tex) { - texture = nv12tex; texture->GetDesc(&td); - this->type = GS_TEXTURE_2D; - this->format = GS_R8G8; - this->flags = flags_; - this->levels = 1; - this->device = device; - this->chroma = true; - this->width = td.Width / 2; - this->height = td.Height / 2; + this->type = GS_TEXTURE_2D; + this->format = GS_R8G8; + this->flags = flags_; + this->levels = 1; + this->device = device; + this->chroma = true; + this->width = td.Width / 2; + this->height = td.Height / 2; this->dxgiFormat = DXGI_FORMAT_R8G8_UNORM; InitResourceView(); @@ -273,35 +277,35 @@ gs_texture_2d::gs_texture_2d(gs_device_t *device, ID3D11Texture2D *nv12tex, } gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t handle) - : gs_texture (device, gs_type::gs_texture_2d, - GS_TEXTURE_2D), - isShared (true), - sharedHandle (handle) + : gs_texture(device, gs_type::gs_texture_2d, GS_TEXTURE_2D), + isShared(true), + sharedHandle(handle) { HRESULT hr; hr = device->device->OpenSharedResource((HANDLE)(uintptr_t)handle, - __uuidof(ID3D11Texture2D), (void**)texture.Assign()); + __uuidof(ID3D11Texture2D), + (void **)texture.Assign()); if (FAILED(hr)) throw HRError("Failed to open shared 2D texture", hr); texture->GetDesc(&td); - this->type = GS_TEXTURE_2D; - this->format = ConvertDXGITextureFormat(td.Format); - this->levels = 1; - this->device = device; + this->type = GS_TEXTURE_2D; + this->format = ConvertDXGITextureFormat(td.Format); + this->levels = 1; + this->device = device; - this->width = td.Width; - this->height = td.Height; + this->width = td.Width; + this->height = td.Height; this->dxgiFormat = td.Format; memset(&resourceDesc, 0, sizeof(resourceDesc)); - resourceDesc.Format = td.Format; - resourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + resourceDesc.Format = td.Format; + resourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; resourceDesc.Texture2D.MipLevels = 1; hr = device->device->CreateShaderResourceView(texture, &resourceDesc, - shaderRes.Assign()); + shaderRes.Assign()); if (FAILED(hr)) throw HRError("Failed to create shader resource view", hr); } diff --git a/libobs-d3d11/d3d11-vertexbuffer.cpp b/libobs-d3d11/d3d11-vertexbuffer.cpp index 580aad6..70a68a9 100644 --- a/libobs-d3d11/d3d11-vertexbuffer.cpp +++ b/libobs-d3d11/d3d11-vertexbuffer.cpp @@ -19,27 +19,27 @@ #include #include "d3d11-subsystem.hpp" -static inline void PushBuffer(vector &buffers, - vector &strides, ID3D11Buffer *buffer, - size_t elementSize, const char *name) +static inline void PushBuffer(vector &buffers, + vector &strides, ID3D11Buffer *buffer, + size_t elementSize, const char *name) { if (buffer) { buffers.push_back(buffer); strides.push_back((uint32_t)elementSize); } else { blog(LOG_ERROR, "This vertex shader requires a %s buffer", - name); + name); } } void gs_vertex_buffer::FlushBuffer(ID3D11Buffer *buffer, void *array, - size_t elementSize) + size_t elementSize) { D3D11_MAPPED_SUBRESOURCE msr; HRESULT hr; - if (FAILED(hr = device->context->Map(buffer, 0, - D3D11_MAP_WRITE_DISCARD, 0, &msr))) + if (FAILED(hr = device->context->Map(buffer, 0, D3D11_MAP_WRITE_DISCARD, + 0, &msr))) throw HRError("Failed to map buffer", hr); memcpy(msr.pData, array, elementSize * vbd.data->num); @@ -47,46 +47,49 @@ void gs_vertex_buffer::FlushBuffer(ID3D11Buffer *buffer, void *array, } void gs_vertex_buffer::MakeBufferList(gs_vertex_shader *shader, - vector &buffers, vector &strides) + vector &buffers, + vector &strides) { PushBuffer(buffers, strides, vertexBuffer, sizeof(vec3), "point"); if (shader->hasNormals) PushBuffer(buffers, strides, normalBuffer, sizeof(vec3), - "normal"); + "normal"); if (shader->hasColors) PushBuffer(buffers, strides, colorBuffer, sizeof(uint32_t), - "color"); + "color"); if (shader->hasTangents) PushBuffer(buffers, strides, tangentBuffer, sizeof(vec3), - "tangent"); + "tangent"); if (shader->nTexUnits <= uvBuffers.size()) { for (size_t i = 0; i < shader->nTexUnits; i++) { buffers.push_back(uvBuffers[i]); strides.push_back((uint32_t)uvSizes[i]); } } else { - blog(LOG_ERROR, "This vertex shader requires at least %u " - "texture buffers.", - (uint32_t)shader->nTexUnits); + blog(LOG_ERROR, + "This vertex shader requires at least %u " + "texture buffers.", + (uint32_t)shader->nTexUnits); } } void gs_vertex_buffer::InitBuffer(const size_t elementSize, - const size_t numVerts, void *array, ID3D11Buffer **buffer) + const size_t numVerts, void *array, + ID3D11Buffer **buffer) { D3D11_BUFFER_DESC bd; D3D11_SUBRESOURCE_DATA srd; HRESULT hr; - memset(&bd, 0, sizeof(bd)); + memset(&bd, 0, sizeof(bd)); memset(&srd, 0, sizeof(srd)); - bd.Usage = dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT; + bd.Usage = dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT; bd.CPUAccessFlags = dynamic ? D3D11_CPU_ACCESS_WRITE : 0; - bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bd.ByteWidth = UINT(elementSize * numVerts); - srd.pSysMem = array; + bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bd.ByteWidth = UINT(elementSize * numVerts); + srd.pSysMem = array; hr = device->device->CreateBuffer(&bd, &srd, buffer); if (FAILED(hr)) @@ -96,22 +99,22 @@ void gs_vertex_buffer::InitBuffer(const size_t elementSize, void gs_vertex_buffer::BuildBuffers() { InitBuffer(sizeof(vec3), vbd.data->num, vbd.data->points, - &vertexBuffer); + &vertexBuffer); if (vbd.data->normals) InitBuffer(sizeof(vec3), vbd.data->num, vbd.data->normals, - &normalBuffer); + &normalBuffer); if (vbd.data->tangents) InitBuffer(sizeof(vec3), vbd.data->num, vbd.data->tangents, - &tangentBuffer); + &tangentBuffer); if (vbd.data->colors) InitBuffer(sizeof(uint32_t), vbd.data->num, vbd.data->colors, - &colorBuffer); + &colorBuffer); for (size_t i = 0; i < vbd.data->num_tex; i++) { - struct gs_tvertarray *tverts = vbd.data->tvarray+i; + struct gs_tvertarray *tverts = vbd.data->tvarray + i; if (tverts->width != 2 && tverts->width != 4) throw "Invalid texture vertex size specified"; @@ -120,7 +123,7 @@ void gs_vertex_buffer::BuildBuffers() ComPtr buffer; InitBuffer(tverts->width * sizeof(float), vbd.data->num, - tverts->array, &buffer); + tverts->array, &buffer); uvBuffers.push_back(buffer); uvSizes.push_back(tverts->width * sizeof(float)); @@ -128,11 +131,11 @@ void gs_vertex_buffer::BuildBuffers() } gs_vertex_buffer::gs_vertex_buffer(gs_device_t *device, struct gs_vb_data *data, - uint32_t flags) - : gs_obj (device, gs_type::gs_vertex_buffer), - dynamic ((flags & GS_DYNAMIC) != 0), - vbd (data), - numVerts (data->num) + uint32_t flags) + : gs_obj(device, gs_type::gs_vertex_buffer), + dynamic((flags & GS_DYNAMIC) != 0), + vbd(data), + numVerts(data->num) { if (!data->num) throw "Cannot initialize vertex buffer with 0 vertices"; diff --git a/libobs-d3d11/d3d11-zstencilbuffer.cpp b/libobs-d3d11/d3d11-zstencilbuffer.cpp index 8c077d1..34b7e49 100644 --- a/libobs-d3d11/d3d11-zstencilbuffer.cpp +++ b/libobs-d3d11/d3d11-zstencilbuffer.cpp @@ -22,37 +22,37 @@ void gs_zstencil_buffer::InitBuffer() HRESULT hr; memset(&td, 0, sizeof(td)); - td.Width = width; - td.Height = height; - td.MipLevels = 1; - td.ArraySize = 1; - td.Format = dxgiFormat; - td.BindFlags = D3D11_BIND_DEPTH_STENCIL; + td.Width = width; + td.Height = height; + td.MipLevels = 1; + td.ArraySize = 1; + td.Format = dxgiFormat; + td.BindFlags = D3D11_BIND_DEPTH_STENCIL; td.SampleDesc.Count = 1; - td.Usage = D3D11_USAGE_DEFAULT; + td.Usage = D3D11_USAGE_DEFAULT; hr = device->device->CreateTexture2D(&td, NULL, texture.Assign()); if (FAILED(hr)) throw HRError("Failed to create depth stencil texture", hr); memset(&dsvd, 0, sizeof(dsvd)); - dsvd.Format = dxgiFormat; + dsvd.Format = dxgiFormat; dsvd.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; hr = device->device->CreateDepthStencilView(texture, &dsvd, - view.Assign()); + view.Assign()); if (FAILED(hr)) throw HRError("Failed to create depth stencil view", hr); } -gs_zstencil_buffer::gs_zstencil_buffer(gs_device_t *device, - uint32_t width, uint32_t height, - gs_zstencil_format format) - : gs_obj (device, gs_type::gs_zstencil_buffer), - width (width), - height (height), - format (format), - dxgiFormat (ConvertGSZStencilFormat(format)) +gs_zstencil_buffer::gs_zstencil_buffer(gs_device_t *device, uint32_t width, + uint32_t height, + gs_zstencil_format format) + : gs_obj(device, gs_type::gs_zstencil_buffer), + width(width), + height(height), + format(format), + dxgiFormat(ConvertGSZStencilFormat(format)) { InitBuffer(); } diff --git a/libobs-opengl/gl-cocoa.m b/libobs-opengl/gl-cocoa.m index 0bcbca2..70d667f 100644 --- a/libobs-opengl/gl-cocoa.m +++ b/libobs-opengl/gl-cocoa.m @@ -21,10 +21,8 @@ #import #import - //#include "util/darray.h" - struct gl_windowinfo { NSView *view; }; @@ -37,9 +35,15 @@ static NSOpenGLContext *gl_context_create(void) { unsigned attrib_count = 0; -#define ADD_ATTR(x) \ - { attributes[attrib_count++] = (NSOpenGLPixelFormatAttribute)x; } -#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); } +#define ADD_ATTR(x) \ + { \ + attributes[attrib_count++] = (NSOpenGLPixelFormatAttribute)x; \ + } +#define ADD_ATTR2(x, y) \ + { \ + ADD_ATTR(x); \ + ADD_ATTR(y); \ + } NSOpenGLPixelFormatAttribute attributes[40]; @@ -52,7 +56,7 @@ static NSOpenGLContext *gl_context_create(void) NSOpenGLPixelFormat *pf; pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; - if(!pf) { + if (!pf) { blog(LOG_ERROR, "Failed to create pixel format"); return NULL; } @@ -60,7 +64,7 @@ static NSOpenGLContext *gl_context_create(void) NSOpenGLContext *context; context = [[NSOpenGLContext alloc] initWithFormat:pf shareContext:nil]; [pf release]; - if(!context) { + if (!context) { blog(LOG_ERROR, "Failed to create context"); return NULL; } @@ -98,7 +102,7 @@ fail: void gl_platform_destroy(struct gl_platform *platform) { - if(!platform) + if (!platform) return; [platform->context release]; @@ -121,10 +125,10 @@ void gl_platform_cleanup_swapchain(struct gs_swap_chain *swap) struct gl_windowinfo *gl_windowinfo_create(const struct gs_init_data *info) { - if(!info) + if (!info) return NULL; - if(!info->window.view) + if (!info->window.view) return NULL; struct gl_windowinfo *wi = bzalloc(sizeof(struct gl_windowinfo)); @@ -137,7 +141,7 @@ struct gl_windowinfo *gl_windowinfo_create(const struct gs_init_data *info) void gl_windowinfo_destroy(struct gl_windowinfo *wi) { - if(!wi) + if (!wi) return; wi->view = nil; @@ -161,9 +165,14 @@ void device_leave_context(gs_device_t *device) [NSOpenGLContext clearCurrentContext]; } +void *device_get_device_obj(gs_device_t *device) +{ + return device->plat->context; +} + void device_load_swapchain(gs_device_t *device, gs_swapchain_t *swap) { - if(device->cur_swap == swap) + if (device->cur_swap == swap) return; device->cur_swap = swap; @@ -180,14 +189,16 @@ void device_present(gs_device_t *device) } void gl_getclientsize(const struct gs_swap_chain *swap, uint32_t *width, - uint32_t *height) + uint32_t *height) { - if(width) *width = swap->info.cx; - if(height) *height = swap->info.cy; + if (width) + *width = swap->info.cx; + if (height) + *height = swap->info.cy; } gs_texture_t *device_texture_create_from_iosurface(gs_device_t *device, - void *iosurf) + void *iosurf) { IOSurfaceRef ref = (IOSurfaceRef)iosurf; struct gs_texture_2d *tex = bzalloc(sizeof(struct gs_texture_2d)); @@ -195,23 +206,23 @@ gs_texture_t *device_texture_create_from_iosurface(gs_device_t *device, OSType pf = IOSurfaceGetPixelFormat(ref); if (pf != 'BGRA') blog(LOG_ERROR, "Unexpected pixel format: %d (%c%c%c%c)", pf, - pf >> 24, pf >> 16, pf >> 8, pf); + pf >> 24, pf >> 16, pf >> 8, pf); const enum gs_color_format color_format = GS_BGRA; - tex->base.device = device; - tex->base.type = GS_TEXTURE_2D; - tex->base.format = GS_BGRA; - tex->base.levels = 1; - tex->base.gl_format = convert_gs_format(color_format); + tex->base.device = device; + tex->base.type = GS_TEXTURE_2D; + tex->base.format = GS_BGRA; + tex->base.levels = 1; + tex->base.gl_format = convert_gs_format(color_format); tex->base.gl_internal_format = convert_gs_internal_format(color_format); - tex->base.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; - tex->base.gl_target = GL_TEXTURE_RECTANGLE; - tex->base.is_dynamic = false; - tex->base.is_render_target = false; - tex->base.gen_mipmaps = false; - tex->width = IOSurfaceGetWidth(ref); - tex->height = IOSurfaceGetHeight(ref); + tex->base.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; + tex->base.gl_target = GL_TEXTURE_RECTANGLE; + tex->base.is_dynamic = false; + tex->base.is_render_target = false; + tex->base.gen_mipmaps = false; + tex->width = IOSurfaceGetWidth(ref); + tex->height = IOSurfaceGetHeight(ref); if (!gl_gen_textures(1, &tex->base.texture)) goto fail; @@ -220,34 +231,30 @@ gs_texture_t *device_texture_create_from_iosurface(gs_device_t *device, goto fail; CGLError err = CGLTexImageIOSurface2D( - [[NSOpenGLContext currentContext] CGLContextObj], - tex->base.gl_target, - tex->base.gl_internal_format, - tex->width, tex->height, - tex->base.gl_format, - tex->base.gl_type, - ref, 0); - - if(err != kCGLNoError) { - blog(LOG_ERROR, "CGLTexImageIOSurface2D: %u, %s" - " (device_texture_create_from_iosurface)", - err, CGLErrorString(err)); + [[NSOpenGLContext currentContext] CGLContextObj], + tex->base.gl_target, tex->base.gl_internal_format, tex->width, + tex->height, tex->base.gl_format, tex->base.gl_type, ref, 0); + + if (err != kCGLNoError) { + blog(LOG_ERROR, + "CGLTexImageIOSurface2D: %u, %s" + " (device_texture_create_from_iosurface)", + err, CGLErrorString(err)); gl_success("CGLTexImageIOSurface2D"); goto fail; } - if (!gl_tex_param_i(tex->base.gl_target, - GL_TEXTURE_MAX_LEVEL, 0)) + if (!gl_tex_param_i(tex->base.gl_target, GL_TEXTURE_MAX_LEVEL, 0)) goto fail; if (!gl_bind_texture(tex->base.gl_target, 0)) goto fail; - return (gs_texture_t*)tex; + return (gs_texture_t *)tex; fail: - gs_texture_destroy((gs_texture_t*)tex); + gs_texture_destroy((gs_texture_t *)tex); blog(LOG_ERROR, "device_texture_create_from_iosurface (GL) failed"); return NULL; } @@ -260,34 +267,31 @@ bool gs_texture_rebind_iosurface(gs_texture_t *texture, void *iosurf) if (!iosurf) return false; - struct gs_texture_2d *tex = (struct gs_texture_2d*)texture; + struct gs_texture_2d *tex = (struct gs_texture_2d *)texture; IOSurfaceRef ref = (IOSurfaceRef)iosurf; OSType pf = IOSurfaceGetPixelFormat(ref); if (pf != 'BGRA') blog(LOG_ERROR, "Unexpected pixel format: %d (%c%c%c%c)", pf, - pf >> 24, pf >> 16, pf >> 8, pf); + pf >> 24, pf >> 16, pf >> 8, pf); if (tex->width != IOSurfaceGetWidth(ref) || - tex->height != IOSurfaceGetHeight(ref)) + tex->height != IOSurfaceGetHeight(ref)) return false; if (!gl_bind_texture(tex->base.gl_target, tex->base.texture)) return false; CGLError err = CGLTexImageIOSurface2D( - [[NSOpenGLContext currentContext] CGLContextObj], - tex->base.gl_target, - tex->base.gl_internal_format, - tex->width, tex->height, - tex->base.gl_format, - tex->base.gl_type, - ref, 0); - - if(err != kCGLNoError) { - blog(LOG_ERROR, "CGLTexImageIOSurface2D: %u, %s" - " (gs_texture_rebind_iosurface)", - err, CGLErrorString(err)); + [[NSOpenGLContext currentContext] CGLContextObj], + tex->base.gl_target, tex->base.gl_internal_format, tex->width, + tex->height, tex->base.gl_format, tex->base.gl_type, ref, 0); + + if (err != kCGLNoError) { + blog(LOG_ERROR, + "CGLTexImageIOSurface2D: %u, %s" + " (gs_texture_rebind_iosurface)", + err, CGLErrorString(err)); gl_success("CGLTexImageIOSurface2D"); return false; diff --git a/libobs-opengl/gl-helpers.c b/libobs-opengl/gl-helpers.c index c6e9012..03574c8 100644 --- a/libobs-opengl/gl-helpers.c +++ b/libobs-opengl/gl-helpers.c @@ -18,9 +18,9 @@ #include "gl-subsystem.h" bool gl_init_face(GLenum target, GLenum type, uint32_t num_levels, - GLenum format, GLint internal_format, bool compressed, - uint32_t width, uint32_t height, uint32_t size, - const uint8_t ***p_data) + GLenum format, GLint internal_format, bool compressed, + uint32_t width, uint32_t height, uint32_t size, + const uint8_t ***p_data) { bool success = true; const uint8_t **data = p_data ? *p_data : NULL; @@ -29,14 +29,14 @@ bool gl_init_face(GLenum target, GLenum type, uint32_t num_levels, for (i = 0; i < num_levels; i++) { if (compressed) { glCompressedTexImage2D(target, i, internal_format, - width, height, 0, size, - data ? *data : NULL); + width, height, 0, size, + data ? *data : NULL); if (!gl_success("glCompressedTexImage2D")) success = false; } else { glTexImage2D(target, i, internal_format, width, height, - 0, format, type, data ? *data : NULL); + 0, format, type, data ? *data : NULL); if (!gl_success("glTexImage2D")) success = false; } @@ -44,12 +44,14 @@ bool gl_init_face(GLenum target, GLenum type, uint32_t num_levels, if (data) data++; - size /= 4; - width /= 2; + size /= 4; + width /= 2; height /= 2; - if (width == 0) width = 1; - if (height == 0) height = 1; + if (width == 0) + width = 1; + if (height == 0) + height = 1; } if (data) @@ -58,8 +60,8 @@ bool gl_init_face(GLenum target, GLenum type, uint32_t num_levels, } static bool gl_copy_fbo(struct gs_texture *dst, uint32_t dst_x, uint32_t dst_y, - struct gs_texture *src, uint32_t src_x, uint32_t src_y, - uint32_t width, uint32_t height) + struct gs_texture *src, uint32_t src_x, uint32_t src_y, + uint32_t width, uint32_t height) { struct fbo_info *fbo = get_fbo(src, width, height); GLint last_fbo; @@ -76,7 +78,7 @@ static bool gl_copy_fbo(struct gs_texture *dst, uint32_t dst_x, uint32_t dst_y, goto fail; glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 0, - src->gl_target, src->texture, 0); + src->gl_target, src->texture, 0); if (!gl_success("glFrameBufferTexture2D")) goto fail; @@ -85,7 +87,7 @@ static bool gl_copy_fbo(struct gs_texture *dst, uint32_t dst_x, uint32_t dst_y, goto fail; glCopyTexSubImage2D(dst->gl_target, 0, dst_x, dst_y, src_x, src_y, - width, height); + width, height); if (!gl_success("glCopyTexSubImage2D")) goto fail; @@ -101,27 +103,27 @@ fail: } bool gl_copy_texture(struct gs_device *device, struct gs_texture *dst, - uint32_t dst_x, uint32_t dst_y, struct gs_texture *src, - uint32_t src_x, uint32_t src_y, uint32_t width, - uint32_t height) + uint32_t dst_x, uint32_t dst_y, struct gs_texture *src, + uint32_t src_x, uint32_t src_y, uint32_t width, + uint32_t height) { bool success = false; if (device->copy_type == COPY_TYPE_ARB) { glCopyImageSubData(src->texture, src->gl_target, 0, src_x, - src_y, 0, dst->texture, dst->gl_target, 0, - dst_x, dst_y, 0, width, height, 1); + src_y, 0, dst->texture, dst->gl_target, 0, + dst_x, dst_y, 0, width, height, 1); success = gl_success("glCopyImageSubData"); } else if (device->copy_type == COPY_TYPE_NV) { glCopyImageSubDataNV(src->texture, src->gl_target, 0, src_x, - src_y, 0, dst->texture, dst->gl_target, 0, - dst_x, dst_y, 0, width, height, 1); + src_y, 0, dst->texture, dst->gl_target, 0, + dst_x, dst_y, 0, width, height, 1); success = gl_success("glCopyImageSubDataNV"); } else if (device->copy_type == COPY_TYPE_FBO_BLIT) { success = gl_copy_fbo(dst, dst_x, dst_y, src, src_x, src_y, - width, height); + width, height); if (!success) blog(LOG_ERROR, "gl_copy_texture failed"); } @@ -130,7 +132,7 @@ bool gl_copy_texture(struct gs_device *device, struct gs_texture *dst, } bool gl_create_buffer(GLenum target, GLuint *buffer, GLsizeiptr size, - const GLvoid *data, GLenum usage) + const GLvoid *data, GLenum usage) { bool success; if (!gl_gen_buffers(1, buffer)) @@ -156,8 +158,7 @@ bool update_buffer(GLenum target, GLuint buffer, const void *data, size_t size) /* glMapBufferRange with these flags will actually give far better * performance than a plain glMapBuffer call */ ptr = glMapBufferRange(target, 0, size, - GL_MAP_WRITE_BIT | - GL_MAP_INVALIDATE_BUFFER_BIT); + GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); success = gl_success("glMapBufferRange"); if (success && ptr) { memcpy(ptr, data, size); diff --git a/libobs-opengl/gl-helpers.h b/libobs-opengl/gl-helpers.h index fe9959a..10a1c9f 100644 --- a/libobs-opengl/gl-helpers.h +++ b/libobs-opengl/gl-helpers.h @@ -17,6 +17,48 @@ #pragma once +static const char *gl_error_to_str(GLenum errorcode) +{ + static const struct { + GLenum error; + const char *str; + } err_to_str[] = { + { + GL_INVALID_ENUM, + "GL_INVALID_ENUM", + }, + { + GL_INVALID_VALUE, + "GL_INVALID_VALUE", + }, + { + GL_INVALID_OPERATION, + "GL_INVALID_OPERATION", + }, + { + GL_INVALID_FRAMEBUFFER_OPERATION, + "GL_INVALID_FRAMEBUFFER_OPERATION", + }, + { + GL_OUT_OF_MEMORY, + "GL_OUT_OF_MEMORY", + }, + { + GL_STACK_UNDERFLOW, + "GL_STACK_UNDERFLOW", + }, + { + GL_STACK_OVERFLOW, + "GL_STACK_OVERFLOW", + }, + }; + for (size_t i = 0; i < sizeof(err_to_str) / sizeof(*err_to_str); i++) { + if (err_to_str[i].error == errorcode) + return err_to_str[i].str; + } + return "Unknown"; +} + /* * Okay, so GL error handling is.. unclean to work with. I don't want * to have to keep typing out the same stuff over and over again do I'll just @@ -27,8 +69,20 @@ static inline bool gl_success(const char *funcname) { GLenum errorcode = glGetError(); if (errorcode != GL_NO_ERROR) { - blog(LOG_ERROR, "%s failed, glGetError returned 0x%X", - funcname, errorcode); + int attempts = 8; + do { + blog(LOG_ERROR, + "%s failed, glGetError returned %s(0x%X)", + funcname, gl_error_to_str(errorcode), errorcode); + errorcode = glGetError(); + + --attempts; + if (attempts == 0) { + blog(LOG_ERROR, + "Too many GL errors, moving on"); + break; + } + } while (errorcode != GL_NO_ERROR); return false; } @@ -144,17 +198,17 @@ static inline bool gl_get_integer_v(GLenum pname, GLint *params) } extern bool gl_init_face(GLenum target, GLenum type, uint32_t num_levels, - GLenum format, GLint internal_format, bool compressed, - uint32_t width, uint32_t height, uint32_t size, - const uint8_t ***p_data); + GLenum format, GLint internal_format, bool compressed, + uint32_t width, uint32_t height, uint32_t size, + const uint8_t ***p_data); extern bool gl_copy_texture(struct gs_device *device, struct gs_texture *dst, - uint32_t dst_x, uint32_t dst_y, struct gs_texture *src, - uint32_t src_x, uint32_t src_y, uint32_t width, - uint32_t height); + uint32_t dst_x, uint32_t dst_y, + struct gs_texture *src, uint32_t src_x, + uint32_t src_y, uint32_t width, uint32_t height); extern bool gl_create_buffer(GLenum target, GLuint *buffer, GLsizeiptr size, - const GLvoid *data, GLenum usage); + const GLvoid *data, GLenum usage); extern bool update_buffer(GLenum target, GLuint buffer, const void *data, - size_t size); + size_t size); diff --git a/libobs-opengl/gl-indexbuffer.c b/libobs-opengl/gl-indexbuffer.c index aef280f..ec09c1e 100644 --- a/libobs-opengl/gl-indexbuffer.c +++ b/libobs-opengl/gl-indexbuffer.c @@ -23,7 +23,7 @@ static inline bool init_ib(struct gs_index_buffer *ib) bool success; success = gl_create_buffer(GL_ELEMENT_ARRAY_BUFFER, &ib->buffer, - ib->size, ib->data, usage); + ib->size, ib->data, usage); if (!ib->dynamic) { bfree(ib->data); @@ -34,21 +34,22 @@ static inline bool init_ib(struct gs_index_buffer *ib) } gs_indexbuffer_t *device_indexbuffer_create(gs_device_t *device, - enum gs_index_type type, void *indices, size_t num, - uint32_t flags) + enum gs_index_type type, + void *indices, size_t num, + uint32_t flags) { struct gs_index_buffer *ib = bzalloc(sizeof(struct gs_index_buffer)); size_t width = type == GS_UNSIGNED_LONG ? 4 : 2; - ib->device = device; - ib->data = indices; + ib->device = device; + ib->data = indices; ib->dynamic = flags & GS_DYNAMIC; - ib->num = num; - ib->width = width; - ib->size = width * num; - ib->type = type; - ib->gl_type = type == GS_UNSIGNED_LONG ? GL_UNSIGNED_INT : - GL_UNSIGNED_SHORT; + ib->num = num; + ib->width = width; + ib->size = width * num; + ib->type = type; + ib->gl_type = type == GS_UNSIGNED_LONG ? GL_UNSIGNED_INT + : GL_UNSIGNED_SHORT; if (!init_ib(ib)) { blog(LOG_ERROR, "device_indexbuffer_create (GL) failed"); @@ -71,7 +72,7 @@ void gs_indexbuffer_destroy(gs_indexbuffer_t *ib) } static inline void gs_indexbuffer_flush_internal(gs_indexbuffer_t *ib, - const void *data) + const void *data) { if (!ib->dynamic) { blog(LOG_ERROR, "Index buffer is not dynamic"); diff --git a/libobs-opengl/gl-shader.c b/libobs-opengl/gl-shader.c index cab4d7f..a5cdbbb 100644 --- a/libobs-opengl/gl-shader.c +++ b/libobs-opengl/gl-shader.c @@ -43,17 +43,17 @@ static inline void shader_attrib_free(struct shader_attrib *attrib) } static void gl_get_shader_info(GLuint shader, const char *file, - char **error_string) + char **error_string) { - char *errors; - GLint info_len = 0; + char *errors; + GLint info_len = 0; GLsizei chars_written = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len); if (!gl_success("glGetProgramiv") || !info_len) return; - errors = bzalloc(info_len+1); + errors = bzalloc(info_len + 1); glGetShaderInfoLog(shader, info_len, &chars_written, errors); gl_success("glGetShaderInfoLog"); @@ -66,18 +66,18 @@ static void gl_get_shader_info(GLuint shader, const char *file, } static bool gl_add_param(struct gs_shader *shader, struct shader_var *var, - GLint *texture_id) + GLint *texture_id) { struct gs_shader_param param = {0}; param.array_count = var->array_count; - param.name = bstrdup(var->name); - param.shader = shader; - param.type = get_shader_param_type(var->type); + param.name = bstrdup(var->name); + param.shader = shader; + param.type = get_shader_param_type(var->type); if (param.type == GS_SHADER_PARAM_TEXTURE) { - param.sampler_id = var->gl_sampler_id; - param.texture_id = (*texture_id)++; + param.sampler_id = var->gl_sampler_id; + param.texture_id = (*texture_id)++; } else { param.changed = true; } @@ -90,23 +90,24 @@ static bool gl_add_param(struct gs_shader *shader, struct shader_var *var, } static inline bool gl_add_params(struct gs_shader *shader, - struct gl_shader_parser *glsp) + struct gl_shader_parser *glsp) { size_t i; GLint tex_id = 0; for (i = 0; i < glsp->parser.params.num; i++) - if (!gl_add_param(shader, glsp->parser.params.array+i, &tex_id)) + if (!gl_add_param(shader, glsp->parser.params.array + i, + &tex_id)) return false; shader->viewproj = gs_shader_get_param_by_name(shader, "ViewProj"); - shader->world = gs_shader_get_param_by_name(shader, "World"); + shader->world = gs_shader_get_param_by_name(shader, "World"); return true; } static inline void gl_add_sampler(struct gs_shader *shader, - struct shader_sampler *sampler) + struct shader_sampler *sampler) { gs_samplerstate_t *new_sampler; struct gs_sampler_info info; @@ -118,44 +119,45 @@ static inline void gl_add_sampler(struct gs_shader *shader, } static inline void gl_add_samplers(struct gs_shader *shader, - struct gl_shader_parser *glsp) + struct gl_shader_parser *glsp) { size_t i; for (i = 0; i < glsp->parser.samplers.num; i++) { - struct shader_sampler *sampler = glsp->parser.samplers.array+i; + struct shader_sampler *sampler = + glsp->parser.samplers.array + i; gl_add_sampler(shader, sampler); } } static void get_attrib_type(const char *mapping, enum attrib_type *type, - size_t *index) + size_t *index) { if (strcmp(mapping, "POSITION") == 0) { - *type = ATTRIB_POSITION; + *type = ATTRIB_POSITION; } else if (strcmp(mapping, "NORMAL") == 0) { - *type = ATTRIB_NORMAL; + *type = ATTRIB_NORMAL; } else if (strcmp(mapping, "TANGENT") == 0) { - *type = ATTRIB_TANGENT; + *type = ATTRIB_TANGENT; } else if (strcmp(mapping, "COLOR") == 0) { - *type = ATTRIB_COLOR; + *type = ATTRIB_COLOR; } else if (astrcmp_n(mapping, "TEXCOORD", 8) == 0) { - *type = ATTRIB_TEXCOORD; - *index = (*(mapping+8)) - '0'; + *type = ATTRIB_TEXCOORD; + *index = (*(mapping + 8)) - '0'; return; } else if (strcmp(mapping, "TARGET") == 0) { - *type = ATTRIB_TARGET; + *type = ATTRIB_TARGET; } *index = 0; } static inline bool gl_process_attrib(struct gs_shader *program, - struct gl_parser_attrib *pa) + struct gl_parser_attrib *pa) { struct shader_attrib attrib = {0}; @@ -166,8 +168,8 @@ static inline bool gl_process_attrib(struct gs_shader *program, get_attrib_type(pa->mapping, &attrib.type, &attrib.index); attrib.name = pa->name.array; - pa->name.array = NULL; - pa->name.len = 0; + pa->name.array = NULL; + pa->name.len = 0; pa->name.capacity = 0; da_push_back(program->attribs, &attrib); @@ -175,11 +177,11 @@ static inline bool gl_process_attrib(struct gs_shader *program, } static inline bool gl_process_attribs(struct gs_shader *shader, - struct gl_shader_parser *glsp) + struct gl_shader_parser *glsp) { size_t i; for (i = 0; i < glsp->attribs.num; i++) { - struct gl_parser_attrib *pa = glsp->attribs.array+i; + struct gl_parser_attrib *pa = glsp->attribs.array + i; if (!gl_process_attrib(shader, pa)) return false; } @@ -188,8 +190,8 @@ static inline bool gl_process_attribs(struct gs_shader *shader, } static bool gl_shader_init(struct gs_shader *shader, - struct gl_shader_parser *glsp, - const char *file, char **error_string) + struct gl_shader_parser *glsp, const char *file, + char **error_string) { GLenum type = convert_shader_type(shader->type); int compiled = 0; @@ -199,8 +201,8 @@ static bool gl_shader_init(struct gs_shader *shader, if (!gl_success("glCreateShader") || !shader->obj) return false; - glShaderSource(shader->obj, 1, (const GLchar**)&glsp->gl_string.array, - 0); + glShaderSource(shader->obj, 1, (const GLchar **)&glsp->gl_string.array, + 0); if (!gl_success("glShaderSource")) return false; @@ -227,7 +229,8 @@ static bool gl_shader_init(struct gs_shader *shader, char *infoLog = malloc(sizeof(char) * infoLength); GLsizei returnedLength = 0; - glGetShaderInfoLog(shader->obj, infoLength, &returnedLength, infoLog); + glGetShaderInfoLog(shader->obj, infoLength, &returnedLength, + infoLog); blog(LOG_ERROR, "Error compiling shader:\n%s\n", infoLog); free(infoLog); @@ -249,15 +252,16 @@ static bool gl_shader_init(struct gs_shader *shader, } static struct gs_shader *shader_create(gs_device_t *device, - enum gs_shader_type type, const char *shader_str, - const char *file, char **error_string) + enum gs_shader_type type, + const char *shader_str, const char *file, + char **error_string) { struct gs_shader *shader = bzalloc(sizeof(struct gs_shader)); struct gl_shader_parser glsp; bool success = true; shader->device = device; - shader->type = type; + shader->type = type; gl_shader_parser_init(&glsp, type); if (!gl_shader_parse(&glsp, shader_str, file)) @@ -274,25 +278,23 @@ static struct gs_shader *shader_create(gs_device_t *device, return shader; } -gs_shader_t *device_vertexshader_create(gs_device_t *device, - const char *shader, const char *file, - char **error_string) +gs_shader_t *device_vertexshader_create(gs_device_t *device, const char *shader, + const char *file, char **error_string) { struct gs_shader *ptr; ptr = shader_create(device, GS_SHADER_VERTEX, shader, file, - error_string); + error_string); if (!ptr) blog(LOG_ERROR, "device_vertexshader_create (GL) failed"); return ptr; } -gs_shader_t *device_pixelshader_create(gs_device_t *device, - const char *shader, const char *file, - char **error_string) +gs_shader_t *device_pixelshader_create(gs_device_t *device, const char *shader, + const char *file, char **error_string) { struct gs_shader *ptr; ptr = shader_create(device, GS_SHADER_PIXEL, shader, file, - error_string); + error_string); if (!ptr) blog(LOG_ERROR, "device_pixelshader_create (GL) failed"); return ptr; @@ -307,11 +309,11 @@ static void remove_program_references(struct gs_shader *shader) bool destroy = false; if (shader->type == GS_SHADER_VERTEX && - program->vertex_shader == shader) + program->vertex_shader == shader) destroy = true; else if (shader->type == GS_SHADER_PIXEL && - program->pixel_shader == shader) + program->pixel_shader == shader) destroy = true; if (destroy) @@ -331,13 +333,13 @@ void gs_shader_destroy(gs_shader_t *shader) remove_program_references(shader); for (i = 0; i < shader->attribs.num; i++) - shader_attrib_free(shader->attribs.array+i); + shader_attrib_free(shader->attribs.array + i); for (i = 0; i < shader->samplers.num; i++) gs_samplerstate_destroy(shader->samplers.array[i]); for (i = 0; i < shader->params.num; i++) - shader_param_free(shader->params.array+i); + shader_param_free(shader->params.array + i); if (shader->obj) { glDeleteShader(shader->obj); @@ -358,14 +360,14 @@ int gs_shader_get_num_params(const gs_shader_t *shader) gs_sparam_t *gs_shader_get_param_by_idx(gs_shader_t *shader, uint32_t param) { assert(param < shader->params.num); - return shader->params.array+param; + return shader->params.array + param; } gs_sparam_t *gs_shader_get_param_by_name(gs_shader_t *shader, const char *name) { size_t i; for (i = 0; i < shader->params.num; i++) { - struct gs_shader_param *param = shader->params.array+i; + struct gs_shader_param *param = shader->params.array + i; if (strcmp(param->name, name) == 0) return param; @@ -385,7 +387,7 @@ gs_sparam_t *gs_shader_get_world_matrix(const gs_shader_t *shader) } void gs_shader_get_param_info(const gs_sparam_t *param, - struct gs_shader_param_info *info) + struct gs_shader_param_info *info) { info->type = param->type; info->name = param->name; @@ -441,14 +443,14 @@ void gs_shader_set_texture(gs_sparam_t *param, gs_texture_t *val) } static inline bool validate_param(struct program_param *pp, - size_t expected_size) + size_t expected_size) { if (pp->param->cur_value.num != expected_size) { - blog(LOG_ERROR, "Parameter '%s' set to invalid size %u, " - "expected %u", - pp->param->name, - (unsigned int)pp->param->cur_value.num, - (unsigned int)expected_size); + blog(LOG_ERROR, + "Parameter '%s' set to invalid size %u, " + "expected %u", + pp->param->name, (unsigned int)pp->param->cur_value.num, + (unsigned int)expected_size); return false; } @@ -456,63 +458,62 @@ static inline bool validate_param(struct program_param *pp, } static void program_set_param_data(struct gs_program *program, - struct program_param *pp) + struct program_param *pp) { void *array = pp->param->cur_value.array; if (pp->param->type == GS_SHADER_PARAM_BOOL || pp->param->type == GS_SHADER_PARAM_INT) { if (validate_param(pp, sizeof(int))) { - glUniform1iv(pp->obj, 1, (int*)array); + glUniform1iv(pp->obj, 1, (int *)array); gl_success("glUniform1iv"); } } else if (pp->param->type == GS_SHADER_PARAM_INT2) { if (validate_param(pp, sizeof(int) * 2)) { - glUniform2iv(pp->obj, 1, (int*)array); + glUniform2iv(pp->obj, 1, (int *)array); gl_success("glUniform2iv"); } } else if (pp->param->type == GS_SHADER_PARAM_INT3) { if (validate_param(pp, sizeof(int) * 3)) { - glUniform3iv(pp->obj, 1, (int*)array); + glUniform3iv(pp->obj, 1, (int *)array); gl_success("glUniform3iv"); } } else if (pp->param->type == GS_SHADER_PARAM_INT4) { if (validate_param(pp, sizeof(int) * 4)) { - glUniform4iv(pp->obj, 1, (int*)array); + glUniform4iv(pp->obj, 1, (int *)array); gl_success("glUniform4iv"); } } else if (pp->param->type == GS_SHADER_PARAM_FLOAT) { if (validate_param(pp, sizeof(float))) { - glUniform1fv(pp->obj, 1, (float*)array); + glUniform1fv(pp->obj, 1, (float *)array); gl_success("glUniform1fv"); } } else if (pp->param->type == GS_SHADER_PARAM_VEC2) { if (validate_param(pp, sizeof(struct vec2))) { - glUniform2fv(pp->obj, 1, (float*)array); + glUniform2fv(pp->obj, 1, (float *)array); gl_success("glUniform2fv"); } } else if (pp->param->type == GS_SHADER_PARAM_VEC3) { if (validate_param(pp, sizeof(float) * 3)) { - glUniform3fv(pp->obj, 1, (float*)array); + glUniform3fv(pp->obj, 1, (float *)array); gl_success("glUniform3fv"); } } else if (pp->param->type == GS_SHADER_PARAM_VEC4) { if (validate_param(pp, sizeof(struct vec4))) { - glUniform4fv(pp->obj, 1, (float*)array); + glUniform4fv(pp->obj, 1, (float *)array); gl_success("glUniform4fv"); } } else if (pp->param->type == GS_SHADER_PARAM_MATRIX4X4) { if (validate_param(pp, sizeof(struct matrix4))) { - glUniformMatrix4fv(pp->obj, 1, false, - (float*)array); + glUniformMatrix4fv(pp->obj, 1, false, (float *)array); gl_success("glUniformMatrix4fv"); } @@ -525,7 +526,7 @@ static void program_set_param_data(struct gs_program *program, glUniform1i(pp->obj, pp->param->texture_id); device_load_texture(program->device, pp->param->texture, - pp->param->texture_id); + pp->param->texture_id); } } @@ -539,15 +540,15 @@ void program_update_params(struct gs_program *program) static void print_link_errors(GLuint program) { - char *errors = NULL; - GLint info_len = 0; + char *errors = NULL; + GLint info_len = 0; GLsizei chars_written = 0; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_len); if (!gl_success("glGetProgramiv") || !info_len) return; - errors = calloc(1, info_len+1); + errors = calloc(1, info_len + 1); glGetProgramInfoLog(program, info_len, &chars_written, errors); gl_success("glGetShaderInfoLog"); @@ -557,15 +558,17 @@ static void print_link_errors(GLuint program) } static bool assign_program_attrib(struct gs_program *program, - struct shader_attrib *attrib) + struct shader_attrib *attrib) { GLint attrib_obj = glGetAttribLocation(program->obj, attrib->name); if (!gl_success("glGetAttribLocation")) return false; if (attrib_obj == -1) { - blog(LOG_ERROR, "glGetAttribLocation: Could not find " - "attribute '%s'", attrib->name); + blog(LOG_ERROR, + "glGetAttribLocation: Could not find " + "attribute '%s'", + attrib->name); return false; } @@ -587,7 +590,7 @@ static inline bool assign_program_attribs(struct gs_program *program) } static bool assign_program_param(struct gs_program *program, - struct gs_shader_param *param) + struct gs_shader_param *param) { struct program_param info; @@ -605,7 +608,7 @@ static bool assign_program_param(struct gs_program *program, } static inline bool assign_program_shader_params(struct gs_program *program, - struct gs_shader *shader) + struct gs_shader *shader) { for (size_t i = 0; i < shader->params.num; i++) { struct gs_shader_param *param = shader->params.array + i; @@ -631,9 +634,9 @@ struct gs_program *gs_program_create(struct gs_device *device) struct gs_program *program = bzalloc(sizeof(*program)); int linked = false; - program->device = device; + program->device = device; program->vertex_shader = device->cur_vertex_shader; - program->pixel_shader = device->cur_pixel_shader; + program->pixel_shader = device->cur_pixel_shader; program->obj = glCreateProgram(); if (!gl_success("glCreateProgram")) @@ -725,18 +728,39 @@ void gs_shader_set_val(gs_sparam_t *param, const void *val, size_t size) count = 1; switch ((uint32_t)param->type) { - case GS_SHADER_PARAM_FLOAT: expected_size = sizeof(float); break; + case GS_SHADER_PARAM_FLOAT: + expected_size = sizeof(float); + break; case GS_SHADER_PARAM_BOOL: - case GS_SHADER_PARAM_INT: expected_size = sizeof(int); break; - case GS_SHADER_PARAM_INT2: expected_size = sizeof(int) * 2; break; - case GS_SHADER_PARAM_INT3: expected_size = sizeof(int) * 3; break; - case GS_SHADER_PARAM_INT4: expected_size = sizeof(int) * 4; break; - case GS_SHADER_PARAM_VEC2: expected_size = sizeof(float)*2; break; - case GS_SHADER_PARAM_VEC3: expected_size = sizeof(float)*3; break; - case GS_SHADER_PARAM_VEC4: expected_size = sizeof(float)*4; break; - case GS_SHADER_PARAM_MATRIX4X4: expected_size = sizeof(float)*4*4;break; - case GS_SHADER_PARAM_TEXTURE: expected_size = sizeof(void*); break; - default: expected_size = 0; + case GS_SHADER_PARAM_INT: + expected_size = sizeof(int); + break; + case GS_SHADER_PARAM_INT2: + expected_size = sizeof(int) * 2; + break; + case GS_SHADER_PARAM_INT3: + expected_size = sizeof(int) * 3; + break; + case GS_SHADER_PARAM_INT4: + expected_size = sizeof(int) * 4; + break; + case GS_SHADER_PARAM_VEC2: + expected_size = sizeof(float) * 2; + break; + case GS_SHADER_PARAM_VEC3: + expected_size = sizeof(float) * 3; + break; + case GS_SHADER_PARAM_VEC4: + expected_size = sizeof(float) * 4; + break; + case GS_SHADER_PARAM_MATRIX4X4: + expected_size = sizeof(float) * 4 * 4; + break; + case GS_SHADER_PARAM_TEXTURE: + expected_size = sizeof(void *); + break; + default: + expected_size = 0; } expected_size *= count; @@ -745,12 +769,12 @@ void gs_shader_set_val(gs_sparam_t *param, const void *val, size_t size) if (expected_size != size) { blog(LOG_ERROR, "gs_shader_set_val (GL): Size of shader " - "param does not match the size of the input"); + "param does not match the size of the input"); return; } if (param->type == GS_SHADER_PARAM_TEXTURE) - gs_shader_set_texture(param, *(gs_texture_t**)val); + gs_shader_set_texture(param, *(gs_texture_t **)val); else da_copy_array(param->cur_value, val, size); } diff --git a/libobs-opengl/gl-shaderparser.c b/libobs-opengl/gl-shaderparser.c index 2c607ac..d952899 100644 --- a/libobs-opengl/gl-shaderparser.c +++ b/libobs-opengl/gl-shaderparser.c @@ -19,14 +19,15 @@ #include "gl-shaderparser.h" static void gl_write_function_contents(struct gl_shader_parser *glsp, - struct cf_token **p_token, const char *end); + struct cf_token **p_token, + const char *end); static inline struct shader_var *sp_getparam(struct gl_shader_parser *glsp, - struct cf_token *token) + struct cf_token *token) { size_t i; for (i = 0; i < glsp->parser.params.num; i++) { - struct shader_var *param = glsp->parser.params.array+i; + struct shader_var *param = glsp->parser.params.array + i; if (strref_cmp(&token->str, param->name) == 0) return param; } @@ -35,11 +36,12 @@ static inline struct shader_var *sp_getparam(struct gl_shader_parser *glsp, } static inline size_t sp_getsampler(struct gl_shader_parser *glsp, - struct cf_token *token) + struct cf_token *token) { size_t i; for (i = 0; i < glsp->parser.samplers.num; i++) { - struct shader_sampler *sampler = glsp->parser.samplers.array+i; + struct shader_sampler *sampler = + glsp->parser.samplers.array + i; if (strref_cmp(&token->str, sampler->name) == 0) return i; } @@ -48,14 +50,14 @@ static inline size_t sp_getsampler(struct gl_shader_parser *glsp, } static inline int cmp_type(const char *name, const size_t name_len, - const char *type, const size_t type_len) + const char *type, const size_t type_len) { size_t min_len = (name_len < type_len) ? type_len : name_len; return astrcmp_n(name, type, min_len); } -static bool gl_write_type_n(struct gl_shader_parser *glsp, - const char *type, size_t len) +static bool gl_write_type_n(struct gl_shader_parser *glsp, const char *type, + size_t len) { if (cmp_type(type, len, "float2", 6) == 0) dstr_cat(&glsp->gl_string, "vec2"); @@ -90,14 +92,14 @@ static bool gl_write_type_n(struct gl_shader_parser *glsp, } static inline void gl_write_type(struct gl_shader_parser *glsp, - const char *type) + const char *type) { if (!gl_write_type_n(glsp, type, strlen(type))) dstr_cat(&glsp->gl_string, type); } static inline bool gl_write_type_token(struct gl_shader_parser *glsp, - struct cf_token *token) + struct cf_token *token) { return gl_write_type_n(glsp, token->str.array, token->str.len); } @@ -122,7 +124,7 @@ static inline void gl_write_params(struct gl_shader_parser *glsp) { size_t i; for (i = 0; i < glsp->parser.params.num; i++) { - struct shader_var *var = glsp->parser.params.array+i; + struct shader_var *var = glsp->parser.params.array + i; gl_write_var(glsp, var); dstr_cat(&glsp->gl_string, ";\n"); } @@ -131,12 +133,13 @@ static inline void gl_write_params(struct gl_shader_parser *glsp) } static void gl_write_storage_var(struct gl_shader_parser *glsp, - struct shader_var *var, bool input, const char *prefix); + struct shader_var *var, bool input, + const char *prefix); /* unwraps a structure that's used for input/output */ static void gl_unwrap_storage_struct(struct gl_shader_parser *glsp, - struct shader_struct *st, const char *name, bool input, - const char *prefix) + struct shader_struct *st, const char *name, + bool input, const char *prefix) { struct dstr prefix_str; size_t i; @@ -148,7 +151,7 @@ static void gl_unwrap_storage_struct(struct gl_shader_parser *glsp, dstr_cat(&prefix_str, "_"); for (i = 0; i < st->vars.num; i++) { - struct shader_var *st_var = st->vars.array+i; + struct shader_var *st_var = st->vars.array + i; gl_write_storage_var(glsp, st_var, input, prefix_str.array); } @@ -156,14 +159,24 @@ static void gl_unwrap_storage_struct(struct gl_shader_parser *glsp, } static void gl_write_storage_var(struct gl_shader_parser *glsp, - struct shader_var *var, bool input, const char *prefix) + struct shader_var *var, bool input, + const char *prefix) { - struct shader_struct *st = shader_parser_getstruct(&glsp->parser, - var->type); + struct shader_struct *st = + shader_parser_getstruct(&glsp->parser, var->type); if (st) { gl_unwrap_storage_struct(glsp, st, var->name, input, prefix); } else { + if (input && (strcmp(var->mapping, "VERTEXID") == 0)) + return; + if (strcmp(var->mapping, "POSITION") == 0) { + if (!input && (glsp->type == GS_SHADER_VERTEX)) + return; + if (input && (glsp->type == GS_SHADER_PIXEL)) + return; + } + struct gl_parser_attrib attrib; gl_parser_attrib_init(&attrib); @@ -178,24 +191,24 @@ static void gl_write_storage_var(struct gl_shader_parser *glsp, dstr_cat_dstr(&glsp->gl_string, &attrib.name); dstr_cat(&glsp->gl_string, ";\n"); - attrib.input = input; + attrib.input = input; attrib.mapping = var->mapping; da_push_back(glsp->attribs, &attrib); } } static inline void gl_write_inputs(struct gl_shader_parser *glsp, - struct shader_func *main) + struct shader_func *main) { size_t i; for (i = 0; i < main->params.num; i++) - gl_write_storage_var(glsp, main->params.array+i, true, - "inputval_"); + gl_write_storage_var(glsp, main->params.array + i, true, + "inputval_"); dstr_cat(&glsp->gl_string, "\n"); } static void gl_write_outputs(struct gl_shader_parser *glsp, - struct shader_func *main) + struct shader_func *main) { struct shader_var var = {0}; var.type = main->return_type; @@ -208,7 +221,7 @@ static void gl_write_outputs(struct gl_shader_parser *glsp, } static void gl_write_struct(struct gl_shader_parser *glsp, - struct shader_struct *st) + struct shader_struct *st) { size_t i; dstr_cat(&glsp->gl_string, "struct "); @@ -216,7 +229,7 @@ static void gl_write_struct(struct gl_shader_parser *glsp, dstr_cat(&glsp->gl_string, " {\n"); for (i = 0; i < st->vars.num; i++) { - struct shader_var *var = st->vars.array+i; + struct shader_var *var = st->vars.array + i; dstr_cat(&glsp->gl_string, "\t"); gl_write_var(glsp, var); @@ -230,7 +243,7 @@ static void gl_write_interface_block(struct gl_shader_parser *glsp) { if (glsp->type == GS_SHADER_VERTEX) { dstr_cat(&glsp->gl_string, "out gl_PerVertex {\n" - "\tvec4 gl_Position;\n};\n\n"); + "\tvec4 gl_Position;\n};\n\n"); } } @@ -238,7 +251,7 @@ static inline void gl_write_structs(struct gl_shader_parser *glsp) { size_t i; for (i = 0; i < glsp->parser.structs.num; i++) { - struct shader_struct *st = glsp->parser.structs.array+i; + struct shader_struct *st = glsp->parser.structs.array + i; gl_write_struct(glsp, st); } } @@ -267,13 +280,15 @@ static inline void gl_write_structs(struct gl_shader_parser *glsp) */ static bool gl_write_mul(struct gl_shader_parser *glsp, - struct cf_token **p_token) + struct cf_token **p_token) { struct cf_parser *cfp = &glsp->parser.cfp; cfp->cur_token = *p_token; - if (!cf_next_token(cfp)) return false; - if (!cf_token_is(cfp, "(")) return false; + if (!cf_next_token(cfp)) + return false; + if (!cf_token_is(cfp, "(")) + return false; dstr_cat(&glsp->gl_string, "("); gl_write_function_contents(glsp, &cfp->cur_token, ","); @@ -287,13 +302,15 @@ static bool gl_write_mul(struct gl_shader_parser *glsp, } static bool gl_write_saturate(struct gl_shader_parser *glsp, - struct cf_token **p_token) + struct cf_token **p_token) { struct cf_parser *cfp = &glsp->parser.cfp; cfp->cur_token = *p_token; - if (!cf_next_token(cfp)) return false; - if (!cf_token_is(cfp, "(")) return false; + if (!cf_next_token(cfp)) + return false; + if (!cf_token_is(cfp, "(")) + return false; dstr_cat(&glsp->gl_string, "clamp"); gl_write_function_contents(glsp, &cfp->cur_token, ")"); @@ -304,23 +321,29 @@ static bool gl_write_saturate(struct gl_shader_parser *glsp, } static inline bool gl_write_texture_call(struct gl_shader_parser *glsp, - struct shader_var *var, const char *call, bool sampler) + struct shader_var *var, + const char *call, bool sampler) { struct cf_parser *cfp = &glsp->parser.cfp; - size_t sampler_id = (size_t)-1; - if (!cf_next_token(cfp)) return false; - if (!cf_token_is(cfp, "(")) return false; + if (!cf_next_token(cfp)) + return false; + if (!cf_token_is(cfp, "(")) + return false; if (sampler) { - if (!cf_next_token(cfp)) return false; - sampler_id = sp_getsampler(glsp, cfp->cur_token); - if (sampler_id == (size_t) -1) return false; - if (!cf_next_token(cfp)) return false; - if (!cf_token_is(cfp, ",")) return false; - } + if (!cf_next_token(cfp)) + return false; + const size_t sampler_id = sp_getsampler(glsp, cfp->cur_token); + if (sampler_id == (size_t)-1) + return false; + if (!cf_next_token(cfp)) + return false; + if (!cf_token_is(cfp, ",")) + return false; - var->gl_sampler_id = sampler_id; + var->gl_sampler_id = sampler_id; + } dstr_cat(&glsp->gl_string, call); dstr_cat(&glsp->gl_string, "("); @@ -331,15 +354,19 @@ static inline bool gl_write_texture_call(struct gl_shader_parser *glsp, /* processes texture.Sample(sampler, texcoord) */ static bool gl_write_texture_code(struct gl_shader_parser *glsp, - struct cf_token **p_token, struct shader_var *var) + struct cf_token **p_token, + struct shader_var *var) { struct cf_parser *cfp = &glsp->parser.cfp; bool written = false; cfp->cur_token = *p_token; - if (!cf_next_token(cfp)) return false; - if (!cf_token_is(cfp, ".")) return false; - if (!cf_next_token(cfp)) return false; + if (!cf_next_token(cfp)) + return false; + if (!cf_token_is(cfp, ".")) + return false; + if (!cf_next_token(cfp)) + return false; const char *function_end = ")"; @@ -360,7 +387,8 @@ static bool gl_write_texture_code(struct gl_shader_parser *glsp, if (!written) return false; - if (!cf_next_token(cfp)) return false; + if (!cf_next_token(cfp)) + return false; gl_write_function_contents(glsp, &cfp->cur_token, ")"); dstr_cat(&glsp->gl_string, function_end); @@ -370,7 +398,7 @@ static bool gl_write_texture_code(struct gl_shader_parser *glsp, } static bool gl_write_intrinsic(struct gl_shader_parser *glsp, - struct cf_token **p_token) + struct cf_token **p_token) { struct cf_token *token = *p_token; bool written = true; @@ -407,13 +435,13 @@ static bool gl_write_intrinsic(struct gl_shader_parser *glsp, } static void gl_write_function_contents(struct gl_shader_parser *glsp, - struct cf_token **p_token, const char *end) + struct cf_token **p_token, + const char *end) { struct cf_token *token = *p_token; - if (token->type != CFTOKEN_NAME - || ( !gl_write_type_token(glsp, token) - && !gl_write_intrinsic(glsp, &token))) + if (token->type != CFTOKEN_NAME || (!gl_write_type_token(glsp, token) && + !gl_write_intrinsic(glsp, &token))) dstr_cat_strref(&glsp->gl_string, &token->str); while (token->type != CFTOKEN_NONE) { @@ -444,7 +472,7 @@ static void gl_write_function_contents(struct gl_shader_parser *glsp, } static void gl_write_function(struct gl_shader_parser *glsp, - struct shader_func *func) + struct shader_func *func) { size_t i; struct cf_token *token; @@ -460,7 +488,7 @@ static void gl_write_function(struct gl_shader_parser *glsp, dstr_cat(&glsp->gl_string, "("); for (i = 0; i < func->params.num; i++) { - struct shader_var *param = func->params.array+i; + struct shader_var *param = func->params.array + i; if (i > 0) dstr_cat(&glsp->gl_string, ", "); @@ -478,14 +506,14 @@ static inline void gl_write_functions(struct gl_shader_parser *glsp) { size_t i; for (i = 0; i < glsp->parser.funcs.num; i++) { - struct shader_func *func = glsp->parser.funcs.array+i; + struct shader_func *func = glsp->parser.funcs.array + i; gl_write_function(glsp, func); } } -static inline void gl_write_main_interface_assign( - struct gl_shader_parser *glsp, struct shader_var *var, - const char *src) +static inline void gl_write_main_interface_assign(struct gl_shader_parser *glsp, + struct shader_var *var, + const char *src) { /* vertex shaders: write gl_Position */ if (glsp->type == GS_SHADER_VERTEX && @@ -498,12 +526,13 @@ static inline void gl_write_main_interface_assign( } static void gl_write_main_storage_assign(struct gl_shader_parser *glsp, - struct shader_var *var, const char *dst, const char *src, - bool input) + struct shader_var *var, + const char *dst, const char *src, + bool input) { struct shader_struct *st; struct dstr dst_copy = {0}; - char ch_left = input ? '.' : '_'; + char ch_left = input ? '.' : '_'; char ch_right = input ? '_' : '.'; if (dst) { @@ -526,20 +555,31 @@ static void gl_write_main_storage_assign(struct gl_shader_parser *glsp, dstr_cat_ch(&src_copy, ch_right); for (i = 0; i < st->vars.num; i++) { - struct shader_var *st_var = st->vars.array+i; + struct shader_var *st_var = st->vars.array + i; gl_write_main_storage_assign(glsp, st_var, - dst_copy.array, src_copy.array, input); + dst_copy.array, + src_copy.array, input); } dstr_free(&src_copy); } else { - if (!dstr_is_empty(&dst_copy)) - dstr_cat_dstr(&glsp->gl_string, &dst_copy); - dstr_cat(&glsp->gl_string, " = "); - if (src) - dstr_cat(&glsp->gl_string, src); - dstr_cat(&glsp->gl_string, var->name); - dstr_cat(&glsp->gl_string, ";\n"); + if (input || (glsp->type != GS_SHADER_VERTEX) || + (strcmp(var->mapping, "POSITION"))) { + if (!dstr_is_empty(&dst_copy)) + dstr_cat_dstr(&glsp->gl_string, &dst_copy); + dstr_cat(&glsp->gl_string, " = "); + if (input && (strcmp(var->mapping, "VERTEXID") == 0)) + dstr_cat(&glsp->gl_string, "uint(gl_VertexID)"); + else if (input && (glsp->type == GS_SHADER_PIXEL) && + (strcmp(var->mapping, "POSITION") == 0)) + dstr_cat(&glsp->gl_string, "gl_FragCoord"); + else { + if (src) + dstr_cat(&glsp->gl_string, src); + dstr_cat(&glsp->gl_string, var->name); + } + dstr_cat(&glsp->gl_string, ";\n"); + } if (!input) gl_write_main_interface_assign(glsp, var, src); @@ -549,28 +589,28 @@ static void gl_write_main_storage_assign(struct gl_shader_parser *glsp, } static inline void gl_write_main_storage_inputs(struct gl_shader_parser *glsp, - struct shader_func *main) + struct shader_func *main) { gl_write_main_storage_assign(glsp, main->params.array, NULL, - "inputval_", true); + "inputval_", true); } static inline void gl_write_main_storage_outputs(struct gl_shader_parser *glsp, - struct shader_func *main) + struct shader_func *main) { /* we only do this *if* we're writing a struct, because otherwise * the call to 'main' already does the assignment for us */ if (!main->mapping) { struct shader_var var = {0}; var.name = "outputval"; - var.type = (char*)main->return_type; + var.type = main->return_type; dstr_cat(&glsp->gl_string, "\n"); gl_write_main_storage_assign(glsp, &var, NULL, NULL, false); } } static inline void gl_write_main_vars(struct gl_shader_parser *glsp, - struct shader_func *main_func) + struct shader_func *main_func) { size_t i; for (i = 0; i < main_func->params.num; i++) { @@ -589,7 +629,7 @@ static inline void gl_write_main_vars(struct gl_shader_parser *glsp, } static inline void gl_write_main_func_call(struct gl_shader_parser *glsp, - struct shader_func *main_func) + struct shader_func *main_func) { size_t i; dstr_cat(&glsp->gl_string, "\n\toutputval = _main_wrap("); @@ -604,7 +644,7 @@ static inline void gl_write_main_func_call(struct gl_shader_parser *glsp, } static void gl_write_main(struct gl_shader_parser *glsp, - struct shader_func *main) + struct shader_func *main) { dstr_cat(&glsp->gl_string, "void main(void)\n{\n"); @@ -622,22 +662,22 @@ static void gl_rename_attributes(struct gl_shader_parser *glsp) size_t i = 0, input_idx = 0, output_idx = 0; for (i = 0; i < glsp->attribs.num; i++) { - struct gl_parser_attrib *attrib = glsp->attribs.array+i; + struct gl_parser_attrib *attrib = glsp->attribs.array + i; struct dstr new_name = {0}; const char *prefix; size_t val; if (attrib->input) { prefix = glsp->input_prefix; - val = input_idx++; + val = input_idx++; } else { prefix = glsp->output_prefix; - val = output_idx++; + val = output_idx++; } dstr_printf(&new_name, "%s%u", prefix, (unsigned int)val); dstr_replace(&glsp->gl_string, attrib->name.array, - new_name.array); + new_name.array); dstr_move(&attrib->name, &new_name); } } @@ -653,6 +693,7 @@ static bool gl_shader_buildstring(struct gl_shader_parser *glsp) } dstr_copy(&glsp->gl_string, "#version 150\n\n"); + dstr_cat(&glsp->gl_string, "const bool obs_glsl_compile = true;\n\n"); gl_write_params(glsp); gl_write_inputs(glsp, main_func); gl_write_outputs(glsp, main_func); @@ -665,8 +706,8 @@ static bool gl_shader_buildstring(struct gl_shader_parser *glsp) return true; } -bool gl_shader_parse(struct gl_shader_parser *glsp, - const char *shader_str, const char *file) +bool gl_shader_parse(struct gl_shader_parser *glsp, const char *shader_str, + const char *file) { bool success = shader_parse(&glsp->parser, shader_str, file); char *str = shader_parser_geterrors(&glsp->parser); diff --git a/libobs-opengl/gl-shaderparser.h b/libobs-opengl/gl-shaderparser.h index 59ceafb..0667aa5 100644 --- a/libobs-opengl/gl-shaderparser.h +++ b/libobs-opengl/gl-shaderparser.h @@ -28,8 +28,8 @@ struct gl_parser_attrib { struct dstr name; - const char *mapping; - bool input; + const char *mapping; + bool input; }; static inline void gl_parser_attrib_init(struct gl_parser_attrib *attr) @@ -43,26 +43,26 @@ static inline void gl_parser_attrib_free(struct gl_parser_attrib *attr) } struct gl_shader_parser { - enum gs_shader_type type; - const char *input_prefix; - const char *output_prefix; - struct shader_parser parser; - struct dstr gl_string; - - DARRAY(uint32_t) texture_samplers; + enum gs_shader_type type; + const char *input_prefix; + const char *output_prefix; + struct shader_parser parser; + struct dstr gl_string; + + DARRAY(uint32_t) texture_samplers; DARRAY(struct gl_parser_attrib) attribs; }; static inline void gl_shader_parser_init(struct gl_shader_parser *glsp, - enum gs_shader_type type) + enum gs_shader_type type) { glsp->type = type; if (type == GS_SHADER_VERTEX) { - glsp->input_prefix = "_input_attrib"; + glsp->input_prefix = "_input_attrib"; glsp->output_prefix = "_vertex_shader_attrib"; } else if (type == GS_SHADER_PIXEL) { - glsp->input_prefix = "_vertex_shader_attrib"; + glsp->input_prefix = "_vertex_shader_attrib"; glsp->output_prefix = "_pixel_shader_attrib"; } @@ -76,7 +76,7 @@ static inline void gl_shader_parser_free(struct gl_shader_parser *glsp) { size_t i; for (i = 0; i < glsp->attribs.num; i++) - gl_parser_attrib_free(glsp->attribs.array+i); + gl_parser_attrib_free(glsp->attribs.array + i); da_free(glsp->attribs); da_free(glsp->texture_samplers); @@ -85,4 +85,4 @@ static inline void gl_shader_parser_free(struct gl_shader_parser *glsp) } extern bool gl_shader_parse(struct gl_shader_parser *glsp, - const char *shader_str, const char *file); + const char *shader_str, const char *file); diff --git a/libobs-opengl/gl-stagesurf.c b/libobs-opengl/gl-stagesurf.c index 35dd212..7f03064 100644 --- a/libobs-opengl/gl-stagesurf.c +++ b/libobs-opengl/gl-stagesurf.c @@ -28,8 +28,8 @@ static bool create_pixel_pack_buffer(struct gs_stage_surface *surf) if (!gl_bind_buffer(GL_PIXEL_PACK_BUFFER, surf->pack_buffer)) return false; - size = surf->width * surf->bytes_per_pixel; - size = (size+3) & 0xFFFFFFFC; /* align width to 4-byte boundary */ + size = surf->width * surf->bytes_per_pixel; + size = (size + 3) & 0xFFFFFFFC; /* align width to 4-byte boundary */ size *= surf->height; glBufferData(GL_PIXEL_PACK_BUFFER, size, 0, GL_DYNAMIC_READ); @@ -43,18 +43,19 @@ static bool create_pixel_pack_buffer(struct gs_stage_surface *surf) } gs_stagesurf_t *device_stagesurface_create(gs_device_t *device, uint32_t width, - uint32_t height, enum gs_color_format color_format) + uint32_t height, + enum gs_color_format color_format) { struct gs_stage_surface *surf; surf = bzalloc(sizeof(struct gs_stage_surface)); - surf->device = device; - surf->format = color_format; - surf->width = width; - surf->height = height; - surf->gl_format = convert_gs_format(color_format); + surf->device = device; + surf->format = color_format; + surf->width = width; + surf->height = height; + surf->gl_format = convert_gs_format(color_format); surf->gl_internal_format = convert_gs_internal_format(color_format); - surf->gl_type = get_gl_format_type(color_format); - surf->bytes_per_pixel = gs_get_format_bpp(color_format)/8; + surf->gl_type = get_gl_format_type(color_format); + surf->bytes_per_pixel = gs_get_format_bpp(color_format) / 8; if (!create_pixel_pack_buffer(surf)) { blog(LOG_ERROR, "device_stagesurface_create (GL) failed"); @@ -99,7 +100,7 @@ static bool can_stage(struct gs_stage_surface *dst, struct gs_texture_2d *src) if (src->width != dst->width || src->height != dst->height) { blog(LOG_ERROR, "Source and destination must have the same " - "dimensions"); + "dimensions"); return false; } @@ -111,9 +112,9 @@ static bool can_stage(struct gs_stage_surface *dst, struct gs_texture_2d *src) /* Apparently for mac, PBOs won't do an asynchronous transfer unless you use * FBOs along with glReadPixels, which is really dumb. */ void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst, - gs_texture_t *src) + gs_texture_t *src) { - struct gs_texture_2d *tex2d = (struct gs_texture_2d*)src; + struct gs_texture_2d *tex2d = (struct gs_texture_2d *)src; struct fbo_info *fbo; GLint last_fbo; bool success = false; @@ -132,12 +133,12 @@ void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst, goto failed_unbind_buffer; glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 0, - src->gl_target, src->texture, 0); + src->gl_target, src->texture, 0); if (!gl_success("glFrameBufferTexture2D")) goto failed_unbind_all; glReadPixels(0, 0, dst->width, dst->height, dst->gl_format, - dst->gl_type, 0); + dst->gl_type, 0); if (!gl_success("glReadPixels")) goto failed_unbind_all; @@ -159,9 +160,9 @@ failed: #else void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst, - gs_texture_t *src) + gs_texture_t *src) { - struct gs_texture_2d *tex2d = (struct gs_texture_2d*)src; + struct gs_texture_2d *tex2d = (struct gs_texture_2d *)src; if (!can_stage(dst, tex2d)) goto failed; @@ -198,14 +199,14 @@ uint32_t gs_stagesurface_get_height(const gs_stagesurf_t *stagesurf) return stagesurf->height; } -enum gs_color_format gs_stagesurface_get_color_format( - const gs_stagesurf_t *stagesurf) +enum gs_color_format +gs_stagesurface_get_color_format(const gs_stagesurf_t *stagesurf) { return stagesurf->format; } bool gs_stagesurface_map(gs_stagesurf_t *stagesurf, uint8_t **data, - uint32_t *linesize) + uint32_t *linesize) { if (!gl_bind_buffer(GL_PIXEL_PACK_BUFFER, stagesurf->pack_buffer)) goto fail; diff --git a/libobs-opengl/gl-subsystem.c b/libobs-opengl/gl-subsystem.c index d91a38d..e9c986f 100644 --- a/libobs-opengl/gl-subsystem.c +++ b/libobs-opengl/gl-subsystem.c @@ -27,9 +27,9 @@ #ifdef _DEBUG -static void APIENTRY gl_debug_proc( - GLenum source, GLenum type, GLuint id, GLenum severity, - GLsizei length, const GLchar *message, const GLvoid *data ) +static void APIENTRY gl_debug_proc(GLenum source, GLenum type, GLuint id, + GLenum severity, GLsizei length, + const GLchar *message, const GLvoid *data) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(data); @@ -45,58 +45,71 @@ static void APIENTRY gl_debug_proc( } #endif - switch(source) { + switch (source) { case GL_DEBUG_SOURCE_API: - source_str = "API"; break; + source_str = "API"; + break; case GL_DEBUG_SOURCE_WINDOW_SYSTEM: - source_str = "Window System"; break; + source_str = "Window System"; + break; case GL_DEBUG_SOURCE_SHADER_COMPILER: - source_str = "Shader Compiler"; break; + source_str = "Shader Compiler"; + break; case GL_DEBUG_SOURCE_THIRD_PARTY: - source_str = "Third Party"; break; + source_str = "Third Party"; + break; case GL_DEBUG_SOURCE_APPLICATION: - source_str = "Application"; break; + source_str = "Application"; + break; case GL_DEBUG_SOURCE_OTHER: - source_str = "Other"; break; + source_str = "Other"; + break; default: source_str = "Unknown"; } - switch(type) { + switch (type) { case GL_DEBUG_TYPE_ERROR: - type_str = "Error"; break; + type_str = "Error"; + break; case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: - type_str = "Deprecated Behavior"; break; + type_str = "Deprecated Behavior"; + break; case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: - type_str = "Undefined Behavior"; break; + type_str = "Undefined Behavior"; + break; case GL_DEBUG_TYPE_PORTABILITY: - type_str = "Portability"; break; + type_str = "Portability"; + break; case GL_DEBUG_TYPE_PERFORMANCE: - type_str = "Performance"; break; + type_str = "Performance"; + break; case GL_DEBUG_TYPE_OTHER: - type_str = "Other"; break; - default: + type_str = "Other"; + break; + default: type_str = "Unknown"; } - switch(severity) { + switch (severity) { case GL_DEBUG_SEVERITY_HIGH: - severity_str = "High"; break; + severity_str = "High"; + break; case GL_DEBUG_SEVERITY_MEDIUM: - severity_str = "Medium"; break; + severity_str = "Medium"; + break; case GL_DEBUG_SEVERITY_LOW: - severity_str = "Low"; break; + severity_str = "Low"; + break; case GL_DEBUG_SEVERITY_NOTIFICATION: - severity_str = "Notification"; break; + severity_str = "Notification"; + break; default: severity_str = "Unknown"; } - blog(LOG_DEBUG, - "[%s][%s]{%s}: %.*s", - source_str, type_str, severity_str, - length, message - ); + blog(LOG_DEBUG, "[%s][%s]{%s}: %.*s", source_str, type_str, + severity_str, length, message); } static void gl_enable_debug() @@ -108,18 +121,18 @@ static void gl_enable_debug() glDebugMessageCallbackARB(gl_debug_proc, NULL); } else { blog(LOG_DEBUG, "Failed to set GL debug callback as it is " - "not supported."); + "not supported."); } } #else static void gl_enable_debug() {} #endif -static bool gl_init_extensions(struct gs_device* device) +static bool gl_init_extensions(struct gs_device *device) { if (!GLAD_GL_VERSION_2_1) { blog(LOG_ERROR, "obs-studio requires OpenGL version 2.1 or " - "higher."); + "higher."); return false; } @@ -127,7 +140,7 @@ static bool gl_init_extensions(struct gs_device* device) if (!GLAD_GL_VERSION_3_0 && !GLAD_GL_ARB_framebuffer_object) { blog(LOG_ERROR, "OpenGL extension ARB_framebuffer_object " - "is required."); + "is required."); return false; } @@ -158,14 +171,14 @@ static void clear_textures(struct gs_device *device) } void convert_sampler_info(struct gs_sampler_state *sampler, - const struct gs_sampler_info *info) + const struct gs_sampler_info *info) { GLint max_anisotropy_max; convert_filter(info->filter, &sampler->min_filter, - &sampler->mag_filter); - sampler->address_u = convert_address_mode(info->address_u); - sampler->address_v = convert_address_mode(info->address_v); - sampler->address_w = convert_address_mode(info->address_w); + &sampler->mag_filter); + sampler->address_u = convert_address_mode(info->address_u); + sampler->address_v = convert_address_mode(info->address_v); + sampler->address_w = convert_address_mode(info->address_w); sampler->max_anisotropy = info->max_anisotropy; max_anisotropy_max = 1; @@ -181,10 +194,10 @@ void convert_sampler_info(struct gs_sampler_state *sampler, else if (sampler->max_anisotropy > max_anisotropy_max) sampler->max_anisotropy = max_anisotropy_max; - blog(LOG_DEBUG, "convert_sampler_info: 1 <= max_anisotropy <= " - "%d violated, selected: %d, set: %d", - max_anisotropy_max, - info->max_anisotropy, sampler->max_anisotropy); + blog(LOG_DEBUG, + "convert_sampler_info: 1 <= max_anisotropy <= " + "%d violated, selected: %d, set: %d", + max_anisotropy_max, info->max_anisotropy, sampler->max_anisotropy); } const char *device_get_name(void) @@ -218,7 +231,7 @@ int device_create(gs_device_t **p_device, uint32_t adapter) const char *glRenderer = (const char *)glGetString(GL_RENDERER); blog(LOG_INFO, "Loading up OpenGL on adapter %s %s", glVendor, - glRenderer); + glRenderer); if (!gl_init_extensions(device)) { errorcode = GS_ERROR_NOT_SUPPORTED; @@ -226,23 +239,26 @@ int device_create(gs_device_t **p_device, uint32_t adapter) } const char *glVersion = (const char *)glGetString(GL_VERSION); - const char *glShadingLanguage = (const char *)glGetString( - GL_SHADING_LANGUAGE_VERSION); + const char *glShadingLanguage = + (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION); - blog(LOG_INFO, "OpenGL loaded successfully, version %s, shading " - "language %s", glVersion, glShadingLanguage); + blog(LOG_INFO, + "OpenGL loaded successfully, version %s, shading " + "language %s", + glVersion, glShadingLanguage); gl_enable(GL_CULL_FACE); - + gl_gen_vertex_arrays(1, &device->empty_vao); + device_leave_context(device); device->cur_swap = NULL; #ifdef _WIN32 blog(LOG_INFO, "Warning: The OpenGL renderer is currently in use. " - "On windows, the OpenGL renderer can decrease " - "capture performance due to the lack of specific " - "features used to maximize capture performance. " - "The Direct3D 11 renderer is recommended instead."); + "On windows, the OpenGL renderer can decrease " + "capture performance due to the lack of specific " + "features used to maximize capture performance. " + "The Direct3D 11 renderer is recommended instead."); #endif *p_device = device; @@ -262,6 +278,8 @@ void device_destroy(gs_device_t *device) while (device->first_program) gs_program_destroy(device->first_program); + gl_delete_vertex_arrays(1, &device->empty_vao); + da_free(device->proj_stack); gl_platform_destroy(device->plat); bfree(device); @@ -269,13 +287,13 @@ void device_destroy(gs_device_t *device) } gs_swapchain_t *device_swapchain_create(gs_device_t *device, - const struct gs_init_data *info) + const struct gs_init_data *info) { struct gs_swap_chain *swap = bzalloc(sizeof(struct gs_swap_chain)); swap->device = device; - swap->info = *info; - swap->wi = gl_windowinfo_create(info); + swap->info = *info; + swap->wi = gl_windowinfo_create(info); if (!swap->wi) { blog(LOG_ERROR, "device_swapchain_create (GL) failed"); gs_swapchain_destroy(swap); @@ -337,9 +355,10 @@ uint32_t device_get_height(const gs_device_t *device) } gs_texture_t *device_voltexture_create(gs_device_t *device, uint32_t width, - uint32_t height, uint32_t depth, - enum gs_color_format color_format, uint32_t levels, - const uint8_t **data, uint32_t flags) + uint32_t height, uint32_t depth, + enum gs_color_format color_format, + uint32_t levels, const uint8_t **data, + uint32_t flags) { /* TODO */ UNUSED_PARAMETER(device); @@ -353,19 +372,45 @@ gs_texture_t *device_voltexture_create(gs_device_t *device, uint32_t width, return NULL; } -gs_samplerstate_t *device_samplerstate_create(gs_device_t *device, - const struct gs_sampler_info *info) +gs_samplerstate_t * +device_samplerstate_create(gs_device_t *device, + const struct gs_sampler_info *info) { struct gs_sampler_state *sampler; sampler = bzalloc(sizeof(struct gs_sampler_state)); sampler->device = device; - sampler->ref = 1; + sampler->ref = 1; convert_sampler_info(sampler, info); return sampler; } +gs_timer_t *device_timer_create(gs_device_t *device) +{ + UNUSED_PARAMETER(device); + + struct gs_timer *timer; + + GLuint queries[2]; + glGenQueries(2, queries); + if (!gl_success("glGenQueries")) + return NULL; + + timer = bzalloc(sizeof(struct gs_timer)); + timer->queries[0] = queries[0]; + timer->queries[1] = queries[1]; + + return timer; +} + +gs_timer_range_t *device_timer_range_create(gs_device_t *device) +{ + UNUSED_PARAMETER(device); + + return NULL; +} + enum gs_texture_type device_get_texture_type(const gs_texture_t *texture) { return texture->type; @@ -374,17 +419,17 @@ enum gs_texture_type device_get_texture_type(const gs_texture_t *texture) static void strip_mipmap_filter(GLint *filter) { switch (*filter) { - case GL_NEAREST: - case GL_LINEAR: - return; - case GL_NEAREST_MIPMAP_NEAREST: - case GL_NEAREST_MIPMAP_LINEAR: - *filter = GL_NEAREST; - return; - case GL_LINEAR_MIPMAP_NEAREST: - case GL_LINEAR_MIPMAP_LINEAR: - *filter = GL_LINEAR; - return; + case GL_NEAREST: + case GL_LINEAR: + return; + case GL_NEAREST_MIPMAP_NEAREST: + case GL_NEAREST_MIPMAP_LINEAR: + *filter = GL_NEAREST; + return; + case GL_LINEAR_MIPMAP_NEAREST: + case GL_LINEAR_MIPMAP_LINEAR: + *filter = GL_LINEAR; + return; } *filter = GL_NEAREST; } @@ -401,7 +446,7 @@ static inline void apply_swizzle(struct gs_texture *tex) static bool load_texture_sampler(gs_texture_t *tex, gs_samplerstate_t *ss) { - bool success = true; + bool success = true; GLint min_filter; if (tex->cur_sampler == ss) @@ -419,11 +464,10 @@ static bool load_texture_sampler(gs_texture_t *tex, gs_samplerstate_t *ss) if (gs_texture_is_rect(tex)) strip_mipmap_filter(&min_filter); - if (!gl_tex_param_i(tex->gl_target, GL_TEXTURE_MIN_FILTER, - min_filter)) + if (!gl_tex_param_i(tex->gl_target, GL_TEXTURE_MIN_FILTER, min_filter)) success = false; if (!gl_tex_param_i(tex->gl_target, GL_TEXTURE_MAG_FILTER, - ss->mag_filter)) + ss->mag_filter)) success = false; if (!gl_tex_param_i(tex->gl_target, GL_TEXTURE_WRAP_S, ss->address_u)) success = false; @@ -432,7 +476,7 @@ static bool load_texture_sampler(gs_texture_t *tex, gs_samplerstate_t *ss) if (!gl_tex_param_i(tex->gl_target, GL_TEXTURE_WRAP_R, ss->address_w)) success = false; if (!gl_tex_param_i(tex->gl_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, - ss->max_anisotropy)) + ss->max_anisotropy)) success = false; apply_swizzle(tex); @@ -441,13 +485,13 @@ static bool load_texture_sampler(gs_texture_t *tex, gs_samplerstate_t *ss) } static inline struct gs_shader_param *get_texture_param(gs_device_t *device, - int unit) + int unit) { struct gs_shader *shader = device->cur_pixel_shader; size_t i; for (i = 0; i < shader->params.num; i++) { - struct gs_shader_param *param = shader->params.array+i; + struct gs_shader_param *param = shader->params.array + i; if (param->type == GS_SHADER_PARAM_TEXTURE) { if (param->texture_id == unit) return param; @@ -506,13 +550,13 @@ fail: } static bool load_sampler_on_textures(gs_device_t *device, gs_samplerstate_t *ss, - int sampler_unit) + int sampler_unit) { struct gs_shader *shader = device->cur_pixel_shader; size_t i; for (i = 0; i < shader->params.num; i++) { - struct gs_shader_param *param = shader->params.array+i; + struct gs_shader_param *param = shader->params.array + i; if (param->type == GS_SHADER_PARAM_TEXTURE && param->sampler_id == (uint32_t)sampler_unit && @@ -528,7 +572,7 @@ static bool load_sampler_on_textures(gs_device_t *device, gs_samplerstate_t *ss, } void device_load_samplerstate(gs_device_t *device, gs_samplerstate_t *ss, - int unit) + int unit) { /* need a pixel shader to properly bind samplers */ if (!device->cur_pixel_shader) @@ -563,7 +607,7 @@ void device_load_vertexshader(gs_device_t *device, gs_shader_t *vertshader) } static void load_default_pixelshader_samplers(struct gs_device *device, - struct gs_shader *ps) + struct gs_shader *ps) { size_t i; if (!ps) @@ -629,17 +673,17 @@ gs_zstencil_t *device_get_zstencil_target(const gs_device_t *device) } static bool get_tex_dimensions(gs_texture_t *tex, uint32_t *width, - uint32_t *height) + uint32_t *height) { if (tex->type == GS_TEXTURE_2D) { - struct gs_texture_2d *tex2d = (struct gs_texture_2d*)tex; - *width = tex2d->width; + struct gs_texture_2d *tex2d = (struct gs_texture_2d *)tex; + *width = tex2d->width; *height = tex2d->height; return true; } else if (tex->type == GS_TEXTURE_CUBE) { - struct gs_texture_cube *cube = (struct gs_texture_cube*)tex; - *width = cube->size; + struct gs_texture_cube *cube = (struct gs_texture_cube *)tex; + *width = cube->size; *height = cube->size; return true; } @@ -654,9 +698,8 @@ static bool get_tex_dimensions(gs_texture_t *tex, uint32_t *width, */ struct fbo_info *get_fbo(gs_texture_t *tex, uint32_t width, uint32_t height) { - if (tex->fbo && tex->fbo->width == width && - tex->fbo->height == height && - tex->fbo->format == tex->format) + if (tex->fbo && tex->fbo->width == width && + tex->fbo->height == height && tex->fbo->format == tex->format) return tex->fbo; GLuint fbo; @@ -665,12 +708,12 @@ struct fbo_info *get_fbo(gs_texture_t *tex, uint32_t width, uint32_t height) return NULL; tex->fbo = bmalloc(sizeof(struct fbo_info)); - tex->fbo->fbo = fbo; - tex->fbo->width = width; - tex->fbo->height = height; - tex->fbo->format = tex->format; - tex->fbo->cur_render_target = NULL; - tex->fbo->cur_render_side = 0; + tex->fbo->fbo = fbo; + tex->fbo->width = width; + tex->fbo->height = height; + tex->fbo->format = tex->format; + tex->fbo->cur_render_target = NULL; + tex->fbo->cur_render_side = 0; tex->fbo->cur_zstencil_buffer = NULL; return tex->fbo; @@ -703,7 +746,7 @@ static bool set_current_fbo(gs_device_t *device, struct fbo_info *fbo) } static bool attach_rendertarget(struct fbo_info *fbo, gs_texture_t *tex, - int side) + int side) { if (fbo->cur_render_target == tex) return true; @@ -712,14 +755,14 @@ static bool attach_rendertarget(struct fbo_info *fbo, gs_texture_t *tex, if (tex->type == GS_TEXTURE_2D) { glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, - tex->texture, 0); + GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + tex->texture, 0); } else if (tex->type == GS_TEXTURE_CUBE) { glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_TEXTURE_CUBE_MAP_POSITIVE_X + side, - tex->texture, 0); + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_CUBE_MAP_POSITIVE_X + side, + tex->texture, 0); } else { return false; @@ -743,8 +786,8 @@ static bool attach_zstencil(struct fbo_info *fbo, gs_zstencil_t *zs) zs_attachment = zs->attachment; } - glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, - zs_attachment, GL_RENDERBUFFER, zsbuffer); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, zs_attachment, + GL_RENDERBUFFER, zsbuffer); if (!gl_success("glFramebufferRenderbuffer")) return false; @@ -752,17 +795,17 @@ static bool attach_zstencil(struct fbo_info *fbo, gs_zstencil_t *zs) } static bool set_target(gs_device_t *device, gs_texture_t *tex, int side, - gs_zstencil_t *zs) + gs_zstencil_t *zs) { struct fbo_info *fbo; - if (device->cur_render_target == tex && - device->cur_zstencil_buffer == zs && - device->cur_render_side == side) + if (device->cur_render_target == tex && + device->cur_zstencil_buffer == zs && + device->cur_render_side == side) return true; - device->cur_render_target = tex; - device->cur_render_side = side; + device->cur_render_target = tex; + device->cur_render_side = side; device->cur_zstencil_buffer = zs; if (!tex) @@ -783,7 +826,7 @@ static bool set_target(gs_device_t *device, gs_texture_t *tex, int side, } void device_set_render_target(gs_device_t *device, gs_texture_t *tex, - gs_zstencil_t *zstencil) + gs_zstencil_t *zstencil) { if (tex) { if (tex->type != GS_TEXTURE_2D) { @@ -807,7 +850,7 @@ fail: } void device_set_cube_render_target(gs_device_t *device, gs_texture_t *cubetex, - int side, gs_zstencil_t *zstencil) + int side, gs_zstencil_t *zstencil) { if (cubetex) { if (cubetex->type != GS_TEXTURE_CUBE) { @@ -830,13 +873,13 @@ fail: blog(LOG_ERROR, "device_set_cube_render_target (GL) failed"); } -void device_copy_texture_region(gs_device_t *device, - gs_texture_t *dst, uint32_t dst_x, uint32_t dst_y, - gs_texture_t *src, uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) +void device_copy_texture_region(gs_device_t *device, gs_texture_t *dst, + uint32_t dst_x, uint32_t dst_y, + gs_texture_t *src, uint32_t src_x, + uint32_t src_y, uint32_t src_w, uint32_t src_h) { - struct gs_texture_2d *src2d = (struct gs_texture_2d*)src; - struct gs_texture_2d *dst2d = (struct gs_texture_2d*)dst; + struct gs_texture_2d *src2d = (struct gs_texture_2d *)src; + struct gs_texture_2d *dst2d = (struct gs_texture_2d *)dst; if (!src) { blog(LOG_ERROR, "Source texture is NULL"); @@ -850,7 +893,7 @@ void device_copy_texture_region(gs_device_t *device, if (dst->type != GS_TEXTURE_2D || src->type != GS_TEXTURE_2D) { blog(LOG_ERROR, "Source and destination textures must be 2D " - "textures"); + "textures"); goto fail; } @@ -859,19 +902,19 @@ void device_copy_texture_region(gs_device_t *device, goto fail; } - uint32_t nw = (uint32_t)src_w ? - (uint32_t)src_w : (src2d->width - src_x); - uint32_t nh = (uint32_t)src_h ? - (uint32_t)src_h : (src2d->height - src_y); + uint32_t nw = (uint32_t)src_w ? (uint32_t)src_w + : (src2d->width - src_x); + uint32_t nh = (uint32_t)src_h ? (uint32_t)src_h + : (src2d->height - src_y); if (dst2d->width - dst_x < nw || dst2d->height - dst_y < nh) { blog(LOG_ERROR, "Destination texture region is not big " - "enough to hold the source region"); + "enough to hold the source region"); goto fail; } if (!gl_copy_texture(device, dst, dst_x, dst_y, src, src_x, src_y, nw, - nh)) + nh)) goto fail; return; @@ -881,7 +924,7 @@ fail: } void device_copy_texture(gs_device_t *device, gs_texture_t *dst, - gs_texture_t *src) + gs_texture_t *src) { device_copy_texture_region(device, dst, 0, 0, src, 0, 0, 0, 0); } @@ -891,7 +934,7 @@ void device_begin_scene(gs_device_t *device) clear_textures(device); } -static inline bool can_render(const gs_device_t *device) +static inline bool can_render(const gs_device_t *device, uint32_t num_verts) { if (!device->cur_vertex_shader) { blog(LOG_ERROR, "No vertex shader specified"); @@ -903,7 +946,7 @@ static inline bool can_render(const gs_device_t *device) return false; } - if (!device->cur_vertex_buffer) { + if (!device->cur_vertex_buffer && (num_verts == 0)) { blog(LOG_ERROR, "No vertex buffer specified"); return false; } @@ -950,7 +993,7 @@ static inline struct gs_program *find_program(const struct gs_device *device) while (program) { if (program->vertex_shader == device->cur_vertex_shader && - program->pixel_shader == device->cur_pixel_shader) + program->pixel_shader == device->cur_pixel_shader) return program; program = program->next; @@ -970,14 +1013,15 @@ static inline struct gs_program *get_shader_program(struct gs_device *device) } void device_draw(gs_device_t *device, enum gs_draw_mode draw_mode, - uint32_t start_vert, uint32_t num_verts) + uint32_t start_vert, uint32_t num_verts) { + struct gs_vertex_buffer *vb = device->cur_vertex_buffer; struct gs_index_buffer *ib = device->cur_index_buffer; - GLenum topology = convert_gs_topology(draw_mode); + GLenum topology = convert_gs_topology(draw_mode); gs_effect_t *effect = gs_get_effect(); struct gs_program *program; - if (!can_render(device)) + if (!can_render(device, num_verts)) goto fail; if (effect) @@ -987,7 +1031,10 @@ void device_draw(gs_device_t *device, enum gs_draw_mode draw_mode, if (!program) goto fail; - load_vb_buffers(program, device->cur_vertex_buffer, ib); + if (vb) + load_vb_buffers(program, vb, ib); + else + gl_bind_vertex_array(device->empty_vao); if (program != device->cur_program && device->cur_program) { glUseProgram(0); @@ -1010,7 +1057,7 @@ void device_draw(gs_device_t *device, enum gs_draw_mode draw_mode, if (num_verts == 0) num_verts = (uint32_t)device->cur_index_buffer->num; glDrawElements(topology, num_verts, ib->gl_type, - (const GLvoid*)(start_vert * ib->width)); + (const GLvoid *)(start_vert * ib->width)); if (!gl_success("glDrawElements")) goto fail; @@ -1035,7 +1082,7 @@ void device_end_scene(gs_device_t *device) } void device_clear(gs_device_t *device, uint32_t clear_flags, - const struct vec4 *color, float depth, uint8_t stencil) + const struct vec4 *color, float depth, uint8_t stencil) { GLbitfield gl_flags = 0; @@ -1136,8 +1183,8 @@ void device_enable_stencil_write(gs_device_t *device, bool enable) UNUSED_PARAMETER(device); } -void device_enable_color(gs_device_t *device, bool red, bool green, - bool blue, bool alpha) +void device_enable_color(gs_device_t *device, bool red, bool green, bool blue, + bool alpha) { glColorMask(red, green, blue, alpha); @@ -1145,7 +1192,7 @@ void device_enable_color(gs_device_t *device, bool red, bool green, } void device_blend_function(gs_device_t *device, enum gs_blend_type src, - enum gs_blend_type dest) + enum gs_blend_type dest) { GLenum gl_src = convert_gs_blend_type(src); GLenum gl_dst = convert_gs_blend_type(dest); @@ -1158,8 +1205,10 @@ void device_blend_function(gs_device_t *device, enum gs_blend_type src, } void device_blend_function_separate(gs_device_t *device, - enum gs_blend_type src_c, enum gs_blend_type dest_c, - enum gs_blend_type src_a, enum gs_blend_type dest_a) + enum gs_blend_type src_c, + enum gs_blend_type dest_c, + enum gs_blend_type src_a, + enum gs_blend_type dest_a) { GLenum gl_src_c = convert_gs_blend_type(src_c); GLenum gl_dst_c = convert_gs_blend_type(dest_c); @@ -1185,7 +1234,7 @@ void device_depth_function(gs_device_t *device, enum gs_depth_test test) } void device_stencil_function(gs_device_t *device, enum gs_stencil_side side, - enum gs_depth_test test) + enum gs_depth_test test) { GLenum gl_side = convert_gs_stencil_side(side); GLenum gl_test = convert_gs_depth_test(test); @@ -1198,11 +1247,12 @@ void device_stencil_function(gs_device_t *device, enum gs_stencil_side side, } void device_stencil_op(gs_device_t *device, enum gs_stencil_side side, - enum gs_stencil_op_type fail, enum gs_stencil_op_type zfail, - enum gs_stencil_op_type zpass) + enum gs_stencil_op_type fail, + enum gs_stencil_op_type zfail, + enum gs_stencil_op_type zpass) { - GLenum gl_side = convert_gs_stencil_side(side); - GLenum gl_fail = convert_gs_stencil_op(fail); + GLenum gl_side = convert_gs_stencil_side(side); + GLenum gl_fail = convert_gs_stencil_op(fail); GLenum gl_zfail = convert_gs_stencil_op(zfail); GLenum gl_zpass = convert_gs_stencil_op(zpass); @@ -1225,7 +1275,7 @@ static inline uint32_t get_target_height(const struct gs_device *device) } void device_set_viewport(gs_device_t *device, int x, int y, int width, - int height) + int height) { uint32_t base_height = 0; int gl_y = 0; @@ -1245,8 +1295,8 @@ void device_set_viewport(gs_device_t *device, int x, int y, int width, if (!gl_success("glViewport")) blog(LOG_ERROR, "device_set_viewport (GL) failed"); - device->cur_viewport.x = x; - device->cur_viewport.y = y; + device->cur_viewport.x = x; + device->cur_viewport.y = y; device->cur_viewport.cx = width; device->cur_viewport.cy = height; } @@ -1272,55 +1322,55 @@ void device_set_scissor_rect(gs_device_t *device, const struct gs_rect *rect) blog(LOG_ERROR, "device_set_scissor_rect (GL) failed"); } -void device_ortho(gs_device_t *device, float left, float right, - float top, float bottom, float near, float far) +void device_ortho(gs_device_t *device, float left, float right, float top, + float bottom, float near, float far) { struct matrix4 *dst = &device->cur_proj; - float rml = right-left; - float bmt = bottom-top; - float fmn = far-near; + float rml = right - left; + float bmt = bottom - top; + float fmn = far - near; vec4_zero(&dst->x); vec4_zero(&dst->y); vec4_zero(&dst->z); vec4_zero(&dst->t); - dst->x.x = 2.0f / rml; - dst->t.x = (left+right) / -rml; + dst->x.x = 2.0f / rml; + dst->t.x = (left + right) / -rml; - dst->y.y = 2.0f / -bmt; - dst->t.y = (bottom+top) / bmt; + dst->y.y = 2.0f / -bmt; + dst->t.y = (bottom + top) / bmt; - dst->z.z = -2.0f / fmn; - dst->t.z = (far+near) / -fmn; + dst->z.z = -2.0f / fmn; + dst->t.z = (far + near) / -fmn; dst->t.w = 1.0f; } -void device_frustum(gs_device_t *device, float left, float right, - float top, float bottom, float near, float far) +void device_frustum(gs_device_t *device, float left, float right, float top, + float bottom, float near, float far) { struct matrix4 *dst = &device->cur_proj; - float rml = right-left; - float tmb = top-bottom; - float nmf = near-far; - float nearx2 = 2.0f*near; + float rml = right - left; + float tmb = top - bottom; + float nmf = near - far; + float nearx2 = 2.0f * near; vec4_zero(&dst->x); vec4_zero(&dst->y); vec4_zero(&dst->z); vec4_zero(&dst->t); - dst->x.x = nearx2 / rml; - dst->z.x = (left+right) / rml; - - dst->y.y = nearx2 / tmb; - dst->z.y = (bottom+top) / tmb; + dst->x.x = nearx2 / rml; + dst->z.x = (left + right) / rml; - dst->z.z = (far+near) / nmf; - dst->t.z = 2.0f * (near*far) / nmf; + dst->y.y = nearx2 / tmb; + dst->z.y = (bottom + top) / tmb; + + dst->z.z = (far + near) / nmf; + dst->t.z = 2.0f * (near * far) / nmf; dst->z.w = -1.0f; } @@ -1341,8 +1391,8 @@ void device_projection_pop(gs_device_t *device) da_pop_back(device->proj_stack); } -void device_debug_marker_begin(gs_device_t *device, - const char *markername, const float color[4]) +void device_debug_marker_begin(gs_device_t *device, const char *markername, + const float color[4]) { UNUSED_PARAMETER(device); UNUSED_PARAMETER(color); @@ -1413,8 +1463,72 @@ void gs_samplerstate_destroy(gs_samplerstate_t *samplerstate) if (samplerstate->device) for (int i = 0; i < GS_MAX_TEXTURES; i++) if (samplerstate->device->cur_samplers[i] == - samplerstate) + samplerstate) samplerstate->device->cur_samplers[i] = NULL; samplerstate_release(samplerstate); } + +void gs_timer_destroy(gs_timer_t *timer) +{ + if (!timer) + return; + + glDeleteQueries(2, timer->queries); + gl_success("glDeleteQueries"); + + bfree(timer); +} + +void gs_timer_begin(gs_timer_t *timer) +{ + glQueryCounter(timer->queries[0], GL_TIMESTAMP); + gl_success("glQueryCounter"); +} + +void gs_timer_end(gs_timer_t *timer) +{ + glQueryCounter(timer->queries[1], GL_TIMESTAMP); + gl_success("glQueryCounter"); +} + +bool gs_timer_get_data(gs_timer_t *timer, uint64_t *ticks) +{ + GLint available = 0; + glGetQueryObjectiv(timer->queries[1], GL_QUERY_RESULT_AVAILABLE, + &available); + + GLuint64 begin, end; + glGetQueryObjectui64v(timer->queries[0], GL_QUERY_RESULT, &begin); + gl_success("glGetQueryObjectui64v"); + glGetQueryObjectui64v(timer->queries[1], GL_QUERY_RESULT, &end); + gl_success("glGetQueryObjectui64v"); + + *ticks = end - begin; + return true; +} + +void gs_timer_range_destroy(gs_timer_range_t *range) +{ + UNUSED_PARAMETER(range); +} + +void gs_timer_range_begin(gs_timer_range_t *range) +{ + UNUSED_PARAMETER(range); +} + +void gs_timer_range_end(gs_timer_range_t *range) +{ + UNUSED_PARAMETER(range); +} + +bool gs_timer_range_get_data(gs_timer_range_t *range, bool *disjoint, + uint64_t *frequency) +{ + UNUSED_PARAMETER(range); + + *disjoint = false; + *frequency = 1000000000; + return true; +} diff --git a/libobs-opengl/gl-subsystem.h b/libobs-opengl/gl-subsystem.h index d5b89c9..2306836 100644 --- a/libobs-opengl/gl-subsystem.h +++ b/libobs-opengl/gl-subsystem.h @@ -30,34 +30,49 @@ struct gl_platform; struct gl_windowinfo; -enum copy_type { - COPY_TYPE_ARB, - COPY_TYPE_NV, - COPY_TYPE_FBO_BLIT -}; +enum copy_type { COPY_TYPE_ARB, COPY_TYPE_NV, COPY_TYPE_FBO_BLIT }; static inline GLenum convert_gs_format(enum gs_color_format format) { switch (format) { - case GS_A8: return GL_RED; - case GS_R8: return GL_RED; - case GS_RGBA: return GL_RGBA; - case GS_BGRX: return GL_BGRA; - case GS_BGRA: return GL_BGRA; - case GS_R10G10B10A2: return GL_RGBA; - case GS_RGBA16: return GL_RGBA; - case GS_R16: return GL_RED; - case GS_RGBA16F: return GL_RGBA; - case GS_RGBA32F: return GL_RGBA; - case GS_RG16F: return GL_RG; - case GS_RG32F: return GL_RG; - case GS_R8G8: return GL_RG; - case GS_R16F: return GL_RED; - case GS_R32F: return GL_RED; - case GS_DXT1: return GL_RGB; - case GS_DXT3: return GL_RGBA; - case GS_DXT5: return GL_RGBA; - case GS_UNKNOWN: return 0; + case GS_A8: + return GL_RED; + case GS_R8: + return GL_RED; + case GS_RGBA: + return GL_RGBA; + case GS_BGRX: + return GL_BGRA; + case GS_BGRA: + return GL_BGRA; + case GS_R10G10B10A2: + return GL_RGBA; + case GS_RGBA16: + return GL_RGBA; + case GS_R16: + return GL_RED; + case GS_RGBA16F: + return GL_RGBA; + case GS_RGBA32F: + return GL_RGBA; + case GS_RG16F: + return GL_RG; + case GS_RG32F: + return GL_RG; + case GS_R8G8: + return GL_RG; + case GS_R16F: + return GL_RED; + case GS_R32F: + return GL_RED; + case GS_DXT1: + return GL_RGB; + case GS_DXT3: + return GL_RGBA; + case GS_DXT5: + return GL_RGBA; + case GS_UNKNOWN: + return 0; } return 0; @@ -66,25 +81,44 @@ static inline GLenum convert_gs_format(enum gs_color_format format) static inline GLenum convert_gs_internal_format(enum gs_color_format format) { switch (format) { - case GS_A8: return GL_R8; /* NOTE: use GL_TEXTURE_SWIZZLE_x */ - case GS_R8: return GL_R8; - case GS_RGBA: return GL_RGBA; - case GS_BGRX: return GL_RGB; - case GS_BGRA: return GL_RGBA; - case GS_R10G10B10A2: return GL_RGB10_A2; - case GS_RGBA16: return GL_RGBA16; - case GS_R16: return GL_R16; - case GS_RGBA16F: return GL_RGBA16F; - case GS_RGBA32F: return GL_RGBA32F; - case GS_RG16F: return GL_RG16F; - case GS_RG32F: return GL_RG32F; - case GS_R8G8: return GL_R16; - case GS_R16F: return GL_R16F; - case GS_R32F: return GL_R32F; - case GS_DXT1: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - case GS_DXT3: return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - case GS_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - case GS_UNKNOWN: return 0; + case GS_A8: + return GL_R8; /* NOTE: use GL_TEXTURE_SWIZZLE_x */ + case GS_R8: + return GL_R8; + case GS_RGBA: + return GL_RGBA; + case GS_BGRX: + return GL_RGB; + case GS_BGRA: + return GL_RGBA; + case GS_R10G10B10A2: + return GL_RGB10_A2; + case GS_RGBA16: + return GL_RGBA16; + case GS_R16: + return GL_R16; + case GS_RGBA16F: + return GL_RGBA16F; + case GS_RGBA32F: + return GL_RGBA32F; + case GS_RG16F: + return GL_RG16F; + case GS_RG32F: + return GL_RG32F; + case GS_R8G8: + return GL_RG8; + case GS_R16F: + return GL_R16F; + case GS_R32F: + return GL_R32F; + case GS_DXT1: + return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + case GS_DXT3: + return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + case GS_DXT5: + return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + case GS_UNKNOWN: + return 0; } return 0; @@ -93,25 +127,44 @@ static inline GLenum convert_gs_internal_format(enum gs_color_format format) static inline GLenum get_gl_format_type(enum gs_color_format format) { switch (format) { - case GS_A8: return GL_UNSIGNED_BYTE; - case GS_R8: return GL_UNSIGNED_BYTE; - case GS_RGBA: return GL_UNSIGNED_BYTE; - case GS_BGRX: return GL_UNSIGNED_BYTE; - case GS_BGRA: return GL_UNSIGNED_BYTE; - case GS_R10G10B10A2: return GL_UNSIGNED_INT_10_10_10_2; - case GS_RGBA16: return GL_UNSIGNED_SHORT; - case GS_R16: return GL_UNSIGNED_SHORT; - case GS_RGBA16F: return GL_UNSIGNED_SHORT; - case GS_RGBA32F: return GL_FLOAT; - case GS_RG16F: return GL_UNSIGNED_SHORT; - case GS_RG32F: return GL_FLOAT; - case GS_R8G8: return GL_UNSIGNED_SHORT; - case GS_R16F: return GL_UNSIGNED_SHORT; - case GS_R32F: return GL_FLOAT; - case GS_DXT1: return GL_UNSIGNED_BYTE; - case GS_DXT3: return GL_UNSIGNED_BYTE; - case GS_DXT5: return GL_UNSIGNED_BYTE; - case GS_UNKNOWN: return 0; + case GS_A8: + return GL_UNSIGNED_BYTE; + case GS_R8: + return GL_UNSIGNED_BYTE; + case GS_RGBA: + return GL_UNSIGNED_BYTE; + case GS_BGRX: + return GL_UNSIGNED_BYTE; + case GS_BGRA: + return GL_UNSIGNED_BYTE; + case GS_R10G10B10A2: + return GL_UNSIGNED_INT_10_10_10_2; + case GS_RGBA16: + return GL_UNSIGNED_SHORT; + case GS_R16: + return GL_UNSIGNED_SHORT; + case GS_RGBA16F: + return GL_UNSIGNED_SHORT; + case GS_RGBA32F: + return GL_FLOAT; + case GS_RG16F: + return GL_UNSIGNED_SHORT; + case GS_RG32F: + return GL_FLOAT; + case GS_R8G8: + return GL_UNSIGNED_BYTE; + case GS_R16F: + return GL_UNSIGNED_SHORT; + case GS_R32F: + return GL_FLOAT; + case GS_DXT1: + return GL_UNSIGNED_BYTE; + case GS_DXT3: + return GL_UNSIGNED_BYTE; + case GS_DXT5: + return GL_UNSIGNED_BYTE; + case GS_UNKNOWN: + return 0; } return GL_UNSIGNED_BYTE; @@ -120,11 +173,16 @@ static inline GLenum get_gl_format_type(enum gs_color_format format) static inline GLenum convert_zstencil_format(enum gs_zstencil_format format) { switch (format) { - case GS_Z16: return GL_DEPTH_COMPONENT16; - case GS_Z24_S8: return GL_DEPTH24_STENCIL8; - case GS_Z32F: return GL_DEPTH_COMPONENT32F; - case GS_Z32F_S8X24: return GL_DEPTH32F_STENCIL8; - case GS_ZS_NONE: return 0; + case GS_Z16: + return GL_DEPTH_COMPONENT16; + case GS_Z24_S8: + return GL_DEPTH24_STENCIL8; + case GS_Z32F: + return GL_DEPTH_COMPONENT32F; + case GS_Z32F_S8X24: + return GL_DEPTH32F_STENCIL8; + case GS_ZS_NONE: + return 0; } return 0; @@ -133,14 +191,22 @@ static inline GLenum convert_zstencil_format(enum gs_zstencil_format format) static inline GLenum convert_gs_depth_test(enum gs_depth_test test) { switch (test) { - case GS_NEVER: return GL_NEVER; - case GS_LESS: return GL_LESS; - case GS_LEQUAL: return GL_LEQUAL; - case GS_EQUAL: return GL_EQUAL; - case GS_GEQUAL: return GL_GEQUAL; - case GS_GREATER: return GL_GREATER; - case GS_NOTEQUAL: return GL_NOTEQUAL; - case GS_ALWAYS: return GL_ALWAYS; + case GS_NEVER: + return GL_NEVER; + case GS_LESS: + return GL_LESS; + case GS_LEQUAL: + return GL_LEQUAL; + case GS_EQUAL: + return GL_EQUAL; + case GS_GEQUAL: + return GL_GEQUAL; + case GS_GREATER: + return GL_GREATER; + case GS_NOTEQUAL: + return GL_NOTEQUAL; + case GS_ALWAYS: + return GL_ALWAYS; } return GL_NEVER; @@ -149,12 +215,18 @@ static inline GLenum convert_gs_depth_test(enum gs_depth_test test) static inline GLenum convert_gs_stencil_op(enum gs_stencil_op_type op) { switch (op) { - case GS_KEEP: return GL_KEEP; - case GS_ZERO: return GL_ZERO; - case GS_REPLACE: return GL_REPLACE; - case GS_INCR: return GL_INCR; - case GS_DECR: return GL_DECR; - case GS_INVERT: return GL_INVERT; + case GS_KEEP: + return GL_KEEP; + case GS_ZERO: + return GL_ZERO; + case GS_REPLACE: + return GL_REPLACE; + case GS_INCR: + return GL_INCR; + case GS_DECR: + return GL_DECR; + case GS_INVERT: + return GL_INVERT; } return GL_KEEP; @@ -163,9 +235,12 @@ static inline GLenum convert_gs_stencil_op(enum gs_stencil_op_type op) static inline GLenum convert_gs_stencil_side(enum gs_stencil_side side) { switch (side) { - case GS_STENCIL_FRONT: return GL_FRONT; - case GS_STENCIL_BACK: return GL_BACK; - case GS_STENCIL_BOTH: return GL_FRONT_AND_BACK; + case GS_STENCIL_FRONT: + return GL_FRONT; + case GS_STENCIL_BACK: + return GL_BACK; + case GS_STENCIL_BOTH: + return GL_FRONT_AND_BACK; } return GL_FRONT; @@ -174,17 +249,28 @@ static inline GLenum convert_gs_stencil_side(enum gs_stencil_side side) static inline GLenum convert_gs_blend_type(enum gs_blend_type type) { switch (type) { - case GS_BLEND_ZERO: return GL_ZERO; - case GS_BLEND_ONE: return GL_ONE; - case GS_BLEND_SRCCOLOR: return GL_SRC_COLOR; - case GS_BLEND_INVSRCCOLOR: return GL_ONE_MINUS_SRC_COLOR; - case GS_BLEND_SRCALPHA: return GL_SRC_ALPHA; - case GS_BLEND_INVSRCALPHA: return GL_ONE_MINUS_SRC_ALPHA; - case GS_BLEND_DSTCOLOR: return GL_DST_COLOR; - case GS_BLEND_INVDSTCOLOR: return GL_ONE_MINUS_DST_COLOR; - case GS_BLEND_DSTALPHA: return GL_DST_ALPHA; - case GS_BLEND_INVDSTALPHA: return GL_ONE_MINUS_DST_ALPHA; - case GS_BLEND_SRCALPHASAT: return GL_SRC_ALPHA_SATURATE; + case GS_BLEND_ZERO: + return GL_ZERO; + case GS_BLEND_ONE: + return GL_ONE; + case GS_BLEND_SRCCOLOR: + return GL_SRC_COLOR; + case GS_BLEND_INVSRCCOLOR: + return GL_ONE_MINUS_SRC_COLOR; + case GS_BLEND_SRCALPHA: + return GL_SRC_ALPHA; + case GS_BLEND_INVSRCALPHA: + return GL_ONE_MINUS_SRC_ALPHA; + case GS_BLEND_DSTCOLOR: + return GL_DST_COLOR; + case GS_BLEND_INVDSTCOLOR: + return GL_ONE_MINUS_DST_COLOR; + case GS_BLEND_DSTALPHA: + return GL_DST_ALPHA; + case GS_BLEND_INVDSTALPHA: + return GL_ONE_MINUS_DST_ALPHA; + case GS_BLEND_SRCALPHASAT: + return GL_SRC_ALPHA_SATURATE; } return GL_ONE; @@ -193,15 +279,17 @@ static inline GLenum convert_gs_blend_type(enum gs_blend_type type) static inline GLenum convert_shader_type(enum gs_shader_type type) { switch (type) { - case GS_SHADER_VERTEX: return GL_VERTEX_SHADER; - case GS_SHADER_PIXEL: return GL_FRAGMENT_SHADER; + case GS_SHADER_VERTEX: + return GL_VERTEX_SHADER; + case GS_SHADER_PIXEL: + return GL_FRAGMENT_SHADER; } return GL_VERTEX_SHADER; } static inline void convert_filter(enum gs_sample_filter filter, - GLint *min_filter, GLint *mag_filter) + GLint *min_filter, GLint *mag_filter) { switch (filter) { case GS_FILTER_POINT: @@ -249,11 +337,16 @@ static inline void convert_filter(enum gs_sample_filter filter, static inline GLint convert_address_mode(enum gs_address_mode mode) { switch (mode) { - case GS_ADDRESS_WRAP: return GL_REPEAT; - case GS_ADDRESS_CLAMP: return GL_CLAMP_TO_EDGE; - case GS_ADDRESS_MIRROR: return GL_MIRRORED_REPEAT; - case GS_ADDRESS_BORDER: return GL_CLAMP_TO_BORDER; - case GS_ADDRESS_MIRRORONCE: return GL_MIRROR_CLAMP_EXT; + case GS_ADDRESS_WRAP: + return GL_REPEAT; + case GS_ADDRESS_CLAMP: + return GL_CLAMP_TO_EDGE; + case GS_ADDRESS_MIRROR: + return GL_MIRRORED_REPEAT; + case GS_ADDRESS_BORDER: + return GL_CLAMP_TO_BORDER; + case GS_ADDRESS_MIRRORONCE: + return GL_MIRROR_CLAMP_EXT; } return GL_REPEAT; @@ -262,29 +355,34 @@ static inline GLint convert_address_mode(enum gs_address_mode mode) static inline GLenum convert_gs_topology(enum gs_draw_mode mode) { switch (mode) { - case GS_POINTS: return GL_POINTS; - case GS_LINES: return GL_LINES; - case GS_LINESTRIP: return GL_LINE_STRIP; - case GS_TRIS: return GL_TRIANGLES; - case GS_TRISTRIP: return GL_TRIANGLE_STRIP; + case GS_POINTS: + return GL_POINTS; + case GS_LINES: + return GL_LINES; + case GS_LINESTRIP: + return GL_LINE_STRIP; + case GS_TRIS: + return GL_TRIANGLES; + case GS_TRISTRIP: + return GL_TRIANGLE_STRIP; } return GL_POINTS; } extern void convert_sampler_info(struct gs_sampler_state *sampler, - const struct gs_sampler_info *info); + const struct gs_sampler_info *info); struct gs_sampler_state { - gs_device_t *device; - volatile long ref; + gs_device_t *device; + volatile long ref; - GLint min_filter; - GLint mag_filter; - GLint address_u; - GLint address_v; - GLint address_w; - GLint max_anisotropy; + GLint min_filter; + GLint mag_filter; + GLint address_u; + GLint address_v; + GLint address_w; + GLint max_anisotropy; }; static inline void samplerstate_addref(gs_samplerstate_t *ss) @@ -298,21 +396,25 @@ static inline void samplerstate_release(gs_samplerstate_t *ss) bfree(ss); } +struct gs_timer { + GLuint queries[2]; +}; + struct gs_shader_param { enum gs_shader_param_type type; - char *name; - gs_shader_t *shader; - gs_samplerstate_t *next_sampler; - GLint texture_id; - size_t sampler_id; - int array_count; + char *name; + gs_shader_t *shader; + gs_samplerstate_t *next_sampler; + GLint texture_id; + size_t sampler_id; + int array_count; - struct gs_texture *texture; + struct gs_texture *texture; - DARRAY(uint8_t) cur_value; - DARRAY(uint8_t) def_value; - bool changed; + DARRAY(uint8_t) cur_value; + DARRAY(uint8_t) def_value; + bool changed; }; enum attrib_type { @@ -325,40 +427,40 @@ enum attrib_type { }; struct shader_attrib { - char *name; - size_t index; - enum attrib_type type; + char *name; + size_t index; + enum attrib_type type; }; struct gs_shader { - gs_device_t *device; - enum gs_shader_type type; - GLuint obj; + gs_device_t *device; + enum gs_shader_type type; + GLuint obj; - struct gs_shader_param *viewproj; - struct gs_shader_param *world; + struct gs_shader_param *viewproj; + struct gs_shader_param *world; - DARRAY(struct shader_attrib) attribs; + DARRAY(struct shader_attrib) attribs; DARRAY(struct gs_shader_param) params; - DARRAY(gs_samplerstate_t*) samplers; + DARRAY(gs_samplerstate_t *) samplers; }; struct program_param { - GLint obj; + GLint obj; struct gs_shader_param *param; }; struct gs_program { - gs_device_t *device; - GLuint obj; - struct gs_shader *vertex_shader; - struct gs_shader *pixel_shader; + gs_device_t *device; + GLuint obj; + struct gs_shader *vertex_shader; + struct gs_shader *pixel_shader; DARRAY(struct program_param) params; - DARRAY(GLint) attribs; + DARRAY(GLint) attribs; - struct gs_program **prev_next; - struct gs_program *next; + struct gs_program **prev_next; + struct gs_program *next; }; extern struct gs_program *gs_program_create(struct gs_device *device); @@ -366,106 +468,107 @@ extern void gs_program_destroy(struct gs_program *program); extern void program_update_params(struct gs_program *shader); struct gs_vertex_buffer { - GLuint vao; - GLuint vertex_buffer; - GLuint normal_buffer; - GLuint tangent_buffer; - GLuint color_buffer; - DARRAY(GLuint) uv_buffers; - DARRAY(size_t) uv_sizes; + GLuint vao; + GLuint vertex_buffer; + GLuint normal_buffer; + GLuint tangent_buffer; + GLuint color_buffer; + DARRAY(GLuint) uv_buffers; + DARRAY(size_t) uv_sizes; - gs_device_t *device; - size_t num; - bool dynamic; - struct gs_vb_data *data; + gs_device_t *device; + size_t num; + bool dynamic; + struct gs_vb_data *data; }; extern bool load_vb_buffers(struct gs_program *program, - struct gs_vertex_buffer *vb, struct gs_index_buffer *ib); + struct gs_vertex_buffer *vb, + struct gs_index_buffer *ib); struct gs_index_buffer { - GLuint buffer; - enum gs_index_type type; - GLuint gl_type; + GLuint buffer; + enum gs_index_type type; + GLuint gl_type; - gs_device_t *device; - void *data; - size_t num; - size_t width; - size_t size; - bool dynamic; + gs_device_t *device; + void *data; + size_t num; + size_t width; + size_t size; + bool dynamic; }; struct gs_texture { - gs_device_t *device; + gs_device_t *device; enum gs_texture_type type; enum gs_color_format format; - GLenum gl_format; - GLenum gl_target; - GLenum gl_internal_format; - GLenum gl_type; - GLuint texture; - uint32_t levels; - bool is_dynamic; - bool is_render_target; - bool is_dummy; - bool gen_mipmaps; + GLenum gl_format; + GLenum gl_target; + GLenum gl_internal_format; + GLenum gl_type; + GLuint texture; + uint32_t levels; + bool is_dynamic; + bool is_render_target; + bool is_dummy; + bool gen_mipmaps; - gs_samplerstate_t *cur_sampler; - struct fbo_info *fbo; + gs_samplerstate_t *cur_sampler; + struct fbo_info *fbo; }; struct gs_texture_2d { - struct gs_texture base; + struct gs_texture base; - uint32_t width; - uint32_t height; - bool gen_mipmaps; - GLuint unpack_buffer; + uint32_t width; + uint32_t height; + bool gen_mipmaps; + GLuint unpack_buffer; }; struct gs_texture_cube { - struct gs_texture base; + struct gs_texture base; - uint32_t size; + uint32_t size; }; struct gs_stage_surface { - gs_device_t *device; + gs_device_t *device; enum gs_color_format format; - uint32_t width; - uint32_t height; + uint32_t width; + uint32_t height; - uint32_t bytes_per_pixel; - GLenum gl_format; - GLint gl_internal_format; - GLenum gl_type; - GLuint pack_buffer; + uint32_t bytes_per_pixel; + GLenum gl_format; + GLint gl_internal_format; + GLenum gl_type; + GLuint pack_buffer; }; struct gs_zstencil_buffer { - gs_device_t *device; - GLuint buffer; - GLuint attachment; - GLenum format; + gs_device_t *device; + GLuint buffer; + GLuint attachment; + GLenum format; }; struct gs_swap_chain { - gs_device_t *device; + gs_device_t *device; struct gl_windowinfo *wi; - struct gs_init_data info; + struct gs_init_data info; }; struct fbo_info { - GLuint fbo; - uint32_t width; - uint32_t height; + GLuint fbo; + uint32_t width; + uint32_t height; enum gs_color_format format; - gs_texture_t *cur_render_target; - int cur_render_side; - gs_zstencil_t *cur_zstencil_buffer; + gs_texture_t *cur_render_target; + int cur_render_side; + gs_zstencil_t *cur_zstencil_buffer; }; static inline void fbo_info_destroy(struct fbo_info *fbo) @@ -479,51 +582,52 @@ static inline void fbo_info_destroy(struct fbo_info *fbo) } struct gs_device { - struct gl_platform *plat; - enum copy_type copy_type; + struct gl_platform *plat; + enum copy_type copy_type; - gs_texture_t *cur_render_target; - gs_zstencil_t *cur_zstencil_buffer; - int cur_render_side; - gs_texture_t *cur_textures[GS_MAX_TEXTURES]; - gs_samplerstate_t *cur_samplers[GS_MAX_TEXTURES]; - gs_vertbuffer_t *cur_vertex_buffer; - gs_indexbuffer_t *cur_index_buffer; - gs_shader_t *cur_vertex_shader; - gs_shader_t *cur_pixel_shader; - gs_swapchain_t *cur_swap; - struct gs_program *cur_program; + GLuint empty_vao; - struct gs_program *first_program; + gs_texture_t *cur_render_target; + gs_zstencil_t *cur_zstencil_buffer; + int cur_render_side; + gs_texture_t *cur_textures[GS_MAX_TEXTURES]; + gs_samplerstate_t *cur_samplers[GS_MAX_TEXTURES]; + gs_vertbuffer_t *cur_vertex_buffer; + gs_indexbuffer_t *cur_index_buffer; + gs_shader_t *cur_vertex_shader; + gs_shader_t *cur_pixel_shader; + gs_swapchain_t *cur_swap; + struct gs_program *cur_program; - enum gs_cull_mode cur_cull_mode; - struct gs_rect cur_viewport; + struct gs_program *first_program; - struct matrix4 cur_proj; - struct matrix4 cur_view; - struct matrix4 cur_viewproj; + enum gs_cull_mode cur_cull_mode; + struct gs_rect cur_viewport; - DARRAY(struct matrix4) proj_stack; + struct matrix4 cur_proj; + struct matrix4 cur_view; + struct matrix4 cur_viewproj; - struct fbo_info *cur_fbo; + DARRAY(struct matrix4) proj_stack; + + struct fbo_info *cur_fbo; }; extern struct fbo_info *get_fbo(gs_texture_t *tex, uint32_t width, - uint32_t height); + uint32_t height); -extern void gl_update(gs_device_t *device); +extern void gl_update(gs_device_t *device); -extern struct gl_platform *gl_platform_create(gs_device_t *device, - uint32_t adapter); -extern void gl_platform_destroy(struct gl_platform *platform); +extern struct gl_platform *gl_platform_create(gs_device_t *device, + uint32_t adapter); +extern void gl_platform_destroy(struct gl_platform *platform); extern bool gl_platform_init_swapchain(struct gs_swap_chain *swap); extern void gl_platform_cleanup_swapchain(struct gs_swap_chain *swap); -extern struct gl_windowinfo *gl_windowinfo_create( - const struct gs_init_data *info); -extern void gl_windowinfo_destroy(struct gl_windowinfo *wi); +extern struct gl_windowinfo * +gl_windowinfo_create(const struct gs_init_data *info); +extern void gl_windowinfo_destroy(struct gl_windowinfo *wi); -extern void gl_getclientsize(const struct gs_swap_chain *swap, - uint32_t *width, - uint32_t *height); +extern void gl_getclientsize(const struct gs_swap_chain *swap, uint32_t *width, + uint32_t *height); diff --git a/libobs-opengl/gl-texture2d.c b/libobs-opengl/gl-texture2d.c index da18b9f..91ca426 100644 --- a/libobs-opengl/gl-texture2d.c +++ b/libobs-opengl/gl-texture2d.c @@ -19,11 +19,11 @@ static bool upload_texture_2d(struct gs_texture_2d *tex, const uint8_t **data) { - uint32_t row_size = tex->width * gs_get_format_bpp(tex->base.format); - uint32_t tex_size = tex->height * row_size / 8; + uint32_t row_size = tex->width * gs_get_format_bpp(tex->base.format); + uint32_t tex_size = tex->height * row_size / 8; uint32_t num_levels = tex->base.levels; - bool compressed = gs_is_compressed_format(tex->base.format); - bool success; + bool compressed = gs_is_compressed_format(tex->base.format); + bool success; if (!num_levels) num_levels = gs_get_total_levels(tex->width, tex->height); @@ -32,10 +32,12 @@ static bool upload_texture_2d(struct gs_texture_2d *tex, const uint8_t **data) return false; success = gl_init_face(GL_TEXTURE_2D, tex->base.gl_type, num_levels, - tex->base.gl_format, tex->base.gl_internal_format, - compressed, tex->width, tex->height, tex_size, &data); + tex->base.gl_format, + tex->base.gl_internal_format, compressed, + tex->width, tex->height, tex_size, &data); - if (!gl_tex_param_i(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, num_levels-1)) + if (!gl_tex_param_i(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, + num_levels - 1)) success = false; if (!gl_bind_texture(GL_TEXTURE_2D, 0)) success = false; @@ -57,7 +59,7 @@ static bool create_pixel_unpack_buffer(struct gs_texture_2d *tex) size = tex->width * gs_get_format_bpp(tex->base.format); if (!gs_is_compressed_format(tex->base.format)) { size /= 8; - size = (size+3) & 0xFFFFFFFC; + size = (size + 3) & 0xFFFFFFFC; size *= tex->height; } else { size *= tex->height; @@ -75,24 +77,26 @@ static bool create_pixel_unpack_buffer(struct gs_texture_2d *tex) } gs_texture_t *device_texture_create(gs_device_t *device, uint32_t width, - uint32_t height, enum gs_color_format color_format, - uint32_t levels, const uint8_t **data, uint32_t flags) + uint32_t height, + enum gs_color_format color_format, + uint32_t levels, const uint8_t **data, + uint32_t flags) { struct gs_texture_2d *tex = bzalloc(sizeof(struct gs_texture_2d)); - tex->base.device = device; - tex->base.type = GS_TEXTURE_2D; - tex->base.format = color_format; - tex->base.levels = levels; - tex->base.gl_format = convert_gs_format(color_format); + tex->base.device = device; + tex->base.type = GS_TEXTURE_2D; + tex->base.format = color_format; + tex->base.levels = levels; + tex->base.gl_format = convert_gs_format(color_format); tex->base.gl_internal_format = convert_gs_internal_format(color_format); - tex->base.gl_type = get_gl_format_type(color_format); - tex->base.gl_target = GL_TEXTURE_2D; - tex->base.is_dynamic = (flags & GS_DYNAMIC) != 0; - tex->base.is_render_target = (flags & GS_RENDER_TARGET) != 0; - tex->base.is_dummy = (flags & GS_GL_DUMMYTEX) != 0; - tex->base.gen_mipmaps = (flags & GS_BUILD_MIPMAPS) != 0; - tex->width = width; - tex->height = height; + tex->base.gl_type = get_gl_format_type(color_format); + tex->base.gl_target = GL_TEXTURE_2D; + tex->base.is_dynamic = (flags & GS_DYNAMIC) != 0; + tex->base.is_render_target = (flags & GS_RENDER_TARGET) != 0; + tex->base.is_dummy = (flags & GS_GL_DUMMYTEX) != 0; + tex->base.gen_mipmaps = (flags & GS_BUILD_MIPMAPS) != 0; + tex->width = width; + tex->height = height; if (!gl_gen_textures(1, &tex->base.texture)) goto fail; @@ -102,12 +106,31 @@ gs_texture_t *device_texture_create(gs_device_t *device, uint32_t width, goto fail; if (!upload_texture_2d(tex, data)) goto fail; + } else { + if (!gl_bind_texture(GL_TEXTURE_2D, tex->base.texture)) + goto fail; + + uint32_t row_size = + tex->width * gs_get_format_bpp(tex->base.format); + uint32_t tex_size = tex->height * row_size / 8; + bool compressed = gs_is_compressed_format(tex->base.format); + bool did_init = gl_init_face(GL_TEXTURE_2D, tex->base.gl_type, + 1, tex->base.gl_format, + tex->base.gl_internal_format, + compressed, tex->width, + tex->height, tex_size, NULL); + did_init = + gl_tex_param_i(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + + bool did_unbind = gl_bind_texture(GL_TEXTURE_2D, 0); + if (!did_init || !did_unbind) + goto fail; } - return (gs_texture_t*)tex; + return (gs_texture_t *)tex; fail: - gs_texture_destroy((gs_texture_t*)tex); + gs_texture_destroy((gs_texture_t *)tex); blog(LOG_ERROR, "device_texture_create (GL) failed"); return NULL; } @@ -122,7 +145,7 @@ static inline bool is_texture_2d(const gs_texture_t *tex, const char *func) void gs_texture_destroy(gs_texture_t *tex) { - struct gs_texture_2d *tex2d = (struct gs_texture_2d*)tex; + struct gs_texture_2d *tex2d = (struct gs_texture_2d *)tex; if (!tex) return; @@ -146,7 +169,7 @@ void gs_texture_destroy(gs_texture_t *tex) uint32_t gs_texture_get_width(const gs_texture_t *tex) { - const struct gs_texture_2d *tex2d = (const struct gs_texture_2d*)tex; + const struct gs_texture_2d *tex2d = (const struct gs_texture_2d *)tex; if (!is_texture_2d(tex, "gs_texture_get_width")) return 0; @@ -155,7 +178,7 @@ uint32_t gs_texture_get_width(const gs_texture_t *tex) uint32_t gs_texture_get_height(const gs_texture_t *tex) { - const struct gs_texture_2d *tex2d = (const struct gs_texture_2d*)tex; + const struct gs_texture_2d *tex2d = (const struct gs_texture_2d *)tex; if (!is_texture_2d(tex, "gs_texture_get_height")) return 0; @@ -169,7 +192,7 @@ enum gs_color_format gs_texture_get_color_format(const gs_texture_t *tex) bool gs_texture_map(gs_texture_t *tex, uint8_t **ptr, uint32_t *linesize) { - struct gs_texture_2d *tex2d = (struct gs_texture_2d*)tex; + struct gs_texture_2d *tex2d = (struct gs_texture_2d *)tex; if (!is_texture_2d(tex, "gs_texture_map")) goto fail; @@ -199,7 +222,7 @@ fail: void gs_texture_unmap(gs_texture_t *tex) { - struct gs_texture_2d *tex2d = (struct gs_texture_2d*)tex; + struct gs_texture_2d *tex2d = (struct gs_texture_2d *)tex; if (!is_texture_2d(tex, "gs_texture_unmap")) goto failed; @@ -213,9 +236,8 @@ void gs_texture_unmap(gs_texture_t *tex) if (!gl_bind_texture(GL_TEXTURE_2D, tex2d->base.texture)) goto failed; - glTexImage2D(GL_TEXTURE_2D, 0, tex->gl_internal_format, - tex2d->width, tex2d->height, 0, - tex->gl_format, tex->gl_type, 0); + glTexImage2D(GL_TEXTURE_2D, 0, tex->gl_internal_format, tex2d->width, + tex2d->height, 0, tex->gl_format, tex->gl_type, 0); if (!gl_success("glTexImage2D")) goto failed; @@ -231,7 +253,7 @@ failed: bool gs_texture_is_rect(const gs_texture_t *tex) { - const struct gs_texture_2d *tex2d = (const struct gs_texture_2d*)tex; + const struct gs_texture_2d *tex2d = (const struct gs_texture_2d *)tex; if (!is_texture_2d(tex, "gs_texture_unmap")) { blog(LOG_ERROR, "gs_texture_is_rect (GL) failed"); return false; @@ -242,7 +264,7 @@ bool gs_texture_is_rect(const gs_texture_t *tex) void *gs_texture_get_obj(gs_texture_t *tex) { - struct gs_texture_2d *tex2d = (struct gs_texture_2d*)tex; + struct gs_texture_2d *tex2d = (struct gs_texture_2d *)tex; if (!is_texture_2d(tex, "gs_texture_unmap")) { blog(LOG_ERROR, "gs_texture_get_obj (GL) failed"); return NULL; diff --git a/libobs-opengl/gl-texturecube.c b/libobs-opengl/gl-texturecube.c index 6086675..02ba4a5 100644 --- a/libobs-opengl/gl-texturecube.c +++ b/libobs-opengl/gl-texturecube.c @@ -18,14 +18,14 @@ #include "gl-subsystem.h" static inline bool upload_texture_cube(struct gs_texture_cube *tex, - const uint8_t **data) + const uint8_t **data) { - uint32_t row_size = tex->size * gs_get_format_bpp(tex->base.format); - uint32_t tex_size = tex->size * row_size / 8; + uint32_t row_size = tex->size * gs_get_format_bpp(tex->base.format); + uint32_t tex_size = tex->size * row_size / 8; uint32_t num_levels = tex->base.levels; - bool compressed = gs_is_compressed_format(tex->base.format); - GLenum gl_type = get_gl_format_type(tex->base.format); - bool success = true; + bool compressed = gs_is_compressed_format(tex->base.format); + GLenum gl_type = get_gl_format_type(tex->base.format); + bool success = true; uint32_t i; if (!num_levels) @@ -38,10 +38,9 @@ static inline bool upload_texture_cube(struct gs_texture_cube *tex, success = false; if (!gl_init_face(target, gl_type, num_levels, - tex->base.gl_format, - tex->base.gl_internal_format, - compressed, tex->size, tex->size, - tex_size, &data)) + tex->base.gl_format, + tex->base.gl_internal_format, compressed, + tex->size, tex->size, tex_size, &data)) success = false; if (!gl_bind_texture(target, 0)) @@ -59,30 +58,31 @@ static inline bool upload_texture_cube(struct gs_texture_cube *tex, } gs_texture_t *device_cubetexture_create(gs_device_t *device, uint32_t size, - enum gs_color_format color_format, uint32_t levels, - const uint8_t **data, uint32_t flags) + enum gs_color_format color_format, + uint32_t levels, const uint8_t **data, + uint32_t flags) { struct gs_texture_cube *tex = bzalloc(sizeof(struct gs_texture_cube)); - tex->base.device = device; - tex->base.type = GS_TEXTURE_CUBE; - tex->base.format = color_format; - tex->base.levels = levels; - tex->base.gl_format = convert_gs_format(color_format); + tex->base.device = device; + tex->base.type = GS_TEXTURE_CUBE; + tex->base.format = color_format; + tex->base.levels = levels; + tex->base.gl_format = convert_gs_format(color_format); tex->base.gl_internal_format = convert_gs_internal_format(color_format); - tex->base.gl_target = GL_TEXTURE_CUBE_MAP; - tex->base.is_render_target = (flags & GS_RENDER_TARGET) != 0; - tex->base.gen_mipmaps = (flags & GS_BUILD_MIPMAPS) != 0; - tex->size = size; + tex->base.gl_target = GL_TEXTURE_CUBE_MAP; + tex->base.is_render_target = (flags & GS_RENDER_TARGET) != 0; + tex->base.gen_mipmaps = (flags & GS_BUILD_MIPMAPS) != 0; + tex->size = size; if (!gl_gen_textures(1, &tex->base.texture)) goto fail; if (!upload_texture_cube(tex, data)) goto fail; - return (gs_texture_t*)tex; + return (gs_texture_t *)tex; fail: - gs_cubetexture_destroy((gs_texture_t*)tex); + gs_cubetexture_destroy((gs_texture_t *)tex); blog(LOG_ERROR, "device_cubetexture_create (GL) failed"); return NULL; } @@ -112,7 +112,7 @@ static inline bool is_texture_cube(const gs_texture_t *tex, const char *func) uint32_t gs_cubetexture_get_size(const gs_texture_t *cubetex) { const struct gs_texture_cube *cube = - (const struct gs_texture_cube*)cubetex; + (const struct gs_texture_cube *)cubetex; if (!is_texture_cube(cubetex, "gs_cubetexture_get_size")) return 0; @@ -120,8 +120,8 @@ uint32_t gs_cubetexture_get_size(const gs_texture_t *cubetex) return cube->size; } -enum gs_color_format gs_cubetexture_get_color_format( - const gs_texture_t *cubetex) +enum gs_color_format +gs_cubetexture_get_color_format(const gs_texture_t *cubetex) { return cubetex->format; } diff --git a/libobs-opengl/gl-vertexbuffer.c b/libobs-opengl/gl-vertexbuffer.c index a56e651..2d212ce 100644 --- a/libobs-opengl/gl-vertexbuffer.c +++ b/libobs-opengl/gl-vertexbuffer.c @@ -24,45 +24,45 @@ static bool create_buffers(struct gs_vertex_buffer *vb) size_t i; if (!gl_create_buffer(GL_ARRAY_BUFFER, &vb->vertex_buffer, - vb->data->num * sizeof(struct vec3), - vb->data->points, usage)) + vb->data->num * sizeof(struct vec3), + vb->data->points, usage)) return false; if (vb->data->normals) { if (!gl_create_buffer(GL_ARRAY_BUFFER, &vb->normal_buffer, - vb->data->num * sizeof(struct vec3), - vb->data->normals, usage)) + vb->data->num * sizeof(struct vec3), + vb->data->normals, usage)) return false; } if (vb->data->tangents) { if (!gl_create_buffer(GL_ARRAY_BUFFER, &vb->tangent_buffer, - vb->data->num * sizeof(struct vec3), - vb->data->tangents, usage)) + vb->data->num * sizeof(struct vec3), + vb->data->tangents, usage)) return false; } if (vb->data->colors) { if (!gl_create_buffer(GL_ARRAY_BUFFER, &vb->color_buffer, - vb->data->num * sizeof(uint32_t), - vb->data->colors, usage)) + vb->data->num * sizeof(uint32_t), + vb->data->colors, usage)) return false; } da_reserve(vb->uv_buffers, vb->data->num_tex); - da_reserve(vb->uv_sizes, vb->data->num_tex); + da_reserve(vb->uv_sizes, vb->data->num_tex); for (i = 0; i < vb->data->num_tex; i++) { GLuint tex_buffer; - struct gs_tvertarray *tv = vb->data->tvarray+i; + struct gs_tvertarray *tv = vb->data->tvarray + i; size_t size = vb->data->num * sizeof(float) * tv->width; if (!gl_create_buffer(GL_ARRAY_BUFFER, &tex_buffer, size, - tv->array, usage)) + tv->array, usage)) return false; da_push_back(vb->uv_buffers, &tex_buffer); - da_push_back(vb->uv_sizes, &tv->width); + da_push_back(vb->uv_sizes, &tv->width); } if (!vb->dynamic) { @@ -77,12 +77,13 @@ static bool create_buffers(struct gs_vertex_buffer *vb) } gs_vertbuffer_t *device_vertexbuffer_create(gs_device_t *device, - struct gs_vb_data *data, uint32_t flags) + struct gs_vb_data *data, + uint32_t flags) { struct gs_vertex_buffer *vb = bzalloc(sizeof(struct gs_vertex_buffer)); - vb->device = device; - vb->data = data; - vb->num = data->num; + vb->device = device; + vb->data = data; + vb->num = data->num; vb->dynamic = flags & GS_DYNAMIC; if (!create_buffers(vb)) { @@ -107,7 +108,7 @@ void gs_vertexbuffer_destroy(gs_vertbuffer_t *vb) gl_delete_buffers(1, &vb->color_buffer); if (vb->uv_buffers.num) gl_delete_buffers((GLsizei)vb->uv_buffers.num, - vb->uv_buffers.array); + vb->uv_buffers.array); if (vb->vao) gl_delete_vertex_arrays(1, &vb->vao); @@ -121,12 +122,11 @@ void gs_vertexbuffer_destroy(gs_vertbuffer_t *vb) } static inline void gs_vertexbuffer_flush_internal(gs_vertbuffer_t *vb, - const struct gs_vb_data *data) + const struct gs_vb_data *data) { size_t i; - size_t num_tex = data->num_tex < vb->data->num_tex - ? data->num_tex - : vb->data->num_tex; + size_t num_tex = data->num_tex < vb->data->num_tex ? data->num_tex + : vb->data->num_tex; if (!vb->dynamic) { blog(LOG_ERROR, "vertex buffer is not dynamic"); @@ -135,35 +135,34 @@ static inline void gs_vertexbuffer_flush_internal(gs_vertbuffer_t *vb, if (data->points) { if (!update_buffer(GL_ARRAY_BUFFER, vb->vertex_buffer, - data->points, - data->num * sizeof(struct vec3))) + data->points, + data->num * sizeof(struct vec3))) goto failed; } if (vb->normal_buffer && data->normals) { if (!update_buffer(GL_ARRAY_BUFFER, vb->normal_buffer, - data->normals, - data->num * sizeof(struct vec3))) + data->normals, + data->num * sizeof(struct vec3))) goto failed; } if (vb->tangent_buffer && data->tangents) { if (!update_buffer(GL_ARRAY_BUFFER, vb->tangent_buffer, - data->tangents, - data->num * sizeof(struct vec3))) + data->tangents, + data->num * sizeof(struct vec3))) goto failed; } if (vb->color_buffer && data->colors) { if (!update_buffer(GL_ARRAY_BUFFER, vb->color_buffer, - data->colors, - data->num * sizeof(uint32_t))) + data->colors, data->num * sizeof(uint32_t))) goto failed; } for (i = 0; i < num_tex; i++) { GLuint buffer = vb->uv_buffers.array[i]; - struct gs_tvertarray *tv = data->tvarray+i; + struct gs_tvertarray *tv = data->tvarray + i; size_t size = data->num * tv->width * sizeof(float); if (!update_buffer(GL_ARRAY_BUFFER, buffer, tv->array, size)) @@ -182,7 +181,7 @@ void gs_vertexbuffer_flush(gs_vertbuffer_t *vb) } void gs_vertexbuffer_flush_direct(gs_vertbuffer_t *vb, - const struct gs_vb_data *data) + const struct gs_vb_data *data) { gs_vertexbuffer_flush_internal(vb, data); } @@ -193,11 +192,11 @@ struct gs_vb_data *gs_vertexbuffer_get_data(const gs_vertbuffer_t *vb) } static inline GLuint get_vb_buffer(struct gs_vertex_buffer *vb, - enum attrib_type type, size_t index, GLint *width, - GLenum *gl_type) + enum attrib_type type, size_t index, + GLint *width, GLenum *gl_type) { *gl_type = GL_FLOAT; - *width = 4; + *width = 4; if (type == ATTRIB_POSITION) { return vb->vertex_buffer; @@ -220,7 +219,7 @@ static inline GLuint get_vb_buffer(struct gs_vertex_buffer *vb, } static bool load_vb_buffer(struct shader_attrib *attrib, - struct gs_vertex_buffer *vb, GLint id) + struct gs_vertex_buffer *vb, GLint id) { GLenum type; GLint width; @@ -230,7 +229,7 @@ static bool load_vb_buffer(struct shader_attrib *attrib, buffer = get_vb_buffer(vb, attrib->type, attrib->index, &width, &type); if (!buffer) { blog(LOG_ERROR, "Vertex buffer does not have the required " - "inputs for vertex shader"); + "inputs for vertex shader"); return false; } @@ -252,7 +251,7 @@ static bool load_vb_buffer(struct shader_attrib *attrib, } bool load_vb_buffers(struct gs_program *program, struct gs_vertex_buffer *vb, - struct gs_index_buffer *ib) + struct gs_index_buffer *ib) { struct gs_shader *shader = program->vertex_shader; size_t i; @@ -261,7 +260,7 @@ bool load_vb_buffers(struct gs_program *program, struct gs_vertex_buffer *vb, return false; for (i = 0; i < shader->attribs.num; i++) { - struct shader_attrib *attrib = shader->attribs.array+i; + struct shader_attrib *attrib = shader->attribs.array + i; if (!load_vb_buffer(attrib, vb, program->attribs.array[i])) return false; } diff --git a/libobs-opengl/gl-windows.c b/libobs-opengl/gl-windows.c index c6c8499..3b2e9cd 100644 --- a/libobs-opengl/gl-windows.c +++ b/libobs-opengl/gl-windows.c @@ -26,7 +26,7 @@ * super basic stuff */ struct gl_windowinfo { HWND hwnd; - HDC hdc; + HDC hdc; }; /* Like the other subsystems, the GL subsystem has one swap chain created by @@ -73,24 +73,24 @@ static inline int get_stencil_format_bits(enum gs_zstencil_format zsformat) static inline void init_dummy_pixel_format(PIXELFORMATDESCRIPTOR *pfd) { memset(pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); - pfd->nSize = sizeof(pfd); - pfd->nVersion = 1; - pfd->iPixelType = PFD_TYPE_RGBA; - pfd->cColorBits = 32; - pfd->cDepthBits = 24; + pfd->nSize = sizeof(pfd); + pfd->nVersion = 1; + pfd->iPixelType = PFD_TYPE_RGBA; + pfd->cColorBits = 32; + pfd->cDepthBits = 24; pfd->cStencilBits = 8; - pfd->iLayerType = PFD_MAIN_PLANE; - pfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | - PFD_DOUBLEBUFFER; + pfd->iLayerType = PFD_MAIN_PLANE; + pfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | + PFD_DOUBLEBUFFER; } static const char *dummy_window_class = "GLDummyWindow"; static bool registered_dummy_window_class = false; struct dummy_context { - HWND hwnd; + HWND hwnd; HGLRC hrc; - HDC hdc; + HDC hdc; }; /* Need a dummy window for the dummy context */ @@ -118,9 +118,8 @@ static bool gl_register_dummy_window_class(void) static inline HWND gl_create_dummy_window(void) { HWND hwnd = CreateWindowExA(0, dummy_window_class, "Dummy GL Window", - WS_POPUP, - 0, 0, 2, 2, - NULL, NULL, GetModuleHandle(NULL), NULL); + WS_POPUP, 0, 0, 2, 2, NULL, NULL, + GetModuleHandle(NULL), NULL); if (!hwnd) blog(LOG_ERROR, "Could not create dummy context window"); @@ -131,8 +130,10 @@ static inline bool wgl_make_current(HDC hdc, HGLRC hglrc) { bool success = wglMakeCurrent(hdc, hglrc); if (!success) - blog(LOG_ERROR, "wglMakeCurrent failed, GetLastError " - "returned %lu", GetLastError()); + blog(LOG_ERROR, + "wglMakeCurrent failed, GetLastError " + "returned %lu", + GetLastError()); return success; } @@ -153,14 +154,11 @@ static inline HGLRC gl_init_basic_context(HDC hdc) return hglrc; } -static const int attribs[] = -{ +static const int attribs[] = { #ifdef _DEBUG - WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, + WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, #endif - WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - 0, 0 -}; + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, 0, 0}; static inline HGLRC gl_init_context(HDC hdc) { @@ -168,8 +166,10 @@ static inline HGLRC gl_init_context(HDC hdc) if (GLAD_WGL_ARB_create_context) { HGLRC hglrc = wglCreateContextAttribsARB(hdc, 0, attribs); if (!hglrc) { - blog(LOG_ERROR, "wglCreateContextAttribsARB failed, " - "%lu", GetLastError()); + blog(LOG_ERROR, + "wglCreateContextAttribsARB failed, " + "%lu", + GetLastError()); return NULL; } @@ -203,13 +203,13 @@ static bool gl_dummy_context_init(struct dummy_context *dummy) format_index = ChoosePixelFormat(dummy->hdc, &pfd); if (!format_index) { blog(LOG_ERROR, "Dummy ChoosePixelFormat failed, %lu", - GetLastError()); + GetLastError()); return false; } if (!SetPixelFormat(dummy->hdc, format_index, &pfd)) { blog(LOG_ERROR, "Dummy SetPixelFormat failed, %lu", - GetLastError()); + GetLastError()); return false; } @@ -270,8 +270,8 @@ static inline void add_attrib(struct darray *list, int attrib, int val) static int gl_choose_pixel_format(HDC hdc, const struct gs_init_data *info) { struct darray attribs; - int color_bits = get_color_format_bits(info->format); - int depth_bits = get_depth_format_bits(info->zsformat); + int color_bits = get_color_format_bits(info->format); + int depth_bits = get_depth_format_bits(info->zsformat); int stencil_bits = get_stencil_format_bits(info->zsformat); UINT num_formats; BOOL success; @@ -279,26 +279,26 @@ static int gl_choose_pixel_format(HDC hdc, const struct gs_init_data *info) if (!color_bits) { blog(LOG_ERROR, "gl_init_pixel_format: color format not " - "supported"); + "supported"); return false; } darray_init(&attribs); add_attrib(&attribs, WGL_DRAW_TO_WINDOW_ARB, GL_TRUE); add_attrib(&attribs, WGL_SUPPORT_OPENGL_ARB, GL_TRUE); - add_attrib(&attribs, WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB); - add_attrib(&attribs, WGL_DOUBLE_BUFFER_ARB, GL_TRUE); - add_attrib(&attribs, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB); - add_attrib(&attribs, WGL_COLOR_BITS_ARB, color_bits); - add_attrib(&attribs, WGL_DEPTH_BITS_ARB, depth_bits); - add_attrib(&attribs, WGL_STENCIL_BITS_ARB, stencil_bits); + add_attrib(&attribs, WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB); + add_attrib(&attribs, WGL_DOUBLE_BUFFER_ARB, GL_TRUE); + add_attrib(&attribs, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB); + add_attrib(&attribs, WGL_COLOR_BITS_ARB, color_bits); + add_attrib(&attribs, WGL_DEPTH_BITS_ARB, depth_bits); + add_attrib(&attribs, WGL_STENCIL_BITS_ARB, stencil_bits); add_attrib(&attribs, 0, 0); success = wglChoosePixelFormatARB(hdc, attribs.array, NULL, 1, &format, - &num_formats); + &num_formats); if (!success || !num_formats) { blog(LOG_ERROR, "wglChoosePixelFormatARB failed, %lu", - GetLastError()); + GetLastError()); format = 0; } @@ -308,7 +308,7 @@ static int gl_choose_pixel_format(HDC hdc, const struct gs_init_data *info) } static inline bool gl_getpixelformat(HDC hdc, const struct gs_init_data *info, - int *format, PIXELFORMATDESCRIPTOR *pfd) + int *format, PIXELFORMATDESCRIPTOR *pfd) { if (!format) return false; @@ -317,7 +317,7 @@ static inline bool gl_getpixelformat(HDC hdc, const struct gs_init_data *info, if (!DescribePixelFormat(hdc, *format, sizeof(*pfd), pfd)) { blog(LOG_ERROR, "DescribePixelFormat failed, %lu", - GetLastError()); + GetLastError()); return false; } @@ -325,7 +325,7 @@ static inline bool gl_getpixelformat(HDC hdc, const struct gs_init_data *info, } static inline bool gl_setpixelformat(HDC hdc, int format, - PIXELFORMATDESCRIPTOR *pfd) + PIXELFORMATDESCRIPTOR *pfd) { if (!SetPixelFormat(hdc, format, pfd)) { blog(LOG_ERROR, "SetPixelFormat failed, %lu", GetLastError()); @@ -339,7 +339,7 @@ static struct gl_windowinfo *gl_windowinfo_bare(const struct gs_init_data *info) { struct gl_windowinfo *wi = bzalloc(sizeof(struct gl_windowinfo)); wi->hwnd = info->window.hwnd; - wi->hdc = GetDC(wi->hwnd); + wi->hdc = GetDC(wi->hwnd); if (!wi->hdc) { blog(LOG_ERROR, "Unable to get device context from window"); @@ -356,10 +356,10 @@ static bool register_dummy_class(void) { static bool created = false; - WNDCLASSA wc = {0}; - wc.style = CS_OWNDC; - wc.hInstance = GetModuleHandleW(NULL); - wc.lpfnWndProc = (WNDPROC)DefWindowProcA; + WNDCLASSA wc = {0}; + wc.style = CS_OWNDC; + wc.hInstance = GetModuleHandleW(NULL); + wc.lpfnWndProc = (WNDPROC)DefWindowProcA; wc.lpszClassName = DUMMY_WNDCLASS; if (created) @@ -367,7 +367,7 @@ static bool register_dummy_class(void) if (!RegisterClassA(&wc)) { blog(LOG_ERROR, "Failed to register dummy GL window class, %lu", - GetLastError()); + GetLastError()); return false; } @@ -378,18 +378,19 @@ static bool register_dummy_class(void) static bool create_dummy_window(struct gl_platform *plat) { plat->window.hwnd = CreateWindowExA(0, DUMMY_WNDCLASS, - "OpenGL Dummy Window", WS_POPUP, 0, 0, 1, 1, - NULL, NULL, GetModuleHandleW(NULL), NULL); + "OpenGL Dummy Window", WS_POPUP, 0, + 0, 1, 1, NULL, NULL, + GetModuleHandleW(NULL), NULL); if (!plat->window.hwnd) { blog(LOG_ERROR, "Failed to create dummy GL window, %lu", - GetLastError()); + GetLastError()); return false; } plat->window.hdc = GetDC(plat->window.hwnd); if (!plat->window.hdc) { blog(LOG_ERROR, "Failed to get dummy GL window DC (%lu)", - GetLastError()); + GetLastError()); return false; } @@ -397,7 +398,7 @@ static bool create_dummy_window(struct gl_platform *plat) } static bool init_default_swap(struct gl_platform *plat, gs_device_t *device, - int pixel_format, PIXELFORMATDESCRIPTOR *pfd) + int pixel_format, PIXELFORMATDESCRIPTOR *pfd) { if (!gl_setpixelformat(plat->window.hdc, pixel_format, pfd)) return false; @@ -541,6 +542,11 @@ void device_leave_context(gs_device_t *device) UNUSED_PARAMETER(device); } +void *device_get_device_obj(gs_device_t *device) +{ + return device->plat->hrc; +} + void device_load_swapchain(gs_device_t *device, gs_swapchain_t *swap) { HDC hdc = device->plat->window.hdc; @@ -561,19 +567,21 @@ void device_load_swapchain(gs_device_t *device, gs_swapchain_t *swap) void device_present(gs_device_t *device) { if (!SwapBuffers(device->cur_swap->wi->hdc)) { - blog(LOG_ERROR, "SwapBuffers failed, GetLastError " - "returned %lu", GetLastError()); + blog(LOG_ERROR, + "SwapBuffers failed, GetLastError " + "returned %lu", + GetLastError()); blog(LOG_ERROR, "device_present (GL) failed"); } } -extern void gl_getclientsize(const struct gs_swap_chain *swap, - uint32_t *width, uint32_t *height) +extern void gl_getclientsize(const struct gs_swap_chain *swap, uint32_t *width, + uint32_t *height) { RECT rc; if (swap) { GetClientRect(swap->wi->hwnd, &rc); - *width = rc.right; + *width = rc.right; *height = rc.bottom; } else { *width = 0; diff --git a/libobs-opengl/gl-x11.c b/libobs-opengl/gl-x11.c index 697ef38..ae35be9 100644 --- a/libobs-opengl/gl-x11.c +++ b/libobs-opengl/gl-x11.c @@ -42,28 +42,34 @@ static const int ctx_attribs[] = { #ifdef _DEBUG - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, + GLX_CONTEXT_FLAGS_ARB, + GLX_CONTEXT_DEBUG_BIT_ARB, #endif - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 2, + GLX_CONTEXT_PROFILE_MASK_ARB, + GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + GLX_CONTEXT_MAJOR_VERSION_ARB, + 3, + GLX_CONTEXT_MINOR_VERSION_ARB, + 2, None, }; -static int ctx_pbuffer_attribs[] = { - GLX_PBUFFER_WIDTH, 2, - GLX_PBUFFER_HEIGHT, 2, - None -}; +static int ctx_pbuffer_attribs[] = {GLX_PBUFFER_WIDTH, 2, GLX_PBUFFER_HEIGHT, 2, + None}; -static int ctx_visual_attribs[] = { - GLX_STENCIL_SIZE, 0, - GLX_DEPTH_SIZE, 0, - GLX_BUFFER_SIZE, 32, - GLX_ALPHA_SIZE, 8, - GLX_DOUBLEBUFFER, true, - GLX_X_RENDERABLE, true, - None -}; +static int ctx_visual_attribs[] = {GLX_STENCIL_SIZE, + 0, + GLX_DEPTH_SIZE, + 0, + GLX_BUFFER_SIZE, + 32, + GLX_ALPHA_SIZE, + 8, + GLX_DOUBLEBUFFER, + true, + GLX_X_RENDERABLE, + true, + None}; struct gl_windowinfo { /* We store this value since we can fetch a lot @@ -91,17 +97,14 @@ struct gl_platform { static void print_info_stuff(const struct gs_init_data *info) { - blog( LOG_INFO, - "X and Y: %i %i\n" - "Backbuffers: %i\n" - "Color Format: %i\n" - "ZStencil Format: %i\n" - "Adapter: %i\n", - info->cx, info->cy, - info->num_backbuffers, - info->format, info->zsformat, - info->adapter - ); + blog(LOG_INFO, + "X and Y: %i %i\n" + "Backbuffers: %i\n" + "Color Format: %i\n" + "ZStencil Format: %i\n" + "Adapter: %i\n", + info->cx, info->cy, info->num_backbuffers, info->format, + info->zsformat, info->adapter); } /* The following utility functions are copied verbatim from WGL code. * GLX and WGL are more similar than most people realize. */ @@ -150,7 +153,7 @@ static inline int get_stencil_format_bits(enum gs_zstencil_format zsformat) /* Returns -1 on invalid screen. */ static int get_screen_num_from_xcb_screen(xcb_connection_t *xcb_conn, - xcb_screen_t *screen) + xcb_screen_t *screen) { xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_get_setup(xcb_conn)); @@ -164,7 +167,7 @@ static int get_screen_num_from_xcb_screen(xcb_connection_t *xcb_conn, } static xcb_screen_t *get_screen_from_root(xcb_connection_t *xcb_conn, - xcb_window_t root) + xcb_window_t root) { xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_get_setup(xcb_conn)); @@ -180,17 +183,18 @@ static xcb_screen_t *get_screen_from_root(xcb_connection_t *xcb_conn, } static inline int get_screen_num_from_root(xcb_connection_t *xcb_conn, - xcb_window_t root) + xcb_window_t root) { xcb_screen_t *screen = get_screen_from_root(xcb_conn, root); - if (!screen) return -1; + if (!screen) + return -1; return get_screen_num_from_xcb_screen(xcb_conn, screen); } -static xcb_get_geometry_reply_t* get_window_geometry( - xcb_connection_t *xcb_conn, xcb_drawable_t drawable) +static xcb_get_geometry_reply_t *get_window_geometry(xcb_connection_t *xcb_conn, + xcb_drawable_t drawable) { xcb_get_geometry_cookie_t cookie; xcb_generic_error_t *error; @@ -224,14 +228,14 @@ static bool gl_context_create(struct gl_platform *plat) } config = glXChooseFBConfig(display, DefaultScreen(display), - ctx_visual_attribs, &frame_buf_config_count); + ctx_visual_attribs, &frame_buf_config_count); if (!config) { blog(LOG_ERROR, "Failed to create OpenGL frame buffer config"); return false; } - context = glXCreateContextAttribsARB(display, config[0], NULL, - true, ctx_attribs); + context = glXCreateContextAttribsARB(display, config[0], NULL, true, + ctx_attribs); if (!context) { blog(LOG_ERROR, "Failed to create OpenGL context."); goto error; @@ -240,8 +244,8 @@ static bool gl_context_create(struct gl_platform *plat) plat->context = context; plat->display = display; - plat->pbuffer = glXCreatePbuffer(display, config[0], - ctx_pbuffer_attribs); + plat->pbuffer = + glXCreatePbuffer(display, config[0], ctx_pbuffer_attribs); if (!plat->pbuffer) { blog(LOG_ERROR, "Failed to create OpenGL pbuffer"); goto error; @@ -264,7 +268,8 @@ static void gl_context_destroy(struct gl_platform *plat) bfree(plat); } -extern struct gl_windowinfo *gl_windowinfo_create(const struct gs_init_data *info) +extern struct gl_windowinfo * +gl_windowinfo_create(const struct gs_init_data *info) { UNUSED_PARAMETER(info); return bmalloc(sizeof(struct gl_windowinfo)); @@ -330,20 +335,21 @@ static int x_error_handler(Display *display, XErrorEvent *error) XGetErrorText(display, error->request_code, str2, sizeof(str2)); XGetErrorText(display, error->minor_code, str3, sizeof(str3)); - blog(LOG_ERROR, "X Error: %s, Major opcode: %s, " - "Minor opcode: %s, Serial: %lu", - str1, str2, str3, error->serial); + blog(LOG_ERROR, + "X Error: %s, Major opcode: %s, " + "Minor opcode: %s, Serial: %lu", + str1, str2, str3, error->serial); return 0; } extern struct gl_platform *gl_platform_create(gs_device_t *device, - uint32_t adapter) + uint32_t adapter) { /* There's some trickery here... we're mixing libX11, xcb, and GLX For an explanation see here: http://xcb.freedesktop.org/MixingCalls/ Essentially, GLX requires Xlib. Everything else we use xcb. */ - struct gl_platform * plat = bmalloc(sizeof(struct gl_platform)); - Display * display = open_windowless_display(); + struct gl_platform *plat = bmalloc(sizeof(struct gl_platform)); + Display *display = open_windowless_display(); if (!display) { goto fail_display_open; @@ -363,7 +369,7 @@ extern struct gl_platform *gl_platform_create(gs_device_t *device, } if (!glXMakeContextCurrent(plat->display, plat->pbuffer, plat->pbuffer, - plat->context)) { + plat->context)) { blog(LOG_ERROR, "Failed to make context current."); goto fail_make_current; } @@ -410,7 +416,8 @@ extern bool gl_platform_init_swapchain(struct gs_swap_chain *swap) int visual; GLXFBConfig *fb_config; - if (!geometry) goto fail_geometry_request; + if (!geometry) + goto fail_geometry_request; screen_num = get_screen_num_from_root(xcb_conn, geometry->root); if (screen_num == -1) { @@ -421,7 +428,7 @@ extern bool gl_platform_init_swapchain(struct gs_swap_chain *swap) { int num_configs; fb_config = glXChooseFBConfig(display, screen_num, - ctx_visual_attribs, &num_configs); + ctx_visual_attribs, &num_configs); if (!fb_config || !num_configs) { blog(LOG_ERROR, "Failed to find FBConfig!"); @@ -431,7 +438,8 @@ extern bool gl_platform_init_swapchain(struct gs_swap_chain *swap) /* ...then fetch matching visual info for xcb. */ { - int error = glXGetFBConfigAttrib(display, fb_config[0], GLX_VISUAL_ID, &visual); + int error = glXGetFBConfigAttrib(display, fb_config[0], + GLX_VISUAL_ID, &visual); if (error) { blog(LOG_ERROR, "Bad call to GetFBConfigAttrib!"); @@ -439,27 +447,16 @@ extern bool gl_platform_init_swapchain(struct gs_swap_chain *swap) } } - xcb_colormap_t colormap = xcb_generate_id(xcb_conn); uint32_t mask = XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP; - uint32_t mask_values[] = { 0, colormap, 0 }; + uint32_t mask_values[] = {0, colormap, 0}; - xcb_create_colormap(xcb_conn, - XCB_COLORMAP_ALLOC_NONE, - colormap, - parent, - visual - ); + xcb_create_colormap(xcb_conn, XCB_COLORMAP_ALLOC_NONE, colormap, parent, + visual); - xcb_create_window( - xcb_conn, 24 /* Hardcoded? */, - wid, parent, - 0, 0, - geometry->width, - geometry->height, - 0, 0, - visual, mask, mask_values - ); + xcb_create_window(xcb_conn, 24 /* Hardcoded? */, wid, parent, 0, 0, + geometry->width, geometry->height, 0, 0, visual, mask, + mask_values); swap->wi->config = fb_config[0]; swap->wi->window = wid; @@ -513,15 +510,22 @@ extern void device_leave_context(gs_device_t *device) } } -extern void gl_getclientsize(const struct gs_swap_chain *swap, - uint32_t *width, uint32_t *height) +void *device_get_device_obj(gs_device_t *device) { - xcb_connection_t *xcb_conn = XGetXCBConnection(swap->device->plat->display); + return device->plat->context; +} + +extern void gl_getclientsize(const struct gs_swap_chain *swap, uint32_t *width, + uint32_t *height) +{ + xcb_connection_t *xcb_conn = + XGetXCBConnection(swap->device->plat->display); xcb_window_t window = swap->wi->window; - xcb_get_geometry_reply_t *geometry = get_window_geometry(xcb_conn, window); + xcb_get_geometry_reply_t *geometry = + get_window_geometry(xcb_conn, window); if (geometry) { - *width = geometry->width; + *width = geometry->width; *height = geometry->height; } @@ -533,16 +537,12 @@ extern void gl_update(gs_device_t *device) Display *display = device->plat->display; xcb_window_t window = device->cur_swap->wi->window; - uint32_t values[] = { - device->cur_swap->info.cx, - device->cur_swap->info.cy - }; + uint32_t values[] = {device->cur_swap->info.cx, + device->cur_swap->info.cy}; - xcb_configure_window( - XGetXCBConnection(display), window, - XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, - values - ); + xcb_configure_window(XGetXCBConnection(display), window, + XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, + values); } extern void device_load_swapchain(gs_device_t *device, gs_swapchain_t *swap) @@ -596,15 +596,21 @@ extern void device_present(gs_device_t *device) xcb_connection_t *xcb_conn = XGetXCBConnection(display); xcb_generic_event_t *xcb_event; - while((xcb_event = xcb_poll_for_event(xcb_conn))) { + while ((xcb_event = xcb_poll_for_event(xcb_conn))) { /* TODO: Handle XCB events. */ free(xcb_event); } switch (swap_type) { - case SWAP_TYPE_EXT: glXSwapIntervalEXT(display, window, 0); break; - case SWAP_TYPE_MESA: glXSwapIntervalMESA(0); break; - case SWAP_TYPE_SGI: glXSwapIntervalSGI(0); break; + case SWAP_TYPE_EXT: + glXSwapIntervalEXT(display, window, 0); + break; + case SWAP_TYPE_MESA: + glXSwapIntervalMESA(0); + break; + case SWAP_TYPE_SGI: + glXSwapIntervalSGI(0); + break; case SWAP_TYPE_NORMAL:; } diff --git a/libobs-opengl/gl-zstencil.c b/libobs-opengl/gl-zstencil.c index 0ab9333..65ffa7d 100644 --- a/libobs-opengl/gl-zstencil.c +++ b/libobs-opengl/gl-zstencil.c @@ -18,7 +18,7 @@ #include "gl-subsystem.h" static bool gl_init_zsbuffer(struct gs_zstencil_buffer *zs, uint32_t width, - uint32_t height) + uint32_t height) { glGenRenderbuffers(1, &zs->buffer); if (!gl_success("glGenRenderbuffers")) @@ -38,25 +38,31 @@ static bool gl_init_zsbuffer(struct gs_zstencil_buffer *zs, uint32_t width, static inline GLenum get_attachment(enum gs_zstencil_format format) { switch (format) { - case GS_Z16: return GL_DEPTH_ATTACHMENT; - case GS_Z24_S8: return GL_DEPTH_STENCIL_ATTACHMENT; - case GS_Z32F: return GL_DEPTH_ATTACHMENT; - case GS_Z32F_S8X24: return GL_DEPTH_STENCIL_ATTACHMENT; - case GS_ZS_NONE: return 0; + case GS_Z16: + return GL_DEPTH_ATTACHMENT; + case GS_Z24_S8: + return GL_DEPTH_STENCIL_ATTACHMENT; + case GS_Z32F: + return GL_DEPTH_ATTACHMENT; + case GS_Z32F_S8X24: + return GL_DEPTH_STENCIL_ATTACHMENT; + case GS_ZS_NONE: + return 0; } return 0; } gs_zstencil_t *device_zstencil_create(gs_device_t *device, uint32_t width, - uint32_t height, enum gs_zstencil_format format) + uint32_t height, + enum gs_zstencil_format format) { struct gs_zstencil_buffer *zs; zs = bzalloc(sizeof(struct gs_zstencil_buffer)); - zs->format = convert_zstencil_format(format); + zs->format = convert_zstencil_format(format); zs->attachment = get_attachment(format); - zs->device = device; + zs->device = device; if (!gl_init_zsbuffer(zs, width, height)) { blog(LOG_ERROR, "device_zstencil_create (GL) failed"); diff --git a/libobs/CMakeLists.txt b/libobs/CMakeLists.txt index fed3e69..8681148 100644 --- a/libobs/CMakeLists.txt +++ b/libobs/CMakeLists.txt @@ -454,7 +454,7 @@ if(UNIX AND NOT APPLE) set(PRIVATE_LIBS "${PRIVATE_LIBS} -l${LIB}") endforeach() CONFIGURE_FILE("libobs.pc.in" "libobs.pc" @ONLY) - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libobs.pc" DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig") + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libobs.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") endif() set_target_properties(libobs PROPERTIES diff --git a/libobs/audio-monitoring/osx/coreaudio-enum-devices.c b/libobs/audio-monitoring/osx/coreaudio-enum-devices.c index 8e6ea9e..0fe19e9 100644 --- a/libobs/audio-monitoring/osx/coreaudio-enum-devices.c +++ b/libobs/audio-monitoring/osx/coreaudio-enum-devices.c @@ -8,21 +8,20 @@ #include "mac-helpers.h" static bool obs_enum_audio_monitoring_device(obs_enum_audio_device_cb cb, - void *data, AudioDeviceID id, bool allow_inputs) + void *data, AudioDeviceID id, + bool allow_inputs) { - UInt32 size = 0; + UInt32 size = 0; CFStringRef cf_name = NULL; - CFStringRef cf_uid = NULL; - char *name = NULL; - char *uid = NULL; - OSStatus stat; - bool cont = true; + CFStringRef cf_uid = NULL; + char *name = NULL; + char *uid = NULL; + OSStatus stat; + bool cont = true; - AudioObjectPropertyAddress addr = { - kAudioDevicePropertyStreams, - kAudioDevicePropertyScopeOutput, - kAudioObjectPropertyElementMaster - }; + AudioObjectPropertyAddress addr = {kAudioDevicePropertyStreams, + kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster}; /* Check if the device is capable of audio output. */ AudioObjectGetPropertyDataSize(id, &addr, 0, NULL, &size); @@ -66,33 +65,31 @@ fail: } static void enum_audio_devices(obs_enum_audio_device_cb cb, void *data, - bool allow_inputs) + bool allow_inputs) { - AudioObjectPropertyAddress addr = { - kAudioHardwarePropertyDevices, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; + AudioObjectPropertyAddress addr = {kAudioHardwarePropertyDevices, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster}; - UInt32 size = 0; - UInt32 count; - OSStatus stat; + UInt32 size = 0; + UInt32 count; + OSStatus stat; AudioDeviceID *ids; stat = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &addr, - 0, NULL, &size); + 0, NULL, &size); if (!success(stat, "get data size")) return; - ids = malloc(size); + ids = malloc(size); count = size / sizeof(AudioDeviceID); - stat = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, - 0, NULL, &size, ids); + stat = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, 0, + NULL, &size, ids); if (success(stat, "get data")) { for (UInt32 i = 0; i < count; i++) { if (!obs_enum_audio_monitoring_device(cb, data, ids[i], - allow_inputs)) + allow_inputs)) break; } } @@ -119,21 +116,20 @@ static void get_default_id(char **p_id) AudioObjectPropertyAddress addr = { kAudioHardwarePropertyDefaultSystemOutputDevice, kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; + kAudioObjectPropertyElementMaster}; if (*p_id) return; - OSStatus stat; + OSStatus stat; AudioDeviceID id = 0; - UInt32 size = sizeof(id); + UInt32 size = sizeof(id); stat = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, 0, - NULL, &size, &id); + NULL, &size, &id); if (success(stat, "AudioObjectGetPropertyData")) obs_enum_audio_monitoring_device(alloc_default_id, p_id, id, - true); + true); if (!*p_id) *p_id = bzalloc(1); } diff --git a/libobs/audio-monitoring/osx/coreaudio-output.c b/libobs/audio-monitoring/osx/coreaudio-output.c index af2d7a0..93f6cf4 100644 --- a/libobs/audio-monitoring/osx/coreaudio-output.c +++ b/libobs/audio-monitoring/osx/coreaudio-output.c @@ -13,21 +13,21 @@ #include "mac-helpers.h" struct audio_monitor { - obs_source_t *source; - AudioQueueRef queue; - AudioQueueBufferRef buffers[3]; + obs_source_t *source; + AudioQueueRef queue; + AudioQueueBufferRef buffers[3]; - pthread_mutex_t mutex; - struct circlebuf empty_buffers; - struct circlebuf new_data; - audio_resampler_t *resampler; - size_t buffer_size; - size_t wait_size; - uint32_t channels; + pthread_mutex_t mutex; + struct circlebuf empty_buffers; + struct circlebuf new_data; + audio_resampler_t *resampler; + size_t buffer_size; + size_t wait_size; + uint32_t channels; - volatile bool active; - bool paused; - bool ignore; + volatile bool active; + bool paused; + bool ignore; }; static inline bool fill_buffer(struct audio_monitor *monitor) @@ -41,21 +41,21 @@ static inline bool fill_buffer(struct audio_monitor *monitor) circlebuf_pop_front(&monitor->empty_buffers, &buf, sizeof(buf)); circlebuf_pop_front(&monitor->new_data, buf->mAudioData, - monitor->buffer_size); + monitor->buffer_size); buf->mAudioDataByteSize = monitor->buffer_size; stat = AudioQueueEnqueueBuffer(monitor->queue, buf, 0, NULL); if (!success(stat, "AudioQueueEnqueueBuffer")) { blog(LOG_WARNING, "%s: %s", __FUNCTION__, - "Failed to enqueue buffer"); + "Failed to enqueue buffer"); AudioQueueStop(monitor->queue, false); } return true; } static void on_audio_playback(void *param, obs_source_t *source, - const struct audio_data *audio_data, bool muted) + const struct audio_data *audio_data, bool muted) { struct audio_monitor *monitor = param; float vol = source->user_volume; @@ -72,10 +72,10 @@ static void on_audio_playback(void *param, obs_source_t *source, uint64_t ts_offset; bool success; - success = audio_resampler_resample(monitor->resampler, resample_data, - &resample_frames, &ts_offset, - (const uint8_t *const *)audio_data->data, - (uint32_t)audio_data->frames); + success = audio_resampler_resample( + monitor->resampler, resample_data, &resample_frames, &ts_offset, + (const uint8_t *const *)audio_data->data, + (uint32_t)audio_data->frames); if (!success) { return; } @@ -87,9 +87,9 @@ static void on_audio_playback(void *param, obs_source_t *source, } else { /* apply volume */ if (!close_float(vol, 1.0f, EPSILON)) { - register float *cur = (float*)resample_data[0]; - register float *end = cur + - resample_frames * monitor->channels; + register float *cur = (float *)resample_data[0]; + register float *end = + cur + resample_frames * monitor->channels; while (cur < end) *(cur++) *= vol; @@ -141,10 +141,10 @@ static void buffer_audio(void *data, AudioQueueRef aq, AudioQueueBufferRef buf) extern bool devices_match(const char *id1, const char *id2); static bool audio_monitor_init(struct audio_monitor *monitor, - obs_source_t *source) + obs_source_t *source) { - const struct audio_output_info *info = audio_output_get_info( - obs->audio.audio); + const struct audio_output_info *info = + audio_output_get_info(obs->audio.audio); uint32_t channels = get_audio_channels(info->speakers); OSStatus stat; @@ -152,13 +152,12 @@ static bool audio_monitor_init(struct audio_monitor *monitor, .mSampleRate = (Float64)info->samples_per_sec, .mFormatID = kAudioFormatLinearPCM, .mFormatFlags = kAudioFormatFlagIsFloat | - kAudioFormatFlagIsPacked, + kAudioFormatFlagIsPacked, .mBytesPerPacket = sizeof(float) * channels, .mFramesPerPacket = 1, .mBytesPerFrame = sizeof(float) * channels, .mChannelsPerFrame = channels, - .mBitsPerChannel = sizeof(float) * 8 - }; + .mBitsPerChannel = sizeof(float) * 8}; monitor->source = source; @@ -187,20 +186,19 @@ static bool audio_monitor_init(struct audio_monitor *monitor, } stat = AudioQueueNewOutput(&desc, buffer_audio, monitor, NULL, NULL, 0, - &monitor->queue); + &monitor->queue); if (!success(stat, "AudioStreamBasicDescription")) { return false; } if (strcmp(uid, "default") != 0) { - CFStringRef cf_uid = CFStringCreateWithBytes(NULL, - (const UInt8*)uid, strlen(uid), - kCFStringEncodingUTF8, - false); + CFStringRef cf_uid = CFStringCreateWithBytes( + NULL, (const UInt8 *)uid, strlen(uid), + kCFStringEncodingUTF8, false); stat = AudioQueueSetProperty(monitor->queue, - kAudioQueueProperty_CurrentDevice, - &cf_uid, sizeof(cf_uid)); + kAudioQueueProperty_CurrentDevice, + &cf_uid, sizeof(cf_uid)); CFRelease(cf_uid); if (!success(stat, "set current device")) { @@ -208,45 +206,42 @@ static bool audio_monitor_init(struct audio_monitor *monitor, } } - stat = AudioQueueSetParameter(monitor->queue, - kAudioQueueParam_Volume, 1.0); + stat = AudioQueueSetParameter(monitor->queue, kAudioQueueParam_Volume, + 1.0); if (!success(stat, "set volume")) { return false; } for (size_t i = 0; i < 3; i++) { stat = AudioQueueAllocateBuffer(monitor->queue, - monitor->buffer_size, &monitor->buffers[i]); + monitor->buffer_size, + &monitor->buffers[i]); if (!success(stat, "allocation of buffer")) { return false; } circlebuf_push_back(&monitor->empty_buffers, - &monitor->buffers[i], - sizeof(monitor->buffers[i])); + &monitor->buffers[i], + sizeof(monitor->buffers[i])); } if (pthread_mutex_init(&monitor->mutex, NULL) != 0) { blog(LOG_WARNING, "%s: %s", __FUNCTION__, - "Failed to init mutex"); + "Failed to init mutex"); return false; } - struct resample_info from = { - .samples_per_sec = info->samples_per_sec, - .speakers = info->speakers, - .format = AUDIO_FORMAT_FLOAT_PLANAR - }; - struct resample_info to = { - .samples_per_sec = info->samples_per_sec, - .speakers = info->speakers, - .format = AUDIO_FORMAT_FLOAT - }; + struct resample_info from = {.samples_per_sec = info->samples_per_sec, + .speakers = info->speakers, + .format = AUDIO_FORMAT_FLOAT_PLANAR}; + struct resample_info to = {.samples_per_sec = info->samples_per_sec, + .speakers = info->speakers, + .format = AUDIO_FORMAT_FLOAT}; monitor->resampler = audio_resampler_create(&to, &from); if (!monitor->resampler) { blog(LOG_WARNING, "%s: %s", __FUNCTION__, - "Failed to create resampler"); + "Failed to create resampler"); return false; } @@ -263,7 +258,7 @@ static void audio_monitor_free(struct audio_monitor *monitor) { if (monitor->source) { obs_source_remove_audio_capture_callback( - monitor->source, on_audio_playback, monitor); + monitor->source, on_audio_playback, monitor); } if (monitor->active) { AudioQueueStop(monitor->queue, true); @@ -271,7 +266,7 @@ static void audio_monitor_free(struct audio_monitor *monitor) for (size_t i = 0; i < 3; i++) { if (monitor->buffers[i]) { AudioQueueFreeBuffer(monitor->queue, - monitor->buffers[i]); + monitor->buffers[i]); } } if (monitor->queue) { @@ -290,7 +285,7 @@ static void audio_monitor_init_final(struct audio_monitor *monitor) return; obs_source_add_audio_capture_callback(monitor->source, - on_audio_playback, monitor); + on_audio_playback, monitor); } struct audio_monitor *audio_monitor_create(obs_source_t *source) diff --git a/libobs/audio-monitoring/osx/mac-helpers.h b/libobs/audio-monitoring/osx/mac-helpers.h index f995990..a4d243f 100644 --- a/libobs/audio-monitoring/osx/mac-helpers.h +++ b/libobs/audio-monitoring/osx/mac-helpers.h @@ -3,13 +3,11 @@ static bool success_(OSStatus stat, const char *func, const char *call) { if (stat != noErr) { - blog(LOG_WARNING, "%s: %s failed: %d", - func, call, (int)stat); + blog(LOG_WARNING, "%s: %s failed: %d", func, call, (int)stat); return false; } return true; } -#define success(stat, call) \ - success_(stat, __FUNCTION__, call) +#define success(stat, call) success_(stat, __FUNCTION__, call) diff --git a/libobs/audio-monitoring/pulse/pulseaudio-enum-devices.c b/libobs/audio-monitoring/pulse/pulseaudio-enum-devices.c index f598829..d055b91 100644 --- a/libobs/audio-monitoring/pulse/pulseaudio-enum-devices.c +++ b/libobs/audio-monitoring/pulse/pulseaudio-enum-devices.c @@ -2,13 +2,13 @@ #include "pulseaudio-wrapper.h" static void pulseaudio_output_info(pa_context *c, const pa_source_info *i, - int eol, void *userdata) + int eol, void *userdata) { UNUSED_PARAMETER(c); if (eol != 0 || i->monitor_of_sink == PA_INVALID_INDEX) goto skip; - struct enum_cb *ecb = (struct enum_cb *) userdata; + struct enum_cb *ecb = (struct enum_cb *)userdata; if (ecb->cont) ecb->cont = ecb->cb(ecb->data, i->description, i->name); @@ -16,8 +16,7 @@ skip: pulseaudio_signal(0); } -void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb, - void *data) +void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb, void *data) { struct enum_cb *ecb = bzalloc(sizeof(struct enum_cb)); ecb->cb = cb; @@ -26,7 +25,7 @@ void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb, pulseaudio_init(); pa_source_info_cb_t pa_cb = pulseaudio_output_info; - pulseaudio_get_source_info_list(pa_cb, (void *) ecb); + pulseaudio_get_source_info_list(pa_cb, (void *)ecb); pulseaudio_unref(); bfree(ecb); diff --git a/libobs/audio-monitoring/pulse/pulseaudio-output.c b/libobs/audio-monitoring/pulse/pulseaudio-output.c index aa791d4..e30ccc7 100644 --- a/libobs/audio-monitoring/pulse/pulseaudio-output.c +++ b/libobs/audio-monitoring/pulse/pulseaudio-output.c @@ -5,47 +5,56 @@ #define blog(level, msg, ...) blog(level, "pulse-am: " msg, ##__VA_ARGS__) struct audio_monitor { - obs_source_t *source; - pa_stream *stream; - char *device; - pa_buffer_attr attr; - enum speaker_layout speakers; - pa_sample_format_t format; - uint_fast32_t samples_per_sec; - uint_fast32_t bytes_per_frame; - uint_fast8_t channels; + obs_source_t *source; + pa_stream *stream; + char *device; + pa_buffer_attr attr; + enum speaker_layout speakers; + pa_sample_format_t format; + uint_fast32_t samples_per_sec; + uint_fast32_t bytes_per_frame; + uint_fast8_t channels; - uint_fast32_t packets; - uint_fast64_t frames; + uint_fast32_t packets; + uint_fast64_t frames; - struct circlebuf new_data; - audio_resampler_t *resampler; - size_t buffer_size; - size_t bytesRemaining; - size_t bytes_per_channel; + struct circlebuf new_data; + audio_resampler_t *resampler; + size_t buffer_size; + size_t bytesRemaining; + size_t bytes_per_channel; - bool ignore; - pthread_mutex_t playback_mutex; + bool ignore; + pthread_mutex_t playback_mutex; }; -static enum speaker_layout pulseaudio_channels_to_obs_speakers( - uint_fast32_t channels) +static enum speaker_layout +pulseaudio_channels_to_obs_speakers(uint_fast32_t channels) { switch (channels) { - case 0: return SPEAKERS_UNKNOWN; - case 1: return SPEAKERS_MONO; - case 2: return SPEAKERS_STEREO; - case 3: return SPEAKERS_2POINT1; - case 4: return SPEAKERS_4POINT0; - case 5: return SPEAKERS_4POINT1; - case 6: return SPEAKERS_5POINT1; - case 8: return SPEAKERS_7POINT1; - default: return SPEAKERS_UNKNOWN; + case 0: + return SPEAKERS_UNKNOWN; + case 1: + return SPEAKERS_MONO; + case 2: + return SPEAKERS_STEREO; + case 3: + return SPEAKERS_2POINT1; + case 4: + return SPEAKERS_4POINT0; + case 5: + return SPEAKERS_4POINT1; + case 6: + return SPEAKERS_5POINT1; + case 8: + return SPEAKERS_7POINT1; + default: + return SPEAKERS_UNKNOWN; } } -static enum audio_format pulseaudio_to_obs_audio_format( - pa_sample_format_t format) +static enum audio_format +pulseaudio_to_obs_audio_format(pa_sample_format_t format) { switch (format) { case PA_SAMPLE_U8: @@ -118,7 +127,7 @@ static pa_channel_map pulseaudio_channel_map(enum speaker_layout layout) static void process_byte(void *p, size_t frames, size_t channels, float vol) { - register char *cur = (char *) p; + register char *cur = (char *)p; register char *end = cur + frames * channels; while (cur < end) @@ -127,7 +136,7 @@ static void process_byte(void *p, size_t frames, size_t channels, float vol) static void process_short(void *p, size_t frames, size_t channels, float vol) { - register short *cur = (short *) p; + register short *cur = (short *)p; register short *end = cur + frames * channels; while (cur < end) @@ -136,7 +145,7 @@ static void process_short(void *p, size_t frames, size_t channels, float vol) static void process_float(void *p, size_t frames, size_t channels, float vol) { - register float *cur = (float *) p; + register float *cur = (float *)p; register float *end = cur + frames * channels; while (cur < end) @@ -144,20 +153,20 @@ static void process_float(void *p, size_t frames, size_t channels, float vol) } void process_volume(const struct audio_monitor *monitor, float vol, - uint8_t *const *resample_data, uint32_t resample_frames) + uint8_t *const *resample_data, uint32_t resample_frames) { switch (monitor->bytes_per_channel) { case 1: process_byte(resample_data[0], resample_frames, - monitor->channels, vol); + monitor->channels, vol); break; case 2: process_short(resample_data[0], resample_frames, - monitor->channels, vol); + monitor->channels, vol); break; default: process_float(resample_data[0], resample_frames, - monitor->channels, vol); + monitor->channels, vol); break; } } @@ -168,20 +177,20 @@ static void do_stream_write(void *param) uint8_t *buffer = NULL; while (data->new_data.size >= data->buffer_size && - data->bytesRemaining > 0) { + data->bytesRemaining > 0) { size_t bytesToFill = data->buffer_size; if (bytesToFill > data->bytesRemaining) bytesToFill = data->bytesRemaining; - pa_stream_begin_write(data->stream, (void **) &buffer, - &bytesToFill); + pa_stream_begin_write(data->stream, (void **)&buffer, + &bytesToFill); circlebuf_pop_front(&data->new_data, buffer, bytesToFill); pulseaudio_lock(); - pa_stream_write(data->stream, buffer, bytesToFill, NULL, - 0LL, PA_SEEK_RELATIVE); + pa_stream_write(data->stream, buffer, bytesToFill, NULL, 0LL, + PA_SEEK_RELATIVE); pulseaudio_unlock(); data->bytesRemaining -= bytesToFill; @@ -189,7 +198,7 @@ static void do_stream_write(void *param) } static void on_audio_playback(void *param, obs_source_t *source, - const struct audio_data *audio_data, bool muted) + const struct audio_data *audio_data, bool muted) { struct audio_monitor *monitor = param; float vol = source->user_volume; @@ -206,10 +215,10 @@ static void on_audio_playback(void *param, obs_source_t *source, if (os_atomic_load_long(&source->activate_refs) == 0) goto unlock; - success = audio_resampler_resample(monitor->resampler, resample_data, - &resample_frames, &ts_offset, - (const uint8_t *const *) audio_data->data, - (uint32_t) audio_data->frames); + success = audio_resampler_resample( + monitor->resampler, resample_data, &resample_frames, &ts_offset, + (const uint8_t *const *)audio_data->data, + (uint32_t)audio_data->frames); if (!success) goto unlock; @@ -221,7 +230,7 @@ static void on_audio_playback(void *param, obs_source_t *source, } else { if (!close_float(vol, 1.0f, EPSILON)) { process_volume(monitor, vol, resample_data, - resample_frames); + resample_frames); } } @@ -262,19 +271,19 @@ static void pulseaudio_underflow(pa_stream *p, void *userdata) } static void pulseaudio_server_info(pa_context *c, const pa_server_info *i, - void *userdata) + void *userdata) { UNUSED_PARAMETER(c); UNUSED_PARAMETER(userdata); blog(LOG_INFO, "Server name: '%s %s'", i->server_name, - i->server_version); + i->server_version); pulseaudio_signal(0); } static void pulseaudio_source_info(pa_context *c, const pa_source_info *i, - int eol, void *userdata) + int eol, void *userdata) { UNUSED_PARAMETER(c); PULSE_DATA(userdata); @@ -287,29 +296,29 @@ static void pulseaudio_source_info(pa_context *c, const pa_source_info *i, if (eol > 0) goto skip; - blog(LOG_INFO, "Audio format: %s, %"PRIu32" Hz, %"PRIu8" channels", - pa_sample_format_to_string(i->sample_spec.format), - i->sample_spec.rate, i->sample_spec.channels); + blog(LOG_INFO, "Audio format: %s, %" PRIu32 " Hz, %" PRIu8 " channels", + pa_sample_format_to_string(i->sample_spec.format), + i->sample_spec.rate, i->sample_spec.channels); pa_sample_format_t format = i->sample_spec.format; if (pulseaudio_to_obs_audio_format(format) == AUDIO_FORMAT_UNKNOWN) { format = PA_SAMPLE_FLOAT32LE; - blog(LOG_INFO, "Sample format %s not supported by OBS," - "using %s instead for recording", - pa_sample_format_to_string( - i->sample_spec.format), - pa_sample_format_to_string(format)); + blog(LOG_INFO, + "Sample format %s not supported by OBS," + "using %s instead for recording", + pa_sample_format_to_string(i->sample_spec.format), + pa_sample_format_to_string(format)); } uint8_t channels = i->sample_spec.channels; if (pulseaudio_channels_to_obs_speakers(channels) == SPEAKERS_UNKNOWN) { channels = 2; - blog(LOG_INFO, "%c channels not supported by OBS," - "using %c instead for recording", - i->sample_spec.channels, - channels); + blog(LOG_INFO, + "%c channels not supported by OBS," + "using %c instead for recording", + i->sample_spec.channels, channels); } data->format = format; @@ -328,15 +337,16 @@ static void pulseaudio_stop_playback(struct audio_monitor *monitor) } blog(LOG_INFO, "Stopped Monitoring in '%s'", monitor->device); - blog(LOG_INFO, "Got %"PRIuFAST32" packets with %"PRIuFAST64" frames", - monitor->packets, monitor->frames); + blog(LOG_INFO, + "Got %" PRIuFAST32 " packets with %" PRIuFAST64 " frames", + monitor->packets, monitor->frames); monitor->packets = 0; monitor->frames = 0; } static bool audio_monitor_init(struct audio_monitor *monitor, - obs_source_t *source) + obs_source_t *source) { pthread_mutex_init_value(&monitor->playback_mutex); @@ -355,7 +365,7 @@ static bool audio_monitor_init(struct audio_monitor *monitor, if (match) { monitor->ignore = true; blog(LOG_INFO, "Prevented feedback-loop in '%s'", - s_dev_id); + s_dev_id); return true; } } @@ -371,25 +381,25 @@ static bool audio_monitor_init(struct audio_monitor *monitor, return false; if (pulseaudio_get_server_info(pulseaudio_server_info, - (void *) monitor) < 0) { + (void *)monitor) < 0) { blog(LOG_ERROR, "Unable to get server info !"); return false; } if (pulseaudio_get_source_info(pulseaudio_source_info, monitor->device, - (void *) monitor) < 0) { + (void *)monitor) < 0) { blog(LOG_ERROR, "Unable to get source info !"); return false; } if (monitor->format == PA_SAMPLE_INVALID) { blog(LOG_ERROR, - "An error occurred while getting the source info!"); + "An error occurred while getting the source info!"); return false; } pa_sample_spec spec; spec.format = monitor->format; - spec.rate = (uint32_t) monitor->samples_per_sec; + spec.rate = (uint32_t)monitor->samples_per_sec; spec.channels = monitor->channels; if (!pa_sample_spec_valid(&spec)) { @@ -397,31 +407,27 @@ static bool audio_monitor_init(struct audio_monitor *monitor, return false; } - const struct audio_output_info *info = audio_output_get_info( - obs->audio.audio); + const struct audio_output_info *info = + audio_output_get_info(obs->audio.audio); - struct resample_info from = { - .samples_per_sec = info->samples_per_sec, - .speakers = info->speakers, - .format = AUDIO_FORMAT_FLOAT_PLANAR - }; + struct resample_info from = {.samples_per_sec = info->samples_per_sec, + .speakers = info->speakers, + .format = AUDIO_FORMAT_FLOAT_PLANAR}; struct resample_info to = { - .samples_per_sec = (uint32_t) monitor->samples_per_sec, - .speakers = pulseaudio_channels_to_obs_speakers( - monitor->channels), - .format = pulseaudio_to_obs_audio_format - (monitor->format) - }; + .samples_per_sec = (uint32_t)monitor->samples_per_sec, + .speakers = + pulseaudio_channels_to_obs_speakers(monitor->channels), + .format = pulseaudio_to_obs_audio_format(monitor->format)}; monitor->resampler = audio_resampler_create(&to, &from); if (!monitor->resampler) { blog(LOG_WARNING, "%s: %s", __FUNCTION__, - "Failed to create resampler"); + "Failed to create resampler"); return false; } monitor->bytes_per_channel = get_audio_bytes_per_channel( - pulseaudio_to_obs_audio_format(monitor->format)); + pulseaudio_to_obs_audio_format(monitor->format)); monitor->speakers = pulseaudio_channels_to_obs_speakers(spec.channels); monitor->bytes_per_frame = pa_frame_size(&spec); @@ -434,26 +440,26 @@ static bool audio_monitor_init(struct audio_monitor *monitor, return false; } - monitor->attr.fragsize = (uint32_t) -1; - monitor->attr.maxlength = (uint32_t) -1; - monitor->attr.minreq = (uint32_t) -1; - monitor->attr.prebuf = (uint32_t) -1; + monitor->attr.fragsize = (uint32_t)-1; + monitor->attr.maxlength = (uint32_t)-1; + monitor->attr.minreq = (uint32_t)-1; + monitor->attr.prebuf = (uint32_t)-1; monitor->attr.tlength = pa_usec_to_bytes(25000, &spec); - monitor->buffer_size = monitor->bytes_per_frame * - pa_usec_to_bytes(5000, &spec); + monitor->buffer_size = + monitor->bytes_per_frame * pa_usec_to_bytes(5000, &spec); pa_stream_flags_t flags = PA_STREAM_INTERPOLATE_TIMING | - PA_STREAM_AUTO_TIMING_UPDATE; + PA_STREAM_AUTO_TIMING_UPDATE; if (pthread_mutex_init(&monitor->playback_mutex, NULL) != 0) { blog(LOG_WARNING, "%s: %s", __FUNCTION__, - "Failed to init mutex"); + "Failed to init mutex"); return false; } - int_fast32_t ret = pulseaudio_connect_playback(monitor->stream, - monitor->device, &monitor->attr, flags); + int_fast32_t ret = pulseaudio_connect_playback( + monitor->stream, monitor->device, &monitor->attr, flags); if (ret < 0) { pulseaudio_stop_playback(monitor); blog(LOG_ERROR, "Unable to connect to stream"); @@ -470,13 +476,13 @@ static void audio_monitor_init_final(struct audio_monitor *monitor) return; obs_source_add_audio_capture_callback(monitor->source, - on_audio_playback, monitor); + on_audio_playback, monitor); pulseaudio_write_callback(monitor->stream, pulseaudio_stream_write, - (void *) monitor); + (void *)monitor); pulseaudio_set_underflow_callback(monitor->stream, pulseaudio_underflow, - (void *) monitor); + (void *)monitor); } static inline void audio_monitor_free(struct audio_monitor *monitor) @@ -485,8 +491,8 @@ static inline void audio_monitor_free(struct audio_monitor *monitor) return; if (monitor->source) - obs_source_remove_audio_capture_callback(monitor->source, - on_audio_playback, monitor); + obs_source_remove_audio_capture_callback( + monitor->source, on_audio_playback, monitor); audio_resampler_destroy(monitor->resampler); circlebuf_free(&monitor->new_data); diff --git a/libobs/audio-monitoring/pulse/pulseaudio-wrapper.c b/libobs/audio-monitoring/pulse/pulseaudio-wrapper.c index 4bbbc9b..46ab365 100644 --- a/libobs/audio-monitoring/pulse/pulseaudio-wrapper.c +++ b/libobs/audio-monitoring/pulse/pulseaudio-wrapper.c @@ -32,11 +32,11 @@ static pa_threaded_mainloop *pulseaudio_mainloop = NULL; static pa_context *pulseaudio_context = NULL; static void pulseaudio_default_devices(pa_context *c, const pa_server_info *i, - void *userdata) + void *userdata) { UNUSED_PARAMETER(c); struct pulseaudio_default_output *d = - (struct pulseaudio_default_output *) userdata; + (struct pulseaudio_default_output *)userdata; d->default_sink_name = bstrdup(i->default_sink_name); pulseaudio_signal(0); } @@ -44,11 +44,10 @@ static void pulseaudio_default_devices(pa_context *c, const pa_server_info *i, void get_default_id(char **id) { pulseaudio_init(); - struct pulseaudio_default_output *pdo = bzalloc( - sizeof(struct pulseaudio_default_output)); + struct pulseaudio_default_output *pdo = + bzalloc(sizeof(struct pulseaudio_default_output)); pulseaudio_get_server_info( - (pa_server_info_cb_t) pulseaudio_default_devices, - (void *) pdo); + (pa_server_info_cb_t)pulseaudio_default_devices, (void *)pdo); *id = bzalloc(strlen(pdo->default_sink_name) + 9); strcat(*id, pdo->default_sink_name); strcat(*id, ".monitor"); @@ -118,14 +117,14 @@ static void pulseaudio_init_context() pa_proplist *p = pulseaudio_properties(); pulseaudio_context = pa_context_new_with_proplist( - pa_threaded_mainloop_get_api(pulseaudio_mainloop), - "OBS-Monitor", p); + pa_threaded_mainloop_get_api(pulseaudio_mainloop), + "OBS-Monitor", p); pa_context_set_state_callback(pulseaudio_context, - pulseaudio_context_state_changed, NULL); + pulseaudio_context_state_changed, NULL); pa_context_connect(pulseaudio_context, NULL, PA_CONTEXT_NOAUTOSPAWN, - NULL); + NULL); pa_proplist_free(p); pulseaudio_unlock(); @@ -217,15 +216,15 @@ void pulseaudio_accept() } int_fast32_t pulseaudio_get_source_info_list(pa_source_info_cb_t cb, - void *userdata) + void *userdata) { if (pulseaudio_context_ready() < 0) return -1; pulseaudio_lock(); - pa_operation *op = pa_context_get_source_info_list( - pulseaudio_context, cb, userdata); + pa_operation *op = pa_context_get_source_info_list(pulseaudio_context, + cb, userdata); if (!op) { pulseaudio_unlock(); return -1; @@ -240,7 +239,7 @@ int_fast32_t pulseaudio_get_source_info_list(pa_source_info_cb_t cb, } int_fast32_t pulseaudio_get_source_info(pa_source_info_cb_t cb, - const char *name, void *userdata) + const char *name, void *userdata) { if (pulseaudio_context_ready() < 0) return -1; @@ -248,7 +247,7 @@ int_fast32_t pulseaudio_get_source_info(pa_source_info_cb_t cb, pulseaudio_lock(); pa_operation *op = pa_context_get_source_info_by_name( - pulseaudio_context, name, cb, userdata); + pulseaudio_context, name, cb, userdata); if (!op) { pulseaudio_unlock(); return -1; @@ -269,8 +268,8 @@ int_fast32_t pulseaudio_get_server_info(pa_server_info_cb_t cb, void *userdata) pulseaudio_lock(); - pa_operation *op = pa_context_get_server_info( - pulseaudio_context, cb, userdata); + pa_operation *op = + pa_context_get_server_info(pulseaudio_context, cb, userdata); if (!op) { pulseaudio_unlock(); return -1; @@ -284,7 +283,7 @@ int_fast32_t pulseaudio_get_server_info(pa_server_info_cb_t cb, void *userdata) } pa_stream *pulseaudio_stream_new(const char *name, const pa_sample_spec *ss, - const pa_channel_map *map) + const pa_channel_map *map) { if (pulseaudio_context_ready() < 0) return NULL; @@ -292,8 +291,8 @@ pa_stream *pulseaudio_stream_new(const char *name, const pa_sample_spec *ss, pulseaudio_lock(); pa_proplist *p = pulseaudio_properties(); - pa_stream *s = pa_stream_new_with_proplist( - pulseaudio_context, name, ss, map, p); + pa_stream *s = pa_stream_new_with_proplist(pulseaudio_context, name, ss, + map, p); pa_proplist_free(p); pulseaudio_unlock(); @@ -301,7 +300,8 @@ pa_stream *pulseaudio_stream_new(const char *name, const pa_sample_spec *ss, } int_fast32_t pulseaudio_connect_playback(pa_stream *s, const char *name, - const pa_buffer_attr *attr, pa_stream_flags_t flags) + const pa_buffer_attr *attr, + pa_stream_flags_t flags) { if (pulseaudio_context_ready() < 0) return -1; @@ -311,8 +311,8 @@ int_fast32_t pulseaudio_connect_playback(pa_stream *s, const char *name, memcpy(device, name, dev_len); pulseaudio_lock(); - int_fast32_t ret = pa_stream_connect_playback(s, device, attr, flags, - NULL, NULL); + int_fast32_t ret = + pa_stream_connect_playback(s, device, attr, flags, NULL, NULL); pulseaudio_unlock(); bfree(device); @@ -320,7 +320,7 @@ int_fast32_t pulseaudio_connect_playback(pa_stream *s, const char *name, } void pulseaudio_write_callback(pa_stream *p, pa_stream_request_cb_t cb, - void *userdata) + void *userdata) { if (pulseaudio_context_ready() < 0) return; @@ -331,7 +331,7 @@ void pulseaudio_write_callback(pa_stream *p, pa_stream_request_cb_t cb, } void pulseaudio_set_underflow_callback(pa_stream *p, pa_stream_notify_cb_t cb, - void *userdata) + void *userdata) { if (pulseaudio_context_ready() < 0) return; diff --git a/libobs/audio-monitoring/pulse/pulseaudio-wrapper.h b/libobs/audio-monitoring/pulse/pulseaudio-wrapper.h index 4baaa92..971797d 100644 --- a/libobs/audio-monitoring/pulse/pulseaudio-wrapper.h +++ b/libobs/audio-monitoring/pulse/pulseaudio-wrapper.h @@ -107,7 +107,7 @@ void pulseaudio_accept(); * @warning call without active locks */ int_fast32_t pulseaudio_get_source_info_list(pa_source_info_cb_t cb, - void *userdata); + void *userdata); /** * Request source information from a specific source @@ -126,7 +126,7 @@ int_fast32_t pulseaudio_get_source_info_list(pa_source_info_cb_t cb, * @warning call without active locks */ int_fast32_t pulseaudio_get_source_info(pa_source_info_cb_t cb, - const char *name, void *userdata); + const char *name, void *userdata); /** * Request server information @@ -150,7 +150,7 @@ int_fast32_t pulseaudio_get_server_info(pa_server_info_cb_t cb, void *userdata); * @warning call without active locks */ pa_stream *pulseaudio_stream_new(const char *name, const pa_sample_spec *ss, - const pa_channel_map *map); + const pa_channel_map *map); /** * Connect to a pulseaudio playback stream @@ -162,7 +162,8 @@ pa_stream *pulseaudio_stream_new(const char *name, const pa_sample_spec *ss, * @return negative on error */ int_fast32_t pulseaudio_connect_playback(pa_stream *s, const char *name, - const pa_buffer_attr *attr, pa_stream_flags_t flags); + const pa_buffer_attr *attr, + pa_stream_flags_t flags); /** * Sets a callback function for when data can be written to the stream @@ -172,7 +173,7 @@ int_fast32_t pulseaudio_connect_playback(pa_stream *s, const char *name, * @param userdata pointer to userdata the callback will be called with */ void pulseaudio_write_callback(pa_stream *p, pa_stream_request_cb_t cb, - void *userdata); + void *userdata); /** * Sets a callback function for when an underflow happen @@ -182,4 +183,4 @@ void pulseaudio_write_callback(pa_stream *p, pa_stream_request_cb_t cb, * @param userdata pointer to userdata the callback will be called with */ void pulseaudio_set_underflow_callback(pa_stream *p, pa_stream_notify_cb_t cb, - void *userdata); + void *userdata); diff --git a/libobs/audio-monitoring/win32/wasapi-enum-devices.c b/libobs/audio-monitoring/win32/wasapi-enum-devices.c index 18b8094..9c10231 100644 --- a/libobs/audio-monitoring/win32/wasapi-enum-devices.c +++ b/libobs/audio-monitoring/win32/wasapi-enum-devices.c @@ -10,10 +10,22 @@ #undef DEFINE_PROPERTYKEY #endif #define DEFINE_PROPERTYKEY(id, a, b, c, d, e, f, g, h, i, j, k, l) \ - const PROPERTYKEY id = { { a,b,c, { d,e,f,g,h,i,j,k, } }, l }; -DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, \ - 0xa45c254e, 0xdf1c, 0x4efd, 0x80, \ - 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14); + const PROPERTYKEY id = {{a, \ + b, \ + c, \ + { \ + d, \ + e, \ + f, \ + g, \ + h, \ + i, \ + j, \ + k, \ + }}, \ + l}; +DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, + 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14); #else @@ -22,7 +34,7 @@ DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, \ #endif static bool get_device_info(obs_enum_audio_device_cb cb, void *data, - IMMDeviceCollection *collection, UINT idx) + IMMDeviceCollection *collection, UINT idx) { IPropertyStore *store = NULL; IMMDevice *device = NULL; @@ -50,7 +62,7 @@ static bool get_device_info(obs_enum_audio_device_cb cb, void *data, PropVariantInit(&name_var); hr = store->lpVtbl->GetValue(store, &PKEY_Device_FriendlyName, - &name_var); + &name_var); if (FAILED(hr)) { goto fail; } @@ -68,8 +80,7 @@ fail: return cont; } -void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb, - void *data) +void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb, void *data) { IMMDeviceEnumerator *enumerator = NULL; IMMDeviceCollection *collection = NULL; @@ -77,13 +88,13 @@ void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb, HRESULT hr; hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, - &IID_IMMDeviceEnumerator, &enumerator); + &IID_IMMDeviceEnumerator, &enumerator); if (FAILED(hr)) { goto fail; } - hr = enumerator->lpVtbl->EnumAudioEndpoints(enumerator, eRender, - DEVICE_STATE_ACTIVE, &collection); + hr = enumerator->lpVtbl->EnumAudioEndpoints( + enumerator, eRender, DEVICE_STATE_ACTIVE, &collection); if (FAILED(hr)) { goto fail; } @@ -115,13 +126,13 @@ static void get_default_id(char **p_id) return; hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, - &IID_IMMDeviceEnumerator, &immde); + &IID_IMMDeviceEnumerator, &immde); if (FAILED(hr)) { goto fail; } - hr = immde->lpVtbl->GetDefaultAudioEndpoint(immde, - eRender, eConsole, &device); + hr = immde->lpVtbl->GetDefaultAudioEndpoint(immde, eRender, eConsole, + &device); if (FAILED(hr)) { goto fail; } diff --git a/libobs/audio-monitoring/win32/wasapi-output.c b/libobs/audio-monitoring/win32/wasapi-output.c index c1eb506..d293f56 100644 --- a/libobs/audio-monitoring/win32/wasapi-output.c +++ b/libobs/audio-monitoring/win32/wasapi-output.c @@ -7,49 +7,45 @@ #include "wasapi-output.h" #define ACTUALLY_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - EXTERN_C const GUID DECLSPEC_SELECTANY name \ - = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } + EXTERN_C const GUID DECLSPEC_SELECTANY name = { \ + l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}} -ACTUALLY_DEFINE_GUID(CLSID_MMDeviceEnumerator, - 0xBCDE0395, 0xE52F, 0x467C, - 0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E); -ACTUALLY_DEFINE_GUID(IID_IMMDeviceEnumerator, - 0xA95664D2, 0x9614, 0x4F35, - 0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6); -ACTUALLY_DEFINE_GUID(IID_IAudioClient, - 0x1CB9AD4C, 0xDBFA, 0x4C32, - 0xB1, 0x78, 0xC2, 0xF5, 0x68, 0xA7, 0x03, 0xB2); -ACTUALLY_DEFINE_GUID(IID_IAudioRenderClient, - 0xF294ACFC, 0x3146, 0x4483, - 0xA7, 0xBF, 0xAD, 0xDC, 0xA7, 0xC2, 0x60, 0xE2); +ACTUALLY_DEFINE_GUID(CLSID_MMDeviceEnumerator, 0xBCDE0395, 0xE52F, 0x467C, 0x8E, + 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E); +ACTUALLY_DEFINE_GUID(IID_IMMDeviceEnumerator, 0xA95664D2, 0x9614, 0x4F35, 0xA7, + 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6); +ACTUALLY_DEFINE_GUID(IID_IAudioClient, 0x1CB9AD4C, 0xDBFA, 0x4C32, 0xB1, 0x78, + 0xC2, 0xF5, 0x68, 0xA7, 0x03, 0xB2); +ACTUALLY_DEFINE_GUID(IID_IAudioRenderClient, 0xF294ACFC, 0x3146, 0x4483, 0xA7, + 0xBF, 0xAD, 0xDC, 0xA7, 0xC2, 0x60, 0xE2); struct audio_monitor { - obs_source_t *source; - IMMDevice *device; - IAudioClient *client; + obs_source_t *source; + IMMDevice *device; + IAudioClient *client; IAudioRenderClient *render; - uint64_t last_recv_time; - uint64_t prev_video_ts; - uint64_t time_since_prev; - audio_resampler_t *resampler; - uint32_t sample_rate; - uint32_t channels; - bool source_has_video; - bool ignore; + uint64_t last_recv_time; + uint64_t prev_video_ts; + uint64_t time_since_prev; + audio_resampler_t *resampler; + uint32_t sample_rate; + uint32_t channels; + bool source_has_video; + bool ignore; - int64_t lowest_audio_offset; - struct circlebuf delay_buffer; - uint32_t delay_size; + int64_t lowest_audio_offset; + struct circlebuf delay_buffer; + uint32_t delay_size; - DARRAY(float) buf; - pthread_mutex_t playback_mutex; + DARRAY(float) buf; + pthread_mutex_t playback_mutex; }; /* #define DEBUG_AUDIO */ -static bool process_audio_delay(struct audio_monitor *monitor, - float **data, uint32_t *frames, uint64_t ts, uint32_t pad) +static bool process_audio_delay(struct audio_monitor *monitor, float **data, + uint32_t *frames, uint64_t ts, uint32_t pad) { obs_source_t *s = monitor->source; uint64_t last_frame_ts = s->last_frame_ts; @@ -68,15 +64,14 @@ static bool process_audio_delay(struct audio_monitor *monitor, circlebuf_push_back(&monitor->delay_buffer, &ts, sizeof(ts)); circlebuf_push_back(&monitor->delay_buffer, frames, sizeof(*frames)); - circlebuf_push_back(&monitor->delay_buffer, *data, - *frames * blocksize); + circlebuf_push_back(&monitor->delay_buffer, *data, *frames * blocksize); if (!monitor->prev_video_ts) { monitor->prev_video_ts = last_frame_ts; } else if (monitor->prev_video_ts == last_frame_ts) { - monitor->time_since_prev += (uint64_t)*frames * - 1000000000ULL / (uint64_t)monitor->sample_rate; + monitor->time_since_prev += (uint64_t)*frames * 1000000000ULL / + (uint64_t)monitor->sample_rate; } else { monitor->time_since_prev = 0; } @@ -86,44 +81,45 @@ static bool process_audio_delay(struct audio_monitor *monitor, bool bad_diff; circlebuf_peek_front(&monitor->delay_buffer, &cur_ts, - sizeof(ts)); - front_ts = cur_ts - - ((uint64_t)pad * 1000000000ULL / - (uint64_t)monitor->sample_rate); + sizeof(ts)); + front_ts = cur_ts - ((uint64_t)pad * 1000000000ULL / + (uint64_t)monitor->sample_rate); diff = (int64_t)front_ts - (int64_t)last_frame_ts; - bad_diff = !last_frame_ts || - llabs(diff) > 5000000000 || - monitor->time_since_prev > 100000000ULL; + bad_diff = !last_frame_ts || llabs(diff) > 5000000000 || + monitor->time_since_prev > 100000000ULL; /* delay audio if rushing */ if (!bad_diff && diff > 75000000) { #ifdef DEBUG_AUDIO - blog(LOG_INFO, "audio rushing, cutting audio, " - "diff: %lld, delay buffer size: %lu, " - "v: %llu: a: %llu", - diff, (int)monitor->delay_buffer.size, - last_frame_ts, front_ts); + blog(LOG_INFO, + "audio rushing, cutting audio, " + "diff: %lld, delay buffer size: %lu, " + "v: %llu: a: %llu", + diff, (int)monitor->delay_buffer.size, + last_frame_ts, front_ts); #endif return false; } circlebuf_pop_front(&monitor->delay_buffer, NULL, sizeof(ts)); circlebuf_pop_front(&monitor->delay_buffer, frames, - sizeof(*frames)); + sizeof(*frames)); size = *frames * blocksize; da_resize(monitor->buf, size); - circlebuf_pop_front(&monitor->delay_buffer, - monitor->buf.array, size); + circlebuf_pop_front(&monitor->delay_buffer, monitor->buf.array, + size); /* cut audio if dragging */ - if (!bad_diff && diff < -75000000 && monitor->delay_buffer.size > 0) { + if (!bad_diff && diff < -75000000 && + monitor->delay_buffer.size > 0) { #ifdef DEBUG_AUDIO - blog(LOG_INFO, "audio dragging, cutting audio, " - "diff: %lld, delay buffer size: %lu, " - "v: %llu: a: %llu", - diff, (int)monitor->delay_buffer.size, - last_frame_ts, front_ts); + blog(LOG_INFO, + "audio dragging, cutting audio, " + "diff: %lld, delay buffer size: %lu, " + "v: %llu: a: %llu", + diff, (int)monitor->delay_buffer.size, + last_frame_ts, front_ts); #endif continue; } @@ -136,7 +132,7 @@ static bool process_audio_delay(struct audio_monitor *monitor, } static void on_audio_playback(void *param, obs_source_t *source, - const struct audio_data *audio_data, bool muted) + const struct audio_data *audio_data, bool muted) { struct audio_monitor *monitor = param; IAudioRenderClient *render = monitor->render; @@ -154,10 +150,10 @@ static void on_audio_playback(void *param, obs_source_t *source, goto unlock; } - success = audio_resampler_resample(monitor->resampler, resample_data, - &resample_frames, &ts_offset, - (const uint8_t *const *)audio_data->data, - (uint32_t)audio_data->frames); + success = audio_resampler_resample( + monitor->resampler, resample_data, &resample_frames, &ts_offset, + (const uint8_t *const *)audio_data->data, + (uint32_t)audio_data->frames); if (!success) { goto unlock; } @@ -165,20 +161,20 @@ static void on_audio_playback(void *param, obs_source_t *source, UINT32 pad = 0; monitor->client->lpVtbl->GetCurrentPadding(monitor->client, &pad); - bool decouple_audio = - source->async_unbuffered && source->async_decoupled; + bool decouple_audio = source->async_unbuffered && + source->async_decoupled; if (monitor->source_has_video && !decouple_audio) { uint64_t ts = audio_data->timestamp - ts_offset; - if (!process_audio_delay(monitor, (float**)(&resample_data[0]), - &resample_frames, ts, pad)) { + if (!process_audio_delay(monitor, (float **)(&resample_data[0]), + &resample_frames, ts, pad)) { goto unlock; } } - HRESULT hr = render->lpVtbl->GetBuffer(render, resample_frames, - &output); + HRESULT hr = + render->lpVtbl->GetBuffer(render, resample_frames, &output); if (FAILED(hr)) { goto unlock; } @@ -186,20 +182,19 @@ static void on_audio_playback(void *param, obs_source_t *source, if (!muted) { /* apply volume */ if (!close_float(vol, 1.0f, EPSILON)) { - register float *cur = (float*)resample_data[0]; - register float *end = cur + - resample_frames * monitor->channels; + register float *cur = (float *)resample_data[0]; + register float *end = + cur + resample_frames * monitor->channels; while (cur < end) *(cur++) *= vol; } memcpy(output, resample_data[0], - resample_frames * monitor->channels * - sizeof(float)); + resample_frames * monitor->channels * sizeof(float)); } render->lpVtbl->ReleaseBuffer(render, resample_frames, - muted ? AUDCLNT_BUFFERFLAGS_SILENT : 0); + muted ? AUDCLNT_BUFFERFLAGS_SILENT : 0); unlock: pthread_mutex_unlock(&monitor->playback_mutex); @@ -212,7 +207,7 @@ static inline void audio_monitor_free(struct audio_monitor *monitor) if (monitor->source) { obs_source_remove_audio_capture_callback( - monitor->source, on_audio_playback, monitor); + monitor->source, on_audio_playback, monitor); } if (monitor->client) @@ -229,11 +224,16 @@ static inline void audio_monitor_free(struct audio_monitor *monitor) static enum speaker_layout convert_speaker_layout(DWORD layout, WORD channels) { switch (layout) { - case KSAUDIO_SPEAKER_2POINT1: return SPEAKERS_2POINT1; - case KSAUDIO_SPEAKER_SURROUND: return SPEAKERS_4POINT0; - case KSAUDIO_SPEAKER_4POINT1: return SPEAKERS_4POINT1; - case KSAUDIO_SPEAKER_5POINT1: return SPEAKERS_5POINT1; - case KSAUDIO_SPEAKER_7POINT1: return SPEAKERS_7POINT1; + case KSAUDIO_SPEAKER_2POINT1: + return SPEAKERS_2POINT1; + case KSAUDIO_SPEAKER_SURROUND: + return SPEAKERS_4POINT0; + case KSAUDIO_SPEAKER_4POINT1: + return SPEAKERS_4POINT1; + case KSAUDIO_SPEAKER_5POINT1: + return SPEAKERS_5POINT1; + case KSAUDIO_SPEAKER_7POINT1: + return SPEAKERS_7POINT1; } return (enum speaker_layout)channels; @@ -242,7 +242,7 @@ static enum speaker_layout convert_speaker_layout(DWORD layout, WORD channels) extern bool devices_match(const char *id1, const char *id2); static bool audio_monitor_init(struct audio_monitor *monitor, - obs_source_t *source) + obs_source_t *source) { IMMDeviceEnumerator *immde = NULL; WAVEFORMATEX *wfex = NULL; @@ -275,14 +275,14 @@ static bool audio_monitor_init(struct audio_monitor *monitor, * Init device */ hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, - &IID_IMMDeviceEnumerator, (void**)&immde); + &IID_IMMDeviceEnumerator, (void **)&immde); if (FAILED(hr)) { return false; } if (strcmp(id, "default") == 0) { - hr = immde->lpVtbl->GetDefaultAudioEndpoint(immde, - eRender, eConsole, &monitor->device); + hr = immde->lpVtbl->GetDefaultAudioEndpoint( + immde, eRender, eConsole, &monitor->device); } else { wchar_t w_id[512]; os_utf8_to_wcs(id, 0, w_id, 512); @@ -298,8 +298,8 @@ static bool audio_monitor_init(struct audio_monitor *monitor, * Init client */ hr = monitor->device->lpVtbl->Activate(monitor->device, - &IID_IAudioClient, CLSCTX_ALL, NULL, - (void**)&monitor->client); + &IID_IAudioClient, CLSCTX_ALL, + NULL, (void **)&monitor->client); if (FAILED(hr)) { goto fail; } @@ -310,8 +310,8 @@ static bool audio_monitor_init(struct audio_monitor *monitor, } hr = monitor->client->lpVtbl->Initialize(monitor->client, - AUDCLNT_SHAREMODE_SHARED, 0, - 10000000, 0, wfex, NULL); + AUDCLNT_SHAREMODE_SHARED, 0, + 10000000, 0, wfex, NULL); if (FAILED(hr)) { goto fail; } @@ -319,9 +319,9 @@ static bool audio_monitor_init(struct audio_monitor *monitor, /* ------------------------------------------ * * Init resampler */ - const struct audio_output_info *info = audio_output_get_info( - obs->audio.audio); - WAVEFORMATEXTENSIBLE *ext = (WAVEFORMATEXTENSIBLE*)wfex; + const struct audio_output_info *info = + audio_output_get_info(obs->audio.audio); + WAVEFORMATEXTENSIBLE *ext = (WAVEFORMATEXTENSIBLE *)wfex; struct resample_info from; struct resample_info to; @@ -330,8 +330,8 @@ static bool audio_monitor_init(struct audio_monitor *monitor, from.format = AUDIO_FORMAT_FLOAT_PLANAR; to.samples_per_sec = (uint32_t)wfex->nSamplesPerSec; - to.speakers = convert_speaker_layout(ext->dwChannelMask, - wfex->nChannels); + to.speakers = + convert_speaker_layout(ext->dwChannelMask, wfex->nChannels); to.format = AUDIO_FORMAT_FLOAT; monitor->sample_rate = (uint32_t)wfex->nSamplesPerSec; @@ -350,7 +350,8 @@ static bool audio_monitor_init(struct audio_monitor *monitor, } hr = monitor->client->lpVtbl->GetService(monitor->client, - &IID_IAudioRenderClient, (void**)&monitor->render); + &IID_IAudioRenderClient, + (void **)&monitor->render); if (FAILED(hr)) { goto fail; } @@ -381,7 +382,7 @@ static void audio_monitor_init_final(struct audio_monitor *monitor) monitor->source_has_video = (monitor->source->info.output_flags & OBS_SOURCE_VIDEO) != 0; obs_source_add_audio_capture_callback(monitor->source, - on_audio_playback, monitor); + on_audio_playback, monitor); } struct audio_monitor *audio_monitor_create(obs_source_t *source) diff --git a/libobs/audio-monitoring/win32/wasapi-output.h b/libobs/audio-monitoring/win32/wasapi-output.h index 8c42868..3eb559a 100644 --- a/libobs/audio-monitoring/win32/wasapi-output.h +++ b/libobs/audio-monitoring/win32/wasapi-output.h @@ -4,21 +4,21 @@ #include #include - #ifndef KSAUDIO_SPEAKER_2POINT1 -#define KSAUDIO_SPEAKER_2POINT1 (KSAUDIO_SPEAKER_STEREO|SPEAKER_LOW_FREQUENCY) +#define KSAUDIO_SPEAKER_2POINT1 (KSAUDIO_SPEAKER_STEREO | SPEAKER_LOW_FREQUENCY) #endif #define KSAUDIO_SPEAKER_SURROUND_AVUTIL \ - (KSAUDIO_SPEAKER_STEREO|SPEAKER_FRONT_CENTER) + (KSAUDIO_SPEAKER_STEREO | SPEAKER_FRONT_CENTER) #ifndef KSAUDIO_SPEAKER_4POINT1 -#define KSAUDIO_SPEAKER_4POINT1 (KSAUDIO_SPEAKER_SURROUND|SPEAKER_LOW_FREQUENCY) +#define KSAUDIO_SPEAKER_4POINT1 \ + (KSAUDIO_SPEAKER_SURROUND | SPEAKER_LOW_FREQUENCY) #endif -#define safe_release(ptr) \ - do { \ - if (ptr) { \ +#define safe_release(ptr) \ + do { \ + if (ptr) { \ ptr->lpVtbl->Release(ptr); \ - } \ + } \ } while (false) diff --git a/libobs/callback/calldata.c b/libobs/callback/calldata.c index 6fa0f62..53941d8 100644 --- a/libobs/callback/calldata.c +++ b/libobs/callback/calldata.c @@ -65,8 +65,7 @@ static inline const char *cd_serialize_string(uint8_t **pos) return (size != 0) ? str : NULL; } -static bool cd_getparam(const calldata_t *data, const char *name, - uint8_t **pos) +static bool cd_getparam(const calldata_t *data, const char *name, uint8_t **pos) { size_t name_size; @@ -97,7 +96,7 @@ static bool cd_getparam(const calldata_t *data, const char *name, static inline void cd_copy_string(uint8_t **pos, const char *str, size_t len) { if (!len) - len = strlen(str)+1; + len = strlen(str) + 1; memcpy(*pos, &len, sizeof(size_t)); *pos += sizeof(size_t); @@ -117,20 +116,20 @@ static inline void cd_copy_data(uint8_t **pos, const void *in, size_t size) } static inline void cd_set_first_param(calldata_t *data, const char *name, - const void *in, size_t size) + const void *in, size_t size) { uint8_t *pos; size_t capacity; - size_t name_len = strlen(name)+1; + size_t name_len = strlen(name) + 1; - capacity = sizeof(size_t)*3 + name_len + size; + capacity = sizeof(size_t) * 3 + name_len + size; data->size = capacity; if (capacity < 128) capacity = 128; data->capacity = capacity; - data->stack = bmalloc(capacity); + data->stack = bmalloc(capacity); pos = data->stack; cd_copy_string(&pos, name, name_len); @@ -139,7 +138,7 @@ static inline void cd_set_first_param(calldata_t *data, const char *name, } static inline bool cd_ensure_capacity(calldata_t *data, uint8_t **pos, - size_t new_size) + size_t new_size) { size_t offset; size_t new_capacity; @@ -157,7 +156,7 @@ static inline bool cd_ensure_capacity(calldata_t *data, uint8_t **pos, if (new_capacity < new_size) new_capacity = new_size; - data->stack = brealloc(data->stack, new_capacity); + data->stack = brealloc(data->stack, new_capacity); data->capacity = new_capacity; *pos = data->stack + offset; @@ -167,7 +166,7 @@ static inline bool cd_ensure_capacity(calldata_t *data, uint8_t **pos, /* ------------------------------------------------------------------------- */ bool calldata_get_data(const calldata_t *data, const char *name, void *out, - size_t size) + size_t size) { uint8_t *pos; size_t data_size; @@ -187,7 +186,7 @@ bool calldata_get_data(const calldata_t *data, const char *name, void *out, } void calldata_set_data(calldata_t *data, const char *name, const void *in, - size_t size) + size_t size) { uint8_t *pos = NULL; @@ -209,22 +208,22 @@ void calldata_set_data(calldata_t *data, const char *name, const void *in, if (!cd_ensure_capacity(data, &pos, bytes + offset)) return; - memmove(pos+offset, pos, bytes - (pos - data->stack)); + memmove(pos + offset, pos, bytes - (pos - data->stack)); data->size += offset; } else if (cur_size > size) { size_t offset = cur_size - size; size_t bytes = data->size - offset; - memmove(pos, pos+offset, bytes - (pos - data->stack)); + memmove(pos, pos + offset, bytes - (pos - data->stack)); data->size -= offset; } cd_copy_data(&pos, in, size); } else { - size_t name_len = strlen(name)+1; - size_t offset = name_len + size + sizeof(size_t)*2; + size_t name_len = strlen(name) + 1; + size_t offset = name_len + size + sizeof(size_t) * 2; if (!cd_ensure_capacity(data, &pos, data->size + offset)) return; data->size += offset; @@ -236,7 +235,7 @@ void calldata_set_data(calldata_t *data, const char *name, const void *in, } bool calldata_get_string(const calldata_t *data, const char *name, - const char **str) + const char **str) { uint8_t *pos; if (!data || !name || !*name) diff --git a/libobs/callback/calldata.h b/libobs/callback/calldata.h index 7acb8e8..90931d5 100644 --- a/libobs/callback/calldata.h +++ b/libobs/callback/calldata.h @@ -40,14 +40,14 @@ enum call_param_type { CALL_PARAM_TYPE_STRING }; -#define CALL_PARAM_IN (1<<0) -#define CALL_PARAM_OUT (1<<1) +#define CALL_PARAM_IN (1 << 0) +#define CALL_PARAM_OUT (1 << 1) struct calldata { uint8_t *stack; - size_t size; /* size of the stack, in bytes */ - size_t capacity; /* capacity of the stack, in bytes */ - bool fixed; /* fixed size (using call stack) */ + size_t size; /* size of the stack, in bytes */ + size_t capacity; /* capacity of the stack, in bytes */ + bool fixed; /* fixed size (using call stack) */ }; typedef struct calldata calldata_t; @@ -60,7 +60,7 @@ static inline void calldata_init(struct calldata *data) static inline void calldata_clear(struct calldata *data); static inline void calldata_init_fixed(struct calldata *data, uint8_t *stack, - size_t size) + size_t size) { data->stack = stack; data->capacity = size; @@ -76,9 +76,9 @@ static inline void calldata_free(struct calldata *data) } EXPORT bool calldata_get_data(const calldata_t *data, const char *name, - void *out, size_t size); + void *out, size_t size); EXPORT void calldata_set_data(calldata_t *data, const char *name, - const void *in, size_t new_size); + const void *in, size_t new_size); static inline void calldata_clear(struct calldata *data) { @@ -90,7 +90,7 @@ static inline void calldata_clear(struct calldata *data) static inline calldata_t *calldata_create(void) { - return (calldata_t*)bzalloc(sizeof(struct calldata)); + return (calldata_t *)bzalloc(sizeof(struct calldata)); } static inline void calldata_destroy(calldata_t *cd) @@ -104,31 +104,31 @@ static inline void calldata_destroy(calldata_t *cd) * same type. They return false otherwise. */ static inline bool calldata_get_int(const calldata_t *data, const char *name, - long long *val) + long long *val) { return calldata_get_data(data, name, val, sizeof(*val)); } -static inline bool calldata_get_float (const calldata_t *data, const char *name, - double *val) +static inline bool calldata_get_float(const calldata_t *data, const char *name, + double *val) { return calldata_get_data(data, name, val, sizeof(*val)); } -static inline bool calldata_get_bool (const calldata_t *data, const char *name, - bool *val) +static inline bool calldata_get_bool(const calldata_t *data, const char *name, + bool *val) { return calldata_get_data(data, name, val, sizeof(*val)); } -static inline bool calldata_get_ptr (const calldata_t *data, const char *name, - void *p_ptr) +static inline bool calldata_get_ptr(const calldata_t *data, const char *name, + void *p_ptr) { return calldata_get_data(data, name, p_ptr, sizeof(p_ptr)); } EXPORT bool calldata_get_string(const calldata_t *data, const char *name, - const char **str); + const char **str); /* ------------------------------------------------------------------------- */ /* call if you know your data is valid */ @@ -162,7 +162,7 @@ static inline void *calldata_ptr(const calldata_t *data, const char *name) } static inline const char *calldata_string(const calldata_t *data, - const char *name) + const char *name) { const char *val = NULL; calldata_get_string(data, name, &val); @@ -171,35 +171,35 @@ static inline const char *calldata_string(const calldata_t *data, /* ------------------------------------------------------------------------- */ -static inline void calldata_set_int (calldata_t *data, const char *name, - long long val) +static inline void calldata_set_int(calldata_t *data, const char *name, + long long val) { calldata_set_data(data, name, &val, sizeof(val)); } -static inline void calldata_set_float (calldata_t *data, const char *name, - double val) +static inline void calldata_set_float(calldata_t *data, const char *name, + double val) { calldata_set_data(data, name, &val, sizeof(val)); } -static inline void calldata_set_bool (calldata_t *data, const char *name, - bool val) +static inline void calldata_set_bool(calldata_t *data, const char *name, + bool val) { calldata_set_data(data, name, &val, sizeof(val)); } -static inline void calldata_set_ptr (calldata_t *data, const char *name, - void *ptr) +static inline void calldata_set_ptr(calldata_t *data, const char *name, + void *ptr) { calldata_set_data(data, name, &ptr, sizeof(ptr)); } static inline void calldata_set_string(calldata_t *data, const char *name, - const char *str) + const char *str) { if (str) - calldata_set_data(data, name, str, strlen(str)+1); + calldata_set_data(data, name, str, strlen(str) + 1); else calldata_set_data(data, name, NULL, 0); } diff --git a/libobs/callback/decl.c b/libobs/callback/decl.c index a7e2c94..1f78350 100644 --- a/libobs/callback/decl.c +++ b/libobs/callback/decl.c @@ -18,16 +18,16 @@ #include "decl.h" static inline void err_specifier_exists(struct cf_parser *cfp, - const char *storage) + const char *storage) { - cf_adderror(cfp, "'$1' specifier already exists", LEX_ERROR, - storage, NULL, NULL); + cf_adderror(cfp, "'$1' specifier already exists", LEX_ERROR, storage, + NULL, NULL); } static inline void err_reserved_name(struct cf_parser *cfp, const char *name) { - cf_adderror(cfp, "'$1' is a reserved name", LEX_ERROR, - name, NULL, NULL); + cf_adderror(cfp, "'$1' is a reserved name", LEX_ERROR, name, NULL, + NULL); } static inline void err_existing_name(struct cf_parser *cfp, const char *name) @@ -36,7 +36,7 @@ static inline void err_existing_name(struct cf_parser *cfp, const char *name) } static bool is_in_out_specifier(struct cf_parser *cfp, struct strref *name, - uint32_t *type) + uint32_t *type) { if (strref_cmp(name, "in") == 0) { if (*type & CALL_PARAM_IN) @@ -60,7 +60,7 @@ static bool is_in_out_specifier(struct cf_parser *cfp, struct strref *name, #define TYPE_OR_STORAGE "type or storage specifier" static bool get_type(struct strref *ref, enum call_param_type *type, - bool is_return) + bool is_return) { if (strref_cmp(ref, "int") == 0) *type = CALL_PARAM_TYPE_INT; @@ -82,12 +82,9 @@ static bool get_type(struct strref *ref, enum call_param_type *type, static bool is_reserved_name(const char *str) { - return (strcmp(str, "int") == 0) || - (strcmp(str, "float") == 0) || - (strcmp(str, "bool") == 0) || - (strcmp(str, "ptr") == 0) || - (strcmp(str, "string") == 0) || - (strcmp(str, "void") == 0) || + return (strcmp(str, "int") == 0) || (strcmp(str, "float") == 0) || + (strcmp(str, "bool") == 0) || (strcmp(str, "ptr") == 0) || + (strcmp(str, "string") == 0) || (strcmp(str, "void") == 0) || (strcmp(str, "return") == 0); } @@ -105,9 +102,9 @@ static bool name_exists(struct decl_info *decl, const char *name) static int parse_param(struct cf_parser *cfp, struct decl_info *decl) { - struct strref ref; - int code; - struct decl_param param = {0}; + struct strref ref; + int code; + struct decl_param param = {0}; /* get storage specifiers */ code = cf_next_name_ref(cfp, &ref, TYPE_OR_STORAGE, ","); @@ -180,7 +177,7 @@ static void print_errors(struct cf_parser *cfp, const char *decl_string) if (errors) { blog(LOG_WARNING, "Errors/warnings for '%s':\n\n%s", - decl_string, errors); + decl_string, errors); bfree(errors); } @@ -188,11 +185,11 @@ static void print_errors(struct cf_parser *cfp, const char *decl_string) bool parse_decl_string(struct decl_info *decl, const char *decl_string) { - struct cf_parser cfp; - struct strref ret_type; - struct decl_param ret_param = {0}; - int code; - bool success; + struct cf_parser cfp; + struct strref ret_type; + struct decl_param ret_param = {0}; + int code; + bool success; decl->decl_string = decl_string; ret_param.flags = CALL_PARAM_OUT; diff --git a/libobs/callback/decl.h b/libobs/callback/decl.h index 1e955dc..4e7a28c 100644 --- a/libobs/callback/decl.h +++ b/libobs/callback/decl.h @@ -24,9 +24,9 @@ extern "C" { #endif struct decl_param { - char *name; + char *name; enum call_param_type type; - uint32_t flags; + uint32_t flags; }; static inline void decl_param_free(struct decl_param *param) @@ -37,8 +37,8 @@ static inline void decl_param_free(struct decl_param *param) } struct decl_info { - char *name; - const char *decl_string; + char *name; + const char *decl_string; DARRAY(struct decl_param) params; }; @@ -46,7 +46,7 @@ static inline void decl_info_free(struct decl_info *decl) { if (decl) { for (size_t i = 0; i < decl->params.num; i++) - decl_param_free(decl->params.array+i); + decl_param_free(decl->params.array + i); da_free(decl->params); bfree(decl->name); diff --git a/libobs/callback/proc.c b/libobs/callback/proc.c index 9c0aca9..80b4537 100644 --- a/libobs/callback/proc.c +++ b/libobs/callback/proc.c @@ -20,8 +20,8 @@ #include "proc.h" struct proc_info { - struct decl_info func; - void *data; + struct decl_info func; + void *data; proc_handler_proc_t callback; }; @@ -46,39 +46,41 @@ void proc_handler_destroy(proc_handler_t *handler) { if (handler) { for (size_t i = 0; i < handler->procs.num; i++) - proc_info_free(handler->procs.array+i); + proc_info_free(handler->procs.array + i); da_free(handler->procs); bfree(handler); } } void proc_handler_add(proc_handler_t *handler, const char *decl_string, - proc_handler_proc_t proc, void *data) + proc_handler_proc_t proc, void *data) { - if (!handler) return; + if (!handler) + return; struct proc_info pi; memset(&pi, 0, sizeof(struct proc_info)); if (!parse_decl_string(&pi.func, decl_string)) { blog(LOG_ERROR, "Function declaration invalid: %s", - decl_string); + decl_string); return; } pi.callback = proc; - pi.data = data; + pi.data = data; da_push_back(handler->procs, &pi); } bool proc_handler_call(proc_handler_t *handler, const char *name, - calldata_t *params) + calldata_t *params) { - if (!handler) return false; + if (!handler) + return false; for (size_t i = 0; i < handler->procs.num; i++) { - struct proc_info *info = handler->procs.array+i; + struct proc_info *info = handler->procs.array + i; if (strcmp(info->func.name, name) == 0) { info->callback(info->data, params); diff --git a/libobs/callback/proc.h b/libobs/callback/proc.h index 7b66676..617df2e 100644 --- a/libobs/callback/proc.h +++ b/libobs/callback/proc.h @@ -34,20 +34,20 @@ extern "C" { struct proc_handler; typedef struct proc_handler proc_handler_t; -typedef void (*proc_handler_proc_t)(void*, calldata_t*); +typedef void (*proc_handler_proc_t)(void *, calldata_t *); EXPORT proc_handler_t *proc_handler_create(void); EXPORT void proc_handler_destroy(proc_handler_t *handler); EXPORT void proc_handler_add(proc_handler_t *handler, const char *decl_string, - proc_handler_proc_t proc, void *data); + proc_handler_proc_t proc, void *data); /** * Calls a function in a procedure handler. Returns false if the named * procedure is not found. */ EXPORT bool proc_handler_call(proc_handler_t *handler, const char *name, - calldata_t *params); + calldata_t *params); #ifdef __cplusplus } diff --git a/libobs/callback/signal.c b/libobs/callback/signal.c index d0f0a4d..37a0a39 100644 --- a/libobs/callback/signal.c +++ b/libobs/callback/signal.c @@ -22,18 +22,18 @@ struct signal_callback { signal_callback_t callback; - void *data; - bool remove; - bool keep_ref; + void *data; + bool remove; + bool keep_ref; }; struct signal_info { - struct decl_info func; + struct decl_info func; DARRAY(struct signal_callback) callbacks; - pthread_mutex_t mutex; - bool signalling; + pthread_mutex_t mutex; + bool signalling; - struct signal_info *next; + struct signal_info *next; }; static inline struct signal_info *signal_info_create(struct decl_info *info) @@ -48,8 +48,8 @@ static inline struct signal_info *signal_info_create(struct decl_info *info) si = bmalloc(sizeof(struct signal_info)); - si->func = *info; - si->next = NULL; + si->func = *info; + si->next = NULL; si->signalling = false; da_init(si->callbacks); @@ -75,10 +75,11 @@ static inline void signal_info_destroy(struct signal_info *si) } static inline size_t signal_get_callback_idx(struct signal_info *si, - signal_callback_t callback, void *data) + signal_callback_t callback, + void *data) { for (size_t i = 0; i < si->callbacks.num; i++) { - struct signal_callback *sc = si->callbacks.array+i; + struct signal_callback *sc = si->callbacks.array + i; if (sc->callback == callback && sc->data == data) return i; @@ -89,24 +90,25 @@ static inline size_t signal_get_callback_idx(struct signal_info *si, struct global_callback_info { global_signal_callback_t callback; - void *data; - long signaling; - bool remove; + void *data; + long signaling; + bool remove; }; struct signal_handler { struct signal_info *first; - pthread_mutex_t mutex; - volatile long refs; + pthread_mutex_t mutex; + volatile long refs; DARRAY(struct global_callback_info) global_callbacks; - pthread_mutex_t global_callbacks_mutex; + pthread_mutex_t global_callbacks_mutex; }; static struct signal_info *getsignal(signal_handler_t *handler, - const char *name, struct signal_info **p_last) + const char *name, + struct signal_info **p_last) { - struct signal_info *signal, *last= NULL; + struct signal_info *signal, *last = NULL; signal = handler->first; while (signal != NULL) { @@ -206,8 +208,9 @@ bool signal_handler_add(signal_handler_t *handler, const char *signal_decl) } static void signal_handler_connect_internal(signal_handler_t *handler, - const char *signal, signal_callback_t callback, void *data, - bool keep_ref) + const char *signal, + signal_callback_t callback, + void *data, bool keep_ref) { struct signal_info *sig, *last; struct signal_callback cb_data = {callback, data, false, keep_ref}; @@ -221,8 +224,10 @@ static void signal_handler_connect_internal(signal_handler_t *handler, pthread_mutex_unlock(&handler->mutex); if (!sig) { - blog(LOG_WARNING, "signal_handler_connect: " - "signal '%s' not found", signal); + blog(LOG_WARNING, + "signal_handler_connect: " + "signal '%s' not found", + signal); return; } @@ -241,19 +246,19 @@ static void signal_handler_connect_internal(signal_handler_t *handler, } void signal_handler_connect(signal_handler_t *handler, const char *signal, - signal_callback_t callback, void *data) + signal_callback_t callback, void *data) { signal_handler_connect_internal(handler, signal, callback, data, false); } void signal_handler_connect_ref(signal_handler_t *handler, const char *signal, - signal_callback_t callback, void *data) + signal_callback_t callback, void *data) { signal_handler_connect_internal(handler, signal, callback, data, true); } static inline struct signal_info *getsignal_locked(signal_handler_t *handler, - const char *name) + const char *name) { struct signal_info *sig; @@ -268,7 +273,7 @@ static inline struct signal_info *getsignal_locked(signal_handler_t *handler, } void signal_handler_disconnect(signal_handler_t *handler, const char *signal, - signal_callback_t callback, void *data) + signal_callback_t callback, void *data) { struct signal_info *sig = getsignal_locked(handler, signal); bool keep_ref = false; @@ -308,7 +313,7 @@ void signal_handler_remove_current(void) } void signal_handler_signal(signal_handler_t *handler, const char *signal, - calldata_t *params) + calldata_t *params) { struct signal_info *sig = getsignal_locked(handler, signal); long remove_refs = 0; @@ -320,7 +325,7 @@ void signal_handler_signal(signal_handler_t *handler, const char *signal, sig->signalling = true; for (size_t i = 0; i < sig->callbacks.num; i++) { - struct signal_callback *cb = sig->callbacks.array+i; + struct signal_callback *cb = sig->callbacks.array + i; if (!cb->remove) { current_signal_cb = cb; cb->callback(cb->data, params); @@ -329,12 +334,12 @@ void signal_handler_signal(signal_handler_t *handler, const char *signal, } for (size_t i = sig->callbacks.num; i > 0; i--) { - struct signal_callback *cb = sig->callbacks.array+i-1; + struct signal_callback *cb = sig->callbacks.array + i - 1; if (cb->remove) { if (cb->keep_ref) remove_refs++; - da_erase(sig->callbacks, i-1); + da_erase(sig->callbacks, i - 1); } } @@ -363,20 +368,21 @@ void signal_handler_signal(signal_handler_t *handler, const char *signal, if (cb->remove && !cb->signaling) da_erase(handler->global_callbacks, i - 1); - } + } } pthread_mutex_unlock(&handler->global_callbacks_mutex); if (remove_refs) { os_atomic_set_long(&handler->refs, - os_atomic_load_long(&handler->refs) - - remove_refs); + os_atomic_load_long(&handler->refs) - + remove_refs); } } void signal_handler_connect_global(signal_handler_t *handler, - global_signal_callback_t callback, void *data) + global_signal_callback_t callback, + void *data) { struct global_callback_info cb_data = {callback, data, 0, false}; size_t idx; @@ -394,7 +400,8 @@ void signal_handler_connect_global(signal_handler_t *handler, } void signal_handler_disconnect_global(signal_handler_t *handler, - global_signal_callback_t callback, void *data) + global_signal_callback_t callback, + void *data) { struct global_callback_info cb_data = {callback, data, false}; size_t idx; diff --git a/libobs/callback/signal.h b/libobs/callback/signal.h index e9f86f7..841aa49 100644 --- a/libobs/callback/signal.h +++ b/libobs/callback/signal.h @@ -33,17 +33,17 @@ extern "C" { struct signal_handler; typedef struct signal_handler signal_handler_t; -typedef void (*global_signal_callback_t)(void*, const char*, calldata_t*); -typedef void (*signal_callback_t)(void*, calldata_t*); +typedef void (*global_signal_callback_t)(void *, const char *, calldata_t *); +typedef void (*signal_callback_t)(void *, calldata_t *); EXPORT signal_handler_t *signal_handler_create(void); EXPORT void signal_handler_destroy(signal_handler_t *handler); EXPORT bool signal_handler_add(signal_handler_t *handler, - const char *signal_decl); + const char *signal_decl); static inline bool signal_handler_add_array(signal_handler_t *handler, - const char **signal_decls) + const char **signal_decls) { bool success = true; if (!signal_decls) @@ -57,21 +57,26 @@ static inline bool signal_handler_add_array(signal_handler_t *handler, } EXPORT void signal_handler_connect(signal_handler_t *handler, - const char *signal, signal_callback_t callback, void *data); + const char *signal, + signal_callback_t callback, void *data); EXPORT void signal_handler_connect_ref(signal_handler_t *handler, - const char *signal, signal_callback_t callback, void *data); + const char *signal, + signal_callback_t callback, void *data); EXPORT void signal_handler_disconnect(signal_handler_t *handler, - const char *signal, signal_callback_t callback, void *data); + const char *signal, + signal_callback_t callback, void *data); EXPORT void signal_handler_connect_global(signal_handler_t *handler, - global_signal_callback_t callback, void *data); + global_signal_callback_t callback, + void *data); EXPORT void signal_handler_disconnect_global(signal_handler_t *handler, - global_signal_callback_t callback, void *data); + global_signal_callback_t callback, + void *data); EXPORT void signal_handler_remove_current(void); EXPORT void signal_handler_signal(signal_handler_t *handler, const char *signal, - calldata_t *params); + calldata_t *params); #ifdef __cplusplus } diff --git a/libobs/data/area.effect b/libobs/data/area.effect index c9369f8..c007736 100644 --- a/libobs/data/area.effect +++ b/libobs/data/area.effect @@ -1,13 +1,29 @@ uniform float4x4 ViewProj; +uniform float2 base_dimension; uniform float2 base_dimension_i; uniform texture2d image; -struct VertInOut { +sampler_state textureSampler { + Filter = Linear; + AddressU = Clamp; + AddressV = Clamp; +}; + +struct VertData { float4 pos : POSITION; float2 uv : TEXCOORD0; }; -VertInOut VSDefault(VertInOut vert_in) +struct VertInOut { + float2 uv : TEXCOORD0; + float4 pos : POSITION; +}; + +struct FragData { + float2 uv : TEXCOORD0; +}; + +VertInOut VSDefault(VertData vert_in) { VertInOut vert_out; vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj); @@ -15,43 +31,97 @@ VertInOut VSDefault(VertInOut vert_in) return vert_out; } -float4 PSDrawAreaRGBA(VertInOut vert_in) : TARGET +float4 DrawArea(float2 uv) { - float4 totalcolor = float4(0.0, 0.0, 0.0, 0.0); - - float2 uv = vert_in.uv; - float2 uvdelta = float2(ddx(uv.x), ddy(uv.y)); + float2 uv_delta = float2(ddx(uv.x), ddy(uv.y)); // Handle potential OpenGL flip. - uvdelta.y = abs(uvdelta.y); + if (obs_glsl_compile) + uv_delta.y = abs(uv_delta.y); - float2 uvhalfdelta = 0.5 * uvdelta; - float2 uvmin = uv - uvhalfdelta; - float2 uvmax = uv + uvhalfdelta; + float2 uv_min = uv - 0.5 * uv_delta; + float2 uv_max = uv_min + uv_delta; - int2 loadindexmin = int2(uvmin / base_dimension_i); - int2 loadindexmax = int2(uvmax / base_dimension_i); + float2 load_index_begin = floor(uv_min * base_dimension); + float2 load_index_end = ceil(uv_max * base_dimension); - float2 targetpos = uv / uvdelta; - float2 targetposmin = targetpos - 0.5; - float2 targetposmax = targetpos + 0.5; - float2 scale = base_dimension_i / uvdelta; - for (int loadindexy = loadindexmin.y; loadindexy <= loadindexmax.y; ++loadindexy) - { - for (int loadindexx = loadindexmin.x; loadindexx <= loadindexmax.x; ++loadindexx) - { - int2 loadindex = int2(loadindexx, loadindexy); - float2 potentialtargetmin = float2(loadindex) * scale; - float2 potentialtargetmax = potentialtargetmin + scale; - float2 targetmin = max(potentialtargetmin, targetposmin); - float2 targetmax = min(potentialtargetmax, targetposmax); - float area = (targetmax.x - targetmin.x) * (targetmax.y - targetmin.y); - float4 sample = image.Load(int3(loadindex, 0)); - totalcolor += area * sample; - } - } + float2 target_dimension = 1.0 / uv_delta; + float2 target_pos = uv * target_dimension; + float2 target_pos_min = target_pos - 0.5; + float2 target_pos_max = target_pos + 0.5; + float2 scale = base_dimension_i * target_dimension; - return totalcolor; + float4 total_color = float4(0.0, 0.0, 0.0, 0.0); + + float load_index_y = load_index_begin.y; + do { + float source_y_min = load_index_y * scale.y; + float source_y_max = source_y_min + scale.y; + float y_min = max(source_y_min, target_pos_min.y); + float y_max = min(source_y_max, target_pos_max.y); + float height = y_max - y_min; + + float load_index_x = load_index_begin.x; + do { + float source_x_min = load_index_x * scale.x; + float source_x_max = source_x_min + scale.x; + float x_min = max(source_x_min, target_pos_min.x); + float x_max = min(source_x_max, target_pos_max.x); + float width = x_max - x_min; + float area = width * height; + + float4 color = image.Load(int3(load_index_x, load_index_y, 0)); + total_color += area * color; + + ++load_index_x; + } while (load_index_x < load_index_end.x); + + ++load_index_y; + } while (load_index_y < load_index_end.y); + + return total_color; +} + +float4 PSDrawAreaRGBA(FragData frag_in) : TARGET +{ + return DrawArea(frag_in.uv); +} + +float4 PSDrawAreaRGBADivide(FragData frag_in) : TARGET +{ + float4 rgba = DrawArea(frag_in.uv); + float alpha = rgba.a; + float multiplier = (alpha > 0.0) ? (1.0 / alpha) : 0.0; + return float4(rgba.rgb * multiplier, alpha); +} + +float4 PSDrawAreaRGBAUpscale(FragData frag_in) : TARGET +{ + float2 uv = frag_in.uv; + float2 uv_delta = float2(ddx(uv.x), ddy(uv.y)); + + // Handle potential OpenGL flip. + if (obs_glsl_compile) + uv_delta.y = abs(uv_delta.y); + + float2 uv_min = uv - 0.5 * uv_delta; + float2 uv_max = uv_min + uv_delta; + + float2 load_index_first = floor(uv_min * base_dimension); + float2 load_index_last = ceil(uv_max * base_dimension) - 1.0; + + if (load_index_first.x < load_index_last.x) { + float uv_boundary_x = load_index_last.x * base_dimension_i.x; + uv.x = ((uv.x - uv_boundary_x) / uv_delta.x) * base_dimension_i.x + uv_boundary_x; + } else + uv.x = (load_index_first.x + 0.5) * base_dimension_i.x; + if (load_index_first.y < load_index_last.y) { + float uv_boundary_y = load_index_last.y * base_dimension_i.y; + uv.y = ((uv.y - uv_boundary_y) / uv_delta.y) * base_dimension_i.y + uv_boundary_y; + } else + uv.y = (load_index_first.y + 0.5) * base_dimension_i.y; + + return image.Sample(textureSampler, uv); } technique Draw @@ -59,6 +129,24 @@ technique Draw pass { vertex_shader = VSDefault(vert_in); - pixel_shader = PSDrawAreaRGBA(vert_in); + pixel_shader = PSDrawAreaRGBA(frag_in); + } +} + +technique DrawAlphaDivide +{ + pass + { + vertex_shader = VSDefault(vert_in); + pixel_shader = PSDrawAreaRGBADivide(frag_in); + } +} + +technique DrawUpscale +{ + pass + { + vertex_shader = VSDefault(vert_in); + pixel_shader = PSDrawAreaRGBAUpscale(frag_in); } } diff --git a/libobs/data/bicubic_scale.effect b/libobs/data/bicubic_scale.effect index 0f55292..b6ba45a 100644 --- a/libobs/data/bicubic_scale.effect +++ b/libobs/data/bicubic_scale.effect @@ -6,7 +6,7 @@ uniform float4x4 ViewProj; uniform texture2d image; -uniform float4x4 color_matrix; +uniform float2 base_dimension; uniform float2 base_dimension_i; uniform float undistort_factor = 1.0; @@ -21,45 +21,31 @@ struct VertData { float2 uv : TEXCOORD0; }; -VertData VSDefault(VertData v_in) +struct VertOut { + float2 uv : TEXCOORD0; + float4 pos : POSITION; +}; + +struct FragData { + float2 uv : TEXCOORD0; +}; + +VertOut VSDefault(VertData v_in) { - VertData vert_out; + VertOut vert_out; + vert_out.uv = v_in.uv * base_dimension; vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj); - vert_out.uv = v_in.uv; return vert_out; } -float weight(float x) -{ - float ax = abs(x); - - /* Sharper version. May look better in some cases. */ - const float B = 0.0; - const float C = 0.75; - - if (ax < 1.0) - return (pow(x, 2.0) * - ((12.0 - 9.0 * B - 6.0 * C) * ax + - (-18.0 + 12.0 * B + 6.0 * C)) + - (6.0 - 2.0 * B)) - / 6.0; - else if ((ax >= 1.0) && (ax < 2.0)) - return (pow(x, 2.0) * - ((-B - 6.0 * C) * ax + (6.0 * B + 30.0 * C)) + - (-12.0 * B - 48.0 * C) * ax + - (8.0 * B + 24.0 * C)) - / 6.0; - else - return 0.0; -} - float4 weight4(float x) { + /* Sharper version. May look better in some cases. B=0, C=0.75 */ return float4( - weight(x - 2.0), - weight(x - 1.0), - weight(x), - weight(x + 1.0)); + ((-0.75 * x + 1.5) * x - 0.75) * x, + (1.25 * x - 2.25) * x * x + 1.0, + ((-1.25 * x + 1.5) * x + 0.75) * x, + (0.75 * x - 0.75) * x * x); } float AspectUndistortX(float x, float a) @@ -74,83 +60,94 @@ float AspectUndistortU(float u) return AspectUndistortX((u - 0.5) * 2.0, undistort_factor) * 0.5 + 0.5; } -float2 pixel_coord(float xpos, float ypos) +float2 undistort_coord(float xpos, float ypos) { return float2(AspectUndistortU(xpos), ypos); } -float4 pixel(float xpos, float ypos, bool undistort) +float4 undistort_pixel(float xpos, float ypos) { - if (undistort) - return image.Sample(textureSampler, pixel_coord(xpos, ypos)); - else - return image.Sample(textureSampler, float2(xpos, ypos)); + return image.Sample(textureSampler, undistort_coord(xpos, ypos)); } -float4 get_line(float ypos, float4 xpos, float4 linetaps, bool undistort) +float4 undistort_line(float4 xpos, float ypos, float4 rowtaps) { - return - pixel(xpos.r, ypos, undistort) * linetaps.r + - pixel(xpos.g, ypos, undistort) * linetaps.g + - pixel(xpos.b, ypos, undistort) * linetaps.b + - pixel(xpos.a, ypos, undistort) * linetaps.a; + return undistort_pixel(xpos.x, ypos) * rowtaps.x + + undistort_pixel(xpos.y, ypos) * rowtaps.y + + undistort_pixel(xpos.z, ypos) * rowtaps.z + + undistort_pixel(xpos.w, ypos) * rowtaps.w; } -float4 DrawBicubic(VertData v_in, bool undistort) +float4 DrawBicubic(FragData f_in, bool undistort) { - float2 stepxy = base_dimension_i; - float2 pos = v_in.uv + stepxy * 0.5; - float2 f = frac(pos / stepxy); + float2 pos = f_in.uv; + float2 pos1 = floor(pos - 0.5) + 0.5; + float2 f = pos - pos1; - float4 rowtaps = weight4(1.0 - f.x); - float4 coltaps = weight4(1.0 - f.y); + float4 rowtaps = weight4(f.x); + float4 coltaps = weight4(f.y); - /* make sure all taps added together is exactly 1.0, otherwise some - * (very small) distortion can occur */ - rowtaps /= rowtaps.r + rowtaps.g + rowtaps.b + rowtaps.a; - coltaps /= coltaps.r + coltaps.g + coltaps.b + coltaps.a; + float2 uv1 = pos1 * base_dimension_i; + float2 uv0 = uv1 - base_dimension_i; + float2 uv2 = uv1 + base_dimension_i; + float2 uv3 = uv2 + base_dimension_i; - float2 xystart = (-1.5 - f) * stepxy + pos; - float4 xpos = float4( - xystart.x, - xystart.x + stepxy.x, - xystart.x + stepxy.x * 2.0, - xystart.x + stepxy.x * 3.0 - ); + if (undistort) { + float4 xpos = float4(uv0.x, uv1.x, uv2.x, uv3.x); + return undistort_line(xpos, uv0.y, rowtaps) * coltaps.x + + undistort_line(xpos, uv1.y, rowtaps) * coltaps.y + + undistort_line(xpos, uv2.y, rowtaps) * coltaps.z + + undistort_line(xpos, uv3.y, rowtaps) * coltaps.w; + } - return - get_line(xystart.y , xpos, rowtaps, undistort) * coltaps.r + - get_line(xystart.y + stepxy.y , xpos, rowtaps, undistort) * coltaps.g + - get_line(xystart.y + stepxy.y * 2.0, xpos, rowtaps, undistort) * coltaps.b + - get_line(xystart.y + stepxy.y * 3.0, xpos, rowtaps, undistort) * coltaps.a; + float u_weight_sum = rowtaps.y + rowtaps.z; + float u_middle_offset = rowtaps.z * base_dimension_i.x / u_weight_sum; + float u_middle = uv1.x + u_middle_offset; + + float v_weight_sum = coltaps.y + coltaps.z; + float v_middle_offset = coltaps.z * base_dimension_i.y / v_weight_sum; + float v_middle = uv1.y + v_middle_offset; + + int2 coord_top_left = int2(max(uv0 * base_dimension, 0.5)); + int2 coord_bottom_right = int2(min(uv3 * base_dimension, base_dimension - 0.5)); + + float4 top = image.Load(int3(coord_top_left, 0)) * rowtaps.x; + top += image.Sample(textureSampler, float2(u_middle, uv0.y)) * u_weight_sum; + top += image.Load(int3(coord_bottom_right.x, coord_top_left.y, 0)) * rowtaps.w; + float4 total = top * coltaps.x; + + float4 middle = image.Sample(textureSampler, float2(uv0.x, v_middle)) * rowtaps.x; + middle += image.Sample(textureSampler, float2(u_middle, v_middle)) * u_weight_sum; + middle += image.Sample(textureSampler, float2(uv3.x, v_middle)) * rowtaps.w; + total += middle * v_weight_sum; + + float4 bottom = image.Load(int3(coord_top_left.x, coord_bottom_right.y, 0)) * rowtaps.x; + bottom += image.Sample(textureSampler, float2(u_middle, uv3.y)) * u_weight_sum; + bottom += image.Load(int3(coord_bottom_right, 0)) * rowtaps.w; + total += bottom * coltaps.w; + + return total; } -float4 PSDrawBicubicRGBA(VertData v_in, bool undistort) : TARGET +float4 PSDrawBicubicRGBA(FragData f_in, bool undistort) : TARGET { - return DrawBicubic(v_in, undistort); + return DrawBicubic(f_in, undistort); } -float4 PSDrawBicubicRGBADivide(VertData v_in) : TARGET +float4 PSDrawBicubicRGBADivide(FragData f_in) : TARGET { - float4 rgba = DrawBicubic(v_in, false); + float4 rgba = DrawBicubic(f_in, false); float alpha = rgba.a; float multiplier = (alpha > 0.0) ? (1.0 / alpha) : 0.0; return float4(rgba.rgb * multiplier, alpha); } -float4 PSDrawBicubicMatrix(VertData v_in) : TARGET -{ - float3 rgb = DrawBicubic(v_in, false).rgb; - float3 yuv = mul(float4(saturate(rgb), 1.0), color_matrix).xyz; - return float4(yuv, 1.0); -} - technique Draw { pass { vertex_shader = VSDefault(v_in); - pixel_shader = PSDrawBicubicRGBA(v_in, false); + pixel_shader = PSDrawBicubicRGBA(f_in, false); } } @@ -159,7 +156,7 @@ technique DrawAlphaDivide pass { vertex_shader = VSDefault(v_in); - pixel_shader = PSDrawBicubicRGBADivide(v_in); + pixel_shader = PSDrawBicubicRGBADivide(f_in); } } @@ -168,15 +165,6 @@ technique DrawUndistort pass { vertex_shader = VSDefault(v_in); - pixel_shader = PSDrawBicubicRGBA(v_in, true); - } -} - -technique DrawMatrix -{ - pass - { - vertex_shader = VSDefault(v_in); - pixel_shader = PSDrawBicubicMatrix(v_in); + pixel_shader = PSDrawBicubicRGBA(f_in, true); } } diff --git a/libobs/data/bilinear_lowres_scale.effect b/libobs/data/bilinear_lowres_scale.effect index e887072..7276239 100644 --- a/libobs/data/bilinear_lowres_scale.effect +++ b/libobs/data/bilinear_lowres_scale.effect @@ -1,12 +1,10 @@ /* - * bilinear low res scaling, samples 9 pixels of a larger image to scale to a + * bilinear low res scaling, samples 8 pixels of a larger image to scale to a * low resolution image below half size */ uniform float4x4 ViewProj; uniform texture2d image; -uniform float4x4 color_matrix; -uniform float2 base_dimension_i; sampler_state textureSampler { Filter = Linear; @@ -34,19 +32,24 @@ float4 pixel(float2 uv) float4 DrawLowresBilinear(VertData v_in) { - float2 stepxy = base_dimension_i; - float4 out_color; + float2 uv = v_in.uv; + float2 stepxy = float2(ddx(uv.x), ddy(uv.y)); + float2 stepxy1 = stepxy * 0.0625; + float2 stepxy3 = stepxy * 0.1875; + float2 stepxy5 = stepxy * 0.3125; + float2 stepxy7 = stepxy * 0.4375; - out_color = pixel(v_in.uv); - out_color += pixel(v_in.uv + float2(-stepxy.x, -stepxy.y)); - out_color += pixel(v_in.uv + float2(-stepxy.x, 0.0)); - out_color += pixel(v_in.uv + float2(-stepxy.x, stepxy.y)); - out_color += pixel(v_in.uv + float2( 0.0, -stepxy.y)); - out_color += pixel(v_in.uv + float2( 0.0, stepxy.y)); - out_color += pixel(v_in.uv + float2( stepxy.x, -stepxy.y)); - out_color += pixel(v_in.uv + float2( stepxy.x, 0.0)); - out_color += pixel(v_in.uv + float2( stepxy.x, stepxy.y)); - return out_color / float4(9.0, 9.0, 9.0, 9.0); + // Simulate Direct3D 8-sample pattern + float4 out_color; + out_color = pixel(uv + float2( stepxy1.x, -stepxy3.y)); + out_color += pixel(uv + float2(-stepxy1.x, stepxy3.y)); + out_color += pixel(uv + float2( stepxy5.x, stepxy1.y)); + out_color += pixel(uv + float2(-stepxy3.x, -stepxy5.y)); + out_color += pixel(uv + float2(-stepxy5.x, stepxy5.y)); + out_color += pixel(uv + float2(-stepxy7.x, -stepxy1.y)); + out_color += pixel(uv + float2( stepxy3.x, stepxy7.y)); + out_color += pixel(uv + float2( stepxy7.x, -stepxy7.y)); + return out_color * 0.125; } float4 PSDrawLowresBilinearRGBA(VertData v_in) : TARGET @@ -62,13 +65,6 @@ float4 PSDrawLowresBilinearRGBADivide(VertData v_in) : TARGET return float4(rgba.rgb * multiplier, alpha); } -float4 PSDrawLowresBilinearMatrix(VertData v_in) : TARGET -{ - float3 rgb = DrawLowresBilinear(v_in).rgb; - float3 yuv = mul(float4(saturate(rgb), 1.0), color_matrix).xyz; - return float4(yuv, 1.0); -} - technique Draw { pass @@ -87,12 +83,3 @@ technique DrawAlphaDivide } } -technique DrawMatrix -{ - pass - { - vertex_shader = VSDefault(v_in); - pixel_shader = PSDrawLowresBilinearMatrix(v_in); - } -} - diff --git a/libobs/data/default.effect b/libobs/data/default.effect index 54e07fa..ebc6a7c 100644 --- a/libobs/data/default.effect +++ b/libobs/data/default.effect @@ -1,5 +1,4 @@ uniform float4x4 ViewProj; -uniform float4x4 color_matrix; uniform texture2d image; sampler_state def_sampler { @@ -34,13 +33,6 @@ float4 PSDrawAlphaDivide(VertInOut vert_in) : TARGET return float4(rgba.rgb * multiplier, alpha); } -float4 PSDrawMatrix(VertInOut vert_in) : TARGET -{ - float3 rgb = image.Sample(def_sampler, vert_in.uv).rgb; - float3 yuv = mul(float4(rgb, 1.0), color_matrix).xyz; - return float4(yuv, 1.0); -} - technique Draw { pass @@ -58,12 +50,3 @@ technique DrawAlphaDivide pixel_shader = PSDrawAlphaDivide(vert_in); } } - -technique DrawMatrix -{ - pass - { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSDrawMatrix(vert_in); - } -} diff --git a/libobs/data/format_conversion.effect b/libobs/data/format_conversion.effect index b3d274e..2913cbd 100644 --- a/libobs/data/format_conversion.effect +++ b/libobs/data/format_conversion.effect @@ -15,38 +15,23 @@ along with this program. If not, see . ******************************************************************************/ -//#define DEBUGGING - -uniform float4x4 ViewProj; - -uniform float u_plane_offset; -uniform float v_plane_offset; - uniform float width; uniform float height; uniform float width_i; -uniform float height_i; uniform float width_d2; uniform float height_d2; -uniform float width_d2_i; -uniform float height_d2_i; -uniform float input_width; -uniform float input_height; -uniform float input_width_i; -uniform float input_height_i; -uniform float input_width_i_d2; -uniform float input_height_i_d2; +uniform float width_x2_i; -uniform int int_width; -uniform int int_input_width; -uniform int int_u_plane_offset; -uniform int int_v_plane_offset; - -uniform float4x4 color_matrix; +uniform float4 color_vec0; +uniform float4 color_vec1; +uniform float4 color_vec2; uniform float3 color_range_min = {0.0, 0.0, 0.0}; uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform texture2d image; +uniform texture2d image1; +uniform texture2d image2; +uniform texture2d image3; sampler_state def_sampler { Filter = Linear; @@ -54,354 +39,385 @@ sampler_state def_sampler { AddressV = Clamp; }; -struct VertInOut { +struct FragPos { float4 pos : POSITION; - float2 uv : TEXCOORD0; }; -VertInOut VSDefault(VertInOut vert_in) +struct VertTexPos { + float2 uv : TEXCOORD0; + float4 pos : POSITION; +}; + +struct VertPosWide { + float3 pos_wide : TEXCOORD0; + float4 pos : POSITION; +}; + +struct VertTexPosWide { + float3 uuv : TEXCOORD0; + float4 pos : POSITION; +}; + +struct FragTex { + float2 uv : TEXCOORD0; +}; + +struct FragPosWide { + float3 pos_wide : TEXCOORD0; +}; + +struct FragTexWide { + float3 uuv : TEXCOORD0; +}; + +FragPos VSPos(uint id : VERTEXID) { - VertInOut vert_out; - vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj); - vert_out.uv = vert_in.uv; + float idHigh = float(id >> 1); + float idLow = float(id & uint(1)); + + float x = idHigh * 4.0 - 1.0; + float y = idLow * 4.0 - 1.0; + + FragPos vert_out; + vert_out.pos = float4(x, y, 0.0, 1.0); return vert_out; } -/* used to prevent internal GPU precision issues width fmod in particular */ -#define PRECISION_OFFSET 0.2 - -float4 PSNV12(VertInOut vert_in) : TARGET +VertTexPosWide VSTexPos_Left(uint id : VERTEXID) { - float v_mul = floor(vert_in.uv.y * input_height); + float idHigh = float(id >> 1); + float idLow = float(id & uint(1)); - float byte_offset = floor((v_mul + vert_in.uv.x) * width) * 4.0; - byte_offset += PRECISION_OFFSET; + float x = idHigh * 4.0 - 1.0; + float y = idLow * 4.0 - 1.0; - float2 sample_pos[4]; + float u_right = idHigh * 2.0; + float u_left = u_right - width_i; + float v = obs_glsl_compile ? (idLow * 2.0) : (1.0 - idLow * 2.0); - if (byte_offset < u_plane_offset) { -#ifdef DEBUGGING - return float4(1.0, 1.0, 1.0, 1.0); -#endif - - float lum_u = floor(fmod(byte_offset, width)) * width_i; - float lum_v = floor(byte_offset * width_i) * height_i; - - /* move to texel centers to sample the 4 pixels properly */ - lum_u += width_i * 0.5; - lum_v += height_i * 0.5; - - sample_pos[0] = float2(lum_u, lum_v); - sample_pos[1] = float2(lum_u += width_i, lum_v); - sample_pos[2] = float2(lum_u += width_i, lum_v); - sample_pos[3] = float2(lum_u + width_i, lum_v); - - float4x4 out_val = float4x4( - image.Sample(def_sampler, sample_pos[0]), - image.Sample(def_sampler, sample_pos[1]), - image.Sample(def_sampler, sample_pos[2]), - image.Sample(def_sampler, sample_pos[3]) - ); - - return transpose(out_val)[1]; - } else { -#ifdef DEBUGGING - return float4(0.5, 0.2, 0.5, 0.2); -#endif - - float new_offset = byte_offset - u_plane_offset; - - float ch_u = floor(fmod(new_offset, width)) * width_i; - float ch_v = floor(new_offset * width_i) * height_d2_i; - float width_i2 = width_i*2.0; - - /* move to the borders of each set of 4 pixels to force it - * to do bilinear averaging */ - ch_u += width_i; - ch_v += height_i; - - sample_pos[0] = float2(ch_u, ch_v); - sample_pos[1] = float2(ch_u + width_i2, ch_v); - - return float4( - image.Sample(def_sampler, sample_pos[0]).rb, - image.Sample(def_sampler, sample_pos[1]).rb - ); - } + VertTexPosWide vert_out; + vert_out.uuv = float3(u_left, u_right, v); + vert_out.pos = float4(x, y, 0.0, 1.0); + return vert_out; } -float PSNV12_Y(VertInOut vert_in) : TARGET +VertTexPos VSTexPosHalf_Reverse(uint id : VERTEXID) { - return image.Sample(def_sampler, vert_in.uv.xy).y; + float idHigh = float(id >> 1); + float idLow = float(id & uint(1)); + + float x = idHigh * 4.0 - 1.0; + float y = idLow * 4.0 - 1.0; + + float u = idHigh * 2.0; + float v = obs_glsl_compile ? (idLow * 2.0) : (1.0 - idLow * 2.0); + + VertTexPos vert_out; + vert_out.uv = float2(width_d2 * u, height * v); + vert_out.pos = float4(x, y, 0.0, 1.0); + return vert_out; } -float2 PSNV12_UV(VertInOut vert_in) : TARGET +VertTexPos VSTexPosHalfHalf_Reverse(uint id : VERTEXID) { - return image.Sample(def_sampler, vert_in.uv.xy).xz; + float idHigh = float(id >> 1); + float idLow = float(id & uint(1)); + + float x = idHigh * 4.0 - 1.0; + float y = idLow * 4.0 - 1.0; + + float u = idHigh * 2.0; + float v = obs_glsl_compile ? (idLow * 2.0) : (1.0 - idLow * 2.0); + + VertTexPos vert_out; + vert_out.uv = float2(width_d2 * u, height_d2 * v); + vert_out.pos = float4(x, y, 0.0, 1.0); + return vert_out; } -float4 PSPlanar420(VertInOut vert_in) : TARGET +VertPosWide VSPosWide_Reverse(uint id : VERTEXID) { - float v_mul = floor(vert_in.uv.y * input_height); + float idHigh = float(id >> 1); + float idLow = float(id & uint(1)); - float byte_offset = floor((v_mul + vert_in.uv.x) * width) * 4.0; - byte_offset += PRECISION_OFFSET; + float x = idHigh * 4.0 - 1.0; + float y = idLow * 4.0 - 1.0; - float2 sample_pos[4]; + float u = idHigh * 2.0; + float v = obs_glsl_compile ? (idLow * 2.0) : (1.0 - idLow * 2.0); - if (byte_offset < u_plane_offset) { -#ifdef DEBUGGING - return float4(1.0, 1.0, 1.0, 1.0); -#endif - - float lum_u = floor(fmod(byte_offset, width)) * width_i; - float lum_v = floor(byte_offset * width_i) * height_i; - - /* move to texel centers to sample the 4 pixels properly */ - lum_u += width_i * 0.5; - lum_v += height_i * 0.5; - - sample_pos[0] = float2(lum_u, lum_v); - sample_pos[1] = float2(lum_u += width_i, lum_v); - sample_pos[2] = float2(lum_u += width_i, lum_v); - sample_pos[3] = float2(lum_u + width_i, lum_v); - - } else { -#ifdef DEBUGGING - return ((byte_offset < v_plane_offset) ? - float4(0.5, 0.5, 0.5, 0.5) : - float4(0.2, 0.2, 0.2, 0.2)); -#endif - - float new_offset = byte_offset - - ((byte_offset < v_plane_offset) ? - u_plane_offset : v_plane_offset); - - float ch_u = floor(fmod(new_offset, width_d2)) * width_d2_i; - float ch_v = floor(new_offset * width_d2_i) * height_d2_i; - float width_i2 = width_i*2.0; - - /* move to the borders of each set of 4 pixels to force it - * to do bilinear averaging */ - ch_u += width_i; - ch_v += height_i; - - /* set up coordinates for next chroma line, in case - * (width / 2) % 4 == 2, i.e. the current set of 4 pixels is split - * between the current and the next chroma line; do note that the next - * chroma line is two source lines below the current source line */ - float ch_u_n = 0. + width_i; - float ch_v_n = ch_v + height_i * 3; - - sample_pos[0] = float2(ch_u, ch_v); - sample_pos[1] = float2(ch_u += width_i2, ch_v); - - ch_u += width_i2; - // check if ch_u overflowed the current source and chroma line - if (ch_u > 1.0) { - sample_pos[2] = float2(ch_u_n, ch_v_n); - sample_pos[2] = float2(ch_u_n + width_i2, ch_v_n); - } else { - sample_pos[2] = float2(ch_u, ch_v); - sample_pos[3] = float2(ch_u + width_i2, ch_v); - } - } - - float4x4 out_val = float4x4( - image.Sample(def_sampler, sample_pos[0]), - image.Sample(def_sampler, sample_pos[1]), - image.Sample(def_sampler, sample_pos[2]), - image.Sample(def_sampler, sample_pos[3]) - ); - - out_val = transpose(out_val); - - if (byte_offset < u_plane_offset) - return out_val[1]; - else if (byte_offset < v_plane_offset) - return out_val[0]; - else - return out_val[2]; + VertPosWide vert_out; + vert_out.pos_wide = float3(float2(width, width_d2) * u, height * v); + vert_out.pos = float4(x, y, 0.0, 1.0); + return vert_out; } -float4 PSPlanar444(VertInOut vert_in) : TARGET +float PS_Y(FragPos frag_in) : TARGET { - float v_mul = floor(vert_in.uv.y * input_height); - - float byte_offset = floor((v_mul + vert_in.uv.x) * width) * 4.0; - byte_offset += PRECISION_OFFSET; - - float new_byte_offset = byte_offset; - - if (byte_offset >= v_plane_offset) - new_byte_offset -= v_plane_offset; - else if (byte_offset >= u_plane_offset) - new_byte_offset -= u_plane_offset; - - float2 sample_pos[4]; - - float u_val = floor(fmod(new_byte_offset, width)) * width_i; - float v_val = floor(new_byte_offset * width_i) * height_i; - - /* move to texel centers to sample the 4 pixels properly */ - u_val += width_i * 0.5; - v_val += height_i * 0.5; - - sample_pos[0] = float2(u_val, v_val); - sample_pos[1] = float2(u_val += width_i, v_val); - sample_pos[2] = float2(u_val += width_i, v_val); - sample_pos[3] = float2(u_val + width_i, v_val); - - float4x4 out_val = float4x4( - image.Sample(def_sampler, sample_pos[0]), - image.Sample(def_sampler, sample_pos[1]), - image.Sample(def_sampler, sample_pos[2]), - image.Sample(def_sampler, sample_pos[3]) - ); - - out_val = transpose(out_val); - - if (byte_offset < u_plane_offset) - return out_val[1]; - else if (byte_offset < v_plane_offset) - return out_val[0]; - else - return out_val[2]; + float3 rgb = image.Load(int3(frag_in.pos.xy, 0)).rgb; + float y = dot(color_vec0.xyz, rgb) + color_vec0.w; + return y; } -float GetIntOffsetColor(int offset) +float2 PS_UV_Wide(FragTexWide frag_in) : TARGET { - return image.Load(int3(offset % int_input_width, - offset / int_input_width, - 0)).r; + float3 rgb_left = image.Sample(def_sampler, frag_in.uuv.xz).rgb; + float3 rgb_right = image.Sample(def_sampler, frag_in.uuv.yz).rgb; + float3 rgb = (rgb_left + rgb_right) * 0.5; + float u = dot(color_vec1.xyz, rgb) + color_vec1.w; + float v = dot(color_vec2.xyz, rgb) + color_vec2.w; + return float2(u, v); } -float4 PSPacked422_Reverse(VertInOut vert_in, int u_pos, int v_pos, - int y0_pos, int y1_pos) : TARGET +float PS_U(FragPos frag_in) : TARGET { - float y = vert_in.uv.y; - float odd = floor(fmod(width * vert_in.uv.x + PRECISION_OFFSET, 2.0)); - float x = floor(width_d2 * vert_in.uv.x + PRECISION_OFFSET) * - width_d2_i; + float3 rgb = image.Load(int3(frag_in.pos.xy, 0)).rgb; + float u = dot(color_vec1.xyz, rgb) + color_vec1.w; + return u; +} - x += input_width_i_d2; +float PS_V(FragPos frag_in) : TARGET +{ + float3 rgb = image.Load(int3(frag_in.pos.xy, 0)).rgb; + float v = dot(color_vec2.xyz, rgb) + color_vec2.w; + return v; +} - float4 texel = image.Sample(def_sampler, float2(x, y)); - float3 yuv = float3(odd > 0.5 ? texel[y1_pos] : texel[y0_pos], - texel[u_pos], texel[v_pos]); +float PS_U_Wide(FragTexWide frag_in) : TARGET +{ + float3 rgb_left = image.Sample(def_sampler, frag_in.uuv.xz).rgb; + float3 rgb_right = image.Sample(def_sampler, frag_in.uuv.yz).rgb; + float3 rgb = (rgb_left + rgb_right) * 0.5; + float u = dot(color_vec1.xyz, rgb) + color_vec1.w; + return u; +} + +float PS_V_Wide(FragTexWide frag_in) : TARGET +{ + float3 rgb_left = image.Sample(def_sampler, frag_in.uuv.xz).rgb; + float3 rgb_right = image.Sample(def_sampler, frag_in.uuv.yz).rgb; + float3 rgb = (rgb_left + rgb_right) * 0.5; + float v = dot(color_vec2.xyz, rgb) + color_vec2.w; + return v; +} + +float3 YUV_to_RGB(float3 yuv) +{ yuv = clamp(yuv, color_range_min, color_range_max); - return saturate(mul(float4(yuv, 1.0), color_matrix)); + float r = dot(color_vec0.xyz, yuv) + color_vec0.w; + float g = dot(color_vec1.xyz, yuv) + color_vec1.w; + float b = dot(color_vec2.xyz, yuv) + color_vec2.w; + return float3(r, g, b); } -float4 PSPlanar420_Reverse(VertInOut vert_in) : TARGET +float3 PSUYVY_Reverse(FragTex frag_in) : TARGET { - int x = int(vert_in.uv.x * width + PRECISION_OFFSET); - int y = int(vert_in.uv.y * height + PRECISION_OFFSET); - - int lum_offset = y * int_width + x; - int chroma_offset = (y / 2) * (int_width / 2) + x / 2; - int chroma1 = int_u_plane_offset + chroma_offset; - int chroma2 = int_v_plane_offset + chroma_offset; - - float3 yuv = float3( - GetIntOffsetColor(lum_offset), - GetIntOffsetColor(chroma1), - GetIntOffsetColor(chroma2) - ); - yuv = clamp(yuv, color_range_min, color_range_max); - return saturate(mul(float4(yuv, 1.0), color_matrix)); + float4 y2uv = image.Load(int3(frag_in.uv.xy, 0)); + float2 y01 = y2uv.yw; + float2 cbcr = y2uv.zx; + float leftover = frac(frag_in.uv.x); + float y = (leftover < 0.5) ? y01.x : y01.y; + float3 yuv = float3(y, cbcr); + float3 rgb = YUV_to_RGB(yuv); + return rgb; } -float4 PSPlanar444_Reverse(VertInOut vert_in) : TARGET +float3 PSYUY2_Reverse(FragTex frag_in) : TARGET { - int x = int(vert_in.uv.x * width + PRECISION_OFFSET); - int y = int(vert_in.uv.y * height + PRECISION_OFFSET); - - int lum_offset = y * int_width + x; - int chroma_offset = y * int_width + x; - int chroma1 = int_u_plane_offset + chroma_offset; - int chroma2 = int_v_plane_offset + chroma_offset; - - float3 yuv = float3( - GetIntOffsetColor(lum_offset), - GetIntOffsetColor(chroma1), - GetIntOffsetColor(chroma2) - ); - yuv = clamp(yuv, color_range_min, color_range_max); - return saturate(mul(float4(yuv, 1.0), color_matrix)); + float4 y2uv = image.Load(int3(frag_in.uv.xy, 0)); + float2 y01 = y2uv.zx; + float2 cbcr = y2uv.yw; + float leftover = frac(frag_in.uv.x); + float y = (leftover < 0.5) ? y01.x : y01.y; + float3 yuv = float3(y, cbcr); + float3 rgb = YUV_to_RGB(yuv); + return rgb; } -float4 PSNV12_Reverse(VertInOut vert_in) : TARGET +float3 PSYVYU_Reverse(FragTex frag_in) : TARGET { - int x = int(vert_in.uv.x * width + PRECISION_OFFSET); - int y = int(vert_in.uv.y * height + PRECISION_OFFSET); - - int lum_offset = y * int_width + x; - int chroma_offset = (y / 2) * (int_width / 2) + x / 2; - int chroma = int_u_plane_offset + chroma_offset * 2; - - float3 yuv = float3( - GetIntOffsetColor(lum_offset), - GetIntOffsetColor(chroma), - GetIntOffsetColor(chroma + 1) - ); - yuv = clamp(yuv, color_range_min, color_range_max); - return saturate(mul(float4(yuv, 1.0), color_matrix)); + float4 y2uv = image.Load(int3(frag_in.uv.xy, 0)); + float2 y01 = y2uv.zx; + float2 cbcr = y2uv.wy; + float leftover = frac(frag_in.uv.x); + float y = (leftover < 0.5) ? y01.x : y01.y; + float3 yuv = float3(y, cbcr); + float3 rgb = YUV_to_RGB(yuv); + return rgb; } -float4 PSY800_Limited(VertInOut vert_in) : TARGET +float3 PSPlanar420_Reverse(VertTexPos frag_in) : TARGET { - int x = int(vert_in.uv.x * width + PRECISION_OFFSET); - int y = int(vert_in.uv.y * height + PRECISION_OFFSET); - - float limited = image.Load(int3(x, y, 0)).x; - float full = saturate((limited - (16.0 / 255.0)) * (255.0 / 219.0)); - return float4(full, full, full, 1.0); + float y = image.Load(int3(frag_in.pos.xy, 0)).x; + int3 xy0_chroma = int3(frag_in.uv, 0); + float cb = image1.Load(xy0_chroma).x; + float cr = image2.Load(xy0_chroma).x; + float3 yuv = float3(y, cb, cr); + float3 rgb = YUV_to_RGB(yuv); + return rgb; } -float4 PSY800_Full(VertInOut vert_in) : TARGET +float4 PSPlanar420A_Reverse(VertTexPos frag_in) : TARGET { - int x = int(vert_in.uv.x * width + PRECISION_OFFSET); - int y = int(vert_in.uv.y * height + PRECISION_OFFSET); - - float3 full = image.Load(int3(x, y, 0)).xxx; - return float4(full, 1.0); -} - -float4 PSRGB_Limited(VertInOut vert_in) : TARGET -{ - int x = int(vert_in.uv.x * width + PRECISION_OFFSET); - int y = int(vert_in.uv.y * height + PRECISION_OFFSET); - - float4 rgba = image.Load(int3(x, y, 0)); - rgba.rgb = saturate((rgba.rgb - (16.0 / 255.0)) * (255.0 / 219.0)); + int3 xy0_luma = int3(frag_in.pos.xy, 0); + float y = image.Load(xy0_luma).x; + int3 xy0_chroma = int3(frag_in.uv, 0); + float cb = image1.Load(xy0_chroma).x; + float cr = image2.Load(xy0_chroma).x; + float alpha = image3.Load(xy0_luma).x; + float3 yuv = float3(y, cb, cr); + float4 rgba = float4(YUV_to_RGB(yuv), alpha); return rgba; } -technique Planar420 +float3 PSPlanar422_Reverse(FragPosWide frag_in) : TARGET +{ + float y = image.Load(int3(frag_in.pos_wide.xz, 0)).x; + int3 xy0_chroma = int3(frag_in.pos_wide.yz, 0); + float cb = image1.Load(xy0_chroma).x; + float cr = image2.Load(xy0_chroma).x; + float3 yuv = float3(y, cb, cr); + float3 rgb = YUV_to_RGB(yuv); + return rgb; +} + +float4 PSPlanar422A_Reverse(FragPosWide frag_in) : TARGET +{ + int3 xy0_luma = int3(frag_in.pos_wide.xz, 0); + float y = image.Load(xy0_luma).x; + int3 xy0_chroma = int3(frag_in.pos_wide.yz, 0); + float cb = image1.Load(xy0_chroma).x; + float cr = image2.Load(xy0_chroma).x; + float alpha = image3.Load(xy0_luma).x; + float3 yuv = float3(y, cb, cr); + float4 rgba = float4(YUV_to_RGB(yuv), alpha); + return rgba; +} + +float3 PSPlanar444_Reverse(FragPos frag_in) : TARGET +{ + int3 xy0 = int3(frag_in.pos.xy, 0); + float y = image.Load(xy0).x; + float cb = image1.Load(xy0).x; + float cr = image2.Load(xy0).x; + float3 yuv = float3(y, cb, cr); + float3 rgb = YUV_to_RGB(yuv); + return rgb; +} + +float4 PSPlanar444A_Reverse(FragPos frag_in) : TARGET +{ + int3 xy0 = int3(frag_in.pos.xy, 0); + float y = image.Load(xy0).x; + float cb = image1.Load(xy0).x; + float cr = image2.Load(xy0).x; + float alpha = image3.Load(xy0).x; + float3 yuv = float3(y, cb, cr); + float4 rgba = float4(YUV_to_RGB(yuv), alpha); + return rgba; +} + +float4 PSAYUV_Reverse(FragPos frag_in) : TARGET +{ + float4 yuva = image.Load(int3(frag_in.pos.xy, 0)); + float4 rgba = float4(YUV_to_RGB(yuva.xyz), yuva.a); + return rgba; +} + +float3 PSNV12_Reverse(VertTexPos frag_in) : TARGET +{ + float y = image.Load(int3(frag_in.pos.xy, 0)).x; + float2 cbcr = image1.Load(int3(frag_in.uv, 0)).xy; + float3 yuv = float3(y, cbcr); + float3 rgb = YUV_to_RGB(yuv); + return rgb; +} + +float3 PSY800_Limited(FragPos frag_in) : TARGET +{ + float limited = image.Load(int3(frag_in.pos.xy, 0)).x; + float full = (255.0 / 219.0) * limited - (16.0 / 219.0); + return float3(full, full, full); +} + +float3 PSY800_Full(FragPos frag_in) : TARGET +{ + float3 full = image.Load(int3(frag_in.pos.xy, 0)).xxx; + return full; +} + +float4 PSRGB_Limited(FragPos frag_in) : TARGET +{ + float4 rgba = image.Load(int3(frag_in.pos.xy, 0)); + rgba.rgb = (255.0 / 219.0) * rgba.rgb - (16.0 / 219.0); + return rgba; +} + +float3 PSBGR3_Limited(FragPos frag_in) : TARGET +{ + float x = frag_in.pos.x * 3.0; + float y = frag_in.pos.y; + float b = image.Load(int3(x - 1.0, y, 0)).x; + float g = image.Load(int3(x, y, 0)).x; + float r = image.Load(int3(x + 1.0, y, 0)).x; + float3 rgb = float3(r, g, b); + rgb = (255.0 / 219.0) * rgb - (16.0 / 219.0); + return rgb; +} + +float3 PSBGR3_Full(FragPos frag_in) : TARGET +{ + float x = frag_in.pos.x * 3.0; + float y = frag_in.pos.y; + float b = image.Load(int3(x - 1.0, y, 0)).x; + float g = image.Load(int3(x, y, 0)).x; + float r = image.Load(int3(x + 1.0, y, 0)).x; + float3 rgb = float3(r, g, b); + return rgb; +} + +technique Planar_Y { pass { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSPlanar420(vert_in); + vertex_shader = VSPos(id); + pixel_shader = PS_Y(frag_in); } } -technique Planar444 +technique Planar_U { pass { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSPlanar444(vert_in); + vertex_shader = VSPos(id); + pixel_shader = PS_U(frag_in); } } -technique NV12 +technique Planar_V { pass { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSNV12(vert_in); + vertex_shader = VSPos(id); + pixel_shader = PS_V(frag_in); + } +} + +technique Planar_U_Left +{ + pass + { + vertex_shader = VSTexPos_Left(id); + pixel_shader = PS_U_Wide(frag_in); + } +} + +technique Planar_V_Left +{ + pass + { + vertex_shader = VSTexPos_Left(id); + pixel_shader = PS_V_Wide(frag_in); } } @@ -409,8 +425,8 @@ technique NV12_Y { pass { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSNV12_Y(vert_in); + vertex_shader = VSPos(id); + pixel_shader = PS_Y(frag_in); } } @@ -418,8 +434,8 @@ technique NV12_UV { pass { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSNV12_UV(vert_in); + vertex_shader = VSTexPos_Left(id); + pixel_shader = PS_UV_Wide(frag_in); } } @@ -427,8 +443,8 @@ technique UYVY_Reverse { pass { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSPacked422_Reverse(vert_in, 2, 0, 1, 3); + vertex_shader = VSTexPosHalf_Reverse(id); + pixel_shader = PSUYVY_Reverse(frag_in); } } @@ -436,8 +452,8 @@ technique YUY2_Reverse { pass { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSPacked422_Reverse(vert_in, 1, 3, 2, 0); + vertex_shader = VSTexPosHalf_Reverse(id); + pixel_shader = PSYUY2_Reverse(frag_in); } } @@ -445,8 +461,8 @@ technique YVYU_Reverse { pass { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSPacked422_Reverse(vert_in, 3, 1, 2, 0); + vertex_shader = VSTexPosHalf_Reverse(id); + pixel_shader = PSYVYU_Reverse(frag_in); } } @@ -454,8 +470,35 @@ technique I420_Reverse { pass { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSPlanar420_Reverse(vert_in); + vertex_shader = VSTexPosHalfHalf_Reverse(id); + pixel_shader = PSPlanar420_Reverse(frag_in); + } +} + +technique I40A_Reverse +{ + pass + { + vertex_shader = VSTexPosHalfHalf_Reverse(id); + pixel_shader = PSPlanar420A_Reverse(frag_in); + } +} + +technique I422_Reverse +{ + pass + { + vertex_shader = VSPosWide_Reverse(id); + pixel_shader = PSPlanar422_Reverse(frag_in); + } +} + +technique I42A_Reverse +{ + pass + { + vertex_shader = VSPosWide_Reverse(id); + pixel_shader = PSPlanar422A_Reverse(frag_in); } } @@ -463,8 +506,26 @@ technique I444_Reverse { pass { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSPlanar444_Reverse(vert_in); + vertex_shader = VSPos(id); + pixel_shader = PSPlanar444_Reverse(frag_in); + } +} + +technique YUVA_Reverse +{ + pass + { + vertex_shader = VSPos(id); + pixel_shader = PSPlanar444A_Reverse(frag_in); + } +} + +technique AYUV_Reverse +{ + pass + { + vertex_shader = VSPos(id); + pixel_shader = PSAYUV_Reverse(frag_in); } } @@ -472,8 +533,8 @@ technique NV12_Reverse { pass { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSNV12_Reverse(vert_in); + vertex_shader = VSTexPosHalfHalf_Reverse(id); + pixel_shader = PSNV12_Reverse(frag_in); } } @@ -481,8 +542,8 @@ technique Y800_Limited { pass { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSY800_Limited(vert_in); + vertex_shader = VSPos(id); + pixel_shader = PSY800_Limited(frag_in); } } @@ -490,8 +551,8 @@ technique Y800_Full { pass { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSY800_Full(vert_in); + vertex_shader = VSPos(id); + pixel_shader = PSY800_Full(frag_in); } } @@ -499,7 +560,25 @@ technique RGB_Limited { pass { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSRGB_Limited(vert_in); + vertex_shader = VSPos(id); + pixel_shader = PSRGB_Limited(frag_in); + } +} + +technique BGR3_Limited +{ + pass + { + vertex_shader = VSPos(id); + pixel_shader = PSBGR3_Limited(frag_in); + } +} + +technique BGR3_Full +{ + pass + { + vertex_shader = VSPos(id); + pixel_shader = PSBGR3_Full(frag_in); } } diff --git a/libobs/data/lanczos_scale.effect b/libobs/data/lanczos_scale.effect index 061acc4..33a31f3 100644 --- a/libobs/data/lanczos_scale.effect +++ b/libobs/data/lanczos_scale.effect @@ -6,7 +6,7 @@ uniform float4x4 ViewProj; uniform texture2d image; -uniform float4x4 color_matrix; +uniform float2 base_dimension; uniform float2 base_dimension_i; uniform float undistort_factor = 1.0; @@ -22,45 +22,46 @@ struct VertData { float2 uv : TEXCOORD0; }; -struct FragData { +struct VertOut { + float2 uv : TEXCOORD0; float4 pos : POSITION; - float2 uv : TEXCOORD0; - float2 scale : TEXCOORD1; }; -FragData VSDefault(VertData v_in) +struct FragData { + float2 uv : TEXCOORD0; +}; + +VertOut VSDefault(VertData v_in) { - FragData vert_out; + VertOut vert_out; + vert_out.uv = v_in.uv * base_dimension; vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj); - vert_out.uv = v_in.uv; - vert_out.scale = min(0.25 + abs(0.75 / mul(float4(1.0 / base_dimension_i.xy, 1.0, 1.0), ViewProj).xy), 1.0); return vert_out; } -float sinc(float x) +float weight(float x) { - const float PIval = 3.1415926535897932384626433832795; - return sin(x * PIval) / (x * PIval); + float x_pi = x * 3.141592654; + return 3.0 * sin(x_pi) * sin(x_pi * (1.0 / 3.0)) / (x_pi * x_pi); } -float weight(float x, float radius) +void weight6(float f_neg, out float3 tap012, out float3 tap345) { - float ax = abs(x); - if (x == 0.0) - return 1.0; - else if (ax < radius) - return sinc(x) * sinc(x / radius); - else - return 0.0; -} + tap012 = float3( + weight(f_neg - 2.0), + weight(f_neg - 1.0), + min(1.0, weight(f_neg))); // Replace NaN with 1.0. + tap345 = float3( + weight(f_neg + 1.0), + weight(f_neg + 2.0), + weight(f_neg + 3.0)); -float3 weight3(float x, float scale) -{ - return float3( - weight((x * 2.0 + 0.0 * 2.0 - 3.0) * scale, 3.0), - weight((x * 2.0 + 1.0 * 2.0 - 3.0) * scale, 3.0), - weight((x * 2.0 + 2.0 * 2.0 - 3.0) * scale, 3.0)); + // Normalize weights + float sum = tap012.x + tap012.y + tap012.z + tap345.x + tap345.y + tap345.z; + float sum_i = 1.0 / sum; + tap012 = tap012 * sum_i; + tap345 = tap345 * sum_i; } float AspectUndistortX(float x, float a) @@ -75,90 +76,134 @@ float AspectUndistortU(float u) return AspectUndistortX((u - 0.5) * 2.0, undistort_factor) * 0.5 + 0.5; } -float2 pixel_coord(float xpos, float ypos) +float2 undistort_coord(float xpos, float ypos) { return float2(AspectUndistortU(xpos), ypos); } -float4 pixel(float xpos, float ypos, bool undistort) +float4 undistort_pixel(float xpos, float ypos) { - if (undistort) - return image.Sample(textureSampler, pixel_coord(xpos, ypos)); - else - return image.Sample(textureSampler, float2(xpos, ypos)); + return image.Sample(textureSampler, undistort_coord(xpos, ypos)); } -float4 get_line(float ypos, float3 xpos1, float3 xpos2, float3 rowtap1, - float3 rowtap2, bool undistort) +float4 undistort_line(float3 xpos012, float3 xpos345, float ypos, float3 rowtap012, + float3 rowtap345) { return - pixel(xpos1.r, ypos, undistort) * rowtap1.r + - pixel(xpos1.g, ypos, undistort) * rowtap2.r + - pixel(xpos1.b, ypos, undistort) * rowtap1.g + - pixel(xpos2.r, ypos, undistort) * rowtap2.g + - pixel(xpos2.g, ypos, undistort) * rowtap1.b + - pixel(xpos2.b, ypos, undistort) * rowtap2.b; + undistort_pixel(xpos012.x, ypos) * rowtap012.x + + undistort_pixel(xpos012.y, ypos) * rowtap012.y + + undistort_pixel(xpos012.z, ypos) * rowtap012.z + + undistort_pixel(xpos345.x, ypos) * rowtap345.x + + undistort_pixel(xpos345.y, ypos) * rowtap345.y + + undistort_pixel(xpos345.z, ypos) * rowtap345.z; } -float4 DrawLanczos(FragData v_in, bool undistort) +float4 DrawLanczos(FragData f_in, bool undistort) { - float2 stepxy = base_dimension_i; - float2 pos = v_in.uv + stepxy * 0.5; - float2 f = frac(pos / stepxy); + float2 pos = f_in.uv; + float2 pos2 = floor(pos - 0.5) + 0.5; + float2 f_neg = pos2 - pos; - float3 rowtap1 = weight3((1.0 - f.x) / 2.0, v_in.scale.x); - float3 rowtap2 = weight3((1.0 - f.x) / 2.0 + 0.5, v_in.scale.x); - float3 coltap1 = weight3((1.0 - f.y) / 2.0, v_in.scale.y); - float3 coltap2 = weight3((1.0 - f.y) / 2.0 + 0.5, v_in.scale.y); + float3 rowtap012, rowtap345; + weight6(f_neg.x, rowtap012, rowtap345); - /* make sure all taps added together is exactly 1.0, otherwise some - * (very small) distortion can occur */ - float suml = rowtap1.r + rowtap1.g + rowtap1.b + rowtap2.r + rowtap2.g + rowtap2.b; - float sumc = coltap1.r + coltap1.g + coltap1.b + coltap2.r + coltap2.g + coltap2.b; - rowtap1 /= suml; - rowtap2 /= suml; - coltap1 /= sumc; - coltap2 /= sumc; + float3 coltap012, coltap345; + weight6(f_neg.y, coltap012, coltap345); - float2 xystart = (-2.5 - f) * stepxy + pos; - float3 xpos1 = float3(xystart.x , xystart.x + stepxy.x , xystart.x + stepxy.x * 2.0); - float3 xpos2 = float3(xystart.x + stepxy.x * 3.0, xystart.x + stepxy.x * 4.0, xystart.x + stepxy.x * 5.0); + float2 uv2 = pos2 * base_dimension_i; + float2 uv1 = uv2 - base_dimension_i; + float2 uv0 = uv1 - base_dimension_i; + float2 uv3 = uv2 + base_dimension_i; + float2 uv4 = uv3 + base_dimension_i; + float2 uv5 = uv4 + base_dimension_i; - return - get_line(xystart.y , xpos1, xpos2, rowtap1, rowtap2, undistort) * coltap1.r + - get_line(xystart.y + stepxy.y , xpos1, xpos2, rowtap1, rowtap2, undistort) * coltap2.r + - get_line(xystart.y + stepxy.y * 2.0, xpos1, xpos2, rowtap1, rowtap2, undistort) * coltap1.g + - get_line(xystart.y + stepxy.y * 3.0, xpos1, xpos2, rowtap1, rowtap2, undistort) * coltap2.g + - get_line(xystart.y + stepxy.y * 4.0, xpos1, xpos2, rowtap1, rowtap2, undistort) * coltap1.b + - get_line(xystart.y + stepxy.y * 5.0, xpos1, xpos2, rowtap1, rowtap2, undistort) * coltap2.b; + if (undistort) { + float3 xpos012 = float3(uv0.x, uv1.x, uv2.x); + float3 xpos345 = float3(uv3.x, uv4.x, uv5.x); + return undistort_line(xpos012, xpos345, uv0.y, rowtap012, rowtap345) * coltap012.x + + undistort_line(xpos012, xpos345, uv1.y, rowtap012, rowtap345) * coltap012.y + + undistort_line(xpos012, xpos345, uv2.y, rowtap012, rowtap345) * coltap012.z + + undistort_line(xpos012, xpos345, uv3.y, rowtap012, rowtap345) * coltap345.x + + undistort_line(xpos012, xpos345, uv4.y, rowtap012, rowtap345) * coltap345.y + + undistort_line(xpos012, xpos345, uv5.y, rowtap012, rowtap345) * coltap345.z; + } + + float u_weight_sum = rowtap012.z + rowtap345.x; + float u_middle_offset = rowtap345.x * base_dimension_i.x / u_weight_sum; + float u_middle = uv2.x + u_middle_offset; + + float v_weight_sum = coltap012.z + coltap345.x; + float v_middle_offset = coltap345.x * base_dimension_i.y / v_weight_sum; + float v_middle = uv2.y + v_middle_offset; + + float2 coord_limit = base_dimension - 0.5; + float2 coord0_f = max(uv0 * base_dimension, 0.5); + float2 coord1_f = max(uv1 * base_dimension, 0.5); + float2 coord4_f = min(uv4 * base_dimension, coord_limit); + float2 coord5_f = min(uv5 * base_dimension, coord_limit); + + int2 coord0 = int2(coord0_f); + int2 coord1 = int2(coord1_f); + int2 coord4 = int2(coord4_f); + int2 coord5 = int2(coord5_f); + + float4 row0 = image.Load(int3(coord0, 0)) * rowtap012.x; + row0 += image.Load(int3(coord1.x, coord0.y, 0)) * rowtap012.y; + row0 += image.Sample(textureSampler, float2(u_middle, uv0.y)) * u_weight_sum; + row0 += image.Load(int3(coord4.x, coord0.y, 0)) * rowtap345.y; + row0 += image.Load(int3(coord5.x, coord0.y, 0)) * rowtap345.z; + float4 total = row0 * coltap012.x; + + float4 row1 = image.Load(int3(coord0.x, coord1.y, 0)) * rowtap012.x; + row1 += image.Load(int3(coord1.x, coord1.y, 0)) * rowtap012.y; + row1 += image.Sample(textureSampler, float2(u_middle, uv1.y)) * u_weight_sum; + row1 += image.Load(int3(coord4.x, coord1.y, 0)) * rowtap345.y; + row1 += image.Load(int3(coord5.x, coord1.y, 0)) * rowtap345.z; + total += row1 * coltap012.y; + + float4 row23 = image.Sample(textureSampler, float2(uv0.x, v_middle)) * rowtap012.x; + row23 += image.Sample(textureSampler, float2(uv1.x, v_middle)) * rowtap012.y; + row23 += image.Sample(textureSampler, float2(u_middle, v_middle)) * u_weight_sum; + row23 += image.Sample(textureSampler, float2(uv4.x, v_middle)) * rowtap345.y; + row23 += image.Sample(textureSampler, float2(uv5.x, v_middle)) * rowtap345.z; + total += row23 * v_weight_sum; + + float4 row4 = image.Load(int3(coord0.x, coord4.y, 0)) * rowtap012.x; + row4 += image.Load(int3(coord1.x, coord4.y, 0)) * rowtap012.y; + row4 += image.Sample(textureSampler, float2(u_middle, uv4.y)) * u_weight_sum; + row4 += image.Load(int3(coord4.x, coord4.y, 0)) * rowtap345.y; + row4 += image.Load(int3(coord5.x, coord4.y, 0)) * rowtap345.z; + total += row4 * coltap345.y; + + float4 row5 = image.Load(int3(coord0.x, coord5.y, 0)) * rowtap012.x; + row5 += image.Load(int3(coord1.x, coord5.y, 0)) * rowtap012.y; + row5 += image.Sample(textureSampler, float2(u_middle, uv5.y)) * u_weight_sum; + row5 += image.Load(int3(coord4.x, coord5.y, 0)) * rowtap345.y; + row5 += image.Load(int3(coord5, 0)) * rowtap345.z; + total += row5 * coltap345.z; + + return total; } -float4 PSDrawLanczosRGBA(FragData v_in, bool undistort) : TARGET +float4 PSDrawLanczosRGBA(FragData f_in, bool undistort) : TARGET { - return DrawLanczos(v_in, undistort); + return DrawLanczos(f_in, undistort); } -float4 PSDrawLanczosRGBADivide(FragData v_in) : TARGET +float4 PSDrawLanczosRGBADivide(FragData f_in) : TARGET { - float4 rgba = DrawLanczos(v_in, false); + float4 rgba = DrawLanczos(f_in, false); float alpha = rgba.a; float multiplier = (alpha > 0.0) ? (1.0 / alpha) : 0.0; return float4(rgba.rgb * multiplier, alpha); } -float4 PSDrawLanczosMatrix(FragData v_in) : TARGET -{ - float3 rgb = DrawLanczos(v_in, false).rgb; - float3 yuv = mul(float4(saturate(rgb), 1.0), color_matrix).xyz; - return float4(yuv, 1.0); -} - technique Draw { pass { vertex_shader = VSDefault(v_in); - pixel_shader = PSDrawLanczosRGBA(v_in, false); + pixel_shader = PSDrawLanczosRGBA(f_in, false); } } @@ -167,7 +212,7 @@ technique DrawAlphaDivide pass { vertex_shader = VSDefault(v_in); - pixel_shader = PSDrawLanczosRGBADivide(v_in); + pixel_shader = PSDrawLanczosRGBADivide(f_in); } } @@ -176,15 +221,6 @@ technique DrawUndistort pass { vertex_shader = VSDefault(v_in); - pixel_shader = PSDrawLanczosRGBA(v_in, true); - } -} - -technique DrawMatrix -{ - pass - { - vertex_shader = VSDefault(v_in); - pixel_shader = PSDrawLanczosMatrix(v_in); + pixel_shader = PSDrawLanczosRGBA(f_in, true); } } diff --git a/libobs/graphics/axisang.c b/libobs/graphics/axisang.c index 95770d5..75a48a7 100644 --- a/libobs/graphics/axisang.c +++ b/libobs/graphics/axisang.c @@ -22,13 +22,13 @@ void axisang_from_quat(struct axisang *dst, const struct quat *q) { float len, leni; - len = q->x*q->x + q->y*q->y + q->z*q->z; + len = q->x * q->x + q->y * q->y + q->z * q->z; if (!close_float(len, 0.0f, EPSILON)) { - leni = 1.0f/sqrtf(len); + leni = 1.0f / sqrtf(len); dst->x = q->x * leni; dst->y = q->y * leni; dst->z = q->z * leni; - dst->w = acosf(q->w)*2.0f; + dst->w = acosf(q->w) * 2.0f; } else { dst->x = 0.0f; dst->y = 0.0f; diff --git a/libobs/graphics/axisang.h b/libobs/graphics/axisang.h index d936d87..112baf1 100644 --- a/libobs/graphics/axisang.h +++ b/libobs/graphics/axisang.h @@ -27,7 +27,9 @@ struct quat; struct axisang { union { - struct {float x, y, z, w;}; + struct { + float x, y, z, w; + }; float ptr[4]; }; }; @@ -49,7 +51,7 @@ static inline void axisang_copy(struct axisang *dst, struct axisang *aa) } static inline void axisang_set(struct axisang *dst, float x, float y, float z, - float w) + float w) { dst->x = x; dst->y = y; diff --git a/libobs/graphics/bounds.c b/libobs/graphics/bounds.c index 7fb581f..7300b33 100644 --- a/libobs/graphics/bounds.c +++ b/libobs/graphics/bounds.c @@ -22,35 +22,34 @@ #include "plane.h" void bounds_move(struct bounds *dst, const struct bounds *b, - const struct vec3 *v) + const struct vec3 *v) { vec3_add(&dst->min, &b->min, v); vec3_add(&dst->max, &b->max, v); } void bounds_scale(struct bounds *dst, const struct bounds *b, - const struct vec3 *v) + const struct vec3 *v) { vec3_mul(&dst->min, &b->min, v); vec3_mul(&dst->max, &b->max, v); } void bounds_merge(struct bounds *dst, const struct bounds *b1, - const struct bounds *b2) + const struct bounds *b2) { vec3_min(&dst->min, &b1->min, &b2->min); vec3_max(&dst->max, &b1->max, &b2->max); } void bounds_merge_point(struct bounds *dst, const struct bounds *b, - const struct vec3 *v) + const struct vec3 *v) { vec3_min(&dst->min, &b->min, v); vec3_max(&dst->max, &b->max, v); } -void bounds_get_point(struct vec3 *dst, const struct bounds *b, - unsigned int i) +void bounds_get_point(struct vec3 *dst, const struct bounds *b, unsigned int i) { if (i > 8) return; @@ -68,11 +67,19 @@ void bounds_get_point(struct vec3 *dst, const struct bounds *b, * 7 = MAX.x,MAX.y,MAX.z */ - if(i > 3) {dst->x = b->max.x; i -= 4;} - else {dst->x = b->min.x;} + if (i > 3) { + dst->x = b->max.x; + i -= 4; + } else { + dst->x = b->min.x; + } - if(i > 1) {dst->y = b->max.y; i -= 2;} - else {dst->y = b->min.y;} + if (i > 1) { + dst->y = b->max.y; + i -= 2; + } else { + dst->y = b->min.y; + } dst->z = (i == 1) ? b->max.z : b->min.z; } @@ -85,7 +92,7 @@ void bounds_get_center(struct vec3 *dst, const struct bounds *b) } void bounds_transform(struct bounds *dst, const struct bounds *b, - const struct matrix4 *m) + const struct matrix4 *m) { struct bounds temp; bool b_init = false; @@ -124,7 +131,7 @@ void bounds_transform(struct bounds *dst, const struct bounds *b, } void bounds_transform3x4(struct bounds *dst, const struct bounds *b, - const struct matrix3 *m) + const struct matrix3 *m) { struct bounds temp; bool b_init = false; @@ -163,7 +170,7 @@ void bounds_transform3x4(struct bounds *dst, const struct bounds *b, } bool bounds_intersection_ray(const struct bounds *b, const struct vec3 *orig, - const struct vec3 *dir, float *t) + const struct vec3 *dir, float *t) { float t_max = M_INFINITE; float t_min = -M_INFINITE; @@ -179,22 +186,26 @@ bool bounds_intersection_ray(const struct bounds *b, const struct vec3 *orig, float f = dir->ptr[i]; if (fabsf(f) > 0.0f) { - float fi = 1.0f/f; - float t1 = (e+max_offset.ptr[i])*fi; - float t2 = (e-max_offset.ptr[i])*fi; + float fi = 1.0f / f; + float t1 = (e + max_offset.ptr[i]) * fi; + float t2 = (e - max_offset.ptr[i]) * fi; if (t1 > t2) { - if (t2 > t_min) t_min = t2; - if (t1 < t_max) t_max = t1; + if (t2 > t_min) + t_min = t2; + if (t1 < t_max) + t_max = t1; } else { - if (t1 > t_min) t_min = t1; - if (t2 < t_max) t_max = t2; + if (t1 > t_min) + t_min = t1; + if (t2 < t_max) + t_max = t2; } if (t_min > t_max) return false; if (t_max < 0.0f) return false; } else if ((-e - max_offset.ptr[i]) > 0.0f || - (-e + max_offset.ptr[i]) < 0.0f) { + (-e + max_offset.ptr[i]) < 0.0f) { return false; } } @@ -204,7 +215,7 @@ bool bounds_intersection_ray(const struct bounds *b, const struct vec3 *orig, } bool bounds_intersection_line(const struct bounds *b, const struct vec3 *p1, - const struct vec3 *p2, float *t) + const struct vec3 *p2, float *t) { struct vec3 dir; float length; @@ -214,7 +225,7 @@ bool bounds_intersection_line(const struct bounds *b, const struct vec3 *p1, if (length <= TINY_EPSILON) return false; - vec3_mulf(&dir, &dir, 1.0f/length); + vec3_mulf(&dir, &dir, 1.0f / length); if (!bounds_intersection_ray(b, p1, &dir, t)) return false; @@ -259,7 +270,7 @@ bool bounds_under_plane(const struct bounds *b, const struct plane *p) } bool bounds_intersects(const struct bounds *b, const struct bounds *test, - float epsilon) + float epsilon) { return ((b->min.x - test->max.x) <= epsilon) && ((test->min.x - b->max.x) <= epsilon) && @@ -270,7 +281,7 @@ bool bounds_intersects(const struct bounds *b, const struct bounds *test, } bool bounds_intersects_obb(const struct bounds *b, const struct bounds *test, - const struct matrix4 *m, float epsilon) + const struct matrix4 *m, float epsilon) { struct bounds b_tr, test_tr; struct matrix4 m_inv; @@ -285,7 +296,7 @@ bool bounds_intersects_obb(const struct bounds *b, const struct bounds *test, } bool bounds_intersects_obb3x4(const struct bounds *b, const struct bounds *test, - const struct matrix3 *m, float epsilon) + const struct matrix3 *m, float epsilon) { struct bounds b_tr, test_tr; struct matrix3 m_inv; @@ -300,7 +311,7 @@ bool bounds_intersects_obb3x4(const struct bounds *b, const struct bounds *test, } static inline float vec3or_offset_len(const struct bounds *b, - const struct vec3 *v) + const struct vec3 *v) { struct vec3 temp1, temp2; vec3_sub(&temp1, &b->max, &b->min); diff --git a/libobs/graphics/bounds.h b/libobs/graphics/bounds.h index c47c258..bb5eb8f 100644 --- a/libobs/graphics/bounds.h +++ b/libobs/graphics/bounds.h @@ -33,7 +33,7 @@ extern "C" { #define BOUNDS_MAX_Z 4 #define BOUNDS_OUTSIDE 1 -#define BOUNDS_INSIDE 2 +#define BOUNDS_INSIDE 2 #define BOUNDS_PARTIAL 3 struct bounds { @@ -53,18 +53,18 @@ static inline void bounds_copy(struct bounds *dst, const struct bounds *b) } EXPORT void bounds_move(struct bounds *dst, const struct bounds *b, - const struct vec3 *v); + const struct vec3 *v); EXPORT void bounds_scale(struct bounds *dst, const struct bounds *b, - const struct vec3 *v); + const struct vec3 *v); EXPORT void bounds_merge(struct bounds *dst, const struct bounds *b1, - const struct bounds *b2); + const struct bounds *b2); EXPORT void bounds_merge_point(struct bounds *dst, const struct bounds *b, - const struct vec3 *v); + const struct vec3 *v); EXPORT void bounds_get_point(struct vec3 *dst, const struct bounds *b, - unsigned int i); + unsigned int i); EXPORT void bounds_get_center(struct vec3 *dst, const struct bounds *b); /** @@ -72,59 +72,56 @@ EXPORT void bounds_get_center(struct vec3 *dst, const struct bounds *b); * the actual size becoming larger than it originally was. */ EXPORT void bounds_transform(struct bounds *dst, const struct bounds *b, - const struct matrix4 *m); + const struct matrix4 *m); EXPORT void bounds_transform3x4(struct bounds *dst, const struct bounds *b, - const struct matrix3 *m); + const struct matrix3 *m); EXPORT bool bounds_intersection_ray(const struct bounds *b, - const struct vec3 *orig, const struct vec3 *dir, float *t); + const struct vec3 *orig, + const struct vec3 *dir, float *t); EXPORT bool bounds_intersection_line(const struct bounds *b, - const struct vec3 *p1, const struct vec3 *p2, float *t); + const struct vec3 *p1, + const struct vec3 *p2, float *t); EXPORT bool bounds_plane_test(const struct bounds *b, const struct plane *p); -EXPORT bool bounds_under_plane(const struct bounds *b, - const struct plane *p); +EXPORT bool bounds_under_plane(const struct bounds *b, const struct plane *p); static inline bool bounds_inside(const struct bounds *b, - const struct bounds *test) + const struct bounds *test) { - return test->min.x >= b->min.x && - test->min.y >= b->min.y && - test->min.z >= b->min.z && - test->max.x <= b->max.x && - test->max.y <= b->max.y && - test->max.z <= b->max.z; + return test->min.x >= b->min.x && test->min.y >= b->min.y && + test->min.z >= b->min.z && test->max.x <= b->max.x && + test->max.y <= b->max.y && test->max.z <= b->max.z; } static inline bool bounds_vec3_inside(const struct bounds *b, - const struct vec3 *v) + const struct vec3 *v) { - return v->x >= (b->min.x-EPSILON) && - v->x <= (b->max.x+EPSILON) && - v->y >= (b->min.y-EPSILON) && - v->y <= (b->max.y+EPSILON) && - v->z >= (b->min.z-EPSILON) && - v->z <= (b->max.z+EPSILON); + return v->x >= (b->min.x - EPSILON) && v->x <= (b->max.x + EPSILON) && + v->y >= (b->min.y - EPSILON) && v->y <= (b->max.y + EPSILON) && + v->z >= (b->min.z - EPSILON) && v->z <= (b->max.z + EPSILON); } -EXPORT bool bounds_intersects(const struct bounds *b, - const struct bounds *test, float epsilon); +EXPORT bool bounds_intersects(const struct bounds *b, const struct bounds *test, + float epsilon); EXPORT bool bounds_intersects_obb(const struct bounds *b, - const struct bounds *test, const struct matrix4 *m, - float epsilon); + const struct bounds *test, + const struct matrix4 *m, float epsilon); EXPORT bool bounds_intersects_obb3x4(const struct bounds *b, - const struct bounds *test, const struct matrix3 *m, - float epsilon); + const struct bounds *test, + const struct matrix3 *m, float epsilon); static inline bool bounds_intersects_ray(const struct bounds *b, - const struct vec3 *orig, const struct vec3 *dir) + const struct vec3 *orig, + const struct vec3 *dir) { float t; return bounds_intersection_ray(b, orig, dir, &t); } static inline bool bounds_intersects_line(const struct bounds *b, - const struct vec3 *p1, const struct vec3 *p2) + const struct vec3 *p1, + const struct vec3 *p2) { float t; return bounds_intersection_line(b, p1, p2, &t); diff --git a/libobs/graphics/device-exports.h b/libobs/graphics/device-exports.h index 2158e58..1f03a5d 100644 --- a/libobs/graphics/device-exports.h +++ b/libobs/graphics/device-exports.h @@ -25,90 +25,103 @@ extern "C" { EXPORT const char *device_get_name(void); EXPORT int device_get_type(void); -EXPORT bool device_enum_adapters( - bool (*callback)(void *param, const char *name, uint32_t id), - void *param); +EXPORT bool device_enum_adapters(bool (*callback)(void *param, const char *name, + uint32_t id), + void *param); EXPORT const char *device_preprocessor_name(void); EXPORT int device_create(gs_device_t **device, uint32_t adapter); EXPORT void device_destroy(gs_device_t *device); EXPORT void device_enter_context(gs_device_t *device); EXPORT void device_leave_context(gs_device_t *device); +EXPORT void *device_get_device_obj(gs_device_t *device); EXPORT gs_swapchain_t *device_swapchain_create(gs_device_t *device, - const struct gs_init_data *data); + const struct gs_init_data *data); EXPORT void device_resize(gs_device_t *device, uint32_t x, uint32_t y); -EXPORT void device_get_size(const gs_device_t *device, uint32_t *x, uint32_t *y); +EXPORT void device_get_size(const gs_device_t *device, uint32_t *x, + uint32_t *y); EXPORT uint32_t device_get_width(const gs_device_t *device); EXPORT uint32_t device_get_height(const gs_device_t *device); -EXPORT gs_texture_t *device_texture_create(gs_device_t *device, uint32_t width, - uint32_t height, enum gs_color_format color_format, - uint32_t levels, const uint8_t **data, uint32_t flags); -EXPORT gs_texture_t *device_cubetexture_create(gs_device_t *device, - uint32_t size, enum gs_color_format color_format, - uint32_t levels, const uint8_t **data, uint32_t flags); -EXPORT gs_texture_t *device_voltexture_create(gs_device_t *device, - uint32_t width, uint32_t height, uint32_t depth, - enum gs_color_format color_format, uint32_t levels, - const uint8_t **data, uint32_t flags); +EXPORT gs_texture_t * +device_texture_create(gs_device_t *device, uint32_t width, uint32_t height, + enum gs_color_format color_format, uint32_t levels, + const uint8_t **data, uint32_t flags); +EXPORT gs_texture_t * +device_cubetexture_create(gs_device_t *device, uint32_t size, + enum gs_color_format color_format, uint32_t levels, + const uint8_t **data, uint32_t flags); +EXPORT gs_texture_t * +device_voltexture_create(gs_device_t *device, uint32_t width, uint32_t height, + uint32_t depth, enum gs_color_format color_format, + uint32_t levels, const uint8_t **data, uint32_t flags); EXPORT gs_zstencil_t *device_zstencil_create(gs_device_t *device, - uint32_t width, uint32_t height, - enum gs_zstencil_format format); -EXPORT gs_stagesurf_t *device_stagesurface_create(gs_device_t *device, - uint32_t width, uint32_t height, - enum gs_color_format color_format); -EXPORT gs_samplerstate_t *device_samplerstate_create(gs_device_t *device, - const struct gs_sampler_info *info); + uint32_t width, uint32_t height, + enum gs_zstencil_format format); +EXPORT gs_stagesurf_t * +device_stagesurface_create(gs_device_t *device, uint32_t width, uint32_t height, + enum gs_color_format color_format); +EXPORT gs_samplerstate_t * +device_samplerstate_create(gs_device_t *device, + const struct gs_sampler_info *info); EXPORT gs_shader_t *device_vertexshader_create(gs_device_t *device, - const char *shader, const char *file, - char **error_string); + const char *shader, + const char *file, + char **error_string); EXPORT gs_shader_t *device_pixelshader_create(gs_device_t *device, - const char *shader, const char *file, - char **error_string); + const char *shader, + const char *file, + char **error_string); EXPORT gs_vertbuffer_t *device_vertexbuffer_create(gs_device_t *device, - struct gs_vb_data *data, uint32_t flags); + struct gs_vb_data *data, + uint32_t flags); EXPORT gs_indexbuffer_t *device_indexbuffer_create(gs_device_t *device, - enum gs_index_type type, void *indices, size_t num, - uint32_t flags); -EXPORT enum gs_texture_type device_get_texture_type( - const gs_texture_t *texture); + enum gs_index_type type, + void *indices, size_t num, + uint32_t flags); +EXPORT gs_timer_t *device_timer_create(gs_device_t *device); +EXPORT gs_timer_range_t *device_timer_range_create(gs_device_t *device); +EXPORT enum gs_texture_type +device_get_texture_type(const gs_texture_t *texture); EXPORT void device_load_vertexbuffer(gs_device_t *device, - gs_vertbuffer_t *vertbuffer); + gs_vertbuffer_t *vertbuffer); EXPORT void device_load_indexbuffer(gs_device_t *device, - gs_indexbuffer_t *indexbuffer); + gs_indexbuffer_t *indexbuffer); EXPORT void device_load_texture(gs_device_t *device, gs_texture_t *tex, - int unit); + int unit); EXPORT void device_load_samplerstate(gs_device_t *device, - gs_samplerstate_t *samplerstate, int unit); + gs_samplerstate_t *samplerstate, int unit); EXPORT void device_load_vertexshader(gs_device_t *device, - gs_shader_t *vertshader); + gs_shader_t *vertshader); EXPORT void device_load_pixelshader(gs_device_t *device, - gs_shader_t *pixelshader); + gs_shader_t *pixelshader); EXPORT void device_load_default_samplerstate(gs_device_t *device, bool b_3d, - int unit); + int unit); EXPORT gs_shader_t *device_get_vertex_shader(const gs_device_t *device); EXPORT gs_shader_t *device_get_pixel_shader(const gs_device_t *device); EXPORT gs_texture_t *device_get_render_target(const gs_device_t *device); EXPORT gs_zstencil_t *device_get_zstencil_target(const gs_device_t *device); EXPORT void device_set_render_target(gs_device_t *device, gs_texture_t *tex, - gs_zstencil_t *zstencil); + gs_zstencil_t *zstencil); EXPORT void device_set_cube_render_target(gs_device_t *device, - gs_texture_t *cubetex, - int side, gs_zstencil_t *zstencil); + gs_texture_t *cubetex, int side, + gs_zstencil_t *zstencil); EXPORT void device_copy_texture(gs_device_t *device, gs_texture_t *dst, - gs_texture_t *src); -EXPORT void device_copy_texture_region(gs_device_t *device, - gs_texture_t *dst, uint32_t dst_x, uint32_t dst_y, - gs_texture_t *src, uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h); + gs_texture_t *src); +EXPORT void device_copy_texture_region(gs_device_t *device, gs_texture_t *dst, + uint32_t dst_x, uint32_t dst_y, + gs_texture_t *src, uint32_t src_x, + uint32_t src_y, uint32_t src_w, + uint32_t src_h); EXPORT void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst, - gs_texture_t *src); + gs_texture_t *src); EXPORT void device_begin_scene(gs_device_t *device); EXPORT void device_draw(gs_device_t *device, enum gs_draw_mode draw_mode, - uint32_t start_vert, uint32_t num_verts); + uint32_t start_vert, uint32_t num_verts); EXPORT void device_end_scene(gs_device_t *device); EXPORT void device_load_swapchain(gs_device_t *device, - gs_swapchain_t *swapchain); + gs_swapchain_t *swapchain); EXPORT void device_clear(gs_device_t *device, uint32_t clear_flags, - const struct vec4 *color, float depth, uint8_t stencil); + const struct vec4 *color, float depth, + uint8_t stencil); EXPORT void device_present(gs_device_t *device); EXPORT void device_flush(gs_device_t *device); EXPORT void device_set_cull_mode(gs_device_t *device, enum gs_cull_mode mode); @@ -118,32 +131,37 @@ EXPORT void device_enable_depth_test(gs_device_t *device, bool enable); EXPORT void device_enable_stencil_test(gs_device_t *device, bool enable); EXPORT void device_enable_stencil_write(gs_device_t *device, bool enable); EXPORT void device_enable_color(gs_device_t *device, bool red, bool green, - bool blue, bool alpha); + bool blue, bool alpha); EXPORT void device_blend_function(gs_device_t *device, enum gs_blend_type src, - enum gs_blend_type dest); + enum gs_blend_type dest); EXPORT void device_blend_function_separate(gs_device_t *device, - enum gs_blend_type src_c, enum gs_blend_type dest_c, - enum gs_blend_type src_a, enum gs_blend_type dest_a); + enum gs_blend_type src_c, + enum gs_blend_type dest_c, + enum gs_blend_type src_a, + enum gs_blend_type dest_a); EXPORT void device_depth_function(gs_device_t *device, enum gs_depth_test test); EXPORT void device_stencil_function(gs_device_t *device, - enum gs_stencil_side side, enum gs_depth_test test); + enum gs_stencil_side side, + enum gs_depth_test test); EXPORT void device_stencil_op(gs_device_t *device, enum gs_stencil_side side, - enum gs_stencil_op_type fail, enum gs_stencil_op_type zfail, - enum gs_stencil_op_type zpass); + enum gs_stencil_op_type fail, + enum gs_stencil_op_type zfail, + enum gs_stencil_op_type zpass); EXPORT void device_set_viewport(gs_device_t *device, int x, int y, int width, - int height); + int height); EXPORT void device_get_viewport(const gs_device_t *device, - struct gs_rect *rect); + struct gs_rect *rect); EXPORT void device_set_scissor_rect(gs_device_t *device, - const struct gs_rect *rect); + const struct gs_rect *rect); EXPORT void device_ortho(gs_device_t *device, float left, float right, - float top, float bottom, float znear, float zfar); + float top, float bottom, float znear, float zfar); EXPORT void device_frustum(gs_device_t *device, float left, float right, - float top, float bottom, float znear, float zfar); + float top, float bottom, float znear, float zfar); EXPORT void device_projection_push(gs_device_t *device); EXPORT void device_projection_pop(gs_device_t *device); EXPORT void device_debug_marker_begin(gs_device_t *device, - const char *markername, const float color[4]); + const char *markername, + const float color[4]); EXPORT void device_debug_marker_end(gs_device_t *device); #ifdef __cplusplus diff --git a/libobs/graphics/effect-parser.c b/libobs/graphics/effect-parser.c index 70e9842..c0c8508 100644 --- a/libobs/graphics/effect-parser.c +++ b/libobs/graphics/effect-parser.c @@ -22,7 +22,7 @@ #include "effect.h" static inline bool ep_parse_param_assign(struct effect_parser *ep, - struct ep_param *param); + struct ep_param *param); static enum gs_shader_param_type get_effect_param_type(const char *type) { @@ -58,15 +58,15 @@ void ep_free(struct effect_parser *ep) { size_t i; for (i = 0; i < ep->params.num; i++) - ep_param_free(ep->params.array+i); + ep_param_free(ep->params.array + i); for (i = 0; i < ep->structs.num; i++) - ep_struct_free(ep->structs.array+i); + ep_struct_free(ep->structs.array + i); for (i = 0; i < ep->funcs.num; i++) - ep_func_free(ep->funcs.array+i); + ep_func_free(ep->funcs.array + i); for (i = 0; i < ep->samplers.num; i++) - ep_sampler_free(ep->samplers.array+i); + ep_sampler_free(ep->samplers.array + i); for (i = 0; i < ep->techniques.num; i++) - ep_technique_free(ep->techniques.array+i); + ep_technique_free(ep->techniques.array + i); ep->cur_pass = NULL; cf_parser_free(&ep->cfp); @@ -78,125 +78,128 @@ void ep_free(struct effect_parser *ep) } static inline struct ep_func *ep_getfunc(struct effect_parser *ep, - const char *name) + const char *name) { size_t i; for (i = 0; i < ep->funcs.num; i++) { if (strcmp(name, ep->funcs.array[i].name) == 0) - return ep->funcs.array+i; + return ep->funcs.array + i; } return NULL; } static inline struct ep_struct *ep_getstruct(struct effect_parser *ep, - const char *name) + const char *name) { size_t i; for (i = 0; i < ep->structs.num; i++) { if (strcmp(name, ep->structs.array[i].name) == 0) - return ep->structs.array+i; + return ep->structs.array + i; } return NULL; } static inline struct ep_sampler *ep_getsampler(struct effect_parser *ep, - const char *name) + const char *name) { size_t i; for (i = 0; i < ep->samplers.num; i++) { if (strcmp(name, ep->samplers.array[i].name) == 0) - return ep->samplers.array+i; + return ep->samplers.array + i; } return NULL; } static inline struct ep_param *ep_getparam(struct effect_parser *ep, - const char *name) + const char *name) { size_t i; for (i = 0; i < ep->params.num; i++) { if (strcmp(name, ep->params.array[i].name) == 0) - return ep->params.array+i; + return ep->params.array + i; } return NULL; } static inline struct ep_param *ep_getannotation(struct ep_param *param, - const char *name) + const char *name) { size_t i; for (i = 0; i < param->annotations.num; i++) { if (strcmp(name, param->annotations.array[i].name) == 0) - return param->annotations.array+i; + return param->annotations.array + i; } return NULL; } static inline struct ep_func *ep_getfunc_strref(struct effect_parser *ep, - const struct strref *ref) + const struct strref *ref) { size_t i; for (i = 0; i < ep->funcs.num; i++) { if (strref_cmp(ref, ep->funcs.array[i].name) == 0) - return ep->funcs.array+i; + return ep->funcs.array + i; } return NULL; } static inline struct ep_struct *ep_getstruct_strref(struct effect_parser *ep, - const struct strref *ref) + const struct strref *ref) { size_t i; for (i = 0; i < ep->structs.num; i++) { if (strref_cmp(ref, ep->structs.array[i].name) == 0) - return ep->structs.array+i; + return ep->structs.array + i; } return NULL; } static inline struct ep_sampler *ep_getsampler_strref(struct effect_parser *ep, - const struct strref *ref) + const struct strref *ref) { size_t i; for (i = 0; i < ep->samplers.num; i++) { if (strref_cmp(ref, ep->samplers.array[i].name) == 0) - return ep->samplers.array+i; + return ep->samplers.array + i; } return NULL; } static inline struct ep_param *ep_getparam_strref(struct effect_parser *ep, - const struct strref *ref) + const struct strref *ref) { size_t i; for (i = 0; i < ep->params.num; i++) { if (strref_cmp(ref, ep->params.array[i].name) == 0) - return ep->params.array+i; + return ep->params.array + i; } return NULL; } static inline int ep_parse_struct_var(struct effect_parser *ep, - struct ep_var *var) + struct ep_var *var) { int code; /* -------------------------------------- */ /* variable type */ - if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; - if (cf_token_is(&ep->cfp, ";")) return PARSE_CONTINUE; - if (cf_token_is(&ep->cfp, "}")) return PARSE_BREAK; + if (cf_token_is(&ep->cfp, ";")) + return PARSE_CONTINUE; + if (cf_token_is(&ep->cfp, "}")) + return PARSE_BREAK; code = cf_token_is_type(&ep->cfp, CFTOKEN_NAME, "type name", ";"); if (code != PARSE_SUCCESS) @@ -207,10 +210,13 @@ static inline int ep_parse_struct_var(struct effect_parser *ep, /* -------------------------------------- */ /* variable name */ - if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; - if (cf_token_is(&ep->cfp, ";")) return PARSE_UNEXPECTED_CONTINUE; - if (cf_token_is(&ep->cfp, "}")) return PARSE_UNEXPECTED_BREAK; + if (cf_token_is(&ep->cfp, ";")) + return PARSE_UNEXPECTED_CONTINUE; + if (cf_token_is(&ep->cfp, "}")) + return PARSE_UNEXPECTED_BREAK; code = cf_token_is_type(&ep->cfp, CFTOKEN_NAME, "variable name", ";"); if (code != PARSE_SUCCESS) @@ -221,24 +227,27 @@ static inline int ep_parse_struct_var(struct effect_parser *ep, /* -------------------------------------- */ /* variable mapping if any (POSITION, TEXCOORD, etc) */ - if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; if (cf_token_is(&ep->cfp, ":")) { - if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; if (cf_token_is(&ep->cfp, ";")) return PARSE_UNEXPECTED_CONTINUE; if (cf_token_is(&ep->cfp, "}")) return PARSE_UNEXPECTED_BREAK; - code = cf_token_is_type(&ep->cfp, CFTOKEN_NAME, - "mapping name", ";"); + code = cf_token_is_type(&ep->cfp, CFTOKEN_NAME, "mapping name", + ";"); if (code != PARSE_SUCCESS) return code; cf_copy_token(&ep->cfp, &var->mapping); - if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; } /* -------------------------------------- */ @@ -308,7 +317,7 @@ error: } static inline int ep_parse_param_annotation_var(struct effect_parser *ep, - struct ep_param *var) + struct ep_param *var) { int code; @@ -385,7 +394,7 @@ static inline int ep_parse_param_annotation_var(struct effect_parser *ep, } static int ep_parse_annotations(struct effect_parser *ep, - struct darray *annotations) + struct darray *annotations) { if (!cf_token_is(&ep->cfp, "<")) { cf_adderror_expecting(&ep->cfp, "<"); @@ -398,7 +407,7 @@ static int ep_parse_annotations(struct effect_parser *ep, struct ep_param var; ep_param_init(&var, bstrdup(""), bstrdup(""), false, false, - false); + false); switch (ep_parse_param_annotation_var(ep, &var)) { case PARSE_UNEXPECTED_CONTINUE: @@ -441,13 +450,13 @@ error: } static int ep_parse_param_annotations(struct effect_parser *ep, - struct ep_param *param) + struct ep_param *param) { return ep_parse_annotations(ep, ¶m->annotations.da); } static inline int ep_parse_pass_command_call(struct effect_parser *ep, - struct darray *call) + struct darray *call) { struct cf_token end_token; cf_token_clear(&end_token); @@ -459,8 +468,9 @@ static inline int ep_parse_pass_command_call(struct effect_parser *ep, } darray_push_back(sizeof(struct cf_token), call, - ep->cfp.cur_token); - if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; + ep->cfp.cur_token); + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; } darray_push_back(sizeof(struct cf_token), call, ep->cfp.cur_token); @@ -472,30 +482,34 @@ static int ep_parse_pass_command(struct effect_parser *ep, struct ep_pass *pass) { struct darray *call; /* struct cf_token */ - if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; if (cf_token_is(&ep->cfp, "vertex_shader") || cf_token_is(&ep->cfp, "vertex_program")) { call = &pass->vertex_program.da; } else if (cf_token_is(&ep->cfp, "pixel_shader") || - cf_token_is(&ep->cfp, "pixel_program")) { + cf_token_is(&ep->cfp, "pixel_program")) { call = &pass->fragment_program.da; } else { cf_adderror_syntax_error(&ep->cfp); - if (!cf_go_to_valid_token(&ep->cfp, ";", "}")) return PARSE_EOF; + if (!cf_go_to_valid_token(&ep->cfp, ";", "}")) + return PARSE_EOF; return PARSE_CONTINUE; } if (cf_next_token_should_be(&ep->cfp, "=", ";", "}") != PARSE_SUCCESS) return PARSE_CONTINUE; - if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; if (cf_token_is(&ep->cfp, "compile")) { cf_adderror(&ep->cfp, "compile keyword not necessary", - LEX_WARNING, NULL, NULL, NULL); - if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; + LEX_WARNING, NULL, NULL, NULL); + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; } return ep_parse_pass_command_call(ep, call); @@ -508,15 +522,18 @@ static int ep_parse_pass(struct effect_parser *ep, struct ep_pass *pass) if (!cf_token_is(&ep->cfp, "pass")) return PARSE_UNEXPECTED_CONTINUE; - if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; if (!cf_token_is(&ep->cfp, "{")) { pass->name = bstrdup_n(ep->cfp.cur_token->str.array, - ep->cfp.cur_token->str.len); - if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; + ep->cfp.cur_token->str.len); + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; } - if (!cf_peek_valid_token(&ep->cfp, &peek)) return PARSE_EOF; + if (!cf_peek_valid_token(&ep->cfp, &peek)) + return PARSE_EOF; while (strref_cmp(&peek.str, "}") != 0) { int ret = ep_parse_pass_command(ep, pass); @@ -589,17 +606,19 @@ error: } static int ep_parse_sampler_state_item(struct effect_parser *ep, - struct ep_sampler *eps) + struct ep_sampler *eps) { int ret; char *state = NULL; struct dstr value = {0}; ret = cf_next_name(&ep->cfp, &state, "state name", ";"); - if (ret != PARSE_SUCCESS) goto fail; + if (ret != PARSE_SUCCESS) + goto fail; ret = cf_next_token_should_be(&ep->cfp, "=", ";", NULL); - if (ret != PARSE_SUCCESS) goto fail; + if (ret != PARSE_SUCCESS) + goto fail; for (;;) { const char *cur_str; @@ -663,7 +682,7 @@ error: } static inline int ep_check_for_keyword(struct effect_parser *ep, - const char *keyword, bool *val) + const char *keyword, bool *val) { bool new_val = cf_token_is(&ep->cfp, keyword); if (new_val) { @@ -672,7 +691,7 @@ static inline int ep_check_for_keyword(struct effect_parser *ep, if (new_val && *val) cf_adderror(&ep->cfp, "'$1' keyword already specified", - LEX_WARNING, keyword, NULL, NULL); + LEX_WARNING, keyword, NULL, NULL); *val = new_val; return PARSE_CONTINUE; @@ -682,7 +701,7 @@ static inline int ep_check_for_keyword(struct effect_parser *ep, } static inline int ep_parse_func_param(struct effect_parser *ep, - struct ep_func *func, struct ep_var *var) + struct ep_func *func, struct ep_var *var) { int code; bool var_type_keyword = false; @@ -733,7 +752,7 @@ static inline int ep_parse_func_param(struct effect_parser *ep, if (cf_token_is(&ep->cfp, ":")) { code = cf_next_name(&ep->cfp, &var->mapping, - "mapping specifier", ")"); + "mapping specifier", ")"); if (code != PARSE_SUCCESS) return code; @@ -789,37 +808,36 @@ exit: } static inline bool ep_process_struct_dep(struct effect_parser *ep, - struct ep_func *func) + struct ep_func *func) { - struct ep_struct *val = ep_getstruct_strref(ep, - &ep->cfp.cur_token->str); + struct ep_struct *val = + ep_getstruct_strref(ep, &ep->cfp.cur_token->str); if (val) da_push_back(func->struct_deps, &val->name); return val != NULL; } static inline bool ep_process_func_dep(struct effect_parser *ep, - struct ep_func *func) + struct ep_func *func) { - struct ep_func *val = ep_getfunc_strref(ep, - &ep->cfp.cur_token->str); + struct ep_func *val = ep_getfunc_strref(ep, &ep->cfp.cur_token->str); if (val) da_push_back(func->func_deps, &val->name); return val != NULL; } static inline bool ep_process_sampler_dep(struct effect_parser *ep, - struct ep_func *func) + struct ep_func *func) { - struct ep_sampler *val = ep_getsampler_strref(ep, - &ep->cfp.cur_token->str); + struct ep_sampler *val = + ep_getsampler_strref(ep, &ep->cfp.cur_token->str); if (val) da_push_back(func->sampler_deps, &val->name); return val != NULL; } static inline bool ep_process_param_dep(struct effect_parser *ep, - struct ep_func *func) + struct ep_func *func) { struct ep_param *val = ep_getparam_strref(ep, &ep->cfp.cur_token->str); if (val) @@ -828,7 +846,7 @@ static inline bool ep_process_param_dep(struct effect_parser *ep, } static inline bool ep_parse_func_contents(struct effect_parser *ep, - struct ep_func *func) + struct ep_func *func) { int braces = 1; @@ -844,10 +862,10 @@ static inline bool ep_parse_func_contents(struct effect_parser *ep, braces++; } else if (cf_token_is(&ep->cfp, "}")) { braces--; - } else if (ep_process_struct_dep(ep, func) || - ep_process_func_dep(ep, func) || - ep_process_sampler_dep(ep, func) || - ep_process_param_dep(ep, func)) { + } else if (ep_process_struct_dep(ep, func) || + ep_process_func_dep(ep, func) || + ep_process_sampler_dep(ep, func) || + ep_process_param_dep(ep, func)) { } dstr_cat_strref(&func->contents, &ep->cfp.cur_token->str); @@ -856,8 +874,7 @@ static inline bool ep_parse_func_contents(struct effect_parser *ep, return true; } -static void ep_parse_function(struct effect_parser *ep, - char *type, char *name) +static void ep_parse_function(struct effect_parser *ep, char *type, char *name) { struct ep_func func; int code; @@ -875,7 +892,7 @@ static void ep_parse_function(struct effect_parser *ep, /* if function is mapped to something, for example COLOR */ if (cf_token_is(&ep->cfp, ":")) { code = cf_next_name(&ep->cfp, &func.mapping, - "mapping specifier", "{"); + "mapping specifier", "{"); if (code == PARSE_EOF) goto error; else if (code != PARSE_CONTINUE) { @@ -904,17 +921,18 @@ error: /* parses "array[count]" */ static bool ep_parse_param_array(struct effect_parser *ep, - struct ep_param *param) + struct ep_param *param) { if (!cf_next_valid_token(&ep->cfp)) return false; if (ep->cfp.cur_token->type != CFTOKEN_NUM || !valid_int_str(ep->cfp.cur_token->str.array, - ep->cfp.cur_token->str.len)) + ep->cfp.cur_token->str.len)) return false; - param->array_count =(int)strtol(ep->cfp.cur_token->str.array, NULL, 10); + param->array_count = + (int)strtol(ep->cfp.cur_token->str.array, NULL, 10); if (cf_next_token_should_be(&ep->cfp, "]", ";", NULL) == PARSE_EOF) return false; @@ -926,7 +944,7 @@ static bool ep_parse_param_array(struct effect_parser *ep, } static inline int ep_parse_param_assign_texture(struct effect_parser *ep, - struct ep_param *param) + struct ep_param *param) { int code; char *str; @@ -934,13 +952,13 @@ static inline int ep_parse_param_assign_texture(struct effect_parser *ep, if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; - code = cf_token_is_type(&ep->cfp, CFTOKEN_STRING, - "texture path string", ";"); + code = cf_token_is_type(&ep->cfp, CFTOKEN_STRING, "texture path string", + ";"); if (code != PARSE_SUCCESS) return code; str = cf_literal_to_str(ep->cfp.cur_token->str.array, - ep->cfp.cur_token->str.len); + ep->cfp.cur_token->str.len); if (str) { da_copy_array(param->default_val, str, strlen(str) + 1); @@ -951,7 +969,7 @@ static inline int ep_parse_param_assign_texture(struct effect_parser *ep, } static inline int ep_parse_param_assign_string(struct effect_parser *ep, - struct ep_param *param) + struct ep_param *param) { int code; char *str = NULL; @@ -964,7 +982,7 @@ static inline int ep_parse_param_assign_string(struct effect_parser *ep, return code; str = cf_literal_to_str(ep->cfp.cur_token->str.array, - ep->cfp.cur_token->str.len); + ep->cfp.cur_token->str.len); if (str) { da_copy_array(param->default_val, str, strlen(str) + 1); @@ -975,7 +993,8 @@ static inline int ep_parse_param_assign_string(struct effect_parser *ep, } static inline int ep_parse_param_assign_intfloat(struct effect_parser *ep, - struct ep_param *param, bool is_float) + struct ep_param *param, + bool is_float) { int code; bool is_negative = false; @@ -996,11 +1015,13 @@ static inline int ep_parse_param_assign_intfloat(struct effect_parser *ep, if (is_float) { float f = (float)os_strtod(ep->cfp.cur_token->str.array); - if (is_negative) f = -f; + if (is_negative) + f = -f; da_push_back_array(param->default_val, &f, sizeof(float)); } else { long l = strtol(ep->cfp.cur_token->str.array, NULL, 10); - if (is_negative) l = -l; + if (is_negative) + l = -l; da_push_back_array(param->default_val, &l, sizeof(long)); } @@ -1008,7 +1029,7 @@ static inline int ep_parse_param_assign_intfloat(struct effect_parser *ep, } static inline int ep_parse_param_assign_bool(struct effect_parser *ep, - struct ep_param *param) + struct ep_param *param) { if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; @@ -1033,7 +1054,8 @@ static inline int ep_parse_param_assign_bool(struct effect_parser *ep, * and any combination for float3x3, float4x4, int3x3, int4x4, etc */ static inline int ep_parse_param_assign_intfloat_array(struct effect_parser *ep, - struct ep_param *param, bool is_float) + struct ep_param *param, + bool is_float) { const char *intfloat_type = param->type + (is_float ? 5 : 3); int intfloat_count = 0, code, i; @@ -1041,39 +1063,42 @@ static inline int ep_parse_param_assign_intfloat_array(struct effect_parser *ep, /* -------------------------------------------- */ if (intfloat_type[0] < '1' || intfloat_type[0] > '4') - cf_adderror(&ep->cfp, "Invalid row count", LEX_ERROR, - NULL, NULL, NULL); + cf_adderror(&ep->cfp, "Invalid row count", LEX_ERROR, NULL, + NULL, NULL); - intfloat_count = intfloat_type[0]-'0'; + intfloat_count = intfloat_type[0] - '0'; if (intfloat_type[1] == 'x') { if (intfloat_type[2] < '1' || intfloat_type[2] > '4') - cf_adderror(&ep->cfp, "Invalid column count", - LEX_ERROR, NULL, NULL, NULL); + cf_adderror(&ep->cfp, "Invalid column count", LEX_ERROR, + NULL, NULL, NULL); - intfloat_count *= intfloat_type[2]-'0'; + intfloat_count *= intfloat_type[2] - '0'; } /* -------------------------------------------- */ code = cf_next_token_should_be(&ep->cfp, "{", ";", NULL); - if (code != PARSE_SUCCESS) return code; + if (code != PARSE_SUCCESS) + return code; for (i = 0; i < intfloat_count; i++) { - char *next = ((i+1) < intfloat_count) ? "," : "}"; + char *next = ((i + 1) < intfloat_count) ? "," : "}"; code = ep_parse_param_assign_intfloat(ep, param, is_float); - if (code != PARSE_SUCCESS) return code; + if (code != PARSE_SUCCESS) + return code; code = cf_next_token_should_be(&ep->cfp, next, ";", NULL); - if (code != PARSE_SUCCESS) return code; + if (code != PARSE_SUCCESS) + return code; } return PARSE_SUCCESS; } static int ep_parse_param_assignment_val(struct effect_parser *ep, - struct ep_param *param) + struct ep_param *param) { if (param->is_texture) return ep_parse_param_assign_texture(ep, param); @@ -1091,13 +1116,13 @@ static int ep_parse_param_assignment_val(struct effect_parser *ep, return ep_parse_param_assign_bool(ep, param); cf_adderror(&ep->cfp, "Invalid type '$1' used for assignment", - LEX_ERROR, param->type, NULL, NULL); + LEX_ERROR, param->type, NULL, NULL); return PARSE_CONTINUE; } static inline bool ep_parse_param_assign(struct effect_parser *ep, - struct ep_param *param) + struct ep_param *param) { if (ep_parse_param_assignment_val(ep, param) != PARSE_SUCCESS) return false; @@ -1113,9 +1138,8 @@ static inline bool ep_parse_param_assign(struct effect_parser *ep, { } */ -static void ep_parse_param(struct effect_parser *ep, - char *type, char *name, - bool is_property, bool is_const, bool is_uniform) +static void ep_parse_param(struct effect_parser *ep, char *type, char *name, + bool is_property, bool is_const, bool is_uniform) { struct ep_param param; ep_param_init(¶m, type, name, is_property, is_const, is_uniform); @@ -1124,8 +1148,8 @@ static void ep_parse_param(struct effect_parser *ep, goto complete; if (cf_token_is(&ep->cfp, "[") && !ep_parse_param_array(ep, ¶m)) goto error; - if (cf_token_is(&ep->cfp, "<") && !ep_parse_param_annotations(ep, - ¶m)) + if (cf_token_is(&ep->cfp, "<") && + !ep_parse_param_annotations(ep, ¶m)) goto error; if (cf_token_is(&ep->cfp, "=") && !ep_parse_param_assign(ep, ¶m)) goto error; @@ -1143,10 +1167,10 @@ error: ep_param_free(¶m); } -static bool ep_get_var_specifiers(struct effect_parser *ep, - bool *is_property, bool *is_const, bool *is_uniform) +static bool ep_get_var_specifiers(struct effect_parser *ep, bool *is_property, + bool *is_const, bool *is_uniform) { - while(true) { + while (true) { int code; code = ep_check_for_keyword(ep, "property", is_property); if (code == PARSE_EOF) @@ -1173,12 +1197,13 @@ static bool ep_get_var_specifiers(struct effect_parser *ep, } static inline void report_invalid_func_keyword(struct effect_parser *ep, - const char *name, bool val) + const char *name, bool val) { if (val) - cf_adderror(&ep->cfp, "'$1' keyword cannot be used with a " - "function", LEX_ERROR, - name, NULL, NULL); + cf_adderror(&ep->cfp, + "'$1' keyword cannot be used with a " + "function", + LEX_ERROR, name, NULL, NULL); } static void ep_parse_other(struct effect_parser *ep) @@ -1198,14 +1223,14 @@ static void ep_parse_other(struct effect_parser *ep) if (cf_token_is(&ep->cfp, "(")) { report_invalid_func_keyword(ep, "property", is_property); - report_invalid_func_keyword(ep, "const", is_const); - report_invalid_func_keyword(ep, "uniform", is_uniform); + report_invalid_func_keyword(ep, "const", is_const); + report_invalid_func_keyword(ep, "uniform", is_uniform); ep_parse_function(ep, type, name); return; } else { ep_parse_param(ep, type, name, is_property, is_const, - is_uniform); + is_uniform); return; } @@ -1219,8 +1244,8 @@ static bool ep_compile(struct effect_parser *ep); extern const char *gs_preprocessor_name(void); #if defined(_DEBUG) && defined(_DEBUG_SHADERS) -static void debug_get_default_value(struct gs_effect_param *param, - char* buffer, unsigned long long buf_size) +static void debug_get_default_value(struct gs_effect_param *param, char *buffer, + unsigned long long buf_size) { if (param->default_val.num == 0) { snprintf(buffer, buf_size, "(null)"); @@ -1229,80 +1254,78 @@ static void debug_get_default_value(struct gs_effect_param *param, switch (param->type) { case GS_SHADER_PARAM_STRING: - snprintf(buffer, buf_size, "'%.*s'", - param->default_val.num, - param->default_val.array); + snprintf(buffer, buf_size, "'%.*s'", param->default_val.num, + param->default_val.array); break; case GS_SHADER_PARAM_INT: snprintf(buffer, buf_size, "%ld", - *(int*)(param->default_val.array + 0)); + *(int *)(param->default_val.array + 0)); break; case GS_SHADER_PARAM_INT2: snprintf(buffer, buf_size, "%ld,%ld", - *(int*)(param->default_val.array + 0), - *(int*)(param->default_val.array + 4)); + *(int *)(param->default_val.array + 0), + *(int *)(param->default_val.array + 4)); break; case GS_SHADER_PARAM_INT3: snprintf(buffer, buf_size, "%ld,%ld,%ld", - *(int*)(param->default_val.array + 0), - *(int*)(param->default_val.array + 4), - *(int*)(param->default_val.array + 8)); + *(int *)(param->default_val.array + 0), + *(int *)(param->default_val.array + 4), + *(int *)(param->default_val.array + 8)); break; case GS_SHADER_PARAM_INT4: snprintf(buffer, buf_size, "%ld,%ld,%ld,%ld", - *(int*)(param->default_val.array + 0), - *(int*)(param->default_val.array + 4), - *(int*)(param->default_val.array + 8), - *(int*)(param->default_val.array + 12)); + *(int *)(param->default_val.array + 0), + *(int *)(param->default_val.array + 4), + *(int *)(param->default_val.array + 8), + *(int *)(param->default_val.array + 12)); break; case GS_SHADER_PARAM_FLOAT: snprintf(buffer, buf_size, "%e", - *(float*)(param->default_val.array + 0)); + *(float *)(param->default_val.array + 0)); break; case GS_SHADER_PARAM_VEC2: snprintf(buffer, buf_size, "%e,%e", - *(float*)(param->default_val.array + 0), - *(float*)(param->default_val.array + 4)); + *(float *)(param->default_val.array + 0), + *(float *)(param->default_val.array + 4)); break; case GS_SHADER_PARAM_VEC3: snprintf(buffer, buf_size, "%e,%e,%e", - *(float*)(param->default_val.array + 0), - *(float*)(param->default_val.array + 4), - *(float*)(param->default_val.array + 8)); + *(float *)(param->default_val.array + 0), + *(float *)(param->default_val.array + 4), + *(float *)(param->default_val.array + 8)); break; case GS_SHADER_PARAM_VEC4: snprintf(buffer, buf_size, "%e,%e,%e,%e", - *(float*)(param->default_val.array + 0), - *(float*)(param->default_val.array + 4), - *(float*)(param->default_val.array + 8), - *(float*)(param->default_val.array + 12)); + *(float *)(param->default_val.array + 0), + *(float *)(param->default_val.array + 4), + *(float *)(param->default_val.array + 8), + *(float *)(param->default_val.array + 12)); break; case GS_SHADER_PARAM_MATRIX4X4: snprintf(buffer, buf_size, - "[[%e,%e,%e,%e],[%e,%e,%e,%e]," - "[%e,%e,%e,%e],[%e,%e,%e,%e]]", - *(float*)(param->default_val.array + 0), - *(float*)(param->default_val.array + 4), - *(float*)(param->default_val.array + 8), - *(float*)(param->default_val.array + 12), - *(float*)(param->default_val.array + 16), - *(float*)(param->default_val.array + 20), - *(float*)(param->default_val.array + 24), - *(float*)(param->default_val.array + 28), - *(float*)(param->default_val.array + 32), - *(float*)(param->default_val.array + 36), - *(float*)(param->default_val.array + 40), - *(float*)(param->default_val.array + 44), - *(float*)(param->default_val.array + 48), - *(float*)(param->default_val.array + 52), - *(float*)(param->default_val.array + 56), - *(float*)(param->default_val.array + 60)); + "[[%e,%e,%e,%e],[%e,%e,%e,%e]," + "[%e,%e,%e,%e],[%e,%e,%e,%e]]", + *(float *)(param->default_val.array + 0), + *(float *)(param->default_val.array + 4), + *(float *)(param->default_val.array + 8), + *(float *)(param->default_val.array + 12), + *(float *)(param->default_val.array + 16), + *(float *)(param->default_val.array + 20), + *(float *)(param->default_val.array + 24), + *(float *)(param->default_val.array + 28), + *(float *)(param->default_val.array + 32), + *(float *)(param->default_val.array + 36), + *(float *)(param->default_val.array + 40), + *(float *)(param->default_val.array + 44), + *(float *)(param->default_val.array + 48), + *(float *)(param->default_val.array + 52), + *(float *)(param->default_val.array + 56), + *(float *)(param->default_val.array + 60)); break; case GS_SHADER_PARAM_BOOL: snprintf(buffer, buf_size, "%s", - (*param->default_val.array) != 0 - ? "true\0" - : "false\0"); + (*param->default_val.array) != 0 ? "true\0" + : "false\0"); break; case GS_SHADER_PARAM_UNKNOWN: case GS_SHADER_PARAM_TEXTURE: @@ -1312,7 +1335,8 @@ static void debug_get_default_value(struct gs_effect_param *param, } static void debug_param(struct gs_effect_param *param, - struct ep_param *param_in, unsigned long long idx, const char* offset) + struct ep_param *param_in, unsigned long long idx, + const char *offset) { char _debug_type[4096]; switch (param->type) { @@ -1359,45 +1383,35 @@ static void debug_param(struct gs_effect_param *param, char _debug_buf[4096]; debug_get_default_value(param, _debug_buf, sizeof(_debug_buf)); - if (param->annotations.num > 0) { - blog(LOG_DEBUG, "%s[%4lld] %.*s '%s' with value %.*s and %lld annotations:", - offset, - idx, - sizeof(_debug_type), _debug_type, - param->name, - sizeof(_debug_buf), _debug_buf, - param->annotations.num); + if (param->annotations.num > 0) { + blog(LOG_DEBUG, + "%s[%4lld] %.*s '%s' with value %.*s and %lld annotations:", + offset, idx, sizeof(_debug_type), _debug_type, param->name, + sizeof(_debug_buf), _debug_buf, param->annotations.num); } else { - blog(LOG_DEBUG, "%s[%4lld] %.*s '%s' with value %.*s.", - offset, - idx, - sizeof(_debug_type), _debug_type, - param->name, - sizeof(_debug_buf), _debug_buf); + blog(LOG_DEBUG, "%s[%4lld] %.*s '%s' with value %.*s.", offset, + idx, sizeof(_debug_type), _debug_type, param->name, + sizeof(_debug_buf), _debug_buf); } - } static void debug_param_annotation(struct gs_effect_param *param, - struct ep_param *param_in, unsigned long long idx, const char* offset) + struct ep_param *param_in, + unsigned long long idx, const char *offset) { char _debug_buf[4096]; debug_get_default_value(param, _debug_buf, sizeof(_debug_buf)); - blog(LOG_DEBUG, "%s[%4lld] %s '%s' with value %.*s", - offset, - idx, - param_in->type, - param->name, - sizeof(_debug_buf), _debug_buf); + blog(LOG_DEBUG, "%s[%4lld] %s '%s' with value %.*s", offset, idx, + param_in->type, param->name, sizeof(_debug_buf), _debug_buf); } -static void debug_print_string(const char* offset, const char* str) +static void debug_print_string(const char *offset, const char *str) { // Bypass 4096 limit in def_log_handler. char const *begin = str; unsigned long long line = 1; for (char const *here = begin; here[0] != '\0'; here++) { - char const * str = begin; + char const *str = begin; unsigned long long len = here - begin; bool is_line = false; @@ -1413,20 +1427,20 @@ static void debug_print_string(const char* offset, const char* str) } if (is_line) { - blog(LOG_DEBUG, "\t\t\t\t[%4lld] %.*s", line, - len, str); + blog(LOG_DEBUG, "\t\t\t\t[%4lld] %.*s", line, len, str); line++; } } if (begin[0] != '\0') { // Final line was not written. - blog(LOG_DEBUG, "\t\t\t\t[%4lld] %*s", line, strlen(begin), begin); + blog(LOG_DEBUG, "\t\t\t\t[%4lld] %*s", line, strlen(begin), + begin); } } #endif bool ep_parse(struct effect_parser *ep, gs_effect_t *effect, - const char *effect_string, const char *file) + const char *effect_string, const char *file) { bool success; @@ -1437,7 +1451,7 @@ bool ep_parse(struct effect_parser *ep, gs_effect_t *effect, cf_def_init(&def); def.name.str.array = graphics_preprocessor; - def.name.str.len = strlen(graphics_preprocessor); + def.name.str.len = strlen(graphics_preprocessor); strref_copy(&def.name.unmerged_str, &def.name.str); cf_preprocessor_add_def(&ep->cfp.pp, &def); @@ -1465,7 +1479,7 @@ bool ep_parse(struct effect_parser *ep, gs_effect_t *effect, } else if (cf_token_is(&ep->cfp, "{")) { /* add error and pass braces */ cf_adderror(&ep->cfp, "Unexpected code segment", - LEX_ERROR, NULL, NULL, NULL); + LEX_ERROR, NULL, NULL, NULL); cf_pass_pair(&ep->cfp, '{', '}'); } else { @@ -1475,7 +1489,8 @@ bool ep_parse(struct effect_parser *ep, gs_effect_t *effect, } #if defined(_DEBUG) && defined(_DEBUG_SHADERS) - blog(LOG_DEBUG, "================================================================================"); + blog(LOG_DEBUG, + "================================================================================"); blog(LOG_DEBUG, "Effect Parser reformatted shader '%s' to:", file); debug_print_string("\t", ep->cfp.lex.reformatted); #endif @@ -1484,9 +1499,9 @@ bool ep_parse(struct effect_parser *ep, gs_effect_t *effect, if (success) success = ep_compile(ep); - #if defined(_DEBUG) && defined(_DEBUG_SHADERS) - blog(LOG_DEBUG, "================================================================================"); + blog(LOG_DEBUG, + "================================================================================"); #endif return success; @@ -1495,7 +1510,7 @@ bool ep_parse(struct effect_parser *ep, gs_effect_t *effect, /* ------------------------------------------------------------------------- */ static inline void ep_write_param(struct dstr *shader, struct ep_param *param, - struct darray *used_params) + struct darray *used_params) { if (param->written) return; @@ -1523,8 +1538,9 @@ static inline void ep_write_param(struct dstr *shader, struct ep_param *param, } static inline void ep_write_func_param_deps(struct effect_parser *ep, - struct dstr *shader, struct ep_func *func, - struct darray *used_params) + struct dstr *shader, + struct ep_func *func, + struct darray *used_params) { size_t i; for (i = 0; i < func->param_deps.num; i++) { @@ -1548,7 +1564,7 @@ static void ep_write_sampler(struct dstr *shader, struct ep_sampler *sampler) dstr_cat(shader, sampler->name); dstr_cat(shader, " {"); - for (i = 0; i values.num; i++) { + for (i = 0; i < sampler->values.num; i++) { dstr_cat(shader, "\n\t"); dstr_cat(shader, sampler->states.array[i]); dstr_cat(shader, " = "); @@ -1561,7 +1577,8 @@ static void ep_write_sampler(struct dstr *shader, struct ep_sampler *sampler) } static inline void ep_write_func_sampler_deps(struct effect_parser *ep, - struct dstr *shader, struct ep_func *func) + struct dstr *shader, + struct ep_func *func) { size_t i; for (i = 0; i < func->sampler_deps.num; i++) { @@ -1607,7 +1624,7 @@ static void ep_write_struct(struct dstr *shader, struct ep_struct *st) for (i = 0; i < st->vars.num; i++) { dstr_cat(shader, "\n\t"); - ep_write_var(shader, st->vars.array+i); + ep_write_var(shader, st->vars.array + i); dstr_cat(shader, ";"); } @@ -1616,7 +1633,8 @@ static void ep_write_struct(struct dstr *shader, struct ep_struct *st) } static inline void ep_write_func_struct_deps(struct effect_parser *ep, - struct dstr *shader, struct ep_func *func) + struct dstr *shader, + struct ep_func *func) { size_t i; for (i = 0; i < func->struct_deps.num; i++) { @@ -1632,11 +1650,12 @@ static inline void ep_write_func_struct_deps(struct effect_parser *ep, } static void ep_write_func(struct effect_parser *ep, struct dstr *shader, - struct ep_func *func, struct darray *used_params); + struct ep_func *func, struct darray *used_params); static inline void ep_write_func_func_deps(struct effect_parser *ep, - struct dstr *shader, struct ep_func *func, - struct darray *used_params) + struct dstr *shader, + struct ep_func *func, + struct darray *used_params) { size_t i; for (i = 0; i < func->func_deps.num; i++) { @@ -1651,12 +1670,12 @@ static inline void ep_write_func_func_deps(struct effect_parser *ep, } static void ep_write_func(struct effect_parser *ep, struct dstr *shader, - struct ep_func *func, struct darray *used_params) + struct ep_func *func, struct darray *used_params) { size_t i; func->written = true; - + ep_write_func_param_deps(ep, shader, func, used_params); ep_write_func_sampler_deps(ep, shader, func); ep_write_func_struct_deps(ep, shader, func); @@ -1670,7 +1689,7 @@ static void ep_write_func(struct effect_parser *ep, struct dstr *shader, dstr_cat(shader, "("); for (i = 0; i < func->param_vars.num; i++) { - struct ep_var *var = func->param_vars.array+i; + struct ep_var *var = func->param_vars.array + i; if (i) dstr_cat(shader, ", "); @@ -1683,15 +1702,14 @@ static void ep_write_func(struct effect_parser *ep, struct dstr *shader, } /* writes mapped vars used by the call as parameters for main */ -static void ep_write_main_params(struct effect_parser *ep, - struct dstr *shader, struct dstr *param_str, - struct ep_func *func) +static void ep_write_main_params(struct effect_parser *ep, struct dstr *shader, + struct dstr *param_str, struct ep_func *func) { size_t i; bool empty_params = dstr_is_empty(param_str); for (i = 0; i < func->param_vars.num; i++) { - struct ep_var *var = func->param_vars.array+i; + struct ep_var *var = func->param_vars.array + i; struct ep_struct *st = NULL; bool mapped = (var->mapping != NULL); @@ -1722,7 +1740,7 @@ static void ep_write_main_params(struct effect_parser *ep, } static void ep_write_main(struct effect_parser *ep, struct dstr *shader, - struct ep_func *func, struct dstr *call_str) + struct ep_func *func, struct dstr *call_str) { struct dstr param_str; struct dstr adjusted_call; @@ -1753,19 +1771,19 @@ static void ep_write_main(struct effect_parser *ep, struct dstr *shader, static inline void ep_reset_written(struct effect_parser *ep) { size_t i; - for (i = 0; i params.num; i++) + for (i = 0; i < ep->params.num; i++) ep->params.array[i].written = false; - for (i = 0; i structs.num; i++) + for (i = 0; i < ep->structs.num; i++) ep->structs.array[i].written = false; - for (i = 0; i funcs.num; i++) + for (i = 0; i < ep->funcs.num; i++) ep->funcs.array[i].written = false; - for (i = 0; i samplers.num; i++) + for (i = 0; i < ep->samplers.num; i++) ep->samplers.array[i].written = false; } -static void ep_makeshaderstring(struct effect_parser *ep, - struct dstr *shader, struct darray *shader_call, - struct darray *used_params) +static void ep_makeshaderstring(struct effect_parser *ep, struct dstr *shader, + struct darray *shader_call, + struct darray *used_params) { struct cf_token *token = shader_call->array; struct cf_token *func_name; @@ -1780,8 +1798,7 @@ static void ep_makeshaderstring(struct effect_parser *ep, while (token->type != CFTOKEN_NONE && is_whitespace(*token->str.array)) token++; - if (token->type == CFTOKEN_NONE || - strref_cmp(&token->str, "NULL") == 0) + if (token->type == CFTOKEN_NONE || strref_cmp(&token->str, "NULL") == 0) return; func_name = token; @@ -1808,17 +1825,18 @@ static void ep_makeshaderstring(struct effect_parser *ep, } static void ep_compile_annotations(struct darray *ep_annotations, - struct darray *gsp_annotations, struct effect_parser *ep) + struct darray *gsp_annotations, + struct effect_parser *ep) { - darray_resize(sizeof(struct gs_effect_param), - gsp_annotations, ep_annotations->num); + darray_resize(sizeof(struct gs_effect_param), gsp_annotations, + ep_annotations->num); size_t i; for (i = 0; i < ep_annotations->num; i++) { - struct gs_effect_param *param = ((struct gs_effect_param *) - gsp_annotations->array)+i; - struct ep_param *param_in = ((struct ep_param *) - ep_annotations->array)+i; + struct gs_effect_param *param = + ((struct gs_effect_param *)gsp_annotations->array) + i; + struct ep_param *param_in = + ((struct ep_param *)ep_annotations->array) + i; param->name = bstrdup(param_in->name); param->section = EFFECT_ANNOTATION; @@ -1833,11 +1851,13 @@ static void ep_compile_annotations(struct darray *ep_annotations, } } -static void ep_compile_param_annotations(struct ep_param *ep_param_input, - struct gs_effect_param *gs_effect_input, struct effect_parser *ep) +static void +ep_compile_param_annotations(struct ep_param *ep_param_input, + struct gs_effect_param *gs_effect_input, + struct effect_parser *ep) { ep_compile_annotations(&(ep_param_input->annotations.da), - &(gs_effect_input->annotations.da), ep); + &(gs_effect_input->annotations.da), ep); } static void ep_compile_param(struct effect_parser *ep, size_t idx) @@ -1845,13 +1865,13 @@ static void ep_compile_param(struct effect_parser *ep, size_t idx) struct gs_effect_param *param; struct ep_param *param_in; - param = ep->effect->params.array+idx; - param_in = ep->params.array+idx; + param = ep->effect->params.array + idx; + param_in = ep->params.array + idx; param_in->param = param; - param->name = bstrdup(param_in->name); + param->name = bstrdup(param_in->name); param->section = EFFECT_PARAM; - param->effect = ep->effect; + param->effect = ep->effect; da_move(param->default_val, param_in->default_val); param->type = get_effect_param_type(param_in->type); @@ -1869,12 +1889,13 @@ static void ep_compile_param(struct effect_parser *ep, size_t idx) } static bool ep_compile_pass_shaderparams(struct effect_parser *ep, - struct darray *pass_params, struct darray *used_params, - gs_shader_t *shader) + struct darray *pass_params, + struct darray *used_params, + gs_shader_t *shader) { size_t i; darray_resize(sizeof(struct pass_shaderparam), pass_params, - used_params->num); + used_params->num); for (i = 0; i < pass_params->num; i++) { struct dstr *param_name; @@ -1882,12 +1903,12 @@ static bool ep_compile_pass_shaderparams(struct effect_parser *ep, param_name = darray_item(sizeof(struct dstr), used_params, i); param = darray_item(sizeof(struct pass_shaderparam), - pass_params, i); + pass_params, i); param->eparam = gs_effect_get_param_by_name(ep->effect, - param_name->array); - param->sparam = gs_shader_get_param_by_name(shader, - param_name->array); + param_name->array); + param->sparam = + gs_shader_get_param_by_name(shader, param_name->array); #if defined(_DEBUG) && defined(_DEBUG_SHADERS) debug_param(param->eparam, 0, i, "\t\t\t\t"); @@ -1903,13 +1924,15 @@ static bool ep_compile_pass_shaderparams(struct effect_parser *ep, } static inline bool ep_compile_pass_shader(struct effect_parser *ep, - struct gs_effect_technique *tech, - struct gs_effect_pass *pass, struct ep_pass *pass_in, - size_t pass_idx, enum gs_shader_type type) + struct gs_effect_technique *tech, + struct gs_effect_pass *pass, + struct ep_pass *pass_in, + size_t pass_idx, + enum gs_shader_type type) { struct dstr shader_str; struct dstr location; - struct darray used_params; /* struct dstr */ + struct darray used_params; /* struct dstr */ struct darray *pass_params = NULL; /* struct pass_shaderparam */ gs_shader_t *shader = NULL; bool success = true; @@ -1928,24 +1951,24 @@ static inline bool ep_compile_pass_shader(struct effect_parser *ep, assert(pass_idx <= UINT_MAX); dstr_catf(&location, "shader, technique %s, pass %u)", tech->name, - (unsigned)pass_idx); + (unsigned)pass_idx); if (type == GS_SHADER_VERTEX) { ep_makeshaderstring(ep, &shader_str, - &pass_in->vertex_program.da, &used_params); + &pass_in->vertex_program.da, &used_params); pass->vertshader = gs_vertexshader_create(shader_str.array, - location.array, NULL); - + location.array, NULL); shader = pass->vertshader; pass_params = &pass->vertshader_params.da; } else if (type == GS_SHADER_PIXEL) { ep_makeshaderstring(ep, &shader_str, - &pass_in->fragment_program.da, &used_params); + &pass_in->fragment_program.da, + &used_params); pass->pixelshader = gs_pixelshader_create(shader_str.array, - location.array, NULL); + location.array, NULL); shader = pass->pixelshader; pass_params = &pass->pixelshader_params.da; @@ -1953,7 +1976,7 @@ static inline bool ep_compile_pass_shader(struct effect_parser *ep, #if defined(_DEBUG) && defined(_DEBUG_SHADERS) blog(LOG_DEBUG, "\t\t\t%s Shader:", - type == GS_SHADER_VERTEX ? "Vertex" : "Fragment"); + type == GS_SHADER_VERTEX ? "Vertex" : "Fragment"); blog(LOG_DEBUG, "\t\t\tCode:"); debug_print_string("\t\t\t\t\t", shader_str.array); blog(LOG_DEBUG, "\t\t\tParameters:"); @@ -1961,7 +1984,7 @@ static inline bool ep_compile_pass_shader(struct effect_parser *ep, if (shader) success = ep_compile_pass_shaderparams(ep, pass_params, - &used_params, shader); + &used_params, shader); else success = false; @@ -1974,36 +1997,34 @@ static inline bool ep_compile_pass_shader(struct effect_parser *ep, } static bool ep_compile_pass(struct effect_parser *ep, - struct gs_effect_technique *tech, - struct ep_technique *tech_in, - size_t idx) + struct gs_effect_technique *tech, + struct ep_technique *tech_in, size_t idx) { struct gs_effect_pass *pass; struct ep_pass *pass_in; bool success = true; - pass = tech->passes.array+idx; - pass_in = tech_in->passes.array+idx; + pass = tech->passes.array + idx; + pass_in = tech_in->passes.array + idx; pass->name = bstrdup(pass_in->name); pass->section = EFFECT_PASS; #if defined(_DEBUG) && defined(_DEBUG_SHADERS) - blog(LOG_DEBUG, "\t\t[%4lld] Pass '%s':", - idx, pass->name); + blog(LOG_DEBUG, "\t\t[%4lld] Pass '%s':", idx, pass->name); #endif if (!ep_compile_pass_shader(ep, tech, pass, pass_in, idx, - GS_SHADER_VERTEX)) { + GS_SHADER_VERTEX)) { success = false; - blog(LOG_ERROR, "Pass (%zu) <%s> missing vertex shader!", - idx, pass->name ? pass->name : ""); + blog(LOG_ERROR, "Pass (%zu) <%s> missing vertex shader!", idx, + pass->name ? pass->name : ""); } if (!ep_compile_pass_shader(ep, tech, pass, pass_in, idx, - GS_SHADER_PIXEL)) { + GS_SHADER_PIXEL)) { success = false; - blog(LOG_ERROR, "Pass (%zu) <%s> missing pixel shader!", - idx, pass->name ? pass->name : ""); + blog(LOG_ERROR, "Pass (%zu) <%s> missing pixel shader!", idx, + pass->name ? pass->name : ""); } return success; } @@ -2015,8 +2036,8 @@ static inline bool ep_compile_technique(struct effect_parser *ep, size_t idx) bool success = true; size_t i; - tech = ep->effect->techniques.array+idx; - tech_in = ep->techniques.array+idx; + tech = ep->effect->techniques.array + idx; + tech_in = ep->techniques.array + idx; tech->name = bstrdup(tech_in->name); tech->section = EFFECT_TECHNIQUE; @@ -2025,8 +2046,8 @@ static inline bool ep_compile_technique(struct effect_parser *ep, size_t idx) da_resize(tech->passes, tech_in->passes.num); #if defined(_DEBUG) && defined(_DEBUG_SHADERS) - blog(LOG_DEBUG, "\t[%4lld] Technique '%s' has %lld passes:", - idx, tech->name, tech->passes.num); + blog(LOG_DEBUG, "\t[%4lld] Technique '%s' has %lld passes:", idx, + tech->name, tech->passes.num); #endif for (i = 0; i < tech->passes.num; i++) { diff --git a/libobs/graphics/effect-parser.h b/libobs/graphics/effect-parser.h index 1281399..1c6000c 100644 --- a/libobs/graphics/effect-parser.h +++ b/libobs/graphics/effect-parser.h @@ -67,9 +67,9 @@ static inline void ep_var_free(struct ep_var *epv) /* effect parser param data */ struct ep_param { - char *type, *name; - DARRAY(uint8_t) default_val; - DARRAY(char*) properties; + char *type, *name; + DARRAY(uint8_t) default_val; + DARRAY(char *) properties; struct gs_effect_param *param; bool is_const, is_property, is_uniform, is_texture, written; int writeorder, array_count; @@ -78,18 +78,18 @@ struct ep_param { extern void ep_param_writevar(struct dstr *dst, struct darray *use_params); -static inline void ep_param_init(struct ep_param *epp, - char *type, char *name, - bool is_property, bool is_const, bool is_uniform) +static inline void ep_param_init(struct ep_param *epp, char *type, char *name, + bool is_property, bool is_const, + bool is_uniform) { - epp->type = type; - epp->name = name; + epp->type = type; + epp->name = name; epp->is_property = is_property; - epp->is_const = is_const; - epp->is_uniform = is_uniform; - epp->is_texture = (astrcmp_n(epp->type, "texture", 7) == 0); - epp->written = false; - epp->writeorder = false; + epp->is_const = is_const; + epp->is_uniform = is_uniform; + epp->is_texture = (astrcmp_n(epp->type, "texture", 7) == 0); + epp->written = false; + epp->writeorder = false; epp->array_count = 0; da_init(epp->default_val); da_init(epp->properties); @@ -136,7 +136,7 @@ static inline void ep_struct_free(struct ep_struct *eps) bfree(eps->name); for (i = 0; i < eps->vars.num; i++) - ep_var_free(eps->vars.array+i); + ep_var_free(eps->vars.array + i); da_free(eps->vars); } @@ -145,8 +145,8 @@ static inline void ep_struct_free(struct ep_struct *eps) struct ep_sampler { char *name; - DARRAY(char*) states; - DARRAY(char*) values; + DARRAY(char *) states; + DARRAY(char *) values; bool written; }; @@ -210,7 +210,7 @@ static inline void ep_technique_free(struct ep_technique *ept) size_t i; for (i = 0; i < ept->passes.num; i++) - ep_pass_free(ept->passes.array+i); + ep_pass_free(ept->passes.array + i); bfree(ept->name); da_free(ept->passes); @@ -223,18 +223,17 @@ struct ep_func { char *name, *ret_type, *mapping; struct dstr contents; DARRAY(struct ep_var) param_vars; - DARRAY(const char*) func_deps; - DARRAY(const char*) struct_deps; - DARRAY(const char*) param_deps; - DARRAY(const char*) sampler_deps; + DARRAY(const char *) func_deps; + DARRAY(const char *) struct_deps; + DARRAY(const char *) param_deps; + DARRAY(const char *) sampler_deps; bool written; }; -static inline void ep_func_init(struct ep_func *epf, char *ret_type, - char *name) +static inline void ep_func_init(struct ep_func *epf, char *ret_type, char *name) { memset(epf, 0, sizeof(struct ep_func)); - epf->name = name; + epf->name = name; epf->ret_type = ret_type; } @@ -242,7 +241,7 @@ static inline void ep_func_free(struct ep_func *epf) { size_t i; for (i = 0; i < epf->param_vars.num; i++) - ep_var_free(epf->param_vars.array+i); + ep_var_free(epf->param_vars.array + i); bfree(epf->name); bfree(epf->ret_type); @@ -260,10 +259,10 @@ static inline void ep_func_free(struct ep_func *epf) struct effect_parser { gs_effect_t *effect; - DARRAY(struct ep_param) params; - DARRAY(struct ep_struct) structs; - DARRAY(struct ep_func) funcs; - DARRAY(struct ep_sampler) samplers; + DARRAY(struct ep_param) params; + DARRAY(struct ep_struct) structs; + DARRAY(struct ep_func) funcs; + DARRAY(struct ep_sampler) samplers; DARRAY(struct ep_technique) techniques; /* internal vars */ @@ -291,7 +290,7 @@ static inline void ep_init(struct effect_parser *ep) extern void ep_free(struct effect_parser *ep); extern bool ep_parse(struct effect_parser *ep, gs_effect_t *effect, - const char *effect_string, const char *file); + const char *effect_string, const char *file); #ifdef __cplusplus } diff --git a/libobs/graphics/effect.c b/libobs/graphics/effect.c index ddd5d5a..4425dbf 100644 --- a/libobs/graphics/effect.c +++ b/libobs/graphics/effect.c @@ -36,12 +36,13 @@ void gs_effect_destroy(gs_effect_t *effect) } gs_technique_t *gs_effect_get_technique(const gs_effect_t *effect, - const char *name) + const char *name) { - if (!effect) return NULL; + if (!effect) + return NULL; for (size_t i = 0; i < effect->techniques.num; i++) { - struct gs_effect_technique *tech = effect->techniques.array+i; + struct gs_effect_technique *tech = effect->techniques.array + i; if (strcmp(tech->name, name) == 0) return tech; } @@ -51,7 +52,8 @@ gs_technique_t *gs_effect_get_technique(const gs_effect_t *effect, gs_technique_t *gs_effect_get_current_technique(const gs_effect_t *effect) { - if (!effect) return NULL; + if (!effect) + return NULL; return effect->cur_technique; } @@ -67,14 +69,16 @@ bool gs_effect_loop(gs_effect_t *effect, const char *name) if (!!gs_get_effect()) { blog(LOG_WARNING, "gs_effect_loop: An effect is " - "already active"); + "already active"); return false; } tech = gs_effect_get_technique(effect, name); if (!tech) { - blog(LOG_WARNING, "gs_effect_loop: Technique '%s' " - "not found.", name); + blog(LOG_WARNING, + "gs_effect_loop: Technique '%s' " + "not found.", + name); return false; } @@ -86,7 +90,7 @@ bool gs_effect_loop(gs_effect_t *effect, const char *name) } if (!gs_technique_begin_pass(effect->cur_technique, - effect->loop_pass++)) { + effect->loop_pass++)) { gs_technique_end(effect->cur_technique); effect->looping = false; effect->loop_pass = 0; @@ -98,7 +102,8 @@ bool gs_effect_loop(gs_effect_t *effect, const char *name) size_t gs_technique_begin(gs_technique_t *tech) { - if (!tech) return 0; + if (!tech) + return 0; tech->effect->cur_technique = tech; tech->effect->graphics->cur_effect = tech->effect; @@ -108,7 +113,8 @@ size_t gs_technique_begin(gs_technique_t *tech) void gs_technique_end(gs_technique_t *tech) { - if (!tech) return; + if (!tech) + return; struct gs_effect *effect = tech->effect; struct gs_effect_param *params = effect->params.array; @@ -121,7 +127,7 @@ void gs_technique_end(gs_technique_t *tech) tech->effect->graphics->cur_effect = NULL; for (i = 0; i < effect->params.num; i++) { - struct gs_effect_param *param = params+i; + struct gs_effect_param *param = params + i; da_free(param->cur_val); param->changed = false; @@ -145,12 +151,13 @@ static void upload_shader_params(struct darray *pass_params, bool changed_only) size_t i; for (i = 0; i < pass_params->num; i++) { - struct pass_shaderparam *param = params+i; + struct pass_shaderparam *param = params + i; struct gs_effect_param *eparam = param->eparam; gs_sparam_t *sparam = param->sparam; if (eparam->next_sampler) - gs_shader_set_next_sampler(sparam, eparam->next_sampler); + gs_shader_set_next_sampler(sparam, + eparam->next_sampler); if (changed_only && !eparam->changed) continue; @@ -163,12 +170,12 @@ static void upload_shader_params(struct darray *pass_params, bool changed_only) } gs_shader_set_val(sparam, eparam->cur_val.array, - eparam->cur_val.num); + eparam->cur_val.num); } } static inline void upload_parameters(struct gs_effect *effect, - bool changed_only) + bool changed_only) { struct darray *vshader_params, *pshader_params; @@ -184,7 +191,7 @@ static inline void upload_parameters(struct gs_effect *effect, reset_params(pshader_params); } -void gs_effect_update_params(gs_effect_t *effect) +void gs_effect_update_params(gs_effect_t *effect) { if (effect) upload_parameters(effect, true); @@ -199,7 +206,7 @@ bool gs_technique_begin_pass(gs_technique_t *tech, size_t idx) return false; passes = tech->passes.array; - cur_pass = passes+idx; + cur_pass = passes + idx; tech->effect->cur_pass = cur_pass; gs_load_vertexshader(cur_pass->vertshader); @@ -209,14 +216,13 @@ bool gs_technique_begin_pass(gs_technique_t *tech, size_t idx) return true; } -bool gs_technique_begin_pass_by_name(gs_technique_t *tech, - const char *name) +bool gs_technique_begin_pass_by_name(gs_technique_t *tech, const char *name) { if (!tech) return false; for (size_t i = 0; i < tech->passes.num; i++) { - struct gs_effect_pass *pass = tech->passes.array+i; + struct gs_effect_pass *pass = tech->passes.array + i; if (strcmp(pass->name, name) == 0) { gs_technique_begin_pass(tech, i); return true; @@ -231,7 +237,7 @@ static inline void clear_tex_params(struct darray *in_params) struct pass_shaderparam *params = in_params->array; for (size_t i = 0; i < in_params->num; i++) { - struct pass_shaderparam *param = params+i; + struct pass_shaderparam *param = params + i; struct gs_shader_param_info info; gs_shader_get_param_info(param->sparam, &info); @@ -242,7 +248,8 @@ static inline void clear_tex_params(struct darray *in_params) void gs_technique_end_pass(gs_technique_t *tech) { - if (!tech) return; + if (!tech) + return; struct gs_effect_pass *pass = tech->effect->cur_pass; if (!pass) @@ -260,24 +267,26 @@ size_t gs_effect_get_num_params(const gs_effect_t *effect) gs_eparam_t *gs_effect_get_param_by_idx(const gs_effect_t *effect, size_t param) { - if (!effect) return NULL; + if (!effect) + return NULL; struct gs_effect_param *params = effect->params.array; if (param >= effect->params.num) return NULL; - return params+param; + return params + param; } gs_eparam_t *gs_effect_get_param_by_name(const gs_effect_t *effect, - const char *name) + const char *name) { - if (!effect) return NULL; + if (!effect) + return NULL; struct gs_effect_param *params = effect->params.array; for (size_t i = 0; i < effect->params.num; i++) { - struct gs_effect_param *param = params+i; + struct gs_effect_param *param = params + i; if (strcmp(param->name, name) == 0) return param; @@ -292,10 +301,11 @@ size_t gs_param_get_num_annotations(const gs_eparam_t *param) } gs_eparam_t *gs_param_get_annotation_by_idx(const gs_eparam_t *param, - size_t annotation) + size_t annotation) { - if (!param) return NULL; - + if (!param) + return NULL; + struct gs_effect_param *params = param->annotations.array; if (annotation > param->annotations.num) return NULL; @@ -304,9 +314,10 @@ gs_eparam_t *gs_param_get_annotation_by_idx(const gs_eparam_t *param, } gs_eparam_t *gs_param_get_annotation_by_name(const gs_eparam_t *param, - const char *name) + const char *name) { - if (!param) return NULL; + if (!param) + return NULL; struct gs_effect_param *params = param->annotations.array; for (size_t i = 0; i < param->annotations.num; i++) { @@ -318,9 +329,10 @@ gs_eparam_t *gs_param_get_annotation_by_name(const gs_eparam_t *param, } gs_epass_t *gs_technique_get_pass_by_idx(const gs_technique_t *technique, - size_t pass) + size_t pass) { - if (!technique) return NULL; + if (!technique) + return NULL; struct gs_effect_pass *passes = technique->passes.array; if (pass > technique->passes.num) @@ -330,9 +342,10 @@ gs_epass_t *gs_technique_get_pass_by_idx(const gs_technique_t *technique, } gs_epass_t *gs_technique_get_pass_by_name(const gs_technique_t *technique, - const char *name) + const char *name) { - if (!technique) return NULL; + if (!technique) + return NULL; struct gs_effect_pass *passes = technique->passes.array; for (size_t i = 0; i < technique->passes.num; i++) { @@ -354,7 +367,7 @@ gs_eparam_t *gs_effect_get_world_matrix(const gs_effect_t *effect) } void gs_effect_get_param_info(const gs_eparam_t *param, - struct gs_effect_param_info *info) + struct gs_effect_param_info *info) { if (!param) return; @@ -363,8 +376,8 @@ void gs_effect_get_param_info(const gs_eparam_t *param, info->type = param->type; } -static inline void effect_setval_inline(gs_eparam_t *param, - const void *data, size_t size) +static inline void effect_setval_inline(gs_eparam_t *param, const void *data, + size_t size) { bool size_changed; @@ -390,10 +403,10 @@ static inline void effect_setval_inline(gs_eparam_t *param, } #ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) +#define min(a, b) (((a) < (b)) ? (a) : (b)) #endif static inline void effect_getval_inline(gs_eparam_t *param, void *data, - size_t size) + size_t size) { if (!param) { blog(LOG_ERROR, "effect_getval_inline: invalid param"); @@ -411,7 +424,7 @@ static inline void effect_getval_inline(gs_eparam_t *param, void *data, } static inline void effect_getdefaultval_inline(gs_eparam_t *param, void *data, - size_t size) + size_t size) { if (!param) { blog(LOG_ERROR, "effect_getdefaultval_inline: invalid param"); @@ -473,7 +486,7 @@ void gs_effect_set_color(gs_eparam_t *param, uint32_t argb) void gs_effect_set_texture(gs_eparam_t *param, gs_texture_t *val) { - effect_setval_inline(param, &val, sizeof(gs_texture_t*)); + effect_setval_inline(param, &val, sizeof(gs_texture_t *)); } void gs_effect_set_val(gs_eparam_t *param, const void *val, size_t size) @@ -491,7 +504,7 @@ void *gs_effect_get_val(gs_eparam_t *param) void *data; if (size) - data = (void*)bzalloc(size); + data = (void *)bzalloc(size); else return NULL; @@ -515,7 +528,7 @@ void *gs_effect_get_default_val(gs_eparam_t *param) void *data; if (size) - data = (void*)bzalloc(size); + data = (void *)bzalloc(size); else return NULL; @@ -532,7 +545,7 @@ size_t gs_effect_get_default_val_size(gs_eparam_t *param) void gs_effect_set_default(gs_eparam_t *param) { effect_setval_inline(param, param->default_val.array, - param->default_val.num); + param->default_val.num); } void gs_effect_set_next_sampler(gs_eparam_t *param, gs_samplerstate_t *sampler) diff --git a/libobs/graphics/effect.h b/libobs/graphics/effect.h index 9a86868..6aae0ce 100644 --- a/libobs/graphics/effect.h +++ b/libobs/graphics/effect.h @@ -86,7 +86,7 @@ static inline void effect_param_free(struct gs_effect_param *param) } EXPORT void effect_param_parse_property(gs_eparam_t *param, - const char *property); + const char *property); /* ------------------------------------------------------------------------- */ @@ -139,7 +139,7 @@ static inline void effect_technique_free(struct gs_effect_technique *t) { size_t i; for (i = 0; i < t->passes.num; i++) - effect_pass_free(t->passes.array+i); + effect_pass_free(t->passes.array + i); da_free(t->passes); bfree(t->name); @@ -176,9 +176,9 @@ static inline void effect_free(gs_effect_t *effect) { size_t i; for (i = 0; i < effect->params.num; i++) - effect_param_free(effect->params.array+i); + effect_param_free(effect->params.array + i); for (i = 0; i < effect->techniques.num; i++) - effect_technique_free(effect->techniques.array+i); + effect_technique_free(effect->techniques.array + i); da_free(effect->params); da_free(effect->techniques); @@ -191,8 +191,9 @@ static inline void effect_free(gs_effect_t *effect) EXPORT void effect_upload_params(gs_effect_t *effect, bool changed_only); EXPORT void effect_upload_shader_params(gs_effect_t *effect, - gs_shader_t *shader, struct darray *pass_params, - bool changed_only); + gs_shader_t *shader, + struct darray *pass_params, + bool changed_only); #ifdef __cplusplus } diff --git a/libobs/graphics/graphics-ffmpeg.c b/libobs/graphics/graphics-ffmpeg.c index cbad19b..5b2e0fb 100644 --- a/libobs/graphics/graphics-ffmpeg.c +++ b/libobs/graphics/graphics-ffmpeg.c @@ -7,42 +7,44 @@ #include "../obs-ffmpeg-compat.h" struct ffmpeg_image { - const char *file; - AVFormatContext *fmt_ctx; - AVCodecContext *decoder_ctx; - AVCodec *decoder; - AVStream *stream; - int stream_idx; + const char *file; + AVFormatContext *fmt_ctx; + AVCodecContext *decoder_ctx; + AVCodec *decoder; + AVStream *stream; + int stream_idx; - int cx, cy; + int cx, cy; enum AVPixelFormat format; }; static bool ffmpeg_image_open_decoder_context(struct ffmpeg_image *info) { - int ret = av_find_best_stream(info->fmt_ctx, AVMEDIA_TYPE_VIDEO, - -1, 1, NULL, 0); + int ret = av_find_best_stream(info->fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, 1, + NULL, 0); if (ret < 0) { blog(LOG_WARNING, "Couldn't find video stream in file '%s': %s", - info->file, av_err2str(ret)); + info->file, av_err2str(ret)); return false; } - info->stream_idx = ret; - info->stream = info->fmt_ctx->streams[ret]; + info->stream_idx = ret; + info->stream = info->fmt_ctx->streams[ret]; info->decoder_ctx = info->stream->codec; - info->decoder = avcodec_find_decoder(info->decoder_ctx->codec_id); + info->decoder = avcodec_find_decoder(info->decoder_ctx->codec_id); if (!info->decoder) { blog(LOG_WARNING, "Failed to find decoder for file '%s'", - info->file); + info->file); return false; } ret = avcodec_open2(info->decoder_ctx, info->decoder, NULL); if (ret < 0) { - blog(LOG_WARNING, "Failed to open video codec for file '%s': " - "%s", info->file, av_err2str(ret)); + blog(LOG_WARNING, + "Failed to open video codec for file '%s': " + "%s", + info->file, av_err2str(ret)); return false; } @@ -63,28 +65,30 @@ static bool ffmpeg_image_init(struct ffmpeg_image *info, const char *file) return false; memset(info, 0, sizeof(struct ffmpeg_image)); - info->file = file; + info->file = file; info->stream_idx = -1; ret = avformat_open_input(&info->fmt_ctx, file, NULL, NULL); if (ret < 0) { - blog(LOG_WARNING, "Failed to open file '%s': %s", - info->file, av_err2str(ret)); + blog(LOG_WARNING, "Failed to open file '%s': %s", info->file, + av_err2str(ret)); return false; } ret = avformat_find_stream_info(info->fmt_ctx, NULL); if (ret < 0) { - blog(LOG_WARNING, "Could not find stream info for file '%s':" - " %s", info->file, av_err2str(ret)); + blog(LOG_WARNING, + "Could not find stream info for file '%s':" + " %s", + info->file, av_err2str(ret)); goto fail; } if (!ffmpeg_image_open_decoder_context(info)) goto fail; - info->cx = info->decoder_ctx->width; - info->cy = info->decoder_ctx->height; + info->cx = info->decoder_ctx->width; + info->cy = info->decoder_ctx->height; info->format = info->decoder_ctx->pix_fmt; return true; @@ -94,18 +98,20 @@ fail: } static bool ffmpeg_image_reformat_frame(struct ffmpeg_image *info, - AVFrame *frame, uint8_t *out, int linesize) + AVFrame *frame, uint8_t *out, + int linesize) { struct SwsContext *sws_ctx = NULL; - int ret = 0; + int ret = 0; if (info->format == AV_PIX_FMT_RGBA || info->format == AV_PIX_FMT_BGRA || info->format == AV_PIX_FMT_BGR0) { if (linesize != frame->linesize[0]) { - int min_line = linesize < frame->linesize[0] ? - linesize : frame->linesize[0]; + int min_line = linesize < frame->linesize[0] + ? linesize + : frame->linesize[0]; for (int y = 0; y < info->cy; y++) memcpy(out + y * linesize, @@ -117,21 +123,23 @@ static bool ffmpeg_image_reformat_frame(struct ffmpeg_image *info, } else { sws_ctx = sws_getContext(info->cx, info->cy, info->format, - info->cx, info->cy, AV_PIX_FMT_BGRA, - SWS_POINT, NULL, NULL, NULL); + info->cx, info->cy, AV_PIX_FMT_BGRA, + SWS_POINT, NULL, NULL, NULL); if (!sws_ctx) { - blog(LOG_WARNING, "Failed to create scale context " - "for '%s'", info->file); + blog(LOG_WARNING, + "Failed to create scale context " + "for '%s'", + info->file); return false; } - ret = sws_scale(sws_ctx, (const uint8_t *const*)frame->data, + ret = sws_scale(sws_ctx, (const uint8_t *const *)frame->data, frame->linesize, 0, info->cy, &out, &linesize); sws_freeContext(sws_ctx); if (ret < 0) { blog(LOG_WARNING, "sws_scale failed for '%s': %s", - info->file, av_err2str(ret)); + info->file, av_err2str(ret)); return false; } @@ -142,24 +150,24 @@ static bool ffmpeg_image_reformat_frame(struct ffmpeg_image *info, } static bool ffmpeg_image_decode(struct ffmpeg_image *info, uint8_t *out, - int linesize) + int linesize) { - AVPacket packet = {0}; - bool success = false; - AVFrame *frame = av_frame_alloc(); - int got_frame = 0; - int ret; + AVPacket packet = {0}; + bool success = false; + AVFrame *frame = av_frame_alloc(); + int got_frame = 0; + int ret; if (!frame) { blog(LOG_WARNING, "Failed to create frame data for '%s'", - info->file); + info->file); return false; } ret = av_read_frame(info->fmt_ctx, &packet); if (ret < 0) { blog(LOG_WARNING, "Failed to read image frame from '%s': %s", - info->file, av_err2str(ret)); + info->file, av_err2str(ret)); goto fail; } @@ -175,11 +183,11 @@ static bool ffmpeg_image_decode(struct ffmpeg_image *info, uint8_t *out, ret = 0; #else ret = avcodec_decode_video2(info->decoder_ctx, frame, - &got_frame, &packet); + &got_frame, &packet); #endif if (ret < 0) { blog(LOG_WARNING, "Failed to decode frame for '%s': %s", - info->file, av_err2str(ret)); + info->file, av_err2str(ret)); goto fail; } } @@ -194,27 +202,30 @@ fail: void gs_init_image_deps(void) { +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) av_register_all(); +#endif } -void gs_free_image_deps(void) -{ -} +void gs_free_image_deps(void) {} static inline enum gs_color_format convert_format(enum AVPixelFormat format) { switch ((int)format) { - case AV_PIX_FMT_RGBA: return GS_RGBA; - case AV_PIX_FMT_BGRA: return GS_BGRA; - case AV_PIX_FMT_BGR0: return GS_BGRX; + case AV_PIX_FMT_RGBA: + return GS_RGBA; + case AV_PIX_FMT_BGRA: + return GS_BGRA; + case AV_PIX_FMT_BGR0: + return GS_BGRX; } return GS_BGRX; } uint8_t *gs_create_texture_file_data(const char *file, - enum gs_color_format *format, - uint32_t *cx_out, uint32_t *cy_out) + enum gs_color_format *format, + uint32_t *cx_out, uint32_t *cy_out) { struct ffmpeg_image image; uint8_t *data = NULL; diff --git a/libobs/graphics/graphics-imports.c b/libobs/graphics/graphics-imports.c index 31ef4ab..10a42b5 100644 --- a/libobs/graphics/graphics-imports.c +++ b/libobs/graphics/graphics-imports.c @@ -20,23 +20,25 @@ #include "../util/platform.h" #include "graphics-internal.h" -#define GRAPHICS_IMPORT(func) \ - do { \ - exports->func = os_dlsym(module, #func); \ - if (!exports->func) { \ - success = false; \ - blog(LOG_ERROR, "Could not load function '%s' from " \ - "module '%s'", #func, module_name); \ - } \ +#define GRAPHICS_IMPORT(func) \ + do { \ + exports->func = os_dlsym(module, #func); \ + if (!exports->func) { \ + success = false; \ + blog(LOG_ERROR, \ + "Could not load function '%s' from " \ + "module '%s'", \ + #func, module_name); \ + } \ } while (false) -#define GRAPHICS_IMPORT_OPTIONAL(func) \ - do { \ +#define GRAPHICS_IMPORT_OPTIONAL(func) \ + do { \ exports->func = os_dlsym(module, #func); \ } while (false) bool load_graphics_imports(struct gs_exports *exports, void *module, - const char *module_name) + const char *module_name) { bool success = true; @@ -48,6 +50,7 @@ bool load_graphics_imports(struct gs_exports *exports, void *module, GRAPHICS_IMPORT(device_destroy); GRAPHICS_IMPORT(device_enter_context); GRAPHICS_IMPORT(device_leave_context); + GRAPHICS_IMPORT(device_get_device_obj); GRAPHICS_IMPORT(device_swapchain_create); GRAPHICS_IMPORT(device_resize); GRAPHICS_IMPORT(device_get_size); @@ -63,6 +66,8 @@ bool load_graphics_imports(struct gs_exports *exports, void *module, GRAPHICS_IMPORT(device_pixelshader_create); GRAPHICS_IMPORT(device_vertexbuffer_create); GRAPHICS_IMPORT(device_indexbuffer_create); + GRAPHICS_IMPORT(device_timer_create); + GRAPHICS_IMPORT(device_timer_range_create); GRAPHICS_IMPORT(device_get_texture_type); GRAPHICS_IMPORT(device_load_vertexbuffer); GRAPHICS_IMPORT(device_load_indexbuffer); @@ -151,6 +156,15 @@ bool load_graphics_imports(struct gs_exports *exports, void *module, GRAPHICS_IMPORT(gs_indexbuffer_get_num_indices); GRAPHICS_IMPORT(gs_indexbuffer_get_type); + GRAPHICS_IMPORT(gs_timer_destroy); + GRAPHICS_IMPORT(gs_timer_begin); + GRAPHICS_IMPORT(gs_timer_end); + GRAPHICS_IMPORT(gs_timer_get_data); + GRAPHICS_IMPORT(gs_timer_range_destroy); + GRAPHICS_IMPORT(gs_timer_range_begin); + GRAPHICS_IMPORT(gs_timer_range_end); + GRAPHICS_IMPORT(gs_timer_range_get_data); + GRAPHICS_IMPORT(gs_shader_destroy); GRAPHICS_IMPORT(gs_shader_get_num_params); GRAPHICS_IMPORT(gs_shader_get_param_by_idx); diff --git a/libobs/graphics/graphics-internal.h b/libobs/graphics/graphics-internal.h index 2c55484..e527e1e 100644 --- a/libobs/graphics/graphics-internal.h +++ b/libobs/graphics/graphics-internal.h @@ -26,162 +26,180 @@ struct gs_exports { const char *(*device_get_name)(void); int (*device_get_type)(void); - bool (*device_enum_adapters)( - bool (*callback)(void*, const char*, uint32_t), - void*); + bool (*device_enum_adapters)(bool (*callback)(void *, const char *, + uint32_t), + void *); const char *(*device_preprocessor_name)(void); int (*device_create)(gs_device_t **device, uint32_t adapter); void (*device_destroy)(gs_device_t *device); void (*device_enter_context)(gs_device_t *device); void (*device_leave_context)(gs_device_t *device); - gs_swapchain_t *(*device_swapchain_create)(gs_device_t *device, - const struct gs_init_data *data); + void *(*device_get_device_obj)(gs_device_t *device); + gs_swapchain_t *(*device_swapchain_create)( + gs_device_t *device, const struct gs_init_data *data); void (*device_resize)(gs_device_t *device, uint32_t x, uint32_t y); - void (*device_get_size)(const gs_device_t *device, - uint32_t *x, uint32_t *y); + void (*device_get_size)(const gs_device_t *device, uint32_t *x, + uint32_t *y); uint32_t (*device_get_width)(const gs_device_t *device); uint32_t (*device_get_height)(const gs_device_t *device); - gs_texture_t *(*device_texture_create)(gs_device_t *device, - uint32_t width, uint32_t height, - enum gs_color_format color_format, uint32_t levels, - const uint8_t **data, uint32_t flags); - gs_texture_t *(*device_cubetexture_create)(gs_device_t *device, - uint32_t size, enum gs_color_format color_format, - uint32_t levels, const uint8_t **data, uint32_t flags); - gs_texture_t *(*device_voltexture_create)(gs_device_t *device, - uint32_t width, uint32_t height, uint32_t depth, - enum gs_color_format color_format, uint32_t levels, - const uint8_t **data, uint32_t flags); - gs_zstencil_t *(*device_zstencil_create)(gs_device_t *device, - uint32_t width, uint32_t height, - enum gs_zstencil_format format); - gs_stagesurf_t *(*device_stagesurface_create)(gs_device_t *device, - uint32_t width, uint32_t height, - enum gs_color_format color_format); - gs_samplerstate_t *(*device_samplerstate_create)(gs_device_t *device, - const struct gs_sampler_info *info); + gs_texture_t *(*device_texture_create)( + gs_device_t *device, uint32_t width, uint32_t height, + enum gs_color_format color_format, uint32_t levels, + const uint8_t **data, uint32_t flags); + gs_texture_t *(*device_cubetexture_create)( + gs_device_t *device, uint32_t size, + enum gs_color_format color_format, uint32_t levels, + const uint8_t **data, uint32_t flags); + gs_texture_t *(*device_voltexture_create)( + gs_device_t *device, uint32_t width, uint32_t height, + uint32_t depth, enum gs_color_format color_format, + uint32_t levels, const uint8_t **data, uint32_t flags); + gs_zstencil_t *(*device_zstencil_create)( + gs_device_t *device, uint32_t width, uint32_t height, + enum gs_zstencil_format format); + gs_stagesurf_t *(*device_stagesurface_create)( + gs_device_t *device, uint32_t width, uint32_t height, + enum gs_color_format color_format); + gs_samplerstate_t *(*device_samplerstate_create)( + gs_device_t *device, const struct gs_sampler_info *info); gs_shader_t *(*device_vertexshader_create)(gs_device_t *device, - const char *shader, const char *file, - char **error_string); + const char *shader, + const char *file, + char **error_string); gs_shader_t *(*device_pixelshader_create)(gs_device_t *device, - const char *shader, const char *file, - char **error_string); + const char *shader, + const char *file, + char **error_string); gs_vertbuffer_t *(*device_vertexbuffer_create)(gs_device_t *device, - struct gs_vb_data *data, uint32_t flags); + struct gs_vb_data *data, + uint32_t flags); gs_indexbuffer_t *(*device_indexbuffer_create)(gs_device_t *device, - enum gs_index_type type, void *indices, size_t num, - uint32_t flags); + enum gs_index_type type, + void *indices, + size_t num, + uint32_t flags); + gs_timer_t *(*device_timer_create)(gs_device_t *device); + gs_timer_range_t *(*device_timer_range_create)(gs_device_t *device); enum gs_texture_type (*device_get_texture_type)( - const gs_texture_t *texture); + const gs_texture_t *texture); void (*device_load_vertexbuffer)(gs_device_t *device, - gs_vertbuffer_t *vertbuffer); + gs_vertbuffer_t *vertbuffer); void (*device_load_indexbuffer)(gs_device_t *device, - gs_indexbuffer_t *indexbuffer); + gs_indexbuffer_t *indexbuffer); void (*device_load_texture)(gs_device_t *device, gs_texture_t *tex, - int unit); + int unit); void (*device_load_samplerstate)(gs_device_t *device, - gs_samplerstate_t *samplerstate, int unit); + gs_samplerstate_t *samplerstate, + int unit); void (*device_load_vertexshader)(gs_device_t *device, - gs_shader_t *vertshader); + gs_shader_t *vertshader); void (*device_load_pixelshader)(gs_device_t *device, - gs_shader_t *pixelshader); - void (*device_load_default_samplerstate)(gs_device_t *device, - bool b_3d, int unit); + gs_shader_t *pixelshader); + void (*device_load_default_samplerstate)(gs_device_t *device, bool b_3d, + int unit); gs_shader_t *(*device_get_vertex_shader)(const gs_device_t *device); gs_shader_t *(*device_get_pixel_shader)(const gs_device_t *device); gs_texture_t *(*device_get_render_target)(const gs_device_t *device); gs_zstencil_t *(*device_get_zstencil_target)(const gs_device_t *device); void (*device_set_render_target)(gs_device_t *device, gs_texture_t *tex, - gs_zstencil_t *zstencil); + gs_zstencil_t *zstencil); void (*device_set_cube_render_target)(gs_device_t *device, - gs_texture_t *cubetex, int side, gs_zstencil_t *zstencil); + gs_texture_t *cubetex, int side, + gs_zstencil_t *zstencil); void (*device_copy_texture)(gs_device_t *device, gs_texture_t *dst, - gs_texture_t *src); + gs_texture_t *src); void (*device_copy_texture_region)(gs_device_t *device, - gs_texture_t *dst, uint32_t dst_x, uint32_t dst_y, - gs_texture_t *src, uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h); + gs_texture_t *dst, uint32_t dst_x, + uint32_t dst_y, gs_texture_t *src, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h); void (*device_stage_texture)(gs_device_t *device, gs_stagesurf_t *dst, - gs_texture_t *src); + gs_texture_t *src); void (*device_begin_scene)(gs_device_t *device); void (*device_draw)(gs_device_t *device, enum gs_draw_mode draw_mode, - uint32_t start_vert, uint32_t num_verts); + uint32_t start_vert, uint32_t num_verts); void (*device_end_scene)(gs_device_t *device); void (*device_load_swapchain)(gs_device_t *device, - gs_swapchain_t *swaphchain); + gs_swapchain_t *swaphchain); void (*device_clear)(gs_device_t *device, uint32_t clear_flags, - const struct vec4 *color, float depth, uint8_t stencil); + const struct vec4 *color, float depth, + uint8_t stencil); void (*device_present)(gs_device_t *device); void (*device_flush)(gs_device_t *device); void (*device_set_cull_mode)(gs_device_t *device, - enum gs_cull_mode mode); + enum gs_cull_mode mode); enum gs_cull_mode (*device_get_cull_mode)(const gs_device_t *device); void (*device_enable_blending)(gs_device_t *device, bool enable); void (*device_enable_depth_test)(gs_device_t *device, bool enable); void (*device_enable_stencil_test)(gs_device_t *device, bool enable); void (*device_enable_stencil_write)(gs_device_t *device, bool enable); void (*device_enable_color)(gs_device_t *device, bool red, bool green, - bool blue, bool alpha); + bool blue, bool alpha); void (*device_blend_function)(gs_device_t *device, - enum gs_blend_type src, enum gs_blend_type dest); + enum gs_blend_type src, + enum gs_blend_type dest); void (*device_blend_function_separate)(gs_device_t *device, - enum gs_blend_type src_c, enum gs_blend_type dest_c, - enum gs_blend_type src_a, enum gs_blend_type dest_a); + enum gs_blend_type src_c, + enum gs_blend_type dest_c, + enum gs_blend_type src_a, + enum gs_blend_type dest_a); void (*device_depth_function)(gs_device_t *device, - enum gs_depth_test test); + enum gs_depth_test test); void (*device_stencil_function)(gs_device_t *device, - enum gs_stencil_side side, enum gs_depth_test test); + enum gs_stencil_side side, + enum gs_depth_test test); void (*device_stencil_op)(gs_device_t *device, - enum gs_stencil_side side, - enum gs_stencil_op_type fail, - enum gs_stencil_op_type zfail, - enum gs_stencil_op_type zpass); + enum gs_stencil_side side, + enum gs_stencil_op_type fail, + enum gs_stencil_op_type zfail, + enum gs_stencil_op_type zpass); void (*device_set_viewport)(gs_device_t *device, int x, int y, - int width, int height); + int width, int height); void (*device_get_viewport)(const gs_device_t *device, - struct gs_rect *rect); + struct gs_rect *rect); void (*device_set_scissor_rect)(gs_device_t *device, - const struct gs_rect *rect); + const struct gs_rect *rect); void (*device_ortho)(gs_device_t *device, float left, float right, - float top, float bottom, float znear, float zfar); + float top, float bottom, float znear, float zfar); void (*device_frustum)(gs_device_t *device, float left, float right, - float top, float bottom, float znear, float zfar); + float top, float bottom, float znear, + float zfar); void (*device_projection_push)(gs_device_t *device); void (*device_projection_pop)(gs_device_t *device); - void (*gs_swapchain_destroy)(gs_swapchain_t *swapchain); + void (*gs_swapchain_destroy)(gs_swapchain_t *swapchain); - void (*gs_texture_destroy)(gs_texture_t *tex); + void (*gs_texture_destroy)(gs_texture_t *tex); uint32_t (*gs_texture_get_width)(const gs_texture_t *tex); uint32_t (*gs_texture_get_height)(const gs_texture_t *tex); enum gs_color_format (*gs_texture_get_color_format)( - const gs_texture_t *tex); - bool (*gs_texture_map)(gs_texture_t *tex, uint8_t **ptr, - uint32_t *linesize); - void (*gs_texture_unmap)(gs_texture_t *tex); - bool (*gs_texture_is_rect)(const gs_texture_t *tex); - void *(*gs_texture_get_obj)(const gs_texture_t *tex); + const gs_texture_t *tex); + bool (*gs_texture_map)(gs_texture_t *tex, uint8_t **ptr, + uint32_t *linesize); + void (*gs_texture_unmap)(gs_texture_t *tex); + bool (*gs_texture_is_rect)(const gs_texture_t *tex); + void *(*gs_texture_get_obj)(const gs_texture_t *tex); - void (*gs_cubetexture_destroy)(gs_texture_t *cubetex); + void (*gs_cubetexture_destroy)(gs_texture_t *cubetex); uint32_t (*gs_cubetexture_get_size)(const gs_texture_t *cubetex); enum gs_color_format (*gs_cubetexture_get_color_format)( - const gs_texture_t *cubetex); + const gs_texture_t *cubetex); - void (*gs_voltexture_destroy)(gs_texture_t *voltex); + void (*gs_voltexture_destroy)(gs_texture_t *voltex); uint32_t (*gs_voltexture_get_width)(const gs_texture_t *voltex); uint32_t (*gs_voltexture_get_height)(const gs_texture_t *voltex); uint32_t (*gs_voltexture_get_depth)(const gs_texture_t *voltex); enum gs_color_format (*gs_voltexture_get_color_format)( - const gs_texture_t *voltex); + const gs_texture_t *voltex); - void (*gs_stagesurface_destroy)(gs_stagesurf_t *stagesurf); + void (*gs_stagesurface_destroy)(gs_stagesurf_t *stagesurf); uint32_t (*gs_stagesurface_get_width)(const gs_stagesurf_t *stagesurf); uint32_t (*gs_stagesurface_get_height)(const gs_stagesurf_t *stagesurf); enum gs_color_format (*gs_stagesurface_get_color_format)( - const gs_stagesurf_t *stagesurf); - bool (*gs_stagesurface_map)(gs_stagesurf_t *stagesurf, - uint8_t **data, uint32_t *linesize); - void (*gs_stagesurface_unmap)(gs_stagesurf_t *stagesurf); + const gs_stagesurf_t *stagesurf); + bool (*gs_stagesurface_map)(gs_stagesurf_t *stagesurf, uint8_t **data, + uint32_t *linesize); + void (*gs_stagesurface_unmap)(gs_stagesurf_t *stagesurf); void (*gs_zstencil_destroy)(gs_zstencil_t *zstencil); @@ -190,98 +208,113 @@ struct gs_exports { void (*gs_vertexbuffer_destroy)(gs_vertbuffer_t *vertbuffer); void (*gs_vertexbuffer_flush)(gs_vertbuffer_t *vertbuffer); void (*gs_vertexbuffer_flush_direct)(gs_vertbuffer_t *vertbuffer, - const struct gs_vb_data *data); + const struct gs_vb_data *data); struct gs_vb_data *(*gs_vertexbuffer_get_data)( - const gs_vertbuffer_t *vertbuffer); + const gs_vertbuffer_t *vertbuffer); - void (*gs_indexbuffer_destroy)(gs_indexbuffer_t *indexbuffer); - void (*gs_indexbuffer_flush)(gs_indexbuffer_t *indexbuffer); - void (*gs_indexbuffer_flush_direct)(gs_indexbuffer_t *indexbuffer, - const void *data); - void *(*gs_indexbuffer_get_data)(const gs_indexbuffer_t *indexbuffer); + void (*gs_indexbuffer_destroy)(gs_indexbuffer_t *indexbuffer); + void (*gs_indexbuffer_flush)(gs_indexbuffer_t *indexbuffer); + void (*gs_indexbuffer_flush_direct)(gs_indexbuffer_t *indexbuffer, + const void *data); + void *(*gs_indexbuffer_get_data)(const gs_indexbuffer_t *indexbuffer); size_t (*gs_indexbuffer_get_num_indices)( - const gs_indexbuffer_t *indexbuffer); + const gs_indexbuffer_t *indexbuffer); enum gs_index_type (*gs_indexbuffer_get_type)( - const gs_indexbuffer_t *indexbuffer); + const gs_indexbuffer_t *indexbuffer); + + void (*gs_timer_destroy)(gs_timer_t *timer); + void (*gs_timer_begin)(gs_timer_t *timer); + void (*gs_timer_end)(gs_timer_t *timer); + bool (*gs_timer_get_data)(gs_timer_t *timer, uint64_t *ticks); + void (*gs_timer_range_destroy)(gs_timer_range_t *range); + bool (*gs_timer_range_begin)(gs_timer_range_t *range); + bool (*gs_timer_range_end)(gs_timer_range_t *range); + bool (*gs_timer_range_get_data)(gs_timer_range_t *range, bool *disjoint, + uint64_t *frequency); void (*gs_shader_destroy)(gs_shader_t *shader); int (*gs_shader_get_num_params)(const gs_shader_t *shader); gs_sparam_t *(*gs_shader_get_param_by_idx)(gs_shader_t *shader, - uint32_t param); + uint32_t param); gs_sparam_t *(*gs_shader_get_param_by_name)(gs_shader_t *shader, - const char *name); - gs_sparam_t *(*gs_shader_get_viewproj_matrix)( - const gs_shader_t *shader); + const char *name); + gs_sparam_t *(*gs_shader_get_viewproj_matrix)(const gs_shader_t *shader); gs_sparam_t *(*gs_shader_get_world_matrix)(const gs_shader_t *shader); void (*gs_shader_get_param_info)(const gs_sparam_t *param, - struct gs_shader_param_info *info); + struct gs_shader_param_info *info); void (*gs_shader_set_bool)(gs_sparam_t *param, bool val); void (*gs_shader_set_float)(gs_sparam_t *param, float val); void (*gs_shader_set_int)(gs_sparam_t *param, int val); void (*gs_shader_set_matrix3)(gs_sparam_t *param, - const struct matrix3 *val); + const struct matrix3 *val); void (*gs_shader_set_matrix4)(gs_sparam_t *param, - const struct matrix4 *val); + const struct matrix4 *val); void (*gs_shader_set_vec2)(gs_sparam_t *param, const struct vec2 *val); void (*gs_shader_set_vec3)(gs_sparam_t *param, const struct vec3 *val); void (*gs_shader_set_vec4)(gs_sparam_t *param, const struct vec4 *val); void (*gs_shader_set_texture)(gs_sparam_t *param, gs_texture_t *val); void (*gs_shader_set_val)(gs_sparam_t *param, const void *val, - size_t size); + size_t size); void (*gs_shader_set_default)(gs_sparam_t *param); void (*gs_shader_set_next_sampler)(gs_sparam_t *param, - gs_samplerstate_t *sampler); + gs_samplerstate_t *sampler); bool (*device_nv12_available)(gs_device_t *device); void (*device_debug_marker_begin)(gs_device_t *device, - const char *markername, const float color[4]); + const char *markername, + const float color[4]); void (*device_debug_marker_end)(gs_device_t *device); #ifdef __APPLE__ /* OSX/Cocoa specific functions */ gs_texture_t *(*device_texture_create_from_iosurface)(gs_device_t *dev, - void *iosurf); + void *iosurf); bool (*gs_texture_rebind_iosurface)(gs_texture_t *texture, - void *iosurf); + void *iosurf); #elif _WIN32 bool (*device_gdi_texture_available)(void); bool (*device_shared_texture_available)(void); - bool (*device_get_duplicator_monitor_info)(gs_device_t *device, - int monitor_idx, struct gs_monitor_info *monitor_info); + bool (*device_get_duplicator_monitor_info)( + gs_device_t *device, int monitor_idx, + struct gs_monitor_info *monitor_info); gs_duplicator_t *(*device_duplicator_create)(gs_device_t *device, - int monitor_idx); + int monitor_idx); void (*gs_duplicator_destroy)(gs_duplicator_t *duplicator); bool (*gs_duplicator_update_frame)(gs_duplicator_t *duplicator); gs_texture_t *(*gs_duplicator_get_texture)(gs_duplicator_t *duplicator); gs_texture_t *(*device_texture_create_gdi)(gs_device_t *device, - uint32_t width, uint32_t height); + uint32_t width, + uint32_t height); void *(*gs_texture_get_dc)(gs_texture_t *gdi_tex); void (*gs_texture_release_dc)(gs_texture_t *gdi_tex); gs_texture_t *(*device_texture_open_shared)(gs_device_t *device, - uint32_t handle); + uint32_t handle); uint32_t (*device_texture_get_shared_handle)(gs_texture_t *tex); int (*device_texture_acquire_sync)(gs_texture_t *tex, uint64_t key, - uint32_t ms); + uint32_t ms); int (*device_texture_release_sync)(gs_texture_t *tex, uint64_t key); bool (*device_texture_create_nv12)(gs_device_t *device, - gs_texture_t **tex_y, gs_texture_t **tex_uv, - uint32_t width, uint32_t height, uint32_t flags); + gs_texture_t **tex_y, + gs_texture_t **tex_uv, + uint32_t width, uint32_t height, + uint32_t flags); gs_stagesurf_t *(*device_stagesurface_create_nv12)(gs_device_t *device, - uint32_t width, uint32_t height); + uint32_t width, + uint32_t height); #endif }; struct blend_state { - bool enabled; + bool enabled; enum gs_blend_type src_c; enum gs_blend_type dest_c; enum gs_blend_type src_a; @@ -289,34 +322,34 @@ struct blend_state { }; struct graphics_subsystem { - void *module; - gs_device_t *device; - struct gs_exports exports; + void *module; + gs_device_t *device; + struct gs_exports exports; DARRAY(struct gs_rect) viewport_stack; DARRAY(struct matrix4) matrix_stack; - size_t cur_matrix; + size_t cur_matrix; - struct matrix4 projection; - struct gs_effect *cur_effect; + struct matrix4 projection; + struct gs_effect *cur_effect; - gs_vertbuffer_t *sprite_buffer; + gs_vertbuffer_t *sprite_buffer; - bool using_immediate; - struct gs_vb_data *vbd; - gs_vertbuffer_t *immediate_vertbuffer; - DARRAY(struct vec3) verts; - DARRAY(struct vec3) norms; - DARRAY(uint32_t) colors; - DARRAY(struct vec2) texverts[16]; + bool using_immediate; + struct gs_vb_data *vbd; + gs_vertbuffer_t *immediate_vertbuffer; + DARRAY(struct vec3) verts; + DARRAY(struct vec3) norms; + DARRAY(uint32_t) colors; + DARRAY(struct vec2) texverts[16]; - pthread_mutex_t effect_mutex; - struct gs_effect *first_effect; + pthread_mutex_t effect_mutex; + struct gs_effect *first_effect; - pthread_mutex_t mutex; - volatile long ref; + pthread_mutex_t mutex; + volatile long ref; - struct blend_state cur_blend_state; + struct blend_state cur_blend_state; DARRAY(struct blend_state) blend_state_stack; }; diff --git a/libobs/graphics/graphics-magick.c b/libobs/graphics/graphics-magick.c index 6e4e1e9..3754c6c 100644 --- a/libobs/graphics/graphics-magick.c +++ b/libobs/graphics/graphics-magick.c @@ -2,7 +2,7 @@ #include "obsconfig.h" #define MAGICKCORE_QUANTUM_DEPTH 16 -#define MAGICKCORE_HDRI_ENABLE 0 +#define MAGICKCORE_HDRI_ENABLE 0 #if LIBOBS_IMAGEMAGICK_DIR_STYLE == LIBOBS_IMAGEMAGICK_DIR_STYLE_6L #include @@ -21,33 +21,34 @@ void gs_free_image_deps() } uint8_t *gs_create_texture_file_data(const char *file, - enum gs_color_format *format, - uint32_t *cx_out, uint32_t *cy_out) + enum gs_color_format *format, + uint32_t *cx_out, uint32_t *cy_out) { - uint8_t *data = NULL; - ImageInfo *info; + uint8_t *data = NULL; + ImageInfo *info; ExceptionInfo *exception; - Image *image; + Image *image; if (!file || !*file) return NULL; - info = CloneImageInfo(NULL); + info = CloneImageInfo(NULL); exception = AcquireExceptionInfo(); strcpy(info->filename, file); image = ReadImage(info, exception); if (image) { - size_t cx = image->magick_columns; - size_t cy = image->magick_rows; - data = bmalloc(cx * cy * 4); + size_t cx = image->magick_columns; + size_t cy = image->magick_rows; + data = bmalloc(cx * cy * 4); - ExportImagePixels(image, 0, 0, cx, cy, "BGRA", CharPixel, - data, exception); + ExportImagePixels(image, 0, 0, cx, cy, "BGRA", CharPixel, data, + exception); if (exception->severity != UndefinedException) { - blog(LOG_WARNING, "magickcore warning/error getting " - "pixels from file '%s': %s", file, - exception->reason); + blog(LOG_WARNING, + "magickcore warning/error getting " + "pixels from file '%s': %s", + file, exception->reason); bfree(data); data = NULL; } @@ -58,8 +59,10 @@ uint8_t *gs_create_texture_file_data(const char *file, DestroyImage(image); } else if (exception->severity != UndefinedException) { - blog(LOG_WARNING, "magickcore warning/error reading file " - "'%s': %s", file, exception->reason); + blog(LOG_WARNING, + "magickcore warning/error reading file " + "'%s': %s", + file, exception->reason); } DestroyImageInfo(info); diff --git a/libobs/graphics/graphics.c b/libobs/graphics/graphics.c index 671d925..9e77cc3 100644 --- a/libobs/graphics/graphics.c +++ b/libobs/graphics/graphics.c @@ -31,7 +31,7 @@ static THREAD_LOCAL graphics_t *thread_graphics = NULL; static inline bool gs_obj_valid(const void *obj, const char *f, - const char *name) + const char *name) { if (!obj) { blog(LOG_DEBUG, "%s: Null '%s' parameter", f, name); @@ -45,7 +45,7 @@ static inline bool gs_valid(const char *f) { if (!thread_graphics) { blog(LOG_DEBUG, "%s: called while not in a graphics context", - f); + f); return false; } @@ -54,22 +54,20 @@ static inline bool gs_valid(const char *f) #define ptr_valid(ptr, func) gs_obj_valid(ptr, func, #ptr) -#define gs_valid_p(func, param1) \ - (gs_valid(func) && ptr_valid(param1, func)) +#define gs_valid_p(func, param1) (gs_valid(func) && ptr_valid(param1, func)) #define gs_valid_p2(func, param1, param2) \ - (gs_valid(func) && ptr_valid(param1, func) \ - && ptr_valid(param2, func)) + (gs_valid(func) && ptr_valid(param1, func) && ptr_valid(param2, func)) -#define gs_valid_p3(func, param1, param2, param3) \ - (gs_valid(func) && ptr_valid(param1, func) \ - && ptr_valid(param2, func) && ptr_valid(param3, func)) +#define gs_valid_p3(func, param1, param2, param3) \ + (gs_valid(func) && ptr_valid(param1, func) && \ + ptr_valid(param2, func) && ptr_valid(param3, func)) #define IMMEDIATE_COUNT 512 -void gs_enum_adapters( - bool (*callback)(void *param, const char *name, uint32_t id), - void *param) +void gs_enum_adapters(bool (*callback)(void *param, const char *name, + uint32_t id), + void *param) { graphics_t *graphics = thread_graphics; @@ -92,25 +90,25 @@ extern void gs_init_image_deps(void); extern void gs_free_image_deps(void); bool load_graphics_imports(struct gs_exports *exports, void *module, - const char *module_name); + const char *module_name); static bool graphics_init_immediate_vb(struct graphics_subsystem *graphics) { struct gs_vb_data *vbd; vbd = gs_vbdata_create(); - vbd->num = IMMEDIATE_COUNT; - vbd->points = bmalloc(sizeof(struct vec3)*IMMEDIATE_COUNT); - vbd->normals = bmalloc(sizeof(struct vec3)*IMMEDIATE_COUNT); - vbd->colors = bmalloc(sizeof(uint32_t) *IMMEDIATE_COUNT); + vbd->num = IMMEDIATE_COUNT; + vbd->points = bmalloc(sizeof(struct vec3) * IMMEDIATE_COUNT); + vbd->normals = bmalloc(sizeof(struct vec3) * IMMEDIATE_COUNT); + vbd->colors = bmalloc(sizeof(uint32_t) * IMMEDIATE_COUNT); vbd->num_tex = 1; vbd->tvarray = bmalloc(sizeof(struct gs_tvertarray)); vbd->tvarray[0].width = 2; - vbd->tvarray[0].array = - bmalloc(sizeof(struct vec2) * IMMEDIATE_COUNT); + vbd->tvarray[0].array = bmalloc(sizeof(struct vec2) * IMMEDIATE_COUNT); - graphics->immediate_vertbuffer = graphics->exports. - device_vertexbuffer_create(graphics->device, vbd, GS_DYNAMIC); + graphics->immediate_vertbuffer = + graphics->exports.device_vertexbuffer_create(graphics->device, + vbd, GS_DYNAMIC); if (!graphics->immediate_vertbuffer) return false; @@ -122,18 +120,18 @@ static bool graphics_init_sprite_vb(struct graphics_subsystem *graphics) struct gs_vb_data *vbd; vbd = gs_vbdata_create(); - vbd->num = 4; - vbd->points = bmalloc(sizeof(struct vec3) * 4); + vbd->num = 4; + vbd->points = bmalloc(sizeof(struct vec3) * 4); vbd->num_tex = 1; vbd->tvarray = bmalloc(sizeof(struct gs_tvertarray)); vbd->tvarray[0].width = 2; vbd->tvarray[0].array = bmalloc(sizeof(struct vec2) * 4); - memset(vbd->points, 0, sizeof(struct vec3) * 4); + memset(vbd->points, 0, sizeof(struct vec3) * 4); memset(vbd->tvarray[0].array, 0, sizeof(struct vec2) * 4); - graphics->sprite_buffer = graphics->exports. - device_vertexbuffer_create(graphics->device, vbd, GS_DYNAMIC); + graphics->sprite_buffer = graphics->exports.device_vertexbuffer_create( + graphics->device, vbd, GS_DYNAMIC); if (!graphics->sprite_buffer) return false; @@ -158,14 +156,14 @@ static bool graphics_init(struct graphics_subsystem *graphics) if (pthread_mutex_init(&graphics->effect_mutex, NULL) != 0) return false; - graphics->exports.device_blend_function_separate(graphics->device, - GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, - GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); + graphics->exports.device_blend_function_separate( + graphics->device, GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, + GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); graphics->cur_blend_state.enabled = true; - graphics->cur_blend_state.src_c = GS_BLEND_SRCALPHA; - graphics->cur_blend_state.dest_c = GS_BLEND_INVSRCALPHA; - graphics->cur_blend_state.src_a = GS_BLEND_ONE; - graphics->cur_blend_state.dest_a = GS_BLEND_INVSRCALPHA; + graphics->cur_blend_state.src_c = GS_BLEND_SRCALPHA; + graphics->cur_blend_state.dest_c = GS_BLEND_INVSRCALPHA; + graphics->cur_blend_state.src_a = GS_BLEND_ONE; + graphics->cur_blend_state.dest_a = GS_BLEND_INVSRCALPHA; graphics->exports.device_leave_context(graphics->device); @@ -188,7 +186,7 @@ int gs_create(graphics_t **pgraphics, const char *module, uint32_t adapter) } if (!load_graphics_imports(&graphics->exports, graphics->module, - module)) + module)) goto error; errcode = graphics->exports.device_create(&graphics->device, adapter); @@ -231,9 +229,9 @@ void gs_destroy(graphics_t *graphics) } graphics->exports.gs_vertexbuffer_destroy( - graphics->sprite_buffer); + graphics->sprite_buffer); graphics->exports.gs_vertexbuffer_destroy( - graphics->immediate_vertbuffer); + graphics->immediate_vertbuffer); graphics->exports.device_destroy(graphics->device); thread_graphics = NULL; @@ -278,7 +276,7 @@ void gs_leave_context(void) graphics_t *graphics = thread_graphics; graphics->exports.device_leave_context( - graphics->device); + graphics->device); pthread_mutex_unlock(&graphics->mutex); thread_graphics = NULL; } @@ -290,16 +288,27 @@ graphics_t *gs_get_context(void) return thread_graphics; } +void *gs_get_device_obj(void) +{ + if (!gs_valid("gs_get_device_obj")) + return NULL; + + return thread_graphics->exports.device_get_device_obj( + thread_graphics->device); +} + const char *gs_get_device_name(void) { - return gs_valid("gs_get_device_name") ? - thread_graphics->exports.device_get_name() : NULL; + return gs_valid("gs_get_device_name") + ? thread_graphics->exports.device_get_name() + : NULL; } int gs_get_device_type(void) { - return gs_valid("gs_get_device_type") ? - thread_graphics->exports.device_get_type() : -1; + return gs_valid("gs_get_device_type") + ? thread_graphics->exports.device_get_type() + : -1; } static inline struct matrix4 *top_matrix(graphics_t *graphics) @@ -509,18 +518,18 @@ void gs_render_start(bool b_new) graphics->vbd = gs_vbdata_create(); } else { graphics->vbd = gs_vertexbuffer_get_data( - graphics->immediate_vertbuffer); + graphics->immediate_vertbuffer); memset(graphics->vbd->colors, 0xFF, - sizeof(uint32_t) * IMMEDIATE_COUNT); + sizeof(uint32_t) * IMMEDIATE_COUNT); - graphics->verts.array = graphics->vbd->points; - graphics->norms.array = graphics->vbd->normals; - graphics->colors.array = graphics->vbd->colors; + graphics->verts.array = graphics->vbd->points; + graphics->norms.array = graphics->vbd->normals; + graphics->colors.array = graphics->vbd->colors; graphics->texverts[0].array = graphics->vbd->tvarray[0].array; - graphics->verts.capacity = IMMEDIATE_COUNT; - graphics->norms.capacity = IMMEDIATE_COUNT; - graphics->colors.capacity = IMMEDIATE_COUNT; + graphics->verts.capacity = IMMEDIATE_COUNT; + graphics->norms.capacity = IMMEDIATE_COUNT; + graphics->colors.capacity = IMMEDIATE_COUNT; graphics->texverts[0].capacity = IMMEDIATE_COUNT; } } @@ -555,21 +564,21 @@ void gs_render_stop(enum gs_draw_mode mode) if (graphics->norms.num && (graphics->norms.num != graphics->verts.num)) { blog(LOG_ERROR, "gs_render_stop: normal count does " - "not match vertex count"); + "not match vertex count"); num = min_size(num, graphics->norms.num); } if (graphics->colors.num && (graphics->colors.num != graphics->verts.num)) { blog(LOG_ERROR, "gs_render_stop: color count does " - "not match vertex count"); + "not match vertex count"); num = min_size(num, graphics->colors.num); } if (graphics->texverts[0].num && - (graphics->texverts[0].num != graphics->verts.num)) { + (graphics->texverts[0].num != graphics->verts.num)) { blog(LOG_ERROR, "gs_render_stop: texture vertex count does " - "not match vertex count"); + "not match vertex count"); num = min_size(num, graphics->texverts[0].num); } @@ -613,10 +622,10 @@ gs_vertbuffer_t *gs_render_save(void) if (!graphics->texverts[num_tex].num) break; - graphics->vbd->points = graphics->verts.array; + graphics->vbd->points = graphics->verts.array; graphics->vbd->normals = graphics->norms.array; - graphics->vbd->colors = graphics->colors.array; - graphics->vbd->num = graphics->verts.num; + graphics->vbd->colors = graphics->colors.array; + graphics->vbd->num = graphics->verts.num; graphics->vbd->num_tex = num_tex; if (graphics->vbd->num_tex) { @@ -669,12 +678,13 @@ void gs_normal3f(float x, float y, float z) } static inline bool validvertsize(graphics_t *graphics, size_t num, - const char *name) + const char *name) { if (graphics->using_immediate && num == IMMEDIATE_COUNT) { - blog(LOG_ERROR, "%s: tried to use over %u " - "for immediate rendering", - name, IMMEDIATE_COUNT); + blog(LOG_ERROR, + "%s: tried to use over %u " + "for immediate rendering", + name, IMMEDIATE_COUNT); return false; } @@ -689,7 +699,7 @@ void gs_color(uint32_t color) return; if (!validvertsize(graphics, graphics->colors.num, "gs_color")) return; - + da_push_back(graphics->colors, &color); } @@ -735,7 +745,7 @@ void gs_normal3v(const struct vec3 *v) return; if (!validvertsize(graphics, graphics->norms.num, "gs_normal")) return; - + da_push_back(graphics->norms, v); } @@ -752,7 +762,7 @@ void gs_texcoord2v(const struct vec2 *v, int unit) if (!gs_valid("gs_texcoord2v")) return; if (!validvertsize(graphics, graphics->texverts[unit].num, - "gs_texcoord")) + "gs_texcoord")) return; da_push_back(graphics->texverts[unit], v); @@ -810,7 +820,7 @@ gs_effect_t *gs_effect_create_from_file(const char *file, char **error_string) } gs_effect_t *gs_effect_create(const char *effect_string, const char *filename, - char **error_string) + char **error_string) { if (!gs_valid_p("gs_effect_create", effect_string)) return NULL; @@ -826,8 +836,8 @@ gs_effect_t *gs_effect_create(const char *effect_string, const char *filename, success = ep_parse(&parser, effect, effect_string, filename); if (!success) { if (error_string) - *error_string = error_data_buildstring( - &parser.cfp.error_list); + *error_string = + error_data_buildstring(&parser.cfp.error_list); gs_effect_destroy(effect); effect = NULL; } @@ -849,7 +859,7 @@ gs_effect_t *gs_effect_create(const char *effect_string, const char *filename, } gs_shader_t *gs_vertexshader_create_from_file(const char *file, - char **error_string) + char **error_string) { if (!gs_valid_p("gs_vertexshader_create_from_file", file)) return NULL; @@ -859,8 +869,7 @@ gs_shader_t *gs_vertexshader_create_from_file(const char *file, file_string = os_quick_read_utf8_file(file); if (!file_string) { - blog(LOG_ERROR, "Could not load vertex shader file '%s'", - file); + blog(LOG_ERROR, "Could not load vertex shader file '%s'", file); return NULL; } @@ -871,7 +880,7 @@ gs_shader_t *gs_vertexshader_create_from_file(const char *file, } gs_shader_t *gs_pixelshader_create_from_file(const char *file, - char **error_string) + char **error_string) { char *file_string; gs_shader_t *shader = NULL; @@ -881,8 +890,7 @@ gs_shader_t *gs_pixelshader_create_from_file(const char *file, file_string = os_quick_read_utf8_file(file); if (!file_string) { - blog(LOG_ERROR, "Could not load pixel shader file '%s'", - file); + blog(LOG_ERROR, "Could not load pixel shader file '%s'", file); return NULL; } @@ -902,7 +910,7 @@ gs_texture_t *gs_texture_create_from_file(const char *file) if (data) { tex = gs_texture_create(cx, cy, format, 1, - (const uint8_t**)&data, 0); + (const uint8_t **)&data, 0); bfree(data); } @@ -910,14 +918,14 @@ gs_texture_t *gs_texture_create_from_file(const char *file) } static inline void assign_sprite_rect(float *start, float *end, float size, - bool flip) + bool flip) { if (!flip) { *start = 0.0f; - *end = size; + *end = size; } else { *start = size; - *end = 0.0f; + *end = 0.0f; } } @@ -925,30 +933,30 @@ static inline void assign_sprite_uv(float *start, float *end, bool flip) { if (!flip) { *start = 0.0f; - *end = 1.0f; + *end = 1.0f; } else { *start = 1.0f; - *end = 0.0f; + *end = 0.0f; } } static void build_sprite(struct gs_vb_data *data, float fcx, float fcy, - float start_u, float end_u, float start_v, float end_v) + float start_u, float end_u, float start_v, float end_v) { struct vec2 *tvarray = data->tvarray[0].array; vec3_zero(data->points); - vec3_set(data->points+1, fcx, 0.0f, 0.0f); - vec3_set(data->points+2, 0.0f, fcy, 0.0f); - vec3_set(data->points+3, fcx, fcy, 0.0f); - vec2_set(tvarray, start_u, start_v); - vec2_set(tvarray+1, end_u, start_v); - vec2_set(tvarray+2, start_u, end_v); - vec2_set(tvarray+3, end_u, end_v); + vec3_set(data->points + 1, fcx, 0.0f, 0.0f); + vec3_set(data->points + 2, 0.0f, fcy, 0.0f); + vec3_set(data->points + 3, fcx, fcy, 0.0f); + vec2_set(tvarray, start_u, start_v); + vec2_set(tvarray + 1, end_u, start_v); + vec2_set(tvarray + 2, start_u, end_v); + vec2_set(tvarray + 3, end_u, end_v); } static inline void build_sprite_norm(struct gs_vb_data *data, float fcx, - float fcy, uint32_t flip) + float fcy, uint32_t flip) { float start_u, end_u; float start_v, end_v; @@ -958,47 +966,48 @@ static inline void build_sprite_norm(struct gs_vb_data *data, float fcx, build_sprite(data, fcx, fcy, start_u, end_u, start_v, end_v); } -static inline void build_subsprite_norm(struct gs_vb_data *data, - float fsub_x, float fsub_y, float fsub_cx, float fsub_cy, - float fcx, float fcy, uint32_t flip) +static inline void build_subsprite_norm(struct gs_vb_data *data, float fsub_x, + float fsub_y, float fsub_cx, + float fsub_cy, float fcx, float fcy, + uint32_t flip) { float start_u, end_u; float start_v, end_v; if ((flip & GS_FLIP_U) == 0) { start_u = fsub_x / fcx; - end_u = (fsub_x + fsub_cx) / fcx; + end_u = (fsub_x + fsub_cx) / fcx; } else { start_u = (fsub_x + fsub_cx) / fcx; - end_u = fsub_x / fcx; + end_u = fsub_x / fcx; } if ((flip & GS_FLIP_V) == 0) { start_v = fsub_y / fcy; - end_v = (fsub_y + fsub_cy) / fcy; + end_v = (fsub_y + fsub_cy) / fcy; } else { start_v = (fsub_y + fsub_cy) / fcy; - end_v = fsub_y / fcy; + end_v = fsub_y / fcy; } build_sprite(data, fsub_cx, fsub_cy, start_u, end_u, start_v, end_v); } static inline void build_sprite_rect(struct gs_vb_data *data, gs_texture_t *tex, - float fcx, float fcy, uint32_t flip) + float fcx, float fcy, uint32_t flip) { float start_u, end_u; float start_v, end_v; - float width = (float)gs_texture_get_width(tex); + float width = (float)gs_texture_get_width(tex); float height = (float)gs_texture_get_height(tex); - assign_sprite_rect(&start_u, &end_u, width, (flip & GS_FLIP_U) != 0); + assign_sprite_rect(&start_u, &end_u, width, (flip & GS_FLIP_U) != 0); assign_sprite_rect(&start_v, &end_v, height, (flip & GS_FLIP_V) != 0); build_sprite(data, fcx, fcy, start_u, end_u, start_v, end_v); } void gs_draw_sprite(gs_texture_t *tex, uint32_t flip, uint32_t width, - uint32_t height) + uint32_t height) { graphics_t *graphics = thread_graphics; float fcx, fcy; @@ -1017,7 +1026,7 @@ void gs_draw_sprite(gs_texture_t *tex, uint32_t flip, uint32_t width, } } - fcx = width ? (float)width : (float)gs_texture_get_width(tex); + fcx = width ? (float)width : (float)gs_texture_get_width(tex); fcy = height ? (float)height : (float)gs_texture_get_height(tex); data = gs_vertexbuffer_get_data(graphics->sprite_buffer); @@ -1033,9 +1042,8 @@ void gs_draw_sprite(gs_texture_t *tex, uint32_t flip, uint32_t width, gs_draw(GS_TRISTRIP, 0, 0); } -void gs_draw_sprite_subregion(gs_texture_t *tex, uint32_t flip, - uint32_t sub_x, uint32_t sub_y, - uint32_t sub_cx, uint32_t sub_cy) +void gs_draw_sprite_subregion(gs_texture_t *tex, uint32_t flip, uint32_t sub_x, + uint32_t sub_y, uint32_t sub_cx, uint32_t sub_cy) { graphics_t *graphics = thread_graphics; float fcx, fcy; @@ -1052,10 +1060,8 @@ void gs_draw_sprite_subregion(gs_texture_t *tex, uint32_t flip, fcy = (float)gs_texture_get_height(tex); data = gs_vertexbuffer_get_data(graphics->sprite_buffer); - build_subsprite_norm(data, - (float)sub_x, (float)sub_y, - (float)sub_cx, (float)sub_cy, - fcx, fcy, flip); + build_subsprite_norm(data, (float)sub_x, (float)sub_y, (float)sub_cx, + (float)sub_cy, fcx, fcy, flip); gs_vertexbuffer_flush(graphics->sprite_buffer); gs_load_vertexbuffer(graphics->sprite_buffer); @@ -1065,7 +1071,8 @@ void gs_draw_sprite_subregion(gs_texture_t *tex, uint32_t flip, } void gs_draw_cube_backdrop(gs_texture_t *cubetex, const struct quat *rot, - float left, float right, float top, float bottom, float znear) + float left, float right, float top, float bottom, + float znear) { /* TODO */ UNUSED_PARAMETER(cubetex); @@ -1112,8 +1119,8 @@ void gs_viewport_push(void) if (!gs_valid("gs_viewport_push")) return; - struct gs_rect *rect = da_push_back_new( - thread_graphics->viewport_stack); + struct gs_rect *rect = + da_push_back_new(thread_graphics->viewport_stack); gs_get_viewport(rect); } @@ -1132,7 +1139,7 @@ void gs_viewport_pop(void) } void gs_texture_set_image(gs_texture_t *tex, const uint8_t *data, - uint32_t linesize, bool flip) + uint32_t linesize, bool flip) { uint8_t *ptr; uint32_t linesize_out; @@ -1151,8 +1158,8 @@ void gs_texture_set_image(gs_texture_t *tex, const uint8_t *data, row_copy = (linesize < linesize_out) ? linesize : linesize_out; if (flip) { - for (y = height-1; y >= 0; y--) - memcpy(ptr + (uint32_t)y * linesize_out, + for (y = height - 1; y >= 0; y--) + memcpy(ptr + (uint32_t)y * linesize_out, data + (uint32_t)(height - y - 1) * linesize, row_copy); @@ -1161,16 +1168,15 @@ void gs_texture_set_image(gs_texture_t *tex, const uint8_t *data, } else { for (y = 0; y < height; y++) - memcpy(ptr + (uint32_t)y * linesize_out, - data + (uint32_t)y * linesize, - row_copy); + memcpy(ptr + (uint32_t)y * linesize_out, + data + (uint32_t)y * linesize, row_copy); } gs_texture_unmap(tex); } void gs_cubetexture_set_image(gs_texture_t *cubetex, uint32_t side, - const void *data, uint32_t linesize, bool invert) + const void *data, uint32_t linesize, bool invert) { /* TODO */ UNUSED_PARAMETER(cubetex); @@ -1188,14 +1194,14 @@ void gs_perspective(float angle, float aspect, float near, float far) if (!gs_valid("gs_perspective")) return; - ymax = near * tanf(RAD(angle)*0.5f); + ymax = near * tanf(RAD(angle) * 0.5f); ymin = -ymax; xmin = ymin * aspect; xmax = ymax * aspect; - graphics->exports.device_frustum(graphics->device, xmin, xmax, - ymin, ymax, near, far); + graphics->exports.device_frustum(graphics->device, xmin, xmax, ymin, + ymax, near, far); } void gs_blend_state_push(void) @@ -1221,8 +1227,8 @@ void gs_blend_state_pop(void) return; gs_enable_blending(state->enabled); - gs_blend_function_separate(state->src_c, state->dest_c, - state->src_a, state->dest_a); + gs_blend_function_separate(state->src_c, state->dest_c, state->src_a, + state->dest_a); da_pop_back(graphics->blend_state_stack); } @@ -1237,13 +1243,13 @@ void gs_reset_blend_state(void) if (!graphics->cur_blend_state.enabled) gs_enable_blending(true); - if (graphics->cur_blend_state.src_c != GS_BLEND_SRCALPHA || + if (graphics->cur_blend_state.src_c != GS_BLEND_SRCALPHA || graphics->cur_blend_state.dest_c != GS_BLEND_INVSRCALPHA || - graphics->cur_blend_state.src_a != GS_BLEND_ONE || + graphics->cur_blend_state.src_a != GS_BLEND_ONE || graphics->cur_blend_state.dest_a != GS_BLEND_INVSRCALPHA) - gs_blend_function_separate( - GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, - GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); + gs_blend_function_separate(GS_BLEND_SRCALPHA, + GS_BLEND_INVSRCALPHA, GS_BLEND_ONE, + GS_BLEND_INVSRCALPHA); } /* ------------------------------------------------------------------------- */ @@ -1270,7 +1276,7 @@ gs_swapchain_t *gs_swapchain_create(const struct gs_init_data *data) new_data.num_backbuffers = 1; return graphics->exports.device_swapchain_create(graphics->device, - &new_data); + &new_data); } void gs_resize(uint32_t x, uint32_t y) @@ -1315,12 +1321,13 @@ uint32_t gs_get_height(void) static inline bool is_pow2(uint32_t size) { - return size >= 2 && (size & (size-1)) == 0; + return size >= 2 && (size & (size - 1)) == 0; } gs_texture_t *gs_texture_create(uint32_t width, uint32_t height, - enum gs_color_format color_format, uint32_t levels, - const uint8_t **data, uint32_t flags) + enum gs_color_format color_format, + uint32_t levels, const uint8_t **data, + uint32_t flags) { graphics_t *graphics = thread_graphics; bool pow2tex = is_pow2(width) && is_pow2(height); @@ -1331,8 +1338,8 @@ gs_texture_t *gs_texture_create(uint32_t width, uint32_t height, if (uses_mipmaps && !pow2tex) { blog(LOG_WARNING, "Cannot use mipmaps with a " - "non-power-of-two texture. Disabling " - "mipmaps for this texture."); + "non-power-of-two texture. Disabling " + "mipmaps for this texture."); uses_mipmaps = false; flags &= ~GS_BUILD_MIPMAPS; @@ -1341,18 +1348,20 @@ gs_texture_t *gs_texture_create(uint32_t width, uint32_t height, if (uses_mipmaps && flags & GS_RENDER_TARGET) { blog(LOG_WARNING, "Cannot use mipmaps with render targets. " - "Disabling mipmaps for this texture."); + "Disabling mipmaps for this texture."); flags &= ~GS_BUILD_MIPMAPS; levels = 1; } - return graphics->exports.device_texture_create(graphics->device, - width, height, color_format, levels, data, flags); + return graphics->exports.device_texture_create(graphics->device, width, + height, color_format, + levels, data, flags); } gs_texture_t *gs_cubetexture_create(uint32_t size, - enum gs_color_format color_format, uint32_t levels, - const uint8_t **data, uint32_t flags) + enum gs_color_format color_format, + uint32_t levels, const uint8_t **data, + uint32_t flags) { graphics_t *graphics = thread_graphics; bool pow2tex = is_pow2(size); @@ -1363,8 +1372,8 @@ gs_texture_t *gs_cubetexture_create(uint32_t size, if (uses_mipmaps && !pow2tex) { blog(LOG_WARNING, "Cannot use mipmaps with a " - "non-power-of-two texture. Disabling " - "mipmaps for this texture."); + "non-power-of-two texture. Disabling " + "mipmaps for this texture."); uses_mipmaps = false; flags &= ~GS_BUILD_MIPMAPS; @@ -1373,19 +1382,21 @@ gs_texture_t *gs_cubetexture_create(uint32_t size, if (uses_mipmaps && flags & GS_RENDER_TARGET) { blog(LOG_WARNING, "Cannot use mipmaps with render targets. " - "Disabling mipmaps for this texture."); + "Disabling mipmaps for this texture."); flags &= ~GS_BUILD_MIPMAPS; levels = 1; - data = NULL; + data = NULL; } - return graphics->exports.device_cubetexture_create(graphics->device, - size, color_format, levels, data, flags); + return graphics->exports.device_cubetexture_create( + graphics->device, size, color_format, levels, data, flags); } gs_texture_t *gs_voltexture_create(uint32_t width, uint32_t height, - uint32_t depth, enum gs_color_format color_format, - uint32_t levels, const uint8_t **data, uint32_t flags) + uint32_t depth, + enum gs_color_format color_format, + uint32_t levels, const uint8_t **data, + uint32_t flags) { graphics_t *graphics = thread_graphics; @@ -1393,32 +1404,33 @@ gs_texture_t *gs_voltexture_create(uint32_t width, uint32_t height, return NULL; return graphics->exports.device_voltexture_create(graphics->device, - width, height, depth, color_format, levels, data, - flags); + width, height, depth, + color_format, levels, + data, flags); } gs_zstencil_t *gs_zstencil_create(uint32_t width, uint32_t height, - enum gs_zstencil_format format) + enum gs_zstencil_format format) { graphics_t *graphics = thread_graphics; if (!gs_valid("gs_zstencil_create")) return NULL; - return graphics->exports.device_zstencil_create(graphics->device, - width, height, format); + return graphics->exports.device_zstencil_create(graphics->device, width, + height, format); } gs_stagesurf_t *gs_stagesurface_create(uint32_t width, uint32_t height, - enum gs_color_format color_format) + enum gs_color_format color_format) { graphics_t *graphics = thread_graphics; if (!gs_valid("gs_stagesurface_create")) return NULL; - return graphics->exports.device_stagesurface_create(graphics->device, - width, height, color_format); + return graphics->exports.device_stagesurface_create( + graphics->device, width, height, color_format); } gs_samplerstate_t *gs_samplerstate_create(const struct gs_sampler_info *info) @@ -1429,35 +1441,34 @@ gs_samplerstate_t *gs_samplerstate_create(const struct gs_sampler_info *info) return NULL; return graphics->exports.device_samplerstate_create(graphics->device, - info); + info); } gs_shader_t *gs_vertexshader_create(const char *shader, const char *file, - char **error_string) + char **error_string) { graphics_t *graphics = thread_graphics; if (!gs_valid_p("gs_vertexshader_create", shader)) return NULL; - return graphics->exports.device_vertexshader_create(graphics->device, - shader, file, error_string); + return graphics->exports.device_vertexshader_create( + graphics->device, shader, file, error_string); } -gs_shader_t *gs_pixelshader_create(const char *shader, - const char *file, char **error_string) +gs_shader_t *gs_pixelshader_create(const char *shader, const char *file, + char **error_string) { graphics_t *graphics = thread_graphics; if (!gs_valid_p("gs_pixelshader_create", shader)) return NULL; - return graphics->exports.device_pixelshader_create(graphics->device, - shader, file, error_string); + return graphics->exports.device_pixelshader_create( + graphics->device, shader, file, error_string); } -gs_vertbuffer_t *gs_vertexbuffer_create(struct gs_vb_data *data, - uint32_t flags) +gs_vertbuffer_t *gs_vertexbuffer_create(struct gs_vb_data *data, uint32_t flags) { graphics_t *graphics = thread_graphics; @@ -1469,13 +1480,12 @@ gs_vertbuffer_t *gs_vertexbuffer_create(struct gs_vb_data *data, new_data->num = data->num; -#define DUP_VAL(val) \ - do { \ - if (data->val) \ - new_data->val = bmemdup(data->val, \ - sizeof(*data->val) * \ - data->num); \ - } while (false) +#define DUP_VAL(val) \ + do { \ + if (data->val) \ + new_data->val = bmemdup( \ + data->val, sizeof(*data->val) * data->num); \ + } while (false) DUP_VAL(points); DUP_VAL(normals); @@ -1486,8 +1496,7 @@ gs_vertbuffer_t *gs_vertexbuffer_create(struct gs_vb_data *data, if (data->tvarray && data->num_tex) { new_data->num_tex = data->num_tex; new_data->tvarray = bzalloc( - sizeof(struct gs_tvertarray) * - data->num_tex); + sizeof(struct gs_tvertarray) * data->num_tex); for (size_t i = 0; i < data->num_tex; i++) { struct gs_tvertarray *tv = &data->tvarray[i]; @@ -1496,8 +1505,8 @@ gs_vertbuffer_t *gs_vertexbuffer_create(struct gs_vb_data *data, size_t size = tv->width * sizeof(float); new_tv->width = tv->width; - new_tv->array = bmemdup(tv->array, - size * data->num); + new_tv->array = + bmemdup(tv->array, size * data->num); } } @@ -1505,11 +1514,11 @@ gs_vertbuffer_t *gs_vertexbuffer_create(struct gs_vb_data *data, } return graphics->exports.device_vertexbuffer_create(graphics->device, - data, flags); + data, flags); } -gs_indexbuffer_t *gs_indexbuffer_create(enum gs_index_type type, - void *indices, size_t num, uint32_t flags) +gs_indexbuffer_t *gs_indexbuffer_create(enum gs_index_type type, void *indices, + size_t num, uint32_t flags) { graphics_t *graphics = thread_graphics; @@ -1521,8 +1530,28 @@ gs_indexbuffer_t *gs_indexbuffer_create(enum gs_index_type type, indices = bmemdup(indices, size * num); } - return graphics->exports.device_indexbuffer_create(graphics->device, - type, indices, num, flags); + return graphics->exports.device_indexbuffer_create( + graphics->device, type, indices, num, flags); +} + +gs_timer_t *gs_timer_create() +{ + graphics_t *graphics = thread_graphics; + + if (!gs_valid("gs_timer_create")) + return NULL; + + return graphics->exports.device_timer_create(graphics->device); +} + +gs_timer_range_t *gs_timer_range_create() +{ + graphics_t *graphics = thread_graphics; + + if (!gs_valid("gs_timer_range_create")) + return NULL; + + return graphics->exports.device_timer_range_create(graphics->device); } enum gs_texture_type gs_get_texture_type(const gs_texture_t *texture) @@ -1543,7 +1572,7 @@ void gs_load_vertexbuffer(gs_vertbuffer_t *vertbuffer) return; graphics->exports.device_load_vertexbuffer(graphics->device, - vertbuffer); + vertbuffer); } void gs_load_indexbuffer(gs_indexbuffer_t *indexbuffer) @@ -1554,7 +1583,7 @@ void gs_load_indexbuffer(gs_indexbuffer_t *indexbuffer) return; graphics->exports.device_load_indexbuffer(graphics->device, - indexbuffer); + indexbuffer); } void gs_load_texture(gs_texture_t *tex, int unit) @@ -1575,7 +1604,7 @@ void gs_load_samplerstate(gs_samplerstate_t *samplerstate, int unit) return; graphics->exports.device_load_samplerstate(graphics->device, - samplerstate, unit); + samplerstate, unit); } void gs_load_vertexshader(gs_shader_t *vertshader) @@ -1586,7 +1615,7 @@ void gs_load_vertexshader(gs_shader_t *vertshader) return; graphics->exports.device_load_vertexshader(graphics->device, - vertshader); + vertshader); } void gs_load_pixelshader(gs_shader_t *pixelshader) @@ -1597,7 +1626,7 @@ void gs_load_pixelshader(gs_shader_t *pixelshader) return; graphics->exports.device_load_pixelshader(graphics->device, - pixelshader); + pixelshader); } void gs_load_default_samplerstate(bool b_3d, int unit) @@ -1608,7 +1637,7 @@ void gs_load_default_samplerstate(bool b_3d, int unit) return; graphics->exports.device_load_default_samplerstate(graphics->device, - b_3d, unit); + b_3d, unit); } gs_shader_t *gs_get_vertex_shader(void) @@ -1659,19 +1688,19 @@ void gs_set_render_target(gs_texture_t *tex, gs_zstencil_t *zstencil) return; graphics->exports.device_set_render_target(graphics->device, tex, - zstencil); + zstencil); } void gs_set_cube_render_target(gs_texture_t *cubetex, int side, - gs_zstencil_t *zstencil) + gs_zstencil_t *zstencil) { graphics_t *graphics = thread_graphics; if (!gs_valid("gs_set_cube_render_target")) return; - graphics->exports.device_set_cube_render_target(graphics->device, - cubetex, side, zstencil); + graphics->exports.device_set_cube_render_target( + graphics->device, cubetex, side, zstencil); } void gs_copy_texture(gs_texture_t *dst, gs_texture_t *src) @@ -1685,17 +1714,17 @@ void gs_copy_texture(gs_texture_t *dst, gs_texture_t *src) } void gs_copy_texture_region(gs_texture_t *dst, uint32_t dst_x, uint32_t dst_y, - gs_texture_t *src, uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) + gs_texture_t *src, uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h) { graphics_t *graphics = thread_graphics; if (!gs_valid_p("gs_copy_texture_region", dst)) return; - graphics->exports.device_copy_texture_region(graphics->device, - dst, dst_x, dst_y, - src, src_x, src_y, src_w, src_h); + graphics->exports.device_copy_texture_region(graphics->device, dst, + dst_x, dst_y, src, src_x, + src_y, src_w, src_h); } void gs_stage_texture(gs_stagesurf_t *dst, gs_texture_t *src) @@ -1719,15 +1748,15 @@ void gs_begin_scene(void) } void gs_draw(enum gs_draw_mode draw_mode, uint32_t start_vert, - uint32_t num_verts) + uint32_t num_verts) { graphics_t *graphics = thread_graphics; if (!gs_valid("gs_draw")) return; - graphics->exports.device_draw(graphics->device, draw_mode, - start_vert, num_verts); + graphics->exports.device_draw(graphics->device, draw_mode, start_vert, + num_verts); } void gs_end_scene(void) @@ -1751,7 +1780,7 @@ void gs_load_swapchain(gs_swapchain_t *swapchain) } void gs_clear(uint32_t clear_flags, const struct vec4 *color, float depth, - uint8_t stencil) + uint8_t stencil) { graphics_t *graphics = thread_graphics; @@ -1759,7 +1788,7 @@ void gs_clear(uint32_t clear_flags, const struct vec4 *color, float depth, return; graphics->exports.device_clear(graphics->device, clear_flags, color, - depth, stencil); + depth, stencil); } void gs_present(void) @@ -1851,7 +1880,7 @@ void gs_enable_color(bool red, bool green, bool blue, bool alpha) return; graphics->exports.device_enable_color(graphics->device, red, green, - blue, alpha); + blue, alpha); } void gs_blend_function(enum gs_blend_type src, enum gs_blend_type dest) @@ -1861,28 +1890,29 @@ void gs_blend_function(enum gs_blend_type src, enum gs_blend_type dest) if (!gs_valid("gs_blend_function")) return; - graphics->cur_blend_state.src_c = src; + graphics->cur_blend_state.src_c = src; graphics->cur_blend_state.dest_c = dest; - graphics->cur_blend_state.src_a = src; + graphics->cur_blend_state.src_a = src; graphics->cur_blend_state.dest_a = dest; graphics->exports.device_blend_function(graphics->device, src, dest); } -void gs_blend_function_separate( - enum gs_blend_type src_c, enum gs_blend_type dest_c, - enum gs_blend_type src_a, enum gs_blend_type dest_a) +void gs_blend_function_separate(enum gs_blend_type src_c, + enum gs_blend_type dest_c, + enum gs_blend_type src_a, + enum gs_blend_type dest_a) { graphics_t *graphics = thread_graphics; if (!gs_valid("gs_blend_function_separate")) return; - graphics->cur_blend_state.src_c = src_c; + graphics->cur_blend_state.src_c = src_c; graphics->cur_blend_state.dest_c = dest_c; - graphics->cur_blend_state.src_a = src_a; + graphics->cur_blend_state.src_a = src_a; graphics->cur_blend_state.dest_a = dest_a; - graphics->exports.device_blend_function_separate(graphics->device, - src_c, dest_c, src_a, dest_a); + graphics->exports.device_blend_function_separate( + graphics->device, src_c, dest_c, src_a, dest_a); } void gs_depth_function(enum gs_depth_test test) @@ -1906,7 +1936,7 @@ void gs_stencil_function(enum gs_stencil_side side, enum gs_depth_test test) } void gs_stencil_op(enum gs_stencil_side side, enum gs_stencil_op_type fail, - enum gs_stencil_op_type zfail, enum gs_stencil_op_type zpass) + enum gs_stencil_op_type zfail, enum gs_stencil_op_type zpass) { graphics_t *graphics = thread_graphics; @@ -1914,7 +1944,7 @@ void gs_stencil_op(enum gs_stencil_side side, enum gs_stencil_op_type fail, return; graphics->exports.device_stencil_op(graphics->device, side, fail, zfail, - zpass); + zpass); } void gs_set_viewport(int x, int y, int width, int height) @@ -1925,7 +1955,7 @@ void gs_set_viewport(int x, int y, int width, int height) return; graphics->exports.device_set_viewport(graphics->device, x, y, width, - height); + height); } void gs_get_viewport(struct gs_rect *rect) @@ -1949,7 +1979,7 @@ void gs_set_scissor_rect(const struct gs_rect *rect) } void gs_ortho(float left, float right, float top, float bottom, float znear, - float zfar) + float zfar) { graphics_t *graphics = thread_graphics; @@ -1957,7 +1987,7 @@ void gs_ortho(float left, float right, float top, float bottom, float znear, return; graphics->exports.device_ortho(graphics->device, left, right, top, - bottom, znear, zfar); + bottom, znear, zfar); } void gs_frustum(float left, float right, float top, float bottom, float znear, @@ -1969,7 +1999,7 @@ void gs_frustum(float left, float right, float top, float bottom, float znear, return; graphics->exports.device_frustum(graphics->device, left, right, top, - bottom, znear, zfar); + bottom, znear, zfar); } void gs_projection_push(void) @@ -2067,7 +2097,7 @@ gs_sparam_t *gs_shader_get_world_matrix(const gs_shader_t *shader) } void gs_shader_get_param_info(const gs_sparam_t *param, - struct gs_shader_param_info *info) + struct gs_shader_param_info *info) { graphics_t *graphics = thread_graphics; @@ -2304,8 +2334,8 @@ uint32_t gs_cubetexture_get_size(const gs_texture_t *cubetex) return graphics->exports.gs_cubetexture_get_size(cubetex); } -enum gs_color_format gs_cubetexture_get_color_format( - const gs_texture_t *cubetex) +enum gs_color_format +gs_cubetexture_get_color_format(const gs_texture_t *cubetex) { graphics_t *graphics = thread_graphics; @@ -2399,8 +2429,8 @@ uint32_t gs_stagesurface_get_height(const gs_stagesurf_t *stagesurf) return graphics->exports.gs_stagesurface_get_height(stagesurf); } -enum gs_color_format gs_stagesurface_get_color_format( - const gs_stagesurf_t *stagesurf) +enum gs_color_format +gs_stagesurface_get_color_format(const gs_stagesurf_t *stagesurf) { graphics_t *graphics = thread_graphics; @@ -2411,7 +2441,7 @@ enum gs_color_format gs_stagesurface_get_color_format( } bool gs_stagesurface_map(gs_stagesurf_t *stagesurf, uint8_t **data, - uint32_t *linesize) + uint32_t *linesize) { graphics_t *graphics = thread_graphics; @@ -2472,13 +2502,12 @@ void gs_vertexbuffer_flush(gs_vertbuffer_t *vertbuffer) } void gs_vertexbuffer_flush_direct(gs_vertbuffer_t *vertbuffer, - const struct gs_vb_data *data) + const struct gs_vb_data *data) { if (!gs_valid_p2("gs_vertexbuffer_flush_direct", vertbuffer, data)) return; - thread_graphics->exports.gs_vertexbuffer_flush_direct(vertbuffer, - data); + thread_graphics->exports.gs_vertexbuffer_flush_direct(vertbuffer, data); } struct gs_vb_data *gs_vertexbuffer_get_data(const gs_vertbuffer_t *vertbuffer) @@ -2501,7 +2530,7 @@ void gs_indexbuffer_destroy(gs_indexbuffer_t *indexbuffer) graphics->exports.gs_indexbuffer_destroy(indexbuffer); } -void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer) +void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer) { if (!gs_valid_p("gs_indexbuffer_flush", indexbuffer)) return; @@ -2509,8 +2538,8 @@ void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer) thread_graphics->exports.gs_indexbuffer_flush(indexbuffer); } -void gs_indexbuffer_flush_direct(gs_indexbuffer_t *indexbuffer, - const void *data) +void gs_indexbuffer_flush_direct(gs_indexbuffer_t *indexbuffer, + const void *data) { if (!gs_valid_p2("gs_indexbuffer_flush_direct", indexbuffer, data)) return; @@ -2518,7 +2547,7 @@ void gs_indexbuffer_flush_direct(gs_indexbuffer_t *indexbuffer, thread_graphics->exports.gs_indexbuffer_flush_direct(indexbuffer, data); } -void *gs_indexbuffer_get_data(const gs_indexbuffer_t *indexbuffer) +void *gs_indexbuffer_get_data(const gs_indexbuffer_t *indexbuffer) { if (!gs_valid_p("gs_indexbuffer_get_data", indexbuffer)) return NULL; @@ -2532,7 +2561,7 @@ size_t gs_indexbuffer_get_num_indices(const gs_indexbuffer_t *indexbuffer) return 0; return thread_graphics->exports.gs_indexbuffer_get_num_indices( - indexbuffer); + indexbuffer); } enum gs_index_type gs_indexbuffer_get_type(const gs_indexbuffer_t *indexbuffer) @@ -2543,6 +2572,96 @@ enum gs_index_type gs_indexbuffer_get_type(const gs_indexbuffer_t *indexbuffer) return thread_graphics->exports.gs_indexbuffer_get_type(indexbuffer); } +void gs_timer_destroy(gs_timer_t *timer) +{ + graphics_t *graphics = thread_graphics; + + if (!gs_valid("gs_timer_destroy")) + return; + if (!timer) + return; + + graphics->exports.gs_timer_destroy(timer); +} + +void gs_timer_begin(gs_timer_t *timer) +{ + graphics_t *graphics = thread_graphics; + + if (!gs_valid("gs_timer_begin")) + return; + if (!timer) + return; + + graphics->exports.gs_timer_begin(timer); +} + +void gs_timer_end(gs_timer_t *timer) +{ + graphics_t *graphics = thread_graphics; + + if (!gs_valid("gs_timer_end")) + return; + if (!timer) + return; + + graphics->exports.gs_timer_end(timer); +} + +bool gs_timer_get_data(gs_timer_t *timer, uint64_t *ticks) +{ + if (!gs_valid_p2("gs_timer_get_data", timer, ticks)) + return false; + + return thread_graphics->exports.gs_timer_get_data(timer, ticks); +} + +void gs_timer_range_destroy(gs_timer_range_t *range) +{ + graphics_t *graphics = thread_graphics; + + if (!gs_valid("gs_timer_range_destroy")) + return; + if (!range) + return; + + graphics->exports.gs_timer_range_destroy(range); +} + +void gs_timer_range_begin(gs_timer_range_t *range) +{ + graphics_t *graphics = thread_graphics; + + if (!gs_valid("gs_timer_range_begin")) + return; + if (!range) + return; + + graphics->exports.gs_timer_range_begin(range); +} + +void gs_timer_range_end(gs_timer_range_t *range) +{ + graphics_t *graphics = thread_graphics; + + if (!gs_valid("gs_timer_range_end")) + return; + if (!range) + return; + + graphics->exports.gs_timer_range_end(range); +} + +bool gs_timer_range_get_data(gs_timer_range_t *range, bool *disjoint, + uint64_t *frequency) +{ + if (!gs_valid_p2("gs_timer_range_get_data", disjoint, frequency)) + return false; + + return thread_graphics->exports.gs_timer_range_get_data(range, disjoint, + frequency); +} + bool gs_nv12_available(void) { if (!gs_valid("gs_nv12_available")) @@ -2552,11 +2671,10 @@ bool gs_nv12_available(void) return false; return thread_graphics->exports.device_nv12_available( - thread_graphics->device); + thread_graphics->device); } -void gs_debug_marker_begin(const float color[4], - const char *markername) +void gs_debug_marker_begin(const float color[4], const char *markername) { if (!gs_valid("gs_debug_marker_begin")) return; @@ -2565,12 +2683,10 @@ void gs_debug_marker_begin(const float color[4], markername = "(null)"; thread_graphics->exports.device_debug_marker_begin( - thread_graphics->device, markername, - color); + thread_graphics->device, markername, color); } -void gs_debug_marker_begin_format(const float color[4], - const char *format, ...) +void gs_debug_marker_begin_format(const float color[4], const char *format, ...) { if (!gs_valid("gs_debug_marker_begin")) return; @@ -2582,8 +2698,7 @@ void gs_debug_marker_begin_format(const float color[4], vsnprintf(markername, sizeof(markername), format, args); va_end(args); thread_graphics->exports.device_debug_marker_begin( - thread_graphics->device, markername, - color); + thread_graphics->device, markername, color); } else { gs_debug_marker_begin(color, NULL); } @@ -2595,7 +2710,7 @@ void gs_debug_marker_end(void) return; thread_graphics->exports.device_debug_marker_end( - thread_graphics->device); + thread_graphics->device); } #ifdef __APPLE__ @@ -2611,7 +2726,7 @@ gs_texture_t *gs_texture_create_from_iosurface(void *iosurf) return NULL; return graphics->exports.device_texture_create_from_iosurface( - graphics->device, iosurf); + graphics->device, iosurf); } bool gs_texture_rebind_iosurface(gs_texture_t *texture, void *iosurf) @@ -2645,7 +2760,7 @@ bool gs_shared_texture_available(void) } bool gs_get_duplicator_monitor_info(int monitor_idx, - struct gs_monitor_info *monitor_info) + struct gs_monitor_info *monitor_info) { if (!gs_valid_p("gs_get_duplicator_monitor_info", monitor_info)) return false; @@ -2653,8 +2768,7 @@ bool gs_get_duplicator_monitor_info(int monitor_idx, return false; return thread_graphics->exports.device_get_duplicator_monitor_info( - thread_graphics->device, monitor_idx, - monitor_info); + thread_graphics->device, monitor_idx, monitor_info); } gs_duplicator_t *gs_duplicator_create(int monitor_idx) @@ -2665,7 +2779,7 @@ gs_duplicator_t *gs_duplicator_create(int monitor_idx) return NULL; return thread_graphics->exports.device_duplicator_create( - thread_graphics->device, monitor_idx); + thread_graphics->device, monitor_idx); } void gs_duplicator_destroy(gs_duplicator_t *duplicator) @@ -2710,7 +2824,7 @@ gs_texture_t *gs_texture_create_gdi(uint32_t width, uint32_t height) if (graphics->exports.device_texture_create_gdi) return graphics->exports.device_texture_create_gdi( - graphics->device, width, height); + graphics->device, width, height); return NULL; } @@ -2741,7 +2855,7 @@ gs_texture_t *gs_texture_open_shared(uint32_t handle) if (graphics->exports.device_texture_open_shared) return graphics->exports.device_texture_open_shared( - graphics->device, handle); + graphics->device, handle); return NULL; } @@ -2763,8 +2877,8 @@ int gs_texture_acquire_sync(gs_texture_t *tex, uint64_t key, uint32_t ms) return -1; if (graphics->exports.device_texture_acquire_sync) - return graphics->exports.device_texture_acquire_sync(tex, - key, ms); + return graphics->exports.device_texture_acquire_sync(tex, key, + ms); return -1; } @@ -2780,7 +2894,7 @@ int gs_texture_release_sync(gs_texture_t *tex, uint64_t key) } bool gs_texture_create_nv12(gs_texture_t **tex_y, gs_texture_t **tex_uv, - uint32_t width, uint32_t height, uint32_t flags) + uint32_t width, uint32_t height, uint32_t flags) { graphics_t *graphics = thread_graphics; bool success = false; @@ -2796,15 +2910,14 @@ bool gs_texture_create_nv12(gs_texture_t **tex_y, gs_texture_t **tex_uv, if (graphics->exports.device_texture_create_nv12) { success = graphics->exports.device_texture_create_nv12( - graphics->device, tex_y, tex_uv, - width, height, flags); + graphics->device, tex_y, tex_uv, width, height, flags); if (success) return true; } *tex_y = gs_texture_create(width, height, GS_R8, 1, NULL, flags); *tex_uv = gs_texture_create(width / 2, height / 2, GS_R8G8, 1, NULL, - flags); + flags); if (!*tex_y || !*tex_uv) { if (*tex_y) @@ -2834,7 +2947,7 @@ gs_stagesurf_t *gs_stagesurface_create_nv12(uint32_t width, uint32_t height) if (graphics->exports.device_stagesurface_create_nv12) return graphics->exports.device_stagesurface_create_nv12( - graphics->device, width, height); + graphics->device, width, height); return NULL; } diff --git a/libobs/graphics/graphics.h b/libobs/graphics/graphics.h index a3f6de8..14245dd 100644 --- a/libobs/graphics/graphics.h +++ b/libobs/graphics/graphics.h @@ -50,7 +50,7 @@ enum gs_draw_mode { GS_LINES, GS_LINESTRIP, GS_TRIS, - GS_TRISTRIP + GS_TRISTRIP, }; enum gs_color_format { @@ -80,18 +80,18 @@ enum gs_zstencil_format { GS_Z16, GS_Z24_S8, GS_Z32F, - GS_Z32F_S8X24 + GS_Z32F_S8X24, }; enum gs_index_type { GS_UNSIGNED_SHORT, - GS_UNSIGNED_LONG + GS_UNSIGNED_LONG, }; enum gs_cull_mode { GS_BACK, GS_FRONT, - GS_NEITHER + GS_NEITHER, }; enum gs_blend_type { @@ -105,7 +105,7 @@ enum gs_blend_type { GS_BLEND_INVDSTCOLOR, GS_BLEND_DSTALPHA, GS_BLEND_INVDSTALPHA, - GS_BLEND_SRCALPHASAT + GS_BLEND_SRCALPHASAT, }; enum gs_depth_test { @@ -116,13 +116,13 @@ enum gs_depth_test { GS_GEQUAL, GS_GREATER, GS_NOTEQUAL, - GS_ALWAYS + GS_ALWAYS, }; enum gs_stencil_side { - GS_STENCIL_FRONT=1, + GS_STENCIL_FRONT = 1, GS_STENCIL_BACK, - GS_STENCIL_BOTH + GS_STENCIL_BOTH, }; enum gs_stencil_op_type { @@ -131,7 +131,7 @@ enum gs_stencil_op_type { GS_REPLACE, GS_INCR, GS_DECR, - GS_INVERT + GS_INVERT, }; enum gs_cube_sides { @@ -140,7 +140,7 @@ enum gs_cube_sides { GS_POSITIVE_Y, GS_NEGATIVE_Y, GS_POSITIVE_Z, - GS_NEGATIVE_Z + GS_NEGATIVE_Z, }; enum gs_sample_filter { @@ -160,13 +160,13 @@ enum gs_address_mode { GS_ADDRESS_WRAP, GS_ADDRESS_MIRROR, GS_ADDRESS_BORDER, - GS_ADDRESS_MIRRORONCE + GS_ADDRESS_MIRRORONCE, }; enum gs_texture_type { GS_TEXTURE_2D, GS_TEXTURE_3D, - GS_TEXTURE_CUBE + GS_TEXTURE_CUBE, }; struct gs_monitor_info { @@ -195,7 +195,7 @@ struct gs_vb_data { static inline struct gs_vb_data *gs_vbdata_create(void) { - return (struct gs_vb_data*)bzalloc(sizeof(struct gs_vb_data)); + return (struct gs_vb_data *)bzalloc(sizeof(struct gs_vb_data)); } static inline void gs_vbdata_destroy(struct gs_vb_data *data) @@ -247,6 +247,7 @@ struct gs_index_buffer; struct gs_sampler_state; struct gs_shader; struct gs_swap_chain; +struct gs_timer; struct gs_texrender; struct gs_shader_param; struct gs_effect; @@ -256,22 +257,24 @@ struct gs_effect_param; struct gs_device; struct graphics_subsystem; -typedef struct gs_texture gs_texture_t; -typedef struct gs_stage_surface gs_stagesurf_t; -typedef struct gs_zstencil_buffer gs_zstencil_t; -typedef struct gs_vertex_buffer gs_vertbuffer_t; -typedef struct gs_index_buffer gs_indexbuffer_t; -typedef struct gs_sampler_state gs_samplerstate_t; -typedef struct gs_swap_chain gs_swapchain_t; -typedef struct gs_texture_render gs_texrender_t; -typedef struct gs_shader gs_shader_t; -typedef struct gs_shader_param gs_sparam_t; -typedef struct gs_effect gs_effect_t; +typedef struct gs_texture gs_texture_t; +typedef struct gs_stage_surface gs_stagesurf_t; +typedef struct gs_zstencil_buffer gs_zstencil_t; +typedef struct gs_vertex_buffer gs_vertbuffer_t; +typedef struct gs_index_buffer gs_indexbuffer_t; +typedef struct gs_sampler_state gs_samplerstate_t; +typedef struct gs_swap_chain gs_swapchain_t; +typedef struct gs_timer gs_timer_t; +typedef struct gs_timer_range gs_timer_range_t; +typedef struct gs_texture_render gs_texrender_t; +typedef struct gs_shader gs_shader_t; +typedef struct gs_shader_param gs_sparam_t; +typedef struct gs_effect gs_effect_t; typedef struct gs_effect_technique gs_technique_t; -typedef struct gs_effect_pass gs_epass_t; -typedef struct gs_effect_param gs_eparam_t; -typedef struct gs_device gs_device_t; -typedef struct graphics_subsystem graphics_t; +typedef struct gs_effect_pass gs_epass_t; +typedef struct gs_effect_param gs_eparam_t; +typedef struct gs_device gs_device_t; +typedef struct graphics_subsystem graphics_t; /* --------------------------------------------------- * shader functions @@ -308,20 +311,22 @@ EXPORT void gs_shader_destroy(gs_shader_t *shader); EXPORT int gs_shader_get_num_params(const gs_shader_t *shader); EXPORT gs_sparam_t *gs_shader_get_param_by_idx(gs_shader_t *shader, - uint32_t param); + uint32_t param); EXPORT gs_sparam_t *gs_shader_get_param_by_name(gs_shader_t *shader, - const char *name); + const char *name); EXPORT gs_sparam_t *gs_shader_get_viewproj_matrix(const gs_shader_t *shader); EXPORT gs_sparam_t *gs_shader_get_world_matrix(const gs_shader_t *shader); EXPORT void gs_shader_get_param_info(const gs_sparam_t *param, - struct gs_shader_param_info *info); + struct gs_shader_param_info *info); EXPORT void gs_shader_set_bool(gs_sparam_t *param, bool val); EXPORT void gs_shader_set_float(gs_sparam_t *param, float val); EXPORT void gs_shader_set_int(gs_sparam_t *param, int val); -EXPORT void gs_shader_set_matrix3(gs_sparam_t *param, const struct matrix3 *val); -EXPORT void gs_shader_set_matrix4(gs_sparam_t *param, const struct matrix4 *val); +EXPORT void gs_shader_set_matrix3(gs_sparam_t *param, + const struct matrix3 *val); +EXPORT void gs_shader_set_matrix4(gs_sparam_t *param, + const struct matrix4 *val); EXPORT void gs_shader_set_vec2(gs_sparam_t *param, const struct vec2 *val); EXPORT void gs_shader_set_vec3(gs_sparam_t *param, const struct vec3 *val); EXPORT void gs_shader_set_vec4(gs_sparam_t *param, const struct vec4 *val); @@ -329,7 +334,7 @@ EXPORT void gs_shader_set_texture(gs_sparam_t *param, gs_texture_t *val); EXPORT void gs_shader_set_val(gs_sparam_t *param, const void *val, size_t size); EXPORT void gs_shader_set_default(gs_sparam_t *param); EXPORT void gs_shader_set_next_sampler(gs_sparam_t *param, - gs_samplerstate_t *sampler); + gs_samplerstate_t *sampler); #endif /* --------------------------------------------------- @@ -359,32 +364,33 @@ struct gs_effect_param_info { EXPORT void gs_effect_destroy(gs_effect_t *effect); EXPORT gs_technique_t *gs_effect_get_technique(const gs_effect_t *effect, - const char *name); + const char *name); -EXPORT gs_technique_t *gs_effect_get_current_technique( - const gs_effect_t *effect); +EXPORT gs_technique_t * +gs_effect_get_current_technique(const gs_effect_t *effect); EXPORT size_t gs_technique_begin(gs_technique_t *technique); EXPORT void gs_technique_end(gs_technique_t *technique); EXPORT bool gs_technique_begin_pass(gs_technique_t *technique, size_t pass); EXPORT bool gs_technique_begin_pass_by_name(gs_technique_t *technique, - const char *name); + const char *name); EXPORT void gs_technique_end_pass(gs_technique_t *technique); EXPORT gs_epass_t *gs_technique_get_pass_by_idx(const gs_technique_t *technique, - size_t pass); -EXPORT gs_epass_t *gs_technique_get_pass_by_name( - const gs_technique_t *technique, const char *name); + size_t pass); +EXPORT gs_epass_t * +gs_technique_get_pass_by_name(const gs_technique_t *technique, + const char *name); EXPORT size_t gs_effect_get_num_params(const gs_effect_t *effect); EXPORT gs_eparam_t *gs_effect_get_param_by_idx(const gs_effect_t *effect, - size_t param); + size_t param); EXPORT gs_eparam_t *gs_effect_get_param_by_name(const gs_effect_t *effect, - const char *name); + const char *name); EXPORT size_t gs_param_get_num_annotations(const gs_eparam_t *param); EXPORT gs_eparam_t *gs_param_get_annotation_by_idx(const gs_eparam_t *param, - size_t annotation); + size_t annotation); EXPORT gs_eparam_t *gs_param_get_annotation_by_name(const gs_eparam_t *param, - const char *name); + const char *name); /** Helper function to simplify effect usage. Use with a while loop that * contains drawing functions. Automatically handles techniques, passes, and @@ -399,14 +405,14 @@ EXPORT gs_eparam_t *gs_effect_get_world_matrix(const gs_effect_t *effect); #ifndef SWIG EXPORT void gs_effect_get_param_info(const gs_eparam_t *param, - struct gs_effect_param_info *info); + struct gs_effect_param_info *info); #endif EXPORT void gs_effect_set_bool(gs_eparam_t *param, bool val); EXPORT void gs_effect_set_float(gs_eparam_t *param, float val); EXPORT void gs_effect_set_int(gs_eparam_t *param, int val); EXPORT void gs_effect_set_matrix4(gs_eparam_t *param, - const struct matrix4 *val); + const struct matrix4 *val); EXPORT void gs_effect_set_vec2(gs_eparam_t *param, const struct vec2 *val); EXPORT void gs_effect_set_vec3(gs_eparam_t *param, const struct vec3 *val); EXPORT void gs_effect_set_vec4(gs_eparam_t *param, const struct vec4 *val); @@ -418,7 +424,7 @@ EXPORT void *gs_effect_get_val(gs_eparam_t *param); EXPORT size_t gs_effect_get_default_val_size(gs_eparam_t *param); EXPORT void *gs_effect_get_default_val(gs_eparam_t *param); EXPORT void gs_effect_set_next_sampler(gs_eparam_t *param, - gs_samplerstate_t *sampler); + gs_samplerstate_t *sampler); EXPORT void gs_effect_set_color(gs_eparam_t *param, uint32_t argb); @@ -427,10 +433,10 @@ EXPORT void gs_effect_set_color(gs_eparam_t *param, uint32_t argb); * --------------------------------------------------- */ EXPORT gs_texrender_t *gs_texrender_create(enum gs_color_format format, - enum gs_zstencil_format zsformat); + enum gs_zstencil_format zsformat); EXPORT void gs_texrender_destroy(gs_texrender_t *texrender); EXPORT bool gs_texrender_begin(gs_texrender_t *texrender, uint32_t cx, - uint32_t cy); + uint32_t cy); EXPORT void gs_texrender_end(gs_texrender_t *texrender); EXPORT void gs_texrender_reset(gs_texrender_t *texrender); EXPORT gs_texture_t *gs_texrender_get_texture(const gs_texrender_t *texrender); @@ -439,60 +445,62 @@ EXPORT gs_texture_t *gs_texrender_get_texture(const gs_texrender_t *texrender); * graphics subsystem * --------------------------------------------------- */ -#define GS_BUILD_MIPMAPS (1<<0) -#define GS_DYNAMIC (1<<1) -#define GS_RENDER_TARGET (1<<2) -#define GS_GL_DUMMYTEX (1<<3) /**<< texture with no allocated texture data */ -#define GS_DUP_BUFFER (1<<4) /**<< do not pass buffer ownership when +#define GS_BUILD_MIPMAPS (1 << 0) +#define GS_DYNAMIC (1 << 1) +#define GS_RENDER_TARGET (1 << 2) +#define GS_GL_DUMMYTEX (1 << 3) /**<< texture with no allocated texture data */ +#define GS_DUP_BUFFER \ + (1 << 4) /**<< do not pass buffer ownership when * creating a vertex/index buffer */ -#define GS_SHARED_TEX (1<<5) -#define GS_SHARED_KM_TEX (1<<6) +#define GS_SHARED_TEX (1 << 5) +#define GS_SHARED_KM_TEX (1 << 6) /* ---------------- */ /* global functions */ -#define GS_SUCCESS 0 -#define GS_ERROR_FAIL -1 +#define GS_SUCCESS 0 +#define GS_ERROR_FAIL -1 #define GS_ERROR_MODULE_NOT_FOUND -2 -#define GS_ERROR_NOT_SUPPORTED -3 +#define GS_ERROR_NOT_SUPPORTED -3 struct gs_window { #if defined(_WIN32) - void *hwnd; + void *hwnd; #elif defined(__APPLE__) - __unsafe_unretained id view; + __unsafe_unretained id view; #elif defined(__linux__) || defined(__FreeBSD__) /* I'm not sure how portable defining id to uint32_t is. */ uint32_t id; - void* display; + void *display; #endif }; struct gs_init_data { - struct gs_window window; - uint32_t cx, cy; - uint32_t num_backbuffers; - enum gs_color_format format; + struct gs_window window; + uint32_t cx, cy; + uint32_t num_backbuffers; + enum gs_color_format format; enum gs_zstencil_format zsformat; - uint32_t adapter; + uint32_t adapter; }; -#define GS_DEVICE_OPENGL 1 +#define GS_DEVICE_OPENGL 1 #define GS_DEVICE_DIRECT3D_11 2 EXPORT const char *gs_get_device_name(void); EXPORT int gs_get_device_type(void); -EXPORT void gs_enum_adapters( - bool (*callback)(void *param, const char *name, uint32_t id), - void *param); +EXPORT void gs_enum_adapters(bool (*callback)(void *param, const char *name, + uint32_t id), + void *param); EXPORT int gs_create(graphics_t **graphics, const char *module, - uint32_t adapter); + uint32_t adapter); EXPORT void gs_destroy(graphics_t *graphics); EXPORT void gs_enter_context(graphics_t *graphics); EXPORT void gs_leave_context(void); EXPORT graphics_t *gs_get_context(void); +EXPORT void *gs_get_device_obj(void); EXPORT void gs_matrix_push(void); EXPORT void gs_matrix_pop(void); @@ -527,21 +535,22 @@ EXPORT input_t *gs_get_input(void); EXPORT gs_effect_t *gs_get_effect(void); EXPORT gs_effect_t *gs_effect_create_from_file(const char *file, - char **error_string); + char **error_string); EXPORT gs_effect_t *gs_effect_create(const char *effect_string, - const char *filename, char **error_string); + const char *filename, char **error_string); EXPORT gs_shader_t *gs_vertexshader_create_from_file(const char *file, - char **error_string); + char **error_string); EXPORT gs_shader_t *gs_pixelshader_create_from_file(const char *file, - char **error_string); + char **error_string); EXPORT gs_texture_t *gs_texture_create_from_file(const char *file); EXPORT uint8_t *gs_create_texture_file_data(const char *file, - enum gs_color_format *format, uint32_t *cx, uint32_t *cy); + enum gs_color_format *format, + uint32_t *cx, uint32_t *cy); -#define GS_FLIP_U (1<<0) -#define GS_FLIP_V (1<<1) +#define GS_FLIP_U (1 << 0) +#define GS_FLIP_V (1 << 1) /** * Draws a 2D sprite @@ -551,13 +560,15 @@ EXPORT uint8_t *gs_create_texture_file_data(const char *file, * axis with GS_FLIP_U and GS_FLIP_V. */ EXPORT void gs_draw_sprite(gs_texture_t *tex, uint32_t flip, uint32_t width, - uint32_t height); + uint32_t height); EXPORT void gs_draw_sprite_subregion(gs_texture_t *tex, uint32_t flip, - uint32_t x, uint32_t y, uint32_t cx, uint32_t cy); + uint32_t x, uint32_t y, uint32_t cx, + uint32_t cy); EXPORT void gs_draw_cube_backdrop(gs_texture_t *cubetex, const struct quat *rot, - float left, float right, float top, float bottom, float znear); + float left, float right, float top, + float bottom, float znear); /** sets the viewport to current swap chain size */ EXPORT void gs_reset_viewport(void); @@ -571,9 +582,10 @@ EXPORT void gs_viewport_push(void); EXPORT void gs_viewport_pop(void); EXPORT void gs_texture_set_image(gs_texture_t *tex, const uint8_t *data, - uint32_t linesize, bool invert); + uint32_t linesize, bool invert); EXPORT void gs_cubetexture_set_image(gs_texture_t *cubetex, uint32_t side, - const void *data, uint32_t linesize, bool invert); + const void *data, uint32_t linesize, + bool invert); EXPORT void gs_perspective(float fovy, float aspect, float znear, float zfar); @@ -592,33 +604,41 @@ EXPORT uint32_t gs_get_width(void); EXPORT uint32_t gs_get_height(void); EXPORT gs_texture_t *gs_texture_create(uint32_t width, uint32_t height, - enum gs_color_format color_format, uint32_t levels, - const uint8_t **data, uint32_t flags); -EXPORT gs_texture_t *gs_cubetexture_create(uint32_t size, - enum gs_color_format color_format, uint32_t levels, - const uint8_t **data, uint32_t flags); + enum gs_color_format color_format, + uint32_t levels, const uint8_t **data, + uint32_t flags); +EXPORT gs_texture_t * +gs_cubetexture_create(uint32_t size, enum gs_color_format color_format, + uint32_t levels, const uint8_t **data, uint32_t flags); EXPORT gs_texture_t *gs_voltexture_create(uint32_t width, uint32_t height, - uint32_t depth, enum gs_color_format color_format, - uint32_t levels, const uint8_t **data, uint32_t flags); + uint32_t depth, + enum gs_color_format color_format, + uint32_t levels, const uint8_t **data, + uint32_t flags); EXPORT gs_zstencil_t *gs_zstencil_create(uint32_t width, uint32_t height, - enum gs_zstencil_format format); + enum gs_zstencil_format format); -EXPORT gs_stagesurf_t *gs_stagesurface_create(uint32_t width, uint32_t height, - enum gs_color_format color_format); +EXPORT gs_stagesurf_t * +gs_stagesurface_create(uint32_t width, uint32_t height, + enum gs_color_format color_format); -EXPORT gs_samplerstate_t *gs_samplerstate_create( - const struct gs_sampler_info *info); +EXPORT gs_samplerstate_t * +gs_samplerstate_create(const struct gs_sampler_info *info); -EXPORT gs_shader_t *gs_vertexshader_create(const char *shader, - const char *file, char **error_string); -EXPORT gs_shader_t *gs_pixelshader_create(const char *shader, - const char *file, char **error_string); +EXPORT gs_shader_t *gs_vertexshader_create(const char *shader, const char *file, + char **error_string); +EXPORT gs_shader_t *gs_pixelshader_create(const char *shader, const char *file, + char **error_string); EXPORT gs_vertbuffer_t *gs_vertexbuffer_create(struct gs_vb_data *data, - uint32_t flags); + uint32_t flags); EXPORT gs_indexbuffer_t *gs_indexbuffer_create(enum gs_index_type type, - void *indices, size_t num, uint32_t flags); + void *indices, size_t num, + uint32_t flags); + +EXPORT gs_timer_t *gs_timer_create(); +EXPORT gs_timer_range_t *gs_timer_range_create(); EXPORT enum gs_texture_type gs_get_texture_type(const gs_texture_t *texture); @@ -634,32 +654,32 @@ EXPORT void gs_load_default_samplerstate(bool b_3d, int unit); EXPORT gs_shader_t *gs_get_vertex_shader(void); EXPORT gs_shader_t *gs_get_pixel_shader(void); -EXPORT gs_texture_t *gs_get_render_target(void); +EXPORT gs_texture_t *gs_get_render_target(void); EXPORT gs_zstencil_t *gs_get_zstencil_target(void); EXPORT void gs_set_render_target(gs_texture_t *tex, gs_zstencil_t *zstencil); EXPORT void gs_set_cube_render_target(gs_texture_t *cubetex, int side, - gs_zstencil_t *zstencil); + gs_zstencil_t *zstencil); EXPORT void gs_copy_texture(gs_texture_t *dst, gs_texture_t *src); -EXPORT void gs_copy_texture_region( - gs_texture_t *dst, uint32_t dst_x, uint32_t dst_y, - gs_texture_t *src, uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h); +EXPORT void gs_copy_texture_region(gs_texture_t *dst, uint32_t dst_x, + uint32_t dst_y, gs_texture_t *src, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h); EXPORT void gs_stage_texture(gs_stagesurf_t *dst, gs_texture_t *src); EXPORT void gs_begin_scene(void); EXPORT void gs_draw(enum gs_draw_mode draw_mode, uint32_t start_vert, - uint32_t num_verts); + uint32_t num_verts); EXPORT void gs_end_scene(void); -#define GS_CLEAR_COLOR (1<<0) -#define GS_CLEAR_DEPTH (1<<1) -#define GS_CLEAR_STENCIL (1<<2) +#define GS_CLEAR_COLOR (1 << 0) +#define GS_CLEAR_DEPTH (1 << 1) +#define GS_CLEAR_STENCIL (1 << 2) EXPORT void gs_load_swapchain(gs_swapchain_t *swapchain); EXPORT void gs_clear(uint32_t clear_flags, const struct vec4 *color, - float depth, uint8_t stencil); + float depth, uint8_t stencil); EXPORT void gs_present(void); EXPORT void gs_flush(void); @@ -673,109 +693,119 @@ EXPORT void gs_enable_stencil_write(bool enable); EXPORT void gs_enable_color(bool red, bool green, bool blue, bool alpha); EXPORT void gs_blend_function(enum gs_blend_type src, enum gs_blend_type dest); -EXPORT void gs_blend_function_separate( - enum gs_blend_type src_c, enum gs_blend_type dest_c, - enum gs_blend_type src_a, enum gs_blend_type dest_a); +EXPORT void gs_blend_function_separate(enum gs_blend_type src_c, + enum gs_blend_type dest_c, + enum gs_blend_type src_a, + enum gs_blend_type dest_a); EXPORT void gs_depth_function(enum gs_depth_test test); EXPORT void gs_stencil_function(enum gs_stencil_side side, - enum gs_depth_test test); + enum gs_depth_test test); EXPORT void gs_stencil_op(enum gs_stencil_side side, - enum gs_stencil_op_type fail, - enum gs_stencil_op_type zfail, - enum gs_stencil_op_type zpass); + enum gs_stencil_op_type fail, + enum gs_stencil_op_type zfail, + enum gs_stencil_op_type zpass); EXPORT void gs_set_viewport(int x, int y, int width, int height); EXPORT void gs_get_viewport(struct gs_rect *rect); EXPORT void gs_set_scissor_rect(const struct gs_rect *rect); EXPORT void gs_ortho(float left, float right, float top, float bottom, - float znear, float zfar); + float znear, float zfar); EXPORT void gs_frustum(float left, float right, float top, float bottom, - float znear, float zfar); + float znear, float zfar); EXPORT void gs_projection_push(void); EXPORT void gs_projection_pop(void); -EXPORT void gs_swapchain_destroy(gs_swapchain_t *swapchain); +EXPORT void gs_swapchain_destroy(gs_swapchain_t *swapchain); -EXPORT void gs_texture_destroy(gs_texture_t *tex); +EXPORT void gs_texture_destroy(gs_texture_t *tex); EXPORT uint32_t gs_texture_get_width(const gs_texture_t *tex); EXPORT uint32_t gs_texture_get_height(const gs_texture_t *tex); -EXPORT enum gs_color_format gs_texture_get_color_format( - const gs_texture_t *tex); -EXPORT bool gs_texture_map(gs_texture_t *tex, uint8_t **ptr, - uint32_t *linesize); -EXPORT void gs_texture_unmap(gs_texture_t *tex); +EXPORT enum gs_color_format +gs_texture_get_color_format(const gs_texture_t *tex); +EXPORT bool gs_texture_map(gs_texture_t *tex, uint8_t **ptr, + uint32_t *linesize); +EXPORT void gs_texture_unmap(gs_texture_t *tex); /** special-case function (GL only) - specifies whether the texture is a * GL_TEXTURE_RECTANGLE type, which doesn't use normalized texture * coordinates, doesn't support mipmapping, and requires address clamping */ -EXPORT bool gs_texture_is_rect(const gs_texture_t *tex); +EXPORT bool gs_texture_is_rect(const gs_texture_t *tex); /** * Gets a pointer to the context-specific object associated with the texture. * For example, for GL, this is a GLuint*. For D3D11, ID3D11Texture2D*. */ -EXPORT void *gs_texture_get_obj(gs_texture_t *tex); +EXPORT void *gs_texture_get_obj(gs_texture_t *tex); -EXPORT void gs_cubetexture_destroy(gs_texture_t *cubetex); +EXPORT void gs_cubetexture_destroy(gs_texture_t *cubetex); EXPORT uint32_t gs_cubetexture_get_size(const gs_texture_t *cubetex); -EXPORT enum gs_color_format gs_cubetexture_get_color_format( - const gs_texture_t *cubetex); +EXPORT enum gs_color_format +gs_cubetexture_get_color_format(const gs_texture_t *cubetex); -EXPORT void gs_voltexture_destroy(gs_texture_t *voltex); +EXPORT void gs_voltexture_destroy(gs_texture_t *voltex); EXPORT uint32_t gs_voltexture_get_width(const gs_texture_t *voltex); EXPORT uint32_t gs_voltexture_get_height(const gs_texture_t *voltex); EXPORT uint32_t gs_voltexture_get_depth(const gs_texture_t *voltex); -EXPORT enum gs_color_format gs_voltexture_get_color_format( - const gs_texture_t *voltex); +EXPORT enum gs_color_format +gs_voltexture_get_color_format(const gs_texture_t *voltex); -EXPORT void gs_stagesurface_destroy(gs_stagesurf_t *stagesurf); +EXPORT void gs_stagesurface_destroy(gs_stagesurf_t *stagesurf); EXPORT uint32_t gs_stagesurface_get_width(const gs_stagesurf_t *stagesurf); EXPORT uint32_t gs_stagesurface_get_height(const gs_stagesurf_t *stagesurf); -EXPORT enum gs_color_format gs_stagesurface_get_color_format( - const gs_stagesurf_t *stagesurf); -EXPORT bool gs_stagesurface_map(gs_stagesurf_t *stagesurf, uint8_t **data, - uint32_t *linesize); -EXPORT void gs_stagesurface_unmap(gs_stagesurf_t *stagesurf); +EXPORT enum gs_color_format +gs_stagesurface_get_color_format(const gs_stagesurf_t *stagesurf); +EXPORT bool gs_stagesurface_map(gs_stagesurf_t *stagesurf, uint8_t **data, + uint32_t *linesize); +EXPORT void gs_stagesurface_unmap(gs_stagesurf_t *stagesurf); -EXPORT void gs_zstencil_destroy(gs_zstencil_t *zstencil); +EXPORT void gs_zstencil_destroy(gs_zstencil_t *zstencil); -EXPORT void gs_samplerstate_destroy(gs_samplerstate_t *samplerstate); +EXPORT void gs_samplerstate_destroy(gs_samplerstate_t *samplerstate); -EXPORT void gs_vertexbuffer_destroy(gs_vertbuffer_t *vertbuffer); -EXPORT void gs_vertexbuffer_flush(gs_vertbuffer_t *vertbuffer); -EXPORT void gs_vertexbuffer_flush_direct(gs_vertbuffer_t *vertbuffer, - const struct gs_vb_data *data); -EXPORT struct gs_vb_data *gs_vertexbuffer_get_data( - const gs_vertbuffer_t *vertbuffer); +EXPORT void gs_vertexbuffer_destroy(gs_vertbuffer_t *vertbuffer); +EXPORT void gs_vertexbuffer_flush(gs_vertbuffer_t *vertbuffer); +EXPORT void gs_vertexbuffer_flush_direct(gs_vertbuffer_t *vertbuffer, + const struct gs_vb_data *data); +EXPORT struct gs_vb_data * +gs_vertexbuffer_get_data(const gs_vertbuffer_t *vertbuffer); -EXPORT void gs_indexbuffer_destroy(gs_indexbuffer_t *indexbuffer); -EXPORT void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer); -EXPORT void gs_indexbuffer_flush_direct(gs_indexbuffer_t *indexbuffer, - const void *data); -EXPORT void *gs_indexbuffer_get_data(const gs_indexbuffer_t *indexbuffer); -EXPORT size_t gs_indexbuffer_get_num_indices( - const gs_indexbuffer_t *indexbuffer); -EXPORT enum gs_index_type gs_indexbuffer_get_type( - const gs_indexbuffer_t *indexbuffer); +EXPORT void gs_indexbuffer_destroy(gs_indexbuffer_t *indexbuffer); +EXPORT void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer); +EXPORT void gs_indexbuffer_flush_direct(gs_indexbuffer_t *indexbuffer, + const void *data); +EXPORT void *gs_indexbuffer_get_data(const gs_indexbuffer_t *indexbuffer); +EXPORT size_t +gs_indexbuffer_get_num_indices(const gs_indexbuffer_t *indexbuffer); +EXPORT enum gs_index_type +gs_indexbuffer_get_type(const gs_indexbuffer_t *indexbuffer); -EXPORT bool gs_nv12_available(void); +EXPORT void gs_timer_destroy(gs_timer_t *timer); +EXPORT void gs_timer_begin(gs_timer_t *timer); +EXPORT void gs_timer_end(gs_timer_t *timer); +EXPORT bool gs_timer_get_data(gs_timer_t *timer, uint64_t *ticks); +EXPORT void gs_timer_range_destroy(gs_timer_range_t *timer); +EXPORT void gs_timer_range_begin(gs_timer_range_t *range); +EXPORT void gs_timer_range_end(gs_timer_range_t *range); +EXPORT bool gs_timer_range_get_data(gs_timer_range_t *range, bool *disjoint, + uint64_t *frequency); + +EXPORT bool gs_nv12_available(void); #define GS_USE_DEBUG_MARKERS 0 #if GS_USE_DEBUG_MARKERS -static const float GS_DEBUG_COLOR_DEFAULT[] = { 0.5f, 0.5f, 0.5f, 1.0f }; -static const float GS_DEBUG_COLOR_RENDER_VIDEO[] = { 0.0f, 0.5f, 0.0f, 1.0f }; -static const float GS_DEBUG_COLOR_MAIN_TEXTURE[] = { 0.0f, 0.25f, 0.0f, 1.0f }; -static const float GS_DEBUG_COLOR_DISPLAY[] = { 0.0f, 0.5f, 0.5f, 1.0f }; -static const float GS_DEBUG_COLOR_SOURCE[] = { 0.0f, 0.5f, 5.0f, 1.0f }; -static const float GS_DEBUG_COLOR_ITEM[] = { 0.5f, 0.0f, 0.0f, 1.0f }; -static const float GS_DEBUG_COLOR_ITEM_TEXTURE[] = { 0.25f, 0.0f, 0.0f, 1.0f }; -static const float GS_DEBUG_COLOR_CONVERT_FORMAT[] = { 0.5f, 0.5f, 0.0f, 1.0f }; +static const float GS_DEBUG_COLOR_DEFAULT[] = {0.5f, 0.5f, 0.5f, 1.0f}; +static const float GS_DEBUG_COLOR_RENDER_VIDEO[] = {0.0f, 0.5f, 0.0f, 1.0f}; +static const float GS_DEBUG_COLOR_MAIN_TEXTURE[] = {0.0f, 0.25f, 0.0f, 1.0f}; +static const float GS_DEBUG_COLOR_DISPLAY[] = {0.0f, 0.5f, 0.5f, 1.0f}; +static const float GS_DEBUG_COLOR_SOURCE[] = {0.0f, 0.5f, 5.0f, 1.0f}; +static const float GS_DEBUG_COLOR_ITEM[] = {0.5f, 0.0f, 0.0f, 1.0f}; +static const float GS_DEBUG_COLOR_ITEM_TEXTURE[] = {0.25f, 0.0f, 0.0f, 1.0f}; +static const float GS_DEBUG_COLOR_CONVERT_FORMAT[] = {0.5f, 0.5f, 0.0f, 1.0f}; #define GS_DEBUG_MARKER_BEGIN(color, markername) \ - gs_debug_marker_begin(color, markername) + gs_debug_marker_begin(color, markername) #define GS_DEBUG_MARKER_BEGIN_FORMAT(color, format, ...) \ - gs_debug_marker_begin_format(color, format, \ - __VA_ARGS__) + gs_debug_marker_begin_format(color, format, __VA_ARGS__) #define GS_DEBUG_MARKER_END() gs_debug_marker_end() #else #define GS_DEBUG_MARKER_BEGIN(color, markername) ((void)0) @@ -783,19 +813,17 @@ static const float GS_DEBUG_COLOR_CONVERT_FORMAT[] = { 0.5f, 0.5f, 0.0f, 1.0f }; #define GS_DEBUG_MARKER_END() ((void)0) #endif -EXPORT void gs_debug_marker_begin(const float color[4], - const char *markername); -EXPORT void gs_debug_marker_begin_format(const float color[4], - const char *format, ...); -EXPORT void gs_debug_marker_end(void); +EXPORT void gs_debug_marker_begin(const float color[4], const char *markername); +EXPORT void gs_debug_marker_begin_format(const float color[4], + const char *format, ...); +EXPORT void gs_debug_marker_end(void); #ifdef __APPLE__ /** platform specific function for creating (GL_TEXTURE_RECTANGLE) textures * from shared surface resources */ EXPORT gs_texture_t *gs_texture_create_from_iosurface(void *iosurf); -EXPORT bool gs_texture_rebind_iosurface(gs_texture_t *texture, - void *iosurf); +EXPORT bool gs_texture_rebind_iosurface(gs_texture_t *texture, void *iosurf); #elif _WIN32 @@ -809,8 +837,9 @@ typedef struct gs_duplicator gs_duplicator_t; * Gets information about the monitor at the specific index, returns false * when there is no monitor at the specified index */ -EXPORT bool gs_get_duplicator_monitor_info(int monitor_idx, - struct gs_monitor_info *monitor_info); +EXPORT bool +gs_get_duplicator_monitor_info(int monitor_idx, + struct gs_monitor_info *monitor_info); /** creates a windows 8+ output duplicator (monitor capture) */ EXPORT gs_duplicator_t *gs_duplicator_create(int monitor_idx); @@ -828,16 +857,17 @@ EXPORT void gs_texture_release_dc(gs_texture_t *gdi_tex); /** creates a windows shared texture from a texture handle */ EXPORT gs_texture_t *gs_texture_open_shared(uint32_t handle); -#define GS_INVALID_HANDLE (uint32_t)-1 +#define GS_INVALID_HANDLE (uint32_t) - 1 EXPORT uint32_t gs_texture_get_shared_handle(gs_texture_t *tex); -#define GS_WAIT_INFINITE (uint32_t)-1 +#define GS_WAIT_INFINITE (uint32_t) - 1 /** * acquires a lock on a keyed mutex texture. * returns -1 on generic failure, ETIMEDOUT if timed out */ -EXPORT int gs_texture_acquire_sync(gs_texture_t *tex, uint64_t key, uint32_t ms); +EXPORT int gs_texture_acquire_sync(gs_texture_t *tex, uint64_t key, + uint32_t ms); /** * releases a lock on a keyed mutex texture to another device. @@ -846,10 +876,11 @@ EXPORT int gs_texture_acquire_sync(gs_texture_t *tex, uint64_t key, uint32_t ms) EXPORT int gs_texture_release_sync(gs_texture_t *tex, uint64_t key); EXPORT bool gs_texture_create_nv12(gs_texture_t **tex_y, gs_texture_t **tex_uv, - uint32_t width, uint32_t height, uint32_t flags); + uint32_t width, uint32_t height, + uint32_t flags); -EXPORT gs_stagesurf_t *gs_stagesurface_create_nv12( - uint32_t width, uint32_t height); +EXPORT gs_stagesurf_t *gs_stagesurface_create_nv12(uint32_t width, + uint32_t height); #endif @@ -858,25 +889,44 @@ EXPORT gs_stagesurf_t *gs_stagesurface_create_nv12( static inline uint32_t gs_get_format_bpp(enum gs_color_format format) { switch (format) { - case GS_A8: return 8; - case GS_R8: return 8; - case GS_RGBA: return 32; - case GS_BGRX: return 32; - case GS_BGRA: return 32; - case GS_R10G10B10A2: return 32; - case GS_RGBA16: return 64; - case GS_R16: return 16; - case GS_RGBA16F: return 64; - case GS_RGBA32F: return 128; - case GS_RG16F: return 32; - case GS_RG32F: return 64; - case GS_R16F: return 16; - case GS_R32F: return 32; - case GS_DXT1: return 4; - case GS_DXT3: return 8; - case GS_DXT5: return 8; - case GS_R8G8: return 16; - case GS_UNKNOWN: return 0; + case GS_A8: + return 8; + case GS_R8: + return 8; + case GS_RGBA: + return 32; + case GS_BGRX: + return 32; + case GS_BGRA: + return 32; + case GS_R10G10B10A2: + return 32; + case GS_RGBA16: + return 64; + case GS_R16: + return 16; + case GS_RGBA16F: + return 64; + case GS_RGBA32F: + return 128; + case GS_RG16F: + return 32; + case GS_RG32F: + return 64; + case GS_R16F: + return 16; + case GS_R32F: + return 32; + case GS_DXT1: + return 4; + case GS_DXT3: + return 8; + case GS_DXT5: + return 8; + case GS_R8G8: + return 16; + case GS_UNKNOWN: + return 0; } return 0; diff --git a/libobs/graphics/image-file.c b/libobs/graphics/image-file.c index 402014f..1d6a043 100644 --- a/libobs/graphics/image-file.c +++ b/libobs/graphics/image-file.c @@ -41,7 +41,7 @@ static bool bi_def_bitmap_test_opaque(void *bitmap) static unsigned char *bi_def_bitmap_get_buffer(void *bitmap) { - return (unsigned char*)bitmap; + return (unsigned char *)bitmap; } static void bi_def_bitmap_destroy(void *bitmap) @@ -56,11 +56,12 @@ static void bi_def_bitmap_modified(void *bitmap) static inline int get_full_decoded_gif_size(gs_image_file_t *image) { - return image->gif.width * image->gif.height * 4 * image->gif.frame_count; + return image->gif.width * image->gif.height * 4 * + image->gif.frame_count; } static inline void *alloc_mem(gs_image_file_t *image, uint64_t *mem_usage, - size_t size) + size_t size) { UNUSED_PARAMETER(image); @@ -70,7 +71,7 @@ static inline void *alloc_mem(gs_image_file_t *image, uint64_t *mem_usage, } static bool init_animated_gif(gs_image_file_t *image, const char *path, - uint64_t *mem_usage) + uint64_t *mem_usage) { bool is_animated_gif = true; gif_result result; @@ -107,24 +108,26 @@ static bool init_animated_gif(gs_image_file_t *image, const char *path, do { result = gif_initialise(&image->gif, size, image->gif_data); if (result < 0) { - blog(LOG_WARNING, "Failed to initialize gif '%s', " - "possible file corruption", path); + blog(LOG_WARNING, + "Failed to initialize gif '%s', " + "possible file corruption", + path); goto fail; } } while (result != GIF_OK); if (image->gif.width > 4096 || image->gif.height > 4096) { blog(LOG_WARNING, "Bad texture dimensions (%dx%d) in '%s'", - image->gif.width, image->gif.height, path); + image->gif.width, image->gif.height, path); goto fail; } max_size = (uint64_t)image->gif.width * (uint64_t)image->gif.height * - (uint64_t)image->gif.frame_count * 4LLU; + (uint64_t)image->gif.frame_count * 4LLU; if ((uint64_t)get_full_decoded_gif_size(image) != max_size) { blog(LOG_WARNING, "Gif '%s' overflowed maximum pointer size", - path); + path); goto fail; } @@ -132,15 +135,18 @@ static bool init_animated_gif(gs_image_file_t *image, const char *path, if (image->is_animated_gif) { gif_decode_frame(&image->gif, 0); - image->animation_frame_cache = alloc_mem(image, mem_usage, - image->gif.frame_count * sizeof(uint8_t*)); - image->animation_frame_data = alloc_mem(image, mem_usage, - get_full_decoded_gif_size(image)); + image->animation_frame_cache = + alloc_mem(image, mem_usage, + image->gif.frame_count * sizeof(uint8_t *)); + image->animation_frame_data = alloc_mem( + image, mem_usage, get_full_decoded_gif_size(image)); for (unsigned int i = 0; i < image->gif.frame_count; i++) { if (gif_decode_frame(&image->gif, i) != GIF_OK) - blog(LOG_WARNING, "Couldn't decode frame %u " - "of '%s'", i, path); + blog(LOG_WARNING, + "Couldn't decode frame %u " + "of '%s'", + i, path); } gif_decode_frame(&image->gif, 0); @@ -174,7 +180,7 @@ not_animated: } static void gs_image_file_init_internal(gs_image_file_t *image, - const char *file, uint64_t *mem_usage) + const char *file, uint64_t *mem_usage) { size_t len; @@ -193,12 +199,12 @@ static void gs_image_file_init_internal(gs_image_file_t *image, return; } - image->texture_data = gs_create_texture_file_data(file, - &image->format, &image->cx, &image->cy); + image->texture_data = gs_create_texture_file_data( + file, &image->format, &image->cx, &image->cy); if (mem_usage) { *mem_usage += image->cx * image->cy * - gs_get_format_bpp(image->format) / 8; + gs_get_format_bpp(image->format) / 8; } image->loaded = !!image->texture_data; @@ -245,14 +251,13 @@ void gs_image_file_init_texture(gs_image_file_t *image) if (image->is_animated_gif) { image->texture = gs_texture_create( - image->cx, image->cy, image->format, 1, - (const uint8_t**)&image->gif.frame_image, - GS_DYNAMIC); + image->cx, image->cy, image->format, 1, + (const uint8_t **)&image->gif.frame_image, GS_DYNAMIC); } else { image->texture = gs_texture_create( - image->cx, image->cy, image->format, 1, - (const uint8_t**)&image->texture_data, 0); + image->cx, image->cy, image->format, 1, + (const uint8_t **)&image->texture_data, 0); bfree(image->texture_data); image->texture_data = NULL; } @@ -267,7 +272,7 @@ static inline uint64_t get_time(gs_image_file_t *image, int i) } static inline int calculate_new_frame(gs_image_file_t *image, - uint64_t elapsed_time_ns, int loops) + uint64_t elapsed_time_ns, int loops) { int new_frame = image->cur_frame; @@ -297,8 +302,9 @@ static void decode_new_frame(gs_image_file_t *image, int new_frame) int last_frame; /* if looped, decode frame 0 */ - last_frame = (new_frame < image->last_decoded_frame) ? - 0 : image->last_decoded_frame + 1; + last_frame = (new_frame < image->last_decoded_frame) + ? 0 + : image->last_decoded_frame + 1; /* decode missed frames */ for (int i = last_frame; i < new_frame; i++) { @@ -309,14 +315,13 @@ static void decode_new_frame(gs_image_file_t *image, int new_frame) /* decode actual desired frame */ if (gif_decode_frame(&image->gif, new_frame) == GIF_OK) { size_t pos = new_frame * image->gif.width * - image->gif.height * 4; + image->gif.height * 4; image->animation_frame_cache[new_frame] = image->animation_frame_data + pos; memcpy(image->animation_frame_cache[new_frame], - image->gif.frame_image, - image->gif.width * - image->gif.height * 4); + image->gif.frame_image, + image->gif.width * image->gif.height * 4); image->last_decoded_frame = new_frame; } @@ -337,8 +342,8 @@ bool gs_image_file_tick(gs_image_file_t *image, uint64_t elapsed_time_ns) loops = 0; if (!loops || image->cur_loop < loops) { - int new_frame = calculate_new_frame(image, elapsed_time_ns, - loops); + int new_frame = + calculate_new_frame(image, elapsed_time_ns, loops); if (new_frame != image->cur_frame) { decode_new_frame(image, new_frame); @@ -358,6 +363,6 @@ void gs_image_file_update_texture(gs_image_file_t *image) decode_new_frame(image, image->cur_frame); gs_texture_set_image(image->texture, - image->animation_frame_cache[image->cur_frame], - image->gif.width * 4, false); + image->animation_frame_cache[image->cur_frame], + image->gif.width * 4, false); } diff --git a/libobs/graphics/image-file.h b/libobs/graphics/image-file.h index 74e944e..f0db05f 100644 --- a/libobs/graphics/image-file.h +++ b/libobs/graphics/image-file.h @@ -59,7 +59,7 @@ EXPORT void gs_image_file_free(gs_image_file_t *image); EXPORT void gs_image_file_init_texture(gs_image_file_t *image); EXPORT bool gs_image_file_tick(gs_image_file_t *image, - uint64_t elapsed_time_ns); + uint64_t elapsed_time_ns); EXPORT void gs_image_file_update_texture(gs_image_file_t *image); EXPORT void gs_image_file2_init(gs_image_file2_t *if2, const char *file); @@ -76,7 +76,7 @@ static inline void gs_image_file2_init_texture(gs_image_file2_t *if2) } static inline bool gs_image_file2_tick(gs_image_file2_t *if2, - uint64_t elapsed_time_ns) + uint64_t elapsed_time_ns) { return gs_image_file_tick(&if2->image, elapsed_time_ns); } diff --git a/libobs/graphics/input.h b/libobs/graphics/input.h index 6c74ef4..778f414 100644 --- a/libobs/graphics/input.h +++ b/libobs/graphics/input.h @@ -23,123 +23,123 @@ extern "C" { #endif -#define KBC_ESCAPE 0x0 -#define KBC_1 0x1 -#define KBC_2 0x2 -#define KBC_3 0x3 -#define KBC_4 0x4 -#define KBC_5 0x5 -#define KBC_6 0x6 -#define KBC_7 0x7 -#define KBC_8 0x8 -#define KBC_9 0x9 -#define KBC_0 0xA -#define KBC_MINUS 0xB -#define KBC_EQUALS 0xC -#define KBC_BACK 0xD -#define KBC_TAB 0xE -#define KBC_Q 0xF -#define KBC_W 0x10 -#define KBC_E 0x11 -#define KBC_R 0x12 -#define KBC_T 0x13 -#define KBC_Y 0x14 -#define KBC_U 0x15 -#define KBC_I 0x16 -#define KBC_O 0x17 -#define KBC_P 0x18 -#define KBC_LBRACKET 0x19 -#define KBC_RBRACKET 0x1A -#define KBC_RETURN 0x1B -#define KBC_LCONTROL 0x1C -#define KBC_A 0x1D -#define KBC_S 0x1E -#define KBC_D 0x1F -#define KBC_F 0x20 -#define KBC_G 0x21 -#define KBC_H 0x22 -#define KBC_J 0x23 -#define KBC_K 0x24 -#define KBC_L 0x25 -#define KBC_SEMICOLON 0x26 -#define KBC_APOSTROPHE 0x27 -#define KBC_TILDE 0x28 -#define KBC_LSHIFT 0x29 -#define KBC_BACKSLASH 0x2A -#define KBC_Z 0x2B -#define KBC_X 0x2C -#define KBC_C 0x2D -#define KBC_V 0x2E -#define KBC_B 0x2F -#define KBC_N 0x30 -#define KBC_M 0x31 -#define KBC_COMMA 0x32 -#define KBC_PERIOD 0x33 -#define KBC_SLASH 0x34 -#define KBC_RSHIFT 0x35 -#define KBC_MULTIPLY 0x36 -#define KBC_LALT 0x37 -#define KBC_SPACE 0x38 -#define KBC_CAPSLOCK 0x39 -#define KBC_F1 0x3A -#define KBC_F2 0x3B -#define KBC_F3 0x3C -#define KBC_F4 0x3D -#define KBC_F5 0x3E -#define KBC_F6 0x3F -#define KBC_F7 0x40 -#define KBC_F8 0x41 -#define KBC_F9 0x42 -#define KBC_F10 0x43 -#define KBC_NUMLOCK 0x44 -#define KBC_SCROLLLOCK 0x45 -#define KBC_NUMPAD7 0x46 -#define KBC_NUMPAD8 0x47 -#define KBC_NUMPAD9 0x48 -#define KBC_SUBTRACT 0x49 -#define KBC_NUMPAD4 0x4A -#define KBC_NUMPAD5 0x4B -#define KBC_NUMPAD6 0x4C -#define KBC_ADD 0x4D -#define KBC_NUMPAD1 0x4E -#define KBC_NUMPAD2 0x4F -#define KBC_NUMPAD3 0x50 -#define KBC_NUMPAD0 0x51 -#define KBC_DECIMAL 0x52 -#define KBC_F11 0x53 -#define KBC_F12 0x54 -#define KBC_NUMPADENTER 0x55 -#define KBC_RCONTROL 0x56 -#define KBC_DIVIDE 0x57 -#define KBC_SYSRQ 0x58 -#define KBC_RALT 0x59 -#define KBC_PAUSE 0x5A -#define KBC_HOME 0x5B -#define KBC_UP 0x5C -#define KBC_PAGEDOWN 0x5D -#define KBC_LEFT 0x5E -#define KBC_RIGHT 0x5F -#define KBC_END 0x60 -#define KBC_DOWN 0x61 -#define KBC_PAGEUP 0x62 -#define KBC_INSERT 0x63 -#define KBC_DELETE 0x64 +#define KBC_ESCAPE 0x0 +#define KBC_1 0x1 +#define KBC_2 0x2 +#define KBC_3 0x3 +#define KBC_4 0x4 +#define KBC_5 0x5 +#define KBC_6 0x6 +#define KBC_7 0x7 +#define KBC_8 0x8 +#define KBC_9 0x9 +#define KBC_0 0xA +#define KBC_MINUS 0xB +#define KBC_EQUALS 0xC +#define KBC_BACK 0xD +#define KBC_TAB 0xE +#define KBC_Q 0xF +#define KBC_W 0x10 +#define KBC_E 0x11 +#define KBC_R 0x12 +#define KBC_T 0x13 +#define KBC_Y 0x14 +#define KBC_U 0x15 +#define KBC_I 0x16 +#define KBC_O 0x17 +#define KBC_P 0x18 +#define KBC_LBRACKET 0x19 +#define KBC_RBRACKET 0x1A +#define KBC_RETURN 0x1B +#define KBC_LCONTROL 0x1C +#define KBC_A 0x1D +#define KBC_S 0x1E +#define KBC_D 0x1F +#define KBC_F 0x20 +#define KBC_G 0x21 +#define KBC_H 0x22 +#define KBC_J 0x23 +#define KBC_K 0x24 +#define KBC_L 0x25 +#define KBC_SEMICOLON 0x26 +#define KBC_APOSTROPHE 0x27 +#define KBC_TILDE 0x28 +#define KBC_LSHIFT 0x29 +#define KBC_BACKSLASH 0x2A +#define KBC_Z 0x2B +#define KBC_X 0x2C +#define KBC_C 0x2D +#define KBC_V 0x2E +#define KBC_B 0x2F +#define KBC_N 0x30 +#define KBC_M 0x31 +#define KBC_COMMA 0x32 +#define KBC_PERIOD 0x33 +#define KBC_SLASH 0x34 +#define KBC_RSHIFT 0x35 +#define KBC_MULTIPLY 0x36 +#define KBC_LALT 0x37 +#define KBC_SPACE 0x38 +#define KBC_CAPSLOCK 0x39 +#define KBC_F1 0x3A +#define KBC_F2 0x3B +#define KBC_F3 0x3C +#define KBC_F4 0x3D +#define KBC_F5 0x3E +#define KBC_F6 0x3F +#define KBC_F7 0x40 +#define KBC_F8 0x41 +#define KBC_F9 0x42 +#define KBC_F10 0x43 +#define KBC_NUMLOCK 0x44 +#define KBC_SCROLLLOCK 0x45 +#define KBC_NUMPAD7 0x46 +#define KBC_NUMPAD8 0x47 +#define KBC_NUMPAD9 0x48 +#define KBC_SUBTRACT 0x49 +#define KBC_NUMPAD4 0x4A +#define KBC_NUMPAD5 0x4B +#define KBC_NUMPAD6 0x4C +#define KBC_ADD 0x4D +#define KBC_NUMPAD1 0x4E +#define KBC_NUMPAD2 0x4F +#define KBC_NUMPAD3 0x50 +#define KBC_NUMPAD0 0x51 +#define KBC_DECIMAL 0x52 +#define KBC_F11 0x53 +#define KBC_F12 0x54 +#define KBC_NUMPADENTER 0x55 +#define KBC_RCONTROL 0x56 +#define KBC_DIVIDE 0x57 +#define KBC_SYSRQ 0x58 +#define KBC_RALT 0x59 +#define KBC_PAUSE 0x5A +#define KBC_HOME 0x5B +#define KBC_UP 0x5C +#define KBC_PAGEDOWN 0x5D +#define KBC_LEFT 0x5E +#define KBC_RIGHT 0x5F +#define KBC_END 0x60 +#define KBC_DOWN 0x61 +#define KBC_PAGEUP 0x62 +#define KBC_INSERT 0x63 +#define KBC_DELETE 0x64 -#define MOUSE_LEFTBUTTON 0x65 -#define MOUSE_MIDDLEBUTTON 0x66 -#define MOUSE_RIGHTBUTTON 0x67 -#define MOUSE_WHEEL 0x68 -#define MOUSE_MOVE 0x69 +#define MOUSE_LEFTBUTTON 0x65 +#define MOUSE_MIDDLEBUTTON 0x66 +#define MOUSE_RIGHTBUTTON 0x67 +#define MOUSE_WHEEL 0x68 +#define MOUSE_MOVE 0x69 -#define KBC_CONTROL 0xFFFFFFFE -#define KBC_ALT 0xFFFFFFFD -#define KBC_SHIFT 0xFFFFFFFC +#define KBC_CONTROL 0xFFFFFFFE +#define KBC_ALT 0xFFFFFFFD +#define KBC_SHIFT 0xFFFFFFFC -#define STATE_LBUTTONDOWN (1<<0) -#define STATE_RBUTTONDOWN (1<<1) -#define STATE_MBUTTONDOWN (1<<2) -#define STATE_X4BUTTONDOWN (1<<3) -#define STATE_X5BUTTONDOWN (1<<4) +#define STATE_LBUTTONDOWN (1 << 0) +#define STATE_RBUTTONDOWN (1 << 1) +#define STATE_MBUTTONDOWN (1 << 2) +#define STATE_X4BUTTONDOWN (1 << 3) +#define STATE_X5BUTTONDOWN (1 << 4) /* wrapped opaque data types */ struct input_subsystem; diff --git a/libobs/graphics/libnsgif/.clang-format b/libobs/graphics/libnsgif/.clang-format new file mode 100644 index 0000000..6420a46 --- /dev/null +++ b/libobs/graphics/libnsgif/.clang-format @@ -0,0 +1,3 @@ +Language: Cpp +SortIncludes: false +DisableFormat: true diff --git a/libobs/graphics/math-defs.h b/libobs/graphics/math-defs.h index 7260cba..748bea1 100644 --- a/libobs/graphics/math-defs.h +++ b/libobs/graphics/math-defs.h @@ -25,19 +25,19 @@ extern "C" { #endif #ifndef M_PI -#define M_PI 3.1415926535897932384626433832795f +#define M_PI 3.1415926535897932384626433832795f #endif -#define RAD(val) ((val)*0.0174532925199432957692369076848f) -#define DEG(val) ((val)*57.295779513082320876798154814105f) -#define LARGE_EPSILON 1e-2f -#define EPSILON 1e-4f -#define TINY_EPSILON 1e-5f -#define M_INFINITE 3.4e38f +#define RAD(val) ((val)*0.0174532925199432957692369076848f) +#define DEG(val) ((val)*57.295779513082320876798154814105f) +#define LARGE_EPSILON 1e-2f +#define EPSILON 1e-4f +#define TINY_EPSILON 1e-5f +#define M_INFINITE 3.4e38f static inline bool close_float(float f1, float f2, float precision) { - return fabsf(f1-f2) <= precision; + return fabsf(f1 - f2) <= precision; } #ifdef __cplusplus diff --git a/libobs/graphics/math-extra.c b/libobs/graphics/math-extra.c index aa8311c..3095a9c 100644 --- a/libobs/graphics/math-extra.c +++ b/libobs/graphics/math-extra.c @@ -24,12 +24,12 @@ void polar_to_cart(struct vec3 *dst, const struct vec3 *v) { struct vec3 cart; - float sinx = cosf(v->x); - float sinx_z = v->z * sinx; + float sinx = cosf(v->x); + float sinx_z = v->z * sinx; cart.x = sinx_z * sinf(v->y); cart.z = sinx_z * cosf(v->y); - cart.y = v->z * sinf(v->x); + cart.y = v->z * sinf(v->x); vec3_copy(dst, &cart); } @@ -65,28 +65,28 @@ void polar_to_norm(struct vec3 *dst, const struct vec2 *polar) } float calc_torquef(float val1, float val2, float torque, float min_adjust, - float t) + float t) { float out = val1; float dist; - bool over; + bool over; if (close_float(val1, val2, EPSILON)) return val1; - dist = (val2-val1)*torque; + dist = (val2 - val1) * torque; over = dist > 0.0f; if (over) { if (dist < min_adjust) /* prevents from going too slow */ dist = min_adjust; - out += dist*t; /* add torque */ - if (out > val2) /* clamp if overshoot */ + out += dist * t; /* add torque */ + if (out > val2) /* clamp if overshoot */ out = val2; } else { if (dist > -min_adjust) dist = -min_adjust; - out += dist*t; + out += dist * t; if (out < val2) out = val2; } @@ -94,9 +94,8 @@ float calc_torquef(float val1, float val2, float torque, float min_adjust, return out; } -void calc_torque(struct vec3 *dst, const struct vec3 *v1, - const struct vec3 *v2, float torque, float min_adjust, - float t) +void calc_torque(struct vec3 *dst, const struct vec3 *v1, const struct vec3 *v2, + float torque, float min_adjust, float t) { struct vec3 line, dir; float orig_dist, torque_dist, adjust_dist; @@ -108,26 +107,26 @@ void calc_torque(struct vec3 *dst, const struct vec3 *v1, vec3_sub(&line, v2, v1); orig_dist = vec3_len(&line); - vec3_mulf(&dir, &line, 1.0f/orig_dist); + vec3_mulf(&dir, &line, 1.0f / orig_dist); - torque_dist = orig_dist*torque; /* use distance to determine speed */ - if (torque_dist < min_adjust) /* prevent from going too slow */ + torque_dist = orig_dist * torque; /* use distance to determine speed */ + if (torque_dist < min_adjust) /* prevent from going too slow */ torque_dist = min_adjust; - adjust_dist = torque_dist*t; + adjust_dist = torque_dist * t; - if (adjust_dist <= (orig_dist-LARGE_EPSILON)) { + if (adjust_dist <= (orig_dist - LARGE_EPSILON)) { vec3_mulf(dst, &dir, adjust_dist); vec3_add(dst, dst, v1); /* add torque */ } else { - vec3_copy(dst, v2); /* clamp if overshoot */ + vec3_copy(dst, v2); /* clamp if overshoot */ } } float rand_float(int positive_only) { if (positive_only) - return (float)((double)rand()/(double)RAND_MAX); + return (float)((double)rand() / (double)RAND_MAX); else - return (float)(((double)rand()/(double)RAND_MAX*2.0)-1.0); + return (float)(((double)rand() / (double)RAND_MAX * 2.0) - 1.0); } diff --git a/libobs/graphics/math-extra.h b/libobs/graphics/math-extra.h index 3042c47..1c5f364 100644 --- a/libobs/graphics/math-extra.h +++ b/libobs/graphics/math-extra.h @@ -40,20 +40,20 @@ EXPORT void norm_to_polar(struct vec2 *dst, const struct vec3 *norm); EXPORT void polar_to_norm(struct vec3 *dst, const struct vec2 *polar); EXPORT float calc_torquef(float val1, float val2, float torque, - float min_adjust, float t); + float min_adjust, float t); EXPORT void calc_torque(struct vec3 *dst, const struct vec3 *v1, - const struct vec3 *v2, float torque, float min_adjust, - float t); + const struct vec3 *v2, float torque, float min_adjust, + float t); static inline float get_percentage(float start, float end, float mid) { - return (mid-start) / (end-start); + return (mid - start) / (end - start); } static inline float get_percentagei(int start, int end, int mid) { - return (float)(mid-start) / (float)(end-start); + return (float)(mid - start) / (float)(end - start); } EXPORT float rand_float(int positive_only); diff --git a/libobs/graphics/matrix3.c b/libobs/graphics/matrix3.c index 06326e7..98f63f9 100644 --- a/libobs/graphics/matrix3.c +++ b/libobs/graphics/matrix3.c @@ -21,11 +21,10 @@ #include "plane.h" #include "quat.h" - void matrix3_from_quat(struct matrix3 *dst, const struct quat *q) { float norm = quat_dot(q, q); - float s = (norm > 0.0f) ? (2.0f/norm) : 0.0f; + float s = (norm > 0.0f) ? (2.0f / norm) : 0.0f; float xx = q->x * q->x * s; float yy = q->y * q->y * s; @@ -63,7 +62,7 @@ void matrix3_from_matrix4(struct matrix3 *dst, const struct matrix4 *m) } void matrix3_mul(struct matrix3 *dst, const struct matrix3 *m1, - const struct matrix3 *m2) + const struct matrix3 *m2) { if (dst == m2) { struct matrix3 temp; @@ -81,7 +80,7 @@ void matrix3_mul(struct matrix3 *dst, const struct matrix3 *m1, } void matrix3_rotate(struct matrix3 *dst, const struct matrix3 *m, - const struct quat *q) + const struct quat *q) { struct matrix3 temp; matrix3_from_quat(&temp, q); @@ -89,7 +88,7 @@ void matrix3_rotate(struct matrix3 *dst, const struct matrix3 *m, } void matrix3_rotate_aa(struct matrix3 *dst, const struct matrix3 *m, - const struct axisang *aa) + const struct axisang *aa) { struct matrix3 temp; matrix3_from_axisang(&temp, aa); @@ -97,7 +96,7 @@ void matrix3_rotate_aa(struct matrix3 *dst, const struct matrix3 *m, } void matrix3_scale(struct matrix3 *dst, const struct matrix3 *m, - const struct vec3 *v) + const struct vec3 *v) { vec3_mul(&dst->x, &m->x, v); vec3_mul(&dst->y, &m->y, v); @@ -122,12 +121,12 @@ void matrix3_inv(struct matrix3 *dst, const struct matrix3 *m) { struct matrix4 m4; matrix4_from_matrix3(&m4, m); - matrix4_inv((struct matrix4*)dst, &m4); + matrix4_inv((struct matrix4 *)dst, &m4); dst->t.w = 0.0f; } void matrix3_mirror(struct matrix3 *dst, const struct matrix3 *m, - const struct plane *p) + const struct plane *p) { vec3_mirrorv(&dst->x, &m->x, &p->dir); vec3_mirrorv(&dst->y, &m->y, &p->dir); @@ -136,7 +135,7 @@ void matrix3_mirror(struct matrix3 *dst, const struct matrix3 *m, } void matrix3_mirrorv(struct matrix3 *dst, const struct matrix3 *m, - const struct vec3 *v) + const struct vec3 *v) { vec3_mirrorv(&dst->x, &m->x, v); vec3_mirrorv(&dst->y, &m->y, v); diff --git a/libobs/graphics/matrix3.h b/libobs/graphics/matrix3.h index d04ec4f..22b0c80 100644 --- a/libobs/graphics/matrix3.h +++ b/libobs/graphics/matrix3.h @@ -53,34 +53,35 @@ static inline void matrix3_identity(struct matrix3 *dst) } EXPORT void matrix3_from_quat(struct matrix3 *dst, const struct quat *q); -EXPORT void matrix3_from_axisang(struct matrix3 *dst, - const struct axisang *aa); +EXPORT void matrix3_from_axisang(struct matrix3 *dst, const struct axisang *aa); EXPORT void matrix3_from_matrix4(struct matrix3 *dst, const struct matrix4 *m); EXPORT void matrix3_mul(struct matrix3 *dst, const struct matrix3 *m1, - const struct matrix3 *m2); + const struct matrix3 *m2); static inline void matrix3_translate(struct matrix3 *dst, - const struct matrix3 *m, const struct vec3 *v) + const struct matrix3 *m, + const struct vec3 *v) { vec3_sub(&dst->t, &m->t, v); } EXPORT void matrix3_rotate(struct matrix3 *dst, const struct matrix3 *m, - const struct quat *q); + const struct quat *q); EXPORT void matrix3_rotate_aa(struct matrix3 *dst, const struct matrix3 *m, - const struct axisang *aa); + const struct axisang *aa); EXPORT void matrix3_scale(struct matrix3 *dst, const struct matrix3 *m, - const struct vec3 *v); + const struct vec3 *v); EXPORT void matrix3_transpose(struct matrix3 *dst, const struct matrix3 *m); EXPORT void matrix3_inv(struct matrix3 *dst, const struct matrix3 *m); EXPORT void matrix3_mirror(struct matrix3 *dst, const struct matrix3 *m, - const struct plane *p); + const struct plane *p); EXPORT void matrix3_mirrorv(struct matrix3 *dst, const struct matrix3 *m, - const struct vec3 *v); + const struct vec3 *v); static inline void matrix3_translate3f(struct matrix3 *dst, - const struct matrix3 *m, float x, float y, float z) + const struct matrix3 *m, float x, + float y, float z) { struct vec3 v; vec3_set(&v, x, y, z); @@ -88,15 +89,16 @@ static inline void matrix3_translate3f(struct matrix3 *dst, } static inline void matrix3_rotate_aa4f(struct matrix3 *dst, - const struct matrix3 *m, float x, float y, float z, float rot) + const struct matrix3 *m, float x, + float y, float z, float rot) { struct axisang aa; axisang_set(&aa, x, y, z, rot); matrix3_rotate_aa(dst, m, &aa); } -static inline void matrix3_scale3f(struct matrix3 *dst, - const struct matrix3 *m, float x, float y, float z) +static inline void matrix3_scale3f(struct matrix3 *dst, const struct matrix3 *m, + float x, float y, float z) { struct vec3 v; vec3_set(&v, x, y, z); diff --git a/libobs/graphics/matrix4.c b/libobs/graphics/matrix4.c index a0a7a25..b03c7d4 100644 --- a/libobs/graphics/matrix4.c +++ b/libobs/graphics/matrix4.c @@ -32,7 +32,7 @@ void matrix4_from_matrix3(struct matrix4 *dst, const struct matrix3 *m) void matrix4_from_quat(struct matrix4 *dst, const struct quat *q) { float norm = quat_dot(q, q); - float s = (norm > 0.0f) ? (2.0f/norm) : 0.0f; + float s = (norm > 0.0f) ? (2.0f / norm) : 0.0f; float xx = q->x * q->x * s; float yy = q->y * q->y * s; @@ -58,26 +58,27 @@ void matrix4_from_axisang(struct matrix4 *dst, const struct axisang *aa) } void matrix4_mul(struct matrix4 *dst, const struct matrix4 *m1, - const struct matrix4 *m2) + const struct matrix4 *m2) { - const struct vec4 *m1v = (const struct vec4*)m1; - const float *m2f = (const float*)m2; + const struct vec4 *m1v = (const struct vec4 *)m1; + const float *m2f = (const float *)m2; struct vec4 out[4]; int i, j; for (i = 0; i < 4; i++) { - for (j=0; j<4; j++) { + for (j = 0; j < 4; j++) { struct vec4 temp; - vec4_set(&temp, m2f[j], m2f[j+4], m2f[j+8], m2f[j+12]); + vec4_set(&temp, m2f[j], m2f[j + 4], m2f[j + 8], + m2f[j + 12]); out[i].ptr[j] = vec4_dot(&m1v[i], &temp); } } - matrix4_copy(dst, (struct matrix4*)out); + matrix4_copy(dst, (struct matrix4 *)out); } -static inline void get_3x3_submatrix(float *dst, const struct matrix4 *m, - int i, int j) +static inline void get_3x3_submatrix(float *dst, const struct matrix4 *m, int i, + int j) { const float *mf = (const float *)m; int ti, tj, idst, jdst; @@ -86,7 +87,7 @@ static inline void get_3x3_submatrix(float *dst, const struct matrix4 *m, if (ti < i) idst = ti; else if (ti > i) - idst = ti-1; + idst = ti - 1; else continue; @@ -94,20 +95,20 @@ static inline void get_3x3_submatrix(float *dst, const struct matrix4 *m, if (tj < j) jdst = tj; else if (tj > j) - jdst = tj-1; + jdst = tj - 1; else continue; - dst[(idst*3) + jdst] = mf[(ti*4) + tj]; + dst[(idst * 3) + jdst] = mf[(ti * 4) + tj]; } } } static inline float get_3x3_determinant(const float *m) { - return (m[0] * ((m[4]*m[8]) - (m[7]*m[5]))) - - (m[1] * ((m[3]*m[8]) - (m[6]*m[5]))) + - (m[2] * ((m[3]*m[7]) - (m[6]*m[4]))); + return (m[0] * ((m[4] * m[8]) - (m[7] * m[5]))) - + (m[1] * ((m[3] * m[8]) - (m[6] * m[5]))) + + (m[2] * ((m[3] * m[7]) - (m[6] * m[4]))); } float matrix4_determinant(const struct matrix4 *m) @@ -117,10 +118,10 @@ float matrix4_determinant(const struct matrix4 *m) float m3x3[9]; int n; - for (n = 0; n < 4; n++, i *= -1.0f) { + for (n = 0; n < 4; n++, i = -i) { // NOLINT(clang-tidy-cert-flp30-c) get_3x3_submatrix(m3x3, m, 0, n); - det = get_3x3_determinant(m3x3); + det = get_3x3_determinant(m3x3); result += mf[n] * det * i; } @@ -128,7 +129,7 @@ float matrix4_determinant(const struct matrix4 *m) } void matrix4_translate3v(struct matrix4 *dst, const struct matrix4 *m, - const struct vec3 *v) + const struct vec3 *v) { struct matrix4 temp; vec4_set(&temp.x, 1.0f, 0.0f, 0.0f, 0.0f); @@ -140,7 +141,7 @@ void matrix4_translate3v(struct matrix4 *dst, const struct matrix4 *m, } void matrix4_translate4v(struct matrix4 *dst, const struct matrix4 *m, - const struct vec4 *v) + const struct vec4 *v) { struct matrix4 temp; vec4_set(&temp.x, 1.0f, 0.0f, 0.0f, 0.0f); @@ -152,7 +153,7 @@ void matrix4_translate4v(struct matrix4 *dst, const struct matrix4 *m, } void matrix4_rotate(struct matrix4 *dst, const struct matrix4 *m, - const struct quat *q) + const struct quat *q) { struct matrix4 temp; matrix4_from_quat(&temp, q); @@ -160,7 +161,7 @@ void matrix4_rotate(struct matrix4 *dst, const struct matrix4 *m, } void matrix4_rotate_aa(struct matrix4 *dst, const struct matrix4 *m, - const struct axisang *aa) + const struct axisang *aa) { struct matrix4 temp; matrix4_from_axisang(&temp, aa); @@ -168,7 +169,7 @@ void matrix4_rotate_aa(struct matrix4 *dst, const struct matrix4 *m, } void matrix4_scale(struct matrix4 *dst, const struct matrix4 *m, - const struct vec3 *v) + const struct vec3 *v) { struct matrix4 temp; vec4_set(&temp.x, v->x, 0.0f, 0.0f, 0.0f); @@ -179,7 +180,7 @@ void matrix4_scale(struct matrix4 *dst, const struct matrix4 *m, } void matrix4_translate3v_i(struct matrix4 *dst, const struct vec3 *v, - const struct matrix4 *m) + const struct matrix4 *m) { struct matrix4 temp; vec4_set(&temp.x, 1.0f, 0.0f, 0.0f, 0.0f); @@ -191,7 +192,7 @@ void matrix4_translate3v_i(struct matrix4 *dst, const struct vec3 *v, } void matrix4_translate4v_i(struct matrix4 *dst, const struct vec4 *v, - const struct matrix4 *m) + const struct matrix4 *m) { struct matrix4 temp; vec4_set(&temp.x, 1.0f, 0.0f, 0.0f, 0.0f); @@ -203,7 +204,7 @@ void matrix4_translate4v_i(struct matrix4 *dst, const struct vec4 *v, } void matrix4_rotate_i(struct matrix4 *dst, const struct quat *q, - const struct matrix4 *m) + const struct matrix4 *m) { struct matrix4 temp; matrix4_from_quat(&temp, q); @@ -211,7 +212,7 @@ void matrix4_rotate_i(struct matrix4 *dst, const struct quat *q, } void matrix4_rotate_aa_i(struct matrix4 *dst, const struct axisang *aa, - const struct matrix4 *m) + const struct matrix4 *m) { struct matrix4 temp; matrix4_from_axisang(&temp, aa); @@ -219,7 +220,7 @@ void matrix4_rotate_aa_i(struct matrix4 *dst, const struct axisang *aa, } void matrix4_scale_i(struct matrix4 *dst, const struct vec3 *v, - const struct matrix4 *m) + const struct matrix4 *m) { struct matrix4 temp; vec4_set(&temp.x, v->x, 0.0f, 0.0f, 0.0f); @@ -234,7 +235,7 @@ bool matrix4_inv(struct matrix4 *dst, const struct matrix4 *m) struct vec4 *dstv; float det; float m3x3[9]; - int i, j, sign; + int i, j, sign; if (dst == m) { struct matrix4 temp = *m; @@ -242,17 +243,17 @@ bool matrix4_inv(struct matrix4 *dst, const struct matrix4 *m) } dstv = (struct vec4 *)dst; - det = matrix4_determinant(m); + det = matrix4_determinant(m); if (fabs(det) < 0.0005f) return false; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { - sign = 1 - ((i+j) % 2) * 2; + sign = 1 - ((i + j) % 2) * 2; get_3x3_submatrix(m3x3, m, i, j); - dstv[j].ptr[i] = get_3x3_determinant(m3x3) * - (float)sign / det; + dstv[j].ptr[i] = + get_3x3_determinant(m3x3) * (float)sign / det; } } diff --git a/libobs/graphics/matrix4.h b/libobs/graphics/matrix4.h index e72e076..40a677d 100644 --- a/libobs/graphics/matrix4.h +++ b/libobs/graphics/matrix4.h @@ -55,40 +55,40 @@ static inline void matrix4_identity(struct matrix4 *dst) EXPORT void matrix4_from_matrix3(struct matrix4 *dst, const struct matrix3 *m); EXPORT void matrix4_from_quat(struct matrix4 *dst, const struct quat *q); -EXPORT void matrix4_from_axisang(struct matrix4 *dst, - const struct axisang *aa); +EXPORT void matrix4_from_axisang(struct matrix4 *dst, const struct axisang *aa); EXPORT void matrix4_mul(struct matrix4 *dst, const struct matrix4 *m1, - const struct matrix4 *m2); + const struct matrix4 *m2); EXPORT float matrix4_determinant(const struct matrix4 *m); EXPORT void matrix4_translate3v(struct matrix4 *dst, const struct matrix4 *m, - const struct vec3 *v); + const struct vec3 *v); EXPORT void matrix4_translate4v(struct matrix4 *dst, const struct matrix4 *m, - const struct vec4 *v); + const struct vec4 *v); EXPORT void matrix4_rotate(struct matrix4 *dst, const struct matrix4 *m, - const struct quat *q); + const struct quat *q); EXPORT void matrix4_rotate_aa(struct matrix4 *dst, const struct matrix4 *m, - const struct axisang *aa); + const struct axisang *aa); EXPORT void matrix4_scale(struct matrix4 *dst, const struct matrix4 *m, - const struct vec3 *v); + const struct vec3 *v); EXPORT bool matrix4_inv(struct matrix4 *dst, const struct matrix4 *m); EXPORT void matrix4_transpose(struct matrix4 *dst, const struct matrix4 *m); EXPORT void matrix4_translate3v_i(struct matrix4 *dst, const struct vec3 *v, - const struct matrix4 *m); + const struct matrix4 *m); EXPORT void matrix4_translate4v_i(struct matrix4 *dst, const struct vec4 *v, - const struct matrix4 *m); + const struct matrix4 *m); EXPORT void matrix4_rotate_i(struct matrix4 *dst, const struct quat *q, - const struct matrix4 *m); + const struct matrix4 *m); EXPORT void matrix4_rotate_aa_i(struct matrix4 *dst, const struct axisang *aa, - const struct matrix4 *m); + const struct matrix4 *m); EXPORT void matrix4_scale_i(struct matrix4 *dst, const struct vec3 *v, - const struct matrix4 *m); + const struct matrix4 *m); static inline void matrix4_translate3f(struct matrix4 *dst, - const struct matrix4 *m, float x, float y, float z) + const struct matrix4 *m, float x, + float y, float z) { struct vec3 v; vec3_set(&v, x, y, z); @@ -96,15 +96,16 @@ static inline void matrix4_translate3f(struct matrix4 *dst, } static inline void matrix4_rotate_aa4f(struct matrix4 *dst, - const struct matrix4 *m, float x, float y, float z, float rot) + const struct matrix4 *m, float x, + float y, float z, float rot) { struct axisang aa; axisang_set(&aa, x, y, z, rot); matrix4_rotate_aa(dst, m, &aa); } -static inline void matrix4_scale3f(struct matrix4 *dst, - const struct matrix4 *m, float x, float y, float z) +static inline void matrix4_scale3f(struct matrix4 *dst, const struct matrix4 *m, + float x, float y, float z) { struct vec3 v; vec3_set(&v, x, y, z); diff --git a/libobs/graphics/plane.c b/libobs/graphics/plane.c index f8fb0ca..237a32e 100644 --- a/libobs/graphics/plane.c +++ b/libobs/graphics/plane.c @@ -19,10 +19,8 @@ #include "matrix3.h" #include "plane.h" -void plane_from_tri(struct plane *dst, - const struct vec3 *v1, - const struct vec3 *v2, - const struct vec3 *v3) +void plane_from_tri(struct plane *dst, const struct vec3 *v1, + const struct vec3 *v2, const struct vec3 *v3) { struct vec3 temp; @@ -34,7 +32,7 @@ void plane_from_tri(struct plane *dst, } void plane_transform(struct plane *dst, const struct plane *p, - const struct matrix4 *m) + const struct matrix4 *m) { struct vec3 temp; @@ -48,7 +46,7 @@ void plane_transform(struct plane *dst, const struct plane *p, } void plane_transform3x4(struct plane *dst, const struct plane *p, - const struct matrix3 *m) + const struct matrix3 *m) { struct vec3 temp; @@ -60,7 +58,7 @@ void plane_transform3x4(struct plane *dst, const struct plane *p, } bool plane_intersection_ray(const struct plane *p, const struct vec3 *orig, - const struct vec3 *dir, float *t) + const struct vec3 *dir, float *t) { float c = vec3_dot(&p->dir, dir); @@ -74,10 +72,10 @@ bool plane_intersection_ray(const struct plane *p, const struct vec3 *orig, } bool plane_intersection_line(const struct plane *p, const struct vec3 *v1, - const struct vec3 *v2, float *t) + const struct vec3 *v2, float *t) { float p1_dist, p2_dist, p1_abs_dist, dist2; - bool p1_over, p2_over; + bool p1_over, p2_over; p1_dist = vec3_plane_dist(v1, p); p2_dist = vec3_plane_dist(v2, p); @@ -108,11 +106,9 @@ bool plane_intersection_line(const struct plane *p, const struct vec3 *v1, return true; } -bool plane_tri_inside(const struct plane *p, - const struct vec3 *v1, - const struct vec3 *v2, - const struct vec3 *v3, - float precision) +bool plane_tri_inside(const struct plane *p, const struct vec3 *v1, + const struct vec3 *v2, const struct vec3 *v3, + float precision) { /* bit 1: part or all is behind the plane */ /* bit 2: part or all is in front of the plane */ @@ -140,7 +136,7 @@ bool plane_tri_inside(const struct plane *p, } bool plane_line_inside(const struct plane *p, const struct vec3 *v1, - const struct vec3 *v2, float precision) + const struct vec3 *v2, float precision) { /* bit 1: part or all is behind the plane */ /* bit 2: part or all is in front of the plane */ diff --git a/libobs/graphics/plane.h b/libobs/graphics/plane.h index 439f452..c9d3dc5 100644 --- a/libobs/graphics/plane.h +++ b/libobs/graphics/plane.h @@ -29,7 +29,7 @@ struct matrix4; struct plane { struct vec3 dir; - float dist; + float dist; }; static inline void plane_copy(struct plane *dst, const struct plane *p) @@ -39,52 +39,50 @@ static inline void plane_copy(struct plane *dst, const struct plane *p) } static inline void plane_set(struct plane *dst, const struct vec3 *dir, - float dist) + float dist) { vec3_copy(&dst->dir, dir); dst->dist = dist; } static inline void plane_setf(struct plane *dst, float a, float b, float c, - float d) + float d) { vec3_set(&dst->dir, a, b, c); dst->dist = d; } -EXPORT void plane_from_tri(struct plane *dst, - const struct vec3 *v1, - const struct vec3 *v2, - const struct vec3 *v3); +EXPORT void plane_from_tri(struct plane *dst, const struct vec3 *v1, + const struct vec3 *v2, const struct vec3 *v3); EXPORT void plane_transform(struct plane *dst, const struct plane *p, - const struct matrix4 *m); + const struct matrix4 *m); EXPORT void plane_transform3x4(struct plane *dst, const struct plane *p, - const struct matrix3 *m); + const struct matrix3 *m); EXPORT bool plane_intersection_ray(const struct plane *p, - const struct vec3 *orig, const struct vec3 *dir, float *t); + const struct vec3 *orig, + const struct vec3 *dir, float *t); EXPORT bool plane_intersection_line(const struct plane *p, - const struct vec3 *v1, const struct vec3 *v2, float *t); + const struct vec3 *v1, + const struct vec3 *v2, float *t); -EXPORT bool plane_tri_inside(const struct plane *p, - const struct vec3 *v1, - const struct vec3 *v2, - const struct vec3 *v3, - float precision); +EXPORT bool plane_tri_inside(const struct plane *p, const struct vec3 *v1, + const struct vec3 *v2, const struct vec3 *v3, + float precision); EXPORT bool plane_line_inside(const struct plane *p, const struct vec3 *v1, - const struct vec3 *v2, float precision); + const struct vec3 *v2, float precision); static inline bool plane_close(const struct plane *p1, const struct plane *p2, - float precision) + float precision) { return vec3_close(&p1->dir, &p2->dir, precision) && close_float(p1->dist, p2->dist, precision); } static inline bool plane_coplanar(const struct plane *p1, - const struct plane *p2, float precision) + const struct plane *p2, float precision) { float cos_angle = vec3_dot(&p1->dir, &p2->dir); diff --git a/libobs/graphics/quat.c b/libobs/graphics/quat.c index 48af8a5..b27ad04 100644 --- a/libobs/graphics/quat.c +++ b/libobs/graphics/quat.c @@ -47,12 +47,12 @@ void quat_mul(struct quat *dst, const struct quat *q1, const struct quat *q2) void quat_from_axisang(struct quat *dst, const struct axisang *aa) { float halfa = aa->w * 0.5f; - float sine = sinf(halfa); + float sine = sinf(halfa); dst->x = aa->x * sine; dst->y = aa->y * sine; dst->z = aa->z * sine; - dst->w = cosf(halfa); + dst->w = cosf(halfa); } struct f4x4 { @@ -61,7 +61,7 @@ struct f4x4 { void quat_from_matrix3(struct quat *dst, const struct matrix3 *m) { - quat_from_matrix4(dst, (const struct matrix4*)m); + quat_from_matrix4(dst, (const struct matrix4 *)m); } void quat_from_matrix4(struct quat *dst, const struct matrix4 *m) @@ -69,7 +69,7 @@ void quat_from_matrix4(struct quat *dst, const struct matrix4 *m) float tr = (m->x.x + m->y.y + m->z.z); float inv_half; float four_d; - int i,j,k; + int i, j, k; if (tr > 0.0f) { four_d = sqrtf(tr + 1.0f); @@ -80,27 +80,28 @@ void quat_from_matrix4(struct quat *dst, const struct matrix4 *m) dst->y = (m->z.x - m->x.z) * inv_half; dst->z = (m->x.y - m->y.x) * inv_half; } else { - struct f4x4 *val = (struct f4x4*)m; + struct f4x4 *val = (struct f4x4 *)m; i = (m->x.x > m->y.y) ? 0 : 1; if (m->z.z > val->ptr[i][i]) i = 2; - j = (i+1) % 3; - k = (i+2) % 3; + j = (i + 1) % 3; + k = (i + 2) % 3; /* ---------------------------------- */ - four_d = sqrtf((val->ptr[i][i] - val->ptr[j][j] - - val->ptr[k][k]) + 1.0f); + four_d = sqrtf( + (val->ptr[i][i] - val->ptr[j][j] - val->ptr[k][k]) + + 1.0f); dst->ptr[i] = four_d * 0.5f; inv_half = 0.5f / four_d; - dst->ptr[j] = (val->ptr[i][j] + val->ptr[j][i]) * inv_half; - dst->ptr[k] = (val->ptr[i][k] + val->ptr[k][i]) * inv_half; - dst->w = (val->ptr[j][k] - val->ptr[k][j]) * inv_half; + dst->ptr[j] = (val->ptr[i][j] + val->ptr[j][i]) * inv_half; + dst->ptr[k] = (val->ptr[i][k] + val->ptr[k][i]) * inv_half; + dst->w = (val->ptr[j][k] - val->ptr[k][j]) * inv_half; } } @@ -115,8 +116,8 @@ void quat_set_look_dir(struct quat *dst, const struct vec3 *dir) { struct vec3 new_dir; struct quat xz_rot, yz_rot; - bool xz_valid; - bool yz_valid; + bool xz_valid; + bool yz_valid; struct axisang aa; vec3_norm(&new_dir, dir); @@ -126,12 +127,12 @@ void quat_set_look_dir(struct quat *dst, const struct vec3 *dir) quat_identity(&yz_rot); xz_valid = close_float(new_dir.x, 0.0f, EPSILON) || - close_float(new_dir.z, 0.0f, EPSILON); + close_float(new_dir.z, 0.0f, EPSILON); yz_valid = close_float(new_dir.y, 0.0f, EPSILON); if (xz_valid) { axisang_set(&aa, 0.0f, 1.0f, 0.0f, - atan2f(new_dir.x, new_dir.z)); + atan2f(new_dir.x, new_dir.z)); quat_from_axisang(&xz_rot, &aa); } @@ -151,31 +152,31 @@ void quat_set_look_dir(struct quat *dst, const struct vec3 *dir) void quat_log(struct quat *dst, const struct quat *q) { float angle = acosf(q->w); - float sine = sinf(angle); - float w = q->w; + float sine = sinf(angle); + float w = q->w; quat_copy(dst, q); dst->w = 0.0f; if ((fabsf(w) < 1.0f) && (fabsf(sine) >= EPSILON)) { - sine = angle/sine; + sine = angle / sine; quat_mulf(dst, dst, sine); } } void quat_exp(struct quat *dst, const struct quat *q) { - float length = sqrtf(q->x*q->x + q->y*q->y + q->z*q->z); - float sine = sinf(length); + float length = sqrtf(q->x * q->x + q->y * q->y + q->z * q->z); + float sine = sinf(length); quat_copy(dst, q); - sine = (length > EPSILON) ? (sine/length) : 1.0f; + sine = (length > EPSILON) ? (sine / length) : 1.0f; quat_mulf(dst, dst, sine); dst->w = cosf(length); } void quat_interpolate(struct quat *dst, const struct quat *q1, - const struct quat *q2, float t) + const struct quat *q2, float t) { float dot = quat_dot(q1, q2); float anglef = acosf(dot); @@ -183,10 +184,10 @@ void quat_interpolate(struct quat *dst, const struct quat *q1, struct quat temp; if (anglef >= EPSILON) { - sine = sinf(anglef); - sinei = 1/sine; - sinet = sinf(anglef*t)*sinei; - sineti = sinf(anglef*(1.0f-t))*sinei; + sine = sinf(anglef); + sinei = 1 / sine; + sinet = sinf(anglef * t) * sinei; + sineti = sinf(anglef * (1.0f - t)) * sinei; quat_mulf(&temp, q1, sineti); quat_mulf(dst, q2, sinet); @@ -199,7 +200,7 @@ void quat_interpolate(struct quat *dst, const struct quat *q1, } void quat_get_tangent(struct quat *dst, const struct quat *prev, - const struct quat *q, const struct quat *next) + const struct quat *q, const struct quat *next) { struct quat temp; @@ -209,14 +210,13 @@ void quat_get_tangent(struct quat *dst, const struct quat *prev, quat_mulf(dst, &temp, 0.5f); } -void quat_interpolate_cubic(struct quat *dst, - const struct quat *q1, const struct quat *q2, - const struct quat *m1, const struct quat *m2, - float t) +void quat_interpolate_cubic(struct quat *dst, const struct quat *q1, + const struct quat *q2, const struct quat *m1, + const struct quat *m2, float t) { struct quat temp1, temp2; quat_interpolate(&temp1, q1, q2, t); quat_interpolate(&temp2, m1, m2, t); - quat_interpolate(dst, &temp1, &temp2, 2.0f*(1.0f-t)*t); + quat_interpolate(dst, &temp1, &temp2, 2.0f * (1.0f - t) * t); } diff --git a/libobs/graphics/quat.h b/libobs/graphics/quat.h index adecac1..23552ca 100644 --- a/libobs/graphics/quat.h +++ b/libobs/graphics/quat.h @@ -40,7 +40,9 @@ struct axisang; struct quat { union { - struct {float x, y, z, w;}; + struct { + float x, y, z, w; + }; float ptr[4]; __m128 m; }; @@ -53,7 +55,7 @@ static inline void quat_identity(struct quat *q) } static inline void quat_set(struct quat *dst, float x, float y, float z, - float w) + float w) { dst->m = _mm_set_ps(x, y, z, w); } @@ -64,40 +66,36 @@ static inline void quat_copy(struct quat *dst, const struct quat *q) } static inline void quat_add(struct quat *dst, const struct quat *q1, - const struct quat *q2) + const struct quat *q2) { dst->m = _mm_add_ps(q1->m, q2->m); } static inline void quat_sub(struct quat *dst, const struct quat *q1, - const struct quat *q2) + const struct quat *q2) { dst->m = _mm_sub_ps(q1->m, q2->m); } EXPORT void quat_mul(struct quat *dst, const struct quat *q1, - const struct quat *q2); + const struct quat *q2); -static inline void quat_addf(struct quat *dst, const struct quat *q, - float f) +static inline void quat_addf(struct quat *dst, const struct quat *q, float f) { dst->m = _mm_add_ps(q->m, _mm_set1_ps(f)); } -static inline void quat_subf(struct quat *dst, const struct quat *q, - float f) +static inline void quat_subf(struct quat *dst, const struct quat *q, float f) { dst->m = _mm_sub_ps(q->m, _mm_set1_ps(f)); } -static inline void quat_mulf(struct quat *dst, const struct quat *q, - float f) +static inline void quat_mulf(struct quat *dst, const struct quat *q, float f) { dst->m = _mm_mul_ps(q->m, _mm_set1_ps(f)); } -static inline void quat_divf(struct quat *dst, const struct quat *q, - float f) +static inline void quat_divf(struct quat *dst, const struct quat *q, float f) { dst->m = _mm_div_ps(q->m, _mm_set1_ps(f)); } @@ -145,19 +143,17 @@ static inline float quat_dist(const struct quat *q1, const struct quat *q2) static inline void quat_norm(struct quat *dst, const struct quat *q) { float dot_val = quat_dot(q, q); - dst->m = (dot_val > 0.0f) ? - _mm_mul_ps(q->m, _mm_set1_ps(1.0f/sqrtf(dot_val))) : - _mm_setzero_ps(); + dst->m = (dot_val > 0.0f) + ? _mm_mul_ps(q->m, _mm_set1_ps(1.0f / sqrtf(dot_val))) + : _mm_setzero_ps(); } static inline bool quat_close(const struct quat *q1, const struct quat *q2, - float epsilon) + float epsilon) { struct quat test; quat_sub(&test, q1, q2); - return test.x < epsilon && - test.y < epsilon && - test.z < epsilon && + return test.x < epsilon && test.y < epsilon && test.z < epsilon && test.w < epsilon; } @@ -172,12 +168,12 @@ EXPORT void quat_log(struct quat *dst, const struct quat *q); EXPORT void quat_exp(struct quat *dst, const struct quat *q); EXPORT void quat_interpolate(struct quat *dst, const struct quat *q1, - const struct quat *q2, float t); + const struct quat *q2, float t); EXPORT void quat_get_tangent(struct quat *dst, const struct quat *prev, - const struct quat *q, const struct quat *next); + const struct quat *q, const struct quat *next); EXPORT void quat_interpolate_cubic(struct quat *dst, const struct quat *q1, - const struct quat *q2, const struct quat *m1, - const struct quat *m2, float t); + const struct quat *q2, const struct quat *m1, + const struct quat *m2, float t); #ifdef __cplusplus } diff --git a/libobs/graphics/shader-parser.c b/libobs/graphics/shader-parser.c index a9b354e..c685e6b 100644 --- a/libobs/graphics/shader-parser.c +++ b/libobs/graphics/shader-parser.c @@ -53,12 +53,12 @@ enum gs_sample_filter get_sample_filter(const char *filter) if (astrcmpi(filter, "Anisotropy") == 0) return GS_FILTER_ANISOTROPIC; - else if (astrcmpi(filter, "Point") == 0 || - strcmp(filter, "MIN_MAG_MIP_POINT") == 0) + else if (astrcmpi(filter, "Point") == 0 || + strcmp(filter, "MIN_MAG_MIP_POINT") == 0) return GS_FILTER_POINT; - else if (astrcmpi(filter, "Linear") == 0 || - strcmp(filter, "MIN_MAG_MIP_LINEAR") == 0) + else if (astrcmpi(filter, "Linear") == 0 || + strcmp(filter, "MIN_MAG_MIP_LINEAR") == 0) return GS_FILTER_LINEAR; else if (strcmp(filter, "MIN_MAG_POINT_MIP_LINEAR") == 0) @@ -99,7 +99,7 @@ extern enum gs_address_mode get_address_mode(const char *mode) } void shader_sampler_convert(struct shader_sampler *ss, - struct gs_sampler_info *info) + struct gs_sampler_info *info) { size_t i; memset(info, 0, sizeof(struct gs_sampler_info)); @@ -128,22 +128,26 @@ void shader_sampler_convert(struct shader_sampler *ss, /* ------------------------------------------------------------------------- */ static int sp_parse_sampler_state_item(struct shader_parser *sp, - struct shader_sampler *ss) + struct shader_sampler *ss) { int ret; char *state = NULL, *value = NULL; ret = cf_next_name(&sp->cfp, &state, "state name", ";"); - if (ret != PARSE_SUCCESS) goto fail; + if (ret != PARSE_SUCCESS) + goto fail; ret = cf_next_token_should_be(&sp->cfp, "=", ";", NULL); - if (ret != PARSE_SUCCESS) goto fail; + if (ret != PARSE_SUCCESS) + goto fail; ret = cf_next_token_copy(&sp->cfp, &value); - if (ret != PARSE_SUCCESS) goto fail; + if (ret != PARSE_SUCCESS) + goto fail; ret = cf_next_token_should_be(&sp->cfp, ";", ";", NULL); - if (ret != PARSE_SUCCESS) goto fail; + if (ret != PARSE_SUCCESS) + goto fail; da_push_back(ss->states, &state); da_push_back(ss->values, &value); @@ -191,17 +195,20 @@ error: } static inline int sp_parse_struct_var(struct shader_parser *sp, - struct shader_var *var) + struct shader_var *var) { int code; /* -------------------------------------- */ /* variable type */ - if (!cf_next_valid_token(&sp->cfp)) return PARSE_EOF; + if (!cf_next_valid_token(&sp->cfp)) + return PARSE_EOF; - if (cf_token_is(&sp->cfp, ";")) return PARSE_CONTINUE; - if (cf_token_is(&sp->cfp, "}")) return PARSE_BREAK; + if (cf_token_is(&sp->cfp, ";")) + return PARSE_CONTINUE; + if (cf_token_is(&sp->cfp, "}")) + return PARSE_BREAK; code = cf_token_is_type(&sp->cfp, CFTOKEN_NAME, "type name", ";"); if (code != PARSE_SUCCESS) @@ -212,13 +219,15 @@ static inline int sp_parse_struct_var(struct shader_parser *sp, /* -------------------------------------- */ /* variable name */ - if (!cf_next_valid_token(&sp->cfp)) return PARSE_EOF; + if (!cf_next_valid_token(&sp->cfp)) + return PARSE_EOF; - if (cf_token_is(&sp->cfp, ";")) return PARSE_UNEXPECTED_CONTINUE; - if (cf_token_is(&sp->cfp, "}")) return PARSE_UNEXPECTED_BREAK; + if (cf_token_is(&sp->cfp, ";")) + return PARSE_UNEXPECTED_CONTINUE; + if (cf_token_is(&sp->cfp, "}")) + return PARSE_UNEXPECTED_BREAK; - code = cf_token_is_type(&sp->cfp, CFTOKEN_NAME, "variable name", - ";"); + code = cf_token_is_type(&sp->cfp, CFTOKEN_NAME, "variable name", ";"); if (code != PARSE_SUCCESS) return code; @@ -227,24 +236,27 @@ static inline int sp_parse_struct_var(struct shader_parser *sp, /* -------------------------------------- */ /* variable mapping if any (POSITION, TEXCOORD, etc) */ - if (!cf_next_valid_token(&sp->cfp)) return PARSE_EOF; + if (!cf_next_valid_token(&sp->cfp)) + return PARSE_EOF; if (cf_token_is(&sp->cfp, ":")) { - if (!cf_next_valid_token(&sp->cfp)) return PARSE_EOF; + if (!cf_next_valid_token(&sp->cfp)) + return PARSE_EOF; if (cf_token_is(&sp->cfp, ";")) return PARSE_UNEXPECTED_CONTINUE; if (cf_token_is(&sp->cfp, "}")) return PARSE_UNEXPECTED_BREAK; - code = cf_token_is_type(&sp->cfp, CFTOKEN_NAME, - "mapping name", ";"); + code = cf_token_is_type(&sp->cfp, CFTOKEN_NAME, "mapping name", + ";"); if (code != PARSE_SUCCESS) return code; cf_copy_token(&sp->cfp, &var->mapping); - if (!cf_next_valid_token(&sp->cfp)) return PARSE_EOF; + if (!cf_next_valid_token(&sp->cfp)) + return PARSE_EOF; } /* -------------------------------------- */ @@ -314,7 +326,7 @@ error: } static inline int sp_check_for_keyword(struct shader_parser *sp, - const char *keyword, bool *val) + const char *keyword, bool *val) { bool new_val = cf_token_is(&sp->cfp, keyword); if (new_val) { @@ -323,7 +335,7 @@ static inline int sp_check_for_keyword(struct shader_parser *sp, if (new_val && *val) cf_adderror(&sp->cfp, "'$1' keyword already specified", - LEX_WARNING, keyword, NULL, NULL); + LEX_WARNING, keyword, NULL, NULL); *val = new_val; return PARSE_CONTINUE; @@ -333,7 +345,7 @@ static inline int sp_check_for_keyword(struct shader_parser *sp, } static inline int sp_parse_func_param(struct shader_parser *sp, - struct shader_var *var) + struct shader_var *var) { int code; bool var_type_keyword = false; @@ -384,7 +396,7 @@ static inline int sp_parse_func_param(struct shader_parser *sp, if (cf_token_is(&sp->cfp, ":")) { code = cf_next_name(&sp->cfp, &var->mapping, - "mapping specifier", ")"); + "mapping specifier", ")"); if (code != PARSE_SUCCESS) return code; @@ -396,7 +408,7 @@ static inline int sp_parse_func_param(struct shader_parser *sp, } static bool sp_parse_func_params(struct shader_parser *sp, - struct shader_func *func) + struct shader_func *func) { struct cf_token peek; int code; @@ -449,8 +461,8 @@ static void sp_parse_function(struct shader_parser *sp, char *type, char *name) /* if function is mapped to something, for example COLOR */ if (cf_token_is(&sp->cfp, ":")) { char *mapping = NULL; - int errorcode = cf_next_name(&sp->cfp, &mapping, "mapping", - "{"); + int errorcode = + cf_next_name(&sp->cfp, &mapping, "mapping", "{"); if (errorcode != PARSE_SUCCESS) goto error; @@ -482,17 +494,18 @@ error: /* parses "array[count]" */ static bool sp_parse_param_array(struct shader_parser *sp, - struct shader_var *param) + struct shader_var *param) { if (!cf_next_valid_token(&sp->cfp)) return false; if (sp->cfp.cur_token->type != CFTOKEN_NUM || !valid_int_str(sp->cfp.cur_token->str.array, - sp->cfp.cur_token->str.len)) + sp->cfp.cur_token->str.len)) return false; - param->array_count =(int)strtol(sp->cfp.cur_token->str.array, NULL, 10); + param->array_count = + (int)strtol(sp->cfp.cur_token->str.array, NULL, 10); if (cf_next_token_should_be(&sp->cfp, "]", ";", NULL) == PARSE_EOF) return false; @@ -504,7 +517,8 @@ static bool sp_parse_param_array(struct shader_parser *sp, } static inline int sp_parse_param_assign_intfloat(struct shader_parser *sp, - struct shader_var *param, bool is_float) + struct shader_var *param, + bool is_float) { int code; bool is_negative = false; @@ -525,11 +539,13 @@ static inline int sp_parse_param_assign_intfloat(struct shader_parser *sp, if (is_float) { float f = (float)os_strtod(sp->cfp.cur_token->str.array); - if (is_negative) f = -f; + if (is_negative) + f = -f; da_push_back_array(param->default_val, &f, sizeof(float)); } else { long l = strtol(sp->cfp.cur_token->str.array, NULL, 10); - if (is_negative) l = -l; + if (is_negative) + l = -l; da_push_back_array(param->default_val, &l, sizeof(long)); } @@ -541,47 +557,50 @@ static inline int sp_parse_param_assign_intfloat(struct shader_parser *sp, * for float3x3, float4x4, etc */ static inline int sp_parse_param_assign_float_array(struct shader_parser *sp, - struct shader_var *param) + struct shader_var *param) { - const char *float_type = param->type+5; + const char *float_type = param->type + 5; int float_count = 0, code, i; /* -------------------------------------------- */ if (float_type[0] < '1' || float_type[0] > '4') - cf_adderror(&sp->cfp, "Invalid row count", LEX_ERROR, - NULL, NULL, NULL); + cf_adderror(&sp->cfp, "Invalid row count", LEX_ERROR, NULL, + NULL, NULL); - float_count = float_type[0]-'0'; + float_count = float_type[0] - '0'; if (float_type[1] == 'x') { if (float_type[2] < '1' || float_type[2] > '4') - cf_adderror(&sp->cfp, "Invalid column count", - LEX_ERROR, NULL, NULL, NULL); + cf_adderror(&sp->cfp, "Invalid column count", LEX_ERROR, + NULL, NULL, NULL); - float_count *= float_type[2]-'0'; + float_count *= float_type[2] - '0'; } /* -------------------------------------------- */ code = cf_next_token_should_be(&sp->cfp, "{", ";", NULL); - if (code != PARSE_SUCCESS) return code; + if (code != PARSE_SUCCESS) + return code; for (i = 0; i < float_count; i++) { - char *next = ((i+1) < float_count) ? "," : "}"; + char *next = ((i + 1) < float_count) ? "," : "}"; code = sp_parse_param_assign_intfloat(sp, param, true); - if (code != PARSE_SUCCESS) return code; + if (code != PARSE_SUCCESS) + return code; code = cf_next_token_should_be(&sp->cfp, next, ";", NULL); - if (code != PARSE_SUCCESS) return code; + if (code != PARSE_SUCCESS) + return code; } return PARSE_SUCCESS; } static int sp_parse_param_assignment_val(struct shader_parser *sp, - struct shader_var *param) + struct shader_var *param) { if (strcmp(param->type, "int") == 0) return sp_parse_param_assign_intfloat(sp, param, false); @@ -591,13 +610,13 @@ static int sp_parse_param_assignment_val(struct shader_parser *sp, return sp_parse_param_assign_float_array(sp, param); cf_adderror(&sp->cfp, "Invalid type '$1' used for assignment", - LEX_ERROR, param->type, NULL, NULL); + LEX_ERROR, param->type, NULL, NULL); return PARSE_CONTINUE; } static inline bool sp_parse_param_assign(struct shader_parser *sp, - struct shader_var *param) + struct shader_var *param) { if (sp_parse_param_assignment_val(sp, param) != PARSE_SUCCESS) return false; @@ -608,8 +627,8 @@ static inline bool sp_parse_param_assign(struct shader_parser *sp, return true; } -static void sp_parse_param(struct shader_parser *sp, - char *type, char *name, bool is_const, bool is_uniform) +static void sp_parse_param(struct shader_parser *sp, char *type, char *name, + bool is_const, bool is_uniform) { struct shader_var param; shader_var_init_param(¶m, type, name, is_uniform, is_const); @@ -631,10 +650,10 @@ error: shader_var_free(¶m); } -static bool sp_get_var_specifiers(struct shader_parser *sp, - bool *is_const, bool *is_uniform) +static bool sp_get_var_specifiers(struct shader_parser *sp, bool *is_const, + bool *is_uniform) { - while(true) { + while (true) { int code = sp_check_for_keyword(sp, "const", is_const); if (code == PARSE_EOF) return false; @@ -654,12 +673,13 @@ static bool sp_get_var_specifiers(struct shader_parser *sp, } static inline void report_invalid_func_keyword(struct shader_parser *sp, - const char *name, bool val) + const char *name, bool val) { if (val) - cf_adderror(&sp->cfp, "'$1' keyword cannot be used with a " - "function", LEX_ERROR, - name, NULL, NULL); + cf_adderror(&sp->cfp, + "'$1' keyword cannot be used with a " + "function", + LEX_ERROR, name, NULL, NULL); } static void sp_parse_other(struct shader_parser *sp) @@ -679,8 +699,8 @@ static void sp_parse_other(struct shader_parser *sp) goto error; if (cf_token_is(&sp->cfp, "(")) { - report_invalid_func_keyword(sp, "const", is_const); - report_invalid_func_keyword(sp, "uniform", is_uniform); + report_invalid_func_keyword(sp, "const", is_const); + report_invalid_func_keyword(sp, "uniform", is_uniform); sp_parse_function(sp, type, name); return; @@ -695,7 +715,7 @@ error: } bool shader_parse(struct shader_parser *sp, const char *shader, - const char *file) + const char *file) { if (!cf_parser_parse(&sp->cfp, shader, file)) return false; @@ -713,7 +733,7 @@ bool shader_parse(struct shader_parser *sp, const char *shader, } else if (cf_token_is(&sp->cfp, "{")) { cf_adderror(&sp->cfp, "Unexpected code segment", - LEX_ERROR, NULL, NULL, NULL); + LEX_ERROR, NULL, NULL, NULL); cf_pass_pair(&sp->cfp, '{', '}'); } else { diff --git a/libobs/graphics/shader-parser.h b/libobs/graphics/shader-parser.h index 8292904..3776734 100644 --- a/libobs/graphics/shader-parser.h +++ b/libobs/graphics/shader-parser.h @@ -61,9 +61,9 @@ static inline void shader_var_init(struct shader_var *sv) memset(sv, 0, sizeof(struct shader_var)); } -static inline void shader_var_init_param(struct shader_var *sv, - char *type, char *name, bool is_uniform, - bool is_const) +static inline void shader_var_init_param(struct shader_var *sv, char *type, + char *name, bool is_uniform, + bool is_const) { if (is_uniform) sv->var_type = SHADER_VAR_UNIFORM; @@ -72,10 +72,11 @@ static inline void shader_var_init_param(struct shader_var *sv, else sv->var_type = SHADER_VAR_NONE; - sv->type = type; - sv->name = name; - sv->mapping = NULL; + sv->type = type; + sv->name = name; + sv->mapping = NULL; sv->array_count = 0; + sv->gl_sampler_id = (size_t)-1; da_init(sv->default_val); } @@ -91,8 +92,8 @@ static inline void shader_var_free(struct shader_var *sv) struct shader_sampler { char *name; - DARRAY(char*) states; - DARRAY(char*) values; + DARRAY(char *) states; + DARRAY(char *) values; }; static inline void shader_sampler_init(struct shader_sampler *ss) @@ -114,7 +115,7 @@ static inline void shader_sampler_free(struct shader_sampler *ss) } EXPORT void shader_sampler_convert(struct shader_sampler *ss, - struct gs_sampler_info *info); + struct gs_sampler_info *info); /* ------------------------------------------------------------------------- */ @@ -133,7 +134,7 @@ static inline void shader_struct_free(struct shader_struct *ss) size_t i; for (i = 0; i < ss->vars.num; i++) - shader_var_free(ss->vars.array+i); + shader_var_free(ss->vars.array + i); bfree(ss->name); da_free(ss->vars); @@ -150,16 +151,16 @@ struct shader_func { struct cf_token *start, *end; }; -static inline void shader_func_init(struct shader_func *sf, - char *return_type, char *name) +static inline void shader_func_init(struct shader_func *sf, char *return_type, + char *name) { da_init(sf->params); - sf->return_type = return_type; + sf->return_type = return_type; sf->mapping = NULL; - sf->name = name; - sf->start = NULL; - sf->end = NULL; + sf->name = name; + sf->start = NULL; + sf->end = NULL; } static inline void shader_func_free(struct shader_func *sf) @@ -167,7 +168,7 @@ static inline void shader_func_free(struct shader_func *sf) size_t i; for (i = 0; i < sf->params.num; i++) - shader_var_free(sf->params.array+i); + shader_var_free(sf->params.array + i); bfree(sf->name); bfree(sf->return_type); @@ -180,10 +181,10 @@ static inline void shader_func_free(struct shader_func *sf) struct shader_parser { struct cf_parser cfp; - DARRAY(struct shader_var) params; - DARRAY(struct shader_struct) structs; + DARRAY(struct shader_var) params; + DARRAY(struct shader_struct) structs; DARRAY(struct shader_sampler) samplers; - DARRAY(struct shader_func) funcs; + DARRAY(struct shader_func) funcs; }; static inline void shader_parser_init(struct shader_parser *sp) @@ -201,13 +202,13 @@ static inline void shader_parser_free(struct shader_parser *sp) size_t i; for (i = 0; i < sp->params.num; i++) - shader_var_free(sp->params.array+i); + shader_var_free(sp->params.array + i); for (i = 0; i < sp->structs.num; i++) - shader_struct_free(sp->structs.array+i); + shader_struct_free(sp->structs.array + i); for (i = 0; i < sp->samplers.num; i++) - shader_sampler_free(sp->samplers.array+i); + shader_sampler_free(sp->samplers.array + i); for (i = 0; i < sp->funcs.num; i++) - shader_func_free(sp->funcs.array+i); + shader_func_free(sp->funcs.array + i); cf_parser_free(&sp->cfp); da_free(sp->params); @@ -217,19 +218,19 @@ static inline void shader_parser_free(struct shader_parser *sp) } EXPORT bool shader_parse(struct shader_parser *sp, const char *shader, - const char *file); + const char *file); static inline char *shader_parser_geterrors(struct shader_parser *sp) { return error_data_buildstring(&sp->cfp.error_list); } -static inline struct shader_var *shader_parser_getparam( - struct shader_parser *sp, const char *param_name) +static inline struct shader_var * +shader_parser_getparam(struct shader_parser *sp, const char *param_name) { size_t i; for (i = 0; i < sp->params.num; i++) { - struct shader_var *param = sp->params.array+i; + struct shader_var *param = sp->params.array + i; if (strcmp(param->name, param_name) == 0) return param; } @@ -237,12 +238,12 @@ static inline struct shader_var *shader_parser_getparam( return NULL; } -static inline struct shader_struct *shader_parser_getstruct( - struct shader_parser *sp, const char *struct_name) +static inline struct shader_struct * +shader_parser_getstruct(struct shader_parser *sp, const char *struct_name) { size_t i; for (i = 0; i < sp->structs.num; i++) { - struct shader_struct *st = sp->structs.array+i; + struct shader_struct *st = sp->structs.array + i; if (strcmp(st->name, struct_name) == 0) return st; } @@ -250,12 +251,12 @@ static inline struct shader_struct *shader_parser_getstruct( return NULL; } -static inline struct shader_sampler *shader_parser_getsampler( - struct shader_parser *sp, const char *sampler_name) +static inline struct shader_sampler * +shader_parser_getsampler(struct shader_parser *sp, const char *sampler_name) { size_t i; for (i = 0; i < sp->samplers.num; i++) { - struct shader_sampler *sampler = sp->samplers.array+i; + struct shader_sampler *sampler = sp->samplers.array + i; if (strcmp(sampler->name, sampler_name) == 0) return sampler; } @@ -263,12 +264,12 @@ static inline struct shader_sampler *shader_parser_getsampler( return NULL; } -static inline struct shader_func *shader_parser_getfunc( - struct shader_parser *sp, const char *func_name) +static inline struct shader_func * +shader_parser_getfunc(struct shader_parser *sp, const char *func_name) { size_t i; for (i = 0; i < sp->funcs.num; i++) { - struct shader_func *func = sp->funcs.array+i; + struct shader_func *func = sp->funcs.array + i; if (strcmp(func->name, func_name) == 0) return func; } diff --git a/libobs/graphics/texture-render.c b/libobs/graphics/texture-render.c index 2e5410e..9027a45 100644 --- a/libobs/graphics/texture-render.c +++ b/libobs/graphics/texture-render.c @@ -24,23 +24,23 @@ #include "graphics.h" struct gs_texture_render { - gs_texture_t *target, *prev_target; + gs_texture_t *target, *prev_target; gs_zstencil_t *zs, *prev_zs; uint32_t cx, cy; - enum gs_color_format format; + enum gs_color_format format; enum gs_zstencil_format zsformat; bool rendered; }; gs_texrender_t *gs_texrender_create(enum gs_color_format format, - enum gs_zstencil_format zsformat) + enum gs_zstencil_format zsformat) { struct gs_texture_render *texrender; texrender = bzalloc(sizeof(struct gs_texture_render)); - texrender->format = format; + texrender->format = format; texrender->zsformat = zsformat; return texrender; @@ -56,7 +56,7 @@ void gs_texrender_destroy(gs_texrender_t *texrender) } static bool texrender_resetbuffer(gs_texrender_t *texrender, uint32_t cx, - uint32_t cy) + uint32_t cy) { if (!texrender) return false; @@ -65,12 +65,12 @@ static bool texrender_resetbuffer(gs_texrender_t *texrender, uint32_t cx, gs_zstencil_destroy(texrender->zs); texrender->target = NULL; - texrender->zs = NULL; - texrender->cx = cx; - texrender->cy = cy; + texrender->zs = NULL; + texrender->cx = cx; + texrender->cy = cy; - texrender->target = gs_texture_create(cx, cy, texrender->format, - 1, NULL, GS_RENDER_TARGET); + texrender->target = gs_texture_create(cx, cy, texrender->format, 1, + NULL, GS_RENDER_TARGET); if (!texrender->target) return false; @@ -108,7 +108,7 @@ bool gs_texrender_begin(gs_texrender_t *texrender, uint32_t cx, uint32_t cy) gs_matrix_identity(); texrender->prev_target = gs_get_render_target(); - texrender->prev_zs = gs_get_zstencil_target(); + texrender->prev_zs = gs_get_zstencil_target(); gs_set_render_target(texrender->target, texrender->zs); gs_set_viewport(0, 0, texrender->cx, texrender->cy); diff --git a/libobs/graphics/vec2.h b/libobs/graphics/vec2.h index f06bc80..a13d2f1 100644 --- a/libobs/graphics/vec2.h +++ b/libobs/graphics/vec2.h @@ -52,51 +52,47 @@ static inline void vec2_copy(struct vec2 *dst, const struct vec2 *v) } static inline void vec2_add(struct vec2 *dst, const struct vec2 *v1, - const struct vec2 *v2) + const struct vec2 *v2) { - vec2_set(dst, v1->x+v2->x, v1->y+v2->y); + vec2_set(dst, v1->x + v2->x, v1->y + v2->y); } static inline void vec2_sub(struct vec2 *dst, const struct vec2 *v1, - const struct vec2 *v2) + const struct vec2 *v2) { - vec2_set(dst, v1->x-v2->x, v1->y-v2->y); + vec2_set(dst, v1->x - v2->x, v1->y - v2->y); } static inline void vec2_mul(struct vec2 *dst, const struct vec2 *v1, - const struct vec2 *v2) + const struct vec2 *v2) { - vec2_set(dst, v1->x*v2->x, v1->y*v2->y); + vec2_set(dst, v1->x * v2->x, v1->y * v2->y); } static inline void vec2_div(struct vec2 *dst, const struct vec2 *v1, - const struct vec2 *v2) + const struct vec2 *v2) { - vec2_set(dst, v1->x/v2->x, v1->y/v2->y); + vec2_set(dst, v1->x / v2->x, v1->y / v2->y); } -static inline void vec2_addf(struct vec2 *dst, const struct vec2 *v, - float f) +static inline void vec2_addf(struct vec2 *dst, const struct vec2 *v, float f) { - vec2_set(dst, v->x+f, v->y+f); + vec2_set(dst, v->x + f, v->y + f); } -static inline void vec2_subf(struct vec2 *dst, const struct vec2 *v, - float f) +static inline void vec2_subf(struct vec2 *dst, const struct vec2 *v, float f) { - vec2_set(dst, v->x-f, v->y-f); + vec2_set(dst, v->x - f, v->y - f); } -static inline void vec2_mulf(struct vec2 *dst, const struct vec2 *v, - float f) +static inline void vec2_mulf(struct vec2 *dst, const struct vec2 *v, float f) { - vec2_set(dst, v->x*f, v->y*f); + vec2_set(dst, v->x * f, v->y * f); } -static inline void vec2_divf(struct vec2 *dst, const struct vec2 *v, - float f) +static inline void vec2_divf(struct vec2 *dst, const struct vec2 *v, float f) { - vec2_set(dst, v->x/f, v->y/f); + vec2_set(dst, v->x / f, v->y / f); } static inline void vec2_neg(struct vec2 *dst, const struct vec2 *v) @@ -106,12 +102,12 @@ static inline void vec2_neg(struct vec2 *dst, const struct vec2 *v) static inline float vec2_dot(const struct vec2 *v1, const struct vec2 *v2) { - return v1->x*v2->x + v1->y*v2->y; + return v1->x * v2->x + v1->y * v2->y; } static inline float vec2_len(const struct vec2 *v) { - return sqrtf(v->x*v->x + v->y*v->y); + return sqrtf(v->x * v->x + v->y * v->y); } static inline float vec2_dist(const struct vec2 *v1, const struct vec2 *v2) @@ -121,8 +117,7 @@ static inline float vec2_dist(const struct vec2 *v1, const struct vec2 *v2) return vec2_len(&temp); } -static inline void vec2_minf(struct vec2 *dst, const struct vec2 *v, - float val) +static inline void vec2_minf(struct vec2 *dst, const struct vec2 *v, float val) { if (v->x < val) dst->x = val; @@ -131,7 +126,7 @@ static inline void vec2_minf(struct vec2 *dst, const struct vec2 *v, } static inline void vec2_min(struct vec2 *dst, const struct vec2 *v, - const struct vec2 *min_v) + const struct vec2 *min_v) { if (v->x < min_v->x) dst->x = min_v->x; @@ -139,8 +134,7 @@ static inline void vec2_min(struct vec2 *dst, const struct vec2 *v, dst->y = min_v->y; } -static inline void vec2_maxf(struct vec2 *dst, const struct vec2 *v, - float val) +static inline void vec2_maxf(struct vec2 *dst, const struct vec2 *v, float val) { if (v->x > val) dst->x = val; @@ -149,7 +143,7 @@ static inline void vec2_maxf(struct vec2 *dst, const struct vec2 *v, } static inline void vec2_max(struct vec2 *dst, const struct vec2 *v, - const struct vec2 *max_v) + const struct vec2 *max_v) { if (v->x > max_v->x) dst->x = max_v->x; @@ -161,7 +155,7 @@ EXPORT void vec2_abs(struct vec2 *dst, const struct vec2 *v); EXPORT void vec2_floor(struct vec2 *dst, const struct vec2 *v); EXPORT void vec2_ceil(struct vec2 *dst, const struct vec2 *v); EXPORT int vec2_close(const struct vec2 *v1, const struct vec2 *v2, - float epsilon); + float epsilon); EXPORT void vec2_norm(struct vec2 *dst, const struct vec2 *v); #ifdef __cplusplus diff --git a/libobs/graphics/vec3.c b/libobs/graphics/vec3.c index 7ccd0ea..7e7fd4e 100644 --- a/libobs/graphics/vec3.c +++ b/libobs/graphics/vec3.c @@ -35,7 +35,7 @@ float vec3_plane_dist(const struct vec3 *v, const struct plane *p) } void vec3_rotate(struct vec3 *dst, const struct vec3 *v, - const struct matrix3 *m) + const struct matrix3 *m) { struct vec3 temp; vec3_copy(&temp, v); @@ -47,7 +47,7 @@ void vec3_rotate(struct vec3 *dst, const struct vec3 *v, } void vec3_transform(struct vec3 *dst, const struct vec3 *v, - const struct matrix4 *m) + const struct matrix4 *m) { struct vec4 v4; vec4_from_vec3(&v4, v); @@ -56,7 +56,7 @@ void vec3_transform(struct vec3 *dst, const struct vec3 *v, } void vec3_transform3x4(struct vec3 *dst, const struct vec3 *v, - const struct matrix3 *m) + const struct matrix3 *m) { struct vec3 temp; vec3_sub(&temp, v, &m->t); @@ -75,7 +75,7 @@ void vec3_mirror(struct vec3 *dst, const struct vec3 *v, const struct plane *p) } void vec3_mirrorv(struct vec3 *dst, const struct vec3 *v, - const struct vec3 *vec) + const struct vec3 *vec) { struct vec3 temp; vec3_mulf(&temp, vec, vec3_dot(v, vec) * 2.0f); diff --git a/libobs/graphics/vec3.h b/libobs/graphics/vec3.h index b0e38f3..d6b9f8d 100644 --- a/libobs/graphics/vec3.h +++ b/libobs/graphics/vec3.h @@ -58,54 +58,50 @@ static inline void vec3_copy(struct vec3 *dst, const struct vec3 *v) EXPORT void vec3_from_vec4(struct vec3 *dst, const struct vec4 *v); static inline void vec3_add(struct vec3 *dst, const struct vec3 *v1, - const struct vec3 *v2) + const struct vec3 *v2) { dst->m = _mm_add_ps(v1->m, v2->m); dst->w = 0.0f; } static inline void vec3_sub(struct vec3 *dst, const struct vec3 *v1, - const struct vec3 *v2) + const struct vec3 *v2) { dst->m = _mm_sub_ps(v1->m, v2->m); dst->w = 0.0f; } static inline void vec3_mul(struct vec3 *dst, const struct vec3 *v1, - const struct vec3 *v2) + const struct vec3 *v2) { dst->m = _mm_mul_ps(v1->m, v2->m); } static inline void vec3_div(struct vec3 *dst, const struct vec3 *v1, - const struct vec3 *v2) + const struct vec3 *v2) { dst->m = _mm_div_ps(v1->m, v2->m); dst->w = 0.0f; } -static inline void vec3_addf(struct vec3 *dst, const struct vec3 *v, - float f) +static inline void vec3_addf(struct vec3 *dst, const struct vec3 *v, float f) { dst->m = _mm_add_ps(v->m, _mm_set1_ps(f)); dst->w = 0.0f; } -static inline void vec3_subf(struct vec3 *dst, const struct vec3 *v, - float f) +static inline void vec3_subf(struct vec3 *dst, const struct vec3 *v, float f) { dst->m = _mm_sub_ps(v->m, _mm_set1_ps(f)); dst->w = 0.0f; } -static inline void vec3_mulf(struct vec3 *dst, const struct vec3 *v, - float f) +static inline void vec3_mulf(struct vec3 *dst, const struct vec3 *v, float f) { dst->m = _mm_mul_ps(v->m, _mm_set1_ps(f)); } -static inline void vec3_divf(struct vec3 *dst, const struct vec3 *v, - float f) +static inline void vec3_divf(struct vec3 *dst, const struct vec3 *v, float f) { dst->m = _mm_div_ps(v->m, _mm_set1_ps(f)); dst->w = 0.0f; @@ -121,7 +117,7 @@ static inline float vec3_dot(const struct vec3 *v1, const struct vec3 *v2) } static inline void vec3_cross(struct vec3 *dst, const struct vec3 *v1, - const struct vec3 *v2) + const struct vec3 *v2) { __m128 s1v1 = _mm_shuffle_ps(v1->m, v1->m, _MM_SHUFFLE(3, 0, 2, 1)); __m128 s1v2 = _mm_shuffle_ps(v2->m, v2->m, _MM_SHUFFLE(3, 1, 0, 2)); @@ -157,13 +153,13 @@ static inline float vec3_dist(const struct vec3 *v1, const struct vec3 *v2) static inline void vec3_norm(struct vec3 *dst, const struct vec3 *v) { float dot_val = vec3_dot(v, v); - dst->m = (dot_val > 0.0f) ? - _mm_mul_ps(v->m, _mm_set1_ps(1.0f/sqrtf(dot_val))) : - _mm_setzero_ps(); + dst->m = (dot_val > 0.0f) + ? _mm_mul_ps(v->m, _mm_set1_ps(1.0f / sqrtf(dot_val))) + : _mm_setzero_ps(); } static inline bool vec3_close(const struct vec3 *v1, const struct vec3 *v2, - float epsilon) + float epsilon) { struct vec3 test; vec3_sub(&test, v1, v2); @@ -171,28 +167,26 @@ static inline bool vec3_close(const struct vec3 *v1, const struct vec3 *v2, } static inline void vec3_min(struct vec3 *dst, const struct vec3 *v1, - const struct vec3 *v2) + const struct vec3 *v2) { dst->m = _mm_min_ps(v1->m, v2->m); dst->w = 0.0f; } -static inline void vec3_minf(struct vec3 *dst, const struct vec3 *v, - float f) +static inline void vec3_minf(struct vec3 *dst, const struct vec3 *v, float f) { dst->m = _mm_min_ps(v->m, _mm_set1_ps(f)); dst->w = 0.0f; } static inline void vec3_max(struct vec3 *dst, const struct vec3 *v1, - const struct vec3 *v2) + const struct vec3 *v2) { dst->m = _mm_max_ps(v1->m, v2->m); dst->w = 0.0f; } -static inline void vec3_maxf(struct vec3 *dst, const struct vec3 *v, - float f) +static inline void vec3_maxf(struct vec3 *dst, const struct vec3 *v, float f) { dst->m = _mm_max_ps(v->m, _mm_set1_ps(f)); dst->w = 0.0f; @@ -225,17 +219,17 @@ static inline void vec3_ceil(struct vec3 *dst, const struct vec3 *v) EXPORT float vec3_plane_dist(const struct vec3 *v, const struct plane *p); EXPORT void vec3_transform(struct vec3 *dst, const struct vec3 *v, - const struct matrix4 *m); + const struct matrix4 *m); EXPORT void vec3_rotate(struct vec3 *dst, const struct vec3 *v, - const struct matrix3 *m); + const struct matrix3 *m); EXPORT void vec3_transform3x4(struct vec3 *dst, const struct vec3 *v, - const struct matrix3 *m); + const struct matrix3 *m); EXPORT void vec3_mirror(struct vec3 *dst, const struct vec3 *v, - const struct plane *p); + const struct plane *p); EXPORT void vec3_mirrorv(struct vec3 *dst, const struct vec3 *v, - const struct vec3 *vec); + const struct vec3 *vec); EXPORT void vec3_rand(struct vec3 *dst, int positive_only); diff --git a/libobs/graphics/vec4.c b/libobs/graphics/vec4.c index d28aa01..3023405 100644 --- a/libobs/graphics/vec4.c +++ b/libobs/graphics/vec4.c @@ -26,7 +26,7 @@ void vec4_from_vec3(struct vec4 *dst, const struct vec3 *v) } void vec4_transform(struct vec4 *dst, const struct vec4 *v, - const struct matrix4 *m) + const struct matrix4 *m) { struct vec4 temp; struct matrix4 transpose; diff --git a/libobs/graphics/vec4.h b/libobs/graphics/vec4.h index c6c5836..61143cc 100644 --- a/libobs/graphics/vec4.h +++ b/libobs/graphics/vec4.h @@ -43,7 +43,7 @@ static inline void vec4_zero(struct vec4 *v) } static inline void vec4_set(struct vec4 *dst, float x, float y, float z, - float w) + float w) { dst->m = _mm_set_ps(w, z, y, x); } @@ -56,49 +56,45 @@ static inline void vec4_copy(struct vec4 *dst, const struct vec4 *v) EXPORT void vec4_from_vec3(struct vec4 *dst, const struct vec3 *v); static inline void vec4_add(struct vec4 *dst, const struct vec4 *v1, - const struct vec4 *v2) + const struct vec4 *v2) { dst->m = _mm_add_ps(v1->m, v2->m); } static inline void vec4_sub(struct vec4 *dst, const struct vec4 *v1, - const struct vec4 *v2) + const struct vec4 *v2) { dst->m = _mm_sub_ps(v1->m, v2->m); } static inline void vec4_mul(struct vec4 *dst, const struct vec4 *v1, - const struct vec4 *v2) + const struct vec4 *v2) { dst->m = _mm_mul_ps(v1->m, v2->m); } static inline void vec4_div(struct vec4 *dst, const struct vec4 *v1, - const struct vec4 *v2) + const struct vec4 *v2) { dst->m = _mm_div_ps(v1->m, v2->m); } -static inline void vec4_addf(struct vec4 *dst, const struct vec4 *v, - float f) +static inline void vec4_addf(struct vec4 *dst, const struct vec4 *v, float f) { dst->m = _mm_add_ps(v->m, _mm_set1_ps(f)); } -static inline void vec4_subf(struct vec4 *dst, const struct vec4 *v, - float f) +static inline void vec4_subf(struct vec4 *dst, const struct vec4 *v, float f) { dst->m = _mm_sub_ps(v->m, _mm_set1_ps(f)); } -static inline void vec4_mulf(struct vec4 *dst, const struct vec4 *v, - float f) +static inline void vec4_mulf(struct vec4 *dst, const struct vec4 *v, float f) { dst->m = _mm_mul_ps(v->m, _mm_set1_ps(f)); } -static inline void vec4_divf(struct vec4 *dst, const struct vec4 *v, - float f) +static inline void vec4_divf(struct vec4 *dst, const struct vec4 *v, float f) { dst->m = _mm_div_ps(v->m, _mm_set1_ps(f)); } @@ -139,42 +135,38 @@ static inline float vec4_dist(const struct vec4 *v1, const struct vec4 *v2) static inline void vec4_norm(struct vec4 *dst, const struct vec4 *v) { float dot_val = vec4_dot(v, v); - dst->m = (dot_val > 0.0f) ? - _mm_mul_ps(v->m, _mm_set1_ps(1.0f/sqrtf(dot_val))) : - _mm_setzero_ps(); + dst->m = (dot_val > 0.0f) + ? _mm_mul_ps(v->m, _mm_set1_ps(1.0f / sqrtf(dot_val))) + : _mm_setzero_ps(); } static inline int vec4_close(const struct vec4 *v1, const struct vec4 *v2, - float epsilon) + float epsilon) { struct vec4 test; vec4_sub(&test, v1, v2); - return test.x < epsilon && - test.y < epsilon && - test.z < epsilon && + return test.x < epsilon && test.y < epsilon && test.z < epsilon && test.w < epsilon; } static inline void vec4_min(struct vec4 *dst, const struct vec4 *v1, - const struct vec4 *v2) + const struct vec4 *v2) { dst->m = _mm_min_ps(v1->m, v2->m); } -static inline void vec4_minf(struct vec4 *dst, const struct vec4 *v, - float f) +static inline void vec4_minf(struct vec4 *dst, const struct vec4 *v, float f) { dst->m = _mm_min_ps(v->m, _mm_set1_ps(f)); } static inline void vec4_max(struct vec4 *dst, const struct vec4 *v1, - const struct vec4 *v2) + const struct vec4 *v2) { dst->m = _mm_max_ps(v1->m, v2->m); } -static inline void vec4_maxf(struct vec4 *dst, const struct vec4 *v, - float f) +static inline void vec4_maxf(struct vec4 *dst, const struct vec4 *v, float f) { dst->m = _mm_max_ps(v->m, _mm_set1_ps(f)); } @@ -206,7 +198,7 @@ static inline void vec4_ceil(struct vec4 *dst, const struct vec4 *v) static inline uint32_t vec4_to_rgba(const struct vec4 *src) { uint32_t val; - val = (uint32_t)((double)src->x * 255.0); + val = (uint32_t)((double)src->x * 255.0); val |= (uint32_t)((double)src->y * 255.0) << 8; val |= (uint32_t)((double)src->z * 255.0) << 16; val |= (uint32_t)((double)src->w * 255.0) << 24; @@ -216,7 +208,7 @@ static inline uint32_t vec4_to_rgba(const struct vec4 *src) static inline uint32_t vec4_to_bgra(const struct vec4 *src) { uint32_t val; - val = (uint32_t)((double)src->z * 255.0); + val = (uint32_t)((double)src->z * 255.0); val |= (uint32_t)((double)src->y * 255.0) << 8; val |= (uint32_t)((double)src->x * 255.0) << 16; val |= (uint32_t)((double)src->w * 255.0) << 24; @@ -225,28 +217,28 @@ static inline uint32_t vec4_to_bgra(const struct vec4 *src) static inline void vec4_from_rgba(struct vec4 *dst, uint32_t rgba) { - dst->x = (float)((double)(rgba&0xFF) * (1.0/255.0)); + dst->x = (float)((double)(rgba & 0xFF) * (1.0 / 255.0)); rgba >>= 8; - dst->y = (float)((double)(rgba&0xFF) * (1.0/255.0)); + dst->y = (float)((double)(rgba & 0xFF) * (1.0 / 255.0)); rgba >>= 8; - dst->z = (float)((double)(rgba&0xFF) * (1.0/255.0)); + dst->z = (float)((double)(rgba & 0xFF) * (1.0 / 255.0)); rgba >>= 8; - dst->w = (float)((double)(rgba&0xFF) * (1.0/255.0)); + dst->w = (float)((double)(rgba & 0xFF) * (1.0 / 255.0)); } static inline void vec4_from_bgra(struct vec4 *dst, uint32_t bgra) { - dst->z = (float)((double)(bgra&0xFF) * (1.0/255.0)); + dst->z = (float)((double)(bgra & 0xFF) * (1.0 / 255.0)); bgra >>= 8; - dst->y = (float)((double)(bgra&0xFF) * (1.0/255.0)); + dst->y = (float)((double)(bgra & 0xFF) * (1.0 / 255.0)); bgra >>= 8; - dst->x = (float)((double)(bgra&0xFF) * (1.0/255.0)); + dst->x = (float)((double)(bgra & 0xFF) * (1.0 / 255.0)); bgra >>= 8; - dst->w = (float)((double)(bgra&0xFF) * (1.0/255.0)); + dst->w = (float)((double)(bgra & 0xFF) * (1.0 / 255.0)); } EXPORT void vec4_transform(struct vec4 *dst, const struct vec4 *v, - const struct matrix4 *m); + const struct matrix4 *m); #ifdef __cplusplus } diff --git a/libobs/libobs.pc.in b/libobs/libobs.pc.in index 03fe4cd..f6c471b 100644 --- a/libobs/libobs.pc.in +++ b/libobs/libobs.pc.in @@ -1,7 +1,7 @@ -prefix=@DEST_DIR@ +prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix} -libdir=${prefix}/@OBS_LIBRARY_DESTINATION@ -includedir=${prefix}/include +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ +includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ Name: libobs Description: OBS Studio Library diff --git a/libobs/media-io/audio-io.c b/libobs/media-io/audio-io.c index f4dfdd3..83225e9 100644 --- a/libobs/media-io/audio-io.c +++ b/libobs/media-io/audio-io.c @@ -31,11 +31,14 @@ extern profiler_name_store_t *obs_get_profiler_name_store(void); /* #define DEBUG_AUDIO */ -#define nop() do {int invalid = 0;} while(0) +#define nop() \ + do { \ + int invalid = 0; \ + } while (0) struct audio_input { struct audio_convert_info conversion; - audio_resampler_t *resampler; + audio_resampler_t *resampler; audio_output_callback_t callback; void *param; @@ -52,20 +55,20 @@ struct audio_mix { }; struct audio_output { - struct audio_output_info info; - size_t block_size; - size_t channels; - size_t planes; + struct audio_output_info info; + size_t block_size; + size_t channels; + size_t planes; - pthread_t thread; - os_event_t *stop_event; + pthread_t thread; + os_event_t *stop_event; - bool initialized; + bool initialized; - audio_input_callback_t input_cb; - void *input_param; - pthread_mutex_t input_mutex; - struct audio_mix mixes[MAX_AUDIO_MIXES]; + audio_input_callback_t input_cb; + void *input_param; + pthread_mutex_t input_mutex; + struct audio_mix mixes[MAX_AUDIO_MIXES]; }; /* ------------------------------------------------------------------------- */ @@ -84,7 +87,7 @@ static inline double ts_to_frames(const audio_t *audio, uint64_t ts) static inline double positive_round(double val) { - return floor(val+0.5); + return floor(val + 0.5); } static int64_t ts_diff_frames(const audio_t *audio, uint64_t ts1, uint64_t ts2) @@ -116,33 +119,32 @@ static inline size_t min_size(size_t a, size_t b) #endif static bool resample_audio_output(struct audio_input *input, - struct audio_data *data) + struct audio_data *data) { bool success = true; if (input->resampler) { - uint8_t *output[MAX_AV_PLANES]; + uint8_t *output[MAX_AV_PLANES]; uint32_t frames; uint64_t offset; memset(output, 0, sizeof(output)); - success = audio_resampler_resample(input->resampler, - output, &frames, &offset, - (const uint8_t *const *)data->data, - data->frames); + success = audio_resampler_resample( + input->resampler, output, &frames, &offset, + (const uint8_t *const *)data->data, data->frames); for (size_t i = 0; i < MAX_AV_PLANES; i++) data->data[i] = output[i]; - data->frames = frames; + data->frames = frames; data->timestamp -= offset; } return success; } -static inline void do_audio_output(struct audio_output *audio, - size_t mix_idx, uint64_t timestamp, uint32_t frames) +static inline void do_audio_output(struct audio_output *audio, size_t mix_idx, + uint64_t timestamp, uint32_t frames) { struct audio_mix *mix = &audio->mixes[mix_idx]; struct audio_data data; @@ -150,10 +152,10 @@ static inline void do_audio_output(struct audio_output *audio, pthread_mutex_lock(&audio->input_mutex); for (size_t i = mix->inputs.num; i > 0; i--) { - struct audio_input *input = mix->inputs.array+(i-1); + struct audio_input *input = mix->inputs.array + (i - 1); for (size_t i = 0; i < audio->planes; i++) - data.data[i] = (uint8_t*)mix->buffer[i]; + data.data[i] = (uint8_t *)mix->buffer[i]; data.frames = frames; data.timestamp = timestamp; @@ -181,7 +183,7 @@ static inline void clamp_audio_output(struct audio_output *audio, size_t bytes) while (mix_data < mix_end) { float val = *mix_data; - val = (val > 1.0f) ? 1.0f : val; + val = (val > 1.0f) ? 1.0f : val; val = (val < -1.0f) ? -1.0f : val; *(mix_data++) = val; } @@ -189,8 +191,8 @@ static inline void clamp_audio_output(struct audio_output *audio, size_t bytes) } } -static void input_and_output(struct audio_output *audio, - uint64_t audio_time, uint64_t prev_time) +static void input_and_output(struct audio_output *audio, uint64_t audio_time, + uint64_t prev_time) { size_t bytes = AUDIO_OUTPUT_FRAMES * audio->block_size; struct audio_output_data data[MAX_AUDIO_MIXES]; @@ -202,7 +204,7 @@ static void input_and_output(struct audio_output *audio, #ifdef DEBUG_AUDIO blog(LOG_DEBUG, "audio_time: %llu, prev_time: %llu, bytes: %lu", - audio_time, prev_time, bytes); + audio_time, prev_time, bytes); #endif /* get mixers */ @@ -217,8 +219,9 @@ static void input_and_output(struct audio_output *audio, for (size_t mix_idx = 0; mix_idx < MAX_AUDIO_MIXES; mix_idx++) { struct audio_mix *mix = &audio->mixes[mix_idx]; - memset(mix->buffer[0], 0, AUDIO_OUTPUT_FRAMES * - MAX_AUDIO_CHANNELS * sizeof(float)); + memset(mix->buffer[0], 0, + AUDIO_OUTPUT_FRAMES * MAX_AUDIO_CHANNELS * + sizeof(float)); for (size_t i = 0; i < audio->planes; i++) data[mix_idx].data[i] = mix->buffer[i]; @@ -226,7 +229,7 @@ static void input_and_output(struct audio_output *audio, /* get new audio data */ success = audio->input_cb(audio->input_param, prev_time, audio_time, - &new_ts, active_mixes, data); + &new_ts, active_mixes, data); if (!success) return; @@ -246,15 +249,14 @@ static void *audio_thread(void *param) uint64_t start_time = os_gettime_ns(); uint64_t prev_time = start_time; uint64_t audio_time = prev_time; - uint32_t audio_wait_time = - (uint32_t)(audio_frames_to_ns(rate, AUDIO_OUTPUT_FRAMES) / - 1000000); + uint32_t audio_wait_time = (uint32_t)( + audio_frames_to_ns(rate, AUDIO_OUTPUT_FRAMES) / 1000000); os_set_thread_name("audio-io: audio thread"); const char *audio_thread_name = profile_store_name(obs_get_profiler_name_store(), - "audio_thread(%s)", audio->info.name); + "audio_thread(%s)", audio->info.name); while (os_event_try(audio->stop_event) == EAGAIN) { uint64_t cur_time; @@ -266,8 +268,8 @@ static void *audio_thread(void *param) cur_time = os_gettime_ns(); while (audio_time <= cur_time) { samples += AUDIO_OUTPUT_FRAMES; - audio_time = start_time + - audio_frames_to_ns(rate, samples); + audio_time = + start_time + audio_frames_to_ns(rate, samples); input_and_output(audio, audio_time, prev_time); prev_time = audio_time; @@ -284,12 +286,12 @@ static void *audio_thread(void *param) /* ------------------------------------------------------------------------- */ static size_t audio_get_input_idx(const audio_t *audio, size_t mix_idx, - audio_output_callback_t callback, void *param) + audio_output_callback_t callback, void *param) { const struct audio_mix *mix = &audio->mixes[mix_idx]; for (size_t i = 0; i < mix->inputs.num; i++) { - struct audio_input *input = mix->inputs.array+i; + struct audio_input *input = mix->inputs.array + i; if (input->callback == callback && input->param == param) return i; @@ -299,27 +301,25 @@ static size_t audio_get_input_idx(const audio_t *audio, size_t mix_idx, } static inline bool audio_input_init(struct audio_input *input, - struct audio_output *audio) + struct audio_output *audio) { - if (input->conversion.format != audio->info.format || + if (input->conversion.format != audio->info.format || input->conversion.samples_per_sec != audio->info.samples_per_sec || - input->conversion.speakers != audio->info.speakers) { + input->conversion.speakers != audio->info.speakers) { struct resample_info from = { - .format = audio->info.format, + .format = audio->info.format, .samples_per_sec = audio->info.samples_per_sec, - .speakers = audio->info.speakers - }; + .speakers = audio->info.speakers}; struct resample_info to = { - .format = input->conversion.format, + .format = input->conversion.format, .samples_per_sec = input->conversion.samples_per_sec, - .speakers = input->conversion.speakers - }; + .speakers = input->conversion.speakers}; input->resampler = audio_resampler_create(&to, &from); if (!input->resampler) { blog(LOG_ERROR, "audio_input_init: Failed to " - "create resampler"); + "create resampler"); return false; } } else { @@ -330,12 +330,13 @@ static inline bool audio_input_init(struct audio_input *input, } bool audio_output_connect(audio_t *audio, size_t mi, - const struct audio_convert_info *conversion, - audio_output_callback_t callback, void *param) + const struct audio_convert_info *conversion, + audio_output_callback_t callback, void *param) { bool success = false; - if (!audio || mi >= MAX_AUDIO_MIXES) return false; + if (!audio || mi >= MAX_AUDIO_MIXES) + return false; pthread_mutex_lock(&audio->input_mutex); @@ -343,7 +344,7 @@ bool audio_output_connect(audio_t *audio, size_t mi, struct audio_mix *mix = &audio->mixes[mi]; struct audio_input input; input.callback = callback; - input.param = param; + input.param = param; if (conversion) { input.conversion = *conversion; @@ -373,16 +374,17 @@ bool audio_output_connect(audio_t *audio, size_t mi, } void audio_output_disconnect(audio_t *audio, size_t mix_idx, - audio_output_callback_t callback, void *param) + audio_output_callback_t callback, void *param) { - if (!audio || mix_idx >= MAX_AUDIO_MIXES) return; + if (!audio || mix_idx >= MAX_AUDIO_MIXES) + return; pthread_mutex_lock(&audio->input_mutex); size_t idx = audio_get_input_idx(audio, mix_idx, callback, param); if (idx != DARRAY_INVALID) { struct audio_mix *mix = &audio->mixes[mix_idx]; - audio_input_free(mix->inputs.array+idx); + audio_input_free(mix->inputs.array + idx); da_erase(mix->inputs, idx); } @@ -409,12 +411,12 @@ int audio_output_open(audio_t **audio, struct audio_output_info *info) goto fail; memcpy(&out->info, info, sizeof(struct audio_output_info)); - out->channels = get_audio_channels(info->speakers); - out->planes = planar ? out->channels : 1; - out->input_cb = info->input_callback; - out->input_param= info->input_param; + out->channels = get_audio_channels(info->speakers); + out->planes = planar ? out->channels : 1; + out->input_cb = info->input_callback; + out->input_param = info->input_param; out->block_size = (planar ? 1 : out->channels) * - get_audio_bytes_per_channel(info->format); + get_audio_bytes_per_channel(info->format); if (pthread_mutexattr_init(&attr) != 0) goto fail; @@ -452,7 +454,7 @@ void audio_output_close(audio_t *audio) struct audio_mix *mix = &audio->mixes[mix_idx]; for (size_t i = 0; i < mix->inputs.num; i++) - audio_input_free(mix->inputs.array+i); + audio_input_free(mix->inputs.array + i); da_free(mix->inputs); } @@ -468,7 +470,8 @@ const struct audio_output_info *audio_output_get_info(const audio_t *audio) bool audio_output_active(const audio_t *audio) { - if (!audio) return false; + if (!audio) + return false; for (size_t mix_idx = 0; mix_idx < MAX_AUDIO_MIXES; mix_idx++) { const struct audio_mix *mix = &audio->mixes[mix_idx]; diff --git a/libobs/media-io/audio-io.h b/libobs/media-io/audio-io.h index 9b4b636..f5dec6d 100644 --- a/libobs/media-io/audio-io.h +++ b/libobs/media-io/audio-io.h @@ -25,13 +25,13 @@ extern "C" { #endif -#define MAX_AUDIO_MIXES 6 -#define MAX_AUDIO_CHANNELS 8 +#define MAX_AUDIO_MIXES 6 +#define MAX_AUDIO_CHANNELS 8 #define AUDIO_OUTPUT_FRAMES 1024 -#define TOTAL_AUDIO_SIZE \ - (MAX_AUDIO_MIXES * MAX_AUDIO_CHANNELS * \ - AUDIO_OUTPUT_FRAMES * sizeof(float)) +#define TOTAL_AUDIO_SIZE \ + (MAX_AUDIO_MIXES * MAX_AUDIO_CHANNELS * AUDIO_OUTPUT_FRAMES * \ + sizeof(float)) /* * Base audio output component. Use this to create an audio output track @@ -65,58 +65,67 @@ enum audio_format { * https://trac.ffmpeg.org/wiki/AudioChannelManipulation */ enum speaker_layout { - SPEAKERS_UNKNOWN, /**< Unknown setting, fallback is stereo. */ - SPEAKERS_MONO, /**< Channels: MONO */ - SPEAKERS_STEREO, /**< Channels: FL, FR */ - SPEAKERS_2POINT1, /**< Channels: FL, FR, LFE */ - SPEAKERS_4POINT0, /**< Channels: FL, FR, FC, RC */ - SPEAKERS_4POINT1, /**< Channels: FL, FR, FC, LFE, RC */ - SPEAKERS_5POINT1, /**< Channels: FL, FR, FC, LFE, RL, RR */ - SPEAKERS_7POINT1=8, /**< Channels: FL, FR, FC, LFE, RL, RR, SL, SR */ + SPEAKERS_UNKNOWN, /**< Unknown setting, fallback is stereo. */ + SPEAKERS_MONO, /**< Channels: MONO */ + SPEAKERS_STEREO, /**< Channels: FL, FR */ + SPEAKERS_2POINT1, /**< Channels: FL, FR, LFE */ + SPEAKERS_4POINT0, /**< Channels: FL, FR, FC, RC */ + SPEAKERS_4POINT1, /**< Channels: FL, FR, FC, LFE, RC */ + SPEAKERS_5POINT1, /**< Channels: FL, FR, FC, LFE, RL, RR */ + SPEAKERS_7POINT1 = 8, /**< Channels: FL, FR, FC, LFE, RL, RR, SL, SR */ }; struct audio_data { - uint8_t *data[MAX_AV_PLANES]; - uint32_t frames; - uint64_t timestamp; + uint8_t *data[MAX_AV_PLANES]; + uint32_t frames; + uint64_t timestamp; }; struct audio_output_data { - float *data[MAX_AUDIO_CHANNELS]; + float *data[MAX_AUDIO_CHANNELS]; }; -typedef bool (*audio_input_callback_t)(void *param, - uint64_t start_ts, uint64_t end_ts, uint64_t *new_ts, - uint32_t active_mixers, struct audio_output_data *mixes); +typedef bool (*audio_input_callback_t)(void *param, uint64_t start_ts, + uint64_t end_ts, uint64_t *new_ts, + uint32_t active_mixers, + struct audio_output_data *mixes); struct audio_output_info { - const char *name; + const char *name; - uint32_t samples_per_sec; - enum audio_format format; + uint32_t samples_per_sec; + enum audio_format format; enum speaker_layout speakers; audio_input_callback_t input_callback; - void *input_param; + void *input_param; }; struct audio_convert_info { - uint32_t samples_per_sec; - enum audio_format format; + uint32_t samples_per_sec; + enum audio_format format; enum speaker_layout speakers; }; static inline uint32_t get_audio_channels(enum speaker_layout speakers) { switch (speakers) { - case SPEAKERS_MONO: return 1; - case SPEAKERS_STEREO: return 2; - case SPEAKERS_2POINT1: return 3; - case SPEAKERS_4POINT0: return 4; - case SPEAKERS_4POINT1: return 5; - case SPEAKERS_5POINT1: return 6; - case SPEAKERS_7POINT1: return 8; - case SPEAKERS_UNKNOWN: return 0; + case SPEAKERS_MONO: + return 1; + case SPEAKERS_STEREO: + return 2; + case SPEAKERS_2POINT1: + return 3; + case SPEAKERS_4POINT0: + return 4; + case SPEAKERS_4POINT1: + return 5; + case SPEAKERS_5POINT1: + return 6; + case SPEAKERS_7POINT1: + return 8; + case SPEAKERS_UNKNOWN: + return 0; } return 0; @@ -169,23 +178,22 @@ static inline bool is_audio_planar(enum audio_format format) } static inline size_t get_audio_planes(enum audio_format format, - enum speaker_layout speakers) + enum speaker_layout speakers) { return (is_audio_planar(format) ? get_audio_channels(speakers) : 1); } static inline size_t get_audio_size(enum audio_format format, - enum speaker_layout speakers, uint32_t frames) + enum speaker_layout speakers, + uint32_t frames) { bool planar = is_audio_planar(format); return (planar ? 1 : get_audio_channels(speakers)) * - get_audio_bytes_per_channel(format) * - frames; + get_audio_bytes_per_channel(format) * frames; } -static inline uint64_t audio_frames_to_ns(size_t sample_rate, - uint64_t frames) +static inline uint64_t audio_frames_to_ns(size_t sample_rate, uint64_t frames) { util_uint128_t val; val = util_mul64_64(frames, 1000000000ULL); @@ -193,8 +201,7 @@ static inline uint64_t audio_frames_to_ns(size_t sample_rate, return val.low; } -static inline uint64_t ns_to_audio_frames(size_t sample_rate, - uint64_t frames) +static inline uint64_t ns_to_audio_frames(size_t sample_rate, uint64_t frames) { util_uint128_t val; val = util_mul64_64(frames, sample_rate); @@ -202,21 +209,22 @@ static inline uint64_t ns_to_audio_frames(size_t sample_rate, return val.low; } -#define AUDIO_OUTPUT_SUCCESS 0 +#define AUDIO_OUTPUT_SUCCESS 0 #define AUDIO_OUTPUT_INVALIDPARAM -1 -#define AUDIO_OUTPUT_FAIL -2 +#define AUDIO_OUTPUT_FAIL -2 EXPORT int audio_output_open(audio_t **audio, struct audio_output_info *info); EXPORT void audio_output_close(audio_t *audio); typedef void (*audio_output_callback_t)(void *param, size_t mix_idx, - struct audio_data *data); + struct audio_data *data); EXPORT bool audio_output_connect(audio_t *video, size_t mix_idx, - const struct audio_convert_info *conversion, - audio_output_callback_t callback, void *param); + const struct audio_convert_info *conversion, + audio_output_callback_t callback, void *param); EXPORT void audio_output_disconnect(audio_t *video, size_t mix_idx, - audio_output_callback_t callback, void *param); + audio_output_callback_t callback, + void *param); EXPORT bool audio_output_active(const audio_t *audio); @@ -224,9 +232,8 @@ EXPORT size_t audio_output_get_block_size(const audio_t *audio); EXPORT size_t audio_output_get_planes(const audio_t *audio); EXPORT size_t audio_output_get_channels(const audio_t *audio); EXPORT uint32_t audio_output_get_sample_rate(const audio_t *audio); -EXPORT const struct audio_output_info *audio_output_get_info( - const audio_t *audio); - +EXPORT const struct audio_output_info * +audio_output_get_info(const audio_t *audio); #ifdef __cplusplus } diff --git a/libobs/media-io/audio-resampler-ffmpeg.c b/libobs/media-io/audio-resampler-ffmpeg.c index e731e7e..c4801d3 100644 --- a/libobs/media-io/audio-resampler-ffmpeg.c +++ b/libobs/media-io/audio-resampler-ffmpeg.c @@ -23,34 +23,43 @@ #include struct audio_resampler { - struct SwrContext *context; - bool opened; + struct SwrContext *context; + bool opened; - uint32_t input_freq; - uint64_t input_layout; + uint32_t input_freq; + uint64_t input_layout; enum AVSampleFormat input_format; - uint8_t *output_buffer[MAX_AV_PLANES]; - uint64_t output_layout; + uint8_t *output_buffer[MAX_AV_PLANES]; + uint64_t output_layout; enum AVSampleFormat output_format; - int output_size; - uint32_t output_ch; - uint32_t output_freq; - uint32_t output_planes; + int output_size; + uint32_t output_ch; + uint32_t output_freq; + uint32_t output_planes; }; static inline enum AVSampleFormat convert_audio_format(enum audio_format format) { switch (format) { - case AUDIO_FORMAT_UNKNOWN: return AV_SAMPLE_FMT_S16; - case AUDIO_FORMAT_U8BIT: return AV_SAMPLE_FMT_U8; - case AUDIO_FORMAT_16BIT: return AV_SAMPLE_FMT_S16; - case AUDIO_FORMAT_32BIT: return AV_SAMPLE_FMT_S32; - case AUDIO_FORMAT_FLOAT: return AV_SAMPLE_FMT_FLT; - case AUDIO_FORMAT_U8BIT_PLANAR: return AV_SAMPLE_FMT_U8P; - case AUDIO_FORMAT_16BIT_PLANAR: return AV_SAMPLE_FMT_S16P; - case AUDIO_FORMAT_32BIT_PLANAR: return AV_SAMPLE_FMT_S32P; - case AUDIO_FORMAT_FLOAT_PLANAR: return AV_SAMPLE_FMT_FLTP; + case AUDIO_FORMAT_UNKNOWN: + return AV_SAMPLE_FMT_S16; + case AUDIO_FORMAT_U8BIT: + return AV_SAMPLE_FMT_U8; + case AUDIO_FORMAT_16BIT: + return AV_SAMPLE_FMT_S16; + case AUDIO_FORMAT_32BIT: + return AV_SAMPLE_FMT_S32; + case AUDIO_FORMAT_FLOAT: + return AV_SAMPLE_FMT_FLT; + case AUDIO_FORMAT_U8BIT_PLANAR: + return AV_SAMPLE_FMT_U8P; + case AUDIO_FORMAT_16BIT_PLANAR: + return AV_SAMPLE_FMT_S16P; + case AUDIO_FORMAT_32BIT_PLANAR: + return AV_SAMPLE_FMT_S32P; + case AUDIO_FORMAT_FLOAT_PLANAR: + return AV_SAMPLE_FMT_FLTP; } /* shouldn't get here */ @@ -60,14 +69,22 @@ static inline enum AVSampleFormat convert_audio_format(enum audio_format format) static inline uint64_t convert_speaker_layout(enum speaker_layout layout) { switch (layout) { - case SPEAKERS_UNKNOWN: return 0; - case SPEAKERS_MONO: return AV_CH_LAYOUT_MONO; - case SPEAKERS_STEREO: return AV_CH_LAYOUT_STEREO; - case SPEAKERS_2POINT1: return AV_CH_LAYOUT_SURROUND; - case SPEAKERS_4POINT0: return AV_CH_LAYOUT_4POINT0; - case SPEAKERS_4POINT1: return AV_CH_LAYOUT_4POINT1; - case SPEAKERS_5POINT1: return AV_CH_LAYOUT_5POINT1_BACK; - case SPEAKERS_7POINT1: return AV_CH_LAYOUT_7POINT1; + case SPEAKERS_UNKNOWN: + return 0; + case SPEAKERS_MONO: + return AV_CH_LAYOUT_MONO; + case SPEAKERS_STEREO: + return AV_CH_LAYOUT_STEREO; + case SPEAKERS_2POINT1: + return AV_CH_LAYOUT_SURROUND; + case SPEAKERS_4POINT0: + return AV_CH_LAYOUT_4POINT0; + case SPEAKERS_4POINT1: + return AV_CH_LAYOUT_4POINT1; + case SPEAKERS_5POINT1: + return AV_CH_LAYOUT_5POINT1_BACK; + case SPEAKERS_7POINT1: + return AV_CH_LAYOUT_7POINT1; } /* shouldn't get here */ @@ -75,26 +92,27 @@ static inline uint64_t convert_speaker_layout(enum speaker_layout layout) } audio_resampler_t *audio_resampler_create(const struct resample_info *dst, - const struct resample_info *src) + const struct resample_info *src) { struct audio_resampler *rs = bzalloc(sizeof(struct audio_resampler)); int errcode; - rs->opened = false; - rs->input_freq = src->samples_per_sec; - rs->input_layout = convert_speaker_layout(src->speakers); - rs->input_format = convert_audio_format(src->format); - rs->output_size = 0; - rs->output_ch = get_audio_channels(dst->speakers); - rs->output_freq = dst->samples_per_sec; + rs->opened = false; + rs->input_freq = src->samples_per_sec; + rs->input_layout = convert_speaker_layout(src->speakers); + rs->input_format = convert_audio_format(src->format); + rs->output_size = 0; + rs->output_ch = get_audio_channels(dst->speakers); + rs->output_freq = dst->samples_per_sec; rs->output_layout = convert_speaker_layout(dst->speakers); rs->output_format = convert_audio_format(dst->format); rs->output_planes = is_audio_planar(dst->format) ? rs->output_ch : 1; - rs->context = swr_alloc_set_opts(NULL, - rs->output_layout, rs->output_format, dst->samples_per_sec, - rs->input_layout, rs->input_format, src->samples_per_sec, - 0, NULL); + rs->context = swr_alloc_set_opts(NULL, rs->output_layout, + rs->output_format, + dst->samples_per_sec, rs->input_layout, + rs->input_format, src->samples_per_sec, + 0, NULL); if (!rs->context) { blog(LOG_ERROR, "swr_alloc_set_opts failed"); @@ -104,23 +122,25 @@ audio_resampler_t *audio_resampler_create(const struct resample_info *dst, if (rs->input_layout == AV_CH_LAYOUT_MONO && rs->output_ch > 1) { const double matrix[MAX_AUDIO_CHANNELS][MAX_AUDIO_CHANNELS] = { - {1}, - {1, 1}, - {1, 1, 0}, - {1, 1, 1, 1}, - {1, 1, 1, 0, 1}, - {1, 1, 1, 1, 1, 1}, - {1, 1, 1, 0, 1, 1, 1}, - {1, 1, 1, 0, 1, 1, 1, 1}, + {1}, + {1, 1}, + {1, 1, 0}, + {1, 1, 1, 1}, + {1, 1, 1, 0, 1}, + {1, 1, 1, 1, 1, 1}, + {1, 1, 1, 0, 1, 1, 1}, + {1, 1, 1, 0, 1, 1, 1, 1}, }; - if (swr_set_matrix(rs->context, matrix[rs->output_ch - 1], 1) < 0) - blog(LOG_DEBUG, "swr_set_matrix failed for mono upmix\n"); + if (swr_set_matrix(rs->context, matrix[rs->output_ch - 1], 1) < + 0) + blog(LOG_DEBUG, + "swr_set_matrix failed for mono upmix\n"); } errcode = swr_init(rs->context); if (errcode != 0) { blog(LOG_ERROR, "avresample_open failed: error code %d", - errcode); + errcode); audio_resampler_destroy(rs); return NULL; } @@ -140,20 +160,21 @@ void audio_resampler_destroy(audio_resampler_t *rs) } } -bool audio_resampler_resample(audio_resampler_t *rs, - uint8_t *output[], uint32_t *out_frames, uint64_t *ts_offset, - const uint8_t *const input[], uint32_t in_frames) +bool audio_resampler_resample(audio_resampler_t *rs, uint8_t *output[], + uint32_t *out_frames, uint64_t *ts_offset, + const uint8_t *const input[], uint32_t in_frames) { - if (!rs) return false; + if (!rs) + return false; struct SwrContext *context = rs->context; int ret; int64_t delay = swr_get_delay(context, rs->input_freq); - int estimated = (int)av_rescale_rnd( - delay + (int64_t)in_frames, - (int64_t)rs->output_freq, (int64_t)rs->input_freq, - AV_ROUND_UP); + int estimated = (int)av_rescale_rnd(delay + (int64_t)in_frames, + (int64_t)rs->output_freq, + (int64_t)rs->input_freq, + AV_ROUND_UP); *ts_offset = (uint64_t)swr_get_delay(context, 1000000000); @@ -163,14 +184,13 @@ bool audio_resampler_resample(audio_resampler_t *rs, av_freep(&rs->output_buffer[0]); av_samples_alloc(rs->output_buffer, NULL, rs->output_ch, - estimated, rs->output_format, 0); + estimated, rs->output_format, 0); rs->output_size = estimated; } - ret = swr_convert(context, - rs->output_buffer, rs->output_size, - (const uint8_t**)input, in_frames); + ret = swr_convert(context, rs->output_buffer, rs->output_size, + (const uint8_t **)input, in_frames); if (ret < 0) { blog(LOG_ERROR, "swr_convert failed: %d", ret); diff --git a/libobs/media-io/audio-resampler.h b/libobs/media-io/audio-resampler.h index be57528..7cca54d 100644 --- a/libobs/media-io/audio-resampler.h +++ b/libobs/media-io/audio-resampler.h @@ -28,18 +28,21 @@ struct audio_resampler; typedef struct audio_resampler audio_resampler_t; struct resample_info { - uint32_t samples_per_sec; - enum audio_format format; + uint32_t samples_per_sec; + enum audio_format format; enum speaker_layout speakers; }; -EXPORT audio_resampler_t *audio_resampler_create(const struct resample_info *dst, - const struct resample_info *src); +EXPORT audio_resampler_t * +audio_resampler_create(const struct resample_info *dst, + const struct resample_info *src); EXPORT void audio_resampler_destroy(audio_resampler_t *resampler); EXPORT bool audio_resampler_resample(audio_resampler_t *resampler, - uint8_t *output[], uint32_t *out_frames, uint64_t *ts_offset, - const uint8_t *const input[], uint32_t in_frames); + uint8_t *output[], uint32_t *out_frames, + uint64_t *ts_offset, + const uint8_t *const input[], + uint32_t in_frames); #ifdef __cplusplus } diff --git a/libobs/media-io/format-conversion.c b/libobs/media-io/format-conversion.c index 1c6d341..f054064 100644 --- a/libobs/media-io/format-conversion.c +++ b/libobs/media-io/format-conversion.c @@ -22,194 +22,191 @@ /* ...surprisingly, if I don't use a macro to force inlining, it causes the * CPU usage to boost by a tremendous amount in debug builds. */ -#define get_m128_32_0(val) (*((uint32_t*)&val)) -#define get_m128_32_1(val) (*(((uint32_t*)&val)+1)) +#define get_m128_32_0(val) (*((uint32_t *)&val)) +#define get_m128_32_1(val) (*(((uint32_t *)&val) + 1)) -#define pack_shift(lum_plane, lum_pos0, lum_pos1, line1, line2, mask, sh) \ -do { \ - __m128i pack_val = _mm_packs_epi32( \ - _mm_srli_si128(_mm_and_si128(line1, mask), sh), \ - _mm_srli_si128(_mm_and_si128(line2, mask), sh)); \ - pack_val = _mm_packus_epi16(pack_val, pack_val); \ - \ - *(uint32_t*)(lum_plane+lum_pos0) = get_m128_32_0(pack_val); \ - *(uint32_t*)(lum_plane+lum_pos1) = get_m128_32_1(pack_val); \ -} while (false) +#define pack_shift(lum_plane, lum_pos0, lum_pos1, line1, line2, mask, sh) \ + do { \ + __m128i pack_val = _mm_packs_epi32( \ + _mm_srli_si128(_mm_and_si128(line1, mask), sh), \ + _mm_srli_si128(_mm_and_si128(line2, mask), sh)); \ + pack_val = _mm_packus_epi16(pack_val, pack_val); \ + \ + *(uint32_t *)(lum_plane + lum_pos0) = get_m128_32_0(pack_val); \ + *(uint32_t *)(lum_plane + lum_pos1) = get_m128_32_1(pack_val); \ + } while (false) -#define pack_val(lum_plane, lum_pos0, lum_pos1, line1, line2, mask) \ -do { \ - __m128i pack_val = _mm_packs_epi32( \ - _mm_and_si128(line1, mask), \ - _mm_and_si128(line2, mask)); \ - pack_val = _mm_packus_epi16(pack_val, pack_val); \ - \ - *(uint32_t*)(lum_plane+lum_pos0) = get_m128_32_0(pack_val); \ - *(uint32_t*)(lum_plane+lum_pos1) = get_m128_32_1(pack_val); \ -} while (false) +#define pack_val(lum_plane, lum_pos0, lum_pos1, line1, line2, mask) \ + do { \ + __m128i pack_val = \ + _mm_packs_epi32(_mm_and_si128(line1, mask), \ + _mm_and_si128(line2, mask)); \ + pack_val = _mm_packus_epi16(pack_val, pack_val); \ + \ + *(uint32_t *)(lum_plane + lum_pos0) = get_m128_32_0(pack_val); \ + *(uint32_t *)(lum_plane + lum_pos1) = get_m128_32_1(pack_val); \ + } while (false) -#define pack_ch_1plane(uv_plane, chroma_pos, line1, line2, uv_mask) \ -do { \ - __m128i add_val = _mm_add_epi64( \ - _mm_and_si128(line1, uv_mask), \ - _mm_and_si128(line2, uv_mask)); \ - __m128i avg_val = _mm_add_epi64( \ - add_val, \ - _mm_shuffle_epi32(add_val, _MM_SHUFFLE(2, 3, 0, 1))); \ - avg_val = _mm_srai_epi16(avg_val, 2); \ - avg_val = _mm_shuffle_epi32(avg_val, _MM_SHUFFLE(3, 1, 2, 0)); \ - avg_val = _mm_packus_epi16(avg_val, avg_val); \ - \ - *(uint32_t*)(uv_plane+chroma_pos) = get_m128_32_0(avg_val); \ -} while (false) - -#define pack_ch_2plane(u_plane, v_plane, chroma_pos, line1, line2, uv_mask) \ -do { \ - uint32_t packed_vals; \ - \ - __m128i add_val = _mm_add_epi64( \ - _mm_and_si128(line1, uv_mask), \ - _mm_and_si128(line2, uv_mask)); \ - __m128i avg_val = _mm_add_epi64( \ - add_val, \ - _mm_shuffle_epi32(add_val, _MM_SHUFFLE(2, 3, 0, 1))); \ - avg_val = _mm_srai_epi16(avg_val, 2); \ - avg_val = _mm_shuffle_epi32(avg_val, _MM_SHUFFLE(3, 1, 2, 0)); \ - avg_val = _mm_shufflelo_epi16(avg_val, _MM_SHUFFLE(3, 1, 2, 0)); \ - avg_val = _mm_packus_epi16(avg_val, avg_val); \ - \ - packed_vals = get_m128_32_0(avg_val); \ - \ - *(uint16_t*)(u_plane+chroma_pos) = (uint16_t)(packed_vals); \ - *(uint16_t*)(v_plane+chroma_pos) = (uint16_t)(packed_vals>>16); \ -} while (false) +#define pack_ch_1plane(uv_plane, chroma_pos, line1, line2, uv_mask) \ + do { \ + __m128i add_val = \ + _mm_add_epi64(_mm_and_si128(line1, uv_mask), \ + _mm_and_si128(line2, uv_mask)); \ + __m128i avg_val = _mm_add_epi64( \ + add_val, \ + _mm_shuffle_epi32(add_val, _MM_SHUFFLE(2, 3, 0, 1))); \ + avg_val = _mm_srai_epi16(avg_val, 2); \ + avg_val = _mm_shuffle_epi32(avg_val, _MM_SHUFFLE(3, 1, 2, 0)); \ + avg_val = _mm_packus_epi16(avg_val, avg_val); \ + \ + *(uint32_t *)(uv_plane + chroma_pos) = get_m128_32_0(avg_val); \ + } while (false) +#define pack_ch_2plane(u_plane, v_plane, chroma_pos, line1, line2, uv_mask) \ + do { \ + uint32_t packed_vals; \ + \ + __m128i add_val = \ + _mm_add_epi64(_mm_and_si128(line1, uv_mask), \ + _mm_and_si128(line2, uv_mask)); \ + __m128i avg_val = _mm_add_epi64( \ + add_val, \ + _mm_shuffle_epi32(add_val, _MM_SHUFFLE(2, 3, 0, 1))); \ + avg_val = _mm_srai_epi16(avg_val, 2); \ + avg_val = _mm_shuffle_epi32(avg_val, _MM_SHUFFLE(3, 1, 2, 0)); \ + avg_val = \ + _mm_shufflelo_epi16(avg_val, _MM_SHUFFLE(3, 1, 2, 0)); \ + avg_val = _mm_packus_epi16(avg_val, avg_val); \ + \ + packed_vals = get_m128_32_0(avg_val); \ + \ + *(uint16_t *)(u_plane + chroma_pos) = (uint16_t)(packed_vals); \ + *(uint16_t *)(v_plane + chroma_pos) = \ + (uint16_t)(packed_vals >> 16); \ + } while (false) static FORCE_INLINE uint32_t min_uint32(uint32_t a, uint32_t b) { return a < b ? a : b; } -void compress_uyvx_to_i420( - const uint8_t *input, uint32_t in_linesize, - uint32_t start_y, uint32_t end_y, - uint8_t *output[], const uint32_t out_linesize[]) +void compress_uyvx_to_i420(const uint8_t *input, uint32_t in_linesize, + uint32_t start_y, uint32_t end_y, uint8_t *output[], + const uint32_t out_linesize[]) { - uint8_t *lum_plane = output[0]; - uint8_t *u_plane = output[1]; - uint8_t *v_plane = output[2]; - uint32_t width = min_uint32(in_linesize, out_linesize[0]); + uint8_t *lum_plane = output[0]; + uint8_t *u_plane = output[1]; + uint8_t *v_plane = output[2]; + uint32_t width = min_uint32(in_linesize, out_linesize[0]); uint32_t y; __m128i lum_mask = _mm_set1_epi32(0x0000FF00); - __m128i uv_mask = _mm_set1_epi16(0x00FF); + __m128i uv_mask = _mm_set1_epi16(0x00FF); for (y = start_y; y < end_y; y += 2) { - uint32_t y_pos = y * in_linesize; - uint32_t chroma_y_pos = (y>>1) * out_linesize[1]; - uint32_t lum_y_pos = y * out_linesize[0]; + uint32_t y_pos = y * in_linesize; + uint32_t chroma_y_pos = (y >> 1) * out_linesize[1]; + uint32_t lum_y_pos = y * out_linesize[0]; uint32_t x; for (x = 0; x < width; x += 4) { - const uint8_t *img = input + y_pos + x*4; - uint32_t lum_pos0 = lum_y_pos + x; - uint32_t lum_pos1 = lum_pos0 + out_linesize[0]; + const uint8_t *img = input + y_pos + x * 4; + uint32_t lum_pos0 = lum_y_pos + x; + uint32_t lum_pos1 = lum_pos0 + out_linesize[0]; - __m128i line1 = _mm_load_si128((const __m128i*)img); + __m128i line1 = _mm_load_si128((const __m128i *)img); __m128i line2 = _mm_load_si128( - (const __m128i*)(img + in_linesize)); + (const __m128i *)(img + in_linesize)); - pack_shift(lum_plane, lum_pos0, lum_pos1, - line1, line2, lum_mask, 1); + pack_shift(lum_plane, lum_pos0, lum_pos1, line1, line2, + lum_mask, 1); pack_ch_2plane(u_plane, v_plane, - chroma_y_pos + (x>>1), - line1, line2, uv_mask); + chroma_y_pos + (x >> 1), line1, line2, + uv_mask); } } } -void compress_uyvx_to_nv12( - const uint8_t *input, uint32_t in_linesize, - uint32_t start_y, uint32_t end_y, - uint8_t *output[], const uint32_t out_linesize[]) +void compress_uyvx_to_nv12(const uint8_t *input, uint32_t in_linesize, + uint32_t start_y, uint32_t end_y, uint8_t *output[], + const uint32_t out_linesize[]) { - uint8_t *lum_plane = output[0]; + uint8_t *lum_plane = output[0]; uint8_t *chroma_plane = output[1]; - uint32_t width = min_uint32(in_linesize, out_linesize[0]); + uint32_t width = min_uint32(in_linesize, out_linesize[0]); uint32_t y; __m128i lum_mask = _mm_set1_epi32(0x0000FF00); - __m128i uv_mask = _mm_set1_epi16(0x00FF); + __m128i uv_mask = _mm_set1_epi16(0x00FF); for (y = start_y; y < end_y; y += 2) { - uint32_t y_pos = y * in_linesize; - uint32_t chroma_y_pos = (y>>1) * out_linesize[1]; - uint32_t lum_y_pos = y * out_linesize[0]; + uint32_t y_pos = y * in_linesize; + uint32_t chroma_y_pos = (y >> 1) * out_linesize[1]; + uint32_t lum_y_pos = y * out_linesize[0]; uint32_t x; for (x = 0; x < width; x += 4) { - const uint8_t *img = input + y_pos + x*4; - uint32_t lum_pos0 = lum_y_pos + x; - uint32_t lum_pos1 = lum_pos0 + out_linesize[0]; + const uint8_t *img = input + y_pos + x * 4; + uint32_t lum_pos0 = lum_y_pos + x; + uint32_t lum_pos1 = lum_pos0 + out_linesize[0]; - __m128i line1 = _mm_load_si128((const __m128i*)img); + __m128i line1 = _mm_load_si128((const __m128i *)img); __m128i line2 = _mm_load_si128( - (const __m128i*)(img + in_linesize)); + (const __m128i *)(img + in_linesize)); - pack_shift(lum_plane, lum_pos0, lum_pos1, - line1, line2, lum_mask, 1); - pack_ch_1plane(chroma_plane, chroma_y_pos + x, - line1, line2, uv_mask); + pack_shift(lum_plane, lum_pos0, lum_pos1, line1, line2, + lum_mask, 1); + pack_ch_1plane(chroma_plane, chroma_y_pos + x, line1, + line2, uv_mask); } } } -void convert_uyvx_to_i444( - const uint8_t *input, uint32_t in_linesize, - uint32_t start_y, uint32_t end_y, - uint8_t *output[], const uint32_t out_linesize[]) +void convert_uyvx_to_i444(const uint8_t *input, uint32_t in_linesize, + uint32_t start_y, uint32_t end_y, uint8_t *output[], + const uint32_t out_linesize[]) { - uint8_t *lum_plane = output[0]; - uint8_t *u_plane = output[1]; - uint8_t *v_plane = output[2]; - uint32_t width = min_uint32(in_linesize, out_linesize[0]); + uint8_t *lum_plane = output[0]; + uint8_t *u_plane = output[1]; + uint8_t *v_plane = output[2]; + uint32_t width = min_uint32(in_linesize, out_linesize[0]); uint32_t y; __m128i lum_mask = _mm_set1_epi32(0x0000FF00); - __m128i u_mask = _mm_set1_epi32(0x000000FF); - __m128i v_mask = _mm_set1_epi32(0x00FF0000); + __m128i u_mask = _mm_set1_epi32(0x000000FF); + __m128i v_mask = _mm_set1_epi32(0x00FF0000); for (y = start_y; y < end_y; y += 2) { - uint32_t y_pos = y * in_linesize; - uint32_t lum_y_pos = y * out_linesize[0]; + uint32_t y_pos = y * in_linesize; + uint32_t lum_y_pos = y * out_linesize[0]; uint32_t x; for (x = 0; x < width; x += 4) { - const uint8_t *img = input + y_pos + x*4; - uint32_t lum_pos0 = lum_y_pos + x; - uint32_t lum_pos1 = lum_pos0 + out_linesize[0]; + const uint8_t *img = input + y_pos + x * 4; + uint32_t lum_pos0 = lum_y_pos + x; + uint32_t lum_pos1 = lum_pos0 + out_linesize[0]; - __m128i line1 = _mm_load_si128((const __m128i*)img); + __m128i line1 = _mm_load_si128((const __m128i *)img); __m128i line2 = _mm_load_si128( - (const __m128i*)(img + in_linesize)); + (const __m128i *)(img + in_linesize)); - pack_shift(lum_plane, lum_pos0, lum_pos1, - line1, line2, lum_mask, 1); - pack_val(u_plane, lum_pos0, lum_pos1, - line1, line2, u_mask); - pack_shift(v_plane, lum_pos0, lum_pos1, - line1, line2, v_mask, 2); + pack_shift(lum_plane, lum_pos0, lum_pos1, line1, line2, + lum_mask, 1); + pack_val(u_plane, lum_pos0, lum_pos1, line1, line2, + u_mask); + pack_shift(v_plane, lum_pos0, lum_pos1, line1, line2, + v_mask, 2); } } } -void decompress_420( - const uint8_t *const input[], const uint32_t in_linesize[], - uint32_t start_y, uint32_t end_y, - uint8_t *output, uint32_t out_linesize) +void decompress_420(const uint8_t *const input[], const uint32_t in_linesize[], + uint32_t start_y, uint32_t end_y, uint8_t *output, + uint32_t out_linesize) { - uint32_t start_y_d2 = start_y/2; - uint32_t width_d2 = in_linesize[0]/2; - uint32_t height_d2 = end_y/2; + uint32_t start_y_d2 = start_y / 2; + uint32_t width_d2 = in_linesize[0] / 2; + uint32_t height_d2 = end_y / 2; uint32_t y; for (y = start_y_d2; y < height_d2; y++) { @@ -221,8 +218,8 @@ void decompress_420( lum0 = input[0] + y * 2 * in_linesize[0]; lum1 = lum0 + in_linesize[0]; - output0 = (uint32_t*)(output + y * 2 * out_linesize); - output1 = (uint32_t*)((uint8_t*)output0 + out_linesize); + output0 = (uint32_t *)(output + y * 2 * out_linesize); + output1 = (uint32_t *)((uint8_t *)output0 + out_linesize); for (x = 0; x < width_d2; x++) { uint32_t out; @@ -237,14 +234,13 @@ void decompress_420( } } -void decompress_nv12( - const uint8_t *const input[], const uint32_t in_linesize[], - uint32_t start_y, uint32_t end_y, - uint8_t *output, uint32_t out_linesize) +void decompress_nv12(const uint8_t *const input[], const uint32_t in_linesize[], + uint32_t start_y, uint32_t end_y, uint8_t *output, + uint32_t out_linesize) { - uint32_t start_y_d2 = start_y/2; - uint32_t width_d2 = min_uint32(in_linesize[0], out_linesize)/2; - uint32_t height_d2 = end_y/2; + uint32_t start_y_d2 = start_y / 2; + uint32_t width_d2 = min_uint32(in_linesize[0], out_linesize) / 2; + uint32_t height_d2 = end_y / 2; uint32_t y; for (y = start_y_d2; y < height_d2; y++) { @@ -253,11 +249,11 @@ void decompress_nv12( register uint32_t *output0, *output1; uint32_t x; - chroma = (const uint16_t*)(input[1] + y * in_linesize[1]); + chroma = (const uint16_t *)(input[1] + y * in_linesize[1]); lum0 = input[0] + y * 2 * in_linesize[0]; lum1 = lum0 + in_linesize[0]; - output0 = (uint32_t*)(output + y * 2 * out_linesize); - output1 = (uint32_t*)((uint8_t*)output0 + out_linesize); + output0 = (uint32_t *)(output + y * 2 * out_linesize); + output1 = (uint32_t *)((uint8_t *)output0 + out_linesize); for (x = 0; x < width_d2; x++) { uint32_t out = *(chroma++) << 8; @@ -271,31 +267,29 @@ void decompress_nv12( } } -void decompress_422( - const uint8_t *input, uint32_t in_linesize, - uint32_t start_y, uint32_t end_y, - uint8_t *output, uint32_t out_linesize, - bool leading_lum) +void decompress_422(const uint8_t *input, uint32_t in_linesize, + uint32_t start_y, uint32_t end_y, uint8_t *output, + uint32_t out_linesize, bool leading_lum) { - uint32_t width_d2 = min_uint32(in_linesize, out_linesize)/2; + uint32_t width_d2 = min_uint32(in_linesize, out_linesize) / 2; uint32_t y; register const uint32_t *input32; register const uint32_t *input32_end; - register uint32_t *output32; + register uint32_t *output32; if (leading_lum) { for (y = start_y; y < end_y; y++) { - input32 = (const uint32_t*)(input + y*in_linesize); + input32 = (const uint32_t *)(input + y * in_linesize); input32_end = input32 + width_d2; - output32 = (uint32_t*)(output + y*out_linesize); + output32 = (uint32_t *)(output + y * out_linesize); - while(input32 < input32_end) { + while (input32 < input32_end) { register uint32_t dw = *input32; output32[0] = dw; dw &= 0xFFFFFF00; - dw |= (uint8_t)(dw>>16); + dw |= (uint8_t)(dw >> 16); output32[1] = dw; output32 += 2; @@ -304,16 +298,16 @@ void decompress_422( } } else { for (y = start_y; y < end_y; y++) { - input32 = (const uint32_t*)(input + y*in_linesize); + input32 = (const uint32_t *)(input + y * in_linesize); input32_end = input32 + width_d2; - output32 = (uint32_t*)(output + y*out_linesize); + output32 = (uint32_t *)(output + y * out_linesize); while (input32 < input32_end) { register uint32_t dw = *input32; output32[0] = dw; dw &= 0xFFFF00FF; - dw |= (dw>>16) & 0xFF00; + dw |= (dw >> 16) & 0xFF00; output32[1] = dw; output32 += 2; diff --git a/libobs/media-io/format-conversion.h b/libobs/media-io/format-conversion.h index ea88005..edc5294 100644 --- a/libobs/media-io/format-conversion.h +++ b/libobs/media-io/format-conversion.h @@ -27,36 +27,34 @@ extern "C" { * Functions for converting to and from packed 444 YUV */ -EXPORT void compress_uyvx_to_i420( - const uint8_t *input, uint32_t in_linesize, - uint32_t start_y, uint32_t end_y, - uint8_t *output[], const uint32_t out_linesize[]); +EXPORT void compress_uyvx_to_i420(const uint8_t *input, uint32_t in_linesize, + uint32_t start_y, uint32_t end_y, + uint8_t *output[], + const uint32_t out_linesize[]); -EXPORT void compress_uyvx_to_nv12( - const uint8_t *input, uint32_t in_linesize, - uint32_t start_y, uint32_t end_y, - uint8_t *output[], const uint32_t out_linesize[]); +EXPORT void compress_uyvx_to_nv12(const uint8_t *input, uint32_t in_linesize, + uint32_t start_y, uint32_t end_y, + uint8_t *output[], + const uint32_t out_linesize[]); -EXPORT void convert_uyvx_to_i444( - const uint8_t *input, uint32_t in_linesize, - uint32_t start_y, uint32_t end_y, - uint8_t *output[], const uint32_t out_linesize[]); +EXPORT void convert_uyvx_to_i444(const uint8_t *input, uint32_t in_linesize, + uint32_t start_y, uint32_t end_y, + uint8_t *output[], + const uint32_t out_linesize[]); -EXPORT void decompress_nv12( - const uint8_t *const input[], const uint32_t in_linesize[], - uint32_t start_y, uint32_t end_y, - uint8_t *output, uint32_t out_linesize); +EXPORT void decompress_nv12(const uint8_t *const input[], + const uint32_t in_linesize[], uint32_t start_y, + uint32_t end_y, uint8_t *output, + uint32_t out_linesize); -EXPORT void decompress_420( - const uint8_t *const input[], const uint32_t in_linesize[], - uint32_t start_y, uint32_t end_y, - uint8_t *output, uint32_t out_linesize); +EXPORT void decompress_420(const uint8_t *const input[], + const uint32_t in_linesize[], uint32_t start_y, + uint32_t end_y, uint8_t *output, + uint32_t out_linesize); -EXPORT void decompress_422( - const uint8_t *input, uint32_t in_linesize, - uint32_t start_y, uint32_t end_y, - uint8_t *output, uint32_t out_linesize, - bool leading_lum); +EXPORT void decompress_422(const uint8_t *input, uint32_t in_linesize, + uint32_t start_y, uint32_t end_y, uint8_t *output, + uint32_t out_linesize, bool leading_lum); #ifdef __cplusplus } diff --git a/libobs/media-io/frame-rate.h b/libobs/media-io/frame-rate.h index 5e72dc5..6c6a3db 100644 --- a/libobs/media-io/frame-rate.h +++ b/libobs/media-io/frame-rate.h @@ -9,20 +9,20 @@ struct media_frames_per_second { uint32_t denominator; }; -static inline double media_frames_per_second_to_frame_interval( - struct media_frames_per_second fps) +static inline double +media_frames_per_second_to_frame_interval(struct media_frames_per_second fps) { return (double)fps.denominator / fps.numerator; } -static inline double media_frames_per_second_to_fps( - struct media_frames_per_second fps) +static inline double +media_frames_per_second_to_fps(struct media_frames_per_second fps) { return (double)fps.numerator / fps.denominator; } -static inline bool media_frames_per_second_is_valid( - struct media_frames_per_second fps) +static inline bool +media_frames_per_second_is_valid(struct media_frames_per_second fps) { return fps.numerator && fps.denominator; } diff --git a/libobs/media-io/media-remux.c b/libobs/media-io/media-remux.c index 9f5f72f..206cb61 100644 --- a/libobs/media-io/media-remux.c +++ b/libobs/media-io/media-remux.c @@ -54,7 +54,7 @@ static inline bool init_input(media_remux_job_t job, const char *in_filename) int ret = avformat_open_input(&job->ifmt_ctx, in_filename, NULL, NULL); if (ret < 0) { blog(LOG_ERROR, "media_remux: Could not open input file '%s'", - in_filename); + in_filename); return false; } @@ -76,16 +76,16 @@ static inline bool init_output(media_remux_job_t job, const char *out_filename) int ret; avformat_alloc_output_context2(&job->ofmt_ctx, NULL, NULL, - out_filename); + out_filename); if (!job->ofmt_ctx) { blog(LOG_ERROR, "media_remux: Could not create output context"); return false; } for (unsigned i = 0; i < job->ifmt_ctx->nb_streams; i++) { - AVStream *in_stream = job->ifmt_ctx->streams[i]; - AVStream *out_stream = avformat_new_stream(job->ofmt_ctx, - in_stream->codec->codec); + AVStream *in_stream = job->ifmt_ctx->streams[i]; + AVStream *out_stream = avformat_new_stream( + job->ofmt_ctx, in_stream->codec->codec); if (!out_stream) { blog(LOG_ERROR, "media_remux: Failed to allocate output" " stream"); @@ -97,7 +97,7 @@ static inline bool init_output(media_remux_job_t job, const char *out_filename) ret = avcodec_parameters_from_context(par, in_stream->codec); if (ret == 0) ret = avcodec_parameters_to_context(out_stream->codec, - par); + par); avcodec_parameters_free(&par); #else ret = avcodec_copy_context(out_stream->codec, in_stream->codec); @@ -124,8 +124,10 @@ static inline bool init_output(media_remux_job_t job, const char *out_filename) ret = avio_open(&job->ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE); if (ret < 0) { - blog(LOG_ERROR, "media_remux: Failed to open output" - " file '%s'", out_filename); + blog(LOG_ERROR, + "media_remux: Failed to open output" + " file '%s'", + out_filename); return false; } } @@ -134,7 +136,7 @@ static inline bool init_output(media_remux_job_t job, const char *out_filename) } bool media_remux_job_create(media_remux_job_t *job, const char *in_filename, - const char *out_filename) + const char *out_filename) { if (!job) return false; @@ -152,7 +154,9 @@ bool media_remux_job_create(media_remux_job_t *job, const char *in_filename, init_size(*job, in_filename); +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) av_register_all(); +#endif if (!init_input(*job, in_filename)) goto fail; @@ -167,23 +171,23 @@ fail: return false; } -static inline void process_packet(AVPacket *pkt, - AVStream *in_stream, AVStream *out_stream) +static inline void process_packet(AVPacket *pkt, AVStream *in_stream, + AVStream *out_stream) { pkt->pts = av_rescale_q_rnd(pkt->pts, in_stream->time_base, - out_stream->time_base, - AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); + out_stream->time_base, + AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); pkt->dts = av_rescale_q_rnd(pkt->dts, in_stream->time_base, - out_stream->time_base, - AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); - pkt->duration = (int)av_rescale_q(pkt->duration, - in_stream->time_base, out_stream->time_base); + out_stream->time_base, + AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); + pkt->duration = (int)av_rescale_q(pkt->duration, in_stream->time_base, + out_stream->time_base); pkt->pos = -1; - } static inline int process_packets(media_remux_job_t job, - media_remux_progress_callback callback, void *data) + media_remux_progress_callback callback, + void *data) { AVPacket pkt; @@ -192,9 +196,10 @@ static inline int process_packets(media_remux_job_t job, ret = av_read_frame(job->ifmt_ctx, &pkt); if (ret < 0) { if (ret != AVERROR_EOF) - blog(LOG_ERROR, "media_remux: Error reading" - " packet: %s", - av_err2str(ret)); + blog(LOG_ERROR, + "media_remux: Error reading" + " packet: %s", + av_err2str(ret)); break; } @@ -206,14 +211,14 @@ static inline int process_packets(media_remux_job_t job, } process_packet(&pkt, job->ifmt_ctx->streams[pkt.stream_index], - job->ofmt_ctx->streams[pkt.stream_index]); + job->ofmt_ctx->streams[pkt.stream_index]); ret = av_interleaved_write_frame(job->ofmt_ctx, &pkt); av_packet_unref(&pkt); if (ret < 0) { blog(LOG_ERROR, "media_remux: Error muxing packet: %s", - av_err2str(ret)); + av_err2str(ret)); break; } } @@ -222,7 +227,7 @@ static inline int process_packets(media_remux_job_t job, } bool media_remux_job_process(media_remux_job_t job, - media_remux_progress_callback callback, void *data) + media_remux_progress_callback callback, void *data) { int ret; bool success = false; @@ -233,7 +238,7 @@ bool media_remux_job_process(media_remux_job_t job, ret = avformat_write_header(job->ofmt_ctx, NULL); if (ret < 0) { blog(LOG_ERROR, "media_remux: Error opening output file: %s", - av_err2str(ret)); + av_err2str(ret)); return success; } @@ -246,7 +251,7 @@ bool media_remux_job_process(media_remux_job_t job, ret = av_write_trailer(job->ofmt_ctx); if (ret < 0) { blog(LOG_ERROR, "media_remux: av_write_trailer: %s", - av_err2str(ret)); + av_err2str(ret)); success = false; } diff --git a/libobs/media-io/media-remux.h b/libobs/media-io/media-remux.h index 0ebdcae..c04ff37 100644 --- a/libobs/media-io/media-remux.h +++ b/libobs/media-io/media-remux.h @@ -22,16 +22,18 @@ struct media_remux_job; typedef struct media_remux_job *media_remux_job_t; -typedef bool (media_remux_progress_callback)(void *data, float percent); +typedef bool(media_remux_progress_callback)(void *data, float percent); #ifdef __cplusplus extern "C" { #endif EXPORT bool media_remux_job_create(media_remux_job_t *job, - const char *in_filename, const char *out_filename); + const char *in_filename, + const char *out_filename); EXPORT bool media_remux_job_process(media_remux_job_t job, - media_remux_progress_callback callback, void *data); + media_remux_progress_callback callback, + void *data); EXPORT void media_remux_job_destroy(media_remux_job_t job); #ifdef __cplusplus diff --git a/libobs/media-io/video-fourcc.c b/libobs/media-io/video-fourcc.c index 37b949b..abe0d83 100644 --- a/libobs/media-io/video-fourcc.c +++ b/libobs/media-io/video-fourcc.c @@ -24,31 +24,29 @@ enum video_format video_format_from_fourcc(uint32_t fourcc) { switch (fourcc) { - case MAKE_FOURCC('U','Y','V','Y'): - case MAKE_FOURCC('H','D','Y','C'): - case MAKE_FOURCC('U','Y','N','V'): - case MAKE_FOURCC('U','Y','N','Y'): - case MAKE_FOURCC('u','y','v','1'): - case MAKE_FOURCC('2','v','u','y'): - case MAKE_FOURCC('2','V','u','y'): - return VIDEO_FORMAT_UYVY; + case MAKE_FOURCC('U', 'Y', 'V', 'Y'): + case MAKE_FOURCC('H', 'D', 'Y', 'C'): + case MAKE_FOURCC('U', 'Y', 'N', 'V'): + case MAKE_FOURCC('U', 'Y', 'N', 'Y'): + case MAKE_FOURCC('u', 'y', 'v', '1'): + case MAKE_FOURCC('2', 'v', 'u', 'y'): + case MAKE_FOURCC('2', 'V', 'u', 'y'): + return VIDEO_FORMAT_UYVY; - case MAKE_FOURCC('Y','U','Y','2'): - case MAKE_FOURCC('Y','4','2','2'): - case MAKE_FOURCC('V','4','2','2'): - case MAKE_FOURCC('V','Y','U','Y'): - case MAKE_FOURCC('Y','U','N','V'): - case MAKE_FOURCC('y','u','v','2'): - case MAKE_FOURCC('y','u','v','s'): - return VIDEO_FORMAT_YUY2; + case MAKE_FOURCC('Y', 'U', 'Y', '2'): + case MAKE_FOURCC('Y', '4', '2', '2'): + case MAKE_FOURCC('V', '4', '2', '2'): + case MAKE_FOURCC('V', 'Y', 'U', 'Y'): + case MAKE_FOURCC('Y', 'U', 'N', 'V'): + case MAKE_FOURCC('y', 'u', 'v', '2'): + case MAKE_FOURCC('y', 'u', 'v', 's'): + return VIDEO_FORMAT_YUY2; - case MAKE_FOURCC('Y','V','Y','U'): - return VIDEO_FORMAT_YVYU; + case MAKE_FOURCC('Y', 'V', 'Y', 'U'): + return VIDEO_FORMAT_YVYU; - case MAKE_FOURCC('Y','8','0','0'): - return VIDEO_FORMAT_Y800; - + case MAKE_FOURCC('Y', '8', '0', '0'): + return VIDEO_FORMAT_Y800; } return VIDEO_FORMAT_NONE; } - diff --git a/libobs/media-io/video-frame.c b/libobs/media-io/video-frame.c index f29a6f1..746d53f 100644 --- a/libobs/media-io/video-frame.c +++ b/libobs/media-io/video-frame.c @@ -17,18 +17,18 @@ #include "video-frame.h" -#define ALIGN_SIZE(size, align) \ - size = (((size)+(align-1)) & (~(align-1))) +#define ALIGN_SIZE(size, align) size = (((size) + (align - 1)) & (~(align - 1))) /* messy code alarm */ void video_frame_init(struct video_frame *frame, enum video_format format, - uint32_t width, uint32_t height) + uint32_t width, uint32_t height) { size_t size; size_t offsets[MAX_AV_PLANES]; - int alignment = base_get_alignment(); + int alignment = base_get_alignment(); - if (!frame) return; + if (!frame) + return; memset(frame, 0, sizeof(struct video_frame)); memset(offsets, 0, sizeof(offsets)); @@ -41,27 +41,27 @@ void video_frame_init(struct video_frame *frame, enum video_format format, size = width * height; ALIGN_SIZE(size, alignment); offsets[0] = size; - size += (width/2) * (height/2); + size += (width / 2) * (height / 2); ALIGN_SIZE(size, alignment); offsets[1] = size; - size += (width/2) * (height/2); + size += (width / 2) * (height / 2); ALIGN_SIZE(size, alignment); frame->data[0] = bmalloc(size); - frame->data[1] = (uint8_t*)frame->data[0] + offsets[0]; - frame->data[2] = (uint8_t*)frame->data[0] + offsets[1]; + frame->data[1] = (uint8_t *)frame->data[0] + offsets[0]; + frame->data[2] = (uint8_t *)frame->data[0] + offsets[1]; frame->linesize[0] = width; - frame->linesize[1] = width/2; - frame->linesize[2] = width/2; + frame->linesize[1] = width / 2; + frame->linesize[2] = width / 2; break; case VIDEO_FORMAT_NV12: size = width * height; ALIGN_SIZE(size, alignment); offsets[0] = size; - size += (width/2) * (height/2) * 2; + size += (width / 2) * (height / 2) * 2; ALIGN_SIZE(size, alignment); frame->data[0] = bmalloc(size); - frame->data[1] = (uint8_t*)frame->data[0] + offsets[0]; + frame->data[1] = (uint8_t *)frame->data[0] + offsets[0]; frame->linesize[0] = width; frame->linesize[1] = width; break; @@ -79,33 +79,124 @@ void video_frame_init(struct video_frame *frame, enum video_format format, size = width * height * 2; ALIGN_SIZE(size, alignment); frame->data[0] = bmalloc(size); - frame->linesize[0] = width*2; + frame->linesize[0] = width * 2; break; case VIDEO_FORMAT_RGBA: case VIDEO_FORMAT_BGRA: case VIDEO_FORMAT_BGRX: + case VIDEO_FORMAT_AYUV: size = width * height * 4; ALIGN_SIZE(size, alignment); frame->data[0] = bmalloc(size); - frame->linesize[0] = width*4; + frame->linesize[0] = width * 4; break; case VIDEO_FORMAT_I444: size = width * height; ALIGN_SIZE(size, alignment); frame->data[0] = bmalloc(size * 3); - frame->data[1] = (uint8_t*)frame->data[0] + size; - frame->data[2] = (uint8_t*)frame->data[1] + size; + frame->data[1] = (uint8_t *)frame->data[0] + size; + frame->data[2] = (uint8_t *)frame->data[1] + size; frame->linesize[0] = width; frame->linesize[1] = width; frame->linesize[2] = width; break; + + case VIDEO_FORMAT_BGR3: + size = width * height * 3; + ALIGN_SIZE(size, alignment); + frame->data[0] = bmalloc(size); + frame->linesize[0] = width * 3; + break; + + case VIDEO_FORMAT_I422: + size = width * height; + ALIGN_SIZE(size, alignment); + offsets[0] = size; + size += (width / 2) * height; + ALIGN_SIZE(size, alignment); + offsets[1] = size; + size += (width / 2) * height; + ALIGN_SIZE(size, alignment); + frame->data[0] = bmalloc(size); + frame->data[1] = (uint8_t *)frame->data[0] + offsets[0]; + frame->data[2] = (uint8_t *)frame->data[0] + offsets[1]; + frame->linesize[0] = width; + frame->linesize[1] = width / 2; + frame->linesize[2] = width / 2; + break; + + case VIDEO_FORMAT_I40A: + size = width * height; + ALIGN_SIZE(size, alignment); + offsets[0] = size; + size += (width / 2) * (height / 2); + ALIGN_SIZE(size, alignment); + offsets[1] = size; + size += (width / 2) * (height / 2); + ALIGN_SIZE(size, alignment); + offsets[2] = size; + size += width * height; + ALIGN_SIZE(size, alignment); + frame->data[0] = bmalloc(size); + frame->data[1] = (uint8_t *)frame->data[0] + offsets[0]; + frame->data[2] = (uint8_t *)frame->data[0] + offsets[1]; + frame->data[3] = (uint8_t *)frame->data[0] + offsets[2]; + frame->linesize[0] = width; + frame->linesize[1] = width / 2; + frame->linesize[2] = width / 2; + frame->linesize[3] = width; + break; + + case VIDEO_FORMAT_I42A: + size = width * height; + ALIGN_SIZE(size, alignment); + offsets[0] = size; + size += (width / 2) * height; + ALIGN_SIZE(size, alignment); + offsets[1] = size; + size += (width / 2) * height; + ALIGN_SIZE(size, alignment); + offsets[2] = size; + size += width * height; + ALIGN_SIZE(size, alignment); + frame->data[0] = bmalloc(size); + frame->data[1] = (uint8_t *)frame->data[0] + offsets[0]; + frame->data[2] = (uint8_t *)frame->data[0] + offsets[1]; + frame->data[3] = (uint8_t *)frame->data[0] + offsets[2]; + frame->linesize[0] = width; + frame->linesize[1] = width / 2; + frame->linesize[2] = width / 2; + frame->linesize[3] = width; + break; + + case VIDEO_FORMAT_YUVA: + size = width * height; + ALIGN_SIZE(size, alignment); + offsets[0] = size; + size += width * height; + ALIGN_SIZE(size, alignment); + offsets[1] = size; + size += width * height; + ALIGN_SIZE(size, alignment); + offsets[2] = size; + size += width * height; + ALIGN_SIZE(size, alignment); + frame->data[0] = bmalloc(size); + frame->data[1] = (uint8_t *)frame->data[0] + offsets[0]; + frame->data[2] = (uint8_t *)frame->data[0] + offsets[1]; + frame->data[3] = (uint8_t *)frame->data[0] + offsets[2]; + frame->linesize[0] = width; + frame->linesize[1] = width; + frame->linesize[2] = width; + frame->linesize[3] = width; + break; } } void video_frame_copy(struct video_frame *dst, const struct video_frame *src, - enum video_format format, uint32_t cy) + enum video_format format, uint32_t cy) { switch (format) { case VIDEO_FORMAT_NONE: @@ -129,13 +220,31 @@ void video_frame_copy(struct video_frame *dst, const struct video_frame *src, case VIDEO_FORMAT_RGBA: case VIDEO_FORMAT_BGRA: case VIDEO_FORMAT_BGRX: + case VIDEO_FORMAT_BGR3: + case VIDEO_FORMAT_AYUV: memcpy(dst->data[0], src->data[0], src->linesize[0] * cy); break; case VIDEO_FORMAT_I444: + case VIDEO_FORMAT_I422: memcpy(dst->data[0], src->data[0], src->linesize[0] * cy); memcpy(dst->data[1], src->data[1], src->linesize[1] * cy); memcpy(dst->data[2], src->data[2], src->linesize[2] * cy); break; + + case VIDEO_FORMAT_I40A: + memcpy(dst->data[0], src->data[0], src->linesize[0] * cy); + memcpy(dst->data[1], src->data[1], src->linesize[1] * cy / 2); + memcpy(dst->data[2], src->data[2], src->linesize[2] * cy / 2); + memcpy(dst->data[3], src->data[3], src->linesize[3] * cy); + break; + + case VIDEO_FORMAT_I42A: + case VIDEO_FORMAT_YUVA: + memcpy(dst->data[0], src->data[0], src->linesize[0] * cy); + memcpy(dst->data[1], src->data[1], src->linesize[1] * cy); + memcpy(dst->data[2], src->data[2], src->linesize[2] * cy); + memcpy(dst->data[3], src->data[3], src->linesize[3] * cy); + break; } } diff --git a/libobs/media-io/video-frame.h b/libobs/media-io/video-frame.h index 4620a2f..f0d021d 100644 --- a/libobs/media-io/video-frame.h +++ b/libobs/media-io/video-frame.h @@ -21,12 +21,13 @@ #include "video-io.h" struct video_frame { - uint8_t *data[MAX_AV_PLANES]; + uint8_t *data[MAX_AV_PLANES]; uint32_t linesize[MAX_AV_PLANES]; }; EXPORT void video_frame_init(struct video_frame *frame, - enum video_format format, uint32_t width, uint32_t height); + enum video_format format, uint32_t width, + uint32_t height); static inline void video_frame_free(struct video_frame *frame) { @@ -36,12 +37,12 @@ static inline void video_frame_free(struct video_frame *frame) } } -static inline struct video_frame *video_frame_create( - enum video_format format, uint32_t width, uint32_t height) +static inline struct video_frame * +video_frame_create(enum video_format format, uint32_t width, uint32_t height) { struct video_frame *frame; - frame = (struct video_frame*)bzalloc(sizeof(struct video_frame)); + frame = (struct video_frame *)bzalloc(sizeof(struct video_frame)); video_frame_init(frame, format, width, height); return frame; } @@ -55,5 +56,5 @@ static inline void video_frame_destroy(struct video_frame *frame) } EXPORT void video_frame_copy(struct video_frame *dst, - const struct video_frame *src, enum video_format format, - uint32_t height); + const struct video_frame *src, + enum video_format format, uint32_t height); diff --git a/libobs/media-io/video-io.c b/libobs/media-io/video-io.c index 43227b7..08d7be2 100644 --- a/libobs/media-io/video-io.c +++ b/libobs/media-io/video-io.c @@ -40,10 +40,10 @@ struct cached_frame_info { }; struct video_input { - struct video_scale_info conversion; - video_scaler_t *scaler; - struct video_frame frame[MAX_CONVERT_BUFFERS]; - int cur_frame; + struct video_scale_info conversion; + video_scaler_t *scaler; + struct video_frame frame[MAX_CONVERT_BUFFERS]; + int cur_frame; void (*callback)(void *param, struct video_data *frame); void *param; @@ -57,35 +57,35 @@ static inline void video_input_free(struct video_input *input) } struct video_output { - struct video_output_info info; + struct video_output_info info; - pthread_t thread; - pthread_mutex_t data_mutex; - bool stop; + pthread_t thread; + pthread_mutex_t data_mutex; + bool stop; - os_sem_t *update_semaphore; - uint64_t frame_time; - volatile long skipped_frames; - volatile long total_frames; + os_sem_t *update_semaphore; + uint64_t frame_time; + volatile long skipped_frames; + volatile long total_frames; - bool initialized; + bool initialized; - pthread_mutex_t input_mutex; + pthread_mutex_t input_mutex; DARRAY(struct video_input) inputs; - size_t available_frames; - size_t first_added; - size_t last_added; - struct cached_frame_info cache[MAX_CACHE_SIZE]; + size_t available_frames; + size_t first_added; + size_t last_added; + struct cached_frame_info cache[MAX_CACHE_SIZE]; - volatile bool raw_active; - volatile long gpu_refs; + volatile bool raw_active; + volatile long gpu_refs; }; /* ------------------------------------------------------------------------- */ static inline bool scale_video_output(struct video_input *input, - struct video_data *data) + struct video_data *data) { bool success = true; @@ -97,14 +97,14 @@ static inline bool scale_video_output(struct video_input *input, frame = &input->frame[input->cur_frame]; - success = video_scaler_scale(input->scaler, - frame->data, frame->linesize, - (const uint8_t * const*)data->data, - data->linesize); + success = video_scaler_scale(input->scaler, frame->data, + frame->linesize, + (const uint8_t *const *)data->data, + data->linesize); if (success) { for (size_t i = 0; i < MAX_AV_PLANES; i++) { - data->data[i] = frame->data[i]; + data->data[i] = frame->data[i]; data->linesize[i] = frame->linesize[i]; } } else { @@ -134,7 +134,7 @@ static inline bool video_output_cur_frame(struct video_output *video) pthread_mutex_lock(&video->input_mutex); for (size_t i = 0; i < video->inputs.num; i++) { - struct video_input *input = video->inputs.array+i; + struct video_input *input = video->inputs.array + i; struct video_data frame = frame_info->frame; if (scale_video_output(input, &frame)) @@ -177,7 +177,7 @@ static void *video_thread(void *param) const char *video_thread_name = profile_store_name(obs_get_profiler_name_store(), - "video_thread(%s)", video->info.name); + "video_thread(%s)", video->info.name); while (os_sem_wait(video->update_semaphore) == 0) { if (video->stop) @@ -212,10 +212,10 @@ static inline void init_cache(struct video_output *video) for (size_t i = 0; i < video->info.cache_size; i++) { struct video_frame *frame; - frame = (struct video_frame*)&video->cache[i]; + frame = (struct video_frame *)&video->cache[i]; - video_frame_init(frame, video->info.format, - video->info.width, video->info.height); + video_frame_init(frame, video->info.format, video->info.width, + video->info.height); } video->available_frames = video->info.cache_size; @@ -235,7 +235,7 @@ int video_output_open(video_t **video, struct video_output_info *info) memcpy(&out->info, info, sizeof(struct video_output_info)); out->frame_time = (uint64_t)(1000000000.0 * (double)info->fps_den / - (double)info->fps_num); + (double)info->fps_num); out->initialized = false; if (pthread_mutexattr_init(&attr) != 0) @@ -274,7 +274,7 @@ void video_output_close(video_t *video) da_free(video->inputs); for (size_t i = 0; i < video->info.cache_size; i++) - video_frame_free((struct video_frame*)&video->cache[i]); + video_frame_free((struct video_frame *)&video->cache[i]); os_sem_destroy(video->update_semaphore); pthread_mutex_destroy(&video->data_mutex); @@ -283,11 +283,12 @@ void video_output_close(video_t *video) } static size_t video_get_input_idx(const video_t *video, - void (*callback)(void *param, struct video_data *frame), - void *param) + void (*callback)(void *param, + struct video_data *frame), + void *param) { for (size_t i = 0; i < video->inputs.num; i++) { - struct video_input *input = video->inputs.array+i; + struct video_input *input = video->inputs.array + i; if (input->callback == callback && input->param == param) return i; } @@ -296,38 +297,37 @@ static size_t video_get_input_idx(const video_t *video, } static inline bool video_input_init(struct video_input *input, - struct video_output *video) + struct video_output *video) { - if (input->conversion.width != video->info.width || + if (input->conversion.width != video->info.width || input->conversion.height != video->info.height || input->conversion.format != video->info.format) { - struct video_scale_info from = { - .format = video->info.format, - .width = video->info.width, - .height = video->info.height, - .range = video->info.range, - .colorspace = video->info.colorspace - }; + struct video_scale_info from = {.format = video->info.format, + .width = video->info.width, + .height = video->info.height, + .range = video->info.range, + .colorspace = + video->info.colorspace}; int ret = video_scaler_create(&input->scaler, - &input->conversion, &from, - VIDEO_SCALE_FAST_BILINEAR); + &input->conversion, &from, + VIDEO_SCALE_FAST_BILINEAR); if (ret != VIDEO_SCALER_SUCCESS) { if (ret == VIDEO_SCALER_BAD_CONVERSION) blog(LOG_ERROR, "video_input_init: Bad " - "scale conversion type"); + "scale conversion type"); else blog(LOG_ERROR, "video_input_init: Failed to " - "create scaler"); + "create scaler"); return false; } for (size_t i = 0; i < MAX_CONVERT_BUFFERS; i++) video_frame_init(&input->frame[i], - input->conversion.format, - input->conversion.width, - input->conversion.height); + input->conversion.format, + input->conversion.width, + input->conversion.height); } return true; @@ -339,10 +339,9 @@ static inline void reset_frames(video_t *video) os_atomic_set_long(&video->total_frames, 0); } -bool video_output_connect(video_t *video, - const struct video_scale_info *conversion, - void (*callback)(void *param, struct video_data *frame), - void *param) +bool video_output_connect( + video_t *video, const struct video_scale_info *conversion, + void (*callback)(void *param, struct video_data *frame), void *param) { bool success = false; @@ -356,14 +355,14 @@ bool video_output_connect(video_t *video, memset(&input, 0, sizeof(input)); input.callback = callback; - input.param = param; + input.param = param; if (conversion) { input.conversion = *conversion; } else { - input.conversion.format = video->info.format; - input.conversion.width = video->info.width; - input.conversion.height = video->info.height; + input.conversion.format = video->info.format; + input.conversion.width = video->info.width; + input.conversion.height = video->info.height; } if (input.conversion.width == 0) @@ -393,22 +392,22 @@ static void log_skipped(video_t *video) long skipped = os_atomic_load_long(&video->skipped_frames); double percentage_skipped = (double)skipped / - (double)os_atomic_load_long(&video->total_frames) * - 100.0; + (double)os_atomic_load_long(&video->total_frames) * 100.0; if (skipped) - blog(LOG_INFO, "Video stopped, number of " - "skipped frames due " - "to encoding lag: " - "%ld/%ld (%0.1f%%)", - video->skipped_frames, - video->total_frames, - percentage_skipped); + blog(LOG_INFO, + "Video stopped, number of " + "skipped frames due " + "to encoding lag: " + "%ld/%ld (%0.1f%%)", + video->skipped_frames, video->total_frames, + percentage_skipped); } void video_output_disconnect(video_t *video, - void (*callback)(void *param, struct video_data *frame), - void *param) + void (*callback)(void *param, + struct video_data *frame), + void *param) { if (!video || !callback) return; @@ -417,7 +416,7 @@ void video_output_disconnect(video_t *video, size_t idx = video_get_input_idx(video, callback, param); if (idx != DARRAY_INVALID) { - video_input_free(video->inputs.array+idx); + video_input_free(video->inputs.array + idx); da_erase(video->inputs, idx); if (video->inputs.num == 0) { @@ -433,7 +432,8 @@ void video_output_disconnect(video_t *video, bool video_output_active(const video_t *video) { - if (!video) return false; + if (!video) + return false; return os_atomic_load_bool(&video->raw_active); } @@ -443,12 +443,13 @@ const struct video_output_info *video_output_get_info(const video_t *video) } bool video_output_lock_frame(video_t *video, struct video_frame *frame, - int count, uint64_t timestamp) + int count, uint64_t timestamp) { struct cached_frame_info *cfi; bool locked; - if (!video) return false; + if (!video) + return false; pthread_mutex_lock(&video->data_mutex); @@ -480,7 +481,8 @@ bool video_output_lock_frame(video_t *video, struct video_frame *frame, void video_output_unlock_frame(video_t *video) { - if (!video) return; + if (!video) + return; pthread_mutex_lock(&video->data_mutex); diff --git a/libobs/media-io/video-io.h b/libobs/media-io/video-io.h index 77acf8f..445ab54 100644 --- a/libobs/media-io/video-io.h +++ b/libobs/media-io/video-io.h @@ -50,6 +50,24 @@ enum video_format { /* planar 4:4:4 */ VIDEO_FORMAT_I444, + + /* more packed uncompressed formats */ + VIDEO_FORMAT_BGR3, + + /* planar 4:2:2 */ + VIDEO_FORMAT_I422, + + /* planar 4:2:0 with alpha */ + VIDEO_FORMAT_I40A, + + /* planar 4:2:2 with alpha */ + VIDEO_FORMAT_I42A, + + /* planar 4:4:4 with alpha */ + VIDEO_FORMAT_YUVA, + + /* packed 4:4:4 with alpha */ + VIDEO_FORMAT_AYUV, }; enum video_colorspace { @@ -65,20 +83,20 @@ enum video_range_type { }; struct video_data { - uint8_t *data[MAX_AV_PLANES]; - uint32_t linesize[MAX_AV_PLANES]; - uint64_t timestamp; + uint8_t *data[MAX_AV_PLANES]; + uint32_t linesize[MAX_AV_PLANES]; + uint64_t timestamp; }; struct video_output_info { - const char *name; + const char *name; enum video_format format; - uint32_t fps_num; - uint32_t fps_den; - uint32_t width; - uint32_t height; - size_t cache_size; + uint32_t fps_num; + uint32_t fps_den; + uint32_t width; + uint32_t height; + size_t cache_size; enum video_colorspace colorspace; enum video_range_type range; @@ -89,16 +107,22 @@ static inline bool format_is_yuv(enum video_format format) switch (format) { case VIDEO_FORMAT_I420: case VIDEO_FORMAT_NV12: + case VIDEO_FORMAT_I422: case VIDEO_FORMAT_YVYU: case VIDEO_FORMAT_YUY2: case VIDEO_FORMAT_UYVY: case VIDEO_FORMAT_I444: + case VIDEO_FORMAT_I40A: + case VIDEO_FORMAT_I42A: + case VIDEO_FORMAT_YUVA: + case VIDEO_FORMAT_AYUV: return true; case VIDEO_FORMAT_NONE: case VIDEO_FORMAT_RGBA: case VIDEO_FORMAT_BGRA: case VIDEO_FORMAT_BGRX: case VIDEO_FORMAT_Y800: + case VIDEO_FORMAT_BGR3: return false; } @@ -108,16 +132,38 @@ static inline bool format_is_yuv(enum video_format format) static inline const char *get_video_format_name(enum video_format format) { switch (format) { - case VIDEO_FORMAT_I420: return "I420"; - case VIDEO_FORMAT_NV12: return "NV12"; - case VIDEO_FORMAT_YVYU: return "YVYU"; - case VIDEO_FORMAT_YUY2: return "YUY2"; - case VIDEO_FORMAT_UYVY: return "UYVY"; - case VIDEO_FORMAT_RGBA: return "RGBA"; - case VIDEO_FORMAT_BGRA: return "BGRA"; - case VIDEO_FORMAT_BGRX: return "BGRX"; - case VIDEO_FORMAT_I444: return "I444"; - case VIDEO_FORMAT_Y800: return "Y800"; + case VIDEO_FORMAT_I420: + return "I420"; + case VIDEO_FORMAT_NV12: + return "NV12"; + case VIDEO_FORMAT_I422: + return "I422"; + case VIDEO_FORMAT_YVYU: + return "YVYU"; + case VIDEO_FORMAT_YUY2: + return "YUY2"; + case VIDEO_FORMAT_UYVY: + return "UYVY"; + case VIDEO_FORMAT_RGBA: + return "RGBA"; + case VIDEO_FORMAT_BGRA: + return "BGRA"; + case VIDEO_FORMAT_BGRX: + return "BGRX"; + case VIDEO_FORMAT_I444: + return "I444"; + case VIDEO_FORMAT_Y800: + return "Y800"; + case VIDEO_FORMAT_BGR3: + return "BGR3"; + case VIDEO_FORMAT_I40A: + return "I40A"; + case VIDEO_FORMAT_I42A: + return "I42A"; + case VIDEO_FORMAT_YUVA: + return "YUVA"; + case VIDEO_FORMAT_AYUV: + return "AYUV"; case VIDEO_FORMAT_NONE:; } @@ -127,7 +173,8 @@ static inline const char *get_video_format_name(enum video_format format) static inline const char *get_video_colorspace_name(enum video_colorspace cs) { switch (cs) { - case VIDEO_CS_709: return "709"; + case VIDEO_CS_709: + return "709"; case VIDEO_CS_601: case VIDEO_CS_DEFAULT:; } @@ -135,20 +182,19 @@ static inline const char *get_video_colorspace_name(enum video_colorspace cs) return "601"; } -static inline enum video_range_type resolve_video_range( - enum video_format format, enum video_range_type range) +static inline enum video_range_type +resolve_video_range(enum video_format format, enum video_range_type range) { if (range == VIDEO_RANGE_DEFAULT) { - range = format_is_yuv(format) - ? VIDEO_RANGE_PARTIAL - : VIDEO_RANGE_FULL; + range = format_is_yuv(format) ? VIDEO_RANGE_PARTIAL + : VIDEO_RANGE_FULL; } return range; } static inline const char *get_video_range_name(enum video_format format, - enum video_range_type range) + enum video_range_type range) { range = resolve_video_range(format, range); return range == VIDEO_RANGE_FULL ? "Full" : "Partial"; @@ -163,9 +209,9 @@ enum video_scale_type { }; struct video_scale_info { - enum video_format format; - uint32_t width; - uint32_t height; + enum video_format format; + uint32_t width; + uint32_t height; enum video_range_type range; enum video_colorspace colorspace; }; @@ -173,30 +219,32 @@ struct video_scale_info { EXPORT enum video_format video_format_from_fourcc(uint32_t fourcc); EXPORT bool video_format_get_parameters(enum video_colorspace color_space, - enum video_range_type range, float matrix[16], - float min_range[3], float max_range[3]); + enum video_range_type range, + float matrix[16], float min_range[3], + float max_range[3]); -#define VIDEO_OUTPUT_SUCCESS 0 +#define VIDEO_OUTPUT_SUCCESS 0 #define VIDEO_OUTPUT_INVALIDPARAM -1 -#define VIDEO_OUTPUT_FAIL -2 +#define VIDEO_OUTPUT_FAIL -2 EXPORT int video_output_open(video_t **video, struct video_output_info *info); EXPORT void video_output_close(video_t *video); -EXPORT bool video_output_connect(video_t *video, - const struct video_scale_info *conversion, - void (*callback)(void *param, struct video_data *frame), - void *param); +EXPORT bool +video_output_connect(video_t *video, const struct video_scale_info *conversion, + void (*callback)(void *param, struct video_data *frame), + void *param); EXPORT void video_output_disconnect(video_t *video, - void (*callback)(void *param, struct video_data *frame), - void *param); + void (*callback)(void *param, + struct video_data *frame), + void *param); EXPORT bool video_output_active(const video_t *video); -EXPORT const struct video_output_info *video_output_get_info( - const video_t *video); +EXPORT const struct video_output_info * +video_output_get_info(const video_t *video); EXPORT bool video_output_lock_frame(video_t *video, struct video_frame *frame, - int count, uint64_t timestamp); + int count, uint64_t timestamp); EXPORT void video_output_unlock_frame(video_t *video); EXPORT uint64_t video_output_get_frame_time(const video_t *video); EXPORT void video_output_stop(video_t *video); @@ -215,7 +263,6 @@ extern void video_output_dec_texture_encoders(video_t *video); extern void video_output_inc_texture_frames(video_t *video); extern void video_output_inc_texture_skipped_frames(video_t *video); - #ifdef __cplusplus } #endif diff --git a/libobs/media-io/video-matrices.c b/libobs/media-io/video-matrices.c index 82b92ef..8def5f7 100644 --- a/libobs/media-io/video-matrices.c +++ b/libobs/media-io/video-matrices.c @@ -37,69 +37,59 @@ static struct { } format_info[] = { {VIDEO_CS_601, - 0.114f, 0.299f, {16, 16, 16}, {235, 240, 240}, - {{16, 128, 128}, {0, 128, 128}}, + 0.114f, + 0.299f, + {16, 16, 16}, + {235, 240, 240}, + {{16, 128, 128}, {0, 128, 128}}, #ifndef COMPUTE_MATRICES - { 16.0f/255.0f, 16.0f/255.0f, 16.0f/255.0f}, - {235.0f/255.0f, 240.0f/255.0f, 240.0f/255.0f}, - { - { - 1.164384f, 0.000000f, 1.596027f, -0.874202f, - 1.164384f, -0.391762f, -0.812968f, 0.531668f, - 1.164384f, 2.017232f, 0.000000f, -1.085631f, - 0.000000f, 0.000000f, 0.000000f, 1.000000f - }, - { - 1.000000f, 0.000000f, 1.407520f, -0.706520f, - 1.000000f, -0.345491f, -0.716948f, 0.533303f, - 1.000000f, 1.778976f, 0.000000f, -0.892976f, - 0.000000f, 0.000000f, 0.000000f, 1.000000f - } - } + {16.0f / 255.0f, 16.0f / 255.0f, 16.0f / 255.0f}, + {235.0f / 255.0f, 240.0f / 255.0f, 240.0f / 255.0f}, + {{1.164384f, 0.000000f, 1.596027f, -0.874202f, 1.164384f, -0.391762f, + -0.812968f, 0.531668f, 1.164384f, 2.017232f, 0.000000f, -1.085631f, + 0.000000f, 0.000000f, 0.000000f, 1.000000f}, + {1.000000f, 0.000000f, 1.407520f, -0.706520f, 1.000000f, -0.345491f, + -0.716948f, 0.533303f, 1.000000f, 1.778976f, 0.000000f, -0.892976f, + 0.000000f, 0.000000f, 0.000000f, 1.000000f}} #endif }, {VIDEO_CS_709, - 0.0722f, 0.2126f, {16, 16, 16}, {235, 240, 240}, - {{16, 128, 128}, {0, 128, 128}}, + 0.0722f, + 0.2126f, + {16, 16, 16}, + {235, 240, 240}, + {{16, 128, 128}, {0, 128, 128}}, #ifndef COMPUTE_MATRICES - { 16.0f/255.0f, 16.0f/255.0f, 16.0f/255.0f}, - {235.0f/255.0f, 240.0f/255.0f, 240.0f/255.0f}, - { - { - 1.164384f, 0.000000f, 1.792741f, -0.972945f, - 1.164384f, -0.213249f, -0.532909f, 0.301483f, - 1.164384f, 2.112402f, 0.000000f, -1.133402f, - 0.000000f, 0.000000f, 0.000000f, 1.000000f - }, - { - 1.000000f, 0.000000f, 1.581000f, -0.793600f, - 1.000000f, -0.188062f, -0.469967f, 0.330305f, - 1.000000f, 1.862906f, 0.000000f, -0.935106f, - 0.000000f, 0.000000f, 0.000000f, 1.000000f - } - } + {16.0f / 255.0f, 16.0f / 255.0f, 16.0f / 255.0f}, + {235.0f / 255.0f, 240.0f / 255.0f, 240.0f / 255.0f}, + {{1.164384f, 0.000000f, 1.792741f, -0.972945f, 1.164384f, -0.213249f, + -0.532909f, 0.301483f, 1.164384f, 2.112402f, 0.000000f, -1.133402f, + 0.000000f, 0.000000f, 0.000000f, 1.000000f}, + {1.000000f, 0.000000f, 1.581000f, -0.793600f, 1.000000f, -0.188062f, + -0.469967f, 0.330305f, 1.000000f, 1.862906f, 0.000000f, -0.935106f, + 0.000000f, 0.000000f, 0.000000f, 1.000000f}} #endif }, }; -#define NUM_FORMATS (sizeof(format_info)/sizeof(format_info[0])) +#define NUM_FORMATS (sizeof(format_info) / sizeof(format_info[0])) #ifdef COMPUTE_MATRICES static void log_matrix(float const matrix[16]) { - blog(LOG_DEBUG, "\n% f, % f, % f, % f" \ - "\n% f, % f, % f, % f" \ - "\n% f, % f, % f, % f" \ - "\n% f, % f, % f, % f", - matrix[ 0], matrix[ 1], matrix[ 2], matrix[ 3], - matrix[ 4], matrix[ 5], matrix[ 6], matrix[ 7], - matrix[ 8], matrix[ 9], matrix[10], matrix[11], - matrix[12], matrix[13], matrix[14], matrix[15]); + blog(LOG_DEBUG, + "\n% f, % f, % f, % f" + "\n% f, % f, % f, % f" + "\n% f, % f, % f, % f" + "\n% f, % f, % f, % f", + matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], + matrix[6], matrix[7], matrix[8], matrix[9], matrix[10], matrix[11], + matrix[12], matrix[13], matrix[14], matrix[15]); } static void initialize_matrix(float const Kb, float const Kr, - int const range_min[3], int const range_max[3], - int const black_levels[3], float matrix[16]) + int const range_min[3], int const range_max[3], + int const black_levels[3], float matrix[16]) { struct matrix3 color_matrix; @@ -107,35 +97,29 @@ static void initialize_matrix(float const Kb, float const Kr, int uvals = (range_max[1] - range_min[1]) / 2; int vvals = (range_max[2] - range_min[2]) / 2; - vec3_set(&color_matrix.x, 255./yvals, - 0., - 255./vvals * (1. - Kr)); - vec3_set(&color_matrix.y, 255./yvals, - 255./uvals * (Kb - 1.) * Kb / (1. - Kb - Kr), - 255./vvals * (Kr - 1.) * Kr / (1. - Kb - Kr)); - vec3_set(&color_matrix.z, 255./yvals, - 255./uvals * (1. - Kb), - 0.); + vec3_set(&color_matrix.x, 255. / yvals, 0., 255. / vvals * (1. - Kr)); + vec3_set(&color_matrix.y, 255. / yvals, + 255. / uvals * (Kb - 1.) * Kb / (1. - Kb - Kr), + 255. / vvals * (Kr - 1.) * Kr / (1. - Kb - Kr)); + vec3_set(&color_matrix.z, 255. / yvals, 255. / uvals * (1. - Kb), 0.); struct vec3 offsets, multiplied; - vec3_set(&offsets, - -black_levels[0]/255., - -black_levels[1]/255., - -black_levels[2]/255.); + vec3_set(&offsets, -black_levels[0] / 255., -black_levels[1] / 255., + -black_levels[2] / 255.); vec3_rotate(&multiplied, &offsets, &color_matrix); - matrix[ 0] = color_matrix.x.x; - matrix[ 1] = color_matrix.x.y; - matrix[ 2] = color_matrix.x.z; - matrix[ 3] = multiplied.x; + matrix[0] = color_matrix.x.x; + matrix[1] = color_matrix.x.y; + matrix[2] = color_matrix.x.z; + matrix[3] = multiplied.x; - matrix[ 4] = color_matrix.y.x; - matrix[ 5] = color_matrix.y.y; - matrix[ 6] = color_matrix.y.z; - matrix[ 7] = multiplied.y; + matrix[4] = color_matrix.y.x; + matrix[5] = color_matrix.y.y; + matrix[6] = color_matrix.y.z; + matrix[7] = multiplied.y; - matrix[ 8] = color_matrix.z.x; - matrix[ 9] = color_matrix.z.y; + matrix[8] = color_matrix.z.x; + matrix[9] = color_matrix.z.y; matrix[10] = color_matrix.z.z; matrix[11] = multiplied.z; @@ -147,26 +131,26 @@ static void initialize_matrix(float const Kb, float const Kr, static void initialize_matrices() { - static int range_min[] = { 0, 0, 0}; + static int range_min[] = {0, 0, 0}; static int range_max[] = {255, 255, 255}; for (size_t i = 0; i < NUM_FORMATS; i++) { initialize_matrix(format_info[i].Kb, format_info[i].Kr, - range_min, range_max, - format_info[i].black_levels[1], - format_info[i].matrix[1]); + range_min, range_max, + format_info[i].black_levels[1], + format_info[i].matrix[1]); initialize_matrix(format_info[i].Kb, format_info[i].Kr, - format_info[i].range_min, - format_info[i].range_max, - format_info[i].black_levels[0], - format_info[i].matrix[0]); + format_info[i].range_min, + format_info[i].range_max, + format_info[i].black_levels[0], + format_info[i].matrix[0]); for (int j = 0; j < 3; j++) { format_info[i].float_range_min[j] = - format_info[i].range_min[j]/255.; + format_info[i].range_min[j] / 255.; format_info[i].float_range_max[j] = - format_info[i].range_max[j]/255.; + format_info[i].range_max[j] / 255.; } } } @@ -178,8 +162,8 @@ static const float full_min[3] = {0.0f, 0.0f, 0.0f}; static const float full_max[3] = {1.0f, 1.0f, 1.0f}; bool video_format_get_parameters(enum video_colorspace color_space, - enum video_range_type range, float matrix[16], - float range_min[3], float range_max[3]) + enum video_range_type range, float matrix[16], + float range_min[3], float range_max[3]) { #ifdef COMPUTE_MATRICES if (!matrices_initialized) { @@ -196,7 +180,7 @@ bool video_format_get_parameters(enum video_colorspace color_space, int full_range = range == VIDEO_RANGE_FULL ? 1 : 0; memcpy(matrix, format_info[i].matrix[full_range], - sizeof(float) * 16); + sizeof(float) * 16); if (range == VIDEO_RANGE_FULL) { if (range_min) @@ -208,11 +192,11 @@ bool video_format_get_parameters(enum video_colorspace color_space, if (range_min) memcpy(range_min, format_info[i].float_range_min, - sizeof(float) * 3); + sizeof(float) * 3); if (range_max) memcpy(range_max, format_info[i].float_range_max, - sizeof(float) * 3); + sizeof(float) * 3); return true; } diff --git a/libobs/media-io/video-scaler-ffmpeg.c b/libobs/media-io/video-scaler-ffmpeg.c index e46aa4e..5ee389c 100644 --- a/libobs/media-io/video-scaler-ffmpeg.c +++ b/libobs/media-io/video-scaler-ffmpeg.c @@ -25,21 +25,43 @@ struct video_scaler { int src_height; }; -static inline enum AVPixelFormat get_ffmpeg_video_format( - enum video_format format) +static inline enum AVPixelFormat +get_ffmpeg_video_format(enum video_format format) { switch (format) { - case VIDEO_FORMAT_NONE: return AV_PIX_FMT_NONE; - case VIDEO_FORMAT_I420: return AV_PIX_FMT_YUV420P; - case VIDEO_FORMAT_NV12: return AV_PIX_FMT_NV12; - case VIDEO_FORMAT_YVYU: return AV_PIX_FMT_NONE; - case VIDEO_FORMAT_YUY2: return AV_PIX_FMT_YUYV422; - case VIDEO_FORMAT_UYVY: return AV_PIX_FMT_UYVY422; - case VIDEO_FORMAT_RGBA: return AV_PIX_FMT_RGBA; - case VIDEO_FORMAT_BGRA: return AV_PIX_FMT_BGRA; - case VIDEO_FORMAT_BGRX: return AV_PIX_FMT_BGRA; - case VIDEO_FORMAT_Y800: return AV_PIX_FMT_GRAY8; - case VIDEO_FORMAT_I444: return AV_PIX_FMT_YUV444P; + case VIDEO_FORMAT_I420: + return AV_PIX_FMT_YUV420P; + case VIDEO_FORMAT_NV12: + return AV_PIX_FMT_NV12; + case VIDEO_FORMAT_YUY2: + return AV_PIX_FMT_YUYV422; + case VIDEO_FORMAT_UYVY: + return AV_PIX_FMT_UYVY422; + case VIDEO_FORMAT_RGBA: + return AV_PIX_FMT_RGBA; + case VIDEO_FORMAT_BGRA: + return AV_PIX_FMT_BGRA; + case VIDEO_FORMAT_BGRX: + return AV_PIX_FMT_BGRA; + case VIDEO_FORMAT_Y800: + return AV_PIX_FMT_GRAY8; + case VIDEO_FORMAT_I444: + return AV_PIX_FMT_YUV444P; + case VIDEO_FORMAT_BGR3: + return AV_PIX_FMT_BGR24; + case VIDEO_FORMAT_I422: + return AV_PIX_FMT_YUV422P; + case VIDEO_FORMAT_I40A: + return AV_PIX_FMT_YUVA420P; + case VIDEO_FORMAT_I42A: + return AV_PIX_FMT_YUVA422P; + case VIDEO_FORMAT_YUVA: + return AV_PIX_FMT_YUVA444P; + case VIDEO_FORMAT_NONE: + case VIDEO_FORMAT_YVYU: + case VIDEO_FORMAT_AYUV: + /* not supported by FFmpeg */ + return AV_PIX_FMT_NONE; } return AV_PIX_FMT_NONE; @@ -48,11 +70,16 @@ static inline enum AVPixelFormat get_ffmpeg_video_format( static inline int get_ffmpeg_scale_type(enum video_scale_type type) { switch (type) { - case VIDEO_SCALE_DEFAULT: return SWS_FAST_BILINEAR; - case VIDEO_SCALE_POINT: return SWS_POINT; - case VIDEO_SCALE_FAST_BILINEAR: return SWS_FAST_BILINEAR; - case VIDEO_SCALE_BILINEAR: return SWS_BILINEAR | SWS_AREA; - case VIDEO_SCALE_BICUBIC: return SWS_BICUBIC; + case VIDEO_SCALE_DEFAULT: + return SWS_FAST_BILINEAR; + case VIDEO_SCALE_POINT: + return SWS_POINT; + case VIDEO_SCALE_FAST_BILINEAR: + return SWS_FAST_BILINEAR; + case VIDEO_SCALE_BILINEAR: + return SWS_BILINEAR | SWS_AREA; + case VIDEO_SCALE_BICUBIC: + return SWS_BICUBIC; } return SWS_POINT; @@ -61,9 +88,12 @@ static inline int get_ffmpeg_scale_type(enum video_scale_type type) static inline const int *get_ffmpeg_coeffs(enum video_colorspace cs) { switch (cs) { - case VIDEO_CS_DEFAULT: return sws_getCoefficients(SWS_CS_ITU601); - case VIDEO_CS_601: return sws_getCoefficients(SWS_CS_ITU601); - case VIDEO_CS_709: return sws_getCoefficients(SWS_CS_ITU709); + case VIDEO_CS_DEFAULT: + return sws_getCoefficients(SWS_CS_ITU601); + case VIDEO_CS_601: + return sws_getCoefficients(SWS_CS_ITU601); + case VIDEO_CS_709: + return sws_getCoefficients(SWS_CS_ITU709); } return sws_getCoefficients(SWS_CS_ITU601); @@ -72,58 +102,59 @@ static inline const int *get_ffmpeg_coeffs(enum video_colorspace cs) static inline int get_ffmpeg_range_type(enum video_range_type type) { switch (type) { - case VIDEO_RANGE_DEFAULT: return 0; - case VIDEO_RANGE_PARTIAL: return 0; - case VIDEO_RANGE_FULL: return 1; + case VIDEO_RANGE_DEFAULT: + return 0; + case VIDEO_RANGE_PARTIAL: + return 0; + case VIDEO_RANGE_FULL: + return 1; } return 0; } -#define FIXED_1_0 (1<<16) +#define FIXED_1_0 (1 << 16) int video_scaler_create(video_scaler_t **scaler_out, - const struct video_scale_info *dst, - const struct video_scale_info *src, - enum video_scale_type type) + const struct video_scale_info *dst, + const struct video_scale_info *src, + enum video_scale_type type) { enum AVPixelFormat format_src = get_ffmpeg_video_format(src->format); enum AVPixelFormat format_dst = get_ffmpeg_video_format(dst->format); - int scale_type = get_ffmpeg_scale_type(type); - const int *coeff_src = get_ffmpeg_coeffs(src->colorspace); - const int *coeff_dst = get_ffmpeg_coeffs(dst->colorspace); - int range_src = get_ffmpeg_range_type(src->range); - int range_dst = get_ffmpeg_range_type(dst->range); + int scale_type = get_ffmpeg_scale_type(type); + const int *coeff_src = get_ffmpeg_coeffs(src->colorspace); + const int *coeff_dst = get_ffmpeg_coeffs(dst->colorspace); + int range_src = get_ffmpeg_range_type(src->range); + int range_dst = get_ffmpeg_range_type(dst->range); struct video_scaler *scaler; int ret; if (!scaler_out) return VIDEO_SCALER_FAILED; - if (format_src == AV_PIX_FMT_NONE || - format_dst == AV_PIX_FMT_NONE) + if (format_src == AV_PIX_FMT_NONE || format_dst == AV_PIX_FMT_NONE) return VIDEO_SCALER_BAD_CONVERSION; scaler = bzalloc(sizeof(struct video_scaler)); scaler->src_height = src->height; - scaler->swscale = sws_getCachedContext(NULL, - src->width, src->height, format_src, - dst->width, dst->height, format_dst, - scale_type, NULL, NULL, NULL); + scaler->swscale = sws_getCachedContext(NULL, src->width, src->height, + format_src, dst->width, + dst->height, format_dst, + scale_type, NULL, NULL, NULL); if (!scaler->swscale) { blog(LOG_ERROR, "video_scaler_create: Could not create " - "swscale"); + "swscale"); goto fail; } - ret = sws_setColorspaceDetails(scaler->swscale, - coeff_src, range_src, - coeff_dst, range_dst, - 0, FIXED_1_0, FIXED_1_0); + ret = sws_setColorspaceDetails(scaler->swscale, coeff_src, range_src, + coeff_dst, range_dst, 0, FIXED_1_0, + FIXED_1_0); if (ret < 0) { blog(LOG_DEBUG, "video_scaler_create: " - "sws_setColorspaceDetails failed, ignoring"); + "sws_setColorspaceDetails failed, ignoring"); } *scaler_out = scaler; @@ -142,20 +173,20 @@ void video_scaler_destroy(video_scaler_t *scaler) } } -bool video_scaler_scale(video_scaler_t *scaler, - uint8_t *output[], const uint32_t out_linesize[], - const uint8_t *const input[], const uint32_t in_linesize[]) +bool video_scaler_scale(video_scaler_t *scaler, uint8_t *output[], + const uint32_t out_linesize[], + const uint8_t *const input[], + const uint32_t in_linesize[]) { if (!scaler) return false; - int ret = sws_scale(scaler->swscale, - input, (const int *)in_linesize, - 0, scaler->src_height, - output, (const int *)out_linesize); + int ret = sws_scale(scaler->swscale, input, (const int *)in_linesize, 0, + scaler->src_height, output, + (const int *)out_linesize); if (ret <= 0) { blog(LOG_ERROR, "video_scaler_scale: sws_scale failed: %d", - ret); + ret); return false; } diff --git a/libobs/media-io/video-scaler.h b/libobs/media-io/video-scaler.h index dd1630c..de56de1 100644 --- a/libobs/media-io/video-scaler.h +++ b/libobs/media-io/video-scaler.h @@ -27,19 +27,20 @@ extern "C" { struct video_scaler; typedef struct video_scaler video_scaler_t; -#define VIDEO_SCALER_SUCCESS 0 +#define VIDEO_SCALER_SUCCESS 0 #define VIDEO_SCALER_BAD_CONVERSION -1 -#define VIDEO_SCALER_FAILED -2 +#define VIDEO_SCALER_FAILED -2 EXPORT int video_scaler_create(video_scaler_t **scaler, - const struct video_scale_info *dst, - const struct video_scale_info *src, - enum video_scale_type type); + const struct video_scale_info *dst, + const struct video_scale_info *src, + enum video_scale_type type); EXPORT void video_scaler_destroy(video_scaler_t *scaler); -EXPORT bool video_scaler_scale(video_scaler_t *scaler, - uint8_t *output[], const uint32_t out_linesize[], - const uint8_t *const input[], const uint32_t in_linesize[]); +EXPORT bool video_scaler_scale(video_scaler_t *scaler, uint8_t *output[], + const uint32_t out_linesize[], + const uint8_t *const input[], + const uint32_t in_linesize[]); #ifdef __cplusplus } diff --git a/libobs/obs-audio-controls.c b/libobs/obs-audio-controls.c index 2808165..81803ad 100644 --- a/libobs/obs-audio-controls.c +++ b/libobs/obs-audio-controls.c @@ -38,45 +38,45 @@ along with this program. If not, see . typedef float (*obs_fader_conversion_t)(const float val); struct fader_cb { - obs_fader_changed_t callback; - void *param; + obs_fader_changed_t callback; + void *param; }; struct obs_fader { - pthread_mutex_t mutex; + pthread_mutex_t mutex; obs_fader_conversion_t def_to_db; obs_fader_conversion_t db_to_def; - obs_source_t *source; - enum obs_fader_type type; - float max_db; - float min_db; - float cur_db; - bool ignore_next_signal; + obs_source_t *source; + enum obs_fader_type type; + float max_db; + float min_db; + float cur_db; + bool ignore_next_signal; - pthread_mutex_t callback_mutex; - DARRAY(struct fader_cb)callbacks; + pthread_mutex_t callback_mutex; + DARRAY(struct fader_cb) callbacks; }; struct meter_cb { obs_volmeter_updated_t callback; - void *param; + void *param; }; struct obs_volmeter { - pthread_mutex_t mutex; - obs_source_t *source; - enum obs_fader_type type; - float cur_db; + pthread_mutex_t mutex; + obs_source_t *source; + enum obs_fader_type type; + float cur_db; - pthread_mutex_t callback_mutex; - DARRAY(struct meter_cb) callbacks; + pthread_mutex_t callback_mutex; + DARRAY(struct meter_cb) callbacks; - enum obs_peak_meter_type peak_meter_type; - unsigned int update_ms; - float prev_samples[MAX_AUDIO_CHANNELS][4]; + enum obs_peak_meter_type peak_meter_type; + unsigned int update_ms; + float prev_samples[MAX_AUDIO_CHANNELS][4]; - float magnitude[MAX_AUDIO_CHANNELS]; - float peak[MAX_AUDIO_CHANNELS]; + float magnitude[MAX_AUDIO_CHANNELS]; + float peak[MAX_AUDIO_CHANNELS]; }; static float cubic_def_to_db(const float def) @@ -157,12 +157,12 @@ static float iec_db_to_def(const float db) return def; } -#define LOG_OFFSET_DB 6.0f -#define LOG_RANGE_DB 96.0f +#define LOG_OFFSET_DB 6.0f +#define LOG_RANGE_DB 96.0f /* equals -log10f(LOG_OFFSET_DB) */ #define LOG_OFFSET_VAL -0.77815125038364363f /* equals -log10f(-LOG_RANGE_DB + LOG_OFFSET_DB) */ -#define LOG_RANGE_VAL -2.00860017176191756f +#define LOG_RANGE_VAL -2.00860017176191756f static float log_def_to_db(const float def) { @@ -171,9 +171,10 @@ static float log_def_to_db(const float def) else if (def <= 0.0f) return -INFINITY; - return -(LOG_RANGE_DB + LOG_OFFSET_DB) * powf( - (LOG_RANGE_DB + LOG_OFFSET_DB) / LOG_OFFSET_DB, -def) - + LOG_OFFSET_DB; + return -(LOG_RANGE_DB + LOG_OFFSET_DB) * + powf((LOG_RANGE_DB + LOG_OFFSET_DB) / LOG_OFFSET_DB, + -def) + + LOG_OFFSET_DB; } static float log_db_to_def(const float db) @@ -183,8 +184,8 @@ static float log_db_to_def(const float db) else if (db <= -96.0f) return 0.0f; - return (-log10f(-db + LOG_OFFSET_DB) - LOG_RANGE_VAL) - / (LOG_OFFSET_VAL - LOG_RANGE_VAL); + return (-log10f(-db + LOG_OFFSET_DB) - LOG_RANGE_VAL) / + (LOG_OFFSET_VAL - LOG_RANGE_VAL); } static void signal_volume_changed(struct obs_fader *fader, const float db) @@ -198,9 +199,9 @@ static void signal_volume_changed(struct obs_fader *fader, const float db) } static void signal_levels_updated(struct obs_volmeter *volmeter, - const float magnitude[MAX_AUDIO_CHANNELS], - const float peak[MAX_AUDIO_CHANNELS], - const float input_peak[MAX_AUDIO_CHANNELS]) + const float magnitude[MAX_AUDIO_CHANNELS], + const float peak[MAX_AUDIO_CHANNELS], + const float input_peak[MAX_AUDIO_CHANNELS]) { pthread_mutex_lock(&volmeter->callback_mutex); for (size_t i = volmeter->callbacks.num; i > 0; i--) { @@ -212,7 +213,7 @@ static void signal_levels_updated(struct obs_volmeter *volmeter, static void fader_source_volume_changed(void *vptr, calldata_t *calldata) { - struct obs_fader *fader = (struct obs_fader *) vptr; + struct obs_fader *fader = (struct obs_fader *)vptr; pthread_mutex_lock(&fader->mutex); @@ -222,9 +223,9 @@ static void fader_source_volume_changed(void *vptr, calldata_t *calldata) return; } - const float mul = (float)calldata_float(calldata, "volume"); - const float db = mul_to_db(mul); - fader->cur_db = db; + const float mul = (float)calldata_float(calldata, "volume"); + const float db = mul_to_db(mul); + fader->cur_db = db; pthread_mutex_unlock(&fader->mutex); @@ -233,11 +234,11 @@ static void fader_source_volume_changed(void *vptr, calldata_t *calldata) static void volmeter_source_volume_changed(void *vptr, calldata_t *calldata) { - struct obs_volmeter *volmeter = (struct obs_volmeter *) vptr; + struct obs_volmeter *volmeter = (struct obs_volmeter *)vptr; pthread_mutex_lock(&volmeter->mutex); - float mul = (float) calldata_float(calldata, "volume"); + float mul = (float)calldata_float(calldata, "volume"); volmeter->cur_db = mul_to_db(mul); pthread_mutex_unlock(&volmeter->mutex); @@ -246,7 +247,7 @@ static void volmeter_source_volume_changed(void *vptr, calldata_t *calldata) static void fader_source_destroyed(void *vptr, calldata_t *calldata) { UNUSED_PARAMETER(calldata); - struct obs_fader *fader = (struct obs_fader *) vptr; + struct obs_fader *fader = (struct obs_fader *)vptr; obs_fader_detach_source(fader); } @@ -254,7 +255,7 @@ static void fader_source_destroyed(void *vptr, calldata_t *calldata) static void volmeter_source_destroyed(void *vptr, calldata_t *calldata) { UNUSED_PARAMETER(calldata); - struct obs_volmeter *volmeter = (struct obs_volmeter *) vptr; + struct obs_volmeter *volmeter = (struct obs_volmeter *)vptr; obs_volmeter_detach_source(volmeter); } @@ -271,43 +272,44 @@ static int get_nr_channels_from_audio_data(const struct audio_data *data) /* msb(h, g, f, e) lsb(d, c, b, a) --> msb(h, h, g, f) lsb(e, d, c, b) */ -#define SHIFT_RIGHT_2PS(msb, lsb) {\ - __m128 tmp = _mm_shuffle_ps(lsb, msb, _MM_SHUFFLE(0, 0, 3, 3));\ - lsb = _mm_shuffle_ps(lsb, tmp, _MM_SHUFFLE(2, 1, 2, 1));\ - msb = _mm_shuffle_ps(msb, msb, _MM_SHUFFLE(3, 3, 2, 1));\ -} +#define SHIFT_RIGHT_2PS(msb, lsb) \ + { \ + __m128 tmp = \ + _mm_shuffle_ps(lsb, msb, _MM_SHUFFLE(0, 0, 3, 3)); \ + lsb = _mm_shuffle_ps(lsb, tmp, _MM_SHUFFLE(2, 1, 2, 1)); \ + msb = _mm_shuffle_ps(msb, msb, _MM_SHUFFLE(3, 3, 2, 1)); \ + } /* x(d, c, b, a) --> (|d|, |c|, |b|, |a|) */ -#define abs_ps(v) \ - _mm_andnot_ps(_mm_set1_ps(-0.f), v) +#define abs_ps(v) _mm_andnot_ps(_mm_set1_ps(-0.f), v) /* Take cross product of a vector with a matrix resulting in vector. */ -#define VECTOR_MATRIX_CROSS_PS(out, v, m0, m1, m2, m3) \ -{\ - out = _mm_mul_ps(v, m0);\ - __m128 mul1 = _mm_mul_ps(v, m1);\ - __m128 mul2 = _mm_mul_ps(v, m2);\ - __m128 mul3 = _mm_mul_ps(v, m3);\ -\ - _MM_TRANSPOSE4_PS(out, mul1, mul2, mul3);\ -\ - out = _mm_add_ps(out, mul1);\ - out = _mm_add_ps(out, mul2);\ - out = _mm_add_ps(out, mul3);\ -} +#define VECTOR_MATRIX_CROSS_PS(out, v, m0, m1, m2, m3) \ + { \ + out = _mm_mul_ps(v, m0); \ + __m128 mul1 = _mm_mul_ps(v, m1); \ + __m128 mul2 = _mm_mul_ps(v, m2); \ + __m128 mul3 = _mm_mul_ps(v, m3); \ + \ + _MM_TRANSPOSE4_PS(out, mul1, mul2, mul3); \ + \ + out = _mm_add_ps(out, mul1); \ + out = _mm_add_ps(out, mul2); \ + out = _mm_add_ps(out, mul3); \ + } /* x4(d, c, b, a) --> max(a, b, c, d) */ -#define hmax_ps(r, x4) \ - do { \ - float x4_mem[4]; \ +#define hmax_ps(r, x4) \ + do { \ + float x4_mem[4]; \ _mm_storeu_ps(x4_mem, x4); \ - r = x4_mem[0]; \ - r = fmaxf(r, x4_mem[1]); \ - r = fmaxf(r, x4_mem[2]); \ - r = fmaxf(r, x4_mem[3]); \ + r = x4_mem[0]; \ + r = fmaxf(r, x4_mem[1]); \ + r = fmaxf(r, x4_mem[2]); \ + r = fmaxf(r, x4_mem[3]); \ } while (false) /* Calculate the true peak over a set of samples. @@ -323,15 +325,19 @@ static int get_nr_channels_from_audio_data(const struct audio_data *data) * @returns 5 times oversampled true-peak from the set of samples. */ static float get_true_peak(__m128 previous_samples, const float *samples, - size_t nr_samples) + size_t nr_samples) { /* These are normalized-sinc parameters for interpolating over sample * points which are located at x-coords: -1.5, -0.5, +0.5, +1.5. * And oversample points at x-coords: -0.3, -0.1, 0.1, 0.3. */ - const __m128 m3 = _mm_set_ps(-0.155915f, 0.935489f, 0.233872f, -0.103943f); - const __m128 m1 = _mm_set_ps(-0.216236f, 0.756827f, 0.504551f, -0.189207f); - const __m128 p1 = _mm_set_ps(-0.189207f, 0.504551f, 0.756827f, -0.216236f); - const __m128 p3 = _mm_set_ps(-0.103943f, 0.233872f, 0.935489f, -0.155915f); + const __m128 m3 = + _mm_set_ps(-0.155915f, 0.935489f, 0.233872f, -0.103943f); + const __m128 m1 = + _mm_set_ps(-0.216236f, 0.756827f, 0.504551f, -0.189207f); + const __m128 p1 = + _mm_set_ps(-0.189207f, 0.504551f, 0.756827f, -0.216236f); + const __m128 p3 = + _mm_set_ps(-0.103943f, 0.233872f, 0.935489f, -0.155915f); __m128 work = previous_samples; __m128 peak = previous_samples; @@ -370,7 +376,7 @@ static float get_true_peak(__m128 previous_samples, const float *samples, * over. They will have come from a previous iteration. */ static float get_sample_peak(__m128 previous_samples, const float *samples, - size_t nr_samples) + size_t nr_samples) { __m128 peak = previous_samples; for (size_t i = 0; (i + 3) < nr_samples; i += 4) { @@ -384,7 +390,8 @@ static float get_sample_peak(__m128 previous_samples, const float *samples, } static void volmeter_process_peak_last_samples(obs_volmeter_t *volmeter, - int channel_nr, float *samples, size_t nr_samples) + int channel_nr, float *samples, + size_t nr_samples) { /* Take the last 4 samples that need to be used for the next peak * calculation. If there are less than 4 samples in total the new @@ -395,38 +402,39 @@ static void volmeter_process_peak_last_samples(obs_volmeter_t *volmeter, break; case 1: volmeter->prev_samples[channel_nr][0] = - volmeter->prev_samples[channel_nr][1]; + volmeter->prev_samples[channel_nr][1]; volmeter->prev_samples[channel_nr][1] = - volmeter->prev_samples[channel_nr][2]; + volmeter->prev_samples[channel_nr][2]; volmeter->prev_samples[channel_nr][2] = - volmeter->prev_samples[channel_nr][3]; - volmeter->prev_samples[channel_nr][3] = samples[nr_samples-1]; + volmeter->prev_samples[channel_nr][3]; + volmeter->prev_samples[channel_nr][3] = samples[nr_samples - 1]; break; case 2: volmeter->prev_samples[channel_nr][0] = - volmeter->prev_samples[channel_nr][2]; + volmeter->prev_samples[channel_nr][2]; volmeter->prev_samples[channel_nr][1] = - volmeter->prev_samples[channel_nr][3]; - volmeter->prev_samples[channel_nr][2] = samples[nr_samples-2]; - volmeter->prev_samples[channel_nr][3] = samples[nr_samples-1]; + volmeter->prev_samples[channel_nr][3]; + volmeter->prev_samples[channel_nr][2] = samples[nr_samples - 2]; + volmeter->prev_samples[channel_nr][3] = samples[nr_samples - 1]; break; case 3: volmeter->prev_samples[channel_nr][0] = - volmeter->prev_samples[channel_nr][3]; - volmeter->prev_samples[channel_nr][1] = samples[nr_samples-3]; - volmeter->prev_samples[channel_nr][2] = samples[nr_samples-2]; - volmeter->prev_samples[channel_nr][3] = samples[nr_samples-1]; + volmeter->prev_samples[channel_nr][3]; + volmeter->prev_samples[channel_nr][1] = samples[nr_samples - 3]; + volmeter->prev_samples[channel_nr][2] = samples[nr_samples - 2]; + volmeter->prev_samples[channel_nr][3] = samples[nr_samples - 1]; break; default: - volmeter->prev_samples[channel_nr][0] = samples[nr_samples-4]; - volmeter->prev_samples[channel_nr][1] = samples[nr_samples-3]; - volmeter->prev_samples[channel_nr][2] = samples[nr_samples-2]; - volmeter->prev_samples[channel_nr][3] = samples[nr_samples-1]; + volmeter->prev_samples[channel_nr][0] = samples[nr_samples - 4]; + volmeter->prev_samples[channel_nr][1] = samples[nr_samples - 3]; + volmeter->prev_samples[channel_nr][2] = samples[nr_samples - 2]; + volmeter->prev_samples[channel_nr][3] = samples[nr_samples - 1]; } } static void volmeter_process_peak(obs_volmeter_t *volmeter, - const struct audio_data *data, int nr_channels) + const struct audio_data *data, + int nr_channels) { int nr_samples = data->frames; int channel_nr = 0; @@ -437,8 +445,8 @@ static void volmeter_process_peak(obs_volmeter_t *volmeter, } if (((uintptr_t)samples & 0xf) > 0) { printf("Audio plane %i is not aligned %p skipping " - "peak volume measurement.\n", - plane_nr, samples); + "peak volume measurement.\n", + plane_nr, samples); volmeter->peak[channel_nr] = 1.0; channel_nr++; continue; @@ -446,26 +454,25 @@ static void volmeter_process_peak(obs_volmeter_t *volmeter, /* volmeter->prev_samples may not be aligned to 16 bytes; * use unaligned load. */ - __m128 previous_samples = _mm_loadu_ps( - volmeter->prev_samples[channel_nr]); + __m128 previous_samples = + _mm_loadu_ps(volmeter->prev_samples[channel_nr]); float peak; switch (volmeter->peak_meter_type) { case TRUE_PEAK_METER: peak = get_true_peak(previous_samples, samples, - nr_samples); + nr_samples); break; case SAMPLE_PEAK_METER: default: peak = get_sample_peak(previous_samples, samples, - nr_samples); + nr_samples); break; - } - volmeter_process_peak_last_samples(volmeter, channel_nr, samples, - nr_samples); + volmeter_process_peak_last_samples(volmeter, channel_nr, + samples, nr_samples); volmeter->peak[channel_nr] = peak; @@ -479,7 +486,8 @@ static void volmeter_process_peak(obs_volmeter_t *volmeter, } static void volmeter_process_magnitude(obs_volmeter_t *volmeter, - const struct audio_data *data, int nr_channels) + const struct audio_data *data, + int nr_channels) { size_t nr_samples = data->frames; @@ -502,7 +510,7 @@ static void volmeter_process_magnitude(obs_volmeter_t *volmeter, } static void volmeter_process_audio_data(obs_volmeter_t *volmeter, - const struct audio_data *data) + const struct audio_data *data) { int nr_channels = get_nr_channels_from_audio_data(data); @@ -511,9 +519,10 @@ static void volmeter_process_audio_data(obs_volmeter_t *volmeter, } static void volmeter_source_data_received(void *vptr, obs_source_t *source, - const struct audio_data *data, bool muted) + const struct audio_data *data, + bool muted) { - struct obs_volmeter *volmeter = (struct obs_volmeter *) vptr; + struct obs_volmeter *volmeter = (struct obs_volmeter *)vptr; float mul; float magnitude[MAX_AUDIO_CHANNELS]; float peak[MAX_AUDIO_CHANNELS]; @@ -527,16 +536,14 @@ static void volmeter_source_data_received(void *vptr, obs_source_t *source, // And convert to dB. mul = muted ? 0.0f : db_to_mul(volmeter->cur_db); for (int channel_nr = 0; channel_nr < MAX_AUDIO_CHANNELS; - channel_nr++) { - magnitude[channel_nr] = mul_to_db( - volmeter->magnitude[channel_nr] * mul); - peak[channel_nr] = mul_to_db( - volmeter->peak[channel_nr] * mul); + channel_nr++) { + magnitude[channel_nr] = + mul_to_db(volmeter->magnitude[channel_nr] * mul); + peak[channel_nr] = mul_to_db(volmeter->peak[channel_nr] * mul); /* The input-peak is NOT adjusted with volume, so that the user * can check the input-gain. */ - input_peak[channel_nr] = mul_to_db( - volmeter->peak[channel_nr]); + input_peak[channel_nr] = mul_to_db(volmeter->peak[channel_nr]); } pthread_mutex_unlock(&volmeter->mutex); @@ -559,24 +566,24 @@ obs_fader_t *obs_fader_create(enum obs_fader_type type) if (pthread_mutex_init(&fader->callback_mutex, NULL) != 0) goto fail; - switch(type) { + switch (type) { case OBS_FADER_CUBIC: fader->def_to_db = cubic_def_to_db; fader->db_to_def = cubic_db_to_def; - fader->max_db = 0.0f; - fader->min_db = -INFINITY; + fader->max_db = 0.0f; + fader->min_db = -INFINITY; break; case OBS_FADER_IEC: fader->def_to_db = iec_def_to_db; fader->db_to_def = iec_db_to_def; - fader->max_db = 0.0f; - fader->min_db = -INFINITY; + fader->max_db = 0.0f; + fader->min_db = -INFINITY; break; case OBS_FADER_LOG: fader->def_to_db = log_def_to_db; fader->db_to_def = log_db_to_def; - fader->max_db = 0.0f; - fader->min_db = -96.0f; + fader->max_db = 0.0f; + fader->min_db = -96.0f; break; default: goto fail; @@ -610,21 +617,21 @@ bool obs_fader_set_db(obs_fader_t *fader, const float db) pthread_mutex_lock(&fader->mutex); - bool clamped = false; + bool clamped = false; fader->cur_db = db; if (fader->cur_db > fader->max_db) { fader->cur_db = fader->max_db; - clamped = true; + clamped = true; } if (fader->cur_db < fader->min_db) { fader->cur_db = -INFINITY; - clamped = true; + clamped = true; } fader->ignore_next_signal = true; - obs_source_t *src = fader->source; - const float mul = db_to_mul(fader->cur_db); + obs_source_t *src = fader->source; + const float mul = db_to_mul(fader->cur_db); pthread_mutex_unlock(&fader->mutex); @@ -697,10 +704,9 @@ bool obs_fader_attach_source(obs_fader_t *fader, obs_source_t *source) obs_fader_detach_source(fader); sh = obs_source_get_signal_handler(source); - signal_handler_connect(sh, "volume", - fader_source_volume_changed, fader); - signal_handler_connect(sh, "destroy", - fader_source_destroyed, fader); + signal_handler_connect(sh, "volume", fader_source_volume_changed, + fader); + signal_handler_connect(sh, "destroy", fader_source_destroyed, fader); vol = obs_source_get_volume(source); pthread_mutex_lock(&fader->mutex); @@ -730,15 +736,13 @@ void obs_fader_detach_source(obs_fader_t *fader) return; sh = obs_source_get_signal_handler(source); - signal_handler_disconnect(sh, "volume", - fader_source_volume_changed, fader); - signal_handler_disconnect(sh, "destroy", - fader_source_destroyed, fader); - + signal_handler_disconnect(sh, "volume", fader_source_volume_changed, + fader); + signal_handler_disconnect(sh, "destroy", fader_source_destroyed, fader); } void obs_fader_add_callback(obs_fader_t *fader, obs_fader_changed_t callback, - void *param) + void *param) { struct fader_cb cb = {callback, param}; @@ -751,7 +755,7 @@ void obs_fader_add_callback(obs_fader_t *fader, obs_fader_changed_t callback, } void obs_fader_remove_callback(obs_fader_t *fader, obs_fader_changed_t callback, - void *param) + void *param) { struct fader_cb cb = {callback, param}; @@ -810,12 +814,12 @@ bool obs_volmeter_attach_source(obs_volmeter_t *volmeter, obs_source_t *source) obs_volmeter_detach_source(volmeter); sh = obs_source_get_signal_handler(source); - signal_handler_connect(sh, "volume", - volmeter_source_volume_changed, volmeter); - signal_handler_connect(sh, "destroy", - volmeter_source_destroyed, volmeter); - obs_source_add_audio_capture_callback(source, - volmeter_source_data_received, volmeter); + signal_handler_connect(sh, "volume", volmeter_source_volume_changed, + volmeter); + signal_handler_connect(sh, "destroy", volmeter_source_destroyed, + volmeter); + obs_source_add_audio_capture_callback( + source, volmeter_source_data_received, volmeter); vol = obs_source_get_volume(source); pthread_mutex_lock(&volmeter->mutex); @@ -845,16 +849,16 @@ void obs_volmeter_detach_source(obs_volmeter_t *volmeter) return; sh = obs_source_get_signal_handler(source); - signal_handler_disconnect(sh, "volume", - volmeter_source_volume_changed, volmeter); - signal_handler_disconnect(sh, "destroy", - volmeter_source_destroyed, volmeter); - obs_source_remove_audio_capture_callback(source, - volmeter_source_data_received, volmeter); + signal_handler_disconnect(sh, "volume", volmeter_source_volume_changed, + volmeter); + signal_handler_disconnect(sh, "destroy", volmeter_source_destroyed, + volmeter); + obs_source_remove_audio_capture_callback( + source, volmeter_source_data_received, volmeter); } void obs_volmeter_set_peak_meter_type(obs_volmeter_t *volmeter, - enum obs_peak_meter_type peak_meter_type) + enum obs_peak_meter_type peak_meter_type) { pthread_mutex_lock(&volmeter->mutex); volmeter->peak_meter_type = peak_meter_type; @@ -862,7 +866,7 @@ void obs_volmeter_set_peak_meter_type(obs_volmeter_t *volmeter, } void obs_volmeter_set_update_interval(obs_volmeter_t *volmeter, - const unsigned int ms) + const unsigned int ms) { if (!volmeter || !ms) return; @@ -907,7 +911,7 @@ int obs_volmeter_get_nr_channels(obs_volmeter_t *volmeter) } void obs_volmeter_add_callback(obs_volmeter_t *volmeter, - obs_volmeter_updated_t callback, void *param) + obs_volmeter_updated_t callback, void *param) { struct meter_cb cb = {callback, param}; @@ -920,7 +924,7 @@ void obs_volmeter_add_callback(obs_volmeter_t *volmeter, } void obs_volmeter_remove_callback(obs_volmeter_t *volmeter, - obs_volmeter_updated_t callback, void *param) + obs_volmeter_updated_t callback, void *param) { struct meter_cb cb = {callback, param}; diff --git a/libobs/obs-audio-controls.h b/libobs/obs-audio-controls.h index c16b32b..9544c1b 100644 --- a/libobs/obs-audio-controls.h +++ b/libobs/obs-audio-controls.h @@ -178,9 +178,10 @@ EXPORT void obs_fader_detach_source(obs_fader_t *fader); typedef void (*obs_fader_changed_t)(void *param, float db); EXPORT void obs_fader_add_callback(obs_fader_t *fader, - obs_fader_changed_t callback, void *param); + obs_fader_changed_t callback, void *param); EXPORT void obs_fader_remove_callback(obs_fader_t *fader, - obs_fader_changed_t callback, void *param); + obs_fader_changed_t callback, + void *param); /** * @brief Create a volume meter @@ -213,7 +214,7 @@ EXPORT void obs_volmeter_destroy(obs_volmeter_t *volmeter); * signal. */ EXPORT bool obs_volmeter_attach_source(obs_volmeter_t *volmeter, - obs_source_t *source); + obs_source_t *source); /** * @brief Detach the volume meter from the currently attached source @@ -226,8 +227,9 @@ EXPORT void obs_volmeter_detach_source(obs_volmeter_t *volmeter); * @param volmeter pointer to the volume meter object * @param peak_meter_type set if true-peak needs to be measured. */ -EXPORT void obs_volmeter_set_peak_meter_type(obs_volmeter_t *volmeter, - enum obs_peak_meter_type peak_meter_type); +EXPORT void +obs_volmeter_set_peak_meter_type(obs_volmeter_t *volmeter, + enum obs_peak_meter_type peak_meter_type); /** * @brief Set the update interval for the volume meter @@ -248,7 +250,7 @@ EXPORT void obs_volmeter_set_peak_meter_type(obs_volmeter_t *volmeter, * circumstances. */ EXPORT void obs_volmeter_set_update_interval(obs_volmeter_t *volmeter, - const unsigned int ms); + const unsigned int ms); /** * @brief Get the update interval currently used for the volume meter @@ -263,15 +265,17 @@ EXPORT unsigned int obs_volmeter_get_update_interval(obs_volmeter_t *volmeter); */ EXPORT int obs_volmeter_get_nr_channels(obs_volmeter_t *volmeter); -typedef void (*obs_volmeter_updated_t)(void *param, - const float magnitude[MAX_AUDIO_CHANNELS], - const float peak[MAX_AUDIO_CHANNELS], - const float input_peak[MAX_AUDIO_CHANNELS]); +typedef void (*obs_volmeter_updated_t)( + void *param, const float magnitude[MAX_AUDIO_CHANNELS], + const float peak[MAX_AUDIO_CHANNELS], + const float input_peak[MAX_AUDIO_CHANNELS]); EXPORT void obs_volmeter_add_callback(obs_volmeter_t *volmeter, - obs_volmeter_updated_t callback, void *param); + obs_volmeter_updated_t callback, + void *param); EXPORT void obs_volmeter_remove_callback(obs_volmeter_t *volmeter, - obs_volmeter_updated_t callback, void *param); + obs_volmeter_updated_t callback, + void *param); EXPORT float obs_mul_to_db(float mul); EXPORT float obs_db_to_mul(float db); diff --git a/libobs/obs-audio.c b/libobs/obs-audio.c index 7bbcc20..c27237e 100644 --- a/libobs/obs-audio.c +++ b/libobs/obs-audio.c @@ -32,7 +32,8 @@ static void push_audio_tree(obs_source_t *parent, obs_source_t *source, void *p) if (da_find(audio->render_order, &source, 0) == DARRAY_INVALID) { obs_source_t *s = obs_source_get_ref(source); - if (s) da_push_back(audio->render_order, &s); + if (s) + da_push_back(audio->render_order, &s); } UNUSED_PARAMETER(parent); @@ -44,8 +45,8 @@ static inline size_t convert_time_to_frames(size_t sample_rate, uint64_t t) } static inline void mix_audio(struct audio_output_data *mixes, - obs_source_t *source, size_t channels, size_t sample_rate, - struct ts_info *ts) + obs_source_t *source, size_t channels, + size_t sample_rate, struct ts_info *ts) { size_t total_floats = AUDIO_OUTPUT_FRAMES; size_t start_point = 0; @@ -54,8 +55,8 @@ static inline void mix_audio(struct audio_output_data *mixes, return; if (source->audio_ts != ts->start) { - start_point = convert_time_to_frames(sample_rate, - source->audio_ts - ts->start); + start_point = convert_time_to_frames( + sample_rate, source->audio_ts - ts->start); if (start_point == AUDIO_OUTPUT_FRAMES) return; @@ -79,18 +80,18 @@ static inline void mix_audio(struct audio_output_data *mixes, } static void ignore_audio(obs_source_t *source, size_t channels, - size_t sample_rate) + size_t sample_rate) { size_t num_floats = source->audio_input_buf[0].size / sizeof(float); if (num_floats) { for (size_t ch = 0; ch < channels; ch++) circlebuf_pop_front(&source->audio_input_buf[ch], NULL, - source->audio_input_buf[ch].size); + source->audio_input_buf[ch].size); source->last_audio_input_buf_size = 0; source->audio_ts += (uint64_t)num_floats * 1000000000ULL / - (uint64_t)sample_rate; + (uint64_t)sample_rate; } } @@ -112,14 +113,14 @@ static bool discard_if_stopped(obs_source_t *source, size_t channels) source->pending_stop = true; #if DEBUG_AUDIO == 1 blog(LOG_DEBUG, "doing pending stop trick: '%s'", - source->context.name); + source->context.name); #endif return true; } for (size_t ch = 0; ch < channels; ch++) circlebuf_pop_front(&source->audio_input_buf[ch], NULL, - source->audio_input_buf[ch].size); + source->audio_input_buf[ch].size); source->pending_stop = false; source->audio_ts = 0; @@ -138,8 +139,8 @@ static bool discard_if_stopped(obs_source_t *source, size_t channels) #define MAX_AUDIO_SIZE (AUDIO_OUTPUT_FRAMES * sizeof(float)) static inline void discard_audio(struct obs_core_audio *audio, - obs_source_t *source, size_t channels, size_t sample_rate, - struct ts_info *ts) + obs_source_t *source, size_t channels, + size_t sample_rate, struct ts_info *ts) { size_t total_floats = AUDIO_OUTPUT_FRAMES; size_t size; @@ -155,10 +156,11 @@ static inline void discard_audio(struct obs_core_audio *audio, if (ts->end <= source->audio_ts) { #if DEBUG_AUDIO == 1 - blog(LOG_DEBUG, "can't discard, source " - "timestamp (%"PRIu64") >= " - "end timestamp (%"PRIu64")", - source->audio_ts, ts->end); + blog(LOG_DEBUG, + "can't discard, source " + "timestamp (%" PRIu64 ") >= " + "end timestamp (%" PRIu64 ")", + source->audio_ts, ts->end); #endif return; } @@ -171,10 +173,11 @@ static inline void discard_audio(struct obs_core_audio *audio, #if DEBUG_AUDIO == 1 if (is_audio_source) { - blog(LOG_DEBUG, "can't discard, source " - "timestamp (%"PRIu64") < " - "start timestamp (%"PRIu64")", - source->audio_ts, ts->start); + blog(LOG_DEBUG, + "can't discard, source " + "timestamp (%" PRIu64 ") < " + "start timestamp (%" PRIu64 ")", + source->audio_ts, ts->start); } #endif if (audio->total_buffering_ticks == MAX_BUFFERING_TICKS) @@ -184,8 +187,8 @@ static inline void discard_audio(struct obs_core_audio *audio, if (source->audio_ts != ts->start && source->audio_ts != (ts->start - 1)) { - size_t start_point = convert_time_to_frames(sample_rate, - source->audio_ts - ts->start); + size_t start_point = convert_time_to_frames( + sample_rate, source->audio_ts - ts->start); if (start_point == AUDIO_OUTPUT_FRAMES) { #if DEBUG_AUDIO == 1 if (is_audio_source) @@ -208,6 +211,7 @@ static inline void discard_audio(struct obs_core_audio *audio, if (is_audio_source) blog(LOG_DEBUG, "can't discard, data still pending"); #endif + source->audio_ts = ts->end; return; } @@ -218,8 +222,7 @@ static inline void discard_audio(struct obs_core_audio *audio, #if DEBUG_AUDIO == 1 if (is_audio_source) - blog(LOG_DEBUG, "audio discarded, new ts: %"PRIu64, - ts->end); + blog(LOG_DEBUG, "audio discarded, new ts: %" PRIu64, ts->end); #endif source->pending_stop = false; @@ -227,8 +230,8 @@ static inline void discard_audio(struct obs_core_audio *audio, } static void add_audio_buffering(struct obs_core_audio *audio, - size_t sample_rate, struct ts_info *ts, uint64_t min_ts, - const char *buffering_name) + size_t sample_rate, struct ts_info *ts, + uint64_t min_ts, const char *buffering_name) { struct ts_info new_ts; uint64_t offset; @@ -257,44 +260,50 @@ static void add_audio_buffering(struct obs_core_audio *audio, ms = ticks * AUDIO_OUTPUT_FRAMES * 1000 / sample_rate; total_ms = audio->total_buffering_ticks * AUDIO_OUTPUT_FRAMES * 1000 / - sample_rate; + sample_rate; - blog(LOG_INFO, "adding %d milliseconds of audio buffering, total " - "audio buffering is now %d milliseconds" - " (source: %s)\n", - (int)ms, (int)total_ms, buffering_name); + blog(LOG_INFO, + "adding %d milliseconds of audio buffering, total " + "audio buffering is now %d milliseconds" + " (source: %s)\n", + (int)ms, (int)total_ms, buffering_name); #if DEBUG_AUDIO == 1 - blog(LOG_DEBUG, "min_ts (%"PRIu64") < start timestamp " - "(%"PRIu64")", min_ts, ts->start); - blog(LOG_DEBUG, "old buffered ts: %"PRIu64"-%"PRIu64, - ts->start, ts->end); + blog(LOG_DEBUG, + "min_ts (%" PRIu64 ") < start timestamp " + "(%" PRIu64 ")", + min_ts, ts->start); + blog(LOG_DEBUG, "old buffered ts: %" PRIu64 "-%" PRIu64, ts->start, + ts->end); #endif - new_ts.start = audio->buffered_ts - audio_frames_to_ns(sample_rate, - audio->buffering_wait_ticks * AUDIO_OUTPUT_FRAMES); + new_ts.start = + audio->buffered_ts - + audio_frames_to_ns(sample_rate, audio->buffering_wait_ticks * + AUDIO_OUTPUT_FRAMES); while (ticks--) { int cur_ticks = ++audio->buffering_wait_ticks; new_ts.end = new_ts.start; - new_ts.start = audio->buffered_ts - audio_frames_to_ns( - sample_rate, - cur_ticks * AUDIO_OUTPUT_FRAMES); + new_ts.start = + audio->buffered_ts - + audio_frames_to_ns(sample_rate, + cur_ticks * AUDIO_OUTPUT_FRAMES); #if DEBUG_AUDIO == 1 - blog(LOG_DEBUG, "add buffered ts: %"PRIu64"-%"PRIu64, - new_ts.start, new_ts.end); + blog(LOG_DEBUG, "add buffered ts: %" PRIu64 "-%" PRIu64, + new_ts.start, new_ts.end); #endif circlebuf_push_front(&audio->buffered_timestamps, &new_ts, - sizeof(new_ts)); + sizeof(new_ts)); } *ts = new_ts; } static bool audio_buffer_insuffient(struct obs_source *source, - size_t sample_rate, uint64_t min_ts) + size_t sample_rate, uint64_t min_ts) { size_t total_floats = AUDIO_OUTPUT_FRAMES; size_t size; @@ -304,10 +313,9 @@ static bool audio_buffer_insuffient(struct obs_source *source, return false; } - if (source->audio_ts != min_ts && - source->audio_ts != (min_ts - 1)) { - size_t start_point = convert_time_to_frames(sample_rate, - source->audio_ts - min_ts); + if (source->audio_ts != min_ts && source->audio_ts != (min_ts - 1)) { + size_t start_point = convert_time_to_frames( + sample_rate, source->audio_ts - min_ts); if (start_point >= AUDIO_OUTPUT_FRAMES) return false; @@ -325,39 +333,39 @@ static bool audio_buffer_insuffient(struct obs_source *source, } static inline const char *find_min_ts(struct obs_core_data *data, - uint64_t *min_ts) + uint64_t *min_ts) { obs_source_t *buffering_source = NULL; struct obs_source *source = data->first_audio_source; while (source) { if (!source->audio_pending && source->audio_ts && - source->audio_ts < *min_ts) { + source->audio_ts < *min_ts) { *min_ts = source->audio_ts; buffering_source = source; } - source = (struct obs_source*)source->next_audio_source; + source = (struct obs_source *)source->next_audio_source; } return buffering_source ? obs_source_get_name(buffering_source) : NULL; } static inline bool mark_invalid_sources(struct obs_core_data *data, - size_t sample_rate, uint64_t min_ts) + size_t sample_rate, uint64_t min_ts) { bool recalculate = false; struct obs_source *source = data->first_audio_source; while (source) { - recalculate |= audio_buffer_insuffient(source, sample_rate, - min_ts); - source = (struct obs_source*)source->next_audio_source; + recalculate |= + audio_buffer_insuffient(source, sample_rate, min_ts); + source = (struct obs_source *)source->next_audio_source; } return recalculate; } static inline const char *calc_min_ts(struct obs_core_data *data, - size_t sample_rate, uint64_t *min_ts) + size_t sample_rate, uint64_t *min_ts) { const char *buffering_name = find_min_ts(data, min_ts); if (mark_invalid_sources(data, sample_rate, *min_ts)) @@ -371,9 +379,9 @@ static inline void release_audio_sources(struct obs_core_audio *audio) obs_source_release(audio->render_order.array[i]); } -bool audio_callback(void *param, - uint64_t start_ts_in, uint64_t end_ts_in, uint64_t *out_ts, - uint32_t mixers, struct audio_output_data *mixes) +bool audio_callback(void *param, uint64_t start_ts_in, uint64_t end_ts_in, + uint64_t *out_ts, uint32_t mixers, + struct audio_output_data *mixes) { struct obs_core_data *data = &obs->data; struct obs_core_audio *audio = &obs->audio; @@ -404,7 +412,7 @@ bool audio_callback(void *param, obs_source_t *source = obs_get_output_source(i); if (source) { obs_source_enum_active_tree(source, push_audio_tree, - audio); + audio); push_audio_tree(NULL, source, audio); da_push_back(audio->root_nodes, &source); obs_source_release(source); @@ -416,7 +424,7 @@ bool audio_callback(void *param, source = data->first_audio_source; while (source) { push_audio_tree(NULL, source, audio); - source = (struct obs_source*)source->next_audio_source; + source = (struct obs_source *)source->next_audio_source; } pthread_mutex_unlock(&data->audio_sources_mutex); @@ -426,7 +434,7 @@ bool audio_callback(void *param, for (size_t i = 0; i < audio->render_order.num; i++) { obs_source_t *source = audio->render_order.array[i]; obs_source_audio_render(source, mixers, channels, sample_rate, - audio_size); + audio_size); } /* ------------------------------------------------ */ @@ -439,7 +447,7 @@ bool audio_callback(void *param, /* if a source has gone backward in time, buffer */ if (min_ts < ts.start) add_audio_buffering(audio, sample_rate, &ts, min_ts, - buffering_name); + buffering_name); /* ------------------------------------------------ */ /* mix audio */ @@ -454,7 +462,7 @@ bool audio_callback(void *param, if (source->audio_output_buf[0][0] && source->audio_ts) mix_audio(mixes, source, channels, sample_rate, - &ts); + &ts); pthread_mutex_unlock(&source->audio_buf_mutex); } @@ -470,7 +478,7 @@ bool audio_callback(void *param, discard_audio(audio, source, channels, sample_rate, &ts); pthread_mutex_unlock(&source->audio_buf_mutex); - source = (struct obs_source*)source->next_audio_source; + source = (struct obs_source *)source->next_audio_source; } pthread_mutex_unlock(&data->audio_sources_mutex); diff --git a/libobs/obs-avc.c b/libobs/obs-avc.c index 8dd6459..424cf88 100644 --- a/libobs/obs-avc.c +++ b/libobs/obs-avc.c @@ -27,7 +27,8 @@ bool obs_avc_keyframe(const uint8_t *data, size_t size) nal_start = obs_avc_find_startcode(data, end); while (true) { - while (nal_start < end && !*(nal_start++)); + while (nal_start < end && !*(nal_start++)) + ; if (nal_start == end) break; @@ -48,7 +49,7 @@ bool obs_avc_keyframe(const uint8_t *data, size_t size) * scenarios that I was unaware of, so instead of just searching for {0, 0, 1} * we'll just use the code from FFmpeg - http://www.ffmpeg.org/ */ static const uint8_t *ff_avc_find_startcode_internal(const uint8_t *p, - const uint8_t *end) + const uint8_t *end) { const uint8_t *a = p + 4 - ((intptr_t)p & 3); @@ -58,21 +59,21 @@ static const uint8_t *ff_avc_find_startcode_internal(const uint8_t *p, } for (end -= 3; p < end; p += 4) { - uint32_t x = *(const uint32_t*)p; + uint32_t x = *(const uint32_t *)p; if ((x - 0x01010101) & (~x) & 0x80808080) { if (p[1] == 0) { if (p[0] == 0 && p[2] == 1) return p; if (p[2] == 0 && p[3] == 1) - return p+1; + return p + 1; } if (p[3] == 0) { if (p[2] == 0 && p[4] == 1) - return p+2; + return p + 2; if (p[4] == 0 && p[5] == 1) - return p+3; + return p + 3; } } } @@ -87,8 +88,9 @@ static const uint8_t *ff_avc_find_startcode_internal(const uint8_t *p, const uint8_t *obs_avc_find_startcode(const uint8_t *p, const uint8_t *end) { - const uint8_t *out= ff_avc_find_startcode_internal(p, end); - if (p < out && out < end && !out[-1]) out--; + const uint8_t *out = ff_avc_find_startcode_internal(p, end); + if (p < out && out < end && !out[-1]) + out--; return out; } @@ -98,15 +100,16 @@ static inline int get_drop_priority(int priority) } static void serialize_avc_data(struct serializer *s, const uint8_t *data, - size_t size, bool *is_keyframe, int *priority) + size_t size, bool *is_keyframe, int *priority) { const uint8_t *nal_start, *nal_end; - const uint8_t *end = data+size; + const uint8_t *end = data + size; int type; nal_start = obs_avc_find_startcode(data, end); while (true) { - while (nal_start < end && !*(nal_start++)); + while (nal_start < end && !*(nal_start++)) + ; if (nal_start == end) break; @@ -128,7 +131,7 @@ static void serialize_avc_data(struct serializer *s, const uint8_t *data, } void obs_parse_avc_packet(struct encoder_packet *avc_packet, - const struct encoder_packet *src) + const struct encoder_packet *src) { struct array_output_data output; struct serializer s; @@ -139,32 +142,32 @@ void obs_parse_avc_packet(struct encoder_packet *avc_packet, serialize(&s, &ref, sizeof(ref)); serialize_avc_data(&s, src->data, src->size, &avc_packet->keyframe, - &avc_packet->priority); + &avc_packet->priority); - avc_packet->data = output.bytes.array + sizeof(ref); - avc_packet->size = output.bytes.num - sizeof(ref); + avc_packet->data = output.bytes.array + sizeof(ref); + avc_packet->size = output.bytes.num - sizeof(ref); avc_packet->drop_priority = get_drop_priority(avc_packet->priority); } static inline bool has_start_code(const uint8_t *data) { if (data[0] != 0 || data[1] != 0) - return false; + return false; return data[2] == 1 || (data[2] == 0 && data[3] == 1); } -static void get_sps_pps(const uint8_t *data, size_t size, - const uint8_t **sps, size_t *sps_size, - const uint8_t **pps, size_t *pps_size) +static void get_sps_pps(const uint8_t *data, size_t size, const uint8_t **sps, + size_t *sps_size, const uint8_t **pps, size_t *pps_size) { const uint8_t *nal_start, *nal_end; - const uint8_t *end = data+size; + const uint8_t *end = data + size; int type; nal_start = obs_avc_find_startcode(data, end); while (true) { - while (nal_start < end && !*(nal_start++)); + while (nal_start < end && !*(nal_start++)) + ; if (nal_start == end) break; @@ -193,7 +196,8 @@ size_t obs_parse_avc_header(uint8_t **header, const uint8_t *data, size_t size) array_output_serializer_init(&s, &output); - if (size <= 6) return 0; + if (size <= 6) + return 0; if (!has_start_code(data)) { *header = bmemdup(data, size); @@ -205,7 +209,7 @@ size_t obs_parse_avc_header(uint8_t **header, const uint8_t *data, size_t size) return 0; s_w8(&s, 0x01); - s_write(&s, sps+1, 3); + s_write(&s, sps + 1, 3); s_w8(&s, 0xff); s_w8(&s, 0xe1); @@ -220,9 +224,9 @@ size_t obs_parse_avc_header(uint8_t **header, const uint8_t *data, size_t size) } void obs_extract_avc_headers(const uint8_t *packet, size_t size, - uint8_t **new_packet_data, size_t *new_packet_size, - uint8_t **header_data, size_t *header_size, - uint8_t **sei_data, size_t *sei_size) + uint8_t **new_packet_data, size_t *new_packet_size, + uint8_t **header_data, size_t *header_size, + uint8_t **sei_data, size_t *sei_size) { DARRAY(uint8_t) new_packet; DARRAY(uint8_t) header; @@ -240,7 +244,8 @@ void obs_extract_avc_headers(const uint8_t *packet, size_t size, while (nal_end != end) { nal_codestart = nal_start; - while (nal_start < end && !*(nal_start++)); + while (nal_start < end && !*(nal_start++)) + ; if (nal_start == end) break; @@ -253,14 +258,14 @@ void obs_extract_avc_headers(const uint8_t *packet, size_t size, if (type == OBS_NAL_SPS || type == OBS_NAL_PPS) { da_push_back_array(header, nal_codestart, - nal_end - nal_codestart); + nal_end - nal_codestart); } else if (type == OBS_NAL_SEI) { da_push_back_array(sei, nal_codestart, - nal_end - nal_codestart); + nal_end - nal_codestart); } else { da_push_back_array(new_packet, nal_codestart, - nal_end - nal_codestart); + nal_end - nal_codestart); } nal_start = nal_end; diff --git a/libobs/obs-avc.h b/libobs/obs-avc.h index afb5ca3..7728911 100644 --- a/libobs/obs-avc.h +++ b/libobs/obs-avc.h @@ -25,40 +25,39 @@ extern "C" { struct encoder_packet; -enum { - OBS_NAL_UNKNOWN = 0, - OBS_NAL_SLICE = 1, - OBS_NAL_SLICE_DPA = 2, - OBS_NAL_SLICE_DPB = 3, - OBS_NAL_SLICE_DPC = 4, - OBS_NAL_SLICE_IDR = 5, - OBS_NAL_SEI = 6, - OBS_NAL_SPS = 7, - OBS_NAL_PPS = 8, - OBS_NAL_AUD = 9, - OBS_NAL_FILLER = 12, +enum { OBS_NAL_UNKNOWN = 0, + OBS_NAL_SLICE = 1, + OBS_NAL_SLICE_DPA = 2, + OBS_NAL_SLICE_DPB = 3, + OBS_NAL_SLICE_DPC = 4, + OBS_NAL_SLICE_IDR = 5, + OBS_NAL_SEI = 6, + OBS_NAL_SPS = 7, + OBS_NAL_PPS = 8, + OBS_NAL_AUD = 9, + OBS_NAL_FILLER = 12, }; -enum { - OBS_NAL_PRIORITY_DISPOSABLE = 0, - OBS_NAL_PRIORITY_LOW = 1, - OBS_NAL_PRIORITY_HIGH = 2, - OBS_NAL_PRIORITY_HIGHEST = 3, +enum { OBS_NAL_PRIORITY_DISPOSABLE = 0, + OBS_NAL_PRIORITY_LOW = 1, + OBS_NAL_PRIORITY_HIGH = 2, + OBS_NAL_PRIORITY_HIGHEST = 3, }; /* Helpers for parsing AVC NAL units. */ EXPORT bool obs_avc_keyframe(const uint8_t *data, size_t size); EXPORT const uint8_t *obs_avc_find_startcode(const uint8_t *p, - const uint8_t *end); + const uint8_t *end); EXPORT void obs_parse_avc_packet(struct encoder_packet *avc_packet, - const struct encoder_packet *src); + const struct encoder_packet *src); EXPORT size_t obs_parse_avc_header(uint8_t **header, const uint8_t *data, - size_t size); + size_t size); EXPORT void obs_extract_avc_headers(const uint8_t *packet, size_t size, - uint8_t **new_packet_data, size_t *new_packet_size, - uint8_t **header_data, size_t *header_size, - uint8_t **sei_data, size_t *sei_size); + uint8_t **new_packet_data, + size_t *new_packet_size, + uint8_t **header_data, size_t *header_size, + uint8_t **sei_data, size_t *sei_size); #ifdef __cplusplus } diff --git a/libobs/obs-cocoa.c b/libobs/obs-cocoa.c index 33a2110..30d0964 100644 --- a/libobs/obs-cocoa.c +++ b/libobs/obs-cocoa.c @@ -45,7 +45,7 @@ static const char *module_data[] = { }; static const int module_patterns_size = - sizeof(module_bin)/sizeof(module_bin[0]); + sizeof(module_bin) / sizeof(module_bin[0]); void add_default_module_paths(void) { @@ -63,9 +63,9 @@ char *find_libobs_data_file(const char *file) static void log_processor_name(void) { - char *name = NULL; + char *name = NULL; size_t size; - int ret; + int ret; ret = sysctlbyname("machdep.cpu.brand_string", NULL, &size, NULL, 0); if (ret != 0) @@ -82,9 +82,9 @@ static void log_processor_name(void) static void log_processor_speed(void) { - size_t size; + size_t size; long long freq; - int ret; + int ret; size = sizeof(freq); ret = sysctlbyname("hw.cpufrequency", &freq, &size, NULL, 0); @@ -95,30 +95,29 @@ static void log_processor_speed(void) static void log_processor_cores(void) { blog(LOG_INFO, "Physical Cores: %d, Logical Cores: %d", - os_get_physical_cores(), os_get_logical_cores()); + os_get_physical_cores(), os_get_logical_cores()); } static void log_available_memory(void) { - size_t size; + size_t size; long long memory_available; - int ret; + int ret; size = sizeof(memory_available); ret = sysctlbyname("hw.memsize", &memory_available, &size, NULL, 0); if (ret == 0) blog(LOG_INFO, "Physical Memory: %lldMB Total", - memory_available / 1024 / 1024); + memory_available / 1024 / 1024); } static void log_os_name(id pi, SEL UTF8String) { - unsigned long os_id = (unsigned long)objc_msgSend(pi, - sel_registerName("operatingSystem")); + unsigned long os_id = (unsigned long)objc_msgSend( + pi, sel_registerName("operatingSystem")); - id os = objc_msgSend(pi, - sel_registerName("operatingSystemName")); - const char *name = (const char*)objc_msgSend(os, UTF8String); + id os = objc_msgSend(pi, sel_registerName("operatingSystemName")); + const char *name = (const char *)objc_msgSend(os, UTF8String); if (os_id == 5 /*NSMACHOperatingSystem*/) { blog(LOG_INFO, "OS Name: Mac OS X (%s)", name); @@ -131,8 +130,8 @@ static void log_os_name(id pi, SEL UTF8String) static void log_os_version(id pi, SEL UTF8String) { id vs = objc_msgSend(pi, - sel_registerName("operatingSystemVersionString")); - const char *version = (const char*)objc_msgSend(vs, UTF8String); + sel_registerName("operatingSystemVersionString")); + const char *version = (const char *)objc_msgSend(vs, UTF8String); blog(LOG_INFO, "OS Version: %s", version ? version : "Unknown"); } @@ -140,8 +139,8 @@ static void log_os_version(id pi, SEL UTF8String) static void log_os(void) { Class NSProcessInfo = objc_getClass("NSProcessInfo"); - id pi = objc_msgSend((id)NSProcessInfo, - sel_registerName("processInfo")); + id pi = objc_msgSend((id)NSProcessInfo, + sel_registerName("processInfo")); SEL UTF8String = sel_registerName("UTF8String"); @@ -151,12 +150,11 @@ static void log_os(void) static void log_kernel_version(void) { - char kernel_version[1024]; + char kernel_version[1024]; size_t size = sizeof(kernel_version); - int ret; + int ret; - ret = sysctlbyname("kern.osrelease", kernel_version, &size, - NULL, 0); + ret = sysctlbyname("kern.osrelease", kernel_version, &size, NULL, 0); if (ret == 0) blog(LOG_INFO, "Kernel Version: %s", kernel_version); } @@ -171,12 +169,11 @@ void log_system_info(void) log_kernel_version(); } - static bool dstr_from_cfstring(struct dstr *str, CFStringRef ref) { - CFIndex length = CFStringGetLength(ref); - CFIndex max_size = CFStringGetMaximumSizeForEncoding(length, - kCFStringEncodingUTF8); + CFIndex length = CFStringGetLength(ref); + CFIndex max_size = CFStringGetMaximumSizeForEncoding( + length, kCFStringEncodingUTF8); dstr_reserve(str, max_size); if (!CFStringGetCString(ref, str->array, max_size, @@ -188,11 +185,11 @@ static bool dstr_from_cfstring(struct dstr *str, CFStringRef ref) } struct obs_hotkeys_platform { - volatile long refs; - TISInputSourceRef tis; - CFDataRef layout_data; - UCKeyboardLayout *layout; - IOHIDManagerRef manager; + volatile long refs; + TISInputSourceRef tis; + CFDataRef layout_data; + UCKeyboardLayout *layout; + IOHIDManagerRef manager; DARRAY(IOHIDElementRef) keys[OBS_KEY_LAST_VALUE]; }; @@ -213,194 +210,303 @@ static void hotkeys_release(struct obs_hotkeys_platform *plat) int obs_key_to_virtual_key(obs_key_t code) { switch (code) { - case OBS_KEY_A: return kVK_ANSI_A; - case OBS_KEY_B: return kVK_ANSI_B; - case OBS_KEY_C: return kVK_ANSI_C; - case OBS_KEY_D: return kVK_ANSI_D; - case OBS_KEY_E: return kVK_ANSI_E; - case OBS_KEY_F: return kVK_ANSI_F; - case OBS_KEY_G: return kVK_ANSI_G; - case OBS_KEY_H: return kVK_ANSI_H; - case OBS_KEY_I: return kVK_ANSI_I; - case OBS_KEY_J: return kVK_ANSI_J; - case OBS_KEY_K: return kVK_ANSI_K; - case OBS_KEY_L: return kVK_ANSI_L; - case OBS_KEY_M: return kVK_ANSI_M; - case OBS_KEY_N: return kVK_ANSI_N; - case OBS_KEY_O: return kVK_ANSI_O; - case OBS_KEY_P: return kVK_ANSI_P; - case OBS_KEY_Q: return kVK_ANSI_Q; - case OBS_KEY_R: return kVK_ANSI_R; - case OBS_KEY_S: return kVK_ANSI_S; - case OBS_KEY_T: return kVK_ANSI_T; - case OBS_KEY_U: return kVK_ANSI_U; - case OBS_KEY_V: return kVK_ANSI_V; - case OBS_KEY_W: return kVK_ANSI_W; - case OBS_KEY_X: return kVK_ANSI_X; - case OBS_KEY_Y: return kVK_ANSI_Y; - case OBS_KEY_Z: return kVK_ANSI_Z; + case OBS_KEY_A: + return kVK_ANSI_A; + case OBS_KEY_B: + return kVK_ANSI_B; + case OBS_KEY_C: + return kVK_ANSI_C; + case OBS_KEY_D: + return kVK_ANSI_D; + case OBS_KEY_E: + return kVK_ANSI_E; + case OBS_KEY_F: + return kVK_ANSI_F; + case OBS_KEY_G: + return kVK_ANSI_G; + case OBS_KEY_H: + return kVK_ANSI_H; + case OBS_KEY_I: + return kVK_ANSI_I; + case OBS_KEY_J: + return kVK_ANSI_J; + case OBS_KEY_K: + return kVK_ANSI_K; + case OBS_KEY_L: + return kVK_ANSI_L; + case OBS_KEY_M: + return kVK_ANSI_M; + case OBS_KEY_N: + return kVK_ANSI_N; + case OBS_KEY_O: + return kVK_ANSI_O; + case OBS_KEY_P: + return kVK_ANSI_P; + case OBS_KEY_Q: + return kVK_ANSI_Q; + case OBS_KEY_R: + return kVK_ANSI_R; + case OBS_KEY_S: + return kVK_ANSI_S; + case OBS_KEY_T: + return kVK_ANSI_T; + case OBS_KEY_U: + return kVK_ANSI_U; + case OBS_KEY_V: + return kVK_ANSI_V; + case OBS_KEY_W: + return kVK_ANSI_W; + case OBS_KEY_X: + return kVK_ANSI_X; + case OBS_KEY_Y: + return kVK_ANSI_Y; + case OBS_KEY_Z: + return kVK_ANSI_Z; - case OBS_KEY_1: return kVK_ANSI_1; - case OBS_KEY_2: return kVK_ANSI_2; - case OBS_KEY_3: return kVK_ANSI_3; - case OBS_KEY_4: return kVK_ANSI_4; - case OBS_KEY_5: return kVK_ANSI_5; - case OBS_KEY_6: return kVK_ANSI_6; - case OBS_KEY_7: return kVK_ANSI_7; - case OBS_KEY_8: return kVK_ANSI_8; - case OBS_KEY_9: return kVK_ANSI_9; - case OBS_KEY_0: return kVK_ANSI_0; + case OBS_KEY_1: + return kVK_ANSI_1; + case OBS_KEY_2: + return kVK_ANSI_2; + case OBS_KEY_3: + return kVK_ANSI_3; + case OBS_KEY_4: + return kVK_ANSI_4; + case OBS_KEY_5: + return kVK_ANSI_5; + case OBS_KEY_6: + return kVK_ANSI_6; + case OBS_KEY_7: + return kVK_ANSI_7; + case OBS_KEY_8: + return kVK_ANSI_8; + case OBS_KEY_9: + return kVK_ANSI_9; + case OBS_KEY_0: + return kVK_ANSI_0; - case OBS_KEY_RETURN: return kVK_Return; - case OBS_KEY_ESCAPE: return kVK_Escape; - case OBS_KEY_BACKSPACE: return kVK_Delete; - case OBS_KEY_TAB: return kVK_Tab; - case OBS_KEY_SPACE: return kVK_Space; - case OBS_KEY_MINUS: return kVK_ANSI_Minus; - case OBS_KEY_EQUAL: return kVK_ANSI_Equal; - case OBS_KEY_BRACKETLEFT: return kVK_ANSI_LeftBracket; - case OBS_KEY_BRACKETRIGHT: return kVK_ANSI_RightBracket; - case OBS_KEY_BACKSLASH: return kVK_ANSI_Backslash; - case OBS_KEY_SEMICOLON: return kVK_ANSI_Semicolon; - case OBS_KEY_QUOTE: return kVK_ANSI_Quote; - case OBS_KEY_DEAD_GRAVE: return kVK_ANSI_Grave; - case OBS_KEY_COMMA: return kVK_ANSI_Comma; - case OBS_KEY_PERIOD: return kVK_ANSI_Period; - case OBS_KEY_SLASH: return kVK_ANSI_Slash; - case OBS_KEY_CAPSLOCK: return kVK_CapsLock; - case OBS_KEY_SECTION: return kVK_ISO_Section; + case OBS_KEY_RETURN: + return kVK_Return; + case OBS_KEY_ESCAPE: + return kVK_Escape; + case OBS_KEY_BACKSPACE: + return kVK_Delete; + case OBS_KEY_TAB: + return kVK_Tab; + case OBS_KEY_SPACE: + return kVK_Space; + case OBS_KEY_MINUS: + return kVK_ANSI_Minus; + case OBS_KEY_EQUAL: + return kVK_ANSI_Equal; + case OBS_KEY_BRACKETLEFT: + return kVK_ANSI_LeftBracket; + case OBS_KEY_BRACKETRIGHT: + return kVK_ANSI_RightBracket; + case OBS_KEY_BACKSLASH: + return kVK_ANSI_Backslash; + case OBS_KEY_SEMICOLON: + return kVK_ANSI_Semicolon; + case OBS_KEY_QUOTE: + return kVK_ANSI_Quote; + case OBS_KEY_DEAD_GRAVE: + return kVK_ANSI_Grave; + case OBS_KEY_COMMA: + return kVK_ANSI_Comma; + case OBS_KEY_PERIOD: + return kVK_ANSI_Period; + case OBS_KEY_SLASH: + return kVK_ANSI_Slash; + case OBS_KEY_CAPSLOCK: + return kVK_CapsLock; + case OBS_KEY_SECTION: + return kVK_ISO_Section; - case OBS_KEY_F1: return kVK_F1; - case OBS_KEY_F2: return kVK_F2; - case OBS_KEY_F3: return kVK_F3; - case OBS_KEY_F4: return kVK_F4; - case OBS_KEY_F5: return kVK_F5; - case OBS_KEY_F6: return kVK_F6; - case OBS_KEY_F7: return kVK_F7; - case OBS_KEY_F8: return kVK_F8; - case OBS_KEY_F9: return kVK_F9; - case OBS_KEY_F10: return kVK_F10; - case OBS_KEY_F11: return kVK_F11; - case OBS_KEY_F12: return kVK_F12; + case OBS_KEY_F1: + return kVK_F1; + case OBS_KEY_F2: + return kVK_F2; + case OBS_KEY_F3: + return kVK_F3; + case OBS_KEY_F4: + return kVK_F4; + case OBS_KEY_F5: + return kVK_F5; + case OBS_KEY_F6: + return kVK_F6; + case OBS_KEY_F7: + return kVK_F7; + case OBS_KEY_F8: + return kVK_F8; + case OBS_KEY_F9: + return kVK_F9; + case OBS_KEY_F10: + return kVK_F10; + case OBS_KEY_F11: + return kVK_F11; + case OBS_KEY_F12: + return kVK_F12; - case OBS_KEY_HELP: return kVK_Help; - case OBS_KEY_HOME: return kVK_Home; - case OBS_KEY_PAGEUP: return kVK_PageUp; - case OBS_KEY_DELETE: return kVK_ForwardDelete; - case OBS_KEY_END: return kVK_End; - case OBS_KEY_PAGEDOWN: return kVK_PageDown; + case OBS_KEY_HELP: + return kVK_Help; + case OBS_KEY_HOME: + return kVK_Home; + case OBS_KEY_PAGEUP: + return kVK_PageUp; + case OBS_KEY_DELETE: + return kVK_ForwardDelete; + case OBS_KEY_END: + return kVK_End; + case OBS_KEY_PAGEDOWN: + return kVK_PageDown; - case OBS_KEY_RIGHT: return kVK_RightArrow; - case OBS_KEY_LEFT: return kVK_LeftArrow; - case OBS_KEY_DOWN: return kVK_DownArrow; - case OBS_KEY_UP: return kVK_UpArrow; + case OBS_KEY_RIGHT: + return kVK_RightArrow; + case OBS_KEY_LEFT: + return kVK_LeftArrow; + case OBS_KEY_DOWN: + return kVK_DownArrow; + case OBS_KEY_UP: + return kVK_UpArrow; - case OBS_KEY_CLEAR: return kVK_ANSI_KeypadClear; - case OBS_KEY_NUMSLASH: return kVK_ANSI_KeypadDivide; - case OBS_KEY_NUMASTERISK: return kVK_ANSI_KeypadMultiply; - case OBS_KEY_NUMMINUS: return kVK_ANSI_KeypadMinus; - case OBS_KEY_NUMPLUS: return kVK_ANSI_KeypadPlus; - case OBS_KEY_ENTER: return kVK_ANSI_KeypadEnter; + case OBS_KEY_CLEAR: + return kVK_ANSI_KeypadClear; + case OBS_KEY_NUMSLASH: + return kVK_ANSI_KeypadDivide; + case OBS_KEY_NUMASTERISK: + return kVK_ANSI_KeypadMultiply; + case OBS_KEY_NUMMINUS: + return kVK_ANSI_KeypadMinus; + case OBS_KEY_NUMPLUS: + return kVK_ANSI_KeypadPlus; + case OBS_KEY_ENTER: + return kVK_ANSI_KeypadEnter; - case OBS_KEY_NUM1: return kVK_ANSI_Keypad1; - case OBS_KEY_NUM2: return kVK_ANSI_Keypad2; - case OBS_KEY_NUM3: return kVK_ANSI_Keypad3; - case OBS_KEY_NUM4: return kVK_ANSI_Keypad4; - case OBS_KEY_NUM5: return kVK_ANSI_Keypad5; - case OBS_KEY_NUM6: return kVK_ANSI_Keypad6; - case OBS_KEY_NUM7: return kVK_ANSI_Keypad7; - case OBS_KEY_NUM8: return kVK_ANSI_Keypad8; - case OBS_KEY_NUM9: return kVK_ANSI_Keypad9; - case OBS_KEY_NUM0: return kVK_ANSI_Keypad0; + case OBS_KEY_NUM1: + return kVK_ANSI_Keypad1; + case OBS_KEY_NUM2: + return kVK_ANSI_Keypad2; + case OBS_KEY_NUM3: + return kVK_ANSI_Keypad3; + case OBS_KEY_NUM4: + return kVK_ANSI_Keypad4; + case OBS_KEY_NUM5: + return kVK_ANSI_Keypad5; + case OBS_KEY_NUM6: + return kVK_ANSI_Keypad6; + case OBS_KEY_NUM7: + return kVK_ANSI_Keypad7; + case OBS_KEY_NUM8: + return kVK_ANSI_Keypad8; + case OBS_KEY_NUM9: + return kVK_ANSI_Keypad9; + case OBS_KEY_NUM0: + return kVK_ANSI_Keypad0; - case OBS_KEY_NUMPERIOD: return kVK_ANSI_KeypadDecimal; - case OBS_KEY_NUMEQUAL: return kVK_ANSI_KeypadEquals; + case OBS_KEY_NUMPERIOD: + return kVK_ANSI_KeypadDecimal; + case OBS_KEY_NUMEQUAL: + return kVK_ANSI_KeypadEquals; - case OBS_KEY_F13: return kVK_F13; - case OBS_KEY_F14: return kVK_F14; - case OBS_KEY_F15: return kVK_F15; - case OBS_KEY_F16: return kVK_F16; - case OBS_KEY_F17: return kVK_F17; - case OBS_KEY_F18: return kVK_F18; - case OBS_KEY_F19: return kVK_F19; - case OBS_KEY_F20: return kVK_F20; + case OBS_KEY_F13: + return kVK_F13; + case OBS_KEY_F14: + return kVK_F14; + case OBS_KEY_F15: + return kVK_F15; + case OBS_KEY_F16: + return kVK_F16; + case OBS_KEY_F17: + return kVK_F17; + case OBS_KEY_F18: + return kVK_F18; + case OBS_KEY_F19: + return kVK_F19; + case OBS_KEY_F20: + return kVK_F20; - case OBS_KEY_CONTROL: return kVK_Control; - case OBS_KEY_SHIFT: return kVK_Shift; - case OBS_KEY_ALT: return kVK_Option; - case OBS_KEY_META: return kVK_Command; - //case OBS_KEY_CONTROL: return kVK_RightControl; - //case OBS_KEY_SHIFT: return kVK_RightShift; - //case OBS_KEY_ALT: return kVK_RightOption; - //case OBS_KEY_META: return 0x36; + case OBS_KEY_CONTROL: + return kVK_Control; + case OBS_KEY_SHIFT: + return kVK_Shift; + case OBS_KEY_ALT: + return kVK_Option; + case OBS_KEY_META: + return kVK_Command; + //case OBS_KEY_CONTROL: return kVK_RightControl; + //case OBS_KEY_SHIFT: return kVK_RightShift; + //case OBS_KEY_ALT: return kVK_RightOption; + //case OBS_KEY_META: return 0x36; case OBS_KEY_NONE: case OBS_KEY_LAST_VALUE: default: - break; + break; } return INVALID_KEY; } static bool localized_key_to_str(obs_key_t key, struct dstr *str) { -#define MAP_KEY(k, s) case k: \ +#define MAP_KEY(k, s) \ + case k: \ dstr_copy(str, obs_get_hotkey_translation(k, s)); \ return true -#define MAP_BUTTON(i) case OBS_KEY_MOUSE ## i: \ +#define MAP_BUTTON(i) \ + case OBS_KEY_MOUSE##i: \ dstr_copy(str, obs_get_hotkey_translation(key, "Mouse " #i)); \ return true switch (key) { - MAP_KEY(OBS_KEY_SPACE, "Space"); - MAP_KEY(OBS_KEY_NUMEQUAL, "= (Keypad)"); - MAP_KEY(OBS_KEY_NUMASTERISK, "* (Keypad)"); - MAP_KEY(OBS_KEY_NUMPLUS, "+ (Keypad)"); - MAP_KEY(OBS_KEY_NUMMINUS, "- (Keypad)"); - MAP_KEY(OBS_KEY_NUMPERIOD, ". (Keypad)"); - MAP_KEY(OBS_KEY_NUMSLASH, "/ (Keypad)"); - MAP_KEY(OBS_KEY_NUM0, "0 (Keypad)"); - MAP_KEY(OBS_KEY_NUM1, "1 (Keypad)"); - MAP_KEY(OBS_KEY_NUM2, "2 (Keypad)"); - MAP_KEY(OBS_KEY_NUM3, "3 (Keypad)"); - MAP_KEY(OBS_KEY_NUM4, "4 (Keypad)"); - MAP_KEY(OBS_KEY_NUM5, "5 (Keypad)"); - MAP_KEY(OBS_KEY_NUM6, "6 (Keypad)"); - MAP_KEY(OBS_KEY_NUM7, "7 (Keypad)"); - MAP_KEY(OBS_KEY_NUM8, "8 (Keypad)"); - MAP_KEY(OBS_KEY_NUM9, "9 (Keypad)"); + MAP_KEY(OBS_KEY_SPACE, "Space"); + MAP_KEY(OBS_KEY_NUMEQUAL, "= (Keypad)"); + MAP_KEY(OBS_KEY_NUMASTERISK, "* (Keypad)"); + MAP_KEY(OBS_KEY_NUMPLUS, "+ (Keypad)"); + MAP_KEY(OBS_KEY_NUMMINUS, "- (Keypad)"); + MAP_KEY(OBS_KEY_NUMPERIOD, ". (Keypad)"); + MAP_KEY(OBS_KEY_NUMSLASH, "/ (Keypad)"); + MAP_KEY(OBS_KEY_NUM0, "0 (Keypad)"); + MAP_KEY(OBS_KEY_NUM1, "1 (Keypad)"); + MAP_KEY(OBS_KEY_NUM2, "2 (Keypad)"); + MAP_KEY(OBS_KEY_NUM3, "3 (Keypad)"); + MAP_KEY(OBS_KEY_NUM4, "4 (Keypad)"); + MAP_KEY(OBS_KEY_NUM5, "5 (Keypad)"); + MAP_KEY(OBS_KEY_NUM6, "6 (Keypad)"); + MAP_KEY(OBS_KEY_NUM7, "7 (Keypad)"); + MAP_KEY(OBS_KEY_NUM8, "8 (Keypad)"); + MAP_KEY(OBS_KEY_NUM9, "9 (Keypad)"); - MAP_BUTTON(1); - MAP_BUTTON(2); - MAP_BUTTON(3); - MAP_BUTTON(4); - MAP_BUTTON(5); - MAP_BUTTON(6); - MAP_BUTTON(7); - MAP_BUTTON(8); - MAP_BUTTON(9); - MAP_BUTTON(10); - MAP_BUTTON(11); - MAP_BUTTON(12); - MAP_BUTTON(13); - MAP_BUTTON(14); - MAP_BUTTON(15); - MAP_BUTTON(16); - MAP_BUTTON(17); - MAP_BUTTON(18); - MAP_BUTTON(19); - MAP_BUTTON(20); - MAP_BUTTON(21); - MAP_BUTTON(22); - MAP_BUTTON(23); - MAP_BUTTON(24); - MAP_BUTTON(25); - MAP_BUTTON(26); - MAP_BUTTON(27); - MAP_BUTTON(28); - MAP_BUTTON(29); - default: break; + MAP_BUTTON(1); + MAP_BUTTON(2); + MAP_BUTTON(3); + MAP_BUTTON(4); + MAP_BUTTON(5); + MAP_BUTTON(6); + MAP_BUTTON(7); + MAP_BUTTON(8); + MAP_BUTTON(9); + MAP_BUTTON(10); + MAP_BUTTON(11); + MAP_BUTTON(12); + MAP_BUTTON(13); + MAP_BUTTON(14); + MAP_BUTTON(15); + MAP_BUTTON(16); + MAP_BUTTON(17); + MAP_BUTTON(18); + MAP_BUTTON(19); + MAP_BUTTON(20); + MAP_BUTTON(21); + MAP_BUTTON(22); + MAP_BUTTON(23); + MAP_BUTTON(24); + MAP_BUTTON(25); + MAP_BUTTON(26); + MAP_BUTTON(27); + MAP_BUTTON(28); + MAP_BUTTON(29); + default: + break; } #undef MAP_BUTTON #undef MAP_KEY @@ -410,56 +516,61 @@ static bool localized_key_to_str(obs_key_t key, struct dstr *str) static bool code_to_str(int code, struct dstr *str) { -#define MAP_GLYPH(c, g) \ - case c: dstr_from_wcs(str, (wchar_t[]){g, 0}); return true -#define MAP_STR(c, s) case c: dstr_copy(str, s); return true +#define MAP_GLYPH(c, g) \ + case c: \ + dstr_from_wcs(str, (wchar_t[]){g, 0}); \ + return true +#define MAP_STR(c, s) \ + case c: \ + dstr_copy(str, s); \ + return true switch (code) { - MAP_GLYPH(kVK_Return, 0x21A9); - MAP_GLYPH(kVK_Escape, 0x238B); - MAP_GLYPH(kVK_Delete, 0x232B); - MAP_GLYPH(kVK_Tab, 0x21e5); - MAP_GLYPH(kVK_CapsLock, 0x21EA); - MAP_GLYPH(kVK_ANSI_KeypadClear, 0x2327); - MAP_GLYPH(kVK_ANSI_KeypadEnter, 0x2305); - MAP_GLYPH(kVK_Help, 0x003F); - MAP_GLYPH(kVK_Home, 0x2196); - MAP_GLYPH(kVK_PageUp, 0x21de); - MAP_GLYPH(kVK_ForwardDelete, 0x2326); - MAP_GLYPH(kVK_End, 0x2198); - MAP_GLYPH(kVK_PageDown, 0x21df); + MAP_GLYPH(kVK_Return, 0x21A9); + MAP_GLYPH(kVK_Escape, 0x238B); + MAP_GLYPH(kVK_Delete, 0x232B); + MAP_GLYPH(kVK_Tab, 0x21e5); + MAP_GLYPH(kVK_CapsLock, 0x21EA); + MAP_GLYPH(kVK_ANSI_KeypadClear, 0x2327); + MAP_GLYPH(kVK_ANSI_KeypadEnter, 0x2305); + MAP_GLYPH(kVK_Help, 0x003F); + MAP_GLYPH(kVK_Home, 0x2196); + MAP_GLYPH(kVK_PageUp, 0x21de); + MAP_GLYPH(kVK_ForwardDelete, 0x2326); + MAP_GLYPH(kVK_End, 0x2198); + MAP_GLYPH(kVK_PageDown, 0x21df); - MAP_GLYPH(kVK_RightArrow, 0x2192); - MAP_GLYPH(kVK_LeftArrow, 0x2190); - MAP_GLYPH(kVK_DownArrow, 0x2193); - MAP_GLYPH(kVK_UpArrow, 0x2191); + MAP_GLYPH(kVK_RightArrow, 0x2192); + MAP_GLYPH(kVK_LeftArrow, 0x2190); + MAP_GLYPH(kVK_DownArrow, 0x2193); + MAP_GLYPH(kVK_UpArrow, 0x2191); - MAP_STR (kVK_F1, "F1"); - MAP_STR (kVK_F2, "F2"); - MAP_STR (kVK_F3, "F3"); - MAP_STR (kVK_F4, "F4"); - MAP_STR (kVK_F5, "F5"); - MAP_STR (kVK_F6, "F6"); - MAP_STR (kVK_F7, "F7"); - MAP_STR (kVK_F8, "F8"); - MAP_STR (kVK_F9, "F9"); - MAP_STR (kVK_F10, "F10"); - MAP_STR (kVK_F11, "F11"); - MAP_STR (kVK_F12, "F12"); - MAP_STR (kVK_F13, "F13"); - MAP_STR (kVK_F14, "F14"); - MAP_STR (kVK_F15, "F15"); - MAP_STR (kVK_F16, "F16"); - MAP_STR (kVK_F17, "F17"); - MAP_STR (kVK_F18, "F18"); - MAP_STR (kVK_F19, "F19"); - MAP_STR (kVK_F20, "F20"); - MAP_GLYPH(kVK_Control, kControlUnicode); - MAP_GLYPH(kVK_Shift, kShiftUnicode); - MAP_GLYPH(kVK_Option, kOptionUnicode); - MAP_GLYPH(kVK_Command, kCommandUnicode); - MAP_GLYPH(kVK_RightControl, kControlUnicode); - MAP_GLYPH(kVK_RightShift, kShiftUnicode); - MAP_GLYPH(kVK_RightOption, kOptionUnicode); + MAP_STR(kVK_F1, "F1"); + MAP_STR(kVK_F2, "F2"); + MAP_STR(kVK_F3, "F3"); + MAP_STR(kVK_F4, "F4"); + MAP_STR(kVK_F5, "F5"); + MAP_STR(kVK_F6, "F6"); + MAP_STR(kVK_F7, "F7"); + MAP_STR(kVK_F8, "F8"); + MAP_STR(kVK_F9, "F9"); + MAP_STR(kVK_F10, "F10"); + MAP_STR(kVK_F11, "F11"); + MAP_STR(kVK_F12, "F12"); + MAP_STR(kVK_F13, "F13"); + MAP_STR(kVK_F14, "F14"); + MAP_STR(kVK_F15, "F15"); + MAP_STR(kVK_F16, "F16"); + MAP_STR(kVK_F17, "F17"); + MAP_STR(kVK_F18, "F18"); + MAP_STR(kVK_F19, "F19"); + MAP_STR(kVK_F20, "F20"); + MAP_GLYPH(kVK_Control, kControlUnicode); + MAP_GLYPH(kVK_Shift, kShiftUnicode); + MAP_GLYPH(kVK_Option, kOptionUnicode); + MAP_GLYPH(kVK_Command, kCommandUnicode); + MAP_GLYPH(kVK_RightControl, kControlUnicode); + MAP_GLYPH(kVK_RightShift, kShiftUnicode); + MAP_GLYPH(kVK_RightOption, kOptionUnicode); } #undef MAP_STR #undef MAP_GLYPH @@ -477,9 +588,10 @@ void obs_key_to_str(obs_key_t key, struct dstr *str) return; if (code == INVALID_KEY) { - blog(LOG_ERROR, "hotkey-cocoa: Got invalid key while " - "translating key '%d' (%s)", - key, obs_key_to_name(key)); + blog(LOG_ERROR, + "hotkey-cocoa: Got invalid key while " + "translating key '%d' (%s)", + key, obs_key_to_name(key)); goto err; } @@ -493,70 +605,64 @@ void obs_key_to_str(obs_key_t key, struct dstr *str) } if (!plat) { - blog(LOG_ERROR, "hotkey-cocoa: Could not get hotkey platform " - "while translating key '%d' (%s)", - key, obs_key_to_name(key)); + blog(LOG_ERROR, + "hotkey-cocoa: Could not get hotkey platform " + "while translating key '%d' (%s)", + key, obs_key_to_name(key)); goto err; } const UniCharCount max_length = 16; - UInt32 dead_key_state = 0; - UniChar buffer[max_length]; - UniCharCount len = 0; + UInt32 dead_key_state = 0; + UniChar buffer[max_length]; + UniCharCount len = 0; - OSStatus err = UCKeyTranslate(plat->layout, - code, - kUCKeyActionDown, - 0x104, //caps lock for upper case letters - LMGetKbdType(), - kUCKeyTranslateNoDeadKeysBit, - &dead_key_state, - max_length, - &len, - buffer); + OSStatus err = + UCKeyTranslate(plat->layout, code, kUCKeyActionDown, + 0x104, //caps lock for upper case letters + LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, + &dead_key_state, max_length, &len, buffer); if (err == noErr && len <= 0 && dead_key_state) { - err = UCKeyTranslate(plat->layout, - kVK_Space, - kUCKeyActionDown, - 0x104, - LMGetKbdType(), - kUCKeyTranslateNoDeadKeysBit, - &dead_key_state, - max_length, - &len, - buffer); + err = UCKeyTranslate(plat->layout, kVK_Space, kUCKeyActionDown, + 0x104, LMGetKbdType(), + kUCKeyTranslateNoDeadKeysBit, + &dead_key_state, max_length, &len, buffer); } hotkeys_release(plat); if (err != noErr) { - blog(LOG_ERROR, "hotkey-cocoa: Error while translating key '%d'" - " (0x%x, %s) to string: %d", key, code, - obs_key_to_name(key), err); + blog(LOG_ERROR, + "hotkey-cocoa: Error while translating key '%d'" + " (0x%x, %s) to string: %d", + key, code, obs_key_to_name(key), err); goto err; } if (len == 0) { - blog(LOG_ERROR, "hotkey-cocoa: Got 0 length string while " - "translating '%d' (0x%x, %s) to string", - key, code, obs_key_to_name(key)); + blog(LOG_ERROR, + "hotkey-cocoa: Got 0 length string while " + "translating '%d' (0x%x, %s) to string", + key, code, obs_key_to_name(key)); goto err; } - CFStringRef string = CFStringCreateWithCharactersNoCopy(NULL, - buffer, len, kCFAllocatorNull); + CFStringRef string = CFStringCreateWithCharactersNoCopy( + NULL, buffer, len, kCFAllocatorNull); if (!string) { - blog(LOG_ERROR, "hotkey-cocoa: Could not create CFStringRef " - "while translating '%d' (0x%x, %s) to string", - key, code, obs_key_to_name(key)); + blog(LOG_ERROR, + "hotkey-cocoa: Could not create CFStringRef " + "while translating '%d' (0x%x, %s) to string", + key, code, obs_key_to_name(key)); goto err; } if (!dstr_from_cfstring(str, string)) { - blog(LOG_ERROR, "hotkey-cocoa: Could not translate CFStringRef " - "to CString while translating '%d' (0x%x, %s)", - key, code, obs_key_to_name(key)); + blog(LOG_ERROR, + "hotkey-cocoa: Could not translate CFStringRef " + "to CString while translating '%d' (0x%x, %s)", + key, code, obs_key_to_name(key)); goto release; } @@ -573,8 +679,8 @@ err: #define OBS_COCOA_MODIFIER_SIZE 7 static void unichar_to_utf8(const UniChar *c, char *buff) { - CFStringRef string = CFStringCreateWithCharactersNoCopy(NULL, c, 2, - kCFAllocatorNull); + CFStringRef string = CFStringCreateWithCharactersNoCopy( + NULL, c, 2, kCFAllocatorNull); if (!string) { blog(LOG_ERROR, "hotkey-cocoa: Could not create CFStringRef " "while populating modifier strings"); @@ -583,9 +689,10 @@ static void unichar_to_utf8(const UniChar *c, char *buff) if (!CFStringGetCString(string, buff, OBS_COCOA_MODIFIER_SIZE, kCFStringEncodingUTF8)) - blog(LOG_ERROR, "hotkey-cocoa: Error while populating " - " modifier string with glyph %d (0x%x)", - c[0], c[0]); + blog(LOG_ERROR, + "hotkey-cocoa: Error while populating " + " modifier string with glyph %d (0x%x)", + c[0], c[0]); CFRelease(string); } @@ -596,10 +703,10 @@ static char shift_str[OBS_COCOA_MODIFIER_SIZE]; static char cmd_str[OBS_COCOA_MODIFIER_SIZE]; static void init_utf_8_strings(void) { - const UniChar ctrl_uni[] = {kControlUnicode, 0}; - const UniChar opt_uni[] = {kOptionUnicode, 0}; + const UniChar ctrl_uni[] = {kControlUnicode, 0}; + const UniChar opt_uni[] = {kOptionUnicode, 0}; const UniChar shift_uni[] = {kShiftUnicode, 0}; - const UniChar cmd_uni[] = {kCommandUnicode, 0}; + const UniChar cmd_uni[] = {kCommandUnicode, 0}; unichar_to_utf8(ctrl_uni, ctrl_str); unichar_to_utf8(opt_uni, opt_str); @@ -616,19 +723,21 @@ void obs_key_combination_to_str(obs_key_combination_t key, struct dstr *str) int res = pthread_once(&strings_token, init_utf_8_strings); if (res) { - blog(LOG_ERROR, "hotkeys-cocoa: Error while translating " - "modifiers %d (0x%x)", res, res); + blog(LOG_ERROR, + "hotkeys-cocoa: Error while translating " + "modifiers %d (0x%x)", + res, res); dstr_move(str, &key_str); return; } #define CHECK_MODIFIER(mod, str) ((key.modifiers & mod) ? str : "") dstr_printf(str, "%s%s%s%s%s", - CHECK_MODIFIER(INTERACT_CONTROL_KEY, ctrl_str), - CHECK_MODIFIER(INTERACT_ALT_KEY, opt_str), - CHECK_MODIFIER(INTERACT_SHIFT_KEY, shift_str), - CHECK_MODIFIER(INTERACT_COMMAND_KEY, cmd_str), - key_str.len ? key_str.array : ""); + CHECK_MODIFIER(INTERACT_CONTROL_KEY, ctrl_str), + CHECK_MODIFIER(INTERACT_ALT_KEY, opt_str), + CHECK_MODIFIER(INTERACT_SHIFT_KEY, shift_str), + CHECK_MODIFIER(INTERACT_COMMAND_KEY, cmd_str), + key_str.len ? key_str.array : ""); #undef CHECK_MODIFIER dstr_free(&key_str); @@ -637,9 +746,8 @@ void obs_key_combination_to_str(obs_key_combination_t key, struct dstr *str) static inline CFDictionaryRef copy_device_mask(UInt32 page, UInt32 usage) { CFMutableDictionaryRef dict = CFDictionaryCreateMutable( - kCFAllocatorDefault, 2, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); CFNumberRef value; // Add the page value. @@ -655,8 +763,8 @@ static inline CFDictionaryRef copy_device_mask(UInt32 page, UInt32 usage) return dict; } -static CFSetRef copy_devices(obs_hotkeys_platform_t *plat, - UInt32 page, UInt32 usage) +static CFSetRef copy_devices(obs_hotkeys_platform_t *plat, UInt32 page, + UInt32 usage) { CFDictionaryRef mask = copy_device_mask(page, usage); IOHIDManagerSetDeviceMatching(plat->manager, mask); @@ -676,204 +784,377 @@ static CFSetRef copy_devices(obs_hotkeys_platform_t *plat, static UInt16 usage_to_carbon(UInt32 usage) { - switch (usage) - { - case kHIDUsage_KeyboardErrorRollOver: return INVALID_KEY; - case kHIDUsage_KeyboardPOSTFail: return INVALID_KEY; - case kHIDUsage_KeyboardErrorUndefined: return INVALID_KEY; + switch (usage) { + case kHIDUsage_KeyboardErrorRollOver: + return INVALID_KEY; + case kHIDUsage_KeyboardPOSTFail: + return INVALID_KEY; + case kHIDUsage_KeyboardErrorUndefined: + return INVALID_KEY; - case kHIDUsage_KeyboardA: return kVK_ANSI_A; - case kHIDUsage_KeyboardB: return kVK_ANSI_B; - case kHIDUsage_KeyboardC: return kVK_ANSI_C; - case kHIDUsage_KeyboardD: return kVK_ANSI_D; - case kHIDUsage_KeyboardE: return kVK_ANSI_E; - case kHIDUsage_KeyboardF: return kVK_ANSI_F; - case kHIDUsage_KeyboardG: return kVK_ANSI_G; - case kHIDUsage_KeyboardH: return kVK_ANSI_H; - case kHIDUsage_KeyboardI: return kVK_ANSI_I; - case kHIDUsage_KeyboardJ: return kVK_ANSI_J; - case kHIDUsage_KeyboardK: return kVK_ANSI_K; - case kHIDUsage_KeyboardL: return kVK_ANSI_L; - case kHIDUsage_KeyboardM: return kVK_ANSI_M; - case kHIDUsage_KeyboardN: return kVK_ANSI_N; - case kHIDUsage_KeyboardO: return kVK_ANSI_O; - case kHIDUsage_KeyboardP: return kVK_ANSI_P; - case kHIDUsage_KeyboardQ: return kVK_ANSI_Q; - case kHIDUsage_KeyboardR: return kVK_ANSI_R; - case kHIDUsage_KeyboardS: return kVK_ANSI_S; - case kHIDUsage_KeyboardT: return kVK_ANSI_T; - case kHIDUsage_KeyboardU: return kVK_ANSI_U; - case kHIDUsage_KeyboardV: return kVK_ANSI_V; - case kHIDUsage_KeyboardW: return kVK_ANSI_W; - case kHIDUsage_KeyboardX: return kVK_ANSI_X; - case kHIDUsage_KeyboardY: return kVK_ANSI_Y; - case kHIDUsage_KeyboardZ: return kVK_ANSI_Z; + case kHIDUsage_KeyboardA: + return kVK_ANSI_A; + case kHIDUsage_KeyboardB: + return kVK_ANSI_B; + case kHIDUsage_KeyboardC: + return kVK_ANSI_C; + case kHIDUsage_KeyboardD: + return kVK_ANSI_D; + case kHIDUsage_KeyboardE: + return kVK_ANSI_E; + case kHIDUsage_KeyboardF: + return kVK_ANSI_F; + case kHIDUsage_KeyboardG: + return kVK_ANSI_G; + case kHIDUsage_KeyboardH: + return kVK_ANSI_H; + case kHIDUsage_KeyboardI: + return kVK_ANSI_I; + case kHIDUsage_KeyboardJ: + return kVK_ANSI_J; + case kHIDUsage_KeyboardK: + return kVK_ANSI_K; + case kHIDUsage_KeyboardL: + return kVK_ANSI_L; + case kHIDUsage_KeyboardM: + return kVK_ANSI_M; + case kHIDUsage_KeyboardN: + return kVK_ANSI_N; + case kHIDUsage_KeyboardO: + return kVK_ANSI_O; + case kHIDUsage_KeyboardP: + return kVK_ANSI_P; + case kHIDUsage_KeyboardQ: + return kVK_ANSI_Q; + case kHIDUsage_KeyboardR: + return kVK_ANSI_R; + case kHIDUsage_KeyboardS: + return kVK_ANSI_S; + case kHIDUsage_KeyboardT: + return kVK_ANSI_T; + case kHIDUsage_KeyboardU: + return kVK_ANSI_U; + case kHIDUsage_KeyboardV: + return kVK_ANSI_V; + case kHIDUsage_KeyboardW: + return kVK_ANSI_W; + case kHIDUsage_KeyboardX: + return kVK_ANSI_X; + case kHIDUsage_KeyboardY: + return kVK_ANSI_Y; + case kHIDUsage_KeyboardZ: + return kVK_ANSI_Z; - case kHIDUsage_Keyboard1: return kVK_ANSI_1; - case kHIDUsage_Keyboard2: return kVK_ANSI_2; - case kHIDUsage_Keyboard3: return kVK_ANSI_3; - case kHIDUsage_Keyboard4: return kVK_ANSI_4; - case kHIDUsage_Keyboard5: return kVK_ANSI_5; - case kHIDUsage_Keyboard6: return kVK_ANSI_6; - case kHIDUsage_Keyboard7: return kVK_ANSI_7; - case kHIDUsage_Keyboard8: return kVK_ANSI_8; - case kHIDUsage_Keyboard9: return kVK_ANSI_9; - case kHIDUsage_Keyboard0: return kVK_ANSI_0; + case kHIDUsage_Keyboard1: + return kVK_ANSI_1; + case kHIDUsage_Keyboard2: + return kVK_ANSI_2; + case kHIDUsage_Keyboard3: + return kVK_ANSI_3; + case kHIDUsage_Keyboard4: + return kVK_ANSI_4; + case kHIDUsage_Keyboard5: + return kVK_ANSI_5; + case kHIDUsage_Keyboard6: + return kVK_ANSI_6; + case kHIDUsage_Keyboard7: + return kVK_ANSI_7; + case kHIDUsage_Keyboard8: + return kVK_ANSI_8; + case kHIDUsage_Keyboard9: + return kVK_ANSI_9; + case kHIDUsage_Keyboard0: + return kVK_ANSI_0; - case kHIDUsage_KeyboardReturnOrEnter: return kVK_Return; - case kHIDUsage_KeyboardEscape: return kVK_Escape; - case kHIDUsage_KeyboardDeleteOrBackspace: return kVK_Delete; - case kHIDUsage_KeyboardTab: return kVK_Tab; - case kHIDUsage_KeyboardSpacebar: return kVK_Space; - case kHIDUsage_KeyboardHyphen: return kVK_ANSI_Minus; - case kHIDUsage_KeyboardEqualSign: return kVK_ANSI_Equal; - case kHIDUsage_KeyboardOpenBracket: return kVK_ANSI_LeftBracket; - case kHIDUsage_KeyboardCloseBracket: return kVK_ANSI_RightBracket; - case kHIDUsage_KeyboardBackslash: return kVK_ANSI_Backslash; - case kHIDUsage_KeyboardNonUSPound: return INVALID_KEY; - case kHIDUsage_KeyboardSemicolon: return kVK_ANSI_Semicolon; - case kHIDUsage_KeyboardQuote: return kVK_ANSI_Quote; - case kHIDUsage_KeyboardGraveAccentAndTilde: return kVK_ANSI_Grave; - case kHIDUsage_KeyboardComma: return kVK_ANSI_Comma; - case kHIDUsage_KeyboardPeriod: return kVK_ANSI_Period; - case kHIDUsage_KeyboardSlash: return kVK_ANSI_Slash; - case kHIDUsage_KeyboardCapsLock: return kVK_CapsLock; + case kHIDUsage_KeyboardReturnOrEnter: + return kVK_Return; + case kHIDUsage_KeyboardEscape: + return kVK_Escape; + case kHIDUsage_KeyboardDeleteOrBackspace: + return kVK_Delete; + case kHIDUsage_KeyboardTab: + return kVK_Tab; + case kHIDUsage_KeyboardSpacebar: + return kVK_Space; + case kHIDUsage_KeyboardHyphen: + return kVK_ANSI_Minus; + case kHIDUsage_KeyboardEqualSign: + return kVK_ANSI_Equal; + case kHIDUsage_KeyboardOpenBracket: + return kVK_ANSI_LeftBracket; + case kHIDUsage_KeyboardCloseBracket: + return kVK_ANSI_RightBracket; + case kHIDUsage_KeyboardBackslash: + return kVK_ANSI_Backslash; + case kHIDUsage_KeyboardNonUSPound: + return INVALID_KEY; + case kHIDUsage_KeyboardSemicolon: + return kVK_ANSI_Semicolon; + case kHIDUsage_KeyboardQuote: + return kVK_ANSI_Quote; + case kHIDUsage_KeyboardGraveAccentAndTilde: + return kVK_ANSI_Grave; + case kHIDUsage_KeyboardComma: + return kVK_ANSI_Comma; + case kHIDUsage_KeyboardPeriod: + return kVK_ANSI_Period; + case kHIDUsage_KeyboardSlash: + return kVK_ANSI_Slash; + case kHIDUsage_KeyboardCapsLock: + return kVK_CapsLock; - case kHIDUsage_KeyboardF1: return kVK_F1; - case kHIDUsage_KeyboardF2: return kVK_F2; - case kHIDUsage_KeyboardF3: return kVK_F3; - case kHIDUsage_KeyboardF4: return kVK_F4; - case kHIDUsage_KeyboardF5: return kVK_F5; - case kHIDUsage_KeyboardF6: return kVK_F6; - case kHIDUsage_KeyboardF7: return kVK_F7; - case kHIDUsage_KeyboardF8: return kVK_F8; - case kHIDUsage_KeyboardF9: return kVK_F9; - case kHIDUsage_KeyboardF10: return kVK_F10; - case kHIDUsage_KeyboardF11: return kVK_F11; - case kHIDUsage_KeyboardF12: return kVK_F12; + case kHIDUsage_KeyboardF1: + return kVK_F1; + case kHIDUsage_KeyboardF2: + return kVK_F2; + case kHIDUsage_KeyboardF3: + return kVK_F3; + case kHIDUsage_KeyboardF4: + return kVK_F4; + case kHIDUsage_KeyboardF5: + return kVK_F5; + case kHIDUsage_KeyboardF6: + return kVK_F6; + case kHIDUsage_KeyboardF7: + return kVK_F7; + case kHIDUsage_KeyboardF8: + return kVK_F8; + case kHIDUsage_KeyboardF9: + return kVK_F9; + case kHIDUsage_KeyboardF10: + return kVK_F10; + case kHIDUsage_KeyboardF11: + return kVK_F11; + case kHIDUsage_KeyboardF12: + return kVK_F12; - case kHIDUsage_KeyboardPrintScreen: return INVALID_KEY; - case kHIDUsage_KeyboardScrollLock: return INVALID_KEY; - case kHIDUsage_KeyboardPause: return INVALID_KEY; - case kHIDUsage_KeyboardInsert: return kVK_Help; - case kHIDUsage_KeyboardHome: return kVK_Home; - case kHIDUsage_KeyboardPageUp: return kVK_PageUp; - case kHIDUsage_KeyboardDeleteForward: return kVK_ForwardDelete; - case kHIDUsage_KeyboardEnd: return kVK_End; - case kHIDUsage_KeyboardPageDown: return kVK_PageDown; + case kHIDUsage_KeyboardPrintScreen: + return INVALID_KEY; + case kHIDUsage_KeyboardScrollLock: + return INVALID_KEY; + case kHIDUsage_KeyboardPause: + return INVALID_KEY; + case kHIDUsage_KeyboardInsert: + return kVK_Help; + case kHIDUsage_KeyboardHome: + return kVK_Home; + case kHIDUsage_KeyboardPageUp: + return kVK_PageUp; + case kHIDUsage_KeyboardDeleteForward: + return kVK_ForwardDelete; + case kHIDUsage_KeyboardEnd: + return kVK_End; + case kHIDUsage_KeyboardPageDown: + return kVK_PageDown; - case kHIDUsage_KeyboardRightArrow: return kVK_RightArrow; - case kHIDUsage_KeyboardLeftArrow: return kVK_LeftArrow; - case kHIDUsage_KeyboardDownArrow: return kVK_DownArrow; - case kHIDUsage_KeyboardUpArrow: return kVK_UpArrow; + case kHIDUsage_KeyboardRightArrow: + return kVK_RightArrow; + case kHIDUsage_KeyboardLeftArrow: + return kVK_LeftArrow; + case kHIDUsage_KeyboardDownArrow: + return kVK_DownArrow; + case kHIDUsage_KeyboardUpArrow: + return kVK_UpArrow; - case kHIDUsage_KeypadNumLock: return kVK_ANSI_KeypadClear; - case kHIDUsage_KeypadSlash: return kVK_ANSI_KeypadDivide; - case kHIDUsage_KeypadAsterisk: return kVK_ANSI_KeypadMultiply; - case kHIDUsage_KeypadHyphen: return kVK_ANSI_KeypadMinus; - case kHIDUsage_KeypadPlus: return kVK_ANSI_KeypadPlus; - case kHIDUsage_KeypadEnter: return kVK_ANSI_KeypadEnter; + case kHIDUsage_KeypadNumLock: + return kVK_ANSI_KeypadClear; + case kHIDUsage_KeypadSlash: + return kVK_ANSI_KeypadDivide; + case kHIDUsage_KeypadAsterisk: + return kVK_ANSI_KeypadMultiply; + case kHIDUsage_KeypadHyphen: + return kVK_ANSI_KeypadMinus; + case kHIDUsage_KeypadPlus: + return kVK_ANSI_KeypadPlus; + case kHIDUsage_KeypadEnter: + return kVK_ANSI_KeypadEnter; - case kHIDUsage_Keypad1: return kVK_ANSI_Keypad1; - case kHIDUsage_Keypad2: return kVK_ANSI_Keypad2; - case kHIDUsage_Keypad3: return kVK_ANSI_Keypad3; - case kHIDUsage_Keypad4: return kVK_ANSI_Keypad4; - case kHIDUsage_Keypad5: return kVK_ANSI_Keypad5; - case kHIDUsage_Keypad6: return kVK_ANSI_Keypad6; - case kHIDUsage_Keypad7: return kVK_ANSI_Keypad7; - case kHIDUsage_Keypad8: return kVK_ANSI_Keypad8; - case kHIDUsage_Keypad9: return kVK_ANSI_Keypad9; - case kHIDUsage_Keypad0: return kVK_ANSI_Keypad0; + case kHIDUsage_Keypad1: + return kVK_ANSI_Keypad1; + case kHIDUsage_Keypad2: + return kVK_ANSI_Keypad2; + case kHIDUsage_Keypad3: + return kVK_ANSI_Keypad3; + case kHIDUsage_Keypad4: + return kVK_ANSI_Keypad4; + case kHIDUsage_Keypad5: + return kVK_ANSI_Keypad5; + case kHIDUsage_Keypad6: + return kVK_ANSI_Keypad6; + case kHIDUsage_Keypad7: + return kVK_ANSI_Keypad7; + case kHIDUsage_Keypad8: + return kVK_ANSI_Keypad8; + case kHIDUsage_Keypad9: + return kVK_ANSI_Keypad9; + case kHIDUsage_Keypad0: + return kVK_ANSI_Keypad0; - case kHIDUsage_KeypadPeriod: return kVK_ANSI_KeypadDecimal; - case kHIDUsage_KeyboardNonUSBackslash: return INVALID_KEY; - case kHIDUsage_KeyboardApplication: return kVK_F13; - case kHIDUsage_KeyboardPower: return INVALID_KEY; - case kHIDUsage_KeypadEqualSign: return kVK_ANSI_KeypadEquals; + case kHIDUsage_KeypadPeriod: + return kVK_ANSI_KeypadDecimal; + case kHIDUsage_KeyboardNonUSBackslash: + return INVALID_KEY; + case kHIDUsage_KeyboardApplication: + return kVK_F13; + case kHIDUsage_KeyboardPower: + return INVALID_KEY; + case kHIDUsage_KeypadEqualSign: + return kVK_ANSI_KeypadEquals; - case kHIDUsage_KeyboardF13: return kVK_F13; - case kHIDUsage_KeyboardF14: return kVK_F14; - case kHIDUsage_KeyboardF15: return kVK_F15; - case kHIDUsage_KeyboardF16: return kVK_F16; - case kHIDUsage_KeyboardF17: return kVK_F17; - case kHIDUsage_KeyboardF18: return kVK_F18; - case kHIDUsage_KeyboardF19: return kVK_F19; - case kHIDUsage_KeyboardF20: return kVK_F20; - case kHIDUsage_KeyboardF21: return INVALID_KEY; - case kHIDUsage_KeyboardF22: return INVALID_KEY; - case kHIDUsage_KeyboardF23: return INVALID_KEY; - case kHIDUsage_KeyboardF24: return INVALID_KEY; + case kHIDUsage_KeyboardF13: + return kVK_F13; + case kHIDUsage_KeyboardF14: + return kVK_F14; + case kHIDUsage_KeyboardF15: + return kVK_F15; + case kHIDUsage_KeyboardF16: + return kVK_F16; + case kHIDUsage_KeyboardF17: + return kVK_F17; + case kHIDUsage_KeyboardF18: + return kVK_F18; + case kHIDUsage_KeyboardF19: + return kVK_F19; + case kHIDUsage_KeyboardF20: + return kVK_F20; + case kHIDUsage_KeyboardF21: + return INVALID_KEY; + case kHIDUsage_KeyboardF22: + return INVALID_KEY; + case kHIDUsage_KeyboardF23: + return INVALID_KEY; + case kHIDUsage_KeyboardF24: + return INVALID_KEY; - case kHIDUsage_KeyboardExecute: return INVALID_KEY; - case kHIDUsage_KeyboardHelp: return INVALID_KEY; - case kHIDUsage_KeyboardMenu: return 0x7F; - case kHIDUsage_KeyboardSelect: return kVK_ANSI_KeypadEnter; - case kHIDUsage_KeyboardStop: return INVALID_KEY; - case kHIDUsage_KeyboardAgain: return INVALID_KEY; - case kHIDUsage_KeyboardUndo: return INVALID_KEY; - case kHIDUsage_KeyboardCut: return INVALID_KEY; - case kHIDUsage_KeyboardCopy: return INVALID_KEY; - case kHIDUsage_KeyboardPaste: return INVALID_KEY; - case kHIDUsage_KeyboardFind: return INVALID_KEY; + case kHIDUsage_KeyboardExecute: + return INVALID_KEY; + case kHIDUsage_KeyboardHelp: + return INVALID_KEY; + case kHIDUsage_KeyboardMenu: + return 0x7F; + case kHIDUsage_KeyboardSelect: + return kVK_ANSI_KeypadEnter; + case kHIDUsage_KeyboardStop: + return INVALID_KEY; + case kHIDUsage_KeyboardAgain: + return INVALID_KEY; + case kHIDUsage_KeyboardUndo: + return INVALID_KEY; + case kHIDUsage_KeyboardCut: + return INVALID_KEY; + case kHIDUsage_KeyboardCopy: + return INVALID_KEY; + case kHIDUsage_KeyboardPaste: + return INVALID_KEY; + case kHIDUsage_KeyboardFind: + return INVALID_KEY; - case kHIDUsage_KeyboardMute: return kVK_Mute; - case kHIDUsage_KeyboardVolumeUp: return kVK_VolumeUp; - case kHIDUsage_KeyboardVolumeDown: return kVK_VolumeDown; + case kHIDUsage_KeyboardMute: + return kVK_Mute; + case kHIDUsage_KeyboardVolumeUp: + return kVK_VolumeUp; + case kHIDUsage_KeyboardVolumeDown: + return kVK_VolumeDown; - case kHIDUsage_KeyboardLockingCapsLock: return INVALID_KEY; - case kHIDUsage_KeyboardLockingNumLock: return INVALID_KEY; - case kHIDUsage_KeyboardLockingScrollLock: return INVALID_KEY; + case kHIDUsage_KeyboardLockingCapsLock: + return INVALID_KEY; + case kHIDUsage_KeyboardLockingNumLock: + return INVALID_KEY; + case kHIDUsage_KeyboardLockingScrollLock: + return INVALID_KEY; - case kHIDUsage_KeypadComma: return INVALID_KEY; - case kHIDUsage_KeypadEqualSignAS400: return INVALID_KEY; - case kHIDUsage_KeyboardInternational1: return INVALID_KEY; - case kHIDUsage_KeyboardInternational2: return INVALID_KEY; - case kHIDUsage_KeyboardInternational3: return INVALID_KEY; - case kHIDUsage_KeyboardInternational4: return INVALID_KEY; - case kHIDUsage_KeyboardInternational5: return INVALID_KEY; - case kHIDUsage_KeyboardInternational6: return INVALID_KEY; - case kHIDUsage_KeyboardInternational7: return INVALID_KEY; - case kHIDUsage_KeyboardInternational8: return INVALID_KEY; - case kHIDUsage_KeyboardInternational9: return INVALID_KEY; + case kHIDUsage_KeypadComma: + return INVALID_KEY; + case kHIDUsage_KeypadEqualSignAS400: + return INVALID_KEY; + case kHIDUsage_KeyboardInternational1: + return INVALID_KEY; + case kHIDUsage_KeyboardInternational2: + return INVALID_KEY; + case kHIDUsage_KeyboardInternational3: + return INVALID_KEY; + case kHIDUsage_KeyboardInternational4: + return INVALID_KEY; + case kHIDUsage_KeyboardInternational5: + return INVALID_KEY; + case kHIDUsage_KeyboardInternational6: + return INVALID_KEY; + case kHIDUsage_KeyboardInternational7: + return INVALID_KEY; + case kHIDUsage_KeyboardInternational8: + return INVALID_KEY; + case kHIDUsage_KeyboardInternational9: + return INVALID_KEY; - case kHIDUsage_KeyboardLANG1: return INVALID_KEY; - case kHIDUsage_KeyboardLANG2: return INVALID_KEY; - case kHIDUsage_KeyboardLANG3: return INVALID_KEY; - case kHIDUsage_KeyboardLANG4: return INVALID_KEY; - case kHIDUsage_KeyboardLANG5: return INVALID_KEY; - case kHIDUsage_KeyboardLANG6: return INVALID_KEY; - case kHIDUsage_KeyboardLANG7: return INVALID_KEY; - case kHIDUsage_KeyboardLANG8: return INVALID_KEY; - case kHIDUsage_KeyboardLANG9: return INVALID_KEY; + case kHIDUsage_KeyboardLANG1: + return INVALID_KEY; + case kHIDUsage_KeyboardLANG2: + return INVALID_KEY; + case kHIDUsage_KeyboardLANG3: + return INVALID_KEY; + case kHIDUsage_KeyboardLANG4: + return INVALID_KEY; + case kHIDUsage_KeyboardLANG5: + return INVALID_KEY; + case kHIDUsage_KeyboardLANG6: + return INVALID_KEY; + case kHIDUsage_KeyboardLANG7: + return INVALID_KEY; + case kHIDUsage_KeyboardLANG8: + return INVALID_KEY; + case kHIDUsage_KeyboardLANG9: + return INVALID_KEY; - case kHIDUsage_KeyboardAlternateErase: return INVALID_KEY; - case kHIDUsage_KeyboardSysReqOrAttention: return INVALID_KEY; - case kHIDUsage_KeyboardCancel: return INVALID_KEY; - case kHIDUsage_KeyboardClear: return INVALID_KEY; - case kHIDUsage_KeyboardPrior: return INVALID_KEY; - case kHIDUsage_KeyboardReturn: return INVALID_KEY; - case kHIDUsage_KeyboardSeparator: return INVALID_KEY; - case kHIDUsage_KeyboardOut: return INVALID_KEY; - case kHIDUsage_KeyboardOper: return INVALID_KEY; - case kHIDUsage_KeyboardClearOrAgain: return INVALID_KEY; - case kHIDUsage_KeyboardCrSelOrProps: return INVALID_KEY; - case kHIDUsage_KeyboardExSel: return INVALID_KEY; + case kHIDUsage_KeyboardAlternateErase: + return INVALID_KEY; + case kHIDUsage_KeyboardSysReqOrAttention: + return INVALID_KEY; + case kHIDUsage_KeyboardCancel: + return INVALID_KEY; + case kHIDUsage_KeyboardClear: + return INVALID_KEY; + case kHIDUsage_KeyboardPrior: + return INVALID_KEY; + case kHIDUsage_KeyboardReturn: + return INVALID_KEY; + case kHIDUsage_KeyboardSeparator: + return INVALID_KEY; + case kHIDUsage_KeyboardOut: + return INVALID_KEY; + case kHIDUsage_KeyboardOper: + return INVALID_KEY; + case kHIDUsage_KeyboardClearOrAgain: + return INVALID_KEY; + case kHIDUsage_KeyboardCrSelOrProps: + return INVALID_KEY; + case kHIDUsage_KeyboardExSel: + return INVALID_KEY; - /* 0xa5-0xdf Reserved */ + /* 0xa5-0xdf Reserved */ - case kHIDUsage_KeyboardLeftControl: return kVK_Control; - case kHIDUsage_KeyboardLeftShift: return kVK_Shift; - case kHIDUsage_KeyboardLeftAlt: return kVK_Option; - case kHIDUsage_KeyboardLeftGUI: return kVK_Command; - case kHIDUsage_KeyboardRightControl: return kVK_RightControl; - case kHIDUsage_KeyboardRightShift: return kVK_RightShift; - case kHIDUsage_KeyboardRightAlt: return kVK_RightOption; - case kHIDUsage_KeyboardRightGUI: return 0x36; //?? + case kHIDUsage_KeyboardLeftControl: + return kVK_Control; + case kHIDUsage_KeyboardLeftShift: + return kVK_Shift; + case kHIDUsage_KeyboardLeftAlt: + return kVK_Option; + case kHIDUsage_KeyboardLeftGUI: + return kVK_Command; + case kHIDUsage_KeyboardRightControl: + return kVK_RightControl; + case kHIDUsage_KeyboardRightShift: + return kVK_RightShift; + case kHIDUsage_KeyboardRightAlt: + return kVK_RightOption; + case kHIDUsage_KeyboardRightGUI: + return 0x36; //?? - /* 0xe8-0xffff Reserved */ + /* 0xe8-0xffff Reserved */ - case kHIDUsage_Keyboard_Reserved: return INVALID_KEY; - default: return INVALID_KEY; + case kHIDUsage_Keyboard_Reserved: + return INVALID_KEY; + default: + return INVALID_KEY; } return INVALID_KEY; } @@ -881,126 +1162,236 @@ static UInt16 usage_to_carbon(UInt32 usage) obs_key_t obs_key_from_virtual_key(int code) { switch (code) { - case kVK_ANSI_A: return OBS_KEY_A; - case kVK_ANSI_B: return OBS_KEY_B; - case kVK_ANSI_C: return OBS_KEY_C; - case kVK_ANSI_D: return OBS_KEY_D; - case kVK_ANSI_E: return OBS_KEY_E; - case kVK_ANSI_F: return OBS_KEY_F; - case kVK_ANSI_G: return OBS_KEY_G; - case kVK_ANSI_H: return OBS_KEY_H; - case kVK_ANSI_I: return OBS_KEY_I; - case kVK_ANSI_J: return OBS_KEY_J; - case kVK_ANSI_K: return OBS_KEY_K; - case kVK_ANSI_L: return OBS_KEY_L; - case kVK_ANSI_M: return OBS_KEY_M; - case kVK_ANSI_N: return OBS_KEY_N; - case kVK_ANSI_O: return OBS_KEY_O; - case kVK_ANSI_P: return OBS_KEY_P; - case kVK_ANSI_Q: return OBS_KEY_Q; - case kVK_ANSI_R: return OBS_KEY_R; - case kVK_ANSI_S: return OBS_KEY_S; - case kVK_ANSI_T: return OBS_KEY_T; - case kVK_ANSI_U: return OBS_KEY_U; - case kVK_ANSI_V: return OBS_KEY_V; - case kVK_ANSI_W: return OBS_KEY_W; - case kVK_ANSI_X: return OBS_KEY_X; - case kVK_ANSI_Y: return OBS_KEY_Y; - case kVK_ANSI_Z: return OBS_KEY_Z; + case kVK_ANSI_A: + return OBS_KEY_A; + case kVK_ANSI_B: + return OBS_KEY_B; + case kVK_ANSI_C: + return OBS_KEY_C; + case kVK_ANSI_D: + return OBS_KEY_D; + case kVK_ANSI_E: + return OBS_KEY_E; + case kVK_ANSI_F: + return OBS_KEY_F; + case kVK_ANSI_G: + return OBS_KEY_G; + case kVK_ANSI_H: + return OBS_KEY_H; + case kVK_ANSI_I: + return OBS_KEY_I; + case kVK_ANSI_J: + return OBS_KEY_J; + case kVK_ANSI_K: + return OBS_KEY_K; + case kVK_ANSI_L: + return OBS_KEY_L; + case kVK_ANSI_M: + return OBS_KEY_M; + case kVK_ANSI_N: + return OBS_KEY_N; + case kVK_ANSI_O: + return OBS_KEY_O; + case kVK_ANSI_P: + return OBS_KEY_P; + case kVK_ANSI_Q: + return OBS_KEY_Q; + case kVK_ANSI_R: + return OBS_KEY_R; + case kVK_ANSI_S: + return OBS_KEY_S; + case kVK_ANSI_T: + return OBS_KEY_T; + case kVK_ANSI_U: + return OBS_KEY_U; + case kVK_ANSI_V: + return OBS_KEY_V; + case kVK_ANSI_W: + return OBS_KEY_W; + case kVK_ANSI_X: + return OBS_KEY_X; + case kVK_ANSI_Y: + return OBS_KEY_Y; + case kVK_ANSI_Z: + return OBS_KEY_Z; - case kVK_ANSI_1: return OBS_KEY_1; - case kVK_ANSI_2: return OBS_KEY_2; - case kVK_ANSI_3: return OBS_KEY_3; - case kVK_ANSI_4: return OBS_KEY_4; - case kVK_ANSI_5: return OBS_KEY_5; - case kVK_ANSI_6: return OBS_KEY_6; - case kVK_ANSI_7: return OBS_KEY_7; - case kVK_ANSI_8: return OBS_KEY_8; - case kVK_ANSI_9: return OBS_KEY_9; - case kVK_ANSI_0: return OBS_KEY_0; + case kVK_ANSI_1: + return OBS_KEY_1; + case kVK_ANSI_2: + return OBS_KEY_2; + case kVK_ANSI_3: + return OBS_KEY_3; + case kVK_ANSI_4: + return OBS_KEY_4; + case kVK_ANSI_5: + return OBS_KEY_5; + case kVK_ANSI_6: + return OBS_KEY_6; + case kVK_ANSI_7: + return OBS_KEY_7; + case kVK_ANSI_8: + return OBS_KEY_8; + case kVK_ANSI_9: + return OBS_KEY_9; + case kVK_ANSI_0: + return OBS_KEY_0; - case kVK_Return: return OBS_KEY_RETURN; - case kVK_Escape: return OBS_KEY_ESCAPE; - case kVK_Delete: return OBS_KEY_BACKSPACE; - case kVK_Tab: return OBS_KEY_TAB; - case kVK_Space: return OBS_KEY_SPACE; - case kVK_ANSI_Minus: return OBS_KEY_MINUS; - case kVK_ANSI_Equal: return OBS_KEY_EQUAL; - case kVK_ANSI_LeftBracket: return OBS_KEY_BRACKETLEFT; - case kVK_ANSI_RightBracket: return OBS_KEY_BRACKETRIGHT; - case kVK_ANSI_Backslash: return OBS_KEY_BACKSLASH; - case kVK_ANSI_Semicolon: return OBS_KEY_SEMICOLON; - case kVK_ANSI_Quote: return OBS_KEY_QUOTE; - case kVK_ANSI_Grave: return OBS_KEY_DEAD_GRAVE; - case kVK_ANSI_Comma: return OBS_KEY_COMMA; - case kVK_ANSI_Period: return OBS_KEY_PERIOD; - case kVK_ANSI_Slash: return OBS_KEY_SLASH; - case kVK_CapsLock: return OBS_KEY_CAPSLOCK; - case kVK_ISO_Section: return OBS_KEY_SECTION; + case kVK_Return: + return OBS_KEY_RETURN; + case kVK_Escape: + return OBS_KEY_ESCAPE; + case kVK_Delete: + return OBS_KEY_BACKSPACE; + case kVK_Tab: + return OBS_KEY_TAB; + case kVK_Space: + return OBS_KEY_SPACE; + case kVK_ANSI_Minus: + return OBS_KEY_MINUS; + case kVK_ANSI_Equal: + return OBS_KEY_EQUAL; + case kVK_ANSI_LeftBracket: + return OBS_KEY_BRACKETLEFT; + case kVK_ANSI_RightBracket: + return OBS_KEY_BRACKETRIGHT; + case kVK_ANSI_Backslash: + return OBS_KEY_BACKSLASH; + case kVK_ANSI_Semicolon: + return OBS_KEY_SEMICOLON; + case kVK_ANSI_Quote: + return OBS_KEY_QUOTE; + case kVK_ANSI_Grave: + return OBS_KEY_DEAD_GRAVE; + case kVK_ANSI_Comma: + return OBS_KEY_COMMA; + case kVK_ANSI_Period: + return OBS_KEY_PERIOD; + case kVK_ANSI_Slash: + return OBS_KEY_SLASH; + case kVK_CapsLock: + return OBS_KEY_CAPSLOCK; + case kVK_ISO_Section: + return OBS_KEY_SECTION; - case kVK_F1: return OBS_KEY_F1; - case kVK_F2: return OBS_KEY_F2; - case kVK_F3: return OBS_KEY_F3; - case kVK_F4: return OBS_KEY_F4; - case kVK_F5: return OBS_KEY_F5; - case kVK_F6: return OBS_KEY_F6; - case kVK_F7: return OBS_KEY_F7; - case kVK_F8: return OBS_KEY_F8; - case kVK_F9: return OBS_KEY_F9; - case kVK_F10: return OBS_KEY_F10; - case kVK_F11: return OBS_KEY_F11; - case kVK_F12: return OBS_KEY_F12; + case kVK_F1: + return OBS_KEY_F1; + case kVK_F2: + return OBS_KEY_F2; + case kVK_F3: + return OBS_KEY_F3; + case kVK_F4: + return OBS_KEY_F4; + case kVK_F5: + return OBS_KEY_F5; + case kVK_F6: + return OBS_KEY_F6; + case kVK_F7: + return OBS_KEY_F7; + case kVK_F8: + return OBS_KEY_F8; + case kVK_F9: + return OBS_KEY_F9; + case kVK_F10: + return OBS_KEY_F10; + case kVK_F11: + return OBS_KEY_F11; + case kVK_F12: + return OBS_KEY_F12; - case kVK_Help: return OBS_KEY_HELP; - case kVK_Home: return OBS_KEY_HOME; - case kVK_PageUp: return OBS_KEY_PAGEUP; - case kVK_ForwardDelete: return OBS_KEY_DELETE; - case kVK_End: return OBS_KEY_END; - case kVK_PageDown: return OBS_KEY_PAGEDOWN; + case kVK_Help: + return OBS_KEY_HELP; + case kVK_Home: + return OBS_KEY_HOME; + case kVK_PageUp: + return OBS_KEY_PAGEUP; + case kVK_ForwardDelete: + return OBS_KEY_DELETE; + case kVK_End: + return OBS_KEY_END; + case kVK_PageDown: + return OBS_KEY_PAGEDOWN; - case kVK_RightArrow: return OBS_KEY_RIGHT; - case kVK_LeftArrow: return OBS_KEY_LEFT; - case kVK_DownArrow: return OBS_KEY_DOWN; - case kVK_UpArrow: return OBS_KEY_UP; + case kVK_RightArrow: + return OBS_KEY_RIGHT; + case kVK_LeftArrow: + return OBS_KEY_LEFT; + case kVK_DownArrow: + return OBS_KEY_DOWN; + case kVK_UpArrow: + return OBS_KEY_UP; - case kVK_ANSI_KeypadClear: return OBS_KEY_CLEAR; - case kVK_ANSI_KeypadDivide: return OBS_KEY_NUMSLASH; - case kVK_ANSI_KeypadMultiply: return OBS_KEY_NUMASTERISK; - case kVK_ANSI_KeypadMinus: return OBS_KEY_NUMMINUS; - case kVK_ANSI_KeypadPlus: return OBS_KEY_NUMPLUS; - case kVK_ANSI_KeypadEnter: return OBS_KEY_ENTER; + case kVK_ANSI_KeypadClear: + return OBS_KEY_CLEAR; + case kVK_ANSI_KeypadDivide: + return OBS_KEY_NUMSLASH; + case kVK_ANSI_KeypadMultiply: + return OBS_KEY_NUMASTERISK; + case kVK_ANSI_KeypadMinus: + return OBS_KEY_NUMMINUS; + case kVK_ANSI_KeypadPlus: + return OBS_KEY_NUMPLUS; + case kVK_ANSI_KeypadEnter: + return OBS_KEY_ENTER; - case kVK_ANSI_Keypad1: return OBS_KEY_NUM1; - case kVK_ANSI_Keypad2: return OBS_KEY_NUM2; - case kVK_ANSI_Keypad3: return OBS_KEY_NUM3; - case kVK_ANSI_Keypad4: return OBS_KEY_NUM4; - case kVK_ANSI_Keypad5: return OBS_KEY_NUM5; - case kVK_ANSI_Keypad6: return OBS_KEY_NUM6; - case kVK_ANSI_Keypad7: return OBS_KEY_NUM7; - case kVK_ANSI_Keypad8: return OBS_KEY_NUM8; - case kVK_ANSI_Keypad9: return OBS_KEY_NUM9; - case kVK_ANSI_Keypad0: return OBS_KEY_NUM0; + case kVK_ANSI_Keypad1: + return OBS_KEY_NUM1; + case kVK_ANSI_Keypad2: + return OBS_KEY_NUM2; + case kVK_ANSI_Keypad3: + return OBS_KEY_NUM3; + case kVK_ANSI_Keypad4: + return OBS_KEY_NUM4; + case kVK_ANSI_Keypad5: + return OBS_KEY_NUM5; + case kVK_ANSI_Keypad6: + return OBS_KEY_NUM6; + case kVK_ANSI_Keypad7: + return OBS_KEY_NUM7; + case kVK_ANSI_Keypad8: + return OBS_KEY_NUM8; + case kVK_ANSI_Keypad9: + return OBS_KEY_NUM9; + case kVK_ANSI_Keypad0: + return OBS_KEY_NUM0; - case kVK_ANSI_KeypadDecimal: return OBS_KEY_NUMPERIOD; - case kVK_ANSI_KeypadEquals: return OBS_KEY_NUMEQUAL; + case kVK_ANSI_KeypadDecimal: + return OBS_KEY_NUMPERIOD; + case kVK_ANSI_KeypadEquals: + return OBS_KEY_NUMEQUAL; - case kVK_F13: return OBS_KEY_F13; - case kVK_F14: return OBS_KEY_F14; - case kVK_F15: return OBS_KEY_F15; - case kVK_F16: return OBS_KEY_F16; - case kVK_F17: return OBS_KEY_F17; - case kVK_F18: return OBS_KEY_F18; - case kVK_F19: return OBS_KEY_F19; - case kVK_F20: return OBS_KEY_F20; + case kVK_F13: + return OBS_KEY_F13; + case kVK_F14: + return OBS_KEY_F14; + case kVK_F15: + return OBS_KEY_F15; + case kVK_F16: + return OBS_KEY_F16; + case kVK_F17: + return OBS_KEY_F17; + case kVK_F18: + return OBS_KEY_F18; + case kVK_F19: + return OBS_KEY_F19; + case kVK_F20: + return OBS_KEY_F20; - case kVK_Control: return OBS_KEY_CONTROL; - case kVK_Shift: return OBS_KEY_SHIFT; - case kVK_Option: return OBS_KEY_ALT; - case kVK_Command: return OBS_KEY_META; - case kVK_RightControl: return OBS_KEY_CONTROL; - case kVK_RightShift: return OBS_KEY_SHIFT; - case kVK_RightOption: return OBS_KEY_ALT; - case 0x36: return OBS_KEY_META; + case kVK_Control: + return OBS_KEY_CONTROL; + case kVK_Shift: + return OBS_KEY_SHIFT; + case kVK_Option: + return OBS_KEY_ALT; + case kVK_Command: + return OBS_KEY_META; + case kVK_RightControl: + return OBS_KEY_CONTROL; + case kVK_RightShift: + return OBS_KEY_SHIFT; + case kVK_RightOption: + return OBS_KEY_ALT; + case 0x36: + return OBS_KEY_META; case kVK_Function: case kVK_Mute: @@ -1013,24 +1404,25 @@ obs_key_t obs_key_from_virtual_key(int code) static inline void load_key(obs_hotkeys_platform_t *plat, IOHIDElementRef key) { - UInt32 usage_code = IOHIDElementGetUsage(key); + UInt32 usage_code = IOHIDElementGetUsage(key); UInt16 carbon_code = usage_to_carbon(usage_code); - if (carbon_code == INVALID_KEY) return; + if (carbon_code == INVALID_KEY) + return; obs_key_t obs_key = obs_key_from_virtual_key(carbon_code); if (obs_key == OBS_KEY_NONE) return; da_push_back(plat->keys[obs_key], &key); - CFRetain(*(IOHIDElementRef*)da_end(plat->keys[obs_key])); + CFRetain(*(IOHIDElementRef *)da_end(plat->keys[obs_key])); } static inline void load_keyboard(obs_hotkeys_platform_t *plat, - IOHIDDeviceRef keyboard) + IOHIDDeviceRef keyboard) { - CFArrayRef keys = IOHIDDeviceCopyMatchingElements(keyboard, NULL, - kIOHIDOptionsTypeNone); + CFArrayRef keys = IOHIDDeviceCopyMatchingElements( + keyboard, NULL, kIOHIDOptionsTypeNone); if (!keys) { blog(LOG_ERROR, "hotkeys-cocoa: Getting keyboard keys failed"); @@ -1061,7 +1453,7 @@ static inline void load_keyboard(obs_hotkeys_platform_t *plat, static bool init_keyboard(obs_hotkeys_platform_t *plat) { CFSetRef keyboards = copy_devices(plat, kHIDPage_GenericDesktop, - kHIDUsage_GD_Keyboard); + kHIDUsage_GD_Keyboard); if (!keyboards) return false; @@ -1110,8 +1502,8 @@ static inline void free_hotkeys_platform(obs_hotkeys_platform_t *plat) static bool log_layout_name(TISInputSourceRef tis) { struct dstr layout_name = {0}; - CFStringRef sid = (CFStringRef)TISGetInputSourceProperty(tis, - kTISPropertyInputSourceID); + CFStringRef sid = (CFStringRef)TISGetInputSourceProperty( + tis, kTISPropertyInputSourceID); if (!sid) { blog(LOG_ERROR, "hotkeys-cocoa: Failed getting InputSourceID"); return false; @@ -1145,9 +1537,9 @@ static bool init_hotkeys_platform(obs_hotkeys_platform_t **plat_) return false; } - plat->tis = TISCopyCurrentKeyboardLayoutInputSource(); - plat->layout_data = (CFDataRef)TISGetInputSourceProperty(plat->tis, - kTISPropertyUnicodeKeyLayoutData); + plat->tis = TISCopyCurrentKeyboardLayoutInputSource(); + plat->layout_data = (CFDataRef)TISGetInputSourceProperty( + plat->tis, kTISPropertyUnicodeKeyLayoutData); if (!plat->layout_data) { blog(LOG_ERROR, "hotkeys-cocoa: Failed getting LayoutData"); @@ -1155,13 +1547,13 @@ static bool init_hotkeys_platform(obs_hotkeys_platform_t **plat_) } CFRetain(plat->layout_data); - plat->layout = (UCKeyboardLayout*)CFDataGetBytePtr(plat->layout_data); + plat->layout = (UCKeyboardLayout *)CFDataGetBytePtr(plat->layout_data); - plat->manager = IOHIDManagerCreate(kCFAllocatorDefault, - kIOHIDOptionsTypeNone); + plat->manager = + IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); - IOReturn openStatus = IOHIDManagerOpen(plat->manager, - kIOHIDOptionsTypeNone); + IOReturn openStatus = + IOHIDManagerOpen(plat->manager, kIOHIDOptionsTypeNone); if (openStatus != kIOReturnSuccess) { blog(LOG_ERROR, "hotkeys-cocoa: Failed opening HIDManager"); goto fail; @@ -1178,7 +1570,8 @@ fail: } static void input_method_changed(CFNotificationCenterRef nc, void *observer, - CFStringRef name, const void *object, CFDictionaryRef user_info) + CFStringRef name, const void *object, + CFDictionaryRef user_info) { UNUSED_PARAMETER(nc); UNUSED_PARAMETER(name); @@ -1195,7 +1588,7 @@ static void input_method_changed(CFNotificationCenterRef nc, void *observer, plat = hotkeys->platform_context; if (new_plat && plat && - new_plat->layout_data == plat->layout_data) { + new_plat->layout_data == plat->layout_data) { pthread_mutex_unlock(&hotkeys->mutex); hotkeys_release(new_plat); return; @@ -1207,21 +1600,20 @@ static void input_method_changed(CFNotificationCenterRef nc, void *observer, pthread_mutex_unlock(&hotkeys->mutex); calldata_t params = {0}; - signal_handler_signal(hotkeys->signals, - "hotkey_layout_change", ¶ms); + signal_handler_signal(hotkeys->signals, "hotkey_layout_change", + ¶ms); if (plat) hotkeys_release(plat); } } - bool obs_hotkeys_platform_init(struct obs_core_hotkeys *hotkeys) { CFNotificationCenterAddObserver( - CFNotificationCenterGetDistributedCenter(), - hotkeys, input_method_changed, - kTISNotifySelectedKeyboardInputSourceChanged, NULL, - CFNotificationSuspensionBehaviorDeliverImmediately); + CFNotificationCenterGetDistributedCenter(), hotkeys, + input_method_changed, + kTISNotifySelectedKeyboardInputSourceChanged, NULL, + CFNotificationSuspensionBehaviorDeliverImmediately); input_method_changed(NULL, hotkeys, NULL, NULL, NULL); return hotkeys->platform_context != NULL; @@ -1230,8 +1622,7 @@ bool obs_hotkeys_platform_init(struct obs_core_hotkeys *hotkeys) void obs_hotkeys_platform_free(struct obs_core_hotkeys *hotkeys) { CFNotificationCenterRemoveEveryObserver( - CFNotificationCenterGetDistributedCenter(), - hotkeys); + CFNotificationCenterGetDistributedCenter(), hotkeys); hotkeys_release(hotkeys->platform_context); } @@ -1241,36 +1632,39 @@ static bool mouse_button_pressed(obs_key_t key, bool *pressed) { int button = 0; switch (key) { -#define MAP_BUTTON(n) case OBS_KEY_MOUSE ## n: button = n - 1; break - MAP_BUTTON(1); - MAP_BUTTON(2); - MAP_BUTTON(3); - MAP_BUTTON(4); - MAP_BUTTON(5); - MAP_BUTTON(6); - MAP_BUTTON(7); - MAP_BUTTON(8); - MAP_BUTTON(9); - MAP_BUTTON(10); - MAP_BUTTON(11); - MAP_BUTTON(12); - MAP_BUTTON(13); - MAP_BUTTON(14); - MAP_BUTTON(15); - MAP_BUTTON(16); - MAP_BUTTON(17); - MAP_BUTTON(18); - MAP_BUTTON(19); - MAP_BUTTON(20); - MAP_BUTTON(21); - MAP_BUTTON(22); - MAP_BUTTON(23); - MAP_BUTTON(24); - MAP_BUTTON(25); - MAP_BUTTON(26); - MAP_BUTTON(27); - MAP_BUTTON(28); - MAP_BUTTON(29); +#define MAP_BUTTON(n) \ + case OBS_KEY_MOUSE##n: \ + button = n - 1; \ + break + MAP_BUTTON(1); + MAP_BUTTON(2); + MAP_BUTTON(3); + MAP_BUTTON(4); + MAP_BUTTON(5); + MAP_BUTTON(6); + MAP_BUTTON(7); + MAP_BUTTON(8); + MAP_BUTTON(9); + MAP_BUTTON(10); + MAP_BUTTON(11); + MAP_BUTTON(12); + MAP_BUTTON(13); + MAP_BUTTON(14); + MAP_BUTTON(15); + MAP_BUTTON(16); + MAP_BUTTON(17); + MAP_BUTTON(18); + MAP_BUTTON(19); + MAP_BUTTON(20); + MAP_BUTTON(21); + MAP_BUTTON(22); + MAP_BUTTON(23); + MAP_BUTTON(24); + MAP_BUTTON(25); + MAP_BUTTON(26); + MAP_BUTTON(27); + MAP_BUTTON(28); + MAP_BUTTON(29); break; #undef MAP_BUTTON @@ -1280,15 +1674,15 @@ static bool mouse_button_pressed(obs_key_t key, bool *pressed) Class NSEvent = objc_getClass("NSEvent"); SEL pressedMouseButtons = sel_registerName("pressedMouseButtons"); - NSUInteger buttons = (NSUInteger)objc_msgSend((id)NSEvent, - pressedMouseButtons); + NSUInteger buttons = + (NSUInteger)objc_msgSend((id)NSEvent, pressedMouseButtons); *pressed = (buttons & (1 << button)) != 0; return true; } bool obs_hotkeys_platform_is_pressed(obs_hotkeys_platform_t *plat, - obs_key_t key) + obs_key_t key) { bool mouse_pressed = false; if (mouse_button_pressed(key, &mouse_pressed)) @@ -1302,11 +1696,11 @@ bool obs_hotkeys_platform_is_pressed(obs_hotkeys_platform_t *plat, for (size_t i = 0; i < plat->keys[key].num;) { IOHIDElementRef element = plat->keys[key].array[i]; - IOHIDValueRef value = 0; - IOHIDDeviceRef device = IOHIDElementGetDevice(element); - + IOHIDValueRef value = 0; + IOHIDDeviceRef device = IOHIDElementGetDevice(element); + if (IOHIDDeviceGetValue(device, element, &value) != - kIOReturnSuccess) { + kIOReturnSuccess) { i += 1; continue; } diff --git a/libobs/obs-config.h b/libobs/obs-config.h index c233ff0..e8bc725 100644 --- a/libobs/obs-config.h +++ b/libobs/obs-config.h @@ -27,45 +27,42 @@ /* * Increment if major breaking API changes */ -#define LIBOBS_API_MAJOR_VER 23 +#define LIBOBS_API_MAJOR_VER 24 /* * Increment if backward-compatible additions * * Reset to zero each major version */ -#define LIBOBS_API_MINOR_VER 2 +#define LIBOBS_API_MINOR_VER 0 /* * Increment if backward-compatible bug fix * * Reset to zero each major or minor version */ -#define LIBOBS_API_PATCH_VER 1 +#define LIBOBS_API_PATCH_VER 1 #define MAKE_SEMANTIC_VERSION(major, minor, patch) \ - ((major << 24) | \ - (minor << 16) | \ - patch ) + ((major << 24) | (minor << 16) | patch) -#define LIBOBS_API_VER \ - MAKE_SEMANTIC_VERSION(LIBOBS_API_MAJOR_VER, \ - LIBOBS_API_MINOR_VER, \ - LIBOBS_API_PATCH_VER) +#define LIBOBS_API_VER \ + MAKE_SEMANTIC_VERSION(LIBOBS_API_MAJOR_VER, LIBOBS_API_MINOR_VER, \ + LIBOBS_API_PATCH_VER) #ifdef HAVE_OBSCONFIG_H -# include "obsconfig.h" +#include "obsconfig.h" #else -# define OBS_VERSION "unknown" -# define OBS_DATA_PATH "../../data" -# define OBS_INSTALL_PREFIX "" -# define OBS_PLUGIN_DESTINATION "obs-plugins" -# define OBS_RELATIVE_PREFIX "../../" -# define OBS_RELEASE_CANDIDATE_MAJOR 0 -# define OBS_RELEASE_CANDIDATE_MINOR 0 -# define OBS_RELEASE_CANDIDATE_PATCH 0 -# define OBS_RELEASE_CANDIDATE_VER 0 -# define OBS_RELEASE_CANDIDATE 0 +#define OBS_VERSION "unknown" +#define OBS_DATA_PATH "../../data" +#define OBS_INSTALL_PREFIX "" +#define OBS_PLUGIN_DESTINATION "obs-plugins" +#define OBS_RELATIVE_PREFIX "../../" +#define OBS_RELEASE_CANDIDATE_MAJOR 0 +#define OBS_RELEASE_CANDIDATE_MINOR 0 +#define OBS_RELEASE_CANDIDATE_PATCH 0 +#define OBS_RELEASE_CANDIDATE_VER 0 +#define OBS_RELEASE_CANDIDATE 0 #endif #define OBS_INSTALL_DATA_PATH OBS_INSTALL_PREFIX OBS_DATA_PATH diff --git a/libobs/obs-data.c b/libobs/obs-data.c index 676431d..20c6952 100644 --- a/libobs/obs-data.c +++ b/libobs/obs-data.c @@ -29,35 +29,35 @@ #include struct obs_data_item { - volatile long ref; - struct obs_data *parent; + volatile long ref; + struct obs_data *parent; struct obs_data_item *next; - enum obs_data_type type; - size_t name_len; - size_t data_len; - size_t data_size; - size_t default_len; - size_t default_size; - size_t autoselect_size; - size_t capacity; + enum obs_data_type type; + size_t name_len; + size_t data_len; + size_t data_size; + size_t default_len; + size_t default_size; + size_t autoselect_size; + size_t capacity; }; struct obs_data { - volatile long ref; - char *json; + volatile long ref; + char *json; struct obs_data_item *first_item; }; struct obs_data_array { - volatile long ref; - DARRAY(obs_data_t*) objects; + volatile long ref; + DARRAY(obs_data_t *) objects; }; struct obs_data_number { enum obs_data_number_type type; union { long long int_val; - double double_val; + double double_val; }; }; @@ -77,20 +77,20 @@ static inline size_t get_name_align_size(const char *name) size_t alignment = base_get_alignment(); size_t total_size; - total_size = sizeof(struct obs_data_item) + (name_size + alignment-1); - total_size &= ~(alignment-1); + total_size = sizeof(struct obs_data_item) + (name_size + alignment - 1); + total_size &= ~(alignment - 1); return total_size - sizeof(struct obs_data_item); } static inline char *get_item_name(struct obs_data_item *item) { - return (char*)item + sizeof(struct obs_data_item); + return (char *)item + sizeof(struct obs_data_item); } static inline void *get_data_ptr(obs_data_item_t *item) { - return (uint8_t*)get_item_name(item) + item->name_len; + return (uint8_t *)get_item_name(item) + item->name_len; } static inline void *get_item_data(struct obs_data_item *item) @@ -102,7 +102,7 @@ static inline void *get_item_data(struct obs_data_item *item) static inline void *get_default_data_ptr(obs_data_item_t *item) { - return (uint8_t*)get_data_ptr(item) + item->data_len; + return (uint8_t *)get_data_ptr(item) + item->data_len; } static inline void *get_item_default_data(struct obs_data_item *item) @@ -112,7 +112,7 @@ static inline void *get_item_default_data(struct obs_data_item *item) static inline void *get_autoselect_data_ptr(obs_data_item_t *item) { - return (uint8_t*)get_default_data_ptr(item) + item->default_len; + return (uint8_t *)get_default_data_ptr(item) + item->default_len; } static inline void *get_item_autoselect_data(struct obs_data_item *item) @@ -122,8 +122,8 @@ static inline void *get_item_autoselect_data(struct obs_data_item *item) static inline size_t obs_data_item_total_size(struct obs_data_item *item) { - return sizeof(struct obs_data_item) + item->name_len + - item->data_len + item->default_len + item->autoselect_size; + return sizeof(struct obs_data_item) + item->name_len + item->data_len + + item->default_len + item->autoselect_size; } static inline obs_data_t *get_item_obj(struct obs_data_item *item) @@ -143,7 +143,7 @@ static inline obs_data_t *get_item_default_obj(struct obs_data_item *item) if (!item || !item->default_size) return NULL; - return *(obs_data_t**)get_default_data_ptr(item); + return *(obs_data_t **)get_default_data_ptr(item); } static inline obs_data_t *get_item_autoselect_obj(struct obs_data_item *item) @@ -151,7 +151,7 @@ static inline obs_data_t *get_item_autoselect_obj(struct obs_data_item *item) if (!item || !item->autoselect_size) return NULL; - return *(obs_data_t**)get_autoselect_data_ptr(item); + return *(obs_data_t **)get_autoselect_data_ptr(item); } static inline obs_data_array_t *get_item_array(struct obs_data_item *item) @@ -161,26 +161,26 @@ static inline obs_data_array_t *get_item_array(struct obs_data_item *item) if (!item) return NULL; - array = (obs_data_array_t**)get_item_data(item); + array = (obs_data_array_t **)get_item_data(item); return array ? *array : NULL; } -static inline obs_data_array_t *get_item_default_array( - struct obs_data_item *item) +static inline obs_data_array_t * +get_item_default_array(struct obs_data_item *item) { if (!item || !item->default_size) return NULL; - return *(obs_data_array_t**)get_default_data_ptr(item); + return *(obs_data_array_t **)get_default_data_ptr(item); } -static inline obs_data_array_t *get_item_autoselect_array( - struct obs_data_item *item) +static inline obs_data_array_t * +get_item_autoselect_array(struct obs_data_item *item) { if (!item || !item->autoselect_size) return NULL; - return *(obs_data_array_t**)get_autoselect_data_ptr(item); + return *(obs_data_array_t **)get_autoselect_data_ptr(item); } static inline void item_data_release(struct obs_data_item *item) @@ -262,8 +262,10 @@ static inline void item_autoselect_data_addref(struct obs_data_item *item) } static struct obs_data_item *obs_data_item_create(const char *name, - const void *data, size_t size, enum obs_data_type type, - bool default_data, bool autoselect_data) + const void *data, size_t size, + enum obs_data_type type, + bool default_data, + bool autoselect_data) { struct obs_data_item *item; size_t name_size, total_size; @@ -277,9 +279,9 @@ static struct obs_data_item *obs_data_item_create(const char *name, item = bzalloc(total_size); item->capacity = total_size; - item->type = type; + item->type = type; item->name_len = name_size; - item->ref = 1; + item->ref = 1; if (default_data) { item->default_len = size; @@ -301,20 +303,20 @@ static struct obs_data_item *obs_data_item_create(const char *name, } static struct obs_data_item **get_item_prev_next(struct obs_data *data, - struct obs_data_item *current) + struct obs_data_item *current) { if (!current || !data) return NULL; struct obs_data_item **prev_next = &data->first_item; - struct obs_data_item *item = data->first_item; + struct obs_data_item *item = data->first_item; while (item) { if (item == current) return prev_next; prev_next = &item->next; - item = item->next; + item = item->next; } return NULL; @@ -322,8 +324,8 @@ static struct obs_data_item **get_item_prev_next(struct obs_data *data, static inline void obs_data_item_detach(struct obs_data_item *item) { - struct obs_data_item **prev_next = get_item_prev_next(item->parent, - item); + struct obs_data_item **prev_next = + get_item_prev_next(item->parent, item); if (prev_next) { *prev_next = item->next; @@ -332,17 +334,17 @@ static inline void obs_data_item_detach(struct obs_data_item *item) } static inline void obs_data_item_reattach(struct obs_data_item *old_ptr, - struct obs_data_item *new_ptr) + struct obs_data_item *new_ptr) { - struct obs_data_item **prev_next = get_item_prev_next(new_ptr->parent, - old_ptr); + struct obs_data_item **prev_next = + get_item_prev_next(new_ptr->parent, old_ptr); if (prev_next) *prev_next = new_ptr; } -static struct obs_data_item *obs_data_item_ensure_capacity( - struct obs_data_item *item) +static struct obs_data_item * +obs_data_item_ensure_capacity(struct obs_data_item *item) { size_t new_size = obs_data_item_total_size(item); struct obs_data_item *new_item; @@ -367,39 +369,41 @@ static inline void obs_data_item_destroy(struct obs_data_item *item) } static inline void move_data(obs_data_item_t *old_item, void *old_data, - obs_data_item_t *item, void *data, size_t len) + obs_data_item_t *item, void *data, size_t len) { - ptrdiff_t old_offset = (uint8_t*)old_data - (uint8_t*)old_item; - ptrdiff_t new_offset = (uint8_t*)data - (uint8_t*)item; + ptrdiff_t old_offset = (uint8_t *)old_data - (uint8_t *)old_item; + ptrdiff_t new_offset = (uint8_t *)data - (uint8_t *)item; if (!old_data) return; - memmove((uint8_t*)item + new_offset, (uint8_t*)item + old_offset, len); + memmove((uint8_t *)item + new_offset, (uint8_t *)item + old_offset, + len); } -static inline void obs_data_item_setdata( - struct obs_data_item **p_item, const void *data, size_t size, - enum obs_data_type type) +static inline void obs_data_item_setdata(struct obs_data_item **p_item, + const void *data, size_t size, + enum obs_data_type type) { if (!p_item || !*p_item) return; struct obs_data_item *item = *p_item; ptrdiff_t old_default_data_pos = - (uint8_t*)get_default_data_ptr(item) - (uint8_t*)item; + (uint8_t *)get_default_data_ptr(item) - (uint8_t *)item; item_data_release(item); item->data_size = size; - item->type = type; - item->data_len = (item->default_size || item->autoselect_size) ? - get_align_size(size) : size; + item->type = type; + item->data_len = (item->default_size || item->autoselect_size) + ? get_align_size(size) + : size; item = obs_data_item_ensure_capacity(item); if (item->default_size || item->autoselect_size) memmove(get_default_data_ptr(item), - (uint8_t*)item + old_default_data_pos, - item->default_len + item->autoselect_size); + (uint8_t *)item + old_default_data_pos, + item->default_len + item->autoselect_size); if (size) { memcpy(get_item_data(item), data, size); @@ -409,9 +413,9 @@ static inline void obs_data_item_setdata( *p_item = item; } -static inline void obs_data_item_set_default_data( - struct obs_data_item **p_item, const void *data, size_t size, - enum obs_data_type type) +static inline void obs_data_item_set_default_data(struct obs_data_item **p_item, + const void *data, size_t size, + enum obs_data_type type) { if (!p_item || !*p_item) return; @@ -420,18 +424,15 @@ static inline void obs_data_item_set_default_data( void *old_autoselect_data = get_autoselect_data_ptr(item); item_default_data_release(item); - item->type = type; + item->type = type; item->default_size = size; - item->default_len = item->autoselect_size ? - get_align_size(size) : size; - item->data_len = item->data_size ? - get_align_size(item->data_size) : 0; + item->default_len = item->autoselect_size ? get_align_size(size) : size; + item->data_len = item->data_size ? get_align_size(item->data_size) : 0; item = obs_data_item_ensure_capacity(item); if (item->autoselect_size) move_data(*p_item, old_autoselect_data, item, - get_autoselect_data_ptr(item), - item->autoselect_size); + get_autoselect_data_ptr(item), item->autoselect_size); if (size) { memcpy(get_item_default_data(item), data, size); @@ -441,9 +442,10 @@ static inline void obs_data_item_set_default_data( *p_item = item; } -static inline void obs_data_item_set_autoselect_data( - struct obs_data_item **p_item, const void *data, size_t size, - enum obs_data_type type) +static inline void +obs_data_item_set_autoselect_data(struct obs_data_item **p_item, + const void *data, size_t size, + enum obs_data_type type) { if (!p_item || !*p_item) return; @@ -452,11 +454,10 @@ static inline void obs_data_item_set_autoselect_data( item_autoselect_data_release(item); item->autoselect_size = size; - item->type = type; - item->data_len = item->data_size ? - get_align_size(item->data_size) : 0; - item->default_len = item->default_size ? - get_align_size(item->default_size) : 0; + item->type = type; + item->data_len = item->data_size ? get_align_size(item->data_size) : 0; + item->default_len = + item->default_size ? get_align_size(item->default_size) : 0; item = obs_data_item_ensure_capacity(item); if (size) { @@ -470,7 +471,7 @@ static inline void obs_data_item_set_autoselect_data( /* ------------------------------------------------------------------------- */ static void obs_data_add_json_item(obs_data_t *data, const char *key, - json_t *json); + json_t *json); static inline void obs_data_add_json_object_data(obs_data_t *data, json_t *jobj) { @@ -483,7 +484,7 @@ static inline void obs_data_add_json_object_data(obs_data_t *data, json_t *jobj) } static inline void obs_data_add_json_object(obs_data_t *data, const char *key, - json_t *jobj) + json_t *jobj) { obs_data_t *sub_obj = obs_data_create(); @@ -493,7 +494,7 @@ static inline void obs_data_add_json_object(obs_data_t *data, const char *key, } static void obs_data_add_json_array(obs_data_t *data, const char *key, - json_t *jarray) + json_t *jarray) { obs_data_array_t *array = obs_data_array_create(); size_t idx; @@ -516,7 +517,7 @@ static void obs_data_add_json_array(obs_data_t *data, const char *key, } static void obs_data_add_json_item(obs_data_t *data, const char *key, - json_t *json) + json_t *json) { if (json_is_object(json)) obs_data_add_json_object(data, key, json); @@ -537,14 +538,14 @@ static void obs_data_add_json_item(obs_data_t *data, const char *key, /* ------------------------------------------------------------------------- */ static inline void set_json_string(json_t *json, const char *name, - obs_data_item_t *item) + obs_data_item_t *item) { const char *val = obs_data_item_get_string(item); json_object_set_new(json, name, json_string(val)); } static inline void set_json_number(json_t *json, const char *name, - obs_data_item_t *item) + obs_data_item_t *item) { enum obs_data_number_type type = obs_data_item_numtype(item); @@ -558,7 +559,7 @@ static inline void set_json_number(json_t *json, const char *name, } static inline void set_json_bool(json_t *json, const char *name, - obs_data_item_t *item) + obs_data_item_t *item) { bool val = obs_data_item_get_bool(item); json_object_set_new(json, name, val ? json_true() : json_false()); @@ -567,7 +568,7 @@ static inline void set_json_bool(json_t *json, const char *name, static json_t *obs_data_to_json(obs_data_t *data); static inline void set_json_obj(json_t *json, const char *name, - obs_data_item_t *item) + obs_data_item_t *item) { obs_data_t *obj = obs_data_item_get_obj(item); json_object_set_new(json, name, obs_data_to_json(obj)); @@ -575,15 +576,15 @@ static inline void set_json_obj(json_t *json, const char *name, } static inline void set_json_array(json_t *json, const char *name, - obs_data_item_t *item) + obs_data_item_t *item) { - json_t *jarray = json_array(); - obs_data_array_t *array = obs_data_item_get_array(item); - size_t count = obs_data_array_count(array); + json_t *jarray = json_array(); + obs_data_array_t *array = obs_data_item_get_array(item); + size_t count = obs_data_array_count(array); for (size_t idx = 0; idx < count; idx++) { obs_data_t *sub_item = obs_data_array_item(array, idx); - json_t *jitem = obs_data_to_json(sub_item); + json_t *jitem = obs_data_to_json(sub_item); json_array_append_new(jarray, jitem); obs_data_release(sub_item); } @@ -599,7 +600,7 @@ static json_t *obs_data_to_json(obs_data_t *data) for (item = obs_data_first(data); item; obs_data_item_next(&item)) { enum obs_data_type type = obs_data_item_gettype(item); - const char *name = get_item_name(item); + const char *name = get_item_name(item); if (!obs_data_item_has_user_value(item)) continue; @@ -640,9 +641,10 @@ obs_data_t *obs_data_create_from_json(const char *json_string) obs_data_add_json_object_data(data, root); json_decref(root); } else { - blog(LOG_ERROR, "obs-data.c: [obs_data_create_from_json] " - "Failed reading json string (%d): %s", - error.line, error.text); + blog(LOG_ERROR, + "obs-data.c: [obs_data_create_from_json] " + "Failed reading json string (%d): %s", + error.line, error.text); obs_data_release(data); data = NULL; } @@ -664,7 +666,7 @@ obs_data_t *obs_data_create_from_json_file(const char *json_file) } obs_data_t *obs_data_create_from_json_file_safe(const char *json_file, - const char *backup_ext) + const char *backup_ext) { obs_data_t *file_data = obs_data_create_from_json_file(json_file); if (!file_data && backup_ext && *backup_ext) { @@ -676,9 +678,10 @@ obs_data_t *obs_data_create_from_json_file_safe(const char *json_file, dstr_cat(&backup_file, backup_ext); if (os_file_exists(backup_file.array)) { - blog(LOG_WARNING, "obs-data.c: " - "[obs_data_create_from_json_file_safe] " - "attempting backup file"); + blog(LOG_WARNING, + "obs-data.c: " + "[obs_data_create_from_json_file_safe] " + "attempting backup file"); /* delete current file if corrupt to prevent it from * being backed up again */ @@ -716,7 +719,8 @@ static inline void obs_data_destroy(struct obs_data *data) void obs_data_release(obs_data_t *data) { - if (!data) return; + if (!data) + return; if (os_atomic_dec_long(&data->ref) == 0) obs_data_destroy(data); @@ -724,7 +728,8 @@ void obs_data_release(obs_data_t *data) const char *obs_data_get_json(obs_data_t *data) { - if (!data) return NULL; + if (!data) + return NULL; /* NOTE: don't use libobs bfree for json text */ free(data->json); @@ -743,20 +748,20 @@ bool obs_data_save_json(obs_data_t *data, const char *file) if (json && *json) { return os_quick_write_utf8_file(file, json, strlen(json), - false); + false); } return false; } bool obs_data_save_json_safe(obs_data_t *data, const char *file, - const char *temp_ext, const char *backup_ext) + const char *temp_ext, const char *backup_ext) { const char *json = obs_data_get_json(data); if (json && *json) { - return os_quick_write_utf8_file_safe(file, json, strlen(json), - false, temp_ext, backup_ext); + return os_quick_write_utf8_file_safe( + file, json, strlen(json), false, temp_ext, backup_ext); } return false; @@ -764,7 +769,8 @@ bool obs_data_save_json_safe(obs_data_t *data, const char *file, static struct obs_data_item *get_item(struct obs_data *data, const char *name) { - if (!data) return NULL; + if (!data) + return NULL; struct obs_data_item *item = data->first_item; @@ -779,33 +785,33 @@ static struct obs_data_item *get_item(struct obs_data *data, const char *name) } static void set_item_data(struct obs_data *data, struct obs_data_item **item, - const char *name, const void *ptr, size_t size, - enum obs_data_type type, - bool default_data, bool autoselect_data) + const char *name, const void *ptr, size_t size, + enum obs_data_type type, bool default_data, + bool autoselect_data) { obs_data_item_t *new_item = NULL; if ((!item || (item && !*item)) && data) { new_item = obs_data_item_create(name, ptr, size, type, - default_data, autoselect_data); + default_data, autoselect_data); obs_data_item_t *prev = obs_data_first(data); obs_data_item_t *next = obs_data_first(data); obs_data_item_next(&next); - for (; prev && next; obs_data_item_next(&prev), - obs_data_item_next(&next)) { + for (; prev && next; + obs_data_item_next(&prev), obs_data_item_next(&next)) { if (strcmp(get_item_name(next), name) > 0) break; } new_item->parent = data; if (prev && strcmp(get_item_name(prev), name) < 0) { - prev->next = new_item; + prev->next = new_item; new_item->next = next; } else { data->first_item = new_item; - new_item->next = prev; + new_item->next = prev; } if (!prev) @@ -824,8 +830,8 @@ static void set_item_data(struct obs_data *data, struct obs_data_item **item, } static inline void set_item(struct obs_data *data, obs_data_item_t **item, - const char *name, - const void *ptr, size_t size, enum obs_data_type type) + const char *name, const void *ptr, size_t size, + enum obs_data_type type) { obs_data_item_t *actual_item = NULL; @@ -841,8 +847,8 @@ static inline void set_item(struct obs_data *data, obs_data_item_t **item, } static inline void set_item_def(struct obs_data *data, obs_data_item_t **item, - const char *name, - const void *ptr, size_t size, enum obs_data_type type) + const char *name, const void *ptr, size_t size, + enum obs_data_type type) { obs_data_item_t *actual_item = NULL; @@ -861,8 +867,8 @@ static inline void set_item_def(struct obs_data *data, obs_data_item_t **item, } static inline void set_item_auto(struct obs_data *data, obs_data_item_t **item, - const char *name, - const void *ptr, size_t size, enum obs_data_type type) + const char *name, const void *ptr, size_t size, + enum obs_data_type type) { obs_data_item_t *actual_item = NULL; @@ -878,8 +884,8 @@ static inline void set_item_auto(struct obs_data *data, obs_data_item_t **item, } static void copy_obj(struct obs_data *data, const char *name, - struct obs_data *obj, - void (*callback)(obs_data_t *, const char *, obs_data_t *)) + struct obs_data *obj, + void (*callback)(obs_data_t *, const char *, obs_data_t *)) { if (obj) { obs_data_t *new_obj = obs_data_create(); @@ -890,8 +896,9 @@ static void copy_obj(struct obs_data *data, const char *name, } static void copy_array(struct obs_data *data, const char *name, - struct obs_data_array *array, - void (*callback)(obs_data_t*, const char*, obs_data_array_t*)) + struct obs_data_array *array, + void (*callback)(obs_data_t *, const char *, + obs_data_array_t *)) { if (array) { obs_data_array_t *new_array = obs_data_array_create(); @@ -932,7 +939,7 @@ static inline void copy_item(struct obs_data *data, struct obs_data_item *item) } else { if (item->data_size) set_item(data, NULL, name, ptr, item->data_size, - item->type); + item->type); } } @@ -982,7 +989,7 @@ static inline void clear_item(struct obs_data_item *item) size = item->default_len + item->autoselect_size; if (size) - memmove(ptr, (uint8_t*)ptr + item->data_len, size); + memmove(ptr, (uint8_t *)ptr + item->data_len, size); item->data_size = 0; item->data_len = 0; @@ -1004,63 +1011,66 @@ void obs_data_clear(obs_data_t *target) } } -typedef void (*set_item_t)(obs_data_t*, obs_data_item_t**, const char*, - const void*, size_t, enum obs_data_type); +typedef void (*set_item_t)(obs_data_t *, obs_data_item_t **, const char *, + const void *, size_t, enum obs_data_type); static inline void obs_set_string(obs_data_t *data, obs_data_item_t **item, - const char *name, - const char *val, set_item_t set_item_) + const char *name, const char *val, + set_item_t set_item_) { - if (!val) val = ""; - set_item_(data, item, name, val, strlen(val)+1, OBS_DATA_STRING); + if (!val) + val = ""; + set_item_(data, item, name, val, strlen(val) + 1, OBS_DATA_STRING); } static inline void obs_set_int(obs_data_t *data, obs_data_item_t **item, - const char *name, - long long val, set_item_t set_item_) + const char *name, long long val, + set_item_t set_item_) { struct obs_data_number num; - num.type = OBS_DATA_NUM_INT; + num.type = OBS_DATA_NUM_INT; num.int_val = val; set_item_(data, item, name, &num, sizeof(struct obs_data_number), - OBS_DATA_NUMBER); + OBS_DATA_NUMBER); } static inline void obs_set_double(obs_data_t *data, obs_data_item_t **item, - const char *name, - double val, set_item_t set_item_) + const char *name, double val, + set_item_t set_item_) { struct obs_data_number num; - num.type = OBS_DATA_NUM_DOUBLE; + num.type = OBS_DATA_NUM_DOUBLE; num.double_val = val; set_item_(data, item, name, &num, sizeof(struct obs_data_number), - OBS_DATA_NUMBER); + OBS_DATA_NUMBER); } static inline void obs_set_bool(obs_data_t *data, obs_data_item_t **item, - const char *name, - bool val, set_item_t set_item_) + const char *name, bool val, + set_item_t set_item_) { set_item_(data, item, name, &val, sizeof(bool), OBS_DATA_BOOLEAN); } static inline void obs_set_obj(obs_data_t *data, obs_data_item_t **item, - const char *name, - obs_data_t *obj, set_item_t set_item_) + const char *name, obs_data_t *obj, + set_item_t set_item_) { - set_item_(data, item, name, &obj, sizeof(obs_data_t*), OBS_DATA_OBJECT); + set_item_(data, item, name, &obj, sizeof(obs_data_t *), + OBS_DATA_OBJECT); } static inline void obs_set_array(obs_data_t *data, obs_data_item_t **item, - const char *name, - obs_data_array_t *array, set_item_t set_item_) + const char *name, obs_data_array_t *array, + set_item_t set_item_) { - set_item_(data, item, name, &array, sizeof(obs_data_t*), OBS_DATA_ARRAY); + set_item_(data, item, name, &array, sizeof(obs_data_t *), + OBS_DATA_ARRAY); } static inline void obs_take_obj(obs_data_t *data, obs_data_item_t **item, - const char *name, - obs_data_t *obj, set_item_t set_item_) + const char *name, obs_data_t *obj, + set_item_t set_item_) { obs_set_obj(data, item, name, obj, set_item_); obs_data_release(obj); @@ -1092,13 +1102,13 @@ void obs_data_set_obj(obs_data_t *data, const char *name, obs_data_t *obj) } void obs_data_set_array(obs_data_t *data, const char *name, - obs_data_array_t *array) + obs_data_array_t *array) { obs_set_array(data, NULL, name, array, set_item); } void obs_data_set_default_string(obs_data_t *data, const char *name, - const char *val) + const char *val) { obs_set_string(data, NULL, name, val, set_item_def); } @@ -1118,25 +1128,26 @@ void obs_data_set_default_bool(obs_data_t *data, const char *name, bool val) obs_set_bool(data, NULL, name, val, set_item_def); } -void obs_data_set_default_obj(obs_data_t *data, const char *name, obs_data_t *obj) +void obs_data_set_default_obj(obs_data_t *data, const char *name, + obs_data_t *obj) { obs_set_obj(data, NULL, name, obj, set_item_def); } void obs_data_set_autoselect_string(obs_data_t *data, const char *name, - const char *val) + const char *val) { obs_set_string(data, NULL, name, val, set_item_auto); } void obs_data_set_autoselect_int(obs_data_t *data, const char *name, - long long val) + long long val) { obs_set_int(data, NULL, name, val, set_item_auto); } void obs_data_set_autoselect_double(obs_data_t *data, const char *name, - double val) + double val) { obs_set_double(data, NULL, name, val, set_item_auto); } @@ -1147,13 +1158,13 @@ void obs_data_set_autoselect_bool(obs_data_t *data, const char *name, bool val) } void obs_data_set_autoselect_obj(obs_data_t *data, const char *name, - obs_data_t *obj) + obs_data_t *obj) { obs_set_obj(data, NULL, name, obj, set_item_auto); } void obs_data_set_autoselect_array(obs_data_t *data, const char *name, - obs_data_array_t *arr) + obs_data_array_t *arr) { obs_set_array(data, NULL, name, arr, set_item_auto); } @@ -1244,7 +1255,7 @@ obs_data_t *obs_data_get_autoselect_obj(obs_data_t *data, const char *name) } obs_data_array_t *obs_data_get_autoselect_array(obs_data_t *data, - const char *name) + const char *name) { return obs_data_item_get_autoselect_array(get_item(data, name)); } @@ -1320,7 +1331,7 @@ void obs_data_array_insert(obs_data_array_t *array, size_t idx, obs_data_t *obj) } void obs_data_array_push_back_array(obs_data_array_t *array, - obs_data_array_t *array2) + obs_data_array_t *array2) { if (!array || !array2) return; @@ -1404,8 +1415,8 @@ void obs_data_item_unset_user_value(obs_data_item_t *item) if (item->default_size || item->autoselect_size) move_data(item, old_non_user_data, item, - get_default_data_ptr(item), - item->default_len + item->autoselect_size); + get_default_data_ptr(item), + item->default_len + item->autoselect_size); } void obs_data_item_unset_default_value(obs_data_item_t *item) @@ -1421,8 +1432,7 @@ void obs_data_item_unset_default_value(obs_data_item_t *item) if (item->autoselect_size) move_data(item, old_autoselect_data, item, - get_autoselect_data_ptr(item), - item->autoselect_size); + get_autoselect_data_ptr(item), item->autoselect_size); } void obs_data_item_unset_autoselect_value(obs_data_item_t *item) @@ -1574,12 +1584,13 @@ void obs_data_item_set_default_obj(obs_data_item_t **item, obs_data_t *val) } void obs_data_item_set_default_array(obs_data_item_t **item, - obs_data_array_t *val) + obs_data_array_t *val) { obs_set_array(NULL, item, NULL, val, set_item_def); } -void obs_data_item_set_autoselect_string(obs_data_item_t **item, const char *val) +void obs_data_item_set_autoselect_string(obs_data_item_t **item, + const char *val) { obs_set_string(NULL, item, NULL, val, set_item_auto); } @@ -1605,90 +1616,94 @@ void obs_data_item_set_autoselect_obj(obs_data_item_t **item, obs_data_t *val) } void obs_data_item_set_autoselect_array(obs_data_item_t **item, - obs_data_array_t *val) + obs_data_array_t *val) { obs_set_array(NULL, item, NULL, val, set_item_auto); } static inline bool item_valid(struct obs_data_item *item, - enum obs_data_type type) + enum obs_data_type type) { return item && item->type == type; } -typedef void *(*get_data_t)(obs_data_item_t*); +typedef void *(*get_data_t)(obs_data_item_t *); static inline const char *data_item_get_string(obs_data_item_t *item, - get_data_t get_data) + get_data_t get_data) { - return item_valid(item, OBS_DATA_STRING) && get_data(item) ? - get_data(item) : ""; + return item_valid(item, OBS_DATA_STRING) && get_data(item) + ? get_data(item) + : ""; } static inline long long item_int(struct obs_data_item *item, - get_data_t get_data) + get_data_t get_data) { if (item && get_data(item)) { struct obs_data_number *num = get_data(item); - return (num->type == OBS_DATA_NUM_INT) ? - num->int_val : (long long)num->double_val; + return (num->type == OBS_DATA_NUM_INT) + ? num->int_val + : (long long)num->double_val; } return 0; } static inline long long data_item_get_int(obs_data_item_t *item, - get_data_t get_data) + get_data_t get_data) { return item_int(item_valid(item, OBS_DATA_NUMBER) ? item : NULL, get_data); } static inline double item_double(struct obs_data_item *item, - get_data_t get_data) + get_data_t get_data) { if (item && get_data(item)) { struct obs_data_number *num = get_data(item); - return (num->type == OBS_DATA_NUM_INT) ? - (double)num->int_val : num->double_val; + return (num->type == OBS_DATA_NUM_INT) ? (double)num->int_val + : num->double_val; } return 0.0; } static inline double data_item_get_double(obs_data_item_t *item, - get_data_t get_data) + get_data_t get_data) { return item_double(item_valid(item, OBS_DATA_NUMBER) ? item : NULL, - get_data); + get_data); } -static inline bool data_item_get_bool(obs_data_item_t *item, get_data_t get_data) +static inline bool data_item_get_bool(obs_data_item_t *item, + get_data_t get_data) { - return item_valid(item, OBS_DATA_BOOLEAN) && get_data(item) ? - *(bool*)get_data(item) : false; + return item_valid(item, OBS_DATA_BOOLEAN) && get_data(item) + ? *(bool *)get_data(item) + : false; } -typedef obs_data_t *(*get_obj_t)(obs_data_item_t*); +typedef obs_data_t *(*get_obj_t)(obs_data_item_t *); static inline obs_data_t *data_item_get_obj(obs_data_item_t *item, - get_obj_t get_obj) + get_obj_t get_obj) { - obs_data_t *obj = item_valid(item, OBS_DATA_OBJECT) ? - get_obj(item) : NULL; + obs_data_t *obj = item_valid(item, OBS_DATA_OBJECT) ? get_obj(item) + : NULL; if (obj) os_atomic_inc_long(&obj->ref); return obj; } -typedef obs_data_array_t *(*get_array_t)(obs_data_item_t*); +typedef obs_data_array_t *(*get_array_t)(obs_data_item_t *); static inline obs_data_array_t *data_item_get_array(obs_data_item_t *item, - get_array_t get_array) + get_array_t get_array) { - obs_data_array_t *array = item_valid(item, OBS_DATA_ARRAY) ? - get_array(item) : NULL; + obs_data_array_t *array = + item_valid(item, OBS_DATA_ARRAY) ? get_array(item) : NULL; if (array) os_atomic_inc_long(&array->ref); @@ -1788,10 +1803,10 @@ obs_data_array_t *obs_data_item_get_autoselect_array(obs_data_item_t *item) /* ------------------------------------------------------------------------- */ /* Helper functions for certain structures */ -typedef void (*set_obj_t)(obs_data_t*, const char*, obs_data_t*); +typedef void (*set_obj_t)(obs_data_t *, const char *, obs_data_t *); static inline void set_vec2(obs_data_t *data, const char *name, - const struct vec2 *val, set_obj_t set_obj) + const struct vec2 *val, set_obj_t set_obj) { obs_data_t *obj = obs_data_create(); obs_data_set_double(obj, "x", val->x); @@ -1801,7 +1816,7 @@ static inline void set_vec2(obs_data_t *data, const char *name, } static inline void set_vec3(obs_data_t *data, const char *name, - const struct vec3 *val, set_obj_t set_obj) + const struct vec3 *val, set_obj_t set_obj) { obs_data_t *obj = obs_data_create(); obs_data_set_double(obj, "x", val->x); @@ -1812,7 +1827,7 @@ static inline void set_vec3(obs_data_t *data, const char *name, } static inline void set_vec4(obs_data_t *data, const char *name, - const struct vec4 *val, set_obj_t set_obj) + const struct vec4 *val, set_obj_t set_obj) { obs_data_t *obj = obs_data_create(); obs_data_set_double(obj, "x", val->x); @@ -1824,7 +1839,7 @@ static inline void set_vec4(obs_data_t *data, const char *name, } static inline void set_quat(obs_data_t *data, const char *name, - const struct quat *val, set_obj_t set_obj) + const struct quat *val, set_obj_t set_obj) { obs_data_t *obj = obs_data_create(); obs_data_set_double(obj, "x", val->x); @@ -1836,80 +1851,81 @@ static inline void set_quat(obs_data_t *data, const char *name, } void obs_data_set_vec2(obs_data_t *data, const char *name, - const struct vec2 *val) + const struct vec2 *val) { set_vec2(data, name, val, obs_data_set_obj); } void obs_data_set_vec3(obs_data_t *data, const char *name, - const struct vec3 *val) + const struct vec3 *val) { set_vec3(data, name, val, obs_data_set_obj); } void obs_data_set_vec4(obs_data_t *data, const char *name, - const struct vec4 *val) + const struct vec4 *val) { set_vec4(data, name, val, obs_data_set_obj); } void obs_data_set_quat(obs_data_t *data, const char *name, - const struct quat *val) + const struct quat *val) { set_quat(data, name, val, obs_data_set_obj); } void obs_data_set_default_vec2(obs_data_t *data, const char *name, - const struct vec2 *val) + const struct vec2 *val) { set_vec2(data, name, val, obs_data_set_default_obj); } void obs_data_set_default_vec3(obs_data_t *data, const char *name, - const struct vec3 *val) + const struct vec3 *val) { set_vec3(data, name, val, obs_data_set_default_obj); } void obs_data_set_default_vec4(obs_data_t *data, const char *name, - const struct vec4 *val) + const struct vec4 *val) { set_vec4(data, name, val, obs_data_set_default_obj); } void obs_data_set_default_quat(obs_data_t *data, const char *name, - const struct quat *val) + const struct quat *val) { set_quat(data, name, val, obs_data_set_default_obj); } void obs_data_set_autoselect_vec2(obs_data_t *data, const char *name, - const struct vec2 *val) + const struct vec2 *val) { set_vec2(data, name, val, obs_data_set_autoselect_obj); } void obs_data_set_autoselect_vec3(obs_data_t *data, const char *name, - const struct vec3 *val) + const struct vec3 *val) { set_vec3(data, name, val, obs_data_set_autoselect_obj); } void obs_data_set_autoselect_vec4(obs_data_t *data, const char *name, - const struct vec4 *val) + const struct vec4 *val) { set_vec4(data, name, val, obs_data_set_autoselect_obj); } void obs_data_set_autoselect_quat(obs_data_t *data, const char *name, - const struct quat *val) + const struct quat *val) { set_quat(data, name, val, obs_data_set_autoselect_obj); } static inline void get_vec2(obs_data_t *obj, struct vec2 *val) { - if (!obj) return; + if (!obj) + return; val->x = (float)obs_data_get_double(obj, "x"); val->y = (float)obs_data_get_double(obj, "y"); @@ -1918,7 +1934,8 @@ static inline void get_vec2(obs_data_t *obj, struct vec2 *val) static inline void get_vec3(obs_data_t *obj, struct vec3 *val) { - if (!obj) return; + if (!obj) + return; val->x = (float)obs_data_get_double(obj, "x"); val->y = (float)obs_data_get_double(obj, "y"); @@ -1928,7 +1945,8 @@ static inline void get_vec3(obs_data_t *obj, struct vec3 *val) static inline void get_vec4(obs_data_t *obj, struct vec4 *val) { - if (!obj) return; + if (!obj) + return; val->x = (float)obs_data_get_double(obj, "x"); val->y = (float)obs_data_get_double(obj, "y"); @@ -1939,7 +1957,8 @@ static inline void get_vec4(obs_data_t *obj, struct vec4 *val) static inline void get_quat(obs_data_t *obj, struct quat *val) { - if (!obj) return; + if (!obj) + return; val->x = (float)obs_data_get_double(obj, "x"); val->y = (float)obs_data_get_double(obj, "y"); @@ -1969,49 +1988,49 @@ void obs_data_get_quat(obs_data_t *data, const char *name, struct quat *val) } void obs_data_get_default_vec2(obs_data_t *data, const char *name, - struct vec2 *val) + struct vec2 *val) { get_vec2(obs_data_get_default_obj(data, name), val); } void obs_data_get_default_vec3(obs_data_t *data, const char *name, - struct vec3 *val) + struct vec3 *val) { get_vec3(obs_data_get_default_obj(data, name), val); } void obs_data_get_default_vec4(obs_data_t *data, const char *name, - struct vec4 *val) + struct vec4 *val) { get_vec4(obs_data_get_default_obj(data, name), val); } void obs_data_get_default_quat(obs_data_t *data, const char *name, - struct quat *val) + struct quat *val) { get_quat(obs_data_get_default_obj(data, name), val); } void obs_data_get_autoselect_vec2(obs_data_t *data, const char *name, - struct vec2 *val) + struct vec2 *val) { get_vec2(obs_data_get_autoselect_obj(data, name), val); } void obs_data_get_autoselect_vec3(obs_data_t *data, const char *name, - struct vec3 *val) + struct vec3 *val) { get_vec3(obs_data_get_autoselect_obj(data, name), val); } void obs_data_get_autoselect_vec4(obs_data_t *data, const char *name, - struct vec4 *val) + struct vec4 *val) { get_vec4(obs_data_get_autoselect_obj(data, name), val); } void obs_data_get_autoselect_quat(obs_data_t *data, const char *name, - struct quat *val) + struct quat *val) { get_quat(obs_data_get_autoselect_obj(data, name), val); } @@ -2019,9 +2038,8 @@ void obs_data_get_autoselect_quat(obs_data_t *data, const char *name, /* ------------------------------------------------------------------------- */ /* Helper functions for media_frames_per_seconds */ -static inline obs_data_t *make_frames_per_second( - struct media_frames_per_second fps, - const char *option) +static inline obs_data_t * +make_frames_per_second(struct media_frames_per_second fps, const char *option) { obs_data_t *obj = obs_data_create(); @@ -2037,33 +2055,37 @@ static inline obs_data_t *make_frames_per_second( } void obs_data_set_frames_per_second(obs_data_t *data, const char *name, - struct media_frames_per_second fps, const char *option) + struct media_frames_per_second fps, + const char *option) { obs_take_obj(data, NULL, name, make_frames_per_second(fps, option), - set_item); + set_item); } void obs_data_set_default_frames_per_second(obs_data_t *data, const char *name, - struct media_frames_per_second fps, const char *option) + struct media_frames_per_second fps, + const char *option) { obs_take_obj(data, NULL, name, make_frames_per_second(fps, option), - set_item_def); + set_item_def); } -void obs_data_set_autoselect_frames_per_second(obs_data_t *data, - const char *name, struct media_frames_per_second fps, - const char *option) +void obs_data_set_autoselect_frames_per_second( + obs_data_t *data, const char *name, struct media_frames_per_second fps, + const char *option) { obs_take_obj(data, NULL, name, make_frames_per_second(fps, option), - set_item_auto); + set_item_auto); } static inline bool get_option(obs_data_t *data, const char **option) { - if (!option) return false; + if (!option) + return false; struct obs_data_item *opt = obs_data_item_byname(data, "option"); - if (!opt) return false; + if (!opt) + return false; *option = obs_data_item_get_string(opt); obs_data_item_release(&opt); @@ -2076,14 +2098,17 @@ static inline bool get_option(obs_data_t *data, const char **option) #define CLAMP(x, min, max) ((x) < min ? min : ((x) > max ? max : (x))) static inline bool get_frames_per_second(obs_data_t *data, - struct media_frames_per_second *fps, - const char **option) + struct media_frames_per_second *fps, + const char **option) { - if (!data) return false; + if (!data) + return false; - if (get_option(data, option)) return true; + if (get_option(data, option)) + return true; - if (!fps) goto free; + if (!fps) + goto free; struct obs_data_item *num = obs_data_item_byname(data, "numerator"); struct obs_data_item *den = obs_data_item_byname(data, "denominator"); @@ -2096,7 +2121,7 @@ static inline bool get_frames_per_second(obs_data_t *data, long long num_ll = obs_data_item_get_int(num); long long den_ll = obs_data_item_get_int(den); - fps->numerator = (uint32_t)CLAMP(num_ll, 0, (long long)UINT32_MAX); + fps->numerator = (uint32_t)CLAMP(num_ll, 0, (long long)UINT32_MAX); fps->denominator = (uint32_t)CLAMP(den_ll, 0, (long long)UINT32_MAX); obs_data_item_release(&num); @@ -2112,64 +2137,71 @@ free: } bool obs_data_get_frames_per_second(obs_data_t *data, const char *name, - struct media_frames_per_second *fps, const char **option) + struct media_frames_per_second *fps, + const char **option) { return get_frames_per_second(obs_data_get_obj(data, name), fps, option); } bool obs_data_get_default_frames_per_second(obs_data_t *data, const char *name, - struct media_frames_per_second *fps, const char **option) + struct media_frames_per_second *fps, + const char **option) { - return get_frames_per_second(obs_data_get_default_obj(data, name), - fps, option); + return get_frames_per_second(obs_data_get_default_obj(data, name), fps, + option); } -bool obs_data_get_autoselect_frames_per_second(obs_data_t *data, - const char *name, struct media_frames_per_second *fps, - const char **option) +bool obs_data_get_autoselect_frames_per_second( + obs_data_t *data, const char *name, struct media_frames_per_second *fps, + const char **option) { return get_frames_per_second(obs_data_get_autoselect_obj(data, name), - fps, option); + fps, option); } void obs_data_item_set_frames_per_second(obs_data_item_t **item, - struct media_frames_per_second fps, const char *option) + struct media_frames_per_second fps, + const char *option) { obs_take_obj(NULL, item, NULL, make_frames_per_second(fps, option), - set_item); + set_item); } -void obs_data_item_set_default_frames_per_second(obs_data_item_t **item, - struct media_frames_per_second fps, const char *option) +void obs_data_item_set_default_frames_per_second( + obs_data_item_t **item, struct media_frames_per_second fps, + const char *option) { obs_take_obj(NULL, item, NULL, make_frames_per_second(fps, option), - set_item_def); + set_item_def); } -void obs_data_item_set_autoselect_frames_per_second(obs_data_item_t **item, - struct media_frames_per_second fps, const char *option) +void obs_data_item_set_autoselect_frames_per_second( + obs_data_item_t **item, struct media_frames_per_second fps, + const char *option) { obs_take_obj(NULL, item, NULL, make_frames_per_second(fps, option), - set_item_auto); + set_item_auto); } bool obs_data_item_get_frames_per_second(obs_data_item_t *item, - struct media_frames_per_second *fps, const char **option) + struct media_frames_per_second *fps, + const char **option) { - return get_frames_per_second(obs_data_item_get_obj(item), - fps, option); + return get_frames_per_second(obs_data_item_get_obj(item), fps, option); } -bool obs_data_item_get_default_frames_per_second(obs_data_item_t *item, - struct media_frames_per_second *fps, const char **option) +bool obs_data_item_get_default_frames_per_second( + obs_data_item_t *item, struct media_frames_per_second *fps, + const char **option) { - return get_frames_per_second(obs_data_item_get_default_obj(item), - fps, option); + return get_frames_per_second(obs_data_item_get_default_obj(item), fps, + option); } -bool obs_data_item_get_autoselect_frames_per_second(obs_data_item_t *item, - struct media_frames_per_second *fps, const char **option) +bool obs_data_item_get_autoselect_frames_per_second( + obs_data_item_t *item, struct media_frames_per_second *fps, + const char **option) { return get_frames_per_second(obs_data_item_get_autoselect_obj(item), - fps, option); + fps, option); } diff --git a/libobs/obs-data.h b/libobs/obs-data.h index c0bbcbe..202190d 100644 --- a/libobs/obs-data.h +++ b/libobs/obs-data.h @@ -39,8 +39,8 @@ struct quat; struct obs_data; struct obs_data_item; struct obs_data_array; -typedef struct obs_data obs_data_t; -typedef struct obs_data_item obs_data_item_t; +typedef struct obs_data obs_data_t; +typedef struct obs_data_item obs_data_item_t; typedef struct obs_data_array obs_data_array_t; enum obs_data_type { @@ -65,14 +65,15 @@ EXPORT obs_data_t *obs_data_create(); EXPORT obs_data_t *obs_data_create_from_json(const char *json_string); EXPORT obs_data_t *obs_data_create_from_json_file(const char *json_file); EXPORT obs_data_t *obs_data_create_from_json_file_safe(const char *json_file, - const char *backup_ext); + const char *backup_ext); EXPORT void obs_data_addref(obs_data_t *data); EXPORT void obs_data_release(obs_data_t *data); EXPORT const char *obs_data_get_json(obs_data_t *data); EXPORT bool obs_data_save_json(obs_data_t *data, const char *file); EXPORT bool obs_data_save_json_safe(obs_data_t *data, const char *file, - const char *temp_ext, const char *backup_ext); + const char *temp_ext, + const char *backup_ext); EXPORT void obs_data_apply(obs_data_t *target, obs_data_t *apply_data); @@ -81,28 +82,28 @@ EXPORT void obs_data_clear(obs_data_t *data); /* Set functions */ EXPORT void obs_data_set_string(obs_data_t *data, const char *name, - const char *val); -EXPORT void obs_data_set_int(obs_data_t *data, const char *name, - long long val); + const char *val); +EXPORT void obs_data_set_int(obs_data_t *data, const char *name, long long val); EXPORT void obs_data_set_double(obs_data_t *data, const char *name, double val); EXPORT void obs_data_set_bool(obs_data_t *data, const char *name, bool val); -EXPORT void obs_data_set_obj(obs_data_t *data, const char *name, obs_data_t *obj); +EXPORT void obs_data_set_obj(obs_data_t *data, const char *name, + obs_data_t *obj); EXPORT void obs_data_set_array(obs_data_t *data, const char *name, - obs_data_array_t *array); + obs_data_array_t *array); /* * Default value functions. */ EXPORT void obs_data_set_default_string(obs_data_t *data, const char *name, - const char *val); + const char *val); EXPORT void obs_data_set_default_int(obs_data_t *data, const char *name, - long long val); + long long val); EXPORT void obs_data_set_default_double(obs_data_t *data, const char *name, - double val); + double val); EXPORT void obs_data_set_default_bool(obs_data_t *data, const char *name, - bool val); + bool val); EXPORT void obs_data_set_default_obj(obs_data_t *data, const char *name, - obs_data_t *obj); + obs_data_t *obj); /* * Application overrides @@ -110,15 +111,15 @@ EXPORT void obs_data_set_default_obj(obs_data_t *data, const char *name, * settings aren't appropriate */ EXPORT void obs_data_set_autoselect_string(obs_data_t *data, const char *name, - const char *val); + const char *val); EXPORT void obs_data_set_autoselect_int(obs_data_t *data, const char *name, - long long val); + long long val); EXPORT void obs_data_set_autoselect_double(obs_data_t *data, const char *name, - double val); + double val); EXPORT void obs_data_set_autoselect_bool(obs_data_t *data, const char *name, - bool val); + bool val); EXPORT void obs_data_set_autoselect_obj(obs_data_t *data, const char *name, - obs_data_t *obj); + obs_data_t *obj); /* * Get functions @@ -131,23 +132,25 @@ EXPORT obs_data_t *obs_data_get_obj(obs_data_t *data, const char *name); EXPORT obs_data_array_t *obs_data_get_array(obs_data_t *data, const char *name); EXPORT const char *obs_data_get_default_string(obs_data_t *data, - const char *name); + const char *name); EXPORT long long obs_data_get_default_int(obs_data_t *data, const char *name); EXPORT double obs_data_get_default_double(obs_data_t *data, const char *name); EXPORT bool obs_data_get_default_bool(obs_data_t *data, const char *name); EXPORT obs_data_t *obs_data_get_default_obj(obs_data_t *data, const char *name); EXPORT obs_data_array_t *obs_data_get_default_array(obs_data_t *data, - const char *name); + const char *name); EXPORT const char *obs_data_get_autoselect_string(obs_data_t *data, - const char *name); -EXPORT long long obs_data_get_autoselect_int(obs_data_t *data, const char *name); -EXPORT double obs_data_get_autoselect_double(obs_data_t *data, const char *name); + const char *name); +EXPORT long long obs_data_get_autoselect_int(obs_data_t *data, + const char *name); +EXPORT double obs_data_get_autoselect_double(obs_data_t *data, + const char *name); EXPORT bool obs_data_get_autoselect_bool(obs_data_t *data, const char *name); EXPORT obs_data_t *obs_data_get_autoselect_obj(obs_data_t *data, - const char *name); + const char *name); EXPORT obs_data_array_t *obs_data_get_autoselect_array(obs_data_t *data, - const char *name); + const char *name); /* Array functions */ EXPORT obs_data_array_t *obs_data_array_create(); @@ -156,11 +159,12 @@ EXPORT void obs_data_array_release(obs_data_array_t *array); EXPORT size_t obs_data_array_count(obs_data_array_t *array); EXPORT obs_data_t *obs_data_array_item(obs_data_array_t *array, size_t idx); -EXPORT size_t obs_data_array_push_back(obs_data_array_t *array, obs_data_t *obj); +EXPORT size_t obs_data_array_push_back(obs_data_array_t *array, + obs_data_t *obj); EXPORT void obs_data_array_insert(obs_data_array_t *array, size_t idx, - obs_data_t *obj); + obs_data_t *obj); EXPORT void obs_data_array_push_back_array(obs_data_array_t *array, - obs_data_array_t *array2); + obs_data_array_t *array2); EXPORT void obs_data_array_erase(obs_data_array_t *array, size_t idx); /* ------------------------------------------------------------------------- */ @@ -189,7 +193,8 @@ EXPORT void obs_data_item_unset_autoselect_value(obs_data_item_t *data); /* Item iteration */ EXPORT obs_data_item_t *obs_data_first(obs_data_t *data); -EXPORT obs_data_item_t *obs_data_item_byname(obs_data_t *data, const char *name); +EXPORT obs_data_item_t *obs_data_item_byname(obs_data_t *data, + const char *name); EXPORT bool obs_data_item_next(obs_data_item_t **item); EXPORT void obs_data_item_release(obs_data_item_t **item); EXPORT void obs_data_item_remove(obs_data_item_t **item); @@ -206,29 +211,31 @@ EXPORT void obs_data_item_set_double(obs_data_item_t **item, double val); EXPORT void obs_data_item_set_bool(obs_data_item_t **item, bool val); EXPORT void obs_data_item_set_obj(obs_data_item_t **item, obs_data_t *val); EXPORT void obs_data_item_set_array(obs_data_item_t **item, - obs_data_array_t *val); + obs_data_array_t *val); EXPORT void obs_data_item_set_default_string(obs_data_item_t **item, - const char *val); -EXPORT void obs_data_item_set_default_int(obs_data_item_t **item, long long val); -EXPORT void obs_data_item_set_default_double(obs_data_item_t **item, double val); + const char *val); +EXPORT void obs_data_item_set_default_int(obs_data_item_t **item, + long long val); +EXPORT void obs_data_item_set_default_double(obs_data_item_t **item, + double val); EXPORT void obs_data_item_set_default_bool(obs_data_item_t **item, bool val); EXPORT void obs_data_item_set_default_obj(obs_data_item_t **item, - obs_data_t *val); + obs_data_t *val); EXPORT void obs_data_item_set_default_array(obs_data_item_t **item, - obs_data_array_t *val); + obs_data_array_t *val); EXPORT void obs_data_item_set_autoselect_string(obs_data_item_t **item, - const char *val); + const char *val); EXPORT void obs_data_item_set_autoselect_int(obs_data_item_t **item, - long long val); + long long val); EXPORT void obs_data_item_set_autoselect_double(obs_data_item_t **item, - double val); + double val); EXPORT void obs_data_item_set_autoselect_bool(obs_data_item_t **item, bool val); EXPORT void obs_data_item_set_autoselect_obj(obs_data_item_t **item, - obs_data_t *val); + obs_data_t *val); EXPORT void obs_data_item_set_autoselect_array(obs_data_item_t **item, - obs_data_array_t *val); + obs_data_array_t *val); /* Item get functions */ EXPORT const char *obs_data_item_get_string(obs_data_item_t *item); @@ -250,106 +257,114 @@ EXPORT long long obs_data_item_get_autoselect_int(obs_data_item_t *item); EXPORT double obs_data_item_get_autoselect_double(obs_data_item_t *item); EXPORT bool obs_data_item_get_autoselect_bool(obs_data_item_t *item); EXPORT obs_data_t *obs_data_item_get_autoselect_obj(obs_data_item_t *item); -EXPORT obs_data_array_t *obs_data_item_get_autoselect_array( - obs_data_item_t *item); +EXPORT obs_data_array_t * +obs_data_item_get_autoselect_array(obs_data_item_t *item); /* ------------------------------------------------------------------------- */ /* Helper functions for certain structures */ EXPORT void obs_data_set_vec2(obs_data_t *data, const char *name, - const struct vec2 *val); + const struct vec2 *val); EXPORT void obs_data_set_vec3(obs_data_t *data, const char *name, - const struct vec3 *val); + const struct vec3 *val); EXPORT void obs_data_set_vec4(obs_data_t *data, const char *name, - const struct vec4 *val); + const struct vec4 *val); EXPORT void obs_data_set_quat(obs_data_t *data, const char *name, - const struct quat *val); + const struct quat *val); EXPORT void obs_data_set_default_vec2(obs_data_t *data, const char *name, - const struct vec2 *val); + const struct vec2 *val); EXPORT void obs_data_set_default_vec3(obs_data_t *data, const char *name, - const struct vec3 *val); + const struct vec3 *val); EXPORT void obs_data_set_default_vec4(obs_data_t *data, const char *name, - const struct vec4 *val); + const struct vec4 *val); EXPORT void obs_data_set_default_quat(obs_data_t *data, const char *name, - const struct quat *val); + const struct quat *val); EXPORT void obs_data_set_autoselect_vec2(obs_data_t *data, const char *name, - const struct vec2 *val); + const struct vec2 *val); EXPORT void obs_data_set_autoselect_vec3(obs_data_t *data, const char *name, - const struct vec3 *val); + const struct vec3 *val); EXPORT void obs_data_set_autoselect_vec4(obs_data_t *data, const char *name, - const struct vec4 *val); + const struct vec4 *val); EXPORT void obs_data_set_autoselect_quat(obs_data_t *data, const char *name, - const struct quat *val); + const struct quat *val); EXPORT void obs_data_get_vec2(obs_data_t *data, const char *name, - struct vec2 *val); + struct vec2 *val); EXPORT void obs_data_get_vec3(obs_data_t *data, const char *name, - struct vec3 *val); + struct vec3 *val); EXPORT void obs_data_get_vec4(obs_data_t *data, const char *name, - struct vec4 *val); + struct vec4 *val); EXPORT void obs_data_get_quat(obs_data_t *data, const char *name, - struct quat *val); + struct quat *val); EXPORT void obs_data_get_default_vec2(obs_data_t *data, const char *name, - struct vec2 *val); + struct vec2 *val); EXPORT void obs_data_get_default_vec3(obs_data_t *data, const char *name, - struct vec3 *val); + struct vec3 *val); EXPORT void obs_data_get_default_vec4(obs_data_t *data, const char *name, - struct vec4 *val); + struct vec4 *val); EXPORT void obs_data_get_default_quat(obs_data_t *data, const char *name, - struct quat *val); + struct quat *val); EXPORT void obs_data_get_autoselect_vec2(obs_data_t *data, const char *name, - struct vec2 *val); + struct vec2 *val); EXPORT void obs_data_get_autoselect_vec3(obs_data_t *data, const char *name, - struct vec3 *val); + struct vec3 *val); EXPORT void obs_data_get_autoselect_vec4(obs_data_t *data, const char *name, - struct vec4 *val); + struct vec4 *val); EXPORT void obs_data_get_autoselect_quat(obs_data_t *data, const char *name, - struct quat *val); + struct quat *val); /* ------------------------------------------------------------------------- */ /* Helper functions for media_frames_per_second/OBS_PROPERTY_FRAME_RATE */ -EXPORT void obs_data_set_frames_per_second(obs_data_t *data, - const char *name, - struct media_frames_per_second fps, const char *option); -EXPORT void obs_data_set_default_frames_per_second(obs_data_t *data, - const char *name, - struct media_frames_per_second fps, const char *option); -EXPORT void obs_data_set_autoselect_frames_per_second(obs_data_t *data, - const char *name, - struct media_frames_per_second fps, const char *option); +EXPORT void obs_data_set_frames_per_second(obs_data_t *data, const char *name, + struct media_frames_per_second fps, + const char *option); +EXPORT void +obs_data_set_default_frames_per_second(obs_data_t *data, const char *name, + struct media_frames_per_second fps, + const char *option); +EXPORT void +obs_data_set_autoselect_frames_per_second(obs_data_t *data, const char *name, + struct media_frames_per_second fps, + const char *option); -EXPORT bool obs_data_get_frames_per_second(obs_data_t *data, - const char *name, - struct media_frames_per_second *fps, const char **option); -EXPORT bool obs_data_get_default_frames_per_second(obs_data_t *data, - const char *name, - struct media_frames_per_second *fps, const char **option); -EXPORT bool obs_data_get_autoselect_frames_per_second(obs_data_t *data, - const char *name, - struct media_frames_per_second *fps, const char **option); +EXPORT bool obs_data_get_frames_per_second(obs_data_t *data, const char *name, + struct media_frames_per_second *fps, + const char **option); +EXPORT bool +obs_data_get_default_frames_per_second(obs_data_t *data, const char *name, + struct media_frames_per_second *fps, + const char **option); +EXPORT bool +obs_data_get_autoselect_frames_per_second(obs_data_t *data, const char *name, + struct media_frames_per_second *fps, + const char **option); -EXPORT void obs_data_item_set_frames_per_second( - obs_data_item_t **item, - struct media_frames_per_second fps, const char *option); -EXPORT void obs_data_item_set_default_frames_per_second( - obs_data_item_t **item, - struct media_frames_per_second fps, const char *option); +EXPORT void +obs_data_item_set_frames_per_second(obs_data_item_t **item, + struct media_frames_per_second fps, + const char *option); +EXPORT void +obs_data_item_set_default_frames_per_second(obs_data_item_t **item, + struct media_frames_per_second fps, + const char *option); EXPORT void obs_data_item_set_autoselect_frames_per_second( - obs_data_item_t **item, - struct media_frames_per_second fps, const char *option); + obs_data_item_t **item, struct media_frames_per_second fps, + const char *option); -EXPORT bool obs_data_item_get_frames_per_second( - obs_data_item_t *item, - struct media_frames_per_second *fps, const char **option); -EXPORT bool obs_data_item_get_default_frames_per_second( - obs_data_item_t *item, - struct media_frames_per_second *fps, const char **option); +EXPORT bool +obs_data_item_get_frames_per_second(obs_data_item_t *item, + struct media_frames_per_second *fps, + const char **option); +EXPORT bool +obs_data_item_get_default_frames_per_second(obs_data_item_t *item, + struct media_frames_per_second *fps, + const char **option); EXPORT bool obs_data_item_get_autoselect_frames_per_second( - obs_data_item_t *item, - struct media_frames_per_second *fps, const char **option); + obs_data_item_t *item, struct media_frames_per_second *fps, + const char **option); /* ------------------------------------------------------------------------- */ /* OBS-specific functions */ diff --git a/libobs/obs-defs.h b/libobs/obs-defs.h index 694b11c..0530d8f 100644 --- a/libobs/obs-defs.h +++ b/libobs/obs-defs.h @@ -21,30 +21,30 @@ #define MAX_CHANNELS 64 #define OBS_ALIGN_CENTER (0) -#define OBS_ALIGN_LEFT (1<<0) -#define OBS_ALIGN_RIGHT (1<<1) -#define OBS_ALIGN_TOP (1<<2) -#define OBS_ALIGN_BOTTOM (1<<3) +#define OBS_ALIGN_LEFT (1 << 0) +#define OBS_ALIGN_RIGHT (1 << 1) +#define OBS_ALIGN_TOP (1 << 2) +#define OBS_ALIGN_BOTTOM (1 << 3) -#define MODULE_SUCCESS 0 -#define MODULE_ERROR -1 -#define MODULE_FILE_NOT_FOUND -2 -#define MODULE_MISSING_EXPORTS -3 -#define MODULE_INCOMPATIBLE_VER -4 +#define MODULE_SUCCESS 0 +#define MODULE_ERROR -1 +#define MODULE_FILE_NOT_FOUND -2 +#define MODULE_MISSING_EXPORTS -3 +#define MODULE_INCOMPATIBLE_VER -4 -#define OBS_OUTPUT_SUCCESS 0 -#define OBS_OUTPUT_BAD_PATH -1 +#define OBS_OUTPUT_SUCCESS 0 +#define OBS_OUTPUT_BAD_PATH -1 #define OBS_OUTPUT_CONNECT_FAILED -2 #define OBS_OUTPUT_INVALID_STREAM -3 -#define OBS_OUTPUT_ERROR -4 -#define OBS_OUTPUT_DISCONNECTED -5 -#define OBS_OUTPUT_UNSUPPORTED -6 -#define OBS_OUTPUT_NO_SPACE -7 -#define OBS_OUTPUT_ENCODE_ERROR -8 +#define OBS_OUTPUT_ERROR -4 +#define OBS_OUTPUT_DISCONNECTED -5 +#define OBS_OUTPUT_UNSUPPORTED -6 +#define OBS_OUTPUT_NO_SPACE -7 +#define OBS_OUTPUT_ENCODE_ERROR -8 -#define OBS_VIDEO_SUCCESS 0 -#define OBS_VIDEO_FAIL -1 -#define OBS_VIDEO_NOT_SUPPORTED -2 -#define OBS_VIDEO_INVALID_PARAM -3 +#define OBS_VIDEO_SUCCESS 0 +#define OBS_VIDEO_FAIL -1 +#define OBS_VIDEO_NOT_SUPPORTED -2 +#define OBS_VIDEO_INVALID_PARAM -3 #define OBS_VIDEO_CURRENTLY_ACTIVE -4 #define OBS_VIDEO_MODULE_NOT_FOUND -5 diff --git a/libobs/obs-display.c b/libobs/obs-display.c index 5244863..695b3bd 100644 --- a/libobs/obs-display.c +++ b/libobs/obs-display.c @@ -20,7 +20,7 @@ #include "obs-internal.h" bool obs_display_init(struct obs_display *display, - const struct gs_init_data *graphics_data) + const struct gs_init_data *graphics_data) { pthread_mutex_init_value(&display->draw_callbacks_mutex); pthread_mutex_init_value(&display->draw_info_mutex); @@ -29,7 +29,7 @@ bool obs_display_init(struct obs_display *display, display->swap = gs_swapchain_create(graphics_data); if (!display->swap) { blog(LOG_ERROR, "obs_display_init: Failed to " - "create swap chain"); + "create swap chain"); return false; } @@ -51,7 +51,7 @@ bool obs_display_init(struct obs_display *display, } obs_display_t *obs_display_create(const struct gs_init_data *graphics_data, - uint32_t background_color) + uint32_t background_color) { struct obs_display *display = bzalloc(sizeof(struct obs_display)); @@ -64,8 +64,8 @@ obs_display_t *obs_display_create(const struct gs_init_data *graphics_data, display = NULL; } else { pthread_mutex_lock(&obs->data.displays_mutex); - display->prev_next = &obs->data.first_display; - display->next = obs->data.first_display; + display->prev_next = &obs->data.first_display; + display->next = obs->data.first_display; obs->data.first_display = display; if (display->next) display->next->prev_next = &display->next; @@ -109,7 +109,8 @@ void obs_display_destroy(obs_display_t *display) void obs_display_resize(obs_display_t *display, uint32_t cx, uint32_t cy) { - if (!display) return; + if (!display) + return; pthread_mutex_lock(&display->draw_info_mutex); @@ -121,10 +122,12 @@ void obs_display_resize(obs_display_t *display, uint32_t cx, uint32_t cy) } void obs_display_add_draw_callback(obs_display_t *display, - void (*draw)(void *param, uint32_t cx, uint32_t cy), - void *param) + void (*draw)(void *param, uint32_t cx, + uint32_t cy), + void *param) { - if (!display) return; + if (!display) + return; struct draw_callback data = {draw, param}; @@ -134,10 +137,12 @@ void obs_display_add_draw_callback(obs_display_t *display, } void obs_display_remove_draw_callback(obs_display_t *display, - void (*draw)(void *param, uint32_t cx, uint32_t cy), - void *param) + void (*draw)(void *param, uint32_t cx, + uint32_t cy), + void *param) { - if (!display) return; + if (!display) + return; struct draw_callback data = {draw, param}; @@ -147,7 +152,8 @@ void obs_display_remove_draw_callback(obs_display_t *display, } static inline void render_display_begin(struct obs_display *display, - uint32_t cx, uint32_t cy, bool size_changed) + uint32_t cx, uint32_t cy, + bool size_changed) { struct vec4 clear_color; @@ -162,7 +168,7 @@ static inline void render_display_begin(struct obs_display *display, clear_color.w = 1.0f; gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH | GS_CLEAR_STENCIL, - &clear_color, 1.0f, 0); + &clear_color, 1.0f, 0); gs_enable_depth_test(false); /* gs_enable_blending(false); */ @@ -182,7 +188,8 @@ void render_display(struct obs_display *display) uint32_t cx, cy; bool size_changed; - if (!display || !display->enabled) return; + if (!display || !display->enabled) + return; GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DISPLAY, "obs_display"); @@ -207,7 +214,7 @@ void render_display(struct obs_display *display) for (size_t i = 0; i < display->draw_callbacks.num; i++) { struct draw_callback *callback; - callback = display->draw_callbacks.array+i; + callback = display->draw_callbacks.array + i; callback->draw(callback->param, cx, cy); } @@ -238,8 +245,7 @@ void obs_display_set_background_color(obs_display_t *display, uint32_t color) display->background_color = color; } -void obs_display_size(obs_display_t *display, - uint32_t *width, uint32_t *height) +void obs_display_size(obs_display_t *display, uint32_t *width, uint32_t *height) { *width = 0; *height = 0; diff --git a/libobs/obs-encoder.c b/libobs/obs-encoder.c index cede06a..309727b 100644 --- a/libobs/obs-encoder.c +++ b/libobs/obs-encoder.c @@ -18,15 +18,14 @@ #include "obs.h" #include "obs-internal.h" -#define encoder_active(encoder) \ - os_atomic_load_bool(&encoder->active) +#define encoder_active(encoder) os_atomic_load_bool(&encoder->active) #define set_encoder_active(encoder, val) \ os_atomic_set_bool(&encoder->active, val) struct obs_encoder_info *find_encoder(const char *id) { for (size_t i = 0; i < obs->encoder_types.num; i++) { - struct obs_encoder_info *info = obs->encoder_types.array+i; + struct obs_encoder_info *info = obs->encoder_types.array + i; if (strcmp(info->id, id) == 0) return info; @@ -42,20 +41,21 @@ const char *obs_encoder_get_display_name(const char *id) } static bool init_encoder(struct obs_encoder *encoder, const char *name, - obs_data_t *settings, obs_data_t *hotkey_data) + obs_data_t *settings, obs_data_t *hotkey_data) { pthread_mutexattr_t attr; pthread_mutex_init_value(&encoder->init_mutex); pthread_mutex_init_value(&encoder->callbacks_mutex); pthread_mutex_init_value(&encoder->outputs_mutex); + pthread_mutex_init_value(&encoder->pause.mutex); if (pthread_mutexattr_init(&attr) != 0) return false; if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0) return false; if (!obs_context_data_init(&encoder->context, OBS_OBJ_TYPE_ENCODER, - settings, name, hotkey_data, false)) + settings, name, hotkey_data, false)) return false; if (pthread_mutex_init(&encoder->init_mutex, &attr) != 0) return false; @@ -63,16 +63,23 @@ static bool init_encoder(struct obs_encoder *encoder, const char *name, return false; if (pthread_mutex_init(&encoder->outputs_mutex, NULL) != 0) return false; + if (pthread_mutex_init(&encoder->pause.mutex, NULL) != 0) + return false; - if (encoder->orig_info.get_defaults) + if (encoder->orig_info.get_defaults) { encoder->orig_info.get_defaults(encoder->context.settings); + } + if (encoder->orig_info.get_defaults2) { + encoder->orig_info.get_defaults2(encoder->context.settings, + encoder->orig_info.type_data); + } return true; } -static struct obs_encoder *create_encoder(const char *id, - enum obs_encoder_type type, const char *name, - obs_data_t *settings, size_t mixer_idx, obs_data_t *hotkey_data) +static struct obs_encoder * +create_encoder(const char *id, enum obs_encoder_type type, const char *name, + obs_data_t *settings, size_t mixer_idx, obs_data_t *hotkey_data) { struct obs_encoder *encoder; struct obs_encoder_info *ei = find_encoder(id); @@ -87,10 +94,10 @@ static struct obs_encoder *create_encoder(const char *id, if (!ei) { blog(LOG_ERROR, "Encoder ID '%s' not found", id); - encoder->info.id = bstrdup(id); - encoder->info.type = type; + encoder->info.id = bstrdup(id); + encoder->info.type = type; encoder->owns_info_id = true; - encoder->orig_info = encoder->info; + encoder->orig_info = encoder->info; } else { encoder->info = *ei; encoder->orig_info = *ei; @@ -106,35 +113,38 @@ static struct obs_encoder *create_encoder(const char *id, encoder->control = bzalloc(sizeof(obs_weak_encoder_t)); encoder->control->encoder = encoder; - obs_context_data_insert(&encoder->context, - &obs->data.encoders_mutex, - &obs->data.first_encoder); + obs_context_data_insert(&encoder->context, &obs->data.encoders_mutex, + &obs->data.first_encoder); blog(LOG_DEBUG, "encoder '%s' (%s) created", name, id); return encoder; } obs_encoder_t *obs_video_encoder_create(const char *id, const char *name, - obs_data_t *settings, obs_data_t *hotkey_data) + obs_data_t *settings, + obs_data_t *hotkey_data) { - if (!name || !id) return NULL; + if (!name || !id) + return NULL; return create_encoder(id, OBS_ENCODER_VIDEO, name, settings, 0, - hotkey_data); + hotkey_data); } obs_encoder_t *obs_audio_encoder_create(const char *id, const char *name, - obs_data_t *settings, size_t mixer_idx, obs_data_t *hotkey_data) + obs_data_t *settings, size_t mixer_idx, + obs_data_t *hotkey_data) { - if (!name || !id) return NULL; + if (!name || !id) + return NULL; return create_encoder(id, OBS_ENCODER_AUDIO, name, settings, mixer_idx, - hotkey_data); + hotkey_data); } static void receive_video(void *param, struct video_data *frame); static void receive_audio(void *param, size_t mix_idx, struct audio_data *data); static inline void get_audio_info(const struct obs_encoder *encoder, - struct audio_convert_info *info) + struct audio_convert_info *info) { const struct audio_output_info *aoi; aoi = audio_output_get_info(encoder->media); @@ -151,16 +161,16 @@ static inline void get_audio_info(const struct obs_encoder *encoder, } static inline void get_video_info(struct obs_encoder *encoder, - struct video_scale_info *info) + struct video_scale_info *info) { const struct video_output_info *voi; voi = video_output_get_info(encoder->media); - info->format = voi->format; + info->format = voi->format; info->colorspace = voi->colorspace; - info->range = voi->range; - info->width = obs_encoder_get_width(encoder); - info->height = obs_encoder_get_height(encoder); + info->range = voi->range; + info->width = obs_encoder_get_width(encoder); + info->height = obs_encoder_get_height(encoder); if (encoder->info.get_video_info) encoder->info.get_video_info(encoder->context.data, info); @@ -171,18 +181,18 @@ static inline void get_video_info(struct obs_encoder *encoder, static inline bool has_scaling(const struct obs_encoder *encoder) { - uint32_t video_width = video_output_get_width(encoder->media); + uint32_t video_width = video_output_get_width(encoder->media); uint32_t video_height = video_output_get_height(encoder->media); return encoder->scaled_width && encoder->scaled_height && - (video_width != encoder->scaled_width || - video_height != encoder->scaled_height); + (video_width != encoder->scaled_width || + video_height != encoder->scaled_height); } static inline bool gpu_encode_available(const struct obs_encoder *encoder) { - return (encoder->info.caps & OBS_ENCODER_CAP_PASS_TEXTURE) != 0 && - obs->video.using_nv12_tex; + return (encoder->info.caps & OBS_ENCODER_CAP_PASS_TEXTURE) != 0 && + obs->video.using_nv12_tex; } static void add_connection(struct obs_encoder *encoder) @@ -192,7 +202,7 @@ static void add_connection(struct obs_encoder *encoder) get_audio_info(encoder, &audio_info); audio_output_connect(encoder->media, encoder->mixer_idx, - &audio_info, receive_audio, encoder); + &audio_info, receive_audio, encoder); } else { struct video_scale_info info = {0}; get_video_info(encoder, &info); @@ -212,7 +222,7 @@ static void remove_connection(struct obs_encoder *encoder, bool shutdown) { if (encoder->info.type == OBS_ENCODER_AUDIO) { audio_output_disconnect(encoder->media, encoder->mixer_idx, - receive_audio, encoder); + receive_audio, encoder); } else { if (gpu_encode_available(encoder)) { stop_gpu_encode(encoder); @@ -251,7 +261,8 @@ static void obs_encoder_actually_destroy(obs_encoder_t *encoder) da_free(encoder->outputs); pthread_mutex_unlock(&encoder->outputs_mutex); - blog(LOG_DEBUG, "encoder '%s' destroyed", encoder->context.name); + blog(LOG_DEBUG, "encoder '%s' destroyed", + encoder->context.name); free_audio_buffers(encoder); @@ -261,9 +272,10 @@ static void obs_encoder_actually_destroy(obs_encoder_t *encoder) pthread_mutex_destroy(&encoder->init_mutex); pthread_mutex_destroy(&encoder->callbacks_mutex); pthread_mutex_destroy(&encoder->outputs_mutex); + pthread_mutex_destroy(&encoder->pause.mutex); obs_context_data_free(&encoder->context); if (encoder->owns_info_id) - bfree((void*)encoder->info.id); + bfree((void *)encoder->info.id); bfree(encoder); } } @@ -292,8 +304,9 @@ void obs_encoder_destroy(obs_encoder_t *encoder) const char *obs_encoder_get_name(const obs_encoder_t *encoder) { - return obs_encoder_valid(encoder, "obs_encoder_get_name") ? - encoder->context.name : NULL; + return obs_encoder_valid(encoder, "obs_encoder_get_name") + ? encoder->context.name + : NULL; } void obs_encoder_set_name(obs_encoder_t *encoder, const char *name) @@ -308,10 +321,11 @@ void obs_encoder_set_name(obs_encoder_t *encoder, const char *name) static inline obs_data_t *get_defaults(const struct obs_encoder_info *info) { obs_data_t *settings = obs_data_create(); + if (info->get_defaults) { + info->get_defaults(settings); + } if (info->get_defaults2) { info->get_defaults2(settings, info->type_data); - } else if (info->get_defaults) { - info->get_defaults(settings); } return settings; } @@ -334,8 +348,8 @@ obs_properties_t *obs_get_encoder_properties(const char *id) { const struct obs_encoder_info *ei = find_encoder(id); if (ei && (ei->get_properties || ei->get_properties2)) { - obs_data_t *defaults = get_defaults(ei); - obs_properties_t *properties; + obs_data_t *defaults = get_defaults(ei); + obs_properties_t *properties = NULL; if (ei->get_properties2) { properties = ei->get_properties2(NULL, ei->type_data); @@ -358,14 +372,14 @@ obs_properties_t *obs_encoder_properties(const obs_encoder_t *encoder) if (encoder->orig_info.get_properties2) { obs_properties_t *props; props = encoder->orig_info.get_properties2( - encoder->context.data, - encoder->orig_info.type_data); + encoder->context.data, encoder->orig_info.type_data); obs_properties_apply_settings(props, encoder->context.settings); return props; } else if (encoder->orig_info.get_properties) { obs_properties_t *props; - props = encoder->orig_info.get_properties(encoder->context.data); + props = encoder->orig_info.get_properties( + encoder->context.data); obs_properties_apply_settings(props, encoder->context.settings); return props; } @@ -382,18 +396,18 @@ void obs_encoder_update(obs_encoder_t *encoder, obs_data_t *settings) if (encoder->info.update && encoder->context.data) encoder->info.update(encoder->context.data, - encoder->context.settings); + encoder->context.settings); } bool obs_encoder_get_extra_data(const obs_encoder_t *encoder, - uint8_t **extra_data, size_t *size) + uint8_t **extra_data, size_t *size) { if (!obs_encoder_valid(encoder, "obs_encoder_get_extra_data")) return false; if (encoder->info.get_extra_data && encoder->context.data) return encoder->info.get_extra_data(encoder->context.data, - extra_data, size); + extra_data, size); return false; } @@ -422,10 +436,10 @@ static void intitialize_audio_encoder(struct obs_encoder *encoder) get_audio_info(encoder, &info); encoder->samplerate = info.samples_per_sec; - encoder->planes = get_audio_planes(info.format, info.speakers); - encoder->blocksize = get_audio_size(info.format, info.speakers, 1); - encoder->framesize = encoder->info.get_frame_size( - encoder->context.data); + encoder->planes = get_audio_planes(info.format, info.speakers); + encoder->blocksize = get_audio_size(info.format, info.speakers, 1); + encoder->framesize = + encoder->info.get_frame_size(encoder->context.data); encoder->framesize_bytes = encoder->blocksize * encoder->framesize; reset_audio_buffers(encoder); @@ -446,7 +460,7 @@ static inline bool obs_encoder_initialize_internal(obs_encoder_t *encoder) can_reroute = true; encoder->info = encoder->orig_info; encoder->context.data = encoder->orig_info.create( - encoder->context.settings, encoder); + encoder->context.settings, encoder); can_reroute = false; } if (!encoder->context.data) @@ -459,7 +473,8 @@ static inline bool obs_encoder_initialize_internal(obs_encoder_t *encoder) return true; } -void *obs_encoder_create_rerouted(obs_encoder_t *encoder, const char *reroute_id) +void *obs_encoder_create_rerouted(obs_encoder_t *encoder, + const char *reroute_id) { if (!obs_ptr_valid(encoder, "obs_encoder_reroute")) return NULL; @@ -485,7 +500,8 @@ bool obs_encoder_initialize(obs_encoder_t *encoder) { bool success; - if (!encoder) return false; + if (!encoder) + return false; pthread_mutex_lock(&encoder->init_mutex); success = obs_encoder_initialize_internal(encoder); @@ -499,22 +515,22 @@ void obs_encoder_shutdown(obs_encoder_t *encoder) pthread_mutex_lock(&encoder->init_mutex); if (encoder->context.data) { encoder->info.destroy(encoder->context.data); - encoder->context.data = NULL; - encoder->paired_encoder = NULL; - encoder->first_received = false; - encoder->offset_usec = 0; - encoder->start_ts = 0; + encoder->context.data = NULL; + encoder->paired_encoder = NULL; + encoder->first_received = false; + encoder->offset_usec = 0; + encoder->start_ts = 0; } pthread_mutex_unlock(&encoder->init_mutex); } -static inline size_t get_callback_idx( - const struct obs_encoder *encoder, - void (*new_packet)(void *param, struct encoder_packet *packet), - void *param) +static inline size_t +get_callback_idx(const struct obs_encoder *encoder, + void (*new_packet)(void *param, struct encoder_packet *packet), + void *param) { for (size_t i = 0; i < encoder->callbacks.num; i++) { - struct encoder_callback *cb = encoder->callbacks.array+i; + struct encoder_callback *cb = encoder->callbacks.array + i; if (cb->new_packet == new_packet && cb->param == param) return i; @@ -523,12 +539,23 @@ static inline size_t get_callback_idx( return DARRAY_INVALID; } -static inline void obs_encoder_start_internal(obs_encoder_t *encoder, - void (*new_packet)(void *param, struct encoder_packet *packet), - void *param) +void pause_reset(struct pause_data *pause) +{ + pthread_mutex_lock(&pause->mutex); + pause->last_video_ts = 0; + pause->ts_start = 0; + pause->ts_end = 0; + pause->ts_offset = 0; + pthread_mutex_unlock(&pause->mutex); +} + +static inline void obs_encoder_start_internal( + obs_encoder_t *encoder, + void (*new_packet)(void *param, struct encoder_packet *packet), + void *param) { struct encoder_callback cb = {false, new_packet, param}; - bool first = false; + bool first = false; if (!encoder->context.data) return; @@ -544,14 +571,18 @@ static inline void obs_encoder_start_internal(obs_encoder_t *encoder, pthread_mutex_unlock(&encoder->callbacks_mutex); if (first) { + os_atomic_set_bool(&encoder->paused, false); + pause_reset(&encoder->pause); + encoder->cur_pts = 0; add_connection(encoder); } } void obs_encoder_start(obs_encoder_t *encoder, - void (*new_packet)(void *param, struct encoder_packet *packet), - void *param) + void (*new_packet)(void *param, + struct encoder_packet *packet), + void *param) { if (!obs_encoder_valid(encoder, "obs_encoder_start")) return; @@ -563,11 +594,12 @@ void obs_encoder_start(obs_encoder_t *encoder, pthread_mutex_unlock(&encoder->init_mutex); } -static inline bool obs_encoder_stop_internal(obs_encoder_t *encoder, - void (*new_packet)(void *param, struct encoder_packet *packet), - void *param) +static inline bool obs_encoder_stop_internal( + obs_encoder_t *encoder, + void (*new_packet)(void *param, struct encoder_packet *packet), + void *param) { - bool last = false; + bool last = false; size_t idx; pthread_mutex_lock(&encoder->callbacks_mutex); @@ -595,8 +627,9 @@ static inline bool obs_encoder_stop_internal(obs_encoder_t *encoder, } void obs_encoder_stop(obs_encoder_t *encoder, - void (*new_packet)(void *param, struct encoder_packet *packet), - void *param) + void (*new_packet)(void *param, + struct encoder_packet *packet), + void *param) { bool destroyed; @@ -613,8 +646,9 @@ void obs_encoder_stop(obs_encoder_t *encoder, const char *obs_encoder_get_codec(const obs_encoder_t *encoder) { - return obs_encoder_valid(encoder, "obs_encoder_get_codec") ? - encoder->info.codec : NULL; + return obs_encoder_valid(encoder, "obs_encoder_get_codec") + ? encoder->info.codec + : NULL; } const char *obs_get_encoder_codec(const char *id) @@ -625,8 +659,9 @@ const char *obs_get_encoder_codec(const char *id) enum obs_encoder_type obs_encoder_get_type(const obs_encoder_t *encoder) { - return obs_encoder_valid(encoder, "obs_encoder_get_type") ? - encoder->info.type : OBS_ENCODER_AUDIO; + return obs_encoder_valid(encoder, "obs_encoder_get_type") + ? encoder->info.type + : OBS_ENCODER_AUDIO; } enum obs_encoder_type obs_get_encoder_type(const char *id) @@ -636,24 +671,26 @@ enum obs_encoder_type obs_get_encoder_type(const char *id) } void obs_encoder_set_scaled_size(obs_encoder_t *encoder, uint32_t width, - uint32_t height) + uint32_t height) { if (!obs_encoder_valid(encoder, "obs_encoder_set_scaled_size")) return; if (encoder->info.type != OBS_ENCODER_VIDEO) { - blog(LOG_WARNING, "obs_encoder_set_scaled_size: " - "encoder '%s' is not a video encoder", - obs_encoder_get_name(encoder)); + blog(LOG_WARNING, + "obs_encoder_set_scaled_size: " + "encoder '%s' is not a video encoder", + obs_encoder_get_name(encoder)); return; } if (encoder_active(encoder)) { - blog(LOG_WARNING, "encoder '%s': Cannot set the scaled " - "resolution while the encoder is active", - obs_encoder_get_name(encoder)); + blog(LOG_WARNING, + "encoder '%s': Cannot set the scaled " + "resolution while the encoder is active", + obs_encoder_get_name(encoder)); return; } - encoder->scaled_width = width; + encoder->scaled_width = width; encoder->scaled_height = height; } @@ -662,17 +699,18 @@ uint32_t obs_encoder_get_width(const obs_encoder_t *encoder) if (!obs_encoder_valid(encoder, "obs_encoder_get_width")) return 0; if (encoder->info.type != OBS_ENCODER_VIDEO) { - blog(LOG_WARNING, "obs_encoder_get_width: " - "encoder '%s' is not a video encoder", - obs_encoder_get_name(encoder)); + blog(LOG_WARNING, + "obs_encoder_get_width: " + "encoder '%s' is not a video encoder", + obs_encoder_get_name(encoder)); return 0; } if (!encoder->media) return 0; - return encoder->scaled_width != 0 ? - encoder->scaled_width : - video_output_get_width(encoder->media); + return encoder->scaled_width != 0 + ? encoder->scaled_width + : video_output_get_width(encoder->media); } uint32_t obs_encoder_get_height(const obs_encoder_t *encoder) @@ -680,17 +718,18 @@ uint32_t obs_encoder_get_height(const obs_encoder_t *encoder) if (!obs_encoder_valid(encoder, "obs_encoder_get_height")) return 0; if (encoder->info.type != OBS_ENCODER_VIDEO) { - blog(LOG_WARNING, "obs_encoder_get_height: " - "encoder '%s' is not a video encoder", - obs_encoder_get_name(encoder)); + blog(LOG_WARNING, + "obs_encoder_get_height: " + "encoder '%s' is not a video encoder", + obs_encoder_get_name(encoder)); return 0; } if (!encoder->media) return 0; - return encoder->scaled_height != 0 ? - encoder->scaled_height : - video_output_get_height(encoder->media); + return encoder->scaled_height != 0 + ? encoder->scaled_height + : video_output_get_height(encoder->media); } uint32_t obs_encoder_get_sample_rate(const obs_encoder_t *encoder) @@ -698,17 +737,18 @@ uint32_t obs_encoder_get_sample_rate(const obs_encoder_t *encoder) if (!obs_encoder_valid(encoder, "obs_encoder_get_sample_rate")) return 0; if (encoder->info.type != OBS_ENCODER_AUDIO) { - blog(LOG_WARNING, "obs_encoder_get_sample_rate: " - "encoder '%s' is not an audio encoder", - obs_encoder_get_name(encoder)); + blog(LOG_WARNING, + "obs_encoder_get_sample_rate: " + "encoder '%s' is not an audio encoder", + obs_encoder_get_name(encoder)); return 0; } if (!encoder->media) return 0; - return encoder->samplerate != 0 ? - encoder->samplerate : - audio_output_get_sample_rate(encoder->media); + return encoder->samplerate != 0 + ? encoder->samplerate + : audio_output_get_sample_rate(encoder->media); } void obs_encoder_set_video(obs_encoder_t *encoder, video_t *video) @@ -718,9 +758,10 @@ void obs_encoder_set_video(obs_encoder_t *encoder, video_t *video) if (!obs_encoder_valid(encoder, "obs_encoder_set_video")) return; if (encoder->info.type != OBS_ENCODER_VIDEO) { - blog(LOG_WARNING, "obs_encoder_set_video: " - "encoder '%s' is not a video encoder", - obs_encoder_get_name(encoder)); + blog(LOG_WARNING, + "obs_encoder_set_video: " + "encoder '%s' is not a video encoder", + obs_encoder_get_name(encoder)); return; } if (!video) @@ -728,7 +769,7 @@ void obs_encoder_set_video(obs_encoder_t *encoder, video_t *video) voi = video_output_get_info(video); - encoder->media = video; + encoder->media = video; encoder->timebase_num = voi->fps_den; encoder->timebase_den = voi->fps_num; } @@ -738,15 +779,16 @@ void obs_encoder_set_audio(obs_encoder_t *encoder, audio_t *audio) if (!obs_encoder_valid(encoder, "obs_encoder_set_audio")) return; if (encoder->info.type != OBS_ENCODER_AUDIO) { - blog(LOG_WARNING, "obs_encoder_set_audio: " - "encoder '%s' is not an audio encoder", - obs_encoder_get_name(encoder)); + blog(LOG_WARNING, + "obs_encoder_set_audio: " + "encoder '%s' is not an audio encoder", + obs_encoder_get_name(encoder)); return; } if (!audio) return; - encoder->media = audio; + encoder->media = audio; encoder->timebase_num = 1; encoder->timebase_den = audio_output_get_sample_rate(audio); } @@ -756,9 +798,10 @@ video_t *obs_encoder_video(const obs_encoder_t *encoder) if (!obs_encoder_valid(encoder, "obs_encoder_video")) return NULL; if (encoder->info.type != OBS_ENCODER_VIDEO) { - blog(LOG_WARNING, "obs_encoder_set_video: " - "encoder '%s' is not a video encoder", - obs_encoder_get_name(encoder)); + blog(LOG_WARNING, + "obs_encoder_set_video: " + "encoder '%s' is not a video encoder", + obs_encoder_get_name(encoder)); return NULL; } @@ -770,9 +813,10 @@ audio_t *obs_encoder_audio(const obs_encoder_t *encoder) if (!obs_encoder_valid(encoder, "obs_encoder_audio")) return NULL; if (encoder->info.type != OBS_ENCODER_AUDIO) { - blog(LOG_WARNING, "obs_encoder_set_audio: " - "encoder '%s' is not an audio encoder", - obs_encoder_get_name(encoder)); + blog(LOG_WARNING, + "obs_encoder_set_audio: " + "encoder '%s' is not an audio encoder", + obs_encoder_get_name(encoder)); return NULL; } @@ -781,26 +825,28 @@ audio_t *obs_encoder_audio(const obs_encoder_t *encoder) bool obs_encoder_active(const obs_encoder_t *encoder) { - return obs_encoder_valid(encoder, "obs_encoder_active") ? - encoder_active(encoder) : false; + return obs_encoder_valid(encoder, "obs_encoder_active") + ? encoder_active(encoder) + : false; } -static inline bool get_sei(const struct obs_encoder *encoder, - uint8_t **sei, size_t *size) +static inline bool get_sei(const struct obs_encoder *encoder, uint8_t **sei, + size_t *size) { if (encoder->info.get_sei_data) return encoder->info.get_sei_data(encoder->context.data, sei, - size); + size); return false; } static void send_first_video_packet(struct obs_encoder *encoder, - struct encoder_callback *cb, struct encoder_packet *packet) + struct encoder_callback *cb, + struct encoder_packet *packet) { struct encoder_packet first_packet; - DARRAY(uint8_t) data; - uint8_t *sei; - size_t size; + DARRAY(uint8_t) data; + uint8_t *sei; + size_t size; /* always wait for first keyframe */ if (!packet->keyframe) @@ -817,7 +863,7 @@ static void send_first_video_packet(struct obs_encoder *encoder, da_push_back_array(data, sei, size); da_push_back_array(data, packet->data, packet->size); - first_packet = *packet; + first_packet = *packet; first_packet.data = data.array; first_packet.size = data.num; @@ -828,7 +874,8 @@ static void send_first_video_packet(struct obs_encoder *encoder, } static inline void send_packet(struct obs_encoder *encoder, - struct encoder_callback *cb, struct encoder_packet *packet) + struct encoder_callback *cb, + struct encoder_packet *packet) { /* include SEI in first video packet */ if (encoder->info.type == OBS_ENCODER_VIDEO && !cb->sent_first_packet) @@ -861,11 +908,11 @@ void full_stop(struct obs_encoder *encoder) } void send_off_encoder_packet(obs_encoder_t *encoder, bool success, - bool received, struct encoder_packet *pkt) + bool received, struct encoder_packet *pkt) { if (!success) { blog(LOG_ERROR, "Error encoding with encoder '%s'", - encoder->context.name); + encoder->context.name); full_stop(encoder); return; } @@ -879,14 +926,18 @@ void send_off_encoder_packet(obs_encoder_t *encoder, bool success, /* we use system time here to ensure sync with other encoders, * you do not want to use relative timestamps here */ pkt->dts_usec = encoder->start_ts / 1000 + - packet_dts_usec(pkt) - encoder->offset_usec; + packet_dts_usec(pkt) - encoder->offset_usec; pkt->sys_dts_usec = pkt->dts_usec; + pthread_mutex_lock(&encoder->pause.mutex); + pkt->sys_dts_usec += encoder->pause.ts_offset / 1000; + pthread_mutex_unlock(&encoder->pause.mutex); + pthread_mutex_lock(&encoder->callbacks_mutex); for (size_t i = encoder->callbacks.num; i > 0; i--) { struct encoder_callback *cb; - cb = encoder->callbacks.array+(i-1); + cb = encoder->callbacks.array + (i - 1); send_packet(encoder, cb, pkt); } @@ -901,7 +952,7 @@ bool do_encode(struct obs_encoder *encoder, struct encoder_frame *frame) if (!encoder->profile_encoder_encode_name) encoder->profile_encoder_encode_name = profile_store_name(obs_get_profiler_name_store(), - "encode(%s)", encoder->context.name); + "encode(%s)", encoder->context.name); struct encoder_packet pkt = {0}; bool received = false; @@ -913,7 +964,7 @@ bool do_encode(struct obs_encoder *encoder, struct encoder_frame *frame) profile_start(encoder->profile_encoder_encode_name); success = encoder->info.encode(encoder->context.data, frame, &pkt, - &received); + &received); profile_end(encoder->profile_encoder_encode_name); send_off_encoder_packet(encoder, success, received, &pkt); @@ -922,14 +973,44 @@ bool do_encode(struct obs_encoder *encoder, struct encoder_frame *frame) return success; } +static inline bool video_pause_check_internal(struct pause_data *pause, + uint64_t ts) +{ + pause->last_video_ts = ts; + if (!pause->ts_start) { + return false; + } + + if (ts == pause->ts_end) { + pause->ts_start = 0; + pause->ts_end = 0; + + } else if (ts >= pause->ts_start) { + return true; + } + + return false; +} + +bool video_pause_check(struct pause_data *pause, uint64_t timestamp) +{ + bool ignore_frame; + + pthread_mutex_lock(&pause->mutex); + ignore_frame = video_pause_check_internal(pause, timestamp); + pthread_mutex_unlock(&pause->mutex); + + return ignore_frame; +} + static const char *receive_video_name = "receive_video"; static void receive_video(void *param, struct video_data *frame) { profile_start(receive_video_name); - struct obs_encoder *encoder = param; - struct obs_encoder *pair = encoder->paired_encoder; - struct encoder_frame enc_frame; + struct obs_encoder *encoder = param; + struct obs_encoder *pair = encoder->paired_encoder; + struct encoder_frame enc_frame; if (!encoder->first_received && pair) { if (!pair->first_received || @@ -938,10 +1019,13 @@ static void receive_video(void *param, struct video_data *frame) } } + if (video_pause_check(&encoder->pause, frame->timestamp)) + goto wait_for_audio; + memset(&enc_frame, 0, sizeof(struct encoder_frame)); for (size_t i = 0; i < MAX_AV_PLANES; i++) { - enc_frame.data[i] = frame->data[i]; + enc_frame.data[i] = frame->data[i]; enc_frame.linesize[i] = frame->linesize[i]; } @@ -949,7 +1033,7 @@ static void receive_video(void *param, struct video_data *frame) encoder->start_ts = frame->timestamp; enc_frame.frames = 1; - enc_frame.pts = encoder->cur_pts; + enc_frame.pts = encoder->cur_pts; if (do_encode(encoder, &enc_frame)) encoder->cur_pts += encoder->timebase_num; @@ -965,7 +1049,8 @@ static void clear_audio(struct obs_encoder *encoder) } static inline void push_back_audio(struct obs_encoder *encoder, - struct audio_data *data, size_t size, size_t offset_size) + struct audio_data *data, size_t size, + size_t offset_size) { size -= offset_size; @@ -973,15 +1058,15 @@ static inline void push_back_audio(struct obs_encoder *encoder, if (size) for (size_t i = 0; i < encoder->planes; i++) circlebuf_push_back(&encoder->audio_input_buffer[i], - data->data[i] + offset_size, size); + data->data[i] + offset_size, size); } static inline size_t calc_offset_size(struct obs_encoder *encoder, - uint64_t v_start_ts, uint64_t a_start_ts) + uint64_t v_start_ts, uint64_t a_start_ts) { uint64_t offset = v_start_ts - a_start_ts; offset = (uint64_t)offset * (uint64_t)encoder->samplerate / - 1000000000ULL; + 1000000000ULL; return (size_t)offset * encoder->blocksize; } @@ -994,12 +1079,12 @@ static void start_from_buffer(struct obs_encoder *encoder, uint64_t v_start_ts) for (size_t i = 0; i < MAX_AV_PLANES; i++) { audio.data[i] = encoder->audio_input_buffer[i].data; memset(&encoder->audio_input_buffer[i], 0, - sizeof(struct circlebuf)); + sizeof(struct circlebuf)); } if (encoder->first_raw_ts < v_start_ts) offset_size = calc_offset_size(encoder, v_start_ts, - encoder->first_raw_ts); + encoder->first_raw_ts); push_back_audio(encoder, &audio, size, offset_size); @@ -1017,7 +1102,7 @@ static bool buffer_audio(struct obs_encoder *encoder, struct audio_data *data) bool success = true; if (!encoder->start_ts && encoder->paired_encoder) { - uint64_t end_ts = data->timestamp; + uint64_t end_ts = data->timestamp; uint64_t v_start_ts = encoder->paired_encoder->start_ts; /* no video yet, so don't start audio */ @@ -1029,7 +1114,7 @@ static bool buffer_audio(struct obs_encoder *encoder, struct audio_data *data) /* audio starting point still not synced with video starting * point, so don't start audio */ end_ts += (uint64_t)data->frames * 1000000000ULL / - (uint64_t)encoder->samplerate; + (uint64_t)encoder->samplerate; if (end_ts <= v_start_ts) { success = false; goto fail; @@ -1038,7 +1123,7 @@ static bool buffer_audio(struct obs_encoder *encoder, struct audio_data *data) /* ready to start audio, truncate if necessary */ if (data->timestamp < v_start_ts) offset_size = calc_offset_size(encoder, v_start_ts, - data->timestamp); + data->timestamp); if (data->timestamp <= v_start_ts) clear_audio(encoder); @@ -1062,21 +1147,21 @@ fail: static bool send_audio_data(struct obs_encoder *encoder) { - struct encoder_frame enc_frame; + struct encoder_frame enc_frame; memset(&enc_frame, 0, sizeof(struct encoder_frame)); for (size_t i = 0; i < encoder->planes; i++) { circlebuf_pop_front(&encoder->audio_input_buffer[i], - encoder->audio_output_buffer[i], - encoder->framesize_bytes); + encoder->audio_output_buffer[i], + encoder->framesize_bytes); - enc_frame.data[i] = encoder->audio_output_buffer[i]; + enc_frame.data[i] = encoder->audio_output_buffer[i]; enc_frame.linesize[i] = (uint32_t)encoder->framesize_bytes; } enc_frame.frames = (uint32_t)encoder->framesize; - enc_frame.pts = encoder->cur_pts; + enc_frame.pts = encoder->cur_pts; if (!do_encode(encoder, &enc_frame)) return false; @@ -1085,23 +1170,100 @@ static bool send_audio_data(struct obs_encoder *encoder) return true; } +static void pause_audio(struct pause_data *pause, struct audio_data *data, + size_t sample_rate) +{ + uint64_t cutoff_frames = pause->ts_start - data->timestamp; + cutoff_frames = ns_to_audio_frames(sample_rate, cutoff_frames); + + data->frames = (uint32_t)cutoff_frames; +} + +static void unpause_audio(struct pause_data *pause, struct audio_data *data, + size_t sample_rate) +{ + uint64_t cutoff_frames = pause->ts_end - data->timestamp; + cutoff_frames = ns_to_audio_frames(sample_rate, cutoff_frames); + + for (size_t i = 0; i < MAX_AV_PLANES; i++) { + if (!data->data[i]) + break; + data->data[i] += cutoff_frames * sizeof(float); + } + + data->timestamp = pause->ts_start; + data->frames = data->frames - (uint32_t)cutoff_frames; + pause->ts_start = 0; + pause->ts_end = 0; +} + +static inline bool audio_pause_check_internal(struct pause_data *pause, + struct audio_data *data, + size_t sample_rate) +{ + uint64_t end_ts; + + if (!pause->ts_start) { + return false; + } + + end_ts = + data->timestamp + audio_frames_to_ns(sample_rate, data->frames); + + if (pause->ts_start >= data->timestamp) { + if (pause->ts_start <= end_ts) { + pause_audio(pause, data, sample_rate); + return !data->frames; + } + + } else { + if (pause->ts_end >= data->timestamp && + pause->ts_end <= end_ts) { + unpause_audio(pause, data, sample_rate); + return !data->frames; + } + + return true; + } + + return false; +} + +bool audio_pause_check(struct pause_data *pause, struct audio_data *data, + size_t sample_rate) +{ + bool ignore_audio; + + pthread_mutex_lock(&pause->mutex); + ignore_audio = audio_pause_check_internal(pause, data, sample_rate); + data->timestamp -= pause->ts_offset; + pthread_mutex_unlock(&pause->mutex); + + return ignore_audio; +} + static const char *receive_audio_name = "receive_audio"; -static void receive_audio(void *param, size_t mix_idx, struct audio_data *data) +static void receive_audio(void *param, size_t mix_idx, struct audio_data *in) { profile_start(receive_audio_name); struct obs_encoder *encoder = param; + struct audio_data audio = *in; if (!encoder->first_received) { - encoder->first_raw_ts = data->timestamp; + encoder->first_raw_ts = audio.timestamp; encoder->first_received = true; clear_audio(encoder); } - if (!buffer_audio(encoder, data)) + if (audio_pause_check(&encoder->pause, &audio, encoder->samplerate)) goto end; - while (encoder->audio_input_buffer[0].size >= encoder->framesize_bytes) { + if (!buffer_audio(encoder, &audio)) + goto end; + + while (encoder->audio_input_buffer[0].size >= + encoder->framesize_bytes) { if (!send_audio_data(encoder)) { break; } @@ -1114,9 +1276,10 @@ end: } void obs_encoder_add_output(struct obs_encoder *encoder, - struct obs_output *output) + struct obs_output *output) { - if (!encoder) return; + if (!encoder) + return; pthread_mutex_lock(&encoder->outputs_mutex); da_push_back(encoder->outputs, &output); @@ -1124,9 +1287,10 @@ void obs_encoder_add_output(struct obs_encoder *encoder, } void obs_encoder_remove_output(struct obs_encoder *encoder, - struct obs_output *output) + struct obs_output *output) { - if (!encoder) return; + if (!encoder) + return; pthread_mutex_lock(&encoder->outputs_mutex); da_erase_item(encoder->outputs, &output); @@ -1134,19 +1298,19 @@ void obs_encoder_remove_output(struct obs_encoder *encoder, } void obs_encoder_packet_create_instance(struct encoder_packet *dst, - const struct encoder_packet *src) + const struct encoder_packet *src) { long *p_refs; *dst = *src; p_refs = bmalloc(src->size + sizeof(long)); - dst->data = (void*)(p_refs + 1); + dst->data = (void *)(p_refs + 1); *p_refs = 1; memcpy(dst->data, src->data, src->size); } void obs_duplicate_encoder_packet(struct encoder_packet *dst, - const struct encoder_packet *src) + const struct encoder_packet *src) { obs_encoder_packet_create_instance(dst, src); } @@ -1157,13 +1321,13 @@ void obs_free_encoder_packet(struct encoder_packet *packet) } void obs_encoder_packet_ref(struct encoder_packet *dst, - struct encoder_packet *src) + struct encoder_packet *src) { if (!src) return; if (src->data) { - long *p_refs = ((long*)src->data) - 1; + long *p_refs = ((long *)src->data) - 1; os_atomic_inc_long(p_refs); } @@ -1176,7 +1340,7 @@ void obs_encoder_packet_release(struct encoder_packet *pkt) return; if (pkt->data) { - long *p_refs = ((long*)pkt->data) - 1; + long *p_refs = ((long *)pkt->data) - 1; if (os_atomic_dec_long(p_refs) == 0) bfree(p_refs); } @@ -1185,7 +1349,7 @@ void obs_encoder_packet_release(struct encoder_packet *pkt) } void obs_encoder_set_preferred_video_format(obs_encoder_t *encoder, - enum video_format format) + enum video_format format) { if (!encoder || encoder->info.type != OBS_ENCODER_VIDEO) return; @@ -1193,8 +1357,8 @@ void obs_encoder_set_preferred_video_format(obs_encoder_t *encoder, encoder->preferred_format = format; } -enum video_format obs_encoder_get_preferred_video_format( - const obs_encoder_t *encoder) +enum video_format +obs_encoder_get_preferred_video_format(const obs_encoder_t *encoder) { if (!encoder || encoder->info.type != OBS_ENCODER_VIDEO) return VIDEO_FORMAT_NONE; @@ -1272,7 +1436,7 @@ obs_encoder_t *obs_weak_encoder_get_encoder(obs_weak_encoder_t *weak) } bool obs_weak_encoder_references_encoder(obs_weak_encoder_t *weak, - obs_encoder_t *encoder) + obs_encoder_t *encoder) { return weak && encoder && weak->encoder == encoder; } @@ -1280,13 +1444,15 @@ bool obs_weak_encoder_references_encoder(obs_weak_encoder_t *weak, void *obs_encoder_get_type_data(obs_encoder_t *encoder) { return obs_encoder_valid(encoder, "obs_encoder_get_type_data") - ? encoder->orig_info.type_data : NULL; + ? encoder->orig_info.type_data + : NULL; } const char *obs_encoder_get_id(const obs_encoder_t *encoder) { return obs_encoder_valid(encoder, "obs_encoder_get_id") - ? encoder->orig_info.id : NULL; + ? encoder->orig_info.id + : NULL; } uint32_t obs_get_encoder_caps(const char *encoder_id) @@ -1298,5 +1464,13 @@ uint32_t obs_get_encoder_caps(const char *encoder_id) uint32_t obs_encoder_get_caps(const obs_encoder_t *encoder) { return obs_encoder_valid(encoder, "obs_encoder_get_caps") - ? encoder->orig_info.caps : 0; + ? encoder->orig_info.caps + : 0; +} + +bool obs_encoder_paused(const obs_encoder_t *encoder) +{ + return obs_encoder_valid(encoder, "obs_encoder_paused") + ? os_atomic_load_bool(&encoder->paused) + : false; } diff --git a/libobs/obs-encoder.h b/libobs/obs-encoder.h index 3264423..1c7daa6 100644 --- a/libobs/obs-encoder.h +++ b/libobs/obs-encoder.h @@ -29,8 +29,9 @@ extern "C" { #endif -#define OBS_ENCODER_CAP_DEPRECATED (1<<0) -#define OBS_ENCODER_CAP_PASS_TEXTURE (1<<1) +#define OBS_ENCODER_CAP_DEPRECATED (1 << 0) +#define OBS_ENCODER_CAP_PASS_TEXTURE (1 << 1) +#define OBS_ENCODER_CAP_DYN_BITRATE (1 << 2) /** Specifies the encoder type */ enum obs_encoder_type { @@ -40,27 +41,27 @@ enum obs_encoder_type { /** Encoder output packet */ struct encoder_packet { - uint8_t *data; /**< Packet data */ - size_t size; /**< Packet size */ + uint8_t *data; /**< Packet data */ + size_t size; /**< Packet size */ - int64_t pts; /**< Presentation timestamp */ - int64_t dts; /**< Decode timestamp */ + int64_t pts; /**< Presentation timestamp */ + int64_t dts; /**< Decode timestamp */ - int32_t timebase_num; /**< Timebase numerator */ - int32_t timebase_den; /**< Timebase denominator */ + int32_t timebase_num; /**< Timebase numerator */ + int32_t timebase_den; /**< Timebase denominator */ - enum obs_encoder_type type; /**< Encoder type */ + enum obs_encoder_type type; /**< Encoder type */ - bool keyframe; /**< Is a keyframe */ + bool keyframe; /**< Is a keyframe */ /* ---------------------------------------------------------------- */ /* Internal video variables (will be parsed automatically) */ /* DTS in microseconds */ - int64_t dts_usec; + int64_t dts_usec; /* System DTS in microseconds */ - int64_t sys_dts_usec; + int64_t sys_dts_usec; /** * Packet priority @@ -68,7 +69,7 @@ struct encoder_packet { * This is generally use by video encoders to specify the priority * of the packet. */ - int priority; + int priority; /** * Dropped packet priority @@ -76,28 +77,28 @@ struct encoder_packet { * If this packet needs to be dropped, the next packet must be of this * priority or higher to continue transmission. */ - int drop_priority; + int drop_priority; /** Audio track index (used with outputs) */ - size_t track_idx; + size_t track_idx; /** Encoder from which the track originated from */ - obs_encoder_t *encoder; + obs_encoder_t *encoder; }; /** Encoder input frame */ struct encoder_frame { /** Data for the frame/audio */ - uint8_t *data[MAX_AV_PLANES]; + uint8_t *data[MAX_AV_PLANES]; /** size of each plane */ - uint32_t linesize[MAX_AV_PLANES]; + uint32_t linesize[MAX_AV_PLANES]; /** Number of frames (audio only) */ - uint32_t frames; + uint32_t frames; /** Presentation timestamp */ - int64_t pts; + int64_t pts; }; /** @@ -161,7 +162,7 @@ struct obs_encoder_info { * @return true if successful, false otherwise. */ bool (*encode)(void *data, struct encoder_frame *frame, - struct encoder_packet *packet, bool *received_packet); + struct encoder_packet *packet, bool *received_packet); /** Audio encoder only: Returns the frame size for this encoder */ size_t (*get_frame_size)(void *data); @@ -238,6 +239,9 @@ struct obs_encoder_info { /** * Gets the default settings for this encoder + * + * If get_defaults is also defined both will be called, and the first + * call will be to get_defaults, then to get_defaults2. * * @param[out] settings Data to assign default settings to * @param[in] typedata Type Data @@ -254,12 +258,13 @@ struct obs_encoder_info { obs_properties_t *(*get_properties2)(void *data, void *type_data); bool (*encode_texture)(void *data, uint32_t handle, int64_t pts, - uint64_t lock_key, uint64_t *next_key, - struct encoder_packet *packet, bool *received_packet); + uint64_t lock_key, uint64_t *next_key, + struct encoder_packet *packet, + bool *received_packet); }; EXPORT void obs_register_encoder_s(const struct obs_encoder_info *info, - size_t size); + size_t size); /** * Register an encoder definition to the current obs context. This should be diff --git a/libobs/obs-ffmpeg-compat.h b/libobs/obs-ffmpeg-compat.h index 0f3f265..c4e23b9 100644 --- a/libobs/obs-ffmpeg-compat.h +++ b/libobs/obs-ffmpeg-compat.h @@ -6,18 +6,20 @@ * a is the major version * b and c the minor and micro versions of libav * d and e the minor and micro versions of FFmpeg */ -#define LIBAVCODEC_VERSION_CHECK( a, b, c, d, e ) \ - ( (LIBAVCODEC_VERSION_MICRO < 100 && LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( a, b, c ) ) || \ - (LIBAVCODEC_VERSION_MICRO >= 100 && LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( a, d, e ) ) ) +#define LIBAVCODEC_VERSION_CHECK(a, b, c, d, e) \ + ((LIBAVCODEC_VERSION_MICRO < 100 && \ + LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(a, b, c)) || \ + (LIBAVCODEC_VERSION_MICRO >= 100 && \ + LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(a, d, e))) #if !LIBAVCODEC_VERSION_CHECK(54, 28, 0, 59, 100) -# define avcodec_free_frame av_freep +#define avcodec_free_frame av_freep #endif #if LIBAVCODEC_VERSION_INT < 0x371c01 -# define av_frame_alloc avcodec_alloc_frame -# define av_frame_unref avcodec_get_frame_defaults -# define av_frame_free avcodec_free_frame +#define av_frame_alloc avcodec_alloc_frame +#define av_frame_unref avcodec_get_frame_defaults +#define av_frame_free avcodec_free_frame #endif #if LIBAVCODEC_VERSION_MAJOR >= 58 diff --git a/libobs/obs-hotkey-name-map.c b/libobs/obs-hotkey-name-map.c index 5dd12df..a7e0683 100644 --- a/libobs/obs-hotkey-name-map.c +++ b/libobs/obs-hotkey-name-map.c @@ -69,7 +69,6 @@ struct obs_hotkey_name_map_edge { struct obs_hotkey_name_map_node *node; }; - static inline obs_hotkey_name_map_node_t *new_node(void) { return bzalloc(sizeof(obs_hotkey_name_map_node_t)); @@ -88,12 +87,12 @@ static inline obs_hotkey_name_map_node_t *new_leaf(void) static inline char *get_prefix(obs_hotkey_name_map_edge_t *e) { - return e->prefix_len >= NAME_MAP_COMPRESS_LENGTH ? - e->prefix : e->compressed_prefix; + return e->prefix_len >= NAME_MAP_COMPRESS_LENGTH ? e->prefix + : e->compressed_prefix; } static void set_prefix(obs_hotkey_name_map_edge_t *e, const char *prefix, - size_t l) + size_t l) { assert(e->prefix_len == 0); @@ -105,7 +104,7 @@ static void set_prefix(obs_hotkey_name_map_edge_t *e, const char *prefix, } static obs_hotkey_name_map_edge_t *add_leaf(obs_hotkey_name_map_node_t *node, - const char *key, size_t l, int v) + const char *key, size_t l, int v) { obs_hotkey_name_map_edge_t *e = da_push_back_new(node->children); @@ -135,19 +134,19 @@ static void shrink_prefix(obs_hotkey_name_map_edge_t *e, size_t l) } static void connect(obs_hotkey_name_map_edge_t *e, - obs_hotkey_name_map_node_t *n) + obs_hotkey_name_map_node_t *n) { e->node = n; } static void reduce_edge(obs_hotkey_name_map_edge_t *e, const char *key, - size_t l, int v) + size_t l, int v) { const char *str = get_prefix(e), *str_ = key; size_t common_length = 0; while (*str == *str_) { common_length += 1; - str += 1; + str += 1; str_ += 1; } @@ -171,8 +170,8 @@ enum obs_hotkey_name_map_edge_compare_result { RES_PREFIX_MATCHES, }; -static enum obs_hotkey_name_map_edge_compare_result compare_prefix( - obs_hotkey_name_map_edge_t *edge, const char *key, size_t l) +static enum obs_hotkey_name_map_edge_compare_result +compare_prefix(obs_hotkey_name_map_edge_t *edge, const char *key, size_t l) { uint8_t pref_len = edge->prefix_len; const char *str = get_prefix(edge); @@ -182,7 +181,6 @@ static enum obs_hotkey_name_map_edge_compare_result compare_prefix( if (str[i] != key[i]) break; - if (i != 0 && pref_len == i) return l == i ? RES_MATCHES : RES_PREFIX_MATCHES; if (i != 0) @@ -191,8 +189,8 @@ static enum obs_hotkey_name_map_edge_compare_result compare_prefix( } static void insert(obs_hotkey_name_map_edge_t *edge, - obs_hotkey_name_map_node_t *node, - const char *key, size_t l, int v) + obs_hotkey_name_map_node_t *node, const char *key, size_t l, + int v) { if (node->is_leaf && l > 0) { obs_hotkey_name_map_node_t *new_node_ = new_node(); @@ -220,7 +218,7 @@ static void insert(obs_hotkey_name_map_edge_t *edge, case RES_MATCHES: case RES_PREFIX_MATCHES: insert(e, e->node, key + e->prefix_len, - l - e->prefix_len, v); + l - e->prefix_len, v); return; case RES_COMMON_PREFIX: @@ -233,7 +231,7 @@ static void insert(obs_hotkey_name_map_edge_t *edge, } static void obs_hotkey_name_map_insert(obs_hotkey_name_map_t *trie, - const char *key, int v) + const char *key, int v) { if (!trie || !key) return; @@ -242,7 +240,7 @@ static void obs_hotkey_name_map_insert(obs_hotkey_name_map_t *trie, } static bool obs_hotkey_name_map_lookup(obs_hotkey_name_map_t *trie, - const char *key, int *v) + const char *key, int *v) { if (!trie || !key) return false; @@ -276,14 +274,16 @@ static bool obs_hotkey_name_map_lookup(obs_hotkey_name_map_t *trie, if (n->children.array[j].prefix_len) continue; - if (v) *v = - n->children.array[j].node->val; + if (v) + *v = n->children.array[j] + .node->val; return true; } return false; } - if (v) *v = n->val; + if (v) + *v = n->val; return true; } } @@ -310,7 +310,7 @@ static void show_node(obs_hotkey_name_map_node_t *node, int in) obs_hotkey_name_map_edge_t *e = &node->children.array[i]; printf("%s", get_prefix(e)); - show_node(e->node, in+2); + show_node(e->node, in + 2); } } @@ -319,17 +319,19 @@ void trie_print_size(obs_hotkey_name_map_t *trie) show_node(&trie->root, 0); } -static const char* obs_key_names[] = { +static const char *obs_key_names[] = { #define OBS_HOTKEY(x) #x, #include "obs-hotkeys.h" #undef OBS_HOTKEY }; -const char* obs_key_to_name(obs_key_t key) +const char *obs_key_to_name(obs_key_t key) { if (key >= OBS_KEY_LAST_VALUE) { - blog(LOG_ERROR, "obs-hotkey.c: queried unknown key " - "with code %d", (int)key); + blog(LOG_ERROR, + "obs-hotkey.c: queried unknown key " + "with code %d", + (int)key); return ""; } @@ -338,7 +340,9 @@ const char* obs_key_to_name(obs_key_t key) static obs_key_t obs_key_from_name_fallback(const char *name) { -#define OBS_HOTKEY(x) if (strcmp(#x, name) == 0) return x; +#define OBS_HOTKEY(x) \ + if (strcmp(#x, name) == 0) \ + return x; #include "obs-hotkeys.h" #undef OBS_HOTKEY return OBS_KEY_NONE; @@ -397,7 +401,8 @@ static void free_node(obs_hotkey_name_map_node_t *node, bool release) da_free(node->children); } - if (release && !node->is_leaf) bfree(node); + if (release && !node->is_leaf) + bfree(node); } void obs_hotkey_name_map_free(void) diff --git a/libobs/obs-hotkey.c b/libobs/obs-hotkey.c index d31076e..c251dca 100644 --- a/libobs/obs-hotkey.c +++ b/libobs/obs-hotkey.c @@ -63,8 +63,8 @@ obs_hotkey_id obs_hotkey_get_pair_partner_id(const obs_hotkey_t *key) return key->pair_partner_id; } -obs_key_combination_t obs_hotkey_binding_get_key_combination( - obs_hotkey_binding_t *binding) +obs_key_combination_t +obs_hotkey_binding_get_key_combination(obs_hotkey_binding_t *binding) { return binding->key; } @@ -105,8 +105,8 @@ void obs_hotkey_set_description(obs_hotkey_id id, const char *desc) } static inline bool find_pair_id(obs_hotkey_pair_id id, size_t *idx); -void obs_hotkey_pair_set_names(obs_hotkey_pair_id id, - const char *name0, const char *name1) +void obs_hotkey_pair_set_names(obs_hotkey_pair_id id, const char *name0, + const char *name1) { size_t idx; obs_hotkey_pair_t pair; @@ -120,8 +120,8 @@ void obs_hotkey_pair_set_names(obs_hotkey_pair_id id, obs_hotkey_set_name(pair.id[1], name1); } -void obs_hotkey_pair_set_descriptions(obs_hotkey_pair_id id, - const char *desc0, const char *desc1) +void obs_hotkey_pair_set_descriptions(obs_hotkey_pair_id id, const char *desc0, + const char *desc1) { size_t idx; obs_hotkey_pair_t pair; @@ -150,31 +150,31 @@ static inline void fixup_pointers(void); static inline void load_bindings(obs_hotkey_t *hotkey, obs_data_array_t *data); static inline void context_add_hotkey(struct obs_context_data *context, - obs_hotkey_id id) + obs_hotkey_id id) { da_push_back(context->hotkeys, &id); } -static inline obs_hotkey_id obs_hotkey_register_internal( - obs_hotkey_registerer_t type, void *registerer, - struct obs_context_data *context, - const char *name, const char *description, - obs_hotkey_func func, void *data) +static inline obs_hotkey_id +obs_hotkey_register_internal(obs_hotkey_registerer_t type, void *registerer, + struct obs_context_data *context, const char *name, + const char *description, obs_hotkey_func func, + void *data) { if ((obs->hotkeys.next_id + 1) == OBS_INVALID_HOTKEY_ID) blog(LOG_WARNING, "obs-hotkey: Available hotkey ids exhausted"); obs_hotkey_t *base_addr = obs->hotkeys.hotkeys.array; - obs_hotkey_id result = obs->hotkeys.next_id++; - obs_hotkey_t *hotkey = da_push_back_new(obs->hotkeys.hotkeys); + obs_hotkey_id result = obs->hotkeys.next_id++; + obs_hotkey_t *hotkey = da_push_back_new(obs->hotkeys.hotkeys); - hotkey->id = result; - hotkey->name = bstrdup(name); - hotkey->description = bstrdup(description); - hotkey->func = func; - hotkey->data = data; + hotkey->id = result; + hotkey->name = bstrdup(name); + hotkey->description = bstrdup(description); + hotkey->func = func; + hotkey->data = data; hotkey->registerer_type = type; - hotkey->registerer = registerer; + hotkey->registerer = registerer; hotkey->pair_partner_id = OBS_INVALID_HOTKEY_PAIR_ID; if (context) { @@ -195,81 +195,81 @@ static inline obs_hotkey_id obs_hotkey_register_internal( } obs_hotkey_id obs_hotkey_register_frontend(const char *name, - const char *description, obs_hotkey_func func, void *data) + const char *description, + obs_hotkey_func func, void *data) { if (!lock()) return OBS_INVALID_HOTKEY_ID; - obs_hotkey_id id = obs_hotkey_register_internal( - OBS_HOTKEY_REGISTERER_FRONTEND, NULL, NULL, - name, description, func, data); + obs_hotkey_id id = obs_hotkey_register_internal( + OBS_HOTKEY_REGISTERER_FRONTEND, NULL, NULL, name, description, + func, data); unlock(); return id; } obs_hotkey_id obs_hotkey_register_encoder(obs_encoder_t *encoder, - const char *name, const char *description, - obs_hotkey_func func, void *data) + const char *name, + const char *description, + obs_hotkey_func func, void *data) { if (!encoder || !lock()) return OBS_INVALID_HOTKEY_ID; obs_hotkey_id id = obs_hotkey_register_internal( - OBS_HOTKEY_REGISTERER_ENCODER, - obs_encoder_get_weak_encoder(encoder), - &encoder->context, name, description, - func, data); + OBS_HOTKEY_REGISTERER_ENCODER, + obs_encoder_get_weak_encoder(encoder), &encoder->context, name, + description, func, data); unlock(); return id; } -obs_hotkey_id obs_hotkey_register_output(obs_output_t *output, - const char *name, const char *description, - obs_hotkey_func func, void *data) +obs_hotkey_id obs_hotkey_register_output(obs_output_t *output, const char *name, + const char *description, + obs_hotkey_func func, void *data) { if (!output || !lock()) return OBS_INVALID_HOTKEY_ID; obs_hotkey_id id = obs_hotkey_register_internal( - OBS_HOTKEY_REGISTERER_OUTPUT, - obs_output_get_weak_output(output), - &output->context, name, description, - func, data); + OBS_HOTKEY_REGISTERER_OUTPUT, + obs_output_get_weak_output(output), &output->context, name, + description, func, data); unlock(); return id; } obs_hotkey_id obs_hotkey_register_service(obs_service_t *service, - const char *name, const char *description, - obs_hotkey_func func, void *data) + const char *name, + const char *description, + obs_hotkey_func func, void *data) { if (!service || !lock()) return OBS_INVALID_HOTKEY_ID; obs_hotkey_id id = obs_hotkey_register_internal( - OBS_HOTKEY_REGISTERER_SERVICE, - obs_service_get_weak_service(service), - &service->context, name, description, - func, data); + OBS_HOTKEY_REGISTERER_SERVICE, + obs_service_get_weak_service(service), &service->context, name, + description, func, data); unlock(); return id; } obs_hotkey_id obs_hotkey_register_source(obs_source_t *source, const char *name, - const char *description, obs_hotkey_func func, void *data) + const char *description, + obs_hotkey_func func, void *data) { if (!source || source->context.private || !lock()) return OBS_INVALID_HOTKEY_ID; obs_hotkey_id id = obs_hotkey_register_internal( - OBS_HOTKEY_REGISTERER_SOURCE, - obs_source_get_weak_source(source), - &source->context, name, description, - func, data); + OBS_HOTKEY_REGISTERER_SOURCE, + obs_source_get_weak_source(source), &source->context, name, + description, func, data); unlock(); return id; @@ -278,16 +278,16 @@ obs_hotkey_id obs_hotkey_register_source(obs_source_t *source, const char *name, static inline void fixup_pair_pointers(void); static obs_hotkey_pair_t *create_hotkey_pair(struct obs_context_data *context, - obs_hotkey_active_func func0, obs_hotkey_active_func func1, - void *data0, void *data1) + obs_hotkey_active_func func0, + obs_hotkey_active_func func1, + void *data0, void *data1) { if ((obs->hotkeys.next_pair_id + 1) == OBS_INVALID_HOTKEY_PAIR_ID) blog(LOG_WARNING, "obs-hotkey: Available hotkey pair ids " - "exhausted"); + "exhausted"); obs_hotkey_pair_t *base_addr = obs->hotkeys.hotkey_pairs.array; - obs_hotkey_pair_t *pair = - da_push_back_new(obs->hotkeys.hotkey_pairs); + obs_hotkey_pair_t *pair = da_push_back_new(obs->hotkeys.hotkey_pairs); pair->pair_id = obs->hotkeys.next_pair_id++; pair->func[0] = func0; @@ -306,8 +306,8 @@ static obs_hotkey_pair_t *create_hotkey_pair(struct obs_context_data *context, return pair; } -static void obs_hotkey_pair_first_func(void *data, - obs_hotkey_id id, obs_hotkey_t *hotkey, bool pressed) +static void obs_hotkey_pair_first_func(void *data, obs_hotkey_id id, + obs_hotkey_t *hotkey, bool pressed) { UNUSED_PARAMETER(id); @@ -321,8 +321,8 @@ static void obs_hotkey_pair_first_func(void *data, pair->pressed0 = pressed; } -static void obs_hotkey_pair_second_func(void *data, - obs_hotkey_id id, obs_hotkey_t *hotkey, bool pressed) +static void obs_hotkey_pair_second_func(void *data, obs_hotkey_id id, + obs_hotkey_t *hotkey, bool pressed) { UNUSED_PARAMETER(id); @@ -338,30 +338,28 @@ static void obs_hotkey_pair_second_func(void *data, static inline bool find_id(obs_hotkey_id id, size_t *idx); static obs_hotkey_pair_id register_hotkey_pair_internal( - obs_hotkey_registerer_t type, void *registerer, - void *(*weak_ref)(void*), - struct obs_context_data *context, - const char *name0, const char *description0, - const char *name1, const char *description1, - obs_hotkey_active_func func0, obs_hotkey_active_func func1, - void *data0, void *data1) + obs_hotkey_registerer_t type, void *registerer, + void *(*weak_ref)(void *), struct obs_context_data *context, + const char *name0, const char *description0, const char *name1, + const char *description1, obs_hotkey_active_func func0, + obs_hotkey_active_func func1, void *data0, void *data1) { if (!lock()) return OBS_INVALID_HOTKEY_PAIR_ID; - obs_hotkey_pair_t *pair = create_hotkey_pair(context, - func0, func1, data0, data1); + obs_hotkey_pair_t *pair = + create_hotkey_pair(context, func0, func1, data0, data1); - pair->id[0] = obs_hotkey_register_internal( - type, weak_ref(registerer), context, - name0, description0, - obs_hotkey_pair_first_func, pair); + pair->id[0] = obs_hotkey_register_internal(type, weak_ref(registerer), + context, name0, description0, + obs_hotkey_pair_first_func, + pair); - pair->id[1] = obs_hotkey_register_internal( - type, weak_ref(registerer), context, - name1, description1, - obs_hotkey_pair_second_func, pair); + pair->id[1] = obs_hotkey_register_internal(type, weak_ref(registerer), + context, name1, description1, + obs_hotkey_pair_second_func, + pair); size_t idx; if (find_id(pair->id[0], &idx)) @@ -382,15 +380,14 @@ static inline void *obs_id_(void *id_) } obs_hotkey_pair_id obs_hotkey_pair_register_frontend( - const char *name0, const char *description0, - const char *name1, const char *description1, - obs_hotkey_active_func func0, obs_hotkey_active_func func1, - void *data0, void *data1) + const char *name0, const char *description0, const char *name1, + const char *description1, obs_hotkey_active_func func0, + obs_hotkey_active_func func1, void *data0, void *data1) { - return register_hotkey_pair_internal( - OBS_HOTKEY_REGISTERER_FRONTEND, NULL, obs_id_, NULL, - name0, description0, name1, description1, - func0, func1, data0, data1); + return register_hotkey_pair_internal(OBS_HOTKEY_REGISTERER_FRONTEND, + NULL, obs_id_, NULL, name0, + description0, name1, description1, + func0, func1, data0, data1); } static inline void *weak_encoder_ref(void *ref) @@ -398,19 +395,19 @@ static inline void *weak_encoder_ref(void *ref) return obs_encoder_get_weak_encoder(ref); } -obs_hotkey_pair_id obs_hotkey_pair_register_encoder(obs_encoder_t *encoder, - const char *name0, const char *description0, - const char *name1, const char *description1, - obs_hotkey_active_func func0, obs_hotkey_active_func func1, - void *data0, void *data1) +obs_hotkey_pair_id obs_hotkey_pair_register_encoder( + obs_encoder_t *encoder, const char *name0, const char *description0, + const char *name1, const char *description1, + obs_hotkey_active_func func0, obs_hotkey_active_func func1, void *data0, + void *data1) { - if (!encoder) return OBS_INVALID_HOTKEY_PAIR_ID; - return register_hotkey_pair_internal( - OBS_HOTKEY_REGISTERER_ENCODER, encoder, - weak_encoder_ref, - &encoder->context, - name0, description0, name1, description1, - func0, func1, data0, data1); + if (!encoder) + return OBS_INVALID_HOTKEY_PAIR_ID; + return register_hotkey_pair_internal(OBS_HOTKEY_REGISTERER_ENCODER, + encoder, weak_encoder_ref, + &encoder->context, name0, + description0, name1, description1, + func0, func1, data0, data1); } static inline void *weak_output_ref(void *ref) @@ -418,19 +415,19 @@ static inline void *weak_output_ref(void *ref) return obs_output_get_weak_output(ref); } -obs_hotkey_pair_id obs_hotkey_pair_register_output(obs_output_t *output, - const char *name0, const char *description0, - const char *name1, const char *description1, - obs_hotkey_active_func func0, obs_hotkey_active_func func1, - void *data0, void *data1) +obs_hotkey_pair_id obs_hotkey_pair_register_output( + obs_output_t *output, const char *name0, const char *description0, + const char *name1, const char *description1, + obs_hotkey_active_func func0, obs_hotkey_active_func func1, void *data0, + void *data1) { - if (!output) return OBS_INVALID_HOTKEY_PAIR_ID; - return register_hotkey_pair_internal( - OBS_HOTKEY_REGISTERER_OUTPUT, output, - weak_output_ref, - &output->context, - name0, description0, name1, description1, - func0, func1, data0, data1); + if (!output) + return OBS_INVALID_HOTKEY_PAIR_ID; + return register_hotkey_pair_internal(OBS_HOTKEY_REGISTERER_OUTPUT, + output, weak_output_ref, + &output->context, name0, + description0, name1, description1, + func0, func1, data0, data1); } static inline void *weak_service_ref(void *ref) @@ -438,19 +435,19 @@ static inline void *weak_service_ref(void *ref) return obs_service_get_weak_service(ref); } -obs_hotkey_pair_id obs_hotkey_pair_register_service(obs_service_t *service, - const char *name0, const char *description0, - const char *name1, const char *description1, - obs_hotkey_active_func func0, obs_hotkey_active_func func1, - void *data0, void *data1) +obs_hotkey_pair_id obs_hotkey_pair_register_service( + obs_service_t *service, const char *name0, const char *description0, + const char *name1, const char *description1, + obs_hotkey_active_func func0, obs_hotkey_active_func func1, void *data0, + void *data1) { - if (!service) return OBS_INVALID_HOTKEY_PAIR_ID; - return register_hotkey_pair_internal( - OBS_HOTKEY_REGISTERER_SERVICE, service, - weak_service_ref, - &service->context, - name0, description0, name1, description1, - func0, func1, data0, data1); + if (!service) + return OBS_INVALID_HOTKEY_PAIR_ID; + return register_hotkey_pair_internal(OBS_HOTKEY_REGISTERER_SERVICE, + service, weak_service_ref, + &service->context, name0, + description0, name1, description1, + func0, func1, data0, data1); } static inline void *weak_source_ref(void *ref) @@ -458,27 +455,27 @@ static inline void *weak_source_ref(void *ref) return obs_source_get_weak_source(ref); } -obs_hotkey_pair_id obs_hotkey_pair_register_source(obs_source_t *source, - const char *name0, const char *description0, - const char *name1, const char *description1, - obs_hotkey_active_func func0, obs_hotkey_active_func func1, - void *data0, void *data1) +obs_hotkey_pair_id obs_hotkey_pair_register_source( + obs_source_t *source, const char *name0, const char *description0, + const char *name1, const char *description1, + obs_hotkey_active_func func0, obs_hotkey_active_func func1, void *data0, + void *data1) { - if (!source) return OBS_INVALID_HOTKEY_PAIR_ID; - return register_hotkey_pair_internal( - OBS_HOTKEY_REGISTERER_SOURCE, source, - weak_source_ref, - &source->context, - name0, description0, name1, description1, - func0, func1, data0, data1); + if (!source) + return OBS_INVALID_HOTKEY_PAIR_ID; + return register_hotkey_pair_internal(OBS_HOTKEY_REGISTERER_SOURCE, + source, weak_source_ref, + &source->context, name0, + description0, name1, description1, + func0, func1, data0, data1); } -typedef bool (*obs_hotkey_internal_enum_func)(void *data, - size_t idx, obs_hotkey_t *hotkey); +typedef bool (*obs_hotkey_internal_enum_func)(void *data, size_t idx, + obs_hotkey_t *hotkey); static inline void enum_hotkeys(obs_hotkey_internal_enum_func func, void *data) { - const size_t num = obs->hotkeys.hotkeys.num; + const size_t num = obs->hotkeys.hotkeys.num; obs_hotkey_t *array = obs->hotkeys.hotkeys.array; for (size_t i = 0; i < num; i++) { if (!func(data, i, &array[i])) @@ -487,12 +484,13 @@ static inline void enum_hotkeys(obs_hotkey_internal_enum_func func, void *data) } typedef bool (*obs_hotkey_pair_internal_enum_func)(size_t idx, - obs_hotkey_pair_t *pair, void *data); + obs_hotkey_pair_t *pair, + void *data); static inline void enum_hotkey_pairs(obs_hotkey_pair_internal_enum_func func, - void *data) + void *data) { - const size_t num = obs->hotkeys.hotkey_pairs.num; + const size_t num = obs->hotkeys.hotkey_pairs.num; obs_hotkey_pair_t *array = obs->hotkeys.hotkey_pairs.array; for (size_t i = 0; i < num; i++) { if (!func(i, &array[i], data)) @@ -500,13 +498,13 @@ static inline void enum_hotkey_pairs(obs_hotkey_pair_internal_enum_func func, } } -typedef bool (*obs_hotkey_binding_internal_enum_func)(void *data, - size_t idx, obs_hotkey_binding_t *binding); +typedef bool (*obs_hotkey_binding_internal_enum_func)( + void *data, size_t idx, obs_hotkey_binding_t *binding); static inline void enum_bindings(obs_hotkey_binding_internal_enum_func func, - void *data) + void *data) { - const size_t num = obs->hotkeys.bindings.num; + const size_t num = obs->hotkeys.bindings.num; obs_hotkey_binding_t *array = obs->hotkeys.bindings.array; for (size_t i = 0; i < num; i++) { if (!func(data, i, &array[i])) @@ -516,8 +514,8 @@ static inline void enum_bindings(obs_hotkey_binding_internal_enum_func func, struct obs_hotkey_internal_find_forward { obs_hotkey_id id; - bool found; - size_t idx; + bool found; + size_t idx; }; static inline bool find_id_helper(void *data, size_t idx, obs_hotkey_t *hotkey) @@ -526,7 +524,7 @@ static inline bool find_id_helper(void *data, size_t idx, obs_hotkey_t *hotkey) if (hotkey->id != find->id) return true; - find->idx = idx; + find->idx = idx; find->found = true; return false; } @@ -539,8 +537,8 @@ static inline bool find_id(obs_hotkey_id id, size_t *idx) return find.found; } -static inline bool pointer_fixup_func(void *data, - size_t idx, obs_hotkey_binding_t *binding) +static inline bool pointer_fixup_func(void *data, size_t idx, + obs_hotkey_binding_t *binding) { UNUSED_PARAMETER(idx); UNUSED_PARAMETER(data); @@ -548,10 +546,10 @@ static inline bool pointer_fixup_func(void *data, size_t idx_; if (!find_id(binding->hotkey_id, &idx_)) { bcrash("obs-hotkey: Could not find hotkey id '%" PRIuMAX "' " - "for binding '%s' (modifiers 0x%x)", - (uintmax_t)binding->hotkey_id, - obs_key_to_name(binding->key.key), - binding->key.modifiers); + "for binding '%s' (modifiers 0x%x)", + (uintmax_t)binding->hotkey_id, + obs_key_to_name(binding->key.key), + binding->key.modifiers); binding->hotkey = NULL; return true; } @@ -568,18 +566,18 @@ static inline void fixup_pointers(void) struct obs_hotkey_internal_find_pair_forward { obs_hotkey_pair_id id; - bool found; - size_t idx; + bool found; + size_t idx; }; static inline bool find_pair_id_helper(size_t idx, obs_hotkey_pair_t *pair, - void *data) + void *data) { struct obs_hotkey_internal_find_pair_forward *find = data; if (pair->pair_id != find->id) return true; - find->idx = idx; + find->idx = idx; find->found = true; return false; } @@ -592,8 +590,8 @@ static inline bool find_pair_id(obs_hotkey_pair_id id, size_t *idx) return find.found; } -static inline bool pair_pointer_fixup_func(size_t idx, - obs_hotkey_pair_t *pair, void *data) +static inline bool pair_pointer_fixup_func(size_t idx, obs_hotkey_pair_t *pair, + void *data) { UNUSED_PARAMETER(idx); UNUSED_PARAMETER(data); @@ -613,9 +611,10 @@ static inline void fixup_pair_pointers(void) } static inline void enum_context_hotkeys(struct obs_context_data *context, - obs_hotkey_internal_enum_func func, void *data) + obs_hotkey_internal_enum_func func, + void *data) { - const size_t num = context->hotkeys.num; + const size_t num = context->hotkeys.num; const obs_hotkey_id *array = context->hotkeys.array; obs_hotkey_t *hotkey_array = obs->hotkeys.hotkeys.array; for (size_t i = 0; i < num; i++) { @@ -629,14 +628,14 @@ static inline void enum_context_hotkeys(struct obs_context_data *context, } static inline void load_modifier(uint32_t *modifiers, obs_data_t *data, - const char *name, uint32_t flag) + const char *name, uint32_t flag) { if (obs_data_get_bool(data, name)) *modifiers |= flag; } static inline void create_binding(obs_hotkey_t *hotkey, - obs_key_combination_t combo) + obs_key_combination_t combo) { obs_hotkey_binding_t *binding = da_push_back_new(obs->hotkeys.bindings); if (!binding) @@ -644,7 +643,7 @@ static inline void create_binding(obs_hotkey_t *hotkey, binding->key = combo; binding->hotkey_id = hotkey->id; - binding->hotkey = hotkey; + binding->hotkey = hotkey; } static inline void load_binding(obs_hotkey_t *hotkey, obs_data_t *data) @@ -660,8 +659,8 @@ static inline void load_binding(obs_hotkey_t *hotkey, obs_data_t *data) load_modifier(modifiers, data, "command", INTERACT_COMMAND_KEY); combo.key = obs_key_from_name(obs_data_get_string(data, "key")); - if (!modifiers && (combo.key == OBS_KEY_NONE || - combo.key >= OBS_KEY_LAST_VALUE)) + if (!modifiers && + (combo.key == OBS_KEY_NONE || combo.key >= OBS_KEY_LAST_VALUE)) return; create_binding(hotkey, combo); @@ -682,7 +681,7 @@ static inline void load_bindings(obs_hotkey_t *hotkey, obs_data_array_t *data) static inline void remove_bindings(obs_hotkey_id id); void obs_hotkey_load_bindings(obs_hotkey_id id, - obs_key_combination_t *combinations, size_t num) + obs_key_combination_t *combinations, size_t num) { size_t idx; @@ -714,8 +713,8 @@ void obs_hotkey_load(obs_hotkey_id id, obs_data_array_t *data) unlock(); } -static inline bool enum_load_bindings(void *data, - size_t idx, obs_hotkey_t *hotkey) +static inline bool enum_load_bindings(void *data, size_t idx, + obs_hotkey_t *hotkey) { UNUSED_PARAMETER(idx); @@ -773,7 +772,7 @@ void obs_hotkeys_load_source(obs_source_t *source, obs_data_t *hotkeys) } void obs_hotkey_pair_load(obs_hotkey_pair_id id, obs_data_array_t *data0, - obs_data_array_t *data1) + obs_data_array_t *data1) { if ((!data0 && !data1) || !lock()) return; @@ -798,7 +797,7 @@ unlock: } static inline void save_modifier(uint32_t modifiers, obs_data_t *data, - const char *name, uint32_t flag) + const char *name, uint32_t flag) { if ((modifiers & flag) == flag) obs_data_set_bool(data, name, true); @@ -806,11 +805,11 @@ static inline void save_modifier(uint32_t modifiers, obs_data_t *data, struct save_bindings_helper_t { obs_data_array_t *array; - obs_hotkey_t *hotkey; + obs_hotkey_t *hotkey; }; -static inline bool save_bindings_helper(void *data, - size_t idx, obs_hotkey_binding_t *binding) +static inline bool save_bindings_helper(void *data, size_t idx, + obs_hotkey_binding_t *binding) { UNUSED_PARAMETER(idx); struct save_bindings_helper_t *h = data; @@ -860,9 +859,8 @@ obs_data_array_t *obs_hotkey_save(obs_hotkey_id id) return result; } -void obs_hotkey_pair_save(obs_hotkey_pair_id id, - obs_data_array_t **p_data0, - obs_data_array_t **p_data1) +void obs_hotkey_pair_save(obs_hotkey_pair_id id, obs_data_array_t **p_data0, + obs_data_array_t **p_data1) { if ((!p_data0 && !p_data1) || !lock()) return; @@ -884,8 +882,8 @@ unlock: unlock(); } -static inline bool enum_save_hotkey(void *data, - size_t idx, obs_hotkey_t *hotkey) +static inline bool enum_save_hotkey(void *data, size_t idx, + obs_hotkey_t *hotkey) { UNUSED_PARAMETER(idx); @@ -963,14 +961,14 @@ struct binding_find_data { bool found; }; -static inline bool binding_finder(void *data, - size_t idx, obs_hotkey_binding_t *binding) +static inline bool binding_finder(void *data, size_t idx, + obs_hotkey_binding_t *binding) { struct binding_find_data *find = data; if (binding->hotkey_id != find->id) return true; - *find->idx = idx; + *find->idx = idx; find->found = true; return false; } @@ -1099,7 +1097,7 @@ static void context_release_hotkeys(struct obs_context_data *context) bool need_fixup = false; for (size_t i = 0; i < context->hotkeys.num; i++) need_fixup = unregister_hotkey(context->hotkeys.array[i]) || - need_fixup; + need_fixup; if (need_fixup) fixup_pointers(); @@ -1115,9 +1113,9 @@ static void context_release_hotkey_pairs(struct obs_context_data *context) bool need_fixup = false; for (size_t i = 0; i < context->hotkey_pairs.num; i++) - need_fixup = - unregister_hotkey_pair(context->hotkey_pairs.array[i]) - || need_fixup; + need_fixup = unregister_hotkey_pair( + context->hotkey_pairs.array[i]) || + need_fixup; if (need_fixup) fixup_pair_pointers(); @@ -1140,7 +1138,7 @@ void obs_hotkeys_context_release(struct obs_context_data *context) void obs_hotkeys_free(void) { - const size_t num = obs->hotkeys.hotkeys.num; + const size_t num = obs->hotkeys.hotkeys.num; obs_hotkey_t *hotkeys = obs->hotkeys.hotkeys.array; for (size_t i = 0; i < num; i++) { bfree(hotkeys[i].name); @@ -1162,7 +1160,7 @@ void obs_hotkeys_free(void) struct obs_hotkey_internal_enum_forward { obs_hotkey_enum_func func; - void *data; + void *data; }; static inline bool enum_hotkey(void *data, size_t idx, obs_hotkey_t *hotkey) @@ -1193,18 +1191,18 @@ void obs_enum_hotkey_bindings(obs_hotkey_binding_enum_func func, void *data) } static inline bool modifiers_match(obs_hotkey_binding_t *binding, - uint32_t modifiers_, bool strict_modifiers) + uint32_t modifiers_, bool strict_modifiers) { uint32_t modifiers = binding->key.modifiers; return !modifiers || - (!strict_modifiers && (modifiers & modifiers_) == modifiers) || - (strict_modifiers && modifiers == modifiers_); + (!strict_modifiers && (modifiers & modifiers_) == modifiers) || + (strict_modifiers && modifiers == modifiers_); } static inline bool is_pressed(obs_key_t key) { return obs_hotkeys_platform_is_pressed(obs->hotkeys.platform_context, - key); + key); } static inline void press_released_binding(obs_hotkey_binding_t *binding) @@ -1219,7 +1217,7 @@ static inline void press_released_binding(obs_hotkey_binding_t *binding) hotkey->func(hotkey->data, hotkey->id, hotkey, true); else if (obs->hotkeys.router_func) obs->hotkeys.router_func(obs->hotkeys.router_func_data, - hotkey->id, true); + hotkey->id, true); } static inline void release_pressed_binding(obs_hotkey_binding_t *binding) @@ -1234,16 +1232,16 @@ static inline void release_pressed_binding(obs_hotkey_binding_t *binding) hotkey->func(hotkey->data, hotkey->id, hotkey, false); else if (obs->hotkeys.router_func) obs->hotkeys.router_func(obs->hotkeys.router_func_data, - hotkey->id, false); + hotkey->id, false); } static inline void handle_binding(obs_hotkey_binding_t *binding, - uint32_t modifiers, bool no_press, bool strict_modifiers, - bool *pressed) + uint32_t modifiers, bool no_press, + bool strict_modifiers, bool *pressed) { - bool modifiers_match_ = modifiers_match(binding, modifiers, - strict_modifiers); - bool modifiers_only = binding->key.key == OBS_KEY_NONE; + bool modifiers_match_ = + modifiers_match(binding, modifiers, strict_modifiers); + bool modifiers_only = binding->key.key == OBS_KEY_NONE; if (!binding->key.modifiers) binding->modifiers_match = true; @@ -1258,7 +1256,7 @@ static inline void handle_binding(obs_hotkey_binding_t *binding, goto reset; if ((pressed && !*pressed) || - (!pressed && !is_pressed(binding->key.key))) + (!pressed && !is_pressed(binding->key.key))) goto reset; if (binding->pressed || no_press) @@ -1277,22 +1275,22 @@ reset: struct obs_hotkey_internal_inject { obs_key_combination_t hotkey; - bool pressed; - bool strict_modifiers; + bool pressed; + bool strict_modifiers; }; -static inline bool inject_hotkey(void *data, - size_t idx, obs_hotkey_binding_t *binding) +static inline bool inject_hotkey(void *data, size_t idx, + obs_hotkey_binding_t *binding) { UNUSED_PARAMETER(idx); struct obs_hotkey_internal_inject *event = data; if (modifiers_match(binding, event->hotkey.modifiers, - event->strict_modifiers)) { + event->strict_modifiers)) { bool pressed = binding->key.key == event->hotkey.key && - event->pressed; + event->pressed; handle_binding(binding, event->hotkey.modifiers, false, - event->strict_modifiers, &pressed); + event->strict_modifiers, &pressed); } return true; @@ -1305,7 +1303,8 @@ void obs_hotkey_inject_event(obs_key_combination_t hotkey, bool pressed) struct obs_hotkey_internal_inject event = { {hotkey.modifiers, hotkey.key}, - pressed, obs->hotkeys.strict_modifiers, + pressed, + obs->hotkeys.strict_modifiers, }; enum_bindings(inject_hotkey, &event); unlock(); @@ -1331,19 +1330,19 @@ void obs_hotkey_enable_strict_modifiers(bool enable) struct obs_query_hotkeys_helper { uint32_t modifiers; - bool no_press; - bool strict_modifiers; + bool no_press; + bool strict_modifiers; }; -static inline bool query_hotkey(void *data, - size_t idx, obs_hotkey_binding_t *binding) +static inline bool query_hotkey(void *data, size_t idx, + obs_hotkey_binding_t *binding) { UNUSED_PARAMETER(idx); struct obs_query_hotkeys_helper *param = - (struct obs_query_hotkeys_helper*)data; + (struct obs_query_hotkeys_helper *)data; handle_binding(binding, param->modifiers, param->no_press, - param->strict_modifiers, NULL); + param->strict_modifiers, NULL); return true; } @@ -1376,7 +1375,7 @@ void *obs_hotkey_thread(void *arg) const char *hotkey_thread_name = profile_store_name(obs_get_profiler_name_store(), - "obs_hotkey_thread(%g"NBSP"ms)", 25.); + "obs_hotkey_thread(%g" NBSP "ms)", 25.); profile_register_root(hotkey_thread_name, (uint64_t)25000000); while (os_event_timedwait(obs->hotkeys.stop_event, 25) == ETIMEDOUT) { @@ -1414,7 +1413,7 @@ unlock: } void obs_hotkey_set_callback_routing_func(obs_hotkey_callback_router_func func, - void *data) + void *data) { if (!lock()) return; @@ -1443,10 +1442,10 @@ static void obs_set_key_translation(obs_key_t key, const char *translation) } void obs_hotkeys_set_translations_s( - struct obs_hotkeys_translations *translations, size_t size) + struct obs_hotkeys_translations *translations, size_t size) { #define ADD_TRANSLATION(key_name, var_name) \ - if (t.var_name) \ + if (t.var_name) \ obs_set_key_translation(key_name, t.var_name); struct obs_hotkeys_translations t = {0}; @@ -1505,10 +1504,10 @@ void obs_hotkeys_set_translations_s( dstr_cat(&numpad, " %1"); } -#define ADD_NUMPAD_NUM(idx) \ - dstr_copy_dstr(&button, &numpad); \ - dstr_replace(&button, "%1", #idx); \ - obs_set_key_translation(OBS_KEY_NUM ## idx, button.array) +#define ADD_NUMPAD_NUM(idx) \ + dstr_copy_dstr(&button, &numpad); \ + dstr_replace(&button, "%1", #idx); \ + obs_set_key_translation(OBS_KEY_NUM##idx, button.array) ADD_NUMPAD_NUM(0); ADD_NUMPAD_NUM(1); @@ -1530,10 +1529,10 @@ void obs_hotkeys_set_translations_s( dstr_cat(&mouse, " %1"); } -#define ADD_MOUSE_NUM(idx) \ - dstr_copy_dstr(&button, &mouse); \ - dstr_replace(&button, "%1", #idx); \ - obs_set_key_translation(OBS_KEY_MOUSE ## idx, button.array) +#define ADD_MOUSE_NUM(idx) \ + dstr_copy_dstr(&button, &mouse); \ + dstr_replace(&button, "%1", #idx); \ + obs_set_key_translation(OBS_KEY_MOUSE##idx, button.array) ADD_MOUSE_NUM(1); ADD_MOUSE_NUM(2); @@ -1577,24 +1576,28 @@ const char *obs_get_hotkey_translation(obs_key_t key, const char *def) return NULL; } - return obs->hotkeys.translations[key] ? - obs->hotkeys.translations[key] : def; + return obs->hotkeys.translations[key] ? obs->hotkeys.translations[key] + : def; } void obs_hotkey_update_atomic(obs_hotkey_atomic_update_func func, void *data) { - if (!lock()) return; + if (!lock()) + return; func(data); unlock(); } -void obs_hotkeys_set_audio_hotkeys_translations( - const char *mute, const char *unmute, - const char *push_to_mute, const char *push_to_talk) +void obs_hotkeys_set_audio_hotkeys_translations(const char *mute, + const char *unmute, + const char *push_to_mute, + const char *push_to_talk) { -#define SET_T(n) bfree(obs->hotkeys.n); obs->hotkeys.n = bstrdup(n) +#define SET_T(n) \ + bfree(obs->hotkeys.n); \ + obs->hotkeys.n = bstrdup(n) SET_T(mute); SET_T(unmute); SET_T(push_to_mute); @@ -1602,10 +1605,11 @@ void obs_hotkeys_set_audio_hotkeys_translations( #undef SET_T } -void obs_hotkeys_set_sceneitem_hotkeys_translations( - const char *show, const char *hide) +void obs_hotkeys_set_sceneitem_hotkeys_translations(const char *show, + const char *hide) { -#define SET_T(n) bfree(obs->hotkeys.sceneitem_##n); \ +#define SET_T(n) \ + bfree(obs->hotkeys.sceneitem_##n); \ obs->hotkeys.sceneitem_##n = bstrdup(n) SET_T(show); SET_T(hide); diff --git a/libobs/obs-hotkey.h b/libobs/obs-hotkey.h index 74a047f..1477ae4 100644 --- a/libobs/obs-hotkey.h +++ b/libobs/obs-hotkey.h @@ -43,7 +43,7 @@ enum obs_key { typedef enum obs_key obs_key_t; struct obs_key_combination { - uint32_t modifiers; + uint32_t modifiers; obs_key_t key; }; typedef struct obs_key_combination obs_key_combination_t; @@ -65,27 +65,27 @@ typedef enum obs_hotkey_registerer_type obs_hotkey_registerer_t; EXPORT obs_hotkey_id obs_hotkey_get_id(const obs_hotkey_t *key); EXPORT const char *obs_hotkey_get_name(const obs_hotkey_t *key); EXPORT const char *obs_hotkey_get_description(const obs_hotkey_t *key); -EXPORT obs_hotkey_registerer_t obs_hotkey_get_registerer_type( - const obs_hotkey_t *key); +EXPORT obs_hotkey_registerer_t +obs_hotkey_get_registerer_type(const obs_hotkey_t *key); EXPORT void *obs_hotkey_get_registerer(const obs_hotkey_t *key); EXPORT obs_hotkey_id obs_hotkey_get_pair_partner_id(const obs_hotkey_t *key); - -EXPORT obs_key_combination_t obs_hotkey_binding_get_key_combination( - obs_hotkey_binding_t *binding); -EXPORT obs_hotkey_id obs_hotkey_binding_get_hotkey_id( - obs_hotkey_binding_t *binding); -EXPORT obs_hotkey_t *obs_hotkey_binding_get_hotkey( - obs_hotkey_binding_t *binding); +EXPORT obs_key_combination_t +obs_hotkey_binding_get_key_combination(obs_hotkey_binding_t *binding); +EXPORT obs_hotkey_id +obs_hotkey_binding_get_hotkey_id(obs_hotkey_binding_t *binding); +EXPORT obs_hotkey_t * +obs_hotkey_binding_get_hotkey(obs_hotkey_binding_t *binding); /* setter functions */ EXPORT void obs_hotkey_set_name(obs_hotkey_id id, const char *name); EXPORT void obs_hotkey_set_description(obs_hotkey_id id, const char *desc); -EXPORT void obs_hotkey_pair_set_names(obs_hotkey_pair_id id, - const char *name0, const char *name1); +EXPORT void obs_hotkey_pair_set_names(obs_hotkey_pair_id id, const char *name0, + const char *name1); EXPORT void obs_hotkey_pair_set_descriptions(obs_hotkey_pair_id id, - const char *desc0, const char *desc1); + const char *desc0, + const char *desc1); #ifndef SWIG struct obs_hotkeys_translations { @@ -134,81 +134,88 @@ struct obs_hotkeys_translations { * translations for these keys, it will use the operating system's translation * over these translations. If no translations are specified, it will use * the default English translations for that specific operating system. */ -EXPORT void obs_hotkeys_set_translations_s( - struct obs_hotkeys_translations *translations, size_t size); +EXPORT void +obs_hotkeys_set_translations_s(struct obs_hotkeys_translations *translations, + size_t size); #endif #define obs_hotkeys_set_translations(translations) \ - obs_hotkeys_set_translations_s(translations, \ - sizeof(struct obs_hotkeys_translations)) + obs_hotkeys_set_translations_s( \ + translations, sizeof(struct obs_hotkeys_translations)) -EXPORT void obs_hotkeys_set_audio_hotkeys_translations( - const char *mute, const char *unmute, - const char *push_to_mute, const char *push_to_talk); +EXPORT void +obs_hotkeys_set_audio_hotkeys_translations(const char *mute, const char *unmute, + const char *push_to_mute, + const char *push_to_talk); -EXPORT void obs_hotkeys_set_sceneitem_hotkeys_translations( - const char *show, const char *hide); +EXPORT void obs_hotkeys_set_sceneitem_hotkeys_translations(const char *show, + const char *hide); /* registering hotkeys (giving hotkeys a name and a function) */ -typedef void (*obs_hotkey_func)(void *data, - obs_hotkey_id id, obs_hotkey_t *hotkey, bool pressed); +typedef void (*obs_hotkey_func)(void *data, obs_hotkey_id id, + obs_hotkey_t *hotkey, bool pressed); EXPORT obs_hotkey_id obs_hotkey_register_frontend(const char *name, - const char *description, obs_hotkey_func func, void *data); + const char *description, + obs_hotkey_func func, + void *data); EXPORT obs_hotkey_id obs_hotkey_register_encoder(obs_encoder_t *encoder, - const char *name, const char *description, - obs_hotkey_func func, void *data); + const char *name, + const char *description, + obs_hotkey_func func, + void *data); EXPORT obs_hotkey_id obs_hotkey_register_output(obs_output_t *output, - const char *name, const char *description, - obs_hotkey_func func, void *data); + const char *name, + const char *description, + obs_hotkey_func func, + void *data); EXPORT obs_hotkey_id obs_hotkey_register_service(obs_service_t *service, - const char *name, const char *description, - obs_hotkey_func func, void *data); + const char *name, + const char *description, + obs_hotkey_func func, + void *data); EXPORT obs_hotkey_id obs_hotkey_register_source(obs_source_t *source, - const char *name, const char *description, - obs_hotkey_func func, void *data); + const char *name, + const char *description, + obs_hotkey_func func, + void *data); -typedef bool (*obs_hotkey_active_func)(void *data, - obs_hotkey_pair_id id, obs_hotkey_t *hotkey, bool pressed); +typedef bool (*obs_hotkey_active_func)(void *data, obs_hotkey_pair_id id, + obs_hotkey_t *hotkey, bool pressed); EXPORT obs_hotkey_pair_id obs_hotkey_pair_register_frontend( - const char *name0, const char *description0, - const char *name1, const char *description1, - obs_hotkey_active_func func0, obs_hotkey_active_func func1, - void *data0, void *data1); + const char *name0, const char *description0, const char *name1, + const char *description1, obs_hotkey_active_func func0, + obs_hotkey_active_func func1, void *data0, void *data1); EXPORT obs_hotkey_pair_id obs_hotkey_pair_register_encoder( - obs_encoder_t *encoder, - const char *name0, const char *description0, - const char *name1, const char *description1, - obs_hotkey_active_func func0, obs_hotkey_active_func func1, - void *data0, void *data1); + obs_encoder_t *encoder, const char *name0, const char *description0, + const char *name1, const char *description1, + obs_hotkey_active_func func0, obs_hotkey_active_func func1, void *data0, + void *data1); EXPORT obs_hotkey_pair_id obs_hotkey_pair_register_output( - obs_output_t *output, - const char *name0, const char *description0, - const char *name1, const char *description1, - obs_hotkey_active_func func0, obs_hotkey_active_func func1, - void *data0, void *data1); + obs_output_t *output, const char *name0, const char *description0, + const char *name1, const char *description1, + obs_hotkey_active_func func0, obs_hotkey_active_func func1, void *data0, + void *data1); EXPORT obs_hotkey_pair_id obs_hotkey_pair_register_service( - obs_service_t *service, - const char *name0, const char *description0, - const char *name1, const char *description1, - obs_hotkey_active_func func0, obs_hotkey_active_func func1, - void *data0, void *data1); + obs_service_t *service, const char *name0, const char *description0, + const char *name1, const char *description1, + obs_hotkey_active_func func0, obs_hotkey_active_func func1, void *data0, + void *data1); EXPORT obs_hotkey_pair_id obs_hotkey_pair_register_source( - obs_source_t *source, - const char *name0, const char *description0, - const char *name1, const char *description1, - obs_hotkey_active_func func0, obs_hotkey_active_func func1, - void *data0, void *data1); + obs_source_t *source, const char *name0, const char *description0, + const char *name1, const char *description1, + obs_hotkey_active_func func0, obs_hotkey_active_func func1, void *data0, + void *data1); EXPORT void obs_hotkey_unregister(obs_hotkey_id id); @@ -217,29 +224,29 @@ EXPORT void obs_hotkey_pair_unregister(obs_hotkey_pair_id id); /* loading hotkeys (associating a hotkey with a physical key and modifiers) */ EXPORT void obs_hotkey_load_bindings(obs_hotkey_id id, - obs_key_combination_t *combinations, size_t num); + obs_key_combination_t *combinations, + size_t num); EXPORT void obs_hotkey_load(obs_hotkey_id id, obs_data_array_t *data); EXPORT void obs_hotkeys_load_encoder(obs_encoder_t *encoder, - obs_data_t *hotkeys); + obs_data_t *hotkeys); EXPORT void obs_hotkeys_load_output(obs_output_t *output, obs_data_t *hotkeys); EXPORT void obs_hotkeys_load_service(obs_service_t *service, - obs_data_t *hotkeys); + obs_data_t *hotkeys); EXPORT void obs_hotkeys_load_source(obs_source_t *source, obs_data_t *hotkeys); EXPORT void obs_hotkey_pair_load(obs_hotkey_pair_id id, obs_data_array_t *data0, - obs_data_array_t *data1); - + obs_data_array_t *data1); EXPORT obs_data_array_t *obs_hotkey_save(obs_hotkey_id id); EXPORT void obs_hotkey_pair_save(obs_hotkey_pair_id id, - obs_data_array_t **p_data0, - obs_data_array_t **p_data1); + obs_data_array_t **p_data0, + obs_data_array_t **p_data1); EXPORT obs_data_t *obs_hotkeys_save_encoder(obs_encoder_t *encoder); @@ -251,18 +258,18 @@ EXPORT obs_data_t *obs_hotkeys_save_source(obs_source_t *source); /* enumerating hotkeys */ -typedef bool (*obs_hotkey_enum_func)(void *data, - obs_hotkey_id id, obs_hotkey_t *key); +typedef bool (*obs_hotkey_enum_func)(void *data, obs_hotkey_id id, + obs_hotkey_t *key); EXPORT void obs_enum_hotkeys(obs_hotkey_enum_func func, void *data); /* enumerating bindings */ -typedef bool (*obs_hotkey_binding_enum_func)(void *data, - size_t idx, obs_hotkey_binding_t* binding); +typedef bool (*obs_hotkey_binding_enum_func)(void *data, size_t idx, + obs_hotkey_binding_t *binding); EXPORT void obs_enum_hotkey_bindings(obs_hotkey_binding_enum_func func, - void *data); + void *data); /* hotkey event control */ @@ -274,11 +281,12 @@ EXPORT void obs_hotkey_enable_strict_modifiers(bool enable); /* hotkey callback routing (trigger callbacks through e.g. a UI thread) */ -typedef void (*obs_hotkey_callback_router_func)(void *data, - obs_hotkey_id id, bool pressed); +typedef void (*obs_hotkey_callback_router_func)(void *data, obs_hotkey_id id, + bool pressed); -EXPORT void obs_hotkey_set_callback_routing_func(obs_hotkey_callback_router_func - func, void *data); +EXPORT void +obs_hotkey_set_callback_routing_func(obs_hotkey_callback_router_func func, + void *data); EXPORT void obs_hotkey_trigger_routed_callback(obs_hotkey_id id, bool pressed); @@ -290,12 +298,12 @@ EXPORT void obs_hotkey_enable_callback_rerouting(bool enable); typedef void (*obs_hotkey_atomic_update_func)(void *); EXPORT void obs_hotkey_update_atomic(obs_hotkey_atomic_update_func func, - void *data); + void *data); struct dstr; EXPORT void obs_key_to_str(obs_key_t key, struct dstr *str); EXPORT void obs_key_combination_to_str(obs_key_combination_t key, - struct dstr *str); + struct dstr *str); EXPORT obs_key_t obs_key_from_virtual_key(int code); EXPORT int obs_key_to_virtual_key(obs_key_t key); diff --git a/libobs/obs-hotkeys.h b/libobs/obs-hotkeys.h index dadb446..329e9c2 100644 --- a/libobs/obs-hotkeys.h +++ b/libobs/obs-hotkeys.h @@ -437,7 +437,6 @@ OBS_HOTKEY(OBS_KEY_SLEEP) OBS_HOTKEY(OBS_KEY_ZOOM) OBS_HOTKEY(OBS_KEY_CANCEL) - #ifndef OBS_MOUSE_BUTTON #define OBS_MOUSE_BUTTON(x) OBS_HOTKEY(x) #define OBS_MOUSE_BUTTON_DEFAULT 1 diff --git a/libobs/obs-interaction.h b/libobs/obs-interaction.h index d213df2..dd9d038 100644 --- a/libobs/obs-interaction.h +++ b/libobs/obs-interaction.h @@ -20,37 +20,37 @@ #include "util/c99defs.h" enum obs_interaction_flags { - INTERACT_NONE = 0, - INTERACT_CAPS_KEY = 1, - INTERACT_SHIFT_KEY = 1 << 1, - INTERACT_CONTROL_KEY = 1 << 2, - INTERACT_ALT_KEY = 1 << 3, - INTERACT_MOUSE_LEFT = 1 << 4, - INTERACT_MOUSE_MIDDLE = 1 << 5, - INTERACT_MOUSE_RIGHT = 1 << 6, - INTERACT_COMMAND_KEY = 1 << 7, - INTERACT_NUMLOCK_KEY = 1 << 8, - INTERACT_IS_KEY_PAD = 1 << 9, - INTERACT_IS_LEFT = 1 << 10, - INTERACT_IS_RIGHT = 1 << 11 + INTERACT_NONE = 0, + INTERACT_CAPS_KEY = 1, + INTERACT_SHIFT_KEY = 1 << 1, + INTERACT_CONTROL_KEY = 1 << 2, + INTERACT_ALT_KEY = 1 << 3, + INTERACT_MOUSE_LEFT = 1 << 4, + INTERACT_MOUSE_MIDDLE = 1 << 5, + INTERACT_MOUSE_RIGHT = 1 << 6, + INTERACT_COMMAND_KEY = 1 << 7, + INTERACT_NUMLOCK_KEY = 1 << 8, + INTERACT_IS_KEY_PAD = 1 << 9, + INTERACT_IS_LEFT = 1 << 10, + INTERACT_IS_RIGHT = 1 << 11, }; enum obs_mouse_button_type { MOUSE_LEFT, MOUSE_MIDDLE, - MOUSE_RIGHT + MOUSE_RIGHT, }; struct obs_mouse_event { - uint32_t modifiers; - int32_t x; - int32_t y; + uint32_t modifiers; + int32_t x; + int32_t y; }; struct obs_key_event { - uint32_t modifiers; - char *text; - uint32_t native_modifiers; - uint32_t native_scancode; - uint32_t native_vkey; + uint32_t modifiers; + char *text; + uint32_t native_modifiers; + uint32_t native_scancode; + uint32_t native_vkey; }; diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index 717360f..68adce0 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -37,6 +37,7 @@ #include "obs.h" #define NUM_TEXTURES 2 +#define NUM_CHANNELS 3 #define MICROSECOND_DEN 1000000 #define NUM_ENCODE_TEXTURES 3 #define NUM_ENCODE_TEXTURE_FRAMES_TO_WAIT 1 @@ -60,7 +61,7 @@ struct draw_callback { /* validity checks */ static inline bool obs_object_valid(const void *obj, const char *f, - const char *t) + const char *t) { if (!obj) { blog(LOG_DEBUG, "%s: Null '%s' parameter", f, t); @@ -71,8 +72,8 @@ static inline bool obs_object_valid(const void *obj, const char *f, } #define obs_ptr_valid(ptr, func) obs_object_valid(ptr, func, #ptr) -#define obs_source_valid obs_ptr_valid -#define obs_output_valid obs_ptr_valid +#define obs_source_valid obs_ptr_valid +#define obs_output_valid obs_ptr_valid #define obs_encoder_valid obs_ptr_valid #define obs_service_valid obs_ptr_valid @@ -87,13 +88,13 @@ struct obs_module { void *module; bool loaded; - bool (*load)(void); - void (*unload)(void); - void (*post_load)(void); - void (*set_locale)(const char *locale); - void (*free_locale)(void); - uint32_t (*ver)(void); - void (*set_pointer)(obs_module_t *module); + bool (*load)(void); + void (*unload)(void); + void (*post_load)(void); + void (*set_locale)(const char *locale); + void (*free_locale)(void); + uint32_t (*ver)(void); + void (*set_pointer)(obs_module_t *module); const char *(*name)(void); const char *(*description)(void); const char *(*author)(void); @@ -117,7 +118,7 @@ static inline void free_module_path(struct obs_module_path *omp) } static inline bool check_path(const char *data, const char *path, - struct dstr *output) + struct dstr *output) { dstr_copy(output, path); dstr_cat(output, data); @@ -125,32 +126,31 @@ static inline bool check_path(const char *data, const char *path, return os_file_exists(output->array); } - /* ------------------------------------------------------------------------- */ /* hotkeys */ struct obs_hotkey { - obs_hotkey_id id; - char *name; - char *description; + obs_hotkey_id id; + char *name; + char *description; - obs_hotkey_func func; - void *data; - int pressed; + obs_hotkey_func func; + void *data; + int pressed; - obs_hotkey_registerer_t registerer_type; - void *registerer; + obs_hotkey_registerer_t registerer_type; + void *registerer; - obs_hotkey_id pair_partner_id; + obs_hotkey_id pair_partner_id; }; struct obs_hotkey_pair { - obs_hotkey_pair_id pair_id; - obs_hotkey_id id[2]; - obs_hotkey_active_func func[2]; - bool pressed0; - bool pressed1; - void *data[2]; + obs_hotkey_pair_id pair_id; + obs_hotkey_id id[2]; + obs_hotkey_active_func func[2]; + bool pressed0; + bool pressed1; + void *data[2]; }; typedef struct obs_hotkey_pair obs_hotkey_pair_t; @@ -163,7 +163,7 @@ struct obs_core_hotkeys; bool obs_hotkeys_platform_init(struct obs_core_hotkeys *hotkeys); void obs_hotkeys_platform_free(struct obs_core_hotkeys *hotkeys); bool obs_hotkeys_platform_is_pressed(obs_hotkeys_platform_t *context, - obs_key_t key); + obs_key_t key); const char *obs_get_hotkey_translation(obs_key_t key, const char *def); @@ -173,52 +173,49 @@ void obs_hotkeys_context_release(struct obs_context_data *context); void obs_hotkeys_free(void); struct obs_hotkey_binding { - obs_key_combination_t key; - bool pressed; - bool modifiers_match; + obs_key_combination_t key; + bool pressed; + bool modifiers_match; - obs_hotkey_id hotkey_id; - obs_hotkey_t *hotkey; + obs_hotkey_id hotkey_id; + obs_hotkey_t *hotkey; }; struct obs_hotkey_name_map; void obs_hotkey_name_map_free(void); - /* ------------------------------------------------------------------------- */ /* views */ struct obs_view { - pthread_mutex_t channels_mutex; - obs_source_t *channels[MAX_CHANNELS]; + pthread_mutex_t channels_mutex; + obs_source_t *channels[MAX_CHANNELS]; }; extern bool obs_view_init(struct obs_view *view); extern void obs_view_free(struct obs_view *view); - /* ------------------------------------------------------------------------- */ /* displays */ struct obs_display { - bool size_changed; - bool enabled; - uint32_t cx, cy; - uint32_t background_color; - gs_swapchain_t *swap; - pthread_mutex_t draw_callbacks_mutex; - pthread_mutex_t draw_info_mutex; - DARRAY(struct draw_callback) draw_callbacks; + bool size_changed; + bool enabled; + uint32_t cx, cy; + uint32_t background_color; + gs_swapchain_t *swap; + pthread_mutex_t draw_callbacks_mutex; + pthread_mutex_t draw_info_mutex; + DARRAY(struct draw_callback) draw_callbacks; - struct obs_display *next; - struct obs_display **prev_next; + struct obs_display *next; + struct obs_display **prev_next; }; extern bool obs_display_init(struct obs_display *display, - const struct gs_init_data *graphics_data); + const struct gs_init_data *graphics_data); extern void obs_display_free(struct obs_display *display); - /* ------------------------------------------------------------------------- */ /* core */ @@ -238,194 +235,191 @@ struct obs_tex_frame { }; struct obs_core_video { - graphics_t *graphics; - gs_stagesurf_t *copy_surfaces[NUM_TEXTURES]; - gs_texture_t *render_textures[NUM_TEXTURES]; - gs_texture_t *output_textures[NUM_TEXTURES]; - gs_texture_t *convert_textures[NUM_TEXTURES]; - gs_texture_t *convert_uv_textures[NUM_TEXTURES]; - bool textures_rendered[NUM_TEXTURES]; - bool textures_output[NUM_TEXTURES]; - bool textures_copied[NUM_TEXTURES]; - bool textures_converted[NUM_TEXTURES]; - bool using_nv12_tex; - struct circlebuf vframe_info_buffer; - struct circlebuf vframe_info_buffer_gpu; - gs_effect_t *default_effect; - gs_effect_t *default_rect_effect; - gs_effect_t *opaque_effect; - gs_effect_t *solid_effect; - gs_effect_t *repeat_effect; - gs_effect_t *conversion_effect; - gs_effect_t *bicubic_effect; - gs_effect_t *lanczos_effect; - gs_effect_t *area_effect; - gs_effect_t *bilinear_lowres_effect; - gs_effect_t *premultiplied_alpha_effect; - gs_samplerstate_t *point_sampler; - gs_stagesurf_t *mapped_surface; - int cur_texture; - long raw_active; - long gpu_encoder_active; - pthread_mutex_t gpu_encoder_mutex; - struct circlebuf gpu_encoder_queue; - struct circlebuf gpu_encoder_avail_queue; - DARRAY(obs_encoder_t *) gpu_encoders; - os_sem_t *gpu_encode_semaphore; - os_event_t *gpu_encode_inactive; - pthread_t gpu_encode_thread; - bool gpu_encode_thread_initialized; - volatile bool gpu_encode_stop; + graphics_t *graphics; + gs_stagesurf_t *copy_surfaces[NUM_TEXTURES][NUM_CHANNELS]; + gs_texture_t *render_texture; + gs_texture_t *output_texture; + gs_texture_t *convert_textures[NUM_CHANNELS]; + bool texture_rendered; + bool textures_copied[NUM_TEXTURES]; + bool texture_converted; + bool using_nv12_tex; + struct circlebuf vframe_info_buffer; + struct circlebuf vframe_info_buffer_gpu; + gs_effect_t *default_effect; + gs_effect_t *default_rect_effect; + gs_effect_t *opaque_effect; + gs_effect_t *solid_effect; + gs_effect_t *repeat_effect; + gs_effect_t *conversion_effect; + gs_effect_t *bicubic_effect; + gs_effect_t *lanczos_effect; + gs_effect_t *area_effect; + gs_effect_t *bilinear_lowres_effect; + gs_effect_t *premultiplied_alpha_effect; + gs_samplerstate_t *point_sampler; + gs_stagesurf_t *mapped_surfaces[NUM_CHANNELS]; + int cur_texture; + long raw_active; + long gpu_encoder_active; + pthread_mutex_t gpu_encoder_mutex; + struct circlebuf gpu_encoder_queue; + struct circlebuf gpu_encoder_avail_queue; + DARRAY(obs_encoder_t *) gpu_encoders; + os_sem_t *gpu_encode_semaphore; + os_event_t *gpu_encode_inactive; + pthread_t gpu_encode_thread; + bool gpu_encode_thread_initialized; + volatile bool gpu_encode_stop; - uint64_t video_time; - uint64_t video_avg_frame_time_ns; - double video_fps; - video_t *video; - pthread_t video_thread; - uint32_t total_frames; - uint32_t lagged_frames; - bool thread_initialized; + uint64_t video_time; + uint64_t video_frame_interval_ns; + uint64_t video_avg_frame_time_ns; + double video_fps; + video_t *video; + pthread_t video_thread; + uint32_t total_frames; + uint32_t lagged_frames; + bool thread_initialized; - bool gpu_conversion; - const char *conversion_tech; - uint32_t conversion_height; - uint32_t plane_offsets[3]; - uint32_t plane_sizes[3]; - uint32_t plane_linewidth[3]; + bool gpu_conversion; + const char *conversion_techs[NUM_CHANNELS]; + bool conversion_needed; + float conversion_width_i; - uint32_t output_width; - uint32_t output_height; - uint32_t base_width; - uint32_t base_height; - float color_matrix[16]; - enum obs_scale_type scale_type; + uint32_t output_width; + uint32_t output_height; + uint32_t base_width; + uint32_t base_height; + float color_matrix[16]; + enum obs_scale_type scale_type; - gs_texture_t *transparent_texture; + gs_texture_t *transparent_texture; - gs_effect_t *deinterlace_discard_effect; - gs_effect_t *deinterlace_discard_2x_effect; - gs_effect_t *deinterlace_linear_effect; - gs_effect_t *deinterlace_linear_2x_effect; - gs_effect_t *deinterlace_blend_effect; - gs_effect_t *deinterlace_blend_2x_effect; - gs_effect_t *deinterlace_yadif_effect; - gs_effect_t *deinterlace_yadif_2x_effect; + gs_effect_t *deinterlace_discard_effect; + gs_effect_t *deinterlace_discard_2x_effect; + gs_effect_t *deinterlace_linear_effect; + gs_effect_t *deinterlace_linear_2x_effect; + gs_effect_t *deinterlace_blend_effect; + gs_effect_t *deinterlace_blend_2x_effect; + gs_effect_t *deinterlace_yadif_effect; + gs_effect_t *deinterlace_yadif_2x_effect; - struct obs_video_info ovi; + struct obs_video_info ovi; }; struct audio_monitor; struct obs_core_audio { - audio_t *audio; + audio_t *audio; - DARRAY(struct obs_source*) render_order; - DARRAY(struct obs_source*) root_nodes; + DARRAY(struct obs_source *) render_order; + DARRAY(struct obs_source *) root_nodes; - uint64_t buffered_ts; - struct circlebuf buffered_timestamps; - int buffering_wait_ticks; - int total_buffering_ticks; + uint64_t buffered_ts; + struct circlebuf buffered_timestamps; + int buffering_wait_ticks; + int total_buffering_ticks; - float user_volume; + float user_volume; - pthread_mutex_t monitoring_mutex; - DARRAY(struct audio_monitor*) monitors; - char *monitoring_device_name; - char *monitoring_device_id; + pthread_mutex_t monitoring_mutex; + DARRAY(struct audio_monitor *) monitors; + char *monitoring_device_name; + char *monitoring_device_id; }; /* user sources, output channels, and displays */ struct obs_core_data { - struct obs_source *first_source; - struct obs_source *first_audio_source; - struct obs_display *first_display; - struct obs_output *first_output; - struct obs_encoder *first_encoder; - struct obs_service *first_service; + struct obs_source *first_source; + struct obs_source *first_audio_source; + struct obs_display *first_display; + struct obs_output *first_output; + struct obs_encoder *first_encoder; + struct obs_service *first_service; - pthread_mutex_t sources_mutex; - pthread_mutex_t displays_mutex; - pthread_mutex_t outputs_mutex; - pthread_mutex_t encoders_mutex; - pthread_mutex_t services_mutex; - pthread_mutex_t audio_sources_mutex; - pthread_mutex_t draw_callbacks_mutex; - DARRAY(struct draw_callback) draw_callbacks; - DARRAY(struct tick_callback) tick_callbacks; + pthread_mutex_t sources_mutex; + pthread_mutex_t displays_mutex; + pthread_mutex_t outputs_mutex; + pthread_mutex_t encoders_mutex; + pthread_mutex_t services_mutex; + pthread_mutex_t audio_sources_mutex; + pthread_mutex_t draw_callbacks_mutex; + DARRAY(struct draw_callback) draw_callbacks; + DARRAY(struct tick_callback) tick_callbacks; - struct obs_view main_view; + struct obs_view main_view; - long long unnamed_index; + long long unnamed_index; - obs_data_t *private_data; + obs_data_t *private_data; - volatile bool valid; + volatile bool valid; }; /* user hotkeys */ struct obs_core_hotkeys { - pthread_mutex_t mutex; - DARRAY(obs_hotkey_t) hotkeys; - obs_hotkey_id next_id; - DARRAY(obs_hotkey_pair_t) hotkey_pairs; - obs_hotkey_pair_id next_pair_id; + pthread_mutex_t mutex; + DARRAY(obs_hotkey_t) hotkeys; + obs_hotkey_id next_id; + DARRAY(obs_hotkey_pair_t) hotkey_pairs; + obs_hotkey_pair_id next_pair_id; - pthread_t hotkey_thread; - bool hotkey_thread_initialized; - os_event_t *stop_event; - bool thread_disable_press; - bool strict_modifiers; - bool reroute_hotkeys; - DARRAY(obs_hotkey_binding_t) bindings; + pthread_t hotkey_thread; + bool hotkey_thread_initialized; + os_event_t *stop_event; + bool thread_disable_press; + bool strict_modifiers; + bool reroute_hotkeys; + DARRAY(obs_hotkey_binding_t) bindings; obs_hotkey_callback_router_func router_func; - void *router_func_data; + void *router_func_data; - obs_hotkeys_platform_t *platform_context; + obs_hotkeys_platform_t *platform_context; - pthread_once_t name_map_init_token; - struct obs_hotkey_name_map *name_map; + pthread_once_t name_map_init_token; + struct obs_hotkey_name_map *name_map; - signal_handler_t *signals; + signal_handler_t *signals; - char *translations[OBS_KEY_LAST_VALUE]; - char *mute; - char *unmute; - char *push_to_mute; - char *push_to_talk; - char *sceneitem_show; - char *sceneitem_hide; + char *translations[OBS_KEY_LAST_VALUE]; + char *mute; + char *unmute; + char *push_to_mute; + char *push_to_talk; + char *sceneitem_show; + char *sceneitem_hide; }; struct obs_core { - struct obs_module *first_module; - DARRAY(struct obs_module_path) module_paths; + struct obs_module *first_module; + DARRAY(struct obs_module_path) module_paths; - DARRAY(struct obs_source_info) source_types; - DARRAY(struct obs_source_info) input_types; - DARRAY(struct obs_source_info) filter_types; - DARRAY(struct obs_source_info) transition_types; - DARRAY(struct obs_output_info) output_types; + DARRAY(struct obs_source_info) source_types; + DARRAY(struct obs_source_info) input_types; + DARRAY(struct obs_source_info) filter_types; + DARRAY(struct obs_source_info) transition_types; + DARRAY(struct obs_output_info) output_types; DARRAY(struct obs_encoder_info) encoder_types; DARRAY(struct obs_service_info) service_types; - DARRAY(struct obs_modal_ui) modal_ui_callbacks; - DARRAY(struct obs_modeless_ui) modeless_ui_callbacks; + DARRAY(struct obs_modal_ui) modal_ui_callbacks; + DARRAY(struct obs_modeless_ui) modeless_ui_callbacks; - signal_handler_t *signals; - proc_handler_t *procs; + signal_handler_t *signals; + proc_handler_t *procs; - char *locale; - char *module_config_path; - bool name_store_owned; - profiler_name_store_t *name_store; + char *locale; + char *module_config_path; + bool name_store_owned; + profiler_name_store_t *name_store; /* segmented into multiple sub-structures to keep things a bit more * clean and organized */ - struct obs_core_video video; - struct obs_core_audio audio; - struct obs_core_data data; - struct obs_core_hotkeys hotkeys; + struct obs_core_video video; + struct obs_core_audio audio; + struct obs_core_data data; + struct obs_core_hotkeys hotkeys; }; extern struct obs_core *obs; @@ -434,59 +428,56 @@ extern void *obs_graphics_thread(void *param); extern gs_effect_t *obs_load_effect(gs_effect_t **effect, const char *file); -extern bool audio_callback(void *param, - uint64_t start_ts_in, uint64_t end_ts_in, uint64_t *out_ts, - uint32_t mixers, struct audio_output_data *mixes); +extern bool audio_callback(void *param, uint64_t start_ts_in, + uint64_t end_ts_in, uint64_t *out_ts, + uint32_t mixers, struct audio_output_data *mixes); -extern void start_raw_video(video_t *video, - const struct video_scale_info *conversion, +extern void +start_raw_video(video_t *video, const struct video_scale_info *conversion, void (*callback)(void *param, struct video_data *frame), void *param); extern void stop_raw_video(video_t *video, - void (*callback)(void *param, struct video_data *frame), - void *param); + void (*callback)(void *param, + struct video_data *frame), + void *param); /* ------------------------------------------------------------------------- */ /* obs shared context data */ struct obs_context_data { - char *name; - void *data; - obs_data_t *settings; - signal_handler_t *signals; - proc_handler_t *procs; - enum obs_obj_type type; + char *name; + void *data; + obs_data_t *settings; + signal_handler_t *signals; + proc_handler_t *procs; + enum obs_obj_type type; - DARRAY(obs_hotkey_id) hotkeys; - DARRAY(obs_hotkey_pair_id) hotkey_pairs; - obs_data_t *hotkey_data; + DARRAY(obs_hotkey_id) hotkeys; + DARRAY(obs_hotkey_pair_id) hotkey_pairs; + obs_data_t *hotkey_data; - DARRAY(char*) rename_cache; - pthread_mutex_t rename_cache_mutex; + DARRAY(char *) rename_cache; + pthread_mutex_t rename_cache_mutex; - pthread_mutex_t *mutex; - struct obs_context_data *next; - struct obs_context_data **prev_next; + pthread_mutex_t *mutex; + struct obs_context_data *next; + struct obs_context_data **prev_next; - bool private; + bool private; }; -extern bool obs_context_data_init( - struct obs_context_data *context, - enum obs_obj_type type, - obs_data_t *settings, - const char *name, - obs_data_t *hotkey_data, - bool private); +extern bool obs_context_data_init(struct obs_context_data *context, + enum obs_obj_type type, obs_data_t *settings, + const char *name, obs_data_t *hotkey_data, + bool private); extern void obs_context_data_free(struct obs_context_data *context); extern void obs_context_data_insert(struct obs_context_data *context, - pthread_mutex_t *mutex, void *first); + pthread_mutex_t *mutex, void *first); extern void obs_context_data_remove(struct obs_context_data *context); extern void obs_context_data_setname(struct obs_context_data *context, - const char *name); - + const char *name); /* ------------------------------------------------------------------------- */ /* ref-counting */ @@ -529,7 +520,6 @@ static inline bool obs_weak_ref_get_ref(struct obs_weak_ref *ref) return false; } - /* ------------------------------------------------------------------------- */ /* sources */ @@ -551,7 +541,7 @@ struct audio_action { enum audio_action_type type; union { float vol; - bool set; + bool set; }; }; @@ -566,177 +556,181 @@ struct audio_cb_info { }; struct obs_source { - struct obs_context_data context; - struct obs_source_info info; - struct obs_weak_source *control; + struct obs_context_data context; + struct obs_source_info info; + struct obs_weak_source *control; /* general exposed flags that can be set for the source */ - uint32_t flags; - uint32_t default_flags; + uint32_t flags; + uint32_t default_flags; + uint32_t last_obs_ver; /* indicates ownership of the info.id buffer */ - bool owns_info_id; + bool owns_info_id; /* signals to call the source update in the video thread */ - bool defer_update; + bool defer_update; /* ensures show/hide are only called once */ - volatile long show_refs; + volatile long show_refs; /* ensures activate/deactivate are only called once */ - volatile long activate_refs; + volatile long activate_refs; /* used to indicate that the source has been removed and all * references to it should be released (not exactly how I would prefer * to handle things but it's the best option) */ - bool removed; + bool removed; - bool active; - bool showing; + bool active; + bool showing; /* used to temporarily disable sources if needed */ - bool enabled; + bool enabled; /* timing (if video is present, is based upon video) */ - volatile bool timing_set; - volatile uint64_t timing_adjust; - uint64_t resample_offset; - uint64_t last_audio_ts; - uint64_t next_audio_ts_min; - uint64_t next_audio_sys_ts_min; - uint64_t last_frame_ts; - uint64_t last_sys_timestamp; - bool async_rendered; + volatile bool timing_set; + volatile uint64_t timing_adjust; + uint64_t resample_offset; + uint64_t last_audio_ts; + uint64_t next_audio_ts_min; + uint64_t next_audio_sys_ts_min; + uint64_t last_frame_ts; + uint64_t last_sys_timestamp; + bool async_rendered; /* audio */ - bool audio_failed; - bool audio_pending; - bool pending_stop; - bool user_muted; - bool muted; - struct obs_source *next_audio_source; - struct obs_source **prev_next_audio_source; - uint64_t audio_ts; - struct circlebuf audio_input_buf[MAX_AUDIO_CHANNELS]; - size_t last_audio_input_buf_size; - DARRAY(struct audio_action) audio_actions; - float *audio_output_buf[MAX_AUDIO_MIXES][MAX_AUDIO_CHANNELS]; - struct resample_info sample_info; - audio_resampler_t *resampler; - pthread_mutex_t audio_actions_mutex; - pthread_mutex_t audio_buf_mutex; - pthread_mutex_t audio_mutex; - pthread_mutex_t audio_cb_mutex; - DARRAY(struct audio_cb_info) audio_cb_list; - struct obs_audio_data audio_data; - size_t audio_storage_size; - uint32_t audio_mixers; - float user_volume; - float volume; - int64_t sync_offset; - int64_t last_sync_offset; - float balance; + bool audio_failed; + bool audio_pending; + bool pending_stop; + bool audio_active; + bool user_muted; + bool muted; + struct obs_source *next_audio_source; + struct obs_source **prev_next_audio_source; + uint64_t audio_ts; + struct circlebuf audio_input_buf[MAX_AUDIO_CHANNELS]; + size_t last_audio_input_buf_size; + DARRAY(struct audio_action) audio_actions; + float *audio_output_buf[MAX_AUDIO_MIXES][MAX_AUDIO_CHANNELS]; + float *audio_mix_buf[MAX_AUDIO_CHANNELS]; + struct resample_info sample_info; + audio_resampler_t *resampler; + pthread_mutex_t audio_actions_mutex; + pthread_mutex_t audio_buf_mutex; + pthread_mutex_t audio_mutex; + pthread_mutex_t audio_cb_mutex; + DARRAY(struct audio_cb_info) audio_cb_list; + struct obs_audio_data audio_data; + size_t audio_storage_size; + uint32_t audio_mixers; + float user_volume; + float volume; + int64_t sync_offset; + int64_t last_sync_offset; + float balance; /* async video data */ - gs_texture_t *async_texture; - gs_texrender_t *async_texrender; - struct obs_source_frame *cur_async_frame; - bool async_gpu_conversion; - enum video_format async_format; - bool async_full_range; - enum video_format async_cache_format; - bool async_cache_full_range; - enum gs_color_format async_texture_format; - int async_plane_offset[2]; - bool async_flip; - bool async_active; - bool async_update_texture; - bool async_unbuffered; - bool async_decoupled; - struct obs_source_frame *async_preload_frame; - DARRAY(struct async_frame) async_cache; - DARRAY(struct obs_source_frame*)async_frames; - pthread_mutex_t async_mutex; - uint32_t async_width; - uint32_t async_height; - uint32_t async_cache_width; - uint32_t async_cache_height; - uint32_t async_convert_width; - uint32_t async_convert_height; + gs_texture_t *async_textures[MAX_AV_PLANES]; + gs_texrender_t *async_texrender; + struct obs_source_frame *cur_async_frame; + bool async_gpu_conversion; + enum video_format async_format; + bool async_full_range; + enum video_format async_cache_format; + bool async_cache_full_range; + enum gs_color_format async_texture_formats[MAX_AV_PLANES]; + int async_channel_count; + bool async_flip; + bool async_active; + bool async_update_texture; + bool async_unbuffered; + bool async_decoupled; + struct obs_source_frame *async_preload_frame; + DARRAY(struct async_frame) async_cache; + DARRAY(struct obs_source_frame *) async_frames; + pthread_mutex_t async_mutex; + uint32_t async_width; + uint32_t async_height; + uint32_t async_cache_width; + uint32_t async_cache_height; + uint32_t async_convert_width[MAX_AV_PLANES]; + uint32_t async_convert_height[MAX_AV_PLANES]; /* async video deinterlacing */ - uint64_t deinterlace_offset; - uint64_t deinterlace_frame_ts; - gs_effect_t *deinterlace_effect; - struct obs_source_frame *prev_async_frame; - gs_texture_t *async_prev_texture; - gs_texrender_t *async_prev_texrender; - uint32_t deinterlace_half_duration; - enum obs_deinterlace_mode deinterlace_mode; - bool deinterlace_top_first; - bool deinterlace_rendered; + uint64_t deinterlace_offset; + uint64_t deinterlace_frame_ts; + gs_effect_t *deinterlace_effect; + struct obs_source_frame *prev_async_frame; + gs_texture_t *async_prev_textures[MAX_AV_PLANES]; + gs_texrender_t *async_prev_texrender; + uint32_t deinterlace_half_duration; + enum obs_deinterlace_mode deinterlace_mode; + bool deinterlace_top_first; + bool deinterlace_rendered; /* filters */ - struct obs_source *filter_parent; - struct obs_source *filter_target; - DARRAY(struct obs_source*) filters; - pthread_mutex_t filter_mutex; - gs_texrender_t *filter_texrender; - enum obs_allow_direct_render allow_direct; - bool rendering_filter; + struct obs_source *filter_parent; + struct obs_source *filter_target; + DARRAY(struct obs_source *) filters; + pthread_mutex_t filter_mutex; + gs_texrender_t *filter_texrender; + enum obs_allow_direct_render allow_direct; + bool rendering_filter; /* sources specific hotkeys */ - obs_hotkey_pair_id mute_unmute_key; - obs_hotkey_id push_to_mute_key; - obs_hotkey_id push_to_talk_key; - bool push_to_mute_enabled; - bool push_to_mute_pressed; - bool user_push_to_mute_pressed; - bool push_to_talk_enabled; - bool push_to_talk_pressed; - bool user_push_to_talk_pressed; - uint64_t push_to_mute_delay; - uint64_t push_to_mute_stop_time; - uint64_t push_to_talk_delay; - uint64_t push_to_talk_stop_time; + obs_hotkey_pair_id mute_unmute_key; + obs_hotkey_id push_to_mute_key; + obs_hotkey_id push_to_talk_key; + bool push_to_mute_enabled; + bool push_to_mute_pressed; + bool user_push_to_mute_pressed; + bool push_to_talk_enabled; + bool push_to_talk_pressed; + bool user_push_to_talk_pressed; + uint64_t push_to_mute_delay; + uint64_t push_to_mute_stop_time; + uint64_t push_to_talk_delay; + uint64_t push_to_talk_stop_time; /* transitions */ - uint64_t transition_start_time; - uint64_t transition_duration; - pthread_mutex_t transition_tex_mutex; - gs_texrender_t *transition_texrender[2]; - pthread_mutex_t transition_mutex; - obs_source_t *transition_sources[2]; - bool transitioning_video; - bool transitioning_audio; - bool transition_source_active[2]; - uint32_t transition_alignment; - uint32_t transition_actual_cx; - uint32_t transition_actual_cy; - uint32_t transition_cx; - uint32_t transition_cy; - uint32_t transition_fixed_duration; - bool transition_use_fixed_duration; - enum obs_transition_mode transition_mode; - enum obs_transition_scale_type transition_scale_type; - struct matrix4 transition_matrices[2]; + uint64_t transition_start_time; + uint64_t transition_duration; + pthread_mutex_t transition_tex_mutex; + gs_texrender_t *transition_texrender[2]; + pthread_mutex_t transition_mutex; + obs_source_t *transition_sources[2]; + bool transitioning_video; + bool transitioning_audio; + bool transition_source_active[2]; + uint32_t transition_alignment; + uint32_t transition_actual_cx; + uint32_t transition_actual_cy; + uint32_t transition_cx; + uint32_t transition_cy; + uint32_t transition_fixed_duration; + bool transition_use_fixed_duration; + enum obs_transition_mode transition_mode; + enum obs_transition_scale_type transition_scale_type; + struct matrix4 transition_matrices[2]; - struct audio_monitor *monitor; - enum obs_monitoring_type monitoring_type; + struct audio_monitor *monitor; + enum obs_monitoring_type monitoring_type; - obs_data_t *private_settings; + obs_data_t *private_settings; }; extern struct obs_source_info *get_source_info(const char *id); extern bool obs_source_init_context(struct obs_source *source, - obs_data_t *settings, const char *name, - obs_data_t *hotkey_data, bool private); + obs_data_t *settings, const char *name, + obs_data_t *hotkey_data, bool private); extern bool obs_transition_init(obs_source_t *transition); extern void obs_transition_free(obs_source_t *transition); extern void obs_transition_tick(obs_source_t *transition); extern void obs_transition_enum_sources(obs_source_t *transition, - obs_source_enum_proc_t enum_callback, void *param); + obs_source_enum_proc_t enum_callback, + void *param); extern void obs_transition_save(obs_source_t *source, obs_data_t *data); extern void obs_transition_load(obs_source_t *source, obs_data_t *data); @@ -744,15 +738,21 @@ struct audio_monitor *audio_monitor_create(obs_source_t *source); void audio_monitor_reset(struct audio_monitor *monitor); extern void audio_monitor_destroy(struct audio_monitor *monitor); +extern obs_source_t *obs_source_create_set_last_ver(const char *id, + const char *name, + obs_data_t *settings, + obs_data_t *hotkey_data, + uint32_t last_obs_ver); extern void obs_source_destroy(struct obs_source *source); enum view_type { MAIN_VIEW, - AUX_VIEW + AUX_VIEW, }; static inline void obs_source_dosignal(struct obs_source *source, - const char *signal_obs, const char *signal_source) + const char *signal_obs, + const char *signal_source) { struct calldata data; uint8_t stack[128]; @@ -763,11 +763,11 @@ static inline void obs_source_dosignal(struct obs_source *source, signal_handler_signal(obs->signals, signal_obs, &data); if (signal_source) signal_handler_signal(source->context.signals, signal_source, - &data); + &data); } /* maximum timestamp variance in nanoseconds */ -#define MAX_TS_VAR 2000000000ULL +#define MAX_TS_VAR 2000000000ULL static inline bool frame_out_of_bounds(const obs_source_t *source, uint64_t ts) { @@ -777,45 +777,55 @@ static inline bool frame_out_of_bounds(const obs_source_t *source, uint64_t ts) return ((ts - source->last_frame_ts) > MAX_TS_VAR); } -static inline enum gs_color_format convert_video_format( - enum video_format format) +static inline enum gs_color_format +convert_video_format(enum video_format format) { - if (format == VIDEO_FORMAT_RGBA) + switch (format) { + case VIDEO_FORMAT_RGBA: return GS_RGBA; - else if (format == VIDEO_FORMAT_BGRA) + case VIDEO_FORMAT_BGRA: + case VIDEO_FORMAT_I40A: + case VIDEO_FORMAT_I42A: + case VIDEO_FORMAT_YUVA: + case VIDEO_FORMAT_AYUV: return GS_BGRA; - - return GS_BGRX; + default: + return GS_BGRX; + } } extern void obs_source_activate(obs_source_t *source, enum view_type type); extern void obs_source_deactivate(obs_source_t *source, enum view_type type); extern void obs_source_video_tick(obs_source_t *source, float seconds); extern float obs_source_get_target_volume(obs_source_t *source, - obs_source_t *target); + obs_source_t *target); extern void obs_source_audio_render(obs_source_t *source, uint32_t mixers, - size_t channels, size_t sample_rate, size_t size); + size_t channels, size_t sample_rate, + size_t size); extern void add_alignment(struct vec2 *v, uint32_t align, int cx, int cy); extern struct obs_source_frame *filter_async_video(obs_source_t *source, - struct obs_source_frame *in); + struct obs_source_frame *in); extern bool update_async_texture(struct obs_source *source, - const struct obs_source_frame *frame, - gs_texture_t *tex, gs_texrender_t *texrender); + const struct obs_source_frame *frame, + gs_texture_t *tex, gs_texrender_t *texrender); +extern bool update_async_textures(struct obs_source *source, + const struct obs_source_frame *frame, + gs_texture_t *tex[MAX_AV_PLANES], + gs_texrender_t *texrender); extern bool set_async_texture_size(struct obs_source *source, - const struct obs_source_frame *frame); + const struct obs_source_frame *frame); extern void remove_async_frame(obs_source_t *source, - struct obs_source_frame *frame); + struct obs_source_frame *frame); extern void set_deinterlace_texture_size(obs_source_t *source); extern void deinterlace_process_last_frame(obs_source_t *source, - uint64_t sys_time); + uint64_t sys_time); extern void deinterlace_update_async_video(obs_source_t *source); extern void deinterlace_render(obs_source_t *s); - /* ------------------------------------------------------------------------- */ /* outputs */ @@ -839,89 +849,115 @@ struct obs_weak_output { }; #define CAPTION_LINE_CHARS (32) -#define CAPTION_LINE_BYTES (4*CAPTION_LINE_CHARS) +#define CAPTION_LINE_BYTES (4 * CAPTION_LINE_CHARS) struct caption_text { - char text[CAPTION_LINE_BYTES+1]; + char text[CAPTION_LINE_BYTES + 1]; double display_duration; struct caption_text *next; }; +struct pause_data { + pthread_mutex_t mutex; + uint64_t last_video_ts; + uint64_t ts_start; + uint64_t ts_end; + uint64_t ts_offset; +}; + +extern bool video_pause_check(struct pause_data *pause, uint64_t timestamp); +extern bool audio_pause_check(struct pause_data *pause, struct audio_data *data, + size_t sample_rate); +extern void pause_reset(struct pause_data *pause); + struct obs_output { - struct obs_context_data context; - struct obs_output_info info; - struct obs_weak_output *control; + struct obs_context_data context; + struct obs_output_info info; + struct obs_weak_output *control; /* indicates ownership of the info.id buffer */ - bool owns_info_id; + bool owns_info_id; - bool received_video; - bool received_audio; - volatile bool data_active; - volatile bool end_data_capture_thread_active; - int64_t video_offset; - int64_t audio_offsets[MAX_AUDIO_MIXES]; - int64_t highest_audio_ts; - int64_t highest_video_ts; - pthread_t end_data_capture_thread; - os_event_t *stopping_event; - pthread_mutex_t interleaved_mutex; - DARRAY(struct encoder_packet) interleaved_packets; - int stop_code; + bool received_video; + bool received_audio; + volatile bool data_active; + volatile bool end_data_capture_thread_active; + int64_t video_offset; + int64_t audio_offsets[MAX_AUDIO_MIXES]; + int64_t highest_audio_ts; + int64_t highest_video_ts; + pthread_t end_data_capture_thread; + os_event_t *stopping_event; + pthread_mutex_t interleaved_mutex; + DARRAY(struct encoder_packet) interleaved_packets; + int stop_code; - int reconnect_retry_sec; - int reconnect_retry_max; - int reconnect_retries; - int reconnect_retry_cur_sec; - pthread_t reconnect_thread; - os_event_t *reconnect_stop_event; - volatile bool reconnecting; - volatile bool reconnect_thread_active; + int reconnect_retry_sec; + int reconnect_retry_max; + int reconnect_retries; + int reconnect_retry_cur_sec; + pthread_t reconnect_thread; + os_event_t *reconnect_stop_event; + volatile bool reconnecting; + volatile bool reconnect_thread_active; - uint32_t starting_drawn_count; - uint32_t starting_lagged_count; - uint32_t starting_frame_count; + uint32_t starting_drawn_count; + uint32_t starting_lagged_count; + uint32_t starting_frame_count; - int total_frames; + int total_frames; - volatile bool active; - video_t *video; - audio_t *audio; - obs_encoder_t *video_encoder; - obs_encoder_t *audio_encoders[MAX_AUDIO_MIXES]; - obs_service_t *service; - size_t mixer_mask; + volatile bool active; + volatile bool paused; + video_t *video; + audio_t *audio; + obs_encoder_t *video_encoder; + obs_encoder_t *audio_encoders[MAX_AUDIO_MIXES]; + obs_service_t *service; + size_t mixer_mask; - uint32_t scaled_width; - uint32_t scaled_height; + struct pause_data pause; - bool video_conversion_set; - bool audio_conversion_set; - struct video_scale_info video_conversion; - struct audio_convert_info audio_conversion; + struct circlebuf audio_buffer[MAX_AUDIO_MIXES][MAX_AV_PLANES]; + uint64_t audio_start_ts; + uint64_t video_start_ts; + size_t audio_size; + size_t planes; + size_t sample_rate; + size_t total_audio_frames; - pthread_mutex_t caption_mutex; - double caption_timestamp; - struct caption_text *caption_head; - struct caption_text *caption_tail; + uint32_t scaled_width; + uint32_t scaled_height; - bool valid; + bool video_conversion_set; + bool audio_conversion_set; + struct video_scale_info video_conversion; + struct audio_convert_info audio_conversion; - uint64_t active_delay_ns; - encoded_callback_t delay_callback; - struct circlebuf delay_data; /* struct delay_data */ - pthread_mutex_t delay_mutex; - uint32_t delay_sec; - uint32_t delay_flags; - uint32_t delay_cur_flags; - volatile long delay_restart_refs; - volatile bool delay_active; - volatile bool delay_capturing; + pthread_mutex_t caption_mutex; + double caption_timestamp; + struct caption_text *caption_head; + struct caption_text *caption_tail; - char *last_error_message; + bool valid; + + uint64_t active_delay_ns; + encoded_callback_t delay_callback; + struct circlebuf delay_data; /* struct delay_data */ + pthread_mutex_t delay_mutex; + uint32_t delay_sec; + uint32_t delay_flags; + uint32_t delay_cur_flags; + volatile long delay_restart_refs; + volatile bool delay_active; + volatile bool delay_capturing; + + char *last_error_message; + + float audio_data[MAX_AUDIO_CHANNELS][AUDIO_OUTPUT_FRAMES]; }; static inline void do_output_signal(struct obs_output *output, - const char *signal) + const char *signal) { struct calldata params = {0}; calldata_set_ptr(¶ms, "output", output); @@ -935,18 +971,18 @@ extern bool obs_output_delay_start(obs_output_t *output); extern void obs_output_delay_stop(obs_output_t *output); extern bool obs_output_actual_start(obs_output_t *output); extern void obs_output_actual_stop(obs_output_t *output, bool force, - uint64_t ts); + uint64_t ts); extern const struct obs_output_info *find_output(const char *id); extern void obs_output_remove_encoder(struct obs_output *output, - struct obs_encoder *encoder); + struct obs_encoder *encoder); -extern void obs_encoder_packet_create_instance(struct encoder_packet *dst, - const struct encoder_packet *src); +extern void +obs_encoder_packet_create_instance(struct encoder_packet *dst, + const struct encoder_packet *src); void obs_output_destroy(obs_output_t *output); - /* ------------------------------------------------------------------------- */ /* encoders */ @@ -962,64 +998,67 @@ struct encoder_callback { }; struct obs_encoder { - struct obs_context_data context; - struct obs_encoder_info info; - struct obs_weak_encoder *control; + struct obs_context_data context; + struct obs_encoder_info info; + struct obs_weak_encoder *control; /* allows re-routing to another encoder */ - struct obs_encoder_info orig_info; + struct obs_encoder_info orig_info; - pthread_mutex_t init_mutex; + pthread_mutex_t init_mutex; - uint32_t samplerate; - size_t planes; - size_t blocksize; - size_t framesize; - size_t framesize_bytes; + uint32_t samplerate; + size_t planes; + size_t blocksize; + size_t framesize; + size_t framesize_bytes; - size_t mixer_idx; + size_t mixer_idx; - uint32_t scaled_width; - uint32_t scaled_height; - enum video_format preferred_format; + uint32_t scaled_width; + uint32_t scaled_height; + enum video_format preferred_format; - volatile bool active; - bool initialized; + volatile bool active; + volatile bool paused; + bool initialized; /* indicates ownership of the info.id buffer */ - bool owns_info_id; + bool owns_info_id; - uint32_t timebase_num; - uint32_t timebase_den; + uint32_t timebase_num; + uint32_t timebase_den; - int64_t cur_pts; + int64_t cur_pts; - struct circlebuf audio_input_buffer[MAX_AV_PLANES]; - uint8_t *audio_output_buffer[MAX_AV_PLANES]; + struct circlebuf audio_input_buffer[MAX_AV_PLANES]; + uint8_t *audio_output_buffer[MAX_AV_PLANES]; /* if a video encoder is paired with an audio encoder, make it start * up at the specific timestamp. if this is the audio encoder, * wait_for_video makes it wait until it's ready to sync up with * video */ - bool wait_for_video; - bool first_received; - struct obs_encoder *paired_encoder; - int64_t offset_usec; - uint64_t first_raw_ts; - uint64_t start_ts; + bool wait_for_video; + bool first_received; + struct obs_encoder *paired_encoder; + int64_t offset_usec; + uint64_t first_raw_ts; + uint64_t start_ts; - pthread_mutex_t outputs_mutex; - DARRAY(obs_output_t*) outputs; + pthread_mutex_t outputs_mutex; + DARRAY(obs_output_t *) outputs; - bool destroy_on_stop; + bool destroy_on_stop; /* stores the video/audio media output pointer. video_t *or audio_t **/ - void *media; + void *media; - pthread_mutex_t callbacks_mutex; + pthread_mutex_t callbacks_mutex; DARRAY(struct encoder_callback) callbacks; - const char *profile_encoder_encode_name; + struct pause_data pause; + + const char *profile_encoder_encode_name; }; extern struct obs_encoder_info *find_encoder(const char *id); @@ -1028,23 +1067,25 @@ extern bool obs_encoder_initialize(obs_encoder_t *encoder); extern void obs_encoder_shutdown(obs_encoder_t *encoder); extern void obs_encoder_start(obs_encoder_t *encoder, - void (*new_packet)(void *param, struct encoder_packet *packet), - void *param); + void (*new_packet)(void *param, + struct encoder_packet *packet), + void *param); extern void obs_encoder_stop(obs_encoder_t *encoder, - void (*new_packet)(void *param, struct encoder_packet *packet), - void *param); + void (*new_packet)(void *param, + struct encoder_packet *packet), + void *param); extern void obs_encoder_add_output(struct obs_encoder *encoder, - struct obs_output *output); + struct obs_output *output); extern void obs_encoder_remove_output(struct obs_encoder *encoder, - struct obs_output *output); + struct obs_output *output); extern bool start_gpu_encode(obs_encoder_t *encoder); extern void stop_gpu_encode(obs_encoder_t *encoder); extern bool do_encode(struct obs_encoder *encoder, struct encoder_frame *frame); extern void send_off_encoder_packet(obs_encoder_t *encoder, bool success, - bool received, struct encoder_packet *pkt); + bool received, struct encoder_packet *pkt); void obs_encoder_destroy(obs_encoder_t *encoder); @@ -1057,16 +1098,16 @@ struct obs_weak_service { }; struct obs_service { - struct obs_context_data context; - struct obs_service_info info; - struct obs_weak_service *control; + struct obs_context_data context; + struct obs_service_info info; + struct obs_weak_service *control; /* indicates ownership of the info.id buffer */ - bool owns_info_id; + bool owns_info_id; - bool active; - bool destroy; - struct obs_output *output; + bool active; + bool destroy; + struct obs_output *output; }; extern const struct obs_service_info *find_service(const char *id); @@ -1074,7 +1115,6 @@ extern const struct obs_service_info *find_service(const char *id); extern void obs_service_activate(struct obs_service *service); extern void obs_service_deactivate(struct obs_service *service, bool remove); extern bool obs_service_initialize(struct obs_service *service, - struct obs_output *output); + struct obs_output *output); void obs_service_destroy(obs_service_t *service); - diff --git a/libobs/obs-module.c b/libobs/obs-module.c index 38276f8..570c12b 100644 --- a/libobs/obs-module.c +++ b/libobs/obs-module.c @@ -26,9 +26,10 @@ extern const char *get_module_extension(void); static inline int req_func_not_found(const char *name, const char *path) { - blog(LOG_DEBUG, "Required module function '%s' in module '%s' not " - "found, loading of module failed", - name, path); + blog(LOG_DEBUG, + "Required module function '%s' in module '%s' not " + "found, loading of module failed", + name, path); return MODULE_MISSING_EXPORTS; } @@ -47,13 +48,13 @@ static int load_module_exports(struct obs_module *mod, const char *path) return req_func_not_found("obs_module_ver", path); /* optional exports */ - mod->unload = os_dlsym(mod->module, "obs_module_unload"); - mod->post_load = os_dlsym(mod->module, "obs_module_post_load"); - mod->set_locale = os_dlsym(mod->module, "obs_module_set_locale"); + mod->unload = os_dlsym(mod->module, "obs_module_unload"); + mod->post_load = os_dlsym(mod->module, "obs_module_post_load"); + mod->set_locale = os_dlsym(mod->module, "obs_module_set_locale"); mod->free_locale = os_dlsym(mod->module, "obs_module_free_locale"); - mod->name = os_dlsym(mod->module, "obs_module_name"); + mod->name = os_dlsym(mod->module, "obs_module_name"); mod->description = os_dlsym(mod->module, "obs_module_description"); - mod->author = os_dlsym(mod->module, "obs_module_author"); + mod->author = os_dlsym(mod->module, "obs_module_author"); return MODULE_SUCCESS; } @@ -77,7 +78,7 @@ extern void reset_win32_symbol_paths(void); #endif int obs_open_module(obs_module_t **module, const char *path, - const char *data_path) + const char *data_path) { struct obs_module mod = {0}; int errorcode; @@ -108,12 +109,12 @@ int obs_open_module(obs_module_t **module, const char *path, if (errorcode != MODULE_SUCCESS) return errorcode; - mod.bin_path = bstrdup(path); - mod.file = strrchr(mod.bin_path, '/'); - mod.file = (!mod.file) ? mod.bin_path : (mod.file + 1); - mod.mod_name = get_module_name(mod.file); + mod.bin_path = bstrdup(path); + mod.file = strrchr(mod.bin_path, '/'); + mod.file = (!mod.file) ? mod.bin_path : (mod.file + 1); + mod.mod_name = get_module_name(mod.file); mod.data_path = bstrdup(data_path); - mod.next = obs->first_module; + mod.next = obs->first_module; if (mod.file) { blog(LOG_DEBUG, "Loading module: %s", mod.file); @@ -138,13 +139,13 @@ bool obs_init_module(obs_module_t *module) const char *profile_name = profile_store_name(obs_get_profiler_name_store(), - "obs_init_module(%s)", module->file); + "obs_init_module(%s)", module->file); profile_start(profile_name); module->loaded = module->load(); if (!module->loaded) blog(LOG_WARNING, "Failed to initialize module '%s'", - module->file); + module->file); profile_end(profile_name); return module->loaded; @@ -226,9 +227,10 @@ void obs_add_module_path(const char *bin, const char *data) { struct obs_module_path omp; - if (!obs || !bin || !data) return; + if (!obs || !bin || !data) + return; - omp.bin = bstrdup(bin); + omp.bin = bstrdup(bin); omp.data = bstrdup(data); da_push_back(obs->module_paths, &omp); } @@ -240,7 +242,7 @@ static void load_all_callback(void *param, const struct obs_module_info *info) int code = obs_open_module(&module, info->bin_path, info->data_path); if (code != MODULE_SUCCESS) { blog(LOG_DEBUG, "Failed to load module file '%s': %d", - info->bin_path, code); + info->bin_path, code); return; } @@ -274,7 +276,7 @@ void obs_post_load_modules(void) } static inline void make_data_dir(struct dstr *parsed_data_dir, - const char *data_dir, const char *name) + const char *data_dir, const char *name) { dstr_copy(parsed_data_dir, data_dir); dstr_replace(parsed_data_dir, "%module%", name); @@ -298,7 +300,7 @@ static char *make_data_directory(const char *module_name, const char *data_dir) } static bool parse_binary_from_directory(struct dstr *parsed_bin_path, - const char *bin_path, const char *file) + const char *bin_path, const char *file) { struct dstr directory = {0}; bool found = true; @@ -330,16 +332,17 @@ static bool parse_binary_from_directory(struct dstr *parsed_bin_path, return found; } -static void process_found_module(struct obs_module_path *omp, - const char *path, bool directory, - obs_find_module_callback_t callback, void *param) +static void process_found_module(struct obs_module_path *omp, const char *path, + bool directory, + obs_find_module_callback_t callback, + void *param) { struct obs_module_info info; - struct dstr name = {0}; - struct dstr parsed_bin_path = {0}; - const char *file; - char *parsed_data_dir; - bool bin_found = true; + struct dstr name = {0}; + struct dstr parsed_bin_path = {0}; + const char *file; + char *parsed_data_dir; + bool bin_found = true; file = strrchr(path, '/'); file = file ? (file + 1) : path; @@ -356,13 +359,13 @@ static void process_found_module(struct obs_module_path *omp, dstr_copy(&parsed_bin_path, path); } else { bin_found = parse_binary_from_directory(&parsed_bin_path, - omp->bin, file); + omp->bin, file); } parsed_data_dir = make_data_directory(name.array, omp->data); if (parsed_data_dir && bin_found) { - info.bin_path = parsed_bin_path.array; + info.bin_path = parsed_bin_path.array; info.data_path = parsed_data_dir; callback(param, &info); } @@ -373,7 +376,8 @@ static void process_found_module(struct obs_module_path *omp, } static void find_modules_in_path(struct obs_module_path *omp, - obs_find_module_callback_t callback, void *param) + obs_find_module_callback_t callback, + void *param) { struct dstr search_path = {0}; char *module_start; @@ -398,10 +402,9 @@ static void find_modules_in_path(struct obs_module_path *omp, if (os_glob(search_path.array, 0, &gi) == 0) { for (size_t i = 0; i < gi->gl_pathc; i++) { if (search_directories == gi->gl_pathv[i].directory) - process_found_module(omp, - gi->gl_pathv[i].path, - search_directories, - callback, param); + process_found_module(omp, gi->gl_pathv[i].path, + search_directories, + callback, param); } os_globfree(gi); @@ -458,10 +461,10 @@ void free_module(struct obs_module *mod) } lookup_t *obs_module_load_locale(obs_module_t *module, - const char *default_locale, const char *locale) + const char *default_locale, const char *locale) { - struct dstr str = {0}; - lookup_t *lookup = NULL; + struct dstr str = {0}; + lookup_t *lookup = NULL; if (!module || !default_locale || !locale) { blog(LOG_WARNING, "obs_module_load_locale: Invalid parameters"); @@ -480,7 +483,7 @@ lookup_t *obs_module_load_locale(obs_module_t *module, if (!lookup) { blog(LOG_WARNING, "Failed to load '%s' text for module: '%s'", - default_locale, module->file); + default_locale, module->file); goto cleanup; } @@ -495,7 +498,7 @@ lookup_t *obs_module_load_locale(obs_module_t *module, if (!text_lookup_add(lookup, file)) blog(LOG_WARNING, "Failed to load '%s' text for module: '%s'", - locale, module->file); + locale, module->file); bfree(file); cleanup: @@ -503,51 +506,53 @@ cleanup: return lookup; } -#define REGISTER_OBS_DEF(size_var, structure, dest, info) \ - do { \ - struct structure data = {0}; \ - if (!size_var) { \ - blog(LOG_ERROR, "Tried to register " #structure \ - " outside of obs_module_load"); \ - return; \ - } \ - \ - if (size_var > sizeof(data)) { \ - blog(LOG_ERROR, "Tried to register " #structure \ - " with size %llu which is more " \ - "than libobs currently supports " \ - "(%llu)", \ - (long long unsigned)size_var, \ - (long long unsigned)sizeof(data));\ - goto error; \ - } \ - \ - memcpy(&data, info, size_var); \ - da_push_back(dest, &data); \ +#define REGISTER_OBS_DEF(size_var, structure, dest, info) \ + do { \ + struct structure data = {0}; \ + if (!size_var) { \ + blog(LOG_ERROR, "Tried to register " #structure \ + " outside of obs_module_load"); \ + return; \ + } \ + \ + if (size_var > sizeof(data)) { \ + blog(LOG_ERROR, \ + "Tried to register " #structure \ + " with size %llu which is more " \ + "than libobs currently supports " \ + "(%llu)", \ + (long long unsigned)size_var, \ + (long long unsigned)sizeof(data)); \ + goto error; \ + } \ + \ + memcpy(&data, info, size_var); \ + da_push_back(dest, &data); \ } while (false) -#define CHECK_REQUIRED_VAL(type, info, val, func) \ - do { \ +#define CHECK_REQUIRED_VAL(type, info, val, func) \ + do { \ if ((offsetof(type, val) + sizeof(info->val) > size) || \ - !info->val) { \ - blog(LOG_ERROR, "Required value '" #val "' for " \ - "'%s' not found. " #func \ - " failed.", info->id); \ - goto error; \ - } \ + !info->val) { \ + blog(LOG_ERROR, \ + "Required value '" #val "' for " \ + "'%s' not found. " #func " failed.", \ + info->id); \ + goto error; \ + } \ } while (false) -#define HANDLE_ERROR(size_var, structure, info) \ - do { \ - struct structure data = {0}; \ - if (!size_var) \ - return; \ - \ - memcpy(&data, info, sizeof(data) < size_var ? \ - sizeof(data) : size_var); \ - \ - if (info->type_data && info->free_type_data) \ - info->free_type_data(info->type_data); \ +#define HANDLE_ERROR(size_var, structure, info) \ + do { \ + struct structure data = {0}; \ + if (!size_var) \ + return; \ + \ + memcpy(&data, info, \ + sizeof(data) < size_var ? sizeof(data) : size_var); \ + \ + if (info->type_data && info->free_type_data) \ + info->free_type_data(info->type_data); \ } while (false) #define source_warn(format, ...) \ @@ -572,13 +577,14 @@ void obs_register_source_s(const struct obs_source_info *info, size_t size) array = &obs->transition_types.da; } else if (info->type != OBS_SOURCE_TYPE_SCENE) { source_warn("Tried to register unknown source type: %u", - info->type); + info->type); goto error; } if (get_source_info(info->id)) { source_warn("Source '%s' already exists! " - "Duplicate library?", info->id); + "Duplicate library?", + info->id); goto error; } @@ -593,25 +599,27 @@ void obs_register_source_s(const struct obs_source_info *info, size_t size) if (data.type == OBS_SOURCE_TYPE_TRANSITION) { if (data.get_width) source_warn("get_width ignored registering " - "transition '%s'", - data.id); + "transition '%s'", + data.id); if (data.get_height) source_warn("get_height ignored registering " - "transition '%s'", - data.id); + "transition '%s'", + data.id); data.output_flags |= OBS_SOURCE_COMPOSITE | OBS_SOURCE_VIDEO | - OBS_SOURCE_CUSTOM_DRAW; + OBS_SOURCE_CUSTOM_DRAW; } if ((data.output_flags & OBS_SOURCE_COMPOSITE) != 0) { if ((data.output_flags & OBS_SOURCE_AUDIO) != 0) { source_warn("Source '%s': Composite sources " - "cannot be audio sources", info->id); + "cannot be audio sources", + info->id); goto error; } if ((data.output_flags & OBS_SOURCE_ASYNC) != 0) { source_warn("Source '%s': Composite sources " - "cannot be async sources", info->id); + "cannot be async sources", + info->id); goto error; } } @@ -619,14 +627,12 @@ void obs_register_source_s(const struct obs_source_info *info, size_t size) #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_source_info, info, val, func) CHECK_REQUIRED_VAL_(info, get_name, obs_register_source); - CHECK_REQUIRED_VAL_(info, create, obs_register_source); - CHECK_REQUIRED_VAL_(info, destroy, obs_register_source); - if (info->type != OBS_SOURCE_TYPE_FILTER && - info->type != OBS_SOURCE_TYPE_TRANSITION && + if (info->type != OBS_SOURCE_TYPE_FILTER && + info->type != OBS_SOURCE_TYPE_TRANSITION && (info->output_flags & OBS_SOURCE_VIDEO) != 0 && (info->output_flags & OBS_SOURCE_ASYNC) == 0) { - CHECK_REQUIRED_VAL_(info, get_width, obs_register_source); + CHECK_REQUIRED_VAL_(info, get_width, obs_register_source); CHECK_REQUIRED_VAL_(info, get_height, obs_register_source); } @@ -637,9 +643,10 @@ void obs_register_source_s(const struct obs_source_info *info, size_t size) if (size > sizeof(data)) { source_warn("Tried to register obs_source_info with size " - "%llu which is more than libobs currently " - "supports (%llu)", (long long unsigned)size, - (long long unsigned)sizeof(data)); + "%llu which is more than libobs currently " + "supports (%llu)", + (long long unsigned)size, + (long long unsigned)sizeof(data)); goto error; } @@ -656,32 +663,33 @@ void obs_register_output_s(const struct obs_output_info *info, size_t size) { if (find_output(info->id)) { output_warn("Output id '%s' already exists! " - "Duplicate library?", info->id); + "Duplicate library?", + info->id); goto error; } #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_output_info, info, val, func) CHECK_REQUIRED_VAL_(info, get_name, obs_register_output); - CHECK_REQUIRED_VAL_(info, create, obs_register_output); - CHECK_REQUIRED_VAL_(info, destroy, obs_register_output); - CHECK_REQUIRED_VAL_(info, start, obs_register_output); - CHECK_REQUIRED_VAL_(info, stop, obs_register_output); + CHECK_REQUIRED_VAL_(info, create, obs_register_output); + CHECK_REQUIRED_VAL_(info, destroy, obs_register_output); + CHECK_REQUIRED_VAL_(info, start, obs_register_output); + CHECK_REQUIRED_VAL_(info, stop, obs_register_output); if (info->flags & OBS_OUTPUT_ENCODED) { CHECK_REQUIRED_VAL_(info, encoded_packet, obs_register_output); } else { if (info->flags & OBS_OUTPUT_VIDEO) CHECK_REQUIRED_VAL_(info, raw_video, - obs_register_output); + obs_register_output); if (info->flags & OBS_OUTPUT_AUDIO) { if (info->flags & OBS_OUTPUT_MULTI_TRACK) { CHECK_REQUIRED_VAL_(info, raw_audio2, - obs_register_output); + obs_register_output); } else { CHECK_REQUIRED_VAL_(info, raw_audio, - obs_register_output); + obs_register_output); } } } @@ -698,15 +706,16 @@ void obs_register_encoder_s(const struct obs_encoder_info *info, size_t size) { if (find_encoder(info->id)) { encoder_warn("Encoder id '%s' already exists! " - "Duplicate library?", info->id); + "Duplicate library?", + info->id); goto error; } #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_encoder_info, info, val, func) CHECK_REQUIRED_VAL_(info, get_name, obs_register_encoder); - CHECK_REQUIRED_VAL_(info, create, obs_register_encoder); - CHECK_REQUIRED_VAL_(info, destroy, obs_register_encoder); + CHECK_REQUIRED_VAL_(info, create, obs_register_encoder); + CHECK_REQUIRED_VAL_(info, destroy, obs_register_encoder); if ((info->caps & OBS_ENCODER_CAP_PASS_TEXTURE) != 0) CHECK_REQUIRED_VAL_(info, encode_texture, obs_register_encoder); @@ -728,15 +737,16 @@ void obs_register_service_s(const struct obs_service_info *info, size_t size) { if (find_service(info->id)) { service_warn("Service id '%s' already exists! " - "Duplicate library?", info->id); + "Duplicate library?", + info->id); goto error; } #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_service_info, info, val, func) CHECK_REQUIRED_VAL_(info, get_name, obs_register_service); - CHECK_REQUIRED_VAL_(info, create, obs_register_service); - CHECK_REQUIRED_VAL_(info, destroy, obs_register_service); + CHECK_REQUIRED_VAL_(info, create, obs_register_service); + CHECK_REQUIRED_VAL_(info, destroy, obs_register_service); #undef CHECK_REQUIRED_VAL_ REGISTER_OBS_DEF(size, obs_service_info, obs->service_types, info); @@ -750,9 +760,9 @@ void obs_register_modal_ui_s(const struct obs_modal_ui *info, size_t size) { #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_modal_ui, info, val, func) - CHECK_REQUIRED_VAL_(info, task, obs_register_modal_ui); + CHECK_REQUIRED_VAL_(info, task, obs_register_modal_ui); CHECK_REQUIRED_VAL_(info, target, obs_register_modal_ui); - CHECK_REQUIRED_VAL_(info, exec, obs_register_modal_ui); + CHECK_REQUIRED_VAL_(info, exec, obs_register_modal_ui); #undef CHECK_REQUIRED_VAL_ REGISTER_OBS_DEF(size, obs_modal_ui, obs->modal_ui_callbacks, info); @@ -766,13 +776,13 @@ void obs_register_modeless_ui_s(const struct obs_modeless_ui *info, size_t size) { #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_modeless_ui, info, val, func) - CHECK_REQUIRED_VAL_(info, task, obs_register_modeless_ui); + CHECK_REQUIRED_VAL_(info, task, obs_register_modeless_ui); CHECK_REQUIRED_VAL_(info, target, obs_register_modeless_ui); CHECK_REQUIRED_VAL_(info, create, obs_register_modeless_ui); #undef CHECK_REQUIRED_VAL_ REGISTER_OBS_DEF(size, obs_modeless_ui, obs->modeless_ui_callbacks, - info); + info); return; error: diff --git a/libobs/obs-module.h b/libobs/obs-module.h index 09f484e..ea57cb2 100644 --- a/libobs/obs-module.h +++ b/libobs/obs-module.h @@ -73,16 +73,16 @@ bool obs_module_load(void) */ /** Required: Declares a libobs module. */ -#define OBS_DECLARE_MODULE() \ - static obs_module_t *obs_module_pointer; \ - MODULE_EXPORT void obs_module_set_pointer(obs_module_t *module); \ - void obs_module_set_pointer(obs_module_t *module) \ - { \ - obs_module_pointer = module; \ - } \ - obs_module_t *obs_current_module(void) {return obs_module_pointer;} \ - MODULE_EXPORT uint32_t obs_module_ver(void); \ - uint32_t obs_module_ver(void) {return LIBOBS_API_VER;} +#define OBS_DECLARE_MODULE() \ + static obs_module_t *obs_module_pointer; \ + MODULE_EXPORT void obs_module_set_pointer(obs_module_t *module); \ + void obs_module_set_pointer(obs_module_t *module) \ + { \ + obs_module_pointer = module; \ + } \ + obs_module_t *obs_current_module(void) { return obs_module_pointer; } \ + MODULE_EXPORT uint32_t obs_module_ver(void); \ + uint32_t obs_module_ver(void) { return LIBOBS_API_VER; } /** * Required: Called when the module is loaded. Use this function to load all @@ -107,28 +107,29 @@ MODULE_EXPORT void obs_module_set_locale(const char *locale); MODULE_EXPORT void obs_module_free_locale(void); /** Optional: Use this macro in a module to use default locale handling. */ -#define OBS_MODULE_USE_DEFAULT_LOCALE(module_name, default_locale) \ - lookup_t *obs_module_lookup = NULL; \ - const char *obs_module_text(const char *val) \ - { \ - const char *out = val; \ - text_lookup_getstr(obs_module_lookup, val, &out); \ - return out; \ - } \ - bool obs_module_get_string(const char *val, const char **out) \ - { \ +#define OBS_MODULE_USE_DEFAULT_LOCALE(module_name, default_locale) \ + lookup_t *obs_module_lookup = NULL; \ + const char *obs_module_text(const char *val) \ + { \ + const char *out = val; \ + text_lookup_getstr(obs_module_lookup, val, &out); \ + return out; \ + } \ + bool obs_module_get_string(const char *val, const char **out) \ + { \ return text_lookup_getstr(obs_module_lookup, val, out); \ - } \ - void obs_module_set_locale(const char *locale) \ - { \ - if (obs_module_lookup) text_lookup_destroy(obs_module_lookup); \ - obs_module_lookup = obs_module_load_locale( \ - obs_current_module(), \ - default_locale, locale); \ - } \ - void obs_module_free_locale(void) \ - { \ - text_lookup_destroy(obs_module_lookup); \ + } \ + void obs_module_set_locale(const char *locale) \ + { \ + if (obs_module_lookup) \ + text_lookup_destroy(obs_module_lookup); \ + obs_module_lookup = obs_module_load_locale( \ + obs_current_module(), default_locale, locale); \ + } \ + void obs_module_free_locale(void) \ + { \ + text_lookup_destroy(obs_module_lookup); \ + obs_module_lookup = NULL; \ } /** Helper function for looking up locale if default locale handler was used */ @@ -137,7 +138,7 @@ MODULE_EXTERN const char *obs_module_text(const char *lookup_string); /** Helper function for looking up locale if default locale handler was used, * returns true if text found, otherwise false */ MODULE_EXTERN bool obs_module_get_string(const char *lookup_string, - const char **translated_string); + const char **translated_string); /** Helper function that returns the current module */ MODULE_EXTERN obs_module_t *obs_current_module(void); @@ -163,9 +164,9 @@ MODULE_EXTERN obs_module_t *obs_current_module(void); * * @param name Author name(s) */ -#define OBS_MODULE_AUTHOR(name) \ +#define OBS_MODULE_AUTHOR(name) \ MODULE_EXPORT const char *obs_module_author(void); \ - const char *obs_module_author(void) {return name;} + const char *obs_module_author(void) { return name; } /** Optional: Returns the full name of the module */ MODULE_EXPORT const char *obs_module_name(void); diff --git a/libobs/obs-nix.c b/libobs/obs-nix.c index f7ce93d..09e989f 100644 --- a/libobs/obs-nix.c +++ b/libobs/obs-nix.c @@ -48,10 +48,9 @@ const char *get_module_extension(void) #define BIT_STRING "32bit" #endif -static const char *module_bin[] = { - "../../obs-plugins/" BIT_STRING, - OBS_INSTALL_PREFIX "/" OBS_PLUGIN_DESTINATION -}; +static const char *module_bin[] = {"../../obs-plugins/" BIT_STRING, + OBS_INSTALL_PREFIX + "/" OBS_PLUGIN_DESTINATION}; static const char *module_data[] = { OBS_DATA_PATH "/obs-plugins/%module%", @@ -59,7 +58,7 @@ static const char *module_data[] = { }; static const int module_patterns_size = - sizeof(module_bin)/sizeof(module_bin[0]); + sizeof(module_bin) / sizeof(module_bin[0]); void add_default_module_paths(void) { @@ -74,14 +73,13 @@ void add_default_module_paths(void) char *find_libobs_data_file(const char *file) { struct dstr output; - dstr_init(&output); + dstr_init(&output); if (check_path(file, OBS_DATA_PATH "/libobs/", &output)) return output.array; - if (OBS_INSTALL_PREFIX [0] != 0) { - if (check_path(file, OBS_INSTALL_DATA_PATH "/libobs/", - &output)) + if (OBS_INSTALL_PREFIX[0] != 0) { + if (check_path(file, OBS_INSTALL_DATA_PATH "/libobs/", &output)) return output.array; } @@ -92,7 +90,7 @@ char *find_libobs_data_file(const char *file) static void log_processor_cores(void) { blog(LOG_INFO, "Physical Cores: %d, Logical Cores: %d", - os_get_physical_cores(), os_get_logical_cores()); + os_get_physical_cores(), os_get_logical_cores()); } #if defined(__linux__) @@ -222,10 +220,11 @@ static void log_memory_info(void) if (sysinfo(&info) < 0) return; - blog(LOG_INFO, "Physical Memory: %"PRIu64"MB Total, %"PRIu64"MB Free", - (uint64_t)info.totalram * info.mem_unit / 1024 / 1024, - ((uint64_t)info.freeram + (uint64_t)info.bufferram) * - info.mem_unit / 1024 / 1024); + blog(LOG_INFO, + "Physical Memory: %" PRIu64 "MB Total, %" PRIu64 "MB Free", + (uint64_t)info.totalram * info.mem_unit / 1024 / 1024, + ((uint64_t)info.freeram + (uint64_t)info.bufferram) * + info.mem_unit / 1024 / 1024); } static void log_kernel_version(void) @@ -245,21 +244,24 @@ static void log_x_info(void) return; } - int protocol_version = ProtocolVersion(dpy); - int protocol_revision = ProtocolRevision(dpy); - int vendor_release = VendorRelease(dpy); - const char *vendor_name = ServerVendor(dpy); + int protocol_version = ProtocolVersion(dpy); + int protocol_revision = ProtocolRevision(dpy); + int vendor_release = VendorRelease(dpy); + const char *vendor_name = ServerVendor(dpy); if (strstr(vendor_name, "X.Org")) { - blog(LOG_INFO, "Window System: X%d.%d, Vendor: %s, Version: %d" - ".%d.%d", protocol_version, protocol_revision, - vendor_name, vendor_release / 10000000, - (vendor_release / 100000) % 100, - (vendor_release / 1000) % 100); + blog(LOG_INFO, + "Window System: X%d.%d, Vendor: %s, Version: %d" + ".%d.%d", + protocol_version, protocol_revision, vendor_name, + vendor_release / 10000000, (vendor_release / 100000) % 100, + (vendor_release / 1000) % 100); } else { - blog(LOG_INFO, "Window System: X%d.%d - vendor string: %s - " - "vendor release: %d", protocol_version, - protocol_revision, vendor_name, vendor_release); + blog(LOG_INFO, + "Window System: X%d.%d - vendor string: %s - " + "vendor release: %d", + protocol_version, protocol_revision, vendor_name, + vendor_release); } XCloseDisplay(dpy); @@ -365,288 +367,556 @@ struct obs_hotkeys_platform { #endif }; -#define MOUSE_1 (1<<16) -#define MOUSE_2 (2<<16) -#define MOUSE_3 (3<<16) -#define MOUSE_4 (4<<16) -#define MOUSE_5 (5<<16) +#define MOUSE_1 (1 << 16) +#define MOUSE_2 (2 << 16) +#define MOUSE_3 (3 << 16) +#define MOUSE_4 (4 << 16) +#define MOUSE_5 (5 << 16) static int get_keysym(obs_key_t key) { switch (key) { - case OBS_KEY_RETURN: return XK_Return; - case OBS_KEY_ESCAPE: return XK_Escape; - case OBS_KEY_TAB: return XK_Tab; - case OBS_KEY_BACKSPACE: return XK_BackSpace; - case OBS_KEY_INSERT: return XK_Insert; - case OBS_KEY_DELETE: return XK_Delete; - case OBS_KEY_PAUSE: return XK_Pause; - case OBS_KEY_PRINT: return XK_Print; - case OBS_KEY_HOME: return XK_Home; - case OBS_KEY_END: return XK_End; - case OBS_KEY_LEFT: return XK_Left; - case OBS_KEY_UP: return XK_Up; - case OBS_KEY_RIGHT: return XK_Right; - case OBS_KEY_DOWN: return XK_Down; - case OBS_KEY_PAGEUP: return XK_Prior; - case OBS_KEY_PAGEDOWN: return XK_Next; + case OBS_KEY_RETURN: + return XK_Return; + case OBS_KEY_ESCAPE: + return XK_Escape; + case OBS_KEY_TAB: + return XK_Tab; + case OBS_KEY_BACKSPACE: + return XK_BackSpace; + case OBS_KEY_INSERT: + return XK_Insert; + case OBS_KEY_DELETE: + return XK_Delete; + case OBS_KEY_PAUSE: + return XK_Pause; + case OBS_KEY_PRINT: + return XK_Print; + case OBS_KEY_HOME: + return XK_Home; + case OBS_KEY_END: + return XK_End; + case OBS_KEY_LEFT: + return XK_Left; + case OBS_KEY_UP: + return XK_Up; + case OBS_KEY_RIGHT: + return XK_Right; + case OBS_KEY_DOWN: + return XK_Down; + case OBS_KEY_PAGEUP: + return XK_Prior; + case OBS_KEY_PAGEDOWN: + return XK_Next; - case OBS_KEY_SHIFT: return XK_Shift_L; - case OBS_KEY_CONTROL: return XK_Control_L; - case OBS_KEY_ALT: return XK_Alt_L; - case OBS_KEY_CAPSLOCK: return XK_Caps_Lock; - case OBS_KEY_NUMLOCK: return XK_Num_Lock; - case OBS_KEY_SCROLLLOCK: return XK_Scroll_Lock; + case OBS_KEY_SHIFT: + return XK_Shift_L; + case OBS_KEY_CONTROL: + return XK_Control_L; + case OBS_KEY_ALT: + return XK_Alt_L; + case OBS_KEY_CAPSLOCK: + return XK_Caps_Lock; + case OBS_KEY_NUMLOCK: + return XK_Num_Lock; + case OBS_KEY_SCROLLLOCK: + return XK_Scroll_Lock; - case OBS_KEY_F1: return XK_F1; - case OBS_KEY_F2: return XK_F2; - case OBS_KEY_F3: return XK_F3; - case OBS_KEY_F4: return XK_F4; - case OBS_KEY_F5: return XK_F5; - case OBS_KEY_F6: return XK_F6; - case OBS_KEY_F7: return XK_F7; - case OBS_KEY_F8: return XK_F8; - case OBS_KEY_F9: return XK_F9; - case OBS_KEY_F10: return XK_F10; - case OBS_KEY_F11: return XK_F11; - case OBS_KEY_F12: return XK_F12; - case OBS_KEY_F13: return XK_F13; - case OBS_KEY_F14: return XK_F14; - case OBS_KEY_F15: return XK_F15; - case OBS_KEY_F16: return XK_F16; - case OBS_KEY_F17: return XK_F17; - case OBS_KEY_F18: return XK_F18; - case OBS_KEY_F19: return XK_F19; - case OBS_KEY_F20: return XK_F20; - case OBS_KEY_F21: return XK_F21; - case OBS_KEY_F22: return XK_F22; - case OBS_KEY_F23: return XK_F23; - case OBS_KEY_F24: return XK_F24; - case OBS_KEY_F25: return XK_F25; - case OBS_KEY_F26: return XK_F26; - case OBS_KEY_F27: return XK_F27; - case OBS_KEY_F28: return XK_F28; - case OBS_KEY_F29: return XK_F29; - case OBS_KEY_F30: return XK_F30; - case OBS_KEY_F31: return XK_F31; - case OBS_KEY_F32: return XK_F32; - case OBS_KEY_F33: return XK_F33; - case OBS_KEY_F34: return XK_F34; - case OBS_KEY_F35: return XK_F35; + case OBS_KEY_F1: + return XK_F1; + case OBS_KEY_F2: + return XK_F2; + case OBS_KEY_F3: + return XK_F3; + case OBS_KEY_F4: + return XK_F4; + case OBS_KEY_F5: + return XK_F5; + case OBS_KEY_F6: + return XK_F6; + case OBS_KEY_F7: + return XK_F7; + case OBS_KEY_F8: + return XK_F8; + case OBS_KEY_F9: + return XK_F9; + case OBS_KEY_F10: + return XK_F10; + case OBS_KEY_F11: + return XK_F11; + case OBS_KEY_F12: + return XK_F12; + case OBS_KEY_F13: + return XK_F13; + case OBS_KEY_F14: + return XK_F14; + case OBS_KEY_F15: + return XK_F15; + case OBS_KEY_F16: + return XK_F16; + case OBS_KEY_F17: + return XK_F17; + case OBS_KEY_F18: + return XK_F18; + case OBS_KEY_F19: + return XK_F19; + case OBS_KEY_F20: + return XK_F20; + case OBS_KEY_F21: + return XK_F21; + case OBS_KEY_F22: + return XK_F22; + case OBS_KEY_F23: + return XK_F23; + case OBS_KEY_F24: + return XK_F24; + case OBS_KEY_F25: + return XK_F25; + case OBS_KEY_F26: + return XK_F26; + case OBS_KEY_F27: + return XK_F27; + case OBS_KEY_F28: + return XK_F28; + case OBS_KEY_F29: + return XK_F29; + case OBS_KEY_F30: + return XK_F30; + case OBS_KEY_F31: + return XK_F31; + case OBS_KEY_F32: + return XK_F32; + case OBS_KEY_F33: + return XK_F33; + case OBS_KEY_F34: + return XK_F34; + case OBS_KEY_F35: + return XK_F35; - case OBS_KEY_MENU: return XK_Menu; - case OBS_KEY_HYPER_L: return XK_Hyper_L; - case OBS_KEY_HYPER_R: return XK_Hyper_R; - case OBS_KEY_HELP: return XK_Help; - case OBS_KEY_SPACE: return XK_space; + case OBS_KEY_MENU: + return XK_Menu; + case OBS_KEY_HYPER_L: + return XK_Hyper_L; + case OBS_KEY_HYPER_R: + return XK_Hyper_R; + case OBS_KEY_HELP: + return XK_Help; + case OBS_KEY_SPACE: + return XK_space; - case OBS_KEY_EXCLAM: return XK_exclam; - case OBS_KEY_QUOTEDBL: return XK_quotedbl; - case OBS_KEY_NUMBERSIGN: return XK_numbersign; - case OBS_KEY_DOLLAR: return XK_dollar; - case OBS_KEY_PERCENT: return XK_percent; - case OBS_KEY_AMPERSAND: return XK_ampersand; - case OBS_KEY_APOSTROPHE: return XK_apostrophe; - case OBS_KEY_PARENLEFT: return XK_parenleft; - case OBS_KEY_PARENRIGHT: return XK_parenright; - case OBS_KEY_ASTERISK: return XK_asterisk; - case OBS_KEY_PLUS: return XK_plus; - case OBS_KEY_COMMA: return XK_comma; - case OBS_KEY_MINUS: return XK_minus; - case OBS_KEY_PERIOD: return XK_period; - case OBS_KEY_SLASH: return XK_slash; - case OBS_KEY_0: return XK_0; - case OBS_KEY_1: return XK_1; - case OBS_KEY_2: return XK_2; - case OBS_KEY_3: return XK_3; - case OBS_KEY_4: return XK_4; - case OBS_KEY_5: return XK_5; - case OBS_KEY_6: return XK_6; - case OBS_KEY_7: return XK_7; - case OBS_KEY_8: return XK_8; - case OBS_KEY_9: return XK_9; - case OBS_KEY_NUMEQUAL: return XK_KP_Equal; - case OBS_KEY_NUMASTERISK: return XK_KP_Multiply; - case OBS_KEY_NUMPLUS: return XK_KP_Add; - case OBS_KEY_NUMCOMMA: return XK_KP_Separator; - case OBS_KEY_NUMMINUS: return XK_KP_Subtract; - case OBS_KEY_NUMPERIOD: return XK_KP_Decimal; - case OBS_KEY_NUMSLASH: return XK_KP_Divide; - case OBS_KEY_NUM0: return XK_KP_0; - case OBS_KEY_NUM1: return XK_KP_1; - case OBS_KEY_NUM2: return XK_KP_2; - case OBS_KEY_NUM3: return XK_KP_3; - case OBS_KEY_NUM4: return XK_KP_4; - case OBS_KEY_NUM5: return XK_KP_5; - case OBS_KEY_NUM6: return XK_KP_6; - case OBS_KEY_NUM7: return XK_KP_7; - case OBS_KEY_NUM8: return XK_KP_8; - case OBS_KEY_NUM9: return XK_KP_9; - case OBS_KEY_COLON: return XK_colon; - case OBS_KEY_SEMICOLON: return XK_semicolon; - case OBS_KEY_LESS: return XK_less; - case OBS_KEY_EQUAL: return XK_equal; - case OBS_KEY_GREATER: return XK_greater; - case OBS_KEY_QUESTION: return XK_question; - case OBS_KEY_AT: return XK_at; - case OBS_KEY_A: return XK_A; - case OBS_KEY_B: return XK_B; - case OBS_KEY_C: return XK_C; - case OBS_KEY_D: return XK_D; - case OBS_KEY_E: return XK_E; - case OBS_KEY_F: return XK_F; - case OBS_KEY_G: return XK_G; - case OBS_KEY_H: return XK_H; - case OBS_KEY_I: return XK_I; - case OBS_KEY_J: return XK_J; - case OBS_KEY_K: return XK_K; - case OBS_KEY_L: return XK_L; - case OBS_KEY_M: return XK_M; - case OBS_KEY_N: return XK_N; - case OBS_KEY_O: return XK_O; - case OBS_KEY_P: return XK_P; - case OBS_KEY_Q: return XK_Q; - case OBS_KEY_R: return XK_R; - case OBS_KEY_S: return XK_S; - case OBS_KEY_T: return XK_T; - case OBS_KEY_U: return XK_U; - case OBS_KEY_V: return XK_V; - case OBS_KEY_W: return XK_W; - case OBS_KEY_X: return XK_X; - case OBS_KEY_Y: return XK_Y; - case OBS_KEY_Z: return XK_Z; - case OBS_KEY_BRACKETLEFT: return XK_bracketleft; - case OBS_KEY_BACKSLASH: return XK_backslash; - case OBS_KEY_BRACKETRIGHT: return XK_bracketright; - case OBS_KEY_ASCIICIRCUM: return XK_asciicircum; - case OBS_KEY_UNDERSCORE: return XK_underscore; - case OBS_KEY_QUOTELEFT: return XK_quoteleft; - case OBS_KEY_BRACELEFT: return XK_braceleft; - case OBS_KEY_BAR: return XK_bar; - case OBS_KEY_BRACERIGHT: return XK_braceright; - case OBS_KEY_ASCIITILDE: return XK_grave; - case OBS_KEY_NOBREAKSPACE: return XK_nobreakspace; - case OBS_KEY_EXCLAMDOWN: return XK_exclamdown; - case OBS_KEY_CENT: return XK_cent; - case OBS_KEY_STERLING: return XK_sterling; - case OBS_KEY_CURRENCY: return XK_currency; - case OBS_KEY_YEN: return XK_yen; - case OBS_KEY_BROKENBAR: return XK_brokenbar; - case OBS_KEY_SECTION: return XK_section; - case OBS_KEY_DIAERESIS: return XK_diaeresis; - case OBS_KEY_COPYRIGHT: return XK_copyright; - case OBS_KEY_ORDFEMININE: return XK_ordfeminine; - case OBS_KEY_GUILLEMOTLEFT: return XK_guillemotleft; - case OBS_KEY_NOTSIGN: return XK_notsign; - case OBS_KEY_HYPHEN: return XK_hyphen; - case OBS_KEY_REGISTERED: return XK_registered; - case OBS_KEY_MACRON: return XK_macron; - case OBS_KEY_DEGREE: return XK_degree; - case OBS_KEY_PLUSMINUS: return XK_plusminus; - case OBS_KEY_TWOSUPERIOR: return XK_twosuperior; - case OBS_KEY_THREESUPERIOR: return XK_threesuperior; - case OBS_KEY_ACUTE: return XK_acute; - case OBS_KEY_MU: return XK_mu; - case OBS_KEY_PARAGRAPH: return XK_paragraph; - case OBS_KEY_PERIODCENTERED: return XK_periodcentered; - case OBS_KEY_CEDILLA: return XK_cedilla; - case OBS_KEY_ONESUPERIOR: return XK_onesuperior; - case OBS_KEY_MASCULINE: return XK_masculine; - case OBS_KEY_GUILLEMOTRIGHT: return XK_guillemotright; - case OBS_KEY_ONEQUARTER: return XK_onequarter; - case OBS_KEY_ONEHALF: return XK_onehalf; - case OBS_KEY_THREEQUARTERS: return XK_threequarters; - case OBS_KEY_QUESTIONDOWN: return XK_questiondown; - case OBS_KEY_AGRAVE: return XK_Agrave; - case OBS_KEY_AACUTE: return XK_Aacute; - case OBS_KEY_ACIRCUMFLEX: return XK_Acircumflex; - case OBS_KEY_ATILDE: return XK_Atilde; - case OBS_KEY_ADIAERESIS: return XK_Adiaeresis; - case OBS_KEY_ARING: return XK_Aring; - case OBS_KEY_AE: return XK_AE; - case OBS_KEY_CCEDILLA: return XK_cedilla; - case OBS_KEY_EGRAVE: return XK_Egrave; - case OBS_KEY_EACUTE: return XK_Eacute; - case OBS_KEY_ECIRCUMFLEX: return XK_Ecircumflex; - case OBS_KEY_EDIAERESIS: return XK_Ediaeresis; - case OBS_KEY_IGRAVE: return XK_Igrave; - case OBS_KEY_IACUTE: return XK_Iacute; - case OBS_KEY_ICIRCUMFLEX: return XK_Icircumflex; - case OBS_KEY_IDIAERESIS: return XK_Idiaeresis; - case OBS_KEY_ETH: return XK_ETH; - case OBS_KEY_NTILDE: return XK_Ntilde; - case OBS_KEY_OGRAVE: return XK_Ograve; - case OBS_KEY_OACUTE: return XK_Oacute; - case OBS_KEY_OCIRCUMFLEX: return XK_Ocircumflex; - case OBS_KEY_ODIAERESIS: return XK_Odiaeresis; - case OBS_KEY_MULTIPLY: return XK_multiply; - case OBS_KEY_OOBLIQUE: return XK_Ooblique; - case OBS_KEY_UGRAVE: return XK_Ugrave; - case OBS_KEY_UACUTE: return XK_Uacute; - case OBS_KEY_UCIRCUMFLEX: return XK_Ucircumflex; - case OBS_KEY_UDIAERESIS: return XK_Udiaeresis; - case OBS_KEY_YACUTE: return XK_Yacute; - case OBS_KEY_THORN: return XK_Thorn; - case OBS_KEY_SSHARP: return XK_ssharp; - case OBS_KEY_DIVISION: return XK_division; - case OBS_KEY_YDIAERESIS: return XK_Ydiaeresis; - case OBS_KEY_MULTI_KEY: return XK_Multi_key; - case OBS_KEY_CODEINPUT: return XK_Codeinput; - case OBS_KEY_SINGLECANDIDATE: return XK_SingleCandidate; - case OBS_KEY_MULTIPLECANDIDATE: return XK_MultipleCandidate; - case OBS_KEY_PREVIOUSCANDIDATE: return XK_PreviousCandidate; - case OBS_KEY_MODE_SWITCH: return XK_Mode_switch; - case OBS_KEY_KANJI: return XK_Kanji; - case OBS_KEY_MUHENKAN: return XK_Muhenkan; - case OBS_KEY_HENKAN: return XK_Henkan; - case OBS_KEY_ROMAJI: return XK_Romaji; - case OBS_KEY_HIRAGANA: return XK_Hiragana; - case OBS_KEY_KATAKANA: return XK_Katakana; - case OBS_KEY_HIRAGANA_KATAKANA: return XK_Hiragana_Katakana; - case OBS_KEY_ZENKAKU: return XK_Zenkaku; - case OBS_KEY_HANKAKU: return XK_Hankaku; - case OBS_KEY_ZENKAKU_HANKAKU: return XK_Zenkaku_Hankaku; - case OBS_KEY_TOUROKU: return XK_Touroku; - case OBS_KEY_MASSYO: return XK_Massyo; - case OBS_KEY_KANA_LOCK: return XK_Kana_Lock; - case OBS_KEY_KANA_SHIFT: return XK_Kana_Shift; - case OBS_KEY_EISU_SHIFT: return XK_Eisu_Shift; - case OBS_KEY_EISU_TOGGLE: return XK_Eisu_toggle; - case OBS_KEY_HANGUL: return XK_Hangul; - case OBS_KEY_HANGUL_START: return XK_Hangul_Start; - case OBS_KEY_HANGUL_END: return XK_Hangul_End; - case OBS_KEY_HANGUL_HANJA: return XK_Hangul_Hanja; - case OBS_KEY_HANGUL_JAMO: return XK_Hangul_Jamo; - case OBS_KEY_HANGUL_ROMAJA: return XK_Hangul_Romaja; - case OBS_KEY_HANGUL_BANJA: return XK_Hangul_Banja; - case OBS_KEY_HANGUL_PREHANJA: return XK_Hangul_PreHanja; - case OBS_KEY_HANGUL_POSTHANJA: return XK_Hangul_PostHanja; - case OBS_KEY_HANGUL_SPECIAL: return XK_Hangul_Special; - case OBS_KEY_DEAD_GRAVE: return XK_dead_grave; - case OBS_KEY_DEAD_ACUTE: return XK_dead_acute; - case OBS_KEY_DEAD_CIRCUMFLEX: return XK_dead_circumflex; - case OBS_KEY_DEAD_TILDE: return XK_dead_tilde; - case OBS_KEY_DEAD_MACRON: return XK_dead_macron; - case OBS_KEY_DEAD_BREVE: return XK_dead_breve; - case OBS_KEY_DEAD_ABOVEDOT: return XK_dead_abovedot; - case OBS_KEY_DEAD_DIAERESIS: return XK_dead_diaeresis; - case OBS_KEY_DEAD_ABOVERING: return XK_dead_abovering; - case OBS_KEY_DEAD_DOUBLEACUTE: return XK_dead_doubleacute; - case OBS_KEY_DEAD_CARON: return XK_dead_caron; - case OBS_KEY_DEAD_CEDILLA: return XK_dead_cedilla; - case OBS_KEY_DEAD_OGONEK: return XK_dead_ogonek; - case OBS_KEY_DEAD_IOTA: return XK_dead_iota; - case OBS_KEY_DEAD_VOICED_SOUND: return XK_dead_voiced_sound; - case OBS_KEY_DEAD_SEMIVOICED_SOUND: return XK_dead_semivoiced_sound; - case OBS_KEY_DEAD_BELOWDOT: return XK_dead_belowdot; - case OBS_KEY_DEAD_HOOK: return XK_dead_hook; - case OBS_KEY_DEAD_HORN: return XK_dead_horn; + case OBS_KEY_EXCLAM: + return XK_exclam; + case OBS_KEY_QUOTEDBL: + return XK_quotedbl; + case OBS_KEY_NUMBERSIGN: + return XK_numbersign; + case OBS_KEY_DOLLAR: + return XK_dollar; + case OBS_KEY_PERCENT: + return XK_percent; + case OBS_KEY_AMPERSAND: + return XK_ampersand; + case OBS_KEY_APOSTROPHE: + return XK_apostrophe; + case OBS_KEY_PARENLEFT: + return XK_parenleft; + case OBS_KEY_PARENRIGHT: + return XK_parenright; + case OBS_KEY_ASTERISK: + return XK_asterisk; + case OBS_KEY_PLUS: + return XK_plus; + case OBS_KEY_COMMA: + return XK_comma; + case OBS_KEY_MINUS: + return XK_minus; + case OBS_KEY_PERIOD: + return XK_period; + case OBS_KEY_SLASH: + return XK_slash; + case OBS_KEY_0: + return XK_0; + case OBS_KEY_1: + return XK_1; + case OBS_KEY_2: + return XK_2; + case OBS_KEY_3: + return XK_3; + case OBS_KEY_4: + return XK_4; + case OBS_KEY_5: + return XK_5; + case OBS_KEY_6: + return XK_6; + case OBS_KEY_7: + return XK_7; + case OBS_KEY_8: + return XK_8; + case OBS_KEY_9: + return XK_9; + case OBS_KEY_NUMEQUAL: + return XK_KP_Equal; + case OBS_KEY_NUMASTERISK: + return XK_KP_Multiply; + case OBS_KEY_NUMPLUS: + return XK_KP_Add; + case OBS_KEY_NUMCOMMA: + return XK_KP_Separator; + case OBS_KEY_NUMMINUS: + return XK_KP_Subtract; + case OBS_KEY_NUMPERIOD: + return XK_KP_Decimal; + case OBS_KEY_NUMSLASH: + return XK_KP_Divide; + case OBS_KEY_NUM0: + return XK_KP_0; + case OBS_KEY_NUM1: + return XK_KP_1; + case OBS_KEY_NUM2: + return XK_KP_2; + case OBS_KEY_NUM3: + return XK_KP_3; + case OBS_KEY_NUM4: + return XK_KP_4; + case OBS_KEY_NUM5: + return XK_KP_5; + case OBS_KEY_NUM6: + return XK_KP_6; + case OBS_KEY_NUM7: + return XK_KP_7; + case OBS_KEY_NUM8: + return XK_KP_8; + case OBS_KEY_NUM9: + return XK_KP_9; + case OBS_KEY_COLON: + return XK_colon; + case OBS_KEY_SEMICOLON: + return XK_semicolon; + case OBS_KEY_LESS: + return XK_less; + case OBS_KEY_EQUAL: + return XK_equal; + case OBS_KEY_GREATER: + return XK_greater; + case OBS_KEY_QUESTION: + return XK_question; + case OBS_KEY_AT: + return XK_at; + case OBS_KEY_A: + return XK_A; + case OBS_KEY_B: + return XK_B; + case OBS_KEY_C: + return XK_C; + case OBS_KEY_D: + return XK_D; + case OBS_KEY_E: + return XK_E; + case OBS_KEY_F: + return XK_F; + case OBS_KEY_G: + return XK_G; + case OBS_KEY_H: + return XK_H; + case OBS_KEY_I: + return XK_I; + case OBS_KEY_J: + return XK_J; + case OBS_KEY_K: + return XK_K; + case OBS_KEY_L: + return XK_L; + case OBS_KEY_M: + return XK_M; + case OBS_KEY_N: + return XK_N; + case OBS_KEY_O: + return XK_O; + case OBS_KEY_P: + return XK_P; + case OBS_KEY_Q: + return XK_Q; + case OBS_KEY_R: + return XK_R; + case OBS_KEY_S: + return XK_S; + case OBS_KEY_T: + return XK_T; + case OBS_KEY_U: + return XK_U; + case OBS_KEY_V: + return XK_V; + case OBS_KEY_W: + return XK_W; + case OBS_KEY_X: + return XK_X; + case OBS_KEY_Y: + return XK_Y; + case OBS_KEY_Z: + return XK_Z; + case OBS_KEY_BRACKETLEFT: + return XK_bracketleft; + case OBS_KEY_BACKSLASH: + return XK_backslash; + case OBS_KEY_BRACKETRIGHT: + return XK_bracketright; + case OBS_KEY_ASCIICIRCUM: + return XK_asciicircum; + case OBS_KEY_UNDERSCORE: + return XK_underscore; + case OBS_KEY_QUOTELEFT: + return XK_quoteleft; + case OBS_KEY_BRACELEFT: + return XK_braceleft; + case OBS_KEY_BAR: + return XK_bar; + case OBS_KEY_BRACERIGHT: + return XK_braceright; + case OBS_KEY_ASCIITILDE: + return XK_grave; + case OBS_KEY_NOBREAKSPACE: + return XK_nobreakspace; + case OBS_KEY_EXCLAMDOWN: + return XK_exclamdown; + case OBS_KEY_CENT: + return XK_cent; + case OBS_KEY_STERLING: + return XK_sterling; + case OBS_KEY_CURRENCY: + return XK_currency; + case OBS_KEY_YEN: + return XK_yen; + case OBS_KEY_BROKENBAR: + return XK_brokenbar; + case OBS_KEY_SECTION: + return XK_section; + case OBS_KEY_DIAERESIS: + return XK_diaeresis; + case OBS_KEY_COPYRIGHT: + return XK_copyright; + case OBS_KEY_ORDFEMININE: + return XK_ordfeminine; + case OBS_KEY_GUILLEMOTLEFT: + return XK_guillemotleft; + case OBS_KEY_NOTSIGN: + return XK_notsign; + case OBS_KEY_HYPHEN: + return XK_hyphen; + case OBS_KEY_REGISTERED: + return XK_registered; + case OBS_KEY_MACRON: + return XK_macron; + case OBS_KEY_DEGREE: + return XK_degree; + case OBS_KEY_PLUSMINUS: + return XK_plusminus; + case OBS_KEY_TWOSUPERIOR: + return XK_twosuperior; + case OBS_KEY_THREESUPERIOR: + return XK_threesuperior; + case OBS_KEY_ACUTE: + return XK_acute; + case OBS_KEY_MU: + return XK_mu; + case OBS_KEY_PARAGRAPH: + return XK_paragraph; + case OBS_KEY_PERIODCENTERED: + return XK_periodcentered; + case OBS_KEY_CEDILLA: + return XK_cedilla; + case OBS_KEY_ONESUPERIOR: + return XK_onesuperior; + case OBS_KEY_MASCULINE: + return XK_masculine; + case OBS_KEY_GUILLEMOTRIGHT: + return XK_guillemotright; + case OBS_KEY_ONEQUARTER: + return XK_onequarter; + case OBS_KEY_ONEHALF: + return XK_onehalf; + case OBS_KEY_THREEQUARTERS: + return XK_threequarters; + case OBS_KEY_QUESTIONDOWN: + return XK_questiondown; + case OBS_KEY_AGRAVE: + return XK_Agrave; + case OBS_KEY_AACUTE: + return XK_Aacute; + case OBS_KEY_ACIRCUMFLEX: + return XK_Acircumflex; + case OBS_KEY_ATILDE: + return XK_Atilde; + case OBS_KEY_ADIAERESIS: + return XK_Adiaeresis; + case OBS_KEY_ARING: + return XK_Aring; + case OBS_KEY_AE: + return XK_AE; + case OBS_KEY_CCEDILLA: + return XK_cedilla; + case OBS_KEY_EGRAVE: + return XK_Egrave; + case OBS_KEY_EACUTE: + return XK_Eacute; + case OBS_KEY_ECIRCUMFLEX: + return XK_Ecircumflex; + case OBS_KEY_EDIAERESIS: + return XK_Ediaeresis; + case OBS_KEY_IGRAVE: + return XK_Igrave; + case OBS_KEY_IACUTE: + return XK_Iacute; + case OBS_KEY_ICIRCUMFLEX: + return XK_Icircumflex; + case OBS_KEY_IDIAERESIS: + return XK_Idiaeresis; + case OBS_KEY_ETH: + return XK_ETH; + case OBS_KEY_NTILDE: + return XK_Ntilde; + case OBS_KEY_OGRAVE: + return XK_Ograve; + case OBS_KEY_OACUTE: + return XK_Oacute; + case OBS_KEY_OCIRCUMFLEX: + return XK_Ocircumflex; + case OBS_KEY_ODIAERESIS: + return XK_Odiaeresis; + case OBS_KEY_MULTIPLY: + return XK_multiply; + case OBS_KEY_OOBLIQUE: + return XK_Ooblique; + case OBS_KEY_UGRAVE: + return XK_Ugrave; + case OBS_KEY_UACUTE: + return XK_Uacute; + case OBS_KEY_UCIRCUMFLEX: + return XK_Ucircumflex; + case OBS_KEY_UDIAERESIS: + return XK_Udiaeresis; + case OBS_KEY_YACUTE: + return XK_Yacute; + case OBS_KEY_THORN: + return XK_Thorn; + case OBS_KEY_SSHARP: + return XK_ssharp; + case OBS_KEY_DIVISION: + return XK_division; + case OBS_KEY_YDIAERESIS: + return XK_Ydiaeresis; + case OBS_KEY_MULTI_KEY: + return XK_Multi_key; + case OBS_KEY_CODEINPUT: + return XK_Codeinput; + case OBS_KEY_SINGLECANDIDATE: + return XK_SingleCandidate; + case OBS_KEY_MULTIPLECANDIDATE: + return XK_MultipleCandidate; + case OBS_KEY_PREVIOUSCANDIDATE: + return XK_PreviousCandidate; + case OBS_KEY_MODE_SWITCH: + return XK_Mode_switch; + case OBS_KEY_KANJI: + return XK_Kanji; + case OBS_KEY_MUHENKAN: + return XK_Muhenkan; + case OBS_KEY_HENKAN: + return XK_Henkan; + case OBS_KEY_ROMAJI: + return XK_Romaji; + case OBS_KEY_HIRAGANA: + return XK_Hiragana; + case OBS_KEY_KATAKANA: + return XK_Katakana; + case OBS_KEY_HIRAGANA_KATAKANA: + return XK_Hiragana_Katakana; + case OBS_KEY_ZENKAKU: + return XK_Zenkaku; + case OBS_KEY_HANKAKU: + return XK_Hankaku; + case OBS_KEY_ZENKAKU_HANKAKU: + return XK_Zenkaku_Hankaku; + case OBS_KEY_TOUROKU: + return XK_Touroku; + case OBS_KEY_MASSYO: + return XK_Massyo; + case OBS_KEY_KANA_LOCK: + return XK_Kana_Lock; + case OBS_KEY_KANA_SHIFT: + return XK_Kana_Shift; + case OBS_KEY_EISU_SHIFT: + return XK_Eisu_Shift; + case OBS_KEY_EISU_TOGGLE: + return XK_Eisu_toggle; + case OBS_KEY_HANGUL: + return XK_Hangul; + case OBS_KEY_HANGUL_START: + return XK_Hangul_Start; + case OBS_KEY_HANGUL_END: + return XK_Hangul_End; + case OBS_KEY_HANGUL_HANJA: + return XK_Hangul_Hanja; + case OBS_KEY_HANGUL_JAMO: + return XK_Hangul_Jamo; + case OBS_KEY_HANGUL_ROMAJA: + return XK_Hangul_Romaja; + case OBS_KEY_HANGUL_BANJA: + return XK_Hangul_Banja; + case OBS_KEY_HANGUL_PREHANJA: + return XK_Hangul_PreHanja; + case OBS_KEY_HANGUL_POSTHANJA: + return XK_Hangul_PostHanja; + case OBS_KEY_HANGUL_SPECIAL: + return XK_Hangul_Special; + case OBS_KEY_DEAD_GRAVE: + return XK_dead_grave; + case OBS_KEY_DEAD_ACUTE: + return XK_dead_acute; + case OBS_KEY_DEAD_CIRCUMFLEX: + return XK_dead_circumflex; + case OBS_KEY_DEAD_TILDE: + return XK_dead_tilde; + case OBS_KEY_DEAD_MACRON: + return XK_dead_macron; + case OBS_KEY_DEAD_BREVE: + return XK_dead_breve; + case OBS_KEY_DEAD_ABOVEDOT: + return XK_dead_abovedot; + case OBS_KEY_DEAD_DIAERESIS: + return XK_dead_diaeresis; + case OBS_KEY_DEAD_ABOVERING: + return XK_dead_abovering; + case OBS_KEY_DEAD_DOUBLEACUTE: + return XK_dead_doubleacute; + case OBS_KEY_DEAD_CARON: + return XK_dead_caron; + case OBS_KEY_DEAD_CEDILLA: + return XK_dead_cedilla; + case OBS_KEY_DEAD_OGONEK: + return XK_dead_ogonek; + case OBS_KEY_DEAD_IOTA: + return XK_dead_iota; + case OBS_KEY_DEAD_VOICED_SOUND: + return XK_dead_voiced_sound; + case OBS_KEY_DEAD_SEMIVOICED_SOUND: + return XK_dead_semivoiced_sound; + case OBS_KEY_DEAD_BELOWDOT: + return XK_dead_belowdot; + case OBS_KEY_DEAD_HOOK: + return XK_dead_hook; + case OBS_KEY_DEAD_HORN: + return XK_dead_horn; - case OBS_KEY_MOUSE1: return MOUSE_1; - case OBS_KEY_MOUSE2: return MOUSE_2; - case OBS_KEY_MOUSE3: return MOUSE_3; - case OBS_KEY_MOUSE4: return MOUSE_4; - case OBS_KEY_MOUSE5: return MOUSE_5; + case OBS_KEY_MOUSE1: + return MOUSE_1; + case OBS_KEY_MOUSE2: + return MOUSE_2; + case OBS_KEY_MOUSE3: + return MOUSE_3; + case OBS_KEY_MOUSE4: + return MOUSE_4; + case OBS_KEY_MOUSE5: + return MOUSE_5; /* TODO: Implement keys for non-US keyboards */ default:; @@ -661,7 +931,7 @@ static inline void fill_base_keysyms(struct obs_core_hotkeys *hotkeys) } static obs_key_t key_from_base_keysym(obs_hotkeys_platform_t *context, - xcb_keysym_t code) + xcb_keysym_t code) { for (size_t i = 0; i < OBS_KEY_LAST_VALUE; i++) { if (context->base_keysyms[i] == (xcb_keysym_t)code) { @@ -673,16 +943,17 @@ static obs_key_t key_from_base_keysym(obs_hotkeys_platform_t *context, } static inline void add_key(obs_hotkeys_platform_t *context, obs_key_t key, - int code) + int code) { xcb_keycode_t kc = (xcb_keycode_t)code; da_push_back(context->keycodes[key].list, &kc); if (context->keycodes[key].list.num > 1) { - blog(LOG_DEBUG, "found alternate keycode %d for %s " - "which already has keycode %d", - code, obs_key_to_name(key), - (int)context->keycodes[key].list.array[0]); + blog(LOG_DEBUG, + "found alternate keycode %d for %s " + "which already has keycode %d", + code, obs_key_to_name(key), + (int)context->keycodes[key].list.array[0]); } } @@ -701,8 +972,8 @@ static inline bool fill_keycodes(struct obs_core_hotkeys *hotkeys) context->min_keycode = setup->min_keycode; - cookie = xcb_get_keyboard_mapping(connection, - mincode, maxcode - mincode + 1); + cookie = xcb_get_keyboard_mapping(connection, mincode, + maxcode - mincode + 1); reply = xcb_get_keyboard_mapping_reply(connection, cookie, &error); @@ -716,8 +987,8 @@ static inline bool fill_keycodes(struct obs_core_hotkeys *hotkeys) context->num_keysyms = (maxcode - mincode + 1) * syms_per_code; context->syms_per_code = syms_per_code; - context->keysyms = bmemdup(keysyms, - sizeof(xcb_keysym_t) * context->num_keysyms); + context->keysyms = + bmemdup(keysyms, sizeof(xcb_keysym_t) * context->num_keysyms); for (code = mincode; code <= maxcode; code++) { const xcb_keysym_t *sym; @@ -744,7 +1015,6 @@ static inline bool fill_keycodes(struct obs_core_hotkeys *hotkeys) } } } - } error1: @@ -755,7 +1025,7 @@ error1: } static xcb_screen_t *default_screen(obs_hotkeys_platform_t *context, - xcb_connection_t *connection) + xcb_connection_t *connection) { int def_screen_idx = XDefaultScreen(context->display); xcb_screen_iterator_t iter; @@ -772,7 +1042,7 @@ static xcb_screen_t *default_screen(obs_hotkeys_platform_t *context, } static inline xcb_window_t root_window(obs_hotkeys_platform_t *context, - xcb_connection_t *connection) + xcb_connection_t *connection) { xcb_screen_t *screen = default_screen(context, connection); if (screen) @@ -783,19 +1053,18 @@ static inline xcb_window_t root_window(obs_hotkeys_platform_t *context, #if USE_XINPUT static inline void registerMouseEvents(struct obs_core_hotkeys *hotkeys) { - obs_hotkeys_platform_t *context = hotkeys->platform_context; - xcb_connection_t *connection = XGetXCBConnection( - context->display); - xcb_window_t window = root_window(context, connection); + obs_hotkeys_platform_t *context = hotkeys->platform_context; + xcb_connection_t *connection = XGetXCBConnection(context->display); + xcb_window_t window = root_window(context, connection); struct { - xcb_input_event_mask_t head; + xcb_input_event_mask_t head; xcb_input_xi_event_mask_t mask; } mask; mask.head.deviceid = XCB_INPUT_DEVICE_ALL_MASTER; mask.head.mask_len = sizeof(mask.mask) / sizeof(uint32_t); - mask.mask = XCB_INPUT_XI_EVENT_MASK_RAW_BUTTON_PRESS | - XCB_INPUT_XI_EVENT_MASK_RAW_BUTTON_RELEASE; + mask.mask = XCB_INPUT_XI_EVENT_MASK_RAW_BUTTON_PRESS | + XCB_INPUT_XI_EVENT_MASK_RAW_BUTTON_RELEASE; xcb_input_xi_select_events(connection, window, 1, &mask.head); xcb_flush(connection); @@ -834,7 +1103,7 @@ void obs_hotkeys_platform_free(struct obs_core_hotkeys *hotkeys) } static bool mouse_button_pressed(xcb_connection_t *connection, - obs_hotkeys_platform_t *context, obs_key_t key) + obs_hotkeys_platform_t *context, obs_key_t key) { bool ret = false; @@ -845,13 +1114,14 @@ static bool mouse_button_pressed(xcb_connection_t *connection, xcb_generic_event_t *ev; while ((ev = xcb_poll_for_event(connection))) { if ((ev->response_type & ~80) == XCB_GE_GENERIC) { - switch (((xcb_ge_event_t *) ev)->event_type) { + switch (((xcb_ge_event_t *)ev)->event_type) { case XCB_INPUT_RAW_BUTTON_PRESS: { xcb_input_raw_button_press_event_t *mot; - mot = (xcb_input_raw_button_press_event_t *) ev; + mot = (xcb_input_raw_button_press_event_t *)ev; if (mot->detail < XINPUT_MOUSE_LEN) { - context->pressed[mot->detail-1] = true; - context->update[mot->detail-1] = true; + context->pressed[mot->detail - 1] = + true; + context->update[mot->detail - 1] = true; } else { blog(LOG_WARNING, "Unsupported button"); } @@ -859,9 +1129,9 @@ static bool mouse_button_pressed(xcb_connection_t *connection, } case XCB_INPUT_RAW_BUTTON_RELEASE: { xcb_input_raw_button_release_event_t *mot; - mot = (xcb_input_raw_button_release_event_t *) ev; + mot = (xcb_input_raw_button_release_event_t *)ev; if (mot->detail < XINPUT_MOUSE_LEN) - context->update[mot->detail-1] = true; + context->update[mot->detail - 1] = true; else blog(LOG_WARNING, "Unsupported button"); break; @@ -984,9 +1254,15 @@ static bool mouse_button_pressed(xcb_connection_t *connection, uint16_t buttons = reply->mask; switch (key) { - case OBS_KEY_MOUSE1: ret = buttons & XCB_BUTTON_MASK_1; break; - case OBS_KEY_MOUSE2: ret = buttons & XCB_BUTTON_MASK_3; break; - case OBS_KEY_MOUSE3: ret = buttons & XCB_BUTTON_MASK_2; break; + case OBS_KEY_MOUSE1: + ret = buttons & XCB_BUTTON_MASK_1; + break; + case OBS_KEY_MOUSE2: + ret = buttons & XCB_BUTTON_MASK_3; + break; + case OBS_KEY_MOUSE3: + ret = buttons & XCB_BUTTON_MASK_2; + break; default:; } } @@ -998,27 +1274,27 @@ static bool mouse_button_pressed(xcb_connection_t *connection, } static inline bool keycode_pressed(xcb_query_keymap_reply_t *reply, - xcb_keycode_t code) + xcb_keycode_t code) { return (reply->keys[code / 8] & (1 << (code % 8))) != 0; } static bool key_pressed(xcb_connection_t *connection, - obs_hotkeys_platform_t *context, obs_key_t key) + obs_hotkeys_platform_t *context, obs_key_t key) { struct keycode_list *codes = &context->keycodes[key]; xcb_generic_error_t *error = NULL; xcb_query_keymap_reply_t *reply; bool pressed = false; - reply = xcb_query_keymap_reply(connection, - xcb_query_keymap(connection), &error); + reply = xcb_query_keymap_reply(connection, xcb_query_keymap(connection), + &error); if (error) { blog(LOG_WARNING, "xcb_query_keymap failed"); } else if (key == OBS_KEY_META) { pressed = keycode_pressed(reply, context->super_l_code) || - keycode_pressed(reply, context->super_r_code); + keycode_pressed(reply, context->super_r_code); } else { for (size_t i = 0; i < codes->list.num; i++) { @@ -1035,7 +1311,7 @@ static bool key_pressed(xcb_connection_t *connection, } bool obs_hotkeys_platform_is_pressed(obs_hotkeys_platform_t *context, - obs_key_t key) + obs_key_t key) { xcb_connection_t *conn = XGetXCBConnection(context->display); @@ -1079,7 +1355,7 @@ void obs_key_to_str(obs_key_t key, struct dstr *dstr) dstr_copy(dstr, obs->hotkeys.translations[key]); } else { dstr_printf(dstr, "Mouse %d", - (int)(key - OBS_KEY_MOUSE1 + 1)); + (int)(key - OBS_KEY_MOUSE1 + 1)); } return; } @@ -1089,7 +1365,7 @@ void obs_key_to_str(obs_key_t key, struct dstr *dstr) dstr_copy(dstr, obs->hotkeys.translations[key]); } else { dstr_printf(dstr, "Numpad %d", - (int)(key - OBS_KEY_NUM0)); + (int)(key - OBS_KEY_NUM0)); } return; } @@ -1098,41 +1374,69 @@ void obs_key_to_str(obs_key_t key, struct dstr *dstr) dstr_copy(dstr, obs_get_hotkey_translation(key, def)) switch (key) { - case OBS_KEY_INSERT: return translate_key(key, "Insert"); - case OBS_KEY_DELETE: return translate_key(key, "Delete"); - case OBS_KEY_HOME: return translate_key(key, "Home"); - case OBS_KEY_END: return translate_key(key, "End"); - case OBS_KEY_PAGEUP: return translate_key(key, "Page Up"); - case OBS_KEY_PAGEDOWN: return translate_key(key, "Page Down"); - case OBS_KEY_NUMLOCK: return translate_key(key, "Num Lock"); - case OBS_KEY_SCROLLLOCK: return translate_key(key, "Scroll Lock"); - case OBS_KEY_CAPSLOCK: return translate_key(key, "Caps Lock"); - case OBS_KEY_BACKSPACE: return translate_key(key, "Backspace"); - case OBS_KEY_TAB: return translate_key(key, "Tab"); - case OBS_KEY_PRINT: return translate_key(key, "Print"); - case OBS_KEY_PAUSE: return translate_key(key, "Pause"); - case OBS_KEY_LEFT: return translate_key(key, "Left"); - case OBS_KEY_RIGHT: return translate_key(key, "Right"); - case OBS_KEY_UP: return translate_key(key, "Up"); - case OBS_KEY_DOWN: return translate_key(key, "Down"); - case OBS_KEY_SHIFT: return translate_key(key, "Shift"); - case OBS_KEY_ALT: return translate_key(key, "Alt"); - case OBS_KEY_CONTROL: return translate_key(key, "Control"); - case OBS_KEY_META: return translate_key(key, "Super"); - case OBS_KEY_MENU: return translate_key(key, "Menu"); - case OBS_KEY_NUMASTERISK: return translate_key(key, "Numpad *"); - case OBS_KEY_NUMPLUS: return translate_key(key, "Numpad +"); - case OBS_KEY_NUMCOMMA: return translate_key(key, "Numpad ,"); - case OBS_KEY_NUMPERIOD: return translate_key(key, "Numpad ."); - case OBS_KEY_NUMSLASH: return translate_key(key, "Numpad /"); - case OBS_KEY_SPACE: return translate_key(key, "Space"); - case OBS_KEY_ESCAPE: return translate_key(key, "Escape"); + case OBS_KEY_INSERT: + return translate_key(key, "Insert"); + case OBS_KEY_DELETE: + return translate_key(key, "Delete"); + case OBS_KEY_HOME: + return translate_key(key, "Home"); + case OBS_KEY_END: + return translate_key(key, "End"); + case OBS_KEY_PAGEUP: + return translate_key(key, "Page Up"); + case OBS_KEY_PAGEDOWN: + return translate_key(key, "Page Down"); + case OBS_KEY_NUMLOCK: + return translate_key(key, "Num Lock"); + case OBS_KEY_SCROLLLOCK: + return translate_key(key, "Scroll Lock"); + case OBS_KEY_CAPSLOCK: + return translate_key(key, "Caps Lock"); + case OBS_KEY_BACKSPACE: + return translate_key(key, "Backspace"); + case OBS_KEY_TAB: + return translate_key(key, "Tab"); + case OBS_KEY_PRINT: + return translate_key(key, "Print"); + case OBS_KEY_PAUSE: + return translate_key(key, "Pause"); + case OBS_KEY_LEFT: + return translate_key(key, "Left"); + case OBS_KEY_RIGHT: + return translate_key(key, "Right"); + case OBS_KEY_UP: + return translate_key(key, "Up"); + case OBS_KEY_DOWN: + return translate_key(key, "Down"); + case OBS_KEY_SHIFT: + return translate_key(key, "Shift"); + case OBS_KEY_ALT: + return translate_key(key, "Alt"); + case OBS_KEY_CONTROL: + return translate_key(key, "Control"); + case OBS_KEY_META: + return translate_key(key, "Super"); + case OBS_KEY_MENU: + return translate_key(key, "Menu"); + case OBS_KEY_NUMASTERISK: + return translate_key(key, "Numpad *"); + case OBS_KEY_NUMPLUS: + return translate_key(key, "Numpad +"); + case OBS_KEY_NUMCOMMA: + return translate_key(key, "Numpad ,"); + case OBS_KEY_NUMPERIOD: + return translate_key(key, "Numpad ."); + case OBS_KEY_NUMSLASH: + return translate_key(key, "Numpad /"); + case OBS_KEY_SPACE: + return translate_key(key, "Space"); + case OBS_KEY_ESCAPE: + return translate_key(key, "Escape"); default:; } if (key >= OBS_KEY_F1 && key <= OBS_KEY_F35) { - dstr_printf(dstr, "F%d", - (int)(key - OBS_KEY_F1 + 1)); + dstr_printf(dstr, "F%d", (int)(key - OBS_KEY_F1 + 1)); return; } @@ -1151,7 +1455,7 @@ void obs_key_to_str(obs_key_t key, struct dstr *dstr) } static obs_key_t key_from_keycode(obs_hotkeys_platform_t *context, - xcb_keycode_t code) + xcb_keycode_t code) { for (size_t i = 0; i < OBS_KEY_LAST_VALUE; i++) { struct keycode_list *codes = &context->keycodes[i]; @@ -1214,7 +1518,7 @@ static inline void add_combo_key(obs_key_t key, struct dstr *str) } void obs_key_combination_to_str(obs_key_combination_t combination, - struct dstr *str) + struct dstr *str) { if ((combination.modifiers & INTERACT_CONTROL_KEY) != 0) { add_combo_key(OBS_KEY_CONTROL, str); diff --git a/libobs/obs-output-delay.c b/libobs/obs-output-delay.c index cfd3c57..10573e3 100644 --- a/libobs/obs-output-delay.c +++ b/libobs/obs-output-delay.c @@ -29,12 +29,12 @@ static inline bool delay_capturing(const struct obs_output *output) } static inline void push_packet(struct obs_output *output, - struct encoder_packet *packet, uint64_t t) + struct encoder_packet *packet, uint64_t t) { struct delay_data dd = {0}; dd.msg = DELAY_MSG_PACKET; - dd.ts = t; + dd.ts = t; obs_encoder_packet_create_instance(&dd.packet, packet); pthread_mutex_lock(&output->delay_mutex); @@ -43,7 +43,7 @@ static inline void push_packet(struct obs_output *output, } static inline void process_delay_data(struct obs_output *output, - struct delay_data *dd) + struct delay_data *dd) { switch (dd->msg) { case DELAY_MSG_PACKET: @@ -98,7 +98,7 @@ static inline bool pop_packet(struct obs_output *output, uint64_t t) } else if (elapsed_time > output->active_delay_ns) { circlebuf_pop_front(&output->delay_data, NULL, - sizeof(dd)); + sizeof(dd)); popped = true; } } @@ -118,7 +118,8 @@ void process_delay(void *data, struct encoder_packet *packet) struct obs_output *output = data; uint64_t t = os_gettime_ns(); push_packet(output, packet, t); - while (pop_packet(output, t)); + while (pop_packet(output, t)) + ; } void obs_output_signal_delay(obs_output_t *output, const char *signal) @@ -136,7 +137,7 @@ bool obs_output_delay_start(obs_output_t *output) { struct delay_data dd = { .msg = DELAY_MSG_START, - .ts = os_gettime_ns(), + .ts = os_gettime_ns(), }; if (!delay_active(output)) { @@ -170,7 +171,7 @@ void obs_output_delay_stop(obs_output_t *output) { struct delay_data dd = { .msg = DELAY_MSG_STOP, - .ts = os_gettime_ns(), + .ts = os_gettime_ns(), }; pthread_mutex_lock(&output->delay_mutex); @@ -181,15 +182,16 @@ void obs_output_delay_stop(obs_output_t *output) } void obs_output_set_delay(obs_output_t *output, uint32_t delay_sec, - uint32_t flags) + uint32_t flags) { if (!obs_output_valid(output, "obs_output_set_delay")) return; if ((output->info.flags & OBS_OUTPUT_ENCODED) == 0) { - blog(LOG_WARNING, "Output '%s': Tried to set a delay " - "value on a non-encoded output", - output->context.name); + blog(LOG_WARNING, + "Output '%s': Tried to set a delay " + "value on a non-encoded output", + output->context.name); return; } @@ -199,12 +201,14 @@ void obs_output_set_delay(obs_output_t *output, uint32_t delay_sec, uint32_t obs_output_get_delay(const obs_output_t *output) { - return obs_output_valid(output, "obs_output_set_delay") ? - output->delay_sec : 0; + return obs_output_valid(output, "obs_output_set_delay") + ? output->delay_sec + : 0; } uint32_t obs_output_get_active_delay(const obs_output_t *output) { - return obs_output_valid(output, "obs_output_set_delay") ? - (uint32_t)(output->active_delay_ns / 1000000000ULL) : 0; + return obs_output_valid(output, "obs_output_set_delay") + ? (uint32_t)(output->active_delay_ns / 1000000000ULL) + : 0; } diff --git a/libobs/obs-output.c b/libobs/obs-output.c index b8fe903..a680970 100644 --- a/libobs/obs-output.c +++ b/libobs/obs-output.c @@ -60,7 +60,7 @@ const struct obs_output_info *find_output(const char *id) size_t i; for (i = 0; i < obs->output_types.num; i++) if (strcmp(obs->output_types.array[i].id, id) == 0) - return obs->output_types.array+i; + return obs->output_types.array + i; return NULL; } @@ -74,20 +74,22 @@ const char *obs_output_get_display_name(const char *id) static const char *output_signals[] = { "void start(ptr output)", "void stop(ptr output, int code)", + "void pause(ptr output)", + "void unpause(ptr output)", "void starting(ptr output)", "void stopping(ptr output)", "void activate(ptr output)", "void deactivate(ptr output)", "void reconnect(ptr output)", "void reconnect_success(ptr output)", - NULL + NULL, }; static bool init_output_handlers(struct obs_output *output, const char *name, - obs_data_t *settings, obs_data_t *hotkey_data) + obs_data_t *settings, obs_data_t *hotkey_data) { if (!obs_context_data_init(&output->context, OBS_OBJ_TYPE_OUTPUT, - settings, name, hotkey_data, false)) + settings, name, hotkey_data, false)) return false; signal_handler_add_array(output->context.signals, output_signals); @@ -95,7 +97,7 @@ static bool init_output_handlers(struct obs_output *output, const char *name, } obs_output_t *obs_output_create(const char *id, const char *name, - obs_data_t *settings, obs_data_t *hotkey_data) + obs_data_t *settings, obs_data_t *hotkey_data) { const struct obs_output_info *info = find_output(id); struct obs_output *output; @@ -105,6 +107,7 @@ obs_output_t *obs_output_create(const char *id, const char *name, pthread_mutex_init_value(&output->interleaved_mutex); pthread_mutex_init_value(&output->delay_mutex); pthread_mutex_init_value(&output->caption_mutex); + pthread_mutex_init_value(&output->pause.mutex); if (pthread_mutex_init(&output->interleaved_mutex, NULL) != 0) goto fail; @@ -112,6 +115,8 @@ obs_output_t *obs_output_create(const char *id, const char *name, goto fail; if (pthread_mutex_init(&output->caption_mutex, NULL) != 0) goto fail; + if (pthread_mutex_init(&output->pause.mutex, NULL) != 0) + goto fail; if (os_event_init(&output->stopping_event, OS_EVENT_TYPE_MANUAL) != 0) goto fail; if (!init_output_handlers(output, name, settings, hotkey_data)) @@ -122,35 +127,34 @@ obs_output_t *obs_output_create(const char *id, const char *name, if (!info) { blog(LOG_ERROR, "Output ID '%s' not found", id); - output->info.id = bstrdup(id); + output->info.id = bstrdup(id); output->owns_info_id = true; } else { output->info = *info; } - output->video = obs_get_video(); - output->audio = obs_get_audio(); + output->video = obs_get_video(); + output->audio = obs_get_audio(); if (output->info.get_defaults) output->info.get_defaults(output->context.settings); ret = os_event_init(&output->reconnect_stop_event, - OS_EVENT_TYPE_MANUAL); + OS_EVENT_TYPE_MANUAL); if (ret < 0) goto fail; output->reconnect_retry_sec = 2; output->reconnect_retry_max = 20; - output->valid = true; + output->valid = true; output->control = bzalloc(sizeof(obs_weak_output_t)); output->control->output = output; - obs_context_data_insert(&output->context, - &obs->data.outputs_mutex, - &obs->data.first_output); + obs_context_data_insert(&output->context, &obs->data.outputs_mutex, + &obs->data.first_output); if (info) - output->context.data = info->create(output->context.settings, - output); + output->context.data = + info->create(output->context.settings, output); if (!output->context.data) blog(LOG_ERROR, "Failed to create output '%s'!", name); @@ -165,10 +169,20 @@ fail: static inline void free_packets(struct obs_output *output) { for (size_t i = 0; i < output->interleaved_packets.num; i++) - obs_encoder_packet_release(output->interleaved_packets.array+i); + obs_encoder_packet_release(output->interleaved_packets.array + + i); da_free(output->interleaved_packets); } +static inline void clear_audio_buffers(obs_output_t *output) +{ + for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { + for (size_t j = 0; j < MAX_AV_PLANES; j++) { + circlebuf_free(&output->audio_buffer[i][j]); + } + } +} + void obs_output_destroy(obs_output_t *output) { if (output) { @@ -192,18 +206,20 @@ void obs_output_destroy(obs_output_t *output) if (output->video_encoder) { obs_encoder_remove_output(output->video_encoder, - output); + output); } for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { if (output->audio_encoders[i]) { obs_encoder_remove_output( - output->audio_encoders[i], - output); + output->audio_encoders[i], output); } } + clear_audio_buffers(output); + os_event_destroy(output->stopping_event); + pthread_mutex_destroy(&output->pause.mutex); pthread_mutex_destroy(&output->caption_mutex); pthread_mutex_destroy(&output->interleaved_mutex); pthread_mutex_destroy(&output->delay_mutex); @@ -211,7 +227,7 @@ void obs_output_destroy(obs_output_t *output) obs_context_data_free(&output->context); circlebuf_free(&output->delay_data); if (output->owns_info_id) - bfree((void*)output->info.id); + bfree((void *)output->info.id); if (output->last_error_message) bfree(output->last_error_message); bfree(output); @@ -220,8 +236,9 @@ void obs_output_destroy(obs_output_t *output) const char *obs_output_get_name(const obs_output_t *output) { - return obs_output_valid(output, "obs_output_get_name") ? - output->context.name : NULL; + return obs_output_valid(output, "obs_output_get_name") + ? output->context.name + : NULL; } bool obs_output_actual_start(obs_output_t *output) @@ -287,7 +304,7 @@ static void log_frame_info(struct obs_output *output) { struct obs_core_video *video = &obs->video; - uint32_t drawn = video->total_frames - output->starting_drawn_count; + uint32_t drawn = video->total_frames - output->starting_drawn_count; uint32_t lagged = video->lagged_frames - output->starting_lagged_count; int dropped = obs_output_get_frames_dropped(output); @@ -297,38 +314,40 @@ static void log_frame_info(struct obs_output *output) double percentage_dropped = 0.0f; if (drawn) - percentage_lagged = (double)lagged / (double)drawn * 100.0; + percentage_lagged = (double)lagged / (double)drawn * 100.0; if (dropped) percentage_dropped = (double)dropped / (double)total * 100.0; blog(LOG_INFO, "Output '%s': stopping", output->context.name); if (!dropped || !total) blog(LOG_INFO, "Output '%s': Total frames output: %d", - output->context.name, total); + output->context.name, total); else - blog(LOG_INFO, "Output '%s': Total frames output: %d" - " (%d attempted)", - output->context.name, total - dropped, total); + blog(LOG_INFO, + "Output '%s': Total frames output: %d" + " (%d attempted)", + output->context.name, total - dropped, total); if (!lagged || !drawn) - blog(LOG_INFO, "Output '%s': Total drawn frames: %"PRIu32, - output->context.name, drawn); + blog(LOG_INFO, "Output '%s': Total drawn frames: %" PRIu32, + output->context.name, drawn); else - blog(LOG_INFO, "Output '%s': Total drawn frames: %"PRIu32 - " (%"PRIu32" attempted)", - output->context.name, drawn - lagged, drawn); + blog(LOG_INFO, + "Output '%s': Total drawn frames: %" PRIu32 " (%" PRIu32 + " attempted)", + output->context.name, drawn - lagged, drawn); if (drawn && lagged) - blog(LOG_INFO, "Output '%s': Number of lagged frames due " - "to rendering lag/stalls: %"PRIu32" (%0.1f%%)", - output->context.name, - lagged, percentage_lagged); + blog(LOG_INFO, + "Output '%s': Number of lagged frames due " + "to rendering lag/stalls: %" PRIu32 " (%0.1f%%)", + output->context.name, lagged, percentage_lagged); if (total && dropped) - blog(LOG_INFO, "Output '%s': Number of dropped frames due " - "to insufficient bandwidth/connection stalls: " - "%d (%0.1f%%)", - output->context.name, - dropped, percentage_dropped); + blog(LOG_INFO, + "Output '%s': Number of dropped frames due " + "to insufficient bandwidth/connection stalls: " + "%d (%0.1f%%)", + output->context.name, dropped, percentage_dropped); } static inline void signal_stop(struct obs_output *output); @@ -340,6 +359,9 @@ void obs_output_actual_stop(obs_output_t *output, bool force, uint64_t ts) if (stopping(output) && !force) return; + + obs_output_pause(output, false); + os_event_reset(output->stopping_event); was_reconnecting = reconnecting(output) && !delay_active(output); @@ -419,14 +441,15 @@ void obs_output_force_stop(obs_output_t *output) bool obs_output_active(const obs_output_t *output) { - return (output != NULL) ? - (active(output) || reconnecting(output)) : false; + return (output != NULL) ? (active(output) || reconnecting(output)) + : false; } uint32_t obs_output_get_flags(const obs_output_t *output) { - return obs_output_valid(output, "obs_output_get_flags") ? - output->info.flags : 0; + return obs_output_valid(output, "obs_output_get_flags") + ? output->info.flags + : 0; } uint32_t obs_get_output_flags(const char *id) @@ -453,7 +476,7 @@ obs_properties_t *obs_get_output_properties(const char *id) { const struct obs_output_info *info = find_output(id); if (info && info->get_properties) { - obs_data_t *defaults = get_defaults(info); + obs_data_t *defaults = get_defaults(info); obs_properties_t *properties; properties = info->get_properties(NULL); @@ -488,7 +511,7 @@ void obs_output_update(obs_output_t *output, obs_data_t *settings) if (output->info.update) output->info.update(output->context.data, - output->context.settings); + output->context.settings); } obs_data_t *obs_output_get_settings(const obs_output_t *output) @@ -502,29 +525,196 @@ obs_data_t *obs_output_get_settings(const obs_output_t *output) bool obs_output_can_pause(const obs_output_t *output) { - return obs_output_valid(output, "obs_output_can_pause") ? - (output->info.pause != NULL) : false; + return obs_output_valid(output, "obs_output_can_pause") + ? !!(output->info.flags & OBS_OUTPUT_CAN_PAUSE) + : false; } -void obs_output_pause(obs_output_t *output) +static inline void end_pause(struct pause_data *pause, uint64_t ts) { - if (!obs_output_valid(output, "obs_output_pause")) - return; + if (!pause->ts_end) { + pause->ts_end = ts; + pause->ts_offset += pause->ts_end - pause->ts_start; + } +} - if (output->info.pause) - output->info.pause(output->context.data); +static inline uint64_t get_closest_v_ts(struct pause_data *pause) +{ + uint64_t interval = obs->video.video_frame_interval_ns; + uint64_t i2 = interval * 2; + uint64_t ts = os_gettime_ns(); + + return pause->last_video_ts + + ((ts - pause->last_video_ts + i2) / interval) * interval; +} + +static inline bool pause_can_start(struct pause_data *pause) +{ + return !pause->ts_start && !pause->ts_end; +} + +static inline bool pause_can_stop(struct pause_data *pause) +{ + return !!pause->ts_start && !pause->ts_end; +} + +static bool obs_encoded_output_pause(obs_output_t *output, bool pause) +{ + obs_encoder_t *venc; + obs_encoder_t *aenc[MAX_AUDIO_MIXES]; + uint64_t closest_v_ts; + bool success = false; + + venc = output->video_encoder; + for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) + aenc[i] = output->audio_encoders[i]; + + pthread_mutex_lock(&venc->pause.mutex); + for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { + if (aenc[i]) { + pthread_mutex_lock(&aenc[i]->pause.mutex); + } + } + + /* ---------------------------- */ + + closest_v_ts = get_closest_v_ts(&venc->pause); + + if (pause) { + if (!pause_can_start(&venc->pause)) { + goto fail; + } + for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { + if (aenc[i] && !pause_can_start(&aenc[i]->pause)) { + goto fail; + } + } + + os_atomic_set_bool(&venc->paused, true); + venc->pause.ts_start = closest_v_ts; + + for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { + if (aenc[i]) { + os_atomic_set_bool(&aenc[i]->paused, true); + aenc[i]->pause.ts_start = closest_v_ts; + } + } + } else { + if (!pause_can_stop(&venc->pause)) { + goto fail; + } + for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { + if (aenc[i] && !pause_can_stop(&aenc[i]->pause)) { + goto fail; + } + } + + os_atomic_set_bool(&venc->paused, false); + end_pause(&venc->pause, closest_v_ts); + + for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { + if (aenc[i]) { + os_atomic_set_bool(&aenc[i]->paused, false); + end_pause(&aenc[i]->pause, closest_v_ts); + } + } + } + + /* ---------------------------- */ + + success = true; + +fail: + for (size_t i = MAX_AUDIO_MIXES; i > 0; i--) { + if (aenc[i - 1]) { + pthread_mutex_unlock(&aenc[i - 1]->pause.mutex); + } + } + pthread_mutex_unlock(&venc->pause.mutex); + + return success; +} + +static bool obs_raw_output_pause(obs_output_t *output, bool pause) +{ + bool success; + uint64_t closest_v_ts; + + pthread_mutex_lock(&output->pause.mutex); + closest_v_ts = get_closest_v_ts(&output->pause); + if (pause) { + success = pause_can_start(&output->pause); + if (success) + output->pause.ts_start = closest_v_ts; + } else { + success = pause_can_stop(&output->pause); + if (success) + end_pause(&output->pause, closest_v_ts); + } + pthread_mutex_unlock(&output->pause.mutex); + + return success; +} + +bool obs_output_pause(obs_output_t *output, bool pause) +{ + bool success; + + if (!obs_output_valid(output, "obs_output_pause")) + return false; + if ((output->info.flags & OBS_OUTPUT_CAN_PAUSE) == 0) + return false; + if (!os_atomic_load_bool(&output->active)) + return false; + if (os_atomic_load_bool(&output->paused) == pause) + return true; + + success = ((output->info.flags & OBS_OUTPUT_ENCODED) != 0) + ? obs_encoded_output_pause(output, pause) + : obs_raw_output_pause(output, pause); + if (success) { + os_atomic_set_bool(&output->paused, pause); + do_output_signal(output, pause ? "pause" : "unpause"); + + blog(LOG_INFO, "output %s %spaused", output->context.name, + pause ? "" : "un"); + } + return success; +} + +bool obs_output_paused(const obs_output_t *output) +{ + return obs_output_valid(output, "obs_output_paused") + ? os_atomic_load_bool(&output->paused) + : false; +} + +uint64_t obs_output_get_pause_offset(obs_output_t *output) +{ + uint64_t offset; + + if (!obs_output_valid(output, "obs_output_get_pause_offset")) + return 0; + + pthread_mutex_lock(&output->pause.mutex); + offset = output->pause.ts_offset; + pthread_mutex_unlock(&output->pause.mutex); + + return offset; } signal_handler_t *obs_output_get_signal_handler(const obs_output_t *output) { - return obs_output_valid(output, "obs_output_get_signal_handler") ? - output->context.signals : NULL; + return obs_output_valid(output, "obs_output_get_signal_handler") + ? output->context.signals + : NULL; } proc_handler_t *obs_output_get_proc_handler(const obs_output_t *output) { - return obs_output_valid(output, "obs_output_get_proc_handler") ? - output->context.procs : NULL; + return obs_output_valid(output, "obs_output_get_proc_handler") + ? output->context.procs + : NULL; } void obs_output_set_media(obs_output_t *output, video_t *video, audio_t *audio) @@ -538,14 +728,14 @@ void obs_output_set_media(obs_output_t *output, video_t *video, audio_t *audio) video_t *obs_output_video(const obs_output_t *output) { - return obs_output_valid(output, "obs_output_video") ? - output->video : NULL; + return obs_output_valid(output, "obs_output_video") ? output->video + : NULL; } audio_t *obs_output_audio(const obs_output_t *output) { - return obs_output_valid(output, "obs_output_audio") ? - output->audio : NULL; + return obs_output_valid(output, "obs_output_audio") ? output->audio + : NULL; } static inline size_t get_first_mixer(const obs_output_t *output) @@ -586,12 +776,13 @@ void obs_output_set_mixers(obs_output_t *output, size_t mixers) size_t obs_output_get_mixers(const obs_output_t *output) { - return obs_output_valid(output, "obs_output_get_mixers") ? - output->mixer_mask : 0; + return obs_output_valid(output, "obs_output_get_mixers") + ? output->mixer_mask + : 0; } void obs_output_remove_encoder(struct obs_output *output, - struct obs_encoder *encoder) + struct obs_encoder *encoder) { if (!obs_output_valid(output, "obs_output_remove_encoder")) return; @@ -612,11 +803,12 @@ void obs_output_set_video_encoder(obs_output_t *output, obs_encoder_t *encoder) return; if (encoder && encoder->info.type != OBS_ENCODER_VIDEO) { blog(LOG_WARNING, "obs_output_set_video_encoder: " - "encoder passed is not a video encoder"); + "encoder passed is not a video encoder"); return; } - if (output->video_encoder == encoder) return; + if (output->video_encoder == encoder) + return; obs_encoder_remove_output(output->video_encoder, output); obs_encoder_add_output(encoder, output); @@ -625,17 +817,18 @@ void obs_output_set_video_encoder(obs_output_t *output, obs_encoder_t *encoder) /* set the preferred resolution on the encoder */ if (output->scaled_width && output->scaled_height) obs_encoder_set_scaled_size(output->video_encoder, - output->scaled_width, output->scaled_height); + output->scaled_width, + output->scaled_height); } void obs_output_set_audio_encoder(obs_output_t *output, obs_encoder_t *encoder, - size_t idx) + size_t idx) { if (!obs_output_valid(output, "obs_output_set_audio_encoder")) return; if (encoder && encoder->info.type != OBS_ENCODER_AUDIO) { blog(LOG_WARNING, "obs_output_set_audio_encoder: " - "encoder passed is not an audio encoder"); + "encoder passed is not an audio encoder"); return; } @@ -649,7 +842,8 @@ void obs_output_set_audio_encoder(obs_output_t *output, obs_encoder_t *encoder, } } - if (output->audio_encoders[idx] == encoder) return; + if (output->audio_encoders[idx] == encoder) + return; obs_encoder_remove_output(output->audio_encoders[idx], output); obs_encoder_add_output(encoder, output); @@ -658,12 +852,13 @@ void obs_output_set_audio_encoder(obs_output_t *output, obs_encoder_t *encoder, obs_encoder_t *obs_output_get_video_encoder(const obs_output_t *output) { - return obs_output_valid(output, "obs_output_get_video_encoder") ? - output->video_encoder : NULL; + return obs_output_valid(output, "obs_output_get_video_encoder") + ? output->video_encoder + : NULL; } obs_encoder_t *obs_output_get_audio_encoder(const obs_output_t *output, - size_t idx) + size_t idx) { if (!obs_output_valid(output, "obs_output_get_audio_encoder")) return NULL; @@ -697,12 +892,13 @@ void obs_output_set_service(obs_output_t *output, obs_service_t *service) obs_service_t *obs_output_get_service(const obs_output_t *output) { - return obs_output_valid(output, "obs_output_get_service") ? - output->service : NULL; + return obs_output_valid(output, "obs_output_get_service") + ? output->service + : NULL; } -void obs_output_set_reconnect_settings(obs_output_t *output, - int retry_count, int retry_sec) +void obs_output_set_reconnect_settings(obs_output_t *output, int retry_count, + int retry_sec) { if (!obs_output_valid(output, "obs_output_set_reconnect_settings")) return; @@ -736,12 +932,13 @@ int obs_output_get_frames_dropped(const obs_output_t *output) int obs_output_get_total_frames(const obs_output_t *output) { - return obs_output_valid(output, "obs_output_get_total_frames") ? - output->total_frames : 0; + return obs_output_valid(output, "obs_output_get_total_frames") + ? output->total_frames + : 0; } void obs_output_set_preferred_size(obs_output_t *output, uint32_t width, - uint32_t height) + uint32_t height) { if (!obs_output_valid(output, "obs_output_set_preferred_size")) return; @@ -749,19 +946,20 @@ void obs_output_set_preferred_size(obs_output_t *output, uint32_t width, return; if (active(output)) { - blog(LOG_WARNING, "output '%s': Cannot set the preferred " - "resolution while the output is active", - obs_output_get_name(output)); + blog(LOG_WARNING, + "output '%s': Cannot set the preferred " + "resolution while the output is active", + obs_output_get_name(output)); return; } - output->scaled_width = width; + output->scaled_width = width; output->scaled_height = height; if (output->info.flags & OBS_OUTPUT_ENCODED) { if (output->video_encoder) obs_encoder_set_scaled_size(output->video_encoder, - width, height); + width, height); } } @@ -775,9 +973,9 @@ uint32_t obs_output_get_width(const obs_output_t *output) if (output->info.flags & OBS_OUTPUT_ENCODED) return obs_encoder_get_width(output->video_encoder); else - return output->scaled_width != 0 ? - output->scaled_width : - video_output_get_width(output->video); + return output->scaled_width != 0 + ? output->scaled_width + : video_output_get_width(output->video); } uint32_t obs_output_get_height(const obs_output_t *output) @@ -790,13 +988,13 @@ uint32_t obs_output_get_height(const obs_output_t *output) if (output->info.flags & OBS_OUTPUT_ENCODED) return obs_encoder_get_height(output->video_encoder); else - return output->scaled_height != 0 ? - output->scaled_height : - video_output_get_height(output->video); + return output->scaled_height != 0 + ? output->scaled_height + : video_output_get_height(output->video); } void obs_output_set_video_conversion(obs_output_t *output, - const struct video_scale_info *conversion) + const struct video_scale_info *conversion) { if (!obs_output_valid(output, "obs_output_set_video_conversion")) return; @@ -807,8 +1005,8 @@ void obs_output_set_video_conversion(obs_output_t *output, output->video_conversion_set = true; } -void obs_output_set_audio_conversion(obs_output_t *output, - const struct audio_convert_info *conversion) +void obs_output_set_audio_conversion( + obs_output_t *output, const struct audio_convert_info *conversion) { if (!obs_output_valid(output, "obs_output_set_audio_conversion")) return; @@ -875,7 +1073,8 @@ static inline bool audio_valid(const struct obs_output *output, bool encoded) } static bool can_begin_data_capture(const struct obs_output *output, - bool encoded, bool has_video, bool has_audio, bool has_service) + bool encoded, bool has_video, bool has_audio, + bool has_service) { if (has_video) { if (encoded) { @@ -901,16 +1100,16 @@ static bool can_begin_data_capture(const struct obs_output *output, static inline bool has_scaling(const struct obs_output *output) { - uint32_t video_width = video_output_get_width(output->video); + uint32_t video_width = video_output_get_width(output->video); uint32_t video_height = video_output_get_height(output->video); return output->scaled_width && output->scaled_height && - (video_width != output->scaled_width || - video_height != output->scaled_height); + (video_width != output->scaled_width || + video_height != output->scaled_height); } -static inline struct video_scale_info *get_video_conversion( - struct obs_output *output) +static inline struct video_scale_info * +get_video_conversion(struct obs_output *output) { if (output->video_conversion_set) { if (!output->video_conversion.width) @@ -927,25 +1126,25 @@ static inline struct video_scale_info *get_video_conversion( const struct video_output_info *info = video_output_get_info(output->video); - output->video_conversion.format = info->format; + output->video_conversion.format = info->format; output->video_conversion.colorspace = VIDEO_CS_DEFAULT; - output->video_conversion.range = VIDEO_RANGE_DEFAULT; - output->video_conversion.width = output->scaled_width; - output->video_conversion.height = output->scaled_height; + output->video_conversion.range = VIDEO_RANGE_DEFAULT; + output->video_conversion.width = output->scaled_width; + output->video_conversion.height = output->scaled_height; return &output->video_conversion; } return NULL; } -static inline struct audio_convert_info *get_audio_conversion( - struct obs_output *output) +static inline struct audio_convert_info * +get_audio_conversion(struct obs_output *output) { return output->audio_conversion_set ? &output->audio_conversion : NULL; } static size_t get_track_index(const struct obs_output *output, - struct encoder_packet *pkt) + struct encoder_packet *pkt) { for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { struct obs_encoder *encoder = output->audio_encoders[i]; @@ -959,7 +1158,7 @@ static size_t get_track_index(const struct obs_output *output, } static inline void check_received(struct obs_output *output, - struct encoder_packet *out) + struct encoder_packet *out) { if (out->type == OBS_ENCODER_VIDEO) { if (!output->received_video) @@ -971,7 +1170,7 @@ static inline void check_received(struct obs_output *output, } static inline void apply_interleaved_packet_offset(struct obs_output *output, - struct encoder_packet *out) + struct encoder_packet *out) { int64_t offset; @@ -979,8 +1178,9 @@ static inline void apply_interleaved_packet_offset(struct obs_output *output, * may not currently be at 0 when we get data. so, we store the * current dts as offset and subtract that value from the dts/pts * of the output packet. */ - offset = (out->type == OBS_ENCODER_VIDEO) ? - output->video_offset : output->audio_offsets[out->track_idx]; + offset = (out->type == OBS_ENCODER_VIDEO) + ? output->video_offset + : output->audio_offsets[out->track_idx]; out->dts -= offset; out->pts -= offset; @@ -995,7 +1195,7 @@ static inline void apply_interleaved_packet_offset(struct obs_output *output, } static inline bool has_higher_opposing_ts(struct obs_output *output, - struct encoder_packet *packet) + struct encoder_packet *packet) { if (packet->type == OBS_ENCODER_VIDEO) return output->highest_audio_ts > packet->dts_usec; @@ -1041,7 +1241,7 @@ static bool add_caption(struct obs_output *output, struct encoder_packet *out) obs_encoder_packet_release(out); *out = backup; - out->data = (uint8_t*)out_data.array + sizeof(ref); + out->data = (uint8_t *)out_data.array + sizeof(ref); out->size = out_data.num - sizeof(ref); sei_free(&sei); @@ -1071,14 +1271,13 @@ static inline void send_interleaved(struct obs_output *output) #if BUILD_CAPTIONS pthread_mutex_lock(&output->caption_mutex); - double frame_timestamp = (out.pts * out.timebase_num) / - (double)out.timebase_den; + double frame_timestamp = + (out.pts * out.timebase_num) / (double)out.timebase_den; if (output->caption_head && output->caption_timestamp <= frame_timestamp) { - blog(LOG_DEBUG,"Sending caption: %f \"%s\"", - frame_timestamp, - &output->caption_head->text[0]); + blog(LOG_DEBUG, "Sending caption: %f \"%s\"", + frame_timestamp, &output->caption_head->text[0]); double display_duration = output->caption_head->display_duration; @@ -1098,7 +1297,7 @@ static inline void send_interleaved(struct obs_output *output) } static inline void set_higher_ts(struct obs_output *output, - struct encoder_packet *packet) + struct encoder_packet *packet) { if (packet->type == OBS_ENCODER_VIDEO) { if (output->highest_video_ts < packet->dts_usec) @@ -1109,18 +1308,19 @@ static inline void set_higher_ts(struct obs_output *output, } } -static inline struct encoder_packet *find_first_packet_type( - struct obs_output *output, enum obs_encoder_type type, - size_t audio_idx); +static inline struct encoder_packet * +find_first_packet_type(struct obs_output *output, enum obs_encoder_type type, + size_t audio_idx); static int find_first_packet_type_idx(struct obs_output *output, - enum obs_encoder_type type, size_t audio_idx); + enum obs_encoder_type type, + size_t audio_idx); /* gets the point where audio and video are closest together */ static size_t get_interleaved_start_idx(struct obs_output *output) { int64_t closest_diff = 0x7FFFFFFFFFFFFFFFLL; - struct encoder_packet *first_video = find_first_packet_type(output, - OBS_ENCODER_VIDEO, 0); + struct encoder_packet *first_video = + find_first_packet_type(output, OBS_ENCODER_VIDEO, 0); size_t video_idx = DARRAY_INVALID; size_t idx = 0; @@ -1170,7 +1370,7 @@ static int prune_premature_packets(struct obs_output *output) int audio_idx; audio_idx = find_first_packet_type_idx(output, - OBS_ENCODER_AUDIO, i); + OBS_ENCODER_AUDIO, i); if (audio_idx == -1) { output->received_audio = false; return -1; @@ -1212,10 +1412,9 @@ static bool prune_interleaved_packets(struct obs_output *output) struct encoder_packet *packet = &output->interleaved_packets.array[i]; blog(LOG_DEBUG, "packet: %s %d, ts: %lld, pruned = %s", - packet->type == OBS_ENCODER_AUDIO ? - "audio" : "video", (int)packet->track_idx, - packet->dts_usec, - (int)i < prune_start ? "true" : "false"); + packet->type == OBS_ENCODER_AUDIO ? "audio" : "video", + (int)packet->track_idx, packet->dts_usec, + (int)i < prune_start ? "true" : "false"); } #endif @@ -1234,7 +1433,8 @@ static bool prune_interleaved_packets(struct obs_output *output) } static int find_first_packet_type_idx(struct obs_output *output, - enum obs_encoder_type type, size_t audio_idx) + enum obs_encoder_type type, + size_t audio_idx) { for (size_t i = 0; i < output->interleaved_packets.num; i++) { struct encoder_packet *packet = @@ -1254,7 +1454,8 @@ static int find_first_packet_type_idx(struct obs_output *output, } static int find_last_packet_type_idx(struct obs_output *output, - enum obs_encoder_type type, size_t audio_idx) + enum obs_encoder_type type, + size_t audio_idx) { for (size_t i = output->interleaved_packets.num; i > 0; i--) { struct encoder_packet *packet = @@ -1273,25 +1474,26 @@ static int find_last_packet_type_idx(struct obs_output *output, return -1; } -static inline struct encoder_packet *find_first_packet_type( - struct obs_output *output, enum obs_encoder_type type, - size_t audio_idx) +static inline struct encoder_packet * +find_first_packet_type(struct obs_output *output, enum obs_encoder_type type, + size_t audio_idx) { int idx = find_first_packet_type_idx(output, type, audio_idx); return (idx != -1) ? &output->interleaved_packets.array[idx] : NULL; } -static inline struct encoder_packet *find_last_packet_type( - struct obs_output *output, enum obs_encoder_type type, - size_t audio_idx) +static inline struct encoder_packet * +find_last_packet_type(struct obs_output *output, enum obs_encoder_type type, + size_t audio_idx) { int idx = find_last_packet_type_idx(output, type, audio_idx); return (idx != -1) ? &output->interleaved_packets.array[idx] : NULL; } static bool get_audio_and_video_packets(struct obs_output *output, - struct encoder_packet **video, - struct encoder_packet **audio, size_t audio_mixes) + struct encoder_packet **video, + struct encoder_packet **audio, + size_t audio_mixes) { *video = find_first_packet_type(output, OBS_ENCODER_VIDEO, 0); if (!*video) @@ -1324,8 +1526,8 @@ static bool initialize_interleaved_packets(struct obs_output *output) return false; for (size_t i = 0; i < audio_mixes; i++) - last_audio[i] = find_last_packet_type(output, OBS_ENCODER_AUDIO, - i); + last_audio[i] = + find_last_packet_type(output, OBS_ENCODER_AUDIO, i); /* ensure that there is audio past the first video packet */ for (size_t i = 0; i < audio_mixes; i++) { @@ -1340,7 +1542,7 @@ static bool initialize_interleaved_packets(struct obs_output *output) if (start_idx) { discard_to_idx(output, start_idx); if (!get_audio_and_video_packets(output, &video, audio, - audio_mixes)) + audio_mixes)) return false; } @@ -1354,9 +1556,10 @@ static bool initialize_interleaved_packets(struct obs_output *output) int64_t a = audio[0]->dts_usec; int64_t diff = v - a; - blog(LOG_DEBUG, "output '%s' offset for video: %lld, audio: %lld, " - "diff: %lldms", output->context.name, v, a, - diff / 1000LL); + blog(LOG_DEBUG, + "output '%s' offset for video: %lld, audio: %lld, " + "diff: %lldms", + output->context.name, v, a, diff / 1000LL); #endif /* subtract offsets from highest TS offset variables */ @@ -1374,7 +1577,7 @@ static bool initialize_interleaved_packets(struct obs_output *output) } static inline void insert_interleaved_packet(struct obs_output *output, - struct encoder_packet *out) + struct encoder_packet *out) { size_t idx; for (idx = 0; idx < output->interleaved_packets.num; idx++) { @@ -1398,7 +1601,7 @@ static void resort_interleaved_packets(struct obs_output *output) old_array.da = output->interleaved_packets.da; memset(&output->interleaved_packets, 0, - sizeof(output->interleaved_packets)); + sizeof(output->interleaved_packets)); for (size_t i = 0; i < old_array.num; i++) insert_interleaved_packet(output, &old_array.array[i]); @@ -1407,7 +1610,7 @@ static void resort_interleaved_packets(struct obs_output *output) } static void discard_unused_audio_packets(struct obs_output *output, - int64_t dts_usec) + int64_t dts_usec) { size_t idx = 0; @@ -1425,9 +1628,9 @@ static void discard_unused_audio_packets(struct obs_output *output, static void interleave_packets(void *data, struct encoder_packet *packet) { - struct obs_output *output = data; + struct obs_output *output = data; struct encoder_packet out; - bool was_started; + bool was_started; if (!active(output)) return; @@ -1438,8 +1641,7 @@ static void interleave_packets(void *data, struct encoder_packet *packet) pthread_mutex_lock(&output->interleaved_mutex); /* if first video frame is not a keyframe, discard until received */ - if (!output->received_video && - packet->type == OBS_ENCODER_VIDEO && + if (!output->received_video && packet->type == OBS_ENCODER_VIDEO && !packet->keyframe) { discard_unused_audio_packets(output, packet->dts_usec); pthread_mutex_unlock(&output->interleaved_mutex); @@ -1503,33 +1705,117 @@ static void default_encoded_callback(void *param, struct encoder_packet *packet) static void default_raw_video_callback(void *param, struct video_data *frame) { struct obs_output *output = param; + + if (video_pause_check(&output->pause, frame->timestamp)) + return; + if (data_active(output)) output->info.raw_video(output->context.data, frame); output->total_frames++; } +static bool prepare_audio(struct obs_output *output, + const struct audio_data *old, struct audio_data *new) +{ + if (!output->video_start_ts) { + pthread_mutex_lock(&output->pause.mutex); + output->video_start_ts = output->pause.last_video_ts; + pthread_mutex_unlock(&output->pause.mutex); + } + + if (!output->video_start_ts) + return false; + + /* ------------------ */ + + *new = *old; + + if (old->timestamp < output->video_start_ts) { + uint64_t duration = (uint64_t)old->frames * 1000000000 / + (uint64_t)output->sample_rate; + uint64_t end_ts = (old->timestamp + duration); + uint64_t cutoff; + + if (end_ts <= output->video_start_ts) + return false; + + cutoff = output->video_start_ts - old->timestamp; + new->timestamp += cutoff; + + cutoff = cutoff * (uint64_t)output->sample_rate / 1000000000; + + for (size_t i = 0; i < output->planes; i++) + new->data[i] += output->audio_size *(uint32_t)cutoff; + new->frames -= (uint32_t)cutoff; + } + + return true; +} static void default_raw_audio_callback(void *param, size_t mix_idx, - struct audio_data *frames) + struct audio_data *in) { struct obs_output *output = param; + struct audio_data out; + size_t frame_size_bytes; + if (!data_active(output)) return; - if (output->info.raw_audio2) - output->info.raw_audio2(output->context.data, mix_idx, frames); - else - output->info.raw_audio(output->context.data, frames); + /* -------------- */ + + if (!prepare_audio(output, in, &out)) + return; + if (audio_pause_check(&output->pause, &out, output->sample_rate)) + return; + if (!output->audio_start_ts) { + output->audio_start_ts = out.timestamp; + } + + frame_size_bytes = AUDIO_OUTPUT_FRAMES * output->audio_size; + + for (size_t i = 0; i < output->planes; i++) + circlebuf_push_back(&output->audio_buffer[mix_idx][i], + out.data[i], + out.frames * output->audio_size); + + /* -------------- */ + + while (output->audio_buffer[mix_idx][0].size > frame_size_bytes) { + for (size_t i = 0; i < output->planes; i++) { + circlebuf_pop_front(&output->audio_buffer[mix_idx][i], + output->audio_data[i], + frame_size_bytes); + out.data[i] = (uint8_t *)output->audio_data[i]; + } + + out.frames = AUDIO_OUTPUT_FRAMES; + out.timestamp = output->audio_start_ts + + audio_frames_to_ns(output->sample_rate, + output->total_audio_frames); + + pthread_mutex_lock(&output->pause.mutex); + out.timestamp += output->pause.ts_offset; + pthread_mutex_unlock(&output->pause.mutex); + + output->total_audio_frames += AUDIO_OUTPUT_FRAMES; + + if (output->info.raw_audio2) + output->info.raw_audio2(output->context.data, mix_idx, + &out); + else + output->info.raw_audio(output->context.data, &out); + } } static inline void start_audio_encoders(struct obs_output *output, - encoded_callback_t encoded_callback) + encoded_callback_t encoded_callback) { size_t num_mixes = num_audio_mixes(output); for (size_t i = 0; i < num_mixes; i++) { - obs_encoder_start(output->audio_encoders[i], - encoded_callback, output); + obs_encoder_start(output->audio_encoders[i], encoded_callback, + output); } } @@ -1538,27 +1824,26 @@ static inline void start_raw_audio(obs_output_t *output) if (output->info.raw_audio2) { for (int idx = 0; idx < MAX_AUDIO_MIXES; idx++) { if ((output->mixer_mask & ((size_t)1 << idx)) != 0) { - audio_output_connect(output->audio, idx, - get_audio_conversion(output), - default_raw_audio_callback, - output); + audio_output_connect( + output->audio, idx, + get_audio_conversion(output), + default_raw_audio_callback, output); } } } else { audio_output_connect(output->audio, get_first_mixer(output), get_audio_conversion(output), - default_raw_audio_callback, - output); + default_raw_audio_callback, output); } } static void reset_packet_data(obs_output_t *output) { - output->received_audio = false; - output->received_video = false; + output->received_audio = false; + output->received_video = false; output->highest_audio_ts = 0; output->highest_video_ts = 0; - output->video_offset = 0; + output->video_offset = 0; for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) output->audio_offsets[i] = 0; @@ -1572,7 +1857,7 @@ static inline bool preserve_active(struct obs_output *output) } static void hook_data_capture(struct obs_output *output, bool encoded, - bool has_video, bool has_audio) + bool has_video, bool has_audio) { encoded_callback_t encoded_callback; @@ -1581,8 +1866,9 @@ static void hook_data_capture(struct obs_output *output, bool encoded, reset_packet_data(output); pthread_mutex_unlock(&output->interleaved_mutex); - encoded_callback = (has_video && has_audio) ? - interleave_packets : default_encoded_callback; + encoded_callback = (has_video && has_audio) + ? interleave_packets + : default_encoded_callback; if (output->delay_sec) { output->active_delay_ns = @@ -1592,18 +1878,18 @@ static void hook_data_capture(struct obs_output *output, bool encoded, encoded_callback = process_delay; os_atomic_set_bool(&output->delay_active, true); - blog(LOG_INFO, "Output '%s': %"PRIu32" second delay " - "active, preserve on disconnect is %s", - output->context.name, - output->delay_sec, - preserve_active(output) ? "on" : "off"); + blog(LOG_INFO, + "Output '%s': %" PRIu32 " second delay " + "active, preserve on disconnect is %s", + output->context.name, output->delay_sec, + preserve_active(output) ? "on" : "off"); } if (has_audio) start_audio_encoders(output, encoded_callback); if (has_video) obs_encoder_start(output->video_encoder, - encoded_callback, output); + encoded_callback, output); } else { if (has_video) start_raw_video(output->video, @@ -1626,7 +1912,7 @@ static inline void signal_reconnect(struct obs_output *output) calldata_init_fixed(¶ms, stack, sizeof(stack)); calldata_set_int(¶ms, "timeout_sec", - output->reconnect_retry_cur_sec); + output->reconnect_retry_cur_sec); calldata_set_ptr(¶ms, "output", output); signal_handler_signal(output->context.signals, "reconnect", ¶ms); } @@ -1651,8 +1937,8 @@ static inline void signal_stop(struct obs_output *output) } static inline void convert_flags(const struct obs_output *output, - uint32_t flags, bool *encoded, bool *has_video, bool *has_audio, - bool *has_service) + uint32_t flags, bool *encoded, bool *has_video, + bool *has_audio, bool *has_service) { *encoded = (output->info.flags & OBS_OUTPUT_ENCODED) != 0; if (!flags) @@ -1660,34 +1946,36 @@ static inline void convert_flags(const struct obs_output *output, else flags &= output->info.flags; - *has_video = (flags & OBS_OUTPUT_VIDEO) != 0; - *has_audio = (flags & OBS_OUTPUT_AUDIO) != 0; + *has_video = (flags & OBS_OUTPUT_VIDEO) != 0; + *has_audio = (flags & OBS_OUTPUT_AUDIO) != 0; *has_service = (flags & OBS_OUTPUT_SERVICE) != 0; } bool obs_output_can_begin_data_capture(const obs_output_t *output, - uint32_t flags) + uint32_t flags) { bool encoded, has_video, has_audio, has_service; if (!obs_output_valid(output, "obs_output_can_begin_data_capture")) return false; - if (delay_active(output)) return true; - if (active(output)) return false; + if (delay_active(output)) + return true; + if (active(output)) + return false; if (data_capture_ending(output)) pthread_join(output->end_data_capture_thread, NULL); convert_flags(output, flags, &encoded, &has_video, &has_audio, - &has_service); + &has_service); return can_begin_data_capture(output, encoded, has_video, has_audio, - has_service); + has_service); } static inline bool initialize_audio_encoders(obs_output_t *output, - size_t num_mixes) + size_t num_mixes) { for (size_t i = 0; i < num_mixes; i++) { if (!obs_encoder_initialize(output->audio_encoders[i])) { @@ -1699,7 +1987,7 @@ static inline bool initialize_audio_encoders(obs_output_t *output, } static inline obs_encoder_t *find_inactive_audio_encoder(obs_output_t *output, - size_t num_mixes) + size_t num_mixes) { for (size_t i = 0; i < num_mixes; i++) { struct obs_encoder *audio = output->audio_encoders[i]; @@ -1714,17 +2002,15 @@ static inline obs_encoder_t *find_inactive_audio_encoder(obs_output_t *output, static inline void pair_encoders(obs_output_t *output, size_t num_mixes) { struct obs_encoder *video = output->video_encoder; - struct obs_encoder *audio = find_inactive_audio_encoder(output, - num_mixes); + struct obs_encoder *audio = + find_inactive_audio_encoder(output, num_mixes); if (video && audio) { pthread_mutex_lock(&audio->init_mutex); pthread_mutex_lock(&video->init_mutex); - if (!audio->active && - !video->active && - !video->paired_encoder && - !audio->paired_encoder) { + if (!audio->active && !video->active && + !video->paired_encoder && !audio->paired_encoder) { audio->wait_for_video = true; audio->paired_encoder = video; @@ -1744,10 +2030,11 @@ bool obs_output_initialize_encoders(obs_output_t *output, uint32_t flags) if (!obs_output_valid(output, "obs_output_initialize_encoders")) return false; - if (active(output)) return delay_active(output); + if (active(output)) + return delay_active(output); convert_flags(output, flags, &encoded, &has_video, &has_audio, - &has_service); + &has_service); if (!encoded) return false; @@ -1779,6 +2066,42 @@ static bool begin_delayed_capture(obs_output_t *output) return true; } +static void reset_raw_output(obs_output_t *output) +{ + clear_audio_buffers(output); + + if (output->audio) { + const struct audio_output_info *aoi = + audio_output_get_info(output->audio); + struct audio_convert_info conv = output->audio_conversion; + struct audio_convert_info info = { + aoi->samples_per_sec, + aoi->format, + aoi->speakers, + }; + + if (output->audio_conversion_set) { + if (conv.samples_per_sec) + info.samples_per_sec = conv.samples_per_sec; + if (conv.format != AUDIO_FORMAT_UNKNOWN) + info.format = conv.format; + if (conv.speakers != SPEAKERS_UNKNOWN) + info.speakers = conv.speakers; + } + + output->sample_rate = info.samples_per_sec; + output->planes = get_audio_planes(info.format, info.speakers); + output->total_audio_frames = 0; + output->audio_size = + get_audio_size(info.format, info.speakers, 1); + } + + output->audio_start_ts = 0; + output->video_start_ts = 0; + + pause_reset(&output->pause); +} + bool obs_output_begin_data_capture(obs_output_t *output, uint32_t flags) { bool encoded, has_video, has_audio, has_service; @@ -1787,16 +2110,22 @@ bool obs_output_begin_data_capture(obs_output_t *output, uint32_t flags) if (!obs_output_valid(output, "obs_output_begin_data_capture")) return false; - if (delay_active(output)) return begin_delayed_capture(output); - if (active(output)) return false; + if (delay_active(output)) + return begin_delayed_capture(output); + if (active(output)) + return false; - output->total_frames = 0; + output->total_frames = 0; + + if ((output->info.flags & OBS_OUTPUT_ENCODED) == 0) { + reset_raw_output(output); + } convert_flags(output, flags, &encoded, &has_video, &has_audio, - &has_service); + &has_service); if (!can_begin_data_capture(output, encoded, has_video, has_audio, - has_service)) + has_service)) return false; num_mixes = num_audio_mixes(output); @@ -1827,13 +2156,13 @@ bool obs_output_begin_data_capture(obs_output_t *output, uint32_t flags) } static inline void stop_audio_encoders(obs_output_t *output, - encoded_callback_t encoded_callback) + encoded_callback_t encoded_callback) { size_t num_mixes = num_audio_mixes(output); for (size_t i = 0; i < num_mixes; i++) { - obs_encoder_stop(output->audio_encoders[i], - encoded_callback, output); + obs_encoder_stop(output->audio_encoders[i], encoded_callback, + output); } } @@ -1842,17 +2171,14 @@ static inline void stop_raw_audio(obs_output_t *output) if (output->info.raw_audio2) { for (int idx = 0; idx < MAX_AUDIO_MIXES; idx++) { if ((output->mixer_mask & ((size_t)1 << idx)) != 0) { - audio_output_disconnect(output->audio, - idx, - default_raw_audio_callback, - output); + audio_output_disconnect( + output->audio, idx, + default_raw_audio_callback, output); } } } else { - audio_output_disconnect(output->audio, - get_first_mixer(output), - default_raw_audio_callback, - output); + audio_output_disconnect(output->audio, get_first_mixer(output), + default_raw_audio_callback, output); } } @@ -1863,24 +2189,25 @@ static void *end_data_capture_thread(void *data) obs_output_t *output = data; convert_flags(output, 0, &encoded, &has_video, &has_audio, - &has_service); + &has_service); if (encoded) { if (output->active_delay_ns) encoded_callback = process_delay; else - encoded_callback = (has_video && has_audio) ? - interleave_packets : default_encoded_callback; + encoded_callback = (has_video && has_audio) + ? interleave_packets + : default_encoded_callback; if (has_video) obs_encoder_stop(output->video_encoder, - encoded_callback, output); + encoded_callback, output); if (has_audio) stop_audio_encoders(output, encoded_callback); } else { if (has_video) stop_raw_video(output->video, - default_raw_video_callback, output); + default_raw_video_callback, output); if (has_audio) stop_raw_audio(output); } @@ -1900,7 +2227,7 @@ static void *end_data_capture_thread(void *data) } static void obs_output_end_data_capture_internal(obs_output_t *output, - bool signal) + bool signal) { int ret; @@ -1937,10 +2264,12 @@ static void obs_output_end_data_capture_internal(obs_output_t *output, os_atomic_set_bool(&output->end_data_capture_thread_active, true); ret = pthread_create(&output->end_data_capture_thread, NULL, - end_data_capture_thread, output); + end_data_capture_thread, output); if (ret != 0) { - blog(LOG_WARNING, "Failed to create end_data_capture_thread " - "for output '%s'!", output->context.name); + blog(LOG_WARNING, + "Failed to create end_data_capture_thread " + "for output '%s'!", + output->context.name); end_data_capture_thread(output); } @@ -2008,15 +2337,14 @@ static void output_reconnect(struct obs_output *output) output->reconnect_retries++; output->stop_code = OBS_OUTPUT_DISCONNECTED; - ret = pthread_create(&output->reconnect_thread, NULL, - &reconnect_thread, output); + ret = pthread_create(&output->reconnect_thread, NULL, &reconnect_thread, + output); if (ret < 0) { blog(LOG_WARNING, "Failed to create reconnect thread"); os_atomic_set_bool(&output->reconnecting, false); } else { blog(LOG_INFO, "Output '%s': Reconnecting in %d seconds..", - output->context.name, - output->reconnect_retry_sec); + output->context.name, output->reconnect_retry_sec); signal_reconnect(output); } @@ -2027,7 +2355,7 @@ static inline bool can_reconnect(const obs_output_t *output, int code) bool reconnect_active = output->reconnect_retry_max != 0; return (reconnecting(output) && code != OBS_OUTPUT_SUCCESS) || - (reconnect_active && code == OBS_OUTPUT_DISCONNECTED); + (reconnect_active && code == OBS_OUTPUT_DISCONNECTED); } void obs_output_signal_stop(obs_output_t *output, int code) @@ -2119,7 +2447,7 @@ obs_output_t *obs_weak_output_get_output(obs_weak_output_t *weak) } bool obs_weak_output_references_output(obs_weak_output_t *weak, - obs_output_t *output) + obs_output_t *output) { return weak && output && weak->output == output; } @@ -2127,23 +2455,25 @@ bool obs_weak_output_references_output(obs_weak_output_t *weak, void *obs_output_get_type_data(obs_output_t *output) { return obs_output_valid(output, "obs_output_get_type_data") - ? output->info.type_data : NULL; + ? output->info.type_data + : NULL; } const char *obs_output_get_id(const obs_output_t *output) { - return obs_output_valid(output, "obs_output_get_id") - ? output->info.id : NULL; + return obs_output_valid(output, "obs_output_get_id") ? output->info.id + : NULL; } #if BUILD_CAPTIONS static struct caption_text *caption_text_new(const char *text, size_t bytes, - struct caption_text *tail, struct caption_text **head, - double display_duration) + struct caption_text *tail, + struct caption_text **head, + double display_duration) { struct caption_text *next = bzalloc(sizeof(struct caption_text)); - snprintf(&next->text[0], CAPTION_LINE_BYTES + 1, "%.*s", - (int)bytes, text); + snprintf(&next->text[0], CAPTION_LINE_BYTES + 1, "%.*s", (int)bytes, + text); next->display_duration = display_duration; if (!*head) { @@ -2163,7 +2493,7 @@ void obs_output_output_caption_text1(obs_output_t *output, const char *text) } void obs_output_output_caption_text2(obs_output_t *output, const char *text, - double display_duration) + double display_duration) { if (!obs_output_valid(output, "obs_output_output_caption_text2")) return; @@ -2176,11 +2506,9 @@ void obs_output_output_caption_text2(obs_output_t *output, const char *text, pthread_mutex_lock(&output->caption_mutex); - output->caption_tail = caption_text_new( - text, size, - output->caption_tail, - &output->caption_head, - display_duration); + output->caption_tail = + caption_text_new(text, size, output->caption_tail, + &output->caption_head, display_duration); pthread_mutex_unlock(&output->caption_mutex); } @@ -2193,8 +2521,10 @@ float obs_output_get_congestion(obs_output_t *output) if (output->info.get_congestion) { float val = output->info.get_congestion(output->context.data); - if (val < 0.0f) val = 0.0f; - else if (val > 1.0f) val = 1.0f; + if (val < 0.0f) + val = 0.0f; + else if (val > 1.0f) + val = 1.0f; return val; } return 0; @@ -2242,12 +2572,14 @@ bool obs_output_reconnecting(const obs_output_t *output) const char *obs_output_get_supported_video_codecs(const obs_output_t *output) { - return obs_output_valid(output, __FUNCTION__) ? - output->info.encoded_video_codecs : NULL; + return obs_output_valid(output, __FUNCTION__) + ? output->info.encoded_video_codecs + : NULL; } const char *obs_output_get_supported_audio_codecs(const obs_output_t *output) { - return obs_output_valid(output, __FUNCTION__) ? - output->info.encoded_audio_codecs : NULL; + return obs_output_valid(output, __FUNCTION__) + ? output->info.encoded_audio_codecs + : NULL; } diff --git a/libobs/obs-output.h b/libobs/obs-output.h index db30fe0..51093f4 100644 --- a/libobs/obs-output.h +++ b/libobs/obs-output.h @@ -21,12 +21,13 @@ extern "C" { #endif -#define OBS_OUTPUT_VIDEO (1<<0) -#define OBS_OUTPUT_AUDIO (1<<1) -#define OBS_OUTPUT_AV (OBS_OUTPUT_VIDEO | OBS_OUTPUT_AUDIO) -#define OBS_OUTPUT_ENCODED (1<<2) -#define OBS_OUTPUT_SERVICE (1<<3) -#define OBS_OUTPUT_MULTI_TRACK (1<<4) +#define OBS_OUTPUT_VIDEO (1 << 0) +#define OBS_OUTPUT_AUDIO (1 << 1) +#define OBS_OUTPUT_AV (OBS_OUTPUT_VIDEO | OBS_OUTPUT_AUDIO) +#define OBS_OUTPUT_ENCODED (1 << 2) +#define OBS_OUTPUT_SERVICE (1 << 3) +#define OBS_OUTPUT_MULTI_TRACK (1 << 4) +#define OBS_OUTPUT_CAN_PAUSE (1 << 5) struct encoder_packet; @@ -56,7 +57,7 @@ struct obs_output_info { obs_properties_t *(*get_properties)(void *data); - void (*pause)(void *data); + void (*unused1)(void *data); uint64_t (*get_total_bytes)(void *data); @@ -77,7 +78,7 @@ struct obs_output_info { }; EXPORT void obs_register_output_s(const struct obs_output_info *info, - size_t size); + size_t size); #define obs_register_output(info) \ obs_register_output_s(info, sizeof(struct obs_output_info)) diff --git a/libobs/obs-properties.c b/libobs/obs-properties.c index c8fcbe5..b52c6c4 100644 --- a/libobs/obs-properties.c +++ b/libobs/obs-properties.c @@ -41,15 +41,15 @@ struct list_item { bool disabled; union { - char *str; + char *str; long long ll; - double d; + double d; }; }; struct path_data { - char *filter; - char *default_path; + char *filter; + char *default_path; enum obs_path_type type; }; @@ -59,14 +59,14 @@ struct text_data { struct list_data { DARRAY(struct list_item) items; - enum obs_combo_type type; - enum obs_combo_format format; + enum obs_combo_type type; + enum obs_combo_format format; }; struct editable_list_data { enum obs_editable_list_type type; - char *filter; - char *default_path; + char *filter; + char *default_path; }; struct button_data { @@ -85,7 +85,7 @@ struct frame_rate_range { struct frame_rate_data { DARRAY(struct frame_rate_option) extra_options; - DARRAY(struct frame_rate_range) ranges; + DARRAY(struct frame_rate_range) ranges; }; struct group_data { @@ -107,7 +107,7 @@ static inline void editable_list_data_free(struct editable_list_data *data) } static inline void list_item_free(struct list_data *data, - struct list_item *item) + struct list_item *item) { bfree(item->name); if (data->format == OBS_COMBO_FORMAT_STRING) @@ -117,7 +117,7 @@ static inline void list_item_free(struct list_data *data, static inline void list_data_free(struct list_data *data) { for (size_t i = 0; i < data->items.num; i++) - list_item_free(data, data->items.array+i); + list_item_free(data, data->items.array + i); da_free(data->items); } @@ -147,16 +147,19 @@ static inline void frame_rate_data_free(struct frame_rate_data *data) da_free(data->ranges); } -static inline void group_data_free(struct group_data *data) { +static inline void group_data_free(struct group_data *data) +{ obs_properties_destroy(data->content); } -static inline void int_data_free(struct int_data *data) { +static inline void int_data_free(struct int_data *data) +{ if (data->suffix) bfree(data->suffix); } -static inline void float_data_free(struct float_data *data) { +static inline void float_data_free(struct float_data *data) +{ if (data->suffix) bfree(data->suffix); } @@ -164,30 +167,30 @@ static inline void float_data_free(struct float_data *data) { struct obs_properties; struct obs_property { - char *name; - char *desc; - char *long_desc; - void *priv; - enum obs_property_type type; - bool visible; - bool enabled; + char *name; + char *desc; + char *long_desc; + void *priv; + enum obs_property_type type; + bool visible; + bool enabled; - struct obs_properties *parent; + struct obs_properties *parent; obs_property_modified_t modified; obs_property_modified2_t modified2; - struct obs_property *next; + struct obs_property *next; }; struct obs_properties { - void *param; - void (*destroy)(void *param); - uint32_t flags; + void *param; + void (*destroy)(void *param); + uint32_t flags; - struct obs_property *first_property; - struct obs_property **last; - struct obs_property *parent; + struct obs_property *first_property; + struct obs_property **last; + struct obs_property *parent; }; obs_properties_t *obs_properties_create(void) @@ -198,8 +201,8 @@ obs_properties_t *obs_properties_create(void) return props; } -void obs_properties_set_param(obs_properties_t *props, - void *param, void (*destroy)(void *param)) +void obs_properties_set_param(obs_properties_t *props, void *param, + void (*destroy)(void *param)) { if (!props) return; @@ -207,7 +210,7 @@ void obs_properties_set_param(obs_properties_t *props, if (props->param && props->destroy) props->destroy(props->param); - props->param = param; + props->param = param; props->destroy = destroy; } @@ -228,7 +231,7 @@ void *obs_properties_get_param(obs_properties_t *props) } obs_properties_t *obs_properties_create_param(void *param, - void (*destroy)(void *param)) + void (*destroy)(void *param)) { struct obs_properties *props = obs_properties_create(); obs_properties_set_param(props, param, destroy); @@ -333,32 +336,50 @@ void obs_properties_remove_by_name(obs_properties_t *props, const char *name) break; } + if (cur->type == OBS_PROPERTY_GROUP) { + obs_properties_remove_by_name( + obs_property_group_content(cur), name); + } + prev = cur; cur = cur->next; } } -void obs_properties_apply_settings(obs_properties_t *props, obs_data_t *settings) +void obs_properties_apply_settings_internal(obs_properties_t *props, + obs_data_t *settings, + obs_properties_t *realprops) { struct obs_property *p; - if (!props) - return; - p = props->first_property; while (p) { + if (p->type == OBS_PROPERTY_GROUP) { + obs_properties_apply_settings_internal( + obs_property_group_content(p), settings, + realprops); + } if (p->modified) - p->modified(props, p, settings); + p->modified(realprops, p, settings); else if (p->modified2) - p->modified2(p->priv, props, p, settings); + p->modified2(p->priv, realprops, p, settings); p = p->next; } } +void obs_properties_apply_settings(obs_properties_t *props, + obs_data_t *settings) +{ + if (!props) + return; + + obs_properties_apply_settings_internal(props, settings, props); +} + /* ------------------------------------------------------------------------- */ static inline void propertes_add(struct obs_properties *props, - struct obs_property *p) + struct obs_property *p) { *props->last = p; props->last = &p->next; @@ -367,39 +388,51 @@ static inline void propertes_add(struct obs_properties *props, static inline size_t get_property_size(enum obs_property_type type) { switch (type) { - case OBS_PROPERTY_INVALID: return 0; - case OBS_PROPERTY_BOOL: return 0; - case OBS_PROPERTY_INT: return sizeof(struct int_data); - case OBS_PROPERTY_FLOAT: return sizeof(struct float_data); - case OBS_PROPERTY_TEXT: return sizeof(struct text_data); - case OBS_PROPERTY_PATH: return sizeof(struct path_data); - case OBS_PROPERTY_LIST: return sizeof(struct list_data); - case OBS_PROPERTY_COLOR: return 0; - case OBS_PROPERTY_BUTTON: return sizeof(struct button_data); - case OBS_PROPERTY_FONT: return 0; + case OBS_PROPERTY_INVALID: + return 0; + case OBS_PROPERTY_BOOL: + return 0; + case OBS_PROPERTY_INT: + return sizeof(struct int_data); + case OBS_PROPERTY_FLOAT: + return sizeof(struct float_data); + case OBS_PROPERTY_TEXT: + return sizeof(struct text_data); + case OBS_PROPERTY_PATH: + return sizeof(struct path_data); + case OBS_PROPERTY_LIST: + return sizeof(struct list_data); + case OBS_PROPERTY_COLOR: + return 0; + case OBS_PROPERTY_BUTTON: + return sizeof(struct button_data); + case OBS_PROPERTY_FONT: + return 0; case OBS_PROPERTY_EDITABLE_LIST: return sizeof(struct editable_list_data); - case OBS_PROPERTY_FRAME_RATE:return sizeof(struct frame_rate_data); - case OBS_PROPERTY_GROUP: return sizeof(struct group_data); + case OBS_PROPERTY_FRAME_RATE: + return sizeof(struct frame_rate_data); + case OBS_PROPERTY_GROUP: + return sizeof(struct group_data); } return 0; } static inline struct obs_property *new_prop(struct obs_properties *props, - const char *name, const char *desc, - enum obs_property_type type) + const char *name, const char *desc, + enum obs_property_type type) { size_t data_size = get_property_size(type); struct obs_property *p; p = bzalloc(sizeof(struct obs_property) + data_size); - p->parent = props; + p->parent = props; p->enabled = true; p->visible = true; - p->type = type; - p->name = bstrdup(name); - p->desc = bstrdup(desc); + p->type = type; + p->name = bstrdup(name); + p->desc = bstrdup(desc); propertes_add(props, p); return p; @@ -427,7 +460,8 @@ static inline bool contains_prop(struct obs_properties *props, const char *name) } if (p->type == OBS_PROPERTY_GROUP) { - if (contains_prop(obs_property_group_content(p), name)) { + if (contains_prop(obs_property_group_content(p), + name)) { return true; } } @@ -445,11 +479,11 @@ static inline bool has_prop(struct obs_properties *props, const char *name) static inline void *get_property_data(struct obs_property *prop) { - return (uint8_t*)prop + sizeof(struct obs_property); + return (uint8_t *)prop + sizeof(struct obs_property); } static inline void *get_type_data(struct obs_property *prop, - enum obs_property_type type) + enum obs_property_type type) { if (!prop || prop->type != type) return NULL; @@ -458,74 +492,82 @@ static inline void *get_type_data(struct obs_property *prop, } obs_property_t *obs_properties_add_bool(obs_properties_t *props, - const char *name, const char *desc) + const char *name, const char *desc) { - if (!props || has_prop(props, name)) return NULL; + if (!props || has_prop(props, name)) + return NULL; return new_prop(props, name, desc, OBS_PROPERTY_BOOL); } -static obs_property_t *add_int(obs_properties_t *props, - const char *name, const char *desc, int min, int max, int step, - enum obs_number_type type) +static obs_property_t *add_int(obs_properties_t *props, const char *name, + const char *desc, int min, int max, int step, + enum obs_number_type type) { - if (!props || has_prop(props, name)) return NULL; + if (!props || has_prop(props, name)) + return NULL; struct obs_property *p = new_prop(props, name, desc, OBS_PROPERTY_INT); struct int_data *data = get_property_data(p); - data->min = min; - data->max = max; + data->min = min; + data->max = max; data->step = step; data->type = type; return p; } -static obs_property_t *add_flt(obs_properties_t *props, - const char *name, const char *desc, - double min, double max, double step, - enum obs_number_type type) +static obs_property_t *add_flt(obs_properties_t *props, const char *name, + const char *desc, double min, double max, + double step, enum obs_number_type type) { - if (!props || has_prop(props, name)) return NULL; + if (!props || has_prop(props, name)) + return NULL; - struct obs_property *p = new_prop(props, name, desc, - OBS_PROPERTY_FLOAT); + struct obs_property *p = + new_prop(props, name, desc, OBS_PROPERTY_FLOAT); struct float_data *data = get_property_data(p); - data->min = min; - data->max = max; + data->min = min; + data->max = max; data->step = step; data->type = type; return p; } obs_property_t *obs_properties_add_int(obs_properties_t *props, - const char *name, const char *desc, int min, int max, int step) + const char *name, const char *desc, + int min, int max, int step) { return add_int(props, name, desc, min, max, step, OBS_NUMBER_SCROLLER); } obs_property_t *obs_properties_add_float(obs_properties_t *props, - const char *name, const char *desc, - double min, double max, double step) + const char *name, const char *desc, + double min, double max, double step) { return add_flt(props, name, desc, min, max, step, OBS_NUMBER_SCROLLER); } obs_property_t *obs_properties_add_int_slider(obs_properties_t *props, - const char *name, const char *desc, int min, int max, int step) + const char *name, + const char *desc, int min, + int max, int step) { return add_int(props, name, desc, min, max, step, OBS_NUMBER_SLIDER); } obs_property_t *obs_properties_add_float_slider(obs_properties_t *props, - const char *name, const char *desc, - double min, double max, double step) + const char *name, + const char *desc, double min, + double max, double step) { return add_flt(props, name, desc, min, max, step, OBS_NUMBER_SLIDER); } obs_property_t *obs_properties_add_text(obs_properties_t *props, - const char *name, const char *desc, enum obs_text_type type) + const char *name, const char *desc, + enum obs_text_type type) { - if (!props || has_prop(props, name)) return NULL; + if (!props || has_prop(props, name)) + return NULL; struct obs_property *p = new_prop(props, name, desc, OBS_PROPERTY_TEXT); struct text_data *data = get_property_data(p); @@ -534,14 +576,17 @@ obs_property_t *obs_properties_add_text(obs_properties_t *props, } obs_property_t *obs_properties_add_path(obs_properties_t *props, - const char *name, const char *desc, enum obs_path_type type, - const char *filter, const char *default_path) + const char *name, const char *desc, + enum obs_path_type type, + const char *filter, + const char *default_path) { - if (!props || has_prop(props, name)) return NULL; + if (!props || has_prop(props, name)) + return NULL; struct obs_property *p = new_prop(props, name, desc, OBS_PROPERTY_PATH); struct path_data *data = get_property_data(p); - data->type = type; + data->type = type; data->default_path = bstrdup(default_path); if (data->type == OBS_PATH_FILE) @@ -551,55 +596,62 @@ obs_property_t *obs_properties_add_path(obs_properties_t *props, } obs_property_t *obs_properties_add_list(obs_properties_t *props, - const char *name, const char *desc, - enum obs_combo_type type, - enum obs_combo_format format) + const char *name, const char *desc, + enum obs_combo_type type, + enum obs_combo_format format) { - if (!props || has_prop(props, name)) return NULL; + if (!props || has_prop(props, name)) + return NULL; - if (type == OBS_COMBO_TYPE_EDITABLE && + if (type == OBS_COMBO_TYPE_EDITABLE && format != OBS_COMBO_FORMAT_STRING) { - blog(LOG_WARNING, "List '%s', error: Editable combo boxes " - "must be of the 'string' type", name); + blog(LOG_WARNING, + "List '%s', error: Editable combo boxes " + "must be of the 'string' type", + name); return NULL; } struct obs_property *p = new_prop(props, name, desc, OBS_PROPERTY_LIST); struct list_data *data = get_property_data(p); data->format = format; - data->type = type; + data->type = type; return p; } obs_property_t *obs_properties_add_color(obs_properties_t *props, - const char *name, const char *desc) + const char *name, const char *desc) { - if (!props || has_prop(props, name)) return NULL; + if (!props || has_prop(props, name)) + return NULL; return new_prop(props, name, desc, OBS_PROPERTY_COLOR); } obs_property_t *obs_properties_add_button(obs_properties_t *props, - const char *name, const char *text, - obs_property_clicked_t callback) + const char *name, const char *text, + obs_property_clicked_t callback) { - if (!props || has_prop(props, name)) return NULL; + if (!props || has_prop(props, name)) + return NULL; - struct obs_property *p = new_prop(props, name, text, - OBS_PROPERTY_BUTTON); + struct obs_property *p = + new_prop(props, name, text, OBS_PROPERTY_BUTTON); struct button_data *data = get_property_data(p); data->callback = callback; return p; } obs_property_t *obs_properties_add_button2(obs_properties_t *props, - const char *name, const char *text, - obs_property_clicked_t callback, void *priv) + const char *name, const char *text, + obs_property_clicked_t callback, + void *priv) { - if (!props || has_prop(props, name)) return NULL; + if (!props || has_prop(props, name)) + return NULL; - struct obs_property *p = new_prop(props, name, text, - OBS_PROPERTY_BUTTON); + struct obs_property *p = + new_prop(props, name, text, OBS_PROPERTY_BUTTON); struct button_data *data = get_property_data(p); data->callback = callback; p->priv = priv; @@ -607,20 +659,23 @@ obs_property_t *obs_properties_add_button2(obs_properties_t *props, } obs_property_t *obs_properties_add_font(obs_properties_t *props, - const char *name, const char *desc) + const char *name, const char *desc) { - if (!props || has_prop(props, name)) return NULL; + if (!props || has_prop(props, name)) + return NULL; return new_prop(props, name, desc, OBS_PROPERTY_FONT); } -obs_property_t *obs_properties_add_editable_list(obs_properties_t *props, - const char *name, const char *desc, - enum obs_editable_list_type type, const char *filter, - const char *default_path) +obs_property_t * +obs_properties_add_editable_list(obs_properties_t *props, const char *name, + const char *desc, + enum obs_editable_list_type type, + const char *filter, const char *default_path) { - if (!props || has_prop(props, name)) return NULL; - struct obs_property *p = new_prop(props, name, desc, - OBS_PROPERTY_EDITABLE_LIST); + if (!props || has_prop(props, name)) + return NULL; + struct obs_property *p = + new_prop(props, name, desc, OBS_PROPERTY_EDITABLE_LIST); struct editable_list_data *data = get_property_data(p); data->type = type; @@ -630,12 +685,14 @@ obs_property_t *obs_properties_add_editable_list(obs_properties_t *props, } obs_property_t *obs_properties_add_frame_rate(obs_properties_t *props, - const char *name, const char *desc) + const char *name, + const char *desc) { - if (!props || has_prop(props, name)) return NULL; + if (!props || has_prop(props, name)) + return NULL; - struct obs_property *p = new_prop(props, name, desc, - OBS_PROPERTY_FRAME_RATE); + struct obs_property *p = + new_prop(props, name, desc, OBS_PROPERTY_FRAME_RATE); struct frame_rate_data *data = get_property_data(p); da_init(data->extra_options); @@ -644,7 +701,7 @@ obs_property_t *obs_properties_add_frame_rate(obs_properties_t *props, } static bool check_property_group_recursion(obs_properties_t *parent, - obs_properties_t *group) + obs_properties_t *group) { /* Scan the group for the parent. */ obs_property_t *current_property = group->first_property; @@ -670,7 +727,7 @@ static bool check_property_group_recursion(obs_properties_t *parent, } static bool check_property_group_duplicates(obs_properties_t *parent, - obs_properties_t *group) + obs_properties_t *group) { obs_property_t *current_property = group->first_property; while (current_property) { @@ -685,18 +742,24 @@ static bool check_property_group_duplicates(obs_properties_t *parent, } obs_property_t *obs_properties_add_group(obs_properties_t *props, - const char *name, const char *desc, enum obs_group_type type, - obs_properties_t *group) + const char *name, const char *desc, + enum obs_group_type type, + obs_properties_t *group) { - if (!props || has_prop(props, name)) return NULL; - if (!group) return NULL; + if (!props || has_prop(props, name)) + return NULL; + if (!group) + return NULL; /* Prevent recursion. */ - if (props == group) return NULL; - if (check_property_group_recursion(props, group)) return NULL; + if (props == group) + return NULL; + if (check_property_group_recursion(props, group)) + return NULL; /* Prevent duplicate properties */ - if (check_property_group_duplicates(props, group)) return NULL; + if (check_property_group_duplicates(props, group)) + return NULL; obs_property_t *p = new_prop(props, name, desc, OBS_PROPERTY_GROUP); group->parent = p; @@ -723,7 +786,7 @@ static inline struct list_data *get_list_data(struct obs_property *p) } static inline struct list_data *get_list_fmt_data(struct obs_property *p, - enum obs_combo_format format) + enum obs_combo_format format) { struct list_data *data = get_list_data(p); return (data && data->format == format) ? data : NULL; @@ -741,13 +804,15 @@ bool obs_property_next(obs_property_t **p) } void obs_property_set_modified_callback(obs_property_t *p, - obs_property_modified_t modified) + obs_property_modified_t modified) { - if (p) p->modified = modified; + if (p) + p->modified = modified; } void obs_property_set_modified_callback2(obs_property_t *p, - obs_property_modified2_t modified2, void *priv) + obs_property_modified2_t modified2, + void *priv) { if (p) { p->modified2 = modified2; @@ -773,14 +838,14 @@ bool obs_property_button_clicked(obs_property_t *p, void *obj) { struct obs_context_data *context = obj; if (p) { - struct button_data *data = get_type_data(p, - OBS_PROPERTY_BUTTON); + struct button_data *data = + get_type_data(p, OBS_PROPERTY_BUTTON); if (data && data->callback) { obs_properties_t *top = get_topmost_parent(p->parent); if (p->priv) return data->callback(top, p, p->priv); return data->callback(top, p, - (context ? context->data : NULL)); + (context ? context->data : NULL)); } } @@ -789,21 +854,22 @@ bool obs_property_button_clicked(obs_property_t *p, void *obj) void obs_property_set_visible(obs_property_t *p, bool visible) { - if (p) p->visible = visible; + if (p) + p->visible = visible; } void obs_property_set_enabled(obs_property_t *p, bool enabled) { - if (p) p->enabled = enabled; + if (p) + p->enabled = enabled; } void obs_property_set_description(obs_property_t *p, const char *description) { if (p) { bfree(p->desc); - p->desc = description && *description - ? bstrdup(description) - : NULL; + p->desc = description && *description ? bstrdup(description) + : NULL; } } @@ -811,9 +877,8 @@ void obs_property_set_long_description(obs_property_t *p, const char *long_desc) { if (p) { bfree(p->long_desc); - p->long_desc = long_desc && *long_desc - ? bstrdup(long_desc) - : NULL; + p->long_desc = long_desc && *long_desc ? bstrdup(long_desc) + : NULL; } } @@ -943,8 +1008,7 @@ enum obs_combo_format obs_property_list_format(obs_property_t *p) return data ? data->format : OBS_COMBO_FORMAT_INVALID; } -void obs_property_int_set_limits(obs_property_t *p, - int min, int max, int step) +void obs_property_int_set_limits(obs_property_t *p, int min, int max, int step) { struct int_data *data = get_type_data(p, OBS_PROPERTY_INT); if (!data) @@ -955,8 +1019,8 @@ void obs_property_int_set_limits(obs_property_t *p, data->step = step; } -void obs_property_float_set_limits(obs_property_t *p, - double min, double max, double step) +void obs_property_float_set_limits(obs_property_t *p, double min, double max, + double step) { struct float_data *data = get_type_data(p, OBS_PROPERTY_FLOAT); if (!data) @@ -995,15 +1059,15 @@ void obs_property_list_clear(obs_property_t *p) } static size_t add_item(struct list_data *data, const char *name, - const void *val) + const void *val) { - struct list_item item = { NULL }; - item.name = bstrdup(name); + struct list_item item = {NULL}; + item.name = bstrdup(name); if (data->format == OBS_COMBO_FORMAT_INT) - item.ll = *(const long long*)val; + item.ll = *(const long long *)val; else if (data->format == OBS_COMBO_FORMAT_FLOAT) - item.d = *(const double*)val; + item.d = *(const double *)val; else item.str = bstrdup(val); @@ -1011,23 +1075,23 @@ static size_t add_item(struct list_data *data, const char *name, } static void insert_item(struct list_data *data, size_t idx, const char *name, - const void *val) + const void *val) { - struct list_item item = { NULL }; - item.name = bstrdup(name); + struct list_item item = {NULL}; + item.name = bstrdup(name); if (data->format == OBS_COMBO_FORMAT_INT) - item.ll = *(const long long*)val; + item.ll = *(const long long *)val; else if (data->format == OBS_COMBO_FORMAT_FLOAT) - item.d = *(const double*)val; + item.d = *(const double *)val; else item.str = bstrdup(val); da_insert(data->items, idx, &item); } -size_t obs_property_list_add_string(obs_property_t *p, - const char *name, const char *val) +size_t obs_property_list_add_string(obs_property_t *p, const char *name, + const char *val) { struct list_data *data = get_list_data(p); if (data && data->format == OBS_COMBO_FORMAT_STRING) @@ -1035,8 +1099,8 @@ size_t obs_property_list_add_string(obs_property_t *p, return 0; } -size_t obs_property_list_add_int(obs_property_t *p, - const char *name, long long val) +size_t obs_property_list_add_int(obs_property_t *p, const char *name, + long long val) { struct list_data *data = get_list_data(p); if (data && data->format == OBS_COMBO_FORMAT_INT) @@ -1044,8 +1108,8 @@ size_t obs_property_list_add_int(obs_property_t *p, return 0; } -size_t obs_property_list_add_float(obs_property_t *p, - const char *name, double val) +size_t obs_property_list_add_float(obs_property_t *p, const char *name, + double val) { struct list_data *data = get_list_data(p); if (data && data->format == OBS_COMBO_FORMAT_FLOAT) @@ -1054,7 +1118,7 @@ size_t obs_property_list_add_float(obs_property_t *p, } void obs_property_list_insert_string(obs_property_t *p, size_t idx, - const char *name, const char *val) + const char *name, const char *val) { struct list_data *data = get_list_data(p); if (data && data->format == OBS_COMBO_FORMAT_STRING) @@ -1062,7 +1126,7 @@ void obs_property_list_insert_string(obs_property_t *p, size_t idx, } void obs_property_list_insert_int(obs_property_t *p, size_t idx, - const char *name, long long val) + const char *name, long long val) { struct list_data *data = get_list_data(p); if (data && data->format == OBS_COMBO_FORMAT_INT) @@ -1070,7 +1134,7 @@ void obs_property_list_insert_int(obs_property_t *p, size_t idx, } void obs_property_list_insert_float(obs_property_t *p, size_t idx, - const char *name, double val) + const char *name, double val) { struct list_data *data = get_list_data(p); if (data && data->format == OBS_COMBO_FORMAT_FLOAT) @@ -1081,7 +1145,7 @@ void obs_property_list_item_remove(obs_property_t *p, size_t idx) { struct list_data *data = get_list_data(p); if (data && idx < data->items.num) { - list_item_free(data, data->items.array+idx); + list_item_free(data, data->items.array + idx); da_erase(data->items, idx); } } @@ -1095,12 +1159,12 @@ size_t obs_property_list_item_count(obs_property_t *p) bool obs_property_list_item_disabled(obs_property_t *p, size_t idx) { struct list_data *data = get_list_data(p); - return (data && idx < data->items.num) ? - data->items.array[idx].disabled : false; + return (data && idx < data->items.num) ? data->items.array[idx].disabled + : false; } void obs_property_list_item_disable(obs_property_t *p, size_t idx, - bool disabled) + bool disabled) { struct list_data *data = get_list_data(p); if (!data || idx >= data->items.num) @@ -1111,49 +1175,47 @@ void obs_property_list_item_disable(obs_property_t *p, size_t idx, const char *obs_property_list_item_name(obs_property_t *p, size_t idx) { struct list_data *data = get_list_data(p); - return (data && idx < data->items.num) ? - data->items.array[idx].name : NULL; + return (data && idx < data->items.num) ? data->items.array[idx].name + : NULL; } const char *obs_property_list_item_string(obs_property_t *p, size_t idx) { struct list_data *data = get_list_fmt_data(p, OBS_COMBO_FORMAT_STRING); - return (data && idx < data->items.num) ? - data->items.array[idx].str : NULL; + return (data && idx < data->items.num) ? data->items.array[idx].str + : NULL; } long long obs_property_list_item_int(obs_property_t *p, size_t idx) { struct list_data *data = get_list_fmt_data(p, OBS_COMBO_FORMAT_INT); - return (data && idx < data->items.num) ? - data->items.array[idx].ll : 0; + return (data && idx < data->items.num) ? data->items.array[idx].ll : 0; } double obs_property_list_item_float(obs_property_t *p, size_t idx) { struct list_data *data = get_list_fmt_data(p, OBS_COMBO_FORMAT_FLOAT); - return (data && idx < data->items.num) ? - data->items.array[idx].d : 0.0; + return (data && idx < data->items.num) ? data->items.array[idx].d : 0.0; } enum obs_editable_list_type obs_property_editable_list_type(obs_property_t *p) { - struct editable_list_data *data = get_type_data(p, - OBS_PROPERTY_EDITABLE_LIST); + struct editable_list_data *data = + get_type_data(p, OBS_PROPERTY_EDITABLE_LIST); return data ? data->type : OBS_EDITABLE_LIST_TYPE_STRINGS; } const char *obs_property_editable_list_filter(obs_property_t *p) { - struct editable_list_data *data = get_type_data(p, - OBS_PROPERTY_EDITABLE_LIST); + struct editable_list_data *data = + get_type_data(p, OBS_PROPERTY_EDITABLE_LIST); return data ? data->filter : NULL; } const char *obs_property_editable_list_default_path(obs_property_t *p) { - struct editable_list_data *data = get_type_data(p, - OBS_PROPERTY_EDITABLE_LIST); + struct editable_list_data *data = + get_type_data(p, OBS_PROPERTY_EDITABLE_LIST); return data ? data->default_path : NULL; } @@ -1164,7 +1226,8 @@ void obs_property_frame_rate_clear(obs_property_t *p) { struct frame_rate_data *data = get_type_data(p, OBS_PROPERTY_FRAME_RATE); - if (!data) return; + if (!data) + return; frame_rate_data_options_free(data); frame_rate_data_ranges_free(data); @@ -1174,7 +1237,8 @@ void obs_property_frame_rate_options_clear(obs_property_t *p) { struct frame_rate_data *data = get_type_data(p, OBS_PROPERTY_FRAME_RATE); - if (!data) return; + if (!data) + return; frame_rate_data_options_free(data); } @@ -1183,33 +1247,36 @@ void obs_property_frame_rate_fps_ranges_clear(obs_property_t *p) { struct frame_rate_data *data = get_type_data(p, OBS_PROPERTY_FRAME_RATE); - if (!data) return; + if (!data) + return; frame_rate_data_ranges_free(data); } -size_t obs_property_frame_rate_option_add(obs_property_t *p, - const char *name, const char *description) +size_t obs_property_frame_rate_option_add(obs_property_t *p, const char *name, + const char *description) { struct frame_rate_data *data = get_type_data(p, OBS_PROPERTY_FRAME_RATE); - if (!data) return DARRAY_INVALID; + if (!data) + return DARRAY_INVALID; struct frame_rate_option *opt = da_push_back_new(data->extra_options); - opt->name = bstrdup(name); + opt->name = bstrdup(name); opt->description = bstrdup(description); return data->extra_options.num - 1; } size_t obs_property_frame_rate_fps_range_add(obs_property_t *p, - struct media_frames_per_second min, - struct media_frames_per_second max) + struct media_frames_per_second min, + struct media_frames_per_second max) { struct frame_rate_data *data = get_type_data(p, OBS_PROPERTY_FRAME_RATE); - if (!data) return DARRAY_INVALID; + if (!data) + return DARRAY_INVALID; struct frame_rate_range *rng = da_push_back_new(data->ranges); @@ -1220,25 +1287,28 @@ size_t obs_property_frame_rate_fps_range_add(obs_property_t *p, } void obs_property_frame_rate_option_insert(obs_property_t *p, size_t idx, - const char *name, const char *description) + const char *name, + const char *description) { struct frame_rate_data *data = get_type_data(p, OBS_PROPERTY_FRAME_RATE); - if (!data) return; + if (!data) + return; struct frame_rate_option *opt = da_insert_new(data->extra_options, idx); - opt->name = bstrdup(name); + opt->name = bstrdup(name); opt->description = bstrdup(description); } -void obs_property_frame_rate_fps_range_insert(obs_property_t *p, size_t idx, - struct media_frames_per_second min, - struct media_frames_per_second max) +void obs_property_frame_rate_fps_range_insert( + obs_property_t *p, size_t idx, struct media_frames_per_second min, + struct media_frames_per_second max) { struct frame_rate_data *data = get_type_data(p, OBS_PROPERTY_FRAME_RATE); - if (!data) return; + if (!data) + return; struct frame_rate_range *rng = da_insert_new(data->ranges, idx); @@ -1253,22 +1323,23 @@ size_t obs_property_frame_rate_options_count(obs_property_t *p) return data ? data->extra_options.num : 0; } -const char *obs_property_frame_rate_option_name(obs_property_t *p, - size_t idx) +const char *obs_property_frame_rate_option_name(obs_property_t *p, size_t idx) { struct frame_rate_data *data = get_type_data(p, OBS_PROPERTY_FRAME_RATE); - return data && data->extra_options.num > idx ? - data->extra_options.array[idx].name : NULL; + return data && data->extra_options.num > idx + ? data->extra_options.array[idx].name + : NULL; } -const char *obs_property_frame_rate_option_description( - obs_property_t *p, size_t idx) +const char *obs_property_frame_rate_option_description(obs_property_t *p, + size_t idx) { struct frame_rate_data *data = get_type_data(p, OBS_PROPERTY_FRAME_RATE); - return data && data->extra_options.num > idx ? - data->extra_options.array[idx].description : NULL; + return data && data->extra_options.num > idx + ? data->extra_options.array[idx].description + : NULL; } size_t obs_property_frame_rate_fps_ranges_count(obs_property_t *p) @@ -1278,23 +1349,23 @@ size_t obs_property_frame_rate_fps_ranges_count(obs_property_t *p) return data ? data->ranges.num : 0; } -struct media_frames_per_second obs_property_frame_rate_fps_range_min( - obs_property_t *p, size_t idx) +struct media_frames_per_second +obs_property_frame_rate_fps_range_min(obs_property_t *p, size_t idx) { struct frame_rate_data *data = get_type_data(p, OBS_PROPERTY_FRAME_RATE); - return data && data->ranges.num > idx ? - data->ranges.array[idx].min_time : - (struct media_frames_per_second){0}; + return data && data->ranges.num > idx + ? data->ranges.array[idx].min_time + : (struct media_frames_per_second){0}; } -struct media_frames_per_second obs_property_frame_rate_fps_range_max( - obs_property_t *p, size_t idx) +struct media_frames_per_second +obs_property_frame_rate_fps_range_max(obs_property_t *p, size_t idx) { struct frame_rate_data *data = get_type_data(p, OBS_PROPERTY_FRAME_RATE); - return data && data->ranges.num > idx ? - data->ranges.array[idx].max_time : - (struct media_frames_per_second){0}; + return data && data->ranges.num > idx + ? data->ranges.array[idx].max_time + : (struct media_frames_per_second){0}; } enum obs_text_type obs_proprety_text_type(obs_property_t *p) diff --git a/libobs/obs-properties.h b/libobs/obs-properties.h index cf17941..a857778 100644 --- a/libobs/obs-properties.h +++ b/libobs/obs-properties.h @@ -40,7 +40,7 @@ extern "C" { #endif /** Only update when the user presses OK or Apply */ -#define OBS_PROPERTIES_DEFER_UPDATE (1<<0) +#define OBS_PROPERTIES_DEFER_UPDATE (1 << 0) enum obs_property_type { OBS_PROPERTY_INVALID, @@ -62,7 +62,7 @@ enum obs_combo_format { OBS_COMBO_FORMAT_INVALID, OBS_COMBO_FORMAT_INT, OBS_COMBO_FORMAT_FLOAT, - OBS_COMBO_FORMAT_STRING + OBS_COMBO_FORMAT_STRING, }; enum obs_combo_type { @@ -74,13 +74,13 @@ enum obs_combo_type { enum obs_editable_list_type { OBS_EDITABLE_LIST_TYPE_STRINGS, OBS_EDITABLE_LIST_TYPE_FILES, - OBS_EDITABLE_LIST_TYPE_FILES_AND_URLS + OBS_EDITABLE_LIST_TYPE_FILES_AND_URLS, }; enum obs_path_type { OBS_PATH_FILE, OBS_PATH_FILE_SAVE, - OBS_PATH_DIRECTORY + OBS_PATH_DIRECTORY, }; enum obs_text_type { @@ -91,7 +91,7 @@ enum obs_text_type { enum obs_number_type { OBS_NUMBER_SCROLLER, - OBS_NUMBER_SLIDER + OBS_NUMBER_SLIDER, }; enum obs_group_type { @@ -100,34 +100,34 @@ enum obs_group_type { OBS_GROUP_CHECKABLE, }; -#define OBS_FONT_BOLD (1<<0) -#define OBS_FONT_ITALIC (1<<1) -#define OBS_FONT_UNDERLINE (1<<2) -#define OBS_FONT_STRIKEOUT (1<<3) +#define OBS_FONT_BOLD (1 << 0) +#define OBS_FONT_ITALIC (1 << 1) +#define OBS_FONT_UNDERLINE (1 << 2) +#define OBS_FONT_STRIKEOUT (1 << 3) struct obs_properties; struct obs_property; typedef struct obs_properties obs_properties_t; -typedef struct obs_property obs_property_t; +typedef struct obs_property obs_property_t; /* ------------------------------------------------------------------------- */ EXPORT obs_properties_t *obs_properties_create(void); -EXPORT obs_properties_t *obs_properties_create_param(void *param, - void (*destroy)(void *param)); +EXPORT obs_properties_t * +obs_properties_create_param(void *param, void (*destroy)(void *param)); EXPORT void obs_properties_destroy(obs_properties_t *props); EXPORT void obs_properties_set_flags(obs_properties_t *props, uint32_t flags); EXPORT uint32_t obs_properties_get_flags(obs_properties_t *props); -EXPORT void obs_properties_set_param(obs_properties_t *props, - void *param, void (*destroy)(void *param)); +EXPORT void obs_properties_set_param(obs_properties_t *props, void *param, + void (*destroy)(void *param)); EXPORT void *obs_properties_get_param(obs_properties_t *props); EXPORT obs_property_t *obs_properties_first(obs_properties_t *props); EXPORT obs_property_t *obs_properties_get(obs_properties_t *props, - const char *property); + const char *property); EXPORT obs_properties_t *obs_properties_get_parent(obs_properties_t *props); @@ -142,14 +142,14 @@ EXPORT obs_properties_t *obs_properties_get_parent(obs_properties_t *props); * @param property Name of the property to remove. */ EXPORT void obs_properties_remove_by_name(obs_properties_t *props, - const char *property); + const char *property); /** * Applies settings to the properties by calling all the necessary * modification callbacks */ EXPORT void obs_properties_apply_settings(obs_properties_t *props, - obs_data_t *settings); + obs_data_t *settings); /* ------------------------------------------------------------------------- */ @@ -159,30 +159,39 @@ EXPORT void obs_properties_apply_settings(obs_properties_t *props, * otherwise return false. */ typedef bool (*obs_property_clicked_t)(obs_properties_t *props, - obs_property_t *property, void *data); + obs_property_t *property, void *data); EXPORT obs_property_t *obs_properties_add_bool(obs_properties_t *props, - const char *name, const char *description); + const char *name, + const char *description); EXPORT obs_property_t *obs_properties_add_int(obs_properties_t *props, - const char *name, const char *description, - int min, int max, int step); + const char *name, + const char *description, int min, + int max, int step); EXPORT obs_property_t *obs_properties_add_float(obs_properties_t *props, - const char *name, const char *description, - double min, double max, double step); + const char *name, + const char *description, + double min, double max, + double step); EXPORT obs_property_t *obs_properties_add_int_slider(obs_properties_t *props, - const char *name, const char *description, - int min, int max, int step); + const char *name, + const char *description, + int min, int max, + int step); EXPORT obs_property_t *obs_properties_add_float_slider(obs_properties_t *props, - const char *name, const char *description, - double min, double max, double step); + const char *name, + const char *description, + double min, double max, + double step); EXPORT obs_property_t *obs_properties_add_text(obs_properties_t *props, - const char *name, const char *description, - enum obs_text_type type); + const char *name, + const char *description, + enum obs_text_type type); /** * Adds a 'path' property. Can be a directory or a file. @@ -200,25 +209,29 @@ EXPORT obs_property_t *obs_properties_add_text(obs_properties_t *props, * double semi-colens. If multiple file types in a * filter, separate with space. */ -EXPORT obs_property_t *obs_properties_add_path(obs_properties_t *props, - const char *name, const char *description, - enum obs_path_type type, const char *filter, - const char *default_path); +EXPORT obs_property_t * +obs_properties_add_path(obs_properties_t *props, const char *name, + const char *description, enum obs_path_type type, + const char *filter, const char *default_path); EXPORT obs_property_t *obs_properties_add_list(obs_properties_t *props, - const char *name, const char *description, - enum obs_combo_type type, enum obs_combo_format format); + const char *name, + const char *description, + enum obs_combo_type type, + enum obs_combo_format format); EXPORT obs_property_t *obs_properties_add_color(obs_properties_t *props, - const char *name, const char *description); + const char *name, + const char *description); -EXPORT obs_property_t *obs_properties_add_button(obs_properties_t *props, - const char *name, const char *text, - obs_property_clicked_t callback); +EXPORT obs_property_t * +obs_properties_add_button(obs_properties_t *props, const char *name, + const char *text, obs_property_clicked_t callback); -EXPORT obs_property_t *obs_properties_add_button2(obs_properties_t *props, - const char *name, const char *text, - obs_property_clicked_t callback, void *priv); +EXPORT obs_property_t * +obs_properties_add_button2(obs_properties_t *props, const char *name, + const char *text, obs_property_clicked_t callback, + void *priv); /** * Adds a font selection property. @@ -230,20 +243,24 @@ EXPORT obs_property_t *obs_properties_add_button2(obs_properties_t *props, * flags: font flags integer (OBS_FONT_* defined above) */ EXPORT obs_property_t *obs_properties_add_font(obs_properties_t *props, - const char *name, const char *description); + const char *name, + const char *description); -EXPORT obs_property_t *obs_properties_add_editable_list(obs_properties_t *props, - const char *name, const char *description, - enum obs_editable_list_type type, const char *filter, - const char *default_path); +EXPORT obs_property_t * +obs_properties_add_editable_list(obs_properties_t *props, const char *name, + const char *description, + enum obs_editable_list_type type, + const char *filter, const char *default_path); EXPORT obs_property_t *obs_properties_add_frame_rate(obs_properties_t *props, - const char *name, const char *description); + const char *name, + const char *description); EXPORT obs_property_t *obs_properties_add_group(obs_properties_t *props, - const char *name, const char *description, enum obs_group_type type, - obs_properties_t *group); - + const char *name, + const char *description, + enum obs_group_type type, + obs_properties_t *group); /* ------------------------------------------------------------------------- */ @@ -253,14 +270,17 @@ EXPORT obs_property_t *obs_properties_add_group(obs_properties_t *props, * otherwise return false. */ typedef bool (*obs_property_modified_t)(obs_properties_t *props, - obs_property_t *property, obs_data_t *settings); + obs_property_t *property, + obs_data_t *settings); typedef bool (*obs_property_modified2_t)(void *priv, obs_properties_t *props, - obs_property_t *property, obs_data_t *settings); + obs_property_t *property, + obs_data_t *settings); -EXPORT void obs_property_set_modified_callback(obs_property_t *p, - obs_property_modified_t modified); -EXPORT void obs_property_set_modified_callback2(obs_property_t *p, - obs_property_modified2_t modified, void *priv); +EXPORT void +obs_property_set_modified_callback(obs_property_t *p, + obs_property_modified_t modified); +EXPORT void obs_property_set_modified_callback2( + obs_property_t *p, obs_property_modified2_t modified, void *priv); EXPORT bool obs_property_modified(obs_property_t *p, obs_data_t *settings); EXPORT bool obs_property_button_clicked(obs_property_t *p, void *obj); @@ -269,72 +289,74 @@ EXPORT void obs_property_set_visible(obs_property_t *p, bool visible); EXPORT void obs_property_set_enabled(obs_property_t *p, bool enabled); EXPORT void obs_property_set_description(obs_property_t *p, - const char *description); + const char *description); EXPORT void obs_property_set_long_description(obs_property_t *p, - const char *long_description); + const char *long_description); -EXPORT const char * obs_property_name(obs_property_t *p); -EXPORT const char * obs_property_description(obs_property_t *p); -EXPORT const char * obs_property_long_description(obs_property_t *p); +EXPORT const char *obs_property_name(obs_property_t *p); +EXPORT const char *obs_property_description(obs_property_t *p); +EXPORT const char *obs_property_long_description(obs_property_t *p); EXPORT enum obs_property_type obs_property_get_type(obs_property_t *p); -EXPORT bool obs_property_enabled(obs_property_t *p); -EXPORT bool obs_property_visible(obs_property_t *p); +EXPORT bool obs_property_enabled(obs_property_t *p); +EXPORT bool obs_property_visible(obs_property_t *p); -EXPORT bool obs_property_next(obs_property_t **p); +EXPORT bool obs_property_next(obs_property_t **p); -EXPORT int obs_property_int_min(obs_property_t *p); -EXPORT int obs_property_int_max(obs_property_t *p); -EXPORT int obs_property_int_step(obs_property_t *p); -EXPORT enum obs_number_type obs_property_int_type(obs_property_t *p); -EXPORT const char * obs_property_int_suffix(obs_property_t *p); -EXPORT double obs_property_float_min(obs_property_t *p); -EXPORT double obs_property_float_max(obs_property_t *p); -EXPORT double obs_property_float_step(obs_property_t *p); -EXPORT enum obs_number_type obs_property_float_type(obs_property_t *p); -EXPORT const char * obs_property_float_suffix(obs_property_t *p); -EXPORT enum obs_text_type obs_property_text_type(obs_property_t *p); -EXPORT enum obs_path_type obs_property_path_type(obs_property_t *p); -EXPORT const char * obs_property_path_filter(obs_property_t *p); -EXPORT const char * obs_property_path_default_path(obs_property_t *p); -EXPORT enum obs_combo_type obs_property_list_type(obs_property_t *p); -EXPORT enum obs_combo_format obs_property_list_format(obs_property_t *p); +EXPORT int obs_property_int_min(obs_property_t *p); +EXPORT int obs_property_int_max(obs_property_t *p); +EXPORT int obs_property_int_step(obs_property_t *p); +EXPORT enum obs_number_type obs_property_int_type(obs_property_t *p); +EXPORT const char *obs_property_int_suffix(obs_property_t *p); +EXPORT double obs_property_float_min(obs_property_t *p); +EXPORT double obs_property_float_max(obs_property_t *p); +EXPORT double obs_property_float_step(obs_property_t *p); +EXPORT enum obs_number_type obs_property_float_type(obs_property_t *p); +EXPORT const char *obs_property_float_suffix(obs_property_t *p); +EXPORT enum obs_text_type obs_property_text_type(obs_property_t *p); +EXPORT enum obs_path_type obs_property_path_type(obs_property_t *p); +EXPORT const char *obs_property_path_filter(obs_property_t *p); +EXPORT const char *obs_property_path_default_path(obs_property_t *p); +EXPORT enum obs_combo_type obs_property_list_type(obs_property_t *p); +EXPORT enum obs_combo_format obs_property_list_format(obs_property_t *p); -EXPORT void obs_property_int_set_limits(obs_property_t *p, - int min, int max, int step); -EXPORT void obs_property_float_set_limits(obs_property_t *p, - double min, double max, double step); +EXPORT void obs_property_int_set_limits(obs_property_t *p, int min, int max, + int step); +EXPORT void obs_property_float_set_limits(obs_property_t *p, double min, + double max, double step); EXPORT void obs_property_int_set_suffix(obs_property_t *p, const char *suffix); -EXPORT void obs_property_float_set_suffix(obs_property_t *p, const char *suffix); +EXPORT void obs_property_float_set_suffix(obs_property_t *p, + const char *suffix); EXPORT void obs_property_list_clear(obs_property_t *p); -EXPORT size_t obs_property_list_add_string(obs_property_t *p, - const char *name, const char *val); -EXPORT size_t obs_property_list_add_int(obs_property_t *p, - const char *name, long long val); -EXPORT size_t obs_property_list_add_float(obs_property_t *p, - const char *name, double val); +EXPORT size_t obs_property_list_add_string(obs_property_t *p, const char *name, + const char *val); +EXPORT size_t obs_property_list_add_int(obs_property_t *p, const char *name, + long long val); +EXPORT size_t obs_property_list_add_float(obs_property_t *p, const char *name, + double val); EXPORT void obs_property_list_insert_string(obs_property_t *p, size_t idx, - const char *name, const char *val); + const char *name, const char *val); EXPORT void obs_property_list_insert_int(obs_property_t *p, size_t idx, - const char *name, long long val); + const char *name, long long val); EXPORT void obs_property_list_insert_float(obs_property_t *p, size_t idx, - const char *name, double val); + const char *name, double val); EXPORT void obs_property_list_item_disable(obs_property_t *p, size_t idx, - bool disabled); + bool disabled); EXPORT bool obs_property_list_item_disabled(obs_property_t *p, size_t idx); EXPORT void obs_property_list_item_remove(obs_property_t *p, size_t idx); -EXPORT size_t obs_property_list_item_count(obs_property_t *p); +EXPORT size_t obs_property_list_item_count(obs_property_t *p); EXPORT const char *obs_property_list_item_name(obs_property_t *p, size_t idx); EXPORT const char *obs_property_list_item_string(obs_property_t *p, size_t idx); -EXPORT long long obs_property_list_item_int(obs_property_t *p, size_t idx); -EXPORT double obs_property_list_item_float(obs_property_t *p, size_t idx); +EXPORT long long obs_property_list_item_int(obs_property_t *p, size_t idx); +EXPORT double obs_property_list_item_float(obs_property_t *p, size_t idx); -EXPORT enum obs_editable_list_type obs_property_editable_list_type(obs_property_t *p); +EXPORT enum obs_editable_list_type +obs_property_editable_list_type(obs_property_t *p); EXPORT const char *obs_property_editable_list_filter(obs_property_t *p); EXPORT const char *obs_property_editable_list_default_path(obs_property_t *p); @@ -343,36 +365,38 @@ EXPORT void obs_property_frame_rate_options_clear(obs_property_t *p); EXPORT void obs_property_frame_rate_fps_ranges_clear(obs_property_t *p); EXPORT size_t obs_property_frame_rate_option_add(obs_property_t *p, - const char *name, const char *description); -EXPORT size_t obs_property_frame_rate_fps_range_add(obs_property_t *p, - struct media_frames_per_second min, - struct media_frames_per_second max); + const char *name, + const char *description); +EXPORT size_t obs_property_frame_rate_fps_range_add( + obs_property_t *p, struct media_frames_per_second min, + struct media_frames_per_second max); EXPORT void obs_property_frame_rate_option_insert(obs_property_t *p, size_t idx, - const char *name, const char *description); -EXPORT void obs_property_frame_rate_fps_range_insert(obs_property_t *p, - size_t idx, - struct media_frames_per_second min, - struct media_frames_per_second max); + const char *name, + const char *description); +EXPORT void +obs_property_frame_rate_fps_range_insert(obs_property_t *p, size_t idx, + struct media_frames_per_second min, + struct media_frames_per_second max); -EXPORT size_t obs_property_frame_rate_options_count(obs_property_t *p); +EXPORT size_t obs_property_frame_rate_options_count(obs_property_t *p); EXPORT const char *obs_property_frame_rate_option_name(obs_property_t *p, - size_t idx); -EXPORT const char *obs_property_frame_rate_option_description( - obs_property_t *p, size_t idx); + size_t idx); +EXPORT const char *obs_property_frame_rate_option_description(obs_property_t *p, + size_t idx); -EXPORT size_t obs_property_frame_rate_fps_ranges_count(obs_property_t *p); -EXPORT struct media_frames_per_second obs_property_frame_rate_fps_range_min( - obs_property_t *p, size_t idx); -EXPORT struct media_frames_per_second obs_property_frame_rate_fps_range_max( - obs_property_t *p, size_t idx); +EXPORT size_t obs_property_frame_rate_fps_ranges_count(obs_property_t *p); +EXPORT struct media_frames_per_second +obs_property_frame_rate_fps_range_min(obs_property_t *p, size_t idx); +EXPORT struct media_frames_per_second +obs_property_frame_rate_fps_range_max(obs_property_t *p, size_t idx); EXPORT enum obs_group_type obs_property_group_type(obs_property_t *p); EXPORT obs_properties_t *obs_property_group_content(obs_property_t *p); #ifndef SWIG DEPRECATED -EXPORT enum obs_text_type obs_proprety_text_type(obs_property_t *p); +EXPORT enum obs_text_type obs_proprety_text_type(obs_property_t *p); #endif #ifdef __cplusplus diff --git a/libobs/obs-scene.c b/libobs/obs-scene.c index f23fd49..dafae00 100644 --- a/libobs/obs-scene.c +++ b/libobs/obs-scene.c @@ -25,15 +25,13 @@ const struct obs_source_info group_info; static void resize_group(obs_sceneitem_t *group); static void resize_scene(obs_scene_t *scene); static void signal_parent(obs_scene_t *parent, const char *name, - calldata_t *params); -static void get_ungrouped_transform(obs_sceneitem_t *group, - struct vec2 *pos, - struct vec2 *scale, - float *rot); + calldata_t *params); +static void get_ungrouped_transform(obs_sceneitem_t *group, struct vec2 *pos, + struct vec2 *scale, float *rot); static inline bool crop_enabled(const struct obs_sceneitem_crop *crop); static inline bool item_texture_enabled(const struct obs_scene_item *item); static void init_hotkeys(obs_scene_t *scene, obs_sceneitem_t *item, - const char *name); + const char *name); /* NOTE: For proper mutex lock order (preventing mutual cross-locks), never * lock the graphics mutex inside either of the scene mutexes. @@ -54,7 +52,8 @@ static const char *obs_scene_signals[] = { "void item_select(ptr scene, ptr item)", "void item_deselect(ptr scene, ptr item)", "void item_transform(ptr scene, ptr item)", - NULL + "void item_locked(ptr scene, ptr item, bool locked)", + NULL, }; static inline void signal_item_remove(struct obs_scene_item *item) @@ -94,7 +93,7 @@ static void *scene_create(obs_data_t *settings, struct obs_source *source) } signal_handler_add_array(obs_source_get_signal_handler(source), - obs_scene_signals); + obs_scene_signals); if (pthread_mutexattr_init(&attr) != 0) goto fail; @@ -151,7 +150,7 @@ static inline void remove_without_release(struct obs_scene_item *item) static void remove_all_items(struct obs_scene *scene) { struct obs_scene_item *item; - DARRAY(struct obs_scene_item*) items; + DARRAY(struct obs_scene_item *) items; da_init(items); @@ -185,9 +184,8 @@ static void scene_destroy(void *data) bfree(scene); } -static void scene_enum_sources(void *data, - obs_source_enum_proc_t enum_callback, - void *param, bool active) +static void scene_enum_sources(void *data, obs_source_enum_proc_t enum_callback, + void *param, bool active) { struct obs_scene *scene = data; struct obs_scene_item *item; @@ -211,15 +209,15 @@ static void scene_enum_sources(void *data, } static void scene_enum_active_sources(void *data, - obs_source_enum_proc_t enum_callback, - void *param) + obs_source_enum_proc_t enum_callback, + void *param) { scene_enum_sources(data, enum_callback, param, true); } static void scene_enum_all_sources(void *data, - obs_source_enum_proc_t enum_callback, - void *param) + obs_source_enum_proc_t enum_callback, + void *param) { scene_enum_sources(data, enum_callback, param, false); } @@ -238,9 +236,10 @@ static inline void detach_sceneitem(struct obs_scene_item *item) } static inline void attach_sceneitem(struct obs_scene *parent, - struct obs_scene_item *item, struct obs_scene_item *prev) + struct obs_scene_item *item, + struct obs_scene_item *prev) { - item->prev = prev; + item->prev = prev; item->parent = parent; if (prev) { @@ -270,15 +269,15 @@ void add_alignment(struct vec2 *v, uint32_t align, int cx, int cy) } static void calculate_bounds_data(struct obs_scene_item *item, - struct vec2 *origin, struct vec2 *scale, - uint32_t *cx, uint32_t *cy) + struct vec2 *origin, struct vec2 *scale, + uint32_t *cx, uint32_t *cy) { - float width = (float)(*cx) * fabsf(scale->x); - float height = (float)(*cy) * fabsf(scale->y); - float item_aspect = width / height; - float bounds_aspect = item->bounds.x / item->bounds.y; - uint32_t bounds_type = item->bounds_type; - float width_diff, height_diff; + float width = (float)(*cx) * fabsf(scale->x); + float height = (float)(*cy) * fabsf(scale->y); + float item_aspect = width / height; + float bounds_aspect = item->bounds.x / item->bounds.y; + uint32_t bounds_type = item->bounds_type; + float width_diff, height_diff; if (item->bounds_type == OBS_BOUNDS_MAX_ONLY) if (width > item->bounds.x || height > item->bounds.y) @@ -286,15 +285,14 @@ static void calculate_bounds_data(struct obs_scene_item *item, if (bounds_type == OBS_BOUNDS_SCALE_INNER || bounds_type == OBS_BOUNDS_SCALE_OUTER) { - bool use_width = (bounds_aspect < item_aspect); + bool use_width = (bounds_aspect < item_aspect); float mul; if (item->bounds_type == OBS_BOUNDS_SCALE_OUTER) use_width = !use_width; - mul = use_width ? - item->bounds.x / width : - item->bounds.y / height; + mul = use_width ? item->bounds.x / width + : item->bounds.y / height; vec2_mulf(scale, scale, mul); @@ -309,26 +307,26 @@ static void calculate_bounds_data(struct obs_scene_item *item, scale->y = item->bounds.y / (float)(*cy); } - width = (float)(*cx) * scale->x; - height = (float)(*cy) * scale->y; - width_diff = item->bounds.x - width; + width = (float)(*cx) * scale->x; + height = (float)(*cy) * scale->y; + width_diff = item->bounds.x - width; height_diff = item->bounds.y - height; - *cx = (uint32_t)item->bounds.x; - *cy = (uint32_t)item->bounds.y; + *cx = (uint32_t)item->bounds.x; + *cy = (uint32_t)item->bounds.y; - add_alignment(origin, item->bounds_align, - (int)-width_diff, (int)-height_diff); + add_alignment(origin, item->bounds_align, (int)-width_diff, + (int)-height_diff); } static inline uint32_t calc_cx(const struct obs_scene_item *item, - uint32_t width) + uint32_t width) { uint32_t crop_cx = item->crop.left + item->crop.right; return (crop_cx > width) ? 2 : (width - crop_cx); } static inline uint32_t calc_cy(const struct obs_scene_item *item, - uint32_t height) + uint32_t height) { uint32_t crop_cy = item->crop.top + item->crop.bottom; return (crop_cy > height) ? 2 : (height - crop_cy); @@ -336,25 +334,25 @@ static inline uint32_t calc_cy(const struct obs_scene_item *item, static void update_item_transform(struct obs_scene_item *item, bool update_tex) { - uint32_t width; - uint32_t height; - uint32_t cx; - uint32_t cy; - struct vec2 base_origin; - struct vec2 origin; - struct vec2 scale; + uint32_t width; + uint32_t height; + uint32_t cx; + uint32_t cy; + struct vec2 base_origin; + struct vec2 origin; + struct vec2 scale; struct calldata params; - uint8_t stack[128]; + uint8_t stack[128]; if (os_atomic_load_long(&item->defer_update) > 0) return; - width = obs_source_get_width(item->source); - height = obs_source_get_height(item->source); - cx = calc_cx(item, width); - cy = calc_cy(item, height); - scale = item->scale; - item->last_width = width; + width = obs_source_get_width(item->source); + height = obs_source_get_height(item->source); + cx = calc_cx(item, width); + cy = calc_cy(item, height); + scale = item->scale; + item->last_width = width; item->last_height = height; width = cx; @@ -375,14 +373,14 @@ static void update_item_transform(struct obs_scene_item *item, bool update_tex) add_alignment(&origin, item->align, (int)cx, (int)cy); matrix4_identity(&item->draw_transform); - matrix4_scale3f(&item->draw_transform, &item->draw_transform, - scale.x, scale.y, 1.0f); + matrix4_scale3f(&item->draw_transform, &item->draw_transform, scale.x, + scale.y, 1.0f); matrix4_translate3f(&item->draw_transform, &item->draw_transform, - -origin.x, -origin.y, 0.0f); - matrix4_rotate_aa4f(&item->draw_transform, &item->draw_transform, - 0.0f, 0.0f, 1.0f, RAD(item->rot)); + -origin.x, -origin.y, 0.0f); + matrix4_rotate_aa4f(&item->draw_transform, &item->draw_transform, 0.0f, + 0.0f, 1.0f, RAD(item->rot)); matrix4_translate3f(&item->draw_transform, &item->draw_transform, - item->pos.x, item->pos.y, 0.0f); + item->pos.x, item->pos.y, 0.0f); item->output_scale = scale; @@ -391,7 +389,7 @@ static void update_item_transform(struct obs_scene_item *item, bool update_tex) if (item->bounds_type != OBS_BOUNDS_NONE) { vec2_copy(&scale, &item->bounds); } else { - scale.x = (float)width * item->scale.x; + scale.x = (float)width * item->scale.x; scale.y = (float)height * item->scale.y; } @@ -400,14 +398,14 @@ static void update_item_transform(struct obs_scene_item *item, bool update_tex) add_alignment(&base_origin, item->align, (int)scale.x, (int)scale.y); matrix4_identity(&item->box_transform); - matrix4_scale3f(&item->box_transform, &item->box_transform, - scale.x, scale.y, 1.0f); + matrix4_scale3f(&item->box_transform, &item->box_transform, scale.x, + scale.y, 1.0f); matrix4_translate3f(&item->box_transform, &item->box_transform, - -base_origin.x, -base_origin.y, 0.0f); - matrix4_rotate_aa4f(&item->box_transform, &item->box_transform, - 0.0f, 0.0f, 1.0f, RAD(item->rot)); + -base_origin.x, -base_origin.y, 0.0f); + matrix4_rotate_aa4f(&item->box_transform, &item->box_transform, 0.0f, + 0.0f, 1.0f, RAD(item->rot)); matrix4_translate3f(&item->box_transform, &item->box_transform, - item->pos.x, item->pos.y, 0.0f); + item->pos.x, item->pos.y, 0.0f); /* ----------------------- */ @@ -435,7 +433,7 @@ static void update_item_transform(struct obs_scene_item *item, bool update_tex) static inline bool source_size_changed(struct obs_scene_item *item) { - uint32_t width = obs_source_get_width(item->source); + uint32_t width = obs_source_get_width(item->source); uint32_t height = obs_source_get_height(item->source); return item->last_width != width || item->last_height != height; @@ -459,29 +457,36 @@ static inline bool item_is_scene(const struct obs_scene_item *item) static inline bool item_texture_enabled(const struct obs_scene_item *item) { return crop_enabled(&item->crop) || scale_filter_enabled(item) || - (item_is_scene(item) && !item->is_group); + (item_is_scene(item) && !item->is_group); } static void render_item_texture(struct obs_scene_item *item) { - GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_ITEM_TEXTURE, "render_item_texture"); - gs_texture_t *tex = gs_texrender_get_texture(item->item_render); + if (!tex) { + return; + } + + GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_ITEM_TEXTURE, + "render_item_texture"); + gs_effect_t *effect = obs->video.default_effect; enum obs_scale_type type = item->scale_filter; uint32_t cx = gs_texture_get_width(tex); uint32_t cy = gs_texture_get_height(tex); + const char *tech = "Draw"; if (type != OBS_SCALE_DISABLE) { if (type == OBS_SCALE_POINT) { - gs_eparam_t *image = gs_effect_get_param_by_name( - effect, "image"); + gs_eparam_t *image = + gs_effect_get_param_by_name(effect, "image"); gs_effect_set_next_sampler(image, - obs->video.point_sampler); + obs->video.point_sampler); } else if (!close_float(item->output_scale.x, 1.0f, EPSILON) || - !close_float(item->output_scale.y, 1.0f, EPSILON)) { + !close_float(item->output_scale.y, 1.0f, EPSILON)) { gs_eparam_t *scale_param; + gs_eparam_t *scale_i_param; if (item->output_scale.x < 0.5f || item->output_scale.y < 0.5f) { @@ -492,17 +497,26 @@ static void render_item_texture(struct obs_scene_item *item) effect = obs->video.lanczos_effect; } else if (type == OBS_SCALE_AREA) { effect = obs->video.area_effect; + if ((item->output_scale.x >= 1.0f) && + (item->output_scale.y >= 1.0f)) + tech = "DrawUpscale"; } - scale_param = gs_effect_get_param_by_name(effect, - "base_dimension_i"); + scale_param = gs_effect_get_param_by_name( + effect, "base_dimension"); if (scale_param) { - struct vec2 base_res_i = { - 1.0f / (float)cx, - 1.0f / (float)cy - }; + struct vec2 base_res = {(float)cx, (float)cy}; - gs_effect_set_vec2(scale_param, &base_res_i); + gs_effect_set_vec2(scale_param, &base_res); + } + + scale_i_param = gs_effect_get_param_by_name( + effect, "base_dimension_i"); + if (scale_i_param) { + struct vec2 base_res_i = {1.0f / (float)cx, + 1.0f / (float)cy}; + + gs_effect_set_vec2(scale_i_param, &base_res_i); } } } @@ -510,7 +524,7 @@ static void render_item_texture(struct obs_scene_item *item) gs_blend_state_push(); gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); - while (gs_effect_loop(effect, "Draw")) + while (gs_effect_loop(effect, tech)) obs_source_draw(tex, 0, 0, 0, 0, 0); gs_blend_state_pop(); @@ -521,10 +535,10 @@ static void render_item_texture(struct obs_scene_item *item) static inline void render_item(struct obs_scene_item *item) { GS_DEBUG_MARKER_BEGIN_FORMAT(GS_DEBUG_COLOR_ITEM, "Item: %s", - obs_source_get_name(item->source)); + obs_source_get_name(item->source)); if (item->item_render) { - uint32_t width = obs_source_get_width(item->source); + uint32_t width = obs_source_get_width(item->source); uint32_t height = obs_source_get_height(item->source); if (!width || !height) { @@ -535,20 +549,18 @@ static inline void render_item(struct obs_scene_item *item) uint32_t cy = calc_cy(item, height); if (cx && cy && gs_texrender_begin(item->item_render, cx, cy)) { - float cx_scale = (float)width / (float)cx; + float cx_scale = (float)width / (float)cx; float cy_scale = (float)height / (float)cy; struct vec4 clear_color; vec4_zero(&clear_color); gs_clear(GS_CLEAR_COLOR, &clear_color, 0.0f, 0); gs_ortho(0.0f, (float)width, 0.0f, (float)height, - -100.0f, 100.0f); + -100.0f, 100.0f); gs_matrix_scale3f(cx_scale, cy_scale, 1.0f); - gs_matrix_translate3f( - -(float)item->crop.left, - -(float)item->crop.top, - 0.0f); + gs_matrix_translate3f(-(float)item->crop.left, + -(float)item->crop.top, 0.0f); obs_source_video_render(item->source); @@ -587,11 +599,14 @@ static void scene_video_tick(void *data, float seconds) } /* assumes video lock */ -static void update_transforms_and_prune_sources(obs_scene_t *scene, - struct darray *remove_items, obs_sceneitem_t *group_sceneitem) +static void +update_transforms_and_prune_sources(obs_scene_t *scene, + struct darray *remove_items, + obs_sceneitem_t *group_sceneitem) { struct obs_scene_item *item = scene->first_item; - bool rebuild_group = group_sceneitem && + bool rebuild_group = + group_sceneitem && os_atomic_load_bool(&group_sceneitem->update_group_resize); while (item) { @@ -600,8 +615,8 @@ static void update_transforms_and_prune_sources(obs_scene_t *scene, item = item->next; remove_without_release(del_item); - darray_push_back(sizeof(struct obs_scene_item*), - remove_items, &del_item); + darray_push_back(sizeof(struct obs_scene_item *), + remove_items, &del_item); rebuild_group = true; continue; } @@ -611,7 +626,7 @@ static void update_transforms_and_prune_sources(obs_scene_t *scene, video_lock(group_scene); update_transforms_and_prune_sources(group_scene, - remove_items, item); + remove_items, item); video_unlock(group_scene); } @@ -631,7 +646,7 @@ static void update_transforms_and_prune_sources(obs_scene_t *scene, static void scene_video_render(void *data, gs_effect_t *effect) { - DARRAY(struct obs_scene_item*) remove_items; + DARRAY(struct obs_scene_item *) remove_items; struct obs_scene *scene = data; struct obs_scene_item *item; @@ -641,7 +656,7 @@ static void scene_video_render(void *data, gs_effect_t *effect) if (!scene->is_group) { update_transforms_and_prune_sources(scene, &remove_items.da, - NULL); + NULL); } gs_blend_state_push(); @@ -675,7 +690,7 @@ static void set_visibility(struct obs_scene_item *item, bool vis) if (os_atomic_load_long(&item->active_refs) > 0) { if (!vis) obs_source_remove_active_child(item->parent->source, - item->source); + item->source); } else if (vis) { obs_source_add_active_child(item->parent->source, item->source); } @@ -691,9 +706,9 @@ static void scene_load(void *data, obs_data_t *settings); static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data) { - const char *name = obs_data_get_string(item_data, "name"); - obs_source_t *source; - const char *scale_filter_str; + const char *name = obs_data_get_string(item_data, "name"); + obs_source_t *source; + const char *scale_filter_str; struct obs_scene_item *item; bool visible; bool lock; @@ -703,17 +718,20 @@ static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data) source = obs_get_source_by_name(name); if (!source) { - blog(LOG_WARNING, "[scene_load_item] Source %s not " - "found!", name); + blog(LOG_WARNING, + "[scene_load_item] Source %s not " + "found!", + name); return; } item = obs_scene_add(scene, source); if (!item) { - blog(LOG_WARNING, "[scene_load_item] Could not add source '%s' " - "to scene '%s'!", - name, obs_source_get_name(scene->source)); - + blog(LOG_WARNING, + "[scene_load_item] Could not add source '%s' " + "to scene '%s'!", + name, obs_source_get_name(scene->source)); + obs_source_release(source); return; } @@ -721,17 +739,17 @@ static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data) item->is_group = source->info.id == group_info.id; obs_data_set_default_int(item_data, "align", - OBS_ALIGN_TOP | OBS_ALIGN_LEFT); + OBS_ALIGN_TOP | OBS_ALIGN_LEFT); if (obs_data_has_user_value(item_data, "id")) item->id = obs_data_get_int(item_data, "id"); - item->rot = (float)obs_data_get_double(item_data, "rot"); - item->align = (uint32_t)obs_data_get_int(item_data, "align"); + item->rot = (float)obs_data_get_double(item_data, "rot"); + item->align = (uint32_t)obs_data_get_int(item_data, "align"); visible = obs_data_get_bool(item_data, "visible"); lock = obs_data_get_bool(item_data, "locked"); - obs_data_get_vec2(item_data, "pos", &item->pos); - obs_data_get_vec2(item_data, "scale", &item->scale); + obs_data_get_vec2(item_data, "pos", &item->pos); + obs_data_get_vec2(item_data, "scale", &item->scale); obs_data_release(item->private_settings); item->private_settings = @@ -742,17 +760,17 @@ static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data) set_visibility(item, visible); obs_sceneitem_set_locked(item, lock); - item->bounds_type = - (enum obs_bounds_type)obs_data_get_int(item_data, - "bounds_type"); + item->bounds_type = (enum obs_bounds_type)obs_data_get_int( + item_data, "bounds_type"); item->bounds_align = (uint32_t)obs_data_get_int(item_data, "bounds_align"); obs_data_get_vec2(item_data, "bounds", &item->bounds); - item->crop.left = (uint32_t)obs_data_get_int(item_data, "crop_left"); - item->crop.top = (uint32_t)obs_data_get_int(item_data, "crop_top"); - item->crop.right = (uint32_t)obs_data_get_int(item_data, "crop_right"); - item->crop.bottom = (uint32_t)obs_data_get_int(item_data, "crop_bottom"); + item->crop.left = (uint32_t)obs_data_get_int(item_data, "crop_left"); + item->crop.top = (uint32_t)obs_data_get_int(item_data, "crop_top"); + item->crop.right = (uint32_t)obs_data_get_int(item_data, "crop_right"); + item->crop.bottom = + (uint32_t)obs_data_get_int(item_data, "crop_bottom"); scale_filter_str = obs_data_get_string(item_data, "scale_filter"); item->scale_filter = OBS_SCALE_DISABLE; @@ -791,11 +809,12 @@ static void scene_load(void *data, obs_data_t *settings) { struct obs_scene *scene = data; obs_data_array_t *items = obs_data_get_array(settings, "items"); - size_t count, i; + size_t count, i; remove_all_items(scene); - if (!items) return; + if (!items) + return; count = obs_data_array_count(items); @@ -820,11 +839,11 @@ static void scene_load(void *data, obs_data_t *settings) static void scene_save(void *data, obs_data_t *settings); static void scene_save_item(obs_data_array_t *array, - struct obs_scene_item *item, - struct obs_scene_item *backup_group) + struct obs_scene_item *item, + struct obs_scene_item *backup_group) { obs_data_t *item_data = obs_data_create(); - const char *name = obs_source_get_name(item->source); + const char *name = obs_source_get_name(item->source); const char *scale_filter; struct vec2 pos = item->pos; struct vec2 scale = item->scale; @@ -834,22 +853,22 @@ static void scene_save_item(obs_data_array_t *array, get_ungrouped_transform(backup_group, &pos, &scale, &rot); } - obs_data_set_string(item_data, "name", name); - obs_data_set_bool (item_data, "visible", item->user_visible); - obs_data_set_bool (item_data, "locked", item->locked); - obs_data_set_double(item_data, "rot", rot); - obs_data_set_vec2 (item_data, "pos", &pos); - obs_data_set_vec2 (item_data, "scale", &scale); - obs_data_set_int (item_data, "align", (int)item->align); - obs_data_set_int (item_data, "bounds_type", (int)item->bounds_type); - obs_data_set_int (item_data, "bounds_align", (int)item->bounds_align); - obs_data_set_vec2 (item_data, "bounds", &item->bounds); - obs_data_set_int (item_data, "crop_left", (int)item->crop.left); - obs_data_set_int (item_data, "crop_top", (int)item->crop.top); - obs_data_set_int (item_data, "crop_right", (int)item->crop.right); - obs_data_set_int (item_data, "crop_bottom", (int)item->crop.bottom); - obs_data_set_int (item_data, "id", item->id); - obs_data_set_bool (item_data, "group_item_backup", !!backup_group); + obs_data_set_string(item_data, "name", name); + obs_data_set_bool(item_data, "visible", item->user_visible); + obs_data_set_bool(item_data, "locked", item->locked); + obs_data_set_double(item_data, "rot", rot); + obs_data_set_vec2(item_data, "pos", &pos); + obs_data_set_vec2(item_data, "scale", &scale); + obs_data_set_int(item_data, "align", (int)item->align); + obs_data_set_int(item_data, "bounds_type", (int)item->bounds_type); + obs_data_set_int(item_data, "bounds_align", (int)item->bounds_align); + obs_data_set_vec2(item_data, "bounds", &item->bounds); + obs_data_set_int(item_data, "crop_left", (int)item->crop.left); + obs_data_set_int(item_data, "crop_top", (int)item->crop.top); + obs_data_set_int(item_data, "crop_right", (int)item->crop.right); + obs_data_set_int(item_data, "crop_bottom", (int)item->crop.bottom); + obs_data_set_int(item_data, "id", item->id); + obs_data_set_bool(item_data, "group_item_backup", !!backup_group); if (item->is_group) { obs_scene_t *group_scene = item->source->context.data; @@ -884,8 +903,7 @@ static void scene_save_item(obs_data_array_t *array, obs_data_set_string(item_data, "scale_filter", scale_filter); - obs_data_set_obj(item_data, "private_settings", - item->private_settings); + obs_data_set_obj(item_data, "private_settings", item->private_settings); obs_data_array_push_back(array, item_data); obs_data_release(item_data); @@ -893,8 +911,8 @@ static void scene_save_item(obs_data_array_t *array, static void scene_save(void *data, obs_data_t *settings) { - struct obs_scene *scene = data; - obs_data_array_t *array = obs_data_array_create(); + struct obs_scene *scene = data; + obs_data_array_t *array = obs_data_array_create(); struct obs_scene_item *item; full_lock(scene); @@ -931,7 +949,8 @@ static uint32_t scene_getheight(void *data) } static void apply_scene_item_audio_actions(struct obs_scene_item *item, - float **p_buf, uint64_t ts, size_t sample_rate) + float **p_buf, uint64_t ts, + size_t sample_rate) { bool cur_visible = item->visible; uint64_t frame_num = 0; @@ -955,7 +974,7 @@ static void apply_scene_item_audio_actions(struct obs_scene_item *item, timestamp = ts; new_frame_num = (timestamp - ts) * (uint64_t)sample_rate / - 1000000000ULL; + 1000000000ULL; if (ts && new_frame_num >= AUDIO_OUTPUT_FRAMES) break; @@ -984,13 +1003,13 @@ static void apply_scene_item_audio_actions(struct obs_scene_item *item, while (deref_count--) { if (os_atomic_dec_long(&item->active_refs) == 0) { obs_source_remove_active_child(item->parent->source, - item->source); + item->source); } } } -static bool apply_scene_item_volume(struct obs_scene_item *item, - float **buf, uint64_t ts, size_t sample_rate) +static bool apply_scene_item_volume(struct obs_scene_item *item, float **buf, + uint64_t ts, size_t sample_rate) { bool actions_pending; struct item_action action; @@ -1005,11 +1024,11 @@ static bool apply_scene_item_volume(struct obs_scene_item *item, if (actions_pending) { uint64_t duration = (uint64_t)AUDIO_OUTPUT_FRAMES * - 1000000000ULL / (uint64_t)sample_rate; + 1000000000ULL / (uint64_t)sample_rate; if (!ts || action.timestamp < (ts + duration)) { apply_scene_item_audio_actions(item, buf, ts, - sample_rate); + sample_rate); return true; } } @@ -1018,13 +1037,14 @@ static bool apply_scene_item_volume(struct obs_scene_item *item, } static void process_all_audio_actions(struct obs_scene_item *item, - size_t sample_rate) + size_t sample_rate) { - while (apply_scene_item_volume(item, NULL, 0, sample_rate)); + while (apply_scene_item_volume(item, NULL, 0, sample_rate)) + ; } static void mix_audio_with_buf(float *p_out, float *p_in, float *buf_in, - size_t pos, size_t count) + size_t pos, size_t count) { register float *out = p_out; register float *buf = buf_in + pos; @@ -1035,8 +1055,8 @@ static void mix_audio_with_buf(float *p_out, float *p_in, float *buf_in, *(out++) += *(in++) * *(buf++); } -static inline void mix_audio(float *p_out, float *p_in, - size_t pos, size_t count) +static inline void mix_audio(float *p_out, float *p_in, size_t pos, + size_t count) { register float *out = p_out; register float *in = p_in + pos; @@ -1047,8 +1067,9 @@ static inline void mix_audio(float *p_out, float *p_in, } static bool scene_audio_render(void *data, uint64_t *ts_out, - struct obs_source_audio_mix *audio_output, uint32_t mixers, - size_t channels, size_t sample_rate) + struct obs_source_audio_mix *audio_output, + uint32_t mixers, size_t channels, + size_t sample_rate) { uint64_t timestamp = 0; float *buf = NULL; @@ -1091,7 +1112,7 @@ static bool scene_audio_render(void *data, uint64_t *ts_out, bool apply_buf; apply_buf = apply_scene_item_volume(item, &buf, timestamp, - sample_rate); + sample_rate); if (obs_source_audio_pending(item->source)) { item = item->next; @@ -1105,7 +1126,7 @@ static bool scene_audio_render(void *data, uint64_t *ts_out, } pos = (size_t)ns_to_audio_frames(sample_rate, - source_ts - timestamp); + source_ts - timestamp); count = AUDIO_OUTPUT_FRAMES - pos; if (!apply_buf && !item->visible) { @@ -1124,7 +1145,7 @@ static bool scene_audio_render(void *data, uint64_t *ts_out, if (apply_buf) mix_audio_with_buf(out, in, buf, pos, - count); + count); else mix_audio(out, in, pos, count); } @@ -1140,59 +1161,51 @@ static bool scene_audio_render(void *data, uint64_t *ts_out, return true; } -const struct obs_source_info scene_info = -{ - .id = "scene", - .type = OBS_SOURCE_TYPE_SCENE, - .output_flags = OBS_SOURCE_VIDEO | - OBS_SOURCE_CUSTOM_DRAW | - OBS_SOURCE_COMPOSITE, - .get_name = scene_getname, - .create = scene_create, - .destroy = scene_destroy, - .video_tick = scene_video_tick, - .video_render = scene_video_render, - .audio_render = scene_audio_render, - .get_width = scene_getwidth, - .get_height = scene_getheight, - .load = scene_load, - .save = scene_save, +const struct obs_source_info scene_info = { + .id = "scene", + .type = OBS_SOURCE_TYPE_SCENE, + .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW | + OBS_SOURCE_COMPOSITE, + .get_name = scene_getname, + .create = scene_create, + .destroy = scene_destroy, + .video_tick = scene_video_tick, + .video_render = scene_video_render, + .audio_render = scene_audio_render, + .get_width = scene_getwidth, + .get_height = scene_getheight, + .load = scene_load, + .save = scene_save, .enum_active_sources = scene_enum_active_sources, - .enum_all_sources = scene_enum_all_sources -}; + .enum_all_sources = scene_enum_all_sources}; -const struct obs_source_info group_info = -{ - .id = "group", - .type = OBS_SOURCE_TYPE_SCENE, - .output_flags = OBS_SOURCE_VIDEO | - OBS_SOURCE_CUSTOM_DRAW | - OBS_SOURCE_COMPOSITE, - .get_name = group_getname, - .create = scene_create, - .destroy = scene_destroy, - .video_tick = scene_video_tick, - .video_render = scene_video_render, - .audio_render = scene_audio_render, - .get_width = scene_getwidth, - .get_height = scene_getheight, - .load = scene_load, - .save = scene_save, +const struct obs_source_info group_info = { + .id = "group", + .type = OBS_SOURCE_TYPE_SCENE, + .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW | + OBS_SOURCE_COMPOSITE, + .get_name = group_getname, + .create = scene_create, + .destroy = scene_destroy, + .video_tick = scene_video_tick, + .video_render = scene_video_render, + .audio_render = scene_audio_render, + .get_width = scene_getwidth, + .get_height = scene_getheight, + .load = scene_load, + .save = scene_save, .enum_active_sources = scene_enum_active_sources, - .enum_all_sources = scene_enum_all_sources -}; + .enum_all_sources = scene_enum_all_sources}; static inline obs_scene_t *create_id(const char *id, const char *name) { - struct obs_source *source = obs_source_create(id, name, NULL, - NULL); + struct obs_source *source = obs_source_create(id, name, NULL, NULL); return source->context.data; } static inline obs_scene_t *create_private_id(const char *id, const char *name) { - struct obs_source *source = obs_source_create_private(id, name, - NULL); + struct obs_source *source = obs_source_create_private(id, name, NULL); return source->context.data; } @@ -1216,9 +1229,9 @@ static obs_source_t *get_child_at_idx(obs_scene_t *scene, size_t idx) } static inline obs_source_t *dup_child(struct darray *array, size_t idx, - obs_scene_t *new_scene, bool private) + obs_scene_t *new_scene, bool private) { - DARRAY(struct obs_scene_item*) old_items; + DARRAY(struct obs_scene_item *) old_items; obs_source_t *source; old_items.da = *array; @@ -1247,8 +1260,10 @@ static inline obs_source_t *new_ref(obs_source_t *source) } static inline void duplicate_item_data(struct obs_scene_item *dst, - struct obs_scene_item *src, bool defer_texture_update, - bool duplicate_hotkeys, bool duplicate_private_data) + struct obs_scene_item *src, + bool defer_texture_update, + bool duplicate_hotkeys, + bool duplicate_private_data) { struct obs_scene *dst_scene = dst->parent; @@ -1289,8 +1304,8 @@ static inline void duplicate_item_data(struct obs_scene_item *dst, } else { if (!dst->item_render && item_texture_enabled(dst)) { obs_enter_graphics(); - dst->item_render = gs_texrender_create( - GS_RGBA, GS_ZS_NONE); + dst->item_render = + gs_texrender_create(GS_RGBA, GS_ZS_NONE); obs_leave_graphics(); } } @@ -1301,11 +1316,11 @@ static inline void duplicate_item_data(struct obs_scene_item *dst, } obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name, - enum obs_scene_duplicate_type type) + enum obs_scene_duplicate_type type) { - bool make_unique = ((int)type & (1<<0)) != 0; - bool make_private = ((int)type & (1<<1)) != 0; - DARRAY(struct obs_scene_item*) items; + bool make_unique = ((int)type & (1 << 0)) != 0; + bool make_private = ((int)type & (1 << 1)) != 0; + DARRAY(struct obs_scene_item *) items; struct obs_scene *new_scene; struct obs_scene_item *item; struct obs_source *source; @@ -1331,13 +1346,13 @@ obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name, /* --------------------------------- */ new_scene = make_private - ? create_private_id(scene->source->info.id, name) - : create_id(scene->source->info.id, name); + ? create_private_id(scene->source->info.id, name) + : create_id(scene->source->info.id, name); obs_source_copy_filters(new_scene->source, scene->source); obs_data_apply(new_scene->source->private_settings, - scene->source->private_settings); + scene->source->private_settings); /* never duplicate sub-items for groups */ if (scene->is_group) @@ -1345,9 +1360,9 @@ obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name, for (size_t i = 0; i < items.num; i++) { item = items.array[i]; - source = make_unique ? - dup_child(&items.da, i, new_scene, make_private) : - new_ref(item->source); + source = make_unique ? dup_child(&items.da, i, new_scene, + make_private) + : new_ref(item->source); if (source) { struct obs_scene_item *new_item = @@ -1359,7 +1374,7 @@ obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name, } duplicate_item_data(new_item, item, false, false, - false); + false); obs_source_release(source); } @@ -1453,8 +1468,9 @@ obs_sceneitem_t *obs_scene_find_sceneitem_by_id(obs_scene_t *scene, int64_t id) } void obs_scene_enum_items(obs_scene_t *scene, - bool (*callback)(obs_scene_t*, obs_sceneitem_t*, void*), - void *param) + bool (*callback)(obs_scene_t *, obs_sceneitem_t *, + void *), + void *param) { struct obs_scene_item *item; @@ -1495,7 +1511,7 @@ static obs_sceneitem_t *sceneitem_get_ref(obs_sceneitem_t *si) } static bool hotkey_show_sceneitem(void *data, obs_hotkey_pair_id id, - obs_hotkey_t *hotkey, bool pressed) + obs_hotkey_t *hotkey, bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(hotkey); @@ -1512,7 +1528,7 @@ static bool hotkey_show_sceneitem(void *data, obs_hotkey_pair_id id, } static bool hotkey_hide_sceneitem(void *data, obs_hotkey_pair_id id, - obs_hotkey_t *hotkey, bool pressed) + obs_hotkey_t *hotkey, bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(hotkey); @@ -1529,7 +1545,7 @@ static bool hotkey_hide_sceneitem(void *data, obs_hotkey_pair_id id, } static void init_hotkeys(obs_scene_t *scene, obs_sceneitem_t *item, - const char *name) + const char *name) { struct dstr show = {0}; struct dstr hide = {0}; @@ -1546,11 +1562,10 @@ static void init_hotkeys(obs_scene_t *scene, obs_sceneitem_t *item, dstr_copy(&hide_desc, obs->hotkeys.sceneitem_hide); dstr_replace(&hide_desc, "%1", name); - item->toggle_visibility = obs_hotkey_pair_register_source(scene->source, - show.array, show_desc.array, - hide.array, hide_desc.array, - hotkey_show_sceneitem, hotkey_hide_sceneitem, - item, item); + item->toggle_visibility = obs_hotkey_pair_register_source( + scene->source, show.array, show_desc.array, hide.array, + hide_desc.array, hotkey_show_sceneitem, hotkey_hide_sceneitem, + item, item); dstr_free(&show); dstr_free(&hide); @@ -1559,20 +1574,20 @@ static void init_hotkeys(obs_scene_t *scene, obs_sceneitem_t *item, } static void sceneitem_rename_hotkey(const obs_sceneitem_t *scene_item, - const char *new_name) + const char *new_name) { - struct dstr show = { 0 }; - struct dstr hide = { 0 }; - struct dstr show_desc = { 0 }; - struct dstr hide_desc = { 0 }; + struct dstr show = {0}; + struct dstr hide = {0}; + struct dstr show_desc = {0}; + struct dstr hide_desc = {0}; dstr_copy(&show, "libobs.show_scene_item.%1"); dstr_replace(&show, "%1", new_name); dstr_copy(&hide, "libobs.hide_scene_item.%1"); dstr_replace(&hide, "%1", new_name); - obs_hotkey_pair_set_names(scene_item->toggle_visibility, - show.array, hide.array); + obs_hotkey_pair_set_names(scene_item->toggle_visibility, show.array, + hide.array); dstr_copy(&show_desc, obs->hotkeys.sceneitem_show); dstr_replace(&show_desc, "%1", new_name); @@ -1580,7 +1595,7 @@ static void sceneitem_rename_hotkey(const obs_sceneitem_t *scene_item, dstr_replace(&hide_desc, "%1", new_name); obs_hotkey_pair_set_descriptions(scene_item->toggle_visibility, - show_desc.array, hide_desc.array); + show_desc.array, hide_desc.array); dstr_free(&show); dstr_free(&hide); @@ -1603,16 +1618,15 @@ static inline bool source_has_audio(obs_source_t *source) } static obs_sceneitem_t *obs_scene_add_internal(obs_scene_t *scene, - obs_source_t *source, obs_sceneitem_t *insert_after) + obs_source_t *source, + obs_sceneitem_t *insert_after) { struct obs_scene_item *last; struct obs_scene_item *item; pthread_mutex_t mutex; - struct item_action action = { - .visible = true, - .timestamp = os_gettime_ns() - }; + struct item_action action = {.visible = true, + .timestamp = os_gettime_ns()}; if (!scene) return NULL; @@ -1629,17 +1643,17 @@ static obs_sceneitem_t *obs_scene_add_internal(obs_scene_t *scene, if (!obs_source_add_active_child(scene->source, source)) { blog(LOG_WARNING, "Failed to add source to scene due to " - "infinite source recursion"); + "infinite source recursion"); pthread_mutex_destroy(&mutex); return NULL; } item = bzalloc(sizeof(struct obs_scene_item)); - item->source = source; - item->id = ++scene->id_counter; - item->parent = scene; - item->ref = 1; - item->align = OBS_ALIGN_TOP | OBS_ALIGN_LEFT; + item->source = source; + item->id = ++scene->id_counter; + item->parent = scene; + item->ref = 1; + item->align = OBS_ALIGN_TOP | OBS_ALIGN_LEFT; item->actions_mutex = mutex; item->user_visible = true; item->locked = false; @@ -1670,7 +1684,8 @@ static obs_sceneitem_t *obs_scene_add_internal(obs_scene_t *scene, if (insert_after) { obs_sceneitem_t *next = insert_after->next; - if (next) next->prev = item; + if (next) + next->prev = item; item->next = insert_after->next; item->prev = insert_after; insert_after->next = item; @@ -1693,7 +1708,7 @@ static obs_sceneitem_t *obs_scene_add_internal(obs_scene_t *scene, init_hotkeys(scene, item, obs_source_get_name(source)); signal_handler_connect(obs_source_get_signal_handler(source), "rename", - sceneitem_renamed, item); + sceneitem_renamed, item); return item; } @@ -1708,7 +1723,7 @@ obs_sceneitem_t *obs_scene_add(obs_scene_t *scene, obs_source_t *source) calldata_set_ptr(¶ms, "scene", scene); calldata_set_ptr(¶ms, "item", item); signal_handler_signal(scene->source->context.signals, "item_add", - ¶ms); + ¶ms); return item; } @@ -1724,8 +1739,8 @@ static void obs_sceneitem_destroy(obs_sceneitem_t *item) obs_hotkey_pair_unregister(item->toggle_visibility); pthread_mutex_destroy(&item->actions_mutex); signal_handler_disconnect( - obs_source_get_signal_handler(item->source), - "rename", sceneitem_renamed, item); + obs_source_get_signal_handler(item->source), "rename", + sceneitem_renamed, item); if (item->source) obs_source_release(item->source); da_free(item->audio_actions); @@ -1791,7 +1806,7 @@ obs_source_t *obs_sceneitem_get_source(const obs_sceneitem_t *item) } static void signal_parent(obs_scene_t *parent, const char *command, - calldata_t *params) + calldata_t *params) { calldata_set_ptr(params, "scene", parent); signal_handler_signal(parent->source->context.signals, command, params); @@ -1809,7 +1824,7 @@ void obs_sceneitem_select(obs_sceneitem_t *item, bool select) item->selected = select; calldata_init_fixed(¶ms, stack, sizeof(stack)); - calldata_set_ptr(¶ms, "item", item); + calldata_set_ptr(¶ms, "item", item); signal_parent(item->parent, command, ¶ms); } @@ -1819,12 +1834,12 @@ bool obs_sceneitem_selected(const obs_sceneitem_t *item) return item ? item->selected : false; } -#define do_update_transform(item) \ - do { \ - if (!item->parent || item->parent->is_group) \ +#define do_update_transform(item) \ + do { \ + if (!item->parent || item->parent->is_group) \ os_atomic_set_bool(&item->update_transform, true); \ - else \ - update_item_transform(item, false); \ + else \ + update_item_transform(item, false); \ } while (false) void obs_sceneitem_set_pos(obs_sceneitem_t *item, const struct vec2 *pos) @@ -1872,9 +1887,10 @@ static inline void signal_reorder(struct obs_scene_item *item) } void obs_sceneitem_set_order(obs_sceneitem_t *item, - enum obs_order_movement movement) + enum obs_order_movement movement) { - if (!item) return; + if (!item) + return; struct obs_scene_item *next, *prev; struct obs_scene *scene = item->parent; @@ -1914,10 +1930,10 @@ void obs_sceneitem_set_order(obs_sceneitem_t *item, obs_scene_release(scene); } -void obs_sceneitem_set_order_position(obs_sceneitem_t *item, - int position) +void obs_sceneitem_set_order_position(obs_sceneitem_t *item, int position) { - if (!item) return; + if (!item) + return; struct obs_scene *scene = item->parent; struct obs_scene_item *next; @@ -1947,7 +1963,7 @@ void obs_sceneitem_set_order_position(obs_sceneitem_t *item, } void obs_sceneitem_set_bounds_type(obs_sceneitem_t *item, - enum obs_bounds_type type) + enum obs_bounds_type type) { if (item) { item->bounds_type = type; @@ -1956,7 +1972,7 @@ void obs_sceneitem_set_bounds_type(obs_sceneitem_t *item, } void obs_sceneitem_set_bounds_alignment(obs_sceneitem_t *item, - uint32_t alignment) + uint32_t alignment) { if (item) { item->bounds_align = alignment; @@ -2011,50 +2027,50 @@ void obs_sceneitem_get_bounds(const obs_sceneitem_t *item, struct vec2 *bounds) } void obs_sceneitem_get_info(const obs_sceneitem_t *item, - struct obs_transform_info *info) + struct obs_transform_info *info) { if (item && info) { - info->pos = item->pos; - info->rot = item->rot; - info->scale = item->scale; - info->alignment = item->align; - info->bounds_type = item->bounds_type; + info->pos = item->pos; + info->rot = item->rot; + info->scale = item->scale; + info->alignment = item->align; + info->bounds_type = item->bounds_type; info->bounds_alignment = item->bounds_align; - info->bounds = item->bounds; + info->bounds = item->bounds; } } void obs_sceneitem_set_info(obs_sceneitem_t *item, - const struct obs_transform_info *info) + const struct obs_transform_info *info) { if (item && info) { - item->pos = info->pos; - item->rot = info->rot; - item->scale = info->scale; - item->align = info->alignment; - item->bounds_type = info->bounds_type; + item->pos = info->pos; + item->rot = info->rot; + item->scale = info->scale; + item->align = info->alignment; + item->bounds_type = info->bounds_type; item->bounds_align = info->bounds_alignment; - item->bounds = info->bounds; + item->bounds = info->bounds; do_update_transform(item); } } void obs_sceneitem_get_draw_transform(const obs_sceneitem_t *item, - struct matrix4 *transform) + struct matrix4 *transform) { if (item) matrix4_copy(transform, &item->draw_transform); } void obs_sceneitem_get_box_transform(const obs_sceneitem_t *item, - struct matrix4 *transform) + struct matrix4 *transform) { if (item) matrix4_copy(transform, &item->box_transform); } void obs_sceneitem_get_box_scale(const obs_sceneitem_t *item, - struct vec2 *scale) + struct vec2 *scale) { if (item) *scale = item->box_scale; @@ -2069,10 +2085,8 @@ bool obs_sceneitem_set_visible(obs_sceneitem_t *item, bool visible) { struct calldata cd; uint8_t stack[256]; - struct item_action action = { - .visible = visible, - .timestamp = os_gettime_ns() - }; + struct item_action action = {.visible = visible, + .timestamp = os_gettime_ns()}; if (!item) return false; @@ -2086,7 +2100,7 @@ bool obs_sceneitem_set_visible(obs_sceneitem_t *item, bool visible) if (visible) { if (os_atomic_inc_long(&item->active_refs) == 1) { if (!obs_source_add_active_child(item->parent->source, - item->source)) { + item->source)) { os_atomic_dec_long(&item->active_refs); return false; } @@ -2118,6 +2132,9 @@ bool obs_sceneitem_locked(const obs_sceneitem_t *item) bool obs_sceneitem_set_locked(obs_sceneitem_t *item, bool lock) { + struct calldata cd; + uint8_t stack[256]; + if (!item) return false; @@ -2129,11 +2146,17 @@ bool obs_sceneitem_set_locked(obs_sceneitem_t *item, bool lock) item->locked = lock; + calldata_init_fixed(&cd, stack, sizeof(stack)); + calldata_set_ptr(&cd, "item", item); + calldata_set_bool(&cd, "locked", lock); + + signal_parent(item->parent, "item_locked", &cd); + return true; } -static bool sceneitems_match(obs_scene_t *scene, obs_sceneitem_t * const *items, - size_t size, bool *order_matches) +static bool sceneitems_match(obs_scene_t *scene, obs_sceneitem_t *const *items, + size_t size, bool *order_matches) { obs_sceneitem_t *item = scene->first_item; @@ -2162,7 +2185,8 @@ static bool sceneitems_match(obs_scene_t *scene, obs_sceneitem_t * const *items, } bool obs_scene_reorder_items(obs_scene_t *scene, - obs_sceneitem_t * const *item_order, size_t item_order_size) + obs_sceneitem_t *const *item_order, + size_t item_order_size) { if (!scene || !item_order_size) return false; @@ -2172,7 +2196,8 @@ bool obs_scene_reorder_items(obs_scene_t *scene, bool order_matches = true; if (!sceneitems_match(scene, item_order, item_order_size, - &order_matches) || order_matches) { + &order_matches) || + order_matches) { full_unlock(scene); obs_scene_release(scene); return false; @@ -2199,7 +2224,7 @@ bool obs_scene_reorder_items(obs_scene_t *scene, } void obs_scene_atomic_update(obs_scene_t *scene, - obs_scene_atomic_update_func func, void *data) + obs_scene_atomic_update_func func, void *data) { if (!scene) return; @@ -2212,16 +2237,14 @@ void obs_scene_atomic_update(obs_scene_t *scene, } static inline bool crop_equal(const struct obs_sceneitem_crop *crop1, - const struct obs_sceneitem_crop *crop2) + const struct obs_sceneitem_crop *crop2) { - return crop1->left == crop2->left && - crop1->right == crop2->right && - crop1->top == crop2->top && - crop1->bottom == crop2->bottom; + return crop1->left == crop2->left && crop1->right == crop2->right && + crop1->top == crop2->top && crop1->bottom == crop2->bottom; } void obs_sceneitem_set_crop(obs_sceneitem_t *item, - const struct obs_sceneitem_crop *crop) + const struct obs_sceneitem_crop *crop) { if (!obs_ptr_valid(item, "obs_sceneitem_set_crop")) return; @@ -2232,16 +2255,20 @@ void obs_sceneitem_set_crop(obs_sceneitem_t *item, memcpy(&item->crop, crop, sizeof(*crop)); - if (item->crop.left < 0) item->crop.left = 0; - if (item->crop.right < 0) item->crop.right = 0; - if (item->crop.top < 0) item->crop.top = 0; - if (item->crop.bottom < 0) item->crop.bottom = 0; + if (item->crop.left < 0) + item->crop.left = 0; + if (item->crop.right < 0) + item->crop.right = 0; + if (item->crop.top < 0) + item->crop.top = 0; + if (item->crop.bottom < 0) + item->crop.bottom = 0; os_atomic_set_bool(&item->update_transform, true); } void obs_sceneitem_get_crop(const obs_sceneitem_t *item, - struct obs_sceneitem_crop *crop) + struct obs_sceneitem_crop *crop) { if (!obs_ptr_valid(item, "obs_sceneitem_get_crop")) return; @@ -2252,7 +2279,7 @@ void obs_sceneitem_get_crop(const obs_sceneitem_t *item, } void obs_sceneitem_set_scale_filter(obs_sceneitem_t *item, - enum obs_scale_type filter) + enum obs_scale_type filter) { if (!obs_ptr_valid(item, "obs_sceneitem_set_scale_filter")) return; @@ -2262,11 +2289,11 @@ void obs_sceneitem_set_scale_filter(obs_sceneitem_t *item, os_atomic_set_bool(&item->update_transform, true); } -enum obs_scale_type obs_sceneitem_get_scale_filter( - obs_sceneitem_t *item) +enum obs_scale_type obs_sceneitem_get_scale_filter(obs_sceneitem_t *item) { - return obs_ptr_valid(item, "obs_sceneitem_get_scale_filter") ? - item->scale_filter : OBS_SCALE_DISABLE; + return obs_ptr_valid(item, "obs_sceneitem_get_scale_filter") + ? item->scale_filter + : OBS_SCALE_DISABLE; } void obs_sceneitem_defer_update_begin(obs_sceneitem_t *item) @@ -2329,10 +2356,8 @@ static inline void transform_val(struct vec2 *v2, struct matrix4 *transform) v2->y = v.y; } -static void get_ungrouped_transform(obs_sceneitem_t *group, - struct vec2 *pos, - struct vec2 *scale, - float *rot) +static void get_ungrouped_transform(obs_sceneitem_t *group, struct vec2 *pos, + struct vec2 *scale, float *rot) { struct matrix4 transform; struct matrix4 mat; @@ -2357,7 +2382,7 @@ static void get_ungrouped_transform(obs_sceneitem_t *group, } static void remove_group_transform(obs_sceneitem_t *group, - obs_sceneitem_t *item) + obs_sceneitem_t *item) { obs_scene_t *parent = item->parent; if (!parent || !group) @@ -2387,17 +2412,17 @@ static void apply_group_transform(obs_sceneitem_t *item, obs_sceneitem_t *group) vec4_set(&mat.t, 0.0f, 0.0f, 0.0f, 1.0f); matrix4_mul(&mat, &mat, &transform); - item->scale.x = vec4_len(&mat.x) * (item->scale.x > 0.0f ? 1.0f : -1.0f); - item->scale.y = vec4_len(&mat.y) * (item->scale.y > 0.0f ? 1.0f : -1.0f); + item->scale.x = + vec4_len(&mat.x) * (item->scale.x > 0.0f ? 1.0f : -1.0f); + item->scale.y = + vec4_len(&mat.y) * (item->scale.y > 0.0f ? 1.0f : -1.0f); item->rot -= group->rot; update_item_transform(item, false); } -static bool resize_scene_base(obs_scene_t *scene, - struct vec2 *minv, - struct vec2 *maxv, - struct vec2 *scale) +static bool resize_scene_base(obs_scene_t *scene, struct vec2 *minv, + struct vec2 *maxv, struct vec2 *scale) { vec2_set(minv, M_INFINITE, M_INFINITE); vec2_set(maxv, -M_INFINITE, -M_INFINITE); @@ -2410,16 +2435,20 @@ static bool resize_scene_base(obs_scene_t *scene, } while (item) { -#define get_min_max(x_val, y_val) \ - do { \ - struct vec3 v; \ - vec3_set(&v, x_val, y_val, 0.0f); \ - vec3_transform(&v, &v, &item->box_transform); \ - if (v.x < minv->x) minv->x = v.x; \ - if (v.y < minv->y) minv->y = v.y; \ - if (v.x > maxv->x) maxv->x = v.x; \ - if (v.y > maxv->y) maxv->y = v.y; \ - } while (false) +#define get_min_max(x_val, y_val) \ + do { \ + struct vec3 v; \ + vec3_set(&v, x_val, y_val, 0.0f); \ + vec3_transform(&v, &v, &item->box_transform); \ + if (v.x < minv->x) \ + minv->x = v.x; \ + if (v.y < minv->y) \ + minv->y = v.y; \ + if (v.x > maxv->x) \ + maxv->x = v.x; \ + if (v.y > maxv->y) \ + maxv->y = v.y; \ + } while (false) get_min_max(0.0f, 0.0f); get_min_max(1.0f, 0.0f); @@ -2496,8 +2525,8 @@ obs_sceneitem_t *obs_scene_add_group(obs_scene_t *scene, const char *name) return obs_scene_insert_group(scene, name, NULL, 0); } -obs_sceneitem_t *obs_scene_insert_group(obs_scene_t *scene, - const char *name, obs_sceneitem_t **items, size_t count) +obs_sceneitem_t *obs_scene_insert_group(obs_scene_t *scene, const char *name, + obs_sceneitem_t **items, size_t count) { if (!scene) return NULL; @@ -2512,8 +2541,8 @@ obs_sceneitem_t *obs_scene_insert_group(obs_scene_t *scene, obs_scene_t *sub_scene = create_id("group", name); obs_sceneitem_t *last_item = items ? items[count - 1] : NULL; - obs_sceneitem_t *item = obs_scene_add_internal( - scene, sub_scene->source, last_item); + obs_sceneitem_t *item = + obs_scene_add_internal(scene, sub_scene->source, last_item); obs_scene_release(sub_scene); @@ -2678,7 +2707,7 @@ void obs_sceneitem_group_add_item(obs_sceneitem_t *group, obs_sceneitem_t *item) } void obs_sceneitem_group_remove_item(obs_sceneitem_t *group, - obs_sceneitem_t *item) + obs_sceneitem_t *item) { if (!item || !group || !group->is_group) return; @@ -2713,9 +2742,10 @@ void obs_sceneitem_group_remove_item(obs_sceneitem_t *group, full_unlock(scene); } -static void build_current_order_info(obs_scene_t *scene, - struct obs_sceneitem_order_info **items_out, - size_t *size_out) +static void +build_current_order_info(obs_scene_t *scene, + struct obs_sceneitem_order_info **items_out, + size_t *size_out) { DARRAY(struct obs_sceneitem_order_info) items; da_init(items); @@ -2748,7 +2778,8 @@ static void build_current_order_info(obs_scene_t *scene, } static bool sceneitems_match2(obs_scene_t *scene, - struct obs_sceneitem_order_info *items, size_t size) + struct obs_sceneitem_order_info *items, + size_t size) { struct obs_sceneitem_order_info *cur_items; size_t cur_size; @@ -2773,8 +2804,8 @@ static bool sceneitems_match2(obs_scene_t *scene, return true; } -static obs_sceneitem_t *get_sceneitem_parent_group(obs_scene_t *scene, - obs_sceneitem_t *group_subitem) +static obs_sceneitem_t * +get_sceneitem_parent_group(obs_scene_t *scene, obs_sceneitem_t *group_subitem) { if (group_subitem->is_group) return NULL; @@ -2791,8 +2822,8 @@ static obs_sceneitem_t *get_sceneitem_parent_group(obs_scene_t *scene, } bool obs_scene_reorder_items2(obs_scene_t *scene, - struct obs_sceneitem_order_info *item_order, - size_t item_order_size) + struct obs_sceneitem_order_info *item_order, + size_t item_order_size) { if (!scene || !item_order_size || !item_order) return false; @@ -2853,7 +2884,7 @@ bool obs_scene_reorder_items2(obs_scene_t *scene, sub_prev->next = sub_item; apply_group_transform(sub_info->item, - sub_info->group); + sub_info->group); sub_prev = sub_item; } @@ -2881,14 +2912,14 @@ bool obs_scene_reorder_items2(obs_scene_t *scene, } obs_sceneitem_t *obs_sceneitem_get_group(obs_scene_t *scene, - obs_sceneitem_t *group_subitem) + obs_sceneitem_t *group_subitem) { if (!scene || !group_subitem || group_subitem->is_group) return NULL; full_lock(scene); - obs_sceneitem_t *group = get_sceneitem_parent_group(scene, - group_subitem); + obs_sceneitem_t *group = + get_sceneitem_parent_group(scene, group_subitem); full_unlock(scene); return group; @@ -2905,8 +2936,9 @@ bool obs_scene_is_group(const obs_scene_t *scene) } void obs_sceneitem_group_enum_items(obs_sceneitem_t *group, - bool (*callback)(obs_scene_t*, obs_sceneitem_t*, void*), - void *param) + bool (*callback)(obs_scene_t *, + obs_sceneitem_t *, void *), + void *param) { if (!group || !group->is_group) return; diff --git a/libobs/obs-scene.h b/libobs/obs-scene.h index 6ac57dd..a9ddf74 100644 --- a/libobs/obs-scene.h +++ b/libobs/obs-scene.h @@ -29,54 +29,54 @@ struct item_action { }; struct obs_scene_item { - volatile long ref; - volatile bool removed; + volatile long ref; + volatile bool removed; - bool is_group; - bool update_transform; - bool update_group_resize; + bool is_group; + bool update_transform; + bool update_group_resize; - int64_t id; + int64_t id; - struct obs_scene *parent; - struct obs_source *source; - volatile long active_refs; - volatile long defer_update; - volatile long defer_group_resize; - bool user_visible; - bool visible; - bool selected; - bool locked; + struct obs_scene *parent; + struct obs_source *source; + volatile long active_refs; + volatile long defer_update; + volatile long defer_group_resize; + bool user_visible; + bool visible; + bool selected; + bool locked; - gs_texrender_t *item_render; + gs_texrender_t *item_render; struct obs_sceneitem_crop crop; - struct vec2 pos; - struct vec2 scale; - float rot; - uint32_t align; + struct vec2 pos; + struct vec2 scale; + float rot; + uint32_t align; /* last width/height of the source, this is used to check whether * the transform needs updating */ - uint32_t last_width; - uint32_t last_height; + uint32_t last_width; + uint32_t last_height; - struct vec2 output_scale; - enum obs_scale_type scale_filter; + struct vec2 output_scale; + enum obs_scale_type scale_filter; - struct matrix4 box_transform; - struct vec2 box_scale; - struct matrix4 draw_transform; + struct matrix4 box_transform; + struct vec2 box_scale; + struct matrix4 draw_transform; - enum obs_bounds_type bounds_type; - uint32_t bounds_align; - struct vec2 bounds; + enum obs_bounds_type bounds_type; + uint32_t bounds_align; + struct vec2 bounds; - obs_hotkey_pair_id toggle_visibility; + obs_hotkey_pair_id toggle_visibility; - obs_data_t *private_settings; + obs_data_t *private_settings; - pthread_mutex_t actions_mutex; + pthread_mutex_t actions_mutex; DARRAY(struct item_action) audio_actions; /* would do **prev_next, but not really great for reordering */ @@ -85,16 +85,16 @@ struct obs_scene_item { }; struct obs_scene { - struct obs_source *source; + struct obs_source *source; - bool is_group; - bool custom_size; - uint32_t cx; - uint32_t cy; + bool is_group; + bool custom_size; + uint32_t cx; + uint32_t cy; - int64_t id_counter; + int64_t id_counter; - pthread_mutex_t video_mutex; - pthread_mutex_t audio_mutex; + pthread_mutex_t video_mutex; + pthread_mutex_t audio_mutex; struct obs_scene_item *first_item; }; diff --git a/libobs/obs-service.c b/libobs/obs-service.c index db73ef9..4668a14 100644 --- a/libobs/obs-service.c +++ b/libobs/obs-service.c @@ -22,7 +22,7 @@ const struct obs_service_info *find_service(const char *id) size_t i; for (i = 0; i < obs->service_types.num; i++) if (strcmp(obs->service_types.array[i].id, id) == 0) - return obs->service_types.array+i; + return obs->service_types.array + i; return NULL; } @@ -34,8 +34,10 @@ const char *obs_service_get_display_name(const char *id) } static obs_service_t *obs_service_create_internal(const char *id, - const char *name, obs_data_t *settings, obs_data_t *hotkey_data, - bool private) + const char *name, + obs_data_t *settings, + obs_data_t *hotkey_data, + bool private) { const struct obs_service_info *info = find_service(id); struct obs_service *service; @@ -48,37 +50,36 @@ static obs_service_t *obs_service_create_internal(const char *id, service = bzalloc(sizeof(struct obs_service)); if (!obs_context_data_init(&service->context, OBS_OBJ_TYPE_SERVICE, - settings, name, hotkey_data, private)) { + settings, name, hotkey_data, private)) { bfree(service); return NULL; } service->info = *info; - service->context.data = service->info.create( - service->context.settings, service); + service->context.data = + service->info.create(service->context.settings, service); if (!service->context.data) blog(LOG_ERROR, "Failed to create service '%s'!", name); service->control = bzalloc(sizeof(obs_weak_service_t)); service->control->service = service; - obs_context_data_insert(&service->context, - &obs->data.services_mutex, - &obs->data.first_service); + obs_context_data_insert(&service->context, &obs->data.services_mutex, + &obs->data.first_service); blog(LOG_DEBUG, "service '%s' (%s) created", name, id); return service; } -obs_service_t *obs_service_create(const char *id, - const char *name, obs_data_t *settings, obs_data_t *hotkey_data) +obs_service_t *obs_service_create(const char *id, const char *name, + obs_data_t *settings, obs_data_t *hotkey_data) { return obs_service_create_internal(id, name, settings, hotkey_data, - false); + false); } -obs_service_t *obs_service_create_private(const char *id, - const char *name, obs_data_t *settings) +obs_service_t *obs_service_create_private(const char *id, const char *name, + obs_data_t *settings) { return obs_service_create_internal(id, name, settings, NULL, true); } @@ -95,7 +96,7 @@ static void actually_destroy_service(struct obs_service *service) obs_context_data_free(&service->context); if (service->owns_info_id) - bfree((void*)service->info.id); + bfree((void *)service->info.id); bfree(service); } @@ -115,8 +116,9 @@ void obs_service_destroy(obs_service_t *service) const char *obs_service_get_name(const obs_service_t *service) { - return obs_service_valid(service, "obs_service_get_name") ? - service->context.name : NULL; + return obs_service_valid(service, "obs_service_get_name") + ? service->context.name + : NULL; } static inline obs_data_t *get_defaults(const struct obs_service_info *info) @@ -137,7 +139,7 @@ obs_properties_t *obs_get_service_properties(const char *id) { const struct obs_service_info *info = find_service(id); if (info && info->get_properties) { - obs_data_t *defaults = get_defaults(info); + obs_data_t *defaults = get_defaults(info); obs_properties_t *properties; properties = info->get_properties(NULL); @@ -165,8 +167,9 @@ obs_properties_t *obs_service_properties(const obs_service_t *service) const char *obs_service_get_type(const obs_service_t *service) { - return obs_service_valid(service, "obs_service_get_type") ? - service->info.id : NULL; + return obs_service_valid(service, "obs_service_get_type") + ? service->info.id + : NULL; } void obs_service_update(obs_service_t *service, obs_data_t *settings) @@ -178,7 +181,7 @@ void obs_service_update(obs_service_t *service, obs_data_t *settings) if (service->info.update) service->info.update(service->context.data, - service->context.settings); + service->context.settings); } obs_data_t *obs_service_get_settings(const obs_service_t *service) @@ -192,14 +195,16 @@ obs_data_t *obs_service_get_settings(const obs_service_t *service) signal_handler_t *obs_service_get_signal_handler(const obs_service_t *service) { - return obs_service_valid(service, "obs_service_get_signal_handler") ? - service->context.signals : NULL; + return obs_service_valid(service, "obs_service_get_signal_handler") + ? service->context.signals + : NULL; } proc_handler_t *obs_service_get_proc_handler(const obs_service_t *service) { - return obs_service_valid(service, "obs_service_get_proc_handler") ? - service->context.procs : NULL; + return obs_service_valid(service, "obs_service_get_proc_handler") + ? service->context.procs + : NULL; } const char *obs_service_get_url(const obs_service_t *service) @@ -207,7 +212,8 @@ const char *obs_service_get_url(const obs_service_t *service) if (!obs_service_valid(service, "obs_service_get_url")) return NULL; - if (!service->info.get_url) return NULL; + if (!service->info.get_url) + return NULL; return service->info.get_url(service->context.data); } @@ -216,7 +222,8 @@ const char *obs_service_get_key(const obs_service_t *service) if (!obs_service_valid(service, "obs_service_get_key")) return NULL; - if (!service->info.get_key) return NULL; + if (!service->info.get_key) + return NULL; return service->info.get_key(service->context.data); } @@ -225,7 +232,8 @@ const char *obs_service_get_username(const obs_service_t *service) if (!obs_service_valid(service, "obs_service_get_username")) return NULL; - if (!service->info.get_username) return NULL; + if (!service->info.get_username) + return NULL; return service->info.get_username(service->context.data); } @@ -234,7 +242,8 @@ const char *obs_service_get_password(const obs_service_t *service) if (!obs_service_valid(service, "obs_service_get_password")) return NULL; - if (!service->info.get_password) return NULL; + if (!service->info.get_password) + return NULL; return service->info.get_password(service->context.data); } @@ -243,9 +252,10 @@ void obs_service_activate(struct obs_service *service) if (!obs_service_valid(service, "obs_service_activate")) return; if (!service->output) { - blog(LOG_WARNING, "obs_service_deactivate: service '%s' " - "is not assigned to an output", - obs_service_get_name(service)); + blog(LOG_WARNING, + "obs_service_deactivate: service '%s' " + "is not assigned to an output", + obs_service_get_name(service)); return; } if (service->active) @@ -253,7 +263,7 @@ void obs_service_activate(struct obs_service *service) if (service->info.activate) service->info.activate(service->context.data, - service->context.settings); + service->context.settings); service->active = true; } @@ -262,13 +272,15 @@ void obs_service_deactivate(struct obs_service *service, bool remove) if (!obs_service_valid(service, "obs_service_deactivate")) return; if (!service->output) { - blog(LOG_WARNING, "obs_service_deactivate: service '%s' " - "is not assigned to an output", - obs_service_get_name(service)); + blog(LOG_WARNING, + "obs_service_deactivate: service '%s' " + "is not assigned to an output", + obs_service_get_name(service)); return; } - if (!service->active) return; + if (!service->active) + return; if (service->info.deactivate) service->info.deactivate(service->context.data); @@ -281,7 +293,7 @@ void obs_service_deactivate(struct obs_service *service, bool remove) } bool obs_service_initialize(struct obs_service *service, - struct obs_output *output) + struct obs_output *output) { if (!obs_service_valid(service, "obs_service_initialize")) return false; @@ -294,8 +306,8 @@ bool obs_service_initialize(struct obs_service *service, } void obs_service_apply_encoder_settings(obs_service_t *service, - obs_data_t *video_encoder_settings, - obs_data_t *audio_encoder_settings) + obs_data_t *video_encoder_settings, + obs_data_t *audio_encoder_settings) { if (!obs_service_valid(service, "obs_service_apply_encoder_settings")) return; @@ -304,7 +316,8 @@ void obs_service_apply_encoder_settings(obs_service_t *service, if (video_encoder_settings || audio_encoder_settings) service->info.apply_encoder_settings(service->context.data, - video_encoder_settings, audio_encoder_settings); + video_encoder_settings, + audio_encoder_settings); } void obs_service_addref(obs_service_t *service) @@ -377,7 +390,7 @@ obs_service_t *obs_weak_service_get_service(obs_weak_service_t *weak) } bool obs_weak_service_references_service(obs_weak_service_t *weak, - obs_service_t *service) + obs_service_t *service) { return weak && service && weak->service == service; } @@ -385,13 +398,15 @@ bool obs_weak_service_references_service(obs_weak_service_t *weak, void *obs_service_get_type_data(obs_service_t *service) { return obs_service_valid(service, "obs_service_get_type_data") - ? service->info.type_data : NULL; + ? service->info.type_data + : NULL; } const char *obs_service_get_id(const obs_service_t *service) { return obs_service_valid(service, "obs_service_get_id") - ? service->info.id : NULL; + ? service->info.id + : NULL; } const char *obs_service_get_output_type(const obs_service_t *service) diff --git a/libobs/obs-service.h b/libobs/obs-service.h index d5ab8a6..8257e2d 100644 --- a/libobs/obs-service.h +++ b/libobs/obs-service.h @@ -66,8 +66,8 @@ struct obs_service_info { bool (*supports_multitrack)(void *data); void (*apply_encoder_settings)(void *data, - obs_data_t *video_encoder_settings, - obs_data_t *audio_encoder_settings); + obs_data_t *video_encoder_settings, + obs_data_t *audio_encoder_settings); void *type_data; void (*free_type_data)(void *type_data); @@ -78,7 +78,7 @@ struct obs_service_info { }; EXPORT void obs_register_service_s(const struct obs_service_info *info, - size_t size); + size_t size); #define obs_register_service(info) \ obs_register_service_s(info, sizeof(struct obs_service_info)) diff --git a/libobs/obs-source-deinterlace.c b/libobs/obs-source-deinterlace.c index c3065e9..bce0e2a 100644 --- a/libobs/obs-source-deinterlace.c +++ b/libobs/obs-source-deinterlace.c @@ -21,7 +21,7 @@ static bool ready_deinterlace_frames(obs_source_t *source, uint64_t sys_time) { struct obs_source_frame *next_frame = source->async_frames.array[0]; struct obs_source_frame *prev_frame = NULL; - struct obs_source_frame *frame = NULL; + struct obs_source_frame *frame = NULL; uint64_t sys_offset = sys_time - source->last_sys_timestamp; uint64_t frame_time = next_frame->timestamp; uint64_t frame_offset = 0; @@ -34,8 +34,28 @@ static bool ready_deinterlace_frames(obs_source_t *source, uint64_t sys_time) next_frame = source->async_frames.array[0]; } - if (source->async_frames.num == 2) - source->async_frames.array[0]->prev_frame = true; + if (source->async_frames.num == 2) { + bool prev_frame = true; + if (source->async_unbuffered && + source->deinterlace_offset) { + const uint64_t timestamp = + source->async_frames.array[0]->timestamp; + const uint64_t after_timestamp = + source->async_frames.array[1]->timestamp; + const uint64_t duration = + after_timestamp - timestamp; + const uint64_t frame_end = + timestamp + source->deinterlace_offset + + duration; + if (sys_time < frame_end) { + // Don't skip ahead prematurely. + prev_frame = false; + source->deinterlace_frame_ts = + timestamp - duration; + } + } + source->async_frames.array[0]->prev_frame = prev_frame; + } source->deinterlace_offset = 0; source->last_frame_ts = next_frame->timestamp; return true; @@ -97,7 +117,7 @@ static bool ready_deinterlace_frames(obs_source_t *source, uint64_t sys_time) source->deinterlace_offset = 0; } - frame_time = next_frame->timestamp; + frame_time = next_frame->timestamp; frame_offset = frame_time - source->last_frame_ts; } @@ -119,21 +139,39 @@ static inline bool first_frame(obs_source_t *s) static inline uint64_t uint64_diff(uint64_t ts1, uint64_t ts2) { - return (ts1 < ts2) ? (ts2 - ts1) : (ts1 - ts2); + return (ts1 < ts2) ? (ts2 - ts1) : (ts1 - ts2); } +#define TWOX_TOLERANCE 1000000 +#define TS_JUMP_THRESHOLD 70000000ULL + static inline void deinterlace_get_closest_frames(obs_source_t *s, - uint64_t sys_time) + uint64_t sys_time) { const struct video_output_info *info; uint64_t half_interval; + if (s->async_unbuffered && s->deinterlace_offset) { + // Want to keep frame if it has not elapsed. + const uint64_t frame_end = + s->deinterlace_frame_ts + s->deinterlace_offset + + ((uint64_t)s->deinterlace_half_duration * 2) - + TWOX_TOLERANCE; + if (sys_time < frame_end) { + // Process new frames if we think time jumped. + const uint64_t diff = frame_end - sys_time; + if (diff < TS_JUMP_THRESHOLD) { + return; + } + } + } + if (!s->async_frames.num) return; info = video_output_get_info(obs->video.video); half_interval = (uint64_t)info->fps_den * 500000000ULL / - (uint64_t)info->fps_num; + (uint64_t)info->fps_num; if (first_frame(s) || ready_deinterlace_frames(s, sys_time)) { uint64_t offset; @@ -149,13 +187,15 @@ static inline void deinterlace_get_closest_frames(obs_source_t *s, da_erase(s->async_frames, 0); - s->deinterlace_half_duration = (uint32_t) - ((s->cur_async_frame->timestamp - - s->prev_async_frame->timestamp) / 2); + s->deinterlace_half_duration = + (uint32_t)((s->cur_async_frame->timestamp - + s->prev_async_frame->timestamp) / + 2); } else { - s->deinterlace_half_duration = (uint32_t) - ((s->cur_async_frame->timestamp - - s->deinterlace_frame_ts) / 2); + s->deinterlace_half_duration = + (uint32_t)((s->cur_async_frame->timestamp - + s->deinterlace_frame_ts) / + 2); } if (!s->last_frame_ts) @@ -168,8 +208,8 @@ static inline void deinterlace_get_closest_frames(obs_source_t *s, if (!s->deinterlace_offset) { s->deinterlace_offset = offset; } else { - uint64_t offset_diff = uint64_diff( - s->deinterlace_offset, offset); + uint64_t offset_diff = + uint64_diff(s->deinterlace_offset, offset); if (offset_diff > half_interval) s->deinterlace_offset = offset; } @@ -196,24 +236,25 @@ void set_deinterlace_texture_size(obs_source_t *source) source->async_prev_texrender = gs_texrender_create(GS_BGRX, GS_ZS_NONE); - source->async_prev_texture = gs_texture_create( - source->async_convert_width, - source->async_convert_height, - source->async_texture_format, - 1, NULL, GS_DYNAMIC); + for (int c = 0; c < source->async_channel_count; c++) + source->async_prev_textures[c] = gs_texture_create( + source->async_convert_width[c], + source->async_convert_height[c], + source->async_texture_formats[c], 1, NULL, + GS_DYNAMIC); } else { - enum gs_color_format format = convert_video_format( - source->async_format); + enum gs_color_format format = + convert_video_format(source->async_format); - source->async_prev_texture = gs_texture_create( - source->async_width, source->async_height, - format, 1, NULL, GS_DYNAMIC); + source->async_prev_textures[0] = gs_texture_create( + source->async_width, source->async_height, format, 1, + NULL, GS_DYNAMIC); } } static inline struct obs_source_frame *get_prev_frame(obs_source_t *source, - bool *updated) + bool *updated) { struct obs_source_frame *frame = NULL; @@ -247,17 +288,20 @@ void deinterlace_update_async_video(obs_source_t *source) if (frame) { if (set_async_texture_size(source, frame)) { - update_async_texture(source, frame, - source->async_prev_texture, - source->async_prev_texrender); + update_async_textures(source, frame, + source->async_prev_textures, + source->async_prev_texrender); } obs_source_release_frame(source, frame); } else if (updated) { /* swap cur/prev if no previous texture */ - gs_texture_t *prev_tex = source->async_prev_texture; - source->async_prev_texture = source->async_texture; - source->async_texture = prev_tex; + for (size_t c = 0; c < MAX_AV_PLANES; c++) { + gs_texture_t *prev_tex = source->async_prev_textures[c]; + source->async_prev_textures[c] = + source->async_textures[c]; + source->async_textures[c] = prev_tex; + } if (source->async_texrender) { gs_texrender_t *prev = source->async_prev_texrender; @@ -270,58 +314,60 @@ void deinterlace_update_async_video(obs_source_t *source) static inline gs_effect_t *get_effect(enum obs_deinterlace_mode mode) { switch (mode) { - case OBS_DEINTERLACE_MODE_DISABLE: return NULL; + case OBS_DEINTERLACE_MODE_DISABLE: + return NULL; case OBS_DEINTERLACE_MODE_DISCARD: return obs_load_effect(&obs->video.deinterlace_discard_effect, - "deinterlace_discard.effect"); + "deinterlace_discard.effect"); case OBS_DEINTERLACE_MODE_RETRO: - return obs_load_effect(&obs->video.deinterlace_discard_2x_effect, - "deinterlace_discard_2x.effect"); + return obs_load_effect( + &obs->video.deinterlace_discard_2x_effect, + "deinterlace_discard_2x.effect"); case OBS_DEINTERLACE_MODE_BLEND: return obs_load_effect(&obs->video.deinterlace_blend_effect, - "deinterlace_blend.effect"); + "deinterlace_blend.effect"); case OBS_DEINTERLACE_MODE_BLEND_2X: return obs_load_effect(&obs->video.deinterlace_blend_2x_effect, - "deinterlace_blend_2x.effect"); + "deinterlace_blend_2x.effect"); case OBS_DEINTERLACE_MODE_LINEAR: return obs_load_effect(&obs->video.deinterlace_linear_effect, - "deinterlace_linear.effect"); + "deinterlace_linear.effect"); case OBS_DEINTERLACE_MODE_LINEAR_2X: return obs_load_effect(&obs->video.deinterlace_linear_2x_effect, - "deinterlace_linear_2x.effect"); + "deinterlace_linear_2x.effect"); case OBS_DEINTERLACE_MODE_YADIF: return obs_load_effect(&obs->video.deinterlace_yadif_effect, - "deinterlace_yadif.effect"); + "deinterlace_yadif.effect"); case OBS_DEINTERLACE_MODE_YADIF_2X: return obs_load_effect(&obs->video.deinterlace_yadif_2x_effect, - "deinterlace_yadif_2x.effect"); + "deinterlace_yadif_2x.effect"); } return NULL; } -#define TWOX_TOLERANCE 1000000 - void deinterlace_render(obs_source_t *s) { gs_effect_t *effect = s->deinterlace_effect; uint64_t frame2_ts; gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); - gs_eparam_t *prev = gs_effect_get_param_by_name(effect, - "previous_image"); + gs_eparam_t *prev = + gs_effect_get_param_by_name(effect, "previous_image"); gs_eparam_t *field = gs_effect_get_param_by_name(effect, "field_order"); gs_eparam_t *frame2 = gs_effect_get_param_by_name(effect, "frame2"); - gs_eparam_t *dimensions = gs_effect_get_param_by_name(effect, - "dimensions"); + gs_eparam_t *dimensions = + gs_effect_get_param_by_name(effect, "dimensions"); struct vec2 size = {(float)s->async_width, (float)s->async_height}; - gs_texture_t *cur_tex = s->async_texrender ? - gs_texrender_get_texture(s->async_texrender) : - s->async_texture; - gs_texture_t *prev_tex = s->async_prev_texrender ? - gs_texrender_get_texture(s->async_prev_texrender) : - s->async_prev_texture; + gs_texture_t *cur_tex = + s->async_texrender + ? gs_texrender_get_texture(s->async_texrender) + : s->async_textures[0]; + gs_texture_t *prev_tex = + s->async_prev_texrender + ? gs_texrender_get_texture(s->async_prev_texrender) + : s->async_prev_textures[0]; if (!cur_tex || !prev_tex || !s->async_width || !s->async_height) return; @@ -332,23 +378,22 @@ void deinterlace_render(obs_source_t *s) gs_effect_set_vec2(dimensions, &size); frame2_ts = s->deinterlace_frame_ts + s->deinterlace_offset + - s->deinterlace_half_duration - TWOX_TOLERANCE; + s->deinterlace_half_duration - TWOX_TOLERANCE; gs_effect_set_bool(frame2, obs->video.video_time >= frame2_ts); while (gs_effect_loop(effect, "Draw")) gs_draw_sprite(NULL, s->async_flip ? GS_FLIP_V : 0, - s->async_width, s->async_height); + s->async_width, s->async_height); } static void enable_deinterlacing(obs_source_t *source, - enum obs_deinterlace_mode mode) + enum obs_deinterlace_mode mode) { obs_enter_graphics(); if (source->async_format != VIDEO_FORMAT_NONE && - source->async_width != 0 && - source->async_height != 0) + source->async_width != 0 && source->async_height != 0) set_deinterlace_texture_size(source); source->deinterlace_mode = mode; @@ -367,16 +412,20 @@ static void enable_deinterlacing(obs_source_t *source, static void disable_deinterlacing(obs_source_t *source) { obs_enter_graphics(); - gs_texture_destroy(source->async_prev_texture); + gs_texture_destroy(source->async_prev_textures[0]); + gs_texture_destroy(source->async_prev_textures[1]); + gs_texture_destroy(source->async_prev_textures[2]); gs_texrender_destroy(source->async_prev_texrender); source->deinterlace_mode = OBS_DEINTERLACE_MODE_DISABLE; - source->async_prev_texture = NULL; + source->async_prev_textures[0] = NULL; + source->async_prev_textures[1] = NULL; + source->async_prev_textures[2] = NULL; source->async_prev_texrender = NULL; obs_leave_graphics(); } void obs_source_set_deinterlace_mode(obs_source_t *source, - enum obs_deinterlace_mode mode) + enum obs_deinterlace_mode mode) { if (!obs_source_valid(source, "obs_source_set_deinterlace_mode")) return; @@ -395,30 +444,31 @@ void obs_source_set_deinterlace_mode(obs_source_t *source, } } -enum obs_deinterlace_mode obs_source_get_deinterlace_mode( - const obs_source_t *source) +enum obs_deinterlace_mode +obs_source_get_deinterlace_mode(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_set_deinterlace_mode") ? - source->deinterlace_mode : OBS_DEINTERLACE_MODE_DISABLE; + return obs_source_valid(source, "obs_source_set_deinterlace_mode") + ? source->deinterlace_mode + : OBS_DEINTERLACE_MODE_DISABLE; } -void obs_source_set_deinterlace_field_order(obs_source_t *source, - enum obs_deinterlace_field_order field_order) +void obs_source_set_deinterlace_field_order( + obs_source_t *source, enum obs_deinterlace_field_order field_order) { if (!obs_source_valid(source, "obs_source_set_deinterlace_field_order")) return; - source->deinterlace_top_first = - field_order == OBS_DEINTERLACE_FIELD_ORDER_TOP; + source->deinterlace_top_first = field_order == + OBS_DEINTERLACE_FIELD_ORDER_TOP; } -enum obs_deinterlace_field_order obs_source_get_deinterlace_field_order( - const obs_source_t *source) +enum obs_deinterlace_field_order +obs_source_get_deinterlace_field_order(const obs_source_t *source) { if (!obs_source_valid(source, "obs_source_set_deinterlace_field_order")) return OBS_DEINTERLACE_FIELD_ORDER_TOP; return source->deinterlace_top_first - ? OBS_DEINTERLACE_FIELD_ORDER_TOP - : OBS_DEINTERLACE_FIELD_ORDER_BOTTOM; + ? OBS_DEINTERLACE_FIELD_ORDER_TOP + : OBS_DEINTERLACE_FIELD_ORDER_BOTTOM; } diff --git a/libobs/obs-source-transition.c b/libobs/obs-source-transition.c index 60db7a6..3750117 100644 --- a/libobs/obs-source-transition.c +++ b/libobs/obs-source-transition.c @@ -30,7 +30,7 @@ pthread_mutex_unlock(&transition->transition_tex_mutex) static inline bool transition_valid(const obs_source_t *transition, - const char *func) + const char *func) { if (!obs_ptr_valid(transition, func)) return false; @@ -101,14 +101,12 @@ void add_alignment(struct vec2 *v, uint32_t align, int cx, int cy); static inline uint32_t get_cx(obs_source_t *tr) { - return tr->transition_cx ? - tr->transition_cx : tr->transition_actual_cx; + return tr->transition_cx ? tr->transition_cx : tr->transition_actual_cx; } static inline uint32_t get_cy(obs_source_t *tr) { - return tr->transition_cy ? - tr->transition_cy : tr->transition_actual_cy; + return tr->transition_cy ? tr->transition_cy : tr->transition_actual_cy; } static void recalculate_transition_matrix(obs_source_t *tr, size_t idx) @@ -153,9 +151,8 @@ static void recalculate_transition_matrix(obs_source_t *tr, size_t idx) if (scale_type == OBS_TRANSITION_SCALE_ASPECT) { bool use_width = tr_aspect < source_aspect; - scale.x = scale.y = use_width ? - tr_cx / source_cx : - tr_cy / source_cy; + scale.x = scale.y = use_width ? tr_cx / source_cx + : tr_cy / source_cy; } else if (scale_type == OBS_TRANSITION_SCALE_STRETCH) { scale.x = tr_cx / source_cx; @@ -166,9 +163,8 @@ static void recalculate_transition_matrix(obs_source_t *tr, size_t idx) source_cy *= scale.y; vec2_zero(&pos); - add_alignment(&pos, tr->transition_alignment, - (int)(tr_cx - source_cx), - (int)(tr_cy - source_cy)); + add_alignment(&pos, tr->transition_alignment, (int)(tr_cx - source_cx), + (int)(tr_cy - source_cy)); matrix4_identity(&mat); matrix4_scale3f(&mat, &mat, scale.x, scale.y, 1.0f); @@ -194,8 +190,10 @@ static void recalculate_transition_size(obs_source_t *transition) if (child) { uint32_t new_cx = obs_source_get_width(child); uint32_t new_cy = obs_source_get_height(child); - if (new_cx > cx) cx = new_cx; - if (new_cy > cy) cy = new_cy; + if (new_cx > cx) + cx = new_cx; + if (new_cy > cy) + cy = new_cy; } } @@ -217,9 +215,10 @@ void obs_transition_tick(obs_source_t *transition) } } -static void set_source(obs_source_t *transition, - enum obs_transition_target target, obs_source_t *new_child, - bool (*callback)(obs_source_t *t, size_t idx, obs_source_t *c)) +static void +set_source(obs_source_t *transition, enum obs_transition_target target, + obs_source_t *new_child, + bool (*callback)(obs_source_t *t, size_t idx, obs_source_t *c)) { size_t idx = (size_t)target; obs_source_t *old_child; @@ -244,7 +243,7 @@ static void set_source(obs_source_t *transition, if (already_active) { if (new_child) add_success = obs_source_add_active_child(transition, - new_child); + new_child); if (old_child && add_success) obs_source_remove_active_child(transition, old_child); } @@ -270,7 +269,7 @@ static void set_source(obs_source_t *transition, } obs_source_t *obs_transition_get_source(obs_source_t *transition, - enum obs_transition_target target) + enum obs_transition_target target) { size_t idx = (size_t)target; obs_source_t *ret; @@ -313,8 +312,8 @@ static inline bool activate_child(obs_source_t *transition, size_t idx) if (transition->transition_sources[idx] && !transition->transition_source_active[idx]) { - success = obs_source_add_active_child(transition, - transition->transition_sources[idx]); + success = obs_source_add_active_child( + transition, transition->transition_sources[idx]); if (success) transition->transition_source_active[idx] = true; } @@ -325,7 +324,7 @@ static inline bool activate_child(obs_source_t *transition, size_t idx) } static bool activate_transition(obs_source_t *transition, size_t idx, - obs_source_t *child) + obs_source_t *child) { if (!transition->transition_source_active[idx]) { if (!obs_source_add_active_child(transition, child)) @@ -346,8 +345,8 @@ static inline bool transition_active(obs_source_t *transition) } bool obs_transition_start(obs_source_t *transition, - enum obs_transition_mode mode, uint32_t duration_ms, - obs_source_t *dest) + enum obs_transition_mode mode, uint32_t duration_ms, + obs_source_t *dest) { bool active; bool same_as_source; @@ -378,14 +377,14 @@ bool obs_transition_start(obs_source_t *transition, } set_source(transition, OBS_TRANSITION_SOURCE_B, dest, - activate_transition); + activate_transition); if (dest == NULL && same_as_dest && !same_as_source) { transition->transitioning_video = true; transition->transitioning_audio = true; } obs_source_dosignal(transition, "source_transition_start", - "transition_start"); + "transition_start"); recalculate_transition_size(transition); recalculate_transition_matrices(transition); @@ -455,14 +454,14 @@ float obs_transition_get_time(obs_source_t *transition) } static inline gs_texture_t *get_texture(obs_source_t *transition, - enum obs_transition_target target) + enum obs_transition_target target) { size_t idx = (size_t)target; return gs_texrender_get_texture(transition->transition_texrender[idx]); } void obs_transition_set_scale_type(obs_source_t *transition, - enum obs_transition_scale_type type) + enum obs_transition_scale_type type) { if (!transition_valid(transition, "obs_transition_set_scale_type")) return; @@ -470,12 +469,12 @@ void obs_transition_set_scale_type(obs_source_t *transition, transition->transition_scale_type = type; } -enum obs_transition_scale_type obs_transition_get_scale_type( - const obs_source_t *transition) +enum obs_transition_scale_type +obs_transition_get_scale_type(const obs_source_t *transition) { - return transition_valid(transition, "obs_transition_get_scale_type") ? - transition->transition_scale_type : - OBS_TRANSITION_SCALE_MAX_ONLY; + return transition_valid(transition, "obs_transition_get_scale_type") + ? transition->transition_scale_type + : OBS_TRANSITION_SCALE_MAX_ONLY; } void obs_transition_set_alignment(obs_source_t *transition, uint32_t alignment) @@ -488,12 +487,12 @@ void obs_transition_set_alignment(obs_source_t *transition, uint32_t alignment) uint32_t obs_transition_get_alignment(const obs_source_t *transition) { - return transition_valid(transition, "obs_transition_get_alignment") ? - transition->transition_alignment : 0; + return transition_valid(transition, "obs_transition_get_alignment") + ? transition->transition_alignment + : 0; } -void obs_transition_set_size(obs_source_t *transition, - uint32_t cx, uint32_t cy) +void obs_transition_set_size(obs_source_t *transition, uint32_t cx, uint32_t cy) { if (!transition_valid(transition, "obs_transition_set_size")) return; @@ -502,8 +501,8 @@ void obs_transition_set_size(obs_source_t *transition, transition->transition_cy = cy; } -void obs_transition_get_size(const obs_source_t *transition, - uint32_t *cx, uint32_t *cy) +void obs_transition_get_size(const obs_source_t *transition, uint32_t *cx, + uint32_t *cy) { if (!transition_valid(transition, "obs_transition_set_size")) { *cx = 0; @@ -520,17 +519,16 @@ void obs_transition_save(obs_source_t *tr, obs_data_t *data) obs_source_t *child; lock_transition(tr); - child = transition_active(tr) ? - tr->transition_sources[1] : tr->transition_sources[0]; + child = transition_active(tr) ? tr->transition_sources[1] + : tr->transition_sources[0]; obs_data_set_string(data, "transition_source_a", - child ? child->context.name : ""); + child ? child->context.name : ""); obs_data_set_int(data, "transition_alignment", - tr->transition_alignment); - obs_data_set_int(data, "transition_mode", - (int64_t)tr->transition_mode); + tr->transition_alignment); + obs_data_set_int(data, "transition_mode", (int64_t)tr->transition_mode); obs_data_set_int(data, "transition_scale_type", - (int64_t)tr->transition_scale_type); + (int64_t)tr->transition_scale_type); obs_data_set_int(data, "transition_cx", tr->transition_cx); obs_data_set_int(data, "transition_cy", tr->transition_cy); unlock_transition(tr); @@ -550,17 +548,19 @@ void obs_transition_load(obs_source_t *tr, obs_data_t *data) source = obs_get_source_by_name(name); if (source) { if (!obs_source_add_active_child(tr, source)) { - blog(LOG_WARNING, "Cannot set transition '%s' " - "to source '%s' due to " - "infinite recursion", - tr->context.name, name); + blog(LOG_WARNING, + "Cannot set transition '%s' " + "to source '%s' due to " + "infinite recursion", + tr->context.name, name); obs_source_release(source); source = NULL; } } else { - blog(LOG_WARNING, "Failed to find source '%s' for " - "transition '%s'", - name, tr->context.name); + blog(LOG_WARNING, + "Failed to find source '%s' for " + "transition '%s'", + name, tr->context.name); } } @@ -585,7 +585,7 @@ struct transition_state { }; static inline void copy_transition_state(obs_source_t *transition, - struct transition_state *state) + struct transition_state *state) { state->s[0] = transition->transition_sources[0]; state->s[1] = transition->transition_sources[1]; @@ -597,31 +597,32 @@ static inline void copy_transition_state(obs_source_t *transition, } static inline void enum_child(obs_source_t *tr, obs_source_t *child, - obs_source_enum_proc_t enum_callback, void *param) + obs_source_enum_proc_t enum_callback, void *param) { if (!child) return; if (child->context.data && child->info.enum_active_sources) child->info.enum_active_sources(child->context.data, - enum_callback, param); + enum_callback, param); enum_callback(tr, child, param); } void obs_transition_enum_sources(obs_source_t *transition, - obs_source_enum_proc_t cb, void *param) + obs_source_enum_proc_t cb, void *param) { lock_transition(transition); for (size_t i = 0; i < 2; i++) { if (transition->transition_sources[i]) - cb(transition, transition->transition_sources[i], param); + cb(transition, transition->transition_sources[i], + param); } unlock_transition(transition); } -static inline void render_child(obs_source_t *transition, - obs_source_t *child, size_t idx) +static inline void render_child(obs_source_t *transition, obs_source_t *child, + size_t idx) { uint32_t cx = get_cx(transition); uint32_t cy = get_cy(transition); @@ -662,7 +663,7 @@ static inline void handle_stop(obs_source_t *transition) if (transition->info.transition_stop) transition->info.transition_stop(transition->context.data); obs_source_dosignal(transition, "source_transition_stop", - "transition_stop"); + "transition_stop"); } void obs_transition_force_stop(obs_source_t *transition) @@ -671,7 +672,7 @@ void obs_transition_force_stop(obs_source_t *transition) } void obs_transition_video_render(obs_source_t *transition, - obs_transition_video_render_callback_t callback) + obs_transition_video_render_callback_t callback) { struct transition_state state; struct matrix4 matrices[2]; @@ -728,7 +729,7 @@ void obs_transition_video_render(obs_source_t *transition, gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); callback(transition->context.data, tex[0], tex[1], t, - cx, cy); + cx, cy); gs_blend_state_pop(); } @@ -757,13 +758,13 @@ void obs_transition_video_render(obs_source_t *transition, if (video_stopped) obs_source_dosignal(transition, "source_transition_video_stop", - "transition_video_stop"); + "transition_video_stop"); if (stopped) handle_stop(transition); } bool obs_transition_video_render_direct(obs_source_t *transition, - enum obs_transition_target target) + enum obs_transition_target target) { struct transition_state state; struct matrix4 matrices[2]; @@ -809,7 +810,7 @@ bool obs_transition_video_render_direct(obs_source_t *transition, if (video_stopped) obs_source_dosignal(transition, "source_transition_video_stop", - "transition_video_stop"); + "transition_video_stop"); if (stopped) handle_stop(transition); @@ -817,17 +818,18 @@ bool obs_transition_video_render_direct(obs_source_t *transition, } static inline float get_sample_time(obs_source_t *transition, - size_t sample_rate, size_t sample, uint64_t ts) + size_t sample_rate, size_t sample, + uint64_t ts) { - uint64_t sample_ts_offset = (uint64_t)sample * 1000000000ULL / - (uint64_t)sample_rate; + uint64_t sample_ts_offset = + (uint64_t)sample * 1000000000ULL / (uint64_t)sample_rate; uint64_t i_ts = ts + sample_ts_offset; return calc_time(transition, i_ts); } static inline void mix_child(obs_source_t *transition, float *out, float *in, - size_t count, size_t sample_rate, uint64_t ts, - obs_transition_audio_mix_callback_t mix) + size_t count, size_t sample_rate, uint64_t ts, + obs_transition_audio_mix_callback_t mix) { void *context_data = transition->context.data; @@ -838,9 +840,9 @@ static inline void mix_child(obs_source_t *transition, float *out, float *in, } static void process_audio(obs_source_t *transition, obs_source_t *child, - struct obs_source_audio_mix *audio, uint64_t min_ts, - uint32_t mixers, size_t channels, size_t sample_rate, - obs_transition_audio_mix_callback_t mix) + struct obs_source_audio_mix *audio, uint64_t min_ts, + uint32_t mixers, size_t channels, size_t sample_rate, + obs_transition_audio_mix_callback_t mix) { bool valid = child && !child->audio_pending; struct obs_source_audio_mix child_audio; @@ -869,8 +871,8 @@ static void process_audio(obs_source_t *transition, obs_source_t *child, float *in = input->data[ch]; mix_child(transition, out + pos, in, - AUDIO_OUTPUT_FRAMES - pos, - sample_rate, ts, mix); + AUDIO_OUTPUT_FRAMES - pos, sample_rate, ts, + mix); } } } @@ -900,11 +902,12 @@ static inline bool stop_audio(obs_source_t *transition) return false; } -bool obs_transition_audio_render(obs_source_t *transition, - uint64_t *ts_out, struct obs_source_audio_mix *audio, - uint32_t mixers, size_t channels, size_t sample_rate, - obs_transition_audio_mix_callback_t mix_a, - obs_transition_audio_mix_callback_t mix_b) +bool obs_transition_audio_render(obs_source_t *transition, uint64_t *ts_out, + struct obs_source_audio_mix *audio, + uint32_t mixers, size_t channels, + size_t sample_rate, + obs_transition_audio_mix_callback_t mix_a, + obs_transition_audio_mix_callback_t mix_b) { obs_source_t *sources[2]; struct transition_state state = {0}; @@ -935,7 +938,7 @@ bool obs_transition_audio_render(obs_source_t *transition, copy_transition_state(transition, &state); } else if (!transition->transitioning_video && - transition->transitioning_audio) { + transition->transitioning_audio) { stopped = stop_audio(transition); } @@ -945,16 +948,16 @@ bool obs_transition_audio_render(obs_source_t *transition, if (state.transitioning_audio) { if (state.s[0]) process_audio(transition, state.s[0], audio, - min_ts, mixers, channels, - sample_rate, mix_a); + min_ts, mixers, channels, + sample_rate, mix_a); if (state.s[1]) process_audio(transition, state.s[1], audio, - min_ts, mixers, channels, - sample_rate, mix_b); + min_ts, mixers, channels, + sample_rate, mix_b); } else if (state.s[0]) { memcpy(audio->output[0].data[0], - state.s[0]->audio_output_buf[0][0], - TOTAL_AUDIO_SIZE); + state.s[0]->audio_output_buf[0][0], + TOTAL_AUDIO_SIZE); } obs_source_release(state.s[0]); @@ -968,8 +971,8 @@ bool obs_transition_audio_render(obs_source_t *transition, return !!min_ts; } -void obs_transition_enable_fixed(obs_source_t *transition, - bool enable, uint32_t duration) +void obs_transition_enable_fixed(obs_source_t *transition, bool enable, + uint32_t duration) { if (!transition_valid(transition, "obs_transition_enable_fixed")) return; @@ -980,12 +983,13 @@ void obs_transition_enable_fixed(obs_source_t *transition, bool obs_transition_fixed(obs_source_t *transition) { - return transition_valid(transition, "obs_transition_fixed") ? - transition->transition_use_fixed_duration : false; + return transition_valid(transition, "obs_transition_fixed") + ? transition->transition_use_fixed_duration + : false; } -static inline obs_source_t *copy_source_state(obs_source_t *tr_dest, - obs_source_t *tr_source, size_t idx) +static inline obs_source_t * +copy_source_state(obs_source_t *tr_dest, obs_source_t *tr_source, size_t idx) { obs_source_t *old_child = tr_dest->transition_sources[idx]; obs_source_t *new_child = tr_source->transition_sources[idx]; diff --git a/libobs/obs-source.c b/libobs/obs-source.c index 033006a..4146a25 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -72,25 +72,27 @@ static const char *source_signals[] = { "void update_flags(ptr source, int flags)", "void audio_sync(ptr source, int out int offset)", "void audio_mixers(ptr source, in out int mixers)", + "void audio_activate(ptr source)", + "void audio_deactivate(ptr source)", "void filter_add(ptr source, ptr filter)", "void filter_remove(ptr source, ptr filter)", "void reorder_filters(ptr source)", "void transition_start(ptr source)", "void transition_video_stop(ptr source)", "void transition_stop(ptr source)", - NULL + NULL, }; -bool obs_source_init_context(struct obs_source *source, - obs_data_t *settings, const char *name, obs_data_t *hotkey_data, - bool private) +bool obs_source_init_context(struct obs_source *source, obs_data_t *settings, + const char *name, obs_data_t *hotkey_data, + bool private) { if (!obs_context_data_init(&source->context, OBS_OBJ_TYPE_SOURCE, - settings, name, hotkey_data, private)) + settings, name, hotkey_data, private)) return false; return signal_handler_add_array(source->context.signals, - source_signals); + source_signals); } const char *obs_source_get_display_name(const char *id) @@ -101,8 +103,8 @@ const char *obs_source_get_display_name(const char *id) static void allocate_audio_output_buffer(struct obs_source *source) { - size_t size = sizeof(float) * - AUDIO_OUTPUT_FRAMES * MAX_AUDIO_CHANNELS * MAX_AUDIO_MIXES; + size_t size = sizeof(float) * AUDIO_OUTPUT_FRAMES * MAX_AUDIO_CHANNELS * + MAX_AUDIO_MIXES; float *ptr = bzalloc(size); for (size_t mix = 0; mix < MAX_AUDIO_MIXES; mix++) { @@ -115,10 +117,20 @@ static void allocate_audio_output_buffer(struct obs_source *source) } } +static void allocate_audio_mix_buffer(struct obs_source *source) +{ + size_t size = sizeof(float) * AUDIO_OUTPUT_FRAMES * MAX_AUDIO_CHANNELS; + float *ptr = bzalloc(size); + + for (size_t i = 0; i < MAX_AUDIO_CHANNELS; i++) { + source->audio_mix_buf[i] = ptr + AUDIO_OUTPUT_FRAMES * i; + } +} + static inline bool is_async_video_source(const struct obs_source *source) { return (source->info.output_flags & OBS_SOURCE_ASYNC_VIDEO) == - OBS_SOURCE_ASYNC_VIDEO; + OBS_SOURCE_ASYNC_VIDEO; } static inline bool is_audio_source(const struct obs_source *source) @@ -134,7 +146,7 @@ static inline bool is_composite_source(const struct obs_source *source) extern char *find_libobs_data_file(const char *file); /* internal initialization */ -bool obs_source_init(struct obs_source *source) +static bool obs_source_init(struct obs_source *source) { pthread_mutexattr_t attr; @@ -142,6 +154,7 @@ bool obs_source_init(struct obs_source *source) source->volume = 1.0f; source->sync_offset = 0; source->balance = 0.5f; + source->audio_active = true; pthread_mutex_init_value(&source->filter_mutex); pthread_mutex_init_value(&source->async_mutex); pthread_mutex_init_value(&source->audio_mutex); @@ -167,6 +180,8 @@ bool obs_source_init(struct obs_source *source) if (is_audio_source(source) || is_composite_source(source)) allocate_audio_output_buffer(source); + if (source->info.audio_mix) + allocate_audio_mix_buffer(source); if (source->info.type == OBS_SOURCE_TYPE_TRANSITION) { if (!obs_transition_init(source)) @@ -178,12 +193,17 @@ bool obs_source_init(struct obs_source *source) source->control->source = source; source->audio_mixers = 0xFF; + source->private_settings = obs_data_create(); + return true; +} + +static void obs_source_init_finalize(struct obs_source *source) +{ if (is_audio_source(source)) { pthread_mutex_lock(&obs->data.audio_sources_mutex); source->next_audio_source = obs->data.first_audio_source; - source->prev_next_audio_source = - &obs->data.first_audio_source; + source->prev_next_audio_source = &obs->data.first_audio_source; if (obs->data.first_audio_source) obs->data.first_audio_source->prev_next_audio_source = &source->next_audio_source; @@ -192,50 +212,46 @@ bool obs_source_init(struct obs_source *source) pthread_mutex_unlock(&obs->data.audio_sources_mutex); } - source->private_settings = obs_data_create(); - - obs_context_data_insert(&source->context, - &obs->data.sources_mutex, - &obs->data.first_source); - return true; + obs_context_data_insert(&source->context, &obs->data.sources_mutex, + &obs->data.first_source); } -static bool obs_source_hotkey_mute(void *data, - obs_hotkey_pair_id id, obs_hotkey_t *key, bool pressed) +static bool obs_source_hotkey_mute(void *data, obs_hotkey_pair_id id, + obs_hotkey_t *key, bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(key); struct obs_source *source = data; - if (!pressed || obs_source_muted(source)) return false; + if (!pressed || obs_source_muted(source)) + return false; obs_source_set_muted(source, true); return true; } -static bool obs_source_hotkey_unmute(void *data, - obs_hotkey_pair_id id, obs_hotkey_t *key, bool pressed) +static bool obs_source_hotkey_unmute(void *data, obs_hotkey_pair_id id, + obs_hotkey_t *key, bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(key); struct obs_source *source = data; - if (!pressed || !obs_source_muted(source)) return false; + if (!pressed || !obs_source_muted(source)) + return false; obs_source_set_muted(source, false); return true; } -static void obs_source_hotkey_push_to_mute(void *data, - obs_hotkey_id id, obs_hotkey_t *key, bool pressed) +static void obs_source_hotkey_push_to_mute(void *data, obs_hotkey_id id, + obs_hotkey_t *key, bool pressed) { - struct audio_action action = { - .timestamp = os_gettime_ns(), - .type = AUDIO_ACTION_PTM, - .set = pressed - }; + struct audio_action action = {.timestamp = os_gettime_ns(), + .type = AUDIO_ACTION_PTM, + .set = pressed}; UNUSED_PARAMETER(id); UNUSED_PARAMETER(key); @@ -249,14 +265,12 @@ static void obs_source_hotkey_push_to_mute(void *data, source->user_push_to_mute_pressed = pressed; } -static void obs_source_hotkey_push_to_talk(void *data, - obs_hotkey_id id, obs_hotkey_t *key, bool pressed) +static void obs_source_hotkey_push_to_talk(void *data, obs_hotkey_id id, + obs_hotkey_t *key, bool pressed) { - struct audio_action action = { - .timestamp = os_gettime_ns(), - .type = AUDIO_ACTION_PTT, - .set = pressed - }; + struct audio_action action = {.timestamp = os_gettime_ns(), + .type = AUDIO_ACTION_PTT, + .set = pressed}; UNUSED_PARAMETER(id); UNUSED_PARAMETER(key); @@ -274,29 +288,29 @@ static void obs_source_init_audio_hotkeys(struct obs_source *source) { if (!(source->info.output_flags & OBS_SOURCE_AUDIO) || source->info.type != OBS_SOURCE_TYPE_INPUT) { - source->mute_unmute_key = OBS_INVALID_HOTKEY_ID; + source->mute_unmute_key = OBS_INVALID_HOTKEY_ID; source->push_to_talk_key = OBS_INVALID_HOTKEY_ID; return; } - source->mute_unmute_key = obs_hotkey_pair_register_source(source, - "libobs.mute", obs->hotkeys.mute, - "libobs.unmute", obs->hotkeys.unmute, - obs_source_hotkey_mute, obs_source_hotkey_unmute, - source, source); + source->mute_unmute_key = obs_hotkey_pair_register_source( + source, "libobs.mute", obs->hotkeys.mute, "libobs.unmute", + obs->hotkeys.unmute, obs_source_hotkey_mute, + obs_source_hotkey_unmute, source, source); - source->push_to_mute_key = obs_hotkey_register_source(source, - "libobs.push-to-mute", obs->hotkeys.push_to_mute, - obs_source_hotkey_push_to_mute, source); + source->push_to_mute_key = obs_hotkey_register_source( + source, "libobs.push-to-mute", obs->hotkeys.push_to_mute, + obs_source_hotkey_push_to_mute, source); - source->push_to_talk_key = obs_hotkey_register_source(source, - "libobs.push-to-talk", obs->hotkeys.push_to_talk, - obs_source_hotkey_push_to_talk, source); + source->push_to_talk_key = obs_hotkey_register_source( + source, "libobs.push-to-talk", obs->hotkeys.push_to_talk, + obs_source_hotkey_push_to_talk, source); } -static obs_source_t *obs_source_create_internal(const char *id, - const char *name, obs_data_t *settings, - obs_data_t *hotkey_data, bool private) +static obs_source_t * +obs_source_create_internal(const char *id, const char *name, + obs_data_t *settings, obs_data_t *hotkey_data, + bool private, uint32_t last_obs_ver) { struct obs_source *source = bzalloc(sizeof(struct obs_source)); @@ -304,7 +318,7 @@ static obs_source_t *obs_source_create_internal(const char *id, if (!info) { blog(LOG_ERROR, "Source ID '%s' not found", id); - source->info.id = bstrdup(id); + source->info.id = bstrdup(id); source->owns_info_id = true; } else { source->info = *info; @@ -314,23 +328,27 @@ static obs_source_t *obs_source_create_internal(const char *id, * * XXX: Fix design flaws with filters */ if (info->type == OBS_SOURCE_TYPE_FILTER) - private = true; + private + = true; } - source->mute_unmute_key = OBS_INVALID_HOTKEY_PAIR_ID; + source->mute_unmute_key = OBS_INVALID_HOTKEY_PAIR_ID; source->push_to_mute_key = OBS_INVALID_HOTKEY_ID; source->push_to_talk_key = OBS_INVALID_HOTKEY_ID; + source->last_obs_ver = last_obs_ver; if (!obs_source_init_context(source, settings, name, hotkey_data, - private)) + private)) goto fail; if (info) { - if (info->get_defaults2) - info->get_defaults2(info->type_data, - source->context.settings); - else if (info->get_defaults) + if (info->get_defaults) { info->get_defaults(source->context.settings); + } + if (info->get_defaults2) { + info->get_defaults2(info->type_data, + source->context.settings); + } } if (!obs_source_init(source)) @@ -341,14 +359,14 @@ static obs_source_t *obs_source_create_internal(const char *id, /* allow the source to be created even if creation fails so that the * user's data doesn't become lost */ - if (info) - source->context.data = info->create(source->context.settings, - source); - if (!source->context.data) + if (info && info->create) + source->context.data = + info->create(source->context.settings, source); + if ((!info || info->create) && !source->context.data) blog(LOG_ERROR, "Failed to create source '%s'!", name); - blog(LOG_DEBUG, "%ssource '%s' (%s) created", - private ? "private " : "", name, id); + blog(LOG_DEBUG, "%ssource '%s' (%s) created", private ? "private " : "", + name, id); source->flags = source->default_flags; source->enabled = true; @@ -357,6 +375,7 @@ static obs_source_t *obs_source_create_internal(const char *id, obs_source_dosignal(source, "source_create", NULL); } + obs_source_init_finalize(source); return source; fail: @@ -366,16 +385,26 @@ fail: } obs_source_t *obs_source_create(const char *id, const char *name, - obs_data_t *settings, obs_data_t *hotkey_data) + obs_data_t *settings, obs_data_t *hotkey_data) { return obs_source_create_internal(id, name, settings, hotkey_data, - false); + false, LIBOBS_API_VER); } obs_source_t *obs_source_create_private(const char *id, const char *name, - obs_data_t *settings) + obs_data_t *settings) { - return obs_source_create_internal(id, name, settings, NULL, true); + return obs_source_create_internal(id, name, settings, NULL, true, + LIBOBS_API_VER); +} + +obs_source_t *obs_source_create_set_last_ver(const char *id, const char *name, + obs_data_t *settings, + obs_data_t *hotkey_data, + uint32_t last_obs_ver) +{ + return obs_source_create_internal(id, name, settings, hotkey_data, + false, last_obs_ver); } static char *get_new_filter_name(obs_source_t *dst, const char *name) @@ -386,8 +415,8 @@ static char *get_new_filter_name(obs_source_t *dst, const char *name) dstr_copy(&new_name, name); for (;;) { - obs_source_t *existing_filter = obs_source_get_filter_by_name( - dst, new_name.array); + obs_source_t *existing_filter = + obs_source_get_filter_by_name(dst, new_name.array); if (!existing_filter) break; @@ -400,9 +429,9 @@ static char *get_new_filter_name(obs_source_t *dst, const char *name) } static void duplicate_filters(obs_source_t *dst, obs_source_t *src, - bool private) + bool private) { - DARRAY(obs_source_t*) filters; + DARRAY(obs_source_t *) filters; da_init(filters); @@ -414,12 +443,12 @@ static void duplicate_filters(obs_source_t *dst, obs_source_t *src, for (size_t i = filters.num; i > 0; i--) { obs_source_t *src_filter = filters.array[i - 1]; - char *new_name = get_new_filter_name(dst, - src_filter->context.name); + char *new_name = + get_new_filter_name(dst, src_filter->context.name); bool enabled = obs_source_enabled(src_filter); - obs_source_t *dst_filter = obs_source_duplicate(src_filter, - new_name, private); + obs_source_t *dst_filter = + obs_source_duplicate(src_filter, new_name, private); obs_source_set_enabled(dst_filter, enabled); bfree(new_name); @@ -443,8 +472,8 @@ void obs_source_copy_filters(obs_source_t *dst, obs_source_t *src) extern obs_scene_t *obs_group_from_source(const obs_source_t *source); -obs_source_t *obs_source_duplicate(obs_source_t *source, - const char *new_name, bool create_private) +obs_source_t *obs_source_duplicate(obs_source_t *source, const char *new_name, + bool create_private) { obs_source_t *new_source; obs_data_t *settings; @@ -464,9 +493,10 @@ obs_source_t *obs_source_duplicate(obs_source_t *source, if (!scene) return NULL; - obs_scene_t *new_scene = obs_scene_duplicate(scene, new_name, - create_private ? OBS_SCENE_DUP_PRIVATE_COPY : - OBS_SCENE_DUP_COPY); + obs_scene_t *new_scene = obs_scene_duplicate( + scene, new_name, + create_private ? OBS_SCENE_DUP_PRIVATE_COPY + : OBS_SCENE_DUP_COPY); obs_source_t *new_source = obs_scene_get_source(new_scene); return new_source; } @@ -474,9 +504,11 @@ obs_source_t *obs_source_duplicate(obs_source_t *source, settings = obs_data_create(); obs_data_apply(settings, source->context.settings); - new_source = create_private ? - obs_source_create_private(source->info.id, new_name, settings) : - obs_source_create(source->info.id, new_name, settings, NULL); + new_source = create_private + ? obs_source_create_private(source->info.id, + new_name, settings) + : obs_source_create(source->info.id, new_name, + settings, NULL); new_source->audio_mixers = source->audio_mixers; new_source->sync_offset = source->sync_offset; @@ -496,7 +528,8 @@ obs_source_t *obs_source_duplicate(obs_source_t *source, } void obs_source_frame_init(struct obs_source_frame *frame, - enum video_format format, uint32_t width, uint32_t height) + enum video_format format, uint32_t width, + uint32_t height) { struct video_frame vid_frame; @@ -505,11 +538,11 @@ void obs_source_frame_init(struct obs_source_frame *frame, video_frame_init(&vid_frame, format, width, height); frame->format = format; - frame->width = width; + frame->width = width; frame->height = height; for (size_t i = 0; i < MAX_AV_PLANES; i++) { - frame->data[i] = vid_frame.data[i]; + frame->data[i] = vid_frame.data[i]; frame->linesize[i] = vid_frame.linesize[i]; } } @@ -521,7 +554,7 @@ static inline void obs_source_frame_decref(struct obs_source_frame *frame) } static bool obs_source_filter_remove_refless(obs_source_t *source, - obs_source_t *filter); + obs_source_t *filter); void obs_source_destroy(struct obs_source *source) { @@ -551,8 +584,7 @@ void obs_source_destroy(struct obs_source *source) obs_context_data_remove(&source->context); blog(LOG_DEBUG, "%ssource '%s' destroyed", - source->context.private ? "private " : "", - source->context.name); + source->context.private ? "private " : "", source->context.name); obs_source_dosignal(source, "source_destroy", "destroy"); @@ -575,10 +607,10 @@ void obs_source_destroy(struct obs_source *source) gs_texrender_destroy(source->async_texrender); if (source->async_prev_texrender) gs_texrender_destroy(source->async_prev_texrender); - if (source->async_texture) - gs_texture_destroy(source->async_texture); - if (source->async_prev_texture) - gs_texture_destroy(source->async_prev_texture); + for (size_t c = 0; c < MAX_AV_PLANES; c++) { + gs_texture_destroy(source->async_textures[c]); + gs_texture_destroy(source->async_prev_textures[c]); + } if (source->filter_texrender) gs_texrender_destroy(source->filter_texrender); gs_leave_context(); @@ -589,6 +621,7 @@ void obs_source_destroy(struct obs_source *source) circlebuf_free(&source->audio_input_buf[i]); audio_resampler_destroy(source->resampler); bfree(source->audio_output_buf[0][0]); + bfree(source->audio_mix_buf[0]); obs_source_frame_destroy(source->async_preload_frame); @@ -610,7 +643,7 @@ void obs_source_destroy(struct obs_source *source) obs_context_data_free(&source->context); if (source->owns_info_id) - bfree((void*)source->info.id); + bfree((void *)source->info.id); bfree(source); } @@ -627,7 +660,7 @@ void obs_source_release(obs_source_t *source) { if (!obs) { blog(LOG_WARNING, "Tried to release a source when the OBS " - "core is shut down!"); + "core is shut down!"); return; } @@ -688,7 +721,7 @@ obs_source_t *obs_weak_source_get_source(obs_weak_source_t *weak) } bool obs_weak_source_references_source(obs_weak_source_t *weak, - obs_source_t *source) + obs_source_t *source) { return weak && source && weak->source == source; } @@ -706,8 +739,8 @@ void obs_source_remove(obs_source_t *source) bool obs_source_removed(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_removed") ? - source->removed : true; + return obs_source_valid(source, "obs_source_removed") ? source->removed + : true; } static inline obs_data_t *get_defaults(const struct obs_source_info *info) @@ -736,7 +769,7 @@ obs_properties_t *obs_get_source_properties(const char *id) { const struct obs_source_info *info = get_source_info(id); if (info && (info->get_properties || info->get_properties2)) { - obs_data_t *defaults = get_defaults(info); + obs_data_t *defaults = get_defaults(info); obs_properties_t *props; if (info->get_properties2) @@ -760,7 +793,7 @@ bool obs_is_source_configurable(const char *id) bool obs_source_configurable(const obs_source_t *source) { return data_valid(source, "obs_source_configurable") && - (source->info.get_properties || source->info.get_properties2); + (source->info.get_properties || source->info.get_properties2); } obs_properties_t *obs_source_properties(const obs_source_t *source) @@ -771,7 +804,7 @@ obs_properties_t *obs_source_properties(const obs_source_t *source) if (source->info.get_properties2) { obs_properties_t *props; props = source->info.get_properties2(source->context.data, - source->info.type_data); + source->info.type_data); obs_properties_apply_settings(props, source->context.settings); return props; @@ -787,8 +820,9 @@ obs_properties_t *obs_source_properties(const obs_source_t *source) uint32_t obs_source_get_output_flags(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_get_output_flags") ? - source->info.output_flags : 0; + return obs_source_valid(source, "obs_source_get_output_flags") + ? source->info.output_flags + : 0; } uint32_t obs_get_source_output_flags(const char *id) @@ -801,7 +835,7 @@ static void obs_source_deferred_update(obs_source_t *source) { if (source->context.data && source->info.update) source->info.update(source->context.data, - source->context.settings); + source->context.settings); source->defer_update = false; } @@ -818,7 +852,7 @@ void obs_source_update(obs_source_t *source, obs_data_t *settings) source->defer_update = true; } else if (source->context.data && source->info.update) { source->info.update(source->context.data, - source->context.settings); + source->context.settings); } } @@ -831,45 +865,47 @@ void obs_source_update_properties(obs_source_t *source) } void obs_source_send_mouse_click(obs_source_t *source, - const struct obs_mouse_event *event, - int32_t type, bool mouse_up, - uint32_t click_count) + const struct obs_mouse_event *event, + int32_t type, bool mouse_up, + uint32_t click_count) { if (!obs_source_valid(source, "obs_source_send_mouse_click")) return; if (source->info.output_flags & OBS_SOURCE_INTERACTION) { if (source->info.mouse_click) { - source->info.mouse_click(source->context.data, - event, type, mouse_up, click_count); + source->info.mouse_click(source->context.data, event, + type, mouse_up, click_count); } } } void obs_source_send_mouse_move(obs_source_t *source, - const struct obs_mouse_event *event, bool mouse_leave) + const struct obs_mouse_event *event, + bool mouse_leave) { if (!obs_source_valid(source, "obs_source_send_mouse_move")) return; if (source->info.output_flags & OBS_SOURCE_INTERACTION) { if (source->info.mouse_move) { - source->info.mouse_move(source->context.data, - event, mouse_leave); + source->info.mouse_move(source->context.data, event, + mouse_leave); } } } void obs_source_send_mouse_wheel(obs_source_t *source, - const struct obs_mouse_event *event, int x_delta, int y_delta) + const struct obs_mouse_event *event, + int x_delta, int y_delta) { if (!obs_source_valid(source, "obs_source_send_mouse_wheel")) return; if (source->info.output_flags & OBS_SOURCE_INTERACTION) { if (source->info.mouse_wheel) { - source->info.mouse_wheel(source->context.data, - event, x_delta, y_delta); + source->info.mouse_wheel(source->context.data, event, + x_delta, y_delta); } } } @@ -887,7 +923,7 @@ void obs_source_send_focus(obs_source_t *source, bool focus) } void obs_source_send_key_click(obs_source_t *source, - const struct obs_key_event *event, bool key_up) + const struct obs_key_event *event, bool key_up) { if (!obs_source_valid(source, "obs_source_send_key_click")) return; @@ -895,7 +931,7 @@ void obs_source_send_key_click(obs_source_t *source, if (source->info.output_flags & OBS_SOURCE_INTERACTION) { if (source->info.key_click) { source->info.key_click(source->context.data, event, - key_up); + key_up); } } } @@ -929,7 +965,7 @@ static void hide_source(obs_source_t *source) } static void activate_tree(obs_source_t *parent, obs_source_t *child, - void *param) + void *param) { os_atomic_inc_long(&child->activate_refs); @@ -938,7 +974,7 @@ static void activate_tree(obs_source_t *parent, obs_source_t *child, } static void deactivate_tree(obs_source_t *parent, obs_source_t *child, - void *param) + void *param) { os_atomic_dec_long(&child->activate_refs); @@ -990,15 +1026,15 @@ void obs_source_deactivate(obs_source_t *source, enum view_type type) if (os_atomic_load_long(&source->activate_refs) > 0) { os_atomic_dec_long(&source->activate_refs); obs_source_enum_active_tree(source, deactivate_tree, - NULL); + NULL); } } } static inline struct obs_source_frame *get_closest_frame(obs_source_t *source, - uint64_t sys_time); + uint64_t sys_time); bool set_async_texture_size(struct obs_source *source, - const struct obs_source_frame *frame); + const struct obs_source_frame *frame); static void async_tick(obs_source_t *source) { @@ -1010,21 +1046,19 @@ static void async_tick(obs_source_t *source) deinterlace_process_last_frame(source, sys_time); } else { if (source->cur_async_frame) { - remove_async_frame(source, - source->cur_async_frame); + remove_async_frame(source, source->cur_async_frame); source->cur_async_frame = NULL; } - source->cur_async_frame = get_closest_frame(source, - sys_time); + source->cur_async_frame = get_closest_frame(source, sys_time); } source->last_sys_timestamp = sys_time; pthread_mutex_unlock(&source->async_mutex); if (source->cur_async_frame) - source->async_update_texture = set_async_texture_size(source, - source->cur_async_frame); + source->async_update_texture = + set_async_texture_size(source, source->cur_async_frame); } void obs_source_video_tick(obs_source_t *source, float seconds) @@ -1080,31 +1114,31 @@ void obs_source_video_tick(obs_source_t *source, float seconds) /* unless the value is 3+ hours worth of frames, this won't overflow */ static inline uint64_t conv_frames_to_time(const size_t sample_rate, - const size_t frames) + const size_t frames) { if (!sample_rate) return 0; - + return (uint64_t)frames * 1000000000ULL / (uint64_t)sample_rate; } static inline size_t conv_time_to_frames(const size_t sample_rate, - const uint64_t duration) + const uint64_t duration) { return (size_t)(duration * (uint64_t)sample_rate / 1000000000ULL); } /* maximum buffer size */ -#define MAX_BUF_SIZE (1000 * AUDIO_OUTPUT_FRAMES * sizeof(float)) +#define MAX_BUF_SIZE (1000 * AUDIO_OUTPUT_FRAMES * sizeof(float)) /* time threshold in nanoseconds to ensure audio timing is as seamless as * possible */ #define TS_SMOOTHING_THRESHOLD 70000000ULL static inline void reset_audio_timing(obs_source_t *source, uint64_t timestamp, - uint64_t os_time) + uint64_t os_time) { - source->timing_set = true; + source->timing_set = true; source->timing_adjust = os_time - timestamp; } @@ -1113,7 +1147,7 @@ static void reset_audio_data(obs_source_t *source, uint64_t os_time) for (size_t i = 0; i < MAX_AUDIO_CHANNELS; i++) { if (source->audio_input_buf[i].size) circlebuf_pop_front(&source->audio_input_buf[i], NULL, - source->audio_input_buf[i].size); + source->audio_input_buf[i].size); } source->last_audio_input_buf_size = 0; @@ -1121,12 +1155,13 @@ static void reset_audio_data(obs_source_t *source, uint64_t os_time) source->next_audio_sys_ts_min = os_time; } -static void handle_ts_jump(obs_source_t *source, uint64_t expected, - uint64_t ts, uint64_t diff, uint64_t os_time) +static void handle_ts_jump(obs_source_t *source, uint64_t expected, uint64_t ts, + uint64_t diff, uint64_t os_time) { - blog(LOG_DEBUG, "Timestamp for source '%s' jumped by '%"PRIu64"', " - "expected value %"PRIu64", input value %"PRIu64, - source->context.name, diff, expected, ts); + blog(LOG_DEBUG, + "Timestamp for source '%s' jumped by '%" PRIu64 "', " + "expected value %" PRIu64 ", input value %" PRIu64, + source->context.name, diff, expected, ts); pthread_mutex_lock(&source->audio_buf_mutex); reset_audio_timing(source, ts, os_time); @@ -1134,7 +1169,7 @@ static void handle_ts_jump(obs_source_t *source, uint64_t expected, } static void source_signal_audio_data(obs_source_t *source, - const struct audio_data *in, bool muted) + const struct audio_data *in, bool muted) { pthread_mutex_lock(&source->audio_cb_mutex); @@ -1148,7 +1183,7 @@ static void source_signal_audio_data(obs_source_t *source, static inline uint64_t uint64_diff(uint64_t ts1, uint64_t ts2) { - return (ts1 < ts2) ? (ts2 - ts1) : (ts1 - ts2); + return (ts1 < ts2) ? (ts2 - ts1) : (ts1 - ts2); } static inline size_t get_buf_placement(audio_t *audio, uint64_t offset) @@ -1158,7 +1193,7 @@ static inline size_t get_buf_placement(audio_t *audio, uint64_t offset) } static void source_output_audio_place(obs_source_t *source, - const struct audio_data *in) + const struct audio_data *in) { audio_t *audio = obs->audio.audio; size_t buf_placement; @@ -1168,16 +1203,16 @@ static void source_output_audio_place(obs_source_t *source, if (!source->audio_ts || in->timestamp < source->audio_ts) reset_audio_data(source, in->timestamp); - buf_placement = get_buf_placement(audio, - in->timestamp - source->audio_ts) * sizeof(float); + buf_placement = + get_buf_placement(audio, in->timestamp - source->audio_ts) * + sizeof(float); #if DEBUG_AUDIO == 1 - blog(LOG_DEBUG, "frames: %lu, size: %lu, placement: %lu, base_ts: %llu, ts: %llu", - (unsigned long)in->frames, - (unsigned long)source->audio_input_buf[0].size, - (unsigned long)buf_placement, - source->audio_ts, - in->timestamp); + blog(LOG_DEBUG, + "frames: %lu, size: %lu, placement: %lu, base_ts: %llu, ts: %llu", + (unsigned long)in->frames, + (unsigned long)source->audio_input_buf[0].size, + (unsigned long)buf_placement, source->audio_ts, in->timestamp); #endif /* do not allow the circular buffers to become too big */ @@ -1188,15 +1223,15 @@ static void source_output_audio_place(obs_source_t *source, circlebuf_place(&source->audio_input_buf[i], buf_placement, in->data[i], size); circlebuf_pop_back(&source->audio_input_buf[i], NULL, - source->audio_input_buf[i].size - - (buf_placement + size)); + source->audio_input_buf[i].size - + (buf_placement + size)); } source->last_audio_input_buf_size = 0; } static inline void source_output_audio_push_back(obs_source_t *source, - const struct audio_data *in) + const struct audio_data *in) { audio_t *audio = obs->audio.audio; size_t channels = audio_output_get_channels(audio); @@ -1207,8 +1242,8 @@ static inline void source_output_audio_push_back(obs_source_t *source, return; for (size_t i = 0; i < channels; i++) - circlebuf_push_back(&source->audio_input_buf[i], - in->data[i], size); + circlebuf_push_back(&source->audio_input_buf[i], in->data[i], + size); /* reset audio input buffer size to ensure that audio doesn't get * perpetually cut */ @@ -1218,25 +1253,25 @@ static inline void source_output_audio_push_back(obs_source_t *source, static inline bool source_muted(obs_source_t *source, uint64_t os_time) { if (source->push_to_mute_enabled && source->user_push_to_mute_pressed) - source->push_to_mute_stop_time = os_time + - source->push_to_mute_delay * 1000000; + source->push_to_mute_stop_time = + os_time + source->push_to_mute_delay * 1000000; if (source->push_to_talk_enabled && source->user_push_to_talk_pressed) - source->push_to_talk_stop_time = os_time + - source->push_to_talk_delay * 1000000; + source->push_to_talk_stop_time = + os_time + source->push_to_talk_delay * 1000000; bool push_to_mute_active = source->user_push_to_mute_pressed || - os_time < source->push_to_mute_stop_time; + os_time < source->push_to_mute_stop_time; bool push_to_talk_active = source->user_push_to_talk_pressed || - os_time < source->push_to_talk_stop_time; + os_time < source->push_to_talk_stop_time; return !source->enabled || source->user_muted || - (source->push_to_mute_enabled && push_to_mute_active) || - (source->push_to_talk_enabled && !push_to_talk_active); + (source->push_to_mute_enabled && push_to_mute_active) || + (source->push_to_talk_enabled && !push_to_talk_active); } static void source_output_audio_data(obs_source_t *source, - const struct audio_data *data) + const struct audio_data *data) { size_t sample_rate = audio_output_get_sample_rate(obs->audio.audio); struct audio_data in = *data; @@ -1263,14 +1298,17 @@ static void source_output_audio_data(obs_source_t *source, /* smooth audio if within threshold */ if (diff > MAX_TS_VAR && !using_direct_ts) handle_ts_jump(source, source->next_audio_ts_min, - in.timestamp, diff, os_time); - else if (diff < TS_SMOOTHING_THRESHOLD) + in.timestamp, diff, os_time); + else if (diff < TS_SMOOTHING_THRESHOLD) { + if (source->async_unbuffered && source->async_decoupled) + source->timing_adjust = os_time - in.timestamp; in.timestamp = source->next_audio_ts_min; + } } source->last_audio_ts = in.timestamp; - source->next_audio_ts_min = in.timestamp + - conv_frames_to_time(sample_rate, in.frames); + source->next_audio_ts_min = + in.timestamp + conv_frames_to_time(sample_rate, in.frames); in.timestamp += source->timing_adjust; @@ -1285,15 +1323,14 @@ static void source_output_audio_data(obs_source_t *source, if (diff < TS_SMOOTHING_THRESHOLD) { push_back = true; - /* This typically only happens if used with async video when + /* This typically only happens if used with async video when * audio/video start transitioning in to a timestamp jump. * Audio will typically have a timestamp jump, and then video * will have a timestamp jump. If that case is encountered, * just clear the audio data in that small window and force a * resync. This handles all cases rather than just looping. */ } else if (diff > MAX_TS_VAR) { - reset_audio_timing(source, data->timestamp, - os_time); + reset_audio_timing(source, data->timestamp, os_time); in.timestamp = data->timestamp + source->timing_adjust; } } @@ -1302,8 +1339,8 @@ static void source_output_audio_data(obs_source_t *source, in.timestamp += sync_offset; in.timestamp -= source->resample_offset; - source->next_audio_sys_ts_min = source->next_audio_ts_min + - source->timing_adjust; + source->next_audio_sys_ts_min = + source->next_audio_ts_min + source->timing_adjust; if (source->last_sync_offset != sync_offset) { if (source->last_sync_offset) @@ -1327,15 +1364,20 @@ enum convert_type { CONVERT_NONE, CONVERT_NV12, CONVERT_420, - CONVERT_422_U, - CONVERT_422_Y, + CONVERT_420_A, + CONVERT_422, + CONVERT_422_A, + CONVERT_422_PACK, CONVERT_444, + CONVERT_444_A, + CONVERT_444_A_PACK, CONVERT_800, CONVERT_RGB_LIMITED, + CONVERT_BGR3, }; static inline enum convert_type get_convert_type(enum video_format format, - bool full_range) + bool full_range) { switch (format) { case VIDEO_FORMAT_I420: @@ -1344,12 +1386,13 @@ static inline enum convert_type get_convert_type(enum video_format format, return CONVERT_NV12; case VIDEO_FORMAT_I444: return CONVERT_444; + case VIDEO_FORMAT_I422: + return CONVERT_422; case VIDEO_FORMAT_YVYU: case VIDEO_FORMAT_YUY2: - return CONVERT_422_Y; case VIDEO_FORMAT_UYVY: - return CONVERT_422_U; + return CONVERT_422_PACK; case VIDEO_FORMAT_Y800: return CONVERT_800; @@ -1359,157 +1402,294 @@ static inline enum convert_type get_convert_type(enum video_format format, case VIDEO_FORMAT_BGRA: case VIDEO_FORMAT_BGRX: return full_range ? CONVERT_NONE : CONVERT_RGB_LIMITED; + + case VIDEO_FORMAT_BGR3: + return CONVERT_BGR3; + + case VIDEO_FORMAT_I40A: + return CONVERT_420_A; + + case VIDEO_FORMAT_I42A: + return CONVERT_422_A; + + case VIDEO_FORMAT_YUVA: + return CONVERT_444_A; + + case VIDEO_FORMAT_AYUV: + return CONVERT_444_A_PACK; } return CONVERT_NONE; } static inline bool set_packed422_sizes(struct obs_source *source, - const struct obs_source_frame *frame) + const struct obs_source_frame *frame) { - source->async_convert_width = frame->width / 2; - source->async_convert_height = frame->height; - source->async_texture_format = GS_BGRA; + source->async_convert_width[0] = frame->width / 2; + source->async_convert_height[0] = frame->height; + source->async_texture_formats[0] = GS_BGRA; + source->async_channel_count = 1; + return true; +} + +static inline bool +set_packed444_alpha_sizes(struct obs_source *source, + const struct obs_source_frame *frame) +{ + source->async_convert_width[0] = frame->width; + source->async_convert_height[0] = frame->height; + source->async_texture_formats[0] = GS_BGRA; + source->async_channel_count = 1; return true; } static inline bool set_planar444_sizes(struct obs_source *source, - const struct obs_source_frame *frame) + const struct obs_source_frame *frame) { - source->async_convert_width = frame->width; - source->async_convert_height = frame->height * 3; - source->async_texture_format = GS_R8; - source->async_plane_offset[0] = (int)(frame->data[1] - frame->data[0]); - source->async_plane_offset[1] = (int)(frame->data[2] - frame->data[0]); + source->async_convert_width[0] = frame->width; + source->async_convert_width[1] = frame->width; + source->async_convert_width[2] = frame->width; + source->async_convert_height[0] = frame->height; + source->async_convert_height[1] = frame->height; + source->async_convert_height[2] = frame->height; + source->async_texture_formats[0] = GS_R8; + source->async_texture_formats[1] = GS_R8; + source->async_texture_formats[2] = GS_R8; + source->async_channel_count = 3; + return true; +} + +static inline bool +set_planar444_alpha_sizes(struct obs_source *source, + const struct obs_source_frame *frame) +{ + source->async_convert_width[0] = frame->width; + source->async_convert_width[1] = frame->width; + source->async_convert_width[2] = frame->width; + source->async_convert_width[3] = frame->width; + source->async_convert_height[0] = frame->height; + source->async_convert_height[1] = frame->height; + source->async_convert_height[2] = frame->height; + source->async_convert_height[3] = frame->height; + source->async_texture_formats[0] = GS_R8; + source->async_texture_formats[1] = GS_R8; + source->async_texture_formats[2] = GS_R8; + source->async_texture_formats[3] = GS_R8; + source->async_channel_count = 4; return true; } static inline bool set_planar420_sizes(struct obs_source *source, - const struct obs_source_frame *frame) + const struct obs_source_frame *frame) { - uint32_t size = frame->width * frame->height; - size += size/2; + source->async_convert_width[0] = frame->width; + source->async_convert_width[1] = frame->width / 2; + source->async_convert_width[2] = frame->width / 2; + source->async_convert_height[0] = frame->height; + source->async_convert_height[1] = frame->height / 2; + source->async_convert_height[2] = frame->height / 2; + source->async_texture_formats[0] = GS_R8; + source->async_texture_formats[1] = GS_R8; + source->async_texture_formats[2] = GS_R8; + source->async_channel_count = 3; + return true; +} - source->async_convert_width = frame->width; - source->async_convert_height = size / frame->width; - source->async_texture_format = GS_R8; - source->async_plane_offset[0] = (int)(frame->data[1] - frame->data[0]); - source->async_plane_offset[1] = (int)(frame->data[2] - frame->data[0]); +static inline bool +set_planar420_alpha_sizes(struct obs_source *source, + const struct obs_source_frame *frame) +{ + source->async_convert_width[0] = frame->width; + source->async_convert_width[1] = frame->width / 2; + source->async_convert_width[2] = frame->width / 2; + source->async_convert_width[3] = frame->width; + source->async_convert_height[0] = frame->height; + source->async_convert_height[1] = frame->height / 2; + source->async_convert_height[2] = frame->height / 2; + source->async_convert_height[3] = frame->height; + source->async_texture_formats[0] = GS_R8; + source->async_texture_formats[1] = GS_R8; + source->async_texture_formats[2] = GS_R8; + source->async_texture_formats[3] = GS_R8; + source->async_channel_count = 4; + return true; +} + +static inline bool set_planar422_sizes(struct obs_source *source, + const struct obs_source_frame *frame) +{ + source->async_convert_width[0] = frame->width; + source->async_convert_width[1] = frame->width / 2; + source->async_convert_width[2] = frame->width / 2; + source->async_convert_height[0] = frame->height; + source->async_convert_height[1] = frame->height; + source->async_convert_height[2] = frame->height; + source->async_texture_formats[0] = GS_R8; + source->async_texture_formats[1] = GS_R8; + source->async_texture_formats[2] = GS_R8; + source->async_channel_count = 3; + return true; +} + +static inline bool +set_planar422_alpha_sizes(struct obs_source *source, + const struct obs_source_frame *frame) +{ + source->async_convert_width[0] = frame->width; + source->async_convert_width[1] = frame->width / 2; + source->async_convert_width[2] = frame->width / 2; + source->async_convert_width[3] = frame->width; + source->async_convert_height[0] = frame->height; + source->async_convert_height[1] = frame->height; + source->async_convert_height[2] = frame->height; + source->async_convert_height[3] = frame->height; + source->async_texture_formats[0] = GS_R8; + source->async_texture_formats[1] = GS_R8; + source->async_texture_formats[2] = GS_R8; + source->async_texture_formats[3] = GS_R8; + source->async_channel_count = 4; return true; } static inline bool set_nv12_sizes(struct obs_source *source, - const struct obs_source_frame *frame) + const struct obs_source_frame *frame) { - uint32_t size = frame->width * frame->height; - size += size/2; - - source->async_convert_width = frame->width; - source->async_convert_height = size / frame->width; - source->async_texture_format = GS_R8; - source->async_plane_offset[0] = (int)(frame->data[1] - frame->data[0]); + source->async_convert_width[0] = frame->width; + source->async_convert_width[1] = frame->width / 2; + source->async_convert_height[0] = frame->height; + source->async_convert_height[1] = frame->height / 2; + source->async_texture_formats[0] = GS_R8; + source->async_texture_formats[1] = GS_R8G8; + source->async_channel_count = 2; return true; } static inline bool set_y800_sizes(struct obs_source *source, - const struct obs_source_frame *frame) + const struct obs_source_frame *frame) { - source->async_convert_width = frame->width; - source->async_convert_height = frame->height; - source->async_texture_format = GS_R8; + source->async_convert_width[0] = frame->width; + source->async_convert_height[0] = frame->height; + source->async_texture_formats[0] = GS_R8; + source->async_channel_count = 1; return true; } static inline bool set_rgb_limited_sizes(struct obs_source *source, - const struct obs_source_frame *frame) + const struct obs_source_frame *frame) { - source->async_convert_width = frame->width; - source->async_convert_height = frame->height; - source->async_texture_format = convert_video_format(frame->format); + source->async_convert_width[0] = frame->width; + source->async_convert_height[0] = frame->height; + source->async_texture_formats[0] = convert_video_format(frame->format); + source->async_channel_count = 1; + return true; +} + +static inline bool set_bgr3_sizes(struct obs_source *source, + const struct obs_source_frame *frame) +{ + source->async_convert_width[0] = frame->width * 3; + source->async_convert_height[0] = frame->height; + source->async_texture_formats[0] = GS_R8; + source->async_channel_count = 1; return true; } static inline bool init_gpu_conversion(struct obs_source *source, - const struct obs_source_frame *frame) + const struct obs_source_frame *frame) { switch (get_convert_type(frame->format, frame->full_range)) { - case CONVERT_422_Y: - case CONVERT_422_U: - return set_packed422_sizes(source, frame); + case CONVERT_422_PACK: + return set_packed422_sizes(source, frame); - case CONVERT_420: - return set_planar420_sizes(source, frame); + case CONVERT_420: + return set_planar420_sizes(source, frame); - case CONVERT_NV12: - return set_nv12_sizes(source, frame); + case CONVERT_422: + return set_planar422_sizes(source, frame); - case CONVERT_444: - return set_planar444_sizes(source, frame); + case CONVERT_NV12: + return set_nv12_sizes(source, frame); - case CONVERT_800: - return set_y800_sizes(source, frame); + case CONVERT_444: + return set_planar444_sizes(source, frame); - case CONVERT_RGB_LIMITED: - return set_rgb_limited_sizes(source, frame); + case CONVERT_800: + return set_y800_sizes(source, frame); - case CONVERT_NONE: - assert(false && "No conversion requested"); - break; + case CONVERT_RGB_LIMITED: + return set_rgb_limited_sizes(source, frame); + case CONVERT_BGR3: + return set_bgr3_sizes(source, frame); + + case CONVERT_420_A: + return set_planar420_alpha_sizes(source, frame); + + case CONVERT_422_A: + return set_planar422_alpha_sizes(source, frame); + + case CONVERT_444_A: + return set_planar444_alpha_sizes(source, frame); + + case CONVERT_444_A_PACK: + return set_packed444_alpha_sizes(source, frame); + + case CONVERT_NONE: + assert(false && "No conversion requested"); + break; } return false; } bool set_async_texture_size(struct obs_source *source, - const struct obs_source_frame *frame) + const struct obs_source_frame *frame) { - enum convert_type cur = get_convert_type(frame->format, - frame->full_range); + enum convert_type cur = + get_convert_type(frame->format, frame->full_range); - if (source->async_width == frame->width && - source->async_height == frame->height && - source->async_format == frame->format && + if (source->async_width == frame->width && + source->async_height == frame->height && + source->async_format == frame->format && source->async_full_range == frame->full_range) return true; - source->async_width = frame->width; - source->async_height = frame->height; - source->async_format = frame->format; + source->async_width = frame->width; + source->async_height = frame->height; + source->async_format = frame->format; source->async_full_range = frame->full_range; gs_enter_context(obs->video.graphics); - gs_texture_destroy(source->async_texture); - gs_texture_destroy(source->async_prev_texture); + for (size_t c = 0; c < MAX_AV_PLANES; c++) { + gs_texture_destroy(source->async_textures[c]); + source->async_textures[c] = NULL; + gs_texture_destroy(source->async_prev_textures[c]); + source->async_prev_textures[c] = NULL; + } + gs_texrender_destroy(source->async_texrender); gs_texrender_destroy(source->async_prev_texrender); - source->async_texture = NULL; - source->async_prev_texture = NULL; source->async_texrender = NULL; source->async_prev_texrender = NULL; - if (cur != CONVERT_NONE && init_gpu_conversion(source, frame)) { - source->async_gpu_conversion = true; - - enum gs_color_format format = CONVERT_RGB_LIMITED ? - convert_video_format(frame->format) : GS_BGRX; + const enum gs_color_format format = convert_video_format(frame->format); + const bool async_gpu_conversion = (cur != CONVERT_NONE) && + init_gpu_conversion(source, frame); + source->async_gpu_conversion = async_gpu_conversion; + if (async_gpu_conversion) { source->async_texrender = gs_texrender_create(format, GS_ZS_NONE); - source->async_texture = gs_texture_create( - source->async_convert_width, - source->async_convert_height, - source->async_texture_format, - 1, NULL, GS_DYNAMIC); - + for (int c = 0; c < source->async_channel_count; ++c) + source->async_textures[c] = gs_texture_create( + source->async_convert_width[c], + source->async_convert_height[c], + source->async_texture_formats[c], 1, NULL, + GS_DYNAMIC); } else { - enum gs_color_format format = convert_video_format( - frame->format); - source->async_gpu_conversion = false; - - source->async_texture = gs_texture_create( - frame->width, frame->height, - format, 1, NULL, GS_DYNAMIC); + source->async_textures[0] = + gs_texture_create(frame->width, frame->height, format, + 1, NULL, GS_DYNAMIC); } if (deinterlacing_enabled(source)) @@ -1517,68 +1697,90 @@ bool set_async_texture_size(struct obs_source *source, gs_leave_context(); - return !!source->async_texture; + return source->async_textures[0] != NULL; } -static void upload_raw_frame(gs_texture_t *tex, - const struct obs_source_frame *frame) +static void upload_raw_frame(gs_texture_t *tex[MAX_AV_PLANES], + const struct obs_source_frame *frame) { switch (get_convert_type(frame->format, frame->full_range)) { - case CONVERT_422_U: - case CONVERT_422_Y: - case CONVERT_800: - case CONVERT_RGB_LIMITED: - gs_texture_set_image(tex, frame->data[0], - frame->linesize[0], false); - break; + case CONVERT_422_PACK: + case CONVERT_800: + case CONVERT_RGB_LIMITED: + case CONVERT_BGR3: + case CONVERT_420: + case CONVERT_422: + case CONVERT_NV12: + case CONVERT_444: + case CONVERT_420_A: + case CONVERT_422_A: + case CONVERT_444_A: + case CONVERT_444_A_PACK: + for (size_t c = 0; c < MAX_AV_PLANES; c++) { + if (tex[c]) + gs_texture_set_image(tex[c], frame->data[c], + frame->linesize[c], false); + } + break; - case CONVERT_420: - case CONVERT_NV12: - case CONVERT_444: - gs_texture_set_image(tex, frame->data[0], - frame->width, false); - break; - - case CONVERT_NONE: - assert(false && "No conversion requested"); - break; + case CONVERT_NONE: + assert(false && "No conversion requested"); + break; } } static const char *select_conversion_technique(enum video_format format, - bool full_range) + bool full_range) { switch (format) { - case VIDEO_FORMAT_UYVY: - return "UYVY_Reverse"; + case VIDEO_FORMAT_UYVY: + return "UYVY_Reverse"; - case VIDEO_FORMAT_YUY2: - return "YUY2_Reverse"; + case VIDEO_FORMAT_YUY2: + return "YUY2_Reverse"; - case VIDEO_FORMAT_YVYU: - return "YVYU_Reverse"; + case VIDEO_FORMAT_YVYU: + return "YVYU_Reverse"; - case VIDEO_FORMAT_I420: - return "I420_Reverse"; + case VIDEO_FORMAT_I420: + return "I420_Reverse"; - case VIDEO_FORMAT_NV12: - return "NV12_Reverse"; + case VIDEO_FORMAT_NV12: + return "NV12_Reverse"; - case VIDEO_FORMAT_I444: - return "I444_Reverse"; + case VIDEO_FORMAT_I444: + return "I444_Reverse"; - case VIDEO_FORMAT_Y800: - return full_range ? "Y800_Full" : "Y800_Limited"; + case VIDEO_FORMAT_Y800: + return full_range ? "Y800_Full" : "Y800_Limited"; - case VIDEO_FORMAT_BGRA: - case VIDEO_FORMAT_BGRX: - case VIDEO_FORMAT_RGBA: - case VIDEO_FORMAT_NONE: - if (full_range) - assert(false && "No conversion requested"); - else - return "RGB_Limited"; - break; + case VIDEO_FORMAT_BGR3: + return full_range ? "BGR3_Full" : "BGR3_Limited"; + + case VIDEO_FORMAT_I422: + return "I422_Reverse"; + + case VIDEO_FORMAT_I40A: + return "I40A_Reverse"; + + case VIDEO_FORMAT_I42A: + return "I42A_Reverse"; + + case VIDEO_FORMAT_YUVA: + return "YUVA_Reverse"; + + case VIDEO_FORMAT_AYUV: + return "AYUV_Reverse"; + + case VIDEO_FORMAT_BGRA: + case VIDEO_FORMAT_BGRX: + case VIDEO_FORMAT_RGBA: + case VIDEO_FORMAT_NONE: + if (full_range) + assert(false && "No conversion requested"); + else + return "RGB_Limited"; + break; } return NULL; } @@ -1596,8 +1798,9 @@ static inline void set_eparami(gs_effect_t *effect, const char *name, int val) } static bool update_async_texrender(struct obs_source *source, - const struct obs_source_frame *frame, - gs_texture_t *tex, gs_texrender_t *texrender) + const struct obs_source_frame *frame, + gs_texture_t *tex[MAX_AV_PLANES], + gs_texrender_t *texrender) { GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_CONVERT_FORMAT, "Convert Format"); @@ -1608,80 +1811,104 @@ static bool update_async_texrender(struct obs_source *source, uint32_t cx = source->async_width; uint32_t cy = source->async_height; - float convert_width = (float)source->async_convert_width; - gs_effect_t *conv = obs->video.conversion_effect; - const char *tech_name = select_conversion_technique(frame->format, - frame->full_range); + const char *tech_name = + select_conversion_technique(frame->format, frame->full_range); gs_technique_t *tech = gs_effect_get_technique(conv, tech_name); - if (!gs_texrender_begin(texrender, cx, cy)) { - GS_DEBUG_MARKER_END(); - return false; - } + const bool success = gs_texrender_begin(texrender, cx, cy); - gs_enable_blending(false); + if (success) { + gs_enable_blending(false); - gs_technique_begin(tech); - gs_technique_begin_pass(tech, 0); + gs_technique_begin(tech); + gs_technique_begin_pass(tech, 0); - gs_effect_set_texture(gs_effect_get_param_by_name(conv, "image"), tex); - set_eparam(conv, "width", (float)cx); - set_eparam(conv, "height", (float)cy); - set_eparam(conv, "width_d2", cx * 0.5f); - set_eparam(conv, "width_d2_i", 1.0f / (cx * 0.5f)); - set_eparam(conv, "input_width_i_d2", (1.0f / convert_width) * 0.5f); + if (tex[0]) + gs_effect_set_texture( + gs_effect_get_param_by_name(conv, "image"), + tex[0]); + if (tex[1]) + gs_effect_set_texture( + gs_effect_get_param_by_name(conv, "image1"), + tex[1]); + if (tex[2]) + gs_effect_set_texture( + gs_effect_get_param_by_name(conv, "image2"), + tex[2]); + if (tex[3]) + gs_effect_set_texture( + gs_effect_get_param_by_name(conv, "image3"), + tex[3]); + set_eparam(conv, "width", (float)cx); + set_eparam(conv, "height", (float)cy); + set_eparam(conv, "width_d2", (float)cx * 0.5f); + set_eparam(conv, "height_d2", (float)cy * 0.5f); + set_eparam(conv, "width_x2_i", 0.5f / (float)cx); - set_eparami(conv, "int_width", (int)cx); - set_eparami(conv, "int_input_width", (int)source->async_convert_width); - set_eparami(conv, "int_u_plane_offset", - (int)source->async_plane_offset[0]); - set_eparami(conv, "int_v_plane_offset", - (int)source->async_plane_offset[1]); - - gs_effect_set_val(gs_effect_get_param_by_name(conv, "color_matrix"), - frame->color_matrix, sizeof(float) * 16); - if (!frame->full_range) { - gs_eparam_t *min_param = gs_effect_get_param_by_name( + struct vec4 vec0, vec1, vec2; + vec4_set(&vec0, frame->color_matrix[0], frame->color_matrix[1], + frame->color_matrix[2], frame->color_matrix[3]); + vec4_set(&vec1, frame->color_matrix[4], frame->color_matrix[5], + frame->color_matrix[6], frame->color_matrix[7]); + vec4_set(&vec2, frame->color_matrix[8], frame->color_matrix[9], + frame->color_matrix[10], frame->color_matrix[11]); + gs_effect_set_vec4( + gs_effect_get_param_by_name(conv, "color_vec0"), &vec0); + gs_effect_set_vec4( + gs_effect_get_param_by_name(conv, "color_vec1"), &vec1); + gs_effect_set_vec4( + gs_effect_get_param_by_name(conv, "color_vec2"), &vec2); + if (!frame->full_range) { + gs_eparam_t *min_param = gs_effect_get_param_by_name( conv, "color_range_min"); - gs_effect_set_val(min_param, frame->color_range_min, - sizeof(float) * 3); - gs_eparam_t *max_param = gs_effect_get_param_by_name( + gs_effect_set_val(min_param, frame->color_range_min, + sizeof(float) * 3); + gs_eparam_t *max_param = gs_effect_get_param_by_name( conv, "color_range_max"); - gs_effect_set_val(max_param, frame->color_range_max, - sizeof(float) * 3); + gs_effect_set_val(max_param, frame->color_range_max, + sizeof(float) * 3); + } + + gs_draw(GS_TRIS, 0, 3); + + gs_technique_end_pass(tech); + gs_technique_end(tech); + + gs_enable_blending(true); + + gs_texrender_end(texrender); } - gs_ortho(0.f, (float)cx, 0.f, (float)cy, -100.f, 100.f); - - gs_draw_sprite(tex, 0, cx, cy); - - gs_technique_end_pass(tech); - gs_technique_end(tech); - - gs_enable_blending(true); - - gs_texrender_end(texrender); - GS_DEBUG_MARKER_END(); - return true; + return success; } bool update_async_texture(struct obs_source *source, - const struct obs_source_frame *frame, - gs_texture_t *tex, gs_texrender_t *texrender) + const struct obs_source_frame *frame, + gs_texture_t *tex, gs_texrender_t *texrender) +{ + gs_texture_t *tex3[MAX_AV_PLANES] = {tex, NULL, NULL, NULL, + NULL, NULL, NULL, NULL}; + return update_async_textures(source, frame, tex3, texrender); +} + +bool update_async_textures(struct obs_source *source, + const struct obs_source_frame *frame, + gs_texture_t *tex[MAX_AV_PLANES], + gs_texrender_t *texrender) { enum convert_type type; - source->async_flip = frame->flip; + source->async_flip = frame->flip; if (source->async_gpu_conversion && texrender) return update_async_texrender(source, frame, tex, texrender); type = get_convert_type(frame->format, frame->full_range); if (type == CONVERT_NONE) { - gs_texture_set_image(tex, frame->data[0], frame->linesize[0], - false); + gs_texture_set_image(tex[0], frame->data[0], frame->linesize[0], + false); return true; } @@ -1689,10 +1916,10 @@ bool update_async_texture(struct obs_source *source, } static inline void obs_source_draw_texture(struct obs_source *source, - gs_effect_t *effect) + gs_effect_t *effect) { - gs_texture_t *tex = source->async_texture; - gs_eparam_t *param; + gs_texture_t *tex = source->async_textures[0]; + gs_eparam_t *param; if (source->async_texrender) tex = gs_texrender_get_texture(source->async_texrender); @@ -1705,9 +1932,9 @@ static inline void obs_source_draw_texture(struct obs_source *source, static void obs_source_draw_async_texture(struct obs_source *source) { - gs_effect_t *effect = gs_get_effect(); - bool def_draw = (!effect); - gs_technique_t *tech = NULL; + gs_effect_t *effect = gs_get_effect(); + bool def_draw = (!effect); + gs_technique_t *tech = NULL; if (def_draw) { effect = obs_get_base_effect(OBS_EFFECT_DEFAULT); @@ -1724,6 +1951,28 @@ static void obs_source_draw_async_texture(struct obs_source *source) } } +static void recreate_async_texture(obs_source_t *source, + enum gs_color_format format) +{ + uint32_t cx = gs_texture_get_width(source->async_textures[0]); + uint32_t cy = gs_texture_get_height(source->async_textures[0]); + gs_texture_destroy(source->async_textures[0]); + source->async_textures[0] = + gs_texture_create(cx, cy, format, 1, NULL, GS_DYNAMIC); +} + +static inline void check_to_swap_bgrx_bgra(obs_source_t *source, + struct obs_source_frame *frame) +{ + enum gs_color_format format = + gs_texture_get_color_format(source->async_textures[0]); + if (format == GS_BGRX && frame->format == VIDEO_FORMAT_BGRA) { + recreate_async_texture(source, GS_BGRA); + } else if (format == GS_BGRA && frame->format == VIDEO_FORMAT_BGRX) { + recreate_async_texture(source, GS_BGRX); + } +} + static void obs_source_update_async_video(obs_source_t *source) { if (!source->async_rendered) { @@ -1734,18 +1983,19 @@ static void obs_source_update_async_video(obs_source_t *source) source->async_rendered = true; if (frame) { + check_to_swap_bgrx_bgra(source, frame); + if (!source->async_decoupled || !source->async_unbuffered) { - source->timing_adjust = - obs->video.video_time - - frame->timestamp; + source->timing_adjust = obs->video.video_time - + frame->timestamp; source->timing_set = true; } if (source->async_update_texture) { - update_async_texture(source, frame, - source->async_texture, - source->async_texrender); + update_async_textures(source, frame, + source->async_textures, + source->async_texrender); source->async_update_texture = false; } @@ -1756,7 +2006,7 @@ static void obs_source_update_async_video(obs_source_t *source) static inline void obs_source_render_async_video(obs_source_t *source) { - if (source->async_texture && source->async_active) + if (source->async_textures[0] && source->async_active) obs_source_draw_async_texture(source); } @@ -1778,9 +2028,9 @@ static inline void obs_source_render_filters(obs_source_t *source) void obs_source_default_render(obs_source_t *source) { - gs_effect_t *effect = obs->video.default_effect; - gs_technique_t *tech = gs_effect_get_technique(effect, "Draw"); - size_t passes, i; + gs_effect_t *effect = obs->video.default_effect; + gs_technique_t *tech = gs_effect_get_technique(effect, "Draw"); + size_t passes, i; passes = gs_technique_begin(tech); for (i = 0; i < passes; i++) { @@ -1794,17 +2044,16 @@ void obs_source_default_render(obs_source_t *source) static inline void obs_source_main_render(obs_source_t *source) { - uint32_t flags = source->info.output_flags; - bool custom_draw = (flags & OBS_SOURCE_CUSTOM_DRAW) != 0; + uint32_t flags = source->info.output_flags; + bool custom_draw = (flags & OBS_SOURCE_CUSTOM_DRAW) != 0; bool default_effect = !source->filter_parent && - source->filters.num == 0 && - !custom_draw; + source->filters.num == 0 && !custom_draw; if (default_effect) obs_source_default_render(source); else if (source->context.data) source->info.video_render(source->context.data, - custom_draw ? NULL : gs_get_effect()); + custom_draw ? NULL : gs_get_effect()); } static bool ready_async_frame(obs_source_t *source, uint64_t sys_time); @@ -1851,8 +2100,8 @@ static inline void render_video(obs_source_t *source) } GS_DEBUG_MARKER_BEGIN_FORMAT(GS_DEBUG_COLOR_SOURCE, - get_type_format(source->info.type), - obs_source_get_name(source)); + get_type_format(source->info.type), + obs_source_get_name(source)); if (source->filters.num && !source->rendering_filter) obs_source_render_filters(source); @@ -1924,9 +2173,8 @@ static uint32_t get_recurse_width(obs_source_t *source) pthread_mutex_lock(&source->filter_mutex); - width = (source->filters.num) ? - get_base_width(source->filters.array[0]) : - get_base_width(source); + width = (source->filters.num) ? get_base_width(source->filters.array[0]) + : get_base_width(source); pthread_mutex_unlock(&source->filter_mutex); @@ -1939,9 +2187,9 @@ static uint32_t get_recurse_height(obs_source_t *source) pthread_mutex_lock(&source->filter_mutex); - height = (source->filters.num) ? - get_base_height(source->filters.array[0]) : - get_base_height(source); + height = (source->filters.num) + ? get_base_height(source->filters.array[0]) + : get_base_height(source); pthread_mutex_unlock(&source->filter_mutex); @@ -1953,9 +2201,9 @@ uint32_t obs_source_get_width(obs_source_t *source) if (!data_valid(source, "obs_source_get_width")) return 0; - return (source->info.type != OBS_SOURCE_TYPE_FILTER) ? - get_recurse_width(source) : - get_base_width(source); + return (source->info.type != OBS_SOURCE_TYPE_FILTER) + ? get_recurse_width(source) + : get_base_width(source); } uint32_t obs_source_get_height(obs_source_t *source) @@ -1963,9 +2211,9 @@ uint32_t obs_source_get_height(obs_source_t *source) if (!data_valid(source, "obs_source_get_height")) return 0; - return (source->info.type != OBS_SOURCE_TYPE_FILTER) ? - get_recurse_height(source) : - get_base_height(source); + return (source->info.type != OBS_SOURCE_TYPE_FILTER) + ? get_recurse_height(source) + : get_base_height(source); } uint32_t obs_source_get_base_width(obs_source_t *source) @@ -1986,14 +2234,16 @@ uint32_t obs_source_get_base_height(obs_source_t *source) obs_source_t *obs_filter_get_parent(const obs_source_t *filter) { - return obs_ptr_valid(filter, "obs_filter_get_parent") ? - filter->filter_parent : NULL; + return obs_ptr_valid(filter, "obs_filter_get_parent") + ? filter->filter_parent + : NULL; } obs_source_t *obs_filter_get_target(const obs_source_t *filter) { - return obs_ptr_valid(filter, "obs_filter_get_target") ? - filter->filter_target : NULL; + return obs_ptr_valid(filter, "obs_filter_get_target") + ? filter->filter_target + : NULL; } static bool filter_compatible(obs_source_t *source, obs_source_t *filter) @@ -2022,7 +2272,7 @@ void obs_source_filter_add(obs_source_t *source, obs_source_t *filter) if (da_find(source->filters, &filter, 0) != DARRAY_INVALID) { blog(LOG_WARNING, "Tried to add a filter that was already " - "present on the source"); + "present on the source"); pthread_mutex_unlock(&source->filter_mutex); return; } @@ -2035,8 +2285,8 @@ void obs_source_filter_add(obs_source_t *source, obs_source_t *filter) obs_source_addref(filter); filter->filter_parent = source; - filter->filter_target = !source->filters.num ? - source : source->filters.array[0]; + filter->filter_target = !source->filters.num ? source + : source->filters.array[0]; da_insert(source->filters, 0, &filter); @@ -2049,12 +2299,11 @@ void obs_source_filter_add(obs_source_t *source, obs_source_t *filter) signal_handler_signal(source->context.signals, "filter_add", &cd); blog(LOG_DEBUG, "- filter '%s' (%s) added to source '%s'", - filter->context.name, filter->info.id, - source->context.name); + filter->context.name, filter->info.id, source->context.name); } static bool obs_source_filter_remove_refless(obs_source_t *source, - obs_source_t *filter) + obs_source_t *filter) { struct calldata cd; uint8_t stack[128]; @@ -2069,7 +2318,7 @@ static bool obs_source_filter_remove_refless(obs_source_t *source, } if (idx > 0) { - obs_source_t *prev = source->filters.array[idx-1]; + obs_source_t *prev = source->filters.array[idx - 1]; prev->filter_target = filter->filter_target; } @@ -2084,12 +2333,11 @@ static bool obs_source_filter_remove_refless(obs_source_t *source, signal_handler_signal(source->context.signals, "filter_remove", &cd); blog(LOG_DEBUG, "- filter '%s' (%s) removed from source '%s'", - filter->context.name, filter->info.id, - source->context.name); + filter->context.name, filter->info.id, source->context.name); if (filter->info.filter_remove) filter->info.filter_remove(filter->context.data, - filter->filter_parent); + filter->filter_parent); filter->filter_parent = NULL; filter->filter_target = NULL; @@ -2108,26 +2356,26 @@ void obs_source_filter_remove(obs_source_t *source, obs_source_t *filter) } static size_t find_next_filter(obs_source_t *source, obs_source_t *filter, - size_t cur_idx) + size_t cur_idx) { bool curAsync = (filter->info.output_flags & OBS_SOURCE_ASYNC) != 0; bool nextAsync; obs_source_t *next; - if (cur_idx == source->filters.num-1) + if (cur_idx == source->filters.num - 1) return DARRAY_INVALID; - next = source->filters.array[cur_idx+1]; + next = source->filters.array[cur_idx + 1]; nextAsync = (next->info.output_flags & OBS_SOURCE_ASYNC); if (nextAsync == curAsync) - return cur_idx+1; + return cur_idx + 1; else - return find_next_filter(source, filter, cur_idx+1); + return find_next_filter(source, filter, cur_idx + 1); } static size_t find_prev_filter(obs_source_t *source, obs_source_t *filter, - size_t cur_idx) + size_t cur_idx) { bool curAsync = (filter->info.output_flags & OBS_SOURCE_ASYNC) != 0; bool prevAsync; @@ -2136,18 +2384,18 @@ static size_t find_prev_filter(obs_source_t *source, obs_source_t *filter, if (cur_idx == 0) return DARRAY_INVALID; - prev = source->filters.array[cur_idx-1]; + prev = source->filters.array[cur_idx - 1]; prevAsync = (prev->info.output_flags & OBS_SOURCE_ASYNC); if (prevAsync == curAsync) - return cur_idx-1; + return cur_idx - 1; else - return find_prev_filter(source, filter, cur_idx-1); + return find_prev_filter(source, filter, cur_idx - 1); } /* moves filters above/below matching filter types */ -static bool move_filter_dir(obs_source_t *source, - obs_source_t *filter, enum obs_order_movement movement) +static bool move_filter_dir(obs_source_t *source, obs_source_t *filter, + enum obs_order_movement movement) { size_t idx; @@ -2168,9 +2416,9 @@ static bool move_filter_dir(obs_source_t *source, da_move_item(source->filters, idx, prev_id); } else if (movement == OBS_ORDER_MOVE_TOP) { - if (idx == source->filters.num-1) + if (idx == source->filters.num - 1) return false; - da_move_item(source->filters, idx, source->filters.num-1); + da_move_item(source->filters, idx, source->filters.num - 1); } else if (movement == OBS_ORDER_MOVE_BOTTOM) { if (idx == 0) @@ -2180,8 +2428,10 @@ static bool move_filter_dir(obs_source_t *source, /* reorder filter targets, not the nicest way of dealing with things */ for (size_t i = 0; i < source->filters.num; i++) { - obs_source_t *next_filter = (i == source->filters.num-1) ? - source : source->filters.array[i + 1]; + obs_source_t *next_filter = + (i == source->filters.num - 1) + ? source + : source->filters.array[i + 1]; source->filters.array[i]->filter_target = next_filter; } @@ -2190,7 +2440,7 @@ static bool move_filter_dir(obs_source_t *source, } void obs_source_filter_set_order(obs_source_t *source, obs_source_t *filter, - enum obs_order_movement movement) + enum obs_order_movement movement) { bool success; @@ -2217,21 +2467,21 @@ obs_data_t *obs_source_get_settings(const obs_source_t *source) } struct obs_source_frame *filter_async_video(obs_source_t *source, - struct obs_source_frame *in) + struct obs_source_frame *in) { size_t i; pthread_mutex_lock(&source->filter_mutex); for (i = source->filters.num; i > 0; i--) { - struct obs_source *filter = source->filters.array[i-1]; + struct obs_source *filter = source->filters.array[i - 1]; if (!filter->enabled) continue; if (filter->context.data && filter->info.filter_video) { in = filter->info.filter_video(filter->context.data, - in); + in); if (!in) break; } @@ -2243,34 +2493,36 @@ struct obs_source_frame *filter_async_video(obs_source_t *source, } static inline void copy_frame_data_line(struct obs_source_frame *dst, - const struct obs_source_frame *src, uint32_t plane, uint32_t y) + const struct obs_source_frame *src, + uint32_t plane, uint32_t y) { uint32_t pos_src = y * src->linesize[plane]; uint32_t pos_dst = y * dst->linesize[plane]; - uint32_t bytes = dst->linesize[plane] < src->linesize[plane] ? - dst->linesize[plane] : src->linesize[plane]; + uint32_t bytes = dst->linesize[plane] < src->linesize[plane] + ? dst->linesize[plane] + : src->linesize[plane]; memcpy(dst->data[plane] + pos_dst, src->data[plane] + pos_src, bytes); } static inline void copy_frame_data_plane(struct obs_source_frame *dst, - const struct obs_source_frame *src, - uint32_t plane, uint32_t lines) + const struct obs_source_frame *src, + uint32_t plane, uint32_t lines) { if (dst->linesize[plane] != src->linesize[plane]) for (uint32_t y = 0; y < lines; y++) copy_frame_data_line(dst, src, plane, y); else memcpy(dst->data[plane], src->data[plane], - dst->linesize[plane] * lines); + dst->linesize[plane] * lines); } static void copy_frame_data(struct obs_source_frame *dst, - const struct obs_source_frame *src) + const struct obs_source_frame *src) { - dst->flip = src->flip; - dst->full_range = src->full_range; - dst->timestamp = src->timestamp; + dst->flip = src->flip; + dst->full_range = src->full_range; + dst->timestamp = src->timestamp; memcpy(dst->color_matrix, src->color_matrix, sizeof(float) * 16); if (!dst->full_range) { size_t const size = sizeof(float) * 3; @@ -2281,16 +2533,17 @@ static void copy_frame_data(struct obs_source_frame *dst, switch (src->format) { case VIDEO_FORMAT_I420: copy_frame_data_plane(dst, src, 0, dst->height); - copy_frame_data_plane(dst, src, 1, dst->height/2); - copy_frame_data_plane(dst, src, 2, dst->height/2); + copy_frame_data_plane(dst, src, 1, dst->height / 2); + copy_frame_data_plane(dst, src, 2, dst->height / 2); break; case VIDEO_FORMAT_NV12: copy_frame_data_plane(dst, src, 0, dst->height); - copy_frame_data_plane(dst, src, 1, dst->height/2); + copy_frame_data_plane(dst, src, 1, dst->height / 2); break; case VIDEO_FORMAT_I444: + case VIDEO_FORMAT_I422: copy_frame_data_plane(dst, src, 0, dst->height); copy_frame_data_plane(dst, src, 1, dst->height); copy_frame_data_plane(dst, src, 2, dst->height); @@ -2304,28 +2557,44 @@ static void copy_frame_data(struct obs_source_frame *dst, case VIDEO_FORMAT_BGRA: case VIDEO_FORMAT_BGRX: case VIDEO_FORMAT_Y800: + case VIDEO_FORMAT_BGR3: + case VIDEO_FORMAT_AYUV: copy_frame_data_plane(dst, src, 0, dst->height); break; + + case VIDEO_FORMAT_I40A: + copy_frame_data_plane(dst, src, 0, dst->height); + copy_frame_data_plane(dst, src, 1, dst->height / 2); + copy_frame_data_plane(dst, src, 2, dst->height / 2); + copy_frame_data_plane(dst, src, 3, dst->height); + break; + + case VIDEO_FORMAT_I42A: + case VIDEO_FORMAT_YUVA: + copy_frame_data_plane(dst, src, 0, dst->height); + copy_frame_data_plane(dst, src, 1, dst->height); + copy_frame_data_plane(dst, src, 2, dst->height); + copy_frame_data_plane(dst, src, 3, dst->height); + break; } } void obs_source_frame_copy(struct obs_source_frame *dst, - const struct obs_source_frame *src) + const struct obs_source_frame *src) { copy_frame_data(dst, src); } static inline bool async_texture_changed(struct obs_source *source, - const struct obs_source_frame *frame) + const struct obs_source_frame *frame) { enum convert_type prev, cur; prev = get_convert_type(source->async_cache_format, - source->async_cache_full_range); - cur = get_convert_type(frame->format, frame->full_range); + source->async_cache_full_range); + cur = get_convert_type(frame->format, frame->full_range); - return source->async_cache_width != frame->width || - source->async_cache_height != frame->height || - prev != cur; + return source->async_cache_width != frame->width || + source->async_cache_height != frame->height || prev != cur; } static inline void free_async_cache(struct obs_source *source) @@ -2358,8 +2627,8 @@ static void clean_cache(obs_source_t *source) #define MAX_ASYNC_FRAMES 30 //if return value is not null then do (os_atomic_dec_long(&output->refs) == 0) && obs_source_frame_destroy(output) -static inline struct obs_source_frame *cache_video(struct obs_source *source, - const struct obs_source_frame *frame) +static inline struct obs_source_frame * +cache_video(struct obs_source *source, const struct obs_source_frame *frame) { struct obs_source_frame *new_frame = NULL; @@ -2374,16 +2643,19 @@ static inline struct obs_source_frame *cache_video(struct obs_source *source, if (async_texture_changed(source, frame)) { free_async_cache(source); - source->async_cache_width = frame->width; - source->async_cache_height = frame->height; - source->async_cache_format = frame->format; - source->async_cache_full_range = frame->full_range; + source->async_cache_width = frame->width; + source->async_cache_height = frame->height; } + const enum video_format format = frame->format; + source->async_cache_format = format; + source->async_cache_full_range = frame->full_range; + for (size_t i = 0; i < source->async_cache.num; i++) { struct async_frame *af = &source->async_cache.array[i]; if (!af->used) { new_frame = af->frame; + new_frame->format = format; af->used = true; af->unused_count = 0; break; @@ -2394,10 +2666,9 @@ static inline struct obs_source_frame *cache_video(struct obs_source *source, if (!new_frame) { struct async_frame new_af; - enum video_format format = frame->format; - new_frame = obs_source_frame_create(format, - frame->width, frame->height); + new_frame = obs_source_frame_create(format, frame->width, + frame->height); new_af.frame = new_frame; new_af.used = true; new_af.unused_count = 0; @@ -2415,8 +2686,9 @@ static inline struct obs_source_frame *cache_video(struct obs_source *source, return new_frame; } -static void obs_source_output_video_internal(obs_source_t *source, - const struct obs_source_frame *frame) +static void +obs_source_output_video_internal(obs_source_t *source, + const struct obs_source_frame *frame) { if (!obs_source_valid(source, "obs_source_output_video")) return; @@ -2426,8 +2698,8 @@ static void obs_source_output_video_internal(obs_source_t *source, return; } - struct obs_source_frame *output = !!frame ? - cache_video(source, frame) : NULL; + struct obs_source_frame *output = !!frame ? cache_video(source, frame) + : NULL; /* ------------------------------------------- */ pthread_mutex_lock(&source->async_mutex); @@ -2444,7 +2716,7 @@ static void obs_source_output_video_internal(obs_source_t *source, } void obs_source_output_video(obs_source_t *source, - const struct obs_source_frame *frame) + const struct obs_source_frame *frame) { if (!frame) { obs_source_output_video_internal(source, NULL); @@ -2452,15 +2724,14 @@ void obs_source_output_video(obs_source_t *source, } struct obs_source_frame new_frame = *frame; - new_frame.full_range = format_is_yuv(frame->format) - ? new_frame.full_range - : true; + new_frame.full_range = + format_is_yuv(frame->format) ? new_frame.full_range : true; obs_source_output_video_internal(source, &new_frame); } void obs_source_output_video2(obs_source_t *source, - const struct obs_source_frame2 *frame) + const struct obs_source_frame2 *frame) { if (!frame) { obs_source_output_video_internal(source, NULL); @@ -2468,8 +2739,8 @@ void obs_source_output_video2(obs_source_t *source, } struct obs_source_frame new_frame; - enum video_range_type range = resolve_video_range(frame->format, - frame->range); + enum video_range_type range = + resolve_video_range(frame->format, frame->range); for (size_t i = 0; i < MAX_AV_PLANES; i++) { new_frame.data[i] = frame->data[i]; @@ -2484,28 +2755,29 @@ void obs_source_output_video2(obs_source_t *source, new_frame.flip = frame->flip; memcpy(&new_frame.color_matrix, &frame->color_matrix, - sizeof(frame->color_matrix)); + sizeof(frame->color_matrix)); memcpy(&new_frame.color_range_min, &frame->color_range_min, - sizeof(frame->color_range_min)); + sizeof(frame->color_range_min)); memcpy(&new_frame.color_range_max, &frame->color_range_max, - sizeof(frame->color_range_max)); + sizeof(frame->color_range_max)); obs_source_output_video_internal(source, &new_frame); } static inline bool preload_frame_changed(obs_source_t *source, - const struct obs_source_frame *in) + const struct obs_source_frame *in) { if (!source->async_preload_frame) return true; - return in->width != source->async_preload_frame->width || + return in->width != source->async_preload_frame->width || in->height != source->async_preload_frame->height || in->format != source->async_preload_frame->format; } -static void obs_source_preload_video_internal(obs_source_t *source, - const struct obs_source_frame *frame) +static void +obs_source_preload_video_internal(obs_source_t *source, + const struct obs_source_frame *frame) { if (!obs_source_valid(source, "obs_source_preload_video")) return; @@ -2517,16 +2789,13 @@ static void obs_source_preload_video_internal(obs_source_t *source, if (preload_frame_changed(source, frame)) { obs_source_frame_destroy(source->async_preload_frame); source->async_preload_frame = obs_source_frame_create( - frame->format, - frame->width, - frame->height); + frame->format, frame->width, frame->height); } copy_frame_data(source->async_preload_frame, frame); set_async_texture_size(source, source->async_preload_frame); - update_async_texture(source, source->async_preload_frame, - source->async_texture, - source->async_texrender); + update_async_textures(source, source->async_preload_frame, + source->async_textures, source->async_texrender); source->last_frame_ts = frame->timestamp; @@ -2534,7 +2803,7 @@ static void obs_source_preload_video_internal(obs_source_t *source, } void obs_source_preload_video(obs_source_t *source, - const struct obs_source_frame *frame) + const struct obs_source_frame *frame) { if (!frame) { obs_source_preload_video_internal(source, NULL); @@ -2542,15 +2811,14 @@ void obs_source_preload_video(obs_source_t *source, } struct obs_source_frame new_frame = *frame; - new_frame.full_range = format_is_yuv(frame->format) - ? new_frame.full_range - : true; + new_frame.full_range = + format_is_yuv(frame->format) ? new_frame.full_range : true; obs_source_preload_video_internal(source, &new_frame); } void obs_source_preload_video2(obs_source_t *source, - const struct obs_source_frame2 *frame) + const struct obs_source_frame2 *frame) { if (!frame) { obs_source_preload_video_internal(source, NULL); @@ -2558,8 +2826,8 @@ void obs_source_preload_video2(obs_source_t *source, } struct obs_source_frame new_frame; - enum video_range_type range = resolve_video_range(frame->format, - frame->range); + enum video_range_type range = + resolve_video_range(frame->format, frame->range); for (size_t i = 0; i < MAX_AV_PLANES; i++) { new_frame.data[i] = frame->data[i]; @@ -2574,11 +2842,11 @@ void obs_source_preload_video2(obs_source_t *source, new_frame.flip = frame->flip; memcpy(&new_frame.color_matrix, &frame->color_matrix, - sizeof(frame->color_matrix)); + sizeof(frame->color_matrix)); memcpy(&new_frame.color_range_min, &frame->color_range_min, - sizeof(frame->color_range_min)); + sizeof(frame->color_range_min)); memcpy(&new_frame.color_range_max, &frame->color_range_max, - sizeof(frame->color_range_max)); + sizeof(frame->color_range_max)); obs_source_preload_video_internal(source, &new_frame); } @@ -2594,26 +2862,26 @@ void obs_source_show_preloaded_video(obs_source_t *source) pthread_mutex_lock(&source->audio_buf_mutex); sys_ts = (source->monitoring_type != OBS_MONITORING_TYPE_MONITOR_ONLY) - ? os_gettime_ns() - : 0; + ? os_gettime_ns() + : 0; reset_audio_timing(source, source->last_frame_ts, sys_ts); reset_audio_data(source, sys_ts); pthread_mutex_unlock(&source->audio_buf_mutex); } -static inline struct obs_audio_data *filter_async_audio(obs_source_t *source, - struct obs_audio_data *in) +static inline struct obs_audio_data * +filter_async_audio(obs_source_t *source, struct obs_audio_data *in) { size_t i; for (i = source->filters.num; i > 0; i--) { - struct obs_source *filter = source->filters.array[i-1]; + struct obs_source *filter = source->filters.array[i - 1]; if (!filter->enabled) continue; if (filter->context.data && filter->info.filter_audio) { in = filter->info.filter_audio(filter->context.data, - in); + in); if (!in) return NULL; } @@ -2623,49 +2891,49 @@ static inline struct obs_audio_data *filter_async_audio(obs_source_t *source, } static inline void reset_resampler(obs_source_t *source, - const struct obs_source_audio *audio) + const struct obs_source_audio *audio) { const struct audio_output_info *obs_info; struct resample_info output_info; obs_info = audio_output_get_info(obs->audio.audio); - output_info.format = obs_info->format; - output_info.samples_per_sec = obs_info->samples_per_sec; - output_info.speakers = obs_info->speakers; + output_info.format = obs_info->format; + output_info.samples_per_sec = obs_info->samples_per_sec; + output_info.speakers = obs_info->speakers; - source->sample_info.format = audio->format; + source->sample_info.format = audio->format; source->sample_info.samples_per_sec = audio->samples_per_sec; - source->sample_info.speakers = audio->speakers; + source->sample_info.speakers = audio->speakers; audio_resampler_destroy(source->resampler); source->resampler = NULL; source->resample_offset = 0; if (source->sample_info.samples_per_sec == obs_info->samples_per_sec && - source->sample_info.format == obs_info->format && - source->sample_info.speakers == obs_info->speakers) { + source->sample_info.format == obs_info->format && + source->sample_info.speakers == obs_info->speakers) { source->audio_failed = false; return; } - source->resampler = audio_resampler_create(&output_info, - &source->sample_info); + source->resampler = + audio_resampler_create(&output_info, &source->sample_info); source->audio_failed = source->resampler == NULL; if (source->resampler == NULL) blog(LOG_ERROR, "creation of resampler failed"); } -static void copy_audio_data(obs_source_t *source, - const uint8_t *const data[], uint32_t frames, uint64_t ts) +static void copy_audio_data(obs_source_t *source, const uint8_t *const data[], + uint32_t frames, uint64_t ts) { - size_t planes = audio_output_get_planes(obs->audio.audio); + size_t planes = audio_output_get_planes(obs->audio.audio); size_t blocksize = audio_output_get_block_size(obs->audio.audio); - size_t size = (size_t)frames * blocksize; - bool resize = source->audio_storage_size < size; + size_t size = (size_t)frames * blocksize; + bool resize = source->audio_storage_size < size; - source->audio_data.frames = frames; + source->audio_data.frames = frames; source->audio_data.timestamp = ts; for (size_t i = 0; i < planes; i++) { @@ -2687,7 +2955,7 @@ static void downmix_to_mono_planar(struct obs_source *source, uint32_t frames) { size_t channels = audio_output_get_channels(obs->audio.audio); const float channels_i = 1.0f / (float)channels; - float **data = (float**)source->audio_data.data; + float **data = (float **)source->audio_data.data; for (size_t channel = 1; channel < channels; channel++) { for (uint32_t frame = 0; frame < frames; frame++) @@ -2704,17 +2972,17 @@ static void downmix_to_mono_planar(struct obs_source *source, uint32_t frames) } static void process_audio_balancing(struct obs_source *source, uint32_t frames, - float balance, enum obs_balance_type type) + float balance, enum obs_balance_type type) { - float **data = (float**)source->audio_data.data; + float **data = (float **)source->audio_data.data; - switch(type) { + switch (type) { case OBS_BALANCE_TYPE_SINE_LAW: for (uint32_t frame = 0; frame < frames; frame++) { data[0][frame] = data[0][frame] * - sinf((1.0f - balance) * (M_PI/2.0f)); - data[1][frame] = data[1][frame] * - sinf(balance * (M_PI/2.0f)); + sinf((1.0f - balance) * (M_PI / 2.0f)); + data[1][frame] = + data[1][frame] * sinf(balance * (M_PI / 2.0f)); } break; case OBS_BALANCE_TYPE_SQUARE_LAW: @@ -2736,27 +3004,27 @@ static void process_audio_balancing(struct obs_source *source, uint32_t frames, /* resamples/remixes new audio to the designated main audio output format */ static void process_audio(obs_source_t *source, - const struct obs_source_audio *audio) + const struct obs_source_audio *audio) { uint32_t frames = audio->frames; bool mono_output; if (source->sample_info.samples_per_sec != audio->samples_per_sec || - source->sample_info.format != audio->format || - source->sample_info.speakers != audio->speakers) + source->sample_info.format != audio->format || + source->sample_info.speakers != audio->speakers) reset_resampler(source, audio); if (source->audio_failed) return; if (source->resampler) { - uint8_t *output[MAX_AV_PLANES]; + uint8_t *output[MAX_AV_PLANES]; memset(output, 0, sizeof(output)); - audio_resampler_resample(source->resampler, - output, &frames, &source->resample_offset, - audio->data, audio->frames); + audio_resampler_resample(source->resampler, output, &frames, + &source->resample_offset, audio->data, + audio->frames); copy_audio_data(source, (const uint8_t *const *)output, frames, audio->timestamp); @@ -2770,7 +3038,7 @@ static void process_audio(obs_source_t *source, if (!mono_output && source->sample_info.speakers == SPEAKERS_STEREO && (source->balance > 0.51f || source->balance < 0.49f)) { process_audio_balancing(source, frames, source->balance, - OBS_BALANCE_TYPE_SINE_LAW); + OBS_BALANCE_TYPE_SINE_LAW); } if (!mono_output && (source->flags & OBS_SOURCE_FLAG_FORCE_MONO) != 0) @@ -2778,7 +3046,7 @@ static void process_audio(obs_source_t *source, } void obs_source_output_audio(obs_source_t *source, - const struct obs_source_audio *audio) + const struct obs_source_audio *audio) { struct obs_audio_data *output; @@ -2798,7 +3066,7 @@ void obs_source_output_audio(obs_source_t *source, for (int i = 0; i < MAX_AV_PLANES; i++) data.data[i] = output->data[i]; - data.frames = output->frames; + data.frames = output->frames; data.timestamp = output->timestamp; pthread_mutex_lock(&source->audio_mutex); @@ -2829,7 +3097,7 @@ void remove_async_frame(obs_source_t *source, struct obs_source_frame *frame) static bool ready_async_frame(obs_source_t *source, uint64_t sys_time) { struct obs_source_frame *next_frame = source->async_frames.array[0]; - struct obs_source_frame *frame = NULL; + struct obs_source_frame *frame = NULL; uint64_t sys_offset = sys_time - source->last_sys_timestamp; uint64_t frame_time = next_frame->timestamp; uint64_t frame_offset = 0; @@ -2846,12 +3114,13 @@ static bool ready_async_frame(obs_source_t *source, uint64_t sys_time) } #if DEBUG_ASYNC_FRAMES - blog(LOG_DEBUG, "source->last_frame_ts: %llu, frame_time: %llu, " - "sys_offset: %llu, frame_offset: %llu, " - "number of frames: %lu", - source->last_frame_ts, frame_time, sys_offset, - frame_time - source->last_frame_ts, - (unsigned long)source->async_frames.num); + blog(LOG_DEBUG, + "source->last_frame_ts: %llu, frame_time: %llu, " + "sys_offset: %llu, frame_offset: %llu, " + "number of frames: %lu", + source->last_frame_ts, frame_time, sys_offset, + frame_time - source->last_frame_ts, + (unsigned long)source->async_frames.num); #endif /* account for timestamp invalidation */ @@ -2879,11 +3148,11 @@ static bool ready_async_frame(obs_source_t *source, uint64_t sys_time) da_erase(source->async_frames, 0); #if DEBUG_ASYNC_FRAMES - blog(LOG_DEBUG, "new frame, " - "source->last_frame_ts: %llu, " - "next_frame->timestamp: %llu", - source->last_frame_ts, - next_frame->timestamp); + blog(LOG_DEBUG, + "new frame, " + "source->last_frame_ts: %llu, " + "next_frame->timestamp: %llu", + source->last_frame_ts, next_frame->timestamp); #endif remove_async_frame(source, frame); @@ -2903,7 +3172,7 @@ static bool ready_async_frame(obs_source_t *source, uint64_t sys_time) next_frame->timestamp - frame_offset; } - frame_time = next_frame->timestamp; + frame_time = next_frame->timestamp; frame_offset = frame_time - source->last_frame_ts; } @@ -2916,7 +3185,7 @@ static bool ready_async_frame(obs_source_t *source, uint64_t sys_time) } static inline struct obs_source_frame *get_closest_frame(obs_source_t *source, - uint64_t sys_time) + uint64_t sys_time) { if (!source->async_frames.num) return NULL; @@ -2962,7 +3231,7 @@ struct obs_source_frame *obs_source_get_frame(obs_source_t *source) } void obs_source_release_frame(obs_source_t *source, - struct obs_source_frame *frame) + struct obs_source_frame *frame) { if (!frame) return; @@ -2983,8 +3252,9 @@ void obs_source_release_frame(obs_source_t *source, const char *obs_source_get_name(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_get_name") ? - source->context.name : NULL; + return obs_source_valid(source, "obs_source_get_name") + ? source->context.name + : NULL; } void obs_source_set_name(obs_source_t *source, const char *name) @@ -2993,7 +3263,7 @@ void obs_source_set_name(obs_source_t *source, const char *name) return; if (!name || !*name || !source->context.name || - strcmp(name, source->context.name) != 0) { + strcmp(name, source->context.name) != 0) { struct calldata data; char *prev_name = bstrdup(source->context.name); obs_context_data_setname(&source->context, name); @@ -3004,7 +3274,7 @@ void obs_source_set_name(obs_source_t *source, const char *name) calldata_set_string(&data, "prev_name", prev_name); if (!source->context.private) signal_handler_signal(obs->signals, "source_rename", - &data); + &data); signal_handler_signal(source->context.signals, "rename", &data); calldata_free(&data); bfree(prev_name); @@ -3013,21 +3283,23 @@ void obs_source_set_name(obs_source_t *source, const char *name) enum obs_source_type obs_source_get_type(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_get_type") ? - source->info.type : OBS_SOURCE_TYPE_INPUT; + return obs_source_valid(source, "obs_source_get_type") + ? source->info.type + : OBS_SOURCE_TYPE_INPUT; } const char *obs_source_get_id(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_get_id") ? - source->info.id : NULL; + return obs_source_valid(source, "obs_source_get_id") ? source->info.id + : NULL; } static inline void render_filter_bypass(obs_source_t *target, - gs_effect_t *effect, const char *tech_name) + gs_effect_t *effect, + const char *tech_name) { - gs_technique_t *tech = gs_effect_get_technique(effect, tech_name); - size_t passes, i; + gs_technique_t *tech = gs_effect_get_technique(effect, tech_name); + size_t passes, i; passes = gs_technique_begin(tech); for (i = 0; i < passes; i++) { @@ -3039,11 +3311,12 @@ static inline void render_filter_bypass(obs_source_t *target, } static inline void render_filter_tex(gs_texture_t *tex, gs_effect_t *effect, - uint32_t width, uint32_t height, const char *tech_name) + uint32_t width, uint32_t height, + const char *tech_name) { - gs_technique_t *tech = gs_effect_get_technique(effect, tech_name); - gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); - size_t passes, i; + gs_technique_t *tech = gs_effect_get_technique(effect, tech_name); + gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); + size_t passes, i; gs_effect_set_texture(image, tex); @@ -3057,43 +3330,43 @@ static inline void render_filter_tex(gs_texture_t *tex, gs_effect_t *effect, } static inline bool can_bypass(obs_source_t *target, obs_source_t *parent, - uint32_t parent_flags, - enum obs_allow_direct_render allow_direct) + uint32_t parent_flags, + enum obs_allow_direct_render allow_direct) { return (target == parent) && - (allow_direct == OBS_ALLOW_DIRECT_RENDERING) && - ((parent_flags & OBS_SOURCE_CUSTOM_DRAW) == 0) && - ((parent_flags & OBS_SOURCE_ASYNC) == 0); + (allow_direct == OBS_ALLOW_DIRECT_RENDERING) && + ((parent_flags & OBS_SOURCE_CUSTOM_DRAW) == 0) && + ((parent_flags & OBS_SOURCE_ASYNC) == 0); } bool obs_source_process_filter_begin(obs_source_t *filter, - enum gs_color_format format, - enum obs_allow_direct_render allow_direct) + enum gs_color_format format, + enum obs_allow_direct_render allow_direct) { obs_source_t *target, *parent; - uint32_t parent_flags; - int cx, cy; + uint32_t parent_flags; + int cx, cy; if (!obs_ptr_valid(filter, "obs_source_process_filter_begin")) return false; - target = obs_filter_get_target(filter); - parent = obs_filter_get_parent(filter); + target = obs_filter_get_target(filter); + parent = obs_filter_get_parent(filter); if (!target) { blog(LOG_INFO, "filter '%s' being processed with no target!", - filter->context.name); + filter->context.name); return false; } if (!parent) { blog(LOG_INFO, "filter '%s' being processed with no parent!", - filter->context.name); + filter->context.name); return false; } parent_flags = parent->info.output_flags; - cx = get_base_width(target); - cy = get_base_height(target); + cx = get_base_width(target); + cy = get_base_height(target); filter->allow_direct = allow_direct; @@ -3111,8 +3384,8 @@ bool obs_source_process_filter_begin(obs_source_t *filter, } if (!filter->filter_texrender) - filter->filter_texrender = gs_texrender_create(format, - GS_ZS_NONE); + filter->filter_texrender = + gs_texrender_create(format, GS_ZS_NONE); gs_blend_state_push(); gs_blend_function(GS_BLEND_ONE, GS_BLEND_ZERO); @@ -3138,17 +3411,19 @@ bool obs_source_process_filter_begin(obs_source_t *filter, return true; } -void obs_source_process_filter_tech_end(obs_source_t *filter, gs_effect_t *effect, - uint32_t width, uint32_t height, const char *tech_name) +void obs_source_process_filter_tech_end(obs_source_t *filter, + gs_effect_t *effect, uint32_t width, + uint32_t height, const char *tech_name) { obs_source_t *target, *parent; gs_texture_t *texture; - uint32_t parent_flags; + uint32_t parent_flags; - if (!filter) return; + if (!filter) + return; - target = obs_filter_get_target(filter); - parent = obs_filter_get_parent(filter); + target = obs_filter_get_target(filter); + parent = obs_filter_get_parent(filter); if (!target || !parent) return; @@ -3161,33 +3436,20 @@ void obs_source_process_filter_tech_end(obs_source_t *filter, gs_effect_t *effec render_filter_bypass(target, effect, tech); } else { texture = gs_texrender_get_texture(filter->filter_texrender); - render_filter_tex(texture, effect, width, height, tech); + if (texture) { + render_filter_tex(texture, effect, width, height, tech); + } } } - void obs_source_process_filter_end(obs_source_t *filter, gs_effect_t *effect, - uint32_t width, uint32_t height) + uint32_t width, uint32_t height) { - obs_source_t *target, *parent; - gs_texture_t *texture; - uint32_t parent_flags; - if (!obs_ptr_valid(filter, "obs_source_process_filter_end")) return; - target = obs_filter_get_target(filter); - parent = obs_filter_get_parent(filter); - parent_flags = parent->info.output_flags; - - if (can_bypass(target, parent, parent_flags, filter->allow_direct)) { - render_filter_bypass(target, effect, "Draw"); - } else { - texture = gs_texrender_get_texture(filter->filter_texrender); - if (texture) - render_filter_tex(texture, effect, width, height, - "Draw"); - } + obs_source_process_filter_tech_end(filter, effect, width, height, + "Draw"); } void obs_source_skip_video_filter(obs_source_t *filter) @@ -3222,24 +3484,24 @@ void obs_source_skip_video_filter(obs_source_t *filter) signal_handler_t *obs_source_get_signal_handler(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_get_signal_handler") ? - source->context.signals : NULL; + return obs_source_valid(source, "obs_source_get_signal_handler") + ? source->context.signals + : NULL; } proc_handler_t *obs_source_get_proc_handler(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_get_proc_handler") ? - source->context.procs : NULL; + return obs_source_valid(source, "obs_source_get_proc_handler") + ? source->context.procs + : NULL; } void obs_source_set_volume(obs_source_t *source, float volume) { if (obs_source_valid(source, "obs_source_set_volume")) { - struct audio_action action = { - .timestamp = os_gettime_ns(), - .type = AUDIO_ACTION_VOL, - .vol = volume - }; + struct audio_action action = {.timestamp = os_gettime_ns(), + .type = AUDIO_ACTION_VOL, + .vol = volume}; struct calldata data; uint8_t stack[128]; @@ -3251,7 +3513,7 @@ void obs_source_set_volume(obs_source_t *source, float volume) signal_handler_signal(source->context.signals, "volume", &data); if (!source->context.private) signal_handler_signal(obs->signals, "source_volume", - &data); + &data); volume = (float)calldata_float(&data, "volume"); @@ -3265,8 +3527,9 @@ void obs_source_set_volume(obs_source_t *source, float volume) float obs_source_get_volume(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_get_volume") ? - source->user_volume : 0.0f; + return obs_source_valid(source, "obs_source_get_volume") + ? source->user_volume + : 0.0f; } void obs_source_set_sync_offset(obs_source_t *source, int64_t offset) @@ -3280,7 +3543,7 @@ void obs_source_set_sync_offset(obs_source_t *source, int64_t offset) calldata_set_int(&data, "offset", offset); signal_handler_signal(source->context.signals, "audio_sync", - &data); + &data); source->sync_offset = calldata_int(&data, "offset"); } @@ -3288,8 +3551,9 @@ void obs_source_set_sync_offset(obs_source_t *source, int64_t offset) int64_t obs_source_get_sync_offset(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_get_sync_offset") ? - source->sync_offset : 0; + return obs_source_valid(source, "obs_source_get_sync_offset") + ? source->sync_offset + : 0; } struct source_enum_data { @@ -3298,18 +3562,19 @@ struct source_enum_data { }; static void enum_source_active_tree_callback(obs_source_t *parent, - obs_source_t *child, void *param) + obs_source_t *child, void *param) { struct source_enum_data *data = param; bool is_transition = child->info.type == OBS_SOURCE_TYPE_TRANSITION; if (is_transition) - obs_transition_enum_sources(child, - enum_source_active_tree_callback, param); + obs_transition_enum_sources( + child, enum_source_active_tree_callback, param); if (child->info.enum_active_sources) { if (child->context.data) { - child->info.enum_active_sources(child->context.data, - enum_source_active_tree_callback, data); + child->info.enum_active_sources( + child->context.data, + enum_source_active_tree_callback, data); } } @@ -3317,8 +3582,8 @@ static void enum_source_active_tree_callback(obs_source_t *parent, } void obs_source_enum_active_sources(obs_source_t *source, - obs_source_enum_proc_t enum_callback, - void *param) + obs_source_enum_proc_t enum_callback, + void *param) { bool is_transition; if (!data_valid(source, "obs_source_enum_active_sources")) @@ -3334,14 +3599,14 @@ void obs_source_enum_active_sources(obs_source_t *source, obs_transition_enum_sources(source, enum_callback, param); if (source->info.enum_active_sources) source->info.enum_active_sources(source->context.data, - enum_callback, param); + enum_callback, param); obs_source_release(source); } void obs_source_enum_active_tree(obs_source_t *source, - obs_source_enum_proc_t enum_callback, - void *param) + obs_source_enum_proc_t enum_callback, + void *param) { struct source_enum_data data = {enum_callback, param}; bool is_transition; @@ -3356,33 +3621,36 @@ void obs_source_enum_active_tree(obs_source_t *source, obs_source_addref(source); if (source->info.type == OBS_SOURCE_TYPE_TRANSITION) - obs_transition_enum_sources(source, - enum_source_active_tree_callback, &data); + obs_transition_enum_sources( + source, enum_source_active_tree_callback, &data); if (source->info.enum_active_sources) - source->info.enum_active_sources(source->context.data, - enum_source_active_tree_callback, &data); + source->info.enum_active_sources( + source->context.data, enum_source_active_tree_callback, + &data); obs_source_release(source); } static void enum_source_full_tree_callback(obs_source_t *parent, - obs_source_t *child, void *param) + obs_source_t *child, void *param) { struct source_enum_data *data = param; bool is_transition = child->info.type == OBS_SOURCE_TYPE_TRANSITION; if (is_transition) - obs_transition_enum_sources(child, - enum_source_full_tree_callback, param); + obs_transition_enum_sources( + child, enum_source_full_tree_callback, param); if (child->info.enum_all_sources) { if (child->context.data) { - child->info.enum_active_sources(child->context.data, - enum_source_full_tree_callback, data); + child->info.enum_active_sources( + child->context.data, + enum_source_full_tree_callback, data); } } else if (child->info.enum_active_sources) { if (child->context.data) { - child->info.enum_active_sources(child->context.data, - enum_source_full_tree_callback, data); + child->info.enum_active_sources( + child->context.data, + enum_source_full_tree_callback, data); } } @@ -3390,8 +3658,8 @@ static void enum_source_full_tree_callback(obs_source_t *parent, } static void obs_source_enum_full_tree(obs_source_t *source, - obs_source_enum_proc_t enum_callback, - void *param) + obs_source_enum_proc_t enum_callback, + void *param) { struct source_enum_data data = {enum_callback, param}; bool is_transition; @@ -3406,16 +3674,18 @@ static void obs_source_enum_full_tree(obs_source_t *source, obs_source_addref(source); if (source->info.type == OBS_SOURCE_TYPE_TRANSITION) - obs_transition_enum_sources(source, - enum_source_full_tree_callback, &data); + obs_transition_enum_sources( + source, enum_source_full_tree_callback, &data); if (source->info.enum_all_sources) { source->info.enum_all_sources(source->context.data, - enum_source_full_tree_callback, &data); + enum_source_full_tree_callback, + &data); } else if (source->info.enum_active_sources) { source->info.enum_active_sources(source->context.data, - enum_source_full_tree_callback, &data); + enum_source_full_tree_callback, + &data); } obs_source_release(source); @@ -3427,7 +3697,7 @@ struct descendant_info { }; static void check_descendant(obs_source_t *parent, obs_source_t *child, - void *param) + void *param) { struct descendant_info *info = param; if (child == info->target || parent == info->target) @@ -3444,7 +3714,7 @@ bool obs_source_add_active_child(obs_source_t *parent, obs_source_t *child) return false; if (parent == child) { blog(LOG_WARNING, "obs_source_add_active_child: " - "parent == child"); + "parent == child"); return false; } @@ -3484,7 +3754,7 @@ void obs_source_save(obs_source_t *source) if (source->info.save) source->info.save(source->context.data, - source->context.settings); + source->context.settings); } void obs_source_load(obs_source_t *source) @@ -3493,21 +3763,23 @@ void obs_source_load(obs_source_t *source) return; if (source->info.load) source->info.load(source->context.data, - source->context.settings); + source->context.settings); obs_source_dosignal(source, "source_load", "load"); } bool obs_source_active(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_active") ? - source->activate_refs != 0 : false; + return obs_source_valid(source, "obs_source_active") + ? source->activate_refs != 0 + : false; } bool obs_source_showing(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_showing") ? - source->show_refs != 0 : false; + return obs_source_valid(source, "obs_source_showing") + ? source->show_refs != 0 + : false; } static inline void signal_flags_updated(obs_source_t *source) @@ -3543,8 +3815,8 @@ void obs_source_set_default_flags(obs_source_t *source, uint32_t flags) uint32_t obs_source_get_flags(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_get_flags") ? - source->flags : 0; + return obs_source_valid(source, "obs_source_get_flags") ? source->flags + : 0; } void obs_source_set_audio_mixers(obs_source_t *source, uint32_t mixers) @@ -3582,8 +3854,8 @@ uint32_t obs_source_get_audio_mixers(const obs_source_t *source) } void obs_source_draw_set_color_matrix(const struct matrix4 *color_matrix, - const struct vec3 *color_range_min, - const struct vec3 *color_range_max) + const struct vec3 *color_range_min, + const struct vec3 *color_range_max) { struct vec3 color_range_min_def; struct vec3 color_range_max_def; @@ -3598,7 +3870,7 @@ void obs_source_draw_set_color_matrix(const struct matrix4 *color_matrix, if (!effect) { blog(LOG_WARNING, "obs_source_draw_set_color_matrix: no " - "active effect!"); + "active effect!"); return; } @@ -3615,12 +3887,12 @@ void obs_source_draw_set_color_matrix(const struct matrix4 *color_matrix, range_max = gs_effect_get_param_by_name(effect, "color_range_max"); gs_effect_set_matrix4(matrix, color_matrix); - gs_effect_set_val(range_min, color_range_min, sizeof(float)*3); - gs_effect_set_val(range_max, color_range_max, sizeof(float)*3); + gs_effect_set_val(range_min, color_range_min, sizeof(float) * 3); + gs_effect_set_val(range_max, color_range_max, sizeof(float) * 3); } void obs_source_draw(gs_texture_t *texture, int x, int y, uint32_t cx, - uint32_t cy, bool flip) + uint32_t cy, bool flip) { gs_effect_t *effect = gs_get_effect(); bool change_pos = (x != 0 || y != 0); @@ -3672,9 +3944,8 @@ void obs_source_dec_active(obs_source_t *source) obs_source_deactivate(source, MAIN_VIEW); } - void obs_source_enum_filters(obs_source_t *source, - obs_source_enum_proc_t callback, void *param) + obs_source_enum_proc_t callback, void *param) { if (!obs_source_valid(source, "obs_source_enum_filters")) return; @@ -3692,7 +3963,7 @@ void obs_source_enum_filters(obs_source_t *source, } obs_source_t *obs_source_get_filter_by_name(obs_source_t *source, - const char *name) + const char *name) { obs_source_t *filter = NULL; @@ -3719,8 +3990,8 @@ obs_source_t *obs_source_get_filter_by_name(obs_source_t *source, bool obs_source_enabled(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_enabled") ? - source->enabled : false; + return obs_source_valid(source, "obs_source_enabled") ? source->enabled + : false; } void obs_source_set_enabled(obs_source_t *source, bool enabled) @@ -3742,19 +4013,17 @@ void obs_source_set_enabled(obs_source_t *source, bool enabled) bool obs_source_muted(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_muted") ? - source->user_muted : false; + return obs_source_valid(source, "obs_source_muted") ? source->user_muted + : false; } void obs_source_set_muted(obs_source_t *source, bool muted) { struct calldata data; uint8_t stack[128]; - struct audio_action action = { - .timestamp = os_gettime_ns(), - .type = AUDIO_ACTION_MUTE, - .set = muted - }; + struct audio_action action = {.timestamp = os_gettime_ns(), + .type = AUDIO_ACTION_MUTE, + .set = muted}; if (!obs_source_valid(source, "obs_source_set_muted")) return; @@ -3773,27 +4042,27 @@ void obs_source_set_muted(obs_source_t *source, bool muted) } static void source_signal_push_to_changed(obs_source_t *source, - const char *signal, bool enabled) + const char *signal, bool enabled) { struct calldata data; uint8_t stack[128]; calldata_init_fixed(&data, stack, sizeof(stack)); - calldata_set_ptr (&data, "source", source); + calldata_set_ptr(&data, "source", source); calldata_set_bool(&data, "enabled", enabled); signal_handler_signal(source->context.signals, signal, &data); } static void source_signal_push_to_delay(obs_source_t *source, - const char *signal, uint64_t delay) + const char *signal, uint64_t delay) { struct calldata data; uint8_t stack[128]; calldata_init_fixed(&data, stack, sizeof(stack)); - calldata_set_ptr (&data, "source", source); - calldata_set_bool(&data, "delay", delay); + calldata_set_ptr(&data, "source", source); + calldata_set_bool(&data, "delay", delay); signal_handler_signal(source->context.signals, signal, &data); } @@ -3820,14 +4089,14 @@ void obs_source_enable_push_to_mute(obs_source_t *source, bool enabled) bool changed = source->push_to_mute_enabled != enabled; if (obs_source_get_output_flags(source) & OBS_SOURCE_AUDIO && changed) blog(LOG_INFO, "source '%s' %s push-to-mute", - obs_source_get_name(source), - enabled ? "enabled" : "disabled"); + obs_source_get_name(source), + enabled ? "enabled" : "disabled"); source->push_to_mute_enabled = enabled; if (changed) source_signal_push_to_changed(source, "push_to_mute_changed", - enabled); + enabled); pthread_mutex_unlock(&source->audio_mutex); } @@ -3878,14 +4147,14 @@ void obs_source_enable_push_to_talk(obs_source_t *source, bool enabled) bool changed = source->push_to_talk_enabled != enabled; if (obs_source_get_output_flags(source) & OBS_SOURCE_AUDIO && changed) blog(LOG_INFO, "source '%s' %s push-to-talk", - obs_source_get_name(source), - enabled ? "enabled" : "disabled"); + obs_source_get_name(source), + enabled ? "enabled" : "disabled"); source->push_to_talk_enabled = enabled; if (changed) source_signal_push_to_changed(source, "push_to_talk_changed", - enabled); + enabled); pthread_mutex_unlock(&source->audio_mutex); } @@ -3917,27 +4186,28 @@ void obs_source_set_push_to_talk_delay(obs_source_t *source, uint64_t delay) void *obs_source_get_type_data(obs_source_t *source) { return obs_source_valid(source, "obs_source_get_type_data") - ? source->info.type_data : NULL; + ? source->info.type_data + : NULL; } static float get_source_volume(obs_source_t *source, uint64_t os_time) { if (source->push_to_mute_enabled && source->push_to_mute_pressed) - source->push_to_mute_stop_time = os_time + - source->push_to_mute_delay * 1000000; + source->push_to_mute_stop_time = + os_time + source->push_to_mute_delay * 1000000; if (source->push_to_talk_enabled && source->push_to_talk_pressed) - source->push_to_talk_stop_time = os_time + - source->push_to_talk_delay * 1000000; + source->push_to_talk_stop_time = + os_time + source->push_to_talk_delay * 1000000; bool push_to_mute_active = source->push_to_mute_pressed || - os_time < source->push_to_mute_stop_time; + os_time < source->push_to_mute_stop_time; bool push_to_talk_active = source->push_to_talk_pressed || - os_time < source->push_to_talk_stop_time; + os_time < source->push_to_talk_stop_time; bool muted = !source->enabled || source->muted || - (source->push_to_mute_enabled && push_to_mute_active) || - (source->push_to_talk_enabled && !push_to_talk_active); + (source->push_to_mute_enabled && push_to_mute_active) || + (source->push_to_talk_enabled && !push_to_talk_active); if (muted || close_float(source->volume, 0.0f, 0.0001f)) return 0.0f; @@ -3948,7 +4218,7 @@ static float get_source_volume(obs_source_t *source, uint64_t os_time) } static inline void multiply_output_audio(obs_source_t *source, size_t mix, - size_t channels, float vol) + size_t channels, float vol) { register float *out = source->audio_output_buf[mix][0]; register float *end = out + AUDIO_OUTPUT_FRAMES * channels; @@ -3958,7 +4228,7 @@ static inline void multiply_output_audio(obs_source_t *source, size_t mix, } static inline void multiply_vol_data(obs_source_t *source, size_t mix, - size_t channels, float *vol_data) + size_t channels, float *vol_data) { for (size_t ch = 0; ch < channels; ch++) { register float *out = source->audio_output_buf[mix][ch]; @@ -3971,22 +4241,26 @@ static inline void multiply_vol_data(obs_source_t *source, size_t mix, } static inline void apply_audio_action(obs_source_t *source, - const struct audio_action *action) + const struct audio_action *action) { switch (action->type) { case AUDIO_ACTION_VOL: - source->volume = action->vol; break; + source->volume = action->vol; + break; case AUDIO_ACTION_MUTE: - source->muted = action->set; break; + source->muted = action->set; + break; case AUDIO_ACTION_PTT: - source->push_to_talk_pressed = action->set; break; + source->push_to_talk_pressed = action->set; + break; case AUDIO_ACTION_PTM: - source->push_to_mute_pressed = action->set; break; + source->push_to_mute_pressed = action->set; + break; } } static void apply_audio_actions(obs_source_t *source, size_t channels, - size_t sample_rate) + size_t sample_rate) { float *vol_data = malloc(sizeof(float) * AUDIO_OUTPUT_FRAMES); float cur_vol = get_source_volume(source, source->audio_ts); @@ -4002,8 +4276,8 @@ static void apply_audio_actions(obs_source_t *source, size_t channels, if (timestamp < source->audio_ts) timestamp = source->audio_ts; - new_frame_num = conv_time_to_frames(sample_rate, - timestamp - source->audio_ts); + new_frame_num = conv_time_to_frames( + sample_rate, timestamp - source->audio_ts); if (new_frame_num >= AUDIO_OUTPUT_FRAMES) break; @@ -4034,7 +4308,7 @@ static void apply_audio_actions(obs_source_t *source, size_t channels, } static void apply_audio_volume(obs_source_t *source, uint32_t mixers, - size_t channels, size_t sample_rate) + size_t channels, size_t sample_rate) { struct audio_action action; bool actions_pending; @@ -4049,8 +4323,8 @@ static void apply_audio_volume(obs_source_t *source, uint32_t mixers, pthread_mutex_unlock(&source->audio_actions_mutex); if (actions_pending) { - uint64_t duration = conv_frames_to_time(sample_rate, - AUDIO_OUTPUT_FRAMES); + uint64_t duration = + conv_frames_to_time(sample_rate, AUDIO_OUTPUT_FRAMES); if (action.timestamp < (source->audio_ts + duration)) { apply_audio_actions(source, channels, sample_rate); @@ -4064,8 +4338,8 @@ static void apply_audio_volume(obs_source_t *source, uint32_t mixers, if (vol == 0.0f || mixers == 0) { memset(source->audio_output_buf[0][0], 0, - AUDIO_OUTPUT_FRAMES * sizeof(float) * - MAX_AUDIO_CHANNELS * MAX_AUDIO_MIXES); + AUDIO_OUTPUT_FRAMES * sizeof(float) * + MAX_AUDIO_CHANNELS * MAX_AUDIO_MIXES); return; } @@ -4078,7 +4352,7 @@ static void apply_audio_volume(obs_source_t *source, uint32_t mixers, } static void custom_audio_render(obs_source_t *source, uint32_t mixers, - size_t channels, size_t sample_rate) + size_t channels, size_t sample_rate) { struct obs_source_audio_mix audio_data; bool success; @@ -4092,13 +4366,13 @@ static void custom_audio_render(obs_source_t *source, uint32_t mixers, if ((source->audio_mixers & mixers & (1 << mix)) != 0) { memset(source->audio_output_buf[mix][0], 0, - sizeof(float) * AUDIO_OUTPUT_FRAMES * - channels); + sizeof(float) * AUDIO_OUTPUT_FRAMES * channels); } } success = source->info.audio_render(source->context.data, &ts, - &audio_data, mixers, channels, sample_rate); + &audio_data, mixers, channels, + sample_rate); source->audio_ts = success ? ts : 0; source->audio_pending = !success; @@ -4113,18 +4387,52 @@ static void custom_audio_render(obs_source_t *source, uint32_t mixers, if ((source->audio_mixers & mix_bit) == 0) { memset(source->audio_output_buf[mix][0], 0, - sizeof(float) * AUDIO_OUTPUT_FRAMES * - channels); + sizeof(float) * AUDIO_OUTPUT_FRAMES * channels); } } apply_audio_volume(source, mixers, channels, sample_rate); } -static inline void process_audio_source_tick(obs_source_t *source, - uint32_t mixers, size_t channels, size_t sample_rate, - size_t size) +static void audio_submix(obs_source_t *source, size_t channels, + size_t sample_rate) { + struct audio_output_data audio_data; + struct obs_source_audio audio = {0}; + bool success; + uint64_t ts; + + for (size_t ch = 0; ch < channels; ch++) { + audio_data.data[ch] = source->audio_mix_buf[ch]; + } + + memset(source->audio_mix_buf[0], 0, + sizeof(float) * AUDIO_OUTPUT_FRAMES * channels); + + success = source->info.audio_mix(source->context.data, &ts, &audio_data, + channels, sample_rate); + + if (!success) + return; + + for (size_t i = 0; i < channels; i++) + audio.data[i] = (const uint8_t *)audio_data.data[i]; + + audio.samples_per_sec = (uint32_t)sample_rate; + audio.frames = AUDIO_OUTPUT_FRAMES; + audio.format = AUDIO_FORMAT_FLOAT_PLANAR; + audio.speakers = (enum speaker_layout)channels; + audio.timestamp = ts; + + obs_source_output_audio(source, &audio); +} + +static inline void process_audio_source_tick(obs_source_t *source, + uint32_t mixers, size_t channels, + size_t sample_rate, size_t size) +{ + bool audio_submix = !!(source->info.output_flags & OBS_SOURCE_SUBMIX); + pthread_mutex_lock(&source->audio_buf_mutex); if (source->audio_input_buf[0].size < size) { @@ -4135,36 +4443,47 @@ static inline void process_audio_source_tick(obs_source_t *source, for (size_t ch = 0; ch < channels; ch++) circlebuf_peek_front(&source->audio_input_buf[ch], - source->audio_output_buf[0][ch], - size); + source->audio_output_buf[0][ch], size); pthread_mutex_unlock(&source->audio_buf_mutex); for (size_t mix = 1; mix < MAX_AUDIO_MIXES; mix++) { uint32_t mix_and_val = (1 << mix); + if (audio_submix) { + if (mix > 1) + break; + + mixers = 1; + mix_and_val = 1; + } + if ((source->audio_mixers & mix_and_val) == 0 || (mixers & mix_and_val) == 0) { - memset(source->audio_output_buf[mix][0], - 0, size * channels); + memset(source->audio_output_buf[mix][0], 0, + size * channels); continue; } for (size_t ch = 0; ch < channels; ch++) memcpy(source->audio_output_buf[mix][ch], - source->audio_output_buf[0][ch], size); + source->audio_output_buf[0][ch], size); + } + + if (audio_submix) { + source->audio_pending = false; + return; } if ((source->audio_mixers & 1) == 0 || (mixers & 1) == 0) - memset(source->audio_output_buf[0][0], 0, - size * channels); + memset(source->audio_output_buf[0][0], 0, size * channels); apply_audio_volume(source, mixers, channels, sample_rate); source->audio_pending = false; } void obs_source_audio_render(obs_source_t *source, uint32_t mixers, - size_t channels, size_t sample_rate, size_t size) + size_t channels, size_t sample_rate, size_t size) { if (!source->audio_output_buf[0][0]) { source->audio_pending = true; @@ -4176,6 +4495,10 @@ void obs_source_audio_render(obs_source_t *source, uint32_t mixers, return; } + if (source->info.audio_mix) { + audio_submix(source, channels, sample_rate); + } + if (!source->audio_ts) { source->audio_pending = true; return; @@ -4189,18 +4512,20 @@ bool obs_source_audio_pending(const obs_source_t *source) if (!obs_source_valid(source, "obs_source_audio_pending")) return true; - return (is_composite_source(source) || is_audio_source(source)) ? - source->audio_pending : true; + return (is_composite_source(source) || is_audio_source(source)) + ? source->audio_pending + : true; } uint64_t obs_source_get_audio_timestamp(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_get_audio_timestamp") ? - source->audio_ts : 0; + return obs_source_valid(source, "obs_source_get_audio_timestamp") + ? source->audio_ts + : 0; } void obs_source_get_audio_mix(const obs_source_t *source, - struct obs_source_audio_mix *audio) + struct obs_source_audio_mix *audio) { if (!obs_source_valid(source, "obs_source_get_audio_mix")) return; @@ -4216,7 +4541,8 @@ void obs_source_get_audio_mix(const obs_source_t *source, } void obs_source_add_audio_capture_callback(obs_source_t *source, - obs_source_audio_capture_t callback, void *param) + obs_source_audio_capture_t callback, + void *param) { struct audio_cb_info info = {callback, param}; @@ -4228,12 +4554,13 @@ void obs_source_add_audio_capture_callback(obs_source_t *source, pthread_mutex_unlock(&source->audio_cb_mutex); } -void obs_source_remove_audio_capture_callback(obs_source_t *source, - obs_source_audio_capture_t callback, void *param) +void obs_source_remove_audio_capture_callback( + obs_source_t *source, obs_source_audio_capture_t callback, void *param) { struct audio_cb_info info = {callback, param}; - if (!obs_source_valid(source, "obs_source_remove_audio_capture_callback")) + if (!obs_source_valid(source, + "obs_source_remove_audio_capture_callback")) return; pthread_mutex_lock(&source->audio_cb_mutex); @@ -4242,7 +4569,7 @@ void obs_source_remove_audio_capture_callback(obs_source_t *source, } void obs_source_set_monitoring_type(obs_source_t *source, - enum obs_monitoring_type type) + enum obs_monitoring_type type) { bool was_on; bool now_on; @@ -4267,11 +4594,12 @@ void obs_source_set_monitoring_type(obs_source_t *source, source->monitoring_type = type; } -enum obs_monitoring_type obs_source_get_monitoring_type( - const obs_source_t *source) +enum obs_monitoring_type +obs_source_get_monitoring_type(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_get_monitoring_type") ? - source->monitoring_type : OBS_MONITORING_TYPE_NONE; + return obs_source_valid(source, "obs_source_get_monitoring_type") + ? source->monitoring_type + : OBS_MONITORING_TYPE_NONE; } void obs_source_set_async_unbuffered(obs_source_t *source, bool unbuffered) @@ -4284,8 +4612,9 @@ void obs_source_set_async_unbuffered(obs_source_t *source, bool unbuffered) bool obs_source_async_unbuffered(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_async_unbuffered") ? - source->async_unbuffered : false; + return obs_source_valid(source, "obs_source_async_unbuffered") + ? source->async_unbuffered + : false; } obs_data_t *obs_source_get_private_settings(obs_source_t *source) @@ -4313,8 +4642,9 @@ void obs_source_set_async_decoupled(obs_source_t *source, bool decouple) bool obs_source_async_decoupled(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_async_decoupled") ? - source->async_decoupled : false; + return obs_source_valid(source, "obs_source_async_decoupled") + ? source->async_decoupled + : false; } /* hidden/undocumented export to allow source type redefinition for scripts */ @@ -4348,6 +4678,37 @@ void obs_source_set_balance_value(obs_source_t *source, float balance) float obs_source_get_balance_value(const obs_source_t *source) { - return obs_source_valid(source, "obs_source_get_balance_value") ? - source->balance : 0.5f; + return obs_source_valid(source, "obs_source_get_balance_value") + ? source->balance + : 0.5f; +} + +void obs_source_set_audio_active(obs_source_t *source, bool active) +{ + if (!obs_source_valid(source, "obs_source_set_audio_active")) + return; + + if (os_atomic_set_bool(&source->audio_active, active) == active) + return; + + if (active) + obs_source_dosignal(source, "source_audio_activate", + "audio_activate"); + else + obs_source_dosignal(source, "source_audio_deactivate", + "audio_deactivate"); +} + +bool obs_source_audio_active(const obs_source_t *source) +{ + return obs_source_valid(source, "obs_source_audio_active") + ? os_atomic_load_bool(&source->audio_active) + : false; +} + +uint32_t obs_source_get_last_obs_version(const obs_source_t *source) +{ + return obs_source_valid(source, "obs_source_get_last_obs_version") + ? source->last_obs_ver + : 0; } diff --git a/libobs/obs-source.h b/libobs/obs-source.h index fdda90d..3e4aac3 100644 --- a/libobs/obs-source.h +++ b/libobs/obs-source.h @@ -30,7 +30,6 @@ extern "C" { #endif - enum obs_source_type { OBS_SOURCE_TYPE_INPUT, OBS_SOURCE_TYPE_FILTER, @@ -57,7 +56,7 @@ enum obs_balance_type { * Unless SOURCE_ASYNC_VIDEO is specified, the source must include the * video_render callback in the source definition structure. */ -#define OBS_SOURCE_VIDEO (1<<0) +#define OBS_SOURCE_VIDEO (1 << 0) /** * Source has audio. @@ -66,10 +65,10 @@ enum obs_balance_type { * be automatically converted and uploaded. If used with SOURCE_ASYNC_VIDEO, * audio will automatically be synced up to the video output. */ -#define OBS_SOURCE_AUDIO (1<<1) +#define OBS_SOURCE_AUDIO (1 << 1) /** Async video flag (use OBS_SOURCE_ASYNC_VIDEO) */ -#define OBS_SOURCE_ASYNC (1<<2) +#define OBS_SOURCE_ASYNC (1 << 2) /** * Source passes raw video data via RAM. @@ -82,7 +81,7 @@ enum obs_balance_type { * obs_source_getframe to get the current frame data, and * obs_source_releaseframe to release the data when complete. */ -#define OBS_SOURCE_ASYNC_VIDEO (OBS_SOURCE_ASYNC | OBS_SOURCE_VIDEO) +#define OBS_SOURCE_ASYNC_VIDEO (OBS_SOURCE_ASYNC | OBS_SOURCE_VIDEO) /** * Source uses custom drawing, rather than a default effect. @@ -90,7 +89,7 @@ enum obs_balance_type { * If this flag is specified, the video_render callback will pass a NULL * effect, and effect-based filters will not use direct rendering. */ -#define OBS_SOURCE_CUSTOM_DRAW (1<<3) +#define OBS_SOURCE_CUSTOM_DRAW (1 << 3) /** * Source supports interaction. @@ -98,7 +97,7 @@ enum obs_balance_type { * When this is used, the source will receive interaction events * if they provide the necessary callbacks in the source definition structure. */ -#define OBS_SOURCE_INTERACTION (1<<5) +#define OBS_SOURCE_INTERACTION (1 << 5) /** * Source composites sub-sources @@ -109,7 +108,7 @@ enum obs_balance_type { * * This capability flag is always set for transitions. */ -#define OBS_SOURCE_COMPOSITE (1<<6) +#define OBS_SOURCE_COMPOSITE (1 << 6) /** * Source should not be fully duplicated @@ -118,12 +117,12 @@ enum obs_balance_type { * and should prefer to duplicate via holding references rather than full * duplication. */ -#define OBS_SOURCE_DO_NOT_DUPLICATE (1<<7) +#define OBS_SOURCE_DO_NOT_DUPLICATE (1 << 7) /** * Source is deprecated and should not be used */ -#define OBS_SOURCE_DEPRECATED (1<<8) +#define OBS_SOURCE_DEPRECATED (1 << 8) /** * Source cannot have its audio monitored @@ -133,17 +132,26 @@ enum obs_balance_type { * * This is used primarily with desktop audio capture sources. */ -#define OBS_SOURCE_DO_NOT_SELF_MONITOR (1<<9) +#define OBS_SOURCE_DO_NOT_SELF_MONITOR (1 << 9) /** * Source type is currently disabled and should not be shown to the user */ -#define OBS_SOURCE_CAP_DISABLED (1<<10) +#define OBS_SOURCE_CAP_DISABLED (1 << 10) + +/** + * Source should enable monitoring by default. Monitoring should be set by the + * frontend if this flag is set. + */ +#define OBS_SOURCE_MONITOR_BY_DEFAULT (1 << 11) + +/** Used internally for audio submixing */ +#define OBS_SOURCE_SUBMIX (1 << 12) /** @} */ typedef void (*obs_source_enum_proc_t)(obs_source_t *parent, - obs_source_t *child, void *param); + obs_source_t *child, void *param); struct obs_source_audio_mix { struct audio_output_data output[MAX_AUDIO_MIXES]; @@ -293,8 +301,8 @@ struct obs_source_info { * @return New video frame data. This can defer video data to * be drawn later if time is needed for processing */ - struct obs_source_frame *(*filter_video)(void *data, - struct obs_source_frame *frame); + struct obs_source_frame *(*filter_video)( + void *data, struct obs_source_frame *frame); /** * Called to filter raw audio data. @@ -311,7 +319,7 @@ struct obs_source_info { * until the filter is removed/destroyed. */ struct obs_audio_data *(*filter_audio)(void *data, - struct obs_audio_data *audio); + struct obs_audio_data *audio); /** * Called to enumerate all active sources being used within this @@ -323,8 +331,8 @@ struct obs_source_info { * @param param User data to pass to callback */ void (*enum_active_sources)(void *data, - obs_source_enum_proc_t enum_callback, - void *param); + obs_source_enum_proc_t enum_callback, + void *param); /** * Called when saving a source. This is a separate function because @@ -357,9 +365,8 @@ struct obs_source_info { * @param mouse_up Mouse event type (true if mouse-up) * @param click_count Mouse click count (1 for single click, etc.) */ - void (*mouse_click)(void *data, - const struct obs_mouse_event *event, - int32_t type, bool mouse_up, uint32_t click_count); + void (*mouse_click)(void *data, const struct obs_mouse_event *event, + int32_t type, bool mouse_up, uint32_t click_count); /** * Called when interacting with a source and a mouse-move occurs. * @@ -367,8 +374,8 @@ struct obs_source_info { * @param event Mouse event properties * @param mouse_leave Mouse leave state (true if mouse left source) */ - void (*mouse_move)(void *data, - const struct obs_mouse_event *event, bool mouse_leave); + void (*mouse_move)(void *data, const struct obs_mouse_event *event, + bool mouse_leave); /** * Called when interacting with a source and a mouse-wheel occurs. @@ -378,9 +385,8 @@ struct obs_source_info { * @param x_delta Movement delta in the horizontal direction * @param y_delta Movement delta in the vertical direction */ - void (*mouse_wheel)(void *data, - const struct obs_mouse_event *event, int x_delta, - int y_delta); + void (*mouse_wheel)(void *data, const struct obs_mouse_event *event, + int x_delta, int y_delta); /** * Called when interacting with a source and gain focus/lost focus event * occurs. @@ -399,7 +405,7 @@ struct obs_source_info { * @param focus Key event type (true if mouse-up) */ void (*key_click)(void *data, const struct obs_key_event *event, - bool key_up); + bool key_up); /** * Called when the filter is removed from a source @@ -420,8 +426,9 @@ struct obs_source_info { void (*free_type_data)(void *type_data); bool (*audio_render)(void *data, uint64_t *ts_out, - struct obs_source_audio_mix *audio_output, - uint32_t mixers, size_t channels, size_t sample_rate); + struct obs_source_audio_mix *audio_output, + uint32_t mixers, size_t channels, + size_t sample_rate); /** * Called to enumerate all active and inactive sources being used @@ -435,14 +442,17 @@ struct obs_source_info { * @param param User data to pass to callback */ void (*enum_all_sources)(void *data, - obs_source_enum_proc_t enum_callback, - void *param); + obs_source_enum_proc_t enum_callback, + void *param); void (*transition_start)(void *data); void (*transition_stop)(void *data); /** * Gets the default settings for this source + * + * If get_defaults is also defined both will be called, and the first + * call will be to get_defaults, then to get_defaults2. * * @param type_data The type_data variable of this structure * @param[out] settings Data to assign default settings to @@ -457,10 +467,14 @@ struct obs_source_info { * @return The properties data */ obs_properties_t *(*get_properties2)(void *data, void *type_data); + + bool (*audio_mix)(void *data, uint64_t *ts_out, + struct audio_output_data *audio_output, + size_t channels, size_t sample_rate); }; EXPORT void obs_register_source_s(const struct obs_source_info *info, - size_t size); + size_t size); /** * Registers a source definition to the current obs context. This should be diff --git a/libobs/obs-ui.h b/libobs/obs-ui.h index 5944505..9d63efe 100644 --- a/libobs/obs-ui.h +++ b/libobs/obs-ui.h @@ -119,8 +119,8 @@ EXPORT void obs_register_modeless_ui(const struct obs_modeless_ui *info); /* ------------------------------------------------------------------------- */ -#define OBS_UI_SUCCESS 0 -#define OBS_UI_CANCEL -1 +#define OBS_UI_SUCCESS 0 +#define OBS_UI_CANCEL -1 #define OBS_UI_NOTFOUND -2 /** @@ -137,7 +137,7 @@ EXPORT void obs_register_modeless_ui(const struct obs_modeless_ui *info); * OBS_UI_NOTFOUND if the UI callback was not found */ EXPORT int obs_exec_ui(const char *id, const char *task, const char *target, - void *data, void *ui_data); + void *data, void *ui_data); /** * Requests modeless UI to be created. Returns immediately. @@ -151,9 +151,8 @@ EXPORT int obs_exec_ui(const char *id, const char *task, const char *target, * @return Pointer/handle to the target-specific modeless object, or * NULL if not found or failed. */ -EXPORT void *obs_create_ui(const char *id, const char *task, - const char *target, void *data, void *ui_data); - +EXPORT void *obs_create_ui(const char *id, const char *task, const char *target, + void *data, void *ui_data); #ifdef __cplusplus } diff --git a/libobs/obs-video-gpu-encode.c b/libobs/obs-video-gpu-encode.c index aca8dfd..808b55c 100644 --- a/libobs/obs-video-gpu-encode.c +++ b/libobs/obs-video-gpu-encode.c @@ -86,6 +86,9 @@ static void *gpu_encode_thread(void *unused) } } + if (video_pause_check(&encoder->pause, timestamp)) + continue; + if (!encoder->start_ts) encoder->start_ts = timestamp; @@ -95,11 +98,11 @@ static void *gpu_encode_thread(void *unused) next_key++; success = encoder->info.encode_texture( - encoder->context.data, tf.handle, - encoder->cur_pts, lock_key, &next_key, - &pkt, &received); + encoder->context.data, tf.handle, + encoder->cur_pts, lock_key, &next_key, &pkt, + &received); send_off_encoder_packet(encoder, success, received, - &pkt); + &pkt); lock_key = next_key; @@ -114,14 +117,13 @@ static void *gpu_encode_thread(void *unused) if (--tf.count) { tf.timestamp += interval; - circlebuf_push_front(&video->gpu_encoder_queue, - &tf, sizeof(tf)); + circlebuf_push_front(&video->gpu_encoder_queue, &tf, + sizeof(tf)); video_output_inc_texture_skipped_frames(video->video); } else { - circlebuf_push_back( - &video->gpu_encoder_avail_queue, - &tf, sizeof(tf)); + circlebuf_push_back(&video->gpu_encoder_avail_queue, + &tf, sizeof(tf)); } pthread_mutex_unlock(&video->gpu_encoder_mutex); @@ -152,10 +154,9 @@ bool init_gpu_encoding(struct obs_core_video *video) gs_texture_t *tex; gs_texture_t *tex_uv; - gs_texture_create_nv12( - &tex, &tex_uv, - ovi->output_width, ovi->output_height, - GS_RENDER_TARGET | GS_SHARED_KM_TEX); + gs_texture_create_nv12(&tex, &tex_uv, ovi->output_width, + ovi->output_height, + GS_RENDER_TARGET | GS_SHARED_KM_TEX); if (!tex) { return false; } @@ -163,21 +164,19 @@ bool init_gpu_encoding(struct obs_core_video *video) uint32_t handle = gs_texture_get_shared_handle(tex); struct obs_tex_frame frame = { - .tex = tex, - .tex_uv = tex_uv, - .handle = handle - }; + .tex = tex, .tex_uv = tex_uv, .handle = handle}; circlebuf_push_back(&video->gpu_encoder_avail_queue, &frame, - sizeof(frame)); + sizeof(frame)); } if (os_sem_init(&video->gpu_encode_semaphore, 0) != 0) return false; - if (os_event_init(&video->gpu_encode_inactive, OS_EVENT_TYPE_MANUAL) != 0) + if (os_event_init(&video->gpu_encode_inactive, OS_EVENT_TYPE_MANUAL) != + 0) return false; - if (pthread_create(&video->gpu_encode_thread, NULL, - gpu_encode_thread, NULL) != 0) + if (pthread_create(&video->gpu_encode_thread, NULL, gpu_encode_thread, + NULL) != 0) return false; os_event_signal(video->gpu_encode_inactive); @@ -211,15 +210,15 @@ void free_gpu_encoding(struct obs_core_video *video) video->gpu_encode_inactive = NULL; } -#define free_circlebuf(x) \ - do { \ - while (x.size) { \ - struct obs_tex_frame frame; \ +#define free_circlebuf(x) \ + do { \ + while (x.size) { \ + struct obs_tex_frame frame; \ circlebuf_pop_front(&x, &frame, sizeof(frame)); \ - gs_texture_destroy(frame.tex); \ - gs_texture_destroy(frame.tex_uv); \ - } \ - circlebuf_free(&x); \ + gs_texture_destroy(frame.tex); \ + gs_texture_destroy(frame.tex_uv); \ + } \ + circlebuf_free(&x); \ } while (false) free_circlebuf(video->gpu_encoder_queue); diff --git a/libobs/obs-video.c b/libobs/obs-video.c index 4df10d0..0bd84fc 100644 --- a/libobs/obs-video.c +++ b/libobs/obs-video.c @@ -27,13 +27,13 @@ static uint64_t tick_sources(uint64_t cur_time, uint64_t last_time) { struct obs_core_data *data = &obs->data; - struct obs_source *source; - uint64_t delta_time; - float seconds; + struct obs_source *source; + uint64_t delta_time; + float seconds; if (!last_time) last_time = cur_time - - video_output_get_frame_time(obs->video.video); + video_output_get_frame_time(obs->video.video); delta_time = cur_time - last_time; seconds = (float)((double)delta_time / 1000000000.0); @@ -59,7 +59,7 @@ static uint64_t tick_sources(uint64_t cur_time, uint64_t last_time) source = data->first_source; while (source) { struct obs_source *cur_source = obs_source_get_ref(source); - source = (struct obs_source*)source->context.next; + source = (struct obs_source *)source->context.next; if (cur_source) { obs_source_video_tick(cur_source, seconds); @@ -109,24 +109,25 @@ static inline void set_render_size(uint32_t width, uint32_t height) static inline void unmap_last_surface(struct obs_core_video *video) { - if (video->mapped_surface) { - gs_stagesurface_unmap(video->mapped_surface); - video->mapped_surface = NULL; + for (int c = 0; c < NUM_CHANNELS; ++c) { + if (video->mapped_surfaces[c]) { + gs_stagesurface_unmap(video->mapped_surfaces[c]); + video->mapped_surfaces[c] = NULL; + } } } static const char *render_main_texture_name = "render_main_texture"; -static inline void render_main_texture(struct obs_core_video *video, - int cur_texture) +static inline void render_main_texture(struct obs_core_video *video) { profile_start(render_main_texture_name); GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_MAIN_TEXTURE, - render_main_texture_name); + render_main_texture_name); struct vec4 clear_color; vec4_set(&clear_color, 0.0f, 0.0f, 0.0f, 0.0f); - gs_set_render_target(video->render_textures[cur_texture], NULL); + gs_set_render_target(video->render_texture, NULL); gs_clear(GS_CLEAR_COLOR, &clear_color, 1.0f, 0); set_render_size(video->base_width, video->base_height); @@ -137,34 +138,38 @@ static inline void render_main_texture(struct obs_core_video *video, struct draw_callback *callback; callback = obs->data.draw_callbacks.array + (i - 1); - callback->draw(callback->param, - video->base_width, video->base_height); + callback->draw(callback->param, video->base_width, + video->base_height); } pthread_mutex_unlock(&obs->data.draw_callbacks_mutex); obs_view_render(&obs->data.main_view); - video->textures_rendered[cur_texture] = true; + video->texture_rendered = true; GS_DEBUG_MARKER_END(); profile_end(render_main_texture_name); } -static inline gs_effect_t *get_scale_effect_internal( - struct obs_core_video *video) +static inline gs_effect_t * +get_scale_effect_internal(struct obs_core_video *video) { /* if the dimension is under half the size of the original image, * bicubic/lanczos can't sample enough pixels to create an accurate * image, so use the bilinear low resolution effect instead */ - if (video->output_width < (video->base_width / 2) && + if (video->output_width < (video->base_width / 2) && video->output_height < (video->base_height / 2)) { return video->bilinear_lowres_effect; } switch (video->scale_type) { - case OBS_SCALE_BILINEAR: return video->default_effect; - case OBS_SCALE_LANCZOS: return video->lanczos_effect; + case OBS_SCALE_BILINEAR: + return video->default_effect; + case OBS_SCALE_LANCZOS: + return video->lanczos_effect; + case OBS_SCALE_AREA: + return video->area_effect; case OBS_SCALE_BICUBIC: default:; } @@ -173,16 +178,16 @@ static inline gs_effect_t *get_scale_effect_internal( } static inline bool resolution_close(struct obs_core_video *video, - uint32_t width, uint32_t height) + uint32_t width, uint32_t height) { - long width_cmp = (long)video->base_width - (long)width; + long width_cmp = (long)video->base_width - (long)width; long height_cmp = (long)video->base_height - (long)height; return labs(width_cmp) <= 16 && labs(height_cmp) <= 16; } static inline gs_effect_t *get_scale_effect(struct obs_core_video *video, - uint32_t width, uint32_t height) + uint32_t width, uint32_t height) { if (resolution_close(video, width, height)) { return video->default_effect; @@ -191,55 +196,61 @@ static inline gs_effect_t *get_scale_effect(struct obs_core_video *video, * or bilinear by default */ gs_effect_t *effect = get_scale_effect_internal(video); if (!effect) - effect = !!video->bicubic_effect ? - video->bicubic_effect : - video->default_effect; + effect = !!video->bicubic_effect + ? video->bicubic_effect + : video->default_effect; return effect; } } static const char *render_output_texture_name = "render_output_texture"; -static inline void render_output_texture(struct obs_core_video *video, - int cur_texture, int prev_texture) +static inline gs_texture_t *render_output_texture(struct obs_core_video *video) { - profile_start(render_output_texture_name); + gs_texture_t *texture = video->render_texture; + gs_texture_t *target = video->output_texture; + uint32_t width = gs_texture_get_width(target); + uint32_t height = gs_texture_get_height(target); - gs_texture_t *texture = video->render_textures[prev_texture]; - gs_texture_t *target = video->output_textures[cur_texture]; - uint32_t width = gs_texture_get_width(target); - uint32_t height = gs_texture_get_height(target); - struct vec2 base_i; - - vec2_set(&base_i, - 1.0f / (float)video->base_width, - 1.0f / (float)video->base_height); - - gs_effect_t *effect = get_scale_effect(video, width, height); + gs_effect_t *effect = get_scale_effect(video, width, height); gs_technique_t *tech; if (video->ovi.output_format == VIDEO_FORMAT_RGBA) { tech = gs_effect_get_technique(effect, "DrawAlphaDivide"); } else { - tech = gs_effect_get_technique(effect, "DrawMatrix"); + if ((effect == video->default_effect) && + (width == video->base_width) && + (height == video->base_height)) + return texture; + + tech = gs_effect_get_technique(effect, "Draw"); } - gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); - gs_eparam_t *matrix = gs_effect_get_param_by_name(effect, - "color_matrix"); - gs_eparam_t *bres_i = gs_effect_get_param_by_name(effect, - "base_dimension_i"); - size_t passes, i; + profile_start(render_output_texture_name); - if (!video->textures_rendered[prev_texture]) - goto end; + gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); + gs_eparam_t *bres = + gs_effect_get_param_by_name(effect, "base_dimension"); + gs_eparam_t *bres_i = + gs_effect_get_param_by_name(effect, "base_dimension_i"); + size_t passes, i; gs_set_render_target(target, NULL); set_render_size(width, height); - if (bres_i) - gs_effect_set_vec2(bres_i, &base_i); + if (bres) { + struct vec2 base; + vec2_set(&base, (float)video->base_width, + (float)video->base_height); + gs_effect_set_vec2(bres, &base); + } + + if (bres_i) { + struct vec2 base_i; + vec2_set(&base_i, 1.0f / (float)video->base_width, + 1.0f / (float)video->base_height); + gs_effect_set_vec2(bres_i, &base_i); + } - gs_effect_set_val(matrix, video->color_matrix, sizeof(float) * 16); gs_effect_set_texture(image, texture); gs_enable_blending(false); @@ -252,165 +263,132 @@ static inline void render_output_texture(struct obs_core_video *video, gs_technique_end(tech); gs_enable_blending(true); - video->textures_output[cur_texture] = true; - -end: profile_end(render_output_texture_name); + + return target; } -static inline void set_eparam(gs_effect_t *effect, const char *name, float val) +static void render_convert_plane(gs_effect_t *effect, gs_texture_t *target, + const char *tech_name) { - gs_eparam_t *param = gs_effect_get_param_by_name(effect, name); - gs_effect_set_float(param, val); + gs_technique_t *tech = gs_effect_get_technique(effect, tech_name); + + const uint32_t width = gs_texture_get_width(target); + const uint32_t height = gs_texture_get_height(target); + + gs_set_render_target(target, NULL); + set_render_size(width, height); + + size_t passes = gs_technique_begin(tech); + for (size_t i = 0; i < passes; i++) { + gs_technique_begin_pass(tech, i); + gs_draw(GS_TRIS, 0, 3); + gs_technique_end_pass(tech); + } + gs_technique_end(tech); } static const char *render_convert_texture_name = "render_convert_texture"; static void render_convert_texture(struct obs_core_video *video, - int cur_texture, int prev_texture) + gs_texture_t *texture) { profile_start(render_convert_texture_name); - gs_texture_t *texture = video->output_textures[prev_texture]; - gs_texture_t *target = video->convert_textures[cur_texture]; - float fwidth = (float)video->output_width; - float fheight = (float)video->output_height; - size_t passes, i; + gs_effect_t *effect = video->conversion_effect; + gs_eparam_t *color_vec0 = + gs_effect_get_param_by_name(effect, "color_vec0"); + gs_eparam_t *color_vec1 = + gs_effect_get_param_by_name(effect, "color_vec1"); + gs_eparam_t *color_vec2 = + gs_effect_get_param_by_name(effect, "color_vec2"); + gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); + gs_eparam_t *width_i = gs_effect_get_param_by_name(effect, "width_i"); - gs_effect_t *effect = video->conversion_effect; - gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); - gs_technique_t *tech = gs_effect_get_technique(effect, - video->conversion_tech); - - if (!video->textures_output[prev_texture]) - goto end; - - set_eparam(effect, "u_plane_offset", (float)video->plane_offsets[1]); - set_eparam(effect, "v_plane_offset", (float)video->plane_offsets[2]); - set_eparam(effect, "width", fwidth); - set_eparam(effect, "height", fheight); - set_eparam(effect, "width_i", 1.0f / fwidth); - set_eparam(effect, "height_i", 1.0f / fheight); - set_eparam(effect, "width_d2", fwidth * 0.5f); - set_eparam(effect, "height_d2", fheight * 0.5f); - set_eparam(effect, "width_d2_i", 1.0f / (fwidth * 0.5f)); - set_eparam(effect, "height_d2_i", 1.0f / (fheight * 0.5f)); - set_eparam(effect, "input_height", (float)video->conversion_height); - - gs_effect_set_texture(image, texture); - - gs_set_render_target(target, NULL); - set_render_size(video->output_width, video->conversion_height); + struct vec4 vec0, vec1, vec2; + vec4_set(&vec0, video->color_matrix[4], video->color_matrix[5], + video->color_matrix[6], video->color_matrix[7]); + vec4_set(&vec1, video->color_matrix[0], video->color_matrix[1], + video->color_matrix[2], video->color_matrix[3]); + vec4_set(&vec2, video->color_matrix[8], video->color_matrix[9], + video->color_matrix[10], video->color_matrix[11]); gs_enable_blending(false); - passes = gs_technique_begin(tech); - for (i = 0; i < passes; i++) { - gs_technique_begin_pass(tech, i); - gs_draw_sprite(texture, 0, video->output_width, - video->conversion_height); - gs_technique_end_pass(tech); + + if (video->convert_textures[0]) { + gs_effect_set_texture(image, texture); + gs_effect_set_vec4(color_vec0, &vec0); + render_convert_plane(effect, video->convert_textures[0], + video->conversion_techs[0]); + + if (video->convert_textures[1]) { + gs_effect_set_texture(image, texture); + gs_effect_set_vec4(color_vec1, &vec1); + if (!video->convert_textures[2]) + gs_effect_set_vec4(color_vec2, &vec2); + gs_effect_set_float(width_i, video->conversion_width_i); + render_convert_plane(effect, video->convert_textures[1], + video->conversion_techs[1]); + + if (video->convert_textures[2]) { + gs_effect_set_texture(image, texture); + gs_effect_set_vec4(color_vec2, &vec2); + gs_effect_set_float(width_i, + video->conversion_width_i); + render_convert_plane( + effect, video->convert_textures[2], + video->conversion_techs[2]); + } + } } - gs_technique_end(tech); + gs_enable_blending(true); - video->textures_converted[cur_texture] = true; + video->texture_converted = true; -end: profile_end(render_convert_texture_name); } -static void render_nv12(struct obs_core_video *video, gs_texture_t *target, - int cur_texture, int prev_texture, const char *tech_name, - uint32_t width, uint32_t height) -{ - gs_texture_t *texture = video->output_textures[prev_texture]; - - gs_effect_t *effect = video->conversion_effect; - gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); - gs_technique_t *tech = gs_effect_get_technique(effect, tech_name); - size_t passes, i; - - gs_effect_set_texture(image, texture); - - gs_set_render_target(target, NULL); - set_render_size(width, height); - - gs_enable_blending(false); - passes = gs_technique_begin(tech); - for (i = 0; i < passes; i++) { - gs_technique_begin_pass(tech, i); - gs_draw_sprite(texture, 0, width, height); - gs_technique_end_pass(tech); - } - gs_technique_end(tech); - gs_enable_blending(true); - - UNUSED_PARAMETER(cur_texture); -} - -static const char *render_convert_nv12_name = "render_convert_texture_nv12"; -static void render_convert_texture_nv12(struct obs_core_video *video, - int cur_texture, int prev_texture) -{ - profile_start(render_convert_nv12_name); - - if (!video->textures_output[prev_texture]) - goto end; - - render_nv12(video, video->convert_textures[cur_texture], - cur_texture, prev_texture, "NV12_Y", - video->output_width, video->output_height); - render_nv12(video, video->convert_uv_textures[cur_texture], - cur_texture, prev_texture, "NV12_UV", - video->output_width / 2, video->output_height / 2); - - video->textures_converted[cur_texture] = true; - -end: - profile_end(render_convert_nv12_name); -} - static const char *stage_output_texture_name = "stage_output_texture"; static inline void stage_output_texture(struct obs_core_video *video, - int cur_texture, int prev_texture) + int cur_texture) { profile_start(stage_output_texture_name); - gs_texture_t *texture; - bool texture_ready; - gs_stagesurf_t *copy = video->copy_surfaces[cur_texture]; - - if (video->gpu_conversion) { - texture = video->convert_textures[prev_texture]; - texture_ready = video->textures_converted[prev_texture]; - } else { - texture = video->output_textures[prev_texture]; - texture_ready = video->textures_output[prev_texture]; - } - unmap_last_surface(video); - if (!texture_ready) - goto end; + if (!video->gpu_conversion) { + gs_stagesurf_t *copy = video->copy_surfaces[cur_texture][0]; + if (copy) + gs_stage_texture(copy, video->output_texture); - gs_stage_texture(copy, texture); + video->textures_copied[cur_texture] = true; + } else if (video->texture_converted) { + for (int i = 0; i < NUM_CHANNELS; i++) { + gs_stagesurf_t *copy = + video->copy_surfaces[cur_texture][i]; + if (copy) + gs_stage_texture(copy, + video->convert_textures[i]); + } - video->textures_copied[cur_texture] = true; + video->textures_copied[cur_texture] = true; + } -end: profile_end(stage_output_texture_name); } #ifdef _WIN32 static inline bool queue_frame(struct obs_core_video *video, bool raw_active, - struct obs_vframe_info *vframe_info, int prev_texture) + struct obs_vframe_info *vframe_info) { - bool duplicate = !video->gpu_encoder_avail_queue.size || + bool duplicate = + !video->gpu_encoder_avail_queue.size || (video->gpu_encoder_queue.size && vframe_info->count > 1); if (duplicate) { struct obs_tex_frame *tf = circlebuf_data( - &video->gpu_encoder_queue, - video->gpu_encoder_queue.size - sizeof(*tf)); + &video->gpu_encoder_queue, + video->gpu_encoder_queue.size - sizeof(*tf)); /* texture-based encoding is stopping */ if (!tf) { @@ -435,13 +413,13 @@ static inline bool queue_frame(struct obs_core_video *video, bool raw_active, * reason. otherwise, it goes to the 'duplicate' case above, which * will ensure better performance. */ if (raw_active || vframe_info->count > 1) { - gs_copy_texture(tf.tex, video->convert_textures[prev_texture]); + gs_copy_texture(tf.tex, video->convert_textures[0]); } else { - gs_texture_t *tex = video->convert_textures[prev_texture]; - gs_texture_t *tex_uv = video->convert_uv_textures[prev_texture]; + gs_texture_t *tex = video->convert_textures[0]; + gs_texture_t *tex_uv = video->convert_textures[1]; - video->convert_textures[prev_texture] = tf.tex; - video->convert_uv_textures[prev_texture] = tf.tex_uv; + video->convert_textures[0] = tf.tex; + video->convert_textures[1] = tf.tex_uv; tf.tex = tex; tf.tex_uv = tex_uv; @@ -463,28 +441,28 @@ finish: extern void full_stop(struct obs_encoder *encoder); static inline void encode_gpu(struct obs_core_video *video, bool raw_active, - struct obs_vframe_info *vframe_info, int prev_texture) + struct obs_vframe_info *vframe_info) { - while (queue_frame(video, raw_active, vframe_info, prev_texture)); + while (queue_frame(video, raw_active, vframe_info)) + ; } static const char *output_gpu_encoders_name = "output_gpu_encoders"; -static void output_gpu_encoders(struct obs_core_video *video, bool raw_active, - int prev_texture) +static void output_gpu_encoders(struct obs_core_video *video, bool raw_active) { profile_start(output_gpu_encoders_name); - if (!video->textures_converted[prev_texture]) + if (!video->texture_converted) goto end; if (!video->vframe_info_buffer_gpu.size) goto end; struct obs_vframe_info vframe_info; circlebuf_pop_front(&video->vframe_info_buffer_gpu, &vframe_info, - sizeof(vframe_info)); + sizeof(vframe_info)); pthread_mutex_lock(&video->gpu_encoder_mutex); - encode_gpu(video, raw_active, &vframe_info, prev_texture); + encode_gpu(video, raw_active, &vframe_info); pthread_mutex_unlock(&video->gpu_encoder_mutex); end: @@ -492,45 +470,36 @@ end: } #endif -static inline void render_video(struct obs_core_video *video, - bool raw_active, const bool gpu_active, - int cur_texture, int prev_texture) +static inline void render_video(struct obs_core_video *video, bool raw_active, + const bool gpu_active, int cur_texture) { gs_begin_scene(); gs_enable_depth_test(false); gs_set_cull_mode(GS_NEITHER); - render_main_texture(video, cur_texture); + render_main_texture(video); if (raw_active || gpu_active) { - render_output_texture(video, cur_texture, prev_texture); + gs_texture_t *texture = render_output_texture(video); + +#ifdef _WIN32 + if (gpu_active) + gs_flush(); +#endif + + if (video->gpu_conversion) + render_convert_texture(video, texture); #ifdef _WIN32 if (gpu_active) { gs_flush(); + output_gpu_encoders(video, raw_active); } #endif - } - if (raw_active || gpu_active) { - if (video->gpu_conversion) { - if (video->using_nv12_tex) - render_convert_texture_nv12(video, - cur_texture, prev_texture); - else - render_convert_texture(video, - cur_texture, prev_texture); - } - -#ifdef _WIN32 - if (gpu_active) { - gs_flush(); - output_gpu_encoders(video, raw_active, prev_texture); - } -#endif if (raw_active) - stage_output_texture(video, cur_texture, prev_texture); + stage_output_texture(video, cur_texture); } gs_set_render_target(NULL, NULL); @@ -540,149 +509,158 @@ static inline void render_video(struct obs_core_video *video, } static inline bool download_frame(struct obs_core_video *video, - int prev_texture, struct video_data *frame) + int prev_texture, struct video_data *frame) { - gs_stagesurf_t *surface = video->copy_surfaces[prev_texture]; - if (!video->textures_copied[prev_texture]) return false; - if (!gs_stagesurface_map(surface, &frame->data[0], &frame->linesize[0])) - return false; + for (int channel = 0; channel < NUM_CHANNELS; ++channel) { + gs_stagesurf_t *surface = + video->copy_surfaces[prev_texture][channel]; + if (surface) { + if (!gs_stagesurface_map(surface, &frame->data[channel], + &frame->linesize[channel])) + return false; - video->mapped_surface = surface; + video->mapped_surfaces[channel] = surface; + } + } return true; } -static inline uint32_t calc_linesize(uint32_t pos, uint32_t linesize) +static const uint8_t *set_gpu_converted_plane(uint32_t width, uint32_t height, + uint32_t linesize_input, + uint32_t linesize_output, + const uint8_t *in, uint8_t *out) { - uint32_t size = pos % linesize; - return size ? size : linesize; -} - -static void copy_dealign( - uint8_t *dst, uint32_t dst_pos, uint32_t dst_linesize, - const uint8_t *src, uint32_t src_pos, uint32_t src_linesize, - uint32_t remaining) -{ - while (remaining) { - uint32_t src_remainder = src_pos % src_linesize; - uint32_t dst_offset = dst_linesize - src_remainder; - uint32_t src_offset = src_linesize - src_remainder; - - if (remaining < dst_offset) { - memcpy(dst + dst_pos, src + src_pos, remaining); - src_pos += remaining; - dst_pos += remaining; - remaining = 0; - } else { - memcpy(dst + dst_pos, src + src_pos, dst_offset); - src_pos += src_offset; - dst_pos += dst_offset; - remaining -= dst_offset; + if ((width == linesize_input) && (width == linesize_output)) { + size_t total = width * height; + memcpy(out, in, total); + in += total; + } else { + for (size_t y = 0; y < height; y++) { + memcpy(out, in, width); + out += linesize_output; + in += linesize_input; } } -} -static inline uint32_t make_aligned_linesize_offset(uint32_t offset, - uint32_t dst_linesize, uint32_t src_linesize) -{ - uint32_t remainder = offset % dst_linesize; - return (offset / dst_linesize) * src_linesize + remainder; -} - -static void fix_gpu_converted_alignment(struct obs_core_video *video, - struct video_frame *output, const struct video_data *input) -{ - uint32_t src_linesize = input->linesize[0]; - uint32_t dst_linesize = output->linesize[0] * 4; - uint32_t src_pos = 0; - - for (size_t i = 0; i < 3; i++) { - if (video->plane_linewidth[i] == 0) - break; - - src_pos = make_aligned_linesize_offset(video->plane_offsets[i], - dst_linesize, src_linesize); - - copy_dealign(output->data[i], 0, dst_linesize, - input->data[0], src_pos, src_linesize, - video->plane_sizes[i]); - } + return in; } static void set_gpu_converted_data(struct obs_core_video *video, - struct video_frame *output, const struct video_data *input, - const struct video_output_info *info) + struct video_frame *output, + const struct video_data *input, + const struct video_output_info *info) { - if (input->linesize[0] == video->output_width*4) { - struct video_frame frame; + if (video->using_nv12_tex) { + const uint32_t width = info->width; + const uint32_t height = info->height; - for (size_t i = 0; i < 3; i++) { - if (video->plane_linewidth[i] == 0) - break; - - frame.linesize[i] = video->plane_linewidth[i]; - frame.data[i] = - input->data[0] + video->plane_offsets[i]; - } - - video_frame_copy(output, &frame, info->format, info->height); - - } else if (video->using_nv12_tex) { - size_t width = info->width; - size_t height = info->height; - size_t height_d2 = height / 2; - uint8_t *out_y = output->data[0]; - uint8_t *out_uv = output->data[1]; - uint8_t *in = input->data[0]; - - for (size_t y = 0; y < height; y++) { - memcpy(out_y, in, width); - out_y += output->linesize[0]; - in += input->linesize[0]; - } - for (size_t y = 0; y < height_d2; y++) { - memcpy(out_uv, in, width); - out_uv += output->linesize[0]; - in += input->linesize[0]; - } + const uint8_t *const in_uv = set_gpu_converted_plane( + width, height, input->linesize[0], output->linesize[0], + input->data[0], output->data[0]); + const uint32_t height_d2 = height / 2; + set_gpu_converted_plane(width, height_d2, input->linesize[0], + output->linesize[1], in_uv, + output->data[1]); } else { - fix_gpu_converted_alignment(video, output, input); + switch (info->format) { + case VIDEO_FORMAT_I420: { + const uint32_t width = info->width; + const uint32_t height = info->height; + + set_gpu_converted_plane(width, height, + input->linesize[0], + output->linesize[0], + input->data[0], + output->data[0]); + + const uint32_t width_d2 = width / 2; + const uint32_t height_d2 = height / 2; + + set_gpu_converted_plane(width_d2, height_d2, + input->linesize[1], + output->linesize[1], + input->data[1], + output->data[1]); + + set_gpu_converted_plane(width_d2, height_d2, + input->linesize[2], + output->linesize[2], + input->data[2], + output->data[2]); + + break; + } + case VIDEO_FORMAT_NV12: { + const uint32_t width = info->width; + const uint32_t height = info->height; + + set_gpu_converted_plane(width, height, + input->linesize[0], + output->linesize[0], + input->data[0], + output->data[0]); + + const uint32_t height_d2 = height / 2; + set_gpu_converted_plane(width, height_d2, + input->linesize[1], + output->linesize[1], + input->data[1], + output->data[1]); + + break; + } + case VIDEO_FORMAT_I444: { + const uint32_t width = info->width; + const uint32_t height = info->height; + + set_gpu_converted_plane(width, height, + input->linesize[0], + output->linesize[0], + input->data[0], + output->data[0]); + + set_gpu_converted_plane(width, height, + input->linesize[1], + output->linesize[1], + input->data[1], + output->data[1]); + + set_gpu_converted_plane(width, height, + input->linesize[2], + output->linesize[2], + input->data[2], + output->data[2]); + + break; + } + + case VIDEO_FORMAT_NONE: + case VIDEO_FORMAT_YVYU: + case VIDEO_FORMAT_YUY2: + case VIDEO_FORMAT_UYVY: + case VIDEO_FORMAT_RGBA: + case VIDEO_FORMAT_BGRA: + case VIDEO_FORMAT_BGRX: + case VIDEO_FORMAT_Y800: + case VIDEO_FORMAT_BGR3: + case VIDEO_FORMAT_I422: + case VIDEO_FORMAT_I40A: + case VIDEO_FORMAT_I42A: + case VIDEO_FORMAT_YUVA: + case VIDEO_FORMAT_AYUV: + /* unimplemented */ + ; + } } } -static void convert_frame( - struct video_frame *output, const struct video_data *input, - const struct video_output_info *info) -{ - if (info->format == VIDEO_FORMAT_I420) { - compress_uyvx_to_i420( - input->data[0], input->linesize[0], - 0, info->height, - output->data, output->linesize); - - } else if (info->format == VIDEO_FORMAT_NV12) { - compress_uyvx_to_nv12( - input->data[0], input->linesize[0], - 0, info->height, - output->data, output->linesize); - - } else if (info->format == VIDEO_FORMAT_I444) { - convert_uyvx_to_i444( - input->data[0], input->linesize[0], - 0, info->height, - output->data, output->linesize); - - } else { - blog(LOG_ERROR, "convert_frame: unsupported texture format"); - } -} - -static inline void copy_rgbx_frame( - struct video_frame *output, const struct video_data *input, - const struct video_output_info *info) +static inline void copy_rgbx_frame(struct video_frame *output, + const struct video_data *input, + const struct video_output_info *info) { uint8_t *in_ptr = input->data[0]; uint8_t *out_ptr = output->data[0]; @@ -700,7 +678,7 @@ static inline void copy_rgbx_frame( } static inline void output_video_data(struct obs_core_video *video, - struct video_data *input_frame, int count) + struct video_data *input_frame, int count) { const struct video_output_info *info; struct video_frame output_frame; @@ -709,14 +687,11 @@ static inline void output_video_data(struct obs_core_video *video, info = video_output_get_info(video->video); locked = video_output_lock_frame(video->video, &output_frame, count, - input_frame->timestamp); + input_frame->timestamp); if (locked) { if (video->gpu_conversion) { set_gpu_converted_data(video, &output_frame, - input_frame, info); - - } else if (format_is_yuv(info->format)) { - convert_frame(&output_frame, input_frame, info); + input_frame, info); } else { copy_rgbx_frame(&output_frame, input_frame, info); } @@ -725,9 +700,9 @@ static inline void output_video_data(struct obs_core_video *video, } } -static inline void video_sleep(struct obs_core_video *video, - bool raw_active, const bool gpu_active, - uint64_t *p_time, uint64_t interval_ns) +static inline void video_sleep(struct obs_core_video *video, bool raw_active, + const bool gpu_active, uint64_t *p_time, + uint64_t interval_ns) { struct obs_vframe_info vframe_info; uint64_t cur_time = *p_time; @@ -750,10 +725,10 @@ static inline void video_sleep(struct obs_core_video *video, if (raw_active) circlebuf_push_back(&video->vframe_info_buffer, &vframe_info, - sizeof(vframe_info)); + sizeof(vframe_info)); if (gpu_active) circlebuf_push_back(&video->vframe_info_buffer_gpu, - &vframe_info, sizeof(vframe_info)); + &vframe_info, sizeof(vframe_info)); } static const char *output_frame_gs_context_name = "gs_context(video->graphics)"; @@ -764,8 +739,9 @@ static const char *output_frame_output_video_data_name = "output_video_data"; static inline void output_frame(bool raw_active, const bool gpu_active) { struct obs_core_video *video = &obs->video; - int cur_texture = video->cur_texture; - int prev_texture = cur_texture == 0 ? NUM_TEXTURES-1 : cur_texture-1; + int cur_texture = video->cur_texture; + int prev_texture = cur_texture == 0 ? NUM_TEXTURES - 1 + : cur_texture - 1; struct video_data frame; bool frame_ready = 0; @@ -776,8 +752,8 @@ static inline void output_frame(bool raw_active, const bool gpu_active) profile_start(output_frame_render_video_name); GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_RENDER_VIDEO, - output_frame_render_video_name); - render_video(video, raw_active, gpu_active, cur_texture, prev_texture); + output_frame_render_video_name); + render_video(video, raw_active, gpu_active, cur_texture); GS_DEBUG_MARKER_END(); profile_end(output_frame_render_video_name); @@ -797,7 +773,7 @@ static inline void output_frame(bool raw_active, const bool gpu_active) if (raw_active && frame_ready) { struct obs_vframe_info vframe_info; circlebuf_pop_front(&video->vframe_info_buffer, &vframe_info, - sizeof(vframe_info)); + sizeof(vframe_info)); frame.timestamp = vframe_info.timestamp; profile_start(output_frame_output_video_data_name); @@ -814,9 +790,8 @@ static inline void output_frame(bool raw_active, const bool gpu_active) static void clear_base_frame_data(void) { struct obs_core_video *video = &obs->video; - memset(video->textures_rendered, 0, sizeof(video->textures_rendered)); - memset(video->textures_output, 0, sizeof(video->textures_output)); - memset(video->textures_converted, 0, sizeof(video->textures_converted)); + video->texture_rendered = false; + video->texture_converted = false; circlebuf_free(&video->vframe_info_buffer); video->cur_texture = 0; } @@ -853,12 +828,13 @@ void *obs_graphics_thread(void *param) bool was_active = false; obs->video.video_time = os_gettime_ns(); + obs->video.video_frame_interval_ns = interval; os_set_thread_name("libobs: graphics thread"); - const char *video_thread_name = - profile_store_name(obs_get_profiler_name_store(), - "obs_graphics_thread(%g"NBSP"ms)", interval / 1000000.); + const char *video_thread_name = profile_store_name( + obs_get_profiler_name_store(), + "obs_graphics_thread(%g" NBSP "ms)", interval / 1000000.); profile_register_root(video_thread_name, interval); srand((unsigned int)time(NULL)); @@ -909,17 +885,19 @@ void *obs_graphics_thread(void *param) profile_reenable_thread(); video_sleep(&obs->video, raw_active, gpu_active, - &obs->video.video_time, interval); + &obs->video.video_time, interval); frame_time_total_ns += frame_time_ns; fps_total_ns += (obs->video.video_time - last_time); fps_total_frames++; if (fps_total_ns >= 1000000000ULL) { - obs->video.video_fps = (double)fps_total_frames / + obs->video.video_fps = + (double)fps_total_frames / ((double)fps_total_ns / 1000000000.0); obs->video.video_avg_frame_time_ns = - frame_time_total_ns / (uint64_t)fps_total_frames; + frame_time_total_ns / + (uint64_t)fps_total_frames; frame_time_total_ns = 0; fps_total_ns = 0; diff --git a/libobs/obs-view.c b/libobs/obs-view.c index a580595..c8c389d 100644 --- a/libobs/obs-view.c +++ b/libobs/obs-view.c @@ -20,7 +20,8 @@ bool obs_view_init(struct obs_view *view) { - if (!view) return false; + if (!view) + return false; pthread_mutex_init_value(&view->channels_mutex); @@ -46,7 +47,8 @@ obs_view_t *obs_view_create(void) void obs_view_free(struct obs_view *view) { - if (!view) return; + if (!view) + return; for (size_t i = 0; i < MAX_CHANNELS; i++) { struct obs_source *source = view->channels[i]; @@ -73,8 +75,10 @@ obs_source_t *obs_view_get_source(obs_view_t *view, uint32_t channel) obs_source_t *source; assert(channel < MAX_CHANNELS); - if (!view) return NULL; - if (channel >= MAX_CHANNELS) return NULL; + if (!view) + return NULL; + if (channel >= MAX_CHANNELS) + return NULL; pthread_mutex_lock(&view->channels_mutex); @@ -88,14 +92,16 @@ obs_source_t *obs_view_get_source(obs_view_t *view, uint32_t channel) } void obs_view_set_source(obs_view_t *view, uint32_t channel, - obs_source_t *source) + obs_source_t *source) { struct obs_source *prev_source; assert(channel < MAX_CHANNELS); - if (!view) return; - if (channel >= MAX_CHANNELS) return; + if (!view) + return; + if (channel >= MAX_CHANNELS) + return; pthread_mutex_lock(&view->channels_mutex); @@ -117,7 +123,8 @@ void obs_view_set_source(obs_view_t *view, uint32_t channel, void obs_view_render(obs_view_t *view) { - if (!view) return; + if (!view) + return; pthread_mutex_lock(&view->channels_mutex); diff --git a/libobs/obs-win-crash-handler.c b/libobs/obs-win-crash-handler.c index 33ffff9..cae4c4d 100644 --- a/libobs/obs-win-crash-handler.c +++ b/libobs/obs-win-crash-handler.c @@ -27,81 +27,83 @@ #include "util/platform.h" #include "util/windows/win-version.h" -typedef BOOL (WINAPI *ENUMERATELOADEDMODULES64)(HANDLE process, - PENUMLOADED_MODULES_CALLBACK64 enum_loaded_modules_callback, - PVOID user_context); -typedef DWORD (WINAPI *SYMSETOPTIONS)(DWORD sym_options); -typedef BOOL (WINAPI *SYMINITIALIZE)(HANDLE process, PCTSTR user_search_path, - BOOL invade_process); -typedef BOOL (WINAPI *SYMCLEANUP)(HANDLE process); -typedef BOOL (WINAPI *STACKWALK64)(DWORD machine_type, HANDLE process, - HANDLE thread, LPSTACKFRAME64 stack_frame, - PVOID context_record, - PREAD_PROCESS_MEMORY_ROUTINE64 read_memory_routine, - PFUNCTION_TABLE_ACCESS_ROUTINE64 function_table_access_routine, - PGET_MODULE_BASE_ROUTINE64 get_module_base_routine, - PTRANSLATE_ADDRESS_ROUTINE64 translate_address); -typedef BOOL (WINAPI *SYMREFRESHMODULELIST)(HANDLE process); +typedef BOOL(WINAPI *ENUMERATELOADEDMODULES64)( + HANDLE process, + PENUMLOADED_MODULES_CALLBACK64 enum_loaded_modules_callback, + PVOID user_context); +typedef DWORD(WINAPI *SYMSETOPTIONS)(DWORD sym_options); +typedef BOOL(WINAPI *SYMINITIALIZE)(HANDLE process, PCTSTR user_search_path, + BOOL invade_process); +typedef BOOL(WINAPI *SYMCLEANUP)(HANDLE process); +typedef BOOL(WINAPI *STACKWALK64)( + DWORD machine_type, HANDLE process, HANDLE thread, + LPSTACKFRAME64 stack_frame, PVOID context_record, + PREAD_PROCESS_MEMORY_ROUTINE64 read_memory_routine, + PFUNCTION_TABLE_ACCESS_ROUTINE64 function_table_access_routine, + PGET_MODULE_BASE_ROUTINE64 get_module_base_routine, + PTRANSLATE_ADDRESS_ROUTINE64 translate_address); +typedef BOOL(WINAPI *SYMREFRESHMODULELIST)(HANDLE process); -typedef PVOID (WINAPI *SYMFUNCTIONTABLEACCESS64)(HANDLE process, - DWORD64 addr_base); -typedef DWORD64 (WINAPI *SYMGETMODULEBASE64)(HANDLE process, DWORD64 addr); -typedef BOOL (WINAPI *SYMFROMADDR)(HANDLE process, DWORD64 address, - PDWORD64 displacement, PSYMBOL_INFOW symbol); -typedef BOOL (WINAPI *SYMGETMODULEINFO64)(HANDLE process, DWORD64 addr, - PIMAGEHLP_MODULE64 module_info); +typedef PVOID(WINAPI *SYMFUNCTIONTABLEACCESS64)(HANDLE process, + DWORD64 addr_base); +typedef DWORD64(WINAPI *SYMGETMODULEBASE64)(HANDLE process, DWORD64 addr); +typedef BOOL(WINAPI *SYMFROMADDR)(HANDLE process, DWORD64 address, + PDWORD64 displacement, PSYMBOL_INFOW symbol); +typedef BOOL(WINAPI *SYMGETMODULEINFO64)(HANDLE process, DWORD64 addr, + PIMAGEHLP_MODULE64 module_info); -typedef DWORD64 (WINAPI *SYMLOADMODULE64)(HANDLE process, HANDLE file, - PSTR image_name, PSTR module_name, DWORD64 base_of_dll, - DWORD size_of_dll); +typedef DWORD64(WINAPI *SYMLOADMODULE64)(HANDLE process, HANDLE file, + PSTR image_name, PSTR module_name, + DWORD64 base_of_dll, + DWORD size_of_dll); -typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE process, DWORD process_id, - HANDLE file, MINIDUMP_TYPE dump_type, - PMINIDUMP_EXCEPTION_INFORMATION exception_param, - PMINIDUMP_USER_STREAM_INFORMATION user_stream_param, - PMINIDUMP_CALLBACK_INFORMATION callback_param); +typedef BOOL(WINAPI *MINIDUMPWRITEDUMP)( + HANDLE process, DWORD process_id, HANDLE file, MINIDUMP_TYPE dump_type, + PMINIDUMP_EXCEPTION_INFORMATION exception_param, + PMINIDUMP_USER_STREAM_INFORMATION user_stream_param, + PMINIDUMP_CALLBACK_INFORMATION callback_param); -typedef HINSTANCE (WINAPI *SHELLEXECUTEA)(HWND hwnd, LPCTSTR operation, - LPCTSTR file, LPCTSTR parameters, LPCTSTR directory, - INT show_flags); +typedef HINSTANCE(WINAPI *SHELLEXECUTEA)(HWND hwnd, LPCTSTR operation, + LPCTSTR file, LPCTSTR parameters, + LPCTSTR directory, INT show_flags); struct stack_trace { - CONTEXT context; - DWORD64 instruction_ptr; - STACKFRAME64 frame; - DWORD image_type; + CONTEXT context; + DWORD64 instruction_ptr; + STACKFRAME64 frame; + DWORD image_type; }; struct exception_handler_data { - SYMINITIALIZE sym_initialize; - SYMCLEANUP sym_cleanup; - SYMSETOPTIONS sym_set_options; - SYMFUNCTIONTABLEACCESS64 sym_function_table_access64; - SYMGETMODULEBASE64 sym_get_module_base64; - SYMFROMADDR sym_from_addr; - SYMGETMODULEINFO64 sym_get_module_info64; - SYMREFRESHMODULELIST sym_refresh_module_list; - STACKWALK64 stack_walk64; - ENUMERATELOADEDMODULES64 enumerate_loaded_modules64; - MINIDUMPWRITEDUMP minidump_write_dump; + SYMINITIALIZE sym_initialize; + SYMCLEANUP sym_cleanup; + SYMSETOPTIONS sym_set_options; + SYMFUNCTIONTABLEACCESS64 sym_function_table_access64; + SYMGETMODULEBASE64 sym_get_module_base64; + SYMFROMADDR sym_from_addr; + SYMGETMODULEINFO64 sym_get_module_info64; + SYMREFRESHMODULELIST sym_refresh_module_list; + STACKWALK64 stack_walk64; + ENUMERATELOADEDMODULES64 enumerate_loaded_modules64; + MINIDUMPWRITEDUMP minidump_write_dump; - HMODULE dbghelp; - SYMBOL_INFOW *sym_info; - PEXCEPTION_POINTERS exception; - struct win_version_info win_version; - SYSTEMTIME time_info; - HANDLE process; + HMODULE dbghelp; + SYMBOL_INFOW *sym_info; + PEXCEPTION_POINTERS exception; + struct win_version_info win_version; + SYSTEMTIME time_info; + HANDLE process; - struct stack_trace main_trace; + struct stack_trace main_trace; - struct dstr str; - struct dstr cpu_info; - struct dstr module_name; - struct dstr module_list; + struct dstr str; + struct dstr cpu_info; + struct dstr module_name; + struct dstr module_list; }; -static inline void exception_handler_data_free( - struct exception_handler_data *data) +static inline void +exception_handler_data_free(struct exception_handler_data *data) { LocalFree(data->sym_info); dstr_free(&data->str); @@ -113,14 +115,14 @@ static inline void exception_handler_data_free( static inline void *get_proc(HMODULE module, const char *func) { - return (void*)GetProcAddress(module, func); + return (void *)GetProcAddress(module, func); } -#define GET_DBGHELP_IMPORT(target, str) \ - do { \ +#define GET_DBGHELP_IMPORT(target, str) \ + do { \ data->target = get_proc(data->dbghelp, str); \ - if (!data->target) \ - return false; \ + if (!data->target) \ + return false; \ } while (false) static inline bool get_dbghelp_imports(struct exception_handler_data *data) @@ -133,14 +135,14 @@ static inline bool get_dbghelp_imports(struct exception_handler_data *data) GET_DBGHELP_IMPORT(sym_cleanup, "SymCleanup"); GET_DBGHELP_IMPORT(sym_set_options, "SymSetOptions"); GET_DBGHELP_IMPORT(sym_function_table_access64, - "SymFunctionTableAccess64"); + "SymFunctionTableAccess64"); GET_DBGHELP_IMPORT(sym_get_module_base64, "SymGetModuleBase64"); GET_DBGHELP_IMPORT(sym_from_addr, "SymFromAddrW"); GET_DBGHELP_IMPORT(sym_get_module_info64, "SymGetModuleInfo64"); GET_DBGHELP_IMPORT(sym_refresh_module_list, "SymRefreshModuleList"); GET_DBGHELP_IMPORT(stack_walk64, "StackWalk64"); GET_DBGHELP_IMPORT(enumerate_loaded_modules64, - "EnumerateLoadedModulesW64"); + "EnumerateLoadedModulesW64"); GET_DBGHELP_IMPORT(minidump_write_dump, "MiniDumpWriteDump"); return true; @@ -171,10 +173,8 @@ extern bool sym_initialize_called; static inline void init_sym_info(struct exception_handler_data *data) { - data->sym_set_options( - SYMOPT_UNDNAME | - SYMOPT_FAIL_CRITICAL_ERRORS | - SYMOPT_LOAD_ANYTHING); + data->sym_set_options(SYMOPT_UNDNAME | SYMOPT_FAIL_CRITICAL_ERRORS | + SYMOPT_LOAD_ANYTHING); if (!sym_initialize_called) data->sym_initialize(data->process, NULL, true); @@ -205,7 +205,7 @@ static inline void init_cpu_info(struct exception_handler_data *data) DWORD size = 1024; status = RegQueryValueExW(key, L"ProcessorNameString", NULL, - NULL, (LPBYTE)str, &size); + NULL, (LPBYTE)str, &size); if (status == ERROR_SUCCESS) dstr_from_wcs(&data->cpu_info, str); else @@ -216,35 +216,34 @@ static inline void init_cpu_info(struct exception_handler_data *data) } static BOOL CALLBACK enum_all_modules(PCTSTR module_name, DWORD64 module_base, - ULONG module_size, struct exception_handler_data *data) + ULONG module_size, + struct exception_handler_data *data) { char name_utf8[MAX_PATH]; os_wcs_to_utf8(module_name, 0, name_utf8, MAX_PATH); if (data->main_trace.instruction_ptr >= module_base && - data->main_trace.instruction_ptr < module_base + module_size) { + data->main_trace.instruction_ptr < module_base + module_size) { dstr_copy(&data->module_name, name_utf8); strlwr(data->module_name.array); } #ifdef _WIN64 - dstr_catf(&data->module_list, "%016"PRIX64"-%016"PRIX64" %s\r\n", - module_base, module_base + module_size, - name_utf8); + dstr_catf(&data->module_list, "%016" PRIX64 "-%016" PRIX64 " %s\r\n", + module_base, module_base + module_size, name_utf8); #else - dstr_catf(&data->module_list, "%08"PRIX64"-%08"PRIX64" %s\r\n", - module_base, module_base + module_size, - name_utf8); + dstr_catf(&data->module_list, "%08" PRIX64 "-%08" PRIX64 " %s\r\n", + module_base, module_base + module_size, name_utf8); #endif return true; } static inline void init_module_info(struct exception_handler_data *data) { - data->enumerate_loaded_modules64(data->process, - (PENUMLOADED_MODULES_CALLBACK64)enum_all_modules, - data); + data->enumerate_loaded_modules64( + data->process, (PENUMLOADED_MODULES_CALLBACK64)enum_all_modules, + data); } static inline void write_header(struct exception_handler_data *data) @@ -256,27 +255,24 @@ static inline void write_header(struct exception_handler_data *data) strftime(date_time, sizeof(date_time), "%Y-%m-%d, %X", &ts); const char *obs_bitness; - if (sizeof(void*) == 8) + if (sizeof(void *) == 8) obs_bitness = "64"; else obs_bitness = "32"; - dstr_catf(&data->str, "Unhandled exception: %x\r\n" - "Date/Time: %s\r\n" - "Fault address: %"PRIX64" (%s)\r\n" - "libobs version: "OBS_VERSION" (%s-bit)\r\n" - "Windows version: %d.%d build %d (revision: %d; " - "%s-bit)\r\n" - "CPU: %s\r\n\r\n", - data->exception->ExceptionRecord->ExceptionCode, - date_time, - data->main_trace.instruction_ptr, - data->module_name.array, - obs_bitness, - data->win_version.major, data->win_version.minor, - data->win_version.build, data->win_version.revis, - is_64_bit_windows() ? "64" : "32", - data->cpu_info.array); + dstr_catf(&data->str, + "Unhandled exception: %x\r\n" + "Date/Time: %s\r\n" + "Fault address: %" PRIX64 " (%s)\r\n" + "libobs version: " OBS_VERSION " (%s-bit)\r\n" + "Windows version: %d.%d build %d (revision: %d; " + "%s-bit)\r\n" + "CPU: %s\r\n\r\n", + data->exception->ExceptionRecord->ExceptionCode, date_time, + data->main_trace.instruction_ptr, data->module_name.array, + obs_bitness, data->win_version.major, data->win_version.minor, + data->win_version.build, data->win_version.revis, + is_64_bit_windows() ? "64" : "32", data->cpu_info.array); } struct module_info { @@ -285,10 +281,10 @@ struct module_info { }; static BOOL CALLBACK enum_module(PCTSTR module_name, DWORD64 module_base, - ULONG module_size, struct module_info *info) + ULONG module_size, struct module_info *info) { if (info->addr >= module_base && - info->addr < module_base + module_size) { + info->addr < module_base + module_size) { os_wcs_to_utf8(module_name, 0, info->name_utf8, MAX_PATH); strlwr(info->name_utf8); @@ -299,24 +295,26 @@ static BOOL CALLBACK enum_module(PCTSTR module_name, DWORD64 module_base, } static inline void get_module_name(struct exception_handler_data *data, - struct module_info *info) + struct module_info *info) { - data->enumerate_loaded_modules64(data->process, - (PENUMLOADED_MODULES_CALLBACK64)enum_module, info); + data->enumerate_loaded_modules64( + data->process, (PENUMLOADED_MODULES_CALLBACK64)enum_module, + info); } static inline bool walk_stack(struct exception_handler_data *data, - HANDLE thread, struct stack_trace *trace) + HANDLE thread, struct stack_trace *trace) { struct module_info module_info = {0}; DWORD64 func_offset; char sym_name[256]; char *p; - bool success = data->stack_walk64(trace->image_type, - data->process, thread, &trace->frame, &trace->context, - NULL, data->sym_function_table_access64, - data->sym_get_module_base64, NULL); + bool success = data->stack_walk64(trace->image_type, data->process, + thread, &trace->frame, + &trace->context, NULL, + data->sym_function_table_access64, + data->sym_get_module_base64, NULL); if (!success) return false; @@ -332,24 +330,24 @@ static inline bool walk_stack(struct exception_handler_data *data, } success = !!data->sym_from_addr(data->process, - trace->frame.AddrPC.Offset, &func_offset, - data->sym_info); + trace->frame.AddrPC.Offset, + &func_offset, data->sym_info); if (success) os_wcs_to_utf8(data->sym_info->Name, 0, sym_name, 256); #ifdef _WIN64 -#define SUCCESS_FORMAT \ +#define SUCCESS_FORMAT \ "%016I64X %016I64X %016I64X %016I64X " \ "%016I64X %016I64X %s!%s+0x%I64x\r\n" -#define FAIL_FORMAT \ +#define FAIL_FORMAT \ "%016I64X %016I64X %016I64X %016I64X " \ "%016I64X %016I64X %s!0x%I64x\r\n" #else -#define SUCCESS_FORMAT \ +#define SUCCESS_FORMAT \ "%08.8I64X %08.8I64X %08.8I64X %08.8I64X " \ "%08.8I64X %08.8I64X %s!%s+0x%I64x\r\n" -#define FAIL_FORMAT \ +#define FAIL_FORMAT \ "%08.8I64X %08.8I64X %08.8I64X %08.8I64X " \ "%08.8I64X %08.8I64X %s!0x%I64x\r\n" @@ -363,39 +361,34 @@ static inline bool walk_stack(struct exception_handler_data *data, if (success && (data->sym_info->Flags & SYMFLAG_EXPORT) == 0) { dstr_catf(&data->str, SUCCESS_FORMAT, - trace->frame.AddrStack.Offset, - trace->frame.AddrPC.Offset, - trace->frame.Params[0], - trace->frame.Params[1], - trace->frame.Params[2], - trace->frame.Params[3], - p, sym_name, func_offset); + trace->frame.AddrStack.Offset, + trace->frame.AddrPC.Offset, trace->frame.Params[0], + trace->frame.Params[1], trace->frame.Params[2], + trace->frame.Params[3], p, sym_name, func_offset); } else { dstr_catf(&data->str, FAIL_FORMAT, - trace->frame.AddrStack.Offset, - trace->frame.AddrPC.Offset, - trace->frame.Params[0], - trace->frame.Params[1], - trace->frame.Params[2], - trace->frame.Params[3], - p, trace->frame.AddrPC.Offset); + trace->frame.AddrStack.Offset, + trace->frame.AddrPC.Offset, trace->frame.Params[0], + trace->frame.Params[1], trace->frame.Params[2], + trace->frame.Params[3], p, + trace->frame.AddrPC.Offset); } return true; } #ifdef _WIN64 -#define TRACE_TOP \ +#define TRACE_TOP \ "Stack EIP Arg0 " \ "Arg1 Arg2 Arg3 Address\r\n" #else -#define TRACE_TOP \ +#define TRACE_TOP \ "Stack EIP Arg0 " \ "Arg1 Arg2 Arg3 Address\r\n" #endif static inline void write_thread_trace(struct exception_handler_data *data, - THREADENTRY32 *entry, bool first_thread) + THREADENTRY32 *entry, bool first_thread) { bool crash_thread = entry->th32ThreadID == GetCurrentThreadId(); struct stack_trace trace = {0}; @@ -416,13 +409,13 @@ static inline void write_thread_trace(struct exception_handler_data *data, GetThreadContext(thread, &trace.context); init_instruction_data(&trace); - dstr_catf(&data->str, "\r\nThread %lX%s\r\n"TRACE_TOP, - entry->th32ThreadID, - crash_thread ? " (Crashed)" : ""); + dstr_catf(&data->str, "\r\nThread %lX%s\r\n" TRACE_TOP, + entry->th32ThreadID, crash_thread ? " (Crashed)" : ""); ptrace = crash_thread ? &data->main_trace : &trace; - while (walk_stack(data, thread, ptrace)); + while (walk_stack(data, thread, ptrace)) + ; CloseHandle(thread); } @@ -431,7 +424,7 @@ static inline void write_thread_traces(struct exception_handler_data *data) { THREADENTRY32 entry = {0}; HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, - GetCurrentProcessId()); + GetCurrentProcessId()); bool success; if (snapshot == INVALID_HANDLE_VALUE) @@ -468,7 +461,7 @@ static inline void write_module_list(struct exception_handler_data *data) /* ------------------------------------------------------------------------- */ static inline void handle_exception(struct exception_handler_data *data, - PEXCEPTION_POINTERS exception) + PEXCEPTION_POINTERS exception) { if (!get_dbghelp_imports(data)) return; diff --git a/libobs/obs-windows.c b/libobs/obs-windows.c index d2a5bde..70e17f2 100644 --- a/libobs/obs-windows.c +++ b/libobs/obs-windows.c @@ -44,13 +44,11 @@ static const char *module_bin[] = { "../../obs-plugins/" BIT_STRING, }; -static const char *module_data[] = { - "data/%module%", - "../../data/obs-plugins/%module%" -}; +static const char *module_data[] = {"data/%module%", + "../../data/obs-plugins/%module%"}; static const int module_patterns_size = - sizeof(module_bin)/sizeof(module_bin[0]); + sizeof(module_bin) / sizeof(module_bin[0]); void add_default_module_paths(void) { @@ -76,23 +74,23 @@ char *find_libobs_data_file(const char *file) static void log_processor_info(void) { - HKEY key; + HKEY key; wchar_t data[1024]; - char *str = NULL; - DWORD size, speed; + char *str = NULL; + DWORD size, speed; LSTATUS status; memset(data, 0, sizeof(data)); - status = RegOpenKeyW(HKEY_LOCAL_MACHINE, - L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", - &key); + status = RegOpenKeyW( + HKEY_LOCAL_MACHINE, + L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &key); if (status != ERROR_SUCCESS) return; size = sizeof(data); status = RegQueryValueExW(key, L"ProcessorNameString", NULL, NULL, - (LPBYTE)data, &size); + (LPBYTE)data, &size); if (status == ERROR_SUCCESS) { os_wcs_to_utf8_ptr(data, 0, &str); blog(LOG_INFO, "CPU Name: %s", str); @@ -101,7 +99,7 @@ static void log_processor_info(void) size = sizeof(speed); status = RegQueryValueExW(key, L"~MHz", NULL, NULL, (LPBYTE)&speed, - &size); + &size); if (status == ERROR_SUCCESS) blog(LOG_INFO, "CPU Speed: %ldMHz", speed); @@ -111,7 +109,7 @@ static void log_processor_info(void) static void log_processor_cores(void) { blog(LOG_INFO, "Physical Cores: %d, Logical Cores: %d", - os_get_physical_cores(), os_get_logical_cores()); + os_get_physical_cores(), os_get_logical_cores()); } static void log_available_memory(void) @@ -128,9 +126,8 @@ static void log_available_memory(void) #endif blog(LOG_INFO, "Physical Memory: %luMB Total, %luMB Free%s", - (DWORD)(ms.ullTotalPhys / 1048576), - (DWORD)(ms.ullAvailPhys / 1048576), - note); + (DWORD)(ms.ullTotalPhys / 1048576), + (DWORD)(ms.ullAvailPhys / 1048576), note); } static void log_windows_version(void) @@ -142,8 +139,7 @@ static void log_windows_version(void) const char *windows_bitness = b64 ? "64" : "32"; blog(LOG_INFO, "Windows Version: %d.%d Build %d (revision: %d; %s-bit)", - ver.major, ver.minor, ver.build, ver.revis, - windows_bitness); + ver.major, ver.minor, ver.build, ver.revis, windows_bitness); } static void log_admin_status(void) @@ -153,8 +149,9 @@ static void log_admin_status(void) BOOL success; success = AllocateAndInitializeSid(&auth, 2, - SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, - 0, 0, 0, 0, 0, 0, &admin_group); + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, + 0, 0, &admin_group); if (success) { if (!CheckTokenMembership(NULL, admin_group, &success)) success = false; @@ -162,17 +159,19 @@ static void log_admin_status(void) } blog(LOG_INFO, "Running as administrator: %s", - success ? "true" : "false"); + success ? "true" : "false"); } -typedef HRESULT (WINAPI *dwm_is_composition_enabled_t)(BOOL*); +typedef HRESULT(WINAPI *dwm_is_composition_enabled_t)(BOOL *); static void log_aero(void) { dwm_is_composition_enabled_t composition_enabled = NULL; - const char *aeroMessage = win_ver >= 0x602 ? - " (Aero is always on for windows 8 and above)" : ""; + const char *aeroMessage = + win_ver >= 0x602 + ? " (Aero is always on for windows 8 and above)" + : ""; HMODULE dwm = LoadLibraryW(L"dwmapi"); BOOL bComposition = true; @@ -181,21 +180,22 @@ static void log_aero(void) return; } - composition_enabled = (dwm_is_composition_enabled_t)GetProcAddress(dwm, - "DwmIsCompositionEnabled"); + composition_enabled = (dwm_is_composition_enabled_t)GetProcAddress( + dwm, "DwmIsCompositionEnabled"); if (!composition_enabled) { + FreeLibrary(dwm); return; } composition_enabled(&bComposition); blog(LOG_INFO, "Aero is %s%s", bComposition ? "Enabled" : "Disabled", - aeroMessage); + aeroMessage); } #define WIN10_GAME_BAR_REG_KEY \ - L"Software\\Microsoft\\Windows\\CurrentVersion\\GameDVR" + L"Software\\Microsoft\\Windows\\CurrentVersion\\GameDVR" #define WIN10_GAME_DVR_POLICY_REG_KEY \ - L"SOFTWARE\\Policies\\Microsoft\\Windows\\GameDVR" + L"SOFTWARE\\Policies\\Microsoft\\Windows\\GameDVR" #define WIN10_GAME_DVR_REG_KEY L"System\\GameConfigStore" #define WIN10_GAME_MODE_REG_KEY L"Software\\Microsoft\\GameBar" @@ -211,45 +211,44 @@ static void log_gaming_features(void) struct reg_dword game_mode_enabled; get_reg_dword(HKEY_CURRENT_USER, WIN10_GAME_BAR_REG_KEY, - L"AppCaptureEnabled", &game_bar_enabled); + L"AppCaptureEnabled", &game_bar_enabled); get_reg_dword(HKEY_CURRENT_USER, WIN10_GAME_DVR_POLICY_REG_KEY, - L"AllowGameDVR", &game_dvr_allowed); + L"AllowGameDVR", &game_dvr_allowed); get_reg_dword(HKEY_CURRENT_USER, WIN10_GAME_DVR_REG_KEY, - L"GameDVR_Enabled", &game_dvr_enabled); + L"GameDVR_Enabled", &game_dvr_enabled); get_reg_dword(HKEY_CURRENT_USER, WIN10_GAME_BAR_REG_KEY, - L"HistoricalCaptureEnabled", &game_dvr_bg_recording); + L"HistoricalCaptureEnabled", &game_dvr_bg_recording); get_reg_dword(HKEY_CURRENT_USER, WIN10_GAME_MODE_REG_KEY, - L"AllowAutoGameMode", &game_mode_enabled); + L"AllowAutoGameMode", &game_mode_enabled); if (game_mode_enabled.status != ERROR_SUCCESS) { get_reg_dword(HKEY_CURRENT_USER, WIN10_GAME_MODE_REG_KEY, - L"AutoGameModeEnabled", &game_mode_enabled); + L"AutoGameModeEnabled", &game_mode_enabled); } blog(LOG_INFO, "Windows 10 Gaming Features:"); if (game_bar_enabled.status == ERROR_SUCCESS) { blog(LOG_INFO, "\tGame Bar: %s", - (bool)game_bar_enabled.return_value ? "On" : "Off"); + (bool)game_bar_enabled.return_value ? "On" : "Off"); } if (game_dvr_allowed.status == ERROR_SUCCESS) { blog(LOG_INFO, "\tGame DVR Allowed: %s", - (bool)game_dvr_allowed.return_value ? "Yes" : "No"); + (bool)game_dvr_allowed.return_value ? "Yes" : "No"); } if (game_dvr_enabled.status == ERROR_SUCCESS) { blog(LOG_INFO, "\tGame DVR: %s", - (bool)game_dvr_enabled.return_value ? "On" : "Off"); + (bool)game_dvr_enabled.return_value ? "On" : "Off"); } if (game_dvr_bg_recording.status == ERROR_SUCCESS) { blog(LOG_INFO, "\tGame DVR Background Recording: %s", - (bool)game_dvr_bg_recording.return_value ? "On" : - "Off"); + (bool)game_dvr_bg_recording.return_value ? "On" : "Off"); } if (game_mode_enabled.status == ERROR_SUCCESS) { blog(LOG_INFO, "\tGame Mode: %s", - (bool)game_mode_enabled.return_value ? "On" : "Off"); + (bool)game_mode_enabled.return_value ? "On" : "Off"); } } @@ -318,8 +317,7 @@ static void log_security_products_by_type(IWSCProductList *prod_list, int type) } blog(LOG_INFO, "\t%S: %s (%s)", name, - get_str_for_state(prod_state), - get_str_for_type(type)); + get_str_for_state(prod_state), get_str_for_type(type)); SysFreeString(name); prod->lpVtbl->Release(prod); @@ -350,27 +348,27 @@ static void log_security_products(void) blog(LOG_INFO, "Sec. Software Status:"); hr = CoCreateInstance(prod_list_clsid, NULL, - CLSCTX_INPROC_SERVER, prod_list_iid, - &prod_list); + CLSCTX_INPROC_SERVER, prod_list_iid, + &prod_list); if (!FAILED(hr)) { - log_security_products_by_type(prod_list, - WSC_SECURITY_PROVIDER_ANTIVIRUS); + log_security_products_by_type( + prod_list, WSC_SECURITY_PROVIDER_ANTIVIRUS); } hr = CoCreateInstance(prod_list_clsid, NULL, - CLSCTX_INPROC_SERVER, prod_list_iid, - &prod_list); + CLSCTX_INPROC_SERVER, prod_list_iid, + &prod_list); if (!FAILED(hr)) { - log_security_products_by_type(prod_list, - WSC_SECURITY_PROVIDER_FIREWALL); + log_security_products_by_type( + prod_list, WSC_SECURITY_PROVIDER_FIREWALL); } hr = CoCreateInstance(prod_list_clsid, NULL, - CLSCTX_INPROC_SERVER, prod_list_iid, - &prod_list); + CLSCTX_INPROC_SERVER, prod_list_iid, + &prod_list); if (!FAILED(hr)) { - log_security_products_by_type(prod_list, - WSC_SECURITY_PROVIDER_ANTISPYWARE); + log_security_products_by_type( + prod_list, WSC_SECURITY_PROVIDER_ANTISPYWARE); } } @@ -394,7 +392,6 @@ void log_system_info(void) log_security_products(); } - struct obs_hotkeys_platform { int vk_codes[OBS_KEY_LAST_VALUE]; }; @@ -402,137 +399,260 @@ struct obs_hotkeys_platform { static int get_virtual_key(obs_key_t key) { switch (key) { - case OBS_KEY_RETURN: return VK_RETURN; - case OBS_KEY_ESCAPE: return VK_ESCAPE; - case OBS_KEY_TAB: return VK_TAB; - case OBS_KEY_BACKTAB: return VK_OEM_BACKTAB; - case OBS_KEY_BACKSPACE: return VK_BACK; - case OBS_KEY_INSERT: return VK_INSERT; - case OBS_KEY_DELETE: return VK_DELETE; - case OBS_KEY_PAUSE: return VK_PAUSE; - case OBS_KEY_PRINT: return VK_SNAPSHOT; - case OBS_KEY_CLEAR: return VK_CLEAR; - case OBS_KEY_HOME: return VK_HOME; - case OBS_KEY_END: return VK_END; - case OBS_KEY_LEFT: return VK_LEFT; - case OBS_KEY_UP: return VK_UP; - case OBS_KEY_RIGHT: return VK_RIGHT; - case OBS_KEY_DOWN: return VK_DOWN; - case OBS_KEY_PAGEUP: return VK_PRIOR; - case OBS_KEY_PAGEDOWN: return VK_NEXT; + case OBS_KEY_RETURN: + return VK_RETURN; + case OBS_KEY_ESCAPE: + return VK_ESCAPE; + case OBS_KEY_TAB: + return VK_TAB; + case OBS_KEY_BACKTAB: + return VK_OEM_BACKTAB; + case OBS_KEY_BACKSPACE: + return VK_BACK; + case OBS_KEY_INSERT: + return VK_INSERT; + case OBS_KEY_DELETE: + return VK_DELETE; + case OBS_KEY_PAUSE: + return VK_PAUSE; + case OBS_KEY_PRINT: + return VK_SNAPSHOT; + case OBS_KEY_CLEAR: + return VK_CLEAR; + case OBS_KEY_HOME: + return VK_HOME; + case OBS_KEY_END: + return VK_END; + case OBS_KEY_LEFT: + return VK_LEFT; + case OBS_KEY_UP: + return VK_UP; + case OBS_KEY_RIGHT: + return VK_RIGHT; + case OBS_KEY_DOWN: + return VK_DOWN; + case OBS_KEY_PAGEUP: + return VK_PRIOR; + case OBS_KEY_PAGEDOWN: + return VK_NEXT; - case OBS_KEY_SHIFT: return VK_SHIFT; - case OBS_KEY_CONTROL: return VK_CONTROL; - case OBS_KEY_ALT: return VK_MENU; - case OBS_KEY_CAPSLOCK: return VK_CAPITAL; - case OBS_KEY_NUMLOCK: return VK_NUMLOCK; - case OBS_KEY_SCROLLLOCK: return VK_SCROLL; + case OBS_KEY_SHIFT: + return VK_SHIFT; + case OBS_KEY_CONTROL: + return VK_CONTROL; + case OBS_KEY_ALT: + return VK_MENU; + case OBS_KEY_CAPSLOCK: + return VK_CAPITAL; + case OBS_KEY_NUMLOCK: + return VK_NUMLOCK; + case OBS_KEY_SCROLLLOCK: + return VK_SCROLL; - case OBS_KEY_F1: return VK_F1; - case OBS_KEY_F2: return VK_F2; - case OBS_KEY_F3: return VK_F3; - case OBS_KEY_F4: return VK_F4; - case OBS_KEY_F5: return VK_F5; - case OBS_KEY_F6: return VK_F6; - case OBS_KEY_F7: return VK_F7; - case OBS_KEY_F8: return VK_F8; - case OBS_KEY_F9: return VK_F9; - case OBS_KEY_F10: return VK_F10; - case OBS_KEY_F11: return VK_F11; - case OBS_KEY_F12: return VK_F12; - case OBS_KEY_F13: return VK_F13; - case OBS_KEY_F14: return VK_F14; - case OBS_KEY_F15: return VK_F15; - case OBS_KEY_F16: return VK_F16; - case OBS_KEY_F17: return VK_F17; - case OBS_KEY_F18: return VK_F18; - case OBS_KEY_F19: return VK_F19; - case OBS_KEY_F20: return VK_F20; - case OBS_KEY_F21: return VK_F21; - case OBS_KEY_F22: return VK_F22; - case OBS_KEY_F23: return VK_F23; - case OBS_KEY_F24: return VK_F24; + case OBS_KEY_F1: + return VK_F1; + case OBS_KEY_F2: + return VK_F2; + case OBS_KEY_F3: + return VK_F3; + case OBS_KEY_F4: + return VK_F4; + case OBS_KEY_F5: + return VK_F5; + case OBS_KEY_F6: + return VK_F6; + case OBS_KEY_F7: + return VK_F7; + case OBS_KEY_F8: + return VK_F8; + case OBS_KEY_F9: + return VK_F9; + case OBS_KEY_F10: + return VK_F10; + case OBS_KEY_F11: + return VK_F11; + case OBS_KEY_F12: + return VK_F12; + case OBS_KEY_F13: + return VK_F13; + case OBS_KEY_F14: + return VK_F14; + case OBS_KEY_F15: + return VK_F15; + case OBS_KEY_F16: + return VK_F16; + case OBS_KEY_F17: + return VK_F17; + case OBS_KEY_F18: + return VK_F18; + case OBS_KEY_F19: + return VK_F19; + case OBS_KEY_F20: + return VK_F20; + case OBS_KEY_F21: + return VK_F21; + case OBS_KEY_F22: + return VK_F22; + case OBS_KEY_F23: + return VK_F23; + case OBS_KEY_F24: + return VK_F24; - case OBS_KEY_SPACE: return VK_SPACE; + case OBS_KEY_SPACE: + return VK_SPACE; - case OBS_KEY_APOSTROPHE: return VK_OEM_7; - case OBS_KEY_PLUS: return VK_OEM_PLUS; - case OBS_KEY_COMMA: return VK_OEM_COMMA; - case OBS_KEY_MINUS: return VK_OEM_MINUS; - case OBS_KEY_PERIOD: return VK_OEM_PERIOD; - case OBS_KEY_SLASH: return VK_OEM_2; - case OBS_KEY_0: return '0'; - case OBS_KEY_1: return '1'; - case OBS_KEY_2: return '2'; - case OBS_KEY_3: return '3'; - case OBS_KEY_4: return '4'; - case OBS_KEY_5: return '5'; - case OBS_KEY_6: return '6'; - case OBS_KEY_7: return '7'; - case OBS_KEY_8: return '8'; - case OBS_KEY_9: return '9'; - case OBS_KEY_NUMASTERISK: return VK_MULTIPLY; - case OBS_KEY_NUMPLUS: return VK_ADD; - case OBS_KEY_NUMMINUS: return VK_SUBTRACT; - case OBS_KEY_NUMPERIOD: return VK_DECIMAL; - case OBS_KEY_NUMSLASH: return VK_DIVIDE; - case OBS_KEY_NUM0: return VK_NUMPAD0; - case OBS_KEY_NUM1: return VK_NUMPAD1; - case OBS_KEY_NUM2: return VK_NUMPAD2; - case OBS_KEY_NUM3: return VK_NUMPAD3; - case OBS_KEY_NUM4: return VK_NUMPAD4; - case OBS_KEY_NUM5: return VK_NUMPAD5; - case OBS_KEY_NUM6: return VK_NUMPAD6; - case OBS_KEY_NUM7: return VK_NUMPAD7; - case OBS_KEY_NUM8: return VK_NUMPAD8; - case OBS_KEY_NUM9: return VK_NUMPAD9; - case OBS_KEY_SEMICOLON: return VK_OEM_1; - case OBS_KEY_A: return 'A'; - case OBS_KEY_B: return 'B'; - case OBS_KEY_C: return 'C'; - case OBS_KEY_D: return 'D'; - case OBS_KEY_E: return 'E'; - case OBS_KEY_F: return 'F'; - case OBS_KEY_G: return 'G'; - case OBS_KEY_H: return 'H'; - case OBS_KEY_I: return 'I'; - case OBS_KEY_J: return 'J'; - case OBS_KEY_K: return 'K'; - case OBS_KEY_L: return 'L'; - case OBS_KEY_M: return 'M'; - case OBS_KEY_N: return 'N'; - case OBS_KEY_O: return 'O'; - case OBS_KEY_P: return 'P'; - case OBS_KEY_Q: return 'Q'; - case OBS_KEY_R: return 'R'; - case OBS_KEY_S: return 'S'; - case OBS_KEY_T: return 'T'; - case OBS_KEY_U: return 'U'; - case OBS_KEY_V: return 'V'; - case OBS_KEY_W: return 'W'; - case OBS_KEY_X: return 'X'; - case OBS_KEY_Y: return 'Y'; - case OBS_KEY_Z: return 'Z'; - case OBS_KEY_BRACKETLEFT: return VK_OEM_4; - case OBS_KEY_BACKSLASH: return VK_OEM_5; - case OBS_KEY_BRACKETRIGHT: return VK_OEM_6; - case OBS_KEY_ASCIITILDE: return VK_OEM_3; + case OBS_KEY_APOSTROPHE: + return VK_OEM_7; + case OBS_KEY_PLUS: + return VK_OEM_PLUS; + case OBS_KEY_COMMA: + return VK_OEM_COMMA; + case OBS_KEY_MINUS: + return VK_OEM_MINUS; + case OBS_KEY_PERIOD: + return VK_OEM_PERIOD; + case OBS_KEY_SLASH: + return VK_OEM_2; + case OBS_KEY_0: + return '0'; + case OBS_KEY_1: + return '1'; + case OBS_KEY_2: + return '2'; + case OBS_KEY_3: + return '3'; + case OBS_KEY_4: + return '4'; + case OBS_KEY_5: + return '5'; + case OBS_KEY_6: + return '6'; + case OBS_KEY_7: + return '7'; + case OBS_KEY_8: + return '8'; + case OBS_KEY_9: + return '9'; + case OBS_KEY_NUMASTERISK: + return VK_MULTIPLY; + case OBS_KEY_NUMPLUS: + return VK_ADD; + case OBS_KEY_NUMMINUS: + return VK_SUBTRACT; + case OBS_KEY_NUMPERIOD: + return VK_DECIMAL; + case OBS_KEY_NUMSLASH: + return VK_DIVIDE; + case OBS_KEY_NUM0: + return VK_NUMPAD0; + case OBS_KEY_NUM1: + return VK_NUMPAD1; + case OBS_KEY_NUM2: + return VK_NUMPAD2; + case OBS_KEY_NUM3: + return VK_NUMPAD3; + case OBS_KEY_NUM4: + return VK_NUMPAD4; + case OBS_KEY_NUM5: + return VK_NUMPAD5; + case OBS_KEY_NUM6: + return VK_NUMPAD6; + case OBS_KEY_NUM7: + return VK_NUMPAD7; + case OBS_KEY_NUM8: + return VK_NUMPAD8; + case OBS_KEY_NUM9: + return VK_NUMPAD9; + case OBS_KEY_SEMICOLON: + return VK_OEM_1; + case OBS_KEY_A: + return 'A'; + case OBS_KEY_B: + return 'B'; + case OBS_KEY_C: + return 'C'; + case OBS_KEY_D: + return 'D'; + case OBS_KEY_E: + return 'E'; + case OBS_KEY_F: + return 'F'; + case OBS_KEY_G: + return 'G'; + case OBS_KEY_H: + return 'H'; + case OBS_KEY_I: + return 'I'; + case OBS_KEY_J: + return 'J'; + case OBS_KEY_K: + return 'K'; + case OBS_KEY_L: + return 'L'; + case OBS_KEY_M: + return 'M'; + case OBS_KEY_N: + return 'N'; + case OBS_KEY_O: + return 'O'; + case OBS_KEY_P: + return 'P'; + case OBS_KEY_Q: + return 'Q'; + case OBS_KEY_R: + return 'R'; + case OBS_KEY_S: + return 'S'; + case OBS_KEY_T: + return 'T'; + case OBS_KEY_U: + return 'U'; + case OBS_KEY_V: + return 'V'; + case OBS_KEY_W: + return 'W'; + case OBS_KEY_X: + return 'X'; + case OBS_KEY_Y: + return 'Y'; + case OBS_KEY_Z: + return 'Z'; + case OBS_KEY_BRACKETLEFT: + return VK_OEM_4; + case OBS_KEY_BACKSLASH: + return VK_OEM_5; + case OBS_KEY_BRACKETRIGHT: + return VK_OEM_6; + case OBS_KEY_ASCIITILDE: + return VK_OEM_3; - case OBS_KEY_HENKAN: return VK_CONVERT; - case OBS_KEY_MUHENKAN: return VK_NONCONVERT; - case OBS_KEY_KANJI: return VK_KANJI; - case OBS_KEY_TOUROKU: return VK_OEM_FJ_TOUROKU; - case OBS_KEY_MASSYO: return VK_OEM_FJ_MASSHOU; + case OBS_KEY_HENKAN: + return VK_CONVERT; + case OBS_KEY_MUHENKAN: + return VK_NONCONVERT; + case OBS_KEY_KANJI: + return VK_KANJI; + case OBS_KEY_TOUROKU: + return VK_OEM_FJ_TOUROKU; + case OBS_KEY_MASSYO: + return VK_OEM_FJ_MASSHOU; - case OBS_KEY_HANGUL: return VK_HANGUL; + case OBS_KEY_HANGUL: + return VK_HANGUL; - case OBS_KEY_BACKSLASH_RT102: return VK_OEM_102; + case OBS_KEY_BACKSLASH_RT102: + return VK_OEM_102; - case OBS_KEY_MOUSE1: return VK_LBUTTON; - case OBS_KEY_MOUSE2: return VK_RBUTTON; - case OBS_KEY_MOUSE3: return VK_MBUTTON; - case OBS_KEY_MOUSE4: return VK_XBUTTON1; - case OBS_KEY_MOUSE5: return VK_XBUTTON2; + case OBS_KEY_MOUSE1: + return VK_LBUTTON; + case OBS_KEY_MOUSE2: + return VK_RBUTTON; + case OBS_KEY_MOUSE3: + return VK_MBUTTON; + case OBS_KEY_MOUSE4: + return VK_XBUTTON1; + case OBS_KEY_MOUSE5: + return VK_XBUTTON2; /* TODO: Implement keys for non-US keyboards */ default:; @@ -565,7 +685,7 @@ static bool vk_down(DWORD vk) } bool obs_hotkeys_platform_is_pressed(obs_hotkeys_platform_t *context, - obs_key_t key) + obs_key_t key) { if (key == OBS_KEY_META) { return vk_down(VK_LWIN) || vk_down(VK_RWIN); @@ -589,11 +709,11 @@ void obs_key_to_str(obs_key_t key, struct dstr *str) dstr_copy(str, obs->hotkeys.translations[key]); } else { dstr_printf(str, "Mouse %d", - (int)(key - OBS_KEY_MOUSE1 + 1)); + (int)(key - OBS_KEY_MOUSE1 + 1)); } return; - - } if (key == OBS_KEY_PAUSE) { + } + if (key == OBS_KEY_PAUSE) { dstr_copy(str, obs_get_hotkey_translation(key, "Pause")); return; @@ -665,7 +785,7 @@ static inline void add_combo_key(obs_key_t key, struct dstr *str) } void obs_key_combination_to_str(obs_key_combination_t combination, - struct dstr *str) + struct dstr *str) { if ((combination.modifiers & INTERACT_CONTROL_KEY) != 0) { add_combo_key(OBS_KEY_CONTROL, str); @@ -688,14 +808,14 @@ bool sym_initialize_called = false; void reset_win32_symbol_paths(void) { - static BOOL (WINAPI *sym_initialize_w)(HANDLE, const wchar_t*, BOOL); - static BOOL (WINAPI *sym_set_search_path_w)(HANDLE, const wchar_t*); + static BOOL(WINAPI * sym_initialize_w)(HANDLE, const wchar_t *, BOOL); + static BOOL(WINAPI * sym_set_search_path_w)(HANDLE, const wchar_t *); static bool funcs_initialized = false; static bool initialize_success = false; struct obs_module *module = obs->first_module; struct dstr path_str = {0}; - DARRAY(char*) paths; + DARRAY(char *) paths; wchar_t *path_str_w = NULL; char *abspath; @@ -709,13 +829,17 @@ void reset_win32_symbol_paths(void) if (!mod) return; - sym_initialize_w = (void*)GetProcAddress(mod, "SymInitializeW"); - sym_set_search_path_w = (void*)GetProcAddress(mod, - "SymSetSearchPathW"); - if (!sym_initialize_w || !sym_set_search_path_w) + sym_initialize_w = + (void *)GetProcAddress(mod, "SymInitializeW"); + sym_set_search_path_w = + (void *)GetProcAddress(mod, "SymSetSearchPathW"); + if (!sym_initialize_w || !sym_set_search_path_w) { + FreeLibrary(mod); return; + } initialize_success = true; + // Leaks 'mod' once. } if (!initialize_success) @@ -775,11 +899,11 @@ void reset_win32_symbol_paths(void) if (path_str_w) { if (!sym_initialize_called) { sym_initialize_w(GetCurrentProcess(), - path_str_w, false); + path_str_w, false); sym_initialize_called = true; } else { sym_set_search_path_w(GetCurrentProcess(), - path_str_w); + path_str_w); } bfree(path_str_w); diff --git a/libobs/obs.c b/libobs/obs.c index acefb3e..5c2db4c 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -29,131 +29,48 @@ extern void add_default_module_paths(void); extern char *find_libobs_data_file(const char *file); static inline void make_video_info(struct video_output_info *vi, - struct obs_video_info *ovi) + struct obs_video_info *ovi) { - vi->name = "video"; - vi->format = ovi->output_format; + vi->name = "video"; + vi->format = ovi->output_format; vi->fps_num = ovi->fps_num; vi->fps_den = ovi->fps_den; - vi->width = ovi->output_width; - vi->height = ovi->output_height; - vi->range = ovi->range; + vi->width = ovi->output_width; + vi->height = ovi->output_height; + vi->range = ovi->range; vi->colorspace = ovi->colorspace; vi->cache_size = 6; } -#define PIXEL_SIZE 4 - -#define GET_ALIGN(val, align) \ - (((val) + (align-1)) & ~(align-1)) - -static inline void set_420p_sizes(const struct obs_video_info *ovi) -{ - struct obs_core_video *video = &obs->video; - uint32_t chroma_pixels; - uint32_t total_bytes; - - chroma_pixels = (ovi->output_width * ovi->output_height / 4); - chroma_pixels = GET_ALIGN(chroma_pixels, PIXEL_SIZE); - - video->plane_offsets[0] = 0; - video->plane_offsets[1] = ovi->output_width * ovi->output_height; - video->plane_offsets[2] = video->plane_offsets[1] + chroma_pixels; - - video->plane_linewidth[0] = ovi->output_width; - video->plane_linewidth[1] = ovi->output_width/2; - video->plane_linewidth[2] = ovi->output_width/2; - - video->plane_sizes[0] = video->plane_offsets[1]; - video->plane_sizes[1] = video->plane_sizes[0]/4; - video->plane_sizes[2] = video->plane_sizes[1]; - - total_bytes = video->plane_offsets[2] + chroma_pixels; - - video->conversion_height = - (total_bytes/PIXEL_SIZE + ovi->output_width-1) / - ovi->output_width; - - video->conversion_height = GET_ALIGN(video->conversion_height, 2); - video->conversion_tech = "Planar420"; -} - -static inline void set_nv12_sizes(const struct obs_video_info *ovi) -{ - struct obs_core_video *video = &obs->video; - uint32_t chroma_pixels; - uint32_t total_bytes; - - chroma_pixels = (ovi->output_width * ovi->output_height / 2); - chroma_pixels = GET_ALIGN(chroma_pixels, PIXEL_SIZE); - - video->plane_offsets[0] = 0; - video->plane_offsets[1] = ovi->output_width * ovi->output_height; - - video->plane_linewidth[0] = ovi->output_width; - video->plane_linewidth[1] = ovi->output_width; - - video->plane_sizes[0] = video->plane_offsets[1]; - video->plane_sizes[1] = video->plane_sizes[0]/2; - - total_bytes = video->plane_offsets[1] + chroma_pixels; - - video->conversion_height = - (total_bytes/PIXEL_SIZE + ovi->output_width-1) / - ovi->output_width; - - video->conversion_height = GET_ALIGN(video->conversion_height, 2); - video->conversion_tech = "NV12"; -} - -static inline void set_444p_sizes(const struct obs_video_info *ovi) -{ - struct obs_core_video *video = &obs->video; - uint32_t chroma_pixels; - uint32_t total_bytes; - - chroma_pixels = (ovi->output_width * ovi->output_height); - chroma_pixels = GET_ALIGN(chroma_pixels, PIXEL_SIZE); - - video->plane_offsets[0] = 0; - video->plane_offsets[1] = chroma_pixels; - video->plane_offsets[2] = chroma_pixels + chroma_pixels; - - video->plane_linewidth[0] = ovi->output_width; - video->plane_linewidth[1] = ovi->output_width; - video->plane_linewidth[2] = ovi->output_width; - - video->plane_sizes[0] = chroma_pixels; - video->plane_sizes[1] = chroma_pixels; - video->plane_sizes[2] = chroma_pixels; - - total_bytes = video->plane_offsets[2] + chroma_pixels; - - video->conversion_height = - (total_bytes/PIXEL_SIZE + ovi->output_width-1) / - ovi->output_width; - - video->conversion_height = GET_ALIGN(video->conversion_height, 2); - video->conversion_tech = "Planar444"; -} - static inline void calc_gpu_conversion_sizes(const struct obs_video_info *ovi) { - obs->video.conversion_height = 0; - memset(obs->video.plane_offsets, 0, sizeof(obs->video.plane_offsets)); - memset(obs->video.plane_sizes, 0, sizeof(obs->video.plane_sizes)); - memset(obs->video.plane_linewidth, 0, - sizeof(obs->video.plane_linewidth)); + struct obs_core_video *video = &obs->video; + + video->conversion_needed = false; + video->conversion_techs[0] = NULL; + video->conversion_techs[1] = NULL; + video->conversion_techs[2] = NULL; + video->conversion_width_i = 0.f; switch ((uint32_t)ovi->output_format) { case VIDEO_FORMAT_I420: - set_420p_sizes(ovi); + video->conversion_needed = true; + video->conversion_techs[0] = "Planar_Y"; + video->conversion_techs[1] = "Planar_U_Left"; + video->conversion_techs[2] = "Planar_V_Left"; + video->conversion_width_i = 1.f / (float)ovi->output_width; break; case VIDEO_FORMAT_NV12: - set_nv12_sizes(ovi); + video->conversion_needed = true; + video->conversion_techs[0] = "NV12_Y"; + video->conversion_techs[1] = "NV12_UV"; + video->conversion_width_i = 1.f / (float)ovi->output_width; break; case VIDEO_FORMAT_I444: - set_444p_sizes(ovi); + video->conversion_needed = true; + video->conversion_techs[0] = "Planar_Y"; + video->conversion_techs[1] = "Planar_U"; + video->conversion_techs[2] = "Planar_V"; break; } } @@ -165,11 +82,12 @@ static bool obs_init_gpu_conversion(struct obs_video_info *ovi) calc_gpu_conversion_sizes(ovi); video->using_nv12_tex = ovi->output_format == VIDEO_FORMAT_NV12 - ? gs_nv12_available() : false; + ? gs_nv12_available() + : false; - if (!video->conversion_height) { + if (!video->conversion_needed) { blog(LOG_INFO, "GPU conversion not available for format: %u", - (unsigned int)ovi->output_format); + (unsigned int)ovi->output_format); video->gpu_conversion = false; video->using_nv12_tex = false; blog(LOG_INFO, "NV12 texture support not available"); @@ -181,28 +99,97 @@ static bool obs_init_gpu_conversion(struct obs_video_info *ovi) else blog(LOG_INFO, "NV12 texture support not available"); - for (size_t i = 0; i < NUM_TEXTURES; i++) { #ifdef _WIN32 - if (video->using_nv12_tex) { - gs_texture_create_nv12( - &video->convert_textures[i], - &video->convert_uv_textures[i], - ovi->output_width, ovi->output_height, - GS_RENDER_TARGET | GS_SHARED_KM_TEX); - if (!video->convert_uv_textures[i]) - return false; - } else { + if (video->using_nv12_tex) { + gs_texture_create_nv12(&video->convert_textures[0], + &video->convert_textures[1], + ovi->output_width, ovi->output_height, + GS_RENDER_TARGET | GS_SHARED_KM_TEX); + } else { #endif - video->convert_textures[i] = gs_texture_create( - ovi->output_width, - video->conversion_height, - GS_RGBA, 1, NULL, GS_RENDER_TARGET); -#ifdef _WIN32 + video->convert_textures[0] = + gs_texture_create(ovi->output_width, ovi->output_height, + GS_R8, 1, NULL, GS_RENDER_TARGET); + + const struct video_output_info *info = + video_output_get_info(video->video); + switch (info->format) { + case VIDEO_FORMAT_I420: + video->convert_textures[1] = gs_texture_create( + ovi->output_width / 2, ovi->output_height / 2, + GS_R8, 1, NULL, GS_RENDER_TARGET); + video->convert_textures[2] = gs_texture_create( + ovi->output_width / 2, ovi->output_height / 2, + GS_R8, 1, NULL, GS_RENDER_TARGET); + if (!video->convert_textures[2]) + return false; + break; + case VIDEO_FORMAT_NV12: + video->convert_textures[1] = gs_texture_create( + ovi->output_width / 2, ovi->output_height / 2, + GS_R8G8, 1, NULL, GS_RENDER_TARGET); + break; + case VIDEO_FORMAT_I444: + video->convert_textures[1] = gs_texture_create( + ovi->output_width, ovi->output_height, GS_R8, 1, + NULL, GS_RENDER_TARGET); + video->convert_textures[2] = gs_texture_create( + ovi->output_width, ovi->output_height, GS_R8, 1, + NULL, GS_RENDER_TARGET); + if (!video->convert_textures[2]) + return false; + break; } +#ifdef _WIN32 + } #endif - if (!video->convert_textures[i]) + if (!video->convert_textures[0]) + return false; + if (!video->convert_textures[1]) + return false; + + return true; +} + +static bool obs_init_gpu_copy_surfaces(struct obs_video_info *ovi, size_t i) +{ + struct obs_core_video *video = &obs->video; + + video->copy_surfaces[i][0] = gs_stagesurface_create( + ovi->output_width, ovi->output_height, GS_R8); + if (!video->copy_surfaces[i][0]) + return false; + + const struct video_output_info *info = + video_output_get_info(video->video); + switch (info->format) { + case VIDEO_FORMAT_I420: + video->copy_surfaces[i][1] = gs_stagesurface_create( + ovi->output_width / 2, ovi->output_height / 2, GS_R8); + if (!video->copy_surfaces[i][1]) return false; + video->copy_surfaces[i][2] = gs_stagesurface_create( + ovi->output_width / 2, ovi->output_height / 2, GS_R8); + if (!video->copy_surfaces[i][2]) + return false; + break; + case VIDEO_FORMAT_NV12: + video->copy_surfaces[i][1] = gs_stagesurface_create( + ovi->output_width / 2, ovi->output_height / 2, GS_R8G8); + if (!video->copy_surfaces[i][1]) + return false; + break; + case VIDEO_FORMAT_I444: + video->copy_surfaces[i][1] = gs_stagesurface_create( + ovi->output_width, ovi->output_height, GS_R8); + if (!video->copy_surfaces[i][1]) + return false; + video->copy_surfaces[i][2] = gs_stagesurface_create( + ovi->output_width, ovi->output_height, GS_R8); + if (!video->copy_surfaces[i][2]) + return false; + break; } return true; @@ -211,44 +198,48 @@ static bool obs_init_gpu_conversion(struct obs_video_info *ovi) static bool obs_init_textures(struct obs_video_info *ovi) { struct obs_core_video *video = &obs->video; - uint32_t output_height = video->gpu_conversion ? - video->conversion_height : ovi->output_height; - size_t i; - for (i = 0; i < NUM_TEXTURES; i++) { + for (size_t i = 0; i < NUM_TEXTURES; i++) { #ifdef _WIN32 if (video->using_nv12_tex) { - video->copy_surfaces[i] = gs_stagesurface_create_nv12( - ovi->output_width, ovi->output_height); - if (!video->copy_surfaces[i]) + video->copy_surfaces[i][0] = + gs_stagesurface_create_nv12(ovi->output_width, + ovi->output_height); + if (!video->copy_surfaces[i][0]) return false; } else { #endif - video->copy_surfaces[i] = gs_stagesurface_create( - ovi->output_width, output_height, - GS_RGBA); - if (!video->copy_surfaces[i]) - return false; + if (video->gpu_conversion) { + if (!obs_init_gpu_copy_surfaces(ovi, i)) + return false; + } else { + video->copy_surfaces[i][0] = + gs_stagesurface_create( + ovi->output_width, + ovi->output_height, GS_RGBA); + if (!video->copy_surfaces[i][0]) + return false; + } #ifdef _WIN32 } #endif - - video->render_textures[i] = gs_texture_create( - ovi->base_width, ovi->base_height, - GS_RGBA, 1, NULL, GS_RENDER_TARGET); - - if (!video->render_textures[i]) - return false; - - video->output_textures[i] = gs_texture_create( - ovi->output_width, ovi->output_height, - GS_RGBA, 1, NULL, GS_RENDER_TARGET); - - if (!video->output_textures[i]) - return false; } + video->render_texture = gs_texture_create(ovi->base_width, + ovi->base_height, GS_RGBA, 1, + NULL, GS_RENDER_TARGET); + + if (!video->render_texture) + return false; + + video->output_texture = gs_texture_create(ovi->output_width, + ovi->output_height, GS_RGBA, + 1, NULL, GS_RENDER_TARGET); + + if (!video->output_texture) + return false; + return true; } @@ -266,14 +257,14 @@ gs_effect_t *obs_load_effect(gs_effect_t **effect, const char *file) static int obs_init_graphics(struct obs_video_info *ovi) { struct obs_core_video *video = &obs->video; - uint8_t transparent_tex_data[2*2*4] = {0}; + uint8_t transparent_tex_data[2 * 2 * 4] = {0}; const uint8_t *transparent_tex = transparent_tex_data; struct gs_sampler_info point_sampler = {0}; bool success = true; int errorcode; - errorcode = gs_create(&video->graphics, ovi->graphics_module, - ovi->adapter); + errorcode = + gs_create(&video->graphics, ovi->graphics_module, ovi->adapter); if (errorcode != GS_SUCCESS) { switch (errorcode) { case GS_ERROR_MODULE_NOT_FOUND: @@ -288,67 +279,59 @@ static int obs_init_graphics(struct obs_video_info *ovi) gs_enter_context(video->graphics); char *filename = obs_find_data_file("default.effect"); - video->default_effect = gs_effect_create_from_file(filename, - NULL); + video->default_effect = gs_effect_create_from_file(filename, NULL); bfree(filename); if (gs_get_device_type() == GS_DEVICE_OPENGL) { filename = obs_find_data_file("default_rect.effect"); - video->default_rect_effect = gs_effect_create_from_file( - filename, NULL); + video->default_rect_effect = + gs_effect_create_from_file(filename, NULL); bfree(filename); } filename = obs_find_data_file("opaque.effect"); - video->opaque_effect = gs_effect_create_from_file(filename, - NULL); + video->opaque_effect = gs_effect_create_from_file(filename, NULL); bfree(filename); filename = obs_find_data_file("solid.effect"); - video->solid_effect = gs_effect_create_from_file(filename, - NULL); + video->solid_effect = gs_effect_create_from_file(filename, NULL); bfree(filename); filename = obs_find_data_file("repeat.effect"); - video->repeat_effect = gs_effect_create_from_file(filename, - NULL); + video->repeat_effect = gs_effect_create_from_file(filename, NULL); bfree(filename); filename = obs_find_data_file("format_conversion.effect"); - video->conversion_effect = gs_effect_create_from_file(filename, - NULL); + video->conversion_effect = gs_effect_create_from_file(filename, NULL); bfree(filename); filename = obs_find_data_file("bicubic_scale.effect"); - video->bicubic_effect = gs_effect_create_from_file(filename, - NULL); + video->bicubic_effect = gs_effect_create_from_file(filename, NULL); bfree(filename); filename = obs_find_data_file("lanczos_scale.effect"); - video->lanczos_effect = gs_effect_create_from_file(filename, - NULL); + video->lanczos_effect = gs_effect_create_from_file(filename, NULL); bfree(filename); filename = obs_find_data_file("area.effect"); - video->area_effect = gs_effect_create_from_file(filename, - NULL); + video->area_effect = gs_effect_create_from_file(filename, NULL); bfree(filename); filename = obs_find_data_file("bilinear_lowres_scale.effect"); - video->bilinear_lowres_effect = gs_effect_create_from_file(filename, - NULL); + video->bilinear_lowres_effect = + gs_effect_create_from_file(filename, NULL); bfree(filename); filename = obs_find_data_file("premultiplied_alpha.effect"); - video->premultiplied_alpha_effect = gs_effect_create_from_file(filename, - NULL); + video->premultiplied_alpha_effect = + gs_effect_create_from_file(filename, NULL); bfree(filename); point_sampler.max_anisotropy = 1; video->point_sampler = gs_samplerstate_create(&point_sampler); - obs->video.transparent_texture = gs_texture_create(2, 2, GS_RGBA, 1, - &transparent_tex, 0); + obs->video.transparent_texture = + gs_texture_create(2, 2, GS_RGBA, 1, &transparent_tex, 0); if (!video->default_effect) success = false; @@ -374,14 +357,14 @@ static int obs_init_graphics(struct obs_video_info *ovi) } static inline void set_video_matrix(struct obs_core_video *video, - struct obs_video_info *ovi) + struct obs_video_info *ovi) { struct matrix4 mat; struct vec4 r_row; if (format_is_yuv(ovi->output_format)) { video_format_get_parameters(ovi->colorspace, ovi->range, - (float*)&mat, NULL, NULL); + (float *)&mat, NULL, NULL); matrix4_inv(&mat, &mat); /* swap R and G */ @@ -403,12 +386,12 @@ static int obs_init_video(struct obs_video_info *ovi) int errorcode; make_video_info(&vi, ovi); - video->base_width = ovi->base_width; - video->base_height = ovi->base_height; - video->output_width = ovi->output_width; - video->output_height = ovi->output_height; + video->base_width = ovi->base_width; + video->base_height = ovi->base_height; + video->output_width = ovi->output_width; + video->output_height = ovi->output_height; video->gpu_conversion = ovi->gpu_conversion; - video->scale_type = ovi->scale_type; + video->scale_type = ovi->scale_type; set_video_matrix(video, ovi); @@ -441,7 +424,7 @@ static int obs_init_video(struct obs_video_info *ovi) return OBS_VIDEO_FAIL; errorcode = pthread_create(&video->video_thread, NULL, - obs_graphics_thread, obs); + obs_graphics_thread, obs); if (errorcode != 0) return OBS_VIDEO_FAIL; @@ -462,7 +445,6 @@ static void stop_video(void) video->thread_initialized = false; } } - } static void obs_free_video(void) @@ -478,38 +460,58 @@ static void obs_free_video(void) gs_enter_context(video->graphics); - if (video->mapped_surface) { - gs_stagesurface_unmap(video->mapped_surface); - video->mapped_surface = NULL; + for (size_t c = 0; c < NUM_CHANNELS; c++) { + if (video->mapped_surfaces[c]) { + gs_stagesurface_unmap( + video->mapped_surfaces[c]); + video->mapped_surfaces[c] = NULL; + } } for (size_t i = 0; i < NUM_TEXTURES; i++) { - gs_stagesurface_destroy(video->copy_surfaces[i]); - gs_texture_destroy(video->render_textures[i]); - gs_texture_destroy(video->convert_textures[i]); - gs_texture_destroy(video->convert_uv_textures[i]); - gs_texture_destroy(video->output_textures[i]); - - video->copy_surfaces[i] = NULL; - video->render_textures[i] = NULL; - video->convert_textures[i] = NULL; - video->convert_uv_textures[i] = NULL; - video->output_textures[i] = NULL; + for (size_t c = 0; c < NUM_CHANNELS; c++) { + if (video->copy_surfaces[i][c]) { + gs_stagesurface_destroy( + video->copy_surfaces[i][c]); + video->copy_surfaces[i][c] = NULL; + } + } } + gs_texture_destroy(video->render_texture); + + for (size_t c = 0; c < NUM_CHANNELS; c++) { + if (video->convert_textures[c]) { + gs_texture_destroy(video->convert_textures[c]); + video->convert_textures[c] = NULL; + } + } + + for (size_t i = 0; i < NUM_TEXTURES; i++) { + for (size_t c = 0; c < NUM_CHANNELS; c++) { + if (video->copy_surfaces[i][c]) { + gs_stagesurface_destroy( + video->copy_surfaces[i][c]); + video->copy_surfaces[i][c] = NULL; + } + } + } + + gs_texture_destroy(video->output_texture); + video->render_texture = NULL; + video->output_texture = NULL; + gs_leave_context(); circlebuf_free(&video->vframe_info_buffer); circlebuf_free(&video->vframe_info_buffer_gpu); - memset(&video->textures_rendered, 0, - sizeof(video->textures_rendered)); - memset(&video->textures_output, 0, - sizeof(video->textures_output)); - memset(&video->textures_copied, 0, - sizeof(video->textures_copied)); - memset(&video->textures_converted, 0, - sizeof(video->textures_converted)); + video->texture_rendered = false; + ; + memset(video->textures_copied, 0, + sizeof(video->textures_copied)); + video->texture_converted = false; + ; pthread_mutex_destroy(&video->gpu_encoder_mutex); pthread_mutex_init_value(&video->gpu_encoder_mutex); @@ -566,7 +568,7 @@ static bool obs_init_audio(struct audio_output_info *ai) if (pthread_mutex_init(&audio->monitoring_mutex, &attr) != 0) return false; - audio->user_volume = 1.0f; + audio->user_volume = 1.0f; audio->monitoring_device_name = bstrdup("Default"); audio->monitoring_device_id = bstrdup("default"); @@ -641,7 +643,8 @@ fail: void obs_main_view_free(struct obs_view *view) { - if (!view) return; + if (!view) + return; for (size_t i = 0; i < MAX_CHANNELS; i++) obs_source_release(view->channels[i]); @@ -650,16 +653,16 @@ void obs_main_view_free(struct obs_view *view) pthread_mutex_destroy(&view->channels_mutex); } -#define FREE_OBS_LINKED_LIST(type) \ - do { \ - int unfreed = 0; \ - while (data->first_ ## type ) { \ - obs_ ## type ## _destroy(data->first_ ## type ); \ - unfreed++; \ - } \ - if (unfreed) \ +#define FREE_OBS_LINKED_LIST(type) \ + do { \ + int unfreed = 0; \ + while (data->first_##type) { \ + obs_##type##_destroy(data->first_##type); \ + unfreed++; \ + } \ + if (unfreed) \ blog(LOG_INFO, "\t%d " #type "(s) were remaining", \ - unfreed); \ + unfreed); \ } while (false) static void obs_free_data(void) @@ -700,10 +703,12 @@ static const char *obs_signals[] = { "void source_deactivate(ptr source)", "void source_show(ptr source)", "void source_hide(ptr source)", + "void source_audio_activate(ptr source)", + "void source_audio_deactivate(ptr source)", "void source_rename(ptr source, string new_name, string prev_name)", "void source_volume(ptr source, in out float volume)", "void source_volume_level(ptr source, float level, float magnitude, " - "float peak)", + "float peak)", "void source_transition_start(ptr source)", "void source_transition_video_stop(ptr source)", "void source_transition_stop(ptr source)", @@ -716,7 +721,7 @@ static const char *obs_signals[] = { "void hotkey_unregister(ptr hotkey)", "void hotkey_bindings_changed(ptr hotkey)", - NULL + NULL, }; static inline bool obs_init_handlers(void) @@ -725,7 +730,7 @@ static inline bool obs_init_handlers(void) if (!obs->signals) return false; - obs->procs = proc_handler_create(); + obs->procs = proc_handler_create(); if (!obs->procs) return false; @@ -763,8 +768,8 @@ static inline bool obs_init_hotkeys(void) if (os_event_init(&hotkeys->stop_event, OS_EVENT_TYPE_MANUAL) != 0) goto fail; - if (pthread_create(&hotkeys->hotkey_thread, NULL, - obs_hotkey_thread, NULL)) + if (pthread_create(&hotkeys->hotkey_thread, NULL, obs_hotkey_thread, + NULL)) goto fail; hotkeys->hotkey_thread_initialized = true; @@ -811,10 +816,24 @@ static inline void obs_free_hotkeys(void) extern const struct obs_source_info scene_info; extern const struct obs_source_info group_info; +static const char *submix_name(void *unused) +{ + UNUSED_PARAMETER(unused); + return "Audio line (internal use only)"; +} + +const struct obs_source_info audio_line_info = { + .id = "audio_line", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_AUDIO | OBS_SOURCE_CAP_DISABLED | + OBS_SOURCE_SUBMIX, + .get_name = submix_name, +}; + extern void log_system_info(void); static bool obs_init(const char *locale, const char *module_config_path, - profiler_name_store_t *store) + profiler_name_store_t *store) { obs = bzalloc(sizeof(struct obs_core)); @@ -842,6 +861,7 @@ static bool obs_init(const char *locale, const char *module_config_path, obs->locale = bstrdup(locale); obs_register_source(&scene_info); obs_register_source(&group_info); + obs_register_source(&audio_line_info); add_default_module_paths(); return true; } @@ -897,7 +917,7 @@ bool obs_remove_data_path(const char *path) static const char *obs_startup_name = "obs_startup"; bool obs_startup(const char *locale, const char *module_config_path, - profiler_name_store_t *store) + profiler_name_store_t *store) { bool success; @@ -921,7 +941,7 @@ bool obs_startup(const char *locale, const char *module_config_path, } static struct obs_cmdline_args cmdline_args = {0, NULL}; -void obs_set_cmdline_args(int argc, const char * const *argv) +void obs_set_cmdline_args(int argc, const char *const *argv) { char *data; size_t len; @@ -939,7 +959,7 @@ void obs_set_cmdline_args(int argc, const char * const *argv) len += strlen(argv[i]) + 1; cmdline_args.argv = bmalloc(sizeof(char *) * (argc + 1) + len); - data = (char *) cmdline_args.argv + sizeof(char *) * (argc + 1); + data = (char *)cmdline_args.argv + sizeof(char *) * (argc + 1); for (i = 0; i < argc; i++) { cmdline_args.argv[i] = data; @@ -964,14 +984,14 @@ void obs_shutdown(void) if (!obs) return; -#define FREE_REGISTERED_TYPES(structure, list) \ - do { \ - for (size_t i = 0; i < list.num; i++) { \ - struct structure *item = &list.array[i]; \ - if (item->type_data && item->free_type_data) \ +#define FREE_REGISTERED_TYPES(structure, list) \ + do { \ + for (size_t i = 0; i < list.num; i++) { \ + struct structure *item = &list.array[i]; \ + if (item->type_data && item->free_type_data) \ item->free_type_data(item->type_data); \ - } \ - da_free(list); \ + } \ + da_free(list); \ } while (false) FREE_REGISTERED_TYPES(obs_source_info, obs->source_types); @@ -1012,7 +1032,7 @@ void obs_shutdown(void) core->first_module = NULL; for (size_t i = 0; i < core->module_paths.num; i++) - free_module_path(core->module_paths.array+i); + free_module_path(core->module_paths.array + i); da_free(core->module_paths); if (core->name_store_owned) @@ -1073,19 +1093,20 @@ const char *obs_get_locale(void) static inline bool size_valid(uint32_t width, uint32_t height) { return (width >= OBS_SIZE_MIN && height >= OBS_SIZE_MIN && - width <= OBS_SIZE_MAX && height <= OBS_SIZE_MAX); + width <= OBS_SIZE_MAX && height <= OBS_SIZE_MAX); } int obs_reset_video(struct obs_video_info *ovi) { - if (!obs) return OBS_VIDEO_FAIL; + if (!obs) + return OBS_VIDEO_FAIL; /* don't allow changing of video settings if active. */ if (obs->video.video && obs_video_active()) return OBS_VIDEO_CURRENTLY_ACTIVE; if (!size_valid(ovi->output_width, ovi->output_height) || - !size_valid(ovi->base_width, ovi->base_height)) + !size_valid(ovi->base_width, ovi->base_height)) return OBS_VIDEO_INVALID_PARAM; struct obs_core_video *video = &obs->video; @@ -1094,7 +1115,7 @@ int obs_reset_video(struct obs_video_info *ovi) obs_free_video(); /* align to multiple-of-two and SSE alignment sizes */ - ovi->output_width &= 0xFFFFFFFC; + ovi->output_width &= 0xFFFFFFFC; ovi->output_height &= 0xFFFFFFFE; if (!video->graphics) { @@ -1129,25 +1150,22 @@ int obs_reset_video(struct obs_video_info *ovi) bool yuv = format_is_yuv(ovi->output_format); const char *yuv_format = get_video_colorspace_name(ovi->colorspace); - const char *yuv_range = get_video_range_name(ovi->output_format, - ovi->range); + const char *yuv_range = + get_video_range_name(ovi->output_format, ovi->range); blog(LOG_INFO, "---------------------------------"); - blog(LOG_INFO, "video settings reset:\n" - "\tbase resolution: %dx%d\n" - "\toutput resolution: %dx%d\n" - "\tdownscale filter: %s\n" - "\tfps: %d/%d\n" - "\tformat: %s\n" - "\tYUV mode: %s%s%s", - ovi->base_width, ovi->base_height, - ovi->output_width, ovi->output_height, - scale_type_name, - ovi->fps_num, ovi->fps_den, - get_video_format_name(ovi->output_format), - yuv ? yuv_format : "None", - yuv ? "/" : "", - yuv ? yuv_range : ""); + blog(LOG_INFO, + "video settings reset:\n" + "\tbase resolution: %dx%d\n" + "\toutput resolution: %dx%d\n" + "\tdownscale filter: %s\n" + "\tfps: %d/%d\n" + "\tformat: %s\n" + "\tYUV mode: %s%s%s", + ovi->base_width, ovi->base_height, ovi->output_width, + ovi->output_height, scale_type_name, ovi->fps_num, ovi->fps_den, + get_video_format_name(ovi->output_format), + yuv ? yuv_format : "None", yuv ? "/" : "", yuv ? yuv_range : ""); return obs_init_video(ovi); } @@ -1156,7 +1174,8 @@ bool obs_reset_audio(const struct obs_audio_info *oai) { struct audio_output_info ai; - if (!obs) return false; + if (!obs) + return false; /* don't allow changing of audio settings if active. */ if (obs->audio.audio && audio_output_active(obs->audio.audio)) @@ -1173,11 +1192,11 @@ bool obs_reset_audio(const struct obs_audio_info *oai) ai.input_callback = audio_callback; blog(LOG_INFO, "---------------------------------"); - blog(LOG_INFO, "audio settings reset:\n" - "\tsamples per sec: %d\n" - "\tspeakers: %d", - (int)ai.samples_per_sec, - (int)ai.speakers); + blog(LOG_INFO, + "audio settings reset:\n" + "\tsamples per sec: %d\n" + "\tspeakers: %d", + (int)ai.samples_per_sec, (int)ai.speakers); return obs_init_audio(&ai); } @@ -1210,7 +1229,8 @@ bool obs_get_audio_info(struct obs_audio_info *oai) bool obs_enum_source_types(size_t idx, const char **id) { - if (!obs) return false; + if (!obs) + return false; if (idx >= obs->source_types.num) return false; @@ -1220,7 +1240,8 @@ bool obs_enum_source_types(size_t idx, const char **id) bool obs_enum_input_types(size_t idx, const char **id) { - if (!obs) return false; + if (!obs) + return false; if (idx >= obs->input_types.num) return false; @@ -1230,7 +1251,8 @@ bool obs_enum_input_types(size_t idx, const char **id) bool obs_enum_filter_types(size_t idx, const char **id) { - if (!obs) return false; + if (!obs) + return false; if (idx >= obs->filter_types.num) return false; @@ -1240,7 +1262,8 @@ bool obs_enum_filter_types(size_t idx, const char **id) bool obs_enum_transition_types(size_t idx, const char **id) { - if (!obs) return false; + if (!obs) + return false; if (idx >= obs->transition_types.num) return false; @@ -1250,7 +1273,8 @@ bool obs_enum_transition_types(size_t idx, const char **id) bool obs_enum_output_types(size_t idx, const char **id) { - if (!obs) return false; + if (!obs) + return false; if (idx >= obs->output_types.num) return false; @@ -1260,7 +1284,8 @@ bool obs_enum_output_types(size_t idx, const char **id) bool obs_enum_encoder_types(size_t idx, const char **id) { - if (!obs) return false; + if (!obs) + return false; if (idx >= obs->encoder_types.num) return false; @@ -1270,7 +1295,8 @@ bool obs_enum_encoder_types(size_t idx, const char **id) bool obs_enum_service_types(size_t idx, const char **id) { - if (!obs) return false; + if (!obs) + return false; if (idx >= obs->service_types.num) return false; @@ -1301,14 +1327,15 @@ video_t *obs_get_video(void) } /* TODO: optimize this later so it's not just O(N) string lookups */ -static inline struct obs_modal_ui *get_modal_ui_callback(const char *id, - const char *task, const char *target) +static inline struct obs_modal_ui * +get_modal_ui_callback(const char *id, const char *task, const char *target) { for (size_t i = 0; i < obs->modal_ui_callbacks.num; i++) { - struct obs_modal_ui *callback = obs->modal_ui_callbacks.array+i; + struct obs_modal_ui *callback = + obs->modal_ui_callbacks.array + i; - if (strcmp(callback->id, id) == 0 && - strcmp(callback->task, task) == 0 && + if (strcmp(callback->id, id) == 0 && + strcmp(callback->task, task) == 0 && strcmp(callback->target, target) == 0) return callback; } @@ -1316,15 +1343,15 @@ static inline struct obs_modal_ui *get_modal_ui_callback(const char *id, return NULL; } -static inline struct obs_modeless_ui *get_modeless_ui_callback(const char *id, - const char *task, const char *target) +static inline struct obs_modeless_ui * +get_modeless_ui_callback(const char *id, const char *task, const char *target) { for (size_t i = 0; i < obs->modeless_ui_callbacks.num; i++) { struct obs_modeless_ui *callback; - callback = obs->modeless_ui_callbacks.array+i; + callback = obs->modeless_ui_callbacks.array + i; - if (strcmp(callback->id, id) == 0 && - strcmp(callback->task, task) == 0 && + if (strcmp(callback->id, id) == 0 && + strcmp(callback->task, task) == 0 && strcmp(callback->target, target) == 0) return callback; } @@ -1338,7 +1365,8 @@ int obs_exec_ui(const char *name, const char *task, const char *target, struct obs_modal_ui *callback; int errorcode = OBS_UI_NOTFOUND; - if (!obs) return errorcode; + if (!obs) + return errorcode; callback = get_modal_ui_callback(name, task, target); if (callback) { @@ -1350,11 +1378,12 @@ int obs_exec_ui(const char *name, const char *task, const char *target, } void *obs_create_ui(const char *name, const char *task, const char *target, - void *data, void *ui_data) + void *data, void *ui_data) { struct obs_modeless_ui *callback; - if (!obs) return NULL; + if (!obs) + return NULL; callback = get_modeless_ui_callback(name, task, target); return callback ? callback->create(data, ui_data) : NULL; @@ -1362,7 +1391,8 @@ void *obs_create_ui(const char *name, const char *task, const char *target, obs_source_t *obs_get_output_source(uint32_t channel) { - if (!obs) return NULL; + if (!obs) + return NULL; return obs_view_get_source(&obs->data.main_view, channel); } @@ -1370,8 +1400,10 @@ void obs_set_output_source(uint32_t channel, obs_source_t *source) { assert(channel < MAX_CHANNELS); - if (!obs) return; - if (channel >= MAX_CHANNELS) return; + if (!obs) + return; + if (channel >= MAX_CHANNELS) + return; struct obs_source *prev_source; struct obs_view *view = &obs->data.main_view; @@ -1403,25 +1435,26 @@ void obs_set_output_source(uint32_t channel, obs_source_t *source) } } -void obs_enum_sources(bool (*enum_proc)(void*, obs_source_t*), void *param) +void obs_enum_sources(bool (*enum_proc)(void *, obs_source_t *), void *param) { obs_source_t *source; - if (!obs) return; + if (!obs) + return; pthread_mutex_lock(&obs->data.sources_mutex); source = obs->data.first_source; while (source) { obs_source_t *next_source = - (obs_source_t*)source->context.next; + (obs_source_t *)source->context.next; if (source->info.id == group_info.id && !enum_proc(param, source)) { break; } else if (source->info.type == OBS_SOURCE_TYPE_INPUT && - !source->context.private && - !enum_proc(param, source)) { + !source->context.private && + !enum_proc(param, source)) { break; } @@ -1431,22 +1464,22 @@ void obs_enum_sources(bool (*enum_proc)(void*, obs_source_t*), void *param) pthread_mutex_unlock(&obs->data.sources_mutex); } -void obs_enum_scenes(bool (*enum_proc)(void*, obs_source_t*), void *param) +void obs_enum_scenes(bool (*enum_proc)(void *, obs_source_t *), void *param) { obs_source_t *source; - if (!obs) return; + if (!obs) + return; pthread_mutex_lock(&obs->data.sources_mutex); source = obs->data.first_source; while (source) { obs_source_t *next_source = - (obs_source_t*)source->context.next; + (obs_source_t *)source->context.next; if (source->info.type == OBS_SOURCE_TYPE_SCENE && - !source->context.private && - !enum_proc(param, source)) { + !source->context.private && !enum_proc(param, source)) { break; } @@ -1457,10 +1490,10 @@ void obs_enum_scenes(bool (*enum_proc)(void*, obs_source_t*), void *param) } static inline void obs_enum(void *pstart, pthread_mutex_t *mutex, void *proc, - void *param) + void *param) { struct obs_context_data **start = pstart, *context; - bool (*enum_proc)(void*, void*) = proc; + bool (*enum_proc)(void *, void *) = proc; assert(start); assert(mutex); @@ -1479,29 +1512,33 @@ static inline void obs_enum(void *pstart, pthread_mutex_t *mutex, void *proc, pthread_mutex_unlock(mutex); } -void obs_enum_outputs(bool (*enum_proc)(void*, obs_output_t*), void *param) +void obs_enum_outputs(bool (*enum_proc)(void *, obs_output_t *), void *param) { - if (!obs) return; - obs_enum(&obs->data.first_output, &obs->data.outputs_mutex, - enum_proc, param); + if (!obs) + return; + obs_enum(&obs->data.first_output, &obs->data.outputs_mutex, enum_proc, + param); } -void obs_enum_encoders(bool (*enum_proc)(void*, obs_encoder_t*), void *param) +void obs_enum_encoders(bool (*enum_proc)(void *, obs_encoder_t *), void *param) { - if (!obs) return; - obs_enum(&obs->data.first_encoder, &obs->data.encoders_mutex, - enum_proc, param); + if (!obs) + return; + obs_enum(&obs->data.first_encoder, &obs->data.encoders_mutex, enum_proc, + param); } -void obs_enum_services(bool (*enum_proc)(void*, obs_service_t*), void *param) +void obs_enum_services(bool (*enum_proc)(void *, obs_service_t *), void *param) { - if (!obs) return; - obs_enum(&obs->data.first_service, &obs->data.services_mutex, - enum_proc, param); + if (!obs) + return; + obs_enum(&obs->data.first_service, &obs->data.services_mutex, enum_proc, + param); } static inline void *get_context_by_name(void *vfirst, const char *name, - pthread_mutex_t *mutex, void *(*addref)(void*)) + pthread_mutex_t *mutex, + void *(*addref)(void *)) { struct obs_context_data **first = vfirst; struct obs_context_data *context; @@ -1548,35 +1585,44 @@ static inline void *obs_id_(void *data) obs_source_t *obs_get_source_by_name(const char *name) { - if (!obs) return NULL; + if (!obs) + return NULL; return get_context_by_name(&obs->data.first_source, name, - &obs->data.sources_mutex, obs_source_addref_safe_); + &obs->data.sources_mutex, + obs_source_addref_safe_); } obs_output_t *obs_get_output_by_name(const char *name) { - if (!obs) return NULL; + if (!obs) + return NULL; return get_context_by_name(&obs->data.first_output, name, - &obs->data.outputs_mutex, obs_output_addref_safe_); + &obs->data.outputs_mutex, + obs_output_addref_safe_); } obs_encoder_t *obs_get_encoder_by_name(const char *name) { - if (!obs) return NULL; + if (!obs) + return NULL; return get_context_by_name(&obs->data.first_encoder, name, - &obs->data.encoders_mutex, obs_encoder_addref_safe_); + &obs->data.encoders_mutex, + obs_encoder_addref_safe_); } obs_service_t *obs_get_service_by_name(const char *name) { - if (!obs) return NULL; + if (!obs) + return NULL; return get_context_by_name(&obs->data.first_service, name, - &obs->data.services_mutex, obs_service_addref_safe_); + &obs->data.services_mutex, + obs_service_addref_safe_); } gs_effect_t *obs_get_base_effect(enum obs_base_effect effect) { - if (!obs) return NULL; + if (!obs) + return NULL; switch (effect) { case OBS_EFFECT_DEFAULT: @@ -1607,52 +1653,56 @@ gs_effect_t *obs_get_base_effect(enum obs_base_effect effect) /* DEPRECATED */ gs_effect_t *obs_get_default_rect_effect(void) { - if (!obs) return NULL; + if (!obs) + return NULL; return obs->video.default_rect_effect; } signal_handler_t *obs_get_signal_handler(void) { - if (!obs) return NULL; + if (!obs) + return NULL; return obs->signals; } proc_handler_t *obs_get_proc_handler(void) { - if (!obs) return NULL; + if (!obs) + return NULL; return obs->procs; } void obs_render_main_view(void) { - if (!obs) return; + if (!obs) + return; obs_view_render(&obs->data.main_view); } -void obs_render_main_texture(void) +static void obs_render_main_texture_internal(enum gs_blend_type src_c, + enum gs_blend_type dest_c, + enum gs_blend_type src_a, + enum gs_blend_type dest_a) { - struct obs_core_video *video = &obs->video; + struct obs_core_video *video; gs_texture_t *tex; gs_effect_t *effect; gs_eparam_t *param; - int last_tex; - if (!obs) return; - - last_tex = video->cur_texture == 0 - ? NUM_TEXTURES - 1 - : video->cur_texture - 1; - - if (!video->textures_rendered[last_tex]) + if (!obs) return; - tex = video->render_textures[last_tex]; + video = &obs->video; + if (!video->texture_rendered) + return; + + tex = video->render_texture; effect = obs_get_base_effect(OBS_EFFECT_DEFAULT); param = gs_effect_get_param_by_name(effect, "image"); gs_effect_set_texture(param, tex); gs_blend_state_push(); - gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); + gs_blend_function_separate(src_c, dest_c, src_a, dest_a); while (gs_effect_loop(effect, "Draw")) gs_draw_sprite(tex, 0, 0, 0); @@ -1660,28 +1710,38 @@ void obs_render_main_texture(void) gs_blend_state_pop(); } +void obs_render_main_texture(void) +{ + obs_render_main_texture_internal(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA, + GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); +} + +void obs_render_main_texture_src_color_only(void) +{ + obs_render_main_texture_internal(GS_BLEND_ONE, GS_BLEND_ZERO, + GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); +} + gs_texture_t *obs_get_main_texture(void) { - struct obs_core_video *video = &obs->video; - int last_tex; + struct obs_core_video *video; - if (!obs) return NULL; - - last_tex = video->cur_texture == 0 - ? NUM_TEXTURES - 1 - : video->cur_texture - 1; - - if (!video->textures_rendered[last_tex]) + if (!obs) return NULL; - return video->render_textures[last_tex]; + video = &obs->video; + if (!video->texture_rendered) + return NULL; + + return video->render_texture; } void obs_set_master_volume(float volume) { struct calldata data = {0}; - if (!obs) return; + if (!obs) + return; calldata_set_float(&data, "volume", volume); signal_handler_signal(obs->signals, "master_volume", &data); @@ -1700,23 +1760,30 @@ static obs_source_t *obs_load_source_type(obs_data_t *source_data) { obs_data_array_t *filters = obs_data_get_array(source_data, "filters"); obs_source_t *source; - const char *name = obs_data_get_string(source_data, "name"); - const char *id = obs_data_get_string(source_data, "id"); - obs_data_t *settings = obs_data_get_obj(source_data, "settings"); - obs_data_t *hotkeys = obs_data_get_obj(source_data, "hotkeys"); - double volume; - double balance; - int64_t sync; - uint32_t flags; - uint32_t mixers; - int di_order; - int di_mode; - int monitoring_type; + const char *name = obs_data_get_string(source_data, "name"); + const char *id = obs_data_get_string(source_data, "id"); + obs_data_t *settings = obs_data_get_obj(source_data, "settings"); + obs_data_t *hotkeys = obs_data_get_obj(source_data, "hotkeys"); + double volume; + double balance; + int64_t sync; + uint32_t prev_ver; + uint32_t caps; + uint32_t flags; + uint32_t mixers; + int di_order; + int di_mode; + int monitoring_type; - source = obs_source_create(id, name, settings, hotkeys); + prev_ver = (uint32_t)obs_data_get_int(source_data, "prev_ver"); + + source = obs_source_create_set_last_ver(id, name, settings, hotkeys, + prev_ver); obs_data_release(hotkeys); + caps = obs_source_get_output_flags(source); + obs_data_set_default_double(source_data, "volume", 1.0); volume = obs_data_get_double(source_data, "volume"); obs_source_set_volume(source, (float)volume); @@ -1728,7 +1795,7 @@ static obs_source_t *obs_load_source_type(obs_data_t *source_data) sync = obs_data_get_int(source_data, "sync"); obs_source_set_sync_offset(source, sync); - obs_data_set_default_int(source_data, "mixers", 0xF); + obs_data_set_default_int(source_data, "mixers", 0x3F); mixers = (uint32_t)obs_data_get_int(source_data, "mixers"); obs_source_set_audio_mixers(source, mixers); @@ -1738,38 +1805,48 @@ static obs_source_t *obs_load_source_type(obs_data_t *source_data) obs_data_set_default_bool(source_data, "enabled", true); obs_source_set_enabled(source, - obs_data_get_bool(source_data, "enabled")); + obs_data_get_bool(source_data, "enabled")); obs_data_set_default_bool(source_data, "muted", false); obs_source_set_muted(source, obs_data_get_bool(source_data, "muted")); obs_data_set_default_bool(source_data, "push-to-mute", false); - obs_source_enable_push_to_mute(source, - obs_data_get_bool(source_data, "push-to-mute")); + obs_source_enable_push_to_mute( + source, obs_data_get_bool(source_data, "push-to-mute")); obs_data_set_default_int(source_data, "push-to-mute-delay", 0); - obs_source_set_push_to_mute_delay(source, - obs_data_get_int(source_data, "push-to-mute-delay")); + obs_source_set_push_to_mute_delay( + source, obs_data_get_int(source_data, "push-to-mute-delay")); obs_data_set_default_bool(source_data, "push-to-talk", false); - obs_source_enable_push_to_talk(source, - obs_data_get_bool(source_data, "push-to-talk")); + obs_source_enable_push_to_talk( + source, obs_data_get_bool(source_data, "push-to-talk")); obs_data_set_default_int(source_data, "push-to-talk-delay", 0); - obs_source_set_push_to_talk_delay(source, - obs_data_get_int(source_data, "push-to-talk-delay")); + obs_source_set_push_to_talk_delay( + source, obs_data_get_int(source_data, "push-to-talk-delay")); di_mode = (int)obs_data_get_int(source_data, "deinterlace_mode"); obs_source_set_deinterlace_mode(source, - (enum obs_deinterlace_mode)di_mode); + (enum obs_deinterlace_mode)di_mode); - di_order = (int)obs_data_get_int(source_data, "deinterlace_field_order"); - obs_source_set_deinterlace_field_order(source, - (enum obs_deinterlace_field_order)di_order); + di_order = + (int)obs_data_get_int(source_data, "deinterlace_field_order"); + obs_source_set_deinterlace_field_order( + source, (enum obs_deinterlace_field_order)di_order); monitoring_type = (int)obs_data_get_int(source_data, "monitoring_type"); - obs_source_set_monitoring_type(source, - (enum obs_monitoring_type)monitoring_type); + if (prev_ver < MAKE_SEMANTIC_VERSION(23, 2, 2)) { + if ((caps & OBS_SOURCE_MONITOR_BY_DEFAULT) != 0) { + /* updates older sources to enable monitoring + * automatically if they added monitoring by default in + * version 24 */ + monitoring_type = OBS_MONITORING_TYPE_MONITOR_ONLY; + obs_source_set_audio_mixers(source, 0x3F); + } + } + obs_source_set_monitoring_type( + source, (enum obs_monitoring_type)monitoring_type); obs_data_release(source->private_settings); source->private_settings = @@ -1784,8 +1861,8 @@ static obs_source_t *obs_load_source_type(obs_data_t *source_data) obs_data_t *filter_data = obs_data_array_item(filters, i); - obs_source_t *filter = obs_load_source_type( - filter_data); + obs_source_t *filter = + obs_load_source_type(filter_data); if (filter) { obs_source_filter_add(source, filter); obs_source_release(filter); @@ -1808,12 +1885,13 @@ obs_source_t *obs_load_source(obs_data_t *source_data) } void obs_load_sources(obs_data_array_t *array, obs_load_source_cb cb, - void *private_data) + void *private_data) { - if (!obs) return; + if (!obs) + return; struct obs_core_data *data = &obs->data; - DARRAY(obs_source_t*) sources; + DARRAY(obs_source_t *) sources; size_t count; size_t i; @@ -1825,8 +1903,8 @@ void obs_load_sources(obs_data_array_t *array, obs_load_source_cb cb, pthread_mutex_lock(&data->sources_mutex); for (i = 0; i < count; i++) { - obs_data_t *source_data = obs_data_array_item(array, i); - obs_source_t *source = obs_load_source(source_data); + obs_data_t *source_data = obs_data_array_item(array, i); + obs_source_t *source = obs_load_source(source_data); da_push_back(sources, &source); @@ -1864,26 +1942,25 @@ obs_data_t *obs_save_source(obs_source_t *source) { obs_data_array_t *filters = obs_data_array_create(); obs_data_t *source_data = obs_data_create(); - obs_data_t *settings = obs_source_get_settings(source); + obs_data_t *settings = obs_source_get_settings(source); obs_data_t *hotkey_data = source->context.hotkey_data; obs_data_t *hotkeys; - float volume = obs_source_get_volume(source); - float balance = obs_source_get_balance_value(source); - uint32_t mixers = obs_source_get_audio_mixers(source); - int64_t sync = obs_source_get_sync_offset(source); - uint32_t flags = obs_source_get_flags(source); - const char *name = obs_source_get_name(source); - const char *id = obs_source_get_id(source); - bool enabled = obs_source_enabled(source); - bool muted = obs_source_muted(source); - bool push_to_mute= obs_source_push_to_mute_enabled(source); - uint64_t ptm_delay = obs_source_get_push_to_mute_delay(source); - bool push_to_talk= obs_source_push_to_talk_enabled(source); - uint64_t ptt_delay = obs_source_get_push_to_talk_delay(source); - int m_type = (int)obs_source_get_monitoring_type(source); - int di_mode = (int)obs_source_get_deinterlace_mode(source); - int di_order = - (int)obs_source_get_deinterlace_field_order(source); + float volume = obs_source_get_volume(source); + float balance = obs_source_get_balance_value(source); + uint32_t mixers = obs_source_get_audio_mixers(source); + int64_t sync = obs_source_get_sync_offset(source); + uint32_t flags = obs_source_get_flags(source); + const char *name = obs_source_get_name(source); + const char *id = obs_source_get_id(source); + bool enabled = obs_source_enabled(source); + bool muted = obs_source_muted(source); + bool push_to_mute = obs_source_push_to_mute_enabled(source); + uint64_t ptm_delay = obs_source_get_push_to_mute_delay(source); + bool push_to_talk = obs_source_push_to_talk_enabled(source); + uint64_t ptt_delay = obs_source_get_push_to_talk_delay(source); + int m_type = (int)obs_source_get_monitoring_type(source); + int di_mode = (int)obs_source_get_deinterlace_mode(source); + int di_order = (int)obs_source_get_deinterlace_field_order(source); obs_source_save(source); hotkeys = obs_hotkeys_save_source(source); @@ -1894,27 +1971,29 @@ obs_data_t *obs_save_source(obs_source_t *source) hotkey_data = hotkeys; } - obs_data_set_string(source_data, "name", name); - obs_data_set_string(source_data, "id", id); - obs_data_set_obj (source_data, "settings", settings); - obs_data_set_int (source_data, "mixers", mixers); - obs_data_set_int (source_data, "sync", sync); - obs_data_set_int (source_data, "flags", flags); - obs_data_set_double(source_data, "volume", volume); - obs_data_set_double(source_data, "balance", balance); - obs_data_set_bool (source_data, "enabled", enabled); - obs_data_set_bool (source_data, "muted", muted); - obs_data_set_bool (source_data, "push-to-mute", push_to_mute); - obs_data_set_int (source_data, "push-to-mute-delay", ptm_delay); - obs_data_set_bool (source_data, "push-to-talk", push_to_talk); - obs_data_set_int (source_data, "push-to-talk-delay", ptt_delay); - obs_data_set_obj (source_data, "hotkeys", hotkey_data); - obs_data_set_int (source_data, "deinterlace_mode", di_mode); - obs_data_set_int (source_data, "deinterlace_field_order", di_order); - obs_data_set_int (source_data, "monitoring_type", m_type); + obs_data_set_int(source_data, "prev_ver", LIBOBS_API_VER); + + obs_data_set_string(source_data, "name", name); + obs_data_set_string(source_data, "id", id); + obs_data_set_obj(source_data, "settings", settings); + obs_data_set_int(source_data, "mixers", mixers); + obs_data_set_int(source_data, "sync", sync); + obs_data_set_int(source_data, "flags", flags); + obs_data_set_double(source_data, "volume", volume); + obs_data_set_double(source_data, "balance", balance); + obs_data_set_bool(source_data, "enabled", enabled); + obs_data_set_bool(source_data, "muted", muted); + obs_data_set_bool(source_data, "push-to-mute", push_to_mute); + obs_data_set_int(source_data, "push-to-mute-delay", ptm_delay); + obs_data_set_bool(source_data, "push-to-talk", push_to_talk); + obs_data_set_int(source_data, "push-to-talk-delay", ptt_delay); + obs_data_set_obj(source_data, "hotkeys", hotkey_data); + obs_data_set_int(source_data, "deinterlace_mode", di_mode); + obs_data_set_int(source_data, "deinterlace_field_order", di_order); + obs_data_set_int(source_data, "monitoring_type", m_type); obs_data_set_obj(source_data, "private_settings", - source->private_settings); + source->private_settings); if (source->info.type == OBS_SOURCE_TYPE_TRANSITION) obs_transition_save(source, source_data); @@ -1941,9 +2020,10 @@ obs_data_t *obs_save_source(obs_source_t *source) } obs_data_array_t *obs_save_sources_filtered(obs_save_source_filter_cb cb, - void *data_) + void *data_) { - if (!obs) return NULL; + if (!obs) + return NULL; struct obs_core_data *data = &obs->data; obs_data_array_t *array; @@ -1957,14 +2037,14 @@ obs_data_array_t *obs_save_sources_filtered(obs_save_source_filter_cb cb, while (source) { if ((source->info.type != OBS_SOURCE_TYPE_FILTER) != 0 && - !source->context.private && cb(data_, source)) { + !source->context.private && cb(data_, source)) { obs_data_t *source_data = obs_save_source(source); obs_data_array_push_back(array, source_data); obs_data_release(source_data); } - source = (obs_source_t*)source->context.next; + source = (obs_source_t *)source->context.next; } pthread_mutex_unlock(&data->sources_mutex); @@ -1993,7 +2073,7 @@ static inline char *dup_name(const char *name, bool private) if (!name || !*name) { struct dstr unnamed = {0}; dstr_printf(&unnamed, "__unnamed%04lld", - obs->data.unnamed_index++); + obs->data.unnamed_index++); return unnamed.array; } else { @@ -2001,13 +2081,12 @@ static inline char *dup_name(const char *name, bool private) } } -static inline bool obs_context_data_init_wrap( - struct obs_context_data *context, - enum obs_obj_type type, - obs_data_t *settings, - const char *name, - obs_data_t *hotkey_data, - bool private) +static inline bool obs_context_data_init_wrap(struct obs_context_data *context, + enum obs_obj_type type, + obs_data_t *settings, + const char *name, + obs_data_t *hotkey_data, + bool private) { assert(context); memset(context, 0, sizeof(*context)); @@ -2026,22 +2105,19 @@ static inline bool obs_context_data_init_wrap( if (!context->procs) return false; - context->name = dup_name(name, private); - context->settings = obs_data_newref(settings); + context->name = dup_name(name, private); + context->settings = obs_data_newref(settings); context->hotkey_data = obs_data_newref(hotkey_data); return true; } -bool obs_context_data_init( - struct obs_context_data *context, - enum obs_obj_type type, - obs_data_t *settings, - const char *name, - obs_data_t *hotkey_data, - bool private) +bool obs_context_data_init(struct obs_context_data *context, + enum obs_obj_type type, obs_data_t *settings, + const char *name, obs_data_t *hotkey_data, + bool private) { if (obs_context_data_init_wrap(context, type, settings, name, - hotkey_data, private)) { + hotkey_data, private)) { return true; } else { obs_context_data_free(context); @@ -2067,7 +2143,7 @@ void obs_context_data_free(struct obs_context_data *context) } void obs_context_data_insert(struct obs_context_data *context, - pthread_mutex_t *mutex, void *pfirst) + pthread_mutex_t *mutex, void *pfirst) { struct obs_context_data **first = pfirst; @@ -2078,9 +2154,9 @@ void obs_context_data_insert(struct obs_context_data *context, context->mutex = mutex; pthread_mutex_lock(mutex); - context->prev_next = first; - context->next = *first; - *first = context; + context->prev_next = first; + context->next = *first; + *first = context; if (context->next) context->next->prev_next = &context->next; pthread_mutex_unlock(mutex); @@ -2101,7 +2177,7 @@ void obs_context_data_remove(struct obs_context_data *context) } void obs_context_data_setname(struct obs_context_data *context, - const char *name) + const char *name) { pthread_mutex_lock(&context->rename_cache_mutex); @@ -2135,6 +2211,11 @@ uint64_t obs_get_average_frame_time_ns(void) return obs ? obs->video.video_avg_frame_time_ns : 0; } +uint64_t obs_get_frame_interval_ns(void) +{ + return obs ? obs->video.video_frame_interval_ns : 0; +} + enum obs_obj_type obs_obj_get_type(void *obj) { struct obs_context_data *context = obj; @@ -2148,10 +2229,14 @@ const char *obs_obj_get_id(void *obj) return NULL; switch (context->type) { - case OBS_OBJ_TYPE_SOURCE: return ((obs_source_t*)obj)->info.id; - case OBS_OBJ_TYPE_OUTPUT: return ((obs_output_t*)obj)->info.id; - case OBS_OBJ_TYPE_ENCODER: return ((obs_encoder_t*)obj)->info.id; - case OBS_OBJ_TYPE_SERVICE: return ((obs_service_t*)obj)->info.id; + case OBS_OBJ_TYPE_SOURCE: + return ((obs_source_t *)obj)->info.id; + case OBS_OBJ_TYPE_OUTPUT: + return ((obs_output_t *)obj)->info.id; + case OBS_OBJ_TYPE_ENCODER: + return ((obs_encoder_t *)obj)->info.id; + case OBS_OBJ_TYPE_SERVICE: + return ((obs_service_t *)obj)->info.id; default:; } @@ -2220,9 +2305,8 @@ void obs_get_audio_monitoring_device(const char **name, const char **id) *id = obs->audio.monitoring_device_id; } -void obs_add_tick_callback( - void (*tick)(void *param, float seconds), - void *param) +void obs_add_tick_callback(void (*tick)(void *param, float seconds), + void *param) { if (!obs) return; @@ -2234,9 +2318,8 @@ void obs_add_tick_callback( pthread_mutex_unlock(&obs->data.draw_callbacks_mutex); } -void obs_remove_tick_callback( - void (*tick)(void *param, float seconds), - void *param) +void obs_remove_tick_callback(void (*tick)(void *param, float seconds), + void *param) { if (!obs) return; @@ -2248,9 +2331,9 @@ void obs_remove_tick_callback( pthread_mutex_unlock(&obs->data.draw_callbacks_mutex); } -void obs_add_main_render_callback( - void (*draw)(void *param, uint32_t cx, uint32_t cy), - void *param) +void obs_add_main_render_callback(void (*draw)(void *param, uint32_t cx, + uint32_t cy), + void *param) { if (!obs) return; @@ -2262,9 +2345,9 @@ void obs_add_main_render_callback( pthread_mutex_unlock(&obs->data.draw_callbacks_mutex); } -void obs_remove_main_render_callback( - void (*draw)(void *param, uint32_t cx, uint32_t cy), - void *param) +void obs_remove_main_render_callback(void (*draw)(void *param, uint32_t cx, + uint32_t cy), + void *param) { if (!obs) return; @@ -2287,8 +2370,8 @@ uint32_t obs_get_lagged_frames(void) } void start_raw_video(video_t *v, const struct video_scale_info *conversion, - void (*callback)(void *param, struct video_data *frame), - void *param) + void (*callback)(void *param, struct video_data *frame), + void *param) { struct obs_core_video *video = &obs->video; os_atomic_inc_long(&video->raw_active); @@ -2296,18 +2379,18 @@ void start_raw_video(video_t *v, const struct video_scale_info *conversion, } void stop_raw_video(video_t *v, - void (*callback)(void *param, struct video_data *frame), - void *param) + void (*callback)(void *param, struct video_data *frame), + void *param) { struct obs_core_video *video = &obs->video; os_atomic_dec_long(&video->raw_active); video_output_disconnect(v, callback, param); } -void obs_add_raw_video_callback( - const struct video_scale_info *conversion, - void (*callback)(void *param, struct video_data *frame), - void *param) +void obs_add_raw_video_callback(const struct video_scale_info *conversion, + void (*callback)(void *param, + struct video_data *frame), + void *param) { struct obs_core_video *video = &obs->video; if (!obs) @@ -2315,9 +2398,9 @@ void obs_add_raw_video_callback( start_raw_video(video->video, conversion, callback, param); } -void obs_remove_raw_video_callback( - void (*callback)(void *param, struct video_data *frame), - void *param) +void obs_remove_raw_video_callback(void (*callback)(void *param, + struct video_data *frame), + void *param) { struct obs_core_video *video = &obs->video; if (!obs) diff --git a/libobs/obs.h b/libobs/obs.h index f6e76ca..b77ed8d 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -51,20 +51,20 @@ struct obs_module; struct obs_fader; struct obs_volmeter; -typedef struct obs_display obs_display_t; -typedef struct obs_view obs_view_t; -typedef struct obs_source obs_source_t; -typedef struct obs_scene obs_scene_t; +typedef struct obs_display obs_display_t; +typedef struct obs_view obs_view_t; +typedef struct obs_source obs_source_t; +typedef struct obs_scene obs_scene_t; typedef struct obs_scene_item obs_sceneitem_t; -typedef struct obs_output obs_output_t; -typedef struct obs_encoder obs_encoder_t; -typedef struct obs_service obs_service_t; -typedef struct obs_module obs_module_t; -typedef struct obs_fader obs_fader_t; -typedef struct obs_volmeter obs_volmeter_t; +typedef struct obs_output obs_output_t; +typedef struct obs_encoder obs_encoder_t; +typedef struct obs_service obs_service_t; +typedef struct obs_module obs_module_t; +typedef struct obs_fader obs_fader_t; +typedef struct obs_volmeter obs_volmeter_t; -typedef struct obs_weak_source obs_weak_source_t; -typedef struct obs_weak_output obs_weak_output_t; +typedef struct obs_weak_source obs_weak_source_t; +typedef struct obs_weak_output obs_weak_output_t; typedef struct obs_weak_encoder obs_weak_encoder_t; typedef struct obs_weak_service obs_weak_service_t; @@ -98,7 +98,7 @@ enum obs_order_movement { OBS_ORDER_MOVE_UP, OBS_ORDER_MOVE_DOWN, OBS_ORDER_MOVE_TOP, - OBS_ORDER_MOVE_BOTTOM + OBS_ORDER_MOVE_BOTTOM, }; /** @@ -136,14 +136,14 @@ enum obs_bounds_type { }; struct obs_transform_info { - struct vec2 pos; - float rot; - struct vec2 scale; - uint32_t alignment; + struct vec2 pos; + float rot; + struct vec2 scale; + uint32_t alignment; enum obs_bounds_type bounds_type; - uint32_t bounds_alignment; - struct vec2 bounds; + uint32_t bounds_alignment; + struct vec2 bounds; }; /** @@ -154,36 +154,36 @@ struct obs_video_info { /** * Graphics module to use (usually "libobs-opengl" or "libobs-d3d11") */ - const char *graphics_module; + const char *graphics_module; #endif - uint32_t fps_num; /**< Output FPS numerator */ - uint32_t fps_den; /**< Output FPS denominator */ + uint32_t fps_num; /**< Output FPS numerator */ + uint32_t fps_den; /**< Output FPS denominator */ - uint32_t base_width; /**< Base compositing width */ - uint32_t base_height; /**< Base compositing height */ + uint32_t base_width; /**< Base compositing width */ + uint32_t base_height; /**< Base compositing height */ - uint32_t output_width; /**< Output width */ - uint32_t output_height; /**< Output height */ - enum video_format output_format; /**< Output format */ + uint32_t output_width; /**< Output width */ + uint32_t output_height; /**< Output height */ + enum video_format output_format; /**< Output format */ /** Video adapter index to use (NOTE: avoid for optimus laptops) */ - uint32_t adapter; + uint32_t adapter; /** Use shaders to convert to different color formats */ - bool gpu_conversion; + bool gpu_conversion; - enum video_colorspace colorspace; /**< YUV type (if YUV) */ - enum video_range_type range; /**< YUV range (if YUV) */ + enum video_colorspace colorspace; /**< YUV type (if YUV) */ + enum video_range_type range; /**< YUV range (if YUV) */ - enum obs_scale_type scale_type; /**< How to scale if scaling */ + enum obs_scale_type scale_type; /**< How to scale if scaling */ }; /** * Audio initialization structure */ struct obs_audio_info { - uint32_t samples_per_sec; + uint32_t samples_per_sec; enum speaker_layout speakers; }; @@ -192,9 +192,9 @@ struct obs_audio_info { * audio data */ struct obs_audio_data { - uint8_t *data[MAX_AV_PLANES]; - uint32_t frames; - uint64_t timestamp; + uint8_t *data[MAX_AV_PLANES]; + uint32_t frames; + uint64_t timestamp; }; /** @@ -202,14 +202,14 @@ struct obs_audio_data { * source audio. Audio is automatically resampled and remixed as necessary. */ struct obs_source_audio { - const uint8_t *data[MAX_AV_PLANES]; - uint32_t frames; + const uint8_t *data[MAX_AV_PLANES]; + uint32_t frames; enum speaker_layout speakers; - enum audio_format format; - uint32_t samples_per_sec; + enum audio_format format; + uint32_t samples_per_sec; - uint64_t timestamp; + uint64_t timestamp; }; /** @@ -226,37 +226,37 @@ struct obs_source_audio { * instead if partial range support is desired for non-YUV video formats. */ struct obs_source_frame { - uint8_t *data[MAX_AV_PLANES]; - uint32_t linesize[MAX_AV_PLANES]; - uint32_t width; - uint32_t height; - uint64_t timestamp; + uint8_t *data[MAX_AV_PLANES]; + uint32_t linesize[MAX_AV_PLANES]; + uint32_t width; + uint32_t height; + uint64_t timestamp; - enum video_format format; - float color_matrix[16]; - bool full_range; - float color_range_min[3]; - float color_range_max[3]; - bool flip; + enum video_format format; + float color_matrix[16]; + bool full_range; + float color_range_min[3]; + float color_range_max[3]; + bool flip; /* used internally by libobs */ - volatile long refs; - bool prev_frame; + volatile long refs; + bool prev_frame; }; struct obs_source_frame2 { - uint8_t *data[MAX_AV_PLANES]; - uint32_t linesize[MAX_AV_PLANES]; - uint32_t width; - uint32_t height; - uint64_t timestamp; + uint8_t *data[MAX_AV_PLANES]; + uint32_t linesize[MAX_AV_PLANES]; + uint32_t width; + uint32_t height; + uint64_t timestamp; - enum video_format format; + enum video_format format; enum video_range_type range; - float color_matrix[16]; - float color_range_min[3]; - float color_range_max[3]; - bool flip; + float color_matrix[16]; + float color_range_min[3]; + float color_range_max[3]; + bool flip; }; /** Access to the argc/argv used to start OBS. What you see is what you get. */ @@ -293,7 +293,6 @@ EXPORT void obs_add_data_path(const char *path); */ EXPORT bool obs_remove_data_path(const char *path); - /** * Initializes OBS * @@ -303,7 +302,7 @@ EXPORT bool obs_remove_data_path(const char *path); * @param store The profiler name store for OBS to use or NULL */ EXPORT bool obs_startup(const char *locale, const char *module_config_path, - profiler_name_store_t *store); + profiler_name_store_t *store); /** Releases all data associated with OBS and terminates the OBS context */ EXPORT void obs_shutdown(void); @@ -325,7 +324,7 @@ EXPORT const char *obs_get_version_string(void); * @param argv An array of command line arguments, copied from main() and ends * with NULL. */ -EXPORT void obs_set_cmdline_args(int argc, const char * const *argv); +EXPORT void obs_set_cmdline_args(int argc, const char *const *argv); /** * Get the argc/argv used to start OBS @@ -412,7 +411,7 @@ EXPORT bool obs_get_audio_info(struct obs_audio_info *oai); * MODULE_INCOMPATIBLE_VER if incompatible version */ EXPORT int obs_open_module(obs_module_t **module, const char *path, - const char *data_path); + const char *data_path); /** * Initializes the module, which calls its obs_module_load export. If the @@ -466,7 +465,7 @@ struct obs_module_info { }; typedef void (*obs_find_module_callback_t)(void *param, - const struct obs_module_info *info); + const struct obs_module_info *info); /** Finds all modules within the search paths added by obs_add_module_path. */ EXPORT void obs_find_modules(obs_find_module_callback_t callback, void *param); @@ -479,7 +478,8 @@ EXPORT void obs_enum_modules(obs_enum_module_callback_t callback, void *param); /** Helper function for using default module locale */ EXPORT lookup_t *obs_module_load_locale(obs_module_t *module, - const char *default_locale, const char *locale); + const char *default_locale, + const char *locale); /** * Returns the location of a plugin module data file. @@ -576,24 +576,24 @@ EXPORT obs_source_t *obs_get_output_source(uint32_t channel); * Use obs_source_get_ref or obs_source_get_weak_source if you want to retain * a reference after obs_enum_sources finishes */ -EXPORT void obs_enum_sources(bool (*enum_proc)(void*, obs_source_t*), - void *param); +EXPORT void obs_enum_sources(bool (*enum_proc)(void *, obs_source_t *), + void *param); /** Enumerates scenes */ -EXPORT void obs_enum_scenes(bool (*enum_proc)(void*, obs_source_t*), - void *param); +EXPORT void obs_enum_scenes(bool (*enum_proc)(void *, obs_source_t *), + void *param); /** Enumerates outputs */ -EXPORT void obs_enum_outputs(bool (*enum_proc)(void*, obs_output_t*), - void *param); +EXPORT void obs_enum_outputs(bool (*enum_proc)(void *, obs_output_t *), + void *param); /** Enumerates encoders */ -EXPORT void obs_enum_encoders(bool (*enum_proc)(void*, obs_encoder_t*), - void *param); +EXPORT void obs_enum_encoders(bool (*enum_proc)(void *, obs_encoder_t *), + void *param); /** Enumerates encoders */ -EXPORT void obs_enum_services(bool (*enum_proc)(void*, obs_service_t*), - void *param); +EXPORT void obs_enum_services(bool (*enum_proc)(void *, obs_service_t *), + void *param); /** * Gets a source by its name. @@ -613,16 +613,16 @@ EXPORT obs_encoder_t *obs_get_encoder_by_name(const char *name); EXPORT obs_service_t *obs_get_service_by_name(const char *name); enum obs_base_effect { - OBS_EFFECT_DEFAULT, /**< RGB/YUV */ - OBS_EFFECT_DEFAULT_RECT, /**< RGB/YUV (using texture_rect) */ - OBS_EFFECT_OPAQUE, /**< RGB/YUV (alpha set to 1.0) */ - OBS_EFFECT_SOLID, /**< RGB/YUV (solid color only) */ - OBS_EFFECT_BICUBIC, /**< Bicubic downscale */ - OBS_EFFECT_LANCZOS, /**< Lanczos downscale */ - OBS_EFFECT_BILINEAR_LOWRES, /**< Bilinear low resolution downscale */ - OBS_EFFECT_PREMULTIPLIED_ALPHA,/**< Premultiplied alpha */ - OBS_EFFECT_REPEAT, /**< RGB/YUV (repeating) */ - OBS_EFFECT_AREA, /**< Area rescale */ + OBS_EFFECT_DEFAULT, /**< RGB/YUV */ + OBS_EFFECT_DEFAULT_RECT, /**< RGB/YUV (using texture_rect) */ + OBS_EFFECT_OPAQUE, /**< RGB/YUV (alpha set to 1.0) */ + OBS_EFFECT_SOLID, /**< RGB/YUV (solid color only) */ + OBS_EFFECT_BICUBIC, /**< Bicubic downscale */ + OBS_EFFECT_LANCZOS, /**< Lanczos downscale */ + OBS_EFFECT_BILINEAR_LOWRES, /**< Bilinear low resolution downscale */ + OBS_EFFECT_PREMULTIPLIED_ALPHA, /**< Premultiplied alpha */ + OBS_EFFECT_REPEAT, /**< RGB/YUV (repeating) */ + OBS_EFFECT_AREA, /**< Area rescale */ }; /** Returns a commonly used base effect */ @@ -649,6 +649,9 @@ EXPORT void obs_render_main_view(void); /** Renders the last main output texture */ EXPORT void obs_render_main_texture(void); +/** Renders the last main output texture ignoring background color */ +EXPORT void obs_render_main_texture_src_color_only(void); + /** Returns the last main output texture. This can return NULL if the texture * is unavailable. */ EXPORT gs_texture_t *obs_get_main_texture(void); @@ -675,21 +678,21 @@ typedef void (*obs_load_source_cb)(void *private_data, obs_source_t *source); /** Loads sources from a data array */ EXPORT void obs_load_sources(obs_data_array_t *array, obs_load_source_cb cb, - void *private_data); + void *private_data); /** Saves sources to a data array */ EXPORT obs_data_array_t *obs_save_sources(void); typedef bool (*obs_save_source_filter_cb)(void *data, obs_source_t *source); EXPORT obs_data_array_t *obs_save_sources_filtered(obs_save_source_filter_cb cb, - void *data); + void *data); enum obs_obj_type { OBS_OBJ_TYPE_INVALID, OBS_OBJ_TYPE_SOURCE, OBS_OBJ_TYPE_OUTPUT, OBS_OBJ_TYPE_ENCODER, - OBS_OBJ_TYPE_SERVICE + OBS_OBJ_TYPE_SERVICE, }; EXPORT enum obs_obj_type obs_obj_get_type(void *obj); @@ -698,40 +701,36 @@ EXPORT bool obs_obj_invalid(void *obj); EXPORT void *obs_obj_get_data(void *obj); typedef bool (*obs_enum_audio_device_cb)(void *data, const char *name, - const char *id); + const char *id); EXPORT void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb, - void *data); + void *data); EXPORT bool obs_set_audio_monitoring_device(const char *name, const char *id); EXPORT void obs_get_audio_monitoring_device(const char **name, const char **id); -EXPORT void obs_add_tick_callback( - void (*tick)(void *param, float seconds), - void *param); -EXPORT void obs_remove_tick_callback( - void (*tick)(void *param, float seconds), - void *param); +EXPORT void obs_add_tick_callback(void (*tick)(void *param, float seconds), + void *param); +EXPORT void obs_remove_tick_callback(void (*tick)(void *param, float seconds), + void *param); -EXPORT void obs_add_main_render_callback( - void (*draw)(void *param, uint32_t cx, uint32_t cy), - void *param); +EXPORT void obs_add_main_render_callback(void (*draw)(void *param, uint32_t cx, + uint32_t cy), + void *param); EXPORT void obs_remove_main_render_callback( - void (*draw)(void *param, uint32_t cx, uint32_t cy), - void *param); + void (*draw)(void *param, uint32_t cx, uint32_t cy), void *param); EXPORT void obs_add_raw_video_callback( - const struct video_scale_info *conversion, - void (*callback)(void *param, struct video_data *frame), - void *param); + const struct video_scale_info *conversion, + void (*callback)(void *param, struct video_data *frame), void *param); EXPORT void obs_remove_raw_video_callback( - void (*callback)(void *param, struct video_data *frame), - void *param); + void (*callback)(void *param, struct video_data *frame), void *param); EXPORT uint64_t obs_get_video_frame_time(void); EXPORT double obs_get_active_fps(void); EXPORT uint64_t obs_get_average_frame_time_ns(void); +EXPORT uint64_t obs_get_frame_interval_ns(void); EXPORT uint32_t obs_get_total_frames(void); EXPORT uint32_t obs_get_lagged_frames(void); @@ -742,7 +741,6 @@ EXPORT void obs_apply_private_data(obs_data_t *settings); EXPORT void obs_set_private_data(obs_data_t *settings); EXPORT obs_data_t *obs_get_private_data(void); - /* ------------------------------------------------------------------------- */ /* View context */ @@ -759,16 +757,14 @@ EXPORT void obs_view_destroy(obs_view_t *view); /** Sets the source to be used for this view context. */ EXPORT void obs_view_set_source(obs_view_t *view, uint32_t channel, - obs_source_t *source); + obs_source_t *source); /** Gets the source currently in use for this view context */ -EXPORT obs_source_t *obs_view_get_source(obs_view_t *view, - uint32_t channel); +EXPORT obs_source_t *obs_view_get_source(obs_view_t *view, uint32_t channel); /** Renders the sources of this view context */ EXPORT void obs_view_render(obs_view_t *view); - /* ------------------------------------------------------------------------- */ /* Display context */ @@ -779,16 +775,16 @@ EXPORT void obs_view_render(obs_view_t *view); * @param graphics_data The swap chain initialization data. * @return The new display context, or NULL if failed. */ -EXPORT obs_display_t *obs_display_create( - const struct gs_init_data *graphics_data, - uint32_t backround_color); +EXPORT obs_display_t * +obs_display_create(const struct gs_init_data *graphics_data, + uint32_t backround_color); /** Destroys a display context */ EXPORT void obs_display_destroy(obs_display_t *display); /** Changes the size of this display */ EXPORT void obs_display_resize(obs_display_t *display, uint32_t cx, - uint32_t cy); + uint32_t cy); /** * Adds a draw callback for this display context @@ -799,23 +795,23 @@ EXPORT void obs_display_resize(obs_display_t *display, uint32_t cx, * @param param The user data to be associated with this draw callback. */ EXPORT void obs_display_add_draw_callback(obs_display_t *display, - void (*draw)(void *param, uint32_t cx, uint32_t cy), - void *param); + void (*draw)(void *param, uint32_t cx, + uint32_t cy), + void *param); /** Removes a draw callback for this display context */ -EXPORT void obs_display_remove_draw_callback(obs_display_t *display, - void (*draw)(void *param, uint32_t cx, uint32_t cy), - void *param); +EXPORT void obs_display_remove_draw_callback( + obs_display_t *display, + void (*draw)(void *param, uint32_t cx, uint32_t cy), void *param); EXPORT void obs_display_set_enabled(obs_display_t *display, bool enable); EXPORT bool obs_display_enabled(obs_display_t *display); EXPORT void obs_display_set_background_color(obs_display_t *display, - uint32_t color); - -EXPORT void obs_display_size(obs_display_t *display, - uint32_t *width, uint32_t *height); + uint32_t color); +EXPORT void obs_display_size(obs_display_t *display, uint32_t *width, + uint32_t *height); /* ------------------------------------------------------------------------- */ /* Sources */ @@ -830,15 +826,17 @@ EXPORT const char *obs_source_get_display_name(const char *id); * or modifying video/audio. Use obs_source_release to release it. */ EXPORT obs_source_t *obs_source_create(const char *id, const char *name, - obs_data_t *settings, obs_data_t *hotkey_data); + obs_data_t *settings, + obs_data_t *hotkey_data); -EXPORT obs_source_t *obs_source_create_private(const char *id, - const char *name, obs_data_t *settings); +EXPORT obs_source_t *obs_source_create_private(const char *id, const char *name, + obs_data_t *settings); /* if source has OBS_SOURCE_DO_NOT_DUPLICATE output flag set, only returns a * reference */ EXPORT obs_source_t *obs_source_duplicate(obs_source_t *source, - const char *desired_name, bool create_private); + const char *desired_name, + bool create_private); /** * Adds/releases a reference to a source. When the last reference is * released, the source is destroyed. @@ -854,7 +852,7 @@ EXPORT obs_weak_source_t *obs_source_get_weak_source(obs_source_t *source); EXPORT obs_source_t *obs_weak_source_get_source(obs_weak_source_t *weak); EXPORT bool obs_weak_source_references_source(obs_weak_source_t *weak, - obs_source_t *source); + obs_source_t *source); /** Notifies all references that the source should be released */ EXPORT void obs_source_remove(obs_source_t *source); @@ -919,11 +917,12 @@ EXPORT void obs_source_filter_add(obs_source_t *source, obs_source_t *filter); /** Removes a filter from the source */ EXPORT void obs_source_filter_remove(obs_source_t *source, - obs_source_t *filter); + obs_source_t *filter); /** Modifies the order of a specific filter */ EXPORT void obs_source_filter_set_order(obs_source_t *source, - obs_source_t *filter, enum obs_order_movement movement); + obs_source_t *filter, + enum obs_order_movement movement); /** Gets the settings string for a source */ EXPORT obs_data_t *obs_source_get_settings(const obs_source_t *source); @@ -941,8 +940,8 @@ EXPORT enum obs_source_type obs_source_get_type(const obs_source_t *source); EXPORT const char *obs_source_get_id(const obs_source_t *source); /** Returns the signal handler for a source */ -EXPORT signal_handler_t *obs_source_get_signal_handler( - const obs_source_t *source); +EXPORT signal_handler_t * +obs_source_get_signal_handler(const obs_source_t *source); /** Returns the procedure handler for a source */ EXPORT proc_handler_t *obs_source_get_proc_handler(const obs_source_t *source); @@ -970,13 +969,13 @@ EXPORT int64_t obs_source_get_sync_offset(const obs_source_t *source); /** Enumerates active child sources used by this source */ EXPORT void obs_source_enum_active_sources(obs_source_t *source, - obs_source_enum_proc_t enum_callback, - void *param); + obs_source_enum_proc_t enum_callback, + void *param); /** Enumerates the entire active child source tree used by this source */ EXPORT void obs_source_enum_active_tree(obs_source_t *source, - obs_source_enum_proc_t enum_callback, - void *param); + obs_source_enum_proc_t enum_callback, + void *param); /** Returns true if active, false if not */ EXPORT bool obs_source_active(const obs_source_t *source); @@ -987,9 +986,9 @@ EXPORT bool obs_source_active(const obs_source_t *source); EXPORT bool obs_source_showing(const obs_source_t *source); /** Unused flag */ -#define OBS_SOURCE_FLAG_UNUSED_1 (1<<0) +#define OBS_SOURCE_FLAG_UNUSED_1 (1 << 0) /** Specifies to force audio to mono */ -#define OBS_SOURCE_FLAG_FORCE_MONO (1<<1) +#define OBS_SOURCE_FLAG_FORCE_MONO (1 << 1) /** * Sets source flags. Note that these are different from the main output @@ -1049,11 +1048,12 @@ EXPORT void obs_source_dec_active(obs_source_t *source); /** Enumerates filters assigned to the source */ EXPORT void obs_source_enum_filters(obs_source_t *source, - obs_source_enum_proc_t callback, void *param); + obs_source_enum_proc_t callback, + void *param); /** Gets a filter of a source by its display name. */ EXPORT obs_source_t *obs_source_get_filter_by_name(obs_source_t *source, - const char *name); + const char *name); EXPORT void obs_source_copy_filters(obs_source_t *dst, obs_source_t *src); @@ -1068,22 +1068,23 @@ EXPORT void obs_source_enable_push_to_mute(obs_source_t *source, bool enabled); EXPORT uint64_t obs_source_get_push_to_mute_delay(obs_source_t *source); EXPORT void obs_source_set_push_to_mute_delay(obs_source_t *source, - uint64_t delay); + uint64_t delay); EXPORT bool obs_source_push_to_talk_enabled(obs_source_t *source); EXPORT void obs_source_enable_push_to_talk(obs_source_t *source, bool enabled); EXPORT uint64_t obs_source_get_push_to_talk_delay(obs_source_t *source); EXPORT void obs_source_set_push_to_talk_delay(obs_source_t *source, - uint64_t delay); + uint64_t delay); typedef void (*obs_source_audio_capture_t)(void *param, obs_source_t *source, - const struct audio_data *audio_data, bool muted); + const struct audio_data *audio_data, + bool muted); -EXPORT void obs_source_add_audio_capture_callback(obs_source_t *source, - obs_source_audio_capture_t callback, void *param); -EXPORT void obs_source_remove_audio_capture_callback(obs_source_t *source, - obs_source_audio_capture_t callback, void *param); +EXPORT void obs_source_add_audio_capture_callback( + obs_source_t *source, obs_source_audio_capture_t callback, void *param); +EXPORT void obs_source_remove_audio_capture_callback( + obs_source_t *source, obs_source_audio_capture_t callback, void *param); enum obs_deinterlace_mode { OBS_DEINTERLACE_MODE_DISABLE, @@ -1094,33 +1095,33 @@ enum obs_deinterlace_mode { OBS_DEINTERLACE_MODE_LINEAR, OBS_DEINTERLACE_MODE_LINEAR_2X, OBS_DEINTERLACE_MODE_YADIF, - OBS_DEINTERLACE_MODE_YADIF_2X + OBS_DEINTERLACE_MODE_YADIF_2X, }; enum obs_deinterlace_field_order { OBS_DEINTERLACE_FIELD_ORDER_TOP, - OBS_DEINTERLACE_FIELD_ORDER_BOTTOM + OBS_DEINTERLACE_FIELD_ORDER_BOTTOM, }; EXPORT void obs_source_set_deinterlace_mode(obs_source_t *source, - enum obs_deinterlace_mode mode); -EXPORT enum obs_deinterlace_mode obs_source_get_deinterlace_mode( - const obs_source_t *source); -EXPORT void obs_source_set_deinterlace_field_order(obs_source_t *source, - enum obs_deinterlace_field_order field_order); -EXPORT enum obs_deinterlace_field_order obs_source_get_deinterlace_field_order( - const obs_source_t *source); + enum obs_deinterlace_mode mode); +EXPORT enum obs_deinterlace_mode +obs_source_get_deinterlace_mode(const obs_source_t *source); +EXPORT void obs_source_set_deinterlace_field_order( + obs_source_t *source, enum obs_deinterlace_field_order field_order); +EXPORT enum obs_deinterlace_field_order +obs_source_get_deinterlace_field_order(const obs_source_t *source); enum obs_monitoring_type { OBS_MONITORING_TYPE_NONE, OBS_MONITORING_TYPE_MONITOR_ONLY, - OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT + OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT, }; EXPORT void obs_source_set_monitoring_type(obs_source_t *source, - enum obs_monitoring_type type); -EXPORT enum obs_monitoring_type obs_source_get_monitoring_type( - const obs_source_t *source); + enum obs_monitoring_type type); +EXPORT enum obs_monitoring_type +obs_source_get_monitoring_type(const obs_source_t *source); /** Gets private front-end settings data. This data is saved/loaded * automatically. Returns an incremented reference. */ @@ -1143,10 +1144,10 @@ EXPORT void *obs_source_get_type_data(obs_source_t *source); * 'color_range_max' effect variable. If NULL, * {1.0f, 1.0f, 1.0f} is used. */ -EXPORT void obs_source_draw_set_color_matrix( - const struct matrix4 *color_matrix, - const struct vec3 *color_range_min, - const struct vec3 *color_range_max); +EXPORT void +obs_source_draw_set_color_matrix(const struct matrix4 *color_matrix, + const struct vec3 *color_range_min, + const struct vec3 *color_range_max); /** * Helper function to draw sprites for a source (synchronous video). @@ -1159,8 +1160,8 @@ EXPORT void obs_source_draw_set_color_matrix( * @param cy Height of the sprite. If 0, uses the texture height. * @param flip Specifies whether to flip the image vertically. */ -EXPORT void obs_source_draw(gs_texture_t *image, int x, int y, - uint32_t cx, uint32_t cy, bool flip); +EXPORT void obs_source_draw(gs_texture_t *image, int x, int y, uint32_t cx, + uint32_t cy, bool flip); /** * Outputs asynchronous video data. Set to NULL to deactivate the texture @@ -1170,9 +1171,9 @@ EXPORT void obs_source_draw(gs_texture_t *image, int x, int y, * desired for non-YUV video formats. */ EXPORT void obs_source_output_video(obs_source_t *source, - const struct obs_source_frame *frame); + const struct obs_source_frame *frame); EXPORT void obs_source_output_video2(obs_source_t *source, - const struct obs_source_frame2 *frame); + const struct obs_source_frame2 *frame); /** * Preloads asynchronous video data to allow instantaneous playback @@ -1182,16 +1183,16 @@ EXPORT void obs_source_output_video2(obs_source_t *source, * desired for non-YUV video formats. */ EXPORT void obs_source_preload_video(obs_source_t *source, - const struct obs_source_frame *frame); + const struct obs_source_frame *frame); EXPORT void obs_source_preload_video2(obs_source_t *source, - const struct obs_source_frame2 *frame); + const struct obs_source_frame2 *frame); /** Shows any preloaded video data */ EXPORT void obs_source_show_preloaded_video(obs_source_t *source); /** Outputs audio data (always asynchronous) */ EXPORT void obs_source_output_audio(obs_source_t *source, - const struct obs_source_audio *audio); + const struct obs_source_audio *audio); /** Signal an update to any currently used properties via 'update_properties' */ EXPORT void obs_source_update_properties(obs_source_t *source); @@ -1201,7 +1202,7 @@ EXPORT struct obs_source_frame *obs_source_get_frame(obs_source_t *source); /** Releases the current async video frame */ EXPORT void obs_source_release_frame(obs_source_t *source, - struct obs_source_frame *frame); + struct obs_source_frame *frame); /** * Default RGB filter handler for generic effect filters. Processes the @@ -1214,9 +1215,10 @@ EXPORT void obs_source_release_frame(obs_source_t *source, * Returns true if filtering should continue, false if the filter is bypassed * for whatever reason. */ -EXPORT bool obs_source_process_filter_begin(obs_source_t *filter, - enum gs_color_format format, - enum obs_allow_direct_render allow_direct); +EXPORT bool +obs_source_process_filter_begin(obs_source_t *filter, + enum gs_color_format format, + enum obs_allow_direct_render allow_direct); /** * Draws the filter. @@ -1226,7 +1228,8 @@ EXPORT bool obs_source_process_filter_begin(obs_source_t *filter, * filter. */ EXPORT void obs_source_process_filter_end(obs_source_t *filter, - gs_effect_t *effect, uint32_t width, uint32_t height); + gs_effect_t *effect, uint32_t width, + uint32_t height); /** * Draws the filter with a specific technique. @@ -1236,8 +1239,9 @@ EXPORT void obs_source_process_filter_end(obs_source_t *filter, * filter. */ EXPORT void obs_source_process_filter_tech_end(obs_source_t *filter, - gs_effect_t *effect, uint32_t width, uint32_t height, - const char *tech_name); + gs_effect_t *effect, + uint32_t width, uint32_t height, + const char *tech_name); /** Skips the filter if the filter is invalid and cannot be rendered */ EXPORT void obs_source_skip_video_filter(obs_source_t *filter); @@ -1250,7 +1254,7 @@ EXPORT void obs_source_skip_video_filter(obs_source_t *filter); * @returns true if source can be added, false if it causes recursion */ EXPORT bool obs_source_add_active_child(obs_source_t *parent, - obs_source_t *child); + obs_source_t *child); /** * Removes an active child source. Must be called by parent sources on child @@ -1258,28 +1262,31 @@ EXPORT bool obs_source_add_active_child(obs_source_t *parent, * is properly deactivated if the parent is no longer active. */ EXPORT void obs_source_remove_active_child(obs_source_t *parent, - obs_source_t *child); + obs_source_t *child); /** Sends a mouse down/up event to a source */ EXPORT void obs_source_send_mouse_click(obs_source_t *source, - const struct obs_mouse_event *event, - int32_t type, bool mouse_up, - uint32_t click_count); + const struct obs_mouse_event *event, + int32_t type, bool mouse_up, + uint32_t click_count); /** Sends a mouse move event to a source. */ EXPORT void obs_source_send_mouse_move(obs_source_t *source, - const struct obs_mouse_event *event, bool mouse_leave); + const struct obs_mouse_event *event, + bool mouse_leave); /** Sends a mouse wheel event to a source */ EXPORT void obs_source_send_mouse_wheel(obs_source_t *source, - const struct obs_mouse_event *event, int x_delta, int y_delta); + const struct obs_mouse_event *event, + int x_delta, int y_delta); /** Sends a got-focus or lost-focus event to a source */ EXPORT void obs_source_send_focus(obs_source_t *source, bool focus); /** Sends a key up/down event to a source */ EXPORT void obs_source_send_key_click(obs_source_t *source, - const struct obs_key_event *event, bool key_up); + const struct obs_key_event *event, + bool key_up); /** Sets the default source flags. */ EXPORT void obs_source_set_default_flags(obs_source_t *source, uint32_t flags); @@ -1293,10 +1300,10 @@ EXPORT uint32_t obs_source_get_base_height(obs_source_t *source); EXPORT bool obs_source_audio_pending(const obs_source_t *source); EXPORT uint64_t obs_source_get_audio_timestamp(const obs_source_t *source); EXPORT void obs_source_get_audio_mix(const obs_source_t *source, - struct obs_source_audio_mix *audio); + struct obs_source_audio_mix *audio); EXPORT void obs_source_set_async_unbuffered(obs_source_t *source, - bool unbuffered); + bool unbuffered); EXPORT bool obs_source_async_unbuffered(const obs_source_t *source); /** Used to decouple audio from video so that audio doesn't attempt to sync up @@ -1305,15 +1312,21 @@ EXPORT bool obs_source_async_unbuffered(const obs_source_t *source); EXPORT void obs_source_set_async_decoupled(obs_source_t *source, bool decouple); EXPORT bool obs_source_async_decoupled(const obs_source_t *source); +EXPORT void obs_source_set_audio_active(obs_source_t *source, bool show); +EXPORT bool obs_source_audio_active(const obs_source_t *source); + +EXPORT uint32_t obs_source_get_last_obs_version(const obs_source_t *source); + /* ------------------------------------------------------------------------- */ /* Transition-specific functions */ enum obs_transition_target { OBS_TRANSITION_SOURCE_A, - OBS_TRANSITION_SOURCE_B + OBS_TRANSITION_SOURCE_B, }; -EXPORT obs_source_t *obs_transition_get_source(obs_source_t *transition, - enum obs_transition_target target); +EXPORT obs_source_t * +obs_transition_get_source(obs_source_t *transition, + enum obs_transition_target target); EXPORT void obs_transition_clear(obs_source_t *transition); EXPORT obs_source_t *obs_transition_get_active_source(obs_source_t *transition); @@ -1323,8 +1336,8 @@ enum obs_transition_mode { }; EXPORT bool obs_transition_start(obs_source_t *transition, - enum obs_transition_mode mode, uint32_t duration_ms, - obs_source_t *dest); + enum obs_transition_mode mode, + uint32_t duration_ms, obs_source_t *dest); EXPORT void obs_transition_set(obs_source_t *transition, obs_source_t *source); @@ -1335,18 +1348,18 @@ enum obs_transition_scale_type { }; EXPORT void obs_transition_set_scale_type(obs_source_t *transition, - enum obs_transition_scale_type type); -EXPORT enum obs_transition_scale_type obs_transition_get_scale_type( - const obs_source_t *transition); + enum obs_transition_scale_type type); +EXPORT enum obs_transition_scale_type +obs_transition_get_scale_type(const obs_source_t *transition); EXPORT void obs_transition_set_alignment(obs_source_t *transition, - uint32_t alignment); + uint32_t alignment); EXPORT uint32_t obs_transition_get_alignment(const obs_source_t *transition); -EXPORT void obs_transition_set_size(obs_source_t *transition, - uint32_t cx, uint32_t cy); +EXPORT void obs_transition_set_size(obs_source_t *transition, uint32_t cx, + uint32_t cy); EXPORT void obs_transition_get_size(const obs_source_t *transition, - uint32_t *cx, uint32_t *cy); + uint32_t *cx, uint32_t *cy); /* function used by transitions */ @@ -1355,39 +1368,43 @@ EXPORT void obs_transition_get_size(const obs_source_t *transition, * are of fixed duration and linearly interpolated */ EXPORT void obs_transition_enable_fixed(obs_source_t *transition, bool enable, - uint32_t duration_ms); + uint32_t duration_ms); EXPORT bool obs_transition_fixed(obs_source_t *transition); typedef void (*obs_transition_video_render_callback_t)(void *data, - gs_texture_t *a, gs_texture_t *b, float t, - uint32_t cx, uint32_t cy); + gs_texture_t *a, + gs_texture_t *b, float t, + uint32_t cx, + uint32_t cy); typedef float (*obs_transition_audio_mix_callback_t)(void *data, float t); EXPORT float obs_transition_get_time(obs_source_t *transition); EXPORT void obs_transition_force_stop(obs_source_t *transition); -EXPORT void obs_transition_video_render(obs_source_t *transition, - obs_transition_video_render_callback_t callback); +EXPORT void +obs_transition_video_render(obs_source_t *transition, + obs_transition_video_render_callback_t callback); /** Directly renders its sub-source instead of to texture. Returns false if no * longer transitioning */ -EXPORT bool obs_transition_video_render_direct(obs_source_t *transition, - enum obs_transition_target target); +EXPORT bool +obs_transition_video_render_direct(obs_source_t *transition, + enum obs_transition_target target); -EXPORT bool obs_transition_audio_render(obs_source_t *transition, - uint64_t *ts_out, struct obs_source_audio_mix *audio, - uint32_t mixers, size_t channels, size_t sample_rate, - obs_transition_audio_mix_callback_t mix_a_callback, - obs_transition_audio_mix_callback_t mix_b_callback); +EXPORT bool +obs_transition_audio_render(obs_source_t *transition, uint64_t *ts_out, + struct obs_source_audio_mix *audio, uint32_t mixers, + size_t channels, size_t sample_rate, + obs_transition_audio_mix_callback_t mix_a_callback, + obs_transition_audio_mix_callback_t mix_b_callback); /* swaps transition sources and textures as an optimization and to reduce * memory usage when switching between transitions */ EXPORT void obs_transition_swap_begin(obs_source_t *tr_dest, - obs_source_t *tr_source); + obs_source_t *tr_source); EXPORT void obs_transition_swap_end(obs_source_t *tr_dest, - obs_source_t *tr_source); - + obs_source_t *tr_source); /* ------------------------------------------------------------------------- */ /* Scenes */ @@ -1406,17 +1423,17 @@ enum obs_scene_duplicate_type { OBS_SCENE_DUP_REFS, /**< Source refs only */ OBS_SCENE_DUP_COPY, /**< Fully duplicate */ OBS_SCENE_DUP_PRIVATE_REFS, /**< Source refs only (as private) */ - OBS_SCENE_DUP_PRIVATE_COPY /**< Fully duplicate (as private) */ + OBS_SCENE_DUP_PRIVATE_COPY, /**< Fully duplicate (as private) */ }; /** * Duplicates a scene. */ EXPORT obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name, - enum obs_scene_duplicate_type type); + enum obs_scene_duplicate_type type); -EXPORT void obs_scene_addref(obs_scene_t *scene); -EXPORT void obs_scene_release(obs_scene_t *scene); +EXPORT void obs_scene_addref(obs_scene_t *scene); +EXPORT void obs_scene_release(obs_scene_t *scene); /** Gets the scene's source context */ EXPORT obs_source_t *obs_scene_get_source(const obs_scene_t *scene); @@ -1426,34 +1443,38 @@ EXPORT obs_scene_t *obs_scene_from_source(const obs_source_t *source); /** Determines whether a source is within a scene */ EXPORT obs_sceneitem_t *obs_scene_find_source(obs_scene_t *scene, - const char *name); + const char *name); EXPORT obs_sceneitem_t *obs_scene_find_sceneitem_by_id(obs_scene_t *scene, - int64_t id); + int64_t id); /** Enumerates sources within a scene */ EXPORT void obs_scene_enum_items(obs_scene_t *scene, - bool (*callback)(obs_scene_t*, obs_sceneitem_t*, void*), - void *param); + bool (*callback)(obs_scene_t *, + obs_sceneitem_t *, void *), + void *param); EXPORT bool obs_scene_reorder_items(obs_scene_t *scene, - obs_sceneitem_t * const *item_order, size_t item_order_size); + obs_sceneitem_t *const *item_order, + size_t item_order_size); struct obs_sceneitem_order_info { obs_sceneitem_t *group; obs_sceneitem_t *item; }; -EXPORT bool obs_scene_reorder_items2(obs_scene_t *scene, - struct obs_sceneitem_order_info *item_order, - size_t item_order_size); +EXPORT bool +obs_scene_reorder_items2(obs_scene_t *scene, + struct obs_sceneitem_order_info *item_order, + size_t item_order_size); /** Adds/creates a new scene item for a source */ EXPORT obs_sceneitem_t *obs_scene_add(obs_scene_t *scene, obs_source_t *source); typedef void (*obs_scene_atomic_update_func)(void *, obs_scene_t *scene); EXPORT void obs_scene_atomic_update(obs_scene_t *scene, - obs_scene_atomic_update_func func, void *data); + obs_scene_atomic_update_func func, + void *data); EXPORT void obs_sceneitem_addref(obs_sceneitem_t *item); EXPORT void obs_sceneitem_release(obs_sceneitem_t *item); @@ -1475,49 +1496,50 @@ EXPORT bool obs_sceneitem_locked(const obs_sceneitem_t *item); EXPORT bool obs_sceneitem_set_locked(obs_sceneitem_t *item, bool lock); /* Functions for getting/setting specific orientation of a scene item */ -EXPORT void obs_sceneitem_set_pos(obs_sceneitem_t *item, const struct vec2 *pos); +EXPORT void obs_sceneitem_set_pos(obs_sceneitem_t *item, + const struct vec2 *pos); EXPORT void obs_sceneitem_set_rot(obs_sceneitem_t *item, float rot_deg); EXPORT void obs_sceneitem_set_scale(obs_sceneitem_t *item, - const struct vec2 *scale); + const struct vec2 *scale); EXPORT void obs_sceneitem_set_alignment(obs_sceneitem_t *item, - uint32_t alignment); + uint32_t alignment); EXPORT void obs_sceneitem_set_order(obs_sceneitem_t *item, - enum obs_order_movement movement); + enum obs_order_movement movement); EXPORT void obs_sceneitem_set_order_position(obs_sceneitem_t *item, - int position); + int position); EXPORT void obs_sceneitem_set_bounds_type(obs_sceneitem_t *item, - enum obs_bounds_type type); + enum obs_bounds_type type); EXPORT void obs_sceneitem_set_bounds_alignment(obs_sceneitem_t *item, - uint32_t alignment); + uint32_t alignment); EXPORT void obs_sceneitem_set_bounds(obs_sceneitem_t *item, - const struct vec2 *bounds); + const struct vec2 *bounds); EXPORT int64_t obs_sceneitem_get_id(const obs_sceneitem_t *item); -EXPORT void obs_sceneitem_get_pos(const obs_sceneitem_t *item, - struct vec2 *pos); +EXPORT void obs_sceneitem_get_pos(const obs_sceneitem_t *item, + struct vec2 *pos); EXPORT float obs_sceneitem_get_rot(const obs_sceneitem_t *item); -EXPORT void obs_sceneitem_get_scale(const obs_sceneitem_t *item, - struct vec2 *scale); +EXPORT void obs_sceneitem_get_scale(const obs_sceneitem_t *item, + struct vec2 *scale); EXPORT uint32_t obs_sceneitem_get_alignment(const obs_sceneitem_t *item); -EXPORT enum obs_bounds_type obs_sceneitem_get_bounds_type( - const obs_sceneitem_t *item); +EXPORT enum obs_bounds_type +obs_sceneitem_get_bounds_type(const obs_sceneitem_t *item); EXPORT uint32_t obs_sceneitem_get_bounds_alignment(const obs_sceneitem_t *item); EXPORT void obs_sceneitem_get_bounds(const obs_sceneitem_t *item, - struct vec2 *bounds); + struct vec2 *bounds); EXPORT void obs_sceneitem_get_info(const obs_sceneitem_t *item, - struct obs_transform_info *info); + struct obs_transform_info *info); EXPORT void obs_sceneitem_set_info(obs_sceneitem_t *item, - const struct obs_transform_info *info); + const struct obs_transform_info *info); EXPORT void obs_sceneitem_get_draw_transform(const obs_sceneitem_t *item, - struct matrix4 *transform); + struct matrix4 *transform); EXPORT void obs_sceneitem_get_box_transform(const obs_sceneitem_t *item, - struct matrix4 *transform); + struct matrix4 *transform); EXPORT void obs_sceneitem_get_box_scale(const obs_sceneitem_t *item, - struct vec2 *scale); + struct vec2 *scale); EXPORT bool obs_sceneitem_visible(const obs_sceneitem_t *item); EXPORT bool obs_sceneitem_set_visible(obs_sceneitem_t *item, bool visible); @@ -1530,14 +1552,14 @@ struct obs_sceneitem_crop { }; EXPORT void obs_sceneitem_set_crop(obs_sceneitem_t *item, - const struct obs_sceneitem_crop *crop); + const struct obs_sceneitem_crop *crop); EXPORT void obs_sceneitem_get_crop(const obs_sceneitem_t *item, - struct obs_sceneitem_crop *crop); + struct obs_sceneitem_crop *crop); EXPORT void obs_sceneitem_set_scale_filter(obs_sceneitem_t *item, - enum obs_scale_type filter); -EXPORT enum obs_scale_type obs_sceneitem_get_scale_filter( - obs_sceneitem_t *item); + enum obs_scale_type filter); +EXPORT enum obs_scale_type +obs_sceneitem_get_scale_filter(obs_sceneitem_t *item); EXPORT void obs_sceneitem_force_update_transform(obs_sceneitem_t *item); @@ -1549,39 +1571,41 @@ EXPORT void obs_sceneitem_defer_update_end(obs_sceneitem_t *item); EXPORT obs_data_t *obs_sceneitem_get_private_settings(obs_sceneitem_t *item); EXPORT obs_sceneitem_t *obs_scene_add_group(obs_scene_t *scene, - const char *name); + const char *name); EXPORT obs_sceneitem_t *obs_scene_insert_group(obs_scene_t *scene, - const char *name, obs_sceneitem_t **items, size_t count); + const char *name, + obs_sceneitem_t **items, + size_t count); EXPORT obs_sceneitem_t *obs_scene_get_group(obs_scene_t *scene, - const char *name); + const char *name); EXPORT bool obs_sceneitem_is_group(obs_sceneitem_t *item); -EXPORT obs_scene_t *obs_sceneitem_group_get_scene( - const obs_sceneitem_t *group); +EXPORT obs_scene_t *obs_sceneitem_group_get_scene(const obs_sceneitem_t *group); EXPORT void obs_sceneitem_group_ungroup(obs_sceneitem_t *group); EXPORT void obs_sceneitem_group_add_item(obs_sceneitem_t *group, - obs_sceneitem_t *item); + obs_sceneitem_t *item); EXPORT void obs_sceneitem_group_remove_item(obs_sceneitem_t *group, - obs_sceneitem_t *item); + obs_sceneitem_t *item); EXPORT obs_sceneitem_t *obs_sceneitem_get_group(obs_scene_t *scene, - obs_sceneitem_t *item); + obs_sceneitem_t *item); EXPORT bool obs_source_is_group(const obs_source_t *source); EXPORT bool obs_scene_is_group(const obs_scene_t *scene); EXPORT void obs_sceneitem_group_enum_items(obs_sceneitem_t *group, - bool (*callback)(obs_scene_t*, obs_sceneitem_t*, void*), - void *param); + bool (*callback)(obs_scene_t *, + obs_sceneitem_t *, + void *), + void *param); EXPORT void obs_sceneitem_defer_group_resize_begin(obs_sceneitem_t *item); EXPORT void obs_sceneitem_defer_group_resize_end(obs_sceneitem_t *item); - /* ------------------------------------------------------------------------- */ /* Outputs */ @@ -1594,7 +1618,8 @@ EXPORT const char *obs_output_get_display_name(const char *id); * directshow, or other custom outputs. */ EXPORT obs_output_t *obs_output_create(const char *id, const char *name, - obs_data_t *settings, obs_data_t *hotkey_data); + obs_data_t *settings, + obs_data_t *hotkey_data); /** * Adds/releases a reference to an output. When the last reference is @@ -1611,7 +1636,7 @@ EXPORT obs_weak_output_t *obs_output_get_weak_output(obs_output_t *output); EXPORT obs_output_t *obs_weak_output_get_output(obs_weak_output_t *weak); EXPORT bool obs_weak_output_references_output(obs_weak_output_t *weak, - obs_output_t *output); + obs_output_t *output); EXPORT const char *obs_output_get_name(const obs_output_t *output); @@ -1626,7 +1651,7 @@ EXPORT void obs_output_stop(obs_output_t *output); * this option will consume extra memory to continually increase delay while * waiting to reconnect. */ -#define OBS_OUTPUT_DELAY_PRESERVE (1<<0) +#define OBS_OUTPUT_DELAY_PRESERVE (1 << 0) /** * Sets the current output delay, in seconds (if the output supports delay). @@ -1636,7 +1661,7 @@ EXPORT void obs_output_stop(obs_output_t *output); * activated. */ EXPORT void obs_output_set_delay(obs_output_t *output, uint32_t delay_sec, - uint32_t flags); + uint32_t flags); /** Gets the currently set delay value, in seconds. */ EXPORT uint32_t obs_output_get_delay(const obs_output_t *output); @@ -1675,14 +1700,17 @@ EXPORT void obs_output_update(obs_output_t *output, obs_data_t *settings); EXPORT bool obs_output_can_pause(const obs_output_t *output); /** Pauses the output (if the functionality is allowed by the output */ -EXPORT void obs_output_pause(obs_output_t *output); +EXPORT bool obs_output_pause(obs_output_t *output, bool pause); + +/** Returns whether output is paused */ +EXPORT bool obs_output_paused(const obs_output_t *output); /* Gets the current output settings string */ EXPORT obs_data_t *obs_output_get_settings(const obs_output_t *output); /** Returns the signal handler for an output */ -EXPORT signal_handler_t *obs_output_get_signal_handler( - const obs_output_t *output); +EXPORT signal_handler_t * +obs_output_get_signal_handler(const obs_output_t *output); /** Returns the procedure handler for an output */ EXPORT proc_handler_t *obs_output_get_proc_handler(const obs_output_t *output); @@ -1691,8 +1719,8 @@ EXPORT proc_handler_t *obs_output_get_proc_handler(const obs_output_t *output); * Sets the current audio/video media contexts associated with this output, * required for non-encoded outputs. Can be null. */ -EXPORT void obs_output_set_media(obs_output_t *output, - video_t *video, audio_t *audio); +EXPORT void obs_output_set_media(obs_output_t *output, video_t *video, + audio_t *audio); /** Returns the video media context associated with this output */ EXPORT video_t *obs_output_video(const obs_output_t *output); @@ -1717,7 +1745,7 @@ EXPORT size_t obs_output_get_mixers(const obs_output_t *output); * required for encoded outputs */ EXPORT void obs_output_set_video_encoder(obs_output_t *output, - obs_encoder_t *encoder); + obs_encoder_t *encoder); /** * Sets the current audio encoder associated with this output, @@ -1728,7 +1756,7 @@ EXPORT void obs_output_set_video_encoder(obs_output_t *output, * otherwise the parameter is ignored. */ EXPORT void obs_output_set_audio_encoder(obs_output_t *output, - obs_encoder_t *encoder, size_t idx); + obs_encoder_t *encoder, size_t idx); /** Returns the current video encoder associated with this output */ EXPORT obs_encoder_t *obs_output_get_video_encoder(const obs_output_t *output); @@ -1741,11 +1769,11 @@ EXPORT obs_encoder_t *obs_output_get_video_encoder(const obs_output_t *output); * ignored. */ EXPORT obs_encoder_t *obs_output_get_audio_encoder(const obs_output_t *output, - size_t idx); + size_t idx); /** Sets the current service associated with this output. */ EXPORT void obs_output_set_service(obs_output_t *output, - obs_service_t *service); + obs_service_t *service); /** Gets the current service associated with this output. */ EXPORT obs_service_t *obs_output_get_service(const obs_output_t *output); @@ -1754,7 +1782,7 @@ EXPORT obs_service_t *obs_output_get_service(const obs_output_t *output); * Sets the reconnect settings. Set retry_count to 0 to disable reconnecting. */ EXPORT void obs_output_set_reconnect_settings(obs_output_t *output, - int retry_count, int retry_sec); + int retry_count, int retry_sec); EXPORT uint64_t obs_output_get_total_bytes(const obs_output_t *output); EXPORT int obs_output_get_frames_dropped(const obs_output_t *output); @@ -1769,7 +1797,7 @@ EXPORT int obs_output_get_total_frames(const obs_output_t *output); * then this function will trigger a warning and do nothing. */ EXPORT void obs_output_set_preferred_size(obs_output_t *output, uint32_t width, - uint32_t height); + uint32_t height); /** For video outputs, returns the width of the encoded image */ EXPORT uint32_t obs_output_get_width(const obs_output_t *output); @@ -1781,9 +1809,10 @@ EXPORT const char *obs_output_get_id(const obs_output_t *output); #if BUILD_CAPTIONS EXPORT void obs_output_output_caption_text1(obs_output_t *output, - const char *text); + const char *text); EXPORT void obs_output_output_caption_text2(obs_output_t *output, - const char *text, double display_duration); + const char *text, + double display_duration); #endif EXPORT float obs_output_get_congestion(obs_output_t *output); @@ -1793,13 +1822,13 @@ EXPORT bool obs_output_reconnecting(const obs_output_t *output); /** Pass a string of the last output error, for UI use */ EXPORT void obs_output_set_last_error(obs_output_t *output, - const char *message); + const char *message); EXPORT const char *obs_output_get_last_error(obs_output_t *output); -EXPORT const char *obs_output_get_supported_video_codecs( - const obs_output_t *output); -EXPORT const char *obs_output_get_supported_audio_codecs( - const obs_output_t *output); +EXPORT const char * +obs_output_get_supported_video_codecs(const obs_output_t *output); +EXPORT const char * +obs_output_get_supported_audio_codecs(const obs_output_t *output); /* ------------------------------------------------------------------------- */ /* Functions used by outputs */ @@ -1807,20 +1836,22 @@ EXPORT const char *obs_output_get_supported_audio_codecs( EXPORT void *obs_output_get_type_data(obs_output_t *output); /** Optionally sets the video conversion info. Used only for raw output */ -EXPORT void obs_output_set_video_conversion(obs_output_t *output, - const struct video_scale_info *conversion); +EXPORT void +obs_output_set_video_conversion(obs_output_t *output, + const struct video_scale_info *conversion); /** Optionally sets the audio conversion info. Used only for raw output */ -EXPORT void obs_output_set_audio_conversion(obs_output_t *output, - const struct audio_convert_info *conversion); +EXPORT void +obs_output_set_audio_conversion(obs_output_t *output, + const struct audio_convert_info *conversion); /** Returns whether data capture can begin with the specified flags */ EXPORT bool obs_output_can_begin_data_capture(const obs_output_t *output, - uint32_t flags); + uint32_t flags); /** Initializes encoders (if any) */ EXPORT bool obs_output_initialize_encoders(obs_output_t *output, - uint32_t flags); + uint32_t flags); /** * Begins data capture from media/encoders. @@ -1847,6 +1878,7 @@ EXPORT void obs_output_end_data_capture(obs_output_t *output); */ EXPORT void obs_output_signal_stop(obs_output_t *output, int code); +EXPORT uint64_t obs_output_get_pause_offset(obs_output_t *output); /* ------------------------------------------------------------------------- */ /* Encoders */ @@ -1862,7 +1894,8 @@ EXPORT const char *obs_encoder_get_display_name(const char *id); * @return The video encoder context, or NULL if failed or not found. */ EXPORT obs_encoder_t *obs_video_encoder_create(const char *id, const char *name, - obs_data_t *settings, obs_data_t *hotkey_data); + obs_data_t *settings, + obs_data_t *hotkey_data); /** * Creates an audio encoder context @@ -1874,8 +1907,9 @@ EXPORT obs_encoder_t *obs_video_encoder_create(const char *id, const char *name, * @return The video encoder context, or NULL if failed or not found. */ EXPORT obs_encoder_t *obs_audio_encoder_create(const char *id, const char *name, - obs_data_t *settings, size_t mixer_idx, - obs_data_t *hotkey_data); + obs_data_t *settings, + size_t mixer_idx, + obs_data_t *hotkey_data); /** * Adds/releases a reference to an encoder. When the last reference is @@ -1892,7 +1926,7 @@ EXPORT obs_weak_encoder_t *obs_encoder_get_weak_encoder(obs_encoder_t *encoder); EXPORT obs_encoder_t *obs_weak_encoder_get_encoder(obs_weak_encoder_t *weak); EXPORT bool obs_weak_encoder_references_encoder(obs_weak_encoder_t *weak, - obs_encoder_t *encoder); + obs_encoder_t *encoder); EXPORT void obs_encoder_set_name(obs_encoder_t *encoder, const char *name); EXPORT const char *obs_encoder_get_name(const obs_encoder_t *encoder); @@ -1915,7 +1949,7 @@ EXPORT enum obs_encoder_type obs_encoder_get_type(const obs_encoder_t *encoder); * a warning, and do nothing. */ EXPORT void obs_encoder_set_scaled_size(obs_encoder_t *encoder, uint32_t width, - uint32_t height); + uint32_t height); /** For video encoders, returns the width of the encoded image */ EXPORT uint32_t obs_encoder_get_width(const obs_encoder_t *encoder); @@ -1935,9 +1969,9 @@ EXPORT uint32_t obs_encoder_get_sample_rate(const obs_encoder_t *encoder); * functionality of converting only when absolutely necessary. */ EXPORT void obs_encoder_set_preferred_video_format(obs_encoder_t *encoder, - enum video_format format); -EXPORT enum video_format obs_encoder_get_preferred_video_format( - const obs_encoder_t *encoder); + enum video_format format); +EXPORT enum video_format +obs_encoder_get_preferred_video_format(const obs_encoder_t *encoder); /** Gets the default settings for an encoder type */ EXPORT obs_data_t *obs_encoder_defaults(const char *id); @@ -1960,7 +1994,7 @@ EXPORT void obs_encoder_update(obs_encoder_t *encoder, obs_data_t *settings); /** Gets extra data (headers) associated with this context */ EXPORT bool obs_encoder_get_extra_data(const obs_encoder_t *encoder, - uint8_t **extra_data, size_t *size); + uint8_t **extra_data, size_t *size); /** Returns the current settings for this encoder */ EXPORT obs_data_t *obs_encoder_get_settings(const obs_encoder_t *encoder); @@ -1997,19 +2031,21 @@ EXPORT uint32_t obs_encoder_get_caps(const obs_encoder_t *encoder); /** Duplicates an encoder packet */ DEPRECATED EXPORT void obs_duplicate_encoder_packet(struct encoder_packet *dst, - const struct encoder_packet *src); + const struct encoder_packet *src); DEPRECATED EXPORT void obs_free_encoder_packet(struct encoder_packet *packet); #endif EXPORT void obs_encoder_packet_ref(struct encoder_packet *dst, - struct encoder_packet *src); + struct encoder_packet *src); EXPORT void obs_encoder_packet_release(struct encoder_packet *packet); EXPORT void *obs_encoder_create_rerouted(obs_encoder_t *encoder, - const char *reroute_id); + const char *reroute_id); +/** Returns whether encoder is paused */ +EXPORT bool obs_encoder_paused(const obs_encoder_t *output); /* ------------------------------------------------------------------------- */ /* Stream Services */ @@ -2017,10 +2053,12 @@ EXPORT void *obs_encoder_create_rerouted(obs_encoder_t *encoder, EXPORT const char *obs_service_get_display_name(const char *id); EXPORT obs_service_t *obs_service_create(const char *id, const char *name, - obs_data_t *settings, obs_data_t *hotkey_data); + obs_data_t *settings, + obs_data_t *hotkey_data); EXPORT obs_service_t *obs_service_create_private(const char *id, - const char *name, obs_data_t *settings); + const char *name, + obs_data_t *settings); /** * Adds/releases a reference to a service. When the last reference is @@ -2037,7 +2075,7 @@ EXPORT obs_weak_service_t *obs_service_get_weak_service(obs_service_t *service); EXPORT obs_service_t *obs_weak_service_get_service(obs_weak_service_t *weak); EXPORT bool obs_weak_service_references_service(obs_weak_service_t *weak, - obs_service_t *service); + obs_service_t *service); EXPORT const char *obs_service_get_name(const obs_service_t *service); @@ -2080,9 +2118,10 @@ EXPORT const char *obs_service_get_password(const obs_service_t *service); * @param video_encoder_settings Video encoder settings. Optional. * @param audio_encoder_settings Audio encoder settings. Optional. */ -EXPORT void obs_service_apply_encoder_settings(obs_service_t *service, - obs_data_t *video_encoder_settings, - obs_data_t *audio_encoder_settings); +EXPORT void +obs_service_apply_encoder_settings(obs_service_t *service, + obs_data_t *video_encoder_settings, + obs_data_t *audio_encoder_settings); EXPORT void *obs_service_get_type_data(obs_service_t *service); @@ -2092,11 +2131,11 @@ EXPORT const char *obs_service_get_id(const obs_service_t *service); * date. */ EXPORT const char *obs_service_get_output_type(const obs_service_t *service); - /* ------------------------------------------------------------------------- */ /* Source frame allocation functions */ EXPORT void obs_source_frame_init(struct obs_source_frame *frame, - enum video_format format, uint32_t width, uint32_t height); + enum video_format format, uint32_t width, + uint32_t height); static inline void obs_source_frame_free(struct obs_source_frame *frame) { @@ -2106,12 +2145,13 @@ static inline void obs_source_frame_free(struct obs_source_frame *frame) } } -static inline struct obs_source_frame *obs_source_frame_create( - enum video_format format, uint32_t width, uint32_t height) +static inline struct obs_source_frame * +obs_source_frame_create(enum video_format format, uint32_t width, + uint32_t height) { struct obs_source_frame *frame; - frame = (struct obs_source_frame*)bzalloc(sizeof(*frame)); + frame = (struct obs_source_frame *)bzalloc(sizeof(*frame)); obs_source_frame_init(frame, format, width, height); return frame; } @@ -2125,7 +2165,7 @@ static inline void obs_source_frame_destroy(struct obs_source_frame *frame) } EXPORT void obs_source_frame_copy(struct obs_source_frame *dst, - const struct obs_source_frame *src); + const struct obs_source_frame *src); #ifdef __cplusplus } diff --git a/libobs/obs.hpp b/libobs/obs.hpp index 78780fc..d73e719 100644 --- a/libobs/obs.hpp +++ b/libobs/obs.hpp @@ -23,33 +23,31 @@ /* RAII wrappers */ -template -class OBSRef; +template class OBSRef; -using OBSSource = OBSRef; -using OBSScene = OBSRef; -using OBSSceneItem = OBSRef; -using OBSData = OBSRef; -using OBSDataArray = OBSRef; -using OBSOutput = OBSRef; -using OBSEncoder = OBSRef; -using OBSService = OBSRef; +using OBSSource = OBSRef; +using OBSScene = OBSRef; +using OBSSceneItem = + OBSRef; +using OBSData = OBSRef; +using OBSDataArray = OBSRef; +using OBSOutput = OBSRef; +using OBSEncoder = + OBSRef; +using OBSService = + OBSRef; -using OBSWeakSource = OBSRef; -using OBSWeakOutput = OBSRef; -using OBSWeakEncoder = OBSRef; -using OBSWeakService = OBSRef; +using OBSWeakSource = OBSRef; +using OBSWeakOutput = OBSRef; +using OBSWeakEncoder = OBSRef; +using OBSWeakService = OBSRef; -template -class OBSRef { +template class OBSRef { T val; inline OBSRef &Replace(T valIn) @@ -60,19 +58,20 @@ class OBSRef { return *this; } - struct TakeOwnership {}; - inline OBSRef(T val, TakeOwnership) : val(val) {} + struct TakeOwnership { + }; + inline OBSRef(T val, TakeOwnership) : val(val) {} public: - inline OBSRef() : val(nullptr) {} - inline OBSRef(T val_) : val(val_) {addref(val);} - inline OBSRef(const OBSRef &ref) : val(ref.val) {addref(val);} - inline OBSRef(OBSRef &&ref) : val(ref.val) {ref.val = nullptr;} + inline OBSRef() : val(nullptr) {} + inline OBSRef(T val_) : val(val_) { addref(val); } + inline OBSRef(const OBSRef &ref) : val(ref.val) { addref(val); } + inline OBSRef(OBSRef &&ref) : val(ref.val) { ref.val = nullptr; } - inline ~OBSRef() {release(val);} + inline ~OBSRef() { release(val); } - inline OBSRef &operator=(T valIn) {return Replace(valIn);} - inline OBSRef &operator=(const OBSRef &ref) {return Replace(ref.val);} + inline OBSRef &operator=(T valIn) { return Replace(valIn); } + inline OBSRef &operator=(const OBSRef &ref) { return Replace(ref.val); } inline OBSRef &operator=(OBSRef &&ref) { @@ -85,10 +84,10 @@ public: return *this; } - inline operator T() const {return val;} + inline operator T() const { return val; } - inline bool operator==(T p) const {return val == p;} - inline bool operator!=(T p) const {return val != p;} + inline bool operator==(T p) const { return val == p; } + inline bool operator!=(T p) const { return val != p; } friend OBSSource OBSGetStrongRef(obs_weak_source_t *weak); friend OBSWeakSource OBSGetWeakRef(obs_source_t *source); @@ -154,12 +153,12 @@ template class OBSObj { T obj; public: - inline OBSObj() : obj(nullptr) {} + inline OBSObj() : obj(nullptr) {} inline OBSObj(T obj_) : obj(obj_) {} - inline OBSObj(const OBSObj&) = delete; + inline OBSObj(const OBSObj &) = delete; inline OBSObj(OBSObj &&other) : obj(other.obj) { other.obj = nullptr; } - inline ~OBSObj() {destroy(obj);} + inline ~OBSObj() { destroy(obj); } inline OBSObj &operator=(T obj_) { @@ -168,48 +167,47 @@ public: obj = obj_; return *this; } - inline OBSObj &operator=(const OBSObj&) = delete; + inline OBSObj &operator=(const OBSObj &) = delete; inline OBSObj &operator=(OBSObj &&other) { if (obj) destroy(obj); - obj = other.obj; + obj = other.obj; other.obj = nullptr; return *this; } - inline operator T() const {return obj;} + inline operator T() const { return obj; } - inline bool operator==(T p) const {return obj == p;} - inline bool operator!=(T p) const {return obj != p;} + inline bool operator==(T p) const { return obj == p; } + inline bool operator!=(T p) const { return obj != p; } }; -using OBSDisplay = OBSObj; -using OBSView = OBSObj; +using OBSDisplay = OBSObj; +using OBSView = OBSObj; /* signal handler connection */ class OBSSignal { - signal_handler_t *handler; - const char *signal; + signal_handler_t *handler; + const char *signal; signal_callback_t callback; - void *param; + void *param; public: inline OBSSignal() - : handler (nullptr), - signal (nullptr), - callback (nullptr), - param (nullptr) - {} + : handler(nullptr), + signal(nullptr), + callback(nullptr), + param(nullptr) + { + } - inline OBSSignal(signal_handler_t *handler_, - const char *signal_, - signal_callback_t callback_, - void *param_) - : handler (handler_), - signal (signal_), - callback (callback_), - param (param_) + inline OBSSignal(signal_handler_t *handler_, const char *signal_, + signal_callback_t callback_, void *param_) + : handler(handler_), + signal(signal_), + callback(callback_), + param(param_) { signal_handler_connect_ref(handler, signal, callback, param); } @@ -217,39 +215,37 @@ public: inline void Disconnect() { signal_handler_disconnect(handler, signal, callback, param); - handler = nullptr; - signal = nullptr; + handler = nullptr; + signal = nullptr; callback = nullptr; - param = nullptr; + param = nullptr; } - inline ~OBSSignal() {Disconnect();} + inline ~OBSSignal() { Disconnect(); } - inline void Connect(signal_handler_t *handler_, - const char *signal_, - signal_callback_t callback_, - void *param_) + inline void Connect(signal_handler_t *handler_, const char *signal_, + signal_callback_t callback_, void *param_) { Disconnect(); - handler = handler_; - signal = signal_; + handler = handler_; + signal = signal_; callback = callback_; - param = param_; + param = param_; signal_handler_connect_ref(handler, signal, callback, param); } - OBSSignal(const OBSSignal&) = delete; + OBSSignal(const OBSSignal &) = delete; OBSSignal(OBSSignal &&other) - : handler (other.handler), - signal (other.signal), + : handler(other.handler), + signal(other.signal), callback(other.callback), - param (other.param) + param(other.param) { - other.handler = nullptr; - other.signal = nullptr; + other.handler = nullptr; + other.signal = nullptr; other.callback = nullptr; - other.param = nullptr; + other.param = nullptr; } OBSSignal &operator=(const OBSSignal &) = delete; @@ -257,15 +253,15 @@ public: { Disconnect(); - handler = other.handler; - signal = other.signal; + handler = other.handler; + signal = other.signal; callback = other.callback; - param = other.param; + param = other.param; - other.handler = nullptr; - other.signal = nullptr; + other.handler = nullptr; + other.signal = nullptr; other.callback = nullptr; - other.param = nullptr; + other.param = nullptr; return *this; } @@ -275,14 +271,11 @@ class OBSContext { public: inline OBSContext() {} inline OBSContext(const char *locale, - const char *module_config_path=nullptr, - profiler_name_store *store=nullptr) + const char *module_config_path = nullptr, + profiler_name_store *store = nullptr) { obs_startup(locale, module_config_path, store); } - inline ~OBSContext() - { - obs_shutdown(); - } + inline ~OBSContext() { obs_shutdown(); } }; diff --git a/libobs/util/AlignedNew.hpp b/libobs/util/AlignedNew.hpp index 1248488..3fb16f1 100644 --- a/libobs/util/AlignedNew.hpp +++ b/libobs/util/AlignedNew.hpp @@ -18,22 +18,22 @@ #include "bmem.h" -inline void* operator new(size_t size) +inline void *operator new(size_t size) { return bmalloc(size); } -inline void operator delete(void* data) +inline void operator delete(void *data) { bfree(data); } -inline void* operator new[](size_t size) +inline void *operator new[](size_t size) { return bmalloc(size); } -inline void operator delete[](void* data) +inline void operator delete[](void *data) { bfree(data); } diff --git a/libobs/util/apple/cfstring-utils.h b/libobs/util/apple/cfstring-utils.h index d131fbb..e847740 100644 --- a/libobs/util/apple/cfstring-utils.h +++ b/libobs/util/apple/cfstring-utils.h @@ -9,8 +9,8 @@ extern "C" { EXPORT char *cfstr_copy_cstr(CFStringRef cfstr, CFStringEncoding cfstr_enc); -EXPORT bool cfstr_copy_dstr(CFStringRef cfstr, CFStringEncoding cfstr_enc, - struct dstr *str); +EXPORT bool cfstr_copy_dstr(CFStringRef cfstr, CFStringEncoding cfstr_enc, + struct dstr *str); #ifdef __cplusplus } diff --git a/libobs/util/array-serializer.c b/libobs/util/array-serializer.c index c9fd71d..1d682fc 100644 --- a/libobs/util/array-serializer.c +++ b/libobs/util/array-serializer.c @@ -31,12 +31,12 @@ static int64_t array_output_get_pos(void *param) } void array_output_serializer_init(struct serializer *s, - struct array_output_data *data) + struct array_output_data *data) { memset(s, 0, sizeof(struct serializer)); memset(data, 0, sizeof(struct array_output_data)); - s->data = data; - s->write = array_output_write; + s->data = data; + s->write = array_output_write; s->get_pos = array_output_get_pos; } diff --git a/libobs/util/array-serializer.h b/libobs/util/array-serializer.h index 64bcd9d..b3143d3 100644 --- a/libobs/util/array-serializer.h +++ b/libobs/util/array-serializer.h @@ -24,5 +24,5 @@ struct array_output_data { }; EXPORT void array_output_serializer_init(struct serializer *s, - struct array_output_data *data); + struct array_output_data *data); EXPORT void array_output_serializer_free(struct array_output_data *data); diff --git a/libobs/util/base.c b/libobs/util/base.c index b7eacbf..a198ef0 100644 --- a/libobs/util/base.c +++ b/libobs/util/base.c @@ -26,12 +26,12 @@ static int log_output_level = LOG_DEBUG; static int log_output_level = LOG_INFO; #endif -static int crashing = 0; -static void *log_param = NULL; +static int crashing = 0; +static void *log_param = NULL; static void *crash_param = NULL; -static void def_log_handler(int log_level, const char *format, - va_list args, void *param) +static void def_log_handler(int log_level, const char *format, va_list args, + void *param) { char out[4096]; vsnprintf(out, sizeof(out), format, args); @@ -69,7 +69,7 @@ static void def_log_handler(int log_level, const char *format, #endif NORETURN static void def_crash_handler(const char *format, va_list args, - void *param) + void *param) { vfprintf(stderr, format, args); exit(0); @@ -93,15 +93,14 @@ void base_set_log_handler(log_handler_t handler, void *param) if (!handler) handler = def_log_handler; - log_param = param; + log_param = param; log_handler = handler; } -void base_set_crash_handler( - void (*handler)(const char *, va_list, void *), - void *param) +void base_set_crash_handler(void (*handler)(const char *, va_list, void *), + void *param) { - crash_param = param; + crash_param = param; crash_handler = handler; } diff --git a/libobs/util/base.h b/libobs/util/base.h index bf1b12f..61875a1 100644 --- a/libobs/util/base.h +++ b/libobs/util/base.h @@ -43,7 +43,7 @@ enum { * Use in creation functions and core subsystem functions. Places that * should definitely not fail. */ - LOG_ERROR = 100, + LOG_ERROR = 100, /** * Use if a problem occurs that doesn't affect the program and is @@ -57,12 +57,12 @@ enum { /** * Informative message to be displayed in the log. */ - LOG_INFO = 300, + LOG_INFO = 300, /** * Debug message to be used mostly by developers. */ - LOG_DEBUG = 400 + LOG_DEBUG = 400 }; typedef void (*log_handler_t)(int lvl, const char *msg, va_list args, void *p); @@ -70,9 +70,9 @@ typedef void (*log_handler_t)(int lvl, const char *msg, va_list args, void *p); EXPORT void base_get_log_handler(log_handler_t *handler, void **param); EXPORT void base_set_log_handler(log_handler_t handler, void *param); -EXPORT void base_set_crash_handler( - void (*handler)(const char *, va_list, void *), - void *param); +EXPORT void base_set_crash_handler(void (*handler)(const char *, va_list, + void *), + void *param); EXPORT void blogva(int log_level, const char *format, va_list args); diff --git a/libobs/util/bmem.c b/libobs/util/bmem.c index 2580966..e0ebfc5 100644 --- a/libobs/util/bmem.c +++ b/libobs/util/bmem.c @@ -43,10 +43,10 @@ static void *a_malloc(size_t size) void *ptr = NULL; long diff; - ptr = malloc(size + ALIGNMENT); + ptr = malloc(size + ALIGNMENT); if (ptr) { diff = ((~(long)ptr) & (ALIGNMENT - 1)) + 1; - ptr = (char *)ptr + diff; + ptr = (char *)ptr + diff; ((char *)ptr)[-1] = (char)diff; } @@ -66,7 +66,7 @@ static void *a_realloc(void *ptr, size_t size) if (!ptr) return a_malloc(size); diff = ((char *)ptr)[-1]; - ptr = realloc((char*)ptr - diff, size + diff); + ptr = realloc((char *)ptr - diff, size + diff); if (ptr) ptr = (char *)ptr + diff; return ptr; @@ -81,7 +81,7 @@ static void a_free(void *ptr) _aligned_free(ptr); #elif ALIGNMENT_HACK if (ptr) - free((char *)ptr - ((char*)ptr)[-1]); + free((char *)ptr - ((char *)ptr)[-1]); #else free(ptr); #endif @@ -103,7 +103,7 @@ void *bmalloc(size_t size) if (!ptr) { os_breakpoint(); bcrash("Out of memory while trying to allocate %lu bytes", - (unsigned long)size); + (unsigned long)size); } os_atomic_inc_long(&num_allocs); @@ -121,7 +121,7 @@ void *brealloc(void *ptr, size_t size) if (!ptr) { os_breakpoint(); bcrash("Out of memory while trying to allocate %lu bytes", - (unsigned long)size); + (unsigned long)size); } return ptr; diff --git a/libobs/util/bmem.h b/libobs/util/bmem.h index b96c804..ce0293e 100644 --- a/libobs/util/bmem.h +++ b/libobs/util/bmem.h @@ -57,7 +57,7 @@ static inline char *bstrdup_n(const char *str, size_t n) if (!str) return NULL; - dup = (char*)bmemdup(str, n+1); + dup = (char *)bmemdup(str, n + 1); dup[n] = 0; return dup; @@ -69,7 +69,7 @@ static inline wchar_t *bwstrdup_n(const wchar_t *str, size_t n) if (!str) return NULL; - dup = (wchar_t*)bmemdup(str, (n+1) * sizeof(wchar_t)); + dup = (wchar_t *)bmemdup(str, (n + 1) * sizeof(wchar_t)); dup[n] = 0; return dup; diff --git a/libobs/util/c99defs.h b/libobs/util/c99defs.h index c4ee627..6ea3534 100644 --- a/libobs/util/c99defs.h +++ b/libobs/util/c99defs.h @@ -27,7 +27,7 @@ #define DEPRECATED __declspec(deprecated) #define FORCE_INLINE __forceinline #else -#define DEPRECATED __attribute__ ((deprecated)) +#define DEPRECATED __attribute__((deprecated)) #define FORCE_INLINE inline __attribute__((always_inline)) #endif diff --git a/libobs/util/cf-lexer.c b/libobs/util/cf-lexer.c index 0a8dd5c..5349b4f 100644 --- a/libobs/util/cf-lexer.c +++ b/libobs/util/cf-lexer.c @@ -20,38 +20,62 @@ #include "cf-lexer.h" static inline void cf_convert_from_escape_literal(char **p_dst, - const char **p_src) + const char **p_src) { char *dst = *p_dst; const char *src = *p_src; switch (*(src++)) { - case '\'': *(dst++) = '\''; break; - case '\"': *(dst++) = '\"'; break; - case '\?': *(dst++) = '\?'; break; - case '\\': *(dst++) = '\\'; break; - case '0': *(dst++) = '\0'; break; - case 'a': *(dst++) = '\a'; break; - case 'b': *(dst++) = '\b'; break; - case 'f': *(dst++) = '\f'; break; - case 'n': *(dst++) = '\n'; break; - case 'r': *(dst++) = '\r'; break; - case 't': *(dst++) = '\t'; break; - case 'v': *(dst++) = '\v'; break; + case '\'': + *(dst++) = '\''; + break; + case '\"': + *(dst++) = '\"'; + break; + case '\?': + *(dst++) = '\?'; + break; + case '\\': + *(dst++) = '\\'; + break; + case '0': + *(dst++) = '\0'; + break; + case 'a': + *(dst++) = '\a'; + break; + case 'b': + *(dst++) = '\b'; + break; + case 'f': + *(dst++) = '\f'; + break; + case 'n': + *(dst++) = '\n'; + break; + case 'r': + *(dst++) = '\r'; + break; + case 't': + *(dst++) = '\t'; + break; + case 'v': + *(dst++) = '\v'; + break; - /* hex */ - case 'X': - case 'x': - *(dst++) = (char)strtoul(src, NULL, 16); - src += 2; - break; + /* hex */ + case 'X': + case 'x': + *(dst++) = (char)strtoul(src, NULL, 16); + src += 2; + break; - /* oct */ - default: - if (isdigit(*src)) { - *(dst++) = (char)strtoul(src, NULL, 8); - src += 3; - } + /* oct */ + default: + if (isdigit(*src)) { + *(dst++) = (char)strtoul(src, NULL, 8); + src += 3; + } /* case 'u': case 'U': */ @@ -71,7 +95,7 @@ char *cf_literal_to_str(const char *literal, size_t count) if (count < 2) return NULL; - if (literal[0] != literal[count-1]) + if (literal[0] != literal[count - 1]) return NULL; if (literal[0] != '\"' && literal[0] != '\'') return NULL; @@ -95,7 +119,7 @@ char *cf_literal_to_str(const char *literal, size_t count) } static bool cf_is_token_break(struct base_token *start_token, - const struct base_token *token) + const struct base_token *token) { switch (start_token->type) { case BASETOKEN_ALPHA: @@ -105,9 +129,9 @@ static bool cf_is_token_break(struct base_token *start_token, break; case BASETOKEN_DIGIT: - if (token->type == BASETOKEN_WHITESPACE - || (token->type == BASETOKEN_OTHER - && *token->text.array != '.')) + if (token->type == BASETOKEN_WHITESPACE || + (token->type == BASETOKEN_OTHER && + *token->text.array != '.')) return true; break; @@ -141,7 +165,7 @@ static inline bool cf_is_splice(const char *array) static inline void cf_pass_any_splices(const char **parray) { while (cf_is_splice(*parray)) - *parray += 1 + newline_size((*parray)+1); + *parray += 1 + newline_size((*parray) + 1); } static inline bool cf_is_comment(const char *array) @@ -157,7 +181,7 @@ static inline bool cf_is_comment(const char *array) } static bool cf_lexer_process_comment(struct cf_lexer *lex, - struct cf_token *out_token) + struct cf_token *out_token) { const char *offset; @@ -200,7 +224,7 @@ static bool cf_lexer_process_comment(struct cf_lexer *lex, } static inline void cf_lexer_write_strref(struct cf_lexer *lex, - const struct strref *ref) + const struct strref *ref) { strncpy(lex->write_offset, ref->array, ref->len); lex->write_offset[ref->len] = 0; @@ -214,14 +238,14 @@ static bool cf_lexer_is_include(struct cf_lexer *lex) size_t i; for (i = lex->tokens.num; i > 0; i--) { - struct cf_token *token = lex->tokens.array+(i-1); + struct cf_token *token = lex->tokens.array + (i - 1); if (is_space_or_tab(*token->str.array)) continue; if (!found_include_import) { if (strref_cmp(&token->str, "include") != 0 && - strref_cmp(&token->str, "import") != 0) + strref_cmp(&token->str, "import") != 0) break; found_include_import = true; @@ -242,8 +266,8 @@ static bool cf_lexer_is_include(struct cf_lexer *lex) } static void cf_lexer_getstrtoken(struct cf_lexer *lex, - struct cf_token *out_token, char delimiter, - bool allow_escaped_delimiters) + struct cf_token *out_token, char delimiter, + bool allow_escaped_delimiters) { const char *offset = lex->base_lexer.offset; bool escaped = false; @@ -280,7 +304,7 @@ static void cf_lexer_getstrtoken(struct cf_lexer *lex, } static bool cf_lexer_process_string(struct cf_lexer *lex, - struct cf_token *out_token) + struct cf_token *out_token) { char ch = *out_token->unmerged_str.array; @@ -290,15 +314,16 @@ static bool cf_lexer_process_string(struct cf_lexer *lex, } else if (ch == '"' || ch == '\'') { cf_lexer_getstrtoken(lex, out_token, ch, - !cf_lexer_is_include(lex)); + !cf_lexer_is_include(lex)); return true; } return false; } -static inline enum cf_token_type cf_get_token_type(const struct cf_token *token, - const struct base_token *start_token) +static inline enum cf_token_type +cf_get_token_type(const struct cf_token *token, + const struct base_token *start_token) { switch (start_token->type) { case BASETOKEN_ALPHA: @@ -338,13 +363,13 @@ static bool cf_lexer_nexttoken(struct cf_lexer *lex, struct cf_token *out_token) /* ignore escaped newlines to merge spliced lines */ if (cf_is_splice(token.text.array)) { lex->base_lexer.offset += - newline_size(token.text.array+1); + newline_size(token.text.array + 1); continue; } if (!wrote_data) { out_token->unmerged_str.array = token.text.array; - out_token->str.array = lex->write_offset; + out_token->str.array = lex->write_offset; /* if comment then output a space */ if (cf_lexer_process_comment(lex, out_token)) @@ -368,8 +393,8 @@ static bool cf_lexer_nexttoken(struct cf_lexer *lex, struct cf_token *out_token) } if (wrote_data) { - out_token->unmerged_str.len = (size_t)(lex->base_lexer.offset - - out_token->unmerged_str.array); + out_token->unmerged_str.len = (size_t)( + lex->base_lexer.offset - out_token->unmerged_str.array); out_token->type = cf_get_token_type(out_token, &start_token); } @@ -381,9 +406,9 @@ void cf_lexer_init(struct cf_lexer *lex) lexer_init(&lex->base_lexer); da_init(lex->tokens); - lex->file = NULL; - lex->reformatted = NULL; - lex->write_offset = NULL; + lex->file = NULL; + lex->reformatted = NULL; + lex->write_offset = NULL; lex->unexpected_eof = false; } @@ -394,9 +419,9 @@ void cf_lexer_free(struct cf_lexer *lex) lexer_free(&lex->base_lexer); da_free(lex->tokens); - lex->file = NULL; - lex->reformatted = NULL; - lex->write_offset = NULL; + lex->file = NULL; + lex->reformatted = NULL; + lex->write_offset = NULL; lex->unexpected_eof = false; } @@ -420,8 +445,7 @@ bool cf_lexer_lex(struct cf_lexer *lex, const char *str, const char *file) lex->write_offset = lex->reformatted; while (cf_lexer_nexttoken(lex, &token)) { - if (last_token && - is_space_or_tab(*last_token->str.array) && + if (last_token && is_space_or_tab(*last_token->str.array) && is_space_or_tab(*token.str.array)) { cf_token_add(last_token, &token); continue; @@ -476,20 +500,19 @@ static inline void macro_params_free(struct macro_params *params) { size_t i; for (i = 0; i < params->params.num; i++) - macro_param_free(params->params.array+i); + macro_param_free(params->params.array + i); da_free(params->params); } -static inline struct macro_param *get_macro_param( - const struct macro_params *params, - const struct strref *name) +static inline struct macro_param * +get_macro_param(const struct macro_params *params, const struct strref *name) { size_t i; if (!params) return NULL; for (i = 0; i < params->params.num; i++) { - struct macro_param *param = params->params.array+i; + struct macro_param *param = params->params.array + i; if (strref_cmp_strref(¶m->name.str, name) == 0) return param; } @@ -499,10 +522,10 @@ static inline struct macro_param *get_macro_param( /* ------------------------------------------------------------------------- */ -static bool cf_preprocessor(struct cf_preprocessor *pp, - bool if_block, struct cf_token **p_cur_token); -static void cf_preprocess_tokens(struct cf_preprocessor *pp, - bool if_block, struct cf_token **p_cur_token); +static bool cf_preprocessor(struct cf_preprocessor *pp, bool if_block, + struct cf_token **p_cur_token); +static void cf_preprocess_tokens(struct cf_preprocessor *pp, bool if_block, + struct cf_token **p_cur_token); static inline bool go_to_newline(struct cf_token **p_cur_token) { @@ -524,7 +547,7 @@ static inline bool next_token(struct cf_token **p_cur_token, bool preprocessor) cur_token++; /* if preprocessor, stop at newline */ - while (cur_token->type == CFTOKEN_SPACETAB && + while (cur_token->type == CFTOKEN_SPACETAB && (preprocessor || cur_token->type == CFTOKEN_NEWLINE)) cur_token++; @@ -533,79 +556,82 @@ static inline bool next_token(struct cf_token **p_cur_token, bool preprocessor) } static inline void cf_gettokenoffset(struct cf_preprocessor *pp, - const struct cf_token *token, uint32_t *row, uint32_t *col) + const struct cf_token *token, + uint32_t *row, uint32_t *col) { - lexer_getstroffset(&pp->lex->base_lexer, - token->unmerged_str.array, row, col); + lexer_getstroffset(&pp->lex->base_lexer, token->unmerged_str.array, row, + col); } static void cf_addew(struct cf_preprocessor *pp, const struct cf_token *token, - const char *message, int error_level, - const char *val1, const char *val2, const char *val3) + const char *message, int error_level, const char *val1, + const char *val2, const char *val3) { uint32_t row, col; cf_gettokenoffset(pp, token, &row, &col); if (!val1 && !val2 && !val3) { - error_data_add(pp->ed, token->lex->file, row, col, - message, error_level); + error_data_add(pp->ed, token->lex->file, row, col, message, + error_level); } else { struct dstr formatted; dstr_init(&formatted); dstr_safe_printf(&formatted, message, val1, val2, val3, NULL); error_data_add(pp->ed, token->lex->file, row, col, - formatted.array, error_level); + formatted.array, error_level); dstr_free(&formatted); } } static inline void cf_adderror(struct cf_preprocessor *pp, - const struct cf_token *token, const char *error, - const char *val1, const char *val2, const char *val3) + const struct cf_token *token, const char *error, + const char *val1, const char *val2, + const char *val3) { cf_addew(pp, token, error, LEX_ERROR, val1, val2, val3); } static inline void cf_addwarning(struct cf_preprocessor *pp, - const struct cf_token *token, const char *warning, - const char *val1, const char *val2, const char *val3) + const struct cf_token *token, + const char *warning, const char *val1, + const char *val2, const char *val3) { cf_addew(pp, token, warning, LEX_WARNING, val1, val2, val3); } static inline void cf_adderror_expecting(struct cf_preprocessor *pp, - const struct cf_token *token, const char *expecting) + const struct cf_token *token, + const char *expecting) { - cf_adderror(pp, token, "Expected $1", expecting, - NULL, NULL); + cf_adderror(pp, token, "Expected $1", expecting, NULL, NULL); } static inline void cf_adderror_expected_newline(struct cf_preprocessor *pp, - const struct cf_token *token) + const struct cf_token *token) { cf_adderror(pp, token, - "Unexpected token after preprocessor, expected " - "newline", - NULL, NULL, NULL); + "Unexpected token after preprocessor, expected " + "newline", + NULL, NULL, NULL); } -static inline void cf_adderror_unexpected_endif_eof(struct cf_preprocessor *pp, - const struct cf_token *token) +static inline void +cf_adderror_unexpected_endif_eof(struct cf_preprocessor *pp, + const struct cf_token *token) { - cf_adderror(pp, token, "Unexpected end of file before #endif", - NULL, NULL, NULL); + cf_adderror(pp, token, "Unexpected end of file before #endif", NULL, + NULL, NULL); } static inline void cf_adderror_unexpected_eof(struct cf_preprocessor *pp, - const struct cf_token *token) + const struct cf_token *token) { - cf_adderror(pp, token, "Unexpected end of file", - NULL, NULL, NULL); + cf_adderror(pp, token, "Unexpected end of file", NULL, NULL, NULL); } static inline void insert_path(struct cf_preprocessor *pp, - struct dstr *str_file) + struct dstr *str_file) { const char *file; const char *slash; @@ -623,7 +649,7 @@ static inline void insert_path(struct cf_preprocessor *pp, } static void cf_include_file(struct cf_preprocessor *pp, - const struct cf_token *file_token) + const struct cf_token *file_token) { struct cf_lexer new_lex; struct dstr str_file; @@ -634,12 +660,12 @@ static void cf_include_file(struct cf_preprocessor *pp, dstr_init(&str_file); dstr_copy_strref(&str_file, &file_token->str); - dstr_mid(&str_file, &str_file, 1, str_file.len-2); + dstr_mid(&str_file, &str_file, 1, str_file.len - 2); insert_path(pp, &str_file); /* if dependency already exists, run preprocessor on it */ for (i = 0; i < pp->dependencies.num; i++) { - struct cf_lexer *dep = pp->dependencies.array+i; + struct cf_lexer *dep = pp->dependencies.array + i; if (strcmp(dep->file, str_file.array) == 0) { tokens = cf_lexer_get_tokens(dep); @@ -651,7 +677,7 @@ static void cf_include_file(struct cf_preprocessor *pp, file = os_fopen(str_file.array, "rb"); if (!file) { cf_adderror(pp, file_token, "Could not open file '$1'", - file_token->str.array, NULL, NULL); + file_token->str.array, NULL, NULL); goto exit; } @@ -672,18 +698,18 @@ exit: static inline bool is_sys_include(struct strref *ref) { - return ref->len >= 2 && - ref->array[0] == '<' && ref->array[ref->len-1] == '>'; + return ref->len >= 2 && ref->array[0] == '<' && + ref->array[ref->len - 1] == '>'; } static inline bool is_loc_include(struct strref *ref) { - return ref->len >= 2 && - ref->array[0] == '"' && ref->array[ref->len-1] == '"'; + return ref->len >= 2 && ref->array[0] == '"' && + ref->array[ref->len - 1] == '"'; } static void cf_preprocess_include(struct cf_preprocessor *pp, - struct cf_token **p_cur_token) + struct cf_token **p_cur_token) { struct cf_token *cur_token = *p_cur_token; @@ -706,8 +732,8 @@ static void cf_preprocess_include(struct cf_preprocessor *pp, if (!pp->ignore_state) cf_include_file(pp, cur_token); } else { - cf_adderror(pp, cur_token, "Invalid or incomplete string", - NULL, NULL, NULL); + cf_adderror(pp, cur_token, "Invalid or incomplete string", NULL, + NULL, NULL); go_to_newline(&cur_token); goto exit; } @@ -719,7 +745,8 @@ exit: } static bool cf_preprocess_macro_params(struct cf_preprocessor *pp, - struct cf_def *def, struct cf_token **p_cur_token) + struct cf_def *def, + struct cf_token **p_cur_token) { struct cf_token *cur_token = *p_cur_token; bool success = false; @@ -736,9 +763,9 @@ static bool cf_preprocess_macro_params(struct cf_preprocessor *pp, cf_def_addparam(def, cur_token); next_token(&cur_token, true); - if (cur_token->type != CFTOKEN_OTHER - || (*cur_token->str.array != ',' - && *cur_token->str.array != ')')) { + if (cur_token->type != CFTOKEN_OTHER || + (*cur_token->str.array != ',' && + *cur_token->str.array != ')')) { cf_adderror_expecting(pp, cur_token, "',' or ')'"); go_to_newline(&cur_token); @@ -758,13 +785,13 @@ exit: #define INVALID_INDEX ((size_t)-1) static inline size_t cf_preprocess_get_def_idx(struct cf_preprocessor *pp, - const struct strref *def_name) + const struct strref *def_name) { struct cf_def *array = pp->defines.array; size_t i; for (i = 0; i < pp->defines.num; i++) { - struct cf_def *cur_def = array+i; + struct cf_def *cur_def = array + i; if (strref_cmp_strref(&cur_def->name.str, def_name) == 0) return i; @@ -773,23 +800,24 @@ static inline size_t cf_preprocess_get_def_idx(struct cf_preprocessor *pp, return INVALID_INDEX; } -static inline struct cf_def *cf_preprocess_get_def(struct cf_preprocessor *pp, - const struct strref *def_name) +static inline struct cf_def * +cf_preprocess_get_def(struct cf_preprocessor *pp, const struct strref *def_name) { size_t idx = cf_preprocess_get_def_idx(pp, def_name); if (idx == INVALID_INDEX) return NULL; - return pp->defines.array+idx; + return pp->defines.array + idx; } static char space_filler[2] = " "; static inline void append_space(struct cf_preprocessor *pp, - struct darray *tokens, const struct cf_token *base) + struct darray *tokens, + const struct cf_token *base) { struct cf_token token; - + strref_set(&token.str, space_filler, 1); token.type = CFTOKEN_SPACETAB; if (base) { @@ -811,7 +839,7 @@ static inline void append_end_token(struct darray *tokens) } static void cf_preprocess_define(struct cf_preprocessor *pp, - struct cf_token **p_cur_token) + struct cf_token **p_cur_token) { struct cf_token *cur_token = *p_cur_token; struct cf_def def; @@ -860,18 +888,18 @@ exit: } static inline void cf_preprocess_remove_def_strref(struct cf_preprocessor *pp, - const struct strref *ref) + const struct strref *ref) { size_t def_idx = cf_preprocess_get_def_idx(pp, ref); if (def_idx != INVALID_INDEX) { struct cf_def *array = pp->defines.array; - cf_def_free(array+def_idx); + cf_def_free(array + def_idx); da_erase(pp->defines, def_idx); } } static void cf_preprocess_undef(struct cf_preprocessor *pp, - struct cf_token **p_cur_token) + struct cf_token **p_cur_token) { struct cf_token *cur_token = *p_cur_token; @@ -896,7 +924,8 @@ exit: /* Processes an #ifdef/#ifndef/#if/#else/#elif sub block recursively */ static inline bool cf_preprocess_subblock(struct cf_preprocessor *pp, - bool ignore, struct cf_token **p_cur_token) + bool ignore, + struct cf_token **p_cur_token) { bool eof; @@ -905,7 +934,7 @@ static inline bool cf_preprocess_subblock(struct cf_preprocessor *pp, if (!pp->ignore_state) { pp->ignore_state = ignore; - cf_preprocess_tokens(pp, true, p_cur_token); + cf_preprocess_tokens(pp, true, p_cur_token); pp->ignore_state = false; } else { cf_preprocess_tokens(pp, true, p_cur_token); @@ -917,8 +946,8 @@ static inline bool cf_preprocess_subblock(struct cf_preprocessor *pp, return !eof; } -static void cf_preprocess_ifdef(struct cf_preprocessor *pp, - bool ifnot, struct cf_token **p_cur_token) +static void cf_preprocess_ifdef(struct cf_preprocessor *pp, bool ifnot, + struct cf_token **p_cur_token) { struct cf_token *cur_token = *p_cur_token; struct cf_def *def; @@ -940,7 +969,7 @@ static void cf_preprocess_ifdef(struct cf_preprocessor *pp, if (strref_cmp(&cur_token->str, "else") == 0) { if (!cf_preprocess_subblock(pp, is_true, &cur_token)) goto exit; - /*} else if (strref_cmp(&cur_token->str, "elif") == 0) {*/ + /*} else if (strref_cmp(&cur_token->str, "elif") == 0) {*/ } cur_token++; @@ -949,8 +978,8 @@ exit: *p_cur_token = cur_token; } -static bool cf_preprocessor(struct cf_preprocessor *pp, - bool if_block, struct cf_token **p_cur_token) +static bool cf_preprocessor(struct cf_preprocessor *pp, bool if_block, + struct cf_token **p_cur_token) { struct cf_token *cur_token = *p_cur_token; @@ -969,17 +998,18 @@ static bool cf_preprocessor(struct cf_preprocessor *pp, } else if (strref_cmp(&cur_token->str, "ifndef") == 0) { cf_preprocess_ifdef(pp, true, p_cur_token); - /*} else if (strref_cmp(&cur_token->str, "if") == 0) { + /*} else if (strref_cmp(&cur_token->str, "if") == 0) { TODO;*/ } else if (strref_cmp(&cur_token->str, "else") == 0 || - /*strref_cmp(&cur_token->str, "elif") == 0 ||*/ - strref_cmp(&cur_token->str, "endif") == 0) { + /*strref_cmp(&cur_token->str, "elif") == 0 ||*/ + strref_cmp(&cur_token->str, "endif") == 0) { if (!if_block) { struct dstr name; dstr_init_copy_strref(&name, &cur_token->str); - cf_adderror(pp, cur_token,"#$1 outside of " - "#if/#ifdef/#ifndef block", - name.array, NULL, NULL); + cf_adderror(pp, cur_token, + "#$1 outside of " + "#if/#ifdef/#ifndef block", + name.array, NULL, NULL); dstr_free(&name); (*p_cur_token)++; @@ -989,7 +1019,7 @@ static bool cf_preprocessor(struct cf_preprocessor *pp, return false; } else if (cur_token->type != CFTOKEN_NEWLINE && - cur_token->type != CFTOKEN_NONE) { + cur_token->type != CFTOKEN_NONE) { /* * TODO: language-specific preprocessor stuff should be sent to * handler of some sort @@ -1001,10 +1031,10 @@ static bool cf_preprocessor(struct cf_preprocessor *pp, } static void cf_preprocess_addtoken(struct cf_preprocessor *pp, - struct darray *dst, /* struct cf_token */ - struct cf_token **p_cur_token, - const struct cf_token *base, - const struct macro_params *params); + struct darray *dst, /* struct cf_token */ + struct cf_token **p_cur_token, + const struct cf_token *base, + const struct macro_params *params); /* * collects tokens for a macro parameter @@ -1013,10 +1043,10 @@ static void cf_preprocess_addtoken(struct cf_preprocessor *pp, * within a macro parameter is preserved, example MACRO(func(1, 2), 3), do not * let it stop on the comma at "1," */ -static void cf_preprocess_save_macro_param(struct cf_preprocessor *pp, - struct cf_token **p_cur_token, struct macro_param *param, - const struct cf_token *base, - const struct macro_params *cur_params) +static void cf_preprocess_save_macro_param( + struct cf_preprocessor *pp, struct cf_token **p_cur_token, + struct macro_param *param, const struct cf_token *base, + const struct macro_params *cur_params) { struct cf_token *cur_token = *p_cur_token; int brace_count = 0; @@ -1037,7 +1067,7 @@ static void cf_preprocess_save_macro_param(struct cf_preprocessor *pp, } cf_preprocess_addtoken(pp, ¶m->tokens.da, &cur_token, base, - cur_params); + cur_params); } if (cur_token->type == CFTOKEN_NONE) @@ -1064,11 +1094,10 @@ static inline bool param_is_whitespace(const struct macro_param *param) } /* collects parameter tokens of a used macro and stores them for the unwrap */ -static void cf_preprocess_save_macro_params(struct cf_preprocessor *pp, - struct cf_token **p_cur_token, const struct cf_def *def, - const struct cf_token *base, - const struct macro_params *cur_params, - struct macro_params *dst) +static void cf_preprocess_save_macro_params( + struct cf_preprocessor *pp, struct cf_token **p_cur_token, + const struct cf_def *def, const struct cf_token *base, + const struct macro_params *cur_params, struct macro_params *dst) { struct cf_token *cur_token = *p_cur_token; size_t count = 0; @@ -1086,10 +1115,10 @@ static void cf_preprocess_save_macro_params(struct cf_preprocessor *pp, count++; cf_preprocess_save_macro_param(pp, &cur_token, ¶m, base, - cur_params); - if (cur_token->type != CFTOKEN_OTHER - || (*cur_token->str.array != ',' - && *cur_token->str.array != ')')) { + cur_params); + if (cur_token->type != CFTOKEN_OTHER || + (*cur_token->str.array != ',' && + *cur_token->str.array != ')')) { macro_param_free(¶m); cf_adderror_expecting(pp, cur_token, "',' or ')'"); @@ -1107,7 +1136,7 @@ static void cf_preprocess_save_macro_params(struct cf_preprocessor *pp, if (count <= def->params.num) { cf_token_copy(¶m.name, - cf_def_getparam(def, count-1)); + cf_def_getparam(def, count - 1)); da_push_back(dst->params, ¶m); } else { macro_param_free(¶m); @@ -1116,18 +1145,17 @@ static void cf_preprocess_save_macro_params(struct cf_preprocessor *pp, if (count != def->params.num) cf_adderror(pp, cur_token, - "Mismatching number of macro parameters", - NULL, NULL, NULL); + "Mismatching number of macro parameters", NULL, + NULL, NULL); exit: *p_cur_token = cur_token; } -static inline void cf_preprocess_unwrap_param(struct cf_preprocessor *pp, - struct darray *dst, /* struct cf_token */ - struct cf_token **p_cur_token, - const struct cf_token *base, - const struct macro_param *param) +static inline void cf_preprocess_unwrap_param( + struct cf_preprocessor *pp, struct darray *dst, /* struct cf_token */ + struct cf_token **p_cur_token, const struct cf_token *base, + const struct macro_param *param) { struct cf_token *cur_token = *p_cur_token; struct cf_token *cur_param_token = param->tokens.array; @@ -1139,12 +1167,10 @@ static inline void cf_preprocess_unwrap_param(struct cf_preprocessor *pp, *p_cur_token = cur_token; } -static inline void cf_preprocess_unwrap_define(struct cf_preprocessor *pp, - struct darray *dst, /* struct cf_token */ - struct cf_token **p_cur_token, - const struct cf_token *base, - const struct cf_def *def, - const struct macro_params *cur_params) +static inline void cf_preprocess_unwrap_define( + struct cf_preprocessor *pp, struct darray *dst, /* struct cf_token */ + struct cf_token **p_cur_token, const struct cf_token *base, + const struct cf_def *def, const struct macro_params *cur_params) { struct cf_token *cur_token = *p_cur_token; struct macro_params new_params; @@ -1154,11 +1180,11 @@ static inline void cf_preprocess_unwrap_define(struct cf_preprocessor *pp, if (def->macro) cf_preprocess_save_macro_params(pp, &cur_token, def, base, - cur_params, &new_params); + cur_params, &new_params); while (cur_def_token->type != CFTOKEN_NONE) cf_preprocess_addtoken(pp, dst, &cur_def_token, base, - &new_params); + &new_params); macro_params_free(&new_params); @@ -1167,10 +1193,10 @@ static inline void cf_preprocess_unwrap_define(struct cf_preprocessor *pp, } static void cf_preprocess_addtoken(struct cf_preprocessor *pp, - struct darray *dst, /* struct cf_token */ - struct cf_token **p_cur_token, - const struct cf_token *base, - const struct macro_params *params) + struct darray *dst, /* struct cf_token */ + struct cf_token **p_cur_token, + const struct cf_token *base, + const struct macro_params *params) { struct cf_token *cur_token = *p_cur_token; @@ -1187,14 +1213,14 @@ static void cf_preprocess_addtoken(struct cf_preprocessor *pp, param = get_macro_param(params, &cur_token->str); if (param) { cf_preprocess_unwrap_param(pp, dst, &cur_token, base, - param); + param); goto exit; } def = cf_preprocess_get_def(pp, &cur_token->str); if (def) { cf_preprocess_unwrap_define(pp, dst, &cur_token, base, - def, params); + def, params); goto exit; } } @@ -1208,16 +1234,16 @@ exit: *p_cur_token = cur_token; } -static void cf_preprocess_tokens(struct cf_preprocessor *pp, - bool if_block, struct cf_token **p_cur_token) +static void cf_preprocess_tokens(struct cf_preprocessor *pp, bool if_block, + struct cf_token **p_cur_token) { bool newline = true; bool preprocessor_line = if_block; struct cf_token *cur_token = *p_cur_token; while (cur_token->type != CFTOKEN_NONE) { - if(cur_token->type != CFTOKEN_SPACETAB && - cur_token->type != CFTOKEN_NEWLINE) { + if (cur_token->type != CFTOKEN_SPACETAB && + cur_token->type != CFTOKEN_NEWLINE) { if (preprocessor_line) { cf_adderror_expected_newline(pp, cur_token); if (!go_to_newline(&cur_token)) @@ -1244,7 +1270,7 @@ static void cf_preprocess_tokens(struct cf_preprocessor *pp, } cf_preprocess_addtoken(pp, &pp->tokens.da, &cur_token, NULL, - NULL); + NULL); } *p_cur_token = cur_token; @@ -1268,12 +1294,12 @@ void cf_preprocessor_free(struct cf_preprocessor *pp) struct cf_def *defs = pp->defines.array; size_t i; - for (i = 0; i defines.num; i++) - cf_def_free(defs+i); + for (i = 0; i < pp->defines.num; i++) + cf_def_free(defs + i); for (i = 0; i < pp->sys_include_dirs.num; i++) bfree(sys_include_dirs[i]); for (i = 0; i < pp->dependencies.num; i++) - cf_lexer_free(dependencies+i); + cf_lexer_free(dependencies + i); da_free(pp->defines); da_free(pp->sys_include_dirs); @@ -1286,7 +1312,7 @@ void cf_preprocessor_free(struct cf_preprocessor *pp) } bool cf_preprocess(struct cf_preprocessor *pp, struct cf_lexer *lex, - struct error_data *ed) + struct error_data *ed) { struct cf_token *token = cf_lexer_get_tokens(lex); if (!token) @@ -1308,10 +1334,10 @@ void cf_preprocessor_add_def(struct cf_preprocessor *pp, struct cf_def *def) struct dstr name; dstr_init_copy_strref(&name, &def->name.str); cf_addwarning(pp, &def->name, "Token $1 already defined", - name.array, NULL, NULL); + name.array, NULL, NULL); cf_addwarning(pp, &existing->name, - "Previous definition of $1 is here", - name.array, NULL, NULL); + "Previous definition of $1 is here", name.array, + NULL, NULL); cf_def_free(existing); memcpy(existing, def, sizeof(struct cf_def)); @@ -1321,10 +1347,10 @@ void cf_preprocessor_add_def(struct cf_preprocessor *pp, struct cf_def *def) } void cf_preprocessor_remove_def(struct cf_preprocessor *pp, - const char *def_name) + const char *def_name) { struct strref ref; ref.array = def_name; - ref.len = strlen(def_name); + ref.len = strlen(def_name); cf_preprocess_remove_def_strref(pp, &ref); } diff --git a/libobs/util/cf-lexer.h b/libobs/util/cf-lexer.h index d33a94c..05c189d 100644 --- a/libobs/util/cf-lexer.h +++ b/libobs/util/cf-lexer.h @@ -57,13 +57,13 @@ static inline void cf_token_clear(struct cf_token *t) } static inline void cf_token_copy(struct cf_token *dst, - const struct cf_token *src) + const struct cf_token *src) { memcpy(dst, src, sizeof(struct cf_token)); } static inline void cf_token_add(struct cf_token *dst, - const struct cf_token *add) + const struct cf_token *add) { strref_add(&dst->str, &add->str); strref_add(&dst->unmerged_str, &add->unmerged_str); @@ -99,7 +99,7 @@ static inline struct cf_token *cf_lexer_get_tokens(struct cf_lexer *lex) } EXPORT bool cf_lexer_lex(struct cf_lexer *lex, const char *str, - const char *file); + const char *file); /* ------------------------------------------------------------------------- */ /* c-family preprocessor definition */ @@ -130,9 +130,9 @@ static inline void cf_def_addtoken(struct cf_def *cfd, struct cf_token *token) } static inline struct cf_token *cf_def_getparam(const struct cf_def *cfd, - size_t idx) + size_t idx) { - return cfd->params.array+idx; + return cfd->params.array + idx; } static inline void cf_def_free(struct cf_def *cfd) @@ -170,8 +170,8 @@ static inline void cf_def_free(struct cf_def *cfd) struct cf_preprocessor { struct cf_lexer *lex; struct error_data *ed; - DARRAY(struct cf_def) defines; - DARRAY(char*) sys_include_dirs; + DARRAY(struct cf_def) defines; + DARRAY(char *) sys_include_dirs; DARRAY(struct cf_lexer) dependencies; DARRAY(struct cf_token) tokens; bool ignore_state; @@ -181,22 +181,23 @@ EXPORT void cf_preprocessor_init(struct cf_preprocessor *pp); EXPORT void cf_preprocessor_free(struct cf_preprocessor *pp); EXPORT bool cf_preprocess(struct cf_preprocessor *pp, struct cf_lexer *lex, - struct error_data *ed); + struct error_data *ed); -static inline void cf_preprocessor_add_sys_include_dir( - struct cf_preprocessor *pp, const char *include_dir) +static inline void +cf_preprocessor_add_sys_include_dir(struct cf_preprocessor *pp, + const char *include_dir) { if (include_dir) da_push_back(pp->sys_include_dirs, bstrdup(include_dir)); } EXPORT void cf_preprocessor_add_def(struct cf_preprocessor *pp, - struct cf_def *def); + struct cf_def *def); EXPORT void cf_preprocessor_remove_def(struct cf_preprocessor *pp, - const char *def_name); + const char *def_name); -static inline struct cf_token *cf_preprocessor_get_tokens( - struct cf_preprocessor *pp) +static inline struct cf_token * +cf_preprocessor_get_tokens(struct cf_preprocessor *pp) { return pp->tokens.array; } diff --git a/libobs/util/cf-parser.c b/libobs/util/cf-parser.c index b4d28f1..c17b608 100644 --- a/libobs/util/cf-parser.c +++ b/libobs/util/cf-parser.c @@ -17,23 +17,22 @@ #include "cf-parser.h" void cf_adderror(struct cf_parser *p, const char *error, int level, - const char *val1, const char *val2, const char *val3) + const char *val1, const char *val2, const char *val3) { uint32_t row, col; lexer_getstroffset(&p->cur_token->lex->base_lexer, - p->cur_token->unmerged_str.array, - &row, &col); + p->cur_token->unmerged_str.array, &row, &col); if (!val1 && !val2 && !val3) { - error_data_add(&p->error_list, p->cur_token->lex->file, - row, col, error, level); + error_data_add(&p->error_list, p->cur_token->lex->file, row, + col, error, level); } else { struct dstr formatted; dstr_init(&formatted); dstr_safe_printf(&formatted, error, val1, val2, val3, NULL); - error_data_add(&p->error_list, p->cur_token->lex->file, - row, col, formatted.array, level); + error_data_add(&p->error_list, p->cur_token->lex->file, row, + col, formatted.array, level); dstr_free(&formatted); } @@ -53,7 +52,7 @@ bool cf_pass_pair(struct cf_parser *p, char in, char out) break; continue; - } else if(*p->cur_token->str.array == out) { + } else if (*p->cur_token->str.array == out) { p->cur_token++; return true; } diff --git a/libobs/util/cf-parser.h b/libobs/util/cf-parser.h index b8538d2..a90976d 100644 --- a/libobs/util/cf-parser.h +++ b/libobs/util/cf-parser.h @@ -30,19 +30,19 @@ extern "C" { #endif -#define PARSE_SUCCESS 0 -#define PARSE_CONTINUE -1 -#define PARSE_BREAK -2 +#define PARSE_SUCCESS 0 +#define PARSE_CONTINUE -1 +#define PARSE_BREAK -2 #define PARSE_UNEXPECTED_CONTINUE -3 -#define PARSE_UNEXPECTED_BREAK -4 -#define PARSE_EOF -5 +#define PARSE_UNEXPECTED_BREAK -4 +#define PARSE_EOF -5 struct cf_parser { - struct cf_lexer lex; + struct cf_lexer lex; struct cf_preprocessor pp; - struct error_data error_list; + struct error_data error_list; - struct cf_token *cur_token; + struct cf_token *cur_token; }; static inline void cf_parser_init(struct cf_parser *parser) @@ -63,8 +63,8 @@ static inline void cf_parser_free(struct cf_parser *parser) parser->cur_token = NULL; } -static inline bool cf_parser_parse(struct cf_parser *parser, - const char *str, const char *file) +static inline bool cf_parser_parse(struct cf_parser *parser, const char *str, + const char *file) { if (!cf_lexer_lex(&parser->lex, str, file)) return false; @@ -76,26 +76,23 @@ static inline bool cf_parser_parse(struct cf_parser *parser, return true; } -EXPORT void cf_adderror(struct cf_parser *parser, const char *error, - int level, const char *val1, const char *val2, - const char *val3); +EXPORT void cf_adderror(struct cf_parser *parser, const char *error, int level, + const char *val1, const char *val2, const char *val3); static inline void cf_adderror_expecting(struct cf_parser *p, - const char *expected) + const char *expected) { cf_adderror(p, "Expected '$1'", LEX_ERROR, expected, NULL, NULL); } static inline void cf_adderror_unexpected_eof(struct cf_parser *p) { - cf_adderror(p, "Unexpected EOF", LEX_ERROR, - NULL, NULL, NULL); + cf_adderror(p, "Unexpected EOF", LEX_ERROR, NULL, NULL, NULL); } static inline void cf_adderror_syntax_error(struct cf_parser *p) { - cf_adderror(p, "Syntax error", LEX_ERROR, - NULL, NULL, NULL); + cf_adderror(p, "Syntax error", LEX_ERROR, NULL, NULL, NULL); } static inline bool cf_next_token(struct cf_parser *p) @@ -124,8 +121,8 @@ static inline bool cf_next_valid_token(struct cf_parser *p) EXPORT bool cf_pass_pair(struct cf_parser *p, char in, char out); -static inline bool cf_go_to_token(struct cf_parser *p, - const char *str1, const char *str2) +static inline bool cf_go_to_token(struct cf_parser *p, const char *str1, + const char *str2) { while (cf_next_token(p)) { if (strref_cmp(&p->cur_token->str, str1) == 0) { @@ -141,8 +138,8 @@ static inline bool cf_go_to_token(struct cf_parser *p, return false; } -static inline bool cf_go_to_valid_token(struct cf_parser *p, - const char *str1, const char *str2) +static inline bool cf_go_to_valid_token(struct cf_parser *p, const char *str1, + const char *str2) { if (!cf_go_to_token(p, str1, str2)) { cf_adderror_unexpected_eof(p); @@ -153,17 +150,16 @@ static inline bool cf_go_to_valid_token(struct cf_parser *p, } static inline bool cf_go_to_token_type(struct cf_parser *p, - enum cf_token_type type) + enum cf_token_type type) { - while (p->cur_token->type != CFTOKEN_NONE && - p->cur_token->type != type) + while (p->cur_token->type != CFTOKEN_NONE && p->cur_token->type != type) p->cur_token++; return p->cur_token->type != CFTOKEN_NONE; } -static inline int cf_token_should_be(struct cf_parser *p, - const char *str, const char *goto1, const char *goto2) +static inline int cf_token_should_be(struct cf_parser *p, const char *str, + const char *goto1, const char *goto2) { if (strref_cmp(&p->cur_token->str, str) == 0) return PARSE_SUCCESS; @@ -177,8 +173,8 @@ static inline int cf_token_should_be(struct cf_parser *p, return PARSE_CONTINUE; } -static inline int cf_next_token_should_be(struct cf_parser *p, - const char *str, const char *goto1, const char *goto2) +static inline int cf_next_token_should_be(struct cf_parser *p, const char *str, + const char *goto1, const char *goto2) { if (!cf_next_token(p)) { cf_adderror_unexpected_eof(p); @@ -208,7 +204,7 @@ static inline bool cf_peek_token(struct cf_parser *p, struct cf_token *peek) } static inline bool cf_peek_valid_token(struct cf_parser *p, - struct cf_token *peek) + struct cf_token *peek) { bool success = cf_peek_token(p, peek); if (!success) @@ -221,9 +217,9 @@ static inline bool cf_token_is(struct cf_parser *p, const char *val) return strref_cmp(&p->cur_token->str, val) == 0; } -static inline int cf_token_is_type(struct cf_parser *p, - enum cf_token_type type, const char *type_expected, - const char *goto_token) +static inline int cf_token_is_type(struct cf_parser *p, enum cf_token_type type, + const char *type_expected, + const char *goto_token) { if (p->cur_token->type != type) { cf_adderror_expecting(p, type_expected); @@ -242,8 +238,8 @@ static inline void cf_copy_token(struct cf_parser *p, char **dst) *dst = bstrdup_n(p->cur_token->str.array, p->cur_token->str.len); } -static inline int cf_get_name(struct cf_parser *p, char **dst, - const char *name, const char *goto_token) +static inline int cf_get_name(struct cf_parser *p, char **dst, const char *name, + const char *goto_token) { int errcode; @@ -256,7 +252,7 @@ static inline int cf_get_name(struct cf_parser *p, char **dst, } static inline int cf_next_name(struct cf_parser *p, char **dst, - const char *name, const char *goto_token) + const char *name, const char *goto_token) { if (!cf_next_valid_token(p)) return PARSE_EOF; @@ -274,7 +270,7 @@ static inline int cf_next_token_copy(struct cf_parser *p, char **dst) } static inline int cf_get_name_ref(struct cf_parser *p, struct strref *dst, - const char *name, const char *goto_token) + const char *name, const char *goto_token) { int errcode; @@ -287,7 +283,7 @@ static inline int cf_get_name_ref(struct cf_parser *p, struct strref *dst, } static inline int cf_next_name_ref(struct cf_parser *p, struct strref *dst, - const char *name, const char *goto_token) + const char *name, const char *goto_token) { if (!cf_next_valid_token(p)) return PARSE_EOF; diff --git a/libobs/util/circlebuf.h b/libobs/util/circlebuf.h index b991612..da97bbe 100644 --- a/libobs/util/circlebuf.h +++ b/libobs/util/circlebuf.h @@ -30,7 +30,7 @@ extern "C" { /* Dynamic circular buffer */ struct circlebuf { - void *data; + void *data; size_t size; size_t start_pos; @@ -50,7 +50,7 @@ static inline void circlebuf_free(struct circlebuf *cb) } static inline void circlebuf_reorder_data(struct circlebuf *cb, - size_t new_capacity) + size_t new_capacity) { size_t difference; uint8_t *data; @@ -59,8 +59,8 @@ static inline void circlebuf_reorder_data(struct circlebuf *cb, return; difference = new_capacity - cb->capacity; - data = (uint8_t*)cb->data + cb->start_pos; - memmove(data+difference, data, cb->capacity - cb->start_pos); + data = (uint8_t *)cb->data + cb->start_pos; + memmove(data + difference, data, cb->capacity - cb->start_pos); cb->start_pos += difference; } @@ -70,7 +70,7 @@ static inline void circlebuf_ensure_capacity(struct circlebuf *cb) if (cb->size <= cb->capacity) return; - new_capacity = cb->capacity*2; + new_capacity = cb->capacity * 2; if (cb->size > new_capacity) new_capacity = cb->size; @@ -105,12 +105,12 @@ static inline void circlebuf_upsize(struct circlebuf *cb, size_t size) size_t loop_size = add_size - back_size; if (back_size) - memset((uint8_t*)cb->data + cb->end_pos, 0, back_size); + memset((uint8_t *)cb->data + cb->end_pos, 0, back_size); memset(cb->data, 0, loop_size); new_end_pos -= cb->capacity; } else { - memset((uint8_t*)cb->data + cb->end_pos, 0, add_size); + memset((uint8_t *)cb->data + cb->end_pos, 0, add_size); } cb->end_pos = new_end_pos; @@ -118,7 +118,7 @@ static inline void circlebuf_upsize(struct circlebuf *cb, size_t size) /** Overwrites data at a specific point in the buffer (relative). */ static inline void circlebuf_place(struct circlebuf *cb, size_t position, - const void *data, size_t size) + const void *data, size_t size) { size_t end_point = position + size; size_t data_end_pos; @@ -136,15 +136,15 @@ static inline void circlebuf_place(struct circlebuf *cb, size_t position, size_t loop_size = size - back_size; if (back_size) - memcpy((uint8_t*)cb->data + position, data, loop_size); - memcpy(cb->data, (uint8_t*)data + loop_size, back_size); + memcpy((uint8_t *)cb->data + position, data, loop_size); + memcpy(cb->data, (uint8_t *)data + loop_size, back_size); } else { - memcpy((uint8_t*)cb->data + position, data, size); + memcpy((uint8_t *)cb->data + position, data, size); } } static inline void circlebuf_push_back(struct circlebuf *cb, const void *data, - size_t size) + size_t size) { size_t new_end_pos = cb->end_pos + size; @@ -156,20 +156,20 @@ static inline void circlebuf_push_back(struct circlebuf *cb, const void *data, size_t loop_size = size - back_size; if (back_size) - memcpy((uint8_t*)cb->data + cb->end_pos, data, - back_size); - memcpy(cb->data, (uint8_t*)data + back_size, loop_size); + memcpy((uint8_t *)cb->data + cb->end_pos, data, + back_size); + memcpy(cb->data, (uint8_t *)data + back_size, loop_size); new_end_pos -= cb->capacity; } else { - memcpy((uint8_t*)cb->data + cb->end_pos, data, size); + memcpy((uint8_t *)cb->data + cb->end_pos, data, size); } cb->end_pos = new_end_pos; } static inline void circlebuf_push_front(struct circlebuf *cb, const void *data, - size_t size) + size_t size) { cb->size += size; circlebuf_ensure_capacity(cb); @@ -178,14 +178,14 @@ static inline void circlebuf_push_front(struct circlebuf *cb, const void *data, size_t back_size = size - cb->start_pos; if (cb->start_pos) - memcpy(cb->data, (uint8_t*)data + back_size, - cb->start_pos); + memcpy(cb->data, (uint8_t *)data + back_size, + cb->start_pos); cb->start_pos = cb->capacity - back_size; - memcpy((uint8_t*)cb->data + cb->start_pos, data, back_size); + memcpy((uint8_t *)cb->data + cb->start_pos, data, back_size); } else { cb->start_pos -= size; - memcpy((uint8_t*)cb->data + cb->start_pos, data, size); + memcpy((uint8_t *)cb->data + cb->start_pos, data, size); } } @@ -201,12 +201,12 @@ static inline void circlebuf_push_back_zero(struct circlebuf *cb, size_t size) size_t loop_size = size - back_size; if (back_size) - memset((uint8_t*)cb->data + cb->end_pos, 0, back_size); + memset((uint8_t *)cb->data + cb->end_pos, 0, back_size); memset(cb->data, 0, loop_size); new_end_pos -= cb->capacity; } else { - memset((uint8_t*)cb->data + cb->end_pos, 0, size); + memset((uint8_t *)cb->data + cb->end_pos, 0, size); } cb->end_pos = new_end_pos; @@ -224,15 +224,15 @@ static inline void circlebuf_push_front_zero(struct circlebuf *cb, size_t size) memset(cb->data, 0, cb->start_pos); cb->start_pos = cb->capacity - back_size; - memset((uint8_t*)cb->data + cb->start_pos, 0, back_size); + memset((uint8_t *)cb->data + cb->start_pos, 0, back_size); } else { cb->start_pos -= size; - memset((uint8_t*)cb->data + cb->start_pos, 0, size); + memset((uint8_t *)cb->data + cb->start_pos, 0, size); } } static inline void circlebuf_peek_front(struct circlebuf *cb, void *data, - size_t size) + size_t size) { assert(size <= cb->size); @@ -240,18 +240,18 @@ static inline void circlebuf_peek_front(struct circlebuf *cb, void *data, size_t start_size = cb->capacity - cb->start_pos; if (start_size < size) { - memcpy(data, (uint8_t*)cb->data + cb->start_pos, - start_size); - memcpy((uint8_t*)data + start_size, cb->data, - size - start_size); + memcpy(data, (uint8_t *)cb->data + cb->start_pos, + start_size); + memcpy((uint8_t *)data + start_size, cb->data, + size - start_size); } else { - memcpy(data, (uint8_t*)cb->data + cb->start_pos, size); + memcpy(data, (uint8_t *)cb->data + cb->start_pos, size); } } } static inline void circlebuf_peek_back(struct circlebuf *cb, void *data, - size_t size) + size_t size) { assert(size <= cb->size); @@ -262,19 +262,19 @@ static inline void circlebuf_peek_back(struct circlebuf *cb, void *data, size_t front_size = size - back_size; size_t new_end_pos = cb->capacity - front_size; - memcpy((uint8_t*)data + (size - back_size), cb->data, - back_size); - memcpy(data, (uint8_t*)cb->data + new_end_pos, - front_size); + memcpy((uint8_t *)data + (size - back_size), cb->data, + back_size); + memcpy(data, (uint8_t *)cb->data + new_end_pos, + front_size); } else { - memcpy(data, (uint8_t*)cb->data + cb->end_pos - size, - size); + memcpy(data, (uint8_t *)cb->data + cb->end_pos - size, + size); } } } static inline void circlebuf_pop_front(struct circlebuf *cb, void *data, - size_t size) + size_t size) { circlebuf_peek_front(cb, data, size); @@ -290,7 +290,7 @@ static inline void circlebuf_pop_front(struct circlebuf *cb, void *data, } static inline void circlebuf_pop_back(struct circlebuf *cb, void *data, - size_t size) + size_t size) { circlebuf_peek_back(cb, data, size); @@ -308,7 +308,7 @@ static inline void circlebuf_pop_back(struct circlebuf *cb, void *data, static inline void *circlebuf_data(struct circlebuf *cb, size_t idx) { - uint8_t *ptr = (uint8_t*)cb->data; + uint8_t *ptr = (uint8_t *)cb->data; size_t offset = cb->start_pos + idx; if (idx >= cb->size) diff --git a/libobs/util/config-file.c b/libobs/util/config-file.c index 317f810..cdd447b 100644 --- a/libobs/util/config-file.c +++ b/libobs/util/config-file.c @@ -48,7 +48,7 @@ static inline void config_section_free(struct config_section *section) size_t i; for (i = 0; i < section->items.num; i++) - config_item_free(items+i); + config_item_free(items + i); darray_free(§ion->items); bfree(section->name); @@ -100,13 +100,12 @@ static inline void remove_ref_whitespace(struct strref *ref) ref->len--; } - while (ref->len && is_whitespace(ref->array[ref->len-1])) + while (ref->len && is_whitespace(ref->array[ref->len - 1])) ref->len--; } } -static bool config_parse_string(struct lexer *lex, struct strref *ref, - char end) +static bool config_parse_string(struct lexer *lex, struct strref *ref, char end) { bool success = end != 0; struct base_token token; @@ -149,7 +148,7 @@ static void unescape(struct dstr *str) } else if (next == 'r') { cur = '\r'; read++; - } else if (next =='n') { + } else if (next == 'n') { cur = '\n'; read++; } @@ -164,7 +163,7 @@ static void unescape(struct dstr *str) } static void config_add_item(struct darray *items, struct strref *name, - struct strref *value) + struct strref *value) { struct config_item item; struct dstr item_value; @@ -172,13 +171,13 @@ static void config_add_item(struct darray *items, struct strref *name, unescape(&item_value); - item.name = bstrdup_n(name->array, name->len); + item.name = bstrdup_n(name->array, name->len); item.value = item_value.array; darray_push_back(sizeof(struct config_item), items, &item); } static void config_parse_section(struct config_section *section, - struct lexer *lex) + struct lexer *lex) { struct base_token token; @@ -193,8 +192,9 @@ static void config_parse_section(struct config_section *section, if (token.type == BASETOKEN_OTHER) { if (*token.text.array == '#') { do { - if (!lexer_getbasetoken(lex, &token, - PARSE_WHITESPACE)) + if (!lexer_getbasetoken( + lex, &token, + PARSE_WHITESPACE)) return; } while (!is_newline(*token.text.array)); @@ -214,10 +214,10 @@ static void config_parse_section(struct config_section *section, if (strref_is_empty(&value)) { struct config_item item; - item.name = bstrdup_n(name.array, name.len); + item.name = bstrdup_n(name.array, name.len); item.value = bzalloc(1); darray_push_back(sizeof(struct config_item), - §ion->items, &item); + §ion->items, &item); } else { config_add_item(§ion->items, &name, &value); } @@ -255,15 +255,14 @@ static void parse_config_data(struct darray *sections, struct lexer *lex) return; section = darray_push_back_new(sizeof(struct config_section), - sections); - section->name = bstrdup_n(section_name.array, - section_name.len); + sections); + section->name = bstrdup_n(section_name.array, section_name.len); config_parse_section(section, lex); } } static int config_parse_file(struct darray *sections, const char *file, - bool always_open) + bool always_open) { char *file_data; struct lexer lex; @@ -379,10 +378,10 @@ int config_save(config_t *config) for (i = 0; i < config->sections.num; i++) { struct config_section *section = darray_item( - sizeof(struct config_section), - &config->sections, i); + sizeof(struct config_section), &config->sections, i); - if (i) dstr_cat(&str, "\n"); + if (i) + dstr_cat(&str, "\n"); dstr_cat(&str, "["); dstr_cat(&str, section->name); @@ -390,8 +389,7 @@ int config_save(config_t *config) for (j = 0; j < section->items.num; j++) { struct config_item *item = darray_item( - sizeof(struct config_item), - §ion->items, j); + sizeof(struct config_item), §ion->items, j); dstr_copy(&tmp, item->value ? item->value : ""); dstr_replace(&tmp, "\\", "\\\\"); @@ -426,7 +424,7 @@ cleanup: } int config_save_safe(config_t *config, const char *temp_ext, - const char *backup_ext) + const char *backup_ext) { struct dstr temp_file = {0}; struct dstr backup_file = {0}; @@ -435,7 +433,7 @@ int config_save_safe(config_t *config, const char *temp_ext, if (!temp_ext || !*temp_ext) { blog(LOG_ERROR, "config_save_safe: invalid " - "temporary extension specified"); + "temporary extension specified"); return CONFIG_ERROR; } @@ -451,8 +449,10 @@ int config_save_safe(config_t *config, const char *temp_ext, config->file = file; if (ret != CONFIG_SUCCESS) { - blog(LOG_ERROR, "config_save_safe: failed to " - "write to %s", temp_file.array); + blog(LOG_ERROR, + "config_save_safe: failed to " + "write to %s", + temp_file.array); goto cleanup; } @@ -478,15 +478,16 @@ void config_close(config_t *config) struct config_section *defaults, *sections; size_t i; - if (!config) return; + if (!config) + return; defaults = config->defaults.array; sections = config->sections.array; for (i = 0; i < config->defaults.num; i++) - config_section_free(defaults+i); + config_section_free(defaults + i); for (i = 0; i < config->sections.num; i++) - config_section_free(sections+i); + config_section_free(sections + i); darray_free(&config->defaults); darray_free(&config->sections); @@ -511,7 +512,7 @@ const char *config_get_section(config_t *config, size_t idx) goto unlock; section = darray_item(sizeof(struct config_section), &config->sections, - idx); + idx); name = section->name; unlock: @@ -520,19 +521,20 @@ unlock: } static const struct config_item *config_find_item(const struct darray *sections, - const char *section, const char *name) + const char *section, + const char *name) { size_t i, j; for (i = 0; i < sections->num; i++) { - const struct config_section *sec = darray_item( - sizeof(struct config_section), sections, i); + const struct config_section *sec = + darray_item(sizeof(struct config_section), sections, i); if (astrcmpi(sec->name, section) == 0) { for (j = 0; j < sec->items.num; j++) { - struct config_item *item = darray_item( - sizeof(struct config_item), - &sec->items, j); + struct config_item *item = + darray_item(sizeof(struct config_item), + &sec->items, j); if (astrcmpi(item->name, name) == 0) return item; @@ -544,7 +546,7 @@ static const struct config_item *config_find_item(const struct darray *sections, } static void config_set_item(config_t *config, struct darray *sections, - const char *section, const char *name, char *value) + const char *section, const char *name, char *value) { struct config_section *sec = NULL; struct config_section *array = sections->array; @@ -554,12 +556,12 @@ static void config_set_item(config_t *config, struct darray *sections, pthread_mutex_lock(&config->mutex); for (i = 0; i < sections->num; i++) { - struct config_section *cur_sec = array+i; + struct config_section *cur_sec = array + i; struct config_item *items = cur_sec->items.array; if (astrcmpi(cur_sec->name, section) == 0) { for (j = 0; j < cur_sec->items.num; j++) { - item = items+j; + item = items + j; if (astrcmpi(item->name, name) == 0) { bfree(item->value); @@ -575,20 +577,20 @@ static void config_set_item(config_t *config, struct darray *sections, if (!sec) { sec = darray_push_back_new(sizeof(struct config_section), - sections); + sections); sec->name = bstrdup(section); } item = darray_push_back_new(sizeof(struct config_item), &sec->items); - item->name = bstrdup(name); + item->name = bstrdup(name); item->value = value; unlock: pthread_mutex_unlock(&config->mutex); } -void config_set_string(config_t *config, const char *section, - const char *name, const char *value) +void config_set_string(config_t *config, const char *section, const char *name, + const char *value) { if (!value) value = ""; @@ -596,33 +598,33 @@ void config_set_string(config_t *config, const char *section, bstrdup(value)); } -void config_set_int(config_t *config, const char *section, - const char *name, int64_t value) +void config_set_int(config_t *config, const char *section, const char *name, + int64_t value) { struct dstr str; dstr_init(&str); - dstr_printf(&str, "%"PRId64, value); + dstr_printf(&str, "%" PRId64, value); config_set_item(config, &config->sections, section, name, str.array); } -void config_set_uint(config_t *config, const char *section, - const char *name, uint64_t value) +void config_set_uint(config_t *config, const char *section, const char *name, + uint64_t value) { struct dstr str; dstr_init(&str); - dstr_printf(&str, "%"PRIu64, value); + dstr_printf(&str, "%" PRIu64, value); config_set_item(config, &config->sections, section, name, str.array); } -void config_set_bool(config_t *config, const char *section, - const char *name, bool value) +void config_set_bool(config_t *config, const char *section, const char *name, + bool value) { char *str = bstrdup(value ? "true" : "false"); config_set_item(config, &config->sections, section, name, str); } -void config_set_double(config_t *config, const char *section, - const char *name, double value) +void config_set_double(config_t *config, const char *section, const char *name, + double value) { char *str = bzalloc(64); os_dtostr(value, str, 64); @@ -630,7 +632,7 @@ void config_set_double(config_t *config, const char *section, } void config_set_default_string(config_t *config, const char *section, - const char *name, const char *value) + const char *name, const char *value) { if (!value) value = ""; @@ -639,32 +641,32 @@ void config_set_default_string(config_t *config, const char *section, } void config_set_default_int(config_t *config, const char *section, - const char *name, int64_t value) + const char *name, int64_t value) { struct dstr str; dstr_init(&str); - dstr_printf(&str, "%"PRId64, value); + dstr_printf(&str, "%" PRId64, value); config_set_item(config, &config->defaults, section, name, str.array); } void config_set_default_uint(config_t *config, const char *section, - const char *name, uint64_t value) + const char *name, uint64_t value) { struct dstr str; dstr_init(&str); - dstr_printf(&str, "%"PRIu64, value); + dstr_printf(&str, "%" PRIu64, value); config_set_item(config, &config->defaults, section, name, str.array); } void config_set_default_bool(config_t *config, const char *section, - const char *name, bool value) + const char *name, bool value) { char *str = bstrdup(value ? "true" : "false"); config_set_item(config, &config->defaults, section, name, str); } void config_set_default_double(config_t *config, const char *section, - const char *name, double value) + const char *name, double value) { struct dstr str; dstr_init(&str); @@ -673,7 +675,7 @@ void config_set_default_double(config_t *config, const char *section, } const char *config_get_string(config_t *config, const char *section, - const char *name) + const char *name) { const struct config_item *item; const char *value = NULL; @@ -712,8 +714,7 @@ static inline uint64_t str_to_uint64(const char *str) return strtoull(str, NULL, 10); } -int64_t config_get_int(config_t *config, const char *section, - const char *name) +int64_t config_get_int(config_t *config, const char *section, const char *name) { const char *value = config_get_string(config, section, name); if (value) @@ -723,7 +724,7 @@ int64_t config_get_int(config_t *config, const char *section, } uint64_t config_get_uint(config_t *config, const char *section, - const char *name) + const char *name) { const char *value = config_get_string(config, section, name); if (value) @@ -732,19 +733,17 @@ uint64_t config_get_uint(config_t *config, const char *section, return 0; } -bool config_get_bool(config_t *config, const char *section, - const char *name) +bool config_get_bool(config_t *config, const char *section, const char *name) { const char *value = config_get_string(config, section, name); if (value) - return astrcmpi(value, "true") == 0 || - !!str_to_uint64(value); + return astrcmpi(value, "true") == 0 || !!str_to_uint64(value); return false; } double config_get_double(config_t *config, const char *section, - const char *name) + const char *name) { const char *value = config_get_string(config, section, name); if (value) @@ -754,7 +753,7 @@ double config_get_double(config_t *config, const char *section, } bool config_remove_value(config_t *config, const char *section, - const char *name) + const char *name) { struct darray *sections = &config->sections; bool success = false; @@ -762,21 +761,20 @@ bool config_remove_value(config_t *config, const char *section, pthread_mutex_lock(&config->mutex); for (size_t i = 0; i < sections->num; i++) { - struct config_section *sec = darray_item( - sizeof(struct config_section), sections, i); + struct config_section *sec = + darray_item(sizeof(struct config_section), sections, i); if (astrcmpi(sec->name, section) != 0) continue; for (size_t j = 0; j < sec->items.num; j++) { struct config_item *item = darray_item( - sizeof(struct config_item), - &sec->items, j); + sizeof(struct config_item), &sec->items, j); if (astrcmpi(item->name, name) == 0) { config_item_free(item); darray_erase(sizeof(struct config_item), - &sec->items, j); + &sec->items, j); success = true; goto unlock; } @@ -788,8 +786,8 @@ unlock: return success; } -const char *config_get_default_string(config_t *config, - const char *section, const char *name) +const char *config_get_default_string(config_t *config, const char *section, + const char *name) { const struct config_item *item; const char *value = NULL; @@ -805,7 +803,7 @@ const char *config_get_default_string(config_t *config, } int64_t config_get_default_int(config_t *config, const char *section, - const char *name) + const char *name) { const char *value = config_get_default_string(config, section, name); if (value) @@ -815,7 +813,7 @@ int64_t config_get_default_int(config_t *config, const char *section, } uint64_t config_get_default_uint(config_t *config, const char *section, - const char *name) + const char *name) { const char *value = config_get_default_string(config, section, name); if (value) @@ -825,18 +823,17 @@ uint64_t config_get_default_uint(config_t *config, const char *section, } bool config_get_default_bool(config_t *config, const char *section, - const char *name) + const char *name) { const char *value = config_get_default_string(config, section, name); if (value) - return astrcmpi(value, "true") == 0 || - !!str_to_uint64(value); + return astrcmpi(value, "true") == 0 || !!str_to_uint64(value); return false; } double config_get_default_double(config_t *config, const char *section, - const char *name) + const char *name) { const char *value = config_get_default_string(config, section, name); if (value) @@ -846,7 +843,7 @@ double config_get_default_double(config_t *config, const char *section, } bool config_has_user_value(config_t *config, const char *section, - const char *name) + const char *name) { bool success; pthread_mutex_lock(&config->mutex); @@ -856,7 +853,7 @@ bool config_has_user_value(config_t *config, const char *section, } bool config_has_default_value(config_t *config, const char *section, - const char *name) + const char *name) { bool success; pthread_mutex_lock(&config->mutex); @@ -864,4 +861,3 @@ bool config_has_default_value(config_t *config, const char *section, pthread_mutex_unlock(&config->mutex); return success; } - diff --git a/libobs/util/config-file.h b/libobs/util/config-file.h index 7c61b6a..ff8bfc4 100644 --- a/libobs/util/config-file.h +++ b/libobs/util/config-file.h @@ -32,9 +32,9 @@ extern "C" { struct config_data; typedef struct config_data config_t; -#define CONFIG_SUCCESS 0 +#define CONFIG_SUCCESS 0 #define CONFIG_FILENOTFOUND -1 -#define CONFIG_ERROR -2 +#define CONFIG_ERROR -2 enum config_open_type { CONFIG_OPEN_EXISTING, @@ -43,40 +43,40 @@ enum config_open_type { EXPORT config_t *config_create(const char *file); EXPORT int config_open(config_t **config, const char *file, - enum config_open_type open_type); + enum config_open_type open_type); EXPORT int config_open_string(config_t **config, const char *str); EXPORT int config_save(config_t *config); EXPORT int config_save_safe(config_t *config, const char *temp_ext, - const char *backup_ext); + const char *backup_ext); EXPORT void config_close(config_t *config); EXPORT size_t config_num_sections(config_t *config); EXPORT const char *config_get_section(config_t *config, size_t idx); EXPORT void config_set_string(config_t *config, const char *section, - const char *name, const char *value); + const char *name, const char *value); EXPORT void config_set_int(config_t *config, const char *section, - const char *name, int64_t value); + const char *name, int64_t value); EXPORT void config_set_uint(config_t *config, const char *section, - const char *name, uint64_t value); + const char *name, uint64_t value); EXPORT void config_set_bool(config_t *config, const char *section, - const char *name, bool value); + const char *name, bool value); EXPORT void config_set_double(config_t *config, const char *section, - const char *name, double value); + const char *name, double value); -EXPORT const char *config_get_string(config_t *config, - const char *section, const char *name); +EXPORT const char *config_get_string(config_t *config, const char *section, + const char *name); EXPORT int64_t config_get_int(config_t *config, const char *section, - const char *name); + const char *name); EXPORT uint64_t config_get_uint(config_t *config, const char *section, - const char *name); + const char *name); EXPORT bool config_get_bool(config_t *config, const char *section, - const char *name); + const char *name); EXPORT double config_get_double(config_t *config, const char *section, - const char *name); + const char *name); EXPORT bool config_remove_value(config_t *config, const char *section, - const char *name); + const char *name); /* * DEFAULT VALUES @@ -95,33 +95,34 @@ EXPORT bool config_remove_value(config_t *config, const char *section, EXPORT int config_open_defaults(config_t *config, const char *file); EXPORT void config_set_default_string(config_t *config, const char *section, - const char *name, const char *value); + const char *name, const char *value); EXPORT void config_set_default_int(config_t *config, const char *section, - const char *name, int64_t value); + const char *name, int64_t value); EXPORT void config_set_default_uint(config_t *config, const char *section, - const char *name, uint64_t value); + const char *name, uint64_t value); EXPORT void config_set_default_bool(config_t *config, const char *section, - const char *name, bool value); + const char *name, bool value); EXPORT void config_set_default_double(config_t *config, const char *section, - const char *name, double value); + const char *name, double value); /* These functions allow you to get the current default values rather than get * the actual values. Probably almost never really needed */ EXPORT const char *config_get_default_string(config_t *config, - const char *section, const char *name); -EXPORT int64_t config_get_default_int(config_t *config, - const char *section, const char *name); -EXPORT uint64_t config_get_default_uint(config_t *config, - const char *section, const char *name); -EXPORT bool config_get_default_bool(config_t *config, - const char *section, const char *name); -EXPORT double config_get_default_double(config_t *config, - const char *section, const char *name); + const char *section, + const char *name); +EXPORT int64_t config_get_default_int(config_t *config, const char *section, + const char *name); +EXPORT uint64_t config_get_default_uint(config_t *config, const char *section, + const char *name); +EXPORT bool config_get_default_bool(config_t *config, const char *section, + const char *name); +EXPORT double config_get_default_double(config_t *config, const char *section, + const char *name); -EXPORT bool config_has_user_value(config_t *config, - const char *section, const char *name); -EXPORT bool config_has_default_value(config_t *config, - const char *section, const char *name); +EXPORT bool config_has_user_value(config_t *config, const char *section, + const char *name); +EXPORT bool config_has_default_value(config_t *config, const char *section, + const char *name); #ifdef __cplusplus } diff --git a/libobs/util/crc32.c b/libobs/util/crc32.c index 0416eb0..61eb99a 100644 --- a/libobs/util/crc32.c +++ b/libobs/util/crc32.c @@ -21,16 +21,16 @@ static uint32_t crc32_tab[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, - 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, - 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, @@ -62,8 +62,7 @@ static uint32_t crc32_tab[] = { 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; uint32_t calc_crc32(uint32_t crc, const void *buf, size_t size) { diff --git a/libobs/util/darray.h b/libobs/util/darray.h index 69e1c40..6faa948 100644 --- a/libobs/util/darray.h +++ b/libobs/util/darray.h @@ -46,50 +46,50 @@ struct darray { static inline void darray_init(struct darray *dst) { - dst->array = NULL; - dst->num = 0; + dst->array = NULL; + dst->num = 0; dst->capacity = 0; } static inline void darray_free(struct darray *dst) { bfree(dst->array); - dst->array = NULL; - dst->num = 0; + dst->array = NULL; + dst->num = 0; dst->capacity = 0; } static inline size_t darray_alloc_size(const size_t element_size, - const struct darray *da) + const struct darray *da) { - return element_size*da->num; + return element_size * da->num; } static inline void *darray_item(const size_t element_size, - const struct darray *da, size_t idx) + const struct darray *da, size_t idx) { - return (void*)(((uint8_t*)da->array) + element_size*idx); + return (void *)(((uint8_t *)da->array) + element_size * idx); } static inline void *darray_end(const size_t element_size, - const struct darray *da) + const struct darray *da) { if (!da->num) return NULL; - return darray_item(element_size, da, da->num-1); + return darray_item(element_size, da, da->num - 1); } -static inline void darray_reserve(const size_t element_size, - struct darray *dst, const size_t capacity) +static inline void darray_reserve(const size_t element_size, struct darray *dst, + const size_t capacity) { void *ptr; if (capacity == 0 || capacity <= dst->num) return; - ptr = bmalloc(element_size*capacity); + ptr = bmalloc(element_size * capacity); if (dst->num) - memcpy(ptr, dst->array, element_size*dst->num); + memcpy(ptr, dst->array, element_size * dst->num); if (dst->array) bfree(dst->array); dst->array = ptr; @@ -97,27 +97,28 @@ static inline void darray_reserve(const size_t element_size, } static inline void darray_ensure_capacity(const size_t element_size, - struct darray *dst, const size_t new_size) + struct darray *dst, + const size_t new_size) { size_t new_cap; void *ptr; if (new_size <= dst->capacity) return; - new_cap = (!dst->capacity) ? new_size : dst->capacity*2; + new_cap = (!dst->capacity) ? new_size : dst->capacity * 2; if (new_size > new_cap) new_cap = new_size; - ptr = bmalloc(element_size*new_cap); + ptr = bmalloc(element_size * new_cap); if (dst->capacity) - memcpy(ptr, dst->array, element_size*dst->capacity); + memcpy(ptr, dst->array, element_size * dst->capacity); if (dst->array) bfree(dst->array); dst->array = ptr; dst->capacity = new_cap; } -static inline void darray_resize(const size_t element_size, - struct darray *dst, const size_t size) +static inline void darray_resize(const size_t element_size, struct darray *dst, + const size_t size) { int b_clear; size_t old_num; @@ -137,38 +138,40 @@ static inline void darray_resize(const size_t element_size, if (b_clear) memset(darray_item(element_size, dst, old_num), 0, - element_size * (dst->num-old_num)); + element_size * (dst->num - old_num)); } static inline void darray_copy(const size_t element_size, struct darray *dst, - const struct darray *da) + const struct darray *da) { if (da->num == 0) { darray_free(dst); } else { darray_resize(element_size, dst, da->num); - memcpy(dst->array, da->array, element_size*da->num); + memcpy(dst->array, da->array, element_size * da->num); } } static inline void darray_copy_array(const size_t element_size, - struct darray *dst, const void *array, const size_t num) + struct darray *dst, const void *array, + const size_t num) { darray_resize(element_size, dst, num); - memcpy(dst->array, array, element_size*dst->num); + memcpy(dst->array, array, element_size * dst->num); } static inline void darray_move(struct darray *dst, struct darray *src) { darray_free(dst); memcpy(dst, src, sizeof(struct darray)); - src->array = NULL; + src->array = NULL; src->capacity = 0; - src->num = 0; + src->num = 0; } static inline size_t darray_find(const size_t element_size, - const struct darray *da, const void *item, const size_t idx) + const struct darray *da, const void *item, + const size_t idx) { size_t i; @@ -184,16 +187,16 @@ static inline size_t darray_find(const size_t element_size, } static inline size_t darray_push_back(const size_t element_size, - struct darray *dst, const void *item) + struct darray *dst, const void *item) { darray_ensure_capacity(element_size, dst, ++dst->num); memcpy(darray_end(element_size, dst), item, element_size); - return dst->num-1; + return dst->num - 1; } static inline void *darray_push_back_new(const size_t element_size, - struct darray *dst) + struct darray *dst) { void *last; @@ -205,7 +208,8 @@ static inline void *darray_push_back_new(const size_t element_size, } static inline size_t darray_push_back_array(const size_t element_size, - struct darray *dst, const void *array, const size_t num) + struct darray *dst, + const void *array, const size_t num) { size_t old_num; if (!dst) @@ -214,21 +218,22 @@ static inline size_t darray_push_back_array(const size_t element_size, return dst->num; old_num = dst->num; - darray_resize(element_size, dst, dst->num+num); + darray_resize(element_size, dst, dst->num + num); memcpy(darray_item(element_size, dst, old_num), array, - element_size*num); + element_size * num); return old_num; } static inline size_t darray_push_back_darray(const size_t element_size, - struct darray *dst, const struct darray *da) + struct darray *dst, + const struct darray *da) { return darray_push_back_array(element_size, dst, da->array, da->num); } static inline void darray_insert(const size_t element_size, struct darray *dst, - const size_t idx, const void *item) + const size_t idx, const void *item) { void *new_item; size_t move_count; @@ -245,13 +250,13 @@ static inline void darray_insert(const size_t element_size, struct darray *dst, new_item = darray_item(element_size, dst, idx); - memmove(darray_item(element_size, dst, idx+1), new_item, - move_count*element_size); + memmove(darray_item(element_size, dst, idx + 1), new_item, + move_count * element_size); memcpy(new_item, item, element_size); } static inline void *darray_insert_new(const size_t element_size, - struct darray *dst, const size_t idx) + struct darray *dst, const size_t idx) { void *item; size_t move_count; @@ -264,16 +269,16 @@ static inline void *darray_insert_new(const size_t element_size, move_count = dst->num - idx; darray_ensure_capacity(element_size, dst, ++dst->num); - memmove(darray_item(element_size, dst, idx+1), item, - move_count*element_size); + memmove(darray_item(element_size, dst, idx + 1), item, + move_count * element_size); memset(item, 0, element_size); return item; } static inline void darray_insert_array(const size_t element_size, - struct darray *dst, const size_t idx, - const void *array, const size_t num) + struct darray *dst, const size_t idx, + const void *array, const size_t num) { size_t old_num; @@ -282,22 +287,23 @@ static inline void darray_insert_array(const size_t element_size, assert(idx < dst->num); old_num = dst->num; - darray_resize(element_size, dst, dst->num+num); + darray_resize(element_size, dst, dst->num + num); - memmove(darray_item(element_size, dst, idx+num), - darray_item(element_size, dst, idx), - element_size*(old_num-idx)); - memcpy(darray_item(element_size, dst, idx), array, element_size*num); + memmove(darray_item(element_size, dst, idx + num), + darray_item(element_size, dst, idx), + element_size * (old_num - idx)); + memcpy(darray_item(element_size, dst, idx), array, element_size * num); } static inline void darray_insert_darray(const size_t element_size, - struct darray *dst, const size_t idx, const struct darray *da) + struct darray *dst, const size_t idx, + const struct darray *da) { darray_insert_array(element_size, dst, idx, da->array, da->num); } static inline void darray_erase(const size_t element_size, struct darray *dst, - const size_t idx) + const size_t idx) { assert(idx < dst->num); @@ -305,12 +311,12 @@ static inline void darray_erase(const size_t element_size, struct darray *dst, return; memmove(darray_item(element_size, dst, idx), - darray_item(element_size, dst, idx+1), - element_size*(dst->num-idx)); + darray_item(element_size, dst, idx + 1), + element_size * (dst->num - idx)); } static inline void darray_erase_item(const size_t element_size, - struct darray *dst, const void *item) + struct darray *dst, const void *item) { size_t idx = darray_find(element_size, dst, item, 0); if (idx != DARRAY_INVALID) @@ -318,7 +324,8 @@ static inline void darray_erase_item(const size_t element_size, } static inline void darray_erase_range(const size_t element_size, - struct darray *dst, const size_t start, const size_t end) + struct darray *dst, const size_t start, + const size_t end) { size_t count, move_count; @@ -326,7 +333,7 @@ static inline void darray_erase_range(const size_t element_size, assert(end <= dst->num); assert(end > start); - count = end-start; + count = end - start; if (count == 1) { darray_erase(element_size, dst, start); return; @@ -338,30 +345,31 @@ static inline void darray_erase_range(const size_t element_size, move_count = dst->num - end; if (move_count) memmove(darray_item(element_size, dst, start), - darray_item(element_size, dst, end), - move_count * element_size); + darray_item(element_size, dst, end), + move_count * element_size); dst->num -= count; } static inline void darray_pop_back(const size_t element_size, - struct darray *dst) + struct darray *dst) { assert(dst->num != 0); if (dst->num) - darray_erase(element_size, dst, dst->num-1); + darray_erase(element_size, dst, dst->num - 1); } static inline void darray_join(const size_t element_size, struct darray *dst, - struct darray *da) + struct darray *da) { darray_push_back_darray(element_size, dst, da); darray_free(da); } static inline void darray_split(const size_t element_size, struct darray *dst1, - struct darray *dst2, const struct darray *da, const size_t idx) + struct darray *dst2, const struct darray *da, + const size_t idx) { struct darray temp; @@ -377,43 +385,44 @@ static inline void darray_split(const size_t element_size, struct darray *dst1, if (da->num) { if (idx) darray_copy_array(element_size, dst1, temp.array, - temp.num); - if (idx < temp.num-1) + temp.num); + if (idx < temp.num - 1) darray_copy_array(element_size, dst2, - darray_item(element_size, &temp, idx), - temp.num-idx); + darray_item(element_size, &temp, idx), + temp.num - idx); } darray_free(&temp); } static inline void darray_move_item(const size_t element_size, - struct darray *dst, const size_t from, const size_t to) + struct darray *dst, const size_t from, + const size_t to) { void *temp, *p_from, *p_to; if (from == to) return; - temp = malloc(element_size); + temp = malloc(element_size); p_from = darray_item(element_size, dst, from); - p_to = darray_item(element_size, dst, to); + p_to = darray_item(element_size, dst, to); memcpy(temp, p_from, element_size); if (to < from) - memmove(darray_item(element_size, dst, to+1), p_to, - element_size*(from-to)); + memmove(darray_item(element_size, dst, to + 1), p_to, + element_size * (from - to)); else - memmove(p_from, darray_item(element_size, dst, from+1), - element_size*(to-from)); + memmove(p_from, darray_item(element_size, dst, from + 1), + element_size * (to - from)); memcpy(p_to, temp, element_size); free(temp); } -static inline void darray_swap(const size_t element_size, - struct darray *dst, const size_t a, const size_t b) +static inline void darray_swap(const size_t element_size, struct darray *dst, + const size_t a, const size_t b) { void *temp, *a_ptr, *b_ptr; @@ -423,13 +432,13 @@ static inline void darray_swap(const size_t element_size, if (a == b) return; - temp = malloc(element_size); + temp = malloc(element_size); a_ptr = darray_item(element_size, dst, a); b_ptr = darray_item(element_size, dst, b); - memcpy(temp, a_ptr, element_size); + memcpy(temp, a_ptr, element_size); memcpy(a_ptr, b_ptr, element_size); - memcpy(b_ptr, temp, element_size); + memcpy(b_ptr, temp, element_size); free(temp); } @@ -457,7 +466,7 @@ static inline void darray_swap(const size_t element_size, #define da_free(v) darray_free(&v.da) -#define da_alloc_size(v) (sizeof(*v.array)*v.num) +#define da_alloc_size(v) (sizeof(*v.array) * v.num) #define da_end(v) darray_end(sizeof(*v.array), &v.da) @@ -466,16 +475,14 @@ static inline void darray_swap(const size_t element_size, #define da_resize(v, size) darray_resize(sizeof(*v.array), &v.da, size) -#define da_copy(dst, src) \ - darray_copy(sizeof(*dst.array), &dst.da, &src.da) +#define da_copy(dst, src) darray_copy(sizeof(*dst.array), &dst.da, &src.da) #define da_copy_array(dst, src_array, n) \ darray_copy_array(sizeof(*dst.array), &dst.da, src_array, n) #define da_move(dst, src) darray_move(&dst.da, &src.da) -#define da_find(v, item, idx) \ - darray_find(sizeof(*v.array), &v.da, item, idx) +#define da_find(v, item, idx) darray_find(sizeof(*v.array), &v.da, item, idx) #define da_push_back(v, item) darray_push_back(sizeof(*v.array), &v.da, item) @@ -490,19 +497,15 @@ static inline void darray_swap(const size_t element_size, #define da_insert(v, idx, item) \ darray_insert(sizeof(*v.array), &v.da, idx, item) -#define da_insert_new(v, idx) \ - darray_insert_new(sizeof(*v.array), &v.da, idx) +#define da_insert_new(v, idx) darray_insert_new(sizeof(*v.array), &v.da, idx) #define da_insert_array(dst, idx, src_array, n) \ - darray_insert_array(sizeof(*dst.array), &dst.da, idx, \ - src_array, n) + darray_insert_array(sizeof(*dst.array), &dst.da, idx, src_array, n) #define da_insert_da(dst, idx, src) \ - darray_insert_darray(sizeof(*dst.array), &dst.da, idx, \ - &src.da) + darray_insert_darray(sizeof(*dst.array), &dst.da, idx, &src.da) -#define da_erase(dst, idx) \ - darray_erase(sizeof(*dst.array), &dst.da, idx) +#define da_erase(dst, idx) darray_erase(sizeof(*dst.array), &dst.da, idx) #define da_erase_item(dst, item) \ darray_erase_item(sizeof(*dst.array), &dst.da, item) @@ -510,21 +513,17 @@ static inline void darray_swap(const size_t element_size, #define da_erase_range(dst, from, to) \ darray_erase_range(sizeof(*dst.array), &dst.da, from, to) -#define da_pop_back(dst) \ - darray_pop_back(sizeof(*dst.array), &dst.da); +#define da_pop_back(dst) darray_pop_back(sizeof(*dst.array), &dst.da); -#define da_join(dst, src) \ - darray_join(sizeof(*dst.array), &dst.da, &src.da) +#define da_join(dst, src) darray_join(sizeof(*dst.array), &dst.da, &src.da) #define da_split(dst1, dst2, src, idx) \ - darray_split(sizeof(*src.array), &dst1.da, &dst2.da, \ - &src.da, idx) + darray_split(sizeof(*src.array), &dst1.da, &dst2.da, &src.da, idx) #define da_move_item(v, from, to) \ darray_move_item(sizeof(*v.array), &v.da, from, to) -#define da_swap(v, idx1, idx2) \ - darray_swap(sizeof(*v.array), &v.da, idx1, idx2) +#define da_swap(v, idx1, idx2) darray_swap(sizeof(*v.array), &v.da, idx1, idx2) #ifdef __cplusplus } diff --git a/libobs/util/dstr.c b/libobs/util/dstr.c index 9764504..0f6ec09 100644 --- a/libobs/util/dstr.c +++ b/libobs/util/dstr.c @@ -174,7 +174,7 @@ char *astrstri(const char *str, const char *find) do { if (astrcmpi_n(str, find, len) == 0) - return (char*)str; + return (char *)str; } while (*str++); return NULL; @@ -191,7 +191,7 @@ wchar_t *wstrstri(const wchar_t *str, const wchar_t *find) do { if (wstrcmpi_n(str, find, len) == 0) - return (wchar_t*)str; + return (wchar_t *)str; } while (*str++); return NULL; @@ -205,7 +205,7 @@ static inline bool is_padding(char ch) char *strdepad(char *str) { char *temp; - size_t len; + size_t len; if (!str) return str; @@ -223,7 +223,7 @@ char *strdepad(char *str) memmove(str, temp, len + 1); if (len) { - temp = str + (len-1); + temp = str + (len - 1); while (is_padding(*temp)) *(temp--) = 0; } @@ -234,7 +234,7 @@ char *strdepad(char *str) wchar_t *wcsdepad(wchar_t *str) { wchar_t *temp; - size_t len; + size_t len; if (!str) return str; @@ -249,10 +249,10 @@ wchar_t *wcsdepad(wchar_t *str) len = wcslen(str); if (temp != str) - memmove(str, temp, (len+1) * sizeof(wchar_t)); + memmove(str, temp, (len + 1) * sizeof(wchar_t)); if (len) { - temp = str + (len-1); + temp = str + (len - 1); while (*temp == ' ' || *temp == '\t') *(temp--) = 0; } @@ -264,9 +264,9 @@ char **strlist_split(const char *str, char split_ch, bool include_empty) { const char *cur_str = str; const char *next_str; - char * out = NULL; - size_t count = 0; - size_t total_size = 0; + char *out = NULL; + size_t count = 0; + size_t total_size = 0; if (str) { char **table; @@ -295,16 +295,16 @@ char **strlist_split(const char *str, char split_ch, bool include_empty) /* ------------------ */ - cur_pos = (count + 1) * sizeof(char *); + cur_pos = (count + 1) * sizeof(char *); total_size += cur_pos; - out = bmalloc(total_size); - offset = out + cur_pos; - table = (char **)out; + out = bmalloc(total_size); + offset = out + cur_pos; + table = (char **)out; /* ------------------ */ next_str = strchr(str, split_ch); - cur_str = str; + cur_str = str; while (next_str) { size_t size = next_str - cur_str; @@ -328,7 +328,7 @@ char **strlist_split(const char *str, char split_ch, bool include_empty) table[cur_idx] = NULL; } - return (char**)out; + return (char **)out; } void strlist_free(char **strlist) @@ -379,7 +379,7 @@ void dstr_ncopy(struct dstr *dst, const char *array, const size_t len) return; dst->array = bmemdup(array, len + 1); - dst->len = len; + dst->len = len; dst->capacity = len + 1; dst->array[len] = 0; @@ -397,7 +397,7 @@ void dstr_ncopy_dstr(struct dstr *dst, const struct dstr *str, const size_t len) newlen = size_min(len, str->len); dst->array = bmemdup(str->array, newlen + 1); - dst->len = newlen; + dst->len = newlen; dst->capacity = newlen + 1; dst->array[newlen] = 0; @@ -412,7 +412,7 @@ void dstr_cat_dstr(struct dstr *dst, const struct dstr *str) new_len = dst->len + str->len; dstr_ensure_capacity(dst, new_len + 1); - memcpy(dst->array+dst->len, str->array, str->len + 1); + memcpy(dst->array + dst->len, str->array, str->len + 1); dst->len = new_len; } @@ -430,7 +430,7 @@ void dstr_ncat(struct dstr *dst, const char *array, const size_t len) new_len = dst->len + len; dstr_ensure_capacity(dst, new_len + 1); - memcpy(dst->array+dst->len, array, len); + memcpy(dst->array + dst->len, array, len); dst->len = new_len; dst->array[new_len] = 0; @@ -446,7 +446,7 @@ void dstr_ncat_dstr(struct dstr *dst, const struct dstr *str, const size_t len) new_len = dst->len + in_len; dstr_ensure_capacity(dst, new_len + 1); - memcpy(dst->array+dst->len, str->array, in_len); + memcpy(dst->array + dst->len, str->array, in_len); dst->len = new_len; dst->array[new_len] = 0; @@ -467,14 +467,14 @@ void dstr_insert(struct dstr *dst, const size_t idx, const char *array) dstr_ensure_capacity(dst, new_len + 1); - memmove(dst->array+idx+len, dst->array+idx, dst->len - idx + 1); - memcpy(dst->array+idx, array, len); + memmove(dst->array + idx + len, dst->array + idx, dst->len - idx + 1); + memcpy(dst->array + idx, array, len); dst->len = new_len; } void dstr_insert_dstr(struct dstr *dst, const size_t idx, - const struct dstr *str) + const struct dstr *str) { size_t new_len; if (!str->len) @@ -486,10 +486,11 @@ void dstr_insert_dstr(struct dstr *dst, const size_t idx, new_len = dst->len + str->len; - dstr_ensure_capacity(dst, (new_len+1)); + dstr_ensure_capacity(dst, (new_len + 1)); - memmove(dst->array+idx+str->len, dst->array+idx, dst->len - idx + 1); - memcpy(dst->array+idx, str->array, str->len); + memmove(dst->array + idx + str->len, dst->array + idx, + dst->len - idx + 1); + memcpy(dst->array + idx, str->array, str->len); dst->len = new_len; } @@ -501,8 +502,8 @@ void dstr_insert_ch(struct dstr *dst, const size_t idx, const char ch) return; } - dstr_ensure_capacity(dst, (++dst->len+1)); - memmove(dst->array+idx+1, dst->array+idx, dst->len - idx + 1); + dstr_ensure_capacity(dst, (++dst->len + 1)); + memmove(dst->array + idx + 1, dst->array + idx, dst->len - idx + 1); dst->array[idx] = ch; } @@ -516,13 +517,13 @@ void dstr_remove(struct dstr *dst, const size_t idx, const size_t count) return; } - end = idx+count; + end = idx + count; if (end == dst->len) dst->array[idx] = 0; else - memmove(dst->array+idx, dst->array+end, dst->len - end + 1); + memmove(dst->array + idx, dst->array + end, dst->len - end + 1); - dst->len -= count; + dst->len -= count; } void dstr_printf(struct dstr *dst, const char *format, ...) @@ -549,7 +550,8 @@ void dstr_vprintf(struct dstr *dst, const char *format, va_list args) int len = vsnprintf(NULL, 0, format, args_cp); va_end(args_cp); - if (len < 0) len = 4095; + if (len < 0) + len = 4095; dstr_ensure_capacity(dst, ((size_t)len) + 1); len = vsnprintf(dst->array, ((size_t)len) + 1, format, args); @@ -570,8 +572,9 @@ void dstr_vcatf(struct dstr *dst, const char *format, va_list args) int len = vsnprintf(NULL, 0, format, args_cp); va_end(args_cp); - if (len < 0) len = 4095; - + if (len < 0) + len = 4095; + dstr_ensure_capacity(dst, dst->len + ((size_t)len) + 1); len = vsnprintf(dst->array + dst->len, ((size_t)len) + 1, format, args); @@ -583,9 +586,8 @@ void dstr_vcatf(struct dstr *dst, const char *format, va_list args) dst->len += len < 0 ? strlen(dst->array + dst->len) : (size_t)len; } -void dstr_safe_printf(struct dstr *dst, const char *format, - const char *val1, const char *val2, const char *val3, - const char *val4) +void dstr_safe_printf(struct dstr *dst, const char *format, const char *val1, + const char *val2, const char *val3, const char *val4) { dstr_copy(dst, format); if (val1) @@ -598,8 +600,7 @@ void dstr_safe_printf(struct dstr *dst, const char *format, dstr_replace(dst, "$4", val4); } -void dstr_replace(struct dstr *str, const char *find, - const char *replace) +void dstr_replace(struct dstr *str, const char *find, const char *replace) { size_t find_len, replace_len; char *temp; @@ -610,7 +611,7 @@ void dstr_replace(struct dstr *str, const char *find, if (!replace) replace = ""; - find_len = strlen(find); + find_len = strlen(find); replace_len = strlen(replace); temp = str->array; @@ -618,11 +619,11 @@ void dstr_replace(struct dstr *str, const char *find, unsigned long count = 0; while ((temp = strstr(temp, find)) != NULL) { - char *end = temp+find_len; + char *end = temp + find_len; size_t end_len = strlen(end); if (end_len) { - memmove(temp+replace_len, end, end_len + 1); + memmove(temp + replace_len, end, end_len + 1); if (replace_len) memcpy(temp, replace, replace_len); } else { @@ -634,7 +635,7 @@ void dstr_replace(struct dstr *str, const char *find, } if (count) - str->len += (replace_len-find_len) * count; + str->len += (replace_len - find_len) * count; } else if (replace_len > find_len) { unsigned long count = 0; @@ -647,16 +648,16 @@ void dstr_replace(struct dstr *str, const char *find, if (!count) return; - str->len += (replace_len-find_len) * count; + str->len += (replace_len - find_len) * count; dstr_ensure_capacity(str, str->len + 1); temp = str->array; while ((temp = strstr(temp, find)) != NULL) { - char *end = temp+find_len; + char *end = temp + find_len; size_t end_len = strlen(end); if (end_len) { - memmove(temp+replace_len, end, end_len + 1); + memmove(temp + replace_len, end, end_len + 1); memcpy(temp, replace, replace_len); } else { strcpy(temp, replace); @@ -692,12 +693,12 @@ void dstr_left(struct dstr *dst, const struct dstr *str, const size_t pos) } void dstr_mid(struct dstr *dst, const struct dstr *str, const size_t start, - const size_t count) + const size_t count) { struct dstr temp; dstr_init(&temp); dstr_copy_dstr(&temp, str); - dstr_ncopy(dst, temp.array+start, count); + dstr_ncopy(dst, temp.array + start, count); dstr_free(&temp); } @@ -705,7 +706,7 @@ void dstr_right(struct dstr *dst, const struct dstr *str, const size_t pos) { struct dstr temp; dstr_init(&temp); - dstr_ncopy(&temp, str->array+pos, str->len-pos); + dstr_ncopy(&temp, str->array + pos, str->len - pos); dstr_copy_dstr(dst, &temp); dstr_free(&temp); } @@ -736,7 +737,7 @@ void dstr_from_wcs(struct dstr *dst, const wchar_t *wstr) if (len) { dstr_resize(dst, len); - wchar_to_utf8(wstr, 0, dst->array, len+1, 0); + wchar_to_utf8(wstr, 0, dst->array, len + 1, 0); } else { dstr_free(dst); } diff --git a/libobs/util/dstr.h b/libobs/util/dstr.h index a07ae1c..4f02948 100644 --- a/libobs/util/dstr.h +++ b/libobs/util/dstr.h @@ -66,7 +66,7 @@ static inline void dstr_init_move(struct dstr *dst, struct dstr *src); static inline void dstr_init_move_array(struct dstr *dst, char *str); static inline void dstr_init_copy(struct dstr *dst, const char *src); static inline void dstr_init_copy_dstr(struct dstr *dst, - const struct dstr *src); + const struct dstr *src); EXPORT void dstr_init_copy_strref(struct dstr *dst, const struct strref *src); static inline void dstr_free(struct dstr *dst); @@ -79,10 +79,9 @@ EXPORT void dstr_copy(struct dstr *dst, const char *array); static inline void dstr_copy_dstr(struct dstr *dst, const struct dstr *src); EXPORT void dstr_copy_strref(struct dstr *dst, const struct strref *src); -EXPORT void dstr_ncopy(struct dstr *dst, const char *array, - const size_t len); +EXPORT void dstr_ncopy(struct dstr *dst, const char *array, const size_t len); EXPORT void dstr_ncopy_dstr(struct dstr *dst, const struct dstr *src, - const size_t len); + const size_t len); static inline void dstr_resize(struct dstr *dst, const size_t num); static inline void dstr_reserve(struct dstr *dst, const size_t num); @@ -97,14 +96,12 @@ static inline void dstr_cat_ch(struct dstr *dst, char ch); EXPORT void dstr_ncat(struct dstr *dst, const char *array, const size_t len); EXPORT void dstr_ncat_dstr(struct dstr *dst, const struct dstr *str, - const size_t len); + const size_t len); -EXPORT void dstr_insert(struct dstr *dst, const size_t idx, - const char *array); +EXPORT void dstr_insert(struct dstr *dst, const size_t idx, const char *array); EXPORT void dstr_insert_dstr(struct dstr *dst, const size_t idx, - const struct dstr *str); -EXPORT void dstr_insert_ch(struct dstr *dst, const size_t idx, - const char ch); + const struct dstr *str); +EXPORT void dstr_insert_ch(struct dstr *dst, const size_t idx, const char ch); EXPORT void dstr_remove(struct dstr *dst, const size_t idx, const size_t count); @@ -117,32 +114,30 @@ EXPORT void dstr_vprintf(struct dstr *dst, const char *format, va_list args); EXPORT void dstr_vcatf(struct dstr *dst, const char *format, va_list args); EXPORT void dstr_safe_printf(struct dstr *dst, const char *format, - const char *val1, const char *val2, const char *val3, - const char *val4); + const char *val1, const char *val2, + const char *val3, const char *val4); -static inline const char *dstr_find_i(const struct dstr *str, - const char *find); -static inline const char *dstr_find(const struct dstr *str, - const char *find); +static inline const char *dstr_find_i(const struct dstr *str, const char *find); +static inline const char *dstr_find(const struct dstr *str, const char *find); EXPORT void dstr_replace(struct dstr *str, const char *find, - const char *replace); + const char *replace); static inline int dstr_cmp(const struct dstr *str1, const char *str2); static inline int dstr_cmpi(const struct dstr *str1, const char *str2); static inline int dstr_ncmp(const struct dstr *str1, const char *str2, - const size_t n); + const size_t n); static inline int dstr_ncmpi(const struct dstr *str1, const char *str2, - const size_t n); + const size_t n); EXPORT void dstr_depad(struct dstr *dst); EXPORT void dstr_left(struct dstr *dst, const struct dstr *str, - const size_t pos); + const size_t pos); EXPORT void dstr_mid(struct dstr *dst, const struct dstr *str, - const size_t start, const size_t count); + const size_t start, const size_t count); EXPORT void dstr_right(struct dstr *dst, const struct dstr *str, - const size_t pos); + const size_t pos); static inline char dstr_end(const struct dstr *str); @@ -160,15 +155,15 @@ EXPORT void dstr_to_lower(struct dstr *str); static inline void dstr_init(struct dstr *dst) { - dst->array = NULL; - dst->len = 0; + dst->array = NULL; + dst->len = 0; dst->capacity = 0; } static inline void dstr_init_move_array(struct dstr *dst, char *str) { - dst->array = str; - dst->len = (!str) ? 0 : strlen(str); + dst->array = str; + dst->len = (!str) ? 0 : strlen(str); dst->capacity = dst->len + 1; } @@ -193,8 +188,8 @@ static inline void dstr_init_copy_dstr(struct dstr *dst, const struct dstr *src) static inline void dstr_free(struct dstr *dst) { bfree(dst->array); - dst->array = NULL; - dst->len = 0; + dst->array = NULL; + dst->len = 0; dst->capacity = 0; } @@ -202,14 +197,14 @@ static inline void dstr_array_free(struct dstr *array, const size_t count) { size_t i; for (i = 0; i < count; i++) - dstr_free(array+i); + dstr_free(array + i); } static inline void dstr_move_array(struct dstr *dst, char *str) { dstr_free(dst); - dst->array = str; - dst->len = (!str) ? 0 : strlen(str); + dst->array = str; + dst->len = (!str) ? 0 : strlen(str); dst->capacity = dst->len + 1; } @@ -225,10 +220,10 @@ static inline void dstr_ensure_capacity(struct dstr *dst, const size_t new_size) if (new_size <= dst->capacity) return; - new_cap = (!dst->capacity) ? new_size : dst->capacity*2; + new_cap = (!dst->capacity) ? new_size : dst->capacity * 2; if (new_size > new_cap) new_cap = new_size; - dst->array = (char*)brealloc(dst->array, new_cap); + dst->array = (char *)brealloc(dst->array, new_cap); dst->capacity = new_cap; } @@ -249,7 +244,7 @@ static inline void dstr_reserve(struct dstr *dst, const size_t capacity) if (capacity == 0 || capacity <= dst->len) return; - dst->array = (char*)brealloc(dst->array, capacity); + dst->array = (char *)brealloc(dst->array, capacity); dst->capacity = capacity; } @@ -288,8 +283,8 @@ static inline void dstr_cat(struct dstr *dst, const char *array) static inline void dstr_cat_ch(struct dstr *dst, char ch) { dstr_ensure_capacity(dst, ++dst->len + 1); - dst->array[dst->len-1] = ch; - dst->array[dst->len] = 0; + dst->array[dst->len - 1] = ch; + dst->array[dst->len] = 0; } static inline const char *dstr_find_i(const struct dstr *str, const char *find) @@ -313,13 +308,13 @@ static inline int dstr_cmpi(const struct dstr *str1, const char *str2) } static inline int dstr_ncmp(const struct dstr *str1, const char *str2, - const size_t n) + const size_t n) { return astrcmp_n(str1->array, str2, n); } static inline int dstr_ncmpi(const struct dstr *str1, const char *str2, - const size_t n) + const size_t n) { return astrcmpi_n(str1->array, str2, n); } diff --git a/libobs/util/dstr.hpp b/libobs/util/dstr.hpp index 082764d..df27749 100644 --- a/libobs/util/dstr.hpp +++ b/libobs/util/dstr.hpp @@ -21,15 +21,12 @@ class DStr { dstr str; - DStr(DStr const&) = delete; - DStr &operator=(DStr const&) = delete; + DStr(DStr const &) = delete; + DStr &operator=(DStr const &) = delete; public: - inline DStr() {dstr_init(&str);} - inline DStr(DStr &&other) : DStr() - { - dstr_move(&str, &other.str); - } + inline DStr() { dstr_init(&str); } + inline DStr(DStr &&other) : DStr() { dstr_move(&str, &other.str); } inline DStr &operator=(DStr &&other) { @@ -37,13 +34,13 @@ public: return *this; } - inline ~DStr() {dstr_free(&str);} + inline ~DStr() { dstr_free(&str); } - inline operator dstr*() {return &str;} - inline operator const dstr*() const {return &str;} + inline operator dstr *() { return &str; } + inline operator const dstr *() const { return &str; } - inline operator char*() {return str.array;} - inline operator const char*() const {return str.array;} + inline operator char *() { return str.array; } + inline operator const char *() const { return str.array; } - inline dstr *operator->() {return &str;} + inline dstr *operator->() { return &str; } }; diff --git a/libobs/util/file-serializer.c b/libobs/util/file-serializer.c index 6d2a699..3468424 100644 --- a/libobs/util/file-serializer.c +++ b/libobs/util/file-serializer.c @@ -24,14 +24,20 @@ static size_t file_input_read(void *file, void *data, size_t size) } static int64_t file_input_seek(void *file, int64_t offset, - enum serialize_seek_type seek_type) + enum serialize_seek_type seek_type) { int origin = SEEK_SET; switch (seek_type) { - case SERIALIZE_SEEK_START: origin = SEEK_SET; break; - case SERIALIZE_SEEK_CURRENT: origin = SEEK_CUR; break; - case SERIALIZE_SEEK_END: origin = SEEK_END; break; + case SERIALIZE_SEEK_START: + origin = SEEK_SET; + break; + case SERIALIZE_SEEK_CURRENT: + origin = SEEK_CUR; + break; + case SERIALIZE_SEEK_END: + origin = SEEK_END; + break; } if (os_fseeki64(file, offset, origin) == -1) @@ -79,15 +85,21 @@ static size_t file_output_write(void *sdata, const void *data, size_t size) } static int64_t file_output_seek(void *sdata, int64_t offset, - enum serialize_seek_type seek_type) + enum serialize_seek_type seek_type) { struct file_output_data *out = sdata; int origin = SEEK_SET; switch (seek_type) { - case SERIALIZE_SEEK_START: origin = SEEK_SET; break; - case SERIALIZE_SEEK_CURRENT: origin = SEEK_CUR; break; - case SERIALIZE_SEEK_END: origin = SEEK_END; break; + case SERIALIZE_SEEK_START: + origin = SEEK_SET; + break; + case SERIALIZE_SEEK_CURRENT: + origin = SEEK_CUR; + break; + case SERIALIZE_SEEK_END: + origin = SEEK_END; + break; } if (os_fseeki64(out->file, offset, origin) == -1) @@ -121,8 +133,8 @@ bool file_output_serializer_init(struct serializer *s, const char *path) return true; } -bool file_output_serializer_init_safe(struct serializer *s, - const char *path, const char *temp_ext) +bool file_output_serializer_init_safe(struct serializer *s, const char *path, + const char *temp_ext) { struct dstr temp_name = {0}; struct file_output_data *out; diff --git a/libobs/util/file-serializer.h b/libobs/util/file-serializer.h index 886ad80..17dcbae 100644 --- a/libobs/util/file-serializer.h +++ b/libobs/util/file-serializer.h @@ -23,5 +23,6 @@ EXPORT void file_input_serializer_free(struct serializer *s); EXPORT bool file_output_serializer_init(struct serializer *s, const char *path); EXPORT bool file_output_serializer_init_safe(struct serializer *s, - const char *path, const char *temp_ext); + const char *path, + const char *temp_ext); EXPORT void file_output_serializer_free(struct serializer *s); diff --git a/libobs/util/lexer.c b/libobs/util/lexer.c index f49627e..e98af19 100644 --- a/libobs/util/lexer.c +++ b/libobs/util/lexer.c @@ -32,7 +32,7 @@ int strref_cmp(const struct strref *str1, const char *str2) char ch1, ch2; ch1 = (i < str1->len) ? str1->array[i] : 0; - ch2 = *str2; + ch2 = *str2; if (ch1 < ch2) return -1; @@ -56,7 +56,7 @@ int strref_cmpi(const struct strref *str1, const char *str2) char ch1, ch2; ch1 = (i < str1->len) ? (char)toupper(str1->array[i]) : 0; - ch2 = (char)toupper(*str2); + ch2 = (char)toupper(*str2); if (ch1 < ch2) return -1; @@ -80,7 +80,7 @@ int strref_cmp_strref(const struct strref *str1, const struct strref *str2) char ch1, ch2; ch1 = (i < str1->len) ? str1->array[i] : 0; - ch2 = (i < str2->len) ? str2->array[i] : 0; + ch2 = (i < str2->len) ? str2->array[i] : 0; if (ch1 < ch2) return -1; @@ -139,7 +139,7 @@ bool valid_int_str(const char *str, size_t n) return false; found_num = true; - } while(*++str && --n); + } while (*++str && --n); return found_num; } @@ -183,26 +183,26 @@ bool valid_float_str(const char *str, size_t n) } else { found_num = true; } - } while(*++str && --n); + } while (*++str && --n); return found_num; } /* ------------------------------------------------------------------------- */ -void error_data_add(struct error_data *data, const char *file, - uint32_t row, uint32_t column, const char *msg, int level) +void error_data_add(struct error_data *data, const char *file, uint32_t row, + uint32_t column, const char *msg, int level) { struct error_item item; if (!data) return; - item.file = file; - item.row = row; + item.file = file; + item.row = row; item.column = column; - item.level = level; - item.error = bstrdup(msg); + item.level = level; + item.error = bstrdup(msg); da_push_back(data->errors, &item); } @@ -215,9 +215,9 @@ char *error_data_buildstring(struct error_data *ed) dstr_init(&str); for (i = 0; i < ed->errors.num; i++) { - struct error_item *item = items+i; + struct error_item *item = items + i; dstr_catf(&str, "%s (%u, %u): %s\n", item->file, item->row, - item->column, item->error); + item->column, item->error); } return str.array; @@ -238,7 +238,7 @@ static inline enum base_token_type get_char_token_type(const char ch) } bool lexer_getbasetoken(struct lexer *lex, struct base_token *token, - enum ignore_whitespace iws) + enum ignore_whitespace iws) { const char *offset = lex->offset; const char *token_start = NULL; @@ -254,10 +254,10 @@ bool lexer_getbasetoken(struct lexer *lex, struct base_token *token, if (type == BASETOKEN_NONE) { if (new_type == BASETOKEN_WHITESPACE && - ignore_whitespace) + ignore_whitespace) continue; - token_start = offset-1; + token_start = offset - 1; type = new_type; if (type != BASETOKEN_DIGIT && @@ -277,7 +277,7 @@ bool lexer_getbasetoken(struct lexer *lex, struct base_token *token, lex->offset = offset; if (token_start && offset > token_start) { - strref_set(&token->text, token_start, offset-token_start); + strref_set(&token->text, token_start, offset - token_start); token->type = type; return true; } @@ -285,8 +285,8 @@ bool lexer_getbasetoken(struct lexer *lex, struct base_token *token, return false; } -void lexer_getstroffset(const struct lexer *lex, const char *str, - uint32_t *row, uint32_t *col) +void lexer_getstroffset(const struct lexer *lex, const char *str, uint32_t *row, + uint32_t *col) { uint32_t cur_col = 1, cur_row = 1; const char *text = lex->text; @@ -296,7 +296,7 @@ void lexer_getstroffset(const struct lexer *lex, const char *str, while (text < str) { if (is_newline(*text)) { - text += newline_size(text)-1; + text += newline_size(text) - 1; cur_col = 1; cur_row++; } else { diff --git a/libobs/util/lexer.h b/libobs/util/lexer.h index bd60bef..986b1b2 100644 --- a/libobs/util/lexer.h +++ b/libobs/util/lexer.h @@ -35,19 +35,19 @@ struct strref { static inline void strref_clear(struct strref *dst) { dst->array = NULL; - dst->len = 0; + dst->len = 0; } static inline void strref_set(struct strref *dst, const char *array, size_t len) { dst->array = array; - dst->len = len; + dst->len = len; } static inline void strref_copy(struct strref *dst, const struct strref *src) { dst->array = src->array; - dst->len = src->len; + dst->len = src->len; } static inline void strref_add(struct strref *dst, const struct strref *t) @@ -66,9 +66,9 @@ static inline bool strref_is_empty(const struct strref *str) EXPORT int strref_cmp(const struct strref *str1, const char *str2); EXPORT int strref_cmpi(const struct strref *str1, const char *str2); EXPORT int strref_cmp_strref(const struct strref *str1, - const struct strref *str2); + const struct strref *str2); EXPORT int strref_cmpi_strref(const struct strref *str1, - const struct strref *str2); + const struct strref *str2); /* ------------------------------------------------------------------------- */ @@ -102,8 +102,7 @@ static inline bool is_space_or_tab(const char ch) static inline bool is_newline_pair(char ch1, char ch2) { - return (ch1 == '\r' && ch2 == '\n') || - (ch1 == '\n' && ch2 == '\r'); + return (ch1 == '\r' && ch2 == '\n') || (ch1 == '\n' && ch2 == '\r'); } static inline int newline_size(const char *array) @@ -146,14 +145,14 @@ static inline void base_token_clear(struct base_token *t) } static inline void base_token_copy(struct base_token *dst, - struct base_token *src) + struct base_token *src) { memcpy(dst, src, sizeof(struct base_token)); } /* ------------------------------------------------------------------------- */ -#define LEX_ERROR 0 +#define LEX_ERROR 0 #define LEX_WARNING 1 struct error_item { @@ -178,7 +177,7 @@ static inline void error_item_array_free(struct error_item *array, size_t num) { size_t i; for (i = 0; i < num; i++) - error_item_free(array+i); + error_item_free(array + i); } /* ------------------------------------------------------------------------- */ @@ -199,18 +198,18 @@ static inline void error_data_free(struct error_data *data) } static inline const struct error_item *error_data_item(struct error_data *ed, - size_t idx) + size_t idx) { - return ed->errors.array+idx; + return ed->errors.array + idx; } EXPORT char *error_data_buildstring(struct error_data *ed); EXPORT void error_data_add(struct error_data *ed, const char *file, - uint32_t row, uint32_t column, const char *msg, int level); + uint32_t row, uint32_t column, const char *msg, + int level); -static inline size_t error_data_type_count(struct error_data *ed, - int type) +static inline size_t error_data_type_count(struct error_data *ed, int type) { size_t count = 0, i; for (i = 0; i < ed->errors.num; i++) { @@ -252,14 +251,14 @@ static inline void lexer_free(struct lexer *lex) static inline void lexer_start(struct lexer *lex, const char *text) { lexer_free(lex); - lex->text = bstrdup(text); + lex->text = bstrdup(text); lex->offset = lex->text; } static inline void lexer_start_move(struct lexer *lex, char *text) { lexer_free(lex); - lex->text = text; + lex->text = text; lex->offset = lex->text; } @@ -268,16 +267,13 @@ static inline void lexer_reset(struct lexer *lex) lex->offset = lex->text; } -enum ignore_whitespace { - PARSE_WHITESPACE, - IGNORE_WHITESPACE -}; +enum ignore_whitespace { PARSE_WHITESPACE, IGNORE_WHITESPACE }; EXPORT bool lexer_getbasetoken(struct lexer *lex, struct base_token *t, - enum ignore_whitespace iws); + enum ignore_whitespace iws); EXPORT void lexer_getstroffset(const struct lexer *lex, const char *str, - uint32_t *row, uint32_t *col); + uint32_t *row, uint32_t *col); #ifdef __cplusplus } diff --git a/libobs/util/pipe-posix.c b/libobs/util/pipe-posix.c index 3d77686..7eb0d83 100644 --- a/libobs/util/pipe-posix.c +++ b/libobs/util/pipe-posix.c @@ -26,7 +26,7 @@ struct os_process_pipe { }; os_process_pipe_t *os_process_pipe_create(const char *cmd_line, - const char *type) + const char *type) { struct os_process_pipe pipe = {0}; struct os_process_pipe *out; @@ -38,7 +38,7 @@ os_process_pipe_t *os_process_pipe_create(const char *cmd_line, pipe.file = popen(cmd_line, type); pipe.read_pipe = *type == 'r'; - if (pipe.file == (FILE*)-1 || pipe.file == NULL) { + if (pipe.file == (FILE *)-1 || pipe.file == NULL) { return NULL; } @@ -73,7 +73,8 @@ size_t os_process_pipe_read(os_process_pipe_t *pp, uint8_t *data, size_t len) return fread(data, 1, len, pp->file); } -size_t os_process_pipe_read_err(os_process_pipe_t *pp, uint8_t *data, size_t len) +size_t os_process_pipe_read_err(os_process_pipe_t *pp, uint8_t *data, + size_t len) { /* XXX: unsupported on posix */ UNUSED_PARAMETER(pp); @@ -83,7 +84,7 @@ size_t os_process_pipe_read_err(os_process_pipe_t *pp, uint8_t *data, size_t len } size_t os_process_pipe_write(os_process_pipe_t *pp, const uint8_t *data, - size_t len) + size_t len) { if (!pp) { return 0; diff --git a/libobs/util/pipe-windows.c b/libobs/util/pipe-windows.c index 5510072..ad82479 100644 --- a/libobs/util/pipe-windows.c +++ b/libobs/util/pipe-windows.c @@ -43,7 +43,8 @@ static bool create_pipe(HANDLE *input, HANDLE *output) } static inline bool create_process(const char *cmd_line, HANDLE stdin_handle, - HANDLE stdout_handle, HANDLE stderr_handle, HANDLE *process) + HANDLE stdout_handle, HANDLE stderr_handle, + HANDLE *process) { PROCESS_INFORMATION pi = {0}; wchar_t *cmd_line_w = NULL; @@ -59,7 +60,8 @@ static inline bool create_process(const char *cmd_line, HANDLE stdin_handle, os_utf8_to_wcs_ptr(cmd_line, 0, &cmd_line_w); if (cmd_line_w) { success = !!CreateProcessW(NULL, cmd_line_w, NULL, NULL, true, - CREATE_NO_WINDOW, NULL, NULL, &si, &pi); + CREATE_NO_WINDOW, NULL, NULL, &si, + &pi); if (success) { *process = pi.hProcess; @@ -73,7 +75,7 @@ static inline bool create_process(const char *cmd_line, HANDLE stdin_handle, } os_process_pipe_t *os_process_pipe_create(const char *cmd_line, - const char *type) + const char *type) { os_process_pipe_t *pp = NULL; bool read_pipe; @@ -100,7 +102,7 @@ os_process_pipe_t *os_process_pipe_create(const char *cmd_line, read_pipe = *type == 'r'; success = !!SetHandleInformation(read_pipe ? input : output, - HANDLE_FLAG_INHERIT, false); + HANDLE_FLAG_INHERIT, false); if (!success) { goto error; } @@ -111,7 +113,8 @@ os_process_pipe_t *os_process_pipe_create(const char *cmd_line, } success = create_process(cmd_line, read_pipe ? NULL : input, - read_pipe ? output : NULL, err_output, &process); + read_pipe ? output : NULL, err_output, + &process); if (!success) { goto error; } @@ -174,7 +177,8 @@ size_t os_process_pipe_read(os_process_pipe_t *pp, uint8_t *data, size_t len) return 0; } -size_t os_process_pipe_read_err(os_process_pipe_t *pp, uint8_t *data, size_t len) +size_t os_process_pipe_read_err(os_process_pipe_t *pp, uint8_t *data, + size_t len) { DWORD bytes_read; bool success; @@ -183,18 +187,18 @@ size_t os_process_pipe_read_err(os_process_pipe_t *pp, uint8_t *data, size_t len return 0; } - success = !!ReadFile(pp->handle_err, data, (DWORD)len, &bytes_read, NULL); + success = + !!ReadFile(pp->handle_err, data, (DWORD)len, &bytes_read, NULL); if (success && bytes_read) { return bytes_read; - } - else + } else bytes_read = GetLastError(); return 0; } size_t os_process_pipe_write(os_process_pipe_t *pp, const uint8_t *data, - size_t len) + size_t len) { DWORD bytes_written; bool success; @@ -206,8 +210,8 @@ size_t os_process_pipe_write(os_process_pipe_t *pp, const uint8_t *data, return 0; } - success = !!WriteFile(pp->handle, data, (DWORD)len, &bytes_written, - NULL); + success = + !!WriteFile(pp->handle, data, (DWORD)len, &bytes_written, NULL); if (success && bytes_written) { return bytes_written; } diff --git a/libobs/util/pipe.h b/libobs/util/pipe.h index 5c44514..fed666c 100644 --- a/libobs/util/pipe.h +++ b/libobs/util/pipe.h @@ -22,12 +22,12 @@ struct os_process_pipe; typedef struct os_process_pipe os_process_pipe_t; EXPORT os_process_pipe_t *os_process_pipe_create(const char *cmd_line, - const char *type); + const char *type); EXPORT int os_process_pipe_destroy(os_process_pipe_t *pp); EXPORT size_t os_process_pipe_read(os_process_pipe_t *pp, uint8_t *data, - size_t len); + size_t len); EXPORT size_t os_process_pipe_read_err(os_process_pipe_t *pp, uint8_t *data, - size_t len); + size_t len); EXPORT size_t os_process_pipe_write(os_process_pipe_t *pp, const uint8_t *data, - size_t len); + size_t len); diff --git a/libobs/util/platform-cocoa.m b/libobs/util/platform-cocoa.m index ff434d6..24ae448 100644 --- a/libobs/util/platform-cocoa.m +++ b/libobs/util/platform-cocoa.m @@ -54,7 +54,8 @@ static double ns_time_compute_factor() static uint64_t ns_time_full() { static double factor = 0.; - if (factor == 0.) factor = ns_time_compute_factor(); + if (factor == 0.) + factor = ns_time_compute_factor(); return (uint64_t)(mach_absolute_time() * factor); } @@ -72,18 +73,19 @@ static time_func ns_time_select_func() uint64_t os_gettime_ns(void) { static time_func f = NULL; - if (!f) f = ns_time_select_func(); + if (!f) + f = ns_time_select_func(); return f(); } /* gets the location [domain mask]/Library/Application Support/[name] */ static int os_get_path_internal(char *dst, size_t size, const char *name, - NSSearchPathDomainMask domainMask) + NSSearchPathDomainMask domainMask) { NSArray *paths = NSSearchPathForDirectoriesInDomains( - NSApplicationSupportDirectory, domainMask, YES); + NSApplicationSupportDirectory, domainMask, YES); - if([paths count] == 0) + if ([paths count] == 0) bcrash("Could not get home directory (platform-cocoa)"); NSString *application_support = paths[0]; @@ -96,12 +98,12 @@ static int os_get_path_internal(char *dst, size_t size, const char *name, } static char *os_get_path_ptr_internal(const char *name, - NSSearchPathDomainMask domainMask) + NSSearchPathDomainMask domainMask) { NSArray *paths = NSSearchPathForDirectoriesInDomains( - NSApplicationSupportDirectory, domainMask, YES); + NSApplicationSupportDirectory, domainMask, YES); - if([paths count] == 0) + if ([paths count] == 0) bcrash("Could not get home directory (platform-cocoa)"); NSString *application_support = paths[0]; @@ -109,7 +111,7 @@ static char *os_get_path_ptr_internal(const char *name, NSUInteger len = [application_support lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - char *path_ptr = bmalloc(len+1); + char *path_ptr = bmalloc(len + 1); path_ptr[len] = 0; @@ -174,47 +176,47 @@ char *os_get_executable_path_ptr(const char *name) struct os_cpu_usage_info { int64_t last_cpu_time; int64_t last_sys_time; - int core_count; + int core_count; }; static inline void add_time_value(time_value_t *dst, time_value_t *a, - time_value_t *b) + time_value_t *b) { dst->microseconds = a->microseconds + b->microseconds; - dst->seconds = a->seconds + b->seconds; + dst->seconds = a->seconds + b->seconds; if (dst->microseconds >= 1000000) { - dst->seconds += dst->microseconds / 1000000; + dst->seconds += dst->microseconds / 1000000; dst->microseconds %= 1000000; } } static bool get_time_info(int64_t *cpu_time, int64_t *sys_time) { - mach_port_t task = mach_task_self(); + mach_port_t task = mach_task_self(); struct task_thread_times_info thread_data; - struct task_basic_info_64 task_data; - mach_msg_type_number_t count; - kern_return_t kern_ret; - time_value_t cur_time; + struct task_basic_info_64 task_data; + mach_msg_type_number_t count; + kern_return_t kern_ret; + time_value_t cur_time; *cpu_time = 0; *sys_time = 0; count = TASK_THREAD_TIMES_INFO_COUNT; kern_ret = task_info(task, TASK_THREAD_TIMES_INFO, - (task_info_t)&thread_data, &count); + (task_info_t)&thread_data, &count); if (kern_ret != KERN_SUCCESS) return false; count = TASK_BASIC_INFO_64_COUNT; - kern_ret = task_info(task, TASK_BASIC_INFO_64, - (task_info_t)&task_data, &count); + kern_ret = task_info(task, TASK_BASIC_INFO_64, (task_info_t)&task_data, + &count); if (kern_ret != KERN_SUCCESS) return false; add_time_value(&cur_time, &thread_data.user_time, - &thread_data.system_time); + &thread_data.system_time); add_time_value(&cur_time, &cur_time, &task_data.user_time); add_time_value(&cur_time, &cur_time, &task_data.system_time); @@ -238,7 +240,7 @@ os_cpu_usage_info_t *os_cpu_usage_info_start(void) double os_cpu_usage_info_query(os_cpu_usage_info_t *info) { - int64_t sys_time, cpu_time; + int64_t sys_time, cpu_time; int64_t sys_time_delta, cpu_time_delta; if (!info || !get_time_info(&cpu_time, &sys_time)) @@ -254,7 +256,7 @@ double os_cpu_usage_info_query(os_cpu_usage_info_t *info) info->last_cpu_time = cpu_time; return (double)sys_time_delta * 100.0 / (double)cpu_time_delta / - (double)info->core_count; + (double)info->core_count; } void os_cpu_usage_info_destroy(os_cpu_usage_info_t *info) @@ -272,7 +274,7 @@ os_performance_token_t *os_request_high_performance(const char *reason) return nil; //taken from http://stackoverflow.com/a/20100906 - id activity = [pi beginActivityWithOptions:0x00FFFFFF + id activity = [pi beginActivityWithOptions:0x00FFFFFF reason:@(reason)]; return CFBridgingRetain(activity); @@ -302,11 +304,11 @@ os_inhibit_t *os_inhibit_sleep_create(const char *reason) { struct os_inhibit_info *info = bzalloc(sizeof(*info)); if (!reason) - info->reason = CFStringCreateWithCString(kCFAllocatorDefault, - reason, kCFStringEncodingUTF8); + info->reason = CFStringCreateWithCString( + kCFAllocatorDefault, reason, kCFStringEncodingUTF8); else - info->reason = CFStringCreateCopy(kCFAllocatorDefault, - CFSTR("")); + info->reason = + CFStringCreateCopy(kCFAllocatorDefault, CFSTR("")); return info; } @@ -321,12 +323,11 @@ bool os_inhibit_sleep_set_active(os_inhibit_t *info, bool active) return false; if (active) { - IOPMAssertionDeclareUserActivity(info->reason, - kIOPMUserActiveLocal, &info->user_id); + IOPMAssertionDeclareUserActivity( + info->reason, kIOPMUserActiveLocal, &info->user_id); success = IOPMAssertionCreateWithName( - kIOPMAssertionTypeNoDisplaySleep, - kIOPMAssertionLevelOn, info->reason, - &info->sleep_id); + kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, + info->reason, &info->sleep_id); if (success != kIOReturnSuccess) { blog(LOG_WARNING, "Failed to disable sleep"); @@ -361,16 +362,16 @@ static void os_get_cores_internal(void) core_count_initialized = true; size_t size; - int ret; + int ret; size = sizeof(physical_cores); - ret = sysctlbyname("machdep.cpu.core_count", &physical_cores, - &size, NULL, 0); + ret = sysctlbyname("machdep.cpu.core_count", &physical_cores, &size, + NULL, 0); if (ret != 0) return; - ret = sysctlbyname("machdep.cpu.thread_count", &logical_cores, - &size, NULL, 0); + ret = sysctlbyname("machdep.cpu.thread_count", &logical_cores, &size, + NULL, 0); } int os_get_physical_cores(void) @@ -390,8 +391,8 @@ int os_get_logical_cores(void) static inline bool os_get_sys_memory_usage_internal(vm_statistics_t vmstat) { mach_msg_type_number_t out_count = HOST_VM_INFO_COUNT; - if (host_statistics(mach_host_self(), HOST_VM_INFO, - (host_info_t)vmstat, &out_count) != KERN_SUCCESS) + if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)vmstat, + &out_count) != KERN_SUCCESS) return false; return true; } @@ -409,8 +410,8 @@ uint64_t os_get_sys_free_size(void) typedef task_basic_info_data_t mach_task_basic_info_data_t; #endif -static inline bool os_get_proc_memory_usage_internal( - mach_task_basic_info_data_t *taskinfo) +static inline bool +os_get_proc_memory_usage_internal(mach_task_basic_info_data_t *taskinfo) { #ifdef MACH_TASK_BASIC_INFO const task_flavor_t flavor = MACH_TASK_BASIC_INFO; @@ -419,8 +420,8 @@ static inline bool os_get_proc_memory_usage_internal( const task_flavor_t flavor = TASK_BASIC_INFO; mach_msg_type_number_t out_count = TASK_BASIC_INFO_COUNT; #endif - if (task_info(mach_task_self(), flavor, - (task_info_t)taskinfo, &out_count) != KERN_SUCCESS) + if (task_info(mach_task_self(), flavor, (task_info_t)taskinfo, + &out_count) != KERN_SUCCESS) return false; return true; } @@ -432,7 +433,7 @@ bool os_get_proc_memory_usage(os_proc_memory_usage_t *usage) return false; usage->resident_size = taskinfo.resident_size; - usage->virtual_size = taskinfo.virtual_size; + usage->virtual_size = taskinfo.virtual_size; return true; } @@ -461,8 +462,8 @@ char *cfstr_copy_cstr(CFStringRef cfstring, CFStringEncoding cfstring_encoding) return NULL; // Try the quick way to obtain the buffer - const char *tmp_buffer = CFStringGetCStringPtr(cfstring, - cfstring_encoding); + const char *tmp_buffer = + CFStringGetCStringPtr(cfstring, cfstring_encoding); if (tmp_buffer != NULL) return bstrdup(tmp_buffer); @@ -486,8 +487,8 @@ char *cfstr_copy_cstr(CFStringRef cfstring, CFStringEncoding cfstring_encoding) } // Copy CFString in requested encoding to buffer - Boolean success = - CFStringGetCString(cfstring, buffer, max_size, cfstring_encoding); + Boolean success = CFStringGetCString(cfstring, buffer, max_size, + cfstring_encoding); if (!success) { bfree(buffer); @@ -500,15 +501,15 @@ char *cfstr_copy_cstr(CFStringRef cfstring, CFStringEncoding cfstring_encoding) * Returns true on success or false on failure. * In case of failure, the dstr capacity but not size is changed. */ -bool cfstr_copy_dstr(CFStringRef cfstring, - CFStringEncoding cfstring_encoding, struct dstr *str) +bool cfstr_copy_dstr(CFStringRef cfstring, CFStringEncoding cfstring_encoding, + struct dstr *str) { if (!cfstring) return false; // Try the quick way to obtain the buffer - const char *tmp_buffer = CFStringGetCStringPtr(cfstring, - cfstring_encoding); + const char *tmp_buffer = + CFStringGetCStringPtr(cfstring, cfstring_encoding); if (tmp_buffer != NULL) { dstr_copy(str, tmp_buffer); @@ -530,8 +531,8 @@ bool cfstr_copy_dstr(CFStringRef cfstring, dstr_ensure_capacity(str, max_size); // Copy CFString in requested encoding to dstr buffer - Boolean success = CFStringGetCString( - cfstring, str->array, max_size, cfstring_encoding); + Boolean success = CFStringGetCString(cfstring, str->array, max_size, + cfstring_encoding); if (success) dstr_resize(str, max_size); diff --git a/libobs/util/platform-nix-dbus.c b/libobs/util/platform-nix-dbus.c index 6bcebd5..94610e6 100644 --- a/libobs/util/platform-nix-dbus.c +++ b/libobs/util/platform-nix-dbus.c @@ -35,26 +35,30 @@ struct service_info { }; static const struct service_info services[] = { - [FREEDESKTOP_SS] = { - .name = "org.freedesktop.ScreenSaver", - .path = "/ScreenSaver", - .uninhibit = "UnInhibit", - }, - [FREEDESKTOP_PM] = { - .name = "org.freedesktop.PowerManagement.Inhibit", - .path = "/org/freedesktop/PowerManagement", - .uninhibit = "UnInhibit", - }, - [MATE_SM] = { - .name = "org.mate.SessionManager", - .path = "/org/mate/SessionManager", - .uninhibit = "Uninhibit", - }, - [GNOME_SM] = { - .name = "org.gnome.SessionManager", - .path = "/org/gnome/SessionManager", - .uninhibit = "Uninhibit", - }, + [FREEDESKTOP_SS] = + { + .name = "org.freedesktop.ScreenSaver", + .path = "/ScreenSaver", + .uninhibit = "UnInhibit", + }, + [FREEDESKTOP_PM] = + { + .name = "org.freedesktop.PowerManagement.Inhibit", + .path = "/org/freedesktop/PowerManagement", + .uninhibit = "UnInhibit", + }, + [MATE_SM] = + { + .name = "org.mate.SessionManager", + .path = "/org/mate/SessionManager", + .uninhibit = "Uninhibit", + }, + [GNOME_SM] = + { + .name = "org.gnome.SessionManager", + .path = "/org/gnome/SessionManager", + .uninhibit = "Uninhibit", + }, }; static const size_t num_services = @@ -92,7 +96,7 @@ struct dbus_sleep_info *dbus_sleep_info_create(void) info->c = dbus_bus_get_private(DBUS_BUS_SESSION, &err); if (!info->c) { blog(LOG_ERROR, "Could not create dbus connection: %s", - err.message); + err.message); bfree(info); return NULL; } @@ -105,7 +109,7 @@ struct dbus_sleep_info *dbus_sleep_info_create(void) if (dbus_bus_name_has_owner(info->c, service->name, NULL)) { blog(LOG_DEBUG, "Found dbus service: %s", - service->name); + service->name); info->service = service; info->type = (enum service_type)i; return info; @@ -117,7 +121,7 @@ struct dbus_sleep_info *dbus_sleep_info_create(void) } void dbus_inhibit_sleep(struct dbus_sleep_info *info, const char *reason, - bool active) + bool active) { DBusMessage *reply; const char *method; @@ -132,8 +136,9 @@ void dbus_inhibit_sleep(struct dbus_sleep_info *info, const char *reason, if (reply) { success = dbus_message_get_args(reply, NULL, - DBUS_TYPE_UINT32, &info->id, - DBUS_TYPE_INVALID); + DBUS_TYPE_UINT32, + &info->id, + DBUS_TYPE_INVALID); if (!success) info->id = 0; dbus_message_unref(reply); @@ -146,7 +151,8 @@ void dbus_inhibit_sleep(struct dbus_sleep_info *info, const char *reason, method = active ? "Inhibit" : info->service->uninhibit; reply = dbus_message_new_method_call(info->service->name, - info->service->path, info->service->name, method); + info->service->path, + info->service->name, method); if (reply == NULL) { blog(LOG_ERROR, "dbus_message_new_method_call failed"); return; @@ -162,31 +168,28 @@ void dbus_inhibit_sleep(struct dbus_sleep_info *info, const char *reason, switch (info->type) { case MATE_SM: case GNOME_SM: - success = dbus_message_append_args(reply, - DBUS_TYPE_STRING, &program, - DBUS_TYPE_UINT32, &xid, - DBUS_TYPE_STRING, &reason, - DBUS_TYPE_UINT32, &flags, - DBUS_TYPE_INVALID); + success = dbus_message_append_args( + reply, DBUS_TYPE_STRING, &program, + DBUS_TYPE_UINT32, &xid, DBUS_TYPE_STRING, + &reason, DBUS_TYPE_UINT32, &flags, + DBUS_TYPE_INVALID); break; default: - success = dbus_message_append_args(reply, - DBUS_TYPE_STRING, &program, - DBUS_TYPE_STRING, &reason, - DBUS_TYPE_INVALID); + success = dbus_message_append_args( + reply, DBUS_TYPE_STRING, &program, + DBUS_TYPE_STRING, &reason, DBUS_TYPE_INVALID); } if (success) { - success = dbus_connection_send_with_reply(info->c, - reply, &info->pending, -1); + success = dbus_connection_send_with_reply( + info->c, reply, &info->pending, -1); if (!success) info->pending = NULL; } } else { assert(info->id != 0); - success = dbus_message_append_args(reply, - DBUS_TYPE_UINT32, &info->id, - DBUS_TYPE_INVALID); + success = dbus_message_append_args( + reply, DBUS_TYPE_UINT32, &info->id, DBUS_TYPE_INVALID); if (success) success = dbus_connection_send(info->c, reply, NULL); if (!success) diff --git a/libobs/util/platform-nix.c b/libobs/util/platform-nix.c index 2fcdd43..e6cf102 100644 --- a/libobs/util/platform-nix.c +++ b/libobs/util/platform-nix.c @@ -73,8 +73,8 @@ void *os_dlopen(const char *path) void *res = dlopen(dylib_name.array, RTLD_LAZY); #endif if (!res) - blog(LOG_ERROR, "os_dlopen(%s->%s): %s\n", - path, dylib_name.array, dlerror()); + blog(LOG_ERROR, "os_dlopen(%s->%s): %s\n", path, + dylib_name.array, dlerror()); dstr_free(&dylib_name); return res; @@ -101,20 +101,20 @@ struct os_cpu_usage_info { os_cpu_usage_info_t *os_cpu_usage_info_start(void) { struct os_cpu_usage_info *info = bmalloc(sizeof(*info)); - struct tms time_sample; + struct tms time_sample; - info->last_cpu_time = times(&time_sample); - info->last_sys_time = time_sample.tms_stime; + info->last_cpu_time = times(&time_sample); + info->last_sys_time = time_sample.tms_stime; info->last_user_time = time_sample.tms_utime; - info->core_count = sysconf(_SC_NPROCESSORS_ONLN); + info->core_count = sysconf(_SC_NPROCESSORS_ONLN); return info; } double os_cpu_usage_info_query(os_cpu_usage_info_t *info) { struct tms time_sample; - clock_t cur_cpu_time; - double percent; + clock_t cur_cpu_time; + double percent; if (!info) return 0.0; @@ -126,12 +126,12 @@ double os_cpu_usage_info_query(os_cpu_usage_info_t *info) return 0.0; percent = (double)(time_sample.tms_stime - info->last_sys_time + - (time_sample.tms_utime - info->last_user_time)); + (time_sample.tms_utime - info->last_user_time)); percent /= (double)(cur_cpu_time - info->last_cpu_time); percent /= (double)info->core_count; - info->last_cpu_time = cur_cpu_time; - info->last_sys_time = time_sample.tms_stime; + info->last_cpu_time = cur_cpu_time; + info->last_sys_time = time_sample.tms_stime; info->last_user_time = time_sample.tms_utime; return percent * 100.0; @@ -156,8 +156,8 @@ bool os_sleepto_ns(uint64_t time_target) struct timespec req, remain; memset(&req, 0, sizeof(req)); memset(&remain, 0, sizeof(remain)); - req.tv_sec = time_target/1000000000; - req.tv_nsec = time_target%1000000000; + req.tv_sec = time_target / 1000000000; + req.tv_nsec = time_target % 1000000000; while (nanosleep(&req, &remain)) { req = remain; @@ -169,7 +169,7 @@ bool os_sleepto_ns(uint64_t time_target) void os_sleep_ms(uint32_t duration) { - usleep(duration*1000); + usleep(duration * 1000); } #if !defined(__APPLE__) @@ -178,7 +178,7 @@ uint64_t os_gettime_ns(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - return ((uint64_t) ts.tv_sec * 1000000000ULL + (uint64_t) ts.tv_nsec); + return ((uint64_t)ts.tv_sec * 1000000000ULL + (uint64_t)ts.tv_nsec); } /* should return $HOME/.[name], or when using XDG, @@ -263,7 +263,8 @@ int os_get_program_data_path(char *dst, size_t size, const char *name) char *os_get_program_data_path_ptr(const char *name) { - size_t len = snprintf(NULL, 0, "/usr/local/share/%s", !!name ? name : ""); + size_t len = + snprintf(NULL, 0, "/usr/local/share/%s", !!name ? name : ""); char *str = bmalloc(len + 1); snprintf(str, len + 1, "/usr/local/share/%s", !!name ? name : ""); str[len] = 0; @@ -332,23 +333,23 @@ char *os_get_abs_path_ptr(const char *path) } struct os_dir { - const char *path; - DIR *dir; - struct dirent *cur_dirent; + const char *path; + DIR *dir; + struct dirent *cur_dirent; struct os_dirent out; }; os_dir_t *os_opendir(const char *path) { struct os_dir *dir; - DIR *dir_val; + DIR *dir_val; dir_val = opendir(path); if (!dir_val) return NULL; dir = bzalloc(sizeof(struct os_dir)); - dir->dir = dir_val; + dir->dir = dir_val; dir->path = path; return dir; } @@ -367,7 +368,8 @@ struct os_dirent *os_readdir(os_dir_t *dir) { struct dstr file_path = {0}; - if (!dir) return NULL; + if (!dir) + return NULL; dir->cur_dirent = readdir(dir->dir); if (!dir->cur_dirent) @@ -442,7 +444,7 @@ int os_glob(const char *pattern, int flags, os_glob_t **pglob) void os_globfree(os_glob_t *pglob) { if (pglob) { - struct posix_glob_info *pgi = (struct posix_glob_info*)pglob; + struct posix_glob_info *pgi = (struct posix_glob_info *)pglob; globfree(&pgi->gl); bfree(pgi->base.gl_pathv); @@ -544,7 +546,7 @@ struct dbus_sleep_info; extern struct dbus_sleep_info *dbus_sleep_info_create(void); extern void dbus_inhibit_sleep(struct dbus_sleep_info *dbus, const char *sleep, - bool active); + bool active); extern void dbus_sleep_info_destroy(struct dbus_sleep_info *dbus); #endif @@ -575,8 +577,8 @@ os_inhibit_t *os_inhibit_sleep_create(const char *reason) posix_spawnattr_setsigmask(&info->attr, &set); sigaddset(&set, SIGPIPE); posix_spawnattr_setsigdefault(&info->attr, &set); - posix_spawnattr_setflags(&info->attr, - POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK); + posix_spawnattr_setflags(&info->attr, POSIX_SPAWN_SETSIGDEF | + POSIX_SPAWN_SETSIGMASK); info->reason = bstrdup(reason); return info; @@ -586,14 +588,15 @@ extern char **environ; static void reset_screensaver(os_inhibit_t *info) { - char *argv[3] = {(char*)"xdg-screensaver", (char*)"reset", NULL}; + char *argv[3] = {(char *)"xdg-screensaver", (char *)"reset", NULL}; pid_t pid; - int err = posix_spawnp(&pid, "xdg-screensaver", NULL, &info->attr, - argv, environ); + int err = posix_spawnp(&pid, "xdg-screensaver", NULL, &info->attr, argv, + environ); if (err == 0) { int status; - while (waitpid(pid, &status, 0) == -1); + while (waitpid(pid, &status, 0) == -1) + ; } else { blog(LOG_WARNING, "Failed to create xdg-screensaver: %d", err); } @@ -628,10 +631,10 @@ bool os_inhibit_sleep_set_active(os_inhibit_t *info, bool active) if (active) { ret = pthread_create(&info->screensaver_thread, NULL, - &screensaver_thread, info); + &screensaver_thread, info); if (ret < 0) { blog(LOG_ERROR, "Failed to create screensaver " - "inhibitor thread"); + "inhibitor thread"); return false; } } else { @@ -714,8 +717,8 @@ static void os_get_cores_internal(void) continue; if (dstr_is_empty(&proc_phys_ids) || - (!dstr_is_empty(&proc_phys_ids) && - !dstr_find(&proc_phys_ids, proc_phys_id.array))) { + (!dstr_is_empty(&proc_phys_ids) && + !dstr_find(&proc_phys_ids, proc_phys_id.array))) { dstr_cat_dstr(&proc_phys_ids, &proc_phys_id); dstr_cat(&proc_phys_ids, " "); core_count += atoi(start); @@ -774,7 +777,7 @@ static void os_get_cores_internal(void) len = strcspn(core_count, " "); dstr_ncopy(&proc_cores, core_count, len); - FreeBSD_cores_cleanup: +FreeBSD_cores_cleanup: if (!dstr_is_empty(&proc_packages)) packages = atoi(proc_packages.array); if (!dstr_is_empty(&proc_cores)) @@ -814,8 +817,8 @@ uint64_t os_get_sys_free_size(void) { uint64_t mem_free = 0; size_t length = sizeof(mem_free); - if (sysctlbyname("vm.stats.vm.v_free_count", &mem_free, &length, - NULL, 0) < 0) + if (sysctlbyname("vm.stats.vm.v_free_count", &mem_free, &length, NULL, + 0) < 0) return 0; return mem_free; } @@ -824,8 +827,8 @@ static inline bool os_get_proc_memory_usage_internal(struct kinfo_proc *kinfo) { int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; size_t length = sizeof(*kinfo); - if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), kinfo, &length, - NULL, 0) < 0) + if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), kinfo, &length, NULL, 0) < + 0) return false; return true; } @@ -837,8 +840,8 @@ bool os_get_proc_memory_usage(os_proc_memory_usage_t *usage) return false; usage->resident_size = - (uint64_t)kinfo.ki_rssize * sysconf(_SC_PAGESIZE); - usage->virtual_size = (uint64_t)kinfo.ki_size; + (uint64_t)kinfo.ki_rssize * sysconf(_SC_PAGESIZE); + usage->virtual_size = (uint64_t)kinfo.ki_size; return true; } @@ -858,10 +861,12 @@ uint64_t os_get_proc_virtual_size(void) return (uint64_t)kinfo.ki_size; } #else -uint64_t os_get_sys_free_size(void) {return 0;} - -typedef struct +uint64_t os_get_sys_free_size(void) { + return 0; +} + +typedef struct { unsigned long virtual_size; unsigned long resident_size; unsigned long share_pages; @@ -879,14 +884,9 @@ static inline bool os_get_proc_memory_usage_internal(statm_t *statm) if (!f) return false; - if (fscanf(f, "%lu %lu %lu %lu %lu %lu %lu", - &statm->virtual_size, - &statm->resident_size, - &statm->share_pages, - &statm->text, - &statm->library, - &statm->data, - &statm->dirty_pages) != 7) { + if (fscanf(f, "%lu %lu %lu %lu %lu %lu %lu", &statm->virtual_size, + &statm->resident_size, &statm->share_pages, &statm->text, + &statm->library, &statm->data, &statm->dirty_pages) != 7) { fclose(f); return false; } @@ -902,7 +902,7 @@ bool os_get_proc_memory_usage(os_proc_memory_usage_t *usage) return false; usage->resident_size = statm.resident_size; - usage->virtual_size = statm.virtual_size; + usage->virtual_size = statm.virtual_size; return true; } diff --git a/libobs/util/platform-windows.c b/libobs/util/platform-windows.c index 08c9e5b..a41b19f 100644 --- a/libobs/util/platform-windows.c +++ b/libobs/util/platform-windows.c @@ -101,20 +101,19 @@ void *os_dlopen(const char *path) char *message = NULL; FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, error, - MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), - (LPSTR)&message, 0, NULL); + FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, error, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + (LPSTR)&message, 0, NULL); - blog(LOG_INFO, "LoadLibrary failed for '%s': %s (%lu)", - path, message, error); + blog(LOG_INFO, "LoadLibrary failed for '%s': %s (%lu)", path, + message, error); if (message) LocalFree(message); } - return h_library; } @@ -122,7 +121,7 @@ void *os_dlsym(void *module, const char *func) { void *handle; - handle = (void*)GetProcAddress(module, func); + handle = (void *)GetProcAddress(module, func); return handle; } @@ -133,7 +132,7 @@ void os_dlclose(void *module) } union time_data { - FILETIME ft; + FILETIME ft; unsigned long long val; }; @@ -145,8 +144,8 @@ struct os_cpu_usage_info { os_cpu_usage_info_t *os_cpu_usage_info_start(void) { struct os_cpu_usage_info *info = bzalloc(sizeof(*info)); - SYSTEM_INFO si; - FILETIME dummy; + SYSTEM_INFO si; + FILETIME dummy; GetSystemInfo(&si); GetSystemTimeAsFileTime(&info->last_time.ft); @@ -160,23 +159,23 @@ os_cpu_usage_info_t *os_cpu_usage_info_start(void) double os_cpu_usage_info_query(os_cpu_usage_info_t *info) { union time_data cur_time, cur_sys_time, cur_user_time; - FILETIME dummy; - double percent; + FILETIME dummy; + double percent; if (!info) return 0.0; GetSystemTimeAsFileTime(&cur_time.ft); - GetProcessTimes(GetCurrentProcess(), &dummy, &dummy, - &cur_sys_time.ft, &cur_user_time.ft); + GetProcessTimes(GetCurrentProcess(), &dummy, &dummy, &cur_sys_time.ft, + &cur_user_time.ft); percent = (double)(cur_sys_time.val - info->last_sys_time.val + - (cur_user_time.val - info->last_user_time.val)); + (cur_user_time.val - info->last_user_time.val)); percent /= (double)(cur_time.val - info->last_time.val); percent /= (double)info->core_count; - info->last_time.val = cur_time.val; - info->last_sys_time.val = cur_sys_time.val; + info->last_time.val = cur_time.val; + info->last_sys_time.val = cur_sys_time.val; info->last_user_time.val = cur_user_time.val; return percent * 100.0; @@ -196,9 +195,9 @@ bool os_sleepto_ns(uint64_t time_target) if (t >= time_target) return false; - milliseconds = (uint32_t)((time_target - t)/1000000); + milliseconds = (uint32_t)((time_target - t) / 1000000); if (milliseconds > 1) - Sleep(milliseconds-1); + Sleep(milliseconds - 1); for (;;) { t = os_gettime_ns(); @@ -237,12 +236,11 @@ uint64_t os_gettime_ns(void) /* returns [folder]\[name] on windows */ static int os_get_path_internal(char *dst, size_t size, const char *name, - int folder) + int folder) { wchar_t path_utf16[MAX_PATH]; - SHGetFolderPathW(NULL, folder, NULL, SHGFP_TYPE_CURRENT, - path_utf16); + SHGetFolderPathW(NULL, folder, NULL, SHGFP_TYPE_CURRENT, path_utf16); if (os_wcs_to_utf8(path_utf16, 0, dst, size) != 0) { if (!name || !*name) { @@ -265,8 +263,7 @@ static char *os_get_path_ptr_internal(const char *name, int folder) wchar_t path_utf16[MAX_PATH]; struct dstr path; - SHGetFolderPathW(NULL, folder, NULL, SHGFP_TYPE_CURRENT, - path_utf16); + SHGetFolderPathW(NULL, folder, NULL, SHGFP_TYPE_CURRENT, path_utf16); os_wcs_to_utf8_ptr(path_utf16, 0, &ptr); dstr_init_move_array(&path, ptr); @@ -369,19 +366,19 @@ char *os_get_abs_path_ptr(const char *path) } struct os_dir { - HANDLE handle; - WIN32_FIND_DATA wfd; - bool first; + HANDLE handle; + WIN32_FIND_DATA wfd; + bool first; struct os_dirent out; }; os_dir_t *os_opendir(const char *path) { - struct dstr path_str = {0}; - struct os_dir *dir = NULL; + struct dstr path_str = {0}; + struct os_dir *dir = NULL; WIN32_FIND_DATA wfd; - HANDLE handle; - wchar_t *w_path; + HANDLE handle; + wchar_t *w_path; dstr_copy(&path_str, path); dstr_cat(&path_str, "/*.*"); @@ -389,10 +386,10 @@ os_dir_t *os_opendir(const char *path) if (os_utf8_to_wcs_ptr(path_str.array, path_str.len, &w_path) > 0) { handle = FindFirstFileW(w_path, &wfd); if (handle != INVALID_HANDLE_VALUE) { - dir = bzalloc(sizeof(struct os_dir)); + dir = bzalloc(sizeof(struct os_dir)); dir->handle = handle; - dir->first = true; - dir->wfd = wfd; + dir->first = true; + dir->wfd = wfd; } bfree(w_path); @@ -421,7 +418,7 @@ struct os_dirent *os_readdir(os_dir_t *dir) } os_wcs_to_utf8(dir->wfd.cFileName, 0, dir->out.d_name, - sizeof(dir->out.d_name)); + sizeof(dir->out.d_name)); dir->out.directory = is_dir(&dir->wfd); @@ -438,15 +435,15 @@ void os_closedir(os_dir_t *dir) int64_t os_get_free_space(const char *path) { - ULARGE_INTEGER remainingSpace; - char abs_path[512]; - wchar_t w_abs_path[512]; + ULARGE_INTEGER remainingSpace; + char abs_path[512]; + wchar_t w_abs_path[512]; if (os_get_abs_path(path, abs_path, 512) > 0) { if (os_utf8_to_wcs(abs_path, 0, w_abs_path, 512) > 0) { - BOOL success = GetDiskFreeSpaceExW(w_abs_path, - (PULARGE_INTEGER)&remainingSpace, - NULL, NULL); + BOOL success = GetDiskFreeSpaceExW( + w_abs_path, (PULARGE_INTEGER)&remainingSpace, + NULL, NULL); if (success) return (int64_t)remainingSpace.QuadPart; } @@ -456,7 +453,7 @@ int64_t os_get_free_space(const char *path) } static void make_globent(struct os_globent *ent, WIN32_FIND_DATA *wfd, - const char *pattern) + const char *pattern) { struct dstr name = {0}; struct dstr path = {0}; @@ -480,10 +477,10 @@ static void make_globent(struct os_globent *ent, WIN32_FIND_DATA *wfd, int os_glob(const char *pattern, int flags, os_glob_t **pglob) { DARRAY(struct os_globent) files; - HANDLE handle; - WIN32_FIND_DATA wfd; - int ret = -1; - wchar_t *w_path; + HANDLE handle; + WIN32_FIND_DATA wfd; + int ret = -1; + wchar_t *w_path; da_init(files); @@ -567,8 +564,8 @@ int os_mkdir(const char *path) bfree(path_utf16); if (!success) - return (GetLastError() == ERROR_ALREADY_EXISTS) ? - MKDIR_EXISTS : MKDIR_ERROR; + return (GetLastError() == ERROR_ALREADY_EXISTS) ? MKDIR_EXISTS + : MKDIR_ERROR; return MKDIR_SUCCESS; } @@ -587,7 +584,9 @@ int os_rename(const char *old_path, const char *new_path) } code = MoveFileExW(old_path_utf16, new_path_utf16, - MOVEFILE_REPLACE_EXISTING) ? 0 : -1; + MOVEFILE_REPLACE_EXISTING) + ? 0 + : -1; error: bfree(old_path_utf16); @@ -615,7 +614,8 @@ int os_safe_replace(const char *target, const char *from, const char *backup) code = 0; } else if (GetLastError() == ERROR_FILE_NOT_FOUND) { code = MoveFileExW(wfrom, wtarget, MOVEFILE_REPLACE_EXISTING) - ? 0 : -1; + ? 0 + : -1; } fail: @@ -726,19 +726,12 @@ int os_chdir(const char *path) return ret; } -typedef DWORD (WINAPI *get_file_version_info_size_w_t)( - LPCWSTR module, - LPDWORD unused); -typedef BOOL (WINAPI *get_file_version_info_w_t)( - LPCWSTR module, - DWORD unused, - DWORD len, - LPVOID data); -typedef BOOL (WINAPI *ver_query_value_w_t)( - LPVOID data, - LPCWSTR subblock, - LPVOID *buf, - PUINT sizeout); +typedef DWORD(WINAPI *get_file_version_info_size_w_t)(LPCWSTR module, + LPDWORD unused); +typedef BOOL(WINAPI *get_file_version_info_w_t)(LPCWSTR module, DWORD unused, + DWORD len, LPVOID data); +typedef BOOL(WINAPI *ver_query_value_w_t)(LPVOID data, LPCWSTR subblock, + LPVOID *buf, PUINT sizeout); static get_file_version_info_size_w_t get_file_version_info_size = NULL; static get_file_version_info_w_t get_file_version_info = NULL; @@ -761,15 +754,15 @@ static bool initialize_version_functions(void) } } - get_file_version_info_size = (get_file_version_info_size_w_t) - GetProcAddress(ver, "GetFileVersionInfoSizeW"); - get_file_version_info = (get_file_version_info_w_t) - GetProcAddress(ver, "GetFileVersionInfoW"); - ver_query_value = (ver_query_value_w_t) - GetProcAddress(ver, "VerQueryValueW"); + get_file_version_info_size = + (get_file_version_info_size_w_t)GetProcAddress( + ver, "GetFileVersionInfoSizeW"); + get_file_version_info = (get_file_version_info_w_t)GetProcAddress( + ver, "GetFileVersionInfoW"); + ver_query_value = + (ver_query_value_w_t)GetProcAddress(ver, "VerQueryValueW"); - if (!get_file_version_info_size || - !get_file_version_info || + if (!get_file_version_info_size || !get_file_version_info || !ver_query_value) { blog(LOG_ERROR, "Failed to load windows version " "functions"); @@ -809,9 +802,10 @@ bool get_dll_ver(const wchar_t *lib, struct win_version_info *ver_info) return false; } - success = ver_query_value(data, L"\\", (LPVOID*)&info, &len); + success = ver_query_value(data, L"\\", (LPVOID *)&info, &len); if (!success || !info || !len) { - blog(LOG_ERROR, "Failed to get %s version info value", utf8_lib); + blog(LOG_ERROR, "Failed to get %s version info value", + utf8_lib); bfree(data); return false; } @@ -836,7 +830,7 @@ bool is_64_bit_windows(void) } void get_reg_dword(HKEY hkey, LPCWSTR sub_key, LPCWSTR value_name, - struct reg_dword *info) + struct reg_dword *info) { struct reg_dword reg = {0}; HKEY key; @@ -854,7 +848,7 @@ void get_reg_dword(HKEY hkey, LPCWSTR sub_key, LPCWSTR value_name, reg.size = sizeof(reg.return_value); reg.status = RegQueryValueExW(key, value_name, NULL, NULL, - (LPBYTE)®.return_value, ®.size); + (LPBYTE)®.return_value, ®.size); RegCloseKey(key); @@ -876,22 +870,24 @@ void get_win_ver(struct win_version_info *info) got_version = true; if (ver.major == 10) { - HKEY key; - DWORD size, win10_revision; + HKEY key; + DWORD size, win10_revision; LSTATUS status; - status = RegOpenKeyW(HKEY_LOCAL_MACHINE, - WINVER_REG_KEY, &key); + status = RegOpenKeyW(HKEY_LOCAL_MACHINE, WINVER_REG_KEY, + &key); if (status != ERROR_SUCCESS) return; size = sizeof(win10_revision); status = RegQueryValueExW(key, L"UBR", NULL, NULL, - (LPBYTE)&win10_revision, &size); + (LPBYTE)&win10_revision, + &size); if (status == ERROR_SUCCESS) - ver.revis = (int)win10_revision > ver.revis ? - (int)win10_revision : ver.revis; + ver.revis = (int)win10_revision > ver.revis + ? (int)win10_revision + : ver.revis; RegCloseKey(key); } @@ -923,11 +919,9 @@ bool os_inhibit_sleep_set_active(os_inhibit_t *info, bool active) return false; if (active) { - SetThreadExecutionState( - ES_CONTINUOUS | - ES_SYSTEM_REQUIRED | - ES_AWAYMODE_REQUIRED | - ES_DISPLAY_REQUIRED); + SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | + ES_AWAYMODE_REQUIRED | + ES_DISPLAY_REQUIRED); } else { SetThreadExecutionState(ES_CONTINUOUS); } @@ -951,13 +945,13 @@ void os_breakpoint(void) DWORD num_logical_cores(ULONG_PTR mask) { - DWORD left_shift = sizeof(ULONG_PTR) * 8 - 1; - DWORD bit_set_count = 0; - ULONG_PTR bit_test = (ULONG_PTR)1 << left_shift; + DWORD left_shift = sizeof(ULONG_PTR) * 8 - 1; + DWORD bit_set_count = 0; + ULONG_PTR bit_test = (ULONG_PTR)1 << left_shift; for (DWORD i = 0; i <= left_shift; ++i) { bit_set_count += ((mask & bit_test) ? 1 : 0); - bit_test /= 2; + bit_test /= 2; } return bit_set_count; @@ -1031,7 +1025,8 @@ uint64_t os_get_sys_free_size(void) return msex.ullAvailPhys; } -static inline bool os_get_proc_memory_usage_internal(PROCESS_MEMORY_COUNTERS *pmc) +static inline bool +os_get_proc_memory_usage_internal(PROCESS_MEMORY_COUNTERS *pmc) { if (!GetProcessMemoryInfo(GetCurrentProcess(), pmc, sizeof(*pmc))) return false; @@ -1045,7 +1040,7 @@ bool os_get_proc_memory_usage(os_proc_memory_usage_t *usage) return false; usage->resident_size = pmc.WorkingSetSize; - usage->virtual_size = pmc.PagefileUsage; + usage->virtual_size = pmc.PagefileUsage; return true; } diff --git a/libobs/util/platform.c b/libobs/util/platform.c index a8d036e..51910c0 100644 --- a/libobs/util/platform.c +++ b/libobs/util/platform.c @@ -145,7 +145,7 @@ size_t os_fread_mbs(FILE *file, char **pstr) *pstr = NULL; if (size > 0) { - char *mbstr = bmalloc(size+1); + char *mbstr = bmalloc(size + 1); fseek(file, 0, SEEK_SET); size = fread(mbstr, 1, size, file); @@ -192,7 +192,7 @@ size_t os_fread_utf8(FILE *file, char **pstr) if (size == 0) return 0; - utf8str = bmalloc(size+1); + utf8str = bmalloc(size + 1); fseek(file, offset, SEEK_SET); size = fread(utf8str, 1, size, file); @@ -256,7 +256,7 @@ bool os_quick_write_mbs_file(const char *path, const char *str, size_t len) } bool os_quick_write_utf8_file(const char *path, const char *str, size_t len, - bool marker) + bool marker) { FILE *f = os_fopen(path, "wb"); if (!f) @@ -282,8 +282,8 @@ bool os_quick_write_utf8_file(const char *path, const char *str, size_t len, } bool os_quick_write_utf8_file_safe(const char *path, const char *str, - size_t len, bool marker, const char *temp_ext, - const char *backup_ext) + size_t len, bool marker, + const char *temp_ext, const char *backup_ext) { struct dstr backup_path = {0}; struct dstr temp_path = {0}; @@ -291,7 +291,7 @@ bool os_quick_write_utf8_file_safe(const char *path, const char *str, if (!temp_ext || !*temp_ext) { blog(LOG_ERROR, "os_quick_write_utf8_file_safe: invalid " - "temporary extension specified"); + "temporary extension specified"); return false; } @@ -301,8 +301,10 @@ bool os_quick_write_utf8_file_safe(const char *path, const char *str, dstr_cat(&temp_path, temp_ext); if (!os_quick_write_utf8_file(temp_path.array, str, len, marker)) { - blog(LOG_ERROR, "os_quick_write_utf8_file_safe: failed to " - "write to %s", temp_path.array); + blog(LOG_ERROR, + "os_quick_write_utf8_file_safe: failed to " + "write to %s", + temp_path.array); goto cleanup; } @@ -324,7 +326,7 @@ cleanup: int64_t os_get_file_size(const char *path) { - FILE* f = os_fopen(path, "rb"); + FILE *f = os_fopen(path, "rb"); if (!f) return -1; @@ -357,7 +359,7 @@ size_t os_mbs_to_wcs(const char *str, size_t len, wchar_t *dst, size_t dst_size) } size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t *dst, - size_t dst_size) + size_t dst_size) { size_t in_len; size_t out_len; @@ -373,8 +375,8 @@ size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t *dst, return 0; if (out_len) - out_len = utf8_to_wchar(str, in_len, - dst, out_len + 1, 0); + out_len = + utf8_to_wchar(str, in_len, dst, out_len + 1, 0); dst[out_len] = 0; } @@ -405,7 +407,7 @@ size_t os_wcs_to_mbs(const wchar_t *str, size_t len, char *dst, size_t dst_size) } size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst, - size_t dst_size) + size_t dst_size) { size_t in_len; size_t out_len; @@ -421,8 +423,8 @@ size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst, return 0; if (out_len) - out_len = wchar_to_utf8(str, in_len, - dst, out_len + 1, 0); + out_len = + wchar_to_utf8(str, in_len, dst, out_len + 1, 0); dst[out_len] = 0; } @@ -484,12 +486,12 @@ size_t os_wcs_to_utf8_ptr(const wchar_t *str, size_t len, char **pstr) size_t os_utf8_to_mbs_ptr(const char *str, size_t len, char **pstr) { - char *dst = NULL; - size_t out_len = 0; + char *dst = NULL; + size_t out_len = 0; if (str) { wchar_t *wstr = NULL; - size_t wlen = os_utf8_to_wcs_ptr(str, len, &wstr); + size_t wlen = os_utf8_to_wcs_ptr(str, len, &wstr); out_len = os_wcs_to_mbs_ptr(wstr, wlen, &dst); bfree(wstr); } @@ -500,12 +502,12 @@ size_t os_utf8_to_mbs_ptr(const char *str, size_t len, char **pstr) size_t os_mbs_to_utf8_ptr(const char *str, size_t len, char **pstr) { - char *dst = NULL; - size_t out_len = 0; + char *dst = NULL; + size_t out_len = 0; if (str) { wchar_t *wstr = NULL; - size_t wlen = os_mbs_to_wcs_ptr(str, len, &wstr); + size_t wlen = os_mbs_to_wcs_ptr(str, len, &wstr); out_len = os_wcs_to_utf8_ptr(wstr, wlen, &dst); bfree(wstr); } @@ -522,13 +524,13 @@ static inline void to_locale(char *str) char *pos; point = localeconv()->decimal_point; - if(*point == '.') { + if (*point == '.') { /* No conversion needed */ return; } pos = strchr(str, '.'); - if(pos) + if (pos) *pos = *point; } @@ -538,13 +540,13 @@ static inline void from_locale(char *buffer) char *pos; point = localeconv()->decimal_point; - if(*point == '.') { + if (*point == '.') { /* No conversion needed */ return; } pos = strchr(buffer, *point); - if(pos) + if (pos) *pos = '.'; } @@ -563,19 +565,19 @@ int os_dtostr(double value, char *dst, size_t size) size_t length; ret = snprintf(dst, size, "%.17g", value); - if(ret < 0) + if (ret < 0) return -1; length = (size_t)ret; - if(length >= size) + if (length >= size) return -1; from_locale(dst); /* Make sure there's a dot or 'e' in the output. Otherwise a real is converted to an integer when decoding */ - if(strchr(dst, '.') == NULL && strchr(dst, 'e') == NULL) { - if(length + 3 >= size) { + if (strchr(dst, '.') == NULL && strchr(dst, 'e') == NULL) { + if (length + 3 >= size) { /* No space to append ".0" */ return -1; } @@ -588,17 +590,17 @@ int os_dtostr(double value, char *dst, size_t size) /* Remove leading '+' from positive exponent. Also remove leading zeros from exponents (added by some printf() implementations) */ start = strchr(dst, 'e'); - if(start) { + if (start) { start++; end = start + 1; - if(*start == '-') + if (*start == '-') start++; - while(*end == '0') + while (*end == '0') end++; - if(end != start) { + if (end != start) { memmove(start, end, length - (size_t)(end - dst)); length -= (size_t)(end - start); } @@ -677,7 +679,7 @@ static inline bool valid_string(const char *str) } static void replace_text(struct dstr *str, size_t pos, size_t len, - const char *new_text) + const char *new_text) { struct dstr front = {0}; struct dstr back = {0}; @@ -701,7 +703,7 @@ static void erase_ch(struct dstr *str, size_t pos) } char *os_generate_formatted_filename(const char *extension, bool space, - const char *format) + const char *format) { time_t now = time(0); struct tm *cur_time; @@ -709,30 +711,13 @@ char *os_generate_formatted_filename(const char *extension, bool space, const size_t spec_count = 23; static const char *spec[][2] = { - {"%CCYY", "%Y"}, - {"%YY", "%y"}, - {"%MM", "%m"}, - {"%DD", "%d"}, - {"%hh", "%H"}, - {"%mm", "%M"}, - {"%ss", "%S"}, - {"%%", "%%"}, + {"%CCYY", "%Y"}, {"%YY", "%y"}, {"%MM", "%m"}, {"%DD", "%d"}, + {"%hh", "%H"}, {"%mm", "%M"}, {"%ss", "%S"}, {"%%", "%%"}, - {"%a", ""}, - {"%A", ""}, - {"%b", ""}, - {"%B", ""}, - {"%d", ""}, - {"%H", ""}, - {"%I", ""}, - {"%m", ""}, - {"%M", ""}, - {"%p", ""}, - {"%S", ""}, - {"%y", ""}, - {"%Y", ""}, - {"%z", ""}, - {"%Z", ""}, + {"%a", ""}, {"%A", ""}, {"%b", ""}, {"%B", ""}, + {"%d", ""}, {"%H", ""}, {"%I", ""}, {"%m", ""}, + {"%M", ""}, {"%p", ""}, {"%S", ""}, {"%y", ""}, + {"%Y", ""}, {"%z", ""}, {"%Z", ""}, }; char convert[128] = {0}; @@ -751,11 +736,10 @@ char *os_generate_formatted_filename(const char *extension, bool space, if (astrcmp_n(cmp, spec[i][0], len) == 0) { if (strlen(spec[i][1])) strftime(convert, sizeof(convert), - spec[i][1], cur_time); + spec[i][1], cur_time); else strftime(convert, sizeof(convert), - spec[i][0], cur_time); - + spec[i][0], cur_time); dstr_copy(&c, convert); if (c.len && valid_string(c.array)) diff --git a/libobs/util/platform.h b/libobs/util/platform.h index ed21b01..45e0315 100644 --- a/libobs/util/platform.h +++ b/libobs/util/platform.h @@ -49,25 +49,26 @@ EXPORT size_t os_fread_utf8(FILE *file, char **pstr); /* functions purely for convenience */ EXPORT char *os_quick_read_utf8_file(const char *path); EXPORT bool os_quick_write_utf8_file(const char *path, const char *str, - size_t len, bool marker); + size_t len, bool marker); EXPORT bool os_quick_write_utf8_file_safe(const char *path, const char *str, - size_t len, bool marker, const char *temp_ext, - const char *backup_ext); + size_t len, bool marker, + const char *temp_ext, + const char *backup_ext); EXPORT char *os_quick_read_mbs_file(const char *path); EXPORT bool os_quick_write_mbs_file(const char *path, const char *str, - size_t len); + size_t len); EXPORT int64_t os_get_file_size(const char *path); EXPORT int64_t os_get_free_space(const char *path); EXPORT size_t os_mbs_to_wcs(const char *str, size_t str_len, wchar_t *dst, - size_t dst_size); + size_t dst_size); EXPORT size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t *dst, - size_t dst_size); + size_t dst_size); EXPORT size_t os_wcs_to_mbs(const wchar_t *str, size_t len, char *dst, - size_t dst_size); + size_t dst_size); EXPORT size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst, - size_t dst_size); + size_t dst_size); EXPORT size_t os_mbs_to_wcs_ptr(const char *str, size_t len, wchar_t **pstr); EXPORT size_t os_utf8_to_wcs_ptr(const char *str, size_t len, wchar_t **pstr); @@ -88,12 +89,12 @@ struct os_cpu_usage_info; typedef struct os_cpu_usage_info os_cpu_usage_info_t; EXPORT os_cpu_usage_info_t *os_cpu_usage_info_start(void); -EXPORT double os_cpu_usage_info_query(os_cpu_usage_info_t *info); -EXPORT void os_cpu_usage_info_destroy(os_cpu_usage_info_t *info); +EXPORT double os_cpu_usage_info_query(os_cpu_usage_info_t *info); +EXPORT void os_cpu_usage_info_destroy(os_cpu_usage_info_t *info); typedef const void os_performance_token_t; EXPORT os_performance_token_t *os_request_high_performance(const char *reason); -EXPORT void os_end_high_performance(os_performance_token_t *); +EXPORT void os_end_high_performance(os_performance_token_t *); /** * Sleeps to a specific time (in nanoseconds). Doesn't have to be super @@ -138,7 +139,7 @@ struct os_globent { }; struct os_glob_info { - size_t gl_pathc; + size_t gl_pathc; struct os_globent *gl_pathv; }; @@ -157,19 +158,19 @@ EXPORT int os_chdir(const char *path); EXPORT uint64_t os_get_free_disk_space(const char *dir); -#define MKDIR_EXISTS 1 -#define MKDIR_SUCCESS 0 -#define MKDIR_ERROR -1 +#define MKDIR_EXISTS 1 +#define MKDIR_SUCCESS 0 +#define MKDIR_ERROR -1 EXPORT int os_mkdir(const char *path); EXPORT int os_mkdirs(const char *path); EXPORT int os_rename(const char *old_path, const char *new_path); EXPORT int os_copyfile(const char *file_in, const char *file_out); EXPORT int os_safe_replace(const char *target_path, const char *from_path, - const char *backup_path); + const char *backup_path); EXPORT char *os_generate_formatted_filename(const char *extension, bool space, - const char *format); + const char *format); struct os_inhibit_info; typedef struct os_inhibit_info os_inhibit_t; @@ -202,6 +203,7 @@ EXPORT uint64_t os_get_proc_virtual_size(void); #endif #endif +/* clang-format off */ #ifdef __APPLE__ # define ARCH_BITS 64 #else @@ -219,6 +221,7 @@ EXPORT uint64_t os_get_proc_virtual_size(void); # endif # endif #endif +/* clang-format on */ #ifdef __cplusplus } diff --git a/libobs/util/profiler.c b/libobs/util/profiler.c index 9b57f2c..29a047f 100644 --- a/libobs/util/profiler.c +++ b/libobs/util/profiler.c @@ -93,16 +93,16 @@ static inline uint64_t diff_ns_to_usec(uint64_t prev, uint64_t next) static inline void update_max_probes(profile_times_table *map, size_t val) { - map->max_probe_count = map->max_probe_count < val ? - val : map->max_probe_count; + map->max_probe_count = + map->max_probe_count < val ? val : map->max_probe_count; } static void migrate_old_entries(profile_times_table *map, bool limit_items); -static void grow_hashmap(profile_times_table *map, - uint64_t usec, uint64_t count); +static void grow_hashmap(profile_times_table *map, uint64_t usec, + uint64_t count); static void add_hashmap_entry(profile_times_table *map, uint64_t usec, - uint64_t count) + uint64_t count) { size_t probes = 1; @@ -127,14 +127,14 @@ static void add_hashmap_entry(profile_times_table *map, uint64_t usec, if (entry->probes >= probes) continue; - if (map->occupied/(double)map->size > 0.7) { + if (map->occupied / (double)map->size > 0.7) { grow_hashmap(map, usec, count); return; } - size_t old_probes = entry->probes; - uint64_t old_count = entry->entry.count; - uint64_t old_usec = entry->entry.time_delta; + size_t old_probes = entry->probes; + uint64_t old_count = entry->entry.count; + uint64_t old_usec = entry->entry.time_delta; entry->probes = probes; entry->entry.count = count; @@ -143,8 +143,8 @@ static void add_hashmap_entry(profile_times_table *map, uint64_t usec, update_max_probes(map, probes); probes = old_probes; - count = old_count; - usec = old_usec; + count = old_count; + usec = old_usec; start = usec % map->size; } @@ -182,24 +182,24 @@ static void migrate_old_entries(profile_times_table *map, bool limit_items) continue; add_hashmap_entry(map, entry->entry.time_delta, - entry->entry.count); + entry->entry.count); map->old_occupied -= 1; } } -static void grow_hashmap(profile_times_table *map, - uint64_t usec, uint64_t count) +static void grow_hashmap(profile_times_table *map, uint64_t usec, + uint64_t count) { migrate_old_entries(map, false); - size_t old_size = map->size; + size_t old_size = map->size; size_t old_occupied = map->occupied; profile_times_table_entry *entries = map->entries; init_hashmap(map, (old_size * 2 < 16) ? 16 : (old_size * 2)); map->old_occupied = old_occupied; - map->old_entries = entries; + map->old_entries = entries; add_hashmap_entry(map, usec, count); } @@ -229,7 +229,7 @@ static profile_entry *get_child(profile_entry *parent, const char *name) } static void merge_call(profile_entry *entry, profile_call *call, - profile_call *prev_call) + profile_call *prev_call) { const size_t num = call->children.num; for (size_t i = 0; i < num; i++) { @@ -240,7 +240,7 @@ static void merge_call(profile_entry *entry, profile_call *call, if (entry->expected_time_between_calls != 0 && prev_call) { migrate_old_entries(&entry->times_between_calls, true); uint64_t usec = diff_ns_to_usec(prev_call->start_time, - call->start_time); + call->start_time); add_hashmap_entry(&entry->times_between_calls, usec, 1); } @@ -250,7 +250,7 @@ static void merge_call(profile_entry *entry, profile_call *call, #ifdef TRACK_OVERHEAD migrate_old_entries(&entry->overhead, true); - usec = diff_ns_to_usec(call->overhead_start, call->start_time); + usec = diff_ns_to_usec(call->overhead_start, call->start_time); usec += diff_ns_to_usec(call->end_time, call->overhead_end); add_hashmap_entry(&entry->overhead, usec, 1); #endif @@ -324,7 +324,7 @@ static profile_root_entry *get_root_entry(const char *name) } void profile_register_root(const char *name, - uint64_t expected_time_between_calls) + uint64_t expected_time_between_calls) { if (!lock_root()) return; @@ -349,8 +349,8 @@ static void merge_context(profile_call *context) profile_root_entry *r_entry = get_root_entry(context->name); - mutex = r_entry->mutex; - entry = r_entry->entry; + mutex = r_entry->mutex; + entry = r_entry->entry; prev_call = r_entry->prev_call; r_entry->prev_call = context; @@ -408,12 +408,13 @@ void profile_end(const char *name) call->name = name; if (call->name != name) { - blog(LOG_ERROR, "Called profile end with mismatching name: " - "start(\"%s\"[%p]) <-> end(\"%s\"[%p])", - call->name, call->name, name, name); + blog(LOG_ERROR, + "Called profile end with mismatching name: " + "start(\"%s\"[%p]) <-> end(\"%s\"[%p])", + call->name, call->name, name, name); profile_call *parent = call->parent; - while (parent && parent->parent && parent->name != name) + while (parent && parent->parent && parent->name != name) parent = parent->parent; if (!parent || parent->name != name) @@ -440,14 +441,14 @@ void profile_end(const char *name) static int profiler_time_entry_compare(const void *first, const void *second) { - int64_t diff = ((profiler_time_entry*)second)->time_delta - - ((profiler_time_entry*)first)->time_delta; + int64_t diff = ((profiler_time_entry *)second)->time_delta - + ((profiler_time_entry *)first)->time_delta; return diff < 0 ? -1 : (diff > 0 ? 1 : 0); } static uint64_t copy_map_to_array(profile_times_table *map, - profiler_time_entries_t *entry_buffer, - uint64_t *min_, uint64_t *max_) + profiler_time_entries_t *entry_buffer, + uint64_t *min_, uint64_t *max_) { migrate_old_entries(map, false); @@ -480,16 +481,18 @@ static uint64_t copy_map_to_array(profile_times_table *map, } typedef void (*profile_entry_print_func)(profiler_snapshot_entry_t *entry, - struct dstr *indent_buffer, struct dstr *output_buffer, - unsigned indent, uint64_t active, uint64_t parent_calls); + struct dstr *indent_buffer, + struct dstr *output_buffer, + unsigned indent, uint64_t active, + uint64_t parent_calls); /* UTF-8 characters */ #define VPIPE_RIGHT " \xe2\x94\xa3" -#define VPIPE " \xe2\x94\x83" -#define DOWN_RIGHT " \xe2\x94\x97" +#define VPIPE " \xe2\x94\x83" +#define DOWN_RIGHT " \xe2\x94\x97" static void make_indent_string(struct dstr *indent_buffer, unsigned indent, - uint64_t active) + uint64_t active) { indent_buffer->len = 0; @@ -505,15 +508,15 @@ static void make_indent_string(struct dstr *indent_buffer, unsigned indent, fragment = last ? VPIPE_RIGHT : VPIPE; else fragment = last ? DOWN_RIGHT : " "; - + dstr_cat(indent_buffer, fragment); } } static void gather_stats(uint64_t expected_time_between_calls, - profiler_time_entries_t *entries, - uint64_t calls, uint64_t *percentile99, uint64_t *median, - double *percent_within_bounds) + profiler_time_entries_t *entries, uint64_t calls, + uint64_t *percentile99, uint64_t *median, + double *percent_within_bounds) { if (!entries->num) { *percentile99 = 0; @@ -559,8 +562,9 @@ static void gather_stats(uint64_t expected_time_between_calls, #define G_MS "g\xC2\xA0ms" static void profile_print_entry(profiler_snapshot_entry_t *entry, - struct dstr *indent_buffer, struct dstr *output_buffer, - unsigned indent, uint64_t active, uint64_t parent_calls) + struct dstr *indent_buffer, + struct dstr *output_buffer, unsigned indent, + uint64_t active, uint64_t parent_calls) { uint64_t calls = entry->overall_count; uint64_t min_ = entry->min_time; @@ -568,28 +572,26 @@ static void profile_print_entry(profiler_snapshot_entry_t *entry, uint64_t percentile99 = 0; uint64_t median = 0; double percent_within_bounds = 0.; - gather_stats(entry->expected_time_between_calls, - &entry->times, calls, - &percentile99, &median, &percent_within_bounds); + gather_stats(entry->expected_time_between_calls, &entry->times, calls, + &percentile99, &median, &percent_within_bounds); make_indent_string(indent_buffer, indent, active); if (min_ == max_) { - dstr_printf(output_buffer, "%s%s: %"G_MS, - indent_buffer->array, entry->name, - min_ / 1000.); + dstr_printf(output_buffer, "%s%s: %" G_MS, indent_buffer->array, + entry->name, min_ / 1000.); } else { - dstr_printf(output_buffer, "%s%s: min=%"G_MS", median=%"G_MS", " - "max=%"G_MS", 99th percentile=%"G_MS, - indent_buffer->array, entry->name, - min_ / 1000., median / 1000., max_ / 1000., - percentile99 / 1000.); + dstr_printf(output_buffer, + "%s%s: min=%" G_MS ", median=%" G_MS ", " + "max=%" G_MS ", 99th percentile=%" G_MS, + indent_buffer->array, entry->name, min_ / 1000., + median / 1000., max_ / 1000., percentile99 / 1000.); if (entry->expected_time_between_calls) { double expected_ms = entry->expected_time_between_calls / 1000.; - dstr_catf(output_buffer, ", %g%% below %"G_MS, - percent_within_bounds, expected_ms); + dstr_catf(output_buffer, ", %g%% below %" G_MS, + percent_within_bounds, expected_ms); } } @@ -597,7 +599,7 @@ static void profile_print_entry(profiler_snapshot_entry_t *entry, double calls_per_parent = (double)calls / parent_calls; if (lround(calls_per_parent * 10) != 10) dstr_catf(output_buffer, ", %g calls per parent call", - calls_per_parent); + calls_per_parent); } blog(LOG_INFO, "%s", output_buffer->array); @@ -606,16 +608,16 @@ static void profile_print_entry(profiler_snapshot_entry_t *entry, for (size_t i = 0; i < entry->children.num; i++) { if ((i + 1) == entry->children.num) active &= (1 << indent) - 1; - profile_print_entry(&entry->children.array[i], - indent_buffer, output_buffer, - indent + 1, active, calls); + profile_print_entry(&entry->children.array[i], indent_buffer, + output_buffer, indent + 1, active, calls); } } static void gather_stats_between(profiler_time_entries_t *entries, - uint64_t calls, uint64_t lower_bound, uint64_t upper_bound, - uint64_t min_, uint64_t max_, uint64_t *median, - double *percent, double *lower, double *higher) + uint64_t calls, uint64_t lower_bound, + uint64_t upper_bound, uint64_t min_, + uint64_t max_, uint64_t *median, + double *percent, double *lower, double *higher) { *median = 0; *percent = 0.; @@ -679,8 +681,10 @@ static void gather_stats_between(profiler_time_entries_t *entries, } static void profile_print_entry_expected(profiler_snapshot_entry_t *entry, - struct dstr *indent_buffer, struct dstr *output_buffer, - unsigned indent, uint64_t active, uint64_t parent_calls) + struct dstr *indent_buffer, + struct dstr *output_buffer, + unsigned indent, uint64_t active, + uint64_t parent_calls) { UNUSED_PARAMETER(parent_calls); @@ -696,33 +700,31 @@ static void profile_print_entry_expected(profiler_snapshot_entry_t *entry, double lower = 0.; double higher = 0.; gather_stats_between(&entry->times_between_calls, - entry->overall_between_calls_count, - (uint64_t)(expected_time * 0.98), - (uint64_t)(expected_time * 1.02 + 0.5), - min_, max_, - &median, &percent, &lower, &higher); + entry->overall_between_calls_count, + (uint64_t)(expected_time * 0.98), + (uint64_t)(expected_time * 1.02 + 0.5), min_, max_, + &median, &percent, &lower, &higher); make_indent_string(indent_buffer, indent, active); - blog(LOG_INFO, "%s%s: min=%"G_MS", median=%"G_MS", max=%"G_MS", %g%% " - "within ±2%% of %"G_MS" (%g%% lower, %g%% higher)", - indent_buffer->array, entry->name, - min_ / 1000., median / 1000., max_ / 1000., percent, - expected_time / 1000., - lower, higher); + blog(LOG_INFO, + "%s%s: min=%" G_MS ", median=%" G_MS ", max=%" G_MS ", %g%% " + "within ±2%% of %" G_MS " (%g%% lower, %g%% higher)", + indent_buffer->array, entry->name, min_ / 1000., median / 1000., + max_ / 1000., percent, expected_time / 1000., lower, higher); active |= (uint64_t)1 << indent; for (size_t i = 0; i < entry->children.num; i++) { if ((i + 1) == entry->children.num) active &= (1 << indent) - 1; profile_print_entry_expected(&entry->children.array[i], - indent_buffer, output_buffer, - indent + 1, active, 0); + indent_buffer, output_buffer, + indent + 1, active, 0); } } void profile_print_func(const char *intro, profile_entry_print_func print, - profiler_snapshot_t *snap) + profiler_snapshot_t *snap) { struct dstr indent_buffer = {0}; struct dstr output_buffer = {0}; @@ -733,8 +735,8 @@ void profile_print_func(const char *intro, profile_entry_print_func print, blog(LOG_INFO, "%s", intro); for (size_t i = 0; i < snap->roots.num; i++) { - print(&snap->roots.array[i], - &indent_buffer, &output_buffer, 0, 0, 0); + print(&snap->roots.array[i], &indent_buffer, &output_buffer, 0, + 0, 0); } blog(LOG_INFO, "================================================="); @@ -748,13 +750,13 @@ void profile_print_func(const char *intro, profile_entry_print_func print, void profiler_print(profiler_snapshot_t *snap) { profile_print_func("== Profiler Results =============================", - profile_print_entry, snap); + profile_print_entry, snap); } void profiler_print_time_between_calls(profiler_snapshot_t *snap) { profile_print_func("== Profiler Time Between Calls ==================", - profile_print_entry_expected, snap); + profile_print_entry_expected, snap); } static void free_call_children(profile_call *call) @@ -825,19 +827,18 @@ void profiler_free(void) da_free(old_root_entries); } - /* ------------------------------------------------------------------------- */ /* Profiler name storage */ struct profiler_name_store { pthread_mutex_t mutex; - DARRAY(char*) names; + DARRAY(char *) names; }; profiler_name_store_t *profiler_name_store_create(void) { profiler_name_store_t *store = bzalloc(sizeof(profiler_name_store_t)); - + if (pthread_mutex_init(&store->mutex, NULL)) goto error; @@ -860,8 +861,8 @@ void profiler_name_store_free(profiler_name_store_t *store) bfree(store); } -const char *profile_store_name(profiler_name_store_t *store, - const char *format, ...) +const char *profile_store_name(profiler_name_store_t *store, const char *format, + ...) { va_list args; va_start(args, format); @@ -881,44 +882,41 @@ const char *profile_store_name(profiler_name_store_t *store, return result; } - /* ------------------------------------------------------------------------- */ /* Profiler data access */ static void add_entry_to_snapshot(profile_entry *entry, - profiler_snapshot_entry_t *s_entry) + profiler_snapshot_entry_t *s_entry) { s_entry->name = entry->name; - s_entry->overall_count = copy_map_to_array(&entry->times, - &s_entry->times, - &s_entry->min_time, &s_entry->max_time); + s_entry->overall_count = + copy_map_to_array(&entry->times, &s_entry->times, + &s_entry->min_time, &s_entry->max_time); - if ((s_entry->expected_time_between_calls = - entry->expected_time_between_calls)) + if ((s_entry->expected_time_between_calls = + entry->expected_time_between_calls)) s_entry->overall_between_calls_count = copy_map_to_array(&entry->times_between_calls, - &s_entry->times_between_calls, - &s_entry->min_time_between_calls, - &s_entry->max_time_between_calls); + &s_entry->times_between_calls, + &s_entry->min_time_between_calls, + &s_entry->max_time_between_calls); da_reserve(s_entry->children, entry->children.num); for (size_t i = 0; i < entry->children.num; i++) add_entry_to_snapshot(&entry->children.array[i], - da_push_back_new(s_entry->children)); + da_push_back_new(s_entry->children)); } static void sort_snapshot_entry(profiler_snapshot_entry_t *entry) { - qsort(entry->times.array, entry->times.num, - sizeof(profiler_time_entry), - profiler_time_entry_compare); + qsort(entry->times.array, entry->times.num, sizeof(profiler_time_entry), + profiler_time_entry_compare); if (entry->expected_time_between_calls) qsort(entry->times_between_calls.array, - entry->times_between_calls.num, - sizeof(profiler_time_entry), - profiler_time_entry_compare); + entry->times_between_calls.num, + sizeof(profiler_time_entry), profiler_time_entry_compare); for (size_t i = 0; i < entry->children.num; i++) sort_snapshot_entry(&entry->children.array[i]); @@ -933,7 +931,7 @@ profiler_snapshot_t *profile_snapshot_create(void) for (size_t i = 0; i < root_entries.num; i++) { pthread_mutex_lock(root_entries.array[i].mutex); add_entry_to_snapshot(root_entries.array[i].entry, - da_push_back_new(snap->roots)); + da_push_back_new(snap->roots)); pthread_mutex_unlock(root_entries.array[i].mutex); } pthread_mutex_unlock(&root_mutex); @@ -968,48 +966,50 @@ void profile_snapshot_free(profiler_snapshot_t *snap) typedef void (*dump_csv_func)(void *data, struct dstr *buffer); static void entry_dump_csv(struct dstr *buffer, - const profiler_snapshot_entry_t *parent, - const profiler_snapshot_entry_t *entry, - dump_csv_func func, void *data) + const profiler_snapshot_entry_t *parent, + const profiler_snapshot_entry_t *entry, + dump_csv_func func, void *data) { const char *parent_name = parent ? parent->name : NULL; for (size_t i = 0; i < entry->times.num; i++) { - dstr_printf(buffer, "%p,%p,%p,%p,%s,0," - "%"PRIu64",%"PRIu64"\n", entry, - parent, entry->name, parent_name, entry->name, - entry->times.array[i].time_delta, - entry->times.array[i].count); + dstr_printf(buffer, + "%p,%p,%p,%p,%s,0," + "%" PRIu64 ",%" PRIu64 "\n", + entry, parent, entry->name, parent_name, + entry->name, entry->times.array[i].time_delta, + entry->times.array[i].count); func(data, buffer); } for (size_t i = 0; i < entry->times_between_calls.num; i++) { - dstr_printf(buffer,"%p,%p,%p,%p,%s," - "%"PRIu64",%"PRIu64",%"PRIu64"\n", entry, - parent, entry->name, parent_name, entry->name, - entry->expected_time_between_calls, - entry->times_between_calls.array[i].time_delta, - entry->times_between_calls.array[i].count); + dstr_printf(buffer, + "%p,%p,%p,%p,%s," + "%" PRIu64 ",%" PRIu64 ",%" PRIu64 "\n", + entry, parent, entry->name, parent_name, + entry->name, entry->expected_time_between_calls, + entry->times_between_calls.array[i].time_delta, + entry->times_between_calls.array[i].count); func(data, buffer); } for (size_t i = 0; i < entry->children.num; i++) - entry_dump_csv(buffer, entry, &entry->children.array[i], - func, data); + entry_dump_csv(buffer, entry, &entry->children.array[i], func, + data); } static void profiler_snapshot_dump(const profiler_snapshot_t *snap, - dump_csv_func func, void *data) + dump_csv_func func, void *data) { struct dstr buffer = {0}; dstr_init_copy(&buffer, "id,parent_id,name_id,parent_name_id,name," - "time_between_calls,time_delta_µs,count\n"); + "time_between_calls,time_delta_µs,count\n"); func(data, &buffer); for (size_t i = 0; i < snap->roots.num; i++) - entry_dump_csv(&buffer, NULL, - &snap->roots.array[i], func, data); + entry_dump_csv(&buffer, NULL, &snap->roots.array[i], func, + data); dstr_free(&buffer); } @@ -1020,7 +1020,7 @@ static void dump_csv_fwrite(void *data, struct dstr *buffer) } bool profiler_snapshot_dump_csv(const profiler_snapshot_t *snap, - const char *filename) + const char *filename) { FILE *f = os_fopen(filename, "wb+"); if (!f) @@ -1038,7 +1038,7 @@ static void dump_csv_gzwrite(void *data, struct dstr *buffer) } bool profiler_snapshot_dump_csv_gz(const profiler_snapshot_t *snap, - const char *filename) + const char *filename) { gzFile gz; #ifdef _WIN32 @@ -1068,7 +1068,8 @@ size_t profiler_snapshot_num_roots(profiler_snapshot_t *snap) } void profiler_snapshot_enumerate_roots(profiler_snapshot_t *snap, - profiler_entry_enum_func func, void *context) + profiler_entry_enum_func func, + void *context) { if (!snap) return; @@ -1079,7 +1080,7 @@ void profiler_snapshot_enumerate_roots(profiler_snapshot_t *snap, } void profiler_snapshot_filter_roots(profiler_snapshot_t *snap, - profiler_name_filter_func func, void *data) + profiler_name_filter_func func, void *data) { for (size_t i = 0; i < snap->roots.num;) { bool remove = false; @@ -1104,7 +1105,8 @@ size_t profiler_snapshot_num_children(profiler_snapshot_entry_t *entry) } void profiler_snapshot_enumerate_children(profiler_snapshot_entry_t *entry, - profiler_entry_enum_func func, void *context) + profiler_entry_enum_func func, + void *context) { if (!entry) return; @@ -1119,14 +1121,13 @@ const char *profiler_snapshot_entry_name(profiler_snapshot_entry_t *entry) return entry ? entry->name : NULL; } -profiler_time_entries_t *profiler_snapshot_entry_times( - profiler_snapshot_entry_t *entry) +profiler_time_entries_t * +profiler_snapshot_entry_times(profiler_snapshot_entry_t *entry) { return entry ? &entry->times : NULL; } -uint64_t profiler_snapshot_entry_overall_count( - profiler_snapshot_entry_t *entry) +uint64_t profiler_snapshot_entry_overall_count(profiler_snapshot_entry_t *entry) { return entry ? entry->overall_count : 0; } @@ -1141,32 +1142,32 @@ uint64_t profiler_snapshot_entry_max_time(profiler_snapshot_entry_t *entry) return entry ? entry->max_time : 0; } -profiler_time_entries_t *profiler_snapshot_entry_times_between_calls( - profiler_snapshot_entry_t *entry) +profiler_time_entries_t * +profiler_snapshot_entry_times_between_calls(profiler_snapshot_entry_t *entry) { return entry ? &entry->times_between_calls : NULL; } uint64_t profiler_snapshot_entry_expected_time_between_calls( - profiler_snapshot_entry_t *entry) + profiler_snapshot_entry_t *entry) { return entry ? entry->expected_time_between_calls : 0; } -uint64_t profiler_snapshot_entry_min_time_between_calls( - profiler_snapshot_entry_t *entry) +uint64_t +profiler_snapshot_entry_min_time_between_calls(profiler_snapshot_entry_t *entry) { return entry ? entry->min_time_between_calls : 0; } -uint64_t profiler_snapshot_entry_max_time_between_calls( - profiler_snapshot_entry_t *entry) +uint64_t +profiler_snapshot_entry_max_time_between_calls(profiler_snapshot_entry_t *entry) { return entry ? entry->max_time_between_calls : 0; } uint64_t profiler_snapshot_entry_overall_between_calls_count( - profiler_snapshot_entry_t *entry) + profiler_snapshot_entry_t *entry) { return entry ? entry->overall_between_calls_count : 0; } diff --git a/libobs/util/profiler.h b/libobs/util/profiler.h index a795d04..91d958e 100644 --- a/libobs/util/profiler.h +++ b/libobs/util/profiler.h @@ -15,7 +15,7 @@ typedef struct profiler_time_entry profiler_time_entry_t; /* Profiling */ EXPORT void profile_register_root(const char *name, - uint64_t expected_time_between_calls); + uint64_t expected_time_between_calls); EXPORT void profile_start(const char *name); EXPORT void profile_end(const char *name); @@ -49,7 +49,7 @@ EXPORT void profiler_name_store_free(profiler_name_store_t *store); PRINTFATTR(2, 3) EXPORT const char *profile_store_name(profiler_name_store_t *store, - const char *format, ...); + const char *format, ...); #undef PRINTFATTR @@ -64,52 +64,55 @@ struct profiler_time_entry { typedef DARRAY(profiler_time_entry_t) profiler_time_entries_t; typedef bool (*profiler_entry_enum_func)(void *context, - profiler_snapshot_entry_t *entry); + profiler_snapshot_entry_t *entry); EXPORT profiler_snapshot_t *profile_snapshot_create(void); EXPORT void profile_snapshot_free(profiler_snapshot_t *snap); EXPORT bool profiler_snapshot_dump_csv(const profiler_snapshot_t *snap, - const char *filename); + const char *filename); EXPORT bool profiler_snapshot_dump_csv_gz(const profiler_snapshot_t *snap, - const char *filename); + const char *filename); EXPORT size_t profiler_snapshot_num_roots(profiler_snapshot_t *snap); EXPORT void profiler_snapshot_enumerate_roots(profiler_snapshot_t *snap, - profiler_entry_enum_func func, void *context); + profiler_entry_enum_func func, + void *context); typedef bool (*profiler_name_filter_func)(void *data, const char *name, - bool *remove); + bool *remove); EXPORT void profiler_snapshot_filter_roots(profiler_snapshot_t *snap, - profiler_name_filter_func func, void *data); + profiler_name_filter_func func, + void *data); EXPORT size_t profiler_snapshot_num_children(profiler_snapshot_entry_t *entry); -EXPORT void profiler_snapshot_enumerate_children( - profiler_snapshot_entry_t *entry, - profiler_entry_enum_func func, void *context); +EXPORT void +profiler_snapshot_enumerate_children(profiler_snapshot_entry_t *entry, + profiler_entry_enum_func func, + void *context); -EXPORT const char *profiler_snapshot_entry_name( - profiler_snapshot_entry_t *entry); +EXPORT const char * +profiler_snapshot_entry_name(profiler_snapshot_entry_t *entry); -EXPORT profiler_time_entries_t *profiler_snapshot_entry_times( - profiler_snapshot_entry_t *entry); -EXPORT uint64_t profiler_snapshot_entry_min_time( - profiler_snapshot_entry_t *entry); -EXPORT uint64_t profiler_snapshot_entry_max_time( - profiler_snapshot_entry_t *entry); -EXPORT uint64_t profiler_snapshot_entry_overall_count( - profiler_snapshot_entry_t *entry); +EXPORT profiler_time_entries_t * +profiler_snapshot_entry_times(profiler_snapshot_entry_t *entry); +EXPORT uint64_t +profiler_snapshot_entry_min_time(profiler_snapshot_entry_t *entry); +EXPORT uint64_t +profiler_snapshot_entry_max_time(profiler_snapshot_entry_t *entry); +EXPORT uint64_t +profiler_snapshot_entry_overall_count(profiler_snapshot_entry_t *entry); -EXPORT profiler_time_entries_t *profiler_snapshot_entry_times_between_calls( - profiler_snapshot_entry_t *entry); +EXPORT profiler_time_entries_t * +profiler_snapshot_entry_times_between_calls(profiler_snapshot_entry_t *entry); EXPORT uint64_t profiler_snapshot_entry_expected_time_between_calls( - profiler_snapshot_entry_t *entry); + profiler_snapshot_entry_t *entry); EXPORT uint64_t profiler_snapshot_entry_min_time_between_calls( - profiler_snapshot_entry_t *entry); + profiler_snapshot_entry_t *entry); EXPORT uint64_t profiler_snapshot_entry_max_time_between_calls( - profiler_snapshot_entry_t *entry); + profiler_snapshot_entry_t *entry); EXPORT uint64_t profiler_snapshot_entry_overall_between_calls_count( - profiler_snapshot_entry_t *entry); + profiler_snapshot_entry_t *entry); #ifdef __cplusplus } diff --git a/libobs/util/profiler.hpp b/libobs/util/profiler.hpp index c61a9bf..3127398 100644 --- a/libobs/util/profiler.hpp +++ b/libobs/util/profiler.hpp @@ -6,18 +6,13 @@ struct ScopeProfiler { const char *name; bool enabled = true; - ScopeProfiler(const char *name) - : name(name) - { - profile_start(name); - } + ScopeProfiler(const char *name) : name(name) { profile_start(name); } ~ScopeProfiler() { Stop(); } ScopeProfiler(const ScopeProfiler &) = delete; ScopeProfiler(ScopeProfiler &&other) - : name(other.name), - enabled(other.enabled) + : name(other.name), enabled(other.enabled) { other.enabled = false; } @@ -37,7 +32,7 @@ struct ScopeProfiler { #ifndef NO_PROFILER_MACROS -#define ScopeProfiler_NameConcatImpl(x, y) x ## y +#define ScopeProfiler_NameConcatImpl(x, y) x##y #define ScopeProfiler_NameConcat(x, y) ScopeProfiler_NameConcatImpl(x, y) #ifdef __COUNTER__ @@ -46,7 +41,7 @@ struct ScopeProfiler { #define ScopeProfiler_Name(x) ScopeProfiler_NameConcat(x, __LINE__) #endif -#define ProfileScope(x) ScopeProfiler \ - ScopeProfiler_Name(SCOPE_PROFILE){x} +#define ProfileScope(x) \ + ScopeProfiler ScopeProfiler_Name(SCOPE_PROFILE) { x } #endif diff --git a/libobs/util/serializer.h b/libobs/util/serializer.h index f97f894..c9c7378 100644 --- a/libobs/util/serializer.h +++ b/libobs/util/serializer.h @@ -34,26 +34,26 @@ enum serialize_seek_type { }; struct serializer { - void *data; + void *data; - size_t (*read)(void *, void *, size_t); - size_t (*write)(void *, const void *, size_t); - int64_t (*seek)(void *, int64_t, enum serialize_seek_type); - int64_t (*get_pos)(void *); + size_t (*read)(void *, void *, size_t); + size_t (*write)(void *, const void *, size_t); + int64_t (*seek)(void *, int64_t, enum serialize_seek_type); + int64_t (*get_pos)(void *); }; static inline size_t s_read(struct serializer *s, void *data, size_t size) { if (s && s->read && data && size) - return s->read(s->data, (void*)data, size); + return s->read(s->data, (void *)data, size); return 0; } static inline size_t s_write(struct serializer *s, const void *data, - size_t size) + size_t size) { if (s && s->write && data && size) - return s->write(s->data, (void*)data, size); + return s->write(s->data, (void *)data, size); return 0; } @@ -70,7 +70,7 @@ static inline size_t serialize(struct serializer *s, void *data, size_t len) } static inline int64_t serializer_seek(struct serializer *s, int64_t offset, - enum serialize_seek_type seek_type) + enum serialize_seek_type seek_type) { if (s && s->seek) return s->seek(s->data, offset, seek_type); @@ -99,7 +99,7 @@ static inline void s_wl16(struct serializer *s, uint16_t u16) static inline void s_wl24(struct serializer *s, uint32_t u24) { - s_w8 (s, (uint8_t)u24); + s_w8(s, (uint8_t)u24); s_wl16(s, (uint16_t)(u24 >> 8)); } @@ -117,12 +117,12 @@ static inline void s_wl64(struct serializer *s, uint64_t u64) static inline void s_wlf(struct serializer *s, float f) { - s_wl32(s, *(uint32_t*)&f); + s_wl32(s, *(uint32_t *)&f); } static inline void s_wld(struct serializer *s, double d) { - s_wl64(s, *(uint64_t*)&d); + s_wl64(s, *(uint64_t *)&d); } static inline void s_wb16(struct serializer *s, uint16_t u16) @@ -134,7 +134,7 @@ static inline void s_wb16(struct serializer *s, uint16_t u16) static inline void s_wb24(struct serializer *s, uint32_t u24) { s_wb16(s, (uint16_t)(u24 >> 8)); - s_w8 (s, (uint8_t)u24); + s_w8(s, (uint8_t)u24); } static inline void s_wb32(struct serializer *s, uint32_t u32) @@ -151,12 +151,12 @@ static inline void s_wb64(struct serializer *s, uint64_t u64) static inline void s_wbf(struct serializer *s, float f) { - s_wb32(s, *(uint32_t*)&f); + s_wb32(s, *(uint32_t *)&f); } static inline void s_wbd(struct serializer *s, double d) { - s_wb64(s, *(uint64_t*)&d); + s_wb64(s, *(uint64_t *)&d); } #ifdef __cplusplus diff --git a/libobs/util/text-lookup.c b/libobs/util/text-lookup.c index eeac096..433aebd 100644 --- a/libobs/util/text-lookup.c +++ b/libobs/util/text-lookup.c @@ -81,7 +81,7 @@ static struct text_node *text_node_bychar(struct text_node *node, char ch) } static struct text_node *text_node_byname(struct text_node *node, - const char *name) + const char *name) { struct text_node *subnode = node->first_subnode; @@ -102,8 +102,8 @@ struct text_lookup { struct text_node *top; }; -static void lookup_createsubnode(const char *lookup_val, - struct text_leaf *leaf, struct text_node *node) +static void lookup_createsubnode(const char *lookup_val, struct text_leaf *leaf, + struct text_node *node) { struct text_node *new = bzalloc(sizeof(struct text_node)); new->leaf = leaf; @@ -114,11 +114,11 @@ static void lookup_createsubnode(const char *lookup_val, } static void lookup_splitnode(const char *lookup_val, size_t len, - struct text_leaf *leaf, struct text_node *node) + struct text_leaf *leaf, struct text_node *node) { struct text_node *split = bzalloc(sizeof(struct text_node)); - dstr_copy(&split->str, node->str.array+len); + dstr_copy(&split->str, node->str.array + len); split->leaf = node->leaf; split->first_subnode = node->first_subnode; node->first_subnode = split; @@ -127,21 +127,21 @@ static void lookup_splitnode(const char *lookup_val, size_t len, if (lookup_val[len] != 0) { node->leaf = NULL; - lookup_createsubnode(lookup_val+len, leaf, node); + lookup_createsubnode(lookup_val + len, leaf, node); } else { node->leaf = leaf; } } static inline void lookup_replaceleaf(struct text_node *node, - struct text_leaf *leaf) + struct text_leaf *leaf) { text_leaf_destroy(node->leaf); node->leaf = leaf; } static void lookup_addstring(const char *lookup_val, struct text_leaf *leaf, - struct text_node *node) + struct text_node *node) { struct text_node *child; @@ -157,7 +157,7 @@ static void lookup_addstring(const char *lookup_val, struct text_leaf *leaf, for (len = 0; len < child->str.len; len++) { char val1 = child->str.array[len], - val2 = lookup_val[len]; + val2 = lookup_val[len]; if (val1 >= 'A' && val1 <= 'Z') val1 += 0x20; @@ -169,7 +169,7 @@ static void lookup_addstring(const char *lookup_val, struct text_leaf *leaf, } if (len == child->str.len) { - lookup_addstring(lookup_val+len, leaf, child); + lookup_addstring(lookup_val + len, leaf, child); return; } else { lookup_splitnode(lookup_val, len, leaf, child); @@ -182,7 +182,7 @@ static void lookup_addstring(const char *lookup_val, struct text_leaf *leaf, static void lookup_getstringtoken(struct lexer *lex, struct strref *token) { const char *temp = lex->offset; - bool was_backslash = false; + bool was_backslash = false; while (*temp != 0 && *temp != '\n') { if (!was_backslash) { @@ -205,7 +205,7 @@ static void lookup_getstringtoken(struct lexer *lex, struct strref *token) token->array++; token->len--; - if (*(temp-1) == '"') + if (*(temp - 1) == '"') token->len--; } @@ -225,7 +225,7 @@ static bool lookup_gettoken(struct lexer *lex, struct strref *str) if (!str->array) { /* comments are designated with a #, and end at LF */ if (ch == '#') { - while(ch != '\n' && ch != 0) + while (ch != '\n' && ch != 0) ch = *(++lex->offset); } else if (temp.type == BASETOKEN_WHITESPACE) { strref_copy(str, &temp.text); @@ -280,9 +280,9 @@ static inline bool lookup_goto_nextline(struct lexer *p) static char *convert_string(const char *str, size_t len) { struct dstr out; - out.array = bstrdup_n(str, len); - out.capacity = len+1; - out.len = len; + out.array = bstrdup_n(str, len); + out.capacity = len + 1; + out.len = len; dstr_replace(&out, "\\n", "\n"); dstr_replace(&out, "\\t", "\t"); @@ -293,7 +293,7 @@ static char *convert_string(const char *str, size_t len) } static void lookup_addfiledata(struct text_lookup *lookup, - const char *file_data) + const char *file_data) { struct lexer lex; struct strref name, value; @@ -309,7 +309,7 @@ static void lookup_addfiledata(struct text_lookup *lookup, if (*name.array == '\n') continue; -getval: + getval: if (!lookup_gettoken(&lex, &value)) break; if (*value.array == '\n') @@ -320,8 +320,8 @@ getval: } leaf = bmalloc(sizeof(struct text_leaf)); - leaf->lookup = bstrdup_n(name.array, name.len); - leaf->value = convert_string(value.array, value.len); + leaf->lookup = bstrdup_n(name.array, name.len); + leaf->value = convert_string(value.array, value.len); lookup_addstring(leaf->lookup, leaf, lookup->top); @@ -332,8 +332,8 @@ getval: lexer_free(&lex); } -static inline bool lookup_getstring(const char *lookup_val, - const char **out, struct text_node *node) +static inline bool lookup_getstring(const char *lookup_val, const char **out, + struct text_node *node) { struct text_node *child; char ch; @@ -409,7 +409,7 @@ void text_lookup_destroy(lookup_t *lookup) } bool text_lookup_getstr(lookup_t *lookup, const char *lookup_val, - const char **out) + const char **out) { if (lookup) return lookup_getstring(lookup_val, out, lookup->top); diff --git a/libobs/util/text-lookup.h b/libobs/util/text-lookup.h index 9531652..f011618 100644 --- a/libobs/util/text-lookup.h +++ b/libobs/util/text-lookup.h @@ -39,7 +39,7 @@ EXPORT lookup_t *text_lookup_create(const char *path); EXPORT bool text_lookup_add(lookup_t *lookup, const char *path); EXPORT void text_lookup_destroy(lookup_t *lookup); EXPORT bool text_lookup_getstr(lookup_t *lookup, const char *lookup_val, - const char **out); + const char **out); #ifdef __cplusplus } diff --git a/libobs/util/threading-posix.c b/libobs/util/threading-posix.c index d02e3d3..0752748 100644 --- a/libobs/util/threading-posix.c +++ b/libobs/util/threading-posix.c @@ -35,9 +35,9 @@ struct os_event_data { pthread_mutex_t mutex; - pthread_cond_t cond; - volatile bool signalled; - bool manual; + pthread_cond_t cond; + volatile bool signalled; + bool manual; }; int os_event_init(os_event_t **event, enum os_event_type type) @@ -89,11 +89,10 @@ int os_event_wait(os_event_t *event) return code; } -static inline void add_ms_to_ts(struct timespec *ts, - unsigned long milliseconds) +static inline void add_ms_to_ts(struct timespec *ts, unsigned long milliseconds) { - ts->tv_sec += milliseconds/1000; - ts->tv_nsec += (milliseconds%1000)*1000000; + ts->tv_sec += milliseconds / 1000; + ts->tv_nsec += (milliseconds % 1000) * 1000000; if (ts->tv_nsec > 1000000000) { ts->tv_sec += 1; ts->tv_nsec -= 1000000000; @@ -109,7 +108,7 @@ int os_event_timedwait(os_event_t *event, unsigned long milliseconds) #if defined(__APPLE__) || defined(__MINGW32__) struct timeval tv; gettimeofday(&tv, NULL); - ts.tv_sec = tv.tv_sec; + ts.tv_sec = tv.tv_sec; ts.tv_nsec = tv.tv_usec * 1000; #else clock_gettime(CLOCK_REALTIME, &ts); @@ -166,13 +165,13 @@ void os_event_reset(os_event_t *event) struct os_sem_data { semaphore_t sem; - task_t task; + task_t task; }; -int os_sem_init(os_sem_t **sem, int value) +int os_sem_init(os_sem_t **sem, int value) { semaphore_t new_sem; - task_t task = mach_task_self(); + task_t task = mach_task_self(); if (semaphore_create(task, &new_sem, 0, value) != KERN_SUCCESS) return -1; @@ -181,7 +180,7 @@ int os_sem_init(os_sem_t **sem, int value) if (!*sem) return -2; - (*sem)->sem = new_sem; + (*sem)->sem = new_sem; (*sem)->task = task; return 0; } @@ -194,15 +193,17 @@ void os_sem_destroy(os_sem_t *sem) } } -int os_sem_post(os_sem_t *sem) +int os_sem_post(os_sem_t *sem) { - if (!sem) return -1; + if (!sem) + return -1; return (semaphore_signal(sem->sem) == KERN_SUCCESS) ? 0 : -1; } -int os_sem_wait(os_sem_t *sem) +int os_sem_wait(os_sem_t *sem) { - if (!sem) return -1; + if (!sem) + return -1; return (semaphore_wait(sem->sem) == KERN_SUCCESS) ? 0 : -1; } @@ -212,7 +213,7 @@ struct os_sem_data { sem_t sem; }; -int os_sem_init(os_sem_t **sem, int value) +int os_sem_init(os_sem_t **sem, int value) { sem_t new_sem; int ret = sem_init(&new_sem, 0, value); @@ -232,15 +233,17 @@ void os_sem_destroy(os_sem_t *sem) } } -int os_sem_post(os_sem_t *sem) +int os_sem_post(os_sem_t *sem) { - if (!sem) return -1; + if (!sem) + return -1; return sem_post(&sem->sem); } -int os_sem_wait(os_sem_t *sem) +int os_sem_wait(os_sem_t *sem) { - if (!sem) return -1; + if (!sem) + return -1; return sem_wait(&sem->sem); } diff --git a/libobs/util/threading-posix.h b/libobs/util/threading-posix.h index 204a9dc..492cc84 100644 --- a/libobs/util/threading-posix.h +++ b/libobs/util/threading-posix.h @@ -36,8 +36,8 @@ static inline long os_atomic_load_long(const volatile long *ptr) return __atomic_load_n(ptr, __ATOMIC_SEQ_CST); } -static inline bool os_atomic_compare_swap_long(volatile long *val, - long old_val, long new_val) +static inline bool os_atomic_compare_swap_long(volatile long *val, long old_val, + long new_val) { return __sync_bool_compare_and_swap(val, old_val, new_val); } diff --git a/libobs/util/threading-windows.c b/libobs/util/threading-windows.c index 917067f..f4a9659 100644 --- a/libobs/util/threading-windows.c +++ b/libobs/util/threading-windows.c @@ -30,7 +30,7 @@ #define __try #endif #ifndef __except -#define __except(x) if (0) +#define __except (x) if (0) #endif #endif #endif @@ -43,7 +43,7 @@ int os_event_init(os_event_t **event, enum os_event_type type) if (!handle) return -1; - *event = (os_event_t*)handle; + *event = (os_event_t *)handle; return 0; } @@ -118,13 +118,13 @@ void os_event_reset(os_event_t *event) ResetEvent((HANDLE)event); } -int os_sem_init(os_sem_t **sem, int value) +int os_sem_init(os_sem_t **sem, int value) { HANDLE handle = CreateSemaphore(NULL, (LONG)value, 0x7FFFFFFF, NULL); if (!handle) return -1; - *sem = (os_sem_t*)handle; + *sem = (os_sem_t *)handle; return 0; } @@ -134,24 +134,26 @@ void os_sem_destroy(os_sem_t *sem) CloseHandle((HANDLE)sem); } -int os_sem_post(os_sem_t *sem) +int os_sem_post(os_sem_t *sem) { - if (!sem) return -1; + if (!sem) + return -1; return ReleaseSemaphore((HANDLE)sem, 1, NULL) ? 0 : -1; } -int os_sem_wait(os_sem_t *sem) +int os_sem_wait(os_sem_t *sem) { DWORD ret; - if (!sem) return -1; + if (!sem) + return -1; ret = WaitForSingleObject((HANDLE)sem, INFINITE); return (ret == WAIT_OBJECT_0) ? 0 : -1; } #define VC_EXCEPTION 0x406D1388 -#pragma pack(push,8) +#pragma pack(push, 8) struct vs_threadname_info { DWORD type; /* 0x1000 */ const char *name; @@ -175,16 +177,18 @@ void os_set_thread_name(const char *name) info.flags = 0; #ifdef NO_SEH_MINGW - __try1(EXCEPTION_EXECUTE_HANDLER) { + __try1(EXCEPTION_EXECUTE_HANDLER) + { #else __try { #endif RaiseException(VC_EXCEPTION, 0, THREADNAME_INFO_SIZE, - (ULONG_PTR*)&info); + (ULONG_PTR *)&info); #ifdef NO_SEH_MINGW - } __except1 { + } + __except1{ #else - } __except(EXCEPTION_EXECUTE_HANDLER) { + } __except (EXCEPTION_EXECUTE_HANDLER) { #endif } #endif diff --git a/libobs/util/threading-windows.h b/libobs/util/threading-windows.h index 6e382d8..73a2c9c 100644 --- a/libobs/util/threading-windows.h +++ b/libobs/util/threading-windows.h @@ -30,26 +30,26 @@ static inline long os_atomic_dec_long(volatile long *val) static inline long os_atomic_set_long(volatile long *ptr, long val) { - return (long)_InterlockedExchange((volatile long*)ptr, (long)val); + return (long)_InterlockedExchange((volatile long *)ptr, (long)val); } static inline long os_atomic_load_long(const volatile long *ptr) { - return (long)_InterlockedOr((volatile long*)ptr, 0); + return (long)_InterlockedOr((volatile long *)ptr, 0); } -static inline bool os_atomic_compare_swap_long(volatile long *val, - long old_val, long new_val) +static inline bool os_atomic_compare_swap_long(volatile long *val, long old_val, + long new_val) { return _InterlockedCompareExchange(val, new_val, old_val) == old_val; } static inline bool os_atomic_set_bool(volatile bool *ptr, bool val) { - return !!_InterlockedExchange8((volatile char*)ptr, (char)val); + return !!_InterlockedExchange8((volatile char *)ptr, (char)val); } static inline bool os_atomic_load_bool(const volatile bool *ptr) { - return !!_InterlockedOr8((volatile char*)ptr, 0); + return !!_InterlockedOr8((volatile char *)ptr, 0); } diff --git a/libobs/util/threading.h b/libobs/util/threading.h index 0ae27a2..e95bfe3 100644 --- a/libobs/util/threading.h +++ b/libobs/util/threading.h @@ -55,26 +55,26 @@ static inline void pthread_mutex_init_value(pthread_mutex_t *mutex) enum os_event_type { OS_EVENT_TYPE_AUTO, - OS_EVENT_TYPE_MANUAL + OS_EVENT_TYPE_MANUAL, }; struct os_event_data; struct os_sem_data; typedef struct os_event_data os_event_t; -typedef struct os_sem_data os_sem_t; +typedef struct os_sem_data os_sem_t; -EXPORT int os_event_init(os_event_t **event, enum os_event_type type); +EXPORT int os_event_init(os_event_t **event, enum os_event_type type); EXPORT void os_event_destroy(os_event_t *event); -EXPORT int os_event_wait(os_event_t *event); -EXPORT int os_event_timedwait(os_event_t *event, unsigned long milliseconds); -EXPORT int os_event_try(os_event_t *event); -EXPORT int os_event_signal(os_event_t *event); +EXPORT int os_event_wait(os_event_t *event); +EXPORT int os_event_timedwait(os_event_t *event, unsigned long milliseconds); +EXPORT int os_event_try(os_event_t *event); +EXPORT int os_event_signal(os_event_t *event); EXPORT void os_event_reset(os_event_t *event); -EXPORT int os_sem_init(os_sem_t **sem, int value); +EXPORT int os_sem_init(os_sem_t **sem, int value); EXPORT void os_sem_destroy(os_sem_t *sem); -EXPORT int os_sem_post(os_sem_t *sem); -EXPORT int os_sem_wait(os_sem_t *sem); +EXPORT int os_sem_post(os_sem_t *sem); +EXPORT int os_sem_wait(os_sem_t *sem); EXPORT void os_set_thread_name(const char *name); @@ -84,7 +84,6 @@ EXPORT void os_set_thread_name(const char *name); #define THREAD_LOCAL __thread #endif - #ifdef __cplusplus } #endif diff --git a/libobs/util/utf8.c b/libobs/util/utf8.c index 0c96de1..526f81c 100644 --- a/libobs/util/utf8.c +++ b/libobs/util/utf8.c @@ -24,12 +24,12 @@ static inline bool has_utf8_bom(const char *in_char) { - uint8_t *in = (uint8_t*)in_char; + uint8_t *in = (uint8_t *)in_char; return (in && in[0] == 0xef && in[1] == 0xbb && in[2] == 0xbf); } size_t utf8_to_wchar(const char *in, size_t insize, wchar_t *out, - size_t outsize, int flags) + size_t outsize, int flags) { int i_insize = (int)insize; int ret; @@ -52,7 +52,7 @@ size_t utf8_to_wchar(const char *in, size_t insize, wchar_t *out, } size_t wchar_to_utf8(const wchar_t *in, size_t insize, char *out, - size_t outsize, int flags) + size_t outsize, int flags) { int i_insize = (int)insize; int ret; @@ -61,7 +61,7 @@ size_t wchar_to_utf8(const wchar_t *in, size_t insize, char *out, i_insize = (int)wcslen(in); ret = WideCharToMultiByte(CP_UTF8, 0, in, i_insize, out, (int)outsize, - NULL, NULL); + NULL, NULL); UNUSED_PARAMETER(flags); return (ret > 0) ? (size_t)ret : 0; @@ -69,14 +69,14 @@ size_t wchar_to_utf8(const wchar_t *in, size_t insize, char *out, #else -#define _NXT 0x80 -#define _SEQ2 0xc0 -#define _SEQ3 0xe0 -#define _SEQ4 0xf0 -#define _SEQ5 0xf8 -#define _SEQ6 0xfc +#define _NXT 0x80 +#define _SEQ2 0xc0 +#define _SEQ3 0xe0 +#define _SEQ4 0xf0 +#define _SEQ5 0xf8 +#define _SEQ6 0xfc -#define _BOM 0xfeff +#define _BOM 0xfeff static int wchar_forbidden(wchar_t sym); static int utf8_forbidden(unsigned char octet); @@ -131,7 +131,7 @@ static int utf8_forbidden(unsigned char octet) * function. */ size_t utf8_to_wchar(const char *in, size_t insize, wchar_t *out, - size_t outsize, int flags) + size_t outsize, int flags) { unsigned char *p, *lim; wchar_t *wlim, high; @@ -142,21 +142,20 @@ size_t utf8_to_wchar(const char *in, size_t insize, wchar_t *out, total = 0; p = (unsigned char *)in; - lim = (insize != 0) ? (p + insize) : (unsigned char*)-1; + lim = (insize != 0) ? (p + insize) : (unsigned char *)-1; wlim = out + outsize; for (; p < lim; p += n) { if (!*p) break; - if (utf8_forbidden(*p) != 0 && - (flags & UTF8_IGNORE_ERROR) == 0) + if (utf8_forbidden(*p) != 0 && (flags & UTF8_IGNORE_ERROR) == 0) return 0; /* * Get number of bytes for one wide character. */ - n = 1; /* default: 1 byte. Used when skipping bytes. */ + n = 1; /* default: 1 byte. Used when skipping bytes. */ if ((*p & 0x80) == 0) high = (wchar_t)*p; else if ((*p & 0xe0) == _SEQ2) { @@ -185,7 +184,7 @@ size_t utf8_to_wchar(const char *in, size_t insize, wchar_t *out, if ((flags & UTF8_IGNORE_ERROR) == 0) return 0; n = 1; - continue; /* skip */ + continue; /* skip */ } /* @@ -201,7 +200,7 @@ size_t utf8_to_wchar(const char *in, size_t insize, wchar_t *out, if ((flags & UTF8_IGNORE_ERROR) == 0) return 0; n = 1; - continue; /* skip */ + continue; /* skip */ } } @@ -211,19 +210,19 @@ size_t utf8_to_wchar(const char *in, size_t insize, wchar_t *out, continue; if (out >= wlim) - return 0; /* no space left */ + return 0; /* no space left */ *out = 0; n_bits = 0; for (i = 1; i < n; i++) { *out |= (wchar_t)(p[n - i] & 0x3f) << n_bits; - n_bits += 6; /* 6 low bits in every byte */ + n_bits += 6; /* 6 low bits in every byte */ } *out |= high << n_bits; if (wchar_forbidden(*out) != 0) { if ((flags & UTF8_IGNORE_ERROR) == 0) - return 0; /* forbidden character */ + return 0; /* forbidden character */ else { total--; out--; @@ -261,7 +260,7 @@ size_t utf8_to_wchar(const char *in, size_t insize, wchar_t *out, * as regular symbols. */ size_t wchar_to_utf8(const wchar_t *in, size_t insize, char *out, - size_t outsize, int flags) + size_t outsize, int flags) { wchar_t *w, *wlim, ch = 0; unsigned char *p, *lim, *oc; @@ -271,7 +270,7 @@ size_t wchar_to_utf8(const wchar_t *in, size_t insize, char *out, return 0; w = (wchar_t *)in; - wlim = (insize != 0) ? (w + insize) : (wchar_t*)-1; + wlim = (insize != 0) ? (w + insize) : (wchar_t *)-1; p = (unsigned char *)out; lim = p + outsize; total = 0; @@ -313,7 +312,7 @@ size_t wchar_to_utf8(const wchar_t *in, size_t insize, char *out, continue; if ((size_t)(lim - p) <= n - 1) - return 0; /* no space left */ + return 0; /* no space left */ ch = *w; oc = (unsigned char *)&ch; @@ -337,7 +336,7 @@ size_t wchar_to_utf8(const wchar_t *in, size_t insize, char *out, p[3] = _NXT | (oc[0] & 0x3f); p[2] = _NXT | (oc[0] >> 6) | ((oc[1] & 0x0f) << 2); p[1] = _NXT | ((oc[1] & 0xf0) >> 4) | - ((oc[2] & 0x03) << 4); + ((oc[2] & 0x03) << 4); p[0] = _SEQ4 | ((oc[2] & 0x1f) >> 2); break; @@ -345,7 +344,7 @@ size_t wchar_to_utf8(const wchar_t *in, size_t insize, char *out, p[4] = _NXT | (oc[0] & 0x3f); p[3] = _NXT | (oc[0] >> 6) | ((oc[1] & 0x0f) << 2); p[2] = _NXT | ((oc[1] & 0xf0) >> 4) | - ((oc[2] & 0x03) << 4); + ((oc[2] & 0x03) << 4); p[1] = _NXT | (oc[2] >> 2); p[0] = _SEQ5 | (oc[3] & 0x03); break; diff --git a/libobs/util/utf8.h b/libobs/util/utf8.h index 63227ce..74c9695 100644 --- a/libobs/util/utf8.h +++ b/libobs/util/utf8.h @@ -25,12 +25,12 @@ extern "C" { #endif #define UTF8_IGNORE_ERROR 0x01 -#define UTF8_SKIP_BOM 0x02 +#define UTF8_SKIP_BOM 0x02 size_t utf8_to_wchar(const char *in, size_t insize, wchar_t *out, - size_t outsize, int flags); + size_t outsize, int flags); size_t wchar_to_utf8(const wchar_t *in, size_t insize, char *out, - size_t outsize, int flags); + size_t outsize, int flags); #ifdef __cplusplus } diff --git a/libobs/util/util.hpp b/libobs/util/util.hpp index 94c5823..1307c9f 100644 --- a/libobs/util/util.hpp +++ b/libobs/util/util.hpp @@ -30,31 +30,41 @@ template class BPtr { T *ptr; - BPtr(BPtr const&) = delete; + BPtr(BPtr const &) = delete; - BPtr &operator=(BPtr const&) = delete; + BPtr &operator=(BPtr const &) = delete; public: - inline BPtr(T *p=nullptr) : ptr(p) {} - inline BPtr(BPtr &&other) : ptr(other.ptr) {other.ptr = nullptr;} - inline ~BPtr() {bfree(ptr);} + inline BPtr(T *p = nullptr) : ptr(p) {} + inline BPtr(BPtr &&other) : ptr(other.ptr) { other.ptr = nullptr; } + inline ~BPtr() { bfree(ptr); } - inline T *operator=(T *p) {bfree(ptr); ptr = p; return p;} - inline operator T*() {return ptr;} - inline T **operator&() {bfree(ptr); ptr = nullptr; return &ptr;} + inline T *operator=(T *p) + { + bfree(ptr); + ptr = p; + return p; + } + inline operator T *() { return ptr; } + inline T **operator&() + { + bfree(ptr); + ptr = nullptr; + return &ptr; + } - inline bool operator!() {return ptr == NULL;} - inline bool operator==(T p) {return ptr == p;} - inline bool operator!=(T p) {return ptr != p;} + inline bool operator!() { return ptr == NULL; } + inline bool operator==(T p) { return ptr == p; } + inline bool operator!=(T p) { return ptr != p; } - inline T *Get() const {return ptr;} + inline T *Get() const { return ptr; } }; class ConfigFile { config_t *config; - ConfigFile(ConfigFile const&) = delete; - ConfigFile &operator=(ConfigFile const&) = delete; + ConfigFile(ConfigFile const &) = delete; + ConfigFile &operator=(ConfigFile const &) = delete; public: inline ConfigFile() : config(NULL) {} @@ -62,10 +72,7 @@ public: { other.config = nullptr; } - inline ~ConfigFile() - { - config_close(config); - } + inline ~ConfigFile() { config_close(config); } inline bool Create(const char *file) { @@ -87,13 +94,10 @@ public: return config_open(&config, file, openType); } - inline int Save() - { - return config_save(config); - } + inline int Save() { return config_save(config); } inline int SaveSafe(const char *temp_ext, - const char *backup_ext = nullptr) + const char *backup_ext = nullptr) { return config_save_safe(config, temp_ext, backup_ext); } @@ -104,32 +108,32 @@ public: config = NULL; } - inline operator config_t*() const {return config;} + inline operator config_t *() const { return config; } }; class TextLookup { lookup_t *lookup; - TextLookup(TextLookup const&) = delete; + TextLookup(TextLookup const &) = delete; - TextLookup &operator=(TextLookup const&) = delete; + TextLookup &operator=(TextLookup const &) = delete; public: - inline TextLookup(lookup_t *lookup=nullptr) : lookup(lookup) {} + inline TextLookup(lookup_t *lookup = nullptr) : lookup(lookup) {} inline TextLookup(TextLookup &&other) : lookup(other.lookup) { other.lookup = nullptr; } - inline ~TextLookup() {text_lookup_destroy(lookup);} + inline ~TextLookup() { text_lookup_destroy(lookup); } - inline TextLookup& operator=(lookup_t *val) + inline TextLookup &operator=(lookup_t *val) { text_lookup_destroy(lookup); lookup = val; return *this; } - inline operator lookup_t*() const {return lookup;} + inline operator lookup_t *() const { return lookup; } inline const char *GetString(const char *lookupVal) const { diff --git a/libobs/util/vc/vc_inttypes.h b/libobs/util/vc/vc_inttypes.h index b2e3fc6..7679e62 100644 --- a/libobs/util/vc/vc_inttypes.h +++ b/libobs/util/vc/vc_inttypes.h @@ -45,201 +45,202 @@ // 7.8 Format conversion of integer types typedef struct { - intmax_t quot; - intmax_t rem; + intmax_t quot; + intmax_t rem; } imaxdiv_t; // 7.8.1 Macros for format specifiers -#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 +#if !defined(__cplusplus) || \ + defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 // The fprintf macros for signed integers are: -#define PRId8 "d" -#define PRIi8 "i" -#define PRIdLEAST8 "d" -#define PRIiLEAST8 "i" -#define PRIdFAST8 "d" -#define PRIiFAST8 "i" +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" -#define PRId16 "hd" -#define PRIi16 "hi" -#define PRIdLEAST16 "hd" -#define PRIiLEAST16 "hi" -#define PRIdFAST16 "hd" -#define PRIiFAST16 "hi" +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" -#define PRId32 "I32d" -#define PRIi32 "I32i" -#define PRIdLEAST32 "I32d" -#define PRIiLEAST32 "I32i" -#define PRIdFAST32 "I32d" -#define PRIiFAST32 "I32i" +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" -#define PRId64 "I64d" -#define PRIi64 "I64i" -#define PRIdLEAST64 "I64d" -#define PRIiLEAST64 "I64i" -#define PRIdFAST64 "I64d" -#define PRIiFAST64 "I64i" +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" -#define PRIdMAX "I64d" -#define PRIiMAX "I64i" +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" -#define PRIdPTR "Id" -#define PRIiPTR "Ii" +#define PRIdPTR "Id" +#define PRIiPTR "Ii" // The fprintf macros for unsigned integers are: -#define PRIo8 "o" -#define PRIu8 "u" -#define PRIx8 "x" -#define PRIX8 "X" -#define PRIoLEAST8 "o" -#define PRIuLEAST8 "u" -#define PRIxLEAST8 "x" -#define PRIXLEAST8 "X" -#define PRIoFAST8 "o" -#define PRIuFAST8 "u" -#define PRIxFAST8 "x" -#define PRIXFAST8 "X" +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" -#define PRIo16 "ho" -#define PRIu16 "hu" -#define PRIx16 "hx" -#define PRIX16 "hX" -#define PRIoLEAST16 "ho" -#define PRIuLEAST16 "hu" -#define PRIxLEAST16 "hx" -#define PRIXLEAST16 "hX" -#define PRIoFAST16 "ho" -#define PRIuFAST16 "hu" -#define PRIxFAST16 "hx" -#define PRIXFAST16 "hX" +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" -#define PRIo32 "I32o" -#define PRIu32 "I32u" -#define PRIx32 "I32x" -#define PRIX32 "I32X" -#define PRIoLEAST32 "I32o" -#define PRIuLEAST32 "I32u" -#define PRIxLEAST32 "I32x" -#define PRIXLEAST32 "I32X" -#define PRIoFAST32 "I32o" -#define PRIuFAST32 "I32u" -#define PRIxFAST32 "I32x" -#define PRIXFAST32 "I32X" +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" -#define PRIo64 "I64o" -#define PRIu64 "I64u" -#define PRIx64 "I64x" -#define PRIX64 "I64X" -#define PRIoLEAST64 "I64o" -#define PRIuLEAST64 "I64u" -#define PRIxLEAST64 "I64x" -#define PRIXLEAST64 "I64X" -#define PRIoFAST64 "I64o" -#define PRIuFAST64 "I64u" -#define PRIxFAST64 "I64x" -#define PRIXFAST64 "I64X" +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" -#define PRIoMAX "I64o" -#define PRIuMAX "I64u" -#define PRIxMAX "I64x" -#define PRIXMAX "I64X" +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" -#define PRIoPTR "Io" -#define PRIuPTR "Iu" -#define PRIxPTR "Ix" -#define PRIXPTR "IX" +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" // The fscanf macros for signed integers are: -#define SCNd16 "hd" -#define SCNi16 "hi" -#define SCNdLEAST16 "hd" -#define SCNiLEAST16 "hi" -#define SCNdFAST16 "hd" -#define SCNiFAST16 "hi" +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" -#define SCNd32 "ld" -#define SCNi32 "li" -#define SCNdLEAST32 "ld" -#define SCNiLEAST32 "li" -#define SCNdFAST32 "ld" -#define SCNiFAST32 "li" +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" -#define SCNd64 "I64d" -#define SCNi64 "I64i" -#define SCNdLEAST64 "I64d" -#define SCNiLEAST64 "I64i" -#define SCNdFAST64 "I64d" -#define SCNiFAST64 "I64i" +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" -#define SCNdMAX "I64d" -#define SCNiMAX "I64i" +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" #ifdef _WIN64 // [ -# define SCNdPTR "I64d" -# define SCNiPTR "I64i" -#else // _WIN64 ][ -# define SCNdPTR "ld" -# define SCNiPTR "li" -#endif // _WIN64 ] +#define SCNdPTR "I64d" +#define SCNiPTR "I64i" +#else // _WIN64 ][ +#define SCNdPTR "ld" +#define SCNiPTR "li" +#endif // _WIN64 ] // The fscanf macros for unsigned integers are: -#define SCNo16 "ho" -#define SCNu16 "hu" -#define SCNx16 "hx" -#define SCNX16 "hX" -#define SCNoLEAST16 "ho" -#define SCNuLEAST16 "hu" -#define SCNxLEAST16 "hx" -#define SCNXLEAST16 "hX" -#define SCNoFAST16 "ho" -#define SCNuFAST16 "hu" -#define SCNxFAST16 "hx" -#define SCNXFAST16 "hX" +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" -#define SCNo32 "lo" -#define SCNu32 "lu" -#define SCNx32 "lx" -#define SCNX32 "lX" -#define SCNoLEAST32 "lo" -#define SCNuLEAST32 "lu" -#define SCNxLEAST32 "lx" -#define SCNXLEAST32 "lX" -#define SCNoFAST32 "lo" -#define SCNuFAST32 "lu" -#define SCNxFAST32 "lx" -#define SCNXFAST32 "lX" +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" -#define SCNo64 "I64o" -#define SCNu64 "I64u" -#define SCNx64 "I64x" -#define SCNX64 "I64X" -#define SCNoLEAST64 "I64o" -#define SCNuLEAST64 "I64u" -#define SCNxLEAST64 "I64x" -#define SCNXLEAST64 "I64X" -#define SCNoFAST64 "I64o" -#define SCNuFAST64 "I64u" -#define SCNxFAST64 "I64x" -#define SCNXFAST64 "I64X" +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" -#define SCNoMAX "I64o" -#define SCNuMAX "I64u" -#define SCNxMAX "I64x" -#define SCNXMAX "I64X" +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" #ifdef _WIN64 // [ -# define SCNoPTR "I64o" -# define SCNuPTR "I64u" -# define SCNxPTR "I64x" -# define SCNXPTR "I64X" -#else // _WIN64 ][ -# define SCNoPTR "lo" -# define SCNuPTR "lu" -# define SCNxPTR "lx" -# define SCNXPTR "lX" -#endif // _WIN64 ] +#define SCNoPTR "I64o" +#define SCNuPTR "I64u" +#define SCNxPTR "I64x" +#define SCNXPTR "I64X" +#else // _WIN64 ][ +#define SCNoPTR "lo" +#define SCNuPTR "lu" +#define SCNxPTR "lx" +#define SCNXPTR "lX" +#endif // _WIN64 ] #endif // __STDC_FORMAT_MACROS ] @@ -254,23 +255,23 @@ typedef struct { // in %MSVC.NET%\crt\src\div.c #ifdef STATIC_IMAXDIV // [ static -#else // STATIC_IMAXDIV ][ +#else // STATIC_IMAXDIV ][ _inline #endif // STATIC_IMAXDIV ] -imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) + imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) { - imaxdiv_t result; + imaxdiv_t result; - result.quot = numer / denom; - result.rem = numer % denom; + result.quot = numer / denom; + result.rem = numer % denom; - if (numer < 0 && result.rem > 0) { - // did division wrong; must fix up - ++result.quot; - result.rem -= denom; - } + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } - return result; + return result; } // 7.8.2.3 The strtoimax and strtoumax functions @@ -281,5 +282,4 @@ imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) #define wcstoimax _wcstoi64 #define wcstoumax _wcstoui64 - #endif // _MSC_INTTYPES_H_ ] diff --git a/libobs/util/vc/vc_stdbool.h b/libobs/util/vc/vc_stdbool.h index 031dd40..ad78bbc 100644 --- a/libobs/util/vc/vc_stdbool.h +++ b/libobs/util/vc/vc_stdbool.h @@ -1,7 +1,7 @@ #pragma once #if !defined(__cplusplus) -typedef int8_t _Bool; +typedef int8_t _Bool; #define bool _Bool #define true 1 #define false 0 diff --git a/libobs/util/vc/vc_stdint.h b/libobs/util/vc/vc_stdint.h index 3ae4832..f941d6e 100644 --- a/libobs/util/vc/vc_stdint.h +++ b/libobs/util/vc/vc_stdint.h @@ -24,23 +24,23 @@ /* 7.18.1.1 Exact-width integer types */ typedef signed char int8_t; -typedef unsigned char uint8_t; -typedef short int16_t; -typedef unsigned short uint16_t; -typedef int int32_t; -typedef unsigned uint32_t; -typedef __int64 int64_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned uint32_t; +typedef __int64 int64_t; typedef unsigned __int64 uint64_t; /* 7.18.1.2 Minimum-width integer types */ typedef signed char int_least8_t; -typedef unsigned char uint_least8_t; -typedef short int_least16_t; -typedef unsigned short uint_least16_t; -typedef int int_least32_t; -typedef unsigned uint_least32_t; -typedef __int64 int_least64_t; -typedef unsigned __int64 uint_least64_t; +typedef unsigned char uint_least8_t; +typedef short int_least16_t; +typedef unsigned short uint_least16_t; +typedef int int_least32_t; +typedef unsigned uint_least32_t; +typedef __int64 int_least64_t; +typedef unsigned __int64 uint_least64_t; /* 7.18.1.3 Fastest minimum-width integer types * Not actually guaranteed to be fastest for all purposes @@ -48,38 +48,38 @@ typedef unsigned __int64 uint_least64_t; */ typedef char int_fast8_t; typedef unsigned char uint_fast8_t; -typedef short int_fast16_t; -typedef unsigned short uint_fast16_t; -typedef int int_fast32_t; -typedef unsigned int uint_fast32_t; -typedef __int64 int_fast64_t; -typedef unsigned __int64 uint_fast64_t; +typedef short int_fast16_t; +typedef unsigned short uint_fast16_t; +typedef int int_fast32_t; +typedef unsigned int uint_fast32_t; +typedef __int64 int_fast64_t; +typedef unsigned __int64 uint_fast64_t; /* 7.18.1.4 Integer types capable of holding object pointers */ /*typedef int intptr_t; typedef unsigned uintptr_t;*/ /* 7.18.1.5 Greatest-width integer types */ -typedef __int64 intmax_t; -typedef unsigned __int64 uintmax_t; +typedef __int64 intmax_t; +typedef unsigned __int64 uintmax_t; /* 7.18.2 Limits of specified-width integer types */ -#if !defined ( __cplusplus) || defined (__STDC_LIMIT_MACROS) +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) /* 7.18.2.1 Limits of exact-width integer types */ #define INT8_MIN (-128) #define INT16_MIN (-32768) #define INT32_MIN (-2147483647 - 1) -#define INT64_MIN (-9223372036854775807LL - 1) +#define INT64_MIN (-9223372036854775807LL - 1) #define INT8_MAX 127 #define INT16_MAX 32767 #define INT32_MAX 2147483647 #define INT64_MAX 9223372036854775807LL -#define UINT8_MAX 0xff /* 255U */ -#define UINT16_MAX 0xffff /* 65535U */ -#define UINT32_MAX 0xffffffff /* 4294967295U */ +#define UINT8_MAX 0xff /* 255U */ +#define UINT16_MAX 0xffff /* 65535U */ +#define UINT32_MAX 0xffffffff /* 4294967295U */ #define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */ /* 7.18.2.2 Limits of minimum-width integer types */ @@ -152,7 +152,7 @@ typedef unsigned __int64 uintmax_t; #endif #if 0 -#ifndef WCHAR_MIN /* also in wchar.h */ +#ifndef WCHAR_MIN /* also in wchar.h */ #define WCHAR_MIN 0 #define WCHAR_MAX ((wchar_t)-1) /* UINT16_MAX */ #endif @@ -166,9 +166,8 @@ typedef unsigned __int64 uintmax_t; #endif /* !defined ( __cplusplus) || defined __STDC_LIMIT_MACROS */ - /* 7.18.4 Macros for integer constants */ -#if !defined ( __cplusplus) || defined (__STDC_CONSTANT_MACROS) +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) /* 7.18.4.1 Macros for minimum-width integer constants @@ -185,20 +184,20 @@ typedef unsigned __int64 uintmax_t; The trick used here is from Clive D W Feather. */ -#define INT8_C(val) (INT_LEAST8_MAX-INT_LEAST8_MAX+(val)) -#define INT16_C(val) (INT_LEAST16_MAX-INT_LEAST16_MAX+(val)) -#define INT32_C(val) (INT_LEAST32_MAX-INT_LEAST32_MAX+(val)) -#define INT64_C(val) (INT_LEAST64_MAX-INT_LEAST64_MAX+(val)) +#define INT8_C(val) (INT_LEAST8_MAX - INT_LEAST8_MAX + (val)) +#define INT16_C(val) (INT_LEAST16_MAX - INT_LEAST16_MAX + (val)) +#define INT32_C(val) (INT_LEAST32_MAX - INT_LEAST32_MAX + (val)) +#define INT64_C(val) (INT_LEAST64_MAX - INT_LEAST64_MAX + (val)) -#define UINT8_C(val) (UINT_LEAST8_MAX-UINT_LEAST8_MAX+(val)) -#define UINT16_C(val) (UINT_LEAST16_MAX-UINT_LEAST16_MAX+(val)) -#define UINT32_C(val) (UINT_LEAST32_MAX-UINT_LEAST32_MAX+(val)) -#define UINT64_C(val) (UINT_LEAST64_MAX-UINT_LEAST64_MAX+(val)) +#define UINT8_C(val) (UINT_LEAST8_MAX - UINT_LEAST8_MAX + (val)) +#define UINT16_C(val) (UINT_LEAST16_MAX - UINT_LEAST16_MAX + (val)) +#define UINT32_C(val) (UINT_LEAST32_MAX - UINT_LEAST32_MAX + (val)) +#define UINT64_C(val) (UINT_LEAST64_MAX - UINT_LEAST64_MAX + (val)) /* 7.18.4.2 Macros for greatest-width integer constants */ -#define INTMAX_C(val) (INTMAX_MAX-INTMAX_MAX+(val)) -#define UINTMAX_C(val) (UINTMAX_MAX-UINTMAX_MAX+(val)) +#define INTMAX_C(val) (INTMAX_MAX - INTMAX_MAX + (val)) +#define UINTMAX_C(val) (UINTMAX_MAX - UINTMAX_MAX + (val)) -#endif /* !defined ( __cplusplus) || defined __STDC_CONSTANT_MACROS */ +#endif /* !defined ( __cplusplus) || defined __STDC_CONSTANT_MACROS */ #endif diff --git a/libobs/util/windows/CoTaskMemPtr.hpp b/libobs/util/windows/CoTaskMemPtr.hpp index ff607de..84368e4 100644 --- a/libobs/util/windows/CoTaskMemPtr.hpp +++ b/libobs/util/windows/CoTaskMemPtr.hpp @@ -19,25 +19,29 @@ template class CoTaskMemPtr { T *ptr; - inline void Clear() {if (ptr) CoTaskMemFree(ptr);} + inline void Clear() + { + if (ptr) + CoTaskMemFree(ptr); + } public: - inline CoTaskMemPtr() : ptr(NULL) {} + inline CoTaskMemPtr() : ptr(NULL) {} inline CoTaskMemPtr(T *ptr_) : ptr(ptr_) {} - inline ~CoTaskMemPtr() {Clear();} + inline ~CoTaskMemPtr() { Clear(); } - inline operator T*() const {return ptr;} - inline T *operator->() const {return ptr;} + inline operator T *() const { return ptr; } + inline T *operator->() const { return ptr; } - inline const T *Get() const {return ptr;} + inline const T *Get() const { return ptr; } - inline CoTaskMemPtr& operator=(T* val) + inline CoTaskMemPtr &operator=(T *val) { Clear(); ptr = val; } - inline T** operator&() + inline T **operator&() { Clear(); ptr = NULL; diff --git a/libobs/util/windows/ComPtr.hpp b/libobs/util/windows/ComPtr.hpp index 2415240..6d83d2d 100644 --- a/libobs/util/windows/ComPtr.hpp +++ b/libobs/util/windows/ComPtr.hpp @@ -33,18 +33,28 @@ protected: inline void Replace(T *p) { if (ptr != p) { - if (p) p->AddRef(); - if (ptr) ptr->Release(); + if (p) + p->AddRef(); + if (ptr) + ptr->Release(); ptr = p; } } public: - inline ComPtr() : ptr(nullptr) {} - inline ComPtr(T *p) : ptr(p) {if (ptr) ptr->AddRef();} - inline ComPtr(const ComPtr &c) : ptr(c.ptr) {if (ptr) ptr->AddRef();} - inline ComPtr(ComPtr &&c) : ptr(c.ptr) {c.ptr = nullptr;} - inline ~ComPtr() {Kill();} + inline ComPtr() : ptr(nullptr) {} + inline ComPtr(T *p) : ptr(p) + { + if (ptr) + ptr->AddRef(); + } + inline ComPtr(const ComPtr &c) : ptr(c.ptr) + { + if (ptr) + ptr->AddRef(); + } + inline ComPtr(ComPtr &&c) : ptr(c.ptr) { c.ptr = nullptr; } + inline ~ComPtr() { Kill(); } inline void Clear() { @@ -87,7 +97,8 @@ public: inline void CopyTo(T **out) { if (out) { - if (ptr) ptr->AddRef(); + if (ptr) + ptr->AddRef(); *out = ptr; } } @@ -96,26 +107,35 @@ public: { ULONG ref; - if (!ptr) return 0; + if (!ptr) + return 0; ref = ptr->Release(); ptr = nullptr; return ref; } - inline T **Assign() {Clear(); return &ptr;} - inline void Set(T *p) {Kill(); ptr = p;} + inline T **Assign() + { + Clear(); + return &ptr; + } + inline void Set(T *p) + { + Kill(); + ptr = p; + } - inline T *Get() const {return ptr;} + inline T *Get() const { return ptr; } - inline T **operator&() {return Assign();} + inline T **operator&() { return Assign(); } - inline operator T*() const {return ptr;} - inline T *operator->() const {return ptr;} + inline operator T *() const { return ptr; } + inline T *operator->() const { return ptr; } - inline bool operator==(T *p) const {return ptr == p;} - inline bool operator!=(T *p) const {return ptr != p;} + inline bool operator==(T *p) const { return ptr == p; } + inline bool operator!=(T *p) const { return ptr != p; } - inline bool operator!() const {return !ptr;} + inline bool operator!() const { return !ptr; } }; #ifdef _WIN32 @@ -126,13 +146,13 @@ public: inline ComQIPtr(IUnknown *unk) { this->ptr = nullptr; - unk->QueryInterface(__uuidof(T), (void**)&this->ptr); + unk->QueryInterface(__uuidof(T), (void **)&this->ptr); } inline ComPtr &operator=(IUnknown *unk) { ComPtr::Clear(); - unk->QueryInterface(__uuidof(T), (void**)&this->ptr); + unk->QueryInterface(__uuidof(T), (void **)&this->ptr); return *this; } }; diff --git a/libobs/util/windows/HRError.hpp b/libobs/util/windows/HRError.hpp index c5b673f..444499d 100644 --- a/libobs/util/windows/HRError.hpp +++ b/libobs/util/windows/HRError.hpp @@ -20,8 +20,5 @@ struct HRError { const char *str; HRESULT hr; - inline HRError(const char *str, HRESULT hr) - : str(str), hr (hr) - { - } + inline HRError(const char *str, HRESULT hr) : str(str), hr(hr) {} }; diff --git a/libobs/util/windows/WinHandle.hpp b/libobs/util/windows/WinHandle.hpp index 4ae3812..66f49c6 100644 --- a/libobs/util/windows/WinHandle.hpp +++ b/libobs/util/windows/WinHandle.hpp @@ -26,13 +26,13 @@ class WinHandle { } public: - inline WinHandle() {} + inline WinHandle() {} inline WinHandle(HANDLE handle_) : handle(handle_) {} - inline ~WinHandle() {Clear();} + inline ~WinHandle() { Clear(); } - inline operator HANDLE() const {return handle;} + inline operator HANDLE() const { return handle; } - inline WinHandle& operator=(HANDLE handle_) + inline WinHandle &operator=(HANDLE handle_) { if (handle_ != handle) { Clear(); @@ -42,10 +42,7 @@ public: return *this; } - inline HANDLE* operator&() - { - return &handle; - } + inline HANDLE *operator&() { return &handle; } inline bool Valid() const { diff --git a/libobs/util/windows/win-registry.h b/libobs/util/windows/win-registry.h index 9e63a58..7248ec9 100644 --- a/libobs/util/windows/win-registry.h +++ b/libobs/util/windows/win-registry.h @@ -26,12 +26,12 @@ extern "C" { struct reg_dword { LSTATUS status; - DWORD size; - DWORD return_value; + DWORD size; + DWORD return_value; }; EXPORT void get_reg_dword(HKEY hkey, LPCWSTR sub_key, LPCWSTR value_name, - struct reg_dword *info); + struct reg_dword *info); #ifdef __cplusplus } diff --git a/plugins/coreaudio-encoder/data/locale/de-DE.ini b/plugins/coreaudio-encoder/data/locale/de-DE.ini index 0e6245d..20d99af 100644 --- a/plugins/coreaudio-encoder/data/locale/de-DE.ini +++ b/plugins/coreaudio-encoder/data/locale/de-DE.ini @@ -1,6 +1,6 @@ CoreAudioAAC="CoreAudio AAC Kodierer" Bitrate="Bitrate" -AllowHEAAC="Erlaube HE-AAC" +AllowHEAAC="Erlaube HE‐AAC" OutputSamplerate="Ausgabeabtastrate" UseInputSampleRate="Verwenden Sie Eingabe (OBS) Abtastrate (kann nicht unterstützte Bitraten auflisten)" diff --git a/plugins/coreaudio-encoder/data/locale/gl-ES.ini b/plugins/coreaudio-encoder/data/locale/gl-ES.ini index bac555a..4b19419 100644 --- a/plugins/coreaudio-encoder/data/locale/gl-ES.ini +++ b/plugins/coreaudio-encoder/data/locale/gl-ES.ini @@ -1,4 +1,6 @@ -CoreAudioAAC="Codificador CoreAudio AAC" -Bitrate="Velocidade de bits" +CoreAudioAAC="Codificador AAC de CoreAudio" +Bitrate="Taxa de bits" AllowHEAAC="Permitir HE-AAC" +OutputSamplerate="Taxa de mostra de saída" +UseInputSampleRate="Utilizar a taxa de mostra de entrada do OBS (pode listar as taxas de bits que non son compatíbeis)" diff --git a/plugins/coreaudio-encoder/data/locale/sl-SI.ini b/plugins/coreaudio-encoder/data/locale/sl-SI.ini new file mode 100644 index 0000000..0f2a252 --- /dev/null +++ b/plugins/coreaudio-encoder/data/locale/sl-SI.ini @@ -0,0 +1,6 @@ +CoreAudioAAC="Kodirnik AAC CoreAudio" +Bitrate="Bitna hitrost" +AllowHEAAC="Omogoči HE-AAC" +OutputSamplerate="Izhodna hitrost vzorčenja" +UseInputSampleRate="Uporabo vhodno hitrost vzorčenja (OBS) (lahko so prikazane nepodprte bitne hitrosti)" + diff --git a/plugins/coreaudio-encoder/encoder.cpp b/plugins/coreaudio-encoder/encoder.cpp index 0affe6e..34fbd64 100644 --- a/plugins/coreaudio-encoder/encoder.cpp +++ b/plugins/coreaudio-encoder/encoder.cpp @@ -15,19 +15,18 @@ #define CA_LOG(level, format, ...) \ blog(level, "[CoreAudio encoder]: " format, ##__VA_ARGS__) -#define CA_LOG_ENCODER(format_name, encoder, level, format, ...) \ - blog(level, "[CoreAudio %s: '%s']: " format, \ - format_name, obs_encoder_get_name(encoder), \ - ##__VA_ARGS__) -#define CA_BLOG(level, format, ...) \ +#define CA_LOG_ENCODER(format_name, encoder, level, format, ...) \ + blog(level, "[CoreAudio %s: '%s']: " format, format_name, \ + obs_encoder_get_name(encoder), ##__VA_ARGS__) +#define CA_BLOG(level, format, ...) \ CA_LOG_ENCODER(ca->format_name, ca->encoder, level, format, \ - ##__VA_ARGS__) -#define CA_CO_LOG(level, format, ...) \ - do { \ - if (ca) \ + ##__VA_ARGS__) +#define CA_CO_LOG(level, format, ...) \ + do { \ + if (ca) \ CA_BLOG(level, format, ##__VA_ARGS__); \ - else \ - CA_LOG(level, format, ##__VA_ARGS__); \ + else \ + CA_LOG(level, format, ##__VA_ARGS__); \ } while (false) #ifdef _WIN32 @@ -91,32 +90,32 @@ struct asbd_builder { }; struct ca_encoder { - obs_encoder_t *encoder = nullptr; - const char *format_name = nullptr; - UInt32 format_id = 0; + obs_encoder_t *encoder = nullptr; + const char *format_name = nullptr; + UInt32 format_id = 0; const initializer_list *allowed_formats = nullptr; AudioConverterRef converter = nullptr; - size_t output_buffer_size = 0; - vector output_buffer; + size_t output_buffer_size = 0; + vector output_buffer; - size_t out_frames_per_packet = 0; + size_t out_frames_per_packet = 0; - size_t in_packets = 0; - size_t in_frame_size = 0; - size_t in_bytes_required = 0; + size_t in_packets = 0; + size_t in_frame_size = 0; + size_t in_bytes_required = 0; - vector input_buffer; - vector encode_buffer; + vector input_buffer; + vector encode_buffer; - uint64_t total_samples = 0; - uint64_t samples_per_second = 0; + uint64_t total_samples = 0; + uint64_t samples_per_second = 0; - vector extra_data; + vector extra_data; - size_t channels = 0; + size_t channels = 0; ~ca_encoder() { @@ -131,16 +130,14 @@ typedef struct ca_encoder ca_encoder; namespace std { #ifndef _WIN32 -template <> -struct default_delete::type> { +template<> struct default_delete::type> { void operator()(remove_pointer::type *err) { CFRelease(err); } }; -template <> -struct default_delete::type> { +template<> struct default_delete::type> { void operator()(remove_pointer::type *str) { CFRelease(str); @@ -148,8 +145,7 @@ struct default_delete::type> { }; #endif -template <> -struct default_delete::type> { +template<> struct default_delete::type> { void operator()(AudioConverterRef converter) { AudioConverterDispose(converter); @@ -158,15 +154,16 @@ struct default_delete::type> { } -template +template using cf_ptr = unique_ptr::type>; #ifndef _MSC_VER __attribute__((__format__(__printf__, 3, 4))) #endif -static void log_to_dstr(DStr &str, ca_encoder *ca, const char *fmt, ...) +static void +log_to_dstr(DStr &str, ca_encoder *ca, const char *fmt, ...) { - dstr prev_str = *static_cast(str); + dstr prev_str = *static_cast(str); va_list args; va_start(args, fmt); @@ -184,12 +181,15 @@ static void log_to_dstr(DStr &str, ca_encoder *ca, const char *fmt, ...) array[4095] = 0; if (!prev_str.array && !prev_str.len) - CA_CO_LOG(LOG_ERROR, "Could not allocate buffer for logging:" - "\n'%s'", array); + CA_CO_LOG(LOG_ERROR, + "Could not allocate buffer for logging:" + "\n'%s'", + array); else - CA_CO_LOG(LOG_ERROR, "Could not allocate buffer for logging:" - "\n'%s'\nPrevious log entries:\n%s", - array, prev_str.array); + CA_CO_LOG(LOG_ERROR, + "Could not allocate buffer for logging:" + "\n'%s'\nPrevious log entries:\n%s", + array, prev_str.array); bfree(prev_str.array); } @@ -208,13 +208,12 @@ static const char *flush_log(DStr &log) } #define CA_CO_DLOG_(level, format) \ - CA_CO_LOG(level, format "%s%s", \ - log->array ? ":\n" : "", flush_log(log)) -#define CA_CO_DLOG(level, format, ...) \ + CA_CO_LOG(level, format "%s%s", log->array ? ":\n" : "", flush_log(log)) +#define CA_CO_DLOG(level, format, ...) \ CA_CO_LOG(level, format "%s%s", ##__VA_ARGS__, \ - log->array ? ":\n" : "", flush_log(log)) + log->array ? ":\n" : "", flush_log(log)) -static const char *aac_get_name(void*) +static const char *aac_get_name(void *) { return obs_module_text("CoreAudioAAC"); } @@ -222,28 +221,31 @@ static const char *aac_get_name(void*) static const char *code_to_str(OSStatus code) { switch (code) { -#define HANDLE_CODE(c) case c: return #c - HANDLE_CODE(kAudio_UnimplementedError); - HANDLE_CODE(kAudio_FileNotFoundError); - HANDLE_CODE(kAudio_FilePermissionError); - HANDLE_CODE(kAudio_TooManyFilesOpenError); - HANDLE_CODE(kAudio_BadFilePathError); - HANDLE_CODE(kAudio_ParamError); - HANDLE_CODE(kAudio_MemFullError); +#define HANDLE_CODE(c) \ + case c: \ + return #c + HANDLE_CODE(kAudio_UnimplementedError); + HANDLE_CODE(kAudio_FileNotFoundError); + HANDLE_CODE(kAudio_FilePermissionError); + HANDLE_CODE(kAudio_TooManyFilesOpenError); + HANDLE_CODE(kAudio_BadFilePathError); + HANDLE_CODE(kAudio_ParamError); + HANDLE_CODE(kAudio_MemFullError); - HANDLE_CODE(kAudioConverterErr_FormatNotSupported); - HANDLE_CODE(kAudioConverterErr_OperationNotSupported); - HANDLE_CODE(kAudioConverterErr_PropertyNotSupported); - HANDLE_CODE(kAudioConverterErr_InvalidInputSize); - HANDLE_CODE(kAudioConverterErr_InvalidOutputSize); - HANDLE_CODE(kAudioConverterErr_UnspecifiedError); - HANDLE_CODE(kAudioConverterErr_BadPropertySizeError); - HANDLE_CODE(kAudioConverterErr_RequiresPacketDescriptionsError); - HANDLE_CODE(kAudioConverterErr_InputSampleRateOutOfRange); - HANDLE_CODE(kAudioConverterErr_OutputSampleRateOutOfRange); + HANDLE_CODE(kAudioConverterErr_FormatNotSupported); + HANDLE_CODE(kAudioConverterErr_OperationNotSupported); + HANDLE_CODE(kAudioConverterErr_PropertyNotSupported); + HANDLE_CODE(kAudioConverterErr_InvalidInputSize); + HANDLE_CODE(kAudioConverterErr_InvalidOutputSize); + HANDLE_CODE(kAudioConverterErr_UnspecifiedError); + HANDLE_CODE(kAudioConverterErr_BadPropertySizeError); + HANDLE_CODE(kAudioConverterErr_RequiresPacketDescriptionsError); + HANDLE_CODE(kAudioConverterErr_InputSampleRateOutOfRange); + HANDLE_CODE(kAudioConverterErr_OutputSampleRateOutOfRange); #undef HANDLE_CODE - default: break; + default: + break; } return NULL; @@ -254,8 +256,8 @@ static DStr osstatus_to_dstr(OSStatus code) DStr result; #ifndef _WIN32 - cf_ptr err{CFErrorCreate(kCFAllocatorDefault, - kCFErrorDomainOSStatus, code, NULL)}; + cf_ptr err{CFErrorCreate( + kCFAllocatorDefault, kCFErrorDomainOSStatus, code, NULL)}; cf_ptr str{CFErrorCopyDescription(err.get())}; if (cfstr_copy_dstr(str.get(), kCFStringEncodingUTF8, result)) @@ -263,16 +265,14 @@ static DStr osstatus_to_dstr(OSStatus code) #endif const char *code_str = code_to_str(code); - dstr_printf(result, "%s%s%d%s", - code_str ? code_str : "", - code_str ? " (" : "", - static_cast(code), - code_str ? ")" : ""); + dstr_printf(result, "%s%s%d%s", code_str ? code_str : "", + code_str ? " (" : "", static_cast(code), + code_str ? ")" : ""); return result; } static void log_osstatus(int log_level, ca_encoder *ca, const char *context, - OSStatus code) + OSStatus code) { DStr str = osstatus_to_dstr(code); if (ca) @@ -283,42 +283,44 @@ static void log_osstatus(int log_level, ca_encoder *ca, const char *context, static const char *format_id_to_str(UInt32 format_id) { -#define FORMAT_TO_STR(x) case x: return #x +#define FORMAT_TO_STR(x) \ + case x: \ + return #x switch (format_id) { - FORMAT_TO_STR(kAudioFormatLinearPCM); - FORMAT_TO_STR(kAudioFormatAC3); - FORMAT_TO_STR(kAudioFormat60958AC3); - FORMAT_TO_STR(kAudioFormatAppleIMA4); - FORMAT_TO_STR(kAudioFormatMPEG4AAC); - FORMAT_TO_STR(kAudioFormatMPEG4CELP); - FORMAT_TO_STR(kAudioFormatMPEG4HVXC); - FORMAT_TO_STR(kAudioFormatMPEG4TwinVQ); - FORMAT_TO_STR(kAudioFormatMACE3); - FORMAT_TO_STR(kAudioFormatMACE6); - FORMAT_TO_STR(kAudioFormatULaw); - FORMAT_TO_STR(kAudioFormatALaw); - FORMAT_TO_STR(kAudioFormatQDesign); - FORMAT_TO_STR(kAudioFormatQDesign2); - FORMAT_TO_STR(kAudioFormatQUALCOMM); - FORMAT_TO_STR(kAudioFormatMPEGLayer1); - FORMAT_TO_STR(kAudioFormatMPEGLayer2); - FORMAT_TO_STR(kAudioFormatMPEGLayer3); - FORMAT_TO_STR(kAudioFormatTimeCode); - FORMAT_TO_STR(kAudioFormatMIDIStream); - FORMAT_TO_STR(kAudioFormatParameterValueStream); - FORMAT_TO_STR(kAudioFormatAppleLossless); - FORMAT_TO_STR(kAudioFormatMPEG4AAC_HE); - FORMAT_TO_STR(kAudioFormatMPEG4AAC_LD); - FORMAT_TO_STR(kAudioFormatMPEG4AAC_ELD); - FORMAT_TO_STR(kAudioFormatMPEG4AAC_ELD_SBR); - FORMAT_TO_STR(kAudioFormatMPEG4AAC_HE_V2); - FORMAT_TO_STR(kAudioFormatMPEG4AAC_Spatial); - FORMAT_TO_STR(kAudioFormatAMR); - FORMAT_TO_STR(kAudioFormatAudible); - FORMAT_TO_STR(kAudioFormatiLBC); - FORMAT_TO_STR(kAudioFormatDVIIntelIMA); - FORMAT_TO_STR(kAudioFormatMicrosoftGSM); - FORMAT_TO_STR(kAudioFormatAES3); + FORMAT_TO_STR(kAudioFormatLinearPCM); + FORMAT_TO_STR(kAudioFormatAC3); + FORMAT_TO_STR(kAudioFormat60958AC3); + FORMAT_TO_STR(kAudioFormatAppleIMA4); + FORMAT_TO_STR(kAudioFormatMPEG4AAC); + FORMAT_TO_STR(kAudioFormatMPEG4CELP); + FORMAT_TO_STR(kAudioFormatMPEG4HVXC); + FORMAT_TO_STR(kAudioFormatMPEG4TwinVQ); + FORMAT_TO_STR(kAudioFormatMACE3); + FORMAT_TO_STR(kAudioFormatMACE6); + FORMAT_TO_STR(kAudioFormatULaw); + FORMAT_TO_STR(kAudioFormatALaw); + FORMAT_TO_STR(kAudioFormatQDesign); + FORMAT_TO_STR(kAudioFormatQDesign2); + FORMAT_TO_STR(kAudioFormatQUALCOMM); + FORMAT_TO_STR(kAudioFormatMPEGLayer1); + FORMAT_TO_STR(kAudioFormatMPEGLayer2); + FORMAT_TO_STR(kAudioFormatMPEGLayer3); + FORMAT_TO_STR(kAudioFormatTimeCode); + FORMAT_TO_STR(kAudioFormatMIDIStream); + FORMAT_TO_STR(kAudioFormatParameterValueStream); + FORMAT_TO_STR(kAudioFormatAppleLossless); + FORMAT_TO_STR(kAudioFormatMPEG4AAC_HE); + FORMAT_TO_STR(kAudioFormatMPEG4AAC_LD); + FORMAT_TO_STR(kAudioFormatMPEG4AAC_ELD); + FORMAT_TO_STR(kAudioFormatMPEG4AAC_ELD_SBR); + FORMAT_TO_STR(kAudioFormatMPEG4AAC_HE_V2); + FORMAT_TO_STR(kAudioFormatMPEG4AAC_Spatial); + FORMAT_TO_STR(kAudioFormatAMR); + FORMAT_TO_STR(kAudioFormatAudible); + FORMAT_TO_STR(kAudioFormatiLBC); + FORMAT_TO_STR(kAudioFormatDVIIntelIMA); + FORMAT_TO_STR(kAudioFormatMicrosoftGSM); + FORMAT_TO_STR(kAudioFormatAES3); } #undef FORMAT_TO_STR @@ -327,23 +329,25 @@ static const char *format_id_to_str(UInt32 format_id) static void aac_destroy(void *data) { - ca_encoder *ca = static_cast(data); + ca_encoder *ca = static_cast(data); delete ca; } -template +template static bool query_converter_property_raw(DStr &log, ca_encoder *ca, - AudioFormatPropertyID property, - const char *get_property_info, const char *get_property, - AudioConverterRef converter, Func &&func) + AudioFormatPropertyID property, + const char *get_property_info, + const char *get_property, + AudioConverterRef converter, + Func &&func) { UInt32 size = 0; OSStatus code = AudioConverterGetPropertyInfo(converter, property, - &size, nullptr); + &size, nullptr); if (code) { log_to_dstr(log, ca, "%s: %s\n", get_property_info, - osstatus_to_dstr(code)->array); + osstatus_to_dstr(code)->array); return false; } @@ -353,57 +357,56 @@ static bool query_converter_property_raw(DStr &log, ca_encoder *ca, } vector buffer; - + try { buffer.resize(size); } catch (...) { log_to_dstr(log, ca, "Failed to allocate %u bytes for %s\n", - static_cast(size), get_property); + static_cast(size), get_property); return false; } code = AudioConverterGetProperty(converter, property, &size, - buffer.data()); + buffer.data()); if (code) { log_to_dstr(log, ca, "%s: %s\n", get_property, - osstatus_to_dstr(code)->array); + osstatus_to_dstr(code)->array); return false; } - func(size, static_cast(buffer.data())); + func(size, static_cast(buffer.data())); return true; } -#define EXPAND_CONVERTER_NAMES(x) x, \ - "AudioConverterGetPropertyInfo(" #x ")", \ - "AudioConverterGetProperty(" #x ")" +#define EXPAND_CONVERTER_NAMES(x) \ + x, "AudioConverterGetPropertyInfo(" #x ")", \ + "AudioConverterGetProperty(" #x ")" -template +template static bool enumerate_bitrates(DStr &log, ca_encoder *ca, - AudioConverterRef converter, Func &&func) + AudioConverterRef converter, Func &&func) { - auto helper = [&](UInt32 size, void *data) - { - auto range = static_cast(data); + auto helper = [&](UInt32 size, void *data) { + auto range = static_cast(data); size_t num_ranges = size / sizeof(AudioValueRange); for (size_t i = 0; i < num_ranges; i++) func(static_cast(range[i].mMinimum), - static_cast(range[i].mMaximum)); + static_cast(range[i].mMaximum)); }; - return query_converter_property_raw(log, ca, EXPAND_CONVERTER_NAMES( - kAudioConverterApplicableEncodeBitRates), - converter, helper); + return query_converter_property_raw( + log, ca, + EXPAND_CONVERTER_NAMES(kAudioConverterApplicableEncodeBitRates), + converter, helper); } static bool bitrate_valid(DStr &log, ca_encoder *ca, - AudioConverterRef converter, UInt32 bitrate) + AudioConverterRef converter, UInt32 bitrate) { bool valid = false; - auto helper = [&](UInt32 min_, UInt32 max_) - { + auto helper = [&](UInt32 min_, UInt32 max_) { if (min_ == bitrate || max_ == bitrate) valid = true; }; @@ -414,47 +417,47 @@ static bool bitrate_valid(DStr &log, ca_encoder *ca, } static bool create_encoder(DStr &log, ca_encoder *ca, - AudioStreamBasicDescription *in, - AudioStreamBasicDescription *out, - UInt32 format_id, UInt32 bitrate, UInt32 samplerate, - UInt32 rate_control) + AudioStreamBasicDescription *in, + AudioStreamBasicDescription *out, UInt32 format_id, + UInt32 bitrate, UInt32 samplerate, + UInt32 rate_control) { -#define STATUS_CHECK(c) \ - code = c; \ - if (code) { \ - log_to_dstr(log, ca, #c " returned %s", \ - osstatus_to_dstr(code)->array); \ - return false; \ +#define STATUS_CHECK(c) \ + code = c; \ + if (code) { \ + log_to_dstr(log, ca, #c " returned %s", \ + osstatus_to_dstr(code)->array); \ + return false; \ } - Float64 srate = samplerate ? - (Float64)samplerate : - (Float64)ca->samples_per_second; + Float64 srate = samplerate ? (Float64)samplerate + : (Float64)ca->samples_per_second; auto out_ = asbd_builder() - .sample_rate(srate) - .channels_per_frame((UInt32)ca->channels) - .format_id(format_id) - .asbd; + .sample_rate(srate) + .channels_per_frame((UInt32)ca->channels) + .format_id(format_id) + .asbd; UInt32 size = sizeof(*out); OSStatus code; - STATUS_CHECK(AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, - 0, NULL, &size, &out_)); + STATUS_CHECK(AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, + NULL, &size, &out_)); *out = out_; STATUS_CHECK(AudioConverterNew(in, out, &ca->converter)) - STATUS_CHECK(AudioConverterSetProperty(ca->converter, - kAudioCodecPropertyBitRateControlMode, - sizeof(rate_control), &rate_control)); + STATUS_CHECK(AudioConverterSetProperty( + ca->converter, kAudioCodecPropertyBitRateControlMode, + sizeof(rate_control), &rate_control)); if (!bitrate_valid(log, ca, ca->converter, bitrate)) { - log_to_dstr(log, ca, "Encoder does not support bitrate %u " - "for format %s (0x%x)\n", - (uint32_t)bitrate, format_id_to_str(format_id), - (uint32_t)format_id); + log_to_dstr(log, ca, + "Encoder does not support bitrate %u " + "for format %s (0x%x)\n", + (uint32_t)bitrate, format_id_to_str(format_id), + (uint32_t)format_id); return false; } @@ -476,17 +479,17 @@ static const initializer_list aac_lc_formats = { static void *aac_create(obs_data_t *settings, obs_encoder_t *encoder) { -#define STATUS_CHECK(c) \ - code = c; \ - if (code) { \ +#define STATUS_CHECK(c) \ + code = c; \ + if (code) { \ log_osstatus(LOG_ERROR, ca.get(), #c, code); \ - return nullptr; \ + return nullptr; \ } UInt32 bitrate = (UInt32)obs_data_get_int(settings, "bitrate") * 1000; if (!bitrate) { CA_LOG_ENCODER("AAC", encoder, LOG_ERROR, - "Invalid bitrate specified"); + "Invalid bitrate specified"); return NULL; } @@ -494,7 +497,7 @@ static void *aac_create(obs_data_t *settings, obs_encoder_t *encoder) if (is_audio_planar(format)) { CA_LOG_ENCODER("AAC", encoder, LOG_ERROR, - "Got non-interleaved audio format %d", format); + "Got non-interleaved audio format %d", format); return NULL; } @@ -504,7 +507,7 @@ static void *aac_create(obs_data_t *settings, obs_encoder_t *encoder) ca.reset(new ca_encoder()); } catch (...) { CA_LOG_ENCODER("AAC", encoder, LOG_ERROR, - "Could not allocate encoder"); + "Could not allocate encoder"); return nullptr; } @@ -517,22 +520,21 @@ static void *aac_create(obs_data_t *settings, obs_encoder_t *encoder) ca->channels = audio_output_get_channels(audio); ca->samples_per_second = audio_output_get_sample_rate(audio); - size_t bytes_per_frame = get_audio_size(format, aoi->speakers, 1); + size_t bytes_per_frame = get_audio_size(format, aoi->speakers, 1); size_t bits_per_channel = get_audio_bytes_per_channel(format) * 8; auto in = asbd_builder() - .sample_rate((Float64)ca->samples_per_second) - .channels_per_frame((UInt32)ca->channels) - .bytes_per_frame((UInt32)bytes_per_frame) - .frames_per_packet(1) - .bytes_per_packet((UInt32)(1 * bytes_per_frame)) - .bits_per_channel((UInt32)bits_per_channel) - .format_id(kAudioFormatLinearPCM) - .format_flags(kAudioFormatFlagsNativeEndian | - kAudioFormatFlagIsPacked | - kAudioFormatFlagIsFloat | - 0) - .asbd; + .sample_rate((Float64)ca->samples_per_second) + .channels_per_frame((UInt32)ca->channels) + .bytes_per_frame((UInt32)bytes_per_frame) + .frames_per_packet(1) + .bytes_per_packet((UInt32)(1 * bytes_per_frame)) + .bits_per_channel((UInt32)bits_per_channel) + .format_id(kAudioFormatLinearPCM) + .format_flags(kAudioFormatFlagsNativeEndian | + kAudioFormatFlagIsPacked | + kAudioFormatFlagIsFloat | 0) + .asbd; AudioStreamBasicDescription out; @@ -552,11 +554,10 @@ static void *aac_create(obs_data_t *settings, obs_encoder_t *encoder) bool encoder_created = false; for (UInt32 format_id : *ca->allowed_formats) { log_to_dstr(log, ca.get(), "Trying format %s (0x%x)\n", - format_id_to_str(format_id), - (uint32_t)format_id); + format_id_to_str(format_id), (uint32_t)format_id); if (!create_encoder(log, ca.get(), &in, &out, format_id, - bitrate, samplerate, rate_control)) + bitrate, samplerate, rate_control)) continue; encoder_created = true; @@ -564,9 +565,10 @@ static void *aac_create(obs_data_t *settings, obs_encoder_t *encoder) } if (!encoder_created) { - CA_CO_DLOG(LOG_ERROR, "Could not create encoder for " - "selected format%s", - ca->allowed_formats->size() == 1 ? "" : "s"); + CA_CO_DLOG(LOG_ERROR, + "Could not create encoder for " + "selected format%s", + ca->allowed_formats->size() == 1 ? "" : "s"); return nullptr; } @@ -575,23 +577,23 @@ static void *aac_create(obs_data_t *settings, obs_encoder_t *encoder) OSStatus code; UInt32 converter_quality = kAudioConverterQuality_Max; - STATUS_CHECK(AudioConverterSetProperty(ca->converter, - kAudioConverterCodecQuality, - sizeof(converter_quality), &converter_quality)); + STATUS_CHECK(AudioConverterSetProperty( + ca->converter, kAudioConverterCodecQuality, + sizeof(converter_quality), &converter_quality)); STATUS_CHECK(AudioConverterSetProperty(ca->converter, - kAudioConverterEncodeBitRate, - sizeof(bitrate), &bitrate)); + kAudioConverterEncodeBitRate, + sizeof(bitrate), &bitrate)); UInt32 size = sizeof(in); - STATUS_CHECK(AudioConverterGetProperty(ca->converter, - kAudioConverterCurrentInputStreamDescription, - &size, &in)); + STATUS_CHECK(AudioConverterGetProperty( + ca->converter, kAudioConverterCurrentInputStreamDescription, + &size, &in)); size = sizeof(out); - STATUS_CHECK(AudioConverterGetProperty(ca->converter, - kAudioConverterCurrentOutputStreamDescription, - &size, &out)); + STATUS_CHECK(AudioConverterGetProperty( + ca->converter, kAudioConverterCurrentOutputStreamDescription, + &size, &out)); /* * Fix channel map differences between CoreAudio AAC, FFmpeg, Wav @@ -600,30 +602,30 @@ static void *aac_create(obs_data_t *settings, obs_encoder_t *encoder) if (ca->channels == 3) { SInt32 channelMap3[3] = {2, 0, 1}; AudioConverterSetProperty(ca->converter, - kAudioConverterChannelMap, - sizeof(channelMap3), channelMap3); + kAudioConverterChannelMap, + sizeof(channelMap3), channelMap3); } else if (ca->channels == 5) { SInt32 channelMap5[5] = {2, 0, 1, 3, 4}; AudioConverterSetProperty(ca->converter, - kAudioConverterChannelMap, - sizeof(channelMap5), channelMap5); + kAudioConverterChannelMap, + sizeof(channelMap5), channelMap5); } else if (ca->channels == 6) { SInt32 channelMap6[6] = {2, 0, 1, 4, 5, 3}; AudioConverterSetProperty(ca->converter, - kAudioConverterChannelMap, - sizeof(channelMap6), channelMap6); + kAudioConverterChannelMap, + sizeof(channelMap6), channelMap6); } else if (ca->channels == 8) { SInt32 channelMap8[8] = {2, 0, 1, 6, 7, 4, 5, 3}; AudioConverterSetProperty(ca->converter, - kAudioConverterChannelMap, - sizeof(channelMap8), channelMap8); + kAudioConverterChannelMap, + sizeof(channelMap8), channelMap8); } - ca->in_frame_size = in.mBytesPerFrame; - ca->in_packets = out.mFramesPerPacket / in.mFramesPerPacket; + ca->in_frame_size = in.mBytesPerFrame; + ca->in_packets = out.mFramesPerPacket / in.mFramesPerPacket; ca->in_bytes_required = ca->in_packets * ca->in_frame_size; ca->out_frames_per_packet = out.mFramesPerPacket; @@ -633,14 +635,15 @@ static void *aac_create(obs_data_t *settings, obs_encoder_t *encoder) if (out.mBytesPerPacket == 0) { UInt32 max_packet_size = 0; size = sizeof(max_packet_size); - - code = AudioConverterGetProperty(ca->converter, - kAudioConverterPropertyMaximumOutputPacketSize, - &size, &max_packet_size); + + code = AudioConverterGetProperty( + ca->converter, + kAudioConverterPropertyMaximumOutputPacketSize, &size, + &max_packet_size); if (code) { log_osstatus(LOG_WARNING, ca.get(), - "AudioConverterGetProperty(PacketSz)", - code); + "AudioConverterGetProperty(PacketSz)", + code); ca->output_buffer_size = 32768; } else { ca->output_buffer_size = max_packet_size; @@ -655,33 +658,37 @@ static void *aac_create(obs_data_t *settings, obs_encoder_t *encoder) } const char *format_name = - out.mFormatID == kAudioFormatMPEG4AAC_HE_V2 ? "HE-AAC v2" : - out.mFormatID == kAudioFormatMPEG4AAC_HE ? "HE-AAC" : "AAC"; - CA_BLOG(LOG_INFO, "settings:\n" - "\tmode: %s\n" - "\tbitrate: %u\n" - "\tsample rate: %llu\n" - "\tcbr: %s\n" - "\toutput buffer: %lu", - format_name, (unsigned int)bitrate / 1000, - ca->samples_per_second, - rate_control == kAudioCodecBitRateControlMode_Constant ? - "on" : "off", - (unsigned long)ca->output_buffer_size); + out.mFormatID == kAudioFormatMPEG4AAC_HE_V2 + ? "HE-AAC v2" + : out.mFormatID == kAudioFormatMPEG4AAC_HE ? "HE-AAC" + : "AAC"; + CA_BLOG(LOG_INFO, + "settings:\n" + "\tmode: %s\n" + "\tbitrate: %u\n" + "\tsample rate: %llu\n" + "\tcbr: %s\n" + "\toutput buffer: %lu", + format_name, (unsigned int)bitrate / 1000, + ca->samples_per_second, + rate_control == kAudioCodecBitRateControlMode_Constant ? "on" + : "off", + (unsigned long)ca->output_buffer_size); return ca.release(); #undef STATUS_CHECK } -static OSStatus complex_input_data_proc(AudioConverterRef inAudioConverter, - UInt32 *ioNumberDataPackets, AudioBufferList *ioData, - AudioStreamPacketDescription **outDataPacketDescription, - void *inUserData) +static OSStatus +complex_input_data_proc(AudioConverterRef inAudioConverter, + UInt32 *ioNumberDataPackets, AudioBufferList *ioData, + AudioStreamPacketDescription **outDataPacketDescription, + void *inUserData) { UNUSED_PARAMETER(inAudioConverter); UNUSED_PARAMETER(outDataPacketDescription); - ca_encoder *ca = static_cast(inUserData); + ca_encoder *ca = static_cast(inUserData); if (ca->input_buffer.size() < ca->in_bytes_required) { *ioNumberDataPackets = 0; @@ -690,7 +697,7 @@ static OSStatus complex_input_data_proc(AudioConverterRef inAudioConverter, } auto start = begin(ca->input_buffer); - auto stop = begin(ca->input_buffer) + ca->in_bytes_required; + auto stop = begin(ca->input_buffer) + ca->in_bytes_required; ca->encode_buffer.assign(start, stop); ca->input_buffer.erase(start, stop); @@ -709,35 +716,35 @@ static OSStatus complex_input_data_proc(AudioConverterRef inAudioConverter, // disable warning that recommends if ((foo = bar > 0) == false) over // if (!(foo = bar > 0)) #pragma warning(push) -#pragma warning(disable: 4706) +#pragma warning(disable : 4706) #endif static bool aac_encode(void *data, struct encoder_frame *frame, - struct encoder_packet *packet, bool *received_packet) + struct encoder_packet *packet, bool *received_packet) { - ca_encoder *ca = static_cast(data); + ca_encoder *ca = static_cast(data); - ca->input_buffer.insert(end(ca->input_buffer), - frame->data[0], frame->data[0] + frame->linesize[0]); + ca->input_buffer.insert(end(ca->input_buffer), frame->data[0], + frame->data[0] + frame->linesize[0]); if (ca->input_buffer.size() < ca->in_bytes_required) return true; UInt32 packets = 1; - AudioBufferList buffer_list = { 0 }; + AudioBufferList buffer_list = {0}; buffer_list.mNumberBuffers = 1; buffer_list.mBuffers[0].mNumberChannels = (UInt32)ca->channels; buffer_list.mBuffers[0].mDataByteSize = (UInt32)ca->output_buffer_size; buffer_list.mBuffers[0].mData = ca->output_buffer.data(); - AudioStreamPacketDescription out_desc = { 0 }; + AudioStreamPacketDescription out_desc = {0}; - OSStatus code = AudioConverterFillComplexBuffer(ca->converter, - complex_input_data_proc, ca, &packets, - &buffer_list, &out_desc); + OSStatus code = AudioConverterFillComplexBuffer( + ca->converter, complex_input_data_proc, ca, &packets, + &buffer_list, &out_desc); if (code && code != 1) { log_osstatus(LOG_ERROR, ca, "AudioConverterFillComplexBuffer", - code); + code); return false; } @@ -750,8 +757,8 @@ static bool aac_encode(void *data, struct encoder_frame *frame, packet->timebase_den = (uint32_t)ca->samples_per_second; packet->type = OBS_ENCODER_AUDIO; packet->size = out_desc.mDataByteSize; - packet->data = - (uint8_t*)buffer_list.mBuffers[0].mData + out_desc.mStartOffset; + packet->data = (uint8_t *)buffer_list.mBuffers[0].mData + + out_desc.mStartOffset; ca->total_samples += ca->in_bytes_required / ca->in_frame_size; @@ -770,22 +777,21 @@ static void aac_audio_info(void *data, struct audio_convert_info *info) static size_t aac_frame_size(void *data) { - ca_encoder *ca = static_cast(data); + ca_encoder *ca = static_cast(data); return ca->out_frames_per_packet; } /* The following code was extracted from encca_aac.c in HandBrake's libhb */ -#define MP4ESDescrTag 0x03 -#define MP4DecConfigDescrTag 0x04 -#define MP4DecSpecificDescrTag 0x05 +#define MP4ESDescrTag 0x03 +#define MP4DecConfigDescrTag 0x04 +#define MP4DecSpecificDescrTag 0x05 // based off of mov_mp4_read_descr_len from mov.c in ffmpeg's libavformat static int read_descr_len(uint8_t **buffer) { int len = 0; int count = 4; - while (count--) - { + while (count--) { int c = *(*buffer)++; len = (len << 7) | (c & 0x7f); if (!(c & 0x80)) @@ -802,8 +808,8 @@ static int read_descr(uint8_t **buffer, int *tag) } // based off of mov_read_esds from mov.c in ffmpeg's libavformat -static void read_esds_desc_ext(uint8_t* desc_ext, vector &buffer, - bool version_flags) +static void read_esds_desc_ext(uint8_t *desc_ext, vector &buffer, + bool version_flags) { uint8_t *esds = desc_ext; int tag, len; @@ -812,9 +818,9 @@ static void read_esds_desc_ext(uint8_t* desc_ext, vector &buffer, esds += 4; // version + flags read_descr(&esds, &tag); - esds += 2; // ID + esds += 2; // ID if (tag == MP4ESDescrTag) - esds++; // priority + esds++; // priority read_descr(&esds, &tag); if (tag == MP4DecConfigDescrTag) { @@ -840,13 +846,13 @@ static void query_extra_data(ca_encoder *ca) UInt32 size = 0; OSStatus code; - code = AudioConverterGetPropertyInfo(ca->converter, - kAudioConverterCompressionMagicCookie, - &size, NULL); + code = AudioConverterGetPropertyInfo( + ca->converter, kAudioConverterCompressionMagicCookie, &size, + NULL); if (code) { log_osstatus(LOG_ERROR, ca, - "AudioConverterGetPropertyInfo(magic_cookie)", - code); + "AudioConverterGetPropertyInfo(magic_cookie)", + code); return; } @@ -856,7 +862,7 @@ static void query_extra_data(ca_encoder *ca) } vector extra_data; - + try { extra_data.resize(size); } catch (...) { @@ -865,12 +871,11 @@ static void query_extra_data(ca_encoder *ca) } code = AudioConverterGetProperty(ca->converter, - kAudioConverterCompressionMagicCookie, - &size, extra_data.data()); + kAudioConverterCompressionMagicCookie, + &size, extra_data.data()); if (code) { log_osstatus(LOG_ERROR, ca, - "AudioConverterGetProperty(magic_cookie)", - code); + "AudioConverterGetProperty(magic_cookie)", code); return; } @@ -884,7 +889,7 @@ static void query_extra_data(ca_encoder *ca) static bool aac_extra_data(void *data, uint8_t **extra_data, size_t *size) { - ca_encoder *ca = static_cast(data); + ca_encoder *ca = static_cast(data); if (!ca->extra_data.size()) query_extra_data(ca); @@ -898,7 +903,8 @@ static bool aac_extra_data(void *data, uint8_t **extra_data, size_t *size) } static asbd_builder fill_common_asbd_fields(asbd_builder builder, - bool in=false, UInt32 channels=2) + bool in = false, + UInt32 channels = 2) { UInt32 bytes_per_frame = sizeof(float) * channels; UInt32 bits_per_channel = bytes_per_frame / channels * 8; @@ -906,8 +912,7 @@ static asbd_builder fill_common_asbd_fields(asbd_builder builder, builder.channels_per_frame(channels); if (in) { - builder - .bytes_per_frame(bytes_per_frame) + builder.bytes_per_frame(bytes_per_frame) .frames_per_packet(1) .bytes_per_packet(1 * bytes_per_frame) .bits_per_channel(bits_per_channel); @@ -922,9 +927,8 @@ static AudioStreamBasicDescription get_default_in_asbd() .sample_rate(44100) .format_id(kAudioFormatLinearPCM) .format_flags(kAudioFormatFlagsNativeEndian | - kAudioFormatFlagIsPacked | - kAudioFormatFlagIsFloat | - 0) + kAudioFormatFlagIsPacked | + kAudioFormatFlagIsFloat | 0) .asbd; } @@ -934,23 +938,23 @@ static asbd_builder get_default_out_asbd_builder(UInt32 channels) .sample_rate(44100); } -static cf_ptr get_converter(DStr &log, ca_encoder *ca, - AudioStreamBasicDescription out, - AudioStreamBasicDescription in = get_default_in_asbd()) +static cf_ptr +get_converter(DStr &log, ca_encoder *ca, AudioStreamBasicDescription out, + AudioStreamBasicDescription in = get_default_in_asbd()) { UInt32 size = sizeof(out); OSStatus code; -#define STATUS_CHECK(x) \ - code = x; \ - if (code) { \ - log_to_dstr(log, ca, "%s: %s\n", #x, \ - osstatus_to_dstr(code)->array); \ - return nullptr; \ +#define STATUS_CHECK(x) \ + code = x; \ + if (code) { \ + log_to_dstr(log, ca, "%s: %s\n", #x, \ + osstatus_to_dstr(code)->array); \ + return nullptr; \ } - STATUS_CHECK(AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, - 0, NULL, &size, &out)); + STATUS_CHECK(AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, + NULL, &size, &out)); AudioConverterRef converter; STATUS_CHECK(AudioConverterNew(&in, &out, &converter)); @@ -960,50 +964,47 @@ static cf_ptr get_converter(DStr &log, ca_encoder *ca, } static bool find_best_match(DStr &log, ca_encoder *ca, UInt32 bitrate, - UInt32 &best_match) + UInt32 &best_match) { UInt32 actual_bitrate = bitrate * 1000; bool found_match = false; - auto handle_bitrate = [&](UInt32 candidate) - { + auto handle_bitrate = [&](UInt32 candidate) { if (abs(static_cast(actual_bitrate - candidate)) < abs(static_cast(actual_bitrate - best_match))) { log_to_dstr(log, ca, "Found new best match %u\n", - static_cast(candidate)); + static_cast(candidate)); found_match = true; best_match = candidate; } }; - auto helper = [&](UInt32 min_, UInt32 max_) - { + auto helper = [&](UInt32 min_, UInt32 max_) { handle_bitrate(min_); if (min_ == max_) return; log_to_dstr(log, ca, "Got actual bit rate range: %u<->%u\n", - static_cast(min_), - static_cast(max_)); + static_cast(min_), + static_cast(max_)); handle_bitrate(max_); }; for (UInt32 format_id : aac_formats) { log_to_dstr(log, ca, "Trying %s (0x%x)\n", - format_id_to_str(format_id), format_id); + format_id_to_str(format_id), format_id); auto out = get_default_out_asbd_builder(2) - .format_id(format_id) - .asbd; + .format_id(format_id) + .asbd; auto converter = get_converter(log, ca, out); if (converter) - enumerate_bitrates(log, ca, converter.get(), - helper); + enumerate_bitrates(log, ca, converter.get(), helper); else log_to_dstr(log, ca, "Could not get converter\n"); } @@ -1019,32 +1020,34 @@ static UInt32 find_matching_bitrate(UInt32 bitrate) static once_flag once; - call_once(once, [&]() - { + call_once(once, [&]() { DStr log; ca_encoder *ca = nullptr; if (!find_best_match(log, ca, bitrate, match)) { - CA_CO_DLOG(LOG_ERROR, "No matching bitrates found for " - "target bitrate %u", - static_cast(bitrate)); + CA_CO_DLOG(LOG_ERROR, + "No matching bitrates found for " + "target bitrate %u", + static_cast(bitrate)); match = bitrate; return; } if (match != bitrate) { - CA_CO_DLOG(LOG_INFO, "Default bitrate (%u) isn't " - "supported, returning %u as closest match", - static_cast(bitrate), - static_cast(match)); + CA_CO_DLOG(LOG_INFO, + "Default bitrate (%u) isn't " + "supported, returning %u as closest match", + static_cast(bitrate), + static_cast(match)); return; } if (log->len) - CA_CO_DLOG(LOG_DEBUG, "Default bitrate matching log " - "for bitrate %u", - static_cast(bitrate)); + CA_CO_DLOG(LOG_DEBUG, + "Default bitrate matching log " + "for bitrate %u", + static_cast(bitrate)); }); return match; @@ -1054,22 +1057,22 @@ static void aac_defaults(obs_data_t *settings) { obs_data_set_default_int(settings, "samplerate", 0); //match input obs_data_set_default_int(settings, "bitrate", - find_matching_bitrate(128)); + find_matching_bitrate(128)); obs_data_set_default_bool(settings, "allow he-aac", true); } -template -static bool query_property_raw(DStr &log, ca_encoder *ca, - AudioFormatPropertyID property, - const char *get_property_info, const char *get_property, - AudioStreamBasicDescription &desc, Func &&func) +template +static bool +query_property_raw(DStr &log, ca_encoder *ca, AudioFormatPropertyID property, + const char *get_property_info, const char *get_property, + AudioStreamBasicDescription &desc, Func &&func) { UInt32 size = 0; - OSStatus code = AudioFormatGetPropertyInfo(property, - sizeof(AudioStreamBasicDescription), &desc, &size); + OSStatus code = AudioFormatGetPropertyInfo( + property, sizeof(AudioStreamBasicDescription), &desc, &size); if (code) { log_to_dstr(log, ca, "%s: %s\n", get_property_info, - osstatus_to_dstr(code)->array); + osstatus_to_dstr(code)->array); return false; } @@ -1079,48 +1082,50 @@ static bool query_property_raw(DStr &log, ca_encoder *ca, } vector buffer; - + try { buffer.resize(size); } catch (...) { log_to_dstr(log, ca, "Failed to allocate %u bytes for %s\n", - static_cast(size), get_property); + static_cast(size), get_property); return false; } code = AudioFormatGetProperty(property, - sizeof(AudioStreamBasicDescription), &desc, &size, - buffer.data()); + sizeof(AudioStreamBasicDescription), + &desc, &size, buffer.data()); if (code) { log_to_dstr(log, ca, "%s: %s\n", get_property, - osstatus_to_dstr(code)->array); + osstatus_to_dstr(code)->array); return false; } - func(size, static_cast(buffer.data())); + func(size, static_cast(buffer.data())); return true; } -#define EXPAND_PROPERTY_NAMES(x) x, \ - "AudioFormatGetPropertyInfo(" #x ")", \ - "AudioFormatGetProperty(" #x ")" +#define EXPAND_PROPERTY_NAMES(x) \ + x, "AudioFormatGetPropertyInfo(" #x ")", \ + "AudioFormatGetProperty(" #x ")" -template +template static bool enumerate_samplerates(DStr &log, ca_encoder *ca, - AudioStreamBasicDescription &desc, Func &&func) + AudioStreamBasicDescription &desc, + Func &&func) { - auto helper = [&](UInt32 size, void *data) - { - auto range = static_cast(data); + auto helper = [&](UInt32 size, void *data) { + auto range = static_cast(data); size_t num_ranges = size / sizeof(AudioValueRange); for (size_t i = 0; i < num_ranges; i++) func(range[i]); }; - return query_property_raw(log, ca, EXPAND_PROPERTY_NAMES( + return query_property_raw( + log, ca, + EXPAND_PROPERTY_NAMES( kAudioFormatProperty_AvailableEncodeSampleRates), - desc, helper); + desc, helper); } #if 0 @@ -1149,21 +1154,19 @@ static vector get_samplerates(DStr &log, ca_encoder *ca) { vector samplerates; - auto handle_samplerate = [&](UInt32 rate) - { + auto handle_samplerate = [&](UInt32 rate) { if (find(begin(samplerates), end(samplerates), rate) == - end(samplerates)) { + end(samplerates)) { log_to_dstr(log, ca, "Adding sample rate %u\n", - static_cast(rate)); + static_cast(rate)); samplerates.push_back(rate); } else { log_to_dstr(log, ca, "Sample rate %u already added\n", - static_cast(rate)); + static_cast(rate)); } }; - auto helper = [&](const AudioValueRange &range) - { + auto helper = [&](const AudioValueRange &range) { auto min_ = static_cast(range.mMinimum); auto max_ = static_cast(range.mMaximum); @@ -1173,20 +1176,18 @@ static vector get_samplerates(DStr &log, ca_encoder *ca) return; log_to_dstr(log, ca, "Got actual sample rate range: %u<->%u\n", - static_cast(min_), - static_cast(max_)); + static_cast(min_), + static_cast(max_)); handle_samplerate(max_); }; for (UInt32 format : (ca ? *ca->allowed_formats : aac_formats)) { log_to_dstr(log, ca, "Trying %s (0x%x)\n", - format_id_to_str(format), - static_cast(format)); + format_id_to_str(format), + static_cast(format)); - auto asbd = asbd_builder() - .format_id(format) - .asbd; + auto asbd = asbd_builder().format_id(format).asbd; enumerate_samplerates(log, ca, asbd, helper); } @@ -1196,8 +1197,8 @@ static vector get_samplerates(DStr &log, ca_encoder *ca) static void add_samplerates(obs_property_t *prop, ca_encoder *ca) { - obs_property_list_add_int(prop, - obs_module_text("UseInputSampleRate"), 0); + obs_property_list_add_int(prop, obs_module_text("UseInputSampleRate"), + 0); DStr log; @@ -1223,7 +1224,7 @@ static void add_samplerates(obs_property_t *prop, ca_encoder *ca) #define NBSP "\xC2\xA0" static vector get_bitrates(DStr &log, ca_encoder *ca, - Float64 samplerate) + Float64 samplerate) { vector bitrates; struct obs_audio_info aoi; @@ -1232,43 +1233,40 @@ static vector get_bitrates(DStr &log, ca_encoder *ca, obs_get_audio_info(&aoi); channels = get_audio_channels(aoi.speakers); - auto handle_bitrate = [&](UInt32 bitrate) - { + auto handle_bitrate = [&](UInt32 bitrate) { if (find(begin(bitrates), end(bitrates), bitrate) == - end(bitrates)) { + end(bitrates)) { log_to_dstr(log, ca, "Adding bitrate %u\n", - static_cast(bitrate)); + static_cast(bitrate)); bitrates.push_back(bitrate); } else { log_to_dstr(log, ca, "Bitrate %u already added\n", - static_cast(bitrate)); + static_cast(bitrate)); } }; - auto helper = [&](UInt32 min_, UInt32 max_) - { + auto helper = [&](UInt32 min_, UInt32 max_) { handle_bitrate(min_); if (min_ == max_) return; log_to_dstr(log, ca, "Got actual bitrate range: %u<->%u\n", - static_cast(min_), - static_cast(max_)); + static_cast(min_), + static_cast(max_)); handle_bitrate(max_); }; for (UInt32 format_id : (ca ? *ca->allowed_formats : aac_formats)) { log_to_dstr(log, ca, "Trying %s (0x%x) at %g" NBSP "hz\n", - format_id_to_str(format_id), - static_cast(format_id), - samplerate); + format_id_to_str(format_id), + static_cast(format_id), samplerate); auto out = get_default_out_asbd_builder(channels) - .format_id(format_id) - .sample_rate(samplerate) - .asbd; + .format_id(format_id) + .sample_rate(samplerate) + .asbd; auto converter = get_converter(log, ca, out); @@ -1280,7 +1278,8 @@ static vector get_bitrates(DStr &log, ca_encoder *ca, } static void add_bitrates(obs_property_t *prop, ca_encoder *ca, - Float64 samplerate=44100., UInt32 *selected=nullptr) + Float64 samplerate = 44100., + UInt32 *selected = nullptr) { obs_property_list_clear(prop); @@ -1299,7 +1298,7 @@ static void add_bitrates(obs_property_t *prop, ca_encoder *ca, bool selected_in_range = true; if (selected) { selected_in_range = find(begin(bitrates), end(bitrates), - *selected * 1000) != end(bitrates); + *selected * 1000) != end(bitrates); if (!selected_in_range) bitrates.push_back(*selected * 1000); @@ -1311,7 +1310,7 @@ static void add_bitrates(obs_property_t *prop, ca_encoder *ca, for (UInt32 bitrate : bitrates) { dstr_printf(buffer, "%u", (uint32_t)bitrate / 1000); size_t idx = obs_property_list_add_int(prop, buffer->array, - bitrate / 1000); + bitrate / 1000); if (selected_in_range || bitrate / 1000 != *selected) continue; @@ -1321,7 +1320,7 @@ static void add_bitrates(obs_property_t *prop, ca_encoder *ca, } static bool samplerate_updated(obs_properties_t *props, obs_property_t *prop, - obs_data_t *settings) + obs_data_t *settings) { auto samplerate = static_cast(obs_data_get_int(settings, "samplerate")); @@ -1331,7 +1330,7 @@ static bool samplerate_updated(obs_properties_t *props, obs_property_t *prop, prop = obs_properties_get(props, "bitrate"); if (prop) { auto bitrate = static_cast( - obs_data_get_int(settings, "bitrate")); + obs_data_get_int(settings, "bitrate")); add_bitrates(prop, nullptr, samplerate, &bitrate); @@ -1343,23 +1342,23 @@ static bool samplerate_updated(obs_properties_t *props, obs_property_t *prop, static obs_properties_t *aac_properties(void *data) { - ca_encoder *ca = static_cast(data); + ca_encoder *ca = static_cast(data); obs_properties_t *props = obs_properties_create(); - obs_property_t *p = obs_properties_add_list(props, "samplerate", - obs_module_text("OutputSamplerate"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_t *p = obs_properties_add_list( + props, "samplerate", obs_module_text("OutputSamplerate"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); add_samplerates(p, ca); obs_property_set_modified_callback(p, samplerate_updated); p = obs_properties_add_list(props, "bitrate", - obs_module_text("Bitrate"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_module_text("Bitrate"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); add_bitrates(p, ca); obs_properties_add_bool(props, "allow he-aac", - obs_module_text("AllowHEAAC")); + obs_module_text("AllowHEAAC")); return props; } @@ -1376,14 +1375,15 @@ bool obs_module_load(void) #ifdef _WIN32 if (!load_core_audio()) { CA_LOG(LOG_WARNING, "CoreAudio AAC encoder not installed on " - "the system or couldn't be loaded"); + "the system or couldn't be loaded"); return true; } CA_LOG(LOG_INFO, "Adding CoreAudio AAC encoder"); #endif - struct obs_encoder_info aac_info{}; + struct obs_encoder_info aac_info { + }; aac_info.id = "CoreAudio_AAC"; aac_info.type = OBS_ENCODER_AUDIO; aac_info.codec = "AAC"; diff --git a/plugins/coreaudio-encoder/windows-imports.h b/plugins/coreaudio-encoder/windows-imports.h index 695229a..73f814c 100644 --- a/plugins/coreaudio-encoder/windows-imports.h +++ b/plugins/coreaudio-encoder/windows-imports.h @@ -5,18 +5,17 @@ #include -typedef unsigned long UInt32; -typedef signed long SInt32; -typedef signed long long SInt64; -typedef double Float64; +typedef unsigned long UInt32; +typedef signed long SInt32; +typedef signed long long SInt64; +typedef double Float64; -typedef SInt32 OSStatus; -typedef unsigned char Boolean; +typedef SInt32 OSStatus; +typedef unsigned char Boolean; typedef UInt32 AudioFormatPropertyID; -enum { - kVariableLengthArray = 1 +enum { kVariableLengthArray = 1, }; struct OpaqueAudioConverter; @@ -30,344 +29,305 @@ struct AudioValueRange { typedef struct AudioValueRange AudioValueRange; struct AudioBuffer { - UInt32 mNumberChannels; - UInt32 mDataByteSize; - void* mData; + UInt32 mNumberChannels; + UInt32 mDataByteSize; + void *mData; }; typedef struct AudioBuffer AudioBuffer; struct AudioBufferList { - UInt32 mNumberBuffers; + UInt32 mNumberBuffers; AudioBuffer mBuffers[kVariableLengthArray]; }; typedef struct AudioBufferList AudioBufferList; struct AudioStreamBasicDescription { Float64 mSampleRate; - UInt32 mFormatID; - UInt32 mFormatFlags; - UInt32 mBytesPerPacket; - UInt32 mFramesPerPacket; - UInt32 mBytesPerFrame; - UInt32 mChannelsPerFrame; - UInt32 mBitsPerChannel; - UInt32 mReserved; + UInt32 mFormatID; + UInt32 mFormatFlags; + UInt32 mBytesPerPacket; + UInt32 mFramesPerPacket; + UInt32 mBytesPerFrame; + UInt32 mChannelsPerFrame; + UInt32 mBitsPerChannel; + UInt32 mReserved; }; typedef struct AudioStreamBasicDescription AudioStreamBasicDescription; struct AudioStreamPacketDescription { - SInt64 mStartOffset; - UInt32 mVariableFramesInPacket; - UInt32 mDataByteSize; + SInt64 mStartOffset; + UInt32 mVariableFramesInPacket; + UInt32 mDataByteSize; }; typedef struct AudioStreamPacketDescription AudioStreamPacketDescription; -typedef OSStatus (*AudioConverterComplexInputDataProc) ( - AudioConverterRef inAudioConverter, - UInt32 *ioNumberDataPackets, - AudioBufferList *ioData, - AudioStreamPacketDescription **outDataPacketDescription, - void *inUserData -); +typedef OSStatus (*AudioConverterComplexInputDataProc)( + AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets, + AudioBufferList *ioData, + AudioStreamPacketDescription **outDataPacketDescription, + void *inUserData); -enum { - kAudioCodecPropertyNameCFString = 'lnam', - kAudioCodecPropertyManufacturerCFString = 'lmak', - kAudioCodecPropertyFormatCFString = 'lfor', - //kAudioCodecPropertyHasVariablePacketByteSizes = 'vpk?', - kAudioCodecPropertySupportedInputFormats = 'ifm#', - kAudioCodecPropertySupportedOutputFormats = 'ofm#', - kAudioCodecPropertyAvailableInputSampleRates = 'aisr', - kAudioCodecPropertyAvailableOutputSampleRates = 'aosr', - kAudioCodecPropertyAvailableBitRateRange = 'abrt', - kAudioCodecPropertyMinimumNumberInputPackets = 'mnip', - kAudioCodecPropertyMinimumNumberOutputPackets = 'mnop', - kAudioCodecPropertyAvailableNumberChannels = 'cmnc', - kAudioCodecPropertyDoesSampleRateConversion = 'lmrc', - kAudioCodecPropertyAvailableInputChannelLayoutTags = 'aicl', - kAudioCodecPropertyAvailableOutputChannelLayoutTags = 'aocl', - kAudioCodecPropertyInputFormatsForOutputFormat = 'if4o', - kAudioCodecPropertyOutputFormatsForInputFormat = 'of4i', - kAudioCodecPropertyFormatInfo = 'acfi', +enum { kAudioCodecPropertyNameCFString = 'lnam', + kAudioCodecPropertyManufacturerCFString = 'lmak', + kAudioCodecPropertyFormatCFString = 'lfor', + //kAudioCodecPropertyHasVariablePacketByteSizes = 'vpk?', + kAudioCodecPropertySupportedInputFormats = 'ifm#', + kAudioCodecPropertySupportedOutputFormats = 'ofm#', + kAudioCodecPropertyAvailableInputSampleRates = 'aisr', + kAudioCodecPropertyAvailableOutputSampleRates = 'aosr', + kAudioCodecPropertyAvailableBitRateRange = 'abrt', + kAudioCodecPropertyMinimumNumberInputPackets = 'mnip', + kAudioCodecPropertyMinimumNumberOutputPackets = 'mnop', + kAudioCodecPropertyAvailableNumberChannels = 'cmnc', + kAudioCodecPropertyDoesSampleRateConversion = 'lmrc', + kAudioCodecPropertyAvailableInputChannelLayoutTags = 'aicl', + kAudioCodecPropertyAvailableOutputChannelLayoutTags = 'aocl', + kAudioCodecPropertyInputFormatsForOutputFormat = 'if4o', + kAudioCodecPropertyOutputFormatsForInputFormat = 'of4i', + kAudioCodecPropertyFormatInfo = 'acfi', }; -enum { - kAudioCodecPropertyInputBufferSize = 'tbuf', - kAudioCodecPropertyPacketFrameSize = 'pakf', - kAudioCodecPropertyMaximumPacketByteSize = 'pakb', - kAudioCodecPropertyCurrentInputFormat = 'ifmt', - kAudioCodecPropertyCurrentOutputFormat = 'ofmt', - kAudioCodecPropertyMagicCookie = 'kuki', - kAudioCodecPropertyUsedInputBufferSize = 'ubuf', - kAudioCodecPropertyIsInitialized = 'init', - kAudioCodecPropertyCurrentTargetBitRate = 'brat', - kAudioCodecPropertyCurrentInputSampleRate = 'cisr', - kAudioCodecPropertyCurrentOutputSampleRate = 'cosr', - kAudioCodecPropertyQualitySetting = 'srcq', - kAudioCodecPropertyApplicableBitRateRange = 'brta', - kAudioCodecPropertyApplicableInputSampleRates = 'isra', - kAudioCodecPropertyApplicableOutputSampleRates = 'osra', - kAudioCodecPropertyPaddedZeros = 'pad0', - kAudioCodecPropertyPrimeMethod = 'prmm', - kAudioCodecPropertyPrimeInfo = 'prim', - kAudioCodecPropertyCurrentInputChannelLayout = 'icl ', - kAudioCodecPropertyCurrentOutputChannelLayout = 'ocl ', - kAudioCodecPropertySettings = 'acs ', - kAudioCodecPropertyFormatList = 'acfl', - kAudioCodecPropertyBitRateControlMode = 'acbf', - kAudioCodecPropertySoundQualityForVBR = 'vbrq', - kAudioCodecPropertyMinimumDelayMode = 'mdel' +enum { kAudioCodecPropertyInputBufferSize = 'tbuf', + kAudioCodecPropertyPacketFrameSize = 'pakf', + kAudioCodecPropertyMaximumPacketByteSize = 'pakb', + kAudioCodecPropertyCurrentInputFormat = 'ifmt', + kAudioCodecPropertyCurrentOutputFormat = 'ofmt', + kAudioCodecPropertyMagicCookie = 'kuki', + kAudioCodecPropertyUsedInputBufferSize = 'ubuf', + kAudioCodecPropertyIsInitialized = 'init', + kAudioCodecPropertyCurrentTargetBitRate = 'brat', + kAudioCodecPropertyCurrentInputSampleRate = 'cisr', + kAudioCodecPropertyCurrentOutputSampleRate = 'cosr', + kAudioCodecPropertyQualitySetting = 'srcq', + kAudioCodecPropertyApplicableBitRateRange = 'brta', + kAudioCodecPropertyApplicableInputSampleRates = 'isra', + kAudioCodecPropertyApplicableOutputSampleRates = 'osra', + kAudioCodecPropertyPaddedZeros = 'pad0', + kAudioCodecPropertyPrimeMethod = 'prmm', + kAudioCodecPropertyPrimeInfo = 'prim', + kAudioCodecPropertyCurrentInputChannelLayout = 'icl ', + kAudioCodecPropertyCurrentOutputChannelLayout = 'ocl ', + kAudioCodecPropertySettings = 'acs ', + kAudioCodecPropertyFormatList = 'acfl', + kAudioCodecPropertyBitRateControlMode = 'acbf', + kAudioCodecPropertySoundQualityForVBR = 'vbrq', + kAudioCodecPropertyMinimumDelayMode = 'mdel' }; + +enum { kAudioCodecBitRateControlMode_Constant = 0, + kAudioCodecBitRateControlMode_LongTermAverage = 1, + kAudioCodecBitRateControlMode_VariableConstrained = 2, + kAudioCodecBitRateControlMode_Variable = 3, }; -enum { - kAudioCodecBitRateControlMode_Constant = 0, - kAudioCodecBitRateControlMode_LongTermAverage = 1, - kAudioCodecBitRateControlMode_VariableConstrained = 2, - kAudioCodecBitRateControlMode_Variable = 3, +enum { kAudioFormatLinearPCM = 'lpcm', + kAudioFormatAC3 = 'ac-3', + kAudioFormat60958AC3 = 'cac3', + kAudioFormatAppleIMA4 = 'ima4', + kAudioFormatMPEG4AAC = 'aac ', + kAudioFormatMPEG4CELP = 'celp', + kAudioFormatMPEG4HVXC = 'hvxc', + kAudioFormatMPEG4TwinVQ = 'twvq', + kAudioFormatMACE3 = 'MAC3', + kAudioFormatMACE6 = 'MAC6', + kAudioFormatULaw = 'ulaw', + kAudioFormatALaw = 'alaw', + kAudioFormatQDesign = 'QDMC', + kAudioFormatQDesign2 = 'QDM2', + kAudioFormatQUALCOMM = 'Qclp', + kAudioFormatMPEGLayer1 = '.mp1', + kAudioFormatMPEGLayer2 = '.mp2', + kAudioFormatMPEGLayer3 = '.mp3', + kAudioFormatTimeCode = 'time', + kAudioFormatMIDIStream = 'midi', + kAudioFormatParameterValueStream = 'apvs', + kAudioFormatAppleLossless = 'alac', + kAudioFormatMPEG4AAC_HE = 'aach', + kAudioFormatMPEG4AAC_LD = 'aacl', + kAudioFormatMPEG4AAC_ELD = 'aace', + kAudioFormatMPEG4AAC_ELD_SBR = 'aacf', + kAudioFormatMPEG4AAC_ELD_V2 = 'aacg', + kAudioFormatMPEG4AAC_HE_V2 = 'aacp', + kAudioFormatMPEG4AAC_Spatial = 'aacs', + kAudioFormatAMR = 'samr', + kAudioFormatAudible = 'AUDB', + kAudioFormatiLBC = 'ilbc', + kAudioFormatDVIIntelIMA = 0x6D730011, + kAudioFormatMicrosoftGSM = 0x6D730031, + kAudioFormatAES3 = 'aes3', }; -enum { - kAudioFormatLinearPCM = 'lpcm', - kAudioFormatAC3 = 'ac-3', - kAudioFormat60958AC3 = 'cac3', - kAudioFormatAppleIMA4 = 'ima4', - kAudioFormatMPEG4AAC = 'aac ', - kAudioFormatMPEG4CELP = 'celp', - kAudioFormatMPEG4HVXC = 'hvxc', - kAudioFormatMPEG4TwinVQ = 'twvq', - kAudioFormatMACE3 = 'MAC3', - kAudioFormatMACE6 = 'MAC6', - kAudioFormatULaw = 'ulaw', - kAudioFormatALaw = 'alaw', - kAudioFormatQDesign = 'QDMC', - kAudioFormatQDesign2 = 'QDM2', - kAudioFormatQUALCOMM = 'Qclp', - kAudioFormatMPEGLayer1 = '.mp1', - kAudioFormatMPEGLayer2 = '.mp2', - kAudioFormatMPEGLayer3 = '.mp3', - kAudioFormatTimeCode = 'time', - kAudioFormatMIDIStream = 'midi', - kAudioFormatParameterValueStream = 'apvs', - kAudioFormatAppleLossless = 'alac', - kAudioFormatMPEG4AAC_HE = 'aach', - kAudioFormatMPEG4AAC_LD = 'aacl', - kAudioFormatMPEG4AAC_ELD = 'aace', - kAudioFormatMPEG4AAC_ELD_SBR = 'aacf', - kAudioFormatMPEG4AAC_ELD_V2 = 'aacg', - kAudioFormatMPEG4AAC_HE_V2 = 'aacp', - kAudioFormatMPEG4AAC_Spatial = 'aacs', - kAudioFormatAMR = 'samr', - kAudioFormatAudible = 'AUDB', - kAudioFormatiLBC = 'ilbc', - kAudioFormatDVIIntelIMA = 0x6D730011, - kAudioFormatMicrosoftGSM = 0x6D730031, - kAudioFormatAES3 = 'aes3' +enum { kAudioFormatFlagIsFloat = (1L << 0), + kAudioFormatFlagIsBigEndian = (1L << 1), + kAudioFormatFlagIsSignedInteger = (1L << 2), + kAudioFormatFlagIsPacked = (1L << 3), + kAudioFormatFlagIsAlignedHigh = (1L << 4), + kAudioFormatFlagIsNonInterleaved = (1L << 5), + kAudioFormatFlagIsNonMixable = (1L << 6), + kAudioFormatFlagsAreAllClear = (1L << 31), + + kLinearPCMFormatFlagIsFloat = kAudioFormatFlagIsFloat, + kLinearPCMFormatFlagIsBigEndian = kAudioFormatFlagIsBigEndian, + kLinearPCMFormatFlagIsSignedInteger = kAudioFormatFlagIsSignedInteger, + kLinearPCMFormatFlagIsPacked = kAudioFormatFlagIsPacked, + kLinearPCMFormatFlagIsAlignedHigh = kAudioFormatFlagIsAlignedHigh, + kLinearPCMFormatFlagIsNonInterleaved = kAudioFormatFlagIsNonInterleaved, + kLinearPCMFormatFlagIsNonMixable = kAudioFormatFlagIsNonMixable, + kLinearPCMFormatFlagsAreAllClear = kAudioFormatFlagsAreAllClear, + + kAppleLosslessFormatFlag_16BitSourceData = 1, + kAppleLosslessFormatFlag_20BitSourceData = 2, + kAppleLosslessFormatFlag_24BitSourceData = 3, + kAppleLosslessFormatFlag_32BitSourceData = 4, }; -enum { - kAudioFormatFlagIsFloat = (1L << 0), - kAudioFormatFlagIsBigEndian = (1L << 1), - kAudioFormatFlagIsSignedInteger = (1L << 2), - kAudioFormatFlagIsPacked = (1L << 3), - kAudioFormatFlagIsAlignedHigh = (1L << 4), - kAudioFormatFlagIsNonInterleaved = (1L << 5), - kAudioFormatFlagIsNonMixable = (1L << 6), - kAudioFormatFlagsAreAllClear = (1L << 31), - - kLinearPCMFormatFlagIsFloat = - kAudioFormatFlagIsFloat, - kLinearPCMFormatFlagIsBigEndian = - kAudioFormatFlagIsBigEndian, - kLinearPCMFormatFlagIsSignedInteger = - kAudioFormatFlagIsSignedInteger, - kLinearPCMFormatFlagIsPacked = - kAudioFormatFlagIsPacked, - kLinearPCMFormatFlagIsAlignedHigh = - kAudioFormatFlagIsAlignedHigh, - kLinearPCMFormatFlagIsNonInterleaved = - kAudioFormatFlagIsNonInterleaved, - kLinearPCMFormatFlagIsNonMixable = - kAudioFormatFlagIsNonMixable, - kLinearPCMFormatFlagsAreAllClear = - kAudioFormatFlagsAreAllClear, - - kAppleLosslessFormatFlag_16BitSourceData = 1, - kAppleLosslessFormatFlag_20BitSourceData = 2, - kAppleLosslessFormatFlag_24BitSourceData = 3, - kAppleLosslessFormatFlag_32BitSourceData = 4 -}; - -enum { - kAudioFormatFlagsNativeEndian = 0, -}; +enum { kAudioFormatFlagsNativeEndian = 0 }; enum { // AudioStreamBasicDescription structure properties - kAudioFormatProperty_FormatInfo = 'fmti', - kAudioFormatProperty_FormatName = 'fnam', - kAudioFormatProperty_EncodeFormatIDs = 'acof', - kAudioFormatProperty_DecodeFormatIDs = 'acif', - kAudioFormatProperty_FormatList = 'flst', - kAudioFormatProperty_ASBDFromESDS = 'essd', - kAudioFormatProperty_ChannelLayoutFromESDS = 'escl', - kAudioFormatProperty_OutputFormatList = 'ofls', - kAudioFormatProperty_Encoders = 'aven', - kAudioFormatProperty_Decoders = 'avde', - kAudioFormatProperty_FormatIsVBR = 'fvbr', - kAudioFormatProperty_FormatIsExternallyFramed = 'fexf', - kAudioFormatProperty_AvailableEncodeBitRates = 'aebr', - kAudioFormatProperty_AvailableEncodeSampleRates = 'aesr', + kAudioFormatProperty_FormatInfo = 'fmti', + kAudioFormatProperty_FormatName = 'fnam', + kAudioFormatProperty_EncodeFormatIDs = 'acof', + kAudioFormatProperty_DecodeFormatIDs = 'acif', + kAudioFormatProperty_FormatList = 'flst', + kAudioFormatProperty_ASBDFromESDS = 'essd', + kAudioFormatProperty_ChannelLayoutFromESDS = 'escl', + kAudioFormatProperty_OutputFormatList = 'ofls', + kAudioFormatProperty_Encoders = 'aven', + kAudioFormatProperty_Decoders = 'avde', + kAudioFormatProperty_FormatIsVBR = 'fvbr', + kAudioFormatProperty_FormatIsExternallyFramed = 'fexf', + kAudioFormatProperty_AvailableEncodeBitRates = 'aebr', + kAudioFormatProperty_AvailableEncodeSampleRates = 'aesr', kAudioFormatProperty_AvailableEncodeChannelLayoutTags = 'aecl', - kAudioFormatProperty_AvailableEncodeNumberChannels = 'avnc', - kAudioFormatProperty_ASBDFromMPEGPacket = 'admp', + kAudioFormatProperty_AvailableEncodeNumberChannels = 'avnc', + kAudioFormatProperty_ASBDFromMPEGPacket = 'admp', // // AudioChannelLayout structure properties - kAudioFormatProperty_BitmapForLayoutTag = 'bmtg', - kAudioFormatProperty_MatrixMixMap = 'mmap', - kAudioFormatProperty_ChannelMap = 'chmp', - kAudioFormatProperty_NumberOfChannelsForLayout = 'nchm', - kAudioFormatProperty_ValidateChannelLayout = 'vacl', - kAudioFormatProperty_ChannelLayoutForTag = 'cmpl', - kAudioFormatProperty_TagForChannelLayout = 'cmpt', - kAudioFormatProperty_ChannelLayoutName = 'lonm', - kAudioFormatProperty_ChannelLayoutSimpleName = 'lsnm', - kAudioFormatProperty_ChannelLayoutForBitmap = 'cmpb', - kAudioFormatProperty_ChannelName = 'cnam', - kAudioFormatProperty_ChannelShortName = 'csnm', - kAudioFormatProperty_TagsForNumberOfChannels = 'tagc', - kAudioFormatProperty_PanningMatrix = 'panm', - kAudioFormatProperty_BalanceFade = 'balf', + kAudioFormatProperty_BitmapForLayoutTag = 'bmtg', + kAudioFormatProperty_MatrixMixMap = 'mmap', + kAudioFormatProperty_ChannelMap = 'chmp', + kAudioFormatProperty_NumberOfChannelsForLayout = 'nchm', + kAudioFormatProperty_ValidateChannelLayout = 'vacl', + kAudioFormatProperty_ChannelLayoutForTag = 'cmpl', + kAudioFormatProperty_TagForChannelLayout = 'cmpt', + kAudioFormatProperty_ChannelLayoutName = 'lonm', + kAudioFormatProperty_ChannelLayoutSimpleName = 'lsnm', + kAudioFormatProperty_ChannelLayoutForBitmap = 'cmpb', + kAudioFormatProperty_ChannelName = 'cnam', + kAudioFormatProperty_ChannelShortName = 'csnm', + kAudioFormatProperty_TagsForNumberOfChannels = 'tagc', + kAudioFormatProperty_PanningMatrix = 'panm', + kAudioFormatProperty_BalanceFade = 'balf', // // ID3 tag (MP3 metadata) properties - kAudioFormatProperty_ID3TagSize = 'id3s', - kAudioFormatProperty_ID3TagToDictionary = 'id3d' + kAudioFormatProperty_ID3TagSize = 'id3s', + kAudioFormatProperty_ID3TagToDictionary = 'id3d', }; -enum { - kAudioConverterPropertyMinimumInputBufferSize = 'mibs', - kAudioConverterPropertyMinimumOutputBufferSize = 'mobs', - kAudioConverterPropertyMaximumInputBufferSize = 'xibs', - kAudioConverterPropertyMaximumInputPacketSize = 'xips', - kAudioConverterPropertyMaximumOutputPacketSize = 'xops', - kAudioConverterPropertyCalculateInputBufferSize = 'cibs', - kAudioConverterPropertyCalculateOutputBufferSize = 'cobs', - kAudioConverterPropertyInputCodecParameters = 'icdp', - kAudioConverterPropertyOutputCodecParameters = 'ocdp', - kAudioConverterSampleRateConverterAlgorithm = 'srci', - kAudioConverterSampleRateConverterComplexity = 'srca', - kAudioConverterSampleRateConverterQuality = 'srcq', - kAudioConverterSampleRateConverterInitialPhase = 'srcp', - kAudioConverterCodecQuality = 'cdqu', - kAudioConverterPrimeMethod = 'prmm', - kAudioConverterPrimeInfo = 'prim', - kAudioConverterChannelMap = 'chmp', - kAudioConverterDecompressionMagicCookie = 'dmgc', - kAudioConverterCompressionMagicCookie = 'cmgc', - kAudioConverterEncodeBitRate = 'brat', - kAudioConverterEncodeAdjustableSampleRate = 'ajsr', - kAudioConverterInputChannelLayout = 'icl ', - kAudioConverterOutputChannelLayout = 'ocl ', - kAudioConverterApplicableEncodeBitRates = 'aebr', - kAudioConverterAvailableEncodeBitRates = 'vebr', - kAudioConverterApplicableEncodeSampleRates = 'aesr', - kAudioConverterAvailableEncodeSampleRates = 'vesr', - kAudioConverterAvailableEncodeChannelLayoutTags = 'aecl', - kAudioConverterCurrentOutputStreamDescription = 'acod', - kAudioConverterCurrentInputStreamDescription = 'acid', - kAudioConverterPropertySettings = 'acps', - kAudioConverterPropertyBitDepthHint = 'acbd', - kAudioConverterPropertyFormatList = 'flst', +enum { kAudioConverterPropertyMinimumInputBufferSize = 'mibs', + kAudioConverterPropertyMinimumOutputBufferSize = 'mobs', + kAudioConverterPropertyMaximumInputBufferSize = 'xibs', + kAudioConverterPropertyMaximumInputPacketSize = 'xips', + kAudioConverterPropertyMaximumOutputPacketSize = 'xops', + kAudioConverterPropertyCalculateInputBufferSize = 'cibs', + kAudioConverterPropertyCalculateOutputBufferSize = 'cobs', + kAudioConverterPropertyInputCodecParameters = 'icdp', + kAudioConverterPropertyOutputCodecParameters = 'ocdp', + kAudioConverterSampleRateConverterAlgorithm = 'srci', + kAudioConverterSampleRateConverterComplexity = 'srca', + kAudioConverterSampleRateConverterQuality = 'srcq', + kAudioConverterSampleRateConverterInitialPhase = 'srcp', + kAudioConverterCodecQuality = 'cdqu', + kAudioConverterPrimeMethod = 'prmm', + kAudioConverterPrimeInfo = 'prim', + kAudioConverterChannelMap = 'chmp', + kAudioConverterDecompressionMagicCookie = 'dmgc', + kAudioConverterCompressionMagicCookie = 'cmgc', + kAudioConverterEncodeBitRate = 'brat', + kAudioConverterEncodeAdjustableSampleRate = 'ajsr', + kAudioConverterInputChannelLayout = 'icl ', + kAudioConverterOutputChannelLayout = 'ocl ', + kAudioConverterApplicableEncodeBitRates = 'aebr', + kAudioConverterAvailableEncodeBitRates = 'vebr', + kAudioConverterApplicableEncodeSampleRates = 'aesr', + kAudioConverterAvailableEncodeSampleRates = 'vesr', + kAudioConverterAvailableEncodeChannelLayoutTags = 'aecl', + kAudioConverterCurrentOutputStreamDescription = 'acod', + kAudioConverterCurrentInputStreamDescription = 'acid', + kAudioConverterPropertySettings = 'acps', + kAudioConverterPropertyBitDepthHint = 'acbd', + kAudioConverterPropertyFormatList = 'flst', }; -enum { - kAudioConverterQuality_Max = 0x7F, - kAudioConverterQuality_High = 0x60, - kAudioConverterQuality_Medium = 0x40, - kAudioConverterQuality_Low = 0x20, - kAudioConverterQuality_Min = 0 +enum { kAudioConverterQuality_Max = 0x7F, + kAudioConverterQuality_High = 0x60, + kAudioConverterQuality_Medium = 0x40, + kAudioConverterQuality_Low = 0x20, + kAudioConverterQuality_Min = 0, }; -enum { - kAudio_UnimplementedError = -4, - kAudio_FileNotFoundError = -43, - kAudio_FilePermissionError = -54, - kAudio_TooManyFilesOpenError = -42, - kAudio_BadFilePathError = '!pth', // 0x21707468, 561017960 - kAudio_ParamError = -50, - kAudio_MemFullError = -108, +enum { kAudio_UnimplementedError = -4, + kAudio_FileNotFoundError = -43, + kAudio_FilePermissionError = -54, + kAudio_TooManyFilesOpenError = -42, + kAudio_BadFilePathError = '!pth', // 0x21707468, 561017960 + kAudio_ParamError = -50, + kAudio_MemFullError = -108, - kAudioConverterErr_FormatNotSupported = 'fmt?', - kAudioConverterErr_OperationNotSupported = 0x6F703F3F, - // 'op??', integer used because of trigraph - kAudioConverterErr_PropertyNotSupported = 'prop', - kAudioConverterErr_InvalidInputSize = 'insz', - kAudioConverterErr_InvalidOutputSize = 'otsz', - // e.g. byte size is not a multiple of the frame size - kAudioConverterErr_UnspecifiedError = 'what', - kAudioConverterErr_BadPropertySizeError = '!siz', - kAudioConverterErr_RequiresPacketDescriptionsError = '!pkd', - kAudioConverterErr_InputSampleRateOutOfRange = '!isr', - kAudioConverterErr_OutputSampleRateOutOfRange = '!osr' + kAudioConverterErr_FormatNotSupported = 'fmt?', + kAudioConverterErr_OperationNotSupported = 0x6F703F3F, + // 'op??', integer used because of trigraph + kAudioConverterErr_PropertyNotSupported = 'prop', + kAudioConverterErr_InvalidInputSize = 'insz', + kAudioConverterErr_InvalidOutputSize = 'otsz', + // e.g. byte size is not a multiple of the frame size + kAudioConverterErr_UnspecifiedError = 'what', + kAudioConverterErr_BadPropertySizeError = '!siz', + kAudioConverterErr_RequiresPacketDescriptionsError = '!pkd', + kAudioConverterErr_InputSampleRateOutOfRange = '!isr', + kAudioConverterErr_OutputSampleRateOutOfRange = '!osr', }; -typedef OSStatus (*AudioConverterNew_t) ( +typedef OSStatus (*AudioConverterNew_t)( const AudioStreamBasicDescription *inSourceFormat, const AudioStreamBasicDescription *inDestinationFormat, - AudioConverterRef *outAudioConverter -); + AudioConverterRef *outAudioConverter); -typedef OSStatus (*AudioConverterDispose_t) ( - AudioConverterRef inAudioConverter -); +typedef OSStatus (*AudioConverterDispose_t)(AudioConverterRef inAudioConverter); -typedef OSStatus (*AudioConverterReset_t) ( - AudioConverterRef inAudioConverter -); +typedef OSStatus (*AudioConverterReset_t)(AudioConverterRef inAudioConverter); -typedef OSStatus (*AudioConverterGetProperty_t) ( - AudioConverterRef inAudioConverter, - AudioConverterPropertyID inPropertyID, - UInt32 *ioPropertyDataSize, - void *outPropertyData -); +typedef OSStatus (*AudioConverterGetProperty_t)( + AudioConverterRef inAudioConverter, + AudioConverterPropertyID inPropertyID, UInt32 *ioPropertyDataSize, + void *outPropertyData); -typedef OSStatus (*AudioConverterGetPropertyInfo_t) ( - AudioConverterRef inAudioConverter, - AudioConverterPropertyID inPropertyID, - UInt32 *outSize, - Boolean *outWritable -); +typedef OSStatus (*AudioConverterGetPropertyInfo_t)( + AudioConverterRef inAudioConverter, + AudioConverterPropertyID inPropertyID, UInt32 *outSize, + Boolean *outWritable); -typedef OSStatus (*AudioConverterSetProperty_t) ( - AudioConverterRef inAudioConverter, - AudioConverterPropertyID inPropertyID, - UInt32 inPropertyDataSize, - const void *inPropertyData -); +typedef OSStatus (*AudioConverterSetProperty_t)( + AudioConverterRef inAudioConverter, + AudioConverterPropertyID inPropertyID, UInt32 inPropertyDataSize, + const void *inPropertyData); -typedef OSStatus (*AudioConverterFillComplexBuffer_t) ( - AudioConverterRef inAudioConverter, +typedef OSStatus (*AudioConverterFillComplexBuffer_t)( + AudioConverterRef inAudioConverter, AudioConverterComplexInputDataProc inInputDataProc, - void *inInputDataProcUserData, - UInt32 *ioOutputDataPacketSize, - AudioBufferList *outOutputData, - AudioStreamPacketDescription *outPacketDescription -); + void *inInputDataProcUserData, UInt32 *ioOutputDataPacketSize, + AudioBufferList *outOutputData, + AudioStreamPacketDescription *outPacketDescription); -typedef OSStatus (*AudioFormatGetProperty_t) ( - AudioFormatPropertyID inPropertyID, - UInt32 inSpecifierSize, - const void *inSpecifier, - UInt32 *ioPropertyDataSize, - void *outPropertyData -); +typedef OSStatus (*AudioFormatGetProperty_t)(AudioFormatPropertyID inPropertyID, + UInt32 inSpecifierSize, + const void *inSpecifier, + UInt32 *ioPropertyDataSize, + void *outPropertyData); -typedef OSStatus (*AudioFormatGetPropertyInfo_t) ( - AudioFormatPropertyID inPropertyID, - UInt32 inSpecifierSize, - const void *inSpecifier, - UInt32 *outPropertyDataSize -); +typedef OSStatus (*AudioFormatGetPropertyInfo_t)( + AudioFormatPropertyID inPropertyID, UInt32 inSpecifierSize, + const void *inSpecifier, UInt32 *outPropertyDataSize); static AudioConverterNew_t AudioConverterNew = NULL; static AudioConverterDispose_t AudioConverterDispose = NULL; @@ -383,9 +343,10 @@ static HMODULE audio_toolbox = NULL; static void release_lib(void) { -#define RELEASE_LIB(x) if (x) { \ +#define RELEASE_LIB(x) \ + if (x) { \ FreeLibrary(x); \ - x = NULL; \ + x = NULL; \ } RELEASE_LIB(audio_toolbox); @@ -396,12 +357,12 @@ static bool load_lib(void) { PWSTR common_path; if (SHGetKnownFolderPath(FOLDERID_ProgramFilesCommon, 0, NULL, - &common_path) != S_OK) { + &common_path) != S_OK) { CA_LOG(LOG_WARNING, "Could not retrieve common files path"); return false; } - struct dstr path = { 0 }; + struct dstr path = {0}; dstr_printf(&path, "%S\\Apple\\Apple Application Support", common_path); CoTaskMemFree(common_path); @@ -411,8 +372,9 @@ static bool load_lib(void) SetDllDirectory(w_path); bfree(w_path); -#define LOAD_LIB(x, n) x = LoadLibrary(TEXT(n)); \ - if (!x) \ +#define LOAD_LIB(x, n) \ + x = LoadLibrary(TEXT(n)); \ + if (!x) \ CA_LOG(LOG_DEBUG, "Failed loading library '" n "'"); LOAD_LIB(audio_toolbox, "CoreAudioToolbox.dll"); @@ -444,19 +406,20 @@ static void unload_core_audio(void) #ifdef _MSC_VER #pragma warning(push) -#pragma warning(disable: 4706) +#pragma warning(disable : 4706) #endif static bool load_core_audio(void) { if (!load_lib()) return false; -#define LOAD_SYM_FROM_LIB(sym, lib, dll) \ - if (!(sym = (sym ## _t)GetProcAddress(lib, #sym))) { \ - DWORD err = GetLastError(); \ - CA_LOG(LOG_ERROR, "Couldn't load " #sym " from " \ - dll ": %lu (0x%lx)", err, err); \ - goto unload_everything; \ +#define LOAD_SYM_FROM_LIB(sym, lib, dll) \ + if (!(sym = (sym##_t)GetProcAddress(lib, #sym))) { \ + DWORD err = GetLastError(); \ + CA_LOG(LOG_ERROR, \ + "Couldn't load " #sym " from " dll ": %lu (0x%lx)", \ + err, err); \ + goto unload_everything; \ } #define LOAD_SYM(sym) \ diff --git a/plugins/decklink/DecklinkBase.cpp b/plugins/decklink/DecklinkBase.cpp index e916a24..b7ba6ad 100644 --- a/plugins/decklink/DecklinkBase.cpp +++ b/plugins/decklink/DecklinkBase.cpp @@ -1,7 +1,7 @@ #include "DecklinkBase.h" DecklinkBase::DecklinkBase(DeckLinkDeviceDiscovery *discovery_) - : discovery(discovery_) + : discovery(discovery_) { } @@ -10,11 +10,9 @@ DeckLinkDevice *DecklinkBase::GetDevice() const return instance ? instance->GetDevice() : nullptr; } -bool DecklinkBase::Activate(DeckLinkDevice*, long long) +bool DecklinkBase::Activate(DeckLinkDevice *, long long) { return false; } -void DecklinkBase::Deactivate() -{ -} +void DecklinkBase::Deactivate() {} diff --git a/plugins/decklink/DecklinkBase.h b/plugins/decklink/DecklinkBase.h index a337092..a8f9f48 100644 --- a/plugins/decklink/DecklinkBase.h +++ b/plugins/decklink/DecklinkBase.h @@ -16,14 +16,14 @@ class DecklinkBase { protected: DecklinkBase(DeckLinkDeviceDiscovery *discovery_); - ComPtr instance; - DeckLinkDeviceDiscovery *discovery; - std::recursive_mutex deviceMutex; - volatile long activateRefs = 0; - BMDPixelFormat pixelFormat = bmdFormat8BitYUV; - video_colorspace colorSpace = VIDEO_CS_DEFAULT; - video_range_type colorRange = VIDEO_RANGE_DEFAULT; - speaker_layout channelFormat = SPEAKERS_STEREO; + ComPtr instance; + DeckLinkDeviceDiscovery *discovery; + std::recursive_mutex deviceMutex; + volatile long activateRefs = 0; + BMDPixelFormat pixelFormat = bmdFormat8BitYUV; + video_colorspace colorSpace = VIDEO_CS_DEFAULT; + video_range_type colorRange = VIDEO_RANGE_DEFAULT; + speaker_layout channelFormat = SPEAKERS_STEREO; public: virtual bool Activate(DeckLinkDevice *device, long long modeId); diff --git a/plugins/decklink/DecklinkInput.cpp b/plugins/decklink/DecklinkInput.cpp index 0f74aa6..965f4dd 100644 --- a/plugins/decklink/DecklinkInput.cpp +++ b/plugins/decklink/DecklinkInput.cpp @@ -2,9 +2,9 @@ #include -DeckLinkInput::DeckLinkInput(obs_source_t *source, DeckLinkDeviceDiscovery *discovery_) - : DecklinkBase(discovery_), - source(source) +DeckLinkInput::DeckLinkInput(obs_source_t *source, + DeckLinkDeviceDiscovery *discovery_) + : DecklinkBase(discovery_), source(source) { discovery->AddCallback(DeckLinkInput::DevicesChanged, this); } @@ -15,9 +15,10 @@ DeckLinkInput::~DeckLinkInput(void) Deactivate(); } -void DeckLinkInput::DevicesChanged(void *param, DeckLinkDevice *device, bool added) +void DeckLinkInput::DevicesChanged(void *param, DeckLinkDevice *device, + bool added) { - DeckLinkInput *decklink = reinterpret_cast(param); + DeckLinkInput *decklink = reinterpret_cast(param); std::lock_guard lock(decklink->deviceMutex); obs_source_update_properties(decklink->source); @@ -31,15 +32,18 @@ void DeckLinkInput::DevicesChanged(void *param, DeckLinkDevice *device, bool add settings = obs_source_get_settings(decklink->source); hash = obs_data_get_string(settings, "device_hash"); - videoConnection = (BMDVideoConnection) obs_data_get_int(settings, "video_connection"); - audioConnection = (BMDAudioConnection) obs_data_get_int(settings, "audio_connection"); + videoConnection = (BMDVideoConnection)obs_data_get_int( + settings, "video_connection"); + audioConnection = (BMDAudioConnection)obs_data_get_int( + settings, "audio_connection"); mode = obs_data_get_int(settings, "mode_id"); obs_data_release(settings); if (device->GetHash().compare(hash) == 0) { if (!decklink->activateRefs) return; - if (decklink->Activate(device, mode, videoConnection, audioConnection)) + if (decklink->Activate(device, mode, videoConnection, + audioConnection)) os_atomic_dec_long(&decklink->activateRefs); } @@ -52,8 +56,8 @@ void DeckLinkInput::DevicesChanged(void *param, DeckLinkDevice *device, bool add } bool DeckLinkInput::Activate(DeckLinkDevice *device, long long modeId, - BMDVideoConnection bmdVideoConnection, - BMDAudioConnection bmdAudioConnection) + BMDVideoConnection bmdVideoConnection, + BMDAudioConnection bmdAudioConnection) { std::lock_guard lock(deviceMutex); DeckLinkDevice *curDevice = GetDevice(); @@ -85,7 +89,8 @@ bool DeckLinkInput::Activate(DeckLinkDevice *device, long long modeId, return false; if (GetDevice() == nullptr) { - LOG(LOG_ERROR, "Tried to activate an input with nullptr device."); + LOG(LOG_ERROR, + "Tried to activate an input with nullptr device."); return false; } @@ -95,7 +100,8 @@ bool DeckLinkInput::Activate(DeckLinkDevice *device, long long modeId, return false; } - if (!instance->StartCapture(mode, bmdVideoConnection, bmdAudioConnection)) { + if (!instance->StartCapture(mode, bmdVideoConnection, + bmdAudioConnection)) { instance = nullptr; return false; } @@ -133,10 +139,9 @@ void DeckLinkInput::SaveSettings() obs_data_t *settings = obs_source_get_settings(source); - obs_data_set_string(settings, "device_hash", - device->GetHash().c_str()); + obs_data_set_string(settings, "device_hash", device->GetHash().c_str()); obs_data_set_string(settings, "device_name", - device->GetDisplayName().c_str()); + device->GetDisplayName().c_str()); obs_data_set_int(settings, "mode_id", instance->GetActiveModeId()); obs_data_set_string(settings, "mode_name", mode->GetName().c_str()); diff --git a/plugins/decklink/DecklinkInput.hpp b/plugins/decklink/DecklinkInput.hpp index c90dd7e..17809f7 100644 --- a/plugins/decklink/DecklinkInput.hpp +++ b/plugins/decklink/DecklinkInput.hpp @@ -4,12 +4,12 @@ class DeckLinkInput : public DecklinkBase { protected: - bool isCapturing = false; - obs_source_t *source; + bool isCapturing = false; + obs_source_t *source; void SaveSettings(); static void DevicesChanged(void *param, DeckLinkDevice *device, - bool added); + bool added); public: DeckLinkInput(obs_source_t *source, DeckLinkDeviceDiscovery *discovery); @@ -18,30 +18,30 @@ public: long long GetActiveModeId(void) const; obs_source_t *GetSource(void) const; - inline BMDPixelFormat GetPixelFormat() const {return pixelFormat;} + inline BMDPixelFormat GetPixelFormat() const { return pixelFormat; } inline void SetPixelFormat(BMDPixelFormat format) { pixelFormat = format; } - inline video_colorspace GetColorSpace() const {return colorSpace;} + inline video_colorspace GetColorSpace() const { return colorSpace; } inline void SetColorSpace(video_colorspace format) { colorSpace = format; } - inline video_range_type GetColorRange() const {return colorRange;} + inline video_range_type GetColorRange() const { return colorRange; } inline void SetColorRange(video_range_type format) { colorRange = format; } - inline speaker_layout GetChannelFormat() const {return channelFormat;} + inline speaker_layout GetChannelFormat() const { return channelFormat; } inline void SetChannelFormat(speaker_layout format) { channelFormat = format; } bool Activate(DeckLinkDevice *device, long long modeId, - BMDVideoConnection bmdVideoConnection, - BMDAudioConnection bmdAudioConnection); + BMDVideoConnection bmdVideoConnection, + BMDAudioConnection bmdAudioConnection); void Deactivate(); bool Capturing(); diff --git a/plugins/decklink/DecklinkOutput.cpp b/plugins/decklink/DecklinkOutput.cpp index 40eaf33..d9b4304 100644 --- a/plugins/decklink/DecklinkOutput.cpp +++ b/plugins/decklink/DecklinkOutput.cpp @@ -2,9 +2,9 @@ #include -DeckLinkOutput::DeckLinkOutput(obs_output_t *output, DeckLinkDeviceDiscovery *discovery_) - : DecklinkBase(discovery_), - output(output) +DeckLinkOutput::DeckLinkOutput(obs_output_t *output, + DeckLinkDeviceDiscovery *discovery_) + : DecklinkBase(discovery_), output(output) { discovery->AddCallback(DeckLinkOutput::DevicesChanged, this); } @@ -17,7 +17,7 @@ DeckLinkOutput::~DeckLinkOutput(void) void DeckLinkOutput::DevicesChanged(void *param, DeckLinkDevice *device, bool) { - auto *decklink = reinterpret_cast(param); + auto *decklink = reinterpret_cast(param); std::lock_guard lock(decklink->deviceMutex); blog(LOG_DEBUG, "%s", device->GetHash().c_str()); @@ -35,10 +35,10 @@ bool DeckLinkOutput::Activate(DeckLinkDevice *device, long long modeId) return false; if (instance->GetActiveModeId() == modeId && - instance->GetActivePixelFormat() == pixelFormat && - instance->GetActiveColorSpace() == colorSpace && - instance->GetActiveColorRange() == colorRange && - instance->GetActiveChannelFormat() == channelFormat) + instance->GetActivePixelFormat() == pixelFormat && + instance->GetActiveColorSpace() == colorSpace && + instance->GetActiveColorRange() == colorRange && + instance->GetActiveChannelFormat() == channelFormat) return false; } @@ -57,7 +57,6 @@ bool DeckLinkOutput::Activate(DeckLinkDevice *device, long long modeId) return false; } - if (!instance->StartOutput(mode)) { instance = nullptr; return false; diff --git a/plugins/decklink/DecklinkOutput.hpp b/plugins/decklink/DecklinkOutput.hpp index 0a4fe85..598206f 100644 --- a/plugins/decklink/DecklinkOutput.hpp +++ b/plugins/decklink/DecklinkOutput.hpp @@ -10,7 +10,8 @@ protected: int width; int height; - static void DevicesChanged(void *param, DeckLinkDevice *device, bool added); + static void DevicesChanged(void *param, DeckLinkDevice *device, + bool added); public: const char *deviceHash; @@ -21,7 +22,8 @@ public: size_t audio_size; int keyerMode; - DeckLinkOutput(obs_output_t *output, DeckLinkDeviceDiscovery *discovery); + DeckLinkOutput(obs_output_t *output, + DeckLinkDeviceDiscovery *discovery); virtual ~DeckLinkOutput(void); obs_output_t *GetOutput(void) const; bool Activate(DeckLinkDevice *device, long long modeId) override; diff --git a/plugins/decklink/audio-repack.c b/plugins/decklink/audio-repack.c index ec92f76..8c59af5 100644 --- a/plugins/decklink/audio-repack.c +++ b/plugins/decklink/audio-repack.c @@ -2,15 +2,14 @@ #include -int check_buffer(struct audio_repack *repack, - uint32_t frame_count) +int check_buffer(struct audio_repack *repack, uint32_t frame_count) { - const uint32_t new_size = frame_count * repack->base_dst_size - + repack->extra_dst_size; + const uint32_t new_size = + frame_count * repack->base_dst_size + repack->extra_dst_size; if (repack->packet_size < new_size) { - repack->packet_buffer = brealloc( - repack->packet_buffer, new_size); + repack->packet_buffer = + brealloc(repack->packet_buffer, new_size); if (!repack->packet_buffer) return -1; @@ -30,8 +29,8 @@ int check_buffer(struct audio_repack *repack, * | FL | FR | LFE | */ -int repack_squash(struct audio_repack *repack, - const uint8_t *bsrc, uint32_t frame_count) +int repack_squash(struct audio_repack *repack, const uint8_t *bsrc, + uint32_t frame_count) { if (check_buffer(repack, frame_count) < 0) return -1; @@ -55,8 +54,8 @@ int repack_squash(struct audio_repack *repack, return 0; } -int repack_squash_swap(struct audio_repack *repack, - const uint8_t *bsrc, uint32_t frame_count) +int repack_squash_swap(struct audio_repack *repack, const uint8_t *bsrc, + uint32_t frame_count) { if (check_buffer(repack, frame_count) < 0) return -1; @@ -66,7 +65,8 @@ int repack_squash_swap(struct audio_repack *repack, uint16_t *dst = (uint16_t *)repack->packet_buffer; while (src != esrc) { __m128i target = _mm_load_si128(src++); - __m128i buf = _mm_shufflelo_epi16(target, _MM_SHUFFLE(2, 3, 1, 0)); + __m128i buf = + _mm_shufflelo_epi16(target, _MM_SHUFFLE(2, 3, 1, 0)); _mm_storeu_si128((__m128i *)dst, buf); dst += 8 - squash; } @@ -74,20 +74,20 @@ int repack_squash_swap(struct audio_repack *repack, } int audio_repack_init(struct audio_repack *repack, - audio_repack_mode_t repack_mode, uint8_t sample_bit) + audio_repack_mode_t repack_mode, uint8_t sample_bit) { memset(repack, 0, sizeof(*repack)); if (sample_bit != 16) return -1; - int _audio_repack_ch[8] = { 3, 4, 5, 6, 5, 6, 8, 8 }; + int _audio_repack_ch[8] = {3, 4, 5, 6, 5, 6, 8, 8}; repack->base_src_size = 8 * (16 / 8); repack->base_dst_size = _audio_repack_ch[repack_mode] * (16 / 8); repack->extra_dst_size = 8 - _audio_repack_ch[repack_mode]; repack->repack_func = &repack_squash; if (repack_mode == repack_mode_8to5ch_swap || - repack_mode == repack_mode_8to6ch_swap || - repack_mode == repack_mode_8ch_swap) + repack_mode == repack_mode_8to6ch_swap || + repack_mode == repack_mode_8ch_swap) repack->repack_func = &repack_squash_swap; return 0; diff --git a/plugins/decklink/audio-repack.h b/plugins/decklink/audio-repack.h index 448cd99..abe383b 100644 --- a/plugins/decklink/audio-repack.h +++ b/plugins/decklink/audio-repack.h @@ -11,22 +11,22 @@ extern "C" { struct audio_repack; -typedef int (*audio_repack_func_t)(struct audio_repack *, - const uint8_t *, uint32_t); +typedef int (*audio_repack_func_t)(struct audio_repack *, const uint8_t *, + uint32_t); struct audio_repack { - uint8_t *packet_buffer; - uint32_t packet_size; + uint8_t *packet_buffer; + uint32_t packet_size; - uint32_t base_src_size; - uint32_t base_dst_size; - uint32_t extra_dst_size; + uint32_t base_src_size; + uint32_t base_dst_size; + uint32_t extra_dst_size; audio_repack_func_t repack_func; }; enum _audio_repack_mode { - repack_mode_8to3ch=0, + repack_mode_8to3ch = 0, repack_mode_8to4ch, repack_mode_8to5ch, repack_mode_8to6ch, @@ -39,7 +39,8 @@ enum _audio_repack_mode { typedef enum _audio_repack_mode audio_repack_mode_t; extern int audio_repack_init(struct audio_repack *repack, - audio_repack_mode_t repack_mode, uint8_t sample_bit); + audio_repack_mode_t repack_mode, + uint8_t sample_bit); extern void audio_repack_free(struct audio_repack *repack); #ifdef __cplusplus diff --git a/plugins/decklink/audio-repack.hpp b/plugins/decklink/audio-repack.hpp index d495172..69e9365 100644 --- a/plugins/decklink/audio-repack.hpp +++ b/plugins/decklink/audio-repack.hpp @@ -10,16 +10,13 @@ public: { audio_repack_init(&arepack, repack_mode, 16); } - inline ~AudioRepacker() - { - audio_repack_free(&arepack); - } + inline ~AudioRepacker() { audio_repack_free(&arepack); } inline int repack(const uint8_t *src, uint32_t frame_size) { return (*arepack.repack_func)(&arepack, src, frame_size); } - inline operator struct audio_repack*() {return &arepack;} - inline struct audio_repack *operator->() {return &arepack;} + inline operator struct audio_repack *() { return &arepack; } + inline struct audio_repack *operator->() { return &arepack; } }; diff --git a/plugins/decklink/const.h b/plugins/decklink/const.h index 4f67a77..bde439e 100644 --- a/plugins/decklink/const.h +++ b/plugins/decklink/const.h @@ -1,41 +1,41 @@ -#define DEVICE_HASH "device_hash" -#define DEVICE_NAME "device_name" -#define VIDEO_CONNECTION "video_connection" -#define AUDIO_CONNECTION "audio_connection" -#define MODE_ID "mode_id" -#define MODE_NAME "mode_name" -#define CHANNEL_FORMAT "channel_format" -#define PIXEL_FORMAT "pixel_format" -#define COLOR_SPACE "color_space" -#define COLOR_RANGE "color_range" -#define BUFFERING "buffering" -#define DEACTIVATE_WNS "deactivate_when_not_showing" -#define AUTO_START "auto_start" -#define KEYER "keyer" -#define SWAP "swap" +#define DEVICE_HASH "device_hash" +#define DEVICE_NAME "device_name" +#define VIDEO_CONNECTION "video_connection" +#define AUDIO_CONNECTION "audio_connection" +#define MODE_ID "mode_id" +#define MODE_NAME "mode_name" +#define CHANNEL_FORMAT "channel_format" +#define PIXEL_FORMAT "pixel_format" +#define COLOR_SPACE "color_space" +#define COLOR_RANGE "color_range" +#define BUFFERING "buffering" +#define DEACTIVATE_WNS "deactivate_when_not_showing" +#define AUTO_START "auto_start" +#define KEYER "keyer" +#define SWAP "swap" -#define TEXT_DEVICE obs_module_text("Device") -#define TEXT_VIDEO_CONNECTION obs_module_text("VideoConnection") -#define TEXT_AUDIO_CONNECTION obs_module_text("AudioConnection") -#define TEXT_MODE obs_module_text("Mode") -#define TEXT_PIXEL_FORMAT obs_module_text("PixelFormat") -#define TEXT_COLOR_SPACE obs_module_text("ColorSpace") -#define TEXT_COLOR_SPACE_DEFAULT obs_module_text("ColorSpace.Default") -#define TEXT_COLOR_RANGE obs_module_text("ColorRange") -#define TEXT_COLOR_RANGE_DEFAULT obs_module_text("ColorRange.Default") -#define TEXT_COLOR_RANGE_PARTIAL obs_module_text("ColorRange.Partial") -#define TEXT_COLOR_RANGE_FULL obs_module_text("ColorRange.Full") -#define TEXT_CHANNEL_FORMAT obs_module_text("ChannelFormat") -#define TEXT_CHANNEL_FORMAT_NONE obs_module_text("ChannelFormat.None") -#define TEXT_CHANNEL_FORMAT_2_0CH obs_module_text("ChannelFormat.2_0ch") -#define TEXT_CHANNEL_FORMAT_2_1CH obs_module_text("ChannelFormat.2_1ch") -#define TEXT_CHANNEL_FORMAT_4_0CH obs_module_text("ChannelFormat.4_0ch") -#define TEXT_CHANNEL_FORMAT_4_1CH obs_module_text("ChannelFormat.4_1ch") -#define TEXT_CHANNEL_FORMAT_5_1CH obs_module_text("ChannelFormat.5_1ch") -#define TEXT_CHANNEL_FORMAT_7_1CH obs_module_text("ChannelFormat.7_1ch") -#define TEXT_BUFFERING obs_module_text("Buffering") -#define TEXT_DWNS obs_module_text("DeactivateWhenNotShowing") -#define TEXT_AUTO_START obs_module_text("AutoStart") -#define TEXT_ENABLE_KEYER obs_module_text("Keyer") -#define TEXT_SWAP obs_module_text("SwapFC-LFE") -#define TEXT_SWAP_TOOLTIP obs_module_text("SwapFC-LFE.Tooltip") +#define TEXT_DEVICE obs_module_text("Device") +#define TEXT_VIDEO_CONNECTION obs_module_text("VideoConnection") +#define TEXT_AUDIO_CONNECTION obs_module_text("AudioConnection") +#define TEXT_MODE obs_module_text("Mode") +#define TEXT_PIXEL_FORMAT obs_module_text("PixelFormat") +#define TEXT_COLOR_SPACE obs_module_text("ColorSpace") +#define TEXT_COLOR_SPACE_DEFAULT obs_module_text("ColorSpace.Default") +#define TEXT_COLOR_RANGE obs_module_text("ColorRange") +#define TEXT_COLOR_RANGE_DEFAULT obs_module_text("ColorRange.Default") +#define TEXT_COLOR_RANGE_PARTIAL obs_module_text("ColorRange.Partial") +#define TEXT_COLOR_RANGE_FULL obs_module_text("ColorRange.Full") +#define TEXT_CHANNEL_FORMAT obs_module_text("ChannelFormat") +#define TEXT_CHANNEL_FORMAT_NONE obs_module_text("ChannelFormat.None") +#define TEXT_CHANNEL_FORMAT_2_0CH obs_module_text("ChannelFormat.2_0ch") +#define TEXT_CHANNEL_FORMAT_2_1CH obs_module_text("ChannelFormat.2_1ch") +#define TEXT_CHANNEL_FORMAT_4_0CH obs_module_text("ChannelFormat.4_0ch") +#define TEXT_CHANNEL_FORMAT_4_1CH obs_module_text("ChannelFormat.4_1ch") +#define TEXT_CHANNEL_FORMAT_5_1CH obs_module_text("ChannelFormat.5_1ch") +#define TEXT_CHANNEL_FORMAT_7_1CH obs_module_text("ChannelFormat.7_1ch") +#define TEXT_BUFFERING obs_module_text("Buffering") +#define TEXT_DWNS obs_module_text("DeactivateWhenNotShowing") +#define TEXT_AUTO_START obs_module_text("AutoStart") +#define TEXT_ENABLE_KEYER obs_module_text("Keyer") +#define TEXT_SWAP obs_module_text("SwapFC-LFE") +#define TEXT_SWAP_TOOLTIP obs_module_text("SwapFC-LFE.Tooltip") diff --git a/plugins/decklink/data/locale/ar-SA.ini b/plugins/decklink/data/locale/ar-SA.ini index f26cc16..d2c827e 100644 --- a/plugins/decklink/data/locale/ar-SA.ini +++ b/plugins/decklink/data/locale/ar-SA.ini @@ -17,4 +17,6 @@ ChannelFormat.5_1ch="5.1ch" ChannelFormat.7_1ch="7.1ch" DeactivateWhenNotShowing="التعطيل عندما لا يكون ظاهراً" AutoStart="البدء تلقائياً مع التشغيل" +VideoConnection="مدخل الفيديو" +AudioConnection="مدخل الصوت" diff --git a/plugins/decklink/data/locale/de-DE.ini b/plugins/decklink/data/locale/de-DE.ini index 3bdbd6e..b21516e 100644 --- a/plugins/decklink/data/locale/de-DE.ini +++ b/plugins/decklink/data/locale/de-DE.ini @@ -1,4 +1,4 @@ -BlackmagicDevice="Blackmagic-Gerät" +BlackmagicDevice="Blackmagic‐Gerät" Device="Gerät" Mode="Modus" Buffering="Puffern benutzen" @@ -11,16 +11,16 @@ ColorRange.Partial="Begrenzt" ColorRange.Full="Voll" ChannelFormat="Kanal" ChannelFormat.None="Keins" -ChannelFormat.2_0ch="2 Kanal" -ChannelFormat.2_1ch="2.1 Kanal" -ChannelFormat.4_0ch="4 Kanal" -ChannelFormat.4_1ch="4.1 Kanal" -ChannelFormat.5_1ch="5.1 Kanal" -ChannelFormat.7_1ch="7.1 Kanal" +ChannelFormat.2_0ch="2‐Kanal" +ChannelFormat.2_1ch="2.1‐Kanal" +ChannelFormat.4_0ch="4‐Kanal" +ChannelFormat.4_1ch="4.1‐Kanal" +ChannelFormat.5_1ch="5.1‐Kanal" +ChannelFormat.7_1ch="7.1‐Kanal" DeactivateWhenNotShowing="Deaktivieren, wenn die Quelle nicht angezeigt wird" AutoStart="Automatisch beim Öffnen starten" SwapFC-LFE="FC und LFE tauschen" -SwapFC-LFE.Tooltip="Vorderen Front-Center-Kanal und LFE-Kanal tauschen" +SwapFC-LFE.Tooltip="Vorderen Front‐Center‐Kanal und LFE‐Kanal tauschen" VideoConnection="Videoverbindung" AudioConnection="Audioverbindung" diff --git a/plugins/decklink/data/locale/gl-ES.ini b/plugins/decklink/data/locale/gl-ES.ini index 48923b9..dc0f29c 100644 --- a/plugins/decklink/data/locale/gl-ES.ini +++ b/plugins/decklink/data/locale/gl-ES.ini @@ -1,5 +1,26 @@ BlackmagicDevice="Dispositivo Blackmagic" Device="Dispositivo" Mode="Modo" -Buffering="Utilizar o almacenamento no búfer" +Buffering="Utilizar o almacenamento na memoria temporal" +PixelFormat="Formato do píxel" +ColorSpace="Espazo de cor" +ColorSpace.Default="Predeterminado" +ColorRange="Gama de cores" +ColorRange.Default="Predeterminado" +ColorRange.Partial="Parcial" +ColorRange.Full="Total" +ChannelFormat="Canle" +ChannelFormat.None="Ningún" +ChannelFormat.2_0ch="2ch" +ChannelFormat.2_1ch="2.1ch" +ChannelFormat.4_0ch="4ch" +ChannelFormat.4_1ch="4.1ch" +ChannelFormat.5_1ch="5.1ch" +ChannelFormat.7_1ch="7.1ch" +DeactivateWhenNotShowing="Desactivado cando non se amose" +AutoStart="Comezar no inicio" +SwapFC-LFE="Intercambiar FC e LFE" +SwapFC-LFE.Tooltip="Intercambiar a canle central frontal e a canle LFE" +VideoConnection="Conexión de vídeo" +AudioConnection="Conexión de son" diff --git a/plugins/decklink/data/locale/ro-RO.ini b/plugins/decklink/data/locale/ro-RO.ini index 24515cf..7949ca6 100644 --- a/plugins/decklink/data/locale/ro-RO.ini +++ b/plugins/decklink/data/locale/ro-RO.ini @@ -2,7 +2,13 @@ BlackmagicDevice="Dispozitiv Blackmagic" Device="Dispozitiv" Mode="Mod" Buffering="Folosește zona tampon" -PixelFormat="Formatul pixelilor" +PixelFormat="Format pentru pixeli" +ColorSpace="Spațiu de culori" ColorSpace.Default="Implicit" +ColorRange="Gamă de culori" ColorRange.Default="Implicit" +ColorRange.Partial="Parțială" +ColorRange.Full="Completă" +VideoConnection="Conexiune video" +AudioConnection="Conexiune audio" diff --git a/plugins/decklink/data/locale/sl-SI.ini b/plugins/decklink/data/locale/sl-SI.ini index 97066ba..6c9c243 100644 --- a/plugins/decklink/data/locale/sl-SI.ini +++ b/plugins/decklink/data/locale/sl-SI.ini @@ -2,4 +2,25 @@ BlackmagicDevice="Blackmagic naprave" Device="Naprava" Mode="Način" Buffering="Uporabi medpomnilnik" +PixelFormat="Oblika sl. točk" +ColorSpace="Barvni prostor" +ColorSpace.Default="Privzeto" +ColorRange="Barvni razpon" +ColorRange.Default="Privzeto" +ColorRange.Partial="Delno" +ColorRange.Full="Polno" +ChannelFormat="Kanal" +ChannelFormat.None="Brez" +ChannelFormat.2_0ch="2 kan." +ChannelFormat.2_1ch="2.1 kan." +ChannelFormat.4_0ch="4 kan." +ChannelFormat.4_1ch="4.1 kan." +ChannelFormat.5_1ch="5.1 kan." +ChannelFormat.7_1ch="7.1 kan." +DeactivateWhenNotShowing="Onemogoči, ko ni prikazano" +AutoStart="Samodejno zaženi ob zagonu" +SwapFC-LFE="Zamenjaj SS in nizke tone" +SwapFC-LFE.Tooltip="Zamenjaj sprednji sredinski kanal in kanal z nizkimi toni" +VideoConnection="Slikovna povezava" +AudioConnection="Zvočna povezava" diff --git a/plugins/decklink/data/locale/uk-UA.ini b/plugins/decklink/data/locale/uk-UA.ini index 6e735b6..7ae2123 100644 --- a/plugins/decklink/data/locale/uk-UA.ini +++ b/plugins/decklink/data/locale/uk-UA.ini @@ -3,7 +3,9 @@ Device="Пристрій" Mode="Режим" Buffering="Увімкнути буферизацію" PixelFormat="Формат пікселів" +ColorSpace="Колірний простір" ColorSpace.Default="За замовчуванням" +ColorRange="Колірний діапазон" ColorRange.Default="За замовчуванням" ColorRange.Partial="Частковий" ColorRange.Full="Повний" diff --git a/plugins/decklink/decklink-device-discovery.cpp b/plugins/decklink/decklink-device-discovery.cpp index d785388..1f7a88e 100644 --- a/plugins/decklink/decklink-device-discovery.cpp +++ b/plugins/decklink/decklink-device-discovery.cpp @@ -54,8 +54,8 @@ DeckLinkDevice *DeckLinkDeviceDiscovery::FindByHash(const char *hash) return ret; } -HRESULT STDMETHODCALLTYPE DeckLinkDeviceDiscovery::DeckLinkDeviceArrived( - IDeckLink *device) +HRESULT STDMETHODCALLTYPE +DeckLinkDeviceDiscovery::DeckLinkDeviceArrived(IDeckLink *device) { DeckLinkDevice *newDev = new DeckLinkDevice(device); if (!newDev->Init()) { @@ -73,8 +73,8 @@ HRESULT STDMETHODCALLTYPE DeckLinkDeviceDiscovery::DeckLinkDeviceArrived( return S_OK; } -HRESULT STDMETHODCALLTYPE DeckLinkDeviceDiscovery::DeckLinkDeviceRemoved( - IDeckLink *device) +HRESULT STDMETHODCALLTYPE +DeckLinkDeviceDiscovery::DeckLinkDeviceRemoved(IDeckLink *device) { std::lock_guard lock(deviceMutex); @@ -98,7 +98,7 @@ ULONG STDMETHODCALLTYPE DeckLinkDeviceDiscovery::AddRef(void) } HRESULT STDMETHODCALLTYPE DeckLinkDeviceDiscovery::QueryInterface(REFIID iid, - LPVOID *ppv) + LPVOID *ppv) { HRESULT result = E_NOINTERFACE; @@ -110,7 +110,7 @@ HRESULT STDMETHODCALLTYPE DeckLinkDeviceDiscovery::QueryInterface(REFIID iid, AddRef(); result = S_OK; } else if (memcmp(&iid, &IID_IDeckLinkDeviceNotificationCallback, - sizeof(REFIID)) == 0) { + sizeof(REFIID)) == 0) { *ppv = (IDeckLinkDeviceNotificationCallback *)this; AddRef(); result = S_OK; diff --git a/plugins/decklink/decklink-device-discovery.hpp b/plugins/decklink/decklink-device-discovery.hpp index 9f2842c..6f62f77 100644 --- a/plugins/decklink/decklink-device-discovery.hpp +++ b/plugins/decklink/decklink-device-discovery.hpp @@ -9,7 +9,7 @@ class DeckLinkDevice; typedef void (*DeviceChangeCallback)(void *param, DeckLinkDevice *device, - bool added); + bool added); struct DeviceChangeInfo { DeviceChangeCallback callback; @@ -19,11 +19,11 @@ struct DeviceChangeInfo { class DeckLinkDeviceDiscovery : public IDeckLinkDeviceNotificationCallback { protected: ComPtr discovery; - long refCount = 1; - bool initialized = false; + long refCount = 1; + bool initialized = false; std::recursive_mutex deviceMutex; - std::vector devices; + std::vector devices; std::vector callbacks; public: @@ -44,8 +44,7 @@ public: info.param = param; for (DeviceChangeInfo &curCB : callbacks) { - if (curCB.callback == callback && - curCB.param == param) + if (curCB.callback == callback && curCB.param == param) return; } @@ -60,7 +59,7 @@ public: DeviceChangeInfo &curCB = callbacks[i]; if (curCB.callback == callback && - curCB.param == param) { + curCB.param == param) { callbacks.erase(callbacks.begin() + i); return; } @@ -69,9 +68,9 @@ public: DeckLinkDevice *FindByHash(const char *hash); - inline void Lock() {deviceMutex.lock();} - inline void Unlock() {deviceMutex.unlock();} - inline const std::vector &GetDevices() const + inline void Lock() { deviceMutex.lock(); } + inline void Unlock() { deviceMutex.unlock(); } + inline const std::vector &GetDevices() const { return devices; } diff --git a/plugins/decklink/decklink-device-instance.cpp b/plugins/decklink/decklink-device-instance.cpp index e2e13d1..0fd9f35 100644 --- a/plugins/decklink/decklink-device-instance.cpp +++ b/plugins/decklink/decklink-device-instance.cpp @@ -13,7 +13,8 @@ static inline enum video_format ConvertPixelFormat(BMDPixelFormat format) { switch (format) { - case bmdFormat8BitBGRA: return VIDEO_FORMAT_BGRX; + case bmdFormat8BitBGRA: + return VIDEO_FORMAT_BGRX; default: case bmdFormat8BitYUV:; @@ -38,7 +39,8 @@ static inline int ConvertChannelFormat(speaker_layout format) } } -static inline audio_repack_mode_t ConvertRepackFormat(speaker_layout format, bool swap) +static inline audio_repack_mode_t ConvertRepackFormat(speaker_layout format, + bool swap) { switch (format) { case SPEAKERS_2POINT1: @@ -46,11 +48,11 @@ static inline audio_repack_mode_t ConvertRepackFormat(speaker_layout format, boo case SPEAKERS_4POINT0: return repack_mode_8to4ch; case SPEAKERS_4POINT1: - return swap? repack_mode_8to5ch_swap:repack_mode_8to5ch; + return swap ? repack_mode_8to5ch_swap : repack_mode_8to5ch; case SPEAKERS_5POINT1: return swap ? repack_mode_8to6ch_swap : repack_mode_8to6ch; case SPEAKERS_7POINT1: - return swap ? repack_mode_8ch_swap: repack_mode_8ch; + return swap ? repack_mode_8ch_swap : repack_mode_8ch; default: assert(false && "No repack requested"); return (audio_repack_mode_t)-1; @@ -58,21 +60,18 @@ static inline audio_repack_mode_t ConvertRepackFormat(speaker_layout format, boo } DeckLinkDeviceInstance::DeckLinkDeviceInstance(DecklinkBase *decklink_, - DeckLinkDevice *device_) : - currentFrame(), currentPacket(), decklink(decklink_), device(device_) + DeckLinkDevice *device_) + : currentFrame(), currentPacket(), decklink(decklink_), device(device_) { currentPacket.samples_per_sec = 48000; - currentPacket.speakers = SPEAKERS_STEREO; - currentPacket.format = AUDIO_FORMAT_16BIT; + currentPacket.speakers = SPEAKERS_STEREO; + currentPacket.format = AUDIO_FORMAT_16BIT; } -DeckLinkDeviceInstance::~DeckLinkDeviceInstance() -{ -} +DeckLinkDeviceInstance::~DeckLinkDeviceInstance() {} void DeckLinkDeviceInstance::HandleAudioPacket( - IDeckLinkAudioInputPacket *audioPacket, - const uint64_t timestamp) + IDeckLinkAudioInputPacket *audioPacket, const uint64_t timestamp) { if (audioPacket == nullptr) return; @@ -83,11 +82,12 @@ void DeckLinkDeviceInstance::HandleAudioPacket( return; } - const uint32_t frameCount = (uint32_t)audioPacket->GetSampleFrameCount(); - currentPacket.frames = frameCount; - currentPacket.timestamp = timestamp; + const uint32_t frameCount = + (uint32_t)audioPacket->GetSampleFrameCount(); + currentPacket.frames = frameCount; + currentPacket.timestamp = timestamp; - if (decklink && !static_cast(decklink)->buffering) { + if (decklink && !static_cast(decklink)->buffering) { currentPacket.timestamp = os_gettime_ns(); currentPacket.timestamp -= (uint64_t)frameCount * 1000000000ULL / @@ -99,8 +99,9 @@ void DeckLinkDeviceInstance::HandleAudioPacket( if (channelFormat != SPEAKERS_UNKNOWN && channelFormat != SPEAKERS_MONO && channelFormat != SPEAKERS_STEREO && - (channelFormat != SPEAKERS_7POINT1 || static_cast(decklink)->swap) - && maxdevicechannel >= 8) { + (channelFormat != SPEAKERS_7POINT1 || + static_cast(decklink)->swap) && + maxdevicechannel >= 8) { if (audioRepacker->repack((uint8_t *)bytes, frameCount) < 0) { LOG(LOG_ERROR, "Failed to convert audio packet data"); @@ -112,13 +113,15 @@ void DeckLinkDeviceInstance::HandleAudioPacket( } nextAudioTS = timestamp + - ((uint64_t)frameCount * 1000000000ULL / 48000ULL) + 1; + ((uint64_t)frameCount * 1000000000ULL / 48000ULL) + 1; - obs_source_output_audio(static_cast(decklink)->GetSource(), ¤tPacket); + obs_source_output_audio( + static_cast(decklink)->GetSource(), + ¤tPacket); } void DeckLinkDeviceInstance::HandleVideoFrame( - IDeckLinkVideoInputFrame *videoFrame, const uint64_t timestamp) + IDeckLinkVideoInputFrame *videoFrame, const uint64_t timestamp) { if (videoFrame == nullptr) return; @@ -129,13 +132,15 @@ void DeckLinkDeviceInstance::HandleVideoFrame( return; } - currentFrame.data[0] = (uint8_t *)bytes; + currentFrame.data[0] = (uint8_t *)bytes; currentFrame.linesize[0] = (uint32_t)videoFrame->GetRowBytes(); - currentFrame.width = (uint32_t)videoFrame->GetWidth(); - currentFrame.height = (uint32_t)videoFrame->GetHeight(); - currentFrame.timestamp = timestamp; + currentFrame.width = (uint32_t)videoFrame->GetWidth(); + currentFrame.height = (uint32_t)videoFrame->GetHeight(); + currentFrame.timestamp = timestamp; - obs_source_output_video2(static_cast(decklink)->GetSource(), ¤tFrame); + obs_source_output_video2( + static_cast(decklink)->GetSource(), + ¤tFrame); } void DeckLinkDeviceInstance::FinalizeStream() @@ -145,8 +150,7 @@ void DeckLinkDeviceInstance::FinalizeStream() if (channelFormat != SPEAKERS_UNKNOWN) input->DisableAudioInput(); - if (audioRepacker != nullptr) - { + if (audioRepacker != nullptr) { delete audioRepacker; audioRepacker = nullptr; } @@ -163,7 +167,7 @@ void DeckLinkDeviceInstance::SetupVideoFormat(DeckLinkDeviceMode *mode_) currentFrame.format = ConvertPixelFormat(pixelFormat); - colorSpace = static_cast(decklink)->GetColorSpace(); + colorSpace = static_cast(decklink)->GetColorSpace(); if (colorSpace == VIDEO_CS_DEFAULT) { const BMDDisplayModeFlags flags = mode_->GetDisplayModeFlags(); if (flags & bmdDisplayModeColorspaceRec709) @@ -176,24 +180,25 @@ void DeckLinkDeviceInstance::SetupVideoFormat(DeckLinkDeviceMode *mode_) activeColorSpace = colorSpace; } - colorRange = static_cast(decklink)->GetColorRange(); + colorRange = static_cast(decklink)->GetColorRange(); currentFrame.range = colorRange; video_format_get_parameters(activeColorSpace, colorRange, - currentFrame.color_matrix, currentFrame.color_range_min, - currentFrame.color_range_max); + currentFrame.color_matrix, + currentFrame.color_range_min, + currentFrame.color_range_max); #ifdef LOG_SETUP_VIDEO_FORMAT LOG(LOG_INFO, "Setup video format: %s, %s, %s", - pixelFormat == bmdFormat8BitYUV ? "YUV" : "RGB", - activeColorSpace == VIDEO_CS_709 ? "BT.709" : "BT.601", - colorRange == VIDEO_RANGE_FULL ? "full" : "limited"); + pixelFormat == bmdFormat8BitYUV ? "YUV" : "RGB", + activeColorSpace == VIDEO_CS_709 ? "BT.709" : "BT.601", + colorRange == VIDEO_RANGE_FULL ? "full" : "limited"); #endif } bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_, - BMDVideoConnection bmdVideoConnection, - BMDAudioConnection bmdAudioConnection) + BMDVideoConnection bmdVideoConnection, + BMDAudioConnection bmdAudioConnection) { if (mode != nullptr) return false; @@ -205,33 +210,33 @@ bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_, if (!device->GetInput(&input)) return false; - IDeckLinkConfiguration *deckLinkConfiguration = NULL; HRESULT result = input->QueryInterface(IID_IDeckLinkConfiguration, - (void**)&deckLinkConfiguration); - if (result != S_OK) - { + (void **)&deckLinkConfiguration); + if (result != S_OK) { LOG(LOG_ERROR, - "Could not obtain the IDeckLinkConfiguration interface: %08x\n", - result); + "Could not obtain the IDeckLinkConfiguration interface: %08x\n", + result); } else { if (bmdVideoConnection > 0) { result = deckLinkConfiguration->SetInt( - bmdDeckLinkConfigVideoInputConnection, bmdVideoConnection); + bmdDeckLinkConfigVideoInputConnection, + bmdVideoConnection); if (result != S_OK) { LOG(LOG_ERROR, - "Couldn't set input video port to %d\n\n", - bmdVideoConnection); + "Couldn't set input video port to %d\n\n", + bmdVideoConnection); } } if (bmdAudioConnection > 0) { result = deckLinkConfiguration->SetInt( - bmdDeckLinkConfigAudioInputConnection, bmdAudioConnection); + bmdDeckLinkConfigAudioInputConnection, + bmdAudioConnection); if (result != S_OK) { LOG(LOG_ERROR, - "Couldn't set input audio port to %d\n\n", - bmdVideoConnection); + "Couldn't set input audio port to %d\n\n", + bmdVideoConnection); } } } @@ -248,12 +253,13 @@ bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_, flags = bmdVideoInputEnableFormatDetection; } else { displayMode = mode_->GetDisplayMode(); - pixelFormat = static_cast(decklink)->GetPixelFormat(); + pixelFormat = + static_cast(decklink)->GetPixelFormat(); flags = bmdVideoInputFlagDefault; } - const HRESULT videoResult = input->EnableVideoInput(displayMode, - pixelFormat, flags); + const HRESULT videoResult = + input->EnableVideoInput(displayMode, pixelFormat, flags); if (videoResult != S_OK) { LOG(LOG_ERROR, "Failed to enable video input"); return false; @@ -261,28 +267,30 @@ bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_, SetupVideoFormat(mode_); - channelFormat = static_cast(decklink)->GetChannelFormat(); + channelFormat = + static_cast(decklink)->GetChannelFormat(); currentPacket.speakers = channelFormat; - swap = static_cast(decklink)->swap; + swap = static_cast(decklink)->swap; int maxdevicechannel = device->GetMaxChannel(); if (channelFormat != SPEAKERS_UNKNOWN) { const int channel = ConvertChannelFormat(channelFormat); const HRESULT audioResult = input->EnableAudioInput( - bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, - channel); + bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, + channel); if (audioResult != S_OK) - LOG(LOG_WARNING, "Failed to enable audio input; continuing..."); + LOG(LOG_WARNING, + "Failed to enable audio input; continuing..."); if (channelFormat != SPEAKERS_UNKNOWN && channelFormat != SPEAKERS_MONO && channelFormat != SPEAKERS_STEREO && - (channelFormat != SPEAKERS_7POINT1 || swap) - && maxdevicechannel >= 8) { + (channelFormat != SPEAKERS_7POINT1 || swap) && + maxdevicechannel >= 8) { - const audio_repack_mode_t repack_mode = ConvertRepackFormat - (channelFormat, swap); + const audio_repack_mode_t repack_mode = + ConvertRepackFormat(channelFormat, swap); audioRepacker = new AudioRepacker(repack_mode); } } @@ -310,7 +318,7 @@ bool DeckLinkDeviceInstance::StopCapture(void) return false; LOG(LOG_INFO, "Stopping capture of '%s'...", - GetDevice()->GetDisplayName().c_str()); + GetDevice()->GetDisplayName().c_str()); input->StopStreams(); FinalizeStream(); @@ -331,18 +339,15 @@ bool DeckLinkDeviceInstance::StartOutput(DeckLinkDeviceMode *mode_) return false; const HRESULT videoResult = output->EnableVideoOutput( - mode_->GetDisplayMode(), - bmdVideoOutputFlagDefault); + mode_->GetDisplayMode(), bmdVideoOutputFlagDefault); if (videoResult != S_OK) { LOG(LOG_ERROR, "Failed to enable video output"); return false; } const HRESULT audioResult = output->EnableAudioOutput( - bmdAudioSampleRate48kHz, - bmdAudioSampleType16bitInteger, - 2, - bmdAudioOutputStreamTimestamped); + bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, 2, + bmdAudioOutputStreamTimestamped); if (audioResult != S_OK) { LOG(LOG_ERROR, "Failed to enable audio output"); return false; @@ -362,7 +367,7 @@ bool DeckLinkDeviceInstance::StartOutput(DeckLinkDeviceMode *mode_) } } - auto decklinkOutput = dynamic_cast(decklink); + auto decklinkOutput = dynamic_cast(decklink); if (decklinkOutput == nullptr) return false; @@ -378,13 +383,11 @@ bool DeckLinkDeviceInstance::StartOutput(DeckLinkDeviceMode *mode_) HRESULT result; result = output->CreateVideoFrame(decklinkOutput->GetWidth(), - decklinkOutput->GetHeight(), - rowBytes, - pixelFormat, - bmdFrameFlagDefault, - &decklinkOutputFrame); + decklinkOutput->GetHeight(), rowBytes, + pixelFormat, bmdFrameFlagDefault, + &decklinkOutputFrame); if (result != S_OK) { - blog(LOG_ERROR ,"failed to make frame 0x%X", result); + blog(LOG_ERROR, "failed to make frame 0x%X", result); return false; } @@ -397,7 +400,7 @@ bool DeckLinkDeviceInstance::StopOutput() return false; LOG(LOG_INFO, "Stopping output of '%s'...", - GetDevice()->GetDisplayName().c_str()); + GetDevice()->GetDisplayName().c_str()); output->DisableVideoOutput(); output->DisableAudioOutput(); @@ -412,12 +415,12 @@ bool DeckLinkDeviceInstance::StopOutput() void DeckLinkDeviceInstance::DisplayVideoFrame(video_data *frame) { - auto decklinkOutput = dynamic_cast(decklink); + auto decklinkOutput = dynamic_cast(decklink); if (decklinkOutput == nullptr) return; uint8_t *destData; - decklinkOutputFrame->GetBytes((void**)&destData); + decklinkOutputFrame->GetBytes((void **)&destData); uint8_t *outData = frame->data[0]; @@ -426,8 +429,8 @@ void DeckLinkDeviceInstance::DisplayVideoFrame(video_data *frame) rowBytes = decklinkOutput->GetWidth() * 4; } - std::copy(outData, outData + (decklinkOutput->GetHeight() * - rowBytes), destData); + std::copy(outData, outData + (decklinkOutput->GetHeight() * rowBytes), + destData); output->DisplayVideoFrameSync(decklinkOutputFrame); } @@ -435,16 +438,15 @@ void DeckLinkDeviceInstance::DisplayVideoFrame(video_data *frame) void DeckLinkDeviceInstance::WriteAudio(audio_data *frames) { uint32_t sampleFramesWritten; - output->WriteAudioSamplesSync(frames->data[0], - frames->frames, - &sampleFramesWritten); + output->WriteAudioSamplesSync(frames->data[0], frames->frames, + &sampleFramesWritten); } #define TIME_BASE 1000000000 HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::VideoInputFrameArrived( - IDeckLinkVideoInputFrame *videoFrame, - IDeckLinkAudioInputPacket *audioPacket) + IDeckLinkVideoInputFrame *videoFrame, + IDeckLinkAudioInputPacket *audioPacket) { BMDTimeValue videoTS = 0; BMDTimeValue videoDur = 0; @@ -481,9 +483,8 @@ HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::VideoInputFrameArrived( } HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::VideoInputFormatChanged( - BMDVideoInputFormatChangedEvents events, - IDeckLinkDisplayMode *newMode, - BMDDetectedVideoInputFormatFlags detectedSignalFlags) + BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *newMode, + BMDDetectedVideoInputFormatFlags detectedSignalFlags) { input->PauseStreams(); @@ -506,8 +507,8 @@ HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::VideoInputFormatChanged( } } - const HRESULT videoResult = input->EnableVideoInput(displayMode, - pixelFormat, bmdVideoInputEnableFormatDetection); + const HRESULT videoResult = input->EnableVideoInput( + displayMode, pixelFormat, bmdVideoInputEnableFormatDetection); if (videoResult != S_OK) { LOG(LOG_ERROR, "Failed to enable video input"); input->StopStreams(); @@ -530,7 +531,7 @@ ULONG STDMETHODCALLTYPE DeckLinkDeviceInstance::AddRef(void) } HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::QueryInterface(REFIID iid, - LPVOID *ppv) + LPVOID *ppv) { HRESULT result = E_NOINTERFACE; @@ -542,7 +543,7 @@ HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::QueryInterface(REFIID iid, AddRef(); result = S_OK; } else if (memcmp(&iid, &IID_IDeckLinkNotificationCallback, - sizeof(REFIID)) == 0) { + sizeof(REFIID)) == 0) { *ppv = (IDeckLinkNotificationCallback *)this; AddRef(); result = S_OK; diff --git a/plugins/decklink/decklink-device-instance.hpp b/plugins/decklink/decklink-device-instance.hpp index bee60e2..d2982bc 100644 --- a/plugins/decklink/decklink-device-instance.hpp +++ b/plugins/decklink/decklink-device-instance.hpp @@ -1,6 +1,7 @@ #pragma once -#define LOG(level, message, ...) blog(level, "%s: " message, "decklink", ##__VA_ARGS__) +#define LOG(level, message, ...) \ + blog(level, "%s: " message, "decklink", ##__VA_ARGS__) #include #include "decklink-device.hpp" @@ -13,25 +14,25 @@ class DeckLinkDeviceInstance : public IDeckLinkInputCallback { protected: struct obs_source_frame2 currentFrame; struct obs_source_audio currentPacket; - DecklinkBase *decklink = nullptr; - DeckLinkDevice *device = nullptr; - DeckLinkDeviceMode *mode = nullptr; - BMDVideoConnection videoConnection; - BMDAudioConnection audioConnection; - BMDDisplayMode displayMode = bmdModeNTSC; - BMDPixelFormat pixelFormat = bmdFormat8BitYUV; - video_colorspace colorSpace = VIDEO_CS_DEFAULT; - video_colorspace activeColorSpace = VIDEO_CS_DEFAULT; - video_range_type colorRange = VIDEO_RANGE_DEFAULT; - ComPtr input; + DecklinkBase *decklink = nullptr; + DeckLinkDevice *device = nullptr; + DeckLinkDeviceMode *mode = nullptr; + BMDVideoConnection videoConnection; + BMDAudioConnection audioConnection; + BMDDisplayMode displayMode = bmdModeNTSC; + BMDPixelFormat pixelFormat = bmdFormat8BitYUV; + video_colorspace colorSpace = VIDEO_CS_DEFAULT; + video_colorspace activeColorSpace = VIDEO_CS_DEFAULT; + video_range_type colorRange = VIDEO_RANGE_DEFAULT; + ComPtr input; ComPtr output; - volatile long refCount = 1; - int64_t audioOffset = 0; - uint64_t nextAudioTS = 0; - uint64_t lastVideoTS = 0; - AudioRepacker *audioRepacker = nullptr; - speaker_layout channelFormat = SPEAKERS_STEREO; - bool swap; + volatile long refCount = 1; + int64_t audioOffset = 0; + uint64_t nextAudioTS = 0; + uint64_t lastVideoTS = 0; + AudioRepacker *audioRepacker = nullptr; + speaker_layout channelFormat = SPEAKERS_STEREO; + bool swap; IDeckLinkMutableVideoFrame *decklinkOutputFrame = nullptr; @@ -39,45 +40,63 @@ protected: void SetupVideoFormat(DeckLinkDeviceMode *mode_); void HandleAudioPacket(IDeckLinkAudioInputPacket *audioPacket, - const uint64_t timestamp); + const uint64_t timestamp); void HandleVideoFrame(IDeckLinkVideoInputFrame *videoFrame, - const uint64_t timestamp); + const uint64_t timestamp); public: DeckLinkDeviceInstance(DecklinkBase *decklink, DeckLinkDevice *device); virtual ~DeckLinkDeviceInstance(); - inline DeckLinkDevice *GetDevice() const {return device;} + inline DeckLinkDevice *GetDevice() const { return device; } inline long long GetActiveModeId() const { return mode ? mode->GetId() : 0; } - inline BMDPixelFormat GetActivePixelFormat() const {return pixelFormat;} - inline video_colorspace GetActiveColorSpace() const {return colorSpace;} - inline video_range_type GetActiveColorRange() const {return colorRange;} - inline speaker_layout GetActiveChannelFormat() const {return channelFormat;} - inline bool GetActiveSwapState() const {return swap;} - inline BMDVideoConnection GetVideoConnection() const {return videoConnection;} - inline BMDAudioConnection GetAudioConnection() const {return audioConnection;} + inline BMDPixelFormat GetActivePixelFormat() const + { + return pixelFormat; + } + inline video_colorspace GetActiveColorSpace() const + { + return colorSpace; + } + inline video_range_type GetActiveColorRange() const + { + return colorRange; + } + inline speaker_layout GetActiveChannelFormat() const + { + return channelFormat; + } + inline bool GetActiveSwapState() const { return swap; } + inline BMDVideoConnection GetVideoConnection() const + { + return videoConnection; + } + inline BMDAudioConnection GetAudioConnection() const + { + return audioConnection; + } - inline DeckLinkDeviceMode *GetMode() const {return mode;} + inline DeckLinkDeviceMode *GetMode() const { return mode; } bool StartCapture(DeckLinkDeviceMode *mode, - BMDVideoConnection bmdVideoConnection, - BMDAudioConnection bmdAudioConnection); + BMDVideoConnection bmdVideoConnection, + BMDAudioConnection bmdAudioConnection); bool StopCapture(void); bool StartOutput(DeckLinkDeviceMode *mode_); bool StopOutput(void); - HRESULT STDMETHODCALLTYPE VideoInputFrameArrived( - IDeckLinkVideoInputFrame *videoFrame, - IDeckLinkAudioInputPacket *audioPacket); + HRESULT STDMETHODCALLTYPE + VideoInputFrameArrived(IDeckLinkVideoInputFrame *videoFrame, + IDeckLinkAudioInputPacket *audioPacket); HRESULT STDMETHODCALLTYPE VideoInputFormatChanged( - BMDVideoInputFormatChangedEvents events, - IDeckLinkDisplayMode *newMode, - BMDDetectedVideoInputFormatFlags detectedSignalFlags); + BMDVideoInputFormatChangedEvents events, + IDeckLinkDisplayMode *newMode, + BMDDetectedVideoInputFormatFlags detectedSignalFlags); ULONG STDMETHODCALLTYPE AddRef(void); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv); diff --git a/plugins/decklink/decklink-device-mode.cpp b/plugins/decklink/decklink-device-mode.cpp index 67a052b..b2f2107 100644 --- a/plugins/decklink/decklink-device-mode.cpp +++ b/plugins/decklink/decklink-device-mode.cpp @@ -1,7 +1,7 @@ #include "decklink-device-mode.hpp" -DeckLinkDeviceMode::DeckLinkDeviceMode(IDeckLinkDisplayMode *mode, - long long id) : id(id), mode(mode) +DeckLinkDeviceMode::DeckLinkDeviceMode(IDeckLinkDisplayMode *mode, long long id) + : id(id), mode(mode) { if (mode == nullptr) return; @@ -13,8 +13,8 @@ DeckLinkDeviceMode::DeckLinkDeviceMode(IDeckLinkDisplayMode *mode, DeckLinkStringToStdString(decklinkStringName, name); } -DeckLinkDeviceMode::DeckLinkDeviceMode(const std::string& name, long long id) : - id(id), mode(nullptr), name(name) +DeckLinkDeviceMode::DeckLinkDeviceMode(const std::string &name, long long id) + : id(id), mode(nullptr), name(name) { } @@ -61,7 +61,7 @@ long long DeckLinkDeviceMode::GetId(void) const return id; } -const std::string& DeckLinkDeviceMode::GetName(void) const +const std::string &DeckLinkDeviceMode::GetName(void) const { return name; } diff --git a/plugins/decklink/decklink-device-mode.hpp b/plugins/decklink/decklink-device-mode.hpp index ae00153..51e1f8b 100644 --- a/plugins/decklink/decklink-device-mode.hpp +++ b/plugins/decklink/decklink-device-mode.hpp @@ -4,23 +4,23 @@ #include -#define MODE_ID_AUTO -1 +#define MODE_ID_AUTO -1 class DeckLinkDeviceMode { protected: - long long id; + long long id; IDeckLinkDisplayMode *mode; - std::string name; + std::string name; public: DeckLinkDeviceMode(IDeckLinkDisplayMode *mode, long long id); - DeckLinkDeviceMode(const std::string& name, long long id); + DeckLinkDeviceMode(const std::string &name, long long id); virtual ~DeckLinkDeviceMode(void); BMDDisplayMode GetDisplayMode(void) const; BMDDisplayModeFlags GetDisplayModeFlags(void) const; long long GetId(void) const; - const std::string& GetName(void) const; + const std::string &GetName(void) const; void SetMode(IDeckLinkDisplayMode *mode); diff --git a/plugins/decklink/decklink-device.cpp b/plugins/decklink/decklink-device.cpp index c2166cd..2497735 100644 --- a/plugins/decklink/decklink-device.cpp +++ b/plugins/decklink/decklink-device.cpp @@ -4,9 +4,7 @@ #include -DeckLinkDevice::DeckLinkDevice(IDeckLink *device_) : device(device_) -{ -} +DeckLinkDevice::DeckLinkDevice(IDeckLink *device_) : device(device_) {} DeckLinkDevice::~DeckLinkDevice(void) { @@ -34,15 +32,15 @@ bool DeckLinkDevice::Init() { ComPtr attributes; const HRESULT result = device->QueryInterface(IID_IDeckLinkAttributes, - (void **)&attributes); + (void **)&attributes); if (result == S_OK) { decklink_bool_t detectable = false; if (attributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, - &detectable) == S_OK && !!detectable) { - DeckLinkDeviceMode *mode = new DeckLinkDeviceMode( - "Auto", - MODE_ID_AUTO); + &detectable) == S_OK && + !!detectable) { + DeckLinkDeviceMode *mode = + new DeckLinkDeviceMode("Auto", MODE_ID_AUTO); inputModes.push_back(mode); inputModeIdMap[MODE_ID_AUTO] = mode; } @@ -50,7 +48,8 @@ bool DeckLinkDevice::Init() // Find input modes ComPtr input; - if (device->QueryInterface(IID_IDeckLinkInput, (void **) &input) == S_OK) { + if (device->QueryInterface(IID_IDeckLinkInput, (void **)&input) == + S_OK) { IDeckLinkDisplayModeIterator *modeIterator; if (input->GetDisplayModeIterator(&modeIterator) == S_OK) { IDeckLinkDisplayMode *displayMode; @@ -61,7 +60,8 @@ bool DeckLinkDevice::Init() continue; DeckLinkDeviceMode *mode = - new DeckLinkDeviceMode(displayMode, modeId); + new DeckLinkDeviceMode(displayMode, + modeId); inputModes.push_back(mode); inputModeIdMap[modeId] = mode; displayMode->Release(); @@ -74,19 +74,20 @@ bool DeckLinkDevice::Init() // Get supported video connections attributes->GetInt(BMDDeckLinkVideoInputConnections, - &supportedVideoInputConnections); + &supportedVideoInputConnections); attributes->GetInt(BMDDeckLinkVideoOutputConnections, - &supportedVideoOutputConnections); + &supportedVideoOutputConnections); // Get supported audio connections attributes->GetInt(BMDDeckLinkAudioInputConnections, - &supportedAudioInputConnections); + &supportedAudioInputConnections); attributes->GetInt(BMDDeckLinkAudioOutputConnections, - &supportedAudioOutputConnections); + &supportedAudioOutputConnections); // find output modes ComPtr output; - if (device->QueryInterface(IID_IDeckLinkOutput, (void **) &output) == S_OK) { + if (device->QueryInterface(IID_IDeckLinkOutput, (void **)&output) == + S_OK) { IDeckLinkDisplayModeIterator *modeIterator; if (output->GetDisplayModeIterator(&modeIterator) == S_OK) { @@ -98,7 +99,8 @@ bool DeckLinkDevice::Init() continue; DeckLinkDeviceMode *mode = - new DeckLinkDeviceMode(displayMode, modeId); + new DeckLinkDeviceMode(displayMode, + modeId); outputModes.push_back(mode); outputModeIdMap[modeId] = mode; displayMode->Release(); @@ -111,9 +113,9 @@ bool DeckLinkDevice::Init() // get keyer support attributes->GetFlag(BMDDeckLinkSupportsExternalKeying, - &supportsExternalKeyer); + &supportsExternalKeyer); attributes->GetFlag(BMDDeckLinkSupportsInternalKeying, - &supportsInternalKeyer); + &supportsInternalKeyer); // Sub Device Counts attributes->GetInt(BMDDeckLinkSubDeviceIndex, &subDeviceIndex); @@ -139,7 +141,8 @@ bool DeckLinkDevice::Init() /* Intensity Shuttle for Thunderbolt return 2; however, it supports 8 channels */ if (name == "Intensity Shuttle Thunderbolt") maxChannel = 8; - else if (attributes->GetInt(BMDDeckLinkMaximumAudioChannels, &channels) == S_OK) + else if (attributes->GetInt(BMDDeckLinkMaximumAudioChannels, + &channels) == S_OK) maxChannel = (int32_t)channels; else maxChannel = 2; @@ -149,7 +152,7 @@ bool DeckLinkDevice::Init() * BMDDeckLinkPersistentID for newer ones */ int64_t value; - if (attributes->GetInt(BMDDeckLinkPersistentID, &value) != S_OK && + if (attributes->GetInt(BMDDeckLinkPersistentID, &value) != S_OK && attributes->GetInt(BMDDeckLinkTopologicalID, &value) != S_OK) return true; @@ -161,14 +164,15 @@ bool DeckLinkDevice::Init() bool DeckLinkDevice::GetInput(IDeckLinkInput **input) { - if (device->QueryInterface(IID_IDeckLinkInput, (void**)input) != S_OK) + if (device->QueryInterface(IID_IDeckLinkInput, (void **)input) != S_OK) return false; return true; } bool DeckLinkDevice::GetOutput(IDeckLinkOutput **output) { - if (device->QueryInterface(IID_IDeckLinkOutput, (void**)output) != S_OK) + if (device->QueryInterface(IID_IDeckLinkOutput, (void **)output) != + S_OK) return false; return true; @@ -176,9 +180,10 @@ bool DeckLinkDevice::GetOutput(IDeckLinkOutput **output) bool DeckLinkDevice::GetKeyer(IDeckLinkKeyer **deckLinkKeyer) { - if (device->QueryInterface(IID_IDeckLinkKeyer, (void**)deckLinkKeyer) != S_OK) - { - fprintf(stderr, "Could not obtain the IDeckLinkKeyer interface\n"); + if (device->QueryInterface(IID_IDeckLinkKeyer, + (void **)deckLinkKeyer) != S_OK) { + fprintf(stderr, + "Could not obtain the IDeckLinkKeyer interface\n"); return false; } @@ -205,22 +210,24 @@ DeckLinkDeviceMode *DeckLinkDevice::FindOutputMode(long long id) return outputModeIdMap[id]; } -const std::string& DeckLinkDevice::GetDisplayName(void) +const std::string &DeckLinkDevice::GetDisplayName(void) { return displayName; } -const std::string& DeckLinkDevice::GetHash(void) const +const std::string &DeckLinkDevice::GetHash(void) const { return hash; } -const std::vector& DeckLinkDevice::GetInputModes(void) const +const std::vector & +DeckLinkDevice::GetInputModes(void) const { return inputModes; } -const std::vector& DeckLinkDevice::GetOutputModes(void) const +const std::vector & +DeckLinkDevice::GetOutputModes(void) const { return outputModes; } @@ -235,7 +242,6 @@ int64_t DeckLinkDevice::GetAudioInputConnections() return supportedAudioInputConnections; } - bool DeckLinkDevice::GetSupportsExternalKeyer(void) const { return supportsExternalKeyer; @@ -256,7 +262,7 @@ int64_t DeckLinkDevice::GetSubDeviceIndex() return subDeviceIndex; } -const std::string& DeckLinkDevice::GetName(void) const +const std::string &DeckLinkDevice::GetName(void) const { return name; } diff --git a/plugins/decklink/decklink-device.hpp b/plugins/decklink/decklink-device.hpp index a882a6c..bf0d550 100644 --- a/plugins/decklink/decklink-device.hpp +++ b/plugins/decklink/decklink-device.hpp @@ -7,28 +7,26 @@ #include #include - - class DeckLinkDevice { - ComPtr device; + ComPtr device; std::map inputModeIdMap; - std::vector inputModes; + std::vector inputModes; std::map outputModeIdMap; - std::vector outputModes; - std::string name; - std::string displayName; - std::string hash; - int32_t maxChannel = 0; - decklink_bool_t supportsExternalKeyer = false; - decklink_bool_t supportsInternalKeyer = false; - int64_t subDeviceIndex = 0; - int64_t numSubDevices = 0; - int64_t supportedVideoInputConnections = -1; - int64_t supportedVideoOutputConnections = -1; - int64_t supportedAudioInputConnections = -1; - int64_t supportedAudioOutputConnections = -1; - int keyerMode = 0; - volatile long refCount = 1; + std::vector outputModes; + std::string name; + std::string displayName; + std::string hash; + int32_t maxChannel = 0; + decklink_bool_t supportsExternalKeyer = false; + decklink_bool_t supportsInternalKeyer = false; + int64_t subDeviceIndex = 0; + int64_t numSubDevices = 0; + int64_t supportedVideoInputConnections = -1; + int64_t supportedVideoOutputConnections = -1; + int64_t supportedAudioInputConnections = -1; + int64_t supportedAudioOutputConnections = -1; + int keyerMode = 0; + volatile long refCount = 1; public: DeckLinkDevice(IDeckLink *device); @@ -41,10 +39,10 @@ public: DeckLinkDeviceMode *FindInputMode(long long id); DeckLinkDeviceMode *FindOutputMode(long long id); - const std::string& GetDisplayName(void); - const std::string& GetHash(void) const; - const std::vector& GetInputModes(void) const; - const std::vector& GetOutputModes(void) const; + const std::string &GetDisplayName(void); + const std::string &GetHash(void) const; + const std::vector &GetInputModes(void) const; + const std::vector &GetOutputModes(void) const; int64_t GetVideoInputConnections(); int64_t GetAudioInputConnections(); bool GetSupportsExternalKeyer(void) const; @@ -53,15 +51,12 @@ public: int64_t GetSubDeviceIndex(); int GetKeyerMode(void); void SetKeyerMode(int newKeyerMode); - const std::string& GetName(void) const; + const std::string &GetName(void) const; int32_t GetMaxChannel(void) const; bool GetInput(IDeckLinkInput **input); bool GetOutput(IDeckLinkOutput **output); bool GetKeyer(IDeckLinkKeyer **keyer); - inline bool IsDevice(IDeckLink *device_) - { - return device_ == device; - } + inline bool IsDevice(IDeckLink *device_) { return device_ == device; } }; diff --git a/plugins/decklink/decklink-devices.cpp b/plugins/decklink/decklink-devices.cpp index 28607ef..c304c69 100644 --- a/plugins/decklink/decklink-devices.cpp +++ b/plugins/decklink/decklink-devices.cpp @@ -6,11 +6,11 @@ void fill_out_devices(obs_property_t *list) { deviceEnum->Lock(); - const std::vector &devices = deviceEnum->GetDevices(); + const std::vector &devices = deviceEnum->GetDevices(); for (DeckLinkDevice *device : devices) { obs_property_list_add_string(list, - device->GetDisplayName().c_str(), - device->GetHash().c_str()); + device->GetDisplayName().c_str(), + device->GetHash().c_str()); } deviceEnum->Unlock(); diff --git a/plugins/decklink/decklink-output.cpp b/plugins/decklink/decklink-output.cpp index a5cf2f4..2047f9c 100644 --- a/plugins/decklink/decklink-output.cpp +++ b/plugins/decklink/decklink-output.cpp @@ -48,7 +48,8 @@ static bool decklink_output_start(void *data) decklink->audio_samplerate = aoi.samples_per_sec; decklink->audio_planes = 2; - decklink->audio_size = get_audio_size(AUDIO_FORMAT_16BIT, aoi.speakers, 1); + decklink->audio_size = + get_audio_size(AUDIO_FORMAT_16BIT, aoi.speakers, 1); decklink->start_timestamp = 0; @@ -68,7 +69,7 @@ static bool decklink_output_start(void *data) to.format = VIDEO_FORMAT_UYVY; } to.width = mode->GetWidth(); - to.height = mode->GetHeight(); + to.height = mode->GetHeight(); obs_output_set_video_conversion(decklink->GetOutput(), &to); @@ -78,7 +79,7 @@ static bool decklink_output_start(void *data) struct audio_convert_info conversion = {}; conversion.format = AUDIO_FORMAT_16BIT; conversion.speakers = SPEAKERS_STEREO; - conversion.samples_per_sec = 48000; // Only format the decklink supports + conversion.samples_per_sec = 48000; // Only format the decklink supports obs_output_set_audio_conversion(decklink->GetOutput(), &conversion); @@ -112,14 +113,14 @@ static void decklink_output_raw_video(void *data, struct video_data *frame) } static bool prepare_audio(DeckLinkOutput *decklink, - const struct audio_data *frame, - struct audio_data *output) + const struct audio_data *frame, + struct audio_data *output) { *output = *frame; if (frame->timestamp < decklink->start_timestamp) { uint64_t duration = (uint64_t)frame->frames * 1000000000 / - (uint64_t)decklink->audio_samplerate; + (uint64_t)decklink->audio_samplerate; uint64_t end_ts = frame->timestamp + duration; uint64_t cutoff; @@ -132,8 +133,8 @@ static bool prepare_audio(DeckLinkOutput *decklink, cutoff *= (uint64_t)decklink->audio_samplerate / 1000000000; for (size_t i = 0; i < decklink->audio_planes; i++) - output->data[i] += decklink->audio_size * - (uint32_t)cutoff; + output->data[i] += + decklink->audio_size * (uint32_t)cutoff; output->frames -= (uint32_t)cutoff; } @@ -156,7 +157,8 @@ static void decklink_output_raw_audio(void *data, struct audio_data *frames) } static bool decklink_output_device_changed(obs_properties_t *props, - obs_property_t *list, obs_data_t *settings) + obs_property_t *list, + obs_data_t *settings) { const char *name = obs_data_get_string(settings, DEVICE_NAME); const char *hash = obs_data_get_string(settings, DEVICE_HASH); @@ -193,13 +195,13 @@ static bool decklink_output_device_changed(obs_properties_t *props, obs_property_list_item_disable(modeList, 0, true); obs_property_list_item_disable(keyerList, 0, true); } else { - const std::vector &modes = - device->GetOutputModes(); + const std::vector &modes = + device->GetOutputModes(); for (DeckLinkDeviceMode *mode : modes) { obs_property_list_add_int(modeList, - mode->GetName().c_str(), - mode->GetId()); + mode->GetName().c_str(), + mode->GetId()); } obs_property_list_add_int(keyerList, "Disabled", 0); @@ -222,22 +224,26 @@ static obs_properties_t *decklink_output_properties(void *unused) obs_properties_t *props = obs_properties_create(); obs_property_t *list = obs_properties_add_list(props, DEVICE_HASH, - TEXT_DEVICE, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); - obs_property_set_modified_callback(list, decklink_output_device_changed); + TEXT_DEVICE, + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); + obs_property_set_modified_callback(list, + decklink_output_device_changed); fill_out_devices(list); - obs_properties_add_list(props, - MODE_ID, TEXT_MODE, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_properties_add_list(props, MODE_ID, TEXT_MODE, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); obs_properties_add_bool(props, AUTO_START, TEXT_AUTO_START); - obs_properties_add_list(props, KEYER, TEXT_ENABLE_KEYER, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_properties_add_list(props, KEYER, TEXT_ENABLE_KEYER, + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); return props; } -static const char *decklink_output_get_name(void*) +static const char *decklink_output_get_name(void *) { return obs_module_text("BlackmagicDevice"); } @@ -246,17 +252,17 @@ struct obs_output_info create_decklink_output_info() { struct obs_output_info decklink_output_info = {}; - decklink_output_info.id = "decklink_output"; - decklink_output_info.flags = OBS_OUTPUT_AV; - decklink_output_info.get_name = decklink_output_get_name; - decklink_output_info.create = decklink_output_create; - decklink_output_info.destroy = decklink_output_destroy; - decklink_output_info.start = decklink_output_start; - decklink_output_info.stop = decklink_output_stop; + decklink_output_info.id = "decklink_output"; + decklink_output_info.flags = OBS_OUTPUT_AV; + decklink_output_info.get_name = decklink_output_get_name; + decklink_output_info.create = decklink_output_create; + decklink_output_info.destroy = decklink_output_destroy; + decklink_output_info.start = decklink_output_start; + decklink_output_info.stop = decklink_output_stop; decklink_output_info.get_properties = decklink_output_properties; - decklink_output_info.raw_video = decklink_output_raw_video; - decklink_output_info.raw_audio = decklink_output_raw_audio; - decklink_output_info.update = decklink_output_update; + decklink_output_info.raw_video = decklink_output_raw_video; + decklink_output_info.raw_audio = decklink_output_raw_audio; + decklink_output_info.update = decklink_output_update; return decklink_output_info; } diff --git a/plugins/decklink/decklink-source.cpp b/plugins/decklink/decklink-source.cpp index f781898..939b0ff 100644 --- a/plugins/decklink/decklink-source.cpp +++ b/plugins/decklink/decklink-source.cpp @@ -15,7 +15,8 @@ static void decklink_enable_buffering(DeckLinkInput *decklink, bool enabled) decklink->buffering = enabled; } -static void decklink_deactivate_when_not_showing(DeckLinkInput *decklink, bool dwns) +static void decklink_deactivate_when_not_showing(DeckLinkInput *decklink, + bool dwns) { decklink->dwns = dwns; } @@ -26,7 +27,7 @@ static void *decklink_create(obs_data_t *settings, obs_source_t *source) obs_source_set_async_decoupled(source, true); decklink_enable_buffering(decklink, - obs_data_get_bool(settings, BUFFERING)); + obs_data_get_bool(settings, BUFFERING)); obs_source_update(source, settings); return decklink; @@ -43,16 +44,18 @@ static void decklink_update(void *data, obs_data_t *settings) DeckLinkInput *decklink = (DeckLinkInput *)data; const char *hash = obs_data_get_string(settings, DEVICE_HASH); long long id = obs_data_get_int(settings, MODE_ID); - BMDVideoConnection videoConnection = (BMDVideoConnection) obs_data_get_int(settings, - VIDEO_CONNECTION); - BMDAudioConnection audioConnection = (BMDAudioConnection) obs_data_get_int(settings, - AUDIO_CONNECTION); - BMDPixelFormat pixelFormat = (BMDPixelFormat)obs_data_get_int(settings, - PIXEL_FORMAT); - video_colorspace colorSpace = (video_colorspace)obs_data_get_int(settings, - COLOR_SPACE); - video_range_type colorRange = (video_range_type)obs_data_get_int(settings, - COLOR_RANGE); + BMDVideoConnection videoConnection = + (BMDVideoConnection)obs_data_get_int(settings, + VIDEO_CONNECTION); + BMDAudioConnection audioConnection = + (BMDAudioConnection)obs_data_get_int(settings, + AUDIO_CONNECTION); + BMDPixelFormat pixelFormat = + (BMDPixelFormat)obs_data_get_int(settings, PIXEL_FORMAT); + video_colorspace colorSpace = + (video_colorspace)obs_data_get_int(settings, COLOR_SPACE); + video_range_type colorRange = + (video_range_type)obs_data_get_int(settings, COLOR_RANGE); int chFmtInt = (int)obs_data_get_int(settings, CHANNEL_FORMAT); if (chFmtInt == 7) @@ -63,10 +66,10 @@ static void decklink_update(void *data, obs_data_t *settings) speaker_layout channelFormat = (speaker_layout)chFmtInt; decklink_enable_buffering(decklink, - obs_data_get_bool(settings, BUFFERING)); + obs_data_get_bool(settings, BUFFERING)); - decklink_deactivate_when_not_showing(decklink, - obs_data_get_bool(settings, DEACTIVATE_WNS)); + decklink_deactivate_when_not_showing( + decklink, obs_data_get_bool(settings, DEACTIVATE_WNS)); ComPtr device; device.Set(deviceEnum->FindByHash(hash)); @@ -88,8 +91,9 @@ static void decklink_show(void *data) if (decklink->dwns && showing && !decklink->Capturing()) { ComPtr device; device.Set(deviceEnum->FindByHash(decklink->hash.c_str())); - decklink->Activate(device, decklink->id, decklink->videoConnection, - decklink->audioConnection); + decklink->Activate(device, decklink->id, + decklink->videoConnection, + decklink->audioConnection); } } static void decklink_hide(void *data) @@ -111,13 +115,13 @@ static void decklink_get_defaults(obs_data_t *settings) obs_data_set_default_bool(settings, SWAP, false); } -static const char *decklink_get_name(void*) +static const char *decklink_get_name(void *) { return obs_module_text("BlackmagicDevice"); } static bool decklink_device_changed(obs_properties_t *props, - obs_property_t *list, obs_data_t *settings) + obs_property_t *list, obs_data_t *settings) { const char *name = obs_data_get_string(settings, DEVICE_NAME); const char *hash = obs_data_get_string(settings, DEVICE_HASH); @@ -140,10 +144,10 @@ static bool decklink_device_changed(obs_properties_t *props, obs_property_list_item_disable(list, 0, true); } - obs_property_t *videoConnectionList = obs_properties_get(props, - VIDEO_CONNECTION); - obs_property_t *audioConnectionList = obs_properties_get(props, - AUDIO_CONNECTION); + obs_property_t *videoConnectionList = + obs_properties_get(props, VIDEO_CONNECTION); + obs_property_t *audioConnectionList = + obs_properties_get(props, AUDIO_CONNECTION); obs_property_t *modeList = obs_properties_get(props, MODE_ID); obs_property_t *channelList = obs_properties_get(props, CHANNEL_FORMAT); @@ -154,9 +158,9 @@ static bool decklink_device_changed(obs_properties_t *props, obs_property_list_clear(channelList); obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_NONE, - SPEAKERS_UNKNOWN); + SPEAKERS_UNKNOWN); obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_2_0CH, - SPEAKERS_STEREO); + SPEAKERS_STEREO); ComPtr device; device.Set(deviceEnum->FindByHash(hash)); @@ -168,60 +172,75 @@ static bool decklink_device_changed(obs_properties_t *props, obs_property_list_item_disable(modeList, 0, true); } else { const BMDVideoConnection BMDVideoConnections[] = { - bmdVideoConnectionSDI, bmdVideoConnectionHDMI, - bmdVideoConnectionOpticalSDI, bmdVideoConnectionComponent, - bmdVideoConnectionComposite, bmdVideoConnectionSVideo - }; + bmdVideoConnectionSDI, + bmdVideoConnectionHDMI, + bmdVideoConnectionOpticalSDI, + bmdVideoConnectionComponent, + bmdVideoConnectionComposite, + bmdVideoConnectionSVideo}; for (BMDVideoConnection conn : BMDVideoConnections) { - if ((device->GetVideoInputConnections() & conn) == conn) { - obs_property_list_add_int(videoConnectionList, - bmd_video_connection_to_name(conn), conn); + if ((device->GetVideoInputConnections() & conn) == + conn) { + obs_property_list_add_int( + videoConnectionList, + bmd_video_connection_to_name(conn), + conn); } } const BMDAudioConnection BMDAudioConnections[] = { - bmdAudioConnectionEmbedded, bmdAudioConnectionAESEBU, - bmdAudioConnectionAnalog, bmdAudioConnectionAnalogXLR, - bmdAudioConnectionAnalogRCA, bmdAudioConnectionMicrophone, - bmdAudioConnectionHeadphones - }; + bmdAudioConnectionEmbedded, + bmdAudioConnectionAESEBU, + bmdAudioConnectionAnalog, + bmdAudioConnectionAnalogXLR, + bmdAudioConnectionAnalogRCA, + bmdAudioConnectionMicrophone, + bmdAudioConnectionHeadphones}; for (BMDAudioConnection conn : BMDAudioConnections) { - if ((device->GetAudioInputConnections() & conn) == conn) { - obs_property_list_add_int(audioConnectionList, - bmd_audio_connection_to_name(conn), conn); + if ((device->GetAudioInputConnections() & conn) == + conn) { + obs_property_list_add_int( + audioConnectionList, + bmd_audio_connection_to_name(conn), + conn); } } - const std::vector &modes = - device->GetInputModes(); + const std::vector &modes = + device->GetInputModes(); for (DeckLinkDeviceMode *mode : modes) { obs_property_list_add_int(modeList, - mode->GetName().c_str(), - mode->GetId()); + mode->GetName().c_str(), + mode->GetId()); } if (device->GetMaxChannel() >= 8) { obs_property_list_add_int(channelList, - TEXT_CHANNEL_FORMAT_2_1CH, SPEAKERS_2POINT1); + TEXT_CHANNEL_FORMAT_2_1CH, + SPEAKERS_2POINT1); obs_property_list_add_int(channelList, - TEXT_CHANNEL_FORMAT_4_0CH, SPEAKERS_4POINT0); + TEXT_CHANNEL_FORMAT_4_0CH, + SPEAKERS_4POINT0); obs_property_list_add_int(channelList, - TEXT_CHANNEL_FORMAT_4_1CH, SPEAKERS_4POINT1); + TEXT_CHANNEL_FORMAT_4_1CH, + SPEAKERS_4POINT1); obs_property_list_add_int(channelList, - TEXT_CHANNEL_FORMAT_5_1CH, SPEAKERS_5POINT1); + TEXT_CHANNEL_FORMAT_5_1CH, + SPEAKERS_5POINT1); obs_property_list_add_int(channelList, - TEXT_CHANNEL_FORMAT_7_1CH, SPEAKERS_7POINT1); + TEXT_CHANNEL_FORMAT_7_1CH, + SPEAKERS_7POINT1); } } return true; } -static bool mode_id_changed(obs_properties_t *props, - obs_property_t *list, obs_data_t *settings) +static bool mode_id_changed(obs_properties_t *props, obs_property_t *list, + obs_data_t *settings) { long long id = obs_data_get_int(settings, MODE_ID); @@ -236,56 +255,65 @@ static obs_properties_t *decklink_get_properties(void *data) obs_properties_t *props = obs_properties_create(); obs_property_t *list = obs_properties_add_list(props, DEVICE_HASH, - TEXT_DEVICE, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + TEXT_DEVICE, + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_set_modified_callback(list, decklink_device_changed); fill_out_devices(list); obs_properties_add_list(props, VIDEO_CONNECTION, TEXT_VIDEO_CONNECTION, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); obs_properties_add_list(props, AUDIO_CONNECTION, TEXT_AUDIO_CONNECTION, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); list = obs_properties_add_list(props, MODE_ID, TEXT_MODE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); obs_property_set_modified_callback(list, mode_id_changed); - list = obs_properties_add_list(props, PIXEL_FORMAT, - TEXT_PIXEL_FORMAT, OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_INT); + list = obs_properties_add_list(props, PIXEL_FORMAT, TEXT_PIXEL_FORMAT, + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); obs_property_list_add_int(list, "8-bit YUV", bmdFormat8BitYUV); obs_property_list_add_int(list, "8-bit BGRA", bmdFormat8BitBGRA); list = obs_properties_add_list(props, COLOR_SPACE, TEXT_COLOR_SPACE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_property_list_add_int(list, TEXT_COLOR_SPACE_DEFAULT, VIDEO_CS_DEFAULT); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(list, TEXT_COLOR_SPACE_DEFAULT, + VIDEO_CS_DEFAULT); obs_property_list_add_int(list, "BT.601", VIDEO_CS_601); obs_property_list_add_int(list, "BT.709", VIDEO_CS_709); list = obs_properties_add_list(props, COLOR_RANGE, TEXT_COLOR_RANGE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_property_list_add_int(list, TEXT_COLOR_RANGE_DEFAULT, VIDEO_RANGE_DEFAULT); - obs_property_list_add_int(list, TEXT_COLOR_RANGE_PARTIAL, VIDEO_RANGE_PARTIAL); - obs_property_list_add_int(list, TEXT_COLOR_RANGE_FULL, VIDEO_RANGE_FULL); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(list, TEXT_COLOR_RANGE_DEFAULT, + VIDEO_RANGE_DEFAULT); + obs_property_list_add_int(list, TEXT_COLOR_RANGE_PARTIAL, + VIDEO_RANGE_PARTIAL); + obs_property_list_add_int(list, TEXT_COLOR_RANGE_FULL, + VIDEO_RANGE_FULL); list = obs_properties_add_list(props, CHANNEL_FORMAT, - TEXT_CHANNEL_FORMAT, OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_INT); + TEXT_CHANNEL_FORMAT, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_NONE, - SPEAKERS_UNKNOWN); + SPEAKERS_UNKNOWN); obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_2_0CH, - SPEAKERS_STEREO); + SPEAKERS_STEREO); obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_2_1CH, - SPEAKERS_2POINT1); + SPEAKERS_2POINT1); obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_4_0CH, - SPEAKERS_4POINT0); + SPEAKERS_4POINT0); obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_4_1CH, - SPEAKERS_4POINT1); + SPEAKERS_4POINT1); obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_5_1CH, - SPEAKERS_5POINT1); + SPEAKERS_5POINT1); obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_7_1CH, - SPEAKERS_7POINT1); + SPEAKERS_7POINT1); obs_property_t *swap = obs_properties_add_bool(props, SWAP, TEXT_SWAP); obs_property_set_long_description(swap, TEXT_SWAP_TOOLTIP); @@ -298,21 +326,22 @@ static obs_properties_t *decklink_get_properties(void *data) return props; } - struct obs_source_info create_decklink_source_info() { struct obs_source_info decklink_source_info = {}; - decklink_source_info.id = "decklink-input"; - decklink_source_info.type = OBS_SOURCE_TYPE_INPUT; - decklink_source_info.output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO | OBS_SOURCE_DO_NOT_DUPLICATE; - decklink_source_info.create = decklink_create; - decklink_source_info.destroy = decklink_destroy; - decklink_source_info.get_defaults = decklink_get_defaults; - decklink_source_info.get_name = decklink_get_name; + decklink_source_info.id = "decklink-input"; + decklink_source_info.type = OBS_SOURCE_TYPE_INPUT; + decklink_source_info.output_flags = OBS_SOURCE_ASYNC_VIDEO | + OBS_SOURCE_AUDIO | + OBS_SOURCE_DO_NOT_DUPLICATE; + decklink_source_info.create = decklink_create; + decklink_source_info.destroy = decklink_destroy; + decklink_source_info.get_defaults = decklink_get_defaults; + decklink_source_info.get_name = decklink_get_name; decklink_source_info.get_properties = decklink_get_properties; - decklink_source_info.update = decklink_update; - decklink_source_info.show = decklink_show; - decklink_source_info.hide = decklink_hide; + decklink_source_info.update = decklink_update; + decklink_source_info.show = decklink_show; + decklink_source_info.hide = decklink_hide; return decklink_source_info; } diff --git a/plugins/decklink/linux/decklink-sdk/.clang-format b/plugins/decklink/linux/decklink-sdk/.clang-format new file mode 100644 index 0000000..6420a46 --- /dev/null +++ b/plugins/decklink/linux/decklink-sdk/.clang-format @@ -0,0 +1,3 @@ +Language: Cpp +SortIncludes: false +DisableFormat: true diff --git a/plugins/decklink/linux/platform.cpp b/plugins/decklink/linux/platform.cpp index ed71f5d..ac7f33f 100644 --- a/plugins/decklink/linux/platform.cpp +++ b/plugins/decklink/linux/platform.cpp @@ -1,6 +1,6 @@ #include "../platform.hpp" -bool DeckLinkStringToStdString(decklink_string_t input, std::string& output) +bool DeckLinkStringToStdString(decklink_string_t input, std::string &output) { if (input == nullptr) return false; diff --git a/plugins/decklink/mac/decklink-sdk/.clang-format b/plugins/decklink/mac/decklink-sdk/.clang-format new file mode 100644 index 0000000..6420a46 --- /dev/null +++ b/plugins/decklink/mac/decklink-sdk/.clang-format @@ -0,0 +1,3 @@ +Language: Cpp +SortIncludes: false +DisableFormat: true diff --git a/plugins/decklink/mac/platform.cpp b/plugins/decklink/mac/platform.cpp index 21ca4ec..2130732 100644 --- a/plugins/decklink/mac/platform.cpp +++ b/plugins/decklink/mac/platform.cpp @@ -1,7 +1,7 @@ #include "../platform.hpp" #include -bool DeckLinkStringToStdString(decklink_string_t input, std::string& output) +bool DeckLinkStringToStdString(decklink_string_t input, std::string &output) { const CFStringRef string = static_cast(input); diff --git a/plugins/decklink/platform.hpp b/plugins/decklink/platform.hpp index b5f7600..b3af22c 100644 --- a/plugins/decklink/platform.hpp +++ b/plugins/decklink/platform.hpp @@ -24,4 +24,4 @@ typedef const char *decklink_string_t; #include -bool DeckLinkStringToStdString(decklink_string_t input, std::string& output); +bool DeckLinkStringToStdString(decklink_string_t input, std::string &output); diff --git a/plugins/decklink/util.cpp b/plugins/decklink/util.cpp index c3055e8..0ebdbc1 100644 --- a/plugins/decklink/util.cpp +++ b/plugins/decklink/util.cpp @@ -3,41 +3,41 @@ const char *bmd_video_connection_to_name(BMDVideoConnection connection) { switch (connection) { - case bmdVideoConnectionSDI: - return "SDI"; - case bmdVideoConnectionHDMI: - return "HDMI"; - case bmdVideoConnectionOpticalSDI: - return "Optical SDI"; - case bmdVideoConnectionComponent: - return "Component"; - case bmdVideoConnectionComposite: - return "Composite"; - case bmdVideoConnectionSVideo: - return "S-Video"; - default: - return "Unknown"; + case bmdVideoConnectionSDI: + return "SDI"; + case bmdVideoConnectionHDMI: + return "HDMI"; + case bmdVideoConnectionOpticalSDI: + return "Optical SDI"; + case bmdVideoConnectionComponent: + return "Component"; + case bmdVideoConnectionComposite: + return "Composite"; + case bmdVideoConnectionSVideo: + return "S-Video"; + default: + return "Unknown"; } } const char *bmd_audio_connection_to_name(BMDAudioConnection connection) { switch (connection) { - case bmdAudioConnectionEmbedded: - return "Embedded"; - case bmdAudioConnectionAESEBU: - return "AES/EBU"; - case bmdAudioConnectionAnalog: - return "Analog"; - case bmdAudioConnectionAnalogXLR: - return "Analog XLR"; - case bmdAudioConnectionAnalogRCA: - return "Analog RCA"; - case bmdAudioConnectionMicrophone: - return "Microphone"; - case bmdAudioConnectionHeadphones: - return "Headphones"; - default: - return "Unknown"; + case bmdAudioConnectionEmbedded: + return "Embedded"; + case bmdAudioConnectionAESEBU: + return "AES/EBU"; + case bmdAudioConnectionAnalog: + return "Analog"; + case bmdAudioConnectionAnalogXLR: + return "Analog XLR"; + case bmdAudioConnectionAnalogRCA: + return "Analog RCA"; + case bmdAudioConnectionMicrophone: + return "Microphone"; + case bmdAudioConnectionHeadphones: + return "Headphones"; + default: + return "Unknown"; } } \ No newline at end of file diff --git a/plugins/decklink/win/platform.cpp b/plugins/decklink/win/platform.cpp index 69d8a6f..c15aae5 100644 --- a/plugins/decklink/win/platform.cpp +++ b/plugins/decklink/win/platform.cpp @@ -5,13 +5,13 @@ IDeckLinkDiscovery *CreateDeckLinkDiscoveryInstance(void) { IDeckLinkDiscovery *instance; - const HRESULT result = CoCreateInstance(CLSID_CDeckLinkDiscovery, - nullptr, CLSCTX_ALL, IID_IDeckLinkDiscovery, - (void **)&instance); + const HRESULT result = + CoCreateInstance(CLSID_CDeckLinkDiscovery, nullptr, CLSCTX_ALL, + IID_IDeckLinkDiscovery, (void **)&instance); return result == S_OK ? instance : nullptr; } -bool DeckLinkStringToStdString(decklink_string_t input, std::string& output) +bool DeckLinkStringToStdString(decklink_string_t input, std::string &output) { if (input == nullptr) return false; diff --git a/plugins/image-source/color-source.c b/plugins/image-source/color-source.c index 7cfa159..28b750a 100644 --- a/plugins/image-source/color-source.c +++ b/plugins/image-source/color-source.c @@ -51,13 +51,15 @@ static obs_properties_t *color_source_properties(void *unused) obs_properties_t *props = obs_properties_create(); obs_properties_add_color(props, "color", - obs_module_text("ColorSource.Color")); + obs_module_text("ColorSource.Color")); obs_properties_add_int(props, "width", - obs_module_text("ColorSource.Width"), 0, 4096, 1); + obs_module_text("ColorSource.Width"), 0, 4096, + 1); obs_properties_add_int(props, "height", - obs_module_text("ColorSource.Height"), 0, 4096, 1); + obs_module_text("ColorSource.Height"), 0, 4096, + 1); return props; } @@ -68,9 +70,9 @@ static void color_source_render(void *data, gs_effect_t *effect) struct color_source *context = data; - gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID); - gs_eparam_t *color = gs_effect_get_param_by_name(solid, "color"); - gs_technique_t *tech = gs_effect_get_technique(solid, "Solid"); + gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID); + gs_eparam_t *color = gs_effect_get_param_by_name(solid, "color"); + gs_technique_t *tech = gs_effect_get_technique(solid, "Solid"); struct vec4 colorVal; vec4_from_rgba(&colorVal, context->color); @@ -99,25 +101,22 @@ static uint32_t color_source_getheight(void *data) static void color_source_defaults(obs_data_t *settings) { - struct obs_video_info ovi; - obs_get_video_info(&ovi); - obs_data_set_default_int(settings, "color", 0xFFFFFFFF); - obs_data_set_default_int(settings, "width", ovi.base_width); - obs_data_set_default_int(settings, "height", ovi.base_height); + obs_data_set_default_int(settings, "width", 400); + obs_data_set_default_int(settings, "height", 400); } struct obs_source_info color_source_info = { - .id = "color_source", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW, - .create = color_source_create, - .destroy = color_source_destroy, - .update = color_source_update, - .get_name = color_source_get_name, - .get_defaults = color_source_defaults, - .get_width = color_source_getwidth, - .get_height = color_source_getheight, - .video_render = color_source_render, - .get_properties = color_source_properties + .id = "color_source", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW, + .create = color_source_create, + .destroy = color_source_destroy, + .update = color_source_update, + .get_name = color_source_get_name, + .get_defaults = color_source_defaults, + .get_width = color_source_getwidth, + .get_height = color_source_getheight, + .video_render = color_source_render, + .get_properties = color_source_properties, }; diff --git a/plugins/image-source/data/locale/es-ES.ini b/plugins/image-source/data/locale/es-ES.ini index 3ca74fc..b015520 100644 --- a/plugins/image-source/data/locale/es-ES.ini +++ b/plugins/image-source/data/locale/es-ES.ini @@ -13,8 +13,8 @@ SlideShow.Loop="Bucle" SlideShow.Transition="Transición" SlideShow.Transition.Cut="Corte" SlideShow.Transition.Fade="Desvanecimiento" -SlideShow.Transition.Swipe="Deslizar Rapido" -SlideShow.Transition.Slide="Deslizar" +SlideShow.Transition.Swipe="Deslizar" +SlideShow.Transition.Slide="Diapositiva" SlideShow.PlaybackBehavior="Comportamiento de visibilidad" SlideShow.PlaybackBehavior.StopRestart="Detener cuando no sea visible, reiniciar cuando sea visible" SlideShow.PlaybackBehavior.PauseUnpause="Pausar cuando no sea visible, reanudar cuando sea visible" diff --git a/plugins/image-source/data/locale/gl-ES.ini b/plugins/image-source/data/locale/gl-ES.ini index 5afd1f9..21ffbbf 100644 --- a/plugins/image-source/data/locale/gl-ES.ini +++ b/plugins/image-source/data/locale/gl-ES.ini @@ -1,6 +1,36 @@ ImageInput="Imaxe" File="Ficheiro de imaxe" -UnloadWhenNotShowing="Non descargar a imaxe cando non se mostre" +UnloadWhenNotShowing="Descargar a imaxe cando non se amosa" +SlideShow="Diaporama" +SlideShow.TransitionSpeed="Velocidade da transición (milisegundos)" +SlideShow.SlideTime="Tempo entre diapositivas (milisegundos)" +SlideShow.Files="Ficheiros de imaxe" +SlideShow.CustomSize="Límite do tamaño/relación de aspecto" +SlideShow.CustomSize.Auto="Automático" +SlideShow.Randomize="Reproducir ao chou" +SlideShow.Loop="Bucle" +SlideShow.Transition="Transición" +SlideShow.Transition.Cut="Cortar" +SlideShow.Transition.Fade="Esvaecer" +SlideShow.Transition.Swipe="Esvarar" +SlideShow.Transition.Slide="Diapositiva" +SlideShow.PlaybackBehavior="Comportamento da visibilidade" +SlideShow.PlaybackBehavior.StopRestart="Parar cando non é visíbel, reiniciar cando sexa visíbel" +SlideShow.PlaybackBehavior.PauseUnpause="Pór en pausa cando non é visíbel, reiniciar cando sexa visíbel" +SlideShow.PlaybackBehavior.AlwaysPlay="Reproducir sempre cando non estea visíbel" +SlideShow.SlideMode="Modo de diapositiva" +SlideShow.SlideMode.Auto="Automático" +SlideShow.SlideMode.Manual="Manual (use as teclas rápidas para controlar o disporama)" +SlideShow.PlayPause="Reproducir/Pór en pausa" +SlideShow.Restart="Reiniciar" +SlideShow.Stop="Parar" +SlideShow.NextSlide="Seguinte diapositiva" +SlideShow.PreviousSlide="Diapositiva anterior" +SlideShow.HideWhenDone="Agochar cando se reproduce o diaporama" +ColorSource="Orixe da cor" +ColorSource.Color="Cor" +ColorSource.Width="Largo" +ColorSource.Height="Alto" diff --git a/plugins/image-source/data/locale/ro-RO.ini b/plugins/image-source/data/locale/ro-RO.ini index 9619905..ad100b9 100644 --- a/plugins/image-source/data/locale/ro-RO.ini +++ b/plugins/image-source/data/locale/ro-RO.ini @@ -13,6 +13,7 @@ SlideShow.Transition.Cut="Decupare" SlideShow.Transition.Fade="Estompare" SlideShow.Transition.Swipe="Glisare" SlideShow.Transition.Slide="Culisare" +SlideShow.SlideMode="Mod de culisare" SlideShow.SlideMode.Auto="Automat" SlideShow.PlayPause="Redă/Pune pe pauză" SlideShow.Restart="Repornește" diff --git a/plugins/image-source/data/locale/sl-SI.ini b/plugins/image-source/data/locale/sl-SI.ini index e3f71a3..e0b6474 100644 --- a/plugins/image-source/data/locale/sl-SI.ini +++ b/plugins/image-source/data/locale/sl-SI.ini @@ -1,6 +1,36 @@ ImageInput="Slika" File="Slikovna datoteka" -UnloadWhenNotShowing="Ne naloži slike, ko ni prikazana" +UnloadWhenNotShowing="Razloži sliko, ko ni prikazana" +SlideShow="Slikovna predstavitev" +SlideShow.TransitionSpeed="Hitrost prehodov (ms)" +SlideShow.SlideTime="Čas med slikami (ms)" +SlideShow.Files="Slikovne datoteke" +SlideShow.CustomSize="Omejitev velikost/Razmerje" +SlideShow.CustomSize.Auto="Samodejno" +SlideShow.Randomize="Naključno predvajanje" +SlideShow.Loop="Ponavljaj" +SlideShow.Transition="Prehod" +SlideShow.Transition.Cut="Izreži" +SlideShow.Transition.Fade="Pojemaj" +SlideShow.Transition.Swipe="Potegni" +SlideShow.Transition.Slide="Podrsaj" +SlideShow.PlaybackBehavior="Vedenje vidnosti" +SlideShow.PlaybackBehavior.StopRestart="Ustavi, ko ni vidno; ponovno zaženi, ko je vidno" +SlideShow.PlaybackBehavior.PauseUnpause="Premor, ko ni vidno; nadaljuj, ko je vidno" +SlideShow.PlaybackBehavior.AlwaysPlay="Vedno predvajaj, ko ni vidno" +SlideShow.SlideMode="Način predstavitve" +SlideShow.SlideMode.Auto="Samodejno" +SlideShow.SlideMode.Manual="Ročno (uporabi hitre tipke na nadzor predstavitve)" +SlideShow.PlayPause="Predvajaj/Premor" +SlideShow.Restart="Ponovno zaženi" +SlideShow.Stop="Ustavi" +SlideShow.NextSlide="Naslednja slika" +SlideShow.PreviousSlide="Prejšnja slika" +SlideShow.HideWhenDone="Skrij, ko je predstavitev končana" +ColorSource="Barvni vir" +ColorSource.Color="Barva" +ColorSource.Width="Širina" +ColorSource.Height="Višina" diff --git a/plugins/image-source/image-source.c b/plugins/image-source/image-source.c index 1c3fa34..c3fde02 100644 --- a/plugins/image-source/image-source.c +++ b/plugins/image-source/image-source.c @@ -4,31 +4,27 @@ #include #include -#define blog(log_level, format, ...) \ +#define blog(log_level, format, ...) \ blog(log_level, "[image_source: '%s'] " format, \ - obs_source_get_name(context->source), ##__VA_ARGS__) + obs_source_get_name(context->source), ##__VA_ARGS__) -#define debug(format, ...) \ - blog(LOG_DEBUG, format, ##__VA_ARGS__) -#define info(format, ...) \ - blog(LOG_INFO, format, ##__VA_ARGS__) -#define warn(format, ...) \ - blog(LOG_WARNING, format, ##__VA_ARGS__) +#define debug(format, ...) blog(LOG_DEBUG, format, ##__VA_ARGS__) +#define info(format, ...) blog(LOG_INFO, format, ##__VA_ARGS__) +#define warn(format, ...) blog(LOG_WARNING, format, ##__VA_ARGS__) struct image_source { obs_source_t *source; - char *file; - bool persistent; - time_t file_timestamp; - float update_time_elapsed; - uint64_t last_time; - bool active; + char *file; + bool persistent; + time_t file_timestamp; + float update_time_elapsed; + uint64_t last_time; + bool active; gs_image_file2_t if2; }; - static time_t get_modified_timestamp(const char *filename) { struct stat stats; @@ -152,9 +148,9 @@ static void image_source_render(void *data, gs_effect_t *effect) return; gs_effect_set_texture(gs_effect_get_param_by_name(effect, "image"), - context->if2.image.texture); - gs_draw_sprite(context->if2.image.texture, 0, - context->if2.image.cx, context->if2.image.cy); + context->if2.image.texture); + gs_draw_sprite(context->if2.image.texture, 0, context->if2.image.cx, + context->if2.image.cy); } static void image_source_tick(void *data, float seconds) @@ -212,7 +208,6 @@ static void image_source_tick(void *data, float seconds) context->last_time = frame_time; } - static const char *image_filter = "All formats (*.bmp *.tga *.png *.jpeg *.jpg *.gif *.psd);;" "BMP Files (*.bmp);;" @@ -240,11 +235,10 @@ static obs_properties_t *image_source_properties(void *data) dstr_resize(&path, slash - path.array + 1); } - obs_properties_add_path(props, - "file", obs_module_text("File"), - OBS_PATH_FILE, image_filter, path.array); - obs_properties_add_bool(props, - "unload", obs_module_text("UnloadWhenNotShowing")); + obs_properties_add_path(props, "file", obs_module_text("File"), + OBS_PATH_FILE, image_filter, path.array); + obs_properties_add_bool(props, "unload", + obs_module_text("UnloadWhenNotShowing")); dstr_free(&path); return props; @@ -257,22 +251,21 @@ uint64_t image_source_get_memory_usage(void *data) } static struct obs_source_info image_source_info = { - .id = "image_source", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_VIDEO, - .get_name = image_source_get_name, - .create = image_source_create, - .destroy = image_source_destroy, - .update = image_source_update, - .get_defaults = image_source_defaults, - .show = image_source_show, - .hide = image_source_hide, - .get_width = image_source_getwidth, - .get_height = image_source_getheight, - .video_render = image_source_render, - .video_tick = image_source_tick, - .get_properties = image_source_properties -}; + .id = "image_source", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_VIDEO, + .get_name = image_source_get_name, + .create = image_source_create, + .destroy = image_source_destroy, + .update = image_source_update, + .get_defaults = image_source_defaults, + .show = image_source_show, + .hide = image_source_hide, + .get_width = image_source_getwidth, + .get_height = image_source_getheight, + .video_render = image_source_render, + .video_tick = image_source_tick, + .get_properties = image_source_properties}; OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("image-source", "en-US") diff --git a/plugins/image-source/obs-slideshow.c b/plugins/image-source/obs-slideshow.c index 4dc1038..ae4cd8d 100644 --- a/plugins/image-source/obs-slideshow.c +++ b/plugins/image-source/obs-slideshow.c @@ -4,11 +4,13 @@ #include #include -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[slideshow: '%s'] " format, \ - obs_source_get_name(ss->source), ##__VA_ARGS__) + obs_source_get_name(ss->source), ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) + +/* clang-format off */ #define S_TR_SPEED "transition_speed" #define S_CUSTOM_SIZE "use_custom_size" @@ -55,12 +57,14 @@ #define T_TR_SWIPE T_TR_("Swipe") #define T_TR_SLIDE T_TR_("Slide") +/* clang-format on */ + /* ------------------------------------------------------------------------- */ extern uint64_t image_source_get_memory_usage(void *data); #define BYTES_TO_MBYTES (1024 * 1024) -#define MAX_MEM_USAGE (250 * BYTES_TO_MBYTES) +#define MAX_MEM_USAGE (250 * BYTES_TO_MBYTES) struct image_file_data { char *path; @@ -182,7 +186,7 @@ static const char *ss_getname(void *unused) } static void add_file(struct slideshow *ss, struct darray *array, - const char *path, uint32_t *cx, uint32_t *cy) + const char *path, uint32_t *cx, uint32_t *cy) { DARRAY(struct image_file_data) new_files; struct image_file_data data; @@ -207,8 +211,10 @@ static void add_file(struct slideshow *ss, struct darray *array, data.source = new_source; da_push_back(new_files, &data); - if (new_cx > *cx) *cx = new_cx; - if (new_cy > *cy) *cy = new_cy; + if (new_cx > *cx) + *cx = new_cx; + if (new_cy > *cy) + *cy = new_cy; void *source_data = obs_obj_get_data(new_source); ss->mem_usage += image_source_get_memory_usage(source_data); @@ -221,12 +227,9 @@ static bool valid_extension(const char *ext) { if (!ext) return false; - return astrcmpi(ext, ".bmp") == 0 || - astrcmpi(ext, ".tga") == 0 || - astrcmpi(ext, ".png") == 0 || - astrcmpi(ext, ".jpeg") == 0 || - astrcmpi(ext, ".jpg") == 0 || - astrcmpi(ext, ".gif") == 0; + return astrcmpi(ext, ".bmp") == 0 || astrcmpi(ext, ".tga") == 0 || + astrcmpi(ext, ".png") == 0 || astrcmpi(ext, ".jpeg") == 0 || + astrcmpi(ext, ".jpg") == 0 || astrcmpi(ext, ".gif") == 0; } static inline bool item_valid(struct slideshow *ss) @@ -241,19 +244,16 @@ static void do_transition(void *data, bool to_null) if (valid && ss->use_cut) obs_transition_set(ss->transition, - ss->files.array[ss->cur_item].source); + ss->files.array[ss->cur_item].source); else if (valid && !to_null) - obs_transition_start(ss->transition, - OBS_TRANSITION_MODE_AUTO, - ss->tr_speed, - ss->files.array[ss->cur_item].source); + obs_transition_start(ss->transition, OBS_TRANSITION_MODE_AUTO, + ss->tr_speed, + ss->files.array[ss->cur_item].source); else - obs_transition_start(ss->transition, - OBS_TRANSITION_MODE_AUTO, - ss->tr_speed, - NULL); + obs_transition_start(ss->transition, OBS_TRANSITION_MODE_AUTO, + ss->tr_speed, NULL); } static void ss_update(void *data, obs_data_t *settings) @@ -344,8 +344,8 @@ static void ss_update(void *data, obs_data_t *settings) dstr_copy(&dir_path, path); dstr_cat_ch(&dir_path, '/'); dstr_cat(&dir_path, ent->d_name); - add_file(ss, &new_files.da, dir_path.array, - &cx, &cy); + add_file(ss, &new_files.da, dir_path.array, &cx, + &cy); if (ss->mem_usage >= MAX_MEM_USAGE) break; @@ -447,7 +447,7 @@ static void ss_update(void *data, obs_data_t *settings) obs_transition_set_size(ss->transition, cx, cy); obs_transition_set_alignment(ss->transition, OBS_ALIGN_CENTER); obs_transition_set_scale_type(ss->transition, - OBS_TRANSITION_SCALE_ASPECT); + OBS_TRANSITION_SCALE_ASPECT); if (ss->randomize && ss->files.num) ss->cur_item = random_file(ss); @@ -475,7 +475,7 @@ static void ss_restart(void *data) ss->cur_item = 0; obs_transition_set(ss->transition, - ss->files.array[ss->cur_item].source); + ss->files.array[ss->cur_item].source); ss->stop = false; ss->paused = false; @@ -522,7 +522,7 @@ static void ss_previous_slide(void *data) } static void play_pause_hotkey(void *data, obs_hotkey_id id, - obs_hotkey_t *hotkey, bool pressed) + obs_hotkey_t *hotkey, bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(hotkey); @@ -533,8 +533,8 @@ static void play_pause_hotkey(void *data, obs_hotkey_id id, ss_play_pause(ss); } -static void restart_hotkey(void *data, obs_hotkey_id id, - obs_hotkey_t *hotkey, bool pressed) +static void restart_hotkey(void *data, obs_hotkey_id id, obs_hotkey_t *hotkey, + bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(hotkey); @@ -545,8 +545,8 @@ static void restart_hotkey(void *data, obs_hotkey_id id, ss_restart(ss); } -static void stop_hotkey(void *data, obs_hotkey_id id, - obs_hotkey_t *hotkey, bool pressed) +static void stop_hotkey(void *data, obs_hotkey_id id, obs_hotkey_t *hotkey, + bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(hotkey); @@ -558,7 +558,7 @@ static void stop_hotkey(void *data, obs_hotkey_id id, } static void next_slide_hotkey(void *data, obs_hotkey_id id, - obs_hotkey_t *hotkey, bool pressed) + obs_hotkey_t *hotkey, bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(hotkey); @@ -573,7 +573,7 @@ static void next_slide_hotkey(void *data, obs_hotkey_id id, } static void previous_slide_hotkey(void *data, obs_hotkey_id id, - obs_hotkey_t *hotkey, bool pressed) + obs_hotkey_t *hotkey, bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(hotkey); @@ -607,30 +607,26 @@ static void *ss_create(obs_data_t *settings, obs_source_t *source) ss->paused = false; ss->stop = false; - ss->play_pause_hotkey = obs_hotkey_register_source(source, - "SlideShow.PlayPause", - obs_module_text("SlideShow.PlayPause"), - play_pause_hotkey, ss); + ss->play_pause_hotkey = obs_hotkey_register_source( + source, "SlideShow.PlayPause", + obs_module_text("SlideShow.PlayPause"), play_pause_hotkey, ss); - ss->restart_hotkey = obs_hotkey_register_source(source, - "SlideShow.Restart", - obs_module_text("SlideShow.Restart"), - restart_hotkey, ss); + ss->restart_hotkey = obs_hotkey_register_source( + source, "SlideShow.Restart", + obs_module_text("SlideShow.Restart"), restart_hotkey, ss); - ss->stop_hotkey = obs_hotkey_register_source(source, - "SlideShow.Stop", - obs_module_text("SlideShow.Stop"), - stop_hotkey, ss); + ss->stop_hotkey = obs_hotkey_register_source( + source, "SlideShow.Stop", obs_module_text("SlideShow.Stop"), + stop_hotkey, ss); - ss->prev_hotkey = obs_hotkey_register_source(source, - "SlideShow.NextSlide", - obs_module_text("SlideShow.NextSlide"), - next_slide_hotkey, ss); + ss->prev_hotkey = obs_hotkey_register_source( + source, "SlideShow.NextSlide", + obs_module_text("SlideShow.NextSlide"), next_slide_hotkey, ss); - ss->prev_hotkey = obs_hotkey_register_source(source, - "SlideShow.PreviousSlide", - obs_module_text("SlideShow.PreviousSlide"), - previous_slide_hotkey, ss); + ss->prev_hotkey = obs_hotkey_register_source( + source, "SlideShow.PreviousSlide", + obs_module_text("SlideShow.PreviousSlide"), + previous_slide_hotkey, ss); pthread_mutex_init_value(&ss->mutex); if (pthread_mutex_init(&ss->mutex, NULL) != 0) @@ -682,7 +678,7 @@ static void ss_video_tick(void *data, float seconds) /* ----------------------------------------------------- */ /* fade to transparency when the file list becomes empty */ if (!ss->files.num) { - obs_source_t* active_transition_source = + obs_source_t *active_transition_source = obs_transition_get_active_source(ss->transition); if (active_transition_source) { @@ -725,8 +721,9 @@ static void ss_video_tick(void *data, float seconds) } static inline bool ss_audio_render_(obs_source_t *transition, uint64_t *ts_out, - struct obs_source_audio_mix *audio_output, - uint32_t mixers, size_t channels, size_t sample_rate) + struct obs_source_audio_mix *audio_output, + uint32_t mixers, size_t channels, + size_t sample_rate) { struct obs_source_audio_mix child_audio; uint64_t source_ts; @@ -747,8 +744,9 @@ static inline bool ss_audio_render_(obs_source_t *transition, uint64_t *ts_out, float *out = audio_output->output[mix].data[ch]; float *in = child_audio.output[mix].data[ch]; - memcpy(out, in, AUDIO_OUTPUT_FRAMES * - MAX_AUDIO_CHANNELS * sizeof(float)); + memcpy(out, in, + AUDIO_OUTPUT_FRAMES * MAX_AUDIO_CHANNELS * + sizeof(float)); } } @@ -759,8 +757,9 @@ static inline bool ss_audio_render_(obs_source_t *transition, uint64_t *ts_out, } static bool ss_audio_render(void *data, uint64_t *ts_out, - struct obs_source_audio_mix *audio_output, - uint32_t mixers, size_t channels, size_t sample_rate) + struct obs_source_audio_mix *audio_output, + uint32_t mixers, size_t channels, + size_t sample_rate) { struct slideshow *ss = data; obs_source_t *transition = get_transition(ss); @@ -770,7 +769,7 @@ static bool ss_audio_render(void *data, uint64_t *ts_out, return false; success = ss_audio_render_(transition, ts_out, audio_output, mixers, - channels, sample_rate); + channels, sample_rate); obs_source_release(transition); return success; @@ -803,9 +802,10 @@ static void ss_defaults(obs_data_t *settings) obs_data_set_default_string(settings, S_TRANSITION, "fade"); obs_data_set_default_int(settings, S_SLIDE_TIME, 8000); obs_data_set_default_int(settings, S_TR_SPEED, 700); - obs_data_set_default_string(settings, S_CUSTOM_SIZE, T_CUSTOM_SIZE_AUTO); + obs_data_set_default_string(settings, S_CUSTOM_SIZE, + T_CUSTOM_SIZE_AUTO); obs_data_set_default_string(settings, S_BEHAVIOR, - S_BEHAVIOR_ALWAYS_PLAY); + S_BEHAVIOR_ALWAYS_PLAY); obs_data_set_default_string(settings, S_MODE, S_MODE_AUTO); obs_data_set_default_bool(settings, S_LOOP, true); } @@ -813,12 +813,7 @@ static void ss_defaults(obs_data_t *settings) static const char *file_filter = "Image files (*.bmp *.tga *.png *.jpeg *.jpg *.gif)"; -static const char *aspects[] = { - "16:9", - "16:10", - "4:3", - "1:1" -}; +static const char *aspects[] = {"16:9", "16:10", "4:3", "1:1"}; #define NUM_ASPECTS (sizeof(aspects) / sizeof(const char *)) @@ -841,36 +836,38 @@ static obs_properties_t *ss_properties(void *data) /* ----------------- */ p = obs_properties_add_list(ppts, S_BEHAVIOR, T_BEHAVIOR, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, T_BEHAVIOR_ALWAYS_PLAY, - S_BEHAVIOR_ALWAYS_PLAY); + S_BEHAVIOR_ALWAYS_PLAY); obs_property_list_add_string(p, T_BEHAVIOR_STOP_RESTART, - S_BEHAVIOR_STOP_RESTART); + S_BEHAVIOR_STOP_RESTART); obs_property_list_add_string(p, T_BEHAVIOR_PAUSE_UNPAUSE, - S_BEHAVIOR_PAUSE_UNPAUSE); + S_BEHAVIOR_PAUSE_UNPAUSE); - p = obs_properties_add_list(ppts, S_MODE, T_MODE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + p = obs_properties_add_list(ppts, S_MODE, T_MODE, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, T_MODE_AUTO, S_MODE_AUTO); obs_property_list_add_string(p, T_MODE_MANUAL, S_MODE_MANUAL); p = obs_properties_add_list(ppts, S_TRANSITION, T_TRANSITION, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, T_TR_CUT, TR_CUT); obs_property_list_add_string(p, T_TR_FADE, TR_FADE); obs_property_list_add_string(p, T_TR_SWIPE, TR_SWIPE); obs_property_list_add_string(p, T_TR_SLIDE, TR_SLIDE); - obs_properties_add_int(ppts, S_SLIDE_TIME, T_SLIDE_TIME, - 50, 3600000, 50); - obs_properties_add_int(ppts, S_TR_SPEED, T_TR_SPEED, - 0, 3600000, 50); + obs_properties_add_int(ppts, S_SLIDE_TIME, T_SLIDE_TIME, 50, 3600000, + 50); + obs_properties_add_int(ppts, S_TR_SPEED, T_TR_SPEED, 0, 3600000, 50); obs_properties_add_bool(ppts, S_LOOP, T_LOOP); obs_properties_add_bool(ppts, S_HIDE, T_HIDE); obs_properties_add_bool(ppts, S_RANDOMIZE, T_RANDOMIZE); p = obs_properties_add_list(ppts, S_CUSTOM_SIZE, T_CUSTOM_SIZE, - OBS_COMBO_TYPE_EDITABLE, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_EDITABLE, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, T_CUSTOM_SIZE_AUTO, T_CUSTOM_SIZE_AUTO); @@ -897,7 +894,8 @@ static obs_properties_t *ss_properties(void *data) } obs_properties_add_editable_list(ppts, S_FILES, T_FILES, - OBS_EDITABLE_LIST_TYPE_FILES, file_filter, path.array); + OBS_EDITABLE_LIST_TYPE_FILES, + file_filter, path.array); dstr_free(&path); return ppts; @@ -924,23 +922,22 @@ static void ss_deactivate(void *data) } struct obs_source_info slideshow_info = { - .id = "slideshow", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_VIDEO | - OBS_SOURCE_CUSTOM_DRAW | - OBS_SOURCE_COMPOSITE, - .get_name = ss_getname, - .create = ss_create, - .destroy = ss_destroy, - .update = ss_update, - .activate = ss_activate, - .deactivate = ss_deactivate, - .video_render = ss_video_render, - .video_tick = ss_video_tick, - .audio_render = ss_audio_render, + .id = "slideshow", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW | + OBS_SOURCE_COMPOSITE, + .get_name = ss_getname, + .create = ss_create, + .destroy = ss_destroy, + .update = ss_update, + .activate = ss_activate, + .deactivate = ss_deactivate, + .video_render = ss_video_render, + .video_tick = ss_video_tick, + .audio_render = ss_audio_render, .enum_active_sources = ss_enum_sources, - .get_width = ss_width, - .get_height = ss_height, - .get_defaults = ss_defaults, - .get_properties = ss_properties + .get_width = ss_width, + .get_height = ss_height, + .get_defaults = ss_defaults, + .get_properties = ss_properties, }; diff --git a/plugins/linux-alsa/alsa-input.c b/plugins/linux-alsa/alsa-input.c index 72ce1d4..d0253db 100644 --- a/plugins/linux-alsa/alsa-input.c +++ b/plugins/linux-alsa/alsa-input.c @@ -29,7 +29,7 @@ along with this program. If not, see . #define blog(level, msg, ...) blog(level, "alsa-input: " msg, ##__VA_ARGS__) -#define NSEC_PER_SEC 1000000000LL +#define NSEC_PER_SEC 1000000000LL #define NSEC_PER_MSEC 1000000L #define STARTUP_TIMEOUT_NS (500 * NSEC_PER_MSEC) #define REOPEN_TIMEOUT 1000UL @@ -63,11 +63,11 @@ struct alsa_data { uint64_t first_ts; }; -static const char * alsa_get_name(void *); -static bool alsa_devices_changed(obs_properties_t *props, - obs_property_t *p, obs_data_t *settings); -static obs_properties_t * alsa_get_properties(void *); -static void * alsa_create(obs_data_t *, obs_source_t *); +static const char *alsa_get_name(void *); +static bool alsa_devices_changed(obs_properties_t *props, obs_property_t *p, + obs_data_t *settings); +static obs_properties_t *alsa_get_properties(void *); +static void *alsa_create(obs_data_t *, obs_source_t *); static void alsa_destroy(void *); static void alsa_activate(void *); static void alsa_deactivate(void *); @@ -75,19 +75,19 @@ static void alsa_get_defaults(obs_data_t *); static void alsa_update(void *, obs_data_t *); struct obs_source_info alsa_input_capture = { - .id = "alsa_input_capture", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_AUDIO, - .create = alsa_create, - .destroy = alsa_destroy, + .id = "alsa_input_capture", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_AUDIO, + .create = alsa_create, + .destroy = alsa_destroy, #if SHUTDOWN_ON_DEACTIVATE - .activate = alsa_activate, - .deactivate = alsa_deactivate, + .activate = alsa_activate, + .deactivate = alsa_deactivate, #endif - .update = alsa_update, - .get_defaults = alsa_get_defaults, - .get_name = alsa_get_name, - .get_properties = alsa_get_properties + .update = alsa_update, + .get_defaults = alsa_get_defaults, + .get_name = alsa_get_name, + .get_properties = alsa_get_properties, }; static bool _alsa_try_open(struct alsa_data *); @@ -96,28 +96,28 @@ static void _alsa_close(struct alsa_data *); static bool _alsa_configure(struct alsa_data *); static void _alsa_start_reopen(struct alsa_data *); static void _alsa_stop_reopen(struct alsa_data *); -static void * _alsa_listen(void *); -static void * _alsa_reopen(void *); +static void *_alsa_listen(void *); +static void *_alsa_reopen(void *); static enum audio_format _alsa_to_obs_audio_format(snd_pcm_format_t); static enum speaker_layout _alsa_channels_to_obs_speakers(unsigned int); /*****************************************************************************/ -void * alsa_create(obs_data_t *settings, obs_source_t *source) +void *alsa_create(obs_data_t *settings, obs_source_t *source) { struct alsa_data *data = bzalloc(sizeof(struct alsa_data)); - data->source = source; + data->source = source; #if SHUTDOWN_ON_DEACTIVATE - data->active = false; + data->active = false; #endif - data->buffer = NULL; - data->device = NULL; + data->buffer = NULL; + data->device = NULL; data->first_ts = 0; - data->handle = NULL; - data->listen = false; - data->reopen = false; + data->handle = NULL; + data->listen = false; + data->reopen = false; data->listen_thread = 0; data->reopen_thread = 0; @@ -217,7 +217,7 @@ void alsa_update(void *vptr, obs_data_t *settings) #endif } -const char * alsa_get_name(void *unused) +const char *alsa_get_name(void *unused) { UNUSED_PARAMETER(unused); return obs_module_text("AlsaInput"); @@ -230,8 +230,8 @@ void alsa_get_defaults(obs_data_t *settings) obs_data_set_default_int(settings, "rate", 44100); } -static bool alsa_devices_changed(obs_properties_t *props, - obs_property_t *p, obs_data_t *settings) +static bool alsa_devices_changed(obs_properties_t *props, obs_property_t *p, + obs_data_t *settings) { UNUSED_PARAMETER(p); bool visible = false; @@ -248,14 +248,14 @@ static bool alsa_devices_changed(obs_properties_t *props, return true; } -obs_properties_t * alsa_get_properties(void *unused) +obs_properties_t *alsa_get_properties(void *unused) { void **hints; void **hint; char *name = NULL; char *descr = NULL; char *io = NULL; - char *descr_i; + char *descr_i; obs_properties_t *props; obs_property_t *devices; obs_property_t *rate; @@ -265,17 +265,18 @@ obs_properties_t * alsa_get_properties(void *unused) props = obs_properties_create(); devices = obs_properties_add_list(props, "device_id", - obs_module_text("Device"), OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_STRING); + obs_module_text("Device"), + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(devices, "Default", "default"); - obs_properties_add_text(props, "custom_pcm", - obs_module_text("PCM"), OBS_TEXT_DEFAULT); + obs_properties_add_text(props, "custom_pcm", obs_module_text("PCM"), + OBS_TEXT_DEFAULT); - rate = obs_properties_add_list(props, "rate", - obs_module_text("Rate"), OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_INT); + rate = obs_properties_add_list(props, "rate", obs_module_text("Rate"), + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); obs_property_set_modified_callback(devices, alsa_devices_changed); @@ -304,10 +305,10 @@ obs_properties_t * alsa_get_properties(void *unused) descr_i = descr; while (*descr_i) { if (*descr_i == '\n') { - *descr_i = '\0'; - break; - } - else ++descr_i; + *descr_i = '\0'; + break; + } else + ++descr_i; } obs_property_list_add_string(devices, descr, name); @@ -350,11 +351,11 @@ bool _alsa_open(struct alsa_data *data) pthread_attr_t attr; int err; - err = snd_pcm_open(&data->handle, data->device, - SND_PCM_STREAM_CAPTURE, 0); + err = snd_pcm_open(&data->handle, data->device, SND_PCM_STREAM_CAPTURE, + 0); if (err < 0) { - blog(LOG_ERROR, "Failed to open '%s': %s", - data->device, snd_strerror(err)); + blog(LOG_ERROR, "Failed to open '%s': %s", data->device, + snd_strerror(err)); return false; } @@ -362,8 +363,7 @@ bool _alsa_open(struct alsa_data *data) goto cleanup; if (snd_pcm_state(data->handle) != SND_PCM_STATE_PREPARED) { - blog(LOG_ERROR, "Device not prepared: '%s'", - data->device); + blog(LOG_ERROR, "Device not prepared: '%s'", data->device); goto cleanup; } @@ -371,8 +371,8 @@ bool _alsa_open(struct alsa_data *data) err = snd_pcm_start(data->handle); if (err < 0) { - blog(LOG_ERROR, "Failed to start '%s': %s", - data->device, snd_strerror(err)); + blog(LOG_ERROR, "Failed to start '%s': %s", data->device, + snd_strerror(err)); goto cleanup; } @@ -385,8 +385,8 @@ bool _alsa_open(struct alsa_data *data) if (err) { pthread_attr_destroy(&attr); blog(LOG_ERROR, - "Failed to create capture thread for device '%s'.", - data->device); + "Failed to create capture thread for device '%s'.", + data->device); goto cleanup; } @@ -412,7 +412,7 @@ void _alsa_close(struct alsa_data *data) } if (data->buffer) - bfree(data->buffer), data->buffer = NULL; + bfree(data->buffer), data->buffer = NULL; } bool _alsa_configure(struct alsa_data *data) @@ -425,37 +425,33 @@ bool _alsa_configure(struct alsa_data *data) err = snd_pcm_hw_params_any(data->handle, hwparams); if (err < 0) { - blog(LOG_ERROR, - "snd_pcm_hw_params_any failed: %s", - snd_strerror(err)); + blog(LOG_ERROR, "snd_pcm_hw_params_any failed: %s", + snd_strerror(err)); return false; } err = snd_pcm_hw_params_set_access(data->handle, hwparams, - SND_PCM_ACCESS_RW_INTERLEAVED); + SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { - blog(LOG_ERROR, - "snd_pcm_hw_params_set_access failed: %s", - snd_strerror(err)); + blog(LOG_ERROR, "snd_pcm_hw_params_set_access failed: %s", + snd_strerror(err)); return false; } data->format = SND_PCM_FORMAT_S16; err = snd_pcm_hw_params_set_format(data->handle, hwparams, - data->format); + data->format); if (err < 0) { - blog(LOG_ERROR, - "snd_pcm_hw_params_set_format failed: %s", - snd_strerror(err)); + blog(LOG_ERROR, "snd_pcm_hw_params_set_format failed: %s", + snd_strerror(err)); return false; } err = snd_pcm_hw_params_set_rate_near(data->handle, hwparams, - &data->rate, 0); + &data->rate, 0); if (err < 0) { - blog(LOG_ERROR, - "snd_pcm_hw_params_set_rate_near failed: %s", - snd_strerror(err)); + blog(LOG_ERROR, "snd_pcm_hw_params_set_rate_near failed: %s", + snd_strerror(err)); return false; } blog(LOG_INFO, "PCM '%s' rate set to %d", data->device, data->rate); @@ -465,34 +461,34 @@ bool _alsa_configure(struct alsa_data *data) data->channels = 2; err = snd_pcm_hw_params_set_channels_near(data->handle, hwparams, - &data->channels); + &data->channels); if (err < 0) { blog(LOG_ERROR, - "snd_pcm_hw_params_set_channels_near failed: %s", - snd_strerror(err)); + "snd_pcm_hw_params_set_channels_near failed: %s", + snd_strerror(err)); return false; } - blog(LOG_INFO, "PCM '%s' channels set to %d", - data->device, data->channels); + blog(LOG_INFO, "PCM '%s' channels set to %d", data->device, + data->channels); err = snd_pcm_hw_params(data->handle, hwparams); if (err < 0) { blog(LOG_ERROR, "snd_pcm_hw_params failed: %s", - snd_strerror(err)); + snd_strerror(err)); return false; } err = snd_pcm_hw_params_get_period_size(hwparams, &data->period_size, - &dir); + &dir); if (err < 0) { - blog(LOG_ERROR, - "snd_pcm_hw_params_get_period_size failed: %s", - snd_strerror(err)); + blog(LOG_ERROR, "snd_pcm_hw_params_get_period_size failed: %s", + snd_strerror(err)); return false; } - data->sample_size = (data->channels - * snd_pcm_format_physical_width(data->format)) / 8; + data->sample_size = + (data->channels * snd_pcm_format_physical_width(data->format)) / + 8; if (data->buffer) bfree(data->buffer); @@ -515,8 +511,8 @@ void _alsa_start_reopen(struct alsa_data *data) err = pthread_create(&data->reopen_thread, &attr, _alsa_reopen, data); if (err) { blog(LOG_ERROR, - "Failed to create reopen thread for device '%s'.", - data->device); + "Failed to create reopen thread for device '%s'.", + data->device); } pthread_attr_destroy(&attr); @@ -535,23 +531,23 @@ void _alsa_stop_reopen(struct alsa_data *data) os_event_reset(data->abort_event); } -void * _alsa_listen(void *attr) +void *_alsa_listen(void *attr) { struct alsa_data *data = attr; struct obs_source_audio out; blog(LOG_DEBUG, "Capture thread started."); - out.data[0] = data->buffer; - out.format = _alsa_to_obs_audio_format(data->format); + out.data[0] = data->buffer; + out.format = _alsa_to_obs_audio_format(data->format); out.speakers = _alsa_channels_to_obs_speakers(data->channels); out.samples_per_sec = data->rate; os_atomic_set_bool(&data->listen, true); do { - snd_pcm_sframes_t frames = snd_pcm_readi(data->handle, - data->buffer, data->period_size); + snd_pcm_sframes_t frames = snd_pcm_readi( + data->handle, data->buffer, data->period_size); if (!os_atomic_load_bool(&data->listen)) break; @@ -565,8 +561,8 @@ void * _alsa_listen(void *attr) } out.frames = frames; - out.timestamp = os_gettime_ns() - - ((frames * NSEC_PER_SEC) / data->rate); + out.timestamp = os_gettime_ns() - + ((frames * NSEC_PER_SEC) / data->rate); if (!data->first_ts) data->first_ts = out.timestamp + STARTUP_TIMEOUT_NS; @@ -581,7 +577,7 @@ void * _alsa_listen(void *attr) return NULL; } -void * _alsa_reopen(void *attr) +void *_alsa_reopen(void *attr) { struct alsa_data *data = attr; unsigned long timeout = REOPEN_TIMEOUT; @@ -609,11 +605,16 @@ void * _alsa_reopen(void *attr) enum audio_format _alsa_to_obs_audio_format(snd_pcm_format_t format) { switch (format) { - case SND_PCM_FORMAT_U8: return AUDIO_FORMAT_U8BIT; - case SND_PCM_FORMAT_S16_LE: return AUDIO_FORMAT_16BIT; - case SND_PCM_FORMAT_S32_LE: return AUDIO_FORMAT_32BIT; - case SND_PCM_FORMAT_FLOAT_LE: return AUDIO_FORMAT_FLOAT; - default: break; + case SND_PCM_FORMAT_U8: + return AUDIO_FORMAT_U8BIT; + case SND_PCM_FORMAT_S16_LE: + return AUDIO_FORMAT_16BIT; + case SND_PCM_FORMAT_S32_LE: + return AUDIO_FORMAT_32BIT; + case SND_PCM_FORMAT_FLOAT_LE: + return AUDIO_FORMAT_FLOAT; + default: + break; } return AUDIO_FORMAT_UNKNOWN; @@ -621,16 +622,22 @@ enum audio_format _alsa_to_obs_audio_format(snd_pcm_format_t format) enum speaker_layout _alsa_channels_to_obs_speakers(unsigned int channels) { - switch(channels) { - case 1: return SPEAKERS_MONO; - case 2: return SPEAKERS_STEREO; - case 3: return SPEAKERS_2POINT1; - case 4: return SPEAKERS_4POINT0; - case 5: return SPEAKERS_4POINT1; - case 6: return SPEAKERS_5POINT1; - case 8: return SPEAKERS_7POINT1; + switch (channels) { + case 1: + return SPEAKERS_MONO; + case 2: + return SPEAKERS_STEREO; + case 3: + return SPEAKERS_2POINT1; + case 4: + return SPEAKERS_4POINT0; + case 5: + return SPEAKERS_4POINT1; + case 6: + return SPEAKERS_5POINT1; + case 8: + return SPEAKERS_7POINT1; } return SPEAKERS_UNKNOWN; } - diff --git a/plugins/linux-alsa/data/locale/bg-BG.ini b/plugins/linux-alsa/data/locale/bg-BG.ini new file mode 100644 index 0000000..faeeb55 --- /dev/null +++ b/plugins/linux-alsa/data/locale/bg-BG.ini @@ -0,0 +1,3 @@ +AlsaInput="Устройство за улавяне на звука (ALSA)" +Device="Устройство" + diff --git a/plugins/linux-alsa/data/locale/gl-ES.ini b/plugins/linux-alsa/data/locale/gl-ES.ini index e1957b0..0520647 100644 --- a/plugins/linux-alsa/data/locale/gl-ES.ini +++ b/plugins/linux-alsa/data/locale/gl-ES.ini @@ -1,3 +1,3 @@ -AlsaInput="Dispositivo de captura de audio (ALSA)" +AlsaInput="Dispositivo de captura de son (ALSA)" Device="Dispositivo" diff --git a/plugins/linux-alsa/data/locale/sl-SI.ini b/plugins/linux-alsa/data/locale/sl-SI.ini new file mode 100644 index 0000000..d6af6a2 --- /dev/null +++ b/plugins/linux-alsa/data/locale/sl-SI.ini @@ -0,0 +1,2 @@ +AlsaInput="Naprava za zajemanje zvoka (ALSA)" + diff --git a/plugins/linux-alsa/linux-alsa.c b/plugins/linux-alsa/linux-alsa.c index 73635b1..7405105 100644 --- a/plugins/linux-alsa/linux-alsa.c +++ b/plugins/linux-alsa/linux-alsa.c @@ -30,4 +30,3 @@ bool obs_module_load(void) obs_register_source(&alsa_input_capture); return true; } - diff --git a/plugins/linux-capture/data/locale/de-DE.ini b/plugins/linux-capture/data/locale/de-DE.ini index e72024c..f3870d6 100644 --- a/plugins/linux-capture/data/locale/de-DE.ini +++ b/plugins/linux-capture/data/locale/de-DE.ini @@ -2,7 +2,7 @@ X11SharedMemoryScreenInput="Bildschirmaufnahme (XSHM)" Screen="Bildschirm" CaptureCursor="Mauszeiger aufnehmen" AdvancedSettings="Erweiterte Einstellungen" -XServer="X-Server" +XServer="X‐Server" XCCapture="Fensteraufnahme (Xcomposite)" Window="Fenster" CropTop="Oben abschneiden (Pixel)" @@ -10,7 +10,7 @@ CropLeft="Links abschneiden (Pixel)" CropRight="Rechts abschneiden (Pixel)" CropBottom="Unten abschneiden (Pixel)" SwapRedBlue="Rot und Blau tauschen" -LockX="X-Server während der Aufnahme sperren" -IncludeXBorder="X-Rahmen anzeigen" -ExcludeAlpha="Alphaloses Texturformat verwenden (Mesa-Problemumgehung)" +LockX="X‐Server während der Aufnahme sperren" +IncludeXBorder="X‐Rahmen anzeigen" +ExcludeAlpha="Alphaloses Texturformat verwenden (Mesa‐Problemumgehung)" diff --git a/plugins/linux-capture/data/locale/gl-ES.ini b/plugins/linux-capture/data/locale/gl-ES.ini index 707a065..a74d345 100644 --- a/plugins/linux-capture/data/locale/gl-ES.ini +++ b/plugins/linux-capture/data/locale/gl-ES.ini @@ -1,15 +1,16 @@ X11SharedMemoryScreenInput="Captura de pantalla (XSHM)" Screen="Pantalla" -CaptureCursor="Captura de cursor" +CaptureCursor="Capturar o cursor" AdvancedSettings="Axustes avanzados" -XServer="X Server" +XServer="Servidor das X" XCCapture="Captura de xanela (Xcomposite)" Window="Xanela" -CropTop="Recortar por arriba (píxeles)" -CropLeft="Recortar pola esquerda (píxeles)" -CropRight="Recortar pola dereita (píxeles)" -CropBottom="Recortar por abaixo (píxeles)" -SwapRedBlue="Trocar vermello e azul" -LockX="Bloquear o servidor X durante a captura" +CropTop="Recortar por riba (píxeis)" +CropLeft="Recortar pola esquerda (píxeis)" +CropRight="Recortar pola dereita (píxeis)" +CropBottom="Recortar por baixo (píxeis)" +SwapRedBlue="Intercambiar vermello e azul" +LockX="Bloquear o servidor das X durante a captura" IncludeXBorder="Incluír o bordo da xanela X" +ExcludeAlpha="Empregar o formato de textura sen alfa (solución Mesa)" diff --git a/plugins/linux-capture/data/locale/ro-RO.ini b/plugins/linux-capture/data/locale/ro-RO.ini index 57a4520..68b1a8c 100644 --- a/plugins/linux-capture/data/locale/ro-RO.ini +++ b/plugins/linux-capture/data/locale/ro-RO.ini @@ -10,7 +10,7 @@ CropLeft="Trunchiază stânga (pixeli)" CropRight="Trunchiază dreapta (pixeli)" CropBottom="Trunchiază partea inferioară (pixeli)" SwapRedBlue="Schimbă roșu cu albastru" -LockX="Blochează serverul X atunci când se capturează" +LockX="Blochează X server când se capturează" IncludeXBorder="Include marginea cu X" ExcludeAlpha="Folosește formatul de texturi fără alpha (soluție de evitare pentru Mesa)" diff --git a/plugins/linux-capture/data/locale/sl-SI.ini b/plugins/linux-capture/data/locale/sl-SI.ini index 94f0b7e..d29d500 100644 --- a/plugins/linux-capture/data/locale/sl-SI.ini +++ b/plugins/linux-capture/data/locale/sl-SI.ini @@ -1,6 +1,6 @@ X11SharedMemoryScreenInput="Zajemanje zaslona (XSHM)" Screen="Zaslon" -CaptureCursor="Zajemaj kazalec" +CaptureCursor="Zajemi kazalec" AdvancedSettings="Napredne nastavitve" XServer="X Server" XCCapture="Zajemanje okna (Xcomposite)" diff --git a/plugins/linux-capture/xcompcap-helper.cpp b/plugins/linux-capture/xcompcap-helper.cpp index 55657f8..676a1ca 100644 --- a/plugins/linux-capture/xcompcap-helper.cpp +++ b/plugins/linux-capture/xcompcap-helper.cpp @@ -11,291 +11,259 @@ #include "xcompcap-helper.hpp" -namespace XCompcap +namespace XCompcap { +static Display *xdisplay = 0; + +Display *disp() { - static Display* xdisplay = 0; + if (!xdisplay) + xdisplay = XOpenDisplay(NULL); - Display *disp() - { - if (!xdisplay) - xdisplay = XOpenDisplay(NULL); + return xdisplay; +} - return xdisplay; - } +void cleanupDisplay() +{ + if (!xdisplay) + return; - void cleanupDisplay() - { - if (!xdisplay) - return; + XCloseDisplay(xdisplay); + xdisplay = 0; +} - XCloseDisplay(xdisplay); - xdisplay = 0; - } +static void getAllWindows(Window parent, std::list &windows) +{ + UNUSED_PARAMETER(parent); + UNUSED_PARAMETER(windows); +} - static void getAllWindows(Window parent, std::list& windows) - { - UNUSED_PARAMETER(parent); - UNUSED_PARAMETER(windows); - } +std::list getAllWindows() +{ + std::list res; - std::list getAllWindows() - { - std::list res; + for (int i = 0; i < ScreenCount(disp()); ++i) + getAllWindows(RootWindow(disp(), i), res); - for (int i = 0; i < ScreenCount(disp()); ++i) - getAllWindows(RootWindow(disp(), i), res); + return res; +} - return res; - } +// Specification for checking for ewmh support at +// http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472693600 - // Specification for checking for ewmh support at - // http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472693600 +bool ewmhIsSupported() +{ + Display *display = disp(); + Atom netSupportingWmCheck = + XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", true); + Atom actualType; + int format = 0; + unsigned long num = 0, bytes = 0; + unsigned char *data = NULL; + Window ewmh_window = 0; - bool ewmhIsSupported() - { - Display *display = disp(); - Atom netSupportingWmCheck = XInternAtom(display, - "_NET_SUPPORTING_WM_CHECK", true); - Atom actualType; - int format = 0; - unsigned long num = 0, bytes = 0; - unsigned char *data = NULL; - Window ewmh_window = 0; + int status = XGetWindowProperty(display, DefaultRootWindow(display), + netSupportingWmCheck, 0L, 1L, false, + XA_WINDOW, &actualType, &format, &num, + &bytes, &data); - int status = XGetWindowProperty( - display, - DefaultRootWindow(display), - netSupportingWmCheck, - 0L, - 1L, - false, - XA_WINDOW, - &actualType, - &format, - &num, - &bytes, - &data); - - if (status == Success) { - if (num > 0) { - ewmh_window = ((Window*)data)[0]; - } - if (data) { - XFree(data); - data = NULL; - } + if (status == Success) { + if (num > 0) { + ewmh_window = ((Window *)data)[0]; } - - if (ewmh_window) { - status = XGetWindowProperty( - display, - ewmh_window, - netSupportingWmCheck, - 0L, - 1L, - false, - XA_WINDOW, - &actualType, - &format, - &num, - &bytes, - &data); - if (status != Success || num == 0 || - ewmh_window != ((Window*)data)[0]) { - ewmh_window = 0; - } - if (status == Success && data) { - XFree(data); - } + if (data) { + XFree(data); + data = NULL; } - - return ewmh_window != 0; } - std::list getTopLevelWindows() - { - std::list res; - - if (!ewmhIsSupported()) { - blog(LOG_WARNING, "Unable to query window list " - "because window manager " - "does not support extended " - "window manager Hints"); - return res; + if (ewmh_window) { + status = XGetWindowProperty(display, ewmh_window, + netSupportingWmCheck, 0L, 1L, false, + XA_WINDOW, &actualType, &format, + &num, &bytes, &data); + if (status != Success || num == 0 || + ewmh_window != ((Window *)data)[0]) { + ewmh_window = 0; } - - Atom netClList = XInternAtom(disp(), "_NET_CLIENT_LIST", true); - Atom actualType; - int format; - unsigned long num, bytes; - Window* data = 0; - - for (int i = 0; i < ScreenCount(disp()); ++i) { - Window rootWin = RootWindow(disp(), i); - - int status = XGetWindowProperty( - disp(), - rootWin, - netClList, - 0L, - ~0L, - false, - AnyPropertyType, - &actualType, - &format, - &num, - &bytes, - (uint8_t**)&data); - - if (status != Success) { - blog(LOG_WARNING, "Failed getting root " - "window properties"); - continue; - } - - for (unsigned long i = 0; i < num; ++i) - res.push_back(data[i]); - + if (status == Success && data) { XFree(data); } + } + return ewmh_window != 0; +} + +std::list getTopLevelWindows() +{ + std::list res; + + if (!ewmhIsSupported()) { + blog(LOG_WARNING, "Unable to query window list " + "because window manager " + "does not support extended " + "window manager Hints"); return res; } - int getRootWindowScreen(Window root) - { - XWindowAttributes attr; + Atom netClList = XInternAtom(disp(), "_NET_CLIENT_LIST", true); + Atom actualType; + int format; + unsigned long num, bytes; + Window *data = 0; - if (!XGetWindowAttributes(disp(), root, &attr)) - return DefaultScreen(disp()); + for (int i = 0; i < ScreenCount(disp()); ++i) { + Window rootWin = RootWindow(disp(), i); - return XScreenNumberOfScreen(attr.screen); - } + int status = XGetWindowProperty(disp(), rootWin, netClList, 0L, + ~0L, false, AnyPropertyType, + &actualType, &format, &num, + &bytes, (uint8_t **)&data); - std::string getWindowAtom(Window win, const char *atom) - { - Atom netWmName = XInternAtom(disp(), atom, false); - int n; - char **list = 0; - XTextProperty tp; - std::string res = "unknown"; - - XGetTextProperty(disp(), win, &tp, netWmName); - - if (!tp.nitems) - XGetWMName(disp(), win, &tp); - - if (!tp.nitems) - return "error"; - - if (tp.encoding == XA_STRING) { - res = (char*)tp.value; - } else { - int ret = XmbTextPropertyToTextList(disp(), &tp, &list, - &n); - - if (ret >= Success && n > 0 && *list) { - res = *list; - XFreeStringList(list); - } + if (status != Success) { + blog(LOG_WARNING, "Failed getting root " + "window properties"); + continue; } - char *conv = nullptr; - if (os_mbs_to_utf8_ptr(res.c_str(), 0, &conv)) - res = conv; - bfree(conv); + for (unsigned long i = 0; i < num; ++i) + res.push_back(data[i]); - XFree(tp.value); - - return res; + XFree(data); } - std::string getWindowCommand(Window win) - { - Atom xi = XInternAtom(disp(), "WM_COMMAND", false); - int n; - char **list = 0; - XTextProperty tp; - std::string res = "error"; + return res; +} - XGetTextProperty(disp(), win, &tp, xi); +int getRootWindowScreen(Window root) +{ + XWindowAttributes attr; - if (!tp.nitems) - return std::string(); + if (!XGetWindowAttributes(disp(), root, &attr)) + return DefaultScreen(disp()); - if (tp.encoding == XA_STRING) { - res = (char*)tp.value; - } else { - int ret = XmbTextPropertyToTextList(disp(), &tp, &list, - &n); - if (ret >= Success && n > 0 && *list) { - res = *list; - XFreeStringList(list); - } + return XScreenNumberOfScreen(attr.screen); +} + +std::string getWindowAtom(Window win, const char *atom) +{ + Atom netWmName = XInternAtom(disp(), atom, false); + int n; + char **list = 0; + XTextProperty tp; + std::string res = "unknown"; + + XGetTextProperty(disp(), win, &tp, netWmName); + + if (!tp.nitems) + XGetWMName(disp(), win, &tp); + + if (!tp.nitems) + return "error"; + + if (tp.encoding == XA_STRING) { + res = (char *)tp.value; + } else { + int ret = XmbTextPropertyToTextList(disp(), &tp, &list, &n); + + if (ret >= Success && n > 0 && *list) { + res = *list; + XFreeStringList(list); } - - XFree(tp.value); - - return res; } - int getWindowPid(Window win) - { - UNUSED_PARAMETER(win); - return 1234; //TODO - } + char *conv = nullptr; + if (os_mbs_to_utf8_ptr(res.c_str(), 0, &conv)) + res = conv; + bfree(conv); - static std::unordered_set changedWindows; - static pthread_mutex_t changeLock = PTHREAD_MUTEX_INITIALIZER; - void processEvents() - { - PLock lock(&changeLock); + XFree(tp.value); - XLockDisplay(disp()); + return res; +} - while (XEventsQueued(disp(), QueuedAfterReading) > 0) { - XEvent ev; +std::string getWindowCommand(Window win) +{ + Atom xi = XInternAtom(disp(), "WM_COMMAND", false); + int n; + char **list = 0; + XTextProperty tp; + std::string res = "error"; - XNextEvent(disp(), &ev); + XGetTextProperty(disp(), win, &tp, xi); - if (ev.type == ConfigureNotify) - changedWindows.insert(ev.xconfigure.event); + if (!tp.nitems) + return std::string(); - if (ev.type == MapNotify) - changedWindows.insert(ev.xmap.event); - - if (ev.type == Expose) - changedWindows.insert(ev.xexpose.window); - - if (ev.type == VisibilityNotify) - changedWindows.insert(ev.xvisibility.window); - - if (ev.type == DestroyNotify) - changedWindows.insert(ev.xdestroywindow.event); + if (tp.encoding == XA_STRING) { + res = (char *)tp.value; + } else { + int ret = XmbTextPropertyToTextList(disp(), &tp, &list, &n); + if (ret >= Success && n > 0 && *list) { + res = *list; + XFreeStringList(list); } - - XUnlockDisplay(disp()); } - bool windowWasReconfigured(Window win) - { - PLock lock(&changeLock); + XFree(tp.value); - auto it = changedWindows.find(win); + return res; +} - if (it != changedWindows.end()) { - changedWindows.erase(it); - return true; - } +int getWindowPid(Window win) +{ + UNUSED_PARAMETER(win); + return 1234; //TODO +} - return false; +static std::unordered_set changedWindows; +static pthread_mutex_t changeLock = PTHREAD_MUTEX_INITIALIZER; +void processEvents() +{ + PLock lock(&changeLock); + + XLockDisplay(disp()); + + while (XEventsQueued(disp(), QueuedAfterReading) > 0) { + XEvent ev; + + XNextEvent(disp(), &ev); + + if (ev.type == ConfigureNotify) + changedWindows.insert(ev.xconfigure.event); + + if (ev.type == MapNotify) + changedWindows.insert(ev.xmap.event); + + if (ev.type == Expose) + changedWindows.insert(ev.xexpose.window); + + if (ev.type == VisibilityNotify) + changedWindows.insert(ev.xvisibility.window); + + if (ev.type == DestroyNotify) + changedWindows.insert(ev.xdestroywindow.event); } + XUnlockDisplay(disp()); +} + +bool windowWasReconfigured(Window win) +{ + PLock lock(&changeLock); + + auto it = changedWindows.find(win); + + if (it != changedWindows.end()) { + changedWindows.erase(it); + return true; + } + + return false; +} + } - -PLock::PLock(pthread_mutex_t* mtx, bool trylock) - :m(mtx) +PLock::PLock(pthread_mutex_t *mtx, bool trylock) : m(mtx) { if (trylock) islock = mtx && pthread_mutex_trylock(mtx) == 0; @@ -331,11 +299,9 @@ void PLock::lock() } } - - -static bool* curErrorTarget = 0; +static bool *curErrorTarget = 0; static char curErrorText[200]; -static int xerrorlock_handler(Display* disp, XErrorEvent* err) +static int xerrorlock_handler(Display *disp, XErrorEvent *err) { if (curErrorTarget) @@ -451,7 +417,6 @@ void XDisplayLock::unlock() } } - ObsGsContextHolder::ObsGsContextHolder() { obs_enter_graphics(); diff --git a/plugins/linux-capture/xcompcap-helper.hpp b/plugins/linux-capture/xcompcap-helper.hpp index 838d84f..dd81895 100644 --- a/plugins/linux-capture/xcompcap-helper.hpp +++ b/plugins/linux-capture/xcompcap-helper.hpp @@ -5,17 +5,15 @@ #define blog(level, msg, ...) blog(level, "xcompcap: " msg, ##__VA_ARGS__) - -class PLock -{ +class PLock { pthread_mutex_t *m; bool islock; - public: - PLock(const PLock&) = delete; - PLock& operator=(const PLock&) = delete; +public: + PLock(const PLock &) = delete; + PLock &operator=(const PLock &) = delete; - PLock(pthread_mutex_t* mtx, bool trylock = false); + PLock(pthread_mutex_t *mtx, bool trylock = false); ~PLock(); @@ -25,15 +23,14 @@ class PLock void lock(); }; -class XErrorLock -{ +class XErrorLock { bool islock; bool goterr; XErrorHandler prevhandler; - public: - XErrorLock(const XErrorLock&) = delete; - XErrorLock& operator=(const XErrorLock&) = delete; +public: + XErrorLock(const XErrorLock &) = delete; + XErrorLock &operator=(const XErrorLock &) = delete; XErrorLock(); ~XErrorLock(); @@ -48,13 +45,12 @@ class XErrorLock void resetError(); }; -class XDisplayLock -{ +class XDisplayLock { bool islock; - public: - XDisplayLock(const XDisplayLock&) = delete; - XDisplayLock& operator=(const XDisplayLock&) = delete; +public: + XDisplayLock(const XDisplayLock &) = delete; + XDisplayLock &operator=(const XDisplayLock &) = delete; XDisplayLock(); ~XDisplayLock(); @@ -65,39 +61,37 @@ class XDisplayLock void lock(); }; -class ObsGsContextHolder -{ - public: - ObsGsContextHolder(const ObsGsContextHolder&) = delete; - ObsGsContextHolder& operator=(const ObsGsContextHolder&) = delete; +class ObsGsContextHolder { +public: + ObsGsContextHolder(const ObsGsContextHolder &) = delete; + ObsGsContextHolder &operator=(const ObsGsContextHolder &) = delete; ObsGsContextHolder(); ~ObsGsContextHolder(); }; -namespace XCompcap +namespace XCompcap { +Display *disp(); +void cleanupDisplay(); + +std::string getWindowCommand(Window win); +int getRootWindowScreen(Window root); +std::string getWindowAtom(Window win, const char *atom); +int getWindowPid(Window win); +bool ewmhIsSupported(); +std::list getTopLevelWindows(); +std::list getAllWindows(); + +inline std::string getWindowName(Window win) { - Display* disp(); - void cleanupDisplay(); - - std::string getWindowCommand(Window win); - int getRootWindowScreen(Window root); - std::string getWindowAtom(Window win, const char *atom); - int getWindowPid(Window win); - bool ewmhIsSupported(); - std::list getTopLevelWindows(); - std::list getAllWindows(); - - inline std::string getWindowName(Window win) - { - return getWindowAtom(win, "_NET_WM_NAME"); - } - - inline std::string getWindowClass(Window win) - { - return getWindowAtom(win, "WM_CLASS"); - } - - void processEvents(); - bool windowWasReconfigured(Window win); + return getWindowAtom(win, "_NET_WM_NAME"); +} + +inline std::string getWindowClass(Window win) +{ + return getWindowAtom(win, "WM_CLASS"); +} + +void processEvents(); +bool windowWasReconfigured(Window win); } diff --git a/plugins/linux-capture/xcompcap-main.cpp b/plugins/linux-capture/xcompcap-main.cpp index bbfe2eb..a705c56 100644 --- a/plugins/linux-capture/xcompcap-main.cpp +++ b/plugins/linux-capture/xcompcap-main.cpp @@ -35,7 +35,7 @@ bool XCompcapMain::init() if (major == 0 && minor < 2) { blog(LOG_ERROR, "Xcomposite extension is too old: %d.%d < 0.2", - major, minor); + major, minor); return false; } @@ -51,43 +51,41 @@ obs_properties_t *XCompcapMain::properties() { obs_properties_t *props = obs_properties_create(); - obs_property_t *wins = obs_properties_add_list(props, "capture_window", - obs_module_text("Window"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + obs_property_t *wins = obs_properties_add_list( + props, "capture_window", obs_module_text("Window"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); - for (Window win: XCompcap::getTopLevelWindows()) { + for (Window win : XCompcap::getTopLevelWindows()) { std::string wname = XCompcap::getWindowName(win); std::string cls = XCompcap::getWindowClass(win); std::string winid = std::to_string((long long)win); std::string desc = - (winid + WIN_STRING_DIV + wname + - WIN_STRING_DIV + cls); + (winid + WIN_STRING_DIV + wname + WIN_STRING_DIV + cls); - obs_property_list_add_string(wins, wname.c_str(), - desc.c_str()); + obs_property_list_add_string(wins, wname.c_str(), desc.c_str()); } - obs_properties_add_int(props, "cut_top", obs_module_text("CropTop"), - 0, 4096, 1); + obs_properties_add_int(props, "cut_top", obs_module_text("CropTop"), 0, + 4096, 1); obs_properties_add_int(props, "cut_left", obs_module_text("CropLeft"), - 0, 4096, 1); + 0, 4096, 1); obs_properties_add_int(props, "cut_right", obs_module_text("CropRight"), - 0, 4096, 1); + 0, 4096, 1); obs_properties_add_int(props, "cut_bot", obs_module_text("CropBottom"), - 0, 4096, 1); + 0, 4096, 1); obs_properties_add_bool(props, "swap_redblue", - obs_module_text("SwapRedBlue")); + obs_module_text("SwapRedBlue")); obs_properties_add_bool(props, "lock_x", obs_module_text("LockX")); obs_properties_add_bool(props, "show_cursor", - obs_module_text("CaptureCursor")); + obs_module_text("CaptureCursor")); obs_properties_add_bool(props, "include_border", - obs_module_text("IncludeXBorder")); + obs_module_text("IncludeXBorder")); obs_properties_add_bool(props, "exclude_alpha", - obs_module_text("ExcludeAlpha")); + obs_module_text("ExcludeAlpha")); return props; } @@ -108,20 +106,24 @@ void XCompcapMain::defaults(obs_data_t *settings) #define FIND_WINDOW_INTERVAL 2.0 -struct XCompcapMain_private -{ +struct XCompcapMain_private { XCompcapMain_private() - :win(0) - ,cut_top(0), cur_cut_top(0) - ,cut_left(0), cur_cut_left(0) - ,cut_right(0), cur_cut_right(0) - ,cut_bot(0), cur_cut_bot(0) - ,inverted(false) - ,width(0),height(0) - ,pixmap(0) - ,glxpixmap(0) - ,tex(0) - ,gltex(0) + : win(0), + cut_top(0), + cur_cut_top(0), + cut_left(0), + cur_cut_left(0), + cut_right(0), + cur_cut_right(0), + cut_bot(0), + cur_cut_bot(0), + inverted(false), + width(0), + height(0), + pixmap(0), + glxpixmap(0), + tex(0), + gltex(0) { pthread_mutexattr_init(&lockattr); pthread_mutexattr_settype(&lockattr, PTHREAD_MUTEX_RECURSIVE); @@ -169,7 +171,6 @@ struct XCompcapMain_private xcursor_t *cursor = nullptr; }; - XCompcapMain::XCompcapMain(obs_data_t *settings, obs_source_t *source) { p = new XCompcapMain_private; @@ -231,7 +232,7 @@ static Window getWindowFromString(std::string wstr) std::string wcls = wstr.substr(lastMark + markSize); Window matchedNameWin = wid; - for (Window cwin: XCompcap::getTopLevelWindows()) { + for (Window cwin : XCompcap::getTopLevelWindows()) { std::string cwinname = XCompcap::getWindowName(cwin); std::string ccls = XCompcap::getWindowClass(cwin); @@ -249,38 +250,103 @@ static Window getWindowFromString(std::string wstr) static void xcc_cleanup(XCompcapMain_private *p) { PLock lock(&p->lock); - XDisplayLock xlock; + XErrorLock xlock; if (p->gltex) { - GLuint gltex = *(GLuint*)gs_texture_get_obj(p->gltex); + GLuint gltex = *(GLuint *)gs_texture_get_obj(p->gltex); glBindTexture(GL_TEXTURE_2D, gltex); - glXReleaseTexImageEXT(xdisp, p->glxpixmap, GLX_FRONT_LEFT_EXT); + if (p->glxpixmap) { + glXReleaseTexImageEXT(xdisp, p->glxpixmap, + GLX_FRONT_LEFT_EXT); + if (xlock.gotError()) { + blog(LOG_ERROR, + "cleanup glXReleaseTexImageEXT failed: %s", + xlock.getErrorText().c_str()); + xlock.resetError(); + } + glXDestroyPixmap(xdisp, p->glxpixmap); + if (xlock.gotError()) { + blog(LOG_ERROR, + "cleanup glXDestroyPixmap failed: %s", + xlock.getErrorText().c_str()); + xlock.resetError(); + } + p->glxpixmap = 0; + } gs_texture_destroy(p->gltex); p->gltex = 0; } - if (p->glxpixmap) { - glXDestroyPixmap(xdisp, p->glxpixmap); - p->glxpixmap = 0; - } - if (p->pixmap) { XFreePixmap(xdisp, p->pixmap); + if (xlock.gotError()) { + blog(LOG_ERROR, "cleanup glXDestroyPixmap failed: %s", + xlock.getErrorText().c_str()); + xlock.resetError(); + } p->pixmap = 0; } if (p->win) { XCompositeUnredirectWindow(xdisp, p->win, - CompositeRedirectAutomatic); + CompositeRedirectAutomatic); XSelectInput(xdisp, p->win, 0); p->win = 0; } + + if (p->tex) { + gs_texture_destroy(p->tex); + p->tex = 0; + } } +static gs_color_format gs_format_from_tex() +{ + GLint iformat = 0; + // consider GL_ARB_internalformat_query + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, + &iformat); + + // These formats are known to be wrong on Intel platforms. We intentionally + // use swapped internal formats here to preserve historic behavior which + // swapped colors accidentally and because D3D11 would not support a + // GS_RGBX format + switch (iformat) { + case GL_RGB: + return GS_BGRX; + case GL_RGBA: + return GS_RGBA; + default: + return GS_RGBA; + } +} + +// from libobs-opengl/gl-subsystem.h because we need to handle GLX modifying textures outside libobs. +struct fb_info; + +struct gs_texture { + gs_device_t *device; + enum gs_texture_type type; + enum gs_color_format format; + GLenum gl_format; + GLenum gl_target; + GLenum gl_internal_format; + GLenum gl_type; + GLuint texture; + uint32_t levels; + bool is_dynamic; + bool is_render_target; + bool is_dummy; + bool gen_mipmaps; + + gs_samplerstate_t *cur_sampler; + struct fbo_info *fbo; +}; +// End shitty hack. + void XCompcapMain::updateSettings(obs_data_t *settings) { PLock lock(&p->lock); - XErrorLock xlock; ObsGsContextHolder obsctx; blog(LOG_DEBUG, "Settings updating"); @@ -290,8 +356,8 @@ void XCompcapMain::updateSettings(obs_data_t *settings) xcc_cleanup(p); if (settings) { - const char *windowName = obs_data_get_string(settings, - "capture_window"); + const char *windowName = + obs_data_get_string(settings, "capture_window"); p->windowName = windowName; p->win = getWindowFromString(windowName); @@ -303,30 +369,28 @@ void XCompcapMain::updateSettings(obs_data_t *settings) p->lockX = obs_data_get_bool(settings, "lock_x"); p->swapRedBlue = obs_data_get_bool(settings, "swap_redblue"); p->show_cursor = obs_data_get_bool(settings, "show_cursor"); - p->include_border = obs_data_get_bool(settings, "include_border"); + p->include_border = + obs_data_get_bool(settings, "include_border"); p->exclude_alpha = obs_data_get_bool(settings, "exclude_alpha"); p->draw_opaque = false; } else { p->win = prevWin; } - xlock.resetError(); - + XErrorLock xlock; if (p->win) XCompositeRedirectWindow(xdisp, p->win, - CompositeRedirectAutomatic); - + CompositeRedirectAutomatic); if (xlock.gotError()) { blog(LOG_ERROR, "XCompositeRedirectWindow failed: %s", - xlock.getErrorText().c_str()); + xlock.getErrorText().c_str()); return; } if (p->win) XSelectInput(xdisp, p->win, - StructureNotifyMask - | ExposureMask - | VisibilityChangeMask); + StructureNotifyMask | ExposureMask | + VisibilityChangeMask); XSync(xdisp, 0); XWindowAttributes attr; @@ -342,75 +406,26 @@ void XCompcapMain::updateSettings(obs_data_t *settings) int x, y; XTranslateCoordinates(xdisp, p->win, attr.root, 0, 0, &x, &y, - &child); + &child); xcursor_offset(p->cursor, x, y); } - gs_color_format cf = GS_RGBA; - - if (p->exclude_alpha) { - cf = GS_BGRX; - } - - bool has_alpha = true; - - const int attrs[] = - { - GLX_BIND_TO_TEXTURE_RGBA_EXT, GL_TRUE, - GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, - GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, - GLX_ALPHA_SIZE, 8, - GLX_DOUBLEBUFFER, GL_FALSE, - None - }; - + const int config_attrs[] = {GLX_BIND_TO_TEXTURE_RGBA_EXT, + GL_TRUE, + GLX_DRAWABLE_TYPE, + GLX_PIXMAP_BIT, + GLX_BIND_TO_TEXTURE_TARGETS_EXT, + GLX_TEXTURE_2D_BIT_EXT, + GLX_DOUBLEBUFFER, + GL_FALSE, + None}; int nelem = 0; - GLXFBConfig *configs = glXGetFBConfigs(xdisp, - XCompcap::getRootWindowScreen(attr.root), - &nelem); + GLXFBConfig *configs = glXChooseFBConfig( + xdisp, XCompcap::getRootWindowScreen(attr.root), config_attrs, + &nelem); - if (nelem <= 0) { - blog(LOG_ERROR, "no fb configs available"); - p->win = 0; - p->height = 0; - p->width = 0; - return; - } - - GLXFBConfig config; - for (int i = 0; i < nelem; i++) { - config = configs[i]; - XVisualInfo *visual = glXGetVisualFromFBConfig(xdisp, config); - if (!visual) - continue; - - if (attr.visual->visualid != visual->visualid) { - XFree(visual); - continue; - } - XFree(visual); - - int value; - glXGetFBConfigAttrib(xdisp, config, GLX_ALPHA_SIZE, &value); - if (value != 8) - has_alpha = false; - - break; - } - - XFree(configs); - configs = glXChooseFBConfig(xdisp, - XCompcap::getRootWindowScreen(attr.root), - attrs, &nelem); - - if (nelem <= 0) { - blog(LOG_ERROR, "no matching fb config found"); - p->win = 0; - p->height = 0; - p->width = 0; - return; - } bool found = false; + GLXFBConfig config; for (int i = 0; i < nelem; i++) { config = configs[i]; XVisualInfo *visual = glXGetVisualFromFBConfig(xdisp, config); @@ -425,10 +440,16 @@ void XCompcapMain::updateSettings(obs_data_t *settings) found = true; break; } - if (!found) - config = configs[0]; + if (!found) { + blog(LOG_ERROR, "no matching fb config found"); + p->win = 0; + p->height = 0; + p->width = 0; + XFree(configs); + return; + } - if (cf == GS_BGRX || !has_alpha) { + if (p->exclude_alpha || attr.depth != 32) { p->draw_opaque = true; } @@ -462,93 +483,83 @@ void XCompcapMain::updateSettings(obs_data_t *settings) p->cur_cut_right = 0; } - if (p->tex) - gs_texture_destroy(p->tex); - - uint8_t *texData = new uint8_t[width() * height() * 4]; - - memset(texData, 0, width() * height() * 4); - - const uint8_t* texDataArr[] = { texData, 0 }; - - p->tex = gs_texture_create(width(), height(), cf, 1, - texDataArr, 0); - - delete[] texData; - - if (p->swapRedBlue) { - GLuint tex = *(GLuint*)gs_texture_get_obj(p->tex); - glBindTexture(GL_TEXTURE_2D, tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); - glBindTexture(GL_TEXTURE_2D, 0); - } - + // Precautionary since we dont error check every GLX call above. xlock.resetError(); p->pixmap = XCompositeNameWindowPixmap(xdisp, p->win); - if (xlock.gotError()) { blog(LOG_ERROR, "XCompositeNameWindowPixmap failed: %s", - xlock.getErrorText().c_str()); + xlock.getErrorText().c_str()); p->pixmap = 0; XFree(configs); return; } - const int attribs_alpha[] = - { - GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, - GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT, - None - }; - - const int attribs_no_alpha[] = - { - GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, - GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, - None - }; - - const int *attribs = cf == GS_RGBA ? attribs_alpha : attribs_no_alpha; - - p->glxpixmap = glXCreatePixmap(xdisp, config, p->pixmap, attribs); + // Should be consistent format with config we are using. Since we searched on RGBA lets use RGBA here. + const int pixmap_attrs[] = {GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, + GLX_TEXTURE_FORMAT_EXT, + GLX_TEXTURE_FORMAT_RGBA_EXT, None}; + p->glxpixmap = glXCreatePixmap(xdisp, config, p->pixmap, pixmap_attrs); if (xlock.gotError()) { blog(LOG_ERROR, "glXCreatePixmap failed: %s", - xlock.getErrorText().c_str()); + xlock.getErrorText().c_str()); XFreePixmap(xdisp, p->pixmap); XFree(configs); p->pixmap = 0; p->glxpixmap = 0; return; } - XFree(configs); - p->gltex = gs_texture_create(p->width, p->height, cf, 1, 0, - GS_GL_DUMMYTEX); - - GLuint gltex = *(GLuint*)gs_texture_get_obj(p->gltex); + // Build an OBS texture to bind the pixmap to. + p->gltex = gs_texture_create(p->width, p->height, GS_RGBA, 1, 0, + GS_GL_DUMMYTEX); + GLuint gltex = *(GLuint *)gs_texture_get_obj(p->gltex); glBindTexture(GL_TEXTURE_2D, gltex); glXBindTexImageEXT(xdisp, p->glxpixmap, GLX_FRONT_LEFT_EXT, NULL); + if (xlock.gotError()) { + blog(LOG_ERROR, "glXBindTexImageEXT failed: %s", + xlock.getErrorText().c_str()); + XFreePixmap(xdisp, p->pixmap); + XFree(configs); + p->pixmap = 0; + p->glxpixmap = 0; + return; + } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + // glxBindTexImageEXT might modify the textures format. + gs_color_format format = gs_format_from_tex(); + glBindTexture(GL_TEXTURE_2D, 0); + // sync OBS texture format based on any glxBindTexImageEXT changes + p->gltex->format = format; + + // Create a pure OBS texture to use for rendering. Using the same + // format so we can copy instead of drawing from the source gltex. + if (p->tex) + gs_texture_destroy(p->tex); + p->tex = gs_texture_create(width(), height(), format, 1, 0, + GS_GL_DUMMYTEX); + if (p->swapRedBlue) { + GLuint tex = *(GLuint *)gs_texture_get_obj(p->tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); + glBindTexture(GL_TEXTURE_2D, 0); + } if (!p->windowName.empty()) { - blog(LOG_INFO, "[window-capture: '%s'] update settings:\n" - "\ttitle: %s\n" - "\tclass: %s\n" - "\tHas alpha: %s\n" - "\tFound proper GLXFBConfig: %s\n", - obs_source_get_name(p->source), - XCompcap::getWindowName(p->win).c_str(), - XCompcap::getWindowClass(p->win).c_str(), - has_alpha ? "yes" : "no", - found ? "yes" : "no"); - blog(LOG_DEBUG, "\n" - "\tid: %s", - std::to_string((long long)p->win).c_str()); + blog(LOG_INFO, + "[window-capture: '%s'] update settings:\n" + "\ttitle: %s\n" + "\tclass: %s\n" + "\tBit depth: %i\n" + "\tFound proper GLXFBConfig (in %i): %s\n", + obs_source_get_name(p->source), + XCompcap::getWindowName(p->win).c_str(), + XCompcap::getWindowClass(p->win).c_str(), attr.depth, + nelem, found ? "yes" : "no"); } } @@ -596,33 +607,28 @@ void XCompcapMain::tick(float seconds) obs_enter_graphics(); if (p->lockX) { + // XDisplayLock is still live so we should already be locked. XLockDisplay(xdisp); XSync(xdisp, 0); } if (p->include_border) { - gs_copy_texture_region( - p->tex, 0, 0, - p->gltex, - p->cur_cut_left, - p->cur_cut_top, - width(), height()); + gs_copy_texture_region(p->tex, 0, 0, p->gltex, p->cur_cut_left, + p->cur_cut_top, width(), height()); } else { - gs_copy_texture_region( - p->tex, 0, 0, - p->gltex, - p->cur_cut_left + p->border, - p->cur_cut_top + p->border, - width(), height()); + gs_copy_texture_region(p->tex, 0, 0, p->gltex, + p->cur_cut_left + p->border, + p->cur_cut_top + p->border, width(), + height()); } if (p->cursor && p->show_cursor) { xcursor_tick(p->cursor); p->cursor_outside = - p->cursor->x < p->cur_cut_left || - p->cursor->y < p->cur_cut_top || - p->cursor->x > int(p->width - p->cur_cut_right) || + p->cursor->x < p->cur_cut_left || + p->cursor->y < p->cur_cut_top || + p->cursor->x > int(p->width - p->cur_cut_right) || p->cursor->y > int(p->height - p->cur_cut_bot); } diff --git a/plugins/linux-capture/xcompcap-main.hpp b/plugins/linux-capture/xcompcap-main.hpp index a076167..4141beb 100644 --- a/plugins/linux-capture/xcompcap-main.hpp +++ b/plugins/linux-capture/xcompcap-main.hpp @@ -2,9 +2,8 @@ struct XCompcapMain_private; -class XCompcapMain -{ - public: +class XCompcapMain { +public: static bool init(); static void deinit(); @@ -22,6 +21,6 @@ class XCompcapMain uint32_t width(); uint32_t height(); - private: +private: XCompcapMain_private *p; }; diff --git a/plugins/linux-capture/xcomposite-main.cpp b/plugins/linux-capture/xcomposite-main.cpp index c553fb2..0fa6591 100644 --- a/plugins/linux-capture/xcomposite-main.cpp +++ b/plugins/linux-capture/xcomposite-main.cpp @@ -2,38 +2,38 @@ #include "xcompcap-main.hpp" -static void* xcompcap_create(obs_data_t *settings, obs_source_t *source) +static void *xcompcap_create(obs_data_t *settings, obs_source_t *source) { return new XCompcapMain(settings, source); } static void xcompcap_destroy(void *data) { - XCompcapMain* cc = (XCompcapMain*)data; + XCompcapMain *cc = (XCompcapMain *)data; delete cc; } -static void xcompcap_video_tick(void* data, float seconds) +static void xcompcap_video_tick(void *data, float seconds) { - XCompcapMain* cc = (XCompcapMain*)data; + XCompcapMain *cc = (XCompcapMain *)data; cc->tick(seconds); } -static void xcompcap_video_render(void* data, gs_effect_t *effect) +static void xcompcap_video_render(void *data, gs_effect_t *effect) { - XCompcapMain* cc = (XCompcapMain*)data; + XCompcapMain *cc = (XCompcapMain *)data; cc->render(effect); } -static uint32_t xcompcap_getwidth(void* data) +static uint32_t xcompcap_getwidth(void *data) { - XCompcapMain* cc = (XCompcapMain*)data; + XCompcapMain *cc = (XCompcapMain *)data; return cc->width(); } -static uint32_t xcompcap_getheight(void* data) +static uint32_t xcompcap_getheight(void *data) { - XCompcapMain* cc = (XCompcapMain*)data; + XCompcapMain *cc = (XCompcapMain *)data; return cc->height(); } @@ -51,11 +51,11 @@ void xcompcap_defaults(obs_data_t *settings) void xcompcap_update(void *data, obs_data_t *settings) { - XCompcapMain* cc = (XCompcapMain*)data; + XCompcapMain *cc = (XCompcapMain *)data; cc->updateSettings(settings); } -static const char* xcompcap_getname(void*) +static const char *xcompcap_getname(void *) { return obs_module_text("XCCapture"); } @@ -69,20 +69,19 @@ extern "C" void xcomposite_load(void) memset(&sinfo, 0, sizeof(obs_source_info)); sinfo.id = "xcomposite_input"; - sinfo.output_flags = OBS_SOURCE_VIDEO | - OBS_SOURCE_CUSTOM_DRAW | - OBS_SOURCE_DO_NOT_DUPLICATE; + sinfo.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW | + OBS_SOURCE_DO_NOT_DUPLICATE; - sinfo.get_name = xcompcap_getname; - sinfo.create = xcompcap_create; - sinfo.destroy = xcompcap_destroy; + sinfo.get_name = xcompcap_getname; + sinfo.create = xcompcap_create; + sinfo.destroy = xcompcap_destroy; sinfo.get_properties = xcompcap_props; - sinfo.get_defaults = xcompcap_defaults; - sinfo.update = xcompcap_update; - sinfo.video_tick = xcompcap_video_tick; - sinfo.video_render = xcompcap_video_render; - sinfo.get_width = xcompcap_getwidth; - sinfo.get_height = xcompcap_getheight; + sinfo.get_defaults = xcompcap_defaults; + sinfo.update = xcompcap_update; + sinfo.video_tick = xcompcap_video_tick; + sinfo.video_render = xcompcap_video_render; + sinfo.get_width = xcompcap_getwidth; + sinfo.get_height = xcompcap_getheight; obs_register_source(&sinfo); } diff --git a/plugins/linux-capture/xcursor-xcb.c b/plugins/linux-capture/xcursor-xcb.c index dd0e230..a0306a6 100644 --- a/plugins/linux-capture/xcursor-xcb.c +++ b/plugins/linux-capture/xcursor-xcb.c @@ -26,26 +26,27 @@ along with this program. If not, see . * size or by creating a new texture if the size is different */ static void xcb_xcursor_create(xcb_xcursor_t *data, - xcb_xfixes_get_cursor_image_reply_t *xc) + xcb_xfixes_get_cursor_image_reply_t *xc) { uint32_t *pixels = xcb_xfixes_get_cursor_image_cursor_image(xc); if (!pixels) return; if (data->tex && data->last_height == xc->width && - data->last_width == xc->height) { - gs_texture_set_image(data->tex, (const uint8_t *) pixels, - xc->width * sizeof(uint32_t), false); + data->last_width == xc->height) { + gs_texture_set_image(data->tex, (const uint8_t *)pixels, + xc->width * sizeof(uint32_t), false); } else { if (data->tex) gs_texture_destroy(data->tex); - data->tex = gs_texture_create(xc->width, xc->height, - GS_BGRA, 1, (const uint8_t **) &pixels, GS_DYNAMIC); + data->tex = gs_texture_create(xc->width, xc->height, GS_BGRA, 1, + (const uint8_t **)&pixels, + GS_DYNAMIC); } data->last_serial = xc->cursor_serial; - data->last_width = xc->width; + data->last_width = xc->width; data->last_height = xc->height; } @@ -58,8 +59,8 @@ xcb_xcursor_t *xcb_xcursor_init(xcb_connection_t *xcb) xcb_xfixes_query_version_cookie_t xfix_c; - xfix_c = xcb_xfixes_query_version_unchecked(xcb, - XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION); + xfix_c = xcb_xfixes_query_version_unchecked( + xcb, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION); free(xcb_xfixes_query_version_reply(xcb, xfix_c, NULL)); return data; @@ -73,7 +74,7 @@ void xcb_xcursor_destroy(xcb_xcursor_t *data) } void xcb_xcursor_update(xcb_xcursor_t *data, - xcb_xfixes_get_cursor_image_reply_t *xc) + xcb_xfixes_get_cursor_image_reply_t *xc) { if (!data || !xc) return; @@ -81,8 +82,8 @@ void xcb_xcursor_update(xcb_xcursor_t *data, if (!data->tex || data->last_serial != xc->cursor_serial) xcb_xcursor_create(data, xc); - data->x = xc->x - data->x_org; - data->y = xc->y - data->y_org; + data->x = xc->x - data->x_org; + data->y = xc->y - data->y_org; data->x_render = data->x - xc->xhot; data->y_render = data->y - xc->yhot; } @@ -92,7 +93,7 @@ void xcb_xcursor_render(xcb_xcursor_t *data) if (!data->tex) return; - gs_effect_t *effect = gs_get_effect(); + gs_effect_t *effect = gs_get_effect(); gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); gs_effect_set_texture(image, data->tex); @@ -109,9 +110,8 @@ void xcb_xcursor_render(xcb_xcursor_t *data) gs_blend_state_pop(); } -void xcb_xcursor_offset(xcb_xcursor_t* data, const int x_org, const int y_org) +void xcb_xcursor_offset(xcb_xcursor_t *data, const int x_org, const int y_org) { data->x_org = x_org; data->y_org = y_org; } - diff --git a/plugins/linux-capture/xcursor-xcb.h b/plugins/linux-capture/xcursor-xcb.h index 69561b6..2a435d9 100644 --- a/plugins/linux-capture/xcursor-xcb.h +++ b/plugins/linux-capture/xcursor-xcb.h @@ -30,12 +30,12 @@ typedef struct { unsigned int last_height; gs_texture_t *tex; - int x; - int y; - int x_org; - int y_org; - float x_render; - float y_render; + int x; + int y; + int x_org; + int y_org; + float x_render; + float y_render; } xcb_xcursor_t; /** @@ -60,7 +60,7 @@ void xcb_xcursor_destroy(xcb_xcursor_t *data); * */ void xcb_xcursor_update(xcb_xcursor_t *data, - xcb_xfixes_get_cursor_image_reply_t *xc); + xcb_xfixes_get_cursor_image_reply_t *xc); /** * Draw the cursor diff --git a/plugins/linux-capture/xcursor.c b/plugins/linux-capture/xcursor.c index 624614f..85bb73a 100644 --- a/plugins/linux-capture/xcursor.c +++ b/plugins/linux-capture/xcursor.c @@ -28,12 +28,13 @@ along with this program. If not, see . * Theres a lot of talk about this in other implementation and they tend to * be really complicated, but this naive approach seems to work fine ... */ -static uint32_t *xcursor_pixels(XFixesCursorImage *xc) { +static uint32_t *xcursor_pixels(XFixesCursorImage *xc) +{ uint_fast32_t size = xc->width * xc->height; uint32_t *pixels = bmalloc(size * sizeof(uint32_t)); for (uint_fast32_t i = 0; i < size; ++i) - pixels[i] = (uint32_t) xc->pixels[i]; + pixels[i] = (uint32_t)xc->pixels[i]; return pixels; } @@ -42,22 +43,23 @@ static uint32_t *xcursor_pixels(XFixesCursorImage *xc) { * Create the cursor texture, either by updating if the new cursor has the same * size or by creating a new texture if the size is different */ -static void xcursor_create(xcursor_t *data, XFixesCursorImage *xc) { +static void xcursor_create(xcursor_t *data, XFixesCursorImage *xc) +{ uint32_t *pixels = xcursor_pixels(xc); if (!pixels) return; - if (data->tex - && data->last_height == xc->width - && data->last_width == xc->height) { - gs_texture_set_image(data->tex, (const uint8_t *) pixels, - xc->width * sizeof(uint32_t), False); + if (data->tex && data->last_height == xc->width && + data->last_width == xc->height) { + gs_texture_set_image(data->tex, (const uint8_t *)pixels, + xc->width * sizeof(uint32_t), False); } else { if (data->tex) gs_texture_destroy(data->tex); - data->tex = gs_texture_create(xc->width, xc->height, - GS_BGRA, 1, (const uint8_t **) &pixels, GS_DYNAMIC); + data->tex = gs_texture_create(xc->width, xc->height, GS_BGRA, 1, + (const uint8_t **)&pixels, + GS_DYNAMIC); } bfree(pixels); @@ -67,7 +69,8 @@ static void xcursor_create(xcursor_t *data, XFixesCursorImage *xc) { data->last_height = xc->height; } -xcursor_t *xcursor_init(Display *dpy) { +xcursor_t *xcursor_init(Display *dpy) +{ xcursor_t *data = bzalloc(sizeof(xcursor_t)); data->dpy = dpy; @@ -76,13 +79,15 @@ xcursor_t *xcursor_init(Display *dpy) { return data; } -void xcursor_destroy(xcursor_t *data) { +void xcursor_destroy(xcursor_t *data) +{ if (data->tex) gs_texture_destroy(data->tex); bfree(data); } -void xcursor_tick(xcursor_t *data) { +void xcursor_tick(xcursor_t *data) +{ XFixesCursorImage *xc = XFixesGetCursorImage(data->dpy); if (!xc) return; @@ -98,11 +103,12 @@ void xcursor_tick(xcursor_t *data) { XFree(xc); } -void xcursor_render(xcursor_t *data) { +void xcursor_render(xcursor_t *data) +{ if (!data->tex) return; - gs_effect_t *effect = gs_get_effect(); + gs_effect_t *effect = gs_get_effect(); gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); gs_effect_set_texture(image, data->tex); @@ -119,9 +125,8 @@ void xcursor_render(xcursor_t *data) { gs_blend_state_pop(); } -void xcursor_offset(xcursor_t* data, int_fast32_t x_org, int_fast32_t y_org) +void xcursor_offset(xcursor_t *data, int_fast32_t x_org, int_fast32_t y_org) { data->x_org = x_org; data->y_org = y_org; } - diff --git a/plugins/linux-capture/xhelpers.c b/plugins/linux-capture/xhelpers.c index 724f4f3..d73d7da 100644 --- a/plugins/linux-capture/xhelpers.c +++ b/plugins/linux-capture/xhelpers.c @@ -30,7 +30,7 @@ bool xinerama_is_active(xcb_connection_t *xcb) bool active = true; xcb_xinerama_is_active_cookie_t xnr_c; - xcb_xinerama_is_active_reply_t *xnr_r; + xcb_xinerama_is_active_reply_t *xnr_r; xnr_c = xcb_xinerama_is_active_unchecked(xcb); xnr_r = xcb_xinerama_is_active_reply(xcb, xnr_c, NULL); @@ -48,7 +48,7 @@ int xinerama_screen_count(xcb_connection_t *xcb) int screens = 0; xcb_xinerama_query_screens_cookie_t scr_c; - xcb_xinerama_query_screens_reply_t *scr_r; + xcb_xinerama_query_screens_reply_t *scr_r; scr_c = xcb_xinerama_query_screens_unchecked(xcb); scr_r = xcb_xinerama_query_screens_reply(xcb, scr_c, NULL); @@ -60,15 +60,15 @@ int xinerama_screen_count(xcb_connection_t *xcb) } int xinerama_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, - int_fast32_t *x, int_fast32_t *y, - int_fast32_t *w, int_fast32_t *h) + int_fast32_t *x, int_fast32_t *y, int_fast32_t *w, + int_fast32_t *h) { if (!xcb) goto fail; bool success = false; xcb_xinerama_query_screens_cookie_t scr_c; - xcb_xinerama_query_screens_reply_t *scr_r; + xcb_xinerama_query_screens_reply_t *scr_r; xcb_xinerama_screen_info_iterator_t iter; scr_c = xcb_xinerama_query_screens_unchecked(xcb); @@ -113,7 +113,7 @@ int randr_screen_count(xcb_connection_t *xcb) screen = xcb_setup_roots_iterator(xcb_get_setup(xcb)).data; xcb_randr_get_screen_resources_cookie_t res_c; - xcb_randr_get_screen_resources_reply_t* res_r; + xcb_randr_get_screen_resources_reply_t *res_r; res_c = xcb_randr_get_screen_resources(xcb, screen->root); res_r = xcb_randr_get_screen_resources_reply(xcb, res_c, 0); @@ -124,15 +124,14 @@ int randr_screen_count(xcb_connection_t *xcb) } int randr_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, - int_fast32_t *x, int_fast32_t *y, - int_fast32_t *w, int_fast32_t *h, - xcb_screen_t **rscreen) + int_fast32_t *x, int_fast32_t *y, int_fast32_t *w, + int_fast32_t *h, xcb_screen_t **rscreen) { xcb_screen_t *xscreen; xscreen = xcb_setup_roots_iterator(xcb_get_setup(xcb)).data; xcb_randr_get_screen_resources_cookie_t res_c; - xcb_randr_get_screen_resources_reply_t* res_r; + xcb_randr_get_screen_resources_reply_t *res_r; res_c = xcb_randr_get_screen_resources(xcb, xscreen->root); res_r = xcb_randr_get_screen_resources_reply(xcb, res_c, 0); @@ -168,8 +167,8 @@ fail: return -1; } -int x11_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, - int_fast32_t *w, int_fast32_t *h) +int x11_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, int_fast32_t *w, + int_fast32_t *h) { if (!xcb) goto fail; @@ -194,14 +193,14 @@ fail: return -1; } -xcb_shm_t* xshm_xcb_attach(xcb_connection_t *xcb, const int w, const int h) +xcb_shm_t *xshm_xcb_attach(xcb_connection_t *xcb, const int w, const int h) { if (!xcb) return NULL; xcb_shm_t *shm = bzalloc(sizeof(xcb_shm_t)); - shm->xcb = xcb; - shm->seg = xcb_generate_id(shm->xcb); + shm->xcb = xcb; + shm->seg = xcb_generate_id(shm->xcb); shm->shmid = shmget(IPC_PRIVATE, w * h * 4, IPC_CREAT | 0777); if (shm->shmid == -1) @@ -224,7 +223,7 @@ void xshm_xcb_detach(xcb_shm_t *shm) xcb_shm_detach(shm->xcb, shm->seg); - if ((char *) shm->data != (char *) -1) + if ((char *)shm->data != (char *)-1) shmdt(shm->data); if (shm->shmid != -1) diff --git a/plugins/linux-capture/xhelpers.h b/plugins/linux-capture/xhelpers.h index 95aff5c..ffc3f8b 100644 --- a/plugins/linux-capture/xhelpers.h +++ b/plugins/linux-capture/xhelpers.h @@ -27,9 +27,9 @@ extern "C" { typedef struct { xcb_connection_t *xcb; - xcb_shm_seg_t seg; - int shmid; - uint8_t *data; + xcb_shm_seg_t seg; + int shmid; + uint8_t *data; } xcb_shm_t; /** @@ -61,8 +61,8 @@ int xinerama_screen_count(xcb_connection_t *xcb); * @return < 0 on error */ int xinerama_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, - int_fast32_t *x, int_fast32_t *y, - int_fast32_t *w, int_fast32_t *h); + int_fast32_t *x, int_fast32_t *y, int_fast32_t *w, + int_fast32_t *h); /** * Check for Randr extension @@ -93,9 +93,8 @@ int randr_screen_count(xcb_connection_t *xcb); * @return < 0 on error */ int randr_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, - int_fast32_t *x, int_fast32_t *y, - int_fast32_t *w, int_fast32_t *h, - xcb_screen_t **rscreen); + int_fast32_t *x, int_fast32_t *y, int_fast32_t *w, + int_fast32_t *h, xcb_screen_t **rscreen); /** * Get screen geometry for a X11 screen @@ -109,8 +108,8 @@ int randr_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, * * @return < 0 on error */ -int x11_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, - int_fast32_t *w, int_fast32_t *h); +int x11_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, int_fast32_t *w, + int_fast32_t *h); /** * Attach a shared memory segment to the X-Server diff --git a/plugins/linux-capture/xshm-input.c b/plugins/linux-capture/xshm-input.c index f00c0eb..c7db74d 100644 --- a/plugins/linux-capture/xshm-input.c +++ b/plugins/linux-capture/xshm-input.c @@ -33,26 +33,26 @@ along with this program. If not, see . #define blog(level, msg, ...) blog(level, "xshm-input: " msg, ##__VA_ARGS__) struct xshm_data { - obs_source_t *source; + obs_source_t *source; xcb_connection_t *xcb; - xcb_screen_t *xcb_screen; - xcb_shm_t *xshm; - xcb_xcursor_t *cursor; + xcb_screen_t *xcb_screen; + xcb_shm_t *xshm; + xcb_xcursor_t *cursor; - char *server; - uint_fast32_t screen_id; - int_fast32_t x_org; - int_fast32_t y_org; - int_fast32_t width; - int_fast32_t height; + char *server; + uint_fast32_t screen_id; + int_fast32_t x_org; + int_fast32_t y_org; + int_fast32_t width; + int_fast32_t height; - gs_texture_t *texture; + gs_texture_t *texture; - bool show_cursor; - bool use_xinerama; - bool use_randr; - bool advanced; + bool show_cursor; + bool use_xinerama; + bool use_randr; + bool advanced; }; /** @@ -66,8 +66,8 @@ static inline void xshm_resize_texture(struct xshm_data *data) { if (data->texture) gs_texture_destroy(data->texture); - data->texture = gs_texture_create(data->width, data->height, - GS_BGRA, 1, NULL, GS_DYNAMIC); + data->texture = gs_texture_create(data->width, data->height, GS_BGRA, 1, + NULL, GS_DYNAMIC); } /** @@ -102,26 +102,23 @@ static int_fast32_t xshm_update_geometry(struct xshm_data *data) int_fast32_t old_height = data->height; if (data->use_randr) { - if (randr_screen_geo(data->xcb, data->screen_id, - &data->x_org, &data->y_org, - &data->width, &data->height, - &data->xcb_screen) < 0) { + if (randr_screen_geo(data->xcb, data->screen_id, &data->x_org, + &data->y_org, &data->width, &data->height, + &data->xcb_screen) < 0) { return -1; } - } - else if (data->use_xinerama) { + } else if (data->use_xinerama) { if (xinerama_screen_geo(data->xcb, data->screen_id, - &data->x_org, &data->y_org, - &data->width, &data->height) < 0) { + &data->x_org, &data->y_org, + &data->width, &data->height) < 0) { return -1; } data->xcb_screen = xcb_get_screen(data->xcb, 0); - } - else { + } else { data->x_org = 0; data->y_org = 0; - if (x11_screen_geo(data->xcb, data->screen_id, - &data->width, &data->height) < 0) { + if (x11_screen_geo(data->xcb, data->screen_id, &data->width, + &data->height) < 0) { return -1; } data->xcb_screen = xcb_get_screen(data->xcb, data->screen_id); @@ -132,9 +129,10 @@ static int_fast32_t xshm_update_geometry(struct xshm_data *data) return -1; } - blog(LOG_INFO, "Geometry %"PRIdFAST32"x%"PRIdFAST32 - " @ %"PRIdFAST32",%"PRIdFAST32, - data->width, data->height, data->x_org, data->y_org); + blog(LOG_INFO, + "Geometry %" PRIdFAST32 "x%" PRIdFAST32 " @ %" PRIdFAST32 + ",%" PRIdFAST32, + data->width, data->height, data->x_org, data->y_org); if (old_width == data->width && old_height == data->height) return 0; @@ -145,7 +143,7 @@ static int_fast32_t xshm_update_geometry(struct xshm_data *data) /** * Returns the name of the plugin */ -static const char* xshm_getname(void *unused) +static const char *xshm_getname(void *unused) { UNUSED_PARAMETER(unused); return obs_module_text("X11SharedMemoryScreenInput"); @@ -190,8 +188,8 @@ static void xshm_capture_stop(struct xshm_data *data) */ static void xshm_capture_start(struct xshm_data *data) { - const char *server = (data->advanced && *data->server) - ? data->server : NULL; + const char *server = (data->advanced && *data->server) ? data->server + : NULL; data->xcb = xcb_connect(server, NULL); if (!data->xcb || xcb_connection_has_error(data->xcb)) { @@ -239,10 +237,10 @@ static void xshm_update(void *vptr, obs_data_t *settings) xshm_capture_stop(data); - data->screen_id = obs_data_get_int(settings, "screen"); + data->screen_id = obs_data_get_int(settings, "screen"); data->show_cursor = obs_data_get_bool(settings, "show_cursor"); - data->advanced = obs_data_get_bool(settings, "advanced"); - data->server = bstrdup(obs_data_get_string(settings, "server")); + data->advanced = obs_data_get_bool(settings, "advanced"); + data->server = bstrdup(obs_data_get_string(settings, "server")); xshm_capture_start(data); } @@ -260,11 +258,11 @@ static void xshm_defaults(obs_data_t *defaults) /** * Toggle visibility of advanced settings */ -static bool xshm_toggle_advanced(obs_properties_t *props, - obs_property_t *p, obs_data_t *settings) +static bool xshm_toggle_advanced(obs_properties_t *props, obs_property_t *p, + obs_data_t *settings) { UNUSED_PARAMETER(p); - const bool visible = obs_data_get_bool(settings, "advanced"); + const bool visible = obs_data_get_bool(settings, "advanced"); obs_property_t *server = obs_properties_get(props, "server"); obs_property_set_visible(server, visible); @@ -278,14 +276,14 @@ static bool xshm_toggle_advanced(obs_properties_t *props, /** * The x server was changed */ -static bool xshm_server_changed(obs_properties_t *props, - obs_property_t *p, obs_data_t *settings) +static bool xshm_server_changed(obs_properties_t *props, obs_property_t *p, + obs_data_t *settings) { UNUSED_PARAMETER(p); - bool advanced = obs_data_get_bool(settings, "advanced"); + bool advanced = obs_data_get_bool(settings, "advanced"); int_fast32_t old_screen = obs_data_get_int(settings, "screen"); - const char *server = obs_data_get_string(settings, "server"); + const char *server = obs_data_get_string(settings, "server"); obs_property_t *screens = obs_properties_get(props, "screen"); /* we want a real NULL here in case there is no string here */ @@ -303,11 +301,11 @@ static bool xshm_server_changed(obs_properties_t *props, dstr_init(&screen_info); bool randr = randr_is_active(xcb); bool xinerama = xinerama_is_active(xcb); - int_fast32_t count = (randr) ? - randr_screen_count(xcb) : - (xinerama) ? - xinerama_screen_count(xcb) : - xcb_setup_roots_length(xcb_get_setup(xcb)); + int_fast32_t count = + (randr) ? randr_screen_count(xcb) + : (xinerama) + ? xinerama_screen_count(xcb) + : xcb_setup_roots_length(xcb_get_setup(xcb)); for (int_fast32_t i = 0; i < count; ++i) { int_fast32_t x, y, w, h; @@ -320,21 +318,22 @@ static bool xshm_server_changed(obs_properties_t *props, else x11_screen_geo(xcb, i, &w, &h); - dstr_printf(&screen_info, "Screen %"PRIuFAST32" (%"PRIuFAST32 - "x%"PRIuFAST32" @ %"PRIuFAST32 - ",%"PRIuFAST32")", i, w, h, x, y); + dstr_printf(&screen_info, + "Screen %" PRIuFAST32 " (%" PRIuFAST32 + "x%" PRIuFAST32 " @ %" PRIuFAST32 ",%" PRIuFAST32 + ")", + i, w, h, x, y); obs_property_list_add_int(screens, screen_info.array, i); } /* handle missing screen */ if (old_screen + 1 > count) { - dstr_printf(&screen_info, "Screen %"PRIuFAST32" (not found)", - old_screen); - size_t index = obs_property_list_add_int(screens, - screen_info.array, old_screen); + dstr_printf(&screen_info, "Screen %" PRIuFAST32 " (not found)", + old_screen); + size_t index = obs_property_list_add_int( + screens, screen_info.array, old_screen); obs_property_list_item_disable(screens, index, true); - } dstr_free(&screen_info); @@ -355,13 +354,13 @@ static obs_properties_t *xshm_properties(void *vptr) obs_properties_t *props = obs_properties_create(); obs_properties_add_list(props, "screen", obs_module_text("Screen"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); obs_properties_add_bool(props, "show_cursor", - obs_module_text("CaptureCursor")); - obs_property_t *advanced = obs_properties_add_bool(props, "advanced", - obs_module_text("AdvancedSettings")); - obs_property_t *server = obs_properties_add_text(props, "server", - obs_module_text("XServer"), OBS_TEXT_DEFAULT); + obs_module_text("CaptureCursor")); + obs_property_t *advanced = obs_properties_add_bool( + props, "advanced", obs_module_text("AdvancedSettings")); + obs_property_t *server = obs_properties_add_text( + props, "server", obs_module_text("XServer"), OBS_TEXT_DEFAULT); obs_property_set_modified_callback(advanced, xshm_toggle_advanced); obs_property_set_modified_callback(server, xshm_server_changed); @@ -415,14 +414,16 @@ static void xshm_video_tick(void *vptr, float seconds) if (!obs_source_showing(data->source)) return; - xcb_shm_get_image_cookie_t img_c; - xcb_shm_get_image_reply_t *img_r; + xcb_shm_get_image_cookie_t img_c; + xcb_shm_get_image_reply_t *img_r; xcb_xfixes_get_cursor_image_cookie_t cur_c; - xcb_xfixes_get_cursor_image_reply_t *cur_r; + xcb_xfixes_get_cursor_image_reply_t *cur_r; img_c = xcb_shm_get_image_unchecked(data->xcb, data->xcb_screen->root, - data->x_org, data->y_org, data->width, data->height, - ~0, XCB_IMAGE_FORMAT_Z_PIXMAP, data->xshm->seg, 0); + data->x_org, data->y_org, + data->width, data->height, ~0, + XCB_IMAGE_FORMAT_Z_PIXMAP, + data->xshm->seg, 0); cur_c = xcb_xfixes_get_cursor_image_unchecked(data->xcb); img_r = xcb_shm_get_image_reply(data->xcb, img_c, NULL); @@ -433,8 +434,8 @@ static void xshm_video_tick(void *vptr, float seconds) obs_enter_graphics(); - gs_texture_set_image(data->texture, (void *) data->xshm->data, - data->width * 4, false); + gs_texture_set_image(data->texture, (void *)data->xshm->data, + data->width * 4, false); xcb_xcursor_update(data->cursor, cur_r); obs_leave_graphics(); @@ -491,19 +492,18 @@ static uint32_t xshm_getheight(void *vptr) } struct obs_source_info xshm_input = { - .id = "xshm_input", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_VIDEO | - OBS_SOURCE_CUSTOM_DRAW | - OBS_SOURCE_DO_NOT_DUPLICATE, - .get_name = xshm_getname, - .create = xshm_create, - .destroy = xshm_destroy, - .update = xshm_update, - .get_defaults = xshm_defaults, + .id = "xshm_input", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW | + OBS_SOURCE_DO_NOT_DUPLICATE, + .get_name = xshm_getname, + .create = xshm_create, + .destroy = xshm_destroy, + .update = xshm_update, + .get_defaults = xshm_defaults, .get_properties = xshm_properties, - .video_tick = xshm_video_tick, - .video_render = xshm_video_render, - .get_width = xshm_getwidth, - .get_height = xshm_getheight + .video_tick = xshm_video_tick, + .video_render = xshm_video_render, + .get_width = xshm_getwidth, + .get_height = xshm_getheight, }; diff --git a/plugins/linux-jack/data/locale/de-DE.ini b/plugins/linux-jack/data/locale/de-DE.ini index 2c222bb..25c86ef 100644 --- a/plugins/linux-jack/data/locale/de-DE.ini +++ b/plugins/linux-jack/data/locale/de-DE.ini @@ -1,4 +1,4 @@ -StartJACKServer="JACK-Server starten" +StartJACKServer="JACK‐Server starten" Channels="Anzahl der Kanäle" -JACKInput="JACK-Eingabe-Client" +JACKInput="JACK‐Eingabe‐Client" diff --git a/plugins/linux-jack/jack-input.c b/plugins/linux-jack/jack-input.c index f147469..7816f2f 100644 --- a/plugins/linux-jack/jack-input.c +++ b/plugins/linux-jack/jack-input.c @@ -33,7 +33,7 @@ static const char *jack_input_getname(void *unused) */ static void jack_destroy(void *vptr) { - struct jack_data* data = (struct jack_data*)vptr; + struct jack_data *data = (struct jack_data *)vptr; if (!data) return; @@ -51,14 +51,14 @@ static void jack_destroy(void *vptr) */ static void jack_update(void *vptr, obs_data_t *settings) { - struct jack_data* data = (struct jack_data*)vptr; + struct jack_data *data = (struct jack_data *)vptr; if (!data) return; const char *new_device; - bool settings_changed = false; + bool settings_changed = false; bool new_jack_start_server = obs_data_get_bool(settings, "startjack"); - int new_channel_count = obs_data_get_int(settings, "channels"); + int new_channel_count = obs_data_get_int(settings, "channels"); if (new_jack_start_server != data->start_jack_server) { data->start_jack_server = new_jack_start_server; @@ -99,7 +99,7 @@ static void *jack_create(obs_data_t *settings, obs_source_t *source) struct jack_data *data = bzalloc(sizeof(struct jack_data)); pthread_mutex_init(&data->jack_mutex, NULL); - data->source = source; + data->source = source; data->channels = -1; jack_update(data, settings); @@ -129,22 +129,22 @@ static obs_properties_t *jack_input_properties(void *unused) obs_properties_t *props = obs_properties_create(); - obs_properties_add_int(props, "channels", - obs_module_text("Channels"), 1, 8, 1); + obs_properties_add_int(props, "channels", obs_module_text("Channels"), + 1, 8, 1); obs_properties_add_bool(props, "startjack", - obs_module_text("StartJACKServer")); + obs_module_text("StartJACKServer")); return props; } struct obs_source_info jack_output_capture = { - .id = "jack_output_capture", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_AUDIO, - .get_name = jack_input_getname, - .create = jack_create, - .destroy = jack_destroy, - .update = jack_update, - .get_defaults = jack_input_defaults, - .get_properties = jack_input_properties + .id = "jack_output_capture", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_AUDIO, + .get_name = jack_input_getname, + .create = jack_create, + .destroy = jack_destroy, + .update = jack_update, + .get_defaults = jack_input_defaults, + .get_properties = jack_input_properties, }; diff --git a/plugins/linux-jack/jack-wrapper.c b/plugins/linux-jack/jack-wrapper.c index 98fa132..b733a6f 100644 --- a/plugins/linux-jack/jack-wrapper.c +++ b/plugins/linux-jack/jack-wrapper.c @@ -36,33 +36,39 @@ along with this program. If not, see . */ static enum speaker_layout jack_channels_to_obs_speakers(uint_fast32_t channels) { - switch(channels) { - case 1: return SPEAKERS_MONO; - case 2: return SPEAKERS_STEREO; - case 3: return SPEAKERS_2POINT1; - case 5: return SPEAKERS_4POINT1; - case 6: return SPEAKERS_5POINT1; + switch (channels) { + case 1: + return SPEAKERS_MONO; + case 2: + return SPEAKERS_STEREO; + case 3: + return SPEAKERS_2POINT1; + case 5: + return SPEAKERS_4POINT1; + case 6: + return SPEAKERS_5POINT1; /* What should we do with 7 channels? */ /* case 7: return SPEAKERS_...; */ - case 8: return SPEAKERS_7POINT1; + case 8: + return SPEAKERS_7POINT1; } return SPEAKERS_UNKNOWN; } -int jack_process_callback(jack_nframes_t nframes, void* arg) +int jack_process_callback(jack_nframes_t nframes, void *arg) { - struct jack_data* data = (struct jack_data*)arg; + struct jack_data *data = (struct jack_data *)arg; if (data == 0) return 0; pthread_mutex_lock(&data->jack_mutex); struct obs_source_audio out; - out.speakers = jack_channels_to_obs_speakers(data->channels); - out.samples_per_sec = jack_get_sample_rate (data->jack_client); + out.speakers = jack_channels_to_obs_speakers(data->channels); + out.samples_per_sec = jack_get_sample_rate(data->jack_client); /* format is always 32 bit float for jack */ - out.format = AUDIO_FORMAT_FLOAT_PLANAR; + out.format = AUDIO_FORMAT_FLOAT_PLANAR; for (unsigned int i = 0; i < data->channels; ++i) { jack_default_audio_sample_t *jack_buffer = @@ -71,61 +77,61 @@ int jack_process_callback(jack_nframes_t nframes, void* arg) out.data[i] = (uint8_t *)jack_buffer; } - out.frames = nframes; + out.frames = nframes; out.timestamp = os_gettime_ns() - - jack_frames_to_time(data->jack_client, nframes); + jack_frames_to_time(data->jack_client, nframes); obs_source_output_audio(data->source, &out); pthread_mutex_unlock(&data->jack_mutex); return 0; } -int_fast32_t jack_init(struct jack_data* data) +int_fast32_t jack_init(struct jack_data *data) { pthread_mutex_lock(&data->jack_mutex); if (data->jack_client != NULL) goto good; - jack_options_t jack_option = data->start_jack_server ? - JackNullOption : JackNoStartServer; + jack_options_t jack_option = + data->start_jack_server ? JackNullOption : JackNoStartServer; data->jack_client = jack_client_open(data->device, jack_option, 0); if (data->jack_client == NULL) { blog(LOG_ERROR, - "jack_client_open Error:" - "Could not create JACK client! %s", - data->device); + "jack_client_open Error:" + "Could not create JACK client! %s", + data->device); goto error; } - data->jack_ports = (jack_port_t**)bzalloc( - sizeof(jack_port_t*) * data->channels); + data->jack_ports = + (jack_port_t **)bzalloc(sizeof(jack_port_t *) * data->channels); for (unsigned int i = 0; i < data->channels; ++i) { char port_name[10] = {'\0'}; - snprintf(port_name, sizeof(port_name), "in_%u", i+1); + snprintf(port_name, sizeof(port_name), "in_%u", i + 1); - data->jack_ports[i] = jack_port_register(data->jack_client, - port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); + data->jack_ports[i] = jack_port_register( + data->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, + JackPortIsInput, 0); if (data->jack_ports[i] == NULL) { blog(LOG_ERROR, - "jack_port_register Error:" - "Could not create JACK port! %s", - port_name); + "jack_port_register Error:" + "Could not create JACK port! %s", + port_name); goto error; } } - if (jack_set_process_callback(data->jack_client, - jack_process_callback, data) != 0) { + if (jack_set_process_callback(data->jack_client, jack_process_callback, + data) != 0) { blog(LOG_ERROR, "jack_set_process_callback Error"); goto error; } if (jack_activate(data->jack_client) != 0) { - blog(LOG_ERROR, - "jack_activate Error:" - "Could not activate JACK client!"); + blog(LOG_ERROR, "jack_activate Error:" + "Could not activate JACK client!"); goto error; } @@ -138,7 +144,7 @@ error: return 1; } -void deactivate_jack(struct jack_data* data) +void deactivate_jack(struct jack_data *data) { pthread_mutex_lock(&data->jack_mutex); @@ -146,7 +152,8 @@ void deactivate_jack(struct jack_data* data) if (data->jack_ports != NULL) { for (int i = 0; i < data->channels; ++i) { if (data->jack_ports[i] != NULL) - jack_port_unregister(data->jack_client, + jack_port_unregister( + data->jack_client, data->jack_ports[i]); } bfree(data->jack_ports); diff --git a/plugins/linux-jack/jack-wrapper.h b/plugins/linux-jack/jack-wrapper.h index 460fe91..26661aa 100644 --- a/plugins/linux-jack/jack-wrapper.h +++ b/plugins/linux-jack/jack-wrapper.h @@ -43,9 +43,9 @@ struct jack_data { /** * Initialize the jack client and register the ports */ -int_fast32_t jack_init(struct jack_data* data); +int_fast32_t jack_init(struct jack_data *data); /** * Destroys the jack client and unregisters the ports */ -void deactivate_jack(struct jack_data* data); +void deactivate_jack(struct jack_data *data); diff --git a/plugins/linux-pulseaudio/data/locale/gl-ES.ini b/plugins/linux-pulseaudio/data/locale/gl-ES.ini index 1eed08b..70e3906 100644 --- a/plugins/linux-pulseaudio/data/locale/gl-ES.ini +++ b/plugins/linux-pulseaudio/data/locale/gl-ES.ini @@ -1,4 +1,4 @@ -PulseInput="Captura de entrada audio (PulseAudio)" -PulseOutput="Captura de saída de audio (PulseAudio)" +PulseInput="Captura de entrada son (PulseAudio)" +PulseOutput="Captura de saída de son (PulseAudio)" Device="Dispositivo" diff --git a/plugins/linux-pulseaudio/data/locale/ka-GE.ini b/plugins/linux-pulseaudio/data/locale/ka-GE.ini index e36f439..b7b7d7a 100644 --- a/plugins/linux-pulseaudio/data/locale/ka-GE.ini +++ b/plugins/linux-pulseaudio/data/locale/ka-GE.ini @@ -1,4 +1,4 @@ -PulseInput="შემავალი ხმოვანი სიგნალის ჩაწერა (PulseAudio)" +PulseInput="შემავალი ხმის ჩაწერა (PulseAudio)" PulseOutput="გამოტანილი ხმის ჩაწერა (PulseAudio)" Device="მოწყობილობა" diff --git a/plugins/linux-pulseaudio/pulse-input.c b/plugins/linux-pulseaudio/pulse-input.c index 698b588..68d44cd 100644 --- a/plugins/linux-pulseaudio/pulse-input.c +++ b/plugins/linux-pulseaudio/pulse-input.c @@ -21,7 +21,7 @@ along with this program. If not, see . #include "pulse-wrapper.h" -#define NSEC_PER_SEC 1000000000LL +#define NSEC_PER_SEC 1000000000LL #define NSEC_PER_MSEC 1000000L #define PULSE_DATA(voidptr) struct pulse_data *data = voidptr; @@ -53,15 +53,19 @@ static void pulse_stop_recording(struct pulse_data *data); /** * get obs from pulse audio format */ -static enum audio_format pulse_to_obs_audio_format( - pa_sample_format_t format) +static enum audio_format pulse_to_obs_audio_format(pa_sample_format_t format) { switch (format) { - case PA_SAMPLE_U8: return AUDIO_FORMAT_U8BIT; - case PA_SAMPLE_S16LE: return AUDIO_FORMAT_16BIT; - case PA_SAMPLE_S32LE: return AUDIO_FORMAT_32BIT; - case PA_SAMPLE_FLOAT32LE: return AUDIO_FORMAT_FLOAT; - default: return AUDIO_FORMAT_UNKNOWN; + case PA_SAMPLE_U8: + return AUDIO_FORMAT_U8BIT; + case PA_SAMPLE_S16LE: + return AUDIO_FORMAT_16BIT; + case PA_SAMPLE_S32LE: + return AUDIO_FORMAT_32BIT; + case PA_SAMPLE_FLOAT32LE: + return AUDIO_FORMAT_FLOAT; + default: + return AUDIO_FORMAT_UNKNOWN; } return AUDIO_FORMAT_UNKNOWN; @@ -77,17 +81,24 @@ static enum audio_format pulse_to_obs_audio_format( * @note This *might* not work for some rather unusual setups, but should work * fine for the majority of cases. */ -static enum speaker_layout pulse_channels_to_obs_speakers( - uint_fast32_t channels) +static enum speaker_layout +pulse_channels_to_obs_speakers(uint_fast32_t channels) { - switch(channels) { - case 1: return SPEAKERS_MONO; - case 2: return SPEAKERS_STEREO; - case 3: return SPEAKERS_2POINT1; - case 4: return SPEAKERS_4POINT0; - case 5: return SPEAKERS_4POINT1; - case 6: return SPEAKERS_5POINT1; - case 8: return SPEAKERS_7POINT1; + switch (channels) { + case 1: + return SPEAKERS_MONO; + case 2: + return SPEAKERS_STEREO; + case 3: + return SPEAKERS_2POINT1; + case 4: + return SPEAKERS_4POINT0; + case 5: + return SPEAKERS_4POINT1; + case 6: + return SPEAKERS_5POINT1; + case 8: + return SPEAKERS_7POINT1; } return SPEAKERS_UNKNOWN; @@ -185,19 +196,18 @@ static void pulse_stream_read(pa_stream *p, size_t nbytes, void *userdata) if (!frames) { blog(LOG_ERROR, "Got audio hole of %u bytes", - (unsigned int) bytes); + (unsigned int)bytes); pa_stream_drop(data->stream); goto exit; } struct obs_source_audio out; - out.speakers = data->speakers; + out.speakers = data->speakers; out.samples_per_sec = data->samples_per_sec; - out.format = pulse_to_obs_audio_format(data->format); - out.data[0] = (uint8_t *) frames; - out.frames = bytes / data->bytes_per_frame; - out.timestamp = get_sample_time(out.frames, - out.samples_per_sec); + out.format = pulse_to_obs_audio_format(data->format); + out.data[0] = (uint8_t *)frames; + out.frames = bytes / data->bytes_per_frame; + out.timestamp = get_sample_time(out.frames, out.samples_per_sec); if (!data->first_ts) data->first_ts = out.timestamp + STARTUP_TIMEOUT_NS; @@ -217,29 +227,32 @@ exit: * Server info callback */ static void pulse_server_info(pa_context *c, const pa_server_info *i, - void *userdata) + void *userdata) { UNUSED_PARAMETER(c); PULSE_DATA(userdata); - blog(LOG_INFO, "Server name: '%s %s'", - i->server_name, i->server_version); + blog(LOG_INFO, "Server name: '%s %s'", i->server_name, + i->server_version); if (data->device && strcmp("default", data->device) == 0) { if (data->input) { bfree(data->device); data->device = bstrdup(i->default_source_name); - blog(LOG_DEBUG, "Default input device: '%s'", data->device); + blog(LOG_DEBUG, "Default input device: '%s'", + data->device); } else { - char *monitor = bzalloc(strlen(i->default_sink_name) + 9); + char *monitor = + bzalloc(strlen(i->default_sink_name) + 9); strcat(monitor, i->default_sink_name); strcat(monitor, ".monitor"); bfree(data->device); data->device = bstrdup(monitor); - blog(LOG_DEBUG, "Default output device: '%s'", data->device); + blog(LOG_DEBUG, "Default output device: '%s'", + data->device); bfree(monitor); } } @@ -254,7 +267,7 @@ static void pulse_server_info(pa_context *c, const pa_server_info *i, * configured to something obs can't deal with. */ static void pulse_source_info(pa_context *c, const pa_source_info *i, int eol, - void *userdata) + void *userdata) { UNUSED_PARAMETER(c); PULSE_DATA(userdata); @@ -267,35 +280,36 @@ static void pulse_source_info(pa_context *c, const pa_source_info *i, int eol, if (eol > 0) goto skip; - blog(LOG_INFO, "Audio format: %s, %"PRIu32" Hz" - ", %"PRIu8" channels", - pa_sample_format_to_string(i->sample_spec.format), - i->sample_spec.rate, - i->sample_spec.channels); + blog(LOG_INFO, + "Audio format: %s, %" PRIu32 " Hz" + ", %" PRIu8 " channels", + pa_sample_format_to_string(i->sample_spec.format), + i->sample_spec.rate, i->sample_spec.channels); pa_sample_format_t format = i->sample_spec.format; if (pulse_to_obs_audio_format(format) == AUDIO_FORMAT_UNKNOWN) { format = PA_SAMPLE_FLOAT32LE; - blog(LOG_INFO, "Sample format %s not supported by OBS," - "using %s instead for recording", - pa_sample_format_to_string(i->sample_spec.format), - pa_sample_format_to_string(format)); + blog(LOG_INFO, + "Sample format %s not supported by OBS," + "using %s instead for recording", + pa_sample_format_to_string(i->sample_spec.format), + pa_sample_format_to_string(format)); } uint8_t channels = i->sample_spec.channels; if (pulse_channels_to_obs_speakers(channels) == SPEAKERS_UNKNOWN) { channels = 2; - blog(LOG_INFO, "%c channels not supported by OBS," - "using %c instead for recording", - i->sample_spec.channels, - channels); + blog(LOG_INFO, + "%c channels not supported by OBS," + "using %c instead for recording", + i->sample_spec.channels, channels); } - data->format = format; + data->format = format; data->samples_per_sec = i->sample_spec.rate; - data->channels = channels; + data->channels = channels; skip: pulse_signal(0); @@ -313,24 +327,25 @@ skip: */ static int_fast32_t pulse_start_recording(struct pulse_data *data) { - if (pulse_get_server_info(pulse_server_info, (void *) data) < 0) { + if (pulse_get_server_info(pulse_server_info, (void *)data) < 0) { blog(LOG_ERROR, "Unable to get server info !"); return -1; } if (pulse_get_source_info(pulse_source_info, data->device, - (void *) data) < 0) { + (void *)data) < 0) { blog(LOG_ERROR, "Unable to get source info !"); return -1; } if (data->format == PA_SAMPLE_INVALID) { - blog(LOG_ERROR, "An error occurred while getting the source info!"); + blog(LOG_ERROR, + "An error occurred while getting the source info!"); return -1; } pa_sample_spec spec; - spec.format = data->format; - spec.rate = data->samples_per_sec; + spec.format = data->format; + spec.rate = data->samples_per_sec; spec.channels = data->channels; if (!pa_sample_spec_valid(&spec)) { @@ -344,7 +359,7 @@ static int_fast32_t pulse_start_recording(struct pulse_data *data) pa_channel_map channel_map = pulse_channel_map(data->speakers); data->stream = pulse_stream_new(obs_source_get_name(data->source), - &spec, &channel_map); + &spec, &channel_map); if (!data->stream) { blog(LOG_ERROR, "Unable to create stream"); return -1; @@ -352,21 +367,21 @@ static int_fast32_t pulse_start_recording(struct pulse_data *data) pulse_lock(); pa_stream_set_read_callback(data->stream, pulse_stream_read, - (void *) data); + (void *)data); pulse_unlock(); pa_buffer_attr attr; - attr.fragsize = pa_usec_to_bytes(25000, &spec); - attr.maxlength = (uint32_t) -1; - attr.minreq = (uint32_t) -1; - attr.prebuf = (uint32_t) -1; - attr.tlength = (uint32_t) -1; + attr.fragsize = pa_usec_to_bytes(25000, &spec); + attr.maxlength = (uint32_t)-1; + attr.minreq = (uint32_t)-1; + attr.prebuf = (uint32_t)-1; + attr.tlength = (uint32_t)-1; pa_stream_flags_t flags = PA_STREAM_ADJUST_LATENCY; pulse_lock(); int_fast32_t ret = pa_stream_connect_record(data->stream, data->device, - &attr, flags); + &attr, flags); pulse_unlock(); if (ret < 0) { pulse_stop_recording(data); @@ -392,8 +407,9 @@ static void pulse_stop_recording(struct pulse_data *data) } blog(LOG_INFO, "Stopped recording from '%s'", data->device); - blog(LOG_INFO, "Got %"PRIuFAST32" packets with %"PRIuFAST64" frames", - data->packets, data->frames); + blog(LOG_INFO, + "Got %" PRIuFAST32 " packets with %" PRIuFAST64 " frames", + data->packets, data->frames); data->first_ts = 0; data->packets = 0; @@ -404,14 +420,14 @@ static void pulse_stop_recording(struct pulse_data *data) * input info callback */ static void pulse_input_info(pa_context *c, const pa_source_info *i, int eol, - void *userdata) + void *userdata) { UNUSED_PARAMETER(c); if (eol != 0 || i->monitor_of_sink != PA_INVALID_INDEX) goto skip; - obs_property_list_add_string((obs_property_t*) userdata, - i->description, i->name); + obs_property_list_add_string((obs_property_t *)userdata, i->description, + i->name); skip: pulse_signal(0); @@ -421,14 +437,14 @@ skip: * output info callback */ static void pulse_output_info(pa_context *c, const pa_sink_info *i, int eol, - void *userdata) + void *userdata) { UNUSED_PARAMETER(c); if (eol != 0 || i->monitor_source == PA_INVALID_INDEX) goto skip; - obs_property_list_add_string((obs_property_t*) userdata, - i->description, i->monitor_source_name); + obs_property_list_add_string((obs_property_t *)userdata, i->description, + i->monitor_source_name); skip: pulse_signal(0); @@ -440,22 +456,22 @@ skip: static obs_properties_t *pulse_properties(bool input) { obs_properties_t *props = obs_properties_create(); - obs_property_t *devices = obs_properties_add_list(props, "device_id", - obs_module_text("Device"), OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_STRING); + obs_property_t *devices = obs_properties_add_list( + props, "device_id", obs_module_text("Device"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); pulse_init(); if (input) - pulse_get_source_info_list(pulse_input_info, (void *) devices); + pulse_get_source_info_list(pulse_input_info, (void *)devices); else - pulse_get_sink_info_list(pulse_output_info, (void *) devices); + pulse_get_sink_info_list(pulse_output_info, (void *)devices); pulse_unref(); size_t count = obs_property_list_item_count(devices); if (count > 0) - obs_property_list_insert_string(devices, 0, - obs_module_text("Default"), "default"); + obs_property_list_insert_string( + devices, 0, obs_module_text("Default"), "default"); return props; } @@ -544,12 +560,13 @@ static void pulse_update(void *vptr, obs_data_t *settings) /** * Create the plugin object */ -static void *pulse_create(obs_data_t *settings, obs_source_t *source, bool input) +static void *pulse_create(obs_data_t *settings, obs_source_t *source, + bool input) { struct pulse_data *data = bzalloc(sizeof(struct pulse_data)); - data->input = input; - data->source = source; + data->input = input; + data->source = source; pulse_init(); pulse_update(data, settings); @@ -568,28 +585,26 @@ static void *pulse_output_create(obs_data_t *settings, obs_source_t *source) } struct obs_source_info pulse_input_capture = { - .id = "pulse_input_capture", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_AUDIO | - OBS_SOURCE_DO_NOT_DUPLICATE, - .get_name = pulse_input_getname, - .create = pulse_input_create, - .destroy = pulse_destroy, - .update = pulse_update, - .get_defaults = pulse_defaults, - .get_properties = pulse_input_properties + .id = "pulse_input_capture", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_AUDIO | OBS_SOURCE_DO_NOT_DUPLICATE, + .get_name = pulse_input_getname, + .create = pulse_input_create, + .destroy = pulse_destroy, + .update = pulse_update, + .get_defaults = pulse_defaults, + .get_properties = pulse_input_properties, }; struct obs_source_info pulse_output_capture = { - .id = "pulse_output_capture", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_AUDIO | - OBS_SOURCE_DO_NOT_DUPLICATE | - OBS_SOURCE_DO_NOT_SELF_MONITOR, - .get_name = pulse_output_getname, - .create = pulse_output_create, - .destroy = pulse_destroy, - .update = pulse_update, - .get_defaults = pulse_defaults, - .get_properties = pulse_output_properties + .id = "pulse_output_capture", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_AUDIO | OBS_SOURCE_DO_NOT_DUPLICATE | + OBS_SOURCE_DO_NOT_SELF_MONITOR, + .get_name = pulse_output_getname, + .create = pulse_output_create, + .destroy = pulse_destroy, + .update = pulse_update, + .get_defaults = pulse_defaults, + .get_properties = pulse_output_properties, }; diff --git a/plugins/linux-pulseaudio/pulse-wrapper.c b/plugins/linux-pulseaudio/pulse-wrapper.c index 77ae41a..bb65148 100644 --- a/plugins/linux-pulseaudio/pulse-wrapper.c +++ b/plugins/linux-pulseaudio/pulse-wrapper.c @@ -70,7 +70,7 @@ static void pulse_init_context() pa_threaded_mainloop_get_api(pulse_mainloop), "OBS", p); pa_context_set_state_callback(pulse_context, - pulse_context_state_changed, NULL); + pulse_context_state_changed, NULL); pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL); pa_proplist_free(p); @@ -163,15 +163,15 @@ void pulse_accept() pa_threaded_mainloop_accept(pulse_mainloop); } -int_fast32_t pulse_get_source_info_list(pa_source_info_cb_t cb, void* userdata) +int_fast32_t pulse_get_source_info_list(pa_source_info_cb_t cb, void *userdata) { if (pulse_context_ready() < 0) return -1; pulse_lock(); - pa_operation *op = pa_context_get_source_info_list( - pulse_context, cb, userdata); + pa_operation *op = + pa_context_get_source_info_list(pulse_context, cb, userdata); if (!op) { pulse_unlock(); return -1; @@ -192,8 +192,8 @@ int_fast32_t pulse_get_sink_info_list(pa_sink_info_cb_t cb, void *userdata) pulse_lock(); - pa_operation *op = pa_context_get_sink_info_list( - pulse_context, cb, userdata); + pa_operation *op = + pa_context_get_sink_info_list(pulse_context, cb, userdata); if (!op) { pulse_unlock(); return -1; @@ -208,7 +208,7 @@ int_fast32_t pulse_get_sink_info_list(pa_sink_info_cb_t cb, void *userdata) } int_fast32_t pulse_get_source_info(pa_source_info_cb_t cb, const char *name, - void *userdata) + void *userdata) { if (pulse_context_ready() < 0) return -1; @@ -230,15 +230,15 @@ int_fast32_t pulse_get_source_info(pa_source_info_cb_t cb, const char *name, return 0; } -int_fast32_t pulse_get_server_info(pa_server_info_cb_t cb, void* userdata) +int_fast32_t pulse_get_server_info(pa_server_info_cb_t cb, void *userdata) { if (pulse_context_ready() < 0) return -1; pulse_lock(); - pa_operation *op = pa_context_get_server_info( - pulse_context, cb, userdata); + pa_operation *op = + pa_context_get_server_info(pulse_context, cb, userdata); if (!op) { pulse_unlock(); return -1; @@ -251,8 +251,8 @@ int_fast32_t pulse_get_server_info(pa_server_info_cb_t cb, void* userdata) return 0; } -pa_stream* pulse_stream_new(const char* name, const pa_sample_spec* ss, - const pa_channel_map* map) +pa_stream *pulse_stream_new(const char *name, const pa_sample_spec *ss, + const pa_channel_map *map) { if (pulse_context_ready() < 0) return NULL; @@ -260,11 +260,10 @@ pa_stream* pulse_stream_new(const char* name, const pa_sample_spec* ss, pulse_lock(); pa_proplist *p = pulse_properties(); - pa_stream *s = pa_stream_new_with_proplist( - pulse_context, name, ss, map, p); + pa_stream *s = + pa_stream_new_with_proplist(pulse_context, name, ss, map, p); pa_proplist_free(p); pulse_unlock(); return s; } - diff --git a/plugins/linux-pulseaudio/pulse-wrapper.h b/plugins/linux-pulseaudio/pulse-wrapper.h index 557b6fe..afd738e 100644 --- a/plugins/linux-pulseaudio/pulse-wrapper.h +++ b/plugins/linux-pulseaudio/pulse-wrapper.h @@ -124,7 +124,7 @@ int_fast32_t pulse_get_sink_info_list(pa_sink_info_cb_t cb, void *userdata); * @warning call without active locks */ int_fast32_t pulse_get_source_info(pa_source_info_cb_t cb, const char *name, - void *userdata); + void *userdata); /** * Request server information @@ -148,4 +148,4 @@ int_fast32_t pulse_get_server_info(pa_server_info_cb_t cb, void *userdata); * @warning call without active locks */ pa_stream *pulse_stream_new(const char *name, const pa_sample_spec *ss, - const pa_channel_map *map); + const pa_channel_map *map); diff --git a/plugins/linux-v4l2/data/locale/ar-SA.ini b/plugins/linux-v4l2/data/locale/ar-SA.ini index 034bfe3..7a341c1 100644 --- a/plugins/linux-v4l2/data/locale/ar-SA.ini +++ b/plugins/linux-v4l2/data/locale/ar-SA.ini @@ -1,5 +1,6 @@ V4L2Input="جهاز التقاط الفيديو (V4L2)" Device="الجهاز" +Input="الوارد" VideoFormat="تنسيق الفيديو" VideoStandard="معيار الفيديو" DVTiming="توقيت DV" diff --git a/plugins/linux-v4l2/data/locale/ca-ES.ini b/plugins/linux-v4l2/data/locale/ca-ES.ini index 4a01274..eaffe09 100644 --- a/plugins/linux-v4l2/data/locale/ca-ES.ini +++ b/plugins/linux-v4l2/data/locale/ca-ES.ini @@ -9,6 +9,7 @@ FrameRate="Fotogrames per segon" LeaveUnchanged="No ho canviïs" UseBuffering="Usa memòria intermèdia" ColorRange="Gamma de colors" +ColorRange.Default="Per defecte" ColorRange.Partial="Parcial" ColorRange.Full="Complet" diff --git a/plugins/linux-v4l2/data/locale/cs-CZ.ini b/plugins/linux-v4l2/data/locale/cs-CZ.ini index 56488ab..3b97886 100644 --- a/plugins/linux-v4l2/data/locale/cs-CZ.ini +++ b/plugins/linux-v4l2/data/locale/cs-CZ.ini @@ -9,6 +9,7 @@ FrameRate="Snímkovací frekvence" LeaveUnchanged="Ponechat nezměněné" UseBuffering="Použít vyrovnávací paměť" ColorRange="Rozsah barev" +ColorRange.Default="Výchozí" ColorRange.Partial="Částečný" ColorRange.Full="Plný" diff --git a/plugins/linux-v4l2/data/locale/da-DK.ini b/plugins/linux-v4l2/data/locale/da-DK.ini index 75755b6..2651c47 100644 --- a/plugins/linux-v4l2/data/locale/da-DK.ini +++ b/plugins/linux-v4l2/data/locale/da-DK.ini @@ -9,6 +9,7 @@ FrameRate="Billedhastighed" LeaveUnchanged="Behold uændret" UseBuffering="Benyt buffering" ColorRange="Farveområde" +ColorRange.Default="Standard" ColorRange.Partial="Delvist" ColorRange.Full="Fuldt" diff --git a/plugins/linux-v4l2/data/locale/de-DE.ini b/plugins/linux-v4l2/data/locale/de-DE.ini index f2f6fc2..85f253a 100644 --- a/plugins/linux-v4l2/data/locale/de-DE.ini +++ b/plugins/linux-v4l2/data/locale/de-DE.ini @@ -3,12 +3,13 @@ Device="Gerät" Input="Eingabe" VideoFormat="Videoformat" VideoStandard="Videostandard" -DVTiming="DV-Timing" +DVTiming="DV‐Timing" Resolution="Auflösung" FrameRate="Bildrate" LeaveUnchanged="Unverändert lassen" UseBuffering="Puffern benutzen" ColorRange="Farbbereich" +ColorRange.Default="Standard" ColorRange.Partial="Begrenzt" ColorRange.Full="Voll" diff --git a/plugins/linux-v4l2/data/locale/en-US.ini b/plugins/linux-v4l2/data/locale/en-US.ini index 7a001c2..9852261 100644 --- a/plugins/linux-v4l2/data/locale/en-US.ini +++ b/plugins/linux-v4l2/data/locale/en-US.ini @@ -9,5 +9,6 @@ FrameRate="Frame Rate" LeaveUnchanged="Leave Unchanged" UseBuffering="Use Buffering" ColorRange="Color Range" +ColorRange.Default="Default" ColorRange.Partial="Partial" ColorRange.Full="Full" diff --git a/plugins/linux-v4l2/data/locale/es-ES.ini b/plugins/linux-v4l2/data/locale/es-ES.ini index 38dbadc..48c995a 100644 --- a/plugins/linux-v4l2/data/locale/es-ES.ini +++ b/plugins/linux-v4l2/data/locale/es-ES.ini @@ -9,6 +9,7 @@ FrameRate="Frecuencia de imágenes" LeaveUnchanged="Dejar sin cambios" UseBuffering="Utilizar el almacenamiento en búfer" ColorRange="Gama de Colores" +ColorRange.Default="Predeterminado" ColorRange.Partial="Parcial" ColorRange.Full="Completo" diff --git a/plugins/linux-v4l2/data/locale/eu-ES.ini b/plugins/linux-v4l2/data/locale/eu-ES.ini index e3f7bd0..1103a0a 100644 --- a/plugins/linux-v4l2/data/locale/eu-ES.ini +++ b/plugins/linux-v4l2/data/locale/eu-ES.ini @@ -9,6 +9,7 @@ FrameRate="Fotograma emaria" LeaveUnchanged="Utzi aldatu gabe" UseBuffering="Erabili bufferreratzea" ColorRange="Kolore tartea" +ColorRange.Default="Lehenetsia" ColorRange.Partial="Partziala" ColorRange.Full="Osoa" diff --git a/plugins/linux-v4l2/data/locale/fi-FI.ini b/plugins/linux-v4l2/data/locale/fi-FI.ini index 14795ed..8690330 100644 --- a/plugins/linux-v4l2/data/locale/fi-FI.ini +++ b/plugins/linux-v4l2/data/locale/fi-FI.ini @@ -9,6 +9,7 @@ FrameRate="Kuvanopeus" LeaveUnchanged="Jätä ennalleen" UseBuffering="Käytä puskurointia" ColorRange="Värialue" +ColorRange.Default="Oletus" ColorRange.Partial="Osittainen" ColorRange.Full="Täysi" diff --git a/plugins/linux-v4l2/data/locale/fr-FR.ini b/plugins/linux-v4l2/data/locale/fr-FR.ini index 367e885..e11f90f 100644 --- a/plugins/linux-v4l2/data/locale/fr-FR.ini +++ b/plugins/linux-v4l2/data/locale/fr-FR.ini @@ -9,6 +9,7 @@ FrameRate="Images par seconde" LeaveUnchanged="Annuler les modifications" UseBuffering="Utiliser le tampon mémoire" ColorRange="Gamme de couleurs" +ColorRange.Default="Par défaut" ColorRange.Partial="Partielle" ColorRange.Full="Complète" diff --git a/plugins/linux-v4l2/data/locale/gl-ES.ini b/plugins/linux-v4l2/data/locale/gl-ES.ini index db8340e..3243afc 100644 --- a/plugins/linux-v4l2/data/locale/gl-ES.ini +++ b/plugins/linux-v4l2/data/locale/gl-ES.ini @@ -3,9 +3,13 @@ Device="Dispositivo" Input="Entrada" VideoFormat="Formato de vídeo" VideoStandard="Vídeo estándar" -DVTiming="Axuste DV" +DVTiming="Sincronización do vídeo dixital (DV)" Resolution="Resolución" -FrameRate="Velocidade de fotogramas" +FrameRate="Taxa de fotogramas" LeaveUnchanged="Deixar sen cambios" -UseBuffering="Utilizar o almacenamento no búfer" +UseBuffering="Utilizar o almacenamento na memoria temporal" +ColorRange="Gama de cores" +ColorRange.Default="Predeterminado" +ColorRange.Partial="Parcial" +ColorRange.Full="Total" diff --git a/plugins/linux-v4l2/data/locale/hu-HU.ini b/plugins/linux-v4l2/data/locale/hu-HU.ini index 85b6e79..d438ddc 100644 --- a/plugins/linux-v4l2/data/locale/hu-HU.ini +++ b/plugins/linux-v4l2/data/locale/hu-HU.ini @@ -9,6 +9,7 @@ FrameRate="Képkockasebesség" LeaveUnchanged="Változatlanul hagyni" UseBuffering="Pufferelés használata" ColorRange="Színtartomány" +ColorRange.Default="Alapértelmezett" ColorRange.Partial="Részleges" ColorRange.Full="Teljes" diff --git a/plugins/linux-v4l2/data/locale/it-IT.ini b/plugins/linux-v4l2/data/locale/it-IT.ini index eac5c7a..6313b4b 100644 --- a/plugins/linux-v4l2/data/locale/it-IT.ini +++ b/plugins/linux-v4l2/data/locale/it-IT.ini @@ -9,6 +9,7 @@ FrameRate="Velocità dei fotogrammi" LeaveUnchanged="Lascia invariato" UseBuffering="Utilizza il buffering" ColorRange="Gamma di colori" +ColorRange.Default="Predefinito" ColorRange.Partial="Parziale" ColorRange.Full="Intero" diff --git a/plugins/linux-v4l2/data/locale/ja-JP.ini b/plugins/linux-v4l2/data/locale/ja-JP.ini index 215675f..ae4b7a0 100644 --- a/plugins/linux-v4l2/data/locale/ja-JP.ini +++ b/plugins/linux-v4l2/data/locale/ja-JP.ini @@ -9,6 +9,7 @@ FrameRate="フレームレート" LeaveUnchanged="変更せずに戻る" UseBuffering="バッファリングを使用する" ColorRange="色範囲" +ColorRange.Default="既定" ColorRange.Partial="一部" ColorRange.Full="全部" diff --git a/plugins/linux-v4l2/data/locale/ka-GE.ini b/plugins/linux-v4l2/data/locale/ka-GE.ini index 1b2e750..d5eb512 100644 --- a/plugins/linux-v4l2/data/locale/ka-GE.ini +++ b/plugins/linux-v4l2/data/locale/ka-GE.ini @@ -1,6 +1,6 @@ -V4L2Input="ვიდეოს გადამღები მოწყობილობა (V4L2)" +V4L2Input="ვიდეოჩამწერი მოწყობილობა (V4L2)" Device="მოწყობილობა" -Input="შემავალი" +Input="შეტანა" VideoFormat="ვიდეოს ფორმატი" VideoStandard="ვიდეოს სტანდარტი" DVTiming="ციფრული ვიდეოს სინქრონიზაცია" @@ -9,6 +9,7 @@ FrameRate="კადრის სიხშირე" LeaveUnchanged="უცვლელად დატოვება" UseBuffering="ბუფერიზაციის გამოყენება" ColorRange="ფერთა გამა" +ColorRange.Default="ნაგულისხმევი" ColorRange.Partial="ნაწილობრივი" ColorRange.Full="სრული" diff --git a/plugins/linux-v4l2/data/locale/ko-KR.ini b/plugins/linux-v4l2/data/locale/ko-KR.ini index 0e55a4d..cf0613a 100644 --- a/plugins/linux-v4l2/data/locale/ko-KR.ini +++ b/plugins/linux-v4l2/data/locale/ko-KR.ini @@ -9,6 +9,7 @@ FrameRate="프레임 레이트" LeaveUnchanged="저장하지 않고 두기" UseBuffering="버퍼링 사용" ColorRange="색상 범위" +ColorRange.Default="기본값" ColorRange.Partial="부분" ColorRange.Full="전체" diff --git a/plugins/linux-v4l2/data/locale/nl-NL.ini b/plugins/linux-v4l2/data/locale/nl-NL.ini index 356e52c..cfa522a 100644 --- a/plugins/linux-v4l2/data/locale/nl-NL.ini +++ b/plugins/linux-v4l2/data/locale/nl-NL.ini @@ -9,6 +9,7 @@ FrameRate="Frame Rate" LeaveUnchanged="Ongewijzigd Laten" UseBuffering="Buffering Gebruiken" ColorRange="Kleurbereik" +ColorRange.Default="Standaard" ColorRange.Partial="Gedeeltelijk" ColorRange.Full="Volledig" diff --git a/plugins/linux-v4l2/data/locale/pl-PL.ini b/plugins/linux-v4l2/data/locale/pl-PL.ini index 34986ff..8b28366 100644 --- a/plugins/linux-v4l2/data/locale/pl-PL.ini +++ b/plugins/linux-v4l2/data/locale/pl-PL.ini @@ -9,6 +9,7 @@ FrameRate="Klatki na sekundę" LeaveUnchanged="Pozostaw bez zmian" UseBuffering="Użyj buforowania" ColorRange="Zakres kolorów" +ColorRange.Default="Domyślny" ColorRange.Partial="Częściowy" ColorRange.Full="Pełny" diff --git a/plugins/linux-v4l2/data/locale/pt-BR.ini b/plugins/linux-v4l2/data/locale/pt-BR.ini index 34fe477..3aef27c 100644 --- a/plugins/linux-v4l2/data/locale/pt-BR.ini +++ b/plugins/linux-v4l2/data/locale/pt-BR.ini @@ -9,6 +9,7 @@ FrameRate="Taxa de quadros" LeaveUnchanged="Deixar inalterado" UseBuffering="Utilizar Buffering" ColorRange="Intervalo de Cor" +ColorRange.Default="Padrão" ColorRange.Partial="Parcial" ColorRange.Full="Completo" diff --git a/plugins/linux-v4l2/data/locale/ro-RO.ini b/plugins/linux-v4l2/data/locale/ro-RO.ini index 78fba1f..1fb32f6 100644 --- a/plugins/linux-v4l2/data/locale/ro-RO.ini +++ b/plugins/linux-v4l2/data/locale/ro-RO.ini @@ -8,4 +8,8 @@ Resolution="Rezoluție" FrameRate="Frecvență de cadre" LeaveUnchanged="Lasă neschimbat" UseBuffering="Folosește zona tampon" +ColorRange="Gamă de culori" +ColorRange.Default="Implicită" +ColorRange.Partial="Parțială" +ColorRange.Full="Completă" diff --git a/plugins/linux-v4l2/data/locale/ru-RU.ini b/plugins/linux-v4l2/data/locale/ru-RU.ini index 3daf760..49f16b4 100644 --- a/plugins/linux-v4l2/data/locale/ru-RU.ini +++ b/plugins/linux-v4l2/data/locale/ru-RU.ini @@ -9,6 +9,7 @@ FrameRate="Частота кадров" LeaveUnchanged="Оставить без изменений" UseBuffering="Использовать буферизацию" ColorRange="Цветовой диапазон" +ColorRange.Default="По умолчанию" ColorRange.Partial="Частичный" ColorRange.Full="Полный" diff --git a/plugins/linux-v4l2/data/locale/sv-SE.ini b/plugins/linux-v4l2/data/locale/sv-SE.ini index 4d96e71..b8e3ec7 100644 --- a/plugins/linux-v4l2/data/locale/sv-SE.ini +++ b/plugins/linux-v4l2/data/locale/sv-SE.ini @@ -9,6 +9,7 @@ FrameRate="Bildhastighet" LeaveUnchanged="Lämna oförändrat" UseBuffering="Använd buffer" ColorRange="Färgintervall" +ColorRange.Default="Standard" ColorRange.Partial="Delvis" ColorRange.Full="Full" diff --git a/plugins/linux-v4l2/data/locale/tr-TR.ini b/plugins/linux-v4l2/data/locale/tr-TR.ini index ad36b52..c263a85 100644 --- a/plugins/linux-v4l2/data/locale/tr-TR.ini +++ b/plugins/linux-v4l2/data/locale/tr-TR.ini @@ -9,6 +9,7 @@ FrameRate="Kare Hızı" LeaveUnchanged="Değişmeden Bırak" UseBuffering="Arabelleğe Almayı Kullan" ColorRange="Renk Aralığı" +ColorRange.Default="Varsayılan" ColorRange.Partial="Kısmi" ColorRange.Full="Tam" diff --git a/plugins/linux-v4l2/data/locale/uk-UA.ini b/plugins/linux-v4l2/data/locale/uk-UA.ini index 2e4614e..28d44a4 100644 --- a/plugins/linux-v4l2/data/locale/uk-UA.ini +++ b/plugins/linux-v4l2/data/locale/uk-UA.ini @@ -9,6 +9,7 @@ FrameRate="Частота кадрів" LeaveUnchanged="Залишити без змін" UseBuffering="Увімкнути буферизацію" ColorRange="Колірний діапазон" +ColorRange.Default="За замовчанням" ColorRange.Partial="Частковий" ColorRange.Full="Повний" diff --git a/plugins/linux-v4l2/data/locale/zh-CN.ini b/plugins/linux-v4l2/data/locale/zh-CN.ini index 68c0c1f..6129a60 100644 --- a/plugins/linux-v4l2/data/locale/zh-CN.ini +++ b/plugins/linux-v4l2/data/locale/zh-CN.ini @@ -9,6 +9,7 @@ FrameRate="帧率" LeaveUnchanged="保持不变" UseBuffering="使用缓冲" ColorRange="颜色范围" +ColorRange.Default="默认" ColorRange.Partial="部分" ColorRange.Full="全部" diff --git a/plugins/linux-v4l2/data/locale/zh-TW.ini b/plugins/linux-v4l2/data/locale/zh-TW.ini index 5a00fd5..e04dae2 100644 --- a/plugins/linux-v4l2/data/locale/zh-TW.ini +++ b/plugins/linux-v4l2/data/locale/zh-TW.ini @@ -9,6 +9,7 @@ FrameRate="影格率" LeaveUnchanged="不改變並離開" UseBuffering="使用緩衝" ColorRange="顏色範圍" +ColorRange.Default="預設" ColorRange.Partial="部分" ColorRange.Full="完整" diff --git a/plugins/linux-v4l2/v4l2-helpers.c b/plugins/linux-v4l2/v4l2-helpers.c index 97ec3aa..ff57f0e 100644 --- a/plugins/linux-v4l2/v4l2-helpers.c +++ b/plugins/linux-v4l2/v4l2-helpers.c @@ -29,7 +29,7 @@ int_fast32_t v4l2_start_capture(int_fast32_t dev, struct v4l2_buffer_data *buf) struct v4l2_buffer enq; memset(&enq, 0, sizeof(enq)); - enq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + enq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; enq.memory = V4L2_MEMORY_MMAP; for (enq.index = 0; enq.index < buf->count; ++enq.index) { @@ -67,8 +67,8 @@ int_fast32_t v4l2_create_mmap(int_fast32_t dev, struct v4l2_buffer_data *buf) struct v4l2_buffer map; memset(&req, 0, sizeof(req)); - req.count = 4; - req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req.count = 4; + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; if (v4l2_ioctl(dev, VIDIOC_REQBUFS, &req) < 0) { @@ -82,10 +82,10 @@ int_fast32_t v4l2_create_mmap(int_fast32_t dev, struct v4l2_buffer_data *buf) } buf->count = req.count; - buf->info = bzalloc(req.count * sizeof(struct v4l2_mmap_info)); + buf->info = bzalloc(req.count * sizeof(struct v4l2_mmap_info)); memset(&map, 0, sizeof(map)); - map.type = req.type; + map.type = req.type; map.memory = req.memory; for (map.index = 0; map.index < req.count; ++map.index) { @@ -95,9 +95,9 @@ int_fast32_t v4l2_create_mmap(int_fast32_t dev, struct v4l2_buffer_data *buf) } buf->info[map.index].length = map.length; - buf->info[map.index].start = v4l2_mmap(NULL, map.length, - PROT_READ | PROT_WRITE, MAP_SHARED, - dev, map.m.offset); + buf->info[map.index].start = + v4l2_mmap(NULL, map.length, PROT_READ | PROT_WRITE, + MAP_SHARED, dev, map.m.offset); if (buf->info[map.index].start == MAP_FAILED) { blog(LOG_ERROR, "mmap for buffer failed"); @@ -110,7 +110,7 @@ int_fast32_t v4l2_create_mmap(int_fast32_t dev, struct v4l2_buffer_data *buf) int_fast32_t v4l2_destroy_mmap(struct v4l2_buffer_data *buf) { - for(uint_fast32_t i = 0; i < buf->count; ++i) { + for (uint_fast32_t i = 0; i < buf->count; ++i) { if (buf->info[i].start != MAP_FAILED && buf->info[i].start != 0) v4l2_munmap(buf->info[i].start, buf->info[i].length); } @@ -128,9 +128,8 @@ int_fast32_t v4l2_set_input(int_fast32_t dev, int *input) if (!dev || !input) return -1; - return (*input == -1) - ? v4l2_ioctl(dev, VIDIOC_G_INPUT, input) - : v4l2_ioctl(dev, VIDIOC_S_INPUT, input); + return (*input == -1) ? v4l2_ioctl(dev, VIDIOC_G_INPUT, input) + : v4l2_ioctl(dev, VIDIOC_S_INPUT, input); } int_fast32_t v4l2_get_input_caps(int_fast32_t dev, int input, uint32_t *caps) @@ -155,7 +154,7 @@ int_fast32_t v4l2_get_input_caps(int_fast32_t dev, int input, uint32_t *caps) } int_fast32_t v4l2_set_format(int_fast32_t dev, int *resolution, - int *pixelformat, int *bytesperline) + int *pixelformat, int *bytesperline) { bool set = false; int width, height; @@ -172,7 +171,7 @@ int_fast32_t v4l2_set_format(int_fast32_t dev, int *resolution, if (*resolution != -1) { v4l2_unpack_tuple(&width, &height, *resolution); - fmt.fmt.pix.width = width; + fmt.fmt.pix.width = width; fmt.fmt.pix.height = height; set = true; } @@ -185,8 +184,8 @@ int_fast32_t v4l2_set_format(int_fast32_t dev, int *resolution, if (set && (v4l2_ioctl(dev, VIDIOC_S_FMT, &fmt) < 0)) return -1; - *resolution = v4l2_pack_tuple(fmt.fmt.pix.width, fmt.fmt.pix.height); - *pixelformat = fmt.fmt.pix.pixelformat; + *resolution = v4l2_pack_tuple(fmt.fmt.pix.width, fmt.fmt.pix.height); + *pixelformat = fmt.fmt.pix.pixelformat; *bytesperline = fmt.fmt.pix.bytesperline; return 0; } @@ -208,7 +207,7 @@ int_fast32_t v4l2_set_framerate(int_fast32_t dev, int *framerate) if (*framerate != -1) { v4l2_unpack_tuple(&num, &denom, *framerate); - par.parm.capture.timeperframe.numerator = num; + par.parm.capture.timeperframe.numerator = num; par.parm.capture.timeperframe.denominator = denom; set = true; } @@ -217,7 +216,7 @@ int_fast32_t v4l2_set_framerate(int_fast32_t dev, int *framerate) return -1; *framerate = v4l2_pack_tuple(par.parm.capture.timeperframe.numerator, - par.parm.capture.timeperframe.denominator); + par.parm.capture.timeperframe.denominator); return 0; } @@ -238,7 +237,7 @@ int_fast32_t v4l2_set_standard(int_fast32_t dev, int *standard) } int_fast32_t v4l2_enum_dv_timing(int_fast32_t dev, struct v4l2_dv_timings *dvt, - int index) + int index) { #if !defined(VIDIOC_ENUM_DV_TIMINGS) || !defined(V4L2_IN_CAP_DV_TIMINGS) UNUSED_PARAMETER(dev); @@ -251,7 +250,7 @@ int_fast32_t v4l2_enum_dv_timing(int_fast32_t dev, struct v4l2_dv_timings *dvt, struct v4l2_enum_dv_timings iter; memset(&iter, 0, sizeof(iter)); - iter.index = index; + iter.index = index; if (v4l2_ioctl(dev, VIDIOC_ENUM_DV_TIMINGS, &iter) < 0) return -1; diff --git a/plugins/linux-v4l2/v4l2-helpers.h b/plugins/linux-v4l2/v4l2-helpers.h index e25d0bb..19c7226 100644 --- a/plugins/linux-v4l2/v4l2-helpers.h +++ b/plugins/linux-v4l2/v4l2-helpers.h @@ -57,19 +57,30 @@ struct v4l2_buffer_data { static inline enum video_format v4l2_to_obs_video_format(uint_fast32_t format) { switch (format) { - case V4L2_PIX_FMT_YVYU: return VIDEO_FORMAT_YVYU; - case V4L2_PIX_FMT_YUYV: return VIDEO_FORMAT_YUY2; - case V4L2_PIX_FMT_UYVY: return VIDEO_FORMAT_UYVY; - case V4L2_PIX_FMT_NV12: return VIDEO_FORMAT_NV12; - case V4L2_PIX_FMT_YUV420: return VIDEO_FORMAT_I420; - case V4L2_PIX_FMT_YVU420: return VIDEO_FORMAT_I420; + case V4L2_PIX_FMT_YVYU: + return VIDEO_FORMAT_YVYU; + case V4L2_PIX_FMT_YUYV: + return VIDEO_FORMAT_YUY2; + case V4L2_PIX_FMT_UYVY: + return VIDEO_FORMAT_UYVY; + case V4L2_PIX_FMT_NV12: + return VIDEO_FORMAT_NV12; + case V4L2_PIX_FMT_YUV420: + return VIDEO_FORMAT_I420; + case V4L2_PIX_FMT_YVU420: + return VIDEO_FORMAT_I420; #ifdef V4L2_PIX_FMT_XBGR32 - case V4L2_PIX_FMT_XBGR32: return VIDEO_FORMAT_BGRX; + case V4L2_PIX_FMT_XBGR32: + return VIDEO_FORMAT_BGRX; #endif #ifdef V4L2_PIX_FMT_ABGR32 - case V4L2_PIX_FMT_ABGR32: return VIDEO_FORMAT_BGRA; + case V4L2_PIX_FMT_ABGR32: + return VIDEO_FORMAT_BGRA; #endif - default: return VIDEO_FORMAT_NONE; + case V4L2_PIX_FMT_BGR24: + return VIDEO_FORMAT_BGR3; + default: + return VIDEO_FORMAT_NONE; } } @@ -80,48 +91,26 @@ static inline enum video_format v4l2_to_obs_video_format(uint_fast32_t format) * and the height in the low word. * The array is terminated with a zero. */ -static const int v4l2_framesizes[] = -{ +static const int v4l2_framesizes[] = { /* 4:3 */ - 160<<16 | 120, - 320<<16 | 240, - 480<<16 | 320, - 640<<16 | 480, - 800<<16 | 600, - 1024<<16 | 768, - 1280<<16 | 960, - 1440<<16 | 1050, - 1440<<16 | 1080, - 1600<<16 | 1200, + 160 << 16 | 120, 320 << 16 | 240, 480 << 16 | 320, 640 << 16 | 480, + 800 << 16 | 600, 1024 << 16 | 768, 1280 << 16 | 960, 1440 << 16 | 1050, + 1440 << 16 | 1080, 1600 << 16 | 1200, /* 16:9 */ - 640<<16 | 360, - 960<<16 | 540, - 1280<<16 | 720, - 1600<<16 | 900, - 1920<<16 | 1080, - 1920<<16 | 1200, - 2560<<16 | 1440, - 3840<<16 | 2160, + 640 << 16 | 360, 960 << 16 | 540, 1280 << 16 | 720, 1600 << 16 | 900, + 1920 << 16 | 1080, 1920 << 16 | 1200, 2560 << 16 | 1440, + 3840 << 16 | 2160, /* 21:9 */ - 2560<<16 | 1080, - 3440<<16 | 1440, - 5120<<16 | 2160, + 2560 << 16 | 1080, 3440 << 16 | 1440, 5120 << 16 | 2160, /* tv */ - 432<<16 | 520, - 480<<16 | 320, - 480<<16 | 530, - 486<<16 | 440, - 576<<16 | 310, - 576<<16 | 520, - 576<<16 | 570, - 720<<16 | 576, - 1024<<16 | 576, + 432 << 16 | 520, 480 << 16 | 320, 480 << 16 | 530, 486 << 16 | 440, + 576 << 16 | 310, 576 << 16 | 520, 576 << 16 | 570, 720 << 16 | 576, + 1024 << 16 | 576, - 0 -}; + 0}; /** * Fixed framerates for devices that don't support enumerating discrete values. @@ -130,19 +119,16 @@ static const int v4l2_framesizes[] = * word and the denominator in the low word. * The array is terminated with a zero. */ -static const int v4l2_framerates[] = -{ - 1<<16 | 60, - 1<<16 | 50, - 1<<16 | 30, - 1<<16 | 25, - 1<<16 | 20, - 1<<16 | 15, - 1<<16 | 10, - 1<<16 | 5, +static const int v4l2_framerates[] = {1 << 16 | 60, + 1 << 16 | 50, + 1 << 16 | 30, + 1 << 16 | 25, + 1 << 16 | 20, + 1 << 16 | 15, + 1 << 16 | 10, + 1 << 16 | 5, - 0 -}; + 0}; /** * Pack two integer values into one @@ -256,7 +242,7 @@ int_fast32_t v4l2_get_input_caps(int_fast32_t dev, int input, uint32_t *caps); * @return negative on failure */ int_fast32_t v4l2_set_format(int_fast32_t dev, int *resolution, - int *pixelformat, int *bytesperline); + int *pixelformat, int *bytesperline); /** * Set the framerate on the device. @@ -292,7 +278,7 @@ int_fast32_t v4l2_set_standard(int_fast32_t dev, int *standard); * @return negative on failure */ int_fast32_t v4l2_enum_dv_timing(int_fast32_t dev, struct v4l2_dv_timings *dvt, - int index); + int index); /** * Set a dv timing on the device * diff --git a/plugins/linux-v4l2/v4l2-input.c b/plugins/linux-v4l2/v4l2-input.c index d3803c1..2329846 100644 --- a/plugins/linux-v4l2/v4l2-input.c +++ b/plugins/linux-v4l2/v4l2-input.c @@ -50,15 +50,13 @@ along with this program. If not, see . #define V4L2_DATA(voidptr) struct v4l2_data *data = voidptr; #define timeval2ns(tv) \ - (((uint64_t) tv.tv_sec * 1000000000) + ((uint64_t) tv.tv_usec * 1000)) + (((uint64_t)tv.tv_sec * 1000000000) + ((uint64_t)tv.tv_usec * 1000)) -#define V4L2_FOURCC_STR(code) \ - (char[5]) { \ - (code >> 24) & 0xFF, \ - (code >> 16) & 0xFF, \ - (code >> 8) & 0xFF, \ - code & 0xFF, \ - 0 \ +#define V4L2_FOURCC_STR(code) \ + (char[5]) \ + { \ + (code >> 24) & 0xFF, (code >> 16) & 0xFF, (code >> 8) & 0xFF, \ + code & 0xFF, 0 \ } #define blog(level, msg, ...) blog(level, "v4l2-input: " msg, ##__VA_ARGS__) @@ -105,7 +103,8 @@ static void v4l2_terminate(struct v4l2_data *data); * pointers for the individual planes. */ static void v4l2_prep_obs_frame(struct v4l2_data *data, - struct obs_source_frame *frame, size_t *plane_offsets) + struct obs_source_frame *frame, + size_t *plane_offsets) { memset(frame, 0, sizeof(struct obs_source_frame)); memset(plane_offsets, 0, sizeof(size_t) * MAX_AV_PLANES); @@ -114,10 +113,10 @@ static void v4l2_prep_obs_frame(struct v4l2_data *data, frame->height = data->height; frame->format = v4l2_to_obs_video_format(data->pixfmt); video_format_get_parameters(VIDEO_CS_DEFAULT, data->color_range, - frame->color_matrix, frame->color_range_min, - frame->color_range_max); + frame->color_matrix, frame->color_range_min, + frame->color_range_max); - switch(data->pixfmt) { + switch (data->pixfmt) { case V4L2_PIX_FMT_NV12: frame->linesize[0] = data->linesize; frame->linesize[1] = data->linesize / 2; @@ -162,7 +161,7 @@ static void *v4l2_thread(void *vptr) if (v4l2_start_capture(data->dev, &data->buffers) < 0) goto exit; - frames = 0; + frames = 0; first_ts = 0; v4l2_prep_obs_frame(data, &out, plane_offsets); @@ -198,7 +197,7 @@ static void *v4l2_thread(void *vptr) first_ts = out.timestamp; out.timestamp -= first_ts; - start = (uint8_t *) data->buffers.info[buf.index].start; + start = (uint8_t *)data->buffers.info[buf.index].start; for (uint_fast32_t i = 0; i < MAX_AV_PLANES; ++i) out.data[i] = start + plane_offsets[i]; obs_source_output_video(data->source, &out); @@ -211,14 +210,14 @@ static void *v4l2_thread(void *vptr) frames++; } - blog(LOG_INFO, "Stopped capture after %"PRIu64" frames", frames); + blog(LOG_INFO, "Stopped capture after %" PRIu64 " frames", frames); exit: v4l2_stop_capture(data->dev); return NULL; } -static const char* v4l2_getname(void *unused) +static const char *v4l2_getname(void *unused) { UNUSED_PARAMETER(unused); return obs_module_text("V4L2Input"); @@ -232,7 +231,7 @@ static void v4l2_defaults(obs_data_t *settings) obs_data_set_default_int(settings, "dv_timing", -1); obs_data_set_default_int(settings, "resolution", -1); obs_data_set_default_int(settings, "framerate", -1); - obs_data_set_default_int(settings, "color_range", VIDEO_RANGE_PARTIAL); + obs_data_set_default_int(settings, "color_range", VIDEO_RANGE_DEFAULT); obs_data_set_default_bool(settings, "buffering", true); } @@ -246,13 +245,13 @@ static void v4l2_defaults(obs_data_t *settings) * @param enable enable/disable all properties */ static void v4l2_props_set_enabled(obs_properties_t *props, - obs_property_t *ignore, bool enable) + obs_property_t *ignore, bool enable) { if (!props) return; for (obs_property_t *prop = obs_properties_first(props); prop != NULL; - obs_property_next(&prop)) { + obs_property_next(&prop)) { if (prop == ignore) continue; @@ -281,7 +280,7 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) return; cur_device_found = false; - cur_device_name = obs_data_get_string(settings, "device_id"); + cur_device_name = obs_data_get_string(settings, "device_id"); obs_property_list_clear(prop); @@ -320,8 +319,8 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) #else /* ... since Linux 3.3 */ caps = (video_cap.capabilities & V4L2_CAP_DEVICE_CAPS) - ? video_cap.device_caps - : video_cap.capabilities; + ? video_cap.device_caps + : video_cap.capabilities; #endif if (!(caps & V4L2_CAP_VIDEO_CAPTURE)) { @@ -334,11 +333,11 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) /* make sure device names are unique */ char unique_device_name[68]; sprintf(unique_device_name, "%s (%s)", video_cap.card, - video_cap.bus_info); + video_cap.bus_info); obs_property_list_add_string(prop, unique_device_name, - device.array); + device.array); blog(LOG_INFO, "Found device '%s' at %s", video_cap.card, - device.array); + device.array); /* check if this is the currently used device */ if (cur_device_name && !strcmp(cur_device_name, device.array)) @@ -349,8 +348,8 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) /* add currently selected device if not present, but disable it ... */ if (!cur_device_found && cur_device_name && strlen(cur_device_name)) { - cur_device_index = obs_property_list_add_string(prop, - cur_device_name, cur_device_name); + cur_device_index = obs_property_list_add_string( + prop, cur_device_name, cur_device_name); obs_property_list_item_disable(prop, cur_device_index, true); } @@ -369,9 +368,9 @@ static void v4l2_input_list(int_fast32_t dev, obs_property_t *prop) obs_property_list_clear(prop); while (v4l2_ioctl(dev, VIDIOC_ENUMINPUT, &in) == 0) { - obs_property_list_add_int(prop, (char *) in.name, in.index); + obs_property_list_add_int(prop, (char *)in.name, in.index); blog(LOG_INFO, "Found input '%s' (Index %d)", in.name, - in.index); + in.index); in.index++; } } @@ -390,14 +389,14 @@ static void v4l2_format_list(int dev, obs_property_t *prop) obs_property_list_clear(prop); while (v4l2_ioctl(dev, VIDIOC_ENUM_FMT, &fmt) == 0) { - dstr_copy(&buffer, (char *) fmt.description); + dstr_copy(&buffer, (char *)fmt.description); if (fmt.flags & V4L2_FMT_FLAG_EMULATED) dstr_cat(&buffer, " (Emulated)"); - if (v4l2_to_obs_video_format(fmt.pixelformat) - != VIDEO_FORMAT_NONE) { + if (v4l2_to_obs_video_format(fmt.pixelformat) != + VIDEO_FORMAT_NONE) { obs_property_list_add_int(prop, buffer.array, - fmt.pixelformat); + fmt.pixelformat); blog(LOG_INFO, "Pixelformat: %s (available)", buffer.array); } else { @@ -423,7 +422,7 @@ static void v4l2_standard_list(int dev, obs_property_t *prop) obs_property_list_add_int(prop, obs_module_text("LeaveUnchanged"), -1); while (v4l2_ioctl(dev, VIDIOC_ENUMSTD, &std) == 0) { - obs_property_list_add_int(prop, (char *) std.name, std.id); + obs_property_list_add_int(prop, (char *)std.name, std.id); std.index++; } } @@ -444,18 +443,17 @@ static void v4l2_dv_timing_list(int dev, obs_property_t *prop) while (v4l2_enum_dv_timing(dev, &dvt, index) == 0) { /* i do not pretend to understand, this is from qv4l2 ... */ - double h = (double) dvt.bt.height + dvt.bt.vfrontporch + - dvt.bt.vsync + dvt.bt.vbackporch + - dvt.bt.il_vfrontporch + dvt.bt.il_vsync + - dvt.bt.il_vbackporch; - double w = (double) dvt.bt.width + dvt.bt.hfrontporch + - dvt.bt.hsync + dvt.bt.hbackporch; - double i = (dvt.bt.interlaced) ? 2.0f : 1.0f; - double rate = (double) dvt.bt.pixelclock / (w * (h / i)); + double h = (double)dvt.bt.height + dvt.bt.vfrontporch + + dvt.bt.vsync + dvt.bt.vbackporch + + dvt.bt.il_vfrontporch + dvt.bt.il_vsync + + dvt.bt.il_vbackporch; + double w = (double)dvt.bt.width + dvt.bt.hfrontporch + + dvt.bt.hsync + dvt.bt.hbackporch; + double i = (dvt.bt.interlaced) ? 2.0f : 1.0f; + double rate = (double)dvt.bt.pixelclock / (w * (h / i)); - dstr_printf(&buf, "%ux%u%c %.2f", - dvt.bt.width, dvt.bt.height, - (dvt.bt.interlaced) ? 'i' : 'p', rate); + dstr_printf(&buf, "%ux%u%c %.2f", dvt.bt.width, dvt.bt.height, + (dvt.bt.interlaced) ? 'i' : 'p', rate); obs_property_list_add_int(prop, buf.array, index); @@ -469,7 +467,7 @@ static void v4l2_dv_timing_list(int dev, obs_property_t *prop) * List resolutions for device and format */ static void v4l2_resolution_list(int dev, uint_fast32_t pixelformat, - obs_property_t *prop) + obs_property_t *prop) { struct v4l2_frmsizeenum frmsize; frmsize.pixel_format = pixelformat; @@ -483,20 +481,21 @@ static void v4l2_resolution_list(int dev, uint_fast32_t pixelformat, v4l2_ioctl(dev, VIDIOC_ENUM_FRAMESIZES, &frmsize); - switch(frmsize.type) { + switch (frmsize.type) { case V4L2_FRMSIZE_TYPE_DISCRETE: while (v4l2_ioctl(dev, VIDIOC_ENUM_FRAMESIZES, &frmsize) == 0) { dstr_printf(&buffer, "%dx%d", frmsize.discrete.width, - frmsize.discrete.height); - obs_property_list_add_int(prop, buffer.array, - v4l2_pack_tuple(frmsize.discrete.width, - frmsize.discrete.height)); + frmsize.discrete.height); + obs_property_list_add_int( + prop, buffer.array, + v4l2_pack_tuple(frmsize.discrete.width, + frmsize.discrete.height)); frmsize.index++; } break; default: blog(LOG_INFO, "Stepwise and Continuous framesizes " - "are currently hardcoded"); + "are currently hardcoded"); for (const int *packed = v4l2_framesizes; *packed; ++packed) { int width; @@ -515,7 +514,8 @@ static void v4l2_resolution_list(int dev, uint_fast32_t pixelformat, * List framerates for device and resolution */ static void v4l2_framerate_list(int dev, uint_fast32_t pixelformat, - uint_fast32_t width, uint_fast32_t height, obs_property_t *prop) + uint_fast32_t width, uint_fast32_t height, + obs_property_t *prop) { struct v4l2_frmivalenum frmival; frmival.pixel_format = pixelformat; @@ -531,14 +531,15 @@ static void v4l2_framerate_list(int dev, uint_fast32_t pixelformat, v4l2_ioctl(dev, VIDIOC_ENUM_FRAMEINTERVALS, &frmival); - switch(frmival.type) { + switch (frmival.type) { case V4L2_FRMIVAL_TYPE_DISCRETE: - while (v4l2_ioctl(dev, VIDIOC_ENUM_FRAMEINTERVALS, - &frmival) == 0) { - float fps = (float) frmival.discrete.denominator / - frmival.discrete.numerator; - int pack = v4l2_pack_tuple(frmival.discrete.numerator, - frmival.discrete.denominator); + while (v4l2_ioctl(dev, VIDIOC_ENUM_FRAMEINTERVALS, &frmival) == + 0) { + float fps = (float)frmival.discrete.denominator / + frmival.discrete.numerator; + int pack = + v4l2_pack_tuple(frmival.discrete.numerator, + frmival.discrete.denominator); dstr_printf(&buffer, "%.2f", fps); obs_property_list_add_int(prop, buffer.array, pack); frmival.index++; @@ -546,13 +547,13 @@ static void v4l2_framerate_list(int dev, uint_fast32_t pixelformat, break; default: blog(LOG_INFO, "Stepwise and Continuous framerates " - "are currently hardcoded"); + "are currently hardcoded"); for (const int *packed = v4l2_framerates; *packed; ++packed) { int num; int denom; v4l2_unpack_tuple(&num, &denom, *packed); - float fps = (float) denom / num; + float fps = (float)denom / num; dstr_printf(&buffer, "%.2f", fps); obs_property_list_add_int(prop, buffer.array, *packed); } @@ -566,10 +567,10 @@ static void v4l2_framerate_list(int dev, uint_fast32_t pixelformat, * Device selected callback */ static bool device_selected(obs_properties_t *props, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { int dev = v4l2_open(obs_data_get_string(settings, "device_id"), - O_RDWR | O_NONBLOCK); + O_RDWR | O_NONBLOCK); v4l2_props_set_enabled(props, p, (dev == -1) ? false : true); @@ -589,11 +590,11 @@ static bool device_selected(obs_properties_t *props, obs_property_t *p, * Input selected callback */ static bool input_selected(obs_properties_t *props, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { UNUSED_PARAMETER(p); int dev = v4l2_open(obs_data_get_string(settings, "device_id"), - O_RDWR | O_NONBLOCK); + O_RDWR | O_NONBLOCK); if (dev == -1) return false; @@ -610,35 +611,36 @@ static bool input_selected(obs_properties_t *props, obs_property_t *p, * Format selected callback */ static bool format_selected(obs_properties_t *props, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { UNUSED_PARAMETER(p); int dev = v4l2_open(obs_data_get_string(settings, "device_id"), - O_RDWR | O_NONBLOCK); + O_RDWR | O_NONBLOCK); if (dev == -1) return false; - int input = (int) obs_data_get_int(settings, "input"); + int input = (int)obs_data_get_int(settings, "input"); uint32_t caps = 0; if (v4l2_get_input_caps(dev, input, &caps) < 0) return false; caps &= V4L2_IN_CAP_STD | V4L2_IN_CAP_DV_TIMINGS; obs_property_t *resolution = obs_properties_get(props, "resolution"); - obs_property_t *framerate = obs_properties_get(props, "framerate"); - obs_property_t *standard = obs_properties_get(props, "standard"); - obs_property_t *dv_timing = obs_properties_get(props, "dv_timing"); + obs_property_t *framerate = obs_properties_get(props, "framerate"); + obs_property_t *standard = obs_properties_get(props, "standard"); + obs_property_t *dv_timing = obs_properties_get(props, "dv_timing"); obs_property_set_visible(resolution, (!caps) ? true : false); - obs_property_set_visible(framerate, (!caps) ? true : false); + obs_property_set_visible(framerate, (!caps) ? true : false); obs_property_set_visible(standard, - (caps & V4L2_IN_CAP_STD) ? true : false); - obs_property_set_visible(dv_timing, - (caps & V4L2_IN_CAP_DV_TIMINGS) ? true : false); + (caps & V4L2_IN_CAP_STD) ? true : false); + obs_property_set_visible( + dv_timing, (caps & V4L2_IN_CAP_DV_TIMINGS) ? true : false); if (!caps) { - v4l2_resolution_list(dev, obs_data_get_int( - settings, "pixelformat"), resolution); + v4l2_resolution_list(dev, + obs_data_get_int(settings, "pixelformat"), + resolution); } if (caps & V4L2_IN_CAP_STD) v4l2_standard_list(dev, standard); @@ -661,20 +663,20 @@ static bool format_selected(obs_properties_t *props, obs_property_t *p, * Resolution selected callback */ static bool resolution_selected(obs_properties_t *props, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { UNUSED_PARAMETER(p); int width, height; int dev = v4l2_open(obs_data_get_string(settings, "device_id"), - O_RDWR | O_NONBLOCK); + O_RDWR | O_NONBLOCK); if (dev == -1) return false; obs_property_t *prop = obs_properties_get(props, "framerate"); - v4l2_unpack_tuple(&width, &height, obs_data_get_int(settings, - "resolution")); + v4l2_unpack_tuple(&width, &height, + obs_data_get_int(settings, "resolution")); v4l2_framerate_list(dev, obs_data_get_int(settings, "pixelformat"), - width, height, prop); + width, height, prop); v4l2_close(dev); obs_property_modified(prop, settings); @@ -735,44 +737,51 @@ static obs_properties_t *v4l2_properties(void *vptr) obs_properties_t *props = obs_properties_create(); - obs_property_t *device_list = obs_properties_add_list(props, - "device_id", obs_module_text("Device"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + obs_property_t *device_list = obs_properties_add_list( + props, "device_id", obs_module_text("Device"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); - obs_property_t *input_list = obs_properties_add_list(props, - "input", obs_module_text("Input"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_t *input_list = obs_properties_add_list( + props, "input", obs_module_text("Input"), OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); - obs_property_t *format_list = obs_properties_add_list(props, - "pixelformat", obs_module_text("VideoFormat"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_t *format_list = obs_properties_add_list( + props, "pixelformat", obs_module_text("VideoFormat"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_property_t *standard_list = obs_properties_add_list(props, - "standard", obs_module_text("VideoStandard"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_t *standard_list = obs_properties_add_list( + props, "standard", obs_module_text("VideoStandard"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); obs_property_set_visible(standard_list, false); - obs_property_t *dv_timing_list = obs_properties_add_list(props, - "dv_timing", obs_module_text("DVTiming"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_t *dv_timing_list = obs_properties_add_list( + props, "dv_timing", obs_module_text("DVTiming"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); obs_property_set_visible(dv_timing_list, false); - obs_property_t *resolution_list = obs_properties_add_list(props, - "resolution", obs_module_text("Resolution"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_t *resolution_list = obs_properties_add_list( + props, "resolution", obs_module_text("Resolution"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_properties_add_list(props, - "framerate", obs_module_text("FrameRate"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_properties_add_list(props, "framerate", + obs_module_text("FrameRate"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_property_t *color_range_list = obs_properties_add_list(props, - "color_range", obs_module_text("ColorRange"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_property_list_add_int(color_range_list, obs_module_text("ColorRange.Partial"), VIDEO_RANGE_PARTIAL); - obs_property_list_add_int(color_range_list, obs_module_text("ColorRange.Full"), VIDEO_RANGE_FULL); + obs_property_t *color_range_list = obs_properties_add_list( + props, "color_range", obs_module_text("ColorRange"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(color_range_list, + obs_module_text("ColorRange.Default"), + VIDEO_RANGE_DEFAULT); + obs_property_list_add_int(color_range_list, + obs_module_text("ColorRange.Partial"), + VIDEO_RANGE_PARTIAL); + obs_property_list_add_int(color_range_list, + obs_module_text("ColorRange.Full"), + VIDEO_RANGE_FULL); - obs_properties_add_bool(props, - "buffering", obs_module_text("UseBuffering")); + obs_properties_add_bool(props, "buffering", + obs_module_text("UseBuffering")); obs_data_t *settings = obs_source_get_settings(data->source); v4l2_device_list(device_list, settings); @@ -782,7 +791,7 @@ static obs_properties_t *v4l2_properties(void *vptr) obs_property_set_modified_callback(input_list, input_selected); obs_property_set_modified_callback(format_list, format_selected); obs_property_set_modified_callback(resolution_list, - resolution_selected); + resolution_selected); return props; } @@ -868,7 +877,7 @@ static void v4l2_init(struct v4l2_data *data) goto fail; } data->resolution = -1; - data->framerate = -1; + data->framerate = -1; } /* set dv timing if supported */ if (input_caps & V4L2_IN_CAP_DV_TIMINGS) { @@ -877,12 +886,12 @@ static void v4l2_init(struct v4l2_data *data) goto fail; } data->resolution = -1; - data->framerate = -1; + data->framerate = -1; } /* set pixel format and resolution */ if (v4l2_set_format(data->dev, &data->resolution, &data->pixfmt, - &data->linesize) < 0) { + &data->linesize) < 0) { blog(LOG_ERROR, "Unable to set format"); goto fail; } @@ -901,7 +910,7 @@ static void v4l2_init(struct v4l2_data *data) goto fail; } v4l2_unpack_tuple(&fps_num, &fps_denom, data->framerate); - blog(LOG_INFO, "Framerate: %.2f fps", (float) fps_denom / fps_num); + blog(LOG_INFO, "Framerate: %.2f fps", (float)fps_denom / fps_num); /* map buffers */ if (v4l2_create_mmap(data->dev, &data->buffers) < 0) { @@ -922,10 +931,10 @@ fail: /** Update source flags depending on the settings */ static void v4l2_update_source_flags(struct v4l2_data *data, - obs_data_t *settings) + obs_data_t *settings) { - obs_source_set_async_unbuffered(data->source, - !obs_data_get_bool(settings, "buffering")); + obs_source_set_async_unbuffered( + data->source, !obs_data_get_bool(settings, "buffering")); } /** @@ -945,14 +954,14 @@ static void v4l2_update(void *vptr, obs_data_t *settings) if (data->device_id) bfree(data->device_id); - data->device_id = bstrdup(obs_data_get_string(settings, "device_id")); - data->input = obs_data_get_int(settings, "input"); - data->pixfmt = obs_data_get_int(settings, "pixelformat"); - data->standard = obs_data_get_int(settings, "standard"); - data->dv_timing = obs_data_get_int(settings, "dv_timing"); + data->device_id = bstrdup(obs_data_get_string(settings, "device_id")); + data->input = obs_data_get_int(settings, "input"); + data->pixfmt = obs_data_get_int(settings, "pixelformat"); + data->standard = obs_data_get_int(settings, "standard"); + data->dv_timing = obs_data_get_int(settings, "dv_timing"); data->resolution = obs_data_get_int(settings, "resolution"); - data->framerate = obs_data_get_int(settings, "framerate"); - data->color_range = obs_data_get_int(settings, "color_range"); + data->framerate = obs_data_get_int(settings, "framerate"); + data->color_range = obs_data_get_int(settings, "color_range"); v4l2_update_source_flags(data, settings); @@ -987,14 +996,13 @@ static void *v4l2_create(obs_data_t *settings, obs_source_t *source) } struct obs_source_info v4l2_input = { - .id = "v4l2_input", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_ASYNC_VIDEO | - OBS_SOURCE_DO_NOT_DUPLICATE, - .get_name = v4l2_getname, - .create = v4l2_create, - .destroy = v4l2_destroy, - .update = v4l2_update, - .get_defaults = v4l2_defaults, - .get_properties = v4l2_properties + .id = "v4l2_input", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_DO_NOT_DUPLICATE, + .get_name = v4l2_getname, + .create = v4l2_create, + .destroy = v4l2_destroy, + .update = v4l2_update, + .get_defaults = v4l2_defaults, + .get_properties = v4l2_properties, }; diff --git a/plugins/linux-v4l2/v4l2-udev.c b/plugins/linux-v4l2/v4l2-udev.c index 44a32d5..efe92b0 100644 --- a/plugins/linux-v4l2/v4l2-udev.c +++ b/plugins/linux-v4l2/v4l2-udev.c @@ -30,14 +30,12 @@ enum udev_action { UDEV_ACTION_UNKNOWN }; -static const char *udev_signals[] = { - "void device_added(string device)", - "void device_removed(string device)", - NULL -}; +static const char *udev_signals[] = {"void device_added(string device)", + "void device_removed(string device)", + NULL}; /* global data */ -static uint_fast32_t udev_refs = 0; +static uint_fast32_t udev_refs = 0; static pthread_mutex_t udev_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_t udev_thread; @@ -77,7 +75,7 @@ static inline void udev_signal_event(struct udev_device *dev) pthread_mutex_lock(&udev_mutex); - node = udev_device_get_devnode(dev); + node = udev_device_get_devnode(dev); action = udev_action_to_enum(udev_device_get_action(dev)); calldata_init(&data); @@ -86,12 +84,12 @@ static inline void udev_signal_event(struct udev_device *dev) switch (action) { case UDEV_ACTION_ADDED: - signal_handler_signal(udev_signalhandler, - "device_added", &data); + signal_handler_signal(udev_signalhandler, "device_added", + &data); break; case UDEV_ACTION_REMOVED: - signal_handler_signal(udev_signalhandler, - "device_removed", &data); + signal_handler_signal(udev_signalhandler, "device_removed", + &data); break; default: break; @@ -118,9 +116,9 @@ static void *udev_event_thread(void *vptr) /* set up udev monitoring */ udev = udev_new(); - mon = udev_monitor_new_from_netlink(udev, "udev"); - udev_monitor_filter_add_match_subsystem_devtype( - mon, "video4linux", NULL); + mon = udev_monitor_new_from_netlink(udev, "udev"); + udev_monitor_filter_add_match_subsystem_devtype(mon, "video4linux", + NULL); if (udev_monitor_enable_receiving(mon) < 0) return NULL; @@ -130,7 +128,7 @@ static void *udev_event_thread(void *vptr) while (os_event_try(udev_event) == EAGAIN) { FD_ZERO(&fds); FD_SET(fd, &fds); - tv.tv_sec = 1; + tv.tv_sec = 1; tv.tv_usec = 0; if (select(fd + 1, &fds, NULL, NULL, &tv) <= 0) @@ -160,14 +158,13 @@ void v4l2_init_udev(void) if (os_event_init(&udev_event, OS_EVENT_TYPE_MANUAL) != 0) goto fail; if (pthread_create(&udev_thread, NULL, udev_event_thread, - NULL) != 0) + NULL) != 0) goto fail; udev_signalhandler = signal_handler_create(); if (!udev_signalhandler) goto fail; signal_handler_add_array(udev_signalhandler, udev_signals); - } udev_refs++; diff --git a/plugins/mac-avcapture/av-capture.mm b/plugins/mac-avcapture/av-capture.mm index 446ba91..1718bb5 100644 --- a/plugins/mac-avcapture/av-capture.mm +++ b/plugins/mac-avcapture/av-capture.mm @@ -26,37 +26,29 @@ using namespace std; namespace std { -template <> -struct default_delete { - void operator()(obs_data_t *data) - { - obs_data_release(data); - } +template<> struct default_delete { + void operator()(obs_data_t *data) { obs_data_release(data); } }; -template <> -struct default_delete { - void operator()(obs_data_item_t *item) - { - obs_data_item_release(&item); - } +template<> struct default_delete { + void operator()(obs_data_item_t *item) { obs_data_item_release(&item); } }; } -#define TEXT_AVCAPTURE obs_module_text("AVCapture") -#define TEXT_DEVICE obs_module_text("Device") +#define TEXT_AVCAPTURE obs_module_text("AVCapture") +#define TEXT_DEVICE obs_module_text("Device") #define TEXT_USE_PRESET obs_module_text("UsePreset") -#define TEXT_PRESET obs_module_text("Preset") +#define TEXT_PRESET obs_module_text("Preset") #define TEXT_RESOLUTION obs_module_text("Resolution") #define TEXT_FRAME_RATE obs_module_text("FrameRate") -#define TEXT_MATCH_OBS obs_module_text("MatchOBS") +#define TEXT_MATCH_OBS obs_module_text("MatchOBS") #define TEXT_INPUT_FORMAT obs_module_text("InputFormat") #define TEXT_COLOR_SPACE obs_module_text("ColorSpace") #define TEXT_VIDEO_RANGE obs_module_text("VideoRange") #define TEXT_RANGE_PARTIAL obs_module_text("VideoRange.Partial") #define TEXT_RANGE_FULL obs_module_text("VideoRange.Full") -#define TEXT_AUTO obs_module_text("Auto") +#define TEXT_AUTO obs_module_text("Auto") #define TEXT_COLOR_UNKNOWN_NAME "Unknown" #define TEXT_RANGE_UNKNOWN_NAME "Unknown" @@ -67,53 +59,52 @@ static const int VIDEO_RANGE_AUTO = -1; #define MILLI_TIMESCALE 1000 #define MICRO_TIMESCALE (MILLI_TIMESCALE * 1000) -#define NANO_TIMESCALE (MICRO_TIMESCALE * 1000) +#define NANO_TIMESCALE (MICRO_TIMESCALE * 1000) -#define AV_FOURCC_STR(code) \ - (char[5]) { \ - static_cast((code >> 24) & 0xFF), \ - static_cast((code >> 16) & 0xFF), \ - static_cast((code >> 8) & 0xFF), \ - static_cast( code & 0xFF), \ - 0 \ +#define AV_FOURCC_STR(code) \ + (char[5]) \ + { \ + static_cast((code >> 24) & 0xFF), \ + static_cast((code >> 16) & 0xFF), \ + static_cast((code >> 8) & 0xFF), \ + static_cast(code & 0xFF), 0 \ } struct av_capture; -#define AVLOG(level, format, ...) \ - blog(level, "%s: " format, \ - obs_source_get_name(capture->source), ##__VA_ARGS__) +#define AVLOG(level, format, ...) \ + blog(level, "%s: " format, obs_source_get_name(capture->source), \ + ##__VA_ARGS__) -@interface OBSAVCaptureDelegate : - NSObject -{ +@interface OBSAVCaptureDelegate + : NSObject { @public struct av_capture *capture; } - (void)captureOutput:(AVCaptureOutput *)out - didDropSampleBuffer:(CMSampleBufferRef)sampleBuffer - fromConnection:(AVCaptureConnection *)connection; + didDropSampleBuffer:(CMSampleBufferRef)sampleBuffer + fromConnection:(AVCaptureConnection *)connection; - (void)captureOutput:(AVCaptureOutput *)captureOutput - didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer - fromConnection:(AVCaptureConnection *)connection; + didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer + fromConnection:(AVCaptureConnection *)connection; @end namespace { -static auto remove_observer = [](id observer) -{ +static auto remove_observer = [](id observer) { [[NSNotificationCenter defaultCenter] removeObserver:observer]; }; -struct observer_handle : - unique_ptr::type, decltype(remove_observer)> { - - using base = unique_ptr::type, - decltype(remove_observer)>; +struct observer_handle + : unique_ptr::type, decltype(remove_observer)> { + + using base = + unique_ptr::type, decltype(remove_observer)>; explicit observer_handle(id observer = nullptr) : base(observer, remove_observer) - {} + { + } }; struct av_video_info { @@ -134,10 +125,10 @@ struct av_capture { left_right::left_right video_info; AVCaptureVideoDataOutput *out; - AVCaptureDevice *device; - AVCaptureDeviceInput *device_input; - AVCaptureSession *session; - + AVCaptureDevice *device; + AVCaptureDeviceInput *device_input; + AVCaptureSession *session; + NSString *uid; observer_handle connect_observer; observer_handle disconnect_observer; @@ -146,7 +137,7 @@ struct av_capture { video_format video_format; bool use_preset = false; - int requested_colorspace = COLOR_SPACE_AUTO; + int requested_colorspace = COLOR_SPACE_AUTO; int requested_video_range = VIDEO_RANGE_AUTO; obs_source_t *source; @@ -165,13 +156,16 @@ static AVCaptureDevice *get_device(obs_data_t *settings) return [AVCaptureDevice deviceWithUniqueID:uid]; } -template -static void clamp(T& store, U val, T low = numeric_limits::min(), - T high = numeric_limits::max()) +template +static void clamp(T &store, U val, T low = numeric_limits::min(), + T high = numeric_limits::max()) { - store = static_cast(val) < static_cast(low) ? low : - (static_cast(val) > static_cast(high) ? - high : static_cast(val)); + store = static_cast(val) < static_cast(low) + ? low + : (static_cast(val) > + static_cast(high) + ? high + : static_cast(val)); } static bool get_resolution(obs_data_t *settings, CMVideoDimensions &dims) @@ -220,9 +214,9 @@ struct config_helper { AVCaptureDevice *dev_ = nullptr; bool dims_valid : 1; - bool fr_valid : 1; - bool fps_valid : 1; - bool if_valid : 1; + bool fr_valid : 1; + bool fps_valid : 1; + bool if_valid : 1; CMVideoDimensions dims_{}; @@ -231,25 +225,21 @@ struct config_helper { FourCharCode input_format_ = INPUT_FORMAT_AUTO; - explicit config_helper(obs_data_t *settings) - : settings(settings) + explicit config_helper(obs_data_t *settings) : settings(settings) { dev_ = get_device(settings); dims_valid = get_resolution(settings, dims_); - fr_valid = obs_data_get_frames_per_second(settings, - "frame_rate", nullptr, &frame_rate_); - fps_valid = obs_data_get_frames_per_second(settings, - "frame_rate", &fps_, nullptr); + fr_valid = obs_data_get_frames_per_second( + settings, "frame_rate", nullptr, &frame_rate_); + fps_valid = obs_data_get_frames_per_second( + settings, "frame_rate", &fps_, nullptr); if_valid = get_input_format(settings, input_format_); } - AVCaptureDevice *dev() const - { - return dev_; - } + AVCaptureDevice *dev() const { return dev_; } const CMVideoDimensions *dims() const { @@ -287,23 +277,16 @@ struct av_capture_ref { capture = capture_; } - operator av_capture *() - { - return capture; - } + operator av_capture *() { return capture; } - av_capture *operator->() - { - return capture; - } + av_capture *operator->() { return capture; } }; struct properties_param { av_capture *capture = nullptr; OBSWeakSource weak_source; - properties_param(av_capture *capture) - : capture(capture) + properties_param(av_capture *capture) : capture(capture) { if (!capture) return; @@ -311,10 +294,7 @@ struct properties_param { weak_source = OBSGetWeakRef(capture->source); } - av_capture_ref get_ref() - { - return {capture, weak_source}; - } + av_capture_ref get_ref() { return {capture, weak_source}; } }; } @@ -325,7 +305,7 @@ static av_capture_ref get_ref(obs_properties_t *props) if (!param) return {}; - return static_cast(param)->get_ref(); + return static_cast(param)->get_ref(); } static inline video_format format_from_subtype(FourCharCode subtype) @@ -351,8 +331,9 @@ static inline video_format format_from_subtype(FourCharCode subtype) static const char *fourcc_subtype_name(FourCharCode fourcc); -static const char *format_description_subtype_name(CMFormatDescriptionRef desc, - FourCharCode *fourcc_=nullptr) +static const char * +format_description_subtype_name(CMFormatDescriptionRef desc, + FourCharCode *fourcc_ = nullptr) { FourCharCode fourcc = CMFormatDescriptionGetMediaSubType(desc); if (fourcc_) @@ -376,17 +357,28 @@ static const char *fourcc_subtype_name(FourCharCode fourcc) case kCVPixelFormatType_32BGRA: return "BGRA - 32BGRA"; //VIDEO_FORMAT_BGRA; - case kCMVideoCodecType_Animation: return "Apple Animation"; - case kCMVideoCodecType_Cinepak: return "Cinepak"; - case kCMVideoCodecType_JPEG: return "JPEG"; - case kCMVideoCodecType_JPEG_OpenDML: return "MJPEG - JPEG OpenDML"; - case kCMVideoCodecType_SorensonVideo: return "Sorenson Video"; - case kCMVideoCodecType_SorensonVideo3: return "Sorenson Video 3"; - case kCMVideoCodecType_H263: return "H.263"; - case kCMVideoCodecType_H264: return "H.264"; - case kCMVideoCodecType_MPEG4Video: return "MPEG-4"; - case kCMVideoCodecType_MPEG2Video: return "MPEG-2"; - case kCMVideoCodecType_MPEG1Video: return "MPEG-1"; + case kCMVideoCodecType_Animation: + return "Apple Animation"; + case kCMVideoCodecType_Cinepak: + return "Cinepak"; + case kCMVideoCodecType_JPEG: + return "JPEG"; + case kCMVideoCodecType_JPEG_OpenDML: + return "MJPEG - JPEG OpenDML"; + case kCMVideoCodecType_SorensonVideo: + return "Sorenson Video"; + case kCMVideoCodecType_SorensonVideo3: + return "Sorenson Video 3"; + case kCMVideoCodecType_H263: + return "H.263"; + case kCMVideoCodecType_H264: + return "H.264"; + case kCMVideoCodecType_MPEG4Video: + return "MPEG-4"; + case kCMVideoCodecType_MPEG2Video: + return "MPEG-2"; + case kCMVideoCodecType_MPEG1Video: + return "MPEG-1"; case kCMVideoCodecType_DVCNTSC: return "DV NTSC"; @@ -443,39 +435,40 @@ static inline bool is_fullrange_yuv(FourCharCode pixel_format) static inline video_colorspace get_colorspace(CMFormatDescriptionRef desc) { - CFPropertyListRef matrix = CMFormatDescriptionGetExtension(desc, - kCMFormatDescriptionExtension_YCbCrMatrix); + CFPropertyListRef matrix = CMFormatDescriptionGetExtension( + desc, kCMFormatDescriptionExtension_YCbCrMatrix); if (!matrix) return VIDEO_CS_DEFAULT; if (CFStringCompare(static_cast(matrix), - kCVImageBufferYCbCrMatrix_ITU_R_709_2, 0) - == kCFCompareEqualTo) + kCVImageBufferYCbCrMatrix_ITU_R_709_2, + 0) == kCFCompareEqualTo) return VIDEO_CS_709; return VIDEO_CS_601; } static inline bool update_colorspace(av_capture *capture, - obs_source_frame *frame, CMFormatDescriptionRef desc, - bool full_range, av_video_info &vi) + obs_source_frame *frame, + CMFormatDescriptionRef desc, + bool full_range, av_video_info &vi) { auto cs_auto = capture->use_preset || - capture->requested_colorspace == COLOR_SPACE_AUTO; + capture->requested_colorspace == COLOR_SPACE_AUTO; auto vr_auto = capture->use_preset || - capture->requested_video_range == VIDEO_RANGE_AUTO; + capture->requested_video_range == VIDEO_RANGE_AUTO; video_colorspace colorspace = get_colorspace(desc); - video_range_type range = full_range ? - VIDEO_RANGE_FULL : VIDEO_RANGE_PARTIAL; + video_range_type range = full_range ? VIDEO_RANGE_FULL + : VIDEO_RANGE_PARTIAL; bool cs_matches = false; if (cs_auto) { cs_matches = colorspace == vi.colorspace; } else { colorspace = static_cast( - capture->requested_colorspace); + capture->requested_colorspace); cs_matches = colorspace == vi.colorspace; } @@ -484,43 +477,41 @@ static inline bool update_colorspace(av_capture *capture, vr_matches = range == vi.video_range; } else { range = static_cast( - capture->requested_video_range); + capture->requested_video_range); vr_matches = range == vi.video_range; full_range = range == VIDEO_RANGE_FULL; } if (cs_matches && vr_matches) { if (!vi.video_params_valid) - capture->video_info.update([&](av_video_info &vi_) - { - vi_.video_params_valid = - vi.video_params_valid = true; + capture->video_info.update([&](av_video_info &vi_) { + vi_.video_params_valid = vi.video_params_valid = + true; }); return true; } frame->full_range = full_range; - if (!video_format_get_parameters(colorspace, range, - frame->color_matrix, - frame->color_range_min, - frame->color_range_max)) { - AVLOG(LOG_ERROR, "Failed to get colorspace parameters for " - "colorspace %u range %u", colorspace, range); + if (!video_format_get_parameters(colorspace, range, frame->color_matrix, + frame->color_range_min, + frame->color_range_max)) { + AVLOG(LOG_ERROR, + "Failed to get colorspace parameters for " + "colorspace %u range %u", + colorspace, range); if (vi.video_params_valid) - capture->video_info.update([&](av_video_info &vi_) - { - vi_.video_params_valid = - vi.video_params_valid = false; + capture->video_info.update([&](av_video_info &vi_) { + vi_.video_params_valid = vi.video_params_valid = + false; }); return false; } - capture->video_info.update([&](av_video_info &vi_) - { - vi_.colorspace = colorspace; + capture->video_info.update([&](av_video_info &vi_) { + vi_.colorspace = colorspace; vi_.video_range = range; vi_.video_params_valid = vi.video_params_valid = true; }); @@ -528,17 +519,17 @@ static inline bool update_colorspace(av_capture *capture, return true; } -static inline bool update_frame(av_capture *capture, - obs_source_frame *frame, CMSampleBufferRef sample_buffer) +static inline bool update_frame(av_capture *capture, obs_source_frame *frame, + CMSampleBufferRef sample_buffer) { CMFormatDescriptionRef desc = CMSampleBufferGetFormatDescription(sample_buffer); - FourCharCode fourcc = CMFormatDescriptionGetMediaSubType(desc); - video_format format = format_from_subtype(fourcc); + FourCharCode fourcc = CMFormatDescriptionGetMediaSubType(desc); + video_format format = format_from_subtype(fourcc); CMVideoDimensions dims = CMVideoFormatDescriptionGetDimensions(desc); - CVImageBufferRef img = CMSampleBufferGetImageBuffer(sample_buffer); + CVImageBufferRef img = CMSampleBufferGetImageBuffer(sample_buffer); auto vi = capture->video_info.read(); @@ -555,32 +546,32 @@ static inline bool update_frame(av_capture *capture, capture->fourcc = fourcc; AVLOG(LOG_ERROR, "Unhandled fourcc: %s (0x%x) (%zu planes)", - AV_FOURCC_STR(fourcc), fourcc, - CVPixelBufferGetPlaneCount(img)); + AV_FOURCC_STR(fourcc), fourcc, + CVPixelBufferGetPlaneCount(img)); return false; } if (frame->format != format) - AVLOG(LOG_DEBUG, "Switching fourcc: " - "'%s' (0x%x) -> '%s' (0x%x)", - AV_FOURCC_STR(capture->fourcc), capture->fourcc, - AV_FOURCC_STR(fourcc), fourcc); + AVLOG(LOG_DEBUG, + "Switching fourcc: " + "'%s' (0x%x) -> '%s' (0x%x)", + AV_FOURCC_STR(capture->fourcc), capture->fourcc, + AV_FOURCC_STR(fourcc), fourcc); bool was_yuv = format_is_yuv(frame->format); capture->fourcc = fourcc; - frame->format = format; - frame->width = dims.width; - frame->height = dims.height; + frame->format = format; + frame->width = dims.width; + frame->height = dims.height; - if (format_is_yuv(format) && !update_colorspace(capture, frame, desc, - is_fullrange_yuv(fourcc), vi)) { + if (format_is_yuv(format) && + !update_colorspace(capture, frame, desc, is_fullrange_yuv(fourcc), + vi)) { return false; } else if (was_yuv == format_is_yuv(format)) { - capture->video_info.update([&](av_video_info &vi_) - { - vi_.video_params_valid = - vi.video_params_valid = true; + capture->video_info.update([&](av_video_info &vi_) { + vi_.video_params_valid = vi.video_params_valid = true; }); } @@ -588,24 +579,24 @@ static inline bool update_frame(av_capture *capture, if (!CVPixelBufferIsPlanar(img)) { frame->linesize[0] = CVPixelBufferGetBytesPerRow(img); - frame->data[0] = static_cast( - CVPixelBufferGetBaseAddress(img)); + frame->data[0] = static_cast( + CVPixelBufferGetBaseAddress(img)); return true; } size_t count = CVPixelBufferGetPlaneCount(img); for (size_t i = 0; i < count; i++) { frame->linesize[i] = CVPixelBufferGetBytesPerRowOfPlane(img, i); - frame->data[i] = static_cast( - CVPixelBufferGetBaseAddressOfPlane(img, i)); + frame->data[i] = static_cast( + CVPixelBufferGetBaseAddressOfPlane(img, i)); } return true; } @implementation OBSAVCaptureDelegate - (void)captureOutput:(AVCaptureOutput *)out - didDropSampleBuffer:(CMSampleBufferRef)sampleBuffer - fromConnection:(AVCaptureConnection *)connection + didDropSampleBuffer:(CMSampleBufferRef)sampleBuffer + fromConnection:(AVCaptureConnection *)connection { UNUSED_PARAMETER(out); UNUSED_PARAMETER(sampleBuffer); @@ -613,8 +604,8 @@ static inline bool update_frame(av_capture *capture, } - (void)captureOutput:(AVCaptureOutput *)captureOutput - didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer - fromConnection:(AVCaptureConnection *)connection + didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer + fromConnection:(AVCaptureConnection *)connection { UNUSED_PARAMETER(captureOutput); UNUSED_PARAMETER(connection); @@ -627,8 +618,8 @@ static inline bool update_frame(av_capture *capture, CMTime target_pts = CMSampleBufferGetOutputPresentationTimeStamp(sampleBuffer); - CMTime target_pts_nano = CMTimeConvertScale(target_pts, NANO_TIMESCALE, - kCMTimeRoundingMethod_Default); + CMTime target_pts_nano = CMTimeConvertScale( + target_pts, NANO_TIMESCALE, kCMTimeRoundingMethod_Default); frame->timestamp = target_pts_nano.value; if (!update_frame(capture, frame, sampleBuffer)) { @@ -648,12 +639,12 @@ static void av_capture_enable_buffering(av_capture *capture, bool enabled) obs_source_set_async_unbuffered(capture->source, !enabled); } -static const char *av_capture_getname(void*) +static const char *av_capture_getname(void *) { return TEXT_AVCAPTURE; } -static void unlock_device(av_capture *capture, AVCaptureDevice *dev=nullptr) +static void unlock_device(av_capture *capture, AVCaptureDevice *dev = nullptr) { if (!dev) dev = capture->device; @@ -692,7 +683,7 @@ static void remove_device(av_capture *capture) static void av_capture_destroy(void *data) { - auto capture = static_cast(data); + auto capture = static_cast(data); delete capture; } @@ -731,9 +722,8 @@ static bool init_session(av_capture *capture) capture->queue = queue; [capture->session addOutput:capture->out]; - [capture->out - setSampleBufferDelegate:capture->delegate - queue:capture->queue]; + [capture->out setSampleBufferDelegate:capture->delegate + queue:capture->queue]; return true; } @@ -743,11 +733,11 @@ static bool init_format(av_capture *capture, AVCaptureDevice *dev); static bool init_device_input(av_capture *capture, AVCaptureDevice *dev) { NSError *err = nil; - AVCaptureDeviceInput *device_input = [AVCaptureDeviceInput - deviceInputWithDevice:dev error:&err]; + AVCaptureDeviceInput *device_input = + [AVCaptureDeviceInput deviceInputWithDevice:dev error:&err]; if (!device_input) { AVLOG(LOG_ERROR, "Error while initializing device input: %s", - err.localizedFailureReason.UTF8String); + err.localizedFailureReason.UTF8String); return false; } @@ -765,38 +755,38 @@ static bool init_device_input(av_capture *capture, AVCaptureDevice *dev) static uint32_t uint_from_dict(NSDictionary *dict, CFStringRef key) { - return ((NSNumber*)dict[(__bridge NSString*)key]).unsignedIntValue; + return ((NSNumber *)dict[(__bridge NSString *)key]).unsignedIntValue; } static bool init_format(av_capture *capture, AVCaptureDevice *dev) { AVCaptureDeviceFormat *format = dev.activeFormat; - CMMediaType mtype = CMFormatDescriptionGetMediaType( - format.formatDescription); + CMMediaType mtype = + CMFormatDescriptionGetMediaType(format.formatDescription); // TODO: support other media types if (mtype != kCMMediaType_Video && mtype != kCMMediaType_Muxed) { AVLOG(LOG_ERROR, "CMMediaType '%s' is unsupported", - AV_FOURCC_STR(mtype)); + AV_FOURCC_STR(mtype)); return false; } capture->out.videoSettings = nil; FourCharCode subtype = uint_from_dict(capture->out.videoSettings, - kCVPixelBufferPixelFormatTypeKey); + kCVPixelBufferPixelFormatTypeKey); if (format_from_subtype(subtype) != VIDEO_FORMAT_NONE) { AVLOG(LOG_DEBUG, "Using native fourcc '%s'", - AV_FOURCC_STR(subtype)); + AV_FOURCC_STR(subtype)); return true; } AVLOG(LOG_DEBUG, "Using fallback fourcc '%s' ('%s' 0x%08x unsupported)", - AV_FOURCC_STR(kCVPixelFormatType_32BGRA), - AV_FOURCC_STR(subtype), subtype); + AV_FOURCC_STR(kCVPixelFormatType_32BGRA), AV_FOURCC_STR(subtype), + subtype); capture->out.videoSettings = @{ - (__bridge NSString*)kCVPixelBufferPixelFormatTypeKey: - @(kCVPixelFormatType_32BGRA) + (__bridge NSString *) + kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA) }; return true; } @@ -824,7 +814,7 @@ static NSString *select_preset(AVCaptureDevice *dev, NSString *cur_preset) } static bool init_preset(av_capture *capture, AVCaptureDevice *dev, - obs_data_t *settings) + obs_data_t *settings) { clear_capture(capture); @@ -833,19 +823,18 @@ static bool init_preset(av_capture *capture, AVCaptureDevice *dev, NSString *preset = get_string(settings, "preset"); if (![dev supportsAVCaptureSessionPreset:preset]) { AVLOG(LOG_WARNING, "Preset %s not available", - preset_names(preset).UTF8String); + preset_names(preset).UTF8String); preset = select_preset(dev, preset); } if (!preset) { AVLOG(LOG_WARNING, "Could not select a preset, " - "initialization failed"); + "initialization failed"); return false; } capture->session.sessionPreset = preset; - AVLOG(LOG_INFO, "Using preset %s", - preset_names(preset).UTF8String); + AVLOG(LOG_INFO, "Using preset %s", preset_names(preset).UTF8String); return true; } @@ -854,7 +843,7 @@ static bool operator==(const CMVideoDimensions &a, const CMVideoDimensions &b); static CMVideoDimensions get_dimensions(AVCaptureDeviceFormat *format); static AVCaptureDeviceFormat *find_format(AVCaptureDevice *dev, - CMVideoDimensions dims) + CMVideoDimensions dims) { for (AVCaptureDeviceFormat *format in dev.formats) { if (get_dimensions(format) == dims) @@ -880,8 +869,10 @@ static bool lock_device(av_capture *capture, AVCaptureDevice *dev) NSError *err; if (![dev lockForConfiguration:&err]) { - AVLOG(LOG_WARNING, "Could not lock device for configuration: " - "%s", err.localizedDescription.UTF8String); + AVLOG(LOG_WARNING, + "Could not lock device for configuration: " + "%s", + err.localizedDescription.UTF8String); return false; } @@ -889,9 +880,9 @@ static bool lock_device(av_capture *capture, AVCaptureDevice *dev) return true; } -template +template static void find_formats(media_frames_per_second fps, AVCaptureDevice *dev, - const CMVideoDimensions *dims, Func &&f) + const CMVideoDimensions *dims, Func &&f) { auto time = convert(fps); @@ -899,11 +890,10 @@ static void find_formats(media_frames_per_second fps, AVCaptureDevice *dev, if (!(get_dimensions(format) == *dims)) continue; - for (AVFrameRateRange *range in - format.videoSupportedFrameRateRanges) { + for (AVFrameRateRange *range in format + .videoSupportedFrameRateRanges) { if (CMTimeCompare(range.maxFrameDuration, time) >= 0 && - CMTimeCompare(range.minFrameDuration, - time) <= 0) + CMTimeCompare(range.minFrameDuration, time) <= 0) if (f(format)) return; } @@ -926,10 +916,14 @@ static bool color_space_valid(int color_space) static const char *color_space_name(int color_space) { switch (color_space) { - case COLOR_SPACE_AUTO: return "Auto"; - case VIDEO_CS_DEFAULT: return "Default"; - case VIDEO_CS_601: return "CS 601"; - case VIDEO_CS_709: return "CS 709"; + case COLOR_SPACE_AUTO: + return "Auto"; + case VIDEO_CS_DEFAULT: + return "Default"; + case VIDEO_CS_601: + return "CS 601"; + case VIDEO_CS_709: + return "CS 709"; } return "Unknown"; @@ -951,17 +945,21 @@ static bool video_range_valid(int video_range) static const char *video_range_name(int video_range) { switch (video_range) { - case VIDEO_RANGE_AUTO: return "Auto"; - case VIDEO_RANGE_DEFAULT: return "Default"; - case VIDEO_RANGE_PARTIAL: return "Partial"; - case VIDEO_RANGE_FULL: return "Full"; + case VIDEO_RANGE_AUTO: + return "Auto"; + case VIDEO_RANGE_DEFAULT: + return "Default"; + case VIDEO_RANGE_PARTIAL: + return "Partial"; + case VIDEO_RANGE_FULL: + return "Full"; } return "Unknown"; } static bool init_manual(av_capture *capture, AVCaptureDevice *dev, - obs_data_t *settings) + obs_data_t *settings) { clear_capture(capture); @@ -973,14 +971,15 @@ static bool init_manual(av_capture *capture, AVCaptureDevice *dev, bool refresh = false; if (input_format != actual_format) { refresh = obs_data_get_autoselect_int(settings, - "input_format") != actual_format; + "input_format") != + actual_format; obs_data_set_autoselect_int(settings, "input_format", - actual_format); + actual_format); } else { refresh = obs_data_has_autoselect_value(settings, - "input_format"); + "input_format"); obs_data_unset_autoselect_value(settings, - "input_format"); + "input_format"); } if (refresh) @@ -991,7 +990,7 @@ static bool init_manual(av_capture *capture, AVCaptureDevice *dev, obs_data_get_int(settings, "color_space"); if (!color_space_valid(capture->requested_colorspace)) { AVLOG(LOG_WARNING, "Unsupported color space: %d", - capture->requested_colorspace); + capture->requested_colorspace); return false; } @@ -999,7 +998,7 @@ static bool init_manual(av_capture *capture, AVCaptureDevice *dev, obs_data_get_int(settings, "video_range"); if (!video_range_valid(capture->requested_video_range)) { AVLOG(LOG_WARNING, "Unsupported color range: %d", - capture->requested_video_range); + capture->requested_video_range); return false; } @@ -1011,14 +1010,13 @@ static bool init_manual(av_capture *capture, AVCaptureDevice *dev, media_frames_per_second fps{}; if (!obs_data_get_frames_per_second(settings, "frame_rate", &fps, - nullptr)) { + nullptr)) { AVLOG(LOG_WARNING, "Could not load frame rate"); return false; } AVCaptureDeviceFormat *format = nullptr; - find_formats(fps, dev, &dims, [&](AVCaptureDeviceFormat *format_) - { + find_formats(fps, dev, &dims, [&](AVCaptureDeviceFormat *format_) { auto desc = format_.formatDescription; auto fourcc = CMFormatDescriptionGetMediaSubType(desc); if (input_format != INPUT_FORMAT_AUTO && fourcc != input_format) @@ -1030,57 +1028,55 @@ static bool init_manual(av_capture *capture, AVCaptureDevice *dev, }); if (!format) { - AVLOG(LOG_WARNING, "Frame rate is not supported: %g FPS " - "(%u/%u)", - media_frames_per_second_to_fps(fps), - fps.numerator, fps.denominator); + AVLOG(LOG_WARNING, + "Frame rate is not supported: %g FPS " + "(%u/%u)", + media_frames_per_second_to_fps(fps), fps.numerator, + fps.denominator); return false; } if (!lock_device(capture, dev)) return false; - const char *if_name = input_format == INPUT_FORMAT_AUTO ? - "Auto" : fourcc_subtype_name(input_format); + const char *if_name = input_format == INPUT_FORMAT_AUTO + ? "Auto" + : fourcc_subtype_name(input_format); #define IF_AUTO(x) (input_format != INPUT_FORMAT_AUTO ? "" : x) - AVLOG(LOG_INFO, "Capturing '%s' (%s):\n" - " Resolution: %ux%u\n" - " FPS: %g (%" PRIu32 "/%" PRIu32 ")\n" - " Frame interval: %g" NBSP "s\n" - " Input format: %s%s%s (%s)%s\n" - " Requested color space: %s (%d)\n" - " Requested video range: %s (%d)\n" - " Using format: %s", - dev.localizedName.UTF8String, dev.uniqueID.UTF8String, - dims.width, dims.height, - media_frames_per_second_to_fps(fps), - fps.numerator, fps.denominator, - media_frames_per_second_to_frame_interval(fps), - if_name, IF_AUTO(" (actual: "), - IF_AUTO(fourcc_subtype_name(actual_format)), - AV_FOURCC_STR(actual_format), IF_AUTO(")"), - color_space_name(capture->requested_colorspace), - capture->requested_colorspace, - video_range_name(capture->requested_video_range), - capture->requested_video_range, - format.description.UTF8String); + AVLOG(LOG_INFO, + "Capturing '%s' (%s):\n" + " Resolution: %ux%u\n" + " FPS: %g (%" PRIu32 "/%" PRIu32 ")\n" + " Frame interval: %g" NBSP "s\n" + " Input format: %s%s%s (%s)%s\n" + " Requested color space: %s (%d)\n" + " Requested video range: %s (%d)\n" + " Using format: %s", + dev.localizedName.UTF8String, dev.uniqueID.UTF8String, dims.width, + dims.height, media_frames_per_second_to_fps(fps), fps.numerator, + fps.denominator, media_frames_per_second_to_frame_interval(fps), + if_name, IF_AUTO(" (actual: "), + IF_AUTO(fourcc_subtype_name(actual_format)), + AV_FOURCC_STR(actual_format), IF_AUTO(")"), + color_space_name(capture->requested_colorspace), + capture->requested_colorspace, + video_range_name(capture->requested_video_range), + capture->requested_video_range, format.description.UTF8String); #undef IF_AUTO dev.activeFormat = format; dev.activeVideoMinFrameDuration = convert(fps); dev.activeVideoMaxFrameDuration = convert(fps); - capture->video_info.update([&](av_video_info &vi) - { - vi.video_params_valid = false; - }); + capture->video_info.update( + [&](av_video_info &vi) { vi.video_params_valid = false; }); return true; } static void capture_device(av_capture *capture, AVCaptureDevice *dev, - obs_data_t *settings) + obs_data_t *settings) { const char *name = dev.localizedName.UTF8String; obs_data_set_string(settings, "device_name", name); @@ -1108,25 +1104,24 @@ static void capture_device(av_capture *capture, AVCaptureDevice *dev, } static inline void handle_disconnect_capture(av_capture *capture, - AVCaptureDevice *dev) + AVCaptureDevice *dev) { if (![dev.uniqueID isEqualTo:capture->uid]) return; if (!capture->device) { AVLOG(LOG_INFO, "Received disconnect for inactive device '%s'", - capture->uid.UTF8String); + capture->uid.UTF8String); return; } AVLOG(LOG_WARNING, "Device with unique ID '%s' disconnected", - dev.uniqueID.UTF8String); + dev.uniqueID.UTF8String); remove_device(capture); } -static inline void handle_disconnect(av_capture *capture, - AVCaptureDevice *dev) +static inline void handle_disconnect(av_capture *capture, AVCaptureDevice *dev) { if (!dev) return; @@ -1136,25 +1131,28 @@ static inline void handle_disconnect(av_capture *capture, } static inline void handle_connect_capture(av_capture *capture, - AVCaptureDevice *dev, obs_data_t *settings) + AVCaptureDevice *dev, + obs_data_t *settings) { if (![dev.uniqueID isEqualTo:capture->uid]) return; if (capture->device) { AVLOG(LOG_ERROR, "Received connect for in-use device '%s'", - capture->uid.UTF8String); + capture->uid.UTF8String); return; } - AVLOG(LOG_INFO, "Device with unique ID '%s' connected, " - "resuming capture", dev.uniqueID.UTF8String); + AVLOG(LOG_INFO, + "Device with unique ID '%s' connected, " + "resuming capture", + dev.uniqueID.UTF8String); capture_device(capture, dev, settings); } -static inline void handle_connect(av_capture *capture, - AVCaptureDevice *dev, obs_data_t *settings) +static inline void handle_connect(av_capture *capture, AVCaptureDevice *dev, + obs_data_t *settings) { if (!dev) return; @@ -1175,21 +1173,17 @@ static bool av_capture_init(av_capture *capture, obs_data_t *settings) addObserverForName:AVCaptureDeviceWasDisconnectedNotification object:nil queue:[NSOperationQueue mainQueue] - usingBlock:^(NSNotification *note) - { + usingBlock:^(NSNotification *note) { handle_disconnect(capture, note.object); - } - ]); + }]); capture->connect_observer.reset([nc addObserverForName:AVCaptureDeviceWasConnectedNotification object:nil queue:[NSOperationQueue mainQueue] - usingBlock:^(NSNotification *note) - { + usingBlock:^(NSNotification *note) { handle_connect(capture, note.object, settings); - } - ]); + }]); AVCaptureDevice *dev = [AVCaptureDevice deviceWithUniqueID:capture->uid]; @@ -1198,9 +1192,10 @@ static bool av_capture_init(av_capture *capture, obs_data_t *settings) if (capture->uid.length < 1) AVLOG(LOG_INFO, "No device selected"); else - AVLOG(LOG_WARNING, "Could not initialize device " \ - "with unique ID '%s'", - capture->uid.UTF8String); + AVLOG(LOG_WARNING, + "Could not initialize device " + "with unique ID '%s'", + capture->uid.UTF8String); return true; } @@ -1227,7 +1222,7 @@ static void *av_capture_create(obs_data_t *settings, obs_source_t *source) } av_capture_enable_buffering(capture.get(), - obs_data_get_bool(settings, "buffering")); + obs_data_get_bool(settings, "buffering")); return capture.release(); } @@ -1237,12 +1232,9 @@ static NSArray *presets(void) return @[ //AVCaptureSessionPresetiFrame1280x720, //AVCaptureSessionPresetiFrame960x540, - AVCaptureSessionPreset1280x720, - AVCaptureSessionPreset960x540, - AVCaptureSessionPreset640x480, - AVCaptureSessionPreset352x288, - AVCaptureSessionPreset320x240, - AVCaptureSessionPresetHigh, + AVCaptureSessionPreset1280x720, AVCaptureSessionPreset960x540, + AVCaptureSessionPreset640x480, AVCaptureSessionPreset352x288, + AVCaptureSessionPreset320x240, AVCaptureSessionPresetHigh, //AVCaptureSessionPresetMedium, //AVCaptureSessionPresetLow, //AVCaptureSessionPresetPhoto, @@ -1252,15 +1244,15 @@ static NSArray *presets(void) static NSString *preset_names(NSString *preset) { NSDictionary *preset_names = @{ - AVCaptureSessionPresetLow:@"Low", - AVCaptureSessionPresetMedium:@"Medium", - AVCaptureSessionPresetHigh:@"High", - AVCaptureSessionPreset320x240:@"320x240", - AVCaptureSessionPreset352x288:@"352x288", - AVCaptureSessionPreset640x480:@"640x480", - AVCaptureSessionPreset960x540:@"960x540", - AVCaptureSessionPreset1280x720:@"1280x720", - AVCaptureSessionPresetHigh:@"High", + AVCaptureSessionPresetLow: @"Low", + AVCaptureSessionPresetMedium: @"Medium", + AVCaptureSessionPresetHigh: @"High", + AVCaptureSessionPreset320x240: @"320x240", + AVCaptureSessionPreset352x288: @"352x288", + AVCaptureSessionPreset640x480: @"640x480", + AVCaptureSessionPreset960x540: @"960x540", + AVCaptureSessionPreset1280x720: @"1280x720", + AVCaptureSessionPresetHigh: @"High", }; NSString *name = preset_names[preset]; if (name) @@ -1268,31 +1260,30 @@ static NSString *preset_names(NSString *preset) return [NSString stringWithFormat:@"Unknown (%@)", preset]; } - static void av_capture_defaults(obs_data_t *settings) { obs_data_set_default_string(settings, "uid", ""); obs_data_set_default_bool(settings, "use_preset", true); obs_data_set_default_string(settings, "preset", - AVCaptureSessionPreset1280x720.UTF8String); + AVCaptureSessionPreset1280x720.UTF8String); obs_data_set_default_int(settings, "input_format", INPUT_FORMAT_AUTO); obs_data_set_default_int(settings, "color_space", COLOR_SPACE_AUTO); obs_data_set_default_int(settings, "video_range", VIDEO_RANGE_AUTO); } -static bool update_device_list(obs_property_t *list, - NSString *uid, NSString *name, bool disconnected) +static bool update_device_list(obs_property_t *list, NSString *uid, + NSString *name, bool disconnected) { - bool dev_found = false; + bool dev_found = false; bool list_modified = false; size_t size = obs_property_list_item_count(list); for (size_t i = 0; i < size;) { const char *uid_ = obs_property_list_item_string(list, i); - bool found = [uid isEqualToString:@(uid_ ? uid_ : "")]; - bool disabled = obs_property_list_item_disabled(list, i); + bool found = [uid isEqualToString:@(uid_ ? uid_ : "")]; + bool disabled = obs_property_list_item_disabled(list, i); if (!found && !disabled) { i += 1; continue; @@ -1303,7 +1294,7 @@ static bool update_device_list(obs_property_t *list, obs_property_list_item_remove(list, i); continue; } - + if (disabled != disconnected) list_modified = true; @@ -1316,22 +1307,22 @@ static bool update_device_list(obs_property_t *list, return list_modified; size_t idx = obs_property_list_add_string(list, name.UTF8String, - uid.UTF8String); + uid.UTF8String); obs_property_list_item_disable(list, idx, disconnected); return true; } static void fill_presets(AVCaptureDevice *dev, obs_property_t *list, - NSString *current_preset) + NSString *current_preset) { obs_property_list_clear(list); bool preset_found = false; for (NSString *preset in presets()) { bool is_current = [preset isEqualToString:current_preset]; - bool supported = dev && - [dev supportsAVCaptureSessionPreset:preset]; + bool supported = dev && + [dev supportsAVCaptureSessionPreset:preset]; if (is_current) preset_found = true; @@ -1339,23 +1330,23 @@ static void fill_presets(AVCaptureDevice *dev, obs_property_t *list, if (!supported && !is_current) continue; - size_t idx = obs_property_list_add_string(list, - preset_names(preset).UTF8String, - preset.UTF8String); + size_t idx = obs_property_list_add_string( + list, preset_names(preset).UTF8String, + preset.UTF8String); obs_property_list_item_disable(list, idx, !supported); } if (preset_found) return; - size_t idx = obs_property_list_add_string(list, - preset_names(current_preset).UTF8String, - current_preset.UTF8String); + size_t idx = obs_property_list_add_string( + list, preset_names(current_preset).UTF8String, + current_preset.UTF8String); obs_property_list_item_disable(list, idx, true); } -static bool check_preset(AVCaptureDevice *dev, - obs_property_t *list, obs_data_t *settings) +static bool check_preset(AVCaptureDevice *dev, obs_property_t *list, + obs_data_t *settings) { NSString *current_preset = get_string(settings, "preset"); @@ -1368,8 +1359,8 @@ static bool check_preset(AVCaptureDevice *dev, bool presets_changed = false; for (NSString *preset in presets()) { bool is_listed = [listed member:preset] != nil; - bool supported = dev && - [dev supportsAVCaptureSessionPreset:preset]; + bool supported = dev && + [dev supportsAVCaptureSessionPreset:preset]; if (supported == is_listed) continue; @@ -1399,7 +1390,7 @@ static bool autoselect_preset(AVCaptureDevice *dev, obs_data_t *settings) obs_data_get_autoselect_string(settings, "preset"); if (![preset isEqualToString:@(autoselect)]) { obs_data_set_autoselect_string(settings, "preset", - preset.UTF8String); + preset.UTF8String); return true; } } @@ -1436,8 +1427,7 @@ static resolutions_t enumerate_resolutions(AVCaptureDevice *dev) static void sort_resolutions(vector &resolutions) { - auto cmp = [](const CMVideoDimensions &a, const CMVideoDimensions &b) - { + auto cmp = [](const CMVideoDimensions &a, const CMVideoDimensions &b) { return a.width * a.height > b.width * b.height; }; @@ -1446,18 +1436,18 @@ static void sort_resolutions(vector &resolutions) static void data_set_resolution(obs_data_t *data, const CMVideoDimensions &dims) { - obs_data_set_int(data, "width", dims.width); + obs_data_set_int(data, "width", dims.width); obs_data_set_int(data, "height", dims.height); } static void data_set_resolution(const unique_ptr &data, - const CMVideoDimensions &dims) + const CMVideoDimensions &dims) { data_set_resolution(data.get(), dims); } static bool add_resolution_to_list(vector &res, - const CMVideoDimensions &dims) + const CMVideoDimensions &dims) { if (find(begin(res), end(res), dims) != end(res)) return false; @@ -1477,7 +1467,7 @@ static bool operator==(const CMVideoDimensions &a, const CMVideoDimensions &b) } static bool resolution_property_needs_update(obs_property_t *p, - const resolutions_t &resolutions) + const resolutions_t &resolutions) { vector res_found(resolutions.size()); @@ -1498,11 +1488,12 @@ static bool resolution_property_needs_update(obs_property_t *p, } return any_of(begin(res_found), end(res_found), - [](bool b) { return !b; }); + [](bool b) { return !b; }); } static bool update_resolution_property(obs_properties_t *props, - const config_helper &conf, obs_property_t *p=nullptr) + const config_helper &conf, + obs_property_t *p = nullptr) { if (!p) p = obs_properties_get(props, "resolution"); @@ -1546,23 +1537,23 @@ static bool update_resolution_property(obs_properties_t *props, static media_frames_per_second convert(CMTime time_) { media_frames_per_second res{}; - clamp(res.numerator, time_.timescale); + clamp(res.numerator, time_.timescale); clamp(res.denominator, time_.value); return res; } -using frame_rates_t = vector>; -static frame_rates_t enumerate_frame_rates(AVCaptureDevice *dev, - const CMVideoDimensions *dims = nullptr) +using frame_rates_t = + vector>; +static frame_rates_t +enumerate_frame_rates(AVCaptureDevice *dev, + const CMVideoDimensions *dims = nullptr) { frame_rates_t res; if (!dev || !dims) return res; - auto add_unique_frame_rate_range = [&](AVFrameRateRange *range) - { + auto add_unique_frame_rate_range = [&](AVFrameRateRange *range) { auto min = convert(range.maxFrameDuration); auto max = convert(range.minFrameDuration); @@ -1578,22 +1569,21 @@ static frame_rates_t enumerate_frame_rates(AVCaptureDevice *dev, if (!(get_dimensions(format) == *dims)) continue; - for (AVFrameRateRange *range in - format.videoSupportedFrameRateRanges) { + for (AVFrameRateRange *range in format + .videoSupportedFrameRateRanges) { add_unique_frame_rate_range(range); if (CMTimeCompare(range.minFrameDuration, - range.maxFrameDuration) != 0) { - blog(LOG_WARNING, "Got actual frame rate range:" - " %g - %g " - "({%lld, %d} - {%lld, %d})", - range.minFrameRate, - range.maxFrameRate, - range.maxFrameDuration.value, - range.maxFrameDuration.timescale, - range.minFrameDuration.value, - range.minFrameDuration.timescale - ); + range.maxFrameDuration) != 0) { + blog(LOG_WARNING, + "Got actual frame rate range:" + " %g - %g " + "({%lld, %d} - {%lld, %d})", + range.minFrameRate, range.maxFrameRate, + range.maxFrameDuration.value, + range.maxFrameDuration.timescale, + range.minFrameDuration.value, + range.minFrameDuration.timescale); } } } @@ -1602,19 +1592,19 @@ static frame_rates_t enumerate_frame_rates(AVCaptureDevice *dev, } static bool operator==(const media_frames_per_second &a, - const media_frames_per_second &b) + const media_frames_per_second &b) { return a.numerator == b.numerator && a.denominator == b.denominator; } static bool operator!=(const media_frames_per_second &a, - const media_frames_per_second &b) + const media_frames_per_second &b) { return !(a == b); } static bool frame_rate_property_needs_update(obs_property_t *p, - const frame_rates_t &frame_rates) + const frame_rates_t &frame_rates) { auto fps_num = frame_rates.size(); auto num = obs_property_frame_rate_fps_ranges_count(p); @@ -1627,7 +1617,7 @@ static bool frame_rate_property_needs_update(obs_property_t *p, auto max_ = obs_property_frame_rate_fps_range_max(p, i); auto it = find(begin(frame_rates), end(frame_rates), - make_pair(min_, max_)); + make_pair(min_, max_)); if (it == end(frame_rates)) return true; @@ -1635,11 +1625,12 @@ static bool frame_rate_property_needs_update(obs_property_t *p, } return any_of(begin(fps_found), end(fps_found), - [](bool b) { return !b; }); + [](bool b) { return !b; }); } static bool update_frame_rate_property(obs_properties_t *props, - const config_helper &conf, obs_property_t *p=nullptr) + const config_helper &conf, + obs_property_t *p = nullptr) { if (!p) p = obs_properties_get(props, "frame_rate"); @@ -1658,20 +1649,19 @@ static bool update_frame_rate_property(obs_properties_t *props, obs_property_frame_rate_fps_ranges_clear(p); for (auto &pair : frame_rates) - obs_property_frame_rate_fps_range_add(p, - pair.first, pair.second); + obs_property_frame_rate_fps_range_add(p, pair.first, + pair.second); return true; } -static vector enumerate_formats(AVCaptureDevice *dev, - const CMVideoDimensions &dims, - const media_frames_per_second &fps) +static vector +enumerate_formats(AVCaptureDevice *dev, const CMVideoDimensions &dims, + const media_frames_per_second &fps) { - vector result; + vector result; - find_formats(fps, dev, &dims, [&](AVCaptureDeviceFormat *format) - { + find_formats(fps, dev, &dims, [&](AVCaptureDeviceFormat *format) { result.push_back(format); return false; }); @@ -1679,9 +1669,9 @@ static vector enumerate_formats(AVCaptureDevice *dev, return result; } -static bool input_format_property_needs_update(obs_property_t *p, - const vector &formats, - const FourCharCode *fourcc_) +static bool input_format_property_needs_update( + obs_property_t *p, const vector &formats, + const FourCharCode *fourcc_) { bool fourcc_found = !fourcc_; vector if_found(formats.size()); @@ -1692,13 +1682,13 @@ static bool input_format_property_needs_update(obs_property_t *p, fourcc_found = fourcc_found || fourcc == *fourcc_; auto pos = find_if(begin(formats), end(formats), - [&](AVCaptureDeviceFormat *format) - { - FourCharCode fourcc_ = 0; - format_description_subtype_name( - format.formatDescription, &fourcc_); - return fourcc_ == fourcc; - }); + [&](AVCaptureDeviceFormat *format) { + FourCharCode fourcc_ = 0; + format_description_subtype_name( + format.formatDescription, + &fourcc_); + return fourcc_ == fourcc; + }); if (pos == end(formats)) return true; @@ -1706,11 +1696,12 @@ static bool input_format_property_needs_update(obs_property_t *p, } return fourcc_found || any_of(begin(if_found), end(if_found), - [](bool b) { return !b; }); + [](bool b) { return !b; }); } static bool update_input_format_property(obs_properties_t *props, - const config_helper &conf, obs_property_t *p=nullptr) + const config_helper &conf, + obs_property_t *p = nullptr) { if (!p) p = obs_properties_get(props, "input_format"); @@ -1718,16 +1709,15 @@ static bool update_input_format_property(obs_properties_t *props, if (!p) return false; - auto update_enabled = [&](bool enabled) - { + auto update_enabled = [&](bool enabled) { bool was_enabled = obs_property_enabled(p); obs_property_set_enabled(p, enabled); return was_enabled != enabled; }; auto valid_dims = conf.dims(); - auto valid_fps = conf.fps(); - auto valid_if = conf.input_format(); + auto valid_fps = conf.fps(); + auto valid_if = conf.input_format(); if (!valid_dims || !valid_fps) return update_enabled(false); @@ -1743,7 +1733,7 @@ static bool update_input_format_property(obs_properties_t *props, for (auto &format : formats) { FourCharCode fourcc = 0; const char *name = format_description_subtype_name( - format.formatDescription, &fourcc); + format.formatDescription, &fourcc); obs_property_list_add_int(p, name, fourcc); fourcc_found = fourcc_found || fourcc == *valid_if; } @@ -1757,7 +1747,8 @@ static bool update_input_format_property(obs_properties_t *props, } static bool update_int_list_property(obs_property_t *p, const int *val, - const size_t count, const char *localization_name) + const size_t count, + const char *localization_name) { size_t num = obs_property_list_item_count(p); if (num > count) { @@ -1784,12 +1775,12 @@ static bool update_int_list_property(obs_property_t *p, const int *val, return true; } -template -static bool update_int_list_property(const char *prop_name, - const char *localization_name, size_t count, - int auto_val, bool (*valid_func)(int), - obs_properties_t *props, const config_helper &conf, - obs_property_t *p, Func get_val) +template +static bool +update_int_list_property(const char *prop_name, const char *localization_name, + size_t count, int auto_val, bool (*valid_func)(int), + obs_properties_t *props, const config_helper &conf, + obs_property_t *p, Func get_val) { auto ref = get_ref(props); if (!p) @@ -1808,20 +1799,20 @@ static bool update_int_list_property(const char *prop_name, obs_data_has_autoselect_value(conf.settings, prop_name); if ((params_valid && format_is_yuv(ref->frame.format)) || - !valid_func(val)) + !valid_func(val)) should_enable = true; obs_property_set_enabled(p, should_enable); bool updated = enabled != should_enable; - updated = update_int_list_property(p, - valid_func(val) ? nullptr : &val, - count, localization_name) || updated; + updated = update_int_list_property(p, valid_func(val) ? nullptr : &val, + count, localization_name) || + updated; if (!should_enable) { if (has_autoselect) obs_data_unset_autoselect_value(conf.settings, - prop_name); + prop_name); return updated || has_autoselect; } @@ -1829,14 +1820,14 @@ static bool update_int_list_property(const char *prop_name, if (!use_autoselect) { if (has_autoselect) obs_data_unset_autoselect_value(conf.settings, - prop_name); + prop_name); return updated || has_autoselect; } - if (params_valid && get_val(vi) != - obs_data_get_autoselect_int(conf.settings, prop_name)) { + if (params_valid && get_val(vi) != obs_data_get_autoselect_int( + conf.settings, prop_name)) { obs_data_set_autoselect_int(conf.settings, prop_name, - get_val(vi)); + get_val(vi)); return true; } @@ -1844,52 +1835,53 @@ static bool update_int_list_property(const char *prop_name, } static bool update_color_space_property(obs_properties_t *props, - const config_helper &conf, obs_property_t *p=nullptr) + const config_helper &conf, + obs_property_t *p = nullptr) { return update_int_list_property("color_space", TEXT_COLOR_UNKNOWN_NAME, - 4, COLOR_SPACE_AUTO, color_space_valid, props, conf, p, - [](av_video_info vi) - { - return vi.colorspace; - }); + 4, COLOR_SPACE_AUTO, color_space_valid, + props, conf, p, [](av_video_info vi) { + return vi.colorspace; + }); } static bool update_video_range_property(obs_properties_t *props, - const config_helper &conf, obs_property_t *p=nullptr) + const config_helper &conf, + obs_property_t *p = nullptr) { return update_int_list_property("video_range", TEXT_RANGE_UNKNOWN_NAME, - 5, VIDEO_RANGE_AUTO, video_range_valid, props, conf, p, - [](av_video_info vi) - { - return vi.video_range; - }); + 5, VIDEO_RANGE_AUTO, video_range_valid, + props, conf, p, [](av_video_info vi) { + return vi.video_range; + }); } -static bool properties_device_changed(obs_properties_t *props, obs_property_t *p, - obs_data_t *settings) +static bool properties_device_changed(obs_properties_t *props, + obs_property_t *p, obs_data_t *settings) { NSString *uid = get_string(settings, "device"); AVCaptureDevice *dev = [AVCaptureDevice deviceWithUniqueID:uid]; NSString *name = get_string(settings, "device_name"); - bool dev_list_updated = update_device_list(p, uid, name, - !dev && uid.length); + bool dev_list_updated = + update_device_list(p, uid, name, !dev && uid.length); p = obs_properties_get(props, "preset"); bool preset_list_changed = check_preset(dev, p, settings); - bool autoselect_changed = autoselect_preset(dev, settings); + bool autoselect_changed = autoselect_preset(dev, settings); config_helper conf{settings}; bool res_changed = update_resolution_property(props, conf); bool fps_changed = update_frame_rate_property(props, conf); - bool if_changed = update_input_format_property(props, conf); + bool if_changed = update_input_format_property(props, conf); - return preset_list_changed || autoselect_changed || dev_list_updated - || res_changed || fps_changed || if_changed; + return preset_list_changed || autoselect_changed || dev_list_updated || + res_changed || fps_changed || if_changed; } static bool properties_use_preset_changed(obs_properties_t *props, - obs_property_t *, obs_data_t *settings) + obs_property_t *, + obs_data_t *settings) { auto use_preset = obs_data_get_bool(settings, "use_preset"); @@ -1899,83 +1891,84 @@ static bool properties_use_preset_changed(obs_properties_t *props, bool visible = false; obs_property_t *p = nullptr; - auto noop = [](obs_properties_t *, const config_helper&, - obs_property_t *) - { - return false; - }; + auto noop = [](obs_properties_t *, const config_helper &, + obs_property_t *) { return false; }; -#define UPDATE_PROPERTY(prop, uses_preset, func) \ - p = obs_properties_get(props, prop); \ - visible = use_preset == uses_preset; \ +#define UPDATE_PROPERTY(prop, uses_preset, func) \ + p = obs_properties_get(props, prop); \ + visible = use_preset == uses_preset; \ updated = obs_property_visible(p) != visible || updated; \ - obs_property_set_visible(p, visible);\ + obs_property_set_visible(p, visible); \ updated = func(props, conf, p) || updated; - UPDATE_PROPERTY("preset", true, noop); - UPDATE_PROPERTY("resolution", false, update_resolution_property); - UPDATE_PROPERTY("frame_rate", false, update_frame_rate_property); + UPDATE_PROPERTY("preset", true, noop); + UPDATE_PROPERTY("resolution", false, update_resolution_property); + UPDATE_PROPERTY("frame_rate", false, update_frame_rate_property); UPDATE_PROPERTY("input_format", false, update_input_format_property); - UPDATE_PROPERTY("color_space", false, update_color_space_property); - UPDATE_PROPERTY("video_range", false, update_video_range_property); + UPDATE_PROPERTY("color_space", false, update_color_space_property); + UPDATE_PROPERTY("video_range", false, update_video_range_property); return updated; } static bool properties_preset_changed(obs_properties_t *, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { NSString *uid = get_string(settings, "device"); AVCaptureDevice *dev = [AVCaptureDevice deviceWithUniqueID:uid]; bool preset_list_changed = check_preset(dev, p, settings); - bool autoselect_changed = autoselect_preset(dev, settings); + bool autoselect_changed = autoselect_preset(dev, settings); return preset_list_changed || autoselect_changed; } static bool properties_resolution_changed(obs_properties_t *props, - obs_property_t *p, obs_data_t *settings) + obs_property_t *p, + obs_data_t *settings) { config_helper conf{settings}; bool res_updated = update_resolution_property(props, conf, p); bool fps_updated = update_frame_rate_property(props, conf); - bool if_updated = update_input_format_property(props, conf); - bool cs_updated = update_color_space_property(props, conf); - bool cr_updated = update_video_range_property(props, conf); + bool if_updated = update_input_format_property(props, conf); + bool cs_updated = update_color_space_property(props, conf); + bool cr_updated = update_video_range_property(props, conf); - return res_updated || fps_updated || - if_updated || cs_updated || cr_updated; + return res_updated || fps_updated || if_updated || cs_updated || + cr_updated; } static bool properties_frame_rate_changed(obs_properties_t *props, - obs_property_t *p, obs_data_t *settings) + obs_property_t *p, + obs_data_t *settings) { config_helper conf{settings}; bool fps_updated = update_frame_rate_property(props, conf, p); - bool if_updated = update_input_format_property(props, conf); - bool cs_updated = update_color_space_property(props, conf); - bool cr_updated = update_video_range_property(props, conf); + bool if_updated = update_input_format_property(props, conf); + bool cs_updated = update_color_space_property(props, conf); + bool cr_updated = update_video_range_property(props, conf); return fps_updated || if_updated || cs_updated || cr_updated; } static bool properties_input_format_changed(obs_properties_t *props, - obs_property_t *p, obs_data_t *settings) + obs_property_t *p, + obs_data_t *settings) { config_helper conf{settings}; - bool if_updated = update_input_format_property(props, conf, p); - bool cs_updated = update_color_space_property(props, conf); - bool cr_updated = update_video_range_property(props, conf); + bool if_updated = update_input_format_property(props, conf, p); + bool cs_updated = update_color_space_property(props, conf); + bool cr_updated = update_video_range_property(props, conf); return if_updated || cs_updated || cr_updated; } static bool properties_color_space_changed(obs_properties_t *props, - obs_property_t *p, obs_data_t *settings) + obs_property_t *p, + obs_data_t *settings) { config_helper conf{settings}; @@ -1983,7 +1976,8 @@ static bool properties_color_space_changed(obs_properties_t *props, } static bool properties_video_range_changed(obs_properties_t *props, - obs_property_t *p, obs_data_t *settings) + obs_property_t *p, + obs_data_t *settings) { config_helper conf{settings}; @@ -1992,77 +1986,73 @@ static bool properties_video_range_changed(obs_properties_t *props, static void add_properties_param(obs_properties_t *props, av_capture *capture) { - auto param = unique_ptr( - new properties_param(capture)); + auto param = + unique_ptr(new properties_param(capture)); - obs_properties_set_param(props, param.release(), - [](void *param) - { - delete static_cast(param); + obs_properties_set_param(props, param.release(), [](void *param) { + delete static_cast(param); }); } static void add_preset_properties(obs_properties_t *props) { - obs_property_t *preset_list = obs_properties_add_list(props, "preset", - TEXT_PRESET, OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_STRING); + obs_property_t *preset_list = obs_properties_add_list( + props, "preset", TEXT_PRESET, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); for (NSString *preset in presets()) obs_property_list_add_string(preset_list, - preset_names(preset).UTF8String, - preset.UTF8String); + preset_names(preset).UTF8String, + preset.UTF8String); obs_property_set_modified_callback(preset_list, - properties_preset_changed); + properties_preset_changed); } static void add_manual_properties(obs_properties_t *props) { - obs_property_t *resolutions = obs_properties_add_list(props, - "resolution", TEXT_RESOLUTION, OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_STRING); + obs_property_t *resolutions = obs_properties_add_list( + props, "resolution", TEXT_RESOLUTION, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_set_enabled(resolutions, false); obs_property_set_modified_callback(resolutions, - properties_resolution_changed); + properties_resolution_changed); - obs_property_t *frame_rates = obs_properties_add_frame_rate(props, - "frame_rate", TEXT_FRAME_RATE); + obs_property_t *frame_rates = obs_properties_add_frame_rate( + props, "frame_rate", TEXT_FRAME_RATE); /*obs_property_frame_rate_option_add(frame_rates, "match obs", TEXT_MATCH_OBS);*/ obs_property_set_enabled(frame_rates, false); obs_property_set_modified_callback(frame_rates, - properties_frame_rate_changed); + properties_frame_rate_changed); - obs_property_t *input_format = obs_properties_add_list(props, - "input_format", TEXT_INPUT_FORMAT, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_property_list_add_int(input_format, TEXT_AUTO, - INPUT_FORMAT_AUTO); + obs_property_t *input_format = obs_properties_add_list( + props, "input_format", TEXT_INPUT_FORMAT, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(input_format, TEXT_AUTO, INPUT_FORMAT_AUTO); obs_property_set_enabled(input_format, false); obs_property_set_modified_callback(input_format, - properties_input_format_changed); + properties_input_format_changed); - obs_property_t *color_space = obs_properties_add_list(props, - "color_space", TEXT_COLOR_SPACE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_t *color_space = obs_properties_add_list( + props, "color_space", TEXT_COLOR_SPACE, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); obs_property_list_add_int(color_space, TEXT_AUTO, COLOR_SPACE_AUTO); obs_property_list_add_int(color_space, "Rec. 601", VIDEO_CS_601); obs_property_list_add_int(color_space, "Rec. 709", VIDEO_CS_709); obs_property_set_enabled(color_space, false); obs_property_set_modified_callback(color_space, - properties_color_space_changed); + properties_color_space_changed); -#define ADD_RANGE(x) \ - obs_property_list_add_int(video_range, TEXT_ ## x, VIDEO_ ## x) - obs_property_t *video_range = obs_properties_add_list(props, - "video_range", TEXT_VIDEO_RANGE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); +#define ADD_RANGE(x) obs_property_list_add_int(video_range, TEXT_##x, VIDEO_##x) + obs_property_t *video_range = obs_properties_add_list( + props, "video_range", TEXT_VIDEO_RANGE, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); obs_property_list_add_int(video_range, TEXT_AUTO, VIDEO_RANGE_AUTO); ADD_RANGE(RANGE_PARTIAL); ADD_RANGE(RANGE_FULL); obs_property_set_enabled(video_range, false); obs_property_set_modified_callback(video_range, - properties_video_range_changed); + properties_video_range_changed); #undef ADD_RANGE } @@ -2070,43 +2060,41 @@ static obs_properties_t *av_capture_properties(void *capture) { obs_properties_t *props = obs_properties_create(); - add_properties_param(props, static_cast(capture)); + add_properties_param(props, static_cast(capture)); - obs_property_t *dev_list = obs_properties_add_list(props, "device", - TEXT_DEVICE, OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_STRING); + obs_property_t *dev_list = obs_properties_add_list( + props, "device", TEXT_DEVICE, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(dev_list, "", ""); - for (AVCaptureDevice *dev in [AVCaptureDevice - devices]) { - if ([dev hasMediaType: AVMediaTypeVideo] || - [dev hasMediaType: AVMediaTypeMuxed]) { - obs_property_list_add_string(dev_list, - dev.localizedName.UTF8String, - dev.uniqueID.UTF8String); + for (AVCaptureDevice *dev in [AVCaptureDevice devices]) { + if ([dev hasMediaType:AVMediaTypeVideo] || + [dev hasMediaType:AVMediaTypeMuxed]) { + obs_property_list_add_string( + dev_list, dev.localizedName.UTF8String, + dev.uniqueID.UTF8String); } } - obs_property_set_modified_callback(dev_list, - properties_device_changed); + obs_property_set_modified_callback(dev_list, properties_device_changed); - obs_property_t *use_preset = obs_properties_add_bool(props, - "use_preset", TEXT_USE_PRESET); + obs_property_t *use_preset = + obs_properties_add_bool(props, "use_preset", TEXT_USE_PRESET); obs_property_set_modified_callback(use_preset, - properties_use_preset_changed); + properties_use_preset_changed); add_preset_properties(props); add_manual_properties(props); obs_properties_add_bool(props, "buffering", - obs_module_text("Buffering")); + obs_module_text("Buffering")); return props; } static void switch_device(av_capture *capture, NSString *uid, - obs_data_t *settings) + obs_data_t *settings) { if (!uid) return; @@ -2124,7 +2112,7 @@ static void switch_device(av_capture *capture, NSString *uid, AVCaptureDevice *dev = [AVCaptureDevice deviceWithUniqueID:uid]; if (!dev) { AVLOG(LOG_WARNING, "Device with unique id '%s' not found", - uid.UTF8String); + uid.UTF8String); return; } @@ -2138,7 +2126,7 @@ static void update_preset(av_capture *capture, obs_data_t *settings) NSString *preset = get_string(settings, "preset"); if (![capture->device supportsAVCaptureSessionPreset:preset]) { AVLOG(LOG_WARNING, "Preset %s not available", - preset.UTF8String); + preset.UTF8String); preset = select_preset(capture->device, preset); } @@ -2156,7 +2144,7 @@ static void update_manual(av_capture *capture, obs_data_t *settings) static void av_capture_update(void *data, obs_data_t *settings) { - auto capture = static_cast(data); + auto capture = static_cast(data); NSString *uid = get_string(settings, "device"); @@ -2170,7 +2158,7 @@ static void av_capture_update(void *data, obs_data_t *settings) } av_capture_enable_buffering(capture, - obs_data_get_bool(settings, "buffering")); + obs_data_get_bool(settings, "buffering")); } OBS_DECLARE_MODULE() @@ -2187,26 +2175,25 @@ bool obs_module_load(void) // From WWDC video 2014 #508 at 5:34 // https://developer.apple.com/videos/wwdc/2014/#508 CMIOObjectPropertyAddress prop = { - kCMIOHardwarePropertyAllowScreenCaptureDevices, - kCMIOObjectPropertyScopeGlobal, - kCMIOObjectPropertyElementMaster - }; + kCMIOHardwarePropertyAllowScreenCaptureDevices, + kCMIOObjectPropertyScopeGlobal, + kCMIOObjectPropertyElementMaster}; UInt32 allow = 1; CMIOObjectSetPropertyData(kCMIOObjectSystemObject, &prop, 0, NULL, - sizeof(allow), &allow); + sizeof(allow), &allow); #endif obs_source_info av_capture_info = { - .id = "av_capture_input", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_ASYNC_VIDEO | - OBS_SOURCE_DO_NOT_DUPLICATE, - .get_name = av_capture_getname, - .create = av_capture_create, - .destroy = av_capture_destroy, - .get_defaults = av_capture_defaults, + .id = "av_capture_input", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_ASYNC_VIDEO | + OBS_SOURCE_DO_NOT_DUPLICATE, + .get_name = av_capture_getname, + .create = av_capture_create, + .destroy = av_capture_destroy, + .get_defaults = av_capture_defaults, .get_properties = av_capture_properties, - .update = av_capture_update, + .update = av_capture_update, }; obs_register_source(&av_capture_info); diff --git a/plugins/mac-avcapture/data/locale/gl-ES.ini b/plugins/mac-avcapture/data/locale/gl-ES.ini index e97cc2f..c849890 100644 --- a/plugins/mac-avcapture/data/locale/gl-ES.ini +++ b/plugins/mac-avcapture/data/locale/gl-ES.ini @@ -1,14 +1,14 @@ AVCapture="Dispositivo de captura de vídeo" Device="Dispositivo" -UsePreset="Usar valores predefinidos" -Preset="Valores predefinidos" -Buffering="Utilizar o almacenamento no búfer" -FrameRate="Velocidade de fotogramas" +UsePreset="Usar valor predefinido" +Preset="Predefinido" +Buffering="Usar o almacenamento na memoria temporal" +FrameRate="Taxa de fotogramas" InputFormat="Formato de entrada" ColorSpace="Espazo de cor" -VideoRange="Rango de video" +VideoRange="Intervalo de vídeo" VideoRange.Partial="Parcial" -VideoRange.Full="Completo" +VideoRange.Full="Total" Auto="Automático" Unknown="Descoñecido ($1)" diff --git a/plugins/mac-avcapture/data/locale/ka-GE.ini b/plugins/mac-avcapture/data/locale/ka-GE.ini index 8aa910f..57c86ea 100644 --- a/plugins/mac-avcapture/data/locale/ka-GE.ini +++ b/plugins/mac-avcapture/data/locale/ka-GE.ini @@ -1,4 +1,4 @@ -AVCapture="ვიდეოს გადამღები მოწყობილობა" +AVCapture="ვიდეოჩამწერი მოწყობილობა" Device="მოწყობილობა" UsePreset="მზა პარამეტრებით სარგებლობა" Preset="მზა პარამეტრები" diff --git a/plugins/mac-avcapture/left-right.hpp b/plugins/mac-avcapture/left-right.hpp index 7b62d30..cbc54e0 100644 --- a/plugins/mac-avcapture/left-right.hpp +++ b/plugins/mac-avcapture/left-right.hpp @@ -12,10 +12,8 @@ namespace left_right { -template -struct left_right { - template - void update(Func &&f) +template struct left_right { + template void update(Func &&f) { std::lock_guard lock(write_mutex); auto cur = current.load(); @@ -56,8 +54,8 @@ struct left_right { private: std::atomic_uint_fast8_t current; - std::atomic_long readers[2]; - std::mutex write_mutex; + std::atomic_long readers[2]; + std::mutex write_mutex; T data[2] = {{}, {}}; }; diff --git a/plugins/mac-avcapture/scope-guard.hpp b/plugins/mac-avcapture/scope-guard.hpp index 0cda779..27f5d92 100644 --- a/plugins/mac-avcapture/scope-guard.hpp +++ b/plugins/mac-avcapture/scope-guard.hpp @@ -8,21 +8,13 @@ namespace scope_guard_util { -template -class ScopeGuard { +template class ScopeGuard { public: - void dismiss() noexcept - { - dismissed_ = true; - } + void dismiss() noexcept { dismissed_ = true; } - explicit ScopeGuard(const FunctionType &fn) - : function_(fn) - {} + explicit ScopeGuard(const FunctionType &fn) : function_(fn) {} - explicit ScopeGuard(FunctionType &&fn) - : function_(std::move(fn)) - {} + explicit ScopeGuard(FunctionType &&fn) : function_(std::move(fn)) {} ScopeGuard(ScopeGuard &&other) : dismissed_(other.dismissed_), @@ -38,43 +30,40 @@ public: } private: - void* operator new(size_t) = delete; + void *operator new(size_t) = delete; - void execute() noexcept - { - function_(); - } + void execute() noexcept { function_(); } bool dismissed_ = false; FunctionType function_; }; -template +template ScopeGuard::type> make_guard(FunctionType &&fn) { return ScopeGuard::type>{ - std::forward(fn)}; + std::forward(fn)}; } namespace detail { enum class ScopeGuardOnExit {}; -template +template ScopeGuard::type> -operator+(detail::ScopeGuardOnExit, FunctionType &&fn) { - return ScopeGuard::type>( - std::forward(fn)); +operator+(detail::ScopeGuardOnExit, FunctionType &&fn) +{ + return ScopeGuard::type>( + std::forward(fn)); } } } // namespace scope_guard_util -#define SCOPE_EXIT_CONCAT2(x, y) x ## y +#define SCOPE_EXIT_CONCAT2(x, y) x##y #define SCOPE_EXIT_CONCAT(x, y) SCOPE_EXIT_CONCAT2(x, y) -#define SCOPE_EXIT \ +#define SCOPE_EXIT \ auto SCOPE_EXIT_CONCAT(SCOPE_EXIT_STATE, __LINE__) = \ ::scope_guard_util::detail::ScopeGuardOnExit() + [&]() noexcept - diff --git a/plugins/mac-capture/audio-device-enum.c b/plugins/mac-capture/audio-device-enum.c index 5a1d7b7..ea12e6d 100644 --- a/plugins/mac-capture/audio-device-enum.c +++ b/plugins/mac-capture/audio-device-enum.c @@ -10,15 +10,15 @@ static inline bool device_is_input(char *device) { return astrstri(device, "soundflower") == NULL && - astrstri(device, "wavtap") == NULL && + astrstri(device, "wavtap") == NULL && astrstri(device, "soundsiphon") == NULL; } static inline bool enum_success(OSStatus stat, const char *msg) { if (stat != noErr) { - blog(LOG_WARNING, "[coreaudio_enum_devices] %s failed: %d", - msg, (int)stat); + blog(LOG_WARNING, "[coreaudio_enum_devices] %s failed: %d", msg, + (int)stat); return false; } @@ -26,22 +26,20 @@ static inline bool enum_success(OSStatus stat, const char *msg) } typedef bool (*enum_device_proc_t)(void *param, CFStringRef cf_name, - CFStringRef cf_uid, AudioDeviceID id); + CFStringRef cf_uid, AudioDeviceID id); static bool coreaudio_enum_device(enum_device_proc_t proc, void *param, - AudioDeviceID id) + AudioDeviceID id) { - UInt32 size = 0; - CFStringRef cf_name = NULL; - CFStringRef cf_uid = NULL; - bool enum_next = true; - OSStatus stat; + UInt32 size = 0; + CFStringRef cf_name = NULL; + CFStringRef cf_uid = NULL; + bool enum_next = true; + OSStatus stat; - AudioObjectPropertyAddress addr = { - kAudioDevicePropertyStreams, - kAudioDevicePropertyScopeInput, - kAudioObjectPropertyElementMaster - }; + AudioObjectPropertyAddress addr = {kAudioDevicePropertyStreams, + kAudioDevicePropertyScopeInput, + kAudioObjectPropertyElementMaster}; /* check to see if it's a mac input device */ AudioObjectGetPropertyDataSize(id, &addr, 0, NULL, &size); @@ -72,27 +70,25 @@ fail: static void enum_devices(enum_device_proc_t proc, void *param) { - AudioObjectPropertyAddress addr = { - kAudioHardwarePropertyDevices, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; + AudioObjectPropertyAddress addr = {kAudioHardwarePropertyDevices, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster}; - UInt32 size = 0; - UInt32 count; - OSStatus stat; + UInt32 size = 0; + UInt32 count; + OSStatus stat; AudioDeviceID *ids; stat = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &addr, - 0, NULL, &size); + 0, NULL, &size); if (!enum_success(stat, "get kAudioObjectSystemObject data size")) return; - ids = bmalloc(size); + ids = bmalloc(size); count = size / sizeof(AudioDeviceID); - stat = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, - 0, NULL, &size, ids); + stat = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, 0, + NULL, &size, ids); if (enum_success(stat, "get kAudioObjectSystemObject data")) for (UInt32 i = 0; i < count; i++) @@ -104,20 +100,20 @@ static void enum_devices(enum_device_proc_t proc, void *param) struct add_data { struct device_list *list; - bool input; + bool input; }; static bool coreaudio_enum_add_device(void *param, CFStringRef cf_name, - CFStringRef cf_uid, AudioDeviceID id) + CFStringRef cf_uid, AudioDeviceID id) { - struct add_data *data = param; + struct add_data *data = param; struct device_item item; memset(&item, 0, sizeof(item)); if (!cfstr_copy_dstr(cf_name, kCFStringEncodingUTF8, &item.name)) goto fail; - if (!cfstr_copy_dstr(cf_uid, kCFStringEncodingUTF8, &item.value)) + if (!cfstr_copy_dstr(cf_uid, kCFStringEncodingUTF8, &item.value)) goto fail; if (data->input || !device_is_input(item.value.array)) @@ -137,18 +133,18 @@ void coreaudio_enum_devices(struct device_list *list, bool input) } struct device_id_data { - CFStringRef uid; + CFStringRef uid; AudioDeviceID *id; - bool found; + bool found; }; static bool get_device_id(void *param, CFStringRef cf_name, CFStringRef cf_uid, - AudioDeviceID id) + AudioDeviceID id) { struct device_id_data *data = param; if (CFStringCompare(cf_uid, data->uid, 0) == 0) { - *data->id = id; + *data->id = id; data->found = true; return false; } diff --git a/plugins/mac-capture/audio-device-enum.h b/plugins/mac-capture/audio-device-enum.h index 306fae5..8996845 100644 --- a/plugins/mac-capture/audio-device-enum.h +++ b/plugins/mac-capture/audio-device-enum.h @@ -20,13 +20,13 @@ struct device_list { static inline void device_list_free(struct device_list *list) { for (size_t i = 0; i < list->items.num; i++) - device_item_free(list->items.array+i); + device_item_free(list->items.array + i); da_free(list->items); } static inline void device_list_add(struct device_list *list, - struct device_item *item) + struct device_item *item) { da_push_back(list->items, item); memset(item, 0, sizeof(struct device_item)); diff --git a/plugins/mac-capture/data/locale/gl-ES.ini b/plugins/mac-capture/data/locale/gl-ES.ini index b4a523e..16694e1 100644 --- a/plugins/mac-capture/data/locale/gl-ES.ini +++ b/plugins/mac-capture/data/locale/gl-ES.ini @@ -1,21 +1,21 @@ -CoreAudio.InputCapture="Captura de entrada de audio" -CoreAudio.OutputCapture="Captura de saída de audio" +CoreAudio.InputCapture="Captura de entrada de son" +CoreAudio.OutputCapture="Captura de saída de son" CoreAudio.Device="Dispositivo" -CoreAudio.Device.Default="Por defecto" +CoreAudio.Device.Default="Predeterminado" DisplayCapture="Captura de pantalla" DisplayCapture.Display="Pantalla" -DisplayCapture.ShowCursor="Mostrar o cursor" -WindowCapture="Capturar xanela" -WindowCapture.ShowShadow="Mostrar sombra da xanela" +DisplayCapture.ShowCursor="Amosar o cursor" +WindowCapture="Captura da xanela" +WindowCapture.ShowShadow="Amosar a sombra da xanela" WindowUtils.Window="Xanela" -WindowUtils.ShowEmptyNames="Mostrar xanelas con nomes baleiros" +WindowUtils.ShowEmptyNames="Amosar as xanelas con nomes baleiros" CropMode="Recortar" CropMode.None="Ningún" CropMode.Manual="Manual" CropMode.ToWindow="Á xanela" CropMode.ToWindowAndManual="Á xanela e manual" -Crop.origin.x="Recortar á esquerda" -Crop.origin.y="Recortar arriba" -Crop.size.width="Recortar á dereita" -Crop.size.height="Recortar abaixo" +Crop.origin.x="Recortar pola esquerda" +Crop.origin.y="Recortar por riba" +Crop.size.width="Recortar pola dereita" +Crop.size.height="Recortar por baixo" diff --git a/plugins/mac-capture/data/locale/ka-GE.ini b/plugins/mac-capture/data/locale/ka-GE.ini index 69d81de..1439de7 100644 --- a/plugins/mac-capture/data/locale/ka-GE.ini +++ b/plugins/mac-capture/data/locale/ka-GE.ini @@ -1,4 +1,4 @@ -CoreAudio.InputCapture="შემავალი ხმოვანი სიგნალის ჩაწერა" +CoreAudio.InputCapture="შემავალი ხმის ჩაწერა" CoreAudio.OutputCapture="გამოტანილი ხმის ჩაწერა" CoreAudio.Device="მოწყობილობა" CoreAudio.Device.Default="ნაგულისხმევი" diff --git a/plugins/mac-capture/data/locale/ro-RO.ini b/plugins/mac-capture/data/locale/ro-RO.ini index 9215d51..887e515 100644 --- a/plugins/mac-capture/data/locale/ro-RO.ini +++ b/plugins/mac-capture/data/locale/ro-RO.ini @@ -4,7 +4,7 @@ CoreAudio.Device="Dispozitiv" CoreAudio.Device.Default="Implicit" DisplayCapture="Captură de display" DisplayCapture.Display="Display" -DisplayCapture.ShowCursor="Arată cursorul" +DisplayCapture.ShowCursor="Afișează cursorul" WindowCapture="Captură de fereastră" WindowCapture.ShowShadow="Afișează umbra ferestrei" WindowUtils.Window="Fereastră" diff --git a/plugins/mac-capture/data/locale/sl-SI.ini b/plugins/mac-capture/data/locale/sl-SI.ini index f941334..18f43c0 100644 --- a/plugins/mac-capture/data/locale/sl-SI.ini +++ b/plugins/mac-capture/data/locale/sl-SI.ini @@ -5,7 +5,7 @@ CoreAudio.Device.Default="Privzeto" DisplayCapture="Zajemanje zaslona" DisplayCapture.Display="Zaslon" DisplayCapture.ShowCursor="Prikaži kazalec" -WindowCapture="Zajem Okna" +WindowCapture="Zajemanje okna" WindowCapture.ShowShadow="Prikaži senco okna" WindowUtils.Window="Okno" WindowUtils.ShowEmptyNames="Prikaži okna z praznimi imeni" diff --git a/plugins/mac-capture/mac-audio.c b/plugins/mac-capture/mac-audio.c index 7d94c64..72e36d0 100644 --- a/plugins/mac-capture/mac-audio.c +++ b/plugins/mac-capture/mac-audio.c @@ -15,44 +15,44 @@ #define PROPERTY_FORMATS kAudioStreamPropertyAvailablePhysicalFormats #define SCOPE_OUTPUT kAudioUnitScope_Output -#define SCOPE_INPUT kAudioUnitScope_Input +#define SCOPE_INPUT kAudioUnitScope_Input #define SCOPE_GLOBAL kAudioUnitScope_Global #define BUS_OUTPUT 0 -#define BUS_INPUT 1 +#define BUS_INPUT 1 #define MAX_DEVICES 20 #define set_property AudioUnitSetProperty #define get_property AudioUnitGetProperty -#define TEXT_AUDIO_INPUT obs_module_text("CoreAudio.InputCapture"); -#define TEXT_AUDIO_OUTPUT obs_module_text("CoreAudio.OutputCapture"); -#define TEXT_DEVICE obs_module_text("CoreAudio.Device") +#define TEXT_AUDIO_INPUT obs_module_text("CoreAudio.InputCapture"); +#define TEXT_AUDIO_OUTPUT obs_module_text("CoreAudio.OutputCapture"); +#define TEXT_DEVICE obs_module_text("CoreAudio.Device") #define TEXT_DEVICE_DEFAULT obs_module_text("CoreAudio.Device.Default") struct coreaudio_data { - char *device_name; - char *device_uid; - AudioUnit unit; - AudioDeviceID device_id; - AudioBufferList *buf_list; - bool au_initialized; - bool active; - bool default_device; - bool input; - bool no_devices; + char *device_name; + char *device_uid; + AudioUnit unit; + AudioDeviceID device_id; + AudioBufferList *buf_list; + bool au_initialized; + bool active; + bool default_device; + bool input; + bool no_devices; - uint32_t sample_rate; - enum audio_format format; + uint32_t sample_rate; + enum audio_format format; enum speaker_layout speakers; - pthread_t reconnect_thread; - os_event_t *exit_event; - volatile bool reconnecting; - unsigned long retry_time; + pthread_t reconnect_thread; + os_event_t *exit_event; + volatile bool reconnecting; + unsigned long retry_time; - obs_source_t *source; + obs_source_t *source; }; static bool get_default_output_device(struct coreaudio_data *ca) @@ -74,17 +74,16 @@ static bool get_default_output_device(struct coreaudio_data *ca) static bool find_device_id_by_uid(struct coreaudio_data *ca) { - UInt32 size = sizeof(AudioDeviceID); - CFStringRef cf_uid = NULL; - CFStringRef qual = NULL; - UInt32 qual_size = 0; - OSStatus stat; - bool success; + UInt32 size = sizeof(AudioDeviceID); + CFStringRef cf_uid = NULL; + CFStringRef qual = NULL; + UInt32 qual_size = 0; + OSStatus stat; + bool success; AudioObjectPropertyAddress addr = { - .mScope = kAudioObjectPropertyScopeGlobal, - .mElement = kAudioObjectPropertyElementMaster - }; + .mScope = kAudioObjectPropertyScopeGlobal, + .mElement = kAudioObjectPropertyElementMaster}; if (!ca->device_uid) ca->device_uid = bstrdup("default"); @@ -105,12 +104,13 @@ static bool find_device_id_by_uid(struct coreaudio_data *ca) } cf_uid = CFStringCreateWithCString(NULL, ca->device_uid, - kCFStringEncodingUTF8); + kCFStringEncodingUTF8); if (ca->default_device) { addr.mSelector = PROPERTY_DEFAULT_DEVICE; stat = AudioObjectGetPropertyData(kAudioObjectSystemObject, - &addr, qual_size, &qual, &size, &ca->device_id); + &addr, qual_size, &qual, + &size, &ca->device_id); success = (stat == noErr); } else { success = coreaudio_get_device_id(cf_uid, &ca->device_id); @@ -123,7 +123,7 @@ static bool find_device_id_by_uid(struct coreaudio_data *ca) } static inline void ca_warn(struct coreaudio_data *ca, const char *func, - const char *format, ...) + const char *format, ...) { va_list args; struct dstr str = {0}; @@ -139,11 +139,11 @@ static inline void ca_warn(struct coreaudio_data *ca, const char *func, } static inline bool ca_success(OSStatus stat, struct coreaudio_data *ca, - const char *func, const char *action) + const char *func, const char *action) { if (stat != noErr) { - blog(LOG_WARNING, "[%s]:[device '%s'] %s failed: %d", - func, ca->device_name, action, (int)stat); + blog(LOG_WARNING, "[%s]:[device '%s'] %s failed: %d", func, + ca->device_name, action, (int)stat); return false; } @@ -156,17 +156,18 @@ enum coreaudio_io_type { }; static inline bool enable_io(struct coreaudio_data *ca, - enum coreaudio_io_type type, bool enable) + enum coreaudio_io_type type, bool enable) { UInt32 enable_int = enable; return set_property(ca->unit, kAudioOutputUnitProperty_EnableIO, - (type == IO_TYPE_INPUT) ? SCOPE_INPUT : SCOPE_OUTPUT, - (type == IO_TYPE_INPUT) ? BUS_INPUT : BUS_OUTPUT, - &enable_int, sizeof(enable_int)); + (type == IO_TYPE_INPUT) ? SCOPE_INPUT + : SCOPE_OUTPUT, + (type == IO_TYPE_INPUT) ? BUS_INPUT : BUS_OUTPUT, + &enable_int, sizeof(enable_int)); } static inline enum audio_format convert_ca_format(UInt32 format_flags, - UInt32 bits) + UInt32 bits) { bool planar = (format_flags & kAudioFormatFlagIsNonInterleaved) != 0; @@ -191,13 +192,20 @@ static inline enum audio_format convert_ca_format(UInt32 format_flags, static inline enum speaker_layout convert_ca_speaker_layout(UInt32 channels) { switch (channels) { - case 1: return SPEAKERS_MONO; - case 2: return SPEAKERS_STEREO; - case 3: return SPEAKERS_2POINT1; - case 4: return SPEAKERS_4POINT0; - case 5: return SPEAKERS_4POINT1; - case 6: return SPEAKERS_5POINT1; - case 8: return SPEAKERS_7POINT1; + case 1: + return SPEAKERS_MONO; + case 2: + return SPEAKERS_STEREO; + case 3: + return SPEAKERS_2POINT1; + case 4: + return SPEAKERS_4POINT0; + case 5: + return SPEAKERS_4POINT1; + case 6: + return SPEAKERS_5POINT1; + case 8: + return SPEAKERS_7POINT1; } return SPEAKERS_UNKNOWN; @@ -218,7 +226,7 @@ static bool coreaudio_init_format(struct coreaudio_data *ca) channels = get_audio_channels(aoi.speakers); stat = get_property(ca->unit, kAudioUnitProperty_StreamFormat, - SCOPE_INPUT, BUS_INPUT, &desc, &size); + SCOPE_INPUT, BUS_INPUT, &desc, &size); if (!ca_success(stat, ca, "coreaudio_init_format", "get input format")) return false; @@ -229,11 +237,11 @@ static bool coreaudio_init_format(struct coreaudio_data *ca) desc.mChannelsPerFrame = channels; desc.mBytesPerFrame = channels * desc.mBitsPerChannel / 8; desc.mBytesPerPacket = - desc.mFramesPerPacket * desc.mBytesPerFrame; + desc.mFramesPerPacket * desc.mBytesPerFrame; } stat = set_property(ca->unit, kAudioUnitProperty_StreamFormat, - SCOPE_OUTPUT, BUS_INPUT, &desc, size); + SCOPE_OUTPUT, BUS_INPUT, &desc, size); if (!ca_success(stat, ca, "coreaudio_init_format", "set output format")) return false; @@ -244,10 +252,11 @@ static bool coreaudio_init_format(struct coreaudio_data *ca) ca->format = convert_ca_format(desc.mFormatFlags, desc.mBitsPerChannel); if (ca->format == AUDIO_FORMAT_UNKNOWN) { - ca_warn(ca, "coreaudio_init_format", "unknown format flags: " - "%u, bits: %u", - (unsigned int)desc.mFormatFlags, - (unsigned int)desc.mBitsPerChannel); + ca_warn(ca, "coreaudio_init_format", + "unknown format flags: " + "%u, bits: %u", + (unsigned int)desc.mFormatFlags, + (unsigned int)desc.mBitsPerChannel); return false; } @@ -255,9 +264,10 @@ static bool coreaudio_init_format(struct coreaudio_data *ca) ca->speakers = convert_ca_speaker_layout(desc.mChannelsPerFrame); if (ca->speakers == SPEAKERS_UNKNOWN) { - ca_warn(ca, "coreaudio_init_format", "unknown speaker layout: " - "%u channels", - (unsigned int)desc.mChannelsPerFrame); + ca_warn(ca, "coreaudio_init_format", + "unknown speaker layout: " + "%u channels", + (unsigned int)desc.mChannelsPerFrame); return false; } @@ -267,24 +277,23 @@ static bool coreaudio_init_format(struct coreaudio_data *ca) static bool coreaudio_init_buffer(struct coreaudio_data *ca) { UInt32 buf_size = 0; - UInt32 size = 0; - UInt32 frames = 0; + UInt32 size = 0; + UInt32 frames = 0; OSStatus stat; AudioObjectPropertyAddress addr = { kAudioDevicePropertyStreamConfiguration, kAudioDevicePropertyScopeInput, - kAudioObjectPropertyElementMaster - }; + kAudioObjectPropertyElementMaster}; stat = AudioObjectGetPropertyDataSize(ca->device_id, &addr, 0, NULL, - &buf_size); + &buf_size); if (!ca_success(stat, ca, "coreaudio_init_buffer", "get list size")) return false; size = sizeof(frames); stat = get_property(ca->unit, kAudioDevicePropertyBufferFrameSize, - SCOPE_GLOBAL, 0, &frames, &size); + SCOPE_GLOBAL, 0, &frames, &size); if (!ca_success(stat, ca, "coreaudio_init_buffer", "get frame size")) return false; @@ -293,7 +302,7 @@ static bool coreaudio_init_buffer(struct coreaudio_data *ca) ca->buf_list = bmalloc(buf_size); stat = AudioObjectGetPropertyData(ca->device_id, &addr, 0, NULL, - &buf_size, ca->buf_list); + &buf_size, ca->buf_list); if (!ca_success(stat, ca, "coreaudio_init_buffer", "allocate")) { bfree(ca->buf_list); ca->buf_list = NULL; @@ -304,7 +313,7 @@ static bool coreaudio_init_buffer(struct coreaudio_data *ca) size = ca->buf_list->mBuffers[i].mDataByteSize; ca->buf_list->mBuffers[i].mData = bmalloc(size); } - + return true; } @@ -318,31 +327,28 @@ static void buf_list_free(AudioBufferList *buf_list) } } -static OSStatus input_callback( - void *data, - AudioUnitRenderActionFlags *action_flags, - const AudioTimeStamp *ts_data, - UInt32 bus_num, - UInt32 frames, - AudioBufferList *ignored_buffers) +static OSStatus input_callback(void *data, + AudioUnitRenderActionFlags *action_flags, + const AudioTimeStamp *ts_data, UInt32 bus_num, + UInt32 frames, AudioBufferList *ignored_buffers) { struct coreaudio_data *ca = data; OSStatus stat; struct obs_source_audio audio; stat = AudioUnitRender(ca->unit, action_flags, ts_data, bus_num, frames, - ca->buf_list); + ca->buf_list); if (!ca_success(stat, ca, "input_callback", "audio retrieval")) return noErr; for (UInt32 i = 0; i < ca->buf_list->mNumberBuffers; i++) audio.data[i] = ca->buf_list->mBuffers[i].mData; - audio.frames = frames; - audio.speakers = ca->speakers; - audio.format = ca->format; + audio.frames = frames; + audio.speakers = ca->speakers; + audio.format = ca->format; audio.samples_per_sec = ca->sample_rate; - audio.timestamp = ts_data->mHostTime; + audio.timestamp = ts_data->mHostTime; obs_source_output_audio(ca->source, &audio); @@ -360,7 +366,8 @@ static void *reconnect_thread(void *param) ca->reconnecting = true; - while (os_event_timedwait(ca->exit_event, ca->retry_time) == ETIMEDOUT) { + while (os_event_timedwait(ca->exit_event, ca->retry_time) == + ETIMEDOUT) { if (coreaudio_init(ca)) break; } @@ -379,15 +386,15 @@ static void coreaudio_begin_reconnect(struct coreaudio_data *ca) ret = pthread_create(&ca->reconnect_thread, NULL, reconnect_thread, ca); if (ret != 0) - blog(LOG_WARNING, "[coreaudio_begin_reconnect] failed to " - "create thread, error code: %d", ret); + blog(LOG_WARNING, + "[coreaudio_begin_reconnect] failed to " + "create thread, error code: %d", + ret); } -static OSStatus notification_callback( - AudioObjectID id, - UInt32 num_addresses, - const AudioObjectPropertyAddress addresses[], - void *data) +static OSStatus +notification_callback(AudioObjectID id, UInt32 num_addresses, + const AudioObjectPropertyAddress addresses[], void *data) { struct coreaudio_data *ca = data; @@ -399,8 +406,10 @@ static OSStatus notification_callback( else ca->retry_time = 2000; - blog(LOG_INFO, "coreaudio: device '%s' disconnected or changed. " - "attempting to reconnect", ca->device_name); + blog(LOG_INFO, + "coreaudio: device '%s' disconnected or changed. " + "attempting to reconnect", + ca->device_name); coreaudio_begin_reconnect(ca); @@ -412,50 +421,48 @@ static OSStatus notification_callback( static OSStatus add_listener(struct coreaudio_data *ca, UInt32 property) { - AudioObjectPropertyAddress addr = { - property, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; + AudioObjectPropertyAddress addr = {property, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster}; return AudioObjectAddPropertyListener(ca->device_id, &addr, - notification_callback, ca); + notification_callback, ca); } static bool coreaudio_init_hooks(struct coreaudio_data *ca) { OSStatus stat; - AURenderCallbackStruct callback_info = { - .inputProc = input_callback, - .inputProcRefCon = ca - }; + AURenderCallbackStruct callback_info = {.inputProc = input_callback, + .inputProcRefCon = ca}; stat = add_listener(ca, kAudioDevicePropertyDeviceIsAlive); if (!ca_success(stat, ca, "coreaudio_init_hooks", - "set disconnect callback")) + "set disconnect callback")) return false; stat = add_listener(ca, PROPERTY_FORMATS); if (!ca_success(stat, ca, "coreaudio_init_hooks", - "set format change callback")) + "set format change callback")) return false; if (ca->default_device) { AudioObjectPropertyAddress addr = { PROPERTY_DEFAULT_DEVICE, kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; + kAudioObjectPropertyElementMaster}; stat = AudioObjectAddPropertyListener(kAudioObjectSystemObject, - &addr, notification_callback, ca); + &addr, + notification_callback, + ca); if (!ca_success(stat, ca, "coreaudio_init_hooks", - "set device change callback")) + "set device change callback")) return false; } stat = set_property(ca->unit, kAudioOutputUnitProperty_SetInputCallback, - SCOPE_GLOBAL, 0, &callback_info, sizeof(callback_info)); + SCOPE_GLOBAL, 0, &callback_info, + sizeof(callback_info)); if (!ca_success(stat, ca, "coreaudio_init_hooks", "set input callback")) return false; @@ -464,32 +471,29 @@ static bool coreaudio_init_hooks(struct coreaudio_data *ca) static void coreaudio_remove_hooks(struct coreaudio_data *ca) { - AURenderCallbackStruct callback_info = { - .inputProc = NULL, - .inputProcRefCon = NULL - }; + AURenderCallbackStruct callback_info = {.inputProc = NULL, + .inputProcRefCon = NULL}; - AudioObjectPropertyAddress addr = { - kAudioDevicePropertyDeviceIsAlive, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; + AudioObjectPropertyAddress addr = {kAudioDevicePropertyDeviceIsAlive, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster}; AudioObjectRemovePropertyListener(ca->device_id, &addr, - notification_callback, ca); + notification_callback, ca); addr.mSelector = PROPERTY_FORMATS; AudioObjectRemovePropertyListener(ca->device_id, &addr, - notification_callback, ca); + notification_callback, ca); if (ca->default_device) { addr.mSelector = PROPERTY_DEFAULT_DEVICE; AudioObjectRemovePropertyListener(kAudioObjectSystemObject, - &addr, notification_callback, ca); + &addr, notification_callback, + ca); } set_property(ca->unit, kAudioOutputUnitProperty_SetInputCallback, - SCOPE_GLOBAL, 0, &callback_info, sizeof(callback_info)); + SCOPE_GLOBAL, 0, &callback_info, sizeof(callback_info)); } static bool coreaudio_get_device_name(struct coreaudio_data *ca) @@ -501,21 +505,22 @@ static bool coreaudio_get_device_name(struct coreaudio_data *ca) const AudioObjectPropertyAddress addr = { kAudioDevicePropertyDeviceNameCFString, kAudioObjectPropertyScopeInput, - kAudioObjectPropertyElementMaster - }; + kAudioObjectPropertyElementMaster}; - OSStatus stat = AudioObjectGetPropertyData(ca->device_id, &addr, - 0, NULL, &size, &cf_name); + OSStatus stat = AudioObjectGetPropertyData(ca->device_id, &addr, 0, + NULL, &size, &cf_name); if (stat != noErr) { - blog(LOG_WARNING, "[coreaudio_get_device_name] failed to " - "get name: %d", (int)stat); + blog(LOG_WARNING, + "[coreaudio_get_device_name] failed to " + "get name: %d", + (int)stat); return false; } name = cfstr_copy_cstr(cf_name, kCFStringEncodingUTF8); if (!name) { blog(LOG_WARNING, "[coreaudio_get_device_name] failed to " - "convert name to cstr for some reason"); + "convert name to cstr for some reason"); return false; } @@ -555,9 +560,8 @@ static void coreaudio_stop(struct coreaudio_data *ca) static bool coreaudio_init_unit(struct coreaudio_data *ca) { AudioComponentDescription desc = { - .componentType = kAudioUnitType_Output, - .componentSubType = kAudioUnitSubType_HALOutput - }; + .componentType = kAudioUnitType_Output, + .componentSubType = kAudioUnitSubType_HALOutput}; AudioComponent component = AudioComponentFindNext(NULL, &desc); if (!component) { @@ -596,7 +600,8 @@ static bool coreaudio_init(struct coreaudio_data *ca) goto fail; stat = set_property(ca->unit, kAudioOutputUnitProperty_CurrentDevice, - SCOPE_GLOBAL, 0, &ca->device_id, sizeof(ca->device_id)); + SCOPE_GLOBAL, 0, &ca->device_id, + sizeof(ca->device_id)); if (!ca_success(stat, ca, "coreaudio_init", "set current device")) goto fail; @@ -625,9 +630,10 @@ fail: static void coreaudio_try_init(struct coreaudio_data *ca) { if (!coreaudio_init(ca)) { - blog(LOG_INFO, "coreaudio: failed to find device " - "uid: %s, waiting for connection", - ca->device_uid); + blog(LOG_INFO, + "coreaudio: failed to find device " + "uid: %s, waiting for connection", + ca->device_uid); ca->retry_time = 2000; @@ -723,20 +729,22 @@ static void coreaudio_defaults(obs_data_t *settings) } static void *coreaudio_create(obs_data_t *settings, obs_source_t *source, - bool input) + bool input) { struct coreaudio_data *ca = bzalloc(sizeof(struct coreaudio_data)); if (os_event_init(&ca->exit_event, OS_EVENT_TYPE_MANUAL) != 0) { - blog(LOG_ERROR, "[coreaudio_create] failed to create " - "semephore: %d", errno); + blog(LOG_ERROR, + "[coreaudio_create] failed to create " + "semephore: %d", + errno); bfree(ca); return NULL; } ca->device_uid = bstrdup(obs_data_get_string(settings, "device_id")); - ca->source = source; - ca->input = input; + ca->source = source; + ca->input = input; if (!ca->device_uid) ca->device_uid = bstrdup("default"); @@ -746,38 +754,39 @@ static void *coreaudio_create(obs_data_t *settings, obs_source_t *source, } static void *coreaudio_create_input_capture(obs_data_t *settings, - obs_source_t *source) + obs_source_t *source) { return coreaudio_create(settings, source, true); } static void *coreaudio_create_output_capture(obs_data_t *settings, - obs_source_t *source) + obs_source_t *source) { return coreaudio_create(settings, source, false); } static obs_properties_t *coreaudio_properties(bool input) { - obs_properties_t *props = obs_properties_create(); - obs_property_t *property; + obs_properties_t *props = obs_properties_create(); + obs_property_t *property; struct device_list devices; memset(&devices, 0, sizeof(struct device_list)); property = obs_properties_add_list(props, "device_id", TEXT_DEVICE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); coreaudio_enum_devices(&devices, input); if (devices.items.num) obs_property_list_add_string(property, TEXT_DEVICE_DEFAULT, - "default"); + "default"); for (size_t i = 0; i < devices.items.num; i++) { - struct device_item *item = devices.items.array+i; - obs_property_list_add_string(property, - item->name.array, item->value.array); + struct device_item *item = devices.items.array + i; + obs_property_list_add_string(property, item->name.array, + item->value.array); } device_list_free(&devices); @@ -799,28 +808,26 @@ static obs_properties_t *coreaudio_output_properties(void *unused) } struct obs_source_info coreaudio_input_capture_info = { - .id = "coreaudio_input_capture", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_AUDIO | - OBS_SOURCE_DO_NOT_DUPLICATE, - .get_name = coreaudio_input_getname, - .create = coreaudio_create_input_capture, - .destroy = coreaudio_destroy, - .update = coreaudio_update, - .get_defaults = coreaudio_defaults, - .get_properties = coreaudio_input_properties + .id = "coreaudio_input_capture", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_AUDIO | OBS_SOURCE_DO_NOT_DUPLICATE, + .get_name = coreaudio_input_getname, + .create = coreaudio_create_input_capture, + .destroy = coreaudio_destroy, + .update = coreaudio_update, + .get_defaults = coreaudio_defaults, + .get_properties = coreaudio_input_properties, }; struct obs_source_info coreaudio_output_capture_info = { - .id = "coreaudio_output_capture", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_AUDIO | - OBS_SOURCE_DO_NOT_DUPLICATE | - OBS_SOURCE_DO_NOT_SELF_MONITOR, - .get_name = coreaudio_output_getname, - .create = coreaudio_create_output_capture, - .destroy = coreaudio_destroy, - .update = coreaudio_update, - .get_defaults = coreaudio_defaults, - .get_properties = coreaudio_output_properties + .id = "coreaudio_output_capture", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_AUDIO | OBS_SOURCE_DO_NOT_DUPLICATE | + OBS_SOURCE_DO_NOT_SELF_MONITOR, + .get_name = coreaudio_output_getname, + .create = coreaudio_create_output_capture, + .destroy = coreaudio_destroy, + .update = coreaudio_update, + .get_defaults = coreaudio_defaults, + .get_properties = coreaudio_output_properties, }; diff --git a/plugins/mac-capture/mac-display-capture.m b/plugins/mac-capture/mac-display-capture.m index 67fd56e..392a7a7 100644 --- a/plugins/mac-capture/mac-display-capture.m +++ b/plugins/mac-capture/mac-display-capture.m @@ -120,16 +120,15 @@ static inline void update_window_params(struct display_capture *dc) if (!requires_window(dc->crop)) return; - NSArray *arr = (NSArray*)CGWindowListCopyWindowInfo( - kCGWindowListOptionIncludingWindow, - dc->window.window_id); - + NSArray *arr = (NSArray *)CGWindowListCopyWindowInfo( + kCGWindowListOptionIncludingWindow, dc->window.window_id); + if (arr.count) { NSDictionary *dict = arr[0]; - NSDictionary *ref = dict[(NSString*)kCGWindowBounds]; + NSDictionary *ref = dict[(NSString *)kCGWindowBounds]; CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)ref, - &dc->window_rect); - dc->on_screen = dict[(NSString*)kCGWindowIsOnscreen] != nil; + &dc->window_rect); + dc->on_screen = dict[(NSString *)kCGWindowIsOnscreen] != nil; dc->window_rect = [dc->screen convertRectToBacking:dc->window_rect]; @@ -144,8 +143,10 @@ static inline void update_window_params(struct display_capture *dc) } static inline void display_stream_update(struct display_capture *dc, - CGDisplayStreamFrameStatus status, uint64_t display_time, - IOSurfaceRef frame_surface, CGDisplayStreamUpdateRef update_ref) + CGDisplayStreamFrameStatus status, + uint64_t display_time, + IOSurfaceRef frame_surface, + CGDisplayStreamUpdateRef update_ref) { UNUSED_PARAMETER(display_time); UNUSED_PARAMETER(update_ref); @@ -176,8 +177,7 @@ static inline void display_stream_update(struct display_capture *dc, size_t dropped_frames = CGDisplayStreamUpdateGetDropCount(update_ref); if (dropped_frames > 0) blog(LOG_INFO, "%s: Dropped %zu frames", - obs_source_get_name(dc->source), - dropped_frames); + obs_source_get_name(dc->source), dropped_frames); } static bool init_display_stream(struct display_capture *dc) @@ -192,38 +192,34 @@ static bool init_display_stream(struct display_capture *dc) NSNumber *screen_num = dc->screen.deviceDescription[@"NSScreenNumber"]; CGDirectDisplayID disp_id = (CGDirectDisplayID)screen_num.pointerValue; - NSDictionary *rect_dict = CFBridgingRelease( - CGRectCreateDictionaryRepresentation( - CGRectMake(0, 0, - dc->screen.frame.size.width, - dc->screen.frame.size.height))); + NSDictionary *rect_dict = + CFBridgingRelease(CGRectCreateDictionaryRepresentation( + CGRectMake(0, 0, dc->screen.frame.size.width, + dc->screen.frame.size.height))); - CFBooleanRef show_cursor_cf = - dc->hide_cursor ? kCFBooleanFalse : kCFBooleanTrue; + CFBooleanRef show_cursor_cf = dc->hide_cursor ? kCFBooleanFalse + : kCFBooleanTrue; NSDictionary *dict = @{ - (__bridge NSString*)kCGDisplayStreamSourceRect: rect_dict, - (__bridge NSString*)kCGDisplayStreamQueueDepth: @5, - (__bridge NSString*)kCGDisplayStreamShowCursor: - (id)show_cursor_cf, + (__bridge NSString *)kCGDisplayStreamSourceRect: rect_dict, + (__bridge NSString *)kCGDisplayStreamQueueDepth: @5, + (__bridge NSString *) + kCGDisplayStreamShowCursor: (id)show_cursor_cf, }; os_event_init(&dc->disp_finished, OS_EVENT_TYPE_MANUAL); const CGSize *size = &dc->frame.size; - dc->disp = CGDisplayStreamCreateWithDispatchQueue(disp_id, - size->width, size->height, 'BGRA', - (__bridge CFDictionaryRef)dict, - dispatch_queue_create(NULL, NULL), - ^(CGDisplayStreamFrameStatus status, - uint64_t displayTime, - IOSurfaceRef frameSurface, - CGDisplayStreamUpdateRef updateRef) - { - display_stream_update(dc, status, displayTime, - frameSurface, updateRef); - } - ); + dc->disp = CGDisplayStreamCreateWithDispatchQueue( + disp_id, size->width, size->height, 'BGRA', + (__bridge CFDictionaryRef)dict, + dispatch_queue_create(NULL, NULL), + ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, + IOSurfaceRef frameSurface, + CGDisplayStreamUpdateRef updateRef) { + display_stream_update(dc, status, displayTime, + frameSurface, updateRef); + }); return !CGDisplayStreamStart(dc->disp); } @@ -252,8 +248,7 @@ bool init_vertbuf(struct display_capture *dc) void load_crop(struct display_capture *dc, obs_data_t *settings); -static void *display_capture_create(obs_data_t *settings, - obs_source_t *source) +static void *display_capture_create(obs_data_t *settings, obs_source_t *source) { UNUSED_PARAMETER(source); UNUSED_PARAMETER(settings); @@ -303,25 +298,24 @@ fail: } static void build_sprite(struct gs_vb_data *data, float fcx, float fcy, - float start_u, float end_u, float start_v, float end_v) + float start_u, float end_u, float start_v, float end_v) { struct vec2 *tvarray = data->tvarray[0].array; - vec3_set(data->points+1, fcx, 0.0f, 0.0f); - vec3_set(data->points+2, 0.0f, fcy, 0.0f); - vec3_set(data->points+3, fcx, fcy, 0.0f); - vec2_set(tvarray, start_u, start_v); - vec2_set(tvarray+1, end_u, start_v); - vec2_set(tvarray+2, start_u, end_v); - vec2_set(tvarray+3, end_u, end_v); + vec3_set(data->points + 1, fcx, 0.0f, 0.0f); + vec3_set(data->points + 2, 0.0f, fcy, 0.0f); + vec3_set(data->points + 3, fcx, fcy, 0.0f); + vec2_set(tvarray, start_u, start_v); + vec2_set(tvarray + 1, end_u, start_v); + vec2_set(tvarray + 2, start_u, end_v); + vec2_set(tvarray + 3, end_u, end_v); } -static inline void build_sprite_rect(struct gs_vb_data *data, - float origin_x, float origin_y, float end_x, float end_y) +static inline void build_sprite_rect(struct gs_vb_data *data, float origin_x, + float origin_y, float end_x, float end_y) { build_sprite(data, fabs(end_x - origin_x), fabs(end_y - origin_y), - origin_x, end_x, - origin_y, end_y); + origin_x, end_x, origin_y, end_y); } static void display_capture_video_tick(void *data, float seconds) @@ -348,8 +342,8 @@ static void display_capture_video_tick(void *data, float seconds) if (requires_window(dc->crop) && !dc->on_screen) goto cleanup; - CGPoint origin = { 0.f }; - CGPoint end = { 0.f }; + CGPoint origin = {0.f}; + CGPoint end = {0.f}; switch (dc->crop) { float x, y; @@ -379,10 +373,9 @@ static void display_capture_video_tick(void *data, float seconds) break; } - obs_enter_graphics(); - build_sprite_rect(gs_vertexbuffer_get_data(dc->vertbuf), - origin.x, origin.y, end.x, end.y); + build_sprite_rect(gs_vertexbuffer_get_data(dc->vertbuf), origin.x, + origin.y, end.x, end.y); if (dc->tex) gs_texture_rebind_iosurface(dc->tex, dc->prev); @@ -412,7 +405,7 @@ static void display_capture_video_render(void *data, gs_effect_t *effect) gs_load_samplerstate(dc->sampler, 0); gs_technique_t *tech = gs_effect_get_technique(dc->effect, "Draw"); gs_effect_set_texture(gs_effect_get_param_by_name(dc->effect, "image"), - dc->tex); + dc->tex); gs_technique_begin(tech); gs_technique_begin_pass(tech, 0); @@ -428,9 +421,9 @@ static const char *display_capture_getname(void *unused) return obs_module_text("DisplayCapture"); } -#define CROPPED_LENGTH(rect, origin_, length) \ - fabs((rect ## .size. ## length - dc->crop_rect.size. ## length) - \ - (rect ## .origin. ## origin_ + dc->crop_rect.origin. ## origin_)) +#define CROPPED_LENGTH(rect, origin_, length) \ + fabs((rect##.size.##length - dc->crop_rect.size.##length) - \ + (rect##.origin.##origin_ + dc->crop_rect.origin.##origin_)) static uint32_t display_capture_getwidth(void *data) { @@ -502,20 +495,20 @@ void load_crop(struct display_capture *dc, obs_data_t *settings) #define CROP_VAR_NAME(var, mode) (mode "." #var) #define LOAD_CROP_VAR(var, mode) \ - dc->crop_rect.var = obs_data_get_double(settings, \ - CROP_VAR_NAME(var, mode)); + dc->crop_rect.var = \ + obs_data_get_double(settings, CROP_VAR_NAME(var, mode)); switch (dc->crop) { case CROP_MANUAL: - LOAD_CROP_VAR(origin.x, "manual"); - LOAD_CROP_VAR(origin.y, "manual"); - LOAD_CROP_VAR(size.width, "manual"); + LOAD_CROP_VAR(origin.x, "manual"); + LOAD_CROP_VAR(origin.y, "manual"); + LOAD_CROP_VAR(size.width, "manual"); LOAD_CROP_VAR(size.height, "manual"); break; case CROP_TO_WINDOW_AND_MANUAL: - LOAD_CROP_VAR(origin.x, "window"); - LOAD_CROP_VAR(origin.y, "window"); - LOAD_CROP_VAR(size.width, "window"); + LOAD_CROP_VAR(origin.x, "window"); + LOAD_CROP_VAR(origin.y, "window"); + LOAD_CROP_VAR(size.width, "window"); LOAD_CROP_VAR(size.height, "window"); break; @@ -552,7 +545,7 @@ static void display_capture_update(void *data, obs_data_t *settings) } static bool switch_crop_mode(obs_properties_t *props, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { UNUSED_PARAMETER(p); @@ -561,20 +554,20 @@ static bool switch_crop_mode(obs_properties_t *props, obs_property_t *p, const char *name; bool visible; -#define LOAD_CROP_VAR(var, mode) \ +#define LOAD_CROP_VAR(var, mode) \ name = CROP_VAR_NAME(var, mode); \ obs_property_set_visible(obs_properties_get(props, name), visible); visible = crop == CROP_MANUAL; - LOAD_CROP_VAR(origin.x, "manual"); - LOAD_CROP_VAR(origin.y, "manual"); - LOAD_CROP_VAR(size.width, "manual"); + LOAD_CROP_VAR(origin.x, "manual"); + LOAD_CROP_VAR(origin.y, "manual"); + LOAD_CROP_VAR(size.width, "manual"); LOAD_CROP_VAR(size.height, "manual"); visible = crop == CROP_TO_WINDOW_AND_MANUAL; - LOAD_CROP_VAR(origin.x, "window"); - LOAD_CROP_VAR(origin.y, "window"); - LOAD_CROP_VAR(size.width, "window"); + LOAD_CROP_VAR(origin.x, "window"); + LOAD_CROP_VAR(origin.y, "window"); + LOAD_CROP_VAR(size.width, "window"); LOAD_CROP_VAR(size.height, "window"); #undef LOAD_CROP_VAR @@ -582,15 +575,12 @@ static bool switch_crop_mode(obs_properties_t *props, obs_property_t *p, return true; } -static const char *crop_names[] = { - "CropMode.None", - "CropMode.Manual", - "CropMode.ToWindow", - "CropMode.ToWindowAndManual" -}; +static const char *crop_names[] = {"CropMode.None", "CropMode.Manual", + "CropMode.ToWindow", + "CropMode.ToWindowAndManual"}; #ifndef COUNTOF -#define COUNTOF(x) (sizeof(x)/sizeof(x[0])) +#define COUNTOF(x) (sizeof(x) / sizeof(x[0])) #endif static obs_properties_t *display_capture_properties(void *unused) { @@ -598,9 +588,9 @@ static obs_properties_t *display_capture_properties(void *unused) obs_properties_t *props = obs_properties_create(); - obs_property_t *list = obs_properties_add_list(props, - "display", obs_module_text("DisplayCapture.Display"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_t *list = obs_properties_add_list( + props, "display", obs_module_text("DisplayCapture.Display"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); for (unsigned i = 0; i < [NSScreen screens].count; i++) { char buf[10]; @@ -609,11 +599,11 @@ static obs_properties_t *display_capture_properties(void *unused) } obs_properties_add_bool(props, "show_cursor", - obs_module_text("DisplayCapture.ShowCursor")); + obs_module_text("DisplayCapture.ShowCursor")); - obs_property_t *crop = obs_properties_add_list(props, "crop_mode", - obs_module_text("CropMode"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_t *crop = obs_properties_add_list( + props, "crop_mode", obs_module_text("CropMode"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); obs_property_set_modified_callback(crop, switch_crop_mode); for (unsigned i = 0; i < COUNTOF(crop_names); i++) { @@ -627,22 +617,22 @@ static obs_properties_t *display_capture_properties(void *unused) obs_property_t *p; const char *name; float min; -#define LOAD_CROP_VAR(var, mode) \ - name = CROP_VAR_NAME(var, mode); \ - p = obs_properties_add_float(props, name, \ - obs_module_text("Crop."#var), min, 4096.f, .5f); \ +#define LOAD_CROP_VAR(var, mode) \ + name = CROP_VAR_NAME(var, mode); \ + p = obs_properties_add_float( \ + props, name, obs_module_text("Crop." #var), min, 4096.f, .5f); \ obs_property_set_visible(p, false); min = 0.f; - LOAD_CROP_VAR(origin.x, "manual"); - LOAD_CROP_VAR(origin.y, "manual"); - LOAD_CROP_VAR(size.width, "manual"); + LOAD_CROP_VAR(origin.x, "manual"); + LOAD_CROP_VAR(origin.y, "manual"); + LOAD_CROP_VAR(size.width, "manual"); LOAD_CROP_VAR(size.height, "manual"); min = -4096.f; - LOAD_CROP_VAR(origin.x, "window"); - LOAD_CROP_VAR(origin.y, "window"); - LOAD_CROP_VAR(size.width, "window"); + LOAD_CROP_VAR(origin.x, "window"); + LOAD_CROP_VAR(origin.y, "window"); + LOAD_CROP_VAR(size.width, "window"); LOAD_CROP_VAR(size.height, "window"); #undef LOAD_CROP_VAR @@ -650,22 +640,22 @@ static obs_properties_t *display_capture_properties(void *unused) } struct obs_source_info display_capture_info = { - .id = "display_capture", - .type = OBS_SOURCE_TYPE_INPUT, - .get_name = display_capture_getname, + .id = "display_capture", + .type = OBS_SOURCE_TYPE_INPUT, + .get_name = display_capture_getname, - .create = display_capture_create, - .destroy = display_capture_destroy, + .create = display_capture_create, + .destroy = display_capture_destroy, - .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW | - OBS_SOURCE_DO_NOT_DUPLICATE, - .video_tick = display_capture_video_tick, - .video_render = display_capture_video_render, + .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW | + OBS_SOURCE_DO_NOT_DUPLICATE, + .video_tick = display_capture_video_tick, + .video_render = display_capture_video_render, - .get_width = display_capture_getwidth, - .get_height = display_capture_getheight, + .get_width = display_capture_getwidth, + .get_height = display_capture_getheight, - .get_defaults = display_capture_defaults, + .get_defaults = display_capture_defaults, .get_properties = display_capture_properties, - .update = display_capture_update, + .update = display_capture_update, }; diff --git a/plugins/mac-capture/mac-window-capture.m b/plugins/mac-capture/mac-window-capture.m index 48f2da7..110ff4d 100644 --- a/plugins/mac-capture/mac-window-capture.m +++ b/plugins/mac-capture/mac-window-capture.m @@ -21,61 +21,59 @@ struct window_capture { DARRAY(uint8_t) buffer; - pthread_t capture_thread; + pthread_t capture_thread; os_event_t *capture_event; os_event_t *stop_event; }; static CGImageRef get_image(struct window_capture *wc) { - NSArray *arr = (NSArray*)CGWindowListCreate( - kCGWindowListOptionIncludingWindow, - wc->window.window_id); + NSArray *arr = (NSArray *)CGWindowListCreate( + kCGWindowListOptionIncludingWindow, wc->window.window_id); [arr autorelease]; if (arr.count) - return CGWindowListCreateImage(CGRectNull, - kCGWindowListOptionIncludingWindow, - wc->window.window_id, wc->image_option); + return CGWindowListCreateImage( + CGRectNull, kCGWindowListOptionIncludingWindow, + wc->window.window_id, wc->image_option); if (!find_window(&wc->window, NULL, false)) return NULL; return CGWindowListCreateImage(CGRectNull, - kCGWindowListOptionIncludingWindow, - wc->window.window_id, wc->image_option); + kCGWindowListOptionIncludingWindow, + wc->window.window_id, wc->image_option); } static inline void capture_frame(struct window_capture *wc) { - uint64_t ts = os_gettime_ns(); + uint64_t ts = os_gettime_ns(); CGImageRef img = get_image(wc); if (!img) return; - size_t width = CGImageGetWidth(img); + size_t width = CGImageGetWidth(img); size_t height = CGImageGetHeight(img); CGRect rect = {{0, 0}, {width, height}}; da_reserve(wc->buffer, width * height * 4); uint8_t *data = wc->buffer.array; - CGContextRef cg_context = CGBitmapContextCreate(data, width, height, - 8, width * 4, wc->color_space, - kCGBitmapByteOrder32Host | - kCGImageAlphaPremultipliedFirst); + CGContextRef cg_context = CGBitmapContextCreate( + data, width, height, 8, width * 4, wc->color_space, + kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst); CGContextSetBlendMode(cg_context, kCGBlendModeCopy); CGContextDrawImage(cg_context, rect, img); CGContextRelease(cg_context); CGImageRelease(img); struct obs_source_frame frame = { - .format = VIDEO_FORMAT_BGRA, - .width = width, - .height = height, - .data[0] = data, + .format = VIDEO_FORMAT_BGRA, + .width = width, + .height = height, + .data[0] = data, .linesize[0] = width * 4, - .timestamp = ts, + .timestamp = ts, }; obs_source_output_video(wc->source, &frame); @@ -99,7 +97,7 @@ static void *capture_thread(void *data) } static inline void *window_capture_create_internal(obs_data_t *settings, - obs_source_t *source) + obs_source_t *source) { struct window_capture *wc = bzalloc(sizeof(struct window_capture)); @@ -111,8 +109,9 @@ static inline void *window_capture_create_internal(obs_data_t *settings, init_window(&wc->window, settings); - wc->image_option = obs_data_get_bool(settings, "show_shadow") ? - kCGWindowImageDefault : kCGWindowImageBoundsIgnoreFraming; + wc->image_option = obs_data_get_bool(settings, "show_shadow") + ? kCGWindowImageDefault + : kCGWindowImageBoundsIgnoreFraming; os_event_init(&wc->capture_event, OS_EVENT_TYPE_AUTO); os_event_init(&wc->stop_event, OS_EVENT_TYPE_MANUAL); @@ -135,7 +134,7 @@ static void window_capture_destroy(void *data) os_event_signal(cap->stop_event); os_event_signal(cap->capture_event); - + pthread_join(cap->capture_thread, NULL); CGColorSpaceRelease(cap->color_space); @@ -165,26 +164,28 @@ static obs_properties_t *window_capture_properties(void *unused) add_window_properties(props); obs_properties_add_bool(props, "show_shadow", - obs_module_text("WindowCapture.ShowShadow")); + obs_module_text("WindowCapture.ShowShadow")); return props; } static inline void window_capture_update_internal(struct window_capture *wc, - obs_data_t *settings) + obs_data_t *settings) { - wc->image_option = obs_data_get_bool(settings, "show_shadow") ? - kCGWindowImageDefault : kCGWindowImageBoundsIgnoreFraming; + wc->image_option = obs_data_get_bool(settings, "show_shadow") + ? kCGWindowImageDefault + : kCGWindowImageBoundsIgnoreFraming; update_window(&wc->window, settings); if (wc->window.window_name.length) { - blog(LOG_INFO, "[window-capture: '%s'] update settings:\n" - "\twindow: %s\n" - "\towner: %s", - obs_source_get_name(wc->source), - [wc->window.window_name UTF8String], - [wc->window.owner_name UTF8String]); + blog(LOG_INFO, + "[window-capture: '%s'] update settings:\n" + "\twindow: %s\n" + "\towner: %s", + obs_source_get_name(wc->source), + [wc->window.window_name UTF8String], + [wc->window.owner_name UTF8String]); } } @@ -202,7 +203,7 @@ static const char *window_capture_getname(void *unused) } static inline void window_capture_tick_internal(struct window_capture *wc, - float seconds) + float seconds) { UNUSED_PARAMETER(seconds); os_event_signal(wc->capture_event); @@ -221,17 +222,17 @@ static void window_capture_tick(void *data, float seconds) } struct obs_source_info window_capture_info = { - .id = "window_capture", - .type = OBS_SOURCE_TYPE_INPUT, - .get_name = window_capture_getname, + .id = "window_capture", + .type = OBS_SOURCE_TYPE_INPUT, + .get_name = window_capture_getname, - .create = window_capture_create, - .destroy = window_capture_destroy, + .create = window_capture_create, + .destroy = window_capture_destroy, - .output_flags = OBS_SOURCE_ASYNC_VIDEO, - .video_tick = window_capture_tick, + .output_flags = OBS_SOURCE_ASYNC_VIDEO, + .video_tick = window_capture_tick, - .get_defaults = window_capture_defaults, + .get_defaults = window_capture_defaults, .get_properties = window_capture_properties, - .update = window_capture_update, + .update = window_capture_update, }; diff --git a/plugins/mac-capture/window-utils.h b/plugins/mac-capture/window-utils.h index bdc3ed2..da0743a 100644 --- a/plugins/mac-capture/window-utils.h +++ b/plugins/mac-capture/window-utils.h @@ -5,11 +5,11 @@ #include struct cocoa_window { - CGWindowID window_id; + CGWindowID window_id; pthread_mutex_t name_lock; - NSString *owner_name; - NSString *window_name; + NSString *owner_name; + NSString *window_name; uint64_t next_search_time; }; diff --git a/plugins/mac-capture/window-utils.m b/plugins/mac-capture/window-utils.m index d2a1978..0380df6 100644 --- a/plugins/mac-capture/window-utils.m +++ b/plugins/mac-capture/window-utils.m @@ -2,13 +2,12 @@ #include -#define WINDOW_NAME ((NSString*)kCGWindowName) -#define WINDOW_NUMBER ((NSString*)kCGWindowNumber) -#define OWNER_NAME ((NSString*)kCGWindowOwnerName) -#define OWNER_PID ((NSNumber*)kCGWindowOwnerPID) +#define WINDOW_NAME ((NSString *)kCGWindowName) +#define WINDOW_NUMBER ((NSString *)kCGWindowNumber) +#define OWNER_NAME ((NSString *)kCGWindowOwnerName) +#define OWNER_PID ((NSNumber *)kCGWindowOwnerPID) -static NSComparator win_info_cmp = ^(NSDictionary *o1, NSDictionary *o2) -{ +static NSComparator win_info_cmp = ^(NSDictionary *o1, NSDictionary *o2) { NSComparisonResult res = [o1[OWNER_NAME] compare:o2[OWNER_NAME]]; if (res != NSOrderedSame) return res; @@ -26,9 +25,8 @@ static NSComparator win_info_cmp = ^(NSDictionary *o1, NSDictionary *o2) NSArray *enumerate_windows(void) { - NSArray *arr = (NSArray*)CGWindowListCopyWindowInfo( - kCGWindowListOptionOnScreenOnly, - kCGNullWindowID); + NSArray *arr = (NSArray *)CGWindowListCopyWindowInfo( + kCGWindowListOptionOnScreenOnly, kCGNullWindowID); [arr autorelease]; @@ -60,8 +58,8 @@ bool find_window(cocoa_window_t cw, obs_data_t *settings, bool force) pthread_mutex_unlock(&cw->name_lock); - NSNumber *window_id = (NSNumber*)dict[WINDOW_NUMBER]; - cw->window_id = window_id.intValue; + NSNumber *window_id = (NSNumber *)dict[WINDOW_NUMBER]; + cw->window_id = window_id.intValue; obs_data_set_int(settings, "window", cw->window_id); return true; @@ -76,9 +74,9 @@ void init_window(cocoa_window_t cw, obs_data_t *settings) { pthread_mutex_init(&cw->name_lock, NULL); - cw->owner_name = @(obs_data_get_string(settings, "owner_name")); + cw->owner_name = @(obs_data_get_string(settings, "owner_name")); cw->window_name = @(obs_data_get_string(settings, "window_name")); - [cw->owner_name retain]; + [cw->owner_name retain]; [cw->window_name retain]; find_window(cw, settings, true); } @@ -86,22 +84,22 @@ void init_window(cocoa_window_t cw, obs_data_t *settings) void destroy_window(cocoa_window_t cw) { pthread_mutex_destroy(&cw->name_lock); - [cw->owner_name release]; + [cw->owner_name release]; [cw->window_name release]; } void update_window(cocoa_window_t cw, obs_data_t *settings) { pthread_mutex_lock(&cw->name_lock); - [cw->owner_name release]; + [cw->owner_name release]; [cw->window_name release]; - cw->owner_name = @(obs_data_get_string(settings, "owner_name")); - cw->window_name = @(obs_data_get_string(settings, "window_name")); - [cw->owner_name retain]; + cw->owner_name = @(obs_data_get_string(settings, "owner_name")); + cw->window_name = @(obs_data_get_string(settings, "window_name")); + [cw->owner_name retain]; [cw->window_name retain]; pthread_mutex_unlock(&cw->name_lock); - cw->window_id = obs_data_get_int(settings, "window"); + cw->window_id = obs_data_get_int(settings, "window"); } static inline const char *make_name(NSString *owner, NSString *name) @@ -116,7 +114,7 @@ static inline const char *make_name(NSString *owner, NSString *name) static inline NSDictionary *find_window_dict(NSArray *arr, int window_id) { for (NSDictionary *dict in arr) { - NSNumber *wid = (NSNumber*)dict[WINDOW_NUMBER]; + NSNumber *wid = (NSNumber *)dict[WINDOW_NUMBER]; if (wid.intValue == window_id) return dict; } @@ -125,12 +123,11 @@ static inline NSDictionary *find_window_dict(NSArray *arr, int window_id) } static inline bool window_changed_internal(obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { - int window_id = obs_data_get_int(settings, "window"); + int window_id = obs_data_get_int(settings, "window"); NSString *window_owner = @(obs_data_get_string(settings, "owner_name")); - NSString *window_name = - @(obs_data_get_string(settings, "window_name")); + NSString *window_name = @(obs_data_get_string(settings, "window_name")); NSDictionary *win_info = @{ OWNER_NAME: window_owner, @@ -147,39 +144,38 @@ static inline bool window_changed_internal(obs_property_t *p, obs_property_list_clear(p); for (NSDictionary *dict in arr) { - NSString *owner = (NSString*)dict[OWNER_NAME]; - NSString *name = (NSString*)dict[WINDOW_NAME]; - NSNumber *wid = (NSNumber*)dict[WINDOW_NUMBER]; + NSString *owner = (NSString *)dict[OWNER_NAME]; + NSString *name = (NSString *)dict[WINDOW_NAME]; + NSNumber *wid = (NSNumber *)dict[WINDOW_NUMBER]; if (!window_added && - win_info_cmp(win_info, dict) == NSOrderedAscending) { + win_info_cmp(win_info, dict) == NSOrderedAscending) { window_added = true; - size_t idx = obs_property_list_add_int(p, - make_name(window_owner, window_name), - window_id); + size_t idx = obs_property_list_add_int( + p, make_name(window_owner, window_name), + window_id); obs_property_list_item_disable(p, idx, true); } if (!show_empty_names && !name.length && - window_id != wid.intValue) + window_id != wid.intValue) continue; obs_property_list_add_int(p, make_name(owner, name), - wid.intValue); + wid.intValue); } if (!window_added) { - size_t idx = obs_property_list_add_int(p, - make_name(window_owner, window_name), - window_id); + size_t idx = obs_property_list_add_int( + p, make_name(window_owner, window_name), window_id); obs_property_list_item_disable(p, idx, true); } if (!window_found) return true; - NSString *owner = (NSString*)cur[OWNER_NAME]; - NSString *window = (NSString*)cur[WINDOW_NAME]; + NSString *owner = (NSString *)cur[OWNER_NAME]; + NSString *window = (NSString *)cur[WINDOW_NAME]; obs_data_set_string(settings, "owner_name", owner.UTF8String); obs_data_set_string(settings, "window_name", window.UTF8String); @@ -188,7 +184,7 @@ static inline bool window_changed_internal(obs_property_t *p, } static bool window_changed(obs_properties_t *props, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { UNUSED_PARAMETER(props); @@ -198,12 +194,12 @@ static bool window_changed(obs_properties_t *props, obs_property_t *p, } static bool toggle_empty_names(obs_properties_t *props, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { UNUSED_PARAMETER(p); return window_changed(props, obs_properties_get(props, "window"), - settings); + settings); } void window_defaults(obs_data_t *settings) @@ -214,20 +210,20 @@ void window_defaults(obs_data_t *settings) void add_window_properties(obs_properties_t *props) { - obs_property_t *window_list = obs_properties_add_list(props, - "window", obs_module_text("WindowUtils.Window"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_t *window_list = obs_properties_add_list( + props, "window", obs_module_text("WindowUtils.Window"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); obs_property_set_modified_callback(window_list, window_changed); - obs_property_t *empty = obs_properties_add_bool(props, - "show_empty_names", - obs_module_text("WindowUtils.ShowEmptyNames")); + obs_property_t *empty = obs_properties_add_bool( + props, "show_empty_names", + obs_module_text("WindowUtils.ShowEmptyNames")); obs_property_set_modified_callback(empty, toggle_empty_names); } void show_window_properties(obs_properties_t *props, bool show) { obs_property_set_visible(obs_properties_get(props, "window"), show); - obs_property_set_visible( - obs_properties_get(props, "show_empty_names"), show); + obs_property_set_visible(obs_properties_get(props, "show_empty_names"), + show); } diff --git a/plugins/mac-syphon/data/locale/de-DE.ini b/plugins/mac-syphon/data/locale/de-DE.ini index eb3e43c..3e03adb 100644 --- a/plugins/mac-syphon/data/locale/de-DE.ini +++ b/plugins/mac-syphon/data/locale/de-DE.ini @@ -1,9 +1,9 @@ -Syphon="Syphon-Client" +Syphon="Syphon‐Client" Source="Quelle" LaunchSyphonInject="SyphonInject starten" Inject="Injizieren" Application="Anwendung" -SyphonLicense="Syphon-Lizenz" +SyphonLicense="Syphon‐Lizenz" Crop="Zuschneiden" Crop.origin.x="Links abschneiden" Crop.origin.y="Oben abschneiden" diff --git a/plugins/mac-syphon/data/locale/gl-ES.ini b/plugins/mac-syphon/data/locale/gl-ES.ini index 27b87bb..01d3ec5 100644 --- a/plugins/mac-syphon/data/locale/gl-ES.ini +++ b/plugins/mac-syphon/data/locale/gl-ES.ini @@ -1,12 +1,13 @@ +Syphon="Cliente Syphon" Source="Fonte" -LaunchSyphonInject="Lanzar SyphonInject" +LaunchSyphonInject="Iniciar SyphonInject" Inject="Inxectar" -Application="Aplicación" +Application="Aplicativo" SyphonLicense="Licenza Syphon" Crop="Recortar" -Crop.origin.x="Recortar á esquerda" -Crop.origin.y="Recortar arriba" -Crop.size.width="Recortar á dereita" -Crop.size.height="Recortar abaixo" +Crop.origin.x="Recortar pola esquerda" +Crop.origin.y="Recortar por riba" +Crop.size.width="Recortar pola dereita" +Crop.size.height="Recortar por baixo" AllowTransparency="Permitir transparencia" diff --git a/plugins/mac-syphon/data/locale/sl-SI.ini b/plugins/mac-syphon/data/locale/sl-SI.ini index c56cc7c..a366828 100644 --- a/plugins/mac-syphon/data/locale/sl-SI.ini +++ b/plugins/mac-syphon/data/locale/sl-SI.ini @@ -2,7 +2,7 @@ Source="Vir" LaunchSyphonInject="Zaženi SyphonInject" Inject="Vstavi" Application="Aplikacija" -SyphonLicense="Syphon Licenca" +SyphonLicense="Licenca za Syphon" Crop="Obreži" Crop.origin.x="Obreži levo" Crop.origin.y="Obreži vrh" diff --git a/plugins/mac-syphon/syphon.m b/plugins/mac-syphon/syphon.m index 6f53264..0dfe60e 100644 --- a/plugins/mac-syphon/syphon.m +++ b/plugins/mac-syphon/syphon.m @@ -3,40 +3,41 @@ #import "syphon-framework/Syphon.h" #include -#define LOG(level, message, ...) \ - blog(level, "%s: " message, obs_source_get_name(s->source), ##__VA_ARGS__) +#define LOG(level, message, ...) \ + blog(level, "%s: " message, obs_source_get_name(s->source), \ + ##__VA_ARGS__) struct syphon { SYPHON_CLIENT_UNIQUE_CLASS_NAME *client; IOSurfaceRef ref; gs_samplerstate_t *sampler; - gs_effect_t *effect; - gs_vertbuffer_t *vertbuffer; - gs_texture_t *tex; - uint32_t width, height; - bool crop; - CGRect crop_rect; - bool allow_transparency; + gs_effect_t *effect; + gs_vertbuffer_t *vertbuffer; + gs_texture_t *tex; + uint32_t width, height; + bool crop; + CGRect crop_rect; + bool allow_transparency; obs_source_t *source; bool active; bool uuid_changed; - id new_server_listener; - id retire_listener; + id new_server_listener; + id retire_listener; NSString *app_name; NSString *name; NSString *uuid; obs_data_t *inject_info; - NSString *inject_app; - NSString *inject_uuid; - bool inject_active; - id launch_listener; - bool inject_server_found; - float inject_wait_time; + NSString *inject_app; + NSString *inject_uuid; + bool inject_active; + id launch_listener; + bool inject_server_found; + float inject_wait_time; }; typedef struct syphon *syphon_t; @@ -55,9 +56,9 @@ static inline void find_and_inject_target(syphon_t s, NSArray *arr, bool retry); @interface OBSSyphonKVObserver : NSObject - (void)observeValueForKeyPath:(NSString *)keyPath - ofObject:(id)object - change:(NSDictionary *)change - context:(void *)context; + ofObject:(id)object + change:(NSDictionary *)change + context:(void *)context; @end static inline void handle_application_launch(syphon_t s, NSArray *new) @@ -73,9 +74,9 @@ static inline void handle_application_launch(syphon_t s, NSArray *new) @implementation OBSSyphonKVObserver - (void)observeValueForKeyPath:(NSString *)keyPath - ofObject:(id)object - change:(NSDictionary *)change - context:(void *)context + ofObject:(id)object + change:(NSDictionary *)change + context:(void *)context { UNUSED_PARAMETER(keyPath); UNUSED_PARAMETER(object); @@ -117,7 +118,7 @@ static void stop_client(syphon_t s) s->ref = NULL; } - s->width = 0; + s->width = 0; s->height = 0; obs_leave_graphics(); @@ -143,8 +144,10 @@ static inline void check_version(syphon_t s, NSDictionary *desc) "VersionKey"); if (version.unsignedIntValue > 0) - LOG(LOG_WARNING, "Got server description version %d, " - "expected 0", version.unsignedIntValue); + LOG(LOG_WARNING, + "Got server description version %d, " + "expected 0", + version.unsignedIntValue); } static inline void check_description(syphon_t s, NSDictionary *desc) @@ -169,9 +172,10 @@ static inline void check_description(syphon_t s, NSDictionary *desc) } NSString *surfaces_string = [NSString stringWithFormat:@"%@", surfaces]; - LOG(LOG_WARNING, "SyphonSurfaces does not contain" - "'SyphonSurfaceTypeIOSurface': %s", - surfaces_string.UTF8String); + LOG(LOG_WARNING, + "SyphonSurfaces does not contain" + "'SyphonSurfaceTypeIOSurface': %s", + surfaces_string.UTF8String); } static inline bool update_string(NSString **str, NSString *new) @@ -185,7 +189,7 @@ static inline bool update_string(NSString **str, NSString *new) } static inline void handle_new_frame(syphon_t s, - SYPHON_CLIENT_UNIQUE_CLASS_NAME *client) + SYPHON_CLIENT_UNIQUE_CLASS_NAME *client) { IOSurfaceRef ref = [client IOSurface]; @@ -206,9 +210,9 @@ static inline void handle_new_frame(syphon_t s, CFRelease(s->ref); } - s->ref = ref; - s->tex = gs_texture_create_from_iosurface(s->ref); - s->width = gs_texture_get_width(s->tex); + s->ref = ref; + s->tex = gs_texture_create_from_iosurface(s->ref); + s->width = gs_texture_get_width(s->tex); s->height = gs_texture_get_height(s->tex); obs_leave_graphics(); } @@ -230,7 +234,7 @@ static void create_client(syphon_t s) if (!desc) { desc = servers[0]; if (update_string(&s->uuid, - desc[SyphonServerDescriptionUUIDKey])) + desc[SyphonServerDescriptionUUIDKey])) s->uuid_changed = true; } @@ -241,11 +245,11 @@ static void create_client(syphon_t s) s->client = [[SYPHON_CLIENT_UNIQUE_CLASS_NAME alloc] initWithServerDescription:desc options:nil - newFrameHandler:^ - (SYPHON_CLIENT_UNIQUE_CLASS_NAME *client) - { - handle_new_frame(s, client); - }]; + newFrameHandler:^( + SYPHON_CLIENT_UNIQUE_CLASS_NAME + *client) { + handle_new_frame(s, client); + }]; } s->active = true; @@ -254,27 +258,27 @@ static void create_client(syphon_t s) static inline void release_settings(syphon_t s) { [s->app_name release]; - [s->name release]; - [s->uuid release]; + [s->name release]; + [s->uuid release]; } static inline bool load_syphon_settings(syphon_t s, obs_data_t *settings) { NSString *app_name = @(obs_data_get_string(settings, "app_name")); - NSString *name = @(obs_data_get_string(settings, "name")); - bool equal_names = [app_name isEqual:s->app_name] && - [name isEqual:s->name]; + NSString *name = @(obs_data_get_string(settings, "name")); + bool equal_names = [app_name isEqual:s->app_name] && + [name isEqual:s->name]; if (s->uuid_changed && equal_names) return false; - NSString *uuid = @(obs_data_get_string(settings, "uuid")); + NSString *uuid = @(obs_data_get_string(settings, "uuid")); if ([uuid isEqual:s->uuid] && equal_names) return false; release_settings(s); - s->app_name = [app_name retain]; - s->name = [name retain]; - s->uuid = [uuid retain]; + s->app_name = [app_name retain]; + s->name = [name retain]; + s->uuid = [uuid retain]; s->uuid_changed = false; return true; } @@ -288,15 +292,15 @@ static inline void update_from_announce(syphon_t s, NSDictionary *info) return; NSString *app_name = info[SyphonServerDescriptionAppNameKey]; - NSString *name = info[SyphonServerDescriptionNameKey]; - NSString *uuid = info[SyphonServerDescriptionUUIDKey]; + NSString *name = info[SyphonServerDescriptionNameKey]; + NSString *uuid = info[SyphonServerDescriptionUUIDKey]; if (![uuid isEqual:s->uuid] && - !([app_name isEqual:s->app_name] && [name isEqual:s->name])) + !([app_name isEqual:s->app_name] && [name isEqual:s->name])) return; update_string(&s->app_name, app_name); - update_string(&s->name, name); + update_string(&s->name, name); if (update_string(&s->uuid, uuid)) s->uuid_changed = true; @@ -304,27 +308,28 @@ static inline void update_from_announce(syphon_t s, NSDictionary *info) } static inline void update_inject_state(syphon_t s, NSDictionary *info, - bool announce) + bool announce) { if (!info) return; NSString *app_name = info[SyphonServerDescriptionAppNameKey]; - NSString *name = info[SyphonServerDescriptionNameKey]; - NSString *uuid = info[SyphonServerDescriptionUUIDKey]; + NSString *name = info[SyphonServerDescriptionNameKey]; + NSString *uuid = info[SyphonServerDescriptionUUIDKey]; if (![uuid isEqual:s->inject_uuid] && - (![app_name isEqual:s->inject_app] - || ![name isEqual:@"InjectedSyphon"])) + (![app_name isEqual:s->inject_app] || + ![name isEqual:@"InjectedSyphon"])) return; if (!(s->inject_server_found = announce)) { s->inject_wait_time = 0.f; objc_release(&s->inject_uuid); - LOG(LOG_INFO, "Injected server retired: " - "[%s] InjectedSyphon (%s)", - s->inject_app.UTF8String, uuid.UTF8String); + LOG(LOG_INFO, + "Injected server retired: " + "[%s] InjectedSyphon (%s)", + s->inject_app.UTF8String, uuid.UTF8String); return; } @@ -333,8 +338,7 @@ static inline void update_inject_state(syphon_t s, NSDictionary *info, s->inject_uuid = [uuid retain]; LOG(LOG_INFO, "Injected server found: [%s] %s (%s)", - app_name.UTF8String, name.UTF8String, - uuid.UTF8String); + app_name.UTF8String, name.UTF8String, uuid.UTF8String); } static inline void handle_announce(syphon_t s, NSNotification *note) @@ -406,15 +410,15 @@ fail_tvarray: static inline bool init_obs_graphics_objects(syphon_t s) { struct gs_sampler_info info = { - .filter = GS_FILTER_LINEAR, - .address_u = GS_ADDRESS_CLAMP, - .address_v = GS_ADDRESS_CLAMP, - .address_w = GS_ADDRESS_CLAMP, + .filter = GS_FILTER_LINEAR, + .address_u = GS_ADDRESS_CLAMP, + .address_v = GS_ADDRESS_CLAMP, + .address_w = GS_ADDRESS_CLAMP, .max_anisotropy = 1, }; obs_enter_graphics(); - s->sampler = gs_samplerstate_create(&info); + s->sampler = gs_samplerstate_create(&info); s->vertbuffer = create_vertbuffer(); obs_leave_graphics(); @@ -426,25 +430,21 @@ static inline bool init_obs_graphics_objects(syphon_t s) static inline bool create_syphon_listeners(syphon_t s) { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - s->new_server_listener = [nc + s->new_server_listener = [nc addObserverForName:SyphonServerAnnounceNotification object:nil queue:[NSOperationQueue mainQueue] - usingBlock:^(NSNotification *note) - { - handle_announce(s, note); - } - ]; + usingBlock:^(NSNotification *note) { + handle_announce(s, note); + }]; - s->retire_listener = [nc + s->retire_listener = [nc addObserverForName:SyphonServerRetireNotification object:nil queue:[NSOperationQueue mainQueue] - usingBlock:^(NSNotification *note) - { - handle_retire(s, note); - } - ]; + usingBlock:^(NSNotification *note) { + handle_retire(s, note); + }]; return s->new_server_listener != nil && s->retire_listener != nil; } @@ -456,9 +456,9 @@ static inline bool create_applications_observer(syphon_t s, NSWorkspace *ws) return false; [ws addObserver:s->launch_listener - forKeyPath:NSStringFromSelector(@selector(runningApplications)) - options:NSKeyValueObservingOptionNew - context:s]; + forKeyPath:NSStringFromSelector(@selector(runningApplications)) + options:NSKeyValueObservingOptionNew + context:s]; return true; } @@ -467,8 +467,7 @@ static inline void load_crop(syphon_t s, obs_data_t *settings) { s->crop = obs_data_get_bool(settings, "crop"); -#define LOAD_CROP(x) \ - s->crop_rect.x = obs_data_get_double(settings, "crop." #x) +#define LOAD_CROP(x) s->crop_rect.x = obs_data_get_double(settings, "crop." #x) LOAD_CROP(origin.x); LOAD_CROP(origin.y); LOAD_CROP(size.width); @@ -486,7 +485,7 @@ static void *syphon_create_internal(obs_data_t *settings, obs_source_t *source) if (!s) return s; - s->source = source; + s->source = source; if (!init_obs_graphics_objects(s)) goto fail; @@ -495,9 +494,9 @@ static void *syphon_create_internal(obs_data_t *settings, obs_source_t *source) goto fail; const char *inject_info = obs_data_get_string(settings, "application"); - s->inject_info = obs_data_create_from_json(inject_info); - s->inject_active = obs_data_get_bool(settings, "inject"); - s->inject_app = @(obs_data_get_string(s->inject_info, "name")); + s->inject_info = obs_data_create_from_json(inject_info); + s->inject_active = obs_data_get_bool(settings, "inject"); + s->inject_app = @(obs_data_get_string(s->inject_info, "name")); if (s->inject_app) [s->inject_app retain]; @@ -516,8 +515,8 @@ static void *syphon_create_internal(obs_data_t *settings, obs_source_t *source) load_crop(s, settings); - s->allow_transparency = obs_data_get_bool(settings, - "allow_transparency"); + s->allow_transparency = + obs_data_get_bool(settings, "allow_transparency"); return s; @@ -549,7 +548,8 @@ static inline void syphon_destroy_internal(syphon_t s) NSWorkspace *ws = [NSWorkspace sharedWorkspace]; [ws removeObserver:s->launch_listener - forKeyPath:NSStringFromSelector(@selector(runningApplications))]; + forKeyPath:NSStringFromSelector(@selector + (runningApplications))]; objc_release(&s->launch_listener); objc_release(&s->inject_app); @@ -561,7 +561,7 @@ static inline void syphon_destroy_internal(syphon_t s) obs_enter_graphics(); stop_client(s); - + if (s->sampler) gs_samplerstate_destroy(s->sampler); if (s->vertbuffer) @@ -587,44 +587,45 @@ static inline NSString *get_string(obs_data_t *settings, const char *name) } static inline void update_strings_from_context(syphon_t s, obs_data_t *settings, - NSString **app, NSString **name, NSString **uuid) + NSString **app, NSString **name, + NSString **uuid) { if (!s || !s->uuid_changed) return; s->uuid_changed = false; - *app = s->app_name; + *app = s->app_name; *name = s->name; *uuid = s->uuid; obs_data_set_string(settings, "app_name", s->app_name.UTF8String); - obs_data_set_string(settings, "name", s->name.UTF8String); - obs_data_set_string(settings, "uuid", s->uuid.UTF8String); + obs_data_set_string(settings, "name", s->name.UTF8String); + obs_data_set_string(settings, "uuid", s->uuid.UTF8String); } static inline void add_servers(syphon_t s, obs_property_t *list, - obs_data_t *settings) + obs_data_t *settings) { bool found_current = settings == NULL; - NSString *set_app = get_string(settings, "app_name"); + NSString *set_app = get_string(settings, "app_name"); NSString *set_name = get_string(settings, "name"); NSString *set_uuid = get_string(settings, "uuid"); - update_strings_from_context(s, settings, - &set_app, &set_name, &set_uuid); + update_strings_from_context(s, settings, &set_app, &set_name, + &set_uuid); obs_property_list_add_string(list, "", ""); NSArray *arr = [[SyphonServerDirectory sharedDirectory] servers]; for (NSDictionary *server in arr) { - NSString *app = server[SyphonServerDescriptionAppNameKey]; + NSString *app = server[SyphonServerDescriptionAppNameKey]; NSString *name = server[SyphonServerDescriptionNameKey]; NSString *uuid = server[SyphonServerDescriptionUUIDKey]; - NSString *serv = [NSString stringWithFormat:@"[%@] %@", - app, name]; + NSString *serv = + [NSString stringWithFormat:@"[%@] %@", app, name]; - obs_property_list_add_string(list, - serv.UTF8String, uuid.UTF8String); + obs_property_list_add_string(list, serv.UTF8String, + uuid.UTF8String); if (!found_current) found_current = [uuid isEqual:set_uuid]; @@ -633,15 +634,15 @@ static inline void add_servers(syphon_t s, obs_property_t *list, if (found_current || !set_uuid.length || !set_app.length) return; - NSString *serv = [NSString stringWithFormat:@"[%@] %@", - set_app, set_name]; - size_t idx = obs_property_list_add_string(list, - serv.UTF8String, set_uuid.UTF8String); + NSString *serv = + [NSString stringWithFormat:@"[%@] %@", set_app, set_name]; + size_t idx = obs_property_list_add_string(list, serv.UTF8String, + set_uuid.UTF8String); obs_property_list_item_disable(list, idx, true); } static bool servers_changed(obs_properties_t *props, obs_property_t *list, - obs_data_t *settings) + obs_data_t *settings) { @autoreleasepool { obs_property_list_clear(list); @@ -662,16 +663,15 @@ static inline bool is_inject_available_in_lib_dir(NSFileManager *fm, NSURL *url) if (!url.isFileURL) return false; - for (NSString *path in [fm - contentsOfDirectoryAtPath:url.path - error:nil]) { + for (NSString *path in [fm contentsOfDirectoryAtPath:url.path + error:nil]) { NSURL *bundle_url = [url URLByAppendingPathComponent:path]; - NSBundle *bundle = [NSBundle bundleWithURL:bundle_url]; + NSBundle *bundle = [NSBundle bundleWithURL:bundle_url]; if (!bundle) continue; if ([bundle.bundleIdentifier - isEqual:@"zakk.lol.SASyphonInjector"]) + isEqual:@"zakk.lol.SASyphonInjector"]) return true; } @@ -705,7 +705,7 @@ static inline void launch_syphon_inject_internal() } static bool launch_syphon_inject(obs_properties_t *props, obs_property_t *prop, - void *data) + void *data) { UNUSED_PARAMETER(props); UNUSED_PARAMETER(prop); @@ -720,13 +720,13 @@ static bool launch_syphon_inject(obs_properties_t *props, obs_property_t *prop, static int describes_app(obs_data_t *info, NSRunningApplication *app) { int score = 0; - if ([app.localizedName isEqual:get_string(info, "name")]) + if ([app.localizedName isEqual:get_string(info, "name")]) score += 2; if ([app.bundleIdentifier isEqual:get_string(info, "bundle")]) score += 2; - if ([app.executableURL isEqual:get_string(info, "executable")]) + if ([app.executableURL isEqual:get_string(info, "executable")]) score += 2; if (score && app.processIdentifier == obs_data_get_int(info, "pid")) @@ -739,10 +739,10 @@ static inline void app_to_data(NSRunningApplication *app, obs_data_t *app_data) { obs_data_set_string(app_data, "name", app.localizedName.UTF8String); obs_data_set_string(app_data, "bundle", - app.bundleIdentifier.UTF8String); + app.bundleIdentifier.UTF8String); // Until we drop 10.8, use path.fileSystemRepsentation obs_data_set_string(app_data, "executable", - app.executableURL.path.fileSystemRepresentation); + app.executableURL.path.fileSystemRepresentation); obs_data_set_int(app_data, "pid", app.processIdentifier); } @@ -760,8 +760,9 @@ static inline NSDictionary *get_duplicate_names(NSArray *apps) } static inline size_t add_app(obs_property_t *prop, NSDictionary *duplicates, - NSString *name, const char *bundle, const char *json_data, - bool is_duplicate, pid_t pid) + NSString *name, const char *bundle, + const char *json_data, bool is_duplicate, + pid_t pid) { if (!is_duplicate) { NSNumber *val = duplicates[name]; @@ -769,20 +770,21 @@ static inline size_t add_app(obs_property_t *prop, NSDictionary *duplicates, } if (is_duplicate) - name = [NSString stringWithFormat:@"%@ (%s: %d)", - name, bundle, pid]; + name = [NSString + stringWithFormat:@"%@ (%s: %d)", name, bundle, pid]; return obs_property_list_add_string(prop, name.UTF8String, json_data); } static void update_inject_list_internal(obs_properties_t *props, - obs_property_t *prop, obs_data_t *settings) + obs_property_t *prop, + obs_data_t *settings) { UNUSED_PARAMETER(props); - const char *current_str = obs_data_get_string(settings, "application"); - obs_data_t *current = obs_data_create_from_json(current_str); - NSString *current_name = @(obs_data_get_string(current, "name")); + const char *current_str = obs_data_get_string(settings, "application"); + obs_data_t *current = obs_data_create_from_json(current_str); + NSString *current_name = @(obs_data_get_string(current, "name")); bool current_found = !obs_data_has_user_value(current, "name"); @@ -790,10 +792,10 @@ static void update_inject_list_internal(obs_properties_t *props, obs_property_list_add_string(prop, "", ""); NSWorkspace *ws = [NSWorkspace sharedWorkspace]; - NSArray *apps = ws.runningApplications; + NSArray *apps = ws.runningApplications; NSDictionary *duplicates = get_duplicate_names(apps); - NSMapTable *candidates = [NSMapTable weakToStrongObjectsMapTable]; + NSMapTable *candidates = [NSMapTable weakToStrongObjectsMapTable]; obs_data_t *app_data = obs_data_create(); for (NSRunningApplication *app in apps) { @@ -801,11 +803,10 @@ static void update_inject_list_internal(obs_properties_t *props, int score = describes_app(current, app); NSString *name = app.localizedName; - add_app(prop, duplicates, name, - app.bundleIdentifier.UTF8String, - obs_data_get_json(app_data), - [name isEqual:current_name] && score < 4, - app.processIdentifier); + add_app(prop, duplicates, name, app.bundleIdentifier.UTF8String, + obs_data_get_json(app_data), + [name isEqual:current_name] && score < 4, + app.processIdentifier); if (score >= 4) { [candidates setObject:@(score) forKey:app]; @@ -816,10 +817,10 @@ static void update_inject_list_internal(obs_properties_t *props, if (!current_found) { size_t idx = add_app(prop, duplicates, current_name, - obs_data_get_string(current, "bundle"), - current_str, - duplicates[current_name] != nil, - obs_data_get_int(current, "pid")); + obs_data_get_string(current, "bundle"), + current_str, + duplicates[current_name] != nil, + obs_data_get_int(current, "pid")); obs_property_list_item_disable(prop, idx, true); } else if (candidates.count > 0) { @@ -829,7 +830,7 @@ static void update_inject_list_internal(obs_properties_t *props, for (NSRunningApplication *app in candidates.keyEnumerator) { NSNumber *score = [candidates objectForKey:app]; if ([score compare:best_match_score] == - NSOrderedDescending) { + NSOrderedDescending) { best_match = app; best_match_score = score; } @@ -839,7 +840,7 @@ static void update_inject_list_internal(obs_properties_t *props, if (best_match_score.intValue >= 4) { app_to_data(best_match, current); obs_data_set_string(settings, "application", - obs_data_get_json(current)); + obs_data_get_json(current)); } } @@ -847,7 +848,7 @@ static void update_inject_list_internal(obs_properties_t *props, } static void toggle_inject_internal(obs_properties_t *props, - obs_property_t *prop, obs_data_t *settings) + obs_property_t *prop, obs_data_t *settings) { bool enabled = obs_data_get_bool(settings, "inject"); obs_property_t *inject_list = obs_properties_get(props, "application"); @@ -857,7 +858,7 @@ static void toggle_inject_internal(obs_properties_t *props, } static bool toggle_inject(obs_properties_t *props, obs_property_t *prop, - obs_data_t *settings) + obs_data_t *settings) { @autoreleasepool { toggle_inject_internal(props, prop, settings); @@ -866,7 +867,7 @@ static bool toggle_inject(obs_properties_t *props, obs_property_t *prop, } static bool update_inject_list(obs_properties_t *props, obs_property_t *prop, - obs_data_t *settings) + obs_data_t *settings) { @autoreleasepool { update_inject_list_internal(props, prop, settings); @@ -875,11 +876,11 @@ static bool update_inject_list(obs_properties_t *props, obs_property_t *prop, } static bool update_crop(obs_properties_t *props, obs_property_t *prop, - obs_data_t *settings) + obs_data_t *settings) { bool enabled = obs_data_get_bool(settings, "crop"); -#define LOAD_CROP(x) \ +#define LOAD_CROP(x) \ prop = obs_properties_get(props, "crop." #x); \ obs_property_set_enabled(prop, enabled); LOAD_CROP(origin.x); @@ -903,7 +904,7 @@ static void show_syphon_license_internal(void) } static bool show_syphon_license(obs_properties_t *props, obs_property_t *prop, - void *data) + void *data) { UNUSED_PARAMETER(props); UNUSED_PARAMETER(prop); @@ -928,28 +929,28 @@ static inline obs_properties_t *syphon_properties_internal(syphon_t s) if (s) obs_source_addref(s->source); - obs_properties_t *props = obs_properties_create_param(s, - syphon_release); + obs_properties_t *props = + obs_properties_create_param(s, syphon_release); - obs_property_t *list = obs_properties_add_list(props, - "uuid", obs_module_text("Source"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + obs_property_t *list = obs_properties_add_list( + props, "uuid", obs_module_text("Source"), OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_set_modified_callback(list, servers_changed); obs_properties_add_bool(props, "allow_transparency", - obs_module_text("AllowTransparency")); + obs_module_text("AllowTransparency")); - obs_property_t *launch = obs_properties_add_button(props, - "launch inject", obs_module_text("LaunchSyphonInject"), - launch_syphon_inject); + obs_property_t *launch = obs_properties_add_button( + props, "launch inject", obs_module_text("LaunchSyphonInject"), + launch_syphon_inject); - obs_property_t *inject = obs_properties_add_bool(props, - "inject", obs_module_text("Inject")); + obs_property_t *inject = obs_properties_add_bool( + props, "inject", obs_module_text("Inject")); obs_property_set_modified_callback(inject, toggle_inject); - obs_property_t *inject_list = obs_properties_add_list(props, - "application", obs_module_text("Application"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + obs_property_t *inject_list = obs_properties_add_list( + props, "application", obs_module_text("Application"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); obs_property_set_modified_callback(inject_list, update_inject_list); if (!get_inject_application_path()) @@ -960,13 +961,14 @@ static inline obs_properties_t *syphon_properties_internal(syphon_t s) obs_property_set_enabled(inject_list, false); } - obs_property_t *crop = obs_properties_add_bool(props, "crop", - obs_module_text("Crop")); + obs_property_t *crop = + obs_properties_add_bool(props, "crop", obs_module_text("Crop")); obs_property_set_modified_callback(crop, update_crop); -#define LOAD_CROP(x) \ - obs_properties_add_float(props, "crop." #x, \ - obs_module_text("Crop." #x), 0., 4096.f, .5f); +#define LOAD_CROP(x) \ + obs_properties_add_float(props, "crop." #x, \ + obs_module_text("Crop." #x), 0., 4096.f, \ + .5f); LOAD_CROP(origin.x); LOAD_CROP(origin.y); LOAD_CROP(size.width); @@ -974,8 +976,8 @@ static inline obs_properties_t *syphon_properties_internal(syphon_t s) #undef LOAD_CROP obs_properties_add_button(props, "syphon license", - obs_module_text("SyphonLicense"), - show_syphon_license); + obs_module_text("SyphonLicense"), + show_syphon_license); return props; } @@ -993,8 +995,8 @@ static inline void syphon_save_internal(syphon_t s, obs_data_t *settings) return; obs_data_set_string(settings, "app_name", s->app_name.UTF8String); - obs_data_set_string(settings, "name", s->name.UTF8String); - obs_data_set_string(settings, "uuid", s->uuid.UTF8String); + obs_data_set_string(settings, "name", s->name.UTF8String); + obs_data_set_string(settings, "uuid", s->uuid.UTF8String); } static void syphon_save(void *data, obs_data_t *settings) @@ -1005,25 +1007,25 @@ static void syphon_save(void *data, obs_data_t *settings) } static inline void build_sprite(struct gs_vb_data *data, float fcx, float fcy, - float start_u, float end_u, float start_v, float end_v) + float start_u, float end_u, float start_v, + float end_v) { struct vec2 *tvarray = data->tvarray[0].array; - vec3_set(data->points+1, fcx, 0.0f, 0.0f); - vec3_set(data->points+2, 0.0f, fcy, 0.0f); - vec3_set(data->points+3, fcx, fcy, 0.0f); - vec2_set(tvarray, start_u, start_v); - vec2_set(tvarray+1, end_u, start_v); - vec2_set(tvarray+2, start_u, end_v); - vec2_set(tvarray+3, end_u, end_v); + vec3_set(data->points + 1, fcx, 0.0f, 0.0f); + vec3_set(data->points + 2, 0.0f, fcy, 0.0f); + vec3_set(data->points + 3, fcx, fcy, 0.0f); + vec2_set(tvarray, start_u, start_v); + vec2_set(tvarray + 1, end_u, start_v); + vec2_set(tvarray + 2, start_u, end_v); + vec2_set(tvarray + 3, end_u, end_v); } -static inline void build_sprite_rect(struct gs_vb_data *data, - float origin_x, float origin_y, float end_x, float end_y) +static inline void build_sprite_rect(struct gs_vb_data *data, float origin_x, + float origin_y, float end_x, float end_y) { build_sprite(data, fabs(end_x - origin_x), fabs(end_y - origin_y), - origin_x, end_x, - origin_y, end_y); + origin_x, end_x, origin_y, end_y); } static inline void tick_inject_state(syphon_t s, float seconds) @@ -1050,17 +1052,15 @@ static void syphon_video_tick(void *data, float seconds) if (!s->tex) return; - static const CGRect null_crop = { { 0.f } }; + static const CGRect null_crop = {{0.f}}; const CGRect *crop = &null_crop; if (s->crop) crop = &s->crop_rect; obs_enter_graphics(); build_sprite_rect(gs_vertexbuffer_get_data(s->vertbuffer), - crop->origin.x, - s->height - crop->origin.y, - s->width - crop->size.width, - crop->size.height); + crop->origin.x, s->height - crop->origin.y, + s->width - crop->size.width, crop->size.height); obs_leave_graphics(); } @@ -1085,7 +1085,7 @@ static void syphon_video_render(void *data, gs_effect_t *effect) gs_load_samplerstate(s->sampler, 0); gs_technique_t *tech = gs_effect_get_technique(s->effect, "Draw"); gs_effect_set_texture(gs_effect_get_param_by_name(s->effect, "image"), - s->tex); + s->tex); gs_technique_begin(tech); gs_technique_begin_pass(tech, 0); @@ -1105,9 +1105,8 @@ static uint32_t syphon_get_width(void *data) syphon_t s = (syphon_t)data; if (!s->crop) return s->width; - int32_t width = s->width - - s->crop_rect.origin.x - - s->crop_rect.size.width; + int32_t width = + s->width - s->crop_rect.origin.x - s->crop_rect.size.width; return MAX(0, width); } @@ -1116,9 +1115,8 @@ static uint32_t syphon_get_height(void *data) syphon_t s = (syphon_t)data; if (!s->crop) return s->height; - int32_t height = s->height - - s->crop_rect.origin.y - - s->crop_rect.size.height; + int32_t height = + s->height - s->crop_rect.origin.y - s->crop_rect.size.height; return MAX(0, height); } @@ -1134,9 +1132,9 @@ static inline void inject_app(syphon_t s, NSRunningApplication *app, bool retry) if (!sbapp) return LOG(LOG_ERROR, "Could not inject %s", - app.localizedName.UTF8String); + app.localizedName.UTF8String); - sbapp.timeout = 10*60; + sbapp.timeout = 10 * 60; sbapp.sendMode = kAEWaitReply; [sbapp sendEvent:'ascr' id:'gdut' parameters:0]; sbapp.sendMode = kAENoReply; @@ -1145,9 +1143,8 @@ static inline void inject_app(syphon_t s, NSRunningApplication *app, bool retry) if (retry) return; - LOG(LOG_INFO, "Injected '%s' (%d, '%s')", - app.localizedName.UTF8String, - app.processIdentifier, app.bundleIdentifier.UTF8String); + LOG(LOG_INFO, "Injected '%s' (%d, '%s')", app.localizedName.UTF8String, + app.processIdentifier, app.bundleIdentifier.UTF8String); } static inline void find_and_inject_target(syphon_t s, NSArray *arr, bool retry) @@ -1174,20 +1171,17 @@ static inline void find_and_inject_target(syphon_t s, NSArray *arr, bool retry) static inline bool inject_info_equal(obs_data_t *prev, obs_data_t *new) { - if (![get_string(prev, "name") - isEqual:get_string(new, "name")]) + if (![get_string(prev, "name") isEqual:get_string(new, "name")]) return false; - if (![get_string(prev, "bundle") - isEqual:get_string(new, "bundle")]) + if (![get_string(prev, "bundle") isEqual:get_string(new, "bundle")]) return false; if (![get_string(prev, "executable") - isEqual:get_string(new, "executable")]) + isEqual:get_string(new, "executable")]) return false; - if (![get_string(prev, "pid") - isEqual:get_string(new, "pid")]) + if (![get_string(prev, "pid") isEqual:get_string(new, "pid")]) return false; return true; @@ -1195,15 +1189,15 @@ static inline bool inject_info_equal(obs_data_t *prev, obs_data_t *new) static inline void update_inject(syphon_t s, obs_data_t *settings) { - bool try_injecting = s->inject_active; - s->inject_active = obs_data_get_bool(settings, "inject"); + bool try_injecting = s->inject_active; + s->inject_active = obs_data_get_bool(settings, "inject"); const char *inject_str = obs_data_get_string(settings, "application"); try_injecting = !try_injecting && s->inject_active; obs_data_t *prev = s->inject_info; s->inject_info = obs_data_create_from_json(inject_str); - + NSString *prev_app = s->inject_app; s->inject_app = [@(obs_data_get_string(s->inject_info, "name")) retain]; [prev_app release]; @@ -1216,10 +1210,10 @@ static inline void update_inject(syphon_t s, obs_data_t *settings) s->inject_server_found = false; for (NSDictionary *server in servers) update_inject_state(s, server, true); - + if (!try_injecting) try_injecting = s->inject_active && - !inject_info_equal(prev, s->inject_info); + !inject_info_equal(prev, s->inject_info); obs_data_release(prev); @@ -1239,15 +1233,15 @@ static inline bool update_syphon(syphon_t s, obs_data_t *settings) NSDictionary *dict = find_by_uuid(arr, s->uuid); if (dict) { - NSString *app = dict[SyphonServerDescriptionAppNameKey]; + NSString *app = dict[SyphonServerDescriptionAppNameKey]; NSString *name = dict[SyphonServerDescriptionNameKey]; obs_data_set_string(settings, "app_name", app.UTF8String); - obs_data_set_string(settings, "name", name.UTF8String); + obs_data_set_string(settings, "name", name.UTF8String); load_syphon_settings(s, settings); } else if (!dict && !s->uuid.length) { obs_data_set_string(settings, "app_name", ""); - obs_data_set_string(settings, "name", ""); + obs_data_set_string(settings, "name", ""); load_syphon_settings(s, settings); } @@ -1256,8 +1250,8 @@ static inline bool update_syphon(syphon_t s, obs_data_t *settings) static void syphon_update_internal(syphon_t s, obs_data_t *settings) { - s->allow_transparency = obs_data_get_bool(settings, - "allow_transparency"); + s->allow_transparency = + obs_data_get_bool(settings, "allow_transparency"); load_crop(s, settings); update_inject(s, settings); @@ -1273,19 +1267,18 @@ static void syphon_update(void *data, obs_data_t *settings) } struct obs_source_info syphon_info = { - .id = "syphon-input", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW | - OBS_SOURCE_DO_NOT_DUPLICATE, - .get_name = syphon_get_name, - .create = syphon_create, - .destroy = syphon_destroy, - .video_render = syphon_video_render, - .video_tick = syphon_video_tick, + .id = "syphon-input", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW | + OBS_SOURCE_DO_NOT_DUPLICATE, + .get_name = syphon_get_name, + .create = syphon_create, + .destroy = syphon_destroy, + .video_render = syphon_video_render, + .video_tick = syphon_video_tick, .get_properties = syphon_properties, - .get_width = syphon_get_width, - .get_height = syphon_get_height, - .update = syphon_update, - .save = syphon_save, + .get_width = syphon_get_width, + .get_height = syphon_get_height, + .update = syphon_update, + .save = syphon_save, }; - diff --git a/plugins/mac-vth264/data/locale/bg-BG.ini b/plugins/mac-vth264/data/locale/bg-BG.ini new file mode 100644 index 0000000..d29b91f --- /dev/null +++ b/plugins/mac-vth264/data/locale/bg-BG.ini @@ -0,0 +1,12 @@ +VTH264EncHW="Хардуерно кодиращо устройство Apple VT H264" +VTH264EncSW="Софтуерно кодиращо устройство Apple VT H264" +Bitrate="Битрейт" +UseMaxBitrate="Ограничаване на битрейта" +MaxBitrate="Макс. битрейт" +MaxBitrateWindow="Прозорец с максимален битрейт (в секунди)" +KeyframeIntervalSec="Интервал за ключови кадри (секунди, 0=автоматично)" +Profile="Профил" +DefaultEncoder="(Стандартно кодиране)" +UseBFrames="Използване на B-кадри" + + diff --git a/plugins/mac-vth264/data/locale/de-DE.ini b/plugins/mac-vth264/data/locale/de-DE.ini index fc0eda5..ed8e421 100644 --- a/plugins/mac-vth264/data/locale/de-DE.ini +++ b/plugins/mac-vth264/data/locale/de-DE.ini @@ -1,14 +1,14 @@ -VTH264EncHW="Apple-VT-H264-Hardware-Kodierer" -VTH264EncSW="Apple-VT-H264-Software-Kodierer" -VTEncoder="VideoToolbox-Kodierer" +VTH264EncHW="Apple‐VT‐H264‐Hardware‐Kodierer" +VTH264EncSW="Apple‐VT‐H264‐Software‐Kodierer" +VTEncoder="VideoToolbox‐Kodierer" Bitrate="Bitrate" UseMaxBitrate="Limitiere Bitrate" MaxBitrate="Max. Bitrate" MaxBitrateWindow="Maximales Bitratenfenster (Sekunden)" -KeyframeIntervalSec="Keyframeintervall (Sekunden, 0 = auto)" +KeyframeIntervalSec="Keyframeintervall in Sek. (0 = automatisch)" Profile="Profil" None="(Nichts)" DefaultEncoder="(Standardkodierer)" -UseBFrames="B-Frames verwenden" +UseBFrames="B‐Frames verwenden" diff --git a/plugins/mac-vth264/data/locale/gl-ES.ini b/plugins/mac-vth264/data/locale/gl-ES.ini index 651bfaf..df0b1c6 100644 --- a/plugins/mac-vth264/data/locale/gl-ES.ini +++ b/plugins/mac-vth264/data/locale/gl-ES.ini @@ -1,12 +1,14 @@ VTH264EncHW="Codificador de hárdware Apple VT H264" VTH264EncSW="Codificador de sóftware Apple VT H264" VTEncoder="Codificador VideoToolbox" -UseMaxBitrate="Limitar velocidade de bits" -MaxBitrate="Velocidade de bits máxima" -MaxBitrateWindow="Xanela de velocidade de bits máxima (segundos)" +Bitrate="Taxa de bits" +UseMaxBitrate="Limitar a taxa de bits" +MaxBitrate="Taxa de bits máxima" +MaxBitrateWindow="Xanela de taxa de bits máxima (segundos)" +KeyframeIntervalSec="Intervalo de fotogramas clave (segundos, 0=auto)" Profile="Perfil" None="(Ningún)" -DefaultEncoder="(Codificador predefinido)" +DefaultEncoder="(Codificador predeterminado)" UseBFrames="Utilizar B-Frames" diff --git a/plugins/mac-vth264/encoder.c b/plugins/mac-vth264/encoder.c index 83137dd..07a05c7 100644 --- a/plugins/mac-vth264/encoder.c +++ b/plugins/mac-vth264/encoder.c @@ -12,13 +12,11 @@ #define VT_LOG(level, format, ...) \ blog(level, "[VideoToolbox encoder]: " format, ##__VA_ARGS__) -#define VT_LOG_ENCODER(encoder, level, format, ...) \ +#define VT_LOG_ENCODER(encoder, level, format, ...) \ blog(level, "[VideoToolbox %s: 'h264']: " format, \ - obs_encoder_get_name(encoder), \ - ##__VA_ARGS__) + obs_encoder_get_name(encoder), ##__VA_ARGS__) #define VT_BLOG(level, format, ...) \ - VT_LOG_ENCODER(enc->encoder, level, format, \ - ##__VA_ARGS__) + VT_LOG_ENCODER(enc->encoder, level, format, ##__VA_ARGS__) // Clipped from NSApplication as it is in a ObjC header extern const double NSAppKitVersionNumber; @@ -28,8 +26,7 @@ extern const double NSAppKitVersionNumber; #define APPLE_H264_ENC_ID_SW "com.apple.videotoolbox.videoencoder.h264" // Get around missing symbol on 10.8 during compilation -enum { - kCMFormatDescriptionBridgeError_InvalidParameter_ = -12712, +enum { kCMFormatDescriptionBridgeError_InvalidParameter_ = -12712, }; static bool is_appkit10_9_or_greater() @@ -44,8 +41,7 @@ static DARRAY(struct vt_encoder { const char *codec_name; }) vt_encoders; -struct vt_h264_encoder -{ +struct vt_h264_encoder { obs_encoder_t *encoder; const char *vt_encoder_id; @@ -74,11 +70,11 @@ struct vt_h264_encoder }; static void log_osstatus(int log_level, struct vt_h264_encoder *enc, - const char *context, OSStatus code) + const char *context, OSStatus code) { char *c_str = NULL; CFErrorRef err = CFErrorCreate(kCFAllocatorDefault, - kCFErrorDomainOSStatus, code, NULL); + kCFErrorDomainOSStatus, code, NULL); CFStringRef str = CFErrorCopyDescription(err); c_str = cfstr_copy_cstr(str, kCFStringEncodingUTF8); @@ -116,17 +112,19 @@ static CFStringRef obs_to_vt_colorspace(enum video_colorspace cs) return NULL; } -#define STATUS_CHECK(c) \ - code = c; \ - if (code) { \ +#define STATUS_CHECK(c) \ + code = c; \ + if (code) { \ log_osstatus(LOG_ERROR, enc, #c, code); \ - goto fail; \ + goto fail; \ } -#define SESSION_CHECK(x) if ((code = (x)) != noErr) return code; +#define SESSION_CHECK(x) \ + if ((code = (x)) != noErr) \ + return code; static OSStatus session_set_prop_int(VTCompressionSessionRef session, - CFStringRef key, int32_t val) + CFStringRef key, int32_t val) { CFNumberRef n = CFNumberCreate(NULL, kCFNumberSInt32Type, &val); OSStatus code = VTSessionSetProperty(session, key, n); @@ -136,7 +134,7 @@ static OSStatus session_set_prop_int(VTCompressionSessionRef session, } static OSStatus session_set_prop_str(VTCompressionSessionRef session, - CFStringRef key, char *val) + CFStringRef key, char *val) { CFStringRef s = CFStringCreateWithFileSystemRepresentation(NULL, val); OSStatus code = VTSessionSetProperty(session, key, s); @@ -146,39 +144,38 @@ static OSStatus session_set_prop_str(VTCompressionSessionRef session, } static OSStatus session_set_prop(VTCompressionSessionRef session, - CFStringRef key, CFTypeRef val) + CFStringRef key, CFTypeRef val) { return VTSessionSetProperty(session, key, val); } static OSStatus session_set_bitrate(VTCompressionSessionRef session, - int new_bitrate, bool limit_bitrate, int max_bitrate, - float max_bitrate_window) + int new_bitrate, bool limit_bitrate, + int max_bitrate, float max_bitrate_window) { OSStatus code; - SESSION_CHECK(session_set_prop_int(session, - kVTCompressionPropertyKey_AverageBitRate, - new_bitrate * 1000)); + SESSION_CHECK(session_set_prop_int( + session, kVTCompressionPropertyKey_AverageBitRate, + new_bitrate * 1000)); if (limit_bitrate) { int32_t cpb_size = max_bitrate * 125 * max_bitrate_window; - CFNumberRef cf_cpb_size = CFNumberCreate(NULL, - kCFNumberIntType, &cpb_size); - CFNumberRef cf_cpb_window_s = CFNumberCreate(NULL, - kCFNumberFloatType, &max_bitrate_window); + CFNumberRef cf_cpb_size = + CFNumberCreate(NULL, kCFNumberIntType, &cpb_size); + CFNumberRef cf_cpb_window_s = CFNumberCreate( + NULL, kCFNumberFloatType, &max_bitrate_window); CFMutableArrayRef rate_control = CFArrayCreateMutable( - kCFAllocatorDefault, 2, - &kCFTypeArrayCallBacks); + kCFAllocatorDefault, 2, &kCFTypeArrayCallBacks); CFArrayAppendValue(rate_control, cf_cpb_size); CFArrayAppendValue(rate_control, cf_cpb_window_s); - code = session_set_prop(session, - kVTCompressionPropertyKey_DataRateLimits, - rate_control); + code = session_set_prop( + session, kVTCompressionPropertyKey_DataRateLimits, + rate_control); CFRelease(cf_cpb_size); CFRelease(cf_cpb_window_s); @@ -186,7 +183,7 @@ static OSStatus session_set_bitrate(VTCompressionSessionRef session, if (code == kVTPropertyNotSupportedErr) { log_osstatus(LOG_WARNING, NULL, - "setting DataRateLimits on session", code); + "setting DataRateLimits on session", code); return noErr; } } @@ -195,21 +192,21 @@ static OSStatus session_set_bitrate(VTCompressionSessionRef session, } static OSStatus session_set_colorspace(VTCompressionSessionRef session, - enum video_colorspace cs) + enum video_colorspace cs) { CFStringRef matrix = obs_to_vt_colorspace(cs); OSStatus code; if (matrix != NULL) { - SESSION_CHECK(session_set_prop(session, - kVTCompressionPropertyKey_ColorPrimaries, - kCVImageBufferColorPrimaries_ITU_R_709_2)); - SESSION_CHECK(session_set_prop(session, - kVTCompressionPropertyKey_TransferFunction, - kCVImageBufferTransferFunction_ITU_R_709_2)); - SESSION_CHECK(session_set_prop(session, - kVTCompressionPropertyKey_YCbCrMatrix, - matrix)); + SESSION_CHECK(session_set_prop( + session, kVTCompressionPropertyKey_ColorPrimaries, + kCVImageBufferColorPrimaries_ITU_R_709_2)); + SESSION_CHECK(session_set_prop( + session, kVTCompressionPropertyKey_TransferFunction, + kCVImageBufferTransferFunction_ITU_R_709_2)); + SESSION_CHECK(session_set_prop( + session, kVTCompressionPropertyKey_YCbCrMatrix, + matrix)); } return noErr; @@ -218,7 +215,8 @@ static OSStatus session_set_colorspace(VTCompressionSessionRef session, #undef SESSION_CHECK void sample_encoded_callback(void *data, void *source, OSStatus status, - VTEncodeInfoFlags info_flags, CMSampleBufferRef buffer) + VTEncodeInfoFlags info_flags, + CMSampleBufferRef buffer) { UNUSED_PARAMETER(status); UNUSED_PARAMETER(info_flags); @@ -231,23 +229,20 @@ void sample_encoded_callback(void *data, void *source, OSStatus status, } CFRelease(pixbuf); } -#define ENCODER_ID \ - kVTVideoEncoderSpecification_EncoderID +#define ENCODER_ID kVTVideoEncoderSpecification_EncoderID #define ENABLE_HW_ACCEL \ kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder #define REQUIRE_HW_ACCEL \ kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder -static inline CFMutableDictionaryRef create_encoder_spec( - const char *vt_encoder_id) +static inline CFMutableDictionaryRef +create_encoder_spec(const char *vt_encoder_id) { CFMutableDictionaryRef encoder_spec = CFDictionaryCreateMutable( - kCFAllocatorDefault, - 3, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + kCFAllocatorDefault, 3, &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); - CFStringRef id = CFStringCreateWithFileSystemRepresentation( - NULL, vt_encoder_id); + CFStringRef id = + CFStringCreateWithFileSystemRepresentation(NULL, vt_encoder_id); CFDictionaryAddValue(encoder_spec, ENCODER_ID, id); CFRelease(id); @@ -260,17 +255,15 @@ static inline CFMutableDictionaryRef create_encoder_spec( #undef REQUIRE_HW_ACCEL #undef ENABLE_HW_ACCEL -static inline CFMutableDictionaryRef create_pixbuf_spec( - struct vt_h264_encoder *enc) +static inline CFMutableDictionaryRef +create_pixbuf_spec(struct vt_h264_encoder *enc) { CFMutableDictionaryRef pixbuf_spec = CFDictionaryCreateMutable( - kCFAllocatorDefault, - 3, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + kCFAllocatorDefault, 3, &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); - CFNumberRef n = CFNumberCreate(NULL, kCFNumberSInt32Type, - &enc->vt_pix_fmt); + CFNumberRef n = + CFNumberCreate(NULL, kCFNumberSInt32Type, &enc->vt_pix_fmt); CFDictionaryAddValue(pixbuf_spec, kCVPixelBufferPixelFormatTypeKey, n); CFRelease(n); @@ -295,22 +288,16 @@ static bool create_encoder(struct vt_h264_encoder *enc) CFDictionaryRef pixbuf_spec = create_pixbuf_spec(enc); STATUS_CHECK(VTCompressionSessionCreate( - kCFAllocatorDefault, - enc->width, - enc->height, - kCMVideoCodecType_H264, - encoder_spec, - pixbuf_spec, - NULL, - &sample_encoded_callback, - enc->queue, - &s)); + kCFAllocatorDefault, enc->width, enc->height, + kCMVideoCodecType_H264, encoder_spec, pixbuf_spec, NULL, + &sample_encoded_callback, enc->queue, &s)); CFRelease(encoder_spec); CFRelease(pixbuf_spec); CFBooleanRef b = NULL; - code = VTSessionCopyProperty(s, + code = VTSessionCopyProperty( + s, kVTCompressionPropertyKey_UsingHardwareAcceleratedVideoEncoder, NULL, &b); @@ -322,35 +309,35 @@ static bool create_encoder(struct vt_h264_encoder *enc) if (b != NULL) CFRelease(b); - STATUS_CHECK(session_set_prop_int(s, - kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, - enc->keyint)); - STATUS_CHECK(session_set_prop_int(s, - kVTCompressionPropertyKey_MaxKeyFrameInterval, - enc->keyint * ((float)enc->fps_num/enc->fps_den))); - STATUS_CHECK(session_set_prop_int(s, - kVTCompressionPropertyKey_ExpectedFrameRate, - ceil((float)enc->fps_num/ enc->fps_den))); - STATUS_CHECK(session_set_prop(s, - kVTCompressionPropertyKey_AllowFrameReordering, - enc->bframes ? kCFBooleanTrue : kCFBooleanFalse)); + STATUS_CHECK(session_set_prop_int( + s, kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, + enc->keyint)); + STATUS_CHECK(session_set_prop_int( + s, kVTCompressionPropertyKey_MaxKeyFrameInterval, + enc->keyint * ((float)enc->fps_num / enc->fps_den))); + STATUS_CHECK(session_set_prop_int( + s, kVTCompressionPropertyKey_ExpectedFrameRate, + ceil((float)enc->fps_num / enc->fps_den))); + STATUS_CHECK(session_set_prop( + s, kVTCompressionPropertyKey_AllowFrameReordering, + enc->bframes ? kCFBooleanTrue : kCFBooleanFalse)); // This can fail depending on hardware configuration code = session_set_prop(s, kVTCompressionPropertyKey_RealTime, - kCFBooleanTrue); + kCFBooleanTrue); if (code != noErr) log_osstatus(LOG_WARNING, enc, - "setting " - "kVTCompressionPropertyKey_RealTime, " - "frame delay might be increased", - code); + "setting " + "kVTCompressionPropertyKey_RealTime, " + "frame delay might be increased", + code); - STATUS_CHECK(session_set_prop(s, - kVTCompressionPropertyKey_ProfileLevel, - obs_to_vt_profile(enc->profile))); + STATUS_CHECK(session_set_prop(s, kVTCompressionPropertyKey_ProfileLevel, + obs_to_vt_profile(enc->profile))); STATUS_CHECK(session_set_bitrate(s, enc->bitrate, enc->limit_bitrate, - enc->rc_max_bitrate, enc->rc_max_bitrate_window)); + enc->rc_max_bitrate, + enc->rc_max_bitrate_window)); STATUS_CHECK(session_set_colorspace(s, enc->colorspace)); @@ -386,7 +373,8 @@ static void vt_h264_destroy(void *data) static void dump_encoder_info(struct vt_h264_encoder *enc) { - VT_BLOG(LOG_INFO, "settings:\n" + VT_BLOG(LOG_INFO, + "settings:\n" "\tvt_encoder_id %s\n" "\tbitrate: %d (kbps)\n" "\tfps_num: %d\n" @@ -399,19 +387,12 @@ static void dump_encoder_info(struct vt_h264_encoder *enc) "\trc_max_bitrate_window: %f (s)\n" "\thw_enc: %s\n" "\tprofile: %s\n", - enc->vt_encoder_id, - enc->bitrate, - enc->fps_num, - enc->fps_den, - enc->width, - enc->height, - enc->keyint, - enc->limit_bitrate ? "on" : "off", - enc->rc_max_bitrate, - enc->rc_max_bitrate_window, - enc->hw_enc ? "on" : "off", - (enc->profile != NULL && !!strlen(enc->profile)) - ? enc->profile : "default"); + enc->vt_encoder_id, enc->bitrate, enc->fps_num, enc->fps_den, + enc->width, enc->height, enc->keyint, + enc->limit_bitrate ? "on" : "off", enc->rc_max_bitrate, + enc->rc_max_bitrate_window, enc->hw_enc ? "on" : "off", + (enc->profile != NULL && !!strlen(enc->profile)) ? enc->profile + : "default"); } static void vt_h264_video_info(void *data, struct video_scale_info *info) @@ -420,8 +401,9 @@ static void vt_h264_video_info(void *data, struct video_scale_info *info) if (info->format == VIDEO_FORMAT_I420) { enc->obs_pix_fmt = info->format; - enc->vt_pix_fmt = enc->fullrange ? - kCVPixelFormatType_420YpCbCr8PlanarFullRange + enc->vt_pix_fmt = + enc->fullrange + ? kCVPixelFormatType_420YpCbCr8PlanarFullRange : kCVPixelFormatType_420YpCbCr8Planar; return; } @@ -431,8 +413,9 @@ static void vt_h264_video_info(void *data, struct video_scale_info *info) // Anything else, return default enc->obs_pix_fmt = VIDEO_FORMAT_NV12; - enc->vt_pix_fmt = enc->fullrange ? - kCVPixelFormatType_420YpCbCr8BiPlanarFullRange + enc->vt_pix_fmt = + enc->fullrange + ? kCVPixelFormatType_420YpCbCr8BiPlanarFullRange : kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; info->format = enc->obs_pix_fmt; @@ -443,7 +426,7 @@ static void update_params(struct vt_h264_encoder *enc, obs_data_t *settings) video_t *video = obs_encoder_video(enc->encoder); const struct video_output_info *voi = video_output_get_info(video); - struct video_scale_info info = { .format = voi->format }; + struct video_scale_info info = {.format = voi->format}; enc->fullrange = voi->range == VIDEO_RANGE_FULL; @@ -461,8 +444,8 @@ static void update_params(struct vt_h264_encoder *enc, obs_data_t *settings) enc->profile = obs_data_get_string(settings, "profile"); enc->limit_bitrate = obs_data_get_bool(settings, "limit_bitrate"); enc->rc_max_bitrate = obs_data_get_int(settings, "max_bitrate"); - enc->rc_max_bitrate_window = obs_data_get_double(settings, - "max_bitrate_window"); + enc->rc_max_bitrate_window = + obs_data_get_double(settings, "max_bitrate_window"); enc->bframes = obs_data_get_bool(settings, "bframes"); } @@ -479,34 +462,35 @@ static bool vt_h264_update(void *data, obs_data_t *settings) old_limit_bitrate == enc->limit_bitrate) return true; - OSStatus code = session_set_bitrate(enc->session, - enc->bitrate, enc->limit_bitrate, enc->rc_max_bitrate, - enc->rc_max_bitrate_window); + OSStatus code = session_set_bitrate(enc->session, enc->bitrate, + enc->limit_bitrate, + enc->rc_max_bitrate, + enc->rc_max_bitrate_window); if (code != noErr) - VT_BLOG(LOG_WARNING, - "failed to set bitrate to session"); + VT_BLOG(LOG_WARNING, "failed to set bitrate to session"); CFNumberRef n; VTSessionCopyProperty(enc->session, - kVTCompressionPropertyKey_AverageBitRate, NULL, - &n); + kVTCompressionPropertyKey_AverageBitRate, NULL, + &n); uint32_t session_bitrate; CFNumberGetValue(n, kCFNumberIntType, &session_bitrate); CFRelease(n); if (session_bitrate == old_bitrate) { - VT_BLOG(LOG_WARNING, "failed to update current session " - " bitrate from %d->%d", - old_bitrate, enc->bitrate); + VT_BLOG(LOG_WARNING, + "failed to update current session " + " bitrate from %d->%d", + old_bitrate, enc->bitrate); } dump_encoder_info(enc); return true; } -static void *vt_h264_create(obs_data_t *settings, - obs_encoder_t *encoder, const char *vt_encoder_id) +static void *vt_h264_create(obs_data_t *settings, obs_encoder_t *encoder, + const char *vt_encoder_id) { struct vt_h264_encoder *enc = bzalloc(sizeof(struct vt_h264_encoder)); @@ -556,27 +540,28 @@ static void packet_put_startcode(struct darray *packet, int size) } static void convert_block_nals_to_annexb(struct vt_h264_encoder *enc, - struct darray *packet, CMBlockBufferRef block, - int nal_length_bytes) + struct darray *packet, + CMBlockBufferRef block, + int nal_length_bytes) { size_t block_size; uint8_t *block_buf; CMBlockBufferGetDataPointer(block, 0, NULL, &block_size, - (char **)&block_buf); + (char **)&block_buf); size_t bytes_remaining = block_size; - while(bytes_remaining > 0) { + while (bytes_remaining > 0) { uint32_t nal_size; if (nal_length_bytes == 1) nal_size = block_buf[0]; else if (nal_length_bytes == 2) nal_size = CFSwapInt16BigToHost( - ((uint16_t *)block_buf)[0]); + ((uint16_t *)block_buf)[0]); else if (nal_length_bytes == 4) nal_size = CFSwapInt32BigToHost( - ((uint32_t *)block_buf)[0]); + ((uint32_t *)block_buf)[0]); else return; @@ -597,21 +582,22 @@ static void convert_block_nals_to_annexb(struct vt_h264_encoder *enc, } static bool handle_keyframe(struct vt_h264_encoder *enc, - CMFormatDescriptionRef format_desc, size_t param_count, - struct darray *packet, struct darray *extra_data) + CMFormatDescriptionRef format_desc, + size_t param_count, struct darray *packet, + struct darray *extra_data) { OSStatus code; const uint8_t *param; size_t param_size; - for(size_t i = 0; i < param_count; i++) { + for (size_t i = 0; i < param_count; i++) { code = CMVideoFormatDescriptionGetH264ParameterSetAtIndex( - format_desc, i, ¶m, ¶m_size, - NULL, NULL); + format_desc, i, ¶m, ¶m_size, NULL, NULL); if (code != noErr) { log_osstatus(LOG_ERROR, enc, - "getting NAL parameter " - "at index", code); + "getting NAL parameter " + "at index", + code); return false; } @@ -628,35 +614,35 @@ static bool handle_keyframe(struct vt_h264_encoder *enc, } static bool convert_sample_to_annexb(struct vt_h264_encoder *enc, - struct darray *packet, struct darray *extra_data, - CMSampleBufferRef buffer, bool keyframe) + struct darray *packet, + struct darray *extra_data, + CMSampleBufferRef buffer, bool keyframe) { OSStatus code; CMFormatDescriptionRef format_desc = - CMSampleBufferGetFormatDescription(buffer); + CMSampleBufferGetFormatDescription(buffer); size_t param_count; int nal_length_bytes; - code = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(format_desc, - 0, NULL, NULL, ¶m_count, &nal_length_bytes); + code = CMVideoFormatDescriptionGetH264ParameterSetAtIndex( + format_desc, 0, NULL, NULL, ¶m_count, &nal_length_bytes); // it is not clear what errors this function can return // so we check the two most reasonable if (code == kCMFormatDescriptionBridgeError_InvalidParameter_ || code == kCMFormatDescriptionError_InvalidParameter) { VT_BLOG(LOG_WARNING, "assuming 2 parameter sets " - "and 4 byte NAL length header"); + "and 4 byte NAL length header"); param_count = 2; nal_length_bytes = 4; } else if (code != noErr) { log_osstatus(LOG_ERROR, enc, - "getting parameter count from sample", - code); + "getting parameter count from sample", code); return false; } - if (keyframe && !handle_keyframe(enc, format_desc, param_count, - packet, extra_data)) + if (keyframe && + !handle_keyframe(enc, format_desc, param_count, packet, extra_data)) return false; CMBlockBufferRef block = CMSampleBufferGetDataBuffer(buffer); @@ -667,13 +653,13 @@ static bool convert_sample_to_annexb(struct vt_h264_encoder *enc, static bool is_sample_keyframe(CMSampleBufferRef buffer) { - CFArrayRef attachments = CMSampleBufferGetSampleAttachmentsArray( - buffer, false); - if(attachments != NULL) { + CFArrayRef attachments = + CMSampleBufferGetSampleAttachmentsArray(buffer, false); + if (attachments != NULL) { CFDictionaryRef attachment; CFBooleanRef has_dependencies; - attachment = (CFDictionaryRef)CFArrayGetValueAtIndex( - attachments, 0); + attachment = + (CFDictionaryRef)CFArrayGetValueAtIndex(attachments, 0); has_dependencies = (CFBooleanRef)CFDictionaryGetValue( attachment, kCMSampleAttachmentKey_DependsOnOthers); return has_dependencies == kCFBooleanFalse; @@ -683,15 +669,15 @@ static bool is_sample_keyframe(CMSampleBufferRef buffer) } static bool parse_sample(struct vt_h264_encoder *enc, CMSampleBufferRef buffer, - struct encoder_packet *packet, CMTime off) + struct encoder_packet *packet, CMTime off) { CMTime pts = CMSampleBufferGetPresentationTimeStamp(buffer); CMTime dts = CMSampleBufferGetDecodeTimeStamp(buffer); pts = CMTimeMultiplyByFloat64(pts, - ((Float64)enc->fps_num/enc->fps_den)); + ((Float64)enc->fps_num / enc->fps_den)); dts = CMTimeMultiplyByFloat64(dts, - ((Float64)enc->fps_num/enc->fps_den)); + ((Float64)enc->fps_num / enc->fps_den)); // imitate x264's negative dts when bframes might have pts < dts if (enc->bframes) @@ -707,7 +693,7 @@ static bool parse_sample(struct vt_h264_encoder *enc, CMSampleBufferRef buffer, extra_data = &enc->extra_data.da; if (!convert_sample_to_annexb(enc, &enc->packet_data.da, extra_data, - buffer, keyframe)) + buffer, keyframe)) goto fail; packet->type = OBS_ENCODER_VIDEO; @@ -725,20 +711,16 @@ fail: return false; } -bool get_cached_pixel_buffer(struct vt_h264_encoder *enc, - CVPixelBufferRef *buf) +bool get_cached_pixel_buffer(struct vt_h264_encoder *enc, CVPixelBufferRef *buf) { OSStatus code; CVPixelBufferPoolRef pool = - VTCompressionSessionGetPixelBufferPool( - enc->session); + VTCompressionSessionGetPixelBufferPool(enc->session); if (!pool) return kCVReturnError; CVPixelBufferRef pixbuf; - STATUS_CHECK(CVPixelBufferPoolCreatePixelBuffer(NULL, pool, - &pixbuf)); - + STATUS_CHECK(CVPixelBufferPoolCreatePixelBuffer(NULL, pool, &pixbuf)); // Why aren't these already set on the pixel buffer? // I would have expected pixel buffers from the session's @@ -746,18 +728,14 @@ bool get_cached_pixel_buffer(struct vt_h264_encoder *enc, CFStringRef matrix = obs_to_vt_colorspace(enc->colorspace); - CVBufferSetAttachment(pixbuf, - kCVImageBufferYCbCrMatrixKey, - matrix, - kCVAttachmentMode_ShouldPropagate); - CVBufferSetAttachment(pixbuf, - kCVImageBufferColorPrimariesKey, - kCVImageBufferColorPrimaries_ITU_R_709_2, - kCVAttachmentMode_ShouldPropagate); - CVBufferSetAttachment(pixbuf, - kCVImageBufferTransferFunctionKey, - kCVImageBufferTransferFunction_ITU_R_709_2, - kCVAttachmentMode_ShouldPropagate); + CVBufferSetAttachment(pixbuf, kCVImageBufferYCbCrMatrixKey, matrix, + kCVAttachmentMode_ShouldPropagate); + CVBufferSetAttachment(pixbuf, kCVImageBufferColorPrimariesKey, + kCVImageBufferColorPrimaries_ITU_R_709_2, + kCVAttachmentMode_ShouldPropagate); + CVBufferSetAttachment(pixbuf, kCVImageBufferTransferFunctionKey, + kCVImageBufferTransferFunction_ITU_R_709_2, + kCVAttachmentMode_ShouldPropagate); *buf = pixbuf; return true; @@ -767,7 +745,7 @@ fail: } static bool vt_h264_encode(void *data, struct encoder_frame *frame, - struct encoder_packet *packet, bool *received_packet) + struct encoder_packet *packet, bool *received_packet) { struct vt_h264_encoder *enc = data; @@ -786,17 +764,17 @@ static bool vt_h264_encode(void *data, struct encoder_frame *frame, STATUS_CHECK(CVPixelBufferLockBaseAddress(pixbuf, 0)); - for(int i = 0; i < MAX_AV_PLANES; i++) { + for (int i = 0; i < MAX_AV_PLANES; i++) { if (frame->data[i] == NULL) break; uint8_t *p = (uint8_t *)CVPixelBufferGetBaseAddressOfPlane( - pixbuf, i); + pixbuf, i); uint8_t *f = frame->data[i]; - size_t plane_linesize = CVPixelBufferGetBytesPerRowOfPlane( - pixbuf, i); + size_t plane_linesize = + CVPixelBufferGetBytesPerRowOfPlane(pixbuf, i); size_t plane_height = CVPixelBufferGetHeightOfPlane(pixbuf, i); - for(size_t j = 0; j < plane_height; j++) { + for (size_t j = 0; j < plane_height; j++) { memcpy(p, f, frame->linesize[i]); p += plane_linesize; f += frame->linesize[i]; @@ -806,10 +784,10 @@ static bool vt_h264_encode(void *data, struct encoder_frame *frame, STATUS_CHECK(CVPixelBufferUnlockBaseAddress(pixbuf, 0)); STATUS_CHECK(VTCompressionSessionEncodeFrame(enc->session, pixbuf, pts, - dur, NULL, pixbuf, NULL)); + dur, NULL, pixbuf, NULL)); CMSampleBufferRef buffer = - (CMSampleBufferRef)CMSimpleQueueDequeue(enc->queue); + (CMSampleBufferRef)CMSimpleQueueDequeue(enc->queue); // No samples waiting in the queue if (buffer == NULL) @@ -845,19 +823,19 @@ static const char *vt_h264_getname_sw(void *unused) return obs_module_text("VTH264EncSW"); } -#define TEXT_VT_ENCODER obs_module_text("VTEncoder") -#define TEXT_BITRATE obs_module_text("Bitrate") -#define TEXT_USE_MAX_BITRATE obs_module_text("UseMaxBitrate") -#define TEXT_MAX_BITRATE obs_module_text("MaxBitrate") +#define TEXT_VT_ENCODER obs_module_text("VTEncoder") +#define TEXT_BITRATE obs_module_text("Bitrate") +#define TEXT_USE_MAX_BITRATE obs_module_text("UseMaxBitrate") +#define TEXT_MAX_BITRATE obs_module_text("MaxBitrate") #define TEXT_MAX_BITRATE_WINDOW obs_module_text("MaxBitrateWindow") -#define TEXT_KEYINT_SEC obs_module_text("KeyframeIntervalSec") -#define TEXT_PROFILE obs_module_text("Profile") -#define TEXT_NONE obs_module_text("None") -#define TEXT_DEFAULT obs_module_text("DefaultEncoder") -#define TEXT_BFRAMES obs_module_text("UseBFrames") +#define TEXT_KEYINT_SEC obs_module_text("KeyframeIntervalSec") +#define TEXT_PROFILE obs_module_text("Profile") +#define TEXT_NONE obs_module_text("None") +#define TEXT_DEFAULT obs_module_text("DefaultEncoder") +#define TEXT_BFRAMES obs_module_text("UseBFrames") static bool limit_bitrate_modified(obs_properties_t *ppts, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { bool use_max_bitrate = obs_data_get_bool(settings, "limit_bitrate"); p = obs_properties_get(ppts, "max_bitrate"); @@ -874,25 +852,26 @@ static obs_properties_t *vt_h264_properties(void *unused) obs_properties_t *props = obs_properties_create(); obs_property_t *p; - p = obs_properties_add_int(props, "bitrate", - TEXT_BITRATE, 50, 10000000, 50); + p = obs_properties_add_int(props, "bitrate", TEXT_BITRATE, 50, 10000000, + 50); obs_property_int_set_suffix(p, " Kbps"); p = obs_properties_add_bool(props, "limit_bitrate", - TEXT_USE_MAX_BITRATE); + TEXT_USE_MAX_BITRATE); obs_property_set_modified_callback(p, limit_bitrate_modified); p = obs_properties_add_int(props, "max_bitrate", TEXT_MAX_BITRATE, 50, - 10000000, 50); + 10000000, 50); obs_property_int_set_suffix(p, " Kbps"); obs_properties_add_float(props, "max_bitrate_window", - TEXT_MAX_BITRATE_WINDOW, 0.10f, 10.0f, 0.25f); + TEXT_MAX_BITRATE_WINDOW, 0.10f, 10.0f, 0.25f); obs_properties_add_int(props, "keyint_sec", TEXT_KEYINT_SEC, 0, 20, 1); p = obs_properties_add_list(props, "profile", TEXT_PROFILE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, TEXT_NONE, ""); obs_property_list_add_string(p, "baseline", "baseline"); obs_property_list_add_string(p, "main", "main"); @@ -923,15 +902,15 @@ void encoder_list_create() VTCopyVideoEncoderList(NULL, &encoder_list); CFIndex size = CFArrayGetCount(encoder_list); - for(CFIndex i = 0; i < size; i++) { + for (CFIndex i = 0; i < size; i++) { CFDictionaryRef encoder_dict = - CFArrayGetValueAtIndex(encoder_list, i); + CFArrayGetValueAtIndex(encoder_list, i); -#define VT_DICTSTR(key, name) \ - CFStringRef name ## _ref = CFDictionaryGetValue(encoder_dict, key); \ - CFIndex name ## _len = CFStringGetLength(name ## _ref); \ - char * name = bzalloc(name ## _len + 1); \ - CFStringGetFileSystemRepresentation(name ## _ref, name, name ## _len); +#define VT_DICTSTR(key, name) \ + CFStringRef name##_ref = CFDictionaryGetValue(encoder_dict, key); \ + CFIndex name##_len = CFStringGetLength(name##_ref); \ + char *name = bzalloc(name##_len + 1); \ + CFStringGetFileSystemRepresentation(name##_ref, name, name##_len); VT_DICTSTR(kVTVideoEncoderList_CodecName, codec_name); if (strcmp("H.264", codec_name) != 0) { @@ -945,7 +924,7 @@ void encoder_list_create() .name = name, .id = id, .disp_name = disp_name, - .codec_name = codec_name + .codec_name = codec_name, }; da_push_back(vt_encoders, &enc); #undef VT_DICTSTR @@ -954,7 +933,7 @@ void encoder_list_create() void encoder_list_destroy() { - for(size_t i = 0; i < vt_encoders.num; i++) { + for (size_t i = 0; i < vt_encoders.num; i++) { bfree((char *)vt_encoders.array[i].name); bfree((char *)vt_encoders.array[i].id); bfree((char *)vt_encoders.array[i].codec_name); @@ -966,26 +945,27 @@ void encoder_list_destroy() void register_encoders() { struct obs_encoder_info info = { - .type = OBS_ENCODER_VIDEO, - .codec = "h264", - .destroy = vt_h264_destroy, - .encode = vt_h264_encode, - .update = vt_h264_update, + .type = OBS_ENCODER_VIDEO, + .codec = "h264", + .destroy = vt_h264_destroy, + .encode = vt_h264_encode, + .update = vt_h264_update, .get_properties = vt_h264_properties, - .get_defaults = vt_h264_defaults, + .get_defaults = vt_h264_defaults, .get_video_info = vt_h264_video_info, - .get_extra_data = vt_h264_extra_data + .get_extra_data = vt_h264_extra_data, + .caps = OBS_ENCODER_CAP_DYN_BITRATE, }; - for(size_t i = 0; i < vt_encoders.num; i++) { - if (strcmp(vt_encoders.array[i].id, - APPLE_H264_ENC_ID_HW) == 0) { + for (size_t i = 0; i < vt_encoders.num; i++) { + if (strcmp(vt_encoders.array[i].id, APPLE_H264_ENC_ID_HW) == + 0) { info.id = "vt_h264_hw"; info.get_name = vt_h264_getname_hw; info.create = vt_h264_create_hw; obs_register_encoder(&info); } else if (strcmp(vt_encoders.array[i].id, - APPLE_H264_ENC_ID_SW) == 0) { + APPLE_H264_ENC_ID_SW) == 0) { info.id = "vt_h264_sw"; info.get_name = vt_h264_getname_sw; info.create = vt_h264_create_sw; @@ -998,7 +978,7 @@ bool obs_module_load(void) { if (!is_appkit10_9_or_greater()) { VT_LOG(LOG_WARNING, "Not adding VideoToolbox H264 encoder; " - "AppKit must be version 10.9 or greater"); + "AppKit must be version 10.9 or greater"); return false; } diff --git a/plugins/obs-ffmpeg/CMakeLists.txt b/plugins/obs-ffmpeg/CMakeLists.txt index 34d08b0..17365ef 100644 --- a/plugins/obs-ffmpeg/CMakeLists.txt +++ b/plugins/obs-ffmpeg/CMakeLists.txt @@ -5,10 +5,20 @@ if(MSVC) w32-pthreads) endif() +option(ENABLE_FFMPEG_LOGGING "Enables obs-ffmpeg logging" OFF) + find_package(FFmpeg REQUIRED COMPONENTS avcodec avfilter avdevice avutil swscale avformat swresample) include_directories(${FFMPEG_INCLUDE_DIRS}) +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/obs-ffmpeg-config.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/obs-ffmpeg-config.h") +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +set(obs-ffmpeg_config_HEADERS + "${CMAKE_CURRENT_BINARY_DIR}/obs-ffmpeg-config.h") + set(obs-ffmpeg_HEADERS obs-ffmpeg-formats.h obs-ffmpeg-compat.h @@ -29,6 +39,11 @@ if(UNIX AND NOT APPLE) ${LIBVA_LBRARIES}) endif() +if(ENABLE_FFMPEG_LOGGING) + list(APPEND obs-ffmpeg_SOURCES + obs-ffmpeg-logging.c) +endif() + if(WIN32) list(APPEND obs-ffmpeg_SOURCES jim-nvenc.c @@ -38,6 +53,7 @@ if(WIN32) endif() add_library(obs-ffmpeg MODULE + ${obs-ffmpeg_config_HEADERS} ${obs-ffmpeg_HEADERS} ${obs-ffmpeg_SOURCES}) target_link_libraries(obs-ffmpeg diff --git a/plugins/obs-ffmpeg/closest-pixel-format.h b/plugins/obs-ffmpeg/closest-pixel-format.h index 720695f..5cb74b9 100644 --- a/plugins/obs-ffmpeg/closest-pixel-format.h +++ b/plugins/obs-ffmpeg/closest-pixel-format.h @@ -1,82 +1,42 @@ #pragma once static const enum AVPixelFormat i420_formats[] = { - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_NV12, - AV_PIX_FMT_NV21, - AV_PIX_FMT_YUYV422, - AV_PIX_FMT_UYVY422, - AV_PIX_FMT_YUV422P, - AV_PIX_FMT_YUV444P, - AV_PIX_FMT_NONE -}; + AV_PIX_FMT_YUV420P, AV_PIX_FMT_NV12, AV_PIX_FMT_NV21, + AV_PIX_FMT_YUYV422, AV_PIX_FMT_UYVY422, AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE}; static const enum AVPixelFormat nv12_formats[] = { - AV_PIX_FMT_NV12, - AV_PIX_FMT_NV21, - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUYV422, - AV_PIX_FMT_UYVY422, - AV_PIX_FMT_YUV444P, - AV_PIX_FMT_NONE -}; + AV_PIX_FMT_NV12, AV_PIX_FMT_NV21, AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUYV422, AV_PIX_FMT_UYVY422, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_NONE}; static const enum AVPixelFormat i444_formats[] = { - AV_PIX_FMT_YUV444P, - AV_PIX_FMT_RGBA, - AV_PIX_FMT_BGRA, - AV_PIX_FMT_YUYV422, - AV_PIX_FMT_UYVY422, - AV_PIX_FMT_NV12, - AV_PIX_FMT_NV21, - AV_PIX_FMT_NONE -}; + AV_PIX_FMT_YUV444P, AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, + AV_PIX_FMT_YUYV422, AV_PIX_FMT_UYVY422, AV_PIX_FMT_NV12, + AV_PIX_FMT_NV21, AV_PIX_FMT_NONE}; static const enum AVPixelFormat yuy2_formats[] = { - AV_PIX_FMT_YUYV422, - AV_PIX_FMT_UYVY422, - AV_PIX_FMT_NV12, - AV_PIX_FMT_NV21, - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV444P, - AV_PIX_FMT_NONE -}; + AV_PIX_FMT_YUYV422, AV_PIX_FMT_UYVY422, AV_PIX_FMT_NV12, + AV_PIX_FMT_NV21, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_NONE}; static const enum AVPixelFormat uyvy_formats[] = { - AV_PIX_FMT_UYVY422, - AV_PIX_FMT_YUYV422, - AV_PIX_FMT_NV12, - AV_PIX_FMT_NV21, - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV444P, - AV_PIX_FMT_NONE -}; + AV_PIX_FMT_UYVY422, AV_PIX_FMT_YUYV422, AV_PIX_FMT_NV12, + AV_PIX_FMT_NV21, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_NONE}; static const enum AVPixelFormat rgba_formats[] = { - AV_PIX_FMT_RGBA, - AV_PIX_FMT_BGRA, - AV_PIX_FMT_YUV444P, - AV_PIX_FMT_YUYV422, - AV_PIX_FMT_UYVY422, - AV_PIX_FMT_NV12, - AV_PIX_FMT_NV21, - AV_PIX_FMT_NONE -}; + AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUYV422, AV_PIX_FMT_UYVY422, AV_PIX_FMT_NV12, + AV_PIX_FMT_NV21, AV_PIX_FMT_NONE}; static const enum AVPixelFormat bgra_formats[] = { - AV_PIX_FMT_BGRA, - AV_PIX_FMT_RGBA, - AV_PIX_FMT_YUV444P, - AV_PIX_FMT_YUYV422, - AV_PIX_FMT_UYVY422, - AV_PIX_FMT_NV12, - AV_PIX_FMT_NV21, - AV_PIX_FMT_NONE -}; + AV_PIX_FMT_BGRA, AV_PIX_FMT_RGBA, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUYV422, AV_PIX_FMT_UYVY422, AV_PIX_FMT_NV12, + AV_PIX_FMT_NV21, AV_PIX_FMT_NONE}; -static enum AVPixelFormat get_best_format( - const enum AVPixelFormat *best, - const enum AVPixelFormat *formats) +static enum AVPixelFormat get_best_format(const enum AVPixelFormat *best, + const enum AVPixelFormat *formats) { while (*best != AV_PIX_FMT_NONE) { enum AVPixelFormat best_format = *best; @@ -97,9 +57,8 @@ static enum AVPixelFormat get_best_format( return AV_PIX_FMT_NONE; } -static inline enum AVPixelFormat get_closest_format( - enum AVPixelFormat format, - const enum AVPixelFormat *formats) +static inline enum AVPixelFormat +get_closest_format(enum AVPixelFormat format, const enum AVPixelFormat *formats) { enum AVPixelFormat best_format = AV_PIX_FMT_NONE; diff --git a/plugins/obs-ffmpeg/data/locale/bg-BG.ini b/plugins/obs-ffmpeg/data/locale/bg-BG.ini index e772f17..06d91e6 100644 --- a/plugins/obs-ffmpeg/data/locale/bg-BG.ini +++ b/plugins/obs-ffmpeg/data/locale/bg-BG.ini @@ -24,7 +24,6 @@ LocalFile="Локален файл" Looping="Преповтаряне" Input="Вход" InputFormat="Формат за вход" -BufferingMB="Мрежова буферизация (MB)" HardwareDecode="Използване на хардуерно декодиране, ако е налично" Advanced="Разширено" RestartWhenActivated="Възобновява възпроизвеждането когато източникът е активен" @@ -32,7 +31,6 @@ CloseFileWhenInactive="Затваряне на файла при неактив ColorRange.Auto="Автоматично" ColorRange.Partial="Частично" ColorRange.Full="Пълно" -SpeedPercentage="Скорост (процент)" diff --git a/plugins/obs-ffmpeg/data/locale/ca-ES.ini b/plugins/obs-ffmpeg/data/locale/ca-ES.ini index c701ea6..80f8879 100644 --- a/plugins/obs-ffmpeg/data/locale/ca-ES.ini +++ b/plugins/obs-ffmpeg/data/locale/ca-ES.ini @@ -29,7 +29,7 @@ LocalFile="Fitxer local" Looping="Bucle" Input="Entrada" InputFormat="Format d'entrada" -BufferingMB="Memòria intermèdia de xarxa (MB)" +BufferingMB="Memòria intermèdia de xarxa" HardwareDecode="Usa la descodificació per maquinari si és disponible" ClearOnMediaEnd="No mostris res quan acabi la reproducció" Advanced="Avançat" @@ -41,7 +41,7 @@ ColorRange.Auto="Automàtic" ColorRange.Partial="Parcial" ColorRange.Full="Màxim" RestartMedia="Reinicia els mitjans" -SpeedPercentage="Velocitat (percentatge)" +SpeedPercentage="Velocitat" Seekable="Cercable" MediaFileFilter.AllMediaFiles="Tots els arxius multimèdia" diff --git a/plugins/obs-ffmpeg/data/locale/cs-CZ.ini b/plugins/obs-ffmpeg/data/locale/cs-CZ.ini index 2df3cac..f03da1e 100644 --- a/plugins/obs-ffmpeg/data/locale/cs-CZ.ini +++ b/plugins/obs-ffmpeg/data/locale/cs-CZ.ini @@ -29,7 +29,7 @@ LocalFile="Místní soubor" Looping="Opakovat" Input="Vstup" InputFormat="Formát vstupu" -BufferingMB="Vyrovnávací paměť pro síť (MB)" +BufferingMB="Vyrovnávací paměť pro síť" HardwareDecode="Použít hardwarové dekódování, pokud je k dispozici" ClearOnMediaEnd="Po skončení přehrávání nezobrazovat nic" Advanced="Pokročilé" @@ -41,7 +41,7 @@ ColorRange.Auto="Automatický" ColorRange.Partial="Částečný" ColorRange.Full="Celkový" RestartMedia="Restartovat mediální zdroj" -SpeedPercentage="Rychlost (procenta)" +SpeedPercentage="Rychlost" Seekable="Posouvatelné" MediaFileFilter.AllMediaFiles="Všechny mediální soubory" diff --git a/plugins/obs-ffmpeg/data/locale/da-DK.ini b/plugins/obs-ffmpeg/data/locale/da-DK.ini index 8b3aad3..3792cfa 100644 --- a/plugins/obs-ffmpeg/data/locale/da-DK.ini +++ b/plugins/obs-ffmpeg/data/locale/da-DK.ini @@ -29,7 +29,7 @@ LocalFile="Lokal fil" Looping="Gentagelse" Input="Input" InputFormat="Inputformat" -BufferingMB="Netværksbuffering (MB)" +BufferingMB="Netværksbuffering" HardwareDecode="Benyt hardwareafkodning, når tilgængelig" ClearOnMediaEnd="Vis intet, når afspilning afsluttes" Advanced="Avanceret" @@ -41,7 +41,7 @@ ColorRange.Auto="Auto" ColorRange.Partial="Delvis" ColorRange.Full="Fuld" RestartMedia="Genstart Media" -SpeedPercentage="Hastighed (procent)" +SpeedPercentage="Hastighed" Seekable="Søgbar" MediaFileFilter.AllMediaFiles="Alle mediefiler" diff --git a/plugins/obs-ffmpeg/data/locale/de-DE.ini b/plugins/obs-ffmpeg/data/locale/de-DE.ini index ad95bdc..e328954 100644 --- a/plugins/obs-ffmpeg/data/locale/de-DE.ini +++ b/plugins/obs-ffmpeg/data/locale/de-DE.ini @@ -1,16 +1,16 @@ -FFmpegOutput="FFmpeg-Ausgabe" -FFmpegAAC="FFmpeg-Standard-AAC-Kodierer" -FFmpegOpus="FFmpeg-Opus-Kodierer" +FFmpegOutput="FFmpeg‐Ausgabe" +FFmpegAAC="FFmpeg‐Standard‐AAC‐Kodierer" +FFmpegOpus="FFmpeg‐Opus‐Kodierer" Bitrate="Bitrate" MaxBitrate="Max. Bitrate" Preset="Voreinstellung" RateControl="Qualitäts Regulierungsmethode" -KeyframeIntervalSec="Keyframeintervall in Sek. (0 = auto)" +KeyframeIntervalSec="Keyframeintervall in Sek. (0 = automatisch)" Lossless="Verlustfrei" -BFrames="Max. B-Frames" +BFrames="Max. B‐Frames" -NVENC.Use2Pass="Two-Pass-Kodierung verwenden" +NVENC.Use2Pass="Two‐Pass‐Kodierung verwenden" NVENC.Preset.default="Leistung" NVENC.Preset.hq="Qualität" NVENC.Preset.hp="Max. Leistung" @@ -18,30 +18,30 @@ NVENC.Preset.mq="Max. Qualität" NVENC.Preset.ll="Niedrige Latenz" NVENC.Preset.llhq="Niedrige Latenz + Qualität" NVENC.Preset.llhp="Niedrige Latenz + Leistung" -NVENC.LookAhead="Look-ahead" -NVENC.LookAhead.ToolTip="Aktiviert dynamische B-Frames.\n\nWenn deaktiviert, wird der Kodierer immer die Anzahl der B-Frames verwenden, die in der „Max B-Frames“-Einstellung angegeben sind.\n\nWenn aktiviert, wird er die visuelle Qualität erhöhen, indem nur so viele B-Frames verwendet werden wie benötigt, bis zum Maximum,\nzu den Kosten einer erhöhten GPU-Nutzung." -NVENC.PsychoVisualTuning="Psycho-visuelle Optimierung" -NVENC.PsychoVisualTuning.ToolTip="Aktiviert Kodierereinstellungen, die die Verwendung der Bitrate für eine erhöhte wahrgenommene visuelle Qualität optimieren,\ninsbesondere in Situationen mit hoher Bewegung, zu Kosten einer erhöhten GPU-Nutzung." -NVENC.CQLevel="CQ-Level" +NVENC.LookAhead="Look‐ahead" +NVENC.LookAhead.ToolTip="Aktiviert dynamische B‐Frames.\n\nWenn deaktiviert, wird der Kodierer immer die Anzahl der B‐Frames verwenden, die in der „Max B‐Frames“‐Einstellung angegeben sind.\n\nWenn aktiviert, wird er die visuelle Qualität erhöhen, indem nur so viele B‐Frames verwendet werden wie benötigt, bis zum Maximum,\nzu den Kosten einer erhöhten GPU‐Nutzung." +NVENC.PsychoVisualTuning="Psycho Visual Tuning" +NVENC.PsychoVisualTuning.ToolTip="Aktiviert Kodierereinstellungen, die die Verwendung der Bitrate für eine erhöhte wahrgenommene visuelle Qualität optimieren,\ninsbesondere in Situationen mit hoher Bewegung, zu Kosten einer erhöhten GPU‐Nutzung." +NVENC.CQLevel="CQ‐Level" FFmpegSource="Medienquelle" LocalFile="Lokale Datei" Looping="Endlosschleife" Input="Eingabe" InputFormat="Eingabeformat" -BufferingMB="Netzwerkpufferung (MB)" +BufferingMB="Netzwerkpufferung" HardwareDecode="Hardwaredekodierung verwenden, falls verfügbar" ClearOnMediaEnd="Nichts anzeigen, wenn Wiedergabe endet" Advanced="Erweitert" RestartWhenActivated="Wiedergabe erneut starten, wenn Quelle aktiviert wird" CloseFileWhenInactive="Datei schließen, wenn inaktiv" -CloseFileWhenInactive.ToolTip="Schließt die Datei, wenn die Quelle im Stream oder der Aufnahme nicht angezeigt wird.\nDies ermöglicht, dass die Datei geändert werden kann, wenn die Quelle nicht aktiv ist,\n aber es gibt wahrscheinlich etwas Startverzögerung, wenn die Quelle reaktiviert wird." -ColorRange="YUV-Farbmatrix" +CloseFileWhenInactive.ToolTip="Schließt die Datei, wenn die Quelle im Stream oder der Aufnahme nicht angezeigt wird.\nDies ermöglicht, dass die Datei geändert werden kann.\nDafür können aber Startverzögerungen auftreten, wenn die Quelle reaktiviert wird." +ColorRange="YUV‐Farbmatrix" ColorRange.Auto="Automatisch" ColorRange.Partial="Teilweise" ColorRange.Full="Voll" RestartMedia="Medium neustarten" -SpeedPercentage="Geschwindigkeit (Prozent)" +SpeedPercentage="Geschwindigkeit" Seekable="Durch­such­bar" MediaFileFilter.AllMediaFiles="Alle Mediendateien" @@ -49,10 +49,10 @@ MediaFileFilter.VideoFiles="Videodateien" MediaFileFilter.AudioFiles="Audiodateien" MediaFileFilter.AllFiles="Alle Dateien" -ReplayBuffer="Replaypuffer" +ReplayBuffer="Replay‐Puffer" ReplayBuffer.Save="Replay speichern" -HelperProcessFailed="Der Aufnahmehelferprozeß kann nicht gestartet werden. Überprüfen Sie, ob OBS-Dateien nicht von einer Drittanbieter Antiviren- / Sicherheitssoftware blockiert oder entfernt wurden." +HelperProcessFailed="Der Aufnahme‐Helfer‐Prozess kann nicht gestartet werden. Überprüfen Sie, ob OBS‐Dateien nicht von einer Drittanbieter‐Antiviren‐/Sicherheitssoftware blockiert oder entfernt werden." UnableToWritePath="Kann nicht zu %1 schreiben. Vergewissern Sie sich, dass Sie einen Aufnahmepfad verwenden, für das Ihr Benutzerkonto Schreibrechte hat und dass genügend Speicherplatz zur Verfügung steht." -WarnWindowsDefender="Wenn Windows-10-Ransomware-Schutz aktiviert ist, kann dies auch den Fehler auslösen. Versuchen Sie, den überwachten Ordnerzugriff in Windows-Sicherheit → Viren- & Bedrohungsschutz auszuschalten." +WarnWindowsDefender="Wenn Windows‐10‐Ransomware‐Schutz aktiviert ist, kann dies auch den Fehler auslösen. Versuchen Sie, den überwachten Ordnerzugriff in Windows‐Sicherheit → Viren‐ & Bedrohungsschutz auszuschalten." diff --git a/plugins/obs-ffmpeg/data/locale/el-GR.ini b/plugins/obs-ffmpeg/data/locale/el-GR.ini index 818f3c8..f72fd5e 100644 --- a/plugins/obs-ffmpeg/data/locale/el-GR.ini +++ b/plugins/obs-ffmpeg/data/locale/el-GR.ini @@ -16,7 +16,6 @@ LocalFile="Τοπικό αρχείο" Looping="Επανάληψη" Input="Είσοδος" InputFormat="Μορφή Εισόδου" -BufferingMB="Μέγεθος προσωρινης αποθήκευσης Δικτύου (MB)" HardwareDecode="Χρήση αποκωδικοποίησης υλικού όταν είναι διαθέσιμη" Advanced="Σύνθετες επιλογές" RestartWhenActivated="Επανεκκίνηση της αναπαραγωγής όταν η πηγή γίνεται ξανά ενεργή" @@ -27,7 +26,6 @@ ColorRange.Auto="Αυτόματο" ColorRange.Partial="Μερικός" ColorRange.Full="Πλήρης" RestartMedia="Επανεκκίνηση Πολυμέσων" -SpeedPercentage="Ταχύτητα (τοις εκατό)" Seekable="Παρεχόμενη" MediaFileFilter.AllMediaFiles="Όλα τα αρχεία πολυμέσων" diff --git a/plugins/obs-ffmpeg/data/locale/en-US.ini b/plugins/obs-ffmpeg/data/locale/en-US.ini index 7d762ac..e42f40d 100644 --- a/plugins/obs-ffmpeg/data/locale/en-US.ini +++ b/plugins/obs-ffmpeg/data/locale/en-US.ini @@ -29,7 +29,7 @@ LocalFile="Local File" Looping="Loop" Input="Input" InputFormat="Input Format" -BufferingMB="Network Buffering (MB)" +BufferingMB="Network Buffering" HardwareDecode="Use hardware decoding when available" ClearOnMediaEnd="Show nothing when playback ends" Advanced="Advanced" @@ -41,7 +41,7 @@ ColorRange.Auto="Auto" ColorRange.Partial="Partial" ColorRange.Full="Full" RestartMedia="Restart Media" -SpeedPercentage="Speed (percent)" +SpeedPercentage="Speed" Seekable="Seekable" MediaFileFilter.AllMediaFiles="All Media Files" diff --git a/plugins/obs-ffmpeg/data/locale/es-ES.ini b/plugins/obs-ffmpeg/data/locale/es-ES.ini index f218ee1..3424946 100644 --- a/plugins/obs-ffmpeg/data/locale/es-ES.ini +++ b/plugins/obs-ffmpeg/data/locale/es-ES.ini @@ -29,7 +29,7 @@ LocalFile="Archivo local" Looping="Bucle" Input="Entrada" InputFormat="Formato de entrada" -BufferingMB="Almacenamiento búfer de Red (MB)" +BufferingMB="Buffering de la red" HardwareDecode="Utilizar la decodificación por hardware cuando esté disponible" ClearOnMediaEnd="No mostrar nada al terminar la reproducción" Advanced="Avanzado" @@ -41,7 +41,7 @@ ColorRange.Auto="Automatico" ColorRange.Partial="Parcial" ColorRange.Full="Completo" RestartMedia="Reiniciar Medio" -SpeedPercentage="Velocidad (porcentaje)" +SpeedPercentage="Velocidad" Seekable="Buscable" MediaFileFilter.AllMediaFiles="Todos los archivos multimedia" diff --git a/plugins/obs-ffmpeg/data/locale/eu-ES.ini b/plugins/obs-ffmpeg/data/locale/eu-ES.ini index 3c54c22..655e1fd 100644 --- a/plugins/obs-ffmpeg/data/locale/eu-ES.ini +++ b/plugins/obs-ffmpeg/data/locale/eu-ES.ini @@ -29,7 +29,7 @@ LocalFile="Tokiko fitxategia" Looping="Begizta" Input="Sarrera" InputFormat="Sarrera formatua" -BufferingMB="Sareko bufferreratzea (MB)" +BufferingMB="Sareko bufferreratzea" HardwareDecode="Erabili hardware deskodeketa eskuragarri dagoenean" ClearOnMediaEnd="Erreprodukzioa bukatzean ez erakutsi ezer" Advanced="Aurreratua" @@ -41,7 +41,7 @@ ColorRange.Auto="Auto" ColorRange.Partial="Partziala" ColorRange.Full="Osoa" RestartMedia="Berrabiarazi euskarria" -SpeedPercentage="Abiadura (ehunekoa)" +SpeedPercentage="Abiadura" Seekable="Bilagai" MediaFileFilter.AllMediaFiles="Multimedia-fitxategi guztiak" diff --git a/plugins/obs-ffmpeg/data/locale/fa-IR.ini b/plugins/obs-ffmpeg/data/locale/fa-IR.ini index ea127f2..17be3da 100644 --- a/plugins/obs-ffmpeg/data/locale/fa-IR.ini +++ b/plugins/obs-ffmpeg/data/locale/fa-IR.ini @@ -24,12 +24,10 @@ LocalFile="فایل محلی" Looping="چرخه" Input="ورودی" InputFormat="فرمت های ورودی" -BufferingMB="شبکه بافری (مگابایت)" ColorRange.Auto="خودکار" ColorRange.Partial="جزئی" ColorRange.Full="کامل" RestartMedia="راه اندازی مجدد رسانه ها" -SpeedPercentage="سرعت (درصد)" Seekable="جستجوگر" MediaFileFilter.AllMediaFiles="تمامی فایل های رسانه" diff --git a/plugins/obs-ffmpeg/data/locale/fi-FI.ini b/plugins/obs-ffmpeg/data/locale/fi-FI.ini index e36e7a6..5ded74c 100644 --- a/plugins/obs-ffmpeg/data/locale/fi-FI.ini +++ b/plugins/obs-ffmpeg/data/locale/fi-FI.ini @@ -29,7 +29,6 @@ LocalFile="Paikallinen tiedosto" Looping="Toista jatkuvasti" Input="Sisääntulo" InputFormat="Sisääntulon muoto" -BufferingMB="Verkon puskurointi (MB)" HardwareDecode="Käytä laitteistotason purkua, kun mahdollista" ClearOnMediaEnd="Älä näytä mitään kun toisto päättyy" Advanced="Lisäasetukset" @@ -41,7 +40,6 @@ ColorRange.Auto="Automaattinen" ColorRange.Partial="Osittainen" ColorRange.Full="Täysi" RestartMedia="Uudelleenkäynnistä media" -SpeedPercentage="Nopeus (prosentti)" Seekable="Haettava" MediaFileFilter.AllMediaFiles="Kaikki mediatiedostot" diff --git a/plugins/obs-ffmpeg/data/locale/fil-PH.ini b/plugins/obs-ffmpeg/data/locale/fil-PH.ini index 53a58a0..4493a49 100644 --- a/plugins/obs-ffmpeg/data/locale/fil-PH.ini +++ b/plugins/obs-ffmpeg/data/locale/fil-PH.ini @@ -16,7 +16,6 @@ LocalFile="Ang File na lokal" Looping="I-Loop" Input="Ang Input" InputFormat="Ang Format ng Input" -BufferingMB="Nag buffering ang Network (MB)" HardwareDecode="Gamitin ang hardware decoding kapag magagamit" Advanced="I-Advanced" RestartWhenActivated="Simulan mulang ang playback kapag aktibo ang pinagmulan" diff --git a/plugins/obs-ffmpeg/data/locale/fr-FR.ini b/plugins/obs-ffmpeg/data/locale/fr-FR.ini index 4d9881f..cfe1118 100644 --- a/plugins/obs-ffmpeg/data/locale/fr-FR.ini +++ b/plugins/obs-ffmpeg/data/locale/fr-FR.ini @@ -29,7 +29,7 @@ LocalFile="Fichier local" Looping="En boucle" Input="Entrée" InputFormat="Format d'entrée" -BufferingMB="Mémoire tampon réseau (Mo)" +BufferingMB="Tampon réseau (Mo)" HardwareDecode="Utiliser le décodage matériel si possible" ClearOnMediaEnd="Ne rien afficher lorsque la lecture se termine" Advanced="Options avancées" @@ -41,7 +41,7 @@ ColorRange.Auto="Auto" ColorRange.Partial="Partielle" ColorRange.Full="Complète" RestartMedia="Reprendre depuis le début" -SpeedPercentage="Vitesse (pourcentage)" +SpeedPercentage="Vitesse" Seekable="Navigable" MediaFileFilter.AllMediaFiles="Tous les fichiers multimédias" diff --git a/plugins/obs-ffmpeg/data/locale/gd-GB.ini b/plugins/obs-ffmpeg/data/locale/gd-GB.ini index 3d519e0..a9fb11b 100644 --- a/plugins/obs-ffmpeg/data/locale/gd-GB.ini +++ b/plugins/obs-ffmpeg/data/locale/gd-GB.ini @@ -25,7 +25,6 @@ LocalFile="Faidhle ionadail" Looping="Lùb" Input="Ion-chur" InputFormat="Fòrmat an ion-chuir" -BufferingMB="Bufair an lìonraidh (MB)" HardwareDecode="Cleachd dì-chòdachadh bathair-chruaidh ma bhios e ri fhaighinn" Advanced="Adhartach" RestartWhenActivated="Ath-thòisich a’ chluiche nuair a thig gnìomh on tùs" @@ -35,7 +34,6 @@ ColorRange.Auto="Fèin-obrachail" ColorRange.Partial="Leth-phàirteach" ColorRange.Full="Làn" RestartMedia="Ath-thòisich am meadhan" -SpeedPercentage="Luaths (sa cheud)" Seekable="Gabhaidh sireadh ann" MediaFileFilter.AllMediaFiles="A h-uile faidhle meadhain" diff --git a/plugins/obs-ffmpeg/data/locale/gl-ES.ini b/plugins/obs-ffmpeg/data/locale/gl-ES.ini index 196a04f..ff13551 100644 --- a/plugins/obs-ffmpeg/data/locale/gl-ES.ini +++ b/plugins/obs-ffmpeg/data/locale/gl-ES.ini @@ -1,17 +1,58 @@ FFmpegOutput="Saída de FFmpeg" -FFmpegAAC="Codificador AAC FFmpeg predefinido" -Bitrate="Velocidade de bits" +FFmpegAAC="Codificador AAC de FFmpeg predeterminado" +FFmpegOpus="Codificador Opus de FFmpeg" +Bitrate="Taxa de bits" +MaxBitrate="Taxa de bits máxima" +Preset="Preaxuste" +RateControl="Control da taxa" +KeyframeIntervalSec="Intervalo de fotogramas clave (segundos, 0=auto)" +Lossless="Sen perdas" +BFrames="Máximo de B-frames" +NVENC.Use2Pass="Usar codificación en dúas pasadas" +NVENC.Preset.default="Rendemento" +NVENC.Preset.hq="Calidade" +NVENC.Preset.hp="Máximo rendemento" +NVENC.Preset.mq="Máxima Calidade" +NVENC.Preset.ll="Baixa latencia" +NVENC.Preset.llhq="Calidade de baixa Latencia" +NVENC.Preset.llhp="Rendemento de baixa Latencia" +NVENC.LookAhead="Previsión" +NVENC.LookAhead.ToolTip="Activar B-frames dinámicos.\n\nSe está desactivado, o codificador empregará sempre o número de B-frames especificados na configuración «Máximo de B-frames».\n\nSe está activado, aumentará a calidade visual empregando só a cantidade de B-frames necesarios, ata o máximo,\nco custo do aumento de emprego da GPU." +NVENC.PsychoVisualTuning="Sintonización psico visual" +NVENC.PsychoVisualTuning.ToolTip="Activa os axustes do codificador que optimizan o uso da taxa de bits para aumentar a calidade visual percibida,\nespecialmente nas situacións con alto movemento, a costa de incrementar a utilización da GPU." +NVENC.CQLevel="Nivel de cuantificación constante" FFmpegSource="Fonte multimedia" LocalFile="Ficheiro local" Looping="Bucle" Input="Entrada" InputFormat="Formato de entrada" +BufferingMB="Memoria intermedia de rede" HardwareDecode="Utilizar a descodificación por hárdware cando estiver dispoñible" +ClearOnMediaEnd="Non amosar nada ao rematar a reprodución" Advanced="Avanzado" +RestartWhenActivated="Reiniciar a reprodución cando fonte estea activa" +CloseFileWhenInactive="Pechar o ficheiro cando estea inactivo" +CloseFileWhenInactive.ToolTip="Pecha o ficheiro cando a fonte non se está a amosar na emisión ou na\ngravación. Isto permite cambiar o ficheiro cando a fonte non está activa,\nmais pode haber algún atraso de inicio cando se reactive a fonte." +ColorRange="Gama de cor YUV" +ColorRange.Auto="Automático" +ColorRange.Partial="Parcial" +ColorRange.Full="Total" +RestartMedia="Reiniciar multimedia" +SpeedPercentage="Velocidade" +Seekable="Buscábel" +MediaFileFilter.AllMediaFiles="Todos os ficheiros multimedia" +MediaFileFilter.VideoFiles="Ficheiros de vídeo" +MediaFileFilter.AudioFiles="Ficheiros de son" +MediaFileFilter.AllFiles="Todos os ficheiros" +ReplayBuffer="Reproducir a memoria intermedia" +ReplayBuffer.Save="Gardar a reprodución" +HelperProcessFailed="Non foi posíbel iniciar o proceso do axudante de gravación. Comprobe que os ficheiros do OBS non foron bloqueados ou eliminados por un antivirus ou software de seguridade de terceiros." +UnableToWritePath="Non foi posíbel escribir en %1. Asegúrese de que está a usar unha ruta de gravación na que a súa conta de usuario teña permisos de escritura e que haxa espazo abondo no disco." +WarnWindowsDefender="Se a protección do Ransomware do Windows está activada tamén pode causar este erro. Tente desactivar o acceso controlado ao cartafol nos axustes de seguridade do Windows / virus e protección contra ameazas." diff --git a/plugins/obs-ffmpeg/data/locale/hu-HU.ini b/plugins/obs-ffmpeg/data/locale/hu-HU.ini index 9f3c3b2..dbc32a2 100644 --- a/plugins/obs-ffmpeg/data/locale/hu-HU.ini +++ b/plugins/obs-ffmpeg/data/locale/hu-HU.ini @@ -29,7 +29,7 @@ LocalFile="Helyi fájl" Looping="Ismétlés" Input="Bemenet" InputFormat="Bemeneti formátum" -BufferingMB="Hálózati pufferelés (MB)" +BufferingMB="Hálózati pufferelés" HardwareDecode="Hardveres dekódolás használata, ha rendelkezésre áll" ClearOnMediaEnd="Semmit se mutasson, a lejátszás végeztével" Advanced="Haladó" @@ -41,7 +41,7 @@ ColorRange.Auto="Auto" ColorRange.Partial="Részleges" ColorRange.Full="Teljes" RestartMedia="Media újraindítása" -SpeedPercentage="Sebesség (százalékos)" +SpeedPercentage="Sebesség" Seekable="Kereshető" MediaFileFilter.AllMediaFiles="Minden médiafájl" diff --git a/plugins/obs-ffmpeg/data/locale/it-IT.ini b/plugins/obs-ffmpeg/data/locale/it-IT.ini index f0a14fd..591c6e1 100644 --- a/plugins/obs-ffmpeg/data/locale/it-IT.ini +++ b/plugins/obs-ffmpeg/data/locale/it-IT.ini @@ -29,7 +29,7 @@ LocalFile="File locale" Looping="Ripeti" Input="Input" InputFormat="Formato dell'input" -BufferingMB="Buffering della rete (in MB)" +BufferingMB="Buffering della rete" HardwareDecode="Utilizza la decodifica hardware quando disponibile" ClearOnMediaEnd="Non mostrare nulla quando la riproduzione finisce" Advanced="Avanzate" @@ -41,7 +41,7 @@ ColorRange.Auto="Automatico" ColorRange.Partial="Parziale" ColorRange.Full="Intero" RestartMedia="Riavvia media dall'inizio" -SpeedPercentage="Velocità (in percentuale)" +SpeedPercentage="Velocità" Seekable="Ricercabile" MediaFileFilter.AllMediaFiles="Tutti i file multimediali" diff --git a/plugins/obs-ffmpeg/data/locale/ja-JP.ini b/plugins/obs-ffmpeg/data/locale/ja-JP.ini index e790cb3..52af41d 100644 --- a/plugins/obs-ffmpeg/data/locale/ja-JP.ini +++ b/plugins/obs-ffmpeg/data/locale/ja-JP.ini @@ -29,7 +29,7 @@ LocalFile="ローカルファイル" Looping="繰り返し" Input="入力" InputFormat="入力フォーマット" -BufferingMB="ネットワークバッファリング (MB)" +BufferingMB="ネットワークバッファリング" HardwareDecode="可能な場合ハードウェアデコードを使用" ClearOnMediaEnd="再生終了時に何も表示しない" Advanced="高度な設定" @@ -41,7 +41,7 @@ ColorRange.Auto="自動" ColorRange.Partial="一部" ColorRange.Full="全部" RestartMedia="メディアを再開する" -SpeedPercentage="速度 (パーセント)" +SpeedPercentage="速度" Seekable="シーク可能" MediaFileFilter.AllMediaFiles="すべてのメディアファイル" diff --git a/plugins/obs-ffmpeg/data/locale/ka-GE.ini b/plugins/obs-ffmpeg/data/locale/ka-GE.ini index cd244e0..677b7f1 100644 --- a/plugins/obs-ffmpeg/data/locale/ka-GE.ini +++ b/plugins/obs-ffmpeg/data/locale/ka-GE.ini @@ -29,7 +29,7 @@ LocalFile="ადგილობრივი ფაილი" Looping="დაუსრულებლად გამეორება" Input="შეტანა" InputFormat="შეტანის ფორმატი" -BufferingMB="ქსელის ბუფერიზაცია (მბაიტი)" +BufferingMB="ქსელის ბუფერიზაცია" HardwareDecode="აპარატურული დაშიფვრის გამოყენება, ხელმისაწვდომობის შემთხვევაში" ClearOnMediaEnd="აღარაფერი გამოჩნდეს, ჩვენების დასრულების შემდგომ" Advanced="გაფართოებული" @@ -41,7 +41,7 @@ ColorRange.Auto="ავტომატური" ColorRange.Partial="ნაწილობრივი" ColorRange.Full="სრული" RestartMedia="მასალის ხელახლა გაშვება" -SpeedPercentage="სიჩქარე (პროცენტი)" +SpeedPercentage="სიჩქარე" Seekable="გადახვევით" MediaFileFilter.AllMediaFiles="ყველა მასალა" diff --git a/plugins/obs-ffmpeg/data/locale/ko-KR.ini b/plugins/obs-ffmpeg/data/locale/ko-KR.ini index 292f8b3..f9b91b0 100644 --- a/plugins/obs-ffmpeg/data/locale/ko-KR.ini +++ b/plugins/obs-ffmpeg/data/locale/ko-KR.ini @@ -29,7 +29,7 @@ LocalFile="로컬 파일" Looping="반복" Input="입력" InputFormat="입력 형식" -BufferingMB="네트워크 버퍼링 (MB)" +BufferingMB="네트워크 버퍼링" HardwareDecode="가능한 경우 하드웨어 디코딩 사용" ClearOnMediaEnd="재생이 끝나면 아무 것도 표시하지 않기" Advanced="고급" @@ -41,7 +41,7 @@ ColorRange.Auto="자동" ColorRange.Partial="부분" ColorRange.Full="전체" RestartMedia="미디어 다시재생" -SpeedPercentage="속도 (백분율)" +SpeedPercentage="속도" Seekable="탐색 가능" MediaFileFilter.AllMediaFiles="모든 미디어 파일" diff --git a/plugins/obs-ffmpeg/data/locale/nb-NO.ini b/plugins/obs-ffmpeg/data/locale/nb-NO.ini index 30849de..bf7bb4f 100644 --- a/plugins/obs-ffmpeg/data/locale/nb-NO.ini +++ b/plugins/obs-ffmpeg/data/locale/nb-NO.ini @@ -29,7 +29,6 @@ LocalFile="Lokal fil" Looping="Repeter" Input="Inngang" InputFormat="Inngangsformat" -BufferingMB="Nettverksbuffer (Mb)" HardwareDecode="Bruk maskinvaredekoding når tilgjengelig" ClearOnMediaEnd="Vis ingenting når avspillingen slutter" Advanced="Avansert" @@ -41,7 +40,6 @@ ColorRange.Auto="Automatisk" ColorRange.Partial="Delvis" ColorRange.Full="Hel" RestartMedia="Start media på nytt" -SpeedPercentage="Fart (prosent)" Seekable="Søkbar" MediaFileFilter.AllMediaFiles="Alle mediefiler" diff --git a/plugins/obs-ffmpeg/data/locale/nl-NL.ini b/plugins/obs-ffmpeg/data/locale/nl-NL.ini index 7f996d7..0e0e86f 100644 --- a/plugins/obs-ffmpeg/data/locale/nl-NL.ini +++ b/plugins/obs-ffmpeg/data/locale/nl-NL.ini @@ -29,7 +29,7 @@ LocalFile="Lokaal bestand" Looping="Herhalen" Input="Invoer" InputFormat="Invoerformaat" -BufferingMB="Netwerk Buffering (MB)" +BufferingMB="Netwerkbuffering" HardwareDecode="Gebruik hardware-decoding wanneer mogelijk" ClearOnMediaEnd="Toon niets wanneer het afspelen eindigt" Advanced="Geavanceerd" @@ -41,7 +41,7 @@ ColorRange.Auto="Automatisch" ColorRange.Partial="Gedeeltelijk" ColorRange.Full="Volledig" RestartMedia="Media herstarten" -SpeedPercentage="Snelheid (percentage)" +SpeedPercentage="Snelheid" Seekable="Zoekbaar" MediaFileFilter.AllMediaFiles="Alle mediabestanden" diff --git a/plugins/obs-ffmpeg/data/locale/pl-PL.ini b/plugins/obs-ffmpeg/data/locale/pl-PL.ini index 2be79c9..6dcc390 100644 --- a/plugins/obs-ffmpeg/data/locale/pl-PL.ini +++ b/plugins/obs-ffmpeg/data/locale/pl-PL.ini @@ -29,7 +29,7 @@ LocalFile="Plik lokalny" Looping="Pętla" Input="Wejście" InputFormat="Format wejściowy" -BufferingMB="Bufor sieciowy (MB)" +BufferingMB="Rozmiar bufora" HardwareDecode="Użyj sprzętowego dekodowania gdy to możliwe" ClearOnMediaEnd="Po zakończeniu odtwarzania nie pokazuj nic" Advanced="Zaawansowane" @@ -41,7 +41,7 @@ ColorRange.Auto="Automatycznie" ColorRange.Partial="Częściowy" ColorRange.Full="Pełny" RestartMedia="Zrestartuj plik audio-wideo" -SpeedPercentage="Szybkość (procent)" +SpeedPercentage="Szybkość" Seekable="Przeszukiwalny" MediaFileFilter.AllMediaFiles="Wszystkie pliki multimedialne" diff --git a/plugins/obs-ffmpeg/data/locale/pt-BR.ini b/plugins/obs-ffmpeg/data/locale/pt-BR.ini index 85fa70e..5bc99d8 100644 --- a/plugins/obs-ffmpeg/data/locale/pt-BR.ini +++ b/plugins/obs-ffmpeg/data/locale/pt-BR.ini @@ -29,7 +29,7 @@ LocalFile="Arquivo Local" Looping="Loop" Input="Entrada" InputFormat="Formato de entrada" -BufferingMB="Buffer de Rede (MB)" +BufferingMB="Buffering de rede" HardwareDecode="Utilizar descodificação de hardware quando disponível" ClearOnMediaEnd="Não mostrar nada quando terminar a reprodução" Advanced="Avançado" @@ -41,7 +41,7 @@ ColorRange.Auto="Auto" ColorRange.Partial="Parcial" ColorRange.Full="Completo" RestartMedia="Reiniciar Mídia" -SpeedPercentage="Velocidade (percentagem)" +SpeedPercentage="Velocidade" Seekable="Procurável" MediaFileFilter.AllMediaFiles="Todos Arquivos de Mídia" diff --git a/plugins/obs-ffmpeg/data/locale/pt-PT.ini b/plugins/obs-ffmpeg/data/locale/pt-PT.ini index d8e2cee..43625ab 100644 --- a/plugins/obs-ffmpeg/data/locale/pt-PT.ini +++ b/plugins/obs-ffmpeg/data/locale/pt-PT.ini @@ -30,7 +30,6 @@ ColorRange="Gama de cor YUV" ColorRange.Auto="Auto" ColorRange.Partial="Parcial" ColorRange.Full="Completo" -SpeedPercentage="Velocidade (percentagem)" MediaFileFilter.AllMediaFiles="Todos os Arquivos de Media" MediaFileFilter.VideoFiles="Arquivos de Vídeo" diff --git a/plugins/obs-ffmpeg/data/locale/ro-RO.ini b/plugins/obs-ffmpeg/data/locale/ro-RO.ini index 535519b..05fddba 100644 --- a/plugins/obs-ffmpeg/data/locale/ro-RO.ini +++ b/plugins/obs-ffmpeg/data/locale/ro-RO.ini @@ -1,6 +1,7 @@ FFmpegOutput="Ieșire FFmpeg" FFmpegAAC="Codificator AAC implicit FFmpeg" Bitrate="Rată de biți" +MaxBitrate="Rată de biți maximă" Preset="Presetare" RateControl="Controlul ratei" KeyframeIntervalSec="Interval de cadre cheie (secunde, 0=auto)" @@ -19,12 +20,11 @@ LocalFile="Fișier local" Looping="Buclă" Input="Intrare" InputFormat="Format de intrare" -BufferingMB="Zonă tampon pentru rețea (MB)" HardwareDecode="Folosește decodarea hardware când este disponibilă" Advanced="Avansat" RestartWhenActivated="Repornește redarea când sursa devine activă" ColorRange="Gamă de culori YUV" -ColorRange.Auto="Auto" +ColorRange.Auto="Automată" ColorRange.Partial="Parțială" ColorRange.Full="Completă" diff --git a/plugins/obs-ffmpeg/data/locale/ru-RU.ini b/plugins/obs-ffmpeg/data/locale/ru-RU.ini index c68c87a..3050675 100644 --- a/plugins/obs-ffmpeg/data/locale/ru-RU.ini +++ b/plugins/obs-ffmpeg/data/locale/ru-RU.ini @@ -29,7 +29,7 @@ LocalFile="Локальный файл" Looping="Повтор" Input="Ввод" InputFormat="Формат ввода" -BufferingMB="Сетевая буферизация (МБ)" +BufferingMB="Сетевая буферизация" HardwareDecode="Использовать аппаратное декодирование при наличии" ClearOnMediaEnd="Ничего не показывать, когда воспроизведение заканчивается" Advanced="Дополнительно" @@ -41,7 +41,7 @@ ColorRange.Auto="Автоматически" ColorRange.Partial="Частичный" ColorRange.Full="Полный" RestartMedia="Перезапустить медиа" -SpeedPercentage="Скорость (проценты)" +SpeedPercentage="Скорость" Seekable="Перематываемый" MediaFileFilter.AllMediaFiles="Все медиа-файлы" diff --git a/plugins/obs-ffmpeg/data/locale/sk-SK.ini b/plugins/obs-ffmpeg/data/locale/sk-SK.ini index 451fd83..887ba28 100644 --- a/plugins/obs-ffmpeg/data/locale/sk-SK.ini +++ b/plugins/obs-ffmpeg/data/locale/sk-SK.ini @@ -16,7 +16,6 @@ LocalFile="Lokálny súbor" Looping="Slučka" Input="Vstup" InputFormat="Vstupný formát" -BufferingMB="Sieťové zapisovanie do medzipamäte (MB)" HardwareDecode="Použiť hardvérové dekódovanie podľa dostupnosti" Advanced="Rozšírené" RestartWhenActivated="Obnoviť prehrávanie pri aktivovaní zdroja" @@ -27,7 +26,6 @@ ColorRange.Auto="Automaticky" ColorRange.Partial="Čiastočný" ColorRange.Full="Plný" RestartMedia="Reštartuj mediálny zdroj" -SpeedPercentage="Rýchlosť (v percentách)" Seekable="Posúvateľný" MediaFileFilter.AllMediaFiles="Všetky mediálne súbory" diff --git a/plugins/obs-ffmpeg/data/locale/sl-SI.ini b/plugins/obs-ffmpeg/data/locale/sl-SI.ini index 2a40a24..c734c4d 100644 --- a/plugins/obs-ffmpeg/data/locale/sl-SI.ini +++ b/plugins/obs-ffmpeg/data/locale/sl-SI.ini @@ -1,17 +1,58 @@ -FFmpegOutput="FFmpeg izhod" -FFmpegAAC="FFmpeg Prevzeti AAC Encoder" -Bitrate="Bitrate" +FFmpegOutput="Izhod FFmpeg" +FFmpegAAC="Privzeti kodirnik AAC FFmpeg" +FFmpegOpus="Kodirnik Opus FFmpeg" +Bitrate="Bitna hitrost" +MaxBitrate="Največja bitna hitrost" +Preset="Prednastavitev" +RateControl="Nadzor hitrosti" +KeyframeIntervalSec="Razmik med ključnimi sličicami (s, 0=samodejno)" +Lossless="Brezizgubno" +BFrames="Največje št. sličic B" +NVENC.Use2Pass="Uporabi kodiranje z dvema prehodoma" +NVENC.Preset.default="Zmogljivost" +NVENC.Preset.hq="Kakovost" +NVENC.Preset.hp="Največja zmogljivost" +NVENC.Preset.mq="Najboljša kakovost" +NVENC.Preset.ll="Nizka zakasnitev" +NVENC.Preset.llhq="Kakovost z nizko zakasnitvijo" +NVENC.Preset.llhp="Zmogljivost z nizko zakasnitvijo" +NVENC.LookAhead="Predvidevanje" +NVENC.LookAhead.ToolTip="Omogoči dinamične sličice B.\n\nČe je onemogočeno, bo kodirnik vedno uporabil število sličic B, ki so navedene v nastavitvi 'Največje št. sličic B'.\n\nČe je omogočeno, bo vidna kakovost izboljšana, ker bo uporabljeno samo toliko sličic B, kot je potrebno, do\nnajvečjega števila na račun dodatne porabe GPE-ja." +NVENC.PsychoVisualTuning="Psiho-vidno uglaševanje" +NVENC.PsychoVisualTuning.ToolTip="Omogoči nastavitve kodirnika, ki optimizirajo uporabo bitne hitrosti za povečano zaznavno vidno kakovost,\nposebno v razmerah z veliko gibanja na račun povečane porabe GPE-ja." +NVENC.CQLevel="Raven CQ" -FFmpegSource="Medijski Vir" -LocalFile="Lokalna Datoteka" +FFmpegSource="Predstavnostni vir" +LocalFile="Lokalna datoteka" Looping="Ponavljaj" Input="Vhod" -InputFormat="Format vnosa" -HardwareDecode="Uporabi strojno pospeševanje, ko je na voljo" +InputFormat="Oblika vhoda" +BufferingMB="Omrežno medpomnenje" +HardwareDecode="Uporabi strojno odkodiranje, ko je na voljo" +ClearOnMediaEnd="Ne prikaži ničesar, ko se predvajanje konča" Advanced="Napredno" +RestartWhenActivated="Ponovno predvajaj, ki vir postane dejaven" +CloseFileWhenInactive="Zapri datoteko, ko ni dejaven" +CloseFileWhenInactive.ToolTip="Zapre datoteko, ki vir ni prikazan v pretoku ali posnetku. To omogoča\nspreminjanje datoteke, ko vir ni dejaven, vendar lahko pride do zakasnitve zagona,\nko vir ponovno postane dejaven." +ColorRange="Barvni razpon YUV" +ColorRange.Auto="Samodejno" +ColorRange.Partial="Delno" +ColorRange.Full="Polno" +RestartMedia="Pon. zaženi predstavnost" +SpeedPercentage="Hitrost" +Seekable="Omogoči iskanje" +MediaFileFilter.AllMediaFiles="Vse predstavne datoteke" +MediaFileFilter.VideoFiles="Videodatoteke" +MediaFileFilter.AudioFiles="Zvočne datoteke" +MediaFileFilter.AllFiles="Vse datoteke" +ReplayBuffer="Medpomn. za pon. predv." +ReplayBuffer.Save="Shrani pon. predv." +HelperProcessFailed="Pomožnega opravila za snemanje ni bilo mogoče začeti. Preverite, da protivirusni/varnostni program ni blokiral ali odstranil datotek OBS." +UnableToWritePath="Ni mogoče pisati v %1. Prepričajte se, da uporabljate pot za snemanje, na katero lahko vaš uporabniški račun zapisuje in da imate dovolj prostora na disku." +WarnWindowsDefender="To napako lahko povzroči tudi omogočena zaščita sistema Windows 10 proti izsiljevanju. V nastavitvah za varnost/zaščito proti virusom in grožnjami sistema Windows poizkusite izklopiti nadziran dostop do map." diff --git a/plugins/obs-ffmpeg/data/locale/sr-CS.ini b/plugins/obs-ffmpeg/data/locale/sr-CS.ini index d2830ac..10e0076 100644 --- a/plugins/obs-ffmpeg/data/locale/sr-CS.ini +++ b/plugins/obs-ffmpeg/data/locale/sr-CS.ini @@ -29,7 +29,6 @@ LocalFile="Lokalna datoteka" Looping="Ponavljanje" Input="Ulaz" InputFormat="Format ulaza" -BufferingMB="Baferovanje mreže (MB)" HardwareDecode="Koristi hardversko enkodiranje kada je dostupno" Advanced="Napredno" RestartWhenActivated="Ponovi reprodukciju kada izvor postane aktivan" @@ -40,7 +39,6 @@ ColorRange.Auto="Automatski" ColorRange.Partial="Delimični" ColorRange.Full="Potpuni" RestartMedia="Restartuj medij" -SpeedPercentage="Brzina (procenat)" Seekable="Pretraživanje" MediaFileFilter.AllMediaFiles="Sve medija datoteke" diff --git a/plugins/obs-ffmpeg/data/locale/sr-SP.ini b/plugins/obs-ffmpeg/data/locale/sr-SP.ini index abf1911..d802fe5 100644 --- a/plugins/obs-ffmpeg/data/locale/sr-SP.ini +++ b/plugins/obs-ffmpeg/data/locale/sr-SP.ini @@ -29,7 +29,6 @@ LocalFile="Локална датотека" Looping="Понављање" Input="Улаз" InputFormat="Формат улаза" -BufferingMB="Баферовање мреже (мегабајти)" HardwareDecode="Користи хардверско енкодирање када је доступно" Advanced="Напредно" RestartWhenActivated="Понови репродукцију када извор постане активан" @@ -40,7 +39,6 @@ ColorRange.Auto="Аутоматски" ColorRange.Partial="Делимични" ColorRange.Full="Потпуни" RestartMedia="Рестартуј медиј" -SpeedPercentage="Брзина (проценат)" Seekable="Претраживање" MediaFileFilter.AllMediaFiles="Све медија датотеке" diff --git a/plugins/obs-ffmpeg/data/locale/sv-SE.ini b/plugins/obs-ffmpeg/data/locale/sv-SE.ini index 9a33cb5..7350687 100644 --- a/plugins/obs-ffmpeg/data/locale/sv-SE.ini +++ b/plugins/obs-ffmpeg/data/locale/sv-SE.ini @@ -29,7 +29,7 @@ LocalFile="Lokal fil" Looping="Upprepa" Input="Infoga" InputFormat="Inmatningsformat" -BufferingMB="Nätverksbuffring (MB)" +BufferingMB="Nätverksbuffring" HardwareDecode="Använda hårdvareavkodning när tillgängligt" ClearOnMediaEnd="Visa ingenting när uppspelningen slutar" Advanced="Avancerat" @@ -41,7 +41,7 @@ ColorRange.Auto="Automatisk" ColorRange.Partial="Delvis" ColorRange.Full="Full" RestartMedia="Starta om media" -SpeedPercentage="Hastighet (procent)" +SpeedPercentage="Hastighet" Seekable="Sökbar" MediaFileFilter.AllMediaFiles="Alla mediafiler" diff --git a/plugins/obs-ffmpeg/data/locale/tl-PH.ini b/plugins/obs-ffmpeg/data/locale/tl-PH.ini index a9417f9..72cc980 100644 --- a/plugins/obs-ffmpeg/data/locale/tl-PH.ini +++ b/plugins/obs-ffmpeg/data/locale/tl-PH.ini @@ -16,7 +16,6 @@ LocalFile="Ang Lokal na File" Looping="Silo" Input="Pampasok" InputFormat="Pampasok na Format" -BufferingMB="Ang Network Buffering (MB)" HardwareDecode="Gamitin ang hardware sa pag-decode kapag itong magagamit na" Advanced="Nauuna" RestartWhenActivated="I-restart ang playback kapag ang pinagmulan ay naging aktibo na" diff --git a/plugins/obs-ffmpeg/data/locale/tr-TR.ini b/plugins/obs-ffmpeg/data/locale/tr-TR.ini index 1c7b908..8fc40d1 100644 --- a/plugins/obs-ffmpeg/data/locale/tr-TR.ini +++ b/plugins/obs-ffmpeg/data/locale/tr-TR.ini @@ -25,7 +25,6 @@ LocalFile="Yerel Dosya" Looping="Döngü" Input="Giriş" InputFormat="Giriş Biçimi" -BufferingMB="Ağ Arabelleğe Alma (MB)" HardwareDecode="Kullanılabilir ise, donanım kod çözmeyi kullan" Advanced="Gelişmiş" RestartWhenActivated="Yeniden oynatmayı kaynak etkin olduğunda yeniden başlat" @@ -36,7 +35,7 @@ ColorRange.Auto="Otomatik" ColorRange.Partial="Kısmi" ColorRange.Full="Tam" RestartMedia="Ortamı Yeniden Başlat" -SpeedPercentage="Hız (yüzde)" +SpeedPercentage="Hız" Seekable="Aranabilir" MediaFileFilter.AllMediaFiles="Tüm Medya Dosyaları" diff --git a/plugins/obs-ffmpeg/data/locale/uk-UA.ini b/plugins/obs-ffmpeg/data/locale/uk-UA.ini index 549cf29..ead6ffa 100644 --- a/plugins/obs-ffmpeg/data/locale/uk-UA.ini +++ b/plugins/obs-ffmpeg/data/locale/uk-UA.ini @@ -29,7 +29,7 @@ LocalFile="Локальний файл" Looping="Циклічно відтворювати" Input="Вхід" InputFormat="Вхідний формат" -BufferingMB="Буферизація мережевого контенту (МБ)" +BufferingMB="Буферизація мережевого контенту" HardwareDecode="Використовувати апаратне декодування, за наявності" ClearOnMediaEnd="Не показувати джерело, коли відтворення завершено" Advanced="Розширені параметри" @@ -41,7 +41,7 @@ ColorRange.Auto="Автовизначення" ColorRange.Partial="Частковий" ColorRange.Full="Повний" RestartMedia="Перезапустити медіа" -SpeedPercentage="Швидкість (відсотків)" +SpeedPercentage="Швидкість" Seekable="HTTP з перемотуванням" MediaFileFilter.AllMediaFiles="Файли мультимедіа" diff --git a/plugins/obs-ffmpeg/data/locale/zh-CN.ini b/plugins/obs-ffmpeg/data/locale/zh-CN.ini index 5ef0fc1..fb332c4 100644 --- a/plugins/obs-ffmpeg/data/locale/zh-CN.ini +++ b/plugins/obs-ffmpeg/data/locale/zh-CN.ini @@ -29,7 +29,7 @@ LocalFile="本地文件" Looping="循环" Input="输入" InputFormat="输入格式" -BufferingMB="网络缓冲 (MB)" +BufferingMB="网络缓冲" HardwareDecode="在可用时使用硬件解码" ClearOnMediaEnd="播放结束时不显示任何内容" Advanced="高级" @@ -41,7 +41,7 @@ ColorRange.Auto="自动" ColorRange.Partial="局部" ColorRange.Full="全部" RestartMedia="重新启动媒体" -SpeedPercentage="速度(百分比)" +SpeedPercentage="速度" Seekable="可搜索" MediaFileFilter.AllMediaFiles="所有媒体文件" diff --git a/plugins/obs-ffmpeg/data/locale/zh-TW.ini b/plugins/obs-ffmpeg/data/locale/zh-TW.ini index f1683d8..3b1f870 100644 --- a/plugins/obs-ffmpeg/data/locale/zh-TW.ini +++ b/plugins/obs-ffmpeg/data/locale/zh-TW.ini @@ -29,7 +29,7 @@ LocalFile="本機檔案" Looping="循環" Input="輸入" InputFormat="輸入格式" -BufferingMB="網路緩衝 (MB)" +BufferingMB="網路緩衝" HardwareDecode="盡可能使用硬體解碼" ClearOnMediaEnd="播放結束時不顯示任何內容" Advanced="進階" @@ -41,7 +41,7 @@ ColorRange.Auto="自動" ColorRange.Partial="部分" ColorRange.Full="全部" RestartMedia="重新播放媒體" -SpeedPercentage="速度 (百分比)" +SpeedPercentage="速度" Seekable="可查找" MediaFileFilter.AllMediaFiles="所有媒體檔案" diff --git a/plugins/obs-ffmpeg/external/.clang-format b/plugins/obs-ffmpeg/external/.clang-format new file mode 100644 index 0000000..6420a46 --- /dev/null +++ b/plugins/obs-ffmpeg/external/.clang-format @@ -0,0 +1,3 @@ +Language: Cpp +SortIncludes: false +DisableFormat: true diff --git a/plugins/obs-ffmpeg/dynlink_cuda.h b/plugins/obs-ffmpeg/external/dynlink_cuda.h similarity index 100% rename from plugins/obs-ffmpeg/dynlink_cuda.h rename to plugins/obs-ffmpeg/external/dynlink_cuda.h diff --git a/plugins/obs-ffmpeg/nvEncodeAPI.h b/plugins/obs-ffmpeg/external/nvEncodeAPI.h similarity index 100% rename from plugins/obs-ffmpeg/nvEncodeAPI.h rename to plugins/obs-ffmpeg/external/nvEncodeAPI.h diff --git a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c index 728555d..7950bb8 100644 --- a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c +++ b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c @@ -39,8 +39,8 @@ struct resize_buf { uint8_t *buf; - size_t size; - size_t capacity; + size_t size; + size_t capacity; }; static inline void resize_buf_resize(struct resize_buf *rb, size_t size) @@ -96,15 +96,15 @@ struct header { }; struct ffmpeg_mux { - AVFormatContext *output; - AVStream *video_stream; - AVStream **audio_streams; - struct main_params params; - struct audio_params *audio; - struct header video_header; - struct header *audio_header; - int num_audio_streams; - bool initialized; + AVFormatContext *output; + AVStream *video_stream; + AVStream **audio_streams; + struct main_params params; + struct audio_params *audio; + struct header video_header; + struct header *audio_header; + int num_audio_streams; + bool initialized; char error[4096]; }; @@ -158,7 +158,7 @@ static void ffmpeg_mux_free(struct ffmpeg_mux *ffm) } static bool get_opt_str(int *p_argc, char ***p_argv, char **str, - const char *opt) + const char *opt) { int argc = *p_argc; char **argv = *p_argv; @@ -187,7 +187,7 @@ static bool get_opt_int(int *p_argc, char ***p_argv, int *i, const char *opt) } static bool get_audio_params(struct audio_params *audio, int *argc, - char ***argv) + char ***argv) { if (!get_opt_str(argc, argv, &audio->name, "audio track name")) return false; @@ -201,7 +201,7 @@ static bool get_audio_params(struct audio_params *audio, int *argc, } static bool init_params(int *argc, char ***argv, struct main_params *params, - struct audio_params **p_audio) + struct audio_params **p_audio) { struct audio_params *audio = NULL; @@ -228,7 +228,8 @@ static bool init_params(int *argc, char ***argv, struct main_params *params, if (params->has_video) { if (!get_opt_str(argc, argv, ¶ms->vcodec, "video codec")) return false; - if (!get_opt_int(argc, argv, ¶ms->vbitrate,"video bitrate")) + if (!get_opt_int(argc, argv, ¶ms->vbitrate, + "video bitrate")) return false; if (!get_opt_int(argc, argv, ¶ms->width, "video width")) return false; @@ -262,7 +263,7 @@ static bool init_params(int *argc, char ***argv, struct main_params *params, } static bool new_stream(struct ffmpeg_mux *ffm, AVStream **stream, - const char *name, enum AVCodecID *id) + const char *name, enum AVCodecID *id) { const AVCodecDescriptor *desc = avcodec_descriptor_get_by_name(name); AVCodec *codec; @@ -282,11 +283,12 @@ static bool new_stream(struct ffmpeg_mux *ffm, AVStream **stream, *stream = avformat_new_stream(ffm->output, codec); if (!*stream) { - fprintf(stderr, "Couldn't create stream for encoder '%s'\n", name); + fprintf(stderr, "Couldn't create stream for encoder '%s'\n", + name); return false; } - (*stream)->id = ffm->output->nb_streams-1; + (*stream)->id = ffm->output->nb_streams - 1; return true; } @@ -296,21 +298,21 @@ static void create_video_stream(struct ffmpeg_mux *ffm) void *extradata = NULL; if (!new_stream(ffm, &ffm->video_stream, ffm->params.vcodec, - &ffm->output->oformat->video_codec)) + &ffm->output->oformat->video_codec)) return; if (ffm->video_header.size) { extradata = av_memdup(ffm->video_header.data, - ffm->video_header.size); + ffm->video_header.size); } - context = ffm->video_stream->codec; - context->bit_rate = ffm->params.vbitrate * 1000; - context->width = ffm->params.width; - context->height = ffm->params.height; - context->coded_width = ffm->params.width; - context->coded_height = ffm->params.height; - context->extradata = extradata; + context = ffm->video_stream->codec; + context->bit_rate = ffm->params.vbitrate * 1000; + context->width = ffm->params.width; + context->height = ffm->params.height; + context->coded_width = ffm->params.width; + context->coded_height = ffm->params.height; + context->extradata = extradata; context->extradata_size = ffm->video_header.size; context->time_base = (AVRational){ffm->params.fps_den, ffm->params.fps_num}; @@ -329,7 +331,7 @@ static void create_audio_stream(struct ffmpeg_mux *ffm, int idx) void *extradata = NULL; if (!new_stream(ffm, &stream, ffm->params.acodec, - &ffm->output->oformat->audio_codec)) + &ffm->output->oformat->audio_codec)) return; ffm->audio_streams[idx] = stream; @@ -340,19 +342,19 @@ static void create_audio_stream(struct ffmpeg_mux *ffm, int idx) if (ffm->audio_header[idx].size) { extradata = av_memdup(ffm->audio_header[idx].data, - ffm->audio_header[idx].size); + ffm->audio_header[idx].size); } - context = stream->codec; - context->bit_rate = ffm->audio[idx].abitrate * 1000; - context->channels = ffm->audio[idx].channels; - context->sample_rate = ffm->audio[idx].sample_rate; - context->sample_fmt = AV_SAMPLE_FMT_S16; - context->time_base = stream->time_base; - context->extradata = extradata; + context = stream->codec; + context->bit_rate = ffm->audio[idx].abitrate * 1000; + context->channels = ffm->audio[idx].channels; + context->sample_rate = ffm->audio[idx].sample_rate; + context->sample_fmt = AV_SAMPLE_FMT_S16; + context->time_base = stream->time_base; + context->extradata = extradata; context->extradata_size = ffm->audio_header[idx].size; context->channel_layout = - av_get_default_channel_layout(context->channels); + av_get_default_channel_layout(context->channels); //AVlib default channel layout for 4 channels is 4.0 ; fix for quad if (context->channels == 4) context->channel_layout = av_get_channel_layout("quad"); @@ -372,7 +374,7 @@ static bool init_streams(struct ffmpeg_mux *ffm) if (ffm->params.tracks) { ffm->audio_streams = - calloc(1, ffm->params.tracks * sizeof(void*)); + calloc(1, ffm->params.tracks * sizeof(void *)); for (int i = 0; i < ffm->params.tracks; i++) create_audio_stream(ffm, i); @@ -392,20 +394,20 @@ static void set_header(struct header *header, uint8_t *data, size_t size) } static void ffmpeg_mux_header(struct ffmpeg_mux *ffm, uint8_t *data, - struct ffm_packet_info *info) + struct ffm_packet_info *info) { if (info->type == FFM_PACKET_VIDEO) { set_header(&ffm->video_header, data, (size_t)info->size); } else { set_header(&ffm->audio_header[info->index], data, - (size_t)info->size); + (size_t)info->size); } } static size_t safe_read(void *vdata, size_t size) { uint8_t *data = vdata; - size_t total = size; + size_t total = size; while (size > 0) { size_t in_size = fread(data, 1, size, stdin); @@ -470,20 +472,20 @@ static inline int open_output_file(struct ffmpeg_mux *ffm) AVIO_FLAG_WRITE); if (ret < 0) { fprintf(stderr, "Couldn't open '%s', %s", - ffm->params.file, av_err2str(ret)); + ffm->params.file, av_err2str(ret)); return FFM_ERROR; } } strncpy(ffm->output->filename, ffm->params.file, - sizeof(ffm->output->filename)); + sizeof(ffm->output->filename)); ffm->output->filename[sizeof(ffm->output->filename) - 1] = 0; AVDictionary *dict = NULL; - if ((ret = av_dict_parse_string(&dict, ffm->params.muxer_settings, - "=", " ", 0))) { + if ((ret = av_dict_parse_string(&dict, ffm->params.muxer_settings, "=", + " ", 0))) { fprintf(stderr, "Failed to parse muxer settings: %s\n%s", - av_err2str(ret), ffm->params.muxer_settings); + av_err2str(ret), ffm->params.muxer_settings); av_dict_free(&dict); } @@ -493,7 +495,7 @@ static inline int open_output_file(struct ffmpeg_mux *ffm) AVDictionaryEntry *entry = NULL; while ((entry = av_dict_get(dict, "", entry, - AV_DICT_IGNORE_SUFFIX))) + AV_DICT_IGNORE_SUFFIX))) printf("\n\t%s=%s", entry->key, entry->value); printf("\n"); @@ -501,8 +503,8 @@ static inline int open_output_file(struct ffmpeg_mux *ffm) ret = avformat_write_header(ffm->output, &dict); if (ret < 0) { - fprintf(stderr, "Error opening '%s': %s", - ffm->params.file, av_err2str(ret)); + fprintf(stderr, "Error opening '%s': %s", ffm->params.file, + av_err2str(ret)); av_dict_free(&dict); @@ -522,15 +524,15 @@ static int ffmpeg_mux_init_context(struct ffmpeg_mux *ffm) output_format = av_guess_format(NULL, ffm->params.file, NULL); if (output_format == NULL) { fprintf(stderr, "Couldn't find an appropriate muxer for '%s'\n", - ffm->params.file); + ffm->params.file); return FFM_ERROR; } - ret = avformat_alloc_output_context2(&ffm->output, output_format, - NULL, NULL); + ret = avformat_alloc_output_context2(&ffm->output, output_format, NULL, + NULL); if (ret < 0) { fprintf(stderr, "Couldn't initialize output context: %s\n", - av_err2str(ret)); + av_err2str(ret)); return FFM_ERROR; } @@ -552,7 +554,7 @@ static int ffmpeg_mux_init_context(struct ffmpeg_mux *ffm) } static int ffmpeg_mux_init_internal(struct ffmpeg_mux *ffm, int argc, - char *argv[]) + char *argv[]) { argc--; argv++; @@ -564,7 +566,9 @@ static int ffmpeg_mux_init_internal(struct ffmpeg_mux *ffm, int argc, calloc(1, sizeof(struct header) * ffm->params.tracks); } +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) av_register_all(); +#endif if (!ffmpeg_mux_get_extra_data(ffm)) return FFM_ERROR; @@ -587,7 +591,7 @@ static int ffmpeg_mux_init(struct ffmpeg_mux *ffm, int argc, char *argv[]) } static inline int get_index(struct ffmpeg_mux *ffm, - struct ffm_packet_info *info) + struct ffm_packet_info *info) { if (info->type == FFM_PACKET_VIDEO) { if (ffm->video_stream) { @@ -612,12 +616,12 @@ static inline int64_t rescale_ts(struct ffmpeg_mux *ffm, int64_t val, int idx) AVStream *stream = get_stream(ffm, idx); return av_rescale_q_rnd(val / stream->codec->time_base.num, - stream->codec->time_base, stream->time_base, - AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); + stream->codec->time_base, stream->time_base, + AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); } static inline bool ffmpeg_mux_packet(struct ffmpeg_mux *ffm, uint8_t *buf, - struct ffm_packet_info *info) + struct ffm_packet_info *info) { int idx = get_index(ffm, info); AVPacket packet = {0}; @@ -627,7 +631,7 @@ static inline bool ffmpeg_mux_packet(struct ffmpeg_mux *ffm, uint8_t *buf, return true; } - av_init_packet(&packet); + av_init_packet(&packet); packet.data = buf; packet.size = (int)info->size; @@ -660,16 +664,16 @@ int main(int argc, char *argv[]) SetErrorMode(SEM_FAILCRITICALERRORS); - argv = malloc(argc * sizeof(char*)); + argv = malloc(argc * sizeof(char *)); for (int i = 0; i < argc; i++) { size_t len = wcslen(argv_w[i]); int size; size = WideCharToMultiByte(CP_UTF8, 0, argv_w[i], (int)len, - NULL, 0, NULL, NULL); + NULL, 0, NULL, NULL); argv[i] = malloc(size + 1); WideCharToMultiByte(CP_UTF8, 0, argv_w[i], (int)len, argv[i], - size + 1, NULL, NULL); + size + 1, NULL, NULL); argv[i][size] = 0; } diff --git a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.h b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.h index 1920ae2..9f7788f 100644 --- a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.h +++ b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.h @@ -20,18 +20,18 @@ enum ffm_packet_type { FFM_PACKET_VIDEO, - FFM_PACKET_AUDIO + FFM_PACKET_AUDIO, }; -#define FFM_SUCCESS 0 -#define FFM_ERROR -1 +#define FFM_SUCCESS 0 +#define FFM_ERROR -1 #define FFM_UNSUPPORTED -2 struct ffm_packet_info { - int64_t pts; - int64_t dts; - uint32_t size; - uint32_t index; + int64_t pts; + int64_t dts; + uint32_t size; + uint32_t index; enum ffm_packet_type type; - bool keyframe; + bool keyframe; }; diff --git a/plugins/obs-ffmpeg/jim-nvenc-helpers.c b/plugins/obs-ffmpeg/jim-nvenc-helpers.c index 68d20b3..2caa89c 100644 --- a/plugins/obs-ffmpeg/jim-nvenc-helpers.c +++ b/plugins/obs-ffmpeg/jim-nvenc-helpers.c @@ -7,16 +7,16 @@ static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER; NV_ENCODE_API_FUNCTION_LIST nv = {NV_ENCODE_API_FUNCTION_LIST_VER}; NV_CREATE_INSTANCE_FUNC nv_create_instance = NULL; -#define error(format, ...) \ - blog(LOG_ERROR, "[jim-nvenc] " format, ##__VA_ARGS__) +#define error(format, ...) blog(LOG_ERROR, "[jim-nvenc] " format, ##__VA_ARGS__) -static inline bool nv_failed(NVENCSTATUS err, const char *func, const char *call) +static inline bool nv_failed(NVENCSTATUS err, const char *func, + const char *call) { if (err == NV_ENC_SUCCESS) return false; error("%s: %s failed: %d (%s)", func, call, (int)err, - nv_error_name(err)); + nv_error_name(err)); return true; } @@ -24,7 +24,7 @@ static inline bool nv_failed(NVENCSTATUS err, const char *func, const char *call bool load_nvenc_lib(void) { - if (sizeof(void*) == 8) { + if (sizeof(void *) == 8) { nvenc_lib = os_dlopen("nvEncodeAPI64.dll"); } else { nvenc_lib = os_dlopen("nvEncodeAPI.dll"); @@ -42,40 +42,41 @@ static void *load_nv_func(const char *func) return func_ptr; } -typedef NVENCSTATUS (NVENCAPI *NV_MAX_VER_FUNC)(uint32_t*); +typedef NVENCSTATUS(NVENCAPI *NV_MAX_VER_FUNC)(uint32_t *); const char *nv_error_name(NVENCSTATUS err) { #define RETURN_CASE(x) \ - case x: return #x + case x: \ + return #x switch (err) { - RETURN_CASE(NV_ENC_SUCCESS); - RETURN_CASE(NV_ENC_ERR_NO_ENCODE_DEVICE); - RETURN_CASE(NV_ENC_ERR_UNSUPPORTED_DEVICE); - RETURN_CASE(NV_ENC_ERR_INVALID_ENCODERDEVICE); - RETURN_CASE(NV_ENC_ERR_INVALID_DEVICE); - RETURN_CASE(NV_ENC_ERR_DEVICE_NOT_EXIST); - RETURN_CASE(NV_ENC_ERR_INVALID_PTR); - RETURN_CASE(NV_ENC_ERR_INVALID_EVENT); - RETURN_CASE(NV_ENC_ERR_INVALID_PARAM); - RETURN_CASE(NV_ENC_ERR_INVALID_CALL); - RETURN_CASE(NV_ENC_ERR_OUT_OF_MEMORY); - RETURN_CASE(NV_ENC_ERR_ENCODER_NOT_INITIALIZED); - RETURN_CASE(NV_ENC_ERR_UNSUPPORTED_PARAM); - RETURN_CASE(NV_ENC_ERR_LOCK_BUSY); - RETURN_CASE(NV_ENC_ERR_NOT_ENOUGH_BUFFER); - RETURN_CASE(NV_ENC_ERR_INVALID_VERSION); - RETURN_CASE(NV_ENC_ERR_MAP_FAILED); - RETURN_CASE(NV_ENC_ERR_NEED_MORE_INPUT); - RETURN_CASE(NV_ENC_ERR_ENCODER_BUSY); - RETURN_CASE(NV_ENC_ERR_EVENT_NOT_REGISTERD); - RETURN_CASE(NV_ENC_ERR_GENERIC); - RETURN_CASE(NV_ENC_ERR_INCOMPATIBLE_CLIENT_KEY); - RETURN_CASE(NV_ENC_ERR_UNIMPLEMENTED); - RETURN_CASE(NV_ENC_ERR_RESOURCE_REGISTER_FAILED); - RETURN_CASE(NV_ENC_ERR_RESOURCE_NOT_REGISTERED); - RETURN_CASE(NV_ENC_ERR_RESOURCE_NOT_MAPPED); + RETURN_CASE(NV_ENC_SUCCESS); + RETURN_CASE(NV_ENC_ERR_NO_ENCODE_DEVICE); + RETURN_CASE(NV_ENC_ERR_UNSUPPORTED_DEVICE); + RETURN_CASE(NV_ENC_ERR_INVALID_ENCODERDEVICE); + RETURN_CASE(NV_ENC_ERR_INVALID_DEVICE); + RETURN_CASE(NV_ENC_ERR_DEVICE_NOT_EXIST); + RETURN_CASE(NV_ENC_ERR_INVALID_PTR); + RETURN_CASE(NV_ENC_ERR_INVALID_EVENT); + RETURN_CASE(NV_ENC_ERR_INVALID_PARAM); + RETURN_CASE(NV_ENC_ERR_INVALID_CALL); + RETURN_CASE(NV_ENC_ERR_OUT_OF_MEMORY); + RETURN_CASE(NV_ENC_ERR_ENCODER_NOT_INITIALIZED); + RETURN_CASE(NV_ENC_ERR_UNSUPPORTED_PARAM); + RETURN_CASE(NV_ENC_ERR_LOCK_BUSY); + RETURN_CASE(NV_ENC_ERR_NOT_ENOUGH_BUFFER); + RETURN_CASE(NV_ENC_ERR_INVALID_VERSION); + RETURN_CASE(NV_ENC_ERR_MAP_FAILED); + RETURN_CASE(NV_ENC_ERR_NEED_MORE_INPUT); + RETURN_CASE(NV_ENC_ERR_ENCODER_BUSY); + RETURN_CASE(NV_ENC_ERR_EVENT_NOT_REGISTERD); + RETURN_CASE(NV_ENC_ERR_GENERIC); + RETURN_CASE(NV_ENC_ERR_INCOMPATIBLE_CLIENT_KEY); + RETURN_CASE(NV_ENC_ERR_UNIMPLEMENTED); + RETURN_CASE(NV_ENC_ERR_RESOURCE_REGISTER_FAILED); + RETURN_CASE(NV_ENC_ERR_RESOURCE_NOT_REGISTERED); + RETURN_CASE(NV_ENC_ERR_RESOURCE_NOT_MAPPED); } #undef RETURN_CASE @@ -91,8 +92,8 @@ static inline bool init_nvenc_internal(void) return success; initialized = true; - NV_MAX_VER_FUNC nv_max_ver = (NV_MAX_VER_FUNC) - load_nv_func("NvEncodeAPIGetMaxSupportedVersion"); + NV_MAX_VER_FUNC nv_max_ver = (NV_MAX_VER_FUNC)load_nv_func( + "NvEncodeAPIGetMaxSupportedVersion"); if (!nv_max_ver) { return false; } @@ -102,16 +103,16 @@ static inline bool init_nvenc_internal(void) return false; } - uint32_t cur_ver = - (NVENCAPI_MAJOR_VERSION << 4) | NVENCAPI_MINOR_VERSION; + uint32_t cur_ver = (NVENCAPI_MAJOR_VERSION << 4) | + NVENCAPI_MINOR_VERSION; if (cur_ver > ver) { error("Current driver version does not support this NVENC " - "version, please upgrade your driver"); + "version, please upgrade your driver"); return false; } - nv_create_instance = (NV_CREATE_INSTANCE_FUNC) - load_nv_func("NvEncodeAPICreateInstance"); + nv_create_instance = (NV_CREATE_INSTANCE_FUNC)load_nv_func( + "NvEncodeAPICreateInstance"); if (!nv_create_instance) { return false; } diff --git a/plugins/obs-ffmpeg/jim-nvenc.c b/plugins/obs-ffmpeg/jim-nvenc.c index 6eae7f9..374da1d 100644 --- a/plugins/obs-ffmpeg/jim-nvenc.c +++ b/plugins/obs-ffmpeg/jim-nvenc.c @@ -12,17 +12,16 @@ #define EXTRA_BUFFERS 5 -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[jim-nvenc: '%s'] " format, \ - obs_encoder_get_name(enc->encoder), ##__VA_ARGS__) + obs_encoder_get_name(enc->encoder), ##__VA_ARGS__) -#define error(format, ...) do_log(LOG_ERROR, format, ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) -#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#define error(format, ...) do_log(LOG_ERROR, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) -#define error_hr(msg) \ - error("%s: %s: 0x%08lX", __FUNCTION__, msg, (uint32_t)hr); +#define error_hr(msg) error("%s: %s: 0x%08lX", __FUNCTION__, msg, (uint32_t)hr); struct nv_bitstream; struct nv_texture; @@ -39,57 +38,57 @@ struct handle_tex { struct nvenc_data { obs_encoder_t *encoder; - void *session; + void *session; NV_ENC_INITIALIZE_PARAMS params; - NV_ENC_CONFIG config; - size_t buf_count; - size_t output_delay; - size_t buffers_queued; - size_t next_bitstream; - size_t cur_bitstream; - bool encode_started; - bool first_packet; - bool can_change_bitrate; - bool bframes; + NV_ENC_CONFIG config; + size_t buf_count; + size_t output_delay; + size_t buffers_queued; + size_t next_bitstream; + size_t cur_bitstream; + bool encode_started; + bool first_packet; + bool can_change_bitrate; + bool bframes; DARRAY(struct nv_bitstream) bitstreams; - DARRAY(struct nv_texture) textures; - DARRAY(struct handle_tex) input_textures; - struct circlebuf dts_list; + DARRAY(struct nv_texture) textures; + DARRAY(struct handle_tex) input_textures; + struct circlebuf dts_list; DARRAY(uint8_t) packet_data; - int64_t packet_pts; - bool packet_keyframe; + int64_t packet_pts; + bool packet_keyframe; - ID3D11Device *device; + ID3D11Device *device; ID3D11DeviceContext *context; uint32_t cx; uint32_t cy; uint8_t *header; - size_t header_size; + size_t header_size; uint8_t *sei; - size_t sei_size; + size_t sei_size; }; /* ------------------------------------------------------------------------- */ /* Bitstream Buffer */ struct nv_bitstream { - void *ptr; + void *ptr; HANDLE event; }; static inline bool nv_failed(struct nvenc_data *enc, NVENCSTATUS err, - const char *func, const char *call) + const char *func, const char *call) { if (err == NV_ENC_SUCCESS) return false; error("%s: %s failed: %d (%s)", func, call, (int)err, - nv_error_name(err)); + nv_error_name(err)); return true; } @@ -97,7 +96,8 @@ static inline bool nv_failed(struct nvenc_data *enc, NVENCSTATUS err, static bool nv_bitstream_init(struct nvenc_data *enc, struct nv_bitstream *bs) { - NV_ENC_CREATE_BITSTREAM_BUFFER buf = {NV_ENC_CREATE_BITSTREAM_BUFFER_VER}; + NV_ENC_CREATE_BITSTREAM_BUFFER buf = { + NV_ENC_CREATE_BITSTREAM_BUFFER_VER}; NV_ENC_EVENT_PARAMS params = {NV_ENC_EVENT_PARAMS_VER}; HANDLE event = NULL; @@ -126,7 +126,7 @@ fail: } if (buf.bitstreamBuffer) { nv.nvEncDestroyBitstreamBuffer(enc->session, - buf.bitstreamBuffer); + buf.bitstreamBuffer); } return false; } @@ -147,9 +147,9 @@ static void nv_bitstream_free(struct nvenc_data *enc, struct nv_bitstream *bs) /* Texture Resource */ struct nv_texture { - void *res; + void *res; ID3D11Texture2D *tex; - void *mapped_res; + void *mapped_res; }; static bool nv_texture_init(struct nvenc_data *enc, struct nv_texture *nvtex) @@ -159,13 +159,13 @@ static bool nv_texture_init(struct nvenc_data *enc, struct nv_texture *nvtex) HRESULT hr; D3D11_TEXTURE2D_DESC desc = {0}; - desc.Width = enc->cx; - desc.Height = enc->cy; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_NV12; - desc.SampleDesc.Count = 1; - desc.BindFlags = D3D11_BIND_RENDER_TARGET; + desc.Width = enc->cx; + desc.Height = enc->cy; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_NV12; + desc.SampleDesc.Count = 1; + desc.BindFlags = D3D11_BIND_RENDER_TARGET; hr = device->lpVtbl->CreateTexture2D(device, &desc, NULL, &tex); if (FAILED(hr)) { @@ -176,11 +176,11 @@ static bool nv_texture_init(struct nvenc_data *enc, struct nv_texture *nvtex) tex->lpVtbl->SetEvictionPriority(tex, DXGI_RESOURCE_PRIORITY_MAXIMUM); NV_ENC_REGISTER_RESOURCE res = {NV_ENC_REGISTER_RESOURCE_VER}; - res.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX; - res.resourceToRegister = tex; - res.width = enc->cx; - res.height = enc->cy; - res.bufferFormat = NV_ENC_BUFFER_FORMAT_NV12; + res.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX; + res.resourceToRegister = tex; + res.width = enc->cx; + res.height = enc->cy; + res.bufferFormat = NV_ENC_BUFFER_FORMAT_NV12; if (NV_FAILED(nv.nvEncRegisterResource(enc->session, &res))) { tex->lpVtbl->Release(tex); @@ -197,7 +197,7 @@ static void nv_texture_free(struct nvenc_data *enc, struct nv_texture *nvtex) if (nvtex->res) { if (nvtex->mapped_res) { nv.nvEncUnmapInputResource(enc->session, - nvtex->mapped_res); + nvtex->mapped_res); } nv.nvEncUnregisterResource(enc->session, nvtex->res); nvtex->tex->lpVtbl->Release(nvtex->tex); @@ -235,13 +235,16 @@ static bool nvenc_update(void *data, obs_data_t *settings) int bitrate = (int)obs_data_get_int(settings, "bitrate"); enc->config.rcParams.averageBitRate = bitrate * 1000; - enc->config.rcParams.maxBitRate = bitrate * 1000; + enc->config.rcParams.maxBitRate = bitrate * 1000; NV_ENC_RECONFIGURE_PARAMS params = {0}; - params.version = NV_ENC_RECONFIGURE_PARAMS_VER; - params.reInitEncodeParams = enc->params; + params.version = NV_ENC_RECONFIGURE_PARAMS_VER; + params.reInitEncodeParams = enc->params; + params.resetEncoder = 1; + params.forceIDR = 1; - if (FAILED(nv.nvEncReconfigureEncoder(enc->session, ¶ms))) { + if (NV_FAILED(nv.nvEncReconfigureEncoder(enc->session, + ¶ms))) { return false; } } @@ -261,28 +264,28 @@ static HANDLE get_lib(struct nvenc_data *enc, const char *lib) return mod; } -typedef HRESULT (WINAPI *CREATEDXGIFACTORY1PROC)(REFIID, void **); +typedef HRESULT(WINAPI *CREATEDXGIFACTORY1PROC)(REFIID, void **); static bool init_d3d11(struct nvenc_data *enc, obs_data_t *settings) { - HMODULE dxgi = get_lib(enc, "DXGI.dll"); - HMODULE d3d11 = get_lib(enc, "D3D11.dll"); - CREATEDXGIFACTORY1PROC create_dxgi; + HMODULE dxgi = get_lib(enc, "DXGI.dll"); + HMODULE d3d11 = get_lib(enc, "D3D11.dll"); + CREATEDXGIFACTORY1PROC create_dxgi; PFN_D3D11_CREATE_DEVICE create_device; - IDXGIFactory1 *factory; - IDXGIAdapter *adapter; - ID3D11Device *device; - ID3D11DeviceContext *context; - HRESULT hr; + IDXGIFactory1 *factory; + IDXGIAdapter *adapter; + ID3D11Device *device; + ID3D11DeviceContext *context; + HRESULT hr; if (!dxgi || !d3d11) { return false; } - create_dxgi = (CREATEDXGIFACTORY1PROC)GetProcAddress(dxgi, - "CreateDXGIFactory1"); - create_device = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(d3d11, - "D3D11CreateDevice"); + create_dxgi = (CREATEDXGIFACTORY1PROC)GetProcAddress( + dxgi, "CreateDXGIFactory1"); + create_device = (PFN_D3D11_CREATE_DEVICE)GetProcAddress( + d3d11, "D3D11CreateDevice"); if (!create_dxgi || !create_device) { error("Failed to load D3D11/DXGI procedures"); @@ -302,8 +305,8 @@ static bool init_d3d11(struct nvenc_data *enc, obs_data_t *settings) return false; } - hr = create_device(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, - NULL, 0, D3D11_SDK_VERSION, &device, NULL, &context); + hr = create_device(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, NULL, 0, + D3D11_SDK_VERSION, &device, NULL, &context); adapter->lpVtbl->Release(adapter); if (FAILED(hr)) { error_hr("D3D11CreateDevice failed"); @@ -317,8 +320,8 @@ static bool init_d3d11(struct nvenc_data *enc, obs_data_t *settings) static bool init_session(struct nvenc_data *enc) { - NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS params = - {NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER}; + NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS params = { + NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER}; params.device = enc->device; params.deviceType = NV_ENC_DEVICE_TYPE_DIRECTX; params.apiVersion = NVENCAPI_VERSION; @@ -384,19 +387,19 @@ static bool init_encoder(struct nvenc_data *enc, obs_data_t *settings) } if (astrcmpi(rc, "lossless") == 0) { - nv_preset = hp - ? NV_ENC_PRESET_LOSSLESS_HP_GUID - : NV_ENC_PRESET_LOSSLESS_DEFAULT_GUID; + nv_preset = hp ? NV_ENC_PRESET_LOSSLESS_HP_GUID + : NV_ENC_PRESET_LOSSLESS_DEFAULT_GUID; } /* -------------------------- */ /* get preset default config */ - NV_ENC_PRESET_CONFIG preset_config = - {NV_ENC_PRESET_CONFIG_VER, {NV_ENC_CONFIG_VER}}; + NV_ENC_PRESET_CONFIG preset_config = {NV_ENC_PRESET_CONFIG_VER, + {NV_ENC_CONFIG_VER}}; err = nv.nvEncGetEncodePresetConfig(enc->session, - NV_ENC_CODEC_H264_GUID, nv_preset, &preset_config); + NV_ENC_CODEC_H264_GUID, nv_preset, + &preset_config); if (nv_failed(enc, err, __FUNCTION__, "nvEncGetEncodePresetConfig")) { return false; } @@ -406,9 +409,8 @@ static bool init_encoder(struct nvenc_data *enc, obs_data_t *settings) enc->config = preset_config.presetCfg; - uint32_t gop_size = (keyint_sec) - ? keyint_sec * voi->fps_num / voi->fps_den - : 250; + uint32_t gop_size = + (keyint_sec) ? keyint_sec * voi->fps_num / voi->fps_den : 250; NV_ENC_INITIALIZE_PARAMS *params = &enc->params; NV_ENC_CONFIG *config = &enc->config; @@ -461,9 +463,8 @@ static bool init_encoder(struct nvenc_data *enc, obs_data_t *settings) enc->can_change_bitrate = nv_get_cap(enc, NV_ENC_CAPS_SUPPORT_DYN_BITRATE_CHANGE); - config->rcParams.rateControlMode = twopass - ? NV_ENC_PARAMS_RC_VBR_HQ - : NV_ENC_PARAMS_RC_VBR; + config->rcParams.rateControlMode = twopass ? NV_ENC_PARAMS_RC_VBR_HQ + : NV_ENC_PARAMS_RC_VBR; if (astrcmpi(rc, "cqp") == 0 || astrcmpi(rc, "lossless") == 0) { if (astrcmpi(rc, "lossless") == 0) @@ -480,9 +481,9 @@ static bool init_encoder(struct nvenc_data *enc, obs_data_t *settings) } else if (astrcmpi(rc, "vbr") != 0) { /* CBR by default */ h264_config->outputBufferingPeriodSEI = 1; - config->rcParams.rateControlMode = twopass - ? NV_ENC_PARAMS_RC_2_PASS_QUALITY - : NV_ENC_PARAMS_RC_CBR; + config->rcParams.rateControlMode = + twopass ? NV_ENC_PARAMS_RC_2_PASS_QUALITY + : NV_ENC_PARAMS_RC_CBR; } h264_config->outputPictureTimingSEI = 1; @@ -508,7 +509,7 @@ static bool init_encoder(struct nvenc_data *enc, obs_data_t *settings) } enc->buf_count = config->frameIntervalP + - config->rcParams.lookaheadDepth + EXTRA_BUFFERS; + config->rcParams.lookaheadDepth + EXTRA_BUFFERS; enc->output_delay = enc->buf_count - 1; info("settings:\n" @@ -524,12 +525,8 @@ static bool init_encoder(struct nvenc_data *enc, obs_data_t *settings) "\tb-frames: %d\n" "\tlookahead: %s\n" "\tpsycho_aq: %s\n", - rc, bitrate, cqp, gop_size, - preset, profile, - enc->cx, enc->cy, - twopass ? "true" : "false", - bf, - lookahead ? "true" : "false", + rc, bitrate, cqp, gop_size, preset, profile, enc->cx, enc->cy, + twopass ? "true" : "false", bf, lookahead ? "true" : "false", psycho_aq ? "true" : "false"); return true; @@ -662,12 +659,13 @@ static void nvenc_destroy(void *data) } static ID3D11Texture2D *get_tex_from_handle(struct nvenc_data *enc, - uint32_t handle, IDXGIKeyedMutex **km_out) + uint32_t handle, + IDXGIKeyedMutex **km_out) { - ID3D11Device *device = enc->device; + ID3D11Device *device = enc->device; IDXGIKeyedMutex *km; ID3D11Texture2D *input_tex; - HRESULT hr; + HRESULT hr; for (size_t i = 0; i < enc->input_textures.num; i++) { struct handle_tex *ht = &enc->input_textures.array[i]; @@ -678,15 +676,16 @@ static ID3D11Texture2D *get_tex_from_handle(struct nvenc_data *enc, } hr = device->lpVtbl->OpenSharedResource(device, - (HANDLE)(uintptr_t)handle, - &IID_ID3D11Texture2D, &input_tex); + (HANDLE)(uintptr_t)handle, + &IID_ID3D11Texture2D, + &input_tex); if (FAILED(hr)) { error_hr("OpenSharedResource failed"); return NULL; } hr = input_tex->lpVtbl->QueryInterface(input_tex, &IID_IDXGIKeyedMutex, - &km); + &km); if (FAILED(hr)) { error_hr("QueryInterface(IDXGIKeyedMutex) failed"); input_tex->lpVtbl->Release(input_tex); @@ -694,7 +693,7 @@ static ID3D11Texture2D *get_tex_from_handle(struct nvenc_data *enc, } input_tex->lpVtbl->SetEvictionPriority(input_tex, - DXGI_RESOURCE_PRIORITY_MAXIMUM); + DXGI_RESOURCE_PRIORITY_MAXIMUM); *km_out = km; @@ -717,15 +716,15 @@ static bool get_encoded_packet(struct nvenc_data *enc, bool finalize) size_t count = finalize ? enc->buffers_queued : 1; for (size_t i = 0; i < count; i++) { - size_t cur_bs_idx = enc->cur_bitstream; - struct nv_bitstream *bs = &enc->bitstreams.array[cur_bs_idx]; - struct nv_texture *nvtex = &enc->textures.array[cur_bs_idx]; + size_t cur_bs_idx = enc->cur_bitstream; + struct nv_bitstream *bs = &enc->bitstreams.array[cur_bs_idx]; + struct nv_texture *nvtex = &enc->textures.array[cur_bs_idx]; /* ---------------- */ NV_ENC_LOCK_BITSTREAM lock = {NV_ENC_LOCK_BITSTREAM_VER}; - lock.outputBitstream = bs->ptr; - lock.doNotWait = false; + lock.outputBitstream = bs->ptr; + lock.doNotWait = false; if (NV_FAILED(nv.nvEncLockBitstream(s, &lock))) { return false; @@ -736,19 +735,17 @@ static bool get_encoded_packet(struct nvenc_data *enc, bool finalize) size_t size; enc->first_packet = false; - obs_extract_avc_headers( - lock.bitstreamBufferPtr, - lock.bitstreamSizeInBytes, - &new_packet, &size, - &enc->header, &enc->header_size, - &enc->sei, &enc->sei_size); + obs_extract_avc_headers(lock.bitstreamBufferPtr, + lock.bitstreamSizeInBytes, + &new_packet, &size, + &enc->header, &enc->header_size, + &enc->sei, &enc->sei_size); da_copy_array(enc->packet_data, new_packet, size); bfree(new_packet); } else { - da_copy_array(enc->packet_data, - lock.bitstreamBufferPtr, - lock.bitstreamSizeInBytes); + da_copy_array(enc->packet_data, lock.bitstreamBufferPtr, + lock.bitstreamSizeInBytes); } enc->packet_pts = (int64_t)lock.outputTimeStamp; @@ -781,18 +778,19 @@ static bool get_encoded_packet(struct nvenc_data *enc, bool finalize) } static bool nvenc_encode_tex(void *data, uint32_t handle, int64_t pts, - uint64_t lock_key, uint64_t *next_key, - struct encoder_packet *packet, bool *received_packet) + uint64_t lock_key, uint64_t *next_key, + struct encoder_packet *packet, + bool *received_packet) { - struct nvenc_data *enc = data; - ID3D11Device *device = enc->device; + struct nvenc_data *enc = data; + ID3D11Device *device = enc->device; ID3D11DeviceContext *context = enc->context; - ID3D11Texture2D *input_tex; - ID3D11Texture2D *output_tex; - IDXGIKeyedMutex *km; - struct nv_texture *nvtex; + ID3D11Texture2D *input_tex; + ID3D11Texture2D *output_tex; + IDXGIKeyedMutex *km; + struct nv_texture *nvtex; struct nv_bitstream *bs; - NVENCSTATUS err; + NVENCSTATUS err; if (handle == GS_INVALID_HANDLE) { error("Encode failed: bad texture handle"); @@ -800,10 +798,10 @@ static bool nvenc_encode_tex(void *data, uint32_t handle, int64_t pts, return false; } - bs = &enc->bitstreams.array[enc->next_bitstream]; + bs = &enc->bitstreams.array[enc->next_bitstream]; nvtex = &enc->textures.array[enc->next_bitstream]; - input_tex = get_tex_from_handle(enc, handle, &km); + input_tex = get_tex_from_handle(enc, handle, &km); output_tex = nvtex->tex; if (!input_tex) { @@ -823,9 +821,8 @@ static bool nvenc_encode_tex(void *data, uint32_t handle, int64_t pts, km->lpVtbl->AcquireSync(km, lock_key, INFINITE); - context->lpVtbl->CopyResource(context, - (ID3D11Resource *)output_tex, - (ID3D11Resource *)input_tex); + context->lpVtbl->CopyResource(context, (ID3D11Resource *)output_tex, + (ID3D11Resource *)input_tex); km->lpVtbl->ReleaseSync(km, *next_key); @@ -833,7 +830,7 @@ static bool nvenc_encode_tex(void *data, uint32_t handle, int64_t pts, /* map output tex so nvenc can use it */ NV_ENC_MAP_INPUT_RESOURCE map = {NV_ENC_MAP_INPUT_RESOURCE_VER}; - map.registeredResource = nvtex->res; + map.registeredResource = nvtex->res; if (NV_FAILED(nv.nvEncMapInputResource(enc->session, &map))) { return false; } @@ -844,15 +841,15 @@ static bool nvenc_encode_tex(void *data, uint32_t handle, int64_t pts, /* do actual encode call */ NV_ENC_PIC_PARAMS params = {0}; - params.version = NV_ENC_PIC_PARAMS_VER; - params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME; - params.inputBuffer = nvtex->mapped_res; - params.bufferFmt = NV_ENC_BUFFER_FORMAT_NV12; - params.inputTimeStamp = (uint64_t)pts; - params.inputWidth = enc->cx; - params.inputHeight = enc->cy; - params.outputBitstream = bs->ptr; - params.completionEvent = bs->event; + params.version = NV_ENC_PIC_PARAMS_VER; + params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME; + params.inputBuffer = nvtex->mapped_res; + params.bufferFmt = NV_ENC_BUFFER_FORMAT_NV12; + params.inputTimeStamp = (uint64_t)pts; + params.inputWidth = enc->cx; + params.inputHeight = enc->cy; + params.outputBitstream = bs->ptr; + params.completionEvent = bs->event; err = nv.nvEncEncodePicture(enc->session, ¶ms); if (err != NV_ENC_SUCCESS && err != NV_ENC_ERR_NEED_MORE_INPUT) { @@ -886,11 +883,11 @@ static bool nvenc_encode_tex(void *data, uint32_t handle, int64_t pts, dts -= packet->timebase_num; *received_packet = true; - packet->data = enc->packet_data.array; - packet->size = enc->packet_data.num; - packet->type = OBS_ENCODER_VIDEO; - packet->pts = enc->packet_pts; - packet->dts = dts; + packet->data = enc->packet_data.array; + packet->size = enc->packet_data.num; + packet->type = OBS_ENCODER_VIDEO; + packet->pts = enc->packet_pts; + packet->dts = dts; packet->keyframe = enc->packet_keyframe; } else { *received_packet = false; @@ -911,7 +908,7 @@ static bool nvenc_extra_data(void *data, uint8_t **header, size_t *size) } *header = enc->header; - *size = enc->header_size; + *size = enc->header_size; return true; } @@ -923,23 +920,23 @@ static bool nvenc_sei_data(void *data, uint8_t **sei, size_t *size) return false; } - *sei = enc->sei; + *sei = enc->sei; *size = enc->sei_size; return true; } struct obs_encoder_info nvenc_info = { - .id = "jim_nvenc", - .codec = "h264", - .type = OBS_ENCODER_VIDEO, - .caps = OBS_ENCODER_CAP_PASS_TEXTURE, - .get_name = nvenc_get_name, - .create = nvenc_create, - .destroy = nvenc_destroy, - .update = nvenc_update, - .encode_texture = nvenc_encode_tex, - .get_defaults = nvenc_defaults, - .get_properties = nvenc_properties, - .get_extra_data = nvenc_extra_data, - .get_sei_data = nvenc_sei_data, + .id = "jim_nvenc", + .codec = "h264", + .type = OBS_ENCODER_VIDEO, + .caps = OBS_ENCODER_CAP_PASS_TEXTURE | OBS_ENCODER_CAP_DYN_BITRATE, + .get_name = nvenc_get_name, + .create = nvenc_create, + .destroy = nvenc_destroy, + .update = nvenc_update, + .encode_texture = nvenc_encode_tex, + .get_defaults = nvenc_defaults, + .get_properties = nvenc_properties, + .get_extra_data = nvenc_extra_data, + .get_sei_data = nvenc_sei_data, }; diff --git a/plugins/obs-ffmpeg/jim-nvenc.h b/plugins/obs-ffmpeg/jim-nvenc.h index c45ecdd..00ee545 100644 --- a/plugins/obs-ffmpeg/jim-nvenc.h +++ b/plugins/obs-ffmpeg/jim-nvenc.h @@ -4,9 +4,10 @@ #include #include -#include "nvEncodeAPI.h" +#include "external/nvEncodeAPI.h" -typedef NVENCSTATUS (NVENCAPI *NV_CREATE_INSTANCE_FUNC)(NV_ENCODE_API_FUNCTION_LIST*); +typedef NVENCSTATUS(NVENCAPI *NV_CREATE_INSTANCE_FUNC)( + NV_ENCODE_API_FUNCTION_LIST *); extern const char *nv_error_name(NVENCSTATUS err); extern NV_ENCODE_API_FUNCTION_LIST nv; diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c b/plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c index 7d6c5ae..2f2ee7d 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c @@ -26,68 +26,82 @@ #include "obs-ffmpeg-formats.h" #include "obs-ffmpeg-compat.h" -#define do_log(level, format, ...) \ - blog(level, "[FFmpeg %s encoder: '%s'] " format, \ - enc->type, \ - obs_encoder_get_name(enc->encoder), \ - ##__VA_ARGS__) +#define do_log(level, format, ...) \ + blog(level, "[FFmpeg %s encoder: '%s'] " format, enc->type, \ + obs_encoder_get_name(enc->encoder), ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) -#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) struct enc_encoder { - obs_encoder_t *encoder; + obs_encoder_t *encoder; - const char *type; + const char *type; - AVCodec *codec; - AVCodecContext *context; + AVCodec *codec; + AVCodecContext *context; - uint8_t *samples[MAX_AV_PLANES]; - AVFrame *aframe; - int64_t total_samples; + uint8_t *samples[MAX_AV_PLANES]; + AVFrame *aframe; + int64_t total_samples; - DARRAY(uint8_t) packet_buffer; + DARRAY(uint8_t) packet_buffer; - size_t audio_planes; - size_t audio_size; + size_t audio_planes; + size_t audio_size; - int frame_size; /* pretty much always 1024 for AAC */ - int frame_size_bytes; + int frame_size; /* pretty much always 1024 for AAC */ + int frame_size_bytes; }; static inline uint64_t convert_speaker_layout(enum speaker_layout layout) { switch (layout) { - case SPEAKERS_UNKNOWN: return 0; - case SPEAKERS_MONO: return AV_CH_LAYOUT_MONO; - case SPEAKERS_STEREO: return AV_CH_LAYOUT_STEREO; - case SPEAKERS_2POINT1: return AV_CH_LAYOUT_SURROUND; - case SPEAKERS_4POINT0: return AV_CH_LAYOUT_4POINT0; - case SPEAKERS_4POINT1: return AV_CH_LAYOUT_4POINT1; - case SPEAKERS_5POINT1: return AV_CH_LAYOUT_5POINT1_BACK; - case SPEAKERS_7POINT1: return AV_CH_LAYOUT_7POINT1; + case SPEAKERS_UNKNOWN: + return 0; + case SPEAKERS_MONO: + return AV_CH_LAYOUT_MONO; + case SPEAKERS_STEREO: + return AV_CH_LAYOUT_STEREO; + case SPEAKERS_2POINT1: + return AV_CH_LAYOUT_SURROUND; + case SPEAKERS_4POINT0: + return AV_CH_LAYOUT_4POINT0; + case SPEAKERS_4POINT1: + return AV_CH_LAYOUT_4POINT1; + case SPEAKERS_5POINT1: + return AV_CH_LAYOUT_5POINT1_BACK; + case SPEAKERS_7POINT1: + return AV_CH_LAYOUT_7POINT1; } /* shouldn't get here */ return 0; } -static inline enum speaker_layout convert_ff_channel_layout(uint64_t channel_layout) +static inline enum speaker_layout +convert_ff_channel_layout(uint64_t channel_layout) { switch (channel_layout) { - case AV_CH_LAYOUT_MONO: return SPEAKERS_MONO; - case AV_CH_LAYOUT_STEREO: return SPEAKERS_STEREO; - case AV_CH_LAYOUT_SURROUND: return SPEAKERS_2POINT1; - case AV_CH_LAYOUT_4POINT0: return SPEAKERS_4POINT0; - case AV_CH_LAYOUT_4POINT1: return SPEAKERS_4POINT1; - case AV_CH_LAYOUT_5POINT1_BACK: return SPEAKERS_5POINT1; - case AV_CH_LAYOUT_7POINT1: return SPEAKERS_7POINT1; + case AV_CH_LAYOUT_MONO: + return SPEAKERS_MONO; + case AV_CH_LAYOUT_STEREO: + return SPEAKERS_STEREO; + case AV_CH_LAYOUT_SURROUND: + return SPEAKERS_2POINT1; + case AV_CH_LAYOUT_4POINT0: + return SPEAKERS_4POINT0; + case AV_CH_LAYOUT_4POINT1: + return SPEAKERS_4POINT1; + case AV_CH_LAYOUT_5POINT1_BACK: + return SPEAKERS_5POINT1; + case AV_CH_LAYOUT_7POINT1: + return SPEAKERS_7POINT1; } /* shouldn't get here */ - return SPEAKERS_UNKNOWN; + return SPEAKERS_UNKNOWN; } static const char *aac_getname(void *unused) @@ -121,7 +135,7 @@ static bool initialize_codec(struct enc_encoder *enc) { int ret; - enc->aframe = av_frame_alloc(); + enc->aframe = av_frame_alloc(); if (!enc->aframe) { warn("Failed to allocate audio frame"); return false; @@ -144,7 +158,7 @@ static bool initialize_codec(struct enc_encoder *enc) enc->frame_size_bytes = enc->frame_size * (int)enc->audio_size; ret = av_samples_alloc(enc->samples, NULL, enc->context->channels, - enc->frame_size, enc->context->sample_fmt, 0); + enc->frame_size, enc->context->sample_fmt, 0); if (ret < 0) { warn("Failed to create audio buffer: %s", av_err2str(ret)); return false; @@ -158,11 +172,11 @@ static void init_sizes(struct enc_encoder *enc, audio_t *audio) const struct audio_output_info *aoi; enum audio_format format; - aoi = audio_output_get_info(audio); + aoi = audio_output_get_info(audio); format = convert_ffmpeg_sample_format(enc->context->sample_fmt); enc->audio_planes = get_audio_planes(format, aoi->speakers); - enc->audio_size = get_audio_size(format, aoi->speakers, 1); + enc->audio_size = get_audio_size(format, aoi->speakers, 1); } #ifndef MIN @@ -170,22 +184,24 @@ static void init_sizes(struct enc_encoder *enc, audio_t *audio) #endif static void *enc_create(obs_data_t *settings, obs_encoder_t *encoder, - const char *type, const char *alt) + const char *type, const char *alt) { struct enc_encoder *enc; - int bitrate = (int)obs_data_get_int(settings, "bitrate"); - audio_t *audio = obs_encoder_audio(encoder); + int bitrate = (int)obs_data_get_int(settings, "bitrate"); + audio_t *audio = obs_encoder_audio(encoder); +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) avcodec_register_all(); +#endif - enc = bzalloc(sizeof(struct enc_encoder)); + enc = bzalloc(sizeof(struct enc_encoder)); enc->encoder = encoder; - enc->codec = avcodec_find_encoder_by_name(type); - enc->type = type; + enc->codec = avcodec_find_encoder_by_name(type); + enc->type = type; if (!enc->codec && alt) { enc->codec = avcodec_find_encoder_by_name(alt); - enc->type = alt; + enc->type = alt; } blog(LOG_INFO, "---------------------------------"); @@ -206,14 +222,15 @@ static void *enc_create(obs_data_t *settings, obs_encoder_t *encoder, goto fail; } - enc->context->bit_rate = bitrate * 1000; + enc->context->bit_rate = bitrate * 1000; const struct audio_output_info *aoi; aoi = audio_output_get_info(audio); - enc->context->channels = (int)audio_output_get_channels(audio); + enc->context->channels = (int)audio_output_get_channels(audio); enc->context->channel_layout = convert_speaker_layout(aoi->speakers); enc->context->sample_rate = audio_output_get_sample_rate(audio); - enc->context->sample_fmt = enc->codec->sample_fmts ? - enc->codec->sample_fmts[0] : AV_SAMPLE_FMT_FLTP; + enc->context->sample_fmt = enc->codec->sample_fmts + ? enc->codec->sample_fmts[0] + : AV_SAMPLE_FMT_FLTP; /* check to make sure sample rate is supported */ if (enc->codec->supported_samplerates) { @@ -239,9 +256,9 @@ static void *enc_create(obs_data_t *settings, obs_encoder_t *encoder, } info("bitrate: %" PRId64 ", channels: %d, channel_layout: %x\n", - (int64_t)enc->context->bit_rate / 1000, - (int)enc->context->channels, - (unsigned int)enc->context->channel_layout); + (int64_t)enc->context->bit_rate / 1000, + (int)enc->context->channels, + (unsigned int)enc->context->channel_layout); init_sizes(enc, audio); @@ -268,22 +285,23 @@ static void *opus_create(obs_data_t *settings, obs_encoder_t *encoder) return enc_create(settings, encoder, "libopus", "opus"); } -static bool do_encode(struct enc_encoder *enc, - struct encoder_packet *packet, bool *received_packet) +static bool do_encode(struct enc_encoder *enc, struct encoder_packet *packet, + bool *received_packet) { AVRational time_base = {1, enc->context->sample_rate}; - AVPacket avpacket = {0}; - int got_packet; - int ret; + AVPacket avpacket = {0}; + int got_packet; + int ret; enc->aframe->nb_samples = enc->frame_size; - enc->aframe->pts = av_rescale_q(enc->total_samples, - (AVRational){1, enc->context->sample_rate}, - enc->context->time_base); + enc->aframe->pts = av_rescale_q( + enc->total_samples, (AVRational){1, enc->context->sample_rate}, + enc->context->time_base); - ret = avcodec_fill_audio_frame(enc->aframe, enc->context->channels, - enc->context->sample_fmt, enc->samples[0], - enc->frame_size_bytes * enc->context->channels, 1); + ret = avcodec_fill_audio_frame( + enc->aframe, enc->context->channels, enc->context->sample_fmt, + enc->samples[0], enc->frame_size_bytes * enc->context->channels, + 1); if (ret < 0) { warn("avcodec_fill_audio_frame failed: %s", av_err2str(ret)); return false; @@ -302,7 +320,7 @@ static bool do_encode(struct enc_encoder *enc, ret = 0; #else ret = avcodec_encode_audio2(enc->context, &avpacket, enc->aframe, - &got_packet); + &got_packet); #endif if (ret < 0) { warn("avcodec_encode_audio2 failed: %s", av_err2str(ret)); @@ -316,8 +334,8 @@ static bool do_encode(struct enc_encoder *enc, da_resize(enc->packet_buffer, 0); da_push_back_array(enc->packet_buffer, avpacket.data, avpacket.size); - packet->pts = rescale_ts(avpacket.pts, enc->context, time_base); - packet->dts = rescale_ts(avpacket.dts, enc->context, time_base); + packet->pts = rescale_ts(avpacket.pts, enc->context, time_base); + packet->dts = rescale_ts(avpacket.dts, enc->context, time_base); packet->data = enc->packet_buffer.array; packet->size = avpacket.size; packet->type = OBS_ENCODER_AUDIO; @@ -328,7 +346,7 @@ static bool do_encode(struct enc_encoder *enc, } static bool enc_encode(void *data, struct encoder_frame *frame, - struct encoder_packet *packet, bool *received_packet) + struct encoder_packet *packet, bool *received_packet) { struct enc_encoder *enc = data; @@ -348,8 +366,8 @@ static obs_properties_t *enc_properties(void *unused) UNUSED_PARAMETER(unused); obs_properties_t *props = obs_properties_create(); - obs_properties_add_int(props, "bitrate", - obs_module_text("Bitrate"), 64, 1024, 32); + obs_properties_add_int(props, "bitrate", obs_module_text("Bitrate"), 64, + 1024, 32); return props; } @@ -358,7 +376,7 @@ static bool enc_extra_data(void *data, uint8_t **extra_data, size_t *size) struct enc_encoder *enc = data; *extra_data = enc->context->extradata; - *size = enc->context->extradata_size; + *size = enc->context->extradata_size; return true; } @@ -367,41 +385,42 @@ static void enc_audio_info(void *data, struct audio_convert_info *info) struct enc_encoder *enc = data; info->format = convert_ffmpeg_sample_format(enc->context->sample_fmt); info->samples_per_sec = (uint32_t)enc->context->sample_rate; - info->speakers = convert_ff_channel_layout(enc->context->channel_layout); + info->speakers = + convert_ff_channel_layout(enc->context->channel_layout); } static size_t enc_frame_size(void *data) { - struct enc_encoder *enc =data; + struct enc_encoder *enc = data; return enc->frame_size; } struct obs_encoder_info aac_encoder_info = { - .id = "ffmpeg_aac", - .type = OBS_ENCODER_AUDIO, - .codec = "AAC", - .get_name = aac_getname, - .create = aac_create, - .destroy = enc_destroy, - .encode = enc_encode, + .id = "ffmpeg_aac", + .type = OBS_ENCODER_AUDIO, + .codec = "AAC", + .get_name = aac_getname, + .create = aac_create, + .destroy = enc_destroy, + .encode = enc_encode, .get_frame_size = enc_frame_size, - .get_defaults = enc_defaults, + .get_defaults = enc_defaults, .get_properties = enc_properties, .get_extra_data = enc_extra_data, - .get_audio_info = enc_audio_info + .get_audio_info = enc_audio_info, }; struct obs_encoder_info opus_encoder_info = { - .id = "ffmpeg_opus", - .type = OBS_ENCODER_AUDIO, - .codec = "opus", - .get_name = opus_getname, - .create = opus_create, - .destroy = enc_destroy, - .encode = enc_encode, + .id = "ffmpeg_opus", + .type = OBS_ENCODER_AUDIO, + .codec = "opus", + .get_name = opus_getname, + .create = opus_create, + .destroy = enc_destroy, + .encode = enc_encode, .get_frame_size = enc_frame_size, - .get_defaults = enc_defaults, + .get_defaults = enc_defaults, .get_properties = enc_properties, .get_extra_data = enc_extra_data, - .get_audio_info = enc_audio_info + .get_audio_info = enc_audio_info, }; diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-compat.h b/plugins/obs-ffmpeg/obs-ffmpeg-compat.h index 1072d70..181167a 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-compat.h +++ b/plugins/obs-ffmpeg/obs-ffmpeg-compat.h @@ -6,18 +6,20 @@ * a is the major version * b and c the minor and micro versions of libav * d and e the minor and micro versions of FFmpeg */ -#define LIBAVCODEC_VERSION_CHECK( a, b, c, d, e ) \ - ( (LIBAVCODEC_VERSION_MICRO < 100 && LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( a, b, c ) ) || \ - (LIBAVCODEC_VERSION_MICRO >= 100 && LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( a, d, e ) ) ) +#define LIBAVCODEC_VERSION_CHECK(a, b, c, d, e) \ + ((LIBAVCODEC_VERSION_MICRO < 100 && \ + LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(a, b, c)) || \ + (LIBAVCODEC_VERSION_MICRO >= 100 && \ + LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(a, d, e))) #if !LIBAVCODEC_VERSION_CHECK(54, 28, 0, 59, 100) -# define avcodec_free_frame av_freep +#define avcodec_free_frame av_freep #endif #if LIBAVCODEC_VERSION_INT < 0x371c01 -# define av_frame_alloc avcodec_alloc_frame -# define av_frame_unref avcodec_get_frame_defaults -# define av_frame_free avcodec_free_frame +#define av_frame_alloc avcodec_alloc_frame +#define av_frame_unref avcodec_get_frame_defaults +#define av_frame_free avcodec_free_frame #endif #if LIBAVCODEC_VERSION_MAJOR >= 57 diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-config.h.in b/plugins/obs-ffmpeg/obs-ffmpeg-config.h.in new file mode 100644 index 0000000..8f528b1 --- /dev/null +++ b/plugins/obs-ffmpeg/obs-ffmpeg-config.h.in @@ -0,0 +1,17 @@ +#ifndef ON +#define ON 1 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef OFF +#define OFF 0 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define ENABLE_FFMPEG_LOGGING @ENABLE_FFMPEG_LOGGING@ diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-formats.h b/plugins/obs-ffmpeg/obs-ffmpeg-formats.h index 260f751..62e3866 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-formats.h +++ b/plugins/obs-ffmpeg/obs-ffmpeg-formats.h @@ -1,61 +1,110 @@ #pragma once static inline int64_t rescale_ts(int64_t val, AVCodecContext *context, - AVRational new_base) + AVRational new_base) { return av_rescale_q_rnd(val, context->time_base, new_base, - AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); + AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); } -static inline enum AVPixelFormat obs_to_ffmpeg_video_format( - enum video_format format) +static inline enum AVPixelFormat +obs_to_ffmpeg_video_format(enum video_format format) { switch (format) { - case VIDEO_FORMAT_NONE: return AV_PIX_FMT_NONE; - case VIDEO_FORMAT_I444: return AV_PIX_FMT_YUV444P; - case VIDEO_FORMAT_I420: return AV_PIX_FMT_YUV420P; - case VIDEO_FORMAT_NV12: return AV_PIX_FMT_NV12; - case VIDEO_FORMAT_YVYU: return AV_PIX_FMT_NONE; - case VIDEO_FORMAT_YUY2: return AV_PIX_FMT_YUYV422; - case VIDEO_FORMAT_UYVY: return AV_PIX_FMT_UYVY422; - case VIDEO_FORMAT_RGBA: return AV_PIX_FMT_RGBA; - case VIDEO_FORMAT_BGRA: return AV_PIX_FMT_BGRA; - case VIDEO_FORMAT_BGRX: return AV_PIX_FMT_BGRA; - case VIDEO_FORMAT_Y800: return AV_PIX_FMT_GRAY8; + case VIDEO_FORMAT_I444: + return AV_PIX_FMT_YUV444P; + case VIDEO_FORMAT_I420: + return AV_PIX_FMT_YUV420P; + case VIDEO_FORMAT_NV12: + return AV_PIX_FMT_NV12; + case VIDEO_FORMAT_YUY2: + return AV_PIX_FMT_YUYV422; + case VIDEO_FORMAT_UYVY: + return AV_PIX_FMT_UYVY422; + case VIDEO_FORMAT_RGBA: + return AV_PIX_FMT_RGBA; + case VIDEO_FORMAT_BGRA: + return AV_PIX_FMT_BGRA; + case VIDEO_FORMAT_BGRX: + return AV_PIX_FMT_BGRA; + case VIDEO_FORMAT_Y800: + return AV_PIX_FMT_GRAY8; + case VIDEO_FORMAT_BGR3: + return AV_PIX_FMT_BGR24; + case VIDEO_FORMAT_I422: + return AV_PIX_FMT_YUV422P; + case VIDEO_FORMAT_I40A: + return AV_PIX_FMT_YUVA420P; + case VIDEO_FORMAT_I42A: + return AV_PIX_FMT_YUVA422P; + case VIDEO_FORMAT_YUVA: + return AV_PIX_FMT_YUVA444P; + case VIDEO_FORMAT_NONE: + case VIDEO_FORMAT_YVYU: + case VIDEO_FORMAT_AYUV: + /* not supported by FFmpeg */ + return AV_PIX_FMT_NONE; } return AV_PIX_FMT_NONE; } -static inline enum video_format ffmpeg_to_obs_video_format( - enum AVPixelFormat format) +static inline enum video_format +ffmpeg_to_obs_video_format(enum AVPixelFormat format) { switch (format) { - case AV_PIX_FMT_YUV444P: return VIDEO_FORMAT_I444; - case AV_PIX_FMT_YUV420P: return VIDEO_FORMAT_I420; - case AV_PIX_FMT_NV12: return VIDEO_FORMAT_NV12; - case AV_PIX_FMT_YUYV422: return VIDEO_FORMAT_YUY2; - case AV_PIX_FMT_UYVY422: return VIDEO_FORMAT_UYVY; - case AV_PIX_FMT_RGBA: return VIDEO_FORMAT_RGBA; - case AV_PIX_FMT_BGRA: return VIDEO_FORMAT_BGRA; - case AV_PIX_FMT_GRAY8: return VIDEO_FORMAT_Y800; + case AV_PIX_FMT_YUV444P: + return VIDEO_FORMAT_I444; + case AV_PIX_FMT_YUV420P: + return VIDEO_FORMAT_I420; + case AV_PIX_FMT_NV12: + return VIDEO_FORMAT_NV12; + case AV_PIX_FMT_YUYV422: + return VIDEO_FORMAT_YUY2; + case AV_PIX_FMT_UYVY422: + return VIDEO_FORMAT_UYVY; + case AV_PIX_FMT_RGBA: + return VIDEO_FORMAT_RGBA; + case AV_PIX_FMT_BGRA: + return VIDEO_FORMAT_BGRA; + case AV_PIX_FMT_GRAY8: + return VIDEO_FORMAT_Y800; + case AV_PIX_FMT_BGR24: + return VIDEO_FORMAT_BGR3; + case AV_PIX_FMT_YUV422P: + return VIDEO_FORMAT_I422; + case AV_PIX_FMT_YUVA420P: + return VIDEO_FORMAT_I40A; + case AV_PIX_FMT_YUVA422P: + return VIDEO_FORMAT_I42A; + case AV_PIX_FMT_YUVA444P: + return VIDEO_FORMAT_YUVA; case AV_PIX_FMT_NONE: - default: return VIDEO_FORMAT_NONE; + default: + return VIDEO_FORMAT_NONE; } } -static inline enum audio_format convert_ffmpeg_sample_format( - enum AVSampleFormat format) +static inline enum audio_format +convert_ffmpeg_sample_format(enum AVSampleFormat format) { switch ((uint32_t)format) { - case AV_SAMPLE_FMT_U8: return AUDIO_FORMAT_U8BIT; - case AV_SAMPLE_FMT_S16: return AUDIO_FORMAT_16BIT; - case AV_SAMPLE_FMT_S32: return AUDIO_FORMAT_32BIT; - case AV_SAMPLE_FMT_FLT: return AUDIO_FORMAT_FLOAT; - case AV_SAMPLE_FMT_U8P: return AUDIO_FORMAT_U8BIT_PLANAR; - case AV_SAMPLE_FMT_S16P: return AUDIO_FORMAT_16BIT_PLANAR; - case AV_SAMPLE_FMT_S32P: return AUDIO_FORMAT_32BIT_PLANAR; - case AV_SAMPLE_FMT_FLTP: return AUDIO_FORMAT_FLOAT_PLANAR; + case AV_SAMPLE_FMT_U8: + return AUDIO_FORMAT_U8BIT; + case AV_SAMPLE_FMT_S16: + return AUDIO_FORMAT_16BIT; + case AV_SAMPLE_FMT_S32: + return AUDIO_FORMAT_32BIT; + case AV_SAMPLE_FMT_FLT: + return AUDIO_FORMAT_FLOAT; + case AV_SAMPLE_FMT_U8P: + return AUDIO_FORMAT_U8BIT_PLANAR; + case AV_SAMPLE_FMT_S16P: + return AUDIO_FORMAT_16BIT_PLANAR; + case AV_SAMPLE_FMT_S32P: + return AUDIO_FORMAT_32BIT_PLANAR; + case AV_SAMPLE_FMT_FLTP: + return AUDIO_FORMAT_FLOAT_PLANAR; } /* shouldn't get here */ diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-logging.c b/plugins/obs-ffmpeg/obs-ffmpeg-logging.c new file mode 100644 index 0000000..4a45a12 --- /dev/null +++ b/plugins/obs-ffmpeg/obs-ffmpeg-logging.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include + +static DARRAY(struct log_context { + void *context; + char str[4096]; + int print_prefix; +} *) active_log_contexts; +static DARRAY(struct log_context *) cached_log_contexts; +pthread_mutex_t log_contexts_mutex = PTHREAD_MUTEX_INITIALIZER; + +static struct log_context *create_or_fetch_log_context(void *context) +{ + pthread_mutex_lock(&log_contexts_mutex); + for (size_t i = 0; i < active_log_contexts.num; i++) { + if (context == active_log_contexts.array[i]->context) { + pthread_mutex_unlock(&log_contexts_mutex); + return active_log_contexts.array[i]; + } + } + + struct log_context *new_log_context = NULL; + + size_t cnt = cached_log_contexts.num; + if (!!cnt) { + new_log_context = cached_log_contexts.array[cnt - 1]; + da_pop_back(cached_log_contexts); + } + + if (!new_log_context) + new_log_context = bzalloc(sizeof(struct log_context)); + + new_log_context->context = context; + new_log_context->str[0] = '\0'; + new_log_context->print_prefix = 1; + + da_push_back(active_log_contexts, &new_log_context); + + pthread_mutex_unlock(&log_contexts_mutex); + + return new_log_context; +} + +static void destroy_log_context(struct log_context *log_context) +{ + pthread_mutex_lock(&log_contexts_mutex); + da_erase_item(active_log_contexts, &log_context); + da_push_back(cached_log_contexts, &log_context); + pthread_mutex_unlock(&log_contexts_mutex); +} + +static void ffmpeg_log_callback(void *context, int level, const char *format, + va_list args) +{ + if (format == NULL) + return; + + struct log_context *log_context = create_or_fetch_log_context(context); + + char *str = log_context->str; + + av_log_format_line(context, level, format, args, str + strlen(str), + (int)(sizeof(log_context->str) - strlen(str)), + &log_context->print_prefix); + + int obs_level; + switch (level) { + case AV_LOG_PANIC: + case AV_LOG_FATAL: + obs_level = LOG_ERROR; + break; + case AV_LOG_ERROR: + case AV_LOG_WARNING: + obs_level = LOG_WARNING; + break; + case AV_LOG_INFO: + case AV_LOG_VERBOSE: + obs_level = LOG_INFO; + break; + case AV_LOG_DEBUG: + default: + obs_level = LOG_DEBUG; + } + + if (!log_context->print_prefix) + return; + + char *str_end = str + strlen(str) - 1; + while (str < str_end) { + if (*str_end != '\n') + break; + *str_end-- = '\0'; + } + + if (str_end <= str) + goto cleanup; + + blog(obs_level, "[ffmpeg] %s", str); + +cleanup: + destroy_log_context(log_context); +} + +static bool logging_initialized = false; + +void obs_ffmpeg_load_logging(void) +{ + da_init(active_log_contexts); + da_init(cached_log_contexts); + + if (pthread_mutex_init(&log_contexts_mutex, NULL) == 0) { + av_log_set_callback(ffmpeg_log_callback); + logging_initialized = true; + } +} + +void obs_ffmpeg_unload_logging(void) +{ + if (!logging_initialized) + return; + + logging_initialized = false; + + av_log_set_callback(av_log_default_callback); + pthread_mutex_destroy(&log_contexts_mutex); + + for (size_t i = 0; i < active_log_contexts.num; i++) { + bfree(active_log_contexts.array[i]); + } + for (size_t i = 0; i < cached_log_contexts.num; i++) { + bfree(cached_log_contexts.array[i]); + } + + da_free(active_log_contexts); + da_free(cached_log_contexts); +} diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c index 2683f8e..f2d3f9b 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c @@ -32,38 +32,38 @@ #include -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[ffmpeg muxer: '%s'] " format, \ - obs_output_get_name(stream->output), ##__VA_ARGS__) + obs_output_get_name(stream->output), ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) struct ffmpeg_muxer { - obs_output_t *output; + obs_output_t *output; os_process_pipe_t *pipe; - int64_t stop_ts; - uint64_t total_bytes; - struct dstr path; - bool sent_headers; - volatile bool active; - volatile bool stopping; - volatile bool capturing; + int64_t stop_ts; + uint64_t total_bytes; + struct dstr path; + bool sent_headers; + volatile bool active; + volatile bool stopping; + volatile bool capturing; /* replay buffer */ - struct circlebuf packets; - int64_t cur_size; - int64_t cur_time; - int64_t max_size; - int64_t max_time; - int64_t save_ts; - int keyframes; - obs_hotkey_id hotkey; + struct circlebuf packets; + int64_t cur_size; + int64_t cur_time; + int64_t max_size; + int64_t max_time; + int64_t save_ts; + int keyframes; + obs_hotkey_id hotkey; DARRAY(struct encoder_packet) mux_packets; - pthread_t mux_thread; - bool mux_thread_joinable; - volatile bool muxing; + pthread_t mux_thread; + bool mux_thread_joinable; + volatile bool muxing; }; static const char *ffmpeg_mux_getname(void *type) @@ -136,7 +136,7 @@ static inline bool active(struct ffmpeg_muxer *stream) /* TODO: allow codecs other than h264 whenever we start using them */ static void add_video_encoder_params(struct ffmpeg_muxer *stream, - struct dstr *cmd, obs_encoder_t *vencoder) + struct dstr *cmd, obs_encoder_t *vencoder) { obs_data_t *settings = obs_encoder_get_settings(vencoder); int bitrate = (int)obs_data_get_int(settings, "bitrate"); @@ -145,13 +145,10 @@ static void add_video_encoder_params(struct ffmpeg_muxer *stream, obs_data_release(settings); - dstr_catf(cmd, "%s %d %d %d %d %d ", - obs_encoder_get_codec(vencoder), - bitrate, - obs_output_get_width(stream->output), - obs_output_get_height(stream->output), - (int)info->fps_num, - (int)info->fps_den); + dstr_catf(cmd, "%s %d %d %d %d %d ", obs_encoder_get_codec(vencoder), + bitrate, obs_output_get_width(stream->output), + obs_output_get_height(stream->output), (int)info->fps_num, + (int)info->fps_den); } static void add_audio_encoder_params(struct dstr *cmd, obs_encoder_t *aencoder) @@ -166,11 +163,9 @@ static void add_audio_encoder_params(struct dstr *cmd, obs_encoder_t *aencoder) dstr_copy(&name, obs_encoder_get_name(aencoder)); dstr_replace(&name, "\"", "\"\""); - dstr_catf(cmd, "\"%s\" %d %d %d ", - name.array, - bitrate, - (int)obs_encoder_get_sample_rate(aencoder), - (int)audio_output_get_channels(audio)); + dstr_catf(cmd, "\"%s\" %d %d %d ", name.array, bitrate, + (int)obs_encoder_get_sample_rate(aencoder), + (int)audio_output_get_channels(audio)); dstr_free(&name); } @@ -181,8 +176,8 @@ static void log_muxer_params(struct ffmpeg_muxer *stream, const char *settings) AVDictionary *dict = NULL; if ((ret = av_dict_parse_string(&dict, settings, "=", " ", 0))) { - warn("Failed to parse muxer settings: %s\n%s", - av_err2str(ret), settings); + warn("Failed to parse muxer settings: %s\n%s", av_err2str(ret), + settings); av_dict_free(&dict); return; @@ -193,7 +188,7 @@ static void log_muxer_params(struct ffmpeg_muxer *stream, const char *settings) AVDictionaryEntry *entry = NULL; while ((entry = av_dict_get(dict, "", entry, - AV_DICT_IGNORE_SUFFIX))) + AV_DICT_IGNORE_SUFFIX))) dstr_catf(&str, "\n\t%s=%s", entry->key, entry->value); info("Using muxer settings:%s", str.array); @@ -221,7 +216,7 @@ static void add_muxer_params(struct dstr *cmd, struct ffmpeg_muxer *stream) } static void build_command_line(struct ffmpeg_muxer *stream, struct dstr *cmd, - const char *path) + const char *path) { obs_encoder_t *vencoder = obs_output_get_video_encoder(stream->output); obs_encoder_t *aencoders[MAX_AUDIO_MIXES]; @@ -229,7 +224,7 @@ static void build_command_line(struct ffmpeg_muxer *stream, struct dstr *cmd, for (;;) { obs_encoder_t *aencoder = obs_output_get_audio_encoder( - stream->output, num_tracks); + stream->output, num_tracks); if (!aencoder) break; @@ -289,7 +284,7 @@ static bool ffmpeg_mux_start(void *data) if (!test_file) { struct dstr error_message; dstr_init_copy(&error_message, - obs_module_text("UnableToWritePath")); + obs_module_text("UnableToWritePath")); #ifdef _WIN32 // special warning for Windows 10 users about Defender struct win_version_info ver; @@ -297,12 +292,11 @@ static bool ffmpeg_mux_start(void *data) if (ver.major >= 10) { dstr_cat(&error_message, "\n\n"); dstr_cat(&error_message, - obs_module_text("WarnWindowsDefender")); + obs_module_text("WarnWindowsDefender")); } #endif dstr_replace(&error_message, "%1", path); - obs_output_set_last_error(stream->output, - error_message.array); + obs_output_set_last_error(stream->output, error_message.array); dstr_free(&error_message); obs_data_release(settings); return false; @@ -315,8 +309,8 @@ static bool ffmpeg_mux_start(void *data) obs_data_release(settings); if (!stream->pipe) { - obs_output_set_last_error(stream->output, - obs_module_text("HelperProcessFailed")); + obs_output_set_last_error( + stream->output, obs_module_text("HelperProcessFailed")); warn("Failed to create process pipe"); return false; } @@ -375,19 +369,22 @@ static void signal_failure(struct ffmpeg_muxer *stream) size_t len; len = os_process_pipe_read_err(stream->pipe, (uint8_t *)error, - sizeof(error) - 1); + sizeof(error) - 1); if (len > 0) { error[len] = 0; - warn ("ffmpeg-mux: %s", error); - obs_output_set_last_error (stream->output, error); + warn("ffmpeg-mux: %s", error); + obs_output_set_last_error(stream->output, error); } ret = deactivate(stream, 0); switch (ret) { - case FFM_UNSUPPORTED: code = OBS_OUTPUT_UNSUPPORTED; break; - default: code = OBS_OUTPUT_ERROR; + case FFM_UNSUPPORTED: + code = OBS_OUTPUT_UNSUPPORTED; + break; + default: + code = OBS_OUTPUT_ERROR; } obs_output_signal_stop(stream->output, code); @@ -395,22 +392,21 @@ static void signal_failure(struct ffmpeg_muxer *stream) } static bool write_packet(struct ffmpeg_muxer *stream, - struct encoder_packet *packet) + struct encoder_packet *packet) { bool is_video = packet->type == OBS_ENCODER_VIDEO; size_t ret; - struct ffm_packet_info info = { - .pts = packet->pts, - .dts = packet->dts, - .size = (uint32_t)packet->size, - .index = (int)packet->track_idx, - .type = is_video ? FFM_PACKET_VIDEO : FFM_PACKET_AUDIO, - .keyframe = packet->keyframe - }; + struct ffm_packet_info info = {.pts = packet->pts, + .dts = packet->dts, + .size = (uint32_t)packet->size, + .index = (int)packet->track_idx, + .type = is_video ? FFM_PACKET_VIDEO + : FFM_PACKET_AUDIO, + .keyframe = packet->keyframe}; - ret = os_process_pipe_write(stream->pipe, (const uint8_t*)&info, - sizeof(info)); + ret = os_process_pipe_write(stream->pipe, (const uint8_t *)&info, + sizeof(info)); if (ret != sizeof(info)) { warn("os_process_pipe_write for info structure failed"); signal_failure(stream); @@ -429,13 +425,10 @@ static bool write_packet(struct ffmpeg_muxer *stream, } static bool send_audio_headers(struct ffmpeg_muxer *stream, - obs_encoder_t *aencoder, size_t idx) + obs_encoder_t *aencoder, size_t idx) { struct encoder_packet packet = { - .type = OBS_ENCODER_AUDIO, - .timebase_den = 1, - .track_idx = idx - }; + .type = OBS_ENCODER_AUDIO, .timebase_den = 1, .track_idx = idx}; obs_encoder_get_extra_data(aencoder, &packet.data, &packet.size); return write_packet(stream, &packet); @@ -445,10 +438,8 @@ static bool send_video_headers(struct ffmpeg_muxer *stream) { obs_encoder_t *vencoder = obs_output_get_video_encoder(stream->output); - struct encoder_packet packet = { - .type = OBS_ENCODER_VIDEO, - .timebase_den = 1 - }; + struct encoder_packet packet = {.type = OBS_ENCODER_VIDEO, + .timebase_den = 1}; obs_encoder_get_extra_data(vencoder, &packet.data, &packet.size); return write_packet(stream, &packet); @@ -511,9 +502,8 @@ static obs_properties_t *ffmpeg_mux_properties(void *unused) obs_properties_t *props = obs_properties_create(); - obs_properties_add_text(props, "path", - obs_module_text("FilePath"), - OBS_TEXT_DEFAULT); + obs_properties_add_text(props, "path", obs_module_text("FilePath"), + OBS_TEXT_DEFAULT); return props; } @@ -524,18 +514,17 @@ static uint64_t ffmpeg_mux_total_bytes(void *data) } struct obs_output_info ffmpeg_muxer = { - .id = "ffmpeg_muxer", - .flags = OBS_OUTPUT_AV | - OBS_OUTPUT_ENCODED | - OBS_OUTPUT_MULTI_TRACK, - .get_name = ffmpeg_mux_getname, - .create = ffmpeg_mux_create, - .destroy = ffmpeg_mux_destroy, - .start = ffmpeg_mux_start, - .stop = ffmpeg_mux_stop, + .id = "ffmpeg_muxer", + .flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_MULTI_TRACK | + OBS_OUTPUT_CAN_PAUSE, + .get_name = ffmpeg_mux_getname, + .create = ffmpeg_mux_create, + .destroy = ffmpeg_mux_destroy, + .start = ffmpeg_mux_start, + .stop = ffmpeg_mux_stop, .encoded_packet = ffmpeg_mux_data, - .get_total_bytes= ffmpeg_mux_total_bytes, - .get_properties = ffmpeg_mux_properties + .get_total_bytes = ffmpeg_mux_total_bytes, + .get_properties = ffmpeg_mux_properties, }; /* ------------------------------------------------------------------------ */ @@ -547,15 +536,27 @@ static const char *replay_buffer_getname(void *type) } static void replay_buffer_hotkey(void *data, obs_hotkey_id id, - obs_hotkey_t *hotkey, bool pressed) + obs_hotkey_t *hotkey, bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(hotkey); UNUSED_PARAMETER(pressed); + if (!pressed) + return; + struct ffmpeg_muxer *stream = data; - if (os_atomic_load_bool(&stream->active)) + + if (os_atomic_load_bool(&stream->active)) { + obs_encoder_t *vencoder = + obs_output_get_video_encoder(stream->output); + if (obs_encoder_paused(vencoder)) { + info("Could not save buffer because encoders paused"); + return; + } + stream->save_ts = os_gettime_ns() / 1000LL; + } } static void save_replay_proc(void *data, calldata_t *cd) @@ -577,15 +578,15 @@ static void *replay_buffer_create(obs_data_t *settings, obs_output_t *output) struct ffmpeg_muxer *stream = bzalloc(sizeof(*stream)); stream->output = output; - stream->hotkey = obs_hotkey_register_output(output, - "ReplayBuffer.Save", - obs_module_text("ReplayBuffer.Save"), - replay_buffer_hotkey, stream); + stream->hotkey = + obs_hotkey_register_output(output, "ReplayBuffer.Save", + obs_module_text("ReplayBuffer.Save"), + replay_buffer_hotkey, stream); proc_handler_t *ph = obs_output_get_proc_handler(output); proc_handler_add(ph, "void save()", save_replay_proc, stream); proc_handler_add(ph, "void get_last_replay(out string path)", - get_last_replay, stream); + get_last_replay, stream); return stream; } @@ -653,7 +654,7 @@ static inline void purge(struct ffmpeg_muxer *stream) for (;;) { circlebuf_peek_front(&stream->packets, &pkt, - sizeof(pkt)); + sizeof(pkt)); if (pkt.type == OBS_ENCODER_VIDEO && pkt.keyframe) return; @@ -663,14 +664,14 @@ static inline void purge(struct ffmpeg_muxer *stream) } static inline void replay_buffer_purge(struct ffmpeg_muxer *stream, - struct encoder_packet *pkt) + struct encoder_packet *pkt) { if (stream->max_size) { if (!stream->packets.size || stream->keyframes <= 2) return; while ((stream->cur_size + (int64_t)pkt->size) > - stream->max_size) + stream->max_size) purge(stream); } @@ -682,8 +683,8 @@ static inline void replay_buffer_purge(struct ffmpeg_muxer *stream, } static void insert_packet(struct darray *array, struct encoder_packet *packet, - int64_t video_offset, int64_t *audio_offsets, - int64_t video_dts_offset, int64_t *audio_dts_offsets) + int64_t video_offset, int64_t *audio_offsets, + int64_t video_dts_offset, int64_t *audio_dts_offsets) { struct encoder_packet pkt; DARRAY(struct encoder_packet) packets; @@ -725,7 +726,7 @@ static void *replay_buffer_mux_thread(void *data) if (!send_headers(stream)) { warn("Could not write headers for file '%s'", - stream->path.array); + stream->path.array); goto error; } @@ -780,9 +781,9 @@ static void replay_buffer_save(struct ffmpeg_muxer *stream) } } - insert_packet(&stream->mux_packets.da, pkt, - video_offset, audio_offsets, - video_dts_offset, audio_dts_offsets); + insert_packet(&stream->mux_packets.da, pkt, video_offset, + audio_offsets, video_dts_offset, + audio_dts_offsets); } /* ---------------------------- */ @@ -809,7 +810,8 @@ static void replay_buffer_save(struct ffmpeg_muxer *stream) os_atomic_set_bool(&stream->muxing, true); stream->mux_thread_joinable = pthread_create(&stream->mux_thread, NULL, - replay_buffer_mux_thread, stream) == 0; + replay_buffer_mux_thread, + stream) == 0; } static void deactivate_replay_buffer(struct ffmpeg_muxer *stream, int code) @@ -883,16 +885,15 @@ static void replay_buffer_defaults(obs_data_t *s) } struct obs_output_info replay_buffer = { - .id = "replay_buffer", - .flags = OBS_OUTPUT_AV | - OBS_OUTPUT_ENCODED | - OBS_OUTPUT_MULTI_TRACK, - .get_name = replay_buffer_getname, - .create = replay_buffer_create, - .destroy = replay_buffer_destroy, - .start = replay_buffer_start, - .stop = ffmpeg_mux_stop, + .id = "replay_buffer", + .flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_MULTI_TRACK | + OBS_OUTPUT_CAN_PAUSE, + .get_name = replay_buffer_getname, + .create = replay_buffer_create, + .destroy = replay_buffer_destroy, + .start = replay_buffer_start, + .stop = ffmpeg_mux_stop, .encoded_packet = replay_buffer_data, - .get_total_bytes= ffmpeg_mux_total_bytes, - .get_defaults = replay_buffer_defaults + .get_total_bytes = ffmpeg_mux_total_bytes, + .get_defaults = replay_buffer_defaults, }; diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c index 469dce4..3fb3c64 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c @@ -28,33 +28,33 @@ #include "obs-ffmpeg-formats.h" -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[NVENC encoder: '%s'] " format, \ - obs_encoder_get_name(enc->encoder), ##__VA_ARGS__) + obs_encoder_get_name(enc->encoder), ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) -#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) struct nvenc_encoder { - obs_encoder_t *encoder; + obs_encoder_t *encoder; - AVCodec *nvenc; - AVCodecContext *context; + AVCodec *nvenc; + AVCodecContext *context; - AVFrame *vframe; + AVFrame *vframe; - DARRAY(uint8_t) buffer; + DARRAY(uint8_t) buffer; - uint8_t *header; - size_t header_size; + uint8_t *header; + size_t header_size; - uint8_t *sei; - size_t sei_size; + uint8_t *sei; + size_t sei_size; - int height; - bool first_packet; - bool initialized; + int height; + bool first_packet; + bool initialized; }; static const char *nvenc_getname(void *unused) @@ -65,8 +65,7 @@ static const char *nvenc_getname(void *unused) static inline bool valid_format(enum video_format format) { - return format == VIDEO_FORMAT_I420 || - format == VIDEO_FORMAT_NV12 || + return format == VIDEO_FORMAT_I420 || format == VIDEO_FORMAT_NV12 || format == VIDEO_FORMAT_I444; } @@ -78,8 +77,8 @@ static void nvenc_video_info(void *data, struct video_scale_info *info) pref_format = obs_encoder_get_preferred_video_format(enc->encoder); if (!valid_format(pref_format)) { - pref_format = valid_format(info->format) ? - info->format : VIDEO_FORMAT_NV12; + pref_format = valid_format(info->format) ? info->format + : VIDEO_FORMAT_NV12; } info->format = pref_format; @@ -117,12 +116,7 @@ static bool nvenc_init_codec(struct nvenc_encoder *enc) return true; } -enum RC_MODE { - RC_MODE_CBR, - RC_MODE_VBR, - RC_MODE_CQP, - RC_MODE_LOSSLESS -}; +enum RC_MODE { RC_MODE_CBR, RC_MODE_VBR, RC_MODE_CQP, RC_MODE_LOSSLESS }; static bool nvenc_update(void *data, obs_data_t *settings) { @@ -177,10 +171,10 @@ static bool nvenc_update(void *data, obs_data_t *settings) cqp = 0; bool hp = (astrcmpi(preset, "hp") == 0 || - astrcmpi(preset, "llhp") == 0); + astrcmpi(preset, "llhp") == 0); av_opt_set(enc->context->priv_data, "preset", - hp ? "losslesshp" : "lossless", 0); + hp ? "losslesshp" : "lossless", 0); } else if (astrcmpi(rc, "vbr") != 0) { /* CBR by default */ av_opt_set_int(enc->context->priv_data, "cbr", true, 0); @@ -189,7 +183,6 @@ static bool nvenc_update(void *data, obs_data_t *settings) cqp = 0; } - av_opt_set(enc->context->priv_data, "level", "auto", 0); av_opt_set_int(enc->context->priv_data, "2pass", twopass, 0); av_opt_set_int(enc->context->priv_data, "gpu", gpu, 0); @@ -200,15 +193,17 @@ static bool nvenc_update(void *data, obs_data_t *settings) enc->context->height = obs_encoder_get_height(enc->encoder); enc->context->time_base = (AVRational){voi->fps_den, voi->fps_num}; enc->context->pix_fmt = obs_to_ffmpeg_video_format(info.format); - enc->context->colorspace = info.colorspace == VIDEO_CS_709 ? - AVCOL_SPC_BT709 : AVCOL_SPC_BT470BG; - enc->context->color_range = info.range == VIDEO_RANGE_FULL ? - AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; + enc->context->colorspace = info.colorspace == VIDEO_CS_709 + ? AVCOL_SPC_BT709 + : AVCOL_SPC_BT470BG; + enc->context->color_range = info.range == VIDEO_RANGE_FULL + ? AVCOL_RANGE_JPEG + : AVCOL_RANGE_MPEG; enc->context->max_b_frames = bf; if (keyint_sec) - enc->context->gop_size = keyint_sec * voi->fps_num / - voi->fps_den; + enc->context->gop_size = + keyint_sec * voi->fps_num / voi->fps_den; else enc->context->gop_size = 250; @@ -226,16 +221,30 @@ static bool nvenc_update(void *data, obs_data_t *settings) "\t2-pass: %s\n" "\tb-frames: %d\n" "\tGPU: %d\n", - rc, bitrate, cqp, enc->context->gop_size, - preset, profile, + rc, bitrate, cqp, enc->context->gop_size, preset, profile, enc->context->width, enc->context->height, - twopass ? "true" : "false", - enc->context->max_b_frames, - gpu); + twopass ? "true" : "false", enc->context->max_b_frames, gpu); return nvenc_init_codec(enc); } +static bool nvenc_reconfigure(void *data, obs_data_t *settings) +{ +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 19, 101) + struct nvenc_encoder *enc = data; + + int bitrate = (int)obs_data_get_int(settings, "bitrate"); + const char *rc = obs_data_get_string(settings, "rate_control"); + bool cbr = astrcmpi(rc, "CBR") == 0; + bool vbr = astrcmpi(rc, "VBR") == 0; + if (cbr || vbr) { + enc->context->bit_rate = bitrate * 1000; + enc->context->rc_max_rate = bitrate * 1000; + } +#endif + return true; +} + static void nvenc_destroy(void *data) { struct nvenc_encoder *enc = data; @@ -250,7 +259,7 @@ static void nvenc_destroy(void *data) break; #else if (avcodec_encode_video2(enc->context, &pkt, NULL, - &r_pkt) < 0) + &r_pkt) < 0) break; #endif @@ -273,7 +282,9 @@ static void *nvenc_create(obs_data_t *settings, obs_encoder_t *encoder) { struct nvenc_encoder *enc; +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) avcodec_register_all(); +#endif enc = bzalloc(sizeof(*enc)); enc->encoder = encoder; @@ -306,33 +317,33 @@ fail: } static inline void copy_data(AVFrame *pic, const struct encoder_frame *frame, - int height, enum AVPixelFormat format) + int height, enum AVPixelFormat format) { int h_chroma_shift, v_chroma_shift; - av_pix_fmt_get_chroma_sub_sample(format, &h_chroma_shift, &v_chroma_shift); + av_pix_fmt_get_chroma_sub_sample(format, &h_chroma_shift, + &v_chroma_shift); for (int plane = 0; plane < MAX_AV_PLANES; plane++) { if (!frame->data[plane]) continue; int frame_rowsize = (int)frame->linesize[plane]; - int pic_rowsize = pic->linesize[plane]; - int bytes = frame_rowsize < pic_rowsize ? - frame_rowsize : pic_rowsize; + int pic_rowsize = pic->linesize[plane]; + int bytes = frame_rowsize < pic_rowsize ? frame_rowsize + : pic_rowsize; int plane_height = height >> (plane ? v_chroma_shift : 0); for (int y = 0; y < plane_height; y++) { int pos_frame = y * frame_rowsize; - int pos_pic = y * pic_rowsize; + int pos_pic = y * pic_rowsize; memcpy(pic->data[plane] + pos_pic, - frame->data[plane] + pos_frame, - bytes); + frame->data[plane] + pos_frame, bytes); } } } static bool nvenc_encode(void *data, struct encoder_frame *frame, - struct encoder_packet *packet, bool *received_packet) + struct encoder_packet *packet, bool *received_packet) { struct nvenc_encoder *enc = data; AVPacket av_pkt = {0}; @@ -355,7 +366,7 @@ static bool nvenc_encode(void *data, struct encoder_frame *frame, ret = 0; #else ret = avcodec_encode_video2(enc->context, &av_pkt, enc->vframe, - &got_packet); + &got_packet); #endif if (ret < 0) { warn("nvenc_encode: Error encoding: %s", av_err2str(ret)); @@ -369,9 +380,9 @@ static bool nvenc_encode(void *data, struct encoder_frame *frame, enc->first_packet = false; obs_extract_avc_headers(av_pkt.data, av_pkt.size, - &new_packet, &size, - &enc->header, &enc->header_size, - &enc->sei, &enc->sei_size); + &new_packet, &size, + &enc->header, &enc->header_size, + &enc->sei, &enc->sei_size); da_copy_array(enc->buffer, new_packet, size); bfree(new_packet); @@ -409,7 +420,7 @@ void nvenc_defaults(obs_data_t *settings) } static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { const char *rc = obs_data_get_string(settings, "rate_control"); bool cqp = astrcmpi(rc, "CQP") == 0; @@ -441,35 +452,39 @@ obs_properties_t *nvenc_properties_internal(bool ffmpeg) obs_property_t *p; p = obs_properties_add_list(props, "rate_control", - obs_module_text("RateControl"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + obs_module_text("RateControl"), + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, "CBR", "CBR"); obs_property_list_add_string(p, "CQP", "CQP"); obs_property_list_add_string(p, "VBR", "VBR"); obs_property_list_add_string(p, obs_module_text("Lossless"), - "lossless"); + "lossless"); obs_property_set_modified_callback(p, rate_control_modified); - p = obs_properties_add_int(props, "bitrate", - obs_module_text("Bitrate"), 50, 300000, 50); + p = obs_properties_add_int(props, "bitrate", obs_module_text("Bitrate"), + 50, 300000, 50); obs_property_int_set_suffix(p, " Kbps"); p = obs_properties_add_int(props, "max_bitrate", - obs_module_text("MaxBitrate"), 50, 300000, 50); + obs_module_text("MaxBitrate"), 50, 300000, + 50); obs_property_int_set_suffix(p, " Kbps"); obs_properties_add_int(props, "cqp", obs_module_text("NVENC.CQLevel"), - 1, 30, 1); + 1, 30, 1); obs_properties_add_int(props, "keyint_sec", - obs_module_text("KeyframeIntervalSec"), 0, 10, 1); + obs_module_text("KeyframeIntervalSec"), 0, 10, + 1); p = obs_properties_add_list(props, "preset", obs_module_text("Preset"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); -#define add_preset(val) \ +#define add_preset(val) \ obs_property_list_add_string(p, obs_module_text("NVENC.Preset." val), \ - val) + val) add_preset("mq"); add_preset("hq"); add_preset("default"); @@ -479,11 +494,12 @@ obs_properties_t *nvenc_properties_internal(bool ffmpeg) add_preset("llhp"); #undef add_preset - p = obs_properties_add_list(props, "profile", obs_module_text("Profile"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + p = obs_properties_add_list(props, "profile", + obs_module_text("Profile"), + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); -#define add_profile(val) \ - obs_property_list_add_string(p, val, val) +#define add_profile(val) obs_property_list_add_string(p, val, val) add_profile("high"); add_profile("main"); add_profile("baseline"); @@ -491,20 +507,21 @@ obs_properties_t *nvenc_properties_internal(bool ffmpeg) if (!ffmpeg) { p = obs_properties_add_bool(props, "lookahead", - obs_module_text("NVENC.LookAhead")); - obs_property_set_long_description(p, - obs_module_text("NVENC.LookAhead.ToolTip")); + obs_module_text("NVENC.LookAhead")); + obs_property_set_long_description( + p, obs_module_text("NVENC.LookAhead.ToolTip")); - p = obs_properties_add_bool(props, "psycho_aq", - obs_module_text("NVENC.PsychoVisualTuning")); - obs_property_set_long_description(p, - obs_module_text("NVENC.PsychoVisualTuning.ToolTip")); + p = obs_properties_add_bool( + props, "psycho_aq", + obs_module_text("NVENC.PsychoVisualTuning")); + obs_property_set_long_description( + p, obs_module_text("NVENC.PsychoVisualTuning.ToolTip")); } obs_properties_add_int(props, "gpu", obs_module_text("GPU"), 0, 8, 1); - obs_properties_add_int(props, "bf", obs_module_text("BFrames"), - 0, 4, 1); + obs_properties_add_int(props, "bf", obs_module_text("BFrames"), 0, 4, + 1); return props; } @@ -526,7 +543,7 @@ static bool nvenc_extra_data(void *data, uint8_t **extra_data, size_t *size) struct nvenc_encoder *enc = data; *extra_data = enc->header; - *size = enc->header_size; + *size = enc->header_size; return true; } @@ -535,21 +552,23 @@ static bool nvenc_sei_data(void *data, uint8_t **extra_data, size_t *size) struct nvenc_encoder *enc = data; *extra_data = enc->sei; - *size = enc->sei_size; + *size = enc->sei_size; return true; } struct obs_encoder_info nvenc_encoder_info = { - .id = "ffmpeg_nvenc", - .type = OBS_ENCODER_VIDEO, - .codec = "h264", - .get_name = nvenc_getname, - .create = nvenc_create, - .destroy = nvenc_destroy, - .encode = nvenc_encode, - .get_defaults = nvenc_defaults, + .id = "ffmpeg_nvenc", + .type = OBS_ENCODER_VIDEO, + .codec = "h264", + .get_name = nvenc_getname, + .create = nvenc_create, + .destroy = nvenc_destroy, + .encode = nvenc_encode, + .update = nvenc_reconfigure, + .get_defaults = nvenc_defaults, .get_properties = nvenc_properties_ffmpeg, .get_extra_data = nvenc_extra_data, - .get_sei_data = nvenc_sei_data, - .get_video_info = nvenc_video_info + .get_sei_data = nvenc_sei_data, + .get_video_info = nvenc_video_info, + .caps = OBS_ENCODER_CAP_DYN_BITRATE, }; diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-output.c b/plugins/obs-ffmpeg/obs-ffmpeg-output.c index 7f687ee..834090f 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-output.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-output.c @@ -32,92 +32,92 @@ #include "obs-ffmpeg-compat.h" struct ffmpeg_cfg { - const char *url; - const char *format_name; - const char *format_mime_type; - const char *muxer_settings; - int gop_size; - int video_bitrate; - int audio_bitrate; - const char *video_encoder; - int video_encoder_id; - const char *audio_encoder; - int audio_encoder_id; - const char *video_settings; - const char *audio_settings; - int audio_mix_count; - int audio_tracks; + const char *url; + const char *format_name; + const char *format_mime_type; + const char *muxer_settings; + int gop_size; + int video_bitrate; + int audio_bitrate; + const char *video_encoder; + int video_encoder_id; + const char *audio_encoder; + int audio_encoder_id; + const char *video_settings; + const char *audio_settings; + int audio_mix_count; + int audio_tracks; enum AVPixelFormat format; - enum AVColorRange color_range; - enum AVColorSpace color_space; - int scale_width; - int scale_height; - int width; - int height; + enum AVColorRange color_range; + enum AVColorSpace color_space; + int scale_width; + int scale_height; + int width; + int height; }; struct ffmpeg_data { - AVStream *video; - AVStream **audio_streams; - AVCodec *acodec; - AVCodec *vcodec; - AVFormatContext *output; - struct SwsContext *swscale; + AVStream *video; + AVStream **audio_streams; + AVCodec *acodec; + AVCodec *vcodec; + AVFormatContext *output; + struct SwsContext *swscale; - int64_t total_frames; - AVFrame *vframe; - int frame_size; + int64_t total_frames; + AVFrame *vframe; + int frame_size; - uint64_t start_timestamp; + uint64_t start_timestamp; - int64_t total_samples[MAX_AUDIO_MIXES]; - uint32_t audio_samplerate; - enum audio_format audio_format; - size_t audio_planes; - size_t audio_size; - int num_audio_streams; + int64_t total_samples[MAX_AUDIO_MIXES]; + uint32_t audio_samplerate; + enum audio_format audio_format; + size_t audio_planes; + size_t audio_size; + int num_audio_streams; /* audio_tracks is a bitmask storing the indices of the mixes */ - int audio_tracks; - struct circlebuf excess_frames[MAX_AUDIO_MIXES][MAX_AV_PLANES]; - uint8_t *samples[MAX_AUDIO_MIXES][MAX_AV_PLANES]; - AVFrame *aframe[MAX_AUDIO_MIXES]; + int audio_tracks; + struct circlebuf excess_frames[MAX_AUDIO_MIXES][MAX_AV_PLANES]; + uint8_t *samples[MAX_AUDIO_MIXES][MAX_AV_PLANES]; + AVFrame *aframe[MAX_AUDIO_MIXES]; - struct ffmpeg_cfg config; + struct ffmpeg_cfg config; - bool initialized; + bool initialized; - char *last_error; + char *last_error; }; struct ffmpeg_output { - obs_output_t *output; - volatile bool active; + obs_output_t *output; + volatile bool active; struct ffmpeg_data ff_data; - bool connecting; - pthread_t start_thread; + bool connecting; + pthread_t start_thread; - uint64_t total_bytes; + uint64_t total_bytes; - uint64_t audio_start_ts; - uint64_t video_start_ts; - uint64_t stop_ts; - volatile bool stopping; + uint64_t audio_start_ts; + uint64_t video_start_ts; + uint64_t stop_ts; + volatile bool stopping; - bool write_thread_active; - pthread_mutex_t write_mutex; - pthread_t write_thread; - os_sem_t *write_sem; - os_event_t *stop_event; + bool write_thread_active; + pthread_mutex_t write_mutex; + pthread_t write_thread; + os_sem_t *write_sem; + os_event_t *stop_event; - DARRAY(AVPacket) packets; + DARRAY(AVPacket) packets; }; /* ------------------------------------------------------------------------- */ static void ffmpeg_output_set_last_error(struct ffmpeg_data *data, - const char *error) + const char *error) { if (data->last_error) bfree(data->last_error); @@ -126,7 +126,7 @@ static void ffmpeg_output_set_last_error(struct ffmpeg_data *data, } void ffmpeg_log_error(int log_level, struct ffmpeg_data *data, - const char *format, ...) + const char *format, ...) { va_list args; char out[4096]; @@ -141,26 +141,27 @@ void ffmpeg_log_error(int log_level, struct ffmpeg_data *data, } static bool new_stream(struct ffmpeg_data *data, AVStream **stream, - AVCodec **codec, enum AVCodecID id, const char *name) + AVCodec **codec, enum AVCodecID id, const char *name) { - *codec = (!!name && *name) ? - avcodec_find_encoder_by_name(name) : - avcodec_find_encoder(id); + *codec = (!!name && *name) ? avcodec_find_encoder_by_name(name) + : avcodec_find_encoder(id); if (!*codec) { - ffmpeg_log_error(LOG_WARNING, data, "Couldn't find encoder '%s'", - avcodec_get_name(id)); + ffmpeg_log_error(LOG_WARNING, data, + "Couldn't find encoder '%s'", + avcodec_get_name(id)); return false; } *stream = avformat_new_stream(data->output, *codec); if (!*stream) { - ffmpeg_log_error(LOG_WARNING, data, "Couldn't create stream for encoder '%s'", - avcodec_get_name(id)); + ffmpeg_log_error(LOG_WARNING, data, + "Couldn't create stream for encoder '%s'", + avcodec_get_name(id)); return false; } - (*stream)->id = data->output->nb_streams-1; + (*stream)->id = data->output->nb_streams - 1; return true; } @@ -180,10 +181,11 @@ static bool parse_params(AVCodecContext *context, char **opts) char *value; *assign = 0; - value = assign+1; + value = assign + 1; if (av_opt_set(context->priv_data, name, value, 0)) { - blog(LOG_WARNING, "Failed to set %s=%s", name, value); + blog(LOG_WARNING, "Failed to set %s=%s", name, + value); ret = false; } } @@ -205,34 +207,39 @@ static bool open_video_codec(struct ffmpeg_data *data) if (opts) { // libav requires x264 parameters in a special format which may be non-obvious - if (!parse_params(context, opts) && strcmp(data->vcodec->name, "libx264") == 0) - blog(LOG_WARNING, "If you're trying to set x264 parameters, use x264-params=name=value:name=value"); + if (!parse_params(context, opts) && + strcmp(data->vcodec->name, "libx264") == 0) + blog(LOG_WARNING, + "If you're trying to set x264 parameters, use x264-params=name=value:name=value"); strlist_free(opts); } ret = avcodec_open2(context, data->vcodec, NULL); if (ret < 0) { - ffmpeg_log_error(LOG_WARNING, data, "Failed to open video codec: %s", - av_err2str(ret)); + ffmpeg_log_error(LOG_WARNING, data, + "Failed to open video codec: %s", + av_err2str(ret)); return false; } data->vframe = av_frame_alloc(); if (!data->vframe) { - ffmpeg_log_error(LOG_WARNING, data, "Failed to allocate video frame"); + ffmpeg_log_error(LOG_WARNING, data, + "Failed to allocate video frame"); return false; } data->vframe->format = context->pix_fmt; - data->vframe->width = context->width; + data->vframe->width = context->width; data->vframe->height = context->height; data->vframe->colorspace = data->config.color_space; data->vframe->color_range = data->config.color_range; ret = av_frame_get_buffer(data->vframe, base_get_alignment()); if (ret < 0) { - ffmpeg_log_error(LOG_WARNING, data, "Failed to allocate vframe: %s", - av_err2str(ret)); + ffmpeg_log_error(LOG_WARNING, data, + "Failed to allocate vframe: %s", + av_err2str(ret)); return false; } @@ -242,14 +249,13 @@ static bool open_video_codec(struct ffmpeg_data *data) static bool init_swscale(struct ffmpeg_data *data, AVCodecContext *context) { data->swscale = sws_getContext( - data->config.width, data->config.height, - data->config.format, - data->config.scale_width, data->config.scale_height, - context->pix_fmt, - SWS_BICUBIC, NULL, NULL, NULL); + data->config.width, data->config.height, data->config.format, + data->config.scale_width, data->config.scale_height, + context->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL); if (!data->swscale) { - ffmpeg_log_error(LOG_WARNING, data, "Could not initialize swscale"); + ffmpeg_log_error(LOG_WARNING, data, + "Could not initialize swscale"); return false; } @@ -268,23 +274,23 @@ static bool create_video_stream(struct ffmpeg_data *data) } if (!new_stream(data, &data->video, &data->vcodec, - data->output->oformat->video_codec, - data->config.video_encoder)) + data->output->oformat->video_codec, + data->config.video_encoder)) return false; - closest_format = get_closest_format(data->config.format, - data->vcodec->pix_fmts); + closest_format = + get_closest_format(data->config.format, data->vcodec->pix_fmts); - context = data->video->codec; - context->bit_rate = data->config.video_bitrate * 1000; - context->width = data->config.scale_width; - context->height = data->config.scale_height; - context->time_base = (AVRational){ ovi.fps_den, ovi.fps_num }; - context->gop_size = data->config.gop_size; - context->pix_fmt = closest_format; - context->colorspace = data->config.color_space; - context->color_range = data->config.color_range; - context->thread_count = 0; + context = data->video->codec; + context->bit_rate = data->config.video_bitrate * 1000; + context->width = data->config.scale_width; + context->height = data->config.scale_height; + context->time_base = (AVRational){ovi.fps_den, ovi.fps_num}; + context->gop_size = data->config.gop_size; + context->pix_fmt = closest_format; + context->colorspace = data->config.color_space; + context->color_range = data->config.color_range; + context->thread_count = 0; data->video->time_base = context->time_base; @@ -294,8 +300,8 @@ static bool create_video_stream(struct ffmpeg_data *data) if (!open_video_codec(data)) return false; - if (context->pix_fmt != data->config.format || - data->config.width != data->config.scale_width || + if (context->pix_fmt != data->config.format || + data->config.width != data->config.scale_width || data->config.height != data->config.scale_height) { if (!init_swscale(data, context)) @@ -318,7 +324,8 @@ static bool open_audio_codec(struct ffmpeg_data *data, int idx) data->aframe[idx] = av_frame_alloc(); if (!data->aframe[idx]) { - ffmpeg_log_error(LOG_WARNING, data, "Failed to allocate audio frame"); + ffmpeg_log_error(LOG_WARNING, data, + "Failed to allocate audio frame"); return false; } @@ -331,18 +338,20 @@ static bool open_audio_codec(struct ffmpeg_data *data, int idx) ret = avcodec_open2(context, data->acodec, NULL); if (ret < 0) { - ffmpeg_log_error(LOG_WARNING, data, "Failed to open audio codec: %s", - av_err2str(ret)); + ffmpeg_log_error(LOG_WARNING, data, + "Failed to open audio codec: %s", + av_err2str(ret)); return false; } data->frame_size = context->frame_size ? context->frame_size : 1024; ret = av_samples_alloc(data->samples[idx], NULL, context->channels, - data->frame_size, context->sample_fmt, 0); + data->frame_size, context->sample_fmt, 0); if (ret < 0) { - ffmpeg_log_error(LOG_WARNING, data, "Failed to create audio buffer: %s", - av_err2str(ret)); + ffmpeg_log_error(LOG_WARNING, data, + "Failed to create audio buffer: %s", + av_err2str(ret)); return false; } @@ -361,25 +370,26 @@ static bool create_audio_stream(struct ffmpeg_data *data, int idx) } if (!new_stream(data, &stream, &data->acodec, - data->output->oformat->audio_codec, - data->config.audio_encoder)) + data->output->oformat->audio_codec, + data->config.audio_encoder)) return false; data->audio_streams[idx] = stream; - context = data->audio_streams[idx]->codec; - context->bit_rate = data->config.audio_bitrate * 1000; - context->time_base = (AVRational){ 1, aoi.samples_per_sec }; - context->channels = get_audio_channels(aoi.speakers); - context->sample_rate = aoi.samples_per_sec; - context->channel_layout = - av_get_default_channel_layout(context->channels); + context = data->audio_streams[idx]->codec; + context->bit_rate = data->config.audio_bitrate * 1000; + context->time_base = (AVRational){1, aoi.samples_per_sec}; + context->channels = get_audio_channels(aoi.speakers); + context->sample_rate = aoi.samples_per_sec; + context->channel_layout = + av_get_default_channel_layout(context->channels); //AVlib default channel layout for 5 channels is 5.0 ; fix for 4.1 if (aoi.speakers == SPEAKERS_4POINT1) context->channel_layout = av_get_channel_layout("4.1"); - context->sample_fmt = data->acodec->sample_fmts ? - data->acodec->sample_fmts[0] : AV_SAMPLE_FMT_FLTP; + context->sample_fmt = data->acodec->sample_fmts + ? data->acodec->sample_fmts[0] + : AV_SAMPLE_FMT_FLTP; data->audio_streams[idx]->time_base = context->time_base; @@ -402,9 +412,10 @@ static inline bool init_streams(struct ffmpeg_data *data) if (!create_video_stream(data)) return false; - if (format->audio_codec != AV_CODEC_ID_NONE && data->num_audio_streams) { - data->audio_streams = calloc(1, - data->num_audio_streams * sizeof(void*)); + if (format->audio_codec != AV_CODEC_ID_NONE && + data->num_audio_streams) { + data->audio_streams = + calloc(1, data->num_audio_streams * sizeof(void *)); for (int i = 0; i < data->num_audio_streams; i++) { if (!create_audio_stream(data, i)) return false; @@ -420,10 +431,11 @@ static inline bool open_output_file(struct ffmpeg_data *data) int ret; AVDictionary *dict = NULL; - if ((ret = av_dict_parse_string(&dict, data->config.muxer_settings, - "=", " ", 0))) { - ffmpeg_log_error(LOG_WARNING, data, "Failed to parse muxer settings: %s\n%s", - av_err2str(ret), data->config.muxer_settings); + if ((ret = av_dict_parse_string(&dict, data->config.muxer_settings, "=", + " ", 0))) { + ffmpeg_log_error(LOG_WARNING, data, + "Failed to parse muxer settings: %s\n%s", + av_err2str(ret), data->config.muxer_settings); av_dict_free(&dict); return false; @@ -434,7 +446,7 @@ static inline bool open_output_file(struct ffmpeg_data *data) AVDictionaryEntry *entry = NULL; while ((entry = av_dict_get(dict, "", entry, - AV_DICT_IGNORE_SUFFIX))) + AV_DICT_IGNORE_SUFFIX))) dstr_catf(&str, "\n\t%s=%s", entry->key, entry->value); blog(LOG_INFO, "Using muxer settings: %s", str.array); @@ -443,24 +455,24 @@ static inline bool open_output_file(struct ffmpeg_data *data) if ((format->flags & AVFMT_NOFILE) == 0) { ret = avio_open2(&data->output->pb, data->config.url, - AVIO_FLAG_WRITE, NULL, &dict); + AVIO_FLAG_WRITE, NULL, &dict); if (ret < 0) { ffmpeg_log_error(LOG_WARNING, data, - "Couldn't open '%s', %s", data->config.url, - av_err2str(ret)); + "Couldn't open '%s', %s", + data->config.url, av_err2str(ret)); av_dict_free(&dict); return false; } } strncpy(data->output->filename, data->config.url, - sizeof(data->output->filename)); + sizeof(data->output->filename)); data->output->filename[sizeof(data->output->filename) - 1] = 0; ret = avformat_write_header(data->output, &dict); if (ret < 0) { ffmpeg_log_error(LOG_WARNING, data, "Error opening '%s': %s", - data->config.url, av_err2str(ret)); + data->config.url, av_err2str(ret)); return false; } @@ -469,7 +481,7 @@ static inline bool open_output_file(struct ffmpeg_data *data) AVDictionaryEntry *entry = NULL; while ((entry = av_dict_get(dict, "", entry, - AV_DICT_IGNORE_SUFFIX))) + AV_DICT_IGNORE_SUFFIX))) dstr_catf(&str, "\n\t%s=%s", entry->key, entry->value); blog(LOG_INFO, "Invalid muxer settings: %s", str.array); @@ -564,16 +576,14 @@ static enum AVCodecID get_codec_id(const char *name, int id) static void set_encoder_ids(struct ffmpeg_data *data) { data->output->oformat->video_codec = get_codec_id( - data->config.video_encoder, - data->config.video_encoder_id); + data->config.video_encoder, data->config.video_encoder_id); data->output->oformat->audio_codec = get_codec_id( - data->config.audio_encoder, - data->config.audio_encoder_id); + data->config.audio_encoder, data->config.audio_encoder_id); } static bool ffmpeg_data_init(struct ffmpeg_data *data, - struct ffmpeg_cfg *config) + struct ffmpeg_cfg *config) { bool is_rtmp = false; @@ -584,35 +594,36 @@ static bool ffmpeg_data_init(struct ffmpeg_data *data, if (!config->url || !*config->url) return false; +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) av_register_all(); +#endif avformat_network_init(); is_rtmp = (astrcmpi_n(config->url, "rtmp://", 7) == 0); AVOutputFormat *output_format = av_guess_format( - is_rtmp ? "flv" : data->config.format_name, - data->config.url, - is_rtmp ? NULL : data->config.format_mime_type); + is_rtmp ? "flv" : data->config.format_name, data->config.url, + is_rtmp ? NULL : data->config.format_mime_type); if (output_format == NULL) { - ffmpeg_log_error(LOG_WARNING, data, + ffmpeg_log_error( + LOG_WARNING, data, "Couldn't find matching output format with " "parameters: name=%s, url=%s, mime=%s", - safe_str(is_rtmp ? - "flv" : data->config.format_name), + safe_str(is_rtmp ? "flv" : data->config.format_name), safe_str(data->config.url), - safe_str(is_rtmp ? - NULL : data->config.format_mime_type)); + safe_str(is_rtmp ? NULL + : data->config.format_mime_type)); goto fail; } - avformat_alloc_output_context2(&data->output, output_format, - NULL, NULL); + avformat_alloc_output_context2(&data->output, output_format, NULL, + NULL); if (!data->output) { ffmpeg_log_error(LOG_WARNING, data, - "Couldn't create avformat context"); + "Couldn't create avformat context"); goto fail; } @@ -653,7 +664,7 @@ static const char *ffmpeg_output_getname(void *unused) } static void ffmpeg_log_callback(void *param, int level, const char *format, - va_list args) + va_list args) { if (level <= AV_LOG_INFO) blogva(LOG_DEBUG, format, args); @@ -707,27 +718,27 @@ static void ffmpeg_output_destroy(void *data) } static inline void copy_data(AVFrame *pic, const struct video_data *frame, - int height, enum AVPixelFormat format) + int height, enum AVPixelFormat format) { int h_chroma_shift, v_chroma_shift; - av_pix_fmt_get_chroma_sub_sample(format, &h_chroma_shift, &v_chroma_shift); + av_pix_fmt_get_chroma_sub_sample(format, &h_chroma_shift, + &v_chroma_shift); for (int plane = 0; plane < MAX_AV_PLANES; plane++) { if (!frame->data[plane]) continue; int frame_rowsize = (int)frame->linesize[plane]; - int pic_rowsize = pic->linesize[plane]; - int bytes = frame_rowsize < pic_rowsize ? - frame_rowsize : pic_rowsize; + int pic_rowsize = pic->linesize[plane]; + int bytes = frame_rowsize < pic_rowsize ? frame_rowsize + : pic_rowsize; int plane_height = height >> (plane ? v_chroma_shift : 0); for (int y = 0; y < plane_height; y++) { int pos_frame = y * frame_rowsize; - int pos_pic = y * pic_rowsize; + int pos_pic = y * pic_rowsize; memcpy(pic->data[plane] + pos_pic, - frame->data[plane] + pos_frame, - bytes); + frame->data[plane] + pos_frame, bytes); } } } @@ -735,7 +746,7 @@ static inline void copy_data(AVFrame *pic, const struct video_data *frame, static void receive_video(void *param, struct video_data *frame) { struct ffmpeg_output *output = param; - struct ffmpeg_data *data = &output->ff_data; + struct ffmpeg_data *data = &output->ff_data; // codec doesn't support video or none configured if (!data->video) @@ -754,17 +765,17 @@ static void receive_video(void *param, struct video_data *frame) if (!!data->swscale) sws_scale(data->swscale, (const uint8_t *const *)frame->data, - (const int*)frame->linesize, - 0, data->config.height, data->vframe->data, - data->vframe->linesize); + (const int *)frame->linesize, 0, data->config.height, + data->vframe->data, data->vframe->linesize); else - copy_data(data->vframe, frame, context->height, context->pix_fmt); + copy_data(data->vframe, frame, context->height, + context->pix_fmt); #if LIBAVFORMAT_VERSION_MAJOR < 58 if (data->output->flags & AVFMT_RAWPICTURE) { - packet.flags |= AV_PKT_FLAG_KEY; - packet.stream_index = data->video->index; - packet.data = data->vframe->data[0]; - packet.size = sizeof(AVPicture); + packet.flags |= AV_PKT_FLAG_KEY; + packet.stream_index = data->video->index; + packet.data = data->vframe->data[0]; + packet.size = sizeof(AVPicture); pthread_mutex_lock(&output->write_mutex); da_push_back(output->packets, &packet); @@ -784,24 +795,26 @@ static void receive_video(void *param, struct video_data *frame) if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) ret = 0; #else - ret = avcodec_encode_video2(context, &packet, data->vframe, - &got_packet); + ret = avcodec_encode_video2(context, &packet, data->vframe, + &got_packet); #endif if (ret < 0) { - blog(LOG_WARNING, "receive_video: Error encoding " - "video: %s", av_err2str(ret)); + blog(LOG_WARNING, + "receive_video: Error encoding " + "video: %s", + av_err2str(ret)); //FIXME: stop the encode with an error return; } if (!ret && got_packet && packet.size) { packet.pts = rescale_ts(packet.pts, context, - data->video->time_base); + data->video->time_base); packet.dts = rescale_ts(packet.dts, context, - data->video->time_base); - packet.duration = (int)av_rescale_q(packet.duration, - context->time_base, - data->video->time_base); + data->video->time_base); + packet.duration = (int)av_rescale_q( + packet.duration, context->time_base, + data->video->time_base); pthread_mutex_lock(&output->write_mutex); da_push_back(output->packets, &packet); @@ -815,7 +828,7 @@ static void receive_video(void *param, struct video_data *frame) #endif if (ret != 0) { blog(LOG_WARNING, "receive_video: Error writing video: %s", - av_err2str(ret)); + av_err2str(ret)); //FIXME: stop the encode with an error } @@ -823,7 +836,7 @@ static void receive_video(void *param, struct video_data *frame) } static void encode_audio(struct ffmpeg_output *output, int idx, - struct AVCodecContext *context, size_t block_size) + struct AVCodecContext *context, size_t block_size) { struct ffmpeg_data *data = &output->ff_data; @@ -832,16 +845,19 @@ static void encode_audio(struct ffmpeg_output *output, int idx, size_t total_size = data->frame_size * block_size * context->channels; data->aframe[idx]->nb_samples = data->frame_size; - data->aframe[idx]->pts = av_rescale_q(data->total_samples[idx], - (AVRational){1, context->sample_rate}, - context->time_base); + data->aframe[idx]->pts = av_rescale_q( + data->total_samples[idx], (AVRational){1, context->sample_rate}, + context->time_base); ret = avcodec_fill_audio_frame(data->aframe[idx], context->channels, - context->sample_fmt, data->samples[idx][0], - (int)total_size, 1); + context->sample_fmt, + data->samples[idx][0], (int)total_size, + 1); if (ret < 0) { - blog(LOG_WARNING, "encode_audio: avcodec_fill_audio_frame " - "failed: %s", av_err2str(ret)); + blog(LOG_WARNING, + "encode_audio: avcodec_fill_audio_frame " + "failed: %s", + av_err2str(ret)); //FIXME: stop the encode with an error return; } @@ -859,11 +875,11 @@ static void encode_audio(struct ffmpeg_output *output, int idx, ret = 0; #else ret = avcodec_encode_audio2(context, &packet, data->aframe[idx], - &got_packet); + &got_packet); #endif if (ret < 0) { blog(LOG_WARNING, "encode_audio: Error encoding audio: %s", - av_err2str(ret)); + av_err2str(ret)); //FIXME: stop the encode with an error return; } @@ -872,11 +888,12 @@ static void encode_audio(struct ffmpeg_output *output, int idx, return; packet.pts = rescale_ts(packet.pts, context, - data->audio_streams[idx]->time_base); + data->audio_streams[idx]->time_base); packet.dts = rescale_ts(packet.dts, context, - data->audio_streams[idx]->time_base); - packet.duration = (int)av_rescale_q(packet.duration, context->time_base, - data->audio_streams[idx]->time_base); + data->audio_streams[idx]->time_base); + packet.duration = + (int)av_rescale_q(packet.duration, context->time_base, + data->audio_streams[idx]->time_base); packet.stream_index = data->audio_streams[idx]->index; pthread_mutex_lock(&output->write_mutex); @@ -885,34 +902,6 @@ static void encode_audio(struct ffmpeg_output *output, int idx, os_sem_post(output->write_sem); } -static bool prepare_audio(struct ffmpeg_data *data, - const struct audio_data *frame, struct audio_data *output) -{ - *output = *frame; - - if (frame->timestamp < data->start_timestamp) { - uint64_t duration = (uint64_t)frame->frames * 1000000000 / - (uint64_t)data->audio_samplerate; - uint64_t end_ts = (frame->timestamp + duration); - uint64_t cutoff; - - if (end_ts <= data->start_timestamp) - return false; - - cutoff = data->start_timestamp - frame->timestamp; - output->timestamp += cutoff; - - cutoff = cutoff * (uint64_t)data->audio_samplerate / - 1000000000; - - for (size_t i = 0; i < data->audio_planes; i++) - output->data[i] += data->audio_size * (uint32_t)cutoff; - output->frames -= (uint32_t)cutoff; - } - - return true; -} - /* Given a bitmask for the selected tracks and the mix index, * this returns the stream index which will be passed to the muxer. */ static int get_track_order(int track_config, size_t mix_index) @@ -928,9 +917,9 @@ static int get_track_order(int track_config, size_t mix_index) static void receive_audio(void *param, size_t mix_idx, struct audio_data *frame) { struct ffmpeg_output *output = param; - struct ffmpeg_data *data = &output->ff_data; + struct ffmpeg_data *data = &output->ff_data; size_t frame_size_bytes; - struct audio_data in; + struct audio_data in = *frame; int track_order; // codec doesn't support audio or none configured @@ -948,8 +937,6 @@ static void receive_audio(void *param, size_t mix_idx, struct audio_data *frame) if (!data->start_timestamp) return; - if (!prepare_audio(data, frame, &in)) - return; if (!output->audio_start_ts) output->audio_start_ts = in.timestamp; @@ -958,22 +945,24 @@ static void receive_audio(void *param, size_t mix_idx, struct audio_data *frame) for (size_t i = 0; i < data->audio_planes; i++) circlebuf_push_back(&data->excess_frames[track_order][i], - in.data[i], in.frames * data->audio_size); + in.data[i], in.frames * data->audio_size); while (data->excess_frames[track_order][0].size >= frame_size_bytes) { for (size_t i = 0; i < data->audio_planes; i++) - circlebuf_pop_front(&data->excess_frames[track_order][i], - data->samples[track_order][i], - frame_size_bytes); + circlebuf_pop_front( + &data->excess_frames[track_order][i], + data->samples[track_order][i], + frame_size_bytes); encode_audio(output, track_order, context, data->audio_size); } } static uint64_t get_packet_sys_dts(struct ffmpeg_output *output, - AVPacket *packet) + AVPacket *packet) { struct ffmpeg_data *data = &output->ff_data; + uint64_t pause_offset = obs_output_get_pause_offset(output->output); uint64_t start_ts; AVRational time_base; @@ -986,8 +975,9 @@ static uint64_t get_packet_sys_dts(struct ffmpeg_output *output, start_ts = output->audio_start_ts; } - return start_ts + (uint64_t)av_rescale_q(packet->dts, - time_base, (AVRational){1, 1000000000}); + return start_ts + pause_offset + + (uint64_t)av_rescale_q(packet->dts, time_base, + (AVRational){1, 1000000000}); } static int process_packet(struct ffmpeg_output *output) @@ -1026,8 +1016,8 @@ static int process_packet(struct ffmpeg_output *output) if (ret < 0) { av_free_packet(&packet); ffmpeg_log_error(LOG_WARNING, &output->ff_data, - "receive_audio: Error writing packet: %s", - av_err2str(ret)); + "receive_audio: Error writing packet: %s", + av_err2str(ret)); return ret; } @@ -1064,7 +1054,7 @@ static void *write_thread(void *data) } static inline const char *get_string_or_null(obs_data_t *settings, - const char *name) + const char *name) { const char *value = obs_data_get_string(settings, name); if (!value || !strlen(value)) @@ -1099,34 +1089,36 @@ static bool try_connect(struct ffmpeg_output *output) config.url = obs_data_get_string(settings, "url"); config.format_name = get_string_or_null(settings, "format_name"); - config.format_mime_type = get_string_or_null(settings, - "format_mime_type"); + config.format_mime_type = + get_string_or_null(settings, "format_mime_type"); config.muxer_settings = obs_data_get_string(settings, "muxer_settings"); config.video_bitrate = (int)obs_data_get_int(settings, "video_bitrate"); config.audio_bitrate = (int)obs_data_get_int(settings, "audio_bitrate"); config.gop_size = (int)obs_data_get_int(settings, "gop_size"); config.video_encoder = get_string_or_null(settings, "video_encoder"); - config.video_encoder_id = (int)obs_data_get_int(settings, - "video_encoder_id"); + config.video_encoder_id = + (int)obs_data_get_int(settings, "video_encoder_id"); config.audio_encoder = get_string_or_null(settings, "audio_encoder"); - config.audio_encoder_id = (int)obs_data_get_int(settings, - "audio_encoder_id"); + config.audio_encoder_id = + (int)obs_data_get_int(settings, "audio_encoder_id"); config.video_settings = obs_data_get_string(settings, "video_settings"); config.audio_settings = obs_data_get_string(settings, "audio_settings"); config.scale_width = (int)obs_data_get_int(settings, "scale_width"); config.scale_height = (int)obs_data_get_int(settings, "scale_height"); - config.width = (int)obs_output_get_width(output->output); + config.width = (int)obs_output_get_width(output->output); config.height = (int)obs_output_get_height(output->output); - config.format = obs_to_ffmpeg_video_format( - video_output_get_format(video)); + config.format = + obs_to_ffmpeg_video_format(video_output_get_format(video)); config.audio_tracks = (int)obs_output_get_mixers(output->output); config.audio_mix_count = get_audio_mix_count(config.audio_tracks); if (format_is_yuv(voi->format)) { - config.color_range = voi->range == VIDEO_RANGE_FULL ? - AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; - config.color_space = voi->colorspace == VIDEO_CS_709 ? - AVCOL_SPC_BT709 : AVCOL_SPC_BT470BG; + config.color_range = voi->range == VIDEO_RANGE_FULL + ? AVCOL_RANGE_JPEG + : AVCOL_RANGE_MPEG; + config.color_space = voi->colorspace == VIDEO_CS_709 + ? AVCOL_SPC_BT709 + : AVCOL_SPC_BT470BG; } else { config.color_range = AVCOL_RANGE_UNSPECIFIED; config.color_space = AVCOL_SPC_RGB; @@ -1148,15 +1140,14 @@ static bool try_connect(struct ffmpeg_output *output) if (!success) { if (output->ff_data.last_error) { obs_output_set_last_error(output->output, - output->ff_data.last_error); + output->ff_data.last_error); } ffmpeg_data_free(&output->ff_data); return false; } - struct audio_convert_info aci = { - .format = output->ff_data.audio_format - }; + struct audio_convert_info aci = {.format = + output->ff_data.audio_format}; output->active = true; @@ -1166,8 +1157,8 @@ static bool try_connect(struct ffmpeg_output *output) ret = pthread_create(&output->write_thread, NULL, write_thread, output); if (ret != 0) { ffmpeg_log_error(LOG_WARNING, &output->ff_data, - "ffmpeg_output_start: failed to create write " - "thread."); + "ffmpeg_output_start: failed to create write " + "thread."); ffmpeg_output_full_stop(output); return false; } @@ -1185,7 +1176,7 @@ static void *start_thread(void *data) if (!try_connect(output)) obs_output_signal_stop(output->output, - OBS_OUTPUT_CONNECT_FAILED); + OBS_OUTPUT_CONNECT_FAILED); output->connecting = false; return NULL; @@ -1244,7 +1235,7 @@ static void ffmpeg_deactivate(struct ffmpeg_output *output) pthread_mutex_lock(&output->write_mutex); for (size_t i = 0; i < output->packets.num; i++) - av_free_packet(output->packets.array+i); + av_free_packet(output->packets.array + i); da_free(output->packets); pthread_mutex_unlock(&output->write_mutex); @@ -1259,15 +1250,14 @@ static uint64_t ffmpeg_output_total_bytes(void *data) } struct obs_output_info ffmpeg_output = { - .id = "ffmpeg_output", - .flags = OBS_OUTPUT_AUDIO | - OBS_OUTPUT_VIDEO | - OBS_OUTPUT_MULTI_TRACK, - .get_name = ffmpeg_output_getname, - .create = ffmpeg_output_create, - .destroy = ffmpeg_output_destroy, - .start = ffmpeg_output_start, - .stop = ffmpeg_output_stop, + .id = "ffmpeg_output", + .flags = OBS_OUTPUT_AUDIO | OBS_OUTPUT_VIDEO | OBS_OUTPUT_MULTI_TRACK | + OBS_OUTPUT_CAN_PAUSE, + .get_name = ffmpeg_output_getname, + .create = ffmpeg_output_create, + .destroy = ffmpeg_output_destroy, + .start = ffmpeg_output_start, + .stop = ffmpeg_output_stop, .raw_video = receive_video, .raw_audio2 = receive_audio, .get_total_bytes = ffmpeg_output_total_bytes, diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-source.c b/plugins/obs-ffmpeg/obs-ffmpeg-source.c index b1fe369..84379b2 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-source.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-source.c @@ -25,9 +25,9 @@ #define FF_LOG(level, format, ...) \ blog(level, "[Media Source]: " format, ##__VA_ARGS__) -#define FF_LOG_S(source, level, format, ...) \ +#define FF_LOG_S(source, level, format, ...) \ blog(level, "[Media Source '%s']: " format, \ - obs_source_get_name(source), ##__VA_ARGS__) + obs_source_get_name(source), ##__VA_ARGS__) #define FF_BLOG(level, format, ...) \ FF_LOG_S(s->source, level, format, ##__VA_ARGS__) @@ -60,18 +60,19 @@ struct ffmpeg_source { }; static bool is_local_file_modified(obs_properties_t *props, - obs_property_t *prop, obs_data_t *settings) + obs_property_t *prop, obs_data_t *settings) { UNUSED_PARAMETER(prop); bool enabled = obs_data_get_bool(settings, "is_local_file"); obs_property_t *input = obs_properties_get(props, "input"); - obs_property_t *input_format =obs_properties_get(props, - "input_format"); + obs_property_t *input_format = + obs_properties_get(props, "input_format"); obs_property_t *local_file = obs_properties_get(props, "local_file"); obs_property_t *looping = obs_properties_get(props, "looping"); obs_property_t *buffering = obs_properties_get(props, "buffering_mb"); - obs_property_t *close = obs_properties_get(props, "close_when_inactive"); + obs_property_t *close = + obs_properties_get(props, "close_when_inactive"); obs_property_t *seekable = obs_properties_get(props, "seekable"); obs_property_t *speed = obs_properties_get(props, "speed_percent"); obs_property_set_visible(input, !enabled); @@ -103,8 +104,7 @@ static const char *media_filter = " (*.mp4 *.ts *.mov *.flv *.mkv *.avi *.mp3 *.ogg *.aac *.wav *.gif *.webm);;"; static const char *video_filter = " (*.mp4 *.ts *.mov *.flv *.mkv *.avi *.gif *.webm);;"; -static const char *audio_filter = - " (*.mp3 *.aac *.ogg *.wav);;"; +static const char *audio_filter = " (*.mp3 *.aac *.ogg *.wav);;"; static obs_properties_t *ffmpeg_source_getproperties(void *data) { @@ -120,7 +120,7 @@ static obs_properties_t *ffmpeg_source_getproperties(void *data) obs_property_t *prop; // use this when obs allows non-readonly paths prop = obs_properties_add_bool(props, "is_local_file", - obs_module_text("LocalFile")); + obs_module_text("LocalFile")); obs_property_set_modified_callback(prop, is_local_file_modified); @@ -144,53 +144,59 @@ static obs_properties_t *ffmpeg_source_getproperties(void *data) } obs_properties_add_path(props, "local_file", - obs_module_text("LocalFile"), OBS_PATH_FILE, - filter.array, path.array); + obs_module_text("LocalFile"), OBS_PATH_FILE, + filter.array, path.array); dstr_free(&filter); dstr_free(&path); prop = obs_properties_add_bool(props, "looping", - obs_module_text("Looping")); + obs_module_text("Looping")); obs_properties_add_bool(props, "restart_on_activate", - obs_module_text("RestartWhenActivated")); + obs_module_text("RestartWhenActivated")); - obs_properties_add_int_slider(props, "buffering_mb", - obs_module_text("BufferingMB"), - 1, 16, 1); + prop = obs_properties_add_int_slider(props, "buffering_mb", + obs_module_text("BufferingMB"), 1, + 16, 1); + obs_property_int_set_suffix(prop, " MB"); - obs_properties_add_text(props, "input", - obs_module_text("Input"), OBS_TEXT_DEFAULT); + obs_properties_add_text(props, "input", obs_module_text("Input"), + OBS_TEXT_DEFAULT); obs_properties_add_text(props, "input_format", - obs_module_text("InputFormat"), OBS_TEXT_DEFAULT); + obs_module_text("InputFormat"), + OBS_TEXT_DEFAULT); #ifndef __APPLE__ obs_properties_add_bool(props, "hw_decode", - obs_module_text("HardwareDecode")); + obs_module_text("HardwareDecode")); #endif obs_properties_add_bool(props, "clear_on_media_end", - obs_module_text("ClearOnMediaEnd")); + obs_module_text("ClearOnMediaEnd")); - prop = obs_properties_add_bool(props, "close_when_inactive", - obs_module_text("CloseFileWhenInactive")); + prop = obs_properties_add_bool( + props, "close_when_inactive", + obs_module_text("CloseFileWhenInactive")); - obs_property_set_long_description(prop, - obs_module_text("CloseFileWhenInactive.ToolTip")); + obs_property_set_long_description( + prop, obs_module_text("CloseFileWhenInactive.ToolTip")); - obs_properties_add_int_slider(props, "speed_percent", - obs_module_text("SpeedPercentage"), 1, 200, 1); + prop = obs_properties_add_int_slider(props, "speed_percent", + obs_module_text("SpeedPercentage"), + 1, 200, 1); + obs_property_int_set_suffix(prop, "%"); prop = obs_properties_add_list(props, "color_range", - obs_module_text("ColorRange"), OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_INT); + obs_module_text("ColorRange"), + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); obs_property_list_add_int(prop, obs_module_text("ColorRange.Auto"), - VIDEO_RANGE_DEFAULT); + VIDEO_RANGE_DEFAULT); obs_property_list_add_int(prop, obs_module_text("ColorRange.Partial"), - VIDEO_RANGE_PARTIAL); + VIDEO_RANGE_PARTIAL); obs_property_list_add_int(prop, obs_module_text("ColorRange.Full"), - VIDEO_RANGE_FULL); + VIDEO_RANGE_FULL); obs_properties_add_bool(props, "seekable", obs_module_text("Seekable")); @@ -198,26 +204,24 @@ static obs_properties_t *ffmpeg_source_getproperties(void *data) } static void dump_source_info(struct ffmpeg_source *s, const char *input, - const char *input_format) + const char *input_format) { FF_BLOG(LOG_INFO, - "settings:\n" - "\tinput: %s\n" - "\tinput_format: %s\n" - "\tspeed: %d\n" - "\tis_looping: %s\n" - "\tis_hw_decoding: %s\n" - "\tis_clear_on_media_end: %s\n" - "\trestart_on_activate: %s\n" - "\tclose_when_inactive: %s", - input ? input : "(null)", - input_format ? input_format : "(null)", - s->speed_percent, - s->is_looping ? "yes" : "no", - s->is_hw_decoding ? "yes" : "no", - s->is_clear_on_media_end ? "yes" : "no", - s->restart_on_activate ? "yes" : "no", - s->close_when_inactive ? "yes" : "no"); + "settings:\n" + "\tinput: %s\n" + "\tinput_format: %s\n" + "\tspeed: %d\n" + "\tis_looping: %s\n" + "\tis_hw_decoding: %s\n" + "\tis_clear_on_media_end: %s\n" + "\trestart_on_activate: %s\n" + "\tclose_when_inactive: %s", + input ? input : "(null)", + input_format ? input_format : "(null)", s->speed_percent, + s->is_looping ? "yes" : "no", s->is_hw_decoding ? "yes" : "no", + s->is_clear_on_media_end ? "yes" : "no", + s->restart_on_activate ? "yes" : "no", + s->close_when_inactive ? "yes" : "no"); } static void get_frame(void *opaque, struct obs_source_frame *f) @@ -267,8 +271,7 @@ static void ffmpeg_source_open(struct ffmpeg_source *s) .speed = s->speed_percent, .force_range = s->range, .hardware_decoding = s->is_hw_decoding, - .is_local_file = s->is_local_file || s->seekable - }; + .is_local_file = s->is_local_file || s->seekable}; s->media_valid = mp_media_init(&s->media, &info); } @@ -316,14 +319,14 @@ static void ffmpeg_source_update(void *data, obs_data_t *settings) input = (char *)obs_data_get_string(settings, "local_file"); input_format = NULL; s->is_looping = obs_data_get_bool(settings, "looping"); - s->close_when_inactive = obs_data_get_bool(settings, - "close_when_inactive"); + s->close_when_inactive = + obs_data_get_bool(settings, "close_when_inactive"); obs_source_set_async_unbuffered(s->source, true); } else { input = (char *)obs_data_get_string(settings, "input"); - input_format = (char *)obs_data_get_string(settings, - "input_format"); + input_format = + (char *)obs_data_get_string(settings, "input_format"); s->is_looping = false; s->close_when_inactive = true; @@ -335,12 +338,12 @@ static void ffmpeg_source_update(void *data, obs_data_t *settings) #ifndef __APPLE__ s->is_hw_decoding = obs_data_get_bool(settings, "hw_decode"); #endif - s->is_clear_on_media_end = obs_data_get_bool(settings, - "clear_on_media_end"); - s->restart_on_activate = obs_data_get_bool(settings, - "restart_on_activate"); + s->is_clear_on_media_end = + obs_data_get_bool(settings, "clear_on_media_end"); + s->restart_on_activate = + obs_data_get_bool(settings, "restart_on_activate"); s->range = (enum video_range_type)obs_data_get_int(settings, - "color_range"); + "color_range"); s->buffering_mb = (int)obs_data_get_int(settings, "buffering_mb"); s->speed_percent = (int)obs_data_get_int(settings, "speed_percent"); s->is_local_file = is_local_file; @@ -369,8 +372,8 @@ static const char *ffmpeg_source_getname(void *unused) return obs_module_text("FFMpegSource"); } -static void restart_hotkey(void *data, obs_hotkey_id id, - obs_hotkey_t *hotkey, bool pressed) +static void restart_hotkey(void *data, obs_hotkey_id id, obs_hotkey_t *hotkey, + bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(hotkey); @@ -407,12 +410,12 @@ static void get_nb_frames(void *data, calldata_t *cd) return; } - int video_stream_index = av_find_best_stream(s->media.fmt, - AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); + int video_stream_index = av_find_best_stream( + s->media.fmt, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); if (video_stream_index < 0) { FF_BLOG(LOG_WARNING, "Getting number of frames failed: No " - "video stream in media file!"); + "video stream in media file!"); calldata_set_int(cd, "num_frames", frames); return; } @@ -423,12 +426,12 @@ static void get_nb_frames(void *data, calldata_t *cd) frames = stream->nb_frames; } else { FF_BLOG(LOG_DEBUG, "nb_frames not set, estimating using frame " - "rate and duration"); + "rate and duration"); AVRational avg_frame_rate = stream->avg_frame_rate; frames = (int64_t)ceil((double)s->media.fmt->duration / - (double)AV_TIME_BASE * - (double)avg_frame_rate.num / - (double)avg_frame_rate.den); + (double)AV_TIME_BASE * + (double)avg_frame_rate.num / + (double)avg_frame_rate.den); } calldata_set_int(cd, "num_frames", frames); @@ -441,17 +444,16 @@ static void *ffmpeg_source_create(obs_data_t *settings, obs_source_t *source) struct ffmpeg_source *s = bzalloc(sizeof(struct ffmpeg_source)); s->source = source; - s->hotkey = obs_hotkey_register_source(source, - "MediaSource.Restart", - obs_module_text("RestartMedia"), - restart_hotkey, s); + s->hotkey = obs_hotkey_register_source(source, "MediaSource.Restart", + obs_module_text("RestartMedia"), + restart_hotkey, s); proc_handler_t *ph = obs_source_get_proc_handler(source); proc_handler_add(ph, "void restart()", restart_proc, s); proc_handler_add(ph, "void get_duration(out int duration)", - get_duration, s); + get_duration, s); proc_handler_add(ph, "void get_nb_frames(out int num_frames)", - get_nb_frames, s); + get_nb_frames, s); ffmpeg_source_update(s, settings); return s; @@ -497,17 +499,17 @@ static void ffmpeg_source_deactivate(void *data) } struct obs_source_info ffmpeg_source = { - .id = "ffmpeg_source", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO | - OBS_SOURCE_DO_NOT_DUPLICATE, - .get_name = ffmpeg_source_getname, - .create = ffmpeg_source_create, - .destroy = ffmpeg_source_destroy, - .get_defaults = ffmpeg_source_defaults, + .id = "ffmpeg_source", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO | + OBS_SOURCE_DO_NOT_DUPLICATE, + .get_name = ffmpeg_source_getname, + .create = ffmpeg_source_create, + .destroy = ffmpeg_source_destroy, + .get_defaults = ffmpeg_source_defaults, .get_properties = ffmpeg_source_getproperties, - .activate = ffmpeg_source_activate, - .deactivate = ffmpeg_source_deactivate, - .video_tick = ffmpeg_source_tick, - .update = ffmpeg_source_update + .activate = ffmpeg_source_activate, + .deactivate = ffmpeg_source_deactivate, + .video_tick = ffmpeg_source_tick, + .update = ffmpeg_source_update, }; diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c b/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c index 28b4d6f..e285e90 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c @@ -37,9 +37,9 @@ #include "obs-ffmpeg-formats.h" -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[FFMPEG VAAPI encoder: '%s'] " format, \ - obs_encoder_get_name(enc->encoder), ##__VA_ARGS__) + obs_encoder_get_name(enc->encoder), ##__VA_ARGS__) #define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) #define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) @@ -51,7 +51,7 @@ struct vaapi_encoder { AVBufferRef *vadevice_ref; AVBufferRef *vaframes_ref; - AVCodec * vaapi; + AVCodec *vaapi; AVCodecContext *context; AVFrame *vframe; @@ -59,12 +59,12 @@ struct vaapi_encoder { DARRAY(uint8_t) buffer; uint8_t *header; - size_t header_size; + size_t header_size; uint8_t *sei; - size_t sei_size; + size_t sei_size; - int height; + int height; bool first_packet; bool initialized; }; @@ -83,7 +83,7 @@ static inline bool valid_format(enum video_format format) static void vaapi_video_info(void *data, struct video_scale_info *info) { struct vaapi_encoder *enc = data; - enum video_format pref_format; + enum video_format pref_format; pref_format = obs_encoder_get_preferred_video_format(enc->encoder); @@ -100,10 +100,10 @@ static bool vaapi_init_codec(struct vaapi_encoder *enc, const char *path) int ret; ret = av_hwdevice_ctx_create(&enc->vadevice_ref, AV_HWDEVICE_TYPE_VAAPI, - path, NULL, 0); + path, NULL, 0); if (ret < 0) { warn("Failed to create VAAPI device context: %s", - av_err2str(ret)); + av_err2str(ret)); return false; } @@ -114,11 +114,11 @@ static bool vaapi_init_codec(struct vaapi_encoder *enc, const char *path) } AVHWFramesContext *frames_ctx = - (AVHWFramesContext *)enc->vaframes_ref->data; - frames_ctx->format = AV_PIX_FMT_VAAPI; - frames_ctx->sw_format = AV_PIX_FMT_NV12; - frames_ctx->width = enc->context->width; - frames_ctx->height = enc->context->height; + (AVHWFramesContext *)enc->vaframes_ref->data; + frames_ctx->format = AV_PIX_FMT_VAAPI; + frames_ctx->sw_format = AV_PIX_FMT_NV12; + frames_ctx->width = enc->context->width; + frames_ctx->height = enc->context->height; frames_ctx->initial_pool_size = 20; ret = av_hwframe_ctx_init(enc->vaframes_ref); @@ -135,9 +135,9 @@ static bool vaapi_init_codec(struct vaapi_encoder *enc, const char *path) } enc->vframe->format = enc->context->pix_fmt; - enc->vframe->width = enc->context->width; + enc->vframe->width = enc->context->width; enc->vframe->height = enc->context->height; - enc->vframe->colorspace = enc->context->colorspace; + enc->vframe->colorspace = enc->context->colorspace; enc->vframe->color_range = enc->context->color_range; ret = av_frame_get_buffer(enc->vframe, base_get_alignment()); @@ -147,7 +147,7 @@ static bool vaapi_init_codec(struct vaapi_encoder *enc, const char *path) } /* 3. set up codec */ - enc->context->pix_fmt = AV_PIX_FMT_VAAPI; + enc->context->pix_fmt = AV_PIX_FMT_VAAPI; enc->context->hw_frames_ctx = av_buffer_ref(enc->vaframes_ref); ret = avcodec_open2(enc->context, enc->vaapi, NULL); @@ -167,49 +167,49 @@ static bool vaapi_update(void *data, obs_data_t *settings) const char *device = obs_data_get_string(settings, "vaapi_device"); int profile = (int)obs_data_get_int(settings, "profile"); - int bf = (int)obs_data_get_int(settings, "bf"); + int bf = (int)obs_data_get_int(settings, "bf"); - int level = (int)obs_data_get_int(settings, "level"); - int bitrate = (int)obs_data_get_int(settings, "bitrate"); + int level = (int)obs_data_get_int(settings, "level"); + int bitrate = (int)obs_data_get_int(settings, "bitrate"); int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec"); - int qp = (int)obs_data_get_int(settings, "qp"); + int qp = (int)obs_data_get_int(settings, "qp"); int quality = (int)obs_data_get_int(settings, "quality"); av_opt_set_int(enc->context->priv_data, "qp", qp, 0); av_opt_set_int(enc->context->priv_data, "quality", quality, 0); - video_t * video = obs_encoder_video(enc->encoder); - const struct video_output_info *voi = video_output_get_info(video); - struct video_scale_info info; + video_t *video = obs_encoder_video(enc->encoder); + const struct video_output_info *voi = video_output_get_info(video); + struct video_scale_info info; - info.format = voi->format; + info.format = voi->format; info.colorspace = voi->colorspace; - info.range = voi->range; + info.range = voi->range; vaapi_video_info(enc, &info); - enc->context->profile = profile; + enc->context->profile = profile; enc->context->max_b_frames = bf; - enc->context->level = level; - enc->context->bit_rate = bitrate * 1000; - enc->context->rc_max_rate = bitrate * 1000; + enc->context->level = level; + enc->context->bit_rate = bitrate * 1000; + enc->context->rc_max_rate = bitrate * 1000; - enc->context->width = obs_encoder_get_width(enc->encoder); + enc->context->width = obs_encoder_get_width(enc->encoder); enc->context->height = obs_encoder_get_height(enc->encoder); - enc->context->time_base = (AVRational){voi->fps_den, voi->fps_num}; - enc->context->pix_fmt = obs_to_ffmpeg_video_format(info.format); + enc->context->time_base = (AVRational){voi->fps_den, voi->fps_num}; + enc->context->pix_fmt = obs_to_ffmpeg_video_format(info.format); enc->context->colorspace = info.colorspace == VIDEO_CS_709 - ? AVCOL_SPC_BT709 - : AVCOL_SPC_BT470BG; + ? AVCOL_SPC_BT709 + : AVCOL_SPC_BT470BG; enc->context->color_range = info.range == VIDEO_RANGE_FULL - ? AVCOL_RANGE_JPEG - : AVCOL_RANGE_MPEG; + ? AVCOL_RANGE_JPEG + : AVCOL_RANGE_MPEG; if (keyint_sec > 0) { enc->context->gop_size = - keyint_sec * voi->fps_num / voi->fps_den; + keyint_sec * voi->fps_num / voi->fps_den; } else { enc->context->gop_size = 120; } @@ -227,9 +227,9 @@ static bool vaapi_update(void *data, obs_data_t *settings) "\twidth: %d\n" "\theight: %d\n" "\tb-frames: %d\n", - device, qp, quality, profile, level, bitrate, - enc->context->gop_size, enc->context->width, - enc->context->height, enc->context->max_b_frames); + device, qp, quality, profile, level, bitrate, + enc->context->gop_size, enc->context->width, enc->context->height, + enc->context->max_b_frames); return vaapi_init_codec(enc, device); } @@ -239,8 +239,8 @@ static void vaapi_destroy(void *data) struct vaapi_encoder *enc = data; if (enc->initialized) { - AVPacket pkt = {0}; - int r_pkt = 1; + AVPacket pkt = {0}; + int r_pkt = 1; while (r_pkt) { #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 40, 101) @@ -248,7 +248,7 @@ static void vaapi_destroy(void *data) break; #else if (avcodec_encode_video2(enc->context, &pkt, NULL, - &r_pkt) < 0) + &r_pkt) < 0) break; #endif @@ -272,9 +272,11 @@ static void vaapi_destroy(void *data) static void *vaapi_create(obs_data_t *settings, obs_encoder_t *encoder) { struct vaapi_encoder *enc; +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) avcodec_register_all(); +#endif - enc = bzalloc(sizeof(*enc)); + enc = bzalloc(sizeof(*enc)); enc->encoder = encoder; int vaapi_codec = (int)obs_data_get_int(settings, "vaapi_codec"); @@ -309,39 +311,39 @@ fail: } static inline void copy_data(AVFrame *pic, const struct encoder_frame *frame, - int height, enum AVPixelFormat format) + int height, enum AVPixelFormat format) { int h_chroma_shift, v_chroma_shift; - av_pix_fmt_get_chroma_sub_sample( - format, &h_chroma_shift, &v_chroma_shift); + av_pix_fmt_get_chroma_sub_sample(format, &h_chroma_shift, + &v_chroma_shift); for (int plane = 0; plane < MAX_AV_PLANES; plane++) { if (!frame->data[plane]) continue; int frame_rowsize = (int)frame->linesize[plane]; - int pic_rowsize = pic->linesize[plane]; - int bytes = frame_rowsize < pic_rowsize ? frame_rowsize + int pic_rowsize = pic->linesize[plane]; + int bytes = frame_rowsize < pic_rowsize ? frame_rowsize : pic_rowsize; int plane_height = height >> (plane ? v_chroma_shift : 0); for (int y = 0; y < plane_height; y++) { int pos_frame = y * frame_rowsize; - int pos_pic = y * pic_rowsize; + int pos_pic = y * pic_rowsize; memcpy(pic->data[plane] + pos_pic, - frame->data[plane] + pos_frame, bytes); + frame->data[plane] + pos_frame, bytes); } } } static bool vaapi_encode(void *data, struct encoder_frame *frame, - struct encoder_packet *packet, bool *received_packet) + struct encoder_packet *packet, bool *received_packet) { - struct vaapi_encoder *enc = data; - AVFrame * hwframe = NULL; - AVPacket av_pkt; - int got_packet; - int ret; + struct vaapi_encoder *enc = data; + AVFrame *hwframe = NULL; + AVPacket av_pkt; + int got_packet; + int ret; hwframe = av_frame_alloc(); if (!hwframe) { @@ -352,28 +354,28 @@ static bool vaapi_encode(void *data, struct encoder_frame *frame, ret = av_hwframe_get_buffer(enc->vaframes_ref, hwframe, 0); if (ret < 0) { warn("vaapi_encode: failed to get buffer for hw frame: %s", - av_err2str(ret)); + av_err2str(ret)); goto fail; } copy_data(enc->vframe, frame, enc->height, enc->context->pix_fmt); enc->vframe->pts = frame->pts; - hwframe->pts = frame->pts; - hwframe->width = enc->vframe->width; - hwframe->height = enc->vframe->height; + hwframe->pts = frame->pts; + hwframe->width = enc->vframe->width; + hwframe->height = enc->vframe->height; ret = av_hwframe_transfer_data(hwframe, enc->vframe, 0); if (ret < 0) { warn("vaapi_encode: failed to upload hw frame: %s", - av_err2str(ret)); + av_err2str(ret)); goto fail; } ret = av_frame_copy_props(hwframe, enc->vframe); if (ret < 0) { warn("vaapi_encode: failed to copy props to hw frame: %s", - av_err2str(ret)); + av_err2str(ret)); goto fail; } @@ -389,8 +391,8 @@ static bool vaapi_encode(void *data, struct encoder_frame *frame, if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) ret = 0; #else - ret = avcodec_encode_video2( - enc->context, &av_pkt, hwframe, &got_packet); + ret = avcodec_encode_video2(enc->context, &av_pkt, hwframe, + &got_packet); #endif if (ret < 0) { warn("vaapi_encode: Error encoding: %s", av_err2str(ret)); @@ -400,13 +402,13 @@ static bool vaapi_encode(void *data, struct encoder_frame *frame, if (got_packet && av_pkt.size) { if (enc->first_packet) { uint8_t *new_packet; - size_t size; + size_t size; enc->first_packet = false; obs_extract_avc_headers(av_pkt.data, av_pkt.size, - &new_packet, &size, &enc->header, - &enc->header_size, &enc->sei, - &enc->sei_size); + &new_packet, &size, + &enc->header, &enc->header_size, + &enc->sei, &enc->sei_size); da_copy_array(enc->buffer, new_packet, size); bfree(new_packet); @@ -414,11 +416,11 @@ static bool vaapi_encode(void *data, struct encoder_frame *frame, da_copy_array(enc->buffer, av_pkt.data, av_pkt.size); } - packet->pts = av_pkt.pts; - packet->dts = av_pkt.dts; - packet->data = enc->buffer.array; - packet->size = enc->buffer.num; - packet->type = OBS_ENCODER_VIDEO; + packet->pts = av_pkt.pts; + packet->dts = av_pkt.dts; + packet->data = enc->buffer.array; + packet->size = enc->buffer.num; + packet->type = OBS_ENCODER_VIDEO; packet->keyframe = obs_avc_keyframe(packet->data, packet->size); *received_packet = true; } else { @@ -442,11 +444,11 @@ static void set_visible(obs_properties_t *ppts, const char *name, bool visible) static void vaapi_defaults(obs_data_t *settings) { - obs_data_set_default_string( - settings, "vaapi_device", "/dev/dri/renderD128"); + obs_data_set_default_string(settings, "vaapi_device", + "/dev/dri/renderD128"); obs_data_set_default_int(settings, "vaapi_codec", AV_CODEC_ID_H264); obs_data_set_default_int(settings, "profile", - FF_PROFILE_H264_CONSTRAINED_BASELINE); + FF_PROFILE_H264_CONSTRAINED_BASELINE); obs_data_set_default_int(settings, "level", 40); obs_data_set_default_int(settings, "bitrate", 2500); obs_data_set_default_int(settings, "keyint_sec", 0); @@ -461,10 +463,11 @@ static obs_properties_t *vaapi_properties(void *unused) UNUSED_PARAMETER(unused); obs_properties_t *props = obs_properties_create(); - obs_property_t * list; + obs_property_t *list; list = obs_properties_add_list(props, "vaapi_device", "VAAPI Device", - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); char path[32] = "/dev/dri/renderD1"; for (int i = 28;; i++) { sprintf(path, "/dev/dri/renderD1%d", i); @@ -478,27 +481,29 @@ static obs_properties_t *vaapi_properties(void *unused) } list = obs_properties_add_list(props, "vaapi_codec", "VAAPI Codec", - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); obs_property_list_add_int(list, "H.264 (default)", AV_CODEC_ID_H264); list = obs_properties_add_list(props, "level", "Level", - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); obs_property_list_add_int(list, "480p30 (3.0)", 30); obs_property_list_add_int(list, "720p30/480p60 (3.1)", 31); - obs_property_list_add_int( - list, "Compatibility mode (4.0 default)", 40); + obs_property_list_add_int(list, "Compatibility mode (4.0 default)", + 40); obs_property_list_add_int(list, "720p60/1080p30 (4.1)", 41); obs_property_list_add_int(list, "1080p60 (4.2)", 42); obs_property_t *p; - p = obs_properties_add_int(props, "bitrate", obs_module_text("Bitrate"), 0, - 300000, 50); + p = obs_properties_add_int(props, "bitrate", obs_module_text("Bitrate"), + 0, 300000, 50); obs_property_int_set_suffix(p, " Kbps"); obs_properties_add_int(props, "keyint_sec", - obs_module_text("Keyframe Interval (seconds)"), 0, 20, - 1); + obs_module_text("Keyframe Interval (seconds)"), + 0, 20, 1); return props; } @@ -508,7 +513,7 @@ static bool vaapi_extra_data(void *data, uint8_t **extra_data, size_t *size) struct vaapi_encoder *enc = data; *extra_data = enc->header; - *size = enc->header_size; + *size = enc->header_size; return true; } @@ -517,23 +522,23 @@ static bool vaapi_sei_data(void *data, uint8_t **extra_data, size_t *size) struct vaapi_encoder *enc = data; *extra_data = enc->sei; - *size = enc->sei_size; + *size = enc->sei_size; return true; } struct obs_encoder_info vaapi_encoder_info = { - .id = "ffmpeg_vaapi", - .type = OBS_ENCODER_VIDEO, - .codec = "h264", - .get_name = vaapi_getname, - .create = vaapi_create, - .destroy = vaapi_destroy, - .encode = vaapi_encode, - .get_defaults = vaapi_defaults, + .id = "ffmpeg_vaapi", + .type = OBS_ENCODER_VIDEO, + .codec = "h264", + .get_name = vaapi_getname, + .create = vaapi_create, + .destroy = vaapi_destroy, + .encode = vaapi_encode, + .get_defaults = vaapi_defaults, .get_properties = vaapi_properties, .get_extra_data = vaapi_extra_data, - .get_sei_data = vaapi_sei_data, - .get_video_info = vaapi_video_info + .get_sei_data = vaapi_sei_data, + .get_video_info = vaapi_video_info, }; #endif diff --git a/plugins/obs-ffmpeg/obs-ffmpeg.c b/plugins/obs-ffmpeg/obs-ffmpeg.c index 808e5a0..e05d612 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg.c @@ -1,11 +1,10 @@ #include -#include #include -#include #include #include #include -#include + +#include "obs-ffmpeg-config.h" #ifdef _WIN32 #include @@ -20,10 +19,10 @@ MODULE_EXPORT const char *obs_module_description(void) return "FFmpeg based sources/outputs/encoders"; } -extern struct obs_source_info ffmpeg_source; -extern struct obs_output_info ffmpeg_output; -extern struct obs_output_info ffmpeg_muxer; -extern struct obs_output_info replay_buffer; +extern struct obs_source_info ffmpeg_source; +extern struct obs_output_info ffmpeg_output; +extern struct obs_output_info ffmpeg_muxer; +extern struct obs_output_info replay_buffer; extern struct obs_encoder_info aac_encoder_info; extern struct obs_encoder_info opus_encoder_info; extern struct obs_encoder_info nvenc_encoder_info; @@ -36,134 +35,16 @@ extern struct obs_encoder_info nvenc_encoder_info; extern struct obs_encoder_info vaapi_encoder_info; #endif -static DARRAY(struct log_context { - void *context; - char str[4096]; - int print_prefix; -} *) active_log_contexts; -static DARRAY(struct log_context *) cached_log_contexts; -pthread_mutex_t log_contexts_mutex = PTHREAD_MUTEX_INITIALIZER; - -static struct log_context *create_or_fetch_log_context(void *context) -{ - pthread_mutex_lock(&log_contexts_mutex); - for (size_t i = 0; i < active_log_contexts.num; i++) { - if (context == active_log_contexts.array[i]->context) { - pthread_mutex_unlock(&log_contexts_mutex); - return active_log_contexts.array[i]; - } - } - - struct log_context *new_log_context = NULL; - - size_t cnt = cached_log_contexts.num; - if (!!cnt) { - new_log_context = cached_log_contexts.array[cnt - 1]; - da_pop_back(cached_log_contexts); - } - - if (!new_log_context) - new_log_context = bzalloc(sizeof(struct log_context)); - - new_log_context->context = context; - new_log_context->str[0] = '\0'; - new_log_context->print_prefix = 1; - - da_push_back(active_log_contexts, &new_log_context); - - pthread_mutex_unlock(&log_contexts_mutex); - - return new_log_context; -} - -static void destroy_log_context(struct log_context *log_context) -{ - pthread_mutex_lock(&log_contexts_mutex); - da_erase_item(active_log_contexts, &log_context); - da_push_back(cached_log_contexts, &log_context); - pthread_mutex_unlock(&log_contexts_mutex); -} - -static void ffmpeg_log_callback(void* context, int level, const char* format, - va_list args) -{ - if (format == NULL) - return; - - struct log_context *log_context = create_or_fetch_log_context(context); - - char *str = log_context->str; - - av_log_format_line(context, level, format, args, str + strlen(str), - (int)(sizeof(log_context->str) - strlen(str)), - &log_context->print_prefix); - - int obs_level; - switch (level) { - case AV_LOG_PANIC: - case AV_LOG_FATAL: - obs_level = LOG_ERROR; - break; - case AV_LOG_ERROR: - case AV_LOG_WARNING: - obs_level = LOG_WARNING; - break; - case AV_LOG_INFO: - case AV_LOG_VERBOSE: - obs_level = LOG_INFO; - break; - case AV_LOG_DEBUG: - default: - obs_level = LOG_DEBUG; - } - - if (!log_context->print_prefix) - return; - - char *str_end = str + strlen(str) - 1; - while(str < str_end) { - if (*str_end != '\n') - break; - *str_end-- = '\0'; - } - - if (str_end <= str) - goto cleanup; - - blog(obs_level, "[ffmpeg] %s", str); - -cleanup: - destroy_log_context(log_context); -} - #ifndef __APPLE__ static const char *nvenc_check_name = "nvenc_check"; #ifdef _WIN32 static const wchar_t *blacklisted_adapters[] = { - L"720M", - L"730M", - L"740M", - L"745M", - L"820M", - L"830M", - L"840M", - L"845M", - L"920M", - L"930M", - L"940M", - L"945M", - L"1030", - L"MX110", - L"MX130", - L"MX150", - L"MX230", - L"MX250", - L"M520", - L"M500", - L"P500", - L"K620M" + L"720M", L"730M", L"740M", L"745M", L"820M", L"830M", + L"840M", L"845M", L"920M", L"930M", L"940M", L"945M", + L"1030", L"MX110", L"MX130", L"MX150", L"MX230", L"MX250", + L"M520", L"M500", L"P500", L"K620M", }; static const size_t num_blacklisted = @@ -202,7 +83,7 @@ static bool is_blacklisted(const wchar_t *name) return false; } -typedef HRESULT (WINAPI *create_dxgi_proc)(const IID *, IDXGIFactory1 **); +typedef HRESULT(WINAPI *create_dxgi_proc)(const IID *, IDXGIFactory1 **); static bool nvenc_device_available(void) { @@ -226,7 +107,7 @@ static bool nvenc_device_available(void) if (!create) { create = (create_dxgi_proc)GetProcAddress(dxgi, - "CreateDXGIFactory1"); + "CreateDXGIFactory1"); if (!create) { return true; } @@ -266,7 +147,9 @@ extern bool load_nvenc_lib(void); static bool nvenc_supported(void) { +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) av_register_all(); +#endif profile_start(nvenc_check_name); @@ -319,13 +202,13 @@ extern void jim_nvenc_load(void); extern void jim_nvenc_unload(void); #endif +#if ENABLE_FFMPEG_LOGGING +extern void obs_ffmpeg_load_logging(void); +extern void obs_ffmpeg_unload_logging(void); +#endif + bool obs_module_load(void) { - da_init(active_log_contexts); - da_init(cached_log_contexts); - - //av_log_set_callback(ffmpeg_log_callback); - obs_register_source(&ffmpeg_source); obs_register_output(&ffmpeg_output); obs_register_output(&ffmpeg_muxer); @@ -348,28 +231,20 @@ bool obs_module_load(void) obs_register_encoder(&vaapi_encoder_info); } #endif +#endif + +#if ENABLE_FFMPEG_LOGGING + obs_ffmpeg_load_logging(); #endif return true; } void obs_module_unload(void) { - av_log_set_callback(av_log_default_callback); - -#ifdef _WIN32 - pthread_mutex_destroy(&log_contexts_mutex); +#if ENABLE_FFMPEG_LOGGING + obs_ffmpeg_unload_logging(); #endif - for (size_t i = 0; i < active_log_contexts.num; i++) { - bfree(active_log_contexts.array[i]); - } - for (size_t i = 0; i < cached_log_contexts.num; i++) { - bfree(cached_log_contexts.array[i]); - } - - da_free(active_log_contexts); - da_free(cached_log_contexts); - #ifdef _WIN32 jim_nvenc_unload(); #endif diff --git a/plugins/obs-filters/async-delay-filter.c b/plugins/obs-filters/async-delay-filter.c index 3baff63..862c78a 100644 --- a/plugins/obs-filters/async-delay-filter.c +++ b/plugins/obs-filters/async-delay-filter.c @@ -9,28 +9,28 @@ #define MSEC_TO_NSEC 1000000ULL #endif -#define SETTING_DELAY_MS "delay_ms" +#define SETTING_DELAY_MS "delay_ms" -#define TEXT_DELAY_MS obs_module_text("DelayMs") +#define TEXT_DELAY_MS obs_module_text("DelayMs") struct async_delay_data { - obs_source_t *context; + obs_source_t *context; /* contains struct obs_source_frame* */ - struct circlebuf video_frames; + struct circlebuf video_frames; /* stores the audio data */ - struct circlebuf audio_frames; - struct obs_audio_data audio_output; + struct circlebuf audio_frames; + struct obs_audio_data audio_output; - uint64_t last_video_ts; - uint64_t last_audio_ts; - uint64_t interval; - uint64_t samplerate; - bool video_delay_reached; - bool audio_delay_reached; - bool reset_video; - bool reset_audio; + uint64_t last_video_ts; + uint64_t last_audio_ts; + uint64_t interval; + uint64_t samplerate; + bool video_delay_reached; + bool audio_delay_reached; + bool reset_video; + bool reset_audio; }; static const char *async_delay_filter_name(void *unused) @@ -40,13 +40,13 @@ static const char *async_delay_filter_name(void *unused) } static void free_video_data(struct async_delay_data *filter, - obs_source_t *parent) + obs_source_t *parent) { while (filter->video_frames.size) { struct obs_source_frame *frame; circlebuf_pop_front(&filter->video_frames, &frame, - sizeof(struct obs_source_frame*)); + sizeof(struct obs_source_frame *)); obs_source_release_frame(parent, frame); } } @@ -64,7 +64,7 @@ static void free_audio_data(struct async_delay_data *filter) struct obs_audio_data audio; circlebuf_pop_front(&filter->audio_frames, &audio, - sizeof(struct obs_audio_data)); + sizeof(struct obs_audio_data)); free_audio_packet(&audio); } } @@ -72,8 +72,9 @@ static void free_audio_data(struct async_delay_data *filter) static void async_delay_filter_update(void *data, obs_data_t *settings) { struct async_delay_data *filter = data; - uint64_t new_interval = (uint64_t)obs_data_get_int(settings, - SETTING_DELAY_MS) * MSEC_TO_NSEC; + uint64_t new_interval = + (uint64_t)obs_data_get_int(settings, SETTING_DELAY_MS) * + MSEC_TO_NSEC; if (new_interval < filter->interval) free_video_data(filter, obs_filter_get_parent(filter->context)); @@ -86,7 +87,7 @@ static void async_delay_filter_update(void *data, obs_data_t *settings) } static void *async_delay_filter_create(obs_data_t *settings, - obs_source_t *context) + obs_source_t *context) { struct async_delay_data *filter = bzalloc(sizeof(*filter)); struct obs_audio_info oai; @@ -114,8 +115,9 @@ static obs_properties_t *async_delay_filter_properties(void *data) { obs_properties_t *props = obs_properties_create(); - obs_properties_add_int(props, SETTING_DELAY_MS, TEXT_DELAY_MS, - 0, 20000, 1); + obs_property_t *p = obs_properties_add_int(props, SETTING_DELAY_MS, + TEXT_DELAY_MS, 0, 20000, 1); + obs_property_int_set_suffix(p, " ms"); UNUSED_PARAMETER(data); return props; @@ -138,8 +140,8 @@ static inline bool is_timestamp_jump(uint64_t ts, uint64_t prev_ts) return ts < prev_ts || (ts - prev_ts) > SEC_TO_NSEC; } -static struct obs_source_frame *async_delay_filter_video(void *data, - struct obs_source_frame *frame) +static struct obs_source_frame * +async_delay_filter_video(void *data, struct obs_source_frame *frame) { struct async_delay_data *filter = data; obs_source_t *parent = obs_filter_get_parent(filter->context); @@ -156,16 +158,16 @@ static struct obs_source_frame *async_delay_filter_video(void *data, filter->last_video_ts = frame->timestamp; circlebuf_push_back(&filter->video_frames, &frame, - sizeof(struct obs_source_frame*)); + sizeof(struct obs_source_frame *)); circlebuf_peek_front(&filter->video_frames, &output, - sizeof(struct obs_source_frame*)); + sizeof(struct obs_source_frame *)); cur_interval = frame->timestamp - output->timestamp; if (!filter->video_delay_reached && cur_interval < filter->interval) return NULL; circlebuf_pop_front(&filter->video_frames, NULL, - sizeof(struct obs_source_frame*)); + sizeof(struct obs_source_frame *)); if (!filter->video_delay_reached) filter->video_delay_reached = true; @@ -179,8 +181,8 @@ static struct obs_source_frame *async_delay_filter_video(void *data, /* #define DELAY_AUDIO */ #ifdef DELAY_AUDIO -static struct obs_audio_data *async_delay_filter_audio(void *data, - struct obs_audio_data *audio) +static struct obs_audio_data * +async_delay_filter_audio(void *data, struct obs_audio_data *audio) { struct async_delay_data *filter = data; struct obs_audio_data cached = *audio; @@ -204,8 +206,8 @@ static struct obs_audio_data *async_delay_filter_audio(void *data, if (!audio->data[i]) break; - cached.data[i] = bmemdup(audio->data[i], - audio->frames * sizeof(float)); + cached.data[i] = + bmemdup(audio->data[i], audio->frames * sizeof(float)); } free_audio_packet(&filter->audio_output); @@ -228,17 +230,17 @@ static struct obs_audio_data *async_delay_filter_audio(void *data, #endif struct obs_source_info async_delay_filter = { - .id = "async_delay_filter", - .type = OBS_SOURCE_TYPE_FILTER, - .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_ASYNC, - .get_name = async_delay_filter_name, - .create = async_delay_filter_create, - .destroy = async_delay_filter_destroy, - .update = async_delay_filter_update, - .get_properties = async_delay_filter_properties, - .filter_video = async_delay_filter_video, + .id = "async_delay_filter", + .type = OBS_SOURCE_TYPE_FILTER, + .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_ASYNC, + .get_name = async_delay_filter_name, + .create = async_delay_filter_create, + .destroy = async_delay_filter_destroy, + .update = async_delay_filter_update, + .get_properties = async_delay_filter_properties, + .filter_video = async_delay_filter_video, #ifdef DELAY_AUDIO - .filter_audio = async_delay_filter_audio, + .filter_audio = async_delay_filter_audio, #endif - .filter_remove = async_delay_filter_remove + .filter_remove = async_delay_filter_remove, }; diff --git a/plugins/obs-filters/chroma-key-filter.c b/plugins/obs-filters/chroma-key-filter.c index 3fa9790..071256e 100644 --- a/plugins/obs-filters/chroma-key-filter.c +++ b/plugins/obs-filters/chroma-key-filter.c @@ -3,6 +3,8 @@ #include #include +/* clang-format off */ + #define SETTING_OPACITY "opacity" #define SETTING_CONTRAST "contrast" #define SETTING_BRIGHTNESS "brightness" @@ -23,31 +25,33 @@ #define TEXT_SMOOTHNESS obs_module_text("Smoothness") #define TEXT_SPILL obs_module_text("ColorSpillReduction") +/* clang-format on */ + struct chroma_key_filter_data { - obs_source_t *context; + obs_source_t *context; - gs_effect_t *effect; + gs_effect_t *effect; - gs_eparam_t *color_param; - gs_eparam_t *contrast_param; - gs_eparam_t *brightness_param; - gs_eparam_t *gamma_param; + gs_eparam_t *color_param; + gs_eparam_t *contrast_param; + gs_eparam_t *brightness_param; + gs_eparam_t *gamma_param; - gs_eparam_t *pixel_size_param; - gs_eparam_t *chroma_param; - gs_eparam_t *similarity_param; - gs_eparam_t *smoothness_param; - gs_eparam_t *spill_param; + gs_eparam_t *pixel_size_param; + gs_eparam_t *chroma_param; + gs_eparam_t *similarity_param; + gs_eparam_t *smoothness_param; + gs_eparam_t *spill_param; - struct vec4 color; - float contrast; - float brightness; - float gamma; + struct vec4 color; + float contrast; + float brightness; + float gamma; - struct vec2 chroma; - float similarity; - float smoothness; - float spill; + struct vec2 chroma; + float similarity; + float smoothness; + float spill; }; static const char *chroma_key_name(void *unused) @@ -56,23 +60,23 @@ static const char *chroma_key_name(void *unused) return obs_module_text("ChromaKeyFilter"); } -static const float yuv_mat[16] = {0.182586f, -0.100644f, 0.439216f, 0.0f, - 0.614231f, -0.338572f, -0.398942f, 0.0f, - 0.062007f, 0.439216f, -0.040274f, 0.0f, - 0.062745f, 0.501961f, 0.501961f, 1.0f}; +static const float yuv_mat[16] = {0.182586f, -0.100644f, 0.439216f, 0.0f, + 0.614231f, -0.338572f, -0.398942f, 0.0f, + 0.062007f, 0.439216f, -0.040274f, 0.0f, + 0.062745f, 0.501961f, 0.501961f, 1.0f}; -static inline void color_settings_update( - struct chroma_key_filter_data *filter, obs_data_t *settings) +static inline void color_settings_update(struct chroma_key_filter_data *filter, + obs_data_t *settings) { - uint32_t opacity = (uint32_t)obs_data_get_int(settings, - SETTING_OPACITY); + uint32_t opacity = + (uint32_t)obs_data_get_int(settings, SETTING_OPACITY); uint32_t color = 0xFFFFFF | (((opacity * 255) / 100) << 24); double contrast = obs_data_get_double(settings, SETTING_CONTRAST); double brightness = obs_data_get_double(settings, SETTING_BRIGHTNESS); double gamma = obs_data_get_double(settings, SETTING_GAMMA); - contrast = (contrast < 0.0) ? - (1.0 / (-contrast + 1.0)) : (contrast + 1.0); + contrast = (contrast < 0.0) ? (1.0 / (-contrast + 1.0)) + : (contrast + 1.0); brightness *= 0.5; @@ -85,16 +89,16 @@ static inline void color_settings_update( vec4_from_rgba(&filter->color, color); } -static inline void chroma_settings_update( - struct chroma_key_filter_data *filter, obs_data_t *settings) +static inline void chroma_settings_update(struct chroma_key_filter_data *filter, + obs_data_t *settings) { int64_t similarity = obs_data_get_int(settings, SETTING_SIMILARITY); int64_t smoothness = obs_data_get_int(settings, SETTING_SMOOTHNESS); int64_t spill = obs_data_get_int(settings, SETTING_SPILL); - uint32_t key_color = (uint32_t)obs_data_get_int(settings, - SETTING_KEY_COLOR); - const char *key_type = obs_data_get_string(settings, - SETTING_COLOR_TYPE); + uint32_t key_color = + (uint32_t)obs_data_get_int(settings, SETTING_KEY_COLOR); + const char *key_type = + obs_data_get_string(settings, SETTING_COLOR_TYPE); struct vec4 key_rgb; struct vec4 key_color_v4; struct matrix4 yuv_mat_m4; @@ -150,24 +154,24 @@ static void *chroma_key_create(obs_data_t *settings, obs_source_t *context) filter->effect = gs_effect_create_from_file(effect_path, NULL); if (filter->effect) { - filter->color_param = gs_effect_get_param_by_name( - filter->effect, "color"); - filter->contrast_param = gs_effect_get_param_by_name( - filter->effect, "contrast"); + filter->color_param = + gs_effect_get_param_by_name(filter->effect, "color"); + filter->contrast_param = + gs_effect_get_param_by_name(filter->effect, "contrast"); filter->brightness_param = gs_effect_get_param_by_name( - filter->effect, "brightness"); - filter->gamma_param = gs_effect_get_param_by_name( - filter->effect, "gamma"); + filter->effect, "brightness"); + filter->gamma_param = + gs_effect_get_param_by_name(filter->effect, "gamma"); filter->chroma_param = gs_effect_get_param_by_name( - filter->effect, "chroma_key"); + filter->effect, "chroma_key"); filter->pixel_size_param = gs_effect_get_param_by_name( - filter->effect, "pixel_size"); + filter->effect, "pixel_size"); filter->similarity_param = gs_effect_get_param_by_name( - filter->effect, "similarity"); + filter->effect, "similarity"); filter->smoothness_param = gs_effect_get_param_by_name( - filter->effect, "smoothness"); - filter->spill_param = gs_effect_get_param_by_name( - filter->effect, "spill"); + filter->effect, "smoothness"); + filter->spill_param = + gs_effect_get_param_by_name(filter->effect, "spill"); } obs_leave_graphics(); @@ -192,7 +196,7 @@ static void chroma_key_render(void *data, gs_effect_t *effect) struct vec2 pixel_size; if (!obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING)) + OBS_ALLOW_DIRECT_RENDERING)) return; vec2_set(&pixel_size, 1.0f / (float)width, 1.0f / (float)height); @@ -213,13 +217,13 @@ static void chroma_key_render(void *data, gs_effect_t *effect) } static bool key_type_changed(obs_properties_t *props, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { const char *type = obs_data_get_string(settings, SETTING_COLOR_TYPE); bool custom = strcmp(type, "custom") == 0; obs_property_set_visible(obs_properties_get(props, SETTING_KEY_COLOR), - custom); + custom); UNUSED_PARAMETER(p); return true; @@ -229,9 +233,10 @@ static obs_properties_t *chroma_key_properties(void *data) { obs_properties_t *props = obs_properties_create(); - obs_property_t *p = obs_properties_add_list(props, - SETTING_COLOR_TYPE, TEXT_COLOR_TYPE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + obs_property_t *p = obs_properties_add_list(props, SETTING_COLOR_TYPE, + TEXT_COLOR_TYPE, + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, obs_module_text("Green"), "green"); obs_property_list_add_string(p, obs_module_text("Blue"), "blue"); obs_property_list_add_string(p, obs_module_text("Magenta"), "magenta"); @@ -241,20 +246,20 @@ static obs_properties_t *chroma_key_properties(void *data) obs_properties_add_color(props, SETTING_KEY_COLOR, TEXT_KEY_COLOR); obs_properties_add_int_slider(props, SETTING_SIMILARITY, - TEXT_SIMILARITY, 1, 1000, 1); + TEXT_SIMILARITY, 1, 1000, 1); obs_properties_add_int_slider(props, SETTING_SMOOTHNESS, - TEXT_SMOOTHNESS, 1, 1000, 1); - obs_properties_add_int_slider(props, SETTING_SPILL, - TEXT_SPILL, 1, 1000, 1); + TEXT_SMOOTHNESS, 1, 1000, 1); + obs_properties_add_int_slider(props, SETTING_SPILL, TEXT_SPILL, 1, 1000, + 1); - obs_properties_add_int_slider(props, SETTING_OPACITY, TEXT_OPACITY, - 0, 100, 1); - obs_properties_add_float_slider(props, SETTING_CONTRAST, - TEXT_CONTRAST, -1.0, 1.0, 0.01); + obs_properties_add_int_slider(props, SETTING_OPACITY, TEXT_OPACITY, 0, + 100, 1); + obs_properties_add_float_slider(props, SETTING_CONTRAST, TEXT_CONTRAST, + -1.0, 1.0, 0.01); obs_properties_add_float_slider(props, SETTING_BRIGHTNESS, - TEXT_BRIGHTNESS, -1.0, 1.0, 0.01); - obs_properties_add_float_slider(props, SETTING_GAMMA, - TEXT_GAMMA, -1.0, 1.0, 0.01); + TEXT_BRIGHTNESS, -1.0, 1.0, 0.01); + obs_properties_add_float_slider(props, SETTING_GAMMA, TEXT_GAMMA, -1.0, + 1.0, 0.01); UNUSED_PARAMETER(data); return props; @@ -274,14 +279,14 @@ static void chroma_key_defaults(obs_data_t *settings) } struct obs_source_info chroma_key_filter = { - .id = "chroma_key_filter", - .type = OBS_SOURCE_TYPE_FILTER, - .output_flags = OBS_SOURCE_VIDEO, - .get_name = chroma_key_name, - .create = chroma_key_create, - .destroy = chroma_key_destroy, - .video_render = chroma_key_render, - .update = chroma_key_update, - .get_properties = chroma_key_properties, - .get_defaults = chroma_key_defaults + .id = "chroma_key_filter", + .type = OBS_SOURCE_TYPE_FILTER, + .output_flags = OBS_SOURCE_VIDEO, + .get_name = chroma_key_name, + .create = chroma_key_create, + .destroy = chroma_key_destroy, + .video_render = chroma_key_render, + .update = chroma_key_update, + .get_properties = chroma_key_properties, + .get_defaults = chroma_key_defaults, }; diff --git a/plugins/obs-filters/color-correction-filter.c b/plugins/obs-filters/color-correction-filter.c index fad36a6..7d06158 100644 --- a/plugins/obs-filters/color-correction-filter.c +++ b/plugins/obs-filters/color-correction-filter.c @@ -18,6 +18,7 @@ along with this program. If not, see . #include #include +/* clang-format off */ #define SETTING_GAMMA "gamma" #define SETTING_CONTRAST "contrast" @@ -35,39 +36,41 @@ along with this program. If not, see . #define TEXT_OPACITY obs_module_text("Opacity") #define TEXT_COLOR obs_module_text("Color") +/* clang-format on */ + struct color_correction_filter_data { - obs_source_t *context; + obs_source_t *context; - gs_effect_t *effect; + gs_effect_t *effect; - gs_eparam_t *gamma_param; - gs_eparam_t *final_matrix_param; + gs_eparam_t *gamma_param; + gs_eparam_t *final_matrix_param; - struct vec3 gamma; - float contrast; - float brightness; - float saturation; - float hue_shift; - float opacity; - struct vec4 color; + struct vec3 gamma; + float contrast; + float brightness; + float saturation; + float hue_shift; + float opacity; + struct vec4 color; /* Pre-Computes */ - struct matrix4 con_matrix; - struct matrix4 bright_matrix; - struct matrix4 sat_matrix; - struct matrix4 hue_op_matrix; - struct matrix4 color_matrix; - struct matrix4 final_matrix; + struct matrix4 con_matrix; + struct matrix4 bright_matrix; + struct matrix4 sat_matrix; + struct matrix4 hue_op_matrix; + struct matrix4 color_matrix; + struct matrix4 final_matrix; - struct vec3 rot_quaternion; - float rot_quaternion_w; - struct vec3 cross; - struct vec3 square; - struct vec3 wimag; - struct vec3 diag; - struct vec3 a_line; - struct vec3 b_line; - struct vec3 half_unit; + struct vec3 rot_quaternion; + float rot_quaternion_w; + struct vec3 cross; + struct vec3 square; + struct vec3 wimag; + struct vec3 diag; + struct vec3 a_line; + struct vec3 b_line; + struct vec3 half_unit; }; static const float root3 = 0.57735f; @@ -101,22 +104,31 @@ static void color_correction_filter_update(void *data, obs_data_t *settings) vec3_set(&filter->gamma, (float)gamma, (float)gamma, (float)gamma); /* Build our contrast number. */ - filter->contrast = (float)obs_data_get_double(settings, - SETTING_CONTRAST) + 1.0f; + filter->contrast = + (float)obs_data_get_double(settings, SETTING_CONTRAST) + 1.0f; float one_minus_con = (1.0f - filter->contrast) / 2.0f; /* Now let's build our Contrast matrix. */ - filter->con_matrix = (struct matrix4) - { - filter->contrast, 0.0f, 0.0f, 0.0f, - 0.0f, filter->contrast, 0.0f, 0.0f, - 0.0f, 0.0f, filter->contrast, 0.0f, - one_minus_con, one_minus_con, one_minus_con, 1.0f - }; + filter->con_matrix = (struct matrix4){filter->contrast, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + filter->contrast, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + filter->contrast, + 0.0f, + one_minus_con, + one_minus_con, + one_minus_con, + 1.0f}; /* Build our brightness number. */ - filter->brightness = (float)obs_data_get_double(settings, - SETTING_BRIGHTNESS); + filter->brightness = + (float)obs_data_get_double(settings, SETTING_BRIGHTNESS); /* * Now let's build our Brightness matrix. @@ -129,49 +141,57 @@ static void color_correction_filter_update(void *data, obs_data_t *settings) filter->bright_matrix.t.z = filter->brightness; /* Build our Saturation number. */ - filter->saturation = (float)obs_data_get_double(settings, - SETTING_SATURATION) + 1.0f; + filter->saturation = + (float)obs_data_get_double(settings, SETTING_SATURATION) + 1.0f; /* Factor in the selected color weights. */ float one_minus_sat_red = (1.0f - filter->saturation) * red_weight; float one_minus_sat_green = (1.0f - filter->saturation) * green_weight; float one_minus_sat_blue = (1.0f - filter->saturation) * blue_weight; - float sat_val_red = one_minus_sat_red + filter->saturation; + float sat_val_red = one_minus_sat_red + filter->saturation; float sat_val_green = one_minus_sat_green + filter->saturation; - float sat_val_blue = one_minus_sat_blue + filter->saturation; + float sat_val_blue = one_minus_sat_blue + filter->saturation; /* Now we build our Saturation matrix. */ - filter->sat_matrix = (struct matrix4) - { - sat_val_red, one_minus_sat_red, one_minus_sat_red, 0.0f, - one_minus_sat_green, sat_val_green, one_minus_sat_green, 0.0f, - one_minus_sat_blue, one_minus_sat_blue, sat_val_blue, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - }; + filter->sat_matrix = (struct matrix4){sat_val_red, + one_minus_sat_red, + one_minus_sat_red, + 0.0f, + one_minus_sat_green, + sat_val_green, + one_minus_sat_green, + 0.0f, + one_minus_sat_blue, + one_minus_sat_blue, + sat_val_blue, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + 1.0f}; /* Build our Hue number. */ - filter->hue_shift = (float)obs_data_get_double(settings, - SETTING_HUESHIFT); + filter->hue_shift = + (float)obs_data_get_double(settings, SETTING_HUESHIFT); /* Build our Transparency number. */ - filter->opacity = (float)obs_data_get_int(settings, - SETTING_OPACITY) * 0.01f; + filter->opacity = + (float)obs_data_get_int(settings, SETTING_OPACITY) * 0.01f; /* Hue is the radian of 0 to 360 degrees. */ float half_angle = 0.5f * (float)(filter->hue_shift / (180.0f / M_PI)); /* Pseudo-Quaternion To Matrix. */ float rot_quad1 = root3 * (float)sin(half_angle); - vec3_set(&filter->rot_quaternion, rot_quad1, rot_quad1, - rot_quad1); + vec3_set(&filter->rot_quaternion, rot_quad1, rot_quad1, rot_quad1); filter->rot_quaternion_w = (float)cos(half_angle); vec3_mul(&filter->cross, &filter->rot_quaternion, - &filter->rot_quaternion); + &filter->rot_quaternion); vec3_mul(&filter->square, &filter->rot_quaternion, - &filter->rot_quaternion); + &filter->rot_quaternion); vec3_mulf(&filter->wimag, &filter->rot_quaternion, - filter->rot_quaternion_w); + filter->rot_quaternion_w); vec3_mulf(&filter->square, &filter->square, 2.0f); vec3_sub(&filter->diag, &filter->half_unit, &filter->square); @@ -179,29 +199,28 @@ static void color_correction_filter_update(void *data, obs_data_t *settings) vec3_sub(&filter->b_line, &filter->cross, &filter->wimag); /* Now we build our Hue and Opacity matrix. */ - filter->hue_op_matrix = (struct matrix4) - { - filter->diag.x * 2.0f, - filter->b_line.z * 2.0f, - filter->a_line.y * 2.0f, - 0.0f, + filter->hue_op_matrix = (struct matrix4){filter->diag.x * 2.0f, + filter->b_line.z * 2.0f, + filter->a_line.y * 2.0f, + 0.0f, - filter->a_line.z * 2.0f, - filter->diag.y * 2.0f, - filter->b_line.x * 2.0f, - 0.0f, + filter->a_line.z * 2.0f, + filter->diag.y * 2.0f, + filter->b_line.x * 2.0f, + 0.0f, - filter->b_line.y * 2.0f, - filter->a_line.x * 2.0f, - filter->diag.z * 2.0f, - 0.0f, + filter->b_line.y * 2.0f, + filter->a_line.x * 2.0f, + filter->diag.z * 2.0f, + 0.0f, - 0.0f, 0.0f, 0.0f, filter->opacity - }; + 0.0f, + 0.0f, + 0.0f, + filter->opacity}; /* Now get the overlay color data. */ - uint32_t color = (uint32_t)obs_data_get_int(settings, - SETTING_COLOR); + uint32_t color = (uint32_t)obs_data_get_int(settings, SETTING_COLOR); vec4_from_rgba(&filter->color, color); /* @@ -214,26 +233,22 @@ static void color_correction_filter_update(void *data, obs_data_t *settings) filter->color_matrix.y.y = filter->color.y; filter->color_matrix.z.z = filter->color.z; - filter->color_matrix.t.x = filter->color.w * - filter->color.x; - filter->color_matrix.t.y = filter->color.w * - filter->color.y; - filter->color_matrix.t.z = filter->color.w * - filter->color.z; - + filter->color_matrix.t.x = filter->color.w * filter->color.x; + filter->color_matrix.t.y = filter->color.w * filter->color.y; + filter->color_matrix.t.z = filter->color.w * filter->color.z; /* First we apply the Contrast & Brightness matrix. */ matrix4_mul(&filter->final_matrix, &filter->bright_matrix, - &filter->con_matrix); + &filter->con_matrix); /* Now we apply the Saturation matrix. */ matrix4_mul(&filter->final_matrix, &filter->final_matrix, - &filter->sat_matrix); + &filter->sat_matrix); /* Next we apply the Hue+Opacity matrix. */ matrix4_mul(&filter->final_matrix, &filter->final_matrix, - &filter->hue_op_matrix); + &filter->hue_op_matrix); /* Lastly we apply the Color Wash matrix. */ matrix4_mul(&filter->final_matrix, &filter->final_matrix, - &filter->color_matrix); + &filter->color_matrix); } /* @@ -261,7 +276,7 @@ static void color_correction_filter_destroy(void *data) * actual rendering code. */ static void *color_correction_filter_create(obs_data_t *settings, - obs_source_t *context) + obs_source_t *context) { /* * Because of limitations of pre-c99 compilers, you can't create an @@ -294,9 +309,9 @@ static void *color_correction_filter_create(obs_data_t *settings, /* If the filter is active pass the parameters to the filter. */ if (filter->effect) { filter->gamma_param = gs_effect_get_param_by_name( - filter->effect, SETTING_GAMMA); + filter->effect, SETTING_GAMMA); filter->final_matrix_param = gs_effect_get_param_by_name( - filter->effect, "color_matrix"); + filter->effect, "color_matrix"); } obs_leave_graphics(); @@ -328,12 +343,13 @@ static void color_correction_filter_render(void *data, gs_effect_t *effect) struct color_correction_filter_data *filter = data; if (!obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING)) + OBS_ALLOW_DIRECT_RENDERING)) return; /* Now pass the interface variables to the .effect file. */ gs_effect_set_vec3(filter->gamma_param, &filter->gamma); - gs_effect_set_matrix4(filter->final_matrix_param, &filter->final_matrix); + gs_effect_set_matrix4(filter->final_matrix_param, + &filter->final_matrix); obs_source_process_filter_end(filter->context, filter->effect, 0, 0); @@ -350,19 +366,19 @@ static obs_properties_t *color_correction_filter_properties(void *data) { obs_properties_t *props = obs_properties_create(); - obs_properties_add_float_slider(props, SETTING_GAMMA, - TEXT_GAMMA, -3.0, 3.0, 0.01); + obs_properties_add_float_slider(props, SETTING_GAMMA, TEXT_GAMMA, -3.0, + 3.0, 0.01); - obs_properties_add_float_slider(props, SETTING_CONTRAST, - TEXT_CONTRAST, -2.0, 2.0, 0.01); + obs_properties_add_float_slider(props, SETTING_CONTRAST, TEXT_CONTRAST, + -2.0, 2.0, 0.01); obs_properties_add_float_slider(props, SETTING_BRIGHTNESS, - TEXT_BRIGHTNESS, -1.0, 1.0, 0.01); + TEXT_BRIGHTNESS, -1.0, 1.0, 0.01); obs_properties_add_float_slider(props, SETTING_SATURATION, - TEXT_SATURATION, -1.0, 5.0, 0.01); - obs_properties_add_float_slider(props, SETTING_HUESHIFT, - TEXT_HUESHIFT, -180.0, 180.0, 0.01); - obs_properties_add_int_slider(props, SETTING_OPACITY, - TEXT_OPACITY, 0, 100, 1); + TEXT_SATURATION, -1.0, 5.0, 0.01); + obs_properties_add_float_slider(props, SETTING_HUESHIFT, TEXT_HUESHIFT, + -180.0, 180.0, 0.01); + obs_properties_add_int_slider(props, SETTING_OPACITY, TEXT_OPACITY, 0, + 100, 1); obs_properties_add_color(props, SETTING_COLOR, TEXT_COLOR); @@ -382,8 +398,7 @@ static void color_correction_filter_defaults(obs_data_t *settings) obs_data_set_default_double(settings, SETTING_GAMMA, 0.0); obs_data_set_default_double(settings, SETTING_CONTRAST, 0.0); obs_data_set_default_double(settings, SETTING_BRIGHTNESS, 0.0); - obs_data_set_default_double(settings, - SETTING_SATURATION, 0.0); + obs_data_set_default_double(settings, SETTING_SATURATION, 0.0); obs_data_set_default_double(settings, SETTING_HUESHIFT, 0.0); obs_data_set_default_double(settings, SETTING_OPACITY, 100.0); obs_data_set_default_int(settings, SETTING_COLOR, 0xFFFFFF); @@ -409,5 +424,5 @@ struct obs_source_info color_filter = { .video_render = color_correction_filter_render, .update = color_correction_filter_update, .get_properties = color_correction_filter_properties, - .get_defaults = color_correction_filter_defaults + .get_defaults = color_correction_filter_defaults, }; diff --git a/plugins/obs-filters/color-grade-filter.c b/plugins/obs-filters/color-grade-filter.c index ffe7d57..fb82ed8 100644 --- a/plugins/obs-filters/color-grade-filter.c +++ b/plugins/obs-filters/color-grade-filter.c @@ -2,20 +2,24 @@ #include #include +/* clang-format off */ + #define SETTING_IMAGE_PATH "image_path" #define SETTING_CLUT_AMOUNT "clut_amount" #define TEXT_IMAGE_PATH obs_module_text("Path") #define TEXT_AMOUNT obs_module_text("Amount") -struct lut_filter_data { - obs_source_t *context; - gs_effect_t *effect; - gs_texture_t *target; - gs_image_file_t image; +/* clang-format on */ - char *file; - float clut_amount; +struct lut_filter_data { + obs_source_t *context; + gs_effect_t *effect; + gs_texture_t *target; + gs_image_file_t image; + + char *file; + float clut_amount; }; static const char *color_grade_filter_get_name(void *unused) @@ -89,9 +93,9 @@ static obs_properties_t *color_grade_filter_properties(void *data) dstr_resize(&path, slash - path.array + 1); obs_properties_add_path(props, SETTING_IMAGE_PATH, TEXT_IMAGE_PATH, - OBS_PATH_FILE, filter_str.array, path.array); - obs_properties_add_float_slider(props, SETTING_CLUT_AMOUNT, - TEXT_AMOUNT, 0, 1, 0.01); + OBS_PATH_FILE, filter_str.array, path.array); + obs_properties_add_float_slider(props, SETTING_CLUT_AMOUNT, TEXT_AMOUNT, + 0, 1, 0.01); dstr_free(&filter_str); dstr_free(&path); @@ -100,8 +104,8 @@ static obs_properties_t *color_grade_filter_properties(void *data) return props; } -static void *color_grade_filter_create( - obs_data_t *settings, obs_source_t *context) +static void *color_grade_filter_create(obs_data_t *settings, + obs_source_t *context) { struct lut_filter_data *filter = bzalloc(sizeof(struct lut_filter_data)); @@ -136,7 +140,7 @@ static void color_grade_filter_render(void *data, gs_effect_t *effect) } if (!obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING)) + OBS_ALLOW_DIRECT_RENDERING)) return; param = gs_effect_get_param_by_name(filter->effect, "clut"); @@ -151,14 +155,14 @@ static void color_grade_filter_render(void *data, gs_effect_t *effect) } struct obs_source_info color_grade_filter = { - .id = "clut_filter", - .type = OBS_SOURCE_TYPE_FILTER, - .output_flags = OBS_SOURCE_VIDEO, - .get_name = color_grade_filter_get_name, - .create = color_grade_filter_create, - .destroy = color_grade_filter_destroy, - .update = color_grade_filter_update, - .get_defaults = color_grade_filter_defaults, - .get_properties = color_grade_filter_properties, - .video_render = color_grade_filter_render + .id = "clut_filter", + .type = OBS_SOURCE_TYPE_FILTER, + .output_flags = OBS_SOURCE_VIDEO, + .get_name = color_grade_filter_get_name, + .create = color_grade_filter_create, + .destroy = color_grade_filter_destroy, + .update = color_grade_filter_update, + .get_defaults = color_grade_filter_defaults, + .get_properties = color_grade_filter_properties, + .video_render = color_grade_filter_render, }; diff --git a/plugins/obs-filters/color-key-filter.c b/plugins/obs-filters/color-key-filter.c index 17a64f2..6dbdf2d 100644 --- a/plugins/obs-filters/color-key-filter.c +++ b/plugins/obs-filters/color-key-filter.c @@ -3,6 +3,8 @@ #include #include +/* clang-format off */ + #define SETTING_OPACITY "opacity" #define SETTING_CONTRAST "contrast" #define SETTING_BRIGHTNESS "brightness" @@ -21,28 +23,30 @@ #define TEXT_SIMILARITY obs_module_text("Similarity") #define TEXT_SMOOTHNESS obs_module_text("Smoothness") +/* clang-format on */ + struct color_key_filter_data { - obs_source_t *context; + obs_source_t *context; - gs_effect_t *effect; + gs_effect_t *effect; - gs_eparam_t *color_param; - gs_eparam_t *contrast_param; - gs_eparam_t *brightness_param; - gs_eparam_t *gamma_param; + gs_eparam_t *color_param; + gs_eparam_t *contrast_param; + gs_eparam_t *brightness_param; + gs_eparam_t *gamma_param; - gs_eparam_t *key_color_param; - gs_eparam_t *similarity_param; - gs_eparam_t *smoothness_param; + gs_eparam_t *key_color_param; + gs_eparam_t *similarity_param; + gs_eparam_t *smoothness_param; - struct vec4 color; - float contrast; - float brightness; - float gamma; + struct vec4 color; + float contrast; + float brightness; + float gamma; - struct vec4 key_color; - float similarity; - float smoothness; + struct vec4 key_color; + float similarity; + float smoothness; }; static const char *color_key_name(void *unused) @@ -51,18 +55,18 @@ static const char *color_key_name(void *unused) return obs_module_text("ColorKeyFilter"); } -static inline void color_settings_update( - struct color_key_filter_data *filter, obs_data_t *settings) +static inline void color_settings_update(struct color_key_filter_data *filter, + obs_data_t *settings) { - uint32_t opacity = (uint32_t)obs_data_get_int(settings, - SETTING_OPACITY); + uint32_t opacity = + (uint32_t)obs_data_get_int(settings, SETTING_OPACITY); uint32_t color = 0xFFFFFF | (((opacity * 255) / 100) << 24); double contrast = obs_data_get_double(settings, SETTING_CONTRAST); double brightness = obs_data_get_double(settings, SETTING_BRIGHTNESS); double gamma = obs_data_get_double(settings, SETTING_GAMMA); - contrast = (contrast < 0.0) ? - (1.0 / (-contrast + 1.0)) : (contrast + 1.0); + contrast = (contrast < 0.0) ? (1.0 / (-contrast + 1.0)) + : (contrast + 1.0); brightness *= 0.5; @@ -75,15 +79,15 @@ static inline void color_settings_update( vec4_from_rgba(&filter->color, color); } -static inline void key_settings_update( - struct color_key_filter_data *filter, obs_data_t *settings) +static inline void key_settings_update(struct color_key_filter_data *filter, + obs_data_t *settings) { int64_t similarity = obs_data_get_int(settings, SETTING_SIMILARITY); int64_t smoothness = obs_data_get_int(settings, SETTING_SMOOTHNESS); - uint32_t key_color = (uint32_t)obs_data_get_int(settings, - SETTING_KEY_COLOR); - const char *key_type = obs_data_get_string(settings, - SETTING_COLOR_TYPE); + uint32_t key_color = + (uint32_t)obs_data_get_int(settings, SETTING_KEY_COLOR); + const char *key_type = + obs_data_get_string(settings, SETTING_COLOR_TYPE); if (strcmp(key_type, "green") == 0) key_color = 0x00FF00; @@ -133,20 +137,20 @@ static void *color_key_create(obs_data_t *settings, obs_source_t *context) filter->effect = gs_effect_create_from_file(effect_path, NULL); if (filter->effect) { - filter->color_param = gs_effect_get_param_by_name( - filter->effect, "color"); - filter->contrast_param = gs_effect_get_param_by_name( - filter->effect, "contrast"); + filter->color_param = + gs_effect_get_param_by_name(filter->effect, "color"); + filter->contrast_param = + gs_effect_get_param_by_name(filter->effect, "contrast"); filter->brightness_param = gs_effect_get_param_by_name( - filter->effect, "brightness"); - filter->gamma_param = gs_effect_get_param_by_name( - filter->effect, "gamma"); + filter->effect, "brightness"); + filter->gamma_param = + gs_effect_get_param_by_name(filter->effect, "gamma"); filter->key_color_param = gs_effect_get_param_by_name( - filter->effect, "key_color"); + filter->effect, "key_color"); filter->similarity_param = gs_effect_get_param_by_name( - filter->effect, "similarity"); + filter->effect, "similarity"); filter->smoothness_param = gs_effect_get_param_by_name( - filter->effect, "smoothness"); + filter->effect, "smoothness"); } obs_leave_graphics(); @@ -167,7 +171,7 @@ static void color_key_render(void *data, gs_effect_t *effect) struct color_key_filter_data *filter = data; if (!obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING)) + OBS_ALLOW_DIRECT_RENDERING)) return; gs_effect_set_vec4(filter->color_param, &filter->color); @@ -184,13 +188,13 @@ static void color_key_render(void *data, gs_effect_t *effect) } static bool key_type_changed(obs_properties_t *props, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { const char *type = obs_data_get_string(settings, SETTING_COLOR_TYPE); bool custom = strcmp(type, "custom") == 0; obs_property_set_visible(obs_properties_get(props, SETTING_KEY_COLOR), - custom); + custom); UNUSED_PARAMETER(p); return true; @@ -200,32 +204,33 @@ static obs_properties_t *color_key_properties(void *data) { obs_properties_t *props = obs_properties_create(); - obs_property_t *p = obs_properties_add_list(props, - SETTING_COLOR_TYPE, TEXT_COLOR_TYPE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + obs_property_t *p = obs_properties_add_list(props, SETTING_COLOR_TYPE, + TEXT_COLOR_TYPE, + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, obs_module_text("Green"), "green"); obs_property_list_add_string(p, obs_module_text("Blue"), "blue"); obs_property_list_add_string(p, obs_module_text("Red"), "red"); obs_property_list_add_string(p, obs_module_text("Magenta"), "magenta"); obs_property_list_add_string(p, obs_module_text("CustomColor"), - "custom"); + "custom"); obs_property_set_modified_callback(p, key_type_changed); obs_properties_add_color(props, SETTING_KEY_COLOR, TEXT_KEY_COLOR); obs_properties_add_int_slider(props, SETTING_SIMILARITY, - TEXT_SIMILARITY, 1, 1000, 1); + TEXT_SIMILARITY, 1, 1000, 1); obs_properties_add_int_slider(props, SETTING_SMOOTHNESS, - TEXT_SMOOTHNESS, 1, 1000, 1); + TEXT_SMOOTHNESS, 1, 1000, 1); - obs_properties_add_int_slider(props, SETTING_OPACITY, TEXT_OPACITY, - 0, 100, 1); - obs_properties_add_float_slider(props, SETTING_CONTRAST, - TEXT_CONTRAST, -1.0, 1.0, 0.01); + obs_properties_add_int_slider(props, SETTING_OPACITY, TEXT_OPACITY, 0, + 100, 1); + obs_properties_add_float_slider(props, SETTING_CONTRAST, TEXT_CONTRAST, + -1.0, 1.0, 0.01); obs_properties_add_float_slider(props, SETTING_BRIGHTNESS, - TEXT_BRIGHTNESS, -1.0, 1.0, 0.01); - obs_properties_add_float_slider(props, SETTING_GAMMA, - TEXT_GAMMA, -1.0, 1.0, 0.01); + TEXT_BRIGHTNESS, -1.0, 1.0, 0.01); + obs_properties_add_float_slider(props, SETTING_GAMMA, TEXT_GAMMA, -1.0, + 1.0, 0.01); UNUSED_PARAMETER(data); return props; @@ -244,14 +249,14 @@ static void color_key_defaults(obs_data_t *settings) } struct obs_source_info color_key_filter = { - .id = "color_key_filter", - .type = OBS_SOURCE_TYPE_FILTER, - .output_flags = OBS_SOURCE_VIDEO, - .get_name = color_key_name, - .create = color_key_create, - .destroy = color_key_destroy, - .video_render = color_key_render, - .update = color_key_update, - .get_properties = color_key_properties, - .get_defaults = color_key_defaults + .id = "color_key_filter", + .type = OBS_SOURCE_TYPE_FILTER, + .output_flags = OBS_SOURCE_VIDEO, + .get_name = color_key_name, + .create = color_key_create, + .destroy = color_key_destroy, + .video_render = color_key_render, + .update = color_key_update, + .get_properties = color_key_properties, + .get_defaults = color_key_defaults, }; diff --git a/plugins/obs-filters/compressor-filter.c b/plugins/obs-filters/compressor-filter.c index 244a9bc..734994a 100644 --- a/plugins/obs-filters/compressor-filter.c +++ b/plugins/obs-filters/compressor-filter.c @@ -10,21 +10,23 @@ /* -------------------------------------------------------- */ -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[compressor: '%s'] " format, \ - obs_source_get_name(cd->context), ##__VA_ARGS__) + obs_source_get_name(cd->context), ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) #ifdef _DEBUG -#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) #else #define debug(format, ...) #endif /* -------------------------------------------------------- */ +/* clang-format off */ + #define S_RATIO "ratio" #define S_THRESHOLD "threshold" #define S_ATTACK_TIME "attack_time" @@ -54,6 +56,8 @@ #define MS_IN_S 1000 #define MS_IN_S_F ((float)MS_IN_S) +/* clang-format on */ + /* -------------------------------------------------------- */ struct compressor_data { @@ -93,7 +97,7 @@ static inline obs_source_t *get_sidechain(struct compressor_data *cd) } static inline void get_sidechain_data(struct compressor_data *cd, - const uint32_t num_samples) + const uint32_t num_samples) { size_t data_size = cd->envelope_buf_len * sizeof(float); if (!data_size) @@ -110,7 +114,7 @@ static inline void get_sidechain_data(struct compressor_data *cd, for (size_t i = 0; i < cd->num_channels; i++) circlebuf_pop_front(&cd->sidechain_data[i], - cd->sidechain_buf[i], data_size); + cd->sidechain_buf[i], data_size); pthread_mutex_unlock(&cd->sidechain_mutex); return; @@ -126,8 +130,8 @@ static void resize_env_buffer(struct compressor_data *cd, size_t len) cd->envelope_buf = brealloc(cd->envelope_buf, len * sizeof(float)); for (size_t i = 0; i < cd->num_channels; i++) - cd->sidechain_buf[i] = brealloc(cd->sidechain_buf[i], - len * sizeof(float)); + cd->sidechain_buf[i] = + brealloc(cd->sidechain_buf[i], len * sizeof(float)); } static inline float gain_coefficient(uint32_t sample_rate, float time) @@ -142,7 +146,7 @@ static const char *compressor_name(void *unused) } static void sidechain_capture(void *param, obs_source_t *source, - const struct audio_data *audio_data, bool muted) + const struct audio_data *audio_data, bool muted) { struct compressor_data *cd = param; @@ -161,20 +165,21 @@ static void sidechain_capture(void *param, obs_source_t *source, if (cd->sidechain_data[0].size > expected_size * 2) { for (size_t i = 0; i < cd->num_channels; i++) { circlebuf_pop_front(&cd->sidechain_data[i], NULL, - expected_size); + expected_size); } } if (muted) { for (size_t i = 0; i < cd->num_channels; i++) { circlebuf_push_back_zero(&cd->sidechain_data[i], - audio_data->frames * sizeof(float)); + audio_data->frames * + sizeof(float)); } } else { for (size_t i = 0; i < cd->num_channels; i++) { circlebuf_push_back(&cd->sidechain_data[i], - audio_data->data[i], - audio_data->frames * sizeof(float)); + audio_data->data[i], + audio_data->frames * sizeof(float)); } } @@ -188,30 +193,27 @@ static void compressor_update(void *data, obs_data_t *s) const uint32_t sample_rate = audio_output_get_sample_rate(obs_get_audio()); - const size_t num_channels = - audio_output_get_channels(obs_get_audio()); - const float attack_time_ms = - (float)obs_data_get_int(s, S_ATTACK_TIME); + const size_t num_channels = audio_output_get_channels(obs_get_audio()); + const float attack_time_ms = (float)obs_data_get_int(s, S_ATTACK_TIME); const float release_time_ms = (float)obs_data_get_int(s, S_RELEASE_TIME); const float output_gain_db = (float)obs_data_get_double(s, S_OUTPUT_GAIN); - const char *sidechain_name = - obs_data_get_string(s, S_SIDECHAIN_SOURCE); + const char *sidechain_name = obs_data_get_string(s, S_SIDECHAIN_SOURCE); cd->ratio = (float)obs_data_get_double(s, S_RATIO); cd->threshold = (float)obs_data_get_double(s, S_THRESHOLD); - cd->attack_gain = gain_coefficient(sample_rate, - attack_time_ms / MS_IN_S_F); - cd->release_gain = gain_coefficient(sample_rate, - release_time_ms / MS_IN_S_F); + cd->attack_gain = + gain_coefficient(sample_rate, attack_time_ms / MS_IN_S_F); + cd->release_gain = + gain_coefficient(sample_rate, release_time_ms / MS_IN_S_F); cd->output_gain = db_to_mul(output_gain_db); cd->num_channels = num_channels; cd->sample_rate = sample_rate; cd->slope = 1.0f - (1.0f / cd->ratio); - bool valid_sidechain = - *sidechain_name && strcmp(sidechain_name, "none") != 0; + bool valid_sidechain = *sidechain_name && + strcmp(sidechain_name, "none") != 0; obs_weak_source_t *old_weak_sidechain = NULL; pthread_mutex_lock(&cd->sidechain_update_mutex); @@ -246,8 +248,8 @@ static void compressor_update(void *data, obs_data_t *s) obs_weak_source_get_source(old_weak_sidechain); if (old_sidechain) { - obs_source_remove_audio_capture_callback(old_sidechain, - sidechain_capture, cd); + obs_source_remove_audio_capture_callback( + old_sidechain, sidechain_capture, cd); obs_source_release(old_sidechain); } @@ -288,8 +290,8 @@ static void compressor_destroy(void *data) if (cd->weak_sidechain) { obs_source_t *sidechain = get_sidechain(cd); if (sidechain) { - obs_source_remove_audio_capture_callback(sidechain, - sidechain_capture, cd); + obs_source_remove_audio_capture_callback( + sidechain, sidechain_capture, cd); obs_source_release(sidechain); } @@ -308,8 +310,8 @@ static void compressor_destroy(void *data) bfree(cd); } -static void analyze_envelope(struct compressor_data *cd, - float **samples, const uint32_t num_samples) +static void analyze_envelope(struct compressor_data *cd, float **samples, + const uint32_t num_samples) { if (cd->envelope_buf_len < num_samples) { resize_env_buffer(cd, num_samples); @@ -339,7 +341,7 @@ static void analyze_envelope(struct compressor_data *cd, } static void analyze_sidechain(struct compressor_data *cd, - const uint32_t num_samples) + const uint32_t num_samples) { if (cd->envelope_buf_len < num_samples) { resize_env_buffer(cd, num_samples); @@ -359,7 +361,7 @@ static void analyze_sidechain(struct compressor_data *cd, float *envelope_buf = cd->envelope_buf; float env = cd->envelope; for (uint32_t i = 0; i < num_samples; ++i) { - const float env_in = fabsf(sidechain_buf[chan][i]); + const float env_in = fabsf(sidechain_buf[chan][i]); if (env < env_in) { env = env_in + attack_gain * (env - env_in); @@ -373,7 +375,7 @@ static void analyze_sidechain(struct compressor_data *cd, } static inline void process_compression(const struct compressor_data *cd, - float **samples, uint32_t num_samples) + float **samples, uint32_t num_samples) { for (size_t i = 0; i < num_samples; ++i) { const float env_db = mul_to_db(cd->envelope_buf[i]); @@ -407,10 +409,12 @@ static void compressor_tick(void *data, float seconds) pthread_mutex_unlock(&cd->sidechain_update_mutex); if (new_name) { - obs_source_t *sidechain = new_name && *new_name ? - obs_get_source_by_name(new_name) : NULL; - obs_weak_source_t *weak_sidechain = sidechain ? - obs_source_get_weak_source(sidechain) : NULL; + obs_source_t *sidechain = + new_name && *new_name ? obs_get_source_by_name(new_name) + : NULL; + obs_weak_source_t *weak_sidechain = + sidechain ? obs_source_get_weak_source(sidechain) + : NULL; pthread_mutex_lock(&cd->sidechain_update_mutex); @@ -423,8 +427,8 @@ static void compressor_tick(void *data, float seconds) pthread_mutex_unlock(&cd->sidechain_update_mutex); if (sidechain) { - obs_source_add_audio_capture_callback(sidechain, - sidechain_capture, cd); + obs_source_add_audio_capture_callback( + sidechain, sidechain_capture, cd); obs_weak_source_release(weak_sidechain); obs_source_release(sidechain); @@ -436,8 +440,8 @@ static void compressor_tick(void *data, float seconds) UNUSED_PARAMETER(seconds); } -static struct obs_audio_data *compressor_filter_audio(void *data, - struct obs_audio_data *audio) +static struct obs_audio_data * +compressor_filter_audio(void *data, struct obs_audio_data *audio) { struct compressor_data *cd = data; @@ -445,7 +449,7 @@ static struct obs_audio_data *compressor_filter_audio(void *data, if (num_samples == 0) return audio; - float **samples = (float**)audio->data; + float **samples = (float **)audio->data; pthread_mutex_lock(&cd->sidechain_update_mutex); obs_weak_source_t *weak_sidechain = cd->weak_sidechain; @@ -495,24 +499,35 @@ static obs_properties_t *compressor_properties(void *data) struct compressor_data *cd = data; obs_properties_t *props = obs_properties_create(); obs_source_t *parent = NULL; + obs_property_t *p; if (cd) parent = obs_filter_get_parent(cd->context); - obs_properties_add_float_slider(props, S_RATIO, - TEXT_RATIO, MIN_RATIO, MAX_RATIO, 0.5); - obs_properties_add_float_slider(props, S_THRESHOLD, - TEXT_THRESHOLD, MIN_THRESHOLD_DB, MAX_THRESHOLD_DB, 0.1); - obs_properties_add_int_slider(props, S_ATTACK_TIME, - TEXT_ATTACK_TIME, MIN_ATK_RLS_MS, MAX_ATK_MS, 1); - obs_properties_add_int_slider(props, S_RELEASE_TIME, - TEXT_RELEASE_TIME, MIN_ATK_RLS_MS, MAX_RLS_MS, 1); - obs_properties_add_float_slider(props, S_OUTPUT_GAIN, - TEXT_OUTPUT_GAIN, MIN_OUTPUT_GAIN_DB, MAX_OUTPUT_GAIN_DB, 0.1); + p = obs_properties_add_float_slider(props, S_RATIO, TEXT_RATIO, + MIN_RATIO, MAX_RATIO, 0.5); + obs_property_float_set_suffix(p, ":1"); + p = obs_properties_add_float_slider(props, S_THRESHOLD, TEXT_THRESHOLD, + MIN_THRESHOLD_DB, MAX_THRESHOLD_DB, + 0.1); + obs_property_float_set_suffix(p, " dB"); + p = obs_properties_add_int_slider(props, S_ATTACK_TIME, + TEXT_ATTACK_TIME, MIN_ATK_RLS_MS, + MAX_ATK_MS, 1); + obs_property_int_set_suffix(p, " ms"); + p = obs_properties_add_int_slider(props, S_RELEASE_TIME, + TEXT_RELEASE_TIME, MIN_ATK_RLS_MS, + MAX_RLS_MS, 1); + obs_property_int_set_suffix(p, " ms"); + p = obs_properties_add_float_slider(props, S_OUTPUT_GAIN, + TEXT_OUTPUT_GAIN, + MIN_OUTPUT_GAIN_DB, + MAX_OUTPUT_GAIN_DB, 0.1); + obs_property_float_set_suffix(p, " dB"); - obs_property_t *sources = obs_properties_add_list(props, - S_SIDECHAIN_SOURCE, TEXT_SIDECHAIN_SOURCE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + obs_property_t *sources = obs_properties_add_list( + props, S_SIDECHAIN_SOURCE, TEXT_SIDECHAIN_SOURCE, + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(sources, obs_module_text("None"), "none"); diff --git a/plugins/obs-filters/crop-filter.c b/plugins/obs-filters/crop-filter.c index 09839ec..2c05cf1 100644 --- a/plugins/obs-filters/crop-filter.c +++ b/plugins/obs-filters/crop-filter.c @@ -2,24 +2,24 @@ #include struct crop_filter_data { - obs_source_t *context; + obs_source_t *context; - gs_effect_t *effect; - gs_eparam_t *param_mul; - gs_eparam_t *param_add; + gs_effect_t *effect; + gs_eparam_t *param_mul; + gs_eparam_t *param_add; - int left; - int right; - int top; - int bottom; - int abs_cx; - int abs_cy; - int width; - int height; - bool absolute; + int left; + int right; + int top; + int bottom; + int abs_cx; + int abs_cy; + int width; + int height; + bool absolute; - struct vec2 mul_val; - struct vec2 add_val; + struct vec2 mul_val; + struct vec2 add_val; }; static const char *crop_filter_get_name(void *unused) @@ -46,10 +46,10 @@ static void *crop_filter_create(obs_data_t *settings, obs_source_t *context) return NULL; } - filter->param_mul = gs_effect_get_param_by_name(filter->effect, - "mul_val"); - filter->param_add = gs_effect_get_param_by_name(filter->effect, - "add_val"); + filter->param_mul = + gs_effect_get_param_by_name(filter->effect, "mul_val"); + filter->param_add = + gs_effect_get_param_by_name(filter->effect, "add_val"); obs_source_update(context, settings); return filter; @@ -80,14 +80,16 @@ static void crop_filter_update(void *data, obs_data_t *settings) } static bool relative_clicked(obs_properties_t *props, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { bool relative = obs_data_get_bool(settings, "relative"); obs_property_set_description(obs_properties_get(props, "left"), - relative ? obs_module_text("Crop.Left") : "X"); + relative ? obs_module_text("Crop.Left") + : "X"); obs_property_set_description(obs_properties_get(props, "top"), - relative ? obs_module_text("Crop.Top") : "Y"); + relative ? obs_module_text("Crop.Top") + : "Y"); obs_property_set_visible(obs_properties_get(props, "right"), relative); obs_property_set_visible(obs_properties_get(props, "bottom"), relative); @@ -102,23 +104,23 @@ static obs_properties_t *crop_filter_properties(void *data) { obs_properties_t *props = obs_properties_create(); - obs_property_t *p = obs_properties_add_bool(props, "relative", - obs_module_text("Crop.Relative")); + obs_property_t *p = obs_properties_add_bool( + props, "relative", obs_module_text("Crop.Relative")); obs_property_set_modified_callback(p, relative_clicked); obs_properties_add_int(props, "left", obs_module_text("Crop.Left"), - -8192, 8192, 1); - obs_properties_add_int(props, "top", obs_module_text("Crop.Top"), - -8192, 8192, 1); + -8192, 8192, 1); + obs_properties_add_int(props, "top", obs_module_text("Crop.Top"), -8192, + 8192, 1); obs_properties_add_int(props, "right", obs_module_text("Crop.Right"), - -8192, 8192, 1); + -8192, 8192, 1); obs_properties_add_int(props, "bottom", obs_module_text("Crop.Bottom"), - -8192, 8192, 1); - obs_properties_add_int(props, "cx", obs_module_text("Crop.Width"), - 0, 8192, 1); - obs_properties_add_int(props, "cy", obs_module_text("Crop.Height"), - 0, 8192, 1); + -8192, 8192, 1); + obs_properties_add_int(props, "cx", obs_module_text("Crop.Width"), 0, + 8192, 1); + obs_properties_add_int(props, "cy", obs_module_text("Crop.Height"), 0, + 8192, 1); UNUSED_PARAMETER(data); return props; @@ -130,7 +132,7 @@ static void crop_filter_defaults(obs_data_t *settings) } static void calc_crop_dimensions(struct crop_filter_data *filter, - struct vec2 *mul_val, struct vec2 *add_val) + struct vec2 *mul_val, struct vec2 *add_val) { obs_source_t *target = obs_filter_get_target(filter->context); uint32_t width; @@ -146,15 +148,17 @@ static void calc_crop_dimensions(struct crop_filter_data *filter, } if (filter->absolute) { - filter->width = filter->abs_cx; + filter->width = filter->abs_cx; filter->height = filter->abs_cy; } else { - filter->width = (int)width - filter->left - filter->right; + filter->width = (int)width - filter->left - filter->right; filter->height = (int)height - filter->top - filter->bottom; } - if (filter->width < 1) filter->width = 1; - if (filter->height < 1) filter->height = 1; + if (filter->width < 1) + filter->width = 1; + if (filter->height < 1) + filter->height = 1; if (width && filter->width) { mul_val->x = (float)filter->width / (float)width; @@ -183,14 +187,14 @@ static void crop_filter_render(void *data, gs_effect_t *effect) struct crop_filter_data *filter = data; if (!obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_NO_DIRECT_RENDERING)) + OBS_NO_DIRECT_RENDERING)) return; gs_effect_set_vec2(filter->param_mul, &filter->mul_val); gs_effect_set_vec2(filter->param_add, &filter->add_val); obs_source_process_filter_end(filter->context, filter->effect, - filter->width, filter->height); + filter->width, filter->height); UNUSED_PARAMETER(effect); } @@ -208,17 +212,17 @@ static uint32_t crop_filter_height(void *data) } struct obs_source_info crop_filter = { - .id = "crop_filter", - .type = OBS_SOURCE_TYPE_FILTER, - .output_flags = OBS_SOURCE_VIDEO, - .get_name = crop_filter_get_name, - .create = crop_filter_create, - .destroy = crop_filter_destroy, - .update = crop_filter_update, - .get_properties = crop_filter_properties, - .get_defaults = crop_filter_defaults, - .video_tick = crop_filter_tick, - .video_render = crop_filter_render, - .get_width = crop_filter_width, - .get_height = crop_filter_height + .id = "crop_filter", + .type = OBS_SOURCE_TYPE_FILTER, + .output_flags = OBS_SOURCE_VIDEO, + .get_name = crop_filter_get_name, + .create = crop_filter_create, + .destroy = crop_filter_destroy, + .update = crop_filter_update, + .get_properties = crop_filter_properties, + .get_defaults = crop_filter_defaults, + .video_tick = crop_filter_tick, + .video_render = crop_filter_render, + .get_width = crop_filter_width, + .get_height = crop_filter_height, }; diff --git a/plugins/obs-filters/data/locale/bg-BG.ini b/plugins/obs-filters/data/locale/bg-BG.ini index c65da8a..5d6dbac 100644 --- a/plugins/obs-filters/data/locale/bg-BG.ini +++ b/plugins/obs-filters/data/locale/bg-BG.ini @@ -1,4 +1,36 @@ +ColorFilter="Корекция на цвета" +AsyncDelayFilter="Забавяне на видеото (асинхронно)" +InvertPolarity="Преобръщане на полярността" +DelayMs="Забавяне (в милисекунди)" +Type="Вид" +Path="Път" +Color="Цвят" +Opacity="Прозиране" +Contrast="Контраст" +Brightness="Яркост" +Gamma="Гама" +BrowsePath.Images="Всички файлове с изображения" +BrowsePath.AllFiles="Всички файлове" +KeyColor="Цвят на ключа" +Similarity="Подобност (1-1000)" +Smoothness="Гладкост (1-1000)" +ScrollFilter.SpeedX="Водоравна бързина" +ScrollFilter.SpeedY="Отвесна бързина" +CustomColor="Подбиране на цвят" +Resolution="Разд. способност" +ScaleFiltering.Point="Точково" +ScaleFiltering.Bilinear="Двулинейно" +ScaleFiltering.Bicubic="Бикубично" +ScaleFiltering.Lanczos="Ланцош" +ScaleFiltering.Area="Област" +Saturation="Наситеност" +Compressor="Компресор" +Compressor.Ratio="Съотношение (X:1)" Limiter="Ограничител" Limiter.Threshold="Праг на отсичане (dB)" Limiter.ReleaseTime="Време за отговор (мс)" +Expander.Ratio="Съотношение (X:1)" +Expander.Presets="Образци" +Expander.Presets.Expander="Експандър" +Expander.Presets.Gate="Порта" diff --git a/plugins/obs-filters/data/locale/de-DE.ini b/plugins/obs-filters/data/locale/de-DE.ini index 449e752..f8a5070 100644 --- a/plugins/obs-filters/data/locale/de-DE.ini +++ b/plugins/obs-filters/data/locale/de-DE.ini @@ -1,6 +1,6 @@ ColorFilter="Farbkorrektur" ColorGradeFilter="LUT anwenden" -MaskFilter="Bildmaske/-Vermischung" +MaskFilter="Bildmaske/‐Vermischung" AsyncDelayFilter="Videoverzögerung (Asynchron)" CropFilter="Zuschneiden/Pad" ScrollFilter="Bewegung" @@ -29,11 +29,11 @@ Brightness="Helligkeit" Gamma="Gamma" BrowsePath.Images="Alle Bilddateien" BrowsePath.AllFiles="Alle Dateien" -KeyColorType="Key-Farbtyp" -KeyColor="Key-Farbe" -Similarity="Ähnlichkeit (1 — 1000)" -Smoothness="Glätte (1 — 1000)" -ColorSpillReduction="Key-Farbe-Spill-Reduzierung (1 — 1000)" +KeyColorType="Key‐Farbtyp" +KeyColor="Key‐Farbe" +Similarity="Ähnlichkeit (1–1000)" +Smoothness="Glätte (1–1000)" +ColorSpillReduction="Key‐Farbe‐Spill‐Reduzierung (1–1000)" Crop.Left="Links" Crop.Right="Rechts" Crop.Top="Oben" @@ -50,15 +50,15 @@ Red="Rot" Green="Grün" Blue="Blau" Magenta="Magenta" -NoiseGate.OpenThreshold="Öffnen-Schwellenwert (dB)" -NoiseGate.CloseThreshold="Schließen-Schwellenwert (dB)" -NoiseGate.AttackTime="Attack-Zeit (Millisekunden)" -NoiseGate.HoldTime="Hold-Zeit (Millisekunden)" -NoiseGate.ReleaseTime="Release-Zeit (Millisekunden)" +NoiseGate.OpenThreshold="Öffnungs‐Schwellwert (dB)" +NoiseGate.CloseThreshold="Schließungs‐Schwellwert (dB)" +NoiseGate.AttackTime="Attack‐Zeit (Millisekunden)" +NoiseGate.HoldTime="Hold‐Zeit (Millisekunden)" +NoiseGate.ReleaseTime="Release‐Zeit (Millisekunden)" Gain.GainDB="Gain (dB)" StretchImage="Bild strecken (Bildseitenverhältnis verwerfen)" Resolution="Auflösung" -Base.Canvas="Basis-(Leinwand-)Auflösung" +Base.Canvas="Basis‐(Leinwand‐)Auflösung" None="Keine" ScaleFiltering="Skalierungsfilterung" ScaleFiltering.Point="Point" @@ -72,30 +72,30 @@ HueShift="Farbtonverschiebung" Amount="Betrag" Compressor="Kompressor" Compressor.Ratio="Verhältnis (X:1)" -Compressor.Threshold="Schwellenwert (dB)" -Compressor.AttackTime="Angriff (ms)" -Compressor.ReleaseTime="Abfallzeit (ms)" +Compressor.Threshold="Schwellwert (dB)" +Compressor.AttackTime="Attack (ms)" +Compressor.ReleaseTime="Release (ms)" Compressor.OutputGain="Ausgangspegel (dB)" -Compressor.SidechainSource="Sidechain-/Ducking-Quelle" +Compressor.SidechainSource="Sidechain‐/Ducking‐Quelle" Limiter="Begrenzer" -Limiter.Threshold="Schwellenwert (dB)" -Limiter.ReleaseTime="Abfallzeit (ms)" +Limiter.Threshold="Schwellwert (dB)" +Limiter.ReleaseTime="Release (ms)" Expander="Expander" Expander.Ratio="Verhältnis (X:1)" -Expander.Threshold="Schwellenwert (dB)" -Expander.AttackTime="Angriff (ms)" -Expander.ReleaseTime="Abfallzeit (ms)" +Expander.Threshold="Schwellwert (dB)" +Expander.AttackTime="Attack (ms)" +Expander.ReleaseTime="Release (ms)" Expander.OutputGain="Ausgangspegel (dB)" Expander.Detector="Erkennung" Expander.RMS="RMS" -Expander.Peak="Spitze" +Expander.Peak="Peak" Expander.None="Keine" Expander.Presets="Voreinstellungen" Expander.Presets.Expander="Expander" Expander.Presets.Gate="Gate" -LumaKeyFilter="Luma-Key" +LumaKeyFilter="Luma Key" Luma.LumaMax="Max. Luma" Luma.LumaMin="Min. Luma" -Luma.LumaMaxSmooth="Max. Luma-Glätte" -Luma.LumaMinSmooth="Min. Luma-Glätte" +Luma.LumaMaxSmooth="Max. Luma‐Glätte" +Luma.LumaMinSmooth="Min. Luma‐Glätte" diff --git a/plugins/obs-filters/data/locale/en-US.ini b/plugins/obs-filters/data/locale/en-US.ini index cf49d70..21d7588 100644 --- a/plugins/obs-filters/data/locale/en-US.ini +++ b/plugins/obs-filters/data/locale/en-US.ini @@ -14,7 +14,7 @@ NoiseGate="Noise Gate" NoiseSuppress="Noise Suppression" InvertPolarity="Invert Polarity" Gain="Gain" -DelayMs="Delay (milliseconds)" +DelayMs="Delay" Type="Type" MaskBlendType.MaskColor="Alpha Mask (Color Channel)" MaskBlendType.MaskAlpha="Alpha Mask (Alpha Channel)" @@ -50,12 +50,12 @@ Red="Red" Green="Green" Blue="Blue" Magenta="Magenta" -NoiseGate.OpenThreshold="Open Threshold (dB)" -NoiseGate.CloseThreshold="Close Threshold (dB)" -NoiseGate.AttackTime="Attack Time (milliseconds)" -NoiseGate.HoldTime="Hold Time (milliseconds)" -NoiseGate.ReleaseTime="Release Time (milliseconds)" -Gain.GainDB="Gain (dB)" +NoiseGate.OpenThreshold="Open Threshold" +NoiseGate.CloseThreshold="Close Threshold" +NoiseGate.AttackTime="Attack Time" +NoiseGate.HoldTime="Hold Time" +NoiseGate.ReleaseTime="Release Time" +Gain.GainDB="Gain" StretchImage="Stretch Image (discard image aspect ratio)" Resolution="Resolution" Base.Canvas="Base (Canvas) Resolution" @@ -66,26 +66,26 @@ ScaleFiltering.Bilinear="Bilinear" ScaleFiltering.Bicubic="Bicubic" ScaleFiltering.Lanczos="Lanczos" ScaleFiltering.Area="Area" -NoiseSuppress.SuppressLevel="Suppression Level (dB)" +NoiseSuppress.SuppressLevel="Suppression Level" Saturation="Saturation" HueShift="Hue Shift" Amount="Amount" Compressor="Compressor" -Compressor.Ratio="Ratio (X:1)" -Compressor.Threshold="Threshold (dB)" -Compressor.AttackTime="Attack (ms)" -Compressor.ReleaseTime="Release (ms)" -Compressor.OutputGain="Output Gain (dB)" +Compressor.Ratio="Ratio" +Compressor.Threshold="Threshold" +Compressor.AttackTime="Attack" +Compressor.ReleaseTime="Release" +Compressor.OutputGain="Output Gain" Compressor.SidechainSource="Sidechain/Ducking Source" Limiter="Limiter" -Limiter.Threshold="Threshold (dB)" -Limiter.ReleaseTime="Release (ms)" +Limiter.Threshold="Threshold" +Limiter.ReleaseTime="Release" Expander="Expander" -Expander.Ratio="Ratio (X:1)" -Expander.Threshold="Threshold (dB)" -Expander.AttackTime="Attack (ms)" -Expander.ReleaseTime="Release (ms)" -Expander.OutputGain="Output Gain (dB)" +Expander.Ratio="Ratio" +Expander.Threshold="Threshold" +Expander.AttackTime="Attack" +Expander.ReleaseTime="Release" +Expander.OutputGain="Output Gain" Expander.Detector="Detection" Expander.RMS="RMS" Expander.Peak="Peak" diff --git a/plugins/obs-filters/data/locale/gl-ES.ini b/plugins/obs-filters/data/locale/gl-ES.ini index de5dd7b..5929039 100644 --- a/plugins/obs-filters/data/locale/gl-ES.ini +++ b/plugins/obs-filters/data/locale/gl-ES.ini @@ -1,12 +1,27 @@ ColorFilter="Corrección da cor" +ColorGradeFilter="Aplicar LUT" MaskFilter="Máscara/mestura de imaxes" AsyncDelayFilter="Atraso do vídeo (asíncrono)" +CropFilter="Recorte/Recheo" ScrollFilter="Desprazamento" +ChromaKeyFilter="Chroma Key" +ColorKeyFilter="Clave de cor" +SharpnessFilter="Nídio" +ScaleFilter="Escala/relación de aspecto" +GPUDelayFilter="Demora na xeración" +UndistortCenter="Non distorsionar o centro da imaxe cando se escala dende ultralarga" +NoiseGate="Porta de ruído" +NoiseSuppress="Supresión do ruído" +InvertPolarity="Inverter a polaridade" +Gain="Ganancia" DelayMs="Atraso (milisegundos)" Type="Tipo" MaskBlendType.MaskColor="Máscara alfa (canle de cor)" MaskBlendType.MaskAlpha="Máscara alfa (canle alfa)" -Path="Camiño" +MaskBlendType.BlendMultiply="Mestura (multiplicar)" +MaskBlendType.BlendAddition="Mestura (adición)" +MaskBlendType.BlendSubtraction="Mestura (substracción)" +Path="Ruta" Color="Cor" Opacity="Opacidade" Contrast="Contraste" @@ -14,17 +29,73 @@ Brightness="Brillo" Gamma="Gama" BrowsePath.Images="Todo os ficheiros de imaxe" BrowsePath.AllFiles="Todos os ficheiros" +KeyColorType="Tipo de cor da clave" +KeyColor="Cor da clave" Similarity="Similitude (1-1000)" -Crop.Left="Á esquerda" -Crop.Right="Á dereita" +Smoothness="Suavidade (1-1000)" +ColorSpillReduction="Redución da vertedura da cor clave (1-1000)" +Crop.Left="Esquerda" +Crop.Right="Dereita" Crop.Top="Arriba" Crop.Bottom="Abaixo" -Crop.Width="Largura" -Crop.Height="Altura" +Crop.Width="Largo" +Crop.Height="Alto" Crop.Relative="Relativo" -CustomColor="Personalizar cor" +ScrollFilter.SpeedX="Velocidade horizontal" +ScrollFilter.SpeedY="Velocidade vertical" +ScrollFilter.LimitWidth="Limitar o largo" +ScrollFilter.LimitHeight="Limitar o alto" +CustomColor="Cor personalizada" Red="Vermello" Green="Verde" Blue="Azul" Magenta="Maxenta" +NoiseGate.OpenThreshold="Limiar de apertura (dB)" +NoiseGate.CloseThreshold="Limiar de peche (dB)" +NoiseGate.AttackTime="Tempo de ataque (milisegundos)" +NoiseGate.HoldTime="Tempo de espera (milisegundos)" +NoiseGate.ReleaseTime="Tempo de liberación (milisegundos)" +Gain.GainDB="Ganancia (dB)" +StretchImage="Estricar a imaxe (desbotar a relación de aspecto da imaxe)" +Resolution="Resolución" +Base.Canvas="Resolución da base (lenzo)" +None="Ningunha" +ScaleFiltering="Filtrado da escala" +ScaleFiltering.Point="Punto" +ScaleFiltering.Bilinear="Bilineal" +ScaleFiltering.Bicubic="Bicúbico" +ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Área" +NoiseSuppress.SuppressLevel="Nivel de supresión (dB)" +Saturation="Saturación" +HueShift="Cambio de tonalidade" +Amount="Cantidade" +Compressor="Compresor" +Compressor.Ratio="Razón (X:1)" +Compressor.Threshold="Limiar (dB)" +Compressor.AttackTime="Ataque (ms)" +Compressor.ReleaseTime="Liberación (ms)" +Compressor.OutputGain="Ganancia da saída (dB)" +Compressor.SidechainSource="Fonte de atenuación/redución" +Limiter="Limitador" +Limiter.Threshold="Limiar (dB)" +Limiter.ReleaseTime="Liberación (ms)" +Expander="Expansor" +Expander.Ratio="Razón (X:1)" +Expander.Threshold="Limiar (dB)" +Expander.AttackTime="Ataque (ms)" +Expander.ReleaseTime="Liberación (ms)" +Expander.OutputGain="Ganancia da saída (dB)" +Expander.Detector="Detección" +Expander.RMS="RMS" +Expander.Peak="Pico" +Expander.None="Ningún" +Expander.Presets="Valores predefinidos" +Expander.Presets.Expander="Expansor" +Expander.Presets.Gate="Porta" +LumaKeyFilter="Clave Luma" +Luma.LumaMax="Máximo Luma" +Luma.LumaMin="Mínimo Luma" +Luma.LumaMaxSmooth="Suavizado máximo Luma" +Luma.LumaMinSmooth="Suavizado mínimo Luma" diff --git a/plugins/obs-filters/data/locale/ja-JP.ini b/plugins/obs-filters/data/locale/ja-JP.ini index ae19476..1418c76 100644 --- a/plugins/obs-filters/data/locale/ja-JP.ini +++ b/plugins/obs-filters/data/locale/ja-JP.ini @@ -96,6 +96,6 @@ Expander.Presets.Gate="ゲート" LumaKeyFilter="ルマキー" Luma.LumaMax="最大輝度" Luma.LumaMin="最小輝度" -Luma.LumaMaxSmooth="ルマ最大スムーズ" -Luma.LumaMinSmooth="ルマ最小スムーズ" +Luma.LumaMaxSmooth="最大輝度グラデーション" +Luma.LumaMinSmooth="最小輝度グラデーション" diff --git a/plugins/obs-filters/data/locale/ka-GE.ini b/plugins/obs-filters/data/locale/ka-GE.ini index b8a465c..d179d77 100644 --- a/plugins/obs-filters/data/locale/ka-GE.ini +++ b/plugins/obs-filters/data/locale/ka-GE.ini @@ -65,7 +65,7 @@ ScaleFiltering.Point="წერტილოვანი" ScaleFiltering.Bilinear="ორხაზოვანი" ScaleFiltering.Bicubic="ბიკუბური" ScaleFiltering.Lanczos="Lanczos" -ScaleFiltering.Area="სივრცე" +ScaleFiltering.Area="სივრცითი" NoiseSuppress.SuppressLevel="დახშობის ხარისხი (dB)" Saturation="გაჯერებულობა" HueShift="შეფერილობის შეცვლა" diff --git a/plugins/obs-filters/data/locale/nl-NL.ini b/plugins/obs-filters/data/locale/nl-NL.ini index 4773aad..9649c0a 100644 --- a/plugins/obs-filters/data/locale/nl-NL.ini +++ b/plugins/obs-filters/data/locale/nl-NL.ini @@ -93,4 +93,9 @@ Expander.None="Geen" Expander.Presets="Vooraf ingestelde instellingen" Expander.Presets.Expander="Uitbreiding" Expander.Presets.Gate="Hek" +LumaKeyFilter="Luma Key" +Luma.LumaMax="Luma Max" +Luma.LumaMin="Luma Min" +Luma.LumaMaxSmooth="Luma Max Smooth" +Luma.LumaMinSmooth="Luma Min Smooth" diff --git a/plugins/obs-filters/data/locale/ro-RO.ini b/plugins/obs-filters/data/locale/ro-RO.ini index f677080..91ddcb3 100644 --- a/plugins/obs-filters/data/locale/ro-RO.ini +++ b/plugins/obs-filters/data/locale/ro-RO.ini @@ -5,7 +5,7 @@ ScrollFilter="Derulare" ChromaKeyFilter="Cheie chroma" ColorKeyFilter="Culoare cheie" SharpnessFilter="Accentuare" -ScaleFilter="Scalare/Rație Aspect" +ScaleFilter="Raport de scalare/aspect" NoiseGate="Poartă de zgomot" InvertPolarity="Inversează polaritatea" Gain="Amplificare" @@ -54,10 +54,13 @@ Gain.GainDB="Amplificare (dB)" StretchImage="Întinde imaginea (renunță la raportul de aspect al imaginii)" Resolution="Rezoluție" Base.Canvas="Rezoluție (planșă) de bază" -None="Fără" -ScaleFiltering.Bilinear="Biliniar" -ScaleFiltering.Bicubic="Bicubic" +None="Niciuna" +ScaleFiltering="Filtrare scalară" +ScaleFiltering.Point="Punct" +ScaleFiltering.Bilinear="Bilineară" +ScaleFiltering.Bicubic="Bicubică" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Zonă" Saturation="Saturație" Compressor="Compresor" Compressor.Ratio="Raport (X:1)" diff --git a/plugins/obs-filters/data/locale/sl-SI.ini b/plugins/obs-filters/data/locale/sl-SI.ini index 46571bb..9bea1d4 100644 --- a/plugins/obs-filters/data/locale/sl-SI.ini +++ b/plugins/obs-filters/data/locale/sl-SI.ini @@ -1,2 +1,99 @@ ColorFilter="Popravljanje barv" +ColorGradeFilter="Uporabi LUT" +MaskFilter="Maskiranje/Mešanje slike" +AsyncDelayFilter="Zakasnitev slike (asinh.)" +CropFilter="Obreži/Zapolni" +ScrollFilter="Pomikanje" +ChromaKeyFilter="Kromatsko prekrivanje" +ColorKeyFilter="Barvno prekrivanje" +SharpnessFilter="Izostri" +ScaleFilter="Spr. velikosti/Razmerje" +GPUDelayFilter="Zakasnitev izrisa" +UndistortCenter="Odpravi popačenje sredine slike med spremembo velikost iz ultraširoke" +NoiseGate="Vrata šuma" +NoiseSuppress="Dušenje šuma" +InvertPolarity="Obrni polarnost" +Gain="Ojačitev" +DelayMs="Zakasnitev (ms)" +Type="Vrsta" +MaskBlendType.MaskColor="Maska alfa (barvni kanal)" +MaskBlendType.MaskAlpha="Maska alfa (kanal alfa)" +MaskBlendType.BlendMultiply="Premešaj (zmnoži)" +MaskBlendType.BlendAddition="Premešaj (seštej)" +MaskBlendType.BlendSubtraction="Premešaj (odštej)" +Path="Pot" +Color="Barva" +Opacity="Motnost" +Contrast="Kontrast" +Brightness="Svetlost" +Gamma="Gama" +BrowsePath.Images="Vse slikovne datoteke" +BrowsePath.AllFiles="Vse datoteke" +KeyColorType="Vrsta ključne barve" +KeyColor="Ključna barva" +Similarity="Podobnost (1-1000)" +Smoothness="Gladkost (1-1000)" +ColorSpillReduction="Zmanjševanje razlivanja ključne barve (1-1000)" +Crop.Left="Levo" +Crop.Right="Desno" +Crop.Top="Zgoraj" +Crop.Bottom="Spodaj" +Crop.Width="Širina" +Crop.Height="Višina" +Crop.Relative="Relativno" +ScrollFilter.SpeedX="Vodoravna hitrost" +ScrollFilter.SpeedY="Navpična hitrost" +ScrollFilter.LimitWidth="Omeji širino" +ScrollFilter.LimitHeight="Omeji višino" +CustomColor="Barva po meri" +Red="Rdeča" +Green="Zelena" +Blue="Modra" +Magenta="Škrlatna" +NoiseGate.OpenThreshold="Odpri prag (dB)" +NoiseGate.CloseThreshold="Zapri prag (dB)" +NoiseGate.AttackTime="Čas napada (ms)" +NoiseGate.HoldTime="Čas držanja (ms)" +NoiseGate.ReleaseTime="Čas sprostitve (ms)" +Gain.GainDB="Ojačitev (dB)" +StretchImage="Raztegni sliko (zavrzi razmerje slike)" +Resolution="Ločljivost" +Base.Canvas="Osnovna ločljivost" +None="Brez" +ScaleFiltering="Filtriranje sprem. velikosti" +ScaleFiltering.Point="Točkovno" +ScaleFiltering.Bilinear="Dvovrstno" +ScaleFiltering.Bicubic="Dvoprostor." +ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Območje" +NoiseSuppress.SuppressLevel="Raven dušenja (dB)" +Saturation="Nasičenost" +HueShift="Zamik odtenka" +Amount="Količina" +Compressor="Stiskalnik" +Compressor.Ratio="Razmerje (x:1)" +Compressor.Threshold="Prag (dB)" +Compressor.AttackTime="Napad (ms)" +Compressor.ReleaseTime="Sprostitev (ms)" +Compressor.OutputGain="Izhodna ojačitev (dB)" +Compressor.SidechainSource="Vir reference/zmanjšanja glasnosti" +Limiter="Omejevalnik" +Limiter.Threshold="Prag (dB)" +Limiter.ReleaseTime="Sprostitev (ms)" +Expander="Razširjevalec" +Expander.Ratio="Razmerje (x:1)" +Expander.Threshold="Prag (dB)" +Expander.AttackTime="Napad (ms)" +Expander.ReleaseTime="Sprostitev (ms)" +Expander.OutputGain="Izhodna ojačitev (dB)" +Expander.Detector="Zaznavanje" +Expander.RMS="Nazivna vrednost" +Expander.Peak="Najvišja točka" +Expander.None="Brez" +Expander.Presets="Prednastavitve" +Expander.Presets.Expander="Razširjevalec" +Expander.Presets.Gate="Vrata" +LumaKeyFilter="Svetlobno prekrivanje" +Luma.LumaMax="Največja svetilnost" +Luma.LumaMin="Najmanjša svetilnost" diff --git a/plugins/obs-filters/data/locale/sv-SE.ini b/plugins/obs-filters/data/locale/sv-SE.ini index 0c8b2d5..667e96e 100644 --- a/plugins/obs-filters/data/locale/sv-SE.ini +++ b/plugins/obs-filters/data/locale/sv-SE.ini @@ -28,7 +28,7 @@ Contrast="Kontrast" Brightness="Ljusstyrka" Gamma="Gamma" BrowsePath.Images="Alla bildfiler" -BrowsePath.AllFiles="Alla Filer" +BrowsePath.AllFiles="Alla filer" KeyColorType="Huvudfärg typ" KeyColor="Huvudfärg" Similarity="Likhet (1-1000)" diff --git a/plugins/obs-filters/expander-filter.c b/plugins/obs-filters/expander-filter.c index dc4e821..fb0db8a 100644 --- a/plugins/obs-filters/expander-filter.c +++ b/plugins/obs-filters/expander-filter.c @@ -10,21 +10,23 @@ /* -------------------------------------------------------- */ -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[expander: '%s'] " format, \ - obs_source_get_name(cd->context), ##__VA_ARGS__) + obs_source_get_name(cd->context), ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) #ifdef _DEBUG -#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) #else #define debug(format, ...) #endif /* -------------------------------------------------------- */ +/* clang-format off */ + #define S_RATIO "ratio" #define S_THRESHOLD "threshold" #define S_ATTACK_TIME "attack_time" @@ -61,6 +63,8 @@ #define MS_IN_S 1000 #define MS_IN_S_F ((float)MS_IN_S) +/* clang-format on */ + /* -------------------------------------------------------- */ struct expander_data { @@ -78,7 +82,7 @@ struct expander_data { size_t sample_rate; float envelope[MAX_AUDIO_CHANNELS]; float slope; - int detector; + int detector; float runave[MAX_AUDIO_CHANNELS]; bool is_gate; float *runaverage[MAX_AUDIO_CHANNELS]; @@ -90,11 +94,10 @@ struct expander_data { size_t env_in_len; }; -enum { - RMS_DETECT, - RMS_STILLWELL_DETECT, - PEAK_DETECT, - NO_DETECT, +enum { RMS_DETECT, + RMS_STILLWELL_DETECT, + PEAK_DETECT, + NO_DETECT, }; /* -------------------------------------------------------- */ @@ -102,16 +105,17 @@ static void resize_env_buffer(struct expander_data *cd, size_t len) { cd->envelope_buf_len = len; for (int i = 0; i < MAX_AUDIO_CHANNELS; i++) - cd->envelope_buf[i] = brealloc(cd->envelope_buf[i], - cd->envelope_buf_len * sizeof(float)); + cd->envelope_buf[i] = + brealloc(cd->envelope_buf[i], + cd->envelope_buf_len * sizeof(float)); } static void resize_runaverage_buffer(struct expander_data *cd, size_t len) { cd->runaverage_len = len; for (int i = 0; i < MAX_AUDIO_CHANNELS; i++) - cd->runaverage[i] = brealloc(cd->runaverage[i], - cd->runaverage_len * sizeof(float)); + cd->runaverage[i] = brealloc( + cd->runaverage[i], cd->runaverage_len * sizeof(float)); } static void resize_env_in_buffer(struct expander_data *cd, size_t len) @@ -124,8 +128,8 @@ static void resize_gaindB_buffer(struct expander_data *cd, size_t len) { cd->gaindB_len = len; for (int i = 0; i < MAX_AUDIO_CHANNELS; i++) - cd->gaindB[i] = brealloc(cd->gaindB[i], - cd->gaindB_len * sizeof(float)); + cd->gaindB[i] = + brealloc(cd->gaindB[i], cd->gaindB_len * sizeof(float)); } static inline float gain_coefficient(uint32_t sample_rate, float time) @@ -145,14 +149,14 @@ static void expander_defaults(obs_data_t *s) bool is_expander_preset = true; if (strcmp(presets, "gate") == 0) is_expander_preset = false; - obs_data_set_default_string(s, S_PRESETS, is_expander_preset ? - "expander" : "gate"); - obs_data_set_default_double(s, S_RATIO, is_expander_preset ? - 2.0 : 10.0); + obs_data_set_default_string(s, S_PRESETS, + is_expander_preset ? "expander" : "gate"); + obs_data_set_default_double(s, S_RATIO, + is_expander_preset ? 2.0 : 10.0); obs_data_set_default_double(s, S_THRESHOLD, -40.0f); obs_data_set_default_int(s, S_ATTACK_TIME, 10); - obs_data_set_default_int(s, S_RELEASE_TIME, is_expander_preset ? - 50 : 125); + obs_data_set_default_int(s, S_RELEASE_TIME, + is_expander_preset ? 50 : 125); obs_data_set_default_double(s, S_OUTPUT_GAIN, 0.0); obs_data_set_default_string(s, S_DETECTOR, "RMS"); } @@ -175,23 +179,21 @@ static void expander_update(void *data, obs_data_t *s) } const uint32_t sample_rate = - audio_output_get_sample_rate(obs_get_audio()); - const size_t num_channels = - audio_output_get_channels(obs_get_audio()); - const float attack_time_ms = - (float)obs_data_get_int(s, S_ATTACK_TIME); + audio_output_get_sample_rate(obs_get_audio()); + const size_t num_channels = audio_output_get_channels(obs_get_audio()); + const float attack_time_ms = (float)obs_data_get_int(s, S_ATTACK_TIME); const float release_time_ms = - (float)obs_data_get_int(s, S_RELEASE_TIME); + (float)obs_data_get_int(s, S_RELEASE_TIME); const float output_gain_db = - (float)obs_data_get_double(s, S_OUTPUT_GAIN); + (float)obs_data_get_double(s, S_OUTPUT_GAIN); cd->ratio = (float)obs_data_get_double(s, S_RATIO); cd->threshold = (float)obs_data_get_double(s, S_THRESHOLD); - cd->attack_gain = gain_coefficient(sample_rate, - attack_time_ms / MS_IN_S_F); - cd->release_gain = gain_coefficient(sample_rate, - release_time_ms / MS_IN_S_F); + cd->attack_gain = + gain_coefficient(sample_rate, attack_time_ms / MS_IN_S_F); + cd->release_gain = + gain_coefficient(sample_rate, release_time_ms / MS_IN_S_F); cd->output_gain = db_to_mul(output_gain_db); cd->num_channels = num_channels; cd->sample_rate = sample_rate; @@ -246,8 +248,8 @@ static void expander_destroy(void *data) } // detection stage -static void analyze_envelope(struct expander_data *cd, - float **samples, const uint32_t num_samples) +static void analyze_envelope(struct expander_data *cd, float **samples, + const uint32_t num_samples) { if (cd->envelope_buf_len < num_samples) resize_env_buffer(cd, num_samples); @@ -261,9 +263,9 @@ static void analyze_envelope(struct expander_data *cd, for (int i = 0; i < MAX_AUDIO_CHANNELS; i++) { memset(cd->envelope_buf[i], 0, - num_samples * sizeof(cd->envelope_buf[i][0])); + num_samples * sizeof(cd->envelope_buf[i][0])); memset(cd->runaverage[i], 0, - num_samples * sizeof(cd->runaverage[i][0])); + num_samples * sizeof(cd->runaverage[i][0])); } memset(cd->env_in, 0, num_samples * sizeof(cd->env_in[0])); @@ -276,13 +278,15 @@ static void analyze_envelope(struct expander_data *cd, float *env_in = cd->env_in; if (cd->detector == RMS_DETECT) { - runave[0] = rmscoef * cd->runave[chan] + + runave[0] = + rmscoef * cd->runave[chan] + (1 - rmscoef) * powf(samples[chan][0], 2.0f); env_in[0] = sqrtf(fmaxf(runave[0], 0)); for (uint32_t i = 1; i < num_samples; ++i) { - runave[i] = rmscoef * runave[i - 1] + + runave[i] = + rmscoef * runave[i - 1] + (1 - rmscoef) * - powf(samples[chan][i], 2.0f); + powf(samples[chan][i], 2.0f); env_in[i] = sqrtf(runave[i]); } } else if (cd->detector == PEAK_DETECT) { @@ -292,7 +296,7 @@ static void analyze_envelope(struct expander_data *cd, } } - cd->runave[chan] = runave[num_samples-1]; + cd->runave[chan] = runave[num_samples - 1]; for (uint32_t i = 0; i < num_samples; ++i) envelope_buf[i] = fmaxf(envelope_buf[i], env_in[i]); cd->envelope[chan] = cd->envelope_buf[chan][num_samples - 1]; @@ -300,8 +304,8 @@ static void analyze_envelope(struct expander_data *cd, } // gain stage and ballistics in dB domain -static inline void process_expansion(struct expander_data *cd, - float **samples, uint32_t num_samples) +static inline void process_expansion(struct expander_data *cd, float **samples, + uint32_t num_samples) { const float attack_gain = cd->attack_gain; const float release_gain = cd->release_gain; @@ -309,35 +313,42 @@ static inline void process_expansion(struct expander_data *cd, if (cd->gaindB_len < num_samples) resize_gaindB_buffer(cd, num_samples); for (int i = 0; i < MAX_AUDIO_CHANNELS; i++) - memset(cd->gaindB[i], 0, num_samples * sizeof(cd->gaindB[i][0])); + memset(cd->gaindB[i], 0, + num_samples * sizeof(cd->gaindB[i][0])); for (size_t chan = 0; chan < cd->num_channels; chan++) { for (size_t i = 0; i < num_samples; ++i) { // gain stage of expansion float env_db = mul_to_db(cd->envelope_buf[chan][i]); - float gain = cd->threshold - env_db > 0.0f ? - fmaxf(cd->slope * - (cd->threshold - env_db), -60.0f) : - 0.0f; + float gain = + cd->threshold - env_db > 0.0f + ? fmaxf(cd->slope * (cd->threshold - + env_db), + -60.0f) + : 0.0f; // ballistics (attack/release) if (i > 0) { if (gain > cd->gaindB[chan][i - 1]) - cd->gaindB[chan][i] = attack_gain * - cd->gaindB[chan][i - 1] + - (1.0f - attack_gain) * gain; + cd->gaindB[chan][i] = + attack_gain * + cd->gaindB[chan][i - 1] + + (1.0f - attack_gain) * gain; else - cd->gaindB[chan][i] = release_gain * - cd->gaindB[chan][i - 1] + - (1.0f - release_gain) * gain; + cd->gaindB[chan][i] = + release_gain * + cd->gaindB[chan][i - 1] + + (1.0f - release_gain) * gain; } else { if (gain > cd->gaindB_buf[chan]) - cd->gaindB[chan][i] = attack_gain * - cd->gaindB_buf[chan] + - (1.0f - attack_gain) * gain; + cd->gaindB[chan][i] = + attack_gain * + cd->gaindB_buf[chan] + + (1.0f - attack_gain) * gain; else - cd->gaindB[chan][i] = release_gain * - cd->gaindB_buf[chan] + - (1.0f - release_gain) * gain; + cd->gaindB[chan][i] = + release_gain * + cd->gaindB_buf[chan] + + (1.0f - release_gain) * gain; } gain = db_to_mul(fminf(0, cd->gaindB[chan][i])); @@ -348,8 +359,8 @@ static inline void process_expansion(struct expander_data *cd, } } -static struct obs_audio_data *expander_filter_audio(void *data, - struct obs_audio_data *audio) +static struct obs_audio_data * +expander_filter_audio(void *data, struct obs_audio_data *audio) { struct expander_data *cd = data; @@ -357,7 +368,7 @@ static struct obs_audio_data *expander_filter_audio(void *data, if (num_samples == 0) return audio; - float **samples = (float**)audio->data; + float **samples = (float **)audio->data; analyze_envelope(cd, samples, num_samples); process_expansion(cd, samples, num_samples); @@ -365,7 +376,7 @@ static struct obs_audio_data *expander_filter_audio(void *data, } static bool presets_changed(obs_properties_t *props, obs_property_t *prop, - obs_data_t *settings) + obs_data_t *settings) { UNUSED_PARAMETER(props); UNUSED_PARAMETER(prop); @@ -376,28 +387,37 @@ static bool presets_changed(obs_properties_t *props, obs_property_t *prop, static obs_properties_t *expander_properties(void *data) { obs_properties_t *props = obs_properties_create(); + obs_property_t *p; - obs_property_t *presets = obs_properties_add_list(props, S_PRESETS, - TEXT_PRESETS, OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_STRING); + obs_property_t *presets = obs_properties_add_list( + props, S_PRESETS, TEXT_PRESETS, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(presets, TEXT_PRESETS_EXP, "expander"); obs_property_list_add_string(presets, TEXT_PRESETS_GATE, "gate"); obs_property_set_modified_callback(presets, presets_changed); - obs_properties_add_float_slider(props, S_RATIO, - TEXT_RATIO, MIN_RATIO, MAX_RATIO, 0.1); - obs_properties_add_float_slider(props, S_THRESHOLD, - TEXT_THRESHOLD, MIN_THRESHOLD_DB, MAX_THRESHOLD_DB, - 0.1); - obs_properties_add_int_slider(props, S_ATTACK_TIME, - TEXT_ATTACK_TIME, MIN_ATK_RLS_MS, MAX_ATK_MS, 1); - obs_properties_add_int_slider(props, S_RELEASE_TIME, - TEXT_RELEASE_TIME, MIN_ATK_RLS_MS, MAX_RLS_MS, 1); - obs_properties_add_float_slider(props, S_OUTPUT_GAIN, - TEXT_OUTPUT_GAIN, MIN_OUTPUT_GAIN_DB, - MAX_OUTPUT_GAIN_DB, 0.1); - obs_property_t *detect = obs_properties_add_list(props, S_DETECTOR, - TEXT_DETECTOR, OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_STRING); + p = obs_properties_add_float_slider(props, S_RATIO, TEXT_RATIO, + MIN_RATIO, MAX_RATIO, 0.1); + obs_property_float_set_suffix(p, ":1"); + p = obs_properties_add_float_slider(props, S_THRESHOLD, TEXT_THRESHOLD, + MIN_THRESHOLD_DB, MAX_THRESHOLD_DB, + 0.1); + obs_property_float_set_suffix(p, " dB"); + p = obs_properties_add_int_slider(props, S_ATTACK_TIME, + TEXT_ATTACK_TIME, MIN_ATK_RLS_MS, + MAX_ATK_MS, 1); + obs_property_int_set_suffix(p, " ms"); + p = obs_properties_add_int_slider(props, S_RELEASE_TIME, + TEXT_RELEASE_TIME, MIN_ATK_RLS_MS, + MAX_RLS_MS, 1); + obs_property_int_set_suffix(p, " ms"); + p = obs_properties_add_float_slider(props, S_OUTPUT_GAIN, + TEXT_OUTPUT_GAIN, + MIN_OUTPUT_GAIN_DB, + MAX_OUTPUT_GAIN_DB, 0.1); + obs_property_float_set_suffix(p, " dB"); + obs_property_t *detect = obs_properties_add_list( + props, S_DETECTOR, TEXT_DETECTOR, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(detect, TEXT_RMS, "RMS"); obs_property_list_add_string(detect, TEXT_PEAK, "peak"); diff --git a/plugins/obs-filters/gain-filter.c b/plugins/obs-filters/gain-filter.c index 13f4131..458abce 100644 --- a/plugins/obs-filters/gain-filter.c +++ b/plugins/obs-filters/gain-filter.c @@ -2,17 +2,17 @@ #include #include -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[gain filter: '%s'] " format, \ - obs_source_get_name(gf->context), ##__VA_ARGS__) + obs_source_get_name(gf->context), ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) -#define S_GAIN_DB "db" +#define S_GAIN_DB "db" #define MT_ obs_module_text -#define TEXT_GAIN_DB MT_("Gain.GainDB") +#define TEXT_GAIN_DB MT_("Gain.GainDB") struct gain_data { obs_source_t *context; @@ -49,11 +49,11 @@ static void *gain_create(obs_data_t *settings, obs_source_t *filter) } static struct obs_audio_data *gain_filter_audio(void *data, - struct obs_audio_data *audio) + struct obs_audio_data *audio) { struct gain_data *gf = data; const size_t channels = gf->channels; - float **adata = (float**)audio->data; + float **adata = (float **)audio->data; const float multiple = gf->multiple; for (size_t c = 0; c < channels; c++) { @@ -76,8 +76,9 @@ static obs_properties_t *gain_properties(void *data) { obs_properties_t *ppts = obs_properties_create(); - obs_properties_add_float_slider(ppts, S_GAIN_DB, TEXT_GAIN_DB, - -30.0, 30.0, 0.1); + obs_property_t *p = obs_properties_add_float_slider( + ppts, S_GAIN_DB, TEXT_GAIN_DB, -30.0, 30.0, 0.1); + obs_property_float_set_suffix(p, " dB"); UNUSED_PARAMETER(data); return ppts; diff --git a/plugins/obs-filters/gpu-delay.c b/plugins/obs-filters/gpu-delay.c index b35482b..4eb98e0 100644 --- a/plugins/obs-filters/gpu-delay.c +++ b/plugins/obs-filters/gpu-delay.c @@ -1,8 +1,8 @@ #include #include -#define S_DELAY_MS "delay_ms" -#define T_DELAY_MS obs_module_text("DelayMs") +#define S_DELAY_MS "delay_ms" +#define T_DELAY_MS obs_module_text("DelayMs") struct frame { gs_texrender_t *render; @@ -10,14 +10,14 @@ struct frame { }; struct gpu_delay_filter_data { - obs_source_t *context; - struct circlebuf frames; - uint64_t delay_ns; - uint64_t interval_ns; - uint32_t cx; - uint32_t cy; - bool target_valid; - bool processed_frame; + obs_source_t *context; + struct circlebuf frames; + uint64_t delay_ns; + uint64_t interval_ns; + uint32_t cx; + uint32_t cy; + bool target_valid; + bool processed_frame; }; static const char *gpu_delay_filter_get_name(void *unused) @@ -44,7 +44,7 @@ static size_t num_frames(struct circlebuf *buf) } static void update_interval(struct gpu_delay_filter_data *f, - uint64_t new_interval_ns) + uint64_t new_interval_ns) { if (!f->target_valid) { free_textures(f); @@ -62,9 +62,10 @@ static void update_interval(struct gpu_delay_filter_data *f, circlebuf_upsize(&f->frames, num * sizeof(struct frame)); for (size_t i = prev_num; i < num; i++) { - struct frame *frame = circlebuf_data(&f->frames, - i * sizeof(*frame)); - frame->render = gs_texrender_create(GS_RGBA, GS_ZS_NONE); + struct frame *frame = + circlebuf_data(&f->frames, i * sizeof(*frame)); + frame->render = + gs_texrender_create(GS_RGBA, GS_ZS_NONE); } obs_leave_graphics(); @@ -89,8 +90,8 @@ static inline void check_interval(struct gpu_delay_filter_data *f) obs_get_video_info(&ovi); - interval_ns = (uint64_t)ovi.fps_den * 1000000000ULL / - (uint64_t)ovi.fps_num; + interval_ns = + (uint64_t)ovi.fps_den * 1000000000ULL / (uint64_t)ovi.fps_num; if (interval_ns != f->interval_ns) update_interval(f, interval_ns); @@ -147,13 +148,16 @@ static obs_properties_t *gpu_delay_filter_properties(void *data) { obs_properties_t *props = obs_properties_create(); - obs_properties_add_int(props, S_DELAY_MS, T_DELAY_MS, 0, 500, 1); + obs_property_t *p = obs_properties_add_int(props, S_DELAY_MS, + T_DELAY_MS, 0, 500, 1); + obs_property_int_set_suffix(p, " ms"); UNUSED_PARAMETER(data); return props; } -static void *gpu_delay_filter_create(obs_data_t *settings, obs_source_t *context) +static void *gpu_delay_filter_create(obs_data_t *settings, + obs_source_t *context) { struct gpu_delay_filter_data *f = bzalloc(sizeof(*f)); f->context = context; @@ -232,8 +236,8 @@ static void gpu_delay_filter_render(void *data, gs_effect_t *effect) vec4_zero(&clear_color); gs_clear(GS_CLEAR_COLOR, &clear_color, 0.0f, 0); - gs_ortho(0.0f, (float)f->cx, 0.0f, (float)f->cy, - -100.0f, 100.0f); + gs_ortho(0.0f, (float)f->cx, 0.0f, (float)f->cy, -100.0f, + 100.0f); if (target == parent && !custom_draw && !async) obs_source_default_render(target); @@ -253,14 +257,14 @@ static void gpu_delay_filter_render(void *data, gs_effect_t *effect) } struct obs_source_info gpu_delay_filter = { - .id = "gpu_delay", - .type = OBS_SOURCE_TYPE_FILTER, - .output_flags = OBS_SOURCE_VIDEO, - .get_name = gpu_delay_filter_get_name, - .create = gpu_delay_filter_create, - .destroy = gpu_delay_filter_destroy, - .update = gpu_delay_filter_update, - .get_properties = gpu_delay_filter_properties, - .video_tick = gpu_delay_filter_tick, - .video_render = gpu_delay_filter_render + .id = "gpu_delay", + .type = OBS_SOURCE_TYPE_FILTER, + .output_flags = OBS_SOURCE_VIDEO, + .get_name = gpu_delay_filter_get_name, + .create = gpu_delay_filter_create, + .destroy = gpu_delay_filter_destroy, + .update = gpu_delay_filter_update, + .get_properties = gpu_delay_filter_properties, + .video_tick = gpu_delay_filter_tick, + .video_render = gpu_delay_filter_render, }; diff --git a/plugins/obs-filters/invert-audio-polarity.c b/plugins/obs-filters/invert-audio-polarity.c index 8c63508..5c225cf 100644 --- a/plugins/obs-filters/invert-audio-polarity.c +++ b/plugins/obs-filters/invert-audio-polarity.c @@ -17,10 +17,10 @@ static void *invert_polarity_create(obs_data_t *settings, obs_source_t *filter) return filter; } -static struct obs_audio_data *invert_polarity_filter_audio(void *unused, - struct obs_audio_data *audio) +static struct obs_audio_data * +invert_polarity_filter_audio(void *unused, struct obs_audio_data *audio) { - float **adata = (float**)audio->data; + float **adata = (float **)audio->data; for (size_t c = 0; c < MAX_AV_PLANES; c++) { register float *channel_data = adata[c]; diff --git a/plugins/obs-filters/limiter-filter.c b/plugins/obs-filters/limiter-filter.c index c6bc139..ec3ed05 100644 --- a/plugins/obs-filters/limiter-filter.c +++ b/plugins/obs-filters/limiter-filter.c @@ -8,21 +8,23 @@ /* -------------------------------------------------------- */ -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[limiter: '%s'] " format, \ - obs_source_get_name(cd->context), ##__VA_ARGS__) + obs_source_get_name(cd->context), ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) #ifdef _DEBUG -#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) #else #define debug(format, ...) #endif /* -------------------------------------------------------- */ +/* clang-format off */ + #define S_THRESHOLD "threshold" #define S_RELEASE_TIME "release_time" @@ -39,6 +41,8 @@ #define MS_IN_S 1000 #define MS_IN_S_F ((float)MS_IN_S) +/* clang-format on */ + /* -------------------------------------------------------- */ struct limiter_data { @@ -82,20 +86,19 @@ static void limiter_update(void *data, obs_data_t *s) const uint32_t sample_rate = audio_output_get_sample_rate(obs_get_audio()); - const size_t num_channels = - audio_output_get_channels(obs_get_audio()); + const size_t num_channels = audio_output_get_channels(obs_get_audio()); float attack_time_ms = ATK_TIME; const float release_time_ms = (float)obs_data_get_int(s, S_RELEASE_TIME); - const float output_gain_db = 0; + const float output_gain_db = 0; cd->threshold = (float)obs_data_get_double(s, S_THRESHOLD); - cd->attack_gain = gain_coefficient(sample_rate, - attack_time_ms / MS_IN_S_F); - cd->release_gain = gain_coefficient(sample_rate, - release_time_ms / MS_IN_S_F); + cd->attack_gain = + gain_coefficient(sample_rate, attack_time_ms / MS_IN_S_F); + cd->release_gain = + gain_coefficient(sample_rate, release_time_ms / MS_IN_S_F); cd->output_gain = db_to_mul(output_gain_db); cd->num_channels = num_channels; cd->sample_rate = sample_rate; @@ -109,7 +112,7 @@ static void limiter_update(void *data, obs_data_t *s) static void *limiter_create(obs_data_t *settings, obs_source_t *filter) { struct limiter_data *cd = bzalloc(sizeof(struct limiter_data)); - cd->context = filter; + cd->context = filter; limiter_update(cd, settings); return cd; @@ -123,8 +126,8 @@ static void limiter_destroy(void *data) bfree(cd); } -static void analyze_envelope(struct limiter_data *cd, - float **samples, const uint32_t num_samples) +static void analyze_envelope(struct limiter_data *cd, float **samples, + const uint32_t num_samples) { if (cd->envelope_buf_len < num_samples) { resize_env_buffer(cd, num_samples); @@ -154,7 +157,7 @@ static void analyze_envelope(struct limiter_data *cd, } static inline void process_compression(const struct limiter_data *cd, - float **samples, uint32_t num_samples) + float **samples, uint32_t num_samples) { for (size_t i = 0; i < num_samples; ++i) { const float env_db = mul_to_db(cd->envelope_buf[i]); @@ -170,7 +173,7 @@ static inline void process_compression(const struct limiter_data *cd, } static struct obs_audio_data *limiter_filter_audio(void *data, - struct obs_audio_data *audio) + struct obs_audio_data *audio) { struct limiter_data *cd = data; @@ -178,7 +181,7 @@ static struct obs_audio_data *limiter_filter_audio(void *data, if (num_samples == 0) return audio; - float **samples = (float**)audio->data; + float **samples = (float **)audio->data; analyze_envelope(cd, samples, num_samples); process_compression(cd, samples, num_samples); return audio; @@ -193,23 +196,30 @@ static void limiter_defaults(obs_data_t *s) static obs_properties_t *limiter_properties(void *data) { obs_properties_t *props = obs_properties_create(); + obs_property_t *p; - obs_properties_add_float_slider(props, S_THRESHOLD, TEXT_THRESHOLD, MIN_THRESHOLD_DB, MAX_THRESHOLD_DB, 0.1); - obs_properties_add_int_slider(props, S_RELEASE_TIME, TEXT_RELEASE_TIME, MIN_ATK_RLS_MS, MAX_RLS_MS, 1); + p = obs_properties_add_float_slider(props, S_THRESHOLD, TEXT_THRESHOLD, + MIN_THRESHOLD_DB, MAX_THRESHOLD_DB, + 0.1); + obs_property_float_set_suffix(p, " dB"); + p = obs_properties_add_int_slider(props, S_RELEASE_TIME, + TEXT_RELEASE_TIME, MIN_ATK_RLS_MS, + MAX_RLS_MS, 1); + obs_property_int_set_suffix(p, " ms"); UNUSED_PARAMETER(data); return props; } struct obs_source_info limiter_filter = { - .id = "limiter_filter", - .type = OBS_SOURCE_TYPE_FILTER, - .output_flags = OBS_SOURCE_AUDIO, - .get_name = limiter_name, - .create = limiter_create, - .destroy = limiter_destroy, - .update = limiter_update, - .filter_audio = limiter_filter_audio, - .get_defaults = limiter_defaults, - .get_properties = limiter_properties, + .id = "limiter_filter", + .type = OBS_SOURCE_TYPE_FILTER, + .output_flags = OBS_SOURCE_AUDIO, + .get_name = limiter_name, + .create = limiter_create, + .destroy = limiter_destroy, + .update = limiter_update, + .filter_audio = limiter_filter_audio, + .get_defaults = limiter_defaults, + .get_properties = limiter_properties, }; diff --git a/plugins/obs-filters/luma-key-filter.c b/plugins/obs-filters/luma-key-filter.c index b738a1c..bdd9b2e 100644 --- a/plugins/obs-filters/luma-key-filter.c +++ b/plugins/obs-filters/luma-key-filter.c @@ -1,5 +1,7 @@ #include +/* clang-format off */ + #define SETTING_LUMA_MAX "luma_max" #define SETTING_LUMA_MIN "luma_min" #define SETTING_LUMA_MAX_SMOOTH "luma_max_smooth" @@ -10,20 +12,22 @@ #define TEXT_LUMA_MAX_SMOOTH obs_module_text("Luma.LumaMaxSmooth") #define TEXT_LUMA_MIN_SMOOTH obs_module_text("Luma.LumaMinSmooth") +/* clang-format on */ + struct luma_key_filter_data { - obs_source_t *context; + obs_source_t *context; - gs_effect_t *effect; + gs_effect_t *effect; - gs_eparam_t *luma_max_param; - gs_eparam_t *luma_min_param; - gs_eparam_t *luma_max_smooth_param; - gs_eparam_t *luma_min_smooth_param; + gs_eparam_t *luma_max_param; + gs_eparam_t *luma_min_param; + gs_eparam_t *luma_max_smooth_param; + gs_eparam_t *luma_min_smooth_param; - float luma_max; - float luma_min; - float luma_max_smooth; - float luma_min_smooth; + float luma_max; + float luma_min; + float luma_max_smooth; + float luma_min_smooth; }; static const char *luma_key_name(void *unused) @@ -38,8 +42,10 @@ static void luma_key_update(void *data, obs_data_t *settings) double lumaMax = obs_data_get_double(settings, SETTING_LUMA_MAX); double lumaMin = obs_data_get_double(settings, SETTING_LUMA_MIN); - double lumaMaxSmooth = obs_data_get_double(settings, SETTING_LUMA_MAX_SMOOTH); - double lumaMinSmooth = obs_data_get_double(settings, SETTING_LUMA_MIN_SMOOTH); + double lumaMaxSmooth = + obs_data_get_double(settings, SETTING_LUMA_MAX_SMOOTH); + double lumaMinSmooth = + obs_data_get_double(settings, SETTING_LUMA_MIN_SMOOTH); filter->luma_max = (float)lumaMax; filter->luma_min = (float)lumaMin; @@ -63,7 +69,7 @@ static void luma_key_destroy(void *data) static void *luma_key_create(obs_data_t *settings, obs_source_t *context) { struct luma_key_filter_data *filter = - bzalloc(sizeof(struct luma_key_filter_data)); + bzalloc(sizeof(struct luma_key_filter_data)); char *effect_path = obs_module_file("luma_key_filter.effect"); filter->context = context; @@ -72,14 +78,14 @@ static void *luma_key_create(obs_data_t *settings, obs_source_t *context) filter->effect = gs_effect_create_from_file(effect_path, NULL); if (filter->effect) { - filter->luma_max_param = gs_effect_get_param_by_name( - filter->effect, "lumaMax"); - filter->luma_min_param = gs_effect_get_param_by_name( - filter->effect, "lumaMin"); + filter->luma_max_param = + gs_effect_get_param_by_name(filter->effect, "lumaMax"); + filter->luma_min_param = + gs_effect_get_param_by_name(filter->effect, "lumaMin"); filter->luma_max_smooth_param = gs_effect_get_param_by_name( - filter->effect, "lumaMaxSmooth"); + filter->effect, "lumaMaxSmooth"); filter->luma_min_smooth_param = gs_effect_get_param_by_name( - filter->effect, "lumaMinSmooth"); + filter->effect, "lumaMinSmooth"); } obs_leave_graphics(); @@ -100,13 +106,15 @@ static void luma_key_render(void *data, gs_effect_t *effect) struct luma_key_filter_data *filter = data; if (!obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING)) + OBS_ALLOW_DIRECT_RENDERING)) return; gs_effect_set_float(filter->luma_max_param, filter->luma_max); gs_effect_set_float(filter->luma_min_param, filter->luma_min); - gs_effect_set_float(filter->luma_max_smooth_param, filter->luma_max_smooth); - gs_effect_set_float(filter->luma_min_smooth_param, filter->luma_min_smooth); + gs_effect_set_float(filter->luma_max_smooth_param, + filter->luma_max_smooth); + gs_effect_set_float(filter->luma_min_smooth_param, + filter->luma_min_smooth); obs_source_process_filter_end(filter->context, filter->effect, 0, 0); @@ -117,14 +125,14 @@ static obs_properties_t *luma_key_properties(void *data) { obs_properties_t *props = obs_properties_create(); - obs_properties_add_float_slider(props, SETTING_LUMA_MAX, - TEXT_LUMA_MAX, 0, 1, 0.01); + obs_properties_add_float_slider(props, SETTING_LUMA_MAX, TEXT_LUMA_MAX, + 0, 1, 0.01); obs_properties_add_float_slider(props, SETTING_LUMA_MAX_SMOOTH, - TEXT_LUMA_MAX_SMOOTH, 0, 1, 0.01); - obs_properties_add_float_slider(props, SETTING_LUMA_MIN, - TEXT_LUMA_MIN, 0, 1, 0.01); + TEXT_LUMA_MAX_SMOOTH, 0, 1, 0.01); + obs_properties_add_float_slider(props, SETTING_LUMA_MIN, TEXT_LUMA_MIN, + 0, 1, 0.01); obs_properties_add_float_slider(props, SETTING_LUMA_MIN_SMOOTH, - TEXT_LUMA_MIN_SMOOTH, 0, 1, 0.01); + TEXT_LUMA_MIN_SMOOTH, 0, 1, 0.01); UNUSED_PARAMETER(data); return props; @@ -138,16 +146,15 @@ static void luma_key_defaults(obs_data_t *settings) obs_data_set_default_double(settings, SETTING_LUMA_MIN_SMOOTH, 0.0); } - struct obs_source_info luma_key_filter = { - .id = "luma_key_filter", - .type = OBS_SOURCE_TYPE_FILTER, - .output_flags = OBS_SOURCE_VIDEO, - .get_name = luma_key_name, - .create = luma_key_create, - .destroy = luma_key_destroy, - .video_render = luma_key_render, - .update = luma_key_update, - .get_properties = luma_key_properties, - .get_defaults = luma_key_defaults + .id = "luma_key_filter", + .type = OBS_SOURCE_TYPE_FILTER, + .output_flags = OBS_SOURCE_VIDEO, + .get_name = luma_key_name, + .create = luma_key_create, + .destroy = luma_key_destroy, + .video_render = luma_key_render, + .update = luma_key_update, + .get_properties = luma_key_properties, + .get_defaults = luma_key_defaults, }; diff --git a/plugins/obs-filters/mask-filter.c b/plugins/obs-filters/mask-filter.c index d832232..fc93079 100644 --- a/plugins/obs-filters/mask-filter.c +++ b/plugins/obs-filters/mask-filter.c @@ -4,6 +4,8 @@ #include #include +/* clang-format off */ + #define SETTING_TYPE "type" #define SETTING_IMAGE_PATH "image_path" #define SETTING_COLOR "color" @@ -18,16 +20,18 @@ #define TEXT_PATH_IMAGES obs_module_text("BrowsePath.Images") #define TEXT_PATH_ALL_FILES obs_module_text("BrowsePath.AllFiles") +/* clang-format on */ + struct mask_filter_data { - uint64_t last_time; + uint64_t last_time; - obs_source_t *context; - gs_effect_t *effect; + obs_source_t *context; + gs_effect_t *effect; - gs_texture_t *target; - gs_image_file_t image; - struct vec4 color; - bool lock_aspect; + gs_texture_t *target; + gs_image_file_t image; + struct vec4 color; + bool lock_aspect; }; static const char *mask_filter_get_name(void *unused) @@ -75,13 +79,12 @@ static void mask_filter_update(void *data, obs_data_t *settings) static void mask_filter_defaults(obs_data_t *settings) { obs_data_set_default_string(settings, SETTING_TYPE, - "mask_color_filter.effect"); + "mask_color_filter.effect"); obs_data_set_default_int(settings, SETTING_COLOR, 0xFFFFFF); obs_data_set_default_int(settings, SETTING_OPACITY, 100); } -#define IMAGE_FILTER_EXTENSIONS \ - " (*.bmp *.jpg *.jpeg *.tga *.gif *.png)" +#define IMAGE_FILTER_EXTENSIONS " (*.bmp *.jpg *.jpeg *.tga *.gif *.png)" static obs_properties_t *mask_filter_properties(void *data) { @@ -95,29 +98,30 @@ static obs_properties_t *mask_filter_properties(void *data) dstr_cat(&filter_str, " (*.*)"); p = obs_properties_add_list(props, SETTING_TYPE, TEXT_TYPE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, - obs_module_text("MaskBlendType.MaskColor"), - "mask_color_filter.effect"); + obs_module_text("MaskBlendType.MaskColor"), + "mask_color_filter.effect"); obs_property_list_add_string(p, - obs_module_text("MaskBlendType.MaskAlpha"), - "mask_alpha_filter.effect"); - obs_property_list_add_string(p, - obs_module_text("MaskBlendType.BlendMultiply"), - "blend_mul_filter.effect"); - obs_property_list_add_string(p, - obs_module_text("MaskBlendType.BlendAddition"), - "blend_add_filter.effect"); - obs_property_list_add_string(p, - obs_module_text("MaskBlendType.BlendSubtraction"), - "blend_sub_filter.effect"); + obs_module_text("MaskBlendType.MaskAlpha"), + "mask_alpha_filter.effect"); + obs_property_list_add_string( + p, obs_module_text("MaskBlendType.BlendMultiply"), + "blend_mul_filter.effect"); + obs_property_list_add_string( + p, obs_module_text("MaskBlendType.BlendAddition"), + "blend_add_filter.effect"); + obs_property_list_add_string( + p, obs_module_text("MaskBlendType.BlendSubtraction"), + "blend_sub_filter.effect"); obs_properties_add_path(props, SETTING_IMAGE_PATH, TEXT_IMAGE_PATH, - OBS_PATH_FILE, filter_str.array, NULL); + OBS_PATH_FILE, filter_str.array, NULL); obs_properties_add_color(props, SETTING_COLOR, TEXT_COLOR); - obs_properties_add_int_slider(props, SETTING_OPACITY, TEXT_OPACITY, - 0, 100, 1); + obs_properties_add_int_slider(props, SETTING_OPACITY, TEXT_OPACITY, 0, + 100, 1); obs_properties_add_bool(props, SETTING_STRETCH, TEXT_STRETCH); dstr_free(&filter_str); @@ -159,7 +163,8 @@ static void mask_filter_tick(void *data, float t) if (!filter->last_time) filter->last_time = cur_time; - gs_image_file_tick(&filter->image, cur_time - filter->last_time); + gs_image_file_tick(&filter->image, + cur_time - filter->last_time); obs_enter_graphics(); gs_image_file_update_texture(&filter->image); obs_leave_graphics(); @@ -199,9 +204,8 @@ static void mask_filter_render(void *data, gs_effect_t *effect) mask_aspect = mask_size.x / mask_size.y; size_to_x = (source_aspect < mask_aspect); - fix = size_to_x ? - (source_size.x / mask_size.x) : - (source_size.y / mask_size.y); + fix = size_to_x ? (source_size.x / mask_size.x) + : (source_size.y / mask_size.y); vec2_mulf(&mask_size, &mask_size, fix); vec2_div(&mul_val, &source_size, &mask_size); @@ -213,7 +217,7 @@ static void mask_filter_render(void *data, gs_effect_t *effect) } if (!obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING)) + OBS_ALLOW_DIRECT_RENDERING)) return; param = gs_effect_get_param_by_name(filter->effect, "target"); @@ -234,15 +238,15 @@ static void mask_filter_render(void *data, gs_effect_t *effect) } struct obs_source_info mask_filter = { - .id = "mask_filter", - .type = OBS_SOURCE_TYPE_FILTER, - .output_flags = OBS_SOURCE_VIDEO, - .get_name = mask_filter_get_name, - .create = mask_filter_create, - .destroy = mask_filter_destroy, - .update = mask_filter_update, - .get_defaults = mask_filter_defaults, - .get_properties = mask_filter_properties, - .video_tick = mask_filter_tick, - .video_render = mask_filter_render + .id = "mask_filter", + .type = OBS_SOURCE_TYPE_FILTER, + .output_flags = OBS_SOURCE_VIDEO, + .get_name = mask_filter_get_name, + .create = mask_filter_create, + .destroy = mask_filter_destroy, + .update = mask_filter_update, + .get_defaults = mask_filter_defaults, + .get_properties = mask_filter_properties, + .video_tick = mask_filter_tick, + .video_render = mask_filter_render, }; diff --git a/plugins/obs-filters/noise-gate-filter.c b/plugins/obs-filters/noise-gate-filter.c index 0993e3b..a866409 100644 --- a/plugins/obs-filters/noise-gate-filter.c +++ b/plugins/obs-filters/noise-gate-filter.c @@ -2,12 +2,14 @@ #include #include -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[noise gate: '%s'] " format, \ - obs_source_get_name(ng->context), ##__VA_ARGS__) + obs_source_get_name(ng->context), ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) + +/* clang-format off */ #define S_OPEN_THRESHOLD "open_threshold" #define S_CLOSE_THRESHOLD "close_threshold" @@ -22,6 +24,8 @@ #define TEXT_HOLD_TIME MT_("NoiseGate.HoldTime") #define TEXT_RELEASE_TIME MT_("NoiseGate.ReleaseTime") +/* clang-format on */ + struct noise_gate_data { obs_source_t *context; @@ -104,12 +108,12 @@ static void *noise_gate_create(obs_data_t *settings, obs_source_t *filter) return ng; } -static struct obs_audio_data *noise_gate_filter_audio(void *data, - struct obs_audio_data *audio) +static struct obs_audio_data * +noise_gate_filter_audio(void *data, struct obs_audio_data *audio) { struct noise_gate_data *ng = data; - float **adata = (float**)audio->data; + float **adata = (float **)audio->data; const float close_threshold = ng->close_threshold; const float open_threshold = ng->open_threshold; const float sample_rate_i = ng->sample_rate_i; @@ -136,13 +140,13 @@ static struct obs_audio_data *noise_gate_filter_audio(void *data, ng->level = fmaxf(ng->level, cur_level) - decay_rate; if (ng->is_open) { - ng->attenuation = fminf(1.0f, - ng->attenuation + attack_rate); + ng->attenuation = + fminf(1.0f, ng->attenuation + attack_rate); } else { ng->held_time += sample_rate_i; if (ng->held_time > hold_time) { - ng->attenuation = fmaxf(0.0f, - ng->attenuation - release_rate); + ng->attenuation = fmaxf( + 0.0f, ng->attenuation - release_rate); } } @@ -157,25 +161,33 @@ static void noise_gate_defaults(obs_data_t *s) { obs_data_set_default_double(s, S_OPEN_THRESHOLD, -26.0); obs_data_set_default_double(s, S_CLOSE_THRESHOLD, -32.0); - obs_data_set_default_int (s, S_ATTACK_TIME, 25); - obs_data_set_default_int (s, S_HOLD_TIME, 200); - obs_data_set_default_int (s, S_RELEASE_TIME, 150); + obs_data_set_default_int(s, S_ATTACK_TIME, 25); + obs_data_set_default_int(s, S_HOLD_TIME, 200); + obs_data_set_default_int(s, S_RELEASE_TIME, 150); } static obs_properties_t *noise_gate_properties(void *data) { obs_properties_t *ppts = obs_properties_create(); + obs_property_t *p; - obs_properties_add_float_slider(ppts, S_CLOSE_THRESHOLD, - TEXT_CLOSE_THRESHOLD, VOL_MIN, VOL_MAX, 1.0); - obs_properties_add_float_slider(ppts, S_OPEN_THRESHOLD, - TEXT_OPEN_THRESHOLD, VOL_MIN, VOL_MAX, 1.0); - obs_properties_add_int(ppts, S_ATTACK_TIME, TEXT_ATTACK_TIME, - 0, 10000, 1); - obs_properties_add_int(ppts, S_HOLD_TIME, TEXT_HOLD_TIME, - 0, 10000, 1); - obs_properties_add_int(ppts, S_RELEASE_TIME, TEXT_RELEASE_TIME, - 0, 10000, 1); + p = obs_properties_add_float_slider(ppts, S_CLOSE_THRESHOLD, + TEXT_CLOSE_THRESHOLD, VOL_MIN, + VOL_MAX, 1.0); + obs_property_float_set_suffix(p, " dB"); + p = obs_properties_add_float_slider(ppts, S_OPEN_THRESHOLD, + TEXT_OPEN_THRESHOLD, VOL_MIN, + VOL_MAX, 1.0); + obs_property_float_set_suffix(p, " dB"); + p = obs_properties_add_int(ppts, S_ATTACK_TIME, TEXT_ATTACK_TIME, 0, + 10000, 1); + obs_property_int_set_suffix(p, " ms"); + p = obs_properties_add_int(ppts, S_HOLD_TIME, TEXT_HOLD_TIME, 0, 10000, + 1); + obs_property_int_set_suffix(p, " ms"); + p = obs_properties_add_int(ppts, S_RELEASE_TIME, TEXT_RELEASE_TIME, 0, + 10000, 1); + obs_property_int_set_suffix(p, " ms"); UNUSED_PARAMETER(data); return ppts; diff --git a/plugins/obs-filters/noise-suppress-filter.c b/plugins/obs-filters/noise-suppress-filter.c index 26c65b3..dd7a9a8 100644 --- a/plugins/obs-filters/noise-suppress-filter.c +++ b/plugins/obs-filters/noise-suppress-filter.c @@ -7,27 +7,27 @@ /* -------------------------------------------------------- */ -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[noise suppress: '%s'] " format, \ - obs_source_get_name(ng->context), ##__VA_ARGS__) + obs_source_get_name(ng->context), ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) #ifdef _DEBUG -#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) #else #define debug(format, ...) #endif /* -------------------------------------------------------- */ -#define S_SUPPRESS_LEVEL "suppress_level" +#define S_SUPPRESS_LEVEL "suppress_level" #define MT_ obs_module_text -#define TEXT_SUPPRESS_LEVEL MT_("NoiseSuppress.SuppressLevel") +#define TEXT_SUPPRESS_LEVEL MT_("NoiseSuppress.SuppressLevel") -#define MAX_PREPROC_CHANNELS 8 +#define MAX_PREPROC_CHANNELS 8 /* -------------------------------------------------------- */ @@ -90,12 +90,13 @@ static void noise_suppress_destroy(void *data) } static inline void alloc_channel(struct noise_suppress_data *ng, - uint32_t sample_rate, size_t channel, size_t frames) + uint32_t sample_rate, size_t channel, + size_t frames) { - ng->states[channel] = speex_preprocess_state_init((int)frames, - sample_rate); + ng->states[channel] = + speex_preprocess_state_init((int)frames, sample_rate); - circlebuf_reserve(&ng->input_buffers[channel], frames * sizeof(float)); + circlebuf_reserve(&ng->input_buffers[channel], frames * sizeof(float)); circlebuf_reserve(&ng->output_buffers[channel], frames * sizeof(float)); } @@ -119,13 +120,13 @@ static void noise_suppress_update(void *data, obs_data_t *s) /* One speex state for each channel (limit 2) */ ng->copy_buffers[0] = bmalloc(frames * channels * sizeof(float)); - ng->segment_buffers[0] = bmalloc(frames * channels * sizeof(spx_int16_t)); + ng->segment_buffers[0] = + bmalloc(frames * channels * sizeof(spx_int16_t)); for (size_t c = 1; c < channels; ++c) { - ng->copy_buffers[c] = ng->copy_buffers[c-1] + frames; - ng->segment_buffers[c] = ng->segment_buffers[c-1] + frames; + ng->copy_buffers[c] = ng->copy_buffers[c - 1] + frames; + ng->segment_buffers[c] = ng->segment_buffers[c - 1] + frames; } - for (size_t i = 0; i < channels; i++) alloc_channel(ng, sample_rate, i, frames); } @@ -145,22 +146,24 @@ static inline void process(struct noise_suppress_data *ng) /* Pop from input circlebuf */ for (size_t i = 0; i < ng->channels; i++) circlebuf_pop_front(&ng->input_buffers[i], ng->copy_buffers[i], - ng->frames * sizeof(float)); + ng->frames * sizeof(float)); /* Set args */ for (size_t i = 0; i < ng->channels; i++) speex_preprocess_ctl(ng->states[i], - SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, - &ng->suppress_level); + SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, + &ng->suppress_level); /* Convert to 16bit */ for (size_t i = 0; i < ng->channels; i++) for (size_t j = 0; j < ng->frames; j++) { float s = ng->copy_buffers[i][j]; - if (s > 1.0f) s = 1.0f; - else if (s < -1.0f) s = -1.0f; - ng->segment_buffers[i][j] = (spx_int16_t) - (s * c_32_to_16); + if (s > 1.0f) + s = 1.0f; + else if (s < -1.0f) + s = -1.0f; + ng->segment_buffers[i][j] = + (spx_int16_t)(s * c_32_to_16); } /* Execute */ @@ -176,7 +179,7 @@ static inline void process(struct noise_suppress_data *ng) /* Push to output circlebuf */ for (size_t i = 0; i < ng->channels; i++) circlebuf_push_back(&ng->output_buffers[i], ng->copy_buffers[i], - ng->frames * sizeof(float)); + ng->frames * sizeof(float)); } struct ng_audio_info { @@ -199,8 +202,8 @@ static void reset_data(struct noise_suppress_data *ng) clear_circlebuf(&ng->info_buffer); } -static struct obs_audio_data *noise_suppress_filter_audio(void *data, - struct obs_audio_data *audio) +static struct obs_audio_data * +noise_suppress_filter_audio(void *data, struct obs_audio_data *audio) { struct noise_suppress_data *ng = data; struct ng_audio_info info; @@ -216,7 +219,7 @@ static struct obs_audio_data *noise_suppress_filter_audio(void *data, * from being processed as part of the new data. */ if (ng->last_timestamp) { int64_t diff = llabs((int64_t)ng->last_timestamp - - (int64_t)audio->timestamp); + (int64_t)audio->timestamp); if (diff > 1000000000LL) reset_data(ng); @@ -234,7 +237,7 @@ static struct obs_audio_data *noise_suppress_filter_audio(void *data, * push back current audio data to input circlebuf */ for (size_t i = 0; i < ng->channels; i++) circlebuf_push_back(&ng->input_buffers[i], audio->data[i], - audio->frames * sizeof(float)); + audio->frames * sizeof(float)); /* ----------------------------------------------- * pop/process each 10ms segments, push back to output circlebuf */ @@ -259,11 +262,10 @@ static struct obs_audio_data *noise_suppress_filter_audio(void *data, for (size_t i = 0; i < ng->channels; i++) { ng->output_audio.data[i] = - (uint8_t*)&ng->output_data.array[i * out_size]; + (uint8_t *)&ng->output_data.array[i * out_size]; circlebuf_pop_front(&ng->output_buffers[i], - ng->output_audio.data[i], - out_size); + ng->output_audio.data[i], out_size); } ng->output_audio.frames = info.frames; @@ -280,8 +282,11 @@ static obs_properties_t *noise_suppress_properties(void *data) { obs_properties_t *ppts = obs_properties_create(); - obs_properties_add_int_slider(ppts, S_SUPPRESS_LEVEL, - TEXT_SUPPRESS_LEVEL, SUP_MIN, SUP_MAX, 1); + obs_property_t *p = obs_properties_add_int_slider(ppts, + S_SUPPRESS_LEVEL, + TEXT_SUPPRESS_LEVEL, + SUP_MIN, SUP_MAX, 1); + obs_property_int_set_suffix(p, " dB"); UNUSED_PARAMETER(data); return ppts; diff --git a/plugins/obs-filters/scale-filter.c b/plugins/obs-filters/scale-filter.c index c4c4022..59726b7 100644 --- a/plugins/obs-filters/scale-filter.c +++ b/plugins/obs-filters/scale-filter.c @@ -6,6 +6,8 @@ #include #include +/* clang-format off */ + #define S_RESOLUTION "resolution" #define S_SAMPLING "sampling" #define S_UNDISTORT "undistort" @@ -27,25 +29,30 @@ #define S_SAMPLING_LANCZOS "lanczos" #define S_SAMPLING_AREA "area" +/* clang-format on */ + struct scale_filter_data { - obs_source_t *context; - gs_effect_t *effect; - gs_eparam_t *image_param; - gs_eparam_t *dimension_param; - gs_eparam_t *undistort_factor_param; - struct vec2 dimension_i; - double undistort_factor; - int cx_in; - int cy_in; - int cx_out; - int cy_out; - enum obs_scale_type sampling; - gs_samplerstate_t *point_sampler; - bool aspect_ratio_only; - bool target_valid; - bool valid; - bool undistort; - bool base_canvas_resolution; + obs_source_t *context; + gs_effect_t *effect; + gs_eparam_t *image_param; + gs_eparam_t *dimension_param; + gs_eparam_t *dimension_i_param; + gs_eparam_t *undistort_factor_param; + struct vec2 dimension; + struct vec2 dimension_i; + double undistort_factor; + int cx_in; + int cy_in; + int cx_out; + int cy_out; + enum obs_scale_type sampling; + gs_samplerstate_t *point_sampler; + bool aspect_ratio_only; + bool target_valid; + bool valid; + bool undistort; + bool upscale; + bool base_canvas_resolution; }; static const char *scale_filter_name(void *unused) @@ -78,7 +85,7 @@ static void scale_filter_update(void *data, obs_data_t *settings) filter->aspect_ratio_only = false; } else { ret = sscanf(res_str, "%d:%d", &filter->cx_in, - &filter->cy_in); + &filter->cy_in); if (ret != 2) { filter->valid = false; return; @@ -179,8 +186,7 @@ static void scale_filter_tick(void *data, float seconds) cy_f = (double)cy; double old_aspect = cx_f / cy_f; - double new_aspect = - (double)filter->cx_in / (double)filter->cy_in; + double new_aspect = (double)filter->cx_in / (double)filter->cy_in; if (filter->aspect_ratio_only) { if (fabs(old_aspect - new_aspect) <= EPSILON) { @@ -200,9 +206,8 @@ static void scale_filter_tick(void *data, float seconds) filter->cy_out = filter->cy_in; } - vec2_set(&filter->dimension_i, - 1.0f / (float)cx, - 1.0f / (float)cy); + vec2_set(&filter->dimension, (float)cx, (float)cy); + vec2_set(&filter->dimension_i, 1.0f / (float)cx, 1.0f / (float)cy); if (filter->undistort) { filter->undistort_factor = new_aspect / old_aspect; @@ -210,6 +215,8 @@ static void scale_filter_tick(void *data, float seconds) filter->undistort_factor = 1.0; } + filter->upscale = false; + /* ------------------------- */ lower_than_2x = filter->cx_out < cx / 2 || filter->cy_out < cy / 2; @@ -220,29 +227,41 @@ static void scale_filter_tick(void *data, float seconds) switch (filter->sampling) { default: case OBS_SCALE_POINT: - case OBS_SCALE_BILINEAR: type = OBS_EFFECT_DEFAULT; break; - case OBS_SCALE_BICUBIC: type = OBS_EFFECT_BICUBIC; break; - case OBS_SCALE_LANCZOS: type = OBS_EFFECT_LANCZOS; break; - case OBS_SCALE_AREA: type = OBS_EFFECT_AREA; break; + case OBS_SCALE_BILINEAR: + type = OBS_EFFECT_DEFAULT; + break; + case OBS_SCALE_BICUBIC: + type = OBS_EFFECT_BICUBIC; + break; + case OBS_SCALE_LANCZOS: + type = OBS_EFFECT_LANCZOS; + break; + case OBS_SCALE_AREA: + type = OBS_EFFECT_AREA; + if ((filter->cx_out >= cx) && (filter->cy_out >= cy)) + filter->upscale = true; + break; } } filter->effect = obs_get_base_effect(type); - filter->image_param = gs_effect_get_param_by_name(filter->effect, - "image"); + filter->image_param = + gs_effect_get_param_by_name(filter->effect, "image"); if (type != OBS_EFFECT_DEFAULT) { filter->dimension_param = gs_effect_get_param_by_name( - filter->effect, "base_dimension_i"); + filter->effect, "base_dimension"); + filter->dimension_i_param = gs_effect_get_param_by_name( + filter->effect, "base_dimension_i"); } else { filter->dimension_param = NULL; + filter->dimension_i_param = NULL; } if (type == OBS_EFFECT_BICUBIC || type == OBS_EFFECT_LANCZOS) { filter->undistort_factor_param = gs_effect_get_param_by_name( filter->effect, "undistort_factor"); - } - else { + } else { filter->undistort_factor_param = NULL; } @@ -252,8 +271,9 @@ static void scale_filter_tick(void *data, float seconds) static void scale_filter_render(void *data, gs_effect_t *effect) { struct scale_filter_data *filter = data; - const char *technique = filter->undistort ? - "DrawUndistort" : "Draw"; + const char *technique = + filter->undistort ? "DrawUndistort" + : (filter->upscale ? "DrawUpscale" : "Draw"); if (!filter->valid || !filter->target_valid) { obs_source_skip_video_filter(filter->context); @@ -261,75 +281,61 @@ static void scale_filter_render(void *data, gs_effect_t *effect) } if (!obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_NO_DIRECT_RENDERING)) + OBS_NO_DIRECT_RENDERING)) return; if (filter->dimension_param) - gs_effect_set_vec2(filter->dimension_param, - &filter->dimension_i); + gs_effect_set_vec2(filter->dimension_param, &filter->dimension); + + if (filter->dimension_i_param) + gs_effect_set_vec2(filter->dimension_i_param, + &filter->dimension_i); if (filter->undistort_factor_param) gs_effect_set_float(filter->undistort_factor_param, - (float)filter->undistort_factor); + (float)filter->undistort_factor); if (filter->sampling == OBS_SCALE_POINT) gs_effect_set_next_sampler(filter->image_param, - filter->point_sampler); + filter->point_sampler); obs_source_process_filter_tech_end(filter->context, filter->effect, - filter->cx_out, filter->cy_out, technique); + filter->cx_out, filter->cy_out, + technique); UNUSED_PARAMETER(effect); } -static const double downscale_vals[] = { - 1.0, - 1.25, - (1.0/0.75), - 1.5, - (1.0/0.6), - 1.75, - 2.0, - 2.25, - 2.5, - 2.75, - 3.0 -}; +static const double downscale_vals[] = {1.0, 1.25, (1.0 / 0.75), 1.5, + (1.0 / 0.6), 1.75, 2.0, 2.25, + 2.5, 2.75, 3.0}; #define NUM_DOWNSCALES (sizeof(downscale_vals) / sizeof(double)) -static const char *aspects[] = { - "16:9", - "16:10", - "4:3", - "1:1" -}; +static const char *aspects[] = {"16:9", "16:10", "4:3", "1:1"}; #define NUM_ASPECTS (sizeof(aspects) / sizeof(const char *)) static bool sampling_modified(obs_properties_t *props, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { const char *sampling = obs_data_get_string(settings, S_SAMPLING); bool has_undistort; if (astrcmpi(sampling, S_SAMPLING_POINT) == 0) { has_undistort = false; - } - else if (astrcmpi(sampling, S_SAMPLING_BILINEAR) == 0) { + } else if (astrcmpi(sampling, S_SAMPLING_BILINEAR) == 0) { has_undistort = false; - } - else if (astrcmpi(sampling, S_SAMPLING_LANCZOS) == 0) { + } else if (astrcmpi(sampling, S_SAMPLING_LANCZOS) == 0) { has_undistort = true; - } - else if (astrcmpi(sampling, S_SAMPLING_AREA) == 0) { + } else if (astrcmpi(sampling, S_SAMPLING_AREA) == 0) { has_undistort = false; - } - else { /* S_SAMPLING_BICUBIC */ + } else { /* S_SAMPLING_BICUBIC */ has_undistort = true; } - obs_property_set_visible(obs_properties_get(props, S_UNDISTORT), has_undistort); + obs_property_set_visible(obs_properties_get(props, S_UNDISTORT), + has_undistort); UNUSED_PARAMETER(p); return true; @@ -360,18 +366,21 @@ static obs_properties_t *scale_filter_properties(void *data) } p = obs_properties_add_list(props, S_SAMPLING, T_SAMPLING, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_set_modified_callback(p, sampling_modified); - obs_property_list_add_string(p, T_SAMPLING_POINT, S_SAMPLING_POINT); - obs_property_list_add_string(p, T_SAMPLING_BILINEAR, S_SAMPLING_BILINEAR); - obs_property_list_add_string(p, T_SAMPLING_BICUBIC, S_SAMPLING_BICUBIC); - obs_property_list_add_string(p, T_SAMPLING_LANCZOS, S_SAMPLING_LANCZOS); - obs_property_list_add_string(p, T_SAMPLING_AREA, S_SAMPLING_AREA); + obs_property_list_add_string(p, T_SAMPLING_POINT, S_SAMPLING_POINT); + obs_property_list_add_string(p, T_SAMPLING_BILINEAR, + S_SAMPLING_BILINEAR); + obs_property_list_add_string(p, T_SAMPLING_BICUBIC, S_SAMPLING_BICUBIC); + obs_property_list_add_string(p, T_SAMPLING_LANCZOS, S_SAMPLING_LANCZOS); + obs_property_list_add_string(p, T_SAMPLING_AREA, S_SAMPLING_AREA); /* ----------------- */ p = obs_properties_add_list(props, S_RESOLUTION, T_RESOLUTION, - OBS_COMBO_TYPE_EDITABLE, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_EDITABLE, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, T_NONE, T_NONE); obs_property_list_add_string(p, T_BASE, T_BASE); @@ -413,17 +422,17 @@ static uint32_t scale_filter_height(void *data) } struct obs_source_info scale_filter = { - .id = "scale_filter", - .type = OBS_SOURCE_TYPE_FILTER, - .output_flags = OBS_SOURCE_VIDEO, - .get_name = scale_filter_name, - .create = scale_filter_create, - .destroy = scale_filter_destroy, - .video_tick = scale_filter_tick, - .video_render = scale_filter_render, - .update = scale_filter_update, - .get_properties = scale_filter_properties, - .get_defaults = scale_filter_defaults, - .get_width = scale_filter_width, - .get_height = scale_filter_height + .id = "scale_filter", + .type = OBS_SOURCE_TYPE_FILTER, + .output_flags = OBS_SOURCE_VIDEO, + .get_name = scale_filter_name, + .create = scale_filter_create, + .destroy = scale_filter_destroy, + .video_tick = scale_filter_tick, + .video_render = scale_filter_render, + .update = scale_filter_update, + .get_properties = scale_filter_properties, + .get_defaults = scale_filter_defaults, + .get_width = scale_filter_width, + .get_height = scale_filter_height, }; diff --git a/plugins/obs-filters/scroll-filter.c b/plugins/obs-filters/scroll-filter.c index 9ff361f..c316fa8 100644 --- a/plugins/obs-filters/scroll-filter.c +++ b/plugins/obs-filters/scroll-filter.c @@ -2,22 +2,22 @@ #include struct scroll_filter_data { - obs_source_t *context; + obs_source_t *context; - gs_effect_t *effect; - gs_eparam_t *param_add; - gs_eparam_t *param_mul; - gs_eparam_t *param_image; + gs_effect_t *effect; + gs_eparam_t *param_add; + gs_eparam_t *param_mul; + gs_eparam_t *param_image; - struct vec2 scroll_speed; - gs_samplerstate_t *sampler; - bool limit_cx; - bool limit_cy; - uint32_t cx; - uint32_t cy; + struct vec2 scroll_speed; + gs_samplerstate_t *sampler; + bool limit_cx; + bool limit_cy; + uint32_t cx; + uint32_t cy; - struct vec2 size_i; - struct vec2 offset; + struct vec2 size_i; + struct vec2 offset; }; static const char *scroll_filter_get_name(void *unused) @@ -31,11 +31,9 @@ static void *scroll_filter_create(obs_data_t *settings, obs_source_t *context) struct scroll_filter_data *filter = bzalloc(sizeof(*filter)); char *effect_path = obs_module_file("crop_filter.effect"); - struct gs_sampler_info sampler_info = { - .filter = GS_FILTER_LINEAR, - .address_u = GS_ADDRESS_WRAP, - .address_v = GS_ADDRESS_WRAP - }; + struct gs_sampler_info sampler_info = {.filter = GS_FILTER_LINEAR, + .address_u = GS_ADDRESS_WRAP, + .address_v = GS_ADDRESS_WRAP}; filter->context = context; @@ -51,12 +49,12 @@ static void *scroll_filter_create(obs_data_t *settings, obs_source_t *context) return NULL; } - filter->param_add = gs_effect_get_param_by_name(filter->effect, - "add_val"); - filter->param_mul = gs_effect_get_param_by_name(filter->effect, - "mul_val"); - filter->param_image = gs_effect_get_param_by_name(filter->effect, - "image"); + filter->param_add = + gs_effect_get_param_by_name(filter->effect, "add_val"); + filter->param_mul = + gs_effect_get_param_by_name(filter->effect, "mul_val"); + filter->param_image = + gs_effect_get_param_by_name(filter->effect, "image"); obs_source_update(context, settings); return filter; @@ -83,10 +81,10 @@ static void scroll_filter_update(void *data, obs_data_t *settings) filter->cx = (uint32_t)obs_data_get_int(settings, "cx"); filter->cy = (uint32_t)obs_data_get_int(settings, "cy"); - filter->scroll_speed.x = (float)obs_data_get_double(settings, - "speed_x"); - filter->scroll_speed.y = (float)obs_data_get_double(settings, - "speed_y"); + filter->scroll_speed.x = + (float)obs_data_get_double(settings, "speed_x"); + filter->scroll_speed.y = + (float)obs_data_get_double(settings, "speed_y"); if (filter->scroll_speed.x == 0.0f) filter->offset.x = 0.0f; @@ -95,7 +93,7 @@ static void scroll_filter_update(void *data, obs_data_t *settings) } static bool limit_cx_clicked(obs_properties_t *props, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { bool limit_size = obs_data_get_bool(settings, "limit_cx"); obs_property_set_visible(obs_properties_get(props, "cx"), limit_size); @@ -105,7 +103,7 @@ static bool limit_cx_clicked(obs_properties_t *props, obs_property_t *p, } static bool limit_cy_clicked(obs_properties_t *props, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { bool limit_size = obs_data_get_bool(settings, "limit_cy"); obs_property_set_visible(obs_properties_get(props, "cy"), limit_size); @@ -120,23 +118,23 @@ static obs_properties_t *scroll_filter_properties(void *data) obs_property_t *p; obs_properties_add_float_slider(props, "speed_x", - obs_module_text("ScrollFilter.SpeedX"), - -500.0, 500.0, 1.0); + obs_module_text("ScrollFilter.SpeedX"), + -500.0, 500.0, 1.0); obs_properties_add_float_slider(props, "speed_y", - obs_module_text("ScrollFilter.SpeedY"), - -500.0, 500.0, 1.0); + obs_module_text("ScrollFilter.SpeedY"), + -500.0, 500.0, 1.0); p = obs_properties_add_bool(props, "limit_cx", - obs_module_text("ScrollFilter.LimitWidth")); + obs_module_text("ScrollFilter.LimitWidth")); obs_property_set_modified_callback(p, limit_cx_clicked); - obs_properties_add_int(props, "cx", - obs_module_text("Crop.Width"), 1, 8192, 1); + obs_properties_add_int(props, "cx", obs_module_text("Crop.Width"), 1, + 8192, 1); - p = obs_properties_add_bool(props, "limit_cy", - obs_module_text("ScrollFilter.LimitHeight")); + p = obs_properties_add_bool( + props, "limit_cy", obs_module_text("ScrollFilter.LimitHeight")); obs_property_set_modified_callback(p, limit_cy_clicked); - obs_properties_add_int(props, "cy", - obs_module_text("Crop.Height"), 1, 8192, 1); + obs_properties_add_int(props, "cy", obs_module_text("Crop.Height"), 1, + 8192, 1); UNUSED_PARAMETER(data); return props; @@ -179,21 +177,19 @@ static void scroll_filter_render(void *data, gs_effect_t *effect) cy = filter->limit_cy ? filter->cy : base_cy; if (base_cx && base_cy) { - vec2_set(&filter->size_i, - 1.0f / (float)base_cx, - 1.0f / (float)base_cy); + vec2_set(&filter->size_i, 1.0f / (float)base_cx, + 1.0f / (float)base_cy); } else { vec2_zero(&filter->size_i); obs_source_skip_video_filter(filter->context); return; } - vec2_set(&mul_val, - (float)cx / (float)base_cx, - (float)cy / (float)base_cy); + vec2_set(&mul_val, (float)cx / (float)base_cx, + (float)cy / (float)base_cy); if (!obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_NO_DIRECT_RENDERING)) + OBS_NO_DIRECT_RENDERING)) return; gs_effect_set_vec2(filter->param_add, &filter->offset); @@ -211,8 +207,8 @@ static uint32_t scroll_filter_width(void *data) struct scroll_filter_data *filter = data; obs_source_t *target = obs_filter_get_target(filter->context); - return filter->limit_cx ? - filter->cx : obs_source_get_base_width(target); + return filter->limit_cx ? filter->cx + : obs_source_get_base_width(target); } static uint32_t scroll_filter_height(void *data) @@ -220,22 +216,22 @@ static uint32_t scroll_filter_height(void *data) struct scroll_filter_data *filter = data; obs_source_t *target = obs_filter_get_target(filter->context); - return filter->limit_cy ? - filter->cy : obs_source_get_base_height(target); + return filter->limit_cy ? filter->cy + : obs_source_get_base_height(target); } struct obs_source_info scroll_filter = { - .id = "scroll_filter", - .type = OBS_SOURCE_TYPE_FILTER, - .output_flags = OBS_SOURCE_VIDEO, - .get_name = scroll_filter_get_name, - .create = scroll_filter_create, - .destroy = scroll_filter_destroy, - .update = scroll_filter_update, - .get_properties = scroll_filter_properties, - .get_defaults = scroll_filter_defaults, - .video_tick = scroll_filter_tick, - .video_render = scroll_filter_render, - .get_width = scroll_filter_width, - .get_height = scroll_filter_height + .id = "scroll_filter", + .type = OBS_SOURCE_TYPE_FILTER, + .output_flags = OBS_SOURCE_VIDEO, + .get_name = scroll_filter_get_name, + .create = scroll_filter_create, + .destroy = scroll_filter_destroy, + .update = scroll_filter_update, + .get_properties = scroll_filter_properties, + .get_defaults = scroll_filter_defaults, + .video_tick = scroll_filter_tick, + .video_render = scroll_filter_render, + .get_width = scroll_filter_width, + .get_height = scroll_filter_height, }; diff --git a/plugins/obs-filters/sharpness-filter.c b/plugins/obs-filters/sharpness-filter.c index 5269614..a445074 100644 --- a/plugins/obs-filters/sharpness-filter.c +++ b/plugins/obs-filters/sharpness-filter.c @@ -4,14 +4,14 @@ #include struct sharpness_data { - obs_source_t *context; + obs_source_t *context; - gs_effect_t *effect; - gs_eparam_t *sharpness_param; - gs_eparam_t *texture_width, *texture_height; + gs_effect_t *effect; + gs_eparam_t *sharpness_param; + gs_eparam_t *texture_width, *texture_height; - float sharpness; - float texwidth, texheight; + float sharpness; + float texwidth, texheight; }; static const char *sharpness_getname(void *unused) @@ -43,8 +43,7 @@ static void sharpness_destroy(void *data) static void *sharpness_create(obs_data_t *settings, obs_source_t *context) { - struct sharpness_data *filter = - bzalloc(sizeof(struct sharpness_data)); + struct sharpness_data *filter = bzalloc(sizeof(struct sharpness_data)); char *effect_path = obs_module_file("sharpness.effect"); filter->context = context; @@ -79,13 +78,13 @@ static void sharpness_render(void *data, gs_effect_t *effect) struct sharpness_data *filter = data; if (!obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING)) + OBS_ALLOW_DIRECT_RENDERING)) return; - filter->texwidth =(float)obs_source_get_width( - obs_filter_get_target(filter->context)); + filter->texwidth = (float)obs_source_get_width( + obs_filter_get_target(filter->context)); filter->texheight = (float)obs_source_get_height( - obs_filter_get_target(filter->context)); + obs_filter_get_target(filter->context)); gs_effect_set_float(filter->sharpness_param, filter->sharpness); gs_effect_set_float(filter->texture_width, filter->texwidth); @@ -100,8 +99,8 @@ static obs_properties_t *sharpness_properties(void *data) { obs_properties_t *props = obs_properties_create(); - obs_properties_add_float_slider(props, "sharpness", - "Sharpness", 0.0, 1.0, 0.01); + obs_properties_add_float_slider(props, "sharpness", "Sharpness", 0.0, + 1.0, 0.01); UNUSED_PARAMETER(data); return props; @@ -122,5 +121,5 @@ struct obs_source_info sharpness_filter = { .update = sharpness_update, .video_render = sharpness_render, .get_properties = sharpness_properties, - .get_defaults = sharpness_defaults + .get_defaults = sharpness_defaults, }; diff --git a/plugins/obs-libfdk/data/locale/bg-BG.ini b/plugins/obs-libfdk/data/locale/bg-BG.ini new file mode 100644 index 0000000..b057350 --- /dev/null +++ b/plugins/obs-libfdk/data/locale/bg-BG.ini @@ -0,0 +1,4 @@ +LibFDK="кодер AAC (libfdk)" +Bitrate="Битрейт" +Afterburner="Включване на AAC Afterburner" + diff --git a/plugins/obs-libfdk/data/locale/de-DE.ini b/plugins/obs-libfdk/data/locale/de-DE.ini index 6092b11..c9266e1 100644 --- a/plugins/obs-libfdk/data/locale/de-DE.ini +++ b/plugins/obs-libfdk/data/locale/de-DE.ini @@ -1,4 +1,4 @@ -LibFDK="libfdk-AAC-Kodierer" +LibFDK="libfdk‐AAC‐Kodierer" Bitrate="Bitrate" -Afterburner="AAC-Afterburner aktivieren" +Afterburner="AAC‐Afterburner aktivieren" diff --git a/plugins/obs-libfdk/data/locale/gl-ES.ini b/plugins/obs-libfdk/data/locale/gl-ES.ini index a33cfa2..ce6aa95 100644 --- a/plugins/obs-libfdk/data/locale/gl-ES.ini +++ b/plugins/obs-libfdk/data/locale/gl-ES.ini @@ -1,4 +1,4 @@ LibFDK="Codificador AAC libfdk" -Bitrate="Velocidade de bits" -Afterburner="Habilitar AAC Afterburner" +Bitrate="Taxa de bits" +Afterburner="Activar AAC Afterburner" diff --git a/plugins/obs-libfdk/data/locale/sl-SI.ini b/plugins/obs-libfdk/data/locale/sl-SI.ini index aa6a27a..d845ba5 100644 --- a/plugins/obs-libfdk/data/locale/sl-SI.ini +++ b/plugins/obs-libfdk/data/locale/sl-SI.ini @@ -1,4 +1,4 @@ -LibFDK="libfdk AAC Encoder" -Bitrate="Bitrate" +LibFDK="Kodirnik AAC libfdk" +Bitrate="Bitna hitrost" Afterburner="Uporabi AAC Afterburner" diff --git a/plugins/obs-libfdk/obs-libfdk.c b/plugins/obs-libfdk/obs-libfdk.c index 94b139d..234ca0e 100644 --- a/plugins/obs-libfdk/obs-libfdk.c +++ b/plugins/obs-libfdk/obs-libfdk.c @@ -1,17 +1,17 @@ #include #ifdef DEBUG -# ifndef _DEBUG -# define _DEBUG -# endif -# undef DEBUG +#ifndef _DEBUG +#define _DEBUG +#endif +#undef DEBUG #endif #include static const char *libfdk_get_error(AACENC_ERROR err) { - switch(err) { + switch (err) { case AACENC_OK: return "No error"; case AACENC_INVALID_HANDLE: @@ -41,7 +41,6 @@ static const char *libfdk_get_error(AACENC_ERROR err) } } - typedef struct libfdk_encoder { obs_encoder_t *encoder; @@ -70,10 +69,10 @@ static obs_properties_t *libfdk_properties(void *unused) obs_properties_t *props = obs_properties_create(); - obs_properties_add_int(props, "bitrate", - obs_module_text("Bitrate"), 32, 1024, 32); + obs_properties_add_int(props, "bitrate", obs_module_text("Bitrate"), 32, + 1024, 32); obs_properties_add_bool(props, "afterburner", - obs_module_text("Afterburner")); + obs_module_text("Afterburner")); return props; } @@ -84,10 +83,10 @@ static void libfdk_defaults(obs_data_t *settings) obs_data_set_default_bool(settings, "afterburner", true); } -#define CHECK_LIBFDK(r) \ - if((err = (r)) != AACENC_OK) { \ +#define CHECK_LIBFDK(r) \ + if ((err = (r)) != AACENC_OK) { \ blog(LOG_ERROR, #r " failed: %s", libfdk_get_error(err)); \ - goto fail; \ + goto fail; \ } static void *libfdk_create(obs_data_t *settings, obs_encoder_t *encoder) @@ -111,7 +110,7 @@ static void *libfdk_create(obs_data_t *settings, obs_encoder_t *encoder) enc->channels = (int)audio_output_get_channels(audio); enc->sample_rate = audio_output_get_sample_rate(audio); - switch(enc->channels) { + switch (enc->channels) { case 1: mode = MODE_1; break; @@ -131,7 +130,7 @@ static void *libfdk_create(obs_data_t *settings, obs_encoder_t *encoder) mode = MODE_1_2_2_1; break; - /* lib_fdk-aac > 1.3 required for 7.1 surround; + /* lib_fdk-aac > 1.3 required for 7.1 surround; * uncomment if available on linux build */ #ifndef __linux__ @@ -149,16 +148,20 @@ static void *libfdk_create(obs_data_t *settings, obs_encoder_t *encoder) hasFdkHandle = true; CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_AOT, - 2)); // MPEG-4 AAC-LC + 2)); // MPEG-4 AAC-LC CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_SAMPLERATE, - enc->sample_rate)); - CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_CHANNELMODE, mode)); - CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_CHANNELORDER, 1)); - CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_BITRATEMODE, 0)); - CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_BITRATE, bitrate)); + enc->sample_rate)); + CHECK_LIBFDK( + aacEncoder_SetParam(enc->fdkhandle, AACENC_CHANNELMODE, mode)); + CHECK_LIBFDK( + aacEncoder_SetParam(enc->fdkhandle, AACENC_CHANNELORDER, 1)); + CHECK_LIBFDK( + aacEncoder_SetParam(enc->fdkhandle, AACENC_BITRATEMODE, 0)); + CHECK_LIBFDK( + aacEncoder_SetParam(enc->fdkhandle, AACENC_BITRATE, bitrate)); CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_TRANSMUX, 0)); CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_AFTERBURNER, - afterburner)); + afterburner)); CHECK_LIBFDK(aacEncEncode(enc->fdkhandle, NULL, NULL, NULL, NULL)); @@ -167,27 +170,27 @@ static void *libfdk_create(obs_data_t *settings, obs_encoder_t *encoder) enc->frame_size_bytes = enc->info.frameLength * 2 * enc->channels; enc->packet_buffer_size = enc->channels * 768; - if(enc->packet_buffer_size < 8192) + if (enc->packet_buffer_size < 8192) enc->packet_buffer_size = 8192; enc->packet_buffer = bmalloc(enc->packet_buffer_size); blog(LOG_INFO, "libfdk_aac encoder created"); - blog(LOG_INFO, "libfdk_aac bitrate: %d, channels: %d", - bitrate / 1000, enc->channels); + blog(LOG_INFO, "libfdk_aac bitrate: %d, channels: %d", bitrate / 1000, + enc->channels); return enc; fail: - if(hasFdkHandle) + if (hasFdkHandle) aacEncClose(&enc->fdkhandle); - if(enc->packet_buffer) + if (enc->packet_buffer) bfree(enc->packet_buffer); - if(enc) + if (enc) bfree(enc); blog(LOG_WARNING, "libfdk_aac encoder creation failed"); @@ -208,14 +211,14 @@ static void libfdk_destroy(void *data) } static bool libfdk_encode(void *data, struct encoder_frame *frame, - struct encoder_packet *packet, bool *received_packet) + struct encoder_packet *packet, bool *received_packet) { libfdk_encoder_t *enc = data; - AACENC_BufDesc in_buf = { 0 }; - AACENC_BufDesc out_buf = { 0 }; - AACENC_InArgs in_args = { 0 }; - AACENC_OutArgs out_args = { 0 }; + AACENC_BufDesc in_buf = {0}; + AACENC_BufDesc out_buf = {0}; + AACENC_InArgs in_args = {0}; + AACENC_OutArgs out_args = {0}; int in_identifier = IN_AUDIO_DATA; int in_size, in_elem_size; int out_identifier = OUT_BITSTREAM_DATA; @@ -246,27 +249,28 @@ static bool libfdk_encode(void *data, struct encoder_frame *frame, out_buf.bufSizes = &out_size; out_buf.bufElSizes = &out_elem_size; - if((err = aacEncEncode(enc->fdkhandle, &in_buf, &out_buf, &in_args, - &out_args)) != AACENC_OK) { - blog(LOG_ERROR, "Failed to encode frame: %s", libfdk_get_error(err)); + if ((err = aacEncEncode(enc->fdkhandle, &in_buf, &out_buf, &in_args, + &out_args)) != AACENC_OK) { + blog(LOG_ERROR, "Failed to encode frame: %s", + libfdk_get_error(err)); return false; } enc->total_samples += enc->info.frameLength; - if(out_args.numOutBytes == 0) { + if (out_args.numOutBytes == 0) { *received_packet = false; return true; } *received_packet = true; #if (AACENCODER_LIB_VL0 >= 4) - encoderDelay= enc->info.nDelay; + encoderDelay = enc->info.nDelay; #else - encoderDelay= enc->info.encoderDelay; + encoderDelay = enc->info.encoderDelay; #endif - packet->pts = enc->total_samples - encoderDelay; - packet->dts = enc->total_samples - encoderDelay; + packet->pts = enc->total_samples - encoderDelay; + packet->dts = enc->total_samples - encoderDelay; packet->data = enc->packet_buffer; packet->size = out_args.numOutBytes; packet->type = OBS_ENCODER_AUDIO; @@ -300,18 +304,18 @@ static size_t libfdk_frame_size(void *data) } struct obs_encoder_info obs_libfdk_encoder = { - .id = "libfdk_aac", - .type = OBS_ENCODER_AUDIO, - .codec = "AAC", - .get_name = libfdk_getname, - .create = libfdk_create, - .destroy = libfdk_destroy, - .encode = libfdk_encode, + .id = "libfdk_aac", + .type = OBS_ENCODER_AUDIO, + .codec = "AAC", + .get_name = libfdk_getname, + .create = libfdk_create, + .destroy = libfdk_destroy, + .encode = libfdk_encode, .get_frame_size = libfdk_frame_size, - .get_defaults = libfdk_defaults, + .get_defaults = libfdk_defaults, .get_properties = libfdk_properties, .get_extra_data = libfdk_extra_data, - .get_audio_info = libfdk_audio_info + .get_audio_info = libfdk_audio_info, }; bool obs_module_load(void) diff --git a/plugins/obs-outputs/data/locale/de-DE.ini b/plugins/obs-outputs/data/locale/de-DE.ini index e332a7a..52cdeff 100644 --- a/plugins/obs-outputs/data/locale/de-DE.ini +++ b/plugins/obs-outputs/data/locale/de-DE.ini @@ -1,15 +1,15 @@ -RTMPStream="RTMP-Stream" -RTMPStream.DropThreshold="Drop-Threshold (Millisekunden)" -FLVOutput="FLV-Dateiausgabe" +RTMPStream="RTMP‐Stream" +RTMPStream.DropThreshold="Drop‐Threshold (Millisekunden)" +FLVOutput="FLV‐Dateiausgabe" FLVOutput.FilePath="Dateipfad" Default="Standard" ConnectionTimedOut="Zeitüberschreitung bei der Verbindung. Stellen Sie sicher, dass Sie einen gültigen Streamingdienst konfiguriert haben und keine Firewall die Verbindung blockiert." -PermissionDenied="Die Verbindung wurde blockiert. Überprüfen Sie Ihre Firewall / Anti-Virus-Einstellungen, um sicherzustellen, dass OBS vollen Internetzugang hat." +PermissionDenied="Die Verbindung wurde blockiert. Überprüfen Sie Ihre Firewall‐/Anti‐Virus‐Einstellungen, um sicherzustellen, dass OBS vollen Internetzugang hat." ConnectionAborted="Die Verbindung wurde abgebrochen. Dies bedeutet in der Regel Probleme mit der Internetverbindung zwischen Ihnen und dem Streamingdienst." ConnectionReset="Die Verbindung wurde durch Kommunikationspartner zurückgesetzt. Dies bedeutet in der Regel Probleme mit der Internetverbindung zwischen Ihnen und dem Streamingdienst." HostNotFound="Hostname nicht gefunden. Stellen Sie sicher, dass Sie einen gültigen Streamingserver eingegeben haben und Ihre Internetverbindung/DNS korrekt arbeiten." -NoData="Hostname gefunden, aber keine Daten des angeforderten Typs vorhanden. Dies kann auftreten, wenn Sie eine IPv6-Adresse verwenden, aber Ihr Streamingdienst nur über IPv4-Adressen verfügt (siehe Einstellungen → Erweitert)." -AddressNotAvailable="Adresse nicht verfügbar. Sie haben möglicherweise eine ungültige IP-Adresse versucht zu verwenden (siehe Einstellungen → Erweitert)." -SSLCertVerifyFailed="Der RTMP-Server hat ein ungültiges SSL-Zertifikat gesendet." +NoData="Hostname gefunden, aber keine Daten des angeforderten Typs vorhanden. Dies kann auftreten, wenn Sie eine IPv6‐Adresse verwenden, aber Ihr Streamingdienst nur über IPv4‐Adressen verfügt (siehe Einstellungen → Erweitert)." +AddressNotAvailable="Adresse nicht verfügbar. Sie haben möglicherweise eine ungültige IP‐Adresse versucht zu verwenden (siehe Einstellungen → Erweitert)." +SSLCertVerifyFailed="Der RTMP‐Server hat ein ungültiges SSL‐Zertifikat gesendet." diff --git a/plugins/obs-outputs/data/locale/fa-IR.ini b/plugins/obs-outputs/data/locale/fa-IR.ini new file mode 100644 index 0000000..127de09 --- /dev/null +++ b/plugins/obs-outputs/data/locale/fa-IR.ini @@ -0,0 +1,4 @@ +FLVOutput.FilePath="مسر پرونده" +Default="پیش فرض" + + diff --git a/plugins/obs-outputs/data/locale/gl-ES.ini b/plugins/obs-outputs/data/locale/gl-ES.ini index bc89bf0..a48b4d5 100644 --- a/plugins/obs-outputs/data/locale/gl-ES.ini +++ b/plugins/obs-outputs/data/locale/gl-ES.ini @@ -1,6 +1,15 @@ -RTMPStream="Retransmisión RTMP" -RTMPStream.DropThreshold="Limiar (milisegundos)" +RTMPStream="Emisión RTMP" +RTMPStream.DropThreshold="Limiar de caída (milisegundos)" FLVOutput="Ficheiro de saída FLV" -FLVOutput.FilePath="Camiño do ficheiro" +FLVOutput.FilePath="Ruta do ficheiro" +Default="Predeterminado" +ConnectionTimedOut="A conexión esgotou o tempo Asegúrese de que configurou un servizo de emisións válido e de que ningunha devasa bloquee a conexión." +PermissionDenied="A conexión bloqueouse. Verifique a súa configuración de devasa / antivirus para asegurarse de que OBS ten acceso total a Internet." +ConnectionAborted="A conexión foi interrompida. Isto xeralmente indica problemas de conexión a Internet entre vostede e o servizo de emisións." +ConnectionReset="A conexión foi restabelecida polo par. Isto xeralmente indica problemas de conexión a Internet entre vostede e o servizo de emisións." +HostNotFound="Non se atopou o nome do servidor. Asegúrese de que introduciu un servidor de emisións válido e que a súa conexión a Internet / DNS funcionan correctamente." +NoData="Atopouse o nome do servidor, mais non hai datos do tipo solicitado. Isto pode ocorrer se está vinculado a un enderezo IPv6 e o ​​seu servizo de emisións só ten enderezos IPv4 (ver Axustes → Avanzado)." +AddressNotAvailable="Enderezo non dispoñíbel. É posíbel que tentase ligar a un enderezo IP non válido (ver Axustes → Avanzado)." +SSLCertVerifyFailed="O servidor RTMP enviou un certificado SSL non válido." diff --git a/plugins/obs-outputs/data/locale/sl-SI.ini b/plugins/obs-outputs/data/locale/sl-SI.ini index 2451f6d..9ed33dd 100644 --- a/plugins/obs-outputs/data/locale/sl-SI.ini +++ b/plugins/obs-outputs/data/locale/sl-SI.ini @@ -1,6 +1,15 @@ -RTMPStream="RTMP Oddajanje" -RTMPStream.DropThreshold="Raven Padca (milisekunde)" +RTMPStream="Pretok RTMP" +RTMPStream.DropThreshold="Prag padca (ms)" FLVOutput="Izhod datoteke FLV" FLVOutput.FilePath="Pot datoteke" +Default="Privzeto" +ConnectionTimedOut="Povezava je potekla. Prepričajte se, da ste nastavili veljavno storitev za pretakanje in da požarni zid ne blokira povezave." +PermissionDenied="Povezava je bila blokirana. Preverite nastavitve požarnega zidu/protivirusnega programa in se prepričajte, da ima OBS poln dostop do interneta." +ConnectionAborted="Povezava je bila prekinjena. To običajno pomeni, da imate težave z internetno povezavo med vami in storitvijo za pretakanje." +ConnectionReset="Soležnik je ponastavil povezavo. To običajno pomeni, da imate težave z internetno povezavo med vami in storitvijo za pretakanje." +HostNotFound="Imena gostitelja ni bilo mogoče najti. Prepričajte se, da ste vnesli veljaven strežnik za pretakanje in da vaša internetna povezava/DNS pravilno delujeta." +NoData="Ime gostitelja je bilo najdeno, vendar ni podatkov zahtevane vrste. To se lahko zgodi, če ste se vezali na naslov IPv6, vaša storitev za pretakanje pa ima samo naslove IPv4 (glejte Nastavitve → Napredno)." +AddressNotAvailable="Naslov ni na voljo. Morda ste se poizkusili vezati na neveljaven naslov IP (glejte Nastavitve → Napredno)." +SSLCertVerifyFailed="Strežnik RMTP je poslal neveljavno potrdilo SSL." diff --git a/plugins/obs-outputs/flv-mux.c b/plugins/obs-outputs/flv-mux.c index b1b2512..011fd24 100644 --- a/plugins/obs-outputs/flv-mux.c +++ b/plugins/obs-outputs/flv-mux.c @@ -56,16 +56,16 @@ void write_file_info(FILE *file, int64_t duration_ms, int64_t size) fwrite(buf, 1, enc - buf, file); } -static bool build_flv_meta_data(obs_output_t *context, - uint8_t **output, size_t *size, size_t a_idx) +static bool build_flv_meta_data(obs_output_t *context, uint8_t **output, + size_t *size, size_t a_idx) { obs_encoder_t *vencoder = obs_output_get_video_encoder(context); obs_encoder_t *aencoder = obs_output_get_audio_encoder(context, a_idx); - video_t *video = obs_encoder_video(vencoder); - audio_t *audio = obs_encoder_audio(aencoder); + video_t *video = obs_encoder_video(vencoder); + audio_t *audio = obs_encoder_audio(aencoder); char buf[4096]; char *enc = buf; - char *end = enc+sizeof(buf); + char *end = enc + sizeof(buf); struct dstr encoder_name = {0}; if (a_idx > 0 && !aencoder) @@ -74,57 +74,48 @@ static bool build_flv_meta_data(obs_output_t *context, enc_str(&enc, end, "onMetaData"); *enc++ = AMF_ECMA_ARRAY; - enc = AMF_EncodeInt32(enc, end, a_idx == 0 ? 20 : 15); + enc = AMF_EncodeInt32(enc, end, a_idx == 0 ? 20 : 15); enc_num_val(&enc, end, "duration", 0.0); enc_num_val(&enc, end, "fileSize", 0.0); if (a_idx == 0) { enc_num_val(&enc, end, "width", - (double)obs_encoder_get_width(vencoder)); + (double)obs_encoder_get_width(vencoder)); enc_num_val(&enc, end, "height", - (double)obs_encoder_get_height(vencoder)); + (double)obs_encoder_get_height(vencoder)); enc_str_val(&enc, end, "videocodecid", "avc1"); enc_num_val(&enc, end, "videodatarate", - encoder_bitrate(vencoder)); + encoder_bitrate(vencoder)); enc_num_val(&enc, end, "framerate", - video_output_get_frame_rate(video)); + video_output_get_frame_rate(video)); } enc_str_val(&enc, end, "audiocodecid", "mp4a"); enc_num_val(&enc, end, "audiodatarate", encoder_bitrate(aencoder)); enc_num_val(&enc, end, "audiosamplerate", - (double)obs_encoder_get_sample_rate(aencoder)); + (double)obs_encoder_get_sample_rate(aencoder)); enc_num_val(&enc, end, "audiosamplesize", 16.0); enc_num_val(&enc, end, "audiochannels", - (double)audio_output_get_channels(audio)); + (double)audio_output_get_channels(audio)); enc_bool_val(&enc, end, "stereo", - audio_output_get_channels(audio) == 2); - enc_bool_val(&enc, end, "2.1", - audio_output_get_channels(audio) == 3); - enc_bool_val(&enc, end, "3.1", - audio_output_get_channels(audio) == 4); - enc_bool_val(&enc, end, "4.0", - audio_output_get_channels(audio) == 4); - enc_bool_val(&enc, end, "4.1", - audio_output_get_channels(audio) == 5); - enc_bool_val(&enc, end, "5.1", - audio_output_get_channels(audio) == 6); - enc_bool_val(&enc, end, "7.1", - audio_output_get_channels(audio) == 8); + audio_output_get_channels(audio) == 2); + enc_bool_val(&enc, end, "2.1", audio_output_get_channels(audio) == 3); + enc_bool_val(&enc, end, "3.1", audio_output_get_channels(audio) == 4); + enc_bool_val(&enc, end, "4.0", audio_output_get_channels(audio) == 4); + enc_bool_val(&enc, end, "4.1", audio_output_get_channels(audio) == 5); + enc_bool_val(&enc, end, "5.1", audio_output_get_channels(audio) == 6); + enc_bool_val(&enc, end, "7.1", audio_output_get_channels(audio) == 8); - dstr_printf(&encoder_name, "%s (libobs version ", - MODULE_NAME); + dstr_printf(&encoder_name, "%s (libobs version ", MODULE_NAME); #ifdef HAVE_OBSCONFIG_H dstr_cat(&encoder_name, OBS_VERSION); #else - dstr_catf(&encoder_name, "%d.%d.%d", - LIBOBS_API_MAJOR_VER, - LIBOBS_API_MINOR_VER, - LIBOBS_API_PATCH_VER); + dstr_catf(&encoder_name, "%d.%d.%d", LIBOBS_API_MAJOR_VER, + LIBOBS_API_MINOR_VER, LIBOBS_API_PATCH_VER); #endif dstr_cat(&encoder_name, ")"); @@ -132,28 +123,28 @@ static bool build_flv_meta_data(obs_output_t *context, enc_str_val(&enc, end, "encoder", encoder_name.array); dstr_free(&encoder_name); - *enc++ = 0; - *enc++ = 0; - *enc++ = AMF_OBJECT_END; + *enc++ = 0; + *enc++ = 0; + *enc++ = AMF_OBJECT_END; - *size = enc-buf; + *size = enc - buf; *output = bmemdup(buf, *size); return true; } bool flv_meta_data(obs_output_t *context, uint8_t **output, size_t *size, - bool write_header, size_t audio_idx) + bool write_header, size_t audio_idx) { struct array_output_data data; struct serializer s; uint8_t *meta_data = NULL; - size_t meta_data_size; + size_t meta_data_size; uint32_t start_pos; array_output_serializer_init(&s, &data); if (!build_flv_meta_data(context, &meta_data, &meta_data_size, - audio_idx)) { + audio_idx)) { bfree(meta_data); return false; } @@ -179,7 +170,7 @@ bool flv_meta_data(obs_output_t *context, uint8_t **output, size_t *size, s_wb32(&s, (uint32_t)serializer_get_pos(&s) - start_pos - 1); *output = data.bytes.array; - *size = data.bytes.num; + *size = data.bytes.num; bfree(meta_data); return true; @@ -190,9 +181,9 @@ static int32_t last_time = 0; #endif static void flv_video(struct serializer *s, int32_t dts_offset, - struct encoder_packet *packet, bool is_header) + struct encoder_packet *packet, bool is_header) { - int64_t offset = packet->pts - packet->dts; + int64_t offset = packet->pts - packet->dts; int32_t time_ms = get_ms_time(packet, packet->dts) - dts_offset; if (!packet->data || !packet->size) @@ -225,7 +216,7 @@ static void flv_video(struct serializer *s, int32_t dts_offset, } static void flv_audio(struct serializer *s, int32_t dts_offset, - struct encoder_packet *packet, bool is_header) + struct encoder_packet *packet, bool is_header) { int32_t time_ms = get_ms_time(packet, packet->dts) - dts_offset; @@ -258,7 +249,7 @@ static void flv_audio(struct serializer *s, int32_t dts_offset, } void flv_packet_mux(struct encoder_packet *packet, int32_t dts_offset, - uint8_t **output, size_t *size, bool is_header) + uint8_t **output, size_t *size, bool is_header) { struct array_output_data data; struct serializer s; @@ -271,5 +262,5 @@ void flv_packet_mux(struct encoder_packet *packet, int32_t dts_offset, flv_audio(&s, dts_offset, packet, is_header); *output = data.bytes.array; - *size = data.bytes.num; + *size = data.bytes.num; } diff --git a/plugins/obs-outputs/flv-mux.h b/plugins/obs-outputs/flv-mux.h index 50c37e2..9355491 100644 --- a/plugins/obs-outputs/flv-mux.h +++ b/plugins/obs-outputs/flv-mux.h @@ -19,7 +19,7 @@ #include -#define MILLISECOND_DEN 1000 +#define MILLISECOND_DEN 1000 static int32_t get_ms_time(struct encoder_packet *packet, int64_t val) { @@ -29,6 +29,6 @@ static int32_t get_ms_time(struct encoder_packet *packet, int64_t val) extern void write_file_info(FILE *file, int64_t duration_ms, int64_t size); extern bool flv_meta_data(obs_output_t *context, uint8_t **output, size_t *size, - bool write_header, size_t audio_idx); + bool write_header, size_t audio_idx); extern void flv_packet_mux(struct encoder_packet *packet, int32_t dts_offset, - uint8_t **output, size_t *size, bool is_header); + uint8_t **output, size_t *size, bool is_header); diff --git a/plugins/obs-outputs/flv-output.c b/plugins/obs-outputs/flv-output.c index de093aa..243ce40 100644 --- a/plugins/obs-outputs/flv-output.c +++ b/plugins/obs-outputs/flv-output.c @@ -24,27 +24,27 @@ #include #include "flv-mux.h" -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[flv output: '%s'] " format, \ - obs_output_get_name(stream->output), ##__VA_ARGS__) + obs_output_get_name(stream->output), ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) struct flv_output { - obs_output_t *output; - struct dstr path; - FILE *file; - volatile bool active; - volatile bool stopping; - uint64_t stop_ts; - bool sent_headers; - int64_t last_packet_ts; + obs_output_t *output; + struct dstr path; + FILE *file; + volatile bool active; + volatile bool stopping; + uint64_t stop_ts; + bool sent_headers; + int64_t last_packet_ts; pthread_mutex_t mutex; - bool got_first_video; - int32_t start_dts_offset; + bool got_first_video; + int32_t start_dts_offset; }; static inline bool stopping(struct flv_output *stream) @@ -85,16 +85,16 @@ static void *flv_output_create(obs_data_t *settings, obs_output_t *output) } static int write_packet(struct flv_output *stream, - struct encoder_packet *packet, bool is_header) + struct encoder_packet *packet, bool is_header) { uint8_t *data; - size_t size; - int ret = 0; + size_t size; + int ret = 0; stream->last_packet_ts = get_ms_time(packet, packet->dts); - flv_packet_mux(packet, is_header ? 0 : stream->start_dts_offset, - &data, &size, is_header); + flv_packet_mux(packet, is_header ? 0 : stream->start_dts_offset, &data, + &size, is_header); fwrite(data, 1, size, stream->file); bfree(data); @@ -104,7 +104,7 @@ static int write_packet(struct flv_output *stream, static void write_meta_data(struct flv_output *stream) { uint8_t *meta_data; - size_t meta_data_size; + size_t meta_data_size; flv_meta_data(stream->output, &meta_data, &meta_data_size, true, 0); fwrite(meta_data, 1, meta_data_size, stream->file); @@ -113,13 +113,11 @@ static void write_meta_data(struct flv_output *stream) static void write_audio_header(struct flv_output *stream) { - obs_output_t *context = stream->output; + obs_output_t *context = stream->output; obs_encoder_t *aencoder = obs_output_get_audio_encoder(context, 0); - struct encoder_packet packet = { - .type = OBS_ENCODER_AUDIO, - .timebase_den = 1 - }; + struct encoder_packet packet = {.type = OBS_ENCODER_AUDIO, + .timebase_den = 1}; obs_encoder_get_extra_data(aencoder, &packet.data, &packet.size); write_packet(stream, &packet, true); @@ -127,16 +125,13 @@ static void write_audio_header(struct flv_output *stream) static void write_video_header(struct flv_output *stream) { - obs_output_t *context = stream->output; + obs_output_t *context = stream->output; obs_encoder_t *vencoder = obs_output_get_video_encoder(context); - uint8_t *header; - size_t size; + uint8_t *header; + size_t size; - struct encoder_packet packet = { - .type = OBS_ENCODER_VIDEO, - .timebase_den = 1, - .keyframe = true - }; + struct encoder_packet packet = { + .type = OBS_ENCODER_VIDEO, .timebase_den = 1, .keyframe = true}; obs_encoder_get_extra_data(vencoder, &header, &size); packet.size = obs_parse_avc_header(&packet.data, header, size); @@ -214,7 +209,7 @@ static void flv_output_actual_stop(struct flv_output *stream, int code) static void flv_output_data(void *data, struct encoder_packet *packet) { - struct flv_output *stream = data; + struct flv_output *stream = data; struct encoder_packet parsed_packet; pthread_mutex_lock(&stream->mutex); @@ -264,21 +259,21 @@ static obs_properties_t *flv_output_properties(void *unused) obs_properties_t *props = obs_properties_create(); obs_properties_add_text(props, "path", - obs_module_text("FLVOutput.FilePath"), - OBS_TEXT_DEFAULT); + obs_module_text("FLVOutput.FilePath"), + OBS_TEXT_DEFAULT); return props; } struct obs_output_info flv_output_info = { - .id = "flv_output", - .flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED, + .id = "flv_output", + .flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED, .encoded_video_codecs = "h264", .encoded_audio_codecs = "aac", - .get_name = flv_output_getname, - .create = flv_output_create, - .destroy = flv_output_destroy, - .start = flv_output_start, - .stop = flv_output_stop, - .encoded_packet = flv_output_data, - .get_properties = flv_output_properties + .get_name = flv_output_getname, + .create = flv_output_create, + .destroy = flv_output_destroy, + .start = flv_output_start, + .stop = flv_output_stop, + .encoded_packet = flv_output_data, + .get_properties = flv_output_properties, }; diff --git a/plugins/obs-outputs/ftl-stream.c b/plugins/obs-outputs/ftl-stream.c index 6bd155f..25ccb45 100644 --- a/plugins/obs-outputs/ftl-stream.c +++ b/plugins/obs-outputs/ftl-stream.c @@ -33,13 +33,13 @@ #define INFINITE 0xFFFFFFFF #endif -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[ftl stream: '%s'] " format, \ - obs_output_get_name(stream->output), ##__VA_ARGS__) + obs_output_get_name(stream->output), ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) -#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) #define OPT_DROP_THRESHOLD "drop_threshold_ms" #define OPT_MAX_SHUTDOWN_TIME_SEC "max_shutdown_time_sec" @@ -59,56 +59,56 @@ typedef struct _frame_of_nalus_t { } frame_of_nalus_t; struct ftl_stream { - obs_output_t *output; + obs_output_t *output; - pthread_mutex_t packets_mutex; + pthread_mutex_t packets_mutex; struct circlebuf packets; - bool sent_headers; - int64_t frames_sent; + bool sent_headers; + int64_t frames_sent; - volatile bool connecting; - pthread_t connect_thread; - pthread_t status_thread; + volatile bool connecting; + pthread_t connect_thread; + pthread_t status_thread; - volatile bool active; - volatile bool disconnected; - volatile bool encode_error; - pthread_t send_thread; + volatile bool active; + volatile bool disconnected; + volatile bool encode_error; + pthread_t send_thread; - int max_shutdown_time_sec; + int max_shutdown_time_sec; - os_sem_t *send_sem; - os_event_t *stop_event; - uint64_t stop_ts; - uint64_t shutdown_timeout_ts; + os_sem_t *send_sem; + os_event_t *stop_event; + uint64_t stop_ts; + uint64_t shutdown_timeout_ts; - struct dstr path; - uint32_t channel_id; - struct dstr username, password; - struct dstr encoder_name; - struct dstr bind_ip; + struct dstr path; + uint32_t channel_id; + struct dstr username, password; + struct dstr encoder_name; + struct dstr bind_ip; /* frame drop variables */ - int64_t drop_threshold_usec; - int64_t pframe_drop_threshold_usec; - int min_priority; - float congestion; + int64_t drop_threshold_usec; + int64_t pframe_drop_threshold_usec; + int min_priority; + float congestion; - int64_t last_dts_usec; + int64_t last_dts_usec; - uint64_t total_bytes_sent; - uint64_t dropped_frames; - uint64_t last_nack_count; + uint64_t total_bytes_sent; + uint64_t dropped_frames; + uint64_t last_nack_count; - ftl_handle_t ftl_handle; + ftl_handle_t ftl_handle; ftl_ingest_params_t params; - int peak_kbps; - uint32_t scale_width, scale_height, width, height; - frame_of_nalus_t coded_pic_buffer; + int peak_kbps; + uint32_t scale_width, scale_height, width, height; + frame_of_nalus_t coded_pic_buffer; }; static void log_libftl_messages(ftl_log_severity_t log_level, - const char *message); + const char *message); static int init_connect(struct ftl_stream *stream); static void *connect_thread(void *data); static void *status_thread(void *data); @@ -261,7 +261,8 @@ static void ftl_stream_stop(void *data, uint64_t ts) stream->stop_ts = ts / 1000ULL; if (ts) { - stream->shutdown_timeout_ts = ts + + stream->shutdown_timeout_ts = + ts + (uint64_t)stream->max_shutdown_time_sec * 1000000000ULL; } @@ -275,14 +276,14 @@ static void ftl_stream_stop(void *data, uint64_t ts) } static inline bool get_next_packet(struct ftl_stream *stream, - struct encoder_packet *packet) + struct encoder_packet *packet) { bool new_packet = false; pthread_mutex_lock(&stream->packets_mutex); if (stream->packets.size) { circlebuf_pop_front(&stream->packets, packet, - sizeof(struct encoder_packet)); + sizeof(struct encoder_packet)); new_packet = true; } pthread_mutex_unlock(&stream->packets_mutex); @@ -291,7 +292,7 @@ static inline bool get_next_packet(struct ftl_stream *stream, } static int avc_get_video_frame(struct ftl_stream *stream, - struct encoder_packet *packet, bool is_header) + struct encoder_packet *packet, bool is_header) { int consumed = 0; int len = (int)packet->size; @@ -301,15 +302,15 @@ static int avc_get_video_frame(struct ftl_stream *stream, while ((size_t)consumed < packet->size) { size_t total_max = sizeof(stream->coded_pic_buffer.nalus) / - sizeof(stream->coded_pic_buffer.nalus[0]); + sizeof(stream->coded_pic_buffer.nalus[0]); if ((size_t)stream->coded_pic_buffer.total >= total_max) { warn("ERROR: cannot continue, nalu buffers are full"); return -1; } - nalu = &stream->coded_pic_buffer.nalus - [stream->coded_pic_buffer.total]; + nalu = &stream->coded_pic_buffer + .nalus[stream->coded_pic_buffer.total]; if (is_header) { if (consumed == 0) { @@ -327,16 +328,13 @@ static int avc_get_video_frame(struct ftl_stream *stream, video_stream += 2; consumed += 2; } else { - len = video_stream[0] << 24 | - video_stream[1] << 16 | - video_stream[2] << 8 | - video_stream[3]; + len = video_stream[0] << 24 | video_stream[1] << 16 | + video_stream[2] << 8 | video_stream[3]; if ((size_t)len > (packet->size - (size_t)consumed)) { warn("ERROR: got len of %d but packet only " - "has %d left", - len, - (int)(packet->size - consumed)); + "has %d left", + len, (int)(packet->size - consumed)); } consumed += 4; @@ -367,8 +365,8 @@ static int avc_get_video_frame(struct ftl_stream *stream, return 0; } -static int send_packet(struct ftl_stream *stream, - struct encoder_packet *packet, bool is_header) +static int send_packet(struct ftl_stream *stream, struct encoder_packet *packet, + bool is_header) { int bytes_sent = 0; int ret = 0; @@ -381,12 +379,9 @@ static int send_packet(struct ftl_stream *stream, for (i = 0; i < stream->coded_pic_buffer.total; i++) { nalu_t *nalu = &stream->coded_pic_buffer.nalus[i]; bytes_sent += ftl_ingest_send_media_dts( - &stream->ftl_handle, - FTL_VIDEO_DATA, - packet->dts_usec, - nalu->data, - nalu->len, - nalu->send_marker_bit); + &stream->ftl_handle, FTL_VIDEO_DATA, + packet->dts_usec, nalu->data, nalu->len, + nalu->send_marker_bit); if (nalu->send_marker_bit) { stream->frames_sent++; @@ -395,19 +390,15 @@ static int send_packet(struct ftl_stream *stream, } else if (packet->type == OBS_ENCODER_AUDIO) { bytes_sent += ftl_ingest_send_media_dts( - &stream->ftl_handle, - FTL_AUDIO_DATA, - packet->dts_usec, - packet->data, - (int)packet->size, 0); + &stream->ftl_handle, FTL_AUDIO_DATA, packet->dts_usec, + packet->data, (int)packet->size, 0); } else { warn("Got packet type %d", packet->type); } if (is_header) { bfree(packet->data); - } - else { + } else { obs_encoder_packet_release(packet); } @@ -422,58 +413,56 @@ static void set_peak_bitrate(struct ftl_stream *stream) speed_test_t results; ftl_status_t status_code; - status_code = ftl_ingest_speed_test_ex( - &stream->ftl_handle, - speedtest_kbps, - speedtest_duration, - &results); + status_code = ftl_ingest_speed_test_ex(&stream->ftl_handle, + speedtest_kbps, + speedtest_duration, &results); float percent_lost = 0; if (status_code == FTL_SUCCESS) { percent_lost = (float)results.lost_pkts * 100.f / - (float)results.pkts_sent; + (float)results.pkts_sent; } else { warn("Speed test failed with: %s", - ftl_status_code_to_string(status_code)); + ftl_status_code_to_string(status_code)); } // Get what the user set the encoding bitrate to. - obs_encoder_t *video_encoder = obs_output_get_video_encoder(stream->output); + obs_encoder_t *video_encoder = + obs_output_get_video_encoder(stream->output); obs_data_t *video_settings = obs_encoder_get_settings(video_encoder); - int user_desired_bitrate = (int)obs_data_get_int(video_settings, "bitrate"); + int user_desired_bitrate = + (int)obs_data_get_int(video_settings, "bitrate"); obs_data_release(video_settings); // Report the results. info("Speed test completed: User desired bitrate %d, Peak kbps %d, " - "initial rtt %d, " - "final rtt %d, %3.2f lost packets", - user_desired_bitrate, - results.peak_kbps, - results.starting_rtt, - results.ending_rtt, - percent_lost); + "initial rtt %d, " + "final rtt %d, %3.2f lost packets", + user_desired_bitrate, results.peak_kbps, results.starting_rtt, + results.ending_rtt, percent_lost); // We still want to set the peak to about 1.2x what the target bitrate is, // even if the speed test reported it should be lower. If we don't, FTL // will queue data on the client and start adding latency. If the internet // connection really can't handle the bitrate the user will see either lost frame // and recovered frame counts go up, which is reflect in the dropped_frames count. - stream->peak_kbps = stream->params.peak_kbps = user_desired_bitrate * 12 / 10; + stream->peak_kbps = stream->params.peak_kbps = + user_desired_bitrate * 12 / 10; ftl_ingest_update_params(&stream->ftl_handle, &stream->params); } static inline bool send_headers(struct ftl_stream *stream, int64_t dts_usec); static inline bool can_shutdown_stream(struct ftl_stream *stream, - struct encoder_packet *packet) + struct encoder_packet *packet) { uint64_t cur_time = os_gettime_ns(); bool timeout = cur_time >= stream->shutdown_timeout_ts; if (timeout) info("Stream shutdown timeout reached (%d second(s))", - stream->max_shutdown_time_sec); + stream->max_shutdown_time_sec); return timeout || packet->sys_dts_usec >= (int64_t)stream->stop_ts; } @@ -552,17 +541,15 @@ static void *send_thread(void *data) static bool send_video_header(struct ftl_stream *stream, int64_t dts_usec) { - obs_output_t *context = stream->output; + obs_output_t *context = stream->output; obs_encoder_t *vencoder = obs_output_get_video_encoder(context); - uint8_t *header; - size_t size; + uint8_t *header; + size_t size; - struct encoder_packet packet = { - .type = OBS_ENCODER_VIDEO, - .timebase_den = 1, - .keyframe = true, - .dts_usec = dts_usec - }; + struct encoder_packet packet = {.type = OBS_ENCODER_VIDEO, + .timebase_den = 1, + .keyframe = true, + .dts_usec = dts_usec}; obs_encoder_get_extra_data(vencoder, &header, &size); packet.size = obs_parse_avc_header(&packet.data, header, size); @@ -626,12 +613,12 @@ static int try_connect(struct ftl_stream *stream) if (status_code != FTL_SUCCESS) { if (status_code == FTL_BAD_OR_INVALID_STREAM_KEY) { blog(LOG_ERROR, "Invalid Key (%s)", - ftl_status_code_to_string(status_code)); + ftl_status_code_to_string(status_code)); return OBS_OUTPUT_INVALID_STREAM; } else { warn("Ingest connect failed with: %s (%d)", - ftl_status_code_to_string(status_code), - status_code); + ftl_status_code_to_string(status_code), + status_code); return _ftl_error_to_obs_error(status_code); } } @@ -653,7 +640,8 @@ static bool ftl_stream_start(void *data) info("ftl_stream_start"); // Mixer doesn't support bframes. So force them off. - obs_encoder_t *video_encoder = obs_output_get_video_encoder(stream->output); + obs_encoder_t *video_encoder = + obs_output_get_video_encoder(stream->output); obs_data_t *video_settings = obs_encoder_get_settings(video_encoder); obs_data_set_int(video_settings, "bf", 0); obs_data_release(video_settings); @@ -669,14 +657,14 @@ static bool ftl_stream_start(void *data) os_atomic_set_bool(&stream->connecting, true); return pthread_create(&stream->connect_thread, NULL, connect_thread, - stream) == 0; + stream) == 0; } static inline bool add_packet(struct ftl_stream *stream, - struct encoder_packet *packet) + struct encoder_packet *packet) { circlebuf_push_back(&stream->packets, packet, - sizeof(struct encoder_packet)); + sizeof(struct encoder_packet)); return true; } @@ -686,12 +674,12 @@ static inline size_t num_buffered_packets(struct ftl_stream *stream) } static void drop_frames(struct ftl_stream *stream, const char *name, - int highest_priority, bool pframes) + int highest_priority, bool pframes) { UNUSED_PARAMETER(pframes); - struct circlebuf new_buf = {0}; - int num_frames_dropped = 0; + struct circlebuf new_buf = {0}; + int num_frames_dropped = 0; #ifdef _DEBUG int start_packets = (int)num_buffered_packets(stream); @@ -706,7 +694,7 @@ static void drop_frames(struct ftl_stream *stream, const char *name, circlebuf_pop_front(&stream->packets, &packet, sizeof(packet)); /* do not drop audio data or video keyframes */ - if (packet.type == OBS_ENCODER_AUDIO || + if (packet.type == OBS_ENCODER_AUDIO || packet.drop_priority >= highest_priority) { circlebuf_push_back(&new_buf, &packet, sizeof(packet)); @@ -726,21 +714,19 @@ static void drop_frames(struct ftl_stream *stream, const char *name, stream->dropped_frames += num_frames_dropped; #ifdef _DEBUG - debug("Dropped %s, prev packet count: %d, new packet count: %d", - name, - start_packets, - (int)num_buffered_packets(stream)); + debug("Dropped %s, prev packet count: %d, new packet count: %d", name, + start_packets, (int)num_buffered_packets(stream)); #endif } static bool find_first_video_packet(struct ftl_stream *stream, - struct encoder_packet *first) + struct encoder_packet *first) { size_t count = stream->packets.size / sizeof(*first); for (size_t i = 0; i < count; i++) { - struct encoder_packet *cur = circlebuf_data(&stream->packets, - i * sizeof(*first)); + struct encoder_packet *cur = + circlebuf_data(&stream->packets, i * sizeof(*first)); if (cur->type == OBS_ENCODER_VIDEO && !cur->keyframe) { *first = *cur; return true; @@ -756,11 +742,10 @@ static void check_to_drop_frames(struct ftl_stream *stream, bool pframes) int64_t buffer_duration_usec; size_t num_packets = num_buffered_packets(stream); const char *name = pframes ? "p-frames" : "b-frames"; - int priority = pframes ? - OBS_NAL_PRIORITY_HIGHEST : OBS_NAL_PRIORITY_HIGH; - int64_t drop_threshold = pframes ? - stream->pframe_drop_threshold_usec : - stream->drop_threshold_usec; + int priority = pframes ? OBS_NAL_PRIORITY_HIGHEST + : OBS_NAL_PRIORITY_HIGH; + int64_t drop_threshold = pframes ? stream->pframe_drop_threshold_usec + : stream->drop_threshold_usec; if (num_packets < 5) { if (!pframes) @@ -776,8 +761,8 @@ static void check_to_drop_frames(struct ftl_stream *stream, bool pframes) buffer_duration_usec = stream->last_dts_usec - first.dts_usec; if (!pframes) { - stream->congestion = (float)buffer_duration_usec / - (float)drop_threshold; + stream->congestion = + (float)buffer_duration_usec / (float)drop_threshold; } if (buffer_duration_usec > drop_threshold) { @@ -787,7 +772,7 @@ static void check_to_drop_frames(struct ftl_stream *stream, bool pframes) } static bool add_video_packet(struct ftl_stream *stream, - struct encoder_packet *packet) + struct encoder_packet *packet) { check_to_drop_frames(stream, false); check_to_drop_frames(stream, true); @@ -805,13 +790,12 @@ static bool add_video_packet(struct ftl_stream *stream, return add_packet(stream, packet); } - static void ftl_stream_data(void *data, struct encoder_packet *packet) { - struct ftl_stream *stream = data; + struct ftl_stream *stream = data; struct encoder_packet new_packet; - bool added_packet = false; + bool added_packet = false; if (disconnected(stream) || !active(stream)) return; @@ -831,9 +815,9 @@ static void ftl_stream_data(void *data, struct encoder_packet *packet) pthread_mutex_lock(&stream->packets_mutex); if (!disconnected(stream)) { - added_packet = (packet->type == OBS_ENCODER_VIDEO) ? - add_video_packet(stream, &new_packet) : - add_packet(stream, &new_packet); + added_packet = (packet->type == OBS_ENCODER_VIDEO) + ? add_video_packet(stream, &new_packet) + : add_packet(stream, &new_packet); } pthread_mutex_unlock(&stream->packets_mutex); @@ -849,20 +833,18 @@ static void ftl_stream_defaults(obs_data_t *defaults) UNUSED_PARAMETER(defaults); } - static obs_properties_t *ftl_stream_properties(void *unused) { UNUSED_PARAMETER(unused); obs_properties_t *props = obs_properties_create(); obs_properties_add_int(props, "peak_bitrate_kbps", - obs_module_text("FTLStream.PeakBitrate"), - 1000, 10000, 500); + obs_module_text("FTLStream.PeakBitrate"), 1000, + 10000, 500); return props; } - static uint64_t ftl_stream_total_bytes_sent(void *data) { struct ftl_stream *stream = data; @@ -889,13 +871,13 @@ enum ret_type { }; static enum ret_type ftl_event(struct ftl_stream *stream, - ftl_status_msg_t status) + ftl_status_msg_t status) { if (status.msg.event.type != FTL_STATUS_EVENT_TYPE_DISCONNECTED) return RET_CONTINUE; info("Disconnected from ingest with reason: %s", - ftl_status_code_to_string(status.msg.event.error_code)); + ftl_status_code_to_string(status.msg.event.error_code)); if (status.msg.event.reason == FTL_STATUS_EVENT_REASON_API_REQUEST) { return RET_BREAK; @@ -916,7 +898,7 @@ static void *status_thread(void *data) while (!disconnected(stream)) { status_code = ftl_ingest_get_status(&stream->ftl_handle, - &status, 1000); + &status, 1000); if (status_code == FTL_STATUS_TIMEOUT || status_code == FTL_QUEUE_EMPTY) { @@ -932,24 +914,25 @@ static void *status_thread(void *data) else if (ret_type == RET_BREAK) break; - } else if(status.type == FTL_STATUS_LOG) { + } else if (status.type == FTL_STATUS_LOG) { blog(LOG_INFO, "[%d] %s", status.msg.log.log_level, - status.msg.log.string); + status.msg.log.string); } else if (status.type == FTL_STATUS_VIDEO_PACKETS) { ftl_packet_stats_msg_t *p = &status.msg.pkt_stats; // Report nack requests as dropped frames stream->dropped_frames += - p->nack_reqs -stream->last_nack_count; + p->nack_reqs - stream->last_nack_count; stream->last_nack_count = p->nack_reqs; int log_level = p->nack_reqs > 0 ? LOG_INFO : LOG_DEBUG; - blog(log_level, "Avg packet send per second %3.1f, " - "total nack requests %d", - (float)p->sent * 1000.f / p->period, - (int)p->nack_reqs); + blog(log_level, + "Avg packet send per second %3.1f, " + "total nack requests %d", + (float)p->sent * 1000.f / p->period, + (int)p->nack_reqs); } else if (status.type == FTL_STATUS_VIDEO_PACKETS_INSTANT) { ftl_packet_stats_instant_msg_t *p = @@ -957,34 +940,38 @@ static void *status_thread(void *data) int log_level = p->avg_rtt > 20 ? LOG_INFO : LOG_DEBUG; - blog(log_level, "avg transmit delay %dms " - "(min: %d, max: %d), " - "avg rtt %dms (min: %d, max: %d)", - p->avg_xmit_delay, - p->min_xmit_delay, p->max_xmit_delay, - p->avg_rtt, p->min_rtt, p->max_rtt); + blog(log_level, + "avg transmit delay %dms " + "(min: %d, max: %d), " + "avg rtt %dms (min: %d, max: %d)", + p->avg_xmit_delay, p->min_xmit_delay, + p->max_xmit_delay, p->avg_rtt, p->min_rtt, + p->max_rtt); } else if (status.type == FTL_STATUS_VIDEO) { ftl_video_frame_stats_msg_t *v = &status.msg.video_stats; - int log_level = v->queue_fullness > 0 ? - LOG_INFO : LOG_DEBUG; + int log_level = v->queue_fullness > 0 ? LOG_INFO + : LOG_DEBUG; - blog(log_level, "Queue an average of %3.2f fps " - "(%3.1f kbps), " - "sent an average of %3.2f fps " - "(%3.1f kbps), " - "queue fullness %d, " - "max frame size %d", - (float)v->frames_queued * 1000.f / v->period, - (float)v->bytes_queued / v->period * 8, - (float)v->frames_sent * 1000.f / v->period, - (float)v->bytes_sent / v->period * 8, - v->queue_fullness, v->max_frame_size); + blog(log_level, + "Queue an average of %3.2f fps " + "(%3.1f kbps), " + "sent an average of %3.2f fps " + "(%3.1f kbps), " + "queue fullness %d, " + "max frame size %d", + (float)v->frames_queued * 1000.f / v->period, + (float)v->bytes_queued / v->period * 8, + (float)v->frames_sent * 1000.f / v->period, + (float)v->bytes_sent / v->period * 8, + v->queue_fullness, v->max_frame_size); } else { - blog(LOG_DEBUG, "Status: Got Status message of type " - "%d", status.type); + blog(LOG_DEBUG, + "Status: Got Status message of type " + "%d", + status.type); } } @@ -1022,7 +1009,7 @@ static void *connect_thread(void *data) } static void log_libftl_messages(ftl_log_severity_t log_level, - const char * message) + const char *message) { UNUSED_PARAMETER(log_level); blog(LOG_WARNING, "[libftl] %s", message); @@ -1049,15 +1036,14 @@ static int init_connect(struct ftl_stream *stream) os_atomic_set_bool(&stream->disconnected, false); os_atomic_set_bool(&stream->encode_error, false); - stream->total_bytes_sent = 0; - stream->dropped_frames = 0; - stream->min_priority = 0; + stream->total_bytes_sent = 0; + stream->dropped_frames = 0; + stream->min_priority = 0; settings = obs_output_get_settings(stream->output); obs_encoder_t *video_encoder = obs_output_get_video_encoder(stream->output); - obs_data_t *video_settings = - obs_encoder_get_settings(video_encoder); + obs_data_t *video_settings = obs_encoder_get_settings(video_encoder); dstr_copy(&stream->path, obs_service_get_url(service)); key = obs_service_get_key(service); @@ -1070,14 +1056,14 @@ static int init_connect(struct ftl_stream *stream) peak_bitrate = target_bitrate; } - stream->params.stream_key = (char*)key; + stream->params.stream_key = (char *)key; stream->params.video_codec = FTL_VIDEO_H264; stream->params.audio_codec = FTL_AUDIO_OPUS; stream->params.ingest_hostname = stream->path.array; stream->params.vendor_name = "OBS Studio"; stream->params.vendor_version = OBS_VERSION; - stream->params.peak_kbps = - stream->peak_kbps < 0 ? 0 : stream->peak_kbps; + stream->params.peak_kbps = stream->peak_kbps < 0 ? 0 + : stream->peak_kbps; //not required when using ftl_ingest_send_media_dts stream->params.fps_num = 0; @@ -1087,12 +1073,11 @@ static int init_connect(struct ftl_stream *stream) if (status_code != FTL_SUCCESS) { if (status_code == FTL_BAD_OR_INVALID_STREAM_KEY) { blog(LOG_ERROR, "Invalid Key (%s)", - ftl_status_code_to_string(status_code)); + ftl_status_code_to_string(status_code)); return OBS_OUTPUT_INVALID_STREAM; - } - else { + } else { blog(LOG_ERROR, "Failed to create ingest handle (%s)", - ftl_status_code_to_string(status_code)); + ftl_status_code_to_string(status_code)); return OBS_OUTPUT_ERROR; } } @@ -1161,21 +1146,19 @@ static int _ftl_error_to_obs_error(int status) } struct obs_output_info ftl_output_info = { - .id = "ftl_output", - .flags = OBS_OUTPUT_AV | - OBS_OUTPUT_ENCODED | - OBS_OUTPUT_SERVICE, + .id = "ftl_output", + .flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_SERVICE, .encoded_video_codecs = "h264", .encoded_audio_codecs = "opus", - .get_name = ftl_stream_getname, - .create = ftl_stream_create, - .destroy = ftl_stream_destroy, - .start = ftl_stream_start, - .stop = ftl_stream_stop, - .encoded_packet = ftl_stream_data, - .get_defaults = ftl_stream_defaults, - .get_properties = ftl_stream_properties, - .get_total_bytes = ftl_stream_total_bytes_sent, - .get_congestion = ftl_stream_congestion, - .get_dropped_frames = ftl_stream_dropped_frames + .get_name = ftl_stream_getname, + .create = ftl_stream_create, + .destroy = ftl_stream_destroy, + .start = ftl_stream_start, + .stop = ftl_stream_stop, + .encoded_packet = ftl_stream_data, + .get_defaults = ftl_stream_defaults, + .get_properties = ftl_stream_properties, + .get_total_bytes = ftl_stream_total_bytes_sent, + .get_congestion = ftl_stream_congestion, + .get_dropped_frames = ftl_stream_dropped_frames, }; diff --git a/plugins/obs-outputs/librtmp/.clang-format b/plugins/obs-outputs/librtmp/.clang-format new file mode 100644 index 0000000..6420a46 --- /dev/null +++ b/plugins/obs-outputs/librtmp/.clang-format @@ -0,0 +1,3 @@ +Language: Cpp +SortIncludes: false +DisableFormat: true diff --git a/plugins/obs-outputs/net-if.c b/plugins/obs-outputs/net-if.c index 9f91cad..9a78d90 100644 --- a/plugins/obs-outputs/net-if.c +++ b/plugins/obs-outputs/net-if.c @@ -24,12 +24,13 @@ #define do_log(level, format, ...) \ blog(level, "[net if] " format, ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) -#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) static inline void netif_saddr_data_push_back(struct netif_saddr_data *sd, - const char *ip, const char *adapter) + const char *ip, + const char *adapter) { struct netif_saddr_item item; struct dstr full_name = {0}; @@ -47,32 +48,33 @@ static inline void netif_saddr_data_push_back(struct netif_saddr_data *sd, } static void netif_convert_to_string(char *dest, - struct sockaddr_storage *byte_address) + struct sockaddr_storage *byte_address) { int family = byte_address->ss_family; char temp_char[INET6_ADDRSTRLEN] = {0}; #ifndef _WIN32 if (family == AF_INET) - inet_ntop(family, &(((struct sockaddr_in*)byte_address)->sin_addr), - temp_char, INET6_ADDRSTRLEN); + inet_ntop(family, + &(((struct sockaddr_in *)byte_address)->sin_addr), + temp_char, INET6_ADDRSTRLEN); else if (family == AF_INET6) - inet_ntop(family, &(((struct sockaddr_in*)byte_address)->sin_addr), - temp_char, INET6_ADDRSTRLEN); + inet_ntop(family, + &(((struct sockaddr_in *)byte_address)->sin_addr), + temp_char, INET6_ADDRSTRLEN); #else if (family == AF_INET) InetNtopA(family, &(((SOCKADDR_IN *)byte_address)->sin_addr), - temp_char, INET6_ADDRSTRLEN); + temp_char, INET6_ADDRSTRLEN); else if (family == AF_INET6) InetNtopA(family, &(((SOCKADDR_IN6 *)byte_address)->sin6_addr), - temp_char, INET6_ADDRSTRLEN); + temp_char, INET6_ADDRSTRLEN); #endif strncpy(dest, temp_char, INET6_ADDRSTRLEN); } static void netif_push(struct sockaddr *copy_source, - struct netif_saddr_data *saddr_d, - const char *adapter) + struct netif_saddr_data *saddr_d, const char *adapter) { char temp_char[INET6_ADDRSTRLEN] = {0}; struct sockaddr_storage sa = {0}; @@ -88,12 +90,12 @@ static void netif_push(struct sockaddr *copy_source, void netif_log_saddrs(struct netif_saddr_data *sd) { - for(size_t i = 0; i < sd->addrs.num; i++) + for (size_t i = 0; i < sd->addrs.num; i++) info("\t\t%s", sd->addrs.array[i].name); } bool netif_str_to_addr(struct sockaddr_storage *out, int *addr_len, - const char *addr) + const char *addr) { bool ipv6; @@ -109,16 +111,15 @@ bool netif_str_to_addr(struct sockaddr_storage *out, int *addr_len, #ifdef _WIN32 int ret = WSAStringToAddressA((LPSTR)addr, out->ss_family, NULL, - (LPSOCKADDR)out, addr_len); + (LPSOCKADDR)out, addr_len); if (ret == SOCKET_ERROR) warn("Could not parse address, error code: %d", GetLastError()); return ret != SOCKET_ERROR; #else struct sockaddr_in *sin = (struct sockaddr_in *)out; if (inet_pton(out->ss_family, addr, &sin->sin_addr)) { - *addr_len = ipv6 ? - sizeof(struct sockaddr_in6) : - sizeof(struct sockaddr_in); + *addr_len = ipv6 ? sizeof(struct sockaddr_in6) + : sizeof(struct sockaddr_in); return true; } @@ -152,13 +153,14 @@ static inline void netif_get_addrs_nix(struct netif_saddr_data *ifaddrs) if ((family == AF_INET) || (family == AF_INET6)) { s = getnameinfo(ifa->ifa_addr, - (family == AF_INET) ? - sizeof(struct sockaddr_in) : - sizeof(struct sockaddr_in6), - host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); + (family == AF_INET) + ? sizeof(struct sockaddr_in) + : sizeof(struct sockaddr_in6), + host, NI_MAXHOST, NULL, 0, + NI_NUMERICHOST); if (s != 0) { warn("getnameinfo() failed: %s", - gai_strerror(s)); + gai_strerror(s)); continue; } @@ -176,20 +178,18 @@ static inline PIP_ADAPTER_ADDRESSES get_adapters(void) PIP_ADAPTER_ADDRESSES adapter = NULL; unsigned long ret = 0; unsigned long out_buf_len = 16384; - unsigned long flags = - GAA_FLAG_SKIP_ANYCAST | - GAA_FLAG_SKIP_MULTICAST | - GAA_FLAG_SKIP_DNS_SERVER; + unsigned long flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | + GAA_FLAG_SKIP_DNS_SERVER; const int max_tries = 3; int i = 0; do { - adapter = (IP_ADAPTER_ADDRESSES*)bmalloc(out_buf_len); + adapter = (IP_ADAPTER_ADDRESSES *)bmalloc(out_buf_len); if (!adapter) return NULL; ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapter, - &out_buf_len); + &out_buf_len); if (ret == ERROR_BUFFER_OVERFLOW) { bfree(adapter); adapter = NULL; @@ -205,16 +205,15 @@ static inline PIP_ADAPTER_ADDRESSES get_adapters(void) bfree(adapter); adapter = NULL; - FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, ret, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - msg_buf, 0, NULL); + FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, ret, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&msg_buf, 0, NULL); if (msg_buf) { warn("Call to GetAdaptersAddresses failed: %s (%d)", - msg_buf, ret); + msg_buf, ret); LocalFree(msg_buf); } } @@ -250,7 +249,7 @@ static inline void netif_get_addrs_win32(struct netif_saddr_data *ifaddrs) family = socket_addr.lpSockaddr->sa_family; if (family == AF_INET || family == AF_INET6) netif_push(socket_addr.lpSockaddr, ifaddrs, - adap_name); + adap_name); } bfree(adap_name); diff --git a/plugins/obs-outputs/net-if.h b/plugins/obs-outputs/net-if.h index 3da69c0..757ee00 100644 --- a/plugins/obs-outputs/net-if.h +++ b/plugins/obs-outputs/net-if.h @@ -20,36 +20,36 @@ #include #ifdef _WIN32 -# include -# include -# include -# include +#include +#include +#include +#include #else -# ifdef __linux__ -# include -# elif __FreeBSD__ -# include -# ifndef _GNU_SOURCE -# define _GNU_SOURCE -# define __NET_IF_GNU_SOURCE__ -# endif //_GNU_SOURCE -# endif //__FreeBSD__ +#ifdef __linux__ +#include +#elif __FreeBSD__ +#include +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#define __NET_IF_GNU_SOURCE__ +#endif //_GNU_SOURCE +#endif //__FreeBSD__ -# include -# include -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include +#include +#include -# ifdef __FreeBSD__ -# ifdef ___NET_IF_GNU_SOURCE__ -# undef ___NET_IF_GNU_SOURCE__ -# undef _GNU_SOURCE -# endif -# endif +#ifdef __FreeBSD__ +#ifdef ___NET_IF_GNU_SOURCE__ +#undef ___NET_IF_GNU_SOURCE__ +#undef _GNU_SOURCE +#endif +#endif #endif @@ -72,6 +72,6 @@ static inline void netif_saddr_data_free(struct netif_saddr_data *data) } extern bool netif_str_to_addr(struct sockaddr_storage *out, int *addr_len, - const char *addr); + const char *addr); extern void netif_get_addrs(struct netif_saddr_data *ifaddrs); extern void netif_log_saddrs(struct netif_saddr_data *sd); diff --git a/plugins/obs-outputs/null-output.c b/plugins/obs-outputs/null-output.c index c63a6c4..f9606d1 100644 --- a/plugins/obs-outputs/null-output.c +++ b/plugins/obs-outputs/null-output.c @@ -77,7 +77,8 @@ static void null_output_stop(void *data, uint64_t ts) UNUSED_PARAMETER(ts); context->stop_thread_active = pthread_create(&context->stop_thread, - NULL, stop_thread, data) == 0; + NULL, stop_thread, + data) == 0; } static void null_output_data(void *data, struct encoder_packet *packet) @@ -87,13 +88,12 @@ static void null_output_data(void *data, struct encoder_packet *packet) } struct obs_output_info null_output_info = { - .id = "null_output", - .flags = OBS_OUTPUT_AV | - OBS_OUTPUT_ENCODED, - .get_name = null_output_getname, - .create = null_output_create, - .destroy = null_output_destroy, - .start = null_output_start, - .stop = null_output_stop, - .encoded_packet = null_output_data + .id = "null_output", + .flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED, + .get_name = null_output_getname, + .create = null_output_create, + .destroy = null_output_destroy, + .start = null_output_start, + .stop = null_output_stop, + .encoded_packet = null_output_data, }; diff --git a/plugins/obs-outputs/rtmp-helpers.h b/plugins/obs-outputs/rtmp-helpers.h index 83be8a5..adb3e8c 100644 --- a/plugins/obs-outputs/rtmp-helpers.h +++ b/plugins/obs-outputs/rtmp-helpers.h @@ -21,32 +21,31 @@ static inline AVal *flv_str(AVal *out, const char *str) { - out->av_val = (char*)str; + out->av_val = (char *)str; out->av_len = (int)strlen(str); return out; } static inline void enc_num_val(char **enc, char *end, const char *name, - double val) + double val) { AVal s; *enc = AMF_EncodeNamedNumber(*enc, end, flv_str(&s, name), val); } static inline void enc_bool_val(char **enc, char *end, const char *name, - bool val) + bool val) { AVal s; *enc = AMF_EncodeNamedBoolean(*enc, end, flv_str(&s, name), val); } static inline void enc_str_val(char **enc, char *end, const char *name, - const char *val) + const char *val) { AVal s1, s2; - *enc = AMF_EncodeNamedString(*enc, end, - flv_str(&s1, name), - flv_str(&s2, val)); + *enc = AMF_EncodeNamedString(*enc, end, flv_str(&s1, name), + flv_str(&s2, val)); } static inline void enc_str(char **enc, char *end, const char *str) diff --git a/plugins/obs-outputs/rtmp-stream.c b/plugins/obs-outputs/rtmp-stream.c index 93629df..810ae7f 100644 --- a/plugins/obs-outputs/rtmp-stream.c +++ b/plugins/obs-outputs/rtmp-stream.c @@ -17,6 +17,24 @@ #include "rtmp-stream.h" +#ifndef SEC_TO_NSEC +#define SEC_TO_NSEC 1000000000ULL +#endif + +#ifndef MSEC_TO_USEC +#define MSEC_TO_USEC 1000ULL +#endif + +#ifndef MSEC_TO_NSEC +#define MSEC_TO_NSEC 1000000ULL +#endif + +/* dynamic bitrate coefficients */ +#define DBR_INC_TIMER (30ULL * SEC_TO_NSEC) +#define DBR_TRIGGER_USEC (200ULL * MSEC_TO_USEC) +#define MIN_ESTIMATE_DURATION_MS 1000 +#define MAX_ESTIMATE_DURATION_MS 2000 + static const char *rtmp_stream_getname(void *unused) { UNUSED_PARAMETER(unused); @@ -107,6 +125,8 @@ static void rtmp_stream_destroy(void *data) #ifdef TEST_FRAMEDROPS circlebuf_free(&stream->droptest_info); #endif + circlebuf_free(&stream->dbr_frames); + pthread_mutex_destroy(&stream->dbr_mutex); os_event_destroy(stream->buffer_space_available_event); os_event_destroy(stream->buffer_has_data_event); @@ -139,23 +159,28 @@ static void *rtmp_stream_create(obs_data_t *settings, obs_output_t *output) goto fail; } + if (pthread_mutex_init(&stream->dbr_mutex, NULL) != 0) { + warn("Failed to initialize dbr mutex"); + goto fail; + } + if (os_event_init(&stream->buffer_space_available_event, - OS_EVENT_TYPE_AUTO) != 0) { + OS_EVENT_TYPE_AUTO) != 0) { warn("Failed to initialize write buffer event"); goto fail; } - if (os_event_init(&stream->buffer_has_data_event, - OS_EVENT_TYPE_AUTO) != 0) { + if (os_event_init(&stream->buffer_has_data_event, OS_EVENT_TYPE_AUTO) != + 0) { warn("Failed to initialize data buffer event"); goto fail; } if (os_event_init(&stream->socket_available_event, - OS_EVENT_TYPE_AUTO) != 0) { + OS_EVENT_TYPE_AUTO) != 0) { warn("Failed to initialize socket buffer event"); goto fail; } if (os_event_init(&stream->send_thread_signaled_exit, - OS_EVENT_TYPE_MANUAL) != 0) { + OS_EVENT_TYPE_MANUAL) != 0) { warn("Failed to initialize socket exit event"); goto fail; } @@ -181,7 +206,8 @@ static void rtmp_stream_stop(void *data, uint64_t ts) stream->stop_ts = ts / 1000ULL; if (ts) - stream->shutdown_timeout_ts = ts + + stream->shutdown_timeout_ts = + ts + (uint64_t)stream->max_shutdown_time_sec * 1000000000ULL; if (active(stream)) { @@ -195,27 +221,27 @@ static void rtmp_stream_stop(void *data, uint64_t ts) static inline void set_rtmp_str(AVal *val, const char *str) { - bool valid = (str && *str); - val->av_val = valid ? (char*)str : NULL; + bool valid = (str && *str); + val->av_val = valid ? (char *)str : NULL; val->av_len = valid ? (int)strlen(str) : 0; } static inline void set_rtmp_dstr(AVal *val, struct dstr *str) { - bool valid = !dstr_is_empty(str); - val->av_val = valid ? str->array : NULL; + bool valid = !dstr_is_empty(str); + val->av_val = valid ? str->array : NULL; val->av_len = valid ? (int)str->len : 0; } static inline bool get_next_packet(struct rtmp_stream *stream, - struct encoder_packet *packet) + struct encoder_packet *packet) { bool new_packet = false; pthread_mutex_lock(&stream->packets_mutex); if (stream->packets.size) { circlebuf_pop_front(&stream->packets, packet, - sizeof(struct encoder_packet)); + sizeof(struct encoder_packet)); new_packet = true; } pthread_mutex_unlock(&stream->packets_mutex); @@ -251,7 +277,7 @@ static bool discard_recv_data(struct rtmp_stream *stream, size_t size) #endif if (ret < 0) { do_log(LOG_ERROR, "recv error: %d (%d bytes)", - error, (int)size); + error, (int)size); } return false; } @@ -266,6 +292,49 @@ static void droptest_cap_data_rate(struct rtmp_stream *stream, size_t size) uint64_t ts = os_gettime_ns(); struct droptest_info info; +#if defined(_WIN32) && defined(TEST_FRAMEDROPS_WITH_BITRATE_SHORTCUTS) + uint64_t check_elapsed = ts - stream->droptest_last_key_check; + + if (check_elapsed > (200ULL * MSEC_TO_NSEC)) { + size_t bitrate = 0; + + stream->droptest_last_key_check = ts; + + if (GetAsyncKeyState(VK_NUMPAD0) & 0x8000) { + stream->droptest_max = 0; + } else if (GetAsyncKeyState(VK_NUMPAD1) & 0x8000) { + bitrate = 1000; + } else if (GetAsyncKeyState(VK_NUMPAD2) & 0x8000) { + bitrate = 2000; + } else if (GetAsyncKeyState(VK_NUMPAD3) & 0x8000) { + bitrate = 3000; + } else if (GetAsyncKeyState(VK_NUMPAD4) & 0x8000) { + bitrate = 4000; + } else if (GetAsyncKeyState(VK_NUMPAD5) & 0x8000) { + bitrate = 5000; + } else if (GetAsyncKeyState(VK_NUMPAD6) & 0x8000) { + bitrate = 6000; + } else if (GetAsyncKeyState(VK_NUMPAD7) & 0x8000) { + bitrate = 7000; + } else if (GetAsyncKeyState(VK_NUMPAD8) & 0x8000) { + bitrate = 8000; + } else if (GetAsyncKeyState(VK_NUMPAD9) & 0x8000) { + bitrate = 9000; + } + + if (bitrate) { + stream->droptest_max = (bitrate * 1000 / 8); + } + } + if (!stream->droptest_max) { + return; + } +#else + if (!stream->droptest_max) { + stream->droptest_max = DROPTEST_MAX_BYTES; + } +#endif + info.ts = ts; info.size = size; @@ -273,10 +342,10 @@ static void droptest_cap_data_rate(struct rtmp_stream *stream, size_t size) stream->droptest_size += size; if (stream->droptest_info.size) { - circlebuf_peek_front(&stream->droptest_info, - &info, sizeof(info)); + circlebuf_peek_front(&stream->droptest_info, &info, + sizeof(info)); - if (stream->droptest_size > DROPTEST_MAX_BYTES) { + if (stream->droptest_size > stream->droptest_max) { uint64_t elapsed = ts - info.ts; if (elapsed < 1000000000ULL) { @@ -284,9 +353,9 @@ static void droptest_cap_data_rate(struct rtmp_stream *stream, size_t size) os_sleepto_ns(ts + elapsed); } - while (stream->droptest_size > DROPTEST_MAX_BYTES) { + while (stream->droptest_size > stream->droptest_max) { circlebuf_pop_front(&stream->droptest_info, - &info, sizeof(info)); + &info, sizeof(info)); stream->droptest_size -= info.size; } } @@ -294,7 +363,8 @@ static void droptest_cap_data_rate(struct rtmp_stream *stream, size_t size) } #endif -static int socket_queue_data(RTMPSockBuf *sb, const char *data, int len, void *arg) +static int socket_queue_data(RTMPSockBuf *sb, const char *data, int len, + void *arg) { UNUSED_PARAMETER(sb); @@ -323,23 +393,24 @@ retry_send: pthread_mutex_unlock(&stream->write_buf_mutex); - os_event_signal (stream->buffer_has_data_event); + os_event_signal(stream->buffer_has_data_event); return len; } static int send_packet(struct rtmp_stream *stream, - struct encoder_packet *packet, bool is_header, size_t idx) + struct encoder_packet *packet, bool is_header, + size_t idx) { uint8_t *data; - size_t size; - int recv_size = 0; - int ret = 0; + size_t size; + int recv_size = 0; + int ret = 0; if (!stream->new_socket_loop) { #ifdef _WIN32 ret = ioctlsocket(stream->rtmp.m_sb.sb_socket, FIONREAD, - (u_long*)&recv_size); + (u_long *)&recv_size); #else ret = ioctl(stream->rtmp.m_sb.sb_socket, FIONREAD, &recv_size); #endif @@ -350,14 +421,14 @@ static int send_packet(struct rtmp_stream *stream, } } - flv_packet_mux(packet, is_header ? 0 : stream->start_dts_offset, - &data, &size, is_header); + flv_packet_mux(packet, is_header ? 0 : stream->start_dts_offset, &data, + &size, is_header); #ifdef TEST_FRAMEDROPS droptest_cap_data_rate(stream, size); #endif - ret = RTMP_Write(&stream->rtmp, (char*)data, (int)size, (int)idx); + ret = RTMP_Write(&stream->rtmp, (char *)data, (int)size, (int)idx); bfree(data); if (is_header) @@ -372,14 +443,14 @@ static int send_packet(struct rtmp_stream *stream, static inline bool send_headers(struct rtmp_stream *stream); static inline bool can_shutdown_stream(struct rtmp_stream *stream, - struct encoder_packet *packet) + struct encoder_packet *packet) { uint64_t cur_time = os_gettime_ns(); bool timeout = cur_time >= stream->shutdown_timeout_ts; if (timeout) info("Stream shutdown timeout reached (%d second(s))", - stream->max_shutdown_time_sec); + stream->max_shutdown_time_sec); return timeout || packet->sys_dts_usec >= (int64_t)stream->stop_ts; } @@ -388,8 +459,7 @@ static void set_output_error(struct rtmp_stream *stream) { const char *msg = NULL; #ifdef _WIN32 - switch (stream->rtmp.last_error_code) - { + switch (stream->rtmp.last_error_code) { case WSAETIMEDOUT: msg = obs_module_text("ConnectionTimedOut"); break; @@ -413,8 +483,7 @@ static void set_output_error(struct rtmp_stream *stream) break; } #else - switch (stream->rtmp.last_error_code) - { + switch (stream->rtmp.last_error_code) { case ETIMEDOUT: msg = obs_module_text("ConnectionTimedOut"); break; @@ -451,6 +520,39 @@ static void set_output_error(struct rtmp_stream *stream) obs_output_set_last_error(stream->output, msg); } +static void dbr_add_frame(struct rtmp_stream *stream, struct dbr_frame *back) +{ + struct dbr_frame front; + uint64_t dur; + + circlebuf_push_back(&stream->dbr_frames, back, sizeof(*back)); + circlebuf_peek_front(&stream->dbr_frames, &front, sizeof(front)); + + stream->dbr_data_size += back->size; + + dur = (back->send_end - front.send_beg) / 1000000; + + if (dur >= MAX_ESTIMATE_DURATION_MS) { + stream->dbr_data_size -= front.size; + circlebuf_pop_front(&stream->dbr_frames, NULL, sizeof(front)); + } + + stream->dbr_est_bitrate = + (dur >= MIN_ESTIMATE_DURATION_MS) + ? (long)(stream->dbr_data_size * 1000 / dur) + : 0; + stream->dbr_est_bitrate *= 8; + stream->dbr_est_bitrate /= 1000; + + if (stream->dbr_est_bitrate) { + stream->dbr_est_bitrate -= stream->audio_bitrate; + if (stream->dbr_est_bitrate < 50) + stream->dbr_est_bitrate = 50; + } +} + +static void dbr_set_bitrate(struct rtmp_stream *stream); + static void *send_thread(void *data) { struct rtmp_stream *stream = data; @@ -459,6 +561,7 @@ static void *send_thread(void *data) while (os_sem_wait(stream->send_sem) == 0) { struct encoder_packet packet; + struct dbr_frame dbr_frame; if (stopping(stream) && stream->stop_ts == 0) { break; @@ -481,10 +584,23 @@ static void *send_thread(void *data) } } + if (stream->dbr_enabled) { + dbr_frame.send_beg = os_gettime_ns(); + dbr_frame.size = packet.size; + } + if (send_packet(stream, &packet, false, packet.track_idx) < 0) { os_atomic_set_bool(&stream->disconnected, true); break; } + + if (stream->dbr_enabled) { + dbr_frame.send_end = os_gettime_ns(); + + pthread_mutex_lock(&stream->dbr_mutex); + dbr_add_frame(stream, &dbr_frame); + pthread_mutex_unlock(&stream->dbr_mutex); + } } bool encode_error = os_atomic_load_bool(&stream->encode_error); @@ -521,21 +637,30 @@ static void *send_thread(void *data) os_event_reset(stream->stop_event); os_atomic_set_bool(&stream->active, false); stream->sent_headers = false; + + /* reset bitrate on stop */ + if (stream->dbr_enabled) { + if (stream->dbr_cur_bitrate != stream->dbr_orig_bitrate) { + stream->dbr_cur_bitrate = stream->dbr_orig_bitrate; + dbr_set_bitrate(stream); + } + } + return NULL; } static bool send_meta_data(struct rtmp_stream *stream, size_t idx, bool *next) { uint8_t *meta_data; - size_t meta_data_size; - bool success = true; + size_t meta_data_size; + bool success = true; - *next = flv_meta_data(stream->output, &meta_data, - &meta_data_size, false, idx); + *next = flv_meta_data(stream->output, &meta_data, &meta_data_size, + false, idx); if (*next) { - success = RTMP_Write(&stream->rtmp, (char*)meta_data, - (int)meta_data_size, (int)idx) >= 0; + success = RTMP_Write(&stream->rtmp, (char *)meta_data, + (int)meta_data_size, (int)idx) >= 0; bfree(meta_data); } @@ -543,16 +668,14 @@ static bool send_meta_data(struct rtmp_stream *stream, size_t idx, bool *next) } static bool send_audio_header(struct rtmp_stream *stream, size_t idx, - bool *next) + bool *next) { - obs_output_t *context = stream->output; + obs_output_t *context = stream->output; obs_encoder_t *aencoder = obs_output_get_audio_encoder(context, idx); - uint8_t *header; + uint8_t *header; - struct encoder_packet packet = { - .type = OBS_ENCODER_AUDIO, - .timebase_den = 1 - }; + struct encoder_packet packet = {.type = OBS_ENCODER_AUDIO, + .timebase_den = 1}; if (!aencoder) { *next = false; @@ -566,16 +689,13 @@ static bool send_audio_header(struct rtmp_stream *stream, size_t idx, static bool send_video_header(struct rtmp_stream *stream) { - obs_output_t *context = stream->output; + obs_output_t *context = stream->output; obs_encoder_t *vencoder = obs_output_get_video_encoder(context); - uint8_t *header; - size_t size; + uint8_t *header; + size_t size; - struct encoder_packet packet = { - .type = OBS_ENCODER_VIDEO, - .timebase_den = 1, - .keyframe = true - }; + struct encoder_packet packet = { + .type = OBS_ENCODER_VIDEO, .timebase_den = 1, .keyframe = true}; obs_encoder_get_extra_data(vencoder, &header, &size); packet.size = obs_parse_avc_header(&packet.data, header, size); @@ -619,12 +739,12 @@ static void adjust_sndbuf_size(struct rtmp_stream *stream, int new_size) socklen_t int_size = sizeof(int); getsockopt(stream->rtmp.m_sb.sb_socket, SOL_SOCKET, SO_SNDBUF, - (char*)&cur_sendbuf_size, &int_size); + (char *)&cur_sendbuf_size, &int_size); if (cur_sendbuf_size < new_size) { cur_sendbuf_size = new_size; setsockopt(stream->rtmp.m_sb.sb_socket, SOL_SOCKET, SO_SNDBUF, - (const char*)&cur_sendbuf_size, int_size); + (const char *)&cur_sendbuf_size, int_size); } } @@ -670,18 +790,19 @@ static int init_send(struct rtmp_stream *stream) bfree(stream->write_buf); int total_bitrate = 0; - obs_output_t *context = stream->output; + obs_output_t *context = stream->output; obs_encoder_t *vencoder = obs_output_get_video_encoder(context); if (vencoder) { obs_data_t *params = obs_encoder_get_settings(vencoder); if (params) { - int bitrate = obs_data_get_int(params, "bitrate"); + int bitrate = + obs_data_get_int(params, "bitrate"); if (!bitrate) { - warn ("Video encoder didn't return a " - "valid bitrate, new network " - "code may function poorly. " - "Low latency mode disabled."); + warn("Video encoder didn't return a " + "valid bitrate, new network " + "code may function poorly. " + "Low latency mode disabled."); stream->low_latency_mode = false; bitrate = 10000; } @@ -690,11 +811,13 @@ static int init_send(struct rtmp_stream *stream) } } - obs_encoder_t *aencoder = obs_output_get_audio_encoder(context, 0); + obs_encoder_t *aencoder = + obs_output_get_audio_encoder(context, 0); if (aencoder) { obs_data_t *params = obs_encoder_get_settings(aencoder); if (params) { - int bitrate = obs_data_get_int(params, "bitrate"); + int bitrate = + obs_data_get_int(params, "bitrate"); if (!bitrate) bitrate = 160; total_bitrate += bitrate; @@ -713,7 +836,7 @@ static int init_send(struct rtmp_stream *stream) #ifdef _WIN32 ret = pthread_create(&stream->socket_thread, NULL, - socket_thread_windows, stream); + socket_thread_windows, stream); #else warn("New socket loop not supported on this platform"); return OBS_OUTPUT_ERROR; @@ -764,13 +887,13 @@ static void win32_log_interface_type(struct rtmp_stream *stream) if (!h) return; - dest_addr = *(uint32_t*)h->h_addr_list[0]; + dest_addr = *(uint32_t *)h->h_addr_list[0]; if (rtmp->m_bindIP.addrLen == 0) source_addr = 0; else if (rtmp->m_bindIP.addr.ss_family == AF_INET) - source_addr = (*(struct sockaddr_in*)&rtmp->m_bindIP) - .sin_addr.S_un.S_addr; + source_addr = (*(struct sockaddr_in *)&rtmp->m_bindIP.addr) + .sin_addr.S_un.S_addr; else return; @@ -780,7 +903,7 @@ static void win32_log_interface_type(struct rtmp_stream *stream) row.dwIndex = route.dwForwardIfIndex; if (!GetIfEntry(&row)) { - uint32_t speed =row.dwSpeed / 1000000; + uint32_t speed = row.dwSpeed / 1000000; char *type; struct dstr other = {0}; @@ -794,7 +917,7 @@ static void win32_log_interface_type(struct rtmp_stream *stream) } info("Interface: %s (%s, %lu mbps)", row.bDescr, type, - speed); + speed); dstr_free(&other); } @@ -819,18 +942,19 @@ static int try_connect(struct rtmp_stream *stream) dstr_copy(&stream->encoder_name, "FMLE/3.0 (compatible; FMSc/1.0)"); - set_rtmp_dstr(&stream->rtmp.Link.pubUser, &stream->username); + set_rtmp_dstr(&stream->rtmp.Link.pubUser, &stream->username); set_rtmp_dstr(&stream->rtmp.Link.pubPasswd, &stream->password); - set_rtmp_dstr(&stream->rtmp.Link.flashVer, &stream->encoder_name); + set_rtmp_dstr(&stream->rtmp.Link.flashVer, &stream->encoder_name); stream->rtmp.Link.swfUrl = stream->rtmp.Link.tcUrl; if (dstr_is_empty(&stream->bind_ip) || dstr_cmp(&stream->bind_ip, "default") == 0) { - memset(&stream->rtmp.m_bindIP, 0, sizeof(stream->rtmp.m_bindIP)); + memset(&stream->rtmp.m_bindIP, 0, + sizeof(stream->rtmp.m_bindIP)); } else { bool success = netif_str_to_addr(&stream->rtmp.m_bindIP.addr, - &stream->rtmp.m_bindIP.addrLen, - stream->bind_ip.array); + &stream->rtmp.m_bindIP.addrLen, + stream->bind_ip.array); if (success) { int len = stream->rtmp.m_bindIP.addrLen; bool ipv6 = len == sizeof(struct sockaddr_in6); @@ -841,8 +965,8 @@ static int try_connect(struct rtmp_stream *stream) RTMP_AddStream(&stream->rtmp, stream->key.array); for (size_t idx = 1;; idx++) { - obs_encoder_t *encoder = obs_output_get_audio_encoder( - stream->output, idx); + obs_encoder_t *encoder = + obs_output_get_audio_encoder(stream->output, idx); const char *encoder_name; if (!encoder) @@ -852,9 +976,9 @@ static int try_connect(struct rtmp_stream *stream) RTMP_AddStream(&stream->rtmp, encoder_name); } - stream->rtmp.m_outChunkSize = 4096; + stream->rtmp.m_outChunkSize = 4096; stream->rtmp.m_bSendChunkSizeInfo = true; - stream->rtmp.m_bUseNagle = true; + stream->rtmp.m_bUseNagle = true; #ifdef _WIN32 win32_log_interface_type(stream); @@ -880,6 +1004,7 @@ static bool init_connect(struct rtmp_stream *stream) const char *bind_ip; int64_t drop_p; int64_t drop_b; + uint32_t caps; if (stopping(stream)) { pthread_join(stream->send_thread, NULL); @@ -894,13 +1019,13 @@ static bool init_connect(struct rtmp_stream *stream) os_atomic_set_bool(&stream->disconnected, false); os_atomic_set_bool(&stream->encode_error, false); stream->total_bytes_sent = 0; - stream->dropped_frames = 0; - stream->min_priority = 0; - stream->got_first_video = false; + stream->dropped_frames = 0; + stream->min_priority = 0; + stream->got_first_video = false; settings = obs_output_get_settings(stream->output); - dstr_copy(&stream->path, obs_service_get_url(service)); - dstr_copy(&stream->key, obs_service_get_key(service)); + dstr_copy(&stream->path, obs_service_get_url(service)); + dstr_copy(&stream->key, obs_service_get_key(service)); dstr_copy(&stream->username, obs_service_get_username(service)); dstr_copy(&stream->password, obs_service_get_password(service)); dstr_depad(&stream->path); @@ -910,6 +1035,37 @@ static bool init_connect(struct rtmp_stream *stream) stream->max_shutdown_time_sec = (int)obs_data_get_int(settings, OPT_MAX_SHUTDOWN_TIME_SEC); + obs_encoder_t *venc = obs_output_get_video_encoder(stream->output); + obs_encoder_t *aenc = obs_output_get_audio_encoder(stream->output, 0); + obs_data_t *vsettings = obs_encoder_get_settings(venc); + obs_data_t *asettings = obs_encoder_get_settings(aenc); + + circlebuf_free(&stream->dbr_frames); + stream->audio_bitrate = (long)obs_data_get_int(asettings, "bitrate"); + stream->dbr_data_size = 0; + stream->dbr_orig_bitrate = (long)obs_data_get_int(vsettings, "bitrate"); + stream->dbr_cur_bitrate = stream->dbr_orig_bitrate; + stream->dbr_est_bitrate = 0; + stream->dbr_inc_bitrate = stream->dbr_orig_bitrate / 10; + stream->dbr_inc_timeout = 0; + stream->dbr_enabled = obs_data_get_bool(settings, OPT_DYN_BITRATE); + + caps = obs_encoder_get_caps(venc); + if ((caps & OBS_ENCODER_CAP_DYN_BITRATE) == 0) { + stream->dbr_enabled = false; + } + + if (obs_output_get_delay(stream->output) != 0) { + stream->dbr_enabled = false; + } + + if (stream->dbr_enabled) { + info("Dynamic bitrate enabled. Dropped frames begone!"); + } + + obs_data_release(vsettings); + obs_data_release(asettings); + if (drop_p < (drop_b + 200)) drop_p = drop_b + 200; @@ -919,10 +1075,10 @@ static bool init_connect(struct rtmp_stream *stream) bind_ip = obs_data_get_string(settings, OPT_BIND_IP); dstr_copy(&stream->bind_ip, bind_ip); - stream->new_socket_loop = obs_data_get_bool(settings, - OPT_NEWSOCKETLOOP_ENABLED); - stream->low_latency_mode = obs_data_get_bool(settings, - OPT_LOWLATENCY_ENABLED); + stream->new_socket_loop = + obs_data_get_bool(settings, OPT_NEWSOCKETLOOP_ENABLED); + stream->low_latency_mode = + obs_data_get_bool(settings, OPT_LOWLATENCY_ENABLED); obs_data_release(settings); return true; @@ -965,14 +1121,14 @@ static bool rtmp_stream_start(void *data) os_atomic_set_bool(&stream->connecting, true); return pthread_create(&stream->connect_thread, NULL, connect_thread, - stream) == 0; + stream) == 0; } static inline bool add_packet(struct rtmp_stream *stream, - struct encoder_packet *packet) + struct encoder_packet *packet) { circlebuf_push_back(&stream->packets, packet, - sizeof(struct encoder_packet)); + sizeof(struct encoder_packet)); return true; } @@ -982,12 +1138,12 @@ static inline size_t num_buffered_packets(struct rtmp_stream *stream) } static void drop_frames(struct rtmp_stream *stream, const char *name, - int highest_priority, bool pframes) + int highest_priority, bool pframes) { UNUSED_PARAMETER(pframes); - struct circlebuf new_buf = {0}; - int num_frames_dropped = 0; + struct circlebuf new_buf = {0}; + int num_frames_dropped = 0; #ifdef _DEBUG int start_packets = (int)num_buffered_packets(stream); @@ -1002,7 +1158,7 @@ static void drop_frames(struct rtmp_stream *stream, const char *name, circlebuf_pop_front(&stream->packets, &packet, sizeof(packet)); /* do not drop audio data or video keyframes */ - if (packet.type == OBS_ENCODER_AUDIO || + if (packet.type == OBS_ENCODER_AUDIO || packet.drop_priority >= highest_priority) { circlebuf_push_back(&new_buf, &packet, sizeof(packet)); @@ -1022,21 +1178,19 @@ static void drop_frames(struct rtmp_stream *stream, const char *name, stream->dropped_frames += num_frames_dropped; #ifdef _DEBUG - debug("Dropped %s, prev packet count: %d, new packet count: %d", - name, - start_packets, - (int)num_buffered_packets(stream)); + debug("Dropped %s, prev packet count: %d, new packet count: %d", name, + start_packets, (int)num_buffered_packets(stream)); #endif } static bool find_first_video_packet(struct rtmp_stream *stream, - struct encoder_packet *first) + struct encoder_packet *first) { size_t count = stream->packets.size / sizeof(*first); for (size_t i = 0; i < count; i++) { - struct encoder_packet *cur = circlebuf_data(&stream->packets, - i * sizeof(*first)); + struct encoder_packet *cur = + circlebuf_data(&stream->packets, i * sizeof(*first)); if (cur->type == OBS_ENCODER_VIDEO && !cur->keyframe) { *first = *cur; return true; @@ -1046,17 +1200,118 @@ static bool find_first_video_packet(struct rtmp_stream *stream, return false; } +static bool dbr_bitrate_lowered(struct rtmp_stream *stream) +{ + long prev_bitrate = stream->dbr_prev_bitrate; + long est_bitrate = 0; + long new_bitrate; + + if (stream->dbr_est_bitrate && + stream->dbr_est_bitrate < stream->dbr_cur_bitrate) { + stream->dbr_data_size = 0; + circlebuf_pop_front(&stream->dbr_frames, NULL, + stream->dbr_frames.size); + est_bitrate = stream->dbr_est_bitrate / 100 * 100; + if (est_bitrate < 50) { + est_bitrate = 50; + } + } + +#if 0 + if (prev_bitrate && est_bitrate) { + if (prev_bitrate < est_bitrate) { + blog(LOG_INFO, "going back to prev bitrate: " + "prev_bitrate (%d) < est_bitrate (%d)", + prev_bitrate, + est_bitrate); + new_bitrate = prev_bitrate; + } else { + new_bitrate = est_bitrate; + } + new_bitrate = est_bitrate; + } else if (prev_bitrate) { + new_bitrate = prev_bitrate; + info("going back to prev bitrate"); + + } else if (est_bitrate) { + new_bitrate = est_bitrate; + + } else { + return false; + } +#else + if (est_bitrate) { + new_bitrate = est_bitrate; + + } else if (prev_bitrate) { + new_bitrate = prev_bitrate; + info("going back to prev bitrate"); + + } else { + return false; + } + + if (new_bitrate == stream->dbr_cur_bitrate) { + return false; + } +#endif + + stream->dbr_prev_bitrate = 0; + stream->dbr_cur_bitrate = new_bitrate; + stream->dbr_inc_timeout = os_gettime_ns() + DBR_INC_TIMER; + info("bitrate decreased to: %ld", stream->dbr_cur_bitrate); + return true; +} + +static void dbr_set_bitrate(struct rtmp_stream *stream) +{ + obs_encoder_t *vencoder = obs_output_get_video_encoder(stream->output); + obs_data_t *settings = obs_encoder_get_settings(vencoder); + + obs_data_set_int(settings, "bitrate", stream->dbr_cur_bitrate); + obs_encoder_update(vencoder, settings); + + obs_data_release(settings); +} + +static void dbr_inc_bitrate(struct rtmp_stream *stream) +{ + stream->dbr_prev_bitrate = stream->dbr_cur_bitrate; + stream->dbr_cur_bitrate += stream->dbr_inc_bitrate; + + if (stream->dbr_cur_bitrate >= stream->dbr_orig_bitrate) { + stream->dbr_cur_bitrate = stream->dbr_orig_bitrate; + info("bitrate increased to: %ld, done", + stream->dbr_cur_bitrate); + } else if (stream->dbr_cur_bitrate < stream->dbr_orig_bitrate) { + stream->dbr_inc_timeout = os_gettime_ns() + DBR_INC_TIMER; + info("bitrate increased to: %ld, waiting", + stream->dbr_cur_bitrate); + } +} + static void check_to_drop_frames(struct rtmp_stream *stream, bool pframes) { struct encoder_packet first; int64_t buffer_duration_usec; size_t num_packets = num_buffered_packets(stream); const char *name = pframes ? "p-frames" : "b-frames"; - int priority = pframes ? - OBS_NAL_PRIORITY_HIGHEST : OBS_NAL_PRIORITY_HIGH; - int64_t drop_threshold = pframes ? - stream->pframe_drop_threshold_usec : - stream->drop_threshold_usec; + int priority = pframes ? OBS_NAL_PRIORITY_HIGHEST + : OBS_NAL_PRIORITY_HIGH; + int64_t drop_threshold = pframes ? stream->pframe_drop_threshold_usec + : stream->drop_threshold_usec; + + if (!pframes && stream->dbr_enabled) { + if (stream->dbr_inc_timeout) { + uint64_t t = os_gettime_ns(); + + if (t >= stream->dbr_inc_timeout) { + stream->dbr_inc_timeout = 0; + dbr_inc_bitrate(stream); + dbr_set_bitrate(stream); + } + } + } if (num_packets < 5) { if (!pframes) @@ -1072,8 +1327,33 @@ static void check_to_drop_frames(struct rtmp_stream *stream, bool pframes) buffer_duration_usec = stream->last_dts_usec - first.dts_usec; if (!pframes) { - stream->congestion = (float)buffer_duration_usec / - (float)drop_threshold; + stream->congestion = + (float)buffer_duration_usec / (float)drop_threshold; + } + + /* alternatively, drop only pframes: + * (!pframes && stream->dbr_enabled) + * but let's test without dropping frames + * at all first */ + if (stream->dbr_enabled) { + bool bitrate_changed = false; + + if (pframes) { + return; + } + + if (buffer_duration_usec >= DBR_TRIGGER_USEC) { + pthread_mutex_lock(&stream->dbr_mutex); + bitrate_changed = dbr_bitrate_lowered(stream); + pthread_mutex_unlock(&stream->dbr_mutex); + } + + if (bitrate_changed) { + debug("buffer_duration_msec: %" PRId64, + buffer_duration_usec / 1000); + dbr_set_bitrate(stream); + } + return; } if (buffer_duration_usec > drop_threshold) { @@ -1083,7 +1363,7 @@ static void check_to_drop_frames(struct rtmp_stream *stream, bool pframes) } static bool add_video_packet(struct rtmp_stream *stream, - struct encoder_packet *packet) + struct encoder_packet *packet) { check_to_drop_frames(stream, false); check_to_drop_frames(stream, true); @@ -1103,9 +1383,9 @@ static bool add_video_packet(struct rtmp_stream *stream, static void rtmp_stream_data(void *data, struct encoder_packet *packet) { - struct rtmp_stream *stream = data; + struct rtmp_stream *stream = data; struct encoder_packet new_packet; - bool added_packet = false; + bool added_packet = false; if (disconnected(stream) || !active(stream)) return; @@ -1132,9 +1412,9 @@ static void rtmp_stream_data(void *data, struct encoder_packet *packet) pthread_mutex_lock(&stream->packets_mutex); if (!disconnected(stream)) { - added_packet = (packet->type == OBS_ENCODER_VIDEO) ? - add_video_packet(stream, &new_packet) : - add_packet(stream, &new_packet); + added_packet = (packet->type == OBS_ENCODER_VIDEO) + ? add_video_packet(stream, &new_packet) + : add_packet(stream, &new_packet); } pthread_mutex_unlock(&stream->packets_mutex); @@ -1164,12 +1444,13 @@ static obs_properties_t *rtmp_stream_properties(void *unused) obs_property_t *p; obs_properties_add_int(props, OPT_DROP_THRESHOLD, - obs_module_text("RTMPStream.DropThreshold"), - 200, 10000, 100); + obs_module_text("RTMPStream.DropThreshold"), 200, + 10000, 100); p = obs_properties_add_list(props, OPT_BIND_IP, - obs_module_text("RTMPStream.BindIP"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + obs_module_text("RTMPStream.BindIP"), + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, obs_module_text("Default"), "default"); @@ -1181,9 +1462,9 @@ static obs_properties_t *rtmp_stream_properties(void *unused) netif_saddr_data_free(&addrs); obs_properties_add_bool(props, OPT_NEWSOCKETLOOP_ENABLED, - obs_module_text("RTMPStream.NewSocketLoop")); + obs_module_text("RTMPStream.NewSocketLoop")); obs_properties_add_bool(props, OPT_LOWLATENCY_ENABLED, - obs_module_text("RTMPStream.LowLatencyMode")); + obs_module_text("RTMPStream.LowLatencyMode")); return props; } @@ -1206,7 +1487,7 @@ static float rtmp_stream_congestion(void *data) if (stream->new_socket_loop) return (float)stream->write_buf_len / - (float)stream->write_buf_size; + (float)stream->write_buf_size; else return stream->min_priority > 0 ? 1.0f : stream->congestion; } @@ -1218,23 +1499,21 @@ static int rtmp_stream_connect_time(void *data) } struct obs_output_info rtmp_output_info = { - .id = "rtmp_output", - .flags = OBS_OUTPUT_AV | - OBS_OUTPUT_ENCODED | - OBS_OUTPUT_SERVICE | - OBS_OUTPUT_MULTI_TRACK, + .id = "rtmp_output", + .flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_SERVICE | + OBS_OUTPUT_MULTI_TRACK, .encoded_video_codecs = "h264", .encoded_audio_codecs = "aac", - .get_name = rtmp_stream_getname, - .create = rtmp_stream_create, - .destroy = rtmp_stream_destroy, - .start = rtmp_stream_start, - .stop = rtmp_stream_stop, - .encoded_packet = rtmp_stream_data, - .get_defaults = rtmp_stream_defaults, - .get_properties = rtmp_stream_properties, - .get_total_bytes = rtmp_stream_total_bytes_sent, - .get_congestion = rtmp_stream_congestion, - .get_connect_time_ms = rtmp_stream_connect_time, - .get_dropped_frames = rtmp_stream_dropped_frames + .get_name = rtmp_stream_getname, + .create = rtmp_stream_create, + .destroy = rtmp_stream_destroy, + .start = rtmp_stream_start, + .stop = rtmp_stream_stop, + .encoded_packet = rtmp_stream_data, + .get_defaults = rtmp_stream_defaults, + .get_properties = rtmp_stream_properties, + .get_total_bytes = rtmp_stream_total_bytes_sent, + .get_congestion = rtmp_stream_congestion, + .get_connect_time_ms = rtmp_stream_connect_time, + .get_dropped_frames = rtmp_stream_dropped_frames, }; diff --git a/plugins/obs-outputs/rtmp-stream.h b/plugins/obs-outputs/rtmp-stream.h index 77d1b44..2aeb787 100644 --- a/plugins/obs-outputs/rtmp-stream.h +++ b/plugins/obs-outputs/rtmp-stream.h @@ -16,14 +16,15 @@ #include #endif -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[rtmp stream: '%s'] " format, \ - obs_output_get_name(stream->output), ##__VA_ARGS__) + obs_output_get_name(stream->output), ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) -#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#define OPT_DYN_BITRATE "dyn_bitrate" #define OPT_DROP_THRESHOLD "drop_threshold_ms" #define OPT_PFRAME_DROP_THRESHOLD "pframe_drop_threshold_ms" #define OPT_MAX_SHUTDOWN_TIME_SEC "max_shutdown_time_sec" @@ -32,6 +33,7 @@ #define OPT_LOWLATENCY_ENABLED "low_latency_mode_enabled" //#define TEST_FRAMEDROPS +//#define TEST_FRAMEDROPS_WITH_BITRATE_SHORTCUTS #ifdef TEST_FRAMEDROPS @@ -44,67 +46,87 @@ struct droptest_info { }; #endif +struct dbr_frame { + uint64_t send_beg; + uint64_t send_end; + size_t size; +}; + struct rtmp_stream { - obs_output_t *output; + obs_output_t *output; - pthread_mutex_t packets_mutex; + pthread_mutex_t packets_mutex; struct circlebuf packets; - bool sent_headers; + bool sent_headers; - bool got_first_video; - int64_t start_dts_offset; + bool got_first_video; + int64_t start_dts_offset; - volatile bool connecting; - pthread_t connect_thread; + volatile bool connecting; + pthread_t connect_thread; - volatile bool active; - volatile bool disconnected; - volatile bool encode_error; - pthread_t send_thread; + volatile bool active; + volatile bool disconnected; + volatile bool encode_error; + pthread_t send_thread; - int max_shutdown_time_sec; + int max_shutdown_time_sec; - os_sem_t *send_sem; - os_event_t *stop_event; - uint64_t stop_ts; - uint64_t shutdown_timeout_ts; + os_sem_t *send_sem; + os_event_t *stop_event; + uint64_t stop_ts; + uint64_t shutdown_timeout_ts; - struct dstr path, key; - struct dstr username, password; - struct dstr encoder_name; - struct dstr bind_ip; + struct dstr path, key; + struct dstr username, password; + struct dstr encoder_name; + struct dstr bind_ip; /* frame drop variables */ - int64_t drop_threshold_usec; - int64_t pframe_drop_threshold_usec; - int min_priority; - float congestion; + int64_t drop_threshold_usec; + int64_t pframe_drop_threshold_usec; + int min_priority; + float congestion; - int64_t last_dts_usec; + int64_t last_dts_usec; - uint64_t total_bytes_sent; - int dropped_frames; + uint64_t total_bytes_sent; + int dropped_frames; #ifdef TEST_FRAMEDROPS struct circlebuf droptest_info; - size_t droptest_size; + uint64_t droptest_last_key_check; + size_t droptest_max; + size_t droptest_size; #endif - RTMP rtmp; + pthread_mutex_t dbr_mutex; + struct circlebuf dbr_frames; + size_t dbr_data_size; + uint64_t dbr_inc_timeout; + long audio_bitrate; + long dbr_est_bitrate; + long dbr_orig_bitrate; + long dbr_prev_bitrate; + long dbr_cur_bitrate; + long dbr_inc_bitrate; + bool dbr_enabled; - bool new_socket_loop; - bool low_latency_mode; - bool disable_send_window_optimization; - bool socket_thread_active; - pthread_t socket_thread; - uint8_t *write_buf; - size_t write_buf_len; - size_t write_buf_size; - pthread_mutex_t write_buf_mutex; - os_event_t *buffer_space_available_event; - os_event_t *buffer_has_data_event; - os_event_t *socket_available_event; - os_event_t *send_thread_signaled_exit; + RTMP rtmp; + + bool new_socket_loop; + bool low_latency_mode; + bool disable_send_window_optimization; + bool socket_thread_active; + pthread_t socket_thread; + uint8_t *write_buf; + size_t write_buf_len; + size_t write_buf_size; + pthread_mutex_t write_buf_mutex; + os_event_t *buffer_space_available_event; + os_event_t *buffer_has_data_event; + os_event_t *socket_available_event; + os_event_t *send_thread_signaled_exit; }; #ifdef _WIN32 diff --git a/plugins/obs-outputs/rtmp-windows.c b/plugins/obs-outputs/rtmp-windows.c index cd0deb8..3b794fa 100644 --- a/plugins/obs-outputs/rtmp-windows.c +++ b/plugins/obs-outputs/rtmp-windows.c @@ -11,17 +11,18 @@ static void fatal_sock_shutdown(struct rtmp_stream *stream) } static bool socket_event(struct rtmp_stream *stream, bool *can_write, - uint64_t last_send_time) + uint64_t last_send_time) { WSANETWORKEVENTS net_events; bool success; success = !WSAEnumNetworkEvents(stream->rtmp.m_sb.sb_socket, NULL, - &net_events); + &net_events); if (!success) { - blog(LOG_ERROR, "socket_thread_windows: Aborting due to " - "WSAEnumNetworkEvents failure, %d", - WSAGetLastError()); + blog(LOG_ERROR, + "socket_thread_windows: Aborting due to " + "WSAEnumNetworkEvents failure, %d", + WSAGetLastError()); fatal_sock_shutdown(stream); return false; } @@ -34,24 +35,26 @@ static bool socket_event(struct rtmp_stream *stream, bool *can_write, uint32_t diff = (os_gettime_ns() / 1000000) - last_send_time; - blog(LOG_ERROR, "socket_thread_windows: Received " - "FD_CLOSE, %u ms since last send " - "(buffer: %d / %d)", - diff, - stream->write_buf_len, - stream->write_buf_size); + blog(LOG_ERROR, + "socket_thread_windows: Received " + "FD_CLOSE, %u ms since last send " + "(buffer: %d / %d)", + diff, stream->write_buf_len, + stream->write_buf_size); } if (os_event_try(stream->stop_event) != EAGAIN) - blog(LOG_ERROR, "socket_thread_windows: Aborting due " - "to FD_CLOSE during shutdown, " - "%d bytes lost, error %d", - stream->write_buf_len, - net_events.iErrorCode[FD_CLOSE_BIT]); + blog(LOG_ERROR, + "socket_thread_windows: Aborting due " + "to FD_CLOSE during shutdown, " + "%d bytes lost, error %d", + stream->write_buf_len, + net_events.iErrorCode[FD_CLOSE_BIT]); else - blog(LOG_ERROR, "socket_thread_windows: Aborting due " - "to FD_CLOSE, error %d", - net_events.iErrorCode[FD_CLOSE_BIT]); + blog(LOG_ERROR, + "socket_thread_windows: Aborting due " + "to FD_CLOSE, error %d", + net_events.iErrorCode[FD_CLOSE_BIT]); fatal_sock_shutdown(stream); return false; @@ -63,8 +66,8 @@ static bool socket_event(struct rtmp_stream *stream, bool *can_write, bool fatal = false; for (;;) { - int ret = recv(stream->rtmp.m_sb.sb_socket, - discard, sizeof(discard), 0); + int ret = recv(stream->rtmp.m_sb.sb_socket, discard, + sizeof(discard), 0); if (ret == -1) { err_code = WSAGetLastError(); if (err_code == WSAEWOULDBLOCK) @@ -77,10 +80,11 @@ static bool socket_event(struct rtmp_stream *stream, bool *can_write, } if (fatal) { - blog(LOG_ERROR, "socket_thread_windows: " - "Socket error, recv() returned " - "%d, GetLastError() %d", - ret, err_code); + blog(LOG_ERROR, + "socket_thread_windows: " + "Socket error, recv() returned " + "%d, GetLastError() %d", + ret, err_code); stream->rtmp.last_error_code = err_code; fatal_sock_shutdown(stream); return false; @@ -92,62 +96,55 @@ static bool socket_event(struct rtmp_stream *stream, bool *can_write, } static void ideal_send_backlog_event(struct rtmp_stream *stream, - bool *can_write) + bool *can_write) { ULONG ideal_send_backlog; int ret; - ret = idealsendbacklogquery( - stream->rtmp.m_sb.sb_socket, - &ideal_send_backlog); + ret = idealsendbacklogquery(stream->rtmp.m_sb.sb_socket, + &ideal_send_backlog); if (ret == 0) { int cur_tcp_bufsize; int size = sizeof(cur_tcp_bufsize); - ret = getsockopt(stream->rtmp.m_sb.sb_socket, - SOL_SOCKET, - SO_SNDBUF, - (char *)&cur_tcp_bufsize, - &size); + ret = getsockopt(stream->rtmp.m_sb.sb_socket, SOL_SOCKET, + SO_SNDBUF, (char *)&cur_tcp_bufsize, &size); if (ret == 0) { if (cur_tcp_bufsize < (int)ideal_send_backlog) { int bufsize = (int)ideal_send_backlog; setsockopt(stream->rtmp.m_sb.sb_socket, - SOL_SOCKET, - SO_SNDBUF, - (const char *)&bufsize, - sizeof(bufsize)); + SOL_SOCKET, SO_SNDBUF, + (const char *)&bufsize, + sizeof(bufsize)); - blog(LOG_INFO, "socket_thread_windows: " - "Increasing send buffer to " - "ISB %d (buffer: %d / %d)", - ideal_send_backlog, - stream->write_buf_len, - stream->write_buf_size); + blog(LOG_INFO, + "socket_thread_windows: " + "Increasing send buffer to " + "ISB %d (buffer: %d / %d)", + ideal_send_backlog, stream->write_buf_len, + stream->write_buf_size); } } else { - blog(LOG_ERROR, "socket_thread_windows: Got " - "send_backlog_event but " - "getsockopt() returned %d", - WSAGetLastError()); + blog(LOG_ERROR, + "socket_thread_windows: Got " + "send_backlog_event but " + "getsockopt() returned %d", + WSAGetLastError()); } } else { - blog(LOG_ERROR, "socket_thread_windows: Got " - "send_backlog_event but WSAIoctl() " - "returned %d", - WSAGetLastError()); + blog(LOG_ERROR, + "socket_thread_windows: Got " + "send_backlog_event but WSAIoctl() " + "returned %d", + WSAGetLastError()); } } -enum data_ret { - RET_BREAK, - RET_FATAL, - RET_CONTINUE -}; +enum data_ret { RET_BREAK, RET_FATAL, RET_CONTINUE }; static enum data_ret write_data(struct rtmp_stream *stream, bool *can_write, - uint64_t *last_send_time, size_t latency_packet_size, - int delay_time) + uint64_t *last_send_time, + size_t latency_packet_size, int delay_time) { bool exit_loop = false; @@ -170,19 +167,18 @@ static enum data_ret write_data(struct rtmp_stream *stream, bool *can_write, min(latency_packet_size, stream->write_buf_len); ret = RTMPSockBuf_Send(&stream->rtmp.m_sb, - (const char *)stream->write_buf, - (int)send_len); + (const char *)stream->write_buf, + (int)send_len); } else { ret = RTMPSockBuf_Send(&stream->rtmp.m_sb, - (const char *)stream->write_buf, - (int)stream->write_buf_len); + (const char *)stream->write_buf, + (int)stream->write_buf_len); } if (ret > 0) { if (stream->write_buf_len - ret) - memmove(stream->write_buf, - stream->write_buf + ret, - stream->write_buf_len - ret); + memmove(stream->write_buf, stream->write_buf + ret, + stream->write_buf_len - ret); stream->write_buf_len -= ret; *last_send_time = os_gettime_ns() / 1000000; @@ -210,10 +206,11 @@ static enum data_ret write_data(struct rtmp_stream *stream, bool *can_write, if (fatal_err) { /* connection closed, or connection was aborted / * socket closed / etc, that's a fatal error. */ - blog(LOG_ERROR, "socket_thread_windows: " - "Socket error, send() returned %d, " - "GetLastError() %d", - ret, err_code); + blog(LOG_ERROR, + "socket_thread_windows: " + "Socket error, send() returned %d, " + "GetLastError() %d", + ret, err_code); pthread_mutex_unlock(&stream->write_buf_mutex); stream->rtmp.last_error_code = err_code; @@ -250,14 +247,15 @@ static inline void socket_thread_windows_internal(struct rtmp_stream *stream) SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); WSAEventSelect(stream->rtmp.m_sb.sb_socket, - stream->socket_available_event, - FD_READ|FD_WRITE|FD_CLOSE); + stream->socket_available_event, + FD_READ | FD_WRITE | FD_CLOSE); send_backlog_event = CreateEvent(NULL, true, false, NULL); if (stream->low_latency_mode) { delay_time = 1000 / LATENCY_FACTOR; - latency_packet_size = stream->write_buf_size / (LATENCY_FACTOR - 2); + latency_packet_size = + stream->write_buf_size / (LATENCY_FACTOR - 2); } else { latency_packet_size = stream->write_buf_size; delay_time = 0; @@ -265,13 +263,13 @@ static inline void socket_thread_windows_internal(struct rtmp_stream *stream) if (!stream->disable_send_window_optimization) { memset(&send_backlog_overlapped, 0, - sizeof(send_backlog_overlapped)); + sizeof(send_backlog_overlapped)); send_backlog_overlapped.hEvent = send_backlog_event; idealsendbacklognotify(stream->rtmp.m_sb.sb_socket, - &send_backlog_overlapped, NULL); + &send_backlog_overlapped, NULL); } else { blog(LOG_INFO, "socket_thread_windows: Send window " - "optimization disabled by user."); + "optimization disabled by user."); } HANDLE objs[3]; @@ -286,7 +284,8 @@ static inline void socket_thread_windows_internal(struct rtmp_stream *stream) if (stream->write_buf_len == 0) { //blog(LOG_DEBUG, "Exiting on empty buffer"); pthread_mutex_unlock(&stream->write_buf_mutex); - os_event_reset(stream->send_thread_signaled_exit); + os_event_reset( + stream->send_thread_signaled_exit); break; } @@ -312,18 +311,15 @@ static inline void socket_thread_windows_internal(struct rtmp_stream *stream) ResetEvent(send_backlog_event); idealsendbacklognotify(stream->rtmp.m_sb.sb_socket, - &send_backlog_overlapped, NULL); + &send_backlog_overlapped, NULL); continue; } if (can_write) { for (;;) { enum data_ret ret = write_data( - stream, - &can_write, - &last_send_time, - latency_packet_size, - delay_time); + stream, &can_write, &last_send_time, + latency_packet_size, delay_time); switch (ret) { case RET_BREAK: @@ -334,12 +330,12 @@ static inline void socket_thread_windows_internal(struct rtmp_stream *stream) } } } - exit_write_loop:; + exit_write_loop:; } if (stream->rtmp.m_sb.sb_socket != INVALID_SOCKET) WSAEventSelect(stream->rtmp.m_sb.sb_socket, - stream->socket_available_event, 0); + stream->socket_available_event, 0); blog(LOG_INFO, "socket_thread_windows: Normal exit"); } diff --git a/plugins/obs-text/data/locale/ar-SA.ini b/plugins/obs-text/data/locale/ar-SA.ini index e7936ec..cd53191 100644 --- a/plugins/obs-text/data/locale/ar-SA.ini +++ b/plugins/obs-text/data/locale/ar-SA.ini @@ -31,4 +31,8 @@ UseCustomExtents="استخدام أبعاد مخصصة لصندوق النص" UseCustomExtents.Wrap="التفاف النص" Width="العرض" Height="الارتفاع" +Transform="تحويل النص" +Transform.None="بلا" +Transform.Uppercase="أحرف كبيرة" +Transform.Lowercase="أحرف صغيرة" diff --git a/plugins/obs-text/data/locale/bg-BG.ini b/plugins/obs-text/data/locale/bg-BG.ini new file mode 100644 index 0000000..b66f942 --- /dev/null +++ b/plugins/obs-text/data/locale/bg-BG.ini @@ -0,0 +1,35 @@ +TextGDIPlus="Текст (GDI+)" +Font="Шрифт" +Text="Текст" +ReadFromFile="Четене от файл" +TextFile="Текстов файл (UTF-8)" +Filter.TextFiles="Текстови файлове" +Filter.AllFiles="Всички файлове" +Color="Цвят" +Opacity="Прозиране" +Gradient="Преливка (градиент)" +Gradient.Color="Цвят на преливката" +Gradient.Opacity="Непрозрачност на преливката" +Gradient.Direction="Посока на преливката" +BkColor="Цвят на фона" +BkOpacity="Непрозрачност на фона" +Alignment="Подравняване" +Alignment.Left="Вляво" +Alignment.Center="Центриране" +Alignment.Right="Вдясно" +Vertical="Отвесно" +VerticalAlignment="Вертикално подравняване" +VerticalAlignment.Top="От горе" +VerticalAlignment.Bottom="От долу" +Outline="Контур" +Outline.Size="Големина на контура" +Outline.Color="Цвят на контура" +Outline.Opacity="Прозрачност на контура" +UseCustomExtents.Wrap="Сбиване в опаковката" +Width="Ширина" +Height="Височина" +Transform="Преобразуване на текста" +Transform.None="Няма" +Transform.Uppercase="Главни букви" +Transform.Lowercase="Малки букви" + diff --git a/plugins/obs-text/data/locale/de-DE.ini b/plugins/obs-text/data/locale/de-DE.ini index ee44b97..d301433 100644 --- a/plugins/obs-text/data/locale/de-DE.ini +++ b/plugins/obs-text/data/locale/de-DE.ini @@ -2,7 +2,7 @@ TextGDIPlus="Text (GDI+)" Font="Schriftart" Text="Text" ReadFromFile="Aus Datei lesen" -TextFile="Textdatei (UTF-8)" +TextFile="Textdatei (UTF‐8)" Filter.TextFiles="Textdateien" Filter.AllFiles="Alle Dateien" Color="Farbe" @@ -18,13 +18,13 @@ Alignment.Left="Linksbündig" Alignment.Center="Zentriert" Alignment.Right="Rechtsbündig" Vertical="Vertikal" -VerticalAlignment="Vertikal ausrichten" +VerticalAlignment="Vertikale Ausrichtung" VerticalAlignment.Top="Oben" VerticalAlignment.Bottom="Unten" Outline="Kontur" Outline.Size="Konturgröße" Outline.Color="Konturfarbe" -Outline.Opacity="Deckkraft der Kontur" +Outline.Opacity="Konturdeckkraft" ChatlogMode="Chatprotokollmodus" ChatlogMode.Lines="Chatprotokollzeilenlimit" UseCustomExtents="Benutzerdefinierten Textbereich benutzen" diff --git a/plugins/obs-text/data/locale/gl-ES.ini b/plugins/obs-text/data/locale/gl-ES.ini new file mode 100644 index 0000000..745d845 --- /dev/null +++ b/plugins/obs-text/data/locale/gl-ES.ini @@ -0,0 +1,38 @@ +TextGDIPlus="Texto (GDI+)" +Font="Tipo de letra" +Text="Texto" +ReadFromFile="Ler a partir dun ficheiro" +TextFile="Ficheiro de texto (UTF-8)" +Filter.TextFiles="Ficheiros de texto" +Filter.AllFiles="Todos os ficheiros" +Color="Cor" +Opacity="Opacidade" +Gradient="Degradado" +Gradient.Color="Cor do degradado" +Gradient.Opacity="Opacidade do degradado" +Gradient.Direction="Dirección do degradado" +BkColor="Cor de fondo" +BkOpacity="Opacidade do fondo" +Alignment="Aliñamento" +Alignment.Left="Esquerda" +Alignment.Center="Centro" +Alignment.Right="Dereita" +Vertical="Vertical" +VerticalAlignment="Aliñamento vertical" +VerticalAlignment.Top="Arriba" +VerticalAlignment.Bottom="Abaixo" +Outline="Contorno" +Outline.Size="Tamaño do contorno" +Outline.Color="Cor de contorno" +Outline.Opacity="Opacidade do contorno" +ChatlogMode="Modo de rexistro da conversa" +ChatlogMode.Lines="Límite das liñas de rexistro da conversa" +UseCustomExtents="Usar extensións de texto personalizadas" +UseCustomExtents.Wrap="Axustar" +Width="Largo" +Height="Alto" +Transform="Transformación do texto" +Transform.None="Ningunha" +Transform.Uppercase="Maiúsculas" +Transform.Lowercase="Minúsculas" + diff --git a/plugins/obs-text/data/locale/ro-RO.ini b/plugins/obs-text/data/locale/ro-RO.ini index 1d46224..c8a05ef 100644 --- a/plugins/obs-text/data/locale/ro-RO.ini +++ b/plugins/obs-text/data/locale/ro-RO.ini @@ -3,21 +3,21 @@ Font="Font" Text="Text" ReadFromFile="Citește din fișier" TextFile="Fișier text (UTF-8)" -Filter.TextFiles="Fișiere Text" +Filter.TextFiles="Fișiere text" Filter.AllFiles="Toate fișierele" Color="Culoare" Opacity="Opacitate" -BkColor="Culoare Fundal" -BkOpacity="Opacitate Fundal" +BkColor="Culoarea fundalului" +BkOpacity="Opacitatea fundalului" Alignment="Aliniere" Alignment.Left="Stânga" Alignment.Center="Centru" Alignment.Right="Dreapta" Vertical="Vertical" Outline="Contur" -Outline.Size="Dimensiune Contur" -Outline.Color="Culoare Contur" -Outline.Opacity="Opacitate Contur" +Outline.Size="Dimensiunea conturului" +Outline.Color="Culoarea conturului" +Outline.Opacity="Opacitatea conturului" Width="Lățime" Height="Înălțime" diff --git a/plugins/obs-text/data/locale/sl-SI.ini b/plugins/obs-text/data/locale/sl-SI.ini new file mode 100644 index 0000000..37b11d6 --- /dev/null +++ b/plugins/obs-text/data/locale/sl-SI.ini @@ -0,0 +1,38 @@ +TextGDIPlus="Besedilo (GDI+)" +Font="Pisava" +Text="Besedilo" +ReadFromFile="Preberi iz datoteke" +TextFile="Besedilna datoteka (UTF-8)" +Filter.TextFiles="Besedilne datoteke" +Filter.AllFiles="Vse datoteke" +Color="Barva" +Opacity="Motnost" +Gradient="Preliv" +Gradient.Color="Barva preliva" +Gradient.Opacity="Motnost preliva" +Gradient.Direction="Smer preliva" +BkColor="Barva ozadja" +BkOpacity="Motnost ozadja" +Alignment="Poravnava" +Alignment.Left="Levo" +Alignment.Center="Sredina" +Alignment.Right="Desno" +Vertical="Navpično" +VerticalAlignment="Navpična poravnava" +VerticalAlignment.Top="Zgoraj" +VerticalAlignment.Bottom="Spodaj" +Outline="Oris" +Outline.Size="Velikost orisa" +Outline.Color="Barva orisa" +Outline.Opacity="Motnost orisa" +ChatlogMode="Način dnevnika klepeta" +ChatlogMode.Lines="Omejitev vrstic dnevnika klepeta" +UseCustomExtents="Uporabi polje besedila po meri" +UseCustomExtents.Wrap="Prelomi" +Width="Širina" +Height="Višina" +Transform="Preoblika besedila" +Transform.None="Brez" +Transform.Uppercase="Velike črke" +Transform.Lowercase="Male črke" + diff --git a/plugins/obs-text/gdiplus/obs-text.cpp b/plugins/obs-text/gdiplus/obs-text.cpp index 3619126..c452821 100644 --- a/plugins/obs-text/gdiplus/obs-text.cpp +++ b/plugins/obs-text/gdiplus/obs-text.cpp @@ -12,20 +12,23 @@ using namespace std; using namespace Gdiplus; -#define warning(format, ...) blog(LOG_WARNING, "[%s] " format, \ - obs_source_get_name(source), ##__VA_ARGS__) +#define warning(format, ...) \ + blog(LOG_WARNING, "[%s] " format, obs_source_get_name(source), \ + ##__VA_ARGS__) -#define warn_stat(call) \ - do { \ - if (stat != Ok) \ +#define warn_stat(call) \ + do { \ + if (stat != Ok) \ warning("%s: %s failed (%d)", __FUNCTION__, call, \ - (int)stat); \ + (int)stat); \ } while (false) #ifndef clamp #define clamp(val, min_val, max_val) \ - if (val < min_val) val = min_val; \ - else if (val > max_val) val = max_val; + if (val < min_val) \ + val = min_val; \ + else if (val > max_val) \ + val = max_val; #endif #define MIN_SIZE_CX 2 @@ -37,6 +40,8 @@ using namespace Gdiplus; /* ------------------------------------------------------------------------- */ +/* clang-format off */ + #define S_FONT "font" #define S_USE_FILE "read_from_file" #define S_FILE "file" @@ -119,6 +124,8 @@ using namespace Gdiplus; #define T_TRANSFORM_UPPERCASE T_("Transform.Uppercase") #define T_TRANSFORM_LOWERCASE T_("Transform.Lowercase") +/* clang-format on */ + /* ------------------------------------------------------------------------- */ static inline DWORD get_alpha_val(uint32_t opacity) @@ -155,7 +162,8 @@ template class GDIObj { inline GDIObj &Replace(T obj_) { - if (obj) deleter(obj); + if (obj) + deleter(obj); obj = obj_; return *this; } @@ -163,14 +171,18 @@ template class GDIObj { public: inline GDIObj() {} inline GDIObj(T obj_) : obj(obj_) {} - inline ~GDIObj() {deleter(obj);} + inline ~GDIObj() { deleter(obj); } - inline T operator=(T obj_) {Replace(obj_); return obj;} + inline T operator=(T obj_) + { + Replace(obj_); + return obj; + } - inline operator T() const {return obj;} + inline operator T() const { return obj; } - inline bool operator==(T obj_) const {return obj == obj_;} - inline bool operator!=(T obj_) const {return obj != obj_;} + inline bool operator==(T obj_) const { return obj == obj_; } + inline bool operator!=(T obj_) const { return obj != obj_; } }; using HDCObj = GDIObj; @@ -182,13 +194,13 @@ using HBITMAPObj = GDIObj; enum class Align { Left, Center, - Right + Right, }; enum class VAlign { Top, Center, - Bottom + Bottom, }; struct TextSource { @@ -246,10 +258,10 @@ struct TextSource { /* --------------------------- */ - inline TextSource(obs_source_t *source_, obs_data_t *settings) : - source (source_), - hdc (CreateCompatibleDC(nullptr)), - graphics (hdc) + inline TextSource(obs_source_t *source_, obs_data_t *settings) + : source(source_), + hdc(CreateCompatibleDC(nullptr)), + graphics(hdc) { obs_source_update(source, settings); } @@ -266,13 +278,13 @@ struct TextSource { void UpdateFont(); void GetStringFormat(StringFormat &format); void RemoveNewlinePadding(const StringFormat &format, RectF &box); - void CalculateTextSizes(const StringFormat &format, - RectF &bounding_box, SIZE &text_size); - void RenderOutlineText(Graphics &graphics, - const GraphicsPath &path, - const Brush &brush); + void CalculateTextSizes(const StringFormat &format, RectF &bounding_box, + SIZE &text_size); + void RenderOutlineText(Graphics &graphics, const GraphicsPath &path, + const Brush &brush); void RenderText(); void LoadFileText(); + void TransformText(); const char *GetMainString(const char *str); @@ -320,11 +332,11 @@ void TextSource::UpdateFont() void TextSource::GetStringFormat(StringFormat &format) { UINT flags = StringFormatFlagsNoFitBlackBox | - StringFormatFlagsMeasureTrailingSpaces; + StringFormatFlagsMeasureTrailingSpaces; if (vertical) flags |= StringFormatFlagsDirectionVertical | - StringFormatFlagsDirectionRightToLeft; + StringFormatFlagsDirectionRightToLeft; format.SetFormatFlags(flags); format.SetTrimming(StringTrimmingWord); @@ -381,11 +393,11 @@ void TextSource::RemoveNewlinePadding(const StringFormat &format, RectF &box) Status stat; stat = graphics.MeasureString(L"W", 2, font.get(), PointF(0.0f, 0.0f), - &format, &before); + &format, &before); warn_stat("MeasureString (without newline)"); stat = graphics.MeasureString(L"W\n", 3, font.get(), PointF(0.0f, 0.0f), - &format, &after); + &format, &after); warn_stat("MeasureString (with newline)"); float offset_cx = after.Width - before.Width; @@ -409,12 +421,12 @@ void TextSource::RemoveNewlinePadding(const StringFormat &format, RectF &box) box.X -= offset_cx; } - box.Width -= offset_cx; + box.Width -= offset_cx; box.Height -= offset_cy; } void TextSource::CalculateTextSizes(const StringFormat &format, - RectF &bounding_box, SIZE &text_size) + RectF &bounding_box, SIZE &text_size) { RectF layout_box; RectF temp_box; @@ -423,26 +435,25 @@ void TextSource::CalculateTextSizes(const StringFormat &format, if (!text.empty()) { if (use_extents && wrap) { layout_box.X = layout_box.Y = 0; - layout_box.Width = float(extents_cx); + layout_box.Width = float(extents_cx); layout_box.Height = float(extents_cy); if (use_outline) { - layout_box.Width -= outline_size; + layout_box.Width -= outline_size; layout_box.Height -= outline_size; } stat = graphics.MeasureString(text.c_str(), - (int)text.size() + 1, font.get(), - layout_box, &format, - &bounding_box); + (int)text.size() + 1, + font.get(), layout_box, + &format, &bounding_box); warn_stat("MeasureString (wrapped)"); temp_box = bounding_box; } else { - stat = graphics.MeasureString(text.c_str(), - (int)text.size() + 1, font.get(), - PointF(0.0f, 0.0f), &format, - &bounding_box); + stat = graphics.MeasureString( + text.c_str(), (int)text.size() + 1, font.get(), + PointF(0.0f, 0.0f), &format, &bounding_box); warn_stat("MeasureString (non-wrapped)"); temp_box = bounding_box; @@ -453,7 +464,7 @@ void TextSource::CalculateTextSizes(const StringFormat &format, RemoveNewlinePadding(format, bounding_box); if (use_outline) { - bounding_box.Width += outline_size; + bounding_box.Width += outline_size; bounding_box.Height += outline_size; } } @@ -503,13 +514,12 @@ void TextSource::CalculateTextSizes(const StringFormat &format, /* the internal text-rendering bounding box for is reset to * its internal value in case the texture gets cut off */ - bounding_box.Width = temp_box.Width; + bounding_box.Width = temp_box.Width; bounding_box.Height = temp_box.Height; } -void TextSource::RenderOutlineText(Graphics &graphics, - const GraphicsPath &path, - const Brush &brush) +void TextSource::RenderOutlineText(Graphics &graphics, const GraphicsPath &path, + const Brush &brush) { DWORD outline_rgba = calc_color(outline_color, outline_opacity); Status stat; @@ -536,15 +546,15 @@ void TextSource::RenderText() GetStringFormat(format); CalculateTextSizes(format, box, size); - unique_ptr bits(new uint8_t[size.cx * size.cy * 4]); + unique_ptr bits(new uint8_t[size.cx * size.cy * 4]); Bitmap bitmap(size.cx, size.cy, 4 * size.cx, PixelFormat32bppARGB, - bits.get()); + bits.get()); Graphics graphics_bitmap(&bitmap); LinearGradientBrush brush(RectF(0, 0, (float)size.cx, (float)size.cy), - Color(calc_color(color, opacity)), - Color(calc_color(color2, opacity2)), - gradient_dir, 1); + Color(calc_color(color, opacity)), + Color(calc_color(color2, opacity2)), + gradient_dir, 1); DWORD full_bk_color = bk_color & 0xFFFFFF; if (!text.empty() || use_extents) @@ -575,15 +585,16 @@ void TextSource::RenderText() font->GetFamily(&family); stat = path.AddString(text.c_str(), (int)text.size(), - &family, font->GetStyle(), - font->GetSize(), box, &format); + &family, font->GetStyle(), + font->GetSize(), box, &format); warn_stat("path.AddString"); RenderOutlineText(graphics_bitmap, path, brush); } else { stat = graphics_bitmap.DrawString(text.c_str(), - (int)text.size(), font.get(), - box, &format, &brush); + (int)text.size(), + font.get(), box, + &format, &brush); warn_stat("graphics_bitmap.DrawString"); } } @@ -593,9 +604,9 @@ void TextSource::RenderText() if (tex) gs_texture_destroy(tex); - const uint8_t *data = (uint8_t*)bits.get(); + const uint8_t *data = (uint8_t *)bits.get(); tex = gs_texture_create(size.cx, size.cy, GS_BGRA, 1, &data, - GS_DYNAMIC); + GS_DYNAMIC); obs_leave_graphics(); @@ -623,7 +634,7 @@ const char *TextSource::GetMainString(const char *str) const char *temp = str + len; - while(temp != str) { + while (temp != str) { temp--; if (temp[0] == '\n' && temp[1] != 0) { @@ -644,55 +655,60 @@ void TextSource::LoadFileText() text.push_back('\n'); } -#define obs_data_get_uint32 (uint32_t)obs_data_get_int +void TextSource::TransformText() +{ + if (text_transform == S_TRANSFORM_UPPERCASE) + transform(text.begin(), text.end(), text.begin(), towupper); + else if (text_transform == S_TRANSFORM_LOWERCASE) + transform(text.begin(), text.end(), text.begin(), towlower); +} + +#define obs_data_get_uint32 (uint32_t) obs_data_get_int inline void TextSource::Update(obs_data_t *s) { - const char *new_text = obs_data_get_string(s, S_TEXT); - obs_data_t *font_obj = obs_data_get_obj(s, S_FONT); - const char *align_str = obs_data_get_string(s, S_ALIGN); + const char *new_text = obs_data_get_string(s, S_TEXT); + obs_data_t *font_obj = obs_data_get_obj(s, S_FONT); + const char *align_str = obs_data_get_string(s, S_ALIGN); const char *valign_str = obs_data_get_string(s, S_VALIGN); - uint32_t new_color = obs_data_get_uint32(s, S_COLOR); - uint32_t new_opacity = obs_data_get_uint32(s, S_OPACITY); - bool gradient = obs_data_get_bool(s, S_GRADIENT); - uint32_t new_color2 = obs_data_get_uint32(s, S_GRADIENT_COLOR); - uint32_t new_opacity2 = obs_data_get_uint32(s, S_GRADIENT_OPACITY); - float new_grad_dir = (float)obs_data_get_double(s, S_GRADIENT_DIR); - bool new_vertical = obs_data_get_bool(s, S_VERTICAL); - bool new_outline = obs_data_get_bool(s, S_OUTLINE); - uint32_t new_o_color = obs_data_get_uint32(s, S_OUTLINE_COLOR); + uint32_t new_color = obs_data_get_uint32(s, S_COLOR); + uint32_t new_opacity = obs_data_get_uint32(s, S_OPACITY); + bool gradient = obs_data_get_bool(s, S_GRADIENT); + uint32_t new_color2 = obs_data_get_uint32(s, S_GRADIENT_COLOR); + uint32_t new_opacity2 = obs_data_get_uint32(s, S_GRADIENT_OPACITY); + float new_grad_dir = (float)obs_data_get_double(s, S_GRADIENT_DIR); + bool new_vertical = obs_data_get_bool(s, S_VERTICAL); + bool new_outline = obs_data_get_bool(s, S_OUTLINE); + uint32_t new_o_color = obs_data_get_uint32(s, S_OUTLINE_COLOR); uint32_t new_o_opacity = obs_data_get_uint32(s, S_OUTLINE_OPACITY); - uint32_t new_o_size = obs_data_get_uint32(s, S_OUTLINE_SIZE); - bool new_use_file = obs_data_get_bool(s, S_USE_FILE); - const char *new_file = obs_data_get_string(s, S_FILE); - bool new_chat_mode = obs_data_get_bool(s, S_CHATLOG_MODE); - int new_chat_lines = (int)obs_data_get_int(s, S_CHATLOG_LINES); - bool new_extents = obs_data_get_bool(s, S_EXTENTS); - bool new_extents_wrap = obs_data_get_bool(s, S_EXTENTS_WRAP); - uint32_t n_extents_cx = obs_data_get_uint32(s, S_EXTENTS_CX); - uint32_t n_extents_cy = obs_data_get_uint32(s, S_EXTENTS_CY); + uint32_t new_o_size = obs_data_get_uint32(s, S_OUTLINE_SIZE); + bool new_use_file = obs_data_get_bool(s, S_USE_FILE); + const char *new_file = obs_data_get_string(s, S_FILE); + bool new_chat_mode = obs_data_get_bool(s, S_CHATLOG_MODE); + int new_chat_lines = (int)obs_data_get_int(s, S_CHATLOG_LINES); + bool new_extents = obs_data_get_bool(s, S_EXTENTS); + bool new_extents_wrap = obs_data_get_bool(s, S_EXTENTS_WRAP); + uint32_t n_extents_cx = obs_data_get_uint32(s, S_EXTENTS_CX); + uint32_t n_extents_cy = obs_data_get_uint32(s, S_EXTENTS_CY); int new_text_transform = (int)obs_data_get_int(s, S_TRANSFORM); - const char *font_face = obs_data_get_string(font_obj, "face"); - int font_size = (int)obs_data_get_int(font_obj, "size"); - int64_t font_flags = obs_data_get_int(font_obj, "flags"); - bool new_bold = (font_flags & OBS_FONT_BOLD) != 0; - bool new_italic = (font_flags & OBS_FONT_ITALIC) != 0; - bool new_underline = (font_flags & OBS_FONT_UNDERLINE) != 0; - bool new_strikeout = (font_flags & OBS_FONT_STRIKEOUT) != 0; + const char *font_face = obs_data_get_string(font_obj, "face"); + int font_size = (int)obs_data_get_int(font_obj, "size"); + int64_t font_flags = obs_data_get_int(font_obj, "flags"); + bool new_bold = (font_flags & OBS_FONT_BOLD) != 0; + bool new_italic = (font_flags & OBS_FONT_ITALIC) != 0; + bool new_underline = (font_flags & OBS_FONT_UNDERLINE) != 0; + bool new_strikeout = (font_flags & OBS_FONT_STRIKEOUT) != 0; - uint32_t new_bk_color = obs_data_get_uint32(s, S_BKCOLOR); + uint32_t new_bk_color = obs_data_get_uint32(s, S_BKCOLOR); uint32_t new_bk_opacity = obs_data_get_uint32(s, S_BKOPACITY); /* ----------------------------- */ wstring new_face = to_wide(font_face); - if (new_face != face || - face_size != font_size || - new_bold != bold || - new_italic != italic || - new_underline != underline || + if (new_face != face || face_size != font_size || new_bold != bold || + new_italic != italic || new_underline != underline || new_strikeout != strikeout) { face = new_face; @@ -751,10 +767,7 @@ inline void TextSource::Update(obs_data_t *s) if (!text.empty()) text.push_back('\n'); } - if(text_transform == S_TRANSFORM_UPPERCASE) - transform(text.begin(), text.end(), text.begin(), towupper); - else if(text_transform == S_TRANSFORM_LOWERCASE) - transform(text.begin(), text.end(), text.begin(), towlower); + TransformText(); use_outline = new_outline; outline_color = new_o_color; @@ -796,6 +809,7 @@ inline void TextSource::Tick(float seconds) if (update_file) { LoadFileText(); + TransformText(); RenderText(); update_file = false; } @@ -813,12 +827,13 @@ inline void TextSource::Render() return; gs_effect_t *effect = obs_get_base_effect(OBS_EFFECT_DEFAULT); - gs_technique_t *tech = gs_effect_get_technique(effect, "Draw"); + gs_technique_t *tech = gs_effect_get_technique(effect, "Draw"); gs_technique_begin(tech); gs_technique_begin_pass(tech, 0); - gs_effect_set_texture(gs_effect_get_param_by_name(effect, "image"), tex); + gs_effect_set_texture(gs_effect_get_param_by_name(effect, "image"), + tex); gs_draw_sprite(tex, 0, cx, cy); gs_technique_end_pass(tech); @@ -836,14 +851,14 @@ MODULE_EXPORT const char *obs_module_description(void) return "Windows GDI+ text source"; } -#define set_vis(var, val, show) \ - do { \ - p = obs_properties_get(props, val); \ +#define set_vis(var, val, show) \ + do { \ + p = obs_properties_get(props, val); \ obs_property_set_visible(p, var == show); \ } while (false) static bool use_file_changed(obs_properties_t *props, obs_property_t *p, - obs_data_t *s) + obs_data_t *s) { bool use_file = obs_data_get_bool(s, S_USE_FILE); @@ -853,7 +868,7 @@ static bool use_file_changed(obs_properties_t *props, obs_property_t *p, } static bool outline_changed(obs_properties_t *props, obs_property_t *p, - obs_data_t *s) + obs_data_t *s) { bool outline = obs_data_get_bool(s, S_OUTLINE); @@ -864,7 +879,7 @@ static bool outline_changed(obs_properties_t *props, obs_property_t *p, } static bool chatlog_mode_changed(obs_properties_t *props, obs_property_t *p, - obs_data_t *s) + obs_data_t *s) { bool chatlog_mode = obs_data_get_bool(s, S_CHATLOG_MODE); @@ -873,7 +888,7 @@ static bool chatlog_mode_changed(obs_properties_t *props, obs_property_t *p, } static bool gradient_changed(obs_properties_t *props, obs_property_t *p, - obs_data_t *s) + obs_data_t *s) { bool gradient = obs_data_get_bool(s, S_GRADIENT); @@ -884,7 +899,7 @@ static bool gradient_changed(obs_properties_t *props, obs_property_t *p, } static bool extents_modified(obs_properties_t *props, obs_property_t *p, - obs_data_t *s) + obs_data_t *s) { bool use_extents = obs_data_get_bool(s, S_EXTENTS); @@ -898,7 +913,7 @@ static bool extents_modified(obs_properties_t *props, obs_property_t *p, static obs_properties_t *get_properties(void *data) { - TextSource *s = reinterpret_cast(data); + TextSource *s = reinterpret_cast(data); string path; obs_properties_t *props = obs_properties_create(); @@ -927,41 +942,48 @@ static obs_properties_t *get_properties(void *data) obs_properties_add_text(props, S_TEXT, T_TEXT, OBS_TEXT_MULTILINE); obs_properties_add_path(props, S_FILE, T_FILE, OBS_PATH_FILE, - filter.c_str(), path.c_str()); + filter.c_str(), path.c_str()); p = obs_properties_add_list(props, S_TRANSFORM, T_TRANSFORM, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); obs_property_list_add_int(p, T_TRANSFORM_NONE, S_TRANSFORM_NONE); - obs_property_list_add_int(p, T_TRANSFORM_UPPERCASE, S_TRANSFORM_UPPERCASE); - obs_property_list_add_int(p, T_TRANSFORM_LOWERCASE, S_TRANSFORM_LOWERCASE); - + obs_property_list_add_int(p, T_TRANSFORM_UPPERCASE, + S_TRANSFORM_UPPERCASE); + obs_property_list_add_int(p, T_TRANSFORM_LOWERCASE, + S_TRANSFORM_LOWERCASE); obs_properties_add_bool(props, S_VERTICAL, T_VERTICAL); obs_properties_add_color(props, S_COLOR, T_COLOR); - obs_properties_add_int_slider(props, S_OPACITY, T_OPACITY, 0, 100, 1); + p = obs_properties_add_int_slider(props, S_OPACITY, T_OPACITY, 0, 100, + 1); + obs_property_int_set_suffix(p, "%"); p = obs_properties_add_bool(props, S_GRADIENT, T_GRADIENT); obs_property_set_modified_callback(p, gradient_changed); obs_properties_add_color(props, S_GRADIENT_COLOR, T_GRADIENT_COLOR); - obs_properties_add_int_slider(props, S_GRADIENT_OPACITY, - T_GRADIENT_OPACITY, 0, 100, 1); - obs_properties_add_float_slider(props, S_GRADIENT_DIR, - T_GRADIENT_DIR, 0, 360, 0.1); + p = obs_properties_add_int_slider(props, S_GRADIENT_OPACITY, + T_GRADIENT_OPACITY, 0, 100, 1); + obs_property_int_set_suffix(p, "%"); + obs_properties_add_float_slider(props, S_GRADIENT_DIR, T_GRADIENT_DIR, + 0, 360, 0.1); obs_properties_add_color(props, S_BKCOLOR, T_BKCOLOR); - obs_properties_add_int_slider(props, S_BKOPACITY, T_BKOPACITY, - 0, 100, 1); + p = obs_properties_add_int_slider(props, S_BKOPACITY, T_BKOPACITY, 0, + 100, 1); + obs_property_int_set_suffix(p, "%"); p = obs_properties_add_list(props, S_ALIGN, T_ALIGN, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); - obs_property_list_add_string(p, T_ALIGN_LEFT, S_ALIGN_LEFT); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); + obs_property_list_add_string(p, T_ALIGN_LEFT, S_ALIGN_LEFT); obs_property_list_add_string(p, T_ALIGN_CENTER, S_ALIGN_CENTER); - obs_property_list_add_string(p, T_ALIGN_RIGHT, S_ALIGN_RIGHT); + obs_property_list_add_string(p, T_ALIGN_RIGHT, S_ALIGN_RIGHT); p = obs_properties_add_list(props, S_VALIGN, T_VALIGN, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); - obs_property_list_add_string(p, T_VALIGN_TOP, S_VALIGN_TOP); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); + obs_property_list_add_string(p, T_VALIGN_TOP, S_VALIGN_TOP); obs_property_list_add_string(p, T_VALIGN_CENTER, S_VALIGN_CENTER); obs_property_list_add_string(p, T_VALIGN_BOTTOM, S_VALIGN_BOTTOM); @@ -970,14 +992,15 @@ static obs_properties_t *get_properties(void *data) obs_properties_add_int(props, S_OUTLINE_SIZE, T_OUTLINE_SIZE, 1, 20, 1); obs_properties_add_color(props, S_OUTLINE_COLOR, T_OUTLINE_COLOR); - obs_properties_add_int_slider(props, S_OUTLINE_OPACITY, - T_OUTLINE_OPACITY, 0, 100, 1); + p = obs_properties_add_int_slider(props, S_OUTLINE_OPACITY, + T_OUTLINE_OPACITY, 0, 100, 1); + obs_property_int_set_suffix(p, "%"); p = obs_properties_add_bool(props, S_CHATLOG_MODE, T_CHATLOG_MODE); obs_property_set_modified_callback(p, chatlog_mode_changed); - obs_properties_add_int(props, S_CHATLOG_LINES, T_CHATLOG_LINES, - 1, 1000, 1); + obs_properties_add_int(props, S_CHATLOG_LINES, T_CHATLOG_LINES, 1, 1000, + 1); p = obs_properties_add_bool(props, S_EXTENTS, T_EXTENTS); obs_property_set_modified_callback(p, extents_modified); @@ -997,28 +1020,20 @@ bool obs_module_load(void) si.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW; si.get_properties = get_properties; - si.get_name = [] (void*) - { - return obs_module_text("TextGDIPlus"); + si.get_name = [](void *) { return obs_module_text("TextGDIPlus"); }; + si.create = [](obs_data_t *settings, obs_source_t *source) { + return (void *)new TextSource(source, settings); }; - si.create = [] (obs_data_t *settings, obs_source_t *source) - { - return (void*)new TextSource(source, settings); + si.destroy = [](void *data) { + delete reinterpret_cast(data); }; - si.destroy = [] (void *data) - { - delete reinterpret_cast(data); + si.get_width = [](void *data) { + return reinterpret_cast(data)->cx; }; - si.get_width = [] (void *data) - { - return reinterpret_cast(data)->cx; + si.get_height = [](void *data) { + return reinterpret_cast(data)->cy; }; - si.get_height = [] (void *data) - { - return reinterpret_cast(data)->cy; - }; - si.get_defaults = [] (obs_data_t *settings) - { + si.get_defaults = [](obs_data_t *settings) { obs_data_t *font_obj = obs_data_create(); obs_data_set_default_string(font_obj, "face", "Arial"); obs_data_set_default_int(font_obj, "size", 36); @@ -1040,21 +1055,19 @@ bool obs_module_load(void) obs_data_set_default_bool(settings, S_EXTENTS_WRAP, true); obs_data_set_default_int(settings, S_EXTENTS_CX, 100); obs_data_set_default_int(settings, S_EXTENTS_CY, 100); - obs_data_set_default_int(settings, S_TRANSFORM, S_TRANSFORM_NONE); + obs_data_set_default_int(settings, S_TRANSFORM, + S_TRANSFORM_NONE); obs_data_release(font_obj); }; - si.update = [] (void *data, obs_data_t *settings) - { - reinterpret_cast(data)->Update(settings); + si.update = [](void *data, obs_data_t *settings) { + reinterpret_cast(data)->Update(settings); }; - si.video_tick = [] (void *data, float seconds) - { - reinterpret_cast(data)->Tick(seconds); + si.video_tick = [](void *data, float seconds) { + reinterpret_cast(data)->Tick(seconds); }; - si.video_render = [] (void *data, gs_effect_t*) - { - reinterpret_cast(data)->Render(); + si.video_render = [](void *data, gs_effect_t *) { + reinterpret_cast(data)->Render(); }; obs_register_source(&si); diff --git a/plugins/obs-transitions/data/locale/ca-ES.ini b/plugins/obs-transitions/data/locale/ca-ES.ini index e5b943d..4d885e1 100644 --- a/plugins/obs-transitions/data/locale/ca-ES.ini +++ b/plugins/obs-transitions/data/locale/ca-ES.ini @@ -12,7 +12,7 @@ Direction.Down="Avall" SwipeIn="Lliscament" Color="Color" VideoFile="Arxiu de vídeo" -TransitionPoint="Punt de la transició (mil·lisegons)" +TransitionPoint="Punt de transició" TransitionPointFrame="Punt de transició (fotograma)" TransitionPointType="Tipus de punt de transició" TransitionPointTypeFrame="Fotograma" @@ -20,7 +20,7 @@ TransitionPointTypeTime="Temps (en mil·lisegons)" AudioFadeStyle="Estil de fos d'àudio" AudioFadeStyle.FadeOutFadeIn="Es descolora al punt de transició i després s'esvaeix" AudioFadeStyle.CrossFade="Transició" -SwitchPoint="Punt de Color màxim (percentatge)" +SwitchPoint="Punt de color àlgid" LumaWipeTransition="Luma Wipe" LumaWipe.Image="Imatge" LumaWipe.Invert="Invertir" diff --git a/plugins/obs-transitions/data/locale/cs-CZ.ini b/plugins/obs-transitions/data/locale/cs-CZ.ini index ce20ef5..651046d 100644 --- a/plugins/obs-transitions/data/locale/cs-CZ.ini +++ b/plugins/obs-transitions/data/locale/cs-CZ.ini @@ -12,7 +12,7 @@ Direction.Down="Dolů" SwipeIn="Vtáhnout" Color="Barva" VideoFile="Video soubor" -TransitionPoint="Bod přechodu (ms)" +TransitionPoint="Bod přechodu" TransitionPointFrame="Bod přechodu (snímky)" TransitionPointType="Typ bodu přechodu" TransitionPointTypeFrame="Snímek" @@ -20,7 +20,7 @@ TransitionPointTypeTime="Čas (ms)" AudioFadeStyle="Styl přechodů" AudioFadeStyle.FadeOutFadeIn="Zeslabovat do bodu přechodu, poté zesilovat" AudioFadeStyle.CrossFade="Prolínání" -SwitchPoint="Špičkový bod barvy (%)" +SwitchPoint="Špičkový bod barev" LumaWipeTransition="Luma Wipe" LumaWipe.Image="Obrázek" LumaWipe.Invert="Invert" diff --git a/plugins/obs-transitions/data/locale/da-DK.ini b/plugins/obs-transitions/data/locale/da-DK.ini index 18c3b2f..8f11d53 100644 --- a/plugins/obs-transitions/data/locale/da-DK.ini +++ b/plugins/obs-transitions/data/locale/da-DK.ini @@ -12,7 +12,7 @@ Direction.Down="Ned" SwipeIn="Stryg ind" Color="Farve" VideoFile="Videofil" -TransitionPoint="Overgangspunkt (millisek.)" +TransitionPoint="Overgangspunkt" TransitionPointFrame="Overgangspunkt (billede)" TransitionPointType="Overgangspunkttype" TransitionPointTypeFrame="Billede" @@ -20,7 +20,7 @@ TransitionPointTypeTime="Tid (millisek.)" AudioFadeStyle="Lydudtoningsstil" AudioFadeStyle.FadeOutFadeIn="Udtone til overgangspunkt, dernæst indtone" AudioFadeStyle.CrossFade="Krydstoning (crossfade)" -SwitchPoint="Farvespidspunkt (procent)" +SwitchPoint="Spidsudslagsfarve" LumaWipeTransition="Luma-overgang" LumaWipe.Image="Billede" LumaWipe.Invert="Invertér" diff --git a/plugins/obs-transitions/data/locale/de-DE.ini b/plugins/obs-transitions/data/locale/de-DE.ini index 3e2a034..efd061b 100644 --- a/plugins/obs-transitions/data/locale/de-DE.ini +++ b/plugins/obs-transitions/data/locale/de-DE.ini @@ -12,7 +12,7 @@ Direction.Down="Runter" SwipeIn="Swipe In" Color="Farbe" VideoFile="Videodatei" -TransitionPoint="Übergangspunkt (Millisekunden)" +TransitionPoint="Übergangspunkt" TransitionPointFrame="Übergangspunkt (Frame)" TransitionPointType="Übergangspunkttyp" TransitionPointTypeFrame="Frame" @@ -20,7 +20,7 @@ TransitionPointTypeTime="Zeit (Millisekunden)" AudioFadeStyle="Audioüberblendstil" AudioFadeStyle.FadeOutFadeIn="Zu Übergangspunkt ausblenden und dann einblenden" AudioFadeStyle.CrossFade="Überblendung" -SwitchPoint="Spitzenfarbpunkt (in Prozent)" +SwitchPoint="Farbhöhepunkt" LumaWipeTransition="Luma Wipe" LumaWipe.Image="Bild" LumaWipe.Invert="Umkehren" @@ -47,8 +47,8 @@ LumaWipe.Type.LinearHorizontal="Linear horizontal" LumaWipe.Type.LinearTopLeft="Linear oben links" LumaWipe.Type.LinearTopRight="Linear oben rechts" LumaWipe.Type.LinearVertical="Linear vertikal" -LumaWipe.Type.ParallelZigzagHorizontal="Parallel Zick-Zack horizontal" -LumaWipe.Type.ParallelZigzagVertical="Parallel Zick-Zack vertikal" +LumaWipe.Type.ParallelZigzagHorizontal="Parallel Zick‐Zack horizontal" +LumaWipe.Type.ParallelZigzagVertical="Parallel Zick‐Zack vertikal" LumaWipe.Type.Sinus9="Sinus 9" LumaWipe.Type.Spiral="Spirale" LumaWipe.Type.Square="Quadrat" diff --git a/plugins/obs-transitions/data/locale/el-GR.ini b/plugins/obs-transitions/data/locale/el-GR.ini index d1961ce..6429272 100644 --- a/plugins/obs-transitions/data/locale/el-GR.ini +++ b/plugins/obs-transitions/data/locale/el-GR.ini @@ -12,7 +12,6 @@ Direction.Down="Κάτω" SwipeIn="Σύρετε προς τα επάνω" Color="Χρώμα" VideoFile="Αρχείο Βίντεο" -TransitionPoint="Ταχύτητα μετάβασης (χιλιοστά δευτερολέπτου)" TransitionPointFrame="Σημείο μετάβασης (πλαίσιο)" TransitionPointType="Τύπος σημείου μετάβασης" TransitionPointTypeFrame="Καρέ" @@ -20,7 +19,6 @@ TransitionPointTypeTime="Χρόνος (χιλιοστά δευτερολέπτο AudioFadeStyle="Στυλ ήχου Fade" AudioFadeStyle.FadeOutFadeIn="Fade out στο σημείο μετάβασης στη συνέχεια, fade in" AudioFadeStyle.CrossFade="Σταδιακή Εξασθένιση" -SwitchPoint="Peak Χρώμα Σημείου (ποσοστό)" LumaWipeTransition="Luma Wipe" LumaWipe.Image="Εικόνα" LumaWipe.Invert="Αντιστροφή" diff --git a/plugins/obs-transitions/data/locale/en-US.ini b/plugins/obs-transitions/data/locale/en-US.ini index 411b49b..0a7141f 100644 --- a/plugins/obs-transitions/data/locale/en-US.ini +++ b/plugins/obs-transitions/data/locale/en-US.ini @@ -12,7 +12,7 @@ Direction.Down="Down" SwipeIn="Swipe In" Color="Color" VideoFile="Video File" -TransitionPoint="Transition Point (milliseconds)" +TransitionPoint="Transition Point" TransitionPointFrame="Transition Point (frame)" TransitionPointType="Transition Point Type" TransitionPointTypeFrame="Frame" @@ -20,7 +20,7 @@ TransitionPointTypeTime="Time (milliseconds)" AudioFadeStyle="Audio Fade Style" AudioFadeStyle.FadeOutFadeIn="Fade out to transition point then fade in" AudioFadeStyle.CrossFade="Crossfade" -SwitchPoint="Peak Color Point (percentage)" +SwitchPoint="Peak Color Point" LumaWipeTransition="Luma Wipe" LumaWipe.Image="Image" LumaWipe.Invert="Invert" diff --git a/plugins/obs-transitions/data/locale/es-ES.ini b/plugins/obs-transitions/data/locale/es-ES.ini index 4adf1a5..dd5c4c3 100644 --- a/plugins/obs-transitions/data/locale/es-ES.ini +++ b/plugins/obs-transitions/data/locale/es-ES.ini @@ -1,7 +1,7 @@ FadeTransition="Desvanecimiento" CutTransition="Corte" SwipeTransition="Deslizar" -SlideTransition="Deslizar" +SlideTransition="Diapositiva" StingerTransition="Stinger" FadeToColorTransition="Desvanecer a Color" Direction="Dirección" @@ -9,10 +9,10 @@ Direction.Left="Izquierda" Direction.Right="Derecha" Direction.Up="Arriba" Direction.Down="Abajo" -SwipeIn="Deslizamiento" +SwipeIn="Deslizar hacia adentro" Color="Color" VideoFile="Archivo de vídeo" -TransitionPoint="Punto de transición (milisegundos)" +TransitionPoint="Punto de transición" TransitionPointFrame="Punto de transición (fotograma)" TransitionPointType="Tipo de punto de transición" TransitionPointTypeFrame="Fotograma" @@ -20,7 +20,7 @@ TransitionPointTypeTime="Tiempo (en milisegundos)" AudioFadeStyle="Estilo de fundido de audio" AudioFadeStyle.FadeOutFadeIn="Se descolora al punto de transición y luego se desvanece" AudioFadeStyle.CrossFade="Transición suave" -SwitchPoint="Punto de Color máximo (porcentaje)" +SwitchPoint="Pico de color" LumaWipeTransition="Luma Wipe" LumaWipe.Image="Imagen" LumaWipe.Invert="Invertir" diff --git a/plugins/obs-transitions/data/locale/eu-ES.ini b/plugins/obs-transitions/data/locale/eu-ES.ini index f155235..a7fee43 100644 --- a/plugins/obs-transitions/data/locale/eu-ES.ini +++ b/plugins/obs-transitions/data/locale/eu-ES.ini @@ -12,7 +12,7 @@ Direction.Down="Behera" SwipeIn="Korritu bertan" Color="Kolorea" VideoFile="Bideo-fitxategia" -TransitionPoint="Trantsizio-puntua (milisegundo)" +TransitionPoint="Trantsizio-puntua" TransitionPointFrame="Trantsizio-puntua (fotograma)" TransitionPointType="Trantsizio-puntu mota" TransitionPointTypeFrame="Fotograma" @@ -20,7 +20,7 @@ TransitionPointTypeTime="Denbora (milisegundo)" AudioFadeStyle="Audio desagertze estiloa" AudioFadeStyle.FadeOutFadeIn="Desagertu trantsizio puntura eta orduan agertu" AudioFadeStyle.CrossFade="Kateatua" -SwitchPoint="Kolorearen gailur puntua (ehunekoa)" +SwitchPoint="Gailurraren kolorezko puntua" LumaWipeTransition="Luma Wipe" LumaWipe.Image="Irudia" LumaWipe.Invert="Irauli" diff --git a/plugins/obs-transitions/data/locale/fi-FI.ini b/plugins/obs-transitions/data/locale/fi-FI.ini index f155234..2fcd375 100644 --- a/plugins/obs-transitions/data/locale/fi-FI.ini +++ b/plugins/obs-transitions/data/locale/fi-FI.ini @@ -12,7 +12,6 @@ Direction.Down="Alhaalta" SwipeIn="Pyyhkäise yli" Color="Väri" VideoFile="Videotiedosto" -TransitionPoint="Siirtymäkohta (millisekuntia)" TransitionPointFrame="Siirtymäpisteen tyyppi (frame)" TransitionPointType="Siirtymäpisteen tyyppi" TransitionPointTypeFrame="Kehys" @@ -20,7 +19,6 @@ TransitionPointTypeTime="Aika (millisekuntia)" AudioFadeStyle="Äänen häivytyksen tyyli" AudioFadeStyle.FadeOutFadeIn="Häivytä ulos siirtymäpisteeseen asti ja sitten häivytä sisään" AudioFadeStyle.CrossFade="Ristiinhäivytys" -SwitchPoint="Korkein väripiste (prosentti)" LumaWipeTransition="Luma-pyyhkäisy" LumaWipe.Image="Kuva" LumaWipe.Invert="Käänteinen" diff --git a/plugins/obs-transitions/data/locale/fil-PH.ini b/plugins/obs-transitions/data/locale/fil-PH.ini index dc918df..6b7122e 100644 --- a/plugins/obs-transitions/data/locale/fil-PH.ini +++ b/plugins/obs-transitions/data/locale/fil-PH.ini @@ -12,7 +12,6 @@ Direction.Down="Pababa" SwipeIn="Mag-swipe In" Color="Kulay" VideoFile="Bidyo File" -TransitionPoint="Paglipat ng tuldok (milsegundo)" TransitionPointFrame="Paglipat ng Punto (preym)" TransitionPointType="Paglipat ng Uri ng Punto" TransitionPointTypeFrame="Preym" @@ -20,7 +19,6 @@ TransitionPointTypeTime="Oras (milsegundo)" AudioFadeStyle="Lumabo ang Estilo ng Awdiyo" AudioFadeStyle.FadeOutFadeIn="Lumalabo sa paglipat ng punto pagkatapos maglabo" AudioFadeStyle.CrossFade="Kruspeyd" -SwitchPoint="Tugatok ng Kulay ng Punto (porsyento)" LumaWipeTransition="Pamunas na Luma" LumaWipe.Image="Larawan" LumaWipe.Invert="Baliktarin" diff --git a/plugins/obs-transitions/data/locale/fr-FR.ini b/plugins/obs-transitions/data/locale/fr-FR.ini index 6fcb4b3..4847606 100644 --- a/plugins/obs-transitions/data/locale/fr-FR.ini +++ b/plugins/obs-transitions/data/locale/fr-FR.ini @@ -12,7 +12,7 @@ Direction.Down="Bas" SwipeIn="Recouvrement" Color="Couleur" VideoFile="Fichier vidéo" -TransitionPoint="Point de transition (millisecondes)" +TransitionPoint="Point de transition" TransitionPointFrame="Point de transition (image)" TransitionPointType="Type de transition" TransitionPointTypeFrame="Image" @@ -20,7 +20,7 @@ TransitionPointTypeTime="Durée (en millisecondes)" AudioFadeStyle="Style de fondu audio" AudioFadeStyle.FadeOutFadeIn="Fondu en fermeture jusqu'au point de transition puis fondu en ouverture" AudioFadeStyle.CrossFade="Fondu enchaîné" -SwitchPoint="Point de couleur maximal (pourcentage)" +SwitchPoint="Point de transition par couleur crête" LumaWipeTransition="Balayage Luma" LumaWipe.Image="Image" LumaWipe.Invert="Inverser" diff --git a/plugins/obs-transitions/data/locale/gl-ES.ini b/plugins/obs-transitions/data/locale/gl-ES.ini index 69587e6..c530892 100644 --- a/plugins/obs-transitions/data/locale/gl-ES.ini +++ b/plugins/obs-transitions/data/locale/gl-ES.ini @@ -1,8 +1,66 @@ +FadeTransition="Esvaecer" CutTransition="Cortar" +SwipeTransition="Esvarar" +SlideTransition="Diapositiva" +StingerTransition="Púa" +FadeToColorTransition="Esvaecer a cor" Direction="Dirección" Direction.Left="Esquerda" Direction.Right="Dereita" Direction.Up="Arriba" Direction.Down="Abaixo" +SwipeIn="Esvarar cara dentro" Color="Cor" +VideoFile="Ficheiro de vídeo" +TransitionPoint="Punto de transición" +TransitionPointFrame="Punto de transición (fotograma)" +TransitionPointType="Tipo de punto de transición" +TransitionPointTypeFrame="Fotograma" +TransitionPointTypeTime="Tempo (milisegundos)" +AudioFadeStyle="Estilo de esvaecemento do son" +AudioFadeStyle.FadeOutFadeIn="Esvaece ao punto de transición e desaparece" +AudioFadeStyle.CrossFade="Transición cruzada" +SwitchPoint="Punto de pico de cor" +LumaWipeTransition="Escaneado luma" +LumaWipe.Image="Imaxe" +LumaWipe.Invert="Inverter" +LumaWipe.Softness="Suavizado" +LumaWipe.Type.BarndoorBottomLeft="Porta esvaradía inferior á esquerda" +LumaWipe.Type.BarndoorHorizontal="Porta esvaradía horizontal" +LumaWipe.Type.BarndoorTopLeft="Porta esvaradía superior á esquerda" +LumaWipe.Type.BarndoorVertical="Porta esvaradía vertical" +LumaWipe.Type.BlindsHorizontal="Persiana horizontal" +LumaWipe.Type.BoxBottomLeft="Caixa inferior á esquerda" +LumaWipe.Type.BoxBottomRight="Caixa inferior á dereita" +LumaWipe.Type.BoxTopLeft="Caixa superior á dereita" +LumaWipe.Type.BoxTopRight="Caixa superior á dereita" +LumaWipe.Type.Burst="Refacho" +LumaWipe.Type.CheckerboardSmall="Pequeno taboleiro de xadrez" +LumaWipe.Type.Circles="Círculos" +LumaWipe.Type.Clock="Reloxo" +LumaWipe.Type.Cloud="Nube" +LumaWipe.Type.Curtain="Cortina" +LumaWipe.Type.Fan="Ventilador" +LumaWipe.Type.Fractal="Fractal" +LumaWipe.Type.Iris="Iris" +LumaWipe.Type.LinearHorizontal="Lineal horizontal" +LumaWipe.Type.LinearTopLeft="Lineal superior á esquerda" +LumaWipe.Type.LinearTopRight="Linear superior á dereita" +LumaWipe.Type.LinearVertical="Lineal vertical" +LumaWipe.Type.ParallelZigzagHorizontal="Zigzag paralelo horizontal" +LumaWipe.Type.ParallelZigzagVertical="Zigzag paralelo vertical" +LumaWipe.Type.Sinus9="Seno 9" +LumaWipe.Type.Spiral="Espiral" +LumaWipe.Type.Square="Cadrado" +LumaWipe.Type.Squares="Cadrados" +LumaWipe.Type.Stripes="Bandas" +LumaWipe.Type.StripsHorizontal="Bandas horizontais" +LumaWipe.Type.StripsVertical="Bandas verticais" +LumaWipe.Type.Watercolor="Acuarela" +LumaWipe.Type.ZigzagHorizontal="Zigzag horizontal" +LumaWipe.Type.ZigzagVertical="Zigzag vertical" +AudioMonitoring="Monitorización do son" +AudioMonitoring.None="Monitor apagado" +AudioMonitoring.MonitorOnly="Só o monitor (silenciar a saída)" +AudioMonitoring.Both="Monitor e saída" diff --git a/plugins/obs-transitions/data/locale/he-IL.ini b/plugins/obs-transitions/data/locale/he-IL.ini index 22abe75..93860ea 100644 --- a/plugins/obs-transitions/data/locale/he-IL.ini +++ b/plugins/obs-transitions/data/locale/he-IL.ini @@ -10,5 +10,4 @@ Direction.Up="למעלה" Direction.Down="למטה" SwipeIn="החלקה פנימה" Color="צבע" -SwitchPoint="נקודת שיא צבע (באחוזים)" diff --git a/plugins/obs-transitions/data/locale/hr-HR.ini b/plugins/obs-transitions/data/locale/hr-HR.ini index 473e46f..b277847 100644 --- a/plugins/obs-transitions/data/locale/hr-HR.ini +++ b/plugins/obs-transitions/data/locale/hr-HR.ini @@ -10,7 +10,6 @@ Direction.Up="Gore" Direction.Down="Dole" SwipeIn="Uvlačenje" Color="Boja" -SwitchPoint="Tačka vrhunca boje (procenat)" LumaWipeTransition="Luma brisanje" LumaWipe.Image="Slika" LumaWipe.Invert="Obrnuto" diff --git a/plugins/obs-transitions/data/locale/hu-HU.ini b/plugins/obs-transitions/data/locale/hu-HU.ini index cd72678..c984985 100644 --- a/plugins/obs-transitions/data/locale/hu-HU.ini +++ b/plugins/obs-transitions/data/locale/hu-HU.ini @@ -12,7 +12,7 @@ Direction.Down="Le" SwipeIn="Belapozás" Color="Szín" VideoFile="Videofájl" -TransitionPoint="Átmenetpont (ezredmásodperc)" +TransitionPoint="Átmenetpont" TransitionPointFrame="Átmenetpont (Képkocka)" TransitionPointType="Átmenetpont típus" TransitionPointTypeFrame="Képkocka" @@ -20,7 +20,7 @@ TransitionPointTypeTime="Idő (Ezredmásodperc)" AudioFadeStyle="Hangáttűnés stílusa" AudioFadeStyle.FadeOutFadeIn="Átmenetponthoz halkítás és visszahangosítás" AudioFadeStyle.CrossFade="Átkeverés" -SwitchPoint="Színpont csúcs (százalék)" +SwitchPoint="Csúcs színpont" LumaWipeTransition="Luma törlés" LumaWipe.Image="Kép" LumaWipe.Invert="Megfordítás" diff --git a/plugins/obs-transitions/data/locale/it-IT.ini b/plugins/obs-transitions/data/locale/it-IT.ini index 4cd1f2c..c0eff1d 100644 --- a/plugins/obs-transitions/data/locale/it-IT.ini +++ b/plugins/obs-transitions/data/locale/it-IT.ini @@ -12,7 +12,7 @@ Direction.Down="Verso il basso" SwipeIn="Inverti l'effetto" Color="Colore" VideoFile="File video" -TransitionPoint="Punto di transizione (in millisecondi)" +TransitionPoint="Punto di transizione" TransitionPointFrame="Punto di transizione (in fotogrammi)" TransitionPointType="Tipo del punto di transizione" TransitionPointTypeFrame="In fotogrammi" @@ -20,7 +20,7 @@ TransitionPointTypeTime="A tempo (in millisecondi)" AudioFadeStyle="Stile della dissolvenza audio" AudioFadeStyle.FadeOutFadeIn="Dissolvenza fino al punto di transizione, poi dissolvenza in entrata" AudioFadeStyle.CrossFade="Dissolvenza incrociata" -SwitchPoint="Picco del colore (in percentuale)" +SwitchPoint="Punto Colore di Picco" LumaWipeTransition="Scansione Luma" LumaWipe.Image="Immagine" LumaWipe.Invert="Inverti" diff --git a/plugins/obs-transitions/data/locale/ja-JP.ini b/plugins/obs-transitions/data/locale/ja-JP.ini index 8c39964..097376b 100644 --- a/plugins/obs-transitions/data/locale/ja-JP.ini +++ b/plugins/obs-transitions/data/locale/ja-JP.ini @@ -12,7 +12,7 @@ Direction.Down="下" SwipeIn="スワイプイン" Color="色" VideoFile="動画ファイル" -TransitionPoint="トランジションポイント (ミリ秒)" +TransitionPoint="トランジションポイント" TransitionPointFrame="トランジションポイント (フレーム)" TransitionPointType="トランジションポイントの種類" TransitionPointTypeFrame="フレーム" @@ -20,7 +20,7 @@ TransitionPointTypeTime="時間 (ミリ秒)" AudioFadeStyle="オーディオフェードスタイル" AudioFadeStyle.FadeOutFadeIn="トランジションポイントまでフェードアウトしてからフェードイン" AudioFadeStyle.CrossFade="クロスフェード" -SwitchPoint="ピークカラーポイント (割合)" +SwitchPoint="ピークカラーポイント" LumaWipeTransition="輝度ワイプ" LumaWipe.Image="画像" LumaWipe.Invert="反転" diff --git a/plugins/obs-transitions/data/locale/ka-GE.ini b/plugins/obs-transitions/data/locale/ka-GE.ini index 77b411e..fe2ff24 100644 --- a/plugins/obs-transitions/data/locale/ka-GE.ini +++ b/plugins/obs-transitions/data/locale/ka-GE.ini @@ -12,7 +12,7 @@ Direction.Down="ქვემოთ" SwipeIn="უძრავად შენაცვლება" Color="ფერი" VideoFile="ვიდეოფაილი" -TransitionPoint="გადასვლის წერტილი (მილიწამი)" +TransitionPoint="გადასვლის წერტილი" TransitionPointFrame="გადასვლის წერტილი (კადრი)" TransitionPointType="გადასვლის წერტილის სახეობა" TransitionPointTypeFrame="კადრი" @@ -20,7 +20,7 @@ TransitionPointTypeTime="დრო (წამები)" AudioFadeStyle="ხმის მილევის ნაირსახეობა" AudioFadeStyle.FadeOutFadeIn="თანდათან მილევა გადასვლის წერტილში და შემდეგ მომატება" AudioFadeStyle.CrossFade="ჯვარედინი გადასვლა" -SwitchPoint="ფერის უმაღლესი წერტილი (პროცენტი)" +SwitchPoint="ფერის უმაღლესი წერტილი" LumaWipeTransition="Luma Wipe" LumaWipe.Image="გამოსახულება" LumaWipe.Invert="შებრუნება" diff --git a/plugins/obs-transitions/data/locale/ko-KR.ini b/plugins/obs-transitions/data/locale/ko-KR.ini index 866aede..6c4c4d0 100644 --- a/plugins/obs-transitions/data/locale/ko-KR.ini +++ b/plugins/obs-transitions/data/locale/ko-KR.ini @@ -12,7 +12,7 @@ Direction.Down="아래쪽" SwipeIn="덮기" Color="색상" VideoFile="비디오 파일" -TransitionPoint="전환 지점 (밀리초)" +TransitionPoint="전환 지점" TransitionPointFrame="전환 지점 (프레임)" TransitionPointType="전환 지점 형식" TransitionPointTypeFrame="프레임" @@ -20,7 +20,7 @@ TransitionPointTypeTime="시간 (밀리초)" AudioFadeStyle="소리 점감 형식" AudioFadeStyle.FadeOutFadeIn="전환 지점까지 서서히 작아졌다가 다시 커지기" AudioFadeStyle.CrossFade="천천히 작아지기와 커지기 동시" -SwitchPoint="최고조 색상 지점 (백분율)" +SwitchPoint="최고조 색상 지점" LumaWipeTransition="루마 지우기" LumaWipe.Image="이미지 파일" LumaWipe.Invert="반전" diff --git a/plugins/obs-transitions/data/locale/nb-NO.ini b/plugins/obs-transitions/data/locale/nb-NO.ini index bcf2280..a60b820 100644 --- a/plugins/obs-transitions/data/locale/nb-NO.ini +++ b/plugins/obs-transitions/data/locale/nb-NO.ini @@ -12,7 +12,6 @@ Direction.Down="Ned" SwipeIn="Sveip inn" Color="Farge" VideoFile="Videofil" -TransitionPoint="Overgangspunkt (millisekunder)" TransitionPointFrame="Overgangspunkt (ramme)" TransitionPointType="Overgangspunkttype" TransitionPointTypeFrame="Ramme" @@ -20,7 +19,6 @@ TransitionPointTypeTime="Tid (millisekunder)" AudioFadeStyle="Lyduttoningsstil" AudioFadeStyle.FadeOutFadeIn="Ton ut til overgangspunktet, og så ton inn igjen" AudioFadeStyle.CrossFade="Kryssuttoning" -SwitchPoint="Farge ved høydepunkt (prosent)" LumaWipeTransition="Luminansfjerning" LumaWipe.Image="Bilde" LumaWipe.Invert="Inverter" diff --git a/plugins/obs-transitions/data/locale/nl-NL.ini b/plugins/obs-transitions/data/locale/nl-NL.ini index f869fcf..dad1723 100644 --- a/plugins/obs-transitions/data/locale/nl-NL.ini +++ b/plugins/obs-transitions/data/locale/nl-NL.ini @@ -12,7 +12,7 @@ Direction.Down="Omlaag" SwipeIn="Naar binnen vegen" Color="Kleur" VideoFile="Videobestand" -TransitionPoint="Overgangspunt (milliseconden)" +TransitionPoint="Transitiepunt" TransitionPointFrame="Transitiepunt (frame)" TransitionPointType="Transitiepunt-type" TransitionPointTypeFrame="Frame" @@ -20,7 +20,7 @@ TransitionPointTypeTime="Tijd (milliseconden)" AudioFadeStyle="Audio Fade stijl" AudioFadeStyle.FadeOutFadeIn="Overgang van punt dan fade-in uitfaden" AudioFadeStyle.CrossFade="Crossfading" -SwitchPoint="Wisselpunt (percentage)" +SwitchPoint="Piek Kleurenpunt" LumaWipeTransition="Luma Wipe" LumaWipe.Image="Afbeelding" LumaWipe.Invert="Omkeren" diff --git a/plugins/obs-transitions/data/locale/pl-PL.ini b/plugins/obs-transitions/data/locale/pl-PL.ini index 3154b2a..d9e116f 100644 --- a/plugins/obs-transitions/data/locale/pl-PL.ini +++ b/plugins/obs-transitions/data/locale/pl-PL.ini @@ -12,7 +12,7 @@ Direction.Down="W dół" SwipeIn="Przesuwaj do środka" Color="Kolor" VideoFile="Plik wideo" -TransitionPoint="Punkt przejścia (w milisekundach)" +TransitionPoint="Punkt przejścia" TransitionPointFrame="Punkt przejścia (ramka)" TransitionPointType="Typ punktu przejścia" TransitionPointTypeFrame="Ramka" @@ -20,7 +20,7 @@ TransitionPointTypeTime="Czas (w milisekundach)" AudioFadeStyle="Styl przejścia dźwięku" AudioFadeStyle.FadeOutFadeIn="Stopniowe wyciszenie do punktu przejścia a następnie stopniowe wzmocnienie" AudioFadeStyle.CrossFade="Płynne przejście" -SwitchPoint="Punkt szczytowy koloru (procent)" +SwitchPoint="Szczytowy punkt koloru" LumaWipeTransition="Luma Wipe" LumaWipe.Image="Obraz" LumaWipe.Invert="Odwróć" diff --git a/plugins/obs-transitions/data/locale/pt-BR.ini b/plugins/obs-transitions/data/locale/pt-BR.ini index 634ab31..983598c 100644 --- a/plugins/obs-transitions/data/locale/pt-BR.ini +++ b/plugins/obs-transitions/data/locale/pt-BR.ini @@ -12,7 +12,7 @@ Direction.Down="Baixo" SwipeIn="Deslizar para" Color="Cor" VideoFile="Arquivo de Vídeo" -TransitionPoint="Ponto de Transição (milissegundos)" +TransitionPoint="Ponto de transição" TransitionPointFrame="Ponto de transição (quadro)" TransitionPointType="Tipo de Ponto de Transição" TransitionPointTypeFrame="Quadro" @@ -20,7 +20,7 @@ TransitionPointTypeTime="Tempo (milissegundos)" AudioFadeStyle="Estilo de Esmaecimento de Áudio" AudioFadeStyle.FadeOutFadeIn="Esmaecer imagem até o ponto de transição e depois aparecer" AudioFadeStyle.CrossFade="Transição Suave" -SwitchPoint="Ponto de Pico de Cor (porcentagem)" +SwitchPoint="Ponto de cor do pico" LumaWipeTransition="Luma Wipe" LumaWipe.Image="Imagem" LumaWipe.Invert="Inverso" diff --git a/plugins/obs-transitions/data/locale/pt-PT.ini b/plugins/obs-transitions/data/locale/pt-PT.ini index 880cf60..45d92d9 100644 --- a/plugins/obs-transitions/data/locale/pt-PT.ini +++ b/plugins/obs-transitions/data/locale/pt-PT.ini @@ -12,9 +12,7 @@ Direction.Down="Baixo" SwipeIn="Deslizar para dentro" Color="Cor" VideoFile="Ficheiro Vídeo" -TransitionPoint="Ponto de Transição (milissegundos)" TransitionPointFrame="Ponto de transição (quadro)" TransitionPointType="Tipo de Ponto de Transição" TransitionPointTypeTime="Tempo (milissegundos)" -SwitchPoint="Ponto de pico de Cor (percentagem)" diff --git a/plugins/obs-transitions/data/locale/ro-RO.ini b/plugins/obs-transitions/data/locale/ro-RO.ini index b7bef52..2c0afc7 100644 --- a/plugins/obs-transitions/data/locale/ro-RO.ini +++ b/plugins/obs-transitions/data/locale/ro-RO.ini @@ -11,12 +11,10 @@ Direction.Up="Sus" Direction.Down="Jos" SwipeIn="Glisează peste" Color="Culoare" -TransitionPoint="Punct de tranziție (milisecunde)" TransitionPointFrame="Punct de tranziție (fotogramă)" TransitionPointType="Tipul punctului de tranziție" TransitionPointTypeFrame="Fotogramă" TransitionPointTypeTime="Timp (milisecunde)" -SwitchPoint="Punctul de vârf al culorii (procent)" LumaWipe.Image="Imagine" LumaWipe.Invert="Inversează" LumaWipe.Softness="Moliciune" diff --git a/plugins/obs-transitions/data/locale/ru-RU.ini b/plugins/obs-transitions/data/locale/ru-RU.ini index a9f5f70..07dfe48 100644 --- a/plugins/obs-transitions/data/locale/ru-RU.ini +++ b/plugins/obs-transitions/data/locale/ru-RU.ini @@ -12,7 +12,7 @@ Direction.Down="Вниз" SwipeIn="Перемещение внутрь" Color="Цвет" VideoFile="Файл видео" -TransitionPoint="Точка перехода (миллисекунды)" +TransitionPoint="Точка перехода" TransitionPointFrame="Точка перехода (кадр)" TransitionPointType="Тип точки перехода" TransitionPointTypeFrame="Кадр" @@ -20,7 +20,7 @@ TransitionPointTypeTime="Время (миллисекунд)" AudioFadeStyle="Стиль затухания аудио" AudioFadeStyle.FadeOutFadeIn="Затухание в точку перехода с последующим появлением" AudioFadeStyle.CrossFade="Переход" -SwitchPoint="Точка цветового пика (в процентах)" +SwitchPoint="Точка цветового пика" LumaWipeTransition="Выцветание" LumaWipe.Image="Изображение" LumaWipe.Invert="Инвертировать" diff --git a/plugins/obs-transitions/data/locale/sk-SK.ini b/plugins/obs-transitions/data/locale/sk-SK.ini index 3d3bf31..d0794a6 100644 --- a/plugins/obs-transitions/data/locale/sk-SK.ini +++ b/plugins/obs-transitions/data/locale/sk-SK.ini @@ -11,7 +11,6 @@ Direction.Up="Nahor" Direction.Down="Nadol" Color="Farba" VideoFile="Video súbor" -TransitionPoint="Bod prechodu (v milisekundách)" TransitionPointFrame="Bod prechodu (v snímkoch)" TransitionPointType="Typ bodu prechodu" TransitionPointTypeFrame="Snímok" diff --git a/plugins/obs-transitions/data/locale/sl-SI.ini b/plugins/obs-transitions/data/locale/sl-SI.ini new file mode 100644 index 0000000..02f3bf0 --- /dev/null +++ b/plugins/obs-transitions/data/locale/sl-SI.ini @@ -0,0 +1,66 @@ +FadeTransition="Pojemaj" +CutTransition="Izreži" +SwipeTransition="Potegni" +SlideTransition="Podrsaj" +StingerTransition="Stinger" +FadeToColorTransition="Pojemaj v barvo" +Direction="Smer" +Direction.Left="Levo" +Direction.Right="Desno" +Direction.Up="Gor" +Direction.Down="Dol" +SwipeIn="Potegni navznoter" +Color="Barva" +VideoFile="Videodatoteka" +TransitionPoint="Točka prehoda" +TransitionPointFrame="Točka prehoda (sličica)" +TransitionPointType="Vrsta točke prehoda" +TransitionPointTypeFrame="Sličica" +TransitionPointTypeTime="Čas (ms)" +AudioFadeStyle="Slog pojemanja zvoka" +AudioFadeStyle.FadeOutFadeIn="Pojemaj do točke prehoda in nato povračaj" +AudioFadeStyle.CrossFade="Navzkrižno pojemanje" +SwitchPoint="Najvišja točka barve" +LumaWipeTransition="Svetlobno brisanje" +LumaWipe.Image="Slika" +LumaWipe.Invert="Obrni" +LumaWipe.Softness="Mehkost" +LumaWipe.Type.BarndoorBottomLeft="Vrata spodaj levo" +LumaWipe.Type.BarndoorHorizontal="Vodoravna vrata" +LumaWipe.Type.BarndoorTopLeft="Vrata zgoraj levo" +LumaWipe.Type.BarndoorVertical="Navpična vrata" +LumaWipe.Type.BlindsHorizontal="Vodoravne žaluzije" +LumaWipe.Type.BoxBottomLeft="Kvader spodaj levo" +LumaWipe.Type.BoxBottomRight="Kvader spodaj desno" +LumaWipe.Type.BoxTopLeft="Kvader zgoraj levo" +LumaWipe.Type.BoxTopRight="Kvader zgoraj desno" +LumaWipe.Type.Burst="Pok" +LumaWipe.Type.CheckerboardSmall="Majhna šahovnica" +LumaWipe.Type.Circles="Krogi" +LumaWipe.Type.Clock="Ura" +LumaWipe.Type.Cloud="Oblak" +LumaWipe.Type.Curtain="Zavesa" +LumaWipe.Type.Fan="Ventilator" +LumaWipe.Type.Fractal="Fraktal" +LumaWipe.Type.Iris="Zaslonka" +LumaWipe.Type.LinearHorizontal="Premočrtno vodoravno" +LumaWipe.Type.LinearTopLeft="Premočrtno zgoraj levo" +LumaWipe.Type.LinearTopRight="Premočrtno zgoraj desno" +LumaWipe.Type.LinearVertical="Premočrtno navpično" +LumaWipe.Type.ParallelZigzagHorizontal="Vzporedno cikcak vodoravno" +LumaWipe.Type.ParallelZigzagVertical="Vzporedno cikcak navpično" +LumaWipe.Type.Sinus9="Sinus 9" +LumaWipe.Type.Spiral="Spirala" +LumaWipe.Type.Square="Kvadrat" +LumaWipe.Type.Squares="Kvadrati" +LumaWipe.Type.Stripes="Črte" +LumaWipe.Type.StripsHorizontal="Vodoravne črte" +LumaWipe.Type.StripsVertical="Navpične črte" +LumaWipe.Type.Watercolor="Vodna barva" +LumaWipe.Type.ZigzagHorizontal="Cikcak vodoravno" +LumaWipe.Type.ZigzagVertical="Cikcak navpično" +AudioMonitoring="Nadzor zvoka" +AudioMonitoring.None="Nadzor je izklopljen" +AudioMonitoring.MonitorOnly="Samo nadziraj (utišaj izhod)" +AudioMonitoring.Both="Nadzor in izhod" + diff --git a/plugins/obs-transitions/data/locale/sr-CS.ini b/plugins/obs-transitions/data/locale/sr-CS.ini index 14be8c6..9abc1a5 100644 --- a/plugins/obs-transitions/data/locale/sr-CS.ini +++ b/plugins/obs-transitions/data/locale/sr-CS.ini @@ -12,7 +12,6 @@ Direction.Down="Dole" SwipeIn="Uvlačenje" Color="Boja" VideoFile="Video fajl" -TransitionPoint="Početak prelaza (milisekunde)" TransitionPointFrame="Početak prelaza (frejm)" TransitionPointType="Tip početka prelaza" TransitionPointTypeFrame="Frejm" @@ -20,7 +19,6 @@ TransitionPointTypeTime="Vreme (milisekunde)" AudioFadeStyle="Način na koji zvuk nestaje" AudioFadeStyle.FadeOutFadeIn="Nestaje do tačke prelaza a zatim se ponovo vraća" AudioFadeStyle.CrossFade="Nestaje unakrsno" -SwitchPoint="Tačka vrhunca boje (procenat)" LumaWipeTransition="Luma brisanje" LumaWipe.Image="Slika" LumaWipe.Invert="Obrnuto" diff --git a/plugins/obs-transitions/data/locale/sr-SP.ini b/plugins/obs-transitions/data/locale/sr-SP.ini index 0934699..f28ba5d 100644 --- a/plugins/obs-transitions/data/locale/sr-SP.ini +++ b/plugins/obs-transitions/data/locale/sr-SP.ini @@ -12,7 +12,6 @@ Direction.Down="Доле" SwipeIn="Увлачење" Color="Боја" VideoFile="Видео фајл" -TransitionPoint="Почетак прелаза (милисекунде)" TransitionPointFrame="Почетак прелаза (фрејм)" TransitionPointType="Тип почетка прелаза" TransitionPointTypeFrame="Фрејм" @@ -20,7 +19,6 @@ TransitionPointTypeTime="Време (милисекунде)" AudioFadeStyle="Начин на који звук нестаје" AudioFadeStyle.FadeOutFadeIn="Нестаје до тачке прелаза а затим се поново враћа" AudioFadeStyle.CrossFade="Нестаје унакрсно" -SwitchPoint="Тачка врхунца боје (проценат)" LumaWipeTransition="Лума брисање" LumaWipe.Image="Слика" LumaWipe.Invert="Обрнуто" diff --git a/plugins/obs-transitions/data/locale/sv-SE.ini b/plugins/obs-transitions/data/locale/sv-SE.ini index 967512e..57badbe 100644 --- a/plugins/obs-transitions/data/locale/sv-SE.ini +++ b/plugins/obs-transitions/data/locale/sv-SE.ini @@ -12,7 +12,7 @@ Direction.Down="Ned" SwipeIn="Svep in" Color="Färg" VideoFile="Videofil" -TransitionPoint="Övergångspunkt (millisekunder)" +TransitionPoint="Övergångspunkt" TransitionPointFrame="Övergångspunkt (bildruta)" TransitionPointType="Typ av övergångspunkt" TransitionPointTypeFrame="Bildruta" @@ -20,7 +20,7 @@ TransitionPointTypeTime="Tid (millisekunder)" AudioFadeStyle="Stil för ljuduttoning" AudioFadeStyle.FadeOutFadeIn="Tona ut till övergångspunkten och sedan tona in" AudioFadeStyle.CrossFade="Övertoning" -SwitchPoint="Maxpunkt för färg (procent)" +SwitchPoint="Färgmaxpunkt" LumaWipeTransition="Luma Wipe" LumaWipe.Image="Bild" LumaWipe.Invert="Invertera" diff --git a/plugins/obs-transitions/data/locale/tl-PH.ini b/plugins/obs-transitions/data/locale/tl-PH.ini index f629c91..84c39c5 100644 --- a/plugins/obs-transitions/data/locale/tl-PH.ini +++ b/plugins/obs-transitions/data/locale/tl-PH.ini @@ -12,7 +12,6 @@ Direction.Down="Pababa" SwipeIn="Mag-swipe papasok" Color="Kulay" VideoFile="File ng mga video" -TransitionPoint="Pinagmulan ng Pagbabago (millisegundos)" TransitionPointFrame="Pinagmulan ng Pagbabago (Frame)" TransitionPointType="Pinagmulan ng Pagbabago ng Tipo" TransitionPointTypeFrame="Ang frame" @@ -20,7 +19,6 @@ TransitionPointTypeTime="Oras (millisegundos)" AudioFadeStyle="Palabo ang istilo ng Audio" AudioFadeStyle.FadeOutFadeIn="Palabo ang palabas sa pinagmulan ng pagbabago tapos palabo papasok" AudioFadeStyle.CrossFade="Crossfade" -SwitchPoint="Peak Color Point (porsyento)" LumaWipeTransition="Luma Wipe" LumaWipe.Image="Imahe" LumaWipe.Invert="Ibaliktad" diff --git a/plugins/obs-transitions/data/locale/tr-TR.ini b/plugins/obs-transitions/data/locale/tr-TR.ini index 5217955..88e3323 100644 --- a/plugins/obs-transitions/data/locale/tr-TR.ini +++ b/plugins/obs-transitions/data/locale/tr-TR.ini @@ -12,7 +12,7 @@ Direction.Down="Aşağı" SwipeIn="İçeri Kaydır" Color="Renk" VideoFile="Video Dosyası" -TransitionPoint="Geçiş Noktası (milisaniye)" +TransitionPoint="Geçiş Noktası" TransitionPointFrame="Geçiş Noktası (kare)" TransitionPointType="Geçiş Noktası Türü" TransitionPointTypeFrame="Kare" @@ -20,7 +20,6 @@ TransitionPointTypeTime="Süre (milisaniye)" AudioFadeStyle="Ses Geçiş Stili" AudioFadeStyle.FadeOutFadeIn="Geçiş noktasına doğru azalt sonra artır" AudioFadeStyle.CrossFade="Çapraz Geçiş" -SwitchPoint="En yüksek Renk Noktası (yüzde)" LumaWipeTransition="Luma Wipe" LumaWipe.Image="Görüntü" LumaWipe.Invert="Ters Çevir" diff --git a/plugins/obs-transitions/data/locale/uk-UA.ini b/plugins/obs-transitions/data/locale/uk-UA.ini index 61fabb0..839a5aa 100644 --- a/plugins/obs-transitions/data/locale/uk-UA.ini +++ b/plugins/obs-transitions/data/locale/uk-UA.ini @@ -12,7 +12,7 @@ Direction.Down="Вниз" SwipeIn="В кадр" Color="Колір" VideoFile="Файл відео" -TransitionPoint="Точка відео-переходу (мілісекунд)" +TransitionPoint="Точка відео-переходу" TransitionPointFrame="Точка відео-переходу (кадр)" TransitionPointType="Тип точки відео-переходу" TransitionPointTypeFrame="Кадр" @@ -20,7 +20,7 @@ TransitionPointTypeTime="Час (мілісекунд)" AudioFadeStyle="Стиль затухання Аудіо" AudioFadeStyle.FadeOutFadeIn="Затухання до точки відео-переходу, потім гучність наростає" AudioFadeStyle.CrossFade="Плавний перехід (з початку)" -SwitchPoint="Найвища точка для кольору (відсоток)" +SwitchPoint="Точка кольору, відстань" LumaWipeTransition="Luma Wipe" LumaWipe.Image="Зображення" LumaWipe.Invert="Інвертувати" diff --git a/plugins/obs-transitions/data/locale/zh-CN.ini b/plugins/obs-transitions/data/locale/zh-CN.ini index 7bd0868..47cdc82 100644 --- a/plugins/obs-transitions/data/locale/zh-CN.ini +++ b/plugins/obs-transitions/data/locale/zh-CN.ini @@ -12,7 +12,7 @@ Direction.Down="下" SwipeIn="滑入" Color="色彩" VideoFile="视频文件" -TransitionPoint="转换点(毫秒)" +TransitionPoint="转换点" TransitionPointFrame="转换点(帧)" TransitionPointType="转换点类型" TransitionPointTypeFrame="帧" @@ -20,7 +20,7 @@ TransitionPointTypeTime="时间(毫秒)" AudioFadeStyle="音频淡入淡出样式" AudioFadeStyle.FadeOutFadeIn="淡出到过渡点然后淡入" AudioFadeStyle.CrossFade="交叉淡入淡出" -SwitchPoint="峰值颜色点(百分比)" +SwitchPoint="峰值颜色点" LumaWipeTransition="亮度擦除" LumaWipe.Image="图像" LumaWipe.Invert="反转" diff --git a/plugins/obs-transitions/data/locale/zh-TW.ini b/plugins/obs-transitions/data/locale/zh-TW.ini index 9db7a53..e77c1b0 100644 --- a/plugins/obs-transitions/data/locale/zh-TW.ini +++ b/plugins/obs-transitions/data/locale/zh-TW.ini @@ -12,7 +12,7 @@ Direction.Down="下" SwipeIn="滑入" Color="顏色" VideoFile="影片檔" -TransitionPoint="轉換點 (毫秒)" +TransitionPoint="轉換點" TransitionPointFrame="轉換點 (訊框)" TransitionPointType="轉換點類型" TransitionPointTypeFrame="訊框" @@ -20,7 +20,7 @@ TransitionPointTypeTime="時間 (毫秒)" AudioFadeStyle="音訊淡入淡出風格" AudioFadeStyle.FadeOutFadeIn="淡出至轉換點再淡入" AudioFadeStyle.CrossFade="交叉式淡入淡出" -SwitchPoint="顏色峰值點 (百分比)" +SwitchPoint="峰值色點" LumaWipeTransition="Luma Wipe" LumaWipe.Image="影像" LumaWipe.Invert="倒置" diff --git a/plugins/obs-transitions/transition-cut.c b/plugins/obs-transitions/transition-cut.c index 9e0a0e5..9b20383 100644 --- a/plugins/obs-transitions/transition-cut.c +++ b/plugins/obs-transitions/transition-cut.c @@ -48,12 +48,13 @@ static float mix_b(void *data, float t) } static bool cut_audio_render(void *data, uint64_t *ts_out, - struct obs_source_audio_mix *audio, uint32_t mixers, - size_t channels, size_t sample_rate) + struct obs_source_audio_mix *audio, + uint32_t mixers, size_t channels, + size_t sample_rate) { struct cut_info *cut = data; - return obs_transition_audio_render(cut->source, ts_out, - audio, mixers, channels, sample_rate, mix_a, mix_b); + return obs_transition_audio_render(cut->source, ts_out, audio, mixers, + channels, sample_rate, mix_a, mix_b); } struct obs_source_info cut_transition = { diff --git a/plugins/obs-transitions/transition-fade-to-color.c b/plugins/obs-transitions/transition-fade-to-color.c index 65e78d3..d5f647f 100644 --- a/plugins/obs-transitions/transition-fade-to-color.c +++ b/plugins/obs-transitions/transition-fade-to-color.c @@ -35,7 +35,7 @@ static inline float clamp(float x, float min, float max) static inline float smoothstep(float min, float max, float x) { x = clamp((x - min) / (max - min), 0.0f, 1.0f); - return x*x*(3 - 2 * x); + return x * x * (3 - 2 * x); } static const char *fade_to_color_get_name(void *type_data) @@ -48,7 +48,7 @@ static void fade_to_color_update(void *data, obs_data_t *settings) { struct fade_to_color_info *fade_to_color = data; uint32_t color = (uint32_t)obs_data_get_int(settings, S_COLOR); - uint32_t swp = (uint32_t)obs_data_get_int(settings, S_SWITCH_POINT); + uint32_t swp = (uint32_t)obs_data_get_int(settings, S_SWITCH_POINT); color |= 0xFF000000; @@ -70,7 +70,8 @@ static void *fade_to_color_create(obs_data_t *settings, obs_source_t *source) bfree(file); if (!effect) { - blog(LOG_ERROR, "Could not find fade_to_color_transition.effect"); + blog(LOG_ERROR, + "Could not find fade_to_color_transition.effect"); return NULL; } @@ -79,8 +80,8 @@ static void *fade_to_color_create(obs_data_t *settings, obs_source_t *source) fade_to_color->source = source; fade_to_color->effect = effect; - fade_to_color->ep_tex = gs_effect_get_param_by_name(effect, "tex"); - fade_to_color->ep_swp = gs_effect_get_param_by_name(effect, "swp"); + fade_to_color->ep_tex = gs_effect_get_param_by_name(effect, "tex"); + fade_to_color->ep_swp = gs_effect_get_param_by_name(effect, "swp"); fade_to_color->ep_color = gs_effect_get_param_by_name(effect, "color"); obs_source_update(source, settings); @@ -95,7 +96,7 @@ static void fade_to_color_destroy(void *data) } static void fade_to_color_callback(void *data, gs_texture_t *a, gs_texture_t *b, - float t, uint32_t cx, uint32_t cy) + float t, uint32_t cx, uint32_t cy) { struct fade_to_color_info *fade_to_color = data; @@ -117,7 +118,7 @@ static void fade_to_color_video_render(void *data, gs_effect_t *effect) { struct fade_to_color_info *fade_to_color = data; obs_transition_video_render(fade_to_color->source, - fade_to_color_callback); + fade_to_color_callback); UNUSED_PARAMETER(effect); } @@ -126,7 +127,7 @@ static float mix_a(void *data, float t) struct fade_to_color_info *fade_to_color = data; float sp = fade_to_color->switch_point; - return lerp(1.0f - t , 0.0f, smoothstep(0.0f, sp, t)); + return lerp(1.0f - t, 0.0f, smoothstep(0.0f, sp, t)); } static float mix_b(void *data, float t) @@ -138,12 +139,14 @@ static float mix_b(void *data, float t) } static bool fade_to_color_audio_render(void *data, uint64_t *ts_out, - struct obs_source_audio_mix *audio, uint32_t mixers, - size_t channels, size_t sample_rate) + struct obs_source_audio_mix *audio, + uint32_t mixers, size_t channels, + size_t sample_rate) { struct fade_to_color_info *fade_to_color = data; - return obs_transition_audio_render(fade_to_color->source, ts_out, - audio, mixers, channels, sample_rate, mix_a, mix_b); + return obs_transition_audio_render(fade_to_color->source, ts_out, audio, + mixers, channels, sample_rate, mix_a, + mix_b); } static obs_properties_t *fade_to_color_properties(void *data) @@ -151,8 +154,9 @@ static obs_properties_t *fade_to_color_properties(void *data) obs_properties_t *props = obs_properties_create(); obs_properties_add_color(props, S_COLOR, S_COLOR_TEXT); - obs_properties_add_int_slider(props, S_SWITCH_POINT, - S_SWITCH_POINT_TEXT, 0, 100, 1); + obs_property_t *p = obs_properties_add_int_slider( + props, S_SWITCH_POINT, S_SWITCH_POINT_TEXT, 0, 100, 1); + obs_property_int_set_suffix(p, "%"); UNUSED_PARAMETER(data); return props; @@ -165,14 +169,14 @@ static void fade_to_color_defaults(obs_data_t *settings) } struct obs_source_info fade_to_color_transition = { - .id = "fade_to_color_transition", - .type = OBS_SOURCE_TYPE_TRANSITION, - .get_name = fade_to_color_get_name, - .create = fade_to_color_create, - .destroy = fade_to_color_destroy, - .update = fade_to_color_update, - .video_render = fade_to_color_video_render, - .audio_render = fade_to_color_audio_render, + .id = "fade_to_color_transition", + .type = OBS_SOURCE_TYPE_TRANSITION, + .get_name = fade_to_color_get_name, + .create = fade_to_color_create, + .destroy = fade_to_color_destroy, + .update = fade_to_color_update, + .video_render = fade_to_color_video_render, + .audio_render = fade_to_color_audio_render, .get_properties = fade_to_color_properties, - .get_defaults = fade_to_color_defaults + .get_defaults = fade_to_color_defaults, }; diff --git a/plugins/obs-transitions/transition-fade.c b/plugins/obs-transitions/transition-fade.c index c814772..9358de9 100644 --- a/plugins/obs-transitions/transition-fade.c +++ b/plugins/obs-transitions/transition-fade.c @@ -49,7 +49,7 @@ static void fade_destroy(void *data) } static void fade_callback(void *data, gs_texture_t *a, gs_texture_t *b, float t, - uint32_t cx, uint32_t cy) + uint32_t cx, uint32_t cy) { struct fade_info *fade = data; @@ -81,12 +81,13 @@ static float mix_b(void *data, float t) } static bool fade_audio_render(void *data, uint64_t *ts_out, - struct obs_source_audio_mix *audio, uint32_t mixers, - size_t channels, size_t sample_rate) + struct obs_source_audio_mix *audio, + uint32_t mixers, size_t channels, + size_t sample_rate) { struct fade_info *fade = data; - return obs_transition_audio_render(fade->source, ts_out, - audio, mixers, channels, sample_rate, mix_a, mix_b); + return obs_transition_audio_render(fade->source, ts_out, audio, mixers, + channels, sample_rate, mix_a, mix_b); } struct obs_source_info fade_transition = { @@ -96,5 +97,5 @@ struct obs_source_info fade_transition = { .create = fade_create, .destroy = fade_destroy, .video_render = fade_video_render, - .audio_render = fade_audio_render + .audio_render = fade_audio_render, }; diff --git a/plugins/obs-transitions/transition-luma-wipe.c b/plugins/obs-transitions/transition-luma-wipe.c index 6b8ec2c..9af2479 100644 --- a/plugins/obs-transitions/transition-luma-wipe.c +++ b/plugins/obs-transitions/transition-luma-wipe.c @@ -2,6 +2,8 @@ #include #include +/* clang-format off */ + #define S_LUMA_IMG "luma_image" #define S_LUMA_INV "luma_invert" #define S_LUMA_SOFT "luma_softness" @@ -10,6 +12,8 @@ #define T_LUMA_INV obs_module_text("LumaWipe.Invert") #define T_LUMA_SOFT obs_module_text("LumaWipe.Softness") +/* clang-format on */ + struct luma_wipe_info { obs_source_t *source; @@ -22,7 +26,7 @@ struct luma_wipe_info { gs_eparam_t *ep_softness; gs_image_file_t luma_image; - bool invert_luma; + bool invert_luma; float softness; obs_data_t *wipes_list; }; @@ -94,14 +98,14 @@ static void *luma_wipe_create(obs_data_t *settings, obs_source_t *source) lwipe = bzalloc(sizeof(*lwipe)); - lwipe->effect = effect; - lwipe->ep_a_tex = gs_effect_get_param_by_name(effect, "a_tex"); - lwipe->ep_b_tex = gs_effect_get_param_by_name(effect, "b_tex"); - lwipe->ep_l_tex = gs_effect_get_param_by_name(effect, "l_tex"); + lwipe->effect = effect; + lwipe->ep_a_tex = gs_effect_get_param_by_name(effect, "a_tex"); + lwipe->ep_b_tex = gs_effect_get_param_by_name(effect, "b_tex"); + lwipe->ep_l_tex = gs_effect_get_param_by_name(effect, "l_tex"); lwipe->ep_progress = gs_effect_get_param_by_name(effect, "progress"); - lwipe->ep_invert = gs_effect_get_param_by_name(effect, "invert"); + lwipe->ep_invert = gs_effect_get_param_by_name(effect, "invert"); lwipe->ep_softness = gs_effect_get_param_by_name(effect, "softness"); - lwipe->source = source; + lwipe->source = source; luma_wipe_get_list(lwipe); @@ -131,7 +135,8 @@ static obs_properties_t *luma_wipe_properties(void *data) obs_property_t *p; p = obs_properties_add_list(props, S_LUMA_IMG, T_LUMA_IMG, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_data_item_t *item = obs_data_first(lwipe->wipes_list); @@ -141,7 +146,8 @@ static obs_properties_t *luma_wipe_properties(void *data) obs_property_list_add_string(p, obs_module_text(name), path); } - obs_properties_add_float(props, S_LUMA_SOFT, T_LUMA_SOFT, 0.0, 1.0, 0.05); + obs_properties_add_float(props, S_LUMA_SOFT, T_LUMA_SOFT, 0.0, 1.0, + 0.05); obs_properties_add_bool(props, S_LUMA_INV, T_LUMA_INV); return props; @@ -191,23 +197,23 @@ static float mix_b(void *data, float t) } bool luma_wipe_audio_render(void *data, uint64_t *ts_out, - struct obs_source_audio_mix *audio, uint32_t mixers, - size_t channels, size_t sample_rate) + struct obs_source_audio_mix *audio, uint32_t mixers, + size_t channels, size_t sample_rate) { struct luma_wipe_info *lwipe = data; return obs_transition_audio_render(lwipe->source, ts_out, audio, mixers, - channels, sample_rate, mix_a, mix_b); + channels, sample_rate, mix_a, mix_b); } struct obs_source_info luma_wipe_transition = { - .id = "wipe_transition", - .type = OBS_SOURCE_TYPE_TRANSITION, - .get_name = luma_wipe_get_name, - .create = luma_wipe_create, - .destroy = luma_wipe_destroy, - .update = luma_wipe_update, - .video_render = luma_wipe_video_render, - .audio_render = luma_wipe_audio_render, - .get_properties = luma_wipe_properties, - .get_defaults = luma_wipe_defaults + .id = "wipe_transition", + .type = OBS_SOURCE_TYPE_TRANSITION, + .get_name = luma_wipe_get_name, + .create = luma_wipe_create, + .destroy = luma_wipe_destroy, + .update = luma_wipe_update, + .video_render = luma_wipe_video_render, + .audio_render = luma_wipe_audio_render, + .get_properties = luma_wipe_properties, + .get_defaults = luma_wipe_defaults, }; diff --git a/plugins/obs-transitions/transition-slide.c b/plugins/obs-transitions/transition-slide.c index d381477..b3c1e53 100644 --- a/plugins/obs-transitions/transition-slide.c +++ b/plugins/obs-transitions/transition-slide.c @@ -29,13 +29,13 @@ static void slide_update(void *data, obs_data_t *settings) const char *dir = obs_data_get_string(settings, S_DIRECTION); if (strcmp(dir, "right") == 0) - slide->dir = (struct vec2){ -1.0f, 0.0f }; + slide->dir = (struct vec2){-1.0f, 0.0f}; else if (strcmp(dir, "up") == 0) - slide->dir = (struct vec2){ 0.0f, 1.0f }; + slide->dir = (struct vec2){0.0f, 1.0f}; else if (strcmp(dir, "down") == 0) - slide->dir = (struct vec2){ 0.0f, -1.0f }; + slide->dir = (struct vec2){0.0f, -1.0f}; else /* left */ - slide->dir = (struct vec2){ 1.0f, 0.0f }; + slide->dir = (struct vec2){1.0f, 0.0f}; } void *slide_create(obs_data_t *settings, obs_source_t *source) @@ -123,12 +123,12 @@ static float mix_b(void *data, float t) } bool slide_audio_render(void *data, uint64_t *ts_out, - struct obs_source_audio_mix *audio, uint32_t mixers, - size_t channels, size_t sample_rate) + struct obs_source_audio_mix *audio, uint32_t mixers, + size_t channels, size_t sample_rate) { struct slide_info *slide = data; - return obs_transition_audio_render(slide->source, ts_out, - audio, mixers, channels, sample_rate, mix_a, mix_b); + return obs_transition_audio_render(slide->source, ts_out, audio, mixers, + channels, sample_rate, mix_a, mix_b); } static obs_properties_t *slide_properties(void *data) @@ -137,16 +137,16 @@ static obs_properties_t *slide_properties(void *data) obs_property_t *p; p = obs_properties_add_list(ppts, S_DIRECTION, - obs_module_text("Direction"), OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_STRING); + obs_module_text("Direction"), + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, obs_module_text("Direction.Left"), - "left"); + "left"); obs_property_list_add_string(p, obs_module_text("Direction.Right"), - "right"); - obs_property_list_add_string(p, obs_module_text("Direction.Up"), - "up"); + "right"); + obs_property_list_add_string(p, obs_module_text("Direction.Up"), "up"); obs_property_list_add_string(p, obs_module_text("Direction.Down"), - "down"); + "down"); UNUSED_PARAMETER(data); return ppts; @@ -161,5 +161,5 @@ struct obs_source_info slide_transition = { .update = slide_update, .video_render = slide_video_render, .audio_render = slide_audio_render, - .get_properties = slide_properties + .get_properties = slide_properties, }; diff --git a/plugins/obs-transitions/transition-stinger.c b/plugins/obs-transitions/transition-stinger.c index dc5b5a7..502f93d 100644 --- a/plugins/obs-transitions/transition-stinger.c +++ b/plugins/obs-transitions/transition-stinger.c @@ -1,12 +1,9 @@ #include -#define TIMING_TIME 0 +#define TIMING_TIME 0 #define TIMING_FRAME 1 -enum fade_style { - FADE_STYLE_FADE_OUT_FADE_IN, - FADE_STYLE_CROSS_FADE -}; +enum fade_style { FADE_STYLE_FADE_OUT_FADE_IN, FADE_STYLE_CROSS_FADE }; struct stinger_info { obs_source_t *source; @@ -50,24 +47,25 @@ static void stinger_update(void *data, obs_data_t *settings) obs_source_release(s->media_source); s->media_source = obs_source_create_private("ffmpeg_source", NULL, - media_settings); + media_settings); obs_data_release(media_settings); int64_t point = obs_data_get_int(settings, "transition_point"); - s->transition_point_is_frame = - obs_data_get_int(settings, "tp_type") == TIMING_FRAME; + s->transition_point_is_frame = obs_data_get_int(settings, "tp_type") == + TIMING_FRAME; if (s->transition_point_is_frame) s->transition_point_frame = (uint64_t)point; else s->transition_point_ns = (uint64_t)(point * 1000000LL); - s->monitoring_type = (int)obs_data_get_int(settings,"audio_monitoring"); + s->monitoring_type = + (int)obs_data_get_int(settings, "audio_monitoring"); obs_source_set_monitoring_type(s->media_source, s->monitoring_type); - s->fade_style = (enum fade_style)obs_data_get_int(settings, - "audio_fade_style"); + s->fade_style = + (enum fade_style)obs_data_get_int(settings, "audio_fade_style"); switch (s->fade_style) { default: @@ -109,9 +107,8 @@ static void stinger_video_render(void *data, gs_effect_t *effect) float t = obs_transition_get_time(s->source); bool use_a = t < s->transition_point; - enum obs_transition_target target = use_a - ? OBS_TRANSITION_SOURCE_A - : OBS_TRANSITION_SOURCE_B; + enum obs_transition_target target = use_a ? OBS_TRANSITION_SOURCE_A + : OBS_TRANSITION_SOURCE_B; if (!obs_transition_video_render_direct(s->source, target)) return; @@ -168,8 +165,9 @@ static float mix_b_cross_fade(void *data, float t) } static bool stinger_audio_render(void *data, uint64_t *ts_out, - struct obs_source_audio_mix *audio, uint32_t mixers, - size_t channels, size_t sample_rate) + struct obs_source_audio_mix *audio, + uint32_t mixers, size_t channels, + size_t sample_rate) { struct stinger_info *s = data; uint64_t ts = 0; @@ -180,8 +178,10 @@ static bool stinger_audio_render(void *data, uint64_t *ts_out, return false; } - bool success = obs_transition_audio_render(s->source, ts_out, - audio, mixers, channels, sample_rate, s->mix_a, s->mix_b); + bool success = obs_transition_audio_render(s->source, ts_out, audio, + mixers, channels, + sample_rate, s->mix_a, + s->mix_b); if (!ts) return success; @@ -229,13 +229,13 @@ static void stinger_transition_start(void *data) s->duration_frames = (uint64_t)calldata_int(&cd, "num_frames"); if (s->transition_point_is_frame) - s->transition_point = (float)( - (long double)s->transition_point_frame / - (long double)s->duration_frames); + s->transition_point = + (float)((long double)s->transition_point_frame / + (long double)s->duration_frames); else - s->transition_point = (float)( - (long double)s->transition_point_ns / - (long double)s->duration_ns); + s->transition_point = + (float)((long double)s->transition_point_ns / + (long double)s->duration_ns); if (s->transition_point > 0.999f) s->transition_point = 0.999f; @@ -245,8 +245,8 @@ static void stinger_transition_start(void *data) s->transition_a_mul = (1.0f / s->transition_point); s->transition_b_mul = (1.0f / (1.0f - s->transition_point)); - obs_transition_enable_fixed(s->source, true, - (uint32_t)(s->duration_ns / 1000000)); + obs_transition_enable_fixed( + s->source, true, (uint32_t)(s->duration_ns / 1000000)); calldata_free(&cd); @@ -267,7 +267,8 @@ static void stinger_transition_stop(void *data) } static void stinger_enum_active_sources(void *data, - obs_source_enum_proc_t enum_callback, void *param) + obs_source_enum_proc_t enum_callback, + void *param) { struct stinger_info *s = data; if (s->media_source && s->transitioning) @@ -275,7 +276,8 @@ static void stinger_enum_active_sources(void *data, } static void stinger_enum_all_sources(void *data, - obs_source_enum_proc_t enum_callback, void *param) + obs_source_enum_proc_t enum_callback, + void *param) { struct stinger_info *s = data; if (s->media_source) @@ -286,17 +288,20 @@ static void stinger_enum_all_sources(void *data, "Video Files (*.mp4 *.ts *.mov *.wmv *.flv *.mkv *.avi *.gif *.webm);;" static bool transition_point_type_modified(obs_properties_t *ppts, - obs_property_t *p, obs_data_t *s) + obs_property_t *p, obs_data_t *s) { int64_t type = obs_data_get_int(s, "tp_type"); p = obs_properties_get(ppts, "transition_point"); - if (type == TIMING_TIME) - obs_property_set_description(p, - obs_module_text("TransitionPoint")); - else - obs_property_set_description(p, - obs_module_text("TransitionPointFrame")); + if (type == TIMING_TIME) { + obs_property_set_description( + p, obs_module_text("TransitionPoint")); + obs_property_int_set_suffix(p, " ms"); + } else { + obs_property_set_description( + p, obs_module_text("TransitionPointFrame")); + obs_property_int_set_suffix(p, ""); + } return true; } @@ -306,48 +311,45 @@ static obs_properties_t *stinger_properties(void *data) obs_properties_set_flags(ppts, OBS_PROPERTIES_DEFER_UPDATE); - obs_properties_add_path(ppts, "path", - obs_module_text("VideoFile"), - OBS_PATH_FILE, - FILE_FILTER, NULL); - obs_property_t *list = obs_properties_add_list(ppts, "tp_type", - obs_module_text("TransitionPointType"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_property_list_add_int(list, - obs_module_text("TransitionPointTypeTime"), - TIMING_TIME); - obs_property_list_add_int(list, - obs_module_text("TransitionPointTypeFrame"), - TIMING_FRAME); + obs_properties_add_path(ppts, "path", obs_module_text("VideoFile"), + OBS_PATH_FILE, FILE_FILTER, NULL); + obs_property_t *p = obs_properties_add_list( + ppts, "tp_type", obs_module_text("TransitionPointType"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(p, obs_module_text("TransitionPointTypeTime"), + TIMING_TIME); + obs_property_list_add_int( + p, obs_module_text("TransitionPointTypeFrame"), TIMING_FRAME); - obs_property_set_modified_callback(list, transition_point_type_modified); + obs_property_set_modified_callback(p, transition_point_type_modified); obs_properties_add_int(ppts, "transition_point", - obs_module_text("TransitionPoint"), - 0, 120000, 1); + obs_module_text("TransitionPoint"), 0, 120000, + 1); - obs_property_t *monitor_list = obs_properties_add_list(ppts, - "audio_monitoring", obs_module_text("AudioMonitoring"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_t *monitor_list = obs_properties_add_list( + ppts, "audio_monitoring", obs_module_text("AudioMonitoring"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); obs_property_list_add_int(monitor_list, - obs_module_text("AudioMonitoring.None"), - OBS_MONITORING_TYPE_NONE); + obs_module_text("AudioMonitoring.None"), + OBS_MONITORING_TYPE_NONE); + obs_property_list_add_int( + monitor_list, obs_module_text("AudioMonitoring.MonitorOnly"), + OBS_MONITORING_TYPE_MONITOR_ONLY); obs_property_list_add_int(monitor_list, - obs_module_text("AudioMonitoring.MonitorOnly"), - OBS_MONITORING_TYPE_MONITOR_ONLY); - obs_property_list_add_int(monitor_list, - obs_module_text("AudioMonitoring.Both"), - OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT); + obs_module_text("AudioMonitoring.Both"), + OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT); - obs_property_t *audio_fade_style = obs_properties_add_list(ppts, - "audio_fade_style", obs_module_text("AudioFadeStyle"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_t *audio_fade_style = obs_properties_add_list( + ppts, "audio_fade_style", obs_module_text("AudioFadeStyle"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_list_add_int( + audio_fade_style, + obs_module_text("AudioFadeStyle.FadeOutFadeIn"), + FADE_STYLE_FADE_OUT_FADE_IN); obs_property_list_add_int(audio_fade_style, - obs_module_text("AudioFadeStyle.FadeOutFadeIn"), - FADE_STYLE_FADE_OUT_FADE_IN); - obs_property_list_add_int(audio_fade_style, - obs_module_text("AudioFadeStyle.CrossFade"), - FADE_STYLE_CROSS_FADE); + obs_module_text("AudioFadeStyle.CrossFade"), + FADE_STYLE_CROSS_FADE); UNUSED_PARAMETER(data); return ppts; @@ -366,5 +368,5 @@ struct obs_source_info stinger_transition = { .enum_active_sources = stinger_enum_active_sources, .enum_all_sources = stinger_enum_all_sources, .transition_start = stinger_transition_start, - .transition_stop = stinger_transition_stop + .transition_stop = stinger_transition_stop, }; diff --git a/plugins/obs-transitions/transition-swipe.c b/plugins/obs-transitions/transition-swipe.c index 3bb5ce0..24b87c9 100644 --- a/plugins/obs-transitions/transition-swipe.c +++ b/plugins/obs-transitions/transition-swipe.c @@ -15,7 +15,7 @@ struct swipe_info { }; #define S_DIRECTION "direction" -#define S_SWIPE_IN "swipe_in" +#define S_SWIPE_IN "swipe_in" static const char *swipe_get_name(void *type_data) { @@ -76,7 +76,7 @@ static void swipe_update(void *data, obs_data_t *settings) } static void swipe_callback(void *data, gs_texture_t *a, gs_texture_t *b, - float t, uint32_t cx, uint32_t cy) + float t, uint32_t cx, uint32_t cy) { struct swipe_info *swipe = data; struct vec2 swipe_val = swipe->dir; @@ -116,12 +116,13 @@ static float mix_b(void *data, float t) } static bool swipe_audio_render(void *data, uint64_t *ts_out, - struct obs_source_audio_mix *audio, uint32_t mixers, - size_t channels, size_t sample_rate) + struct obs_source_audio_mix *audio, + uint32_t mixers, size_t channels, + size_t sample_rate) { struct swipe_info *swipe = data; - return obs_transition_audio_render(swipe->source, ts_out, - audio, mixers, channels, sample_rate, mix_a, mix_b); + return obs_transition_audio_render(swipe->source, ts_out, audio, mixers, + channels, sample_rate, mix_a, mix_b); } static obs_properties_t *swipe_properties(void *data) @@ -130,16 +131,16 @@ static obs_properties_t *swipe_properties(void *data) obs_property_t *p; p = obs_properties_add_list(ppts, S_DIRECTION, - obs_module_text("Direction"), OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_STRING); + obs_module_text("Direction"), + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, obs_module_text("Direction.Left"), - "left"); + "left"); obs_property_list_add_string(p, obs_module_text("Direction.Right"), - "right"); - obs_property_list_add_string(p, obs_module_text("Direction.Up"), - "up"); + "right"); + obs_property_list_add_string(p, obs_module_text("Direction.Up"), "up"); obs_property_list_add_string(p, obs_module_text("Direction.Down"), - "down"); + "down"); obs_properties_add_bool(ppts, S_SWIPE_IN, obs_module_text("SwipeIn")); @@ -156,5 +157,5 @@ struct obs_source_info swipe_transition = { .update = swipe_update, .video_render = swipe_video_render, .audio_render = swipe_audio_render, - .get_properties = swipe_properties + .get_properties = swipe_properties, }; diff --git a/plugins/obs-x264/data/locale/ar-SA.ini b/plugins/obs-x264/data/locale/ar-SA.ini index 188671d..ed1e8a2 100644 --- a/plugins/obs-x264/data/locale/ar-SA.ini +++ b/plugins/obs-x264/data/locale/ar-SA.ini @@ -1,6 +1,8 @@ Bitrate="معدل النقل" CustomBufsize="استخدام حجم Buffer مخصص" -BufferSize="حجم المخزن المؤقت" +BufferSize="حجم المخزون المؤقت" +RateControl="التحكم بمعدل النقل" +CRF="CRF" KeyframeIntervalSec="الفاصل الزمني لـKeyframe (ثانية, 0=تلقائي)" CPUPreset="إعداد مسبق لاستخدام CPU (الأعلى = CPU أقل)" Profile="الملف الشخصي" diff --git a/plugins/obs-x264/data/locale/de-DE.ini b/plugins/obs-x264/data/locale/de-DE.ini index 904eab9..69eee7b 100644 --- a/plugins/obs-x264/data/locale/de-DE.ini +++ b/plugins/obs-x264/data/locale/de-DE.ini @@ -1,13 +1,13 @@ Bitrate="Bitrate" -CustomBufsize="Verwende benutzerdefinierte Puffergröße" +CustomBufsize="Benutzerdefinierte Puffergröße verwenden" BufferSize="Puffergröße" RateControl="Qualitäts Regulierungsmethode" CRF="CRF" -KeyframeIntervalSec="Keyframeintervall (Sekunden, 0=auto)" -CPUPreset="Prozessorauslastung-Voreinstellung (höher = weniger CPU Auslastung)" +KeyframeIntervalSec="Keyframeintervall in Sek. (0 = automatisch)" +CPUPreset="Prozessorauslastungsvoreinstellung (höher = weniger CPU‐Auslastung)" Profile="Profil" Tune="Tune" None="(Nichts)" -EncoderOptions="x264-Optionen (durch Leerzeichen getrennt)" +EncoderOptions="x264‐Optionen (durch Leerzeichen getrennt)" VFR="Variable Framerate (VFR)" diff --git a/plugins/obs-x264/data/locale/gl-ES.ini b/plugins/obs-x264/data/locale/gl-ES.ini index 9b61f5d..c174f88 100644 --- a/plugins/obs-x264/data/locale/gl-ES.ini +++ b/plugins/obs-x264/data/locale/gl-ES.ini @@ -1,12 +1,13 @@ -Bitrate="Velocidade de bits" -CustomBufsize="Utilizar tamaño da caché personalizado" -BufferSize="Tamaño do búfer" +Bitrate="Taxa de bits" +CustomBufsize="Utilizar tamaño personalizado da memoria temporal" +BufferSize="Tamaño da memoria temporal" +RateControl="Control da taxa" CRF="CRF" -KeyframeIntervalSec="Intervalo de fotogramas chave (segundos, 0 = auto)" +KeyframeIntervalSec="Intervalo de fotogramas clave (segundos, 0=auto)" CPUPreset="Uso predefinido da CPU (superior = menos CPU)" Profile="Perfil" Tune="Sintonizar" None="(Ningún)" EncoderOptions="Opcións x264 (separadas por un espazo)" -VFR="Velocidade de fotogramas variable (VFR)" +VFR="Taxa variábel de fotogramas (VFR)" diff --git a/plugins/obs-x264/data/locale/sl-SI.ini b/plugins/obs-x264/data/locale/sl-SI.ini index 6fc4373..1fe470d 100644 --- a/plugins/obs-x264/data/locale/sl-SI.ini +++ b/plugins/obs-x264/data/locale/sl-SI.ini @@ -1,6 +1,13 @@ -Bitrate="Bitrate" -BufferSize="Velikost medpolnilnika" -KeyframeIntervalSec="Okvirni Interval(sekunde, 0=avtomatsko)" +Bitrate="Bitna hitrost" +CustomBufsize="Uporabi velikost medpomnilnika po meri" +BufferSize="Velikost medpomnilnika" +RateControl="Nadzor hitrosti" +CRF="CRF" +KeyframeIntervalSec="Razmik med ključnimi sličicami (s, 0=samodejno)" +CPUPreset="Prednastavitev porabe CPE-ja (višja = manj CPE-ja)" Profile="Profil" -Tune="Tune" +Tune="Uglasi" +None="(brez)" +EncoderOptions="Možnosti x264 (ločene s presledkom)" +VFR="Spremenljiva hitrost sličic" diff --git a/plugins/obs-x264/obs-x264.c b/plugins/obs-x264/obs-x264.c index 6e0d2e6..a5e318c 100644 --- a/plugins/obs-x264/obs-x264.c +++ b/plugins/obs-x264/obs-x264.c @@ -27,31 +27,31 @@ #include -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[x264 encoder: '%s'] " format, \ - obs_encoder_get_name(obsx264->encoder), ##__VA_ARGS__) + obs_encoder_get_name(obsx264->encoder), ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) -#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) -#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) //#define ENABLE_VFR /* ------------------------------------------------------------------------- */ struct obs_x264 { - obs_encoder_t *encoder; + obs_encoder_t *encoder; - x264_param_t params; - x264_t *context; + x264_param_t params; + x264_t *context; - DARRAY(uint8_t) packet_data; + DARRAY(uint8_t) packet_data; - uint8_t *extra_data; - uint8_t *sei; + uint8_t *extra_data; + uint8_t *sei; - size_t extra_data_size; - size_t sei_size; + size_t extra_data_size; + size_t sei_size; os_performance_token_t *performance_token; }; @@ -73,8 +73,8 @@ static void clear_data(struct obs_x264 *obsx264) bfree(obsx264->sei); bfree(obsx264->extra_data); - obsx264->context = NULL; - obsx264->sei = NULL; + obsx264->context = NULL; + obsx264->sei = NULL; obsx264->extra_data = NULL; } } @@ -93,20 +93,20 @@ static void obs_x264_destroy(void *data) static void obs_x264_defaults(obs_data_t *settings) { - obs_data_set_default_int (settings, "bitrate", 2500); - obs_data_set_default_bool (settings, "use_bufsize", false); - obs_data_set_default_int (settings, "buffer_size", 2500); - obs_data_set_default_int (settings, "keyint_sec", 0); - obs_data_set_default_int (settings, "crf", 23); + obs_data_set_default_int(settings, "bitrate", 2500); + obs_data_set_default_bool(settings, "use_bufsize", false); + obs_data_set_default_int(settings, "buffer_size", 2500); + obs_data_set_default_int(settings, "keyint_sec", 0); + obs_data_set_default_int(settings, "crf", 23); #ifdef ENABLE_VFR - obs_data_set_default_bool (settings, "vfr", false); + obs_data_set_default_bool(settings, "vfr", false); #endif - obs_data_set_default_string(settings, "rate_control","CBR"); + obs_data_set_default_string(settings, "rate_control", "CBR"); - obs_data_set_default_string(settings, "preset", "veryfast"); - obs_data_set_default_string(settings, "profile", ""); - obs_data_set_default_string(settings, "tune", ""); - obs_data_set_default_string(settings, "x264opts", ""); + obs_data_set_default_string(settings, "preset", "veryfast"); + obs_data_set_default_string(settings, "profile", ""); + obs_data_set_default_string(settings, "tune", ""); + obs_data_set_default_string(settings, "x264opts", ""); } static inline void add_strings(obs_property_t *list, const char *const *strings) @@ -118,20 +118,20 @@ static inline void add_strings(obs_property_t *list, const char *const *strings) } #define TEXT_RATE_CONTROL obs_module_text("RateControl") -#define TEXT_BITRATE obs_module_text("Bitrate") +#define TEXT_BITRATE obs_module_text("Bitrate") #define TEXT_CUSTOM_BUF obs_module_text("CustomBufsize") -#define TEXT_BUF_SIZE obs_module_text("BufferSize") -#define TEXT_VFR obs_module_text("VFR") -#define TEXT_CRF obs_module_text("CRF") +#define TEXT_BUF_SIZE obs_module_text("BufferSize") +#define TEXT_VFR obs_module_text("VFR") +#define TEXT_CRF obs_module_text("CRF") #define TEXT_KEYINT_SEC obs_module_text("KeyframeIntervalSec") -#define TEXT_PRESET obs_module_text("CPUPreset") -#define TEXT_PROFILE obs_module_text("Profile") -#define TEXT_TUNE obs_module_text("Tune") -#define TEXT_NONE obs_module_text("None") -#define TEXT_X264_OPTS obs_module_text("EncoderOptions") +#define TEXT_PRESET obs_module_text("CPUPreset") +#define TEXT_PROFILE obs_module_text("Profile") +#define TEXT_TUNE obs_module_text("Tune") +#define TEXT_NONE obs_module_text("None") +#define TEXT_X264_OPTS obs_module_text("EncoderOptions") static bool use_bufsize_modified(obs_properties_t *ppts, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { bool use_bufsize = obs_data_get_bool(settings, "use_bufsize"); const char *rc = obs_data_get_string(settings, "rate_control"); @@ -143,7 +143,7 @@ static bool use_bufsize_modified(obs_properties_t *ppts, obs_property_t *p, } static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { const char *rc = obs_data_get_string(settings, "rate_control"); bool use_bufsize = obs_data_get_bool(settings, "use_bufsize"); @@ -171,7 +171,8 @@ static obs_properties_t *obs_x264_props(void *unused) obs_property_t *p; list = obs_properties_add_list(props, "rate_control", TEXT_RATE_CONTROL, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(list, "CBR", "CBR"); obs_property_list_add_string(list, "ABR", "ABR"); obs_property_list_add_string(list, "VBR", "VBR"); @@ -179,32 +180,35 @@ static obs_properties_t *obs_x264_props(void *unused) obs_property_set_modified_callback(list, rate_control_modified); - p = obs_properties_add_int(props, "bitrate", - TEXT_BITRATE, 50, 10000000, 50); + p = obs_properties_add_int(props, "bitrate", TEXT_BITRATE, 50, 10000000, + 50); obs_property_int_set_suffix(p, " Kbps"); p = obs_properties_add_bool(props, "use_bufsize", TEXT_CUSTOM_BUF); obs_property_set_modified_callback(p, use_bufsize_modified); - obs_properties_add_int(props, "buffer_size", TEXT_BUF_SIZE, 0, - 10000000, 1); + obs_properties_add_int(props, "buffer_size", TEXT_BUF_SIZE, 0, 10000000, + 1); obs_properties_add_int(props, "crf", TEXT_CRF, 0, 51, 1); obs_properties_add_int(props, "keyint_sec", TEXT_KEYINT_SEC, 0, 20, 1); list = obs_properties_add_list(props, "preset", TEXT_PRESET, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); add_strings(list, x264_preset_names); list = obs_properties_add_list(props, "profile", TEXT_PROFILE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(list, TEXT_NONE, ""); obs_property_list_add_string(list, "baseline", "baseline"); obs_property_list_add_string(list, "main", "main"); obs_property_list_add_string(list, "high", "high"); list = obs_properties_add_list(props, "tune", TEXT_TUNE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(list, TEXT_NONE, ""); add_strings(list, x264_tune_names); @@ -213,7 +217,7 @@ static obs_properties_t *obs_x264_props(void *unused) #endif obs_properties_add_text(props, "x264opts", TEXT_X264_OPTS, - OBS_TEXT_DEFAULT); + OBS_TEXT_DEFAULT); return props; } @@ -226,17 +230,16 @@ static bool getparam(const char *param, char **name, const char **value) return false; assign = strchr(param, '='); - if (!assign || !*assign || !*(assign+1)) + if (!assign || !*assign || !*(assign + 1)) return false; - *name = bstrdup_n(param, assign-param); - *value = assign+1; + *name = bstrdup_n(param, assign - param); + *value = assign + 1; return true; } -static const char *validate(struct obs_x264 *obsx264, - const char *val, const char *name, - const char *const *list) +static const char *validate(struct obs_x264 *obsx264, const char *val, + const char *name, const char *const *list) { if (!val || !*val) return val; @@ -253,31 +256,31 @@ static const char *validate(struct obs_x264 *obsx264, } static void override_base_param(struct obs_x264 *obsx264, const char *param, - char **preset, char **profile, char **tune) + char **preset, char **profile, char **tune) { - char *name; + char *name; const char *val; if (getparam(param, &name, &val)) { if (astrcmpi(name, "preset") == 0) { - const char *valid_name = validate(obsx264, val, - "preset", x264_preset_names); + const char *valid_name = validate( + obsx264, val, "preset", x264_preset_names); if (valid_name) { bfree(*preset); *preset = bstrdup(val); } } else if (astrcmpi(name, "profile") == 0) { - const char *valid_name = validate(obsx264, val, - "profile", x264_profile_names); + const char *valid_name = validate( + obsx264, val, "profile", x264_profile_names); if (valid_name) { bfree(*profile); *profile = bstrdup(val); } } else if (astrcmpi(name, "tune") == 0) { - const char *valid_name = validate(obsx264, val, - "tune", x264_tune_names); + const char *valid_name = + validate(obsx264, val, "tune", x264_tune_names); if (valid_name) { bfree(*tune); *tune = bstrdup(val); @@ -289,29 +292,28 @@ static void override_base_param(struct obs_x264 *obsx264, const char *param, } static inline void override_base_params(struct obs_x264 *obsx264, char **params, - char **preset, char **profile, char **tune) + char **preset, char **profile, + char **tune) { while (*params) - override_base_param(obsx264, *(params++), - preset, profile, tune); + override_base_param(obsx264, *(params++), preset, profile, + tune); } #define OPENCL_ALIAS "opencl_is_experimental_and_potentially_unstable" static inline void set_param(struct obs_x264 *obsx264, const char *param) { - char *name; + char *name; const char *val; if (getparam(param, &name, &val)) { - if (strcmp(name, "preset") != 0 && - strcmp(name, "profile") != 0 && - strcmp(name, "tune") != 0 && - strcmp(name, "fps") != 0 && + if (strcmp(name, "preset") != 0 && + strcmp(name, "profile") != 0 && strcmp(name, "tune") != 0 && + strcmp(name, "fps") != 0 && strcmp(name, "force-cfr") != 0 && - strcmp(name, "width") != 0 && - strcmp(name, "height") != 0 && - strcmp(name, "opencl") != 0) { + strcmp(name, "width") != 0 && strcmp(name, "height") != 0 && + strcmp(name, "opencl") != 0) { if (strcmp(name, OPENCL_ALIAS) == 0) strcpy(name, "opencl"); if (x264_param_parse(&obsx264->params, name, val) != 0) @@ -323,7 +325,7 @@ static inline void set_param(struct obs_x264 *obsx264, const char *param) } static inline void apply_x264_profile(struct obs_x264 *obsx264, - const char *profile) + const char *profile) { if (!obsx264->context && profile && *profile) { int ret = x264_param_apply_profile(&obsx264->params, profile); @@ -333,19 +335,19 @@ static inline void apply_x264_profile(struct obs_x264 *obsx264, } static inline const char *validate_preset(struct obs_x264 *obsx264, - const char *preset) + const char *preset) { - const char *new_preset = validate(obsx264, preset, "preset", - x264_preset_names); + const char *new_preset = + validate(obsx264, preset, "preset", x264_preset_names); return new_preset ? new_preset : "veryfast"; } -static bool reset_x264_params(struct obs_x264 *obsx264, - const char *preset, const char *tune) +static bool reset_x264_params(struct obs_x264 *obsx264, const char *preset, + const char *tune) { - int ret = x264_param_default_preset(&obsx264->params, - validate_preset(obsx264, preset), - validate(obsx264, tune, "tune", x264_tune_names)); + int ret = x264_param_default_preset( + &obsx264->params, validate_preset(obsx264, preset), + validate(obsx264, tune, "tune", x264_tune_names)); return ret == 0; } @@ -373,7 +375,7 @@ static inline const char *get_x264_colorspace_name(enum video_colorspace cs) } static inline int get_x264_cs_val(enum video_colorspace cs, - const char *const names[]) + const char *const names[]) { const char *name = get_x264_colorspace_name(cs); int idx = 0; @@ -395,7 +397,7 @@ enum rate_control { }; static void update_params(struct obs_x264 *obsx264, obs_data_t *settings, - char **params) + char **params, bool update) { video_t *video = obs_encoder_video(obsx264->encoder); const struct video_output_info *voi = video_output_get_info(video); @@ -407,21 +409,22 @@ static void update_params(struct obs_x264 *obsx264, obs_data_t *settings, obs_x264_video_info(obsx264, &info); - const char *rate_control = obs_data_get_string(settings, "rate_control"); + const char *rate_control = + obs_data_get_string(settings, "rate_control"); - int bitrate = (int)obs_data_get_int(settings, "bitrate"); - int buffer_size = (int)obs_data_get_int(settings, "buffer_size"); - int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec"); - int crf = (int)obs_data_get_int(settings, "crf"); - int width = (int)obs_encoder_get_width(obsx264->encoder); - int height = (int)obs_encoder_get_height(obsx264->encoder); - int bf = (int)obs_data_get_int(settings, "bf"); + int bitrate = (int)obs_data_get_int(settings, "bitrate"); + int buffer_size = (int)obs_data_get_int(settings, "buffer_size"); + int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec"); + int crf = (int)obs_data_get_int(settings, "crf"); + int width = (int)obs_encoder_get_width(obsx264->encoder); + int height = (int)obs_encoder_get_height(obsx264->encoder); + int bf = (int)obs_data_get_int(settings, "bf"); bool use_bufsize = obs_data_get_bool(settings, "use_bufsize"); - bool cbr_override= obs_data_get_bool(settings, "cbr"); + bool cbr_override = obs_data_get_bool(settings, "cbr"); enum rate_control rc; #ifdef ENABLE_VFR - bool vfr = obs_data_get_bool(settings, "vfr"); + bool vfr = obs_data_get_bool(settings, "vfr"); #endif /* XXX: "cbr" setting has been deprecated */ @@ -459,20 +462,20 @@ static void update_params(struct obs_x264 *obsx264, obs_data_t *settings, buffer_size = bitrate; #ifdef ENABLE_VFR - obsx264->params.b_vfr_input = vfr; + obsx264->params.b_vfr_input = vfr; #else - obsx264->params.b_vfr_input = false; + obsx264->params.b_vfr_input = false; #endif obsx264->params.rc.i_vbv_max_bitrate = bitrate; obsx264->params.rc.i_vbv_buffer_size = buffer_size; - obsx264->params.rc.i_bitrate = bitrate; - obsx264->params.i_width = width; - obsx264->params.i_height = height; - obsx264->params.i_fps_num = voi->fps_num; - obsx264->params.i_fps_den = voi->fps_den; - obsx264->params.pf_log = log_x264; - obsx264->params.p_log_private = obsx264; - obsx264->params.i_log_level = X264_LOG_WARNING; + obsx264->params.rc.i_bitrate = bitrate; + obsx264->params.i_width = width; + obsx264->params.i_height = height; + obsx264->params.i_fps_num = voi->fps_num; + obsx264->params.i_fps_den = voi->fps_den; + obsx264->params.pf_log = log_x264; + obsx264->params.p_log_private = obsx264; + obsx264->params.i_log_level = X264_LOG_WARNING; if (obs_data_has_user_value(settings, "bf")) obsx264->params.i_bframe = bf; @@ -483,13 +486,12 @@ static void update_params(struct obs_x264 *obsx264, obs_data_t *settings, get_x264_cs_val(info.colorspace, x264_colmatrix_names); obsx264->params.vui.i_colorprim = get_x264_cs_val(info.colorspace, x264_colorprim_names); - obsx264->params.vui.b_fullrange = - info.range == VIDEO_RANGE_FULL; + obsx264->params.vui.b_fullrange = info.range == VIDEO_RANGE_FULL; /* use the new filler method for CBR to allow real-time adjusting of * the bitrate */ if (rc == RATE_CONTROL_CBR || rc == RATE_CONTROL_ABR) { - obsx264->params.rc.i_rc_method = X264_RC_ABR; + obsx264->params.rc.i_rc_method = X264_RC_ABR; if (rc == RATE_CONTROL_CBR) { #if X264_BUILD >= 139 @@ -499,7 +501,7 @@ static void update_params(struct obs_x264 *obsx264, obs_data_t *settings, #endif } } else { - obsx264->params.rc.i_rc_method = X264_RC_CRF; + obsx264->params.rc.i_rc_method = X264_RC_CRF; } obsx264->params.rc.f_rf_constant = (float)crf; @@ -516,30 +518,30 @@ static void update_params(struct obs_x264 *obsx264, obs_data_t *settings, while (*params) set_param(obsx264, *(params++)); - info("settings:\n" - "\trate_control: %s\n" - "\tbitrate: %d\n" - "\tbuffer size: %d\n" - "\tcrf: %d\n" - "\tfps_num: %d\n" - "\tfps_den: %d\n" - "\twidth: %d\n" - "\theight: %d\n" - "\tkeyint: %d\n", - rate_control, - obsx264->params.rc.i_vbv_max_bitrate, - obsx264->params.rc.i_vbv_buffer_size, - (int)obsx264->params.rc.f_rf_constant, - voi->fps_num, voi->fps_den, - width, height, - obsx264->params.i_keyint_max); + if (!update) { + info("settings:\n" + "\trate_control: %s\n" + "\tbitrate: %d\n" + "\tbuffer size: %d\n" + "\tcrf: %d\n" + "\tfps_num: %d\n" + "\tfps_den: %d\n" + "\twidth: %d\n" + "\theight: %d\n" + "\tkeyint: %d\n", + rate_control, obsx264->params.rc.i_vbv_max_bitrate, + obsx264->params.rc.i_vbv_buffer_size, + (int)obsx264->params.rc.f_rf_constant, voi->fps_num, + voi->fps_den, width, height, obsx264->params.i_keyint_max); + } } -static bool update_settings(struct obs_x264 *obsx264, obs_data_t *settings) +static bool update_settings(struct obs_x264 *obsx264, obs_data_t *settings, + bool update) { - char *preset = bstrdup(obs_data_get_string(settings, "preset")); - char *profile = bstrdup(obs_data_get_string(settings, "profile")); - char *tune = bstrdup(obs_data_get_string(settings, "tune")); + char *preset = bstrdup(obs_data_get_string(settings, "preset")); + char *profile = bstrdup(obs_data_get_string(settings, "profile")); + char *tune = bstrdup(obs_data_get_string(settings, "tune")); const char *opts = obs_data_get_string(settings, "x264opts"); char **paramlist; @@ -547,22 +549,26 @@ static bool update_settings(struct obs_x264 *obsx264, obs_data_t *settings) paramlist = strlist_split(opts, ' ', false); - blog(LOG_INFO, "---------------------------------"); + if (!update) + blog(LOG_INFO, "---------------------------------"); if (!obsx264->context) { - override_base_params(obsx264, paramlist, - &preset, &profile, &tune); + override_base_params(obsx264, paramlist, &preset, &profile, + &tune); - if (preset && *preset) info("preset: %s", preset); - if (profile && *profile) info("profile: %s", profile); - if (tune && *tune) info("tune: %s", tune); + if (preset && *preset) + info("preset: %s", preset); + if (profile && *profile) + info("profile: %s", profile); + if (tune && *tune) + info("tune: %s", tune); success = reset_x264_params(obsx264, preset, tune); } if (success) { - update_params(obsx264, settings, paramlist); - if (opts && *opts) + update_params(obsx264, settings, paramlist, update); + if (opts && *opts && !update) info("custom settings: %s", opts); if (!obsx264->context) @@ -582,7 +588,7 @@ static bool update_settings(struct obs_x264 *obsx264, obs_data_t *settings) static bool obs_x264_update(void *data, obs_data_t *settings) { struct obs_x264 *obsx264 = data; - bool success = update_settings(obsx264, settings); + bool success = update_settings(obsx264, settings, true); int ret; if (success) { @@ -597,8 +603,8 @@ static bool obs_x264_update(void *data, obs_data_t *settings) static void load_headers(struct obs_x264 *obsx264) { - x264_nal_t *nals; - int nal_count; + x264_nal_t *nals; + int nal_count; DARRAY(uint8_t) header; DARRAY(uint8_t) sei; @@ -608,19 +614,19 @@ static void load_headers(struct obs_x264 *obsx264) x264_encoder_headers(obsx264->context, &nals, &nal_count); for (int i = 0; i < nal_count; i++) { - x264_nal_t *nal = nals+i; + x264_nal_t *nal = nals + i; if (nal->i_type == NAL_SEI) da_push_back_array(sei, nal->p_payload, nal->i_payload); else da_push_back_array(header, nal->p_payload, - nal->i_payload); + nal->i_payload); } - obsx264->extra_data = header.array; + obsx264->extra_data = header.array; obsx264->extra_data_size = header.num; - obsx264->sei = sei.array; - obsx264->sei_size = sei.num; + obsx264->sei = sei.array; + obsx264->sei_size = sei.num; } static void *obs_x264_create(obs_data_t *settings, obs_encoder_t *encoder) @@ -628,7 +634,7 @@ static void *obs_x264_create(obs_data_t *settings, obs_encoder_t *encoder) struct obs_x264 *obsx264 = bzalloc(sizeof(struct obs_x264)); obsx264->encoder = encoder; - if (update_settings(obsx264, settings)) { + if (update_settings(obsx264, settings, false)) { obsx264->context = x264_encoder_open(&obsx264->params); if (obsx264->context == NULL) @@ -651,29 +657,30 @@ static void *obs_x264_create(obs_data_t *settings, obs_encoder_t *encoder) } static void parse_packet(struct obs_x264 *obsx264, - struct encoder_packet *packet, x264_nal_t *nals, - int nal_count, x264_picture_t *pic_out) + struct encoder_packet *packet, x264_nal_t *nals, + int nal_count, x264_picture_t *pic_out) { - if (!nal_count) return; + if (!nal_count) + return; da_resize(obsx264->packet_data, 0); for (int i = 0; i < nal_count; i++) { - x264_nal_t *nal = nals+i; + x264_nal_t *nal = nals + i; da_push_back_array(obsx264->packet_data, nal->p_payload, - nal->i_payload); + nal->i_payload); } - packet->data = obsx264->packet_data.array; - packet->size = obsx264->packet_data.num; - packet->type = OBS_ENCODER_VIDEO; - packet->pts = pic_out->i_pts; - packet->dts = pic_out->i_dts; - packet->keyframe = pic_out->b_keyframe != 0; + packet->data = obsx264->packet_data.array; + packet->size = obsx264->packet_data.num; + packet->type = OBS_ENCODER_VIDEO; + packet->pts = pic_out->i_pts; + packet->dts = pic_out->i_dts; + packet->keyframe = pic_out->b_keyframe != 0; } static inline void init_pic_data(struct obs_x264 *obsx264, x264_picture_t *pic, - struct encoder_frame *frame) + struct encoder_frame *frame) { x264_picture_init(pic); @@ -689,18 +696,19 @@ static inline void init_pic_data(struct obs_x264 *obsx264, x264_picture_t *pic, for (int i = 0; i < pic->img.i_plane; i++) { pic->img.i_stride[i] = (int)frame->linesize[i]; - pic->img.plane[i] = frame->data[i]; + pic->img.plane[i] = frame->data[i]; } } static bool obs_x264_encode(void *data, struct encoder_frame *frame, - struct encoder_packet *packet, bool *received_packet) + struct encoder_packet *packet, + bool *received_packet) { struct obs_x264 *obsx264 = data; - x264_nal_t *nals; - int nal_count; - int ret; - x264_picture_t pic, pic_out; + x264_nal_t *nals; + int nal_count; + int ret; + x264_picture_t pic, pic_out; if (!frame || !packet || !received_packet) return false; @@ -709,7 +717,7 @@ static bool obs_x264_encode(void *data, struct encoder_frame *frame, init_pic_data(obsx264, &pic, frame); ret = x264_encoder_encode(obsx264->context, &nals, &nal_count, - (frame ? &pic : NULL), &pic_out); + (frame ? &pic : NULL), &pic_out); if (ret < 0) { warn("encode failed"); return false; @@ -729,7 +737,7 @@ static bool obs_x264_extra_data(void *data, uint8_t **extra_data, size_t *size) return false; *extra_data = obsx264->extra_data; - *size = obsx264->extra_data_size; + *size = obsx264->extra_data_size; return true; } @@ -740,15 +748,14 @@ static bool obs_x264_sei(void *data, uint8_t **sei, size_t *size) if (!obsx264->context) return false; - *sei = obsx264->sei; + *sei = obsx264->sei; *size = obsx264->sei_size; return true; } static inline bool valid_format(enum video_format format) { - return format == VIDEO_FORMAT_I420 || - format == VIDEO_FORMAT_NV12 || + return format == VIDEO_FORMAT_I420 || format == VIDEO_FORMAT_NV12 || format == VIDEO_FORMAT_I444; } @@ -760,25 +767,26 @@ static void obs_x264_video_info(void *data, struct video_scale_info *info) pref_format = obs_encoder_get_preferred_video_format(obsx264->encoder); if (!valid_format(pref_format)) { - pref_format = valid_format(info->format) ? - info->format : VIDEO_FORMAT_NV12; + pref_format = valid_format(info->format) ? info->format + : VIDEO_FORMAT_NV12; } info->format = pref_format; } struct obs_encoder_info obs_x264_encoder = { - .id = "obs_x264", - .type = OBS_ENCODER_VIDEO, - .codec = "h264", - .get_name = obs_x264_getname, - .create = obs_x264_create, - .destroy = obs_x264_destroy, - .encode = obs_x264_encode, - .update = obs_x264_update, + .id = "obs_x264", + .type = OBS_ENCODER_VIDEO, + .codec = "h264", + .get_name = obs_x264_getname, + .create = obs_x264_create, + .destroy = obs_x264_destroy, + .encode = obs_x264_encode, + .update = obs_x264_update, .get_properties = obs_x264_props, - .get_defaults = obs_x264_defaults, + .get_defaults = obs_x264_defaults, .get_extra_data = obs_x264_extra_data, - .get_sei_data = obs_x264_sei, - .get_video_info = obs_x264_video_info + .get_sei_data = obs_x264_sei, + .get_video_info = obs_x264_video_info, + .caps = OBS_ENCODER_CAP_DYN_BITRATE, }; diff --git a/plugins/rtmp-services/data/locale/bg-BG.ini b/plugins/rtmp-services/data/locale/bg-BG.ini new file mode 100644 index 0000000..1a80ffd --- /dev/null +++ b/plugins/rtmp-services/data/locale/bg-BG.ini @@ -0,0 +1,9 @@ +Service="Услуга" +Server="Сървър" +Server.Auto="Автоматично (препоръчва се)" +StreamKey="Ключ за поточно излъчване" +UseAuth="Използване на удостоверение" +Username="Потребителско име" +Password="Парола" +ShowAll="Показване на всички услуги" + diff --git a/plugins/rtmp-services/data/locale/de-DE.ini b/plugins/rtmp-services/data/locale/de-DE.ini index cdfbf98..fda26c4 100644 --- a/plugins/rtmp-services/data/locale/de-DE.ini +++ b/plugins/rtmp-services/data/locale/de-DE.ini @@ -1,4 +1,4 @@ -StreamingServices="Streaming-Plattformen" +StreamingServices="Streaming‐Plattformen" CustomStreamingServer="Benutzerdefinierter Streamingserver" Service="Plattform" Server="Server" diff --git a/plugins/rtmp-services/data/locale/fa-IR.ini b/plugins/rtmp-services/data/locale/fa-IR.ini new file mode 100644 index 0000000..3c311b3 --- /dev/null +++ b/plugins/rtmp-services/data/locale/fa-IR.ini @@ -0,0 +1,11 @@ +StreamingServices="سرویس پخش زنده" +CustomStreamingServer="سرویس پخش زنده جریانی" +Service="سرویس" +Server="سرور" +Server.Auto="خودکار (پیشنهاد شده)" +StreamKey="کلید پخش زنده" +UseAuth="استفاده از تایید اعتبار" +Username="نام کاربری" +Password="رمزعبور" +ShowAll="همه سرویس ها را نمایش بده" + diff --git a/plugins/rtmp-services/data/locale/gl-ES.ini b/plugins/rtmp-services/data/locale/gl-ES.ini index 3b0a3b9..307059c 100644 --- a/plugins/rtmp-services/data/locale/gl-ES.ini +++ b/plugins/rtmp-services/data/locale/gl-ES.ini @@ -1,8 +1,9 @@ -StreamingServices="Servizos de retransmisión" -CustomStreamingServer="Presonalizar o servidor de retranmisión" +StreamingServices="Servizos de emisións" +CustomStreamingServer="Personalizar o servidor de emisións" Service="Servizo" Server="Servidor" -StreamKey="Chave de retransmisión" +Server.Auto="Automático (recomendado)" +StreamKey="Clave da emisión" UseAuth="Usar a autenticación" Username="Nome de usuario" Password="Contrasinal" diff --git a/plugins/rtmp-services/data/locale/sl-SI.ini b/plugins/rtmp-services/data/locale/sl-SI.ini index 840fae4..18f350d 100644 --- a/plugins/rtmp-services/data/locale/sl-SI.ini +++ b/plugins/rtmp-services/data/locale/sl-SI.ini @@ -1,6 +1,11 @@ -StreamingServices="Storitev oddajanja" -CustomStreamingServer="Streming Server po želji" +StreamingServices="Storitve pretakanja" +CustomStreamingServer="Strežnik pretakanja po meri" Service="Storitev" Server="Strežnik" +Server.Auto="Samodejno (priporočeno)" StreamKey="Ključ pretoka" +UseAuth="Uporabi overitev" +Username="Uporabniško ime" +Password="Geslo" +ShowAll="Prikaži vse storitve" diff --git a/plugins/rtmp-services/data/package.json b/plugins/rtmp-services/data/package.json index f514d10..56470f7 100644 --- a/plugins/rtmp-services/data/package.json +++ b/plugins/rtmp-services/data/package.json @@ -1,10 +1,10 @@ { "url": "https://obsproject.com/obs2_update/rtmp-services", - "version": 107, + "version": 112, "files": [ { "name": "services.json", - "version": 107 + "version": 112 } ] } diff --git a/plugins/rtmp-services/data/services.json b/plugins/rtmp-services/data/services.json index 9276a35..17587f9 100644 --- a/plugins/rtmp-services/data/services.json +++ b/plugins/rtmp-services/data/services.json @@ -69,6 +69,10 @@ "name": "EU: Milan, Italy", "url": "rtmp://live-mil.twitch.tv/app" }, + { + "name": "EU: Norway, Oslo", + "url": "rtmp://live-osl.twitch.tv/app" + }, { "name": "EU: Paris, FR", "url": "rtmp://live-cdg.twitch.tv/app" @@ -214,7 +218,6 @@ }, { "name": "Smashcast", - "common": true, "servers": [ { "name": "Default", @@ -461,21 +464,6 @@ "max audio bitrate": 160 } }, - { - "name": "GamePlank", - "servers": [ - { - "name": "Primary", - "url": "rtmp://live.gameplank.tv/go" - } - ], - "recommended": { - "keyint": 1, - "profile": "main", - "max video bitrate": 2500, - "max audio bitrate": 160 - } - }, { "name": "Web.TV", "servers": [ @@ -573,21 +561,6 @@ } ] }, - { - "name": "DJlive.pl", - "servers": [ - { - "name": "Default", - "url": "rtmp://live.djlive.pl/live" - } - ], - "recommended": { - "keyint": 1, - "profile": "high", - "max video bitrate": 1300, - "max audio bitrate": 320 - } - }, { "name": "Facebook Live", "common": true, @@ -617,63 +590,83 @@ }, { "name": "EU-West (London, GB)", - "url": "rtmp://eu-london.restream.io/live" + "url": "rtmp://london.restream.io/live" }, { "name": "EU-West (Amsterdam, NL)", - "url": "rtmp://eu-ams.restream.io/live" + "url": "rtmp://amsterdam.restream.io/live" }, { "name": "EU-West (Luxembourg)", - "url": "rtmp://eu-luxembourg.restream.io/live" + "url": "rtmp://luxembourg.restream.io/live" }, { "name": "EU-West (Paris, FR)", - "url": "rtmp://eu-paris.restream.io/live" + "url": "rtmp://paris.restream.io/live" + }, + { + "name": "EU-West (Milan, IT)", + "url": "rtmp://milan.restream.io/live" }, { "name": "EU-Central (Frankfurt, DE)", - "url": "rtmp://eu-central.restream.io/live" + "url": "rtmp://frankfurt.restream.io/live" }, { "name": "EU-East (Falkenstein, DE)", - "url": "rtmp://eu-east.restream.io/live" + "url": "rtmp://falkenstein.restream.io/live" }, { "name": "EU-South (Madrid, Spain)", - "url": "rtmp://eu-madrid.restream.io/live" + "url": "rtmp://madrid.restream.io/live" }, { "name": "Russia (Moscow)", - "url": "rtmp://ru.restream.io/live" + "url": "rtmp://moscow.restream.io/live" + }, + { + "name": "Turkey (Istanbul)", + "url": "rtmp://istanbul.restream.io/live" + }, + { + "name": "Israel (Tel Aviv)", + "url": "rtmp://telaviv.restream.io/live" }, { "name": "US-West (Seattle, WA)", - "url": "rtmp://us-seattle.restream.io/live" + "url": "rtmp://seattle.restream.io/live" }, { "name": "US-West (San Jose, CA)", - "url": "rtmp://us-west.restream.io/live" + "url": "rtmp://sanjose.restream.io/live" }, { "name": "US-Central (Dallas, TX)", - "url": "rtmp://us-central.restream.io/live" + "url": "rtmp://dallas.restream.io/live" }, { "name": "US-East (Washington, DC)", - "url": "rtmp://us-east.restream.io/live" + "url": "rtmp://washington.restream.io/live" }, { "name": "US-East (Miami, FL)", - "url": "rtmp://us-miami.restream.io/live" + "url": "rtmp://miami.restream.io/live" + }, + { + "name": "US-East (Chicago, IL)", + "url": "rtmp://chicago.restream.io/live" }, { "name": "NA-East (Toronto, Canada)", - "url": "rtmp://na-toronto.restream.io/live" + "url": "rtmp://toronto.restream.io/live" }, { "name": "SA (Saint Paul, Brazil)", - "url": "rtmp://sa.restream.io/live" + "url": "rtmp://saopaulo.restream.io/live" + }, + { + "name": "India (Bangalore)", + "url": "rtmp://bangalore.restream.io/live" }, { "name": "Asia (Singapore)", @@ -687,13 +680,9 @@ "name": "Asia (Tokyo, Japan)", "url": "rtmp://tokyo.restream.io/live" }, - { - "name": "India (Bangalore)", - "url": "rtmp://india.restream.io/live" - }, { "name": "Australia (Sydney)", - "url": "rtmp://au.restream.io/live" + "url": "rtmp://sydney.restream.io/live" } ], "recommended": { @@ -710,63 +699,83 @@ }, { "name": "EU-West (London, GB)", - "url": "eu-london.restream.io" + "url": "london.restream.io" }, { "name": "EU-West (Amsterdam, NL)", - "url": "eu-ams.restream.io" + "url": "amsterdam.restream.io" }, { "name": "EU-West (Luxembourg)", - "url": "eu-luxembourg.restream.io" + "url": "luxembourg.restream.io" }, { "name": "EU-West (Paris, FR)", - "url": "eu-paris.restream.io" + "url": "paris.restream.io" + }, + { + "name": "EU-West (Milan, IT)", + "url": "milan.restream.io" }, { "name": "EU-Central (Frankfurt, DE)", - "url": "eu-central.restream.io" + "url": "frankfurt.restream.io" }, { "name": "EU-East (Falkenstein, DE)", - "url": "eu-east.restream.io" + "url": "falkenstein.restream.io" }, { "name": "EU-South (Madrid, Spain)", - "url": "eu-madrid.restream.io" + "url": "madrid.restream.io" }, { "name": "Russia (Moscow)", - "url": "ru.restream.io" + "url": "moscow.restream.io" + }, + { + "name": "Turkey (Istanbul)", + "url": "istanbul.restream.io" + }, + { + "name": "Israel (Tel Aviv)", + "url": "telaviv.restream.io" }, { "name": "US-West (Seattle, WA)", - "url": "us-seattle.restream.io" + "url": "seattle.restream.io" }, { "name": "US-West (San Jose, CA)", - "url": "us-west.restream.io" + "url": "sanjose.restream.io" }, { "name": "US-Central (Dallas, TX)", - "url": "us-central.restream.io" + "url": "dallas.restream.io" }, { "name": "US-East (Washington, DC)", - "url": "us-east.restream.io" + "url": "washington.restream.io" }, { "name": "US-East (Miami, FL)", - "url": "us-miami.restream.io" + "url": "miami.restream.io" + }, + { + "name": "US-East (Chicago, IL)", + "url": "chicago.restream.io" }, { "name": "NA-East (Toronto, Canada)", - "url": "na-toronto.restream.io" + "url": "toronto.restream.io" }, { "name": "SA (Saint Paul, Brazil)", - "url": "sa.restream.io" + "url": "saopaulo.restream.io" + }, + { + "name": "India (Bangalore)", + "url": "bangalore.restream.io" }, { "name": "Asia (Singapore)", @@ -782,7 +791,7 @@ }, { "name": "Australia (Sydney)", - "url": "au.restream.io" + "url": "sydney.restream.io" } ], "recommended": { @@ -798,8 +807,12 @@ "name": "GameTips.TV", "servers": [ { - "name": "Server Iran", + "name": "Iran - Rasht", "url": "rtmp://rtmp.cdn.server1.gametips.tv:1935/hls" + }, + { + "name": "Germany - Falkenstein/Vogtland", + "url": "rtmp://rtmp.cdn.server2.gametips.tv:1935/hls" } ] }, @@ -1083,6 +1096,23 @@ } ] }, + { + "name": "Stripchat", + "servers": [ + { + "name": "Auto", + "url": "rtmp://s-sd.stripcdn.com/ext" + } + ], + "recommended": { + "keyint": 2, + "profile": "main", + "bframes": 0, + "max video bitrate": 6000, + "max audio bitrate": 128, + "x264opts": "tune=zerolatency" + } + }, { "name": "Chaturbate", "servers": [ @@ -1230,10 +1260,6 @@ { "name": "Australia East", "url": "rtmp://ingest-au-east.a.switchboard.zone/live" - }, - { - "name": "Asia Central", - "url": "rtmp://ingest-as-central.a.switchboard.zone/live" } ] }, @@ -1253,38 +1279,6 @@ "max audio bitrate": 160 } }, - { - "name": "Stream.me", - "common": false, - "servers": [ - { - "name": "US, Central", - "url": "rtmp://uc-origin.stream.me/origin" - }, - { - "name": "US, East", - "url": "rtmp://ue-origin.stream.me/origin" - }, - { - "name": "US, West", - "url": "rtmp://uw-origin.stream.me/origin" - }, - { - "name": "Europe, West", - "url": "rtmp://ew-origin.stream.me/origin" - }, - { - "name": "Asia, East", - "url": "rtmp://ae-origin.stream.me/origin" - } - ], - "recommended": { - "keyint": 2, - "profile": "main", - "max video bitrate": 20000, - "max audio bitrate": 192 - } - }, { "name": "Eventials", "servers": [ @@ -1505,6 +1499,66 @@ "bframes": 0, "x264opts": "tune=zerolatency" } + }, + { + "name": "Steam", + "common": false, + "servers": [ + { + "name": "Chicago, US", + "url": "rtmp://ingest-any-ord1.broadcast.steamcontent.com/app" + }, + { + "name": "Seattle, US", + "url": "rtmp://ingest-any-sea1.broadcast.steamcontent.com/app" + }, + { + "name": "Los Angeles, US", + "url": "rtmp://ingest-any-lax1.broadcast.steamcontent.com/app" + }, + { + "name": "Washington DC, US", + "url": "rtmp://ingest-any-iad1.broadcast.steamcontent.com/app" + }, + { + "name": "Frankfurt, DE", + "url": "rtmp://ingest-any-fra1.broadcast.steamcontent.com/app" + }, + { + "name": "London, UK", + "url": "rtmp://ingest-any-lhr1.broadcast.steamcontent.com/app" + }, + { + "name": "Stockholm, SE", + "url": "rtmp://ingest-any-sto1.broadcast.steamcontent.com/app" + }, + { + "name": "Tokyo, JP", + "url": "rtmp://ingest-any-tyo1.broadcast.steamcontent.com/app" + }, + { + "name": "Hong Kong, HK", + "url": "rtmp://ingest-any-hkg1.broadcast.steamcontent.com/app" + }, + { + "name": "Singapore, SG", + "url": "rtmp://ingest-any-sgp1.broadcast.steamcontent.com/app" + }, + { + "name": "Sydney, AU", + "url": "rtmp://ingest-any-syd1.broadcast.steamcontent.com/app" + }, + { + "name": "São Paulo, BR", + "url": "rtmp://ingest-any-gru1.broadcast.steamcontent.com/app" + } + ], + "recommended": { + "keyint": 2, + "profile": "high", + "max video bitrate": 7000, + "max audio bitrate": 128 + } } ] } diff --git a/plugins/rtmp-services/rtmp-common.c b/plugins/rtmp-services/rtmp-common.c index 272fa77..bf0b178 100644 --- a/plugins/rtmp-services/rtmp-common.c +++ b/plugins/rtmp-services/rtmp-common.c @@ -22,13 +22,13 @@ static const char *rtmp_common_getname(void *unused) static json_t *open_services_file(void); static inline json_t *find_service(json_t *root, const char *name, - const char **p_new_name); + const char **p_new_name); static inline const char *get_string_val(json_t *service, const char *key); extern void twitch_ingests_refresh(int seconds); static void ensure_valid_url(struct rtmp_common *service, json_t *json, - obs_data_t *settings) + obs_data_t *settings) { json_t *servers = json_object_get(json, "servers"); const char *top_url = NULL; @@ -70,9 +70,9 @@ static void rtmp_common_update(void *data, obs_data_t *settings) bfree(service->key); service->service = bstrdup(obs_data_get_string(settings, "service")); - service->server = bstrdup(obs_data_get_string(settings, "server")); - service->key = bstrdup(obs_data_get_string(settings, "key")); - service->output = NULL; + service->server = bstrdup(obs_data_get_string(settings, "server")); + service->key = bstrdup(obs_data_get_string(settings, "key")); + service->output = NULL; json_t *root = open_services_file(); if (root) { @@ -86,7 +86,7 @@ static void rtmp_common_update(void *data, obs_data_t *settings) if (serv) { json_t *rec = json_object_get(serv, "recommended"); - if (rec && json_is_object(rec)) { + if (json_is_object(rec)) { const char *out = get_string_val(rec, "output"); if (out) service->output = bstrdup(out); @@ -149,7 +149,7 @@ static inline bool get_bool_val(json_t *service, const char *key) } static void add_service(obs_property_t *list, json_t *service, bool show_all, - const char *cur_service) + const char *cur_service) { json_t *servers; const char *name; @@ -157,14 +157,14 @@ static void add_service(obs_property_t *list, json_t *service, bool show_all, if (!json_is_object(service)) { blog(LOG_WARNING, "rtmp-common.c: [add_service] service " - "is not an object"); + "is not an object"); return; } name = get_string_val(service, "name"); if (!name) { blog(LOG_WARNING, "rtmp-common.c: [add_service] service " - "has no name"); + "has no name"); return; } @@ -175,8 +175,10 @@ static void add_service(obs_property_t *list, json_t *service, bool show_all, servers = json_object_get(service, "servers"); if (!servers || !json_is_array(servers)) { - blog(LOG_WARNING, "rtmp-common.c: [add_service] service " - "'%s' has no servers", name); + blog(LOG_WARNING, + "rtmp-common.c: [add_service] service " + "'%s' has no servers", + name); return; } @@ -184,14 +186,14 @@ static void add_service(obs_property_t *list, json_t *service, bool show_all, } static void add_services(obs_property_t *list, json_t *root, bool show_all, - const char *cur_service) + const char *cur_service) { json_t *service; size_t index; if (!json_is_array(root)) { blog(LOG_WARNING, "rtmp-common.c: [add_services] JSON file " - "root is not an array"); + "root is not an array"); return; } @@ -202,18 +204,18 @@ static void add_services(obs_property_t *list, json_t *root, bool show_all, service = find_service(root, cur_service, NULL); if (!service && cur_service && *cur_service) { obs_property_list_insert_string(list, 0, cur_service, - cur_service); + cur_service); obs_property_list_item_disable(list, 0, true); } } static json_t *open_json_file(const char *file) { - char *file_data = os_quick_read_utf8_file(file); + char *file_data = os_quick_read_utf8_file(file); json_error_t error; - json_t *root; - json_t *list; - int format_ver; + json_t *root; + json_t *list; + int format_ver; if (!file_data) return NULL; @@ -222,18 +224,20 @@ static json_t *open_json_file(const char *file) bfree(file_data); if (!root) { - blog(LOG_WARNING, "rtmp-common.c: [open_json_file] " - "Error reading JSON file (%d): %s", - error.line, error.text); + blog(LOG_WARNING, + "rtmp-common.c: [open_json_file] " + "Error reading JSON file (%d): %s", + error.line, error.text); return NULL; } format_ver = get_int_val(root, "format_version"); if (format_ver != RTMP_SERVICES_FORMAT_VERSION) { - blog(LOG_DEBUG, "rtmp-common.c: [open_json_file] " - "Wrong format version (%d), expected %d", - format_ver, RTMP_SERVICES_FORMAT_VERSION); + blog(LOG_DEBUG, + "rtmp-common.c: [open_json_file] " + "Wrong format version (%d), expected %d", + format_ver, RTMP_SERVICES_FORMAT_VERSION); json_decref(root); return NULL; } @@ -245,7 +249,7 @@ static json_t *open_json_file(const char *file) if (!list) { blog(LOG_WARNING, "rtmp-common.c: [open_json_file] " - "No services list"); + "No services list"); return NULL; } @@ -275,7 +279,7 @@ static json_t *open_services_file(void) } static void build_service_list(obs_property_t *list, json_t *root, - bool show_all, const char *cur_service) + bool show_all, const char *cur_service) { obs_property_list_clear(list); add_services(list, root, show_all, cur_service); @@ -293,7 +297,7 @@ static bool fill_twitch_servers_locked(obs_property_t *servers_prop) size_t count = twitch_ingest_count(); obs_property_list_add_string(servers_prop, - obs_module_text("Server.Auto"), "auto"); + obs_module_text("Server.Auto"), "auto"); if (count <= 1) return false; @@ -318,7 +322,7 @@ static inline bool fill_twitch_servers(obs_property_t *servers_prop) } static void fill_servers(obs_property_t *servers_prop, json_t *service, - const char *name) + const char *name) { json_t *servers, *server; size_t index; @@ -328,15 +332,16 @@ static void fill_servers(obs_property_t *servers_prop, json_t *service, servers = json_object_get(service, "servers"); if (!json_is_array(servers)) { - blog(LOG_WARNING, "rtmp-common.c: [fill_servers] " - "Servers for service '%s' not a valid object", - name); + blog(LOG_WARNING, + "rtmp-common.c: [fill_servers] " + "Servers for service '%s' not a valid object", + name); return; } if (strcmp(name, "Mixer.com - FTL") == 0) { - obs_property_list_add_string(servers_prop, - obs_module_text("Server.Auto"), "auto"); + obs_property_list_add_string( + servers_prop, obs_module_text("Server.Auto"), "auto"); } if (strcmp(name, "Twitch") == 0) { if (fill_twitch_servers(servers_prop)) @@ -345,7 +350,7 @@ static void fill_servers(obs_property_t *servers_prop, json_t *service, json_array_foreach (servers, index, server) { const char *server_name = get_string_val(server, "name"); - const char *url = get_string_val(server, "url"); + const char *url = get_string_val(server, "url"); if (!server_name || !url) continue; @@ -355,12 +360,13 @@ static void fill_servers(obs_property_t *servers_prop, json_t *service, } static inline json_t *find_service(json_t *root, const char *name, - const char **p_new_name) + const char **p_new_name) { size_t index; json_t *service; - if (p_new_name) *p_new_name = NULL; + if (p_new_name) + *p_new_name = NULL; json_array_foreach (root, index, service) { const char *cur_name = get_string_val(service, "name"); @@ -376,7 +382,8 @@ static inline json_t *find_service(json_t *root, const char *name, json_array_foreach (alt_names, alt_name_idx, alt_name_obj) { const char *alt_name = json_string_value(alt_name_obj); if (alt_name && strcmp(name, alt_name) == 0) { - if (p_new_name) *p_new_name = cur_name; + if (p_new_name) + *p_new_name = cur_name; return service; } } @@ -386,10 +393,10 @@ static inline json_t *find_service(json_t *root, const char *name, } static bool service_selected(obs_properties_t *props, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { const char *name = obs_data_get_string(settings, "service"); - json_t *root = obs_properties_get_param(props); + json_t *root = obs_properties_get_param(props); json_t *service; const char *new_name; @@ -418,8 +425,8 @@ static bool service_selected(obs_properties_t *props, obs_property_t *p, return true; } -static bool show_all_services_toggled(obs_properties_t *ppts, - obs_property_t *p, obs_data_t *settings) +static bool show_all_services_toggled(obs_properties_t *ppts, obs_property_t *p, + obs_data_t *settings) { const char *cur_service = obs_data_get_string(settings, "service"); bool show_all = obs_data_get_bool(settings, "show_all"); @@ -429,7 +436,7 @@ static bool show_all_services_toggled(obs_properties_t *ppts, return false; build_service_list(obs_properties_get(ppts, "service"), root, show_all, - cur_service); + cur_service); UNUSED_PARAMETER(p); return true; @@ -440,37 +447,37 @@ static obs_properties_t *rtmp_common_properties(void *unused) UNUSED_PARAMETER(unused); obs_properties_t *ppts = obs_properties_create(); - obs_property_t *p; - json_t *root; + obs_property_t *p; + json_t *root; root = open_services_file(); if (root) obs_properties_set_param(ppts, root, properties_data_destroy); - p = obs_properties_add_list(ppts, "service", - obs_module_text("Service"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + p = obs_properties_add_list(ppts, "service", obs_module_text("Service"), + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_set_modified_callback(p, service_selected); p = obs_properties_add_bool(ppts, "show_all", - obs_module_text("ShowAll")); + obs_module_text("ShowAll")); obs_property_set_modified_callback(p, show_all_services_toggled); obs_properties_add_list(ppts, "server", obs_module_text("Server"), - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); obs_properties_add_text(ppts, "key", obs_module_text("StreamKey"), - OBS_TEXT_PASSWORD); + OBS_TEXT_PASSWORD); return ppts; } static void apply_video_encoder_settings(obs_data_t *settings, - json_t *recommended) + json_t *recommended) { json_t *item = json_object_get(recommended, "keyint"); - if (item && json_is_integer(item)) { + if (json_is_integer(item)) { int keyint = (int)json_integer_value(item); obs_data_set_int(settings, "keyint_sec", keyint); } @@ -478,13 +485,13 @@ static void apply_video_encoder_settings(obs_data_t *settings, obs_data_set_string(settings, "rate_control", "CBR"); item = json_object_get(recommended, "profile"); - if (item && json_is_string(item)) { + if (json_is_string(item)) { const char *profile = json_string_value(item); obs_data_set_string(settings, "profile", profile); } item = json_object_get(recommended, "max video bitrate"); - if (item && json_is_integer(item)) { + if (json_is_integer(item)) { int max_bitrate = (int)json_integer_value(item); if (obs_data_get_int(settings, "bitrate") > max_bitrate) { obs_data_set_int(settings, "bitrate", max_bitrate); @@ -493,11 +500,11 @@ static void apply_video_encoder_settings(obs_data_t *settings, } item = json_object_get(recommended, "bframes"); - if (item && json_is_integer(item)) + if (json_is_integer(item)) obs_data_set_int(settings, "bf", 0); item = json_object_get(recommended, "x264opts"); - if (item && json_is_string(item)) { + if (json_is_string(item)) { const char *x264_settings = json_string_value(item); const char *cur_settings = obs_data_get_string(settings, "x264opts"); @@ -514,10 +521,10 @@ static void apply_video_encoder_settings(obs_data_t *settings, } static void apply_audio_encoder_settings(obs_data_t *settings, - json_t *recommended) + json_t *recommended) { json_t *item = json_object_get(recommended, "max audio bitrate"); - if (item && json_is_integer(item)) { + if (json_is_integer(item)) { int max_bitrate = (int)json_integer_value(item); if (obs_data_get_int(settings, "bitrate") > max_bitrate) obs_data_set_int(settings, "bitrate", max_bitrate); @@ -525,16 +532,18 @@ static void apply_audio_encoder_settings(obs_data_t *settings, } static void initialize_output(struct rtmp_common *service, json_t *root, - obs_data_t *video_settings, obs_data_t *audio_settings) + obs_data_t *video_settings, + obs_data_t *audio_settings) { - json_t *json_service = find_service(root, service->service, NULL); - json_t *recommended; + json_t *json_service = find_service(root, service->service, NULL); + json_t *recommended; if (!json_service) { if (service->service && *service->service) - blog(LOG_WARNING, "rtmp-common.c: [initialize_output] " - "Could not find service '%s'", - service->service); + blog(LOG_WARNING, + "rtmp-common.c: [initialize_output] " + "Could not find service '%s'", + service->service); return; } @@ -548,15 +557,15 @@ static void initialize_output(struct rtmp_common *service, json_t *root, apply_audio_encoder_settings(audio_settings, recommended); } -static void rtmp_common_apply_settings(void *data, - obs_data_t *video_settings, obs_data_t *audio_settings) +static void rtmp_common_apply_settings(void *data, obs_data_t *video_settings, + obs_data_t *audio_settings) { struct rtmp_common *service = data; - json_t *root = open_services_file(); + json_t *root = open_services_file(); if (root) { initialize_output(service, root, video_settings, - audio_settings); + audio_settings); json_decref(root); } } @@ -595,14 +604,14 @@ static const char *rtmp_common_key(void *data) } struct obs_service_info rtmp_common_service = { - .id = "rtmp_common", - .get_name = rtmp_common_getname, - .create = rtmp_common_create, - .destroy = rtmp_common_destroy, - .update = rtmp_common_update, + .id = "rtmp_common", + .get_name = rtmp_common_getname, + .create = rtmp_common_create, + .destroy = rtmp_common_destroy, + .update = rtmp_common_update, .get_properties = rtmp_common_properties, - .get_url = rtmp_common_url, - .get_key = rtmp_common_key, + .get_url = rtmp_common_url, + .get_key = rtmp_common_key, .apply_encoder_settings = rtmp_common_apply_settings, .get_output_type = rtmp_common_get_output_type, }; diff --git a/plugins/rtmp-services/rtmp-custom.c b/plugins/rtmp-services/rtmp-custom.c index 68a6e85..4f6c1ad 100644 --- a/plugins/rtmp-services/rtmp-custom.c +++ b/plugins/rtmp-services/rtmp-custom.c @@ -20,7 +20,7 @@ static void rtmp_custom_update(void *data, obs_data_t *settings) bfree(service->key); service->server = bstrdup(obs_data_get_string(settings, "server")); - service->key = bstrdup(obs_data_get_string(settings, "key")); + service->key = bstrdup(obs_data_get_string(settings, "key")); service->use_auth = obs_data_get_bool(settings, "use_auth"); service->username = bstrdup(obs_data_get_string(settings, "username")); service->password = bstrdup(obs_data_get_string(settings, "password")); @@ -47,7 +47,7 @@ static void *rtmp_custom_create(obs_data_t *settings, obs_service_t *service) } static bool use_auth_modified(obs_properties_t *ppts, obs_property_t *p, - obs_data_t *settings) + obs_data_t *settings) { bool use_auth = obs_data_get_bool(settings, "use_auth"); p = obs_properties_get(ppts, "username"); @@ -67,13 +67,14 @@ static obs_properties_t *rtmp_custom_properties(void *unused) obs_properties_add_text(ppts, "server", "URL", OBS_TEXT_DEFAULT); obs_properties_add_text(ppts, "key", obs_module_text("StreamKey"), - OBS_TEXT_PASSWORD); + OBS_TEXT_PASSWORD); - p = obs_properties_add_bool(ppts, "use_auth", obs_module_text("UseAuth")); + p = obs_properties_add_bool(ppts, "use_auth", + obs_module_text("UseAuth")); obs_properties_add_text(ppts, "username", obs_module_text("Username"), - OBS_TEXT_DEFAULT); + OBS_TEXT_DEFAULT); obs_properties_add_text(ppts, "password", obs_module_text("Password"), - OBS_TEXT_PASSWORD); + OBS_TEXT_PASSWORD); obs_property_set_modified_callback(p, use_auth_modified); return ppts; } @@ -107,14 +108,14 @@ static const char *rtmp_custom_password(void *data) } struct obs_service_info rtmp_custom_service = { - .id = "rtmp_custom", - .get_name = rtmp_custom_name, - .create = rtmp_custom_create, - .destroy = rtmp_custom_destroy, - .update = rtmp_custom_update, + .id = "rtmp_custom", + .get_name = rtmp_custom_name, + .create = rtmp_custom_create, + .destroy = rtmp_custom_destroy, + .update = rtmp_custom_update, .get_properties = rtmp_custom_properties, - .get_url = rtmp_custom_url, - .get_key = rtmp_custom_key, - .get_username = rtmp_custom_username, - .get_password = rtmp_custom_password + .get_url = rtmp_custom_url, + .get_key = rtmp_custom_key, + .get_username = rtmp_custom_username, + .get_password = rtmp_custom_password, }; diff --git a/plugins/rtmp-services/rtmp-services-main.c b/plugins/rtmp-services/rtmp-services-main.c index 0eeaa73..b9afb59 100644 --- a/plugins/rtmp-services/rtmp-services-main.c +++ b/plugins/rtmp-services/rtmp-services-main.c @@ -35,7 +35,7 @@ static bool confirm_service_file(void *param, struct file_download_data *file) obs_data_t *data; int format_version; - data = obs_data_create_from_json((char*)file->buffer.array); + data = obs_data_create_from_json((char *)file->buffer.array); if (!data) return false; @@ -78,20 +78,18 @@ bool obs_module_load(void) proc_handler_t *ph = obs_get_proc_handler(); proc_handler_add(ph, "void twitch_ingests_refresh(int seconds)", - refresh_callback, NULL); + refresh_callback, NULL); #if !defined(_WIN32) || CHECK_FOR_SERVICE_UPDATES char *local_dir = obs_module_file(""); char *cache_dir = obs_module_config_path(""); if (cache_dir) { - update_info = update_info_create( - RTMP_SERVICES_LOG_STR, - module_name.array, - RTMP_SERVICES_URL, - local_dir, - cache_dir, - confirm_service_file, NULL); + update_info = update_info_create(RTMP_SERVICES_LOG_STR, + module_name.array, + RTMP_SERVICES_URL, local_dir, + cache_dir, + confirm_service_file, NULL); } load_twitch_data(); diff --git a/plugins/rtmp-services/twitch.c b/plugins/rtmp-services/twitch.c index 31fdd1f..baf96f6 100644 --- a/plugins/rtmp-services/twitch.c +++ b/plugins/rtmp-services/twitch.c @@ -145,7 +145,7 @@ struct twitch_ingest twitch_ingest(size_t idx) ingest.name = NULL; ingest.url = NULL; } else { - ingest = *(struct twitch_ingest*)(cur_ingests.array + idx); + ingest = *(struct twitch_ingest *)(cur_ingests.array + idx); } return ingest; @@ -168,10 +168,9 @@ void twitch_ingests_refresh(int seconds) os_atomic_set_bool(&ingests_refreshing, true); twitch_update_info = update_info_create_single( - "[twitch ingest update] ", - get_module_name(), - "https://ingest.twitch.tv/api/v2/ingests", - twitch_ingest_update, NULL); + "[twitch ingest update] ", get_module_name(), + "https://ingest.twitch.tv/api/v2/ingests", + twitch_ingest_update, NULL); } /* wait five seconds max when loading ingests for the first time */ @@ -189,10 +188,8 @@ void load_twitch_data(void) { char *twitch_cache = obs_module_config_path("twitch_ingests.json"); - struct ingest def = { - .name = bstrdup("Default"), - .url = bstrdup("rtmp://live.twitch.tv/app") - }; + struct ingest def = {.name = bstrdup("Default"), + .url = bstrdup("rtmp://live.twitch.tv/app")}; pthread_mutex_lock(&mutex); da_push_back(cur_ingests, &def); diff --git a/plugins/text-freetype2/data/locale/de-DE.ini b/plugins/text-freetype2/data/locale/de-DE.ini index 46db766..ddd15f5 100644 --- a/plugins/text-freetype2/data/locale/de-DE.ini +++ b/plugins/text-freetype2/data/locale/de-DE.ini @@ -1,7 +1,7 @@ TextFreetype2="Text (FreeType 2)" Font="Schriftart" Text="Text" -TextFile="Textdatei (UTF-8 oder UTF-16)" +TextFile="Textdatei (UTF‐8 oder UTF‐16)" TextFileFilter="Textdateien (*.txt);;" ChatLogMode="Chatprotokollmodus" ChatLogLines="Chatprotokollzeilen" diff --git a/plugins/text-freetype2/data/locale/gl-ES.ini b/plugins/text-freetype2/data/locale/gl-ES.ini index 30f20c8..c6eccdf 100644 --- a/plugins/text-freetype2/data/locale/gl-ES.ini +++ b/plugins/text-freetype2/data/locale/gl-ES.ini @@ -1,8 +1,10 @@ TextFreetype2="Texto (FreeType 2)" -Font="Fonte" +Font="Tipo de letra" Text="Texto" TextFile="Ficheiro de texto (UTF-8 ou UTF-16)" TextFileFilter="Ficheiros de texto (*.txt);;" +ChatLogMode="Modo de rexistro da conversa" +ChatLogLines="Liñas de rexistro da conversa" Color1="Cor 1" Color2="Cor 2" Outline="Contorno" diff --git a/plugins/text-freetype2/data/locale/sl-SI.ini b/plugins/text-freetype2/data/locale/sl-SI.ini index 297a84d..31a9258 100644 --- a/plugins/text-freetype2/data/locale/sl-SI.ini +++ b/plugins/text-freetype2/data/locale/sl-SI.ini @@ -1,12 +1,15 @@ +TextFreetype2="Besedilo (FreeType 2)" Font="Pisava" -Text="Tekst" -TextFile="Besedilna datoteka (UTF-8 or UTF-16)" -TextFileFilter="Besedilne Datoteke (*.txt);;" -Color1="Barva 1" -Color2="Barva 2" +Text="Besedilo" +TextFile="Besedilna datoteka (UTF-8 ali UTF-16)" +TextFileFilter="Besedilne datoteke (*.txt);;" +ChatLogMode="Način dnevnika klepeta" +ChatLogLines="Št. vrstic dnevnika klepeta" +Color1="1. barva" +Color2="2. barva" Outline="Oris" DropShadow="Odajaj senco" -ReadFromFile="Preberi iz datoteka" -CustomWidth="Širina poljubnega besedila" -WordWrap="Prelom besedila" +ReadFromFile="Preberi iz datoteke" +CustomWidth="Širina besedila po meri" +WordWrap="Prelomi besedilo" diff --git a/plugins/text-freetype2/find-font-cocoa.m b/plugins/text-freetype2/find-font-cocoa.m index 9583cb6..22b3792 100644 --- a/plugins/text-freetype2/find-font-cocoa.m +++ b/plugins/text-freetype2/find-font-cocoa.m @@ -30,12 +30,12 @@ static void add_path_fonts(NSFileManager *file_manager, NSString *path) files = [file_manager contentsOfDirectoryAtPath:path error:nil]; for (NSString *file in files) { - NSString *full_path = [path stringByAppendingPathComponent:file]; + NSString *full_path = + [path stringByAppendingPathComponent:file]; BOOL is_dir = FALSE; - bool folder_exists = [file_manager - fileExistsAtPath:full_path - isDirectory:&is_dir]; + bool folder_exists = [file_manager fileExistsAtPath:full_path + isDirectory:&is_dir]; if (folder_exists && is_dir) { add_path_fonts(file_manager, full_path); @@ -50,7 +50,7 @@ void load_os_font_list(void) @autoreleasepool { BOOL is_dir; NSArray *paths = NSSearchPathForDirectoriesInDomains( - NSLibraryDirectory, NSAllDomainsMask, true); + NSLibraryDirectory, NSAllDomainsMask, true); for (NSString *path in paths) { NSFileManager *file_manager = @@ -59,8 +59,8 @@ void load_os_font_list(void) [path stringByAppendingPathComponent:@"Fonts"]; bool folder_exists = [file_manager - fileExistsAtPath:font_path - isDirectory:&is_dir]; + fileExistsAtPath:font_path + isDirectory:&is_dir]; if (folder_exists && is_dir) add_path_fonts(file_manager, font_path); @@ -78,17 +78,19 @@ static uint32_t add_font_checksum(uint32_t checksum, const char *path) } static uint32_t add_font_checksum_path(uint32_t checksum, - NSFileManager *file_manager, NSString *path) + NSFileManager *file_manager, + NSString *path) { NSArray *files = NULL; files = [file_manager contentsOfDirectoryAtPath:path error:nil]; for (NSString *file in files) { - NSString *full_path = [path stringByAppendingPathComponent:file]; + NSString *full_path = + [path stringByAppendingPathComponent:file]; - checksum = add_font_checksum(checksum, - full_path.fileSystemRepresentation); + checksum = add_font_checksum( + checksum, full_path.fileSystemRepresentation); } return checksum; @@ -101,7 +103,7 @@ uint32_t get_font_checksum(void) @autoreleasepool { BOOL is_dir; NSArray *paths = NSSearchPathForDirectoriesInDomains( - NSLibraryDirectory, NSAllDomainsMask, true); + NSLibraryDirectory, NSAllDomainsMask, true); for (NSString *path in paths) { NSFileManager *file_manager = @@ -110,12 +112,12 @@ uint32_t get_font_checksum(void) [path stringByAppendingPathComponent:@"Fonts"]; bool folder_exists = [file_manager - fileExistsAtPath:font_path - isDirectory:&is_dir]; + fileExistsAtPath:font_path + isDirectory:&is_dir]; if (folder_exists && is_dir) - checksum = add_font_checksum_path(checksum, - file_manager, font_path); + checksum = add_font_checksum_path( + checksum, file_manager, font_path); } } diff --git a/plugins/text-freetype2/find-font-iconv.c b/plugins/text-freetype2/find-font-iconv.c index 2262f12..2265432 100644 --- a/plugins/text-freetype2/find-font-iconv.c +++ b/plugins/text-freetype2/find-font-iconv.c @@ -5,80 +5,51 @@ struct mac_font_mapping { unsigned short encoding_id; unsigned short language_id; - const char *code_page; + const char *code_page; }; #define TT_MAC_LANGID_ANY 0xFFFF static const struct mac_font_mapping mac_codes[] = { - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ENGLISH, "macintosh"}, - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ICELANDIC,"x-mac-icelandic"}, - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_TURKISH, "x-mac-ce"}, - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_POLISH, "x-mac-ce"}, - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ROMANIAN, "x-mac-romanian"}, - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_CZECH, "x-mac-ce"}, - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_SLOVAK, "x-mac-ce"}, - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ANY, "macintosh"}, - {TT_MAC_ID_JAPANESE, TT_MAC_LANGID_JAPANESE, "Shift_JIS"}, - {TT_MAC_ID_JAPANESE, TT_MAC_LANGID_ANY, "Shift_JIS"}, - {TT_MAC_ID_KOREAN, TT_MAC_LANGID_KOREAN, "EUC-KR"}, - {TT_MAC_ID_KOREAN, TT_MAC_LANGID_ANY, "EUC-KR"}, - {TT_MAC_ID_ARABIC, TT_MAC_LANGID_ARABIC, "x-mac-arabic"}, - {TT_MAC_ID_ARABIC, TT_MAC_LANGID_URDU, "x-mac-farsi"}, - {TT_MAC_ID_ARABIC, TT_MAC_LANGID_FARSI, "x-mac-farsi"}, - {TT_MAC_ID_ARABIC, TT_MAC_LANGID_ANY, "x-mac-arabic"}, - {TT_MAC_ID_HEBREW, TT_MAC_LANGID_HEBREW, "x-mac-hebrew"}, - {TT_MAC_ID_HEBREW, TT_MAC_LANGID_ANY, "x-mac-hebrew"}, - {TT_MAC_ID_GREEK, TT_MAC_LANGID_ANY, "x-mac-greek"}, - {TT_MAC_ID_RUSSIAN, TT_MAC_LANGID_ANY, "x-mac-cyrillic"}, - {TT_MAC_ID_DEVANAGARI, TT_MAC_LANGID_ANY, "x-mac-devanagari"}, - {TT_MAC_ID_GURMUKHI, TT_MAC_LANGID_ANY, "x-mac-gurmukhi"}, - {TT_MAC_ID_GUJARATI, TT_MAC_LANGID_ANY, "x-mac-gujarati"}, - { - TT_MAC_ID_TRADITIONAL_CHINESE, - TT_MAC_LANGID_CHINESE_SIMPLIFIED, - "Big5" - }, - { - TT_MAC_ID_TRADITIONAL_CHINESE, - TT_MAC_LANGID_ANY, - "Big5" - }, - { - TT_MAC_ID_SIMPLIFIED_CHINESE, - TT_MAC_LANGID_CHINESE_SIMPLIFIED, - "GB2312" - }, - { - TT_MAC_ID_SIMPLIFIED_CHINESE, - TT_MAC_LANGID_ANY, - "GB2312" - } -}; + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ENGLISH, "macintosh"}, + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ICELANDIC, "x-mac-icelandic"}, + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_TURKISH, "x-mac-ce"}, + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_POLISH, "x-mac-ce"}, + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ROMANIAN, "x-mac-romanian"}, + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_CZECH, "x-mac-ce"}, + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_SLOVAK, "x-mac-ce"}, + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ANY, "macintosh"}, + {TT_MAC_ID_JAPANESE, TT_MAC_LANGID_JAPANESE, "Shift_JIS"}, + {TT_MAC_ID_JAPANESE, TT_MAC_LANGID_ANY, "Shift_JIS"}, + {TT_MAC_ID_KOREAN, TT_MAC_LANGID_KOREAN, "EUC-KR"}, + {TT_MAC_ID_KOREAN, TT_MAC_LANGID_ANY, "EUC-KR"}, + {TT_MAC_ID_ARABIC, TT_MAC_LANGID_ARABIC, "x-mac-arabic"}, + {TT_MAC_ID_ARABIC, TT_MAC_LANGID_URDU, "x-mac-farsi"}, + {TT_MAC_ID_ARABIC, TT_MAC_LANGID_FARSI, "x-mac-farsi"}, + {TT_MAC_ID_ARABIC, TT_MAC_LANGID_ANY, "x-mac-arabic"}, + {TT_MAC_ID_HEBREW, TT_MAC_LANGID_HEBREW, "x-mac-hebrew"}, + {TT_MAC_ID_HEBREW, TT_MAC_LANGID_ANY, "x-mac-hebrew"}, + {TT_MAC_ID_GREEK, TT_MAC_LANGID_ANY, "x-mac-greek"}, + {TT_MAC_ID_RUSSIAN, TT_MAC_LANGID_ANY, "x-mac-cyrillic"}, + {TT_MAC_ID_DEVANAGARI, TT_MAC_LANGID_ANY, "x-mac-devanagari"}, + {TT_MAC_ID_GURMUKHI, TT_MAC_LANGID_ANY, "x-mac-gurmukhi"}, + {TT_MAC_ID_GUJARATI, TT_MAC_LANGID_ANY, "x-mac-gujarati"}, + {TT_MAC_ID_TRADITIONAL_CHINESE, TT_MAC_LANGID_CHINESE_SIMPLIFIED, + "Big5"}, + {TT_MAC_ID_TRADITIONAL_CHINESE, TT_MAC_LANGID_ANY, "Big5"}, + {TT_MAC_ID_SIMPLIFIED_CHINESE, TT_MAC_LANGID_CHINESE_SIMPLIFIED, + "GB2312"}, + {TT_MAC_ID_SIMPLIFIED_CHINESE, TT_MAC_LANGID_ANY, "GB2312"}}; -const char *iso_codes[] = { - "us-ascii", - NULL, - "iso-8859-1" -}; +const char *iso_codes[] = {"us-ascii", NULL, "iso-8859-1"}; -const char *ms_codes[] = { - "UTF-16BE", - "UTF-16BE", - "Shift_JIS", - NULL, - "Big5", - NULL, - NULL, - NULL, - NULL, - NULL, - "UTF-16BE" -}; +const char *ms_codes[] = {"UTF-16BE", "UTF-16BE", "Shift_JIS", NULL, + "Big5", NULL, NULL, NULL, + NULL, NULL, "UTF-16BE"}; static const size_t mac_code_count = sizeof(mac_codes) / sizeof(mac_codes[0]); static const size_t iso_code_count = sizeof(iso_codes) / sizeof(iso_codes[0]); -static const size_t ms_code_count = sizeof(ms_codes) / sizeof(ms_codes[0]); +static const size_t ms_code_count = sizeof(ms_codes) / sizeof(ms_codes[0]); static const char *get_mac_code(uint16_t encoding_id, uint16_t language_id) { @@ -94,7 +65,8 @@ static const char *get_mac_code(uint16_t encoding_id, uint16_t language_id) } static const char *get_code_page_for_font(uint16_t platform_id, - uint16_t encoding_id, uint16_t language_id) + uint16_t encoding_id, + uint16_t language_id) { const char *ret; @@ -122,38 +94,40 @@ static const char *get_code_page_for_font(uint16_t platform_id, char *sfnt_name_to_utf8(FT_SfntName *sfnt_name) { const char *charset = get_code_page_for_font(sfnt_name->platform_id, - sfnt_name->encoding_id, sfnt_name->language_id); + sfnt_name->encoding_id, + sfnt_name->language_id); char utf8[256]; char *conv_in, *conv_out; size_t in_len, out_len; if (!charset) { - blog(LOG_DEBUG, "invalid character set found, " - "platform_id: %d, encoding_id: %d, " - "language_id: %d", - sfnt_name->platform_id, - sfnt_name->encoding_id, - sfnt_name->language_id); + blog(LOG_DEBUG, + "invalid character set found, " + "platform_id: %d, encoding_id: %d, " + "language_id: %d", + sfnt_name->platform_id, sfnt_name->encoding_id, + sfnt_name->language_id); return NULL; } iconv_t ic = iconv_open("UTF-8", charset); if (ic == (iconv_t)-1) { - blog(LOG_DEBUG, "couldn't intialize font code page " - "conversion: '%s' to 'utf-8': errno = %d", - charset, (int)errno); + blog(LOG_DEBUG, + "couldn't intialize font code page " + "conversion: '%s' to 'utf-8': errno = %d", + charset, (int)errno); return NULL; } - conv_in = (char*)sfnt_name->string; + conv_in = (char *)sfnt_name->string; conv_out = utf8; - in_len = sfnt_name->string_len; - out_len = 256; + in_len = sfnt_name->string_len; + out_len = 256; size_t n = iconv(ic, &conv_in, &in_len, &conv_out, &out_len); if (n == (size_t)-1) { blog(LOG_WARNING, "couldn't convert font name text: errno = %d", - (int)errno); + (int)errno); iconv_close(ic); return NULL; } diff --git a/plugins/text-freetype2/find-font-unix.c b/plugins/text-freetype2/find-font-unix.c index 05d83bc..668aa5d 100644 --- a/plugins/text-freetype2/find-font-unix.c +++ b/plugins/text-freetype2/find-font-unix.c @@ -22,38 +22,34 @@ along with this program. If not, see . #include "find-font.h" #include "text-freetype2.h" -void free_os_font_list(void) -{ -} +void free_os_font_list(void) {} bool load_cached_os_font_list(void) { return true; } -void load_os_font_list(void) -{ -} +void load_os_font_list(void) {} const char *get_font_path(const char *family, uint16_t size, const char *style, - uint32_t flags, FT_Long *idx) + uint32_t flags, FT_Long *idx) { - bool bold = !!(flags & OBS_FONT_BOLD); - bool italic = !!(flags & OBS_FONT_ITALIC); + bool bold = !!(flags & OBS_FONT_BOLD); + bool italic = !!(flags & OBS_FONT_ITALIC); FcPattern *pattern = FcPatternCreate(); - FcPattern *match = NULL; - bool success = false; - FcResult match_result; + FcPattern *match = NULL; + bool success = false; + FcResult match_result; /* somewhat of a cheap hack */ static __thread char result[512]; - FcPatternAddString(pattern, FC_FAMILY, (const FcChar8*)family); - FcPatternAddString(pattern, FC_STYLE, (const FcChar8*)style); + FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *)family); + FcPatternAddString(pattern, FC_STYLE, (const FcChar8 *)style); FcPatternAddInteger(pattern, FC_WEIGHT, - bold ? FC_WEIGHT_BOLD : FC_WEIGHT_REGULAR); + bold ? FC_WEIGHT_BOLD : FC_WEIGHT_REGULAR); FcPatternAddInteger(pattern, FC_SLANT, - italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); + italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); FcPatternAddDouble(pattern, FC_SIZE, (double)size); FcConfigSubstitute(NULL, pattern, FcMatchPattern); @@ -61,9 +57,9 @@ const char *get_font_path(const char *family, uint16_t size, const char *style, match = FcFontMatch(NULL, pattern, &match_result); if (match) { - FcChar8 *path = FcPatternFormat(match, - (const FcChar8*)"%{file}"); - strncpy(result, (char*)path, 511); + FcChar8 *path = + FcPatternFormat(match, (const FcChar8 *)"%{file}"); + strncpy(result, (char *)path, 511); FcStrFree(path); int fc_index = 0; @@ -73,8 +69,7 @@ const char *get_font_path(const char *family, uint16_t size, const char *style, FcPatternDestroy(match); success = true; } else { - blog(LOG_WARNING, "no matching font for '%s' found", - family); + blog(LOG_WARNING, "no matching font for '%s' found", family); } FcPatternDestroy(pattern); diff --git a/plugins/text-freetype2/find-font-windows.c b/plugins/text-freetype2/find-font-windows.c index 542a77d..71fe6b4 100644 --- a/plugins/text-freetype2/find-font-windows.c +++ b/plugins/text-freetype2/find-font-windows.c @@ -15,64 +15,47 @@ extern void save_font_list(void); struct mac_font_mapping { unsigned short encoding_id; unsigned short language_id; - unsigned int code_page; + unsigned int code_page; }; #define TT_MAC_LANGID_ANY 0xFFFF static const struct mac_font_mapping mac_codes[] = { - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ENGLISH, 10000}, - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ICELANDIC, 10079}, - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_TURKISH, 10081}, - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_POLISH, 10029}, - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ROMANIAN, 10010}, - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_CZECH, 10029}, - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_SLOVAK, 10029}, - {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ANY, 10000}, - {TT_MAC_ID_JAPANESE, TT_MAC_LANGID_JAPANESE, 932}, - {TT_MAC_ID_JAPANESE, TT_MAC_LANGID_ANY, 932}, - {TT_MAC_ID_TRADITIONAL_CHINESE,TT_MAC_LANGID_CHINESE_SIMPLIFIED, 950}, - {TT_MAC_ID_TRADITIONAL_CHINESE,TT_MAC_LANGID_ANY, 950}, - {TT_MAC_ID_KOREAN, TT_MAC_LANGID_KOREAN, 51949}, - {TT_MAC_ID_KOREAN, TT_MAC_LANGID_ANY, 51949}, - {TT_MAC_ID_ARABIC, TT_MAC_LANGID_ARABIC, 10004}, - {TT_MAC_ID_ARABIC, TT_MAC_LANGID_URDU, 0}, - {TT_MAC_ID_ARABIC, TT_MAC_LANGID_FARSI, 0}, - {TT_MAC_ID_ARABIC, TT_MAC_LANGID_ANY, 10004}, - {TT_MAC_ID_HEBREW, TT_MAC_LANGID_HEBREW, 10005}, - {TT_MAC_ID_HEBREW, TT_MAC_LANGID_ANY, 10005}, - {TT_MAC_ID_GREEK, TT_MAC_LANGID_ANY, 10006}, - {TT_MAC_ID_RUSSIAN, TT_MAC_LANGID_ANY, 10007}, - {TT_MAC_ID_DEVANAGARI, TT_MAC_LANGID_ANY, 0}, - {TT_MAC_ID_GURMUKHI, TT_MAC_LANGID_ANY, 0}, - {TT_MAC_ID_GUJARATI, TT_MAC_LANGID_ANY, 0}, + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ENGLISH, 10000}, + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ICELANDIC, 10079}, + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_TURKISH, 10081}, + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_POLISH, 10029}, + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ROMANIAN, 10010}, + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_CZECH, 10029}, + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_SLOVAK, 10029}, + {TT_MAC_ID_ROMAN, TT_MAC_LANGID_ANY, 10000}, + {TT_MAC_ID_JAPANESE, TT_MAC_LANGID_JAPANESE, 932}, + {TT_MAC_ID_JAPANESE, TT_MAC_LANGID_ANY, 932}, + {TT_MAC_ID_TRADITIONAL_CHINESE, TT_MAC_LANGID_CHINESE_SIMPLIFIED, 950}, + {TT_MAC_ID_TRADITIONAL_CHINESE, TT_MAC_LANGID_ANY, 950}, + {TT_MAC_ID_KOREAN, TT_MAC_LANGID_KOREAN, 51949}, + {TT_MAC_ID_KOREAN, TT_MAC_LANGID_ANY, 51949}, + {TT_MAC_ID_ARABIC, TT_MAC_LANGID_ARABIC, 10004}, + {TT_MAC_ID_ARABIC, TT_MAC_LANGID_URDU, 0}, + {TT_MAC_ID_ARABIC, TT_MAC_LANGID_FARSI, 0}, + {TT_MAC_ID_ARABIC, TT_MAC_LANGID_ANY, 10004}, + {TT_MAC_ID_HEBREW, TT_MAC_LANGID_HEBREW, 10005}, + {TT_MAC_ID_HEBREW, TT_MAC_LANGID_ANY, 10005}, + {TT_MAC_ID_GREEK, TT_MAC_LANGID_ANY, 10006}, + {TT_MAC_ID_RUSSIAN, TT_MAC_LANGID_ANY, 10007}, + {TT_MAC_ID_DEVANAGARI, TT_MAC_LANGID_ANY, 0}, + {TT_MAC_ID_GURMUKHI, TT_MAC_LANGID_ANY, 0}, + {TT_MAC_ID_GUJARATI, TT_MAC_LANGID_ANY, 0}, {TT_MAC_ID_SIMPLIFIED_CHINESE, TT_MAC_LANGID_CHINESE_SIMPLIFIED, 936}, - {TT_MAC_ID_SIMPLIFIED_CHINESE, TT_MAC_LANGID_ANY, 936} -}; + {TT_MAC_ID_SIMPLIFIED_CHINESE, TT_MAC_LANGID_ANY, 936}}; -unsigned int iso_codes[] = { - 20127, - 0, - 28591 -}; +unsigned int iso_codes[] = {20127, 0, 28591}; -unsigned int ms_codes[] = { - 1201, - 1201, - 932, - 0, - 950, - 0, - 0, - 0, - 0, - 0, - 1201 -}; +unsigned int ms_codes[] = {1201, 1201, 932, 0, 950, 0, 0, 0, 0, 0, 1201}; static const size_t mac_code_count = sizeof(mac_codes) / sizeof(mac_codes[0]); static const size_t iso_code_count = sizeof(iso_codes) / sizeof(iso_codes[0]); -static const size_t ms_code_count = sizeof(ms_codes) / sizeof(ms_codes[0]); +static const size_t ms_code_count = sizeof(ms_codes) / sizeof(ms_codes[0]); static unsigned int get_mac_code(uint16_t encoding_id, uint16_t language_id) { @@ -88,7 +71,8 @@ static unsigned int get_mac_code(uint16_t encoding_id, uint16_t language_id) } static unsigned int get_code_page_for_font(uint16_t platform_id, - uint16_t encoding_id, uint16_t language_id) + uint16_t encoding_id, + uint16_t language_id) { unsigned int ret; @@ -116,15 +100,16 @@ static unsigned int get_code_page_for_font(uint16_t platform_id, static char *wide_to_utf8(const wchar_t *str, size_t len) { size_t utf8_len; - char *utf8_str = NULL; + char *utf8_str = NULL; - utf8_len = (size_t)WideCharToMultiByte(CP_UTF8, 0, str, (int)len, - NULL, 0, NULL, false); + utf8_len = (size_t)WideCharToMultiByte(CP_UTF8, 0, str, (int)len, NULL, + 0, NULL, false); if (utf8_len) { utf8_str = bzalloc(utf8_len + 1); - utf8_len = (size_t)WideCharToMultiByte(CP_UTF8, 0, - str, (int)len, - utf8_str, (int)utf8_len + 1, NULL, false); + utf8_len = (size_t)WideCharToMultiByte(CP_UTF8, 0, str, + (int)len, utf8_str, + (int)utf8_len + 1, NULL, + false); if (!utf8_len) { bfree(utf8_str); @@ -137,16 +122,16 @@ static char *wide_to_utf8(const wchar_t *str, size_t len) static char *convert_utf16_be_to_utf8(FT_SfntName *sfnt_name) { - size_t utf16_len = sfnt_name->string_len / 2; + size_t utf16_len = sfnt_name->string_len / 2; wchar_t *utf16_str = malloc((utf16_len + 1) * sizeof(wchar_t)); - char *utf8_str = NULL; + char *utf8_str = NULL; utf16_str[utf16_len] = 0; /* convert to little endian */ for (size_t i = 0; i < utf16_len; i++) { - size_t pos = i * 2; - wchar_t ch = *(wchar_t *)&sfnt_name->string[pos]; + size_t pos = i * 2; + wchar_t ch = *(wchar_t *)&sfnt_name->string[pos]; utf16_str[i] = ((ch >> 8) & 0xFF) | ((ch << 8) & 0xFF00); } @@ -159,28 +144,27 @@ static char *convert_utf16_be_to_utf8(FT_SfntName *sfnt_name) char *sfnt_name_to_utf8(FT_SfntName *sfnt_name) { - unsigned int code_page = get_code_page_for_font( - sfnt_name->platform_id, - sfnt_name->encoding_id, - sfnt_name->language_id); + unsigned int code_page = get_code_page_for_font(sfnt_name->platform_id, + sfnt_name->encoding_id, + sfnt_name->language_id); - char *utf8_str = NULL; + char *utf8_str = NULL; wchar_t *utf16_str; - size_t utf16_len; + size_t utf16_len; if (code_page == 1201) return convert_utf16_be_to_utf8(sfnt_name); else if (code_page == 0) return NULL; - utf16_len = MultiByteToWideChar(code_page, 0, - (char*)sfnt_name->string, sfnt_name->string_len, - NULL, 0); + utf16_len = MultiByteToWideChar(code_page, 0, (char *)sfnt_name->string, + sfnt_name->string_len, NULL, 0); if (utf16_len) { utf16_str = malloc((utf16_len + 1) * sizeof(wchar_t)); utf16_len = MultiByteToWideChar(code_page, 0, - (char*)sfnt_name->string, sfnt_name->string_len, - utf16_str, (int)utf16_len); + (char *)sfnt_name->string, + sfnt_name->string_len, + utf16_str, (int)utf16_len); if (utf16_len) { utf16_str[utf16_len] = 0; @@ -195,15 +179,15 @@ char *sfnt_name_to_utf8(FT_SfntName *sfnt_name) uint32_t get_font_checksum(void) { - uint32_t checksum = 0; - struct dstr path = {0}; - HANDLE handle; + uint32_t checksum = 0; + struct dstr path = {0}; + HANDLE handle; WIN32_FIND_DATAA wfd; dstr_reserve(&path, MAX_PATH); HRESULT res = SHGetFolderPathA(NULL, CSIDL_FONTS, NULL, - SHGFP_TYPE_CURRENT, path.array); + SHGFP_TYPE_CURRENT, path.array); if (res != S_OK) { blog(LOG_WARNING, "Error finding windows font folder"); return 0; @@ -220,9 +204,9 @@ uint32_t get_font_checksum(void) do { checksum = calc_crc32(checksum, &wfd.ftLastWriteTime, - sizeof(FILETIME)); + sizeof(FILETIME)); checksum = calc_crc32(checksum, wfd.cFileName, - strlen(wfd.cFileName)); + strlen(wfd.cFileName)); } while (FindNextFileA(handle, &wfd)); FindClose(handle); @@ -234,14 +218,14 @@ free_string: void load_os_font_list(void) { - struct dstr path = {0}; - HANDLE handle; + struct dstr path = {0}; + HANDLE handle; WIN32_FIND_DATAA wfd; dstr_reserve(&path, MAX_PATH); HRESULT res = SHGetFolderPathA(NULL, CSIDL_FONTS, NULL, - SHGFP_TYPE_CURRENT, path.array); + SHGFP_TYPE_CURRENT, path.array); if (res != S_OK) { blog(LOG_WARNING, "Error finding windows font folder"); return; @@ -271,7 +255,7 @@ void load_os_font_list(void) while (idx < max_faces) { FT_Error ret = FT_New_Face(ft2_lib, full_path.array, - idx, &face); + idx, &face); if (ret != 0) break; diff --git a/plugins/text-freetype2/find-font.c b/plugins/text-freetype2/find-font.c index d9e7750..557abf7 100644 --- a/plugins/text-freetype2/find-font.c +++ b/plugins/text-freetype2/find-font.c @@ -12,7 +12,7 @@ static inline bool read_data(struct serializer *s, void *data, size_t size) } static inline bool write_data(struct serializer *s, const void *data, - size_t size) + size_t size) { return s_write(s, data, size) == size; } @@ -56,20 +56,23 @@ static bool load_cached_font_list(struct serializer *s) int count; success = read_var(s, count); - if (!success) return false; + if (!success) + return false; da_init(font_list); da_resize(font_list, count); -#define do_read(var) \ +#define do_read(var) \ success = read_var(s, var); \ - if (!success) break + if (!success) \ + break for (int i = 0; i < count; i++) { struct font_path_info *info = &font_list.array[i]; success = read_str(s, &info->face_and_style); - if (!success) break; + if (!success) + break; do_read(info->full_len); do_read(info->face_len); @@ -78,13 +81,15 @@ static bool load_cached_font_list(struct serializer *s) info->sizes = bmalloc(sizeof(int) * info->num_sizes); success = read_data(s, info->sizes, - sizeof(int) * info->num_sizes); - if (!success) break; + sizeof(int) * info->num_sizes); + if (!success) + break; do_read(info->bold); success = read_str(s, &info->path); - if (!success) break; + if (!success) + break; do_read(info->italic); do_read(info->index); @@ -149,29 +154,34 @@ void save_font_list(void) bool success = false; if (font_checksum) - success = file_output_serializer_init_safe(&s, file_name, - "tmp"); + success = + file_output_serializer_init_safe(&s, file_name, "tmp"); bfree(file_name); if (!success) return; success = write_var(&s, font_cache_ver); - if (!success) return; + if (!success) + return; success = write_var(&s, font_checksum); - if (!success) return; + if (!success) + return; success = write_var(&s, font_count); - if (!success) return; + if (!success) + return; -#define do_write(var) \ +#define do_write(var) \ success = write_var(&s, var); \ - if (!success) break + if (!success) \ + break for (size_t i = 0; i < font_list.num; i++) { struct font_path_info *info = &font_list.array[i]; success = write_str(&s, info->face_and_style); - if (!success) break; + if (!success) + break; do_write(info->full_len); do_write(info->face_len); @@ -179,13 +189,15 @@ void save_font_list(void) do_write(info->num_sizes); success = write_data(&s, info->sizes, - sizeof(int) * info->num_sizes); - if (!success) break; + sizeof(int) * info->num_sizes); + if (!success) + break; do_write(info->bold); success = write_str(&s, info->path); - if (!success) break; + if (!success) + break; do_write(info->italic); do_write(info->index); @@ -202,7 +214,7 @@ static void create_bitmap_sizes(struct font_path_info *info, FT_Face face) if (!info->is_bitmap) { info->num_sizes = 0; - info->sizes = NULL; + info->sizes = NULL; return; } @@ -214,15 +226,12 @@ static void create_bitmap_sizes(struct font_path_info *info, FT_Face face) da_push_back(sizes, &val); } - info->sizes = sizes.array; + info->sizes = sizes.array; info->num_sizes = (uint32_t)face->num_fixed_sizes; } -static void add_font_path(FT_Face face, - FT_Long idx, - const char *family_in, - const char *style_in, - const char *path) +static void add_font_path(FT_Face face, FT_Long idx, const char *family_in, + const char *style_in, const char *path) { struct dstr face_and_style = {0}; struct font_path_info info; @@ -249,15 +258,15 @@ static void add_font_path(FT_Face face, } info.face_and_style = face_and_style.array; - info.full_len = (uint32_t)face_and_style.len; - info.face_len = (uint32_t)strlen(family_in); + info.full_len = (uint32_t)face_and_style.len; + info.face_len = (uint32_t)strlen(family_in); - info.is_bitmap = !!(face->face_flags & FT_FACE_FLAG_FIXED_SIZES); - info.bold = !!(face->style_flags & FT_STYLE_FLAG_BOLD); - info.italic = !!(face->style_flags & FT_STYLE_FLAG_ITALIC); - info.index = idx; + info.is_bitmap = !!(face->face_flags & FT_FACE_FLAG_FIXED_SIZES); + info.bold = !!(face->style_flags & FT_STYLE_FLAG_BOLD); + info.italic = !!(face->style_flags & FT_STYLE_FLAG_ITALIC); + info.index = idx; - info.path = bstrdup(path); + info.path = bstrdup(path); create_bitmap_sizes(&info, face); da_push_back(font_list, &info); @@ -271,15 +280,15 @@ static void add_font_path(FT_Face face, void build_font_path_info(FT_Face face, FT_Long idx, const char *path) { FT_UInt num_names = FT_Get_Sfnt_Name_Count(face); - DARRAY(char*) family_names; + DARRAY(char *) family_names; da_init(family_names); da_push_back(family_names, &face->family_name); for (FT_UInt i = 0; i < num_names; i++) { FT_SfntName name; - char *family; - FT_Error ret = FT_Get_Sfnt_Name(face, i, &name); + char *family; + FT_Error ret = FT_Get_Sfnt_Name(face, i, &name); if (ret != 0 || name.name_id != TT_NAME_ID_FONT_FAMILY) continue; @@ -302,7 +311,7 @@ void build_font_path_info(FT_Face face, FT_Long idx, const char *path) for (size_t i = 0; i < family_names.num; i++) { add_font_path(face, idx, family_names.array[i], - face->style_name, path); + face->style_name, path); /* first item isn't our allocation */ if (i > 0) @@ -339,14 +348,14 @@ static inline size_t get_rating(struct font_path_info *info, struct dstr *cmp) } const char *get_font_path(const char *family, uint16_t size, const char *style, - uint32_t flags, FT_Long *idx) + uint32_t flags, FT_Long *idx) { - const char *best_path = NULL; - double best_rating = 0.0; + const char *best_path = NULL; + double best_rating = 0.0; struct dstr face_and_style = {0}; - struct dstr style_str = {0}; - bool bold = !!(flags & OBS_FONT_BOLD); - bool italic = !!(flags & OBS_FONT_ITALIC); + struct dstr style_str = {0}; + bool bold = !!(flags & OBS_FONT_BOLD); + bool italic = !!(flags & OBS_FONT_ITALIC); if (!family || !*family) return NULL; @@ -383,12 +392,14 @@ const char *get_font_path(const char *family, uint16_t size, const char *style, rating /= (double)(best_diff + 1.0); } - if (info->bold == bold) rating += 1.0; - if (info->italic == italic) rating += 1.0; + if (info->bold == bold) + rating += 1.0; + if (info->italic == italic) + rating += 1.0; if (rating > best_rating) { - best_path = info->path; - *idx = info->index; + best_path = info->path; + *idx = info->index; best_rating = rating; } } diff --git a/plugins/text-freetype2/find-font.h b/plugins/text-freetype2/find-font.h index 198fb15..43a003f 100644 --- a/plugins/text-freetype2/find-font.h +++ b/plugins/text-freetype2/find-font.h @@ -9,19 +9,19 @@ #include struct font_path_info { - char *face_and_style; + char *face_and_style; uint32_t full_len; uint32_t face_len; - bool is_bitmap; + bool is_bitmap; uint32_t num_sizes; - int *sizes; + int *sizes; - bool bold; - bool italic; + bool bold; + bool italic; - char *path; - FT_Long index; + char *path; + FT_Long index; }; static inline void font_path_info_free(struct font_path_info *info) @@ -38,4 +38,5 @@ extern bool load_cached_os_font_list(void); extern void load_os_font_list(void); extern void free_os_font_list(void); extern const char *get_font_path(const char *family, uint16_t size, - const char *style, uint32_t flags, FT_Long *idx); + const char *style, uint32_t flags, + FT_Long *idx); diff --git a/plugins/text-freetype2/obs-convenience.c b/plugins/text-freetype2/obs-convenience.c index 99aaf9b..2670e69 100644 --- a/plugins/text-freetype2/obs-convenience.c +++ b/plugins/text-freetype2/obs-convenience.c @@ -21,7 +21,8 @@ along with this program. If not, see . #include #include "obs-convenience.h" -gs_vertbuffer_t *create_uv_vbuffer(uint32_t num_verts, bool add_color) { +gs_vertbuffer_t *create_uv_vbuffer(uint32_t num_verts, bool add_color) +{ obs_enter_graphics(); gs_vertbuffer_t *tmp = NULL; @@ -36,13 +37,13 @@ gs_vertbuffer_t *create_uv_vbuffer(uint32_t num_verts, bool add_color) { vrect->tvarray[0].width = 2; vrect->tvarray[0].array = bmalloc(sizeof(struct vec2) * num_verts); if (add_color) - vrect->colors = (uint32_t *)bmalloc - (sizeof(uint32_t)* num_verts); + vrect->colors = + (uint32_t *)bmalloc(sizeof(uint32_t) * num_verts); memset(vrect->points, 0, sizeof(struct vec3) * num_verts); memset(vrect->tvarray[0].array, 0, sizeof(struct vec2) * num_verts); if (add_color) - memset(vrect->colors, 0, sizeof(uint32_t)* num_verts); + memset(vrect->colors, 0, sizeof(uint32_t) * num_verts); tmp = gs_vertexbuffer_create(vrect, GS_DYNAMIC); @@ -56,14 +57,15 @@ gs_vertbuffer_t *create_uv_vbuffer(uint32_t num_verts, bool add_color) { } void draw_uv_vbuffer(gs_vertbuffer_t *vbuf, gs_texture_t *tex, - gs_effect_t *effect, uint32_t num_verts) + gs_effect_t *effect, uint32_t num_verts) { - gs_texture_t *texture = tex; + gs_texture_t *texture = tex; gs_technique_t *tech = gs_effect_get_technique(effect, "Draw"); - gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); - size_t passes; + gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); + size_t passes; - if (vbuf == NULL || tex == NULL) return; + if (vbuf == NULL || tex == NULL) + return; gs_vertexbuffer_flush(vbuf); gs_load_vertexbuffer(vbuf); diff --git a/plugins/text-freetype2/obs-convenience.h b/plugins/text-freetype2/obs-convenience.h index 3da3b98..f004686 100644 --- a/plugins/text-freetype2/obs-convenience.h +++ b/plugins/text-freetype2/obs-convenience.h @@ -21,10 +21,10 @@ along with this program. If not, see . gs_vertbuffer_t *create_uv_vbuffer(uint32_t num_verts, bool add_color); void draw_uv_vbuffer(gs_vertbuffer_t *vbuf, gs_texture_t *tex, - gs_effect_t *effect, uint32_t num_verts); + gs_effect_t *effect, uint32_t num_verts); -#define set_v3_rect(a, x, y, w, h) \ - vec3_set(a, x, y, 0.0f); \ +#define set_v3_rect(a, x, y, w, h) \ + vec3_set(a, x, y, 0.0f); \ vec3_set(a + 1, x + w, y, 0.0f); \ vec3_set(a + 2, x, y + h, 0.0f); \ vec3_set(a + 3, x, y + h, 0.0f); \ @@ -32,14 +32,14 @@ void draw_uv_vbuffer(gs_vertbuffer_t *vbuf, gs_texture_t *tex, vec3_set(a + 5, x + w, y + h, 0.0f); #define set_v2_uv(a, u, v, u2, v2) \ - vec2_set(a, u, v); \ - vec2_set(a + 1, u2, v); \ - vec2_set(a + 2, u, v2); \ - vec2_set(a + 3, u, v2); \ - vec2_set(a + 4, u2, v); \ + vec2_set(a, u, v); \ + vec2_set(a + 1, u2, v); \ + vec2_set(a + 2, u, v2); \ + vec2_set(a + 3, u, v2); \ + vec2_set(a + 4, u2, v); \ vec2_set(a + 5, u2, v2); #define set_rect_colors2(a, c1, c2) \ - uint32_t *b = a; \ - b[0] = b[1] = b[4] = c1; \ + uint32_t *b = a; \ + b[0] = b[1] = b[4] = c1; \ b[2] = b[3] = b[5] = c2; diff --git a/plugins/text-freetype2/text-freetype2.c b/plugins/text-freetype2/text-freetype2.c index 9940ec7..bc2dd18 100644 --- a/plugins/text-freetype2/text-freetype2.c +++ b/plugins/text-freetype2/text-freetype2.c @@ -40,9 +40,9 @@ static struct obs_source_info freetype2_source_info = { .type = OBS_SOURCE_TYPE_INPUT, .output_flags = OBS_SOURCE_VIDEO | #ifdef _WIN32 - OBS_SOURCE_DEPRECATED | + OBS_SOURCE_DEPRECATED | #endif - OBS_SOURCE_CUSTOM_DRAW, + OBS_SOURCE_CUSTOM_DRAW, .get_name = ft2_source_get_name, .create = ft2_source_create, .destroy = ft2_source_destroy, @@ -128,42 +128,38 @@ static obs_properties_t *ft2_source_properties(void *unused) // Better/pixel shader outline/drop shadow // Some way to pull text files from network, I dunno - obs_properties_add_font(props, "font", - obs_module_text("Font")); + obs_properties_add_font(props, "font", obs_module_text("Font")); - obs_properties_add_text(props, "text", - obs_module_text("Text"), OBS_TEXT_MULTILINE); + obs_properties_add_text(props, "text", obs_module_text("Text"), + OBS_TEXT_MULTILINE); obs_properties_add_bool(props, "from_file", - obs_module_text("ReadFromFile")); + obs_module_text("ReadFromFile")); obs_properties_add_bool(props, "log_mode", - obs_module_text("ChatLogMode")); + obs_module_text("ChatLogMode")); obs_properties_add_int(props, "log_lines", - obs_module_text("ChatLogLines"), 1, 1000, 1); + obs_module_text("ChatLogLines"), 1, 1000, 1); - obs_properties_add_path(props, - "text_file", obs_module_text("TextFile"), - OBS_PATH_FILE, obs_module_text("TextFileFilter"), NULL); + obs_properties_add_path(props, "text_file", obs_module_text("TextFile"), + OBS_PATH_FILE, + obs_module_text("TextFileFilter"), NULL); - obs_properties_add_color(props, "color1", - obs_module_text("Color1")); + obs_properties_add_color(props, "color1", obs_module_text("Color1")); - obs_properties_add_color(props, "color2", - obs_module_text("Color2")); + obs_properties_add_color(props, "color2", obs_module_text("Color2")); - obs_properties_add_bool(props, "outline", - obs_module_text("Outline")); + obs_properties_add_bool(props, "outline", obs_module_text("Outline")); obs_properties_add_bool(props, "drop_shadow", - obs_module_text("DropShadow")); + obs_module_text("DropShadow")); obs_properties_add_int(props, "custom_width", - obs_module_text("CustomWidth"), 0, 4096, 1); + obs_module_text("CustomWidth"), 0, 4096, 1); obs_properties_add_bool(props, "word_wrap", - obs_module_text("WordWrap")); + obs_module_text("WordWrap")); return props; } @@ -220,17 +216,22 @@ static void ft2_source_destroy(void *data) static void ft2_source_render(void *data, gs_effect_t *effect) { struct ft2_source *srcdata = data; - if (srcdata == NULL) return; + if (srcdata == NULL) + return; - if (srcdata->tex == NULL || srcdata->vbuf == NULL) return; - if (srcdata->text == NULL || *srcdata->text == 0) return; + if (srcdata->tex == NULL || srcdata->vbuf == NULL) + return; + if (srcdata->text == NULL || *srcdata->text == 0) + return; gs_reset_blend_state(); - if (srcdata->outline_text) draw_outlines(srcdata); - if (srcdata->drop_shadow) draw_drop_shadow(srcdata); + if (srcdata->outline_text) + draw_outlines(srcdata); + if (srcdata->drop_shadow) + draw_drop_shadow(srcdata); - draw_uv_vbuffer(srcdata->vbuf, srcdata->tex, - srcdata->draw_effect, (uint32_t)wcslen(srcdata->text) * 6); + draw_uv_vbuffer(srcdata->vbuf, srcdata->tex, srcdata->draw_effect, + (uint32_t)wcslen(srcdata->text) * 6); UNUSED_PARAMETER(effect); } @@ -238,8 +239,10 @@ static void ft2_source_render(void *data, gs_effect_t *effect) static void ft2_video_tick(void *data, float seconds) { struct ft2_source *srcdata = data; - if (srcdata == NULL) return; - if (!srcdata->from_file || !srcdata->text_file) return; + if (srcdata == NULL) + return; + if (!srcdata->from_file || !srcdata->text_file) + return; if (os_gettime_ns() - srcdata->last_checked >= 1000000000) { time_t t = get_modified_timestamp(srcdata->text_file); @@ -250,7 +253,7 @@ static void ft2_video_tick(void *data, float seconds) read_from_end(srcdata, srcdata->text_file); else load_text_from_file(srcdata, - srcdata->text_file); + srcdata->text_file); cache_glyphs(srcdata, srcdata->text); set_up_vertex_buffer(srcdata); srcdata->update_file = false; @@ -269,7 +272,8 @@ static bool init_font(struct ft2_source *srcdata) { FT_Long index; const char *path = get_font_path(srcdata->font_name, srcdata->font_size, - srcdata->font_style, srcdata->font_flags, &index); + srcdata->font_style, + srcdata->font_flags, &index); if (!path) return false; @@ -290,10 +294,10 @@ static void ft2_source_update(void *data, obs_data_t *settings) uint32_t color[2]; uint32_t custom_width = 0; - const char *font_name = obs_data_get_string(font_obj, "face"); + const char *font_name = obs_data_get_string(font_obj, "face"); const char *font_style = obs_data_get_string(font_obj, "style"); - uint16_t font_size = (uint16_t)obs_data_get_int(font_obj, "size"); - uint32_t font_flags = (uint32_t)obs_data_get_int(font_obj, "flags"); + uint16_t font_size = (uint16_t)obs_data_get_int(font_obj, "size"); + uint32_t font_flags = (uint32_t)obs_data_get_int(font_obj, "flags"); if (!font_obj) return; @@ -311,8 +315,7 @@ static void ft2_source_update(void *data, obs_data_t *settings) srcdata->custom_width = custom_width; vbuf_needs_update = true; } - } - else { + } else { if (srcdata->custom_width >= 100) vbuf_needs_update = true; srcdata->custom_width = 0; @@ -339,14 +342,14 @@ static void ft2_source_update(void *data, obs_data_t *settings) } srcdata->log_mode = chat_log_mode; - if (ft2_lib == NULL) goto error; + if (ft2_lib == NULL) + goto error; if (srcdata->draw_effect == NULL) { char *effect_file = NULL; char *error_string = NULL; - effect_file = - obs_module_file("text_default.effect"); + effect_file = obs_module_file("text_default.effect"); if (effect_file) { obs_enter_graphics(); @@ -360,18 +363,17 @@ static void ft2_source_update(void *data, obs_data_t *settings) } } - if (srcdata->font_size != font_size || - srcdata->from_file != from_file) + if (srcdata->font_size != font_size || srcdata->from_file != from_file) vbuf_needs_update = true; srcdata->file_load_failed = false; srcdata->from_file = from_file; if (srcdata->font_name != NULL) { - if (strcmp(font_name, srcdata->font_name) == 0 && + if (strcmp(font_name, srcdata->font_name) == 0 && strcmp(font_style, srcdata->font_style) == 0 && font_flags == srcdata->font_flags && - font_size == srcdata->font_size) + font_size == srcdata->font_size) goto skip_font_load; bfree(srcdata->font_name); @@ -382,17 +384,16 @@ static void ft2_source_update(void *data, obs_data_t *settings) vbuf_needs_update = true; } - srcdata->font_name = bstrdup(font_name); + srcdata->font_name = bstrdup(font_name); srcdata->font_style = bstrdup(font_style); - srcdata->font_size = font_size; + srcdata->font_size = font_size; srcdata->font_flags = font_flags; if (!init_font(srcdata) || srcdata->font_face == NULL) { blog(LOG_WARNING, "FT2-text: Failed to load font %s", - srcdata->font_name); + srcdata->font_name); goto error; - } - else { + } else { FT_Set_Pixel_Sizes(srcdata->font_face, 0, srcdata->font_size); FT_Select_Charmap(srcdata->font_face, FT_ENCODING_UNICODE); } @@ -417,14 +418,15 @@ skip_font_load: srcdata->text = NULL; os_utf8_to_wcs_ptr(emptystr, strlen(emptystr), - &srcdata->text); - blog(LOG_WARNING, "FT2-text: Failed to open %s for " - "reading", tmp); - } - else { + &srcdata->text); + blog(LOG_WARNING, + "FT2-text: Failed to open %s for " + "reading", + tmp); + } else { if (srcdata->text_file != NULL && - strcmp(srcdata->text_file, tmp) == 0 && - !vbuf_needs_update) + strcmp(srcdata->text_file, tmp) == 0 && + !vbuf_needs_update) goto error; bfree(srcdata->text_file); @@ -436,10 +438,10 @@ skip_font_load: load_text_from_file(srcdata, tmp); srcdata->last_checked = os_gettime_ns(); } - } - else { + } else { const char *tmp = obs_data_get_string(settings, "text"); - if (!tmp || !*tmp) goto error; + if (!tmp || !*tmp) + goto error; if (srcdata->text != NULL) { bfree(srcdata->text); diff --git a/plugins/text-freetype2/text-freetype2.h b/plugins/text-freetype2/text-freetype2.h index 654b303..b9af53b 100644 --- a/plugins/text-freetype2/text-freetype2.h +++ b/plugins/text-freetype2/text-freetype2.h @@ -30,8 +30,8 @@ struct glyph_info { }; struct ft2_source { - char *font_name; - char *font_style; + char *font_name; + char *font_style; uint16_t font_size; uint32_t font_flags; @@ -54,7 +54,7 @@ struct ft2_source { struct glyph_info *cacheglyphs[num_cache_slots]; - FT_Face font_face; + FT_Face font_face; uint8_t *texbuf; gs_vertbuffer_t *vbuf; diff --git a/plugins/text-freetype2/text-functionality.c b/plugins/text-freetype2/text-functionality.c index 36c9721..d46a533 100644 --- a/plugins/text-freetype2/text-functionality.c +++ b/plugins/text-freetype2/text-functionality.c @@ -23,8 +23,8 @@ along with this program. If not, see . #include "text-freetype2.h" #include "obs-convenience.h" -float offsets[16] = { -2.0f, 0.0f, 0.0f, -2.0f, 2.0f, 0.0f, 2.0f, 0.0f, - 0.0f, 2.0f, 0.0f, 2.0f, -2.0f, 0.0f, -2.0f, 0.0f }; +float offsets[16] = {-2.0f, 0.0f, 0.0f, -2.0f, 2.0f, 0.0f, 2.0f, 0.0f, + 0.0f, 2.0f, 0.0f, 2.0f, -2.0f, 0.0f, -2.0f, 0.0f}; extern uint32_t texbuf_w, texbuf_h; @@ -44,10 +44,10 @@ void draw_outlines(struct ft2_source *srcdata) gs_matrix_push(); for (int32_t i = 0; i < 8; i++) { gs_matrix_translate3f(offsets[i * 2], offsets[(i * 2) + 1], - 0.0f); + 0.0f); draw_uv_vbuffer(srcdata->vbuf, srcdata->tex, - srcdata->draw_effect, - (uint32_t)wcslen(srcdata->text) * 6); + srcdata->draw_effect, + (uint32_t)wcslen(srcdata->text) * 6); } gs_matrix_identity(); gs_matrix_pop(); @@ -70,8 +70,8 @@ void draw_drop_shadow(struct ft2_source *srcdata) gs_matrix_push(); gs_matrix_translate3f(4.0f, 4.0f, 0.0f); - draw_uv_vbuffer(srcdata->vbuf, srcdata->tex, - srcdata->draw_effect, (uint32_t)wcslen(srcdata->text) * 6); + draw_uv_vbuffer(srcdata->vbuf, srcdata->tex, srcdata->draw_effect, + (uint32_t)wcslen(srcdata->text) * 6); gs_matrix_identity(); gs_matrix_pop(); @@ -105,16 +105,19 @@ void set_up_vertex_buffer(struct ft2_source *srcdata) return; } - srcdata->vbuf = create_uv_vbuffer((uint32_t)wcslen(srcdata->text) * 6, - true); + srcdata->vbuf = + create_uv_vbuffer((uint32_t)wcslen(srcdata->text) * 6, true); - if (srcdata->custom_width <= 100) goto skip_word_wrap; - if (!srcdata->word_wrap) goto skip_word_wrap; + if (srcdata->custom_width <= 100) + goto skip_word_wrap; + if (!srcdata->word_wrap) + goto skip_word_wrap; len = wcslen(srcdata->text); for (uint32_t i = 0; i <= len; i++) { - if (i == wcslen(srcdata->text)) goto eos_check; + if (i == wcslen(srcdata->text)) + goto eos_check; if (srcdata->text[i] != L' ' && srcdata->text[i] != L'\n') goto next_char; @@ -125,7 +128,8 @@ void set_up_vertex_buffer(struct ft2_source *srcdata) srcdata->text[space_pos] = L'\n'; x = 0; } - if (i == wcslen(srcdata->text)) goto eos_skip; + if (i == wcslen(srcdata->text)) + goto eos_skip; x += word_width; word_width = 0; @@ -134,8 +138,8 @@ void set_up_vertex_buffer(struct ft2_source *srcdata) if (srcdata->text[i] == L' ') space_pos = i; next_char:; - glyph_index = FT_Get_Char_Index(srcdata->font_face, - srcdata->text[i]); + glyph_index = + FT_Get_Char_Index(srcdata->font_face, srcdata->text[i]); word_width += src_glyph->xadv; eos_skip:; } @@ -148,7 +152,8 @@ skip_word_wrap:; void fill_vertex_buffer(struct ft2_source *srcdata) { struct gs_vb_data *vdata = gs_vertexbuffer_get_data(srcdata->vbuf); - if (vdata == NULL || !srcdata->text) return; + if (vdata == NULL || !srcdata->text) + return; struct vec2 *tvarray = (struct vec2 *)vdata->tvarray[0].array; uint32_t *col = (uint32_t *)vdata->colors; @@ -163,28 +168,35 @@ void fill_vertex_buffer(struct ft2_source *srcdata) bfree(srcdata->colorbuf); srcdata->colorbuf = NULL; } - srcdata->colorbuf = bzalloc(sizeof(uint32_t)*wcslen(srcdata->text) * 6); + srcdata->colorbuf = + bzalloc(sizeof(uint32_t) * wcslen(srcdata->text) * 6); for (size_t i = 0; i < len * 6; i++) { srcdata->colorbuf[i] = 0xFF000000; } for (size_t i = 0; i < len; i++) { add_linebreak:; - if (srcdata->text[i] != L'\n') goto draw_glyph; - dx = 0; i++; + if (srcdata->text[i] != L'\n') + goto draw_glyph; + dx = 0; + i++; dy += srcdata->max_h + 4; - if (i == wcslen(srcdata->text)) goto skip_glyph; - if (srcdata->text[i] == L'\n') goto add_linebreak; + if (i == wcslen(srcdata->text)) + goto skip_glyph; + if (srcdata->text[i] == L'\n') + goto add_linebreak; draw_glyph:; // Skip filthy dual byte Windows line breaks - if (srcdata->text[i] == L'\r') goto skip_glyph; + if (srcdata->text[i] == L'\r') + goto skip_glyph; - glyph_index = FT_Get_Char_Index(srcdata->font_face, - srcdata->text[i]); + glyph_index = + FT_Get_Char_Index(srcdata->font_face, srcdata->text[i]); if (src_glyph == NULL) goto skip_glyph; - if (srcdata->custom_width < 100) goto skip_custom_width; + if (srcdata->custom_width < 100) + goto skip_custom_width; if (dx + src_glyph->xadv > srcdata->custom_width) { dx = 0; @@ -194,18 +206,13 @@ void fill_vertex_buffer(struct ft2_source *srcdata) skip_custom_width:; set_v3_rect(vdata->points + (cur_glyph * 6), - (float)dx + (float)src_glyph->xoff, - (float)dy - (float)src_glyph->yoff, - (float)src_glyph->w, - (float)src_glyph->h); - set_v2_uv(tvarray + (cur_glyph * 6), - src_glyph->u, - src_glyph->v, - src_glyph->u2, - src_glyph->v2); - set_rect_colors2(col + (cur_glyph * 6), - srcdata->color[0], - srcdata->color[1]); + (float)dx + (float)src_glyph->xoff, + (float)dy - (float)src_glyph->yoff, + (float)src_glyph->w, (float)src_glyph->h); + set_v2_uv(tvarray + (cur_glyph * 6), src_glyph->u, src_glyph->v, + src_glyph->u2, src_glyph->v2); + set_rect_colors2(col + (cur_glyph * 6), srcdata->color[0], + srcdata->color[1]); dx += src_glyph->xadv; if (dy - (float)src_glyph->yoff + src_glyph->h > max_y) max_y = dy - src_glyph->yoff + src_glyph->h; @@ -228,12 +235,12 @@ void cache_standard_glyphs(struct ft2_source *srcdata) srcdata->texbuf_x = 0; srcdata->texbuf_y = 0; - cache_glyphs(srcdata, L"abcdefghijklmnopqrstuvwxyz" \ - L"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" \ - L"!@#$%^&*()-_=+,<.>/?\\|[]{}`~ \'\"\0"); + cache_glyphs(srcdata, L"abcdefghijklmnopqrstuvwxyz" + L"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" + L"!@#$%^&*()-_=+,<.>/?\\|[]{}`~ \'\"\0"); } -#define glyph_pos x + (y*slot->bitmap.pitch) +#define glyph_pos x + (y * slot->bitmap.pitch) #define buf_pos (dx + x) + ((dy + y) * texbuf_w) void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs) @@ -252,8 +259,8 @@ void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs) size_t len = wcslen(cache_glyphs); for (size_t i = 0; i < len; i++) { - glyph_index = FT_Get_Char_Index(srcdata->font_face, - cache_glyphs[i]); + glyph_index = + FT_Get_Char_Index(srcdata->font_face, cache_glyphs[i]); if (src_glyph != NULL) goto skip_glyph; @@ -264,7 +271,8 @@ void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs) uint32_t g_w = slot->bitmap.width; uint32_t g_h = slot->bitmap.rows; - if (srcdata->max_h < g_h) srcdata->max_h = g_h; + if (srcdata->max_h < g_h) + srcdata->max_h = g_h; if (dx + g_w >= texbuf_w) { dx = 0; @@ -272,7 +280,8 @@ void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs) } if (dy + g_h >= texbuf_h) { - blog(LOG_WARNING, "Out of space trying to render glyphs"); + blog(LOG_WARNING, + "Out of space trying to render glyphs"); break; } @@ -317,8 +326,9 @@ void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs) gs_texture_destroy(tmp_texture); } - srcdata->tex = gs_texture_create(texbuf_w, texbuf_h, - GS_A8, 1, (const uint8_t **)&srcdata->texbuf, 0); + srcdata->tex = gs_texture_create( + texbuf_w, texbuf_h, GS_A8, 1, + (const uint8_t **)&srcdata->texbuf, 0); obs_leave_graphics(); } @@ -336,7 +346,7 @@ time_t get_modified_timestamp(char *filename) return stats.st_mtime; } -static void remove_cr(wchar_t* source) +static void remove_cr(wchar_t *source) { int j = 0; for (int i = 0; source[i] != '\0'; ++i) { @@ -393,9 +403,9 @@ void load_text_from_file(struct ft2_source *srcdata, const char *filename) bfree(srcdata->text); srcdata->text = NULL; } - srcdata->text = bzalloc((strlen(tmp_read) + 1)*sizeof(wchar_t)); - os_utf8_to_wcs(tmp_read, strlen(tmp_read), - srcdata->text, (strlen(tmp_read) + 1)); + srcdata->text = bzalloc((strlen(tmp_read) + 1) * sizeof(wchar_t)); + os_utf8_to_wcs(tmp_read, strlen(tmp_read), srcdata->text, + (strlen(tmp_read) + 1)); remove_cr(srcdata->text); bfree(tmp_read); @@ -431,16 +441,17 @@ void read_from_end(struct ft2_source *srcdata, const char *filename) log_lines = srcdata->log_lines; while (line_breaks <= log_lines && cur_pos != 0) { - if (!utf16) cur_pos--; - else cur_pos -= 2; + if (!utf16) + cur_pos--; + else + cur_pos -= 2; fseek(tmp_file, cur_pos, SEEK_SET); if (!utf16) { bytes_read = fread(&bvalue, 1, 1, tmp_file); if (bytes_read == 1 && bvalue == '\n') line_breaks++; - } - else { + } else { bytes_read = fread(&value, 2, 1, tmp_file); if (bytes_read == 2 && value == L'\n') line_breaks++; @@ -458,8 +469,8 @@ void read_from_end(struct ft2_source *srcdata, const char *filename) srcdata->text = NULL; } srcdata->text = bzalloc(filesize - cur_pos); - bytes_read = fread(srcdata->text, (filesize - cur_pos), 1, - tmp_file); + bytes_read = + fread(srcdata->text, (filesize - cur_pos), 1, tmp_file); remove_cr(srcdata->text); bfree(tmp_read); @@ -476,9 +487,9 @@ void read_from_end(struct ft2_source *srcdata, const char *filename) bfree(srcdata->text); srcdata->text = NULL; } - srcdata->text = bzalloc((strlen(tmp_read) + 1)*sizeof(wchar_t)); - os_utf8_to_wcs(tmp_read, strlen(tmp_read), - srcdata->text, (strlen(tmp_read) + 1)); + srcdata->text = bzalloc((strlen(tmp_read) + 1) * sizeof(wchar_t)); + os_utf8_to_wcs(tmp_read, strlen(tmp_read), srcdata->text, + (strlen(tmp_read) + 1)); remove_cr(srcdata->text); bfree(tmp_read); @@ -499,10 +510,12 @@ uint32_t get_ft2_text_width(wchar_t *text, struct ft2_source *srcdata) glyph_index = FT_Get_Char_Index(srcdata->font_face, text[i]); FT_Load_Glyph(srcdata->font_face, glyph_index, FT_LOAD_DEFAULT); - if (text[i] == L'\n') w = 0; + if (text[i] == L'\n') + w = 0; else { w += slot->advance.x >> 6; - if (w > max_w) max_w = w; + if (w > max_w) + max_w = w; } } diff --git a/plugins/vlc-video/data/locale/de-DE.ini b/plugins/vlc-video/data/locale/de-DE.ini index 62d0d45..5a5344d 100644 --- a/plugins/vlc-video/data/locale/de-DE.ini +++ b/plugins/vlc-video/data/locale/de-DE.ini @@ -1,4 +1,4 @@ -VLCSource="VLC-Videoquelle" +VLCSource="VLC‐Videoquelle" Playlist="Wiedergabeliste" LoopPlaylist="Wiedergabeliste wiederholen" Shuffle="Wiedergabeliste zufällig wiedergeben" diff --git a/plugins/vlc-video/data/locale/es-ES.ini b/plugins/vlc-video/data/locale/es-ES.ini index 35b0423..9fa307a 100644 --- a/plugins/vlc-video/data/locale/es-ES.ini +++ b/plugins/vlc-video/data/locale/es-ES.ini @@ -13,6 +13,6 @@ Stop="Detener" PlaylistNext="Siguiente" PlaylistPrev="Anterior" AudioTrack="Pista de audio" -SubtitleTrack="Rastreador de subtítulos" +SubtitleTrack="Pista de subtítulos" SubtitleEnable="Subtítulos activados" diff --git a/plugins/vlc-video/data/locale/gl-ES.ini b/plugins/vlc-video/data/locale/gl-ES.ini new file mode 100644 index 0000000..14f8be4 --- /dev/null +++ b/plugins/vlc-video/data/locale/gl-ES.ini @@ -0,0 +1,18 @@ +VLCSource="Fonte de vídeo VLC" +Playlist="Lista de reprodución" +LoopPlaylist="Lista de reprodución en bucle" +Shuffle="Barallar a lista de reprodución" +PlaybackBehavior="Comportamento da visibilidade" +PlaybackBehavior.StopRestart="Parar cando non é visíbel, reiniciar cando sexa visíbel" +PlaybackBehavior.PauseUnpause="Pór en pausa cando non é visíbel, reiniciar cando sexa visíbel" +PlaybackBehavior.AlwaysPlay="Reproducir sempre cando non estea visíbel" +NetworkCaching="Caché de rede (ms)" +PlayPause="Reproducir/Pór en pausa" +Restart="Reiniciar" +Stop="Parar" +PlaylistNext="Seguinte" +PlaylistPrev="Anterior" +AudioTrack="Pista de son" +SubtitleTrack="Pista de subtítulos" +SubtitleEnable="Subtítulos activados" + diff --git a/plugins/vlc-video/data/locale/ko-KR.ini b/plugins/vlc-video/data/locale/ko-KR.ini index c2cc00c..f2bcd5f 100644 --- a/plugins/vlc-video/data/locale/ko-KR.ini +++ b/plugins/vlc-video/data/locale/ko-KR.ini @@ -4,7 +4,7 @@ LoopPlaylist="반복 재생" Shuffle="재생목록 섞기" PlaybackBehavior="표시 동작 설정" PlaybackBehavior.StopRestart="보이지 않을 때 중단, 보이면 재시작" -PlaybackBehavior.PauseUnpause="보이지 않을 때 일시 중지, 보이면 일시 중지 해제" +PlaybackBehavior.PauseUnpause="보이지 않을 때 일시 정지, 보이면 일시 정지 해제" PlaybackBehavior.AlwaysPlay="보이지 않더라도 항상 재생" NetworkCaching="네트워크 캐싱 (ms)" PlayPause="재생/일시정지" diff --git a/plugins/vlc-video/data/locale/ro-RO.ini b/plugins/vlc-video/data/locale/ro-RO.ini index 1988c04..7d3f718 100644 --- a/plugins/vlc-video/data/locale/ro-RO.ini +++ b/plugins/vlc-video/data/locale/ro-RO.ini @@ -1,8 +1,8 @@ -VLCSource="Sursă Video VLC" +VLCSource="Sursă video VLC" Playlist="Listă de redare" LoopPlaylist="Repetă lista de redare" Shuffle="Amestecă lista de redare" -PlaybackBehavior="Comportament vizibilitate" +PlaybackBehavior="Comportamentul vizibilității" PlaybackBehavior.StopRestart="Oprește cand nu este vizibil, repornește cand este vizibil" PlaybackBehavior.PauseUnpause="Pauză cand nu este vizibil, continuă cand este vizibil" PlaybackBehavior.AlwaysPlay="Redă întotdeauna chiar si când nu este vizibil" diff --git a/plugins/vlc-video/data/locale/sl-SI.ini b/plugins/vlc-video/data/locale/sl-SI.ini new file mode 100644 index 0000000..b11793f --- /dev/null +++ b/plugins/vlc-video/data/locale/sl-SI.ini @@ -0,0 +1,18 @@ +VLCSource="Vir videoposnetkov VLC" +Playlist="Seznam predvajanja" +LoopPlaylist="Ponavljaj seznam predvajanja" +Shuffle="Premešaj seznam predvajanja" +PlaybackBehavior="Vedenje vidnosti" +PlaybackBehavior.StopRestart="Ustavi, ko ni vidno; ponovno zaženi, ko je vidno" +PlaybackBehavior.PauseUnpause="Premor, ko ni vidno; nadaljuj, ko je vidno" +PlaybackBehavior.AlwaysPlay="Vedno predvajaj, tudi ko ni vidno" +NetworkCaching="Omrežno medpomnenje (ms)" +PlayPause="Predvajaj/Premor" +Restart="Ponovno zaženi" +Stop="Ustavi" +PlaylistNext="Naslednja" +PlaylistPrev="Prejšnja" +AudioTrack="Zvočna sled" +SubtitleTrack="Sled podnapisov" +SubtitleEnable="Omogoči podnapise" + diff --git a/plugins/vlc-video/vlc-video-plugin.c b/plugins/vlc-video/vlc-video-plugin.c index b0668e0..45e0048 100644 --- a/plugins/vlc-video/vlc-video-plugin.c +++ b/plugins/vlc-video/vlc-video-plugin.c @@ -53,10 +53,12 @@ LIBVLC_MEDIA_LIST_PLAYER_RELEASE libvlc_media_list_player_release_; LIBVLC_MEDIA_LIST_PLAYER_PLAY libvlc_media_list_player_play_; LIBVLC_MEDIA_LIST_PLAYER_PAUSE libvlc_media_list_player_pause_; LIBVLC_MEDIA_LIST_PLAYER_STOP libvlc_media_list_player_stop_; -LIBVLC_MEDIA_LIST_PLAYER_SET_MEDIA_PLAYER libvlc_media_list_player_set_media_player_; +LIBVLC_MEDIA_LIST_PLAYER_SET_MEDIA_PLAYER +libvlc_media_list_player_set_media_player_; LIBVLC_MEDIA_LIST_PLAYER_SET_MEDIA_LIST libvlc_media_list_player_set_media_list_; LIBVLC_MEDIA_LIST_PLAYER_EVENT_MANAGER libvlc_media_list_player_event_manager_; -LIBVLC_MEDIA_LIST_PLAYER_SET_PLAYBACK_MODE libvlc_media_list_player_set_playback_mode_; +LIBVLC_MEDIA_LIST_PLAYER_SET_PLAYBACK_MODE +libvlc_media_list_player_set_playback_mode_; LIBVLC_MEDIA_LIST_PLAYER_NEXT libvlc_media_list_player_next_; LIBVLC_MEDIA_LIST_PLAYER_PREVIOUS libvlc_media_list_player_previous_; @@ -70,14 +72,16 @@ uint64_t time_start = 0; static bool load_vlc_funcs(void) { -#define LOAD_VLC_FUNC(func) \ - do { \ - func ## _ = os_dlsym(libvlc_module, #func); \ - if (!func ## _) { \ - blog(LOG_WARNING, "Could not func VLC function %s, " \ - "VLC loading failed", #func); \ - return false; \ - } \ +#define LOAD_VLC_FUNC(func) \ + do { \ + func##_ = os_dlsym(libvlc_module, #func); \ + if (!func##_) { \ + blog(LOG_WARNING, \ + "Could not func VLC function %s, " \ + "VLC loading failed", \ + #func); \ + return false; \ + } \ } while (false) /* libvlc core */ @@ -133,23 +137,22 @@ static bool load_vlc_funcs(void) static bool load_libvlc_module(void) { #ifdef _WIN32 - char *path_utf8 = NULL; + char *path_utf8 = NULL; wchar_t path[1024]; LSTATUS status; - DWORD size; - HKEY key; + DWORD size; + HKEY key; memset(path, 0, 1024 * sizeof(wchar_t)); - status = RegOpenKeyW(HKEY_LOCAL_MACHINE, - L"SOFTWARE\\VideoLAN\\VLC", - &key); + status = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\VideoLAN\\VLC", + &key); if (status != ERROR_SUCCESS) return false; size = 1024; - status = RegQueryValueExW(key, L"InstallDir", NULL, NULL, - (LPBYTE)path, &size); + status = RegQueryValueExW(key, L"InstallDir", NULL, NULL, (LPBYTE)path, + &size); if (status == ERROR_SUCCESS) { wcscat(path, L"\\libvlc.dll"); os_wcs_to_utf8_ptr(path, 0, &path_utf8); @@ -201,7 +204,7 @@ bool obs_module_load(void) { if (!load_libvlc_module()) { blog(LOG_INFO, "Couldn't find VLC installation, VLC video " - "source disabled"); + "source disabled"); return true; } diff --git a/plugins/vlc-video/vlc-video-plugin.h b/plugins/vlc-video/vlc-video-plugin.h index 189b3f8..085bc12 100644 --- a/plugins/vlc-video/vlc-video-plugin.h +++ b/plugins/vlc-video/vlc-video-plugin.h @@ -22,99 +22,81 @@ typedef libvlc_instance_t *(*LIBVLC_NEW)(int argc, const char *const *argv); typedef void (*LIBVLC_RELEASE)(libvlc_instance_t *p_instance); typedef int64_t (*LIBVLC_CLOCK)(void); typedef int (*LIBVLC_EVENT_ATTACH)(libvlc_event_manager_t *p_event_manager, - libvlc_event_type_t i_event_type, - libvlc_callback_t f_callback, - void *user_data); + libvlc_event_type_t i_event_type, + libvlc_callback_t f_callback, + void *user_data); /* libvlc media */ -typedef libvlc_media_t *(*LIBVLC_MEDIA_NEW_PATH)( - libvlc_instance_t *p_instance, const char *path); +typedef libvlc_media_t *(*LIBVLC_MEDIA_NEW_PATH)(libvlc_instance_t *p_instance, + const char *path); typedef libvlc_media_t *(*LIBVLC_MEDIA_NEW_LOCATION)( - libvlc_instance_t *p_instance, const char *location); -typedef void (*LIBVLC_MEDIA_ADD_OPTION)(libvlc_media_t *p_md, const char *options); + libvlc_instance_t *p_instance, const char *location); +typedef void (*LIBVLC_MEDIA_ADD_OPTION)(libvlc_media_t *p_md, + const char *options); typedef void (*LIBVLC_MEDIA_RETAIN)(libvlc_media_t *p_md); typedef void (*LIBVLC_MEDIA_RELEASE)(libvlc_media_t *p_md); /* libvlc media player */ typedef libvlc_media_player_t *(*LIBVLC_MEDIA_PLAYER_NEW)( - libvlc_instance_t *p_libvlc); + libvlc_instance_t *p_libvlc); typedef libvlc_media_player_t *(*LIBVLC_MEDIA_PLAYER_NEW_FROM_MEDIA)( - libvlc_media_t *p_md); -typedef void (*LIBVLC_MEDIA_PLAYER_RELEASE)( - libvlc_media_player_t *p_mi); -typedef void (*LIBVLC_VIDEO_SET_CALLBACKS)( - libvlc_media_player_t *mp, - libvlc_video_lock_cb lock, - libvlc_video_unlock_cb unlock, - libvlc_video_display_cb display, - void *opaque); + libvlc_media_t *p_md); +typedef void (*LIBVLC_MEDIA_PLAYER_RELEASE)(libvlc_media_player_t *p_mi); +typedef void (*LIBVLC_VIDEO_SET_CALLBACKS)(libvlc_media_player_t *mp, + libvlc_video_lock_cb lock, + libvlc_video_unlock_cb unlock, + libvlc_video_display_cb display, + void *opaque); typedef void (*LIBVLC_VIDEO_SET_FORMAT_CALLBACKS)( - libvlc_media_player_t *mp, - libvlc_video_format_cb setup, - libvlc_video_cleanup_cb cleanup); + libvlc_media_player_t *mp, libvlc_video_format_cb setup, + libvlc_video_cleanup_cb cleanup); typedef void (*LIBVLC_AUDIO_SET_CALLBACKS)( - libvlc_media_player_t *mp, - libvlc_audio_play_cb play, - libvlc_audio_pause_cb pause, - libvlc_audio_resume_cb resume, - libvlc_audio_flush_cb flush, - libvlc_audio_drain_cb drain, - void *opaque); + libvlc_media_player_t *mp, libvlc_audio_play_cb play, + libvlc_audio_pause_cb pause, libvlc_audio_resume_cb resume, + libvlc_audio_flush_cb flush, libvlc_audio_drain_cb drain, void *opaque); typedef void (*LIBVLC_AUDIO_SET_FORMAT_CALLBACKS)( - libvlc_media_player_t *mp, - libvlc_audio_setup_cb setup, - libvlc_audio_cleanup_cb cleanup); -typedef int (*LIBVLC_MEDIA_PLAYER_PLAY)( - libvlc_media_player_t *p_mi); -typedef void (*LIBVLC_MEDIA_PLAYER_STOP)( - libvlc_media_player_t *p_mi); + libvlc_media_player_t *mp, libvlc_audio_setup_cb setup, + libvlc_audio_cleanup_cb cleanup); +typedef int (*LIBVLC_MEDIA_PLAYER_PLAY)(libvlc_media_player_t *p_mi); +typedef void (*LIBVLC_MEDIA_PLAYER_STOP)(libvlc_media_player_t *p_mi); typedef libvlc_time_t (*LIBVLC_MEDIA_PLAYER_GET_TIME)( - libvlc_media_player_t *p_mi); -typedef int (*LIBVLC_VIDEO_GET_SIZE)( - libvlc_media_player_t *p_mi, - unsigned num, - unsigned *px, - unsigned *py); + libvlc_media_player_t *p_mi); +typedef int (*LIBVLC_VIDEO_GET_SIZE)(libvlc_media_player_t *p_mi, unsigned num, + unsigned *px, unsigned *py); typedef libvlc_event_manager_t *(*LIBVLC_MEDIA_PLAYER_EVENT_MANAGER)( - libvlc_media_player_t *p_mp); + libvlc_media_player_t *p_mp); /* libvlc media list */ typedef libvlc_media_list_t *(*LIBVLC_MEDIA_LIST_NEW)( - libvlc_instance_t *p_instance); + libvlc_instance_t *p_instance); typedef void (*LIBVLC_MEDIA_LIST_RELEASE)(libvlc_media_list_t *p_ml); typedef int (*LIBVLC_MEDIA_LIST_ADD_MEDIA)(libvlc_media_list_t *p_ml, - libvlc_media_t *p_md); + libvlc_media_t *p_md); typedef void (*LIBVLC_MEDIA_LIST_LOCK)(libvlc_media_list_t *p_ml); typedef void (*LIBVLC_MEDIA_LIST_UNLOCK)(libvlc_media_list_t *p_ml); typedef libvlc_event_manager_t *(*LIBVLC_MEDIA_LIST_EVENT_MANAGER)( - libvlc_media_list_t *p_ml); + libvlc_media_list_t *p_ml); /* libvlc media list player */ typedef libvlc_media_list_player_t *(*LIBVLC_MEDIA_LIST_PLAYER_NEW)( - libvlc_instance_t * p_instance); + libvlc_instance_t *p_instance); typedef void (*LIBVLC_MEDIA_LIST_PLAYER_RELEASE)( - libvlc_media_list_player_t *p_mlp); -typedef void (*LIBVLC_MEDIA_LIST_PLAYER_PLAY)( - libvlc_media_list_player_t *p_mlp); + libvlc_media_list_player_t *p_mlp); +typedef void (*LIBVLC_MEDIA_LIST_PLAYER_PLAY)(libvlc_media_list_player_t *p_mlp); typedef void (*LIBVLC_MEDIA_LIST_PLAYER_PAUSE)( - libvlc_media_list_player_t *p_mlp); -typedef void (*LIBVLC_MEDIA_LIST_PLAYER_STOP)( - libvlc_media_list_player_t *p_mlp); + libvlc_media_list_player_t *p_mlp); +typedef void (*LIBVLC_MEDIA_LIST_PLAYER_STOP)(libvlc_media_list_player_t *p_mlp); typedef void (*LIBVLC_MEDIA_LIST_PLAYER_SET_MEDIA_PLAYER)( - libvlc_media_list_player_t *p_mlp, - libvlc_media_player_t *p_mp); + libvlc_media_list_player_t *p_mlp, libvlc_media_player_t *p_mp); typedef void (*LIBVLC_MEDIA_LIST_PLAYER_SET_MEDIA_LIST)( - libvlc_media_list_player_t *p_mlp, - libvlc_media_list_t *p_mlist); + libvlc_media_list_player_t *p_mlp, libvlc_media_list_t *p_mlist); typedef libvlc_event_manager_t *(*LIBVLC_MEDIA_LIST_PLAYER_EVENT_MANAGER)( - libvlc_media_list_player_t *p_mlp); + libvlc_media_list_player_t *p_mlp); typedef void (*LIBVLC_MEDIA_LIST_PLAYER_SET_PLAYBACK_MODE)( - libvlc_media_list_player_t *p_mlp, - libvlc_playback_mode_t e_mode); -typedef int (*LIBVLC_MEDIA_LIST_PLAYER_NEXT)( - libvlc_media_list_player_t *p_mlp); + libvlc_media_list_player_t *p_mlp, libvlc_playback_mode_t e_mode); +typedef int (*LIBVLC_MEDIA_LIST_PLAYER_NEXT)(libvlc_media_list_player_t *p_mlp); typedef int (*LIBVLC_MEDIA_LIST_PLAYER_PREVIOUS)( - libvlc_media_list_player_t *p_mlp); + libvlc_media_list_player_t *p_mlp); /* -------------------------------------------------------------------- */ @@ -159,82 +141,88 @@ extern LIBVLC_MEDIA_LIST_PLAYER_RELEASE libvlc_media_list_player_release_; extern LIBVLC_MEDIA_LIST_PLAYER_PLAY libvlc_media_list_player_play_; extern LIBVLC_MEDIA_LIST_PLAYER_PAUSE libvlc_media_list_player_pause_; extern LIBVLC_MEDIA_LIST_PLAYER_STOP libvlc_media_list_player_stop_; -extern LIBVLC_MEDIA_LIST_PLAYER_SET_MEDIA_PLAYER libvlc_media_list_player_set_media_player_; -extern LIBVLC_MEDIA_LIST_PLAYER_SET_MEDIA_LIST libvlc_media_list_player_set_media_list_; -extern LIBVLC_MEDIA_LIST_PLAYER_EVENT_MANAGER libvlc_media_list_player_event_manager_; -extern LIBVLC_MEDIA_LIST_PLAYER_SET_PLAYBACK_MODE libvlc_media_list_player_set_playback_mode_; +extern LIBVLC_MEDIA_LIST_PLAYER_SET_MEDIA_PLAYER + libvlc_media_list_player_set_media_player_; +extern LIBVLC_MEDIA_LIST_PLAYER_SET_MEDIA_LIST + libvlc_media_list_player_set_media_list_; +extern LIBVLC_MEDIA_LIST_PLAYER_EVENT_MANAGER + libvlc_media_list_player_event_manager_; +extern LIBVLC_MEDIA_LIST_PLAYER_SET_PLAYBACK_MODE + libvlc_media_list_player_set_playback_mode_; extern LIBVLC_MEDIA_LIST_PLAYER_NEXT libvlc_media_list_player_next_; extern LIBVLC_MEDIA_LIST_PLAYER_PREVIOUS libvlc_media_list_player_previous_; #define EXTENSIONS_AUDIO \ - "*.3ga;" \ - "*.669;" \ - "*.a52;" \ - "*.aac;" \ - "*.ac3;" \ - "*.adt;" \ - "*.adts;" \ - "*.aif;"\ - "*.aifc;"\ - "*.aiff;"\ - "*.amb;" \ - "*.amr;" \ - "*.aob;" \ - "*.ape;" \ - "*.au;" \ - "*.awb;" \ - "*.caf;" \ - "*.dts;" \ - "*.flac;"\ - "*.it;" \ - "*.kar;" \ - "*.m4a;" \ - "*.m4b;" \ - "*.m4p;" \ - "*.m5p;" \ - "*.mid;" \ - "*.mka;" \ - "*.mlp;" \ - "*.mod;" \ - "*.mpa;" \ - "*.mp1;" \ - "*.mp2;" \ - "*.mp3;" \ - "*.mpc;" \ - "*.mpga;" \ - "*.mus;" \ - "*.oga;" \ - "*.ogg;" \ - "*.oma;" \ - "*.opus;" \ - "*.qcp;" \ - "*.ra;" \ - "*.rmi;" \ - "*.s3m;" \ - "*.sid;" \ - "*.spx;" \ - "*.tak;" \ - "*.thd;" \ - "*.tta;" \ - "*.voc;" \ - "*.vqf;" \ - "*.w64;" \ - "*.wav;" \ - "*.wma;" \ - "*.wv;" \ - "*.xa;" \ + "*.3ga;" \ + "*.669;" \ + "*.a52;" \ + "*.aac;" \ + "*.ac3;" \ + "*.adt;" \ + "*.adts;" \ + "*.aif;" \ + "*.aifc;" \ + "*.aiff;" \ + "*.amb;" \ + "*.amr;" \ + "*.aob;" \ + "*.ape;" \ + "*.au;" \ + "*.awb;" \ + "*.caf;" \ + "*.dts;" \ + "*.flac;" \ + "*.it;" \ + "*.kar;" \ + "*.m4a;" \ + "*.m4b;" \ + "*.m4p;" \ + "*.m5p;" \ + "*.mid;" \ + "*.mka;" \ + "*.mlp;" \ + "*.mod;" \ + "*.mpa;" \ + "*.mp1;" \ + "*.mp2;" \ + "*.mp3;" \ + "*.mpc;" \ + "*.mpga;" \ + "*.mus;" \ + "*.oga;" \ + "*.ogg;" \ + "*.oma;" \ + "*.opus;" \ + "*.qcp;" \ + "*.ra;" \ + "*.rmi;" \ + "*.s3m;" \ + "*.sid;" \ + "*.spx;" \ + "*.tak;" \ + "*.thd;" \ + "*.tta;" \ + "*.voc;" \ + "*.vqf;" \ + "*.w64;" \ + "*.wav;" \ + "*.wma;" \ + "*.wv;" \ + "*.xa;" \ "*.xm" -#define EXTENSIONS_VIDEO "*.3g2;*.3gp;*.3gp2;*.3gpp;*.amv;*.asf;*.avi;" \ - "*.bik;*.bin;*.crf;*.divx;*.drc;*.dv;*.evo;*.f4v;*.flv;*.gvi;*.gxf;" \ +#define EXTENSIONS_VIDEO \ + "*.3g2;*.3gp;*.3gp2;*.3gpp;*.amv;*.asf;*.avi;" \ + "*.bik;*.bin;*.crf;*.divx;*.drc;*.dv;*.evo;*.f4v;*.flv;*.gvi;*.gxf;" \ "*.iso;*.m1v;*.m2v;*.m2t;*.m2ts;*.m4v;*.mkv;*.mov;*.mp2;*.mp2v;*.mp4;" \ - "*.mp4v;*.mpe;*.mpeg;*.mpeg1;*.mpeg2;*.mpeg4;*.mpg;*.mpv2;*.mts;" \ - "*.mtv;*.mxf;*.mxg;*.nsv;*.nuv;*.ogg;*.ogm;*.ogv;*.ogx;*.ps;*.rec;" \ - "*.rm;*.rmvb;*.rpl;*.thp;*.tod;*.ts;*.tts;*.txd;*.vob;*.vro;*.webm;" \ + "*.mp4v;*.mpe;*.mpeg;*.mpeg1;*.mpeg2;*.mpeg4;*.mpg;*.mpv2;*.mts;" \ + "*.mtv;*.mxf;*.mxg;*.nsv;*.nuv;*.ogg;*.ogm;*.ogv;*.ogx;*.ps;*.rec;" \ + "*.rm;*.rmvb;*.rpl;*.thp;*.tod;*.ts;*.tts;*.txd;*.vob;*.vro;*.webm;" \ "*.wm;*.wmv;*.wtv;*.xesc" -#define EXTENSIONS_PLAYLIST "*.asx;*.b4s;*.cue;*.ifo;*.m3u;*.m3u8;*.pls;" \ +#define EXTENSIONS_PLAYLIST \ + "*.asx;*.b4s;*.cue;*.ifo;*.m3u;*.m3u8;*.pls;" \ "*.ram;*.rar;*.sdp;*.vlc;*.xspf;*.wax;*.wvx;*.zip;*.conf" -#define EXTENSIONS_MEDIA EXTENSIONS_VIDEO ";" EXTENSIONS_AUDIO ";" \ - EXTENSIONS_PLAYLIST +#define EXTENSIONS_MEDIA \ + EXTENSIONS_VIDEO ";" EXTENSIONS_AUDIO ";" EXTENSIONS_PLAYLIST diff --git a/plugins/vlc-video/vlc-video-source.c b/plugins/vlc-video/vlc-video-source.c index a436e2e..550b04f 100644 --- a/plugins/vlc-video/vlc-video-source.c +++ b/plugins/vlc-video/vlc-video-source.c @@ -4,11 +4,13 @@ #include #include -#define do_log(level, format, ...) \ +#define do_log(level, format, ...) \ blog(level, "[vlc_source: '%s'] " format, \ - obs_source_get_name(ss->source), ##__VA_ARGS__) + obs_source_get_name(ss->source), ##__VA_ARGS__) -#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) + +/* clang-format off */ #define S_PLAYLIST "playlist" #define S_LOOP "loop" @@ -35,6 +37,8 @@ #define T_SUBTITLE_ENABLE T_("SubtitleEnable") #define T_SUBTITLE_TRACK T_("SubtitleTrack") +/* clang-format on */ + /* ------------------------------------------------------------------------- */ struct media_file_data { @@ -94,8 +98,8 @@ static libvlc_media_t *get_media(struct darray *array, const char *path) static inline libvlc_media_t *create_media_from_file(const char *file) { return (file && strstr(file, "://") != NULL) - ? libvlc_media_new_location_(libvlc, file) - : libvlc_media_new_path_(libvlc, file); + ? libvlc_media_new_location_(libvlc, file) + : libvlc_media_new_path_(libvlc, file); } static void free_files(struct darray *array) @@ -113,25 +117,26 @@ static void free_files(struct darray *array) static inline bool chroma_is(const char *chroma, const char *val) { - return *(uint32_t*)chroma == *(uint32_t*)val; + return *(uint32_t *)chroma == *(uint32_t *)val; } static enum video_format convert_vlc_video_format(char *chroma, bool *full) { *full = false; -#define CHROMA_TEST(val, ret) \ - if (chroma_is(chroma, val)) return ret -#define CHROMA_CONV(val, new_val, ret) \ - do { \ - if (chroma_is(chroma, val)) { \ - *(uint32_t*)chroma = *(uint32_t*)new_val; \ - return ret; \ - } \ +#define CHROMA_TEST(val, ret) \ + if (chroma_is(chroma, val)) \ + return ret +#define CHROMA_CONV(val, new_val, ret) \ + do { \ + if (chroma_is(chroma, val)) { \ + *(uint32_t *)chroma = *(uint32_t *)new_val; \ + return ret; \ + } \ } while (false) -#define CHROMA_CONV_FULL(val, new_val, ret) \ - do { \ - *full = true; \ +#define CHROMA_CONV_FULL(val, new_val, ret) \ + do { \ + *full = true; \ CHROMA_CONV(val, new_val, ret); \ } while (false) @@ -205,12 +210,12 @@ static enum video_format convert_vlc_video_format(char *chroma, bool *full) #undef CHROMA_CONV #undef CHROMA_TEST - *(uint32_t*)chroma = *(uint32_t*)"BGRA"; + *(uint32_t *)chroma = *(uint32_t *)"BGRA"; return VIDEO_FORMAT_BGRA; } static inline unsigned get_format_lines(enum video_format format, - unsigned height, size_t plane) + unsigned height, size_t plane) { switch (format) { case VIDEO_FORMAT_I420: @@ -225,7 +230,9 @@ static inline unsigned get_format_lines(enum video_format format, case VIDEO_FORMAT_BGRX: case VIDEO_FORMAT_Y800: return height; - case VIDEO_FORMAT_NONE:; + case VIDEO_FORMAT_NONE: + default: + break; } return 0; @@ -233,14 +240,15 @@ static inline unsigned get_format_lines(enum video_format format, static enum audio_format convert_vlc_audio_format(char *format) { -#define AUDIO_TEST(val, ret) \ - if (chroma_is(format, val)) return ret -#define AUDIO_CONV(val, new_val, ret) \ - do { \ - if (chroma_is(format, val)) { \ - *(uint32_t*)format = *(uint32_t*)new_val; \ - return ret; \ - } \ +#define AUDIO_TEST(val, ret) \ + if (chroma_is(format, val)) \ + return ret +#define AUDIO_CONV(val, new_val, ret) \ + do { \ + if (chroma_is(format, val)) { \ + *(uint32_t *)format = *(uint32_t *)new_val; \ + return ret; \ + } \ } while (false) AUDIO_TEST("S16N", AUDIO_FORMAT_16BIT); @@ -262,7 +270,7 @@ static enum audio_format convert_vlc_audio_format(char *format) #undef AUDIO_CONV #undef AUDIO_TEST - *(uint32_t*)format = *(uint32_t*)"FL32"; + *(uint32_t *)format = *(uint32_t *)"FL32"; return AUDIO_FORMAT_FLOAT; } @@ -286,7 +294,7 @@ static void vlcs_destroy(void *data) libvlc_media_player_release_(c->media_player); } - bfree((void*)c->audio.data[0]); + bfree((void *)c->audio.data[0]); obs_source_frame_free(&c->frame); free_files(&c->files.da); @@ -312,7 +320,8 @@ static void vlcs_video_display(void *data, void *picture) } static unsigned vlcs_video_format(void **p_data, char *chroma, unsigned *width, - unsigned *height, unsigned *pitches, unsigned *lines) + unsigned *height, unsigned *pitches, + unsigned *lines) { struct vlc_source *c = *p_data; enum video_format new_format; @@ -334,25 +343,24 @@ static unsigned vlcs_video_format(void **p_data, char *chroma, unsigned *width, libvlc_video_get_size_(c->media_player, 0, &new_width, &new_height); if (new_width && new_height) { - *width = new_width; + *width = new_width; *height = new_height; } /* don't allocate a new frame if format/width/height hasn't changed */ - if (c->frame.format != new_format || - c->frame.width != *width || + if (c->frame.format != new_format || c->frame.width != *width || c->frame.height != *height) { obs_source_frame_free(&c->frame); obs_source_frame_init(&c->frame, new_format, *width, *height); c->frame.format = new_format; c->frame.full_range = new_range; - range = c->frame.full_range ? - VIDEO_RANGE_FULL : VIDEO_RANGE_PARTIAL; + range = c->frame.full_range ? VIDEO_RANGE_FULL + : VIDEO_RANGE_PARTIAL; video_format_get_parameters(VIDEO_CS_DEFAULT, range, - c->frame.color_matrix, - c->frame.color_range_min, - c->frame.color_range_max); + c->frame.color_matrix, + c->frame.color_range_min, + c->frame.color_range_max); } while (c->frame.data[i]) { @@ -365,17 +373,17 @@ static unsigned vlcs_video_format(void **p_data, char *chroma, unsigned *width, } static void vlcs_audio_play(void *data, const void *samples, unsigned count, - int64_t pts) + int64_t pts) { struct vlc_source *c = data; size_t size = get_audio_size(c->audio.format, c->audio.speakers, count); if (c->audio_capacity < count) { - c->audio.data[0] = brealloc((void*)c->audio.data[0], size); + c->audio.data[0] = brealloc((void *)c->audio.data[0], size); c->audio_capacity = count; } - memcpy((void*)c->audio.data[0], samples, size); + memcpy((void *)c->audio.data[0], samples, size); c->audio.timestamp = (uint64_t)pts * 1000ULL - time_start; c->audio.frames = count; @@ -383,7 +391,7 @@ static void vlcs_audio_play(void *data, const void *samples, unsigned count, } static int vlcs_audio_setup(void **p_data, char *format, unsigned *rate, - unsigned *channels) + unsigned *channels) { struct vlc_source *c = *p_data; enum audio_format new_audio_format; @@ -395,22 +403,22 @@ static int vlcs_audio_setup(void **p_data, char *format, unsigned *rate, /* don't free audio data if the data is the same format */ if (c->audio.format == new_audio_format && c->audio.samples_per_sec == *rate && - c->audio.speakers == (enum speaker_layout)*channels) + c->audio.speakers == (enum speaker_layout) * channels) return 0; c->audio_capacity = 0; - bfree((void*)c->audio.data[0]); + bfree((void *)c->audio.data[0]); memset(&c->audio, 0, sizeof(c->audio)); - c->audio.speakers = (enum speaker_layout)*channels; + c->audio.speakers = (enum speaker_layout) * channels; c->audio.samples_per_sec = *rate; c->audio.format = new_audio_format; return 0; } static void add_file(struct vlc_source *c, struct darray *array, - const char *path, int network_caching, int track_index, - int subtitle_index, bool subtitle_enable) + const char *path, int network_caching, int track_index, + int subtitle_index, bool subtitle_enable) { DARRAY(struct media_file_data) new_files; struct media_file_data data; @@ -438,21 +446,20 @@ static void add_file(struct vlc_source *c, struct darray *array, if (is_url) { struct dstr network_caching_option = {0}; dstr_catf(&network_caching_option, - ":network-caching=%d", network_caching); + ":network-caching=%d", network_caching); libvlc_media_add_option_(new_media, - network_caching_option.array); + network_caching_option.array); dstr_free(&network_caching_option); } - struct dstr track_option = { 0 }; - dstr_catf(&track_option, - ":audio-track=%d", track_index - 1); + struct dstr track_option = {0}; + dstr_catf(&track_option, ":audio-track=%d", track_index - 1); libvlc_media_add_option_(new_media, track_option.array); dstr_free(&track_option); struct dstr sub_option = {0}; if (subtitle_enable) { - dstr_catf(&sub_option, - ":sub-track=%d", subtitle_index - 1); + dstr_catf(&sub_option, ":sub-track=%d", + subtitle_index - 1); } libvlc_media_add_option_(new_media, sub_option.array); dstr_free(&sub_option); @@ -481,8 +488,10 @@ static bool valid_extension(const char *ext) e = strchr(b, ';'); for (;;) { - if (e) dstr_ncopy(&test, b, e - b); - else dstr_copy(&test, b); + if (e) + dstr_ncopy(&test, b, e - b); + else + dstr_copy(&test, b); if (dstr_cmp(&test, ext) == 0) { valid = true; @@ -569,17 +578,15 @@ static void vlcs_update(void *data, obs_data_t *settings) dstr_cat_ch(&dir_path, '/'); dstr_cat(&dir_path, ent->d_name); add_file(c, &new_files.da, dir_path.array, - network_caching, track_index, - subtitle_index, - subtitle_enable); + network_caching, track_index, + subtitle_index, subtitle_enable); } dstr_free(&dir_path); os_closedir(dir); } else { add_file(c, &new_files.da, path, network_caching, - track_index, subtitle_index, - subtitle_enable); + track_index, subtitle_index, subtitle_enable); } obs_data_release(item); @@ -634,19 +641,19 @@ static void vlcs_update(void *data, obs_data_t *settings) libvlc_media_list_lock_(media_list); for (size_t i = 0; i < c->files.num; i++) libvlc_media_list_add_media_(media_list, - c->files.array[i].media); + c->files.array[i].media); libvlc_media_list_unlock_(media_list); libvlc_media_list_player_set_media_list_(c->media_list_player, - media_list); + media_list); libvlc_media_list_release_(media_list); - libvlc_media_list_player_set_playback_mode_(c->media_list_player, - c->loop ? libvlc_playback_mode_loop : - libvlc_playback_mode_default); + libvlc_media_list_player_set_playback_mode_( + c->media_list_player, c->loop ? libvlc_playback_mode_loop + : libvlc_playback_mode_default); - if (c->files.num && - (c->behavior == BEHAVIOR_ALWAYS_PLAY || obs_source_active(c->source))) + if (c->files.num && (c->behavior == BEHAVIOR_ALWAYS_PLAY || + obs_source_active(c->source))) libvlc_media_list_player_play_(c->media_list_player); else obs_source_output_video(c->source, NULL); @@ -701,7 +708,7 @@ static void vlcs_playlist_prev(void *data) } static void vlcs_play_pause_hotkey(void *data, obs_hotkey_id id, - obs_hotkey_t *hotkey, bool pressed) + obs_hotkey_t *hotkey, bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(hotkey); @@ -713,7 +720,7 @@ static void vlcs_play_pause_hotkey(void *data, obs_hotkey_id id, } static void vlcs_restart_hotkey(void *data, obs_hotkey_id id, - obs_hotkey_t *hotkey, bool pressed) + obs_hotkey_t *hotkey, bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(hotkey); @@ -724,8 +731,8 @@ static void vlcs_restart_hotkey(void *data, obs_hotkey_id id, vlcs_restart(c); } -static void vlcs_stop_hotkey(void *data, obs_hotkey_id id, - obs_hotkey_t *hotkey, bool pressed) +static void vlcs_stop_hotkey(void *data, obs_hotkey_id id, obs_hotkey_t *hotkey, + bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(hotkey); @@ -737,7 +744,7 @@ static void vlcs_stop_hotkey(void *data, obs_hotkey_id id, } static void vlcs_playlist_next_hotkey(void *data, obs_hotkey_id id, - obs_hotkey_t *hotkey, bool pressed) + obs_hotkey_t *hotkey, bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(hotkey); @@ -749,7 +756,7 @@ static void vlcs_playlist_next_hotkey(void *data, obs_hotkey_id id, } static void vlcs_playlist_prev_hotkey(void *data, obs_hotkey_id id, - obs_hotkey_t *hotkey, bool pressed) + obs_hotkey_t *hotkey, bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(hotkey); @@ -765,30 +772,25 @@ static void *vlcs_create(obs_data_t *settings, obs_source_t *source) struct vlc_source *c = bzalloc(sizeof(*c)); c->source = source; - c->play_pause_hotkey = obs_hotkey_register_source(source, - "VLCSource.PlayPause", - obs_module_text("PlayPause"), - vlcs_play_pause_hotkey, c); + c->play_pause_hotkey = obs_hotkey_register_source( + source, "VLCSource.PlayPause", obs_module_text("PlayPause"), + vlcs_play_pause_hotkey, c); - c->restart_hotkey = obs_hotkey_register_source(source, - "VLCSource.Restart", - obs_module_text("Restart"), - vlcs_restart_hotkey, c); + c->restart_hotkey = obs_hotkey_register_source( + source, "VLCSource.Restart", obs_module_text("Restart"), + vlcs_restart_hotkey, c); - c->stop_hotkey = obs_hotkey_register_source(source, - "VLCSource.Stop", - obs_module_text("Stop"), - vlcs_stop_hotkey, c); + c->stop_hotkey = obs_hotkey_register_source(source, "VLCSource.Stop", + obs_module_text("Stop"), + vlcs_stop_hotkey, c); - c->playlist_next_hotkey = obs_hotkey_register_source(source, - "VLCSource.PlaylistNext", - obs_module_text("PlaylistNext"), - vlcs_playlist_next_hotkey, c); + c->playlist_next_hotkey = obs_hotkey_register_source( + source, "VLCSource.PlaylistNext", + obs_module_text("PlaylistNext"), vlcs_playlist_next_hotkey, c); - c->playlist_prev_hotkey = obs_hotkey_register_source(source, - "VLCSource.PlaylistPrev", - obs_module_text("PlaylistPrev"), - vlcs_playlist_prev_hotkey, c); + c->playlist_prev_hotkey = obs_hotkey_register_source( + source, "VLCSource.PlaylistPrev", + obs_module_text("PlaylistPrev"), vlcs_playlist_prev_hotkey, c); pthread_mutex_init_value(&c->mutex); if (pthread_mutex_init(&c->mutex, NULL) != 0) @@ -806,23 +808,22 @@ static void *vlcs_create(obs_data_t *settings, obs_source_t *source) goto error; libvlc_media_list_player_set_media_player_(c->media_list_player, - c->media_player); + c->media_player); - libvlc_video_set_callbacks_(c->media_player, - vlcs_video_lock, NULL, vlcs_video_display, - c); - libvlc_video_set_format_callbacks_(c->media_player, - vlcs_video_format, NULL); + libvlc_video_set_callbacks_(c->media_player, vlcs_video_lock, NULL, + vlcs_video_display, c); + libvlc_video_set_format_callbacks_(c->media_player, vlcs_video_format, + NULL); - libvlc_audio_set_callbacks_(c->media_player, - vlcs_audio_play, NULL, NULL, NULL, NULL, c); - libvlc_audio_set_format_callbacks_(c->media_player, - vlcs_audio_setup, NULL); + libvlc_audio_set_callbacks_(c->media_player, vlcs_audio_play, NULL, + NULL, NULL, NULL, c); + libvlc_audio_set_format_callbacks_(c->media_player, vlcs_audio_setup, + NULL); libvlc_event_manager_t *event_manager; event_manager = libvlc_media_player_event_manager_(c->media_player); libvlc_event_attach_(event_manager, libvlc_MediaPlayerEndReached, - vlcs_stopped, c); + vlcs_stopped, c); obs_source_update(source, NULL); @@ -864,7 +865,7 @@ static void vlcs_defaults(obs_data_t *settings) obs_data_set_default_bool(settings, S_LOOP, true); obs_data_set_default_bool(settings, S_SHUFFLE, false); obs_data_set_default_string(settings, S_BEHAVIOR, - S_BEHAVIOR_STOP_RESTART); + S_BEHAVIOR_STOP_RESTART); obs_data_set_default_int(settings, S_NETWORK_CACHING, 400); obs_data_set_default_int(settings, S_TRACK, 1); obs_data_set_default_bool(settings, S_SUBTITLE_ENABLE, false); @@ -900,13 +901,14 @@ static obs_properties_t *vlcs_properties(void *data) } p = obs_properties_add_list(ppts, S_BEHAVIOR, T_BEHAVIOR, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, T_BEHAVIOR_STOP_RESTART, - S_BEHAVIOR_STOP_RESTART); + S_BEHAVIOR_STOP_RESTART); obs_property_list_add_string(p, T_BEHAVIOR_PAUSE_UNPAUSE, - S_BEHAVIOR_PAUSE_UNPAUSE); + S_BEHAVIOR_PAUSE_UNPAUSE); obs_property_list_add_string(p, T_BEHAVIOR_ALWAYS_PLAY, - S_BEHAVIOR_ALWAYS_PLAY); + S_BEHAVIOR_ALWAYS_PLAY); dstr_cat(&filter, "Media Files ("); dstr_copy(&exts, EXTENSIONS_MEDIA); @@ -930,18 +932,18 @@ static obs_properties_t *vlcs_properties(void *data) dstr_cat(&filter, ")"); obs_properties_add_editable_list(ppts, S_PLAYLIST, T_PLAYLIST, - OBS_EDITABLE_LIST_TYPE_FILES_AND_URLS, - filter.array, path.array); + OBS_EDITABLE_LIST_TYPE_FILES_AND_URLS, + filter.array, path.array); dstr_free(&path); dstr_free(&filter); dstr_free(&exts); - obs_properties_add_int(ppts, S_NETWORK_CACHING, T_NETWORK_CACHING, - 100, 60000, 10); + obs_properties_add_int(ppts, S_NETWORK_CACHING, T_NETWORK_CACHING, 100, + 60000, 10); obs_properties_add_int(ppts, S_TRACK, T_TRACK, 1, 10, 1); obs_properties_add_bool(ppts, S_SUBTITLE_ENABLE, T_SUBTITLE_ENABLE); - obs_properties_add_int(ppts, S_SUBTITLE_TRACK, T_SUBTITLE_TRACK, - 1, 10, 1); + obs_properties_add_int(ppts, S_SUBTITLE_TRACK, T_SUBTITLE_TRACK, 1, 10, + 1); return ppts; } @@ -949,9 +951,8 @@ static obs_properties_t *vlcs_properties(void *data) struct obs_source_info vlc_source_info = { .id = "vlc_source", .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_ASYNC_VIDEO | - OBS_SOURCE_AUDIO | - OBS_SOURCE_DO_NOT_DUPLICATE, + .output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO | + OBS_SOURCE_DO_NOT_DUPLICATE, .get_name = vlcs_get_name, .create = vlcs_create, .destroy = vlcs_destroy, @@ -959,5 +960,5 @@ struct obs_source_info vlc_source_info = { .get_defaults = vlcs_defaults, .get_properties = vlcs_properties, .activate = vlcs_activate, - .deactivate = vlcs_deactivate + .deactivate = vlcs_deactivate, }; diff --git a/test/osx/test.mm b/test/osx/test.mm index 136b513..353884b 100644 --- a/test/osx/test.mm +++ b/test/osx/test.mm @@ -16,24 +16,23 @@ static const int cy = 600; /* --------------------------------------------------- */ -template -struct OBSUniqueHandle : std::unique_ptr> -{ +template +struct OBSUniqueHandle : std::unique_ptr> { using base = std::unique_ptr>; - explicit OBSUniqueHandle(T *obj=nullptr) : base(obj, D) {} - operator T*() { return base::get(); } + explicit OBSUniqueHandle(T *obj = nullptr) : base(obj, D) {} + operator T *() { return base::get(); } }; #define DECLARE_DELETER(x) decltype(x), x -using SourceContext = OBSUniqueHandle; +using SourceContext = + OBSUniqueHandle; -using SceneContext = OBSUniqueHandle; +using SceneContext = + OBSUniqueHandle; -using DisplayContext = OBSUniqueHandle; +using DisplayContext = + OBSUniqueHandle; #undef DECLARE_DELETER @@ -45,15 +44,15 @@ static void CreateOBS() throw "Couldn't create OBS"; struct obs_video_info ovi; - ovi.adapter = 0; - ovi.fps_num = 30000; - ovi.fps_den = 1001; + ovi.adapter = 0; + ovi.fps_num = 30000; + ovi.fps_den = 1001; ovi.graphics_module = DL_OPENGL; - ovi.output_format = VIDEO_FORMAT_RGBA; - ovi.base_width = cx; - ovi.base_height = cy; - ovi.output_width = cx; - ovi.output_height = cy; + ovi.output_format = VIDEO_FORMAT_RGBA; + ovi.base_width = cx; + ovi.base_height = cy; + ovi.output_width = cx; + ovi.output_height = cy; if (obs_reset_video(&ovi) != 0) throw "Couldn't initialize video"; @@ -61,12 +60,12 @@ static void CreateOBS() static DisplayContext CreateDisplay(NSView *view) { - gs_init_data info = {}; - info.cx = cx; - info.cy = cy; - info.format = GS_RGBA; - info.zsformat = GS_ZS_NONE; - info.window.view = view; + gs_init_data info = {}; + info.cx = cx; + info.cy = cy; + info.format = GS_RGBA; + info.zsformat = GS_ZS_NONE; + info.window.view = view; return DisplayContext{obs_display_create(&info)}; } @@ -79,8 +78,8 @@ static SceneContext SetupScene() /* ------------------------------------------------------ */ /* create source */ - SourceContext source{obs_source_create("random", "a test source", - nullptr, nullptr)}; + SourceContext source{ + obs_source_create("random", "a test source", nullptr, nullptr)}; if (!source) throw "Couldn't create random test source"; @@ -99,20 +98,19 @@ static SceneContext SetupScene() return scene; } -@interface OBSTest : NSObject -{ +@interface OBSTest : NSObject { NSWindow *win; NSView *view; DisplayContext display; SceneContext scene; } -- (void)applicationDidFinishLaunching:(NSNotification*)notification; -- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)app; -- (void)windowWillClose:(NSNotification*)notification; +- (void)applicationDidFinishLaunching:(NSNotification *)notification; +- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app; +- (void)windowWillClose:(NSNotification *)notification; @end @implementation OBSTest -- (void)applicationDidFinishLaunching:(NSNotification*)notification +- (void)applicationDidFinishLaunching:(NSNotification *)notification { UNUSED_PARAMETER(notification); @@ -120,9 +118,10 @@ static SceneContext SetupScene() NSRect content_rect = NSMakeRect(0, 0, cx, cy); win = [[NSWindow alloc] initWithContentRect:content_rect - styleMask:NSTitledWindowMask | NSClosableWindowMask - backing:NSBackingStoreBuffered - defer:NO]; + styleMask:NSTitledWindowMask | + NSClosableWindowMask + backing:NSBackingStoreBuffered + defer:NO]; if (!win) throw "Could not create window"; @@ -144,10 +143,12 @@ static SceneContext SetupScene() scene = SetupScene(); - obs_display_add_draw_callback(display.get(), - [](void *, uint32_t, uint32_t) { - obs_render_main_texture(); - }, nullptr); + obs_display_add_draw_callback( + display.get(), + [](void *, uint32_t, uint32_t) { + obs_render_main_texture(); + }, + nullptr); } catch (char const *error) { NSLog(@"%s\n", error); @@ -156,14 +157,14 @@ static SceneContext SetupScene() } } -- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)app +- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app { UNUSED_PARAMETER(app); return YES; } -- (void)windowWillClose:(NSNotification*)notification +- (void)windowWillClose:(NSNotification *)notification { UNUSED_PARAMETER(notification); diff --git a/test/test-input/sync-async-source.c b/test/test-input/sync-async-source.c index 8aa6dd1..e549d12 100644 --- a/test/test-input/sync-async-source.c +++ b/test/test-input/sync-async-source.c @@ -5,19 +5,19 @@ struct async_sync_test { obs_source_t *source; - os_event_t *stop_signal; - pthread_t thread; - bool initialized; + os_event_t *stop_signal; + pthread_t thread; + bool initialized; }; /* middle C */ -static const double rate = 261.63/48000.0; +static const double rate = 261.63 / 48000.0; #ifndef M_PI #define M_PI 3.1415926535897932384626433832795 #endif -#define M_PI_X2 M_PI*2 +#define M_PI_X2 M_PI * 2 static const char *ast_getname(void *unused) { @@ -44,7 +44,7 @@ static inline void fill_texture(uint32_t *pixels, uint32_t color) for (y = 0; y < 20; y++) { for (x = 0; x < 20; x++) { - pixels[y*20 + x] = color; + pixels[y * 20 + x] = color; } } } @@ -56,25 +56,25 @@ static void *video_thread(void *data) uint32_t sample_rate = audio_output_get_sample_rate(obs_get_audio()); uint32_t *pixels = bmalloc(20 * 20 * sizeof(uint32_t)); - float *samples = bmalloc(sample_rate * sizeof(float)); + float *samples = bmalloc(sample_rate * sizeof(float)); uint64_t cur_time = os_gettime_ns(); - bool whitelist = false; - double cos_val = 0.0; + bool whitelist = false; + double cos_val = 0.0; uint64_t start_time = cur_time; struct obs_source_frame frame = { - .data = {[0] = (uint8_t*)pixels}, - .linesize = {[0] = 20*4}, - .width = 20, - .height = 20, - .format = VIDEO_FORMAT_BGRX + .data = {[0] = (uint8_t *)pixels}, + .linesize = {[0] = 20 * 4}, + .width = 20, + .height = 20, + .format = VIDEO_FORMAT_BGRX, }; struct obs_source_audio audio = { - .speakers = SPEAKERS_MONO, - .data = {[0] = (uint8_t*)samples}, + .speakers = SPEAKERS_MONO, + .data = {[0] = (uint8_t *)samples}, .samples_per_sec = sample_rate, - .frames = sample_rate, - .format = AUDIO_FORMAT_FLOAT + .frames = sample_rate, + .format = AUDIO_FORMAT_FLOAT, }; while (os_event_try(ast->stop_signal) == EAGAIN) { @@ -133,11 +133,10 @@ static void *ast_create(obs_data_t *settings, obs_source_t *source) } struct obs_source_info async_sync_test = { - .id = "async_sync_test", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_ASYNC_VIDEO | - OBS_SOURCE_AUDIO, - .get_name = ast_getname, - .create = ast_create, - .destroy = ast_destroy, + .id = "async_sync_test", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO, + .get_name = ast_getname, + .create = ast_create, + .destroy = ast_destroy, }; diff --git a/test/test-input/sync-audio-buffering.c b/test/test-input/sync-audio-buffering.c index 24010f7..b0b2a82 100644 --- a/test/test-input/sync-audio-buffering.c +++ b/test/test-input/sync-audio-buffering.c @@ -5,29 +5,27 @@ struct buffering_async_sync_test { obs_source_t *source; - os_event_t *stop_signal; - pthread_t thread; - bool initialized; - bool buffer_audio; + os_event_t *stop_signal; + pthread_t thread; + bool initialized; + bool buffer_audio; }; #define CYCLE_COUNT 7 static const double aud_rates[CYCLE_COUNT] = { - 220.00/48000.0, /* A */ - 233.08/48000.0, /* A# */ - 246.94/48000.0, /* B */ - 261.63/48000.0, /* C */ - 277.18/48000.0, /* C# */ - 293.67/48000.0, /* D */ - 311.13/48000.0, /* D# */ + 220.00 / 48000.0, /* A */ + 233.08 / 48000.0, /* A# */ + 246.94 / 48000.0, /* B */ + 261.63 / 48000.0, /* C */ + 277.18 / 48000.0, /* C# */ + 293.67 / 48000.0, /* D */ + 311.13 / 48000.0, /* D# */ }; #define MAKE_COL_CHAN(x, y) (((0xFF / 7) * x) << (y * 8)) #define MAKE_GRAYSCALE(x) \ - (MAKE_COL_CHAN(x, 0) | \ - MAKE_COL_CHAN(x, 1) | \ - MAKE_COL_CHAN(x, 2)) + (MAKE_COL_CHAN(x, 0) | MAKE_COL_CHAN(x, 1) | MAKE_COL_CHAN(x, 2)) static const uint32_t vid_colors[CYCLE_COUNT] = { 0xFF000000, @@ -43,7 +41,7 @@ static const uint32_t vid_colors[CYCLE_COUNT] = { #define M_PI 3.1415926535897932384626433832795 #endif -#define M_PI_X2 M_PI*2 +#define M_PI_X2 M_PI * 2 static const char *bast_getname(void *unused) { @@ -70,7 +68,7 @@ static inline void fill_texture(uint32_t *pixels, uint32_t color) for (y = 0; y < 20; y++) { for (x = 0; x < 20; x++) { - pixels[y*20 + x] = color; + pixels[y * 20 + x] = color; } } } @@ -82,27 +80,27 @@ static void *video_thread(void *data) uint32_t sample_rate = audio_output_get_sample_rate(obs_get_audio()); uint32_t *pixels = bmalloc(20 * 20 * sizeof(uint32_t)); - float *samples = bmalloc(sample_rate * sizeof(float)); + float *samples = bmalloc(sample_rate * sizeof(float)); uint64_t cur_time = os_gettime_ns(); - int cur_vid_pos = 0; - int cur_aud_pos = 0; - double cos_val = 0.0; + int cur_vid_pos = 0; + int cur_aud_pos = 0; + double cos_val = 0.0; uint64_t start_time = cur_time; - bool audio_buffering_enabled = false; + bool audio_buffering_enabled = false; struct obs_source_frame frame = { - .data = {[0] = (uint8_t*)pixels}, - .linesize = {[0] = 20*4}, - .width = 20, - .height = 20, - .format = VIDEO_FORMAT_BGRX + .data = {[0] = (uint8_t *)pixels}, + .linesize = {[0] = 20 * 4}, + .width = 20, + .height = 20, + .format = VIDEO_FORMAT_BGRX, }; struct obs_source_audio audio = { - .speakers = SPEAKERS_MONO, - .data = {[0] = (uint8_t*)samples}, + .speakers = SPEAKERS_MONO, + .data = {[0] = (uint8_t *)samples}, .samples_per_sec = sample_rate, - .frames = sample_rate / 4, - .format = AUDIO_FORMAT_FLOAT + .frames = sample_rate / 4, + .format = AUDIO_FORMAT_FLOAT, }; while (os_event_try(bast->stop_signal) == EAGAIN) { @@ -123,7 +121,7 @@ static void *video_thread(void *data) * buffering */ frame.timestamp = cur_time - start_time; audio.timestamp = cur_time - start_time - - (audio_buffering_enabled ? 1000000000 : 0); + (audio_buffering_enabled ? 1000000000 : 0); const double rate = aud_rates[cur_aud_pos]; @@ -153,7 +151,7 @@ static void *video_thread(void *data) } static void bast_buffer_audio(void *data, obs_hotkey_id id, - obs_hotkey_t *hotkey, bool pressed) + obs_hotkey_t *hotkey, bool pressed) { struct buffering_async_sync_test *bast = data; @@ -180,7 +178,7 @@ static void *bast_create(obs_data_t *settings, obs_source_t *source) } obs_hotkey_register_source(source, "AudioBufferingSyncTest.Buffer", - "Buffer Audio", bast_buffer_audio, bast); + "Buffer Audio", bast_buffer_audio, bast); bast->initialized = true; @@ -190,11 +188,10 @@ static void *bast_create(obs_data_t *settings, obs_source_t *source) } struct obs_source_info buffering_async_sync_test = { - .id = "buffering_async_sync_test", - .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_ASYNC_VIDEO | - OBS_SOURCE_AUDIO, - .get_name = bast_getname, - .create = bast_create, - .destroy = bast_destroy, + .id = "buffering_async_sync_test", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO, + .get_name = bast_getname, + .create = bast_create, + .destroy = bast_destroy, }; diff --git a/test/test-input/sync-pair-aud.c b/test/test-input/sync-pair-aud.c index 52a66c1..6ee57dc 100644 --- a/test/test-input/sync-pair-aud.c +++ b/test/test-input/sync-pair-aud.c @@ -5,25 +5,25 @@ #include struct sync_pair_aud { - bool initialized_thread; - pthread_t thread; - os_event_t *event; + bool initialized_thread; + pthread_t thread; + os_event_t *event; obs_source_t *source; }; /* middle C */ -static const double rate = 261.63/48000.0; +static const double rate = 261.63 / 48000.0; #ifndef M_PI #define M_PI 3.1415926535897932384626433832795 #endif -#define M_PI_X2 M_PI*2 +#define M_PI_X2 M_PI * 2 extern uint64_t starting_time; static inline bool whitelist_time(uint64_t ts, uint64_t interval, - uint64_t fps_num, uint64_t fps_den) + uint64_t fps_num, uint64_t fps_den) { if (!starting_time) return false; @@ -53,8 +53,8 @@ static void *sync_pair_aud_thread(void *pdata) last_time = obs_get_video_frame_time(); for (uint64_t i = 0; i < frames; i++) { - uint64_t ts = last_time + - i * 1000000000ULL / sample_rate; + uint64_t ts = + last_time + i * 1000000000ULL / sample_rate; if (whitelist_time(ts, interval, fps_num, fps_den)) { cos_val += rate * M_PI_X2; @@ -68,7 +68,7 @@ static void *sync_pair_aud_thread(void *pdata) } struct obs_source_audio data; - data.data[0] = (uint8_t*)samples; + data.data[0] = (uint8_t *)samples; data.frames = frames; data.speakers = SPEAKERS_MONO; data.samples_per_sec = sample_rate; @@ -106,8 +106,7 @@ static void sync_pair_aud_destroy(void *data) } } -static void *sync_pair_aud_create(obs_data_t *settings, - obs_source_t *source) +static void *sync_pair_aud_create(obs_data_t *settings, obs_source_t *source) { struct sync_pair_aud *spa = bzalloc(sizeof(struct sync_pair_aud)); spa->source = source; @@ -128,10 +127,10 @@ fail: } struct obs_source_info sync_audio = { - .id = "sync_audio", - .type = OBS_SOURCE_TYPE_INPUT, + .id = "sync_audio", + .type = OBS_SOURCE_TYPE_INPUT, .output_flags = OBS_SOURCE_AUDIO, - .get_name = sync_pair_aud_getname, - .create = sync_pair_aud_create, - .destroy = sync_pair_aud_destroy, + .get_name = sync_pair_aud_getname, + .create = sync_pair_aud_create, + .destroy = sync_pair_aud_destroy, }; diff --git a/test/test-input/sync-pair-vid.c b/test/test-input/sync-pair-vid.c index ebfc32c..76d4386 100644 --- a/test/test-input/sync-pair-vid.c +++ b/test/test-input/sync-pair-vid.c @@ -39,7 +39,7 @@ static inline void fill_texture(uint32_t *pixels, uint32_t pixel) for (y = 0; y < 32; y++) { for (x = 0; x < 32; x++) { - pixels[y*32 + x] = pixel; + pixels[y * 32 + x] = pixel; } } } @@ -57,11 +57,11 @@ static void *sync_pair_vid_create(obs_data_t *settings, obs_source_t *source) uint8_t *ptr; uint32_t linesize; if (gs_texture_map(spv->white, &ptr, &linesize)) { - fill_texture((uint32_t*)ptr, 0xFFFFFFFF); + fill_texture((uint32_t *)ptr, 0xFFFFFFFF); gs_texture_unmap(spv->white); } if (gs_texture_map(spv->black, &ptr, &linesize)) { - fill_texture((uint32_t*)ptr, 0xFF000000); + fill_texture((uint32_t *)ptr, 0xFF000000); gs_texture_unmap(spv->black); } @@ -71,7 +71,7 @@ static void *sync_pair_vid_create(obs_data_t *settings, obs_source_t *source) } static inline bool whitelist_time(uint64_t ts, uint64_t interval, - uint64_t fps_num, uint64_t fps_den) + uint64_t fps_num, uint64_t fps_den) { if (!starting_time) return false; @@ -120,13 +120,13 @@ static uint32_t sync_pair_vid_size(void *data) } struct obs_source_info sync_video = { - .id = "sync_video", - .type = OBS_SOURCE_TYPE_INPUT, + .id = "sync_video", + .type = OBS_SOURCE_TYPE_INPUT, .output_flags = OBS_SOURCE_VIDEO, - .get_name = sync_pair_vid_getname, - .create = sync_pair_vid_create, - .destroy = sync_pair_vid_destroy, + .get_name = sync_pair_vid_getname, + .create = sync_pair_vid_create, + .destroy = sync_pair_vid_destroy, .video_render = sync_pair_vid_render, - .get_width = sync_pair_vid_size, - .get_height = sync_pair_vid_size, + .get_width = sync_pair_vid_size, + .get_height = sync_pair_vid_size, }; diff --git a/test/test-input/test-filter.c b/test/test-input/test-filter.c index 0fbeec9..35c114d 100644 --- a/test/test-input/test-filter.c +++ b/test/test-input/test-filter.c @@ -53,7 +53,7 @@ static void filter_render(void *data, gs_effect_t *effect) struct test_filter *tf = data; if (!obs_source_process_filter_begin(tf->source, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING)) + OBS_ALLOW_DIRECT_RENDERING)) return; obs_source_process_filter_end(tf->source, tf->whatever, 0, 0); @@ -62,11 +62,11 @@ static void filter_render(void *data, gs_effect_t *effect) } struct obs_source_info test_filter = { - .id = "test_filter", - .type = OBS_SOURCE_TYPE_FILTER, + .id = "test_filter", + .type = OBS_SOURCE_TYPE_FILTER, .output_flags = OBS_SOURCE_VIDEO, - .get_name = filter_getname, - .create = filter_create, - .destroy = filter_destroy, - .video_render = filter_render + .get_name = filter_getname, + .create = filter_create, + .destroy = filter_destroy, + .video_render = filter_render, }; diff --git a/test/test-input/test-random.c b/test/test-input/test-random.c index 34ebd15..af2e5b7 100644 --- a/test/test-input/test-random.c +++ b/test/test-input/test-random.c @@ -5,9 +5,9 @@ struct random_tex { obs_source_t *source; - os_event_t *stop_signal; - pthread_t thread; - bool initialized; + os_event_t *stop_signal; + pthread_t thread; + bool initialized; }; static const char *random_getname(void *unused) @@ -38,28 +38,28 @@ static inline void fill_texture(uint32_t *pixels) for (y = 0; y < 20; y++) { for (x = 0; x < 20; x++) { uint32_t pixel = 0; - pixel |= (rand()%256); - pixel |= (rand()%256) << 8; - pixel |= (rand()%256) << 16; + pixel |= (rand() % 256); + pixel |= (rand() % 256) << 8; + pixel |= (rand() % 256) << 16; //pixel |= (rand()%256) << 24; //pixel |= 0xFFFFFFFF; - pixels[y*20 + x] = pixel; + pixels[y * 20 + x] = pixel; } } } static void *video_thread(void *data) { - struct random_tex *rt = data; - uint32_t pixels[20*20]; - uint64_t cur_time = os_gettime_ns(); + struct random_tex *rt = data; + uint32_t pixels[20 * 20]; + uint64_t cur_time = os_gettime_ns(); struct obs_source_frame frame = { - .data = {[0] = (uint8_t*)pixels}, - .linesize = {[0] = 20*4}, - .width = 20, - .height = 20, - .format = VIDEO_FORMAT_BGRX + .data = {[0] = (uint8_t *)pixels}, + .linesize = {[0] = 20 * 4}, + .width = 20, + .height = 20, + .format = VIDEO_FORMAT_BGRX, }; while (os_event_try(rt->stop_signal) == EAGAIN) { @@ -98,10 +98,10 @@ static void *random_create(obs_data_t *settings, obs_source_t *source) } struct obs_source_info test_random = { - .id = "random", - .type = OBS_SOURCE_TYPE_INPUT, + .id = "random", + .type = OBS_SOURCE_TYPE_INPUT, .output_flags = OBS_SOURCE_ASYNC_VIDEO, - .get_name = random_getname, - .create = random_create, - .destroy = random_destroy, + .get_name = random_getname, + .create = random_create, + .destroy = random_destroy, }; diff --git a/test/test-input/test-sinewave.c b/test/test-input/test-sinewave.c index 7a920c8..640212c 100644 --- a/test/test-input/test-sinewave.c +++ b/test/test-input/test-sinewave.c @@ -5,20 +5,20 @@ #include struct sinewave_data { - bool initialized_thread; - pthread_t thread; - os_event_t *event; + bool initialized_thread; + pthread_t thread; + os_event_t *event; obs_source_t *source; }; /* middle C */ -static const double rate = 261.63/48000.0; +static const double rate = 261.63 / 48000.0; #ifndef M_PI #define M_PI 3.1415926535897932384626433832795 #endif -#define M_PI_X2 M_PI*2 +#define M_PI_X2 M_PI * 2 static void *sinewave_thread(void *pdata) { @@ -38,7 +38,7 @@ static void *sinewave_thread(void *pdata) cos_val -= M_PI_X2; double wave = cos(cos_val) * 0.5; - bytes[i] = (uint8_t)((wave+1.0)*0.5 * 255.0); + bytes[i] = (uint8_t)((wave + 1.0) * 0.5 * 255.0); } struct obs_source_audio data; @@ -80,8 +80,7 @@ static void sinewave_destroy(void *data) } } -static void *sinewave_create(obs_data_t *settings, - obs_source_t *source) +static void *sinewave_create(obs_data_t *settings, obs_source_t *source) { struct sinewave_data *swd = bzalloc(sizeof(struct sinewave_data)); swd->source = source; @@ -102,10 +101,10 @@ fail: } struct obs_source_info test_sinewave = { - .id = "test_sinewave", - .type = OBS_SOURCE_TYPE_INPUT, + .id = "test_sinewave", + .type = OBS_SOURCE_TYPE_INPUT, .output_flags = OBS_SOURCE_AUDIO, - .get_name = sinewave_getname, - .create = sinewave_create, - .destroy = sinewave_destroy, + .get_name = sinewave_getname, + .create = sinewave_create, + .destroy = sinewave_destroy, }; diff --git a/test/win/test.cpp b/test/win/test.cpp index 5f966c6..62659cd 100644 --- a/test/win/test.cpp +++ b/test/win/test.cpp @@ -19,8 +19,8 @@ class SourceContext { public: inline SourceContext(obs_source_t *source) : source(source) {} - inline ~SourceContext() {obs_source_release(source);} - inline operator obs_source_t*() {return source;} + inline ~SourceContext() { obs_source_release(source); } + inline operator obs_source_t *() { return source; } }; /* --------------------------------------------------- */ @@ -30,8 +30,8 @@ class SceneContext { public: inline SceneContext(obs_scene_t *scene) : scene(scene) {} - inline ~SceneContext() {obs_scene_release(scene);} - inline operator obs_scene_t*() {return scene;} + inline ~SceneContext() { obs_scene_release(scene); } + inline operator obs_scene_t *() { return scene; } }; /* --------------------------------------------------- */ @@ -41,14 +41,14 @@ class DisplayContext { public: inline DisplayContext(obs_display_t *display) : display(display) {} - inline ~DisplayContext() {obs_display_destroy(display);} - inline operator obs_display_t*() {return display;} + inline ~DisplayContext() { obs_display_destroy(display); } + inline operator obs_display_t *() { return display; } }; /* --------------------------------------------------- */ static LRESULT CALLBACK sceneProc(HWND hwnd, UINT message, WPARAM wParam, - LPARAM lParam) + LPARAM lParam) { switch (message) { @@ -86,15 +86,15 @@ static void CreateOBS(HWND hwnd) throw "Couldn't create OBS"; struct obs_video_info ovi; - ovi.adapter = 0; - ovi.base_width = rc.right; - ovi.base_height = rc.bottom; - ovi.fps_num = 30000; - ovi.fps_den = 1001; + ovi.adapter = 0; + ovi.base_width = rc.right; + ovi.base_height = rc.bottom; + ovi.fps_num = 30000; + ovi.fps_den = 1001; ovi.graphics_module = DL_OPENGL; - ovi.output_format = VIDEO_FORMAT_RGBA; - ovi.output_width = rc.right; - ovi.output_height = rc.bottom; + ovi.output_format = VIDEO_FORMAT_RGBA; + ovi.output_width = rc.right; + ovi.output_height = rc.bottom; if (obs_reset_video(&ovi) != 0) throw "Couldn't initialize video"; @@ -133,17 +133,17 @@ static HWND CreateTestWindow(HINSTANCE instance) memset(&wc, 0, sizeof(wc)); wc.lpszClassName = TEXT("bla"); wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.hInstance = instance; - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.lpfnWndProc = (WNDPROC)sceneProc; + wc.hInstance = instance; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.lpfnWndProc = (WNDPROC)sceneProc; if (!RegisterClass(&wc)) return 0; return CreateWindow(TEXT("bla"), TEXT("bla"), - WS_OVERLAPPEDWINDOW|WS_VISIBLE, - 1920/2 - cx/2, 1080/2 - cy/2, cx, cy, - NULL, NULL, instance, NULL); + WS_OVERLAPPEDWINDOW | WS_VISIBLE, 1920 / 2 - cx / 2, + 1080 / 2 - cy / 2, cx, cy, NULL, NULL, instance, + NULL); } /* --------------------------------------------------- */ @@ -160,7 +160,7 @@ static void RenderWindow(void *data, uint32_t cx, uint32_t cy) /* --------------------------------------------------- */ int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, - int numCmd) + int numCmd) { HWND hwnd = NULL; base_set_log_handler(do_log, nullptr); @@ -180,15 +180,15 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, /* ------------------------------------------------------ */ /* create source */ - SourceContext source = obs_source_create("random", - "some randon source", NULL, nullptr); + SourceContext source = obs_source_create( + "random", "some randon source", NULL, nullptr); if (!source) throw "Couldn't create random test source"; /* ------------------------------------------------------ */ /* create filter */ - SourceContext filter = obs_source_create("test_filter", - "a nice green filter", NULL, nullptr); + SourceContext filter = obs_source_create( + "test_filter", "a nice green filter", NULL, nullptr); if (!filter) throw "Couldn't create test filter"; obs_source_filter_add(source, filter);