From 41a01dbf0591ef92f012e49bd1f8cce5e0f8b7a1 Mon Sep 17 00:00:00 2001 From: Sebastian Ramacher Date: Tue, 24 May 2016 21:53:01 +0200 Subject: [PATCH] Imported Upstream version 0.14.2+dfsg1 --- cmake/Modules/CopyMSVCBins.cmake | 3 + deps/file-updater/file-updater/file-updater.c | 109 +- deps/libff/libff/ff-audio-decoder.c | 67 +- deps/libff/libff/ff-compat.h | 29 + deps/libff/libff/ff-decoder.c | 5 +- deps/libff/libff/ff-decoder.h | 1 + deps/libff/libff/ff-demuxer.c | 19 +- deps/libff/libff/ff-packet-queue.c | 5 +- deps/libff/libff/ff-timer.c | 3 + deps/libff/libff/ff-video-decoder.c | 18 +- libobs-opengl/gl-indexbuffer.c | 13 +- libobs-opengl/gl-shaderparser.c | 38 +- libobs-opengl/gl-subsystem.c | 8 +- libobs-opengl/gl-subsystem.h | 4 +- libobs-opengl/gl-vertexbuffer.c | 6 +- libobs/CMakeLists.txt | 1 + libobs/data/default_rect.effect | 20 - libobs/data/deinterlace_base.effect | 293 ++++ libobs/data/deinterlace_blend.effect | 21 + libobs/data/deinterlace_blend_2x.effect | 21 + libobs/data/deinterlace_discard.effect | 21 + libobs/data/deinterlace_discard_2x.effect | 21 + libobs/data/deinterlace_linear.effect | 21 + libobs/data/deinterlace_linear_2x.effect | 21 + libobs/data/deinterlace_yadif.effect | 21 + libobs/data/deinterlace_yadif_2x.effect | 21 + libobs/data/lanczos_scale.effect | 34 +- libobs/data/premultiplied_alpha.effect | 38 + libobs/graphics/graphics.h | 3 + libobs/graphics/matrix4.c | 2 +- libobs/graphics/shader-parser.c | 6 + libobs/graphics/texture-render.c | 3 + libobs/media-io/video-fourcc.c | 3 + libobs/media-io/video-frame.c | 8 + libobs/media-io/video-io.h | 3 + libobs/media-io/video-scaler-ffmpeg.c | 1 + libobs/obs-avc.c | 55 + libobs/obs-avc.h | 4 + libobs/obs-config.h | 2 +- libobs/obs-encoder.c | 12 +- libobs/obs-encoder.h | 4 + libobs/obs-internal.h | 68 +- libobs/obs-output.c | 86 +- libobs/obs-scene.c | 197 ++- libobs/obs-scene.h | 4 + libobs/obs-service.c | 41 +- libobs/obs-source-deinterlace.c | 444 ++++++ libobs/obs-source-transition.c | 3 +- libobs/obs-source.c | 254 +-- libobs/obs-source.h | 9 - libobs/obs-windows.c | 4 +- libobs/obs.c | 78 +- libobs/obs.h | 83 +- libobs/util/cf-lexer.c | 19 + libobs/util/dstr.c | 8 +- libobs/util/platform.c | 31 + libobs/util/platform.h | 6 + libobs/util/text-lookup.c | 1 + obs/data/locale.ini | 11 +- obs/data/locale/ar-SA.ini | 100 +- obs/data/locale/bg-BG.ini | 7 +- obs/data/locale/ca-ES.ini | 68 +- obs/data/locale/cs-CZ.ini | 129 +- obs/data/locale/da-DK.ini | 199 ++- obs/data/locale/de-DE.ini | 97 +- obs/data/locale/el-GR.ini | 14 +- obs/data/locale/en-US.ini | 49 +- obs/data/locale/es-ES.ini | 69 +- obs/data/locale/eu-ES.ini | 589 +++---- obs/data/locale/fi-FI.ini | 48 +- obs/data/locale/fr-FR.ini | 49 +- obs/data/locale/gl-ES.ini | 28 +- obs/data/locale/he-IL.ini | 497 ++++++ obs/data/locale/hr-HR.ini | 44 +- obs/data/locale/hu-HU.ini | 233 +-- obs/data/locale/it-IT.ini | 15 +- obs/data/locale/ja-JP.ini | 97 +- obs/data/locale/ko-KR.ini | 45 +- obs/data/locale/lt-LT.ini | 198 +++ obs/data/locale/ms-MY.ini | 49 +- obs/data/locale/nb-NO.ini | 7 +- obs/data/locale/nl-NL.ini | 43 +- obs/data/locale/pl-PL.ini | 44 +- obs/data/locale/pt-BR.ini | 65 +- obs/data/locale/pt-PT.ini | 36 +- obs/data/locale/ro-RO.ini | 573 +++---- obs/data/locale/ru-RU.ini | 54 +- obs/data/locale/sk-SK.ini | 5 +- obs/data/locale/sl-SI.ini | 5 +- obs/data/locale/sr-CS.ini | 44 +- obs/data/locale/sr-SP.ini | 44 +- obs/data/locale/sv-SE.ini | 143 +- obs/data/locale/ta-IN.ini | 89 ++ obs/data/locale/th-TH.ini | 4 + obs/data/locale/tr-TR.ini | 59 +- obs/data/locale/uk-UA.ini | 4 + obs/data/locale/vi-VN.ini | 6 +- obs/data/locale/zh-CN.ini | 71 +- obs/data/locale/zh-TW.ini | 50 +- obs/dist/obs.desktop | 1 + obs/forms/OBSBasic.ui | 115 +- obs/forms/OBSBasicSettings.ui | 315 +++- obs/forms/OBSBasicTransform.ui | 293 +++- obs/installer/mp-installer.nsi | 286 ++++ obs/obs-app.cpp | 316 +++- obs/obs-app.hpp | 8 + obs/remote-text.cpp | 5 + obs/window-basic-filters.cpp | 12 +- obs/window-basic-interaction.cpp | 3 + obs/window-basic-main-outputs.cpp | 206 ++- obs/window-basic-main-scene-collections.cpp | 2 + obs/window-basic-main-transitions.cpp | 239 ++- obs/window-basic-main.cpp | 168 +- obs/window-basic-main.hpp | 18 +- obs/window-basic-preview.cpp | 351 ++++- obs/window-basic-preview.hpp | 7 +- obs/window-basic-properties.cpp | 12 +- obs/window-basic-settings.cpp | 371 ++++- obs/window-basic-settings.hpp | 11 + obs/window-basic-status-bar.cpp | 2 +- obs/window-basic-transform.cpp | 28 + obs/window-basic-transform.hpp | 1 + obs/window-projector.cpp | 2 +- obs/window-remux.cpp | 7 +- plugins/CMakeLists.txt | 2 + .../coreaudio-encoder/data/locale/ar-SA.ini | 6 + .../coreaudio-encoder/data/locale/ca-ES.ini | 2 + .../coreaudio-encoder/data/locale/da-DK.ini | 6 + .../coreaudio-encoder/data/locale/eu-ES.ini | 8 +- .../coreaudio-encoder/data/locale/hu-HU.ini | 6 +- .../coreaudio-encoder/data/locale/ja-JP.ini | 2 +- .../coreaudio-encoder/data/locale/pt-BR.ini | 2 + .../coreaudio-encoder/data/locale/ro-RO.ini | 8 +- .../coreaudio-encoder/data/locale/ru-RU.ini | 2 + .../coreaudio-encoder/data/locale/sv-SE.ini | 3 +- .../coreaudio-encoder/data/locale/ta-IN.ini | 4 + .../coreaudio-encoder/data/locale/tr-TR.ini | 1 + plugins/decklink/data/locale/ar-SA.ini | 6 + plugins/decklink/data/locale/da-DK.ini | 1 + plugins/decklink/data/locale/el-GR.ini | 2 + plugins/decklink/data/locale/eu-ES.ini | 4 +- plugins/decklink/data/locale/he-IL.ini | 6 + plugins/decklink/data/locale/hu-HU.ini | 6 +- plugins/decklink/data/locale/pt-BR.ini | 1 + plugins/decklink/data/locale/ro-RO.ini | 4 +- plugins/decklink/data/locale/sv-SE.ini | 1 + plugins/decklink/decklink-device.cpp | 7 +- plugins/image-source/data/locale/ar-SA.ini | 1 + plugins/image-source/data/locale/eu-ES.ini | 4 +- plugins/image-source/data/locale/he-IL.ini | 4 + plugins/image-source/data/locale/pt-PT.ini | 2 +- plugins/image-source/data/locale/ro-RO.ini | 4 +- plugins/image-source/data/locale/sv-SE.ini | 2 +- plugins/image-source/image-source.c | 22 +- plugins/linux-alsa/CMakeLists.txt | 34 + plugins/linux-alsa/alsa-input.c | 599 +++++++ plugins/linux-alsa/data/locale/ar-SA.ini | 3 + plugins/linux-alsa/data/locale/ca-ES.ini | 3 + plugins/linux-alsa/data/locale/cs-CZ.ini | 3 + plugins/linux-alsa/data/locale/da-DK.ini | 3 + plugins/linux-alsa/data/locale/de-DE.ini | 3 + plugins/linux-alsa/data/locale/en-US.ini | 2 + plugins/linux-alsa/data/locale/es-ES.ini | 3 + plugins/linux-alsa/data/locale/eu-ES.ini | 3 + plugins/linux-alsa/data/locale/fi-FI.ini | 3 + plugins/linux-alsa/data/locale/fr-FR.ini | 3 + plugins/linux-alsa/data/locale/gl-ES.ini | 3 + plugins/linux-alsa/data/locale/hr-HR.ini | 3 + plugins/linux-alsa/data/locale/hu-HU.ini | 3 + plugins/linux-alsa/data/locale/ja-JP.ini | 3 + plugins/linux-alsa/data/locale/ko-KR.ini | 3 + plugins/linux-alsa/data/locale/nl-NL.ini | 3 + plugins/linux-alsa/data/locale/pl-PL.ini | 3 + plugins/linux-alsa/data/locale/pt-BR.ini | 3 + plugins/linux-alsa/data/locale/ro-RO.ini | 3 + plugins/linux-alsa/data/locale/ru-RU.ini | 3 + plugins/linux-alsa/data/locale/sr-CS.ini | 3 + plugins/linux-alsa/data/locale/sr-SP.ini | 3 + plugins/linux-alsa/data/locale/sv-SE.ini | 3 + plugins/linux-alsa/data/locale/tr-TR.ini | 3 + plugins/linux-alsa/data/locale/zh-CN.ini | 3 + plugins/linux-alsa/data/locale/zh-TW.ini | 3 + plugins/linux-alsa/linux-alsa.c | 29 + plugins/linux-capture/data/locale/ar-SA.ini | 2 + plugins/linux-capture/data/locale/ca-ES.ini | 1 + plugins/linux-capture/data/locale/cs-CZ.ini | 3 +- plugins/linux-capture/data/locale/da-DK.ini | 11 +- plugins/linux-capture/data/locale/de-DE.ini | 1 + plugins/linux-capture/data/locale/en-US.ini | 1 + plugins/linux-capture/data/locale/es-ES.ini | 1 + plugins/linux-capture/data/locale/eu-ES.ini | 23 +- plugins/linux-capture/data/locale/fi-FI.ini | 1 + plugins/linux-capture/data/locale/fr-FR.ini | 11 +- plugins/linux-capture/data/locale/he-IL.ini | 15 + plugins/linux-capture/data/locale/hr-HR.ini | 1 + plugins/linux-capture/data/locale/hu-HU.ini | 21 +- plugins/linux-capture/data/locale/ja-JP.ini | 11 +- plugins/linux-capture/data/locale/ko-KR.ini | 1 + plugins/linux-capture/data/locale/nl-NL.ini | 3 +- plugins/linux-capture/data/locale/pl-PL.ini | 1 + plugins/linux-capture/data/locale/pt-BR.ini | 1 + plugins/linux-capture/data/locale/pt-PT.ini | 16 +- plugins/linux-capture/data/locale/ro-RO.ini | 17 +- plugins/linux-capture/data/locale/ru-RU.ini | 1 + plugins/linux-capture/data/locale/sr-CS.ini | 1 + plugins/linux-capture/data/locale/sr-SP.ini | 1 + plugins/linux-capture/data/locale/zh-CN.ini | 1 + plugins/linux-capture/xcompcap-main.cpp | 10 + plugins/linux-jack/data/locale/ar-SA.ini | 3 + plugins/linux-jack/data/locale/eu-ES.ini | 6 +- plugins/linux-jack/data/locale/he-IL.ini | 4 + plugins/linux-jack/data/locale/hu-HU.ini | 4 +- plugins/linux-jack/data/locale/ja-JP.ini | 4 +- plugins/linux-jack/data/locale/ro-RO.ini | 6 +- .../linux-pulseaudio/data/locale/da-DK.ini | 4 +- .../linux-pulseaudio/data/locale/eu-ES.ini | 4 +- .../linux-pulseaudio/data/locale/fr-FR.ini | 4 +- .../linux-pulseaudio/data/locale/he-IL.ini | 4 + .../linux-pulseaudio/data/locale/hu-HU.ini | 4 +- .../linux-pulseaudio/data/locale/nl-NL.ini | 4 +- .../linux-pulseaudio/data/locale/ro-RO.ini | 4 +- .../linux-pulseaudio/data/locale/zh-CN.ini | 4 +- plugins/linux-v4l2/data/locale/cs-CZ.ini | 4 +- plugins/linux-v4l2/data/locale/eu-ES.ini | 12 +- plugins/linux-v4l2/data/locale/he-IL.ini | 11 + plugins/linux-v4l2/data/locale/hu-HU.ini | 12 +- plugins/linux-v4l2/data/locale/pt-PT.ini | 2 +- plugins/linux-v4l2/data/locale/ro-RO.ini | 12 +- plugins/linux-v4l2/data/locale/sv-SE.ini | 2 +- plugins/mac-avcapture/data/locale/ar-SA.ini | 3 + plugins/mac-avcapture/data/locale/cs-CZ.ini | 2 +- plugins/mac-avcapture/data/locale/da-DK.ini | 7 + plugins/mac-avcapture/data/locale/eu-ES.ini | 16 +- plugins/mac-avcapture/data/locale/gl-ES.ini | 8 + plugins/mac-avcapture/data/locale/hu-HU.ini | 6 +- plugins/mac-avcapture/data/locale/pt-BR.ini | 8 + plugins/mac-avcapture/data/locale/pt-PT.ini | 2 +- plugins/mac-avcapture/data/locale/ro-RO.ini | 16 +- plugins/mac-avcapture/data/locale/sv-SE.ini | 8 + plugins/mac-avcapture/data/locale/tr-TR.ini | 7 + plugins/mac-capture/data/locale/ar-SA.ini | 13 + plugins/mac-capture/data/locale/bg-BG.ini | 19 + plugins/mac-capture/data/locale/da-DK.ini | 8 +- plugins/mac-capture/data/locale/eu-ES.ini | 12 +- plugins/mac-capture/data/locale/fr-FR.ini | 12 +- plugins/mac-capture/data/locale/hu-HU.ini | 12 +- plugins/mac-capture/data/locale/nl-NL.ini | 6 +- plugins/mac-capture/data/locale/pt-PT.ini | 6 +- plugins/mac-capture/data/locale/ro-RO.ini | 28 +- plugins/mac-capture/data/locale/sv-SE.ini | 2 +- plugins/mac-syphon/data/locale/ar-SA.ini | 13 + plugins/mac-syphon/data/locale/eu-ES.ini | 8 +- plugins/mac-syphon/data/locale/hu-HU.ini | 8 +- plugins/mac-syphon/data/locale/ja-JP.ini | 2 +- plugins/mac-syphon/data/locale/ro-RO.ini | 20 +- plugins/mac-syphon/data/locale/sv-SE.ini | 2 +- plugins/mac-vth264/data/locale/ar-SA.ini | 6 + plugins/mac-vth264/data/locale/el-GR.ini | 6 + plugins/mac-vth264/data/locale/eu-ES.ini | 20 +- plugins/mac-vth264/data/locale/gl-ES.ini | 7 + plugins/mac-vth264/data/locale/hu-HU.ini | 12 +- plugins/mac-vth264/data/locale/ja-JP.ini | 4 +- plugins/mac-vth264/data/locale/ro-RO.ini | 22 +- plugins/mac-vth264/data/locale/sv-SE.ini | 12 + plugins/mac-vth264/data/locale/tr-TR.ini | 8 + plugins/obs-ffmpeg/CMakeLists.txt | 1 + plugins/obs-ffmpeg/data/locale/ar-SA.ini | 21 + plugins/obs-ffmpeg/data/locale/bg-BG.ini | 2 + plugins/obs-ffmpeg/data/locale/ca-ES.ini | 24 + plugins/obs-ffmpeg/data/locale/cs-CZ.ini | 19 + plugins/obs-ffmpeg/data/locale/da-DK.ini | 2 + plugins/obs-ffmpeg/data/locale/de-DE.ini | 19 + plugins/obs-ffmpeg/data/locale/el-GR.ini | 2 + plugins/obs-ffmpeg/data/locale/en-US.ini | 19 + plugins/obs-ffmpeg/data/locale/es-ES.ini | 19 + plugins/obs-ffmpeg/data/locale/eu-ES.ini | 67 +- plugins/obs-ffmpeg/data/locale/fi-FI.ini | 19 + plugins/obs-ffmpeg/data/locale/fr-FR.ini | 19 + plugins/obs-ffmpeg/data/locale/gl-ES.ini | 3 + plugins/obs-ffmpeg/data/locale/he-IL.ini | 32 + plugins/obs-ffmpeg/data/locale/hr-HR.ini | 17 + plugins/obs-ffmpeg/data/locale/hu-HU.ini | 53 +- plugins/obs-ffmpeg/data/locale/it-IT.ini | 3 + plugins/obs-ffmpeg/data/locale/ja-JP.ini | 29 +- plugins/obs-ffmpeg/data/locale/ko-KR.ini | 19 + plugins/obs-ffmpeg/data/locale/nb-NO.ini | 2 + plugins/obs-ffmpeg/data/locale/nl-NL.ini | 19 + plugins/obs-ffmpeg/data/locale/pl-PL.ini | 17 + plugins/obs-ffmpeg/data/locale/pt-BR.ini | 11 + plugins/obs-ffmpeg/data/locale/pt-PT.ini | 6 +- plugins/obs-ffmpeg/data/locale/ro-RO.ini | 58 +- plugins/obs-ffmpeg/data/locale/ru-RU.ini | 18 + plugins/obs-ffmpeg/data/locale/sk-SK.ini | 2 + plugins/obs-ffmpeg/data/locale/sl-SI.ini | 2 + plugins/obs-ffmpeg/data/locale/sr-CS.ini | 17 + plugins/obs-ffmpeg/data/locale/sr-SP.ini | 17 + plugins/obs-ffmpeg/data/locale/sv-SE.ini | 21 + plugins/obs-ffmpeg/data/locale/th-TH.ini | 2 + plugins/obs-ffmpeg/data/locale/tr-TR.ini | 11 + plugins/obs-ffmpeg/data/locale/zh-CN.ini | 19 + plugins/obs-ffmpeg/data/locale/zh-TW.ini | 13 +- plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c | 26 + plugins/obs-ffmpeg/obs-ffmpeg-compat.h | 3 + plugins/obs-ffmpeg/obs-ffmpeg-formats.h | 2 + plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c | 508 ++++++ plugins/obs-ffmpeg/obs-ffmpeg-source.c | 38 +- plugins/obs-ffmpeg/obs-ffmpeg.c | 28 + plugins/obs-filters/chroma-key-filter.c | 5 +- plugins/obs-filters/color-filter.c | 5 +- plugins/obs-filters/color-key-filter.c | 5 +- plugins/obs-filters/crop-filter.c | 5 +- .../obs-filters/data/blend_add_filter.effect | 25 - .../obs-filters/data/blend_mul_filter.effect | 25 - .../obs-filters/data/blend_sub_filter.effect | 25 - .../obs-filters/data/chroma_key_filter.effect | 60 +- plugins/obs-filters/data/color_filter.effect | 21 - .../obs-filters/data/color_key_filter.effect | 21 - plugins/obs-filters/data/locale/ar-SA.ini | 15 + plugins/obs-filters/data/locale/ca-ES.ini | 1 + plugins/obs-filters/data/locale/da-DK.ini | 12 + plugins/obs-filters/data/locale/el-GR.ini | 3 + plugins/obs-filters/data/locale/eu-ES.ini | 80 +- plugins/obs-filters/data/locale/fr-FR.ini | 4 +- plugins/obs-filters/data/locale/he-IL.ini | 54 + plugins/obs-filters/data/locale/hu-HU.ini | 26 +- plugins/obs-filters/data/locale/it-IT.ini | 8 +- plugins/obs-filters/data/locale/ja-JP.ini | 8 +- plugins/obs-filters/data/locale/pt-BR.ini | 49 +- plugins/obs-filters/data/locale/ro-RO.ini | 66 +- plugins/obs-filters/data/locale/sv-SE.ini | 3 +- .../obs-filters/data/mask_alpha_filter.effect | 25 - .../obs-filters/data/mask_color_filter.effect | 24 - plugins/obs-filters/data/sharpness.effect | 37 - plugins/obs-filters/mask-filter.c | 5 +- plugins/obs-filters/scroll-filter.c | 9 +- plugins/obs-filters/sharpness-filter.c | 7 +- plugins/obs-libfdk/data/locale/eu-ES.ini | 4 +- plugins/obs-libfdk/data/locale/he-IL.ini | 4 + plugins/obs-libfdk/data/locale/hu-HU.ini | 4 +- plugins/obs-libfdk/data/locale/ja-JP.ini | 2 +- plugins/obs-libfdk/data/locale/pt-PT.ini | 6 +- plugins/obs-libfdk/data/locale/ro-RO.ini | 6 +- plugins/obs-outputs/data/locale/eu-ES.ini | 6 +- plugins/obs-outputs/data/locale/fr-FR.ini | 6 +- plugins/obs-outputs/data/locale/he-IL.ini | 5 + plugins/obs-outputs/data/locale/hu-HU.ini | 8 +- plugins/obs-outputs/data/locale/nl-NL.ini | 2 +- plugins/obs-outputs/data/locale/pt-PT.ini | 8 +- plugins/obs-outputs/data/locale/ro-RO.ini | 8 +- plugins/obs-outputs/data/locale/sv-SE.ini | 4 +- plugins/obs-outputs/rtmp-stream.c | 74 +- plugins/obs-qsv11/CMakeLists.txt | 86 + plugins/obs-qsv11/QSV_Encoder.cpp | 228 +++ plugins/obs-qsv11/QSV_Encoder.h | 149 ++ plugins/obs-qsv11/QSV_Encoder_Internal.cpp | 598 +++++++ plugins/obs-qsv11/QSV_Encoder_Internal.h | 112 ++ plugins/obs-qsv11/bits/linux_defs.h | 19 + plugins/obs-qsv11/bits/windows_defs.h | 16 + plugins/obs-qsv11/common_directx11.cpp | 487 ++++++ plugins/obs-qsv11/common_directx11.h | 39 + plugins/obs-qsv11/common_utils.cpp | 306 ++++ plugins/obs-qsv11/common_utils.h | 109 ++ plugins/obs-qsv11/common_utils_windows.cpp | 104 ++ plugins/obs-qsv11/data/locale/ar-SA.ini | 5 + plugins/obs-qsv11/data/locale/ca-ES.ini | 12 + plugins/obs-qsv11/data/locale/cs-CZ.ini | 12 + plugins/obs-qsv11/data/locale/de-DE.ini | 12 + plugins/obs-qsv11/data/locale/en-US.ini | 11 + plugins/obs-qsv11/data/locale/es-ES.ini | 12 + plugins/obs-qsv11/data/locale/eu-ES.ini | 12 + plugins/obs-qsv11/data/locale/fi-FI.ini | 12 + plugins/obs-qsv11/data/locale/fr-FR.ini | 12 + plugins/obs-qsv11/data/locale/gl-ES.ini | 2 + plugins/obs-qsv11/data/locale/hr-HR.ini | 12 + plugins/obs-qsv11/data/locale/hu-HU.ini | 12 + plugins/obs-qsv11/data/locale/ja-JP.ini | 12 + plugins/obs-qsv11/data/locale/ko-KR.ini | 12 + plugins/obs-qsv11/data/locale/nl-NL.ini | 12 + plugins/obs-qsv11/data/locale/pl-PL.ini | 12 + plugins/obs-qsv11/data/locale/ro-RO.ini | 4 + plugins/obs-qsv11/data/locale/ru-RU.ini | 12 + plugins/obs-qsv11/data/locale/sr-CS.ini | 12 + plugins/obs-qsv11/data/locale/sr-SP.ini | 12 + plugins/obs-qsv11/data/locale/sv-SE.ini | 6 + plugins/obs-qsv11/data/locale/tr-TR.ini | 6 + plugins/obs-qsv11/data/locale/zh-CN.ini | 12 + plugins/obs-qsv11/data/locale/zh-TW.ini | 10 + .../libmfx/include/mfx_critical_section.h | 76 + .../obs-qsv11/libmfx/include/mfx_dispatcher.h | 213 +++ .../libmfx/include/mfx_dispatcher_defs.h | 85 + .../libmfx/include/mfx_dispatcher_log.h | 306 ++++ .../libmfx/include/mfx_dxva2_device.h | 210 +++ .../include/mfx_exposed_functions_list.h | 142 ++ .../libmfx/include/mfx_library_iterator.h | 161 ++ .../obs-qsv11/libmfx/include/mfx_load_dll.h | 59 + .../libmfx/include/mfx_load_plugin.h | 93 ++ .../libmfx/include/mfx_plugin_hive.h | 132 ++ plugins/obs-qsv11/libmfx/include/mfx_vector.h | 220 +++ .../libmfx/include/mfx_win_reg_key.h | 116 ++ .../include/mfxaudio_exposed_functions_list.h | 81 + .../include/msdk/include/mfxastructures.h | 172 ++ .../libmfx/include/msdk/include/mfxaudio++.h | 113 ++ .../libmfx/include/msdk/include/mfxaudio.h | 70 + .../libmfx/include/msdk/include/mfxcommon.h | 159 ++ .../libmfx/include/msdk/include/mfxdefs.h | 153 ++ .../libmfx/include/msdk/include/mfxenc.h | 80 + .../libmfx/include/msdk/include/mfxjpeg.h | 107 ++ .../libmfx/include/msdk/include/mfxmvc.h | 109 ++ .../libmfx/include/msdk/include/mfxpak.h | 78 + .../libmfx/include/msdk/include/mfxplugin++.h | 719 +++++++++ .../libmfx/include/msdk/include/mfxplugin.h | 206 +++ .../libmfx/include/msdk/include/mfxsession.h | 60 + .../include/msdk/include/mfxstructures.h | 1379 +++++++++++++++++ .../libmfx/include/msdk/include/mfxvideo++.h | 197 +++ .../libmfx/include/msdk/include/mfxvideo.h | 112 ++ .../include/msdk/include/mfxvstructures.h | 32 + plugins/obs-qsv11/libmfx/src/main.cpp | 937 +++++++++++ .../libmfx/src/mfx_critical_section.cpp | 88 ++ .../obs-qsv11/libmfx/src/mfx_dispatcher.cpp | 349 +++++ .../libmfx/src/mfx_dispatcher_log.cpp | 449 ++++++ .../obs-qsv11/libmfx/src/mfx_dxva2_device.cpp | 558 +++++++ .../libmfx/src/mfx_function_table.cpp | 143 ++ .../libmfx/src/mfx_library_iterator.cpp | 475 ++++++ plugins/obs-qsv11/libmfx/src/mfx_load_dll.cpp | 241 +++ .../obs-qsv11/libmfx/src/mfx_load_plugin.cpp | 458 ++++++ .../obs-qsv11/libmfx/src/mfx_plugin_hive.cpp | 500 ++++++ .../obs-qsv11/libmfx/src/mfx_win_reg_key.cpp | 228 +++ plugins/obs-qsv11/obs-qsv11-plugin-main.c | 86 + plugins/obs-qsv11/obs-qsv11.c | 694 +++++++++ plugins/obs-transitions/CMakeLists.txt | 3 + .../data/fade_to_color_transition.effect | 37 + plugins/obs-transitions/data/locale/ar-SA.ini | 10 + plugins/obs-transitions/data/locale/ca-ES.ini | 14 + plugins/obs-transitions/data/locale/cs-CZ.ini | 11 + plugins/obs-transitions/data/locale/da-DK.ini | 14 + plugins/obs-transitions/data/locale/de-DE.ini | 11 + plugins/obs-transitions/data/locale/el-GR.ini | 3 + plugins/obs-transitions/data/locale/en-US.ini | 11 + plugins/obs-transitions/data/locale/es-ES.ini | 11 + plugins/obs-transitions/data/locale/eu-ES.ini | 15 +- plugins/obs-transitions/data/locale/fi-FI.ini | 11 + plugins/obs-transitions/data/locale/fr-FR.ini | 11 + plugins/obs-transitions/data/locale/gl-ES.ini | 8 + plugins/obs-transitions/data/locale/he-IL.ini | 14 + plugins/obs-transitions/data/locale/hr-HR.ini | 11 + plugins/obs-transitions/data/locale/hu-HU.ini | 11 + plugins/obs-transitions/data/locale/ja-JP.ini | 11 + plugins/obs-transitions/data/locale/ko-KR.ini | 11 + plugins/obs-transitions/data/locale/nl-NL.ini | 11 + plugins/obs-transitions/data/locale/pl-PL.ini | 11 + plugins/obs-transitions/data/locale/pt-BR.ini | 13 + plugins/obs-transitions/data/locale/ro-RO.ini | 15 +- plugins/obs-transitions/data/locale/ru-RU.ini | 12 + plugins/obs-transitions/data/locale/sr-CS.ini | 11 + plugins/obs-transitions/data/locale/sr-SP.ini | 11 + plugins/obs-transitions/data/locale/sv-SE.ini | 13 + plugins/obs-transitions/data/locale/tr-TR.ini | 8 + plugins/obs-transitions/data/locale/zh-CN.ini | 11 + plugins/obs-transitions/data/locale/zh-TW.ini | 7 + .../data/slide_transition.effect | 45 + .../data/swipe_transition.effect | 42 + plugins/obs-transitions/easings.h | 11 + plugins/obs-transitions/obs-transitions.c | 6 + .../transition-fade-to-color.c | 178 +++ plugins/obs-transitions/transition-slide.c | 165 ++ plugins/obs-transitions/transition-swipe.c | 160 ++ plugins/obs-x264/data/locale/ar-SA.ini | 5 + plugins/obs-x264/data/locale/ca-ES.ini | 2 +- plugins/obs-x264/data/locale/cs-CZ.ini | 2 +- plugins/obs-x264/data/locale/da-DK.ini | 5 +- plugins/obs-x264/data/locale/de-DE.ini | 2 +- plugins/obs-x264/data/locale/el-GR.ini | 2 +- plugins/obs-x264/data/locale/en-US.ini | 2 +- plugins/obs-x264/data/locale/es-ES.ini | 2 +- plugins/obs-x264/data/locale/eu-ES.ini | 18 +- plugins/obs-x264/data/locale/fi-FI.ini | 2 +- plugins/obs-x264/data/locale/fr-FR.ini | 4 +- plugins/obs-x264/data/locale/gl-ES.ini | 2 +- plugins/obs-x264/data/locale/he-IL.ini | 12 + plugins/obs-x264/data/locale/hr-HR.ini | 1 - plugins/obs-x264/data/locale/hu-HU.ini | 10 +- plugins/obs-x264/data/locale/it-IT.ini | 1 - plugins/obs-x264/data/locale/ja-JP.ini | 4 +- plugins/obs-x264/data/locale/ko-KR.ini | 2 +- plugins/obs-x264/data/locale/nb-NO.ini | 1 - plugins/obs-x264/data/locale/nl-NL.ini | 2 +- plugins/obs-x264/data/locale/pl-PL.ini | 1 - plugins/obs-x264/data/locale/pt-BR.ini | 1 - plugins/obs-x264/data/locale/pt-PT.ini | 7 +- plugins/obs-x264/data/locale/ro-RO.ini | 15 +- plugins/obs-x264/data/locale/ru-RU.ini | 2 +- plugins/obs-x264/data/locale/sk-SK.ini | 1 - plugins/obs-x264/data/locale/sr-CS.ini | 1 - plugins/obs-x264/data/locale/sr-SP.ini | 1 - plugins/obs-x264/data/locale/sv-SE.ini | 2 +- plugins/obs-x264/data/locale/tr-TR.ini | 1 - plugins/obs-x264/data/locale/zh-CN.ini | 8 +- plugins/obs-x264/data/locale/zh-TW.ini | 3 +- plugins/obs-x264/obs-x264.c | 114 +- plugins/rtmp-services/data/locale/ar-SA.ini | 2 + plugins/rtmp-services/data/locale/da-DK.ini | 4 + plugins/rtmp-services/data/locale/de-DE.ini | 4 +- plugins/rtmp-services/data/locale/el-GR.ini | 3 + plugins/rtmp-services/data/locale/es-ES.ini | 2 +- plugins/rtmp-services/data/locale/eu-ES.ini | 10 +- plugins/rtmp-services/data/locale/fr-FR.ini | 6 +- plugins/rtmp-services/data/locale/he-IL.ini | 10 + plugins/rtmp-services/data/locale/hu-HU.ini | 6 +- plugins/rtmp-services/data/locale/pt-PT.ini | 6 +- plugins/rtmp-services/data/locale/ro-RO.ini | 8 +- plugins/rtmp-services/data/locale/sv-SE.ini | 5 +- plugins/rtmp-services/data/locale/tr-TR.ini | 2 +- plugins/rtmp-services/data/package.json | 4 +- plugins/rtmp-services/data/services.json | 94 +- plugins/rtmp-services/rtmp-common.c | 19 +- plugins/text-freetype2/data/locale/ar-SA.ini | 14 + plugins/text-freetype2/data/locale/da-DK.ini | 2 +- plugins/text-freetype2/data/locale/eu-ES.ini | 26 +- plugins/text-freetype2/data/locale/he-IL.ini | 14 + plugins/text-freetype2/data/locale/hu-HU.ini | 4 +- plugins/text-freetype2/data/locale/ja-JP.ini | 4 +- plugins/text-freetype2/data/locale/ro-RO.ini | 12 +- plugins/text-freetype2/data/locale/sv-SE.ini | 1 + plugins/text-freetype2/data/locale/zh-CN.ini | 2 +- .../text-freetype2/data/text_default.effect | 22 +- plugins/text-freetype2/text-freetype2.c | 6 +- plugins/text-freetype2/text-freetype2.h | 2 +- plugins/text-freetype2/text-functionality.c | 23 +- test/test-input/test-filter.c | 6 +- 529 files changed, 25112 insertions(+), 2336 deletions(-) create mode 100644 deps/libff/libff/ff-compat.h create mode 100644 libobs/data/deinterlace_base.effect create mode 100644 libobs/data/deinterlace_blend.effect create mode 100644 libobs/data/deinterlace_blend_2x.effect create mode 100644 libobs/data/deinterlace_discard.effect create mode 100644 libobs/data/deinterlace_discard_2x.effect create mode 100644 libobs/data/deinterlace_linear.effect create mode 100644 libobs/data/deinterlace_linear_2x.effect create mode 100644 libobs/data/deinterlace_yadif.effect create mode 100644 libobs/data/deinterlace_yadif_2x.effect create mode 100644 libobs/data/premultiplied_alpha.effect create mode 100644 libobs/obs-source-deinterlace.c create mode 100644 obs/data/locale/he-IL.ini create mode 100644 obs/data/locale/lt-LT.ini create mode 100644 obs/data/locale/ta-IN.ini create mode 100644 obs/installer/mp-installer.nsi create mode 100644 plugins/coreaudio-encoder/data/locale/ar-SA.ini create mode 100644 plugins/coreaudio-encoder/data/locale/da-DK.ini create mode 100644 plugins/coreaudio-encoder/data/locale/ta-IN.ini create mode 100644 plugins/decklink/data/locale/ar-SA.ini create mode 100644 plugins/decklink/data/locale/he-IL.ini create mode 100644 plugins/image-source/data/locale/he-IL.ini create mode 100644 plugins/linux-alsa/CMakeLists.txt create mode 100644 plugins/linux-alsa/alsa-input.c create mode 100644 plugins/linux-alsa/data/locale/ar-SA.ini create mode 100644 plugins/linux-alsa/data/locale/ca-ES.ini create mode 100644 plugins/linux-alsa/data/locale/cs-CZ.ini create mode 100644 plugins/linux-alsa/data/locale/da-DK.ini create mode 100644 plugins/linux-alsa/data/locale/de-DE.ini create mode 100644 plugins/linux-alsa/data/locale/en-US.ini create mode 100644 plugins/linux-alsa/data/locale/es-ES.ini create mode 100644 plugins/linux-alsa/data/locale/eu-ES.ini create mode 100644 plugins/linux-alsa/data/locale/fi-FI.ini create mode 100644 plugins/linux-alsa/data/locale/fr-FR.ini create mode 100644 plugins/linux-alsa/data/locale/gl-ES.ini create mode 100644 plugins/linux-alsa/data/locale/hr-HR.ini create mode 100644 plugins/linux-alsa/data/locale/hu-HU.ini create mode 100644 plugins/linux-alsa/data/locale/ja-JP.ini create mode 100644 plugins/linux-alsa/data/locale/ko-KR.ini create mode 100644 plugins/linux-alsa/data/locale/nl-NL.ini create mode 100644 plugins/linux-alsa/data/locale/pl-PL.ini create mode 100644 plugins/linux-alsa/data/locale/pt-BR.ini create mode 100644 plugins/linux-alsa/data/locale/ro-RO.ini create mode 100644 plugins/linux-alsa/data/locale/ru-RU.ini create mode 100644 plugins/linux-alsa/data/locale/sr-CS.ini create mode 100644 plugins/linux-alsa/data/locale/sr-SP.ini create mode 100644 plugins/linux-alsa/data/locale/sv-SE.ini create mode 100644 plugins/linux-alsa/data/locale/tr-TR.ini create mode 100644 plugins/linux-alsa/data/locale/zh-CN.ini create mode 100644 plugins/linux-alsa/data/locale/zh-TW.ini create mode 100644 plugins/linux-alsa/linux-alsa.c create mode 100644 plugins/linux-capture/data/locale/he-IL.ini create mode 100644 plugins/linux-jack/data/locale/ar-SA.ini create mode 100644 plugins/linux-jack/data/locale/he-IL.ini create mode 100644 plugins/linux-pulseaudio/data/locale/he-IL.ini create mode 100644 plugins/linux-v4l2/data/locale/he-IL.ini create mode 100644 plugins/mac-capture/data/locale/bg-BG.ini create mode 100644 plugins/mac-syphon/data/locale/ar-SA.ini create mode 100644 plugins/mac-vth264/data/locale/ar-SA.ini create mode 100644 plugins/mac-vth264/data/locale/el-GR.ini create mode 100644 plugins/mac-vth264/data/locale/sv-SE.ini create mode 100644 plugins/mac-vth264/data/locale/tr-TR.ini create mode 100644 plugins/obs-ffmpeg/data/locale/he-IL.ini create mode 100644 plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c create mode 100644 plugins/obs-filters/data/locale/ar-SA.ini create mode 100644 plugins/obs-filters/data/locale/he-IL.ini create mode 100644 plugins/obs-libfdk/data/locale/he-IL.ini create mode 100644 plugins/obs-outputs/data/locale/he-IL.ini create mode 100644 plugins/obs-qsv11/CMakeLists.txt create mode 100644 plugins/obs-qsv11/QSV_Encoder.cpp create mode 100644 plugins/obs-qsv11/QSV_Encoder.h create mode 100644 plugins/obs-qsv11/QSV_Encoder_Internal.cpp create mode 100644 plugins/obs-qsv11/QSV_Encoder_Internal.h create mode 100644 plugins/obs-qsv11/bits/linux_defs.h create mode 100644 plugins/obs-qsv11/bits/windows_defs.h create mode 100644 plugins/obs-qsv11/common_directx11.cpp create mode 100644 plugins/obs-qsv11/common_directx11.h create mode 100644 plugins/obs-qsv11/common_utils.cpp create mode 100644 plugins/obs-qsv11/common_utils.h create mode 100644 plugins/obs-qsv11/common_utils_windows.cpp create mode 100644 plugins/obs-qsv11/data/locale/ar-SA.ini create mode 100644 plugins/obs-qsv11/data/locale/ca-ES.ini create mode 100644 plugins/obs-qsv11/data/locale/cs-CZ.ini create mode 100644 plugins/obs-qsv11/data/locale/de-DE.ini create mode 100644 plugins/obs-qsv11/data/locale/en-US.ini create mode 100644 plugins/obs-qsv11/data/locale/es-ES.ini create mode 100644 plugins/obs-qsv11/data/locale/eu-ES.ini create mode 100644 plugins/obs-qsv11/data/locale/fi-FI.ini create mode 100644 plugins/obs-qsv11/data/locale/fr-FR.ini create mode 100644 plugins/obs-qsv11/data/locale/gl-ES.ini create mode 100644 plugins/obs-qsv11/data/locale/hr-HR.ini create mode 100644 plugins/obs-qsv11/data/locale/hu-HU.ini create mode 100644 plugins/obs-qsv11/data/locale/ja-JP.ini create mode 100644 plugins/obs-qsv11/data/locale/ko-KR.ini create mode 100644 plugins/obs-qsv11/data/locale/nl-NL.ini create mode 100644 plugins/obs-qsv11/data/locale/pl-PL.ini create mode 100644 plugins/obs-qsv11/data/locale/ro-RO.ini create mode 100644 plugins/obs-qsv11/data/locale/ru-RU.ini create mode 100644 plugins/obs-qsv11/data/locale/sr-CS.ini create mode 100644 plugins/obs-qsv11/data/locale/sr-SP.ini create mode 100644 plugins/obs-qsv11/data/locale/sv-SE.ini create mode 100644 plugins/obs-qsv11/data/locale/tr-TR.ini create mode 100644 plugins/obs-qsv11/data/locale/zh-CN.ini create mode 100644 plugins/obs-qsv11/data/locale/zh-TW.ini create mode 100644 plugins/obs-qsv11/libmfx/include/mfx_critical_section.h create mode 100644 plugins/obs-qsv11/libmfx/include/mfx_dispatcher.h create mode 100644 plugins/obs-qsv11/libmfx/include/mfx_dispatcher_defs.h create mode 100644 plugins/obs-qsv11/libmfx/include/mfx_dispatcher_log.h create mode 100644 plugins/obs-qsv11/libmfx/include/mfx_dxva2_device.h create mode 100644 plugins/obs-qsv11/libmfx/include/mfx_exposed_functions_list.h create mode 100644 plugins/obs-qsv11/libmfx/include/mfx_library_iterator.h create mode 100644 plugins/obs-qsv11/libmfx/include/mfx_load_dll.h create mode 100644 plugins/obs-qsv11/libmfx/include/mfx_load_plugin.h create mode 100644 plugins/obs-qsv11/libmfx/include/mfx_plugin_hive.h create mode 100644 plugins/obs-qsv11/libmfx/include/mfx_vector.h create mode 100644 plugins/obs-qsv11/libmfx/include/mfx_win_reg_key.h create mode 100644 plugins/obs-qsv11/libmfx/include/mfxaudio_exposed_functions_list.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxastructures.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxaudio++.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxaudio.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxcommon.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxdefs.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxenc.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxjpeg.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxmvc.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxpak.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxplugin++.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxplugin.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxsession.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxstructures.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxvideo++.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxvideo.h create mode 100644 plugins/obs-qsv11/libmfx/include/msdk/include/mfxvstructures.h create mode 100644 plugins/obs-qsv11/libmfx/src/main.cpp create mode 100644 plugins/obs-qsv11/libmfx/src/mfx_critical_section.cpp create mode 100644 plugins/obs-qsv11/libmfx/src/mfx_dispatcher.cpp create mode 100644 plugins/obs-qsv11/libmfx/src/mfx_dispatcher_log.cpp create mode 100644 plugins/obs-qsv11/libmfx/src/mfx_dxva2_device.cpp create mode 100644 plugins/obs-qsv11/libmfx/src/mfx_function_table.cpp create mode 100644 plugins/obs-qsv11/libmfx/src/mfx_library_iterator.cpp create mode 100644 plugins/obs-qsv11/libmfx/src/mfx_load_dll.cpp create mode 100644 plugins/obs-qsv11/libmfx/src/mfx_load_plugin.cpp create mode 100644 plugins/obs-qsv11/libmfx/src/mfx_plugin_hive.cpp create mode 100644 plugins/obs-qsv11/libmfx/src/mfx_win_reg_key.cpp create mode 100644 plugins/obs-qsv11/obs-qsv11-plugin-main.c create mode 100644 plugins/obs-qsv11/obs-qsv11.c create mode 100644 plugins/obs-transitions/data/fade_to_color_transition.effect create mode 100644 plugins/obs-transitions/data/locale/ar-SA.ini create mode 100644 plugins/obs-transitions/data/locale/ca-ES.ini create mode 100644 plugins/obs-transitions/data/locale/da-DK.ini create mode 100644 plugins/obs-transitions/data/locale/el-GR.ini create mode 100644 plugins/obs-transitions/data/locale/gl-ES.ini create mode 100644 plugins/obs-transitions/data/locale/he-IL.ini create mode 100644 plugins/obs-transitions/data/locale/pt-BR.ini create mode 100644 plugins/obs-transitions/data/locale/sv-SE.ini create mode 100644 plugins/obs-transitions/data/locale/zh-TW.ini create mode 100644 plugins/obs-transitions/data/slide_transition.effect create mode 100644 plugins/obs-transitions/data/swipe_transition.effect create mode 100644 plugins/obs-transitions/easings.h create mode 100644 plugins/obs-transitions/transition-fade-to-color.c create mode 100644 plugins/obs-transitions/transition-slide.c create mode 100644 plugins/obs-transitions/transition-swipe.c create mode 100644 plugins/obs-x264/data/locale/he-IL.ini create mode 100644 plugins/rtmp-services/data/locale/he-IL.ini create mode 100644 plugins/text-freetype2/data/locale/ar-SA.ini create mode 100644 plugins/text-freetype2/data/locale/he-IL.ini diff --git a/cmake/Modules/CopyMSVCBins.cmake b/cmake/Modules/CopyMSVCBins.cmake index f3cef15..1dd0723 100644 --- a/cmake/Modules/CopyMSVCBins.cmake +++ b/cmake/Modules/CopyMSVCBins.cmake @@ -68,6 +68,9 @@ file(GLOB FFMPEG_BIN_FILES "${FFMPEG_avcodec_INCLUDE_DIR}/bin/libogg*.dll" "${FFMPEG_avcodec_INCLUDE_DIR}/bin/libvorbis*.dll" + "${FFMPEG_avcodec_INCLUDE_DIR}/../bin/libvpx*.dll" + "${FFMPEG_avcodec_INCLUDE_DIR}/bin/libvpx*.dll" + "${FFMPEG_avcodec_INCLUDE_DIR}/../bin${_bin_suffix}/libopus*.dll" "${FFMPEG_avcodec_INCLUDE_DIR}/../bin${_bin_suffix}/opus*.dll" "${FFMPEG_avcodec_INCLUDE_DIR}/bin${_bin_suffix}/libopus*.dll" diff --git a/deps/file-updater/file-updater/file-updater.c b/deps/file-updater/file-updater/file-updater.c index 04ed70b..4743541 100644 --- a/deps/file-updater/file-updater/file-updater.c +++ b/deps/file-updater/file-updater/file-updater.c @@ -29,6 +29,9 @@ struct update_info { obs_data_t *cache_package; obs_data_t *remote_package; + char *etag_local; + char *etag_remote; + confirm_file_callback_t callback; void *param; @@ -76,7 +79,33 @@ static size_t http_write(uint8_t *ptr, size_t size, size_t nmemb, return total; } -static bool do_http_request(struct update_info *info, const char *url) +static size_t http_header(char *buffer, size_t size, size_t nitems, + struct update_info *info) +{ + if (!strncmp(buffer, "ETag: ", 6)) + { + char *etag = buffer + 6; + if (*etag) { + char *etag_clean, *p; + + etag_clean = bstrdup(etag); + + p = strchr(etag_clean, '\r'); + if (p) + *p = 0; + + p = strchr(etag_clean, '\n'); + if (p) + *p = 0; + + info->etag_remote = etag_clean; + } + } + return nitems * size; +} + +static bool do_http_request(struct update_info *info, const char *url, + long *response_code) { CURLcode code; uint8_t null_terminator = 0; @@ -89,6 +118,17 @@ 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); + 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_HEADERDATA, info); + } + +#if LIBCURL_VERSION_NUM >= 0x072400 + // A lot of servers don't yet support ALPN + curl_easy_setopt(info->curl, CURLOPT_SSL_ENABLE_ALPN, 0); +#endif + code = curl_easy_perform(info->curl); if (code != CURLE_OK) { warn("Remote update of URL \"%s\" failed: %s", url, @@ -96,6 +136,16 @@ static bool do_http_request(struct update_info *info, const char *url) return false; } + if (curl_easy_getinfo(info->curl, CURLINFO_RESPONSE_CODE, + response_code) != CURLE_OK) + return false; + + if (*response_code >= 400) { + warn("Remote update of URL \"%s\" failed: HTTP/%ld", url, + *response_code); + return false; + } + da_push_back(info->file_data, &null_terminator); return true; @@ -135,6 +185,25 @@ static bool init_update(struct update_info *info) info->local_package = get_package(info->local, "package.json"); info->cache_package = get_package(info->cache, "package.json"); + obs_data_t *metadata = get_package(info->cache, "meta.json"); + if (metadata) { + const char *etag = obs_data_get_string(metadata, "etag"); + if (etag) { + 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); + + dstr_free(&if_none_match); + } + + obs_data_release(metadata); + } + dstr_copy(&user_agent, "User-Agent: "); dstr_cat(&user_agent, info->user_agent); @@ -246,10 +315,11 @@ 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) { + long response_code; char *full_url = get_path(url, file); - bool success = do_http_request(info, full_url); + bool success = do_http_request(info, full_url, &response_code); bfree(full_url); - return success; + return success && response_code == 200; } static inline void write_file_data(struct update_info *info, @@ -320,11 +390,34 @@ static bool update_remote_files(void *param, obs_data_t *remote_file) return true; } +static void update_save_metadata(struct update_info *info) +{ + struct dstr path = { 0 }; + + if (!info->etag_remote) + return; + + dstr_copy(&path, info->cache); + dstr_cat(&path, "meta.json"); + + obs_data_t *data; + data = obs_data_create(); + obs_data_set_string(data, "etag", info->etag_remote); + obs_data_save_json(data, path.array); + obs_data_release(data); + + dstr_free(&path); +} + static void update_remote_version(struct update_info *info, int cur_version) { int remote_version; + long response_code; - if (!do_http_request(info, info->url)) + if (!do_http_request(info, info->url, &response_code)) + return; + + if (response_code == 304) return; if (!info->file_data.array || info->file_data.array[0] != '{') { @@ -332,6 +425,8 @@ static void update_remote_version(struct update_info *info, int cur_version) return; } + update_save_metadata(info); + info->remote_package = obs_data_create_from_json( (char*)info->file_data.array); if (!info->remote_package) { @@ -371,6 +466,12 @@ static void *update_thread(void *data) cur_version = update_local_version(info); update_remote_version(info, cur_version); os_rmdir(info->temp); + + if (info->etag_local) + bfree(info->etag_local); + if (info->etag_remote) + bfree(info->etag_remote); + return NULL; } diff --git a/deps/libff/libff/ff-audio-decoder.c b/deps/libff/libff/ff-audio-decoder.c index f951fdd..07853c1 100644 --- a/deps/libff/libff/ff-audio-decoder.c +++ b/deps/libff/libff/ff-audio-decoder.c @@ -28,6 +28,8 @@ #include +#include "ff-compat.h" + static inline void shrink_packet(struct ff_packet *packet, int packet_length) { if (packet_length <= packet->base.size) { @@ -47,11 +49,6 @@ static bool handle_reset_packet(struct ff_decoder *decoder, decoder->clock = packet->clock; av_free_packet(&packet->base); - // not a real packet, so try to get another packet - if (packet_queue_get(&decoder->packet_queue, packet, 1) - == FF_PACKET_FAIL) - return false; - return true; } @@ -73,6 +70,28 @@ static int decode_frame(struct ff_decoder *decoder, int ret; while (true) { + if (decoder->eof) + ret = packet_queue_get(&decoder->packet_queue, packet, 0); + else + ret = packet_queue_get(&decoder->packet_queue, packet, 1); + + if (ret == FF_PACKET_EMPTY) { + return 0; + } else if (ret == FF_PACKET_FAIL) { + return -1; + } + + if (packet->base.data == + decoder->packet_queue.flush_packet.base.data) { + avcodec_flush_buffers(decoder->codec); + continue; + } + + // Packet has a new clock (reset packet) + if (packet->clock != NULL) + if (!handle_reset_packet(decoder, packet)) + return -1; + while (packet->base.size > 0) { int complete; @@ -93,33 +112,11 @@ 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) av_packet_unref(&packet->base); - - ret = packet_queue_get(&decoder->packet_queue, packet, 1); - if (ret == FF_PACKET_FAIL) { - return -1; - } - - if (packet->base.data == - decoder->packet_queue.flush_packet.base.data) { - avcodec_flush_buffers(decoder->codec); - - // we were flushed, so try to get another packet - ret = packet_queue_get(&decoder->packet_queue, - packet, 1); - if (ret == FF_PACKET_FAIL) { - return -1; - } - } - - // Packet has a new clock (reset packet) - if (packet->clock != NULL) - if (!handle_reset_packet(decoder, packet)) - return -1; } } @@ -143,8 +140,10 @@ static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame, || queue_frame->frame->sample_rate != codec->sample_rate || queue_frame->frame->format != codec->sample_fmt); - if (queue_frame->frame != NULL) + if (queue_frame->frame != NULL) { + //FIXME: this shouldn't happen any more! av_frame_free(&queue_frame->frame); + } queue_frame->frame = av_frame_clone(frame); queue_frame->clock = ff_clock_retain(decoder->clock); @@ -166,10 +165,13 @@ void *ff_audio_decoder_thread(void *opaque_audio_decoder) struct ff_packet packet = {0}; bool frame_complete; AVFrame *frame = av_frame_alloc(); + int ret; while (!decoder->abort) { - if (decode_frame(decoder, &packet, frame, &frame_complete) - < 0) { + ret = decode_frame(decoder, &packet, frame, &frame_complete); + if (ret == 0) { + break; + } else if (ret < 0) { av_free_packet(&packet.base); continue; } @@ -193,5 +195,8 @@ void *ff_audio_decoder_thread(void *opaque_audio_decoder) ff_clock_release(&decoder->clock); av_frame_free(&frame); + + decoder->finished = true; + return NULL; } diff --git a/deps/libff/libff/ff-compat.h b/deps/libff/libff/ff-compat.h new file mode 100644 index 0000000..ba2bdf3 --- /dev/null +++ b/deps/libff/libff/ff-compat.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016 Hugh Bailey + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma once + +#if LIBAVCODEC_VERSION_MAJOR >= 57 +#define av_free_packet av_packet_unref +static inline int av_dup_packet_2(AVPacket *pkt) +{ + AVPacket tmp = *pkt; + int ret = av_packet_ref(pkt, &tmp); + av_packet_unref(&tmp); + return ret; +} +#define av_dup_packet av_dup_packet_2 +#endif diff --git a/deps/libff/libff/ff-decoder.c b/deps/libff/libff/ff-decoder.c index cd12e61..a0e4088 100644 --- a/deps/libff/libff/ff-decoder.c +++ b/deps/libff/libff/ff-decoder.c @@ -42,6 +42,7 @@ struct ff_decoder *ff_decoder_init(AVCodecContext *codec_context, decoder->codec->opaque = decoder; decoder->stream = stream; decoder->abort = false; + decoder->finished = false; decoder->packet_queue_size = packet_queue_size; if (!packet_queue_init(&decoder->packet_queue)) @@ -179,7 +180,7 @@ void ff_decoder_refresh(void *opaque) if (decoder && decoder->stream) { if (decoder->frame_queue.size == 0) { - if (!decoder->eof) { + if (!decoder->eof || !decoder->finished) { // We expected a frame, but there were none // available @@ -280,6 +281,8 @@ void ff_decoder_refresh(void *opaque) (int)(delay_until_next_wake * 1000 + 0.5L)); + av_frame_free(&frame->frame); + ff_circular_queue_advance_read(&decoder->frame_queue); } } else { diff --git a/deps/libff/libff/ff-decoder.h b/deps/libff/libff/ff-decoder.h index c0df5fc..0050046 100644 --- a/deps/libff/libff/ff-decoder.h +++ b/deps/libff/libff/ff-decoder.h @@ -56,6 +56,7 @@ struct ff_decoder { bool first_frame; bool eof; bool abort; + bool finished; }; typedef struct ff_decoder ff_decoder_t; diff --git a/deps/libff/libff/ff-demuxer.c b/deps/libff/libff/ff-demuxer.c index e635f27..2feef7a 100644 --- a/deps/libff/libff/ff-demuxer.c +++ b/deps/libff/libff/ff-demuxer.c @@ -23,6 +23,8 @@ #include +#include "ff-compat.h" + #define DEFAULT_AV_SYNC_TYPE AV_SYNC_VIDEO_MASTER #define AUDIO_FRAME_QUEUE_SIZE 1 @@ -92,7 +94,7 @@ void ff_demuxer_free(struct ff_demuxer *demuxer) ff_decoder_free(demuxer->video_decoder); if (demuxer->format_context) - avformat_free_context(demuxer->format_context); + avformat_close_input(&demuxer->format_context); av_free(demuxer); } @@ -342,15 +344,15 @@ void ff_demuxer_reset(struct ff_demuxer *demuxer) packet.clock = clock; if (demuxer->audio_decoder != NULL) { + ff_clock_retain(clock); packet_queue_put(&demuxer->audio_decoder->packet_queue, &packet); - ff_clock_retain(clock); } if (demuxer->video_decoder != NULL) { + ff_clock_retain(clock); packet_queue_put(&demuxer->video_decoder->packet_queue, &packet); - ff_clock_retain(clock); } } @@ -500,7 +502,7 @@ static bool handle_seek(struct ff_demuxer *demuxer) seek_stream = demuxer->audio_decoder->stream; } - if (seek_stream != NULL) { + 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); @@ -529,8 +531,13 @@ static bool handle_seek(struct ff_demuxer *demuxer) static void seek_beginning(struct ff_demuxer *demuxer) { - demuxer->seek_flags = AVSEEK_FLAG_BACKWARD; - demuxer->seek_pos = demuxer->format_context->start_time; + if (demuxer->format_context->duration == AV_NOPTS_VALUE) { + demuxer->seek_flags = AVSEEK_FLAG_FRAME; + demuxer->seek_pos = 0; + } else { + demuxer->seek_flags = AVSEEK_FLAG_BACKWARD; + demuxer->seek_pos = demuxer->format_context->start_time; + } demuxer->seek_request = true; demuxer->seek_flush = false; av_log(NULL, AV_LOG_VERBOSE, "looping media %s", demuxer->input); diff --git a/deps/libff/libff/ff-packet-queue.c b/deps/libff/libff/ff-packet-queue.c index bec472f..dd85dd4 100644 --- a/deps/libff/libff/ff-packet-queue.c +++ b/deps/libff/libff/ff-packet-queue.c @@ -15,6 +15,7 @@ */ #include "ff-packet-queue.h" +#include "ff-compat.h" bool packet_queue_init(struct ff_packet_queue *q) { @@ -60,10 +61,6 @@ int packet_queue_put(struct ff_packet_queue *q, struct ff_packet *packet) { struct ff_packet_list *new_packet; - if (packet != &q->flush_packet - && av_dup_packet(&packet->base) < 0) - return FF_PACKET_FAIL; - new_packet = av_malloc(sizeof(struct ff_packet_list)); if (new_packet == NULL) diff --git a/deps/libff/libff/ff-timer.c b/deps/libff/libff/ff-timer.c index 2c74beb..c0b301b 100644 --- a/deps/libff/libff/ff-timer.c +++ b/deps/libff/libff/ff-timer.c @@ -51,6 +51,9 @@ static void *timer_thread(void *opaque) - current_time)); } + pthread_mutex_unlock(&timer->mutex); + continue; + // we can be woken up merely to set a sooner wake time } else { diff --git a/deps/libff/libff/ff-video-decoder.c b/deps/libff/libff/ff-video-decoder.c index 20e00cb..040d232 100644 --- a/deps/libff/libff/ff-video-decoder.c +++ b/deps/libff/libff/ff-video-decoder.c @@ -27,6 +27,8 @@ #include +#include "ff-compat.h" + static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame, double best_effort_pts) { @@ -49,8 +51,11 @@ static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame, || queue_frame->frame->height != codec->height || queue_frame->frame->format != codec->pix_fmt); - if (queue_frame->frame != NULL) + if (queue_frame->frame != NULL) { + // This shouldn't happen any more, the frames are freed in + // ff_decoder_refresh. av_frame_free(&queue_frame->frame); + } queue_frame->frame = av_frame_clone(frame); queue_frame->clock = ff_clock_retain(decoder->clock); @@ -76,8 +81,12 @@ void *ff_video_decoder_thread(void *opaque_video_decoder) bool key_frame; while (!decoder->abort) { - ret = packet_queue_get(&decoder->packet_queue, &packet, 1); - if (ret == FF_PACKET_FAIL) { + if (decoder->eof) + ret = packet_queue_get(&decoder->packet_queue, &packet, 0); + else + 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; } @@ -135,5 +144,8 @@ void *ff_video_decoder_thread(void *opaque_video_decoder) ff_clock_release(&decoder->clock); av_frame_free(&frame); + + decoder->finished = true; + return NULL; } diff --git a/libobs-opengl/gl-indexbuffer.c b/libobs-opengl/gl-indexbuffer.c index 82251f2..2210fbc 100644 --- a/libobs-opengl/gl-indexbuffer.c +++ b/libobs-opengl/gl-indexbuffer.c @@ -22,8 +22,8 @@ static inline bool init_ib(struct gs_index_buffer *ib) GLenum usage = ib->dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW; bool success; - success = gl_create_buffer(GL_ARRAY_BUFFER, &ib->buffer, ib->size, - ib->data, usage); + success = gl_create_buffer(GL_ELEMENT_ARRAY_BUFFER, &ib->buffer, + ib->size, ib->data, usage); if (!ib->dynamic) { bfree(ib->data); @@ -77,7 +77,8 @@ void gs_indexbuffer_flush(gs_indexbuffer_t *ib) goto fail; } - if (!update_buffer(GL_ARRAY_BUFFER, ib->buffer, ib->data, ib->size)) + if (!update_buffer(GL_ELEMENT_ARRAY_BUFFER, ib->buffer, ib->data, + ib->size)) goto fail; return; @@ -103,11 +104,5 @@ enum gs_index_type gs_indexbuffer_get_type(const gs_indexbuffer_t *ib) void device_load_indexbuffer(gs_device_t *device, gs_indexbuffer_t *ib) { - if (ib == device->cur_index_buffer) - return; - device->cur_index_buffer = ib; - - if (!gl_bind_buffer(GL_ELEMENT_ARRAY_BUFFER, ib->buffer)) - blog(LOG_ERROR, "device_load_indexbuffer (GL) failed"); } diff --git a/libobs-opengl/gl-shaderparser.c b/libobs-opengl/gl-shaderparser.c index 7dc505d..61f19dc 100644 --- a/libobs-opengl/gl-shaderparser.c +++ b/libobs-opengl/gl-shaderparser.c @@ -63,6 +63,12 @@ static bool gl_write_type_n(struct gl_shader_parser *glsp, dstr_cat(&glsp->gl_string, "vec3"); else if (cmp_type(type, len, "float4", 6) == 0) dstr_cat(&glsp->gl_string, "vec4"); + else if (cmp_type(type, len, "int2", 4) == 0) + dstr_cat(&glsp->gl_string, "ivec2"); + else if (cmp_type(type, len, "int3", 4) == 0) + dstr_cat(&glsp->gl_string, "ivec3"); + else if (cmp_type(type, len, "int4", 4) == 0) + dstr_cat(&glsp->gl_string, "ivec4"); else if (cmp_type(type, len, "float3x3", 8) == 0) dstr_cat(&glsp->gl_string, "mat3x3"); else if (cmp_type(type, len, "float3x4", 8) == 0) @@ -294,20 +300,21 @@ 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) + 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; - 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 (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; + } var->gl_sampler_id = sampler_id; @@ -330,14 +337,21 @@ static bool gl_write_texture_code(struct gl_shader_parser *glsp, if (!cf_token_is(cfp, ".")) return false; if (!cf_next_token(cfp)) return false; + const char *function_end = ")"; + if (cf_token_is(cfp, "Sample")) - written = gl_write_texture_call(glsp, var, "texture"); + written = gl_write_texture_call(glsp, var, "texture", true); else if (cf_token_is(cfp, "SampleBias")) - written = gl_write_texture_call(glsp, var, "texture"); + written = gl_write_texture_call(glsp, var, "texture", true); else if (cf_token_is(cfp, "SampleGrad")) - written = gl_write_texture_call(glsp, var, "textureGrad"); + written = gl_write_texture_call(glsp, var, "textureGrad", true); else if (cf_token_is(cfp, "SampleLevel")) - written = gl_write_texture_call(glsp, var, "textureLod"); + written = gl_write_texture_call(glsp, var, "textureLod", true); + else if (cf_token_is(cfp, "Load")) { + written = gl_write_texture_call(glsp, var, "texelFetch", false); + dstr_cat(&glsp->gl_string, "("); + function_end = ").xy, 0)"; + } if (!written) return false; @@ -345,7 +359,7 @@ static bool gl_write_texture_code(struct gl_shader_parser *glsp, if (!cf_next_token(cfp)) return false; gl_write_function_contents(glsp, &cfp->cur_token, ")"); - dstr_cat(&glsp->gl_string, ")"); + dstr_cat(&glsp->gl_string, function_end); *p_token = cfp->cur_token; return true; diff --git a/libobs-opengl/gl-subsystem.c b/libobs-opengl/gl-subsystem.c index e43d839..3ce12e2 100644 --- a/libobs-opengl/gl-subsystem.c +++ b/libobs-opengl/gl-subsystem.c @@ -470,7 +470,11 @@ void device_load_texture(gs_device_t *device, gs_texture_t *tex, int unit) if (!tex) return; - sampler = device->cur_samplers[param->sampler_id]; + // texelFetch doesn't need a sampler + if (param->sampler_id != (size_t)-1) + sampler = device->cur_samplers[param->sampler_id]; + else + sampler = NULL; if (!gl_bind_texture(tex->gl_target, tex->texture)) goto fail; @@ -975,7 +979,7 @@ 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); + load_vb_buffers(program, device->cur_vertex_buffer, ib); if (program != device->cur_program && device->cur_program) { glUseProgram(0); diff --git a/libobs-opengl/gl-subsystem.h b/libobs-opengl/gl-subsystem.h index 0b550de..8f360b9 100644 --- a/libobs-opengl/gl-subsystem.h +++ b/libobs-opengl/gl-subsystem.h @@ -39,7 +39,7 @@ enum copy_type { static inline GLint convert_gs_format(enum gs_color_format format) { switch (format) { - case GS_A8: return GL_RGBA; + case GS_A8: return GL_RED; case GS_R8: return GL_RED; case GS_RGBA: return GL_RGBA; case GS_BGRX: return GL_BGRA; @@ -377,7 +377,7 @@ struct gs_vertex_buffer { }; extern bool load_vb_buffers(struct gs_program *program, - struct gs_vertex_buffer *vb); + struct gs_vertex_buffer *vb, struct gs_index_buffer *ib); struct gs_index_buffer { GLuint buffer; diff --git a/libobs-opengl/gl-vertexbuffer.c b/libobs-opengl/gl-vertexbuffer.c index 6744d20..62f2476 100644 --- a/libobs-opengl/gl-vertexbuffer.c +++ b/libobs-opengl/gl-vertexbuffer.c @@ -234,7 +234,8 @@ static bool load_vb_buffer(struct shader_attrib *attrib, return success; } -bool load_vb_buffers(struct gs_program *program, struct gs_vertex_buffer *vb) +bool load_vb_buffers(struct gs_program *program, struct gs_vertex_buffer *vb, + struct gs_index_buffer *ib) { struct gs_shader *shader = program->vertex_shader; size_t i; @@ -248,6 +249,9 @@ bool load_vb_buffers(struct gs_program *program, struct gs_vertex_buffer *vb) return false; } + if (ib && !gl_bind_buffer(GL_ELEMENT_ARRAY_BUFFER, ib->buffer)) + return false; + return true; } diff --git a/libobs/CMakeLists.txt b/libobs/CMakeLists.txt index a124c21..3cf6bd8 100644 --- a/libobs/CMakeLists.txt +++ b/libobs/CMakeLists.txt @@ -273,6 +273,7 @@ set(libobs_libobs_SOURCES obs-encoder.c obs-service.c obs-source.c + obs-source-deinterlace.c obs-source-transition.c obs-output.c obs-output-delay.c diff --git a/libobs/data/default_rect.effect b/libobs/data/default_rect.effect index b9660b2..e8364ef 100644 --- a/libobs/data/default_rect.effect +++ b/libobs/data/default_rect.effect @@ -1,7 +1,4 @@ uniform float4x4 ViewProj; -uniform float4x4 color_matrix; -uniform float3 color_range_min = {0.0, 0.0, 0.0}; -uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform texture_rect image; sampler_state def_sampler { @@ -28,13 +25,6 @@ float4 PSDrawBare(VertInOut vert_in) : TARGET return image.Sample(def_sampler, vert_in.uv); } -float4 PSDrawMatrix(VertInOut vert_in) : TARGET -{ - float4 yuv = image.Sample(def_sampler, vert_in.uv); - yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max); - return saturate(mul(float4(yuv.xyz, 1.0), color_matrix)); -} - technique Draw { pass @@ -43,13 +33,3 @@ technique Draw pixel_shader = PSDrawBare(vert_in); } } - -technique DrawMatrix -{ - pass - { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSDrawMatrix(vert_in); - } -} - diff --git a/libobs/data/deinterlace_base.effect b/libobs/data/deinterlace_base.effect new file mode 100644 index 0000000..8755da7 --- /dev/null +++ b/libobs/data/deinterlace_base.effect @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2015 Ruwen Hahn + * John R. Bradley + * Hugh Bailey "Jim" + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +uniform float4x4 ViewProj; +uniform texture2d image; +uniform float4x4 color_matrix; +uniform float3 color_range_min = {0.0, 0.0, 0.0}; +uniform float3 color_range_max = {1.0, 1.0, 1.0}; + +uniform texture2d previous_image; +uniform float2 dimensions; +uniform int field_order; +uniform bool frame2; + +sampler_state textureSampler { + Filter = Linear; + AddressU = Clamp; + AddressV = Clamp; +}; + +struct VertData { + float4 pos : POSITION; + float2 uv : TEXCOORD0; +}; + +int3 select(int2 texel, int x, int y) +{ + return int3(texel + int2(x, y), 0); +} + +float4 load_at_prev(int2 texel, int x, int y) +{ + return previous_image.Load(select(texel, x, y)); +} + +float4 load_at_image(int2 texel, int x, int y) +{ + return image.Load(select(texel, x, y)); +} + +float4 load_at(int2 texel, int x, int y, int field) +{ + if(field == 0) + return load_at_image(texel, x, y); + else + return load_at_prev(texel, x, y); +} + +#define YADIF_UPDATE(c, level) \ + if(score.c < spatial_score.c) \ + { \ + spatial_score.c = score.c; \ + spatial_pred.c = (load_at(texel, level, -1, field) + load_at(texel, -level, 1, field)).c / 2; \ + +#define YADIF_CHECK_ONE(level, c) \ +{ \ + float4 score = abs(load_at(texel, -1 + level, 1, field) - load_at(texel, -1 - level, -1, field)) + \ + abs(load_at(texel, level, 1, field) - load_at(texel, -level, -1, field)) + \ + abs(load_at(texel, 1 + level, 1, field) - load_at(texel, 1 - level, -1, field)); \ + YADIF_UPDATE(c, level) } \ +} + +#define YADIF_CHECK(level) \ +{ \ + float4 score = abs(load_at(texel, -1 + level, 1, field) - load_at(texel, -1 - level, -1, field)) + \ + abs(load_at(texel, level, 1, field) - load_at(texel, -level, -1, field)) + \ + abs(load_at(texel, 1 + level, 1, field) - load_at(texel, 1 - level, -1, field)); \ + YADIF_UPDATE(r, level) YADIF_CHECK_ONE(level * 2, r) } \ + YADIF_UPDATE(g, level) YADIF_CHECK_ONE(level * 2, g) } \ + YADIF_UPDATE(b, level) YADIF_CHECK_ONE(level * 2, b) } \ + YADIF_UPDATE(a, level) YADIF_CHECK_ONE(level * 2, a) } \ +} + +float4 texel_at_yadif(int2 texel, int field, bool mode0) +{ + if((texel.y % 2) == field) + return load_at(texel, 0, 0, field); + + #define YADIF_AVG(x_off, y_off) ((load_at_prev(texel, x_off, y_off) + load_at_image(texel, x_off, y_off))/2) + float4 c = load_at(texel, 0, 1, field), + d = YADIF_AVG(0, 0), + e = load_at(texel, 0, -1, field); + + float4 temporal_diff0 = (abs(load_at_prev(texel, 0, 0) - load_at_image(texel, 0, 0))) / 2, + temporal_diff1 = (abs(load_at_prev(texel, 0, 1) - c) + abs(load_at_prev(texel, 0, -1) - e)) / 2, + temporal_diff2 = (abs(load_at_image(texel, 0, 1) - c) + abs(load_at_image(texel, 0, -1) - e)) / 2, + diff = max(temporal_diff0, max(temporal_diff1, temporal_diff2)); + + float4 spatial_pred = (c + e) / 2, + spatial_score = abs(load_at(texel, -1, 1, field) - load_at(texel, -1, -1, field)) + + abs(c - e) + + abs(load_at(texel, 1, 1, field) - load_at(texel, 1, -1, field)) - 1; + + YADIF_CHECK(-1) + YADIF_CHECK(1) + + if (mode0) { + float4 b = YADIF_AVG(0, 2), + f = YADIF_AVG(0, -2); + + float4 max_ = max(d - e, max(d - c, min(b - c, f - e))), + min_ = min(d - e, min(d - c, max(b - c, f - e))); + + diff = max(diff, max(min_, -max_)); + } else { + diff = max(diff, max(min(d - e, d - c), -max(d - e, d - c))); + } + +#define YADIF_SPATIAL(c) \ +{ \ + if(spatial_pred.c > d.c + diff.c) \ + spatial_pred.c = d.c + diff.c; \ + else if(spatial_pred.c < d.c - diff.c) \ + spatial_pred.c = d.c - diff.c; \ +} + + YADIF_SPATIAL(r) + YADIF_SPATIAL(g) + YADIF_SPATIAL(b) + YADIF_SPATIAL(a) + + return spatial_pred; +} + +float4 texel_at_yadif_2x(int2 texel, int field, bool mode0) +{ + field = frame2 ? (1 - field) : field; + return texel_at_yadif(texel, field, mode0); +} + +float4 texel_at_discard(int2 texel, int field) +{ + texel.y = texel.y / 2 * 2; + return load_at_image(texel, 0, field); +} + +float4 texel_at_discard_2x(int2 texel, int field) +{ + field = frame2 ? field : (1 - field); + return texel_at_discard(texel, field); +} + +float4 texel_at_blend(int2 texel, int field) +{ + return (load_at_image(texel, 0, 0) + load_at_image(texel, 0, 1)) / 2; +} + +float4 texel_at_blend_2x(int2 texel, int field) +{ + if (!frame2) + return (load_at_image(texel, 0, 0) + + load_at_prev(texel, 0, 1)) / 2; + else + return (load_at_image(texel, 0, 0) + + load_at_image(texel, 0, 1)) / 2; +} + +float4 texel_at_linear(int2 texel, int field) +{ + if ((texel.y % 2) == field) + return load_at_image(texel, 0, 0); + return (load_at_image(texel, 0, -1) + load_at_image(texel, 0, 1)) / 2; +} + +float4 texel_at_linear_2x(int2 texel, int field) +{ + field = frame2 ? field : (1 - field); + return texel_at_linear(texel, field); +} + +float4 texel_at_yadif_discard(int2 texel, int field) +{ + return (texel_at_yadif(texel, field, true) + texel_at_discard(texel, field)) / 2; +} + +float4 texel_at_yadif_discard_2x(int2 texel, int field) +{ + field = frame2 ? (1 - field) : field; + return (texel_at_yadif(texel, field, true) + texel_at_discard(texel, field)) / 2; +} + +int2 pixel_uv(float2 uv) +{ + return int2(uv * dimensions); +} + +float4 PSYadifMode0RGBA(VertData v_in) : TARGET +{ + return texel_at_yadif(pixel_uv(v_in.uv), field_order, true); +} + +float4 PSYadifMode0RGBA_2x(VertData v_in) : TARGET +{ + return texel_at_yadif_2x(pixel_uv(v_in.uv), field_order, true); +} + +float4 PSYadifMode2RGBA(VertData v_in) : TARGET +{ + return texel_at_yadif(pixel_uv(v_in.uv), field_order, false); +} + +float4 PSYadifMode2RGBA_2x(VertData v_in) : TARGET +{ + return texel_at_yadif_2x(pixel_uv(v_in.uv), field_order, false); +} + +float4 PSYadifDiscardRGBA(VertData v_in) : TARGET +{ + return texel_at_yadif_discard(pixel_uv(v_in.uv), field_order); +} + +float4 PSYadifDiscardRGBA_2x(VertData v_in) : TARGET +{ + return texel_at_yadif_discard_2x(pixel_uv(v_in.uv), field_order); +} + +float4 PSLinearRGBA(VertData v_in) : TARGET +{ + return texel_at_linear(pixel_uv(v_in.uv), field_order); +} + +float4 PSLinearRGBA_2x(VertData v_in) : TARGET +{ + return texel_at_linear_2x(pixel_uv(v_in.uv), field_order); +} + +float4 PSDiscardRGBA(VertData v_in) : TARGET +{ + return texel_at_discard(pixel_uv(v_in.uv), field_order); +} + +float4 PSDiscardRGBA_2x(VertData v_in) : TARGET +{ + return texel_at_discard_2x(pixel_uv(v_in.uv), field_order); +} + +float4 PSBlendRGBA(VertData v_in) : TARGET +{ + return texel_at_blend(pixel_uv(v_in.uv), field_order); +} + +float4 PSBlendRGBA_2x(VertData v_in) : TARGET +{ + return texel_at_blend_2x(pixel_uv(v_in.uv), field_order); +} + +VertData VSDefault(VertData v_in) +{ + VertData vert_out; + vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj); + vert_out.uv = v_in.uv; + return vert_out; +} + +#define TECHNIQUE(rgba_ps, matrix_ps) \ +technique Draw \ +{ \ + pass \ + { \ + vertex_shader = VSDefault(v_in); \ + pixel_shader = rgba_ps(v_in); \ + } \ +} \ +float4 matrix_ps(VertData v_in) : TARGET \ +{ \ + float4 yuv = rgba_ps(v_in); \ + yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max); \ + return saturate(mul(float4(yuv.xyz, 1.0), color_matrix)); \ +} \ +\ +technique DrawMatrix \ +{ \ + pass \ + { \ + vertex_shader = VSDefault(v_in); \ + pixel_shader = matrix_ps(v_in); \ + } \ +} diff --git a/libobs/data/deinterlace_blend.effect b/libobs/data/deinterlace_blend.effect new file mode 100644 index 0000000..7def8e2 --- /dev/null +++ b/libobs/data/deinterlace_blend.effect @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2016 Ruwen Hahn + * John R. Bradley + * Hugh Bailey "Jim" + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "deinterlace_base.effect" + +TECHNIQUE( PSBlendRGBA, PSBlendMatrix); diff --git a/libobs/data/deinterlace_blend_2x.effect b/libobs/data/deinterlace_blend_2x.effect new file mode 100644 index 0000000..33c102c --- /dev/null +++ b/libobs/data/deinterlace_blend_2x.effect @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2016 Ruwen Hahn + * John R. Bradley + * Hugh Bailey "Jim" + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "deinterlace_base.effect" + +TECHNIQUE(PSBlendRGBA_2x, PSBlendMatrix_2x); diff --git a/libobs/data/deinterlace_discard.effect b/libobs/data/deinterlace_discard.effect new file mode 100644 index 0000000..e1ce6e1 --- /dev/null +++ b/libobs/data/deinterlace_discard.effect @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2016 Ruwen Hahn + * John R. Bradley + * Hugh Bailey "Jim" + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "deinterlace_base.effect" + +TECHNIQUE(PSDiscardRGBA, PSDiscardMatrix); diff --git a/libobs/data/deinterlace_discard_2x.effect b/libobs/data/deinterlace_discard_2x.effect new file mode 100644 index 0000000..fe6eb9e --- /dev/null +++ b/libobs/data/deinterlace_discard_2x.effect @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2016 Ruwen Hahn + * John R. Bradley + * Hugh Bailey "Jim" + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "deinterlace_base.effect" + +TECHNIQUE(PSDiscardRGBA_2x, PSDiscardMatrix_2x); diff --git a/libobs/data/deinterlace_linear.effect b/libobs/data/deinterlace_linear.effect new file mode 100644 index 0000000..19aa513 --- /dev/null +++ b/libobs/data/deinterlace_linear.effect @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2016 Ruwen Hahn + * John R. Bradley + * Hugh Bailey "Jim" + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "deinterlace_base.effect" + +TECHNIQUE(PSLinearRGBA, PSLinearMatrix); diff --git a/libobs/data/deinterlace_linear_2x.effect b/libobs/data/deinterlace_linear_2x.effect new file mode 100644 index 0000000..69224ae --- /dev/null +++ b/libobs/data/deinterlace_linear_2x.effect @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2016 Ruwen Hahn + * John R. Bradley + * Hugh Bailey "Jim" + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "deinterlace_base.effect" + +TECHNIQUE(PSLinearRGBA_2x, PSLinearxMatrixA_2x); diff --git a/libobs/data/deinterlace_yadif.effect b/libobs/data/deinterlace_yadif.effect new file mode 100644 index 0000000..e22fe06 --- /dev/null +++ b/libobs/data/deinterlace_yadif.effect @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2016 Ruwen Hahn + * John R. Bradley + * Hugh Bailey "Jim" + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "deinterlace_base.effect" + +TECHNIQUE(PSYadifMode0RGBA, PSYadifMode0Matrix); diff --git a/libobs/data/deinterlace_yadif_2x.effect b/libobs/data/deinterlace_yadif_2x.effect new file mode 100644 index 0000000..6c1d329 --- /dev/null +++ b/libobs/data/deinterlace_yadif_2x.effect @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2016 Ruwen Hahn + * John R. Bradley + * Hugh Bailey "Jim" + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "deinterlace_base.effect" + +TECHNIQUE(PSYadifMode0RGBA_2x, PSYadifMode0Matrix_2x); diff --git a/libobs/data/lanczos_scale.effect b/libobs/data/lanczos_scale.effect index 5c441ce..b10034c 100644 --- a/libobs/data/lanczos_scale.effect +++ b/libobs/data/lanczos_scale.effect @@ -23,11 +23,19 @@ struct VertData { float2 uv : TEXCOORD0; }; -VertData VSDefault(VertData v_in) +struct FragData { + float4 pos : POSITION; + float2 uv : TEXCOORD0; + float2 scale : TEXCOORD1; +}; + +FragData VSDefault(VertData v_in) { - VertData vert_out; + FragData vert_out; 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; } @@ -48,12 +56,12 @@ float weight(float x, float radius) return 0.0; } -float3 weight3(float x) +float3 weight3(float x, float scale) { return float3( - weight(x * 2.0 + 0.0 * 2.0 - 3.0, 3.0), - weight(x * 2.0 + 1.0 * 2.0 - 3.0, 3.0), - weight(x * 2.0 + 2.0 * 2.0 - 3.0, 3.0)); + 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)); } float4 pixel(float xpos, float ypos) @@ -73,16 +81,16 @@ float4 get_line(float ypos, float3 xpos1, float3 xpos2, float3 rowtap1, pixel(xpos2.b, ypos) * rowtap2.b; } -float4 DrawLanczos(VertData v_in) +float4 DrawLanczos(FragData v_in) { float2 stepxy = base_dimension_i; float2 pos = v_in.uv + stepxy * 0.5; float2 f = frac(pos / stepxy); - float3 rowtap1 = weight3((1.0 - f.x) / 2.0); - float3 rowtap2 = weight3((1.0 - f.x) / 2.0 + 0.5); - float3 coltap1 = weight3((1.0 - f.y) / 2.0); - float3 coltap2 = weight3((1.0 - f.y) / 2.0 + 0.5); + 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); /* make sure all taps added together is exactly 1.0, otherwise some * (very small) distortion can occur */ @@ -106,12 +114,12 @@ float4 DrawLanczos(VertData v_in) get_line(xystart.y + stepxy.y * 5.0, xpos1, xpos2, rowtap1, rowtap2) * coltap2.b; } -float4 PSDrawLanczosRGBA(VertData v_in) : TARGET +float4 PSDrawLanczosRGBA(FragData v_in) : TARGET { return DrawLanczos(v_in); } -float4 PSDrawLanczosMatrix(VertData v_in) : TARGET +float4 PSDrawLanczosMatrix(FragData v_in) : TARGET { float4 rgba = DrawLanczos(v_in); float4 yuv; diff --git a/libobs/data/premultiplied_alpha.effect b/libobs/data/premultiplied_alpha.effect new file mode 100644 index 0000000..6abe825 --- /dev/null +++ b/libobs/data/premultiplied_alpha.effect @@ -0,0 +1,38 @@ +uniform float4x4 ViewProj; +uniform texture2d image; + +sampler_state def_sampler { + Filter = Linear; + AddressU = Clamp; + AddressV = Clamp; +}; + +struct VertInOut { + float4 pos : POSITION; + float2 uv : TEXCOORD0; +}; + +VertInOut VSDefault(VertInOut vert_in) +{ + VertInOut vert_out; + vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj); + vert_out.uv = vert_in.uv; + return vert_out; +} + +float4 PSDraw(VertInOut vert_in) : TARGET +{ + float4 rgba = image.Sample(def_sampler, vert_in.uv); + if (rgba.a > 0.0) + rgba.rgb /= rgba.a; + return saturate(rgba); +} + +technique Draw +{ + pass + { + vertex_shader = VSDefault(vert_in); + pixel_shader = PSDraw(vert_in); + } +} diff --git a/libobs/graphics/graphics.h b/libobs/graphics/graphics.h index 8d753d3..584d29e 100644 --- a/libobs/graphics/graphics.h +++ b/libobs/graphics/graphics.h @@ -284,6 +284,9 @@ enum gs_shader_param_type { GS_SHADER_PARAM_VEC2, GS_SHADER_PARAM_VEC3, GS_SHADER_PARAM_VEC4, + GS_SHADER_PARAM_INT2, + GS_SHADER_PARAM_INT3, + GS_SHADER_PARAM_INT4, GS_SHADER_PARAM_MATRIX4X4, GS_SHADER_PARAM_TEXTURE, }; diff --git a/libobs/graphics/matrix4.c b/libobs/graphics/matrix4.c index 3acc3ea..12d1ebd 100644 --- a/libobs/graphics/matrix4.c +++ b/libobs/graphics/matrix4.c @@ -232,7 +232,7 @@ void matrix4_scale_i(struct matrix4 *dst, const struct vec3 *v, bool matrix4_inv(struct matrix4 *dst, const struct matrix4 *m) { struct vec4 *dstv = (struct vec4 *)dst; - float det = matrix4_determinant(m); + float det; float m3x3[9]; int i, j, sign; diff --git a/libobs/graphics/shader-parser.c b/libobs/graphics/shader-parser.c index cfd3fde..2d852bd 100644 --- a/libobs/graphics/shader-parser.c +++ b/libobs/graphics/shader-parser.c @@ -28,6 +28,12 @@ enum gs_shader_param_type get_shader_param_type(const char *type) return GS_SHADER_PARAM_VEC3; else if (strcmp(type, "float4") == 0) return GS_SHADER_PARAM_VEC4; + else if (strcmp(type, "int2") == 0) + return GS_SHADER_PARAM_INT2; + else if (strcmp(type, "int3") == 0) + return GS_SHADER_PARAM_INT3; + else if (strcmp(type, "int4") == 0) + return GS_SHADER_PARAM_INT4; else if (astrcmp_n(type, "texture", 7) == 0) return GS_SHADER_PARAM_TEXTURE; else if (strcmp(type, "float4x4") == 0) diff --git a/libobs/graphics/texture-render.c b/libobs/graphics/texture-render.c index 6789f01..2e5410e 100644 --- a/libobs/graphics/texture-render.c +++ b/libobs/graphics/texture-render.c @@ -99,6 +99,9 @@ bool gs_texrender_begin(gs_texrender_t *texrender, uint32_t cx, uint32_t cy) if (!texrender_resetbuffer(texrender, cx, cy)) return false; + if (!texrender->target) + return false; + gs_viewport_push(); gs_projection_push(); gs_matrix_push(); diff --git a/libobs/media-io/video-fourcc.c b/libobs/media-io/video-fourcc.c index a1c0e42..37b949b 100644 --- a/libobs/media-io/video-fourcc.c +++ b/libobs/media-io/video-fourcc.c @@ -44,6 +44,9 @@ enum video_format video_format_from_fourcc(uint32_t fourcc) case MAKE_FOURCC('Y','V','Y','U'): return VIDEO_FORMAT_YVYU; + + 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 d950814..f29a6f1 100644 --- a/libobs/media-io/video-frame.c +++ b/libobs/media-io/video-frame.c @@ -66,6 +66,13 @@ void video_frame_init(struct video_frame *frame, enum video_format format, frame->linesize[1] = width; break; + case VIDEO_FORMAT_Y800: + size = width * height; + ALIGN_SIZE(size, alignment); + frame->data[0] = bmalloc(size); + frame->linesize[0] = width; + break; + case VIDEO_FORMAT_YVYU: case VIDEO_FORMAT_YUY2: case VIDEO_FORMAT_UYVY: @@ -115,6 +122,7 @@ void video_frame_copy(struct video_frame *dst, const struct video_frame *src, memcpy(dst->data[1], src->data[1], src->linesize[1] * cy / 2); break; + case VIDEO_FORMAT_Y800: case VIDEO_FORMAT_YVYU: case VIDEO_FORMAT_YUY2: case VIDEO_FORMAT_UYVY: diff --git a/libobs/media-io/video-io.h b/libobs/media-io/video-io.h index cef009d..ec6b2fa 100644 --- a/libobs/media-io/video-io.h +++ b/libobs/media-io/video-io.h @@ -46,6 +46,7 @@ enum video_format { VIDEO_FORMAT_RGBA, VIDEO_FORMAT_BGRA, VIDEO_FORMAT_BGRX, + VIDEO_FORMAT_Y800, /* grayscale */ /* planar 4:4:4 */ VIDEO_FORMAT_I444, @@ -97,6 +98,7 @@ static inline bool format_is_yuv(enum video_format format) case VIDEO_FORMAT_RGBA: case VIDEO_FORMAT_BGRA: case VIDEO_FORMAT_BGRX: + case VIDEO_FORMAT_Y800: return false; } @@ -115,6 +117,7 @@ static inline const char *get_video_format_name(enum video_format format) 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_NONE:; } diff --git a/libobs/media-io/video-scaler-ffmpeg.c b/libobs/media-io/video-scaler-ffmpeg.c index 31f721e..e46aa4e 100644 --- a/libobs/media-io/video-scaler-ffmpeg.c +++ b/libobs/media-io/video-scaler-ffmpeg.c @@ -38,6 +38,7 @@ static inline enum AVPixelFormat get_ffmpeg_video_format( 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; } diff --git a/libobs/obs-avc.c b/libobs/obs-avc.c index 8592472..757865a 100644 --- a/libobs/obs-avc.c +++ b/libobs/obs-avc.c @@ -221,3 +221,58 @@ size_t obs_parse_avc_header(uint8_t **header, const uint8_t *data, size_t size) *header = output.bytes.array; return output.bytes.num; } + +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) +{ + DARRAY(uint8_t) new_packet; + DARRAY(uint8_t) header; + DARRAY(uint8_t) sei; + const uint8_t *nal_start, *nal_end, *nal_codestart; + const uint8_t *end = packet + size; + int type; + + da_init(new_packet); + da_init(header); + da_init(sei); + + nal_start = obs_avc_find_startcode(packet, end); + nal_end = NULL; + while (nal_end != end) { + nal_codestart = nal_start; + + while (nal_start < end && !*(nal_start++)); + + if (nal_start == end) + break; + + type = nal_start[0] & 0x1F; + + nal_end = obs_avc_find_startcode(nal_start, end); + if (!nal_end) + nal_end = end; + + if (type == OBS_NAL_SPS || type == OBS_NAL_PPS) { + da_push_back_array(header, nal_codestart, + nal_end - nal_codestart); + } else if (type == OBS_NAL_SEI) { + da_push_back_array(sei, nal_codestart, + nal_end - nal_codestart); + + } else { + da_push_back_array(new_packet, nal_codestart, + nal_end - nal_codestart); + } + + nal_start = nal_end; + } + + *new_packet_data = new_packet.array; + *new_packet_size = new_packet.num; + *header_data = header.array; + *header_size = header.num; + *sei_data = sei.array; + *sei_size = sei.num; +} diff --git a/libobs/obs-avc.h b/libobs/obs-avc.h index 8ff1ac4..afb5ca3 100644 --- a/libobs/obs-avc.h +++ b/libobs/obs-avc.h @@ -55,6 +55,10 @@ EXPORT void obs_parse_avc_packet(struct encoder_packet *avc_packet, const struct encoder_packet *src); EXPORT size_t obs_parse_avc_header(uint8_t **header, const uint8_t *data, 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); #ifdef __cplusplus } diff --git a/libobs/obs-config.h b/libobs/obs-config.h index 031fa84..4172595 100644 --- a/libobs/obs-config.h +++ b/libobs/obs-config.h @@ -34,7 +34,7 @@ * * Reset to zero each major version */ -#define LIBOBS_API_MINOR_VER 13 +#define LIBOBS_API_MINOR_VER 14 /* * Increment if backward-compatible bug fix diff --git a/libobs/obs-encoder.c b/libobs/obs-encoder.c index c13c1b7..a0e54f5 100644 --- a/libobs/obs-encoder.c +++ b/libobs/obs-encoder.c @@ -54,8 +54,8 @@ static bool init_encoder(struct obs_encoder *encoder, const char *name, return false; if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0) return false; - if (!obs_context_data_init(&encoder->context, settings, name, - hotkey_data, false)) + if (!obs_context_data_init(&encoder->context, OBS_OBJ_TYPE_ENCODER, + settings, name, hotkey_data, false)) return false; if (pthread_mutex_init(&encoder->init_mutex, &attr) != 0) return false; @@ -731,7 +731,7 @@ static void send_first_video_packet(struct obs_encoder *encoder, da_init(data); - if (!get_sei(encoder, &sei, &size)) { + if (!get_sei(encoder, &sei, &size) || !sei || !size) { cb->new_packet(cb->param, packet); cb->sent_first_packet = true; return; @@ -1150,3 +1150,9 @@ const char *obs_encoder_get_id(const obs_encoder_t *encoder) return obs_encoder_valid(encoder, "obs_encoder_get_id") ? encoder->info.id : NULL; } + +uint32_t obs_get_encoder_caps(const char *encoder_id) +{ + struct obs_encoder_info *info = find_encoder(encoder_id); + return info ? info->caps : 0; +} diff --git a/libobs/obs-encoder.h b/libobs/obs-encoder.h index deedc64..89a782a 100644 --- a/libobs/obs-encoder.h +++ b/libobs/obs-encoder.h @@ -29,6 +29,8 @@ extern "C" { #endif +#define OBS_ENCODER_CAP_DEPRECATED (1<<0) + /** Specifies the encoder type */ enum obs_encoder_type { OBS_ENCODER_AUDIO, /**< The encoder provides an audio codec */ @@ -227,6 +229,8 @@ struct obs_encoder_info { void *type_data; void (*free_type_data)(void *type_data); + + uint32_t caps; }; EXPORT void obs_register_encoder_s(const struct obs_encoder_info *info, diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index 0f40f6a..e9df2f2 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -237,6 +237,7 @@ struct obs_core_video { gs_effect_t *bicubic_effect; gs_effect_t *lanczos_effect; gs_effect_t *bilinear_lowres_effect; + gs_effect_t *premultiplied_alpha_effect; gs_stagesurf_t *mapped_surface; int cur_texture; @@ -262,6 +263,15 @@ struct obs_core_video { enum obs_scale_type scale_type; 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; }; struct obs_core_audio { @@ -371,6 +381,8 @@ extern struct obs_core *obs; extern void *obs_video_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); @@ -385,6 +397,7 @@ struct obs_context_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; @@ -402,6 +415,7 @@ struct obs_context_data { 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, @@ -564,7 +578,7 @@ struct obs_source { /* async video data */ gs_texture_t *async_texture; - gs_texrender_t *async_convert_texrender; + gs_texrender_t *async_texrender; struct obs_source_frame *cur_async_frame; bool async_gpu_conversion; enum video_format async_format; @@ -587,6 +601,18 @@ struct obs_source { uint32_t async_convert_width; uint32_t async_convert_height; + /* 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; + /* filters */ struct obs_source *filter_parent; struct obs_source *filter_target; @@ -671,6 +697,30 @@ static inline void obs_source_dosignal(struct obs_source *source, &data); } +/* maximum timestamp variance in nanoseconds */ +#define MAX_TS_VAR 2000000000ULL + +static inline bool frame_out_of_bounds(const obs_source_t *source, uint64_t ts) +{ + if (ts < source->last_frame_ts) + return ((source->last_frame_ts - ts) > MAX_TS_VAR); + else + return ((ts - source->last_frame_ts) > MAX_TS_VAR); +} + +static inline enum gs_color_format convert_video_format( + enum video_format format) +{ + if (format == VIDEO_FORMAT_RGBA) + return GS_RGBA; + else if (format == VIDEO_FORMAT_BGRA) + return GS_BGRA; + else if (format == VIDEO_FORMAT_Y800) + return GS_R8; + + 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); @@ -682,6 +732,22 @@ extern void obs_source_audio_render(obs_source_t *source, uint32_t mixers, 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); +extern bool update_async_texture(struct obs_source *source, + const struct obs_source_frame *frame, + gs_texture_t *tex, gs_texrender_t *texrender); +extern bool set_async_texture_size(struct obs_source *source, + const struct obs_source_frame *frame); +extern void remove_async_frame(obs_source_t *source, + 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); +extern void deinterlace_update_async_video(obs_source_t *source); +extern void deinterlace_render(obs_source_t *s); + /* ------------------------------------------------------------------------- */ /* outputs */ diff --git a/libobs/obs-output.c b/libobs/obs-output.c index f7a67af..d450a6f 100644 --- a/libobs/obs-output.c +++ b/libobs/obs-output.c @@ -53,8 +53,8 @@ static const char *output_signals[] = { static bool init_output_handlers(struct obs_output *output, const char *name, obs_data_t *settings, obs_data_t *hotkey_data) { - if (!obs_context_data_init(&output->context, settings, name, - hotkey_data, false)) + if (!obs_context_data_init(&output->context, OBS_OBJ_TYPE_OUTPUT, + settings, name, hotkey_data, false)) return false; signal_handler_add_array(output->context.signals, output_signals); @@ -994,14 +994,15 @@ static bool prune_interleaved_packets(struct obs_output *output) int prune_start = prune_premature_packets(output); #if DEBUG_STARTING_PACKETS == 1 - blog(LOG_DEBUG, "--------- Pruning! ---------"); + blog(LOG_DEBUG, "--------- Pruning! %d ---------", prune_start); for (size_t i = 0; i < output->interleaved_packets.num; i++) { struct encoder_packet *packet = &output->interleaved_packets.array[i]; - blog(LOG_DEBUG, "packet: %s %d, ts: %lld", + blog(LOG_DEBUG, "packet: %s %d, ts: %lld, pruned = %s", packet->type == OBS_ENCODER_AUDIO ? "audio" : "video", (int)packet->track_idx, - packet->dts_usec); + packet->dts_usec, + (int)i < prune_start ? "true" : "false"); } #endif @@ -1039,6 +1040,26 @@ static int find_first_packet_type_idx(struct obs_output *output, return -1; } +static int find_last_packet_type_idx(struct obs_output *output, + enum obs_encoder_type type, size_t audio_idx) +{ + for (size_t i = output->interleaved_packets.num; i > 0; i--) { + struct encoder_packet *packet = + &output->interleaved_packets.array[i - 1]; + + if (packet->type == type) { + if (type == OBS_ENCODER_AUDIO && + packet->track_idx != audio_idx) { + continue; + } + + return (int)(i - 1); + } + } + + return -1; +} + static inline struct encoder_packet *find_first_packet_type( struct obs_output *output, enum obs_encoder_type type, size_t audio_idx) @@ -1047,14 +1068,20 @@ static inline struct encoder_packet *find_first_packet_type( return (idx != -1) ? &output->interleaved_packets.array[idx] : NULL; } -static bool initialize_interleaved_packets(struct obs_output *output) +static inline struct encoder_packet *find_last_packet_type( + struct obs_output *output, enum obs_encoder_type type, + size_t audio_idx) { - struct encoder_packet *video; - struct encoder_packet *audio[MAX_AUDIO_MIXES]; - size_t audio_mixes = num_audio_mixes(output); + int idx = find_last_packet_type_idx(output, type, audio_idx); + return (idx != -1) ? &output->interleaved_packets.array[idx] : NULL; +} - video = find_first_packet_type(output, OBS_ENCODER_VIDEO, 0); - if (!video) +static bool get_audio_and_video_packets(struct obs_output *output, + struct encoder_packet **video, + struct encoder_packet **audio, size_t audio_mixes) +{ + *video = find_first_packet_type(output, OBS_ENCODER_VIDEO, 0); + if (!*video) output->received_video = false; for (size_t i = 0; i < audio_mixes; i++) { @@ -1065,10 +1092,45 @@ static bool initialize_interleaved_packets(struct obs_output *output) } } - if (!video) { + if (!*video) { return false; } + return true; +} + +static bool initialize_interleaved_packets(struct obs_output *output) +{ + struct encoder_packet *video; + struct encoder_packet *audio[MAX_AUDIO_MIXES]; + struct encoder_packet *last_audio[MAX_AUDIO_MIXES]; + size_t audio_mixes = num_audio_mixes(output); + size_t start_idx; + + if (!get_audio_and_video_packets(output, &video, audio, audio_mixes)) + return false; + + for (size_t i = 0; i < audio_mixes; 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++) { + if (last_audio[i]->dts_usec < video->dts_usec) { + output->received_audio = false; + return false; + } + } + + /* clear out excess starting audio if it hasn't been already */ + start_idx = get_interleaved_start_idx(output); + if (start_idx) { + discard_to_idx(output, start_idx); + if (!get_audio_and_video_packets(output, &video, audio, + audio_mixes)) + return false; + } + /* get new offsets */ output->video_offset = video->dts; for (size_t i = 0; i < audio_mixes; i++) diff --git a/libobs/obs-scene.c b/libobs/obs-scene.c index 692f4dc..3fa74e3 100644 --- a/libobs/obs-scene.c +++ b/libobs/obs-scene.c @@ -281,18 +281,38 @@ static void calculate_bounds_data(struct obs_scene_item *item, (int)-width_diff, (int)-height_diff); } +static inline uint32_t calc_cx(const struct obs_scene_item *item, + 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 crop_cy = item->crop.top + item->crop.bottom; + return (crop_cy > height) ? 2 : (height - crop_cy); +} + static void update_item_transform(struct obs_scene_item *item) { uint32_t width = obs_source_get_width(item->source); uint32_t height = obs_source_get_height(item->source); - uint32_t cx = width; - uint32_t cy = height; + uint32_t cx = calc_cx(item, width); + uint32_t cy = calc_cy(item, height); struct vec2 base_origin; struct vec2 origin; struct vec2 scale = item->scale; struct calldata params; uint8_t stack[128]; + if (os_atomic_load_long(&item->defer_update) > 0) + return; + + width = cx; + height = cy; + vec2_zero(&base_origin); vec2_zero(&origin); @@ -358,6 +378,70 @@ static inline bool source_size_changed(struct obs_scene_item *item) return item->last_width != width || item->last_height != height; } +static inline bool crop_enabled(const struct obs_sceneitem_crop *crop) +{ + return crop->left || crop->right || crop->top || crop->bottom; +} + +static inline void render_item(struct obs_scene_item *item) +{ + if (item->crop_render) { + uint32_t width = obs_source_get_width(item->source); + uint32_t height = obs_source_get_height(item->source); + uint32_t cx = calc_cx(item, width); + uint32_t cy = calc_cy(item, height); + + if (cx && cy && gs_texrender_begin(item->crop_render, cx, cy)) { + 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); + + gs_matrix_scale3f(cx_scale, cy_scale, 1.0f); + gs_matrix_translate3f( + -(float)item->crop.left, + -(float)item->crop.top, + 0.0f); + + obs_source_video_render(item->source); + gs_texrender_end(item->crop_render); + } + } + + gs_matrix_push(); + gs_matrix_mul(&item->draw_transform); + if (item->crop_render) { + gs_texture_t *tex = gs_texrender_get_texture(item->crop_render); + + while (gs_effect_loop(obs->video.default_effect, "Draw")) + obs_source_draw(tex, 0, 0, 0, 0, 0); + } else { + obs_source_video_render(item->source); + } + gs_matrix_pop(); +} + +static void scene_video_tick(void *data, float seconds) +{ + struct obs_scene *scene = data; + struct obs_scene_item *item; + + video_lock(scene); + item = scene->first_item; + while (item) { + if (item->crop_render) + gs_texrender_reset(item->crop_render); + item = item->next; + } + video_unlock(scene); + + UNUSED_PARAMETER(seconds); +} + static void scene_video_render(void *data, gs_effect_t *effect) { DARRAY(struct obs_scene_item*) remove_items; @@ -385,12 +469,8 @@ static void scene_video_render(void *data, gs_effect_t *effect) if (source_size_changed(item)) update_item_transform(item); - if (item->user_visible) { - gs_matrix_push(); - gs_matrix_mul(&item->draw_transform); - obs_source_video_render(item->source); - gs_matrix_pop(); - } + if (item->user_visible) + render_item(item); item = item->next; } @@ -468,6 +548,23 @@ static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data) (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"); + + if (item->crop_render && !crop_enabled(&item->crop)) { + obs_enter_graphics(); + gs_texrender_destroy(item->crop_render); + item->crop_render = NULL; + obs_leave_graphics(); + + } else if (!item->crop_render && crop_enabled(&item->crop)) { + obs_enter_graphics(); + item->crop_render = gs_texrender_create(GS_RGBA, GS_ZS_NONE); + obs_leave_graphics(); + } + obs_source_release(source); update_item_transform(item); @@ -508,6 +605,10 @@ static void scene_save_item(obs_data_array_t *array, 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_array_push_back(array, item_data); obs_data_release(item_data); @@ -742,6 +843,7 @@ const struct obs_source_info scene_info = .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, @@ -869,6 +971,8 @@ obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name, new_item->bounds_align = item->bounds_align; new_item->bounds = item->bounds; + obs_sceneitem_set_crop(new_item, &item->crop); + obs_source_release(source); } } @@ -1123,6 +1227,11 @@ obs_sceneitem_t *obs_scene_add(obs_scene_t *scene, obs_source_t *source) static void obs_sceneitem_destroy(obs_sceneitem_t *item) { if (item) { + if (item->crop_render) { + obs_enter_graphics(); + gs_texrender_destroy(item->crop_render); + obs_leave_graphics(); + } obs_hotkey_pair_unregister(item->toggle_visibility); pthread_mutex_destroy(&item->actions_mutex); if (item->source) @@ -1573,3 +1682,75 @@ void obs_scene_atomic_update(obs_scene_t *scene, full_unlock(scene); obs_scene_release(scene); } + +static inline bool crop_equal(const struct obs_sceneitem_crop *crop1, + const struct obs_sceneitem_crop *crop2) +{ + 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) +{ + bool now_enabled; + + if (!obs_ptr_valid(item, "obs_sceneitem_set_crop")) + return; + if (!obs_ptr_valid(crop, "obs_sceneitem_set_crop")) + return; + if (crop_equal(crop, &item->crop)) + return; + + now_enabled = crop_enabled(crop); + + obs_enter_graphics(); + + if (!now_enabled) { + gs_texrender_destroy(item->crop_render); + item->crop_render = NULL; + + } else if (!item->crop_render) { + item->crop_render = gs_texrender_create(GS_RGBA, GS_ZS_NONE); + } + + 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; + obs_leave_graphics(); + + update_item_transform(item); +} + +void obs_sceneitem_get_crop(const obs_sceneitem_t *item, + struct obs_sceneitem_crop *crop) +{ + if (!obs_ptr_valid(item, "obs_sceneitem_get_crop")) + return; + if (!obs_ptr_valid(crop, "obs_sceneitem_get_crop")) + return; + + memcpy(crop, &item->crop, sizeof(*crop)); +} + +void obs_sceneitem_defer_update_begin(obs_sceneitem_t *item) +{ + if (!obs_ptr_valid(item, "obs_sceneitem_defer_update_begin")) + return; + + os_atomic_inc_long(&item->defer_update); +} + +void obs_sceneitem_defer_update_end(obs_sceneitem_t *item) +{ + if (!obs_ptr_valid(item, "obs_sceneitem_defer_update_end")) + return; + + if (os_atomic_dec_long(&item->defer_update) == 0) + update_item_transform(item); +} diff --git a/libobs/obs-scene.h b/libobs/obs-scene.h index 915c21b..3c953a3 100644 --- a/libobs/obs-scene.h +++ b/libobs/obs-scene.h @@ -35,10 +35,14 @@ struct obs_scene_item { struct obs_scene *parent; struct obs_source *source; volatile long active_refs; + volatile long defer_update; bool user_visible; bool visible; bool selected; + gs_texrender_t *crop_render; + struct obs_sceneitem_crop crop; + struct vec2 pos; struct vec2 scale; float rot; diff --git a/libobs/obs-service.c b/libobs/obs-service.c index 3fc851e..c9ef6b3 100644 --- a/libobs/obs-service.c +++ b/libobs/obs-service.c @@ -33,8 +33,9 @@ const char *obs_service_get_display_name(const char *id) return (info != NULL) ? info->get_name(info->type_data) : NULL; } -obs_service_t *obs_service_create(const char *id, const char *name, - obs_data_t *settings, obs_data_t *hotkey_data) +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 struct obs_service_info *info = find_service(id); struct obs_service *service; @@ -46,23 +47,14 @@ obs_service_t *obs_service_create(const char *id, const char *name, service = bzalloc(sizeof(struct obs_service)); - if (!obs_context_data_init(&service->context, settings, name, - hotkey_data, false)) { + if (!obs_context_data_init(&service->context, OBS_OBJ_TYPE_SERVICE, + settings, name, hotkey_data, private)) { bfree(service); return NULL; } - if (!info) { - blog(LOG_ERROR, "Service ID '%s' not found", id); - - service->info.id = bstrdup(id); - service->owns_info_id = true; - } else { - service->info = *info; - } - - if (info) - service->context.data = service->info.create( + service->info = *info; + service->context.data = service->info.create( service->context.settings, service); if (!service->context.data) blog(LOG_ERROR, "Failed to create service '%s'!", name); @@ -74,10 +66,24 @@ obs_service_t *obs_service_create(const char *id, const char *name, &obs->data.services_mutex, &obs->data.first_service); - blog(LOG_INFO, "service '%s' (%s) created", name, id); + blog(private ? LOG_DEBUG : LOG_INFO, "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) +{ + return obs_service_create_internal(id, name, settings, hotkey_data, + false); +} + +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); +} + static void actually_destroy_service(struct obs_service *service) { if (service->context.data) @@ -86,7 +92,8 @@ static void actually_destroy_service(struct obs_service *service) if (service->output) service->output->service = NULL; - blog(LOG_INFO, "service '%s' destroyed", service->context.name); + blog(service->context.private ? LOG_DEBUG : LOG_INFO, + "service '%s' destroyed", service->context.name); obs_context_data_free(&service->context); if (service->owns_info_id) diff --git a/libobs/obs-source-deinterlace.c b/libobs/obs-source-deinterlace.c new file mode 100644 index 0000000..319a1be --- /dev/null +++ b/libobs/obs-source-deinterlace.c @@ -0,0 +1,444 @@ +/****************************************************************************** + Copyright (C) 2016 by Hugh Bailey + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +******************************************************************************/ + +#include "obs-internal.h" + +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; + uint64_t sys_offset = sys_time - source->last_sys_timestamp; + uint64_t frame_time = next_frame->timestamp; + uint64_t frame_offset = 0; + size_t idx = 1; + + if ((source->flags & OBS_SOURCE_FLAG_UNBUFFERED) != 0) { + while (source->async_frames.num > 2) { + da_erase(source->async_frames, 0); + remove_async_frame(source, next_frame); + next_frame = source->async_frames.array[0]; + } + + if (source->async_frames.num == 2) + source->async_frames.array[0]->prev_frame = true; + source->deinterlace_offset = 0; + return true; + } + + /* account for timestamp invalidation */ + if (frame_out_of_bounds(source, frame_time)) { + source->last_frame_ts = next_frame->timestamp; + source->deinterlace_offset = 0; + return true; + } else { + frame_offset = frame_time - source->last_frame_ts; + source->last_frame_ts += sys_offset; + } + + while (source->last_frame_ts > next_frame->timestamp) { + + /* this tries to reduce the needless frame duplication, also + * helps smooth out async rendering to frame boundaries. In + * other words, tries to keep the framerate as smooth as + * possible */ + if ((source->last_frame_ts - next_frame->timestamp) < 2000000) + break; + + if (prev_frame) { + da_erase(source->async_frames, 0); + remove_async_frame(source, prev_frame); + } + + if (source->async_frames.num <= 2) { + bool exit = true; + + if (prev_frame) { + prev_frame->prev_frame = true; + + } else if (!frame && source->async_frames.num == 2) { + exit = false; + } + + if (exit) { + source->deinterlace_offset = 0; + return true; + } + } + + if (frame) + idx = 2; + else + idx = 1; + + prev_frame = frame; + frame = next_frame; + next_frame = source->async_frames.array[idx]; + + /* more timestamp checking and compensating */ + if ((next_frame->timestamp - frame_time) > MAX_TS_VAR) { + source->last_frame_ts = + next_frame->timestamp - frame_offset; + source->deinterlace_offset = 0; + } + + frame_time = next_frame->timestamp; + frame_offset = frame_time - source->last_frame_ts; + } + + if (prev_frame) + prev_frame->prev_frame = true; + + return frame != NULL; +} + +static inline bool first_frame(obs_source_t *s) +{ + if (s->last_frame_ts) + return false; + + if (s->async_frames.num >= 2) + s->async_frames.array[0]->prev_frame = true; + return true; +} + +static inline uint64_t uint64_diff(uint64_t ts1, uint64_t ts2) +{ + return (ts1 < ts2) ? (ts2 - ts1) : (ts1 - ts2); +} + +static inline void deinterlace_get_closest_frames(obs_source_t *s, + uint64_t sys_time) +{ + const struct video_output_info *info; + uint64_t half_interval; + + 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; + + if (first_frame(s) || ready_deinterlace_frames(s, sys_time)) { + uint64_t offset; + + s->prev_async_frame = NULL; + s->cur_async_frame = s->async_frames.array[0]; + + da_erase(s->async_frames, 0); + + if (s->cur_async_frame->prev_frame) { + s->prev_async_frame = s->cur_async_frame; + s->cur_async_frame = s->async_frames.array[0]; + + da_erase(s->async_frames, 0); + + 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); + } + + if (!s->last_frame_ts) + s->last_frame_ts = s->cur_async_frame->timestamp; + + s->deinterlace_frame_ts = s->cur_async_frame->timestamp; + + offset = obs->video.video_time - s->deinterlace_frame_ts; + + if (!s->deinterlace_offset) { + s->deinterlace_offset = offset; + } else { + uint64_t offset_diff = uint64_diff( + s->deinterlace_offset, offset); + if (offset_diff > half_interval) + s->deinterlace_offset = offset; + } + } +} + +void deinterlace_process_last_frame(obs_source_t *s, uint64_t sys_time) +{ + if (s->prev_async_frame) { + remove_async_frame(s, s->prev_async_frame); + s->prev_async_frame = NULL; + } + if (s->cur_async_frame) { + remove_async_frame(s, s->cur_async_frame); + s->cur_async_frame = NULL; + } + + deinterlace_get_closest_frames(s, sys_time); +} + +void set_deinterlace_texture_size(obs_source_t *source) +{ + if (source->async_gpu_conversion) { + 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); + + } else { + 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); + } +} + +static inline struct obs_source_frame *get_prev_frame(obs_source_t *source, + bool *updated) +{ + struct obs_source_frame *frame = NULL; + + pthread_mutex_lock(&source->async_mutex); + + *updated = source->cur_async_frame != NULL; + frame = source->prev_async_frame; + source->prev_async_frame = NULL; + + if (frame) + os_atomic_inc_long(&frame->refs); + + pthread_mutex_unlock(&source->async_mutex); + + return frame; +} + +void deinterlace_update_async_video(obs_source_t *source) +{ + struct obs_source_frame *frame; + bool updated; + + if (source->deinterlace_rendered) + return; + + frame = get_prev_frame(source, &updated); + + source->deinterlace_rendered = true; + if (frame) + frame = filter_async_video(source, frame); + + if (frame) { + if (set_async_texture_size(source, frame)) { + update_async_texture(source, frame, + source->async_prev_texture, + 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; + + if (source->async_texrender) { + gs_texrender_t *prev = source->async_prev_texrender; + source->async_prev_texrender = source->async_texrender; + source->async_texrender = prev; + } + } +} + +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_DISCARD: + return obs_load_effect(&obs->video.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"); + case OBS_DEINTERLACE_MODE_BLEND: + return obs_load_effect(&obs->video.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"); + case OBS_DEINTERLACE_MODE_LINEAR: + return obs_load_effect(&obs->video.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"); + case OBS_DEINTERLACE_MODE_YADIF: + return obs_load_effect(&obs->video.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"); + } + + 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 *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"); + struct vec2 size = {(float)s->async_width, (float)s->async_height}; + bool yuv = format_is_yuv(s->async_format); + bool limited_range = yuv && !s->async_full_range; + const char *tech = yuv ? "DrawMatrix" : "Draw"; + + 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; + + if (!cur_tex || !prev_tex || !s->async_width || !s->async_height) + return; + + gs_effect_set_texture(image, cur_tex); + gs_effect_set_texture(prev, prev_tex); + gs_effect_set_int(field, s->deinterlace_top_first); + gs_effect_set_vec2(dimensions, &size); + + if (yuv) { + gs_eparam_t *color_matrix = gs_effect_get_param_by_name( + effect, "color_matrix"); + gs_effect_set_val(color_matrix, s->async_color_matrix, + sizeof(float) * 16); + } + if (limited_range) { + const size_t size = sizeof(float) * 3; + gs_eparam_t *color_range_min = gs_effect_get_param_by_name( + effect, "color_range_min"); + gs_eparam_t *color_range_max = gs_effect_get_param_by_name( + effect, "color_range_max"); + gs_effect_set_val(color_range_min, s->async_color_range_min, + size); + gs_effect_set_val(color_range_max, s->async_color_range_max, + size); + } + + frame2_ts = s->deinterlace_frame_ts + s->deinterlace_offset + + s->deinterlace_half_duration - TWOX_TOLERANCE; + + gs_effect_set_bool(frame2, obs->video.video_time >= frame2_ts); + + while (gs_effect_loop(effect, tech)) + gs_draw_sprite(NULL, s->async_flip ? GS_FLIP_V : 0, + s->async_width, s->async_height); +} + +static void enable_deinterlacing(obs_source_t *source, + enum obs_deinterlace_mode mode) +{ + obs_enter_graphics(); + + if (source->async_format != VIDEO_FORMAT_NONE && + source->async_width != 0 && + source->async_height != 0) + set_deinterlace_texture_size(source); + + source->deinterlace_mode = mode; + source->deinterlace_effect = get_effect(mode); + + pthread_mutex_lock(&source->async_mutex); + if (source->prev_async_frame) { + remove_async_frame(source, source->prev_async_frame); + source->prev_async_frame = NULL; + } + pthread_mutex_unlock(&source->async_mutex); + + obs_leave_graphics(); +} + +static void disable_deinterlacing(obs_source_t *source) +{ + obs_enter_graphics(); + gs_texture_destroy(source->async_prev_texture); + gs_texrender_destroy(source->async_prev_texrender); + source->deinterlace_mode = OBS_DEINTERLACE_MODE_DISABLE; + source->async_prev_texture = NULL; + source->async_prev_texrender = NULL; + obs_leave_graphics(); +} + +void obs_source_set_deinterlace_mode(obs_source_t *source, + enum obs_deinterlace_mode mode) +{ + if (!obs_source_valid(source, "obs_source_set_deinterlace_mode")) + return; + if (source->deinterlace_mode == mode) + return; + + if (source->deinterlace_mode == OBS_DEINTERLACE_MODE_DISABLE) { + enable_deinterlacing(source, mode); + } else if (mode == OBS_DEINTERLACE_MODE_DISABLE) { + disable_deinterlacing(source); + } else { + obs_enter_graphics(); + source->deinterlace_mode = mode; + source->deinterlace_effect = get_effect(mode); + obs_leave_graphics(); + } +} + +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; +} + +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; +} + +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; +} diff --git a/libobs/obs-source-transition.c b/libobs/obs-source-transition.c index 18e9553..fb079dd 100644 --- a/libobs/obs-source-transition.c +++ b/libobs/obs-source-transition.c @@ -824,7 +824,8 @@ bool obs_transition_audio_render(obs_source_t *transition, if (min_ts) copy_transition_state(transition, &state); - } else if (transition->transitioning_audio) { + } else if (!transition->transitioning_video && + transition->transitioning_audio) { stopped = stop_audio(transition); } diff --git a/libobs/obs-source.c b/libobs/obs-source.c index 2ed3e66..e465dc0 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -34,6 +34,11 @@ static inline bool data_valid(const struct obs_source *source, const char *f) return obs_source_valid(source, f) && source->context.data; } +static inline bool deinterlacing_enabled(const struct obs_source *source) +{ + return source->deinterlace_mode != OBS_DEINTERLACE_MODE_DISABLE; +} + const struct obs_source_info *get_source_info(const char *id) { for (size_t i = 0; i < obs->source_types.num; i++) { @@ -79,8 +84,8 @@ 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, settings, name, - hotkey_data, private)) + if (!obs_context_data_init(&source->context, OBS_OBJ_TYPE_SOURCE, + settings, name, hotkey_data, private)) return false; return signal_handler_add_array(source->context.signals, @@ -109,6 +114,12 @@ static void allocate_audio_output_buffer(struct obs_source *source) } } +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; +} + static inline bool is_audio_source(const struct obs_source *source) { return source->info.output_flags & OBS_SOURCE_AUDIO; @@ -119,6 +130,8 @@ static inline bool is_composite_source(const struct obs_source *source) return source->info.output_flags & OBS_SOURCE_COMPOSITE; } +extern char *find_libobs_data_file(const char *file); + /* internal initialization */ bool obs_source_init(struct obs_source *source) { @@ -153,6 +166,16 @@ 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.type == OBS_SOURCE_TYPE_TRANSITION) { + if (!obs_transition_init(source)) + return false; + } + + source->control = bzalloc(sizeof(obs_weak_source_t)); + source->deinterlace_top_first = true; + source->control->source = source; + source->audio_mixers = 0xF; + if (is_audio_source(source)) { pthread_mutex_lock(&obs->data.audio_sources_mutex); @@ -167,15 +190,6 @@ bool obs_source_init(struct obs_source *source) pthread_mutex_unlock(&obs->data.audio_sources_mutex); } - if (source->info.type == OBS_SOURCE_TYPE_TRANSITION) { - if (!obs_transition_init(source)) - return false; - } - - source->control = bzalloc(sizeof(obs_weak_source_t)); - source->control->source = source; - source->audio_mixers = 0xF; - obs_context_data_insert(&source->context, &obs->data.sources_mutex, &obs->data.first_source); @@ -290,6 +304,13 @@ static obs_source_t *obs_source_create_internal(const char *id, source->owns_info_id = true; } else { source->info = *info; + + /* Always mark filters as private so they aren't found by + * source enum/search functions. + * + * XXX: Fix design flaws with filters */ + if (info->type == OBS_SOURCE_TYPE_FILTER) + private = true; } source->mute_unmute_key = OBS_INVALID_HOTKEY_PAIR_ID; @@ -481,10 +502,14 @@ void obs_source_destroy(struct obs_source *source) obs_source_frame_decref(source->async_cache.array[i].frame); gs_enter_context(obs->video.graphics); - if (source->async_convert_texrender) - gs_texrender_destroy(source->async_convert_texrender); + if (source->async_texrender) + 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); if (source->filter_texrender) gs_texrender_destroy(source->filter_texrender); gs_leave_context(); @@ -888,8 +913,6 @@ void obs_source_deactivate(obs_source_t *source, enum view_type type) static inline struct obs_source_frame *get_closest_frame(obs_source_t *source, uint64_t sys_time); -static void remove_async_frame(obs_source_t *source, - struct obs_source_frame *frame); void obs_source_video_tick(obs_source_t *source, float seconds) { @@ -905,12 +928,20 @@ void obs_source_video_tick(obs_source_t *source, float seconds) uint64_t sys_time = obs->video.video_time; pthread_mutex_lock(&source->async_mutex); - if (source->cur_async_frame) { - remove_async_frame(source, source->cur_async_frame); - source->cur_async_frame = NULL; + + if (deinterlacing_enabled(source)) { + deinterlace_process_last_frame(source, sys_time); + } else { + if (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); } @@ -950,6 +981,7 @@ void obs_source_video_tick(obs_source_t *source, float seconds) source->info.video_tick(source->context.data, seconds); source->async_rendered = false; + source->deinterlace_rendered = false; } /* unless the value is 3+ hours worth of frames, this won't overflow */ @@ -965,8 +997,6 @@ static inline size_t conv_time_to_frames(const size_t sample_rate, return (size_t)(duration * (uint64_t)sample_rate / 1000000000ULL); } -/* maximum timestamp variance in nanoseconds */ -#define MAX_TS_VAR 2000000000ULL /* maximum buffer size */ #define MAX_BUF_SIZE (1000 * AUDIO_OUTPUT_FRAMES * sizeof(float)) @@ -1210,6 +1240,7 @@ static inline enum convert_type get_convert_type(enum video_format format) case VIDEO_FORMAT_UYVY: return CONVERT_422_U; + case VIDEO_FORMAT_Y800: case VIDEO_FORMAT_I444: case VIDEO_FORMAT_NONE: case VIDEO_FORMAT_RGBA: @@ -1280,18 +1311,7 @@ static inline bool init_gpu_conversion(struct obs_source *source, return false; } -static inline enum gs_color_format convert_video_format( - enum video_format format) -{ - if (format == VIDEO_FORMAT_RGBA) - return GS_RGBA; - else if (format == VIDEO_FORMAT_BGRA) - return GS_BGRA; - - return GS_BGRX; -} - -static inline bool set_async_texture_size(struct obs_source *source, +bool set_async_texture_size(struct obs_source *source, const struct obs_source_frame *frame) { enum convert_type cur = get_convert_type(frame->format); @@ -1306,13 +1326,18 @@ static inline bool set_async_texture_size(struct obs_source *source, source->async_format = frame->format; gs_texture_destroy(source->async_texture); - gs_texrender_destroy(source->async_convert_texrender); - source->async_convert_texrender = NULL; + gs_texture_destroy(source->async_prev_texture); + 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; - source->async_convert_texrender = + source->async_texrender = gs_texrender_create(GS_BGRX, GS_ZS_NONE); source->async_texture = gs_texture_create( @@ -1331,6 +1356,9 @@ static inline bool set_async_texture_size(struct obs_source *source, format, 1, NULL, GS_DYNAMIC); } + if (deinterlacing_enabled(source)) + set_deinterlace_texture_size(source); + return !!source->async_texture; } @@ -1379,6 +1407,7 @@ static const char *select_conversion_technique(enum video_format format) return "NV12_Reverse"; break; + case VIDEO_FORMAT_Y800: case VIDEO_FORMAT_BGRA: case VIDEO_FORMAT_BGRX: case VIDEO_FORMAT_RGBA: @@ -1397,11 +1426,9 @@ static inline void set_eparam(gs_effect_t *effect, const char *name, float val) } static bool update_async_texrender(struct obs_source *source, - const struct obs_source_frame *frame) + const struct obs_source_frame *frame, + gs_texture_t *tex, gs_texrender_t *texrender) { - gs_texture_t *tex = source->async_texture; - gs_texrender_t *texrender = source->async_convert_texrender; - gs_texrender_reset(texrender); upload_raw_frame(tex, frame); @@ -1454,11 +1481,10 @@ static bool update_async_texrender(struct obs_source *source, return true; } -static bool update_async_texture(struct obs_source *source, - const struct obs_source_frame *frame) +bool update_async_texture(struct obs_source *source, + const struct obs_source_frame *frame, + gs_texture_t *tex, gs_texrender_t *texrender) { - gs_texture_t *tex = source->async_texture; - gs_texrender_t *texrender = source->async_convert_texrender; enum convert_type type = get_convert_type(frame->format); uint8_t *ptr; uint32_t linesize; @@ -1473,7 +1499,7 @@ static bool update_async_texture(struct obs_source *source, sizeof frame->color_range_max); if (source->async_gpu_conversion && texrender) - return update_async_texrender(source, frame); + return update_async_texrender(source, frame, tex, texrender); if (type == CONVERT_NONE) { gs_texture_set_image(tex, frame->data[0], frame->linesize[0], @@ -1513,8 +1539,8 @@ static inline void obs_source_draw_texture(struct obs_source *source, gs_texture_t *tex = source->async_texture; gs_eparam_t *param; - if (source->async_convert_texrender) - tex = gs_texrender_get_texture(source->async_convert_texrender); + if (source->async_texrender) + tex = gs_texrender_get_texture(source->async_texrender); if (color_range_min) { size_t const size = sizeof(float) * 3; @@ -1566,9 +1592,6 @@ static void obs_source_draw_async_texture(struct obs_source *source) } } -static inline struct obs_source_frame *filter_async_video(obs_source_t *source, - struct obs_source_frame *in); - static void obs_source_update_async_video(obs_source_t *source) { if (!source->async_rendered) { @@ -1583,13 +1606,14 @@ static void obs_source_update_async_video(obs_source_t *source) os_gettime_ns() - frame->timestamp; source->timing_set = true; - if (!set_async_texture_size(source, frame)) - return; - if (!update_async_texture(source, frame)) - return; - } + if (set_async_texture_size(source, frame)) { + update_async_texture(source, frame, + source->async_texture, + source->async_texrender); + } - obs_source_release_frame(source, frame); + obs_source_release_frame(source, frame); + } } } @@ -1606,11 +1630,10 @@ static inline void obs_source_render_filters(obs_source_t *source) source->rendering_filter = false; } -static void obs_source_default_render(obs_source_t *source, bool color_matrix) +static void obs_source_default_render(obs_source_t *source) { gs_effect_t *effect = obs->video.default_effect; - const char *tech_name = color_matrix ? "DrawMatrix" : "Draw"; - gs_technique_t *tech = gs_effect_get_technique(effect, tech_name); + gs_technique_t *tech = gs_effect_get_technique(effect, "Draw"); size_t passes, i; passes = gs_technique_begin(tech); @@ -1626,14 +1649,13 @@ static void obs_source_default_render(obs_source_t *source, bool color_matrix) static inline void obs_source_main_render(obs_source_t *source) { uint32_t flags = source->info.output_flags; - bool color_matrix = (flags & OBS_SOURCE_COLOR_MATRIX) != 0; bool custom_draw = (flags & OBS_SOURCE_CUSTOM_DRAW) != 0; bool default_effect = !source->filter_parent && source->filters.num == 0 && !custom_draw; if (default_effect) - obs_source_default_render(source, color_matrix); + obs_source_default_render(source); else if (source->context.data) source->info.video_render(source->context.data, custom_draw ? NULL : gs_get_effect()); @@ -1649,8 +1671,11 @@ static inline void render_video(obs_source_t *source) if (source->info.type == OBS_SOURCE_TYPE_INPUT && (source->info.output_flags & OBS_SOURCE_ASYNC) != 0 && - !source->rendering_filter) + !source->rendering_filter) { + if (deinterlacing_enabled(source)) + deinterlace_update_async_video(source); obs_source_update_async_video(source); + } if (!source->context.data || !source->enabled) { if (source->filter_parent) @@ -1667,6 +1692,9 @@ static inline void render_video(obs_source_t *source) else if (source->filter_target) obs_source_video_render(source->filter_target); + else if (deinterlacing_enabled(source)) + deinterlace_render(source); + else obs_source_render_async_video(source); } @@ -1827,6 +1855,12 @@ void obs_source_filter_add(obs_source_t *source, obs_source_t *filter) calldata_set_ptr(&cd, "filter", filter); signal_handler_signal(source->context.signals, "filter_add", &cd); + + if (source && filter) + blog(source->context.private ? LOG_DEBUG : LOG_INFO, + "- filter '%s' (%s) added to source '%s'", + filter->context.name, filter->info.id, + source->context.name); } static bool obs_source_filter_remove_refless(obs_source_t *source, @@ -1859,6 +1893,12 @@ static bool obs_source_filter_remove_refless(obs_source_t *source, signal_handler_signal(source->context.signals, "filter_remove", &cd); + if (source && filter) + blog(source->context.private ? LOG_DEBUG : LOG_INFO, + "- filter '%s' (%s) removed from source '%s'", + filter->context.name, filter->info.id, + source->context.name); + if (filter->info.filter_remove) filter->info.filter_remove(filter->context.data, filter->filter_parent); @@ -1988,7 +2028,7 @@ obs_data_t *obs_source_get_settings(const obs_source_t *source) return source->context.settings; } -static inline struct obs_source_frame *filter_async_video(obs_source_t *source, +struct obs_source_frame *filter_async_video(obs_source_t *source, struct obs_source_frame *in) { size_t i; @@ -2071,6 +2111,7 @@ static void copy_frame_data(struct obs_source_frame *dst, case VIDEO_FORMAT_YVYU: case VIDEO_FORMAT_YUY2: case VIDEO_FORMAT_UYVY: + case VIDEO_FORMAT_Y800: case VIDEO_FORMAT_NONE: case VIDEO_FORMAT_RGBA: case VIDEO_FORMAT_BGRA: @@ -2099,6 +2140,7 @@ static inline void free_async_cache(struct obs_source *source) da_resize(source->async_cache, 0); da_resize(source->async_frames, 0); source->cur_async_frame = NULL; + source->prev_async_frame = NULL; } #define MAX_UNUSED_FRAME_DURATION 5 @@ -2375,17 +2417,11 @@ void obs_source_output_audio(obs_source_t *source, pthread_mutex_unlock(&source->filter_mutex); } -static inline bool frame_out_of_bounds(const obs_source_t *source, uint64_t ts) +void remove_async_frame(obs_source_t *source, struct obs_source_frame *frame) { - if (ts < source->last_frame_ts) - return ((source->last_frame_ts - ts) > MAX_TS_VAR); - else - return ((ts - source->last_frame_ts) > MAX_TS_VAR); -} + if (frame) + frame->prev_frame = false; -static void remove_async_frame(obs_source_t *source, - struct obs_source_frame *frame) -{ for (size_t i = 0; i < source->async_cache.num; i++) { struct async_frame *f = &source->async_cache.array[i]; @@ -2594,9 +2630,8 @@ const char *obs_source_get_id(const obs_source_t *source) } static inline void render_filter_bypass(obs_source_t *target, - gs_effect_t *effect, bool use_matrix) + gs_effect_t *effect, const char *tech_name) { - const char *tech_name = use_matrix ? "DrawMatrix" : "Draw"; gs_technique_t *tech = gs_effect_get_technique(effect, tech_name); size_t passes, i; @@ -2610,9 +2645,8 @@ 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, bool use_matrix) + uint32_t width, uint32_t height, const char *tech_name) { - const char *tech_name = use_matrix ? "DrawMatrix" : "Draw"; 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; @@ -2638,25 +2672,35 @@ static inline bool can_bypass(obs_source_t *target, obs_source_t *parent, ((parent_flags & OBS_SOURCE_ASYNC) == 0); } -void obs_source_process_filter_begin(obs_source_t *filter, +bool obs_source_process_filter_begin(obs_source_t *filter, enum gs_color_format format, enum obs_allow_direct_render allow_direct) { obs_source_t *target, *parent; uint32_t target_flags, parent_flags; int cx, cy; - bool use_matrix; if (!obs_ptr_valid(filter, "obs_source_process_filter_begin")) - return; + return false; 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); + return false; + } + if (!parent) { + blog(LOG_INFO, "filter '%s' being processed with no parent!", + filter->context.name); + return false; + } + target_flags = target->info.output_flags; parent_flags = parent->info.output_flags; cx = get_base_width(target); cy = get_base_height(target); - use_matrix = !!(target_flags & OBS_SOURCE_COLOR_MATRIX); filter->allow_direct = allow_direct; @@ -2665,12 +2709,12 @@ void obs_source_process_filter_begin(obs_source_t *filter, * using the filter effect instead of rendering to texture to reduce * the total number of passes */ if (can_bypass(target, parent, parent_flags, allow_direct)) { - return; + return true; } if (!cx || !cy) { obs_source_skip_video_filter(filter); - return; + return false; } if (!filter->filter_texrender) @@ -2690,7 +2734,7 @@ void obs_source_process_filter_begin(obs_source_t *filter, gs_ortho(0.0f, (float)cx, 0.0f, (float)cy, -100.0f, 100.0f); if (target == parent && !custom_draw && !async) - obs_source_default_render(target, use_matrix); + obs_source_default_render(target); else obs_source_video_render(target); @@ -2698,15 +2742,44 @@ void obs_source_process_filter_begin(obs_source_t *filter, } gs_blend_state_pop(); + 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) +{ + obs_source_t *target, *parent; + gs_texture_t *texture; + uint32_t target_flags, parent_flags; + + if (!filter) return; + + target = obs_filter_get_target(filter); + parent = obs_filter_get_parent(filter); + + if (!target || !parent) + return; + + target_flags = target->info.output_flags; + parent_flags = parent->info.output_flags; + + const char *tech = tech_name ? tech_name : "Draw"; + + if (can_bypass(target, parent, parent_flags, filter->allow_direct)) { + render_filter_bypass(target, effect, tech); + } else { + texture = gs_texrender_get_texture(filter->filter_texrender); + 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) { obs_source_t *target, *parent; gs_texture_t *texture; uint32_t target_flags, parent_flags; - bool use_matrix; if (!obs_ptr_valid(filter, "obs_source_process_filter_end")) return; @@ -2715,15 +2788,14 @@ void obs_source_process_filter_end(obs_source_t *filter, gs_effect_t *effect, parent = obs_filter_get_parent(filter); target_flags = target->info.output_flags; parent_flags = parent->info.output_flags; - use_matrix = !!(target_flags & OBS_SOURCE_COLOR_MATRIX); if (can_bypass(target, parent, parent_flags, filter->allow_direct)) { - render_filter_bypass(target, effect, use_matrix); + render_filter_bypass(target, effect, "Draw"); } else { texture = gs_texrender_get_texture(filter->filter_texrender); if (texture) render_filter_tex(texture, effect, width, height, - use_matrix); + "Draw"); } } @@ -2732,7 +2804,6 @@ void obs_source_skip_video_filter(obs_source_t *filter) obs_source_t *target, *parent; bool custom_draw, async; uint32_t parent_flags; - bool use_matrix; if (!obs_ptr_valid(filter, "obs_source_skip_video_filter")) return; @@ -2742,13 +2813,14 @@ void obs_source_skip_video_filter(obs_source_t *filter) parent_flags = parent->info.output_flags; custom_draw = (parent_flags & OBS_SOURCE_CUSTOM_DRAW) != 0; async = (parent_flags & OBS_SOURCE_ASYNC) != 0; - use_matrix = !!(parent_flags & OBS_SOURCE_COLOR_MATRIX); if (target == parent) { if (!custom_draw && !async) - obs_source_default_render(target, use_matrix); + obs_source_default_render(target); else if (target->info.video_render) obs_source_main_render(target); + else if (deinterlacing_enabled(target)) + deinterlace_render(target); else obs_source_render_async_video(target); @@ -3622,7 +3694,7 @@ static inline void process_audio_source_tick(obs_source_t *source, void obs_source_audio_render(obs_source_t *source, uint32_t mixers, size_t channels, size_t sample_rate, size_t size) { - if (!source || !source->audio_output_buf[0][0]) { + if (!source->audio_output_buf[0][0]) { source->audio_pending = true; return; } diff --git a/libobs/obs-source.h b/libobs/obs-source.h index c852ceb..f4b0f80 100644 --- a/libobs/obs-source.h +++ b/libobs/obs-source.h @@ -87,15 +87,6 @@ enum obs_source_type { */ #define OBS_SOURCE_CUSTOM_DRAW (1<<3) -/** - * Source uses a color matrix (usually YUV sources). - * - * When this is used, the video_render callback will automatically assign a - * 4x4 YUV->RGB matrix to the "color_matrix" parameter of the effect, or it can - * be changed to a custom value. - */ -#define OBS_SOURCE_COLOR_MATRIX (1<<4) - /** * Source supports interaction. * diff --git a/libobs/obs-windows.c b/libobs/obs-windows.c index f578e6d..e282a27 100644 --- a/libobs/obs-windows.c +++ b/libobs/obs-windows.c @@ -384,8 +384,8 @@ static bool vk_down(DWORD vk) { short state = GetAsyncKeyState(vk); bool down = (state & 0x8000) != 0; - bool was_down = (state & 0x1) != 0; - return down || was_down; + + return down; } bool obs_hotkeys_platform_is_pressed(obs_hotkeys_platform_t *context, diff --git a/libobs/obs.c b/libobs/obs.c index 9416356..3c93b86 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -215,6 +215,17 @@ static bool obs_init_textures(struct obs_video_info *ovi) return true; } +gs_effect_t *obs_load_effect(gs_effect_t **effect, const char *file) +{ + if (!*effect) { + char *filename = find_libobs_data_file(file); + *effect = gs_effect_create_from_file(filename, NULL); + bfree(filename); + } + + return *effect; +} + static int obs_init_graphics(struct obs_video_info *ovi) { struct obs_core_video *video = &obs->video; @@ -280,6 +291,11 @@ static int obs_init_graphics(struct obs_video_info *ovi) NULL); bfree(filename); + filename = find_libobs_data_file("premultiplied_alpha.effect"); + video->premultiplied_alpha_effect = gs_effect_create_from_file(filename, + NULL); + bfree(filename); + obs->video.transparent_texture = gs_texture_create(2, 2, GS_RGBA, 1, &transparent_tex, 0); @@ -295,6 +311,8 @@ static int obs_init_graphics(struct obs_video_info *ovi) success = false; if (!video->conversion_effect) success = false; + if (!video->premultiplied_alpha_effect) + success = false; if (!video->transparent_texture) success = false; @@ -1340,6 +1358,8 @@ gs_effect_t *obs_get_base_effect(enum obs_base_effect effect) return obs->video.lanczos_effect; case OBS_EFFECT_BILINEAR_LOWRES: return obs->video.bilinear_lowres_effect; + case OBS_EFFECT_PREMULTIPLIED_ALPHA: + return obs->video.premultiplied_alpha_effect; } return NULL; @@ -1401,6 +1421,8 @@ static obs_source_t *obs_load_source_type(obs_data_t *source_data) int64_t sync; uint32_t flags; uint32_t mixers; + int di_order; + int di_mode; source = obs_source_create(id, name, settings, hotkeys); @@ -1444,6 +1466,14 @@ static obs_source_t *obs_load_source_type(obs_data_t *source_data) 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); + + 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); + if (filters) { size_t count = obs_data_array_count(filters); @@ -1474,7 +1504,8 @@ obs_source_t *obs_load_source(obs_data_t *source_data) return obs_load_source_type(source_data); } -void obs_load_sources(obs_data_array_t *array) +void obs_load_sources(obs_data_array_t *array, obs_load_source_cb cb, + void *private_data) { if (!obs) return; @@ -1507,6 +1538,7 @@ void obs_load_sources(obs_data_array_t *array) if (source->info.type == OBS_SOURCE_TYPE_TRANSITION) obs_transition_load(source, source_data); obs_source_load(source); + cb(private_data, source); } obs_data_release(source_data); } @@ -1538,6 +1570,9 @@ obs_data_t *obs_save_source(obs_source_t *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 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); @@ -1562,6 +1597,8 @@ obs_data_t *obs_save_source(obs_source_t *source) 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); if (source->info.type == OBS_SOURCE_TYPE_TRANSITION) obs_transition_save(source, source_data); @@ -1650,6 +1687,7 @@ 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, @@ -1658,6 +1696,7 @@ static inline bool obs_context_data_init_wrap( assert(context); memset(context, 0, sizeof(*context)); context->private = private; + context->type = type; pthread_mutex_init_value(&context->rename_cache_mutex); if (pthread_mutex_init(&context->rename_cache_mutex, NULL) < 0) @@ -1679,13 +1718,14 @@ static inline bool obs_context_data_init_wrap( 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, settings, name, hotkey_data, - private)) { + if (obs_context_data_init_wrap(context, type, settings, name, + hotkey_data, private)) { return true; } else { obs_context_data_free(context); @@ -1768,3 +1808,35 @@ uint64_t obs_get_video_frame_time(void) { return obs ? obs->video.video_time : 0; } + +enum obs_obj_type obs_obj_get_type(void *obj) +{ + struct obs_context_data *context = obj; + return context ? context->type : OBS_OBJ_TYPE_INVALID; +} + +const char *obs_obj_get_id(void *obj) +{ + struct obs_context_data *context = obj; + if (!context) + 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; + default:; + } + + return NULL; +} + +bool obs_obj_invalid(void *obj) +{ + struct obs_context_data *context = obj; + if (!context) + return true; + + return !context->data; +} diff --git a/libobs/obs.h b/libobs/obs.h index f22a146..bc2d995 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -1,5 +1,5 @@ /****************************************************************************** - Copyright (C) 2013-2014 by Hugh Bailey + Copyright (C) 2013-2014 by Hugh Bailey This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -232,6 +232,7 @@ struct obs_source_frame { /* used internally by libobs */ volatile long refs; + bool prev_frame; }; /* ------------------------------------------------------------------------- */ @@ -520,6 +521,7 @@ enum obs_base_effect { OBS_EFFECT_BICUBIC, /**< Bicubic downscale */ OBS_EFFECT_LANCZOS, /**< Lanczos downscale */ OBS_EFFECT_BILINEAR_LOWRES, /**< Bilinear low resolution downscale */ + OBS_EFFECT_PREMULTIPLIED_ALPHA,/**< Premultiplied alpha */ }; /** Returns a commonly used base effect */ @@ -550,8 +552,11 @@ EXPORT obs_data_t *obs_save_source(obs_source_t *source); /** Loads a source from settings data */ EXPORT obs_source_t *obs_load_source(obs_data_t *data); +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); +EXPORT void obs_load_sources(obs_data_array_t *array, obs_load_source_cb cb, + void *private_data); /** Saves sources to a data array */ EXPORT obs_data_array_t *obs_save_sources(void); @@ -560,6 +565,18 @@ 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); +enum obs_obj_type { + OBS_OBJ_TYPE_INVALID, + OBS_OBJ_TYPE_SOURCE, + OBS_OBJ_TYPE_OUTPUT, + OBS_OBJ_TYPE_ENCODER, + OBS_OBJ_TYPE_SERVICE +}; + +EXPORT enum obs_obj_type obs_obj_get_type(void *obj); +EXPORT const char *obs_obj_get_id(void *obj); +EXPORT bool obs_obj_invalid(void *obj); + /* ------------------------------------------------------------------------- */ /* View context */ @@ -864,6 +881,32 @@ EXPORT void obs_source_add_audio_capture_callback(obs_source_t *source, 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, + OBS_DEINTERLACE_MODE_DISCARD, + OBS_DEINTERLACE_MODE_RETRO, + OBS_DEINTERLACE_MODE_BLEND, + OBS_DEINTERLACE_MODE_BLEND_2X, + OBS_DEINTERLACE_MODE_LINEAR, + OBS_DEINTERLACE_MODE_LINEAR_2X, + OBS_DEINTERLACE_MODE_YADIF, + OBS_DEINTERLACE_MODE_YADIF_2X +}; + +enum obs_deinterlace_field_order { + OBS_DEINTERLACE_FIELD_ORDER_TOP, + 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); + /* ------------------------------------------------------------------------- */ /* Functions used by sources */ @@ -925,8 +968,11 @@ EXPORT void obs_source_release_frame(obs_source_t *source, * * After calling this, set your parameters for the effect, then call * obs_source_process_filter_end to draw the filter. + * + * Returns true if filtering should continue, false if the filter is bypassed + * for whatever reason. */ -EXPORT void obs_source_process_filter_begin(obs_source_t *filter, +EXPORT bool obs_source_process_filter_begin(obs_source_t *filter, enum gs_color_format format, enum obs_allow_direct_render allow_direct); @@ -940,6 +986,17 @@ EXPORT void obs_source_process_filter_begin(obs_source_t *filter, EXPORT void obs_source_process_filter_end(obs_source_t *filter, gs_effect_t *effect, uint32_t width, uint32_t height); +/** + * Draws the filter with a specific technique. + * + * Before calling this function, first call obs_source_process_filter_begin and + * then set the effect parameters, and then call this function to finalize the + * 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); + /** Skips the filter if the filter is invalid and cannot be rendered */ EXPORT void obs_source_skip_video_filter(obs_source_t *filter); @@ -1184,6 +1241,21 @@ EXPORT void obs_sceneitem_get_box_transform(const obs_sceneitem_t *item, EXPORT bool obs_sceneitem_visible(const obs_sceneitem_t *item); EXPORT bool obs_sceneitem_set_visible(obs_sceneitem_t *item, bool visible); +struct obs_sceneitem_crop { + int left; + int top; + int right; + int bottom; +}; + +EXPORT void obs_sceneitem_set_crop(obs_sceneitem_t *item, + const struct obs_sceneitem_crop *crop); +EXPORT void obs_sceneitem_get_crop(const obs_sceneitem_t *item, + struct obs_sceneitem_crop *crop); + +EXPORT void obs_sceneitem_defer_update_begin(obs_sceneitem_t *item); +EXPORT void obs_sceneitem_defer_update_end(obs_sceneitem_t *item); + /* ------------------------------------------------------------------------- */ /* Outputs */ @@ -1564,6 +1636,8 @@ EXPORT void *obs_encoder_get_type_data(obs_encoder_t *encoder); EXPORT const char *obs_encoder_get_id(const obs_encoder_t *encoder); +EXPORT uint32_t obs_get_encoder_caps(const char *encoder_id); + /** Duplicates an encoder packet */ EXPORT void obs_duplicate_encoder_packet(struct encoder_packet *dst, const struct encoder_packet *src); @@ -1579,6 +1653,9 @@ 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); +EXPORT obs_service_t *obs_service_create_private(const char *id, + const char *name, obs_data_t *settings); + /** * Adds/releases a reference to a service. When the last reference is * released, the service is destroyed. diff --git a/libobs/util/cf-lexer.c b/libobs/util/cf-lexer.c index e031a96..b62308c 100644 --- a/libobs/util/cf-lexer.c +++ b/libobs/util/cf-lexer.c @@ -602,6 +602,24 @@ static inline void cf_adderror_unexpected_eof(struct cf_preprocessor *pp, NULL, NULL, NULL); } +static inline void insert_path(struct cf_preprocessor *pp, + struct dstr *str_file) +{ + const char *file; + const char *slash; + + if (pp && pp->lex && pp->lex->file) { + file = pp->lex->file; + slash = strrchr(file, '/'); + if (slash) { + struct dstr path = {0}; + dstr_ncopy(&path, file, slash - file + 1); + dstr_insert_dstr(str_file, 0, &path); + dstr_free(&path); + } + } +} + static void cf_include_file(struct cf_preprocessor *pp, const struct cf_token *file_token) { @@ -615,6 +633,7 @@ 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); + insert_path(pp, &str_file); /* if dependency already exists, run preprocessor on it */ for (i = 0; i < pp->dependencies.num; i++) { diff --git a/libobs/util/dstr.c b/libobs/util/dstr.c index d377c32..73cf052 100644 --- a/libobs/util/dstr.c +++ b/libobs/util/dstr.c @@ -346,6 +346,7 @@ void dstr_ncopy(struct dstr *dst, const char *array, const size_t len) dst->array = bmemdup(array, len + 1); dst->len = len; + dst->capacity = len + 1; dst->array[len] = 0; } @@ -363,6 +364,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->capacity = newlen + 1; dst->array[newlen] = 0; } @@ -430,10 +432,11 @@ void dstr_insert(struct dstr *dst, const size_t idx, const char *array) new_len = dst->len + len; dstr_ensure_capacity(dst, new_len + 1); - dst->len = new_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, @@ -450,10 +453,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)); - dst->len = new_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; } void dstr_insert_ch(struct dstr *dst, const size_t idx, const char ch) diff --git a/libobs/util/platform.c b/libobs/util/platform.c index 6f8afea..af031e6 100644 --- a/libobs/util/platform.c +++ b/libobs/util/platform.c @@ -85,6 +85,37 @@ int64_t os_fgetsize(FILE *file) return size; } +#ifdef _WIN32 +int os_stat(const char *file, struct stat *st) +{ + if (file) { + wchar_t w_file[512]; + size_t size = os_utf8_to_wcs(file, 0, w_file, sizeof(w_file)); + if (size > 0) { + struct _stat st_w32; + int ret = _wstat(w_file, &st_w32); + if (ret == 0) { + st->st_dev = st_w32.st_dev; + st->st_ino = st_w32.st_ino; + st->st_mode = st_w32.st_mode; + st->st_nlink = st_w32.st_nlink; + st->st_uid = st_w32.st_uid; + st->st_gid = st_w32.st_gid; + st->st_rdev = st_w32.st_rdev; + st->st_size = st_w32.st_size; + st->st_atime = st_w32.st_atime; + st->st_mtime = st_w32.st_mtime; + st->st_ctime = st_w32.st_ctime; + } + + return ret; + } + } + + return -1; +} +#endif + int os_fseeki64(FILE *file, int64_t offset, int origin) { #ifdef _MSC_VER diff --git a/libobs/util/platform.h b/libobs/util/platform.h index 836d38d..8081717 100644 --- a/libobs/util/platform.h +++ b/libobs/util/platform.h @@ -34,6 +34,12 @@ EXPORT FILE *os_wfopen(const wchar_t *path, const char *mode); EXPORT FILE *os_fopen(const char *path, const char *mode); EXPORT int64_t os_fgetsize(FILE *file); +#ifdef _WIN32 +EXPORT int os_stat(const char *file, struct stat *st); +#else +#define os_stat stat +#endif + EXPORT int os_fseeki64(FILE *file, int64_t offset, int origin); EXPORT int64_t os_ftelli64(FILE *file); diff --git a/libobs/util/text-lookup.c b/libobs/util/text-lookup.c index 2669890..eeac096 100644 --- a/libobs/util/text-lookup.c +++ b/libobs/util/text-lookup.c @@ -287,6 +287,7 @@ static char *convert_string(const char *str, size_t len) dstr_replace(&out, "\\n", "\n"); dstr_replace(&out, "\\t", "\t"); dstr_replace(&out, "\\r", "\r"); + dstr_replace(&out, "\\\"", "\""); return out.array; } diff --git a/obs/data/locale.ini b/obs/data/locale.ini index dbc9077..5c40ddd 100644 --- a/obs/data/locale.ini +++ b/obs/data/locale.ini @@ -85,6 +85,9 @@ Name=Galego [hr-HR] Name=Hrvatski +[he-IL] +Name=עברית + [sr-CS] Name=Srpski @@ -107,4 +110,10 @@ Name=slovenčina Name=Bahasa Melayu [vi-VN] -Name=Tiếng Việt \ No newline at end of file +Name=Tiếng Việt + +[ta-IN] +Name=தமிழ் + +[lt-LT] +Name=Lietuvių kalba \ No newline at end of file diff --git a/obs/data/locale/ar-SA.ini b/obs/data/locale/ar-SA.ini index 7b7e912..e1d53c5 100644 --- a/obs/data/locale/ar-SA.ini +++ b/obs/data/locale/ar-SA.ini @@ -8,31 +8,77 @@ 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)" +PreviewProjector="عرض بالشاشة الكاملة (المعاينة)" +SceneProjector="عرض بالشاشة الكاملة (المشهد)" +SourceProjector="عرض بالشاشة الكاملة (المصدر)" +Clear="مسح" +Revert="استعادة" +Show="إظهار" +Hide="اخفاء" +Untitled="بدون عنوان" +New="جديد" +Duplicate="تكرار مزدوج" +Enable="تفعيل" +DisableOSXVSync="تعطيل خاصية OSX V-Sync" +ResetOSXVSyncOnExit="اعادة تعيين خاصية OSX V-sync عند الخروج" +HighResourceUsage="زيادة الحِمل في غملية ترميز الفيديو! خذ بعين الاعتبار تخفيض اعدادات الفيديو, او استخدم اعدادات ترميز اسرع." +Transition="تبديل المشهد" +QuickTransitions="تبديل سريع" +Left="يسار" +Right="يمين" +Top="أعلى" +Bottom="أسفل" +QuickTransitions.SwapScenes="التبديل بين مشهدي المعاينة و الاخراج بعد عملية الانتقال" +QuickTransitions.SwapScenesTT="يقوم بتبديل مشهد المعاينة مع مشهد الاخراج بعد عملية الانتقال بين المشاهد (اذا كان مشهد الاخراج الاصلي لازال موجوداً) \n هذا لن يقوم بالتراجع عن اي تغييرات قمت بها على مشهد الاخراج الأصلي." +QuickTransitions.DuplicateScene="استنساخ المشهد" +QuickTransitions.EditProperties="استنساخ المصدر" +QuickTransitions.HotkeyName="الانتقال السريع: %1" +Basic.TransitionProperties="خصائص تأثير الإنتقال" +Basic.SceneTransitions="تأثير انتقال المشهد" +Basic.TransitionDuration="مدة الانتقال" +Basic.TogglePreviewProgramMode="طور الاستوديو" +TransitionNameDlg.Title="اسم تأثير الإنتقال" + +TitleBar.Profile="الملف الشخصي" +TitleBar.Scenes="المشاهد" NameExists.Title="الاسم موجود بالفعل" NameExists.Text="الاسم مستخدم حاليا." +NoNameEntered.Title="الرجاء إدخال اسم صالح" +NoNameEntered.Text="لا يمكنك استخدام أسماء فارغة." +ConfirmStart.Title="بدء البث ؟" +ConfirmStart.Text="هل انت متأكد انك تريد بدء البث ؟" +ConfirmStop.Title="ايقاف البث؟" +ConfirmStop.Text="هل أنت متأكد انك تريد ايقاف البث؟" +ConfirmExit.Title="الخروج من OBS ؟" +ConfirmExit.Text="OBS حالياً نشط، كافة عمليات البث/التسجيلات سيتم إيقافها، هل أنت متأكد من رغبتك في الخروج ؟" ConfirmRemove.Title="تأكيد الإزالة" ConfirmRemove.Text="هل أنت متأكد من رغبتك في إزالة '$1' ?" @@ -40,10 +86,12 @@ ConfirmRemove.Text="هل أنت متأكد من رغبتك في إزالة '$1' Output.ConnectFail.Title="فشل في الاتصال" Output.ConnectFail.BadPath="مسار أو رابط الاتصال غير صالح. الرجاء التحقق من الإعدادات للتحقق من كونه صالح." Output.ConnectFail.ConnectFailed="فشل الاتصال بالسيرفر" -Output.ConnectFail.InvalidStream="غير قادر على الوصول للقناة المحددة او مفتاح البث. قد يكون هذا بسبب ان المفتاح/القناة غير صحيحة , او بسبب ان السيرفر يعتبر انك لازلت في وضع تسجيل الدخول." +Output.ConnectFail.InvalidStream="تعذر الوصول إلى القناة أو مفتاح البث المحدد، الرجاء أعد التحقق من صحة مفتاح البث الخاص بك، أما إذا كان صحيحاً، قد تكون المشكلة في الاتصال بالخادم." Output.ConnectFail.Error="حدث خطأ غير متوقع عند محاولة الاتصال بالخادم. مزيد من المعلومات في ملف السجل." Output.ConnectFail.Disconnected="تم قطع الاتصال من السيرفر." +Output.RecordFail.Title="فشل في بدء التسجيل" +Output.RecordError.Title="خطأ في التسجيل" Output.BadPath.Title="مسار الملف غير صحيح" Output.BadPath.Text="مسار الإخراج ملف تكوين غير صالح. الرجاء التحقق من الإعدادات الخاصة بك للتأكد من أنه تم تعيين مسار ملف صحيح." @@ -58,6 +106,9 @@ LicenseAgreement.ClickIAgreeToContinue="إذا قمت بقبول شروط الا LicenseAgreement.IAgree="موافق" LicenseAgreement.Exit="خروج" +Remux.SourceFile="تسجيل OBS" +Remux.TargetFile="الملف الهدف" +Remux.OBSRecording="تسجيل OBS" UpdateAvailable="تحديث جديد متوفر" UpdateAvailable.Text="الإصدار %1.%2.%3 متوفر الآن. انقر هنا للتتحميل" @@ -72,6 +123,9 @@ Basic.AuxDevice4="Mic/Aux 4" Basic.Scene="مشهد" Basic.DisplayCapture="التقاط الشاشة" +Basic.Main.PreviewConextMenu.Enable="تمكين المعاينة" + +Deinterlacing.Discard="تجاهل" Basic.Main.AddSceneDlg.Title="أضف المشهد" Basic.Main.AddSceneDlg.Text="الرجاء إدخال اسم المشهد" @@ -89,20 +143,30 @@ Basic.SourceSelect.AddExisting="إضافة عنصر موجود" Basic.PropertiesWindow="خصائص ل '%1'" Basic.PropertiesWindow.SelectColor="تحديد اللون" +Basic.PropertiesWindow.SelectFont="إختيار خط" +Basic.PropertiesWindow.AddFiles="إضافة ملفات" Basic.StatusBar.ReconnectSuccessful="إعادة الاتصال الناجح" +Basic.Filters="مرشحات" +Basic.Filters.AsyncFilters="مرشحات الصوت/الفيديو" +Basic.Filters.AudioFilters="مرشحات الصوت" +Basic.Filters.EffectFilters="مرشحات التأثير" +Basic.Filters.Title="مرشحات لـ '%1'" +Basic.Filters.AddFilter.Title="اسم المرشّح" +Basic.Filters.AddFilter.Text="الرجاء تحديد اسم المرشح" -Basic.TransformWindow="تحويل البند المشهد" -Basic.TransformWindow.Position="موقف" -Basic.TransformWindow.Rotation="التدوير" +Basic.TransformWindow="تحوّل عنصر المشهد" +Basic.TransformWindow.Position="موضع" +Basic.TransformWindow.Rotation="الإستدارة" Basic.TransformWindow.Size="الحجم" Basic.TransformWindow.Alignment="محاذاة الموضعية" Basic.TransformWindow.BoundsType="نوع مربع الإحاطة" Basic.TransformWindow.BoundsAlignment="المحاذاة في المربع المحيط" Basic.TransformWindow.Bounds="حجم المربع المحيط" +Basic.TransformWindow.Crop="قطع" Basic.TransformWindow.Alignment.TopLeft="أعلى اليسار" Basic.TransformWindow.Alignment.TopCenter="أعلى الوسط" @@ -116,8 +180,8 @@ Basic.TransformWindow.Alignment.BottomRight="أسفل اليمين" Basic.TransformWindow.BoundsType.None="لا حدود له" Basic.TransformWindow.BoundsType.MaxOnly="الحد الأقصى للحجم فقط" -Basic.TransformWindow.BoundsType.ScaleInner="مقياس لحدود داخلية" -Basic.TransformWindow.BoundsType.ScaleOuter="مقياس للحدود الخارجية" +Basic.TransformWindow.BoundsType.ScaleInner="تحجيم للحدود الداخلية" +Basic.TransformWindow.BoundsType.ScaleOuter="تحجيم للحدود الخارجية" Basic.TransformWindow.BoundsType.ScaleToWidth="مقياس لعرض الحدود" Basic.TransformWindow.BoundsType.ScaleToHeight="مقياس للارتفاع الحدود" Basic.TransformWindow.BoundsType.Stretch="تمتد إلى الحدود" @@ -127,7 +191,7 @@ Basic.Main.AddSourceHelp.Text="تحتاج إلى أن يكون على الأقل Basic.Main.Scenes="المشاهد" Basic.Main.Sources="المصادر" -Basic.Main.Connecting="جاري الإتصال..." +Basic.Main.Connecting="يتصل..." Basic.Main.StartRecording="بدء التسجيل" Basic.Main.StartStreaming="بدء البث" Basic.Main.StopRecording="إيقاف التسجيل" @@ -136,7 +200,11 @@ Basic.Main.StopStreaming="ايقاف البث" Basic.MainMenu.File="&ملف" Basic.MainMenu.File.Export="&تصدير" Basic.MainMenu.File.Import="&استيراد" +Basic.MainMenu.File.ShowRecordings="إظهار &التسجيلات" Basic.MainMenu.File.Settings="&الإعدادات" +Basic.MainMenu.File.ShowSettingsFolder="إظهار مجلد الإعدادات" +Basic.MainMenu.File.ShowProfileFolder="إظهار مجلد الملف الشخصي" +Basic.MainMenu.AlwaysOnTop="&دائماً في القمة" Basic.MainMenu.File.Exit="&خروج" Basic.MainMenu.Edit="&تعديل" @@ -155,14 +223,18 @@ Basic.MainMenu.Edit.Transform.FlipVertical="انعكاس &عمودي" Basic.MainMenu.Edit.Transform.FitToScreen="&تمديد الشاشة" Basic.MainMenu.Edit.Transform.StretchToScreen="&تمتد إلى الشاشة" Basic.MainMenu.Edit.Transform.CenterToScreen="&وسط الشاشة" -Basic.MainMenu.Edit.Order="&الطلب" +Basic.MainMenu.Edit.Order="&الترتيب" Basic.MainMenu.Edit.Order.MoveUp="التحرك &للأعلى" Basic.MainMenu.Edit.Order.MoveDown="التحرك &للأسفل" Basic.MainMenu.Edit.Order.MoveToTop="التحرك &للقمة" Basic.MainMenu.Edit.Order.MoveToBottom="التحرك &للقاع" +Basic.MainMenu.Edit.AdvAudio="&خصائص الصوت المتقدمة" +Basic.MainMenu.SceneCollection="&مجموعة المشاهد" +Basic.MainMenu.Profile="&الملف الشخصي" -Basic.MainMenu.Help="&المساعدة" +Basic.MainMenu.Help="&مساعدة" +Basic.MainMenu.Help.Website="زيارة &الموقع الإلكتروني" Basic.MainMenu.Help.Logs="&ملفات السجل" Basic.MainMenu.Help.Logs.UploadCurrentLog="رفع &ملف السجل الحالي" Basic.MainMenu.Help.Logs.UploadLastLog="رفع &آخر ملف سجل" @@ -173,12 +245,18 @@ Basic.Settings.ConfirmTitle="تأكيد التغييرات" Basic.Settings.Confirm="لديك تغييرات غير محفوظة. هل تريد حفظها?" Basic.Settings.General="عام" +Basic.Settings.General.Theme="السمة" +Basic.Settings.General.Language="اللغة" Basic.Settings.Stream="بث" Basic.Settings.Stream.StreamType="نوع البث" Basic.Settings.Output="المخرج" +Basic.Settings.Output.Format="صيغة التسجيل" +Basic.Settings.Output.Encoder="مرمّز" Basic.Settings.Output.Mode="نوع المخرج" +Basic.Settings.Output.Mode.Simple="بسيط" +Basic.Settings.Output.Mode.Adv="متقدم" Basic.Settings.Output.VideoBitrate="معدل البت للفيديو" Basic.Settings.Output.AudioBitrate="معدل البت للصوت" Basic.Settings.Output.Reconnect="إعادة الاتصال تلقائياً" @@ -186,6 +264,10 @@ Basic.Settings.Output.RetryDelay="إعادة محاولة تأخير (ثوان)" Basic.Settings.Output.MaxRetries="أقصى عدد للمحاولات" +Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="‮كل الملفات" +Basic.Settings.Output.Adv.FFmpeg.Format="صيغة الحاوية" + + Basic.Settings.Video="الفيديو" Basic.Settings.Video.Adapter="محول الفيديو:" diff --git a/obs/data/locale/bg-BG.ini b/obs/data/locale/bg-BG.ini index d4ec584..1499e6a 100644 --- a/obs/data/locale/bg-BG.ini +++ b/obs/data/locale/bg-BG.ini @@ -8,6 +8,7 @@ Cancel="Откажи" Close="Затвори" Save="Запази" Discard="Отхвърли" +Disable="Деактивирай" Yes="Да" No="Не" Add="Добави" @@ -43,6 +44,7 @@ ResetOSXVSyncOnExit="Рестартиране на OSX V-синхронизац + TitleBar.Profile="Профил" TitleBar.Scenes="Сцени" @@ -62,7 +64,6 @@ ConfirmRemove.Text="Наистина ли искате да премахнете Output.ConnectFail.Title="Неуспешно свързване" Output.ConnectFail.BadPath="Невалиден път или URL. Проверете дали настройките ви са валидни." Output.ConnectFail.ConnectFailed="Неуспешна връзка със сървъра" -Output.ConnectFail.InvalidStream="Избраният канал или стрийм ключ не е достъпен, Причината може да е невалиден ключ/канал, или защото сървърът предполага, че сте все още логнат." Output.ConnectFail.Error="Неочаквана грешка при опит за връзка със сървъра. Повече информация в \"log\" файла." Output.ConnectFail.Disconnected="Изключен от сървъра." @@ -84,7 +85,6 @@ LicenseAgreement.Exit="Изход" Remux.SourceFile="OBS запис" Remux.TargetFile="Целеви файл" Remux.Remux="Конвертиране" -Remux.RecordingPattern="OBS запис (*.flv)" Remux.FinishedTitle="Конвертирането завърши" Remux.Finished="Записът е конвертиран" Remux.FinishedError="Записът е конвертиран, но файлът може да бъде незавършен" @@ -110,6 +110,7 @@ Basic.DisplayCapture="Заснемане на екрана" Basic.Main.PreviewConextMenu.Enable="Разреши преглед" + Basic.Main.AddSceneDlg.Title="Добави сцена" Basic.Main.AddSceneDlg.Text="Моля, въведете името на сцената" @@ -248,6 +249,8 @@ Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Аудио" Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Видео" Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Формат по подразбиране" + + Basic.Settings.Video="Видео" Basic.Settings.Video.Adapter="Видео адаптер:" Basic.Settings.Video.DownscaleFilter="Филтър:" diff --git a/obs/data/locale/ca-ES.ini b/obs/data/locale/ca-ES.ini index 2c507ae..540d82a 100644 --- a/obs/data/locale/ca-ES.ini +++ b/obs/data/locale/ca-ES.ini @@ -8,6 +8,7 @@ Cancel="Cancel·la" Close="Tanca" Save="Desa" Discard="Descarta" +Disable="Inhabilita" Yes="Sí" No="No" Add="Afegeix" @@ -38,8 +39,33 @@ Untitled="Sense títol" New="Nou" Duplicate="Duplica" Enable="Activa" +DisableOSXVSync="Inhabilita V-Sync en OSX" +ResetOSXVSyncOnExit="Reinicia V-Sync de OSX a la sortida" +HighResourceUsage="Sobrecàrrega en codificar! Consideri baixar els ajustos de vídeo o utilitzar una configuració del codificador mes ràpida." +Transition="Transició" +QuickTransitions="Transicions ràpides" +Left="Esquerra" +Right="Dreta" +Top="Part superior" +Bottom="Part inferior" +QuickTransitions.SwapScenes="Canvia la vista prèvia i sortida d'escenes després de la transició" +QuickTransitions.SwapScenesTT="Canvia la vista prèvia i sortida d'escenes després de la transició (si encara existeix l'escena original de la sortida). \nAixò no desfarà qualsevol canvi que pugui haver fet a l'escena original de la sortida." +QuickTransitions.DuplicateScene="Duplica l'escena" +QuickTransitions.DuplicateSceneTT="Al editar la misma escena, permite la edición transformar/visibilidad de fuentes sin modificar las salida.\nPer editar les propietats de les fonts sense modificar la sortida, activi 'Duplicar Fonts'.\nCanviant aquest valor restablirà l'escena actual de sortida (si encara existeix)." +QuickTransitions.EditProperties="Duplica les fonts" +QuickTransitions.EditPropertiesTT="En editar la mateixa escena, permeti editar propietats de fonts sense modificar la sortida.\n Això només es pot utilitzar si està activat 'Duplicar l'escena'.\nCertes fonts (tals com a fonts de captura o els mitjans de comunicació) no són compatibles amb això i no es poden editar per separat.\nCanviant aquest valor restablirà l'escena actual de sortida (si encara existeix).\n\nAdvertiment: com es duplicaran les fonts, això requerirà un extra de recursos del sistema i de vídeo." +QuickTransitions.HotkeyName="Transició Ràpida: %1" +Basic.AddTransition="Afegir transició configurable" +Basic.RemoveTransition="Eliminar transició configurable" +Basic.TransitionProperties="Propietats de la transició" +Basic.SceneTransitions="Transicions d'escena" +Basic.TransitionDuration="Duració" +Basic.TogglePreviewProgramMode="Mode estudi" + +TransitionNameDlg.Text="Si us plau, introdueixi el nom de la transició" +TransitionNameDlg.Title="Nom de la transició" TitleBar.Profile="Perfil" TitleBar.Scenes="Escenes" @@ -50,7 +76,11 @@ NameExists.Text="Aquest nom ja és en ús." NoNameEntered.Title="Introduïu un nom vàlid" NoNameEntered.Text="No podeu usar noms buits." +ConfirmStart.Title="Inicia la transmissió?" +ConfirmStart.Text="Està segur que desitja iniciar la transmissió?" +ConfirmStop.Title="Atura la transmissió?" +ConfirmStop.Text="Està segur que desitja aturar la transmissió?" ConfirmExit.Title="Voleu sortir de l'OBS?" ConfirmExit.Text="OBS és actualment actiu. Tots els directes/gravacions s'aturaran. Esteu segur que voleu sortir?" @@ -61,7 +91,7 @@ ConfirmRemove.Text="Esteu segur que voleu suprimir «$1»?" 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." Output.ConnectFail.ConnectFailed="No ha pogut connectar al servidor" -Output.ConnectFail.InvalidStream="No es pot accedir al canal o la clau d'stream especificat. Això podria ser degut a que el codi o la clau introduïts no són vàlids, o perquè el servidor encara considera que hi estàs connectat." +Output.ConnectFail.InvalidStream="No pot accedir a la clau del canal especificat o de la transmissió, per favor comprovar dues vegades la seva clau de transmissió. Si és correcte, pot haver-hi un problema connectant-se al servidor." Output.ConnectFail.Error="S'ha produït un error inesperat quan s'intentava connectar amb el servidor. Més informació al fitxer de registre." Output.ConnectFail.Disconnected="Desconnectat del servidor." @@ -88,7 +118,7 @@ LicenseAgreement.Exit="Surt" Remux.SourceFile="Enregistrament OBS" Remux.TargetFile="Fitxer de destinació" Remux.Remux="Converteix" -Remux.RecordingPattern="Gravació OBS (*.flv)" +Remux.OBSRecording="Enregistrament OBS" Remux.FinishedTitle="Conversió finalitzada" Remux.Finished="Gravació convertida" Remux.FinishedError="Gravació convertida, però l'arxiu pot ser incomplet" @@ -114,6 +144,18 @@ Basic.DisplayCapture="Captura de pantalla" Basic.Main.PreviewConextMenu.Enable="Habilita la visualització prèvia" +Deinterlacing="Desentrellaçar" +Deinterlacing.Discard="Descarta" +Deinterlacing.Retro="Retro" +Deinterlacing.Blend="Barrejat" +Deinterlacing.Blend2x="Barrejat 2x" +Deinterlacing.Linear="Lineal" +Deinterlacing.Linear2x="Lineal 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Camp superior primer" +Deinterlacing.BottomFieldFirst="Camp inferior primer" + Basic.Main.AddSceneDlg.Title="Afegeix una escena" Basic.Main.AddSceneDlg.Text="Introduïu el nom de l'escena" @@ -179,6 +221,7 @@ Basic.TransformWindow.Alignment="Posició" Basic.TransformWindow.BoundsType="Tipus de quadre de limitació" Basic.TransformWindow.BoundsAlignment="Alineació en el quadre de limitació" Basic.TransformWindow.Bounds="Mida del quadre de limitació" +Basic.TransformWindow.Crop="Retalla" Basic.TransformWindow.Alignment.TopLeft="Part superior esquerra" Basic.TransformWindow.Alignment.TopCenter="Part superior centre" @@ -218,6 +261,7 @@ Basic.MainMenu.File.Remux="Converteix format de gravacions" Basic.MainMenu.File.Settings="&Paràmetres" Basic.MainMenu.File.ShowSettingsFolder="Mostrar carpeta de configuració" Basic.MainMenu.File.ShowProfileFolder="Mostra la carpeta del perfil" +Basic.MainMenu.AlwaysOnTop="&Sempre al davant" Basic.MainMenu.File.Exit="&Surt" Basic.MainMenu.Edit="&Edita" @@ -262,6 +306,13 @@ Basic.Settings.Confirm="Hi han canvis no desats. Voleu desar els canvis?" Basic.Settings.General="General" Basic.Settings.General.Theme="Tema" Basic.Settings.General.Language="Llengua" +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.Snapping="Ajustament d'alineació de la font" +Basic.Settings.General.ScreenSnapping="Ajustar les fonts a la vora de la pantalla" +Basic.Settings.General.CenterSnapping="Ajustar les fonts al centre horitzontal i vertical" +Basic.Settings.General.SourceSnapping="Ajustar les fonts a altres fonts" +Basic.Settings.General.SnapDistance="Ajusta la sensibilitat" Basic.Settings.Stream="Directe" Basic.Settings.Stream.StreamType="Tipus de directe" @@ -271,6 +322,7 @@ Basic.Settings.Output.Format="Format d'enregistrament" 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.Mode="Mode de sortida" Basic.Settings.Output.Mode.Simple="Simple" Basic.Settings.Output.Mode.Adv="Avançat" @@ -281,11 +333,16 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Mateixa que en directe" Basic.Settings.Output.Simple.RecordingQuality.Small="Qualitat alta, mida d'arxiu mitjana" Basic.Settings.Output.Simple.RecordingQuality.HQ="Qualitat molt elevada, mida de fitxer gran" 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.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?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Advertiment de qualitat sense pèrdues!" +Basic.Settings.Output.Simple.Warn.MultipleQSV="Advertència: No es poden utilitzar diversos descodificadors QSV separats en transmetre i enregistrar al mateix temps. Per transmetre i engrestriar al mateix temps, si us plau modifiqueu-los, ja sigui el codificador de gravació o el codificador de transmissió." Basic.Settings.Output.Simple.Encoder.Software="Programari (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Maquinari (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Maquinari (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Programari (preconfiguració de x264 amb baix ús de CPU, augmenta la mida del fitxer)" Basic.Settings.Output.VideoBitrate="Bitrate de vídeo" Basic.Settings.Output.AudioBitrate="Bitrate d'àudio" @@ -312,6 +369,8 @@ Basic.Settings.Output.Adv.Recording.Type="Tipus" Basic.Settings.Output.Adv.Recording.Type.Standard="Estàndard" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Sortida personalitzada (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Fer servir codificador de directe)" +Basic.Settings.Output.Adv.Recording.Filename="Nom de l'arxiu de format" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Sobreescriure si l'arxiu existeix" Basic.Settings.Output.Adv.FFmpeg.Type="Tipus de sortida FFmpeg" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Sortida a un URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Sortida a un fitxer" @@ -332,6 +391,10 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Codificador d'àudio" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Configuració de codificador d'àudio (si escau)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Configuració del convertidor (si escau)" +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 Any, quatre dígits\n%YY Any, darrers dos digits (00-99)\n%MM Mes com a número decimal (01-12)\n%DD Dia del mes, emplena amb zero (01-31)\n%hh Hora en format 24h (00-23)\n%mm Minut (00-59)\n%ss Segon (00-61)\n%% A % signe\n%a Nom de la setmana abreujat\n%A Nom complet de la setmana\n%b Nom del mes abreujat\n%B Nom del mes complet\n%d Dia del mes, zero-afegit (01-31)\n%H Hora en format 24h (00-23)\n%I Hora en format 12h (01-12)\n%m Mes com a número decimal (01-12)\n%M Minut (00-59)\n%p Designació AM o PM\n%S Segon (00-61)\n%y Any, darrers dos dígits (00-99)\n%Y Any\n%z ISO 8601 ajust UTC o zona horària\n nom or abreujament\n%Z Nom de la zona horària o abreujament\n" + Basic.Settings.Video="Vídeo" Basic.Settings.Video.Adapter="Adaptador de vídeo:" Basic.Settings.Video.BaseResolution="Resolució base (quadre):" @@ -365,6 +428,7 @@ Basic.Settings.Audio.EnablePushToMute="Activa \"prémer-per-silenciar\"" Basic.Settings.Audio.PushToMuteDelay="Retard \"prémer-per-silenciar\"" Basic.Settings.Audio.EnablePushToTalk="Activa \"prémer-per-parlar\"" Basic.Settings.Audio.PushToTalkDelay="Retard de \"prémer-per-parlar\"" +Basic.Settings.Audio.UnknownAudioDevice="[Dispositiu no connectat o no disponible]" Basic.Settings.Advanced="Avançat" Basic.Settings.Advanced.FormatWarning="Advertiment: Els formats de color diferents de NV12 estan destinats principalment per a la gravació i no són recomanables quan es fa un directe. Fer un directe pot comportar un major ús de CPU a causa de la conversió de format de color." diff --git a/obs/data/locale/cs-CZ.ini b/obs/data/locale/cs-CZ.ini index 4bb1871..9f20351 100644 --- a/obs/data/locale/cs-CZ.ini +++ b/obs/data/locale/cs-CZ.ini @@ -8,6 +8,7 @@ Cancel="Zrušit" Close="Zavřít" Save="Uložit" Discard="Zahodit" +Disable="Vypnout" Yes="Ano" No="Ne" Add="Přidat" @@ -43,6 +44,10 @@ ResetOSXVSyncOnExit="Resetovat OSX V-Sync při ukončení" HighResourceUsage="Vysoké zatížení enkodéru! Zvažte snížení požadavků v nastavení obrazu nebo použití rychlé předvolby enkodéru." Transition="Přechod" QuickTransitions="Rychlé přechody" +Left="Vlevo" +Right="Vpravo" +Top="Nahoře" +Bottom="Dole" QuickTransitions.SwapScenes="Prohodit scény náhledu a výstupu po přechodu" QuickTransitions.SwapScenesTT="Prohodí scény náhledu a výstupu po přechodu (pokud originální výstupní scéna stále existuje).\nTato funkce nevrátí provedené změny, které byly provedeny v originální scéně výstupu." @@ -52,10 +57,16 @@ QuickTransitions.EditProperties="Duplikovat zdroje" QuickTransitions.EditPropertiesTT="Při úpravě stejné scény, umožňuje úpravu vlastností zdrojů bez úpravy výstupu.\nTato funkce může být použita pouze, pokud je zapnuto 'Duplikovat scénu'.\nNěkteré zdroje (jako jsou zdroje záznamu či mediální zdroje) tuto funkci nepodporují a nemohou být upraveny samostatně.\nPo změně této hodnoty bude aktuální scéna výstupu resetována (pokud stále existuje).\n\nVarování: Z důvodu duplikace zdrojů může tato funkce vyžadovat více systémových prostředků." QuickTransitions.HotkeyName="Rychlý přechod: %1" +Basic.AddTransition="Přidat nastavitelný přechod" +Basic.RemoveTransition="Odebrat nastavitelný přechod" +Basic.TransitionProperties="Vlastnosti přechodu" Basic.SceneTransitions="Přechody scény" Basic.TransitionDuration="Délka" Basic.TogglePreviewProgramMode="Studiový mód" +TransitionNameDlg.Text="Zadejte název přechodu" +TransitionNameDlg.Title="Název přechodu" + TitleBar.Profile="Profil" TitleBar.Scenes="Scény" @@ -80,7 +91,7 @@ ConfirmRemove.Text="Opravdu si přejete odebrat '$1'?" Output.ConnectFail.Title="Spojení se nezdařilo" Output.ConnectFail.BadPath="Chybná cesta nebo adresa připojení. Zkontrolujte, prosím, správnost svých nastavení." Output.ConnectFail.ConnectFailed="K serveru se nepodařilo připojit" -Output.ConnectFail.InvalidStream="Nelze přistoupit ke specifickému vysílacímu klíči. Může to být zapříčiněno chybným klíčem nebo samotným serverem (stále si myslí, že jste přihlášeni)." +Output.ConnectFail.InvalidStream="K nastavenému kanálu či klíči nelze přistoupit. Zkontrolujte, zda je vysílací klíč správný. Pokud ano, může být problém s připojením k serveru." Output.ConnectFail.Error="Při pokusu o připojení k serveru došlo k neočekávané chybě. Další informace v záznamovém souboru." Output.ConnectFail.Disconnected="Odpojen od serveru." @@ -95,7 +106,7 @@ Output.BadPath.Title="Špatná cesta k souboru" Output.BadPath.Text="Nastavená cesta k výstupnímu souboru je chybná. Zkontrolujte nastavení, zda není cesta špatně napsána." LogReturnDialog="Záznam byl úspěšně nahrán" -LogReturnDialog.CopyURL="Zkopírovat URL" +LogReturnDialog.CopyURL="Zkopírovat" LogReturnDialog.ErrorUploadingLog="Nahrání záznamu se nezdařilo" LicenseAgreement="Licenční smlouva" @@ -107,7 +118,7 @@ LicenseAgreement.Exit="Konec" Remux.SourceFile="OBS nahrávka" Remux.TargetFile="Cílový soubor" Remux.Remux="Převést" -Remux.RecordingPattern="OBS nahrávka (*.flv)" +Remux.OBSRecording="OBS nahrávka" Remux.FinishedTitle="Převod dokončen" Remux.Finished="Nahrávka převedena" Remux.FinishedError="Nahrávka převedena, ale soubor nemusí být kompletní" @@ -133,6 +144,18 @@ Basic.DisplayCapture="Záznam obrazovky" Basic.Main.PreviewConextMenu.Enable="Povolit náhled" +Deinterlacing="Odstranění prokladu" +Deinterlacing.Discard="Zahození" +Deinterlacing.Retro="Retro" +Deinterlacing.Blend="Prolnutí" +Deinterlacing.Blend2x="Prolnutí 2x" +Deinterlacing.Linear="Lineární" +Deinterlacing.Linear2x="Lineární 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Svrchní řádek dříve" +Deinterlacing.BottomFieldFirst="Spodní řádek dříve" + Basic.Main.AddSceneDlg.Title="Přidat scénu" Basic.Main.AddSceneDlg.Text="Prosím, zadejte jméno scény" @@ -155,7 +178,7 @@ Basic.SourceSelect.CreateNew="Vytvořit nový" Basic.SourceSelect.AddExisting="Přidat existující" Basic.SourceSelect.AddVisible="Zviditelnit zdroj" -Basic.PropertiesWindow="Vlastnosti pro '%1'" +Basic.PropertiesWindow="Vlastnosti objektu '%1'" Basic.PropertiesWindow.AutoSelectFormat="%1 (automatické: %2)" Basic.PropertiesWindow.SelectColor="Výběr barvy" Basic.PropertiesWindow.SelectFont="Výběr písma" @@ -198,6 +221,7 @@ Basic.TransformWindow.Alignment="Zarovnání pozice" Basic.TransformWindow.BoundsType="Typ ohraničení" Basic.TransformWindow.BoundsAlignment="Zarovnání v hranici" Basic.TransformWindow.Bounds="Velikost hranice" +Basic.TransformWindow.Crop="Oříznout" Basic.TransformWindow.Alignment.TopLeft="Nahoře, vlevo" Basic.TransformWindow.Alignment.TopCenter="Nahoře, uprostřed" @@ -229,50 +253,50 @@ Basic.Main.StopRecording="Zastavit nahrávání" Basic.Main.StopStreaming="Zastavit vysílání" Basic.Main.ForceStopStreaming="Zastavit vysání (bez zpoždění)" -Basic.MainMenu.File="&Soubor" +Basic.MainMenu.File="Soubor (&F)" Basic.MainMenu.File.Export="&Exportovat" Basic.MainMenu.File.Import="&Importovat" -Basic.MainMenu.File.ShowRecordings="Zobrazit &nahrávky" -Basic.MainMenu.File.Remux="&Převést nahrávky" +Basic.MainMenu.File.ShowRecordings="Zobrazit nahrávky (&R)" +Basic.MainMenu.File.Remux="Převést nahrávky (&M)" Basic.MainMenu.File.Settings="Na&stavení" Basic.MainMenu.File.ShowSettingsFolder="Zobrazit složku nastavení" Basic.MainMenu.File.ShowProfileFolder="Zobrazit složku profilu" -Basic.MainMenu.AlwaysOnTop="&Vždy navrchu" -Basic.MainMenu.File.Exit="&Skončit" +Basic.MainMenu.AlwaysOnTop="Vždy n&avrchu" +Basic.MainMenu.File.Exit="Kon&ec" -Basic.MainMenu.Edit="&Upravit" -Basic.MainMenu.Edit.Undo="&Zpět" -Basic.MainMenu.Edit.Redo="Zno&vu" -Basic.MainMenu.Edit.UndoAction="&Zpět $1" -Basic.MainMenu.Edit.RedoAction="Zno&vu $1" -Basic.MainMenu.Edit.Transform="&Pozicování" -Basic.MainMenu.Edit.Transform.EditTransform="&Upravit pozici..." -Basic.MainMenu.Edit.Transform.ResetTransform="&Obnovit pozici" +Basic.MainMenu.Edit="Upravit (&E)" +Basic.MainMenu.Edit.Undo="Zpět (&U)" +Basic.MainMenu.Edit.Redo="Znovu (&R)" +Basic.MainMenu.Edit.UndoAction="Zpět $1 (&U)" +Basic.MainMenu.Edit.RedoAction="Znovu $1 (&R)" +Basic.MainMenu.Edit.Transform="Pozicování (&T)" +Basic.MainMenu.Edit.Transform.EditTransform="Upravit pozici... (&E)" +Basic.MainMenu.Edit.Transform.ResetTransform="Obnovit pozici (&R)" Basic.MainMenu.Edit.Transform.Rotate90CW="Otočit o 90 stupňů vpravo" Basic.MainMenu.Edit.Transform.Rotate90CCW="Otočit o 90 stupňů vlevo" Basic.MainMenu.Edit.Transform.Rotate180="Otočit o 180 stupňů" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Překlopit &vodorovně" -Basic.MainMenu.Edit.Transform.FlipVertical="Překlopit &svisle" -Basic.MainMenu.Edit.Transform.FitToScreen="&Přizpůsobit obrazovce" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Roztáhnout na obrazovku" -Basic.MainMenu.Edit.Transform.CenterToScreen="&Vycentrovat" -Basic.MainMenu.Edit.Order="&Pořadí" -Basic.MainMenu.Edit.Order.MoveUp="Posunout &výše" -Basic.MainMenu.Edit.Order.MoveDown="Posunout &níže" -Basic.MainMenu.Edit.Order.MoveToTop="Posunout na &vršek" -Basic.MainMenu.Edit.Order.MoveToBottom="Posunout na &spodek" -Basic.MainMenu.Edit.AdvAudio="&Rozšířené vlastnosti zvuku" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Překlopit vodorovně (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="Překlopit s&visle" +Basic.MainMenu.Edit.Transform.FitToScreen="Přizpůsobit obrazovce (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Roztáhnout na obrazovku (&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="Vy¢rovat" +Basic.MainMenu.Edit.Order="P&ořadí" +Basic.MainMenu.Edit.Order.MoveUp="Posunout výše (&U)" +Basic.MainMenu.Edit.Order.MoveDown="Posunout níže (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="Posunout na vršek (&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="Posunout na spodek (&B)" +Basic.MainMenu.Edit.AdvAudio="Rozšířené vl&astnosti zvuku" -Basic.MainMenu.SceneCollection="&Kolekce scén" +Basic.MainMenu.SceneCollection="Kolekce &scén" Basic.MainMenu.Profile="&Profil" -Basic.MainMenu.Help="&Pomoc" +Basic.MainMenu.Help="Pomoc (&H)" Basic.MainMenu.Help.Website="Navštívit &web" -Basic.MainMenu.Help.Logs="Soubory &záznamu" -Basic.MainMenu.Help.Logs.ShowLogs="Zobrazit s&oubory záznamu" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Nahrát &aktuální soubor záznamu" -Basic.MainMenu.Help.Logs.UploadLastLog="Nahrát &poslední soubor záznamu" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Zobrazit aktuální záznam" +Basic.MainMenu.Help.Logs="Soubory záznamu (&L)" +Basic.MainMenu.Help.Logs.ShowLogs="Zobrazit soubory záznamu (&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Nahrát aktuální soubor záznamu (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Nahrát poslední soubor záznamu (&L)" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Zobrazit aktuální záznam (&V)" Basic.MainMenu.Help.CheckForUpdates="Zkontrolovat aktualizace" Basic.Settings.ProgramRestart="Pro projevení nastavení je potřeba restartovat aplikaci." @@ -282,8 +306,13 @@ Basic.Settings.Confirm="Některé změny nejsou uložené. Chcete je uložit nyn Basic.Settings.General="Hlavní" Basic.Settings.General.Theme="Vzhled" Basic.Settings.General.Language="Jazyk" -Basic.Settings.General.WarnBeforeStartingStream="Zobrazit dialog potvrzení před začátkem vysílání" -Basic.Settings.General.WarnBeforeStoppingStream="Zobrazit dialog potvrzení před ukončením vysílá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.Snapping="Přichycování zdrojů" +Basic.Settings.General.ScreenSnapping="Přichytávat zdroje k okraji obrazovky" +Basic.Settings.General.CenterSnapping="Přichytávat zdroje k vertikálnímu a horizontálnímu středu" +Basic.Settings.General.SourceSnapping="Přichytávat zdroje k ostatním zdrojům" +Basic.Settings.General.SnapDistance="Citlivost přichycení" Basic.Settings.Stream="Vysílání" Basic.Settings.Stream.StreamType="Typ vysílání" @@ -293,6 +322,7 @@ Basic.Settings.Output.Format="Formát nahrávání" 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.Mode="Režim výstupu" Basic.Settings.Output.Mode.Simple="Jednoduché" Basic.Settings.Output.Mode.Adv="Rozšířené" @@ -302,12 +332,17 @@ Basic.Settings.Output.Simple.RecordingQuality="Nahrávací kvalita" Basic.Settings.Output.Simple.RecordingQuality.Stream="Stejná jako vysílaná" Basic.Settings.Output.Simple.RecordingQuality.Small="Vysoká kvalita, střední velikost souboru" Basic.Settings.Output.Simple.RecordingQuality.HQ="Nerozeznatelný pokles kvality, velké soubory" -Basic.Settings.Output.Simple.RecordingQuality.Lossless="Bez ztrát, obrovské soubory" +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.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í: Nahrané soubory, při použití kvality \"bez ztrát\", budou enormní! Tato kvalita může využít, při vysokých rozlišeních a snímkování, až 7 GB diskového prostoru za minutu. Tato kvalita není doporučena pro dlouhé nahrávky, pokud nemáte opravdu velký volný prostor na disku." +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 ?" -Basic.Settings.Output.Simple.Warn.Lossless.Title="Varování bez ztrátové kvality!" +Basic.Settings.Output.Simple.Warn.Lossless.Title="Varování nastavené kvality!" +Basic.Settings.Output.Simple.Warn.MultipleQSV="Varování: Není možné použit více oddělených QSV enkodérů pro streamování a nahrávání ve stejnou dobu. Pokud chcete tuto limitaci obejít, tak změňte použitý enkodér pro streamování či nahrávání." Basic.Settings.Output.Simple.Encoder.Software="Softwarový (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardwarový (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardwarový (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softwarový (x264 předvolba nízkého zatížení CPU, větší soubory)" Basic.Settings.Output.VideoBitrate="Bitrate videa" Basic.Settings.Output.AudioBitrate="Bitrate zvuku" @@ -331,9 +366,11 @@ Basic.Settings.Output.Adv.Audio.Track4="Stopa 4" Basic.Settings.Output.Adv.Recording="Nahrávání" Basic.Settings.Output.Adv.Recording.Type="Typ" -Basic.Settings.Output.Adv.Recording.Type.Standard="Standrartní" +Basic.Settings.Output.Adv.Recording.Type.Standard="Standardní" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Vlastní výstup (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Použít enkodér vysílání)" +Basic.Settings.Output.Adv.Recording.Filename="Formát názvu souborů" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Přepsat existující" Basic.Settings.Output.Adv.FFmpeg.Type="Typ výstupu FFmpegu" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Výstup do URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Výstup do souboru" @@ -354,6 +391,10 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Enkodér zvuku" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Nastavení enkodéru zvuku (pokud existuje)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Nastavení směšovače (pokud existuje)" +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 Rok, 4 číslice\n%YY Rok, 2 poslední číslice (00-99)\n%MM Měsíc, číslo (01-12)\n%DD Den v měsíci, 2 číslice (01-31)\n%hh Hodina ve 24h formátu (00-23)\n%mm Minuta (00-59)\n%ss Vteřina (00-61)\n%% Znak %\n%a Zkratka dne v týdnu\n%A Den v týdnu\n%b Zkratka měsíce\n%B Měsíc\n%d Den v měsíci, 2 číslice (01-31)\n%H Hodina ve 24h formátu (00-23)\n%I Hodina ve 12h formátu (01-12)\n%m Měsíc, číslo (01-12)\n%M Minuta (00-59)\n%p AM / PM\n%S Vteřina (00-61)\n%y Rok, 2 poslední číslice (00-99)\n%Y Rok\n%z ISO 8601 časový posun od UTC nebo časového pásma\n - název nebo zkratka\n%Z Zkratka nebo název časového pásma\n" + Basic.Settings.Video="Obraz" Basic.Settings.Video.Adapter="Grafická karta:" Basic.Settings.Video.BaseResolution="Základní rozlišení:" @@ -383,9 +424,9 @@ Basic.Settings.Audio.DesktopDevice2="Zařízení zvuku plochy 2" Basic.Settings.Audio.AuxDevice="Zvukové zařízení - mikrofon/AUX" Basic.Settings.Audio.AuxDevice2="Zvukové zařízení - mikrofon/AUX 2" Basic.Settings.Audio.AuxDevice3="Zvukové zařízení - mikrofon/AUX 3" -Basic.Settings.Audio.EnablePushToMute="Povolit \"Ztlumit podržením\"" +Basic.Settings.Audio.EnablePushToMute="Povolit Ztlumit podržením" Basic.Settings.Audio.PushToMuteDelay="Zpoždění" -Basic.Settings.Audio.EnablePushToTalk="Povolit \"Naslouchat podržením\"" +Basic.Settings.Audio.EnablePushToTalk="Povolit Naslouchat podržením" Basic.Settings.Audio.PushToTalkDelay="Zpoždění" Basic.Settings.Audio.UnknownAudioDevice="[Zařízení není připojeno nebo není k dispozici]" @@ -464,5 +505,5 @@ SceneItemShow="Zobrazit '%1'" SceneItemHide="Skrýt '%1'" OutputWarnings.NoTracksSelected="Musíte vybrat alespoň jednu stopu" -OutputWarnings.MultiTrackRecording="Varování: Některé formáte (např. FLV) nepodporují více zvukových stop na nahrávku" +OutputWarnings.MultiTrackRecording="Varování: Některé formáty (např. FLV) nepodporují více zvukových stop na nahrávku" diff --git a/obs/data/locale/da-DK.ini b/obs/data/locale/da-DK.ini index b5fe6ab..7aa3e1e 100644 --- a/obs/data/locale/da-DK.ini +++ b/obs/data/locale/da-DK.ini @@ -8,6 +8,7 @@ Cancel="Annuller" Close="Luk" Save="Gem" Discard="Kassér" +Disable="Deaktiver" Yes="Ja" No="Nej" Add="Tilføj" @@ -27,6 +28,9 @@ Browse="Browse" Mono="Mono" Stereo="Stereo" DroppedFrames="Taber frames %1 (%2%)" +PreviewProjector="Fuldskærms projektering (forhåndsvisning)" +SceneProjector="Fuldskærms projektering (scene)" +SourceProjector="Fuldskærms projektering (kilde)" Clear="Ryd" Revert="Gendan" Show="Vis" @@ -34,8 +38,31 @@ Hide="Skjul" Untitled="Ikke-navngivet" New="Ny" Duplicate="Dupliker" +Enable="Slå til" +DisableOSXVSync="Deaktiver OSX V-Sync" +ResetOSXVSyncOnExit="Nulstil OSX V-Sync ved afslutning" +HighResourceUsage="Encoding overbelastet! Overvej at skrue ned for videoindstillingerne eller brug et hurtigere encoding forvalg." +Transition="Overgange" +QuickTransitions="Hurtig overgange" +Left="Venstre" +Right="Højre" +Top="Top" +Bottom="Bund" +QuickTransitions.SwapScenes="Byt om på forhåndsvisning/output scener efter overgang" +QuickTransitions.DuplicateScene="Dupliker scene" +QuickTransitions.EditProperties="Dupliker kilder" +QuickTransitions.HotkeyName="Hurtig overgang: %1" +Basic.AddTransition="Tilføj konfigurerbar overgang" +Basic.RemoveTransition="Fjern konfigurerbar overgang" +Basic.TransitionProperties="Overgangsegenskaber" +Basic.SceneTransitions="Scene overgange" +Basic.TransitionDuration="Varighed" +Basic.TogglePreviewProgramMode="Studio tilstand" + +TransitionNameDlg.Text="Indtast venligst navnet på overgangen" +TransitionNameDlg.Title="Overgangsnavn" TitleBar.Profile="Profil" TitleBar.Scenes="Scener" @@ -46,20 +73,31 @@ NameExists.Text="Navnet er allerede i brug." NoNameEntered.Title="Indtast venligst et gyldigt navn" NoNameEntered.Text="Du kan ikke bruge tomme navne." +ConfirmStart.Title="Start stream?" +ConfirmStart.Text="Er du sikker på at du ønsker at starte streamen?" +ConfirmStop.Title="Stop stream?" +ConfirmStop.Text="Er du sikker på at du ønsker at stoppe streamen?" ConfirmExit.Title="Forlad OBS?" +ConfirmExit.Text="OBS er aktiv i øjeblikket. Alle streams/optagelser vil blive lukket ned. Er du sikker på at du ønsker at afslutte?" ConfirmRemove.Title="Bekræfte fjern" ConfirmRemove.Text="Er du sikker på du ønsker at fjerne '$1'?" Output.ConnectFail.Title="Kunne ikke oprette forbindelse" -Output.ConnectFail.BadPath="Ugyldig sti eller forbindelse URL. Kontroller indstillinger for at bekræfte, at de er gyldige." +Output.ConnectFail.BadPath="Ugyldig sti eller forbindelses URL. Kontroller indstillinger for at bekræfte, at de er gyldige." Output.ConnectFail.ConnectFailed="Kunne ikke forbinde til server" -Output.ConnectFail.InvalidStream="Kunne ikke få adgang til den angivne kanal eller stream nøgle. Dette kunne være fordi nøglen/kanalen er ugyldige, eller fordi serveren stadig tror, du er logget ind." +Output.ConnectFail.InvalidStream="Kunne ikke tilgå den angivne kanel eller streamnøgle, kontroller venligst din streamnøgle. Hvis den er korrekt kan der være problemer med at forbinde til serveren." Output.ConnectFail.Error="Der opstod en uventet fejl, da du forsøgte at oprette forbindelse til serveren. Du kan finde flere oplysninger i logfilen." Output.ConnectFail.Disconnected="Afbrudt fra serveren." +Output.RecordFail.Title="Kunne ikke begynde optagelsen" +Output.RecordFail.Unsupported="Outputformatet er enten ikke understøttet eller understøtter ikke mere end ét lydspor. Tjek venligst dine indstillinger og prøv igen." +Output.RecordNoSpace.Title="Utilstrækkelig diskplads" +Output.RecordNoSpace.Msg="Der er ikke tilstrækkelig diskplads til at fortsætte optagelsen." +Output.RecordError.Title="Optagelsesfejl" +Output.RecordError.Msg="Der opstod en uangivet fejl under optagelsen." Output.BadPath.Title="Dårlig filsti" Output.BadPath.Text="Den konfigureret output sti er ugyldig. Kontroller indstillinger for at bekræfte, at en gyldig filsti er angivet." @@ -77,7 +115,6 @@ LicenseAgreement.Exit="Afslut" Remux.SourceFile="OBS optagelse" Remux.TargetFile="Destinationsfil" Remux.Remux="Remux" -Remux.RecordingPattern="OBS optagelse (*.flv)" Remux.FinishedTitle="Remuxing færdigt" Remux.Finished="Optagelse remuxed" Remux.FinishedError="Optagelse remuxed, men filen kan være ufuldstændige" @@ -103,33 +140,65 @@ Basic.DisplayCapture="Indfang display" Basic.Main.PreviewConextMenu.Enable="Aktiver visning" +Deinterlacing="Deinterlacing" +Deinterlacing.Discard="Kassér" +Deinterlacing.Retro="Retro" +Deinterlacing.Linear="Lineær" +Deinterlacing.Linear2x="Lineær 2x" + Basic.Main.AddSceneDlg.Title="Tilføje scene" Basic.Main.AddSceneDlg.Text="Angiv navnet på scene" Basic.Main.DefaultSceneName.Text="Scene %1" +Basic.Main.AddSceneCollection.Title="Tilføj scenesamling" +Basic.Main.AddSceneCollection.Text="Indtast venligst navnet på scenesamlingen" +Basic.Main.RenameSceneCollection.Title="Omdøb scenesamling" +AddProfile.Title="Tilføj profil" +AddProfile.Text="Indtast venligst profilens navn" +RenameProfile.Title="Omdøb profil" +Basic.Main.PreviewDisabled="Forhåndsvisning er i øjeblikket deaktiveret" Basic.SourceSelect="Opret/Vælg kilde" Basic.SourceSelect.CreateNew="Opret ny" Basic.SourceSelect.AddExisting="Tilføj eksisterende" +Basic.SourceSelect.AddVisible="Gør kilden synlig" Basic.PropertiesWindow="Egenskaber for '%1'" +Basic.PropertiesWindow.AutoSelectFormat="%1 (auto-vælg: %2)" Basic.PropertiesWindow.SelectColor="Vælg farve" Basic.PropertiesWindow.SelectFont="Vælg skrifttype" Basic.PropertiesWindow.ConfirmTitle="Indstillinger ændret" Basic.PropertiesWindow.Confirm="Der er ændringer, som ikke er gemt. Vil du gerne beholde dem?" Basic.PropertiesWindow.NoProperties="Ingen egenskaber tilgængelige" +Basic.PropertiesWindow.AddFiles="Tilføj filer" +Basic.PropertiesWindow.AddURL="Tilføj sti/url" +Basic.PropertiesWindow.AddEditableListFiles="Tilføj filer til '%1'" +Basic.PropertiesWindow.AddEditableListEntry="Tilføj emne til '%1'" +Basic.PropertiesWindow.EditEditableListEntry="Rediger emne fra '%1'" +Basic.PropertiesView.FPS.Simple="Simple FPS værdier" +Basic.PropertiesView.FPS.Rational="Rationelle FPS værdier" +Basic.PropertiesView.FPS.ValidFPSRanges="Gyldige FPS områder:" Basic.InteractionWindow="Interagere med '%1'" +Basic.StatusBar.Reconnecting="Afbrudt, tilslutter igen om %2 sekund(er) (forsøg %1)" +Basic.StatusBar.AttemptingReconnect="Prøver at forbinde igen... (forsøg %1)" Basic.StatusBar.ReconnectSuccessful="Gentilslutning vellykket" +Basic.StatusBar.Delay="Forsinkelse (%1 sek)" +Basic.StatusBar.DelayStartingIn="Forsinkelse (starter om %1 sek)" +Basic.StatusBar.DelayStoppingIn="Forsinkelse (stopper om %1 sek)" +Basic.StatusBar.DelayStartingStoppingIn="Forsinkelse (stopper om %1 sek, starter om %2 sek)" Basic.Filters="Filtre" +Basic.Filters.AsyncFilters="Lyd/video filtre" +Basic.Filters.AudioFilters="Lyd filter" +Basic.Filters.EffectFilters="Effektfiltre" Basic.Filters.Title="Filtre for '%1'" Basic.Filters.AddFilter.Title="Filternavn" Basic.Filters.AddFilter.Text="Angiv navnet på filteret" @@ -142,6 +211,7 @@ Basic.TransformWindow.Alignment="Positionelle justering" Basic.TransformWindow.BoundsType="Afgrænsning Rammen Boks Type" Basic.TransformWindow.BoundsAlignment="Justering i afgrænsningsområdet" Basic.TransformWindow.Bounds="Afgrænsning Rammen boksstørrelse" +Basic.TransformWindow.Crop="Beskær" Basic.TransformWindow.Alignment.TopLeft="Øverst til venstre" Basic.TransformWindow.Alignment.TopCenter="Top Center" @@ -171,6 +241,7 @@ Basic.Main.StartRecording="Start optagelse" Basic.Main.StartStreaming="Start streaming" Basic.Main.StopRecording="Stop optagelse" Basic.Main.StopStreaming="Stop streaming" +Basic.Main.ForceStopStreaming="Stop streaming (ignorer forsinkelse)" Basic.MainMenu.File="&Fil" Basic.MainMenu.File.Export="&Eksport" @@ -178,6 +249,9 @@ Basic.MainMenu.File.Import="&Import" Basic.MainMenu.File.ShowRecordings="Vis optagelse&r" Basic.MainMenu.File.Remux="Re&mux optagelser" Basic.MainMenu.File.Settings="Indstillinger (&S)" +Basic.MainMenu.File.ShowSettingsFolder="Vis indstillings-mappen" +Basic.MainMenu.File.ShowProfileFolder="Vis profil-mappe" +Basic.MainMenu.AlwaysOnTop="&Altid øverst" Basic.MainMenu.File.Exit="Afslut (&X)" Basic.MainMenu.Edit="Redigere (&E)" @@ -203,12 +277,16 @@ Basic.MainMenu.Edit.Order.MoveToTop="Flyt til &Toppen" Basic.MainMenu.Edit.Order.MoveToBottom="Flyt til &Bunden" Basic.MainMenu.Edit.AdvAudio="&Avancerede lydegenskaber" +Basic.MainMenu.SceneCollection="&Scenesamling" +Basic.MainMenu.Profile="&Profil" Basic.MainMenu.Help="&Hjælp" +Basic.MainMenu.Help.Website="Besøg &websted" Basic.MainMenu.Help.Logs="&Logfiler" Basic.MainMenu.Help.Logs.ShowLogs="Vis log-filer (&S)" Basic.MainMenu.Help.Logs.UploadCurrentLog="Upload Aktuelle logfil (&C)" Basic.MainMenu.Help.Logs.UploadLastLog="Upload Sidste logfil (&L)" +Basic.MainMenu.Help.Logs.ViewCurrentLog="&Vis aktuel logfil" Basic.MainMenu.Help.CheckForUpdates="Tjek for opdateringer" Basic.Settings.ProgramRestart="Programmet skal genstartes, før disse indstillinger træder i kraft." @@ -218,24 +296,43 @@ Basic.Settings.Confirm="Du har ugemte ændringer. Skal ændringerne gemmes?" Basic.Settings.General="Generelt" Basic.Settings.General.Theme="Tema" Basic.Settings.General.Language="Sprog" +Basic.Settings.General.WarnBeforeStartingStream="Vis bekræftelses-dialog ved opstart af stream" +Basic.Settings.General.WarnBeforeStoppingStream="Vis bekræftelses-dialog ved afslutning af stream" +Basic.Settings.General.Snapping="Kilde justeringsfastgørelse" +Basic.Settings.General.ScreenSnapping="Fastgør kilder til kanten af skærmen" +Basic.Settings.General.CenterSnapping="Fastgør kilder til horisontalt og vertikalt centrum" +Basic.Settings.General.SourceSnapping="Fastgør kilder til andre kilder" +Basic.Settings.General.SnapDistance="Fastgørings-følsomhed" Basic.Settings.Stream="Stream" -Basic.Settings.Stream.StreamType="Stream Type" +Basic.Settings.Stream.StreamType="Streamtype" Basic.Settings.Output="Output" +Basic.Settings.Output.Format="Optagelsesformat" Basic.Settings.Output.Encoder="Encoder" Basic.Settings.Output.SelectDirectory="Vælg optagelsesmappe" Basic.Settings.Output.SelectFile="Vælg optagelsesfil" -Basic.Settings.Output.Mode="Output Mode" +Basic.Settings.Output.EnforceBitrate="Håndhæv streaming service bitrate grænser" +Basic.Settings.Output.Mode="Output tilstand" Basic.Settings.Output.Mode.Simple="Simpel" Basic.Settings.Output.Mode.Adv="Avanceret" Basic.Settings.Output.Mode.FFmpeg="FFmpeg output" +Basic.Settings.Output.Simple.SavePath="Optagelsessti" +Basic.Settings.Output.Simple.RecordingQuality="Optagelseskvalitet" +Basic.Settings.Output.Simple.RecordingQuality.Stream="Samme som stream" +Basic.Settings.Output.Simple.RecordingQuality.Small="Høj kvalitet, medium filstørrelse" +Basic.Settings.Output.Simple.RecordingQuality.HQ="Samme kvalitet, stor filstørrelse" +Basic.Settings.Output.Simple.RecordingQuality.Lossless="Tabsfri kvalitet, utrolig stor filstørrelse" +Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)" Basic.Settings.Output.VideoBitrate="Video Bitrate" Basic.Settings.Output.AudioBitrate="Audio Bitrate" Basic.Settings.Output.Reconnect="Automatisk Reconnect" Basic.Settings.Output.RetryDelay="Retry forsinkelse (sekunder)" Basic.Settings.Output.MaxRetries="Maksimum forsøg" -Basic.Settings.Output.Advanced="Aktivere avancerede Encoder indstillinger" +Basic.Settings.Output.Advanced="Aktiver avancerede Encoder indstillinger" +Basic.Settings.Output.NoSpaceFileName="Opret filnavne uden mellemrum" Basic.Settings.Output.Adv.Rescale="Om-skalere output" Basic.Settings.Output.Adv.AudioTrack="Lydspor" @@ -249,13 +346,36 @@ Basic.Settings.Output.Adv.Audio.Track4="Spor 4" Basic.Settings.Output.Adv.Recording="Optagelse" Basic.Settings.Output.Adv.Recording.Type="Type" Basic.Settings.Output.Adv.Recording.Type.Standard="Standard" +Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Tilpasset output (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Brug stream encoder)" +Basic.Settings.Output.Adv.Recording.Filename="Filnavnsformatering" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Overskriv hvis filen eksisterer" +Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg outputtype" +Basic.Settings.Output.Adv.FFmpeg.Type.URL="Output til URL" +Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Output til fil" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Alle filer" Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Filsti eller URL" +Basic.Settings.Output.Adv.FFmpeg.Format="Containerformat" +Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Lyd" +Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Video" +Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Standard format" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Standard encoder" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Deaktiver encoder" +Basic.Settings.Output.Adv.FFmpeg.VEncoder="Video encoder" +Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Video encoder indstillinger (hvis nogen)" +Basic.Settings.Output.Adv.FFmpeg.AEncoder="Lyd encoder" +Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Lyd encoder indstillinger (hvis nogen)" +Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer indstillinger (hvis nogen)" + +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 år, fire cifre\n%YY år, sidste to cifre (00-99)\n%MM måned som tal (01-12)\n%DD dag i måneden, foranstillet nul (01-31)\n%hh time i 24t format (00-23)\n%mm minut (00-59)\n%ss sekund (00-61)\n%% et % tegn\n%a forkortet ugedagsnavn\n%A helt ugedagsnavn\n%b forkortet månedsnavn\n%B helt månedsnavn\n%d dag i åneden, foranstillet nul (01-31)\n%H time i 24t format (00-23)\n%I time i 12t format (01-12)\n%m måned som et tal (01-12)\n%M minut (00-59)\n%p am eller pm angivelse\n%S sekund (00-61)\n%y år, sidste to cifre (00-99)\n%Y år\n%z ISO 8601 offset fra UTC eller tidszone\n navn eller forkortelse\n%Z tidszone navn eller forkortelse\n" Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Skærmkort:" -Basic.Settings.Video.DownscaleFilter="Nedskalere Filter:" +Basic.Settings.Video.BaseResolution="Grund (lærred) opløsning:" +Basic.Settings.Video.ScaledResolution="Output (skaleret) opløsning:" +Basic.Settings.Video.DownscaleFilter="Nedskaleringsfilter:" Basic.Settings.Video.DisableAeroWindows="Deaktivere Aero (kun Windows)" Basic.Settings.Video.FPS="FPS:" Basic.Settings.Video.FPSCommon="Fælles FPS værdier" @@ -266,7 +386,11 @@ Basic.Settings.Video.Denominator="Nævneren:" Basic.Settings.Video.Renderer="Renderer:" Basic.Settings.Video.InvalidResolution="Ugyldig opløsningsværdi. Skal være [bredde] x [højde] (dvs. 1920 x 1080)" Basic.Settings.Video.CurrentlyActive="Video output er aktiv i øjeblikket. Venligst slukke eventuelle udgange til at ændre videoindstillinger." +Basic.Settings.Video.DisableAero="Deaktiver Aero" +Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (hurtigst, men sløret ved skalering)" +Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (Skarp skalering, 16 prøver)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Skarp skalering, 32 prøver)" Basic.Settings.Audio="Lyd" Basic.Settings.Audio.SampleRate="Sample Rate" @@ -276,6 +400,9 @@ Basic.Settings.Audio.DesktopDevice2="Desktop lydenhed 2" Basic.Settings.Audio.AuxDevice="Mic/Auxiliary lydenhed" Basic.Settings.Audio.AuxDevice2="Mic/Auxiliary lydenhed 2" Basic.Settings.Audio.AuxDevice3="Mic/Auxiliary lydenhed 3" +Basic.Settings.Audio.EnablePushToMute="Aktiver tryk-for-stilhed" +Basic.Settings.Audio.EnablePushToTalk="Aktiver tryk-for-tale" +Basic.Settings.Audio.UnknownAudioDevice="[Enhed ikke tilsluttet eller ikke tilgængelig]" Basic.Settings.Advanced="Avanceret" Basic.Settings.Advanced.Video.ColorFormat="Farveformat" @@ -283,6 +410,9 @@ Basic.Settings.Advanced.Video.ColorSpace="YUV farverum" Basic.Settings.Advanced.Video.ColorRange="YUV farveområde" Basic.Settings.Advanced.Video.ColorRange.Partial="Delvis" Basic.Settings.Advanced.Video.ColorRange.Full="Fuld" +Basic.Settings.Advanced.StreamDelay="Stream forsinkelse" +Basic.Settings.Advanced.StreamDelay.Duration="Varighed (sekunder)" +Basic.Settings.Advanced.StreamDelay.MemoryUsage="Anslået hukommelsesbrug: %1 MB" Basic.AdvAudio="Avancerede lydegenskaber" Basic.AdvAudio.Name="Navn" @@ -290,9 +420,56 @@ Basic.AdvAudio.Volume="Volumen (%)" Basic.AdvAudio.Panning="Panorering" Basic.AdvAudio.AudioTracks="Spor" - - - - +Basic.Settings.Hotkeys="Genvejstaster" + +Basic.Hotkeys.StartStreaming="Start streaming" +Basic.Hotkeys.StopStreaming="Stop streaming" +Basic.Hotkeys.StartRecording="Start optagelse" +Basic.Hotkeys.StopRecording="Stop optagelse" +Basic.Hotkeys.SelectScene="Skift til scene" + +Hotkeys.Insert="Insert" +Hotkeys.Delete="Delete" +Hotkeys.Home="Home" +Hotkeys.End="End" +Hotkeys.PageUp="Page up" +Hotkeys.PageDown="Page Down" +Hotkeys.NumLock="Num Lock" +Hotkeys.ScrollLock="Scroll Lock" +Hotkeys.CapsLock="Caps Lock" +Hotkeys.Backspace="Backspace" +Hotkeys.Tab="Tab" +Hotkeys.Print="Print" +Hotkeys.Pause="Pause" +Hotkeys.Left="Venstre" +Hotkeys.Right="Højre" +Hotkeys.Up="Op" +Hotkeys.Down="Ned" +Hotkeys.Windows="Windows" +Hotkeys.Super="Super" +Hotkeys.Menu="Menu" +Hotkeys.Space="Mellemrum" +Hotkeys.NumpadNum="Numerisk %1" +Hotkeys.NumpadMultiply="Numeriske tastatur gange" +Hotkeys.NumpadDivide="Numeriske tastatur dividere" +Hotkeys.NumpadAdd="Numeriske tastatur plus" +Hotkeys.NumpadSubtract="Numeriske tastatur minus" +Hotkeys.NumpadDecimal="Numeriske tastatur komma" +Hotkeys.AppleKeypadNum="%1 (numeriske tastatur)" +Hotkeys.AppleKeypadMultiply="* (numeriske tastatur)" +Hotkeys.AppleKeypadDivide="/ (numeriske tastatur)" +Hotkeys.AppleKeypadAdd="+ (numeriske tastatur)" +Hotkeys.AppleKeypadSubtract="- (numeriske tastatur)" +Hotkeys.AppleKeypadDecimal=", (numeriske tastatur)" +Hotkeys.AppleKeypadEqual="= (numeriske tastatur)" +Hotkeys.MouseButton="Mus %1" + +Mute="Lyd fra" +Unmute="Lyd til" +Push-to-mute="Tryk-for-lydløs" +Push-to-talk="Tryk-for-tale" + +SceneItemShow="Vis '%1'" +SceneItemHide="Skjul '%1'" diff --git a/obs/data/locale/de-DE.ini b/obs/data/locale/de-DE.ini index 7ead773..d251c05 100644 --- a/obs/data/locale/de-DE.ini +++ b/obs/data/locale/de-DE.ini @@ -8,6 +8,7 @@ Cancel="Abbrechen" Close="Schließen" Save="Speichern" Discard="Verwerfen" +Disable="Deaktivieren" Yes="Ja" No="Nein" Add="Hinzufügen" @@ -30,37 +31,47 @@ DroppedFrames="Verworfene Frames %1 (%2%)" PreviewProjector="Vollbild-Projektor (Vorschau)" SceneProjector="Vollbild-Projektor (Szene)" SourceProjector="Vollbild-Projektor (Quelle)" -Clear="Leeren" +Clear="Entfernen" Revert="Wiederherstellen" -Show="Zeigen" +Show="Anzeigen" Hide="Ausblenden" Untitled="Unbenannt" New="Neu" -Duplicate="Duplizieren" +Duplicate="Klonen" Enable="Aktivieren" DisableOSXVSync="OSX V-Sync deaktivieren" -ResetOSXVSyncOnExit="Zurücksetzen von OSX V-Sync beim Beenden" -HighResourceUsage="Kodierung überladet! Erwägen Sie Ihre Video-Einstellungen zu verringen, oder benutzen Sie eine schnellere Encoder-Voreinstellung." +ResetOSXVSyncOnExit="OSX V-Sync beim Beenden zurücksetzen" +HighResourceUsage="Kodierung überlastet! Erwägen Sie Ihre Video-Einstellungen zu verringern, oder benutzen Sie eine schnellere Encoder-Voreinstellung." Transition="Übergang" QuickTransitions="Schnelle Übergänge" +Left="Links" +Right="Rechts" +Top="Oben" +Bottom="Unten" -QuickTransitions.SwapScenes="Tausche Vorschau/Ausgabe-Szenen, nach dem Übergang" -QuickTransitions.SwapScenesTT="Vertauscht die Vorschau- und Ausgabe-Szenen beim Übergang (wenn die ursprüngliche Ausgabe-Szene noch vorhanden ist).\nBeachten Sie, dass dies nicht Änderungen, die in der Originalszene der Ausgabe vorgenommen wurden, rückgängig machen wird." +QuickTransitions.SwapScenes="Tausche Vorschau/Ausgabe-Szenen nach dem Übergang" +QuickTransitions.SwapScenesTT="Vertauscht die Vorschau- und Ausgabe-Szenen nach dem Übergang (falls die ursprüngliche Ausgabe-Szene noch vorhanden ist).\nEventuelle Änderungen an der original Ausgabe-Szene werden hierbei nicht rückgängig gemacht." QuickTransitions.DuplicateScene="Dupliziere Szene" -QuickTransitions.DuplicateSceneTT="Ermöglicht das bearbeiten von Transformation/Sichtbarkeit von Quellen, ohne die Ausgabe zu verändern, wenn dieselbe Szene bearbeitet wird.\nUm die Eigenschaften von Quellen zu bearbeiten, ohne die Ausgabe zu verändern, aktivieren Sie 'Dupliziere Quellen'.\nDas ändern dieses Wertes, wird die derzeitige Ausgabe-Szene zurücksetzen (falls sie noch existiert)." +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 'Dupliziere Szene' um die Eigenschaften von Quellen zu bearbeiten, ohne die Ausgabe zu verändern.\nDas Ändern dieses Wertes wird die derzeitige Ausgabe-Szene zurücksetzen (falls sie noch existiert)." QuickTransitions.EditProperties="Dupliziere Quellen" -QuickTransitions.EditPropertiesTT="Ermöglicht das bearbeiten der Eigenschaften von Quellen, ohne die Ausgabe zu verändern, wenn dieselbe Szene bearbeitet wird.\nDies kann nur benutzt werden, wenn 'Dupliziere Szene' aktiviert ist.\nBestimmte Quellen (wie Aufnahme- oder Medienquellen) unterstützen dies nicht und können nicht separat bearbeitet werden.\n Das ändern dieses Wertes, wird die derzeitige Ausgabe-Szene zurücksetzen (falls sie noch existiert).\n\nWarnung: Da Quellen dupliziert werden, könnte dies zusätzliche System- oder Videoresourcen 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 'Dupliziere Szene' aktiviert ist.\nBestimmte Quellen (wie Aufnahme- oder Medienquellen) unterstützen dies nicht und können nicht separat bearbeitet werden.\n Das Ändern dieses Wertes wird die derzeitige Ausgabe-Szene zurücksetzen (falls sie noch existiert).\n\nWarnung: Da Quellen dupliziert werden, könnte dies zusätzliche System- oder Videoressourcen verbrauchen." QuickTransitions.HotkeyName="Schneller Übergang: %1" +Basic.AddTransition="Konfigurierbaren Übergang hinzufügen" +Basic.RemoveTransition="Konfigurierbaren Übergang entfernen" +Basic.TransitionProperties="Übergangseigenschaften" Basic.SceneTransitions="Szenenübergänge" Basic.TransitionDuration="Dauer" Basic.TogglePreviewProgramMode="Studio-Modus" +TransitionNameDlg.Text="Bitte geben Sie den Namen des Übergangs ein" +TransitionNameDlg.Title="Übergangsname" + TitleBar.Profile="Profil" TitleBar.Scenes="Szenen" NameExists.Title="Name existiert bereits" -NameExists.Text="Name wird bereits verwendet." +NameExists.Text="Dieser Name wird bereits verwendet." NoNameEntered.Title="Bitte geben Sie einen gültigen Namen ein" NoNameEntered.Text="Sie können leere Namen nicht verwenden." @@ -72,15 +83,15 @@ ConfirmStop.Title="Stream stoppen?" ConfirmStop.Text="Sind Sie sicher, dass Sie den Stream beenden möchten?" ConfirmExit.Title="OBS beenden?" -ConfirmExit.Text="OBS ist derzeit aktiv. Alle Streams/Aufnahmen werden heruntergefahren. Sind Sie sicher, dass Sie OBS beenden möchten?" +ConfirmExit.Text="OBS ist derzeit aktiv. Alle Streams/Aufnahmen werden beendet. Sind Sie sicher, dass Sie OBS beenden möchten?" ConfirmRemove.Title="Entfernen bestätigen" ConfirmRemove.Text="Sind Sie sicher, dass Sie '$1' entfernen möchten?" 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 sie gültig 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 auf den angegebenen Kanal oder Streamschlüssel nicht zugreifen. Dies kann daran liegen, dass der Schlüssel oder Kanal ungültig ist, oder der Server noch denkt, dass Sie angemeldet sind." +Output.ConnectFail.InvalidStream="Konnte nicht auf den angegebenen Kanal oder Stream-Key zugreifen. Bitte überprüfen Sie den eingegebenen Stream-Key. 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 Logdatei." Output.ConnectFail.Disconnected="Verbindung zum Server getrennt." @@ -89,7 +100,7 @@ Output.RecordFail.Unsupported="Das Ausgabeformat wird entweder nicht unterstütz Output.RecordNoSpace.Title="Nicht genügend Speicherplatz" Output.RecordNoSpace.Msg="Es gibt nicht genügend Speicherplatz, um die Aufnahme fortzusetzen." Output.RecordError.Title="Aufnahmefehler" -Output.RecordError.Msg="Ein unbekannter Fehler ist aufgetreten, während der Aufnahme." +Output.RecordError.Msg="Während der Aufnahme ist ein unbekannter Fehler aufgetreten." 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." @@ -99,7 +110,7 @@ LogReturnDialog.CopyURL="URL kopieren" LogReturnDialog.ErrorUploadingLog="Fehler beim Upload der Logdatei" LicenseAgreement="Lizenzvereinbarung" -LicenseAgreement.PleaseReview="Bitte lesen Sie die Lizenzbedingungen vor der Verwendung von OBS. Mit dem verwenden dieses Programms, bestätigen Sie, dass Sie diese gelesen haben und den Bedingungen der GNU General Public License v2.0 zustimmen. Bitte scrollen Sie nach unten, um den Rest der Vereinbarung zu sehen." +LicenseAgreement.PleaseReview="Bitte lesen Sie die Lizenzbedingungen vor der Verwendung von OBS. Mit der Verwendung dieses Programms bestätigen Sie, dass Sie diese gelesen haben und den Bedingungen der GNU General Public License v2.0 zustimmen. Bitte scrollen Sie nach unten, um den Rest der Vereinbarung zu sehen." LicenseAgreement.ClickIAgreeToContinue="Wenn Sie die Vereinbarung akzeptieren, klicken Sie auf ich stimme zu, um fortzufahren. Sie müssen akzeptieren, um OBS verwenden zu können." LicenseAgreement.IAgree="Ich stimme zu" LicenseAgreement.Exit="Beenden" @@ -107,10 +118,10 @@ LicenseAgreement.Exit="Beenden" Remux.SourceFile="OBS Aufnahme" Remux.TargetFile="Zieldatei" Remux.Remux="Remuxen" -Remux.RecordingPattern="OBS Aufnahme (*.flv)" +Remux.OBSRecording="OBS Aufnahme" Remux.FinishedTitle="Remuxen beendet" Remux.Finished="Aufnahme remuxed" -Remux.FinishedError="Aufnahme remuxed, aber die Datei kann unvollständig sein" +Remux.FinishedError="Aufnahme remuxed, aber die Datei könnte unvollständig sein" Remux.SelectRecording="Wählen Sie die OBS Aufnahme aus …" Remux.SelectTarget="Wähle Zieldatei …" Remux.FileExistsTitle="Zieldatei ist bereits vorhanden" @@ -133,6 +144,18 @@ Basic.DisplayCapture="Monitoraufnahme" Basic.Main.PreviewConextMenu.Enable="Vorschau aktivieren" +Deinterlacing="Zeilenentflechtung (Deinterlacing)" +Deinterlacing.Discard="Verwerfen" +Deinterlacing.Retro="Retro" +Deinterlacing.Blend="Blend" +Deinterlacing.Blend2x="Blend 2x" +Deinterlacing.Linear="Linear" +Deinterlacing.Linear2x="Linear 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Oberes Feld zuerst" +Deinterlacing.BottomFieldFirst="Unteres Feld zuerst" + Basic.Main.AddSceneDlg.Title="Szene hinzufügen" Basic.Main.AddSceneDlg.Text="Bitte geben Sie einen Namen für die Szene ein" @@ -155,7 +178,7 @@ Basic.SourceSelect.CreateNew="Neu erstellen" Basic.SourceSelect.AddExisting="Existierende hinzufügen" Basic.SourceSelect.AddVisible="Quelle sichtbar machen" -Basic.PropertiesWindow="Eigenschaften für '%1'" +Basic.PropertiesWindow="Eigenschaften von '%1'" Basic.PropertiesWindow.AutoSelectFormat="%1 (automatisch ausgewählt: %2)" Basic.PropertiesWindow.SelectColor="Farbe auswählen" Basic.PropertiesWindow.SelectFont="Schriftart auswählen" @@ -176,7 +199,7 @@ Basic.InteractionWindow="Interagiere mit '%1'" Basic.StatusBar.Reconnecting="Verbindung getrennt; Verbindungsversuch %1 in %2 Sekunde(n)" Basic.StatusBar.AttemptingReconnect="Versuche die Verbindung wiederherzustellen ... (Versuch %1)" -Basic.StatusBar.ReconnectSuccessful="Wiederverbindung erfolgreich" +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)" @@ -194,10 +217,11 @@ Basic.TransformWindow="Szenen-Element-Transformation" Basic.TransformWindow.Position="Position" Basic.TransformWindow.Rotation="Drehung" Basic.TransformWindow.Size="Größe" -Basic.TransformWindow.Alignment="Positionelle Ausrichtung" +Basic.TransformWindow.Alignment="Ausrichtung" Basic.TransformWindow.BoundsType="Bounding Box Typ" Basic.TransformWindow.BoundsAlignment="Ausrichtung in Bounding Box" Basic.TransformWindow.Bounds="BoundingBox Größe" +Basic.TransformWindow.Crop="Zuschneiden" Basic.TransformWindow.Alignment.TopLeft="Oben links" Basic.TransformWindow.Alignment.TopCenter="Oben in der Mitte" @@ -227,7 +251,7 @@ Basic.Main.StartRecording="Aufnahme starten" Basic.Main.StartStreaming="Streaming starten" Basic.Main.StopRecording="Aufnahme stoppen" Basic.Main.StopStreaming="Streaming stoppen" -Basic.Main.ForceStopStreaming="Streaming stoppen (verwerfe Verzögerung)" +Basic.Main.ForceStopStreaming="Streaming stoppen (Verzögerung verwerfen)" Basic.MainMenu.File="Datei (&F)" Basic.MainMenu.File.Export="&Exportieren" @@ -284,6 +308,11 @@ Basic.Settings.General.Theme="Motiv" Basic.Settings.General.Language="Sprache" Basic.Settings.General.WarnBeforeStartingStream="Bestätigungsdialog beim Streamstart anzeigen" Basic.Settings.General.WarnBeforeStoppingStream="Bestätigungsdialog beim Streamstop anzeigen" +Basic.Settings.General.Snapping="Quellenausrichtung" +Basic.Settings.General.ScreenSnapping="Quellen am Bildschirmrand ausrichten" +Basic.Settings.General.CenterSnapping="Quellen zur horizontalen und vertikalen Mitte ausrichten" +Basic.Settings.General.SourceSnapping="Quellen an anderen Quellen ausrichten" +Basic.Settings.General.SnapDistance="Ausrichtungsempfindlichkeit" Basic.Settings.Stream="Stream" Basic.Settings.Stream.StreamType="Stream Typ" @@ -293,6 +322,7 @@ Basic.Settings.Output.Format="Aufnahmeformat" Basic.Settings.Output.Encoder="Encoder" Basic.Settings.Output.SelectDirectory="Wählen Sie das Aufnahmeverzeichnis" Basic.Settings.Output.SelectFile="Wählen Sie die Aufnahmedatei" +Basic.Settings.Output.EnforceBitrate="Erzwinge Bitratenlimit des Streamingdiensts" Basic.Settings.Output.Mode="Ausgabemodus" Basic.Settings.Output.Mode.Simple="Einfach" Basic.Settings.Output.Mode.Adv="Erweitert" @@ -303,18 +333,23 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Gleiche 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.Encoder="Achtung: Aufnahmen mit einem Software-Encoder mit einer anderen Qualität als der Stream, wird zusätzliche CPU-Auslastung erfordern, wenn Sie gleichzeitig streamen und aufzeichnen." -Basic.Settings.Output.Simple.Warn.Lossless="Warnung: Verlustfreie Qualität erzeugt enorm großen Dateigrößen! 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.VideoBitrate="Warnung: Die Videobitrate beim streamen wird auf %1 festlegt, was der Obergrenze des aktuellen Streamingdiensts entspricht. Falls Sie sicher sind, dass Sie %1 überschreiten wollen, deaktivieren Sie \"Erzwinge Bitratenlimit des Streamingdiensts\" in den erweiterten Encodereinstellungen." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Warnung: Die Audiobitrate beim streamen wird auf %1 festlegt, was der Obergrenze des aktuellen Streamingdiensts entspricht. Falls Sie sicher sind, dass Sie %1 überschreiten wollen, deaktivieren Sie \"Erzwinge Bitratenlimit des Streamingdiensts\" in den erweiterten Encodereinstellungen." +Basic.Settings.Output.Simple.Warn.Encoder="Warnung: Mit einem Software-Encoder in einer anderen Qualität als der des Stream aufzunehmen wird zusätzliche CPU-Auslastung erzeugen, wenn Sie gleichzeitig streamen und aufzeichnen." +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.Lossless.Msg="Sind Sie sicher, dass Sie verlustfreie Qualität verwenden möchten?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Verlustfreie Qualität-Warnung!" +Basic.Settings.Output.Simple.Warn.MultipleQSV="Achtung: Sie können nicht mehrere separate QSV-Encoder beim streamen und aufnehmen gleichzeitig verwenden. Wenn Sie zur gleichen Zeit streamen und aufnehmen möchten, dann ändern Sie bitte entweder den Aufnahme-Encoder oder den Stream-Encoder." Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 niedrige CPU-Auslastung Voreinstellung, erhöht die Dateigröße)" -Basic.Settings.Output.VideoBitrate="Video-Bitrate" -Basic.Settings.Output.AudioBitrate="Audio-Bitrate" +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.MaxRetries="Maximale Wiederholungsversuche" -Basic.Settings.Output.Advanced="Erweiterte Encoder-Einstellungen aktivieren" +Basic.Settings.Output.Advanced="Erweiterte Encodereinstellungen aktivieren" Basic.Settings.Output.EncoderPreset="Encoder-Voreinstellung (höher = weniger CPU Auslastung)" Basic.Settings.Output.CustomEncoderSettings="Benutzerdefinierte Encoder-Einstellungen" Basic.Settings.Output.CustomMuxerSettings="Benutzerdefinierte Muxereinstellungen" @@ -334,6 +369,8 @@ 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="(Benutze Streamencoder)" +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.FFmpeg.Type.URL="Ausgabe zu URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Ausgabe in Datei" @@ -354,11 +391,15 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audio-Encoder" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audio Encoder-Einstellungen (falls gewünscht)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer Einstellungen (falls vorhanden)" +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" + +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 AM oder PM 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 Name oder Abkürzung\n%Z Zeitzonenname oder Abkürzung\n" + Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Grafikkarte:" Basic.Settings.Video.BaseResolution="Basis (Leinwand) Auflösung:" Basic.Settings.Video.ScaledResolution="Ausgabe (skaliert) Auflösung:" -Basic.Settings.Video.DownscaleFilter="Skalierungs Filter:" +Basic.Settings.Video.DownscaleFilter="Skalierungs-Filter:" Basic.Settings.Video.DisableAeroWindows="Aero deaktivieren (nur Windows)" Basic.Settings.Video.FPS="FPS:" Basic.Settings.Video.FPSCommon="Übliche FPS Werte" @@ -395,7 +436,7 @@ Basic.Settings.Advanced.Audio.BufferingTime="Audio Pufferungszeit" Basic.Settings.Advanced.Video.ColorFormat="Farbformat" Basic.Settings.Advanced.Video.ColorSpace="YUV-Farbmatrix" Basic.Settings.Advanced.Video.ColorRange="YUV Farbbereich" -Basic.Settings.Advanced.Video.ColorRange.Partial="Teilweise" +Basic.Settings.Advanced.Video.ColorRange.Partial="Begrenzt" Basic.Settings.Advanced.Video.ColorRange.Full="Voll" Basic.Settings.Advanced.StreamDelay="Stream-Verzögerung" Basic.Settings.Advanced.StreamDelay.Duration="Dauer (Sekunden)" diff --git a/obs/data/locale/el-GR.ini b/obs/data/locale/el-GR.ini index 1fe84f0..26b041c 100644 --- a/obs/data/locale/el-GR.ini +++ b/obs/data/locale/el-GR.ini @@ -34,9 +34,16 @@ Clear="Καθαρισμός" Revert="Επαναφορά" Show="Εμφάνιση" Hide="Απόκρυψη" +Untitled="Χωρίς όνομα" New="Νέο" +Duplicate="Διπλότυπη εγγραφή" +Enable="Ενεργοποίηση" +DisableOSXVSync="Απενεργοποίηση OSX V-Sync" +Basic.TransitionDuration="Διάρκεια" +Basic.TogglePreviewProgramMode="Λειτουργία στούντιο" + TitleBar.Profile="Προφίλ" TitleBar.Scenes="Σκηνές" @@ -57,7 +64,6 @@ ConfirmRemove.Text="Είστε βέβαιοι ότι θέλετε να κατα Output.ConnectFail.Title="Η σύνδεση απέτυχε" Output.ConnectFail.BadPath="Μη έγκυρη Διαδρομή ή URL Σύνδεσης. Παρακαλώ ελέγξτε τις ρυθμίσεις σας και επιβεβαιώστε ότι είναι έγκυρες." Output.ConnectFail.ConnectFailed="Απέτυχε η σύνδεση στον διακομιστή" -Output.ConnectFail.InvalidStream="Δεν ήταν δυνατή η πρόσβαση στο συγκεκριμένο κανάλι ή το κλειδί μετάδοσης. Αυτό ίσως συνέβη διότι το κλειδί/κανάλη δεν είναι έγκυρα, ή επειδή ο διακομιστής πιστέυει ότι είστε ακόμα συνδεμένος." Output.ConnectFail.Error="Παρουσιάστηκε μη αναμενόμενο σφάλμα κατα την προσπάθεια σύνδεσης με τον διακομιστή. Περισσότερες πληροφορίες στο αρχείο καταγραφής." Output.ConnectFail.Disconnected="Αποσυνδεθήκατε από τον διακομιστή." @@ -80,7 +86,6 @@ LicenseAgreement.Exit="Έξοδος" Remux.SourceFile="OBS Καταγραφή" Remux.TargetFile="Αρχείο Προορισμού" Remux.Remux="Μετατροπή" -Remux.RecordingPattern="OBS Καταγραφή (*.flv)" Remux.FinishedTitle="Η μετατροπή τελείωσε" Remux.Finished="Η καταγραφή μετατράπηκε" Remux.FinishedError="Η καταγραφή μετατράπηκε, άλλα ενδέχεται το αρχείο να είναι ελλιπής" @@ -106,6 +111,7 @@ Basic.DisplayCapture="Σύλληψη Οθόνης" Basic.Main.PreviewConextMenu.Enable="Ενεργοποίηση Προεπισκόπησης" + Basic.Main.AddSceneDlg.Title="Προσθήκη Σκηνής" Basic.Main.AddSceneDlg.Text="Παρακαλώ εισάγετε το όνομα της σκηνής" @@ -257,6 +263,7 @@ Basic.Settings.Output.Mode.Simple="Απλό" Basic.Settings.Output.Mode.Adv="Σύνθετες επιλογές" Basic.Settings.Output.Mode.FFmpeg="Έξοδος FFmpeg" Basic.Settings.Output.Simple.SavePath="Διαδρομή Καταγραφής" +Basic.Settings.Output.Simple.Encoder.Software="Λογισμικό (x264)" Basic.Settings.Output.VideoBitrate="Ρυθμός Bit του Βίντεο" Basic.Settings.Output.AudioBitrate="Ρυθμός Bit του Ήχου" Basic.Settings.Output.Reconnect="Αυτόματη Επανασύνδεση" @@ -280,6 +287,7 @@ 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.FFmpeg.Type.URL="Έξοδος σε διεύθυνση URL" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Κοινή μορφές εγγραφής" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Όλα τα αρχεία" Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Διαδρομή αρχείου ή URL" @@ -296,6 +304,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Ρυθμίσεις Κωδικ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Κωδικοποιητής Ήχου" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Ρυθμίσεις Κωδικοποιητή Ήχου (αν υπάρχουν)" + + Basic.Settings.Video="Βίντεο" Basic.Settings.Video.Adapter="Προσαρμογέας Βίντεο:" Basic.Settings.Video.DownscaleFilter="Φίλτρο Σμίκρυνσης:" diff --git a/obs/data/locale/en-US.ini b/obs/data/locale/en-US.ini index 014035d..90cb492 100644 --- a/obs/data/locale/en-US.ini +++ b/obs/data/locale/en-US.ini @@ -13,6 +13,7 @@ Cancel="Cancel" Close="Close" Save="Save" Discard="Discard" +Disable="Disable" Yes="Yes" No="No" Add="Add" @@ -48,6 +49,10 @@ ResetOSXVSyncOnExit="Reset OSX V-Sync on Exit" HighResourceUsage="Encoding overloaded! Consider turning down video settings or using a faster encoding preset." Transition="Transition" QuickTransitions="Quick Transitions" +Left="Left" +Right="Right" +Top="Top" +Bottom="Bottom" # quick transitions QuickTransitions.SwapScenes="Swap Preview/Output Scenes After Transitioning" @@ -59,10 +64,17 @@ QuickTransitions.EditPropertiesTT="When editing the same scene, allows editing p QuickTransitions.HotkeyName="Quick Transition: %1" # transitions +Basic.AddTransition="Add Configurable Transition" +Basic.RemoveTransition="Remove Configurable Transition" +Basic.TransitionProperties="Transition Properties" Basic.SceneTransitions="Scene Transitions" Basic.TransitionDuration="Duration" Basic.TogglePreviewProgramMode="Studio Mode" +# transition name dialog +TransitionNameDlg.Text="Please enter the name of the transition" +TransitionNameDlg.Title="Transition Name" + # title bar strings TitleBar.Profile="Profile" TitleBar.Scenes="Scenes" @@ -94,7 +106,7 @@ ConfirmRemove.Text="Are you sure you wish to remove '$1'?" Output.ConnectFail.Title="Failed to connect" Output.ConnectFail.BadPath="Invalid Path or Connection URL. Please check your settings to confirm that they are valid." Output.ConnectFail.ConnectFailed="Failed to connect to server" -Output.ConnectFail.InvalidStream="Could not access the specified channel or stream key. This could be because the key/channel is invalid, or because the server still thinks you are logged in." +Output.ConnectFail.InvalidStream="Could not access the specified channel or stream key, please double-check your stream key. If it is correct, there may be a problem connecting to the server." Output.ConnectFail.Error="An unexpected error occurred when trying to connect to the server. More information in the log file." Output.ConnectFail.Disconnected="Disconnected from server." @@ -126,7 +138,7 @@ LicenseAgreement.Exit="Exit" Remux.SourceFile="OBS Recording" Remux.TargetFile="Target File" Remux.Remux="Remux" -Remux.RecordingPattern="OBS Recording (*.flv)" +Remux.OBSRecording="OBS Recording" Remux.FinishedTitle="Remuxing finished" Remux.Finished="Recording remuxed" Remux.FinishedError="Recording remuxed, but the file may be incomplete" @@ -156,6 +168,19 @@ Basic.DisplayCapture="Display Capture" # display context menu Basic.Main.PreviewConextMenu.Enable="Enable Preview" +# deinterlacing +Deinterlacing="Deinterlacing" +Deinterlacing.Discard="Discard" +Deinterlacing.Retro="Retro" +Deinterlacing.Blend="Blend" +Deinterlacing.Blend2x="Blend 2x" +Deinterlacing.Linear="Linear" +Deinterlacing.Linear2x="Linear 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Top Field First" +Deinterlacing.BottomFieldFirst="Bottom Field First" + # add scene dialog Basic.Main.AddSceneDlg.Title="Add Scene" Basic.Main.AddSceneDlg.Text="Please enter the name of the scene" @@ -235,6 +260,7 @@ Basic.TransformWindow.Alignment="Positional Alignment" Basic.TransformWindow.BoundsType="Bounding Box Type" Basic.TransformWindow.BoundsAlignment="Alignment in Bounding Box" Basic.TransformWindow.Bounds="Bounding Box Size" +Basic.TransformWindow.Crop="Crop" Basic.TransformWindow.Alignment.TopLeft="Top Left" Basic.TransformWindow.Alignment.TopCenter="Top Center" @@ -329,6 +355,11 @@ Basic.Settings.General.Theme="Theme" Basic.Settings.General.Language="Language" Basic.Settings.General.WarnBeforeStartingStream="Show confirmation dialog when starting streams" Basic.Settings.General.WarnBeforeStoppingStream="Show confirmation dialog when stopping streams" +Basic.Settings.General.Snapping="Source Alignment Snapping" +Basic.Settings.General.ScreenSnapping="Snap Sources to edge of screen" +Basic.Settings.General.CenterSnapping="Snap Sources to horizontal and vertical center" +Basic.Settings.General.SourceSnapping="Snap Sources to other sources" +Basic.Settings.General.SnapDistance="Snap Sensitivity" # basic mode 'stream' settings Basic.Settings.Stream="Stream" @@ -340,6 +371,7 @@ Basic.Settings.Output.Format="Recording Format" 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.Mode="Output Mode" Basic.Settings.Output.Mode.Simple="Simple" Basic.Settings.Output.Mode.Adv="Advanced" @@ -350,11 +382,16 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Same as stream" Basic.Settings.Output.Simple.RecordingQuality.Small="High Quality, Medium File Size" Basic.Settings.Output.Simple.RecordingQuality.HQ="Indistinguishable Quality, Large File Size" 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.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?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Lossless quality warning!" +Basic.Settings.Output.Simple.Warn.MultipleQSV="Warning: You cannot use multiple separate QSV encoders when streaming and recording at the same time. If you want to stream and record at the same time, please change either the recording encoder or the stream encoder." Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 low CPU usage preset, increases file size)" Basic.Settings.Output.VideoBitrate="Video Bitrate" Basic.Settings.Output.AudioBitrate="Audio Bitrate" @@ -383,6 +420,8 @@ Basic.Settings.Output.Adv.Recording.Type="Type" Basic.Settings.Output.Adv.Recording.Type.Standard="Standard" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Custom Output (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Use stream encoder)" +Basic.Settings.Output.Adv.Recording.Filename="Filename Formatting" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Overwrite if file exists" Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg Output Type" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Output to URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Output to File" @@ -403,6 +442,12 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audio Encoder" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audio Encoder Settings (if any)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer Settings (if any)" +# basic mode 'output' settings - advanced section - recording subsection - completer +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" + +# basic mode 'output' settings - advanced section - recording subsection - TT +FilenameFormatting.TT="%CCYY Year, four digits\n%YY Year, last two digits (00-99)\n%MM Month as a decimal number (01-12)\n%DD Day of the month, zero-padded (01-31)\n%hh Hour in 24h format (00-23)\n%mm Minute (00-59)\n%ss Second (00-61)\n%% A % sign\n%a Abbreviated weekday name\n%A Full weekday name\n%b Abbreviated month name\n%B Full month name\n%d Day of the month, zero-padded (01-31)\n%H Hour in 24h format (00-23)\n%I Hour in 12h format (01-12)\n%m Month as a decimal number (01-12)\n%M Minute (00-59)\n%p AM or PM designation\n%S Second (00-61)\n%y Year, last two digits (00-99)\n%Y Year\n%z ISO 8601 offset from UTC or timezone\n name or abbreviation\n%Z Timezone name or abbreviation\n" + # basic mode 'video' settings Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Video Adapter:" diff --git a/obs/data/locale/es-ES.ini b/obs/data/locale/es-ES.ini index 9924841..eb8d5c7 100644 --- a/obs/data/locale/es-ES.ini +++ b/obs/data/locale/es-ES.ini @@ -8,6 +8,7 @@ Cancel="Cancelar" Close="Cerrar" Save="Grabar" Discard="Descartar" +Disable="Deshabilitar" Yes="Sí" No="No" Add="Agregar" @@ -43,6 +44,10 @@ ResetOSXVSyncOnExit="Resetear V-Sync de OSX a la salida" HighResourceUsage="¡Sobrecarga al codificar! Considera bajar los ajustes de vídeo o usa una configuración del codificador mas rapida." Transition="Transición" QuickTransitions="Transiciones rápidas" +Left="Izquierda" +Right="Derecha" +Top="Arriba" +Bottom="Abajo" QuickTransitions.SwapScenes="Cambiar vista previa y salida escenas después de la transición" QuickTransitions.SwapScenesTT="Cambia la vista previa y salida escenas después de la transición (si todavía existe la escena original de la salida). \nEsto no deshará cualquier cambio que pueda haber hecho a la escena original de la salida." @@ -52,10 +57,16 @@ QuickTransitions.EditProperties="Duplicar fuentes" QuickTransitions.EditPropertiesTT="Al editar la misma escena, permite editar propiedades de fuentes sin modificar la salida. \n Esto sólo se puede utilizar si está activado 'Escena de duplicar'. \nCiertas fuentes (tales como fuentes de captura o los medios de comunicación) no son compatibles con esto y no se pueden editar por separado. \nCambiando este valor restablecerá la escena actual de salida (si todavía existe).\n\nAdvertencia: porque se duplicarán las fuentes, esto puede requerir extra sistema o recursos de vídeo." QuickTransitions.HotkeyName="Transición Rápida: %1" +Basic.AddTransition="Añadir transición configurable" +Basic.RemoveTransition="Quitar transición configurable" +Basic.TransitionProperties="Propiedades de la transición" Basic.SceneTransitions="Transiciones de escena" Basic.TransitionDuration="Duración" Basic.TogglePreviewProgramMode="Modo de estudio" +TransitionNameDlg.Text="Por favor, introduzca el nombre de la transición" +TransitionNameDlg.Title="Nombre de la transición" + TitleBar.Profile="Perfíl" TitleBar.Scenes="Escenas" @@ -68,7 +79,7 @@ NoNameEntered.Text="No puede utilizar nombres de vacíos." ConfirmStart.Title="¿Iniciar Transmisión?" ConfirmStart.Text="¿Está seguro que desea iniciar la transmisión?" -ConfirmStop.Title="¿Parar la Transmisión?" +ConfirmStop.Title="¿Parar Transmisión?" ConfirmStop.Text="¿Está seguro que desea parar la transmisión?" ConfirmExit.Title="¿Cerrar OBS?" @@ -80,7 +91,7 @@ ConfirmRemove.Text="¿Seguro que desea eliminar '$1'?" 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." Output.ConnectFail.ConnectFailed="No se pudo conectar al servidor" -Output.ConnectFail.InvalidStream="No se pudo acceder al canal o flujo encriptado. Esto podría deberse a que el canal o la clave no son válidos, o porque el servidor piensa que todavía tienes una sesión iniciada." +Output.ConnectFail.InvalidStream="No puede acceder a la llave del canal especificado o de la trasmisión, por favor comprobar dos veces su llave de trasmisión. Si es correcto, puede haber un problema conectándose al servidor." Output.ConnectFail.Error="Se ha producido un error inesperado al intentar conectar con el servidor. Más información en el archivo de registro." Output.ConnectFail.Disconnected="Desconectado del servidor." @@ -107,7 +118,7 @@ LicenseAgreement.Exit="Salir" Remux.SourceFile="Grabación OBS" Remux.TargetFile="Archivo de destino" Remux.Remux="Convertir" -Remux.RecordingPattern="OBS grabación (*.flv)" +Remux.OBSRecording="Grabación OBS" Remux.FinishedTitle="Conversión finalizada" Remux.Finished="Grabando conversión" Remux.FinishedError="Grabación convertida, pero el archivo podría estar incompleto" @@ -133,6 +144,18 @@ Basic.DisplayCapture="Captura de pantalla" Basic.Main.PreviewConextMenu.Enable="Habilitar previsualización" +Deinterlacing="Desentrelazado" +Deinterlacing.Discard="Descartar" +Deinterlacing.Retro="Retro" +Deinterlacing.Blend="Mezclado" +Deinterlacing.Blend2x="Mezclado 2x" +Deinterlacing.Linear="Lineal" +Deinterlacing.Linear2x="Lineal 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Campo Superior Primero" +Deinterlacing.BottomFieldFirst="Campo Inferior Primero" + Basic.Main.AddSceneDlg.Title="Añadir escena" Basic.Main.AddSceneDlg.Text="Por favor, introduzca el nombre de la escena" @@ -198,6 +221,7 @@ Basic.TransformWindow.Alignment="Alineamiento posicional" Basic.TransformWindow.BoundsType="Tipo de cuadro delimitador" Basic.TransformWindow.BoundsAlignment="Alineamiento en el cuadro delimitador" Basic.TransformWindow.Bounds="Tamaño de cuadro delimitador" +Basic.TransformWindow.Crop="Recorte" Basic.TransformWindow.Alignment.TopLeft="Parte superior izquierda" Basic.TransformWindow.Alignment.TopCenter="Parte superior central" @@ -224,10 +248,10 @@ Basic.Main.Scenes="Escenas" Basic.Main.Sources="Fuentes" Basic.Main.Connecting="Conectando..." Basic.Main.StartRecording="Iniciar grabación" -Basic.Main.StartStreaming="Iniciar retransmisión" +Basic.Main.StartStreaming="Iniciar Transmisión" Basic.Main.StopRecording="Detener grabación" -Basic.Main.StopStreaming="Detener retransmisión" -Basic.Main.ForceStopStreaming="Parar transmisión (descartar retraso)" +Basic.Main.StopStreaming="Detener Transmisión" +Basic.Main.ForceStopStreaming="Parar Transmisión (descartar retraso)" Basic.MainMenu.File="&Archivo" Basic.MainMenu.File.Export="&Exportar" @@ -284,30 +308,41 @@ Basic.Settings.General.Theme="Tema" Basic.Settings.General.Language="Idioma" 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.Snapping="Ajuste de alineación de la fuente" +Basic.Settings.General.ScreenSnapping="Ajustar las fuentes al borde de la pantalla" +Basic.Settings.General.CenterSnapping="Ajustar las fuentes al centro horizontal y vertical" +Basic.Settings.General.SourceSnapping="Ajustar las fuentes a otras fuentes" +Basic.Settings.General.SnapDistance="Ajustar la sensibilidad" -Basic.Settings.Stream="Flujo" -Basic.Settings.Stream.StreamType="Tipo de flujo" +Basic.Settings.Stream="Emision" +Basic.Settings.Stream.StreamType="Tipo de Emision" Basic.Settings.Output="Salida" Basic.Settings.Output.Format="Formato de grabación" 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="Forzar limites de bitrate en el servicio de streaming" 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.Simple.SavePath="Ruta de grabación" Basic.Settings.Output.Simple.RecordingQuality="Calidad de grabación" -Basic.Settings.Output.Simple.RecordingQuality.Stream="Igual a la entrada" +Basic.Settings.Output.Simple.RecordingQuality.Stream="Igual a la emision" Basic.Settings.Output.Simple.RecordingQuality.Small="Alta calidad, tamaño de archivo medio" Basic.Settings.Output.Simple.RecordingQuality.HQ="Tamaño de archivo grande, calidad indistinguible" 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.Encoder="ADVERTENCIA: La grabación con un codificador de software con una calidad diferente de la secuencia requerirá el uso de CPU extra si transmitir y registro 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?" Basic.Settings.Output.Simple.Warn.Lossless.Title="¡Atención de calidad sin pérdidas!" +Basic.Settings.Output.Simple.Warn.MultipleQSV="Advertencia: No se pueden usar varios codificadores QSV separados al transmitir y grabar al mismo tiempo. Si desea transmitir y grabar al mismo tiempo, por favor cambíelos, ya sea el codificador de grabación o el codificador de trasmisión." Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 bajo uso de CPU, aumenta el tamaño de archivo)" Basic.Settings.Output.VideoBitrate="Bitrate de vídeo" Basic.Settings.Output.AudioBitrate="Bitrate de audio" @@ -322,7 +357,7 @@ Basic.Settings.Output.NoSpaceFileName="Generar el nombre del archivo sin espacio Basic.Settings.Output.Adv.Rescale="Cambiar la escala de salida" Basic.Settings.Output.Adv.AudioTrack="Pista de audio" -Basic.Settings.Output.Adv.Streaming="En tiempo real" +Basic.Settings.Output.Adv.Streaming="Emision en directo" Basic.Settings.Output.Adv.ApplyServiceSettings="Aplicar ajustes de codificador de servicio streaming" Basic.Settings.Output.Adv.Audio.Track1="Pista 1" Basic.Settings.Output.Adv.Audio.Track2="Pista 2" @@ -333,7 +368,9 @@ Basic.Settings.Output.Adv.Recording="Grabando" Basic.Settings.Output.Adv.Recording.Type="Tipo" Basic.Settings.Output.Adv.Recording.Type.Standard="Estándar" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Salida personalizada (FFmpeg)" -Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Usar flujo del codificador)" +Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Usar codificación de trasmisión)" +Basic.Settings.Output.Adv.Recording.Filename="Nombre de archivo de formato" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Sobrescribir si el archivo existe" Basic.Settings.Output.Adv.FFmpeg.Type="Tipo de salida de FFmpeg" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Salida a URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Salida a archivo" @@ -354,6 +391,10 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Codificador de audio" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Configuración de codificador de vídeo (si existe)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Ajustes de Muxer (en caso de que haya)" +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 Año, cuatro dígitos\n%YY Año, ultimo dos dígitos (00-99)\n%MM Mes como numero decimal (01-12)\n%DD Día del mes, cero-añadido (01-31)\n%hh Hora en formato 24h (00-23)\n%mm Minuto (00-59)\n%ss Segundo (00-61)\n%% A % signo\n%a Nombre del día semanal Abreviado\n%A completo nombre dia semanal\n%b Nombre del Mes Abreviado\n%B Nombre completo del nombre del mes\n%d Día del mes, cero-añadido (01-31)\n%H Formato Hora en 24h (00-23)\n%I Formato Hora en 12h (01-12)\n%m Mes como numero decimal (01-12)\n%M Minuto (00-59)\n%p Designación AM o PM\n%S Segundo (00-61)\n%y Año, últimos dos dígitos (00-99)\n%Y Year\n%z ISO 8601 ajuste de UTC o zona horaria\n nombre o abreviación\n%Z Nombre de zona horaria o abreviación\n" + Basic.Settings.Video="Vídeo" Basic.Settings.Video.Adapter="Adaptador de vídeo:" Basic.Settings.Video.BaseResolution="Resolución de la base (Canvas):" @@ -410,11 +451,11 @@ Basic.AdvAudio.Panning="Panorámica" Basic.AdvAudio.SyncOffset="Sincronización Offset (ms)" Basic.AdvAudio.AudioTracks="Pistas" -Basic.Settings.Hotkeys="Teclas de acceso rápido" +Basic.Settings.Hotkeys="Atajos" Basic.Settings.Hotkeys.Pair="Combinaciones de teclas con '%1' actúan como interruptores" -Basic.Hotkeys.StartStreaming="Iniciar transmisión" -Basic.Hotkeys.StopStreaming="Detener retransmisión" +Basic.Hotkeys.StartStreaming="Iniciar Transmisión" +Basic.Hotkeys.StopStreaming="Detener Transmisión" Basic.Hotkeys.StartRecording="Iniciar grabación" Basic.Hotkeys.StopRecording="Detener grabación" Basic.Hotkeys.SelectScene="Cambiar a la escena" diff --git a/obs/data/locale/eu-ES.ini b/obs/data/locale/eu-ES.ini index b6d058a..73e37f5 100644 --- a/obs/data/locale/eu-ES.ini +++ b/obs/data/locale/eu-ES.ini @@ -2,238 +2,266 @@ Language="Euskara" Region="Euskal Herria" -OK="Ongi" -Apply="Ezarri" +OK="Ados" +Apply="Aplikatu" Cancel="Ezeztatu" Close="Itxi" Save="Gorde" Discard="Baztertu" +Disable="Ezgaitu" Yes="Bai" No="Ez" Add="Gehitu" Remove="Kendu" Rename="Berrizendatu" -Interact="Elkarrekintza" +Interact="Elkarreragin" Filters="Iragazkiak" Properties="Ezaugarriak" -MoveUp="Mugitu Gora" -MoveDown="Mugitu Behera" -Settings="Ezarpenak..." -Display="Erakusleihoa" +MoveUp="Mugitu gora" +MoveDown="Mugitu behera" +Settings="Ezarpenak" +Display="Pantaila" Name="Izena" Exit="Irten" -Mixer="Nahastzailea" -Browse="Bilatu..." +Mixer="Nahastailea" +Browse="Arakatu" Mono="Monoa" Stereo="Estereoa" -DroppedFrames="Eroritako Frameak %1 (%2%)" -PreviewProjector="Ikusleiho-osoko Proiektorea (Aurreikuspena)" -SceneProjector="Ikusleiho-osoko Proiektorea (Agerraldia)" -SourceProjector="Ikusleiho-osoko Proiektorea (Iturburua)" +DroppedFrames="Galdutako fotogramak %1 (%2%)" +PreviewProjector="Pantaila osoko proiektorea (aurrebista)" +SceneProjector="Pantaila osoko proiektorea (eszena)" +SourceProjector="Pantaila osoko proiektorea (iturburua)" Clear="Garbitu" Revert="Leheneratu" Show="Erakutsi" Hide="Ezkutatu" -Untitled="Izenburugabea" +Untitled="Izengabea" New="Berria" Duplicate="Bikoiztu" Enable="Gaitu" DisableOSXVSync="Ezgaitu OSX V-Sync" -ResetOSXVSyncOnExit="Berrezarri OSX V-Sync Irtetzerakoan" -HighResourceUsage="Kodeaketa gainzamatuta! Kontuan hartu bideo ezarpenak beheratzea edo kodeaketa aurrezarpen azkarrago bat erabiltzea." -Transition="Aldaketa" -QuickTransitions="Aldaketa Azkarrak" +ResetOSXVSyncOnExit="Berrezarri OSX V-Sync-a Irtetean" +HighResourceUsage="Kodeketa gainzamatuta! Kontuan hartu bideo ezarpenak jaistea edo kodeketa-aurrezarpen azkarragoa erabiltzea." +Transition="Trantsizioa" +QuickTransitions="Trantsizio azkarrak" +Left="Ezkerrean" +Right="Eskuinean" +Top="Goian" +Bottom="Behean" -QuickTransitions.DuplicateScene="Bikoiztu Agerraldia" -QuickTransitions.EditProperties="Bikoiztu Iturburuak" -QuickTransitions.HotkeyName="Aldaketa Azkarra: %1" +QuickTransitions.SwapScenes="Trukatu Aurrebista/Irteera-eszenak trantsizioen ondoren" +QuickTransitions.SwapScenesTT="Trukatu aurrebistak eta irteera-eszenak trantsizioen ondoren (baldin eta irteerakoaren jatorrizkoa eszena badago).\n Honek ez du desegingo irteerakoaren jatorrizko eszenari egindako aldaketak." +QuickTransitions.DuplicateScene="Bikoiztu eszena" +QuickTransitions.DuplicateSceneTT="Eszena bera editatzerakoan, iturburuen eraldaketa/ikusgarritasuna editatzea ahalbidetzen du irteera aldatu gabe.\nIturburuen ezaugarriak editatzeko irteera aldatu gabe, gaitu 'Bikoiztu iturburuak'.\nBalio hau aldatzeak uneko agerraldi irteera (oraindik badago) berrezarriko du." +QuickTransitions.EditProperties="Bikoiztu iturburuak" +QuickTransitions.EditPropertiesTT="Eszena bera editatzerakoan, iturburuen ezaugarriak irteera aldatu gabe editatzea ahalbidetzen du.\nHau 'Bikoiztu Iturburuak' gaituta badago bakarrik erabili daiteke.\nZenbait iturburuk (kaptura edo multimedia iturburuak) ez dute hau onartzen eta ezin dira bereizita editatu.\nBalio hau aldatzeak uneko eszena irteera (oraindik badago) berrezarriko du.\n\nKontuz: Iturburuak bikoiztuko direnez, honek sistema edo bideo baliabide gehigarriak behar izan ditzake." +QuickTransitions.HotkeyName="Trantsizio azkarra: %1" -Basic.SceneTransitions="Agerraldi Aldaketak" +Basic.AddTransition="Gehitu trantsizio konfiguragarria" +Basic.RemoveTransition="Kendu trantsizio konfiguragarria" +Basic.TransitionProperties="Trantsizioaren ezaugarriak" +Basic.SceneTransitions="Eszena-trantsizioak" Basic.TransitionDuration="Iraupena" Basic.TogglePreviewProgramMode="Estudio Modua" +TransitionNameDlg.Text="Sartu trantsizioaren izena" +TransitionNameDlg.Title="Trantsizioaren Izena" + TitleBar.Profile="Profila" -TitleBar.Scenes="Agerraldiak" +TitleBar.Scenes="Eszenak" NameExists.Title="Izena badago jadanik" -NameExists.Text="Izena jadanik erabilia da." +NameExists.Text="Izena dagoeneko erabilia." -NoNameEntered.Title="Mesedez sartu baliozko izen bat" -NoNameEntered.Text="Ezin duzu izena hutsik erabili." +NoNameEntered.Title="Sartu baliozko izena" +NoNameEntered.Text="Ezin duzu hutsik dagoen izena erabili." -ConfirmStart.Title="Hasi Jarioa?" -ConfirmStart.Text="Zihur zaude jarioa hastea nahi duzula?" +ConfirmStart.Title="Hasi transmisioa?" +ConfirmStart.Text="Ziur zaude transmisioa hasi nahi duzula?" -ConfirmStop.Title="Gelditu Jarioa?" -ConfirmStop.Text="Zihur zaude jarioa gelditzea nahi duzula?" +ConfirmStop.Title="Gelditu transmisioa?" +ConfirmStop.Text="Ziur zaude transmisioa gelditu nahi duzula?" ConfirmExit.Title="Irten OBS-tik?" -ConfirmExit.Text="OBS jardunean dago. Jario/grabaketa guztiak itzali egingo dira. Zihur zaude irtetzea nahi duzula?" +ConfirmExit.Text="OBS jardunean dago. Transmisio/grabazio guztiak itzaliko dira. Ziur zaude irten nahi duzula?" -ConfirmRemove.Title="Baieztatu Kentzea" -ConfirmRemove.Text="Zihur zaude '$1' kentzea nahi duzula?" +ConfirmRemove.Title="Baieztatu kentzea" +ConfirmRemove.Text="Ziur zaude '$1' kendu nahi duzula?" -Output.ConnectFail.Title="Hutsegitea elkartzerakoan" -Output.ConnectFail.BadPath="Helburu edo Elkarketa URL okerra. Mesedez egiaztatu zure ezarpenak baliozkoak direla baieztatzeko." -Output.ConnectFail.ConnectFailed="Hutsegitea zerbitzariarekin elkartzerakoan" -Output.ConnectFail.InvalidStream="Ez dago sarbiderik adierazitako bidera edo jario giltzara. Hau izan daiteke giltza/bidea baliogabea delako, edo zerbitzariak oraindik saioa hasita zaudela uste duelako." -Output.ConnectFail.Error="Ustekabeko akats bat gertatu da zerbitzariarekin elkartzen saiatzerakoan. Argibide gehiago ohar agirian." -Output.ConnectFail.Disconnected="Zerbitzaritik etenda." +Output.ConnectFail.Title="Huts egin du konektatzean" +Output.ConnectFail.BadPath="Helburu edo konexio-URL okerra. Egiaztatu zure ezarpenak baliozkoak direla baieztatzeko." +Output.ConnectFail.ConnectFailed="Huts egin du zerbitzariarekin konektatzean" +Output.ConnectFail.InvalidStream="Ezin da atzitu kanala edo transmisioaren gakoa. Egiaztatu, mesedez, birritan transmisio gakoa. Zuzena bada zerbitzariarekin konektatzen arazoa egon daiteke." +Output.ConnectFail.Error="Ustekabeko akats bat gertatu da zerbitzariarekin konektatzen saiatzerakoan. Argibide gehiago egunkari-fitxategian." +Output.ConnectFail.Disconnected="Zerbitzaritik deskonektatuta." -Output.RecordFail.Title="Hutsegitea grabaketa hastean" -Output.RecordFail.Unsupported="Irteera heuskarria ez dago sostengatua edo ez du audio bide bat baino gehiago sostengatzen. Mesedez egiaztatu zure ezarpenak eta saiatu berriro." -Output.RecordNoSpace.Title="Ez dago nahikoa toki diskan" -Output.RecordNoSpace.Msg="Ez dago nahikoa toki diskan grabatzen jarraitzeko." -Output.RecordError.Title="Grabaketa akatsa" +Output.RecordFail.Title="Ezin izan da grabaketa hasi" +Output.RecordFail.Unsupported="Irteera formatua ez da onartzen edo ez du audio pista bat baino gehiago onartzen. Egiaztatu zure ezarpenak eta saiatu berriro." +Output.RecordNoSpace.Title="Ez dago nahiko tokirik diskoan" +Output.RecordNoSpace.Msg="Ez dago nahikoa tokirik diskoan grabatzen jarraitzeko." +Output.RecordError.Title="Grabazio akatsa" Output.RecordError.Msg="Zehaztugabeko akats bat gertatu da grabatzerakoan." -Output.BadPath.Title="Agiri Helburu Okerra" -Output.BadPath.Text="Itxuratutako agiri irteera helburua baliogabea da. Mesedez egiaztatu zure ezarpenak agiri helburu baliozkoa bat ezarri dela baieztatzeko." +Output.BadPath.Title="Fitxategi-bide okerra" +Output.BadPath.Text="Ezarritako fitxategiaren irteera-bidea baliogabea da. Egiaztatu zure ezarpenak baieztatzeko baliozko fitxategi-bidea ezarri dela." -LogReturnDialog="Ohar Igotzea Ongi" +LogReturnDialog="Egunkaria ongi kargatu da" LogReturnDialog.CopyURL="Kopiatu URL-a" -LogReturnDialog.ErrorUploadingLog="Akatsa ohar agiria igotzerakoan" +LogReturnDialog.ErrorUploadingLog="Errorea egunkari-fitxategia kargatzean" -LicenseAgreement="Baimen Ituna" -LicenseAgreement.PleaseReview="Mesedez berrikusi baimenaren baldintzak OBS erabili aurretik. Programa hau erabiliz, adierazten duzu GNU Baimen Publiko Orokorra v2.0 ituna irakurri duzula eta itunaren baldintzak onartzen dituzula. Mesedez irristatu behera itunaren gainontzekoa ikusteko." -LicenseAgreement.ClickIAgreeToContinue="Itunaren baldintzak onartzen badituzu, klikatu Onartzen dut jarraitzeko. Ituna onartu behar duzu OBS erabiltzeko." +LicenseAgreement="Lizentzia-kontratua" +LicenseAgreement.PleaseReview="Berrikusi lizentziaren baldintzak OBS erabili aurretik. Programa hau erabiltzean, adierazten duzu GNU General Public License v2.0-ren baldintzak irakurri eta onartzen dituzula. Korritu behera itun osoa ikusteko." +LicenseAgreement.ClickIAgreeToContinue="Lizentziaren baldintzak onartzen badituzu, klikatu Onartzen dut jarraitzeko. Lizentzia onartu behar duzu OBS erabiltzeko." LicenseAgreement.IAgree="Onartzen dut" LicenseAgreement.Exit="Irten" -Remux.SourceFile="OBS Grabaketa" -Remux.TargetFile="Xede Agiria" +Remux.SourceFile="OBS Grabazioa" +Remux.TargetFile="Helburu-fitxategia" Remux.Remux="Bermultiplexatu" -Remux.RecordingPattern="OBS Grabaketa (*.flv)" -Remux.FinishedTitle="Bermultiplexaketa amaituta" -Remux.Finished="Grabaketa bermultiplexatuta" -Remux.FinishedError="Grabaketa bermultiplexatuta, baina badaiteke agiria osatugabe egotea" -Remux.SelectRecording="Hautatu OBS Grabaketa…" -Remux.SelectTarget="Hautatu xede agiria..." -Remux.FileExistsTitle="Xede agiria badago" -Remux.FileExists="Xede agiria badago, ordeztea nahi duzu?" +Remux.OBSRecording="OBS Grabazioa" +Remux.FinishedTitle="Bihurketa amaituta" +Remux.Finished="Grabazioa bihurtuta" +Remux.FinishedError="Grabazioa bihurtua, baina fitxategia osatu gabe egon daiteke" +Remux.SelectRecording="Hautatu OBS grabazioa…" +Remux.SelectTarget="Hautatu helburu-fitxategia…" +Remux.FileExistsTitle="Helburu-fitxategia badago" +Remux.FileExists="Helburu-fitxategia badago, ordeztea nahi duzu?" Remux.ExitUnfinishedTitle="Bermultiplexaketa garatzen" -Remux.ExitUnfinished="Bermultiplexaketa ez da amaitu, orain gelditzeak xede agiria erabiltezin aurkeztu dezake.\nZihur zaude bermultiplexaketa gelditzea nahi duzula?" +Remux.ExitUnfinished="Bihurketa ez da amaitu, orain gelditzeak fitxategi-helburua erabiltezin bihur dezake.\nZiur zaude bihurtzea gelditu nahi duzula?" -UpdateAvailable="Eguneraketa Berria Eskuragarri" -UpdateAvailable.Text="%1.%2.%3 bertsioa eskuragarri dago. Klikatu hemen jeisteko" +UpdateAvailable="Eguneraketa eskuragarria" +UpdateAvailable.Text="%1.%2.%3 bertsioa eskuragarri dago. Klikatu hemen deskargatzeko" -Basic.DesktopDevice1="Mahaigaineko Audioa" -Basic.DesktopDevice2="Mahaigaineko Audioa 2" +Basic.DesktopDevice1="Mahaigaineko audioa" +Basic.DesktopDevice2="Mahaigaineko audioa 2" Basic.AuxDevice1="Mik/Osag" Basic.AuxDevice2="Mik/Osag 2" Basic.AuxDevice3="Mik/Osag 3" Basic.AuxDevice4="Mik/Osag 4" -Basic.Scene="Agerraldia" -Basic.DisplayCapture="Erakusleiho Harpena" +Basic.Scene="Eszena" +Basic.DisplayCapture="Pantaila-kaptura" -Basic.Main.PreviewConextMenu.Enable="Gaitu aurreikuspena" +Basic.Main.PreviewConextMenu.Enable="Gaitu aurrebista" -Basic.Main.AddSceneDlg.Title="Gehitu Agerraldia" -Basic.Main.AddSceneDlg.Text="Mesedez sartu agerraldiaren izena" +Deinterlacing="Desgurutzelarkatzea" +Deinterlacing.Discard="Baztertu" +Deinterlacing.Retro="Retro" +Deinterlacing.Blend="Nahasketa" +Deinterlacing.Blend2x="Nahasketa 2x" +Deinterlacing.Linear="Lineala" +Deinterlacing.Linear2x="Lineala 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Goiko eremua lehenik" +Deinterlacing.BottomFieldFirst="Beheko eremua lehenik" -Basic.Main.DefaultSceneName.Text="%1 agerraldia" +Basic.Main.AddSceneDlg.Title="Gehitu eszena" +Basic.Main.AddSceneDlg.Text="Sartu eszenaren izena" -Basic.Main.AddSceneCollection.Title="Gehitu Agerraldi Bilduma" -Basic.Main.AddSceneCollection.Text="Mesedez sartu agerraldi bildumaren izena" +Basic.Main.DefaultSceneName.Text="%1 eszena" -Basic.Main.RenameSceneCollection.Title="Berrizendatu Agerraldi Bilduma" +Basic.Main.AddSceneCollection.Title="Gehitu eszena-bilduma" +Basic.Main.AddSceneCollection.Text="Sartu eszena-bildumaren izena" -AddProfile.Title="Gehitu Profila" -AddProfile.Text="Mesedez sartu profilaren izena" +Basic.Main.RenameSceneCollection.Title="Berrizendatu eszena-bilduma" + +AddProfile.Title="Gehitu profila" +AddProfile.Text="Sartu profilaren izena" RenameProfile.Title="Berrizendatu profila" -Basic.Main.PreviewDisabled="Aurreikuspena ezgaituta dago" +Basic.Main.PreviewDisabled="Aurrebista ezgaituta dago" Basic.SourceSelect="Sortu/Hautatu Iturburua" Basic.SourceSelect.CreateNew="Sortu berria" -Basic.SourceSelect.AddExisting="Gehitu Badagoena" +Basic.SourceSelect.AddExisting="Gehitu lehendik dagoena" Basic.SourceSelect.AddVisible="Egin iturburua ikusgarri" Basic.PropertiesWindow="'%1'-ren ezaugarriak" Basic.PropertiesWindow.AutoSelectFormat="%1 (berez-hautatu: %2)" -Basic.PropertiesWindow.SelectColor="Hautatu margoa" -Basic.PropertiesWindow.SelectFont="Hautatu hizkia" -Basic.PropertiesWindow.ConfirmTitle="Ezarpenak Aldatuta" -Basic.PropertiesWindow.Confirm="Gorde gabeko aldaketak daude. Heustea nahi diezu?" +Basic.PropertiesWindow.SelectColor="Hautatu kolorea" +Basic.PropertiesWindow.SelectFont="Hautatu letra-mota" +Basic.PropertiesWindow.ConfirmTitle="Ezarpenak aldatuta" +Basic.PropertiesWindow.Confirm="Gorde gabeko aldaketak daude. Nahi duzu dagoena mantentzea?" Basic.PropertiesWindow.NoProperties="Ezaugarriak ez daude eskuragarri" -Basic.PropertiesWindow.AddFiles="Gehitu Agiriak" -Basic.PropertiesWindow.AddURL="Gehitu Helburua/URL-a" -Basic.PropertiesWindow.AddEditableListFiles="Gehitu agiriak '%1'-ra" +Basic.PropertiesWindow.AddFiles="Gehitu fitxategiak" +Basic.PropertiesWindow.AddURL="Gehitu bidea/URL-a" +Basic.PropertiesWindow.AddEditableListFiles="Gehitu fitxategiak '%1'-ra" Basic.PropertiesWindow.AddEditableListEntry="Gehitu sarrera '%1'-ra" Basic.PropertiesWindow.EditEditableListEntry="Editatu sarrera '%1'-tik" -Basic.PropertiesView.FPS.Simple="FS-ko Balio Arrunta" -Basic.PropertiesView.FPS.Rational="FS-ko Balio Arrazionala" -Basic.PropertiesView.FPS.ValidFPSRanges="Baliozko FS-ko Tarteak:" +Basic.PropertiesView.FPS.Simple="FPS-ko balio arruntak" +Basic.PropertiesView.FPS.Rational="FPS-ko balio arrazionalak" +Basic.PropertiesView.FPS.ValidFPSRanges="Baliozko FPS-ko tarteak:" Basic.InteractionWindow="Elkarrekintza '%1'-rekin" -Basic.StatusBar.Reconnecting="Entenda, %2 segundu barru berrelkartzen (saiakera %1)" -Basic.StatusBar.AttemptingReconnect="Berrelkartzen saiatzen... (saiakera %1)" -Basic.StatusBar.ReconnectSuccessful="Ber-elkarketa ongi" +Basic.StatusBar.Reconnecting="Konexiorik gabe, %2 segundo barru birkonektatzen (saiakera %1)" +Basic.StatusBar.AttemptingReconnect="Birkonektatzen saiatzen... (saiakera %1)" +Basic.StatusBar.ReconnectSuccessful="Birkonexioa ongi burutu da" Basic.StatusBar.Delay="Atzerapena (%1 seg)" -Basic.StatusBar.DelayStartingIn="Atzerapena (hasiera %1 seg)" -Basic.StatusBar.DelayStoppingIn="Atzerapena (gelditzea %1 seg)" -Basic.StatusBar.DelayStartingStoppingIn="Atzerapena (gelditzea %1 seg, hasiera %2 seg)" +Basic.StatusBar.DelayStartingIn="Atzerapena (hasiera %1 seg-tan)" +Basic.StatusBar.DelayStoppingIn="Atzerapena (gelditzea %1 seg-tan)" +Basic.StatusBar.DelayStartingStoppingIn="Atzerapena (gelditzea %1 seg-tan, hasiera %2 seg-tan)" Basic.Filters="Iragazkiak" Basic.Filters.AsyncFilters="Audio/Bideo Iragazkiak" Basic.Filters.AudioFilters="Audio Iragazkiak" -Basic.Filters.EffectFilters="Eragin Iragazkiak" +Basic.Filters.EffectFilters="Efektu Iragazkiak" Basic.Filters.Title="Iragazkiak '%1'-rako" Basic.Filters.AddFilter.Title="Iragazkiaren Izena" -Basic.Filters.AddFilter.Text="Mesedez adierazi iragazkiaren izena" +Basic.Filters.AddFilter.Text="Adierazi iragazkiaren izena" -Basic.TransformWindow="Agerraldi Gaiaren Eraldaketa" +Basic.TransformWindow="Eszenaren ezarpenak" Basic.TransformWindow.Position="Kokapena" -Basic.TransformWindow.Rotation="Itzulikapena" -Basic.TransformWindow.Size="Neurria" -Basic.TransformWindow.Alignment="Kokapen Lerrokapena" -Basic.TransformWindow.BoundsType="Muga Kutxa Mota" -Basic.TransformWindow.BoundsAlignment="Lerrokatu Muga Kutxan" -Basic.TransformWindow.Bounds="Muga Kutxa Neurria" +Basic.TransformWindow.Rotation="Biraketa" +Basic.TransformWindow.Size="Tamaina" +Basic.TransformWindow.Alignment="Kokapen lerrokatzea" +Basic.TransformWindow.BoundsType="Muga-koadro mota" +Basic.TransformWindow.BoundsAlignment="Lerrokatu muga-koadroan" +Basic.TransformWindow.Bounds="Muga-koadroaren tamaina" +Basic.TransformWindow.Crop="Moztu" -Basic.TransformWindow.Alignment.TopLeft="Goi Ezkerrean" -Basic.TransformWindow.Alignment.TopCenter="Goi Erdian" -Basic.TransformWindow.Alignment.TopRight="Goi Eskuinean" -Basic.TransformWindow.Alignment.CenterLeft="Erdi Ezkerrean" +Basic.TransformWindow.Alignment.TopLeft="Goian ezkerrean" +Basic.TransformWindow.Alignment.TopCenter="Goian erdian" +Basic.TransformWindow.Alignment.TopRight="Goian eskuinean" +Basic.TransformWindow.Alignment.CenterLeft="Erdian ezkerrean" Basic.TransformWindow.Alignment.Center="Erdian" -Basic.TransformWindow.Alignment.CenterRight="Erdi Eskuinean" -Basic.TransformWindow.Alignment.BottomLeft="Behe Ezkerrean" -Basic.TransformWindow.Alignment.BottomCenter="Behe Erdian" -Basic.TransformWindow.Alignment.BottomRight="Behe Eskuinean" +Basic.TransformWindow.Alignment.CenterRight="Erdian eskuinean" +Basic.TransformWindow.Alignment.BottomLeft="Behean ezkerrean" +Basic.TransformWindow.Alignment.BottomCenter="Behean erdian" +Basic.TransformWindow.Alignment.BottomRight="Behean eskuinean" Basic.TransformWindow.BoundsType.None="Mugarik ez" -Basic.TransformWindow.BoundsType.MaxOnly="Gehienezko neurria bakarrik" +Basic.TransformWindow.BoundsType.MaxOnly="Gehienezko tamaina bakarrik" Basic.TransformWindow.BoundsType.ScaleInner="Eskalatu barruko mugetara" Basic.TransformWindow.BoundsType.ScaleOuter="Eskalatu kanpoko mugetara" Basic.TransformWindow.BoundsType.ScaleToWidth="Eskalatu muga zabalerara" -Basic.TransformWindow.BoundsType.ScaleToHeight="Eskalatu garaiera mugetara" +Basic.TransformWindow.BoundsType.ScaleToHeight="Eskalatu altuera-mugetara" Basic.TransformWindow.BoundsType.Stretch="Luzatu mugetara" -Basic.Main.AddSourceHelp.Title="Ezin da Iturbururik Gehitu" -Basic.Main.AddSourceHelp.Text="Gutxienez 1 agerraldi eduki behar duzu iturburu batera gehituta." +Basic.Main.AddSourceHelp.Title="Ezin da iturbururik gehitu" +Basic.Main.AddSourceHelp.Text="Gutxienez eszena bat eduki behar duzu iturburu bat gehitzeko." -Basic.Main.Scenes="Agerraldiak" +Basic.Main.Scenes="Eszenak" Basic.Main.Sources="Iturburuak" -Basic.Main.Connecting="Elkartzen..." -Basic.Main.StartRecording="Hasi Grabaketa" -Basic.Main.StartStreaming="Hasi Jarioa" -Basic.Main.StopRecording="Gelditu Grabaketa" -Basic.Main.StopStreaming="Gelditu Jarioa" -Basic.Main.ForceStopStreaming="Gelditu Jarioa (baztertu atzerapena)" +Basic.Main.Connecting="Konektatzen..." +Basic.Main.StartRecording="Hasi grabazioa" +Basic.Main.StartStreaming="Hasi transmisioa" +Basic.Main.StopRecording="Gelditu grabazioa" +Basic.Main.StopStreaming="Gelditu transmisioa" +Basic.Main.ForceStopStreaming="Gelditu transmisioa (baztertu atzerapena)" -Basic.MainMenu.File="&Agiria" -Basic.MainMenu.File.Export="E&sportatu" -Basic.MainMenu.File.Import="I&nportatu" -Basic.MainMenu.File.ShowRecordings="Erakutsi &Grabaketak" +Basic.MainMenu.File="&Fitxategia" +Basic.MainMenu.File.Export="&Esportatu" +Basic.MainMenu.File.Import="&Inportatu" +Basic.MainMenu.File.ShowRecordings="Erakutsi &Grabazioak" Basic.MainMenu.File.Remux="&Bermultiplexaketa Grabaketak" Basic.MainMenu.File.Settings="&Ezarpenak" -Basic.MainMenu.File.ShowSettingsFolder="Erakutsi Ezarpenak Agiritegia" -Basic.MainMenu.File.ShowProfileFolder="Erakutsi Profila Agiritegia" -Basic.MainMenu.AlwaysOnTop="&Betik Gainean" +Basic.MainMenu.File.ShowSettingsFolder="Erakutsi ezarpenen karpeta" +Basic.MainMenu.File.ShowProfileFolder="Erakutsi profilaren karpeta" +Basic.MainMenu.AlwaysOnTop="&Beti gainean" Basic.MainMenu.File.Exit="I&rten" Basic.MainMenu.Edit="&Editatu" @@ -244,189 +272,206 @@ Basic.MainMenu.Edit.RedoAction="&Berregin $1" Basic.MainMenu.Edit.Transform="&Eraldatu" Basic.MainMenu.Edit.Transform.EditTransform="E&ditatu Eraldaketa..." Basic.MainMenu.Edit.Transform.ResetTransform="&Berrezarri Eraldaketa" -Basic.MainMenu.Edit.Transform.Rotate90CW="Itzulikatu 90 gradu ON" -Basic.MainMenu.Edit.Transform.Rotate90CCW="Itzulikatu 90 gradu OAN" -Basic.MainMenu.Edit.Transform.Rotate180="Itzulikatu 180 gradu" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Itzulikatu &Etzanka" -Basic.MainMenu.Edit.Transform.FlipVertical="Itzulikatu &Zutika" -Basic.MainMenu.Edit.Transform.FitToScreen="&Finkatu ikusleihora" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Luzatu ikusleihora" -Basic.MainMenu.Edit.Transform.CenterToScreen="&Erdiratu ikusleihoan" +Basic.MainMenu.Edit.Transform.Rotate90CW="Biratu 90 gradu erlojuaren norabidean" +Basic.MainMenu.Edit.Transform.Rotate90CCW="Itzulikatu 90 gradu erlojuaren kontrako norabidean" +Basic.MainMenu.Edit.Transform.Rotate180="Biratu 180 gradu" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Irauli &horizontala" +Basic.MainMenu.Edit.Transform.FlipVertical="Irauli &bertikala" +Basic.MainMenu.Edit.Transform.FitToScreen="&Doitu pantailara" +Basic.MainMenu.Edit.Transform.StretchToScreen="&Luzatu pantailara" +Basic.MainMenu.Edit.Transform.CenterToScreen="&Erdiratu pantailan" Basic.MainMenu.Edit.Order="&Ordenatu" Basic.MainMenu.Edit.Order.MoveUp="Mugitu &Gora" -Basic.MainMenu.Edit.Order.MoveDown="Mugitu &Behera" -Basic.MainMenu.Edit.Order.MoveToTop="Mugitu G&oren" -Basic.MainMenu.Edit.Order.MoveToBottom="Mugitu B&eheren" -Basic.MainMenu.Edit.AdvAudio="A&udio Ezaugarri Aurreratuak" +Basic.MainMenu.Edit.Order.MoveDown="Mugitu &behera" +Basic.MainMenu.Edit.Order.MoveToTop="Mugitu &goraino" +Basic.MainMenu.Edit.Order.MoveToBottom="Mugitu &beheraino" +Basic.MainMenu.Edit.AdvAudio="&Audio ezarpen aurreratuak" -Basic.MainMenu.SceneCollection="&Agerraldi Bilduma" +Basic.MainMenu.SceneCollection="&Eszena-bilduma" Basic.MainMenu.Profile="&Profila" Basic.MainMenu.Help="&Laguntza" Basic.MainMenu.Help.Website="Ikusi &Webgunea" -Basic.MainMenu.Help.Logs="&Ohar Agiriak" -Basic.MainMenu.Help.Logs.ShowLogs="&Erakutsi Ohar Agiriak" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Igo &Oraingo Ohar Agiria" -Basic.MainMenu.Help.Logs.UploadLastLog="Igo &Azken Ohar Agiria" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Ikusi Oraingo Oharra" -Basic.MainMenu.Help.CheckForUpdates="Egiaztatu Eguneraketak" +Basic.MainMenu.Help.Logs="&Egunkari-fitxategiak" +Basic.MainMenu.Help.Logs.ShowLogs="&Erakutsi egunkari-fitxategiak" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Kargatu &uneko egunkari-fitxategiak" +Basic.MainMenu.Help.Logs.UploadLastLog="Kargatu &azken egunkari-fitxategia" +Basic.MainMenu.Help.Logs.ViewCurrentLog="&Ikusi uneko egunkari-fitxategia" +Basic.MainMenu.Help.CheckForUpdates="Begiratu eguneraketak" Basic.Settings.ProgramRestart="Programa berrabiarazi egin behar da ezarpen hauek eragina izateko." -Basic.Settings.ConfirmTitle="Baieztatu Aldaketak" +Basic.Settings.ConfirmTitle="Baieztatu aldaketak" Basic.Settings.Confirm="Gordegabeko aldaketak dituzu. Gorde aldaketak?" Basic.Settings.General="Orokorra" -Basic.Settings.General.Theme="Azalgaia" +Basic.Settings.General.Theme="Gaia" Basic.Settings.General.Language="Hizkuntza" -Basic.Settings.General.WarnBeforeStartingStream="Erakutsi baieztapen elkarrizketa jairoak hasterakoan" -Basic.Settings.General.WarnBeforeStoppingStream="Erakutsi baieztapen elkarrizketa jairoak gelditzerakoan" +Basic.Settings.General.WarnBeforeStartingStream="Erakutsi baieztapen elkarrizketa transmisioak hasterakoan" +Basic.Settings.General.WarnBeforeStoppingStream="Erakutsi baieztapen elkarrizketa transmisioak gelditzerakoan" +Basic.Settings.General.Snapping="Iturburuaren lerrokatzearen doitzea" +Basic.Settings.General.ScreenSnapping="Doitu iturburuak pantailaren ertzera" +Basic.Settings.General.CenterSnapping="Doitu iturburuak bertikalki eta horizontalki erdira" +Basic.Settings.General.SourceSnapping="Doitu iturburuak beste iturburuetara" +Basic.Settings.General.SnapDistance="Doitu sentikortasuna" -Basic.Settings.Stream="Jarioa" -Basic.Settings.Stream.StreamType="Jario Mota" +Basic.Settings.Stream="Transmisioa" +Basic.Settings.Stream.StreamType="Transmisio-mota" Basic.Settings.Output="Irteera" -Basic.Settings.Output.Format="Grabaketa Heuskarria" -Basic.Settings.Output.Encoder="Kodeatzailea" -Basic.Settings.Output.SelectDirectory="Hautatu Grabaketa Zuzenbidea" -Basic.Settings.Output.SelectFile="Hautatu Grabaketa Agiria" -Basic.Settings.Output.Mode="Irteera Modua" +Basic.Settings.Output.Format="Grabazio-formatua" +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.Mode="Irteera-modua" Basic.Settings.Output.Mode.Simple="Arrunta" Basic.Settings.Output.Mode.Adv="Aurreratua" Basic.Settings.Output.Mode.FFmpeg="FFmpeg Irteera" -Basic.Settings.Output.Simple.SavePath="Grabaketa Helburua" -Basic.Settings.Output.Simple.RecordingQuality="Grabaketa Ontasuna" -Basic.Settings.Output.Simple.RecordingQuality.Stream="Jarioaren berdina" -Basic.Settings.Output.Simple.RecordingQuality.Small="Ontasun Handia. Agiri Neurri Ertaina" -Basic.Settings.Output.Simple.RecordingQuality.HQ="Bereizgabeko Ontasuna. Agiri Neurri Handia" -Basic.Settings.Output.Simple.RecordingQuality.Lossless="Galeragabeko Ontasuna. Agiri Neurri Izugarri Handia" -Basic.Settings.Output.Simple.Warn.Encoder="Oharra: Software kodeatzaile batekin grabatzeak jarioaren ontasun ezberdin batean CPU-aren erabilpen gehigarria beharko du jarioa eta grabaketa aldiberean egiten badituzu." -Basic.Settings.Output.Simple.Warn.Lossless="Oharra: Galeragabeko ontasunak agiri neurri izugarri handiak sortzen ditu! Galeragabeko ontasunak 7 gigabytetik gorako diska tokia erabili dezake minutuko bereizmen eta frameneurri handietan. Galeragabea ez dago gomendatua grabaketa luzeetarako diska toki eskuragarri oso handi bat ez baduzu." -Basic.Settings.Output.Simple.Warn.Lossless.Msg="Zihur zaude galeragabeko ontasuna erabiltzea nahi duzula?" -Basic.Settings.Output.Simple.Warn.Lossless.Title="Galeragabeko ontasun oharra!" +Basic.Settings.Output.Simple.SavePath="Grabazio-bidea" +Basic.Settings.Output.Simple.RecordingQuality="Grabazio-kalitatea" +Basic.Settings.Output.Simple.RecordingQuality.Stream="Transmisioaren berdina" +Basic.Settings.Output.Simple.RecordingQuality.Small="Kalitate altua. Fitxategi-tamaina ertaina" +Basic.Settings.Output.Simple.RecordingQuality.HQ="Bereizigabeko kalitatea. Fitxategi-tamaina handia" +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.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?" +Basic.Settings.Output.Simple.Warn.Lossless.Title="Galerarik gabeko kalitateaz oharra!" +Basic.Settings.Output.Simple.Warn.MultipleQSV="Kontuz: Ezin dituzu QSV kodeatzaile ugari bananduta erabili aldiberean jariotu eta grabatzerakoan. Aldiberean jariotu eta grabatzea nahi baduzu, mesedez aldatu bietako bat, grabaketa kodeatzailea edo jariotze kodeatzailea." Basic.Settings.Output.Simple.Encoder.Software="Softwarea (x264)" -Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softwarea (x264 CPU erabilpen apaleko aurrezarpena, agiri neurria handitzen du)" -Basic.Settings.Output.VideoBitrate="Bideo Bitneurria" -Basic.Settings.Output.AudioBitrate="Audio Bitneurria" -Basic.Settings.Output.Reconnect="Berezgaitasunez Berrelkartu" -Basic.Settings.Output.RetryDelay="Saiakera Atzerapena (segundu)" -Basic.Settings.Output.MaxRetries="Gehienezko Saiakerak" -Basic.Settings.Output.Advanced="Gaitu Kodeatzaile Aurreratu Ezarpenak" -Basic.Settings.Output.EncoderPreset="Kodeatzaile Aurrezarpena (handiagoa = CPU gutxiago)" -Basic.Settings.Output.CustomEncoderSettings="Norbere Kodeatzaile Ezarpenak" -Basic.Settings.Output.CustomMuxerSettings="Norbere Nahastzaile Ezarpenak" -Basic.Settings.Output.NoSpaceFileName="Sortu Agiri Izena Tarterik gabe" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardwarea (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardwarea (NVENC)" +Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softwarea (x264 PUZ erabilpen apaleko aurre-ezarpena, fitxategiaren tamaina handitzen du)" +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.MaxRetries="Gehienezko saiakerak" +Basic.Settings.Output.Advanced="Gaitu Kodetzaile aurreratuaren ezarpenak" +Basic.Settings.Output.EncoderPreset="Kodetzailearen aurre-ezarpena (handiagoa = PUZ gutxiago)" +Basic.Settings.Output.CustomEncoderSettings="Kodetzailearen ezarpen pertsonalizatuak" +Basic.Settings.Output.CustomMuxerSettings="Bihurtzailearen ezarpen pertsonalizatuak" +Basic.Settings.Output.NoSpaceFileName="Sortu tarterik gabeko fitxategi-izena" -Basic.Settings.Output.Adv.Rescale="Birneurriratu Irteera" -Basic.Settings.Output.Adv.AudioTrack="Audio Bidea" -Basic.Settings.Output.Adv.Streaming="Jarioa" -Basic.Settings.Output.Adv.ApplyServiceSettings="Behartu jario zerbitzu kodeatzaile ezarpenak" -Basic.Settings.Output.Adv.Audio.Track1="1 Bidea" -Basic.Settings.Output.Adv.Audio.Track2="2 Bidea" -Basic.Settings.Output.Adv.Audio.Track3="3 Bidea" -Basic.Settings.Output.Adv.Audio.Track4="4 Bidea" +Basic.Settings.Output.Adv.Rescale="Eskala-aldaketaren Irteera" +Basic.Settings.Output.Adv.AudioTrack="Audio-pista" +Basic.Settings.Output.Adv.Streaming="Transmisioa" +Basic.Settings.Output.Adv.ApplyServiceSettings="Behartu transmisio-zerbitzu kodetzaileren ezarpenak" +Basic.Settings.Output.Adv.Audio.Track1="1 pista" +Basic.Settings.Output.Adv.Audio.Track2="2 pista" +Basic.Settings.Output.Adv.Audio.Track3="3 pista" +Basic.Settings.Output.Adv.Audio.Track4="4 pista" Basic.Settings.Output.Adv.Recording="Grabatzen" Basic.Settings.Output.Adv.Recording.Type="Mota" Basic.Settings.Output.Adv.Recording.Type.Standard="Estandarra" -Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Norbere Irteera (FFmpeg)" -Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Erabili jario kodeatzailea)" -Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg Irteera Mota" +Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Irteera pertsonalizatua (FFmpeg)" +Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Erabili transmisio kodetzailea)" +Basic.Settings.Output.Adv.Recording.Filename="Fitxategi-izenaren formatua" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Gainidatzi fitxategia badago" +Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg Irteera-mota" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Irteera URL-ra" -Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Irteera Agirira" -Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Grabaketa heuskarri arruntak" -Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Agiri Guztiak" -Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Agiri helburua edo URL-a" -Basic.Settings.Output.Adv.FFmpeg.Format="Edukiontzi Heuskarria" +Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Irteera fitxategira" +Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Grabazio formatu arruntak" +Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Fitxategi guztiak" +Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Fitxategi-bidea edo URL-a" +Basic.Settings.Output.Adv.FFmpeg.Format="Edukiontziaren formatua" Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Audioa" Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Bideoa" -Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Berezko Heuskarria" -Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Edukiontzi Heuskarri Azalpena" -Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Audio/Bideo Kodeka Agiri helburutik edo URL-tik igarria" -Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Berezko Kodeatzailea" -Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Ezgaitu Kodeatzailea" -Basic.Settings.Output.Adv.FFmpeg.VEncoder="Bideo Kodeatzailea" -Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Bideo Kodeatzaile Ezarpenak (egonez gero)" -Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audio Kodeatzailea" -Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audio Kodeatzaile Ezarpenak (egonez gero)" -Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Nahastzaile Ezarpenak (egonez gero)" +Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Formatu lehenetsia" +Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Edukiontzi-formatuaren ezaugarriak" +Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Audio/Bideo Kodeka fitxategiaren bidetik edo URLtik igarria" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Lehenetsitako kodetzailea" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Ezgaitu kodetzailea" +Basic.Settings.Output.Adv.FFmpeg.VEncoder="Bideo kodetzailea" +Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Bideo kodetzailearen ezarpenak (egonez gero)" +Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audio kodetzailea" +Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audio kodetzailearen ezarpenak (egonez gero)" +Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Bihurtzailearen ezarpenak (egonez gero)" + +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 Urtea, lau digitu\n%YY Urtea, azken bi digitu (00-99)\n%MM Hilabetea zenbaki hamartarrez (01-12)\n%DD Hilabeteko eguna bi digituz (01-31)\n%hh Ordua 24h formatuan (00-23)\n%mm Minutu (00-59)\n%ss Segundo (00-61)\n%% A % ikur\n%a Asteko eguna laburtua\n%A Asteko eguna izen osoa\n%b Hilabetea laburtua\n%B Hilabeteko izen osoa\n%d Hilabeteko eguna bi digituz (01-31)\n%H Ordua 24h formatuan (00-23)\n%I Ordua 12h formatuan (01-12)\n%m Hilabetea zenbaki hamartarrez (01-12)\n%M Minutua (00-59)\n%p AM edo PM \n%S Segundo (00-61)\n%y Urtea, azken bi digituz (00-99)\n%Y Urtea\n%z ISO 8601 UTC edo ordu-zonaz desplazatua\n laburduraren izena\n%Z Ordu-zona edo laburdura\n" Basic.Settings.Video="Bideoa" -Basic.Settings.Video.Adapter="Bideo Egokitzailea:" -Basic.Settings.Video.BaseResolution="Ohinarria (Oihala) Bereizmena:" -Basic.Settings.Video.ScaledResolution="Irteera (Eskalatua) Bereizmena:" -Basic.Settings.Video.DownscaleFilter="Behera-eskalatze Iragazkia:" +Basic.Settings.Video.Adapter="Bideo moldagailua:" +Basic.Settings.Video.BaseResolution="Oinarriaren (oihalaren) bereizmena:" +Basic.Settings.Video.ScaledResolution="Irteera (eskalatuaren) bereizmena:" +Basic.Settings.Video.DownscaleFilter="Behera-eskalatze iragazkia:" Basic.Settings.Video.DisableAeroWindows="Ezgaitu Aero (Windows bakarrik)" -Basic.Settings.Video.FPS="FS-ko:" -Basic.Settings.Video.FPSCommon="FS-ko Balio Arruntak" -Basic.Settings.Video.FPSInteger="FS-ko Balio Osoa" -Basic.Settings.Video.FPSFraction="FS-ko Balio Zatizkia" +Basic.Settings.Video.FPS="FPS:" +Basic.Settings.Video.FPSCommon="FPS balio arruntak" +Basic.Settings.Video.FPSInteger="FPS balio osoa" +Basic.Settings.Video.FPSFraction="FPS zatikizko balioa" Basic.Settings.Video.Numerator="Zenbakitzailea:" Basic.Settings.Video.Denominator="Izendatzailea:" -Basic.Settings.Video.Renderer="Aurkezlea:" -Basic.Settings.Video.InvalidResolution="Bereizmen balio baliogabea. Izan behar da [width]x[height] (adib. 1920x1080)" -Basic.Settings.Video.CurrentlyActive="Bideo irtera gaituta dago une honetan. Mesedez eten irteera guztiak bideo ezarpenak aldatzeko." +Basic.Settings.Video.Renderer="Errendatzailea:" +Basic.Settings.Video.InvalidResolution="Bereizmen baliogabea. Izan behar da [width]x[height] (adib. 1920x1080)" +Basic.Settings.Video.CurrentlyActive="Bideo irteera gaituta dago une honetan. Eten irteera guztiak bideo ezarpenak aldatzeko." Basic.Settings.Video.DisableAero="Ezgaitu Aero" -Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinearra (Azkarrena, baina lausoa eskalatuz gero)" -Basic.Settings.Video.DownscaleFilter.Bicubic="Bikubikoa (Eskalatze itzaldua, 16 lagin)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Eskalatze itzaldua, 32 lagin)" +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 (enfokatutako eskalatzea, 32 lagin)" Basic.Settings.Audio="Audioa" -Basic.Settings.Audio.SampleRate="Laginketa Neurria" +Basic.Settings.Audio.SampleRate="Lagin-maiztasuna" Basic.Settings.Audio.Channels="Bideak" -Basic.Settings.Audio.DesktopDevice="Mahaigaineko Audio Gailua" -Basic.Settings.Audio.DesktopDevice2="Mahaigaineko Audio Gailua 2" -Basic.Settings.Audio.AuxDevice="Mik/Osagarri Audio Gailua" -Basic.Settings.Audio.AuxDevice2="Mik/Osagarri Audio Gailua 2" -Basic.Settings.Audio.AuxDevice3="Mik/Osagarri Audio Gailua 3" +Basic.Settings.Audio.DesktopDevice="Mahaigaineko audio gailua" +Basic.Settings.Audio.DesktopDevice2="Mahaigaineko audio gailua 2" +Basic.Settings.Audio.AuxDevice="Mik/Osagarri audio gailua" +Basic.Settings.Audio.AuxDevice2="Mik/Osagarri audio gailua 2" +Basic.Settings.Audio.AuxDevice3="Mik/Osagarri audio gailua 3" Basic.Settings.Audio.EnablePushToMute="Gaitu Sakatu-mututzeko" Basic.Settings.Audio.PushToMuteDelay="Sakatu-mututzeko atzerapena" Basic.Settings.Audio.EnablePushToTalk="Gaitu Sakatu-hitz-egiteko" Basic.Settings.Audio.PushToTalkDelay="Sakatu-hitz-egiteko atzerapena" -Basic.Settings.Audio.UnknownAudioDevice="[Gailua ezin da elkartu edo ez dago eskuragarri]" +Basic.Settings.Audio.UnknownAudioDevice="[Gailua konektatu gabe edo ez dago eskuragarri]" Basic.Settings.Advanced="Aurreratua" -Basic.Settings.Advanced.FormatWarning="Kontuz: NV12 ez diren margo heuskarriak grabaketarako dira gehienbat, eta ez daude gomendatutarik jariorako. Jarioak CPU erabilpena handitu dezake margo heuskarri bihurketa dela-eta." -Basic.Settings.Advanced.Audio.BufferingTime="Audio Buffer Denbora" -Basic.Settings.Advanced.Video.ColorFormat="Margo Heuskarria" -Basic.Settings.Advanced.Video.ColorSpace="YUV Margo Tartea" -Basic.Settings.Advanced.Video.ColorRange="YUV Margo Maila" +Basic.Settings.Advanced.FormatWarning="Oharra: NV12 ez diren kolore formatuak grabaziorako dira gehienbat, eta ez daude gomendatuta transmisiorako. Transmisioak PUZ erabilpena handitu dezake kolore formatu bihurketa dela medio." +Basic.Settings.Advanced.Audio.BufferingTime="Audio bufferratze denbora" +Basic.Settings.Advanced.Video.ColorFormat="Kolore formatua" +Basic.Settings.Advanced.Video.ColorSpace="YUV kolore-espazioa" +Basic.Settings.Advanced.Video.ColorRange="YUV kolore-barrutia" Basic.Settings.Advanced.Video.ColorRange.Partial="Partziala" Basic.Settings.Advanced.Video.ColorRange.Full="Osoa" -Basic.Settings.Advanced.StreamDelay="Jario Atzerapena" -Basic.Settings.Advanced.StreamDelay.Duration="Iraupena (segunduak)" -Basic.Settings.Advanced.StreamDelay.Preserve="Heutsi ebaketa puntuari (handitu atzerapena) berrelkartzean" -Basic.Settings.Advanced.StreamDelay.MemoryUsage="Ustezko Oroimen Erabilpena: %1 MB" +Basic.Settings.Advanced.StreamDelay="Taansmisio-atzerapena" +Basic.Settings.Advanced.StreamDelay.Duration="Iraupena (segundoak)" +Basic.Settings.Advanced.StreamDelay.Preserve="Mantendu ebaketa puntua (handitu atzerapena) birkonektatzean" +Basic.Settings.Advanced.StreamDelay.MemoryUsage="Estimatutako memoria erabilpena: %1 MB" -Basic.AdvAudio="Audio Ezaugarri Aurreratuak" +Basic.AdvAudio="Audio propietate aurreratuak" Basic.AdvAudio.Name="Izena" Basic.AdvAudio.Volume="Bolumena (%)" -Basic.AdvAudio.Mono="Behera-nahastu Monora" +Basic.AdvAudio.Mono="Nahasketa monora murriztu" Basic.AdvAudio.Panning="Panoramika" -Basic.AdvAudio.SyncOffset="Aldiberetze Oreka (sm)" -Basic.AdvAudio.AudioTracks="Bideak" +Basic.AdvAudio.SyncOffset="Sinkronizazioaren desplazamendua (ms)" +Basic.AdvAudio.AudioTracks="Pistak" -Basic.Settings.Hotkeys="Lasterteklak" -Basic.Settings.Hotkeys.Pair="'%1'-rekin elkarbanatutako tekla konbinazioak aldatzaile bezala ekiten dute" +Basic.Settings.Hotkeys="Laster-teklak" +Basic.Settings.Hotkeys.Pair="'%1'-rekin egindako tekla konbinazioek txandakatze moduan jokatzen dute" -Basic.Hotkeys.StartStreaming="Hasi Jarioa" -Basic.Hotkeys.StopStreaming="Gelditu Jarioa" -Basic.Hotkeys.StartRecording="Hasi Grabaketa" -Basic.Hotkeys.StopRecording="Gelditu Grabaketa" -Basic.Hotkeys.SelectScene="Aldatu agerraldira" +Basic.Hotkeys.StartStreaming="Hasi transmisioa" +Basic.Hotkeys.StopStreaming="Gelditu transmisioa" +Basic.Hotkeys.StartRecording="Hasi Grabazioa" +Basic.Hotkeys.StopRecording="Gelditu grabazioa" +Basic.Hotkeys.SelectScene="Aldatu eszenara" Hotkeys.Insert="Txertatu" Hotkeys.Delete="Ezabatu" Hotkeys.Home="Hasiera" Hotkeys.End="Amaiera" -Hotkeys.PageUp="Orrialdean Gora" -Hotkeys.PageDown="Orrialdean Behera" -Hotkeys.NumLock="Zbk. Blokeoa" -Hotkeys.ScrollLock="Irristari Blokeoa" -Hotkeys.CapsLock="Hizki-larri Blokeoa" +Hotkeys.PageUp="Orria gora" +Hotkeys.PageDown="Orria behera" +Hotkeys.NumLock="Blok Zenb" +Hotkeys.ScrollLock="Blok korr" +Hotkeys.CapsLock="Blok Maius" Hotkeys.Backspace="Atzera" -Hotkeys.Tab="Tabulazioa" -Hotkeys.Print="Irarkitu" +Hotkeys.Tab="Tab" +Hotkeys.Print="Inprimatu" Hotkeys.Pause="Pausatu" Hotkeys.Left="Ezker" Hotkeys.Right="Eskuin" @@ -435,30 +480,30 @@ Hotkeys.Down="Behera" Hotkeys.Windows="Windows" Hotkeys.Super="Super" Hotkeys.Menu="Menua" -Hotkeys.Space="Tartea" -Hotkeys.NumpadNum="Zbk-panela %1" -Hotkeys.NumpadMultiply="Zbk-panela Biderkatu" -Hotkeys.NumpadDivide="Zbk-panela Zatitu" -Hotkeys.NumpadAdd="Zbk-panela Gehitu" -Hotkeys.NumpadSubtract="Zbk-panela Kendu" -Hotkeys.NumpadDecimal="Zbk-panela Hamarrena" -Hotkeys.AppleKeypadNum="%1 (Zbk-panela)" -Hotkeys.AppleKeypadMultiply="* (Zbk-panela)" -Hotkeys.AppleKeypadDivide="/ (Zbk-panela)" -Hotkeys.AppleKeypadAdd="+ (Zbk-panela)" -Hotkeys.AppleKeypadSubtract="- (Zbk-panela)" -Hotkeys.AppleKeypadDecimal=". (Zbk-panela)" -Hotkeys.AppleKeypadEqual="= (Zbk-panela)" +Hotkeys.Space="Zuriunea" +Hotkeys.NumpadNum="Zenb-teklatua %1" +Hotkeys.NumpadMultiply="Zenb-teklatuko biderketa" +Hotkeys.NumpadDivide="Zenb-teklatuaren Zatiketa" +Hotkeys.NumpadAdd="Zenb-teklatuaren gehiketa" +Hotkeys.NumpadSubtract="Zenb-teklatuaren kenketa" +Hotkeys.NumpadDecimal="Zenb-teklatuaren hamartarra" +Hotkeys.AppleKeypadNum="%1 (tekla)" +Hotkeys.AppleKeypadMultiply="* (tekla)" +Hotkeys.AppleKeypadDivide="/ (tekla)" +Hotkeys.AppleKeypadAdd="+ (tekla)" +Hotkeys.AppleKeypadSubtract="- (tekla)" +Hotkeys.AppleKeypadDecimal=". (tekla)" +Hotkeys.AppleKeypadEqual="= (tekla)" Hotkeys.MouseButton="Sagua %1" Mute="Mututu" -Unmute="Desmututu" +Unmute="Ez mututu" Push-to-mute="Sakatu-mututzeko" Push-to-talk="Sakatu-hitz-egiteko" SceneItemShow="Erakutsi '%1'" SceneItemHide="Ezkutatu '%1'" -OutputWarnings.NoTracksSelected="Gutxienez bide bat hautatu behar duzu" -OutputWarnings.MultiTrackRecording="Kontuz: Zenbait heuskarrik (FLV bezalakoak) ez dituzte bide anitz sostengatzen grabaketa bakoitzeko" +OutputWarnings.NoTracksSelected="Gutxienez pista bat hautatu behar duzu" +OutputWarnings.MultiTrackRecording="Oharra: Zenbait formatuk (esaterako FLV-k) ez ditu pista anitzak onartzen grabazioan" diff --git a/obs/data/locale/fi-FI.ini b/obs/data/locale/fi-FI.ini index 55da4cd..dc3ba0d 100644 --- a/obs/data/locale/fi-FI.ini +++ b/obs/data/locale/fi-FI.ini @@ -8,6 +8,7 @@ Cancel="Peruuta" Close="Sulje" Save="Tallenna" Discard="Hylkää" +Disable="Poista käytöstä" Yes="Kyllä" No="Ei" Add="Lisää" @@ -43,6 +44,10 @@ ResetOSXVSyncOnExit="Palauta OSX V-Sync suljettaessa" HighResourceUsage="Enkoodaus on ylikuormitettu! Harkitse laatu-asetusten laskemista tai käytä nopeampaa preset-asetusta." Transition="Siirtymä" QuickTransitions="Pikasiirtymät" +Left="Vasen" +Right="Oikea" +Top="Ylhäältä" +Bottom="Alhaalta" QuickTransitions.SwapScenes="Vaihda esikatselu- ja ulostulo-skenet siirtymän jälkeen" QuickTransitions.SwapScenesTT="Vaihda esikatselu- ja ulostulo-skenet siirtymän jälkeen (jos ulostulon alkuperäinen skene on yhä olemassa).\nTämä ei peruuta muutoksia joita on tehty alkuperäiseen skeneen." @@ -52,10 +57,16 @@ QuickTransitions.EditProperties="Kahdenna lähteet" QuickTransitions.EditPropertiesTT="Sallitaan lähteiden muuntaminen ja näkyvyyden muuttaminen muuttamatta ulostuloa samaa skeneä muokattaessa.\nTämä on käytössä vain jos 'Kahdenna skene' on käytössä.\nTietyt lähteet, kuten kaappauslaitteiden ja medialähteiden, eivät tue tätä, eikä niitä voi muokata erikseen.\nAsetuksen muuttaminen palauttaa nykyisen ulostulo-skenen (jos se on olemassa).\n\nVaroitus: Tämä saattaa vaatia järjestelmältä lisätehoa, koska lähteitä kahdennetaan." QuickTransitions.HotkeyName="Pikasiirtymä: %1" +Basic.AddTransition="Lisää muokattava siirtymä" +Basic.RemoveTransition="Poista muokattava siirtymä" +Basic.TransitionProperties="Siirtymän ominaisuudet" Basic.SceneTransitions="Skene-siirtymät" Basic.TransitionDuration="Kesto" Basic.TogglePreviewProgramMode="Studio-tila" +TransitionNameDlg.Text="Syötä siirtymän nimi" +TransitionNameDlg.Title="Siirtymän nimi" + TitleBar.Profile="Profiili" TitleBar.Scenes="Skenet" @@ -80,7 +91,7 @@ ConfirmRemove.Text="Haluatko varmasti poistaa '$1'?" Output.ConnectFail.Title="Yhdistäminen epäonnistui" Output.ConnectFail.BadPath="Viallinen polku tai yhteysosoite. Tarkista, että asetuksesi ovat kunnossa." Output.ConnectFail.ConnectFailed="Palvelimelle yhdistäminen epäonnistui" -Output.ConnectFail.InvalidStream="Kanavaan tai striimiavaimeen ei saada oikeuksia. Tämä saattaa johtua siitä, että kanava tai avain on kirjoitettu väärin tai siksi että palvelin luulee sinun olevan yhä kirjautuneena." +Output.ConnectFail.InvalidStream="Kanavaa tai lähetysavainta ei voida käyttää. Tarkista lähetysavain varmuuden vuoksi. Jos se kuitenkin on oikein, vika saattaa olla yhdistettävässä palvelimessa." Output.ConnectFail.Error="Odottamaton virhe ilmeni, kun palvelimelle yritettiin yhdistää. Lisää tietoa saat lokitiedostosta." Output.ConnectFail.Disconnected="Yhteys palvelimeen katkaistiin." @@ -99,8 +110,7 @@ LogReturnDialog.CopyURL="Kopioi osoite" LogReturnDialog.ErrorUploadingLog="Lokitiedoston lähetyksessä tapahtui virhe" LicenseAgreement="Käyttöoikeussopimus" -LicenseAgreement.PleaseReview="Lukaise lisenssin ehdot ennen kuin käytät OBS-ohjelmistoa. Käyttämällä tätä ohjelmaa tunnustat, että olet lukenut ja hyväksynyt GNU General Public License v2.0 ehdot. -Vieritä alas nähdäksesi loput sopimuksesta." +LicenseAgreement.PleaseReview="Lukaise lisenssin ehdot ennen kuin käytät OBS-ohjelmistoa. Käyttämällä tätä ohjelmaa tunnustat, että olet lukenut ja hyväksynyt GNU General Public License v2.0 ehdot. Vieritä alas nähdäksesi loput sopimuksesta." LicenseAgreement.ClickIAgreeToContinue="Jos hyväksyt sopimuksen ehdot, klikkaa 'Hyväksyn' jatkaaksesi. Sinun täytyy hyväksyä sopimus käyttääksesi OBS-ohjelmistoa." LicenseAgreement.IAgree="Hyväksyn" LicenseAgreement.Exit="Sulje" @@ -108,7 +118,7 @@ LicenseAgreement.Exit="Sulje" Remux.SourceFile="OBS-tallenne" Remux.TargetFile="Kohdetiedosto" Remux.Remux="Muunna" -Remux.RecordingPattern="OBS-tallenne (*.flv)" +Remux.OBSRecording="OBS-tallenne" Remux.FinishedTitle="Muunto on valmistunut" Remux.Finished="Tallenne muunnettu" Remux.FinishedError="Tallenne on muunnettu, mutta tiedosto saattaa olla keskeneräinen" @@ -134,6 +144,18 @@ Basic.DisplayCapture="Kaappaa monitori" Basic.Main.PreviewConextMenu.Enable="Näytä esikatselu" +Deinterlacing="Lomituksen poisto (Deinterlace)" +Deinterlacing.Discard="Ohita" +Deinterlacing.Retro="Retro" +Deinterlacing.Blend="Blend" +Deinterlacing.Blend2x="Blend 2x" +Deinterlacing.Linear="Linear" +Deinterlacing.Linear2x="Linear 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Ylin kenttä ensin" +Deinterlacing.BottomFieldFirst="Alin kenttä ensin" + Basic.Main.AddSceneDlg.Title="Lisää skene" Basic.Main.AddSceneDlg.Text="Aseta skenen nimi" @@ -199,6 +221,7 @@ Basic.TransformWindow.Alignment="Sijaintiin kohdistus" Basic.TransformWindow.BoundsType="Rajauslaatikon tyyppi" Basic.TransformWindow.BoundsAlignment="Rajauslaatikon kohdistus" Basic.TransformWindow.Bounds="Rajauslaatikon koko" +Basic.TransformWindow.Crop="Rajaa" Basic.TransformWindow.Alignment.TopLeft="Ylävasen" Basic.TransformWindow.Alignment.TopCenter="Yläkeski" @@ -285,6 +308,11 @@ Basic.Settings.General.Theme="Teema" Basic.Settings.General.Language="Kieli" Basic.Settings.General.WarnBeforeStartingStream="Näytä varmistus-ikkuna kun lähetys aloitetaan" Basic.Settings.General.WarnBeforeStoppingStream="Näytä varmistusikkuna kun lähetys pysäytetään" +Basic.Settings.General.Snapping="Lähteiden kiinnitys" +Basic.Settings.General.ScreenSnapping="Kiinnitä lähteitä ruudun reunaan" +Basic.Settings.General.CenterSnapping="Kiinnitä lähteitä vaaka- sekä pystysuunnan keskilinjaan" +Basic.Settings.General.SourceSnapping="Kiinnitä lähteitä muihin lähteisiin" +Basic.Settings.General.SnapDistance="Kiinnityksen herkkyys" Basic.Settings.Stream="Lähetys" Basic.Settings.Stream.StreamType="Lähetystyyppi" @@ -294,6 +322,7 @@ Basic.Settings.Output.Format="Tallennuksen muoto" Basic.Settings.Output.Encoder="Enkooderi" Basic.Settings.Output.SelectDirectory="Valitse tallennuskansio" Basic.Settings.Output.SelectFile="Valitse tallennustiedosto" +Basic.Settings.Output.EnforceBitrate="Rajoita bitrate lähetyspalvelun suosituksiin" Basic.Settings.Output.Mode="Ulostulon tila" Basic.Settings.Output.Mode.Simple="Yksinkertainen" Basic.Settings.Output.Mode.Adv="Kehittynyt" @@ -304,11 +333,16 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Lähetyksen laatu" Basic.Settings.Output.Simple.RecordingQuality.Small="Korkea laatu, keskikokoinen tiedostokoko" Basic.Settings.Output.Simple.RecordingQuality.HQ="Erottamaton laatu, suuri tiedostokoko" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Häviötön laatu, jättimäinen 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.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?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Häviötön laatu!" +Basic.Settings.Output.Simple.Warn.MultipleQSV="Varoitus: Et voi käyttää useampaa QSV-enkooderia lähettäessä ja tallentaessa samaan aikaan. Jos haluat tehdä molempia yhtä aikaa, vaihda lähetys tai tallennus-enkooderi." Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Laitteisto (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Laitteisto (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 matala CPU-käyttö, lisää tiedostokokoa)" Basic.Settings.Output.VideoBitrate="Kuvan bitrate" Basic.Settings.Output.AudioBitrate="Äänen bitrate" @@ -335,6 +369,8 @@ Basic.Settings.Output.Adv.Recording.Type="Tyyppi" Basic.Settings.Output.Adv.Recording.Type.Standard="Tavallinen" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Valinnainen lähtö (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Käytä lähetysenkooderia)" +Basic.Settings.Output.Adv.Recording.Filename="Tiedostonimen muoto" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Korvaa olemassa oleva" Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg ulostulon tyyppi" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Ulostulo osoitteeseen" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Ulostulo tiedostoon" @@ -355,6 +391,10 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Äänienkooderi" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Ääni-enkooderin asetukset" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Mukserin asetukset" +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 vuosi, neljä digits\n%YY vuoden kaksi viimeistä numeroa (00-99)\n%MM kuukauden desimaalin numero (01-12) \n%DD nolla-pehmustettu kuukauden päivänä (01-31)\n%hh Fi 24h muodossa (00-23)\n%mm minuutin (00-59) \n%ss toinen (00-61) \n%% A % sign\n%a Abbreviated arkipäivä name\n%A koko päivän name\n%b Abbreviated kuukauden name\n%B Kuukauden koko kuukauden, päivän name\n%d nolla-pehmustettu (01-31)\n%H tunnin 24h muodossa (00-23) \n%I Fi 12h muodossa (01-12)\n%m kuukauden desimaalilukuna (01-12)\n%M minuutin (00-59) \n%p AM tai PM designation\n%S toinen (00-61)\n%y vuoden kaksi viimeistä numeroa (00-99)\n%Y Year\n%z ISO 8601 offset UTC tai timezone\n tai abbreviation\n%Z Aikavyöhykkeen nimi tai abbreviation\n" + Basic.Settings.Video="Kuva" Basic.Settings.Video.Adapter="Näytönohjain:" Basic.Settings.Video.BaseResolution="Piirtoalueen resoluutio:" diff --git a/obs/data/locale/fr-FR.ini b/obs/data/locale/fr-FR.ini index 25c316b..82b1495 100644 --- a/obs/data/locale/fr-FR.ini +++ b/obs/data/locale/fr-FR.ini @@ -8,6 +8,7 @@ Cancel="Annuler" Close="Fermer" Save="Enregistrer" Discard="Ignorer les modifications" +Disable="Désactiver" Yes="Oui" No="Non" Add="Ajouter" @@ -22,7 +23,7 @@ Settings="Paramètres" Display="Affichage" Name="Nom" Exit="Quitter OBS" -Mixer="Table de mixage" +Mixer="Mixage audio" Browse="Parcourir" Mono="Mono" Stereo="Stéréo" @@ -43,6 +44,10 @@ ResetOSXVSyncOnExit="Réinitialiser le V-Sync d'OSX en quittant" HighResourceUsage="Encodage en surcharge ! Pensez à désactiver des paramètres vidéo ou à utiliser un préréglage d'encodage plus rapide." Transition="Transition" QuickTransitions="Transitions rapides" +Left="À gauche" +Right="À droite" +Top="En haut" +Bottom="En bas" QuickTransitions.SwapScenes="Permuter les scènes d'aperçu et de sortie après la transition" QuickTransitions.SwapScenesTT="Permute les scènes d'aperçu et de sortie après la transition (si la scène d'origine de la sortie existe toujours). \nCela n'annulera pas les modifications qui auront pu être faites sur la scène d'origine de la sortie." @@ -52,10 +57,16 @@ QuickTransitions.EditProperties="Dupliquer les sources" QuickTransitions.EditPropertiesTT="Lors de l'édition d'une même scène, permet de modifier les propriétés des sources sans modification de la sortie. \nCela ne peut être utilisé que si \"Dupliquer la scène\" est activé. \nCertaines sources (telles que les captures ou sources médias) ne supportent pas cela et ne peuvent être modifiés séparément. \nModifier ce paramètre réinitialisera la scène actuelle de sortie (si elle existe encore).\n\nAttention : parce que les sources seront dupliquées , cela peut nécessiter des ressources système ou vidéo supplémentaires." QuickTransitions.HotkeyName="Transition rapide : %1" -Basic.SceneTransitions="Transitions de scènes" +Basic.AddTransition="Ajouter une transition configurable" +Basic.RemoveTransition="Supprimer une transition configurable" +Basic.TransitionProperties="Propriétés de la transition" +Basic.SceneTransitions="Transition de scènes" Basic.TransitionDuration="Durée" Basic.TogglePreviewProgramMode="Mode Studio" +TransitionNameDlg.Text="Veuillez entrer le nom de la transition" +TransitionNameDlg.Title="Nom de la transition" + TitleBar.Profile="Profil" TitleBar.Scenes="Scènes" @@ -80,7 +91,7 @@ ConfirmRemove.Text="Êtes-vous sûr de vouloir supprimer « $1 » ?" 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é." Output.ConnectFail.ConnectFailed="Échec de la connexion au serveur" -Output.ConnectFail.InvalidStream="Impossible d'accéder à la chaîne ou à la clé spécifiée. Cela peut être causé par une chaîne/clé invalide ou par le serveur qui vous considère toujours connecté." +Output.ConnectFail.InvalidStream="Impossible d'accéder à la chaîne ou à la clé de stream spécifiée, veuillez revérifier votre clé de stream. Si celle-ci est correcte, il y a peut-être un problème de connexion au serveur." Output.ConnectFail.Error="Une erreur inattendue s'est produite en essayant de se connecter au serveur. Plus d'informations dans le fichier journal." Output.ConnectFail.Disconnected="Déconnecté du serveur." @@ -107,7 +118,7 @@ LicenseAgreement.Exit="Quitter" Remux.SourceFile="Enregistrement OBS" Remux.TargetFile="Fichier cible" Remux.Remux="Convertir" -Remux.RecordingPattern="Enregistrement OBS (*.flv)" +Remux.OBSRecording="Enregistrement OBS" Remux.FinishedTitle="Conversion terminée" Remux.Finished="L'enregistrement a été converti" Remux.FinishedError="L'enregistrement a été converti, mais le fichier peut être incomplet" @@ -133,6 +144,18 @@ Basic.DisplayCapture="Afficher la capture" Basic.Main.PreviewConextMenu.Enable="Activer l'aperçu" +Deinterlacing="Désentrelacement" +Deinterlacing.Discard="Abandonner" +Deinterlacing.Retro="Rétro" +Deinterlacing.Blend="Mélange" +Deinterlacing.Blend2x="Mélange 2x" +Deinterlacing.Linear="Linéaire" +Deinterlacing.Linear2x="Linéaire 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Champ du haut prioritaire" +Deinterlacing.BottomFieldFirst="Champ du bas prioritaire" + Basic.Main.AddSceneDlg.Title="Ajouter une scène" Basic.Main.AddSceneDlg.Text="Veuillez entrer le nom de la scène" @@ -198,6 +221,7 @@ Basic.TransformWindow.Alignment="Position de l'alignement" Basic.TransformWindow.BoundsType="Type de la fenêtre" Basic.TransformWindow.BoundsAlignment="Alignement de la fenêtre" Basic.TransformWindow.Bounds="Taille de la fenêtre" +Basic.TransformWindow.Crop="Rogner" Basic.TransformWindow.Alignment.TopLeft="En haut à gauche" Basic.TransformWindow.Alignment.TopCenter="Centrer en haut" @@ -284,6 +308,11 @@ Basic.Settings.General.Theme="Thème" Basic.Settings.General.Language="Langue" 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.Snapping="Déclenchement d'alignement des sources" +Basic.Settings.General.ScreenSnapping="Déclencher avec les bords de l'écran" +Basic.Settings.General.CenterSnapping="Déclencher avec le centre de l'écran" +Basic.Settings.General.SourceSnapping="Déclencher avec d'autres sources" +Basic.Settings.General.SnapDistance="Sensibilité du déclenchement" Basic.Settings.Stream="Flux" Basic.Settings.Stream.StreamType="Type de diffusion" @@ -293,6 +322,7 @@ Basic.Settings.Output.Format="Format d'enregistrement" 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.Mode="Mode de sortie" Basic.Settings.Output.Mode.Simple="Simple" Basic.Settings.Output.Mode.Adv="Avancé" @@ -303,11 +333,16 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Identique au stream" Basic.Settings.Output.Simple.RecordingQuality.Small="Haute qualité, taille de fichier moyenne" Basic.Settings.Output.Simple.RecordingQuality.HQ="Qualité indistinguable, grande taille de fichier " 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.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 ?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Avertissement de qualité sans perte" +Basic.Settings.Output.Simple.Warn.MultipleQSV="Attention : Vous ne pouvez pas utiliser plusieurs encodeurs QSV distincts lorsque vous streamez et enregistrez en même temps. Si vous voulez streamer et enregistrer en même temps, veuillez changer soit l'encodeur d'enregistrement, soit l'encodeur de streaming." Basic.Settings.Output.Simple.Encoder.Software="Logiciel (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Matériel (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Matériel (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Logiciel (préréglage x264 \"faible utilisation du CPU\", augmente la taille du fichier)" Basic.Settings.Output.VideoBitrate="Débit vidéo" Basic.Settings.Output.AudioBitrate="Débit audio" @@ -334,6 +369,8 @@ Basic.Settings.Output.Adv.Recording.Type="Type " Basic.Settings.Output.Adv.Recording.Type.Standard="Standard" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Sortie personnalisée (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Utiliser l'encodeur de flux)" +Basic.Settings.Output.Adv.Recording.Filename="Format du nom de fichier" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Écraser si le fichier existe" Basic.Settings.Output.Adv.FFmpeg.Type="Type de sortie FFmpeg" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Sortie vers une URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Sortie vers un fichier" @@ -354,6 +391,10 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Encodeur audio" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Paramètres de l'encodeur audio (le cas échéant)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Paramètres du muxer (le cas échéant)" +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 Année, 4 chiffres\n%YY Année, 2 derniers chiffres (00-99)\n%MM Mois en nombre (01-12)\n%DD Jour du mois(01-31)\n%hh Heure au format 24h (00-23)\n%mm Minute (00-59)\n%ss Seconde (00-61)\n%% Symbole %\n%a Jour de la semaine en abrégé\n%A Jour de la semaine\n%b Mois abrégé\n%B Mois\n%d Jour du mois (01-31)\n%H Heure au format 24h (00-23)\n%I Heure au format 12h (01-12)\n%m Mois en nombre (01-12)\n%M Minute (00-59)\n%p Désignation AM ou PM\n%S Seconde (00-61)\n%y Année, 2 derniers chiffres (00-99)\n%Y Année\n%z Nom ou abbréviation du fuseau horaire/n ou décalage ISO 8601 par rapport à l'UTC\n%Z Nom ou abbréviation du fuseau horaire\n" + Basic.Settings.Video="Vidéo" Basic.Settings.Video.Adapter="Périphérique vidéo :" Basic.Settings.Video.BaseResolution="Résolution de base (canvas) :" diff --git a/obs/data/locale/gl-ES.ini b/obs/data/locale/gl-ES.ini index 7782692..ea5f0f7 100644 --- a/obs/data/locale/gl-ES.ini +++ b/obs/data/locale/gl-ES.ini @@ -8,6 +8,7 @@ Cancel="Cancelar" Close="Pechar" Save="Gardar" Discard="Descartar" +Disable="Desactivar" Yes="Si" No="Non" Add="Engadir" @@ -34,8 +35,26 @@ Revert="Anular" Show="Mostrar" Hide="Agochar" Untitled="Sen título" +New="Novo" +Duplicate="Duplicar" +Enable="Activar" +DisableOSXVSync="Desactivar V-Sync en OSX" +Transition="Transición" +QuickTransitions="Transicións rápidas" +Left="Esquerda" +Right="Dereita" +Top="Arriba" +Bottom="Abaixo" +Basic.AddTransition="Engadir transición configurable" +Basic.RemoveTransition="Eliminar transición configurable" +Basic.TransitionProperties="Propiedades da transición" +Basic.SceneTransitions="Transicións de escena" +Basic.TransitionDuration="Duración" +Basic.TogglePreviewProgramMode="Modo de estudio" + +TransitionNameDlg.Title="Nome da transición" TitleBar.Profile="Perfil" TitleBar.Scenes="Escenas" @@ -46,7 +65,10 @@ NameExists.Text="O nome xa está en uso." NoNameEntered.Title="Por favor, insire un nome válido" NoNameEntered.Text="Non podes empregar nomes baleiros." +ConfirmStart.Title="Iniciar transmisión?" +ConfirmStop.Title="Deter transmisión?" +ConfirmStop.Text="Tes a certeza de querer deter a transmisión?" ConfirmExit.Title="Saír de OBS?" @@ -56,7 +78,6 @@ ConfirmRemove.Text="Tes a certeza de querer eliminar '$1'?" 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.ConnectFail.InvalidStream="Non se puido acceder á canle ou chave de retransmisión. Isto podería deberse a que a canle ou a chave non son válidas ou porque o servidor pensa que aínda tes unha sesión iniciada." 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." @@ -78,7 +99,6 @@ LicenseAgreement.Exit="Saír" Remux.SourceFile="Gravación OBS" Remux.TargetFile="Ficheiro de destino" Remux.Remux="Converter" -Remux.RecordingPattern="Gravación OBS (*.flv)" Remux.FinishedTitle="Conversión rematada" Remux.Finished="Gravando conversión" Remux.FinishedError="Gravación convertida, mais o ficheiro podería estar incompleto" @@ -104,6 +124,7 @@ Basic.DisplayCapture="Captura de pantalla" Basic.Main.PreviewConextMenu.Enable="Habilitar vista previa" + Basic.Main.AddSceneDlg.Title="Engadir escena" Basic.Main.AddSceneDlg.Text="Por favor, insire un nome para a escena" @@ -292,6 +313,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Axustes do codificador de ví Basic.Settings.Output.Adv.FFmpeg.AEncoder="Codificador de audio" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Axustes do codificador de audio (se existe)" + + Basic.Settings.Video="Vídeo" Basic.Settings.Video.Adapter="Adaptador de vídeo:" Basic.Settings.Video.DownscaleFilter="Filtro de redución:" @@ -343,6 +366,7 @@ Basic.Hotkeys.StopRecording="Deter gravación" Hotkeys.Insert="Inserir" Hotkeys.Delete="Eliminar" +Hotkeys.Home="Inicio" Hotkeys.NumLock="BLOQ NÚM" Hotkeys.ScrollLock="BLOQ DESPR" Hotkeys.CapsLock="BLOQ MAIÚS" diff --git a/obs/data/locale/he-IL.ini b/obs/data/locale/he-IL.ini new file mode 100644 index 0000000..3a59890 --- /dev/null +++ b/obs/data/locale/he-IL.ini @@ -0,0 +1,497 @@ + +Language="עברית" +Region="ישראל" + +OK="אישור" +Apply="החל" +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%)" +PreviewProjector="מקרן מסך מלא (תצוגה מקדימה)" +SceneProjector="מקרן מסך מלא (סצנה)" +SourceProjector="מקרן מסך מלא (מקור)" +Clear="נקה" +Revert="החזר לקדמותו" +Show="הצג" +Hide="הסתר" +Untitled="ללא כותרת" +New="חדש" +Duplicate="שכפל" +Enable="אפשר" +DisableOSXVSync="בטל סנכרון אנכי OSX" +ResetOSXVSyncOnExit="איפוס סנכרון אנכי OSX ביציאה" +HighResourceUsage="קידוד עמוס מידי! שקול להנמיך הגדרות וידאו או שימוש בקידוד מהיר יותר." +Transition="מעבר" +QuickTransitions="מעברים מהירים" +Left="שמאל" +Right="ימין" +Top="עליון" +Bottom="תחתון" + +QuickTransitions.SwapScenes="החלף סצינות תצוגה מקדימה/פלט לאחר המעבר" +QuickTransitions.SwapScenesTT="החלף הסצינות של התצוגה המקדימה ושל הפלט לאחר המעבר (באם הסצינה המקורית של הפלט עדיין קיימת). \n פעולה זו לא תבטל כל שינוי שייתכן ובוצע לסצינה המקורית של הפלט." +QuickTransitions.DuplicateScene="הכפל סצינה" +QuickTransitions.DuplicateSceneTT="בעת עריכת אותה הסצנה, מאפשר עריכת שינוי צורה/הנראות של המקורות מבלי לשנות את הפלט.\nבכדי לערוך מאפייני מקורות מבלי לשנות את הפלט, אפשר 'שכפל מקורות'.\nשינוי ערך זה יאפס את פלט הסצנה הנוכחית (אם הוא עדיין קיים)." +QuickTransitions.EditProperties="הכפל מקורות" +QuickTransitions.EditPropertiesTT="בזמן עריכת אותה הסצנה, מאפשר עריכת מאפיינים של מקורות ללא שינוי הפלט. \nפעולה זו אפשרית רק אם אפשרות 'שכפל סצינה' מופעלת. \nמקורות מסויימים (כגון לכידה או מקורות מדיה) לא תומכים באפשרות זו ולא ניתן לערוך אותם בנפרד. \nשינוי ערך זה יאפס את פלט הסצנה (אם עדיין קיים).\n\nאזהרה: בגלל שמקורות ישוכפלו, ייתכן ומשאבי מערכת או ווידאו נוספים יידרשו." +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="האם אתה בטוח שברצונך להפסיק את הזרמת הנתונים?" + +ConfirmExit.Title="יציאה מ-OBS?" +ConfirmExit.Text="תוכנת OBS פעילה כעת. כל הזרמת נתונים/הקלטות ייסגרו. האם אתה בטוח שאתה רוצה לצאת?" + +ConfirmRemove.Title="אשר הסרה" +ConfirmRemove.Text="האם אתה בטוח שברצונך להסיר את '$1'?" + +Output.ConnectFail.Title="ההתחברות נכשלה" +Output.ConnectFail.BadPath="URL לא חוקי של נתיב או חיבור. נא בדוק את ההגדרות שלך כדי לוודא כי הם נכונים." +Output.ConnectFail.ConnectFailed="ההתחברות לשרת נכשלה" +Output.ConnectFail.InvalidStream="לא ניתן להתחבר לערוץ שצויין או למפתח זרם הנתונים, נא בדוק שנית את מפתח זרם הנתונים. אם הוא נכון, ככל הנראה יש בעיה בהתחברות לשרת." +Output.ConnectFail.Error="אירעה שגיאה בלתי צפויה בעת ניסיון להתחבר לשרת. מידע נוסף בקובץ יומן הרישום." +Output.ConnectFail.Disconnected="התנתקת מהשרת." + +Output.RecordFail.Title="התחלת ההקלטה נכשלה" +Output.RecordFail.Unsupported="תבנית הפלט לא נתמכת או לא תומכת ביותר מרצועת שמע אחת. נא בדוק את ההגדרות ונסה שוב." +Output.RecordNoSpace.Title="אין די שטח דיסק" +Output.RecordNoSpace.Msg="אין די שטח דיסק כדי להמשיך הקלטה." +Output.RecordError.Title="שגיאה הקלטה" +Output.RecordError.Msg="אירעה שגיאה לא מוגדרת בזמן ההקלטה." + +Output.BadPath.Title="נתיב קובץ לא תקין" +Output.BadPath.Text="נתיב פלט הקובץ שהוגדר אינו חוקי. נא בדוק את הגדרות כדי לוודא שנתיב קובץ תקני נקבע." + +LogReturnDialog="עידכון יומן הצליח" +LogReturnDialog.CopyURL="העתק קישור" +LogReturnDialog.ErrorUploadingLog="עידכון קובץ יומן נכשל" + +LicenseAgreement="הסכם רשיון" +LicenseAgreement.PleaseReview="אנא קרא את תנאי רשיון לפני השימוש בתוכנית זו.בשימוש בתוכנית אתה מכיר בעובדה כי יש לקרוא ולהסכים לתנאים המופיעים ב הרישיון הציבורי הכללי של גנו v 2.0. נא גלול למטה כדי לראות את שאר ההסכם." +LicenseAgreement.ClickIAgreeToContinue="אם אתה מקבל את תנאי ההסכם, לחץ על אני מסכים בכדי להמשיך. עליך לקבל ההסכם בכדי להשתמש בתוכנת OBS." +LicenseAgreement.IAgree="אני מסכים" +LicenseAgreement.Exit="יציאה" + +Remux.SourceFile="הקלטת OBS" +Remux.TargetFile="קובץ היעד" +Remux.Remux="המרה" +Remux.FinishedTitle="המרה הסתיימה" +Remux.Finished="הקלטה הומרה" +Remux.FinishedError="הקלטה הומרה, אבל הקובץ עשוי להיות לא שלם" +Remux.SelectRecording="בחר הקלטת OBS…" +Remux.SelectTarget="בחר קובץ יעד…" +Remux.FileExistsTitle="קובץ היעד קיים" +Remux.FileExists="קובץ היעד קיים, האם ברצונך להחליפו?" +Remux.ExitUnfinishedTitle="המרה בתהליך" +Remux.ExitUnfinished="ההמרה לא הסתיימה, עצירה עכשיו עלולה להפוך את קובץ היעד לא שמיש. \n אתה בטוח שאתה רוצה לעצור את ההמרה?" + +UpdateAvailable="עידכון חדש זמין" +UpdateAvailable.Text="גירסה %1.%2.%3 זמין כעת. לחץ כאן כדי להוריד" + +Basic.DesktopDevice1="אודיו שולחן עבודה" +Basic.DesktopDevice2="אודיו שולחן עבודה 2" +Basic.AuxDevice1="מיקרופון/Aux" +Basic.AuxDevice2="מיקרופון/Aux 2" +Basic.AuxDevice3="מיקרופון/Aux 3" +Basic.AuxDevice4="מיקרופון/Aux 4" + +Basic.Scene="סצנה" +Basic.DisplayCapture="הצג לכידת מסך" + +Basic.Main.PreviewConextMenu.Enable="אפשר תצוגה מקדימה" + +Deinterlacing="ביטול שזירה" +Deinterlacing.Discard="אל תשמור" +Deinterlacing.Retro="רטרו" +Deinterlacing.Blend="מיזוג" +Deinterlacing.Blend2x="מיזוג 2x" +Deinterlacing.Linear="לינארי" +Deinterlacing.Linear2x="לינארי 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="שדה עליון ראשון" +Deinterlacing.BottomFieldFirst="שדה תחתון ראשון" + +Basic.Main.AddSceneDlg.Title="הוסף סצנה" +Basic.Main.AddSceneDlg.Text="אנא הזן את השם של הסצנה" + +Basic.Main.DefaultSceneName.Text="סצנה %1" + +Basic.Main.AddSceneCollection.Title="הוסף אוסף סצינות" +Basic.Main.AddSceneCollection.Text="נא הזן את שם אוסף הסצינות" + +Basic.Main.RenameSceneCollection.Title="שינוי שם של אוסף הסצינות" + +AddProfile.Title="הוסף פרופיל" +AddProfile.Text="אנא הזן את שם הפרופיל" + +RenameProfile.Title="שנה שם פרופיל" + +Basic.Main.PreviewDisabled="תצוגה מקדימה אינה זמינה כעת" + +Basic.SourceSelect="בחר/צור מקור" +Basic.SourceSelect.CreateNew="צור חדש" +Basic.SourceSelect.AddExisting="הוסף קיימים" +Basic.SourceSelect.AddVisible="הפוך מקור לגלוי" + +Basic.PropertiesWindow="מאפיינים עבור '%1'" +Basic.PropertiesWindow.AutoSelectFormat="%1 (בחירה אוטומטית: %2)" +Basic.PropertiesWindow.SelectColor="בחר צבע" +Basic.PropertiesWindow.SelectFont="בחר גופן" +Basic.PropertiesWindow.ConfirmTitle="הגדרות שונו" +Basic.PropertiesWindow.Confirm="יש שינויים שלא נשמרו. האם ברצונך לשמור אותם?" +Basic.PropertiesWindow.NoProperties="אין מאפיינים זמינים" +Basic.PropertiesWindow.AddFiles="הוסף קבצים" +Basic.PropertiesWindow.AddURL="הוסף נתיב/כתובת" +Basic.PropertiesWindow.AddEditableListFiles="הוסף קבצים '%1'" +Basic.PropertiesWindow.AddEditableListEntry="הוסף ערך ל- '%1'" +Basic.PropertiesWindow.EditEditableListEntry="ערוך ערך של '%1'" + +Basic.PropertiesView.FPS.Simple="ערכים פשוטים של פריימים לשניה" +Basic.PropertiesView.FPS.Rational="ערכים הגיוניים של פריימים לשניה" +Basic.PropertiesView.FPS.ValidFPSRanges="טווחים תקינים של פריימים לשניה:" + +Basic.InteractionWindow="אינטראקציה עם '%1'" + +Basic.StatusBar.Reconnecting="החיבור מנותק, התחברות מחדש ב- %2 שניות (ניסיון %1)" +Basic.StatusBar.AttemptingReconnect="מנסה להתחבר מחדש... (ניסיון %1)" +Basic.StatusBar.ReconnectSuccessful="חיבור מחדש הצליח" +Basic.StatusBar.Delay="השהיה (%1 שניות)" +Basic.StatusBar.DelayStartingIn="השהיה (מתחיל בעוד %1 שניות)" +Basic.StatusBar.DelayStoppingIn="השהיה (מסיים בעוד %1 שניות)" +Basic.StatusBar.DelayStartingStoppingIn="השהיה (מסיים בעוד %1 שניות, מתחיל בעוד %2 שניות)" + +Basic.Filters="מסננים" +Basic.Filters.AsyncFilters="מסנני אודיו/וידאו" +Basic.Filters.AudioFilters="מסנני שמע" +Basic.Filters.EffectFilters="מסנני אפקטים" +Basic.Filters.Title="מסננים עבור '%1'" +Basic.Filters.AddFilter.Title="שם מסנן" +Basic.Filters.AddFilter.Text="נא ציין את שם המסנן" + +Basic.TransformWindow="שנה פריט סצנה" +Basic.TransformWindow.Position="מיקום" +Basic.TransformWindow.Rotation="סיבוב" +Basic.TransformWindow.Size="גודל" +Basic.TransformWindow.Alignment="יישור לפי מיקום" +Basic.TransformWindow.BoundsType="סוג התיבה התוחמת" +Basic.TransformWindow.BoundsAlignment="יישור בתיבה תוחמת" +Basic.TransformWindow.Bounds="גודל התיבה התוחמת" +Basic.TransformWindow.Crop="חתוך" + +Basic.TransformWindow.Alignment.TopLeft="למעלה שמאל" +Basic.TransformWindow.Alignment.TopCenter="למעלה מרכז" +Basic.TransformWindow.Alignment.TopRight="למעלה ימין" +Basic.TransformWindow.Alignment.CenterLeft="מרכז שמאל" +Basic.TransformWindow.Alignment.Center="מרכז" +Basic.TransformWindow.Alignment.CenterRight="מרכז ימין" +Basic.TransformWindow.Alignment.BottomLeft="למטה שמאל" +Basic.TransformWindow.Alignment.BottomCenter="למטה מרכז" +Basic.TransformWindow.Alignment.BottomRight="למטה ימין" + +Basic.TransformWindow.BoundsType.None="ללא גבולות" +Basic.TransformWindow.BoundsType.MaxOnly="הגודל המרבי בלבד" +Basic.TransformWindow.BoundsType.ScaleInner="שנה גודל לגבולות הפנימיים" +Basic.TransformWindow.BoundsType.ScaleOuter="שנה גודל לגבולות החיצוניים" +Basic.TransformWindow.BoundsType.ScaleToWidth="שנה גודל לרוחב של הגבולות" +Basic.TransformWindow.BoundsType.ScaleToHeight="שנה גודל לגובה של הגבולות" +Basic.TransformWindow.BoundsType.Stretch="מתח לגבולות" + +Basic.Main.AddSourceHelp.Title="אין אפשרות להוסיף מקור" +Basic.Main.AddSourceHelp.Text="צריכה להיות לפחות סצנה אחת בכדי להוסיף מקור." + +Basic.Main.Scenes="סצינות" +Basic.Main.Sources="מקורות" +Basic.Main.Connecting="מתחבר..." +Basic.Main.StartRecording="התחל הקלטה" +Basic.Main.StartStreaming="התחל הזרמת נתונים" +Basic.Main.StopRecording="עצור הקלטה" +Basic.Main.StopStreaming="עצור זרם נתונים" +Basic.Main.ForceStopStreaming="עצור זרם נתונים (בטל השהייה)" + +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.Settings="הגדרות(&S)" +Basic.MainMenu.File.ShowSettingsFolder="הצג תיקיית הגדרות" +Basic.MainMenu.File.ShowProfileFolder="הצג תיקיית פרופיל" +Basic.MainMenu.AlwaysOnTop="תמיד עליון(&A)" +Basic.MainMenu.File.Exit="יציאה(&E)" + +Basic.MainMenu.Edit="ערוך(&E)" +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.Transform="שנה(&T)" +Basic.MainMenu.Edit.Transform.EditTransform="ערוך שינוי...(&E)" +Basic.MainMenu.Edit.Transform.ResetTransform="אפס שינוי(&R)" +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)" +Basic.MainMenu.Edit.Transform.FitToScreen="התאם למסך(&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="מתח לגודל המסך(&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="מרכז למסך(&C)" +Basic.MainMenu.Edit.Order="סדר(&O)" +Basic.MainMenu.Edit.Order.MoveUp="הזז למעלה(&U)" +Basic.MainMenu.Edit.Order.MoveDown="הזז למטה(&D)" +Basic.MainMenu.Edit.Order.MoveToTop="הזז לקצה עליון(&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="הזז לקצה תחתון(&B)" +Basic.MainMenu.Edit.AdvAudio="מאפייני קול מתקדמים(&A)" + +Basic.MainMenu.SceneCollection="אוסף סצינות(&S)" +Basic.MainMenu.Profile="פרופיל(&P)" + +Basic.MainMenu.Help="עזרה(&H)" +Basic.MainMenu.Help.Website="בקר אתר(&W)" +Basic.MainMenu.Help.Logs="קבצי יומן רישום(&L)" +Basic.MainMenu.Help.Logs.ShowLogs="הצג קבצי יומן רישום(&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="העלה קובץ יומן רישום נוכחי(&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="העלה קובץ יומן רישום אחרון(&L)" +Basic.MainMenu.Help.Logs.ViewCurrentLog="הצג את יומן הרישום הנוכחי(&V)" +Basic.MainMenu.Help.CheckForUpdates="בדוק עדכונים" + +Basic.Settings.ProgramRestart="יש להפעיל מחדש את התוכנה בכדי שהגדרות האלה ייכנסו לתוקף." +Basic.Settings.ConfirmTitle="אשר את השינויים" +Basic.Settings.Confirm="קיימים שינויים שלא נשמרו. האם לשמור שינויים?" + +Basic.Settings.General="כללי" +Basic.Settings.General.Theme="ערכת עיצוב" +Basic.Settings.General.Language="שפה" +Basic.Settings.General.WarnBeforeStartingStream="הצג תיבת דו-שיח לאישור בעת הפעלת זרם נתונים" +Basic.Settings.General.WarnBeforeStoppingStream="הצג תיבת דו-שיח לאישור בעת עצירת זרם נתונים" + +Basic.Settings.Stream="זרם נתונים" +Basic.Settings.Stream.StreamType="סוג זרם נתונים" + +Basic.Settings.Output="פלט" +Basic.Settings.Output.Format="פורמט הקלטה" +Basic.Settings.Output.Encoder="מקודד" +Basic.Settings.Output.SelectDirectory="בחר ספריית הקלטות" +Basic.Settings.Output.SelectFile="בחר קובץ הקלטה" +Basic.Settings.Output.Mode="מצב פלט" +Basic.Settings.Output.Mode.Simple="פשוט" +Basic.Settings.Output.Mode.Adv="מתקדם" +Basic.Settings.Output.Mode.FFmpeg="פלט FFmpeg" +Basic.Settings.Output.Simple.SavePath="נתיב הקלטה" +Basic.Settings.Output.Simple.RecordingQuality="איכות הקלטה" +Basic.Settings.Output.Simple.RecordingQuality.Stream="כמו זרם הנתונים" +Basic.Settings.Output.Simple.RecordingQuality.Small="איכות גבוהה, גודל קובץ בינוני" +Basic.Settings.Output.Simple.RecordingQuality.HQ="איכות בלתי מובחנת, גודל קובץ גדול" +Basic.Settings.Output.Simple.RecordingQuality.Lossless="ללא אובדן איכות, גודל קובץ עצום" +Basic.Settings.Output.Simple.Warn.Encoder="אזהרה: הקלטה עם מקודד תוכנה באיכות שונה מאשר זרם הנתונים ידרוש שימוש במשאבי מעבד נוספים אם מתבצעת הקלטה וזרם נתונים במקביל." +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)" +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.EncoderPreset="מקודד קבוע מראש (גבוה = מעט מעבד)" +Basic.Settings.Output.CustomEncoderSettings="הגדרות מקודד מותאמות אישית" +Basic.Settings.Output.CustomMuxerSettings="הגדרות ממיר מותאמות אישית" +Basic.Settings.Output.NoSpaceFileName="צור שם קובץ ללא רווחים" + +Basic.Settings.Output.Adv.Rescale="שנה קנה מידה של הפלט" +Basic.Settings.Output.Adv.AudioTrack="ערוץ שמע" +Basic.Settings.Output.Adv.Streaming="זרם נתונים" +Basic.Settings.Output.Adv.ApplyServiceSettings="אכוף הגדרות מקודד של שירות זרם נתונים" +Basic.Settings.Output.Adv.Audio.Track1="ערוץ 1" +Basic.Settings.Output.Adv.Audio.Track2="ערוץ 2" +Basic.Settings.Output.Adv.Audio.Track3="ערוץ 3" +Basic.Settings.Output.Adv.Audio.Track4="ערוץ 4" + +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.Filename="תבנית שם קובץ" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="דרוס אם קובץ קיים" +Basic.Settings.Output.Adv.FFmpeg.Type="סוג פלט FFmpeg" +Basic.Settings.Output.Adv.FFmpeg.Type.URL="פלט לקישור" +Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="פלט לקובץ" +Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="תבניות הקלטה נפוצות" +Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="כל הקבצים" +Basic.Settings.Output.Adv.FFmpeg.SavePathURL="נתיב קובץ או קישור" +Basic.Settings.Output.Adv.FFmpeg.Format="פורמט קובץ" +Basic.Settings.Output.Adv.FFmpeg.FormatAudio="שמע" +Basic.Settings.Output.Adv.FFmpeg.FormatVideo="וידאו" +Basic.Settings.Output.Adv.FFmpeg.FormatDefault="פורמט ברירת מחדל" +Basic.Settings.Output.Adv.FFmpeg.FormatDesc="תיאור סוג הקובץ" +Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="ניחוש הקודקד של השמע/וידאו מנתיב קובץ או קישור" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="מקודד ברירת המחדל" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="שתק את המקודד" +Basic.Settings.Output.Adv.FFmpeg.VEncoder="מקודד וידאו" +Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="הגדרות מקודד וידאו (אם בכלל)" +Basic.Settings.Output.Adv.FFmpeg.AEncoder="מקודד אודיו" +Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="הגדרות מקודד שמע (אם בכלל)" +Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="הגדרות Muxer (אם בכלל)" + +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%% A % סימן\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="מתאם תצוגה:" +Basic.Settings.Video.BaseResolution="רזולציית (קנבס) בסיס:" +Basic.Settings.Video.ScaledResolution="רזולוציית (קנה מידה) פלט:" +Basic.Settings.Video.DownscaleFilter="מסנן מצמצם:" +Basic.Settings.Video.DisableAeroWindows="בטל את Aero (Windows בלבד)" +Basic.Settings.Video.FPS="פריימים לשנייה:" +Basic.Settings.Video.FPSCommon="ערכים משותפים לפריימים לשניה" +Basic.Settings.Video.FPSInteger="ערך מספר שלם של פריימים לשניה" +Basic.Settings.Video.FPSFraction="ערך שברים של פריימים לשניה" +Basic.Settings.Video.Numerator="מונה:" +Basic.Settings.Video.Denominator="מכנה:" +Basic.Settings.Video.Renderer="מעבד:" +Basic.Settings.Video.InvalidResolution="ערך רזולוציה לא חוקי. חייב להיות [width]x[height] (לדוגמה 1920x1080)" +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.Audio="אודיו" +Basic.Settings.Audio.SampleRate="קצב דגימה" +Basic.Settings.Audio.Channels="ערוצים" +Basic.Settings.Audio.DesktopDevice="התקן שמע בשולחן עבודה" +Basic.Settings.Audio.DesktopDevice2="התקן שמע בשולחן עבודה 2" +Basic.Settings.Audio.AuxDevice="התקן שמע מיקרופון/עזר" +Basic.Settings.Audio.AuxDevice2="התקן שמע מיקרופון/עזר 2" +Basic.Settings.Audio.AuxDevice3="התקן שמע מיקרופון/עזר 3" +Basic.Settings.Audio.EnablePushToMute="אפשר לחץ-להשתקה" +Basic.Settings.Audio.PushToMuteDelay="השהיית לחץ-להשתקה" +Basic.Settings.Audio.EnablePushToTalk="הפעל לחץ-כדי-לדבר" +Basic.Settings.Audio.PushToTalkDelay="השהיית לחץ-כדי-לדבר" +Basic.Settings.Audio.UnknownAudioDevice="[התקן לא מחובר או לא זמין]" + +Basic.Settings.Advanced="הגדרות מתקדמות" +Basic.Settings.Advanced.FormatWarning="אזהרה: תבניות צבע שונות מ-NV12 נועדו בעיקר עבור הקלטה, והם אינם מומלצות בעת הזרמת נתונים. הזרמת נתונים עלולה לגרום למשאבי עיבוד מוגברים כתוצאה מהמרת תבנית צבע." +Basic.Settings.Advanced.Audio.BufferingTime="זמן אוגר שמע" +Basic.Settings.Advanced.Video.ColorFormat="תבנית צבע" +Basic.Settings.Advanced.Video.ColorSpace="מרחב צבע YUV" +Basic.Settings.Advanced.Video.ColorRange="טווח צבעים YUV" +Basic.Settings.Advanced.Video.ColorRange.Partial="חלקי" +Basic.Settings.Advanced.Video.ColorRange.Full="מלא" +Basic.Settings.Advanced.StreamDelay="השהיית זרם נתונים" +Basic.Settings.Advanced.StreamDelay.Duration="משך זמן (בשניות)" +Basic.Settings.Advanced.StreamDelay.Preserve="שמר נקודת חיתוך (השהייה מוגדלת) בעת חיבור מחדש" +Basic.Settings.Advanced.StreamDelay.MemoryUsage="שימוש זיכרון משוער: %1 MB" + +Basic.AdvAudio="מאפייני קול מתקדמים" +Basic.AdvAudio.Name="שם" +Basic.AdvAudio.Volume="עוצמת קול (%)" +Basic.AdvAudio.Mono="הפוך למונו" +Basic.AdvAudio.Panning="איזון" +Basic.AdvAudio.SyncOffset="היסט סינכרון (מילישניות)" +Basic.AdvAudio.AudioTracks="ערוצים" + +Basic.Settings.Hotkeys="מקשי קיצור" +Basic.Settings.Hotkeys.Pair="צירופי מקשים משותים עם '%1' משמשים כמחליפים" + +Basic.Hotkeys.StartStreaming="התחל הזרמת נתונים" +Basic.Hotkeys.StopStreaming="עצור הזרמת נתונים" +Basic.Hotkeys.StartRecording="התחל הקלטה" +Basic.Hotkeys.StopRecording="עצור הקלטה" +Basic.Hotkeys.SelectScene="עבור לסצנה" + +Hotkeys.Insert="הוסף" +Hotkeys.Delete="מחק" +Hotkeys.Home="בית" +Hotkeys.End="סיום" +Hotkeys.PageUp="דף למעלה" +Hotkeys.PageDown="דף למטה" +Hotkeys.NumLock="Num Lock" +Hotkeys.ScrollLock="Scroll Lock" +Hotkeys.CapsLock="Caps lock" +Hotkeys.Backspace="מחק תו" +Hotkeys.Tab="טאב" +Hotkeys.Print="הדפס" +Hotkeys.Pause="השהה" +Hotkeys.Left="שמאל" +Hotkeys.Right="ימין" +Hotkeys.Up="למעלה" +Hotkeys.Down="למטה" +Hotkeys.Windows="Windows" +Hotkeys.Super="סופר" +Hotkeys.Menu="תפריט" +Hotkeys.Space="רווח" +Hotkeys.NumpadNum="מקשי מספרים %1" +Hotkeys.NumpadMultiply="מקשי מספרים הכפל" +Hotkeys.NumpadDivide="מקשי מספרים חלק" +Hotkeys.NumpadAdd="מקשי מספרים הוסף" +Hotkeys.NumpadSubtract="מקשי מספרים חסר" +Hotkeys.NumpadDecimal="מקשי מספרים עשרוני" +Hotkeys.AppleKeypadNum="%1 (מקלדת נומרית)" +Hotkeys.AppleKeypadMultiply="* (מקלדת נומרית)" +Hotkeys.AppleKeypadDivide="/ (מקלדת נומרית)" +Hotkeys.AppleKeypadAdd="+ (מקלדת נומרית)" +Hotkeys.AppleKeypadSubtract="-(מקלדת נומרית)" +Hotkeys.AppleKeypadDecimal=". (מקלדת נומרית)" +Hotkeys.AppleKeypadEqual="= (מקלדת נומרית)" +Hotkeys.MouseButton="עכבר %1" + +Mute="השתק" +Unmute="בטל השתקה" +Push-to-mute="לחץ-להשתקה" +Push-to-talk="לחץ-כדי-לדבר" + +SceneItemShow="הצג '%1'" +SceneItemHide="הסתר '%1'" + +OutputWarnings.NoTracksSelected="עליך לבחור ערוץ אחד לפחות" +OutputWarnings.MultiTrackRecording="אזהרה: תבניות מסוימות (כגון FLV) אינם תומכים במספר רצועות להקלטה" + diff --git a/obs/data/locale/hr-HR.ini b/obs/data/locale/hr-HR.ini index 6047fbc..5bed0d7 100644 --- a/obs/data/locale/hr-HR.ini +++ b/obs/data/locale/hr-HR.ini @@ -8,6 +8,7 @@ Cancel="Otkaži" Close="Zatvori" Save="Sačuvaj" Discard="Odbaci" +Disable="Onemogući" Yes="Da" No="Ne" Add="Dodaj" @@ -43,6 +44,10 @@ ResetOSXVSyncOnExit="Povrati OSX vertikalnu sinhronizaciju po izlasku" HighResourceUsage="Enkodiranje preopterećeno! Razmotrite snižavanje video podešavanja ili korišćenje bržeg šablona za enkodiranje." Transition="Prelaz" QuickTransitions="Brzi prelazi" +Left="Sleva" +Right="Zdesna" +Top="Odozgo" +Bottom="Odozdo" QuickTransitions.SwapScenes="Zameni scene pregleda/izlaza nakon prelaza" QuickTransitions.SwapScenesTT="Zamenjuje scene pregleda i izlaza nakon prelaza (ako originalna scena izlaza još uvek postoji).\nOvo neće poništiti promene koje su načinjene nad originalnom scenom izlaza." @@ -52,10 +57,16 @@ QuickTransitions.EditProperties="Dupliraj izvore" QuickTransitions.EditPropertiesTT="Kada se menja ista scena, dozvoli promenu svojstava izvora bez promene izlaza.\nOvo može biti upotrebljeno samo ako je 'Dupliraj scene' omogućeno.\nOdređeni izvori (kao što su video hvatanja ili medija izvori) ne podržavaju ovo i ne mogu biti izmenjeni zasebno.\nPromena ove vrednosti će poništiti trenutnu scenu izlaza (ako i dalje postoji).\n\nUpozorenje: Zbog toga što izvori mogu biti duplirani, ovo može zahtevati dodatne sistemske ili video resurse." QuickTransitions.HotkeyName="Brzi prelaz: %1" +Basic.AddTransition="Dodaj podesivi prelaz" +Basic.RemoveTransition="Ukloni podesivi prelaz" +Basic.TransitionProperties="Svojstva prelaza" Basic.SceneTransitions="Prelazi scena" Basic.TransitionDuration="Trajanje" Basic.TogglePreviewProgramMode="Studijski režim" +TransitionNameDlg.Text="Molim unesite ime prelaza" +TransitionNameDlg.Title="Ime prelaza" + TitleBar.Profile="Profil" TitleBar.Scenes="Scene" @@ -80,7 +91,7 @@ ConfirmRemove.Text="Da li ste sigurni da želite izbaciti '$1'?" Output.ConnectFail.Title="Neuspešno povezivanje" Output.ConnectFail.BadPath="Neispravna putanja ili URL konekcije. Molim proverite vaša podešavanja da potvrdite njihovu ispravnost." Output.ConnectFail.ConnectFailed="Neuspešno povezivanje na server" -Output.ConnectFail.InvalidStream="Ne mogu pristupiti određenom kanalu ili strim ključu. Ovo je moguće, zato što je uneti ključ ili kanal pogrešan, ili zato što server misli da ste i dalje ulogovani." +Output.ConnectFail.InvalidStream="Ne mogu pristupiti navedenom kanalu ili strim ključu, molim proverite vaš strim ključ. Ako je ispravan, možda postoji problem pri povezivanju na server." Output.ConnectFail.Error="Neočekivana greška u povezivanju sa serverom. Više informacija se nalazi u log datoteci." Output.ConnectFail.Disconnected="Prekinuta veza sa serverom." @@ -107,7 +118,6 @@ LicenseAgreement.Exit="Izlaz" Remux.SourceFile="OBS snimak" Remux.TargetFile="Datoteka" Remux.Remux="Remux" -Remux.RecordingPattern="OBS snimci (*.flv)" Remux.FinishedTitle="Remux završen" Remux.Finished="Završen remux snimka" Remux.FinishedError="Remux završen, ali datoteka možda nije kompletirana" @@ -133,6 +143,18 @@ Basic.DisplayCapture="Prikaži ulaz" Basic.Main.PreviewConextMenu.Enable="Omogući pregled" +Deinterlacing="Deinterlejsing" +Deinterlacing.Discard="Odbaci" +Deinterlacing.Retro="Retro" +Deinterlacing.Blend="Stapanje" +Deinterlacing.Blend2x="Stapanje 2x" +Deinterlacing.Linear="Linearno" +Deinterlacing.Linear2x="Linearno 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Prvo gornje polje" +Deinterlacing.BottomFieldFirst="Prvo donje polje" + Basic.Main.AddSceneDlg.Title="Dodaj scenu" Basic.Main.AddSceneDlg.Text="Molim unesite ime scene" @@ -198,6 +220,7 @@ Basic.TransformWindow.Alignment="Poziciono poravnanje" Basic.TransformWindow.BoundsType="Tip okvira" Basic.TransformWindow.BoundsAlignment="Poravnanje u okviru" Basic.TransformWindow.Bounds="Veličina okvira" +Basic.TransformWindow.Crop="Isecanje" Basic.TransformWindow.Alignment.TopLeft="Gore levo" Basic.TransformWindow.Alignment.TopCenter="Gore centar" @@ -284,6 +307,11 @@ Basic.Settings.General.Theme="Tema" Basic.Settings.General.Language="Jezik" Basic.Settings.General.WarnBeforeStartingStream="Prikaži prozor za potvrdu kada se započinju strimovi" Basic.Settings.General.WarnBeforeStoppingStream="Prikaži prozor za potvrdu kada se zaustavljaju strimovi" +Basic.Settings.General.Snapping="Poravnavanje privlačenjem izvora" +Basic.Settings.General.ScreenSnapping="Privuci izvore ivici ekrana" +Basic.Settings.General.CenterSnapping="Privuci izvore horizontalnoj i vertikalnoj sredini" +Basic.Settings.General.SourceSnapping="Privlačenje izvora ka drugim izvorima" +Basic.Settings.General.SnapDistance="Osetljivost privlačenja" Basic.Settings.Stream="Strim" Basic.Settings.Stream.StreamType="Vrsta strima" @@ -293,6 +321,7 @@ Basic.Settings.Output.Format="Format snimanja" Basic.Settings.Output.Encoder="Enkoder" Basic.Settings.Output.SelectDirectory="Odaberi direktorijum za snimanje" Basic.Settings.Output.SelectFile="Odaberi datoteku za snimanje" +Basic.Settings.Output.EnforceBitrate="Sprovedi ograničenja u protoku striming servisa" Basic.Settings.Output.Mode="Režim izlaza" Basic.Settings.Output.Mode.Simple="Jednostavno" Basic.Settings.Output.Mode.Adv="Napredno" @@ -303,11 +332,16 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Isto kao strim" Basic.Settings.Output.Simple.RecordingQuality.Small="Visoki kvalitet, osrednja veličina datoteke" Basic.Settings.Output.Simple.RecordingQuality.HQ="Kvalitet sa neprimetnim razlikama, velika datoteka" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Kvalitet bez gubitka, izričito velika datoteka" +Basic.Settings.Output.Simple.Warn.VideoBitrate="Upozorenje: Video protok strima će biti postavljen na %1, što je gornja granica za trenutni striming servis. Ako ste sigurni da želite ići preko %1, omogućite napredne opcije enkodera i isključite \"Sprovedi ograničenja u protoku striming servisa\"." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Upozorenje: Zvučni protok strima će biti postavljen na %1, što je gornja granica za trenutni striming servis. Ako ste sigurni da želite ići preko %1, omogućite napredne opcije enkodera i isključite \"Sprovedi ograničenja u protoku striming servisa\"." Basic.Settings.Output.Simple.Warn.Encoder="Upozorenje: Snimanje sa softverskim enkoderom drugačijeg kvaliteta u odnosu na strim će zahtevati dodatnu procesorsku snagu ako strimujete i snimate u isto vreme." Basic.Settings.Output.Simple.Warn.Lossless="Upozorenje: Kvalitet bez gubitka stvara izričito velike datoteke! Kvalitet bez gubitka može koristiti više od 7 gigabajta prostora na disku po minutu pri visokim rezolucijama i framerate-om. Kvalitet bez gubitka nije preporučen za duže snimanje osim ako imate veliku količinu slobodnog prostora na disku." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Da li ste sigurni da želite koristiti kvalitet bez gubitka?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Upozorenje za kvalitet bez gubitka!" +Basic.Settings.Output.Simple.Warn.MultipleQSV="Upozorenje: Ne možete koristi više odvojenih QSV enkodera kada emitujete i snimate u isto vreme. Ako želite da emitujete i snimate u isto vreme, molim promenite ili enkoder snimanja ili enkoder emitovanja." Basic.Settings.Output.Simple.Encoder.Software="Softverski (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Mašinski (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Mašinski (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softverski (x264 niska upotreba procesora, povećava veličinu datoteke)" Basic.Settings.Output.VideoBitrate="Protok videa" Basic.Settings.Output.AudioBitrate="Protok zvuka" @@ -334,6 +368,8 @@ Basic.Settings.Output.Adv.Recording.Type="Vrsta" Basic.Settings.Output.Adv.Recording.Type.Standard="Uobičajeni" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Prilagođeni izlaz (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Koristi strim enkoder)" +Basic.Settings.Output.Adv.Recording.Filename="Oblikovanje imena datoteke" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Prepiši ako postoji datoteka" Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg vrsta ispisa" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Ispis na URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Ispis u datoteku" @@ -354,6 +390,10 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Zvučni enkoder" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Podešavanja zvučnog enkodera (ako postoje)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Podešavanja muxer-a (ako postoje)" +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 Godina, četiri cifre\n%YY Godina, poslednje dve cifre (00-99)\n%MM Mesec kao decimalni broj (01-12)\n%DD Dan u mesecu, sa nulom ispred (01-31)\n%hh Sat u 24-časovnom zapisu (00-23)\n%mm Minut (00-59)\n%ss Sekunda (00-61)\n%% Znak procenta\n%a Skraćeno ime dana u nedelji\n%A Puno ime dana u nedelji\n%b Skraćeno ime meseca\n%B Puno ime meseca\n%d Dan u mesecu, sa nulom ispred (01-31)\n%H Sat u 24-časovnom zapisu (00-23)\n%I Sat u 12-časovnom zapisu (01-12)\n%m Mesec kao decimalni broj (01-12)\n%M Minut (00-59)\n%p Oznaka za pre ili posle podne\n%S Sekunda (00-61)\n%y Godina, poslednje dve cifre (00-99)\n%Y Godina\n%z ISO 8601 odstupanje od UTC ili ime\n vremenske zone ili skraćenica\n%Z Ime vremenske zone ili skraćenica\n" + Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Video adapter:" Basic.Settings.Video.BaseResolution="Osnovna (površinska) rezolucija:" diff --git a/obs/data/locale/hu-HU.ini b/obs/data/locale/hu-HU.ini index 8dd9c1b..2759f5b 100644 --- a/obs/data/locale/hu-HU.ini +++ b/obs/data/locale/hu-HU.ini @@ -8,6 +8,7 @@ Cancel="Mégse" Close="Bezár" Save="Mentés" Discard="Elvet" +Disable="Letiltás" Yes="Igen" No="Nem" Add="Hozzáadás" @@ -26,7 +27,7 @@ Mixer="Keverő" Browse="Tallózás" Mono="Mono" Stereo="Sztereó" -DroppedFrames="Ejtett Képkockák: %1 (%2 %)" +DroppedFrames="Ejtett képkockák: %1 (%2 %)" PreviewProjector="Teljes képernyős projektor (Előnézet)" SceneProjector="Teljes képernyős projektor (Jelenet)" SourceProjector="Teljes képernyős projektor (Forrás)" @@ -38,23 +39,33 @@ Untitled="Névtelen" New="Új" Duplicate="Másolat készítése" Enable="Engedélyezés" -DisableOSXVSync="OSX V-Sync Kikapcsolása" +DisableOSXVSync="OSX V-Sync kikapcsolása" ResetOSXVSyncOnExit="OSX V-Sync visszaállítása kilépéskor" HighResourceUsage="Túlterhelt kódolás! Fontolja meg a videó beállítások csökkentését vagy egy gyorsabb kódoló készletre váltást." Transition="Átmenet" -QuickTransitions="Gyors Átmenetek" +QuickTransitions="Gyors átmenetek" +Left="Bal" +Right="Jobb" +Top="Felső" +Bottom="Alsó" QuickTransitions.SwapScenes="Előnézeti/Kimeneti Jelenetek cseréje átmenet után" QuickTransitions.SwapScenesTT="Az előnézet és a kimeneti jelenet cseréje átmenet után (ha a kimenet eredeti jelenete még létezik).\nEz nincs kihatással a kimenet eredeti jelenetére." -QuickTransitions.DuplicateScene="Jelenet Kettőzése" +QuickTransitions.DuplicateScene="Jelenet kettőzése" QuickTransitions.DuplicateSceneTT="Ugyanazon jelenet szerkesztésekor, lehetősége van átformálni ás a láthatóságát megváltoztatni a kimenetnek.\nA kimeneti forrás tulajdonságainak módosításához, engedélyezze a 'Forrás Kettőzését'.\nAz érték megváltoztatásakor a jelenlegi kimeneti jelenetet visszaállítja (ha még létezik)." -QuickTransitions.EditProperties="Forrás Kettőzése" +QuickTransitions.EditProperties="Forrás kettőzése" QuickTransitions.EditPropertiesTT="Ugyanazon jelenet szerkesztésekor, lehetősége van a kimeneti források tulajdonságainak módosítására.\nCsak akkor használható ha a 'Jelenet Kettőzés' engedélyezve van.\nEgyes források (a felvevő és média források) nem támogatják ezt és nem lehet őket külön szerkeszteni.\nAz érték megváltoztatásakor az aktuális kimeneti jelenetet visszaállítja (ha az még létezik).\n\nFigyelem: A források megkettőzése, extra erőforrásigénnyel járhat." -QuickTransitions.HotkeyName="Gyors Átmenet: %1" +QuickTransitions.HotkeyName="Gyors átmenet: %1" -Basic.SceneTransitions="Jelenet Átmenetek" +Basic.AddTransition="Konfigurálható átmenet hozzáadása" +Basic.RemoveTransition="Konfigurálható átmenet eltávolítása" +Basic.TransitionProperties="Átmenet tulajdonságai" +Basic.SceneTransitions="Jelenet átmenetek" Basic.TransitionDuration="Időtartam" -Basic.TogglePreviewProgramMode="Stúdió Mód" +Basic.TogglePreviewProgramMode="Stúdió mód" + +TransitionNameDlg.Text="Kérem írja be az átmenet nevét" +TransitionNameDlg.Title="Átmenet neve" TitleBar.Profile="Profil" TitleBar.Scenes="Jelenetek" @@ -65,7 +76,7 @@ NameExists.Text="A név már használatban van." NoNameEntered.Title="Kérem adjon meg egy érvényes nevet" NoNameEntered.Text="Üres nevek nem használhatóak." -ConfirmStart.Title="Stream Indítása?" +ConfirmStart.Title="Stream indítása?" ConfirmStart.Text="Biztos benne, hogy elindítja a streamet?" ConfirmStop.Title="Stream megállítása?" @@ -74,13 +85,13 @@ ConfirmStop.Text="Biztos benne, hogy leállítja a streamet?" ConfirmExit.Title="Kilép a programbó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" +ConfirmRemove.Title="Eltávolítás megerősítése" ConfirmRemove.Text="\"$1\" eltávolítására készül, biztos benne?" 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." Output.ConnectFail.ConnectFailed="Nem sikerült kapcsolódni a szerverhez" -Output.ConnectFail.InvalidStream="Nem lehet hozzáférni a megadott csatornához vagy stream kulcshoz. Lehet, hogy a kulcs / csatorna érvénytelen, vagy a kiszolgáló szerint már be van jelentkezve." +Output.ConnectFail.InvalidStream="Nem lehet hozzáférni a megadott csatornához vagy stream kulcshoz, kérem ellenőrizze a kulcsot. Ha helyesnek találja, akkor probléma merült fel a szerverhez csatlakozás során." Output.ConnectFail.Error="A szerverhez való kapcsolódás során váratlan hiba történt. További információért tekintse meg a naplófájlt." Output.ConnectFail.Disconnected="Kiszolgálóról lecsatlakoztatva." @@ -95,7 +106,7 @@ Output.BadPath.Title="A fájl elérési útja hibás" Output.BadPath.Text="A beállított elérési útvonal érvénytelen. Kérem ellenőrizze a beállításait és győződjön meg arról, hogy a fájl elérési útja érvényes." LogReturnDialog="Napló feltöltése sikeres" -LogReturnDialog.CopyURL="URL Másolása" +LogReturnDialog.CopyURL="URL másolása" LogReturnDialog.ErrorUploadingLog="Naplófájl feltöltésekor hiba lépett fel" LicenseAgreement="Licencmegállapodás" @@ -104,10 +115,10 @@ LicenseAgreement.ClickIAgreeToContinue="Amennyiben elfogadja a megállapodás fe LicenseAgreement.IAgree="Elfogadom" LicenseAgreement.Exit="Kilépés" -Remux.SourceFile="OBS Felvétel" +Remux.SourceFile="OBS felvétel" Remux.TargetFile="Célfájl" Remux.Remux="Remux" -Remux.RecordingPattern="OBS Felvétel (*.flv)" +Remux.OBSRecording="OBS felvétel" Remux.FinishedTitle="Remux kész" Remux.Finished="Felvétel remuxolva" Remux.FinishedError="Felvétel remuxolva, de a fájl hiányos lehet" @@ -118,22 +129,34 @@ Remux.FileExists="A célfájl létezik, kívánja cserélni?" Remux.ExitUnfinishedTitle="Remuxolás folyamatban" Remux.ExitUnfinished="A Remux nem fejeződött be, a megállítása a célfájlt használhatatlanná teheti.\nBiztosan megállítja?" -UpdateAvailable="Elérhető Újabb Programváltozat" +UpdateAvailable="Elérhető újabb programváltozat" UpdateAvailable.Text="Verzió: %1. %2. %3 most elérhető. Kattintson ide a letöltéshez" -Basic.DesktopDevice1="Asztal Audio" -Basic.DesktopDevice2="Asztal Audio 2" +Basic.DesktopDevice1="Asztal audio" +Basic.DesktopDevice2="Asztal audio 2" Basic.AuxDevice1="Mikrofon/Aux" Basic.AuxDevice2="Mikrofon/Aux 2" Basic.AuxDevice3="Mikrofon/Aux 3" Basic.AuxDevice4="Mikrofon/Aux 4" Basic.Scene="Jelenet" -Basic.DisplayCapture="Képernyő Felvétel" +Basic.DisplayCapture="Képernyő felvétel" Basic.Main.PreviewConextMenu.Enable="Előnézet bekapcsolása" -Basic.Main.AddSceneDlg.Title="Jelenet Hozzáadása" +Deinterlacing="Váltottsorosság" +Deinterlacing.Discard="Elvetés" +Deinterlacing.Retro="Retró mód" +Deinterlacing.Blend="Vegyítés" +Deinterlacing.Blend2x="Kétszeres Vegyítés" +Deinterlacing.Linear="Lineáris" +Deinterlacing.Linear2x="Kétszeresen Lineáris" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Felső mező először" +Deinterlacing.BottomFieldFirst="Alsó mező először" + +Basic.Main.AddSceneDlg.Title="Jelenet hozzáadása" Basic.Main.AddSceneDlg.Text="Kérem adja meg a jelenet nevét" Basic.Main.DefaultSceneName.Text="Jelenet %1" @@ -151,15 +174,15 @@ RenameProfile.Title="Profil átnevezése" Basic.Main.PreviewDisabled="Előnézet pillanatnyilag lekapcsolva" Basic.SourceSelect="Forrás Létrehozása/Kijelölése" -Basic.SourceSelect.CreateNew="Új Létrehozása" +Basic.SourceSelect.CreateNew="Új létrehozása" Basic.SourceSelect.AddExisting="Létező tartalom hozzáadása" Basic.SourceSelect.AddVisible="Forrás láthatóvá tétele" Basic.PropertiesWindow="Tulajdonságok: '%1'" Basic.PropertiesWindow.AutoSelectFormat="%1 (autokiválasztás: %2)" -Basic.PropertiesWindow.SelectColor="Szín Kiválasztása" +Basic.PropertiesWindow.SelectColor="Szín kiválasztása" Basic.PropertiesWindow.SelectFont="Betűtípus kiválasztása" -Basic.PropertiesWindow.ConfirmTitle="Beállítások Módosultak" +Basic.PropertiesWindow.ConfirmTitle="Beállítások módosultak" Basic.PropertiesWindow.Confirm="Változtatásai nincsenek elmentve. Szeretné megtartani őket?" Basic.PropertiesWindow.NoProperties="Nincsenek elérhető tulajdonságok" Basic.PropertiesWindow.AddFiles="Fájlok hozzáadása" @@ -183,21 +206,22 @@ Basic.StatusBar.DelayStoppingIn="Késleltetés (megáll: %1 mp)" Basic.StatusBar.DelayStartingStoppingIn="Késleltetés (megáll: %1 mp; kezdés: %2 mp)" Basic.Filters="Szűrők" -Basic.Filters.AsyncFilters="Audió/Videó szűrők" -Basic.Filters.AudioFilters="Audio Szűrők" -Basic.Filters.EffectFilters="Effekt Szűrők" +Basic.Filters.AsyncFilters="Audio/Videó szűrők" +Basic.Filters.AudioFilters="Hangszűrők" +Basic.Filters.EffectFilters="Effekt szűrők" Basic.Filters.Title="Szűrők a \"%1\"" Basic.Filters.AddFilter.Title="Szűrő neve" Basic.Filters.AddFilter.Text="Kérem adja meg a szűrő nevét" -Basic.TransformWindow="Jelenet Elemének Alakítása" +Basic.TransformWindow="Jelenet elemének alakítása" Basic.TransformWindow.Position="Pozíció" Basic.TransformWindow.Rotation="Forgatás" Basic.TransformWindow.Size="Méret" Basic.TransformWindow.Alignment="Tartalom pozícionálása" -Basic.TransformWindow.BoundsType="Méretezőkeret Típus" -Basic.TransformWindow.BoundsAlignment="Méretezőkeret Igazítás" -Basic.TransformWindow.Bounds="Méretezőkeret Mérete" +Basic.TransformWindow.BoundsType="Méretezőkeret típus" +Basic.TransformWindow.BoundsAlignment="Méretezőkeret igazítás" +Basic.TransformWindow.Bounds="Határkeret mérete" +Basic.TransformWindow.Crop="Vágás" Basic.TransformWindow.Alignment.TopLeft="Bal Felül" Basic.TransformWindow.Alignment.TopCenter="Középen Fent" @@ -223,17 +247,17 @@ Basic.Main.AddSourceHelp.Text="Legalább 1 jelenetre van szükség forrás hozz Basic.Main.Scenes="Jelenetek" Basic.Main.Sources="Források" Basic.Main.Connecting="Kapcsolódás..." -Basic.Main.StartRecording="Felvétel Indítása" -Basic.Main.StartStreaming="Stream Indítása" -Basic.Main.StopRecording="Felvétel Leállítása" -Basic.Main.StopStreaming="Stream Leállítása" -Basic.Main.ForceStopStreaming="Stream Leállítása (Késleltetés elvetése)" +Basic.Main.StartRecording="Felvétel indítása" +Basic.Main.StartStreaming="Stream indítása" +Basic.Main.StopRecording="Felvétel leállítása" +Basic.Main.StopStreaming="Stream leállítása" +Basic.Main.ForceStopStreaming="Stream leállítása (Késleltetés elvetése)" Basic.MainMenu.File="&Fájl" Basic.MainMenu.File.Export="&Exportálás" Basic.MainMenu.File.Import="&Importálás" -Basic.MainMenu.File.ShowRecordings="&Felvételek Mutatása" -Basic.MainMenu.File.Remux="Re&mux Felvételek" +Basic.MainMenu.File.ShowRecordings="&Felvételek megjelenítése" +Basic.MainMenu.File.Remux="Re&mux felvételek" Basic.MainMenu.File.Settings="&Beállítások" Basic.MainMenu.File.ShowSettingsFolder="Beállítási mappa megjelenítése" Basic.MainMenu.File.ShowProfileFolder="Profilmappa megjelenítése" @@ -246,13 +270,13 @@ Basic.MainMenu.Edit.Redo="&Ismét" Basic.MainMenu.Edit.UndoAction="&Visszavonás $1" Basic.MainMenu.Edit.RedoAction="&Ismét $1" Basic.MainMenu.Edit.Transform="&Alakítás" -Basic.MainMenu.Edit.Transform.EditTransform="&Alakítás Átszerkesztése..." -Basic.MainMenu.Edit.Transform.ResetTransform="&Alakítás Visszaállítása" +Basic.MainMenu.Edit.Transform.EditTransform="&Alakítás átszerkesztése..." +Basic.MainMenu.Edit.Transform.ResetTransform="&Alakítás visszaállítása" Basic.MainMenu.Edit.Transform.Rotate90CW="Forgatás 90 fokkal balra" Basic.MainMenu.Edit.Transform.Rotate90CCW="Forgatás 90 fokkal jobbra" Basic.MainMenu.Edit.Transform.Rotate180="Forgatás 180 fokkal" -Basic.MainMenu.Edit.Transform.FlipHorizontal="&Vízszintes Tükrözés" -Basic.MainMenu.Edit.Transform.FlipVertical="&Függőleges Tükrözés" +Basic.MainMenu.Edit.Transform.FlipHorizontal="&Vízszintes tükrözés" +Basic.MainMenu.Edit.Transform.FlipVertical="&Függőleges tükrözés" Basic.MainMenu.Edit.Transform.FitToScreen="&Képernyőhöz igazítás" Basic.MainMenu.Edit.Transform.StretchToScreen="&Képernyőhöz nyújtás" Basic.MainMenu.Edit.Transform.CenterToScreen="&Képernyő középpontjához" @@ -261,7 +285,7 @@ Basic.MainMenu.Edit.Order.MoveUp="Mozgatás &Fel" Basic.MainMenu.Edit.Order.MoveDown="Mozgatás &Le" Basic.MainMenu.Edit.Order.MoveToTop="Mozgatás a &Tetejére" Basic.MainMenu.Edit.Order.MoveToBottom="Mozgatás az &Aljára" -Basic.MainMenu.Edit.AdvAudio="&Speciális Audio Tulajdonságok" +Basic.MainMenu.Edit.AdvAudio="&Speciális hangtulajdonságok" Basic.MainMenu.SceneCollection="&Jelenet gyűjtemény" Basic.MainMenu.Profile="&Profil" @@ -269,14 +293,14 @@ Basic.MainMenu.Profile="&Profil" Basic.MainMenu.Help="&Segítség" Basic.MainMenu.Help.Website="Weboldal meglátogatása" Basic.MainMenu.Help.Logs="&Naplófájlok" -Basic.MainMenu.Help.Logs.ShowLogs="&Naplófájlok Mutatása" -Basic.MainMenu.Help.Logs.UploadCurrentLog="&Aktuális Naplófájl Feltöltése" -Basic.MainMenu.Help.Logs.UploadLastLog="&Utolsó Naplófájl Feltöltése" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Jelenlegi Napló Megtekintése" -Basic.MainMenu.Help.CheckForUpdates="Frissítések Ellenőrzése" +Basic.MainMenu.Help.Logs.ShowLogs="&Naplófájlok megjelenítése" +Basic.MainMenu.Help.Logs.UploadCurrentLog="&Aktuális Naplófájl feltöltése" +Basic.MainMenu.Help.Logs.UploadLastLog="&Utolsó Naplófájl feltöltése" +Basic.MainMenu.Help.Logs.ViewCurrentLog="&Jelenlegi napló megtekintése" +Basic.MainMenu.Help.CheckForUpdates="Frissítések ellenőrzése" Basic.Settings.ProgramRestart="A beállítások érvénybe lépéséhez a program újraindítása szükséges." -Basic.Settings.ConfirmTitle="Változtatások Megerősítése" +Basic.Settings.ConfirmTitle="Változtatások megerősítése" Basic.Settings.Confirm="Nem mentette a módosításokat. Menti a változtatásokat?" Basic.Settings.General="Általános" @@ -284,43 +308,54 @@ Basic.Settings.General.Theme="Téma" Basic.Settings.General.Language="Nyelv" 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.Snapping="Forrás pozicionálásának igazítása" +Basic.Settings.General.ScreenSnapping="Források igazítása a képernyő széléhez" +Basic.Settings.General.CenterSnapping="Források vízszintes és függőleges középponthoz igazítása" +Basic.Settings.General.SourceSnapping="Források igazítása más forrásokhoz" +Basic.Settings.General.SnapDistance="Igazítás érzékenysége" Basic.Settings.Stream="Stream" Basic.Settings.Stream.StreamType="Stream típusa" Basic.Settings.Output="Kimenet" -Basic.Settings.Output.Format="Felvétel Formátuma" +Basic.Settings.Output.Format="Felvétel formátuma" 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.Mode="Kimeneti Mód" +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ó bitráta korlátainak kényszerítése" +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.Simple.SavePath="Felvétel Helye" -Basic.Settings.Output.Simple.RecordingQuality="Felvételi Minőség" +Basic.Settings.Output.Mode.FFmpeg="FFmpeg kimenet" +Basic.Settings.Output.Simple.SavePath="Felvétel helye" +Basic.Settings.Output.Simple.RecordingQuality="Felvétel minősége" Basic.Settings.Output.Simple.RecordingQuality.Stream="Ugyanaz, mint a stream" -Basic.Settings.Output.Simple.RecordingQuality.Small="Kiváló Minőség, Közepes Fájlméret" -Basic.Settings.Output.Simple.RecordingQuality.HQ="Megkülönböztethetetlen Minőség, Nagy Fájlméret" -Basic.Settings.Output.Simple.RecordingQuality.Lossless="Veszteségmentes Minőség, Terjedelmes Fájlméret" +Basic.Settings.Output.Simple.RecordingQuality.Small="Jó minőség, közepes fájlméret" +Basic.Settings.Output.Simple.RecordingQuality.HQ="Megkülönböztethetetlen minőség, nagy fájlméret" +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ó bitrátája %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ó bitráta korlátainak kényszerítése\" opciót." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Figyelem: Az adás audio bitrátája %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ó bitráta korlátainak kényszerítése\" opciót." 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ájtnyi 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="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?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Veszteségmentes minőség figyelem!" +Basic.Settings.Output.Simple.Warn.MultipleQSV="Figyelem: Nem használható több különálló QSV kódoló streamelésre és felvételre egyidejűleg. Ha ön egyidejűleg kíván streamet és felvételt készíteni, akkor váltsa le a felvevő vagy a stream kódolóját." Basic.Settings.Output.Simple.Encoder.Software="Szoftver (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardver (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardver (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Szoftveres (x264 alacsony CPU használati készlet, növekvő fájlméret)" -Basic.Settings.Output.VideoBitrate="Videó Bitráta" -Basic.Settings.Output.AudioBitrate="Audio Bitráta" -Basic.Settings.Output.Reconnect="Automatikus Újracsatlakozás" -Basic.Settings.Output.RetryDelay="Újrapróbálkozás Késleltetése (másodperc)" -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 (magasabb = kevesebb CPU igény)" -Basic.Settings.Output.CustomEncoderSettings="Egyéni Kódolási Beállítások" -Basic.Settings.Output.CustomMuxerSettings="Egyéni Muxer Beállítások" +Basic.Settings.Output.VideoBitrate="Videó bitráta" +Basic.Settings.Output.AudioBitrate="Audio bitráta" +Basic.Settings.Output.Reconnect="Automatikus újracsatlakozás" +Basic.Settings.Output.RetryDelay="Újrapróbálkozás késleltetése (másodperc)" +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 (magasabb = kevesebb CPU igény)" +Basic.Settings.Output.CustomEncoderSettings="Egyéni kódolási beállítások" +Basic.Settings.Output.CustomMuxerSettings="Egyéni Muxer beállítások" Basic.Settings.Output.NoSpaceFileName="Fájlnév generálása helyfoglalás nélkül" -Basic.Settings.Output.Adv.Rescale="Kimenet Átméretezése" +Basic.Settings.Output.Adv.Rescale="Kimenet átméretezése" Basic.Settings.Output.Adv.AudioTrack="Hangsáv" Basic.Settings.Output.Adv.Streaming="Streamelés" Basic.Settings.Output.Adv.ApplyServiceSettings="A kiszolgáló kódoló beállításainak kényszerítése" @@ -332,33 +367,39 @@ Basic.Settings.Output.Adv.Audio.Track4="Sáv 4" Basic.Settings.Output.Adv.Recording="Rögzítés" Basic.Settings.Output.Adv.Recording.Type="Típus" Basic.Settings.Output.Adv.Recording.Type.Standard="Szabvány" -Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Egyéni Kimenet (FFmpeg)" +Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Egyéni kimenet (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Stream kódoló használata)" -Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg Kimenet Típusa" +Basic.Settings.Output.Adv.Recording.Filename="Fájlnév formázás" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Létező fájl felülírása" +Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg kimenet típusa" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Kimenet URL-re" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Kimenet fájlba" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Általános felvételi formátumok" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Minden fájl" Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Fájl elérési útja vagy URL" -Basic.Settings.Output.Adv.FFmpeg.Format="Tároló Formátum" +Basic.Settings.Output.Adv.FFmpeg.Format="Tároló formátum" Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Hang" Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Videó" -Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Alapértelmezett Formátum" -Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Tároló Formátum Leírás" -Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Audió/Videó Kodek kitalálása a fájl elérési útból vagy URL-ből" -Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Alapértelmezett Kódoló" -Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Kódoló Letiltása" -Basic.Settings.Output.Adv.FFmpeg.VEncoder="Videó Kódoló" -Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Videó Kódoló Beállítások (ha van)" -Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audio Kódoló" -Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audio Kódoló Beállítások (ha van)" -Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer Beállítások (ha van)" +Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Alapértelmezett formátum" +Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Tároló formátum leírás" +Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Audio/Videó kodek kitalálása a fájl elérési útból vagy URL-ből" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Alapértelmezett kódoló" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Kódoló letiltása" +Basic.Settings.Output.Adv.FFmpeg.VEncoder="Videó kódoló" +Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Videó kódoló beállítások (ha van)" +Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audio kódoló" +Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audio kódoló beállítások (ha van)" +Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer beállítások (ha van)" + +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 Év, négy számjegy\n%YY Év, utolsó két számjegy (00-99)\n%MM Hónap mint tizedes szám (01-12)\n%DD Hónap napja, nulla kitöltéssel (01-31)\n%hh Óra 24ó formátumban (00-23)\n%mm Perc (00-59)\n%ss Másodperc (00-61)\n%% A % sign\n%a Rövidített hétköznap neve\n%A Teljes hétköznap neve\n%b Rövidített hónap neve\n%B Teljes hónap neve\n%d Hónap napja, nulla kitöltéssel (01-31)\n%H Óra 24ó formátumban (00-23)\n%I Óra 12ó formátumban (01-12)\n%m Hónap mint decimális szám (01-12)\n%M Perc (00-59)\n%p DE vagy DU megjelölés\n%S Másodperc (00-61)\n%y Év, utolsó két számjegy (00-99)\n%Y Év\n%z ISO 8601 eltolással UTC-hez képest vagy időzóna\n név vagy rövidítés\n%Z Időzóna neve vagy rövidítése\n" Basic.Settings.Video="Videó" -Basic.Settings.Video.Adapter="Videó Adapter:" -Basic.Settings.Video.BaseResolution="Alap (Vászon) Felbontás:" -Basic.Settings.Video.ScaledResolution="Kimeneti (Skálázott) Felbontás:" -Basic.Settings.Video.DownscaleFilter="Leskálázás Szűrő:" +Basic.Settings.Video.Adapter="Videó adapter:" +Basic.Settings.Video.BaseResolution="Alap (Vászon) felbontás:" +Basic.Settings.Video.ScaledResolution="Kimeneti (Skálázott) felbontás:" +Basic.Settings.Video.DownscaleFilter="Leskálázás szűrő:" Basic.Settings.Video.DisableAeroWindows="Aero Letiltása (csak Windows esetén)" Basic.Settings.Video.FPS="FPS:" Basic.Settings.Video.FPSCommon="Átlagos FPS érték" @@ -380,9 +421,9 @@ Basic.Settings.Audio.SampleRate="Mintavételezés" Basic.Settings.Audio.Channels="Csatornák" Basic.Settings.Audio.DesktopDevice="Asztali hangeszköz" Basic.Settings.Audio.DesktopDevice2="Asztali hangeszköz 2" -Basic.Settings.Audio.AuxDevice="Mikrofon/Aux Audio eszköz" -Basic.Settings.Audio.AuxDevice2="Mikrofon/Aux Audio eszköz 2" -Basic.Settings.Audio.AuxDevice3="Mikrofon/Aux Audio eszköz 3" +Basic.Settings.Audio.AuxDevice="Mikrofon/Aux hangeszköz" +Basic.Settings.Audio.AuxDevice2="Mikrofon/Aux hangeszköz 2" +Basic.Settings.Audio.AuxDevice3="Mikrofon/Aux hangeszköz 3" Basic.Settings.Audio.EnablePushToMute="Push-to-mute engedélyezése" Basic.Settings.Audio.PushToMuteDelay="Push-to-mute késleltetés" Basic.Settings.Audio.EnablePushToTalk="Push-to-talk engedélyezése" @@ -393,16 +434,16 @@ Basic.Settings.Advanced="Haladó" Basic.Settings.Advanced.FormatWarning="Figyelem: Az NV12-től eltérő színformátumok elsősorban felvételhez vannak és nem ajánlott a használatuk streamekhez. Adás közben megnövekedett processzor igényt okozhat a színkonverzió." Basic.Settings.Advanced.Audio.BufferingTime="Audio pufferelési idő" Basic.Settings.Advanced.Video.ColorFormat="Színformátum" -Basic.Settings.Advanced.Video.ColorSpace="YUV Színtér" -Basic.Settings.Advanced.Video.ColorRange="YUV Színtartomány" +Basic.Settings.Advanced.Video.ColorSpace="YUV színtér" +Basic.Settings.Advanced.Video.ColorRange="YUV színtartomány" Basic.Settings.Advanced.Video.ColorRange.Partial="Részleges" Basic.Settings.Advanced.Video.ColorRange.Full="Teljes" -Basic.Settings.Advanced.StreamDelay="Stream Késleltetés" +Basic.Settings.Advanced.StreamDelay="Stream késleltetés" Basic.Settings.Advanced.StreamDelay.Duration="Időtartam (másodperc)" 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.AdvAudio="Speciális Audio Tulajdonságok" +Basic.AdvAudio="Speciális hangtulajdonságok" Basic.AdvAudio.Name="Név" Basic.AdvAudio.Volume="Hangerő (%)" Basic.AdvAudio.Mono="Monora lekeverés" @@ -413,10 +454,10 @@ Basic.AdvAudio.AudioTracks="Sávok" Basic.Settings.Hotkeys="Gyorsbillentyűk" Basic.Settings.Hotkeys.Pair="Azonos billentyűkombináció a '%1' mezővel, ezért kapcsolóként működik" -Basic.Hotkeys.StartStreaming="Stream Indítása" -Basic.Hotkeys.StopStreaming="Stream Leállítása" -Basic.Hotkeys.StartRecording="Felvétel Indítása" -Basic.Hotkeys.StopRecording="Felvétel Leállítása" +Basic.Hotkeys.StartStreaming="Stream indítása" +Basic.Hotkeys.StopStreaming="Stream leállítása" +Basic.Hotkeys.StartRecording="Felvétel indítása" +Basic.Hotkeys.StopRecording="Felvétel leállítása" Basic.Hotkeys.SelectScene="Jelenethez kapcsolás" Hotkeys.Insert="Beszúrás" diff --git a/obs/data/locale/it-IT.ini b/obs/data/locale/it-IT.ini index 82f8a5c..5fd9b25 100644 --- a/obs/data/locale/it-IT.ini +++ b/obs/data/locale/it-IT.ini @@ -8,6 +8,7 @@ Cancel="Annulla" Close="Chiudi" Save="Salva" Discard="Ignora" +Disable="Disabilita" Yes="Sì" No="No" Add="Aggiungi" @@ -38,6 +39,12 @@ Untitled="Senza Titolo" New="Nuovo" Duplicate="Duplica" Enable="Abilita" +DisableOSXVSync="Disabilita il V-Sync OSX" +ResetOSXVSyncOnExit="Reimpostare V-Sync OSX in uscita" +HighResourceUsage="Codifica in sovraccarico! È consigliabile abbassare le impostazioni video o utilizzare un settaggio predefinito di codifica più veloce." +Transition="Transizione" +QuickTransitions="Transizioni rapide" + @@ -58,10 +65,9 @@ ConfirmExit.Text="OBS è attualmente attivo. Tutte le dirette/registrazioni sara ConfirmRemove.Title="Conferma la rimozione" ConfirmRemove.Text="Sei sicuro di voler rimuovere '$1'?" -Output.ConnectFail.Title="Connessione fallita" +Output.ConnectFail.Title="Impossibile connettersi" Output.ConnectFail.BadPath="Percorso o URL di connessione non valido. Controlla le tue impostazioni per confermare che siano valide." Output.ConnectFail.ConnectFailed="Connessione al server fallita" -Output.ConnectFail.InvalidStream="Impossibile accedere al canale o alla chiave di streaming specificata. La chiave e/o il canale potrebbero non essere validi, o il server potrebbe crederti ancora autenticato." Output.ConnectFail.Error="Si è verificato un errore non previsto durante la connessione al server. Controlla il file di log per più informazioni." Output.ConnectFail.Disconnected="Disconnesso dal server." @@ -88,7 +94,6 @@ LicenseAgreement.Exit="Esci" Remux.SourceFile="Registrazione OBS" Remux.TargetFile="File di destinazione" Remux.Remux="Converti" -Remux.RecordingPattern="Registrazione OBS (*.flv)" Remux.FinishedTitle="Conversione finita" Remux.Finished="Registrazione convertita" Remux.FinishedError="Registrazione convertita, ma il file potrebbe essere incompleta" @@ -114,6 +119,7 @@ Basic.DisplayCapture="Mostra cattura" Basic.Main.PreviewConextMenu.Enable="Abilita Anteprima" + Basic.Main.AddSceneDlg.Title="Aggiungi scena" Basic.Main.AddSceneDlg.Text="Inserisci il nome della scena" @@ -326,6 +332,8 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Encoder Audio" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Impostazioni codifica audio (se presente)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Impostazioni Muxer (se possibile)" + + Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Adattatore video:" Basic.Settings.Video.BaseResolution="Risoluzione base (Canvas):" @@ -359,6 +367,7 @@ Basic.Settings.Audio.EnablePushToMute="Abilita Push-to-mute" Basic.Settings.Audio.PushToMuteDelay="Ritardo Push-to-mute" Basic.Settings.Audio.EnablePushToTalk="Abilita Push-to-talk" Basic.Settings.Audio.PushToTalkDelay="Ritardo Push-to-talk" +Basic.Settings.Audio.UnknownAudioDevice="[Dispositivo non collegato o non disponibile]" Basic.Settings.Advanced="Avanzate" Basic.Settings.Advanced.FormatWarning="Attenzione: I formati colore diversi da NV12 sono principalmente pensati per la registrazione, e non sono consigliati durante le dirette. Lo streaming può avere un utilizzo maggiore delle CPU a causa della conversione del formato del colore." diff --git a/obs/data/locale/ja-JP.ini b/obs/data/locale/ja-JP.ini index 970696e..432cf92 100644 --- a/obs/data/locale/ja-JP.ini +++ b/obs/data/locale/ja-JP.ini @@ -8,6 +8,7 @@ Cancel="キャンセル" Close="閉じる" Save="保存" Discard="破棄" +Disable="無効化" Yes="はい" No="いいえ" Add="追加" @@ -27,9 +28,9 @@ Browse="参照" Mono="モノラル" Stereo="ステレオ" DroppedFrames="ドロップしたフレーム %1 (%2%)" -PreviewProjector="全画面プロジェクター(プレビュー)" -SceneProjector="全画面プロジェクター(シーン)" -SourceProjector="全画面プロジェクター(ソース)" +PreviewProjector="全画面プロジェクター (プレビュー)" +SceneProjector="全画面プロジェクター (シーン)" +SourceProjector="全画面プロジェクター (ソース)" Clear="クリア" Revert="元に戻す" Show="表示" @@ -38,11 +39,15 @@ Untitled="無題" New="新規" Duplicate="複製" Enable=" 有効にする" -DisableOSXVSync="OSXのV-同期を無効にする" -ResetOSXVSyncOnExit="終了時にOSXのV-同期をリセットする" +DisableOSXVSync="OSX の V-Sync を無効にする" +ResetOSXVSyncOnExit="終了時に OSX の V-Sync をリセットする" HighResourceUsage="エンコードが高負荷です! ビデオ設定を下げるかより高速のエンコードプリセットの使用を検討してください。" Transition="トランジション" QuickTransitions="クイックトランジション" +Left="左" +Right="右" +Top="上" +Bottom="下" QuickTransitions.SwapScenes="トランジション後にプレビュー/出力シーンを入れ替え" QuickTransitions.SwapScenesTT="(出力のオリジナルシーンがまだ存在する場合)、トランジション後のプレビューと出力シーンを入れ替えます。\nこれは出力のオリジナルシーンに加えられた可能性があるすべての変更を元に戻しません。" @@ -52,10 +57,16 @@ QuickTransitions.EditProperties="ソースを複製" QuickTransitions.EditPropertiesTT="同じシーンを編集する場合、出力を変更することなくソースの変換/表示設定を編集することが出来ます。\nこの機能は'シーン複製'が有効になっている場合にのみ使用可能です。\n(キャプチャやメディア ソース) などのある種のソースはこの機能をサポートしておらず別々に編集できません。\nこの値の変更は (もしまだ存在する場合) 現在の出力シーンをリセットします。\n\n警告: ソースが複製されるため、余分なシステムまたはビデオ リソースを必要とします。" QuickTransitions.HotkeyName="クイックトランジション: %1" +Basic.AddTransition="構成可能なトランジションを追加" +Basic.RemoveTransition="構成可能なトランジションを削除" +Basic.TransitionProperties="トランジションのプロパティ" Basic.SceneTransitions="シーントランジション" Basic.TransitionDuration="期間" Basic.TogglePreviewProgramMode="スタジオモード" +TransitionNameDlg.Text="トランジションの名前を入力してください" +TransitionNameDlg.Title="トランジション名" + TitleBar.Profile="プロファイル" TitleBar.Scenes="シーン" @@ -80,7 +91,7 @@ ConfirmRemove.Text="'$1' を削除してもよろしいですか?" Output.ConnectFail.Title="接続失敗" Output.ConnectFail.BadPath="パスかURLが無効です。再確認して下さい。" Output.ConnectFail.ConnectFailed="サーバーへの接続に失敗しました" -Output.ConnectFail.InvalidStream="指定されたチャンネルかストリームキーにアクセスできませんでした。ストリームキーかチャンネルが間違ってるか、サーバーにすでに接続されている可能性があります。" +Output.ConnectFail.InvalidStream="指定したチャンネルまたはストリームキーにアクセスできませんでした。ストリームキーを再確認してください。 それが正しい場合は、サーバーへの接続に問題があります。" Output.ConnectFail.Error="サーバー接続時に予期しないエラーが発生しました。ログファイルを確認して下さい。" Output.ConnectFail.Disconnected="サーバーから切断されました。" @@ -107,7 +118,7 @@ LicenseAgreement.Exit="終了" Remux.SourceFile="OBS録画" Remux.TargetFile="対象ファイル" Remux.Remux="再多重化" -Remux.RecordingPattern="OBS録画(*.flv)" +Remux.OBSRecording="OBS 録画" Remux.FinishedTitle="再多重化完了" Remux.Finished="録画が再多重化されました" Remux.FinishedError="録画が再多重化されましたが、ファイルが未完成の可能性があります" @@ -116,7 +127,7 @@ Remux.SelectTarget="対象ファイルを選択 ..." Remux.FileExistsTitle="対象ファイルが存在しています" Remux.FileExists="対象ファイルが存在しています、置き換えますか?" Remux.ExitUnfinishedTitle="再多重化が進行中です" -Remux.ExitUnfinished="再多重化が完了しておらず、今停止すると対象ファイルが使用不能になる可能性があります。\n再多重化を停止しますか?。" +Remux.ExitUnfinished="再多重化が完了しておらず、今停止すると対象ファイルが使用不能になる可能性があります。\n再多重化を停止しますか?" UpdateAvailable="更新が利用可能" UpdateAvailable.Text="バージョン %1.%2.%3 が利用可能です。ダウンロードはこちら" @@ -133,6 +144,18 @@ Basic.DisplayCapture="画面キャプチャ" Basic.Main.PreviewConextMenu.Enable="プレビュー有効化" +Deinterlacing="インターレース解除" +Deinterlacing.Discard="破棄" +Deinterlacing.Retro="レトロ" +Deinterlacing.Blend="Blend" +Deinterlacing.Blend2x="Blend 2x" +Deinterlacing.Linear="Linear" +Deinterlacing.Linear2x="Linear 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="トップフィールドが先" +Deinterlacing.BottomFieldFirst="ボトムフィールドが先" + Basic.Main.AddSceneDlg.Title="シーン追加" Basic.Main.AddSceneDlg.Text="シーンの名前を入力してください" @@ -175,7 +198,7 @@ Basic.PropertiesView.FPS.ValidFPSRanges="有効なFPS範囲:" Basic.InteractionWindow="'%1' との相互作用" Basic.StatusBar.Reconnecting="切断されました、%2 秒で再接続 (試行 %1)" -Basic.StatusBar.AttemptingReconnect="再接続しています...(試行 %1)" +Basic.StatusBar.AttemptingReconnect="再接続しています... (試行 %1)" Basic.StatusBar.ReconnectSuccessful="再接続に成功" Basic.StatusBar.Delay="遅延 (%1 秒)" Basic.StatusBar.DelayStartingIn="遅延 (%1 秒で開始)" @@ -195,9 +218,10 @@ Basic.TransformWindow.Position="位置" Basic.TransformWindow.Rotation="回転" Basic.TransformWindow.Size="大きさ" Basic.TransformWindow.Alignment="位置揃え" -Basic.TransformWindow.BoundsType="バウンディング ボックスの種類" -Basic.TransformWindow.BoundsAlignment="バウンディング ボックス内の配置" -Basic.TransformWindow.Bounds="バウンディング ボックスのサイズ" +Basic.TransformWindow.BoundsType="バウンディングボックスの種類" +Basic.TransformWindow.BoundsAlignment="バウンディングボックス内の配置" +Basic.TransformWindow.Bounds="バウンディングボックスのサイズ" +Basic.TransformWindow.Crop="クロップ" Basic.TransformWindow.Alignment.TopLeft="左上" Basic.TransformWindow.Alignment.TopCenter="中央上" @@ -227,7 +251,7 @@ Basic.Main.StartRecording="録画開始" Basic.Main.StartStreaming="配信開始" Basic.Main.StopRecording="録画終了" Basic.Main.StopStreaming="配信終了" -Basic.Main.ForceStopStreaming="配信停止(遅延破棄)" +Basic.Main.ForceStopStreaming="配信停止 (遅延破棄)" Basic.MainMenu.File="ファイル(&F)" Basic.MainMenu.File.Export="エクスポート(&E)" @@ -284,15 +308,21 @@ Basic.Settings.General.Theme="テーマ" Basic.Settings.General.Language="言語" Basic.Settings.General.WarnBeforeStartingStream="配信を開始するときに確認ダイアログを表示する" Basic.Settings.General.WarnBeforeStoppingStream="配信を停止するときに確認ダイアログを表示する" +Basic.Settings.General.Snapping="ソース配置のスナップ" +Basic.Settings.General.ScreenSnapping="画面の端にソースをスナップする" +Basic.Settings.General.CenterSnapping="水平方向および垂直方向の中心にソースをスナップする" +Basic.Settings.General.SourceSnapping="他のソースにソースをスナップする" +Basic.Settings.General.SnapDistance="スナップ感度" Basic.Settings.Stream="配信" Basic.Settings.Stream.StreamType="配信種別" Basic.Settings.Output="出力" Basic.Settings.Output.Format="録画フォーマット" -Basic.Settings.Output.Encoder="エンコーダー" +Basic.Settings.Output.Encoder="エンコーダ" Basic.Settings.Output.SelectDirectory="録画ディレクトリを選択" Basic.Settings.Output.SelectFile="録画ファイルを選択" +Basic.Settings.Output.EnforceBitrate="配信サービスのビットレートを制限する" Basic.Settings.Output.Mode="出力モード" Basic.Settings.Output.Mode.Simple="基本" Basic.Settings.Output.Mode.Adv="詳細" @@ -303,20 +333,25 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="配信と同じ" Basic.Settings.Output.Simple.RecordingQuality.Small="高品質、ファイルサイズ中" 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.Encoder="警告: 配信と録画を同時に行う場合に配信と異なる品質でソフトウェアエンコーダで録画する場合にはさらなるCPU 使用率が必要になります。" Basic.Settings.Output.Simple.Warn.Lossless="警告: 無損失品質は途方もなく大きなファイルサイズになります!無損失品質は高解像度と高フレーム レートで 1 分あたり7 ギガバイト以上のディスク容量を使用します。 非常に大量のディスクの空き容量がない場合の長時間録画には無損失設定の使用はお勧めしません。" Basic.Settings.Output.Simple.Warn.Lossless.Msg="無損失品質を使用してもよろしいですか?" Basic.Settings.Output.Simple.Warn.Lossless.Title="無損失品質警告!" +Basic.Settings.Output.Simple.Warn.MultipleQSV="警告: 配信と同時に録画する場合複数の独立した QSV エンコーダは使用できません。 配信と同時に録画したい場合、配信エンコーダか録画エンコーダのどちらかを変更してください。" Basic.Settings.Output.Simple.Encoder.Software="ソフトウェア (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="ハードウェア (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="ハードウェア (NVENC)" 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.MaxRetries="最大再試行回数" -Basic.Settings.Output.Advanced="高度なエンコーダーの設定を有効にする" -Basic.Settings.Output.EncoderPreset="エンコーダープリセット (上にいくほど = CPU使用低い)" -Basic.Settings.Output.CustomEncoderSettings="エンコーダーのカスタム設定" +Basic.Settings.Output.Advanced="高度なエンコーダの設定を有効にする" +Basic.Settings.Output.EncoderPreset="エンコーダプリセット (上にいくほど = CPU使用低い)" +Basic.Settings.Output.CustomEncoderSettings="エンコーダのカスタム設定" Basic.Settings.Output.CustomMuxerSettings="カスタムマルチプレクサーの設定" Basic.Settings.Output.NoSpaceFileName="スペースなしのファイル名を生成" @@ -333,7 +368,9 @@ 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 の出力の種類" Basic.Settings.Output.Adv.FFmpeg.Type.URL="URL に出力" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="ファイルに出力" @@ -349,11 +386,15 @@ Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="ファイルパスまたは URL Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="既定のエンコーダ" Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="エンコーダを無効にする" Basic.Settings.Output.Adv.FFmpeg.VEncoder="映像エンコーダ" -Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="映像エンコーダー設定 (ある場合)" +Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="映像エンコーダ設定 (ある場合)" Basic.Settings.Output.Adv.FFmpeg.AEncoder="音声エンコーダ" -Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="音声エンコーダー設定 (ある場合)" +Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="音声エンコーダ設定 (ある場合)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="マルチプレクサーの設定 (ある場合)" +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 名前または省略名\n%Z タイムゾーン名または省略名\n" + Basic.Settings.Video="映像" Basic.Settings.Video.Adapter="ビデオアダプター:" Basic.Settings.Video.BaseResolution="基本 (キャンバス) 解像度:" @@ -371,9 +412,9 @@ Basic.Settings.Video.InvalidResolution="解像度の値が不正です。[幅]x[ 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="ランチョス(先鋭化スケーリング、32 のサンプル)" +Basic.Settings.Video.DownscaleFilter.Bilinear="バイリニア (スケーリングする場合ぼやけているが最速)" +Basic.Settings.Video.DownscaleFilter.Bicubic="バイキュービック (先鋭化スケーリング、16 のサンプル)" +Basic.Settings.Video.DownscaleFilter.Lanczos="ランチョス (先鋭化スケーリング、32 のサンプル)" Basic.Settings.Audio="音声" Basic.Settings.Audio.SampleRate="サンプリングレート" @@ -398,8 +439,8 @@ Basic.Settings.Advanced.Video.ColorRange="YUV 色範囲" Basic.Settings.Advanced.Video.ColorRange.Partial="一部" Basic.Settings.Advanced.Video.ColorRange.Full="全部" Basic.Settings.Advanced.StreamDelay="遅延配信" -Basic.Settings.Advanced.StreamDelay.Duration="継続時間(秒)" -Basic.Settings.Advanced.StreamDelay.Preserve="再接続時にカットオフポイントを保持する(増加遅延)" +Basic.Settings.Advanced.StreamDelay.Duration="継続時間 (秒)" +Basic.Settings.Advanced.StreamDelay.Preserve="再接続時にカットオフポイントを保持する (増加遅延)" Basic.Settings.Advanced.StreamDelay.MemoryUsage="概算メモリ使用量: %1 MB" Basic.AdvAudio="オーディオの詳細プロパティ" @@ -448,10 +489,10 @@ Hotkeys.NumpadSubtract="-(テンキー)" Hotkeys.NumpadDecimal=".(テンキー)" Hotkeys.AppleKeypadNum="%1 (キーパッド)" Hotkeys.AppleKeypadMultiply="* (キーパッド)" -Hotkeys.AppleKeypadDivide="/(キーパッド)" +Hotkeys.AppleKeypadDivide="/ (キーパッド)" Hotkeys.AppleKeypadAdd="+ (キーパッド)" -Hotkeys.AppleKeypadSubtract="-(キーパッド)" -Hotkeys.AppleKeypadDecimal=".(キーパッド)" +Hotkeys.AppleKeypadSubtract="- (キーパッド)" +Hotkeys.AppleKeypadDecimal=". (キーパッド)" Hotkeys.AppleKeypadEqual="= (キーパッド)" Hotkeys.MouseButton="マウス %1" diff --git a/obs/data/locale/ko-KR.ini b/obs/data/locale/ko-KR.ini index 69cc2f1..2de8b51 100644 --- a/obs/data/locale/ko-KR.ini +++ b/obs/data/locale/ko-KR.ini @@ -8,6 +8,7 @@ Cancel="취소" Close="닫기" Save="저장" Discard="저장 안함" +Disable="사용 안함" Yes="예" No="아니오" Add="추가" @@ -43,6 +44,10 @@ ResetOSXVSyncOnExit="종료 시 OSX 수직동기화 재설정" HighResourceUsage="인코딩 과부하! 비디오 설정을 낮추거나 더 빠른 인코딩 사전설정을 사용하는 것을 고려하세요." Transition="전환" QuickTransitions="빠른 전환" +Left="왼쪽" +Right="오른쪽" +Top="위" +Bottom="아래" QuickTransitions.SwapScenes="전환 후 미리 보기/출력 장면을 교체" QuickTransitions.SwapScenesTT="(만약 출력 쪽 원본 장면이 있을 때) 전환 작업 이후 미리 보기와 출력 장면을 교체합니다. \n출력 쪽 원본 장면에서 변경한 내용은 사라지지 않습니다." @@ -52,10 +57,16 @@ QuickTransitions.EditProperties="소스 복제" QuickTransitions.EditPropertiesTT="같은 장면을 편집하고 있을 때 출력하고 있는 영상을 수정하지 않고도, 소스의 속성을 수정할 수 있습니다.\n이런 방법으로 편집하려면 '장면 복제'를 켜세요.\n특정 소스(예를 들어 캡처 혹은 미디어 소스)는 이 기능을 지원하지 않고 따로따로 편집할 수 없습니다.\n이 값을 변경하면 현재 출력하고 있는 장면(만약 여전히 존재한다면)을 초기화합니다.\n\n경고: 소스를 복제하기 때문에 여분의 시스템 혹은 비디오 자원이 필요할 수 있습니다." QuickTransitions.HotkeyName="빠른 전환: %1" +Basic.AddTransition="설정 가능한 화면 전환 추가" +Basic.RemoveTransition="설정 가능한 화면 전환 제거" +Basic.TransitionProperties="화면 전환 속성" Basic.SceneTransitions="장면 전환" Basic.TransitionDuration="지속 기간" Basic.TogglePreviewProgramMode="스튜디오 모드" +TransitionNameDlg.Text="이 화면 전환의 이름을 입력하세요" +TransitionNameDlg.Title="화면 전환 이름" + TitleBar.Profile="프로파일" TitleBar.Scenes="장면" @@ -80,7 +91,7 @@ ConfirmRemove.Text="'$1'을 정말로 제거하시겠습니까?" Output.ConnectFail.Title="연결에 실패했음" Output.ConnectFail.BadPath="잘못된 경로 혹은 연결 주소입니다. 유효한 값인지 설정을 확인하시기 바랍니다. " Output.ConnectFail.ConnectFailed="서버에 연결하지 못했습니다" -Output.ConnectFail.InvalidStream="지정한 채널 혹은 스트림 키로 엑세스할 수 없었습니다. 키/채널 정보가 올바르지 않거나, 접속하려는 서버가 여전히 사용자가 로그인하고 있다고 인지하고 있습니다." +Output.ConnectFail.InvalidStream="지정한 채널 혹은 스트림 키에 접근할 수 없습니다. 스트림 키를 다시 확인하세요. 키가 올바르다면 서버 접속에 문제가 있을 수 있습니다." Output.ConnectFail.Error="예기치 않은 오류가 서버에 접속을 시도하는 과정에서 발생했습니다. 자세한 정보는 기록 파일을 조회하십시오. " Output.ConnectFail.Disconnected="서버로부터 접속이 끊겼습니다. " @@ -107,7 +118,7 @@ LicenseAgreement.Exit="끝내기" Remux.SourceFile="OBS 녹화" Remux.TargetFile="대상 파일" Remux.Remux="재다중화" -Remux.RecordingPattern="OBS 녹화 (*.flv)" +Remux.OBSRecording="OBS 녹화" Remux.FinishedTitle="재다중화 작업 완료" Remux.Finished="녹화가 재다중화 처리되었음" Remux.FinishedError="녹화가 재다중화 처리되었으나 파일이 완성되지 않을 수 있습니다" @@ -133,6 +144,18 @@ Basic.DisplayCapture="캡처 표시" Basic.Main.PreviewConextMenu.Enable="미리보기 활성화" +Deinterlacing="디인터레이싱" +Deinterlacing.Discard="저장 안함" +Deinterlacing.Retro="레트로" +Deinterlacing.Blend="블렌드" +Deinterlacing.Blend2x="블렌드 2x" +Deinterlacing.Linear="선형" +Deinterlacing.Linear2x="선형 2x" +Deinterlacing.Yadif="야디프" +Deinterlacing.Yadif2x="야디프 2x" +Deinterlacing.TopFieldFirst="상위 필드 우선" +Deinterlacing.BottomFieldFirst="하단 필드 우선" + Basic.Main.AddSceneDlg.Title="장면 추가" Basic.Main.AddSceneDlg.Text="장면의 이름을 입력하십시오" @@ -198,6 +221,7 @@ Basic.TransformWindow.Alignment="위치 정렬" Basic.TransformWindow.BoundsType="경계 상자 유형" Basic.TransformWindow.BoundsAlignment="상자 내부 정렬" Basic.TransformWindow.Bounds="경계 상자 크기" +Basic.TransformWindow.Crop="자르기" Basic.TransformWindow.Alignment.TopLeft="왼쪽 상단" Basic.TransformWindow.Alignment.TopCenter="중앙 상단" @@ -284,6 +308,11 @@ Basic.Settings.General.Theme="테마" Basic.Settings.General.Language="언어" Basic.Settings.General.WarnBeforeStartingStream="방송을 시작할 때 확인 대화 상자 표시" Basic.Settings.General.WarnBeforeStoppingStream="방송을 중단할 때 확인 대화 상자 표시" +Basic.Settings.General.Snapping="소스를 자석처럼 달라붙여서 정렬" +Basic.Settings.General.ScreenSnapping="소스를 화면 변두리에 붙임" +Basic.Settings.General.CenterSnapping="소스를 수평과 수직 중앙에 붙임" +Basic.Settings.General.SourceSnapping="소스를 다른 소스에 붙임" +Basic.Settings.General.SnapDistance="자석 감도" Basic.Settings.Stream="방송" Basic.Settings.Stream.StreamType="방송 형식" @@ -293,6 +322,7 @@ Basic.Settings.Output.Format="녹화 형식" Basic.Settings.Output.Encoder="인코더" Basic.Settings.Output.SelectDirectory="녹화 경로 선택" Basic.Settings.Output.SelectFile="녹화 파일 선택" +Basic.Settings.Output.EnforceBitrate="방송 서비스의 비트레이트 제한 적용" Basic.Settings.Output.Mode="출력 모드" Basic.Settings.Output.Mode.Simple="단순" Basic.Settings.Output.Mode.Adv="고급" @@ -303,11 +333,16 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="방송 품질과 동일하 Basic.Settings.Output.Simple.RecordingQuality.Small="높은 품질, 중간 파일 크기" 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.Encoder="경고: 방송과 녹화를 동시에 진행할 때 다음을 주의하십시오. 소프트웨어 인코더로 방송과 다른 품질로 녹화하면 더 많은 CPU 부담이 발생합니다." 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.Warn.MultipleQSV="경고: 방송과 녹화를 동시에 하고 있을 때 여러 개의 독립된 QSV 인코더를 사용할 수 없습니다. 두 작업을 동시에 하려면 녹화 혹은 방송 인코더 둘 중 하나를 바꿔야 합니다." Basic.Settings.Output.Simple.Encoder.Software="소프트웨어 (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="하드웨어 (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="하드웨어 (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="소프트웨어 (x264 CPU 부담이 적지만 파일 크기가 증가)" Basic.Settings.Output.VideoBitrate="비디오 비트레이트" Basic.Settings.Output.AudioBitrate="오디오 비트레이트" @@ -334,6 +369,8 @@ 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.Filename="파일명 형식" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="파일이 있는 경우 덮어쓰기" Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg 출력 형식" Basic.Settings.Output.Adv.FFmpeg.Type.URL="URL로 보냄" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="파일로 보냄" @@ -354,6 +391,10 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="오디오 인코더" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="오디오 인코더 설정 (지원되는 경우)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="다중화 설정 (제공되는 경우)" +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 일, 선행 0 포함 (01-31)\n%hh 시 24 시간 형식 (00-23)\n%mm Minute (00-59)\n%ss 초 (00-61)\n%% A % sign\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 AM 혹은 PM 구분\n%S 초 (00-61)\n%y 연도, 마지막 두 자리 (00-99)\n%Y 연도\n%z UTC에서 ISO 8601 기준만큼 조정 혹은 시간대\n 이름 혹은 축약\n%Z 시간대 이름 혹은 축약\n" + Basic.Settings.Video="비디오" Basic.Settings.Video.Adapter="비디오 어댑터:" Basic.Settings.Video.BaseResolution="기본 (캔버스) 해상도:" diff --git a/obs/data/locale/lt-LT.ini b/obs/data/locale/lt-LT.ini new file mode 100644 index 0000000..b9e7f1a --- /dev/null +++ b/obs/data/locale/lt-LT.ini @@ -0,0 +1,198 @@ + +Language="Anglų" +Region="Jungtinės Valstijos" + +OK="ОК" +Apply="Pritaikyti" +Cancel="Atšaukti" +Close="Užverti" +Save="Išsaugoti" +Discard="Atmesti" +Disable="Išjungti" +Yes="Taip" +No="Ne" +Add="Pridėti" +Remove="Pašalinti" +Rename="Pervardinti" +Interact="Sąveikauti" +Filters="Filtrai" +Properties="Savybės" +MoveUp="Perkelti aukštyn" +MoveDown="Perkelti žemyn" +Settings="Nustatymai" +Display="Ekranas" +Name="Vardas" +Exit="Išeiti" +Mixer="Mikseris" +Browse="Naršyti" +Mono="Mono" +Stereo="Stereo" +DroppedFrames="Atmesti kadrai %1 (%2%)" +PreviewProjector="Pilno ekrano projektorius (Peržiūra)" +SceneProjector="Pilno ekrano projektorius (Scena)" +SourceProjector="Pilno ekrano projektorius (Šaltinis)" +Clear="Išvalyti" +Revert="Atstatyti" +Show="Parodyti" +Hide="Paslėpti" +Untitled="Nepavadintas" +New="Naujas" +Duplicate="Dubliuoti" +Enable="Įjungti" +DisableOSXVSync="Išjungti OSX V-Sync" +ResetOSXVSyncOnExit="Iš naujo nustatyti OSX V-Sync išeinant" +HighResourceUsage="Kodavimas perkrautas! Mažinkite vaizdo parametrus arba naudokite greitesnę kodavimo parengtį." +Transition="Perėjimas" +QuickTransitions="Greitieji perėjimai" +Left="Iš kairės" +Right="Iš dešinės" +Top="Iš viršaus" +Bottom="Iš apačios" + +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ą" + + + + + + + + + + + + + + + +Remux.TargetFile="Paskirties failas" +Remux.Remux="Permiksuoti" +Remux.FinishedTitle="Permiksavimas baigtas" +Remux.Finished="Įrašas permiksuotas" +Remux.FinishedError="Įrašas permiksuotas, tačiau failas gali būti neužbaigtas" +Remux.SelectRecording="Pasirinkite OBS įrašą …" +Remux.SelectTarget="Pasirinkite paskirties failą …" +Remux.FileExistsTitle="Toks paskirties failas jau yra" +Remux.FileExists="Toks paskirties failas jau yra, ar norite jį pakeisti?" +Remux.ExitUnfinishedTitle="Vyksta permiksavimimas" +Remux.ExitUnfinished="Permiksavimas nebaigtas. Sustabdžius dabar, paskirites failas gali būti nepanaudojamas.\nAr esate tikras, kad norite sustabdyti permiksavimą?" + +UpdateAvailable="Galimas atnaujinimas" +UpdateAvailable.Text="Naujausia versija: %1.%2.%3. Spauskite čia, kad parsisiųstumėte" + +Basic.DesktopDevice1="Darbastalio garsas" +Basic.DesktopDevice2="Darbastalio garsas 2" +Basic.AuxDevice1="Mic/Aux" +Basic.AuxDevice2="Mic/Aux 2" +Basic.AuxDevice3="Mic/Aux 3" +Basic.AuxDevice4="Mic/Aux 4" + +Basic.Scene="Scena" +Basic.DisplayCapture="Ekrano perėmimas" + +Basic.Main.PreviewConextMenu.Enable="Įjungti peržiūrą" + +Deinterlacing="Perėjimo šalinimas" +Deinterlacing.Discard="Atmesti" +Deinterlacing.Retro="Retro" +Deinterlacing.Blend="Sulieti" +Deinterlacing.Blend2x="Sulieti 2x" +Deinterlacing.Linear="Linijinis" +Deinterlacing.Linear2x="Linijinis 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Piršutinis puskadris pirmas" +Deinterlacing.BottomFieldFirst="Apatinis puskadris pirmas" + +Basic.Main.AddSceneDlg.Title="Pridėti sceną" +Basic.Main.AddSceneDlg.Text="Įveskite pasirinktą scenos pavadinimą" + +Basic.Main.DefaultSceneName.Text="Scena %1" + +Basic.Main.AddSceneCollection.Title="Pridėti scenų rinkinį" +Basic.Main.AddSceneCollection.Text="Įveskite pasirinktą scenų rinkinio pavadinimą" + +Basic.Main.RenameSceneCollection.Title="Pervardinti scenų rinkinį" + +AddProfile.Title="Pridėti profilį" +AddProfile.Text="Įveskite pasirinktą profilio pavadinimą" + +RenameProfile.Title="Pervardinti profilį" + +Basic.Main.PreviewDisabled="Peržiūra šiuo metu išjungta" + +Basic.SourceSelect="Sukurti/Pasirinkti šaltinį" +Basic.SourceSelect.CreateNew="Sukurti naują" +Basic.SourceSelect.AddExisting="Pridėti esamą" +Basic.SourceSelect.AddVisible="Padaryti šaltinį matomu" + +Basic.PropertiesWindow="'%1' savybės" +Basic.PropertiesWindow.AutoSelectFormat="%1 (automatinis pasirinkimas: %2)" + + + + + + + + +Basic.Main.AddSourceHelp.Text="Turite turėti bent 1 sceną, kad galėtumėte pridėti šaltinį." + +Basic.Main.Scenes="Scenos" +Basic.Main.Sources="Šaltiniai" +Basic.Main.Connecting="Jungiamasi..." +Basic.Main.StartRecording="Pradėti įrašymą" +Basic.Main.StartStreaming="Pradėti transliavimą" +Basic.Main.StopRecording="Stabdyti įrašymą" +Basic.Main.StopStreaming="Stabdyti transliavimą" +Basic.Main.ForceStopStreaming="Stabdyti transliavimą (atmesti vėlavimą)" + +Basic.MainMenu.File="&Failas" +Basic.MainMenu.File.Export="&Eksportuoti" +Basic.MainMenu.File.Import="&Importuoti" +Basic.MainMenu.File.ShowRecordings="Parodyti Į&rašus" +Basic.MainMenu.File.Remux="Per&miksuoti įrašus" +Basic.MainMenu.File.Settings="Nu&statymai" +Basic.MainMenu.File.ShowSettingsFolder="Parodyti nustatymų katalogą" +Basic.MainMenu.File.ShowProfileFolder="Parodyti profilių katalogą" +Basic.MainMenu.AlwaysOnTop="Visuomet &viršuje" +Basic.MainMenu.File.Exit="Iš&eiti" + +Basic.MainMenu.Edit="&Redaguoti" +Basic.MainMenu.Edit.Undo="&Atšaukti" +Basic.MainMenu.Edit.Redo="&Gražinti atšaukimą" +Basic.MainMenu.Edit.UndoAction="&Atšaukti $1" +Basic.MainMenu.Edit.RedoAction="&Gražinti atšaukimą $1" +Basic.MainMenu.Edit.Transform="&Transformuoti" +Basic.MainMenu.Edit.Transform.EditTransform="&Redaguoti transformaciją..." +Basic.MainMenu.Edit.Transform.ResetTransform="&Atšaukti transformaciją" +Basic.MainMenu.Edit.Transform.Rotate90CW="Pasukti 90 laipsnių pagal LL" +Basic.MainMenu.Edit.Transform.Rotate90CCW="Pasukti 90 laipsnių prieš LL" +Basic.MainMenu.Edit.Transform.Rotate180="Pasukti 180 laipsnių" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Apversti &horizontaliai" +Basic.MainMenu.Edit.Transform.FlipVertical="Apversti &vertikaliai" +Basic.MainMenu.Edit.Transform.FitToScreen="Sutalpinti į ekraną" + + + + + + + + + + + + + + + + + + + + + + diff --git a/obs/data/locale/ms-MY.ini b/obs/data/locale/ms-MY.ini index 2781aa8..0d03804 100644 --- a/obs/data/locale/ms-MY.ini +++ b/obs/data/locale/ms-MY.ini @@ -8,13 +8,14 @@ Cancel="Batal" Close="Tutup" Save="Simpan" Discard="Buang" +Disable="Nyahaktifkan" Yes="Ya" No="Tidak" Add="Tambah" Remove="Buang" Rename="Namakan Semula" Interact="Interaksi" -Filters="Penapis" +Filters="Tapisan-tapisan" Properties="Sifat-sifat" MoveUp="Gerakkan ke atas" MoveDown="Gerakkan ke bawah" @@ -38,11 +39,36 @@ Untitled="Tiada tajuk" New="Baru" Duplicate="Salin" Enable="Benarkan" +DisableOSXVSync="Nyahaktifkan OSX V-Sync" +ResetOSXVSyncOnExit="Tetapkan semula OSX V-Sync apabila keluar" +HighResourceUsage="Pengekodan terbeban! Cuba turunkan tetapan video ataupun gunakan pratetapan pengekodan yang lebih cepat." +Transition="Peralihan" +QuickTransitions="Peralihan Pantas" +Left="Kiri" +Right="Kanan" +Top="Atas" +Bottom="Bawah" +QuickTransitions.SwapScenes="Tukar Pratonton/Output Adegan-adegan Selepas Peralihan" +QuickTransitions.SwapScenesTT="Menukarkan pratonton dan output adegan-adegan sleeps peralihan(jika output adegan mash wujud).\nIni tidak akan mengundurkan semarang perubahan yang mungkin telah dibuat pada output adegan yang asal." +QuickTransitions.DuplicateScene="Klonkan Adegan" +QuickTransitions.DuplicateSceneTT="Apabila menyunting adegan yang sama, ini membolehkan penyuntingan perubahan/keterlihatan tanpa mengubah output..\nUntuk edit sifat-sifat adegan-adegan tanpa mengubah suai output, aktifkan 'Klonkan Adegan'.\nPengubahan nilai ini akan menetapkan semula output adegan (jika adegan masih wujud)." +QuickTransitions.EditProperties="Klonkan Sumber" +QuickTransitions.EditPropertiesTT="Apabila menyunting adegan yang sama, ini membolehkan penyuntingan sumber-sumber tanpa mengubah output.\nIni hanya boleh dilakukan jika 'Klonkan Adegan' diaktifkan.\nSebahagian sumber (seperti sumber-sumber tangkapan atau media) tidak menyokong tetapan ini dan tidak boleh disunting secara berasingan.\nPenukaran nilai ini akan menetapkan semula output adegan yang sedang digunakan (jika adegan masih wujud).\n\nAmaran: Kerana sumber-sumber akan diklonkan, ini mungkin memerlukan penambahan sumber-sumber sistem/video." +QuickTransitions.HotkeyName="Peralihan Pantas: %1" +Basic.AddTransition="Tambah Peralihan Yang Boleh Diubahsuai" +Basic.RemoveTransition="Buang Peralihan Yang Boleh Diubahsuai" +Basic.TransitionProperties="Sifat-sifat Peralihan" +Basic.SceneTransitions="Peralihan-peralihan Adegan" +Basic.TransitionDuration="Tempoh" +Basic.TogglePreviewProgramMode="Mod Studio" + +TransitionNameDlg.Text="Sila taip nama peralihan" +TransitionNameDlg.Title="Nama Peralihan" TitleBar.Profile="Profil" -TitleBar.Scenes="'Scenes'" +TitleBar.Scenes="Adegan-adegan" NameExists.Title="Nama sudah wujud" NameExists.Text="Nama ini sudah digunakan." @@ -50,18 +76,21 @@ NameExists.Text="Nama ini sudah digunakan." NoNameEntered.Title="Sila taip nama yang sah" NoNameEntered.Text="Anda tidak boleh membiarkan ruang nama kosong." +ConfirmStart.Title="Mulakan 'Stream'?" +ConfirmStart.Text="Adakah anda pasti anda mahu memulakan 'stream'?" +ConfirmStop.Title="Berhenti 'Stream'?" +ConfirmStop.Text="Adakah anda pasti anda mahu menghentikan 'stream'?" ConfirmExit.Title="Tutup OBS?" -ConfirmExit.Text="OBS kini sedang aktif. Semua 'streams'/rakaman akan ditutup. Adakah anda pasti anda mahu tutup(OBS)?" +ConfirmExit.Text="OBS kini sedang aktif. Semua 'stream'/rakaman akan ditutup. Adakah anda pasti anda mahu tutup(OBS)?" -ConfirmRemove.Title="Pengesahan untuk buang" +ConfirmRemove.Title="Pengesahan untuk Buang" ConfirmRemove.Text="Adakah anda pasti untuk buang '$1'?" -Output.ConnectFail.Title="Gagal menyambung" -Output.ConnectFail.BadPath="Sambungan URL atau laluan yang tidak sah.Sila semak semula tetapan anda to mengesahkan bahawa semuanya sah." -Output.ConnectFail.ConnectFailed="Gagal menyambung ke pelayan" -Output.ConnectFail.InvalidStream="Tidak dapat mengakses kunci saluran atau 'stream' ditetapkan. Ini mungkin disebabkan kunci/saluran tidak sah, atau pelayan masih menganggap anda telah log masuk." +Output.ConnectFail.Title="Penyambungan gagal" +Output.ConnectFail.BadPath="Sambungan URL atau Laluan yang tidak sah. Sila semak semula tetapan anda to mengesahkan bahawa semuanya sah." +Output.ConnectFail.ConnectFailed="Penyambungan ke pelayan gagal" Output.ConnectFail.Error="Ralat tidak dijangka berlaku sewaktu percubaan menyambung ke pelayan. Maklumat lanjut di dalam fail log." Output.ConnectFail.Disconnected="Terputus daripada pelayan." @@ -87,7 +116,6 @@ LicenseAgreement.Exit="Keluar" Remux.SourceFile="Rakaman OBS" Remux.TargetFile="Fail sasaran" -Remux.RecordingPattern="Rakaman OBS (*.flv)" Remux.SelectRecording="Pilih Rakaman OBS …" Remux.SelectTarget="Pilih fail sasaran …" Remux.FileExistsTitle="Fail sasaran wujud" @@ -107,6 +135,7 @@ Basic.Scene="Adegan" Basic.Main.PreviewConextMenu.Enable="Benarkan Pratonton" + Basic.Main.AddSceneDlg.Title="Tambah Adegan" Basic.Main.AddSceneDlg.Text="Sila taip nama adegan" @@ -218,6 +247,8 @@ Basic.Settings.Output.Adv.FFmpeg.Type="Jenis Output FFmpeg" + + Basic.Settings.Advanced.FormatWarning="Amaran:Format warna selain daripada 'NV12' lebih digunakan untuk rakaman,dan tidak disyorkan apabila 'streaming'.'Streaming' mungkin menyebabkan peningkatan penggunaan CPU disebabkan oleh penukaran format warna." diff --git a/obs/data/locale/nb-NO.ini b/obs/data/locale/nb-NO.ini index 16feebc..8bf7b83 100644 --- a/obs/data/locale/nb-NO.ini +++ b/obs/data/locale/nb-NO.ini @@ -38,6 +38,8 @@ Untitled="Uten navn" New="Ny" Duplicate="Dupliser" Enable="Aktiver" +Transition="Overgang" + @@ -61,7 +63,6 @@ ConfirmRemove.Text="Er du sikker på at du vil fjerne '$1'?" Output.ConnectFail.Title="Tilkobling misklytes" Output.ConnectFail.BadPath="Ugyldig filbane eller tilkoblings-URL. Vennligst bekreft at instillingene dine er riktige." Output.ConnectFail.ConnectFailed="Kunne ikke koble til tjener." -Output.ConnectFail.InvalidStream="Fikk ikke adgang til den etterspurte kanalen. Årsaken kan være ugyldig nøkkel eller kanalnavn, eller at serveren tror du fortsatt er pålogget denne kanalen." Output.ConnectFail.Error="En uventet feil oppstod ved tilkobling til serveren. Detaljert informasjon kan du finne i loggfila." Output.ConnectFail.Disconnected="Koblet fra tjeneren." @@ -88,7 +89,6 @@ LicenseAgreement.Exit="Avslutt" Remux.SourceFile="OBS-opptak" Remux.TargetFile="Målfil" Remux.Remux="Remuks" -Remux.RecordingPattern="OBS-opptak (*.flv)" Remux.FinishedTitle="Remuksing ferdig" Remux.Finished="Opptak remukset" Remux.FinishedError="Opptak remukset, men filen kan være ufullstendig." @@ -114,6 +114,7 @@ Basic.DisplayCapture="Skjermopptak" Basic.Main.PreviewConextMenu.Enable="Aktiver forhåndsvisning" + Basic.Main.AddSceneDlg.Title="Ny Scene" Basic.Main.AddSceneDlg.Text="Vennligst gi et navn til scenen." @@ -326,6 +327,8 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Lydkoder" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Lydkoderinstillinger (om noen)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Mukserinstillinger (om noen)" + + Basic.Settings.Video="Bilde" Basic.Settings.Video.Adapter="Bildeadapter:" Basic.Settings.Video.BaseResolution="Grunnoppløsning (lerret):" diff --git a/obs/data/locale/nl-NL.ini b/obs/data/locale/nl-NL.ini index 972b90c..020e032 100644 --- a/obs/data/locale/nl-NL.ini +++ b/obs/data/locale/nl-NL.ini @@ -8,6 +8,7 @@ Cancel="Annuleren" Close="Afsluiten" Save="Opslaan" Discard="Verwerpen" +Disable="Uitschakelen" Yes="Ja" No="Nee" Add="Toevoegen" @@ -43,6 +44,10 @@ ResetOSXVSyncOnExit="OSX V-Sync resetten bij afsluiten" HighResourceUsage="Encoden overbelast! Overweeg de video-instellingen te verlagen of een snellere encoder preset te gebruiken." Transition="Overgang" QuickTransitions="Snelle overgangen" +Left="Links" +Right="Rechts" +Top="Boven" +Bottom="Onder" QuickTransitions.SwapScenes="Preview-/uitvoerscenes verwisselen na overgang" QuickTransitions.SwapScenesTT="Verwisselt de preview- en uitvoercenes na een overgang (als de originele uitvoerscène nog bestaat.)\nDit zal geen veranderingen ongedaan maken die mogelijk zijn gemaakt aan de originele uitvoerscène." @@ -52,10 +57,16 @@ QuickTransitions.EditProperties="Bronnen Dupliceren" QuickTransitions.EditPropertiesTT="Wanneer je dezelfde scène bewerkt, staat dit het bewerken van eigenschappen van bronnen toe zonder de uitvoerscène aan te passen.\nDit kan alleen worden gebruikt als 'Scène Dupliceren' is ingeschakeld.\nSommige bronnen (zoals opname- of mediabronnen) ondersteunen dit niet en kunnen niet onafhankelijk worden bewerkt.\nHet veranderen van deze waarden zal de huidige scène resetten (als deze nog bestaat).\n\nWaarschuwing: Omdat bronnen zullen worden gedupliceerd kan dit extra systeem of video rekenkracht verbruiken." QuickTransitions.HotkeyName="Snelle overgang: %1" +Basic.AddTransition="Instelbare overgang toevoegen" +Basic.RemoveTransition="Instelbare overgang verwijderen" +Basic.TransitionProperties="Overgang-eigenschappen" Basic.SceneTransitions="Scène-overgangen" Basic.TransitionDuration="Duur" Basic.TogglePreviewProgramMode="Studiomodus" +TransitionNameDlg.Text="Voer a.u.b. de naam van de transitie in" +TransitionNameDlg.Title="Naam van de overgang" + TitleBar.Profile="Profiel" TitleBar.Scenes="Scènes" @@ -107,7 +118,7 @@ LicenseAgreement.Exit="Afsluiten" Remux.SourceFile="OBS Opname" Remux.TargetFile="Doelbestand" Remux.Remux="Remuxen" -Remux.RecordingPattern="OBS Opname (*.flv)" +Remux.OBSRecording="OBS Opname" Remux.FinishedTitle="Remuxen voltooid" Remux.Finished="Opname geremuxt" Remux.FinishedError="Opname geremuxt, maar het bestand zou incompleet kunnen zijn" @@ -133,6 +144,18 @@ Basic.DisplayCapture="Beeldschermcapture" Basic.Main.PreviewConextMenu.Enable="Preview inschakelen" +Deinterlacing="Deinterlacing" +Deinterlacing.Discard="Verwerpen" +Deinterlacing.Retro="Retro" +Deinterlacing.Blend="Blend" +Deinterlacing.Blend2x="Blend 2x" +Deinterlacing.Linear="Linear" +Deinterlacing.Linear2x="Linear 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Bovenste Veld Eerst" +Deinterlacing.BottomFieldFirst="Onderste Veld Eerst" + Basic.Main.AddSceneDlg.Title="Scène Toevoegen" Basic.Main.AddSceneDlg.Text="Voer a.u.b. de naam van de scène in" @@ -198,6 +221,7 @@ Basic.TransformWindow.Alignment="Positionele uitlijning" Basic.TransformWindow.BoundsType="Bounding Box Type" Basic.TransformWindow.BoundsAlignment="Uitlijning in Bounding Box" Basic.TransformWindow.Bounds="Bounding Box Grootte" +Basic.TransformWindow.Crop="Bijsnijden" Basic.TransformWindow.Alignment.TopLeft="Linksboven" Basic.TransformWindow.Alignment.TopCenter="Boven" @@ -284,6 +308,11 @@ Basic.Settings.General.Theme="Thema" Basic.Settings.General.Language="Taal" 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.Snapping="Bronuitlijning" +Basic.Settings.General.ScreenSnapping="Bronnen uitlijnen op de rand van het scherm" +Basic.Settings.General.CenterSnapping="Bronnen uitlijnen op het horizontale en verticale midden" +Basic.Settings.General.SourceSnapping="Bronnen uitlijnen op andere bronnen" +Basic.Settings.General.SnapDistance="Gevoeligheid" Basic.Settings.Stream="Stream" Basic.Settings.Stream.StreamType="Stream Type" @@ -293,6 +322,7 @@ Basic.Settings.Output.Format="Opnameformaat" 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.Mode="Uitvoermodus" Basic.Settings.Output.Mode.Simple="Simpel" Basic.Settings.Output.Mode.Adv="Geavanceerd" @@ -303,11 +333,16 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Hetzelfde als de stream" Basic.Settings.Output.Simple.RecordingQuality.Small="Hoge Kwaliteit, Gemiddelde Bestandsgrootte" Basic.Settings.Output.Simple.RecordingQuality.HQ="Ononderscheidbare Kwaliteit, Grote Bestandsgrootte" 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.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?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Lossless kwaliteit waarschuwing!" +Basic.Settings.Output.Simple.Warn.MultipleQSV="Waarschuwing: Je kunt niet meerdere QSV encoders gebruiken wanneer je tegelijkertijd aan het streamen en opnemen bent. Als je tegelijkertijd wil streamen en opnemen, verander dan de opname- of streamencoder." Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 laag cpu gebruik, verhoogt bestandsgrootte)" Basic.Settings.Output.VideoBitrate="Video Bitrate" Basic.Settings.Output.AudioBitrate="Audio Bitrate" @@ -334,6 +369,8 @@ Basic.Settings.Output.Adv.Recording.Type="Type" Basic.Settings.Output.Adv.Recording.Type.Standard="Standaard" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Aangepaste Uitvoer (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Gebruik stream encoder)" +Basic.Settings.Output.Adv.Recording.Filename="Bestandsnaamformaat" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Overschrijven als bestand bestaat" Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg Uitvoertype" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Uitvoer naar URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Uitvoer naar Bestand" @@ -354,6 +391,10 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audio Encoder" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audio Encoderinstellingen (indien gewenst)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxerinstellingen (indien aanwezig)" +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 Jaar, vier cijfers\n%YY Jaar, laatste twee cijfers (00-99)\n%MM Maand, cijfer (0-12)\n%DD Dag van de maand, nul aangevuld (01-31)\n%hh Uur in 24h formaat (00-23)\n%mm Minuut (00-59)\n%ss Seconde (00-61)\n%% Een % teken\n%a Dag van de week afgekort\n%A Dag van de week volledig\n%b Maand, afgekorte naam\n%B Maand, volledige naam\n%d Dag van de maand, nul aangevuld (01-31)\n%H Uur in 24h formaat (00-23)\n%I Uur in 12h formaat (01-12)\n%m Maand, cijfer (01-12)\n%M Minuut (00-59)\n%p AM of PM\n%S Second e(00-61)\n%y Jaar, laatste twee cijfers (00-99)\n%Y Jaar\n%z ISO 8601 afstand van UTC of tijdzone\n naam of afkorting\n%Z naam of afkorting van tijdzone\n" + Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Videoadapter:" Basic.Settings.Video.BaseResolution="Basisresolutie (Canvas):" diff --git a/obs/data/locale/pl-PL.ini b/obs/data/locale/pl-PL.ini index 89ce92a..1eec74f 100644 --- a/obs/data/locale/pl-PL.ini +++ b/obs/data/locale/pl-PL.ini @@ -8,6 +8,7 @@ Cancel="Anuluj" Close="Zamknij" Save="Zapisz" Discard="Odrzuć" +Disable="Wyłączone" Yes="Tak" No="Nie" Add="Dodaj" @@ -43,6 +44,10 @@ ResetOSXVSyncOnExit="Przywróć synchronizację pionową OSX po zamknięciu apli HighResourceUsage="Enkodowanie przeciążone! Zmień ustawienia video lub użyj szybszego presetu enkodowania." Transition="Efekt przejścia" QuickTransitions="Szybkie efekty przejścia" +Left="Od lewej" +Right="Od prawej" +Top="Od góry" +Bottom="Od dołu" QuickTransitions.SwapScenes="Zamień podgląd/wyjście scen po przejściu" QuickTransitions.SwapScenesTT="Zamienia podgląd i wyjście scen po przejściu (jeżeli wyjście oryginalnej sceny istnieje).\nNie przywraca to zmian jakie zostały dokonane w oryginalnej scenie." @@ -52,10 +57,16 @@ QuickTransitions.EditProperties="Duplikuj źródła" QuickTransitions.EditPropertiesTT="Edytując tę samą scenę, opcja ta pozwala na edycję źródeł bez modyfikacji wyjścia sceny.\nMożliwe to jest jedynie przy włączonej opcji 'Duplikuj scenę'.\nNiektóre źródła (np. przechwytywanie obrazu lub źródła mediów) nie obsługując tej funkcjonalności i nie mogą być edytowane oddzielnie.\nZmiana tej opcji zresetuje wyjście obecnej sceny, jeżeli takowa istnieje.\n\nUwaga: Ponieważ źródła są duplikowane, może to oznaczać zwiększenie obciążenia komputera i tychże źródeł." QuickTransitions.HotkeyName="Szybkie przejście: %1" +Basic.AddTransition="Dodaj konfigurowalne przejście" +Basic.RemoveTransition="Usuń konfigurowalne przejście" +Basic.TransitionProperties="Właściwości przejścia" Basic.SceneTransitions="Efekty przejścia scen" Basic.TransitionDuration="Czas trwania" Basic.TogglePreviewProgramMode="Tryb studia" +TransitionNameDlg.Text="Proszę podać nazwę przejścia" +TransitionNameDlg.Title="Nazwa przejścia" + TitleBar.Profile="Profile" TitleBar.Scenes="Sceny" @@ -80,7 +91,7 @@ ConfirmRemove.Text="Czy na pewno chcesz usunąć '$1'?" Output.ConnectFail.Title="Nie udało się połączyć" Output.ConnectFail.BadPath="Nieprawidłowa ścieżka lub adres URL połączenia. Sprawdź poprawność ustawień." Output.ConnectFail.ConnectFailed="Nie udało się połączyć z serwerem" -Output.ConnectFail.InvalidStream="Nie można uzyskać dostępu do kanału lub klucza streamu. Możliwe, że klucz/kanał jest nieprawidłowy lub serwer nadal uważa, że jesteś zalogowany." +Output.ConnectFail.InvalidStream="Nie można uzyskać dostępu do wybranego kanału lub klucza streamu. Proszę sprawdzić klucz streamu. Jeżeli jest poprawny, to problemem może być połączenie do serwera." Output.ConnectFail.Error="Wystąpił nieoczekiwany błąd podczas próby połączenia z serwerem. Więcej informacji w pliku dziennika." Output.ConnectFail.Disconnected="Utracono połączenie z serwerem." @@ -107,7 +118,6 @@ LicenseAgreement.Exit="Wyjście" Remux.SourceFile="Nagrywanie OBS" Remux.TargetFile="Plik docelowy" Remux.Remux="Przepakowanie (remux)" -Remux.RecordingPattern="Nagranie OBS (*.flv)" Remux.FinishedTitle="Przepakowanie zakończone" Remux.Finished="Nagranie przepakowane" Remux.FinishedError="Nagranie przepakowane ale może być niekompletne" @@ -133,6 +143,18 @@ Basic.DisplayCapture="Przechwytywanie obrazu" Basic.Main.PreviewConextMenu.Enable="Włącz podgląd" +Deinterlacing="Usuwanie przeplotu" +Deinterlacing.Discard="Odrzuć" +Deinterlacing.Retro="Retro" +Deinterlacing.Blend="Wtapianie" +Deinterlacing.Blend2x="Wtapianie 2x" +Deinterlacing.Linear="Liniowe" +Deinterlacing.Linear2x="Liniowe 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Najpierw pole górne" +Deinterlacing.BottomFieldFirst="Najpierw pole dolne" + Basic.Main.AddSceneDlg.Title="Dodaj scenę" Basic.Main.AddSceneDlg.Text="Podaj nazwę sceny" @@ -198,6 +220,7 @@ Basic.TransformWindow.Alignment="Wyrównanie" Basic.TransformWindow.BoundsType="Typ ograniczenia" Basic.TransformWindow.BoundsAlignment="Wyrównanie w obwiedni" Basic.TransformWindow.Bounds="Rozmiar obwiedni" +Basic.TransformWindow.Crop="Kadrowanie" Basic.TransformWindow.Alignment.TopLeft="Lewy/górny" Basic.TransformWindow.Alignment.TopCenter="Środek/górny" @@ -284,6 +307,11 @@ Basic.Settings.General.Theme="Motyw" Basic.Settings.General.Language="Język" Basic.Settings.General.WarnBeforeStartingStream="Pokaż komunikat potwierdzenia uruchomienia streamowania" Basic.Settings.General.WarnBeforeStoppingStream="Pokaż komunikat potwierdzenia zatrzymania streamowania" +Basic.Settings.General.Snapping="Przyciąganie elementów źródłowych" +Basic.Settings.General.ScreenSnapping="Przyciągaj do krawędzi ekranu" +Basic.Settings.General.CenterSnapping="Przyciągaj do poziomego i pionowego środka" +Basic.Settings.General.SourceSnapping="Przyciągaj źródła do innych źródeł" +Basic.Settings.General.SnapDistance="Czułość przyciągania" Basic.Settings.Stream="Stream" Basic.Settings.Stream.StreamType="Typ streamu" @@ -293,6 +321,7 @@ Basic.Settings.Output.Format="Format nagrywania" 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.Mode="Tryb wyjścia" Basic.Settings.Output.Mode.Simple="Proste" Basic.Settings.Output.Mode.Adv="Zaawansowane" @@ -303,11 +332,16 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Taki sam jak stream" Basic.Settings.Output.Simple.RecordingQuality.Small="Wysoka jakość, średni rozmiar pliku" Basic.Settings.Output.Simple.RecordingQuality.HQ="Jakość nie do odróżnienia, duża wielkość pliku" 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.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?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Ostrzeżenie o bezstratnej jakości!" +Basic.Settings.Output.Simple.Warn.MultipleQSV="Ostrzeżenie: Korzystanie z wielu różnych enkoderów QSV do streamowania i nagrywania jest niedozwolone. Jeżeli chcesz streamować i nagrywać w tym samym czasie, zmień ustawienia enkodera nagrywania bądź streamowania." Basic.Settings.Output.Simple.Encoder.Software="Programowy (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Sprzętowy (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Sprzętowy (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Programowy (x264 ustawienia małego zużycia procesora, zwiększa wielkość pliku)" Basic.Settings.Output.VideoBitrate="Bitrate obrazu" Basic.Settings.Output.AudioBitrate="Bitrate dźwięku" @@ -334,6 +368,8 @@ Basic.Settings.Output.Adv.Recording.Type="Typ" Basic.Settings.Output.Adv.Recording.Type.Standard="Standardowe" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Niestandardowe ustawienia (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Użyj enkodera streamu)" +Basic.Settings.Output.Adv.Recording.Filename="Format nazwy pliku" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Nadpisz istniejący plik" Basic.Settings.Output.Adv.FFmpeg.Type="Tryb wyjścia FFmpeg" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Wyjście do adresu URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Wyjście do pliku" @@ -354,6 +390,10 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Enkoder dźwięku" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Ustawienia enkodera audio (jeśli są)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Ustawienia muxera (jeżeli są)" +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 Rok, cztery cyfry\n%YY Rok, ostatnie dwie cyfry (00-99)\n%MM Miesiąc, liczba dziesiętna, dwie cyfry (01-12)\n%DD Dzień, liczba dziesiętna, dwie cyfry (01-31)\n%hh Godzina, format 24-godzinny, dwie cyfry (00-23)\n%mm Minuta (00-59)\n%ss Sekunda (00-61)\n%% Znak %\n%a Dzień tygodnia, skrót\n%A Dzień tygodnia, pełna nazwa\n%b Nazwa miesiąca, skrót\n%B Nazwa miesiąca, pełna nazwa\n%d Dzień miesiąca, dwie cyfry (01-31)\n%H Godzina, format 24-godzinny, dwie cyfry (00-23)\n%I Godzina, format 12-godzinny, dwie cyfry (01-12)\n%m Miesiąc, dwie cyfry (01-12)\n%M Minuta (00-59)\n%p oznaczenie przed lub po południu\n%S Sekunda (00-61)\n%y Rok, ostatnie dwie cyfry (00-99)\n%Y Rok\n%z ISO 8601, przesunięcie od czasu UTC\n nazwa lub skrót\n%Z Nazwa lub skrót strefy czasowej\n" + Basic.Settings.Video="Obraz" Basic.Settings.Video.Adapter="Karta graficzna:" Basic.Settings.Video.BaseResolution="Rozdzielczość bazowa (obraz):" diff --git a/obs/data/locale/pt-BR.ini b/obs/data/locale/pt-BR.ini index 6f8b210..42b33e1 100644 --- a/obs/data/locale/pt-BR.ini +++ b/obs/data/locale/pt-BR.ini @@ -8,6 +8,7 @@ Cancel="Cancelar" Close="Fechar" Save="Salvar" Discard="Não Salvar" +Disable="Desabilitar" Yes="Sim" No="Não" Add="Adicionar" @@ -38,8 +39,32 @@ Untitled="Sem nome" New="Novo" Duplicate="Duplicar" Enable="Habilitar" +DisableOSXVSync="Desabilitar V-Sync em OSX" +ResetOSXVSyncOnExit="Resetar V-Sync em OSX ao Sair" +HighResourceUsage="Codificação sobrecarregada! Considere abaixar as configurações de vídeo ou usar um padrão de codificação mais rápido." +Transition="Transição" +QuickTransitions="Transições Rápidas" +Left="Esquerda" +Right="Direita" +Top="Topo" +Bottom="Baixo" +QuickTransitions.SwapScenes="Trocar Cenas de Prévia/Saída após a Transição" +QuickTransitions.SwapScenesTT="Troca a preview e a saída após transicionar (se a a cena original de saída ainda exisitr).\nIsto não irá desfazer nenhuma mudança que foi feita na cena original da saída." +QuickTransitions.DuplicateScene="Duplicar Cena" +QuickTransitions.DuplicateSceneTT="Quando estiver editando a mesma cena, permite editar a visibilidade/transformação de fontes sem modificar a saída.\nPara editar as propriedades das fontes sem modificar a saída, habilite 'Fontes Duplicadas'.\nMudar este valor irá resetar a cena atual de saída (se ainda existir)." +QuickTransitions.EditProperties="Duplicar Fontes" +QuickTransitions.HotkeyName="Transição Rápida: %1" +Basic.AddTransition="Adicionar Transição Configurável" +Basic.RemoveTransition="Remover Transição Configurável" +Basic.TransitionProperties="Propriedades da Transição" +Basic.SceneTransitions="Transições de Cena" +Basic.TransitionDuration="Duração" +Basic.TogglePreviewProgramMode="Modo Estúdio" + +TransitionNameDlg.Text="Por favor, insira o nome da transição" +TransitionNameDlg.Title="Nome da Transição" TitleBar.Profile="Perfil" TitleBar.Scenes="Cenas" @@ -50,7 +75,11 @@ NameExists.Text="O Nome já está em uso." NoNameEntered.Title="Por favor digite um nome válido" NoNameEntered.Text="Você não pode usar nomes vazios." +ConfirmStart.Title="Iniciar Transmissão?" +ConfirmStart.Text="Tens certeza de que queres iniciar a transmissão?" +ConfirmStop.Title="Parar Transmissão?" +ConfirmStop.Text="Tens certeza de que queres parar a transmissão?" ConfirmExit.Title="Sair do OBS?" ConfirmExit.Text="OBS está ativo no momento. Todos as streams/gravações serão encerradas. Tem certeza que deseja sair?" @@ -61,7 +90,7 @@ ConfirmRemove.Text="Tem certeza que deseja remover '$1'?" Output.ConnectFail.Title="Falha ao conectar" Output.ConnectFail.BadPath="Caminho inválido ou URL inválida. Por favor verifique se as configurações estão válidas." Output.ConnectFail.ConnectFailed="Falha ao conectar com o Servidor" -Output.ConnectFail.InvalidStream="Não foi possível acessar o canal especificado ou a chave da stream. Isto pode ser porque o canal/chave é inválido, ou porque o servidor ainda acha que você está logado." +Output.ConnectFail.InvalidStream="Não foi possível acessar o canal especificado ou a chave de transmissão, por favor, verifique sua chave de transimissão. Se estiver correta, pode haver um problema em conectar ao servidor." Output.ConnectFail.Error="Um erro inesperado ocorreu ao tentar se conectar com o servidor. Veja o arquivo de Log para mais informações." Output.ConnectFail.Disconnected="Desconectado do Servidor." @@ -88,7 +117,6 @@ LicenseAgreement.Exit="Sair" Remux.SourceFile="OBS Gravando" Remux.TargetFile="Arquivo de destino" Remux.Remux="Remux" -Remux.RecordingPattern="OBS Gravando (*.flv)" Remux.FinishedTitle="Remux finalizado" Remux.Finished="Remux da gravação finalizado" Remux.FinishedError="Remux da gravação finalizado, mas o arquivo pode estar incompleto" @@ -110,10 +138,19 @@ Basic.AuxDevice3="Mic/Aux 3" Basic.AuxDevice4="Mic/Aux 4" Basic.Scene="Cena" -Basic.DisplayCapture="Captura de Exposição" +Basic.DisplayCapture="Captura de tela" Basic.Main.PreviewConextMenu.Enable="Ativar pré-vizualização" +Deinterlacing.Discard="Descartar" +Deinterlacing.Retro="Retro" +Deinterlacing.Blend="Misturar" +Deinterlacing.Blend2x="Misturar 2x" +Deinterlacing.Linear="Linear" +Deinterlacing.Linear2x="Linear 2x" +Deinterlacing.TopFieldFirst="Campo Superior Primeiro" +Deinterlacing.BottomFieldFirst="Campo Inferior Primeiro" + Basic.Main.AddSceneDlg.Title="Adicionar Cena" Basic.Main.AddSceneDlg.Text="Por favor, digite o nome da cena" @@ -134,7 +171,7 @@ Basic.Main.PreviewDisabled="A pré-visualização esta desativada" Basic.SourceSelect="Criar/Selecionar Fonte" Basic.SourceSelect.CreateNew="Criar Nova" Basic.SourceSelect.AddExisting="Adicionar Existente" -Basic.SourceSelect.AddVisible="Tornar a fonte visível" +Basic.SourceSelect.AddVisible="Tornar a Fonte visível" Basic.PropertiesWindow="Propriedades para '%1'" Basic.PropertiesWindow.AutoSelectFormat="%1 (seleção automática: %2)" @@ -149,7 +186,7 @@ Basic.PropertiesWindow.AddEditableListFiles="Adicionar arquivos para '%1'" Basic.PropertiesWindow.AddEditableListEntry="Adicionar entrada a '%1'" Basic.PropertiesWindow.EditEditableListEntry="Editar a entrada de '%1'" -Basic.PropertiesView.FPS.Simple="Valores de FPS simples" +Basic.PropertiesView.FPS.Simple="Valores de FPS Simples" Basic.PropertiesView.FPS.Rational="Valores de FPS racionais" Basic.PropertiesView.FPS.ValidFPSRanges="Intervalos de FPS válidos:" @@ -179,6 +216,7 @@ Basic.TransformWindow.Alignment="Alinhamento da Posição" Basic.TransformWindow.BoundsType="Tipo da caixa delimitadora" Basic.TransformWindow.BoundsAlignment="Alinhamento na caixa delimitadora" Basic.TransformWindow.Bounds="Tamanho da Caixa Delimitadora" +Basic.TransformWindow.Crop="Cortar" Basic.TransformWindow.Alignment.TopLeft="Superior esquerdo" Basic.TransformWindow.Alignment.TopCenter="Superior Central" @@ -218,6 +256,7 @@ Basic.MainMenu.File.Remux="Re&mux gravações" Basic.MainMenu.File.Settings="&Configurações" Basic.MainMenu.File.ShowSettingsFolder="Mostrar pasta de configurações" Basic.MainMenu.File.ShowProfileFolder="Mostrar pasta de perfil" +Basic.MainMenu.AlwaysOnTop="&Sempre no Topo" Basic.MainMenu.File.Exit="&Sair" Basic.MainMenu.Edit="&Editar" @@ -262,6 +301,12 @@ Basic.Settings.Confirm="Você tem alterações não salvas. Salvar as alteraç Basic.Settings.General="Geral" Basic.Settings.General.Theme="Tema" Basic.Settings.General.Language="Idioma" +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.ScreenSnapping="Encaixar Fontes ás bordas da tela" +Basic.Settings.General.CenterSnapping="Encaixar Fontes aos centros vertical e horizontal" +Basic.Settings.General.SourceSnapping="Encaixar fontes com outras fontes" +Basic.Settings.General.SnapDistance="Sensibilidade de Encaixamento" Basic.Settings.Stream="Stream" Basic.Settings.Stream.StreamType="Tipo de Stream" @@ -271,6 +316,7 @@ Basic.Settings.Output.Format="Formato de gravação" 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.Mode="Modo de Saída" Basic.Settings.Output.Mode.Simple="Simples" Basic.Settings.Output.Mode.Adv="Avançado" @@ -281,6 +327,8 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Mesmo que a stream" Basic.Settings.Output.Simple.RecordingQuality.Small="Alta qualidade, tamanho médio" Basic.Settings.Output.Simple.RecordingQuality.HQ="Qualidade indistinguível, Tamanho grande" 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.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?" @@ -295,6 +343,7 @@ 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="Predefinição de codificação (maior = menor uso de CPU)" Basic.Settings.Output.CustomEncoderSettings="Configurações de codificador personalizadas" +Basic.Settings.Output.NoSpaceFileName="Gerar Nome de Arquivo sem Espaços" Basic.Settings.Output.Adv.Rescale="Redimensionar a saída" Basic.Settings.Output.Adv.AudioTrack="Faixa de áudio" @@ -310,6 +359,8 @@ Basic.Settings.Output.Adv.Recording.Type="Tipo" Basic.Settings.Output.Adv.Recording.Type.Standard="Padrão" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Saída personalizada (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Utilizar o codificador da transmissão)" +Basic.Settings.Output.Adv.Recording.Filename="Formatação de Nome de Arquivo" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Substituir, se o arquivo existir" Basic.Settings.Output.Adv.FFmpeg.Type="Tipo de saída FFmpeg" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Saída para URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Exportar para arquivo" @@ -330,6 +381,9 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Codificador de áudio" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Configurações do codificador de áudio(se houver)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Configurações do Muxer (se houver)" + +FilenameFormatting.TT="%CCYY Ano, quatro dígitos\n%YY Ano, dois dígitos (00-99)\n%MM Mês como um número decimal (01-12)\n%DD Dia do mês, começando com 0 (01-31)\n%hh Hora, em formato de 24h (00-23)\n%mm Minuto (00-59)\n%ss Segundo (00-61)\n%% A % sign\n%a Dia da Semana abreviado\n%A Nome da Semana completo\n%b Nome do Mês abreviado\n%B Nome do Mês completo\n%d Dia do Mês, começando com 0 (01-31)\n%H Hora, no formato de 24h (00-23)\n%I Hora no formato de 12h (01-12)\n%m Mês como um número decimal (01-12)\n%M Minuto (00-59)\n%p Designação AM ou PM\n%S Segundo (00-61)\n%y Ano, últimos dois dígitos (00-99)\n%Y Ano\n%z ISO 8601 diferença de fuso horário ou de UTC\n nome ou abreviação\n%Z Nome do Fuso Horário ou abreviação\n" + Basic.Settings.Video="Vídeo" Basic.Settings.Video.Adapter="Adaptador de Vídeo:" Basic.Settings.Video.BaseResolution="Resolução de base (tela):" @@ -363,6 +417,7 @@ Basic.Settings.Audio.EnablePushToMute="Ativar pressionar-para-mutar" Basic.Settings.Audio.PushToMuteDelay="Delay do Pressionar-para-mutar" Basic.Settings.Audio.EnablePushToTalk="Ativar pressionar-para-falar" Basic.Settings.Audio.PushToTalkDelay="Delay do pressionar-para-falar" +Basic.Settings.Audio.UnknownAudioDevice="[Dispositivo nao conectado ou não disponível]" Basic.Settings.Advanced="Avançado" Basic.Settings.Advanced.FormatWarning="Aviso: Formatos de cor diferentes do NV12 destinam-se principalmente para gravação e não são recomendados para transmissão. Durante a transmissão pode ocorrer aumento do uso da CPU devido a conversão do formato de cor." diff --git a/obs/data/locale/pt-PT.ini b/obs/data/locale/pt-PT.ini index fd50c23..95eb5cb 100644 --- a/obs/data/locale/pt-PT.ini +++ b/obs/data/locale/pt-PT.ini @@ -8,6 +8,7 @@ Cancel="Cancelar" Close="Fechar" Save="Guardar" Discard="Rejeitar" +Disable="Desativar" Yes="Sim" No="Não" Add="Adicionar" @@ -38,7 +39,17 @@ Untitled="Sem título" New="Novo" Duplicate="Duplicar" Enable="Ativar" +Transition="Transição" +QuickTransitions="Transições rápidas" +Left="Esquerda" +Right="Direita" +Top="Cima" +Bottom="Baixo" +QuickTransitions.DuplicateScene="Duplicar cena" + +Basic.RemoveTransition="Remover transição configurável" +Basic.TransitionProperties="Propriedades da transição" TitleBar.Profile="Perfil" @@ -59,9 +70,8 @@ ConfirmRemove.Title="Comfirmar Remover" ConfirmRemove.Text="Tem a certeza que quer remover '$1'?" Output.ConnectFail.Title="Falha ao ligar" -Output.ConnectFail.BadPath="Caminho inválido ou erro no endereço. Por favor verifiique as definições e confirme que são válidas." +Output.ConnectFail.BadPath="Caminho ou endereço de ligação inválido. Por favor, verifique as suas definições para confirmar que são válidas." Output.ConnectFail.ConnectFailed="Falhou a ligação ao servidor" -Output.ConnectFail.InvalidStream="Sem acesso ao canal ou chave de stream. Pode ser porque a chave ou o canal é inválido, ou porque o servidor pensa que voçê ainda encontra-se ligado." Output.ConnectFail.Error="Ocurreu um erro inesperado ao ligar-se ao servidor. Mais informação no ficheiro Log." Output.ConnectFail.Disconnected="Desligado do servidor." @@ -76,7 +86,7 @@ Output.BadPath.Title="Caminho de Ficheiro de Gravação Inválido" Output.BadPath.Text="O caminho de ficheiro de gravação definido é inválido. Por favor verifique as definições e confirme que um caminho válido foi introduzido." LogReturnDialog="Envio de Log Sucedido" -LogReturnDialog.CopyURL="Copiar endereçoCopy URL" +LogReturnDialog.CopyURL="Copiar endereço" LogReturnDialog.ErrorUploadingLog="Erro no envio de ficheiro Log" LicenseAgreement="Termos e condições da licença" @@ -88,7 +98,6 @@ LicenseAgreement.Exit="Sair" Remux.SourceFile="Gravação do OBS" Remux.TargetFile="Ficheiro de destino" Remux.Remux="Remisturar" -Remux.RecordingPattern="Gravação do OBS (*.flv)" Remux.FinishedTitle="Remistura concluída" Remux.Finished="Gravação remisturada" Remux.FinishedError="Gravação remisturada, mas o ficheiro pode estar incompleto" @@ -100,7 +109,7 @@ Remux.ExitUnfinishedTitle="Remistura em progresso" Remux.ExitUnfinished="A remistura não está concluída. Ao parar agora pode tornar o ficheiro de destino inutilizável.\nTem a certeza de que pretende para a remistura?" UpdateAvailable="Nova atualização disponível" -UpdateAvailable.Text="Versão %1. %2. %3 está agora disponível. clique aqui para baixar" +UpdateAvailable.Text="Versão %1.%2.%3 está agora disponível. Clique aqui para descarregar" Basic.DesktopDevice1="Desktop Audio" Basic.DesktopDevice2="Desktop Audio 2" @@ -114,6 +123,7 @@ Basic.DisplayCapture="Captura de Ecrã" Basic.Main.PreviewConextMenu.Enable="Ativar pré-visualização" + Basic.Main.AddSceneDlg.Title="Adicionar Cena" Basic.Main.AddSceneDlg.Text="Por favor introduza o nome da cena" @@ -205,9 +215,9 @@ Basic.Main.Scenes="Cenas" Basic.Main.Sources="Fontes" Basic.Main.Connecting="A ligar..." Basic.Main.StartRecording="Começar Gravação" -Basic.Main.StartStreaming="Começar Stream" +Basic.Main.StartStreaming="Iniciar transmissão" Basic.Main.StopRecording="Parar Gravação" -Basic.Main.StopStreaming="Parar Stream" +Basic.Main.StopStreaming="Parar transmissão" Basic.Main.ForceStopStreaming="Parar transmissão (ignorar atraso)" Basic.MainMenu.File="&Ficheiro" @@ -253,7 +263,7 @@ Basic.MainMenu.Help.Logs.ShowLogs="Most&rar ficheiros de registo" Basic.MainMenu.Help.Logs.UploadCurrentLog="Enviar Ficheiro &Currente de Log" Basic.MainMenu.Help.Logs.UploadLastLog="Enviar Ultímo Ficheiro de &Log" Basic.MainMenu.Help.Logs.ViewCurrentLog="&Ver registo atual" -Basic.MainMenu.Help.CheckForUpdates="Verificar se há atualizações" +Basic.MainMenu.Help.CheckForUpdates="Procurar atualizações" Basic.Settings.ProgramRestart="O programa necessita de ser reinicializado para estas alterações terem efeito." Basic.Settings.ConfirmTitle="Confirmar Alterações" @@ -263,15 +273,15 @@ Basic.Settings.General="Geral" Basic.Settings.General.Theme="Tema" Basic.Settings.General.Language="Idioma" -Basic.Settings.Stream="Stream" -Basic.Settings.Stream.StreamType="Tipo de Stream" +Basic.Settings.Stream="Transmissão" +Basic.Settings.Stream.StreamType="Tipo de transmissão" -Basic.Settings.Output="Saída Output" +Basic.Settings.Output="Saída" Basic.Settings.Output.Format="Formato de gravação" Basic.Settings.Output.Encoder="Codificador" Basic.Settings.Output.SelectDirectory="Selecione o diretório de gravação" Basic.Settings.Output.SelectFile="Selecione ficheiro de gravação" -Basic.Settings.Output.Mode="Modo de Saída" +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 FFmpeg" @@ -323,6 +333,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Definições do codificador d Basic.Settings.Output.Adv.FFmpeg.AEncoder="Codificador de áudio" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Definições do codificador de áudio (se houver)" + + Basic.Settings.Video="Vídeo" Basic.Settings.Video.Adapter="Adaptador de Vídeo:" Basic.Settings.Video.DownscaleFilter="Filtro de Escalamento:" diff --git a/obs/data/locale/ro-RO.ini b/obs/data/locale/ro-RO.ini index 5790762..6b5b259 100644 --- a/obs/data/locale/ro-RO.ini +++ b/obs/data/locale/ro-RO.ini @@ -2,425 +2,464 @@ Language="Română" Region="România" -OK="OK" +OK="Ok" Apply="Aplică" -Cancel="Anulare" -Close="Inchide" -Save="Salvaţi" -Discard="Renunţă" +Cancel="Anulează" +Close="Închide" +Save="Salvează" +Discard="Înlătură" +Disable="Dezactivează" Yes="Da" No="Nu" Add="Adaugă" -Remove="Eliminaţi" -Rename="Redenumiţi" -Interact="Interacţioneaza" +Remove="Elimină" +Rename="Redenumește" +Interact="Interacționează" Filters="Filtre" -Properties="Proprietăţi" +Properties="Proprietăți" MoveUp="Mută în sus" MoveDown="Mută în jos" Settings="Setări" Display="Display" Name="Nume" -Exit="Ieșire" +Exit="Ieși" Mixer="Mixer" -Browse="Căutare" +Browse="Răsfoiește" Mono="Mono" Stereo="Stereo" -DroppedFrames="Cadre Pierdute %1 (%2%)" +DroppedFrames="Cadre pierdute %1 (%2%)" PreviewProjector="Proiector pe tot ecranul (Previzualizare)" -SceneProjector="Proiector pe tot ecranul (Scena)" -SourceProjector="Proiector pe tot ecranul (Sursa)" -Clear="Ştergeţi" -Revert="Inverseaza" +SceneProjector="Proiector pe tot ecranul (Scenă)" +SourceProjector="Proiector pe tot ecranul (Sursă)" +Clear="Șterge" +Revert="Inversează" Show="Arată" Hide="Ascunde" -Untitled="Fără Nume" +Untitled="Fără nume" New="Nou" Duplicate="Duplică" Enable="Activează" -DisableOSXVSync="Dezactivaţi OSX V-Sync" -ResetOSXVSyncOnExit="Resetare OSX V-Sync la Ieşire" -HighResourceUsage="Codificarea supraîncărcata! Luaţi în considerare reducerea setărilor video sau folosirea unui preset de codare mai rapid." -Transition="Tranziţie" -QuickTransitions="Tranziţii rapide" +DisableOSXVSync="Dezactivează OSX V-Sync" +ResetOSXVSyncOnExit="Resetează OSX V-Sync la ieșire" +HighResourceUsage="Codificare supraîncărcată! Ia în considerare reducerea setărilor video sau folosirea unei presetări de codare mai rapidă." +Transition="Tranziție" +QuickTransitions="Tranziții rapide" +Left="Stânga" +Right="Dreapta" +Top="Sus" +Bottom="Jos" -QuickTransitions.SwapScenes="Schimba Previzualizarea/Scena de Output dupa Tranzitionare" +QuickTransitions.SwapScenes="Comută între previzualizare/scenele de ieșire după tranziționare" QuickTransitions.SwapScenesTT="Schimba previzualizarea si scenele de output dupa tranzitionare (în cazul în care încă există outputul scenei originale). \nAceasta nu va anula nicio modificăre care au fost făcute la outputul scenei originale." -QuickTransitions.DuplicateScene="Scena Dublata" +QuickTransitions.DuplicateScene="Duplică scena" QuickTransitions.DuplicateSceneTT="La editarea aceleiaşi scene, permite editarea transformarii/vizibilitatii surselor fără modificarea output-ului. \nPentru a edita proprietăţile surselor fără a modifica output-ul, activaţi 'Surse Dublate'. \nSchimband această valoare va reseta outputul scenei curente (în cazul în care încă mai există)." -QuickTransitions.EditProperties="Surse Dublate" +QuickTransitions.EditProperties="Surse duplicate" QuickTransitions.EditPropertiesTT="La editarea aceleiaşi scene, permite editarea proprietăţilor surselor fără modificareaa outputului. \nAceasta poate fi utilizat doar dacă este activată 'Scena Dublata'. \nAnumite surse (cum ar fi sursele de captare sau mass-media) nu acceptă acest lucru şi nu poate fi editat separat. \nSchimband această valoare va reseta outputul scenei curente (în cazul în care încă mai există).\n\nAtentie: deoarece sursele vor fi dublate, aceasta poate solicita suplimentar sistemul sau resursele video." -QuickTransitions.HotkeyName="Tranziţie rapidă: %1" +QuickTransitions.HotkeyName="Tranziție rapidă: %1" -Basic.SceneTransitions="Tranzitii de Scene" -Basic.TransitionDuration="Durata" -Basic.TogglePreviewProgramMode="Modul de studio" +Basic.AddTransition="Adaugă tranziție configurabilă" +Basic.RemoveTransition="Elimină tranziția configurabilă" +Basic.TransitionProperties="Proprietăți pentru tranziții" +Basic.SceneTransitions="Tranziții pentru scene" +Basic.TransitionDuration="Durată" +Basic.TogglePreviewProgramMode="Mod studio" + +TransitionNameDlg.Text="Te rugăm să introduci numele tranziției" +TransitionNameDlg.Title="Numele tranziției" TitleBar.Profile="Profil" TitleBar.Scenes="Scene" NameExists.Title="Numele există deja" -NameExists.Text="Acest nume este deja folosit." +NameExists.Text="Numele este deja în uz." -NoNameEntered.Title="Va rugăm introduceţi un nume valid" -NoNameEntered.Text="Nu puteți utiliza un nume gol." +NoNameEntered.Title="Te rugăm să introduci un nume valid" +NoNameEntered.Text="Nu poți folosi nume necompletate." -ConfirmStart.Title="Pornire Stream?" -ConfirmStart.Text="Sunteţi sigur că doriţi să începeţi streamul?" +ConfirmStart.Title="Începi streamul?" +ConfirmStart.Text="Sigur dorești să pornești streamul?" -ConfirmStop.Title="Oprire Stream?" -ConfirmStop.Text="Sunteţi sigur că doriţi să opriţi streamul?" +ConfirmStop.Title="Oprești streamul?" +ConfirmStop.Text="Sigur dorești să oprești streamul?" -ConfirmExit.Title="Ieşiţi din OBS?" -ConfirmExit.Text="OBS este în prezent activ. Toate stream-urile/înregistrările vor fi închise. Sunteţi sigur că doriţi să ieşiţi?" +ConfirmExit.Title="Ieși din OBS?" +ConfirmExit.Text="OBS este în prezent activ. Toate streamurile/înregistrările vor fi închise. Sigur dorești să ieși?" -ConfirmRemove.Title="Confirmă Ştergere" -ConfirmRemove.Text="Sigur eliminaţi '$1'?" +ConfirmRemove.Title="Confirmă eliminarea" +ConfirmRemove.Text="Sigur dorești să elimini „$1”?" -Output.ConnectFail.Title="Nu a reuşit să se conecteze" -Output.ConnectFail.BadPath="Link URL sau rută greșită. Vă rugăm să verificaţi setările pentru a confirma că sunt corecte." -Output.ConnectFail.ConnectFailed="Nu a reușit conectarea la server" -Output.ConnectFail.InvalidStream="Nu s-a putut accesa canalul sau codul de stream. Acest lucru s-ar putea întampla deoarece canalul/codul nu este valid, sau pentru că serverul încă mai crede că sunteţi logat." +Output.ConnectFail.Title="Eșec la conectare" +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 stream respectiva, vă rugăm să verificaţi cheia de stream. Dacă aceasta este corectă, poate fi o problemă la 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.RecordFail.Title="Inregistrarea nu a putut fi pornita" +Output.RecordFail.Title="Eșec la pornirea înregistrării" Output.RecordFail.Unsupported="Formatul de ieşire este fie neacceptat sau nu acceptă mai multe piese audio. Vă rugăm să verificaţi setările şi încercaţi din nou." -Output.RecordNoSpace.Title="Spațiu insuficient" -Output.RecordNoSpace.Msg="Nu este suficient spațiu pentru a continua înregistrarea." +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.Msg="O eroare nespecificată a avut loc în timpul înregistrarii." +Output.RecordError.Msg="S-a produs o eroare nespecificată în timpul înregistrării." -Output.BadPath.Title="Calea de fişier greşita" +Output.BadPath.Title="Calea fișierului greșită" Output.BadPath.Text="Calea de ieşire pentru fişiere invalidă. Vă rugăm să verificaţi setările pentru a confirma că s-a stabilit o cale de fişier validă." LogReturnDialog="Jurnal incărcat cu succes" -LogReturnDialog.CopyURL="Copiază URL" -LogReturnDialog.ErrorUploadingLog="Eroare la încărcarea fişierul jurnal" +LogReturnDialog.CopyURL="Copiază URL-ul" +LogReturnDialog.ErrorUploadingLog="Eroare la încărcarea fișierului jurnal" -LicenseAgreement="Acord de licenţă" +LicenseAgreement="Acord de licență" LicenseAgreement.PleaseReview="Vă rugăm să revedeţi termenii de licenţă înainte de a utiliza OBS. Utilizând acest program, confirmaţi că aţi citit şi sunt de acord cu termenii Licenței Publice Generale GNU v2.0. Vă rugăm să derulaţi în jos pentru a vedea restul acordului." LicenseAgreement.ClickIAgreeToContinue="Dacă acceptaţi termenii acordului, faceţi clic pe Sunt de acord să continuaţi. Trebuie să acceptaţi acordul pentru a utiliza OBS." LicenseAgreement.IAgree="Sunt de acord" LicenseAgreement.Exit="Ieși" Remux.SourceFile="Înregistrare OBS" -Remux.TargetFile="Fişierul ţintă" +Remux.TargetFile="Fișier țintă" Remux.Remux="Remux" -Remux.RecordingPattern="Înregistrare OBS (*.flv)" -Remux.FinishedTitle="Remux terminat" -Remux.Finished="Înregistrare remuxata" -Remux.FinishedError="Înregistrare remuxata, dar fişierul poate fi incomplet" -Remux.SelectRecording="Selectaţi înregistrarea OBS …" -Remux.SelectTarget="Selectaţi fişierul ţintă …" +Remux.FinishedTitle="Remuxing încheiat" +Remux.Finished="Înregistrare remuxată" +Remux.FinishedError="Înregistrare remuxată, însă fișierul poate fi incomplet" +Remux.SelectRecording="Selectează înregistrarea OBS …" +Remux.SelectTarget="Selectează fișierul țintă …" Remux.FileExistsTitle="Fișierul țintă există" -Remux.FileExists="Fişierul ţintă există, doriţi să-l înlocuiască?" -Remux.ExitUnfinishedTitle="Remuxing în curs de desfăşurare" -Remux.ExitUnfinished="Remuxing nu este terminat, oprirea imediata poate face fişierul ţintă inutilizabil. \nSunteți sigur că doriţi să opriţi remuxing?" +Remux.FileExists="Fișierul țintă există, dorești să-l înlocuiești?" +Remux.ExitUnfinishedTitle="Remuxing în desfășurare" +Remux.ExitUnfinished="Remuxingul nu este încheiat, oprirea în acest moment poate face fișierul țintă inutilizabil.\nSigur dorești să oprești remuxingul?" -UpdateAvailable="O Nouă Actualizare Este Disponibilă" -UpdateAvailable.Text="Versiunea %1.%2.%3 este acum disponibilă. Click aici pentru a descarca" +UpdateAvailable="Actualizare nouă disponibilă" +UpdateAvailable.Text="Versiunea %1.%2.%3 este acum disponibilă. Clic aici pentru a descărca" -Basic.DesktopDevice1="Desktop Audio" -Basic.DesktopDevice2="Desktop Audio 2" +Basic.DesktopDevice1="Desktop audio" +Basic.DesktopDevice2="Desktop audio 2" Basic.AuxDevice1="Microfon/Aux" Basic.AuxDevice2="Microfon/Aux 2" Basic.AuxDevice3="Microfon/Aux 3" Basic.AuxDevice4="Microfon/Aux 4" -Basic.Scene="Scena" -Basic.DisplayCapture="Captura de ecran" +Basic.Scene="Scenă" +Basic.DisplayCapture="Captură de display" -Basic.Main.PreviewConextMenu.Enable="Activeaza previzualizarea" +Basic.Main.PreviewConextMenu.Enable="Activează previzualizarea" -Basic.Main.AddSceneDlg.Title="Adauga scena" -Basic.Main.AddSceneDlg.Text="Vă rugăm să introduceţi numele de scena" +Deinterlacing="Deîntrețesere" +Deinterlacing.Discard="Înlătură" +Deinterlacing.Retro="Retro" +Deinterlacing.Blend="Amestecare" +Deinterlacing.Blend2x="Amestecare 2x" +Deinterlacing.Linear="Liniară" +Deinterlacing.Linear2x="Liniară 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Câmpul de sus prima oară" +Deinterlacing.BottomFieldFirst="Câmpul de jos prima oară" + +Basic.Main.AddSceneDlg.Title="Adaugă scenă" +Basic.Main.AddSceneDlg.Text="Te rugăm să introduci numele scenei" Basic.Main.DefaultSceneName.Text="Scena %1" -Basic.Main.AddSceneCollection.Title="Adauga o colectie de scene" -Basic.Main.AddSceneCollection.Text="Vă rugăm să introduceţi numele colectiei de scene" +Basic.Main.AddSceneCollection.Title="Adaugă colecție de scene" +Basic.Main.AddSceneCollection.Text="Te rugăm să introduci numele colecției de scene" -Basic.Main.RenameSceneCollection.Title="Redenumiţi colectia de scene" +Basic.Main.RenameSceneCollection.Title="Redenumește colecția de scene" AddProfile.Title="Adaugă profil" -AddProfile.Text="Vă rugăm să introduceţi numele profilului" +AddProfile.Text="Te rugăm să introduci numele profilului" -RenameProfile.Title="Redenumește profil" +RenameProfile.Title="Redenumește profilul" Basic.Main.PreviewDisabled="Previzualizarea este în prezent dezactivată" -Basic.SourceSelect="Creaţi/Selectaţi Sursa" +Basic.SourceSelect="Creează/Selectează sursa" Basic.SourceSelect.CreateNew="Creează nouă" Basic.SourceSelect.AddExisting="Adaugă existentă" -Basic.SourceSelect.AddVisible="Faceți vizibilă sursa" +Basic.SourceSelect.AddVisible="Fă sursa vizibilă" -Basic.PropertiesWindow="Proprietăţi pentru '%1'" -Basic.PropertiesWindow.AutoSelectFormat="%1 (Selectare automată: %2)" -Basic.PropertiesWindow.SelectColor="Selectaţi culoarea" -Basic.PropertiesWindow.SelectFont="Selectează Fontul" -Basic.PropertiesWindow.ConfirmTitle="Setări Schimbate" -Basic.PropertiesWindow.Confirm="Există modificări nesalvate. Vrei să le păstrezi?" -Basic.PropertiesWindow.NoProperties="Nicio proprietate disponibila" -Basic.PropertiesWindow.AddFiles="Adăugaţi fişiere" -Basic.PropertiesWindow.AddURL="Adauga calea/URL" -Basic.PropertiesWindow.AddEditableListFiles="Adăuga fişiere la \"%1\"" -Basic.PropertiesWindow.AddEditableListEntry="Adăugaţi intrare la \"%1\"" -Basic.PropertiesWindow.EditEditableListEntry="Editeaza intrarea de la \"%1\"" +Basic.PropertiesWindow="Proprietăți pentru '%1'" +Basic.PropertiesWindow.AutoSelectFormat="%1 (autoselectare: %2)" +Basic.PropertiesWindow.SelectColor="Selectează culoarea" +Basic.PropertiesWindow.SelectFont="Selectează fontul" +Basic.PropertiesWindow.ConfirmTitle="Setări schimbate" +Basic.PropertiesWindow.Confirm="Există modificări nesalvate. Dorești să le păstrezi?" +Basic.PropertiesWindow.NoProperties="Nicio proprietate disponibilă" +Basic.PropertiesWindow.AddFiles="Adaugă fișiere" +Basic.PropertiesWindow.AddURL="Adaugă cale/URL" +Basic.PropertiesWindow.AddEditableListFiles="Adaugă fișiere la '%1'" +Basic.PropertiesWindow.AddEditableListEntry="Adaugă intrare la '%1'" +Basic.PropertiesWindow.EditEditableListEntry="Editează intrarea de la '%1'" -Basic.PropertiesView.FPS.Simple="Valori FPS Simple" -Basic.PropertiesView.FPS.Rational="Valori FPS Raţionale" -Basic.PropertiesView.FPS.ValidFPSRanges="Intervale de FPS valabile:" +Basic.PropertiesView.FPS.Simple="Valori FPS simple" +Basic.PropertiesView.FPS.Rational="Valori FPS raționale" +Basic.PropertiesView.FPS.ValidFPSRanges="Intervale FPS valide:" Basic.InteractionWindow="Interacționează cu '%1'" -Basic.StatusBar.Reconnecting="Deconectat, reconectare în %2 secunda(e) (încercarea %1)" -Basic.StatusBar.AttemptingReconnect="Încearcă să se reconecteze... (încercarea %1)" -Basic.StatusBar.ReconnectSuccessful="Reconectat cu succes" +Basic.StatusBar.Reconnecting="Deconectat, se reconectează în %2 secunda(e) (încercarea %1)" +Basic.StatusBar.AttemptingReconnect="Se încearcă reconectarea... (încercarea %1)" +Basic.StatusBar.ReconnectSuccessful="Reconectare cu succes" Basic.StatusBar.Delay="Întârziere (%1 secunde)" -Basic.StatusBar.DelayStartingIn="Întârziere (începând cu %1 sec)" -Basic.StatusBar.DelayStoppingIn="Întârziere (oprirea în %1 sec)" -Basic.StatusBar.DelayStartingStoppingIn="Întârziere (oprindu-se în %1 sec, începând in %2 sec)" +Basic.StatusBar.DelayStartingIn="Întârziere (începând în %1 sec)" +Basic.StatusBar.DelayStoppingIn="Întârziere (oprindu-se în %1 sec)" +Basic.StatusBar.DelayStartingStoppingIn="Întârziere (oprindu-se în %1 sec, începând în %2 sec)" Basic.Filters="Filtre" -Basic.Filters.AsyncFilters="Filtre audio/Video" +Basic.Filters.AsyncFilters="Filtre audio/video" Basic.Filters.AudioFilters="Filtre audio" Basic.Filters.EffectFilters="Filtre de efect" -Basic.Filters.Title="Filtre pentru \"%1\"" -Basic.Filters.AddFilter.Title="Denumire filtru" -Basic.Filters.AddFilter.Text="Vă rugăm să specificaţi numele filtrului" +Basic.Filters.Title="Filtre pentru „%1”" +Basic.Filters.AddFilter.Title="Numele filtrului" +Basic.Filters.AddFilter.Text="Te rugăm să specifici numele filtrului" -Basic.TransformWindow="Scena de transformare a obiectelor" -Basic.TransformWindow.Position="Poziţie" +Basic.TransformWindow="Transformare a elementelor pentru scene" +Basic.TransformWindow.Position="Poziție" Basic.TransformWindow.Rotation="Rotație" Basic.TransformWindow.Size="Dimensiune" -Basic.TransformWindow.Alignment="Alinierea poziţiei" -Basic.TransformWindow.BoundsType="Tip caseta de încadrare" -Basic.TransformWindow.BoundsAlignment="Alinierea în caseta de încadrare" -Basic.TransformWindow.Bounds="Dimensiunea casetei de încadrare" +Basic.TransformWindow.Alignment="Aliniere pozițională" +Basic.TransformWindow.BoundsType="Tipul casetei de încadrare" +Basic.TransformWindow.BoundsAlignment="Aliniere în caseta de încadrare" +Basic.TransformWindow.Bounds="Mărime pentru caseta de încadrare" +Basic.TransformWindow.Crop="Trunchiază" Basic.TransformWindow.Alignment.TopLeft="Stânga sus" -Basic.TransformWindow.Alignment.TopCenter="Mijloc Sus" +Basic.TransformWindow.Alignment.TopCenter="Centru sus" Basic.TransformWindow.Alignment.TopRight="Dreapta sus" Basic.TransformWindow.Alignment.CenterLeft="Centru stânga" Basic.TransformWindow.Alignment.Center="Centru" Basic.TransformWindow.Alignment.CenterRight="Centru dreapta" Basic.TransformWindow.Alignment.BottomLeft="Stânga jos" -Basic.TransformWindow.Alignment.BottomCenter="Mijloc jos" +Basic.TransformWindow.Alignment.BottomCenter="Centru jos" Basic.TransformWindow.Alignment.BottomRight="Dreapta jos" Basic.TransformWindow.BoundsType.None="Fără limite" Basic.TransformWindow.BoundsType.MaxOnly="Doar dimensiunea maximă" Basic.TransformWindow.BoundsType.ScaleInner="Scalează la limitele interioare" Basic.TransformWindow.BoundsType.ScaleOuter="Scalează la limitele exterioare" -Basic.TransformWindow.BoundsType.ScaleToWidth="Scalează la lăţimea limitei" -Basic.TransformWindow.BoundsType.ScaleToHeight="Scalează la înălţimea limitei" +Basic.TransformWindow.BoundsType.ScaleToWidth="Scalează la lățimea limitei" +Basic.TransformWindow.BoundsType.ScaleToHeight="Scalează la înălțimea limitei" Basic.TransformWindow.BoundsType.Stretch="Întinde la limite" -Basic.Main.AddSourceHelp.Title="Imposibil de adăugat sursa" -Basic.Main.AddSourceHelp.Text="Trebuie să aveţi cel puţin o scena pentru a adăuga o sursă." +Basic.Main.AddSourceHelp.Title="Nu se poate adăuga sursă" +Basic.Main.AddSourceHelp.Text="Trebuie să ai cel puțin 1 scenă pentru a adăuga o sursă." Basic.Main.Scenes="Scene" Basic.Main.Sources="Surse" -Basic.Main.Connecting="Conectare..." -Basic.Main.StartRecording="Începe înregistrarea" -Basic.Main.StartStreaming="Porneşte Stream" +Basic.Main.Connecting="Se conectează..." +Basic.Main.StartRecording="Pornește înregistrarea" +Basic.Main.StartStreaming="Pornește streamingul" Basic.Main.StopRecording="Oprește înregistrarea" -Basic.Main.StopStreaming="Oprește streaming-ul" -Basic.Main.ForceStopStreaming="Oprire Streaming (renunţaţi la întârziere)" +Basic.Main.StopStreaming="Oprește streamingul" +Basic.Main.ForceStopStreaming="Oprește streamingul (renunță la întârziere)" -Basic.MainMenu.File="&Fişier" -Basic.MainMenu.File.Export="&Export" -Basic.MainMenu.File.Import="&Import" -Basic.MainMenu.File.ShowRecordings="Arată &Înregistrări" -Basic.MainMenu.File.Remux="Înregistrări &Remux" +Basic.MainMenu.File="&Fișier" +Basic.MainMenu.File.Export="&Exportă" +Basic.MainMenu.File.Import="&Importă" +Basic.MainMenu.File.ShowRecordings="Arată în®istrări" +Basic.MainMenu.File.Remux="Înregistrări re&mux" Basic.MainMenu.File.Settings="&Setări" -Basic.MainMenu.File.ShowSettingsFolder="Arată Folderul Setări" -Basic.MainMenu.File.ShowProfileFolder="Arată Folderul Profiluri" -Basic.MainMenu.AlwaysOnTop="&Întotdeauna Deasupra" +Basic.MainMenu.File.ShowSettingsFolder="Arată folderul cu setări" +Basic.MainMenu.File.ShowProfileFolder="Arată folderul cu profil" +Basic.MainMenu.AlwaysOnTop="Întotde&auna deasupra" Basic.MainMenu.File.Exit="Ieșire (&X)" Basic.MainMenu.Edit="&Editare" -Basic.MainMenu.Edit.Undo="&Inapoi" -Basic.MainMenu.Edit.Redo="&Refacere" -Basic.MainMenu.Edit.UndoAction="&Inapoi $1" -Basic.MainMenu.Edit.RedoAction="&Refaceţi $1" +Basic.MainMenu.Edit.Undo="An&ulează acțiunea" +Basic.MainMenu.Edit.Redo="&Refă acțiunea" +Basic.MainMenu.Edit.UndoAction="An&ulează $1" +Basic.MainMenu.Edit.RedoAction="&Refă $1" Basic.MainMenu.Edit.Transform="&Transformare" -Basic.MainMenu.Edit.Transform.EditTransform="&Editare transformare..." -Basic.MainMenu.Edit.Transform.ResetTransform="&Resetare transformare" -Basic.MainMenu.Edit.Transform.Rotate90CW="Rotire la 90 de grade conform acelor de ceasornic" -Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotire la 90 de grade invers acelor de ceasornic" -Basic.MainMenu.Edit.Transform.Rotate180="Rotește 180 de grade" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Răstoarnă &Orizontal" -Basic.MainMenu.Edit.Transform.FlipVertical="Răstoarnă &Vertical" +Basic.MainMenu.Edit.Transform.EditTransform="&Editează transformarea..." +Basic.MainMenu.Edit.Transform.ResetTransform="&Resetează transformarea" +Basic.MainMenu.Edit.Transform.Rotate90CW="Rotește la 90° (în sensul acelor ceasornicului)" +Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotește la 90° (în sensul contrar acelor ceasornicului)" +Basic.MainMenu.Edit.Transform.Rotate180="Rotește la 180°" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Răstoarnă &orizontal" +Basic.MainMenu.Edit.Transform.FlipVertical="Răstoarnă &vertical" Basic.MainMenu.Edit.Transform.FitToScreen="&Potrivește pe ecran" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Intinde pe ecran" +Basic.MainMenu.Edit.Transform.StretchToScreen="În&tinde pe ecran" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centrează pe ecran" -Basic.MainMenu.Edit.Order="&Ordine" -Basic.MainMenu.Edit.Order.MoveUp="Mută &Sus" -Basic.MainMenu.Edit.Order.MoveDown="Mută &Jos" -Basic.MainMenu.Edit.Order.MoveToTop="Mută &Prima" -Basic.MainMenu.Edit.Order.MoveToBottom="Mută &Ultima" -Basic.MainMenu.Edit.AdvAudio="&Proprietăţi Audio Avansate" +Basic.MainMenu.Edit.Order="&Ordonare" +Basic.MainMenu.Edit.Order.MoveUp="Mută &sus" +Basic.MainMenu.Edit.Order.MoveDown="Mută &jos" +Basic.MainMenu.Edit.Order.MoveToTop="Mu&tă în vârf" +Basic.MainMenu.Edit.Order.MoveToBottom="Mută la fu&nd" +Basic.MainMenu.Edit.AdvAudio="Proprietăți audio &avansate" -Basic.MainMenu.SceneCollection="Colectia de &Scene" +Basic.MainMenu.SceneCollection="Colecție de &scene" Basic.MainMenu.Profile="&Profil" Basic.MainMenu.Help="&Ajutor" -Basic.MainMenu.Help.Website="Vizitați site-ul &web" -Basic.MainMenu.Help.Logs="&Fişierele jurnal" -Basic.MainMenu.Help.Logs.ShowLogs="&Arată fişierele jurnal" +Basic.MainMenu.Help.Website="Vizitează site-ul &web" +Basic.MainMenu.Help.Logs="Fișiere jurna&l" +Basic.MainMenu.Help.Logs.ShowLogs="Arată &fișierele jurnal" Basic.MainMenu.Help.Logs.UploadCurrentLog="Încărcaţi &fişierul de Log curent" Basic.MainMenu.Help.Logs.UploadLastLog="Încărcaţi &ultimul fișier log" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Vezi log-ul curent" -Basic.MainMenu.Help.CheckForUpdates="Verifică pentru Actualizare" +Basic.MainMenu.Help.Logs.ViewCurrentLog="&Vezi log-ul actual" +Basic.MainMenu.Help.CheckForUpdates="Caută actualizări" Basic.Settings.ProgramRestart="Programul trebuie repornit pentru ca aceste setări să aibă efect." -Basic.Settings.ConfirmTitle="Confirmare modificări" -Basic.Settings.Confirm="Ai modificări nesalvate. Salvați modificările?" +Basic.Settings.ConfirmTitle="Confirmă modificările" +Basic.Settings.Confirm="Ai modificări nesalvate. Salvezi modificările?" -Basic.Settings.General="General" +Basic.Settings.General="Generale" Basic.Settings.General.Theme=" Temă" Basic.Settings.General.Language="Limbă" -Basic.Settings.General.WarnBeforeStartingStream="Arata dialog de confirmare la pornirea streamului" -Basic.Settings.General.WarnBeforeStoppingStream="Arata dialog de confirmare la oprirea streamului" +Basic.Settings.General.WarnBeforeStartingStream="Arată dialog de confirmare când pornește streamul" +Basic.Settings.General.WarnBeforeStoppingStream="Arată dialog de confirmare când se oprește streamul" +Basic.Settings.General.Snapping="Alipire la alinierea cu sursa" +Basic.Settings.General.ScreenSnapping="Aliniază sursele la marginea ecranului" +Basic.Settings.General.CenterSnapping="Aliniază sursele la centrul vertical și orizontal" +Basic.Settings.General.SourceSnapping="Aliniază sursele la alte surse" +Basic.Settings.General.SnapDistance="Sensibilitatea alinierii" Basic.Settings.Stream="Stream" -Basic.Settings.Stream.StreamType="Tip de Stream" +Basic.Settings.Stream.StreamType="Tipul streamului" -Basic.Settings.Output="Ieşire" +Basic.Settings.Output="Ieșire" Basic.Settings.Output.Format="Format de înregistrare" Basic.Settings.Output.Encoder="Codificator" -Basic.Settings.Output.SelectDirectory="Selectati folderul de Inregistrari" -Basic.Settings.Output.SelectFile="Selectati fisierul de Inregistrari" -Basic.Settings.Output.Mode="Modul de ieşire" +Basic.Settings.Output.SelectDirectory="Selectează folderul de înregistrări" +Basic.Settings.Output.SelectFile="Selectează fișierul de înregistrări" +Basic.Settings.Output.EnforceBitrate="Forțează limitele ratei de biți pentru streaming" +Basic.Settings.Output.Mode="Mod de ieșire" Basic.Settings.Output.Mode.Simple="Simplu" Basic.Settings.Output.Mode.Adv="Avansat" -Basic.Settings.Output.Mode.FFmpeg="Ieşire FFmpeg" -Basic.Settings.Output.Simple.SavePath="Calea de înregistrare" -Basic.Settings.Output.Simple.RecordingQuality="Calitatea înregistrarii" -Basic.Settings.Output.Simple.RecordingQuality.Stream="La fel ca stream-ul" -Basic.Settings.Output.Simple.RecordingQuality.Small="Calitate înaltă, Marime medie" +Basic.Settings.Output.Mode.FFmpeg="Ieșire FFmpeg" +Basic.Settings.Output.Simple.SavePath="Cale de înregistrare" +Basic.Settings.Output.Simple.RecordingQuality="Calitatea înregistrării" +Basic.Settings.Output.Simple.RecordingQuality.Stream="La fel cu cea a streamului" +Basic.Settings.Output.Simple.RecordingQuality.Small="Calitate înaltă, dimensiune medie a fișierului" Basic.Settings.Output.Simple.RecordingQuality.HQ="Calitate imposibil de distins, Marime mare" -Basic.Settings.Output.Simple.RecordingQuality.Lossless="Calitate fara pierderi (lossless), Marime enorm de mare" +Basic.Settings.Output.Simple.RecordingQuality.Lossless="Calitate lossless, dimensiune extrem de mare a fișierelor" +Basic.Settings.Output.Simple.Warn.VideoBitrate="Atentie: Bitrate-ul pentru video stream va fi setat la %1, care este limita superioară pentru serviciul de streaming actual. Dacă sunteţi sigur că doriţi să depasiţi %1, permiteţi opțiuni codare avansate şi debifaţi \"Forteaza limite de bitrate pentru stream\"." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Atentie: Bitrate-ul pentru audio stream va fi setat la %1, care este limita superioară pentru serviciul de streaming actual. Dacă sunteţi sigur că doriţi să depasiţi %1, permiteţi opțiuni codare avansate şi debifaţi \"Forteaza limite de bitrate pentru stream\"." Basic.Settings.Output.Simple.Warn.Encoder="Atenție: Înregistrarea cu un encoder software la o calitate diferită decât stream-ul va necesita o utilizare CPU crescută dacă faci stream şi înregistrezi în acelaşi timp." -Basic.Settings.Output.Simple.Warn.Lossless="Atenţie: Calitatea Lossless generează dimensiuni de fişier extrem de mari! Calitatea Lossless poate utiliza peste 7GB pe minut, la frame-uri şi rezolutii mari. Lossless nu este recomandat pentru înregistrări lungi decât dacă aveţi o cantitate foarte mare de spaţiu disponibil." -Basic.Settings.Output.Simple.Warn.Lossless.Msg="Sunteţi sigur că doriţi să utilizaţi calitatea lossless?" -Basic.Settings.Output.Simple.Warn.Lossless.Title="Avertizare calitate lossless!" +Basic.Settings.Output.Simple.Warn.Lossless="Avertisment: Calitatea lossless generează dimensiuni extrem de mari de fișiere! Calitatea lossless poate utiliza 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 dorești să folosești calitatea lossless?" +Basic.Settings.Output.Simple.Warn.Lossless.Title="Avertizare privind calitatea lossless!" Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" -Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (preset x264 cu utilizare scazuta CPU, creşte dimensiunea fişierului)" -Basic.Settings.Output.VideoBitrate="Video Bitrate" -Basic.Settings.Output.AudioBitrate="Audio Bitrate" -Basic.Settings.Output.Reconnect="Reconectare Automată" -Basic.Settings.Output.RetryDelay="Intârziere reincercare (secunde)" -Basic.Settings.Output.MaxRetries="Maxim de reîncercări" -Basic.Settings.Output.Advanced="Activează Setări Codare Avansate" -Basic.Settings.Output.EncoderPreset="Preset Codare (mai mare = mai puţin CPU)" -Basic.Settings.Output.CustomEncoderSettings="Setări Particularizate Codare" -Basic.Settings.Output.CustomMuxerSettings="Setări particularizate pentru Muxer" -Basic.Settings.Output.NoSpaceFileName="Generează nume de fişier fără spaţiu" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)" +Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (presetare x264 cu utilizare scăzută de CPU, crește dimensiunea fișierului)" +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="Încercări maxime" +Basic.Settings.Output.Advanced="Activează setările avansate ale codificatorului" +Basic.Settings.Output.EncoderPreset="Presetare a codificatorului (mai mare = mai puțin CPU)" +Basic.Settings.Output.CustomEncoderSettings="Setări particularizate ale codificatorului" +Basic.Settings.Output.CustomMuxerSettings="Setări particularizate ale muxerului" +Basic.Settings.Output.NoSpaceFileName="Generează nume de fișier fără spațiu" -Basic.Settings.Output.Adv.Rescale="Rescaleaza Fisierul de iesire" -Basic.Settings.Output.Adv.AudioTrack="Piesa Audio" +Basic.Settings.Output.Adv.Rescale="Rescalează ieșirea" +Basic.Settings.Output.Adv.AudioTrack="Pistă audio" Basic.Settings.Output.Adv.Streaming="Streaming" -Basic.Settings.Output.Adv.ApplyServiceSettings="Aplica setarile serviciului de codare pentru stream" -Basic.Settings.Output.Adv.Audio.Track1="Piesa 1" -Basic.Settings.Output.Adv.Audio.Track2="Piesa 2" -Basic.Settings.Output.Adv.Audio.Track3="Piesa 3" -Basic.Settings.Output.Adv.Audio.Track4="Piesa 4" +Basic.Settings.Output.Adv.ApplyServiceSettings="Aplică setările codificatorului pentru serviciul de streaming" +Basic.Settings.Output.Adv.Audio.Track1="Pistă 1" +Basic.Settings.Output.Adv.Audio.Track2="Pistă 2" +Basic.Settings.Output.Adv.Audio.Track3="Pistă 3" +Basic.Settings.Output.Adv.Audio.Track4="Pistă 4" Basic.Settings.Output.Adv.Recording="Înregistrare" Basic.Settings.Output.Adv.Recording.Type="Tip" Basic.Settings.Output.Adv.Recording.Type.Standard="Standard" -Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Output Personalizat (FFmpeg)" -Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Utilizaţi codare stream)" -Basic.Settings.Output.Adv.FFmpeg.Type="Tipul de ieşire FFmpeg" -Basic.Settings.Output.Adv.FFmpeg.Type.URL="Ieşire la URL" -Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Ieşire la fişier" -Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Formate de înregistrare" -Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Toate fişierele" -Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Calea fisierului sau URL-ul" -Basic.Settings.Output.Adv.FFmpeg.Format="Format de recipient" +Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Ieșire personalizată (FFmpeg)" +Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Folosește codificatorul de stream)" +Basic.Settings.Output.Adv.Recording.Filename="Formatarea numelui de fișier" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Suprascrie dacă fișierul există" +Basic.Settings.Output.Adv.FFmpeg.Type="Tipul ieșirii FFmpeg" +Basic.Settings.Output.Adv.FFmpeg.Type.URL="Ieșire spre URL" +Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Ieșire spre fișier" +Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Formate comune de înregistrare" +Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Toate fișierele" +Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Calea fișierului sau URL-ul" +Basic.Settings.Output.Adv.FFmpeg.Format="Format container" Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Audio" Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Video" -Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Formatul implicit" +Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Format implicit" Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Descriere Format Recipient" Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Codecul Audio/Video ghicit din calea fisierului sau URL-ul" -Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Encoder implicit" -Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Dezactivaţi Encoder" -Basic.Settings.Output.Adv.FFmpeg.VEncoder="Encoder Video" -Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Setările video Encoder (dacă există)" -Basic.Settings.Output.Adv.FFmpeg.AEncoder="Encoder Audio" -Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Setările audio Encoder (dacă există)" -Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Setări Muxer (dacă există)" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Codificator implicit" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Dezactivează codificatorul" +Basic.Settings.Output.Adv.FFmpeg.VEncoder="Codificator video" +Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Setările codificatorului video (dacă există)" +Basic.Settings.Output.Adv.FFmpeg.AEncoder="Codificator audio" +Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Setările codificatorului audio (dacă există)" +Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Setările muxerului (dacă există)" + +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 An, patru cifre\n%YY An, ultimele 2 cifre (00-99)\n%MM Luna ca numar decimal (01-12)\n%DD Ziua lunii, prefixat cu 0 (01-31)\n%hh Ora in format 24h (00-23)\n%mm Minut (00-59)\n%ss Secunda (00-61)\n%% Un % semn\n%a Numele zilei abreviat\n%A Numele zilei full\n%b Numele lunii abreviat\n%B Numele lunii full\n%d Ziua lunii, prefixat cu 0 (01-31)\n%H Ora in format 24h (00-23)\n%I Ora in format 12h (01-12)\n%m Luna ca numar decimal (01-12)\n%M Minut (00-59)\n%p Desemnari AM or PM\n%S Secunda (00-61)\n%y An, ultimele 2 cifre (00-99)\n%Y An\n%z ISO 8601 compensare UTC or fus orar\n nume sau abreviere\n%Z Numele fusului orar sau abreviere\n" Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Adaptor video:" -Basic.Settings.Video.BaseResolution="Rezoluţia de bază (panza):" -Basic.Settings.Video.ScaledResolution="Ieşire rezoluţie (scalată):" -Basic.Settings.Video.DownscaleFilter="Filtru descalare:" -Basic.Settings.Video.DisableAeroWindows="Dezactivare Aero (numai Windows)" +Basic.Settings.Video.BaseResolution="Rezoluție (canvas) de bază:" +Basic.Settings.Video.ScaledResolution="Rezoluție (scalată) la ieșire:" +Basic.Settings.Video.DownscaleFilter="Filtru pentru descalare:" +Basic.Settings.Video.DisableAeroWindows="Dezactivează Aero (Numai Windows)" Basic.Settings.Video.FPS="FPS:" -Basic.Settings.Video.FPSCommon="Valorile comune ale FPS" -Basic.Settings.Video.FPSInteger="Număr întreg valoare FPS" -Basic.Settings.Video.FPSFraction="Valoare FPS fracţionată" -Basic.Settings.Video.Numerator="Numărătorul:" -Basic.Settings.Video.Denominator="Numitorul:" -Basic.Settings.Video.Renderer="Randare:" +Basic.Settings.Video.FPSCommon="Valori FPS comune" +Basic.Settings.Video.FPSInteger="Valoare cu număr întreg pentru FPS" +Basic.Settings.Video.FPSFraction="Valoare FPS fracționată" +Basic.Settings.Video.Numerator="Numărător:" +Basic.Settings.Video.Denominator="Numitor:" +Basic.Settings.Video.Renderer="Renderer:" Basic.Settings.Video.InvalidResolution="Valoare rezoluţie invalidă. Trebuie să fie [latime]x[înălţime] (de exemplu, 1920x1080)" Basic.Settings.Video.CurrentlyActive="Ieşirea video este în prezent activă. Vă rugăm să opriţi orice ieşiri pentru a schimba setările video." -Basic.Settings.Video.DisableAero="Dezactivare Aero" +Basic.Settings.Video.DisableAero="Dezactivează Aero" -Basic.Settings.Video.DownscaleFilter.Bilinear="Biliniar (mai rapid, dar neclar la scalare)" -Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (Scalare ascutita, 16 mostre)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Scalare ascutita, 32 de mostre)" +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.Audio="Audio" -Basic.Settings.Audio.SampleRate="Rata de eşantionare" +Basic.Settings.Audio.SampleRate="Rată de eșantionare" Basic.Settings.Audio.Channels="Canale" -Basic.Settings.Audio.DesktopDevice="Dispozitiv Audio Desktop" -Basic.Settings.Audio.DesktopDevice2="Dispozitiv Audio Desktop 2" -Basic.Settings.Audio.AuxDevice="Dispozitiv Audio microfon/auxiliar" -Basic.Settings.Audio.AuxDevice2="Dispozitiv Audio microfon/auxiliar 2" -Basic.Settings.Audio.AuxDevice3="Dispozitiv Audio microfon/auxiliar 3" -Basic.Settings.Audio.EnablePushToMute="Porneste Push-to-mute" -Basic.Settings.Audio.PushToMuteDelay="Intarziere Push-to-mute" -Basic.Settings.Audio.EnablePushToTalk="Permite Push-to-talk" -Basic.Settings.Audio.PushToTalkDelay="Intarziere Push-to-talk" +Basic.Settings.Audio.DesktopDevice="Dispozitiv audio desktop" +Basic.Settings.Audio.DesktopDevice2="Dispozitiv audio desktop 2" +Basic.Settings.Audio.AuxDevice="Dispozitiv audio microfon/auxiliar" +Basic.Settings.Audio.AuxDevice2="Dispozitiv audio microfon/auxiliar 2" +Basic.Settings.Audio.AuxDevice3="Dispozitiv audio microfon/auxiliar 3" +Basic.Settings.Audio.EnablePushToMute="Pornește push-to-mute" +Basic.Settings.Audio.PushToMuteDelay="Întârziere push-to-mute" +Basic.Settings.Audio.EnablePushToTalk="Activează push-to-talk" +Basic.Settings.Audio.PushToTalkDelay="Întârziere push-to-talk" Basic.Settings.Audio.UnknownAudioDevice="[Dispozitivul nu este disponibil sau nu este conectat]" -Basic.Settings.Advanced="Avansat" +Basic.Settings.Advanced="Avansate" 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 tampon Audio" +Basic.Settings.Advanced.Audio.BufferingTime="Timp de buffering pentru audio" Basic.Settings.Advanced.Video.ColorFormat="Format de culoare" -Basic.Settings.Advanced.Video.ColorSpace="Spaţiul de culoare YUV" -Basic.Settings.Advanced.Video.ColorRange="Gama de culori YUV" -Basic.Settings.Advanced.Video.ColorRange.Partial="Parţial" -Basic.Settings.Advanced.Video.ColorRange.Full="Full" -Basic.Settings.Advanced.StreamDelay="Intârziere/delay stream" -Basic.Settings.Advanced.StreamDelay.Duration="Durata (secunde)" -Basic.Settings.Advanced.StreamDelay.Preserve="Păstrează punctul de taiere (creştere întârziere) la reconectare" -Basic.Settings.Advanced.StreamDelay.MemoryUsage="Estimare Folosire Memorie: %1 MB" +Basic.Settings.Advanced.Video.ColorSpace="Spațiu de culori YUV" +Basic.Settings.Advanced.Video.ColorRange="Gamă de culori YUV" +Basic.Settings.Advanced.Video.ColorRange.Partial="Parțială" +Basic.Settings.Advanced.Video.ColorRange.Full="Completă" +Basic.Settings.Advanced.StreamDelay="Întârziere pentru stream" +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.AdvAudio="Proprietăţi Audio Avansate" +Basic.AdvAudio="Proprietăți audio avansate" Basic.AdvAudio.Name="Nume" Basic.AdvAudio.Volume="Volum (%)" -Basic.AdvAudio.Mono="Transformă in Mono" +Basic.AdvAudio.Mono="Transformă în mono" Basic.AdvAudio.Panning="Panning" -Basic.AdvAudio.SyncOffset="Compensare Sincronizare (ms)" -Basic.AdvAudio.AudioTracks="Piese" +Basic.AdvAudio.SyncOffset="Decalajul sincronizării (ms)" +Basic.AdvAudio.AudioTracks="Piste" -Basic.Settings.Hotkeys="Taste Rapide/Hotkeys" -Basic.Settings.Hotkeys.Pair="Combinaţiile de taste în comun cu \"%1\" acţionează precum un comutator" +Basic.Settings.Hotkeys="Taste rapide" +Basic.Settings.Hotkeys.Pair="Combinațiile de taste partajate cu '%1' acționează ca comutatoare" -Basic.Hotkeys.StartStreaming="Porneşte Stream" -Basic.Hotkeys.StopStreaming="Oprește streaming-ul" -Basic.Hotkeys.StartRecording="Începe înregistrarea" +Basic.Hotkeys.StartStreaming="Pornește streamingul" +Basic.Hotkeys.StopStreaming="Oprește streamingul" +Basic.Hotkeys.StartRecording="Pornește înregistrarea" Basic.Hotkeys.StopRecording="Oprește înregistrarea" -Basic.Hotkeys.SelectScene="Comutaţi la scena" +Basic.Hotkeys.SelectScene="Comută la scenă" -Hotkeys.Insert="Inserare" -Hotkeys.Delete="Ştergeţi" +Hotkeys.Insert="Inserează" +Hotkeys.Delete="Șterge" Hotkeys.Home="Home" Hotkeys.End="End" Hotkeys.PageUp="Page Up" @@ -440,29 +479,29 @@ Hotkeys.Windows="Windows" Hotkeys.Super="Super" Hotkeys.Menu="Meniu" Hotkeys.Space="Space" -Hotkeys.NumpadNum="NumPad %1" +Hotkeys.NumpadNum="Numpad %1" Hotkeys.NumpadMultiply="Numpad Multiplica" Hotkeys.NumpadDivide="Numpad Divide" Hotkeys.NumpadAdd="Numpad Aduna" Hotkeys.NumpadSubtract="Numpad Scade" Hotkeys.NumpadDecimal="Numpad Zecimal" -Hotkeys.AppleKeypadNum="%1 (Keypad)" -Hotkeys.AppleKeypadMultiply="* (Tastatura)" -Hotkeys.AppleKeypadDivide="/ (Tastatura)" -Hotkeys.AppleKeypadAdd="+ (Tastatura)" -Hotkeys.AppleKeypadSubtract="- (Tastatura)" -Hotkeys.AppleKeypadDecimal=". (Tastatura)" -Hotkeys.AppleKeypadEqual="= (Tastatura)" +Hotkeys.AppleKeypadNum="%1 (Tastatură numerică)" +Hotkeys.AppleKeypadMultiply="* (Tastatură numerică)" +Hotkeys.AppleKeypadDivide="/ (Tastatură numerică)" +Hotkeys.AppleKeypadAdd="+ (Tastatură numerică)" +Hotkeys.AppleKeypadSubtract="- (Tastatură numerică)" +Hotkeys.AppleKeypadDecimal=". (Tastatură numerică)" +Hotkeys.AppleKeypadEqual="= (Tastatură numerică)" Hotkeys.MouseButton="Mouse %1" -Mute="Mut" -Unmute="Dezactiveaza Mut" -Push-to-mute="Push-to-mut" +Mute="Pune pe mut" +Unmute="Scoate de pe mut" +Push-to-mute="Push-to-mute" Push-to-talk="Push-to-talk" -SceneItemShow="Arată \"%1\"" -SceneItemHide="Ascunde \"%1\"" +SceneItemShow="Arată „%1”" +SceneItemHide="Ascunde „%1”" -OutputWarnings.NoTracksSelected="Trebuie să selectaţi cel puţin o piesa" -OutputWarnings.MultiTrackRecording="Atentie: Anumite formate (precum FLV) nu acceptă mai multe piese pentru înregistrare" +OutputWarnings.NoTracksSelected="Trebuie să selectezi cel puțin o pistă" +OutputWarnings.MultiTrackRecording="Atenție: Anumite formate (precum FLV) nu suportă multiple piste per înregistrare" diff --git a/obs/data/locale/ru-RU.ini b/obs/data/locale/ru-RU.ini index a9be918..66975d4 100644 --- a/obs/data/locale/ru-RU.ini +++ b/obs/data/locale/ru-RU.ini @@ -8,6 +8,7 @@ Cancel="Отмена" Close="Закрыть" Save="Сохранить" Discard="Отклонить" +Disable="Отключить" Yes="Да" No="Нет" Add="Добавить" @@ -38,15 +39,34 @@ Untitled="Безымянный" New="Создать" Duplicate="Дублировать" Enable="Включить" +DisableOSXVSync="Отключить OSX V-Sync" +ResetOSXVSyncOnExit="Сброс OSX V-Sync на выходе" HighResourceUsage="Кодировщик перегружен! Попробуйте понизить настройки видео или использовать более быстрые настройки кодировщика." Transition="Переход" QuickTransitions="Быстрые переходы" +Left="Слева" +Right="Справа" +Top="Сверху" +Bottom="Снизу" +QuickTransitions.SwapScenes="Замена Просмотра/Вывода Сцены После Перехода" +QuickTransitions.SwapScenesTT="Замена просмотра и вывода сцены после перехода (если выходная оригинальная сцена до сих пор существует).\nЭто будет не отмена каких-либо изменений, что, возможно, было сделано в выходной оригинальной сцены." +QuickTransitions.DuplicateScene="Повторяющиеся Сцены" +QuickTransitions.DuplicateSceneTT="При редактировании одной и той же сцены, функция позволяет трансформировать редактирования/видимости источников без изменения выхода.\nДля редактирования свойств источников без изменения выходного сигнала, включить \"дублировать источники'.\nИзменение этого параметра приведет к сбросу выходного сигнала в сцене (если оно еще существует)." +QuickTransitions.EditProperties="Дублировать Источники" +QuickTransitions.EditPropertiesTT="При редактировании одной и той же сцены, функция позволяет редактировать свойства источников без изменения выхода.\nЭто может только использоваться, если \"Повторяющиеся Сцены\" включен.\nНекоторые источники (такие как захват или медиа-источники) не поддерживаются и не могут быть отредактированы отдельно.\nИзменение этого параметра приведет к сбросу выходного сигнала в сцене (если оно еще существует).\n\nПредупреждение: поскольку источники будут дублироваться, это может потребовать дополнительных системных ресурсов или видео." QuickTransitions.HotkeyName="Быстрый переход: %1" +Basic.AddTransition="Добавить настраиваемый переход" +Basic.RemoveTransition="Удалить настраиваемый переход" +Basic.TransitionProperties="Параметры перехода" +Basic.SceneTransitions="Переходы между сценами" Basic.TransitionDuration="Длительность" Basic.TogglePreviewProgramMode="Режим студии" +TransitionNameDlg.Text="Пожалуйста, введите имя перехода" +TransitionNameDlg.Title="Имя перехода" + TitleBar.Profile="Профиль" TitleBar.Scenes="Сцены" @@ -71,7 +91,7 @@ ConfirmRemove.Text="Вы уверены, что хотите удалить '$1' Output.ConnectFail.Title="Не удалось подключиться" Output.ConnectFail.BadPath="Неверный путь или URL соединения. Пожалуйста, проверьте настройки, чтобы подтвердить, что они являются действительными." Output.ConnectFail.ConnectFailed="Не удалось подключиться к серверу" -Output.ConnectFail.InvalidStream="Не удалось получить доступ к указанному каналу или к stream key. Это может быть, потому что ключ/канал является недействительным, или потому, что сервер все еще думает, что вы зашли" +Output.ConnectFail.InvalidStream="Не удалось получить доступ к указанному ключу канала или стрима, пожалуйста, перепроверьте ключ. Если он правильный, проблема может быть с подключением к серверу." Output.ConnectFail.Error="Произошла непредвиденная ошибка при попытке подключиться к серверу. Более подробная информация в лог-файле." Output.ConnectFail.Disconnected="Отключен от сервера." @@ -98,7 +118,7 @@ LicenseAgreement.Exit="Выход" Remux.SourceFile="OBS Запись" Remux.TargetFile="Конечный файл" Remux.Remux="Ремультиплексирование" -Remux.RecordingPattern="OBS запись (*.flv)" +Remux.OBSRecording="OBS Запись" Remux.FinishedTitle="Ремультиплексирование завершено" Remux.Finished="Запись ремультиплексирована" Remux.FinishedError="Запись ремультиплексирована, но файл может быть неполон" @@ -124,6 +144,18 @@ Basic.DisplayCapture="Захват экрана" Basic.Main.PreviewConextMenu.Enable="Включить предпросмотр" +Deinterlacing="Устранение чересстрочности" +Deinterlacing.Discard="Отклонить" +Deinterlacing.Retro="Ретро" +Deinterlacing.Blend="Смешивание" +Deinterlacing.Blend2x="Смешивание 2x" +Deinterlacing.Linear="Линейно" +Deinterlacing.Linear2x="Линейно 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Верхнее поле первое" +Deinterlacing.BottomFieldFirst="Нижнее поле первое" + Basic.Main.AddSceneDlg.Title="Добавить сцену" Basic.Main.AddSceneDlg.Text="Пожалуйста, введите название сцены" @@ -189,6 +221,7 @@ Basic.TransformWindow.Alignment="Выравнивание позиции" Basic.TransformWindow.BoundsType="Тип ограничителя" Basic.TransformWindow.BoundsAlignment="Выравнивание внутри ограничителя" Basic.TransformWindow.Bounds="Размер ограничителя" +Basic.TransformWindow.Crop="Обрезка" Basic.TransformWindow.Alignment.TopLeft="Сверху слева" Basic.TransformWindow.Alignment.TopCenter="Сверху по центру" @@ -275,6 +308,11 @@ Basic.Settings.General.Theme="Тема" Basic.Settings.General.Language="Язык" Basic.Settings.General.WarnBeforeStartingStream="Показывать окно подтверждения при запуске трансляции" Basic.Settings.General.WarnBeforeStoppingStream="Показывать окно подтверждения при остановке трансляции" +Basic.Settings.General.Snapping="Привязка расположения источника" +Basic.Settings.General.ScreenSnapping="Привязка к краю экрана" +Basic.Settings.General.CenterSnapping="Привязка к центру по горизонтали и вертикали" +Basic.Settings.General.SourceSnapping="Привязка к другим источникам" +Basic.Settings.General.SnapDistance="Чувствительность привязки" Basic.Settings.Stream="Вещание" Basic.Settings.Stream.StreamType="Тип вещания" @@ -284,6 +322,7 @@ Basic.Settings.Output.Format="Формат записи" Basic.Settings.Output.Encoder="Кодировщик" Basic.Settings.Output.SelectDirectory="Выбрать каталог записи" Basic.Settings.Output.SelectFile="Выбрать файл записи" +Basic.Settings.Output.EnforceBitrate="Следовать ограничениям битрейта, накладываемые потоковой службой" Basic.Settings.Output.Mode="Режим вывода" Basic.Settings.Output.Mode.Simple="Простой" Basic.Settings.Output.Mode.Adv="Расширенные" @@ -294,11 +333,16 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="То же, что у тр Basic.Settings.Output.Simple.RecordingQuality.Small="Высокое качество, средний размер файла" 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.Encoder="Предупреждение: Запись с программным кодировщиком в качестве, отличным от качества трансляции, потребует дополнительной нагрузки на ЦП, если записывать и транслировать одновременно." 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.Warn.MultipleQSV="Предупреждение: вы не можете использовать несколько различных QSV-кодировщиков при одновременной трансляции и записи. Если вы хотите одновременно и транслировать, и записывать, поменяйте либо кодировщик вещания, либо кодировщик записи." Basic.Settings.Output.Simple.Encoder.Software="Программный (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Аппаратный (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Аппаратный (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Программный (x264 с низкой нагрузкой на ЦП, увеличивает размер файла)" Basic.Settings.Output.VideoBitrate="Видео битрейт" Basic.Settings.Output.AudioBitrate="Аудио битрейт" @@ -325,6 +369,8 @@ 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.Filename="Формат имени файла" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Заменять, если файл уже существует" Basic.Settings.Output.Adv.FFmpeg.Type="Тип вывода FFmpeg" Basic.Settings.Output.Adv.FFmpeg.Type.URL="На указанный адрес (URL)" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="В файл" @@ -345,6 +391,10 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Кодировщик аудио" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Настройки кодировщика аудио (если есть)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Настройки мультиплексора (если есть)" +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" + +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="Видеоадаптер:" Basic.Settings.Video.BaseResolution="Базовое (основа) разрешение:" diff --git a/obs/data/locale/sk-SK.ini b/obs/data/locale/sk-SK.ini index 28e55fa..b6c77a2 100644 --- a/obs/data/locale/sk-SK.ini +++ b/obs/data/locale/sk-SK.ini @@ -35,6 +35,7 @@ Enable="Povoliť" + TitleBar.Profile="Profil" TitleBar.Scenes="Scéna" @@ -67,7 +68,6 @@ LicenseAgreement.Exit="Ukončiť" Remux.SourceFile="OBS nahrávka" Remux.TargetFile="Cieľový súbor" -Remux.RecordingPattern="OBS nahrávka (*.flv)" Remux.SelectRecording="Vybrať OBS nahrávku …" Remux.SelectTarget="Vyberte cieľový súbor …" Remux.FileExistsTitle="Cieľový súbor existuje" @@ -81,6 +81,7 @@ Basic.Scene="Scéna" Basic.DisplayCapture="Zachytávanie monitora" + Basic.Main.AddSceneDlg.Title="Pridať scénu" Basic.Main.AddSceneDlg.Text="Prosím, zadajte názov scény" @@ -199,6 +200,8 @@ Basic.Settings.Output.Advanced="Povoliť pokročilé nastavenia enkodéra" + + Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Video adaptér:" Basic.Settings.Video.DisableAeroWindows="Vypnúť Aero (len Windows)" diff --git a/obs/data/locale/sl-SI.ini b/obs/data/locale/sl-SI.ini index 5baf98e..a7b5b61 100644 --- a/obs/data/locale/sl-SI.ini +++ b/obs/data/locale/sl-SI.ini @@ -30,6 +30,7 @@ DroppedFrames="Izpuščene sličice %1 (%2 %)" + NameExists.Title="Ime že obstaja" NameExists.Text="Ime je že v uporabi." @@ -46,7 +47,6 @@ ConfirmRemove.Text="Ali ste prepričani, da želite odstraniti '$ 1'?" 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.InvalidStream="Dostop do kanala oz. ključa streama ni mogoč. Mogoče je, da je ključ/kanal napačen ali pa ker ste na serverju še vedno vpisani." 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." @@ -79,6 +79,7 @@ Basic.Scene="Scena" Basic.DisplayCapture="Zajemanje zaslona" + Basic.Main.AddSceneDlg.Title="Dodaj seceno" Basic.Main.AddSceneDlg.Text="Prosimo, vnesite ime scene" @@ -199,6 +200,8 @@ Basic.Settings.Output.Advanced="Omogoči napredne nastavitve kodiranja" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Vse datoteke" + + Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Grafična kartica:" Basic.Settings.Video.DownscaleFilter="Pomanjševalni filter:" diff --git a/obs/data/locale/sr-CS.ini b/obs/data/locale/sr-CS.ini index 2939ee7..e758e13 100644 --- a/obs/data/locale/sr-CS.ini +++ b/obs/data/locale/sr-CS.ini @@ -8,6 +8,7 @@ Cancel="Otkaži" Close="Zatvori" Save="Sačuvaj" Discard="Odbaci" +Disable="Onemogući" Yes="Da" No="Ne" Add="Dodaj" @@ -43,6 +44,10 @@ ResetOSXVSyncOnExit="Povrati OSX vertikalnu sinhronizaciju po izlasku" HighResourceUsage="Enkodiranje preopterećeno! Razmotrite snižavanje video podešavanja ili korišćenje bržeg šablona za enkodiranje." Transition="Prelaz" QuickTransitions="Brzi prelazi" +Left="Sleva" +Right="Zdesna" +Top="Odozgo" +Bottom="Odozdo" QuickTransitions.SwapScenes="Zameni scene pregleda/izlaza nakon prelaza" QuickTransitions.SwapScenesTT="Zamenjuje scene pregleda i izlaza nakon prelaza (ako originalna scena izlaza još uvek postoji).\nOvo neće poništiti promene koje su načinjene nad originalnom scenom izlaza." @@ -52,10 +57,16 @@ QuickTransitions.EditProperties="Dupliraj izvore" QuickTransitions.EditPropertiesTT="Kada se menja ista scena, dozvoli promenu svojstava izvora bez promene izlaza.\nOvo može biti upotrebljeno samo ako je 'Dupliraj scene' omogućeno.\nOdređeni izvori (kao što su video hvatanja ili medija izvori) ne podržavaju ovo i ne mogu biti izmenjeni zasebno.\nPromena ove vrednosti će poništiti trenutnu scenu izlaza (ako i dalje postoji).\n\nUpozorenje: Zbog toga što izvori mogu biti duplirani, ovo može zahtevati dodatne sistemske ili video resurse." QuickTransitions.HotkeyName="Brzi prelaz: %1" +Basic.AddTransition="Dodaj podesivi prelaz" +Basic.RemoveTransition="Ukloni podesivi prelaz" +Basic.TransitionProperties="Svojstva prelaza" Basic.SceneTransitions="Prelazi scena" Basic.TransitionDuration="Trajanje" Basic.TogglePreviewProgramMode="Studijski režim" +TransitionNameDlg.Text="Molim unesite ime prelaza" +TransitionNameDlg.Title="Ime prelaza" + TitleBar.Profile="Profil" TitleBar.Scenes="Scene" @@ -80,7 +91,7 @@ ConfirmRemove.Text="Da li ste sigurni da želite izbaciti '$1'?" Output.ConnectFail.Title="Neuspešno povezivanje" Output.ConnectFail.BadPath="Neispravna putanja ili URL konekcije. Molim proverite vaša podešavanja da potvrdite njihovu ispravnost." Output.ConnectFail.ConnectFailed="Neuspešno povezivanje na server" -Output.ConnectFail.InvalidStream="Ne mogu pristupiti određenom kanalu ili strim ključu. Ovo je moguće, zato što je uneti ključ ili kanal pogrešan, ili zato što server misli da ste i dalje ulogovani." +Output.ConnectFail.InvalidStream="Ne mogu pristupiti navedenom kanalu ili strim ključu, molim proverite vaš strim ključ. Ako je ispravan, možda postoji problem pri povezivanju na server." Output.ConnectFail.Error="Neočekivana greška u povezivanju sa serverom. Više informacija se nalazi u log datoteci." Output.ConnectFail.Disconnected="Prekinuta veza sa serverom." @@ -107,7 +118,6 @@ LicenseAgreement.Exit="Izlaz" Remux.SourceFile="OBS snimak" Remux.TargetFile="Datoteka" Remux.Remux="Remux" -Remux.RecordingPattern="OBS snimci (*.flv)" Remux.FinishedTitle="Remux završen" Remux.Finished="Završen remux snimka" Remux.FinishedError="Remux završen, ali datoteka možda nije kompletirana" @@ -133,6 +143,18 @@ Basic.DisplayCapture="Prikaži ulaz" Basic.Main.PreviewConextMenu.Enable="Omogući pregled" +Deinterlacing="Deinterlejsing" +Deinterlacing.Discard="Odbaci" +Deinterlacing.Retro="Retro" +Deinterlacing.Blend="Stapanje" +Deinterlacing.Blend2x="Stapanje 2x" +Deinterlacing.Linear="Linearno" +Deinterlacing.Linear2x="Linearno 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Prvo gornje polje" +Deinterlacing.BottomFieldFirst="Prvo donje polje" + Basic.Main.AddSceneDlg.Title="Dodaj scenu" Basic.Main.AddSceneDlg.Text="Molim unesite ime scene" @@ -198,6 +220,7 @@ Basic.TransformWindow.Alignment="Poziciono poravnanje" Basic.TransformWindow.BoundsType="Tip okvira" Basic.TransformWindow.BoundsAlignment="Poravnanje u okviru" Basic.TransformWindow.Bounds="Veličina okvira" +Basic.TransformWindow.Crop="Isecanje" Basic.TransformWindow.Alignment.TopLeft="Gore levo" Basic.TransformWindow.Alignment.TopCenter="Gore centar" @@ -284,6 +307,11 @@ Basic.Settings.General.Theme="Tema" Basic.Settings.General.Language="Jezik" Basic.Settings.General.WarnBeforeStartingStream="Prikaži prozor za potvrdu kada se započinju strimovi" Basic.Settings.General.WarnBeforeStoppingStream="Prikaži prozor za potvrdu kada se zaustavljaju strimovi" +Basic.Settings.General.Snapping="Poravnavanje privlačenjem izvora" +Basic.Settings.General.ScreenSnapping="Privuci izvore ivici ekrana" +Basic.Settings.General.CenterSnapping="Privuci izvore horizontalnoj i vertikalnoj sredini" +Basic.Settings.General.SourceSnapping="Privlačenje izvora ka drugim izvorima" +Basic.Settings.General.SnapDistance="Osetljivost privlačenja" Basic.Settings.Stream="Strim" Basic.Settings.Stream.StreamType="Vrsta strima" @@ -293,6 +321,7 @@ Basic.Settings.Output.Format="Format snimanja" Basic.Settings.Output.Encoder="Enkoder" Basic.Settings.Output.SelectDirectory="Odaberi direktorijum za snimanje" Basic.Settings.Output.SelectFile="Odaberi datoteku za snimanje" +Basic.Settings.Output.EnforceBitrate="Sprovedi ograničenja u protoku striming servisa" Basic.Settings.Output.Mode="Režim izlaza" Basic.Settings.Output.Mode.Simple="Jednostavno" Basic.Settings.Output.Mode.Adv="Napredno" @@ -303,11 +332,16 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Isto kao strim" Basic.Settings.Output.Simple.RecordingQuality.Small="Visoki kvalitet, osrednja veličina datoteke" Basic.Settings.Output.Simple.RecordingQuality.HQ="Kvalitet sa neprimetnim razlikama, velika datoteka" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Kvalitet bez gubitka, izričito velika datoteka" +Basic.Settings.Output.Simple.Warn.VideoBitrate="Upozorenje: Video protok strima će biti postavljen na %1, što je gornja granica za trenutni striming servis. Ako ste sigurni da želite ići preko %1, omogućite napredne opcije enkodera i isključite \"Sprovedi ograničenja u protoku striming servisa\"." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Upozorenje: Zvučni protok strima će biti postavljen na %1, što je gornja granica za trenutni striming servis. Ako ste sigurni da želite ići preko %1, omogućite napredne opcije enkodera i isključite \"Sprovedi ograničenja u protoku striming servisa\"." Basic.Settings.Output.Simple.Warn.Encoder="Upozorenje: Snimanje sa softverskim enkoderom drugačijeg kvaliteta u odnosu na strim će zahtevati dodatnu procesorsku snagu ako strimujete i snimate u isto vreme." Basic.Settings.Output.Simple.Warn.Lossless="Upozorenje: Kvalitet bez gubitka stvara izričito velike datoteke! Kvalitet bez gubitka može koristiti više od 7 gigabajta prostora na disku po minutu pri visokim rezolucijama i framerate-om. Kvalitet bez gubitka nije preporučen za duže snimanje osim ako imate veliku količinu slobodnog prostora na disku." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Da li ste sigurni da želite koristiti kvalitet bez gubitka?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Upozorenje za kvalitet bez gubitka!" +Basic.Settings.Output.Simple.Warn.MultipleQSV="Upozorenje: Ne možete koristi više odvojenih QSV enkodera kada emitujete i snimate u isto vreme. Ako želite da emitujete i snimate u isto vreme, molim promenite ili enkoder snimanja ili enkoder emitovanja." Basic.Settings.Output.Simple.Encoder.Software="Softverski (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Mašinski (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Mašinski (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softverski (x264 niska upotreba procesora, povećava veličinu datoteke)" Basic.Settings.Output.VideoBitrate="Protok videa" Basic.Settings.Output.AudioBitrate="Protok zvuka" @@ -334,6 +368,8 @@ Basic.Settings.Output.Adv.Recording.Type="Vrsta" Basic.Settings.Output.Adv.Recording.Type.Standard="Uobičajeni" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Prilagođeni izlaz (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Koristi strim enkoder)" +Basic.Settings.Output.Adv.Recording.Filename="Oblikovanje imena datoteke" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Prepiši ako postoji datoteka" Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg vrsta ispisa" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Ispis na URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Ispis u datoteku" @@ -354,6 +390,10 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Zvučni enkoder" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Podešavanja zvučnog enkodera (ako postoje)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Podešavanja muxer-a (ako postoje)" +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 Godina, četiri cifre\n%YY Godina, poslednje dve cifre (00-99)\n%MM Mesec kao decimalni broj (01-12)\n%DD Dan u mesecu, sa nulom ispred (01-31)\n%hh Sat u 24-časovnom zapisu (00-23)\n%mm Minut (00-59)\n%ss Sekunda (00-61)\n%% Znak procenta\n%a Skraćeno ime dana u nedelji\n%A Puno ime dana u nedelji\n%b Skraćeno ime meseca\n%B Puno ime meseca\n%d Dan u mesecu, sa nulom ispred (01-31)\n%H Sat u 24-časovnom zapisu (00-23)\n%I Sat u 12-časovnom zapisu (01-12)\n%m Mesec kao decimalni broj (01-12)\n%M Minut (00-59)\n%p Oznaka za pre ili posle podne\n%S Sekunda (00-61)\n%y Godina, poslednje dve cifre (00-99)\n%Y Godina\n%z ISO 8601 odstupanje od UTC ili ime\n vremenske zone ili skraćenica\n%Z Ime vremenske zone ili skraćenica\n" + Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Video adapter:" Basic.Settings.Video.BaseResolution="Osnovna (površinska) rezolucija:" diff --git a/obs/data/locale/sr-SP.ini b/obs/data/locale/sr-SP.ini index 95fc864..9181b64 100644 --- a/obs/data/locale/sr-SP.ini +++ b/obs/data/locale/sr-SP.ini @@ -8,6 +8,7 @@ Cancel="Откажи" Close="Затвори" Save="Сачувај" Discard="Одбаци" +Disable="Онемогући" Yes="Да" No="Не" Add="Додај" @@ -43,6 +44,10 @@ ResetOSXVSyncOnExit="Поврати OSX вертикалну синхрониз HighResourceUsage="Енкодирање преоптерећено! Размотрите снижавање видео подешавања ли коришћење бржег шаблона за енкодирање." Transition="Прелаз" QuickTransitions="Брзи прелази" +Left="Слева" +Right="Здесна" +Top="Одозго" +Bottom="Одоздо" QuickTransitions.SwapScenes="Замени сцене прегледа/излаза након прелаза" QuickTransitions.SwapScenesTT="Замењује сцене прегледа и излаза након прелаза (ако оригинална сцена још увек постоји).\nОво неће поништити промене које су начињене над оригиналном сценом излаза." @@ -52,10 +57,16 @@ QuickTransitions.EditProperties="Дуплирај изворе" QuickTransitions.EditPropertiesTT="Када се мења иста сцена, дозволи промену својстава извора без промене излаза.\nОво може бити употребљено само ако је 'Дуплирај сцене' омогућено.\nОдређени извори (као што су видео хватања или медија извори) не подржавају ово и не могу бити измењени засебно.\nПромена ове вредности ће поништити тренутну сцену излаза (ако и даље постоји).\n\nУпозорење: Због тога што извори могу бити дуплирани, ово може захтевати додатне системске или видео ресурсе." QuickTransitions.HotkeyName="Брзи прелаз: %1" +Basic.AddTransition="Додај подесиви прелаз" +Basic.RemoveTransition="Уклони подесиви прелаз" +Basic.TransitionProperties="Својства прелаза" Basic.SceneTransitions="Прелази сцена" Basic.TransitionDuration="Трајање" Basic.TogglePreviewProgramMode="Студијски режим" +TransitionNameDlg.Text="Молим унесите име прелаза" +TransitionNameDlg.Title="Име прелаза" + TitleBar.Profile="Профил" TitleBar.Scenes="Сцене" @@ -80,7 +91,7 @@ ConfirmRemove.Text="Да ли сте сигурни да желите избац Output.ConnectFail.Title="Неуспешно повезивање" Output.ConnectFail.BadPath="Неисправна путања или URL конекције. Молим проверите ваша подешавања да потврдите њихову исправност." Output.ConnectFail.ConnectFailed="Неуспешно повезивање на сервер" -Output.ConnectFail.InvalidStream="Не могу приступити одређеном каналу или стрим кључу. Ово је могуће, зато што је унети кључ или канал погрешан, или зато што сервер мисли да сте и даље улоговани." +Output.ConnectFail.InvalidStream="Не могу приступити наведеном каналу или стрим кључу, молим проверите ваш стрим кључ. Ако је исправан, можда постоји проблем при повезивању на сервер." Output.ConnectFail.Error="Неочекивана грешка у повезивању са сервером. Више информација се налази у лог датотеци." Output.ConnectFail.Disconnected="Прекинута веза са сервером." @@ -107,7 +118,6 @@ LicenseAgreement.Exit="Излаз" Remux.SourceFile="OBS снимак" Remux.TargetFile="Датотека" Remux.Remux="Remux" -Remux.RecordingPattern="OBS снимци (*.flv)" Remux.FinishedTitle="Remux завршен" Remux.Finished="Завршен remux снимка" Remux.FinishedError="Remux завршен, али датотека можда није комплетирана" @@ -133,6 +143,18 @@ Basic.DisplayCapture="Прикажи улаз" Basic.Main.PreviewConextMenu.Enable="Омогући преглед" +Deinterlacing="Деинтерлејсинг" +Deinterlacing.Discard="Одбаци" +Deinterlacing.Retro="Ретро" +Deinterlacing.Blend="Стапање" +Deinterlacing.Blend2x="Стапање 2x" +Deinterlacing.Linear="Линеарно" +Deinterlacing.Linear2x="Линеарно 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Прво горње поље" +Deinterlacing.BottomFieldFirst="Прво доње поље" + Basic.Main.AddSceneDlg.Title="Додај сцену" Basic.Main.AddSceneDlg.Text="Молим унесите име сцене" @@ -198,6 +220,7 @@ Basic.TransformWindow.Alignment="Позиционо поравнање" Basic.TransformWindow.BoundsType="Тип оквира" Basic.TransformWindow.BoundsAlignment="Поравнање у оквиру" Basic.TransformWindow.Bounds="Величина оквира" +Basic.TransformWindow.Crop="Исецање" Basic.TransformWindow.Alignment.TopLeft="Горе лево" Basic.TransformWindow.Alignment.TopCenter="Горе центар" @@ -284,6 +307,11 @@ Basic.Settings.General.Theme="Тема" Basic.Settings.General.Language="Језик" Basic.Settings.General.WarnBeforeStartingStream="Прикажи прозор за потврду када се започињу стримови" Basic.Settings.General.WarnBeforeStoppingStream="Прикажи прозор за потврду када се заустављају стримови" +Basic.Settings.General.Snapping="Поравнавање привлачењем извора" +Basic.Settings.General.ScreenSnapping="Привуци изворе ивици екрана" +Basic.Settings.General.CenterSnapping="Привуци изворе хоризонталној и вертикалној средини" +Basic.Settings.General.SourceSnapping="Привлачење извора ка другим изворима" +Basic.Settings.General.SnapDistance="Осетљивост привлачења" Basic.Settings.Stream="Стрим" Basic.Settings.Stream.StreamType="Врста стрима" @@ -293,6 +321,7 @@ Basic.Settings.Output.Format="Формат снимања" Basic.Settings.Output.Encoder="Енкодер" Basic.Settings.Output.SelectDirectory="Одабери директоријум за снимање" Basic.Settings.Output.SelectFile="Одабери датотеку за снимање" +Basic.Settings.Output.EnforceBitrate="Спроведи ограничења у протоку стриминг сервиса" Basic.Settings.Output.Mode="Режим излаза" Basic.Settings.Output.Mode.Simple="Једноставно" Basic.Settings.Output.Mode.Adv="Напредно" @@ -303,11 +332,16 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Исто као стрим Basic.Settings.Output.Simple.RecordingQuality.Small="Високи квалитет, осредња величина датотеке" 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.Encoder="Упозорење: Снимање са софтверским енкодером другачијег квалитета у односу на стрим ће захтевати додатну процесорску снагу ако стримујете и снимате у исто време." Basic.Settings.Output.Simple.Warn.Lossless="Упозорење: Квалитет без губитка ствара изричито велике датотеке! Квалитет без губитка може користити више од 7 гигабајта простора на диску по минуту при високим резолуцијама и framerate-ом. Квалитет без губитка није препоручен за дуже снимање осим ако имате велику количину слободног простора на диску." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Да ли сте сигурни да желите користити квалитет без губитка?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Упозорење за квалитет без губитка!" +Basic.Settings.Output.Simple.Warn.MultipleQSV="Упозорење: Не можете користити више одвојених QSV енкодера када емитујете и снимате у исто време. Ако желите да емитујете и снимате у исто време, молим промените или енкодер снимања или енкодер емитовања." Basic.Settings.Output.Simple.Encoder.Software="Софтверски (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Машински (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Машински (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Софтверски (x264 ниска употреба процесора, повећава величину датотеке)" Basic.Settings.Output.VideoBitrate="Проток видеа" Basic.Settings.Output.AudioBitrate="Проток звука" @@ -334,6 +368,8 @@ 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.Filename="Обликовање имена датотеке" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Препиши ако постоји датотека" Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg врста исписа" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Испис на URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Испис у датотеку" @@ -354,6 +390,10 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Звучни енкодер" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Подешавања звучног енкодера (ако постоје)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Подешавања muxer-а (ако постоје)" +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 Ознака за пре или после подне\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="Видео адаптер:" Basic.Settings.Video.BaseResolution="Основна (површинска) резолуција:" diff --git a/obs/data/locale/sv-SE.ini b/obs/data/locale/sv-SE.ini index 89cc1db..56d1da6 100644 --- a/obs/data/locale/sv-SE.ini +++ b/obs/data/locale/sv-SE.ini @@ -3,11 +3,12 @@ Language="Svenska" Region="Sverige" OK="OK" -Apply="Bekräfta" +Apply="Verkställ" Cancel="Avbryt" Close="Stäng" Save="Spara" Discard="Radera" +Disable="Inaktivera" Yes="Ja" No="Nej" Add="Lägg till" @@ -38,8 +39,28 @@ Untitled="Namnlös" New="Ny" Duplicate="Duplicera" Enable="Aktivera" +DisableOSXVSync="Inaktivera OSX V-Sync" +ResetOSXVSyncOnExit="Återställ OSX V-Sync vid avslutning" +Transition="Övergång" +QuickTransitions="Snabba övergångar" +Left="Vänster" +Right="Höger" +Top="Överkant" +Bottom="Nederkant" +QuickTransitions.DuplicateScene="Duplicera scen" +QuickTransitions.EditProperties="Duplicera källa" +QuickTransitions.HotkeyName="Snabba övergång: %1" +Basic.AddTransition="Lägg till konfigurerbar övergång" +Basic.RemoveTransition="Ta bort konfigurerbar övergång" +Basic.TransitionProperties="Övergångsegenskaper" +Basic.SceneTransitions="Scenövergångar" +Basic.TransitionDuration="Varaktighet" +Basic.TogglePreviewProgramMode="Studioläge" + +TransitionNameDlg.Text="Skriv in namnet på övergången" +TransitionNameDlg.Title="Övergångsnamn" TitleBar.Profile="Profil" TitleBar.Scenes="Scener" @@ -50,7 +71,11 @@ NameExists.Text="Det namnet används redan." NoNameEntered.Title="Vänligen ange ett giltigt namn" NoNameEntered.Text="Du måste ange ett namn." +ConfirmStart.Title="Börja strömma?" +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?" ConfirmExit.Title="Avsluta OBS?" ConfirmExit.Text="OBS är aktivt. Alla strömmar/inspelningar kommer att stängas av. Är du säker på att du vill avsluta?" @@ -61,7 +86,6 @@ ConfirmRemove.Text="Vill du verkligen ta bort '$1'?" Output.ConnectFail.Title="Anslutning misslyckades" 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.InvalidStream="Kunde inte komma åt den angivna kanalen eller streamnyckeln. Din angivna streamnyckel/kanal kan vara ogiltig, eller så tror servern att du fortfarande är inloggad på din tidigare anslutning." 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." @@ -88,7 +112,7 @@ LicenseAgreement.Exit="Avsluta" Remux.SourceFile="OBS Inspelning" Remux.TargetFile="Målfil" Remux.Remux="Remux" -Remux.RecordingPattern="OBS Inspelning (*.flv)" +Remux.OBSRecording="OBS Inspelning" Remux.FinishedTitle="Remuxing färdig" Remux.Finished="Inspelning remuxed" Remux.FinishedError="Inspelning remuxed, men filen kan vara ofullständig" @@ -114,6 +138,13 @@ Basic.DisplayCapture="Bildskärmskälla" Basic.Main.PreviewConextMenu.Enable="Förhandsvisa" +Deinterlacing.Discard="Avfärda" +Deinterlacing.Retro="Retro" +Deinterlacing.Linear="Linjär" +Deinterlacing.Linear2x="Linjär 2x" +Deinterlacing.TopFieldFirst="Övre fältet först" +Deinterlacing.BottomFieldFirst="Nedre fältet först" + Basic.Main.AddSceneDlg.Title="Lägg till scen" Basic.Main.AddSceneDlg.Text="Vänligen ange ett namn för scenen" @@ -145,11 +176,21 @@ Basic.PropertiesWindow.Confirm="Det finns osparade ändringar. Vill du behålla Basic.PropertiesWindow.NoProperties="Inga inställningar tillgängliga" Basic.PropertiesWindow.AddFiles="Lägg till Filer" Basic.PropertiesWindow.AddURL="Lägg till Sökväg/URL" +Basic.PropertiesWindow.AddEditableListFiles="Lägg till filer i '%1'" +Basic.PropertiesView.FPS.Simple="Enkla bildfrekvensvärden" +Basic.PropertiesView.FPS.Rational="Rationella bildfrekvensvärden" +Basic.PropertiesView.FPS.ValidFPSRanges="Giltiga bildfrekvensintervall:" Basic.InteractionWindow="Interagerar med '%1'" +Basic.StatusBar.Reconnecting="Frånkopplad, återansluter om %2 sekund(er) (försök %1)" +Basic.StatusBar.AttemptingReconnect="Försöker att återansluta... (försök %1)" Basic.StatusBar.ReconnectSuccessful="Återanslutning lyckades" +Basic.StatusBar.Delay="Fördröjning (%1 s)" +Basic.StatusBar.DelayStartingIn="Fördröjning (börjar om %1 s)" +Basic.StatusBar.DelayStoppingIn="Fördröjning (stoppar efter %1 s)" +Basic.StatusBar.DelayStartingStoppingIn="Fördröjning (stoppar efter %1 s, börjar om %2 s)" Basic.Filters="Filter" Basic.Filters.AsyncFilters="Audio/Video filter" @@ -167,6 +208,7 @@ Basic.TransformWindow.Alignment="Positionsjustering" Basic.TransformWindow.BoundsType="Avgränsningsramstyp" Basic.TransformWindow.BoundsAlignment="Justering i avgränsningsramen" Basic.TransformWindow.Bounds="Avgränsningsramstorlek" +Basic.TransformWindow.Crop="Beskär" Basic.TransformWindow.Alignment.TopLeft="Överst till vänster" Basic.TransformWindow.Alignment.TopCenter="Centrerad mot övre kant" @@ -193,16 +235,20 @@ Basic.Main.Scenes="Scener" Basic.Main.Sources="Källor" Basic.Main.Connecting="Ansluter..." Basic.Main.StartRecording="Starta inspelning" -Basic.Main.StartStreaming="Börja streama" +Basic.Main.StartStreaming="Börja strömma" Basic.Main.StopRecording="Stoppa inspelning" -Basic.Main.StopStreaming="Sluta streama" +Basic.Main.StopStreaming="Sluta strömma" +Basic.Main.ForceStopStreaming="Sluta strömma (ignorera fördröjning)" Basic.MainMenu.File="&Arkiv" Basic.MainMenu.File.Export="&Exportera" Basic.MainMenu.File.Import="&Importera" -Basic.MainMenu.File.ShowRecordings="Visa &Inspelningar" +Basic.MainMenu.File.ShowRecordings="Visa &inspelningar" Basic.MainMenu.File.Remux="Re&mux Inspelningar" 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" Basic.MainMenu.Edit="&Redigera" @@ -228,8 +274,11 @@ Basic.MainMenu.Edit.Order.MoveToTop="Lägg &överst" Basic.MainMenu.Edit.Order.MoveToBottom="Lägg unders&t" Basic.MainMenu.Edit.AdvAudio="&Avancerade ljudinställningar" +Basic.MainMenu.SceneCollection="&Scensamling" +Basic.MainMenu.Profile="&Profil" Basic.MainMenu.Help="&Hjälp" +Basic.MainMenu.Help.Website="Besök &webbplats" Basic.MainMenu.Help.Logs="&Loggfiler" Basic.MainMenu.Help.Logs.ShowLogs="&Visa loggfiler" Basic.MainMenu.Help.Logs.UploadCurrentLog="Ladda upp &aktuell loggfil" @@ -244,11 +293,18 @@ Basic.Settings.Confirm="Du har osparade ändringar. Vill du spara ändringarna?" Basic.Settings.General="Allmänt" Basic.Settings.General.Theme=" Tema" Basic.Settings.General.Language="Språk" +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.ScreenSnapping="Fäst källor till skärmens kant" +Basic.Settings.General.CenterSnapping="Fäst källor till den horisontala och vertikala mittenlinjen" +Basic.Settings.General.SourceSnapping="Fäst källor till andra källor" +Basic.Settings.General.SnapDistance="Fästkänslighet" Basic.Settings.Stream="Stream" Basic.Settings.Stream.StreamType="Streamtyp" Basic.Settings.Output="Utmatning" +Basic.Settings.Output.Format="Inspelningsformat" Basic.Settings.Output.Encoder="Kodare" Basic.Settings.Output.SelectDirectory="Välj inspelningsplats" Basic.Settings.Output.SelectFile="Välj inspelningsfil" @@ -256,6 +312,18 @@ 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.Simple.SavePath="Inspelningssökväg" +Basic.Settings.Output.Simple.RecordingQuality="Inspelningskvalitet" +Basic.Settings.Output.Simple.RecordingQuality.Stream="Samma som ström" +Basic.Settings.Output.Simple.RecordingQuality.Small="Hög kvalitet, mellanstor filstorlek" +Basic.Settings.Output.Simple.RecordingQuality.HQ="Oskiljbar kvalitet, stor filstorlek" +Basic.Settings.Output.Simple.RecordingQuality.Lossless="Förlustfri kvalitet, oerhört stor filstorlek" +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?" +Basic.Settings.Output.Simple.Warn.Lossless.Title="Varning angående förlustfri kvalitet!" +Basic.Settings.Output.Simple.Encoder.Software="Programvara (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hårdvara (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hårdvara (NVENC)" Basic.Settings.Output.VideoBitrate="Bithastighet för video" Basic.Settings.Output.AudioBitrate="Bithastighet för ljud" Basic.Settings.Output.Reconnect="Automatisk återanslutning" @@ -264,6 +332,8 @@ Basic.Settings.Output.MaxRetries="Maximalt antal försök" Basic.Settings.Output.Advanced="Aktivera avancerade kodarinställningar" Basic.Settings.Output.EncoderPreset="Kodarförinställning (högre = mindre CPU)" Basic.Settings.Output.CustomEncoderSettings="Inställningar för anpassade kodare" +Basic.Settings.Output.CustomMuxerSettings="Anpassade muxerinställningar" +Basic.Settings.Output.NoSpaceFileName="Generera filnamn utan mellanrum" Basic.Settings.Output.Adv.Rescale="Skala om utmatning" Basic.Settings.Output.Adv.AudioTrack="Ljudspår" @@ -279,6 +349,11 @@ Basic.Settings.Output.Adv.Recording.Type="Typ" Basic.Settings.Output.Adv.Recording.Type.Standard="Standard" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Anpassad utmatning (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Använd strömkodare)" +Basic.Settings.Output.Adv.Recording.Filename="Filnamnsformat" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Skriv över om filen finns" +Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg-utmatningstyp" +Basic.Settings.Output.Adv.FFmpeg.Type.URL="Utmatning till URL" +Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Utmatning till fil" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Vanliga inspelningsformat" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Alla Filer" Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Sökväg eller webbadress" @@ -294,11 +369,17 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoder="Videokodare" Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Videokodar-inställningar (om något)" Basic.Settings.Output.Adv.FFmpeg.AEncoder="Ljudkodare" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Ljudkodar-inställningar (om något)" +Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxerinställningar (om det finns)" + + +FilenameFormatting.TT="%CCYY År, fyra siffror\n%YY År, de två sista siffrorna (00-99)\n%MM Månad som en siffra (01-12)\n%DD Månadens dag, inledande nolla (01-31)\n%hh Timme i 24-timmarsformat (00-23)\n%mm Minut (00-59)\n%ss Sekund (00-61)\n%% Ett procenttecken\n%a Förkortad veckodag\n%A Fullständig veckodag\n%b Förkortat månadsnamn\n%B Fullständigt månadsnamn\n%d Månadens dag, inledande nolla (01-31)\n%H Timme i 24-timmarsformat (00-23)\n%I Timme i 12-timmarsformat (01-12)\n%m Månad som en siffra (01-12)\n%M Minut (00-59)\n%p AM eller PM\n%S Sekund (00-61)\n%y År, de två sista siffrorna (00-99)\n%Y År\n%z ISO 8601-offset från UTC eller tidszonens\n namn eller förkortning\n%Z Tidszonens namn eller förkortning\n" Basic.Settings.Video="Video" 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.DisableAeroWindows="Inaktivera Aero (endast Windows)" Basic.Settings.Video.FPS="FPS:" Basic.Settings.Video.FPSCommon="Vanliga bildhastighetsvärden" Basic.Settings.Video.FPSInteger="Heltals-bildhastighetsvärde" @@ -308,6 +389,7 @@ 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.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)" @@ -321,26 +403,71 @@ Basic.Settings.Audio.DesktopDevice2="Skrivbordsljudenhet 2" Basic.Settings.Audio.AuxDevice="Mikrofon/extra ljudenhet" Basic.Settings.Audio.AuxDevice2="Mikrofon/extra ljudenhet 2" Basic.Settings.Audio.AuxDevice3="Mikrofon/extra ljudenhet 3" +Basic.Settings.Audio.EnablePushToMute="Aktivera tryck för att tysta" +Basic.Settings.Audio.PushToMuteDelay="Fördröjning för tryck för att tysta" +Basic.Settings.Audio.EnablePushToTalk="Aktivera tryck för att tala" +Basic.Settings.Audio.PushToTalkDelay="Fördröjning för tryck för att tala" +Basic.Settings.Audio.UnknownAudioDevice="[Enheten är inte ansluten eller tillgänglig]" Basic.Settings.Advanced="Avancerat" +Basic.Settings.Advanced.FormatWarning="Varning: Andra färgformat än NV12 är avsedda för inspelning och rekommenderas inte för att strömma. Högre processoranvändning kan uppstå vid strömning p.g.a. konvertering av färgformat." Basic.Settings.Advanced.Audio.BufferingTime="Ljudbuffringstid" Basic.Settings.Advanced.Video.ColorFormat="Färgformat" Basic.Settings.Advanced.Video.ColorSpace="YUV-färgrymd" Basic.Settings.Advanced.Video.ColorRange="YUV färgområde" Basic.Settings.Advanced.Video.ColorRange.Partial="Partiell" Basic.Settings.Advanced.Video.ColorRange.Full="Full" +Basic.Settings.Advanced.StreamDelay="Strömfördröjning" +Basic.Settings.Advanced.StreamDelay.Duration="Varaktighet (sekunder)" +Basic.Settings.Advanced.StreamDelay.MemoryUsage="Uppskattad minnesanvändning: %1 MB" Basic.AdvAudio="Avancerade ljudinställningar" Basic.AdvAudio.Name="Namn" Basic.AdvAudio.Volume="Volym (%)" -Basic.AdvAudio.Mono="Downmixa till Mono" +Basic.AdvAudio.Mono="Nedmixa till mono" Basic.AdvAudio.Panning="Panorering" Basic.AdvAudio.SyncOffset="Sync Offset (ms)" Basic.AdvAudio.AudioTracks="Spår" +Basic.Settings.Hotkeys="Kortkommandon" +Basic.Hotkeys.StartStreaming="Börja strömma" +Basic.Hotkeys.StopStreaming="Sluta strömma" +Basic.Hotkeys.StartRecording="Starta inspelning" +Basic.Hotkeys.StopRecording="Stoppa inspelning" +Basic.Hotkeys.SelectScene="Byt till scen" +Hotkeys.Insert="Insert" +Hotkeys.Delete="Delete" +Hotkeys.Home="Home" +Hotkeys.End="End" +Hotkeys.PageUp="Page Up" +Hotkeys.PageDown="Page Down" +Hotkeys.NumLock="Num Lock" +Hotkeys.ScrollLock="Scroll Lock" +Hotkeys.CapsLock="Caps Lock" +Hotkeys.Backspace="Backsteg" +Hotkeys.Tab="Tabb" +Hotkeys.Print="Print" +Hotkeys.Pause="Pause" +Hotkeys.Left="Vänster" +Hotkeys.Right="Höger" +Hotkeys.Up="Upp" +Hotkeys.Down="Ned" +Hotkeys.Windows="Windows" +Hotkeys.Super="Super" +Hotkeys.Menu="Meny" +Hotkeys.Space="Mellanslag" +Hotkeys.MouseButton="Musknapp %1" +Mute="Stäng av ljud" +Unmute="Slå på ljud" +Push-to-mute="Tryck för att tysta" +Push-to-talk="Tryck för att tala" +SceneItemShow="Visa '%1'" +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" diff --git a/obs/data/locale/ta-IN.ini b/obs/data/locale/ta-IN.ini new file mode 100644 index 0000000..777158e --- /dev/null +++ b/obs/data/locale/ta-IN.ini @@ -0,0 +1,89 @@ + +Language="ஆங்கிலம்" +Region="யூனைடெட் ஸ்டேட்ஸ்" + +OK="சரி" +Apply="அமல்படுத்து" +Cancel="ரத்துசெய்" +Close="மூடு" +Save="சேமி" +Discard="புறக்கணி" +Disable="செயல் நீக்கு" +Yes="ஆம்" +No="இல்லை" +Add="சேர்க்க" +Remove="அகற்ற" +Rename="மறுபெயரிடு" +Properties="பண்புகள்" +MoveUp="மேலே நகர்த்து" +MoveDown="கீழ் நகர்த்து" +Settings="அமைப்புகள்" +Name="பெயர்" +Exit="வெளியேறு" +Show="காட்டு" +Hide="மறை" +Untitled="தலைப்பிடாத" +New="புதிய" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/obs/data/locale/th-TH.ini b/obs/data/locale/th-TH.ini index 2708727..5228d51 100644 --- a/obs/data/locale/th-TH.ini +++ b/obs/data/locale/th-TH.ini @@ -27,6 +27,7 @@ Stereo="สเตอริโอ" + ConfirmRemove.Title="ยืนยันการลบ" ConfirmRemove.Text="คุณแน่ใจแล้วหรือที่จะลบ '$1'?" @@ -48,6 +49,7 @@ LicenseAgreement.Exit="ออก" Basic.Scene="ฉาก" + Basic.Main.AddSceneDlg.Title="เพิ่มฉาก" Basic.Main.DefaultSceneName.Text="ฉาก %1" @@ -97,6 +99,8 @@ Basic.Settings.Stream.StreamType="รูปแบบการสตรีม" + + Basic.Settings.Video="วีดีโอ" Basic.Settings.Video.DisableAeroWindows="ปิดการใช้งาน Aero (เฉพาะ Windows เท่านั้น)" Basic.Settings.Video.FPS="FPS:" diff --git a/obs/data/locale/tr-TR.ini b/obs/data/locale/tr-TR.ini index 4edaa54..da1061c 100644 --- a/obs/data/locale/tr-TR.ini +++ b/obs/data/locale/tr-TR.ini @@ -8,6 +8,7 @@ Cancel="İptal" Close="Kapat" Save="Kaydet" Discard="Vazgeç" +Disable="Devre dışı bırak" Yes="Evet" No="Hayır" Add="Ekle" @@ -19,9 +20,9 @@ Properties="Özellikler" MoveUp="Yukarı Taşı" MoveDown="Aşağı Taşı" Settings="Ayarlar" -Display="Görüntü" -Name="Adı" -Exit="Çıkış" +Display="Görüntüle" +Name="İsim" +Exit="Çık" Mixer="Karıştırıcı" Browse="Gözat" Mono="Mono" @@ -31,28 +32,35 @@ PreviewProjector="Tam Ekran Yansıtması (Önizleme)" SceneProjector="Tam Ekran Yansıtması (Sahne)" SourceProjector="Tam Ekran Yansıtması (Kaynak)" Clear="Temizle" -Revert="Sıfırla" +Revert="Eski Haline Döndür" Show="Göster" Hide="Gizle" Untitled="İsimsiz" New="Yeni" Duplicate="Çoğalt" Enable="Etkinleştir" +Transition="Geçiş" +Left="Sol" +Right="Sağ" +Top="Üst" +Bottom="Alt" +Basic.TransitionDuration="Süre" + TitleBar.Profile="Profil" TitleBar.Scenes="Sahneler" -NameExists.Title="Bu ad zaten kullanılıyor" -NameExists.Text="Bu ad zaten kullanılıyor." +NameExists.Title="Bu isim zaten mevcut" +NameExists.Text="Bu isim zaten kullanılıyor." -NoNameEntered.Title="Lütfen geçerli bir ad girin" -NoNameEntered.Text="İsim boş olamaz." +NoNameEntered.Title="Lütfen geçerli bir isim girin" +NoNameEntered.Text="İsmi boş kullanamazsınız." -ConfirmExit.Title="OBS'den Çık?" +ConfirmExit.Title="OBS'den Çıkılsın mı?" ConfirmExit.Text="OBS şu anda etkin. Tüm yayınlar / kayıtlar kapatılacak. Çıkmak istediğinize emin misiniz?" ConfirmRemove.Title="Kaldırmayı Onayla" @@ -61,7 +69,6 @@ ConfirmRemove.Text="'$1''i kaldırmak istediğinizden emin misiniz?" 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." Output.ConnectFail.ConnectFailed="Sunucuya bağlanılamadı" -Output.ConnectFail.InvalidStream="Seçilen yayına veya yayın anahtarına erişilemedi. Bu sorun , yayın anahtarının veya kanalının yanlış olmasından veya sistemin hala oturum açmış olduğunuzu düşünmesinden kaynaklanıyor olabilir." Output.ConnectFail.Error="Sunucuya bağlanmaya çalışırken beklenmeyen bir hata oluştu. Daha fazla bilgi için günlük dosyasına bakınız." Output.ConnectFail.Disconnected="Sunucu bağlantısı kesildi." @@ -72,7 +79,7 @@ Output.RecordNoSpace.Msg="Kayıt'aa devam etmek yeterli disk alanı yok." Output.RecordError.Title="Kayıt Hatası" Output.RecordError.Msg="Kayıt anında bir hata oluştu." -Output.BadPath.Title="Geçersiz Dosya Dizini" +Output.BadPath.Title="Dosya Yolu Geçersiz" Output.BadPath.Text="Ayarlanan dosya kayıt yolu geçersiz. Lütfen ayarlarınızı kontrol ederek geçerli bir dosya yolunun girilmiş olduğundan emin olunuz." LogReturnDialog="Günlük Dosyası Başarıyla Karşıya Yüklendi" @@ -83,12 +90,11 @@ LicenseAgreement="Lisans Sözleşmesi" LicenseAgreement.PleaseReview="Lütfen OBS'yi kullanmadan önce lisans sözleşmesini gözden geçiriniz. Bu programı kullanarak GNU Genel Kamu Lisansı v2.0 okuyup anladığınızı kabul etmiş sayılırsınız. Sözleşmenin geri kalan kısmını görmek için lütfen sayfayı aşağı kaydırınız." LicenseAgreement.ClickIAgreeToContinue="Sözleşme koşullarını kabul ediyorsanız, devam etmek için Kabul Ediyoruma tıklayın. OBS'yi kullanmak için sözleşme koşullarını kabul etmelisiniz." LicenseAgreement.IAgree="Kabul Ediyorum" -LicenseAgreement.Exit="Çıkış" +LicenseAgreement.Exit="Çık" -Remux.SourceFile="OBS Kaydediyor" +Remux.SourceFile="OBS Kayıt ediyor" Remux.TargetFile="Hedef Dosya" Remux.Remux="Remux" -Remux.RecordingPattern="OBS Kaydı (*.flv)" Remux.FinishedTitle="Remux tamamlandı" Remux.Finished="Kayıt remux edildi" Remux.FinishedError="Kayıt remux edildi, ancak dosya tamamlanmamış olabilir" @@ -100,7 +106,7 @@ Remux.ExitUnfinishedTitle="Remux işlemi devam etmekte" Remux.ExitUnfinished="Remux işlemi tamamlanmadı, şu anda durma dosyayı kullanılamaz hale getirebilir.\nRemux işlemini durdurmak istediğinizden emin misiniz?" UpdateAvailable="Yeni Güncelleştirme Mevcut" -UpdateAvailable.Text="Versiyon %1.%2.%3 şimdi mevcut. İndirmek için tıklayınız" +UpdateAvailable.Text="%1.%2.%3 sürümü şimdi kullanılabilir. İndirmek için tıklayın" Basic.DesktopDevice1="Masaüstü Ses" Basic.DesktopDevice2="Masaüstü Ses 2" @@ -114,10 +120,11 @@ Basic.DisplayCapture="Ekran Yakalama" Basic.Main.PreviewConextMenu.Enable="Önizlemeyi Etkinleştir" + Basic.Main.AddSceneDlg.Title="Sahne Ekle" Basic.Main.AddSceneDlg.Text="Lütfen sahne adını giriniz" -Basic.Main.DefaultSceneName.Text="Sahne %1" +Basic.Main.DefaultSceneName.Text="%1 Sahnesi" Basic.Main.AddSceneCollection.Title="Sahne Koleksiyonu Ekle" Basic.Main.AddSceneCollection.Text="Sahne koleksiyonunun isimini giriniz" @@ -168,7 +175,7 @@ Basic.Filters.Title="'%1' için filtreler" Basic.Filters.AddFilter.Title="Filtre adı" Basic.Filters.AddFilter.Text="Lütfen filtrenin adını belirtin" -Basic.TransformWindow="Sahne Eleman Dönüşümü" +Basic.TransformWindow="Sahne Ögesini Dönüştür" Basic.TransformWindow.Position="Konum" Basic.TransformWindow.Rotation="Döndürme" Basic.TransformWindow.Size="Boyut" @@ -219,13 +226,13 @@ Basic.MainMenu.File.Exit="Ç&ıkış" Basic.MainMenu.Edit="&Düzenle" Basic.MainMenu.Edit.Undo="&Geri al" Basic.MainMenu.Edit.Redo="&Tekrar Yap" -Basic.MainMenu.Edit.UndoAction="&Geri al $1" -Basic.MainMenu.Edit.RedoAction="&Tekrar Yap $1" +Basic.MainMenu.Edit.UndoAction="&$1 Geri al" +Basic.MainMenu.Edit.RedoAction="&$1 Yinele" Basic.MainMenu.Edit.Transform="&Dönüştür" Basic.MainMenu.Edit.Transform.EditTransform="&Dönüştürmeyi Düzenle..." Basic.MainMenu.Edit.Transform.ResetTransform="&Dönüştürmeyi Sıfırla" -Basic.MainMenu.Edit.Transform.Rotate90CW="Saat yönünde 90 derece döndür" -Basic.MainMenu.Edit.Transform.Rotate90CCW="Saatin tersi yönünde 90 derece döndür" +Basic.MainMenu.Edit.Transform.Rotate90CW="90 derece saat yönüne döndür" +Basic.MainMenu.Edit.Transform.Rotate90CCW="90 derece saatin tersi yönüne döndür" Basic.MainMenu.Edit.Transform.Rotate180="180 derece döndür" Basic.MainMenu.Edit.Transform.FlipHorizontal="&Yatay Döndür" Basic.MainMenu.Edit.Transform.FlipVertical="Dikey &Çevir" @@ -249,11 +256,11 @@ Basic.MainMenu.Help.Logs.ShowLogs="&Günlük Dosyalarını Göster" Basic.MainMenu.Help.Logs.UploadCurrentLog="&Mevcut Günlük Dosyasını Karşıya Yükle" Basic.MainMenu.Help.Logs.UploadLastLog="&Son Günlük Dosyasını Karşıya Yükle" Basic.MainMenu.Help.Logs.ViewCurrentLog="&Şimdiki Günlüğü Göster" -Basic.MainMenu.Help.CheckForUpdates="Güncelleştirmeleri Kontrol et" +Basic.MainMenu.Help.CheckForUpdates="Güncellemeleri Kontrol et" Basic.Settings.ProgramRestart="Programın, bu ayarların etkinleşmesi için yeniden başlatılması gerekir." Basic.Settings.ConfirmTitle="Değişiklikleri Onayla" -Basic.Settings.Confirm="Kaydedilmemiş değişiklikleriniz var. Değişiklikler kaydedilsin mi?" +Basic.Settings.Confirm="Kayıt edilmemiş değişiklikleriniz var. Değişiklikler kayıt edilsin mi?" Basic.Settings.General="Genel" Basic.Settings.General.Theme="Tema" @@ -323,14 +330,16 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Ses Kodlayıcı" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Ses Kodlayıcı Ayarları (var ise)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer Ayarları (eğer varsa)" + + Basic.Settings.Video="Video" -Basic.Settings.Video.Adapter="Video Bağdaştırıcısi:" +Basic.Settings.Video.Adapter="Video Bağdaştırıcı:" Basic.Settings.Video.BaseResolution="Temel (Tuval) Çözünürlüğü:" Basic.Settings.Video.ScaledResolution="Çıkış (Ölçekli) Çözünürlüğü:" Basic.Settings.Video.DownscaleFilter="Filtreyi Azalt:" Basic.Settings.Video.DisableAeroWindows="Aero'yu Devre Dışı Bırak (yalnızca Windows)" Basic.Settings.Video.FPS="FPS:" -Basic.Settings.Video.FPSCommon="Yaygın FPS değerleri" +Basic.Settings.Video.FPSCommon="Ortak FPS Değerleri" Basic.Settings.Video.FPSInteger="Tamsayı FPS değeri" Basic.Settings.Video.FPSFraction="Kesirli FPS değeri" Basic.Settings.Video.Numerator="Pay:" diff --git a/obs/data/locale/uk-UA.ini b/obs/data/locale/uk-UA.ini index e576d52..07c0ca9 100644 --- a/obs/data/locale/uk-UA.ini +++ b/obs/data/locale/uk-UA.ini @@ -37,6 +37,7 @@ Enable="Увімкнути" + TitleBar.Profile="Профіль" TitleBar.Scenes="Сцени" @@ -106,6 +107,9 @@ Basic.Scene="Сцена" + + + diff --git a/obs/data/locale/vi-VN.ini b/obs/data/locale/vi-VN.ini index d71f293..d00db1c 100644 --- a/obs/data/locale/vi-VN.ini +++ b/obs/data/locale/vi-VN.ini @@ -41,6 +41,7 @@ Enable="Kích hoạt" + TitleBar.Profile="Hồ sơ cá nhân" TitleBar.Scenes="Cảnh" @@ -61,7 +62,6 @@ ConfirmRemove.Text="Bạn có chắc bạn muốn loại bỏ '$1' không?" 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ệ." Output.ConnectFail.ConnectFailed="Không thể kết nối tới hệ phục vụ" -Output.ConnectFail.InvalidStream="'' stream key '' lỗi không xác định. Bạn nên đăng nhập để lấy lại key hoặc làm mới lại key." Output.ConnectFail.Error="Lỗi bất ngờ xảy ra khi thử kết nối tới hệ phục vụ. Biết thêm thông tin trong các tập tin log." Output.ConnectFail.Disconnected="Ngắt kết nối từ máy chủ." @@ -88,7 +88,6 @@ LicenseAgreement.Exit="Thoát" Remux.SourceFile="Ghi âm OBS" Remux.TargetFile="Tệp đích" Remux.Remux="Remux" -Remux.RecordingPattern="OBS ghi âm (*.flv)" 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 đủ" @@ -114,6 +113,7 @@ Basic.DisplayCapture="Chụp màn hình" Basic.Main.PreviewConextMenu.Enable="Bật xem trước" + Basic.Main.AddSceneDlg.Title="Thêm cảnh" Basic.Main.AddSceneDlg.Text="Vui lòng nhập tên của cảnh" @@ -332,6 +332,8 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Mã hóa âm thanh" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Thiết đặt bộ mã hóa video (nếu có)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer cài đặt (nếu có)" + + Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Video Adapter:" Basic.Settings.Video.BaseResolution="Cơ sở (vải) độ phân giải:" diff --git a/obs/data/locale/zh-CN.ini b/obs/data/locale/zh-CN.ini index 17806a1..be86f53 100644 --- a/obs/data/locale/zh-CN.ini +++ b/obs/data/locale/zh-CN.ini @@ -8,13 +8,14 @@ Cancel="取消" Close="关闭" Save="保存" Discard="舍弃" +Disable="禁用" Yes="是" No="否" Add="添加" Remove="移除" Rename="重命名" Interact="交互" -Filters="过滤器" +Filters="滤镜" Properties="属性" MoveUp="上移" MoveDown="下移" @@ -26,7 +27,7 @@ Mixer="混音器" Browse="浏览" Mono="单声道​" Stereo="立体声​​​" -DroppedFrames="掉帧 %1 (%2%)" +DroppedFrames="丢帧 %1 (%2%)" PreviewProjector="全屏投影仪(预览)" SceneProjector="全屏投影仪 (现场)" SourceProjector="全屏投影仪(源)" @@ -36,21 +37,37 @@ Show="显示" Hide="隐藏" Untitled="未命名" New="新建" -Duplicate="重复" +Duplicate="复制" Enable="启用" DisableOSXVSync="禁用 OSX V-Sync" ResetOSXVSyncOnExit="退出时重置 OSX V-Sync" HighResourceUsage="编码过载! 考虑下调低视频设置或使用更快的编码预设." Transition="过渡动画" QuickTransitions="快速过渡动画" +Left="左" +Right="右" +Top="上" +Bottom="下" +QuickTransitions.SwapScenes="在过渡动画后交换预览/输出场景" +QuickTransitions.SwapScenesTT="在过渡后,交换预览和输出场景(如果输出的原始场景仍然存在). \n 这个不会撤消任何可能对输出的原始场景的更改." +QuickTransitions.DuplicateScene="复制场景" +QuickTransitions.DuplicateSceneTT="当编辑同一场景, 允许编辑来源的可见性/变换而无需修改源输出. \n 为了编辑源属性而无需修改输出, 启动 ' 复制源'. \n 改变这个值将会重置当前的输出场景(如果它仍然存在)." +QuickTransitions.EditProperties="复制源" +QuickTransitions.EditPropertiesTT="当编辑同一场景, 允许编辑来源的属性而不修改输出. \n 只有启用了'复制场景',才能使用这项设置. \n 某些来源 (如捕获或媒体源) 并不支持这个, 并不能单独编辑. \n 修改这个值将重置当前输出场景 (如果它仍然存在). \n\n 警告: 因为源将被复制这可能需要额外的系统或视频资源." QuickTransitions.HotkeyName="快速过渡: %1" +Basic.AddTransition="添加可配置的过渡动画" +Basic.RemoveTransition="删除可配置的过渡动画" +Basic.TransitionProperties="过渡动画属性" Basic.SceneTransitions="场景过渡" Basic.TransitionDuration="时长" Basic.TogglePreviewProgramMode="工作室模式" -TitleBar.Profile="档案" +TransitionNameDlg.Text="请输入过渡动画的名称" +TransitionNameDlg.Title="过渡动画名称" + +TitleBar.Profile="配置文件" TitleBar.Scenes="场景" NameExists.Title="名称已存在" @@ -66,15 +83,15 @@ ConfirmStop.Title="停止流?" ConfirmStop.Text="你确定你想要停止流?" ConfirmExit.Title="退出OBS?" -ConfirmExit.Text="OBS当前活跃. 所有的流/录像将会停止. 你确定想要退出吗?" +ConfirmExit.Text="OBS工作中. 所有的流/录像将会停止. 你确定想要退出吗?" ConfirmRemove.Title="确认移除" -ConfirmRemove.Text="确实要删除 '$1' 吗?" +ConfirmRemove.Text="确定要删除 '$1' 吗?" Output.ConnectFail.Title="连接失败" Output.ConnectFail.BadPath="无效的路径或URL。请检查您的设置以确认它们是有效的。" Output.ConnectFail.ConnectFailed="无法连接到服务器" -Output.ConnectFail.InvalidStream="无法访问指定的通道或流密钥. 这可能是因为 密钥/通道 是无效的, 或者服务器认为你已经登录了." +Output.ConnectFail.InvalidStream="无法访问指定的频道或流密钥, 请仔细检查您的密钥流. 如果它是正确的, 有可能是连接到服务器时出现问题." Output.ConnectFail.Error="试图连接到服务器时出现意外的错误。详细信息记录在日志文件中。" Output.ConnectFail.Disconnected="已从服务器断开。" @@ -101,7 +118,7 @@ LicenseAgreement.Exit="退出" Remux.SourceFile="OBS 录像" Remux.TargetFile="目标文件" Remux.Remux="重新封装" -Remux.RecordingPattern="OBS 录像(*.flv)" +Remux.OBSRecording="OBS 录像" Remux.FinishedTitle="转封装完成" Remux.Finished="录像已经转封装" Remux.FinishedError="录像已经转封装, 但是文件可能不完整." @@ -127,6 +144,18 @@ Basic.DisplayCapture="显示捕获" Basic.Main.PreviewConextMenu.Enable="开启预览" +Deinterlacing="去隔行扫描" +Deinterlacing.Discard="舍弃" +Deinterlacing.Retro="复古" +Deinterlacing.Blend="混合" +Deinterlacing.Blend2x="混合 2x" +Deinterlacing.Linear="线性" +Deinterlacing.Linear2x="线性 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="上场优先" +Deinterlacing.BottomFieldFirst="下场优先" + Basic.Main.AddSceneDlg.Title="添加场景" Basic.Main.AddSceneDlg.Text="请输入场景名称" @@ -192,6 +221,7 @@ Basic.TransformWindow.Alignment="位置对齐" Basic.TransformWindow.BoundsType="边界框类型" Basic.TransformWindow.BoundsAlignment="边界框对齐方式" Basic.TransformWindow.Bounds="边界框大小" +Basic.TransformWindow.Crop="裁剪" Basic.TransformWindow.Alignment.TopLeft="左上" Basic.TransformWindow.Alignment.TopCenter="顶上" @@ -278,6 +308,11 @@ Basic.Settings.General.Theme="主题" Basic.Settings.General.Language="语言" Basic.Settings.General.WarnBeforeStartingStream="启动流时显示确认对话框" Basic.Settings.General.WarnBeforeStoppingStream="停止流时显示确认对话框" +Basic.Settings.General.Snapping="源对齐方式" +Basic.Settings.General.ScreenSnapping="对齐源到屏幕边缘" +Basic.Settings.General.CenterSnapping="水平和垂直居中对齐源" +Basic.Settings.General.SourceSnapping="对齐源跟其他的源" +Basic.Settings.General.SnapDistance="对齐的敏感性" Basic.Settings.Stream="串流" Basic.Settings.Stream.StreamType="串流类型" @@ -287,6 +322,7 @@ Basic.Settings.Output.Format="录像格式" Basic.Settings.Output.Encoder="编码器" Basic.Settings.Output.SelectDirectory="选择录像目录" Basic.Settings.Output.SelectFile="选择录像文件" +Basic.Settings.Output.EnforceBitrate="强制执行流媒体服务比特率限制" Basic.Settings.Output.Mode="输出模式" Basic.Settings.Output.Mode.Simple="简单" Basic.Settings.Output.Mode.Adv="高级" @@ -295,13 +331,18 @@ Basic.Settings.Output.Simple.SavePath="录像路径" Basic.Settings.Output.Simple.RecordingQuality="录像质量" Basic.Settings.Output.Simple.RecordingQuality.Stream="与流相同" Basic.Settings.Output.Simple.RecordingQuality.Small="高质量, 中等文件大小" -Basic.Settings.Output.Simple.RecordingQuality.HQ="无法区分的质量, 大文件大小" +Basic.Settings.Output.Simple.RecordingQuality.HQ="近似无损的质量, 大文件大小" Basic.Settings.Output.Simple.RecordingQuality.Lossless="无损的质量, 非常大的文件大小" -Basic.Settings.Output.Simple.Warn.Encoder="警告: 使用一个软件编码器录像使用与流不同的质量, 将会需要额外的CPU使用, 如果你同时流传输跟录像. " -Basic.Settings.Output.Simple.Warn.Lossless="警告: 无损质量产生非常大的文件大小! 无损的质量可以每分钟使用超过 7 千兆字节的磁盘空间在高分辨率和帧速率的情况。 无损不适合长时间录像,除非你有很大数量的可用磁盘空间。" +Basic.Settings.Output.Simple.Warn.VideoBitrate="警告: 视频比特率将设置为 %1, 这是当前的流媒体服务的上限值. 如果你确定你想要超过 %1, 启用高级的编码器选项并取消选中\"强制流媒体服务比特率限制\"." +Basic.Settings.Output.Simple.Warn.AudioBitrate="警告: 音频比特率将设置为 %1, 这是当前的流媒体服务的上限值. 如果你确定你想要超过 %1, 启用高级的编码器选项并取消选中\"强制流媒体服务比特率限制\"." +Basic.Settings.Output.Simple.Warn.Encoder="警告: 同时传输流和录像, 并使用软件编码器编码与流不同的质量, 将会需要额外的CPU使用." +Basic.Settings.Output.Simple.Warn.Lossless="警告: 无损质量产生的文件大小非常大! 无损质量在高分辨率和帧速率的情况下可以使用超过7GB的磁盘空间每分钟。 无损不适合长时间录像,除非你有很多可用的磁盘空间。" Basic.Settings.Output.Simple.Warn.Lossless.Msg="你确定你想要使用无损质量?" Basic.Settings.Output.Simple.Warn.Lossless.Title="无损质量警告!" -Basic.Settings.Output.Simple.Encoder.Software="软件 (264)" +Basic.Settings.Output.Simple.Warn.MultipleQSV="警告: 当同时推流和录像时, 你不能使用多个单独的 QSV 编码器. 如果你想要同时推流和录像, 请更改录像的编码器或者推流的编码器." +Basic.Settings.Output.Simple.Encoder.Software="软件 (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="硬件 (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="硬件 (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="软件 (x 264 低 CPU 使用率预设,增加文件大小)" Basic.Settings.Output.VideoBitrate="视频比特率" Basic.Settings.Output.AudioBitrate="音频比特率" @@ -328,6 +369,8 @@ 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.Filename="文件名格式" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="如果文件存在, 覆盖" Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg 输出类型" Basic.Settings.Output.Adv.FFmpeg.Type.URL="输出到 URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="输出到文件" @@ -348,6 +391,10 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="音频编码器" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="视频编码器设置 (如果有)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer 设置 (如果有)" +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 年, 后两位 (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 % sign\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 AM 或 PM\n%S 秒 (00-61)\n%y 年, 后两位 (00-99)\n%Y 年\n%z ISO 8601 offset from UTC 或者 时区\n 名称或缩写\n%Z 时区名称或缩写\n" + Basic.Settings.Video="视频" Basic.Settings.Video.Adapter="视频适配器:" Basic.Settings.Video.BaseResolution="基础 (Canvas) 分辨率:" diff --git a/obs/data/locale/zh-TW.ini b/obs/data/locale/zh-TW.ini index 9a2ec22..c6f71f0 100644 --- a/obs/data/locale/zh-TW.ini +++ b/obs/data/locale/zh-TW.ini @@ -8,13 +8,14 @@ Cancel="取消" Close="關閉" Save="儲存" Discard="捨棄" +Disable="停用" Yes="是" No="否" Add="新增" -Remove="刪除" +Remove="移除" Rename="重新命名" Interact="互動" -Filters="篩選器" +Filters="濾鏡" Properties="屬性" MoveUp="向上移動" MoveDown="向下移動" @@ -43,6 +44,10 @@ ResetOSXVSyncOnExit="離開時重製OSX垂直同步" HighResourceUsage="編碼過載!考慮降低影像設定或使用更快的編碼預設。" Transition="轉場" QuickTransitions="快速轉場" +Left="左" +Right="右" +Top="上" +Bottom="下" QuickTransitions.SwapScenes="轉場後交換預覽/輸出場景" QuickTransitions.SwapScenesTT="(如果輸出的原始場景仍然存在) 轉場後交換預覽和輸出場景。\n這並不會復原任何對輸出原始場景所作的改動。" @@ -52,10 +57,16 @@ QuickTransitions.EditProperties="複製來源" QuickTransitions.EditPropertiesTT="在修改同樣的場景時,讓修改影像來源的屬性時不需要修改輸出。\n這只能在'複製場景'被啟動時使用。\n某些來源 (如擷取或是媒體來源) 並不支援此功能且無法被單獨修改。\n變更這個值將會 (如果還存在的話) 重置目前的輸出場景。\n\n警告:由於來源會被複製,這功能可能會使用額外的系統或是影像資源。" QuickTransitions.HotkeyName="快速轉場:%1" +Basic.AddTransition="添加設置轉換動畫" +Basic.RemoveTransition="移除設置轉換動畫" +Basic.TransitionProperties="轉換動畫屬性" Basic.SceneTransitions="轉場特效" Basic.TransitionDuration="持續時間" Basic.TogglePreviewProgramMode="工作室模式" +TransitionNameDlg.Text="請輸入轉換動畫名稱" +TransitionNameDlg.Title="轉換動畫名稱" + TitleBar.Profile="設定檔" TitleBar.Scenes="場景" @@ -63,7 +74,7 @@ NameExists.Title="名稱已經存在" NameExists.Text="這個名稱已被使用。" NoNameEntered.Title="請輸入有效的名稱" -NoNameEntered.Text="您使用的名稱不能為空。" +NoNameEntered.Text="您不能使用空白的名稱。" ConfirmStart.Title="啟動串流?" ConfirmStart.Text="你確定你想要啟動串流?" @@ -72,7 +83,7 @@ ConfirmStop.Title="停止串流?" ConfirmStop.Text="你確定你想要停止串流?" ConfirmExit.Title="離開OBS?" -ConfirmExit.Text="正在使用 OBS,所有的錄製活動都將被關閉。您確定要退出嗎?" +ConfirmExit.Text="正在使用 OBS,所有的串流/錄製都將被關閉。您確定要退出嗎?" ConfirmRemove.Title="確認刪除?" ConfirmRemove.Text="您確定要刪除「$1」?" @@ -80,7 +91,7 @@ ConfirmRemove.Text="您確定要刪除「$1」?" Output.ConnectFail.Title="連線失敗" Output.ConnectFail.BadPath="無效的路徑或 URL。 請確認您的設定是正確的。" Output.ConnectFail.ConnectFailed="與伺服器連線失敗。" -Output.ConnectFail.InvalidStream="無法存取指定的頻道或串流金鑰。 可能輸入了無效的金鑰或頻道,或伺服器認爲您已在發送串流中(已登入)。" +Output.ConnectFail.InvalidStream="無法訪問指定的頻道或串流金鑰,請仔細檢查您的串流金鑰。 如果它是正確的有可能是連接到伺服器時出現問題。" Output.ConnectFail.Error="發生無法預期的連線錯誤。 參見 Log 檔以便獲取更多資訊。" Output.ConnectFail.Disconnected="與伺服器連線中斷。" @@ -107,7 +118,6 @@ LicenseAgreement.Exit="離開" Remux.SourceFile="OBS 錄影" Remux.TargetFile="目標檔案" Remux.Remux="重新封裝" -Remux.RecordingPattern="OBS 錄影 (*.flv)" Remux.FinishedTitle="重新封裝完成" Remux.Finished="錄影已被重新封裝" Remux.FinishedError="錄影已被重新封裝,但檔案可能不完整" @@ -133,6 +143,16 @@ Basic.DisplayCapture="截取螢幕" Basic.Main.PreviewConextMenu.Enable="啟用預覽" +Deinterlacing="去交錯" +Deinterlacing.Discard="捨棄" +Deinterlacing.Retro="復古" +Deinterlacing.Blend="混合" +Deinterlacing.Blend2x="混合 2x" +Deinterlacing.Linear="線性" +Deinterlacing.Linear2x="線性 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" + Basic.Main.AddSceneDlg.Title="新增場景" Basic.Main.AddSceneDlg.Text="請輸入場景名稱" @@ -182,8 +202,8 @@ Basic.StatusBar.DelayStartingIn="延遲(在 %1 秒內開始)" Basic.StatusBar.DelayStoppingIn="延遲(在 %1 秒內停止)" Basic.StatusBar.DelayStartingStoppingIn="延遲(在 %1 秒內停止,%2 秒後開始)" -Basic.Filters="篩選器" -Basic.Filters.AsyncFilters="音訊/影像 篩選器" +Basic.Filters="濾鏡" +Basic.Filters.AsyncFilters="音訊/影像 濾鏡" Basic.Filters.AudioFilters="音訊濾鏡" Basic.Filters.EffectFilters="特效濾鏡" Basic.Filters.Title="'%1' 的濾鏡" @@ -198,6 +218,7 @@ Basic.TransformWindow.Alignment="位置原點" Basic.TransformWindow.BoundsType="外框類型" Basic.TransformWindow.BoundsAlignment="對齊外框" Basic.TransformWindow.Bounds="外框大小" +Basic.TransformWindow.Crop="剪裁" Basic.TransformWindow.Alignment.TopLeft="左上角" Basic.TransformWindow.Alignment.TopCenter="水平靠上" @@ -293,6 +314,7 @@ Basic.Settings.Output.Format="錄影格式" Basic.Settings.Output.Encoder="編碼器" Basic.Settings.Output.SelectDirectory="選擇錄影資料夾" Basic.Settings.Output.SelectFile="選擇錄影檔案" +Basic.Settings.Output.EnforceBitrate="強制設定實況流量上限" Basic.Settings.Output.Mode="輸出模式" Basic.Settings.Output.Mode.Simple="簡易" Basic.Settings.Output.Mode.Adv="進階" @@ -303,11 +325,16 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="與實況同等畫質" Basic.Settings.Output.Simple.RecordingQuality.Small="高畫質,檔案大小中等" 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.Encoder="警告:如果錄影與實況同時運作,並使用與實況不同的編碼品質設定將會增加額外的CPU使用量" Basic.Settings.Output.Simple.Warn.Lossless="警告:無損畫質將會產生大容量的暫存檔!無損畫質在高解析度或高幀率時,可能會每分鐘使用高達 7GB(gigabytes)的容量。除非您擁有海量的硬碟空間,否則不建議使用無損畫質錄製長時間的影片。" Basic.Settings.Output.Simple.Warn.Lossless.Msg="你確定你想要使用無損畫質?" Basic.Settings.Output.Simple.Warn.Lossless.Title="無損畫質警告!" +Basic.Settings.Output.Simple.Warn.MultipleQSV="警告 ︰ 在同一時間串流和錄像,您不能使用多個單獨的 QSV 編碼器。 如果你想要在同一時間串流和錄像,請更改錄像編碼器或串流編碼器。" Basic.Settings.Output.Simple.Encoder.Software="軟體編碼( x264 )" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="硬體 (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="硬體 (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="軟體編碼( x264 預設低 CPU 使用率,將增加檔案容量 )" Basic.Settings.Output.VideoBitrate="影像頻率(kbit/s)" Basic.Settings.Output.AudioBitrate="音效頻率(kbit/s)" @@ -334,6 +361,8 @@ 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.Filename="檔案名稱格式" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="如果檔案存在就覆寫" Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg 輸出類型" Basic.Settings.Output.Adv.FFmpeg.Type.URL="輸出到 URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="輸出到檔案" @@ -354,6 +383,9 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="音效編碼器" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="音效編碼設定(如果有才啟用)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer 設定(如果有才啟用)" +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" + + Basic.Settings.Video="影像" Basic.Settings.Video.Adapter="顯示卡:" Basic.Settings.Video.BaseResolution="來源(全畫面)解析度:" @@ -384,7 +416,7 @@ Basic.Settings.Audio.AuxDevice="麥克風/輸入音效 1" Basic.Settings.Audio.AuxDevice2="麥克風/輸入音效 2" Basic.Settings.Audio.AuxDevice3="麥克風/輸入音效 3" Basic.Settings.Audio.EnablePushToMute="啟用 按壓時靜音" -Basic.Settings.Audio.PushToMuteDelay="延遲 按壓時靜音" +Basic.Settings.Audio.PushToMuteDelay="按壓時靜音 延遲" Basic.Settings.Audio.EnablePushToTalk="啟用 按壓時說話" Basic.Settings.Audio.PushToTalkDelay="按壓時說話 延遲" Basic.Settings.Audio.UnknownAudioDevice="[設備未連接或不可用]" diff --git a/obs/dist/obs.desktop b/obs/dist/obs.desktop index 9cc1b1f..f70a77c 100644 --- a/obs/dist/obs.desktop +++ b/obs/dist/obs.desktop @@ -3,6 +3,7 @@ Version=1.0 Name=OBS GenericName=Streaming/Recording Software Comment=Free and Open Source Streaming/Recording Software +Comment[ru]=Бесплатная программа с открытым кодом для записи/трансляции видео Exec=obs Icon=obs Terminal=false diff --git a/obs/forms/OBSBasic.ui b/obs/forms/OBSBasic.ui index fae7d33..0bd0191 100644 --- a/obs/forms/OBSBasic.ui +++ b/obs/forms/OBSBasic.ui @@ -581,10 +581,103 @@ 4 - - - 2 + + + + 120 + 0 + + + + + + + 4 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 22 + 22 + + + + Basic.AddTransition + + + Basic.AddTransition + + + + + + + :/res/images/add.png:/res/images/add.png + + + true + + + addIconSmall + + + + + + + + 0 + 0 + + + + + 22 + 22 + + + + Basic.RemoveTransition + + + Basic.RemoveTransition + + + + + + + :/res/images/list_remove.png:/res/images/list_remove.png + + + true + + + removeIconSmall + + + @@ -599,6 +692,12 @@ 22 + + Basic.TransitionProperties + + + Basic.TransitionProperties + @@ -614,16 +713,6 @@ - - - - - 120 - 0 - - - - diff --git a/obs/forms/OBSBasicSettings.ui b/obs/forms/OBSBasicSettings.ui index 4b8919c..736b75e 100644 --- a/obs/forms/OBSBasicSettings.ui +++ b/obs/forms/OBSBasicSettings.ui @@ -185,6 +185,106 @@ + + + + Qt::Horizontal + + + + + + + true + + + + 0 + 0 + + + + Basic.Settings.General.Snapping + + + false + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Enable + + + true + + + + + + + Basic.Settings.General.ScreenSnapping + + + true + + + + + + + Basic.Settings.General.CenterSnapping + + + true + + + + + + + Basic.Settings.General.SourceSnapping + + + true + + + + + + + 1 + + + 0.500000000000000 + + + 10.000000000000000 + + + + + + + + 170 + 0 + + + + Basic.Settings.General.SnapDistance + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + @@ -439,7 +539,7 @@ - + Basic.Settings.Output.AudioBitrate @@ -449,7 +549,7 @@ - + 8 @@ -511,7 +611,7 @@ - + Basic.Settings.Output.Advanced @@ -521,51 +621,10 @@ - - - - - ultrafast - - - - - superfast - - - - - veryfast - - - - - faster - - - - - fast - - - - - medium - - - - - slow - - - - - slower - - - + + - + true @@ -578,7 +637,7 @@ - + Basic.Settings.Output.CustomEncoderSettings @@ -588,9 +647,29 @@ - + + + + + Basic.Settings.Output.EnforceBitrate + + + + + + + + + + Basic.Settings.Output.Encoder + + + simpleOutRecEncoder + + + @@ -2418,8 +2497,8 @@ 0 0 - 98 - 28 + 80 + 16 @@ -2784,8 +2863,8 @@ 0 0 - 525 - 383 + 559 + 563 @@ -2953,6 +3032,32 @@ + + + + Basic.Settings.Output.Adv.Recording + + + + + + Basic.Settings.Output.Adv.Recording.Filename + + + + + + + + + + Basic.Settings.Output.Adv.Recording.OverwriteIfExists + + + + + + @@ -3459,12 +3564,108 @@ setEnabled(bool) - 517 - 267 + 690 + 454 - 777 - 206 + 690 + 506 + + + + + snappingEnabled + toggled(bool) + label_9 + setEnabled(bool) + + + 376 + 196 + + + 305 + 224 + + + + + snappingEnabled + toggled(bool) + snapDistance + setEnabled(bool) + + + 417 + 204 + + + 434 + 234 + + + + + snappingEnabled + toggled(bool) + screenSnapping + setEnabled(bool) + + + 476 + 202 + + + 466 + 253 + + + + + snappingEnabled + toggled(bool) + sourceSnapping + setEnabled(bool) + + + 518 + 204 + + + 515 + 277 + + + + + snappingEnabled + toggled(bool) + centerSnapping + setEnabled(bool) + + + 557 + 207 + + + 866 + 306 + + + + + simpleOutAdvanced + toggled(bool) + simpleOutEnforce + setVisible(bool) + + + 484 + 147 + + + 483 + 170 diff --git a/obs/forms/OBSBasicTransform.ui b/obs/forms/OBSBasicTransform.ui index f48d3e1..7f49ffa 100644 --- a/obs/forms/OBSBasicTransform.ui +++ b/obs/forms/OBSBasicTransform.ui @@ -275,6 +275,19 @@ + + + + Qt::Vertical + + + + 10 + 10 + + + + @@ -321,19 +334,6 @@ - - - - Qt::Vertical - - - - 20 - 20 - - - - @@ -341,6 +341,61 @@ + + + + false + + + Basic.TransformWindow.Alignment.TopLeft + + + + Basic.TransformWindow.Alignment.TopLeft + + + + + Basic.TransformWindow.Alignment.TopCenter + + + + + Basic.TransformWindow.Alignment.TopRight + + + + + Basic.TransformWindow.Alignment.CenterLeft + + + + + Basic.TransformWindow.Alignment.Center + + + + + Basic.TransformWindow.Alignment.CenterRight + + + + + Basic.TransformWindow.Alignment.BottomLeft + + + + + Basic.TransformWindow.Alignment.BottomCenter + + + + + Basic.TransformWindow.Alignment.BottomRight + + + + @@ -416,61 +471,171 @@ - - - - false + + + + Qt::Vertical - - Basic.TransformWindow.Alignment.TopLeft + + + 10 + 10 + + + + + + + + Basic.TransformWindow.Crop - - - Basic.TransformWindow.Alignment.TopLeft - - - - - Basic.TransformWindow.Alignment.TopCenter - - - - - Basic.TransformWindow.Alignment.TopRight - - - - - Basic.TransformWindow.Alignment.CenterLeft - - - - - Basic.TransformWindow.Alignment.Center - - - - - Basic.TransformWindow.Alignment.CenterRight - - - - - Basic.TransformWindow.Alignment.BottomLeft - - - - - Basic.TransformWindow.Alignment.BottomCenter - - - - - Basic.TransformWindow.Alignment.BottomRight - - + + + + + + + 0 + 0 + + + + + 70 + 0 + + + + 100000 + + + + + + + Left + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + cropLeft + + + + + + + Bottom + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + cropBottom + + + + + + + + 0 + 0 + + + + + 70 + 0 + + + + 100000 + + + + + + + + 0 + 0 + + + + + 70 + 0 + + + + 100000 + + + + + + + Top + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + cropTop + + + + + + + Right + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + cropRight + + + + + + + + 0 + 0 + + + + + 70 + 0 + + + + 100000 + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + diff --git a/obs/installer/mp-installer.nsi b/obs/installer/mp-installer.nsi new file mode 100644 index 0000000..2a9146f --- /dev/null +++ b/obs/installer/mp-installer.nsi @@ -0,0 +1,286 @@ +; Script generated with the Venis Install Wizard + +; Define your application name +!define APPNAME "OBS Studio" +!define APPVERSION "0.13.4" +!define APPNAMEANDVERSION "OBS Studio ${APPVERSION}" +; !define BROWSER + +; Additional script dependencies +!include WinVer.nsh +!include x64.nsh + +; Main Install settings +Name "${APPNAMEANDVERSION}" +InstallDir "$PROGRAMFILES32\obs-studio" +InstallDirRegKey HKLM "Software\${APPNAME}" "" +!ifdef BROWSER +OutFile "OBS-Studio-${APPVERSION}-With-Browser-Installer.exe" +!else +OutFile "OBS-Studio-${APPVERSION}-Installer.exe" +!endif + +; Use compression +SetCompressor /SOLID LZMA + +; Need Admin +RequestExecutionLevel admin + +; Modern interface settings +!include "MUI.nsh" + +!define MUI_ABORTWARNING +!define MUI_FINISHPAGE_RUN "$INSTDIR\bin\32bit\obs32.exe" + +!define MUI_PAGE_CUSTOMFUNCTION_LEAVE PreReqCheck + +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_LICENSE "data\obs-studio\license\gplv2.txt" +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH + +;!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_COMPONENTS +!insertmacro MUI_UNPAGE_INSTFILES + +; Set languages (first is default language) +!insertmacro MUI_LANGUAGE "English" +!insertmacro MUI_RESERVEFILE_LANGDLL + +Function PreReqCheck + ; Abort on XP or lower + ${If} ${AtMostWinXP} + MessageBox MB_OK|MB_ICONSTOP "Due to extensive use of DirectX 10 features, ${APPNAME} requires Windows Vista SP2 or higher and cannot be installed on this version of Windows." + Quit + ${EndIf} + + ; Vista specific checks + ${If} ${IsWinVista} + ; Check Vista SP2 + ${If} ${AtMostServicePack} 1 + MessageBox MB_YESNO|MB_ICONEXCLAMATION "${APPNAME} requires Service Pack 2 when running on Vista. Would you like to download it?" IDYES sptrue IDNO spfalse + sptrue: + ExecShell "open" "http://windows.microsoft.com/en-US/windows-vista/Learn-how-to-install-Windows-Vista-Service-Pack-2-SP2" + spfalse: + Quit + ${EndIf} + + ; Check Vista Platform Update + nsexec::exectostack "$SYSDIR\wbem\wmic.exe qfe where HotFixID='KB971512' get HotFixID /Format:list" + pop $0 + pop $0 + strcpy $1 $0 17 6 + strcmps $1 "HotFixID=KB971512" gotPatch + MessageBox MB_YESNO|MB_ICONEXCLAMATION "${APPNAME} requires the Windows Vista Platform Update. Would you like to download it?" IDYES putrue IDNO pufalse + putrue: + ${If} ${RunningX64} + ; 64 bit + ExecShell "open" "http://www.microsoft.com/en-us/download/details.aspx?id=4390" + ${Else} + ; 32 bit + ExecShell "open" "http://www.microsoft.com/en-us/download/details.aspx?id=3274" + ${EndIf} + pufalse: + Quit + gotPatch: + ${EndIf} + + ClearErrors + GetDLLVersion "MSVCR120.DLL" $R0 $R1 + IfErrors vs2013Missing vs2013OK + vs2013Missing: + MessageBox MB_YESNO|MB_ICONEXCLAMATION "Your system is missing runtime components that ${APPNAME} requires. Please make sure to install both vcredist_x64 and vcredist_x86. Would you like to download them?" IDYES vs2013true IDNO vs2013false + vs2013true: + ExecShell "open" "http://www.microsoft.com/en-us/download/details.aspx?id=40784" + vs2013false: + Quit + vs2013OK: + ClearErrors + + ; DirectX Version Check + ClearErrors + GetDLLVersion "D3DCompiler_33.dll" $R0 $R1 + IfErrors dxMissing33 dxOK + dxMissing33: + ClearErrors + GetDLLVersion "D3DCompiler_34.dll" $R0 $R1 + IfErrors dxMissing34 dxOK + dxMissing34: + ClearErrors + GetDLLVersion "D3DCompiler_35.dll" $R0 $R1 + IfErrors dxMissing35 dxOK + dxMissing35: + ClearErrors + GetDLLVersion "D3DCompiler_36.dll" $R0 $R1 + IfErrors dxMissing36 dxOK + dxMissing36: + ClearErrors + GetDLLVersion "D3DCompiler_37.dll" $R0 $R1 + IfErrors dxMissing37 dxOK + dxMissing37: + ClearErrors + GetDLLVersion "D3DCompiler_38.dll" $R0 $R1 + IfErrors dxMissing38 dxOK + dxMissing38: + ClearErrors + GetDLLVersion "D3DCompiler_39.dll" $R0 $R1 + IfErrors dxMissing39 dxOK + dxMissing39: + ClearErrors + GetDLLVersion "D3DCompiler_40.dll" $R0 $R1 + IfErrors dxMissing40 dxOK + dxMissing40: + ClearErrors + GetDLLVersion "D3DCompiler_41.dll" $R0 $R1 + IfErrors dxMissing41 dxOK + dxMissing41: + ClearErrors + GetDLLVersion "D3DCompiler_42.dll" $R0 $R1 + IfErrors dxMissing42 dxOK + dxMissing42: + ClearErrors + GetDLLVersion "D3DCompiler_43.dll" $R0 $R1 + IfErrors dxMissing43 dxOK + dxMissing43: + ClearErrors + GetDLLVersion "D3DCompiler_47.dll" $R0 $R1 + IfErrors dxMissing47 dxOK + dxMissing47: + MessageBox MB_YESNO|MB_ICONEXCLAMATION "Your system is missing DirectX components that ${APPNAME} requires. Would you like to download them?" IDYES dxtrue IDNO dxfalse + dxtrue: + ExecShell "open" "https://obsproject.com/go/dxwebsetup" + dxfalse: + Quit + dxOK: + ClearErrors + + ; Check previous instance + ; System::Call 'kernel32::OpenMutexW(i 0x100000, b 0, w "OBSMutex") i .R0' + ; IntCmp $R0 0 notRunning + ; System::Call 'kernel32::CloseHandle(i $R0)' + ; MessageBox MB_OK|MB_ICONEXCLAMATION "${APPNAME} is already running. Please close it first before installing a new version." /SD IDOK + ; Quit +notRunning: + +FunctionEnd + +Function filesInUse + MessageBox MB_OK|MB_ICONEXCLAMATION "Some files were not able to be installed. If this is the first time you are installing OBS, please disable any anti-virus or other security software and try again. If you are re-installing or updating OBS, close any applications that may be have been hooked, or reboot and try again." /SD IDOK +FunctionEnd + +Var outputErrors + +Section "OBS Studio" Section1 + + ; Set Section properties + SetOverwrite on + + SetShellVarContext all + + ; Set Section Files and Shortcuts + SetOutPath "$INSTDIR" + File /r "data" + SetOutPath "$INSTDIR\bin" + File /r "bin\32bit" + SetOutPath "$INSTDIR\obs-plugins" + File /r "obs-plugins\32bit" + + ${if} ${RunningX64} + SetOutPath "$INSTDIR\bin" + File /r "bin\64bit" + SetOutPath "$INSTDIR\obs-plugins" + File /r "obs-plugins\64bit" + ${endif} + + ClearErrors + + IfErrors 0 +2 + StrCpy $outputErrors "yes" + + WriteUninstaller "$INSTDIR\uninstall.exe" + + ; Delete Old "Multiplatform" Shortcuts + Delete "$DESKTOP\OBS Multiplatform.lnk" + Delete "$SMPROGRAMS\OBS Multiplatform\OBS Multiplatform (32bit).lnk" + Delete "$SMPROGRAMS\OBS Multiplatform\Uninstall.lnk" + ${if} ${RunningX64} + Delete "$SMPROGRAMS\OBS Multiplatform\OBS Multiplatform (64bit).lnk" + ${endif} + + SetOutPath "$INSTDIR\bin\32bit" + CreateShortCut "$DESKTOP\OBS Studio.lnk" "$INSTDIR\bin\32bit\obs32.exe" + CreateDirectory "$SMPROGRAMS\OBS Studio" + CreateShortCut "$SMPROGRAMS\OBS Studio\OBS Studio (32bit).lnk" "$INSTDIR\bin\32bit\obs32.exe" + CreateShortCut "$SMPROGRAMS\OBS Studio\Uninstall.lnk" "$INSTDIR\uninstall.exe" + + ${if} ${RunningX64} + SetOutPath "$INSTDIR\bin\64bit" + CreateShortCut "$SMPROGRAMS\OBS Studio\OBS Studio (64bit).lnk" "$INSTDIR\bin\64bit\obs64.exe" + ${endif} + + SetOutPath "$INSTDIR\bin\32bit" + + StrCmp $outputErrors "yes" 0 +2 + Call filesInUse +SectionEnd + +Section -FinishSection + + WriteRegStr HKLM "Software\${APPNAME}" "" "$INSTDIR" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$INSTDIR\uninstall.exe" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "ProductID" "d16d2409-3151-4331-a9b1-dfd8cf3f0d9c" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayIcon" "$INSTDIR\bin\32bit\obs32.exe" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "Publisher" "OBS Project" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "HelpLink" "https://obsproject.com" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayVersion" "${APPVERSION}" + +SectionEnd + +; Modern install component descriptions +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${Section1} "" +!insertmacro MUI_FUNCTION_DESCRIPTION_END + +;Uninstall section +Section "un.obs-studio Program Files" + + SectionIn RO + + ;Remove from registry... + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" + DeleteRegKey HKLM "SOFTWARE\${APPNAME}" + + ; Delete self + Delete "$INSTDIR\uninstall.exe" + + ; Delete Shortcuts + Delete "$DESKTOP\OBS Studio.lnk" + Delete "$SMPROGRAMS\OBS Studio\OBS Studio (32bit).lnk" + Delete "$SMPROGRAMS\OBS Studio\Uninstall.lnk" + ${if} ${RunningX64} + Delete "$SMPROGRAMS\OBS Studio\OBS Studio (64bit).lnk" + ${endif} + + ; Clean up OBS Studio + RMDir /r "$INSTDIR\bin" + RMDir /r "$INSTDIR\data" + RMDir /r "$INSTDIR\obs-plugins" + RMDir "$INSTDIR" + + ; Remove remaining directories + RMDir "$SMPROGRAMS\OBS Studio" + RMDir "$INSTDIR\OBS Studio" +SectionEnd + +Section /o "un.User Settings" Section2 + RMDir /R "$APPDATA\obs-studio" +SectionEnd + +!insertmacro MUI_UNFUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${Section1} "Remove the OBS program files." + !insertmacro MUI_DESCRIPTION_TEXT ${Section2} "Removes all settings, plugins, scenes and sources, profiles, log files and other application data." +!insertmacro MUI_UNFUNCTION_DESCRIPTION_END + +; eof diff --git a/obs/obs-app.cpp b/obs/obs-app.cpp index 663c62a..0422027 100644 --- a/obs/obs-app.cpp +++ b/obs/obs-app.cpp @@ -57,6 +57,11 @@ static string currentLogFile; static string lastLogFile; static bool portable_mode = false; +bool opt_start_streaming = false; +bool opt_start_recording = false; +string opt_starting_collection; +string opt_starting_profile; +string opt_starting_scene; QObject *CreateShortcutFilter() { @@ -310,7 +315,7 @@ static void do_log(int log_level, const char *msg, va_list args, void *param) if (log_level <= LOG_INFO) LogStringChunk(logFile, str); -#ifdef _WIN32 +#if defined(_WIN32) && defined(OBS_DEBUGBREAK_ON_ERROR) if (log_level <= LOG_ERROR && IsDebuggerPresent()) __debugbreak(); #endif @@ -339,6 +344,16 @@ bool OBSApp::InitGlobalConfigDefaults() "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); #ifdef __APPLE__ config_set_default_bool(globalConfig, "Video", "DisableOSXVSync", true); @@ -408,6 +423,97 @@ static bool MakeUserProfileDirs() return true; } +static string GetProfileDirFromName(const char *name) +{ + string outputPath; + os_glob_t *glob; + char path[512]; + + if (GetConfigPath(path, sizeof(path), "obs-studio/basic/profiles") <= 0) + return outputPath; + + strcat(path, "/*.*"); + + if (os_glob(path, 0, &glob) != 0) + return outputPath; + + for (size_t i = 0; i < glob->gl_pathc; i++) { + struct os_globent ent = glob->gl_pathv[i]; + if (!ent.directory) + continue; + + strcpy(path, ent.path); + strcat(path, "/basic.ini"); + + ConfigFile config; + if (config.Open(path, CONFIG_OPEN_EXISTING) != 0) + continue; + + const char *curName = config_get_string(config, "General", + "Name"); + if (astrcmpi(curName, name) == 0) { + outputPath = ent.path; + break; + } + } + + os_globfree(glob); + + if (!outputPath.empty()) { + replace(outputPath.begin(), outputPath.end(), '\\', '/'); + const char *start = strrchr(outputPath.c_str(), '/'); + if (start) + outputPath.erase(0, start - outputPath.c_str() + 1); + } + + return outputPath; +} + +static string GetSceneCollectionFileFromName(const char *name) +{ + string outputPath; + os_glob_t *glob; + char path[512]; + + if (GetConfigPath(path, sizeof(path), "obs-studio/basic/scenes") <= 0) + return outputPath; + + strcat(path, "/*.json"); + + if (os_glob(path, 0, &glob) != 0) + return outputPath; + + for (size_t i = 0; i < glob->gl_pathc; i++) { + struct os_globent ent = glob->gl_pathv[i]; + if (ent.directory) + continue; + + obs_data_t *data = + obs_data_create_from_json_file_safe(ent.path, "bak"); + const char *curName = obs_data_get_string(data, "name"); + + if (astrcmpi(name, curName) == 0) { + outputPath = ent.path; + obs_data_release(data); + break; + } + + obs_data_release(data); + } + + os_globfree(glob); + + if (!outputPath.empty()) { + outputPath.resize(outputPath.size() - 5); + replace(outputPath.begin(), outputPath.end(), '\\', '/'); + const char *start = strrchr(outputPath.c_str(), '/'); + if (start) + outputPath.erase(0, start - outputPath.c_str() + 1); + } + + return outputPath; +} + bool OBSApp::InitGlobalConfig() { char path[512]; @@ -424,6 +530,30 @@ bool OBSApp::InitGlobalConfig() return false; } + if (!opt_starting_collection.empty()) { + string path = GetSceneCollectionFileFromName( + 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()); + } + } + + if (!opt_starting_profile.empty()) { + string path = GetProfileDirFromName( + opt_starting_profile.c_str()); + if (!path.empty()) { + config_set_string(globalConfig, "Basic", "Profile", + opt_starting_profile.c_str()); + config_set_string(globalConfig, "Basic", "ProfileDir", + path.c_str()); + } + } + return InitGlobalConfigDefaults(); } @@ -935,6 +1065,84 @@ string GenerateTimeDateFilename(const char *extension, bool noSpace) return string(file); } +string GenerateSpecifiedFilename(const char *extension, bool noSpace, + const char *format) +{ + time_t now = time(0); + struct tm *cur_time; + cur_time = localtime(&now); + + const size_t spec_count = 23; + const char *spec[][2] = { + {"%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", ""}, + }; + + char convert[128] = {}; + string sf = format; + string c; + size_t pos = 0, len; + + while (pos < sf.length()) { + len = 0; + for (size_t i = 0; i < spec_count && len == 0; i++) { + + if (sf.find(spec[i][0], pos) == pos) { + if (strlen(spec[i][1])) + strftime(convert, sizeof(convert), + spec[i][1], cur_time); + else + strftime(convert, sizeof(convert), + spec[i][0], cur_time); + + len = strlen(spec[i][0]); + + c = convert; + if (c.length() && c.find_first_not_of(' ') != + std::string::npos) + sf.replace(pos, len, convert); + } + } + + if (len) + pos += strlen(convert); + else if (!len && sf.at(pos) == '%') + sf.erase(pos,1); + else + pos++; + } + + if (noSpace) + replace(sf.begin(), sf.end(), ' ', '_'); + + sf += '.'; + sf += extension; + + return (sf.length() < 256) ? sf : sf.substr(0, 255); +} + vector> GetLocaleNames() { string path; @@ -1116,6 +1324,7 @@ static void main_crash_handler(const char *format, va_list args, void *param) char *text = new char[MAX_CRASH_REPORT_SIZE]; vsnprintf(text, MAX_CRASH_REPORT_SIZE, format, args); + text[MAX_CRASH_REPORT_SIZE - 1] = 0; delete_oldest_file("obs-studio/crashes"); @@ -1125,7 +1334,8 @@ static void main_crash_handler(const char *format, va_list args, void *param) BPtr path(GetConfigPathPtr(name.c_str())); fstream file; - file.open(path, ios_base::in | ios_base::out | ios_base::trunc); + file.open(path, ios_base::in | ios_base::out | ios_base::trunc | + ios_base::binary); file << text; file.close(); @@ -1273,6 +1483,23 @@ bool GetClosestUnusedFileName(std::string &path, const char *extension) return true; } +bool WindowPositionValid(int x, int y) +{ + vector monitors; + GetMonitors(monitors); + + for (auto &monitor : monitors) { + int br_x = monitor.x + monitor.cx; + int br_y = monitor.y + monitor.cy; + + if (x >= monitor.x && x < br_x && + y >= monitor.y && y < br_y) + return true; + } + + return false; +} + static inline bool arg_is(const char *arg, const char *long_form, const char *short_form) { @@ -1400,6 +1627,51 @@ static bool update_reconnect(ConfigFile &config) return false; } +static void convert_x264_settings(obs_data_t *data) +{ + bool use_bufsize = obs_data_get_bool(data, "use_bufsize"); + + if (use_bufsize) { + int buffer_size = (int)obs_data_get_int(data, "buffer_size"); + if (buffer_size == 0) + obs_data_set_string(data, "rate_control", "CRF"); + } +} + +static void convert_14_2_encoder_setting(const char *encoder, const char *file) +{ + obs_data_t *data = obs_data_create_from_json_file_safe(file, "bak"); + obs_data_item_t *cbr_item = obs_data_item_byname(data, "cbr"); + obs_data_item_t *rc_item = obs_data_item_byname(data, "rate_control"); + bool modified = false; + bool cbr = true; + + if (cbr_item) { + cbr = obs_data_item_get_bool(cbr_item); + obs_data_item_unset_user_value(cbr_item); + + obs_data_set_string(data, "rate_control", cbr ? "CBR" : "VBR"); + + modified = true; + } + + if (!rc_item && astrcmpi(encoder, "obs_x264") == 0) { + if (!cbr_item) + obs_data_set_string(data, "rate_control", "CBR"); + else if (!cbr) + convert_x264_settings(data); + + modified = true; + } + + if (modified) + obs_data_save_json_safe(data, file, "tmp", "bak"); + + obs_data_item_release(&rc_item); + obs_data_item_release(&cbr_item); + obs_data_release(data); +} + static void upgrade_settings(void) { char path[512]; @@ -1417,7 +1689,8 @@ static void upgrade_settings(void) struct os_dirent *ent = os_readdir(dir); while (ent) { - if (ent->directory) { + if (ent->directory && strcmp(ent->d_name, ".") != 0 && + strcmp(ent->d_name, "..") != 0) { strcat(path, "/"); strcat(path, ent->d_name); strcat(path, "/basic.ini"); @@ -1434,6 +1707,28 @@ static void upgrade_settings(void) } } + + if (config) { + 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 */ + path[pathlen] = 0; + strcat(path, "/"); + strcat(path, ent->d_name); + strcat(path, "/recordEncoder.json"); + convert_14_2_encoder_setting(rEnc, path); + + path[pathlen] = 0; + strcat(path, "/"); + strcat(path, ent->d_name); + strcat(path, "/streamEncoder.json"); + convert_14_2_encoder_setting(sEnc, path); + } + path[pathlen] = 0; } @@ -1463,6 +1758,21 @@ int main(int argc, char *argv[]) for (int i = 1; i < argc; i++) { if (arg_is(argv[i], "--portable", "-p")) { portable_mode = true; + + } else if (arg_is(argv[i], "--startstreaming", nullptr)) { + opt_start_streaming = true; + + } else if (arg_is(argv[i], "--startrecording", nullptr)) { + opt_start_recording = true; + + } else if (arg_is(argv[i], "--collection", nullptr)) { + if (++i < argc) opt_starting_collection = argv[i]; + + } else if (arg_is(argv[i], "--profile", nullptr)) { + if (++i < argc) opt_starting_profile = argv[i]; + + } else if (arg_is(argv[i], "--scene", nullptr)) { + if (++i < argc) opt_starting_scene = argv[i]; } } diff --git a/obs/obs-app.hpp b/obs/obs-app.hpp index 5fa2f7c..8eac175 100644 --- a/obs/obs-app.hpp +++ b/obs/obs-app.hpp @@ -34,6 +34,8 @@ std::string CurrentTimeString(); std::string CurrentDateTimeString(); std::string GenerateTimeDateFilename(const char *extension, bool noSpace=false); +std::string GenerateSpecifiedFilename(const char *extension, bool noSpace, + const char *format); QObject *CreateShortcutFilter(); struct BaseLexer { @@ -145,9 +147,15 @@ inline const char *Str(const char *lookup) {return App()->GetString(lookup);} bool GetFileSafeName(const char *name, std::string &file); bool GetClosestUnusedFileName(std::string &path, const char *extension); +bool WindowPositionValid(int x, int y); + static inline int GetProfilePath(char *path, size_t size, const char *file) { OBSMainWindow *window = reinterpret_cast( App()->GetMainWindow()); return window->GetProfilePath(path, size, file); } + +extern bool opt_start_streaming; +extern bool opt_start_recording; +extern std::string opt_starting_scene; diff --git a/obs/remote-text.cpp b/obs/remote-text.cpp index a7fcc5d..b77a802 100644 --- a/obs/remote-text.cpp +++ b/obs/remote-text.cpp @@ -71,6 +71,11 @@ void RemoteTextThread::run() curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &str); +#if LIBCURL_VERSION_NUM >= 0x072400 + // A lot of servers don't yet support ALPN + curl_easy_setopt(curl.get(), CURLOPT_SSL_ENABLE_ALPN, 0); +#endif + if (!postData.empty()) { curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS, postData.c_str()); diff --git a/obs/window-basic-filters.cpp b/obs/window-basic-filters.cpp index d58f968..2eeb437 100644 --- a/obs/window-basic-filters.cpp +++ b/obs/window-basic-filters.cpp @@ -109,7 +109,14 @@ OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_) OBSBasicFilters::DrawPreview, this); }; - connect(ui->preview, &OBSQTDisplay::DisplayCreated, addDrawCallback); + enum obs_source_type type = obs_source_get_type(source); + uint32_t caps = obs_source_get_output_flags(source); + bool drawable_type = type == OBS_SOURCE_TYPE_INPUT || + type == OBS_SOURCE_TYPE_SCENE; + + if (drawable_type && (caps & OBS_SOURCE_VIDEO) != 0) + connect(ui->preview, &OBSQTDisplay::DisplayCreated, + addDrawCallback); } OBSBasicFilters::~OBSBasicFilters() @@ -387,6 +394,9 @@ void OBSBasicFilters::closeEvent(QCloseEvent *event) if (!event->isAccepted()) return; + obs_display_remove_draw_callback (ui->preview->GetDisplay(), + OBSBasicFilters::DrawPreview, this); + main->SaveProject(); } diff --git a/obs/window-basic-interaction.cpp b/obs/window-basic-interaction.cpp index e1585f0..a0265fc 100644 --- a/obs/window-basic-interaction.cpp +++ b/obs/window-basic-interaction.cpp @@ -168,6 +168,9 @@ void OBSBasicInteraction::closeEvent(QCloseEvent *event) width()); config_set_int(App()->GlobalConfig(), "InteractionWindow", "cy", height()); + + obs_display_remove_draw_callback(ui->preview->GetDisplay(), + OBSBasicInteraction::DrawPreview, this); } static int TranslateQtKeyboardEventModifiers(QInputEvent *event, bool mouseEvent) { diff --git a/obs/window-basic-main-outputs.cpp b/obs/window-basic-main-outputs.cpp index 7149df4..8dcd875 100644 --- a/obs/window-basic-main-outputs.cpp +++ b/obs/window-basic-main-outputs.cpp @@ -75,6 +75,36 @@ static void OBSStopRecording(void *data, calldata_t *params) UNUSED_PARAMETER(params); } +static void FindBestFilename(string &strPath, bool noSpace) +{ + int num = 2; + + if (!os_file_exists(strPath.c_str())) + return; + + const char *ext = strrchr(strPath.c_str(), '.'); + if (!ext) + return; + + int extStart = int(ext - strPath.c_str()); + for (;;) { + string testPath = strPath; + string numStr; + + numStr = noSpace ? "_" : " ("; + numStr += to_string(num++); + if (!noSpace) + numStr += ")"; + + testPath.insert(extStart, numStr); + + if (!os_file_exists(testPath.c_str())) { + strPath = testPath; + break; + } + } +} + /* ------------------------------------------------------------------------ */ static bool CreateAACEncoder(OBSEncoder &res, string &id, int bitrate, @@ -123,6 +153,8 @@ struct SimpleOutput : BasicOutputHandler { int CalcCRF(int crf); void UpdateRecordingSettings_x264_crf(int crf); + void UpdateRecordingSettings_qsv11(int crf); + void UpdateRecordingSettings_nvenc(int cqp); void UpdateRecordingSettings(); void UpdateRecordingAudioSettings(); virtual void Update() override; @@ -130,10 +162,12 @@ struct SimpleOutput : BasicOutputHandler { void SetupOutputs(); int GetAudioBitrate() const; - void LoadRecordingPreset_x264(); + void LoadRecordingPreset_h264(const char *encoder); void LoadRecordingPreset_Lossless(); void LoadRecordingPreset(); + void LoadStreamingPreset_h264(const char *encoder); + virtual bool StartStreaming(obs_service_t *service) override; virtual bool StartRecording() override; virtual void StopStreaming() override; @@ -161,17 +195,22 @@ void SimpleOutput::LoadRecordingPreset_Lossless() obs_data_release(settings); } -void SimpleOutput::LoadRecordingPreset_x264() +void SimpleOutput::LoadRecordingPreset_h264(const char *encoderId) { - h264Recording = obs_video_encoder_create("obs_x264", + 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); +} - if (!CreateAACEncoder(aacRecording, aacRecEncID, 192, - "simple_aac_recording", 0)) - throw "Failed to create aac recording encoder (simple output)"; +void SimpleOutput::LoadStreamingPreset_h264(const char *encoderId) +{ + 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); } void SimpleOutput::LoadRecordingPreset() @@ -198,9 +237,24 @@ void SimpleOutput::LoadRecordingPreset() return; } else { - lowCPUx264 = strcmp(encoder, SIMPLE_ENCODER_X264_LOWCPU) == 0; - LoadRecordingPreset_x264(); + lowCPUx264 = false; + + if (strcmp(encoder, SIMPLE_ENCODER_X264) == 0) { + LoadRecordingPreset_h264("obs_x264"); + } else if (strcmp(encoder, SIMPLE_ENCODER_X264_LOWCPU) == 0) { + LoadRecordingPreset_h264("obs_x264"); + lowCPUx264 = true; + } else if (strcmp(encoder, SIMPLE_ENCODER_QSV) == 0) { + LoadRecordingPreset_h264("obs_qsv11"); + } else if (strcmp(encoder, SIMPLE_ENCODER_NVENC) == 0) { + LoadRecordingPreset_h264("ffmpeg_nvenc"); + } usingRecordingPreset = true; + + if (!CreateAACEncoder(aacRecording, aacRecEncID, 192, + "simple_aac_recording", 0)) + throw "Failed to create aac recording encoder " + "(simple output)"; } } @@ -212,11 +266,14 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_) throw "Failed to create stream output (simple output)"; obs_output_release(streamOutput); - h264Streaming = obs_video_encoder_create("obs_x264", - "simple_h264_stream", nullptr, nullptr); - if (!h264Streaming) - throw "Failed to create h264 streaming encoder (simple output)"; - obs_encoder_release(h264Streaming); + const char *encoder = config_get_string(main->Config(), "SimpleOutput", + "StreamEncoder"); + if (strcmp(encoder, SIMPLE_ENCODER_QSV) == 0) + LoadStreamingPreset_h264("obs_qsv11"); + else if (strcmp(encoder, SIMPLE_ENCODER_NVENC) == 0) + LoadStreamingPreset_h264("ffmpeg_nvenc"); + else + LoadStreamingPreset_h264("obs_x264"); if (!CreateAACEncoder(aacStreaming, aacStreamEncID, GetAudioBitrate(), "simple_aac", 0)) @@ -267,10 +324,23 @@ void SimpleOutput::Update() int audioBitrate = GetAudioBitrate(); bool advanced = config_get_bool(main->Config(), "SimpleOutput", "UseAdvanced"); - const char *preset = config_get_string(main->Config(), - "SimpleOutput", "Preset"); + bool enforceBitrate = config_get_bool(main->Config(), "SimpleOutput", + "EnforceBitrate"); const char *custom = config_get_string(main->Config(), "SimpleOutput", "x264Settings"); + const char *encoder = config_get_string(main->Config(), "SimpleOutput", + "StreamEncoder"); + const char *presetType; + const char *preset; + + if (strcmp(encoder, SIMPLE_ENCODER_QSV) == 0) + presetType = "QSVPreset"; + else if (strcmp(encoder, SIMPLE_ENCODER_NVENC) == 0) + presetType = "NVENCPreset"; + else + presetType = "Preset"; + + preset = config_get_string(main->Config(), "SimpleOutput", presetType); obs_data_set_int(h264Settings, "bitrate", videoBitrate); @@ -279,12 +349,17 @@ void SimpleOutput::Update() obs_data_set_string(h264Settings, "x264opts", custom); } - obs_data_set_bool(aacSettings, "cbr", true); + obs_data_set_string(aacSettings, "rate_control", "CBR"); obs_data_set_int(aacSettings, "bitrate", audioBitrate); obs_service_apply_encoder_settings(main->GetService(), h264Settings, aacSettings); + if (advanced && !enforceBitrate) { + obs_data_set_int(h264Settings, "bitrate", videoBitrate); + obs_data_set_int(aacSettings, "bitrate", audioBitrate); + } + video_t *video = obs_get_video(); enum video_format format = video_output_get_format(video); @@ -303,7 +378,7 @@ void SimpleOutput::UpdateRecordingAudioSettings() { obs_data_t *settings = obs_data_create(); obs_data_set_int(settings, "bitrate", 192); - obs_data_set_bool(settings, "cbr", true); + obs_data_set_string(settings, "rate_control", "CBR"); obs_encoder_update(aacRecording, settings); @@ -333,11 +408,9 @@ int SimpleOutput::CalcCRF(int crf) void SimpleOutput::UpdateRecordingSettings_x264_crf(int crf) { obs_data_t *settings = obs_data_create(); - obs_data_set_int(settings, "bitrate", 1000); - obs_data_set_int(settings, "buffer_size", 0); obs_data_set_int(settings, "crf", crf); obs_data_set_bool(settings, "use_bufsize", true); - obs_data_set_bool(settings, "cbr", false); + obs_data_set_string(settings, "rate_control", "CRF"); obs_data_set_string(settings, "profile", "high"); obs_data_set_string(settings, "preset", lowCPUx264 ? "ultrafast" : "veryfast"); @@ -347,13 +420,73 @@ void SimpleOutput::UpdateRecordingSettings_x264_crf(int crf) obs_data_release(settings); } +static bool icq_available(obs_encoder_t *encoder) +{ + obs_properties_t *props = obs_encoder_properties(encoder); + obs_property_t *p = obs_properties_get(props, "rate_control"); + bool icq_found = false; + + size_t num = obs_property_list_item_count(p); + for (size_t i = 0; i < num; i++) { + const char *val = obs_property_list_item_string(p, i); + if (strcmp(val, "ICQ") == 0) { + icq_found = true; + break; + } + } + + obs_properties_destroy(props); + return icq_found; +} + +void SimpleOutput::UpdateRecordingSettings_qsv11(int crf) +{ + bool icq = icq_available(h264Recording); + + obs_data_t *settings = obs_data_create(); + obs_data_set_string(settings, "profile", "high"); + + if (icq) { + obs_data_set_string(settings, "rate_control", "ICQ"); + obs_data_set_int(settings, "icq_quality", crf); + } else { + obs_data_set_string(settings, "rate_control", "CQP"); + obs_data_set_int(settings, "qpi", crf); + obs_data_set_int(settings, "qpp", crf); + obs_data_set_int(settings, "qpb", crf); + } + + obs_encoder_update(h264Recording, settings); + + obs_data_release(settings); +} + +void SimpleOutput::UpdateRecordingSettings_nvenc(int cqp) +{ + obs_data_t *settings = obs_data_create(); + obs_data_set_string(settings, "rate_control", "CQP"); + obs_data_set_string(settings, "profile", "high"); + obs_data_set_string(settings, "preset", "hq"); + obs_data_set_int(settings, "cqp", cqp); + + obs_encoder_update(h264Recording, settings); + + obs_data_release(settings); +} + void SimpleOutput::UpdateRecordingSettings() { + bool ultra_hq = (videoQuality == "HQ"); + int crf = CalcCRF(ultra_hq ? 16 : 23); + if (astrcmp_n(videoEncoder.c_str(), "x264", 4) == 0) { - if (videoQuality == "Small") - UpdateRecordingSettings_x264_crf(CalcCRF(23)); - else if (videoQuality == "HQ") - UpdateRecordingSettings_x264_crf(CalcCRF(16)); + UpdateRecordingSettings_x264_crf(crf); + + } else if (videoEncoder == SIMPLE_ENCODER_QSV) { + UpdateRecordingSettings_qsv11(crf); + + } else if (videoEncoder == SIMPLE_ENCODER_NVENC) { + UpdateRecordingSettings_nvenc(crf); } } @@ -431,6 +564,10 @@ bool SimpleOutput::StartRecording() "MuxerCustom"); bool noSpace = config_get_bool(main->Config(), "SimpleOutput", "FileNameWithoutSpace"); + const char *filenameFormat = config_get_string(main->Config(), "Output", + "FilenameFormatting"); + bool overwriteIfExists = config_get_bool(main->Config(), "Output", + "OverwriteIfExists"); os_dir_t *dir = path ? os_opendir(path) : nullptr; @@ -450,8 +587,10 @@ bool SimpleOutput::StartRecording() if (lastChar != '/' && lastChar != '\\') strPath += "/"; - strPath += GenerateTimeDateFilename(ffmpegOutput ? "avi" : format, - noSpace); + strPath += GenerateSpecifiedFilename(ffmpegOutput ? "avi" : format, + noSpace, filenameFormat); + if (!overwriteIfExists) + FindBestFilename(strPath, noSpace); SetupOutputs(); @@ -932,8 +1071,10 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service) bool AdvancedOutput::StartRecording() { const char *path; - const char *format; + const char *recFormat; + const char *filenameFormat; bool noSpace = false; + bool overwriteIfExists = false; if (!useStreamEncoder) { if (!ffmpegOutput) { @@ -951,8 +1092,12 @@ bool AdvancedOutput::StartRecording() if (!ffmpegOutput || ffmpegRecording) { path = config_get_string(main->Config(), "AdvOut", ffmpegRecording ? "FFFilePath" : "RecFilePath"); - format = config_get_string(main->Config(), "AdvOut", + recFormat = config_get_string(main->Config(), "AdvOut", ffmpegRecording ? "FFExtension" : "RecFormat"); + filenameFormat = config_get_string(main->Config(), "Output", + "FilenameFormatting"); + overwriteIfExists = config_get_bool(main->Config(), "Output", + "OverwriteIfExists"); noSpace = config_get_bool(main->Config(), "AdvOut", ffmpegRecording ? "FFFileNameWithoutSpace" : @@ -976,7 +1121,10 @@ bool AdvancedOutput::StartRecording() if (lastChar != '/' && lastChar != '\\') strPath += "/"; - strPath += GenerateTimeDateFilename(format, noSpace); + strPath += GenerateSpecifiedFilename(recFormat, noSpace, + filenameFormat); + if (!overwriteIfExists) + FindBestFilename(strPath, noSpace); obs_data_t *settings = obs_data_create(); obs_data_set_string(settings, diff --git a/obs/window-basic-main-scene-collections.cpp b/obs/window-basic-main-scene-collections.cpp index 710a163..b3ec515 100644 --- a/obs/window-basic-main-scene-collections.cpp +++ b/obs/window-basic-main-scene-collections.cpp @@ -255,6 +255,8 @@ void OBSBasic::on_actionRenameSceneCollection_triggered() oldFile.insert(0, path); oldFile += ".json"; os_unlink(oldFile.c_str()); + oldFile += ".bak"; + os_unlink(oldFile.c_str()); blog(LOG_INFO, "------------------------------------------------"); blog(LOG_INFO, "Renamed scene collection to '%s' (%s.json)", diff --git a/obs/window-basic-main-transitions.cpp b/obs/window-basic-main-transitions.cpp index 3d5f86d..212b316 100644 --- a/obs/window-basic-main-transitions.cpp +++ b/obs/window-basic-main-transitions.cpp @@ -18,9 +18,11 @@ #include #include #include +#include #include #include "window-basic-main.hpp" #include "display-helpers.hpp" +#include "window-namedialog.hpp" #include "menu-button.hpp" #include "qt-wrappers.hpp" @@ -162,14 +164,18 @@ void OBSBasic::LoadQuickTransitions(obs_data_array_t *array) if (id) { obs_source_t *source = FindTransition(name); - quickTransitions.emplace_back(source, duration, id); + if (source) { + quickTransitions.emplace_back(source, duration, + id); - if (quickTransitionIdCounter <= id) - quickTransitionIdCounter = id + 1; + if (quickTransitionIdCounter <= id) + quickTransitionIdCounter = id + 1; - int idx = (int)quickTransitions.size() - 1; - AddQuickTransitionHotkey(&quickTransitions[idx]); - obs_hotkey_load(quickTransitions[idx].hotkey, hotkeys); + int idx = (int)quickTransitions.size() - 1; + AddQuickTransitionHotkey(&quickTransitions[idx]); + obs_hotkey_load(quickTransitions[idx].hotkey, + hotkeys); + } } obs_data_release(data); @@ -297,9 +303,6 @@ void OBSBasic::SetTransition(obs_source_t *transition) SetComboTransition(ui->transitions, transition); obs_set_output_source(0, transition); obs_transition_swap_end(transition, oldTransition); - - bool showPropertiesButton = obs_source_configurable(transition); - ui->transitionProps->setVisible(showPropertiesButton); } else { obs_set_output_source(0, transition); } @@ -310,6 +313,10 @@ void OBSBasic::SetTransition(obs_source_t *transition) bool fixed = transition ? obs_transition_fixed(transition) : false; ui->transitionDurationLabel->setVisible(!fixed); ui->transitionDuration->setVisible(!fixed); + + bool configurable = obs_source_configurable(transition); + ui->transitionRemove->setEnabled(configurable); + ui->transitionProps->setEnabled(configurable); } OBSSource OBSBasic::GetCurrentTransition() @@ -323,9 +330,170 @@ void OBSBasic::on_transitions_currentIndexChanged(int) SetTransition(transition); } +void OBSBasic::AddTransition() +{ + 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 format = placeHolderText + " (%1)"; + obs_source_t *source = nullptr; + int i = 1; + + while ((source = FindTransition(QT_TO_UTF8(placeHolderText)))) { + placeHolderText = format.arg(++i); + } + + bool accepted = NameDialog::AskForName(this, + QTStr("TransitionNameDlg.Title"), + QTStr("TransitionNameDlg.Text"), + name, placeHolderText); + + if (accepted) { + if (name.empty()) { + QMessageBox::information(this, + QTStr("NoNameEntered.Title"), + QTStr("NoNameEntered.Text")); + AddTransition(); + return; + } + + source = FindTransition(name.c_str()); + if (source) { + QMessageBox::information(this, + QTStr("NameExists.Title"), + QTStr("NameExists.Text")); + + AddTransition(); + return; + } + + source = obs_source_create_private(QT_TO_UTF8(idStr), + name.c_str(), NULL); + InitTransition(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); + } +} + +void OBSBasic::on_transitionAdd_clicked() +{ + bool foundConfigurableTransitions = false; + QMenu menu(this); + size_t idx = 0; + const char *id; + + while (obs_enum_transition_types(idx++, &id)) { + if (obs_is_source_configurable(id)) { + const char *name = obs_source_get_display_name(id); + QAction *action = new QAction(name, this); + action->setProperty("id", id); + + connect(action, SIGNAL(triggered()), + this, SLOT(AddTransition())); + + menu.addAction(action); + foundConfigurableTransitions = true; + } + } + + if (foundConfigurableTransitions) + menu.exec(QCursor::pos()); +} + +void OBSBasic::on_transitionRemove_clicked() +{ + OBSSource tr = GetCurrentTransition(); + + if (!tr || !obs_source_configurable(tr) || !QueryRemoveSource(tr)) + return; + + int idx = ui->transitions->findData(QVariant::fromValue(tr)); + if (idx == -1) + return; + + for (size_t i = quickTransitions.size(); i > 0; i--) { + QuickTransition &qt = quickTransitions[i - 1]; + if (qt.source == tr) { + if (qt.button) + qt.button->deleteLater(); + RemoveQuickTransitionHotkey(&qt); + quickTransitions.erase(quickTransitions.begin() + i - 1); + } + } + + ui->transitions->removeItem(idx); +} + +void OBSBasic::RenameTransition() +{ + QAction *action = reinterpret_cast(sender()); + QVariant variant = action->property("transition"); + obs_source_t *transition = variant.value(); + + string name; + QString placeHolderText = QT_UTF8(obs_source_get_name(transition)); + obs_source_t *source = nullptr; + + bool accepted = NameDialog::AskForName(this, + QTStr("TransitionNameDlg.Title"), + QTStr("TransitionNameDlg.Text"), + name, placeHolderText); + + if (accepted) { + if (name.empty()) { + QMessageBox::information(this, + QTStr("NoNameEntered.Title"), + QTStr("NoNameEntered.Text")); + RenameTransition(); + return; + } + + source = FindTransition(name.c_str()); + if (source) { + QMessageBox::information(this, + QTStr("NameExists.Title"), + QTStr("NameExists.Text")); + + RenameTransition(); + return; + } + + 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())); + } +} + void OBSBasic::on_transitionProps_clicked() { - // TODO + OBSSource source = GetCurrentTransition(); + + if (!obs_source_configurable(source)) + return; + + auto properties = [&] () { + CreatePropertiesWindow(source); + }; + + QMenu menu(this); + + QAction *action = new QAction(QTStr("Rename"), &menu); + connect(action, SIGNAL(triggered()), this, SLOT(RenameTransition())); + action->setProperty("transition", QVariant::fromValue(source)); + menu.addAction(action); + + action = new QAction(QTStr("Properties"), &menu); + connect(action, &QAction::triggered, properties); + menu.addAction(action); + + menu.exec(QCursor::pos()); } QuickTransition *OBSBasic::GetQuickTransition(int id) @@ -871,3 +1039,54 @@ void OBSBasic::ResizeProgram(uint32_t cx, uint32_t cy) programX += float(PREVIEW_EDGE_SIZE); programY += float(PREVIEW_EDGE_SIZE); } + +obs_data_array_t *OBSBasic::SaveTransitions() +{ + obs_data_array_t *transitions = obs_data_array_create(); + + for (int i = 0; i < ui->transitions->count(); i++) { + OBSSource tr = ui->transitions->itemData(i).value(); + if (!obs_source_configurable(tr)) + continue; + + 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, "id", obs_obj_get_id(tr)); + obs_data_set_obj(sourceData, "settings", settings); + + obs_data_array_push_back(transitions, sourceData); + + obs_data_release(settings); + obs_data_release(sourceData); + } + + return transitions; +} + +void OBSBasic::LoadTransitions(obs_data_array_t *transitions) +{ + size_t count = obs_data_array_count(transitions); + + for (size_t i = 0; i < count; i++) { + obs_data_t *item = obs_data_array_item(transitions, i); + const char *name = obs_data_get_string(item, "name"); + 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); + if (!obs_obj_invalid(source)) { + InitTransition(source); + ui->transitions->addItem(QT_UTF8(name), + QVariant::fromValue(OBSSource(source))); + ui->transitions->setCurrentIndex( + ui->transitions->count() - 1); + } + + obs_data_release(settings); + obs_data_release(item); + obs_source_release(source); + } +} diff --git a/obs/window-basic-main.cpp b/obs/window-basic-main.cpp index 78d8954..20eb765 100644 --- a/obs/window-basic-main.cpp +++ b/obs/window-basic-main.cpp @@ -132,6 +132,9 @@ OBSBasic::OBSBasic(QWidget *parent) int posy = config_get_int(App()->GlobalConfig(), "BasicWindow", "posy"); + if (!WindowPositionValid(posx, posy)) + posx = posy = 0; + setGeometry(posx, posy, width, height); } @@ -247,6 +250,7 @@ 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_t *saveData = obs_data_create(); @@ -287,6 +291,7 @@ static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder, obs_data_set_string(saveData, "name", sceneCollection); obs_data_set_array(saveData, "sources", sourcesArray); obs_data_set_array(saveData, "quick_transitions", quickTransitionData); + obs_data_set_array(saveData, "transitions", transitions); obs_data_array_release(sourcesArray); obs_data_set_string(saveData, "current_transition", @@ -352,9 +357,10 @@ void OBSBasic::Save(const char *file) curProgramScene = obs_scene_get_source(scene); obs_data_array_t *sceneOrder = SaveSceneListOrder(); + obs_data_array_t *transitions = SaveTransitions(); obs_data_array_t *quickTrData = SaveQuickTransitions(); obs_data_t *saveData = GenerateSaveData(sceneOrder, quickTrData, - ui->transitionDuration->value(), + ui->transitionDuration->value(), transitions, scene, curProgramScene); if (!obs_data_save_json_safe(saveData, file, "tmp", "bak")) @@ -363,6 +369,7 @@ void OBSBasic::Save(const char *file) obs_data_release(saveData); obs_data_array_release(sceneOrder); obs_data_array_release(quickTrData); + obs_data_array_release(transitions); } static void LoadAudioDevice(const char *name, int channel, obs_data_t *parent) @@ -488,6 +495,7 @@ void OBSBasic::Load(const char *file) 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 *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, @@ -495,6 +503,12 @@ void OBSBasic::Load(const char *file) const char *transitionName = obs_data_get_string(data, "current_transition"); + if (!opt_starting_scene.empty()) { + programSceneName = opt_starting_scene.c_str(); + if (!IsPreviewProgramMode()) + sceneName = opt_starting_scene.c_str(); + } + int newDuration = obs_data_get_int(data, "transition_duration"); if (!newDuration) newDuration = 300; @@ -521,11 +535,15 @@ void OBSBasic::Load(const char *file) LoadAudioDevice(AUX_AUDIO_2, 4, data); LoadAudioDevice(AUX_AUDIO_3, 5, data); - obs_load_sources(sources); + obs_load_sources(sources, OBSBasic::SourceLoaded, this); + if (transitions) + LoadTransitions(transitions); if (sceneOrder) LoadSceneListOrder(sceneOrder); + obs_data_array_release(transitions); + curTransition = FindTransition(transitionName); if (!curTransition) curTransition = fadeTransition; @@ -533,8 +551,22 @@ void OBSBasic::Load(const char *file) ui->transitionDuration->setValue(newDuration); SetTransition(curTransition); +retryScene: curScene = obs_get_source_by_name(sceneName); curProgramScene = obs_get_source_by_name(programSceneName); + + /* if the starting scene command line parameter is bad at all, + * 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"); + obs_source_release(curScene); + obs_source_release(curProgramScene); + opt_starting_scene.clear(); + goto retryScene; + } + if (!curProgramScene) { curProgramScene = curScene; obs_source_addref(curScene); @@ -566,6 +598,21 @@ void OBSBasic::Load(const char *file) obs_data_release(data); + if (!opt_starting_scene.empty()) + opt_starting_scene.clear(); + + if (opt_start_streaming) { + QMetaObject::invokeMethod(this, "StartStreaming", + Qt::QueuedConnection); + opt_start_streaming = false; + } + + if (opt_start_recording) { + QMetaObject::invokeMethod(this, "StartRecording", + Qt::QueuedConnection); + opt_start_recording = false; + } + disableSaving--; } @@ -694,9 +741,13 @@ bool OBSBasic::InitBasicConfigDefaults() "flv"); config_set_default_uint (basicConfig, "SimpleOutput", "VBitrate", 2500); + config_set_default_string(basicConfig, "SimpleOutput", "StreamEncoder", + SIMPLE_ENCODER_X264); 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"); config_set_default_string(basicConfig, "SimpleOutput", "RecQuality", @@ -740,6 +791,9 @@ bool OBSBasic::InitBasicConfigDefaults() config_set_default_uint (basicConfig, "Video", "BaseCX", cx); config_set_default_uint (basicConfig, "Video", "BaseCY", cy); + config_set_default_string(basicConfig, "Output", "FilenameFormatting", + "%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); @@ -826,8 +880,6 @@ void OBSBasic::InitOBSCallbacks() ProfileScope("OBSBasic::InitOBSCallbacks"); signalHandlers.reserve(signalHandlers.size() + 6); - signalHandlers.emplace_back(obs_get_signal_handler(), "source_load", - OBSBasic::SourceLoaded, this); signalHandlers.emplace_back(obs_get_signal_handler(), "source_remove", OBSBasic::SourceRemoved, this); signalHandlers.emplace_back(obs_get_signal_handler(), "source_activate", @@ -852,6 +904,26 @@ void OBSBasic::InitPrimitives() gs_vertex2f(0.0f, 0.0f); box = gs_render_save(); + gs_render_start(true); + gs_vertex2f(0.0f, 0.0f); + gs_vertex2f(0.0f, 1.0f); + boxLeft = gs_render_save(); + + gs_render_start(true); + gs_vertex2f(0.0f, 0.0f); + gs_vertex2f(1.0f, 0.0f); + boxTop = gs_render_save(); + + gs_render_start(true); + gs_vertex2f(1.0f, 0.0f); + gs_vertex2f(1.0f, 1.0f); + boxRight = gs_render_save(); + + gs_render_start(true); + gs_vertex2f(0.0f, 1.0f); + gs_vertex2f(1.0f, 1.0f); + boxBottom = gs_render_save(); + gs_render_start(true); for (int i = 0; i <= 360; i += (360/20)) { float pos = RAD(float(i)); @@ -1269,6 +1341,10 @@ OBSBasic::~OBSBasic() obs_enter_graphics(); gs_vertexbuffer_destroy(box); + gs_vertexbuffer_destroy(boxLeft); + gs_vertexbuffer_destroy(boxTop); + gs_vertexbuffer_destroy(boxRight); + gs_vertexbuffer_destroy(boxBottom); gs_vertexbuffer_destroy(circle); obs_leave_graphics(); @@ -2022,10 +2098,9 @@ void OBSBasic::SceneItemDeselected(void *data, calldata_t *params) Q_ARG(bool, false)); } -void OBSBasic::SourceLoaded(void *data, calldata_t *params) +void OBSBasic::SourceLoaded(void *data, obs_source_t *source) { OBSBasic *window = static_cast(data); - obs_source_t *source = (obs_source_t*)calldata_ptr(params, "source"); if (obs_scene_from_source(source) != NULL) QMetaObject::invokeMethod(window, @@ -2741,6 +2816,71 @@ void OBSBasic::EditSceneItemName() item->setFlags(flags); } +void OBSBasic::SetDeinterlacingMode() +{ + QAction *action = reinterpret_cast(sender()); + obs_deinterlace_mode mode = + (obs_deinterlace_mode)action->property("mode").toInt(); + OBSSceneItem sceneItem = GetCurrentSceneItem(); + obs_source_t *source = obs_sceneitem_get_source(sceneItem); + + obs_source_set_deinterlace_mode(source, mode); +} + +void OBSBasic::SetDeinterlacingOrder() +{ + QAction *action = reinterpret_cast(sender()); + obs_deinterlace_field_order order = + (obs_deinterlace_field_order)action->property("order").toInt(); + OBSSceneItem sceneItem = GetCurrentSceneItem(); + obs_source_t *source = obs_sceneitem_get_source(sceneItem); + + obs_source_set_deinterlace_field_order(source, order); +} + +QMenu *OBSBasic::AddDeinterlacingMenu(obs_source_t *source) +{ + QMenu *menu = new QMenu(QTStr("Deinterlacing")); + obs_deinterlace_mode deinterlaceMode = + obs_source_get_deinterlace_mode(source); + obs_deinterlace_field_order deinterlaceOrder = + 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); \ + 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("Deinterlacing.Linear2x", OBS_DEINTERLACE_MODE_LINEAR_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) \ + action = menu->addAction(QTStr("Deinterlacing." name), this, \ + SLOT(SetDeinterlacingOrder())); \ + action->setProperty("order", (int)order); \ + action->setCheckable(true); \ + action->setChecked(deinterlaceOrder == order); + + ADD_ORDER("TopFieldFirst", OBS_DEINTERLACE_FIELD_ORDER_TOP); + ADD_ORDER("BottomFieldFirst", OBS_DEINTERLACE_FIELD_ORDER_BOTTOM); +#undef ADD_ORDER + + return menu; +} + void OBSBasic::CreateSourcePopupMenu(QListWidgetItem *item, bool preview) { QMenu popup(this); @@ -2776,6 +2916,9 @@ void OBSBasic::CreateSourcePopupMenu(QListWidgetItem *item, bool preview) OBSSceneItem sceneItem = GetSceneItem(item); 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; QAction *action; popup.addAction(QTStr("Rename"), this, @@ -2792,6 +2935,10 @@ void OBSBasic::CreateSourcePopupMenu(QListWidgetItem *item, bool preview) SLOT(OpenSourceProjector())); popup.addSeparator(); + if (isAsyncVideo) { + popup.addMenu(AddDeinterlacingMenu(source)); + popup.addSeparator(); + } popup.addMenu(sourceProjector); popup.addSeparator(); @@ -3609,6 +3756,8 @@ void OBSBasic::on_actionResetTransform_triggered() if (!obs_sceneitem_selected(item)) return true; + obs_sceneitem_defer_update_begin(item); + obs_transform_info info; vec2_set(&info.pos, 0.0f, 0.0f); vec2_set(&info.scale, 1.0f, 1.0f); @@ -3619,6 +3768,11 @@ void OBSBasic::on_actionResetTransform_triggered() vec2_set(&info.bounds, 0.0f, 0.0f); obs_sceneitem_set_info(item, &info); + obs_sceneitem_crop crop = {}; + obs_sceneitem_set_crop(item, &crop); + + obs_sceneitem_defer_update_end(item); + UNUSED_PARAMETER(scene); UNUSED_PARAMETER(param); return true; @@ -3884,7 +4038,7 @@ void OBSBasic::OpenProjector(obs_source_t *source, int monitor) delete projectors[monitor]; projectors[monitor].clear(); - OBSProjector *projector = new OBSProjector(this, source); + OBSProjector *projector = new OBSProjector(nullptr, source); projector->Init(monitor); projectors[monitor] = projector; diff --git a/obs/window-basic-main.hpp b/obs/window-basic-main.hpp index 8dc6468..f75feb5 100644 --- a/obs/window-basic-main.hpp +++ b/obs/window-basic-main.hpp @@ -49,6 +49,8 @@ class QNetworkReply; #define SIMPLE_ENCODER_X264 "x264" #define SIMPLE_ENCODER_X264_LOWCPU "x264_lowcpu" +#define SIMPLE_ENCODER_QSV "qsv" +#define SIMPLE_ENCODER_NVENC "nvenc" #define PREVIEW_EDGE_SIZE 10 @@ -113,6 +115,10 @@ private: std::unique_ptr outputHandler; gs_vertbuffer_t *box = nullptr; + gs_vertbuffer_t *boxLeft = nullptr; + gs_vertbuffer_t *boxTop = nullptr; + gs_vertbuffer_t *boxRight = nullptr; + gs_vertbuffer_t *boxBottom = nullptr; gs_vertbuffer_t *circle = nullptr; bool sceneChanging = false; @@ -220,6 +226,8 @@ private: obs_source_t *FindTransition(const char *name); void SetTransition(obs_source_t *transition); OBSSource GetCurrentTransition(); + obs_data_array_t *SaveTransitions(); + void LoadTransitions(obs_data_array_t *transitions); obs_source_t *fadeTransition; @@ -314,10 +322,15 @@ private slots: void ProcessHotkey(obs_hotkey_id id, bool pressed); + void AddTransition(); + void RenameTransition(); void TransitionClicked(); void TransitionStopped(); void TriggerQuickTransition(int id); + void SetDeinterlacingMode(); + void SetDeinterlacingOrder(); + private: /* OBS Callbacks */ static void SceneReordered(void *data, calldata_t *params); @@ -325,7 +338,7 @@ private: static void SceneItemRemoved(void *data, calldata_t *params); static void SceneItemSelected(void *data, calldata_t *params); static void SceneItemDeselected(void *data, calldata_t *params); - static void SourceLoaded(void *data, calldata_t *params); + static void SourceLoaded(void *data, obs_source_t *source); static void SourceRemoved(void *data, calldata_t *params); static void SourceActivated(void *data, calldata_t *params); static void SourceDeactivated(void *data, calldata_t *params); @@ -384,6 +397,7 @@ public: void ReorderSceneItem(obs_sceneitem_t *item, size_t idx); + QMenu *AddDeinterlacingMenu(obs_source_t *source); void CreateSourcePopupMenu(QListWidgetItem *item, bool preview); void UpdateTitleBar(); @@ -465,6 +479,8 @@ private slots: void on_actionAlwaysOnTop_triggered(); void on_transitions_currentIndexChanged(int index); + void on_transitionAdd_clicked(); + void on_transitionRemove_clicked(); void on_transitionProps_clicked(); void on_modeSwitch_clicked(); diff --git a/obs/window-basic-preview.cpp b/obs/window-basic-preview.cpp index 3f92a31..8e7725c 100644 --- a/obs/window-basic-preview.cpp +++ b/obs/window-basic-preview.cpp @@ -11,7 +11,6 @@ #define HANDLE_RADIUS 4.0f #define HANDLE_SEL_RADIUS (HANDLE_RADIUS * 1.5f) -#define CLAMP_DISTANCE 10.0f /* TODO: make C++ math classes and clean up code here later */ @@ -133,7 +132,7 @@ static inline vec2 GetOBSScreenSize() return size; } -vec3 OBSBasicPreview::GetScreenSnapOffset(const vec3 &tl, const vec3 &br) +vec3 OBSBasicPreview::GetSnapOffset(const vec3 &tl, const vec3 &br) { OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); vec2 screenSize = GetOBSScreenSize(); @@ -141,19 +140,50 @@ vec3 OBSBasicPreview::GetScreenSnapOffset(const vec3 &tl, const vec3 &br) vec3_zero(&clampOffset); - const float clampDist = CLAMP_DISTANCE / main->previewScale; + const bool snap = config_get_bool(GetGlobalConfig(), + "BasicWindow", "SnappingEnabled"); + if (snap == false) + return clampOffset; - if (fabsf(tl.x) < clampDist) + 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; + 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) clampOffset.x = -tl.x; - if (fabsf(clampOffset.x) < EPSILON && + // Right screen edge. + 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 && + fabsf(screenSize.x / 2.0f - centerX) < clampDist) + clampOffset.x = screenSize.x / 2.0f - centerX; - if (fabsf(tl.y) < clampDist) + // Top screen edge. + if (screenSnap && + fabsf(tl.y) < clampDist) clampOffset.y = -tl.y; - if (fabsf(clampOffset.y) < EPSILON && + // Bottom screen edge. + 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 && + fabsf(screenSize.y / 2.0f - centerY) < clampDist) + clampOffset.y = screenSize.y / 2.0f - centerY; return clampOffset; } @@ -284,11 +314,15 @@ static vec2 GetItemSize(obs_sceneitem_t *item) obs_sceneitem_get_bounds(item, &size); } else { obs_source_t *source = obs_sceneitem_get_source(item); + obs_sceneitem_crop crop; vec2 scale; obs_sceneitem_get_scale(item, &scale); - size.x = float(obs_source_get_width(source)) * scale.x; - size.y = float(obs_source_get_height(source)) * scale.y; + 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; } return size; @@ -331,6 +365,15 @@ void OBSBasicPreview::GetStretchHandleData(const vec2 &pos) -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); + cropSize.y = float(obs_source_get_height(source) - + startCrop.top - startCrop.bottom); } } @@ -340,6 +383,8 @@ void OBSBasicPreview::mousePressEvent(QMouseEvent *event) float pixelRatio = main->devicePixelRatio(); float x = float(event->x()) - main->previewX / pixelRatio; float y = float(event->y()) - main->previewY / pixelRatio; + Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers(); + bool altDown = (modifiers & Qt::AltModifier); OBSQTDisplay::mousePressEvent(event); @@ -350,6 +395,9 @@ void OBSBasicPreview::mousePressEvent(QMouseEvent *event) if (event->button() == Qt::LeftButton) mouseDown = true; + if (altDown) + cropping = true; + vec2_set(&startPos, x, y); GetStretchHandleData(startPos); @@ -412,6 +460,7 @@ void OBSBasicPreview::mouseReleaseEvent(QMouseEvent *event) stretchItem = nullptr; mouseDown = false; mouseMoved = false; + cropping = false; } } @@ -453,6 +502,66 @@ static bool AddItemBounds(obs_scene_t *scene, obs_sceneitem_t *item, return true; } +struct OffsetData { + float clampDist; + vec3 tl, br, offset; +}; + +static bool GetSourceSnapOffset(obs_scene_t *scene, obs_sceneitem_t *item, + void *param) +{ + OffsetData *data = reinterpret_cast(param); + + if (obs_sceneitem_selected(item)) + return true; + + 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) + }; + + bool first = true; + vec3 tl, br; + vec3_zero(&tl); + vec3_zero(&br); + for (const vec3 &v : t) { + if (first) { + vec3_copy(&tl, &v); + vec3_copy(&br, &v); + first = false; + } else { + vec3_min(&tl, &tl, &v); + vec3_max(&br, &br, &v); + } + } + + // 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; \ + } while (false) + + EDGE_SNAP(tl, br, x, y); + EDGE_SNAP(tl, br, y, x); + EDGE_SNAP(br, tl, x, y); + EDGE_SNAP(br, tl, y, x); +#undef EDGE_SNAP + + UNUSED_PARAMETER(scene); + return true; +} + void OBSBasicPreview::SnapItemMovement(vec2 &offset) { OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); @@ -466,9 +575,39 @@ void OBSBasicPreview::SnapItemMovement(vec2 &offset) data.br.x += offset.x; data.br.y += offset.y; - vec3 snapOffset = GetScreenSnapOffset(data.tl, data.br); - offset.x += snapOffset.x; - offset.y += snapOffset.y; + 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"); + if (snap == false) + return; + if (sourcesSnap == false) { + offset.x += snapOffset.x; + offset.y += snapOffset.y; + return; + } + + const float clampDist = config_get_double(GetGlobalConfig(), + "BasicWindow", "SnapDistance") / main->previewScale; + + OffsetData offsetData; + offsetData.clampDist = clampDist; + offsetData.tl = data.tl; + offsetData.br = data.br; + vec3_copy(&offsetData.offset, &snapOffset); + + obs_scene_enum_items(scene, GetSourceSnapOffset, &offsetData); + + if (fabsf(offsetData.offset.x) > EPSILON || + fabsf(offsetData.offset.y) > EPSILON) { + offset.x += offsetData.offset.x; + offset.y += offsetData.offset.y; + } else { + offset.x += snapOffset.x; + offset.y += snapOffset.y; + } } static bool move_items(obs_scene_t *scene, obs_sceneitem_t *item, void *param) @@ -587,7 +726,7 @@ void OBSBasicPreview::SnapStretchingToScreen(vec3 &tl, vec3 &br) vec3_max(&boundingBR, &boundingBR, &newBL); vec3_max(&boundingBR, &boundingBR, &newBR); - vec3 offset = GetScreenSnapOffset(boundingTL, boundingBR); + vec3 offset = GetSnapOffset(boundingTL, boundingBR); vec3_add(&offset, &offset, &newTL); vec3_transform(&offset, &offset, &screenToItem); vec3_sub(&offset, &offset, &tl); @@ -603,6 +742,134 @@ void OBSBasicPreview::SnapStretchingToScreen(vec3 &tl, vec3 &br) br.y += offset.y; } +static float maxfunc(float x, float y) +{ + return x > y ? x : y; +} + +static float minfunc(float x, float y) +{ + return x < y ? x : y; +} + +void OBSBasicPreview::CropItem(const vec2 &pos) +{ + obs_bounds_type boundsType = obs_sceneitem_get_bounds_type(stretchItem); + uint32_t stretchFlags = (uint32_t)stretchHandle; + uint32_t align = obs_sceneitem_get_alignment(stretchItem); + vec3 tl, br, pos3; + + if (boundsType != OBS_BOUNDS_NONE) /* TODO */ + return; + + vec3_zero(&tl); + vec3_set(&br, stretchItemSize.x, stretchItemSize.y, 0.0f); + + vec3_set(&pos3, pos.x, pos.y, 0.0f); + vec3_transform(&pos3, &pos3, &screenToItem); + + obs_sceneitem_crop crop = startCrop; + vec2 scale; + + obs_sceneitem_get_scale(stretchItem, &scale); + + 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); + + 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; + minmax_func_t max_x = scale.x < 0.0f ? minfunc : maxfunc; + minmax_func_t max_y = scale.y < 0.0f ? minfunc : maxfunc; + + pos3.x = min_x(pos3.x, max_br.x); + pos3.x = max_x(pos3.x, max_tl.x); + pos3.y = min_y(pos3.y, max_br.y); + pos3.y = max_y(pos3.y, max_tl.y); + + if (stretchFlags & ITEM_LEFT) { + float maxX = stretchItemSize.x - (2.0 * scale.x); + pos3.x = tl.x = min_x(pos3.x, maxX); + + } else if (stretchFlags & ITEM_RIGHT) { + float minX = (2.0 * scale.x); + pos3.x = br.x = max_x(pos3.x, minX); + } + + if (stretchFlags & ITEM_TOP) { + float maxY = stretchItemSize.y - (2.0 * scale.y); + pos3.y = tl.y = min_y(pos3.y, maxY); + + } else if (stretchFlags & ITEM_BOTTOM) { + float minY = (2.0 * scale.y); + pos3.y = br.y = max_y(pos3.y, minY); + } + +#define ALIGN_X (ITEM_LEFT|ITEM_RIGHT) +#define ALIGN_Y (ITEM_TOP|ITEM_BOTTOM) + vec3 newPos; + vec3_zero(&newPos); + + uint32_t align_x = (align & ALIGN_X); + uint32_t align_y = (align & ALIGN_Y); + if (align_x == (stretchFlags & ALIGN_X) && align_x != 0) + newPos.x = pos3.x; + else if (align & ITEM_RIGHT) + newPos.x = stretchItemSize.x; + else if (!(align & ITEM_LEFT)) + newPos.x = stretchItemSize.x * 0.5f; + + if (align_y == (stretchFlags & ALIGN_Y) && align_y != 0) + newPos.y = pos3.y; + else if (align & ITEM_BOTTOM) + newPos.y = stretchItemSize.y; + else if (!(align & ITEM_TOP)) + newPos.y = stretchItemSize.y * 0.5f; +#undef ALIGN_X +#undef ALIGN_Y + + crop = startCrop; + + 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)); + + 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)); + + vec3_transform(&newPos, &newPos, &itemToScreen); + newPos.x = std::round(newPos.x); + newPos.y = std::round(newPos.y); + +#if 0 + vec3 curPos; + vec3_zero(&curPos); + obs_sceneitem_get_pos(stretchItem, (vec2*)&curPos); + blog(LOG_DEBUG, "curPos {%d, %d} - newPos {%d, %d}", + int(curPos.x), int(curPos.y), + int(newPos.x), int(newPos.y)); + blog(LOG_DEBUG, "crop {%d, %d, %d, %d}", + crop.left, crop.top, + crop.right, crop.bottom); +#endif + + obs_sceneitem_defer_update_begin(stretchItem); + obs_sceneitem_set_crop(stretchItem, &crop); + obs_sceneitem_set_pos(stretchItem, (vec2*)&newPos); + obs_sceneitem_defer_update_end(stretchItem); +} + void OBSBasicPreview::StretchItem(const vec2 &pos) { Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers(); @@ -651,6 +918,12 @@ void OBSBasicPreview::StretchItem(const vec2 &pos) obs_sceneitem_set_bounds(stretchItem, &size); } else { + obs_sceneitem_crop crop; + obs_sceneitem_get_crop(stretchItem, &crop); + + baseSize.x -= float(crop.left + crop.right); + baseSize.y -= float(crop.top + crop.bottom); + if (!shiftDown) ClampAspect(tl, br, size, baseSize); @@ -680,10 +953,15 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event) pos.x = std::round(pos.x); pos.y = std::round(pos.y); - if (stretchHandle != ItemHandle::None) - StretchItem(pos); - else if (mouseOverItems) + if (stretchHandle != ItemHandle::None) { + if (cropping) + CropItem(pos); + else + StretchItem(pos); + + } else if (mouseOverItems) { MoveItems(pos); + } mouseMoved = true; } @@ -704,6 +982,14 @@ static void DrawCircleAtPos(float x, float y, matrix4 &matrix, gs_matrix_pop(); } +static inline bool crop_enabled(const obs_sceneitem_crop *crop) +{ + return crop->left > 0 || + crop->top > 0 || + crop->right > 0 || + crop->bottom > 0; +} + bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene, obs_sceneitem_t *item, void *param) { @@ -736,6 +1022,9 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene, if (!visible) return true; + obs_transform_info info; + obs_sceneitem_get_info(item, &info); + gs_load_vertexbuffer(main->circle); DrawCircleAtPos(0.0f, 0.0f, boxTransform, main->previewScale); @@ -747,12 +1036,36 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene, DrawCircleAtPos(0.5f, 1.0f, boxTransform, main->previewScale); DrawCircleAtPos(1.0f, 0.5f, boxTransform, main->previewScale); - gs_load_vertexbuffer(main->box); - gs_matrix_push(); gs_matrix_scale3f(main->previewScale, main->previewScale, 1.0f); gs_matrix_mul(&boxTransform); - gs_draw(GS_LINESTRIP, 0, 0); + + obs_sceneitem_crop crop; + obs_sceneitem_get_crop(item, &crop); + + if (info.bounds_type == OBS_BOUNDS_NONE && crop_enabled(&crop)) { + vec4 color; + gs_effect_t *eff = gs_get_effect(); + gs_eparam_t *param = gs_effect_get_param_by_name(eff, "color"); + +#define DRAW_SIDE(side, vb) \ + if (crop.side > 0) \ + vec4_set(&color, 0.0f, 1.0f, 0.0f, 1.0f); \ + else \ + vec4_set(&color, 1.0f, 0.0f, 0.0f, 1.0f); \ + gs_effect_set_vec4(param, &color); \ + gs_load_vertexbuffer(main->vb); \ + gs_draw(GS_LINESTRIP, 0, 0); + + DRAW_SIDE(left, boxLeft); + DRAW_SIDE(top, boxTop); + DRAW_SIDE(right, boxRight); + DRAW_SIDE(bottom, boxBottom); +#undef DRAW_SIDE + } else { + gs_load_vertexbuffer(main->box); + gs_draw(GS_LINESTRIP, 0, 0); + } gs_matrix_pop(); diff --git a/obs/window-basic-preview.hpp b/obs/window-basic-preview.hpp index aaa8bdd..1a25245 100644 --- a/obs/window-basic-preview.hpp +++ b/obs/window-basic-preview.hpp @@ -30,6 +30,9 @@ class OBSBasicPreview : public OBSQTDisplay { Q_OBJECT private: + obs_sceneitem_crop startCrop; + vec2 startItemPos; + vec2 cropSize; OBSSceneItem stretchItem; ItemHandle stretchHandle = ItemHandle::None; vec2 stretchItemSize; @@ -41,6 +44,7 @@ private: bool mouseDown = false; bool mouseMoved = false; bool mouseOverItems = false; + bool cropping = false; static vec2 GetMouseEventPos(QMouseEvent *event); static bool DrawSelectedItem(obs_scene_t *scene, obs_sceneitem_t *item, @@ -52,13 +56,14 @@ private: static void DoSelect(const vec2 &pos); static void DoCtrlSelect(const vec2 &pos); - static vec3 GetScreenSnapOffset(const vec3 &tl, const vec3 &br); + static vec3 GetSnapOffset(const vec3 &tl, const vec3 &br); void GetStretchHandleData(const vec2 &pos); void SnapStretchingToScreen(vec3 &tl, vec3 &br); void ClampAspect(vec3 &tl, vec3 &br, vec2 &size, const vec2 &baseSize); vec3 CalculateStretchPos(const vec3 &tl, const vec3 &br); + void CropItem(const vec2 &pos); void StretchItem(const vec2 &pos); static void SnapItemMovement(vec2 &offset); diff --git a/obs/window-basic-properties.cpp b/obs/window-basic-properties.cpp index 456bf1a..2fad427 100644 --- a/obs/window-basic-properties.cpp +++ b/obs/window-basic-properties.cpp @@ -103,7 +103,14 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_) OBSBasicProperties::DrawPreview, this); }; - connect(preview.data(), &OBSQTDisplay::DisplayCreated, addDrawCallback); + enum obs_source_type type = obs_source_get_type(source); + uint32_t caps = obs_source_get_output_flags(source); + bool drawable_type = type == OBS_SOURCE_TYPE_INPUT || + type == OBS_SOURCE_TYPE_SCENE; + + if (drawable_type && (caps & OBS_SOURCE_VIDEO) != 0) + connect(preview.data(), &OBSQTDisplay::DisplayCreated, + addDrawCallback); } OBSBasicProperties::~OBSBasicProperties() @@ -198,6 +205,9 @@ void OBSBasicProperties::Cleanup() width()); config_set_int(App()->GlobalConfig(), "PropertiesWindow", "cy", height()); + + obs_display_remove_draw_callback(preview->GetDisplay(), + OBSBasicProperties::DrawPreview, this); } void OBSBasicProperties::reject() diff --git a/obs/window-basic-settings.cpp b/obs/window-basic-settings.cpp index b80306a..3fa2dda 100644 --- a/obs/window-basic-settings.cpp +++ b/obs/window-basic-settings.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -136,11 +137,15 @@ static inline void SetComboByName(QComboBox *combo, const char *name) combo->setCurrentIndex(idx); } -static inline void SetComboByValue(QComboBox *combo, const char *name) +static inline bool SetComboByValue(QComboBox *combo, const char *name) { int idx = combo->findData(QT_UTF8(name)); - if (idx != -1) + if (idx != -1) { combo->setCurrentIndex(idx); + return true; + } + + return false; } static inline QString GetComboData(QComboBox *combo) @@ -230,6 +235,7 @@ void OBSBasicSettings::HookWidget(QWidget *widget, const char *signal, #define CBEDIT_CHANGED SIGNAL(editTextChanged(const QString &)) #define CHECK_CHANGED SIGNAL(clicked(bool)) #define SCROLL_CHANGED SIGNAL(valueChanged(int)) +#define DSCROLL_CHANGED SIGNAL(valueChanged(double)) #define GENERAL_CHANGED SLOT(GeneralChanged()) #define STREAM1_CHANGED SLOT(Stream1Changed()) @@ -265,14 +271,21 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) HookWidget(ui->theme, COMBO_CHANGED, GENERAL_CHANGED); HookWidget(ui->warnBeforeStreamStart,CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->warnBeforeStreamStop, CHECK_CHANGED, GENERAL_CHANGED); + HookWidget(ui->snappingEnabled, CHECK_CHANGED, GENERAL_CHANGED); + HookWidget(ui->screenSnapping, CHECK_CHANGED, GENERAL_CHANGED); + HookWidget(ui->centerSnapping, CHECK_CHANGED, GENERAL_CHANGED); + HookWidget(ui->sourceSnapping, CHECK_CHANGED, GENERAL_CHANGED); + HookWidget(ui->snapDistance, DSCROLL_CHANGED,GENERAL_CHANGED); HookWidget(ui->outputMode, COMBO_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->streamType, COMBO_CHANGED, STREAM1_CHANGED); HookWidget(ui->simpleOutputPath, EDIT_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->simpleNoSpace, CHECK_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->simpleOutRecFormat, COMBO_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->simpleOutputVBitrate, SCROLL_CHANGED, OUTPUTS_CHANGED); + HookWidget(ui->simpleOutStrEncoder, COMBO_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->simpleOutputABitrate, COMBO_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->simpleOutAdvanced, CHECK_CHANGED, OUTPUTS_CHANGED); + HookWidget(ui->simpleOutEnforce, CHECK_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->simpleOutPreset, COMBO_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->simpleOutCustom, EDIT_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->simpleOutRecQuality, COMBO_CHANGED, OUTPUTS_CHANGED); @@ -347,6 +360,8 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) HookWidget(ui->colorRange, COMBO_CHANGED, ADV_CHANGED); HookWidget(ui->disableOSXVSync, CHECK_CHANGED, ADV_CHANGED); HookWidget(ui->resetOSXVSync, CHECK_CHANGED, ADV_CHANGED); + HookWidget(ui->filenameFormatting, EDIT_CHANGED, ADV_CHANGED); + HookWidget(ui->overwriteIfExists, CHECK_CHANGED, ADV_CHANGED); HookWidget(ui->streamDelayEnable, CHECK_CHANGED, ADV_CHANGED); HookWidget(ui->streamDelaySec, SCROLL_CHANGED, ADV_CHANGED); HookWidget(ui->streamDelayPreserve, CHECK_CHANGED, ADV_CHANGED); @@ -456,12 +471,28 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) "hotkey_unregister", ReloadHotkeysIgnore, this); FillSimpleRecordingValues(); + FillSimpleStreamingValues(); + connect(ui->simpleOutRecQuality, SIGNAL(currentIndexChanged(int)), this, SLOT(SimpleRecordingQualityChanged())); connect(ui->simpleOutRecQuality, SIGNAL(currentIndexChanged(int)), this, SLOT(SimpleRecordingQualityLosslessWarning(int))); + 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->listWidget, SIGNAL(currentRowChanged(int)), + this, SLOT(SimpleRecordingEncoderChanged())); LoadSettings(false); @@ -553,9 +584,12 @@ void OBSBasicSettings::LoadEncoderTypes() while (obs_enum_encoder_types(idx++, &type)) { const char *name = obs_encoder_get_display_name(type); const char *codec = obs_get_encoder_codec(type); + uint32_t caps = obs_get_encoder_caps(type); if (strcmp(codec, "h264") != 0) continue; + if ((caps & OBS_ENCODER_CAP_DEPRECATED) != 0) + continue; QString qName = QT_UTF8(name); QString qType = QT_UTF8(type); @@ -760,6 +794,27 @@ void OBSBasicSettings::LoadGeneralSettings() LoadLanguageList(); LoadThemeList(); + bool snappingEnabled = config_get_bool(GetGlobalConfig(), + "BasicWindow", "SnappingEnabled"); + ui->snappingEnabled->setChecked(snappingEnabled); + + bool screenSnapping = config_get_bool(GetGlobalConfig(), + "BasicWindow", "ScreenSnapping"); + ui->screenSnapping->setChecked(screenSnapping); + + bool centerSnapping = config_get_bool(GetGlobalConfig(), + "BasicWindow", "CenterSnapping"); + ui->centerSnapping->setChecked(centerSnapping); + + bool sourceSnapping = config_get_bool(GetGlobalConfig(), + "BasicWindow", "SourceSnapping"); + ui->sourceSnapping->setChecked(sourceSnapping); + + double snapDistance = config_get_double(GetGlobalConfig(), + "BasicWindow", "SnapDistance"); + ui->snapDistance->setValue(snapDistance); + + bool warnBeforeStreamStart = config_get_bool(GetGlobalConfig(), "BasicWindow", "WarnBeforeStartingStream"); ui->warnBeforeStreamStart->setChecked(warnBeforeStreamStart); @@ -1070,12 +1125,20 @@ void OBSBasicSettings::LoadSimpleOutputSettings() "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"); + const char *nvPreset = config_get_string(main->Config(), "SimpleOutput", + "NVENCPreset"); const char *custom = config_get_string(main->Config(), "SimpleOutput", "x264Settings"); const char *recQual = config_get_string(main->Config(), "SimpleOutput", @@ -1085,6 +1148,10 @@ void OBSBasicSettings::LoadSimpleOutputSettings() const char *muxCustom = config_get_string(main->Config(), "SimpleOutput", "MuxerCustom"); + curPreset = preset; + curQSVPreset = qsvPreset; + curNVENCPreset = nvPreset; + audioBitrate = FindClosestAvailableAACBitrate(audioBitrate); ui->simpleOutputPath->setText(path); @@ -1098,18 +1165,24 @@ void OBSBasicSettings::LoadSimpleOutputSettings() std::to_string(audioBitrate).c_str()); ui->simpleOutAdvanced->setChecked(advanced); - ui->simpleOutPreset->setCurrentText(preset); + ui->simpleOutEnforce->setChecked(enforceBitrate); ui->simpleOutCustom->setText(custom); idx = ui->simpleOutRecQuality->findData(QString(recQual)); if (idx == -1) idx = 0; ui->simpleOutRecQuality->setCurrentIndex(idx); + idx = ui->simpleOutStrEncoder->findData(QString(streamEnc)); + if (idx == -1) idx = 0; + ui->simpleOutStrEncoder->setCurrentIndex(idx); + idx = ui->simpleOutRecEncoder->findData(QString(recEnc)); if (idx == -1) idx = 0; ui->simpleOutRecEncoder->setCurrentIndex(idx); ui->simpleOutMuxCustom->setText(muxCustom); + + SimpleStreamingEncoderChanged(); } void OBSBasicSettings::LoadAdvOutputStreamingSettings() @@ -1128,6 +1201,14 @@ void OBSBasicSettings::LoadAdvOutputStreamingSettings() ui->advOutRescale->setEnabled(rescale); ui->advOutRescale->setCurrentText(rescaleRes); + QStringList specList = QTStr("FilenameFormatting.completer").split( + QRegularExpression("\n")); + QCompleter *specCompleter = new QCompleter(specList); + specCompleter->setCaseSensitivity(Qt::CaseSensitive); + specCompleter->setFilterMode(Qt::MatchContains); + ui->filenameFormatting->setCompleter(specCompleter); + ui->filenameFormatting->setToolTip(QTStr("FilenameFormatting.TT")); + switch (trackIndex) { case 1: ui->advOutTrack1->setChecked(true); break; case 2: ui->advOutTrack2->setChecked(true); break; @@ -1165,18 +1246,29 @@ OBSPropertiesView *OBSBasicSettings::CreateEncoderPropertyView( void OBSBasicSettings::LoadAdvOutputStreamingEncoderProperties() { - const char *encoder = config_get_string(main->Config(), "AdvOut", + const char *type = config_get_string(main->Config(), "AdvOut", "Encoder"); delete streamEncoderProps; - streamEncoderProps = CreateEncoderPropertyView(encoder, + streamEncoderProps = CreateEncoderPropertyView(type, "streamEncoder.json"); ui->advOutputStreamTab->layout()->addWidget(streamEncoderProps); connect(streamEncoderProps, SIGNAL(Changed()), this, SLOT(UpdateStreamDelayEstimate())); - SetComboByValue(ui->advOutEncoder, encoder); + curAdvStreamEncoder = type; + + if (!SetComboByValue(ui->advOutEncoder, type)) { + uint32_t caps = obs_get_encoder_caps(type); + if ((caps & OBS_ENCODER_CAP_DEPRECATED) != 0) { + const char *name = obs_encoder_get_display_name(type); + + ui->advOutEncoder->insertItem(0, QT_UTF8(name), + QT_UTF8(type)); + SetComboByValue(ui->advOutEncoder, type); + } + } UpdateStreamDelayEstimate(); } @@ -1218,19 +1310,30 @@ void OBSBasicSettings::LoadAdvOutputRecordingSettings() void OBSBasicSettings::LoadAdvOutputRecordingEncoderProperties() { - const char *encoder = config_get_string(main->Config(), "AdvOut", + const char *type = config_get_string(main->Config(), "AdvOut", "RecEncoder"); delete recordEncoderProps; recordEncoderProps = nullptr; - if (astrcmpi(encoder, "none") != 0) { - recordEncoderProps = CreateEncoderPropertyView(encoder, + if (astrcmpi(type, "none") != 0) { + recordEncoderProps = CreateEncoderPropertyView(type, "recordEncoder.json"); ui->advOutRecStandard->layout()->addWidget(recordEncoderProps); } - SetComboByValue(ui->advOutRecEncoder, encoder); + curAdvRecordEncoder = type; + + if (!SetComboByValue(ui->advOutRecEncoder, type)) { + uint32_t caps = obs_get_encoder_caps(type); + if ((caps & OBS_ENCODER_CAP_DEPRECATED) != 0) { + const char *name = obs_encoder_get_display_name(type); + + ui->advOutRecEncoder->insertItem(1, QT_UTF8(name), + QT_UTF8(type)); + SetComboByValue(ui->advOutRecEncoder, type); + } + } } static void SelectFormat(QComboBox *combo, const char *name, @@ -1664,11 +1767,18 @@ void OBSBasicSettings::LoadAdvancedSettings() "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"); loading = true; LoadRendererList(); + ui->filenameFormatting->setText(filename); + ui->overwriteIfExists->setChecked(overwriteIfExists); + ui->reconnectEnable->setChecked(reconnect); ui->reconnectRetryDelay->setValue(retryDelay); ui->reconnectMaxRetries->setValue(maxRetries); @@ -2020,6 +2130,27 @@ void OBSBasicSettings::SaveGeneralSettings() App()->SetTheme(theme); } + if (WidgetChanged(ui->snappingEnabled)) + config_set_bool(GetGlobalConfig(), "BasicWindow", + "SnappingEnabled", + ui->snappingEnabled->isChecked()); + if (WidgetChanged(ui->screenSnapping)) + config_set_bool(GetGlobalConfig(), "BasicWindow", + "ScreenSnapping", + ui->screenSnapping->isChecked()); + if (WidgetChanged(ui->centerSnapping)) + config_set_bool(GetGlobalConfig(), "BasicWindow", + "CenterSnapping", + ui->centerSnapping->isChecked()); + if (WidgetChanged(ui->sourceSnapping)) + config_set_bool(GetGlobalConfig(), "BasicWindow", + "SourceSnapping", + ui->sourceSnapping->isChecked()); + if (WidgetChanged(ui->snapDistance)) + config_set_double(GetGlobalConfig(), "BasicWindow", + "SnapDistance", + ui->snapDistance->value()); + config_set_bool(GetGlobalConfig(), "BasicWindow", "WarnBeforeStartingStream", ui->warnBeforeStreamStart->isChecked()); @@ -2110,6 +2241,8 @@ void OBSBasicSettings::SaveAdvancedSettings() SaveCombo(ui->colorFormat, "Video", "ColorFormat"); SaveCombo(ui->colorSpace, "Video", "ColorSpace"); SaveComboData(ui->colorRange, "Video", "ColorRange"); + SaveEdit(ui->filenameFormatting, "Output", "FilenameFormatting"); + SaveCheckBox(ui->overwriteIfExists, "Output", "OverwriteIfExists"); SaveCheckBox(ui->streamDelayEnable, "Output", "DelayEnable"); SaveSpinBox(ui->streamDelaySec, "Output", "DelaySec"); SaveCheckBox(ui->streamDelayPreserve, "Output", "DelayPreserve"); @@ -2213,18 +2346,32 @@ void OBSBasicSettings::SaveOutputSettings() config_set_string(main->Config(), "Output", "Mode", OutputModeFromIdx(ui->outputMode->currentIndex())); + QString encoder = ui->simpleOutStrEncoder->currentData().toString(); + const char *presetType; + + if (encoder == SIMPLE_ENCODER_QSV) + presetType = "QSVPreset"; + else if (encoder == SIMPLE_ENCODER_NVENC) + presetType = "NVENCPreset"; + else + presetType = "Preset"; + SaveSpinBox(ui->simpleOutputVBitrate, "SimpleOutput", "VBitrate"); + SaveComboData(ui->simpleOutStrEncoder, "SimpleOutput", "StreamEncoder"); SaveCombo(ui->simpleOutputABitrate, "SimpleOutput", "ABitrate"); SaveEdit(ui->simpleOutputPath, "SimpleOutput", "FilePath"); SaveCheckBox(ui->simpleNoSpace, "SimpleOutput", "FileNameWithoutSpace"); SaveCombo(ui->simpleOutRecFormat, "SimpleOutput", "RecFormat"); SaveCheckBox(ui->simpleOutAdvanced, "SimpleOutput", "UseAdvanced"); - SaveCombo(ui->simpleOutPreset, "SimpleOutput", "Preset"); + SaveCheckBox(ui->simpleOutEnforce, "SimpleOutput", "EnforceBitrate"); + SaveComboData(ui->simpleOutPreset, "SimpleOutput", presetType); SaveEdit(ui->simpleOutCustom, "SimpleOutput", "x264Settings"); SaveComboData(ui->simpleOutRecQuality, "SimpleOutput", "RecQuality"); SaveComboData(ui->simpleOutRecEncoder, "SimpleOutput", "RecEncoder"); SaveEdit(ui->simpleOutMuxCustom, "SimpleOutput", "MuxerCustom"); + curAdvStreamEncoder = GetComboData(ui->advOutEncoder); + SaveCheckBox(ui->advOutApplyService, "AdvOut", "ApplyServiceSettings"); SaveComboData(ui->advOutEncoder, "AdvOut", "Encoder"); SaveCheckBox(ui->advOutUseRescale, "AdvOut", "Rescale"); @@ -2236,6 +2383,8 @@ void OBSBasicSettings::SaveOutputSettings() config_set_string(main->Config(), "AdvOut", "RecType", RecTypeFromIdx(ui->advOutRecType->currentIndex())); + curAdvRecordEncoder = GetComboData(ui->advOutRecEncoder); + SaveEdit(ui->advOutRecPath, "AdvOut", "RecFilePath"); SaveCheckBox(ui->advOutNoSpace, "AdvOut", "RecFileNameWithoutSpace"); SaveCombo(ui->advOutRecFormat, "AdvOut", "RecFormat"); @@ -2562,11 +2711,15 @@ void OBSBasicSettings::on_advOutFFPathBrowse_clicked() void OBSBasicSettings::on_advOutEncoder_currentIndexChanged(int idx) { + if (loading) + return; + QString encoder = GetComboData(ui->advOutEncoder); + bool loadSettings = encoder == curAdvStreamEncoder; delete streamEncoderProps; streamEncoderProps = CreateEncoderPropertyView(QT_TO_UTF8(encoder), - "streamEncoder.json", true); + loadSettings ? "streamEncoder.json" : nullptr, true); ui->advOutputStreamTab->layout()->addWidget(streamEncoderProps); UNUSED_PARAMETER(idx); @@ -2574,6 +2727,9 @@ void OBSBasicSettings::on_advOutEncoder_currentIndexChanged(int idx) void OBSBasicSettings::on_advOutRecEncoder_currentIndexChanged(int idx) { + if (loading) + return; + ui->advOutRecUseRescale->setEnabled(idx > 0); ui->advOutRecRescaleContainer->setEnabled(idx > 0); @@ -2582,10 +2738,12 @@ void OBSBasicSettings::on_advOutRecEncoder_currentIndexChanged(int idx) if (idx > 0) { QString encoder = GetComboData(ui->advOutRecEncoder); + bool loadSettings = encoder == curAdvRecordEncoder; recordEncoderProps = CreateEncoderPropertyView( QT_TO_UTF8(encoder), - "recordEncoder.json", true); + loadSettings ? "recordEncoder.json" : nullptr, + true); ui->advOutRecStandard->layout()->addWidget(recordEncoderProps); } } @@ -2690,6 +2848,23 @@ 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("<>:\"/\\|?*"); +#else + size_t invalidLocation = text.toStdString().find_first_of("/"); +#endif + + if (invalidLocation != string::npos) + ui->filenameFormatting->backspace(); +} + void OBSBasicSettings::on_outputResolution_editTextChanged(const QString &text) { if (!loading) @@ -2917,6 +3092,18 @@ void OBSBasicSettings::UpdateStreamDelayEstimate() UpdateAdvOutStreamDelayEstimate(); } +static bool EncoderAvailable(const char *encoder) +{ + const char *val; + int i = 0; + + while (obs_enum_encoder_types(i++, &val)) + if (strcmp(val, encoder) == 0) + return true; + + return false; +} + void OBSBasicSettings::FillSimpleRecordingValues() { #define ADD_QUALITY(str) \ @@ -2937,7 +3124,30 @@ void OBSBasicSettings::FillSimpleRecordingValues() 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)); + if (EncoderAvailable("ffmpeg_nvenc")) + ui->simpleOutRecEncoder->addItem( + ENCODER_STR("Hardware.NVENC"), + QString(SIMPLE_ENCODER_NVENC)); #undef ADD_QUALITY +} + +void OBSBasicSettings::FillSimpleStreamingValues() +{ + 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)); + if (EncoderAvailable("ffmpeg_nvenc")) + ui->simpleOutStrEncoder->addItem( + ENCODER_STR("Hardware.NVENC"), + QString(SIMPLE_ENCODER_NVENC)); #undef ENCODER_STR } @@ -2956,6 +3166,69 @@ void OBSBasicSettings::SimpleRecordingQualityChanged() SimpleRecordingEncoderChanged(); } +void OBSBasicSettings::SimpleStreamingEncoderChanged() +{ + QString encoder = ui->simpleOutStrEncoder->currentData().toString(); + QString preset; + const char *defaultPreset = nullptr; + + ui->simpleOutPreset->clear(); + + if (encoder == SIMPLE_ENCODER_QSV) { + ui->simpleOutPreset->addItem("speed", "speed"); + ui->simpleOutPreset->addItem("balanced", "balanced"); + ui->simpleOutPreset->addItem("quality", "quality"); + + defaultPreset = "balanced"; + preset = curQSVPreset; + + } else if (encoder == SIMPLE_ENCODER_NVENC) { + obs_properties_t *props = + obs_get_encoder_properties("ffmpeg_nvenc"); + + obs_property_t *p = obs_properties_get(props, "preset"); + 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); + + /* bluray is for ideal bluray disc recording settings, + * not streaming */ + if (strcmp(val, "bd") == 0) + continue; + /* lossless should of course not be used to stream */ + if (astrcmp_n(val, "lossless", 8) == 0) + continue; + + ui->simpleOutPreset->addItem(QT_UTF8(name), val); + } + + obs_properties_destroy(props); + + defaultPreset = "default"; + preset = curNVENCPreset; + + } else { + ui->simpleOutPreset->addItem("ultrafast", "ultrafast"); + ui->simpleOutPreset->addItem("superfast", "superfast"); + ui->simpleOutPreset->addItem("veryfast", "veryfast"); + ui->simpleOutPreset->addItem("faster", "faster"); + ui->simpleOutPreset->addItem("fast", "fast"); + ui->simpleOutPreset->addItem("medium", "medium"); + ui->simpleOutPreset->addItem("slow", "slow"); + ui->simpleOutPreset->addItem("slower", "slower"); + + defaultPreset = "veryfast"; + preset = curPreset; + } + + int idx = ui->simpleOutPreset->findData(QVariant(preset)); + if (idx == -1) + idx = ui->simpleOutPreset->findData(QVariant(defaultPreset)); + + ui->simpleOutPreset->setCurrentIndex(idx); +} + #define SIMPLE_OUTPUT_WARNING(str) \ QTStr("Basic.Settings.Output.Simple.Warn." str) @@ -2963,26 +3236,80 @@ void OBSBasicSettings::SimpleRecordingEncoderChanged() { QString qual = ui->simpleOutRecQuality->currentData().toString(); QString warning; + bool advanced = ui->simpleOutAdvanced->isChecked(); + bool enforceBitrate = ui->simpleOutEnforce->isChecked() || !advanced; + OBSService service; + + if (stream1Changed) { + QString streamType = GetComboData(ui->streamType); + service = obs_service_create_private( + QT_TO_UTF8(streamType), nullptr, + streamProperties->GetSettings()); + obs_service_release(service); + } else { + service = main->GetService(); + } delete simpleOutRecWarning; - if (qual == "Stream") { - return; + if (enforceBitrate && service) { + 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(); + obs_data_set_int(videoSettings, "bitrate", oldVBitrate); + obs_data_set_int(audioSettings, "bitrate", oldABitrate); - } else if (qual == "Lossless") { - warning = SIMPLE_OUTPUT_WARNING("Lossless"); + obs_service_apply_encoder_settings(service, videoSettings, + 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); + if (newABitrate < oldABitrate) { + if (!warning.isEmpty()) + warning += "\n\n"; + warning += SIMPLE_OUTPUT_WARNING("AudioBitrate") + .arg(newABitrate); + } + + obs_data_release(videoSettings); + obs_data_release(audioSettings); + } + + if (qual == "Lossless") { + if (!warning.isEmpty()) + warning += "\n\n"; + warning += SIMPLE_OUTPUT_WARNING("Lossless"); warning += "\n\n"; warning += SIMPLE_OUTPUT_WARNING("Encoder"); - } else { + } else if (qual != "Stream") { QString enc = ui->simpleOutRecEncoder->currentData().toString(); - if (enc != SIMPLE_ENCODER_X264 && - enc != SIMPLE_ENCODER_X264_LOWCPU) - return; + QString streamEnc = + ui->simpleOutStrEncoder->currentData().toString(); + bool x264RecEnc = (enc == SIMPLE_ENCODER_X264 || + enc == SIMPLE_ENCODER_X264_LOWCPU); - warning = SIMPLE_OUTPUT_WARNING("Encoder"); + if (streamEnc == SIMPLE_ENCODER_X264 && x264RecEnc) { + if (!warning.isEmpty()) + warning += "\n\n"; + warning += SIMPLE_OUTPUT_WARNING("Encoder"); + } + + if (streamEnc == enc && enc == SIMPLE_ENCODER_QSV) { + if (!warning.isEmpty()) + warning += "\n\n"; + warning += SIMPLE_OUTPUT_WARNING("MultipleQSV"); + } } + if (warning.isEmpty()) + return; + simpleOutRecWarning = new QLabel(warning, this); simpleOutRecWarning->setObjectName("warningLabel"); simpleOutRecWarning->setWordWrap(true); diff --git a/obs/window-basic-settings.hpp b/obs/window-basic-settings.hpp index ded66ee..e3bdcfa 100644 --- a/obs/window-basic-settings.hpp +++ b/obs/window-basic-settings.hpp @@ -108,6 +108,13 @@ private: QPointer advOutRecWarning; QPointer simpleOutRecWarning; + QString curPreset; + QString curQSVPreset; + QString curNVENCPreset; + + QString curAdvStreamEncoder; + QString curAdvRecordEncoder; + using AudioSource_t = std::tuple, QPointer, @@ -231,6 +238,7 @@ private: void UpdateAdvOutStreamDelayEstimate(); void FillSimpleRecordingValues(); + void FillSimpleStreamingValues(); void RecalcOutputResPixels(const char *resText); @@ -253,6 +261,7 @@ private slots: void on_colorFormat_currentIndexChanged(const QString &text); + void on_filenameFormatting_textEdited(const QString &text); void on_outputResolution_editTextChanged(const QString &text); void on_baseResolution_editTextChanged(const QString &text); @@ -280,6 +289,8 @@ private slots: void SimpleRecordingEncoderChanged(); void SimpleRecordingQualityLosslessWarning(int idx); + void SimpleStreamingEncoderChanged(); + protected: virtual void closeEvent(QCloseEvent *event); diff --git a/obs/window-basic-status-bar.cpp b/obs/window-basic-status-bar.cpp index 5ad3427..660544f 100644 --- a/obs/window-basic-status-bar.cpp +++ b/obs/window-basic-status-bar.cpp @@ -261,7 +261,7 @@ void OBSBasicStatusBar::UpdateStatusBar() int diff = skipped - lastSkippedFrameCount; double percentage = double(skipped) / double(total) * 100.0; - if (diff && percentage >= 0.1f) + if (diff > 10 && percentage >= 0.1f) showMessage(QTStr("HighResourceUsage"), 4000); lastSkippedFrameCount = skipped; diff --git a/obs/window-basic-transform.cpp b/obs/window-basic-transform.cpp index f9f9d98..57ad630 100644 --- a/obs/window-basic-transform.cpp +++ b/obs/window-basic-transform.cpp @@ -30,6 +30,7 @@ void OBSBasicTransform::HookWidget(QWidget *widget, const char *signal, } #define COMBO_CHANGED SIGNAL(currentIndexChanged(int)) +#define ISCROLL_CHANGED SIGNAL(valueChanged(int)) #define DSCROLL_CHANGED SIGNAL(valueChanged(double)) OBSBasicTransform::OBSBasicTransform(OBSBasic *parent) @@ -49,6 +50,10 @@ OBSBasicTransform::OBSBasicTransform(OBSBasic *parent) 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())); installEventFilter(CreateShortcutFilter()); @@ -183,7 +188,9 @@ void OBSBasicTransform::RefreshControls() return; obs_transform_info osi; + obs_sceneitem_crop crop; obs_sceneitem_get_info(item, &osi); + obs_sceneitem_get_crop(item, &crop); obs_source_t *source = obs_sceneitem_get_source(item); float width = float(obs_source_get_width(source)); @@ -204,6 +211,11 @@ void OBSBasicTransform::RefreshControls() ui->boundsAlign->setCurrentIndex(boundsAlignIndex); ui->boundsWidth->setValue(osi.bounds.x); ui->boundsHeight->setValue(osi.bounds.y); + + ui->cropLeft->setValue(int(crop.left)); + ui->cropRight->setValue(int(crop.right)); + ui->cropTop->setValue(int(crop.top)); + ui->cropBottom->setValue(int(crop.bottom)); ignoreItemChange = false; } @@ -260,3 +272,19 @@ void OBSBasicTransform::OnControlChanged() obs_sceneitem_set_info(item, &oti); ignoreTransformSignal = false; } + +void OBSBasicTransform::OnCropChanged() +{ + if (ignoreItemChange) + 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.bottom = uint32_t(ui->cropBottom->value()); + + ignoreTransformSignal = true; + obs_sceneitem_set_crop(item, &crop); + ignoreTransformSignal = false; +} diff --git a/obs/window-basic-transform.hpp b/obs/window-basic-transform.hpp index c8e2e40..9764f28 100644 --- a/obs/window-basic-transform.hpp +++ b/obs/window-basic-transform.hpp @@ -41,6 +41,7 @@ private slots: void SetItemQt(OBSSceneItem newItem); void OnBoundsType(int index); void OnControlChanged(); + void OnCropChanged(); public: OBSBasicTransform(OBSBasic *parent); diff --git a/obs/window-projector.cpp b/obs/window-projector.cpp index ff23406..b6091d9 100644 --- a/obs/window-projector.cpp +++ b/obs/window-projector.cpp @@ -12,7 +12,7 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_) Qt::Window | Qt::FramelessWindowHint), source (source_), removedSignal (obs_source_get_signal_handler(source), - "removed", OBSSourceRemoved, this) + "remove", OBSSourceRemoved, this) { setAttribute(Qt::WA_DeleteOnClose, true); diff --git a/obs/window-remux.cpp b/obs/window-remux.cpp index 2802f3e..ea9ecce 100644 --- a/obs/window-remux.cpp +++ b/obs/window-remux.cpp @@ -97,6 +97,8 @@ OBSRemux::~OBSRemux() remuxer.wait(); } +#define RECORDING_PATTERN "(*.flv *.mp4 *.mov *.mkv *.ts *.m3u8)" + void OBSRemux::BrowseInput() { QString path = ui->sourceFile->text(); @@ -105,7 +107,8 @@ void OBSRemux::BrowseInput() path = QFileDialog::getOpenFileName(this, QTStr("Remux.SelectRecording"), path, - QTStr("Remux.RecordingPattern")); + QTStr("Remux.OBSRecording") + QString(" ") + + RECORDING_PATTERN); inputChanged(path); } @@ -132,7 +135,7 @@ void OBSRemux::BrowseOutput() { QString path(ui->targetFile->text()); path = QFileDialog::getSaveFileName(this, QTStr("Remux.SelectTarget"), - path, "(*.mp4)"); + path, RECORDING_PATTERN); if (path.isEmpty()) return; diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 4e80a63..8791183 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -9,6 +9,7 @@ if(WIN32) add_subdirectory(win-capture) add_subdirectory(decklink/win) add_subdirectory(win-mf) + add_subdirectory(obs-qsv11) elseif(APPLE) add_subdirectory(coreaudio-encoder) add_subdirectory(mac-avcapture) @@ -21,6 +22,7 @@ elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") add_subdirectory(linux-pulseaudio) add_subdirectory(linux-v4l2) add_subdirectory(linux-jack) + add_subdirectory(linux-alsa) add_subdirectory(decklink/linux) elseif("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD") add_subdirectory(linux-capture) diff --git a/plugins/coreaudio-encoder/data/locale/ar-SA.ini b/plugins/coreaudio-encoder/data/locale/ar-SA.ini new file mode 100644 index 0000000..2ebfd6b --- /dev/null +++ b/plugins/coreaudio-encoder/data/locale/ar-SA.ini @@ -0,0 +1,6 @@ +CoreAudioAAC="مرمّز CoreAudio AAC" +Bitrate="معدّل البِت" +AllowHEAAC="السماح بـ HE-AAC" +OutputSamplerate="معدل عينة الإخراج" +UseInputSampleRate="استخدم مدخل معدل عينة (OBS) (قد تيم إدراج معدلات بت غير معتمدة)" + diff --git a/plugins/coreaudio-encoder/data/locale/ca-ES.ini b/plugins/coreaudio-encoder/data/locale/ca-ES.ini index cb852ba..fc2187f 100644 --- a/plugins/coreaudio-encoder/data/locale/ca-ES.ini +++ b/plugins/coreaudio-encoder/data/locale/ca-ES.ini @@ -1,4 +1,6 @@ CoreAudioAAC="Codificador CoreAudio AAC" Bitrate="Taxa de bits" AllowHEAAC="Permet HE-AAC" +OutputSamplerate="Freqüència de mostreig de sortida" +UseInputSampleRate="Utilitzar les taxa de mostra de l'entrada d'OBS (pot mostrar taxes de bits no compatibles)" diff --git a/plugins/coreaudio-encoder/data/locale/da-DK.ini b/plugins/coreaudio-encoder/data/locale/da-DK.ini new file mode 100644 index 0000000..64cdc29 --- /dev/null +++ b/plugins/coreaudio-encoder/data/locale/da-DK.ini @@ -0,0 +1,6 @@ +CoreAudioAAC="CoreAudio AAC encoder" +Bitrate="Bitrate" +AllowHEAAC="Tillad HE-AAC" +OutputSamplerate="Output Sample Rate" +UseInputSampleRate="Brug Input (OBS) Sample Rate (kan vise ikke-understøttede bithastigheder)" + diff --git a/plugins/coreaudio-encoder/data/locale/eu-ES.ini b/plugins/coreaudio-encoder/data/locale/eu-ES.ini index 0a18d48..c1cb04e 100644 --- a/plugins/coreaudio-encoder/data/locale/eu-ES.ini +++ b/plugins/coreaudio-encoder/data/locale/eu-ES.ini @@ -1,6 +1,6 @@ -CoreAudioAAC="CoreAudio AAC kodeatzailea" -Bitrate="Bitneurria" +CoreAudioAAC="CoreAudio AAC kodetzailea" +Bitrate="Bit-tasa" AllowHEAAC="Ahalbidetu HE-AAC" -OutputSamplerate="Irteera Lagin Neurria" -UseInputSampleRate="Erabili Sarrerako (OBS) Lagin Neurria (badaiteke sostengugabeko bitneurriak zerrendatea)" +OutputSamplerate="Irteera lagin-emaria" +UseInputSampleRate="Erabili sarrerako (OBS) lagin-emaria (sostengurik gabeko bit-tasak ager daitezke zerrendan)" diff --git a/plugins/coreaudio-encoder/data/locale/hu-HU.ini b/plugins/coreaudio-encoder/data/locale/hu-HU.ini index fd992f0..4cb1545 100644 --- a/plugins/coreaudio-encoder/data/locale/hu-HU.ini +++ b/plugins/coreaudio-encoder/data/locale/hu-HU.ini @@ -1,6 +1,6 @@ CoreAudioAAC="CoreAudio AAC kódoló" Bitrate="Bitráta" -AllowHEAAC="HE-AAC Engedélyezése" -OutputSamplerate="Kimeneti Mintavételráta" -UseInputSampleRate="Beviteli (OBS) Minta Rátájának használata (kilistázza a nem támogatott bitrátákat)" +AllowHEAAC="HE-AAC engedélyezése" +OutputSamplerate="Kimeneti mintavételráta" +UseInputSampleRate="Beviteli (OBS) mintaráta használata (kilistázza a nem támogatott bitrátákat)" diff --git a/plugins/coreaudio-encoder/data/locale/ja-JP.ini b/plugins/coreaudio-encoder/data/locale/ja-JP.ini index 90d73bc..bcda7fc 100644 --- a/plugins/coreaudio-encoder/data/locale/ja-JP.ini +++ b/plugins/coreaudio-encoder/data/locale/ja-JP.ini @@ -2,5 +2,5 @@ CoreAudioAAC="CoreAudio AAC エンコーダ" Bitrate="ビットレート" AllowHEAAC="HE-AAC を許可" OutputSamplerate="出力のサンプルレート" -UseInputSampleRate="(OBSで) 入力したサンプルレートを使用(サポートされていないビットレートをリストする可能性があります)" +UseInputSampleRate="(OBSで) 入力したサンプルレートを使用 (サポートされていないビットレートをリストする可能性があります)" diff --git a/plugins/coreaudio-encoder/data/locale/pt-BR.ini b/plugins/coreaudio-encoder/data/locale/pt-BR.ini index 3e647f2..b251e2b 100644 --- a/plugins/coreaudio-encoder/data/locale/pt-BR.ini +++ b/plugins/coreaudio-encoder/data/locale/pt-BR.ini @@ -1,4 +1,6 @@ CoreAudioAAC="Codec de AAC CoreAudio" Bitrate="Bitrate" AllowHEAAC="Permitir HE-AAC" +OutputSamplerate="Taxa de Amostragem de Saída" +UseInputSampleRate="Utilize a Taxa de Amostrarem de Entrada (OBS) (pode mostrar bitrates não-suportados)" diff --git a/plugins/coreaudio-encoder/data/locale/ro-RO.ini b/plugins/coreaudio-encoder/data/locale/ro-RO.ini index 290c5fd..c3f3246 100644 --- a/plugins/coreaudio-encoder/data/locale/ro-RO.ini +++ b/plugins/coreaudio-encoder/data/locale/ro-RO.ini @@ -1,6 +1,6 @@ -CoreAudioAAC="CoreAudio AAC Encoder" -Bitrate="Rata biti / Bitrate" +CoreAudioAAC="Cofificator AAC CoreAudio" +Bitrate="Rată de biți" AllowHEAAC="Permite HE-AAC" -OutputSamplerate="Mostra Ratei de Output" -UseInputSampleRate="Utilizeaza Mostra de Rata (OBS) ca Input (pot enumera bitrate-uri neacceptate)" +OutputSamplerate="Rată de eșantionare a ieșirii" +UseInputSampleRate="Folosește rata de eșantionare (OBS) ca intrare (poate lista rate de biți neacceptate)" diff --git a/plugins/coreaudio-encoder/data/locale/ru-RU.ini b/plugins/coreaudio-encoder/data/locale/ru-RU.ini index f30fc0d..5510bcc 100644 --- a/plugins/coreaudio-encoder/data/locale/ru-RU.ini +++ b/plugins/coreaudio-encoder/data/locale/ru-RU.ini @@ -1,4 +1,6 @@ CoreAudioAAC="Кодировщик CoreAudio AAC" Bitrate="Битрейт" AllowHEAAC="Разрешить HE-AAC" +OutputSamplerate="Выходная Частота Дискретизации" +UseInputSampleRate="Использование Входной (OBS) Частоты Дискретизации (может иметь список не поддерживаемых битрейтом)" diff --git a/plugins/coreaudio-encoder/data/locale/sv-SE.ini b/plugins/coreaudio-encoder/data/locale/sv-SE.ini index ad12840..8bf5f03 100644 --- a/plugins/coreaudio-encoder/data/locale/sv-SE.ini +++ b/plugins/coreaudio-encoder/data/locale/sv-SE.ini @@ -1,4 +1,5 @@ CoreAudioAAC="CoreAudio AAC-kodare" -Bitrate="Bitrate" +Bitrate="Bithastighet" AllowHEAAC="Tillåt HE-AAC" +OutputSamplerate="Samplingsfrekvens för utmatning" diff --git a/plugins/coreaudio-encoder/data/locale/ta-IN.ini b/plugins/coreaudio-encoder/data/locale/ta-IN.ini new file mode 100644 index 0000000..348f412 --- /dev/null +++ b/plugins/coreaudio-encoder/data/locale/ta-IN.ini @@ -0,0 +1,4 @@ +Bitrate="பிட்விகிதம்" +AllowHEAAC="HE-AACஐ அனுமதி" +OutputSamplerate="வெளியீடுக்கான மாதிரி விகிதம்" + diff --git a/plugins/coreaudio-encoder/data/locale/tr-TR.ini b/plugins/coreaudio-encoder/data/locale/tr-TR.ini index 0783c15..e9082d4 100644 --- a/plugins/coreaudio-encoder/data/locale/tr-TR.ini +++ b/plugins/coreaudio-encoder/data/locale/tr-TR.ini @@ -1,4 +1,5 @@ CoreAudioAAC="CoreAudio AAC kodlayıcısı" Bitrate="Bit hızı" AllowHEAAC="HE-ACC'ye izin ver" +OutputSamplerate="Çıkış örnek hızı" diff --git a/plugins/decklink/data/locale/ar-SA.ini b/plugins/decklink/data/locale/ar-SA.ini new file mode 100644 index 0000000..fdaf139 --- /dev/null +++ b/plugins/decklink/data/locale/ar-SA.ini @@ -0,0 +1,6 @@ +BlackmagicDevice="جهاز Blackmagic" +Device="الجهاز" +Mode="الوضع" +Buffering="استخدام التخزين المؤقت" +PixelFormat="صيغة البكسل" + diff --git a/plugins/decklink/data/locale/da-DK.ini b/plugins/decklink/data/locale/da-DK.ini index a0ecc1b..1ebc715 100644 --- a/plugins/decklink/data/locale/da-DK.ini +++ b/plugins/decklink/data/locale/da-DK.ini @@ -2,4 +2,5 @@ BlackmagicDevice="Blackmagic enhed" Device="Enhed" Mode="Tilstand" Buffering="Brug buffering" +PixelFormat="Pixel format" diff --git a/plugins/decklink/data/locale/el-GR.ini b/plugins/decklink/data/locale/el-GR.ini index cab7158..9c7ecfd 100644 --- a/plugins/decklink/data/locale/el-GR.ini +++ b/plugins/decklink/data/locale/el-GR.ini @@ -1,4 +1,6 @@ BlackmagicDevice="Συσκευή Blackmagic" Device="Συσκευή" +Mode="Λειτουργία" Buffering="Χρήση ενδιάμεσης μνήμης" +PixelFormat="Μορφή pixel" diff --git a/plugins/decklink/data/locale/eu-ES.ini b/plugins/decklink/data/locale/eu-ES.ini index fa121ab..0e2c79d 100644 --- a/plugins/decklink/data/locale/eu-ES.ini +++ b/plugins/decklink/data/locale/eu-ES.ini @@ -1,6 +1,6 @@ -BlackmagicDevice="Blackmagic Gailua" +BlackmagicDevice="Blackmagic gailua" Device="Gailua" Mode="Modua" Buffering="Erabili Bufferreratzea" -PixelFormat="Pixel Heuskarria" +PixelFormat="Pixel formatua" diff --git a/plugins/decklink/data/locale/he-IL.ini b/plugins/decklink/data/locale/he-IL.ini new file mode 100644 index 0000000..0d99ed4 --- /dev/null +++ b/plugins/decklink/data/locale/he-IL.ini @@ -0,0 +1,6 @@ +BlackmagicDevice="התקן Blackmagic" +Device="התקן" +Mode="מצב" +Buffering="השתמש באוגר" +PixelFormat="תבנית פיקסלים" + diff --git a/plugins/decklink/data/locale/hu-HU.ini b/plugins/decklink/data/locale/hu-HU.ini index 121c948..18bf1bf 100644 --- a/plugins/decklink/data/locale/hu-HU.ini +++ b/plugins/decklink/data/locale/hu-HU.ini @@ -1,6 +1,6 @@ -BlackmagicDevice="BlackMagic Eszköz" +BlackmagicDevice="BlackMagic eszköz" Device="Eszköz" Mode="Mód" -Buffering="Pufferelés Használata" -PixelFormat="Képpont Formátum" +Buffering="Pufferelés használata" +PixelFormat="Képpont formátum" diff --git a/plugins/decklink/data/locale/pt-BR.ini b/plugins/decklink/data/locale/pt-BR.ini index 9ad1547..b17a47d 100644 --- a/plugins/decklink/data/locale/pt-BR.ini +++ b/plugins/decklink/data/locale/pt-BR.ini @@ -2,4 +2,5 @@ BlackmagicDevice="Dispositivo Blackmagic" Device="Dispositivo" Mode="Modo" Buffering="Utilizar Buffering" +PixelFormat="Formato de Pixel" diff --git a/plugins/decklink/data/locale/ro-RO.ini b/plugins/decklink/data/locale/ro-RO.ini index 19e8c38..e3a29fa 100644 --- a/plugins/decklink/data/locale/ro-RO.ini +++ b/plugins/decklink/data/locale/ro-RO.ini @@ -1,6 +1,6 @@ BlackmagicDevice="Dispozitiv Blackmagic" Device="Dispozitiv" Mode="Mod" -Buffering="Utilizaţi Tampon/Buffer" -PixelFormat="Format pixeli" +Buffering="Folosește buffering" +PixelFormat="Formatul pixelilor" diff --git a/plugins/decklink/data/locale/sv-SE.ini b/plugins/decklink/data/locale/sv-SE.ini index d77838b..acd4e1b 100644 --- a/plugins/decklink/data/locale/sv-SE.ini +++ b/plugins/decklink/data/locale/sv-SE.ini @@ -2,4 +2,5 @@ BlackmagicDevice="Blackmagicenhet" Device="Enhet" Mode="Läge" Buffering="Använd buffert" +PixelFormat="Bildpunktsformat" diff --git a/plugins/decklink/decklink-device.cpp b/plugins/decklink/decklink-device.cpp index 899c0f9..8dc109b 100644 --- a/plugins/decklink/decklink-device.cpp +++ b/plugins/decklink/decklink-device.cpp @@ -72,8 +72,13 @@ bool DeckLinkDevice::Init() if (result != S_OK) return true; + /* http://forum.blackmagicdesign.com/viewtopic.php?f=12&t=33967 + * BMDDeckLinkTopologicalID for older devices + * 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; std::ostringstream os; diff --git a/plugins/image-source/data/locale/ar-SA.ini b/plugins/image-source/data/locale/ar-SA.ini index c170139..d75aa98 100644 --- a/plugins/image-source/data/locale/ar-SA.ini +++ b/plugins/image-source/data/locale/ar-SA.ini @@ -1,3 +1,4 @@ ImageInput="الصورة" File="ملف الصورة" +UnloadWhenNotShowing="إلغاء تحميل الصورة إذا لم تظهر" diff --git a/plugins/image-source/data/locale/eu-ES.ini b/plugins/image-source/data/locale/eu-ES.ini index 7c942c7..ab9a648 100644 --- a/plugins/image-source/data/locale/eu-ES.ini +++ b/plugins/image-source/data/locale/eu-ES.ini @@ -1,4 +1,4 @@ ImageInput="Irudia" -File="Irudi Agiria" -UnloadWhenNotShowing="Desgertatu irudia erakusten ez denean" +File="Irudi-fitxategia" +UnloadWhenNotShowing="Ez kargatu irudia erakusten ez denean" diff --git a/plugins/image-source/data/locale/he-IL.ini b/plugins/image-source/data/locale/he-IL.ini new file mode 100644 index 0000000..92732e6 --- /dev/null +++ b/plugins/image-source/data/locale/he-IL.ini @@ -0,0 +1,4 @@ +ImageInput="תמונה" +File="קובץ תמונה" +UnloadWhenNotShowing="הסר טעינת תמונה כאשר לא נראה" + diff --git a/plugins/image-source/data/locale/pt-PT.ini b/plugins/image-source/data/locale/pt-PT.ini index 8a4ac35..fc12920 100644 --- a/plugins/image-source/data/locale/pt-PT.ini +++ b/plugins/image-source/data/locale/pt-PT.ini @@ -1,4 +1,4 @@ ImageInput="Imagem" -File="Ficheiro de Imagem" +File="Ficheiro de imagem" UnloadWhenNotShowing="Descarregar imagem quando não estiver em visualização" diff --git a/plugins/image-source/data/locale/ro-RO.ini b/plugins/image-source/data/locale/ro-RO.ini index d0eb0f7..c93f400 100644 --- a/plugins/image-source/data/locale/ro-RO.ini +++ b/plugins/image-source/data/locale/ro-RO.ini @@ -1,4 +1,4 @@ ImageInput="Imagine" -File="Fișier Imagine" -UnloadWhenNotShowing="Descarca imaginea din memorie cand nu este utilizata" +File="Fișier imagine" +UnloadWhenNotShowing="Eliberează din memorie imaginea când nu este afișată" diff --git a/plugins/image-source/data/locale/sv-SE.ini b/plugins/image-source/data/locale/sv-SE.ini index 06a667e..4727f33 100644 --- a/plugins/image-source/data/locale/sv-SE.ini +++ b/plugins/image-source/data/locale/sv-SE.ini @@ -1,4 +1,4 @@ ImageInput="Bild" File="Bildfil" -UnloadWhenNotShowing="Ta bort bild från VRAM när den inte visas" +UnloadWhenNotShowing="Ta bort bild när den inte visas" diff --git a/plugins/image-source/image-source.c b/plugins/image-source/image-source.c index f872966..f47d1dc 100644 --- a/plugins/image-source/image-source.c +++ b/plugins/image-source/image-source.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #define blog(log_level, format, ...) \ @@ -30,7 +31,8 @@ struct image_source { static time_t get_modified_timestamp(const char *filename) { struct stat stats; - stat(filename, &stats); + if (os_stat(filename, &stats) != 0) + return -1; return stats.st_mtime; } @@ -196,17 +198,29 @@ static const char *image_filter = "JPEG Files (*.jpeg *.jpg);;" "GIF Files (*.gif)"; -static obs_properties_t *image_source_properties(void *unused) +static obs_properties_t *image_source_properties(void *data) { - UNUSED_PARAMETER(unused); + struct image_source *s = data; + struct dstr path = {0}; obs_properties_t *props = obs_properties_create(); + if (s && s->file && *s->file) { + const char *slash; + + dstr_copy(&path, s->file); + dstr_replace(&path, "\\", "/"); + slash = strrchr(path.array, '/'); + if (slash) + dstr_resize(&path, slash - path.array + 1); + } + obs_properties_add_path(props, "file", obs_module_text("File"), - OBS_PATH_FILE, image_filter, NULL); + OBS_PATH_FILE, image_filter, path.array); obs_properties_add_bool(props, "unload", obs_module_text("UnloadWhenNotShowing")); + dstr_free(&path); return props; } diff --git a/plugins/linux-alsa/CMakeLists.txt b/plugins/linux-alsa/CMakeLists.txt new file mode 100644 index 0000000..226a4e7 --- /dev/null +++ b/plugins/linux-alsa/CMakeLists.txt @@ -0,0 +1,34 @@ +project(linux-alsa) + +if(DISABLE_ALSA) + message(STATUS "ALSA support disabled") + return() +endif() + +find_package(ALSA) +if(NOT ALSA_FOUND AND ENABLE_ALSA) + message(FATAL_ERROR "ALSA not found but set as enabled") +elseif(NOT ALSA_FOUND) + message(STATUS "ALSA not found, disabling ALSA plugin") + return() +endif() + +include_directories( + SYSTEM "${CMAKE_SOURCE_DIR}/libobs" + ${ALSA_INCLUDE_DIR} +) + +set(linux-alsa_SOURCES + linux-alsa.c + alsa-input.c +) + +add_library(linux-alsa MODULE + ${linux-alsa_SOURCES} +) +target_link_libraries(linux-alsa + libobs + ${ALSA_LIBRARY} +) + +install_obs_plugin_with_data(linux-alsa data) diff --git a/plugins/linux-alsa/alsa-input.c b/plugins/linux-alsa/alsa-input.c new file mode 100644 index 0000000..94ea5ef --- /dev/null +++ b/plugins/linux-alsa/alsa-input.c @@ -0,0 +1,599 @@ +/* +Copyright (C) 2015. Guillermo A. Amaral B. + +Based on Pulse Input plugin by Leonhard Oelke. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +#include +#include + +#include + +#define blog(level, msg, ...) blog(level, "alsa-input: " msg, ##__VA_ARGS__) + +#define NSEC_PER_SEC 1000000000LL +#define NSEC_PER_MSEC 1000000L +#define STARTUP_TIMEOUT_NS (500 * NSEC_PER_MSEC) +#define REOPEN_TIMEOUT 1000UL +#define SHUTDOWN_ON_DEACTIVATE false + +struct alsa_data { + obs_source_t *source; +#if SHUTDOWN_ON_DEACTIVATE + bool active; +#endif + + /* user settings */ + char *device; + + /* pthread */ + pthread_t listen_thread; + pthread_t reopen_thread; + os_event_t *abort_event; + volatile bool listen; + volatile bool reopen; + + /* alsa */ + snd_pcm_t *handle; + snd_pcm_format_t format; + snd_pcm_uframes_t period_size; + + unsigned int channels; + unsigned int rate; + unsigned int sample_size; + uint8_t *buffer; + uint64_t first_ts; +}; + +static const char * alsa_get_name(void *); +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 *); +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, +#if SHUTDOWN_ON_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 +}; + +static bool _alsa_try_open(struct alsa_data *); +static bool _alsa_open(struct alsa_data *); +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 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) +{ + struct alsa_data *data = bzalloc(sizeof(struct alsa_data)); + + data->source = source; +#if SHUTDOWN_ON_DEACTIVATE + data->active = false; +#endif + data->buffer = NULL; + data->device = NULL; + data->first_ts = 0; + data->handle = NULL; + data->listen = false; + data->reopen = false; + data->listen_thread = 0; + data->reopen_thread = 0; + + data->device = bstrdup(obs_data_get_string(settings, "device_id")); + data->rate = obs_data_get_int(settings, "rate"); + + if (os_event_init(&data->abort_event, OS_EVENT_TYPE_MANUAL) != 0) { + blog(LOG_ERROR, "Abort event creation failed!"); + goto cleanup; + } + +#if !SHUTDOWN_ON_DEACTIVATE + _alsa_try_open(data); +#endif + return data; + +cleanup: + if (data->device) + bfree(data->device); + + bfree(data); + return NULL; +} + +void alsa_destroy(void *vptr) +{ + struct alsa_data *data = vptr; + + if (data->handle) + _alsa_close(data); + + os_event_destroy(data->abort_event); + bfree(data->device); + bfree(data); +} + +#if SHUTDOWN_ON_DEACTIVATE +void alsa_activate(void *vptr) +{ + struct alsa_data *data = vptr; + + data->active = true; + _alsa_try_open(data); +} + +void alsa_deactivate(void *vptr) +{ + struct alsa_data *data = vptr; + + _alsa_stop_reopen(data); + _alsa_close(data); + data->active = false; +} +#endif + +void alsa_update(void *vptr, obs_data_t *settings) +{ + struct alsa_data *data = vptr; + const char *device; + unsigned int rate; + bool reset = false; + + device = obs_data_get_string(settings, "device_id"); + if (strcmp(data->device, device) != 0) { + bfree(data->device); + data->device = bstrdup(device); + reset = true; + } + + rate = obs_data_get_int(settings, "rate"); + if (data->rate != rate) { + data->rate = rate; + reset = true; + } + +#if SHUTDOWN_ON_DEACTIVATE + if (reset && data->handle) + _alsa_close(data); + + if (data->active && !data->handle) + _alsa_try_open(data); +#else + if (reset) { + if (data->handle) + _alsa_close(data); + _alsa_try_open(data); + } +#endif +} + +const char * alsa_get_name(void *unused) +{ + UNUSED_PARAMETER(unused); + return obs_module_text("AlsaInput"); +} + +void alsa_get_defaults(obs_data_t *settings) +{ + obs_data_set_default_string(settings, "device_id", "default"); + obs_data_set_default_int(settings, "rate", 44100); +} + +obs_properties_t * alsa_get_properties(void *unused) +{ + void **hints; + void **hint; + char *name = NULL; + char *descr = NULL; + char *io = NULL; + char *descr_i; + obs_properties_t *props; + obs_property_t *devices; + obs_property_t *rate; + + UNUSED_PARAMETER(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_property_list_add_string(devices, "Default", "default"); + + rate = obs_properties_add_list(props, "rate", + obs_module_text("Rate"), OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); + + obs_property_list_add_int(rate, "32000 Hz", 32000); + obs_property_list_add_int(rate, "44100 Hz", 44100); + obs_property_list_add_int(rate, "48000 Hz", 48000); + + if (snd_device_name_hint(-1, "pcm", &hints) < 0) + return props; + + hint = hints; + while (*hint != NULL) { + /* check if we're dealing with an Input */ + io = snd_device_name_get_hint(*hint, "IOID"); + if (io != NULL && strcmp(io, "Input") != 0) + goto next; + + name = snd_device_name_get_hint(*hint, "NAME"); + if (name == NULL || strstr(name, "front:") == NULL) + goto next; + + descr = snd_device_name_get_hint(*hint, "DESC"); + if (!descr) + goto next; + + descr_i = descr; + while (*descr_i) { + if (*descr_i == '\n') { + *descr_i = '\0'; + break; + } + else ++descr_i; + } + + obs_property_list_add_string(devices, descr, name); + + next: + if (name != NULL) + free(name), name = NULL; + + if (descr != NULL) + free(descr), descr = NULL; + + if (io != NULL) + free(io), io = NULL; + + ++hint; + } + snd_device_name_free_hint(hints); + + return props; +} + +/*****************************************************************************/ + +bool _alsa_try_open(struct alsa_data *data) +{ + _alsa_stop_reopen(data); + + if (_alsa_open(data)) + return true; + + _alsa_start_reopen(data); + + return false; +} + +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); + if (err < 0) { + blog(LOG_ERROR, "Failed to open '%s': %s", + data->device, snd_strerror(err)); + return false; + } + + if (!_alsa_configure(data)) + goto cleanup; + + if (snd_pcm_state(data->handle) != SND_PCM_STATE_PREPARED) { + blog(LOG_ERROR, "Device not prepared: '%s'", + data->device); + goto cleanup; + } + + /* start listening */ + + err = snd_pcm_start(data->handle); + if (err < 0) { + blog(LOG_ERROR, "Failed to start '%s': %s", + data->device, snd_strerror(err)); + goto cleanup; + } + + /* create capture thread */ + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + err = pthread_create(&data->listen_thread, &attr, _alsa_listen, data); + if (err) { + pthread_attr_destroy(&attr); + blog(LOG_ERROR, + "Failed to create capture thread for device '%s'.", + data->device); + goto cleanup; + } + + pthread_attr_destroy(&attr); + return true; + +cleanup: + _alsa_close(data); + return false; +} + +void _alsa_close(struct alsa_data *data) +{ + if (data->listen_thread) { + os_atomic_set_bool(&data->listen, false); + pthread_join(data->listen_thread, NULL); + data->listen_thread = 0; + } + + if (data->handle) { + snd_pcm_drop(data->handle); + snd_pcm_close(data->handle), data->handle = NULL; + } + + if (data->buffer) + bfree(data->buffer), data->buffer = NULL; +} + +bool _alsa_configure(struct alsa_data *data) +{ + snd_pcm_hw_params_t *hwparams; + int err; + int dir; + + snd_pcm_hw_params_alloca(&hwparams); + + 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)); + return false; + } + + err = snd_pcm_hw_params_set_access(data->handle, hwparams, + SND_PCM_ACCESS_RW_INTERLEAVED); + if (err < 0) { + 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); + if (err < 0) { + 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); + if (err < 0) { + 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); + + err = snd_pcm_hw_params_get_channels(hwparams, &data->channels); + if (err < 0) + data->channels = 2; + + err = snd_pcm_hw_params_set_channels_near(data->handle, hwparams, + &data->channels); + if (err < 0) { + blog(LOG_ERROR, + "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); + + err = snd_pcm_hw_params(data->handle, hwparams); + if (err < 0) { + blog(LOG_ERROR, "snd_pcm_hw_params failed: %s", + snd_strerror(err)); + return false; + } + + err = snd_pcm_hw_params_get_period_size(hwparams, &data->period_size, + &dir); + if (err < 0) { + 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; + + if (data->buffer) + bfree(data->buffer); + data->buffer = bzalloc(data->period_size * data->sample_size); + + return true; +} + +void _alsa_start_reopen(struct alsa_data *data) +{ + pthread_attr_t attr; + int err; + + if (os_atomic_load_bool(&data->reopen)) + return; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + 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); + } + + pthread_attr_destroy(&attr); +} + +void _alsa_stop_reopen(struct alsa_data *data) +{ + if (os_atomic_load_bool(&data->reopen)) + os_event_signal(data->abort_event); + + if (data->reopen_thread) { + pthread_join(data->reopen_thread, NULL); + data->reopen_thread = 0; + } + + os_event_reset(data->abort_event); +} + +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.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); + + if (!os_atomic_load_bool(&data->listen)) + break; + + if (frames <= 0) { + frames = snd_pcm_recover(data->handle, frames, 0); + if (frames <= 0) { + snd_pcm_wait(data->handle, 100); + continue; + } + } + + out.frames = frames; + out.timestamp = os_gettime_ns() + - ((frames * NSEC_PER_SEC) / data->rate); + + if (!data->first_ts) + data->first_ts = out.timestamp + STARTUP_TIMEOUT_NS; + + if (out.timestamp > data->first_ts) + obs_source_output_audio(data->source, &out); + } while (os_atomic_load_bool(&data->listen)); + + blog(LOG_DEBUG, "Capture thread is about to exit."); + + pthread_exit(NULL); + return NULL; +} + +void * _alsa_reopen(void *attr) +{ + struct alsa_data *data = attr; + unsigned long timeout = REOPEN_TIMEOUT; + + blog(LOG_DEBUG, "Reopen thread started."); + + os_atomic_set_bool(&data->reopen, true); + + while (os_event_timedwait(data->abort_event, timeout) == ETIMEDOUT) { + if (_alsa_open(data)) + break; + + if (timeout < (REOPEN_TIMEOUT * 5)) + timeout += REOPEN_TIMEOUT; + } + + os_atomic_set_bool(&data->reopen, false); + + blog(LOG_DEBUG, "Reopen thread is about to exit."); + + pthread_exit(NULL); + return NULL; +} + +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; + } + + return AUDIO_FORMAT_UNKNOWN; +} + +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_SURROUND; + 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/ar-SA.ini b/plugins/linux-alsa/data/locale/ar-SA.ini new file mode 100644 index 0000000..c7ca8ec --- /dev/null +++ b/plugins/linux-alsa/data/locale/ar-SA.ini @@ -0,0 +1,3 @@ +AlsaInput="جهاز التقاط الصوت (ALSA)" +Device="الجهاز" + diff --git a/plugins/linux-alsa/data/locale/ca-ES.ini b/plugins/linux-alsa/data/locale/ca-ES.ini new file mode 100644 index 0000000..e738d5d --- /dev/null +++ b/plugins/linux-alsa/data/locale/ca-ES.ini @@ -0,0 +1,3 @@ +AlsaInput="Dispositiu de captura d'àudio (ALSA)" +Device="Dispositiu" + diff --git a/plugins/linux-alsa/data/locale/cs-CZ.ini b/plugins/linux-alsa/data/locale/cs-CZ.ini new file mode 100644 index 0000000..abd61a4 --- /dev/null +++ b/plugins/linux-alsa/data/locale/cs-CZ.ini @@ -0,0 +1,3 @@ +AlsaInput="Zaznamenávací zařízení zvuku (ALSA)" +Device="Zařízení" + diff --git a/plugins/linux-alsa/data/locale/da-DK.ini b/plugins/linux-alsa/data/locale/da-DK.ini new file mode 100644 index 0000000..40fe514 --- /dev/null +++ b/plugins/linux-alsa/data/locale/da-DK.ini @@ -0,0 +1,3 @@ +AlsaInput="Lyd-optagelsesenhed (ALSA)" +Device="Enhed" + diff --git a/plugins/linux-alsa/data/locale/de-DE.ini b/plugins/linux-alsa/data/locale/de-DE.ini new file mode 100644 index 0000000..4d36811 --- /dev/null +++ b/plugins/linux-alsa/data/locale/de-DE.ini @@ -0,0 +1,3 @@ +AlsaInput="Audioaufnahmegerät (ALSA)" +Device="Gerät" + diff --git a/plugins/linux-alsa/data/locale/en-US.ini b/plugins/linux-alsa/data/locale/en-US.ini new file mode 100644 index 0000000..45d8647 --- /dev/null +++ b/plugins/linux-alsa/data/locale/en-US.ini @@ -0,0 +1,2 @@ +AlsaInput="Audio Capture Device (ALSA)" +Device="Device" diff --git a/plugins/linux-alsa/data/locale/es-ES.ini b/plugins/linux-alsa/data/locale/es-ES.ini new file mode 100644 index 0000000..e1957b0 --- /dev/null +++ b/plugins/linux-alsa/data/locale/es-ES.ini @@ -0,0 +1,3 @@ +AlsaInput="Dispositivo de captura de audio (ALSA)" +Device="Dispositivo" + diff --git a/plugins/linux-alsa/data/locale/eu-ES.ini b/plugins/linux-alsa/data/locale/eu-ES.ini new file mode 100644 index 0000000..9c5f61c --- /dev/null +++ b/plugins/linux-alsa/data/locale/eu-ES.ini @@ -0,0 +1,3 @@ +AlsaInput="Audio kapturako gailua (ALSA)" +Device="Gailua" + diff --git a/plugins/linux-alsa/data/locale/fi-FI.ini b/plugins/linux-alsa/data/locale/fi-FI.ini new file mode 100644 index 0000000..9b68074 --- /dev/null +++ b/plugins/linux-alsa/data/locale/fi-FI.ini @@ -0,0 +1,3 @@ +AlsaInput="Äänenkaappauslaite (ALSA)" +Device="Laite" + diff --git a/plugins/linux-alsa/data/locale/fr-FR.ini b/plugins/linux-alsa/data/locale/fr-FR.ini new file mode 100644 index 0000000..ca3d986 --- /dev/null +++ b/plugins/linux-alsa/data/locale/fr-FR.ini @@ -0,0 +1,3 @@ +AlsaInput="Périphérique de capture audio (ALSA)" +Device="Périphérique" + diff --git a/plugins/linux-alsa/data/locale/gl-ES.ini b/plugins/linux-alsa/data/locale/gl-ES.ini new file mode 100644 index 0000000..e1957b0 --- /dev/null +++ b/plugins/linux-alsa/data/locale/gl-ES.ini @@ -0,0 +1,3 @@ +AlsaInput="Dispositivo de captura de audio (ALSA)" +Device="Dispositivo" + diff --git a/plugins/linux-alsa/data/locale/hr-HR.ini b/plugins/linux-alsa/data/locale/hr-HR.ini new file mode 100644 index 0000000..733101a --- /dev/null +++ b/plugins/linux-alsa/data/locale/hr-HR.ini @@ -0,0 +1,3 @@ +AlsaInput="Ulazni zvučni uređaj (ALSA)" +Device="Uređaj" + diff --git a/plugins/linux-alsa/data/locale/hu-HU.ini b/plugins/linux-alsa/data/locale/hu-HU.ini new file mode 100644 index 0000000..9c779f8 --- /dev/null +++ b/plugins/linux-alsa/data/locale/hu-HU.ini @@ -0,0 +1,3 @@ +AlsaInput="Hangrögzítő eszköz (ALSA)" +Device="Eszköz" + diff --git a/plugins/linux-alsa/data/locale/ja-JP.ini b/plugins/linux-alsa/data/locale/ja-JP.ini new file mode 100644 index 0000000..adcb57c --- /dev/null +++ b/plugins/linux-alsa/data/locale/ja-JP.ini @@ -0,0 +1,3 @@ +AlsaInput="音声キャプチャデバイス (ALSA)" +Device="デバイス" + diff --git a/plugins/linux-alsa/data/locale/ko-KR.ini b/plugins/linux-alsa/data/locale/ko-KR.ini new file mode 100644 index 0000000..9706c9e --- /dev/null +++ b/plugins/linux-alsa/data/locale/ko-KR.ini @@ -0,0 +1,3 @@ +AlsaInput="오디오 캡쳐 장치 (ALSA)" +Device="장치" + diff --git a/plugins/linux-alsa/data/locale/nl-NL.ini b/plugins/linux-alsa/data/locale/nl-NL.ini new file mode 100644 index 0000000..5d826ce --- /dev/null +++ b/plugins/linux-alsa/data/locale/nl-NL.ini @@ -0,0 +1,3 @@ +AlsaInput="Audio-opnameapparaat (ALSA)" +Device="Apparaat" + diff --git a/plugins/linux-alsa/data/locale/pl-PL.ini b/plugins/linux-alsa/data/locale/pl-PL.ini new file mode 100644 index 0000000..201bafd --- /dev/null +++ b/plugins/linux-alsa/data/locale/pl-PL.ini @@ -0,0 +1,3 @@ +AlsaInput="Urządzenie przechwytujące dźwięk (ALSA)" +Device="Urządzenie" + diff --git a/plugins/linux-alsa/data/locale/pt-BR.ini b/plugins/linux-alsa/data/locale/pt-BR.ini new file mode 100644 index 0000000..2eef7ca --- /dev/null +++ b/plugins/linux-alsa/data/locale/pt-BR.ini @@ -0,0 +1,3 @@ +AlsaInput="Dispositivo de Captura de Áudio (ALSA)" +Device="Dispositivo" + diff --git a/plugins/linux-alsa/data/locale/ro-RO.ini b/plugins/linux-alsa/data/locale/ro-RO.ini new file mode 100644 index 0000000..858c469 --- /dev/null +++ b/plugins/linux-alsa/data/locale/ro-RO.ini @@ -0,0 +1,3 @@ +AlsaInput="Dispozitiv de captură audio (ALSA)" +Device="Dispozitiv" + diff --git a/plugins/linux-alsa/data/locale/ru-RU.ini b/plugins/linux-alsa/data/locale/ru-RU.ini new file mode 100644 index 0000000..fff935c --- /dev/null +++ b/plugins/linux-alsa/data/locale/ru-RU.ini @@ -0,0 +1,3 @@ +AlsaInput="Устройство захвата аудио (ALSA)" +Device="Устройство" + diff --git a/plugins/linux-alsa/data/locale/sr-CS.ini b/plugins/linux-alsa/data/locale/sr-CS.ini new file mode 100644 index 0000000..733101a --- /dev/null +++ b/plugins/linux-alsa/data/locale/sr-CS.ini @@ -0,0 +1,3 @@ +AlsaInput="Ulazni zvučni uređaj (ALSA)" +Device="Uređaj" + diff --git a/plugins/linux-alsa/data/locale/sr-SP.ini b/plugins/linux-alsa/data/locale/sr-SP.ini new file mode 100644 index 0000000..22204d8 --- /dev/null +++ b/plugins/linux-alsa/data/locale/sr-SP.ini @@ -0,0 +1,3 @@ +AlsaInput="Улазни звучни уређај (ALSA)" +Device="Уређај" + diff --git a/plugins/linux-alsa/data/locale/sv-SE.ini b/plugins/linux-alsa/data/locale/sv-SE.ini new file mode 100644 index 0000000..ff778d6 --- /dev/null +++ b/plugins/linux-alsa/data/locale/sv-SE.ini @@ -0,0 +1,3 @@ +AlsaInput="Ljudinspelningsenhet (ALSA)" +Device="Enhet" + diff --git a/plugins/linux-alsa/data/locale/tr-TR.ini b/plugins/linux-alsa/data/locale/tr-TR.ini new file mode 100644 index 0000000..4439ffb --- /dev/null +++ b/plugins/linux-alsa/data/locale/tr-TR.ini @@ -0,0 +1,3 @@ +AlsaInput="Ses yakalama cihazı (ALSA)" +Device="Cihaz" + diff --git a/plugins/linux-alsa/data/locale/zh-CN.ini b/plugins/linux-alsa/data/locale/zh-CN.ini new file mode 100644 index 0000000..bf16482 --- /dev/null +++ b/plugins/linux-alsa/data/locale/zh-CN.ini @@ -0,0 +1,3 @@ +AlsaInput="音频捕获设备 (ALSA)" +Device="设备" + diff --git a/plugins/linux-alsa/data/locale/zh-TW.ini b/plugins/linux-alsa/data/locale/zh-TW.ini new file mode 100644 index 0000000..6577649 --- /dev/null +++ b/plugins/linux-alsa/data/locale/zh-TW.ini @@ -0,0 +1,3 @@ +AlsaInput="音訊擷取裝置(ALSA)" +Device="裝置" + diff --git a/plugins/linux-alsa/linux-alsa.c b/plugins/linux-alsa/linux-alsa.c new file mode 100644 index 0000000..b0cad0c --- /dev/null +++ b/plugins/linux-alsa/linux-alsa.c @@ -0,0 +1,29 @@ +/* +Copyright (C) 2015. Guillermo A. Amaral B. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include + +OBS_DECLARE_MODULE() +OBS_MODULE_USE_DEFAULT_LOCALE("linux-alsa", "en-US") + +extern struct obs_source_info alsa_input_capture; + +bool obs_module_load(void) +{ + obs_register_source(&alsa_input_capture); + return true; +} + diff --git a/plugins/linux-capture/data/locale/ar-SA.ini b/plugins/linux-capture/data/locale/ar-SA.ini index c70f886..547458e 100644 --- a/plugins/linux-capture/data/locale/ar-SA.ini +++ b/plugins/linux-capture/data/locale/ar-SA.ini @@ -1,6 +1,8 @@ X11SharedMemoryScreenInput="التقاط الشاشة (XSHM)" Screen="الشاشة" CaptureCursor="مؤشر الالتقاط" +AdvancedSettings="إعدادات متقدمة" +XServer="X Server" XCCapture="التقاط النافذة (Xcomposite)" Window="نافذة" CropTop="الاقتطاع من الأعلى (بكسل)" diff --git a/plugins/linux-capture/data/locale/ca-ES.ini b/plugins/linux-capture/data/locale/ca-ES.ini index 7c4a67b..10913d3 100644 --- a/plugins/linux-capture/data/locale/ca-ES.ini +++ b/plugins/linux-capture/data/locale/ca-ES.ini @@ -12,4 +12,5 @@ CropBottom="Escapçament inferior (en píxels)" SwapRedBlue="Intercanvia els colors vermell i blau" LockX="Bloca el servidor X quan s'estigui capturant" IncludeXBorder="Inclou-hi la vora X" +ExcludeAlpha="Usar format de textura sense alpha (solució de Mesa)" diff --git a/plugins/linux-capture/data/locale/cs-CZ.ini b/plugins/linux-capture/data/locale/cs-CZ.ini index 5b05871..342a927 100644 --- a/plugins/linux-capture/data/locale/cs-CZ.ini +++ b/plugins/linux-capture/data/locale/cs-CZ.ini @@ -1,6 +1,6 @@ X11SharedMemoryScreenInput="Záznam obrazovky (XSHM)" Screen="Obrazovka" -CaptureCursor="Snímat kurzor" +CaptureCursor="Zaznamenávat kurzor" AdvancedSettings="Rozšířená nastavení" XServer="Server X" XCCapture="Záznam okna (Xcomposite)" @@ -12,4 +12,5 @@ CropBottom="Oříznout spodek (px)" SwapRedBlue="Prohodit červenou a modrou" LockX="Zamknout server X při záznamu" IncludeXBorder="Zahrnout hranice X" +ExcludeAlpha="Použít formát textury bez alpha kanálu (Mesa workaround)" diff --git a/plugins/linux-capture/data/locale/da-DK.ini b/plugins/linux-capture/data/locale/da-DK.ini index 2e325bb..58f6b95 100644 --- a/plugins/linux-capture/data/locale/da-DK.ini +++ b/plugins/linux-capture/data/locale/da-DK.ini @@ -1,15 +1,16 @@ -X11SharedMemoryScreenInput="Indfang Skærm (XSHM)" +X11SharedMemoryScreenInput="Indfang skærm (XSHM)" Screen="Skærm" CaptureCursor="Indfang markøren" AdvancedSettings="Avancerede indstillinger" XServer="X Server" -XCCapture="Indfang Vindue (Xcomposite)" +XCCapture="Indfang vindue (Xcomposite)" Window="Vindue" -CropTop="Beskær Top (pixels)" -CropLeft="Beskær Venstre (pixels)" -CropRight="Beskær Højre (pixels)" +CropTop="Beskær top (pixels)" +CropLeft="Beskær venstre (pixels)" +CropRight="Beskær højre (pixels)" CropBottom="Beskær bund (pixels)" SwapRedBlue="Swap rød og blå" LockX="Lås X server ved optagelse" IncludeXBorder="Inkluder X kant" +ExcludeAlpha="Brug alpha-mindre tekstur format (Mesa løsning)" diff --git a/plugins/linux-capture/data/locale/de-DE.ini b/plugins/linux-capture/data/locale/de-DE.ini index 4f777d4..e879a93 100644 --- a/plugins/linux-capture/data/locale/de-DE.ini +++ b/plugins/linux-capture/data/locale/de-DE.ini @@ -12,4 +12,5 @@ CropBottom="Unten abschneiden (Pixel)" SwapRedBlue="Rot und Blau tauschen" LockX="X Server sperren während der Aufnahme" IncludeXBorder="X Rahmen anzeigen" +ExcludeAlpha="Verwenden von alphalosem Texturformat (Mesa Problemumgehung)" diff --git a/plugins/linux-capture/data/locale/en-US.ini b/plugins/linux-capture/data/locale/en-US.ini index 4f20c37..5661f38 100644 --- a/plugins/linux-capture/data/locale/en-US.ini +++ b/plugins/linux-capture/data/locale/en-US.ini @@ -12,3 +12,4 @@ CropBottom="Crop Bottom (pixels)" SwapRedBlue="Swap red and blue" LockX="Lock X server when capturing" IncludeXBorder="Include X Border" +ExcludeAlpha="Use alpha-less texture format (Mesa workaround)" diff --git a/plugins/linux-capture/data/locale/es-ES.ini b/plugins/linux-capture/data/locale/es-ES.ini index e0e132b..1ee5706 100644 --- a/plugins/linux-capture/data/locale/es-ES.ini +++ b/plugins/linux-capture/data/locale/es-ES.ini @@ -12,4 +12,5 @@ CropBottom="Recortar abajo (píxeles)" SwapRedBlue="Intercambiar rojo y azúl" LockX="Fijar X server mientras se captura" IncludeXBorder="Incluir borde de ventana X" +ExcludeAlpha="Usar formato de textura sin alpha (Arreglo para Mesa)" diff --git a/plugins/linux-capture/data/locale/eu-ES.ini b/plugins/linux-capture/data/locale/eu-ES.ini index d136360..802bf05 100644 --- a/plugins/linux-capture/data/locale/eu-ES.ini +++ b/plugins/linux-capture/data/locale/eu-ES.ini @@ -1,15 +1,16 @@ -X11SharedMemoryScreenInput="Ikusleiho Harpena (XSHM)" -Screen="Ikusleihoa" -CaptureCursor="Hartu Kurtsorea" -AdvancedSettings="Ezarpen Aurreratuak" +X11SharedMemoryScreenInput="Pantaila-kaptura (XSHM)" +Screen="Pantaila" +CaptureCursor="Kapturatu kurtsorea" +AdvancedSettings="Ezarpen aurreratuak" XServer="X Zerbitzaria" -XCCapture="Leiho Harpena (Xcomposite)" +XCCapture="Leiho-kaptura (Xcomposite)" Window="Leihoa" -CropTop="Moztu Goitik (pixel)" -CropLeft="Moztu Ezkerretik (pixel)" -CropRight="Moztu Eskuinetik (pixel)" -CropBottom="Moztu Behetik (pixel)" +CropTop="Moztu goitik (pixel)" +CropLeft="Moztu ezkerretik (pixel)" +CropRight="Moztu eskuinetik (pixel)" +CropBottom="Moztu behetik (pixel)" SwapRedBlue="Aldatu gorria eta urdina" -LockX="Blokeatu X zerbitzaria harpenean" -IncludeXBorder="Barneratu X Hertza" +LockX="Blokeatu X zerbitzaria kapturatzean" +IncludeXBorder="Sartu X ertza" +ExcludeAlpha="Alfarik gabeko testura formatua (Mesarako konponbidea)" diff --git a/plugins/linux-capture/data/locale/fi-FI.ini b/plugins/linux-capture/data/locale/fi-FI.ini index 47d596c..129eddd 100644 --- a/plugins/linux-capture/data/locale/fi-FI.ini +++ b/plugins/linux-capture/data/locale/fi-FI.ini @@ -12,4 +12,5 @@ CropBottom="Rajaa alhaalta (pikselit)" SwapRedBlue="Vaihda punainen ja sininen" LockX="Lukitse X Server kaappauksen aikana" IncludeXBorder="Sisällytä X-reunus" +ExcludeAlpha="Käytä tekstuuriformaattia ilman alpha-kanavaa (Mesa-yhteensopiva)" diff --git a/plugins/linux-capture/data/locale/fr-FR.ini b/plugins/linux-capture/data/locale/fr-FR.ini index dc8aa9b..9258fa3 100644 --- a/plugins/linux-capture/data/locale/fr-FR.ini +++ b/plugins/linux-capture/data/locale/fr-FR.ini @@ -1,15 +1,16 @@ X11SharedMemoryScreenInput="Capture d'écran (XSHM)" Screen="Écran" -CaptureCursor="Enregistrer le Curseur" +CaptureCursor="Capturer le curseur" AdvancedSettings="Paramètres avancés" XServer="Serveur X" XCCapture="Capture de la fenêtre (Xcomposite)" Window="Fenêtre" -CropTop="Rogner en Haut (pixels)" -CropLeft="Rogner à Gauche (pixels)" -CropRight="Rogner à Droite (pixels)" -CropBottom="Rogner en Bas (pixels)" +CropTop="Rogner en haut (pixels)" +CropLeft="Rogner à gauche (pixels)" +CropRight="Rogner à droite (pixels)" +CropBottom="Rogner en bas (pixels)" SwapRedBlue="Intervertir le rouge et le bleu" LockX="Verrouiller le serveur X lors de la capture" IncludeXBorder="Inclure la bordure de X" +ExcludeAlpha="Utiliser un format de texture sans alpha (contournement pour Mesa)" diff --git a/plugins/linux-capture/data/locale/he-IL.ini b/plugins/linux-capture/data/locale/he-IL.ini new file mode 100644 index 0000000..3e7b532 --- /dev/null +++ b/plugins/linux-capture/data/locale/he-IL.ini @@ -0,0 +1,15 @@ +X11SharedMemoryScreenInput="לכידת מסך (XSHM)" +Screen="מסך" +CaptureCursor="לכוד סמן" +AdvancedSettings="הגדרות מתקדמות" +XServer="שרת X" +XCCapture="לכידת חלון (Xcomposite)" +Window="חלון" +CropTop="חיתוך עליון (פיקסלים)" +CropLeft="חיתוך שמאל (פיקסלים)" +CropRight="חיתוך ימין (פיקסלים)" +CropBottom="חיתוך תחתון (פיקסלים)" +SwapRedBlue="החלף אדום וכחול" +LockX="נעל שרת X בעת לכידה" +IncludeXBorder="כלול קצה שרת X" + diff --git a/plugins/linux-capture/data/locale/hr-HR.ini b/plugins/linux-capture/data/locale/hr-HR.ini index 3190a3e..68ab0d5 100644 --- a/plugins/linux-capture/data/locale/hr-HR.ini +++ b/plugins/linux-capture/data/locale/hr-HR.ini @@ -12,4 +12,5 @@ CropBottom="Odseci odozdo (pikseli)" SwapRedBlue="Zameni crvenu i plavu" LockX="Zaključaj X server u toku snimanja" IncludeXBorder="Uključujući i X okvir" +ExcludeAlpha="Koristi neprovidni format teksture (zaobilaženje Mesa problema)" diff --git a/plugins/linux-capture/data/locale/hu-HU.ini b/plugins/linux-capture/data/locale/hu-HU.ini index b184164..03bb3dc 100644 --- a/plugins/linux-capture/data/locale/hu-HU.ini +++ b/plugins/linux-capture/data/locale/hu-HU.ini @@ -1,15 +1,16 @@ -X11SharedMemoryScreenInput="Képernyő Felvétel (XSHM)" +X11SharedMemoryScreenInput="Képernyő felvétel (XSHM)" Screen="Képernyő" -CaptureCursor="Kurzor Rögztítése" -AdvancedSettings="Speciális Beállítások" +CaptureCursor="Kurzor felvétele" +AdvancedSettings="Speciális beállítások" XServer="X Szerver" -XCCapture="Ablak Felvétel (Xcomposite)" +XCCapture="Ablak felvétel (Xcomposite)" Window="Ablak" -CropTop="Felső Levágása (pixelek)" -CropLeft="Bal Levágása (pixelek)" -CropRight="Jobb Levágása (pixelek)" -CropBottom="Alsó Levágása (pixelek)" -SwapRedBlue="Piros és Kék Cseréje" -LockX="X Szerver Zárolása Rögzítéskor" +CropTop="Felső levágása (pixelek)" +CropLeft="Bal levágása (pixelek)" +CropRight="Jobb levágása (pixelek)" +CropBottom="Alsó levágása (pixelek)" +SwapRedBlue="Piros és kék cseréje" +LockX="X Szerver zárolása rögzítéskor" IncludeXBorder="X Kerettel" +ExcludeAlpha="Alfa-mentesebb textúra formátum használata (Mesa áthidalás)" diff --git a/plugins/linux-capture/data/locale/ja-JP.ini b/plugins/linux-capture/data/locale/ja-JP.ini index 67bce28..332892c 100644 --- a/plugins/linux-capture/data/locale/ja-JP.ini +++ b/plugins/linux-capture/data/locale/ja-JP.ini @@ -1,15 +1,16 @@ -X11SharedMemoryScreenInput="画面キャプチャ (XSHM)" +X11SharedMemoryScreenInput="画面キャプチャ (XSHM)" Screen="画面" CaptureCursor="カーソルをキャプチャ" AdvancedSettings="高度な設定" XServer="X サーバ" XCCapture="ウィンドウキャプチャ (Xcomposite)" Window="ウィンドウ" -CropTop="上部クロップ(ピクセル)" -CropLeft="左側クロップ(ピクセル)" -CropRight="右側クロップ(ピクセル)" -CropBottom="下部クロップ(ピクセル)" +CropTop="上部クロップ (ピクセル)" +CropLeft="左側クロップ (ピクセル)" +CropRight="右側クロップ (ピクセル)" +CropBottom="下部クロップ (ピクセル)" SwapRedBlue="赤と青を入れ替え" LockX="キャプチャ時にXサーバをロック" IncludeXBorder="Xウインドウの境界を含める" +ExcludeAlpha="アルファなしテクスチャ形式を使用 (Mesaの回避策)" diff --git a/plugins/linux-capture/data/locale/ko-KR.ini b/plugins/linux-capture/data/locale/ko-KR.ini index bdf5e16..2af4dd1 100644 --- a/plugins/linux-capture/data/locale/ko-KR.ini +++ b/plugins/linux-capture/data/locale/ko-KR.ini @@ -12,4 +12,5 @@ CropBottom="아래 자르기 (픽셀)" SwapRedBlue="적청 교환" LockX="캡쳐 시 X 서버를 잠금" IncludeXBorder="X 윈도우 경계를 포함" +ExcludeAlpha="알파가 없는 텍스쳐 형식 사용 (Mesa 방법)" diff --git a/plugins/linux-capture/data/locale/nl-NL.ini b/plugins/linux-capture/data/locale/nl-NL.ini index 698cdd1..629fa5c 100644 --- a/plugins/linux-capture/data/locale/nl-NL.ini +++ b/plugins/linux-capture/data/locale/nl-NL.ini @@ -1,4 +1,4 @@ -X11SharedMemoryScreenInput="Schermcapture (XSHM)" +X11SharedMemoryScreenInput="Schermopname (XSHM)" Screen="Scherm" CaptureCursor="Cursor Opnemen" AdvancedSettings="Geavanceerde instellingen" @@ -12,4 +12,5 @@ CropBottom="Onder Bijsnijden (pixels)" SwapRedBlue="Rood en blauw omwisselen" LockX="X server vergrendelen tijdens het opnemen" IncludeXBorder="Inclusief X-schermranden" +ExcludeAlpha="Gebruik textuurformaat zonder alpha (alternatief voor Mesa)" diff --git a/plugins/linux-capture/data/locale/pl-PL.ini b/plugins/linux-capture/data/locale/pl-PL.ini index 4aceb9c..2353ac4 100644 --- a/plugins/linux-capture/data/locale/pl-PL.ini +++ b/plugins/linux-capture/data/locale/pl-PL.ini @@ -12,4 +12,5 @@ CropBottom="Przytnij od spodu (piksele)" SwapRedBlue="Zamień czerwony i niebieski" LockX="Zablokuj serwer X podczas przechwytywania" IncludeXBorder="Dołącz ramkę okna" +ExcludeAlpha="Użyj tekstur bez kanału alpha (obejście problemu Mesa)" diff --git a/plugins/linux-capture/data/locale/pt-BR.ini b/plugins/linux-capture/data/locale/pt-BR.ini index c2eff60..567edfa 100644 --- a/plugins/linux-capture/data/locale/pt-BR.ini +++ b/plugins/linux-capture/data/locale/pt-BR.ini @@ -12,4 +12,5 @@ CropBottom="Cortar em Baixo (Pixels)" SwapRedBlue="Trocar Vermelho com Azul" LockX="Bloquear servidor X durante a captura" IncludeXBorder="Incluir X Borda" +ExcludeAlpha="Utilizar formato de texture sem Alpha (solução para Mesa)" diff --git a/plugins/linux-capture/data/locale/pt-PT.ini b/plugins/linux-capture/data/locale/pt-PT.ini index 414a66b..7ed2b91 100644 --- a/plugins/linux-capture/data/locale/pt-PT.ini +++ b/plugins/linux-capture/data/locale/pt-PT.ini @@ -1,15 +1,15 @@ -X11SharedMemoryScreenInput="Captura de tela (XSHM)" -Screen="Tela" -CaptureCursor="Capturar o Cursor" +X11SharedMemoryScreenInput="Captura de ecrã (XSHM)" +Screen="Ecrã" +CaptureCursor="Capturar cursor" AdvancedSettings="Definições avançadas" XServer="X Server" XCCapture="Captura de janela (Xcomposite)" Window="Janela" -CropTop="Cortar em Cima (Pixels)" -CropLeft="Cortar à Esquerda (Pixels)" -CropRight="Cortar à direita (Pixels)" -CropBottom="Cortar em Baixo (Pixels)" +CropTop="Cortar em cima (píxeis)" +CropLeft="Cortar à esquerda (píxeis)" +CropRight="Cortar à direita (píxeis)" +CropBottom="Cortar em baixo (píxeis)" SwapRedBlue="Trocar vermelho e azul" -LockX="Bloquear servidor X durante a captura" +LockX="Bloquear X Server durante a captura" IncludeXBorder="Incluir X Border" diff --git a/plugins/linux-capture/data/locale/ro-RO.ini b/plugins/linux-capture/data/locale/ro-RO.ini index 0c0b56e..0ae7367 100644 --- a/plugins/linux-capture/data/locale/ro-RO.ini +++ b/plugins/linux-capture/data/locale/ro-RO.ini @@ -1,15 +1,16 @@ X11SharedMemoryScreenInput="Captură de ecran (XSHM)" Screen="Ecran" CaptureCursor="Capturează cursorul" -AdvancedSettings="Setări Avansate" +AdvancedSettings="Setări avansate" XServer="X Server" -XCCapture="Captură Fereastră (Xcomposite)" +XCCapture="Captură de fereastră (Xcomposite)" Window="Fereastră" -CropTop="Taie Sus (pixeli)" -CropLeft="Taie stânga (pixeli)" -CropRight="Taie Dreapta (pixeli)" -CropBottom="Taie jos (pixeli)" -SwapRedBlue="Schimbă Roșu cu Albastru" -LockX="Blochează server X atunci când se capturează" +CropTop="Trunchiază partea superioară (pixeli)" +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ă" IncludeXBorder="Include marginea cu X" +ExcludeAlpha="Folosește formatul de texturi fără alpha (soluție de evitare Mesa)" diff --git a/plugins/linux-capture/data/locale/ru-RU.ini b/plugins/linux-capture/data/locale/ru-RU.ini index d823fba..4d7e3b5 100644 --- a/plugins/linux-capture/data/locale/ru-RU.ini +++ b/plugins/linux-capture/data/locale/ru-RU.ini @@ -12,4 +12,5 @@ CropBottom="Обрезать снизу (пикселей)" SwapRedBlue="Поменять местами красный и синий" LockX="Блокировать X-сервер при захвате" IncludeXBorder="Включить захват границы" +ExcludeAlpha="Использовать формат текстур без прозрачности (обходной путь для Mesa)" diff --git a/plugins/linux-capture/data/locale/sr-CS.ini b/plugins/linux-capture/data/locale/sr-CS.ini index 6ff0747..912e937 100644 --- a/plugins/linux-capture/data/locale/sr-CS.ini +++ b/plugins/linux-capture/data/locale/sr-CS.ini @@ -12,4 +12,5 @@ CropBottom="Одсеци одоздо (пиксели)" SwapRedBlue="Замени црвену и плаву" LockX="Закључај X сервер у току снимања" IncludeXBorder="Uključujući i X okvir" +ExcludeAlpha="Koristi neprovidni format teksture (zaobilaženje Mesa problema)" diff --git a/plugins/linux-capture/data/locale/sr-SP.ini b/plugins/linux-capture/data/locale/sr-SP.ini index 99ad988..1823224 100644 --- a/plugins/linux-capture/data/locale/sr-SP.ini +++ b/plugins/linux-capture/data/locale/sr-SP.ini @@ -12,4 +12,5 @@ CropBottom="Odseci odozdo (pikseli)" SwapRedBlue="Zameni crvenu i plavu" LockX="Zaključaj X server u toku snimanja" IncludeXBorder="Укључујући и X оквир" +ExcludeAlpha="Користи непровидни формат текстуре (заобилажење Меса проблема)" diff --git a/plugins/linux-capture/data/locale/zh-CN.ini b/plugins/linux-capture/data/locale/zh-CN.ini index a5c40e3..a711eae 100644 --- a/plugins/linux-capture/data/locale/zh-CN.ini +++ b/plugins/linux-capture/data/locale/zh-CN.ini @@ -12,4 +12,5 @@ CropBottom="裁剪下部(像素)" SwapRedBlue="交换红色和蓝色" LockX="当捕获时锁定X server" IncludeXBorder="包括 X 边框" +ExcludeAlpha="使用阿尔法少纹理格式 (Mesa 变通办法)" diff --git a/plugins/linux-capture/xcompcap-main.cpp b/plugins/linux-capture/xcompcap-main.cpp index 42ecd77..f9cf00c 100644 --- a/plugins/linux-capture/xcompcap-main.cpp +++ b/plugins/linux-capture/xcompcap-main.cpp @@ -86,6 +86,9 @@ obs_properties_t *XCompcapMain::properties() obs_properties_add_bool(props, "include_border", obs_module_text("IncludeXBorder")); + obs_properties_add_bool(props, "exclude_alpha", + obs_module_text("ExcludeAlpha")); + return props; } @@ -100,6 +103,7 @@ void XCompcapMain::defaults(obs_data_t *settings) obs_data_set_default_bool(settings, "lock_x", false); obs_data_set_default_bool(settings, "show_cursor", true); obs_data_set_default_bool(settings, "include_border", false); + obs_data_set_default_bool(settings, "exclude_alpha", false); } @@ -142,6 +146,7 @@ struct XCompcapMain_private bool swapRedBlue; bool lockX; bool include_border; + bool exclude_alpha; uint32_t width; uint32_t height; @@ -287,6 +292,7 @@ void XCompcapMain::updateSettings(obs_data_t *settings) 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->exclude_alpha = obs_data_get_bool(settings, "exclude_alpha"); } else { p->win = prevWin; } @@ -323,6 +329,10 @@ void XCompcapMain::updateSettings(obs_data_t *settings) gs_color_format cf = GS_RGBA; + if (p->exclude_alpha) { + cf = GS_BGRX; + } + p->border = attr.border_width; if (p->include_border) { diff --git a/plugins/linux-jack/data/locale/ar-SA.ini b/plugins/linux-jack/data/locale/ar-SA.ini new file mode 100644 index 0000000..6d8e58a --- /dev/null +++ b/plugins/linux-jack/data/locale/ar-SA.ini @@ -0,0 +1,3 @@ +StartJACKServer="بدء خادم JACK" +Channels="عدد القنوات" + diff --git a/plugins/linux-jack/data/locale/eu-ES.ini b/plugins/linux-jack/data/locale/eu-ES.ini index 57fad33..a50dc41 100644 --- a/plugins/linux-jack/data/locale/eu-ES.ini +++ b/plugins/linux-jack/data/locale/eu-ES.ini @@ -1,4 +1,4 @@ -StartJACKServer="Hasi JACK Zerbitzaria" -Channels="Bide Zenbatekoa" -JACKInput="JACK Sarrera Bezeroa" +StartJACKServer="Abiatu JACK zerbitzaria" +Channels="Kanal kopurua" +JACKInput="JACK sarrera bezeroa" diff --git a/plugins/linux-jack/data/locale/he-IL.ini b/plugins/linux-jack/data/locale/he-IL.ini new file mode 100644 index 0000000..830648c --- /dev/null +++ b/plugins/linux-jack/data/locale/he-IL.ini @@ -0,0 +1,4 @@ +StartJACKServer="התחל שרת JACK" +Channels="מספר ערוצים" +JACKInput="לקוח קלט JACK" + diff --git a/plugins/linux-jack/data/locale/hu-HU.ini b/plugins/linux-jack/data/locale/hu-HU.ini index 574097c..1de86ac 100644 --- a/plugins/linux-jack/data/locale/hu-HU.ini +++ b/plugins/linux-jack/data/locale/hu-HU.ini @@ -1,4 +1,4 @@ -StartJACKServer="JACK Kiszolgáló indítása" +StartJACKServer="JACK kiszolgáló indítása" Channels="Csatornák száma" -JACKInput="JACK Csatlakozó Ügyfél" +JACKInput="JACK csatlakozó ügyfél" diff --git a/plugins/linux-jack/data/locale/ja-JP.ini b/plugins/linux-jack/data/locale/ja-JP.ini index a4b34f5..5f8297a 100644 --- a/plugins/linux-jack/data/locale/ja-JP.ini +++ b/plugins/linux-jack/data/locale/ja-JP.ini @@ -1,4 +1,4 @@ -StartJACKServer="JACKサーバーを開始" +StartJACKServer="JACK サーバーを開始" Channels="チャンネル数" -JACKInput="JACK入力クライアント" +JACKInput="JACK 入力クライアント" diff --git a/plugins/linux-jack/data/locale/ro-RO.ini b/plugins/linux-jack/data/locale/ro-RO.ini index 5aff608..24c630f 100644 --- a/plugins/linux-jack/data/locale/ro-RO.ini +++ b/plugins/linux-jack/data/locale/ro-RO.ini @@ -1,4 +1,4 @@ -StartJACKServer="Porneste Serverul JACK" -Channels="Numar de canale" -JACKInput="Clientul de input JACK" +StartJACKServer="Pornește serverul JACK" +Channels="Număr de canale" +JACKInput="Client de intrare JACK" diff --git a/plugins/linux-pulseaudio/data/locale/da-DK.ini b/plugins/linux-pulseaudio/data/locale/da-DK.ini index 54fd217..ba09e5a 100644 --- a/plugins/linux-pulseaudio/data/locale/da-DK.ini +++ b/plugins/linux-pulseaudio/data/locale/da-DK.ini @@ -1,4 +1,4 @@ -PulseInput="Indfang Lyd ind (PulseAudio)" -PulseOutput="Indfang Lyd Ud (PulseAudio)" +PulseInput="Indfang lyd ind (PulseAudio)" +PulseOutput="Indfang lyd Ud (PulseAudio)" Device="Enhed" diff --git a/plugins/linux-pulseaudio/data/locale/eu-ES.ini b/plugins/linux-pulseaudio/data/locale/eu-ES.ini index 8f4e5c0..767a88a 100644 --- a/plugins/linux-pulseaudio/data/locale/eu-ES.ini +++ b/plugins/linux-pulseaudio/data/locale/eu-ES.ini @@ -1,4 +1,4 @@ -PulseInput="Audio Sarrera Harpena (PulseAudio)" -PulseOutput="Audio Irteera Harpena (PulseAudio)" +PulseInput="Audioa kapturatzeko gailua (PulseAudio)" +PulseOutput="Audio irteeraren kaptura (PulseAudio)" Device="Gailua" diff --git a/plugins/linux-pulseaudio/data/locale/fr-FR.ini b/plugins/linux-pulseaudio/data/locale/fr-FR.ini index bce9168..152b52a 100644 --- a/plugins/linux-pulseaudio/data/locale/fr-FR.ini +++ b/plugins/linux-pulseaudio/data/locale/fr-FR.ini @@ -1,4 +1,4 @@ -PulseInput="Capture d'Audio Entrant (PulseAudio)" -PulseOutput="Capture d'Audio Sortant (PulseAudio)" +PulseInput="Capture de l'audio entrant (PulseAudio)" +PulseOutput="Capture de l'audio sortant (PulseAudio)" Device="Périphérique" diff --git a/plugins/linux-pulseaudio/data/locale/he-IL.ini b/plugins/linux-pulseaudio/data/locale/he-IL.ini new file mode 100644 index 0000000..294a21a --- /dev/null +++ b/plugins/linux-pulseaudio/data/locale/he-IL.ini @@ -0,0 +1,4 @@ +PulseInput="לכידת קלט שמע (PulseAudio)" +PulseOutput="לכידת פלט שמע (PulseAudio)" +Device="התקן" + diff --git a/plugins/linux-pulseaudio/data/locale/hu-HU.ini b/plugins/linux-pulseaudio/data/locale/hu-HU.ini index d9aa15c..b17b707 100644 --- a/plugins/linux-pulseaudio/data/locale/hu-HU.ini +++ b/plugins/linux-pulseaudio/data/locale/hu-HU.ini @@ -1,4 +1,4 @@ -PulseInput="Bemeneti Hangrögzítő (PulseAudio)" -PulseOutput="Kimeneti Hangrögzítő (PulseAudio)" +PulseInput="Bemeneti hangrögzítő (PulseAudio)" +PulseOutput="Kimeneti hangrögzítő (PulseAudio)" Device="Eszköz" diff --git a/plugins/linux-pulseaudio/data/locale/nl-NL.ini b/plugins/linux-pulseaudio/data/locale/nl-NL.ini index 10c8052..3d154e1 100644 --- a/plugins/linux-pulseaudio/data/locale/nl-NL.ini +++ b/plugins/linux-pulseaudio/data/locale/nl-NL.ini @@ -1,4 +1,4 @@ -PulseInput="Audioinvoer-capture (PulseAudio)" -PulseOutput="Audiouitvoer-capture (PulseAudio)" +PulseInput="Audioinvoer-opname (PulseAudio)" +PulseOutput="Audiouitvoer-opname (PulseAudio)" Device="Apparaat" diff --git a/plugins/linux-pulseaudio/data/locale/ro-RO.ini b/plugins/linux-pulseaudio/data/locale/ro-RO.ini index af1045c..2b6ec2e 100644 --- a/plugins/linux-pulseaudio/data/locale/ro-RO.ini +++ b/plugins/linux-pulseaudio/data/locale/ro-RO.ini @@ -1,4 +1,4 @@ -PulseInput="Captură Intrare Audio (PulseAudio)" -PulseOutput="Captură Ieşire Audio (PulseAudio)" +PulseInput="Captură de intrare audio (PulseAudio)" +PulseOutput="Captură de ieșire audio (PulseAudio)" Device="Dispozitiv" diff --git a/plugins/linux-pulseaudio/data/locale/zh-CN.ini b/plugins/linux-pulseaudio/data/locale/zh-CN.ini index 216daf7..0cfb9f7 100644 --- a/plugins/linux-pulseaudio/data/locale/zh-CN.ini +++ b/plugins/linux-pulseaudio/data/locale/zh-CN.ini @@ -1,4 +1,4 @@ -PulseInput="音频输入捕获(脉冲音频)" -PulseOutput="音频输出捕获(脉冲音频)" +PulseInput="音频输入捕获(PulseAudio)" +PulseOutput="音频输出捕获(PulseAudio)" Device="设备" diff --git a/plugins/linux-v4l2/data/locale/cs-CZ.ini b/plugins/linux-v4l2/data/locale/cs-CZ.ini index 7384838..ad33b44 100644 --- a/plugins/linux-v4l2/data/locale/cs-CZ.ini +++ b/plugins/linux-v4l2/data/locale/cs-CZ.ini @@ -1,11 +1,11 @@ -V4L2Input="Zařízení pro záznam (V4L2)" +V4L2Input="Zaznamenávací zařízení obrazu (V4L2)" Device="Zařízení" Input="Vstup" VideoFormat="Formát videa" VideoStandard="Standard videa" DVTiming="Časování DV" Resolution="Rozlišení" -FrameRate="Frekvence snímkování" +FrameRate="Snímkovací frekvence" LeaveUnchanged="Ponechat nezměněné" UseBuffering="Použít vyrovnávací paměť" diff --git a/plugins/linux-v4l2/data/locale/eu-ES.ini b/plugins/linux-v4l2/data/locale/eu-ES.ini index f6ade9e..3769275 100644 --- a/plugins/linux-v4l2/data/locale/eu-ES.ini +++ b/plugins/linux-v4l2/data/locale/eu-ES.ini @@ -1,11 +1,11 @@ -V4L2Input="Bideo Harpen Gailua (V4L2)" +V4L2Input="Bideoa kapturatzeko gailua (V4L2)" Device="Gailua" Input="Sarrera" -VideoFormat="Bideo Heuskarria" +VideoFormat="Bideo formatua" VideoStandard="Bideo Estandarra" -DVTiming="DV Denborapena" +DVTiming="DV sinkronizazioa" Resolution="Bereizmena" -FrameRate="Frame Neurria" -LeaveUnchanged="Utzi Aldatugabe" -UseBuffering="Erabili Bufferreratzea" +FrameRate="Fotograma emaria" +LeaveUnchanged="Utzi aldatu gabe" +UseBuffering="Erabili bufferreratzea" diff --git a/plugins/linux-v4l2/data/locale/he-IL.ini b/plugins/linux-v4l2/data/locale/he-IL.ini new file mode 100644 index 0000000..f68d291 --- /dev/null +++ b/plugins/linux-v4l2/data/locale/he-IL.ini @@ -0,0 +1,11 @@ +V4L2Input="התקן לכידת וידאו (V4L2)" +Device="התקן" +Input="קלט" +VideoFormat="פורמט וידאו" +VideoStandard="תקן וידאו" +DVTiming="תזמון DV" +Resolution="רזולוציה" +FrameRate="קצב פריימים" +LeaveUnchanged="ללא שינוי" +UseBuffering="השתמש באוגר" + diff --git a/plugins/linux-v4l2/data/locale/hu-HU.ini b/plugins/linux-v4l2/data/locale/hu-HU.ini index 1f24510..1f2db15 100644 --- a/plugins/linux-v4l2/data/locale/hu-HU.ini +++ b/plugins/linux-v4l2/data/locale/hu-HU.ini @@ -1,11 +1,11 @@ -V4L2Input="Videorögzítő Eszköz (V4L2)" +V4L2Input="Videorögzítő eszköz (V4L2)" Device="Eszköz" Input="Bemenet" -VideoFormat="Videó Formátum" -VideoStandard="Video Szabvány" -DVTiming="DV Időzítés" +VideoFormat="Videó formátum" +VideoStandard="Video szabvány" +DVTiming="DV időzítés" Resolution="Felbontás" FrameRate="Képkockasebesség" -LeaveUnchanged="Változatlanul Hagyni" -UseBuffering="Pufferelés Használata" +LeaveUnchanged="Változatlanul hagyni" +UseBuffering="Pufferelés használata" diff --git a/plugins/linux-v4l2/data/locale/pt-PT.ini b/plugins/linux-v4l2/data/locale/pt-PT.ini index 14a3057..24032ad 100644 --- a/plugins/linux-v4l2/data/locale/pt-PT.ini +++ b/plugins/linux-v4l2/data/locale/pt-PT.ini @@ -5,7 +5,7 @@ VideoFormat="Formato de vídeo" VideoStandard="Padrão de vídeo" DVTiming="Sincronismo DV" Resolution="Resolução" -FrameRate="Taxa de quadros" +FrameRate="Taxa de fotogramas" LeaveUnchanged="Deixar inalterado" UseBuffering="Utilizar Buffering" diff --git a/plugins/linux-v4l2/data/locale/ro-RO.ini b/plugins/linux-v4l2/data/locale/ro-RO.ini index 80245c1..77481d0 100644 --- a/plugins/linux-v4l2/data/locale/ro-RO.ini +++ b/plugins/linux-v4l2/data/locale/ro-RO.ini @@ -1,11 +1,11 @@ -V4L2Input="Dispozitiv de Captură Video (V4L2)" +V4L2Input="Dispozitiv de captură video (V4L2)" Device="Dispozitiv" Input="Intrare" -VideoFormat="Format Video" -VideoStandard="Standard Video" +VideoFormat="Format video" +VideoStandard="Standard video" DVTiming="Sincronizare DV" -Resolution="Rezoluţie" -FrameRate="Rata de cadru" +Resolution="Rezoluție" +FrameRate="Frecvență de cadre" LeaveUnchanged="Lasă neschimbat" -UseBuffering="Utilizaţi Tampon/Buffer" +UseBuffering="Folosește buffering" diff --git a/plugins/linux-v4l2/data/locale/sv-SE.ini b/plugins/linux-v4l2/data/locale/sv-SE.ini index 979efee..25b0486 100644 --- a/plugins/linux-v4l2/data/locale/sv-SE.ini +++ b/plugins/linux-v4l2/data/locale/sv-SE.ini @@ -1,4 +1,4 @@ -V4L2Input="Videoinmatningssenhet (V4L2)" +V4L2Input="Videoinspelningsenhet (V4L2)" Device="Enhet" Input="Inmatning" VideoFormat="Videoformat" diff --git a/plugins/mac-avcapture/data/locale/ar-SA.ini b/plugins/mac-avcapture/data/locale/ar-SA.ini index 72ff0dc..4fecc55 100644 --- a/plugins/mac-avcapture/data/locale/ar-SA.ini +++ b/plugins/mac-avcapture/data/locale/ar-SA.ini @@ -1,4 +1,7 @@ +AVCapture="جهاز التقاط الفيديو" Device="الجهاز" UsePreset="استعمال عارض ضوئي" Preset="العارض الضوئي" +Buffering="استخدام التخزين المؤقت Buffering" +FrameRate="معدل الإطار" diff --git a/plugins/mac-avcapture/data/locale/cs-CZ.ini b/plugins/mac-avcapture/data/locale/cs-CZ.ini index 40315ca..ad03e4f 100644 --- a/plugins/mac-avcapture/data/locale/cs-CZ.ini +++ b/plugins/mac-avcapture/data/locale/cs-CZ.ini @@ -1,4 +1,4 @@ -AVCapture="Zaznamenávací zařízení" +AVCapture="Zaznamenávací zařízení obrazu" Device="Zařízení" UsePreset="Použít předvolbu" Preset="Předvolba" diff --git a/plugins/mac-avcapture/data/locale/da-DK.ini b/plugins/mac-avcapture/data/locale/da-DK.ini index 72756cb..f1eff88 100644 --- a/plugins/mac-avcapture/data/locale/da-DK.ini +++ b/plugins/mac-avcapture/data/locale/da-DK.ini @@ -3,4 +3,11 @@ Device="Enhed" UsePreset="Brug forudindstilling" Preset="Forudindstilling" Buffering="Brug buffering" +FrameRate="Billedfrekvens" +InputFormat="Input format" +ColorSpace="Farverum" +VideoRange.Partial="Delvis" +VideoRange.Full="Fuld" +Auto="Auto" +Unknown="Ukendt($1)" diff --git a/plugins/mac-avcapture/data/locale/eu-ES.ini b/plugins/mac-avcapture/data/locale/eu-ES.ini index 60c0e59..0ae77a4 100644 --- a/plugins/mac-avcapture/data/locale/eu-ES.ini +++ b/plugins/mac-avcapture/data/locale/eu-ES.ini @@ -1,14 +1,14 @@ -AVCapture="Bideo Harpen Gailua" +AVCapture="Bideoa kapturatzeko gailua" Device="Gailua" -UsePreset="Erabili Aurrezarpena" +UsePreset="Erabili aurrezarpena" Preset="Aurrezarpena" -Buffering="Erabili Bufferreratzea" -FrameRate="Frame neurria" -InputFormat="Sarrera heuskarria" -ColorSpace="Margo tartea" -VideoRange="Bideo eremua" +Buffering="Erabili bufferreratzea" +FrameRate="Fotograma emaria" +InputFormat="Sarrera formatua" +ColorSpace="Kolore espazioa" +VideoRange="Bideo-bitartea" VideoRange.Partial="Partziala" VideoRange.Full="Osoa" -Auto="Berez" +Auto="Auto" Unknown="Ezezaguna ($1)" diff --git a/plugins/mac-avcapture/data/locale/gl-ES.ini b/plugins/mac-avcapture/data/locale/gl-ES.ini index 8d4dce2..e97cc2f 100644 --- a/plugins/mac-avcapture/data/locale/gl-ES.ini +++ b/plugins/mac-avcapture/data/locale/gl-ES.ini @@ -3,4 +3,12 @@ Device="Dispositivo" UsePreset="Usar valores predefinidos" Preset="Valores predefinidos" Buffering="Utilizar o almacenamento no búfer" +FrameRate="Velocidade de fotogramas" +InputFormat="Formato de entrada" +ColorSpace="Espazo de cor" +VideoRange="Rango de video" +VideoRange.Partial="Parcial" +VideoRange.Full="Completo" +Auto="Automático" +Unknown="Descoñecido ($1)" diff --git a/plugins/mac-avcapture/data/locale/hu-HU.ini b/plugins/mac-avcapture/data/locale/hu-HU.ini index a73129b..c5a91bd 100644 --- a/plugins/mac-avcapture/data/locale/hu-HU.ini +++ b/plugins/mac-avcapture/data/locale/hu-HU.ini @@ -1,10 +1,10 @@ AVCapture="Videorögzítő eszköz" Device="Eszköz" -UsePreset="Készlet Használata" +UsePreset="Készlet használata" Preset="Készlet" -Buffering="Pufferelés Használata" +Buffering="Pufferelés használata" FrameRate="Képkockasebesség" -InputFormat="Bemeneti Formátum" +InputFormat="Bemeneti formátum" ColorSpace="Színtér" VideoRange="Videotartomány" VideoRange.Partial="Részleges" diff --git a/plugins/mac-avcapture/data/locale/pt-BR.ini b/plugins/mac-avcapture/data/locale/pt-BR.ini index 6348a6e..2966cfb 100644 --- a/plugins/mac-avcapture/data/locale/pt-BR.ini +++ b/plugins/mac-avcapture/data/locale/pt-BR.ini @@ -3,4 +3,12 @@ Device="Dispositivo" UsePreset="Usar Predefinição" Preset="Predefinição" Buffering="Utilizar Buffering" +FrameRate="Taxa de Frame" +InputFormat="Formato de Entrada" +ColorSpace="Espaço de Cor" +VideoRange="Intervalo de Vídeo" +VideoRange.Partial="Parcial" +VideoRange.Full="Completo" +Auto="Auto" +Unknown="Desconhecido ($1)" diff --git a/plugins/mac-avcapture/data/locale/pt-PT.ini b/plugins/mac-avcapture/data/locale/pt-PT.ini index 179e98e..6c9b2c9 100644 --- a/plugins/mac-avcapture/data/locale/pt-PT.ini +++ b/plugins/mac-avcapture/data/locale/pt-PT.ini @@ -1,6 +1,6 @@ AVCapture="Dispositivo de captura de vídeo" Device="Dispositivo" -UsePreset="Usar predefinição" +UsePreset="Utilizar predefinição" Preset="Predefinição" Buffering="Utilizar Buffering" diff --git a/plugins/mac-avcapture/data/locale/ro-RO.ini b/plugins/mac-avcapture/data/locale/ro-RO.ini index 997c270..a997f67 100644 --- a/plugins/mac-avcapture/data/locale/ro-RO.ini +++ b/plugins/mac-avcapture/data/locale/ro-RO.ini @@ -1,14 +1,14 @@ AVCapture="Dispozitiv de captură video" Device="Dispozitiv" -UsePreset="Folosiţi Presetat" -Preset="Presetat" -Buffering="Utilizaţi Tampon/Buffer" -FrameRate="Rata de cadru" +UsePreset="Folosește presetare" +Preset="Presetare" +Buffering="Folosește buffering" +FrameRate="Frecvență de cadre" InputFormat="Format de intrare" -ColorSpace="Spaţiul de culoare" -VideoRange="Gama Video" -VideoRange.Partial="Parţial" -VideoRange.Full="Full" +ColorSpace="Spațiu de culori" +VideoRange="Gamă video" +VideoRange.Partial="Parțială" +VideoRange.Full="Completă" Auto="Auto" Unknown="Necunoscut ($1)" diff --git a/plugins/mac-avcapture/data/locale/sv-SE.ini b/plugins/mac-avcapture/data/locale/sv-SE.ini index ec5d6b7..972b58e 100644 --- a/plugins/mac-avcapture/data/locale/sv-SE.ini +++ b/plugins/mac-avcapture/data/locale/sv-SE.ini @@ -3,4 +3,12 @@ Device="Enhet" UsePreset="Använd förinställning" Preset="Förinställning" Buffering="Använd buffer" +FrameRate="Bildfrekvens" +InputFormat="Inmatningsformat" +ColorSpace="Färgrymd" +VideoRange="Videointervall" +VideoRange.Partial="Partiell" +VideoRange.Full="Full" +Auto="Automatisk" +Unknown="Okänd ($1)" diff --git a/plugins/mac-avcapture/data/locale/tr-TR.ini b/plugins/mac-avcapture/data/locale/tr-TR.ini index 75d490b..5cf8767 100644 --- a/plugins/mac-avcapture/data/locale/tr-TR.ini +++ b/plugins/mac-avcapture/data/locale/tr-TR.ini @@ -3,4 +3,11 @@ Device="Aygıt" UsePreset="Ön Tanımlı Kullan" Preset="Ön Tanımlı" Buffering="Arabelleğe Almayı Kullan" +FrameRate="Kare hızı" +ColorSpace="Renk alanı" +VideoRange="Video aralığı" +VideoRange.Partial="Kısmi" +VideoRange.Full="Tam" +Auto="Otomatik" +Unknown="Bilinmiyor (%1)" diff --git a/plugins/mac-capture/data/locale/ar-SA.ini b/plugins/mac-capture/data/locale/ar-SA.ini index 18c7dd7..c100fa6 100644 --- a/plugins/mac-capture/data/locale/ar-SA.ini +++ b/plugins/mac-capture/data/locale/ar-SA.ini @@ -5,4 +5,17 @@ CoreAudio.Device.Default="الافتراضي" DisplayCapture="التقاط الشاشة" DisplayCapture.Display="عرض" DisplayCapture.ShowCursor="إظهار المؤشر" +WindowCapture="التقاط نافذة" +WindowCapture.ShowShadow="إظهار ظلال النافذة" +WindowUtils.Window="النافذة" +WindowUtils.ShowEmptyNames="إظهار نوافذ بأسماء فارغة" +CropMode="إقتطاع" +CropMode.None="لا شيء" +CropMode.Manual="يدوي" +CropMode.ToWindow="للنافذة" +CropMode.ToWindowAndManual="يدوي وللنافذة" +Crop.origin.x="قطع لليسار" +Crop.origin.y="قطع للأعلى" +Crop.size.width="قطع لليمين" +Crop.size.height="قطع للأسفل" diff --git a/plugins/mac-capture/data/locale/bg-BG.ini b/plugins/mac-capture/data/locale/bg-BG.ini new file mode 100644 index 0000000..f56493e --- /dev/null +++ b/plugins/mac-capture/data/locale/bg-BG.ini @@ -0,0 +1,19 @@ +CoreAudio.InputCapture="Вътрешно записване на аудио" +CoreAudio.OutputCapture="Външно записване на аудио" +CoreAudio.Device="Устройство" +CoreAudio.Device.Default="По подразбиране" +DisplayCapture="Заснемане на екрана" +DisplayCapture.Display="Дисплей" +DisplayCapture.ShowCursor="Показвай курсора" +WindowCapture="Прозорец на заснемане" +WindowCapture.ShowShadow="Показвай Windows сянка" +WindowUtils.Window="Windows" +WindowUtils.ShowEmptyNames="Показвай Windows с празни имена" +CropMode="Изрежи" +CropMode.None="Без" +CropMode.Manual="Ръчно" +Crop.origin.x="Изрежи отляво" +Crop.origin.y="Изрежи отгоре" +Crop.size.width="Изрежи отдясно" +Crop.size.height="Изрежи отдолу" + diff --git a/plugins/mac-capture/data/locale/da-DK.ini b/plugins/mac-capture/data/locale/da-DK.ini index df86f32..b784969 100644 --- a/plugins/mac-capture/data/locale/da-DK.ini +++ b/plugins/mac-capture/data/locale/da-DK.ini @@ -1,9 +1,9 @@ -CoreAudio.InputCapture="Indfang Lyd Ind" -CoreAudio.OutputCapture="Indfang Lyd Ud" +CoreAudio.InputCapture="Indfang lyd ind" +CoreAudio.OutputCapture="Indfang lyd ud" CoreAudio.Device="Enhed" CoreAudio.Device.Default="Standard" -DisplayCapture="Indfang Display" -DisplayCapture.Display="Display" +DisplayCapture="Skærm optag" +DisplayCapture.Display="Skærm" DisplayCapture.ShowCursor="Vis markøren" WindowCapture="Vindue indfang" WindowCapture.ShowShadow="Vis vinduesskygge" diff --git a/plugins/mac-capture/data/locale/eu-ES.ini b/plugins/mac-capture/data/locale/eu-ES.ini index a230fc8..98d163e 100644 --- a/plugins/mac-capture/data/locale/eu-ES.ini +++ b/plugins/mac-capture/data/locale/eu-ES.ini @@ -1,12 +1,12 @@ -CoreAudio.InputCapture="Audio Sarrera Harpena" -CoreAudio.OutputCapture="Audio Irteera Harpena" +CoreAudio.InputCapture="Audio sarreraren kaptura" +CoreAudio.OutputCapture="Audio irteeraren kaptura" CoreAudio.Device="Gailua" CoreAudio.Device.Default="Berezkoa" DisplayCapture="Erakusleiho Harpena" -DisplayCapture.Display="Erakusleihoa" -DisplayCapture.ShowCursor="Erakutsi Kurtsorea" -WindowCapture="Leiho Harpena" -WindowCapture.ShowShadow="Erakutsi Leiho Itzala" +DisplayCapture.Display="Pantaila" +DisplayCapture.ShowCursor="Erakutsi kurtsorea" +WindowCapture="Leiho-kaptura" +WindowCapture.ShowShadow="Erakutsi leihoaren itzala" WindowUtils.Window="Leihoa" WindowUtils.ShowEmptyNames="Erakutsi izen gabeko Leihoak" CropMode="Moztu" diff --git a/plugins/mac-capture/data/locale/fr-FR.ini b/plugins/mac-capture/data/locale/fr-FR.ini index 74a71f4..659dbc5 100644 --- a/plugins/mac-capture/data/locale/fr-FR.ini +++ b/plugins/mac-capture/data/locale/fr-FR.ini @@ -1,15 +1,15 @@ -CoreAudio.InputCapture="Capture d'Audio Entrant" -CoreAudio.OutputCapture="Capture d'Audio Sortant" -CoreAudio.Device="Appareil" +CoreAudio.InputCapture="Capture de l'audio entrant" +CoreAudio.OutputCapture="Capture de l'audio sortant" +CoreAudio.Device="Périphérique" CoreAudio.Device.Default="Par défaut" -DisplayCapture="Afficher la Capture" +DisplayCapture="Afficher la capture" DisplayCapture.Display="Affichage" DisplayCapture.ShowCursor="Afficher le curseur" -WindowCapture="Capture de Fenêtre" +WindowCapture="Capture de la fenêtre" WindowCapture.ShowShadow="Afficher l'ombre de la fenêtre" WindowUtils.Window="Fenêtre" WindowUtils.ShowEmptyNames="Afficher les fenêtres avec des noms vides" -CropMode="Découper" +CropMode="Rogner" CropMode.None="Aucune" CropMode.Manual="Manuel" CropMode.ToWindow="À la fenêtre" diff --git a/plugins/mac-capture/data/locale/hu-HU.ini b/plugins/mac-capture/data/locale/hu-HU.ini index 9066e2f..b4420b4 100644 --- a/plugins/mac-capture/data/locale/hu-HU.ini +++ b/plugins/mac-capture/data/locale/hu-HU.ini @@ -1,11 +1,11 @@ -CoreAudio.InputCapture="Bemeneti Hangrögzítés" -CoreAudio.OutputCapture="Kimeneti Hangrögzítés" +CoreAudio.InputCapture="Bemeneti hangrögzítés" +CoreAudio.OutputCapture="Kimeneti hangrögzítés" CoreAudio.Device="Eszköz" CoreAudio.Device.Default="Alapértelmezett" -DisplayCapture="Kijelző Felvétel" +DisplayCapture="Kijelző felvétel" DisplayCapture.Display="Kijelző" -DisplayCapture.ShowCursor="Kurzor Megjelenítése" -WindowCapture="Ablak Felvétel" +DisplayCapture.ShowCursor="Kurzor megjelenítése" +WindowCapture="Ablak felvétel" WindowCapture.ShowShadow="Ablak árnyékának megjelenítése" WindowUtils.Window="Ablak" WindowUtils.ShowEmptyNames="Ablakok üres névvel való megjelenítése" @@ -13,7 +13,7 @@ CropMode="Vágás" CropMode.None="Egyik sem" CropMode.Manual="Kézikönyv" CropMode.ToWindow="Ablakhoz" -CropMode.ToWindowAndManual="Ablakhoz és Kézikönyvhöz" +CropMode.ToWindowAndManual="Ablakhoz és kézikönyvhöz" Crop.origin.x="Levágás balra" Crop.origin.y="Levágás fent" Crop.size.width="Levágás jobbra" diff --git a/plugins/mac-capture/data/locale/nl-NL.ini b/plugins/mac-capture/data/locale/nl-NL.ini index 2c540af..56210fd 100644 --- a/plugins/mac-capture/data/locale/nl-NL.ini +++ b/plugins/mac-capture/data/locale/nl-NL.ini @@ -1,8 +1,8 @@ -CoreAudio.InputCapture="Audioinvoer Capture" -CoreAudio.OutputCapture="Audiouitvoer Capture" +CoreAudio.InputCapture="Audioinvoer Opname" +CoreAudio.OutputCapture="Audiouitvoer Opname" CoreAudio.Device="Apparaat" CoreAudio.Device.Default="Standaardinstellingen" -DisplayCapture="Beeldschermcapture" +DisplayCapture="Beeldschermopname" DisplayCapture.Display="Beeldscherm" DisplayCapture.ShowCursor="Cursor Weergeven" WindowCapture="Venstercapture" diff --git a/plugins/mac-capture/data/locale/pt-PT.ini b/plugins/mac-capture/data/locale/pt-PT.ini index ab3c772..f104179 100644 --- a/plugins/mac-capture/data/locale/pt-PT.ini +++ b/plugins/mac-capture/data/locale/pt-PT.ini @@ -1,10 +1,10 @@ CoreAudio.InputCapture="Captura de entrada de áudio" CoreAudio.OutputCapture="Captura de saída de áudio" CoreAudio.Device="Dispositivo" -CoreAudio.Device.Default="Predefinição" -DisplayCapture="Captura de Ecrã" +CoreAudio.Device.Default="Predefinido" +DisplayCapture="Captura de ecrã" DisplayCapture.Display="Ecrã" -DisplayCapture.ShowCursor="Mostrar o Cursor" +DisplayCapture.ShowCursor="Mostrar cursor" WindowCapture="Captura de janela" WindowCapture.ShowShadow="Mostrar sombra da janela" WindowUtils.Window="Janela" diff --git a/plugins/mac-capture/data/locale/ro-RO.ini b/plugins/mac-capture/data/locale/ro-RO.ini index a1cf8b3..3f07ce8 100644 --- a/plugins/mac-capture/data/locale/ro-RO.ini +++ b/plugins/mac-capture/data/locale/ro-RO.ini @@ -1,21 +1,21 @@ CoreAudio.InputCapture="Captură de intrare audio" -CoreAudio.OutputCapture="Captură de Ieşire Audio" +CoreAudio.OutputCapture="Captură de ieșire audio" CoreAudio.Device="Dispozitiv" -CoreAudio.Device.Default="Prestabilit" -DisplayCapture="Captura de ecran" -DisplayCapture.Display="Afişare" +CoreAudio.Device.Default="Implicit" +DisplayCapture="Captură de display" +DisplayCapture.Display="Display" DisplayCapture.ShowCursor="Arată cursorul" -WindowCapture="Captura Fereastră" -WindowCapture.ShowShadow="Arată umbra fereastrei" +WindowCapture="Captură de fereastră" +WindowCapture.ShowShadow="Arată umbra ferestrei" WindowUtils.Window="Fereastră" -WindowUtils.ShowEmptyNames="Arată ferestrele cu numele gol" -CropMode="Taie (redimensionează prin tăierea imaginii)" -CropMode.None="Nici unul" +WindowUtils.ShowEmptyNames="Arată ferestrele cu numele goale" +CropMode="Trunchiază" +CropMode.None="Niciunul" CropMode.Manual="Manual" CropMode.ToWindow="La fereastră" -CropMode.ToWindowAndManual="La fereastră și Manual" -Crop.origin.x="Taie stânga" -Crop.origin.y="Taie sus" -Crop.size.width="Taie dreapta" -Crop.size.height="Taie jos" +CropMode.ToWindowAndManual="La fereastră și manual" +Crop.origin.x="Trunchiază stânga" +Crop.origin.y="Trunchiază partea superioară" +Crop.size.width="Trunchiază dreapta" +Crop.size.height="Trunchiază partea inferioară" diff --git a/plugins/mac-capture/data/locale/sv-SE.ini b/plugins/mac-capture/data/locale/sv-SE.ini index e1c95e3..b6ffcf7 100644 --- a/plugins/mac-capture/data/locale/sv-SE.ini +++ b/plugins/mac-capture/data/locale/sv-SE.ini @@ -1,5 +1,5 @@ CoreAudio.InputCapture="Ljudinmatningsenhet" -CoreAudio.OutputCapture="Ljudppspelningssenhet" +CoreAudio.OutputCapture="Ljuduppspelningssenhet" CoreAudio.Device="Enhet" CoreAudio.Device.Default="Standard" DisplayCapture="Bildskärmskälla" diff --git a/plugins/mac-syphon/data/locale/ar-SA.ini b/plugins/mac-syphon/data/locale/ar-SA.ini new file mode 100644 index 0000000..55a9c1f --- /dev/null +++ b/plugins/mac-syphon/data/locale/ar-SA.ini @@ -0,0 +1,13 @@ +Syphon="التقاط لعبة (Syphon)" +Source="مصدر" +LaunchSyphonInject="بدء تشغيل حقن SyphonInject" +Inject="حقن" +Application="التطبيق" +SyphonLicense="رخصة Syphon" +Crop="اقتصاص" +Crop.origin.x="قص لليسار" +Crop.origin.y="قص للأعلى" +Crop.size.width="قص لليمين" +Crop.size.height="قص للأسفل" +AllowTransparency="السماح بالشفافية" + diff --git a/plugins/mac-syphon/data/locale/eu-ES.ini b/plugins/mac-syphon/data/locale/eu-ES.ini index b81c7f2..1a4c5f5 100644 --- a/plugins/mac-syphon/data/locale/eu-ES.ini +++ b/plugins/mac-syphon/data/locale/eu-ES.ini @@ -1,13 +1,13 @@ -Syphon="Jolas Harpena (Syphon)" +Syphon="Jokoen kaptura (Syphon)" Source="Iturburua" LaunchSyphonInject="Abiarazi SyphonInject" -Inject="Inject" +Inject="Injektatu" Application="Aplikazioa" -SyphonLicense="Syphon Baimena" +SyphonLicense="Syphon lizentzia" Crop="Moztu" Crop.origin.x="Moztu ezkerra" Crop.origin.y="Moztu goia" Crop.size.width="Moztu eskuina" Crop.size.height="Moztu behea" -AllowTransparency="Ahalbidetu Gardentasuna" +AllowTransparency="Onartu gardentasuna" diff --git a/plugins/mac-syphon/data/locale/hu-HU.ini b/plugins/mac-syphon/data/locale/hu-HU.ini index 7d566e5..b920289 100644 --- a/plugins/mac-syphon/data/locale/hu-HU.ini +++ b/plugins/mac-syphon/data/locale/hu-HU.ini @@ -1,13 +1,13 @@ -Syphon="Játék Felvétel (Syphon)" +Syphon="Játék felvétel (Syphon)" Source="Forrás" -LaunchSyphonInject="SyphonInject Indítása" +LaunchSyphonInject="SyphonInject indítása" Inject="Fecskendezés" Application="Alkalmazás" -SyphonLicense="Syphon Engedély" +SyphonLicense="Syphon engedély" Crop="Vágás" Crop.origin.x="Levágás balra" Crop.origin.y="Levágás fent" Crop.size.width="Levágás jobbra" Crop.size.height="Levágás alul" -AllowTransparency="Áttetszőség Engedélyezése" +AllowTransparency="Áttetszőség engedélyezése" diff --git a/plugins/mac-syphon/data/locale/ja-JP.ini b/plugins/mac-syphon/data/locale/ja-JP.ini index dd1784b..47013a2 100644 --- a/plugins/mac-syphon/data/locale/ja-JP.ini +++ b/plugins/mac-syphon/data/locale/ja-JP.ini @@ -3,7 +3,7 @@ Source="ソース" LaunchSyphonInject="サイフォンインジェクトを起動する" Inject="インジェクト" Application="アプリケーション" -SyphonLicense="サイフォン ライセンス" +SyphonLicense="サイフォンライセンス" Crop="クロップ" Crop.origin.x="左をクロップ" Crop.origin.y="上をクロップ" diff --git a/plugins/mac-syphon/data/locale/ro-RO.ini b/plugins/mac-syphon/data/locale/ro-RO.ini index dcc996e..9cc2423 100644 --- a/plugins/mac-syphon/data/locale/ro-RO.ini +++ b/plugins/mac-syphon/data/locale/ro-RO.ini @@ -1,13 +1,13 @@ -Syphon="Captura Joc (Syphon)" +Syphon="Captură de joc (Syphon)" Source="Sursă" -LaunchSyphonInject="Lansare SyphonInject" +LaunchSyphonInject="Lansează SyphonInject" Inject="Injectează" -Application="Aplicaţie" -SyphonLicense="Licenţă Syphon" -Crop="Taie (redimensionează prin tăierea imaginii)" -Crop.origin.x="Taie stânga" -Crop.origin.y="Taie sus" -Crop.size.width="Taie dreapta" -Crop.size.height="Taie jos" -AllowTransparency="Permite transparenţa" +Application="Aplicație" +SyphonLicense="Licență Syphon" +Crop="Trunchiază" +Crop.origin.x="Trunchiază stânga" +Crop.origin.y="Trunchiază partea superioară" +Crop.size.width="Trunchiază dreapta" +Crop.size.height="Trunchiază partea inferioară" +AllowTransparency="Permite transparență" diff --git a/plugins/mac-syphon/data/locale/sv-SE.ini b/plugins/mac-syphon/data/locale/sv-SE.ini index e455081..7f37426 100644 --- a/plugins/mac-syphon/data/locale/sv-SE.ini +++ b/plugins/mac-syphon/data/locale/sv-SE.ini @@ -9,5 +9,5 @@ Crop.origin.x="Beskär vänster" Crop.origin.y="Beskär topp" Crop.size.width="Beskär höger" Crop.size.height="Beskär botten" -AllowTransparency="Tillåt opacitet" +AllowTransparency="Tillåt transparens" diff --git a/plugins/mac-vth264/data/locale/ar-SA.ini b/plugins/mac-vth264/data/locale/ar-SA.ini new file mode 100644 index 0000000..8a3e491 --- /dev/null +++ b/plugins/mac-vth264/data/locale/ar-SA.ini @@ -0,0 +1,6 @@ +Bitrate="معدّل البِت" +Profile="الملف الشخصي" +None="(بلا)" +DefaultEncoder="(المرمّز الافتراضي)" + + diff --git a/plugins/mac-vth264/data/locale/el-GR.ini b/plugins/mac-vth264/data/locale/el-GR.ini new file mode 100644 index 0000000..66152b8 --- /dev/null +++ b/plugins/mac-vth264/data/locale/el-GR.ini @@ -0,0 +1,6 @@ +Bitrate="Ρυθμός μετάδοσης bit" +Profile="Προφίλ" +None="(Κανένα)" +DefaultEncoder="(Προεπιλεγμένος κωδικοποιητής)" + + diff --git a/plugins/mac-vth264/data/locale/eu-ES.ini b/plugins/mac-vth264/data/locale/eu-ES.ini index 21c2500..00b2586 100644 --- a/plugins/mac-vth264/data/locale/eu-ES.ini +++ b/plugins/mac-vth264/data/locale/eu-ES.ini @@ -1,14 +1,14 @@ -VTH264EncHW="Apple VT H264 Hardware Kodeatzailea" -VTH264EncSW="Apple VT H264 Software Kodeatzailea" -VTEncoder="VideoToolbox Kodeatzailea" -Bitrate="Bitneurria" -UseMaxBitrate="Mugatu bitneurria" -MaxBitrate="Gehienezko bitneurria" -MaxBitrateWindow="Gehinezko bitneurri leihoa (segunduak)" -KeyframeIntervalSec="Giltzaframe Tartea (segundu, 0=berez)" +VTH264EncHW="Apple VT H264 hardware kodetzailea" +VTH264EncSW="Apple VT H264 software kodetzailea" +VTEncoder="VideoToolbox kodetzailea" +Bitrate="Bit-tasa" +UseMaxBitrate="Mugatu bit-tasa" +MaxBitrate="Gehienezko bit-tasa" +MaxBitrateWindow="Gehinezko bit-tasa leihoa (segundo)" +KeyframeIntervalSec="Fotograma-gakoen tartea (segundo, 0=auto)" Profile="Profila" None="(Bat ere ez)" -DefaultEncoder="(Berezko Kodeatzailea)" -UseBFrames="Erabili B-Frameak" +DefaultEncoder="(Lehenetsitako kodetzailea)" +UseBFrames="Erabili B-fotogramak" diff --git a/plugins/mac-vth264/data/locale/gl-ES.ini b/plugins/mac-vth264/data/locale/gl-ES.ini index 399a3e6..651bfaf 100644 --- a/plugins/mac-vth264/data/locale/gl-ES.ini +++ b/plugins/mac-vth264/data/locale/gl-ES.ini @@ -1,5 +1,12 @@ +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)" Profile="Perfil" None="(Ningún)" DefaultEncoder="(Codificador predefinido)" +UseBFrames="Utilizar B-Frames" diff --git a/plugins/mac-vth264/data/locale/hu-HU.ini b/plugins/mac-vth264/data/locale/hu-HU.ini index 902aa87..9cf5d8c 100644 --- a/plugins/mac-vth264/data/locale/hu-HU.ini +++ b/plugins/mac-vth264/data/locale/hu-HU.ini @@ -1,11 +1,11 @@ -VTH264EncHW="Apple VT H264 Hardveres Kódoló" -VTH264EncSW="Apple VT H264 Szoftveres Kódoló" -VTEncoder="VideoToolbox H264 Kódoló" +VTH264EncHW="Apple VT H264 hardveres kódoló" +VTH264EncSW="Apple VT H264 szoftveres kódoló" +VTEncoder="VideoToolbox H264 kódoló" Bitrate="Bitráta" -UseMaxBitrate="Bitráta Limit" +UseMaxBitrate="Bitráta limit" MaxBitrate="Maximális bitráta" -MaxBitrateWindow="Maximális bitráta ablak (másodperc)" -KeyframeIntervalSec="Kulcsképkocka Időköze (másodpercben, 0=automata)" +MaxBitrateWindow="Maximális bitrátaablak (másodperc)" +KeyframeIntervalSec="Kulcsképkocka időköze (másodperc, 0=auto)" Profile="Profil" None="(Nincs)" DefaultEncoder="(Alapértelmezett kódoló)" diff --git a/plugins/mac-vth264/data/locale/ja-JP.ini b/plugins/mac-vth264/data/locale/ja-JP.ini index 48d2ac6..ed8f6ab 100644 --- a/plugins/mac-vth264/data/locale/ja-JP.ini +++ b/plugins/mac-vth264/data/locale/ja-JP.ini @@ -1,5 +1,5 @@ -VTH264EncHW="アップル VT H264 ハードウェア エンコーダ" -VTH264EncSW="アップル VT H264 ソフトウェア エンコーダ" +VTH264EncHW="アップル VT H264 ハードウェアエンコーダ" +VTH264EncSW="アップル VT H264 ソフトウェアエンコーダ" VTEncoder="VideoToolbox エンコーダ" Bitrate="ビットレート" UseMaxBitrate="限界ビットレート" diff --git a/plugins/mac-vth264/data/locale/ro-RO.ini b/plugins/mac-vth264/data/locale/ro-RO.ini index 0cd0948..0a9e2a8 100644 --- a/plugins/mac-vth264/data/locale/ro-RO.ini +++ b/plugins/mac-vth264/data/locale/ro-RO.ini @@ -1,14 +1,14 @@ -VTH264EncHW="Codare Hardware Apple VT H264" -VTH264EncSW="Codare Software Apple VT H264" -VTEncoder="Codare VideoToolbox" -Bitrate="Rată biţi" -UseMaxBitrate="Limitare rată biţi" -MaxBitrate="Maxim rată biţi" -MaxBitrateWindow="Fereastra de Maxim Rată biţi (secunde)" -KeyframeIntervalSec="Intervalul de cadre (secunde, 0=auto)" +VTH264EncHW="Codificator hardware H264 Apple VT" +VTH264EncSW="Codificator software H264 Apple VT" +VTEncoder="Codificator VideoToolbox" +Bitrate="Rată de biți" +UseMaxBitrate="Limitează rata de biți" +MaxBitrate="Rată de biți maximă" +MaxBitrateWindow="Fereastră de rată de biți maximă (secunde)" +KeyframeIntervalSec="Interval de cadre cheie (secunde, 0=auto)" Profile="Profil" -None="(Nici unul)" -DefaultEncoder="(Codare Implicita)" -UseBFrames="Utilizeaza B-frames" +None="(Niciunul)" +DefaultEncoder="(Codificator implicit)" +UseBFrames="Folosește B-frames" diff --git a/plugins/mac-vth264/data/locale/sv-SE.ini b/plugins/mac-vth264/data/locale/sv-SE.ini new file mode 100644 index 0000000..df219f8 --- /dev/null +++ b/plugins/mac-vth264/data/locale/sv-SE.ini @@ -0,0 +1,12 @@ +VTH264EncHW="Apple VT H264-hårdvarukodare" +VTH264EncSW="Apple VT H264-mjukvarukodare" +VTEncoder="VideoToolbox-kodare" +Bitrate="Bithastighet" +UseMaxBitrate="Begränsa bithastighet" +MaxBitrate="Maximal bithastighet" +MaxBitrateWindow="Maximalt bithastighetsfönster (sekunder)" +Profile="Profil" +None="(Ingen)" +DefaultEncoder="(Standardkodare)" + + diff --git a/plugins/mac-vth264/data/locale/tr-TR.ini b/plugins/mac-vth264/data/locale/tr-TR.ini new file mode 100644 index 0000000..db89c21 --- /dev/null +++ b/plugins/mac-vth264/data/locale/tr-TR.ini @@ -0,0 +1,8 @@ +Bitrate="Bithızı" +MaxBitrate="Maks bit hızı" +KeyframeIntervalSec="Anahtarkare Aralığı (saniye, 0=otomatik)" +Profile="Profil" +None="(Yok)" +DefaultEncoder="(Varsayılan Kodlayıcı)" + + diff --git a/plugins/obs-ffmpeg/CMakeLists.txt b/plugins/obs-ffmpeg/CMakeLists.txt index 511431d..50c9c8d 100644 --- a/plugins/obs-ffmpeg/CMakeLists.txt +++ b/plugins/obs-ffmpeg/CMakeLists.txt @@ -16,6 +16,7 @@ set(obs-ffmpeg_HEADERS set(obs-ffmpeg_SOURCES obs-ffmpeg.c obs-ffmpeg-aac.c + obs-ffmpeg-nvenc.c obs-ffmpeg-output.c obs-ffmpeg-mux.c obs-ffmpeg-source.c) diff --git a/plugins/obs-ffmpeg/data/locale/ar-SA.ini b/plugins/obs-ffmpeg/data/locale/ar-SA.ini index 576b3d9..b7edd47 100644 --- a/plugins/obs-ffmpeg/data/locale/ar-SA.ini +++ b/plugins/obs-ffmpeg/data/locale/ar-SA.ini @@ -1,6 +1,27 @@ FFmpegOutput="مخرج FFmpeg" FFmpegAAC="ترميز AAC الافتراضي لـFFmpeg" Bitrate="معدل النقل" +Preset="الإعداد المسبق" + +NVENC.Preset.default="الإفتراضي" +NVENC.Preset.hq="جودة عالية" +NVENC.Preset.hp="أداء عالي" +NVENC.Preset.bd="بلوراي Bluray" +NVENC.Level="المستوى" + +FFmpegSource="مصدر وسائط" +LocalFile="ملف محلي" +Looping="تكرار حلقي" +Advanced="متقدم" +DiscardNone="لا شيء" +ColorRange="نطاق ألوان YUV" +ColorRange.Auto="تلقائي" +ColorRange.Partial="جزئي" +ColorRange.Full="كامل" +MediaFileFilter.AllMediaFiles="كافة ملفات الوسائط" +MediaFileFilter.VideoFiles="ملفات الفيديو" +MediaFileFilter.AudioFiles="ملفات الصوت" +MediaFileFilter.AllFiles="‮كل الملفات" diff --git a/plugins/obs-ffmpeg/data/locale/bg-BG.ini b/plugins/obs-ffmpeg/data/locale/bg-BG.ini index 7f2be12..10c4189 100644 --- a/plugins/obs-ffmpeg/data/locale/bg-BG.ini +++ b/plugins/obs-ffmpeg/data/locale/bg-BG.ini @@ -3,3 +3,5 @@ Bitrate="Битрейт" + + diff --git a/plugins/obs-ffmpeg/data/locale/ca-ES.ini b/plugins/obs-ffmpeg/data/locale/ca-ES.ini index 176207a..14ff28c 100644 --- a/plugins/obs-ffmpeg/data/locale/ca-ES.ini +++ b/plugins/obs-ffmpeg/data/locale/ca-ES.ini @@ -1,6 +1,20 @@ FFmpegOutput="Sortida FFmpeg" FFmpegAAC="Codificador FFmpeg AAC predeterminat" Bitrate="Taxa de bits" +Preset="Valors predefinits" +RateControl="Control de freqüència" +KeyframeIntervalSec="Interval de fotograma clau (en segons, 0 = automàtic)" +Lossless="Sense pèrdues" + +NVENC.Use2Pass="Utilitza codificació en dues passades" +NVENC.Preset.default="Per defecte" +NVENC.Preset.hq="Alta Qualitat" +NVENC.Preset.hp="Alt rendiment" +NVENC.Preset.bd="BluRay" +NVENC.Preset.ll="Latencia baixa" +NVENC.Preset.llhq="Latència baixa Alta Qualitat" +NVENC.Preset.llhp="Latència baixa alt rendiment" +NVENC.Level="Nivell" FFmpegSource="Font multimèdia" LocalFile="Fitxer local" @@ -21,5 +35,15 @@ DiscardBiDir="Quadres bidireccionals" DiscardNonIntra="Quadres no-interiors" DiscardNonKey="Quadres no-clau" DiscardAll="Tots els marcs (aneu amb compte!)" +RestartWhenActivated="Reinicia la reproducció quan la font estigui activa" +ColorRange="Gamma de color YUV" +ColorRange.Auto="Automàtic" +ColorRange.Partial="Parcial" +ColorRange.Full="Màxim" +MediaFileFilter.AllMediaFiles="Tots els arxius multimèdia" +MediaFileFilter.VideoFiles="Arxius de vídeo" +MediaFileFilter.AudioFiles="Arxius d'àudio" +MediaFileFilter.AllFiles="Tots els fitxers" + diff --git a/plugins/obs-ffmpeg/data/locale/cs-CZ.ini b/plugins/obs-ffmpeg/data/locale/cs-CZ.ini index 1c4ffc2..d06917f 100644 --- a/plugins/obs-ffmpeg/data/locale/cs-CZ.ini +++ b/plugins/obs-ffmpeg/data/locale/cs-CZ.ini @@ -1,6 +1,20 @@ FFmpegOutput="Výstup FFmpegu" FFmpegAAC="Výchozí FFmpeg AAC enkodér" Bitrate="Bitrate" +Preset="Předvolba" +RateControl="Řízení toku" +KeyframeIntervalSec="Interval klíč. snímků (vteřiny, 0=auto)" +Lossless="Lossless" + +NVENC.Use2Pass="Použít dvoustupňové enkódování" +NVENC.Preset.default="Výchozí" +NVENC.Preset.hq="Vysoká kvalita" +NVENC.Preset.hp="Vysoký výkon" +NVENC.Preset.bd="Bluray" +NVENC.Preset.ll="Nízká odezva" +NVENC.Preset.llhq="Nízká odezva, vysoká kvalita" +NVENC.Preset.llhp="Nízká odezva, vysoký výkon" +NVENC.Level="Úrověň" FFmpegSource="Médium" LocalFile="Místní soubor" @@ -22,6 +36,11 @@ DiscardNonIntra="Snímky mimo rámec" DiscardNonKey="Ne-klíčové snímky" DiscardAll="Všechny snímky (Pozor!)" RestartWhenActivated="Restartovat přehrávání poté, co je zdroj aktivován" +ColorRange="Rozsah barev YUV" +ColorRange.Auto="Automatický" +ColorRange.Partial="Částečný" +ColorRange.Full="Celkový" + MediaFileFilter.AllMediaFiles="Všechny mediální soubory" MediaFileFilter.VideoFiles="Video soubory" diff --git a/plugins/obs-ffmpeg/data/locale/da-DK.ini b/plugins/obs-ffmpeg/data/locale/da-DK.ini index 19c7a59..6c63f79 100644 --- a/plugins/obs-ffmpeg/data/locale/da-DK.ini +++ b/plugins/obs-ffmpeg/data/locale/da-DK.ini @@ -2,6 +2,7 @@ FFmpegOutput="FFmpeg Output" FFmpegAAC="FFmpeg Standard AAC Encoder" Bitrate="Bitrate" + FFmpegSource="Mediekilde" LocalFile="Lokal fil" Looping="Gentagelse" @@ -19,3 +20,4 @@ DiscardNonKey="Non-Key Frames" DiscardAll="Alle frames (pas på!)" + diff --git a/plugins/obs-ffmpeg/data/locale/de-DE.ini b/plugins/obs-ffmpeg/data/locale/de-DE.ini index bd8b70a..cef2671 100644 --- a/plugins/obs-ffmpeg/data/locale/de-DE.ini +++ b/plugins/obs-ffmpeg/data/locale/de-DE.ini @@ -1,6 +1,20 @@ FFmpegOutput="FFmpeg Ausgabe" FFmpegAAC="FFmpeg Standard AAC Encoder" Bitrate="Bitrate" +Preset="Voreinstellung" +RateControl="Qualitäts Regulierungsmethode" +KeyframeIntervalSec="Keyframeintervall (Sekunden, 0=auto)" +Lossless="Verlustfrei" + +NVENC.Use2Pass="Benutze Two-Pass Encoding" +NVENC.Preset.default="Standard" +NVENC.Preset.hq="Hohe Qualität" +NVENC.Preset.hp="Hohe Leistung" +NVENC.Preset.bd="Bluray" +NVENC.Preset.ll="Niedrige Latenz" +NVENC.Preset.llhq="Niedrige Latenz, Hohe Qualität" +NVENC.Preset.llhp="Niedrige Latenz, Hohe Leistung" +NVENC.Level="Level" FFmpegSource="Medienquelle" LocalFile="Lokale Datei" @@ -22,6 +36,11 @@ DiscardNonIntra="Non-Intra Frames" DiscardNonKey="Non-Key Frames" DiscardAll="Alle Frames (Vorsicht!)" RestartWhenActivated="Wiedergabe erneut starten, wenn Quelle aktiviert wird" +ColorRange="YUV-Farbmatrix" +ColorRange.Auto="Automatisch" +ColorRange.Partial="Teilweise" +ColorRange.Full="Voll" + MediaFileFilter.AllMediaFiles="Alle Mediendateien" MediaFileFilter.VideoFiles="Video-Dateien" diff --git a/plugins/obs-ffmpeg/data/locale/el-GR.ini b/plugins/obs-ffmpeg/data/locale/el-GR.ini index 1e80153..d82c271 100644 --- a/plugins/obs-ffmpeg/data/locale/el-GR.ini +++ b/plugins/obs-ffmpeg/data/locale/el-GR.ini @@ -2,6 +2,7 @@ FFmpegOutput="Έξοδος FFmpeg" FFmpegAAC="FFmpeg προεπιλεγμένος κωδικοποιητής AAC" Bitrate="Ρυθμός μετάδοσης bit" + LocalFile="Τοπικό αρχείο" Looping="Επανάληψη" Input="Είσοδος" @@ -16,3 +17,4 @@ DiscardDefault="Προεπιλογή (άκυρα πακέτα)" DiscardAll="Όλα τα καρέ (Προσοχή!)" + diff --git a/plugins/obs-ffmpeg/data/locale/en-US.ini b/plugins/obs-ffmpeg/data/locale/en-US.ini index f74fb77..959d751 100644 --- a/plugins/obs-ffmpeg/data/locale/en-US.ini +++ b/plugins/obs-ffmpeg/data/locale/en-US.ini @@ -1,6 +1,20 @@ FFmpegOutput="FFmpeg Output" FFmpegAAC="FFmpeg Default AAC Encoder" Bitrate="Bitrate" +Preset="Preset" +RateControl="Rate Control" +KeyframeIntervalSec="Keyframe Interval (seconds, 0=auto)" +Lossless="Lossless" + +NVENC.Use2Pass="Use Two-Pass Encoding" +NVENC.Preset.default="Default" +NVENC.Preset.hq="High Quality" +NVENC.Preset.hp="High Performance" +NVENC.Preset.bd="Bluray" +NVENC.Preset.ll="Low-Latency" +NVENC.Preset.llhq="Low-Latency High Quality" +NVENC.Preset.llhp="Low-Latency High Performance" +NVENC.Level="Level" FFmpegSource="Media Source" LocalFile="Local File" @@ -22,6 +36,11 @@ DiscardNonIntra="Non-Intra Frames" DiscardNonKey="Non-Key Frames" DiscardAll="All Frames (Careful!)" RestartWhenActivated="Restart playback when source becomes active" +ColorRange="YUV Color Range" +ColorRange.Auto="Auto" +ColorRange.Partial="Partial" +ColorRange.Full="Full" + MediaFileFilter.AllMediaFiles="All Media Files" MediaFileFilter.VideoFiles="Video Files" diff --git a/plugins/obs-ffmpeg/data/locale/es-ES.ini b/plugins/obs-ffmpeg/data/locale/es-ES.ini index 871cc08..0702b35 100644 --- a/plugins/obs-ffmpeg/data/locale/es-ES.ini +++ b/plugins/obs-ffmpeg/data/locale/es-ES.ini @@ -1,6 +1,20 @@ FFmpegOutput="Salida de FFmpeg" FFmpegAAC="Codificador AAC FFmpeg predeterminado" Bitrate="Tasa de bits" +Preset="Preajuste" +RateControl="Control de la frecuencia" +KeyframeIntervalSec="Intervalo de keyframes (segundos, 0=auto)" +Lossless="Sin pérdidas" + +NVENC.Use2Pass="Usar codificación en dos pasadas" +NVENC.Preset.default="Por defecto" +NVENC.Preset.hq="Alta Calidad" +NVENC.Preset.hp="Alto rendimiento" +NVENC.Preset.bd="BluRay" +NVENC.Preset.ll="Baja latencia" +NVENC.Preset.llhq="Baja latencia alta calidad" +NVENC.Preset.llhp="Baja latencia alto rendimiento" +NVENC.Level="Nivel" FFmpegSource="Fuente multimedia" LocalFile="Archivo local" @@ -22,6 +36,11 @@ DiscardNonIntra="Fotogramas no intra-frame" DiscardNonKey="Fotogramas no claves" DiscardAll="Todos los fotogramas (¡Cuidado!)" RestartWhenActivated="Reiniciar la reproducción cuando la fuente esté activa" +ColorRange="Gama de Color YUV" +ColorRange.Auto="Automatico" +ColorRange.Partial="Parcial" +ColorRange.Full="Completo" + MediaFileFilter.AllMediaFiles="Todos los archivos multimedia" MediaFileFilter.VideoFiles="Archivos de vídeo" diff --git a/plugins/obs-ffmpeg/data/locale/eu-ES.ini b/plugins/obs-ffmpeg/data/locale/eu-ES.ini index fa776b6..b9f7b59 100644 --- a/plugins/obs-ffmpeg/data/locale/eu-ES.ini +++ b/plugins/obs-ffmpeg/data/locale/eu-ES.ini @@ -1,30 +1,49 @@ -FFmpegOutput="FFmpeg Irteera" -FFmpegAAC="FFmpeg Berezko AAC Kodeatzailea" -Bitrate="Bitneurria" +FFmpegOutput="FFmpeg irteera" +FFmpegAAC="FFmpeg lehenetsitako AAC Kodetzailea" +Bitrate="Bit-tasa" +Preset="Aurrezarpena" +RateControl="Tasaren kontrola" +KeyframeIntervalSec="Gako-fotogramen tartea (segundoak, 0=auto)" +Lossless="Galerarik gabe" -FFmpegSource="Multimedia Iturburua" -LocalFile="Tokiko Agiria" -Looping="Onartu begizta" +NVENC.Use2Pass="Erabili bi urratseko kodeketa" +NVENC.Preset.default="Lehenetsia" +NVENC.Preset.hq="Kalitate handia" +NVENC.Preset.hp="Eraginkortasun handia" +NVENC.Preset.bd="Bluray" +NVENC.Preset.ll="Latentzia txikia" +NVENC.Preset.llhq="Latentzia txikia kalitate handia" +NVENC.Preset.llhp="Latentzia txikia eraginkortasun handia" +NVENC.Level="Maila" + +FFmpegSource="Multimedia iturburua" +LocalFile="Tokiko fitxategia" +Looping="Begizta" Input="Sarrera" -InputFormat="Sarrera Heuskarria" -ForceFormat="Behartu heuskarri bihurketa" -HardwareDecode="Erabili hardware dekodeaketa eskuragarri dagoenean" -ClearOnMediaEnd="Ezkutatu iturburua irakurketa amaitutakoan" +InputFormat="Sarrera formatua" +ForceFormat="Behartu formatu-bihurketa" +HardwareDecode="Erabili hardware deskodeketa eskuragarri dagoenean" +ClearOnMediaEnd="Ezkutatu iturburua erreprodukzioa amaitzean" Advanced="Aurreratua" -AudioBufferSize="Audio Buffer Neurria (frameak)" -VideoBufferSize="Bideo Buffer Neurria (frameak)" -FrameDropping="Frame Erortze Maila" +AudioBufferSize="Audio-bufferraren tamaina (fotogramak)" +VideoBufferSize="Bideo-bufferraren tamaina (fotogramak)" +FrameDropping="Fotogramen erorketa maila" DiscardNone="Ezer ez" -DiscardDefault="Berezkoa (Pakete Baliogabeak)" -DiscardNonRef="Ez-Xehetasun Frameak" -DiscardBiDir="Bi-Norabideko Frameak" -DiscardNonIntra="Ez-Intra Frameak" -DiscardNonKey="Ez-Giltza Frameak" -DiscardAll="Frame Guztiak (Kontuz!)" -RestartWhenActivated="Berrabiarazi irakurketa iturburua gaitua bihurtzerakoan" +DiscardDefault="Lehenetsia (pakete baliogabeak)" +DiscardNonRef="Erreferentziarik gabeko fotogramak" +DiscardBiDir="Norabide biko fotogramak" +DiscardNonIntra="Non-Intra fotogramak" +DiscardNonKey="Gakoa ez diren fotogramak" +DiscardAll="Fotograma guztiak (kontuz!)" +RestartWhenActivated="Berrabiarazi erreprodukzioa iturburua aktiboa dagoenean" +ColorRange="YUV kolore-barrutia" +ColorRange.Auto="Auto" +ColorRange.Partial="Partziala" +ColorRange.Full="Osoa" -MediaFileFilter.AllMediaFiles="Multimedia Agiri Guztiak" -MediaFileFilter.VideoFiles="Bideo Agiriak" -MediaFileFilter.AudioFiles="Audio Agiriak" -MediaFileFilter.AllFiles="Agiri Guztiak" + +MediaFileFilter.AllMediaFiles="Multimedia-fitxategi guztiak" +MediaFileFilter.VideoFiles="Bideo-fitxategiak" +MediaFileFilter.AudioFiles="Audio-fitxategiak" +MediaFileFilter.AllFiles="Fitxategi guztiak" diff --git a/plugins/obs-ffmpeg/data/locale/fi-FI.ini b/plugins/obs-ffmpeg/data/locale/fi-FI.ini index b5ea63f..2ea579c 100644 --- a/plugins/obs-ffmpeg/data/locale/fi-FI.ini +++ b/plugins/obs-ffmpeg/data/locale/fi-FI.ini @@ -1,6 +1,20 @@ FFmpegOutput="FFmpeg ulostulo" FFmpegAAC="FFmpeg oletus AAC-enkooderi" Bitrate="Bitrate" +Preset="Esiasetus" +RateControl="Nopeudensäädin" +KeyframeIntervalSec="Keyframe-väli (sec, 0=auto)" +Lossless="Häviötön" + +NVENC.Use2Pass="Käytä kaksivaiheista enkoodausta" +NVENC.Preset.default="Oletusarvo" +NVENC.Preset.hq="Korkea laatu" +NVENC.Preset.hp="Korkea suorituskyky" +NVENC.Preset.bd="Bluray" +NVENC.Preset.ll="Alhainen latenssi" +NVENC.Preset.llhq="Alhainen latenssi, korkea laatu" +NVENC.Preset.llhp="Alhainen latenssi, korkea suorituskyky" +NVENC.Level="Taso" FFmpegSource="Lisää media" LocalFile="Paikallinen tiedosto" @@ -22,6 +36,11 @@ DiscardNonIntra="Non-Intra Frames" DiscardNonKey="Non-Key Frames" DiscardAll="All Frames (Varoitus!)" RestartWhenActivated="Aloita toisto uudelleen kun lähde aktivoituu" +ColorRange="YUV värialue" +ColorRange.Auto="Automaattinen" +ColorRange.Partial="Osittainen" +ColorRange.Full="Täysi" + MediaFileFilter.AllMediaFiles="Kaikki mediatiedostot" MediaFileFilter.VideoFiles="Videotiedostot" diff --git a/plugins/obs-ffmpeg/data/locale/fr-FR.ini b/plugins/obs-ffmpeg/data/locale/fr-FR.ini index 3b4420e..d1caf13 100644 --- a/plugins/obs-ffmpeg/data/locale/fr-FR.ini +++ b/plugins/obs-ffmpeg/data/locale/fr-FR.ini @@ -1,6 +1,20 @@ FFmpegOutput="Sortie FFmpeg" FFmpegAAC="Encodeur AAC FFmpeg par défaut" Bitrate="Débit" +Preset="Préréglage" +RateControl="Contrôle du débit" +KeyframeIntervalSec="Intervalle d'image-clé (en secondes, 0 = auto)" +Lossless="Sans perte" + +NVENC.Use2Pass="Utiliser l'encodage double passe" +NVENC.Preset.default="Défaut" +NVENC.Preset.hq="Haute qualité" +NVENC.Preset.hp="Haute performance" +NVENC.Preset.bd="Blu-ray" +NVENC.Preset.ll="Faible latence" +NVENC.Preset.llhq="Faible latence haute qualité" +NVENC.Preset.llhp="Faible latence haute performance" +NVENC.Level="Niveau" FFmpegSource="Source média" LocalFile="Fichier local" @@ -22,6 +36,11 @@ DiscardNonIntra="Images non-intra" DiscardNonKey="Images non-clés" DiscardAll="Toutes les images (Attention !)" RestartWhenActivated="Reprendre la lecture quand la source est active" +ColorRange="Gamme de couleurs YUV" +ColorRange.Auto="Auto" +ColorRange.Partial="Partielle" +ColorRange.Full="Complète" + MediaFileFilter.AllMediaFiles="Tous les fichiers multimédias" MediaFileFilter.VideoFiles="Fichiers vidéo" diff --git a/plugins/obs-ffmpeg/data/locale/gl-ES.ini b/plugins/obs-ffmpeg/data/locale/gl-ES.ini index c161f7c..a3b620f 100644 --- a/plugins/obs-ffmpeg/data/locale/gl-ES.ini +++ b/plugins/obs-ffmpeg/data/locale/gl-ES.ini @@ -2,6 +2,8 @@ FFmpegOutput="Saída de FFmpeg" FFmpegAAC="Codificador AAC FFmpeg predefinido" Bitrate="Velocidade de bits" +NVENC.Level="Nivel" + FFmpegSource="Fonte multimedia" LocalFile="Ficheiro local" Looping="Bucle" @@ -21,3 +23,4 @@ DiscardBiDir="Marcos bidireccionais" DiscardAll="Todos os marcos (con tino!)" + diff --git a/plugins/obs-ffmpeg/data/locale/he-IL.ini b/plugins/obs-ffmpeg/data/locale/he-IL.ini new file mode 100644 index 0000000..5523c3c --- /dev/null +++ b/plugins/obs-ffmpeg/data/locale/he-IL.ini @@ -0,0 +1,32 @@ +FFmpegOutput="פלט FFmpeg" +FFmpegAAC="FFmpeg מקודד AAC ברירת מחדל" +Bitrate="קצב ביטים" + + +FFmpegSource="מקור מדיה" +LocalFile="קובץ מקומי" +Looping="לולאה" +Input="קלט" +InputFormat="תבנית קלט" +ForceFormat="כפה המרת תבנית" +HardwareDecode="השתמש בפענוח חומרה כאשר היא זמין" +ClearOnMediaEnd="הסתר את מקור כאשר ההשמעה מסתיימת" +Advanced="מתקדם" +AudioBufferSize="גודל מאגר שמע (פריימים)" +VideoBufferSize="גודל מאגר הווידאו (פריימים)" +FrameDropping="רמת נשירת פריימים" +DiscardNone="ללא" +DiscardDefault="ברירת מחדל (מנות לא חוקיות)" +DiscardNonRef="פריימים לא יחס" +DiscardBiDir="פריימים דו-כיוונים" +DiscardNonIntra="פריימים לא ביינים" +DiscardNonKey="מסגרות שאינן מפתח" +DiscardAll="כל הפריימים (זהירות!)" +RestartWhenActivated="הפעל מחדש השמעה כאשר מקור הופך לפעיל" + + +MediaFileFilter.AllMediaFiles="כל קבצי המדיה" +MediaFileFilter.VideoFiles="קבצי וידאו" +MediaFileFilter.AudioFiles="קבצי אודיו" +MediaFileFilter.AllFiles="כל הקבצים" + diff --git a/plugins/obs-ffmpeg/data/locale/hr-HR.ini b/plugins/obs-ffmpeg/data/locale/hr-HR.ini index 6012458..4a8a315 100644 --- a/plugins/obs-ffmpeg/data/locale/hr-HR.ini +++ b/plugins/obs-ffmpeg/data/locale/hr-HR.ini @@ -1,6 +1,18 @@ FFmpegOutput="FFmpeg izlaz" FFmpegAAC="FFmpeg podrazumevani AAC enkoder" Bitrate="Protok" +Preset="Šablon" +KeyframeIntervalSec="Interval ključnih frejmova (sekunde, 0=automatski)" + +NVENC.Use2Pass="Koristi enkoding duplog prolaza" +NVENC.Preset.default="Podrazumevani" +NVENC.Preset.hq="Visoki kvalitet" +NVENC.Preset.hp="Visoke performanse" +NVENC.Preset.bd="Bluray" +NVENC.Preset.ll="Nisko kašnjenje" +NVENC.Preset.llhq="Visoki kvalitet niskog kašnjenja" +NVENC.Preset.llhp="Visoke performanse niskog kašnjenja" +NVENC.Level="Nivo" FFmpegSource="Medija izvor" LocalFile="Lokalna datoteka" @@ -22,6 +34,11 @@ DiscardNonIntra="Ne-intra frejmovi" DiscardNonKey="Frejmovi koji nisu ključni" DiscardAll="Svi frejmovi (oprezno!)" RestartWhenActivated="Ponovi reprodukciju kada izvor postane aktivan" +ColorRange="YUV opseg boja" +ColorRange.Auto="Automatski" +ColorRange.Partial="Delimični" +ColorRange.Full="Potpuni" + MediaFileFilter.AllMediaFiles="Sve medija datoteke" MediaFileFilter.VideoFiles="Video datoteke" diff --git a/plugins/obs-ffmpeg/data/locale/hu-HU.ini b/plugins/obs-ffmpeg/data/locale/hu-HU.ini index b1dbc5a..284fbb0 100644 --- a/plugins/obs-ffmpeg/data/locale/hu-HU.ini +++ b/plugins/obs-ffmpeg/data/locale/hu-HU.ini @@ -1,30 +1,49 @@ -FFmpegOutput="FFmpeg Kimenet" +FFmpegOutput="FFmpeg kimenet" FFmpegAAC="FFmpeg alapértelmezett AAC kódoló" Bitrate="Bitráta" +Preset="Készlet" +RateControl="Sebesség Vezérlés" +KeyframeIntervalSec="Kulcsképkocka időköze (másodperc, 0=auto)" +Lossless="Veszteségmentes" -FFmpegSource="Média Forrás" -LocalFile="Helyi Fájl" +NVENC.Use2Pass="Kétmenetes kódolás" +NVENC.Preset.default="Alapértelmezett" +NVENC.Preset.hq="Kiváló minőség" +NVENC.Preset.hp="Nagy teljesítmény" +NVENC.Preset.bd="BluRay" +NVENC.Preset.ll="Alacsony-késleltetés" +NVENC.Preset.llhq="Alacsony-késleltetés kiváló minőséggel" +NVENC.Preset.llhp="Alacsony-késleltetés nagy teljesítménnyel" +NVENC.Level="Szint" + +FFmpegSource="Médiaforrás" +LocalFile="Helyi fájl" Looping="Ismétlés" Input="Bemenet" -InputFormat="Bemeneti Formátum" +InputFormat="Bemeneti formátum" ForceFormat="Formátum átváltás kényszerítése" HardwareDecode="Hardveres dekódolás használata, ha rendelkezésre áll" ClearOnMediaEnd="Forrás elrejtése a lejátszás végeztével" Advanced="Haladó" -AudioBufferSize="Audio Puffer Méret (képkockák)" -VideoBufferSize="Video Puffer Méret (képkockák)" -FrameDropping="Képkocka Ejtésszint" +AudioBufferSize="Audio pufferméret (képkockák)" +VideoBufferSize="Video pufferméret (képkockák)" +FrameDropping="Képkocka ejtésszint" DiscardNone="Semmi" -DiscardDefault="Alapértelmezett (Érvénytelen Csomagok)" -DiscardNonRef="Nem Referencia Kockák" -DiscardBiDir="Kétirányú Kockák" -DiscardNonIntra="Nem Belső Kockák" -DiscardNonKey="Nem Kulcskockák" -DiscardAll="Összes Kocka (Óvatosan!)" +DiscardDefault="Alapértelmezett (érvénytelen csomagok)" +DiscardNonRef="Nem referencia kockák" +DiscardBiDir="Kétirányú kockák" +DiscardNonIntra="Nem belső kockák" +DiscardNonKey="Nem kulcskockák" +DiscardAll="Összes kocka (óvatosan!)" RestartWhenActivated="Lejátszás újraindítása, ha a forrás aktivizálódik" +ColorRange="YUV színtartomány" +ColorRange.Auto="Auto" +ColorRange.Partial="Részleges" +ColorRange.Full="Teljes" -MediaFileFilter.AllMediaFiles="Minden Média Fájl" -MediaFileFilter.VideoFiles="Video Fájlok" -MediaFileFilter.AudioFiles="Hang Fájlok" -MediaFileFilter.AllFiles="Minden Fájl" + +MediaFileFilter.AllMediaFiles="Minden médiafájl" +MediaFileFilter.VideoFiles="Videofájlok" +MediaFileFilter.AudioFiles="Hangfájlok" +MediaFileFilter.AllFiles="Minden fájl" diff --git a/plugins/obs-ffmpeg/data/locale/it-IT.ini b/plugins/obs-ffmpeg/data/locale/it-IT.ini index bab1b8c..53864f9 100644 --- a/plugins/obs-ffmpeg/data/locale/it-IT.ini +++ b/plugins/obs-ffmpeg/data/locale/it-IT.ini @@ -2,6 +2,7 @@ FFmpegOutput="Uscita FFmpeg" FFmpegAAC="Codificatore FFmpeg predefinito AAC" Bitrate="Bitrate" + FFmpegSource="Origine multimediale" LocalFile="File locale" Looping="Ripeti" @@ -21,5 +22,7 @@ DiscardBiDir="Frame bi-direzionali" DiscardNonIntra="Frame non interposti" DiscardNonKey="Frame non di chiave" DiscardAll="Tutti i Frame (opzione per utenti più esperti)" +RestartWhenActivated="Riattiva playback quando la fonte torna attiva" + diff --git a/plugins/obs-ffmpeg/data/locale/ja-JP.ini b/plugins/obs-ffmpeg/data/locale/ja-JP.ini index b8f14f3..2b1e2ad 100644 --- a/plugins/obs-ffmpeg/data/locale/ja-JP.ini +++ b/plugins/obs-ffmpeg/data/locale/ja-JP.ini @@ -1,6 +1,20 @@ FFmpegOutput="FFmpeg の出力" -FFmpegAAC="FFmpeg 既定のAAC エンコーダー" +FFmpegAAC="FFmpeg 既定のAAC エンコーダ" Bitrate="ビットレート" +Preset="プリセット" +RateControl="レート制御" +KeyframeIntervalSec="キーフレーム間隔 (秒, 0=自動)" +Lossless="無損失" + +NVENC.Use2Pass="2パスエンコードを使用" +NVENC.Preset.default="既定" +NVENC.Preset.hq="高品質" +NVENC.Preset.hp="高性能" +NVENC.Preset.bd="ブルーレイ" +NVENC.Preset.ll="低遅延" +NVENC.Preset.llhq="低遅延高品質" +NVENC.Preset.llhp="低遅延高性能" +NVENC.Level="レベル" FFmpegSource="メディアソース" LocalFile="ローカルファイル" @@ -11,17 +25,22 @@ ForceFormat="強制的にフォーマットを変換" HardwareDecode="可能な場合ハードウェアデコードを使用" ClearOnMediaEnd="再生終了時にソースを非表示にする" Advanced="高度な設定" -AudioBufferSize="音声バッファーサイズ(フレーム)" -VideoBufferSize="映像バッファーサイズ(フレーム)" +AudioBufferSize="音声バッファーサイズ (フレーム)" +VideoBufferSize="映像バッファーサイズ (フレーム)" FrameDropping="フレームドロップレベル" DiscardNone="なし" -DiscardDefault="既定(無効なパケット)" +DiscardDefault="既定 (無効なパケット)" DiscardNonRef="非参照フレーム" DiscardBiDir="双方向フレーム" DiscardNonIntra="非イントラフレーム" DiscardNonKey="非キーフレーム" -DiscardAll="すべてのフレーム(注意!)" +DiscardAll="すべてのフレーム (注意!)" RestartWhenActivated="ソースがアクティブになったときに再生を再開する" +ColorRange="YUV 色範囲" +ColorRange.Auto="自動" +ColorRange.Partial="一部" +ColorRange.Full="全部" + MediaFileFilter.AllMediaFiles="すべてのメディアファイル" MediaFileFilter.VideoFiles="ビデオファイル" diff --git a/plugins/obs-ffmpeg/data/locale/ko-KR.ini b/plugins/obs-ffmpeg/data/locale/ko-KR.ini index 53d05b9..c2a3b02 100644 --- a/plugins/obs-ffmpeg/data/locale/ko-KR.ini +++ b/plugins/obs-ffmpeg/data/locale/ko-KR.ini @@ -1,6 +1,20 @@ FFmpegOutput="FFmpeg 출력" FFmpegAAC="FFmpeg 기본 AAC 인코더" Bitrate="비트레이트" +Preset="사전 설정" +RateControl="데이터율 제어" +KeyframeIntervalSec="키프레임 간격 (초 단위, 0=자동)" +Lossless="무손실" + +NVENC.Use2Pass="2 패스 인코딩 사용" +NVENC.Preset.default="기본" +NVENC.Preset.hq="우수한 품질" +NVENC.Preset.hp="우수한 성능" +NVENC.Preset.bd="블루레이" +NVENC.Preset.ll="낮은 지연 시간" +NVENC.Preset.llhq="낮은 지연 시간 우수한 품질" +NVENC.Preset.llhp="낮은 지연 시간 우수한 성능" +NVENC.Level="수준" FFmpegSource="미디어 소스" LocalFile="로컬 파일" @@ -22,6 +36,11 @@ DiscardNonIntra="비 내부 프레임" DiscardNonKey="비 키 프레임" DiscardAll="모든 프레임 (주의!)" RestartWhenActivated="소스가 활성화될 때 재생을 다시 시작" +ColorRange="YUV 색상 범위" +ColorRange.Auto="자동" +ColorRange.Partial="부분" +ColorRange.Full="전체" + MediaFileFilter.AllMediaFiles="모든 미디어 파일" MediaFileFilter.VideoFiles="비디오 파일" diff --git a/plugins/obs-ffmpeg/data/locale/nb-NO.ini b/plugins/obs-ffmpeg/data/locale/nb-NO.ini index c635dd9..965826f 100644 --- a/plugins/obs-ffmpeg/data/locale/nb-NO.ini +++ b/plugins/obs-ffmpeg/data/locale/nb-NO.ini @@ -2,6 +2,7 @@ FFmpegOutput="FFmpeg utdata" FFmpegAAC="Standard FFmpeg AAC-koder" Bitrate="Bitrate" + FFmpegSource="Mediekilde" LocalFile="Lokal fil" Looping="Repeter" @@ -23,3 +24,4 @@ DiscardNonKey="Ikkenøkkelbilder" DiscardAll="Alle bilder (forsiktig!)" + diff --git a/plugins/obs-ffmpeg/data/locale/nl-NL.ini b/plugins/obs-ffmpeg/data/locale/nl-NL.ini index 54f4d54..1c386af 100644 --- a/plugins/obs-ffmpeg/data/locale/nl-NL.ini +++ b/plugins/obs-ffmpeg/data/locale/nl-NL.ini @@ -1,6 +1,20 @@ FFmpegOutput="FFmpeg-uitvoer" FFmpegAAC="FFmpeg Standaard AAC Encoder" Bitrate="Bitrate" +Preset="Preset" +RateControl="Rate Control" +KeyframeIntervalSec="Tijd tussen keyframes (seconden, 0=auto)" +Lossless="Lossless" + +NVENC.Use2Pass="Gebruik two-pass encoding" +NVENC.Preset.default="Standaard" +NVENC.Preset.hq="Hoge kwaliteit" +NVENC.Preset.hp="Hoge prestaties" +NVENC.Preset.bd="Blu-ray" +NVENC.Preset.ll="Lage Latency" +NVENC.Preset.llhq="Lage latency, hoge kwaliteit" +NVENC.Preset.llhp="Lage latency, hoge prestaties" +NVENC.Level="Niveau" FFmpegSource="Mediabron" LocalFile="Lokaal bestand" @@ -22,6 +36,11 @@ DiscardNonIntra="Niet-Intra Frames" DiscardNonKey="Niet-Key Frames" DiscardAll="Alle Frames (Voorzichtig!)" RestartWhenActivated="Opnieuw starten met afspelen zodra de bron actief wordt" +ColorRange="YUV Kleurbereik" +ColorRange.Auto="Automatisch" +ColorRange.Partial="Gedeeltelijk" +ColorRange.Full="Volledig" + MediaFileFilter.AllMediaFiles="Alle mediabestanden" MediaFileFilter.VideoFiles="Videobestanden" diff --git a/plugins/obs-ffmpeg/data/locale/pl-PL.ini b/plugins/obs-ffmpeg/data/locale/pl-PL.ini index ff05dd8..7b0381f 100644 --- a/plugins/obs-ffmpeg/data/locale/pl-PL.ini +++ b/plugins/obs-ffmpeg/data/locale/pl-PL.ini @@ -1,6 +1,18 @@ FFmpegOutput="Wyjście FFmpeg" FFmpegAAC="Domyślny enkoder AAC w FFmpeg" Bitrate="Przepływność bitowa" +Preset="Profil ustawień" +KeyframeIntervalSec="Odstęp między klatkami kluczowymi (sekundy, 0=automatyczny)" + +NVENC.Use2Pass="Użyj enkodowania dwuprzebiegowego" +NVENC.Preset.default="Domyślny" +NVENC.Preset.hq="Wysoka jakość" +NVENC.Preset.hp="Wysoka wydajność" +NVENC.Preset.bd="Blu-ray" +NVENC.Preset.ll="Niskie opóźnienie" +NVENC.Preset.llhq="Niskie opóźnienie - wysoka jakość" +NVENC.Preset.llhp="Niskie opóźnienie - wysoka wydajność" +NVENC.Level="Poziom" FFmpegSource="Źródło danych" LocalFile="Plik lokalny" @@ -22,6 +34,11 @@ DiscardNonIntra="Klatki niewewnętrzne (non-intra)" DiscardNonKey="Klatki niekluczowe (non-key)" DiscardAll="Wszystkie klatki (Ostrożnie!)" RestartWhenActivated="Zrestartuj odtwarzanie, gdy źródła będą aktywne" +ColorRange="Zakres kolorów YUV" +ColorRange.Auto="Automatycznie" +ColorRange.Partial="Częściowy" +ColorRange.Full="Pełny" + MediaFileFilter.AllMediaFiles="Wszystkie pliki multimedialne" MediaFileFilter.VideoFiles="Pliki video" diff --git a/plugins/obs-ffmpeg/data/locale/pt-BR.ini b/plugins/obs-ffmpeg/data/locale/pt-BR.ini index 076a019..f6f8c5c 100644 --- a/plugins/obs-ffmpeg/data/locale/pt-BR.ini +++ b/plugins/obs-ffmpeg/data/locale/pt-BR.ini @@ -2,6 +2,7 @@ FFmpegOutput="Saída do FFmpeg" FFmpegAAC="Codificador AAC Padrão do FFmpeg" Bitrate="Taxa de Bits" + FFmpegSource="Fonte de mídia" LocalFile="Arquivo Local" Looping="Loop" @@ -21,5 +22,15 @@ DiscardBiDir="Frames Bi-direcionais" DiscardNonIntra="Sem intra-frames" DiscardNonKey="Sem keyframes" DiscardAll="Todos os frames(cuidado!)" +RestartWhenActivated="Reiniciar reprodução quando a fonte se tornar ativa" +ColorRange="Intervalo de Cores YUV" +ColorRange.Auto="Auto" +ColorRange.Partial="Parcial" +ColorRange.Full="Completo" +MediaFileFilter.AllMediaFiles="Todos Arquivos de Mídia" +MediaFileFilter.VideoFiles="Arquivos de Vídeo" +MediaFileFilter.AudioFiles="Arquivos de Áudio" +MediaFileFilter.AllFiles="Todos os Arquivos" + diff --git a/plugins/obs-ffmpeg/data/locale/pt-PT.ini b/plugins/obs-ffmpeg/data/locale/pt-PT.ini index 7577828..30f5001 100644 --- a/plugins/obs-ffmpeg/data/locale/pt-PT.ini +++ b/plugins/obs-ffmpeg/data/locale/pt-PT.ini @@ -1,6 +1,7 @@ FFmpegOutput="Saída de FFmpeg" -FFmpegAAC="FFmpeg Codificador AAC padrão" -Bitrate="Taxa de Bits (Bitrate)" +FFmpegAAC="Codificador AAC padrão do FFmpeg" +Bitrate="Bitrate" + FFmpegSource="Fonte de multimédia" LocalFile="Ficheiro local" @@ -23,3 +24,4 @@ DiscardNonKey="Fotogramas não registados" DiscardAll="Todos os fotogramas (cuidado!)" + diff --git a/plugins/obs-ffmpeg/data/locale/ro-RO.ini b/plugins/obs-ffmpeg/data/locale/ro-RO.ini index 35a5729..fae18b6 100644 --- a/plugins/obs-ffmpeg/data/locale/ro-RO.ini +++ b/plugins/obs-ffmpeg/data/locale/ro-RO.ini @@ -1,30 +1,40 @@ -FFmpegOutput="Ieşire FFmpeg" -FFmpegAAC="Codare AAC implicită pentru FFmpeg" -Bitrate="Bitrate" +FFmpegOutput="Ieșire FFmpeg" +FFmpegAAC="Codificator AAC implicit FFmpeg" +Bitrate="Rată de biți" +Preset="Presetare" -FFmpegSource="Sursa Media" -LocalFile="Fişier Local" -Looping="Loop/Buclă" +NVENC.Preset.default="Implicită" +NVENC.Preset.bd="Bluray" +NVENC.Level="Nivel" + +FFmpegSource="Sursă media" +LocalFile="Fișier local" +Looping="Buclă" Input="Intrare" InputFormat="Format de intrare" -ForceFormat="Obliga conversia formatului" -HardwareDecode="Foloseste decodarea hardware cand e disponibila" -ClearOnMediaEnd="Ascunde sursă atunci când se termină redarea" +ForceFormat="Forțează conversia formatului" +HardwareDecode="Folosește decodarea hardware când este disponibilă" +ClearOnMediaEnd="Ascunde sursa atunci când se termină redarea" Advanced="Avansat" -AudioBufferSize="Dimensiune tampon/buffer audio (cadre)" -VideoBufferSize="Dimensiune tampon/buffer video (cadre)" -FrameDropping="Nivelul de pierdere a frame-urilor" -DiscardNone="Nici unul" -DiscardDefault="Implicit (pachetele invalide)" -DiscardNonRef="Frame-urile fara referinte" -DiscardBiDir="Frame-urile Bi-directionale" -DiscardNonIntra="Frame-urile Non-Intra" -DiscardNonKey="Frame-urile Non-Key" -DiscardAll="Toate frame-urile (Atentie!)" -RestartWhenActivated="Reporniţi redarea când sursa devine activă" +AudioBufferSize="Dimensiune pentru bufferul audio (cadre)" +VideoBufferSize="Dimensiune pentru bufferul video (cadre)" +FrameDropping="Nivel de pierdere al cadrelor" +DiscardNone="Niciunul" +DiscardDefault="Implicit (Pachete invalide)" +DiscardNonRef="Cadre fără referință" +DiscardBiDir="Cadre bidirecționale" +DiscardNonIntra="Cadre non-intra" +DiscardNonKey="Cadre non-cheie" +DiscardAll="Toate cadrele (Atenție!)" +RestartWhenActivated="Repornește redarea când sursa devine activă" +ColorRange="Gamă de culori YUV" +ColorRange.Auto="Auto" +ColorRange.Partial="Parțială" +ColorRange.Full="Completă" -MediaFileFilter.AllMediaFiles="Toate fişierele Media" -MediaFileFilter.VideoFiles="Fişiere video" -MediaFileFilter.AudioFiles="Fişiere audio" -MediaFileFilter.AllFiles="Toate fişierele" + +MediaFileFilter.AllMediaFiles="Toate fișierele media" +MediaFileFilter.VideoFiles="Fișiere video" +MediaFileFilter.AudioFiles="Fișiere audio" +MediaFileFilter.AllFiles="Toate fișierele" diff --git a/plugins/obs-ffmpeg/data/locale/ru-RU.ini b/plugins/obs-ffmpeg/data/locale/ru-RU.ini index db85001..6cd426b 100644 --- a/plugins/obs-ffmpeg/data/locale/ru-RU.ini +++ b/plugins/obs-ffmpeg/data/locale/ru-RU.ini @@ -1,6 +1,18 @@ FFmpegOutput="Вывод FFmpeg" FFmpegAAC="Стандартный AAC-кодер FFmpeg" Bitrate="Битрейт" +Preset="Пресет" +KeyframeIntervalSec="Интервал ключевых кадров (сек, 0=авто)" + +NVENC.Use2Pass="Использовать двухпроходное кодирование" +NVENC.Preset.default="По умолчанию" +NVENC.Preset.hq="Высокое качество" +NVENC.Preset.hp="Высокая производительность" +NVENC.Preset.bd="Blu-ray" +NVENC.Preset.ll="Малая задержка" +NVENC.Preset.llhq="Малая задержка, высокое качество" +NVENC.Preset.llhp="Малая задержка, высокая производительность" +NVENC.Level="Уровень" FFmpegSource="Источник медиа" LocalFile="Локальный файл" @@ -21,6 +33,12 @@ DiscardBiDir="Двунаправленные кадры" DiscardNonIntra="Невнутренние кадры" DiscardNonKey="Неключевые кадры" DiscardAll="Все кадры (осторожно!)" +RestartWhenActivated="Перезапустить воспроизведение, когда источник становится активным" +ColorRange="Цветовой диапазон YUV" +ColorRange.Auto="Автоматически" +ColorRange.Partial="Частичный" +ColorRange.Full="Полный" + MediaFileFilter.AllMediaFiles="Все медиа-файлы" MediaFileFilter.VideoFiles="Видеофайлы" diff --git a/plugins/obs-ffmpeg/data/locale/sk-SK.ini b/plugins/obs-ffmpeg/data/locale/sk-SK.ini index 5a59186..757cf2f 100644 --- a/plugins/obs-ffmpeg/data/locale/sk-SK.ini +++ b/plugins/obs-ffmpeg/data/locale/sk-SK.ini @@ -2,8 +2,10 @@ FFmpegOutput="Výstup FFmpeg" FFmpegAAC="Predvolený FFmpeg AAC enkodér" Bitrate="Bitrate" + Looping="Slučka" Advanced="Rozšírené" DiscardNone="Žiadny" + diff --git a/plugins/obs-ffmpeg/data/locale/sl-SI.ini b/plugins/obs-ffmpeg/data/locale/sl-SI.ini index d71ec64..4094562 100644 --- a/plugins/obs-ffmpeg/data/locale/sl-SI.ini +++ b/plugins/obs-ffmpeg/data/locale/sl-SI.ini @@ -2,6 +2,7 @@ FFmpegOutput="FFmpeg izhod" FFmpegAAC="FFmpeg Prevzeti AAC Encoder" Bitrate="Bitrate" + FFmpegSource="Medijski Vir" LocalFile="Lokalna Datoteka" Looping="Ponavljaj" @@ -23,3 +24,4 @@ DiscardNonKey="Non-Key Frames" DiscardAll="Vse Frame (Pazite!)" + diff --git a/plugins/obs-ffmpeg/data/locale/sr-CS.ini b/plugins/obs-ffmpeg/data/locale/sr-CS.ini index 6012458..4a8a315 100644 --- a/plugins/obs-ffmpeg/data/locale/sr-CS.ini +++ b/plugins/obs-ffmpeg/data/locale/sr-CS.ini @@ -1,6 +1,18 @@ FFmpegOutput="FFmpeg izlaz" FFmpegAAC="FFmpeg podrazumevani AAC enkoder" Bitrate="Protok" +Preset="Šablon" +KeyframeIntervalSec="Interval ključnih frejmova (sekunde, 0=automatski)" + +NVENC.Use2Pass="Koristi enkoding duplog prolaza" +NVENC.Preset.default="Podrazumevani" +NVENC.Preset.hq="Visoki kvalitet" +NVENC.Preset.hp="Visoke performanse" +NVENC.Preset.bd="Bluray" +NVENC.Preset.ll="Nisko kašnjenje" +NVENC.Preset.llhq="Visoki kvalitet niskog kašnjenja" +NVENC.Preset.llhp="Visoke performanse niskog kašnjenja" +NVENC.Level="Nivo" FFmpegSource="Medija izvor" LocalFile="Lokalna datoteka" @@ -22,6 +34,11 @@ DiscardNonIntra="Ne-intra frejmovi" DiscardNonKey="Frejmovi koji nisu ključni" DiscardAll="Svi frejmovi (oprezno!)" RestartWhenActivated="Ponovi reprodukciju kada izvor postane aktivan" +ColorRange="YUV opseg boja" +ColorRange.Auto="Automatski" +ColorRange.Partial="Delimični" +ColorRange.Full="Potpuni" + MediaFileFilter.AllMediaFiles="Sve medija datoteke" MediaFileFilter.VideoFiles="Video datoteke" diff --git a/plugins/obs-ffmpeg/data/locale/sr-SP.ini b/plugins/obs-ffmpeg/data/locale/sr-SP.ini index 2222674..f4606c7 100644 --- a/plugins/obs-ffmpeg/data/locale/sr-SP.ini +++ b/plugins/obs-ffmpeg/data/locale/sr-SP.ini @@ -1,6 +1,18 @@ FFmpegOutput="FFmpeg излаз" FFmpegAAC="FFmpeg подразумевани AAC енкодер" Bitrate="Проток" +Preset="Шаблон" +KeyframeIntervalSec="Интервал кључних фрејмова (секунде, 0=аутоматски)" + +NVENC.Use2Pass="Користи енкодинг дуплог пролаза" +NVENC.Preset.default="Подразумевани" +NVENC.Preset.hq="Високи квалитет" +NVENC.Preset.hp="Високе перформансе" +NVENC.Preset.bd="Bluray" +NVENC.Preset.ll="Ниско кашњење" +NVENC.Preset.llhq="Високи квалитет ниског кашњења" +NVENC.Preset.llhp="Високе перформансе ниског кашњења" +NVENC.Level="Ниво" FFmpegSource="Медија извор" LocalFile="Локална датотека" @@ -22,6 +34,11 @@ DiscardNonIntra="Не-интра фрејмови" DiscardNonKey="Фрејмови који нису кључни" DiscardAll="Сви фрејмови (опрезно!)" RestartWhenActivated="Понови репродукцију када извор постане активан" +ColorRange="YUV опсег боја" +ColorRange.Auto="Аутоматски" +ColorRange.Partial="Делимични" +ColorRange.Full="Потпуни" + MediaFileFilter.AllMediaFiles="Све медија датотеке" MediaFileFilter.VideoFiles="Видео датотеке" diff --git a/plugins/obs-ffmpeg/data/locale/sv-SE.ini b/plugins/obs-ffmpeg/data/locale/sv-SE.ini index 2b4d1d5..0d1426f 100644 --- a/plugins/obs-ffmpeg/data/locale/sv-SE.ini +++ b/plugins/obs-ffmpeg/data/locale/sv-SE.ini @@ -1,6 +1,17 @@ FFmpegOutput="FFmpeg-utmatning" FFmpegAAC="AAC-kodare (FFmpeg standard)" Bitrate="Bithastighet" +Preset="Förinställning" + +NVENC.Use2Pass="Använd tvåpassavkodning" +NVENC.Preset.default="Standard" +NVENC.Preset.hq="Hög kvalitet" +NVENC.Preset.hp="Hög prestanda" +NVENC.Preset.bd="Bluray" +NVENC.Preset.ll="Låg latens" +NVENC.Preset.llhq="Låg latens, hög kvalitet" +NVENC.Preset.llhp="Låg latens, hög prestanda" +NVENC.Level="Nivå" FFmpegSource="Mediakälla" LocalFile="Lokal fil" @@ -21,5 +32,15 @@ DiscardBiDir="Dubbelriktade bilder" DiscardNonIntra="Icke-Intra bilder" DiscardNonKey="Icke-nyckel bild" DiscardAll="Alla bilder (Varsam!)" +RestartWhenActivated="Starta om uppspelning när källa blir aktiv" +ColorRange="YUV-färgområde" +ColorRange.Auto="Automatisk" +ColorRange.Partial="Delvis" +ColorRange.Full="Full" +MediaFileFilter.AllMediaFiles="Alla mediafiler" +MediaFileFilter.VideoFiles="Videofiler" +MediaFileFilter.AudioFiles="Ljudfiler" +MediaFileFilter.AllFiles="Alla filer" + diff --git a/plugins/obs-ffmpeg/data/locale/th-TH.ini b/plugins/obs-ffmpeg/data/locale/th-TH.ini index c1f6c51..0eafac3 100644 --- a/plugins/obs-ffmpeg/data/locale/th-TH.ini +++ b/plugins/obs-ffmpeg/data/locale/th-TH.ini @@ -2,3 +2,5 @@ Bitrate="บิตเรท" + + diff --git a/plugins/obs-ffmpeg/data/locale/tr-TR.ini b/plugins/obs-ffmpeg/data/locale/tr-TR.ini index e8f70e3..bce3260 100644 --- a/plugins/obs-ffmpeg/data/locale/tr-TR.ini +++ b/plugins/obs-ffmpeg/data/locale/tr-TR.ini @@ -1,6 +1,12 @@ FFmpegOutput="FFmpeg Çıkışı" FFmpegAAC="FFmpeg Varsayılan AAC Kodlayıcı" Bitrate="Bit hızı" +Preset="Ön Tanımlı" +KeyframeIntervalSec="Anahtarkare Aralığı (saniye, 0=otomatik)" + +NVENC.Preset.default="Varsayılan" +NVENC.Preset.hq="Yüksek Kalite" +NVENC.Preset.hp="Yüksek Performans" FFmpegSource="Ortam Kaynağı" LocalFile="Yerel Dosya" @@ -23,3 +29,8 @@ DiscardNonKey="Anahtar Olmayan Kareler" DiscardAll="Tüm Kareler (Dikkatli Olun!)" +MediaFileFilter.AllMediaFiles="Tüm Medya Dosyaları" +MediaFileFilter.VideoFiles="Video Dosyaları" +MediaFileFilter.AudioFiles="Ses Dosyaları" +MediaFileFilter.AllFiles="Tüm Dosyalar" + diff --git a/plugins/obs-ffmpeg/data/locale/zh-CN.ini b/plugins/obs-ffmpeg/data/locale/zh-CN.ini index 792477d..23077a7 100644 --- a/plugins/obs-ffmpeg/data/locale/zh-CN.ini +++ b/plugins/obs-ffmpeg/data/locale/zh-CN.ini @@ -1,6 +1,20 @@ FFmpegOutput="FFmpeg 输出" FFmpegAAC="FFmpeg 默认 AAC 编码器" Bitrate="比特率" +Preset="预设" +RateControl="速率控制" +KeyframeIntervalSec="关键帧间隔(秒, 0=自动)" +Lossless="无损" + +NVENC.Use2Pass="使用 Two-Pass 编码" +NVENC.Preset.default="默认" +NVENC.Preset.hq="高质量" +NVENC.Preset.hp="高性能" +NVENC.Preset.bd="蓝光" +NVENC.Preset.ll="低延迟" +NVENC.Preset.llhq="低延迟高质量" +NVENC.Preset.llhp="低延迟高性能" +NVENC.Level="等级" FFmpegSource="媒体源" LocalFile="本地文件" @@ -22,6 +36,11 @@ DiscardNonIntra="非intra帧" DiscardNonKey="非关键帧" DiscardAll="所有的帧(小心!)" RestartWhenActivated="当源变为活动状态时重新启动播放" +ColorRange="YUV 颜色范围" +ColorRange.Auto="自动" +ColorRange.Partial="局部" +ColorRange.Full="全部" + MediaFileFilter.AllMediaFiles="所有媒体文件" MediaFileFilter.VideoFiles="视频文件" diff --git a/plugins/obs-ffmpeg/data/locale/zh-TW.ini b/plugins/obs-ffmpeg/data/locale/zh-TW.ini index 58fe4d0..447224c 100644 --- a/plugins/obs-ffmpeg/data/locale/zh-TW.ini +++ b/plugins/obs-ffmpeg/data/locale/zh-TW.ini @@ -1,9 +1,11 @@ FFmpegOutput="FFmpeg 輸出" FFmpegAAC="FFmpeg 預設 AAC 編碼器" -Bitrate="位元率" +Bitrate="流量" + FFmpegSource="媒體來源" LocalFile="本機檔案" +Looping="循環" Input="輸入" InputFormat="輸入格式" ForceFormat="強制格式轉換" @@ -15,5 +17,14 @@ VideoBufferSize="影像緩衝區大小 (幀)" FrameDropping="掉幀程度" DiscardNone="無" DiscardDefault="預設 (無效封包)" +DiscardNonRef="非參考幀" +DiscardNonIntra="非內部框架" +DiscardNonKey="非關鍵幀" +DiscardAll="所有幀(小心!)" +MediaFileFilter.AllMediaFiles="所有媒體檔案" +MediaFileFilter.VideoFiles="影像檔" +MediaFileFilter.AudioFiles="音效檔" +MediaFileFilter.AllFiles="所有檔案" + diff --git a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c index 74bb1f4..09fb3b6 100644 --- a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c +++ b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c @@ -17,6 +17,7 @@ #ifdef _WIN32 #include #include +#include #define inline __inline #endif @@ -629,7 +630,11 @@ static inline bool ffmpeg_mux_packet(struct ffmpeg_mux *ffm, uint8_t *buf, /* ------------------------------------------------------------------------- */ +#ifdef _WIN32 +int wmain(int argc, wchar_t *argv_w[]) +#else int main(int argc, char *argv[]) +#endif { struct ffm_packet_info info = {0}; struct ffmpeg_mux ffm = {0}; @@ -638,6 +643,21 @@ int main(int argc, char *argv[]) int ret; #ifdef _WIN32 + char **argv; + + 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); + argv[i] = malloc(size + 1); + WideCharToMultiByte(CP_UTF8, 0, argv_w[i], (int)len, argv[i], + size + 1, NULL, NULL); + argv[i][size] = 0; + } + _setmode(_fileno(stdin), O_BINARY); #endif setvbuf(stderr, NULL, _IONBF, 0); @@ -660,5 +680,11 @@ int main(int argc, char *argv[]) ffmpeg_mux_free(&ffm); resize_buf_free(&rb); + +#ifdef _WIN32 + for (int i = 0; i < argc; i++) + free(argv[i]); + free(argv); +#endif return 0; } diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-compat.h b/plugins/obs-ffmpeg/obs-ffmpeg-compat.h index 9228917..ba35eba 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-compat.h +++ b/plugins/obs-ffmpeg/obs-ffmpeg-compat.h @@ -20,3 +20,6 @@ # define av_frame_free avcodec_free_frame #endif +#if LIBAVCODEC_VERSION_MAJOR >= 57 +#define av_free_packet av_packet_unref +#endif diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-formats.h b/plugins/obs-ffmpeg/obs-ffmpeg-formats.h index 7b70e6e..260f751 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-formats.h +++ b/plugins/obs-ffmpeg/obs-ffmpeg-formats.h @@ -21,6 +21,7 @@ static inline enum AVPixelFormat obs_to_ffmpeg_video_format( 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; } return AV_PIX_FMT_NONE; @@ -37,6 +38,7 @@ static inline enum video_format ffmpeg_to_obs_video_format( 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_NONE: default: return VIDEO_FORMAT_NONE; } diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c new file mode 100644 index 0000000..9c38143 --- /dev/null +++ b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c @@ -0,0 +1,508 @@ +/****************************************************************************** + Copyright (C) 2016 by Hugh Bailey + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "obs-ffmpeg-formats.h" + +#define do_log(level, format, ...) \ + blog(level, "[NVENC encoder: '%s'] " format, \ + 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__) + +struct nvenc_encoder { + obs_encoder_t *encoder; + + AVCodec *nvenc; + AVCodecContext *context; + + AVPicture dst_picture; + AVFrame *vframe; + + DARRAY(uint8_t) buffer; + + uint8_t *header; + size_t header_size; + + uint8_t *sei; + size_t sei_size; + + int height; + bool first_packet; +}; + +static const char *nvenc_getname(void *unused) +{ + UNUSED_PARAMETER(unused); + return "NVENC H.264"; +} + +static inline bool valid_format(enum video_format format) +{ + return format == VIDEO_FORMAT_I420 || + format == VIDEO_FORMAT_NV12 || + format == VIDEO_FORMAT_I444; +} + +static void nvenc_video_info(void *data, struct video_scale_info *info) +{ + struct nvenc_encoder *enc = data; + enum video_format pref_format; + + 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; + } + + info->format = pref_format; +} + +static bool nvenc_init_codec(struct nvenc_encoder *enc) +{ + int ret; + + ret = avcodec_open2(enc->context, enc->nvenc, NULL); + if (ret < 0) { + warn("Failed to open NVENC codec: %s", av_err2str(ret)); + return false; + } + + enc->vframe = av_frame_alloc(); + if (!enc->vframe) { + warn("Failed to allocate video frame"); + return false; + } + + enc->vframe->format = enc->context->pix_fmt; + enc->vframe->width = enc->context->width; + enc->vframe->height = enc->context->height; + enc->vframe->colorspace = enc->context->colorspace; + enc->vframe->color_range = enc->context->color_range; + + ret = avpicture_alloc(&enc->dst_picture, enc->context->pix_fmt, + enc->context->width, enc->context->height); + if (ret < 0) { + warn("Failed to allocate dst_picture: %s", av_err2str(ret)); + return false; + } + + *((AVPicture*)enc->vframe) = enc->dst_picture; + return true; +} + +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) +{ + struct nvenc_encoder *enc = data; + + const char *rc = obs_data_get_string(settings, "rate_control"); + int bitrate = (int)obs_data_get_int(settings, "bitrate"); + int cqp = (int)obs_data_get_int(settings, "cqp"); + int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec"); + const char *preset = obs_data_get_string(settings, "preset"); + const char *profile = obs_data_get_string(settings, "profile"); + const char *level = obs_data_get_string(settings, "level"); + bool twopass = obs_data_get_bool(settings, "2pass"); + int gpu = (int)obs_data_get_int(settings, "gpu"); + bool cbr_override = obs_data_get_bool(settings, "cbr"); + + video_t *video = obs_encoder_video(enc->encoder); + const struct video_output_info *voi = video_output_get_info(video); + struct video_scale_info info; + + /* XXX: "cbr" setting has been deprecated */ + if (cbr_override) { + warn("\"cbr\" setting has been deprecated for all encoders! " + "Please set \"rate_control\" to \"CBR\" instead. " + "Forcing CBR mode. " + "(Note to all: this is why you shouldn't use strings for " + "common settings)"); + rc = "CBR"; + } + + info.format = voi->format; + info.colorspace = voi->colorspace; + info.range = voi->range; + + nvenc_video_info(enc, &info); + av_opt_set_int(enc->context->priv_data, "cbr", false, 0); + + if (astrcmpi(rc, "cqp") == 0) { + bitrate = 0; + enc->context->global_quality = cqp; + + } else if (astrcmpi(rc, "lossless") == 0) { + bitrate = 0; + cqp = 0; + + bool hp = (astrcmpi(preset, "hp") == 0 || + astrcmpi(preset, "llhp") == 0); + + av_opt_set(enc->context->priv_data, "profile", + hp ? "losslesshp" : "lossless", 0); + + } else if (astrcmpi(rc, "vbr") != 0) { /* CBR by default */ + av_opt_set_int(enc->context->priv_data, "cbr", true, 0); + enc->context->rc_max_rate = bitrate * 1000; + enc->context->rc_min_rate = bitrate * 1000; + cqp = 0; + } + + + av_opt_set(enc->context->priv_data, "preset", preset, 0); + av_opt_set(enc->context->priv_data, "level", level, 0); + av_opt_set_int(enc->context->priv_data, "2pass", twopass, 0); + av_opt_set_int(enc->context->priv_data, "gpu", gpu, 0); + + enc->context->bit_rate = bitrate * 1000; + enc->context->rc_buffer_size = bitrate * 1000; + 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->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; + + if (keyint_sec) + enc->context->gop_size = keyint_sec * voi->fps_num / + voi->fps_den; + else + enc->context->gop_size = 250; + + enc->height = enc->context->height; + + info("settings:\n" + "\trate_control: %s\n" + "\tbitrate: %d\n" + "\tcqp: %d\n" + "\tkeyint: %d\n" + "\tpreset: %s\n" + "\tprofile: %s\n" + "\tlevel: %s\n" + "\twidth: %d\n" + "\theight: %d\n" + "\t2-pass: %s\n" + "\tGPU: %d\n", + rc, bitrate, cqp, enc->context->gop_size, + preset, profile, level, + enc->context->width, enc->context->height, + twopass ? "true" : "false", + gpu); + + return nvenc_init_codec(enc); +} + +static void nvenc_destroy(void *data) +{ + struct nvenc_encoder *enc = data; + + avcodec_close(enc->context); + av_frame_free(&enc->vframe); + avpicture_free(&enc->dst_picture); + da_free(enc->buffer); + bfree(enc->header); + bfree(enc->sei); + + bfree(enc); +} + +static void *nvenc_create(obs_data_t *settings, obs_encoder_t *encoder) +{ + struct nvenc_encoder *enc; + + avcodec_register_all(); + + enc = bzalloc(sizeof(*enc)); + enc->encoder = encoder; + enc->nvenc = avcodec_find_encoder_by_name("nvenc_h264"); + enc->first_packet = true; + + blog(LOG_INFO, "---------------------------------"); + + if (!enc->nvenc) { + warn("Couldn't find encoder"); + goto fail; + } + + enc->context = avcodec_alloc_context3(enc->nvenc); + if (!enc->context) { + warn("Failed to create codec context"); + goto fail; + } + + if (!nvenc_update(enc, settings)) + goto fail; + + return enc; + +fail: + nvenc_destroy(enc); + return NULL; +} + +static inline void copy_data(AVPicture *pic, const struct encoder_frame *frame, + int height) +{ + 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 plane_height = plane == 0 ? height : height/2; + + for (int y = 0; y < plane_height; y++) { + int pos_frame = y * frame_rowsize; + int pos_pic = y * pic_rowsize; + + memcpy(pic->data[plane] + pos_pic, + frame->data[plane] + pos_frame, + bytes); + } + } +} + +static bool nvenc_encode(void *data, struct encoder_frame *frame, + struct encoder_packet *packet, bool *received_packet) +{ + struct nvenc_encoder *enc = data; + AVPacket av_pkt = {0}; + int got_packet; + int ret; + + av_init_packet(&av_pkt); + + copy_data(&enc->dst_picture, frame, enc->height); + + enc->vframe->pts = frame->pts; + ret = avcodec_encode_video2(enc->context, &av_pkt, enc->vframe, + &got_packet); + if (ret < 0) { + warn("nvenc_encode: Error encoding: %s", av_err2str(ret)); + return false; + } + + if (got_packet && av_pkt.size) { + if (enc->first_packet) { + uint8_t *new_packet; + 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); + + da_copy_array(enc->buffer, new_packet, size); + bfree(new_packet); + } else { + 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->keyframe = obs_avc_keyframe(packet->data, packet->size); + *received_packet = true; + } else { + *received_packet = false; + } + + av_free_packet(&av_pkt); + return true; +} + +static void nvenc_defaults(obs_data_t *settings) +{ + obs_data_set_default_int(settings, "bitrate", 2500); + obs_data_set_default_int(settings, "keyint_sec", 0); + obs_data_set_default_int(settings, "cqp", 23); + obs_data_set_default_string(settings, "rate_control", "CBR"); + obs_data_set_default_string(settings, "preset", "default"); + obs_data_set_default_string(settings, "profile", "main"); + obs_data_set_default_string(settings, "level", "auto"); + obs_data_set_default_bool(settings, "2pass", true); + obs_data_set_default_int(settings, "gpu", 0); +} + +static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p, + obs_data_t *settings) +{ + const char *rc = obs_data_get_string(settings, "rate_control"); + bool cqp = astrcmpi(rc, "CQP") == 0; + bool lossless = astrcmpi(rc, "lossless") == 0; + size_t count; + + p = obs_properties_get(ppts, "bitrate"); + obs_property_set_visible(p, !cqp && !lossless); + p = obs_properties_get(ppts, "cqp"); + obs_property_set_visible(p, cqp); + + p = obs_properties_get(ppts, "preset"); + count = obs_property_list_item_count(p); + + for (size_t i = 0; i < count; i++) { + bool compatible = (i == 0 || i == 2); + obs_property_list_item_disable(p, i, lossless && !compatible); + } + + return true; +} + +static obs_properties_t *nvenc_properties(void *unused) +{ + UNUSED_PARAMETER(unused); + + obs_properties_t *props = obs_properties_create(); + 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_property_list_add_string(p, "CBR", "CBR"); + obs_property_list_add_string(p, "VBR", "VBR"); + obs_property_list_add_string(p, "CQP", "CQP"); + obs_property_list_add_string(p, obs_module_text("Lossless"), + "lossless"); + + obs_property_set_modified_callback(p, rate_control_modified); + + obs_properties_add_int(props, "bitrate", + obs_module_text("Bitrate"), 50, 300000, 50); + + obs_properties_add_int(props, "cqp", "CQP", 0, 50, 1); + + obs_properties_add_int(props, "keyint_sec", + 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); + +#define add_preset(val) \ + obs_property_list_add_string(p, obs_module_text("NVENC.Preset." val), \ + val) + add_preset("default"); + add_preset("hq"); + add_preset("hp"); + add_preset("bd"); + add_preset("ll"); + add_preset("llhq"); + 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); + +#define add_profile(val) \ + obs_property_list_add_string(p, val, val) + add_profile("high"); + add_profile("main"); + add_profile("baseline"); + add_profile("high444p"); + + p = obs_properties_add_list(props, "level", + obs_module_text("NVENC.Level"), OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); + add_profile("auto"); + add_profile("1" ); + add_profile("1.0" ); + add_profile("1b" ); + add_profile("1.0b"); + add_profile("1.1" ); + add_profile("1.2" ); + add_profile("1.3" ); + add_profile("2" ); + add_profile("2.0" ); + add_profile("2.1" ); + add_profile("2.2" ); + add_profile("3" ); + add_profile("3.0" ); + add_profile("3.1" ); + add_profile("3.2" ); + add_profile("4" ); + add_profile("4.0" ); + add_profile("4.1" ); + add_profile("4.2" ); + add_profile("5" ); + add_profile("5.0" ); + add_profile("5.1" ); +#undef add_profile + + obs_properties_add_bool(props, "2pass", + obs_module_text("NVENC.Use2Pass")); + obs_properties_add_int(props, "gpu", obs_module_text("GPU"), 0, 8, 1); + + return props; +} + +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; + return true; +} + +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; + 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, + .get_properties = nvenc_properties, + .get_extra_data = nvenc_extra_data, + .get_sei_data = nvenc_sei_data, + .get_video_info = nvenc_video_info +}; diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-source.c b/plugins/obs-ffmpeg/obs-ffmpeg-source.c index 9a728c1..c272ef5 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-source.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-source.c @@ -49,6 +49,7 @@ struct ffmpeg_source { char *input; char *input_format; enum AVDiscard frame_drop; + enum video_range_type range; int audio_buffer_size; int video_buffer_size; bool is_advanced; @@ -81,6 +82,9 @@ static bool set_obs_frame_colorprops(struct ff_frame *frame, obs_frame->full_range = frame->frame->color_range == AVCOL_RANGE_JPEG; + if (s->range != VIDEO_RANGE_DEFAULT) + obs_frame->full_range = s->range == VIDEO_RANGE_FULL; + range = obs_frame->full_range ? VIDEO_RANGE_FULL : VIDEO_RANGE_PARTIAL; if (!video_format_get_parameters(obs_cs, @@ -265,7 +269,7 @@ static bool audio_frame(struct ff_frame *frame, void *opaque) uint64_t pts; // Media ended - if (frame == NULL) + if (frame == NULL || frame->frame == NULL) return true; pts = (uint64_t)(frame->pts * 1000000000.0L); @@ -316,10 +320,12 @@ static bool is_advanced_modified(obs_properties_t *props, obs_property_t *abuf = obs_properties_get(props, "audio_buffer_size"); obs_property_t *vbuf = obs_properties_get(props, "video_buffer_size"); obs_property_t *frame_drop = obs_properties_get(props, "frame_drop"); + obs_property_t *color_range = obs_properties_get(props, "color_range"); obs_property_set_visible(fscale, enabled); obs_property_set_visible(abuf, enabled); obs_property_set_visible(vbuf, enabled); obs_property_set_visible(frame_drop, enabled); + obs_property_set_visible(color_range, enabled); return true; } @@ -345,7 +351,9 @@ static const char *audio_filter = static obs_properties_t *ffmpeg_source_getproperties(void *data) { + struct ffmpeg_source *s = data; struct dstr filter = {0}; + struct dstr path = {0}; UNUSED_PARAMETER(data); obs_properties_t *props = obs_properties_create(); @@ -368,10 +376,21 @@ static obs_properties_t *ffmpeg_source_getproperties(void *data) dstr_cat(&filter, obs_module_text("MediaFileFilter.AllFiles")); dstr_cat(&filter, " (*.*)"); + if (s && s->input && *s->input) { + const char *slash; + + dstr_copy(&path, s->input); + dstr_replace(&path, "\\", "/"); + slash = strrchr(path.array, '/'); + if (slash) + dstr_resize(&path, slash - path.array + 1); + } + obs_properties_add_path(props, "local_file", obs_module_text("LocalFile"), OBS_PATH_FILE, - filter.array, NULL); + filter.array, path.array); dstr_free(&filter); + dstr_free(&path); obs_properties_add_bool(props, "looping", obs_module_text("Looping")); @@ -431,6 +450,18 @@ static obs_properties_t *ffmpeg_source_getproperties(void *data) obs_property_set_visible(prop, false); + prop = obs_properties_add_list(props, "color_range", + 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); + obs_property_list_add_int(prop, obs_module_text("ColorRange.Partial"), + VIDEO_RANGE_PARTIAL); + obs_property_list_add_int(prop, obs_module_text("ColorRange.Full"), + VIDEO_RANGE_FULL); + + obs_property_set_visible(prop, false); + return props; } @@ -547,6 +578,7 @@ static void ffmpeg_source_update(void *data, obs_data_t *settings) s->restart_on_activate = obs_data_get_bool(settings, "restart_on_activate"); s->is_forcing_scale = true; + s->range = VIDEO_RANGE_DEFAULT; if (is_advanced) { s->audio_buffer_size = (int)obs_data_get_int(settings, @@ -557,6 +589,8 @@ static void ffmpeg_source_update(void *data, obs_data_t *settings) "frame_drop"); s->is_forcing_scale = obs_data_get_bool(settings, "force_scale"); + s->range = (enum video_range_type)obs_data_get_int(settings, + "color_range"); if (s->audio_buffer_size < 1) { s->audio_buffer_size = 1; diff --git a/plugins/obs-ffmpeg/obs-ffmpeg.c b/plugins/obs-ffmpeg/obs-ffmpeg.c index d4e4f0b..943e6c5 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg.c @@ -1,6 +1,8 @@ #include #include +#include #include +#include #include OBS_DECLARE_MODULE() @@ -10,6 +12,7 @@ extern struct obs_source_info ffmpeg_source; extern struct obs_output_info ffmpeg_output; extern struct obs_output_info ffmpeg_muxer; extern struct obs_encoder_info aac_encoder_info; +extern struct obs_encoder_info nvenc_encoder_info; static DARRAY(struct log_context { void *context; @@ -111,6 +114,27 @@ cleanup: destroy_log_context(log_context); } +static bool nvenc_supported(void) +{ + AVCodec *nvenc = avcodec_find_encoder_by_name("nvenc_h264"); + void *lib = NULL; + + if (!nvenc) + return false; + +#if defined(_WIN32) + if (sizeof(void*) == 8) { + lib = os_dlopen("nvEncodeAPI64.dll"); + } else { + lib = os_dlopen("nvEncodeAPI.dll"); + } +#else + lib = os_dlopen("libnvidia-encode.so.1"); +#endif + os_dlclose(lib); + return !!lib; +} + bool obs_module_load(void) { da_init(active_log_contexts); @@ -122,6 +146,10 @@ bool obs_module_load(void) obs_register_output(&ffmpeg_output); obs_register_output(&ffmpeg_muxer); obs_register_encoder(&aac_encoder_info); + if (nvenc_supported()) { + blog(LOG_INFO, "NVENC supported"); + obs_register_encoder(&nvenc_encoder_info); + } return true; } diff --git a/plugins/obs-filters/chroma-key-filter.c b/plugins/obs-filters/chroma-key-filter.c index d00725d..728135e 100644 --- a/plugins/obs-filters/chroma-key-filter.c +++ b/plugins/obs-filters/chroma-key-filter.c @@ -194,8 +194,9 @@ static void chroma_key_render(void *data, gs_effect_t *effect) uint32_t height = obs_source_get_base_height(target); struct vec2 pixel_size; - obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING); + if (!obs_source_process_filter_begin(filter->context, GS_RGBA, + OBS_ALLOW_DIRECT_RENDERING)) + return; vec2_set(&pixel_size, 1.0f / (float)width, 1.0f / (float)height); diff --git a/plugins/obs-filters/color-filter.c b/plugins/obs-filters/color-filter.c index f31b5c1..8238a59 100644 --- a/plugins/obs-filters/color-filter.c +++ b/plugins/obs-filters/color-filter.c @@ -119,8 +119,9 @@ static void color_filter_render(void *data, gs_effect_t *effect) { struct color_filter_data *filter = data; - obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING); + if (!obs_source_process_filter_begin(filter->context, GS_RGBA, + OBS_ALLOW_DIRECT_RENDERING)) + return; gs_effect_set_vec4(filter->color_param, &filter->color); gs_effect_set_float(filter->contrast_param, filter->contrast); diff --git a/plugins/obs-filters/color-key-filter.c b/plugins/obs-filters/color-key-filter.c index b6e4bef..1b1c310 100644 --- a/plugins/obs-filters/color-key-filter.c +++ b/plugins/obs-filters/color-key-filter.c @@ -166,8 +166,9 @@ static void color_key_render(void *data, gs_effect_t *effect) { struct color_key_filter_data *filter = data; - obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING); + if (!obs_source_process_filter_begin(filter->context, GS_RGBA, + OBS_ALLOW_DIRECT_RENDERING)) + return; gs_effect_set_vec4(filter->color_param, &filter->color); gs_effect_set_float(filter->contrast_param, filter->contrast); diff --git a/plugins/obs-filters/crop-filter.c b/plugins/obs-filters/crop-filter.c index b97435d..11070fa 100644 --- a/plugins/obs-filters/crop-filter.c +++ b/plugins/obs-filters/crop-filter.c @@ -193,8 +193,9 @@ static void crop_filter_render(void *data, gs_effect_t *effect) { struct crop_filter_data *filter = data; - obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_NO_DIRECT_RENDERING); + if (!obs_source_process_filter_begin(filter->context, GS_RGBA, + 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); diff --git a/plugins/obs-filters/data/blend_add_filter.effect b/plugins/obs-filters/data/blend_add_filter.effect index ccb5107..ad7189f 100644 --- a/plugins/obs-filters/data/blend_add_filter.effect +++ b/plugins/obs-filters/data/blend_add_filter.effect @@ -1,8 +1,5 @@ uniform float4x4 ViewProj; uniform texture2d image; -uniform float4x4 color_matrix; -uniform float3 color_range_min = {0.0, 0.0, 0.0}; -uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform texture2d target; uniform float4 color; @@ -44,19 +41,6 @@ float4 PSAddImageRGBA(VertDataOut v_in) : TARGET return rgba; } -float4 PSAddImageMatrix(VertDataOut v_in) : TARGET -{ - float4 yuv = image.Sample(textureSampler, v_in.uv); - yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max); - - float4 rgba = saturate(mul(float4(yuv.xyz, 1.0), color_matrix)) * - color; - - float4 targetRGB = target.Sample(textureSampler, v_in.uv2); - rgba.rgb = saturate(rgba.rgb + targetRGB.rgb); - return rgba; -} - technique Draw { pass @@ -65,12 +49,3 @@ technique Draw pixel_shader = PSAddImageRGBA(v_in); } } - -technique DrawMatrix -{ - pass - { - vertex_shader = VSDefault(v_in); - pixel_shader = PSAddImageMatrix(v_in); - } -} diff --git a/plugins/obs-filters/data/blend_mul_filter.effect b/plugins/obs-filters/data/blend_mul_filter.effect index 94bbe59..c4c793a 100644 --- a/plugins/obs-filters/data/blend_mul_filter.effect +++ b/plugins/obs-filters/data/blend_mul_filter.effect @@ -1,8 +1,5 @@ uniform float4x4 ViewProj; uniform texture2d image; -uniform float4x4 color_matrix; -uniform float3 color_range_min = {0.0, 0.0, 0.0}; -uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform texture2d target; uniform float4 color; @@ -44,19 +41,6 @@ float4 PSMuliplyImageRGBA(VertDataOut v_in) : TARGET return rgba; } -float4 PSMuliplyImageMatrix(VertDataOut v_in) : TARGET -{ - float4 yuv = image.Sample(textureSampler, v_in.uv); - yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max); - - float4 rgba = saturate(mul(float4(yuv.xyz, 1.0), color_matrix)) * - color; - - float4 targetRGB = target.Sample(textureSampler, v_in.uv2); - rgba.rgb = saturate(rgba.rgb * targetRGB.rgb); - return rgba; -} - technique Draw { pass @@ -65,12 +49,3 @@ technique Draw pixel_shader = PSMuliplyImageRGBA(v_in); } } - -technique DrawMatrix -{ - pass - { - vertex_shader = VSDefault(v_in); - pixel_shader = PSMuliplyImageMatrix(v_in); - } -} diff --git a/plugins/obs-filters/data/blend_sub_filter.effect b/plugins/obs-filters/data/blend_sub_filter.effect index 5b63329..a91aa71 100644 --- a/plugins/obs-filters/data/blend_sub_filter.effect +++ b/plugins/obs-filters/data/blend_sub_filter.effect @@ -1,8 +1,5 @@ uniform float4x4 ViewProj; uniform texture2d image; -uniform float4x4 color_matrix; -uniform float3 color_range_min = {0.0, 0.0, 0.0}; -uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform texture2d target; uniform float4 color; @@ -44,19 +41,6 @@ float4 PSSubtractImageRGBA(VertDataOut v_in) : TARGET return rgba; } -float4 PSSubtractImageMatrix(VertDataOut v_in) : TARGET -{ - float4 yuv = image.Sample(textureSampler, v_in.uv); - yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max); - - float4 rgba = saturate(mul(float4(yuv.xyz, 1.0), color_matrix)) * - color; - - float4 targetRGB = target.Sample(textureSampler, v_in.uv2); - rgba.rgb = saturate(rgba.rgb - targetRGB.rgb); - return rgba; -} - technique Draw { pass @@ -65,12 +49,3 @@ technique Draw pixel_shader = PSSubtractImageRGBA(v_in); } } - -technique DrawMatrix -{ - pass - { - vertex_shader = VSDefault(v_in); - pixel_shader = PSSubtractImageMatrix(v_in); - } -} diff --git a/plugins/obs-filters/data/chroma_key_filter.effect b/plugins/obs-filters/data/chroma_key_filter.effect index 79df925..8a75968 100644 --- a/plugins/obs-filters/data/chroma_key_filter.effect +++ b/plugins/obs-filters/data/chroma_key_filter.effect @@ -1,11 +1,5 @@ uniform float4x4 ViewProj; uniform texture2d image; -uniform float4x4 color_matrix = {1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0}; -uniform float3 color_range_min = {0.0, 0.0, 0.0}; -uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform float4x4 yuv_mat = { 0.182586, 0.614231, 0.062007, 0.062745, -0.100644, -0.338572, 0.439216, 0.501961, @@ -54,41 +48,30 @@ float GetChromaDist(float3 rgb) return distance(chroma_key, yuvx.yz); } -float4 SampleYUVToRGB(float2 uv) +float4 SampleTexture(float2 uv) { - float4 yuv = image.Sample(textureSampler, uv); - yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max); - return saturate(mul(float4(yuv.xyz, 1.0), color_matrix)); + return image.Sample(textureSampler, uv); } -float4 SampleTexture(float2 uv, bool use_matrix) -{ - if (use_matrix) { - return SampleYUVToRGB(uv); - } else { - return image.Sample(textureSampler, uv); - } -} - -float GetBoxFilteredChromaDist(float3 rgb, float2 texCoord, bool use_matrix) +float GetBoxFilteredChromaDist(float3 rgb, float2 texCoord) { float distVal = GetChromaDist(rgb); - distVal += GetChromaDist(SampleTexture(texCoord-pixel_size, use_matrix).rgb); - distVal += GetChromaDist(SampleTexture(texCoord-float2(pixel_size.x, 0.0), use_matrix).rgb); - distVal += GetChromaDist(SampleTexture(texCoord-float2(pixel_size.x, -pixel_size.y), use_matrix).rgb); + distVal += GetChromaDist(SampleTexture(texCoord-pixel_size).rgb); + distVal += GetChromaDist(SampleTexture(texCoord-float2(pixel_size.x, 0.0)).rgb); + distVal += GetChromaDist(SampleTexture(texCoord-float2(pixel_size.x, -pixel_size.y)).rgb); - distVal += GetChromaDist(SampleTexture(texCoord-float2(0.0, pixel_size.y), use_matrix).rgb); - distVal += GetChromaDist(SampleTexture(texCoord+float2(0.0, pixel_size.y), use_matrix).rgb); + distVal += GetChromaDist(SampleTexture(texCoord-float2(0.0, pixel_size.y)).rgb); + distVal += GetChromaDist(SampleTexture(texCoord+float2(0.0, pixel_size.y)).rgb); - distVal += GetChromaDist(SampleTexture(texCoord+float2(pixel_size.x, -pixel_size.y), use_matrix).rgb); - distVal += GetChromaDist(SampleTexture(texCoord+float2(pixel_size.x, 0.0), use_matrix).rgb); - distVal += GetChromaDist(SampleTexture(texCoord+pixel_size, use_matrix).rgb); + distVal += GetChromaDist(SampleTexture(texCoord+float2(pixel_size.x, -pixel_size.y)).rgb); + distVal += GetChromaDist(SampleTexture(texCoord+float2(pixel_size.x, 0.0)).rgb); + distVal += GetChromaDist(SampleTexture(texCoord+pixel_size).rgb); return distVal / 9.0; } -float4 ProcessChromaKey(float4 rgba, VertData v_in, bool use_matrix) +float4 ProcessChromaKey(float4 rgba, VertData v_in) { - float chromaDist = GetBoxFilteredChromaDist(rgba.rgb, v_in.uv, use_matrix); + float chromaDist = GetBoxFilteredChromaDist(rgba.rgb, v_in.uv); float baseMask = chromaDist - similarity; float fullMask = pow(saturate(baseMask / smoothness), 1.5); float spillVal = pow(saturate(baseMask / spill), 1.5); @@ -104,13 +87,7 @@ float4 ProcessChromaKey(float4 rgba, VertData v_in, bool use_matrix) float4 PSChromaKeyRGBA(VertData v_in) : TARGET { float4 rgba = image.Sample(textureSampler, v_in.uv) * color; - return ProcessChromaKey(rgba, v_in, false); -} - -float4 PSChromaKeyMatrix(VertData v_in) : TARGET -{ - float4 rgba = SampleYUVToRGB(v_in.uv) * color; - return ProcessChromaKey(rgba, v_in, true); + return ProcessChromaKey(rgba, v_in); } technique Draw @@ -121,12 +98,3 @@ technique Draw pixel_shader = PSChromaKeyRGBA(v_in); } } - -technique DrawMatrix -{ - pass - { - vertex_shader = VSDefault(v_in); - pixel_shader = PSChromaKeyMatrix(v_in); - } -} diff --git a/plugins/obs-filters/data/color_filter.effect b/plugins/obs-filters/data/color_filter.effect index 712ca4b..5f4eecd 100644 --- a/plugins/obs-filters/data/color_filter.effect +++ b/plugins/obs-filters/data/color_filter.effect @@ -1,8 +1,5 @@ uniform float4x4 ViewProj; uniform texture2d image; -uniform float4x4 color_matrix; -uniform float3 color_range_min = {0.0, 0.0, 0.0}; -uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform float4 color; uniform float contrast; @@ -39,15 +36,6 @@ float4 PSColorFilterRGBA(VertData v_in) : TARGET return CalcColor(rgba); } -float4 PSColorFilterMatrix(VertData v_in) : TARGET -{ - float4 yuv = image.Sample(textureSampler, v_in.uv); - yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max); - float4 rgba = saturate(mul(float4(yuv.xyz, 1.0), color_matrix)) * color; - - return CalcColor(rgba); -} - technique Draw { pass @@ -56,12 +44,3 @@ technique Draw pixel_shader = PSColorFilterRGBA(v_in); } } - -technique DrawMatrix -{ - pass - { - vertex_shader = VSDefault(v_in); - pixel_shader = PSColorFilterMatrix(v_in); - } -} diff --git a/plugins/obs-filters/data/color_key_filter.effect b/plugins/obs-filters/data/color_key_filter.effect index 7d611ec..599d088 100644 --- a/plugins/obs-filters/data/color_key_filter.effect +++ b/plugins/obs-filters/data/color_key_filter.effect @@ -1,11 +1,5 @@ uniform float4x4 ViewProj; uniform texture2d image; -uniform float4x4 color_matrix = {1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0}; -uniform float3 color_range_min = {0.0, 0.0, 0.0}; -uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform float4 color; uniform float contrast; @@ -67,12 +61,6 @@ float4 PSColorKeyRGBA(VertData v_in) : TARGET return ProcessColorKey(rgba, v_in); } -float4 PSColorKeyMatrix(VertData v_in) : TARGET -{ - float4 rgba = SampleYUVToRGB(v_in.uv) * color; - return ProcessColorKey(rgba, v_in); -} - technique Draw { pass @@ -81,12 +69,3 @@ technique Draw pixel_shader = PSColorKeyRGBA(v_in); } } - -technique DrawMatrix -{ - pass - { - vertex_shader = VSDefault(v_in); - pixel_shader = PSColorKeyMatrix(v_in); - } -} diff --git a/plugins/obs-filters/data/locale/ar-SA.ini b/plugins/obs-filters/data/locale/ar-SA.ini new file mode 100644 index 0000000..d1c53ff --- /dev/null +++ b/plugins/obs-filters/data/locale/ar-SA.ini @@ -0,0 +1,15 @@ +CropFilter="إقتطاع" +ScrollFilter="التمرير" +DelayMs="التأخير (مللي ثانية)" +Type="النّوع" +Contrast="التباين" +Gamma="غاما" +BrowsePath.Images="كل ملفات الصور" +BrowsePath.AllFiles="‮كل الملفات" +Crop.Width="العرض" +Crop.Height="الإرتفاع" +CustomColor="لون مخصص" +Red="أحمر" +Green="أخضر" +Blue="أزرق" + diff --git a/plugins/obs-filters/data/locale/ca-ES.ini b/plugins/obs-filters/data/locale/ca-ES.ini index bbffdd0..b418a1e 100644 --- a/plugins/obs-filters/data/locale/ca-ES.ini +++ b/plugins/obs-filters/data/locale/ca-ES.ini @@ -50,4 +50,5 @@ NoiseGate.AttackTime="Temps d'atac (mil·lisegons)" NoiseGate.HoldTime="Temps de mantenir (mil·lisegons)" NoiseGate.ReleaseTime="Temps d'alliberar (mil·lisegons)" Gain.GainDB="Guany (dB)" +StretchImage="Expandir imatge (descarta la relació d'aspecte d'imatge)" diff --git a/plugins/obs-filters/data/locale/da-DK.ini b/plugins/obs-filters/data/locale/da-DK.ini index 646df30..da181b5 100644 --- a/plugins/obs-filters/data/locale/da-DK.ini +++ b/plugins/obs-filters/data/locale/da-DK.ini @@ -2,8 +2,12 @@ ColorFilter="Farvekorrektion" MaskFilter="Billede maske/blanding" AsyncDelayFilter="Video forsinkelse (asynkron)" CropFilter="Beskær" +ScrollFilter="Rul" ChromaKeyFilter="Chroma nøgle" ColorKeyFilter="Farvenøgle" +SharpnessFilter="Skarphed" +NoiseGate="Noise Gate" +Gain="Forstærkning" DelayMs="Forsinkelse (millisekunder)" Type="Type" MaskBlendType.MaskColor="Alpha maske (farvekanal)" @@ -27,11 +31,19 @@ ColorSpillReduction="Nøglefarve udslipsreduktion (1-1000)" Crop.Left="Venstre" Crop.Right="Højre" Crop.Top="Top" +Crop.Bottom="Bund" +Crop.Width="Bredde" Crop.Height="Højde" Crop.Relative="Relativ" +ScrollFilter.SpeedX="Horisontal hastighed" +ScrollFilter.SpeedY="Vertikal hastighed" +ScrollFilter.LimitWidth="Begræns bredde" +ScrollFilter.LimitHeight="Begræns højde" CustomColor="Brugerdefineret farve" Red="Rød" Green="Grøn" Blue="Blå" Magenta="Magenta" +Gain.GainDB="Forstærkning (dB)" +StretchImage="Stræk billedet (ignorer størrelsesforhold)" diff --git a/plugins/obs-filters/data/locale/el-GR.ini b/plugins/obs-filters/data/locale/el-GR.ini index e25c763..38268a4 100644 --- a/plugins/obs-filters/data/locale/el-GR.ini +++ b/plugins/obs-filters/data/locale/el-GR.ini @@ -36,5 +36,8 @@ Red="Κόκκινο" Green="Πράσινο" Blue="Μπλε" Magenta="Ματζέντα" +NoiseGate.AttackTime="Χρόνος προσβολής (msec)" +NoiseGate.HoldTime="Χρόνος αναμονής (msec)" +NoiseGate.ReleaseTime="Χρόνος διάχυσης (msec)" Gain.GainDB="Απολαβή (dB)" diff --git a/plugins/obs-filters/data/locale/eu-ES.ini b/plugins/obs-filters/data/locale/eu-ES.ini index 3fbaa03..1b7c39c 100644 --- a/plugins/obs-filters/data/locale/eu-ES.ini +++ b/plugins/obs-filters/data/locale/eu-ES.ini @@ -1,54 +1,54 @@ -ColorFilter="Margo Zuzenketa" -MaskFilter="Irudi Mozorro/Nahasketa" -AsyncDelayFilter="Bideo Atzerapena (Async)" +ColorFilter="Kolore-zuzenketa" +MaskFilter="Irudi maskara/nahasketa" +AsyncDelayFilter="Bideo atzerapena (Async)" CropFilter="Moztu" -ScrollFilter="Irristatu" -ChromaKeyFilter="Margo Giltza" -ColorKeyFilter="Margo Giltza" -SharpnessFilter="Zorrotza" -NoiseGate="Zarata Atartea" +ScrollFilter="Korritu" +ChromaKeyFilter="Kroma gakoa" +ColorKeyFilter="Kolore gakoa" +SharpnessFilter="Enfokea" +NoiseGate="Zarata atalasea" Gain="Irabazia" -DelayMs="Atzerapen (segundumilaen)" +DelayMs="Atzerapena (milisegundo)" Type="Mota" -MaskBlendType.MaskColor="Alfa Mozorroa (Margo Bidea)" -MaskBlendType.MaskAlpha="Alfa Mozorroa (Alfa Bidea)" -MaskBlendType.BlendMultiply="Nahasketa (Biderketa)" -MaskBlendType.BlendAddition="Nahasketa (Gehiketa)" -MaskBlendType.BlendSubtraction="Nahasketa (Kenketa)" -Path="Helburua" -Color="Margoa" -Opacity="Argikaiztasuna" -Contrast="Zuribeltztasuna" -Brightness="Dizdira" -Gamma="Gama" -BrowsePath.Images="Irudi Agiri Guztiak" -BrowsePath.AllFiles="Agiri Guztiak" -KeyColorType="Giltza Margo Mota" -KeyColor="Giltza Margoa" +MaskBlendType.MaskColor="Alfa maskara (kolore kanala)" +MaskBlendType.MaskAlpha="Alfa maskara (Alfa kanala)" +MaskBlendType.BlendMultiply="Nahasketa (biderketa)" +MaskBlendType.BlendAddition="Nahasketa (batuketa)" +MaskBlendType.BlendSubtraction="Nahasketa (kenketa)" +Path="Bidea" +Color="Kolorea" +Opacity="Opakutasuna" +Contrast="Kontrastea" +Brightness="Distira" +Gamma="Gamma" +BrowsePath.Images="Irudi-fitxategi guztiak" +BrowsePath.AllFiles="Fitxategi guztiak" +KeyColorType="Kolore gako mota" +KeyColor="Kolore gakoa" Similarity="Antzekotasuna (1-1000)" Smoothness="Lehuntasuna (1-1000)" -ColorSpillReduction="Giltza Margo Isuri Murrizpena (1-1000)" +ColorSpillReduction="Kolore gakoaren isuri murrizpena (1-1000)" Crop.Left="Ezker" Crop.Right="Eskuin" -Crop.Top="Goi" -Crop.Bottom="Behe" +Crop.Top="Goian" +Crop.Bottom="Behean" Crop.Width="Zabalera" -Crop.Height="Garaiera" +Crop.Height="Altuera" Crop.Relative="Erlatiboa" -ScrollFilter.SpeedX="Etzaneko Abiadura" -ScrollFilter.SpeedY="Zutikako Abiadura" -ScrollFilter.LimitWidth="Mugatu Zabalera" -ScrollFilter.LimitHeight="Mugatu Garaiera" -CustomColor="Norbere Margoa" +ScrollFilter.SpeedX="Abiadura horizontala" +ScrollFilter.SpeedY="Abiadura bertikala" +ScrollFilter.LimitWidth="Mugatu zabalera" +ScrollFilter.LimitHeight="Mugatu altuera" +CustomColor="Kolore pertsonalizatua" Red="Gorria" -Green="Orlegia" +Green="Berdea" Blue="Urdina" Magenta="Magenta" -NoiseGate.OpenThreshold="Irekiera Muga (dB)" -NoiseGate.CloseThreshold="Itxiera Muga (dB)" -NoiseGate.AttackTime="Eraso denbora (segundumilaen)" -NoiseGate.HoldTime="Heuste denbora (segundumilaen)" -NoiseGate.ReleaseTime="Askapen denbora (segundumilaen)" +NoiseGate.OpenThreshold="Irekiera muga (dB)" +NoiseGate.CloseThreshold="Itxiera muga (dB)" +NoiseGate.AttackTime="Eraso denbora (milisegundo)" +NoiseGate.HoldTime="Euste denbora (milisegundo)" +NoiseGate.ReleaseTime="Askatze denbora (milisegundo)" Gain.GainDB="Irabazia (dB)" -StretchImage="Luzatu Irudia (baztertu irudiaren ikuspegi maila)" +StretchImage="Luzatu irudia (baztertu irudiaren aspektu-erlazioa)" diff --git a/plugins/obs-filters/data/locale/fr-FR.ini b/plugins/obs-filters/data/locale/fr-FR.ini index 5789805..f44a0a0 100644 --- a/plugins/obs-filters/data/locale/fr-FR.ini +++ b/plugins/obs-filters/data/locale/fr-FR.ini @@ -1,9 +1,9 @@ -ColorFilter="Correction des couleurs" +ColorFilter="Corrections colorimétrique" MaskFilter="Masque d'image/mélange" AsyncDelayFilter="Délai vidéo (async.)" CropFilter="Rogner" ScrollFilter="Défilement" -ChromaKeyFilter="Chroma Key" +ChromaKeyFilter="Clé chromatique" ColorKeyFilter="Couleur d'incrustation" SharpnessFilter="Accentuer" NoiseGate="Noise Gate" diff --git a/plugins/obs-filters/data/locale/he-IL.ini b/plugins/obs-filters/data/locale/he-IL.ini new file mode 100644 index 0000000..28b9161 --- /dev/null +++ b/plugins/obs-filters/data/locale/he-IL.ini @@ -0,0 +1,54 @@ +ColorFilter="תיקון צבע" +MaskFilter="מסכה/עירבוב תמונה" +AsyncDelayFilter="השהיית וידאו (אסינכרונית)" +CropFilter="חתוך" +ScrollFilter="גלול" +ChromaKeyFilter="מסך כחול" +ColorKeyFilter="מפתח צבע" +SharpnessFilter="חידוד" +NoiseGate="שער רעש" +Gain="הגברה" +DelayMs="השהייה (אלפיות שניה)" +Type="סוג" +MaskBlendType.MaskColor="מסכת אלפא (ערוץ צבע)" +MaskBlendType.MaskAlpha="מסכת אלפא (ערוץ אלפא)" +MaskBlendType.BlendMultiply="עירבוב (להכפיל)" +MaskBlendType.BlendAddition="עירבוב (תוספת)" +MaskBlendType.BlendSubtraction="עירבוב (חיסור)" +Path="נתיב" +Color="צבע" +Opacity="אטימות" +Contrast="ניגודיות" +Brightness="בהירות" +Gamma="גאמה" +BrowsePath.Images="כל קיבצי תמונה" +BrowsePath.AllFiles="כל הקבצים" +KeyColorType="סוג מפתח צבע" +KeyColor="מפתח צבע" +Similarity="תאימות (1-1000)" +Smoothness="חלקות (1-1000)" +ColorSpillReduction="הפחתת פיזור צבע מפתח (1-1000)" +Crop.Left="שמאל" +Crop.Right="ימין" +Crop.Top="עליון" +Crop.Bottom="תחתון" +Crop.Width="רוחב" +Crop.Height="גובה" +Crop.Relative="יחסיות" +ScrollFilter.SpeedX="מהירות אופקית" +ScrollFilter.SpeedY="מהירות אנכית" +ScrollFilter.LimitWidth="מגבלת רוחב" +ScrollFilter.LimitHeight="מגבלת גובה" +CustomColor="צבע מותאם אישית" +Red="אדום" +Green="ירוק" +Blue="כחול" +Magenta="מגנטה" +NoiseGate.OpenThreshold="פתח סף (dB)" +NoiseGate.CloseThreshold="סגור את הסף (dB)" +NoiseGate.AttackTime="זמן התקפה (אלפיות שניה)" +NoiseGate.HoldTime="זמן החזקה (אלפיות שניה)" +NoiseGate.ReleaseTime="זמן שחרור (אלפיות שניה)" +Gain.GainDB="הגברה (dB)" +StretchImage="מתח תמונה (יחס הגובה-רוחב של התמונה לא ישמר)" + diff --git a/plugins/obs-filters/data/locale/hu-HU.ini b/plugins/obs-filters/data/locale/hu-HU.ini index 588baa4..4a74a88 100644 --- a/plugins/obs-filters/data/locale/hu-HU.ini +++ b/plugins/obs-filters/data/locale/hu-HU.ini @@ -1,20 +1,20 @@ ColorFilter="Színkorrekció" MaskFilter="Képmaszk/Keverés" -AsyncDelayFilter="Videó Késleltetés (Async)" +AsyncDelayFilter="Videó késleltetés (Async)" CropFilter="Vágás" ScrollFilter="Görgetés" -ChromaKeyFilter="Chroma Kulcs" +ChromaKeyFilter="Chroma kulcs" ColorKeyFilter="Színkulcs" SharpnessFilter="Élesítés" NoiseGate="Zajgát" Gain="Erősítés" DelayMs="Késleltetés (ezredmásodperc)" Type="Típus" -MaskBlendType.MaskColor="Alfa Maszk (Színcsatorna)" -MaskBlendType.MaskAlpha="Alfa Maszk (Alfacsatorna)" -MaskBlendType.BlendMultiply="Keverés (Szorzás)" -MaskBlendType.BlendAddition="Keverés (Kiegészítés)" -MaskBlendType.BlendSubtraction="Keverés (Kivonás)" +MaskBlendType.MaskColor="Alfa maszk (színcsatorna)" +MaskBlendType.MaskAlpha="Alfa maszk (alfacsatorna)" +MaskBlendType.BlendMultiply="Keverés (szorzás)" +MaskBlendType.BlendAddition="Keverés (kiegészítés)" +MaskBlendType.BlendSubtraction="Keverés (kivonás)" Path="Elérési Út" Color="Szín" Opacity="Áttetszőség" @@ -23,11 +23,11 @@ Brightness="Fényerő" Gamma="Gamma" BrowsePath.Images="Összes képfájl" BrowsePath.AllFiles="Minden fájl" -KeyColorType="Kulcsszín Típus" +KeyColorType="Kulcsszín típus" KeyColor="Kulcsszín" Similarity="Hasonlóság (1-1000)" Smoothness="Simaság (1-1000)" -ColorSpillReduction="Kulcsszín Szennyezés Csökkentés (1-1000)" +ColorSpillReduction="Kulcsszín szennyezés csökkentés (1-1000)" Crop.Left="Bal" Crop.Right="Jobb" Crop.Top="Fent" @@ -37,9 +37,9 @@ Crop.Height="Magasság" Crop.Relative="Relatív" ScrollFilter.SpeedX="Vízszintes sebesség" ScrollFilter.SpeedY="Függőleges sebesség" -ScrollFilter.LimitWidth="Szélesség Limit" -ScrollFilter.LimitHeight="Magasság Limit" -CustomColor="Egyéni Szín" +ScrollFilter.LimitWidth="Szélesség limit" +ScrollFilter.LimitHeight="Magasság limit" +CustomColor="Egyéni szín" Red="Piros" Green="Zöld" Blue="Kék" @@ -50,5 +50,5 @@ NoiseGate.AttackTime="Aktiválási idő (ezredmásodperc)" NoiseGate.HoldTime="Kitartás ideje (ezredmásodperc)" NoiseGate.ReleaseTime="Felengedés ideje (ezredmásodperc)" Gain.GainDB="Erősítés (dB)" -StretchImage="Kép Nyújtása (képarány elvetésével)" +StretchImage="Kép nyújtása (képarány elvetésével)" diff --git a/plugins/obs-filters/data/locale/it-IT.ini b/plugins/obs-filters/data/locale/it-IT.ini index 18025d8..c4f171a 100644 --- a/plugins/obs-filters/data/locale/it-IT.ini +++ b/plugins/obs-filters/data/locale/it-IT.ini @@ -1,17 +1,17 @@ -ColorFilter="Correzione del colore" +ColorFilter="Correzione colore" MaskFilter="Immagine maschera/miscela" AsyncDelayFilter="Ritardo video (Asincrono)" CropFilter="Ritaglia" ScrollFilter="Scorrimento" ChromaKeyFilter="Chroma Key" -ColorKeyFilter="Color Key" +ColorKeyFilter="Chiave Colore" SharpnessFilter="Nitidizza" NoiseGate="Noise Gate" Gain="Incremento" -DelayMs="Ritardo (in millisecondi)" +DelayMs="Ritardo (millisecondi)" Type="Tipo" MaskBlendType.MaskColor="Maschera alfa (canale di colore)" -MaskBlendType.MaskAlpha="Maschera alfa (Alpha Channel)" +MaskBlendType.MaskAlpha="Maschera alfa (Canale alpha)" MaskBlendType.BlendMultiply="Miscela (moltiplica)" MaskBlendType.BlendAddition="Miscela (aggiunta)" MaskBlendType.BlendSubtraction="Miscela (sottrazione)" diff --git a/plugins/obs-filters/data/locale/ja-JP.ini b/plugins/obs-filters/data/locale/ja-JP.ini index 57372a0..1464b2c 100644 --- a/plugins/obs-filters/data/locale/ja-JP.ini +++ b/plugins/obs-filters/data/locale/ja-JP.ini @@ -10,9 +10,9 @@ NoiseGate="ノイズゲート" Gain="ゲイン" DelayMs="遅延時間 (ミリ秒)" Type="種別" -MaskBlendType.MaskColor="アルファ マスク(カラー チャンネル)" +MaskBlendType.MaskColor="アルファマスク (カラーチャンネル)" MaskBlendType.MaskAlpha="アルファ マスク (アルファ チャネル)" -MaskBlendType.BlendMultiply="合成(乗算)" +MaskBlendType.BlendMultiply="合成 (乗算)" MaskBlendType.BlendAddition="合成 (加算)" MaskBlendType.BlendSubtraction="合成 (減算)" Path="パス" @@ -25,7 +25,7 @@ BrowsePath.Images="すべての画像ファイル" BrowsePath.AllFiles="すべてのファイル" KeyColorType="色キーの種類" KeyColor="キーの色" -Similarity="類似性(1-1000)" +Similarity="類似性 (1-1000)" Smoothness="滑らかさ (1-1000)" ColorSpillReduction="キーカラー流出低減 (1-1000)" Crop.Left="左" @@ -50,5 +50,5 @@ NoiseGate.AttackTime="動作開始時間 (ミリ秒)" NoiseGate.HoldTime="保持時間 (ミリ秒)" NoiseGate.ReleaseTime="解除時間 (ミリ秒)" Gain.GainDB="ゲイン (dB)" -StretchImage="画像を拡大(アスペクト比を破棄)" +StretchImage="画像を拡大 (アスペクト比を破棄)" diff --git a/plugins/obs-filters/data/locale/pt-BR.ini b/plugins/obs-filters/data/locale/pt-BR.ini index 5de8ba8..c55ce0c 100644 --- a/plugins/obs-filters/data/locale/pt-BR.ini +++ b/plugins/obs-filters/data/locale/pt-BR.ini @@ -2,52 +2,53 @@ ColorFilter="Correção de cor" MaskFilter="Máscara/mistura de imagem" AsyncDelayFilter="Atraso de vídeo (Async)" CropFilter="Cortar" -ScrollFilter="Percorre" +ScrollFilter="Rolagem" ChromaKeyFilter="Chroma Key" ColorKeyFilter="Color Key" SharpnessFilter="Nitidez" -NoiseGate="Filtro de ruído" +NoiseGate="Filtro de Rúido" Gain="Ganho" DelayMs="Atraso (milissegundos)" -Type="Topo" -MaskBlendType.MaskColor="Alpha Mask (Color Channel)" -MaskBlendType.MaskAlpha="Alpha Mask (Alpha Channel)" -MaskBlendType.BlendMultiply="Misturar (multiplicação)" -MaskBlendType.BlendAddition="Misturar (adição)" -MaskBlendType.BlendSubtraction="Misturar (subtração)" +Type="Tipo" +MaskBlendType.MaskColor="Máscara Alpha (Canal de Cor)" +MaskBlendType.MaskAlpha="Máscara Alpha (Canal Alpha)" +MaskBlendType.BlendMultiply="Misturar (Multiplicar)" +MaskBlendType.BlendAddition="Misturar (Adicionar)" +MaskBlendType.BlendSubtraction="Misturar (Subtrair)" Path="Caminho" Color="Cor" -Opacity="Transparência" +Opacity="Opacidade" Contrast="Contraste" Brightness="Brilho" Gamma="Gama" -BrowsePath.Images="Todos os ficheiros de imagem" -BrowsePath.AllFiles="Todos os ficheiros" -KeyColorType="Tipo de cor-chave" -KeyColor="Cor-chave" -Similarity="Semelhança (1-1000)" +BrowsePath.Images="Todos Arquivos de Imagem" +BrowsePath.AllFiles="Todos os Arquivos" +KeyColorType="Tipo de Key Color" +KeyColor="Key Color" +Similarity="Similaridade (1-1000)" Smoothness="Suavidade (1-1000)" -ColorSpillReduction="Redução de excesso da cor-chave (1-1000)" +ColorSpillReduction="Redução de Excesso de Key Color (1-1000)" Crop.Left="Esquerda" Crop.Right="Direita" -Crop.Top="Cima" +Crop.Top="Topo" Crop.Bottom="Baixo" Crop.Width="Largura" Crop.Height="Altura" Crop.Relative="Relativo" -ScrollFilter.SpeedX="Velocidade horizontal" -ScrollFilter.SpeedY="Velocidade vertical" -ScrollFilter.LimitWidth="Limitar largura" -ScrollFilter.LimitHeight="Limitar altura" -CustomColor="Cor personalizada" +ScrollFilter.SpeedX="Velocidade Horizontal" +ScrollFilter.SpeedY="Velocidade Vertical" +ScrollFilter.LimitWidth="Limitar Largura" +ScrollFilter.LimitHeight="Limitar Altura" +CustomColor="Cor Personalizada" Red="Vermelho" Green="Verde" Blue="Azul" Magenta="Magenta" -NoiseGate.OpenThreshold="Limite de abertura (dB)" -NoiseGate.CloseThreshold="Limite de fecho (dB)" +NoiseGate.OpenThreshold="Limite de Abertura (dB)" +NoiseGate.CloseThreshold="Limite de Fecho (dB)" NoiseGate.AttackTime="Tempo de ataque (milissegundos)" -NoiseGate.HoldTime="Tempo de bloqueio (milissegundos)" +NoiseGate.HoldTime="Tempo de Bloqueio (milissegundos)" NoiseGate.ReleaseTime="Tempo de libertação (milissegundos)" Gain.GainDB="Ganho (dB)" +StretchImage="Esticar a Imagem (descartar aspecto da imagem)" diff --git a/plugins/obs-filters/data/locale/ro-RO.ini b/plugins/obs-filters/data/locale/ro-RO.ini index e7dc25e..d8ff402 100644 --- a/plugins/obs-filters/data/locale/ro-RO.ini +++ b/plugins/obs-filters/data/locale/ro-RO.ini @@ -1,54 +1,54 @@ -ColorFilter="Corecţie de culoare" -MaskFilter="Mascare Imagine" +ColorFilter="Corecție de culoare" +MaskFilter="Mască/amestec de imagine" AsyncDelayFilter="Întârziere video (asincron)" -CropFilter="Crop" -ScrollFilter="Scroll" -ChromaKeyFilter="Cheia Chroma" +CropFilter="Trunchiere" +ScrollFilter="Derulare" +ChromaKeyFilter="Cheie chroma" ColorKeyFilter="Culoare cheie" -SharpnessFilter="Accentuează" -NoiseGate="Poarta de zgomot" +SharpnessFilter="Accentuare" +NoiseGate="Poartă de zgomot" Gain="Amplificare" DelayMs="Întârziere (milisecunde)" Type="Tip" -MaskBlendType.MaskColor="Masca Alpha (Canal Culoare)" -MaskBlendType.MaskAlpha="Masca Alpha (Canal Alpha)" -MaskBlendType.BlendMultiply="Blend (Multiply)" +MaskBlendType.MaskColor="Mască alpha (Canal de culoare)" +MaskBlendType.MaskAlpha="Mască alpha (Canal alpha)" +MaskBlendType.BlendMultiply="Amestec (Multiplicare)" MaskBlendType.BlendAddition="Amestec (Plus)" -MaskBlendType.BlendSubtraction="Blend (Minus)" +MaskBlendType.BlendSubtraction="Amestec (Minus)" Path="Cale" Color="Culoare" Opacity="Opacitate" Contrast="Contrast" Brightness="Luminozitate" -Gamma="Gamma" -BrowsePath.Images="Toate fişierele de imagini" -BrowsePath.AllFiles="Toate fişierele" -KeyColorType="Tip Culoare Cheie" -KeyColor="Culoarea cheie" -Similarity="Similitudine (1-100)" -Smoothness="Netezime (1-1000)" -ColorSpillReduction="Reducere Devarsare Culoare Cheie (1-1000)" +Gamma="Gama" +BrowsePath.Images="Toate fișierele de imagini" +BrowsePath.AllFiles="Toate fișierele" +KeyColorType="Tipul culorii cheie" +KeyColor="Culoare cheie" +Similarity="Similaritate (1-100)" +Smoothness="Netezire (1-1000)" +ColorSpillReduction="Reducere pentru devărsarea culorii cheie (1-1000)" Crop.Left="Stânga" Crop.Right="Dreapta" Crop.Top="Sus" Crop.Bottom="Jos" -Crop.Width="Lăţime" -Crop.Height="Înălţime" -Crop.Relative="Relativa" -ScrollFilter.SpeedX="Viteza orizontală" -ScrollFilter.SpeedY="Viteza verticală" -ScrollFilter.LimitWidth="Limită lățime" -ScrollFilter.LimitHeight="Limita inaltime" -CustomColor="Culoare personalizata" +Crop.Width="Lățime" +Crop.Height="Înălțime" +Crop.Relative="Relativă" +ScrollFilter.SpeedX="Viteză orizontală" +ScrollFilter.SpeedY="Viteză verticală" +ScrollFilter.LimitWidth="Limitează lățimea" +ScrollFilter.LimitHeight="Limitează înălțimea" +CustomColor="Culoare personalizată" Red="Roșu" Green="Verde" Blue="Albastru" Magenta="Purpuriu" -NoiseGate.OpenThreshold="Pragul de pornire (dB)" -NoiseGate.CloseThreshold="Pragul de oprire (dB)" -NoiseGate.AttackTime="Timpul de raspuns (milisecunde)" -NoiseGate.HoldTime="Timpul de menţinut (milisecunde)" -NoiseGate.ReleaseTime="Timpul de eliberare (milisecunde)" +NoiseGate.OpenThreshold="Prag de deschidere (dB)" +NoiseGate.CloseThreshold="Prag de închidere (dB)" +NoiseGate.AttackTime="Timp de atac (milisecunde)" +NoiseGate.HoldTime="Timp de menținere (milisecunde)" +NoiseGate.ReleaseTime="Timp de eliberare (milisecunde)" Gain.GainDB="Amplificare (dB)" -StretchImage="Întinde imaginea (renunța la raportul de aspect al imaginii)" +StretchImage="Întinde imaginea (renunță la raportul de aspect al imaginii)" diff --git a/plugins/obs-filters/data/locale/sv-SE.ini b/plugins/obs-filters/data/locale/sv-SE.ini index c514b62..7219081 100644 --- a/plugins/obs-filters/data/locale/sv-SE.ini +++ b/plugins/obs-filters/data/locale/sv-SE.ini @@ -10,7 +10,7 @@ NoiseGate="Brusblockering" Gain="Förstärkning" DelayMs="Fördröjning (millisekunder)" Type="Typ" -MaskBlendType.MaskColor="Alpha Mask (färgkanal)" +MaskBlendType.MaskColor="Alfamaskering (färgkanal)" MaskBlendType.MaskAlpha="Alpha Mask (alfakanal)" MaskBlendType.BlendMultiply="Blanda (Multiplicera)" MaskBlendType.BlendAddition="Blanda (Addition)" @@ -50,4 +50,5 @@ NoiseGate.AttackTime="Ansatstid (millisekunder)" NoiseGate.HoldTime="Hålltid (millisekunder)" NoiseGate.ReleaseTime="Släpptid (millisekunder)" Gain.GainDB="Förstärkning (dB)" +StretchImage="Sträck bild (ignorera bildförhållandet)" diff --git a/plugins/obs-filters/data/mask_alpha_filter.effect b/plugins/obs-filters/data/mask_alpha_filter.effect index 72f3d7a..7e9d513 100644 --- a/plugins/obs-filters/data/mask_alpha_filter.effect +++ b/plugins/obs-filters/data/mask_alpha_filter.effect @@ -1,8 +1,5 @@ uniform float4x4 ViewProj; uniform texture2d image; -uniform float4x4 color_matrix; -uniform float3 color_range_min = {0.0, 0.0, 0.0}; -uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform texture2d target; uniform float4 color; @@ -44,19 +41,6 @@ float4 PSAlphaMaskRGBA(VertDataOut v_in) : TARGET return rgba; } -float4 PSAlphaMaskMatrix(VertDataOut v_in) : TARGET -{ - float4 yuv = image.Sample(textureSampler, v_in.uv); - yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max); - - float4 rgba = saturate(mul(float4(yuv.xyz, 1.0), color_matrix)) * - color; - - float4 targetRGB = target.Sample(textureSampler, v_in.uv2); - rgba.a = targetRGB.a; - return rgba; -} - technique Draw { pass @@ -65,12 +49,3 @@ technique Draw pixel_shader = PSAlphaMaskRGBA(v_in); } } - -technique DrawMatrix -{ - pass - { - vertex_shader = VSDefault(v_in); - pixel_shader = PSAlphaMaskMatrix(v_in); - } -} diff --git a/plugins/obs-filters/data/mask_color_filter.effect b/plugins/obs-filters/data/mask_color_filter.effect index 6e0ab7e..6822a2f 100644 --- a/plugins/obs-filters/data/mask_color_filter.effect +++ b/plugins/obs-filters/data/mask_color_filter.effect @@ -1,8 +1,5 @@ uniform float4x4 ViewProj; uniform texture2d image; -uniform float4x4 color_matrix; -uniform float3 color_range_min = {0.0, 0.0, 0.0}; -uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform texture2d target; uniform float4 color; @@ -44,19 +41,6 @@ float4 PSColorMaskRGBA(VertDataOut v_in) : TARGET return rgba; } -float4 PSColorMaskMatrix(VertDataOut v_in) : TARGET -{ - float4 yuv = image.Sample(textureSampler, v_in.uv); - yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max); - - float4 rgba = saturate(mul(float4(yuv.xyz, 1.0), color_matrix)) * - color; - - float4 targetRGB = target.Sample(textureSampler, v_in.uv2); - rgba.a = (targetRGB.r + targetRGB.g + targetRGB.b) / 3.0; - return rgba; -} - technique Draw { pass @@ -66,11 +50,3 @@ technique Draw } } -technique DrawMatrix -{ - pass - { - vertex_shader = VSDefault(v_in); - pixel_shader = PSColorMaskMatrix(v_in); - } -} diff --git a/plugins/obs-filters/data/sharpness.effect b/plugins/obs-filters/data/sharpness.effect index b27e90a..54a023e 100644 --- a/plugins/obs-filters/data/sharpness.effect +++ b/plugins/obs-filters/data/sharpness.effect @@ -3,9 +3,6 @@ uniform float4x4 ViewProj; uniform texture2d image; -uniform float4x4 color_matrix; -uniform float3 color_range_min = {0.0, 0.0, 0.0}; -uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform texture2d target; uniform float4 color = {1.0, 1.0, 1.0, 1.0}; @@ -74,31 +71,6 @@ float4 PSDrawBare(VertOut vert_in) : TARGET return colorx; } -float4 PSDrawMatrix(VertOut vert_in) : TARGET -{ - float4 E = image.Sample(def_sampler, vert_in.uv); - - float4 colorx = 8*E; - float4 B = image.Sample(def_sampler, vert_in.t1.yw); - float4 D = image.Sample(def_sampler, vert_in.t2.xw); - float4 F = image.Sample(def_sampler, vert_in.t2.zw); - float4 H = image.Sample(def_sampler, vert_in.t3.yw); - colorx -= image.Sample(def_sampler, vert_in.t1.xw); - colorx -= B; - colorx -= image.Sample(def_sampler, vert_in.t1.zw); - colorx -= D; - colorx -= F; - colorx -= image.Sample(def_sampler, vert_in.t3.xw); - colorx -= H; - colorx -= image.Sample(def_sampler, vert_in.t3.zw); - - colorx = ((E!=F && E!=D) || (E!=B && E!=H)) ? saturate(E + colorx*sharpness) : E; - - float4 yuv = colorx; - yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max); - return saturate(mul(float4(yuv.xyz, 1.0), color_matrix)); -} - technique Draw { pass @@ -107,12 +79,3 @@ technique Draw pixel_shader = PSDrawBare(vert_in); } } - -technique DrawMatrix -{ - pass - { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSDrawMatrix(vert_in); - } -} diff --git a/plugins/obs-filters/mask-filter.c b/plugins/obs-filters/mask-filter.c index 3757b3d..ae6e5d1 100644 --- a/plugins/obs-filters/mask-filter.c +++ b/plugins/obs-filters/mask-filter.c @@ -210,8 +210,9 @@ static void mask_filter_render(void *data, gs_effect_t *effect) vec2_div(&add_val, &add_val, &mask_size); } - obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING); + if (!obs_source_process_filter_begin(filter->context, GS_RGBA, + OBS_ALLOW_DIRECT_RENDERING)) + return; param = gs_effect_get_param_by_name(filter->effect, "target"); gs_effect_set_texture(param, filter->target); diff --git a/plugins/obs-filters/scroll-filter.c b/plugins/obs-filters/scroll-filter.c index a6710f5..1e38a77 100644 --- a/plugins/obs-filters/scroll-filter.c +++ b/plugins/obs-filters/scroll-filter.c @@ -166,20 +166,23 @@ static void scroll_filter_render(void *data, gs_effect_t *effect) cx = filter->limit_cx ? filter->cx : base_cx; cy = filter->limit_cy ? filter->cy : base_cy; - if (cx && cy) { + if (base_cx && 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); - obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_NO_DIRECT_RENDERING); + if (!obs_source_process_filter_begin(filter->context, GS_RGBA, + OBS_NO_DIRECT_RENDERING)) + return; gs_effect_set_vec2(filter->param_add, &filter->offset); gs_effect_set_vec2(filter->param_mul, &mul_val); diff --git a/plugins/obs-filters/sharpness-filter.c b/plugins/obs-filters/sharpness-filter.c index fe5c441..0e7a795 100644 --- a/plugins/obs-filters/sharpness-filter.c +++ b/plugins/obs-filters/sharpness-filter.c @@ -77,11 +77,10 @@ static void *sharpness_create(obs_data_t *settings, obs_source_t *context) static void sharpness_render(void *data, gs_effect_t *effect) { struct sharpness_data *filter = data; - if (!filter) return; - if (!obs_filter_get_target(filter->context)) return; - obs_source_process_filter_begin(filter->context, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING); + if (!obs_source_process_filter_begin(filter->context, GS_RGBA, + OBS_ALLOW_DIRECT_RENDERING)) + return; filter->texwidth =(float)obs_source_get_width( obs_filter_get_target(filter->context)); diff --git a/plugins/obs-libfdk/data/locale/eu-ES.ini b/plugins/obs-libfdk/data/locale/eu-ES.ini index 5c5d5ae..f2da006 100644 --- a/plugins/obs-libfdk/data/locale/eu-ES.ini +++ b/plugins/obs-libfdk/data/locale/eu-ES.ini @@ -1,4 +1,4 @@ -LibFDK="libfdk AAC Kodeatzailea" -Bitrate="Bitneurria" +LibFDK="libfdk AAC Kodetzailea" +Bitrate="Bit-tasa" Afterburner="Gaitu AAC Afterburner" diff --git a/plugins/obs-libfdk/data/locale/he-IL.ini b/plugins/obs-libfdk/data/locale/he-IL.ini new file mode 100644 index 0000000..156c647 --- /dev/null +++ b/plugins/obs-libfdk/data/locale/he-IL.ini @@ -0,0 +1,4 @@ +LibFDK="מקודד libfdk AAV" +Bitrate="קצב ביטים" +Afterburner="אפשר מבער אחורי עבור AAC" + diff --git a/plugins/obs-libfdk/data/locale/hu-HU.ini b/plugins/obs-libfdk/data/locale/hu-HU.ini index d2665a3..0f6984c 100644 --- a/plugins/obs-libfdk/data/locale/hu-HU.ini +++ b/plugins/obs-libfdk/data/locale/hu-HU.ini @@ -1,4 +1,4 @@ -LibFDK="libfdk AAC Kódoló" +LibFDK="libfdk AAC kódoló" Bitrate="Bitráta" -Afterburner="AAC Afterburner Engedélyezése" +Afterburner="AAC Afterburner engedélyezése" diff --git a/plugins/obs-libfdk/data/locale/ja-JP.ini b/plugins/obs-libfdk/data/locale/ja-JP.ini index 40cd254..8daf488 100644 --- a/plugins/obs-libfdk/data/locale/ja-JP.ini +++ b/plugins/obs-libfdk/data/locale/ja-JP.ini @@ -1,4 +1,4 @@ -LibFDK="libfdk AAC エンコーダー" +LibFDK="libfdk AAC エンコーダ" Bitrate="ビットレート" Afterburner="AAC アフターバーナーを有効にする" diff --git a/plugins/obs-libfdk/data/locale/pt-PT.ini b/plugins/obs-libfdk/data/locale/pt-PT.ini index 4da6336..03b7742 100644 --- a/plugins/obs-libfdk/data/locale/pt-PT.ini +++ b/plugins/obs-libfdk/data/locale/pt-PT.ini @@ -1,4 +1,4 @@ -LibFDK="Cidificador AAC libfdk" -Bitrate="Taxa de Bits (Bitrate)" -Afterburner="Activar pós-combustor AAC" +LibFDK="Codificador libfdk AAC" +Bitrate="Bitrate" +Afterburner="Ativar AAC Afterburner" diff --git a/plugins/obs-libfdk/data/locale/ro-RO.ini b/plugins/obs-libfdk/data/locale/ro-RO.ini index cd94d3d..872b490 100644 --- a/plugins/obs-libfdk/data/locale/ro-RO.ini +++ b/plugins/obs-libfdk/data/locale/ro-RO.ini @@ -1,4 +1,4 @@ -LibFDK="libfdk Codare AAC" -Bitrate="Rata biti" -Afterburner="Permite AAC Afterburner" +LibFDK="Codificator AAC libfdk" +Bitrate="Rată de biți" +Afterburner="Activează AAC Afterburner" diff --git a/plugins/obs-outputs/data/locale/eu-ES.ini b/plugins/obs-outputs/data/locale/eu-ES.ini index b229521..e246230 100644 --- a/plugins/obs-outputs/data/locale/eu-ES.ini +++ b/plugins/obs-outputs/data/locale/eu-ES.ini @@ -1,5 +1,5 @@ RTMPStream="RTMP Jarioa" -RTMPStream.DropThreshold="Erorketa Muga (segundumilaen)" -FLVOutput="FLV Irteera Agiria" -FLVOutput.FilePath="Agiri Helburua" +RTMPStream.DropThreshold="Galera atalasea (milisegundoak)" +FLVOutput="FLV irteera fitxategia" +FLVOutput.FilePath="Fitxategiaren bidea" diff --git a/plugins/obs-outputs/data/locale/fr-FR.ini b/plugins/obs-outputs/data/locale/fr-FR.ini index d26b5cb..6bd6f2b 100644 --- a/plugins/obs-outputs/data/locale/fr-FR.ini +++ b/plugins/obs-outputs/data/locale/fr-FR.ini @@ -1,5 +1,5 @@ RTMPStream="Flux RTMP" -RTMPStream.DropThreshold="Seuil de baisse (millisecondes)" -FLVOutput="Fichier FLV Sortant" -FLVOutput.FilePath="Chemin du Fichier" +RTMPStream.DropThreshold="Seuil de baisse (en millisecondes)" +FLVOutput="Fichier FLV sortant" +FLVOutput.FilePath="Chemin du fichier" diff --git a/plugins/obs-outputs/data/locale/he-IL.ini b/plugins/obs-outputs/data/locale/he-IL.ini new file mode 100644 index 0000000..836a106 --- /dev/null +++ b/plugins/obs-outputs/data/locale/he-IL.ini @@ -0,0 +1,5 @@ +RTMPStream="זרם RTMP" +RTMPStream.DropThreshold="הורד סף (אלפיות שניה)" +FLVOutput="קובץ פלט FLV" +FLVOutput.FilePath="נתיב קובץ" + diff --git a/plugins/obs-outputs/data/locale/hu-HU.ini b/plugins/obs-outputs/data/locale/hu-HU.ini index f0c1c83..65b40bb 100644 --- a/plugins/obs-outputs/data/locale/hu-HU.ini +++ b/plugins/obs-outputs/data/locale/hu-HU.ini @@ -1,5 +1,5 @@ -RTMPStream="RTMP Stream" -RTMPStream.DropThreshold="Ejtési Küszöb (ezredmásodperc)" -FLVOutput="FLV Kimeneti Fájl" -FLVOutput.FilePath="Fájl Elérési Útja" +RTMPStream="RTMP stream" +RTMPStream.DropThreshold="Ejtési küszöb (ezredmásodperc)" +FLVOutput="FLV kimeneti fájl" +FLVOutput.FilePath="Fájl elérési útja" diff --git a/plugins/obs-outputs/data/locale/nl-NL.ini b/plugins/obs-outputs/data/locale/nl-NL.ini index 3fc3154..5c374aa 100644 --- a/plugins/obs-outputs/data/locale/nl-NL.ini +++ b/plugins/obs-outputs/data/locale/nl-NL.ini @@ -1,5 +1,5 @@ RTMPStream="RTMP Stream" -RTMPStream.DropThreshold="Drop Threshold (milliseconden)" +RTMPStream.DropThreshold="Uitvaldrempel (milliseconden)" FLVOutput="FLV Bestandsuitvoer" FLVOutput.FilePath="Bestandspad" diff --git a/plugins/obs-outputs/data/locale/pt-PT.ini b/plugins/obs-outputs/data/locale/pt-PT.ini index 8239a45..ebcd465 100644 --- a/plugins/obs-outputs/data/locale/pt-PT.ini +++ b/plugins/obs-outputs/data/locale/pt-PT.ini @@ -1,5 +1,5 @@ -RTMPStream="Steam RTMP" -RTMPStream.DropThreshold="Limiar de Caída (milisegundos)" -FLVOutput="Ficheiro de Saída FLV" -FLVOutput.FilePath="Caminho do Ficheiro" +RTMPStream="RTMP Stream" +RTMPStream.DropThreshold="Limite de corte (milissegundos)" +FLVOutput="Ficheiro de saída FLV" +FLVOutput.FilePath="Caminho do ficheiro" diff --git a/plugins/obs-outputs/data/locale/ro-RO.ini b/plugins/obs-outputs/data/locale/ro-RO.ini index 4530c6a..2333b47 100644 --- a/plugins/obs-outputs/data/locale/ro-RO.ini +++ b/plugins/obs-outputs/data/locale/ro-RO.ini @@ -1,5 +1,5 @@ -RTMPStream="RTMP Stream" -RTMPStream.DropThreshold="Prag de Pierderi (milisecunde)" -FLVOutput="Ieşire fişier FLV" -FLVOutput.FilePath="Calea fişierului" +RTMPStream="Flux RTMP" +RTMPStream.DropThreshold="Prag de pierderi (milisecunde)" +FLVOutput="Ieșire fișier FLV" +FLVOutput.FilePath="Calea fișierului" diff --git a/plugins/obs-outputs/data/locale/sv-SE.ini b/plugins/obs-outputs/data/locale/sv-SE.ini index e9bebc7..5138672 100644 --- a/plugins/obs-outputs/data/locale/sv-SE.ini +++ b/plugins/obs-outputs/data/locale/sv-SE.ini @@ -1,5 +1,5 @@ -RTMPStream="RTMP-stream" +RTMPStream="RTMP-ström" RTMPStream.DropThreshold="Tappgräns (ms)" FLVOutput="FLV-filutmatning" -FLVOutput.FilePath="Filsökväg" +FLVOutput.FilePath="Sökväg" diff --git a/plugins/obs-outputs/rtmp-stream.c b/plugins/obs-outputs/rtmp-stream.c index 250c2e5..9fbdc98 100644 --- a/plugins/obs-outputs/rtmp-stream.c +++ b/plugins/obs-outputs/rtmp-stream.c @@ -311,7 +311,7 @@ static int send_packet(struct rtmp_stream *stream, return ret; } -static inline void send_headers(struct rtmp_stream *stream); +static inline bool send_headers(struct rtmp_stream *stream); static bool send_remaining_packets(struct rtmp_stream *stream) { @@ -319,8 +319,10 @@ static bool send_remaining_packets(struct rtmp_stream *stream) uint64_t max_ns = (uint64_t)stream->max_shutdown_time_sec * 1000000000; uint64_t begin_time_ns = os_gettime_ns(); - if (!stream->sent_headers) - send_headers(stream); + if (!stream->sent_headers) { + if (!send_headers(stream)) + return false; + } while (get_next_packet(stream, &packet)) { if (send_packet(stream, &packet, false, packet.track_idx) < 0) @@ -352,8 +354,12 @@ static void *send_thread(void *data) if (!get_next_packet(stream, &packet)) continue; - if (!stream->sent_headers) - send_headers(stream); + if (!stream->sent_headers) { + if (!send_headers(stream)) { + os_atomic_set_bool(&stream->disconnected, true); + break; + } + } if (send_packet(stream, &packet, false, packet.track_idx) < 0) { os_atomic_set_bool(&stream->disconnected, true); @@ -384,23 +390,26 @@ static void *send_thread(void *data) return NULL; } -static bool send_meta_data(struct rtmp_stream *stream, size_t idx) +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 = flv_meta_data(stream->output, &meta_data, + bool success = true; + + *next = flv_meta_data(stream->output, &meta_data, &meta_data_size, false, idx); - if (success) { - RTMP_Write(&stream->rtmp, (char*)meta_data, - (int)meta_data_size, (int)idx); + if (*next) { + success = RTMP_Write(&stream->rtmp, (char*)meta_data, + (int)meta_data_size, (int)idx) >= 0; bfree(meta_data); } return success; } -static bool send_audio_header(struct rtmp_stream *stream, size_t idx) +static bool send_audio_header(struct rtmp_stream *stream, size_t idx, + bool *next) { obs_output_t *context = stream->output; obs_encoder_t *aencoder = obs_output_get_audio_encoder(context, idx); @@ -411,16 +420,17 @@ static bool send_audio_header(struct rtmp_stream *stream, size_t idx) .timebase_den = 1 }; - if (!aencoder) - return false; + if (!aencoder) { + *next = false; + return true; + } obs_encoder_get_extra_data(aencoder, &header, &packet.size); packet.data = bmemdup(header, packet.size); - send_packet(stream, &packet, true, idx); - return true; + return send_packet(stream, &packet, true, idx) >= 0; } -static void send_video_header(struct rtmp_stream *stream) +static bool send_video_header(struct rtmp_stream *stream) { obs_output_t *context = stream->output; obs_encoder_t *vencoder = obs_output_get_video_encoder(context); @@ -435,18 +445,27 @@ static void send_video_header(struct rtmp_stream *stream) obs_encoder_get_extra_data(vencoder, &header, &size); packet.size = obs_parse_avc_header(&packet.data, header, size); - send_packet(stream, &packet, true, 0); + return send_packet(stream, &packet, true, 0) >= 0; } -static inline void send_headers(struct rtmp_stream *stream) +static inline bool send_headers(struct rtmp_stream *stream) { stream->sent_headers = true; size_t i = 0; + bool next = true; + bool fail = false; - send_audio_header(stream, i++); - send_video_header(stream); + if (!send_audio_header(stream, i++, &next)) + return false; + if (!send_video_header(stream)) + return false; - while (send_audio_header(stream, i++)); + while (next) { + if (!send_audio_header(stream, i++, &next)) + return false; + } + + return true; } static inline bool reset_semaphore(struct rtmp_stream *stream) @@ -480,6 +499,7 @@ static int init_send(struct rtmp_stream *stream) { int ret; size_t idx = 0; + bool next = true; #if defined(_WIN32) adjust_sndbuf_size(stream, MIN_SENDBUF_SIZE); @@ -495,7 +515,13 @@ static int init_send(struct rtmp_stream *stream) } os_atomic_set_bool(&stream->active, true); - while (send_meta_data(stream, idx++)); + while (next) { + if (!send_meta_data(stream, idx++, &next)) { + warn("Disconnected while attempting to connect to " + "server."); + return OBS_OUTPUT_DISCONNECTED; + } + } obs_output_begin_data_capture(stream->output, 0); return OBS_OUTPUT_SUCCESS; @@ -524,7 +550,7 @@ static void win32_log_interface_type(struct rtmp_stream *stream) if (rtmp->m_bindIP.addrLen == 0) source_addr = 0; - else if (rtmp->m_bindIP.addr.ss_family = AF_INET) + else if (rtmp->m_bindIP.addr.ss_family == AF_INET) source_addr = (*(struct sockaddr_in*)&rtmp->m_bindIP) .sin_addr.S_un.S_addr; else @@ -648,6 +674,8 @@ static bool init_connect(struct rtmp_stream *stream) 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); + dstr_depad(&stream->key); stream->drop_threshold_usec = (int64_t)obs_data_get_int(settings, OPT_DROP_THRESHOLD) * 1000; stream->max_shutdown_time_sec = diff --git a/plugins/obs-qsv11/CMakeLists.txt b/plugins/obs-qsv11/CMakeLists.txt new file mode 100644 index 0000000..611c7aa --- /dev/null +++ b/plugins/obs-qsv11/CMakeLists.txt @@ -0,0 +1,86 @@ +project(obs-qsv11) + +include_directories(libmfx/include/msdk/include) +include_directories(libmfx/include) + +set(obs-qsv11_libmfx_SOURCES + libmfx/src/main.cpp + libmfx/src/mfx_critical_section.cpp + libmfx/src/mfx_dispatcher.cpp + libmfx/src/mfx_dispatcher_log.cpp + libmfx/src/mfx_dxva2_device.cpp + libmfx/src/mfx_function_table.cpp + libmfx/src/mfx_library_iterator.cpp + libmfx/src/mfx_load_dll.cpp + libmfx/src/mfx_load_plugin.cpp + libmfx/src/mfx_plugin_hive.cpp + libmfx/src/mfx_win_reg_key.cpp + ) + +set(obs-qsv11_libmfx_HEADERS + libmfx/include/msdk/include/mfxastructures.h + libmfx/include/msdk/include/mfxaudio.h + libmfx/include/msdk/include/mfxaudio++.h + libmfx/include/msdk/include/mfxcommon.h + libmfx/include/msdk/include/mfxdefs.h + libmfx/include/msdk/include/mfxjpeg.h + libmfx/include/msdk/include/mfxmvc.h + libmfx/include/msdk/include/mfxplugin.h + libmfx/include/msdk/include/mfxplugin++.h + libmfx/include/msdk/include/mfxsession.h + libmfx/include/msdk/include/mfxstructures.h + libmfx/include/msdk/include/mfxvideo.h + libmfx/include/msdk/include/mfxvideo++.h + libmfx/include/msdk/include/mfxvstructures.h + libmfx/include/mfx_critical_section.h + libmfx/include/mfx_dispatcher.h + libmfx/include/mfx_dispatcher_defs.h + libmfx/include/mfx_dispatcher_log.h + libmfx/include/mfx_dxva2_device.h + libmfx/include/mfx_exposed_functions_list.h + libmfx/include/mfx_library_iterator.h + libmfx/include/mfx_load_dll.h + libmfx/include/mfx_load_plugin.h + libmfx/include/mfx_plugin_hive.h + libmfx/include/mfx_vector.h + libmfx/include/mfx_win_reg_key.h + libmfx/include/mfxaudio_exposed_functions_list.h + ) + +set(obs-qsv11_SOURCES + common_directx11.cpp + common_utils.cpp + common_utils_windows.cpp + QSV_Encoder.cpp + QSV_Encoder_Internal.cpp + obs-qsv11.c + obs-qsv11-plugin-main.c) + +set(obs-qsv11_HEADERS + bits/linux_defs.h + bits/windows_defs.h + common_directx11.h + common_utils.h + QSV_Encoder.h + QSV_Encoder_Internal.h) + +add_library(obs-qsv11 MODULE + ${obs-qsv11_SOURCES} + ${obs-qsv11_HEADERS} + ${obs-qsv11_libmfx_SOURCES} + ${obs-qsv11_libmfx_HEADERS} + ) +target_link_libraries(obs-qsv11 + libobs + d3d11 + dxgi + ) + +target_compile_definitions(obs-qsv11 PRIVATE DX11_D3D) + +source_group("obs-qsv11\\Source Files" FILES ${obs-qsv11_SOURCES}) +source_group("obs-qsv11\\Header Files" FILES ${obs-qsv11_HEADERS}) +source_group("libmfx\\Source Files" FILES ${obs-qsv11_libmfx_SOURCES}) +source_group("libmfx\\Header Files" FILES ${obs-qsv11_libmfx_HEADERS}) + +install_obs_plugin_with_data(obs-qsv11 data) diff --git a/plugins/obs-qsv11/QSV_Encoder.cpp b/plugins/obs-qsv11/QSV_Encoder.cpp new file mode 100644 index 0000000..6476a29 --- /dev/null +++ b/plugins/obs-qsv11/QSV_Encoder.cpp @@ -0,0 +1,228 @@ +/* + +This file is provided under a dual BSD/GPLv2 license. When using or +redistributing this file, you may do so under either license. + +GPL LICENSE SUMMARY + +Copyright(c) Oct. 2015 Intel Corporation. + +This program is free software; you can redistribute it and/or modify +it under the terms of version 2 of the GNU General Public License as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +Contact Information: + +Seung-Woo Kim, seung-woo.kim@intel.com +705 5th Ave S #500, Seattle, WA 98104 + +BSD LICENSE + +Copyright(c) Intel Corporation. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +* Neither the name of Intel Corporation nor the names of its +contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// QSV_Encoder.cpp : Defines the exported functions for the DLL application. +// + +#include "QSV_Encoder.h" +#include "QSV_Encoder_Internal.h" +#include +#include +#include + +#define do_log(level, format, ...) \ + blog(level, "[qsv encoder: '%s'] " format, \ + "msdk_impl", ##__VA_ARGS__) + +mfxIMPL impl = MFX_IMPL_HARDWARE_ANY; +mfxVersion ver = {{0, 1}}; // for backward compatibility +std::mutex active_mutex; + +void qsv_encoder_version(unsigned short *major, unsigned short *minor) +{ + *major = ver.Major; + *minor = ver.Minor; +} + +qsv_t *qsv_encoder_open(qsv_param_t *pParams) +{ + if (!active_mutex.try_lock()) { + do_log(LOG_ERROR, "Cannot have more than one encoder " + "active at a time"); + return NULL; + } + + QSV_Encoder_Internal *pEncoder = new QSV_Encoder_Internal(impl, ver); + mfxStatus sts = pEncoder->Open(pParams); + if (sts != MFX_ERR_NONE) { + delete pEncoder; + if (pEncoder) + active_mutex.unlock(); + return NULL; + } + + return (qsv_t *) pEncoder; +} + +int qsv_encoder_headers(qsv_t *pContext, uint8_t **pSPS, uint8_t **pPPS, + uint16_t *pnSPS, uint16_t *pnPPS) +{ + QSV_Encoder_Internal *pEncoder = (QSV_Encoder_Internal *)pContext; + pEncoder->GetSPSPPS(pSPS, pPPS, pnSPS, pnPPS); + + return 0; +} + +int qsv_encoder_encode(qsv_t * pContext, uint64_t ts, uint8_t *pDataY, + uint8_t *pDataUV, uint32_t strideY, uint32_t strideUV, + mfxBitstream **pBS) +{ + QSV_Encoder_Internal *pEncoder = (QSV_Encoder_Internal *)pContext; + mfxStatus sts = MFX_ERR_NONE; + + if (pDataY != NULL && pDataUV != NULL) + sts = pEncoder->Encode(ts, pDataY, pDataUV, strideY, strideUV, + pBS); + + if (sts == MFX_ERR_NONE) + return 0; + else if (sts == MFX_ERR_MORE_DATA) + return 1; + else + return -1; +} + +int qsv_encoder_close(qsv_t *pContext) +{ + QSV_Encoder_Internal *pEncoder = (QSV_Encoder_Internal *)pContext; + delete pEncoder; + + if (pEncoder) + active_mutex.unlock(); + + return 0; +} + +/* +int qsv_param_default_preset(qsv_param_t *pParams, const char *preset, + const char *tune) +{ + return 0; +} + +int qsv_param_parse(qsv_param_t *, const char *name, const char *value) +{ + return 0; +} + +int qsv_param_apply_profile(qsv_param_t *, const char *profile) +{ + return 0; +} +*/ + +int qsv_encoder_reconfig(qsv_t *pContext, qsv_param_t *pParams) +{ + QSV_Encoder_Internal *pEncoder = (QSV_Encoder_Internal *)pContext; + mfxStatus sts = pEncoder->Reset(pParams); + + if (sts == MFX_ERR_NONE) + return 0; + else + return -1; +} + +enum qsv_cpu_platform qsv_get_cpu_platform() +{ + using std::string; + + int cpuInfo[4]; + __cpuid(cpuInfo, 0); + + string vendor; + vendor += string((char*)&cpuInfo[1], 4); + vendor += string((char*)&cpuInfo[3], 4); + vendor += string((char*)&cpuInfo[2], 4); + + if (vendor != "GenuineIntel") + return QSV_CPU_PLATFORM_UNKNOWN; + + __cpuid(cpuInfo, 1); + BYTE model = ((cpuInfo[0] >> 4) & 0xF) + ((cpuInfo[0] >> 12) & 0xF0); + BYTE family = ((cpuInfo[0] >> 8) & 0xF) + ((cpuInfo[0] >> 20) & 0xFF); + + // See Intel 64 and IA-32 Architectures Software Developer's Manual, + // Vol 3C Table 35-1 + if (family != 6) + return QSV_CPU_PLATFORM_UNKNOWN; + + switch (model) + { + case 0x1C: + case 0x26: + case 0x27: + case 0x35: + case 0x36: + return QSV_CPU_PLATFORM_BNL; + + case 0x2a: + case 0x2d: + return QSV_CPU_PLATFORM_SNB; + + case 0x3a: + case 0x3e: + return QSV_CPU_PLATFORM_IVB; + + case 0x37: + case 0x4A: + case 0x4D: + case 0x5A: + case 0x5D: + return QSV_CPU_PLATFORM_SLM; + + case 0x4C: + return QSV_CPU_PLATFORM_CHT; + + case 0x3c: + case 0x3f: + case 0x45: + case 0x46: + return QSV_CPU_PLATFORM_HSW; + } + + //assume newer revisions are at least as capable as haswell + return QSV_CPU_PLATFORM_INTEL; +} diff --git a/plugins/obs-qsv11/QSV_Encoder.h b/plugins/obs-qsv11/QSV_Encoder.h new file mode 100644 index 0000000..ffd2a69 --- /dev/null +++ b/plugins/obs-qsv11/QSV_Encoder.h @@ -0,0 +1,149 @@ +/* + +This file is provided under a dual BSD/GPLv2 license. When using or +redistributing this file, you may do so under either license. + +GPL LICENSE SUMMARY + +Copyright(c) Oct. 2015 Intel Corporation. + +This program is free software; you can redistribute it and/or modify +it under the terms of version 2 of the GNU General Public License as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +Contact Information: + +Seung-Woo Kim, seung-woo.kim@intel.com +705 5th Ave S #500, Seattle, WA 98104 + +BSD LICENSE + +Copyright(c) Intel Corporation. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +* Neither the name of Intel Corporation nor the names of its +contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#pragma once + +#include +#include "mfxstructures.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct qsv_rate_control_info { + const char *name; + bool haswell_or_greater; +}; + +static const struct qsv_rate_control_info qsv_ratecontrols[] = { + {"CBR", false}, + {"VBR", false}, + {"VCM", true}, + {"CQP", false}, + {"AVBR", false}, + {"ICQ", true}, + {"LA_ICQ", true}, + {"LA", true}, + {0, false} +}; +static const char * const qsv_profile_names[] = { + "high", + "main", + "baseline", + 0 +}; +static const char * const qsv_usage_names[] = { + "quality", + "balanced", + "speed", + 0 +}; + +typedef struct qsv_t qsv_t; + +typedef struct +{ + mfxU16 nTargetUsage; /* 1 through 7, 1 being best quality and 7 + being the best speed */ + mfxU16 nWidth; /* source picture width */ + mfxU16 nHeight; /* source picture height */ + mfxU16 nAsyncDepth; + mfxU16 nFpsNum; + mfxU16 nFpsDen; + mfxU16 nTargetBitRate; + mfxU16 nMaxBitRate; + mfxU16 nCodecProfile; + mfxU16 nRateControl; + mfxU16 nAccuracy; + mfxU16 nConvergence; + mfxU16 nQPI; + mfxU16 nQPP; + mfxU16 nQPB; + mfxU16 nLADEPTH; + mfxU16 nKeyIntSec; + mfxU16 nbFrames; + mfxU16 nICQQuality; +} qsv_param_t; + +enum qsv_cpu_platform { + QSV_CPU_PLATFORM_UNKNOWN, + QSV_CPU_PLATFORM_BNL, + QSV_CPU_PLATFORM_SNB, + QSV_CPU_PLATFORM_IVB, + QSV_CPU_PLATFORM_SLM, + QSV_CPU_PLATFORM_CHT, + QSV_CPU_PLATFORM_HSW, + QSV_CPU_PLATFORM_INTEL +}; + +int qsv_encoder_close(qsv_t *); +int qsv_param_parse(qsv_param_t *, const char *name, const char *value); +int qsv_param_apply_profile(qsv_param_t *, const char *profile); +int qsv_param_default_preset(qsv_param_t *, const char *preset, + const char *tune); +int qsv_encoder_reconfig(qsv_t *, qsv_param_t *); +void qsv_encoder_version(unsigned short *major, unsigned short *minor); +qsv_t *qsv_encoder_open( qsv_param_t * ); +int qsv_encoder_encode(qsv_t *, uint64_t, uint8_t *, uint8_t *, uint32_t, + uint32_t, mfxBitstream **pBS); +int qsv_encoder_headers(qsv_t *, uint8_t **pSPS, uint8_t **pPPS, + uint16_t *pnSPS, uint16_t *pnPPS); +enum qsv_cpu_platform qsv_get_cpu_platform(); + +#ifdef __cplusplus +} +#endif diff --git a/plugins/obs-qsv11/QSV_Encoder_Internal.cpp b/plugins/obs-qsv11/QSV_Encoder_Internal.cpp new file mode 100644 index 0000000..c73838b --- /dev/null +++ b/plugins/obs-qsv11/QSV_Encoder_Internal.cpp @@ -0,0 +1,598 @@ +/* + +This file is provided under a dual BSD/GPLv2 license. When using or +redistributing this file, you may do so under either license. + +GPL LICENSE SUMMARY + +Copyright(c) Oct. 2015 Intel Corporation. + +This program is free software; you can redistribute it and/or modify +it under the terms of version 2 of the GNU General Public License as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +Contact Information: + +Seung-Woo Kim, seung-woo.kim@intel.com +705 5th Ave S #500, Seattle, WA 98104 + +BSD LICENSE + +Copyright(c) Intel Corporation. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +* Neither the name of Intel Corporation nor the names of its +contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "QSV_Encoder_Internal.h" +#include "QSV_Encoder.h" +#include "mfxastructures.h" +#include "mfxvideo++.h" +#include +#include + +#define do_log(level, format, ...) \ + blog(level, "[qsv encoder: '%s'] " format, \ + "msdk_impl", ##__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__) + +QSV_Encoder_Internal::QSV_Encoder_Internal(mfxIMPL& impl, mfxVersion& version) : + m_pmfxENC(NULL), + m_nSPSBufferSize(100), + m_nPPSBufferSize(100), + m_nTaskPool(0), + m_pTaskPool(NULL), + m_nTaskIdx(0), + m_nFirstSyncTask(0) +{ + mfxIMPL tempImpl; + mfxStatus sts; + + m_bIsWindows8OrGreater = IsWindows8OrGreater(); + m_bUseD3D11 = false; + + if (m_bIsWindows8OrGreater) { + tempImpl = impl | MFX_IMPL_VIA_D3D11; + sts = m_session.Init(tempImpl, &version); + if (sts == MFX_ERR_NONE) { + m_session.QueryVersion(&version); + m_session.Close(); + + // Use D3D11 surface + // m_bUseD3D11 = ((version.Major > 1) || + // (version.Major == 1 && version.Minor >= 8)); + m_bUseD3D11 = true; + if (m_bUseD3D11) + blog(LOG_INFO, "\timpl: D3D11\n" + "\tsurf: D3D11"); + else + blog(LOG_INFO, "\timpl: D3D11\n" + "\tsurf: SysMem"); + + m_impl = tempImpl; + m_ver = version; + return; + } + } + + // Either windows 7 or D3D11 failed at this point. + tempImpl = impl | MFX_IMPL_VIA_D3D9; + sts = m_session.Init(tempImpl, &version); + if (sts == MFX_ERR_NONE) { + m_session.QueryVersion(&version); + m_session.Close(); + + blog(LOG_INFO, "\timpl: D3D09\n" + "\tsurf: SysMem"); + + m_impl = tempImpl; + m_ver = version; + } + +} + +QSV_Encoder_Internal::~QSV_Encoder_Internal() +{ + if (m_pmfxENC) + ClearData(); +} + +mfxStatus QSV_Encoder_Internal::Open(qsv_param_t * pParams) +{ + mfxStatus sts = MFX_ERR_NONE; + + if (m_bUseD3D11) + // Use D3D11 surface + sts = Initialize(m_impl, m_ver, &m_session, &m_mfxAllocator); + else + // Use system memory + sts = Initialize(m_impl, m_ver, &m_session, NULL); + + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + m_pmfxENC = new MFXVideoENCODE(m_session); + + InitParams(pParams); + + sts = m_pmfxENC->Query(&m_mfxEncParams, &m_mfxEncParams); + MSDK_IGNORE_MFX_STS(sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + sts = AllocateSurfaces(); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + sts = m_pmfxENC->Init(&m_mfxEncParams); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + sts = GetVideoParam(); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + sts = InitBitstream(); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + return sts; +} + + +bool QSV_Encoder_Internal::InitParams(qsv_param_t * pParams) +{ + memset(&m_mfxEncParams, 0, sizeof(m_mfxEncParams)); + + m_mfxEncParams.mfx.CodecId = MFX_CODEC_AVC; + m_mfxEncParams.mfx.GopOptFlag = MFX_GOP_STRICT; + m_mfxEncParams.mfx.NumSlice = 1; + m_mfxEncParams.mfx.TargetUsage = pParams->nTargetUsage; + m_mfxEncParams.mfx.CodecProfile = pParams->nCodecProfile; + m_mfxEncParams.mfx.FrameInfo.FrameRateExtN = pParams->nFpsNum; + m_mfxEncParams.mfx.FrameInfo.FrameRateExtD = pParams->nFpsDen; + m_mfxEncParams.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12; + m_mfxEncParams.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420; + m_mfxEncParams.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE; + m_mfxEncParams.mfx.FrameInfo.CropX = 0; + m_mfxEncParams.mfx.FrameInfo.CropY = 0; + m_mfxEncParams.mfx.FrameInfo.CropW = pParams->nWidth; + m_mfxEncParams.mfx.FrameInfo.CropH = pParams->nHeight; + + m_mfxEncParams.mfx.RateControlMethod = pParams->nRateControl; + + switch (pParams->nRateControl) { + case MFX_RATECONTROL_CBR: + m_mfxEncParams.mfx.TargetKbps = pParams->nTargetBitRate; + break; + case MFX_RATECONTROL_VBR: + case MFX_RATECONTROL_VCM: + m_mfxEncParams.mfx.TargetKbps = pParams->nTargetBitRate; + m_mfxEncParams.mfx.MaxKbps = pParams->nMaxBitRate; + break; + case MFX_RATECONTROL_CQP: + m_mfxEncParams.mfx.QPI = pParams->nQPI; + m_mfxEncParams.mfx.QPB = pParams->nQPB; + m_mfxEncParams.mfx.QPP = pParams->nQPP; + break; + case MFX_RATECONTROL_AVBR: + m_mfxEncParams.mfx.TargetKbps = pParams->nTargetBitRate; + m_mfxEncParams.mfx.Accuracy = pParams->nAccuracy; + m_mfxEncParams.mfx.Convergence = pParams->nConvergence; + break; + case MFX_RATECONTROL_ICQ: + m_mfxEncParams.mfx.ICQQuality = pParams->nICQQuality; + break; + case MFX_RATECONTROL_LA: + m_mfxEncParams.mfx.TargetKbps = pParams->nTargetBitRate; + break; + case MFX_RATECONTROL_LA_ICQ: + m_mfxEncParams.mfx.ICQQuality = pParams->nICQQuality; + break; + default: + break; + } + + m_mfxEncParams.AsyncDepth = pParams->nAsyncDepth; + m_mfxEncParams.mfx.GopPicSize = (mfxU16)(pParams->nKeyIntSec * + pParams->nFpsNum / (float)pParams->nFpsDen); + + static mfxExtBuffer* extendedBuffers[2]; + int iBuffers = 0; + if (pParams->nAsyncDepth == 1) { + m_mfxEncParams.mfx.NumRefFrame = 1; + // low latency, I and P frames only + m_mfxEncParams.mfx.GopRefDist = 1; + memset(&m_co, 0, sizeof(mfxExtCodingOption)); + m_co.Header.BufferId = MFX_EXTBUFF_CODING_OPTION; + m_co.Header.BufferSz = sizeof(mfxExtCodingOption); + m_co.MaxDecFrameBuffering = 1; + extendedBuffers[iBuffers++] = (mfxExtBuffer*)&m_co; + } + else + m_mfxEncParams.mfx.GopRefDist = pParams->nbFrames + 1; + + if (pParams->nRateControl == MFX_RATECONTROL_LA_ICQ || + pParams->nRateControl == MFX_RATECONTROL_LA) { + + memset(&m_co2, 0, sizeof(mfxExtCodingOption2)); + m_co2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION; + m_co2.Header.BufferSz = sizeof(m_co2); + m_co2.LookAheadDepth = pParams->nLADEPTH; + extendedBuffers[iBuffers++] = (mfxExtBuffer*)& m_co2; + } + + if (iBuffers > 0) { + m_mfxEncParams.ExtParam = extendedBuffers; + m_mfxEncParams.NumExtParam = (mfxU16)iBuffers; + } + + // Width must be a multiple of 16 + // Height must be a multiple of 16 in case of frame picture and a + // multiple of 32 in case of field picture + m_mfxEncParams.mfx.FrameInfo.Width = MSDK_ALIGN16(pParams->nWidth); + m_mfxEncParams.mfx.FrameInfo.Height = MSDK_ALIGN16(pParams->nHeight); + + if (m_bUseD3D11) + m_mfxEncParams.IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY; + else + m_mfxEncParams.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY; + + return true; +} + +mfxStatus QSV_Encoder_Internal::AllocateSurfaces() +{ + // Query number of required surfaces for encoder + mfxFrameAllocRequest EncRequest; + memset(&EncRequest, 0, sizeof(EncRequest)); + mfxStatus sts = m_pmfxENC->QueryIOSurf(&m_mfxEncParams, &EncRequest); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + EncRequest.Type |= WILL_WRITE; + + // SNB hack. On some SNB, it seems to require more surfaces + EncRequest.NumFrameSuggested += m_mfxEncParams.AsyncDepth; + + // Allocate required surfaces + if (m_bUseD3D11) { + sts = m_mfxAllocator.Alloc(m_mfxAllocator.pthis, &EncRequest, + &m_mfxResponse); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + m_nSurfNum = m_mfxResponse.NumFrameActual; + + m_pmfxSurfaces = new mfxFrameSurface1 *[m_nSurfNum]; + MSDK_CHECK_POINTER(m_pmfxSurfaces, MFX_ERR_MEMORY_ALLOC); + + for (int i = 0; i < m_nSurfNum; i++) { + m_pmfxSurfaces[i] = new mfxFrameSurface1; + memset(m_pmfxSurfaces[i], 0, sizeof(mfxFrameSurface1)); + memcpy(&(m_pmfxSurfaces[i]->Info), + &(m_mfxEncParams.mfx.FrameInfo), + sizeof(mfxFrameInfo)); + m_pmfxSurfaces[i]->Data.MemId = m_mfxResponse.mids[i]; + } + } + else { + mfxU16 width = (mfxU16)MSDK_ALIGN32(EncRequest.Info.Width); + mfxU16 height = (mfxU16)MSDK_ALIGN32(EncRequest.Info.Height); + mfxU8 bitsPerPixel = 12; + mfxU32 surfaceSize = width * height * bitsPerPixel / 8; + m_nSurfNum = EncRequest.NumFrameSuggested; + + m_pmfxSurfaces = new mfxFrameSurface1 *[m_nSurfNum]; + for (int i = 0; i < m_nSurfNum; i++) { + m_pmfxSurfaces[i] = new mfxFrameSurface1; + memset(m_pmfxSurfaces[i], 0, sizeof(mfxFrameSurface1)); + memcpy(&(m_pmfxSurfaces[i]->Info), + &(m_mfxEncParams.mfx.FrameInfo), + sizeof(mfxFrameInfo)); + + mfxU8* pSurface = (mfxU8*) new mfxU8[surfaceSize]; + m_pmfxSurfaces[i]->Data.Y = pSurface; + m_pmfxSurfaces[i]->Data.U = pSurface + width * height; + m_pmfxSurfaces[i]->Data.V = pSurface + width * height + 1; + m_pmfxSurfaces[i]->Data.Pitch = width; + } + } + + blog(LOG_INFO, "\tm_nSurfNum: %d", m_nSurfNum); + + return sts; +} + +mfxStatus QSV_Encoder_Internal::GetVideoParam() +{ + memset(&m_parameter, 0, sizeof(m_parameter)); + mfxExtCodingOptionSPSPPS opt; + memset(&m_parameter, 0, sizeof(m_parameter)); + opt.Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS; + opt.Header.BufferSz = sizeof(mfxExtCodingOptionSPSPPS); + + static mfxExtBuffer* extendedBuffers[1]; + extendedBuffers[0] = (mfxExtBuffer*)& opt; + m_parameter.ExtParam = extendedBuffers; + m_parameter.NumExtParam = 1; + + opt.SPSBuffer = m_SPSBuffer; + opt.PPSBuffer = m_PPSBuffer; + opt.SPSBufSize = 100; // m_nSPSBufferSize; + opt.PPSBufSize = 100; // m_nPPSBufferSize; + + mfxStatus sts = m_pmfxENC->GetVideoParam(&m_parameter); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + m_nSPSBufferSize = opt.SPSBufSize; + m_nPPSBufferSize = opt.PPSBufSize; + + return sts; +} + +void QSV_Encoder_Internal::GetSPSPPS(mfxU8 **pSPSBuf, mfxU8 **pPPSBuf, + mfxU16 *pnSPSBuf, mfxU16 *pnPPSBuf) +{ + *pSPSBuf = m_SPSBuffer; + *pPPSBuf = m_PPSBuffer; + *pnSPSBuf = m_nSPSBufferSize; + *pnPPSBuf = m_nPPSBufferSize; +} + +mfxStatus QSV_Encoder_Internal::InitBitstream() +{ + m_nTaskPool = m_parameter.AsyncDepth; + m_nFirstSyncTask = 0; + + m_pTaskPool = new Task[m_nTaskPool]; + memset(m_pTaskPool, 0, sizeof(Task) * m_nTaskPool); + + for (int i = 0; i < m_nTaskPool; i++) { + m_pTaskPool[i].mfxBS.MaxLength = + m_parameter.mfx.BufferSizeInKB * 1000; + m_pTaskPool[i].mfxBS.Data = + new mfxU8[m_pTaskPool[i].mfxBS.MaxLength]; + m_pTaskPool[i].mfxBS.DataOffset = 0; + m_pTaskPool[i].mfxBS.DataLength = 0; + + MSDK_CHECK_POINTER(m_pTaskPool[i].mfxBS.Data, + MFX_ERR_MEMORY_ALLOC); + } + + memset(&m_outBitstream, 0, sizeof(mfxBitstream)); + m_outBitstream.MaxLength = m_parameter.mfx.BufferSizeInKB * 1000; + m_outBitstream.Data = new mfxU8[m_outBitstream.MaxLength]; + m_outBitstream.DataOffset = 0; + m_outBitstream.DataLength = 0; + + blog(LOG_INFO, "\tm_nTaskPool: %d", m_nTaskPool); + + return MFX_ERR_NONE; +} + +mfxStatus QSV_Encoder_Internal::LoadNV12(mfxFrameSurface1 *pSurface, + uint8_t *pDataY, uint8_t *pDataUV, uint32_t strideY, + uint32_t strideUV) +{ + mfxU16 w, h, i, pitch; + mfxU8* ptr; + mfxFrameInfo* pInfo = &pSurface->Info; + mfxFrameData* pData = &pSurface->Data; + + if (pInfo->CropH > 0 && pInfo->CropW > 0) + { + w = pInfo->CropW; + h = pInfo->CropH; + } + else + { + w = pInfo->Width; + h = pInfo->Height; + } + + pitch = pData->Pitch; + ptr = pData->Y + pInfo->CropX + pInfo->CropY * pData->Pitch; + + // load Y plane + for (i = 0; i < h; i++) + memcpy(ptr + i * pitch, pDataY + i * strideY, w); + + // load UV plane + h /= 2; + ptr = pData->UV + pInfo->CropX + (pInfo->CropY / 2) * pitch; + + for (i = 0; i < h; i++) + memcpy(ptr + i * pitch, pDataUV + i * strideUV, w); + + return MFX_ERR_NONE; +} + +int QSV_Encoder_Internal::GetFreeTaskIndex(Task* pTaskPool, mfxU16 nPoolSize) +{ + if (pTaskPool) + for (int i = 0; i < nPoolSize; i++) + if (!pTaskPool[i].syncp) + return i; + return MFX_ERR_NOT_FOUND; +} + +mfxStatus QSV_Encoder_Internal::Encode(uint64_t ts, uint8_t *pDataY, + uint8_t *pDataUV, uint32_t strideY, uint32_t strideUV, + mfxBitstream **pBS) +{ + mfxStatus sts = MFX_ERR_NONE; + *pBS = NULL; + int nTaskIdx = GetFreeTaskIndex(m_pTaskPool, m_nTaskPool); + +#if 0 + info("MSDK Encode:\n" + "\tTaskIndex: %d", + nTaskIdx); +#endif + + int nSurfIdx = GetFreeSurfaceIndex(m_pmfxSurfaces, m_nSurfNum); +#if 0 + info("MSDK Encode:\n" + "\tnSurfIdx: %d", + nSurfIdx); +#endif + + while (MFX_ERR_NOT_FOUND == nTaskIdx || MFX_ERR_NOT_FOUND == nSurfIdx) { + // No more free tasks or surfaces, need to sync + sts = m_session.SyncOperation(m_pTaskPool[m_nFirstSyncTask].syncp, + 60000); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + mfxU8 *pTemp = m_outBitstream.Data; + memcpy(&m_outBitstream, &m_pTaskPool[m_nFirstSyncTask].mfxBS, + sizeof(mfxBitstream)); + + m_pTaskPool[m_nFirstSyncTask].mfxBS.Data = pTemp; + m_pTaskPool[m_nFirstSyncTask].mfxBS.DataLength = 0; + m_pTaskPool[m_nFirstSyncTask].mfxBS.DataOffset = 0; + m_pTaskPool[m_nFirstSyncTask].syncp = NULL; + nTaskIdx = m_nFirstSyncTask; + m_nFirstSyncTask = (m_nFirstSyncTask + 1) % m_nTaskPool; + *pBS = &m_outBitstream; + +#if 0 + info("MSDK Encode:\n" + "\tnew FirstSyncTask: %d\n" + "\tTaskIndex: %d", + m_nFirstSyncTask, + nTaskIdx); +#endif + + nSurfIdx = GetFreeSurfaceIndex(m_pmfxSurfaces, m_nSurfNum); +#if 0 + info("MSDK Encode:\n" + "\tnSurfIdx: %d", + nSurfIdx); +#endif + } + + mfxFrameSurface1 *pSurface = m_pmfxSurfaces[nSurfIdx]; + if (m_bUseD3D11) + sts = m_mfxAllocator.Lock(m_mfxAllocator.pthis, + pSurface->Data.MemId, &(pSurface->Data)); + + sts = LoadNV12(pSurface, pDataY, pDataUV, strideY, strideUV); + pSurface->Data.TimeStamp = ts; + + if (m_bUseD3D11) + sts = m_mfxAllocator.Unlock(m_mfxAllocator.pthis, + pSurface->Data.MemId, &(pSurface->Data)); + + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + for (;;) { + // Encode a frame asychronously (returns immediately) + sts = m_pmfxENC->EncodeFrameAsync(NULL, pSurface, + &m_pTaskPool[nTaskIdx].mfxBS, + &m_pTaskPool[nTaskIdx].syncp); + + if (MFX_ERR_NONE < sts && !m_pTaskPool[nTaskIdx].syncp) { + // Repeat the call if warning and no output + if (MFX_WRN_DEVICE_BUSY == sts) + MSDK_SLEEP(1); // Wait if device is busy, then repeat the same call + } else if (MFX_ERR_NONE < sts && m_pTaskPool[nTaskIdx].syncp) { + sts = MFX_ERR_NONE; // Ignore warnings if output is available + break; + } else if (MFX_ERR_NOT_ENOUGH_BUFFER == sts) { + // Allocate more bitstream buffer memory here if needed... + break; + } else + break; + } + + return sts; +} + +mfxStatus QSV_Encoder_Internal::Drain() +{ + mfxStatus sts = MFX_ERR_NONE; + + while (m_pTaskPool[m_nFirstSyncTask].syncp) { + sts = m_session.SyncOperation(m_pTaskPool[m_nFirstSyncTask].syncp, 60000); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + m_pTaskPool[m_nFirstSyncTask].syncp = NULL; + m_nFirstSyncTask = (m_nFirstSyncTask + 1) % m_nTaskPool; + } + + return sts; +} + +mfxStatus QSV_Encoder_Internal::ClearData() +{ + mfxStatus sts = MFX_ERR_NONE; + sts = Drain(); + + sts = m_pmfxENC->Close(); + + if (m_bUseD3D11) + m_mfxAllocator.Free(m_mfxAllocator.pthis, &m_mfxResponse); + + for (int i = 0; i < m_nSurfNum; i++) { + if (!m_bUseD3D11) + delete m_pmfxSurfaces[i]->Data.Y; + + delete m_pmfxSurfaces[i]; + } + MSDK_SAFE_DELETE_ARRAY(m_pmfxSurfaces); + + for (int i = 0; i < m_nTaskPool; i++) + delete m_pTaskPool[i].mfxBS.Data; + MSDK_SAFE_DELETE_ARRAY(m_pTaskPool); + + delete m_outBitstream.Data; + + if (m_pmfxENC != NULL) { + delete m_pmfxENC; + m_pmfxENC = NULL; + } + + if (m_bUseD3D11) + Release(); + + m_session.Close(); + + return sts; +} + +mfxStatus QSV_Encoder_Internal::Reset(qsv_param_t *pParams) +{ + mfxStatus sts = ClearData(); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + sts = Open(pParams); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + return sts; +} diff --git a/plugins/obs-qsv11/QSV_Encoder_Internal.h b/plugins/obs-qsv11/QSV_Encoder_Internal.h new file mode 100644 index 0000000..b2648a1 --- /dev/null +++ b/plugins/obs-qsv11/QSV_Encoder_Internal.h @@ -0,0 +1,112 @@ +/* + +This file is provided under a dual BSD/GPLv2 license. When using or +redistributing this file, you may do so under either license. + +GPL LICENSE SUMMARY + +Copyright(c) Oct. 2015 Intel Corporation. + +This program is free software; you can redistribute it and/or modify +it under the terms of version 2 of the GNU General Public License as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +Contact Information: + +Seung-Woo Kim, seung-woo.kim@intel.com +705 5th Ave S #500, Seattle, WA 98104 + +BSD LICENSE + +Copyright(c) Intel Corporation. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +* Neither the name of Intel Corporation nor the names of its +contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#pragma once +#include "mfxastructures.h" +#include "mfxvideo++.h" +#include "QSV_Encoder.h" +#include "common_utils.h" + +class QSV_Encoder_Internal +{ +public: + QSV_Encoder_Internal(mfxIMPL& impl, mfxVersion& version); + ~QSV_Encoder_Internal(); + + mfxStatus Open(qsv_param_t * pParams); + void GetSPSPPS(mfxU8 **pSPSBuf, mfxU8 **pPPSBuf, + mfxU16 *pnSPSBuf, mfxU16 *pnPPSBuf); + mfxStatus Encode(uint64_t ts, uint8_t *pDataY, uint8_t *pDataUV, + uint32_t strideY, uint32_t strideUV, mfxBitstream + **pBS); + mfxStatus ClearData(); + mfxStatus Reset(qsv_param_t *pParams); + +protected: + bool InitParams(qsv_param_t * pParams); + mfxStatus AllocateSurfaces(); + mfxStatus GetVideoParam(); + mfxStatus InitBitstream(); + mfxStatus LoadNV12(mfxFrameSurface1 *pSurface, uint8_t *pDataY, + uint8_t *pDataUV, uint32_t strideY, uint32_t strideUV); + mfxStatus Drain(); + int GetFreeTaskIndex(Task* pTaskPool, mfxU16 nPoolSize); + +private: + mfxIMPL m_impl; + mfxVersion m_ver; + MFXVideoSession m_session; + mfxFrameAllocator m_mfxAllocator; + mfxVideoParam m_mfxEncParams; + mfxFrameAllocResponse m_mfxResponse; + mfxFrameSurface1** m_pmfxSurfaces; + mfxU16 m_nSurfNum; + MFXVideoENCODE* m_pmfxENC; + mfxU8 m_SPSBuffer[100]; + mfxU8 m_PPSBuffer[100]; + mfxU16 m_nSPSBufferSize; + mfxU16 m_nPPSBufferSize; + mfxVideoParam m_parameter; + mfxExtCodingOption2 m_co2; + mfxExtCodingOption m_co; + mfxU16 m_nTaskPool; + Task* m_pTaskPool; + int m_nTaskIdx; + int m_nFirstSyncTask; + mfxBitstream m_outBitstream; + bool m_bIsWindows8OrGreater; + bool m_bUseD3D11; +}; + diff --git a/plugins/obs-qsv11/bits/linux_defs.h b/plugins/obs-qsv11/bits/linux_defs.h new file mode 100644 index 0000000..7a46dbb --- /dev/null +++ b/plugins/obs-qsv11/bits/linux_defs.h @@ -0,0 +1,19 @@ +/***************************************************************************** + +INTEL CORPORATION PROPRIETARY INFORMATION +This software is supplied under the terms of a license agreement or +nondisclosure agreement with Intel Corporation and may not be copied +or disclosed except in accordance with the terms of that agreement. +Copyright(c) 2005-2014 Intel Corporation. All Rights Reserved. + +*****************************************************************************/ + +#include +#include +#include +#include + +#define MSDK_FOPEN(FH, FN, M) { FH=fopen(FN,M); } +#define MSDK_SLEEP(X) { usleep(1000*(X)); } + +typedef timespec mfxTime; diff --git a/plugins/obs-qsv11/bits/windows_defs.h b/plugins/obs-qsv11/bits/windows_defs.h new file mode 100644 index 0000000..d81cae5 --- /dev/null +++ b/plugins/obs-qsv11/bits/windows_defs.h @@ -0,0 +1,16 @@ +/***************************************************************************** + +INTEL CORPORATION PROPRIETARY INFORMATION +This software is supplied under the terms of a license agreement or +nondisclosure agreement with Intel Corporation and may not be copied +or disclosed except in accordance with the terms of that agreement. +Copyright(c) 2005-2014 Intel Corporation. All Rights Reserved. + +*****************************************************************************/ + +#include + +#define MSDK_FOPEN(FH, FN, M) { fopen_s(&FH, FN, M); } +#define MSDK_SLEEP(X) { Sleep(X); } + +typedef LARGE_INTEGER mfxTime; diff --git a/plugins/obs-qsv11/common_directx11.cpp b/plugins/obs-qsv11/common_directx11.cpp new file mode 100644 index 0000000..bd800b7 --- /dev/null +++ b/plugins/obs-qsv11/common_directx11.cpp @@ -0,0 +1,487 @@ +/***************************************************************************** + +INTEL CORPORATION PROPRIETARY INFORMATION +This software is supplied under the terms of a license agreement or +nondisclosure agreement with Intel Corporation and may not be copied +or disclosed except in accordance with the terms of that agreement. +Copyright(c) 2005-2014 Intel Corporation. All Rights Reserved. + +*****************************************************************************/ + +#include "common_directx11.h" + +#include + +ID3D11Device* g_pD3D11Device; +ID3D11DeviceContext* g_pD3D11Ctx; +IDXGIFactory2* g_pDXGIFactory; +IDXGIAdapter* g_pAdapter; + +std::map allocResponses; +std::map allocDecodeResponses; +std::map allocDecodeRefCount; + +typedef struct { + mfxMemId memId; + mfxMemId memIdStage; + mfxU16 rw; +} CustomMemId; + +const struct { + mfxIMPL impl; // actual implementation + mfxU32 adapterID; // device adapter number +} implTypes[] = { + {MFX_IMPL_HARDWARE, 0}, + {MFX_IMPL_HARDWARE2, 1}, + {MFX_IMPL_HARDWARE3, 2}, + {MFX_IMPL_HARDWARE4, 3} +}; + +// ================================================================= +// DirectX functionality required to manage DX11 device and surfaces +// + +IDXGIAdapter* GetIntelDeviceAdapterHandle(mfxSession session) +{ + mfxU32 adapterNum = 0; + mfxIMPL impl; + + MFXQueryIMPL(session, &impl); + + mfxIMPL baseImpl = MFX_IMPL_BASETYPE(impl); // Extract Media SDK base implementation type + + // get corresponding adapter number + for (mfxU8 i = 0; i < sizeof(implTypes)/sizeof(implTypes[0]); i++) { + if (implTypes[i].impl == baseImpl) { + adapterNum = implTypes[i].adapterID; + break; + } + } + + HRESULT hres = CreateDXGIFactory(__uuidof(IDXGIFactory2), (void**)(&g_pDXGIFactory) ); + if (FAILED(hres)) return NULL; + + IDXGIAdapter* adapter; + hres = g_pDXGIFactory->EnumAdapters(adapterNum, &adapter); + if (FAILED(hres)) return NULL; + + return adapter; +} + +// Create HW device context +mfxStatus CreateHWDevice(mfxSession session, mfxHDL* deviceHandle, HWND hWnd, bool bCreateSharedHandles) +{ + //Note: not using bCreateSharedHandles for DX11 -- for API consistency only + hWnd; // Window handle not required by DX11 since we do not showcase rendering. + bCreateSharedHandles; // For rendering, not used here. Just for consistencies sake. + + HRESULT hres = S_OK; + + static D3D_FEATURE_LEVEL FeatureLevels[] = { + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0 + }; + D3D_FEATURE_LEVEL pFeatureLevelsOut; + + g_pAdapter = GetIntelDeviceAdapterHandle(session); + if (NULL == g_pAdapter) + return MFX_ERR_DEVICE_FAILED; + + UINT dxFlags = 0; + //UINT dxFlags = D3D11_CREATE_DEVICE_DEBUG; + + hres = D3D11CreateDevice( g_pAdapter, + D3D_DRIVER_TYPE_UNKNOWN, + NULL, + dxFlags, + FeatureLevels, + (sizeof(FeatureLevels) / sizeof(FeatureLevels[0])), + D3D11_SDK_VERSION, + &g_pD3D11Device, + &pFeatureLevelsOut, + &g_pD3D11Ctx); + if (FAILED(hres)) + return MFX_ERR_DEVICE_FAILED; + + // turn on multithreading for the DX11 context + CComQIPtr p_mt(g_pD3D11Ctx); + if (p_mt) + p_mt->SetMultithreadProtected(true); + else + return MFX_ERR_DEVICE_FAILED; + + *deviceHandle = (mfxHDL)g_pD3D11Device; + + return MFX_ERR_NONE; +} + + +void SetHWDeviceContext(CComPtr devCtx) +{ + g_pD3D11Ctx = devCtx; + devCtx->GetDevice(&g_pD3D11Device); +} + +// Free HW device context +void CleanupHWDevice() +{ + if (g_pAdapter) + { + g_pAdapter->Release(); + g_pAdapter = NULL; + } + if (g_pD3D11Device) + { + g_pD3D11Device->Release(); + g_pD3D11Device = NULL; + } + if (g_pD3D11Ctx) + { + g_pD3D11Ctx->Release(); + g_pD3D11Ctx = NULL; + } + if (g_pDXGIFactory) + { + g_pDXGIFactory->Release(); + g_pDXGIFactory = NULL; + } +} + +CComPtr GetHWDeviceContext() +{ + return g_pD3D11Ctx; +} + +/* (Hugh) Functions currently unused */ +#if 0 +void ClearYUVSurfaceD3D(mfxMemId memId) +{ + // TBD +} + +void ClearRGBSurfaceD3D(mfxMemId memId) +{ + // TBD +} +#endif + +// +// Intel Media SDK memory allocator entrypoints.... +// +mfxStatus _simple_alloc(mfxFrameAllocRequest* request, mfxFrameAllocResponse* response) +{ + HRESULT hRes; + + // Determine surface format + DXGI_FORMAT format; + if (MFX_FOURCC_NV12 == request->Info.FourCC) + format = DXGI_FORMAT_NV12; + else if (MFX_FOURCC_RGB4 == request->Info.FourCC) + format = DXGI_FORMAT_B8G8R8A8_UNORM; + else if (MFX_FOURCC_YUY2== request->Info.FourCC) + format = DXGI_FORMAT_YUY2; + else if (MFX_FOURCC_P8 == request->Info.FourCC ) //|| MFX_FOURCC_P8_TEXTURE == request->Info.FourCC + format = DXGI_FORMAT_P8; + else + format = DXGI_FORMAT_UNKNOWN; + + if (DXGI_FORMAT_UNKNOWN == format) + return MFX_ERR_UNSUPPORTED; + + + // Allocate custom container to keep texture and stage buffers for each surface + // Container also stores the intended read and/or write operation. + CustomMemId** mids = (CustomMemId**)calloc(request->NumFrameSuggested, sizeof(CustomMemId*)); + if (!mids) return MFX_ERR_MEMORY_ALLOC; + + for (int i=0; iNumFrameSuggested; i++) { + mids[i] = (CustomMemId*)calloc(1, sizeof(CustomMemId)); + if (!mids[i]) { + return MFX_ERR_MEMORY_ALLOC; + } + mids[i]->rw = request->Type & 0xF000; // Set intended read/write operation + } + + request->Type = request->Type & 0x0FFF; + + // because P8 data (bitstream) for h264 encoder should be allocated by CreateBuffer() + // but P8 data (MBData) for MPEG2 encoder should be allocated by CreateTexture2D() + if (request->Info.FourCC == MFX_FOURCC_P8) { + D3D11_BUFFER_DESC desc = { 0 }; + + if (!request->NumFrameSuggested) return MFX_ERR_MEMORY_ALLOC; + + desc.ByteWidth = request->Info.Width * request->Info.Height; + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + desc.MiscFlags = 0; + desc.StructureByteStride = 0; + + ID3D11Buffer* buffer = 0; + hRes = g_pD3D11Device->CreateBuffer(&desc, 0, &buffer); + if (FAILED(hRes)) + return MFX_ERR_MEMORY_ALLOC; + + mids[0]->memId = reinterpret_cast(buffer); + } else { + D3D11_TEXTURE2D_DESC desc = {0}; + + desc.Width = request->Info.Width; + desc.Height = request->Info.Height; + desc.MipLevels = 1; + desc.ArraySize = 1; // number of subresources is 1 in this case + desc.Format = format; + desc.SampleDesc.Count = 1; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_DECODER; + desc.MiscFlags = 0; + //desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; + + if ( (MFX_MEMTYPE_FROM_VPPIN & request->Type) && + (DXGI_FORMAT_B8G8R8A8_UNORM == desc.Format) ) { + desc.BindFlags = D3D11_BIND_RENDER_TARGET; + if (desc.ArraySize > 2) + return MFX_ERR_MEMORY_ALLOC; + } + + if ( (MFX_MEMTYPE_FROM_VPPOUT & request->Type) || + (MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET & request->Type)) { + desc.BindFlags = D3D11_BIND_RENDER_TARGET; + if (desc.ArraySize > 2) + return MFX_ERR_MEMORY_ALLOC; + } + + if ( DXGI_FORMAT_P8 == desc.Format ) + desc.BindFlags = 0; + + ID3D11Texture2D* pTexture2D; + + // Create surface textures + for (size_t i = 0; i < request->NumFrameSuggested / desc.ArraySize; i++) { + hRes = g_pD3D11Device->CreateTexture2D(&desc, NULL, &pTexture2D); + + if (FAILED(hRes)) + return MFX_ERR_MEMORY_ALLOC; + + mids[i]->memId = pTexture2D; + } + + desc.ArraySize = 1; + desc.Usage = D3D11_USAGE_STAGING; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;// | D3D11_CPU_ACCESS_WRITE; + desc.BindFlags = 0; + desc.MiscFlags = 0; + //desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; + + // Create surface staging textures + for (size_t i = 0; i < request->NumFrameSuggested; i++) { + hRes = g_pD3D11Device->CreateTexture2D(&desc, NULL, &pTexture2D); + + if (FAILED(hRes)) + return MFX_ERR_MEMORY_ALLOC; + + mids[i]->memIdStage = pTexture2D; + } + } + + + response->mids = (mfxMemId*)mids; + response->NumFrameActual = request->NumFrameSuggested; + + return MFX_ERR_NONE; +} + +mfxStatus simple_alloc(mfxHDL pthis, mfxFrameAllocRequest* request, mfxFrameAllocResponse* response) +{ + mfxStatus sts = MFX_ERR_NONE; + + if (request->Type & MFX_MEMTYPE_SYSTEM_MEMORY) + return MFX_ERR_UNSUPPORTED; + + if (allocDecodeResponses.find(pthis) != allocDecodeResponses.end() && + MFX_MEMTYPE_EXTERNAL_FRAME & request->Type && + MFX_MEMTYPE_FROM_DECODE & request->Type) { + // Memory for this request was already allocated during manual allocation stage. Return saved response + // When decode acceleration device (DXVA) is created it requires a list of d3d surfaces to be passed. + // Therefore Media SDK will ask for the surface info/mids again at Init() stage, thus requiring us to return the saved response + // (No such restriction applies to Encode or VPP) + *response = allocDecodeResponses[pthis]; + allocDecodeRefCount[pthis]++; + } else { + sts = _simple_alloc(request, response); + + if (MFX_ERR_NONE == sts) { + if ( MFX_MEMTYPE_EXTERNAL_FRAME & request->Type && + MFX_MEMTYPE_FROM_DECODE & request->Type) { + // Decode alloc response handling + allocDecodeResponses[pthis] = *response; + allocDecodeRefCount[pthis]++; + } else { + // Encode and VPP alloc response handling + allocResponses[response->mids] = pthis; + } + } + } + + return sts; +} + +mfxStatus simple_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData* ptr) +{ + pthis; // To suppress warning for this unused parameter + + HRESULT hRes = S_OK; + + D3D11_TEXTURE2D_DESC desc = {0}; + D3D11_MAPPED_SUBRESOURCE lockedRect = {0}; + + CustomMemId* memId = (CustomMemId*)mid; + ID3D11Texture2D* pSurface = (ID3D11Texture2D*)memId->memId; + ID3D11Texture2D* pStage = (ID3D11Texture2D*)memId->memIdStage; + + D3D11_MAP mapType = D3D11_MAP_READ; + UINT mapFlags = D3D11_MAP_FLAG_DO_NOT_WAIT; + + if (NULL == pStage) { + hRes = g_pD3D11Ctx->Map(pSurface, 0, mapType, mapFlags, &lockedRect); + desc.Format = DXGI_FORMAT_P8; + } else { + pSurface->GetDesc(&desc); + + // copy data only in case of user wants o read from stored surface + if (memId->rw & WILL_READ) + g_pD3D11Ctx->CopySubresourceRegion(pStage, 0, 0, 0, 0, pSurface, 0, NULL); + + do { + hRes = g_pD3D11Ctx->Map(pStage, 0, mapType, mapFlags, &lockedRect); + if (S_OK != hRes && DXGI_ERROR_WAS_STILL_DRAWING != hRes) + return MFX_ERR_LOCK_MEMORY; + } while (DXGI_ERROR_WAS_STILL_DRAWING == hRes); + } + + if (FAILED(hRes)) + return MFX_ERR_LOCK_MEMORY; + + switch (desc.Format) { + case DXGI_FORMAT_NV12: + ptr->Pitch = (mfxU16)lockedRect.RowPitch; + ptr->Y = (mfxU8*)lockedRect.pData; + ptr->U = (mfxU8*)lockedRect.pData + desc.Height * lockedRect.RowPitch; + ptr->V = ptr->U + 1; + break; + case DXGI_FORMAT_B8G8R8A8_UNORM : + ptr->Pitch = (mfxU16)lockedRect.RowPitch; + ptr->B = (mfxU8*)lockedRect.pData; + ptr->G = ptr->B + 1; + ptr->R = ptr->B + 2; + ptr->A = ptr->B + 3; + break; + case DXGI_FORMAT_YUY2: + ptr->Pitch = (mfxU16)lockedRect.RowPitch; + ptr->Y = (mfxU8*)lockedRect.pData; + ptr->U = ptr->Y + 1; + ptr->V = ptr->Y + 3; + break; + case DXGI_FORMAT_P8 : + ptr->Pitch = (mfxU16)lockedRect.RowPitch; + ptr->Y = (mfxU8*)lockedRect.pData; + ptr->U = 0; + ptr->V = 0; + break; + default: + return MFX_ERR_LOCK_MEMORY; + } + + return MFX_ERR_NONE; +} + +mfxStatus simple_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData* ptr) +{ + pthis; // To suppress warning for this unused parameter + + CustomMemId* memId = (CustomMemId*)mid; + ID3D11Texture2D* pSurface = (ID3D11Texture2D*)memId->memId; + ID3D11Texture2D* pStage = (ID3D11Texture2D*)memId->memIdStage; + + if (NULL == pStage) { + g_pD3D11Ctx->Unmap(pSurface, 0); + } else { + g_pD3D11Ctx->Unmap(pStage, 0); + // copy data only in case of user wants to write to stored surface + if (memId->rw & WILL_WRITE) + g_pD3D11Ctx->CopySubresourceRegion(pSurface, 0, 0, 0, 0, pStage, 0, NULL); + } + + if (ptr) { + ptr->Pitch=0; + ptr->U=ptr->V=ptr->Y=0; + ptr->A=ptr->R=ptr->G=ptr->B=0; + } + + return MFX_ERR_NONE; +} + +mfxStatus simple_gethdl(mfxHDL pthis, mfxMemId mid, mfxHDL* handle) +{ + pthis; // To suppress warning for this unused parameter + + if (NULL == handle) + return MFX_ERR_INVALID_HANDLE; + + mfxHDLPair* pPair = (mfxHDLPair*)handle; + CustomMemId* memId = (CustomMemId*)mid; + + pPair->first = memId->memId; // surface texture + pPair->second = 0; + + return MFX_ERR_NONE; +} + + +mfxStatus _simple_free(mfxFrameAllocResponse* response) +{ + if (response->mids) { + for (mfxU32 i = 0; i < response->NumFrameActual; i++) { + if (response->mids[i]) { + CustomMemId* mid = (CustomMemId*)response->mids[i]; + ID3D11Texture2D* pSurface = (ID3D11Texture2D*)mid->memId; + ID3D11Texture2D* pStage = (ID3D11Texture2D*)mid->memIdStage; + + if (pSurface) + pSurface->Release(); + if (pStage) + pStage->Release(); + + free(mid); + } + } + free(response->mids); + response->mids = NULL; + } + + return MFX_ERR_NONE; +} + +mfxStatus simple_free(mfxHDL pthis, mfxFrameAllocResponse* response) +{ + if (NULL == response) + return MFX_ERR_NULL_PTR; + + if (allocResponses.find(response->mids) == allocResponses.end()) { + // Decode free response handling + if (--allocDecodeRefCount[pthis] == 0) { + _simple_free(response); + allocDecodeResponses.erase(pthis); + allocDecodeRefCount.erase(pthis); + } + } else { + // Encode and VPP free response handling + allocResponses.erase(response->mids); + _simple_free(response); + } + + return MFX_ERR_NONE; +} diff --git a/plugins/obs-qsv11/common_directx11.h b/plugins/obs-qsv11/common_directx11.h new file mode 100644 index 0000000..3aa6075 --- /dev/null +++ b/plugins/obs-qsv11/common_directx11.h @@ -0,0 +1,39 @@ +/***************************************************************************** + +INTEL CORPORATION PROPRIETARY INFORMATION +This software is supplied under the terms of a license agreement or +nondisclosure agreement with Intel Corporation and may not be copied +or disclosed except in accordance with the terms of that agreement. +Copyright(c) 2005-2014 Intel Corporation. All Rights Reserved. + +*****************************************************************************/ + +#pragma once + +#include "common_utils.h" + +#include +#include +#include +#include + +#define DEVICE_MGR_TYPE MFX_HANDLE_D3D11_DEVICE + +// ================================================================= +// DirectX functionality required to manage D3D surfaces +// + +// Create DirectX 11 device context +// - Required when using D3D surfaces. +// - D3D Device created and handed to Intel Media SDK +// - Intel graphics device adapter will be determined automatically (does not have to be primary), +// but with the following caveats: +// - Device must be active (but monitor does NOT have to be attached) +// - Device must be enabled in BIOS. Required for the case when used together with a discrete graphics card +// - For switchable graphics solutions (mobile) make sure that Intel device is the active device +mfxStatus CreateHWDevice(mfxSession session, mfxHDL* deviceHandle, HWND hWnd, bool bCreateSharedHandles); +void CleanupHWDevice(); +void SetHWDeviceContext(CComPtr devCtx); +CComPtr GetHWDeviceContext(); +void ClearYUVSurfaceD3D(mfxMemId memId); +void ClearRGBSurfaceD3D(mfxMemId memId); \ No newline at end of file diff --git a/plugins/obs-qsv11/common_utils.cpp b/plugins/obs-qsv11/common_utils.cpp new file mode 100644 index 0000000..15ab60d --- /dev/null +++ b/plugins/obs-qsv11/common_utils.cpp @@ -0,0 +1,306 @@ +/***************************************************************************** + +INTEL CORPORATION PROPRIETARY INFORMATION +This software is supplied under the terms of a license agreement or +nondisclosure agreement with Intel Corporation and may not be copied +or disclosed except in accordance with the terms of that agreement. +Copyright(c) 2005-2014 Intel Corporation. All Rights Reserved. + +*****************************************************************************/ + +#include "common_utils.h" + +// ================================================================= +// Utility functions, not directly tied to Intel Media SDK functionality +// + + +void PrintErrString(int err,const char* filestr,int line) +{ + switch (err) { + case 0: + printf("\n No error.\n"); + break; + case -1: + printf("\n Unknown error: %s %d\n",filestr,line); + break; + case -2: + printf("\n Null pointer. Check filename/path + permissions? %s %d\n",filestr,line); + break; + case -3: + printf("\n Unsupported feature/library load error. %s %d\n",filestr,line); + break; + case -4: + printf("\n Could not allocate memory. %s %d\n",filestr,line); + break; + case -5: + printf("\n Insufficient IO buffers. %s %d\n",filestr,line); + break; + case -6: + printf("\n Invalid handle. %s %d\n",filestr,line); + break; + case -7: + printf("\n Memory lock failure. %s %d\n",filestr,line); + break; + case -8: + printf("\n Function called before initialization. %s %d\n",filestr,line); + break; + case -9: + printf("\n Specified object not found. %s %d\n",filestr,line); + break; + case -10: + printf("\n More input data expected. %s %d\n",filestr,line); + break; + case -11: + printf("\n More output surfaces expected. %s %d\n",filestr,line); + break; + case -12: + printf("\n Operation aborted. %s %d\n",filestr,line); + break; + case -13: + printf("\n HW device lost. %s %d\n",filestr,line); + break; + case -14: + printf("\n Incompatible video parameters. %s %d\n",filestr,line); + break; + case -15: + printf("\n Invalid video parameters. %s %d\n",filestr,line); + break; + case -16: + printf("\n Undefined behavior. %s %d\n",filestr,line); + break; + case -17: + printf("\n Device operation failure. %s %d\n",filestr,line); + break; + case -18: + printf("\n More bitstream data expected. %s %d\n",filestr,line); + break; + case -19: + printf("\n Incompatible audio parameters. %s %d\n",filestr,line); + break; + case -20: + printf("\n Invalid audio parameters. %s %d\n",filestr,line); + break; + default: + printf("\nError code %d,\t%s\t%d\n\n", err, filestr, line); + } +} + +mfxStatus ReadPlaneData(mfxU16 w, mfxU16 h, mfxU8* buf, mfxU8* ptr, + mfxU16 pitch, mfxU16 offset, FILE* fSource) +{ + mfxU32 nBytesRead; + for (mfxU16 i = 0; i < h; i++) { + nBytesRead = (mfxU32) fread(buf, 1, w, fSource); + if (w != nBytesRead) + return MFX_ERR_MORE_DATA; + for (mfxU16 j = 0; j < w; j++) + ptr[i * pitch + j * 2 + offset] = buf[j]; + } + return MFX_ERR_NONE; +} + +mfxStatus LoadRawFrame(mfxFrameSurface1* pSurface, FILE* fSource) +{ + if (!fSource) { + // Simulate instantaneous access to 1000 "empty" frames. + static int frameCount = 0; + if (1000 == frameCount++) + return MFX_ERR_MORE_DATA; + else + return MFX_ERR_NONE; + } + + mfxStatus sts = MFX_ERR_NONE; + mfxU32 nBytesRead; + mfxU16 w, h, i, pitch; + mfxU8* ptr; + mfxFrameInfo* pInfo = &pSurface->Info; + mfxFrameData* pData = &pSurface->Data; + + if (pInfo->CropH > 0 && pInfo->CropW > 0) { + w = pInfo->CropW; + h = pInfo->CropH; + } else { + w = pInfo->Width; + h = pInfo->Height; + } + + pitch = pData->Pitch; + ptr = pData->Y + pInfo->CropX + pInfo->CropY * pData->Pitch; + + // read luminance plane + for (i = 0; i < h; i++) { + nBytesRead = (mfxU32) fread(ptr + i * pitch, 1, w, fSource); + if (w != nBytesRead) + return MFX_ERR_MORE_DATA; + } + + mfxU8 buf[2048]; // maximum supported chroma width for nv12 + w /= 2; + h /= 2; + ptr = pData->UV + pInfo->CropX + (pInfo->CropY / 2) * pitch; + if (w > 2048) + return MFX_ERR_UNSUPPORTED; + + // load U + sts = ReadPlaneData(w, h, buf, ptr, pitch, 0, fSource); + if (MFX_ERR_NONE != sts) + return sts; + // load V + ReadPlaneData(w, h, buf, ptr, pitch, 1, fSource); + if (MFX_ERR_NONE != sts) + return sts; + + return MFX_ERR_NONE; +} + +mfxStatus LoadRawRGBFrame(mfxFrameSurface1* pSurface, FILE* fSource) +{ + if (!fSource) { + // Simulate instantaneous access to 1000 "empty" frames. + static int frameCount = 0; + if (1000 == frameCount++) + return MFX_ERR_MORE_DATA; + else + return MFX_ERR_NONE; + } + + size_t nBytesRead; + mfxU16 w, h; + mfxFrameInfo* pInfo = &pSurface->Info; + + if (pInfo->CropH > 0 && pInfo->CropW > 0) { + w = pInfo->CropW; + h = pInfo->CropH; + } else { + w = pInfo->Width; + h = pInfo->Height; + } + + for (mfxU16 i = 0; i < h; i++) { + nBytesRead = fread(pSurface->Data.B + i * pSurface->Data.Pitch, + 1, w * 4, fSource); + if ((size_t)(w * 4) != nBytesRead) + return MFX_ERR_MORE_DATA; + } + + return MFX_ERR_NONE; +} + +mfxStatus WriteBitStreamFrame(mfxBitstream* pMfxBitstream, FILE* fSink) +{ + mfxU32 nBytesWritten = + (mfxU32) fwrite(pMfxBitstream->Data + pMfxBitstream->DataOffset, 1, + pMfxBitstream->DataLength, fSink); + if (nBytesWritten != pMfxBitstream->DataLength) + return MFX_ERR_UNDEFINED_BEHAVIOR; + + pMfxBitstream->DataLength = 0; + + return MFX_ERR_NONE; +} + +mfxStatus ReadBitStreamData(mfxBitstream* pBS, FILE* fSource) +{ + memmove(pBS->Data, pBS->Data + pBS->DataOffset, pBS->DataLength); + pBS->DataOffset = 0; + + mfxU32 nBytesRead = (mfxU32) fread(pBS->Data + pBS->DataLength, 1, + pBS->MaxLength - pBS->DataLength, + fSource); + + if (0 == nBytesRead) + return MFX_ERR_MORE_DATA; + + pBS->DataLength += nBytesRead; + + return MFX_ERR_NONE; +} + +mfxStatus WriteSection(mfxU8* plane, mfxU16 factor, mfxU16 chunksize, + mfxFrameInfo* pInfo, mfxFrameData* pData, mfxU32 i, + mfxU32 j, FILE* fSink) +{ + if (chunksize != + fwrite(plane + + (pInfo->CropY * pData->Pitch / factor + pInfo->CropX) + + i * pData->Pitch + j, 1, chunksize, fSink)) + return MFX_ERR_UNDEFINED_BEHAVIOR; + return MFX_ERR_NONE; +} + +mfxStatus WriteRawFrame(mfxFrameSurface1* pSurface, FILE* fSink) +{ + mfxFrameInfo* pInfo = &pSurface->Info; + mfxFrameData* pData = &pSurface->Data; + mfxU32 i, j, h, w; + mfxStatus sts = MFX_ERR_NONE; + + for (i = 0; i < pInfo->CropH; i++) + sts = + WriteSection(pData->Y, 1, pInfo->CropW, pInfo, pData, i, 0, + fSink); + + h = pInfo->CropH / 2; + w = pInfo->CropW; + for (i = 0; i < h; i++) + for (j = 0; j < w; j += 2) + sts = + WriteSection(pData->UV, 2, 1, pInfo, pData, i, j, + fSink); + for (i = 0; i < h; i++) + for (j = 1; j < w; j += 2) + sts = + WriteSection(pData->UV, 2, 1, pInfo, pData, i, j, + fSink); + + return sts; +} + +int GetFreeTaskIndex(Task* pTaskPool, mfxU16 nPoolSize) +{ + if (pTaskPool) + for (int i = 0; i < nPoolSize; i++) + if (!pTaskPool[i].syncp) + return i; + return MFX_ERR_NOT_FOUND; +} + +void ClearYUVSurfaceSysMem(mfxFrameSurface1* pSfc, mfxU16 width, mfxU16 height) +{ + // In case simulating direct access to frames we initialize the allocated surfaces with default pattern + memset(pSfc->Data.Y, 100, width * height); // Y plane + memset(pSfc->Data.U, 50, (width * height)/2); // UV plane +} + + +// Get free raw frame surface +int GetFreeSurfaceIndex(mfxFrameSurface1** pSurfacesPool, mfxU16 nPoolSize) +{ + if (pSurfacesPool) + for (mfxU16 i = 0; i < nPoolSize; i++) + if (0 == pSurfacesPool[i]->Data.Locked) + return i; + return MFX_ERR_NOT_FOUND; +} + +char mfxFrameTypeString(mfxU16 FrameType) +{ + mfxU8 FrameTmp = FrameType & 0xF; + char FrameTypeOut; + switch (FrameTmp) { + case MFX_FRAMETYPE_I: + FrameTypeOut = 'I'; + break; + case MFX_FRAMETYPE_P: + FrameTypeOut = 'P'; + break; + case MFX_FRAMETYPE_B: + FrameTypeOut = 'B'; + break; + default: + FrameTypeOut = '*'; + } + return FrameTypeOut; +} diff --git a/plugins/obs-qsv11/common_utils.h b/plugins/obs-qsv11/common_utils.h new file mode 100644 index 0000000..4cb5c57 --- /dev/null +++ b/plugins/obs-qsv11/common_utils.h @@ -0,0 +1,109 @@ +/***************************************************************************** + +INTEL CORPORATION PROPRIETARY INFORMATION +This software is supplied under the terms of a license agreement or +nondisclosure agreement with Intel Corporation and may not be copied +or disclosed except in accordance with the terms of that agreement. +Copyright(c) 2005-2014 Intel Corporation. All Rights Reserved. + +*****************************************************************************/ + +#pragma once + +#include + +#include "mfxvideo++.h" + +// ================================================================= +// OS-specific definitions of types, macro, etc... +// The following should be defined: +// - mfxTime +// - MSDK_FOPEN +// - MSDK_SLEEP +#if defined(_WIN32) || defined(_WIN64) +#include "bits/windows_defs.h" +#elif defined(__linux__) +#include "bits/linux_defs.h" +#endif + +// ================================================================= +// Helper macro definitions... +#define MSDK_PRINT_RET_MSG(ERR) {PrintErrString(ERR, __FILE__, __LINE__);} +#define MSDK_CHECK_RESULT(P, X, ERR) {if ((X) > (P)) {MSDK_PRINT_RET_MSG(ERR); return ERR;}} +#define MSDK_CHECK_POINTER(P, ERR) {if (!(P)) {MSDK_PRINT_RET_MSG(ERR); return ERR;}} +#define MSDK_CHECK_ERROR(P, X, ERR) {if ((X) == (P)) {MSDK_PRINT_RET_MSG(ERR); return ERR;}} +#define MSDK_IGNORE_MFX_STS(P, X) {if ((X) == (P)) {P = MFX_ERR_NONE;}} +#define MSDK_BREAK_ON_ERROR(P) {if (MFX_ERR_NONE != (P)) break;} +#define MSDK_SAFE_DELETE_ARRAY(P) {if (P) {delete[] P; P = NULL;}} +#define MSDK_ALIGN32(X) (((mfxU32)((X)+31)) & (~ (mfxU32)31)) +#define MSDK_ALIGN16(value) (((value + 15) >> 4) << 4) +#define MSDK_SAFE_RELEASE(X) {if (X) { X->Release(); X = NULL; }} +#define MSDK_MAX(A, B) (((A) > (B)) ? (A) : (B)) + +// Usage of the following two macros are only required for certain Windows DirectX11 use cases +#define WILL_READ 0x1000 +#define WILL_WRITE 0x2000 + +// ================================================================= +// Intel Media SDK memory allocator entrypoints.... +// Implementation of this functions is OS/Memory type specific. +mfxStatus simple_alloc(mfxHDL pthis, mfxFrameAllocRequest* request, mfxFrameAllocResponse* response); +mfxStatus simple_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData* ptr); +mfxStatus simple_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData* ptr); +mfxStatus simple_gethdl(mfxHDL pthis, mfxMemId mid, mfxHDL* handle); +mfxStatus simple_free(mfxHDL pthis, mfxFrameAllocResponse* response); + + + +// ================================================================= +// Utility functions, not directly tied to Media SDK functionality +// + +void PrintErrString(int err,const char* filestr,int line); + +// LoadRawFrame: Reads raw frame from YUV file (YV12) into NV12 surface +// - YV12 is a more common format for for YUV files than NV12 (therefore the conversion during read and write) +// - For the simulation case (fSource = NULL), the surface is filled with default image data +// LoadRawRGBFrame: Reads raw RGB32 frames from file into RGB32 surface +// - For the simulation case (fSource = NULL), the surface is filled with default image data + +mfxStatus LoadRawFrame(mfxFrameSurface1* pSurface, FILE* fSource); +mfxStatus LoadRawRGBFrame(mfxFrameSurface1* pSurface, FILE* fSource); + +// Write raw YUV (NV12) surface to YUV (YV12) file +mfxStatus WriteRawFrame(mfxFrameSurface1* pSurface, FILE* fSink); + +// Write bit stream data for frame to file +mfxStatus WriteBitStreamFrame(mfxBitstream* pMfxBitstream, FILE* fSink); +// Read bit stream data from file. Stream is read as large chunks (= many frames) +mfxStatus ReadBitStreamData(mfxBitstream* pBS, FILE* fSource); + +void ClearYUVSurfaceSysMem(mfxFrameSurface1* pSfc, mfxU16 width, mfxU16 height); +void ClearYUVSurfaceVMem(mfxMemId memId); +void ClearRGBSurfaceVMem(mfxMemId memId); + +// Get free raw frame surface +int GetFreeSurfaceIndex(mfxFrameSurface1** pSurfacesPool, mfxU16 nPoolSize); + +// For use with asynchronous task management +typedef struct { + mfxBitstream mfxBS; + mfxSyncPoint syncp; +} Task; + +// Get free task +int GetFreeTaskIndex(Task* pTaskPool, mfxU16 nPoolSize); + +// Initialize Intel Media SDK Session, device/display and memory manager +mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession* pSession, mfxFrameAllocator* pmfxAllocator, bool bCreateSharedHandles = false); + +// Release resources (device/display) +void Release(); + +// Convert frame type to string +char mfxFrameTypeString(mfxU16 FrameType); + +void mfxGetTime(mfxTime* timestamp); + +//void mfxInitTime(); might need this for Windows +double TimeDiffMsec(mfxTime tfinish, mfxTime tstart); diff --git a/plugins/obs-qsv11/common_utils_windows.cpp b/plugins/obs-qsv11/common_utils_windows.cpp new file mode 100644 index 0000000..2bb9f86 --- /dev/null +++ b/plugins/obs-qsv11/common_utils_windows.cpp @@ -0,0 +1,104 @@ +/***************************************************************************** + +INTEL CORPORATION PROPRIETARY INFORMATION +This software is supplied under the terms of a license agreement or +nondisclosure agreement with Intel Corporation and may not be copied +or disclosed except in accordance with the terms of that agreement. +Copyright(c) 2005-2014 Intel Corporation. All Rights Reserved. + +*****************************************************************************/ + +#include "common_utils.h" + +// ATTENTION: If D3D surfaces are used, DX9_D3D or DX11_D3D must be set in project settings or hardcoded here + +#ifdef DX9_D3D +#include "common_directx.h" +#elif DX11_D3D +#include "common_directx11.h" +#endif + +/* ======================================================= + * Windows implementation of OS-specific utility functions + */ + +mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession* pSession, mfxFrameAllocator* pmfxAllocator, bool bCreateSharedHandles) +{ + bCreateSharedHandles; // (Hugh) Currently unused + pmfxAllocator; // (Hugh) Currently unused + + mfxStatus sts = MFX_ERR_NONE; + + // If mfxFrameAllocator is provided it means we need to setup DirectX device and memory allocator + if (pmfxAllocator) { + // Initialize Intel Media SDK Session + sts = pSession->Init(impl, &ver); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + // Create DirectX device context + mfxHDL deviceHandle; + sts = CreateHWDevice(*pSession, &deviceHandle, NULL, bCreateSharedHandles); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + // Provide device manager to Media SDK + sts = pSession->SetHandle(DEVICE_MGR_TYPE, deviceHandle); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + + pmfxAllocator->pthis = *pSession; // We use Media SDK session ID as the allocation identifier + pmfxAllocator->Alloc = simple_alloc; + pmfxAllocator->Free = simple_free; + pmfxAllocator->Lock = simple_lock; + pmfxAllocator->Unlock = simple_unlock; + pmfxAllocator->GetHDL = simple_gethdl; + + // Since we are using video memory we must provide Media SDK with an external allocator + sts = pSession->SetFrameAllocator(pmfxAllocator); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + } + else + { + // Initialize Intel Media SDK Session + sts = pSession->Init(impl, &ver); + MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); + } + return sts; +} + +void Release() +{ +#if defined(DX9_D3D) || defined(DX11_D3D) + CleanupHWDevice(); +#endif +} + +void mfxGetTime(mfxTime* timestamp) +{ + QueryPerformanceCounter(timestamp); +} + +double TimeDiffMsec(mfxTime tfinish, mfxTime tstart) +{ + static LARGE_INTEGER tFreq = { 0 }; + + if (!tFreq.QuadPart) QueryPerformanceFrequency(&tFreq); + + double freq = (double)tFreq.QuadPart; + return 1000.0 * ((double)tfinish.QuadPart - (double)tstart.QuadPart) / freq; +} + +/* (Hugh) Functions currently unused */ +#if 0 +void ClearYUVSurfaceVMem(mfxMemId memId) +{ +#if defined(DX9_D3D) || defined(DX11_D3D) + ClearYUVSurfaceD3D(memId); +#endif +} + +void ClearRGBSurfaceVMem(mfxMemId memId) +{ +#if defined(DX9_D3D) || defined(DX11_D3D) + ClearRGBSurfaceD3D(memId); +#endif +} +#endif diff --git a/plugins/obs-qsv11/data/locale/ar-SA.ini b/plugins/obs-qsv11/data/locale/ar-SA.ini new file mode 100644 index 0000000..3e669bc --- /dev/null +++ b/plugins/obs-qsv11/data/locale/ar-SA.ini @@ -0,0 +1,5 @@ +Bitrate="معدّل البِت" +KeyframeIntervalSec="الفاصل الزمني لـKeyframe (ثانية, 0=تلقائي)" +Profile="الملف الشخصي" +Accuracy="الدقة" + diff --git a/plugins/obs-qsv11/data/locale/ca-ES.ini b/plugins/obs-qsv11/data/locale/ca-ES.ini new file mode 100644 index 0000000..ee0a761 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/ca-ES.ini @@ -0,0 +1,12 @@ +TargetUsage="Ús de destí" +Bitrate="Taxa de bits" +MaxBitrate="Taxa de bits màxima" +RateControl="Control de la freqüència" +KeyframeIntervalSec="Interval de fotograma clau (en segons, 0 = automàtic)" +Profile="Perfil" +AsyncDepth="Profunditat d'Async" +Accuracy="Precisió" +Convergence="Convergència" +ICQQuality="Qualitat ICQ" +LookAheadDepth="Profunditat de cerca anticipada" + diff --git a/plugins/obs-qsv11/data/locale/cs-CZ.ini b/plugins/obs-qsv11/data/locale/cs-CZ.ini new file mode 100644 index 0000000..34ccc6f --- /dev/null +++ b/plugins/obs-qsv11/data/locale/cs-CZ.ini @@ -0,0 +1,12 @@ +TargetUsage="Cíl použití" +Bitrate="Bitrate" +MaxBitrate="Maximální bitrate" +RateControl="Řízení toku" +KeyframeIntervalSec="Interval klíč. snímků (vteřiny, 0=auto)" +Profile="Profil" +AsyncDepth="Asynchronní hloubka" +Accuracy="Přesnost" +Convergence="Konvergence" +ICQQuality="Kvalita ICQ" +LookAheadDepth="Hloubka dopředné analýzy" + diff --git a/plugins/obs-qsv11/data/locale/de-DE.ini b/plugins/obs-qsv11/data/locale/de-DE.ini new file mode 100644 index 0000000..8b1cca7 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/de-DE.ini @@ -0,0 +1,12 @@ +TargetUsage="Zielnutzung" +Bitrate="Bitrate" +MaxBitrate="Max Bitrate" +RateControl="Qualitäts Regulierungsmethode" +KeyframeIntervalSec="Keyframeintervall (Sekunden, 0=auto)" +Profile="Profil" +AsyncDepth="Async Depth" +Accuracy="Genauigkeit" +Convergence="Konvergenz" +ICQQuality="ICQ-Qualität" +LookAheadDepth="Lookahead Depth" + diff --git a/plugins/obs-qsv11/data/locale/en-US.ini b/plugins/obs-qsv11/data/locale/en-US.ini new file mode 100644 index 0000000..84b5e07 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/en-US.ini @@ -0,0 +1,11 @@ +TargetUsage="Target Usage" +Bitrate="Bitrate" +MaxBitrate="Max Bitrate" +RateControl="Rate Control" +KeyframeIntervalSec="Keyframe Interval (seconds, 0=auto)" +Profile="Profile" +AsyncDepth="Async Depth" +Accuracy="Accuracy" +Convergence="Convergence" +ICQQuality="ICQ Quality" +LookAheadDepth="Lookahead Depth" diff --git a/plugins/obs-qsv11/data/locale/es-ES.ini b/plugins/obs-qsv11/data/locale/es-ES.ini new file mode 100644 index 0000000..0563bd7 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/es-ES.ini @@ -0,0 +1,12 @@ +TargetUsage="Uso de destino" +Bitrate="Bitrate" +MaxBitrate="Tasa de bits máxima" +RateControl="Control de la frecuencia" +KeyframeIntervalSec="Intervalo de keyframes (segundos, 0=auto)" +Profile="Perfíl" +AsyncDepth="Profundidad de Async" +Accuracy="Precision" +Convergence="Convergencia" +ICQQuality="Calidad ICQ" +LookAheadDepth="Profundidad de búsqueda anticipada" + diff --git a/plugins/obs-qsv11/data/locale/eu-ES.ini b/plugins/obs-qsv11/data/locale/eu-ES.ini new file mode 100644 index 0000000..7ea23a7 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/eu-ES.ini @@ -0,0 +1,12 @@ +TargetUsage="Xede Erabilpena" +Bitrate="Bitneurria" +MaxBitrate="Geh Bitneurria" +RateControl="Neurri Agintea" +KeyframeIntervalSec="Giltzaframe Tartea (segundu, 0=berez)" +Profile="Profila" +AsyncDepth="Async Sakonera" +Accuracy="Zehaztasuna" +Convergence="Bateratasuna" +ICQQuality="ICQ Ontasuna" +LookAheadDepth="Aurrerabegirako Sakonera" + diff --git a/plugins/obs-qsv11/data/locale/fi-FI.ini b/plugins/obs-qsv11/data/locale/fi-FI.ini new file mode 100644 index 0000000..180b8df --- /dev/null +++ b/plugins/obs-qsv11/data/locale/fi-FI.ini @@ -0,0 +1,12 @@ +TargetUsage="Käyttötarkoitus" +Bitrate="Bitrate" +MaxBitrate="Bitrate-maksimi" +RateControl="Nopeudensäädin" +KeyframeIntervalSec="Keyframe-väli (sec, 0=auto)" +Profile="Profiili" +AsyncDepth="Async-syvyys" +Accuracy="Tarkkus" +Convergence="Suppeneminen" +ICQQuality="ICQ laatu" +LookAheadDepth="Lookadead-syvyys" + diff --git a/plugins/obs-qsv11/data/locale/fr-FR.ini b/plugins/obs-qsv11/data/locale/fr-FR.ini new file mode 100644 index 0000000..cc6e647 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/fr-FR.ini @@ -0,0 +1,12 @@ +TargetUsage="Utilisation ciblée" +Bitrate="Débit" +MaxBitrate="Débit maximal" +RateControl="Contrôle du débit" +KeyframeIntervalSec="Intervalle d'image-clé (en secondes, 0 = auto)" +Profile="Profil" +AsyncDepth="Profondeur d'asynchronisme" +Accuracy="Précision" +Convergence="Convergence" +ICQQuality="Qualité ICQ" +LookAheadDepth="Profondeur d'anticipation" + diff --git a/plugins/obs-qsv11/data/locale/gl-ES.ini b/plugins/obs-qsv11/data/locale/gl-ES.ini new file mode 100644 index 0000000..71ae7b0 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/gl-ES.ini @@ -0,0 +1,2 @@ +Profile="Perfil" + diff --git a/plugins/obs-qsv11/data/locale/hr-HR.ini b/plugins/obs-qsv11/data/locale/hr-HR.ini new file mode 100644 index 0000000..630ddf7 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/hr-HR.ini @@ -0,0 +1,12 @@ +TargetUsage="Ciljno zauzeće" +Bitrate="Protok" +MaxBitrate="Maksimalni protok" +RateControl="Kontrola protoka" +KeyframeIntervalSec="Interval ključnih frejmova (sekunde, 0=automatski)" +Profile="Profil" +AsyncDepth="Dubina asinhronizacije" +Accuracy="Preciznost" +Convergence="Konvergencija" +ICQQuality="ICQ kvalitet" +LookAheadDepth="Dubina predviđanja" + diff --git a/plugins/obs-qsv11/data/locale/hu-HU.ini b/plugins/obs-qsv11/data/locale/hu-HU.ini new file mode 100644 index 0000000..2a33d55 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/hu-HU.ini @@ -0,0 +1,12 @@ +TargetUsage="Felhasználási cél" +Bitrate="Bitráta" +MaxBitrate="Max bitráta" +RateControl="Sebesség Vezérlés" +KeyframeIntervalSec="Kulcsképkocka időköze (másodperc, 0=auto)" +Profile="Profil" +AsyncDepth="Aszinkron mélység" +Accuracy="Pontosság" +Convergence="Konvergencia" +ICQQuality="ICQ minőség" +LookAheadDepth="Lookahead mélység" + diff --git a/plugins/obs-qsv11/data/locale/ja-JP.ini b/plugins/obs-qsv11/data/locale/ja-JP.ini new file mode 100644 index 0000000..755d098 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/ja-JP.ini @@ -0,0 +1,12 @@ +TargetUsage="ターゲットの使用法" +Bitrate="ビットレート" +MaxBitrate="最大ビットレート" +RateControl="レート制御" +KeyframeIntervalSec="キーフレーム間隔 (秒, 0=自動)" +Profile="プロファイル" +AsyncDepth="非同期深度" +Accuracy="精度" +Convergence="収束" +ICQQuality="ICQ の品質" +LookAheadDepth="先読み深度" + diff --git a/plugins/obs-qsv11/data/locale/ko-KR.ini b/plugins/obs-qsv11/data/locale/ko-KR.ini new file mode 100644 index 0000000..c853fe4 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/ko-KR.ini @@ -0,0 +1,12 @@ +TargetUsage="목표 사용 수준" +Bitrate="비트레이트" +MaxBitrate="최대 비트레이트" +RateControl="데이터율 제어" +KeyframeIntervalSec="키프레임 간격 (초 단위, 0=자동)" +Profile="프로파일" +AsyncDepth="비동기(Async) 심도" +Accuracy="정확도" +Convergence="수렴도" +ICQQuality="ICQ 품질" +LookAheadDepth="미리보기(Lookahead) 심도" + diff --git a/plugins/obs-qsv11/data/locale/nl-NL.ini b/plugins/obs-qsv11/data/locale/nl-NL.ini new file mode 100644 index 0000000..e1df4d4 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/nl-NL.ini @@ -0,0 +1,12 @@ +TargetUsage="Doelgebruik" +Bitrate="Bitrate" +MaxBitrate="Maximale bitrate" +RateControl="Rate Control" +KeyframeIntervalSec="Tijd tussen keyframes (seconden, 0=auto)" +Profile="Profiel" +AsyncDepth="Async diepte" +Accuracy="Nauwkeurigheid" +Convergence="Convergentie" +ICQQuality="ICQ kwaliteit" +LookAheadDepth="Lookahead diepte" + diff --git a/plugins/obs-qsv11/data/locale/pl-PL.ini b/plugins/obs-qsv11/data/locale/pl-PL.ini new file mode 100644 index 0000000..312e984 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/pl-PL.ini @@ -0,0 +1,12 @@ +TargetUsage="Tryb enkodowania" +Bitrate="Przepływność (bitrate)" +MaxBitrate="Maksymalna przepływność (bitrate)" +RateControl="Kontrola przepływności" +KeyframeIntervalSec="Odstęp między klatkami kluczowymi (sekundy, 0=automatyczny)" +Profile="Profil" +AsyncDepth="Głębokość async" +Accuracy="Dokładność" +Convergence="Zbieżność" +ICQQuality="Jakość ICQ" +LookAheadDepth="Głębokość lookahead" + diff --git a/plugins/obs-qsv11/data/locale/ro-RO.ini b/plugins/obs-qsv11/data/locale/ro-RO.ini new file mode 100644 index 0000000..2b8e432 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/ro-RO.ini @@ -0,0 +1,4 @@ +Bitrate="Rată de biți" +MaxBitrate="Rată de biți maximă" +Profile="Profil" + diff --git a/plugins/obs-qsv11/data/locale/ru-RU.ini b/plugins/obs-qsv11/data/locale/ru-RU.ini new file mode 100644 index 0000000..2fc06ca --- /dev/null +++ b/plugins/obs-qsv11/data/locale/ru-RU.ini @@ -0,0 +1,12 @@ +TargetUsage="Целевое использование" +Bitrate="Битрейт" +MaxBitrate="Максимальный битрейт" +RateControl="Управление битрейтом" +KeyframeIntervalSec="Интервал ключевых кадров (сек, 0=авто)" +Profile="Профиль" +AsyncDepth="Сила асинхронизации" +Accuracy="Точность" +Convergence="Конвергенция" +ICQQuality="Качество ICQ" +LookAheadDepth="Глубина просмотра наперёд" + diff --git a/plugins/obs-qsv11/data/locale/sr-CS.ini b/plugins/obs-qsv11/data/locale/sr-CS.ini new file mode 100644 index 0000000..630ddf7 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/sr-CS.ini @@ -0,0 +1,12 @@ +TargetUsage="Ciljno zauzeće" +Bitrate="Protok" +MaxBitrate="Maksimalni protok" +RateControl="Kontrola protoka" +KeyframeIntervalSec="Interval ključnih frejmova (sekunde, 0=automatski)" +Profile="Profil" +AsyncDepth="Dubina asinhronizacije" +Accuracy="Preciznost" +Convergence="Konvergencija" +ICQQuality="ICQ kvalitet" +LookAheadDepth="Dubina predviđanja" + diff --git a/plugins/obs-qsv11/data/locale/sr-SP.ini b/plugins/obs-qsv11/data/locale/sr-SP.ini new file mode 100644 index 0000000..ff79d02 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/sr-SP.ini @@ -0,0 +1,12 @@ +TargetUsage="Циљно заузеће" +Bitrate="Проток" +MaxBitrate="Максимални проток" +RateControl="Контрола протока" +KeyframeIntervalSec="Интервал кључних фрејмова (секунде, 0=аутоматски)" +Profile="Профил" +AsyncDepth="Дубина асинхронизације" +Accuracy="Прецизност" +Convergence="Конвергенција" +ICQQuality="ICQ квалитет" +LookAheadDepth="Дубина предвиђања" + diff --git a/plugins/obs-qsv11/data/locale/sv-SE.ini b/plugins/obs-qsv11/data/locale/sv-SE.ini new file mode 100644 index 0000000..ba41d60 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/sv-SE.ini @@ -0,0 +1,6 @@ +TargetUsage="Målanvändning" +Bitrate="Bithastighet" +MaxBitrate="Maximal bithastighet" +Profile="Profil" +Accuracy="Noggrannhet" + diff --git a/plugins/obs-qsv11/data/locale/tr-TR.ini b/plugins/obs-qsv11/data/locale/tr-TR.ini new file mode 100644 index 0000000..ca6e147 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/tr-TR.ini @@ -0,0 +1,6 @@ +Bitrate="Bit hızı" +MaxBitrate="Maks Bit hızı" +KeyframeIntervalSec="Anahtarkare Aralığı (saniye, 0=otomatik)" +Profile="Profil" +Accuracy="Doğruluk" + diff --git a/plugins/obs-qsv11/data/locale/zh-CN.ini b/plugins/obs-qsv11/data/locale/zh-CN.ini new file mode 100644 index 0000000..26baaf9 --- /dev/null +++ b/plugins/obs-qsv11/data/locale/zh-CN.ini @@ -0,0 +1,12 @@ +TargetUsage="目标使用" +Bitrate="比特率" +MaxBitrate="最大比特率" +RateControl="速率控制" +KeyframeIntervalSec="关键帧间隔(秒, 0=自动)" +Profile="配置文件" +AsyncDepth="异步深度" +Accuracy="精确度" +Convergence="收敛性" +ICQQuality="ICQ 质量" +LookAheadDepth="预测先行深度" + diff --git a/plugins/obs-qsv11/data/locale/zh-TW.ini b/plugins/obs-qsv11/data/locale/zh-TW.ini new file mode 100644 index 0000000..2c163cc --- /dev/null +++ b/plugins/obs-qsv11/data/locale/zh-TW.ini @@ -0,0 +1,10 @@ +TargetUsage="目標使用" +Bitrate="位元率:" +MaxBitrate="最大位元率" +RateControl="速率控制" +KeyframeIntervalSec="關鍵影格間隔 (秒,0 = 自動)" +Profile="設定檔" +AsyncDepth="非同步深度" +Accuracy="精準度" +ICQQuality="ICQ 品質" + diff --git a/plugins/obs-qsv11/libmfx/include/mfx_critical_section.h b/plugins/obs-qsv11/libmfx/include/mfx_critical_section.h new file mode 100644 index 0000000..ee3abd2 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/mfx_critical_section.h @@ -0,0 +1,76 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2013 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_critical_section.h + +\* ****************************************************************************** */ + +#if !defined(__MFX_CRITICAL_SECTION_H) +#define __MFX_CRITICAL_SECTION_H + +#include + +namespace MFX +{ + +// Just set "critical section" instance to zero for initialization. +typedef volatile mfxL32 mfxCriticalSection; + +// Enter the global critical section. +void mfxEnterCriticalSection(mfxCriticalSection *pCSection); + +// Leave the global critical section. +void mfxLeaveCriticalSection(mfxCriticalSection *pCSection); + +class MFXAutomaticCriticalSection +{ +public: + // Constructor + explicit MFXAutomaticCriticalSection(mfxCriticalSection *pCSection) + { + m_pCSection = pCSection; + mfxEnterCriticalSection(m_pCSection); + } + + // Destructor + ~MFXAutomaticCriticalSection() + { + mfxLeaveCriticalSection(m_pCSection); + } + +protected: + // Pointer to a critical section + mfxCriticalSection *m_pCSection; + +private: + // unimplemented by intent to make this class non-copyable + MFXAutomaticCriticalSection(const MFXAutomaticCriticalSection &); + void operator=(const MFXAutomaticCriticalSection &); +}; + +} // namespace MFX + +#endif // __MFX_CRITICAL_SECTION_H diff --git a/plugins/obs-qsv11/libmfx/include/mfx_dispatcher.h b/plugins/obs-qsv11/libmfx/include/mfx_dispatcher.h new file mode 100644 index 0000000..9555c52 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/mfx_dispatcher.h @@ -0,0 +1,213 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2015 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_dispatcher.h + +\* ****************************************************************************** */ + +#if !defined(__MFX_DISPATCHER_H) +#define __MFX_DISPATCHER_H + +#include +#include +#include +#include +#include "mfx_dispatcher_defs.h" +#include "mfx_load_plugin.h" +#include "mfxenc.h" +#include "mfxpak.h" + + +mfxStatus MFXQueryVersion(mfxSession session, mfxVersion *version); + +enum +{ + // to avoid code changing versions are just inherited + // from the API header file. + DEFAULT_API_VERSION_MAJOR = MFX_VERSION_MAJOR, + DEFAULT_API_VERSION_MINOR = MFX_VERSION_MINOR +}; + +// +// declare functions' integer identifiers. +// + +#undef FUNCTION +#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \ + e##func_name, + +enum eFunc +{ + eMFXInit, + eMFXClose, + eMFXQueryIMPL, + eMFXQueryVersion, + eMFXJoinSession, + eMFXDisjoinSession, + eMFXCloneSession, + eMFXSetPriority, + eMFXGetPriority, + eMFXInitEx, +#include "mfx_exposed_functions_list.h" + eVideoFuncTotal +}; + +enum eAudioFunc +{ + eFakeAudioEnum = eMFXGetPriority, +#include "mfxaudio_exposed_functions_list.h" + eAudioFuncTotal +}; + +// declare max buffer length for regsitry key name +enum +{ + MFX_MAX_REGISTRY_KEY_NAME = 256 +}; + +// declare the maximum DLL path +enum +{ + MFX_MAX_DLL_PATH = 1024 +}; + +// declare library's implementation types +enum eMfxImplType +{ + MFX_LIB_HARDWARE = 0, + MFX_LIB_SOFTWARE = 1, + MFX_LIB_PSEUDO = 2, + + MFX_LIB_IMPL_TYPES +}; + +// declare dispatcher's version +enum +{ + MFX_DISPATCHER_VERSION_MAJOR = 1, + MFX_DISPATCHER_VERSION_MINOR = 2 +}; + +// declare a dispatcher's handle +struct MFX_DISP_HANDLE +{ + // Default constructor + MFX_DISP_HANDLE(const mfxVersion requiredVersion); + // Destructor + ~MFX_DISP_HANDLE(void); + + // Load the library's module + mfxStatus LoadSelectedDLL(const msdk_disp_char *pPath, eMfxImplType implType, mfxIMPL impl, mfxIMPL implInterface, mfxInitParam &par); + // Unload the library's module + mfxStatus UnLoadSelectedDLL(void); + + // Close the handle + mfxStatus Close(void); + + // NOTE: changing order of struct's members can make different version of + // dispatchers incompatible. Think of different modules (e.g. MFT filters) + // within a single application. + + // Library's implementation type (hardware or software) + eMfxImplType implType; + // Current library's implementation (exact implementation) + mfxIMPL impl; + // Current library's VIA interface + mfxIMPL implInterface; + // Dispatcher's version. If version is 1.1 or lower, then old dispatcher's + // architecture is used. Otherwise it means current dispatcher's version. + mfxVersion dispVersion; + // A real handle passed to a called function + mfxSession session; + // Required API version of session initialized + const mfxVersion apiVersion; + // Actual library API version + mfxVersion actualApiVersion; + // Status of loaded dll + mfxStatus loadStatus; + // Resgistry subkey name for windows version + msdk_disp_char subkeyName[MFX_MAX_REGISTRY_KEY_NAME]; + // Storage ID for windows version + int storageID; + + // Library's module handle + mfxModuleHandle hModule; + + MFX::MFXPluginStorage pluginHive; + MFX::MFXPluginFactory pluginFactory; + + // function call table + mfxFunctionPointer callTable[eVideoFuncTotal]; + mfxFunctionPointer callAudioTable[eAudioFuncTotal]; + +private: + // Declare assignment operator and copy constructor to prevent occasional assignment + MFX_DISP_HANDLE(const MFX_DISP_HANDLE &); + MFX_DISP_HANDLE & operator = (const MFX_DISP_HANDLE &); + +}; + +// declare comparison operator +inline +bool operator == (const mfxVersion &one, const mfxVersion &two) +{ + return (one.Version == two.Version); + +} // bool operator == (const mfxVersion &one, const mfxVersion &two) + +inline +bool operator < (const mfxVersion &one, const mfxVersion &two) +{ + return (one.Major == two.Major) && (one.Minor < two.Minor); + +} // bool operator < (const mfxVersion &one, const mfxVersion &two) + +inline +bool operator <= (const mfxVersion &one, const mfxVersion &two) +{ + return (one == two) || (one < two); +} // bool operator <= (const mfxVersion &one, const mfxVersion &two) + + +// +// declare a table with functions descriptions +// + +typedef +struct FUNCTION_DESCRIPTION +{ + // Literal function's name + const char *pName; + // API version when function appeared first time + mfxVersion apiVersion; +} FUNCTION_DESCRIPTION; + +extern const +FUNCTION_DESCRIPTION APIFunc[eVideoFuncTotal]; + +extern const +FUNCTION_DESCRIPTION APIAudioFunc[eAudioFuncTotal]; +#endif // __MFX_DISPATCHER_H diff --git a/plugins/obs-qsv11/libmfx/include/mfx_dispatcher_defs.h b/plugins/obs-qsv11/libmfx/include/mfx_dispatcher_defs.h new file mode 100644 index 0000000..b948403 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/mfx_dispatcher_defs.h @@ -0,0 +1,85 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2013-2015 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_dispatcher_defs.h + +\* ****************************************************************************** */ + +#pragma once +#include "mfxdefs.h" +#include + +#if defined(MFX_DISPATCHER_LOG) +#include +#include +#endif + +#if defined(_WIN32) || defined(_WIN64) +typedef wchar_t msdk_disp_char; +#define MSDK2WIDE(x) x + +#if _MSC_VER >= 1400 + #define msdk_disp_char_cpy_s(to, to_size, from) wcscpy_s(to,to_size, from) +#else + #define msdk_disp_char_cpy_s(to, to_size, from) wcscpy(to, from) +#endif + +#else +typedef char msdk_disp_char; +//#define msdk_disp_char_cpy_s(to, to_size, from) strcpy(to, from) + +inline void msdk_disp_char_cpy_s(char * to, size_t to_size, const char * from) +{ + size_t source_len = strlen(from); + size_t num_chars = (to_size - 1) < source_len ? (to_size - 1) : source_len; + strncpy(to, from, num_chars); + to[num_chars] = 0; +} + +#if defined(MFX_DISPATCHER_LOG) +#define MSDK2WIDE(x) getWideString(x).c_str() + +inline std::wstring getWideString(const char * string) +{ + size_t len = strlen(string); + return std::wstring(string, string + len); +} +#else + #define MSDK2WIDE(x) x +#endif + +#endif + +#ifdef __GNUC__ +#define sscanf_s sscanf +#define swscanf_s swscanf +#endif + + +// declare library module's handle +typedef void * mfxModuleHandle; + +typedef void (MFX_CDECL * mfxFunctionPointer)(void); diff --git a/plugins/obs-qsv11/libmfx/include/mfx_dispatcher_log.h b/plugins/obs-qsv11/libmfx/include/mfx_dispatcher_log.h new file mode 100644 index 0000000..7225c88 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/mfx_dispatcher_log.h @@ -0,0 +1,306 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_dispatcher_log.h + +\* ****************************************************************************** */ + +#if !defined(__MFX_DISPATCHER_LOG_H) +#define __MFX_DISPATCHER_LOG_H + +////////////////////////////////////////////////////////////////////////// +//dispatcher log (DL) level +#define DL_INFO 1 +#define DL_WRN 2 +#define DL_ERROR 4 +#define DL_LOADED_LIBRARY 8 +////////////////////////////////////////////////////////////////////////// +//opcodes used only in events +enum +{ + DL_EVENT_START = 1, + DL_EVENT_STOP, + DL_EVENT_MSG +}; +////////////////////////////////////////////////////////////////////////// +#define DL_SINK_NULL 0 +#define DL_SINK_PRINTF 1 +#define DL_SINK_IMsgHandler 2 + +#define MFXFOURCCTYPE() "%c%c%c%c" +#define ZERO_OR_SPACE(value) ((0==(value)) ? '0' : (value)) +#define MFXU32TOFOURCC(mfxu32)\ + ZERO_OR_SPACE((char)(mfxu32 & 0xFF)), \ + ZERO_OR_SPACE((char)((mfxu32 >> 8) & 0xFF)),\ + ZERO_OR_SPACE((char)((mfxu32 >> 16) & 0xFF)),\ + ZERO_OR_SPACE((char)((mfxu32 >> 24) & 0xFF)) + +#define MFXGUIDTYPE() "%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X" + +#define MFXGUIDTOHEX(guid)\ + (guid)->Data[0],\ + (guid)->Data[1],\ + (guid)->Data[2],\ + (guid)->Data[3],\ + (guid)->Data[4],\ + (guid)->Data[5],\ + (guid)->Data[6],\ + (guid)->Data[7],\ + (guid)->Data[8],\ + (guid)->Data[9],\ + (guid)->Data[10],\ + (guid)->Data[11],\ + (guid)->Data[12],\ + (guid)->Data[13],\ + (guid)->Data[14],\ + (guid)->Data[15] + +#if defined(MFX_DISPATCHER_LOG) + +//---------------------------setup section------------------------ +//using of formating instead of variadic macro with NULL end, +//leads to more flexibility in format, however constructing string +//with vsprintf_s is a time wasting +#define DISPATCHER_LOG_USE_FORMATING 1 + +//creates unique object, event guid registration, factories on heap +//heap reduce stack allocation and reduce reservation time at startup +//is a vital if mediasdk wont use +#define DISPATCHER_LOG_HEAP_SINGLETONES + +#if defined(_WIN32) || defined(_WIN64) +// guid for all dispatcher events +#define DISPATCHER_LOG_EVENT_GUID L"{EB0538CC-4FEE-484d-ACEE-1182E9F37A57}" + +//puts a sink into listeners list +//#define DISPATCHER_LOG_REGISTER_EVENT_PROVIDER + +//puts a sink into listeners list +//#define DISPATCHER_LOG_REGISTER_FILE_WRITER +#define DISPACTHER_LOG_FW_PATH "c:\\dispatcher.log" + +#endif // #if defined(_WIN32) || defined(_WIN64) + +#include +#include + +//callback interface for intercept logging messages +class IMsgHandler +{ +public: + virtual ~IMsgHandler(){} + virtual void Write(int level, int opcode, const char * msg, va_list argptr) = 0; +}; + +#if defined(_WIN32) || defined(_WIN64) +#if DISPATCHER_LOG_USE_FORMATING + + #define DISPATCHER_LOG(lvl, opcode, str)\ + {\ + DispatcherLogBracketsHelper wrt(lvl,opcode);\ + wrt.Write str;\ + } +#else + #define DISPATCHER_LOG_VA_ARGS(...) wrt.Write(__VA_ARGS__, NULL) + //WARNING: don't use types that occupy more that 4 bytes in memory + //WARNING: don't use %s in format specifier + #define DISPATCHER_LOG(lvl, opcode, str) \ + {\ + DispatcherLogBracketsHelper wrt(lvl, opcode);\ + DISPATCHER_LOG_VA_ARGS str;\ + } +#endif//DISPATCHER_LOG_USE_FORMATING + +#define DISPATCHER_LOG_OPERATION(operation) operation +#else +#define DISPATCHER_LOG(lvl, opcode, str) +#define DISPATCHER_LOG_OPERATION(operation) +#endif + +#define __name_from_line( name, line ) name ## line +#define _name_from_line( name , line) __name_from_line( name, line ) +#define name_from_line( name ) _name_from_line( name, __LINE__) + + +#define DISPATCHER_LOG_AUTO(lvl, msg)\ + DispatchLogBlockHelper name_from_line(__auto_log_)(lvl); name_from_line(__auto_log_).Write msg; + +#include +#include +#include +#include + +template +class DSSingleTone +{ +public: + template + inline static T & get(TParam1 par1) + { + T * pstored; + if (NULL == (pstored = store_or_load())) + { + return *store_or_load(new T(par1)); + } + return *pstored; + } + + inline static T & get() + { + T * pstored; + if (NULL == (pstored = store_or_load())) + { + return *store_or_load(new T()); + } + return *pstored; + } +private: + //if obj == NULL, then it load + //if obj != NULL then it store obj + inline static T * store_or_load(T * obj = NULL) + { + static std::auto_ptr instance; + if (NULL != obj) + { + instance.reset(obj); + } + return instance.get(); + } +}; + +class DispatchLog + : public DSSingleTone +{ + friend class DSSingleTone; + std::listm_Recepients; + int m_DispatcherLogSink; + +public: + //sets current sink + void SetSink(int nsink, IMsgHandler *pHandler); + void AttachSink(int nsink, IMsgHandler *pHandler); + void DetachSink(int nsink, IMsgHandler *pHandler); + void ExchangeSink(int nsink, IMsgHandler *pOld, IMsgHandler *pNew); + void DetachAllSinks(); + void Write(int level, int opcode, const char * msg, va_list argptr); + +protected: + DispatchLog(); +}; + +//allows to push arguments on the stack without declaring them as function parameters +struct DispatcherLogBracketsHelper +{ + int m_level; + int m_opcode; + DispatcherLogBracketsHelper(int level, int opcode) + :m_level(level) + ,m_opcode(opcode) + { + } + void Write(const char * str, ...); +} ; + +//auto log on ctor dtor +struct DispatchLogBlockHelper +{ + int m_level; + void Write(const char * str, ...); + DispatchLogBlockHelper (int level) + : m_level(level) + { + } + ~DispatchLogBlockHelper(); +}; + +//----utility sinks----- +#if defined(_WIN32) || defined(_WIN64) +#if defined(DISPATCHER_LOG_REGISTER_EVENT_PROVIDER) +class ETWHandlerFactory + : public DSSingleTone +{ + friend class DSSingleTone; + typedef std::map _storage_type; + _storage_type m_storage; + +public: + ~ETWHandlerFactory(); + IMsgHandler *GetSink(const wchar_t* sguid = DISPATCHER_LOG_EVENT_GUID); + +protected: + ETWHandlerFactory(){} +}; +#endif +#endif // #if defined(_WIN32) || defined(_WIN64) + +#if defined(DISPATCHER_LOG_REGISTER_FILE_WRITER) +class FileSink + : public DSSingleTone + , public IMsgHandler +{ + friend class DSSingleTone; +public: + virtual void Write(int level, int opcode, const char * msg, va_list argptr); + ~FileSink() + { + if (NULL != m_hdl) + fclose(m_hdl); + } +private: + FILE * m_hdl; + FileSink(const std::string & log_file) + { +#if defined(_WIN32) || defined(_WIN64) + fopen_s(&m_hdl, log_file.c_str(), "a"); +#else + m_hdl = fopen(log_file.c_str(), "a"); +#endif + } + +}; +#endif + +//-----utility functions +//since they are not called outside of macro we can define them here +std::string DispatcherLog_GetMFXImplString(int impl); +const char *DispatcherLog_GetMFXStatusString(int sts); + +#else // !defined(MFX_DISPATCHER_LOG) + + #define DISPATCHER_LOG(level, opcode, message) + #define DISPATCHER_LOG_AUTO(level, message) + #define DISPATCHER_LOG_OPERATION(operation) + +#endif// !defined(MFX_DISPATCHER_LOG) + + +#define DISPATCHER_LOG_INFO(msg) DISPATCHER_LOG(DL_INFO, DL_EVENT_MSG, msg) +#define DISPATCHER_LOG_WRN(msg) DISPATCHER_LOG(DL_WRN, DL_EVENT_MSG, msg) +#define DISPATCHER_LOG_ERROR(msg) DISPATCHER_LOG(DL_ERROR, DL_EVENT_MSG, msg) +#define DISPATCHER_LOG_LIBRARY(msg) DISPATCHER_LOG(DL_LOADED_LIBRARY, DL_EVENT_MSG, msg) +#define DISPATCHER_LOG_BLOCK(msg) DISPATCHER_LOG_AUTO(DL_INFO, msg) + +#endif // !defined(__MFX_DISPATCHER_LOG_H) diff --git a/plugins/obs-qsv11/libmfx/include/mfx_dxva2_device.h b/plugins/obs-qsv11/libmfx/include/mfx_dxva2_device.h new file mode 100644 index 0000000..cd5e219 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/mfx_dxva2_device.h @@ -0,0 +1,210 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2013 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_dxva2_device.h + +\* ****************************************************************************** */ + +#if !defined(__MFX_DXVA2_DEVICE_H) +#define __MFX_DXVA2_DEVICE_H + +#if defined(_WIN32) || defined(_WIN64) +#include +#endif // #if defined(_WIN32) || defined(_WIN64) + +#include + +#ifdef DXVA2DEVICE_LOG +#include +#define DXVA2DEVICE_TRACE(expr) printf expr; +#define DXVA2DEVICE_TRACE_OPERATION(expr) expr; +#else +#define DXVA2DEVICE_TRACE(expr) +#define DXVA2DEVICE_TRACE_OPERATION(expr) +#endif + +namespace MFX +{ + +class DXDevice +{ +public: + // Default constructor + DXDevice(void); + // Destructor + virtual + ~DXDevice(void) = 0; + + // Initialize device using DXGI 1.1 or VAAPI interface + virtual + bool Init(const mfxU32 adapterNum) = 0; + + // Obtain graphic card's parameter + mfxU32 GetVendorID(void) const; + mfxU32 GetDeviceID(void) const; + mfxU64 GetDriverVersion(void) const; + mfxU64 GetLUID(void) const; + + // Provide the number of available adapters + mfxU32 GetAdapterCount(void) const; + + // Close the object + virtual + void Close(void); + + // Load the required DLL module + void LoadDLLModule(const wchar_t *pModuleName); + +protected: + + // Free DLL module + void UnloadDLLModule(void); + +#if defined(_WIN32) || defined(_WIN64) + // Handle to the DLL library + HMODULE m_hModule; +#endif // #if defined(_WIN32) || defined(_WIN64) + + // Number of adapters available + mfxU32 m_numAdapters; + + // Vendor ID + mfxU32 m_vendorID; + // Device ID + mfxU32 m_deviceID; + // x.x.x.x each x of two bytes + mfxU64 m_driverVersion; + // LUID + mfxU64 m_luid; + +private: + // unimplemented by intent to make this class and its descendants non-copyable + DXDevice(const DXDevice &); + void operator=(const DXDevice &); +}; + +#if defined(_WIN32) || defined(_WIN64) +class D3D9Device : public DXDevice +{ +public: + // Default constructor + D3D9Device(void); + // Destructor + virtual + ~D3D9Device(void); + + // Initialize device using D3D v9 interface + virtual + bool Init(const mfxU32 adapterNum); + + // Close the object + virtual + void Close(void); + +protected: + + // Pointer to the D3D v9 interface + void *m_pD3D9; + // Pointer to the D3D v9 extended interface + void *m_pD3D9Ex; + +}; + +class DXGI1Device : public DXDevice +{ +public: + // Default constructor + DXGI1Device(void); + // Destructor + virtual + ~DXGI1Device(void); + + // Initialize device + virtual + bool Init(const mfxU32 adapterNum); + + // Close the object + virtual + void Close(void); + +protected: + + // Pointer to the DXGI1 factory + void *m_pDXGIFactory1; + // Pointer to the current DXGI1 adapter + void *m_pDXGIAdapter1; + +}; +#endif // #if defined(_WIN32) || defined(_WIN64) + +class DXVA2Device +{ +public: + // Default constructor + DXVA2Device(void); + // Destructor + ~DXVA2Device(void); + + // Initialize device using D3D v9 interface + bool InitD3D9(const mfxU32 adapterNum); + + // Initialize device using DXGI 1.1 interface + bool InitDXGI1(const mfxU32 adapterNum); + + // Obtain graphic card's parameter + mfxU32 GetVendorID(void) const; + mfxU32 GetDeviceID(void) const; + mfxU64 GetDriverVersion(void) const; + + // Provide the number of available adapters + mfxU32 GetAdapterCount(void) const; + + void Close(void); + +protected: + + // Get vendor & device IDs by alternative way (D3D9 in Remote Desktop sessions) + void UseAlternativeWay(const D3D9Device *pD3D9Device); + + // Number of adapters available + mfxU32 m_numAdapters; + + // Vendor ID + mfxU32 m_vendorID; + // Device ID + mfxU32 m_deviceID; + //x.x.x.x + mfxU64 m_driverVersion; + +private: + // unimplemented by intent to make this class non-copyable + DXVA2Device(const DXVA2Device &); + void operator=(const DXVA2Device &); +}; + +} // namespace MFX + +#endif // __MFX_DXVA2_DEVICE_H diff --git a/plugins/obs-qsv11/libmfx/include/mfx_exposed_functions_list.h b/plugins/obs-qsv11/libmfx/include/mfx_exposed_functions_list.h new file mode 100644 index 0000000..50cce3a --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/mfx_exposed_functions_list.h @@ -0,0 +1,142 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_exposed_functions_list.h + +\* ****************************************************************************** */ + +// +// WARNING: +// this file doesn't contain an include guard by intension. +// The file may be included into a source file many times. +// That is why this header doesn't contain any include directive. +// Please, do no try to fix it. +// + + + +// Use define API_VERSION to set the API of functions listed further +// When new functions are added new section with functions declarations must be started with updated define + +// +// API version 1.0 functions +// + +// API version where a function is added. Minor value should precedes the major value +#define API_VERSION {{0, 1}} + +// CORE interface functions +FUNCTION(mfxStatus, MFXVideoCORE_SetBufferAllocator, (mfxSession session, mfxBufferAllocator *allocator), (session, allocator)) +FUNCTION(mfxStatus, MFXVideoCORE_SetFrameAllocator, (mfxSession session, mfxFrameAllocator *allocator), (session, allocator)) +FUNCTION(mfxStatus, MFXVideoCORE_SetHandle, (mfxSession session, mfxHandleType type, mfxHDL hdl), (session, type, hdl)) +FUNCTION(mfxStatus, MFXVideoCORE_GetHandle, (mfxSession session, mfxHandleType type, mfxHDL *hdl), (session, type, hdl)) + +FUNCTION(mfxStatus, MFXVideoCORE_SyncOperation, (mfxSession session, mfxSyncPoint syncp, mfxU32 wait), (session, syncp, wait)) + +// ENCODE interface functions +FUNCTION(mfxStatus, MFXVideoENCODE_Query, (mfxSession session, mfxVideoParam *in, mfxVideoParam *out), (session, in, out)) +FUNCTION(mfxStatus, MFXVideoENCODE_QueryIOSurf, (mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request), (session, par, request)) +FUNCTION(mfxStatus, MFXVideoENCODE_Init, (mfxSession session, mfxVideoParam *par), (session, par)) +FUNCTION(mfxStatus, MFXVideoENCODE_Reset, (mfxSession session, mfxVideoParam *par), (session, par)) +FUNCTION(mfxStatus, MFXVideoENCODE_Close, (mfxSession session), (session)) + +FUNCTION(mfxStatus, MFXVideoENCODE_GetVideoParam, (mfxSession session, mfxVideoParam *par), (session, par)) +FUNCTION(mfxStatus, MFXVideoENCODE_GetEncodeStat, (mfxSession session, mfxEncodeStat *stat), (session, stat)) +FUNCTION(mfxStatus, MFXVideoENCODE_EncodeFrameAsync, (mfxSession session, mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxSyncPoint *syncp), (session, ctrl, surface, bs, syncp)) + +// DECODE interface functions +FUNCTION(mfxStatus, MFXVideoDECODE_Query, (mfxSession session, mfxVideoParam *in, mfxVideoParam *out), (session, in, out)) +FUNCTION(mfxStatus, MFXVideoDECODE_DecodeHeader, (mfxSession session, mfxBitstream *bs, mfxVideoParam *par), (session, bs, par)) +FUNCTION(mfxStatus, MFXVideoDECODE_QueryIOSurf, (mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request), (session, par, request)) +FUNCTION(mfxStatus, MFXVideoDECODE_Init, (mfxSession session, mfxVideoParam *par), (session, par)) +FUNCTION(mfxStatus, MFXVideoDECODE_Reset, (mfxSession session, mfxVideoParam *par), (session, par)) +FUNCTION(mfxStatus, MFXVideoDECODE_Close, (mfxSession session), (session)) + +FUNCTION(mfxStatus, MFXVideoDECODE_GetVideoParam, (mfxSession session, mfxVideoParam *par), (session, par)) +FUNCTION(mfxStatus, MFXVideoDECODE_GetDecodeStat, (mfxSession session, mfxDecodeStat *stat), (session, stat)) +FUNCTION(mfxStatus, MFXVideoDECODE_SetSkipMode, (mfxSession session, mfxSkipMode mode), (session, mode)) +FUNCTION(mfxStatus, MFXVideoDECODE_GetPayload, (mfxSession session, mfxU64 *ts, mfxPayload *payload), (session, ts, payload)) +FUNCTION(mfxStatus, MFXVideoDECODE_DecodeFrameAsync, (mfxSession session, mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxSyncPoint *syncp), (session, bs, surface_work, surface_out, syncp)) + +// VPP interface functions +FUNCTION(mfxStatus, MFXVideoVPP_Query, (mfxSession session, mfxVideoParam *in, mfxVideoParam *out), (session, in, out)) +FUNCTION(mfxStatus, MFXVideoVPP_QueryIOSurf, (mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request), (session, par, request)) +FUNCTION(mfxStatus, MFXVideoVPP_Init, (mfxSession session, mfxVideoParam *par), (session, par)) +FUNCTION(mfxStatus, MFXVideoVPP_Reset, (mfxSession session, mfxVideoParam *par), (session, par)) +FUNCTION(mfxStatus, MFXVideoVPP_Close, (mfxSession session), (session)) + +FUNCTION(mfxStatus, MFXVideoVPP_GetVideoParam, (mfxSession session, mfxVideoParam *par), (session, par)) +FUNCTION(mfxStatus, MFXVideoVPP_GetVPPStat, (mfxSession session, mfxVPPStat *stat), (session, stat)) +FUNCTION(mfxStatus, MFXVideoVPP_RunFrameVPPAsync, (mfxSession session, mfxFrameSurface1 *in, mfxFrameSurface1 *out, mfxExtVppAuxData *aux, mfxSyncPoint *syncp), (session, in, out, aux, syncp)) + +#undef API_VERSION + +// +// API version 1.1 functions +// + +#define API_VERSION {{1, 1}} + +FUNCTION(mfxStatus, MFXVideoUSER_Register, (mfxSession session, mfxU32 type, const mfxPlugin *par), (session, type, par)) +FUNCTION(mfxStatus, MFXVideoUSER_Unregister, (mfxSession session, mfxU32 type), (session, type)) +FUNCTION(mfxStatus, MFXVideoUSER_ProcessFrameAsync, (mfxSession session, const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp), (session, in, in_num, out, out_num, syncp)) + +#undef API_VERSION + +// +// API version 1.10 functions +// + +#define API_VERSION {{10, 1}} + +FUNCTION(mfxStatus, MFXVideoENC_Query,(mfxSession session, mfxVideoParam *in, mfxVideoParam *out), (session,in,out)) +FUNCTION(mfxStatus, MFXVideoENC_QueryIOSurf,(mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request), (session,par,request)) +FUNCTION(mfxStatus, MFXVideoENC_Init,(mfxSession session, mfxVideoParam *par), (session,par)) +FUNCTION(mfxStatus, MFXVideoENC_Reset,(mfxSession session, mfxVideoParam *par), (session,par)) +FUNCTION(mfxStatus, MFXVideoENC_Close,(mfxSession session),(session)) +FUNCTION(mfxStatus, MFXVideoENC_ProcessFrameAsync,(mfxSession session, mfxENCInput *in, mfxENCOutput *out, mfxSyncPoint *syncp),(session,in,out,syncp)) + +FUNCTION(mfxStatus, MFXVideoVPP_RunFrameVPPAsyncEx, (mfxSession session, mfxFrameSurface1 *in, mfxFrameSurface1 *work, mfxFrameSurface1 **out, mfxSyncPoint *syncp), (session, in, work, out, syncp)) + +#undef API_VERSION + +#define API_VERSION {{13, 1}} + +FUNCTION(mfxStatus, MFXVideoPAK_Query, (mfxSession session, mfxVideoParam *in, mfxVideoParam *out), (session, in, out)) +FUNCTION(mfxStatus, MFXVideoPAK_QueryIOSurf, (mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request), (session, par, request)) +FUNCTION(mfxStatus, MFXVideoPAK_Init, (mfxSession session, mfxVideoParam *par), (session, par)) +FUNCTION(mfxStatus, MFXVideoPAK_Reset, (mfxSession session, mfxVideoParam *par), (session, par)) +FUNCTION(mfxStatus, MFXVideoPAK_Close, (mfxSession session), (session)) +FUNCTION(mfxStatus, MFXVideoPAK_ProcessFrameAsync, (mfxSession session, mfxPAKInput *in, mfxPAKOutput *out, mfxSyncPoint *syncp), (session, in, out, syncp)) + +#undef API_VERSION + +#define API_VERSION {{14, 1}} + +// FUNCTION(mfxStatus, MFXInitEx, (mfxInitParam par, mfxSession session), (par, session)) +FUNCTION(mfxStatus, MFXDoWork, (mfxSession session), (session)) + +#undef API_VERSION \ No newline at end of file diff --git a/plugins/obs-qsv11/libmfx/include/mfx_library_iterator.h b/plugins/obs-qsv11/libmfx/include/mfx_library_iterator.h new file mode 100644 index 0000000..857881d --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/mfx_library_iterator.h @@ -0,0 +1,161 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_library_iterator.h + +\* ****************************************************************************** */ + +#if !defined(__MFX_LIBRARY_ITERATOR_H) +#define __MFX_LIBRARY_ITERATOR_H + + +#include +#include "mfx_win_reg_key.h" +#include "mfx_dispatcher.h" + +#if !defined(_WIN32) && !defined(_WIN64) +struct mfx_disp_adapters +{ + mfxU32 vendor_id; + mfxU32 device_id; +}; + +#ifndef __APPLE__ +#define MFX_SO_BASE_NAME_LEN 15 // sizeof("libmfxhw32-p.so") = 15 +#else + +#define MFX_SO_BASE_NAME_LEN 16 // sizeof("libmfxhw64.dylib") = 16 +#endif + +#define MFX_MIN_REAL_LIBNAME MFX_SO_BASE_NAME_LEN + 4 // sizeof("libmfxhw32-p.so.0.0") >= 19 +#define MFX_MAX_REAL_LIBNAME MFX_MIN_REAL_LIBNAME + 8 // sizeof("libmfxhw32-p.so..") <= 27, max(sizeof())=sizeof(0xFFFF) = sizeof(65535) = 5 + +struct mfx_libs +{ + char name[MFX_MAX_REAL_LIBNAME+1]; + mfxVersion version; +}; +#endif + +namespace MFX +{ + +// declare desired storage ID +#if defined(_WIN32) || defined(_WIN64) +enum +{ + MFX_UNKNOWN_KEY = -1, + MFX_CURRENT_USER_KEY = 0, + MFX_LOCAL_MACHINE_KEY = 1, + MFX_APP_FOLDER = 2, + + MFX_STORAGE_ID_FIRST = MFX_CURRENT_USER_KEY, + MFX_STORAGE_ID_LAST = MFX_LOCAL_MACHINE_KEY +}; +#else +enum +{ + MFX_UNKNOWN_KEY = -1, + MFX_STORAGE_ID_OPT = 0, // storage is: /opt/intel + MFX_APP_FOLDER = 1, + + MFX_STORAGE_ID_FIRST = MFX_STORAGE_ID_OPT, + MFX_STORAGE_ID_LAST = MFX_STORAGE_ID_OPT +}; +#endif + +// Try to initialize using given implementation type. Select appropriate type automatically in case of MFX_IMPL_VIA_ANY. +// Params: adapterNum - in, pImplInterface - in/out, pVendorID - out, pDeviceID - out +mfxStatus SelectImplementationType(const mfxU32 adapterNum, mfxIMPL *pImplInterface, mfxU32 *pVendorID, mfxU32 *pDeviceID); + +class MFXLibraryIterator +{ +public: + // Default constructor + MFXLibraryIterator(void); + // Destructor + ~MFXLibraryIterator(void); + + // Initialize the iterator + mfxStatus Init(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, int storageID); + + // Get the next library path + mfxStatus SelectDLLVersion(msdk_disp_char *pPath, size_t pathSize, + eMfxImplType *pImplType, mfxVersion minVersion); + + // Return interface type on which Intel adapter was found (if any): D3D9 or D3D11 + mfxIMPL GetImplementationType(); + + // Retrun registry subkey name on which dll was selected after sucesfull call to selectDllVesion + bool GetSubKeyName(msdk_disp_char *subKeyName, size_t length) const; + + int GetStorageID() const { return m_StorageID; } +protected: + + // Release the iterator + void Release(void); + + // Initialize the registry iterator + mfxStatus InitRegistry(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, int storageID); + // Initialize the app folder iterator + mfxStatus InitFolder(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, const msdk_disp_char * path); + + + eMfxImplType m_implType; // Required library implementation + mfxIMPL m_implInterface; // Required interface (D3D9, D3D11) + + mfxU32 m_vendorID; // (mfxU32) property of used graphic card + mfxU32 m_deviceID; // (mfxU32) property of used graphic card + bool m_bIsSubKeyValid; + wchar_t m_SubKeyName[MFX_MAX_REGISTRY_KEY_NAME]; // registry subkey for selected module loaded + int m_StorageID; + +#if defined(_WIN32) || defined(_WIN64) + WinRegKey m_baseRegKey; // (WinRegKey) main registry key + + mfxU32 m_lastLibIndex; // (mfxU32) index of previously returned library + mfxU32 m_lastLibMerit; // (mfxU32) merit of previously returned library +#else + int m_lastLibIndex; // (mfxU32) index of previously returned library + + mfxU32 m_adapters_num; + struct mfx_disp_adapters* m_adapters; + int m_selected_adapter; + mfxU32 m_libs_num; + struct mfx_libs* m_libs; +#endif // #if defined(_WIN32) || defined(_WIN64) + + msdk_disp_char m_path[260]; + +private: + // unimplemented by intent to make this class non-copyable + MFXLibraryIterator(const MFXLibraryIterator &); + void operator=(const MFXLibraryIterator &); +}; + +} // namespace MFX + +#endif // __MFX_LIBRARY_ITERATOR_H diff --git a/plugins/obs-qsv11/libmfx/include/mfx_load_dll.h b/plugins/obs-qsv11/libmfx/include/mfx_load_dll.h new file mode 100644 index 0000000..4a4cff5 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/mfx_load_dll.h @@ -0,0 +1,59 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_load_dll.h + +\* ****************************************************************************** */ + +#if !defined(__MFX_LOAD_DLL_H) +#define __MFX_LOAD_DLL_H + +#include "mfx_dispatcher.h" + +namespace MFX +{ + + + // + // declare DLL loading routines + // + + mfxStatus mfx_get_rt_dll_name(msdk_disp_char *pPath, size_t pathSize); + mfxStatus mfx_get_default_dll_name(msdk_disp_char *pPath, size_t pathSize, eMfxImplType implType); + mfxStatus mfx_get_default_plugin_name(msdk_disp_char *pPath, size_t pathSize, eMfxImplType implType); + + mfxStatus mfx_get_default_audio_dll_name(msdk_disp_char *pPath, size_t pathSize, eMfxImplType implType); + + + mfxModuleHandle mfx_dll_load(const msdk_disp_char *file_name); + //increments reference counter + mfxModuleHandle mfx_get_dll_handle(const msdk_disp_char *file_name); + mfxFunctionPointer mfx_dll_get_addr(mfxModuleHandle handle, const char *func_name); + bool mfx_dll_free(mfxModuleHandle handle); + +} // namespace MFX + +#endif // __MFX_LOAD_DLL_H diff --git a/plugins/obs-qsv11/libmfx/include/mfx_load_plugin.h b/plugins/obs-qsv11/libmfx/include/mfx_load_plugin.h new file mode 100644 index 0000000..d487ff4 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/mfx_load_plugin.h @@ -0,0 +1,93 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2013-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_load_plugin.h + +\* ****************************************************************************** */ + +#pragma once +#include "mfxplugin.h" +#include "mfx_dispatcher_defs.h" +#include "mfx_plugin_hive.h" + +namespace MFX +{ + typedef mfxStatus (MFX_CDECL *CreatePluginPtr_t)(mfxPluginUID uid, mfxPlugin* plugin); + + class PluginModule + { + mfxModuleHandle mHmodule; + CreatePluginPtr_t mCreatePluginPtr; + msdk_disp_char mPath[MAX_PLUGIN_PATH]; + + public: + PluginModule(); + PluginModule(const msdk_disp_char * path); + PluginModule(const PluginModule & that) ; + PluginModule & operator = (const PluginModule & that); + bool Create(mfxPluginUID guid, mfxPlugin&); + ~PluginModule(void); + + private: + void Tidy(); + }; + + class MFXPluginFactory { + struct FactoryRecord { + mfxPluginParam plgParams; + PluginModule module; + mfxPlugin plugin; + FactoryRecord () {} + FactoryRecord(const mfxPluginParam &plgParams, + PluginModule &module, + mfxPlugin plugin) + : plgParams(plgParams) + , module(module) + , plugin(plugin) { + } + }; + MFXVector mPlugins; + mfxU32 nPlugins; + mfxSession mSession; + public: + MFXPluginFactory(mfxSession session); + void Close(); + mfxStatus Create(const PluginDescriptionRecord &); + bool Destroy(const mfxPluginUID &); + + ~MFXPluginFactory(); + protected: + void DestroyPlugin( FactoryRecord & ); + static bool RunVerification( const mfxPlugin & plg, const PluginDescriptionRecord &dsc, mfxPluginParam &pluginParams ); + static bool VerifyEncoder( const mfxVideoCodecPlugin &videoCodec ); + static bool VerifyAudioEncoder( const mfxAudioCodecPlugin &audioCodec ); + static bool VerifyEnc( const mfxVideoCodecPlugin &videoEnc ); + static bool VerifyVpp( const mfxVideoCodecPlugin &videoCodec ); + static bool VerifyDecoder( const mfxVideoCodecPlugin &videoCodec ); + static bool VerifyAudioDecoder( const mfxAudioCodecPlugin &audioCodec ); + static bool VerifyCodecCommon( const mfxVideoCodecPlugin & Video ); + }; +} diff --git a/plugins/obs-qsv11/libmfx/include/mfx_plugin_hive.h b/plugins/obs-qsv11/libmfx/include/mfx_plugin_hive.h new file mode 100644 index 0000000..91bfa8e --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/mfx_plugin_hive.h @@ -0,0 +1,132 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2013-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_plugin_hive.h + +\* ****************************************************************************** */ + +#pragma once + +#include "mfx_dispatcher_defs.h" +#include "mfxplugin.h" +#include "mfx_win_reg_key.h" +#include "mfx_vector.h" +#include +#include +#include + +struct MFX_DISP_HANDLE; + +namespace MFX { + + enum + { + MAX_PLUGIN_PATH = 4096 + }; + + enum + { + MAX_PLUGIN_NAME = 4096 + }; + + inline bool operator == (const mfxPluginUID &lhs, const mfxPluginUID & rhs) + { + return !memcmp(lhs.Data, rhs.Data, sizeof(mfxPluginUID)); + } + + inline bool operator != (const mfxPluginUID &lhs, const mfxPluginUID & rhs) + { + return !(lhs == rhs); + } +#ifdef _WIN32 + //warning C4351: new behavior: elements of array 'MFX::PluginDescriptionRecord::sName' will be default initialized + #pragma warning (disable: 4351) +#endif + class PluginDescriptionRecord : public mfxPluginParam + { + public: + msdk_disp_char sPath[MAX_PLUGIN_PATH]; + char sName[MAX_PLUGIN_NAME]; + //used for FS plugins that has poor description + bool onlyVersionRegistered; + bool Default; + PluginDescriptionRecord() + : mfxPluginParam() + , sPath() + , sName() + , onlyVersionRegistered() + , Default() + { + } + }; + + typedef MFXVector MFXPluginStorage; + + class MFXPluginStorageBase : public MFXPluginStorage + { + protected: + mfxVersion mCurrentAPIVersion; + protected: + MFXPluginStorageBase(mfxVersion currentAPIVersion) + : mCurrentAPIVersion(currentAPIVersion) + { + } + void ConvertAPIVersion( mfxU32 APIVersion, PluginDescriptionRecord &descriptionRecord) const + { + descriptionRecord.APIVersion.Minor = static_cast (APIVersion & 0x0ff); + descriptionRecord.APIVersion.Major = static_cast (APIVersion >> 8); + } + }; + + //populated from registry + class MFXPluginsInHive : public MFXPluginStorageBase + { + public: + MFXPluginsInHive(int mfxStorageID, const msdk_disp_char *msdkLibSubKey, mfxVersion currentAPIVersion); + }; + + //plugins are loaded from FS close to executable + class MFXPluginsInFS : public MFXPluginStorageBase + { + bool mIsVersionParsed; + bool mIsAPIVersionParsed; + public: + MFXPluginsInFS(mfxVersion currentAPIVersion); + private: + bool ParseFile(FILE * f, PluginDescriptionRecord & des); + bool ParseKVPair( msdk_disp_char *key, msdk_disp_char * value, PluginDescriptionRecord & des); + }; + + + //plugins are loaded from FS close to Runtime library + class MFXDefaultPlugins : public MFXPluginStorageBase + { + public: + MFXDefaultPlugins(mfxVersion currentAPIVersion, MFX_DISP_HANDLE * hdl, int implType); + private: + }; + +} diff --git a/plugins/obs-qsv11/libmfx/include/mfx_vector.h b/plugins/obs-qsv11/libmfx/include/mfx_vector.h new file mode 100644 index 0000000..65af859 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/mfx_vector.h @@ -0,0 +1,220 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2013-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_vector.h + +\* ****************************************************************************** */ + +#pragma once +#include "mfxstructures.h" +#include + +namespace MFX +{ + template + class iterator_tmpl + { + template friend class MFXVector; + mfxU32 mIndex; + T* mRecords; + iterator_tmpl(mfxU32 index , T * records) + : mIndex (index) + , mRecords(records) + {} + public: + iterator_tmpl() + : mIndex () + , mRecords() + {} + bool operator ==(const iterator_tmpl & that )const + { + return mIndex == that.mIndex; + } + bool operator !=(const iterator_tmpl & that )const + { + return mIndex != that.mIndex; + } + mfxU32 operator - (const iterator_tmpl &that) const + { + return mIndex - that.mIndex; + } + iterator_tmpl & operator ++() + { + mIndex++; + return * this; + } + iterator_tmpl & operator ++(int) + { + mIndex++; + return * this; + } + T & operator *() + { + return mRecords[mIndex]; + } + T * operator ->() + { + return mRecords + mIndex; + } + }; + + class MFXVectorRangeError : public std::exception + { + }; + + template + class MFXVector + { + T* mRecords; + mfxU32 mNrecords; + public: + MFXVector() + : mRecords() + , mNrecords() + {} + MFXVector(const MFXVector & rhs) + : mRecords() + , mNrecords() + { + insert(end(), rhs.begin(), rhs.end()); + } + MFXVector & operator = (const MFXVector & rhs) + { + if (this != &rhs) + { + clear(); + insert(end(), rhs.begin(), rhs.end()); + } + return *this; + } + virtual ~MFXVector () + { + clear(); + } + typedef iterator_tmpl iterator; + + iterator begin() const + { + return iterator(0u, mRecords); + } + iterator end() const + { + return iterator(mNrecords, mRecords); + } + void insert(iterator where, iterator beg_iter, iterator end_iter) + { + mfxU32 elementsToInsert = (end_iter - beg_iter); + if (!elementsToInsert) + { + return; + } + if (where.mIndex > mNrecords) + { + throw MFXVectorRangeError(); + } + + T *newRecords = new T[mNrecords + elementsToInsert](); + mfxU32 i = 0; + + // save left + for (; i < where.mIndex; i++) + { + newRecords[i] = mRecords[i]; + } + // insert + for (; beg_iter != end_iter; beg_iter++, i++) + { + newRecords[i] = *beg_iter; + } + + //save right + for (; i < mNrecords + elementsToInsert; i++) + { + newRecords[i] = mRecords[i - elementsToInsert]; + } + + delete [] mRecords; + + mRecords = newRecords; + mNrecords = i; + } + T& operator [] (mfxU32 idx) + { + return mRecords[idx]; + } + void push_back(const T& obj) + { + T *newRecords = new T[mNrecords + 1](); + mfxU32 i = 0; + for (; i = mNrecords) + { + throw MFXVectorRangeError(); + } + mNrecords--; + mfxU32 i = at.mIndex; + for (; i != mNrecords; i++) + { + mRecords[i] = mRecords[i+1]; + } + //destroy last element + mRecords[i] = T(); + } + void resize(mfxU32 nSize) + { + T * newRecords = new T[nSize](); + for (mfxU32 i = 0; i +#include "mfxplugin.h" +#include "mfx_dispatcher_log.h" + +namespace MFX { + +template struct RegKey{}; +template<> struct RegKey{enum {type = REG_DWORD};}; +template<> struct RegKey{enum {type = REG_DWORD};}; +template<> struct RegKey{enum {type = REG_BINARY};}; +template<> struct RegKey{enum {type = REG_DWORD};}; +template<> struct RegKey{enum {type = REG_SZ};}; +template<> struct RegKey{enum {type = REG_SZ};}; + + +class WinRegKey +{ +public: + // Default constructor + WinRegKey(void); + // Destructor + ~WinRegKey(void); + + // Open a registry key + bool Open(HKEY hRootKey, const wchar_t *pSubKey, REGSAM samDesired); + bool Open(WinRegKey &rootKey, const wchar_t *pSubKey, REGSAM samDesired); + + // Query value + bool QueryInfo(LPDWORD lpcSubkeys); + + bool QueryValueSize(const wchar_t *pValueName, DWORD type, LPDWORD pcbData); + bool Query(const wchar_t *pValueName, DWORD type, LPBYTE pData, LPDWORD pcbData); + + bool Query(const wchar_t *pValueName, wchar_t *pData, mfxU32 &nData) { + DWORD dw = (DWORD)nData; + if (!Query(pValueName, RegKey::type, (LPBYTE)pData, &dw)){ + return false; + } + nData = dw; + return true; + } + + // Enumerate value names + bool EnumValue(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName, LPDWORD pType); + bool EnumKey(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName); + +protected: + + // Release the object + void Release(void); + + HKEY m_hKey; // (HKEY) handle to the opened key + +private: + // unimplemented by intent to make this class non-copyable + WinRegKey(const WinRegKey &); + void operator=(const WinRegKey &); + +}; + + +template +inline bool QueryKey(WinRegKey & key, const wchar_t *pValueName, T &data ) { + DWORD size = sizeof(data); + return key.Query(pValueName, RegKey::type, (LPBYTE) &data, &size); +} + +template<> +inline bool QueryKey(WinRegKey & key, const wchar_t *pValueName, bool &data ) { + mfxU32 value = 0; + bool bRes = QueryKey(key, pValueName, value); + data = (1 == value); + return bRes; +} + + +} // namespace MFX + +#endif // #if defined(_WIN32) || defined(_WIN64) + +#endif // __MFX_WIN_REG_KEY_H diff --git a/plugins/obs-qsv11/libmfx/include/mfxaudio_exposed_functions_list.h b/plugins/obs-qsv11/libmfx/include/mfxaudio_exposed_functions_list.h new file mode 100644 index 0000000..aa12408 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/mfxaudio_exposed_functions_list.h @@ -0,0 +1,81 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2013-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfxaudio_exposed_function_list.h + +\* ****************************************************************************** */ + +// +// WARNING: +// this file doesn't contain an include guard by intension. +// The file may be included into a source file many times. +// That is why this header doesn't contain any include directive. +// Please, do no try to fix it. +// + +// +// API version 1.8 functions +// + +// Minor value should precedes the major value +#define API_VERSION {{8, 1}} + +// CORE interface functions +FUNCTION(mfxStatus, MFXAudioCORE_SyncOperation, (mfxSession session, mfxSyncPoint syncp, mfxU32 wait), (session, syncp, wait)) + +// ENCODE interface functions +FUNCTION(mfxStatus, MFXAudioENCODE_Query, (mfxSession session, mfxAudioParam *in, mfxAudioParam *out), (session, in, out)) +FUNCTION(mfxStatus, MFXAudioENCODE_QueryIOSize, (mfxSession session, mfxAudioParam *par, mfxAudioAllocRequest *request), (session, par, request)) +FUNCTION(mfxStatus, MFXAudioENCODE_Init, (mfxSession session, mfxAudioParam *par), (session, par)) +FUNCTION(mfxStatus, MFXAudioENCODE_Reset, (mfxSession session, mfxAudioParam *par), (session, par)) +FUNCTION(mfxStatus, MFXAudioENCODE_Close, (mfxSession session), (session)) +FUNCTION(mfxStatus, MFXAudioENCODE_GetAudioParam, (mfxSession session, mfxAudioParam *par), (session, par)) +FUNCTION(mfxStatus, MFXAudioENCODE_EncodeFrameAsync, (mfxSession session, mfxAudioFrame *frame, mfxBitstream *buffer_out, mfxSyncPoint *syncp), (session, frame, buffer_out, syncp)) + +// DECODE interface functions +FUNCTION(mfxStatus, MFXAudioDECODE_Query, (mfxSession session, mfxAudioParam *in, mfxAudioParam *out), (session, in, out)) +FUNCTION(mfxStatus, MFXAudioDECODE_DecodeHeader, (mfxSession session, mfxBitstream *bs, mfxAudioParam *par), (session, bs, par)) +FUNCTION(mfxStatus, MFXAudioDECODE_Init, (mfxSession session, mfxAudioParam *par), (session, par)) +FUNCTION(mfxStatus, MFXAudioDECODE_Reset, (mfxSession session, mfxAudioParam *par), (session, par)) +FUNCTION(mfxStatus, MFXAudioDECODE_Close, (mfxSession session), (session)) +FUNCTION(mfxStatus, MFXAudioDECODE_QueryIOSize, (mfxSession session, mfxAudioParam *par, mfxAudioAllocRequest *request), (session, par, request)) +FUNCTION(mfxStatus, MFXAudioDECODE_GetAudioParam, (mfxSession session, mfxAudioParam *par), (session, par)) +FUNCTION(mfxStatus, MFXAudioDECODE_DecodeFrameAsync, (mfxSession session, mfxBitstream *bs, mfxAudioFrame *frame_out, mfxSyncPoint *syncp), (session, bs, frame_out, syncp)) + +#undef API_VERSION + +// +// API version 1.9 functions +// + +#define API_VERSION {{9, 1}} + +FUNCTION(mfxStatus, MFXAudioUSER_Register, (mfxSession session, mfxU32 type, const mfxPlugin *par), (session, type, par)) +FUNCTION(mfxStatus, MFXAudioUSER_Unregister, (mfxSession session, mfxU32 type), (session, type)) +FUNCTION(mfxStatus, MFXAudioUSER_ProcessFrameAsync, (mfxSession session, const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp), (session, in, in_num, out, out_num, syncp)) + + +#undef API_VERSION diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxastructures.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxastructures.h new file mode 100644 index 0000000..6157aee --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxastructures.h @@ -0,0 +1,172 @@ +/******************************************************************************* + +Copyright (C) 2013 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfxastructures.h + +*******************************************************************************/ +#ifndef __MFXASTRUCTURES_H__ +#define __MFXASTRUCTURES_H__ +#include "mfxcommon.h" + +#if !defined (__GNUC__) +#pragma warning(disable: 4201) +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* CodecId */ +enum { + MFX_CODEC_AAC =MFX_MAKEFOURCC('A','A','C',' '), + MFX_CODEC_MP3 =MFX_MAKEFOURCC('M','P','3',' ') +}; + +enum { + /* AAC Profiles & Levels */ + MFX_PROFILE_AAC_LC =2, + MFX_PROFILE_AAC_LTP =4, + MFX_PROFILE_AAC_MAIN =1, + MFX_PROFILE_AAC_SSR =3, + MFX_PROFILE_AAC_HE =5, + MFX_PROFILE_AAC_ALS =0x20, + MFX_PROFILE_AAC_BSAC =22, + MFX_PROFILE_AAC_PS =29, + + /*MPEG AUDIO*/ + MFX_AUDIO_MPEG1_LAYER1 =0x00000110, + MFX_AUDIO_MPEG1_LAYER2 =0x00000120, + MFX_AUDIO_MPEG1_LAYER3 =0x00000140, + MFX_AUDIO_MPEG2_LAYER1 =0x00000210, + MFX_AUDIO_MPEG2_LAYER2 =0x00000220, + MFX_AUDIO_MPEG2_LAYER3 =0x00000240 +}; + +/*AAC HE decoder down sampling*/ +enum { + MFX_AUDIO_AAC_HE_DWNSMPL_OFF=0, + MFX_AUDIO_AAC_HE_DWNSMPL_ON= 1 +}; + +/* AAC decoder support of PS */ +enum { + MFX_AUDIO_AAC_PS_DISABLE= 0, + MFX_AUDIO_AAC_PS_PARSER= 1, + MFX_AUDIO_AAC_PS_ENABLE_BL= 111, + MFX_AUDIO_AAC_PS_ENABLE_UR= 411 +}; + +/*AAC decoder SBR support*/ +enum { + MFX_AUDIO_AAC_SBR_DISABLE = 0, + MFX_AUDIO_AAC_SBR_ENABLE= 1, + MFX_AUDIO_AAC_SBR_UNDEF= 2 +}; + +/*AAC header type*/ +enum{ + MFX_AUDIO_AAC_ADTS= 1, + MFX_AUDIO_AAC_ADIF= 2, + MFX_AUDIO_AAC_RAW= 3, +}; + +/*AAC encoder stereo mode*/ +enum +{ + MFX_AUDIO_AAC_MONO= 0, + MFX_AUDIO_AAC_LR_STEREO= 1, + MFX_AUDIO_AAC_MS_STEREO= 2, + MFX_AUDIO_AAC_JOINT_STEREO= 3 +}; + +typedef struct { + mfxU32 CodecId; + mfxU16 CodecProfile; + mfxU16 CodecLevel; + + mfxU32 Bitrate; + mfxU32 SampleFrequency; + mfxU16 NumChannel; + mfxU16 BitPerSample; + + mfxU16 reserved1[22]; + + union { + struct { /* AAC Decoding Options */ + mfxU16 FlagPSSupportLev; + mfxU16 Layer; + mfxU16 AACHeaderDataSize; + mfxU8 AACHeaderData[64]; + }; + struct { /* AAC Encoding Options */ + mfxU16 OutputFormat; + mfxU16 StereoMode; + mfxU16 reserved2[61]; + }; + }; +} mfxAudioInfoMFX; + +typedef struct { + mfxU16 AsyncDepth; + mfxU16 Protected; + mfxU16 reserved[14]; + + mfxAudioInfoMFX mfx; + mfxExtBuffer** ExtParam; + mfxU16 NumExtParam; +} mfxAudioParam; + +typedef struct { + mfxU32 SuggestedInputSize; + mfxU32 SuggestedOutputSize; + mfxU32 reserved[6]; +} mfxAudioAllocRequest; + +typedef struct { + mfxU64 TimeStamp; /* 1/90KHz */ + mfxU16 Locked; + mfxU16 NumChannels; + mfxU32 SampleFrequency; + mfxU16 BitPerSample; + mfxU16 reserved1[7]; + + mfxU8* Data; + mfxU32 reserved2; + mfxU32 DataLength; + mfxU32 MaxLength; + + mfxU32 NumExtParam; + mfxExtBuffer **ExtParam; +} mfxAudioFrame; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + + diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxaudio++.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxaudio++.h new file mode 100644 index 0000000..52760a8 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxaudio++.h @@ -0,0 +1,113 @@ +/******************************************************************************* + +Copyright (C) 2013 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +File Name: mfxaudio++.h + + +*******************************************************************************/ +#ifndef __MFXAUDIOPLUSPLUS_H +#define __MFXAUDIOPLUSPLUS_H + +#include "mfxaudio.h" + +class MFXAudioSession +{ +public: + MFXAudioSession(void) { m_session = (mfxSession) 0; } + virtual ~MFXAudioSession(void) { Close(); } + + virtual mfxStatus Init(mfxIMPL impl, mfxVersion *ver) { return MFXInit(impl, ver, &m_session); } + virtual mfxStatus Close(void) + { + mfxStatus mfxRes; + mfxRes = MFXClose(m_session); m_session = (mfxSession) 0; + return mfxRes; + } + + virtual mfxStatus QueryIMPL(mfxIMPL *impl) { return MFXQueryIMPL(m_session, impl); } + virtual mfxStatus QueryVersion(mfxVersion *version) { return MFXQueryVersion(m_session, version); } + + virtual mfxStatus JoinSession(mfxSession child_session) { return MFXJoinSession(m_session, child_session);} + virtual mfxStatus DisjoinSession( ) { return MFXDisjoinSession(m_session);} + virtual mfxStatus CloneSession( mfxSession *clone) { return MFXCloneSession(m_session, clone);} + virtual mfxStatus SetPriority( mfxPriority priority) { return MFXSetPriority(m_session, priority);} + virtual mfxStatus GetPriority( mfxPriority *priority) { return MFXGetPriority(m_session, priority);} + + virtual mfxStatus SyncOperation(mfxSyncPoint syncp, mfxU32 wait) { return MFXAudioCORE_SyncOperation(m_session, syncp, wait); } + + virtual operator mfxSession (void) { return m_session; } + +protected: + + mfxSession m_session; // (mfxSession) handle to the owning session +}; + + +class MFXAudioDECODE +{ +public: + + MFXAudioDECODE(mfxSession session) { m_session = session; } + virtual ~MFXAudioDECODE(void) { Close(); } + + virtual mfxStatus Query(mfxAudioParam *in, mfxAudioParam *out) { return MFXAudioDECODE_Query(m_session, in, out); } + virtual mfxStatus DecodeHeader(mfxBitstream *bs, mfxAudioParam *par) { return MFXAudioDECODE_DecodeHeader(m_session, bs, par); } + virtual mfxStatus QueryIOSize(mfxAudioParam *par, mfxAudioAllocRequest *request) { return MFXAudioDECODE_QueryIOSize(m_session, par, request); } + virtual mfxStatus Init(mfxAudioParam *par) { return MFXAudioDECODE_Init(m_session, par); } + virtual mfxStatus Reset(mfxAudioParam *par) { return MFXAudioDECODE_Reset(m_session, par); } + virtual mfxStatus Close(void) { return MFXAudioDECODE_Close(m_session); } + virtual mfxStatus GetAudioParam(mfxAudioParam *par) { return MFXAudioDECODE_GetAudioParam(m_session, par); } + virtual mfxStatus DecodeFrameAsync(mfxBitstream *bs, mfxAudioFrame *frame, mfxSyncPoint *syncp) { return MFXAudioDECODE_DecodeFrameAsync(m_session, bs, frame, syncp); } + + +protected: + + mfxSession m_session; // (mfxSession) handle to the owning session +}; + + +class MFXAudioENCODE +{ +public: + + MFXAudioENCODE(mfxSession session) { m_session = session; } + virtual ~MFXAudioENCODE(void) { Close(); } + + virtual mfxStatus Query(mfxAudioParam *in, mfxAudioParam *out) { return MFXAudioENCODE_Query(m_session, in, out); } + virtual mfxStatus QueryIOSize(mfxAudioParam *par, mfxAudioAllocRequest *request) { return MFXAudioENCODE_QueryIOSize(m_session, par, request); } + virtual mfxStatus Init(mfxAudioParam *par) { return MFXAudioENCODE_Init(m_session, par); } + virtual mfxStatus Reset(mfxAudioParam *par) { return MFXAudioENCODE_Reset(m_session, par); } + virtual mfxStatus Close(void) { return MFXAudioENCODE_Close(m_session); } + virtual mfxStatus GetAudioParam(mfxAudioParam *par) { return MFXAudioENCODE_GetAudioParam(m_session, par); } + virtual mfxStatus EncodeFrameAsync(mfxAudioFrame *frame, mfxBitstream *buffer_out, mfxSyncPoint *syncp) { return MFXAudioENCODE_EncodeFrameAsync(m_session, frame, buffer_out, syncp); } + +protected: + + mfxSession m_session; // (mfxSession) handle to the owning session +}; + +#endif \ No newline at end of file diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxaudio.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxaudio.h new file mode 100644 index 0000000..985da94 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxaudio.h @@ -0,0 +1,70 @@ +/******************************************************************************* + +Copyright (C) 2013 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfxaudio.h + +*******************************************************************************/ + +#ifndef __MFXAUDIO_H__ +#define __MFXAUDIO_H__ +#include "mfxsession.h" +#include "mfxastructures.h" + +#define MFX_AUDIO_VERSION_MAJOR 1 +#define MFX_AUDIO_VERSION_MINOR 15 + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* AudioCORE */ +mfxStatus MFX_CDECL MFXAudioCORE_SyncOperation(mfxSession session, mfxSyncPoint syncp, mfxU32 wait); + +/* AudioENCODE */ +mfxStatus MFX_CDECL MFXAudioENCODE_Query(mfxSession session, mfxAudioParam *in, mfxAudioParam *out); +mfxStatus MFX_CDECL MFXAudioENCODE_QueryIOSize(mfxSession session, mfxAudioParam *par, mfxAudioAllocRequest *request); +mfxStatus MFX_CDECL MFXAudioENCODE_Init(mfxSession session, mfxAudioParam *par); +mfxStatus MFX_CDECL MFXAudioENCODE_Reset(mfxSession session, mfxAudioParam *par); +mfxStatus MFX_CDECL MFXAudioENCODE_Close(mfxSession session); +mfxStatus MFX_CDECL MFXAudioENCODE_GetAudioParam(mfxSession session, mfxAudioParam *par); +mfxStatus MFX_CDECL MFXAudioENCODE_EncodeFrameAsync(mfxSession session, mfxAudioFrame *frame, mfxBitstream *bs, mfxSyncPoint *syncp); + +/* AudioDECODE */ +mfxStatus MFX_CDECL MFXAudioDECODE_Query(mfxSession session, mfxAudioParam *in, mfxAudioParam *out); +mfxStatus MFX_CDECL MFXAudioDECODE_DecodeHeader(mfxSession session, mfxBitstream *bs, mfxAudioParam* par); +mfxStatus MFX_CDECL MFXAudioDECODE_Init(mfxSession session, mfxAudioParam *par); +mfxStatus MFX_CDECL MFXAudioDECODE_Reset(mfxSession session, mfxAudioParam *par); +mfxStatus MFX_CDECL MFXAudioDECODE_Close(mfxSession session); +mfxStatus MFX_CDECL MFXAudioDECODE_QueryIOSize(mfxSession session, mfxAudioParam *par, mfxAudioAllocRequest *request); +mfxStatus MFX_CDECL MFXAudioDECODE_GetAudioParam(mfxSession session, mfxAudioParam *par); +mfxStatus MFX_CDECL MFXAudioDECODE_DecodeFrameAsync(mfxSession session, mfxBitstream *bs, mfxAudioFrame *frame, mfxSyncPoint *syncp); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxcommon.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxcommon.h new file mode 100644 index 0000000..a9c6e4a --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxcommon.h @@ -0,0 +1,159 @@ +/******************************************************************************* + +Copyright (C) 2013-2015 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfxcommon.h + +*******************************************************************************/ +#ifndef __MFXCOMMON_H__ +#define __MFXCOMMON_H__ +#include "mfxdefs.h" + +#if !defined (__GNUC__) +#pragma warning(disable: 4201) +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#define MFX_MAKEFOURCC(A,B,C,D) ((((int)A))+(((int)B)<<8)+(((int)C)<<16)+(((int)D)<<24)) + +/* Extended Configuration Header Structure */ +typedef struct { + mfxU32 BufferId; + mfxU32 BufferSz; +} mfxExtBuffer; + +/* Library initialization and deinitialization */ +typedef mfxI32 mfxIMPL; +#define MFX_IMPL_BASETYPE(x) (0x00ff & (x)) + +enum { + MFX_IMPL_AUTO = 0x0000, /* Auto Selection/In or Not Supported/Out */ + MFX_IMPL_SOFTWARE = 0x0001, /* Pure Software Implementation */ + MFX_IMPL_HARDWARE = 0x0002, /* Hardware Accelerated Implementation (default device) */ + MFX_IMPL_AUTO_ANY = 0x0003, /* Auto selection of any hardware/software implementation */ + MFX_IMPL_HARDWARE_ANY = 0x0004, /* Auto selection of any hardware implementation */ + MFX_IMPL_HARDWARE2 = 0x0005, /* Hardware accelerated implementation (2nd device) */ + MFX_IMPL_HARDWARE3 = 0x0006, /* Hardware accelerated implementation (3rd device) */ + MFX_IMPL_HARDWARE4 = 0x0007, /* Hardware accelerated implementation (4th device) */ + MFX_IMPL_RUNTIME = 0x0008, + + MFX_IMPL_VIA_ANY = 0x0100, + MFX_IMPL_VIA_D3D9 = 0x0200, + MFX_IMPL_VIA_D3D11 = 0x0300, + MFX_IMPL_VIA_VAAPI = 0x0400, + + MFX_IMPL_AUDIO = 0x8000, + + MFX_IMPL_UNSUPPORTED = 0x0000 /* One of the MFXQueryIMPL returns */ +}; + +/* Version Info */ +typedef union { + struct { + mfxU16 Minor; + mfxU16 Major; + }; + mfxU32 Version; +} mfxVersion; + +/* session priority */ +typedef enum +{ + MFX_PRIORITY_LOW = 0, + MFX_PRIORITY_NORMAL = 1, + MFX_PRIORITY_HIGH = 2 + +} mfxPriority; + +typedef struct _mfxEncryptedData mfxEncryptedData; +typedef struct { + union { + struct { + mfxEncryptedData* EncryptedData; + mfxExtBuffer **ExtParam; + mfxU16 NumExtParam; + }; + mfxU32 reserved[6]; + }; + mfxI64 DecodeTimeStamp; + mfxU64 TimeStamp; + mfxU8* Data; + mfxU32 DataOffset; + mfxU32 DataLength; + mfxU32 MaxLength; + + mfxU16 PicStruct; + mfxU16 FrameType; + mfxU16 DataFlag; + mfxU16 reserved2; +} mfxBitstream; + +typedef struct _mfxSyncPoint *mfxSyncPoint; + +/* GPUCopy */ +enum { + MFX_GPUCOPY_DEFAULT = 0, + MFX_GPUCOPY_ON = 1, + MFX_GPUCOPY_OFF = 2 +}; + +typedef struct { + mfxIMPL Implementation; + mfxVersion Version; + mfxU16 ExternalThreads; + union { + struct { + mfxExtBuffer **ExtParam; + mfxU16 NumExtParam; + }; + mfxU16 reserved2[5]; + }; + mfxU16 GPUCopy; + mfxU16 reserved[21]; +} mfxInitParam; + +enum { + MFX_EXTBUFF_THREADS_PARAM = MFX_MAKEFOURCC('T','H','D','P') +}; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 NumThread; + mfxI32 SchedulingType; + mfxI32 Priority; + mfxU16 reserved[55]; +} mfxExtThreadsParam; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxdefs.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxdefs.h new file mode 100644 index 0000000..3091275 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxdefs.h @@ -0,0 +1,153 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2007-2015 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfxdefs.h + +\* ****************************************************************************** */ +#ifndef __MFXDEFS_H__ +#define __MFXDEFS_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +#if (defined( _WIN32 ) || defined ( _WIN64 )) && !defined (__GNUC__) + #define __INT64 __int64 + #define __UINT64 unsigned __int64 +#else + #define __INT64 long long + #define __UINT64 unsigned long long +#endif + +#ifdef _WIN32 + #define MFX_CDECL __cdecl + #define MFX_STDCALL __stdcall +#else + #define MFX_CDECL + #define MFX_STDCALL +#endif /* _WIN32 */ + +#define MFX_INFINITE 0xFFFFFFFF + +typedef unsigned char mfxU8; +typedef char mfxI8; +typedef short mfxI16; +typedef unsigned short mfxU16; +typedef unsigned int mfxU32; +typedef int mfxI32; +#if defined( _WIN32 ) || defined ( _WIN64 ) +typedef unsigned long mfxUL32; +typedef long mfxL32; +#else +typedef unsigned int mfxUL32; +typedef int mfxL32; +#endif +typedef float mfxF32; +typedef double mfxF64; +typedef __UINT64 mfxU64; +typedef __INT64 mfxI64; +typedef void* mfxHDL; +typedef mfxHDL mfxMemId; +typedef void* mfxThreadTask; +typedef char mfxChar; + +typedef struct { + mfxI16 x; + mfxI16 y; +} mfxI16Pair; + +typedef struct { + mfxHDL first; + mfxHDL second; +} mfxHDLPair; + + +/*********************************************************************************\ +Error message +\*********************************************************************************/ +typedef enum +{ + /* no error */ + MFX_ERR_NONE = 0, /* no error */ + + /* reserved for unexpected errors */ + MFX_ERR_UNKNOWN = -1, /* unknown error. */ + + /* error codes <0 */ + MFX_ERR_NULL_PTR = -2, /* null pointer */ + MFX_ERR_UNSUPPORTED = -3, /* undeveloped feature */ + MFX_ERR_MEMORY_ALLOC = -4, /* failed to allocate memory */ + MFX_ERR_NOT_ENOUGH_BUFFER = -5, /* insufficient buffer at input/output */ + MFX_ERR_INVALID_HANDLE = -6, /* invalid handle */ + MFX_ERR_LOCK_MEMORY = -7, /* failed to lock the memory block */ + MFX_ERR_NOT_INITIALIZED = -8, /* member function called before initialization */ + MFX_ERR_NOT_FOUND = -9, /* the specified object is not found */ + MFX_ERR_MORE_DATA = -10, /* expect more data at input */ + MFX_ERR_MORE_SURFACE = -11, /* expect more surface at output */ + MFX_ERR_ABORTED = -12, /* operation aborted */ + MFX_ERR_DEVICE_LOST = -13, /* lose the HW acceleration device */ + MFX_ERR_INCOMPATIBLE_VIDEO_PARAM = -14, /* incompatible video parameters */ + MFX_ERR_INVALID_VIDEO_PARAM = -15, /* invalid video parameters */ + MFX_ERR_UNDEFINED_BEHAVIOR = -16, /* undefined behavior */ + MFX_ERR_DEVICE_FAILED = -17, /* device operation failure */ + MFX_ERR_MORE_BITSTREAM = -18, /* expect more bitstream buffers at output */ + MFX_ERR_INCOMPATIBLE_AUDIO_PARAM = -19, /* incompatible audio parameters */ + MFX_ERR_INVALID_AUDIO_PARAM = -20, /* invalid audio parameters */ + + /* warnings >0 */ + MFX_WRN_IN_EXECUTION = 1, /* the previous asynchronous operation is in execution */ + MFX_WRN_DEVICE_BUSY = 2, /* the HW acceleration device is busy */ + MFX_WRN_VIDEO_PARAM_CHANGED = 3, /* the video parameters are changed during decoding */ + MFX_WRN_PARTIAL_ACCELERATION = 4, /* SW is used */ + MFX_WRN_INCOMPATIBLE_VIDEO_PARAM = 5, /* incompatible video parameters */ + MFX_WRN_VALUE_NOT_CHANGED = 6, /* the value is saturated based on its valid range */ + MFX_WRN_OUT_OF_RANGE = 7, /* the value is out of valid range */ + MFX_WRN_FILTER_SKIPPED = 10, /* one of requested filters has been skipped */ + MFX_WRN_INCOMPATIBLE_AUDIO_PARAM = 11, /* incompatible audio parameters */ + + /* threading statuses */ + MFX_TASK_DONE = MFX_ERR_NONE, /* task has been completed */ + MFX_TASK_WORKING = 8, /* there is some more work to do */ + MFX_TASK_BUSY = 9 /* task is waiting for resources */ + +} mfxStatus; + + +// Application +#if defined(MFX_DISPATCHER_EXPOSED_PREFIX) + +#include "mfxdispatcherprefixedfunctions.h" + +#endif // MFX_DISPATCHER_EXPOSED_PREFIX + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __MFXDEFS_H__ */ diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxenc.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxenc.h new file mode 100644 index 0000000..f4ff9c6 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxenc.h @@ -0,0 +1,80 @@ +/******************************************************************************* *\ + +Copyright (C) 2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfxenc.h + +*******************************************************************************/ +#ifndef __MFXENC_H__ +#define __MFXENC_H__ +#include "mfxdefs.h" +#include "mfxvstructures.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +typedef struct _mfxENCInput mfxENCInput; +struct _mfxENCInput{ + mfxU32 reserved[32]; + + mfxFrameSurface1 *InSurface; + + mfxU16 NumFrameL0; + mfxFrameSurface1 **L0Surface; + mfxU16 NumFrameL1; + mfxFrameSurface1 **L1Surface; + + mfxU16 NumExtParam; + mfxExtBuffer **ExtParam; +} ; +typedef struct _mfxENCOutput mfxENCOutput; +struct _mfxENCOutput{ + mfxU32 reserved[32]; + + mfxFrameSurface1 *OutSurface; + + mfxU16 NumExtParam; + mfxExtBuffer **ExtParam; +} ; + + +mfxStatus MFX_CDECL MFXVideoENC_Query(mfxSession session, mfxVideoParam *in, mfxVideoParam *out); +mfxStatus MFX_CDECL MFXVideoENC_QueryIOSurf(mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request); +mfxStatus MFX_CDECL MFXVideoENC_Init(mfxSession session, mfxVideoParam *par); +mfxStatus MFX_CDECL MFXVideoENC_Reset(mfxSession session, mfxVideoParam *par); +mfxStatus MFX_CDECL MFXVideoENC_Close(mfxSession session); + +mfxStatus MFX_CDECL MFXVideoENC_ProcessFrameAsync(mfxSession session, mfxENCInput *in, mfxENCOutput *out, mfxSyncPoint *syncp); + + +#ifdef __cplusplus +} // extern "C" +#endif /* __cplusplus */ + + +#endif + diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxjpeg.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxjpeg.h new file mode 100644 index 0000000..3966047 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxjpeg.h @@ -0,0 +1,107 @@ +/******************************************************************************* *\ + +Copyright (C) 2010-2013 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfxjpeg.h + +*******************************************************************************/ +#ifndef __MFX_JPEG_H__ +#define __MFX_JPEG_H__ + +#include "mfxdefs.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* CodecId */ +enum { + MFX_CODEC_JPEG = MFX_MAKEFOURCC('J','P','E','G') +}; + +/* CodecProfile, CodecLevel */ +enum +{ + MFX_PROFILE_JPEG_BASELINE = 1 +}; + +enum +{ + MFX_ROTATION_0 = 0, + MFX_ROTATION_90 = 1, + MFX_ROTATION_180 = 2, + MFX_ROTATION_270 = 3 +}; + +enum { + MFX_EXTBUFF_JPEG_QT = MFX_MAKEFOURCC('J','P','G','Q'), + MFX_EXTBUFF_JPEG_HUFFMAN = MFX_MAKEFOURCC('J','P','G','H') +}; + +enum { + MFX_JPEG_COLORFORMAT_UNKNOWN = 0, + MFX_JPEG_COLORFORMAT_YCbCr = 1, + MFX_JPEG_COLORFORMAT_RGB = 2 +}; + +enum { + MFX_SCANTYPE_UNKNOWN = 0, + MFX_SCANTYPE_INTERLEAVED = 1, + MFX_SCANTYPE_NONINTERLEAVED = 2 +}; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 reserved[7]; + mfxU16 NumTable; + + mfxU16 Qm[4][64]; +} mfxExtJPEGQuantTables; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 reserved[2]; + mfxU16 NumDCTable; + mfxU16 NumACTable; + + struct { + mfxU8 Bits[16]; + mfxU8 Values[12]; + } DCTables[4]; + + struct { + mfxU8 Bits[16]; + mfxU8 Values[162]; + } ACTables[4]; +} mfxExtJPEGHuffmanTables; + +#ifdef __cplusplus +} // extern "C" +#endif /* __cplusplus */ + +#endif // __MFX_JPEG_H__ diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxmvc.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxmvc.h new file mode 100644 index 0000000..e9ebe85 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxmvc.h @@ -0,0 +1,109 @@ +/******************************************************************************* *\ + +Copyright (C) 2010-2013 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfxmvc.h + +*******************************************************************************/ +#ifndef __MFXMVC_H__ +#define __MFXMVC_H__ + +#include "mfxdefs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* CodecProfile, CodecLevel */ +enum { + /* MVC profiles */ + MFX_PROFILE_AVC_MULTIVIEW_HIGH =118, + MFX_PROFILE_AVC_STEREO_HIGH =128 +}; + +/* Extended Buffer Ids */ +enum { + MFX_EXTBUFF_MVC_SEQ_DESC = MFX_MAKEFOURCC('M','V','C','D'), + MFX_EXTBUFF_MVC_TARGET_VIEWS = MFX_MAKEFOURCC('M','V','C','T') +}; + +typedef struct { + mfxU16 ViewId; + + mfxU16 NumAnchorRefsL0; + mfxU16 NumAnchorRefsL1; + mfxU16 AnchorRefL0[16]; + mfxU16 AnchorRefL1[16]; + + mfxU16 NumNonAnchorRefsL0; + mfxU16 NumNonAnchorRefsL1; + mfxU16 NonAnchorRefL0[16]; + mfxU16 NonAnchorRefL1[16]; +} mfxMVCViewDependency; + +typedef struct { + mfxU16 TemporalId; + mfxU16 LevelIdc; + + mfxU16 NumViews; + mfxU16 NumTargetViews; + mfxU16 *TargetViewId; +} mfxMVCOperationPoint; + +typedef struct { + mfxExtBuffer Header; + + mfxU32 NumView; + mfxU32 NumViewAlloc; + mfxMVCViewDependency *View; + + mfxU32 NumViewId; + mfxU32 NumViewIdAlloc; + mfxU16 *ViewId; + + mfxU32 NumOP; + mfxU32 NumOPAlloc; + mfxMVCOperationPoint *OP; + + mfxU16 NumRefsTotal; + mfxU32 Reserved[16]; + +} mfxExtMVCSeqDesc; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 TemporalId; + mfxU32 NumView; + mfxU16 ViewId[1024]; +} mfxExtMVCTargetViews ; + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif + diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxpak.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxpak.h new file mode 100644 index 0000000..b124901 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxpak.h @@ -0,0 +1,78 @@ +/******************************************************************************* *\ + +Copyright (C) 2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfxpak.h + +*******************************************************************************/ +#ifndef __MFXPAK_H__ +#define __MFXPAK_H__ +#include "mfxdefs.h" +#include "mfxvstructures.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +typedef struct { + mfxU32 reserved[32]; + + mfxFrameSurface1 *InSurface; + + mfxU16 NumFrameL0; + mfxFrameSurface1 **L0Surface; + mfxU16 NumFrameL1; + mfxFrameSurface1 **L1Surface; + + mfxU16 NumExtParam; + mfxExtBuffer **ExtParam; +} mfxPAKInput; + +typedef struct { + mfxBitstream *Bs; + + mfxFrameSurface1 *OutSurface; + + mfxU16 NumExtParam; + mfxExtBuffer **ExtParam; +} mfxPAKOutput; + +typedef struct _mfxSession *mfxSession; +mfxStatus MFX_CDECL MFXVideoPAK_Query(mfxSession session, mfxVideoParam *in, mfxVideoParam *out); +mfxStatus MFX_CDECL MFXVideoPAK_QueryIOSurf(mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request); +mfxStatus MFX_CDECL MFXVideoPAK_Init(mfxSession session, mfxVideoParam *par); +mfxStatus MFX_CDECL MFXVideoPAK_Reset(mfxSession session, mfxVideoParam *par); +mfxStatus MFX_CDECL MFXVideoPAK_Close(mfxSession session); + +mfxStatus MFX_CDECL MFXVideoPAK_ProcessFrameAsync(mfxSession session, mfxPAKInput *in, mfxPAKOutput *out, mfxSyncPoint *syncp); + + +#ifdef __cplusplus +} // extern "C" +#endif /* __cplusplus */ + + +#endif diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxplugin++.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxplugin++.h new file mode 100644 index 0000000..47212dd --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxplugin++.h @@ -0,0 +1,719 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2007-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +File Name: mfxplugin++.h + +\* ****************************************************************************** */ + +#ifndef __MFXPLUGINPLUSPLUS_H +#define __MFXPLUGINPLUSPLUS_H + +#include "mfxplugin.h" + +// base class for MFXVideoUSER/MFXAudioUSER API + +class MFXBaseUSER { +public: + explicit MFXBaseUSER(mfxSession session = NULL) + : m_session(session){} + + virtual ~MFXBaseUSER() {}; + + virtual mfxStatus Register(mfxU32 type, const mfxPlugin *par) = 0; + virtual mfxStatus Unregister(mfxU32 type) = 0; + virtual mfxStatus ProcessFrameAsync(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp) = 0; + +protected: + mfxSession m_session; +}; + +//c++ wrapper over only 3 exposed functions from MFXVideoUSER module +class MFXVideoUSER: public MFXBaseUSER { +public: + explicit MFXVideoUSER(mfxSession session = NULL) + : MFXBaseUSER(session){} + + virtual mfxStatus Register(mfxU32 type, const mfxPlugin *par) { + return MFXVideoUSER_Register(m_session, type, par); + } + virtual mfxStatus Unregister(mfxU32 type) { + return MFXVideoUSER_Unregister(m_session, type); + } + virtual mfxStatus ProcessFrameAsync(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp) { + return MFXVideoUSER_ProcessFrameAsync(m_session, in, in_num, out, out_num, syncp); + } +}; + +//c++ wrapper over only 3 exposed functions from MFXAudioUSER module +class MFXAudioUSER: public MFXBaseUSER { +public: + explicit MFXAudioUSER(mfxSession session = NULL) + : MFXBaseUSER(session){} + + virtual mfxStatus Register(mfxU32 type, const mfxPlugin *par) { + return MFXAudioUSER_Register(m_session, type, par); + } + virtual mfxStatus Unregister(mfxU32 type) { + return MFXAudioUSER_Unregister(m_session, type); + } + virtual mfxStatus ProcessFrameAsync(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp) { + return MFXAudioUSER_ProcessFrameAsync(m_session, in, in_num, out, out_num, syncp); + } +}; + + +//initialize mfxPlugin struct +class MFXPluginParam { + mfxPluginParam m_param; + +public: + MFXPluginParam(mfxU32 CodecId, mfxU32 Type, mfxPluginUID uid, mfxThreadPolicy ThreadPolicy = MFX_THREADPOLICY_SERIAL, mfxU32 MaxThreadNum = 1) + : m_param() { + m_param.PluginUID = uid; + m_param.Type = Type; + m_param.CodecId = CodecId; + m_param.MaxThreadNum = MaxThreadNum; + m_param.ThreadPolicy = ThreadPolicy; + } + operator const mfxPluginParam& () const { + return m_param; + } + operator mfxPluginParam& () { + return m_param; + } +}; + +//common interface part for every plugin: decoder/encoder and generic +struct MFXPlugin +{ + virtual ~MFXPlugin() {}; + //init function always required for any transform or codec plugins, for codec plugins it maps to callback from MediaSDK + //for generic plugin application should call it + //MediaSDK mfxPlugin API mapping + virtual mfxStatus PluginInit(mfxCoreInterface *core) = 0; + //release CoreInterface, and destroy plugin state, not destroy plugin instance + virtual mfxStatus PluginClose() = 0; + virtual mfxStatus GetPluginParam(mfxPluginParam *par) = 0; + virtual mfxStatus Execute(mfxThreadTask task, mfxU32 uid_p, mfxU32 uid_a) = 0; + virtual mfxStatus FreeResources(mfxThreadTask task, mfxStatus sts) = 0; + //destroy plugin due to shared module distribution model plugin wont support virtual destructor + virtual void Release() = 0; + //release resources associated with current instance of plugin, but do not release CoreInterface related resource set in pluginInit + virtual mfxStatus Close() = 0; + //communication protocol between particular version of plugin and application + virtual mfxStatus SetAuxParams(void* auxParam, int auxParamSize) = 0; +}; + +//common extension interface that codec plugins should expose additionally to MFXPlugin +struct MFXCodecPlugin : MFXPlugin +{ + virtual mfxStatus Init(mfxVideoParam *par) = 0; + virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *in, mfxFrameAllocRequest *out) = 0; + virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) =0; + virtual mfxStatus Reset(mfxVideoParam *par) = 0; + virtual mfxStatus GetVideoParam(mfxVideoParam *par) = 0; +}; + +//common extension interface that audio codec plugins should expose additionally to MFXPlugin +struct MFXAudioCodecPlugin : MFXPlugin +{ + virtual mfxStatus Init(mfxAudioParam *par) = 0; + virtual mfxStatus Query(mfxAudioParam *in, mfxAudioParam *out) =0; + virtual mfxStatus QueryIOSize(mfxAudioParam *par, mfxAudioAllocRequest *request) = 0; + virtual mfxStatus Reset(mfxAudioParam *par) = 0; + virtual mfxStatus GetAudioParam(mfxAudioParam *par) = 0; +}; + +//general purpose transform plugin interface, not a codec plugin +struct MFXGenericPlugin : MFXPlugin +{ + virtual mfxStatus Init(mfxVideoParam *par) = 0; + virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *in, mfxFrameAllocRequest *out) = 0; + virtual mfxStatus Submit(const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxThreadTask *task) = 0; +}; + +//decoder plugins may only support this interface +struct MFXDecoderPlugin : MFXCodecPlugin +{ + virtual mfxStatus DecodeHeader(mfxBitstream *bs, mfxVideoParam *par) = 0; + virtual mfxStatus GetPayload(mfxU64 *ts, mfxPayload *payload) = 0; + virtual mfxStatus DecodeFrameSubmit(mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxThreadTask *task) = 0; +}; + +//audio decoder plugins may only support this interface +struct MFXAudioDecoderPlugin : MFXAudioCodecPlugin +{ + virtual mfxStatus DecodeHeader(mfxBitstream *bs, mfxAudioParam *par) = 0; +// virtual mfxStatus GetPayload(mfxU64 *ts, mfxPayload *payload) = 0; + virtual mfxStatus DecodeFrameSubmit(mfxBitstream *in, mfxAudioFrame *out, mfxThreadTask *task) = 0; +}; + +//encoder plugins may only support this interface +struct MFXEncoderPlugin : MFXCodecPlugin +{ + virtual mfxStatus EncodeFrameSubmit(mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxThreadTask *task) = 0; +}; + +//audio encoder plugins may only support this interface +struct MFXAudioEncoderPlugin : MFXAudioCodecPlugin +{ + virtual mfxStatus EncodeFrameSubmit(mfxAudioFrame *aFrame, mfxBitstream *out, mfxThreadTask *task) = 0; +}; + +//vpp plugins may only support this interface +struct MFXVPPPlugin : MFXCodecPlugin +{ + virtual mfxStatus VPPFrameSubmit(mfxFrameSurface1 *surface_in, mfxFrameSurface1 *surface_out, mfxExtVppAuxData *aux, mfxThreadTask *task) = 0; + virtual mfxStatus VPPFrameSubmitEx(mfxFrameSurface1 *in, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxThreadTask *task) = 0; +}; + +struct MFXEncPlugin : MFXCodecPlugin +{ + virtual mfxStatus EncFrameSubmit(mfxENCInput *in, mfxENCOutput *out, mfxThreadTask *task) = 0; +}; + + + + +class MFXCoreInterface +{ +protected: + mfxCoreInterface m_core; +public: + + MFXCoreInterface() + : m_core() { + } + MFXCoreInterface(const mfxCoreInterface & pCore) + : m_core(pCore) { + } + + MFXCoreInterface(const MFXCoreInterface & that) + : m_core(that.m_core) { + } + MFXCoreInterface &operator = (const MFXCoreInterface & that) + { + m_core = that.m_core; + return *this; + } + bool IsCoreSet() { + return m_core.pthis != 0; + } + mfxStatus GetCoreParam(mfxCoreParam *par) { + if (!IsCoreSet()) { + return MFX_ERR_NULL_PTR; + } + return m_core.GetCoreParam(m_core.pthis, par); + } + mfxStatus GetHandle (mfxHandleType type, mfxHDL *handle) { + if (!IsCoreSet()) { + return MFX_ERR_NULL_PTR; + } + return m_core.GetHandle(m_core.pthis, type, handle); + } + mfxStatus IncreaseReference (mfxFrameData *fd) { + if (!IsCoreSet()) { + return MFX_ERR_NULL_PTR; + } + return m_core.IncreaseReference(m_core.pthis, fd); + } + mfxStatus DecreaseReference (mfxFrameData *fd) { + if (!IsCoreSet()) { + return MFX_ERR_NULL_PTR; + } + return m_core.DecreaseReference(m_core.pthis, fd); + } + mfxStatus CopyFrame (mfxFrameSurface1 *dst, mfxFrameSurface1 *src) { + if (!IsCoreSet()) { + return MFX_ERR_NULL_PTR; + } + return m_core.CopyFrame(m_core.pthis, dst, src); + } + mfxStatus CopyBuffer(mfxU8 *dst, mfxU32 size, mfxFrameSurface1 *src) { + if (!IsCoreSet()) { + return MFX_ERR_NULL_PTR; + } + return m_core.CopyBuffer(m_core.pthis, dst, size, src); + } + mfxStatus MapOpaqueSurface(mfxU32 num, mfxU32 type, mfxFrameSurface1 **op_surf) { + if (!IsCoreSet()) { + return MFX_ERR_NULL_PTR; + } + return m_core.MapOpaqueSurface(m_core.pthis, num, type, op_surf); + } + mfxStatus UnmapOpaqueSurface(mfxU32 num, mfxU32 type, mfxFrameSurface1 **op_surf) { + if (!IsCoreSet()) { + return MFX_ERR_NULL_PTR; + } + return m_core.UnmapOpaqueSurface(m_core.pthis, num, type, op_surf); + } + mfxStatus GetRealSurface(mfxFrameSurface1 *op_surf, mfxFrameSurface1 **surf) { + if (!IsCoreSet()) { + return MFX_ERR_NULL_PTR; + } + return m_core.GetRealSurface(m_core.pthis, op_surf, surf); + } + mfxStatus GetOpaqueSurface(mfxFrameSurface1 *surf, mfxFrameSurface1 **op_surf) { + if (!IsCoreSet()) { + return MFX_ERR_NULL_PTR; + } + return m_core.GetOpaqueSurface(m_core.pthis, surf, op_surf); + } + mfxStatus CreateAccelerationDevice(mfxHandleType type, mfxHDL *handle) { + if (!IsCoreSet()) { + return MFX_ERR_NULL_PTR; + } + return m_core.CreateAccelerationDevice(m_core.pthis, type, handle); + } + mfxFrameAllocator & FrameAllocator() { + return m_core.FrameAllocator; + } + +} ; + +/* Class adapter between "C" structure mfxPlugin and C++ interface MFXPlugin */ + +namespace detail +{ + template + class MFXPluginAdapterBase + { + protected: + mfxPlugin m_mfxAPI; + public: + MFXPluginAdapterBase( T *plugin, mfxVideoCodecPlugin *pCodec = NULL) + { + SetupCallbacks(plugin, pCodec); + } + + MFXPluginAdapterBase( T *plugin, mfxAudioCodecPlugin *pCodec) + { + SetupCallbacks(plugin, pCodec); + } + + operator mfxPlugin () const { + return m_mfxAPI; + } + void SetupCallbacks(T *plugin) { + m_mfxAPI.pthis = plugin; + m_mfxAPI.PluginInit = _PluginInit; + m_mfxAPI.PluginClose = _PluginClose; + m_mfxAPI.GetPluginParam = _GetPluginParam; + m_mfxAPI.Submit = 0; + m_mfxAPI.Execute = _Execute; + m_mfxAPI.FreeResources = _FreeResources; + } + + void SetupCallbacks( T *plugin, mfxVideoCodecPlugin *pCodec) { + SetupCallbacks(plugin); + m_mfxAPI.Video = pCodec; + } + + void SetupCallbacks( T *plugin, mfxAudioCodecPlugin *pCodec) { + SetupCallbacks(plugin); + m_mfxAPI.Audio = pCodec; + } + private: + + static mfxStatus _PluginInit(mfxHDL pthis, mfxCoreInterface *core) { + return reinterpret_cast(pthis)->PluginInit(core); + } + static mfxStatus _PluginClose(mfxHDL pthis) { + return reinterpret_cast(pthis)->PluginClose(); + } + static mfxStatus _GetPluginParam(mfxHDL pthis, mfxPluginParam *par) { + return reinterpret_cast(pthis)->GetPluginParam(par); + } + static mfxStatus _Execute(mfxHDL pthis, mfxThreadTask task, mfxU32 thread_id, mfxU32 call_count) { + return reinterpret_cast(pthis)->Execute(task, thread_id, call_count); + } + static mfxStatus _FreeResources(mfxHDL pthis, mfxThreadTask task, mfxStatus sts) { + return reinterpret_cast(pthis)->FreeResources(task, sts); + } + }; + + template + class MFXCodecPluginAdapterBase : public MFXPluginAdapterBase + { + protected: + //stub to feed mediasdk plugin API + mfxVideoCodecPlugin m_codecPlg; + public: + MFXCodecPluginAdapterBase(T * pCodecPlg) + : MFXPluginAdapterBase(pCodecPlg, &m_codecPlg) + , m_codecPlg() + { + m_codecPlg.Query = _Query; + m_codecPlg.QueryIOSurf = _QueryIOSurf ; + m_codecPlg.Init = _Init; + m_codecPlg.Reset = _Reset; + m_codecPlg.Close = _Close; + m_codecPlg.GetVideoParam = _GetVideoParam; + } + MFXCodecPluginAdapterBase(const MFXCodecPluginAdapterBase & that) + : MFXPluginAdapterBase(reinterpret_cast(that.m_mfxAPI.pthis), &m_codecPlg) + , m_codecPlg() { + SetupCallbacks(); + } + MFXCodecPluginAdapterBase& operator = (const MFXCodecPluginAdapterBase & that) { + MFXPluginAdapterBase :: SetupCallbacks(reinterpret_cast(that.m_mfxAPI.pthis), &m_codecPlg); + SetupCallbacks(); + return *this; + } + + private: + void SetupCallbacks() { + m_codecPlg.Query = _Query; + m_codecPlg.QueryIOSurf = _QueryIOSurf ; + m_codecPlg.Init = _Init; + m_codecPlg.Reset = _Reset; + m_codecPlg.Close = _Close; + m_codecPlg.GetVideoParam = _GetVideoParam; + } + static mfxStatus _Query(mfxHDL pthis, mfxVideoParam *in, mfxVideoParam *out) { + return reinterpret_cast(pthis)->Query(in, out); + } + static mfxStatus _QueryIOSurf(mfxHDL pthis, mfxVideoParam *par, mfxFrameAllocRequest *in, mfxFrameAllocRequest *out){ + return reinterpret_cast(pthis)->QueryIOSurf(par, in, out); + } + static mfxStatus _Init(mfxHDL pthis, mfxVideoParam *par){ + return reinterpret_cast(pthis)->Init(par); + } + static mfxStatus _Reset(mfxHDL pthis, mfxVideoParam *par){ + return reinterpret_cast(pthis)->Reset(par); + } + static mfxStatus _Close(mfxHDL pthis) { + return reinterpret_cast(pthis)->Close(); + } + static mfxStatus _GetVideoParam(mfxHDL pthis, mfxVideoParam *par) { + return reinterpret_cast(pthis)->GetVideoParam(par); + } + }; + + template + class MFXAudioCodecPluginAdapterBase : public MFXPluginAdapterBase + { + protected: + //stub to feed mediasdk plugin API + mfxAudioCodecPlugin m_codecPlg; + public: + MFXAudioCodecPluginAdapterBase(T * pCodecPlg) + : MFXPluginAdapterBase(pCodecPlg, &m_codecPlg) + , m_codecPlg() + { + m_codecPlg.Query = _Query; + m_codecPlg.QueryIOSize = _QueryIOSize ; + m_codecPlg.Init = _Init; + m_codecPlg.Reset = _Reset; + m_codecPlg.Close = _Close; + m_codecPlg.GetAudioParam = _GetAudioParam; + } + MFXAudioCodecPluginAdapterBase(const MFXCodecPluginAdapterBase & that) + : MFXPluginAdapterBase(reinterpret_cast(that.m_mfxAPI.pthis), &m_codecPlg) + , m_codecPlg() { + SetupCallbacks(); + } + MFXAudioCodecPluginAdapterBase& operator = (const MFXAudioCodecPluginAdapterBase & that) { + MFXPluginAdapterBase :: SetupCallbacks(reinterpret_cast(that.m_mfxAPI.pthis), &m_codecPlg); + SetupCallbacks(); + return *this; + } + + private: + void SetupCallbacks() { + m_codecPlg.Query = _Query; + m_codecPlg.QueryIOSize = _QueryIOSize; + m_codecPlg.Init = _Init; + m_codecPlg.Reset = _Reset; + m_codecPlg.Close = _Close; + m_codecPlg.GetAudioParam = _GetAudioParam; + } + static mfxStatus _Query(mfxHDL pthis, mfxAudioParam *in, mfxAudioParam *out) { + return reinterpret_cast(pthis)->Query(in, out); + } + static mfxStatus _QueryIOSize(mfxHDL pthis, mfxAudioParam *par, mfxAudioAllocRequest *request){ + return reinterpret_cast(pthis)->QueryIOSize(par, request); + } + static mfxStatus _Init(mfxHDL pthis, mfxAudioParam *par){ + return reinterpret_cast(pthis)->Init(par); + } + static mfxStatus _Reset(mfxHDL pthis, mfxAudioParam *par){ + return reinterpret_cast(pthis)->Reset(par); + } + static mfxStatus _Close(mfxHDL pthis) { + return reinterpret_cast(pthis)->Close(); + } + static mfxStatus _GetAudioParam(mfxHDL pthis, mfxAudioParam *par) { + return reinterpret_cast(pthis)->GetAudioParam(par); + } + }; + + template + struct MFXPluginAdapterInternal{}; + template<> + class MFXPluginAdapterInternal : public MFXPluginAdapterBase + { + public: + MFXPluginAdapterInternal(MFXGenericPlugin *pPlugin) + : MFXPluginAdapterBase(pPlugin) + { + m_mfxAPI.Submit = _Submit; + } + MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that ) + : MFXPluginAdapterBase(that) { + m_mfxAPI.Submit = that._Submit; + } + MFXPluginAdapterInternal& operator = (const MFXPluginAdapterInternal & that) { + MFXPluginAdapterBase::operator=(that); + m_mfxAPI.Submit = that._Submit; + return *this; + } + + private: + static mfxStatus _Submit(mfxHDL pthis, const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxThreadTask *task) { + return reinterpret_cast(pthis)->Submit(in, in_num, out, out_num, task); + } + }; + + template<> + class MFXPluginAdapterInternal : public MFXCodecPluginAdapterBase + { + public: + MFXPluginAdapterInternal(MFXDecoderPlugin *pPlugin) + : MFXCodecPluginAdapterBase(pPlugin) + { + SetupCallbacks(); + } + + MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that) + : MFXCodecPluginAdapterBase(that) { + SetupCallbacks(); + } + + MFXPluginAdapterInternal& operator = (const MFXPluginAdapterInternal & that) { + MFXCodecPluginAdapterBase::operator=(that); + SetupCallbacks(); + return *this; + } + + private: + void SetupCallbacks() { + m_codecPlg.DecodeHeader = _DecodeHeader; + m_codecPlg.GetPayload = _GetPayload; + m_codecPlg.DecodeFrameSubmit = _DecodeFrameSubmit; + } + static mfxStatus _DecodeHeader(mfxHDL pthis, mfxBitstream *bs, mfxVideoParam *par) { + return reinterpret_cast(pthis)->DecodeHeader(bs, par); + } + static mfxStatus _GetPayload(mfxHDL pthis, mfxU64 *ts, mfxPayload *payload) { + return reinterpret_cast(pthis)->GetPayload(ts, payload); + } + static mfxStatus _DecodeFrameSubmit(mfxHDL pthis, mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxThreadTask *task) { + return reinterpret_cast(pthis)->DecodeFrameSubmit(bs, surface_work, surface_out, task); + } + }; + + template<> + class MFXPluginAdapterInternal : public MFXAudioCodecPluginAdapterBase + { + public: + MFXPluginAdapterInternal(MFXAudioDecoderPlugin *pPlugin) + : MFXAudioCodecPluginAdapterBase(pPlugin) + { + SetupCallbacks(); + } + + MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that) + : MFXAudioCodecPluginAdapterBase(that) { + SetupCallbacks(); + } + + MFXPluginAdapterInternal& operator = (const MFXPluginAdapterInternal & that) { + MFXAudioCodecPluginAdapterBase::operator=(that); + SetupCallbacks(); + return *this; + } + + private: + void SetupCallbacks() { + m_codecPlg.DecodeHeader = _DecodeHeader; +// m_codecPlg.GetPayload = _GetPayload; + m_codecPlg.DecodeFrameSubmit = _DecodeFrameSubmit; + } + static mfxStatus _DecodeHeader(mfxHDL pthis, mfxBitstream *bs, mfxAudioParam *par) { + return reinterpret_cast(pthis)->DecodeHeader(bs, par); + } +// static mfxStatus _GetPayload(mfxHDL pthis, mfxU64 *ts, mfxPayload *payload) { + // return reinterpret_cast(pthis)->GetPayload(ts, payload); + // } + static mfxStatus _DecodeFrameSubmit(mfxHDL pthis, mfxBitstream *in, mfxAudioFrame *out, mfxThreadTask *task) { + return reinterpret_cast(pthis)->DecodeFrameSubmit(in, out, task); + } + }; + + template<> + class MFXPluginAdapterInternal : public MFXCodecPluginAdapterBase + { + public: + MFXPluginAdapterInternal(MFXEncoderPlugin *pPlugin) + : MFXCodecPluginAdapterBase(pPlugin) + { + m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit; + } + MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that) + : MFXCodecPluginAdapterBase(that) { + m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit; + } + + MFXPluginAdapterInternal& operator = (const MFXPluginAdapterInternal & that) { + MFXCodecPluginAdapterBase::operator = (that); + m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit; + return *this; + } + + private: + static mfxStatus _EncodeFrameSubmit(mfxHDL pthis, mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxThreadTask *task) { + return reinterpret_cast(pthis)->EncodeFrameSubmit(ctrl, surface, bs, task); + } + }; + + template<> + class MFXPluginAdapterInternal : public MFXAudioCodecPluginAdapterBase + { + public: + MFXPluginAdapterInternal(MFXAudioEncoderPlugin *pPlugin) + : MFXAudioCodecPluginAdapterBase(pPlugin) + { + SetupCallbacks(); + } + + MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that) + : MFXAudioCodecPluginAdapterBase(that) { + SetupCallbacks(); + } + + MFXPluginAdapterInternal& operator = (const MFXPluginAdapterInternal & that) { + MFXAudioCodecPluginAdapterBase::operator=(that); + SetupCallbacks(); + return *this; + } + + private: + void SetupCallbacks() { + m_codecPlg.EncodeFrameSubmit = _EncodeFrameSubmit; + } + static mfxStatus _EncodeFrameSubmit(mfxHDL pthis, mfxAudioFrame *aFrame, mfxBitstream *out, mfxThreadTask *task) { + return reinterpret_cast(pthis)->EncodeFrameSubmit(aFrame, out, task); + } + }; + + template<> + class MFXPluginAdapterInternal : public MFXCodecPluginAdapterBase + { + public: + MFXPluginAdapterInternal(MFXEncPlugin *pPlugin) + : MFXCodecPluginAdapterBase(pPlugin) + { + m_codecPlg.ENCFrameSubmit = _ENCFrameSubmit; + } + MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that) + : MFXCodecPluginAdapterBase(that) { + m_codecPlg.ENCFrameSubmit = _ENCFrameSubmit; + } + + MFXPluginAdapterInternal& operator = (const MFXPluginAdapterInternal & that) { + MFXCodecPluginAdapterBase::operator = (that); + m_codecPlg.ENCFrameSubmit = _ENCFrameSubmit; + return *this; + } + + private: + static mfxStatus _ENCFrameSubmit(mfxHDL pthis,mfxENCInput *in, mfxENCOutput *out, mfxThreadTask *task) { + return reinterpret_cast(pthis)->EncFrameSubmit(in, out, task); + } + }; + + + template<> + class MFXPluginAdapterInternal : public MFXCodecPluginAdapterBase + { + public: + MFXPluginAdapterInternal(MFXVPPPlugin *pPlugin) + : MFXCodecPluginAdapterBase(pPlugin) + { + SetupCallbacks(); + } + MFXPluginAdapterInternal(const MFXPluginAdapterInternal & that) + : MFXCodecPluginAdapterBase(that) { + SetupCallbacks(); + } + + MFXPluginAdapterInternal& operator = (const MFXPluginAdapterInternal & that) { + MFXCodecPluginAdapterBase::operator = (that); + SetupCallbacks(); + return *this; + } + + private: + void SetupCallbacks() { + m_codecPlg.VPPFrameSubmit = _VPPFrameSubmit; + m_codecPlg.VPPFrameSubmitEx = _VPPFrameSubmitEx; + } + static mfxStatus _VPPFrameSubmit(mfxHDL pthis, mfxFrameSurface1 *surface_in, mfxFrameSurface1 *surface_out, mfxExtVppAuxData *aux, mfxThreadTask *task) { + return reinterpret_cast(pthis)->VPPFrameSubmit(surface_in, surface_out, aux, task); + } + static mfxStatus _VPPFrameSubmitEx(mfxHDL pthis, mfxFrameSurface1 *surface_in, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxThreadTask *task) { + return reinterpret_cast(pthis)->VPPFrameSubmitEx(surface_in, surface_work, surface_out, task); + } + }; +} + +/* adapter for particular plugin type*/ +template +class MFXPluginAdapter +{ +public: + detail::MFXPluginAdapterInternal m_Adapter; + + operator mfxPlugin () const { + return m_Adapter.operator mfxPlugin(); + } + + MFXPluginAdapter(T* pPlugin = NULL) + : m_Adapter(pPlugin) + { + } +}; + +template +inline MFXPluginAdapter make_mfx_plugin_adapter(T* pPlugin) { + + MFXPluginAdapter adapt(pPlugin); + return adapt; +} + +#endif // __MFXPLUGINPLUSPLUS_H diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxplugin.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxplugin.h new file mode 100644 index 0000000..3d34d13 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxplugin.h @@ -0,0 +1,206 @@ +/******************************************************************************* *\ + +Copyright (C) 2007-2015 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfxplugin.h + +*******************************************************************************/ +#ifndef __MFXPLUGIN_H__ +#define __MFXPLUGIN_H__ +#include "mfxvideo.h" +#include "mfxaudio.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +typedef struct { + mfxU8 Data[16]; +} mfxPluginUID; + +static const mfxPluginUID MFX_PLUGINID_HEVCD_SW = {{0x15, 0xdd, 0x93, 0x68, 0x25, 0xad, 0x47, 0x5e, 0xa3, 0x4e, 0x35, 0xf3, 0xf5, 0x42, 0x17, 0xa6}}; +static const mfxPluginUID MFX_PLUGINID_HEVCD_HW = {{0x33, 0xa6, 0x1c, 0x0b, 0x4c, 0x27, 0x45, 0x4c, 0xa8, 0xd8, 0x5d, 0xde, 0x75, 0x7c, 0x6f, 0x8e}}; +static const mfxPluginUID MFX_PLUGINID_HEVCE_SW = {{0x2f, 0xca, 0x99, 0x74, 0x9f, 0xdb, 0x49, 0xae, 0xb1, 0x21, 0xa5, 0xb6, 0x3e, 0xf5, 0x68, 0xf7}}; +static const mfxPluginUID MFX_PLUGINID_HEVCE_GACC = {{0xe5, 0x40, 0x0a, 0x06, 0xc7, 0x4d, 0x41, 0xf5, 0xb1, 0x2d, 0x43, 0x0b, 0xba, 0xa2, 0x3d, 0x0b}}; +static const mfxPluginUID MFX_PLUGINID_HEVCE_HW = {{0x6f, 0xad, 0xc7, 0x91, 0xa0, 0xc2, 0xeb, 0x47, 0x9a, 0xb6, 0xdc, 0xd5, 0xea, 0x9d, 0xa3, 0x47}}; +static const mfxPluginUID MFX_PLUGINID_VP8D_HW = {{0xf6, 0x22, 0x39, 0x4d, 0x8d, 0x87, 0x45, 0x2f, 0x87, 0x8c, 0x51, 0xf2, 0xfc, 0x9b, 0x41, 0x31}}; +static const mfxPluginUID MFX_PLUGINID_VP8E_HW = {{0xbf, 0xfc, 0x51, 0x8c, 0xde, 0x13, 0x4d, 0xf9, 0x8a, 0x96, 0xf4, 0xcf, 0x81, 0x6c, 0x0f, 0xac}}; +static const mfxPluginUID MFX_PLUGINID_VP9E_HW = {{0xce, 0x44, 0xef, 0x6f, 0x1a, 0x6d, 0x22, 0x46, 0xb4, 0x12, 0xbb, 0x38, 0xd6, 0xe4, 0x51, 0x82}}; +static const mfxPluginUID MFX_PLUGINID_VP9D_HW = {{0xa9, 0x22, 0x39, 0x4d, 0x8d, 0x87, 0x45, 0x2f, 0x87, 0x8c, 0x51, 0xf2, 0xfc, 0x9b, 0x41, 0x31}}; +static const mfxPluginUID MFX_PLUGINID_CAMERA_HW = {{0x54, 0x54, 0x26, 0x16, 0x24, 0x33, 0x41, 0xe6, 0x93, 0xae, 0x89, 0x99, 0x42, 0xce, 0x73, 0x55}}; +static const mfxPluginUID MFX_PLUGINID_CAPTURE_HW = {{0x22, 0xd6, 0x2c, 0x07, 0xe6, 0x72, 0x40, 0x8f, 0xbb, 0x4c, 0xc2, 0x0e, 0xd7, 0xa0, 0x53, 0xe4}}; +static const mfxPluginUID MFX_PLUGINID_ITELECINE_HW = {{0xe7, 0x44, 0x75, 0x3a, 0xcd, 0x74, 0x40, 0x2e, 0x89, 0xa2, 0xee, 0x06, 0x35, 0x49, 0x61, 0x79}}; +static const mfxPluginUID MFX_PLUGINID_H264LA_HW = {{0x58, 0x8f, 0x11, 0x85, 0xd4, 0x7b, 0x42, 0x96, 0x8d, 0xea, 0x37, 0x7b, 0xb5, 0xd0, 0xdc, 0xb4}}; +static const mfxPluginUID MFX_PLUGINID_AACD = {{0xe9, 0x34, 0x67, 0x25, 0xac, 0x2f, 0x4c, 0x93, 0xaa, 0x58, 0x5c, 0x11, 0xc7, 0x08, 0x7c, 0xf4}}; +static const mfxPluginUID MFX_PLUGINID_AACE = {{0xb2, 0xa2, 0xa0, 0x5a, 0x4e, 0xac, 0x46, 0xbf, 0xa9, 0xde, 0x7e, 0x80, 0xc9, 0x8d, 0x2e, 0x18}}; +static const mfxPluginUID MFX_PLUGINID_HEVCE_FEI_HW = {{0x87, 0xe0, 0xe8, 0x02, 0x07, 0x37, 0x52, 0x40, 0x85, 0x25, 0x15, 0xcf, 0x4a, 0x5e, 0xdd, 0xe6}}; + + +typedef enum { + MFX_PLUGINTYPE_VIDEO_GENERAL = 0, + MFX_PLUGINTYPE_VIDEO_DECODE = 1, + MFX_PLUGINTYPE_VIDEO_ENCODE = 2, + MFX_PLUGINTYPE_VIDEO_VPP = 3, + MFX_PLUGINTYPE_VIDEO_ENC = 4, + MFX_PLUGINTYPE_AUDIO_DECODE = 5, + MFX_PLUGINTYPE_AUDIO_ENCODE = 6 +} mfxPluginType; + +typedef enum { + MFX_THREADPOLICY_SERIAL = 0, + MFX_THREADPOLICY_PARALLEL = 1 +} mfxThreadPolicy; + +typedef struct mfxPluginParam { + mfxU32 reserved[6]; + mfxU16 reserved1; + mfxU16 PluginVersion; + mfxVersion APIVersion; + mfxPluginUID PluginUID; + mfxU32 Type; + mfxU32 CodecId; + mfxThreadPolicy ThreadPolicy; + mfxU32 MaxThreadNum; +} mfxPluginParam; + +typedef struct mfxCoreParam{ + mfxU32 reserved[13]; + mfxIMPL Impl; + mfxVersion Version; + mfxU32 NumWorkingThread; +} mfxCoreParam; + +typedef struct mfxCoreInterface { + mfxHDL pthis; + + mfxHDL reserved1[2]; + mfxFrameAllocator FrameAllocator; + mfxBufferAllocator reserved3; + + mfxStatus (MFX_CDECL *GetCoreParam)(mfxHDL pthis, mfxCoreParam *par); + mfxStatus (MFX_CDECL *GetHandle) (mfxHDL pthis, mfxHandleType type, mfxHDL *handle); + mfxStatus (MFX_CDECL *IncreaseReference) (mfxHDL pthis, mfxFrameData *fd); + mfxStatus (MFX_CDECL *DecreaseReference) (mfxHDL pthis, mfxFrameData *fd); + mfxStatus (MFX_CDECL *CopyFrame) (mfxHDL pthis, mfxFrameSurface1 *dst, mfxFrameSurface1 *src); + mfxStatus (MFX_CDECL *CopyBuffer)(mfxHDL pthis, mfxU8 *dst, mfxU32 size, mfxFrameSurface1 *src); + + mfxStatus (MFX_CDECL *MapOpaqueSurface)(mfxHDL pthis, mfxU32 num, mfxU32 type, mfxFrameSurface1 **op_surf); + mfxStatus (MFX_CDECL *UnmapOpaqueSurface)(mfxHDL pthis, mfxU32 num, mfxU32 type, mfxFrameSurface1 **op_surf); + + mfxStatus (MFX_CDECL *GetRealSurface)(mfxHDL pthis, mfxFrameSurface1 *op_surf, mfxFrameSurface1 **surf); + mfxStatus (MFX_CDECL *GetOpaqueSurface)(mfxHDL pthis, mfxFrameSurface1 *surf, mfxFrameSurface1 **op_surf); + + mfxStatus (MFX_CDECL *CreateAccelerationDevice)(mfxHDL pthis, mfxHandleType type, mfxHDL *handle); + + mfxHDL reserved4[3]; +} mfxCoreInterface; + +/* video codec plugin extension*/ +typedef struct _mfxENCInput mfxENCInput; +typedef struct _mfxENCOutput mfxENCOutput; +typedef struct mfxVideoCodecPlugin{ + mfxStatus (MFX_CDECL *Query)(mfxHDL pthis, mfxVideoParam *in, mfxVideoParam *out); + mfxStatus (MFX_CDECL *QueryIOSurf)(mfxHDL pthis, mfxVideoParam *par, mfxFrameAllocRequest *in, mfxFrameAllocRequest *out); + mfxStatus (MFX_CDECL *Init)(mfxHDL pthis, mfxVideoParam *par); + mfxStatus (MFX_CDECL *Reset)(mfxHDL pthis, mfxVideoParam *par); + mfxStatus (MFX_CDECL *Close)(mfxHDL pthis); + mfxStatus (MFX_CDECL *GetVideoParam)(mfxHDL pthis, mfxVideoParam *par); + + mfxStatus (MFX_CDECL *EncodeFrameSubmit)(mfxHDL pthis, mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxThreadTask *task); + + mfxStatus (MFX_CDECL *DecodeHeader)(mfxHDL pthis, mfxBitstream *bs, mfxVideoParam *par); + mfxStatus (MFX_CDECL *GetPayload)(mfxHDL pthis, mfxU64 *ts, mfxPayload *payload); + mfxStatus (MFX_CDECL *DecodeFrameSubmit)(mfxHDL pthis, mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxThreadTask *task); + + mfxStatus (MFX_CDECL *VPPFrameSubmit)(mfxHDL pthis, mfxFrameSurface1 *in, mfxFrameSurface1 *out, mfxExtVppAuxData *aux, mfxThreadTask *task); + mfxStatus (MFX_CDECL *VPPFrameSubmitEx)(mfxHDL pthis, mfxFrameSurface1 *in, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxThreadTask *task); + + mfxStatus (MFX_CDECL *ENCFrameSubmit)(mfxHDL pthis, mfxENCInput *in, mfxENCOutput *out, mfxThreadTask *task); + + mfxHDL reserved1[3]; + mfxU32 reserved2[8]; +} mfxVideoCodecPlugin; + +typedef struct mfxAudioCodecPlugin{ + mfxStatus (MFX_CDECL *Query)(mfxHDL pthis, mfxAudioParam *in, mfxAudioParam *out); + mfxStatus (MFX_CDECL *QueryIOSize)(mfxHDL pthis, mfxAudioParam *par, mfxAudioAllocRequest *request); + mfxStatus (MFX_CDECL *Init)(mfxHDL pthis, mfxAudioParam *par); + mfxStatus (MFX_CDECL *Reset)(mfxHDL pthis, mfxAudioParam *par); + mfxStatus (MFX_CDECL *Close)(mfxHDL pthis); + mfxStatus (MFX_CDECL *GetAudioParam)(mfxHDL pthis, mfxAudioParam *par); + + mfxStatus (MFX_CDECL *EncodeFrameSubmit)(mfxHDL pthis, mfxAudioFrame *aFrame, mfxBitstream *out, mfxThreadTask *task); + + mfxStatus (MFX_CDECL *DecodeHeader)(mfxHDL pthis, mfxBitstream *bs, mfxAudioParam *par); +// mfxStatus (MFX_CDECL *GetPayload)(mfxHDL pthis, mfxU64 *ts, mfxPayload *payload); + mfxStatus (MFX_CDECL *DecodeFrameSubmit)(mfxHDL pthis, mfxBitstream *in, mfxAudioFrame *out, mfxThreadTask *task); + + mfxHDL reserved1[6]; + mfxU32 reserved2[8]; +} mfxAudioCodecPlugin; + +typedef struct mfxPlugin{ + mfxHDL pthis; + + mfxStatus (MFX_CDECL *PluginInit) (mfxHDL pthis, mfxCoreInterface *core); + mfxStatus (MFX_CDECL *PluginClose) (mfxHDL pthis); + + mfxStatus (MFX_CDECL *GetPluginParam)(mfxHDL pthis, mfxPluginParam *par); + + mfxStatus (MFX_CDECL *Submit)(mfxHDL pthis, const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxThreadTask *task); + mfxStatus (MFX_CDECL *Execute)(mfxHDL pthis, mfxThreadTask task, mfxU32 uid_p, mfxU32 uid_a); + mfxStatus (MFX_CDECL *FreeResources)(mfxHDL pthis, mfxThreadTask task, mfxStatus sts); + + union { + mfxVideoCodecPlugin *Video; + mfxAudioCodecPlugin *Audio; + }; + + mfxHDL reserved[8]; +} mfxPlugin; + + + +mfxStatus MFX_CDECL MFXVideoUSER_Register(mfxSession session, mfxU32 type, const mfxPlugin *par); +mfxStatus MFX_CDECL MFXVideoUSER_Unregister(mfxSession session, mfxU32 type); +mfxStatus MFX_CDECL MFXVideoUSER_ProcessFrameAsync(mfxSession session, const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp); + +mfxStatus MFX_CDECL MFXVideoUSER_Load(mfxSession session, const mfxPluginUID *uid, mfxU32 version); +mfxStatus MFX_CDECL MFXVideoUSER_LoadByPath(mfxSession session, const mfxPluginUID *uid, mfxU32 version, const mfxChar *path, mfxU32 len); +mfxStatus MFX_CDECL MFXVideoUSER_UnLoad(mfxSession session, const mfxPluginUID *uid); + +mfxStatus MFX_CDECL MFXAudioUSER_Register(mfxSession session, mfxU32 type, const mfxPlugin *par); +mfxStatus MFX_CDECL MFXAudioUSER_Unregister(mfxSession session, mfxU32 type); +mfxStatus MFX_CDECL MFXAudioUSER_ProcessFrameAsync(mfxSession session, const mfxHDL *in, mfxU32 in_num, const mfxHDL *out, mfxU32 out_num, mfxSyncPoint *syncp); + +mfxStatus MFX_CDECL MFXAudioUSER_Load(mfxSession session, const mfxPluginUID *uid, mfxU32 version); +mfxStatus MFX_CDECL MFXAudioUSER_UnLoad(mfxSession session, const mfxPluginUID *uid); + +#ifdef __cplusplus +} // extern "C" +#endif /* __cplusplus */ + +#endif /* __MFXPLUGIN_H__ */ diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxsession.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxsession.h new file mode 100644 index 0000000..e93c993 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxsession.h @@ -0,0 +1,60 @@ +/******************************************************************************* + +Copyright (C) 2013 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfxsession.h + +*******************************************************************************/ +#ifndef __MFXSESSION_H__ +#define __MFXSESSION_H__ +#include "mfxcommon.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Global Functions */ +typedef struct _mfxSession *mfxSession; +mfxStatus MFX_CDECL MFXInit(mfxIMPL impl, mfxVersion *ver, mfxSession *session); +mfxStatus MFX_CDECL MFXInitEx(mfxInitParam par, mfxSession *session); +mfxStatus MFX_CDECL MFXClose(mfxSession session); + +mfxStatus MFX_CDECL MFXQueryIMPL(mfxSession session, mfxIMPL *impl); +mfxStatus MFX_CDECL MFXQueryVersion(mfxSession session, mfxVersion *version); + +mfxStatus MFX_CDECL MFXJoinSession(mfxSession session, mfxSession child); +mfxStatus MFX_CDECL MFXDisjoinSession(mfxSession session); +mfxStatus MFX_CDECL MFXCloneSession(mfxSession session, mfxSession *clone); +mfxStatus MFX_CDECL MFXSetPriority(mfxSession session, mfxPriority priority); +mfxStatus MFX_CDECL MFXGetPriority(mfxSession session, mfxPriority *priority); +mfxStatus MFX_CDECL MFXDoWork(mfxSession session); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxstructures.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxstructures.h new file mode 100644 index 0000000..041157d --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxstructures.h @@ -0,0 +1,1379 @@ +/******************************************************************************* *\ + +Copyright (C) 2007-2015 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfxstructures.h + +*******************************************************************************/ +#ifndef __MFXSTRUCTURES_H__ +#define __MFXSTRUCTURES_H__ +#include "mfxcommon.h" + +#if !defined (__GNUC__) +#pragma warning(disable: 4201) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Frame ID for SVC and MVC */ +typedef struct { + mfxU16 TemporalId; + mfxU16 PriorityId; + union { + struct { + mfxU16 DependencyId; + mfxU16 QualityId; + }; + struct { + mfxU16 ViewId; + }; + }; +} mfxFrameId; + +#pragma pack(push, 4) +/* Frame Info */ +typedef struct { + mfxU32 reserved[4]; + mfxU16 reserved4; + mfxU16 BitDepthLuma; + mfxU16 BitDepthChroma; + mfxU16 Shift; + + mfxFrameId FrameId; + + mfxU32 FourCC; + union { + struct { /* Frame parameters */ + mfxU16 Width; + mfxU16 Height; + + mfxU16 CropX; + mfxU16 CropY; + mfxU16 CropW; + mfxU16 CropH; + }; + struct { /* Buffer parameters (for plain formats like P8) */ + mfxU64 BufferSize; + mfxU32 reserved5; + }; + }; + + mfxU32 FrameRateExtN; + mfxU32 FrameRateExtD; + mfxU16 reserved3; + + mfxU16 AspectRatioW; + mfxU16 AspectRatioH; + + mfxU16 PicStruct; + mfxU16 ChromaFormat; + mfxU16 reserved2; +} mfxFrameInfo; +#pragma pack(pop) + +/* FourCC */ +enum { + MFX_FOURCC_NV12 = MFX_MAKEFOURCC('N','V','1','2'), /* Native Format */ + MFX_FOURCC_YV12 = MFX_MAKEFOURCC('Y','V','1','2'), + MFX_FOURCC_NV16 = MFX_MAKEFOURCC('N','V','1','6'), + MFX_FOURCC_YUY2 = MFX_MAKEFOURCC('Y','U','Y','2'), + MFX_FOURCC_RGB3 = MFX_MAKEFOURCC('R','G','B','3'), /* deprecated */ + MFX_FOURCC_RGB4 = MFX_MAKEFOURCC('R','G','B','4'), /* ARGB in that order, A channel is 8 MSBs */ + MFX_FOURCC_P8 = 41, /* D3DFMT_P8 */ + MFX_FOURCC_P8_TEXTURE = MFX_MAKEFOURCC('P','8','M','B'), + MFX_FOURCC_P010 = MFX_MAKEFOURCC('P','0','1','0'), + MFX_FOURCC_P210 = MFX_MAKEFOURCC('P','2','1','0'), + MFX_FOURCC_BGR4 = MFX_MAKEFOURCC('B','G','R','4'), /* ABGR in that order, A channel is 8 MSBs */ + MFX_FOURCC_A2RGB10 = MFX_MAKEFOURCC('R','G','1','0'), /* ARGB in that order, A channel is two MSBs */ + MFX_FOURCC_ARGB16 = MFX_MAKEFOURCC('R','G','1','6'), /* ARGB in that order, 64 bits, A channel is 16 MSBs */ + MFX_FOURCC_ABGR16 = MFX_MAKEFOURCC('B','G','1','6'), /* ABGR in that order, 64 bits, A channel is 16 MSBs */ + MFX_FOURCC_R16 = MFX_MAKEFOURCC('R','1','6','U'), + MFX_FOURCC_AYUV = MFX_MAKEFOURCC('A','Y','U','V'), /* YUV 4:4:4, AYUV in that order, A channel is 8 MSBs */ + MFX_FOURCC_AYUV_RGB4 = MFX_MAKEFOURCC('A','V','U','Y'), /* ARGB in that order, A channel is 8 MSBs stored in AYUV surface*/ + MFX_FOURCC_UYVY = MFX_MAKEFOURCC('U','Y','V','Y') +}; + +/* PicStruct */ +enum { + MFX_PICSTRUCT_UNKNOWN =0x00, + MFX_PICSTRUCT_PROGRESSIVE =0x01, + MFX_PICSTRUCT_FIELD_TFF =0x02, + MFX_PICSTRUCT_FIELD_BFF =0x04, + + MFX_PICSTRUCT_FIELD_REPEATED=0x10, /* first field repeated, pic_struct=5 or 6 in H.264 */ + MFX_PICSTRUCT_FRAME_DOUBLING=0x20, /* pic_struct=7 in H.264 */ + MFX_PICSTRUCT_FRAME_TRIPLING=0x40 /* pic_struct=8 in H.264 */ +}; + +/* ColorFormat */ +enum { + MFX_CHROMAFORMAT_MONOCHROME =0, + MFX_CHROMAFORMAT_YUV420 =1, + MFX_CHROMAFORMAT_YUV422 =2, + MFX_CHROMAFORMAT_YUV444 =3, + MFX_CHROMAFORMAT_YUV400 = MFX_CHROMAFORMAT_MONOCHROME, + MFX_CHROMAFORMAT_YUV411 = 4, + MFX_CHROMAFORMAT_YUV422H = MFX_CHROMAFORMAT_YUV422, + MFX_CHROMAFORMAT_YUV422V = 5 +}; + +enum { + MFX_TIMESTAMP_UNKNOWN = -1 +}; + +enum { + MFX_FRAMEORDER_UNKNOWN = -1 +}; + +/* DataFlag in mfxFrameData */ +enum { + MFX_FRAMEDATA_ORIGINAL_TIMESTAMP = 0x0001 +}; + +/* Corrupted in mfxFrameData */ +enum { + MFX_CORRUPTION_MINOR = 0x0001, + MFX_CORRUPTION_MAJOR = 0x0002, + MFX_CORRUPTION_ABSENT_TOP_FIELD = 0x0004, + MFX_CORRUPTION_ABSENT_BOTTOM_FIELD = 0x0008, + MFX_CORRUPTION_REFERENCE_FRAME = 0x0010, + MFX_CORRUPTION_REFERENCE_LIST = 0x0020 +}; + +/* Frame Data Info */ +typedef struct { + union { + mfxExtBuffer **ExtParam; + mfxU64 reserved2; + }; + mfxU16 NumExtParam; + + mfxU16 reserved[10]; + mfxU16 PitchHigh; + + mfxU64 TimeStamp; + mfxU32 FrameOrder; + mfxU16 Locked; + union{ + mfxU16 Pitch; + mfxU16 PitchLow; + }; + + /* color planes */ + union { + mfxU8 *Y; + mfxU16 *Y16; + mfxU8 *R; + }; + union { + mfxU8 *UV; /* for UV merged formats */ + mfxU8 *VU; /* for VU merged formats */ + mfxU8 *CbCr; /* for CbCr merged formats */ + mfxU8 *CrCb; /* for CrCb merged formats */ + mfxU8 *Cb; + mfxU8 *U; + mfxU16 *U16; + mfxU8 *G; + }; + union { + mfxU8 *Cr; + mfxU8 *V; + mfxU16 *V16; + mfxU8 *B; + }; + mfxU8 *A; + mfxMemId MemId; + + /* Additional Flags */ + mfxU16 Corrupted; + mfxU16 DataFlag; +} mfxFrameData; + +/* Frame Surface */ +typedef struct { + mfxU32 reserved[4]; + mfxFrameInfo Info; + mfxFrameData Data; +} mfxFrameSurface1; + +enum { + MFX_TIMESTAMPCALC_UNKNOWN = 0, + MFX_TIMESTAMPCALC_TELECINE = 1, +}; + +/* Transcoding Info */ +typedef struct { + mfxU32 reserved[7]; + + mfxU16 LowPower; + mfxU16 BRCParamMultiplier; + + mfxFrameInfo FrameInfo; + mfxU32 CodecId; + mfxU16 CodecProfile; + mfxU16 CodecLevel; + mfxU16 NumThread; + + union { + struct { /* MPEG-2/H.264 Encoding Options */ + mfxU16 TargetUsage; + + mfxU16 GopPicSize; + mfxU16 GopRefDist; + mfxU16 GopOptFlag; + mfxU16 IdrInterval; + + mfxU16 RateControlMethod; + union { + mfxU16 InitialDelayInKB; + mfxU16 QPI; + mfxU16 Accuracy; + }; + mfxU16 BufferSizeInKB; + union { + mfxU16 TargetKbps; + mfxU16 QPP; + mfxU16 ICQQuality; + }; + union { + mfxU16 MaxKbps; + mfxU16 QPB; + mfxU16 Convergence; + }; + + mfxU16 NumSlice; + mfxU16 NumRefFrame; + mfxU16 EncodedOrder; + }; + struct { /* H.264, MPEG-2 and VC-1 Decoding Options */ + mfxU16 DecodedOrder; + mfxU16 ExtendedPicStruct; + mfxU16 TimeStampCalc; + mfxU16 SliceGroupsPresent; + mfxU16 MaxDecFrameBuffering; + mfxU16 reserved2[8]; + }; + struct { /* JPEG Decoding Options */ + mfxU16 JPEGChromaFormat; + mfxU16 Rotation; + mfxU16 JPEGColorFormat; + mfxU16 InterleavedDec; + mfxU16 reserved3[9]; + }; + struct { /* JPEG Encoding Options */ + mfxU16 Interleaved; + mfxU16 Quality; + mfxU16 RestartInterval; + mfxU16 reserved5[10]; + }; + }; +} mfxInfoMFX; + +typedef struct { + mfxU32 reserved[8]; + mfxFrameInfo In; + mfxFrameInfo Out; +} mfxInfoVPP; + +typedef struct { + mfxU32 AllocId; + mfxU32 reserved[2]; + mfxU16 reserved3; + mfxU16 AsyncDepth; + + union { + mfxInfoMFX mfx; + mfxInfoVPP vpp; + }; + mfxU16 Protected; + mfxU16 IOPattern; + mfxExtBuffer** ExtParam; + mfxU16 NumExtParam; + mfxU16 reserved2; +} mfxVideoParam; + +/* IOPattern */ +enum { + MFX_IOPATTERN_IN_VIDEO_MEMORY = 0x01, + MFX_IOPATTERN_IN_SYSTEM_MEMORY = 0x02, + MFX_IOPATTERN_IN_OPAQUE_MEMORY = 0x04, + MFX_IOPATTERN_OUT_VIDEO_MEMORY = 0x10, + MFX_IOPATTERN_OUT_SYSTEM_MEMORY = 0x20, + MFX_IOPATTERN_OUT_OPAQUE_MEMORY = 0x40 +}; + +/* CodecId */ +enum { + MFX_CODEC_AVC =MFX_MAKEFOURCC('A','V','C',' '), + MFX_CODEC_HEVC =MFX_MAKEFOURCC('H','E','V','C'), + MFX_CODEC_MPEG2 =MFX_MAKEFOURCC('M','P','G','2'), + MFX_CODEC_VC1 =MFX_MAKEFOURCC('V','C','1',' '), + MFX_CODEC_CAPTURE =MFX_MAKEFOURCC('C','A','P','T') +}; + +/* CodecProfile, CodecLevel */ +enum { + MFX_PROFILE_UNKNOWN =0, + MFX_LEVEL_UNKNOWN =0, + + /* AVC Profiles & Levels */ + MFX_PROFILE_AVC_CONSTRAINT_SET0 = (0x100 << 0), + MFX_PROFILE_AVC_CONSTRAINT_SET1 = (0x100 << 1), + MFX_PROFILE_AVC_CONSTRAINT_SET2 = (0x100 << 2), + MFX_PROFILE_AVC_CONSTRAINT_SET3 = (0x100 << 3), + MFX_PROFILE_AVC_CONSTRAINT_SET4 = (0x100 << 4), + MFX_PROFILE_AVC_CONSTRAINT_SET5 = (0x100 << 5), + + MFX_PROFILE_AVC_BASELINE =66, + MFX_PROFILE_AVC_MAIN =77, + MFX_PROFILE_AVC_EXTENDED =88, + MFX_PROFILE_AVC_HIGH =100, + MFX_PROFILE_AVC_HIGH_422 =122, + MFX_PROFILE_AVC_CONSTRAINED_BASELINE =MFX_PROFILE_AVC_BASELINE + MFX_PROFILE_AVC_CONSTRAINT_SET1, + MFX_PROFILE_AVC_CONSTRAINED_HIGH =MFX_PROFILE_AVC_HIGH + MFX_PROFILE_AVC_CONSTRAINT_SET4 + + MFX_PROFILE_AVC_CONSTRAINT_SET5, + MFX_PROFILE_AVC_PROGRESSIVE_HIGH =MFX_PROFILE_AVC_HIGH + MFX_PROFILE_AVC_CONSTRAINT_SET4, + + MFX_LEVEL_AVC_1 =10, + MFX_LEVEL_AVC_1b =9, + MFX_LEVEL_AVC_11 =11, + MFX_LEVEL_AVC_12 =12, + MFX_LEVEL_AVC_13 =13, + MFX_LEVEL_AVC_2 =20, + MFX_LEVEL_AVC_21 =21, + MFX_LEVEL_AVC_22 =22, + MFX_LEVEL_AVC_3 =30, + MFX_LEVEL_AVC_31 =31, + MFX_LEVEL_AVC_32 =32, + MFX_LEVEL_AVC_4 =40, + MFX_LEVEL_AVC_41 =41, + MFX_LEVEL_AVC_42 =42, + MFX_LEVEL_AVC_5 =50, + MFX_LEVEL_AVC_51 =51, + MFX_LEVEL_AVC_52 =52, + + /* MPEG-2 Profiles & Levels */ + MFX_PROFILE_MPEG2_SIMPLE =0x50, + MFX_PROFILE_MPEG2_MAIN =0x40, + MFX_PROFILE_MPEG2_HIGH =0x10, + + MFX_LEVEL_MPEG2_LOW =0xA, + MFX_LEVEL_MPEG2_MAIN =0x8, + MFX_LEVEL_MPEG2_HIGH =0x4, + MFX_LEVEL_MPEG2_HIGH1440 =0x6, + + /* VC1 Profiles & Levels */ + MFX_PROFILE_VC1_SIMPLE =(0+1), + MFX_PROFILE_VC1_MAIN =(4+1), + MFX_PROFILE_VC1_ADVANCED =(12+1), + + /* VC1 levels for simple & main profiles */ + MFX_LEVEL_VC1_LOW =(0+1), + MFX_LEVEL_VC1_MEDIAN =(2+1), + MFX_LEVEL_VC1_HIGH =(4+1), + + /* VC1 levels for the advanced profile */ + MFX_LEVEL_VC1_0 =(0x00+1), + MFX_LEVEL_VC1_1 =(0x01+1), + MFX_LEVEL_VC1_2 =(0x02+1), + MFX_LEVEL_VC1_3 =(0x03+1), + MFX_LEVEL_VC1_4 =(0x04+1), + + /* HEVC Profiles & Levels & Tiers */ + MFX_PROFILE_HEVC_MAIN =1, + MFX_PROFILE_HEVC_MAIN10 =2, + MFX_PROFILE_HEVC_MAINSP =3, + MFX_PROFILE_HEVC_REXT =4, + + MFX_LEVEL_HEVC_1 = 10, + MFX_LEVEL_HEVC_2 = 20, + MFX_LEVEL_HEVC_21 = 21, + MFX_LEVEL_HEVC_3 = 30, + MFX_LEVEL_HEVC_31 = 31, + MFX_LEVEL_HEVC_4 = 40, + MFX_LEVEL_HEVC_41 = 41, + MFX_LEVEL_HEVC_5 = 50, + MFX_LEVEL_HEVC_51 = 51, + MFX_LEVEL_HEVC_52 = 52, + MFX_LEVEL_HEVC_6 = 60, + MFX_LEVEL_HEVC_61 = 61, + MFX_LEVEL_HEVC_62 = 62, + + MFX_TIER_HEVC_MAIN = 0, + MFX_TIER_HEVC_HIGH = 0x100, +}; + +/* GopOptFlag */ +enum { + MFX_GOP_CLOSED =1, + MFX_GOP_STRICT =2 +}; + +/* TargetUsages: from 1 to 7 inclusive */ +enum { + MFX_TARGETUSAGE_1 =1, + MFX_TARGETUSAGE_2 =2, + MFX_TARGETUSAGE_3 =3, + MFX_TARGETUSAGE_4 =4, + MFX_TARGETUSAGE_5 =5, + MFX_TARGETUSAGE_6 =6, + MFX_TARGETUSAGE_7 =7, + + MFX_TARGETUSAGE_UNKNOWN =0, + MFX_TARGETUSAGE_BEST_QUALITY =MFX_TARGETUSAGE_1, + MFX_TARGETUSAGE_BALANCED =MFX_TARGETUSAGE_4, + MFX_TARGETUSAGE_BEST_SPEED =MFX_TARGETUSAGE_7 +}; + +/* RateControlMethod */ +enum { + MFX_RATECONTROL_CBR =1, + MFX_RATECONTROL_VBR =2, + MFX_RATECONTROL_CQP =3, + MFX_RATECONTROL_AVBR =4, + MFX_RATECONTROL_RESERVED1 =5, + MFX_RATECONTROL_RESERVED2 =6, + MFX_RATECONTROL_RESERVED3 =100, + MFX_RATECONTROL_RESERVED4 =7, + MFX_RATECONTROL_LA =8, + MFX_RATECONTROL_ICQ =9, + MFX_RATECONTROL_VCM =10, + MFX_RATECONTROL_LA_ICQ =11, + MFX_RATECONTROL_LA_EXT =12, + MFX_RATECONTROL_LA_HRD =13, + MFX_RATECONTROL_QVBR =14 +}; + +/* Trellis control*/ +enum { + MFX_TRELLIS_UNKNOWN =0, + MFX_TRELLIS_OFF =0x01, + MFX_TRELLIS_I =0x02, + MFX_TRELLIS_P =0x04, + MFX_TRELLIS_B =0x08 +}; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 reserved1; + mfxU16 RateDistortionOpt; /* tri-state option */ + mfxU16 MECostType; + mfxU16 MESearchType; + mfxI16Pair MVSearchWindow; + mfxU16 EndOfSequence; /* tri-state option */ + mfxU16 FramePicture; /* tri-state option */ + + mfxU16 CAVLC; /* tri-state option */ + mfxU16 reserved2[2]; + mfxU16 RecoveryPointSEI; /* tri-state option */ + mfxU16 ViewOutput; /* tri-state option */ + mfxU16 NalHrdConformance; /* tri-state option */ + mfxU16 SingleSeiNalUnit; /* tri-state option */ + mfxU16 VuiVclHrdParameters; /* tri-state option */ + + mfxU16 RefPicListReordering; /* tri-state option */ + mfxU16 ResetRefList; /* tri-state option */ + mfxU16 RefPicMarkRep; /* tri-state option */ + mfxU16 FieldOutput; /* tri-state option */ + + mfxU16 IntraPredBlockSize; + mfxU16 InterPredBlockSize; + mfxU16 MVPrecision; + mfxU16 MaxDecFrameBuffering; + + mfxU16 AUDelimiter; /* tri-state option */ + mfxU16 EndOfStream; /* tri-state option */ + mfxU16 PicTimingSEI; /* tri-state option */ + mfxU16 VuiNalHrdParameters; /* tri-state option */ +} mfxExtCodingOption; + +enum { + MFX_B_REF_UNKNOWN = 0, + MFX_B_REF_OFF = 1, + MFX_B_REF_PYRAMID = 2 +}; + +enum { + MFX_LOOKAHEAD_DS_UNKNOWN = 0, + MFX_LOOKAHEAD_DS_OFF = 1, + MFX_LOOKAHEAD_DS_2x = 2, + MFX_LOOKAHEAD_DS_4x = 3 +}; + +enum { + MFX_BPSEI_DEFAULT = 0x00, + MFX_BPSEI_IFRAME = 0x01 +}; + +enum { + MFX_SKIPFRAME_NO_SKIP = 0, + MFX_SKIPFRAME_INSERT_DUMMY = 1, + MFX_SKIPFRAME_INSERT_NOTHING = 2, + MFX_SKIPFRAME_BRC_ONLY = 3, +}; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 IntRefType; + mfxU16 IntRefCycleSize; + mfxI16 IntRefQPDelta; + + mfxU32 MaxFrameSize; + mfxU32 MaxSliceSize; + + mfxU16 BitrateLimit; /* tri-state option */ + mfxU16 MBBRC; /* tri-state option */ + mfxU16 ExtBRC; /* tri-state option */ + mfxU16 LookAheadDepth; + mfxU16 Trellis; + mfxU16 RepeatPPS; /* tri-state option */ + mfxU16 BRefType; + mfxU16 AdaptiveI; /* tri-state option */ + mfxU16 AdaptiveB; /* tri-state option */ + mfxU16 LookAheadDS; + mfxU16 NumMbPerSlice; + mfxU16 SkipFrame; + mfxU8 MinQPI; /* 1..51, 0 = default */ + mfxU8 MaxQPI; /* 1..51, 0 = default */ + mfxU8 MinQPP; /* 1..51, 0 = default */ + mfxU8 MaxQPP; /* 1..51, 0 = default */ + mfxU8 MinQPB; /* 1..51, 0 = default */ + mfxU8 MaxQPB; /* 1..51, 0 = default */ + mfxU16 FixedFrameRate; /* tri-state option */ + mfxU16 DisableDeblockingIdc; + mfxU16 DisableVUI; + mfxU16 BufferingPeriodSEI; + mfxU16 EnableMAD; /* tri-state option */ + mfxU16 UseRawRef; /* tri-state option */ +} mfxExtCodingOption2; + +/* WeightedPred */ +enum { + MFX_WEIGHTED_PRED_UNKNOWN = 0, + MFX_WEIGHTED_PRED_DEFAULT = 1, + MFX_WEIGHTED_PRED_EXPLICIT = 2, + MFX_WEIGHTED_PRED_IMPLICIT = 3 +}; + +/* ScenarioInfo */ +enum { + MFX_SCENARIO_UNKNOWN = 0, + MFX_SCENARIO_DISPLAY_REMOTING = 1, + MFX_SCENARIO_VIDEO_CONFERENCE = 2, + MFX_SCENARIO_ARCHIVE = 3, + MFX_SCENARIO_LIVE_STREAMING = 4, + MFX_SCENARIO_CAMERA_CAPTURE = 5 +}; + +/* ContentInfo */ +enum { + MFX_CONTENT_UNKNOWN = 0, + MFX_CONTENT_FULL_SCREEN_VIDEO = 1, + MFX_CONTENT_NON_VIDEO_SCREEN = 2 +}; + +/* PRefType */ +enum { + MFX_P_REF_DEFAULT = 0, + MFX_P_REF_SIMPLE = 1, + MFX_P_REF_PYRAMID = 2 +}; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 NumSliceI; + mfxU16 NumSliceP; + mfxU16 NumSliceB; + + mfxU16 WinBRCMaxAvgKbps; + mfxU16 WinBRCSize; + + mfxU16 QVBRQuality; + mfxU16 EnableMBQP; + mfxU16 IntRefCycleDist; + mfxU16 DirectBiasAdjustment; /* tri-state option */ + mfxU16 GlobalMotionBiasAdjustment; /* tri-state option */ + mfxU16 MVCostScalingFactor; + mfxU16 MBDisableSkipMap; /* tri-state option */ + + mfxU16 WeightedPred; + mfxU16 WeightedBiPred; + + mfxU16 AspectRatioInfoPresent; /* tri-state option */ + mfxU16 OverscanInfoPresent; /* tri-state option */ + mfxU16 OverscanAppropriate; /* tri-state option */ + mfxU16 TimingInfoPresent; /* tri-state option */ + mfxU16 BitstreamRestriction; /* tri-state option */ + mfxU16 reserved1[4]; + + mfxU16 ScenarioInfo; + mfxU16 ContentInfo; + + mfxU16 PRefType; + mfxU16 FadeDetection; /* tri-state option */ + mfxU16 reserved[225]; +} mfxExtCodingOption3; + +/* IntraPredBlockSize/InterPredBlockSize */ +enum { + MFX_BLOCKSIZE_UNKNOWN = 0, + MFX_BLOCKSIZE_MIN_16X16 = 1, /* 16x16 */ + MFX_BLOCKSIZE_MIN_8X8 = 2, /* 16x16, 8x8 */ + MFX_BLOCKSIZE_MIN_4X4 = 3 /* 16x16, 8x8, 4x4 */ +}; + +/* MVPrecision */ +enum { + MFX_MVPRECISION_UNKNOWN = 0, + MFX_MVPRECISION_INTEGER = (1 << 0), + MFX_MVPRECISION_HALFPEL = (1 << 1), + MFX_MVPRECISION_QUARTERPEL = (1 << 2) +}; + +enum { + MFX_CODINGOPTION_UNKNOWN =0, + MFX_CODINGOPTION_ON =0x10, + MFX_CODINGOPTION_OFF =0x20, + MFX_CODINGOPTION_ADAPTIVE =0x30 +}; + +/* Data Flag for mfxBitstream*/ +enum { + MFX_BITSTREAM_COMPLETE_FRAME = 0x0001, /* the bitstream contains a complete frame or field pair of data */ + MFX_BITSTREAM_EOS = 0x0002 +}; + +/* Extended Buffer Ids */ +enum { + MFX_EXTBUFF_CODING_OPTION = MFX_MAKEFOURCC('C','D','O','P'), + MFX_EXTBUFF_CODING_OPTION_SPSPPS = MFX_MAKEFOURCC('C','O','S','P'), + MFX_EXTBUFF_VPP_DONOTUSE = MFX_MAKEFOURCC('N','U','S','E'), + MFX_EXTBUFF_VPP_AUXDATA = MFX_MAKEFOURCC('A','U','X','D'), + MFX_EXTBUFF_VPP_DENOISE = MFX_MAKEFOURCC('D','N','I','S'), + MFX_EXTBUFF_VPP_SCENE_ANALYSIS = MFX_MAKEFOURCC('S','C','L','Y'), + MFX_EXTBUFF_VPP_SCENE_CHANGE = MFX_EXTBUFF_VPP_SCENE_ANALYSIS, + MFX_EXTBUFF_VPP_PROCAMP = MFX_MAKEFOURCC('P','A','M','P'), + MFX_EXTBUFF_VPP_DETAIL = MFX_MAKEFOURCC('D','E','T',' '), + MFX_EXTBUFF_VIDEO_SIGNAL_INFO = MFX_MAKEFOURCC('V','S','I','N'), + MFX_EXTBUFF_VPP_DOUSE = MFX_MAKEFOURCC('D','U','S','E'), + MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION = MFX_MAKEFOURCC('O','P','Q','S'), + MFX_EXTBUFF_AVC_REFLIST_CTRL = MFX_MAKEFOURCC('R','L','S','T'), + MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION = MFX_MAKEFOURCC('F','R','C',' '), + MFX_EXTBUFF_PICTURE_TIMING_SEI = MFX_MAKEFOURCC('P','T','S','E'), + MFX_EXTBUFF_AVC_TEMPORAL_LAYERS = MFX_MAKEFOURCC('A','T','M','L'), + MFX_EXTBUFF_CODING_OPTION2 = MFX_MAKEFOURCC('C','D','O','2'), + MFX_EXTBUFF_VPP_IMAGE_STABILIZATION = MFX_MAKEFOURCC('I','S','T','B'), + MFX_EXTBUFF_VPP_PICSTRUCT_DETECTION = MFX_MAKEFOURCC('I','D','E','T'), + MFX_EXTBUFF_ENCODER_CAPABILITY = MFX_MAKEFOURCC('E','N','C','P'), + MFX_EXTBUFF_ENCODER_RESET_OPTION = MFX_MAKEFOURCC('E','N','R','O'), + MFX_EXTBUFF_ENCODED_FRAME_INFO = MFX_MAKEFOURCC('E','N','F','I'), + MFX_EXTBUFF_VPP_COMPOSITE = MFX_MAKEFOURCC('V','C','M','P'), + MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO = MFX_MAKEFOURCC('V','V','S','I'), + MFX_EXTBUFF_ENCODER_ROI = MFX_MAKEFOURCC('E','R','O','I'), + MFX_EXTBUFF_VPP_DEINTERLACING = MFX_MAKEFOURCC('V','P','D','I'), + MFX_EXTBUFF_AVC_REFLISTS = MFX_MAKEFOURCC('R','L','T','S'), + MFX_EXTBUFF_VPP_FIELD_PROCESSING = MFX_MAKEFOURCC('F','P','R','O'), + MFX_EXTBUFF_CODING_OPTION3 = MFX_MAKEFOURCC('C','D','O','3'), + MFX_EXTBUFF_CHROMA_LOC_INFO = MFX_MAKEFOURCC('C','L','I','N'), + MFX_EXTBUFF_MBQP = MFX_MAKEFOURCC('M','B','Q','P'), + MFX_EXTBUFF_HEVC_TILES = MFX_MAKEFOURCC('2','6','5','T'), + MFX_EXTBUFF_MB_DISABLE_SKIP_MAP = MFX_MAKEFOURCC('M','D','S','M'), + MFX_EXTBUFF_HEVC_PARAM = MFX_MAKEFOURCC('2','6','5','P'), + MFX_EXTBUFF_DECODED_FRAME_INFO = MFX_MAKEFOURCC('D','E','F','I'), + MFX_EXTBUFF_TIME_CODE = MFX_MAKEFOURCC('T','M','C','D'), + MFX_EXTBUFF_HEVC_REGION = MFX_MAKEFOURCC('2','6','5','R'), + MFX_EXTBUFF_PRED_WEIGHT_TABLE = MFX_MAKEFOURCC('E','P','W','T'), + MFX_EXTBUFF_DIRTY_RECTANGLES = MFX_MAKEFOURCC('D','R','O','I'), + MFX_EXTBUFF_MOVING_RECTANGLES = MFX_MAKEFOURCC('M','R','O','I'), + MFX_EXTBUFF_CODING_OPTION_VPS = MFX_MAKEFOURCC('C','O','V','P'), + MFX_EXTBUFF_VPP_ROTATION = MFX_MAKEFOURCC('R','O','T',' ') +}; + +/* VPP Conf: Do not use certain algorithms */ +typedef struct { + mfxExtBuffer Header; + mfxU32 NumAlg; + mfxU32* AlgList; +} mfxExtVPPDoNotUse; + +typedef struct { + mfxExtBuffer Header; + mfxU16 DenoiseFactor; +} mfxExtVPPDenoise; + +typedef struct { + mfxExtBuffer Header; + mfxU16 DetailFactor; +} mfxExtVPPDetail; + +typedef struct { + mfxExtBuffer Header; + mfxF64 Brightness; + mfxF64 Contrast; + mfxF64 Hue; + mfxF64 Saturation; +} mfxExtVPPProcAmp; + +/* statistics collected for decode, encode and vpp */ +typedef struct { + mfxU32 reserved[16]; + mfxU32 NumFrame; + mfxU64 NumBit; + mfxU32 NumCachedFrame; +} mfxEncodeStat; + +typedef struct { + mfxU32 reserved[16]; + mfxU32 NumFrame; + mfxU32 NumSkippedFrame; + mfxU32 NumError; + mfxU32 NumCachedFrame; +} mfxDecodeStat; + +typedef struct { + mfxU32 reserved[16]; + mfxU32 NumFrame; + mfxU32 NumCachedFrame; +} mfxVPPStat; + +typedef struct { + mfxExtBuffer Header; + + union{ + struct{ + mfxU32 SpatialComplexity; + mfxU32 TemporalComplexity; + }; + struct{ + mfxU16 PicStruct; + mfxU16 reserved[3]; + }; + }; + mfxU16 SceneChangeRate; + mfxU16 RepeatedFrame; +} mfxExtVppAuxData; + +typedef struct { + mfxU32 reserved[4]; + mfxU8 *Data; /* buffer pointer */ + mfxU32 NumBit; /* number of bits */ + mfxU16 Type; /* SEI message type in H.264 or user data start_code in MPEG-2 */ + mfxU16 BufSize; /* payload buffer size in bytes */ +} mfxPayload; + +typedef struct { + mfxExtBuffer Header; + mfxU32 reserved[5]; + mfxU16 SkipFrame; + + mfxU16 QP; /* per frame QP */ + + mfxU16 FrameType; + mfxU16 NumExtParam; + mfxU16 NumPayload; /* MPEG-2 user data or H.264 SEI message(s) */ + mfxU16 reserved2; + + mfxExtBuffer **ExtParam; + mfxPayload **Payload; /* for field pair, first field uses even payloads and second field uses odd payloads */ +} mfxEncodeCtrl; + +/* Buffer Memory Types */ +enum { + /* Buffer types */ + MFX_MEMTYPE_PERSISTENT_MEMORY =0x0002 +}; + +/* Frame Memory Types */ +#define MFX_MEMTYPE_BASE(x) (0xf0ff & (x)) + +enum { + MFX_MEMTYPE_DXVA2_DECODER_TARGET =0x0010, + MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET =0x0020, + MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET = MFX_MEMTYPE_DXVA2_DECODER_TARGET, + MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET = MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET, + MFX_MEMTYPE_SYSTEM_MEMORY =0x0040, + MFX_MEMTYPE_RESERVED1 =0x0080, + + MFX_MEMTYPE_FROM_ENCODE = 0x0100, + MFX_MEMTYPE_FROM_DECODE = 0x0200, + MFX_MEMTYPE_FROM_VPPIN = 0x0400, + MFX_MEMTYPE_FROM_VPPOUT = 0x0800, + + MFX_MEMTYPE_INTERNAL_FRAME = 0x0001, + MFX_MEMTYPE_EXTERNAL_FRAME = 0x0002, + MFX_MEMTYPE_OPAQUE_FRAME = 0x0004, + MFX_MEMTYPE_EXPORT_FRAME = 0x0008, + + MFX_MEMTYPE_RESERVED2 = 0x1000 +}; + +typedef struct { + union { + mfxU32 AllocId; + mfxU32 reserved[1]; + }; + mfxU32 reserved3[3]; + mfxFrameInfo Info; + mfxU16 Type; /* decoder or processor render targets */ + mfxU16 NumFrameMin; + mfxU16 NumFrameSuggested; + mfxU16 reserved2; +} mfxFrameAllocRequest; + +typedef struct { + mfxU32 AllocId; + mfxU32 reserved[3]; + mfxMemId *mids; /* the array allocated by application */ + mfxU16 NumFrameActual; + mfxU16 reserved2; +} mfxFrameAllocResponse; + +/* FrameType */ +enum { + MFX_FRAMETYPE_UNKNOWN =0x0000, + + MFX_FRAMETYPE_I =0x0001, + MFX_FRAMETYPE_P =0x0002, + MFX_FRAMETYPE_B =0x0004, + MFX_FRAMETYPE_S =0x0008, + + MFX_FRAMETYPE_REF =0x0040, + MFX_FRAMETYPE_IDR =0x0080, + + MFX_FRAMETYPE_xI =0x0100, + MFX_FRAMETYPE_xP =0x0200, + MFX_FRAMETYPE_xB =0x0400, + MFX_FRAMETYPE_xS =0x0800, + + MFX_FRAMETYPE_xREF =0x4000, + MFX_FRAMETYPE_xIDR =0x8000 +}; + +typedef enum { + MFX_HANDLE_DIRECT3D_DEVICE_MANAGER9 =1, /* IDirect3DDeviceManager9 */ + MFX_HANDLE_D3D9_DEVICE_MANAGER = MFX_HANDLE_DIRECT3D_DEVICE_MANAGER9, + MFX_HANDLE_RESERVED1 = 2, + MFX_HANDLE_D3D11_DEVICE = 3, + MFX_HANDLE_VA_DISPLAY = 4, + MFX_HANDLE_RESERVED3 = 5 +} mfxHandleType; + +typedef enum { + MFX_SKIPMODE_NOSKIP=0, + MFX_SKIPMODE_MORE=1, + MFX_SKIPMODE_LESS=2 +} mfxSkipMode; + +typedef struct { + mfxExtBuffer Header; + mfxU8 *SPSBuffer; + mfxU8 *PPSBuffer; + mfxU16 SPSBufSize; + mfxU16 PPSBufSize; + mfxU16 SPSId; + mfxU16 PPSId; +} mfxExtCodingOptionSPSPPS; + +typedef struct { + mfxExtBuffer Header; + + union { + mfxU8 *VPSBuffer; + mfxU64 reserved1; + }; + mfxU16 VPSBufSize; + mfxU16 VPSId; + + mfxU16 reserved[6]; +} mfxExtCodingOptionVPS; + +typedef struct { + mfxExtBuffer Header; + mfxU16 VideoFormat; + mfxU16 VideoFullRange; + mfxU16 ColourDescriptionPresent; + mfxU16 ColourPrimaries; + mfxU16 TransferCharacteristics; + mfxU16 MatrixCoefficients; +} mfxExtVideoSignalInfo; + +typedef struct { + mfxExtBuffer Header; + mfxU32 NumAlg; + mfxU32 *AlgList; +} mfxExtVPPDoUse; + +typedef struct { + mfxExtBuffer Header; + mfxU32 reserved1[2]; + struct { + mfxFrameSurface1 **Surfaces; + mfxU32 reserved2[5]; + mfxU16 Type; + mfxU16 NumSurface; + } In, Out; +} mfxExtOpaqueSurfaceAlloc; + +typedef struct { + mfxExtBuffer Header; + mfxU16 NumRefIdxL0Active; + mfxU16 NumRefIdxL1Active; + + struct { + mfxU32 FrameOrder; + mfxU16 PicStruct; + mfxU16 ViewId; + mfxU16 LongTermIdx; + mfxU16 reserved[3]; + } PreferredRefList[32], RejectedRefList[16], LongTermRefList[16]; + + mfxU16 ApplyLongTermIdx; + mfxU16 reserved[15]; +} mfxExtAVCRefListCtrl; + +enum { + MFX_FRCALGM_PRESERVE_TIMESTAMP = 0x0001, + MFX_FRCALGM_DISTRIBUTED_TIMESTAMP = 0x0002, + MFX_FRCALGM_FRAME_INTERPOLATION = 0x0004 +}; + +typedef struct { + mfxExtBuffer Header; + mfxU16 Algorithm; + mfxU16 reserved; + mfxU32 reserved2[15]; +} mfxExtVPPFrameRateConversion; + +enum { + MFX_IMAGESTAB_MODE_UPSCALE = 0x0001, + MFX_IMAGESTAB_MODE_BOXING = 0x0002 +}; + +typedef struct { + mfxExtBuffer Header; + mfxU16 Mode; + mfxU16 reserved[11]; +} mfxExtVPPImageStab; + +typedef struct { + mfxExtBuffer Header; + mfxU32 reserved[14]; + + struct { + mfxU16 ClockTimestampFlag; + mfxU16 CtType; + mfxU16 NuitFieldBasedFlag; + mfxU16 CountingType; + mfxU16 FullTimestampFlag; + mfxU16 DiscontinuityFlag; + mfxU16 CntDroppedFlag; + mfxU16 NFrames; + mfxU16 SecondsFlag; + mfxU16 MinutesFlag; + mfxU16 HoursFlag; + mfxU16 SecondsValue; + mfxU16 MinutesValue; + mfxU16 HoursValue; + mfxU32 TimeOffset; + } TimeStamp[3]; +} mfxExtPictureTimingSEI; + +typedef struct { + mfxExtBuffer Header; + mfxU32 reserved1[4]; + mfxU16 reserved2; + mfxU16 BaseLayerPID; + + struct { + mfxU16 Scale; + mfxU16 reserved[3]; + }Layer[8]; +} mfxExtAvcTemporalLayers; + +typedef struct { + mfxExtBuffer Header; + + mfxU32 MBPerSec; + mfxU16 reserved[58]; +} mfxExtEncoderCapability; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 StartNewSequence; + mfxU16 reserved[11]; +} mfxExtEncoderResetOption; + +/*LongTermIdx*/ +enum { + MFX_LONGTERM_IDX_NO_IDX = 0xFFFF +}; + +typedef struct { + mfxExtBuffer Header; + + mfxU32 FrameOrder; + mfxU16 PicStruct; + mfxU16 LongTermIdx; + mfxU32 MAD; + mfxU16 BRCPanicMode; + mfxU16 QP; + mfxU32 SecondFieldOffset; + mfxU16 reserved[2]; + + struct { + mfxU32 FrameOrder; + mfxU16 PicStruct; + mfxU16 LongTermIdx; + mfxU16 reserved[4]; + } UsedRefListL0[32], UsedRefListL1[32]; +} mfxExtAVCEncodedFrameInfo; + +typedef struct mfxVPPCompInputStream { + mfxU32 DstX; + mfxU32 DstY; + mfxU32 DstW; + mfxU32 DstH; + + mfxU16 LumaKeyEnable; + mfxU16 LumaKeyMin; + mfxU16 LumaKeyMax; + + mfxU16 GlobalAlphaEnable; + mfxU16 GlobalAlpha; + + mfxU16 PixelAlphaEnable; + + mfxU16 reserved2[18]; +} mfxVPPCompInputStream; + +typedef struct { + mfxExtBuffer Header; + + /* background color*/ + union { + mfxU16 Y; + mfxU16 R; + }; + union { + mfxU16 U; + mfxU16 G; + }; + union { + mfxU16 V; + mfxU16 B; + }; + + mfxU16 reserved1[24]; + + mfxU16 NumInputStream; + mfxVPPCompInputStream *InputStream; +} mfxExtVPPComposite; + +/* TransferMatrix */ +enum { + MFX_TRANSFERMATRIX_UNKNOWN = 0, + MFX_TRANSFERMATRIX_BT709 = 1, + MFX_TRANSFERMATRIX_BT601 = 2 +}; + +/* NominalRange */ +enum { + MFX_NOMINALRANGE_UNKNOWN = 0, + MFX_NOMINALRANGE_0_255 = 1, + MFX_NOMINALRANGE_16_235 = 2 +}; + +typedef struct { + mfxExtBuffer Header; + mfxU16 reserved1[4]; + + struct { + mfxU16 TransferMatrix; + mfxU16 NominalRange; + mfxU16 reserved2[6]; + } In, Out; +} mfxExtVPPVideoSignalInfo; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 NumROI; + mfxU16 reserved1[11]; + + struct { + mfxU32 Left; + mfxU32 Top; + mfxU32 Right; + mfxU32 Bottom; + + mfxI16 Priority; + mfxU16 reserved2[7]; + } ROI[256]; +} mfxExtEncoderROI; + +/*Deinterlacing Mode*/ +enum { + MFX_DEINTERLACING_BOB = 1, + MFX_DEINTERLACING_ADVANCED = 2, + MFX_DEINTERLACING_AUTO_DOUBLE = 3, + MFX_DEINTERLACING_AUTO_SINGLE = 4, + MFX_DEINTERLACING_FULL_FR_OUT = 5, + MFX_DEINTERLACING_HALF_FR_OUT = 6, + MFX_DEINTERLACING_24FPS_OUT = 7, + MFX_DEINTERLACING_FIXED_TELECINE_PATTERN = 8, + MFX_DEINTERLACING_30FPS_OUT = 9, + MFX_DEINTERLACING_DETECT_INTERLACE = 10, + MFX_DEINTERLACING_ADVANCED_NOREF = 11 +}; + +/*TelecinePattern*/ +enum { + MFX_TELECINE_PATTERN_32 = 0, + MFX_TELECINE_PATTERN_2332 = 1, + MFX_TELECINE_PATTERN_FRAME_REPEAT = 2, + MFX_TELECINE_PATTERN_41 = 3, + MFX_TELECINE_POSITION_PROVIDED = 4 +}; + +typedef struct { + mfxExtBuffer Header; + mfxU16 Mode; + mfxU16 TelecinePattern; + mfxU16 TelecineLocation; + mfxU16 reserved[9]; +} mfxExtVPPDeinterlacing; + +typedef struct { + mfxExtBuffer Header; + mfxU16 NumRefIdxL0Active; + mfxU16 NumRefIdxL1Active; + mfxU16 reserved[2]; + + struct mfxRefPic{ + mfxU32 FrameOrder; + mfxU16 PicStruct; + mfxU16 reserved[5]; + } RefPicList0[32], RefPicList1[32]; + +}mfxExtAVCRefLists; + +enum { + MFX_VPP_COPY_FRAME =0x01, + MFX_VPP_COPY_FIELD =0x02, + MFX_VPP_SWAP_FIELDS =0x03 +}; + +/*PicType*/ +enum { + MFX_PICTYPE_UNKNOWN =0x00, + MFX_PICTYPE_FRAME =0x01, + MFX_PICTYPE_TOPFIELD =0x02, + MFX_PICTYPE_BOTTOMFIELD =0x04 +}; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 Mode; + mfxU16 InField; + mfxU16 OutField; + mfxU16 reserved[25]; +} mfxExtVPPFieldProcessing; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 ChromaLocInfoPresentFlag; + mfxU16 ChromaSampleLocTypeTopField; + mfxU16 ChromaSampleLocTypeBottomField; + mfxU16 reserved[9]; +} mfxExtChromaLocInfo; + +typedef struct { + mfxExtBuffer Header; + + mfxU32 reserved[11]; + mfxU32 NumQPAlloc; + union { + mfxU8 *QP; + mfxU64 reserved2; + }; +} mfxExtMBQP; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 NumTileRows; + mfxU16 NumTileColumns; + mfxU16 reserved[74]; +}mfxExtHEVCTiles; + +typedef struct { + mfxExtBuffer Header; + + mfxU32 reserved[11]; + mfxU32 MapSize; + union { + mfxU8 *Map; + mfxU64 reserved2; + }; +} mfxExtMBDisableSkipMap; + +/*GeneralConstraintFlags*/ +enum { + /* REXT Profile constraint flags*/ + MFX_HEVC_CONSTR_REXT_MAX_12BIT = (1 << 0), + MFX_HEVC_CONSTR_REXT_MAX_10BIT = (1 << 1), + MFX_HEVC_CONSTR_REXT_MAX_8BIT = (1 << 2), + MFX_HEVC_CONSTR_REXT_MAX_422CHROMA = (1 << 3), + MFX_HEVC_CONSTR_REXT_MAX_420CHROMA = (1 << 4), + MFX_HEVC_CONSTR_REXT_MAX_MONOCHROME = (1 << 5), + MFX_HEVC_CONSTR_REXT_INTRA = (1 << 6), + MFX_HEVC_CONSTR_REXT_ONE_PICTURE_ONLY = (1 << 7), + MFX_HEVC_CONSTR_REXT_LOWER_BIT_RATE = (1 << 8) +}; + +#pragma pack(push, 4) +typedef struct { + mfxExtBuffer Header; + + mfxU16 PicWidthInLumaSamples; + mfxU16 PicHeightInLumaSamples; + mfxU64 GeneralConstraintFlags; + mfxU16 reserved[118]; +} mfxExtHEVCParam; +#pragma pack(pop) + +typedef struct { + mfxExtBuffer Header; + + mfxU16 FrameType; + mfxU16 reserved[59]; +} mfxExtDecodedFrameInfo; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 DropFrameFlag; + mfxU16 TimeCodeHours; + mfxU16 TimeCodeMinutes; + mfxU16 TimeCodeSeconds; + mfxU16 TimeCodePictures; + mfxU16 reserved[7]; +} mfxExtTimeCode; + +/*RegionType*/ +enum { + MFX_HEVC_REGION_SLICE = 0 +}; + +/*RegionEncoding*/ +enum { + MFX_HEVC_REGION_ENCODING_ON = 0, + MFX_HEVC_REGION_ENCODING_OFF = 1 +}; + +typedef struct { + mfxExtBuffer Header; + + mfxU32 RegionId; + mfxU16 RegionType; + mfxU16 RegionEncoding; + mfxU16 reserved[24]; +} mfxExtHEVCRegion; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 LumaLog2WeightDenom; // 0..7 + mfxU16 ChromaLog2WeightDenom; // 0..7 + mfxU16 LumaWeightFlag[2][32]; // [list] 0,1 + mfxU16 ChromaWeightFlag[2][32]; // [list] 0,1 + mfxI16 Weights[2][32][3][2]; // [list][list entry][Y, Cb, Cr][weight, offset] + mfxU16 reserved[58]; +} mfxExtPredWeightTable; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 NumRect; + mfxU16 reserved1[11]; + + struct { + mfxU32 Left; + mfxU32 Top; + mfxU32 Right; + mfxU32 Bottom; + + mfxU16 reserved2[8]; + } Rect[256]; +} mfxExtDirtyRect; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 NumRect; + mfxU16 reserved1[11]; + + struct { + mfxU32 DestLeft; + mfxU32 DestTop; + mfxU32 DestRight; + mfxU32 DestBottom; + + mfxU32 SourceLeft; + mfxU32 SourceTop; + mfxU16 reserved2[4]; + } Rect[256]; +} mfxExtMoveRect; + +/* Angle */ +enum { + MFX_ANGLE_0 = 0, + MFX_ANGLE_90 = 90, + MFX_ANGLE_180 = 180, + MFX_ANGLE_270 = 270 +}; + +typedef struct { + mfxExtBuffer Header; + + mfxU16 Angle; + mfxU16 reserved[11]; +} mfxExtVPPRotation; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif + diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxvideo++.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxvideo++.h new file mode 100644 index 0000000..971456a --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxvideo++.h @@ -0,0 +1,197 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2007-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +File Name: mfxvideo++.h + +\* ****************************************************************************** */ + +#ifndef __MFXVIDEOPLUSPLUS_H +#define __MFXVIDEOPLUSPLUS_H + +#include "mfxvideo.h" +#include "mfxenc.h" +#include "mfxpak.h" + +class MFXVideoSession +{ +public: + MFXVideoSession(void) { m_session = (mfxSession) 0; } + virtual ~MFXVideoSession(void) { Close(); } + + virtual mfxStatus Init(mfxIMPL impl, mfxVersion *ver) { return MFXInit(impl, ver, &m_session); } + virtual mfxStatus InitEx(mfxInitParam par) { return MFXInitEx(par, &m_session); } + virtual mfxStatus Close(void) + { + mfxStatus mfxRes; + mfxRes = MFXClose(m_session); m_session = (mfxSession) 0; + return mfxRes; + } + + virtual mfxStatus QueryIMPL(mfxIMPL *impl) { return MFXQueryIMPL(m_session, impl); } + virtual mfxStatus QueryVersion(mfxVersion *version) { return MFXQueryVersion(m_session, version); } + + virtual mfxStatus JoinSession(mfxSession child_session) { return MFXJoinSession(m_session, child_session);} + virtual mfxStatus DisjoinSession( ) { return MFXDisjoinSession(m_session);} + virtual mfxStatus CloneSession( mfxSession *clone) { return MFXCloneSession(m_session, clone);} + virtual mfxStatus SetPriority( mfxPriority priority) { return MFXSetPriority(m_session, priority);} + virtual mfxStatus GetPriority( mfxPriority *priority) { return MFXGetPriority(m_session, priority);} + + virtual mfxStatus SetBufferAllocator(mfxBufferAllocator *allocator) { return MFXVideoCORE_SetBufferAllocator(m_session, allocator); } + virtual mfxStatus SetFrameAllocator(mfxFrameAllocator *allocator) { return MFXVideoCORE_SetFrameAllocator(m_session, allocator); } + virtual mfxStatus SetHandle(mfxHandleType type, mfxHDL hdl) { return MFXVideoCORE_SetHandle(m_session, type, hdl); } + virtual mfxStatus GetHandle(mfxHandleType type, mfxHDL *hdl) { return MFXVideoCORE_GetHandle(m_session, type, hdl); } + + virtual mfxStatus SyncOperation(mfxSyncPoint syncp, mfxU32 wait) { return MFXVideoCORE_SyncOperation(m_session, syncp, wait); } + + virtual mfxStatus DoWork() { return MFXDoWork(m_session); } + + virtual operator mfxSession (void) { return m_session; } + +protected: + + mfxSession m_session; // (mfxSession) handle to the owning session +private: + MFXVideoSession(const MFXVideoSession &); + void operator=(MFXVideoSession &); +}; + +class MFXVideoENCODE +{ +public: + + MFXVideoENCODE(mfxSession session) { m_session = session; } + virtual ~MFXVideoENCODE(void) { Close(); } + + virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) { return MFXVideoENCODE_Query(m_session, in, out); } + virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *request) { return MFXVideoENCODE_QueryIOSurf(m_session, par, request); } + virtual mfxStatus Init(mfxVideoParam *par) { return MFXVideoENCODE_Init(m_session, par); } + virtual mfxStatus Reset(mfxVideoParam *par) { return MFXVideoENCODE_Reset(m_session, par); } + virtual mfxStatus Close(void) { return MFXVideoENCODE_Close(m_session); } + + virtual mfxStatus GetVideoParam(mfxVideoParam *par) { return MFXVideoENCODE_GetVideoParam(m_session, par); } + virtual mfxStatus GetEncodeStat(mfxEncodeStat *stat) { return MFXVideoENCODE_GetEncodeStat(m_session, stat); } + + virtual mfxStatus EncodeFrameAsync(mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxSyncPoint *syncp) { return MFXVideoENCODE_EncodeFrameAsync(m_session, ctrl, surface, bs, syncp); } + +protected: + + mfxSession m_session; // (mfxSession) handle to the owning session +}; + +class MFXVideoDECODE +{ +public: + + MFXVideoDECODE(mfxSession session) { m_session = session; } + virtual ~MFXVideoDECODE(void) { Close(); } + + virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) { return MFXVideoDECODE_Query(m_session, in, out); } + virtual mfxStatus DecodeHeader(mfxBitstream *bs, mfxVideoParam *par) { return MFXVideoDECODE_DecodeHeader(m_session, bs, par); } + virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *request) { return MFXVideoDECODE_QueryIOSurf(m_session, par, request); } + virtual mfxStatus Init(mfxVideoParam *par) { return MFXVideoDECODE_Init(m_session, par); } + virtual mfxStatus Reset(mfxVideoParam *par) { return MFXVideoDECODE_Reset(m_session, par); } + virtual mfxStatus Close(void) { return MFXVideoDECODE_Close(m_session); } + + virtual mfxStatus GetVideoParam(mfxVideoParam *par) { return MFXVideoDECODE_GetVideoParam(m_session, par); } + + virtual mfxStatus GetDecodeStat(mfxDecodeStat *stat) { return MFXVideoDECODE_GetDecodeStat(m_session, stat); } + virtual mfxStatus GetPayload(mfxU64 *ts, mfxPayload *payload) {return MFXVideoDECODE_GetPayload(m_session, ts, payload); } + virtual mfxStatus SetSkipMode(mfxSkipMode mode) { return MFXVideoDECODE_SetSkipMode(m_session, mode); } + virtual mfxStatus DecodeFrameAsync(mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxSyncPoint *syncp) { return MFXVideoDECODE_DecodeFrameAsync(m_session, bs, surface_work, surface_out, syncp); } + +protected: + + mfxSession m_session; // (mfxSession) handle to the owning session +}; + +class MFXVideoVPP +{ +public: + + MFXVideoVPP(mfxSession session) { m_session = session; } + virtual ~MFXVideoVPP(void) { Close(); } + + virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) { return MFXVideoVPP_Query(m_session, in, out); } + virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest request[2]) { return MFXVideoVPP_QueryIOSurf(m_session, par, request); } + virtual mfxStatus Init(mfxVideoParam *par) { return MFXVideoVPP_Init(m_session, par); } + virtual mfxStatus Reset(mfxVideoParam *par) { return MFXVideoVPP_Reset(m_session, par); } + virtual mfxStatus Close(void) { return MFXVideoVPP_Close(m_session); } + + virtual mfxStatus GetVideoParam(mfxVideoParam *par) { return MFXVideoVPP_GetVideoParam(m_session, par); } + virtual mfxStatus GetVPPStat(mfxVPPStat *stat) { return MFXVideoVPP_GetVPPStat(m_session, stat); } + virtual mfxStatus RunFrameVPPAsync(mfxFrameSurface1 *in, mfxFrameSurface1 *out, mfxExtVppAuxData *aux, mfxSyncPoint *syncp) { return MFXVideoVPP_RunFrameVPPAsync(m_session, in, out, aux, syncp); } + virtual mfxStatus RunFrameVPPAsyncEx(mfxFrameSurface1 *in, mfxFrameSurface1 *work, mfxFrameSurface1 **out, mfxSyncPoint *syncp) {return MFXVideoVPP_RunFrameVPPAsyncEx(m_session, in, work, out, syncp); } + +protected: + + mfxSession m_session; // (mfxSession) handle to the owning session +}; + +class MFXVideoENC +{ +public: + + MFXVideoENC(mfxSession session) { m_session = session; } + virtual ~MFXVideoENC(void) { Close(); } + + virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) { return MFXVideoENC_Query(m_session, in, out); } + virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *request) { return MFXVideoENC_QueryIOSurf(m_session, par, request); } + virtual mfxStatus Init(mfxVideoParam *par) { return MFXVideoENC_Init(m_session, par); } + virtual mfxStatus Reset(mfxVideoParam *par) { return MFXVideoENC_Reset(m_session, par); } + virtual mfxStatus Close(void) { return MFXVideoENC_Close(m_session); } + + virtual mfxStatus ProcessFrameAsync(mfxENCInput *in, mfxENCOutput *out, mfxSyncPoint *syncp) { return MFXVideoENC_ProcessFrameAsync(m_session, in, out, syncp); } + +protected: + + mfxSession m_session; // (mfxSession) handle to the owning session +}; + +class MFXVideoPAK +{ +public: + + MFXVideoPAK(mfxSession session) { m_session = session; } + virtual ~MFXVideoPAK(void) { Close(); } + + virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) { return MFXVideoPAK_Query(m_session, in, out); } + virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *request) { return MFXVideoPAK_QueryIOSurf(m_session, par, request); } + virtual mfxStatus Init(mfxVideoParam *par) { return MFXVideoPAK_Init(m_session, par); } + virtual mfxStatus Reset(mfxVideoParam *par) { return MFXVideoPAK_Reset(m_session, par); } + virtual mfxStatus Close(void) { return MFXVideoPAK_Close(m_session); } + + //virtual mfxStatus GetVideoParam(mfxVideoParam *par) { return MFXVideoENCODE_GetVideoParam(m_session, par); } + //virtual mfxStatus GetEncodeStat(mfxEncodeStat *stat) { return MFXVideoENCODE_GetEncodeStat(m_session, stat); } + + virtual mfxStatus ProcessFrameAsync(mfxPAKInput *in, mfxPAKOutput *out, mfxSyncPoint *syncp) { return MFXVideoPAK_ProcessFrameAsync(m_session, in, out, syncp); } + +protected: + + mfxSession m_session; // (mfxSession) handle to the owning session +}; + +#endif // __MFXVIDEOPLUSPLUS_H diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxvideo.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxvideo.h new file mode 100644 index 0000000..7042c17 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxvideo.h @@ -0,0 +1,112 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2007-2015 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfxvideo.h + +\* ****************************************************************************** */ +#ifndef __MFXVIDEO_H__ +#define __MFXVIDEO_H__ +#include "mfxsession.h" +#include "mfxvstructures.h" + +#define MFX_VERSION_MAJOR 1 +#define MFX_VERSION_MINOR 17 + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* MFXVideoCORE */ +typedef struct { + mfxU32 reserved[4]; + mfxHDL pthis; + mfxStatus (MFX_CDECL *Alloc) (mfxHDL pthis, mfxU32 nbytes, mfxU16 type, mfxMemId *mid); + mfxStatus (MFX_CDECL *Lock) (mfxHDL pthis, mfxMemId mid, mfxU8 **ptr); + mfxStatus (MFX_CDECL *Unlock) (mfxHDL pthis, mfxMemId mid); + mfxStatus (MFX_CDECL *Free) (mfxHDL pthis, mfxMemId mid); +} mfxBufferAllocator; + +typedef struct { + mfxU32 reserved[4]; + mfxHDL pthis; + + mfxStatus (MFX_CDECL *Alloc) (mfxHDL pthis, mfxFrameAllocRequest *request, mfxFrameAllocResponse *response); + mfxStatus (MFX_CDECL *Lock) (mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr); + mfxStatus (MFX_CDECL *Unlock) (mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr); + mfxStatus (MFX_CDECL *GetHDL) (mfxHDL pthis, mfxMemId mid, mfxHDL *handle); + mfxStatus (MFX_CDECL *Free) (mfxHDL pthis, mfxFrameAllocResponse *response); +} mfxFrameAllocator; + +/* VideoCORE */ +mfxStatus MFX_CDECL MFXVideoCORE_SetBufferAllocator(mfxSession session, mfxBufferAllocator *allocator); +mfxStatus MFX_CDECL MFXVideoCORE_SetFrameAllocator(mfxSession session, mfxFrameAllocator *allocator); +mfxStatus MFX_CDECL MFXVideoCORE_SetHandle(mfxSession session, mfxHandleType type, mfxHDL hdl); +mfxStatus MFX_CDECL MFXVideoCORE_GetHandle(mfxSession session, mfxHandleType type, mfxHDL *hdl); +mfxStatus MFX_CDECL MFXVideoCORE_SyncOperation(mfxSession session, mfxSyncPoint syncp, mfxU32 wait); + +/* VideoENCODE */ +mfxStatus MFX_CDECL MFXVideoENCODE_Query(mfxSession session, mfxVideoParam *in, mfxVideoParam *out); +mfxStatus MFX_CDECL MFXVideoENCODE_QueryIOSurf(mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request); +mfxStatus MFX_CDECL MFXVideoENCODE_Init(mfxSession session, mfxVideoParam *par); +mfxStatus MFX_CDECL MFXVideoENCODE_Reset(mfxSession session, mfxVideoParam *par); +mfxStatus MFX_CDECL MFXVideoENCODE_Close(mfxSession session); + +mfxStatus MFX_CDECL MFXVideoENCODE_GetVideoParam(mfxSession session, mfxVideoParam *par); +mfxStatus MFX_CDECL MFXVideoENCODE_GetEncodeStat(mfxSession session, mfxEncodeStat *stat); +mfxStatus MFX_CDECL MFXVideoENCODE_EncodeFrameAsync(mfxSession session, mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxSyncPoint *syncp); + +/* VideoDECODE */ +mfxStatus MFX_CDECL MFXVideoDECODE_Query(mfxSession session, mfxVideoParam *in, mfxVideoParam *out); +mfxStatus MFX_CDECL MFXVideoDECODE_DecodeHeader(mfxSession session, mfxBitstream *bs, mfxVideoParam *par); +mfxStatus MFX_CDECL MFXVideoDECODE_QueryIOSurf(mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request); +mfxStatus MFX_CDECL MFXVideoDECODE_Init(mfxSession session, mfxVideoParam *par); +mfxStatus MFX_CDECL MFXVideoDECODE_Reset(mfxSession session, mfxVideoParam *par); +mfxStatus MFX_CDECL MFXVideoDECODE_Close(mfxSession session); + +mfxStatus MFX_CDECL MFXVideoDECODE_GetVideoParam(mfxSession session, mfxVideoParam *par); +mfxStatus MFX_CDECL MFXVideoDECODE_GetDecodeStat(mfxSession session, mfxDecodeStat *stat); +mfxStatus MFX_CDECL MFXVideoDECODE_SetSkipMode(mfxSession session, mfxSkipMode mode); +mfxStatus MFX_CDECL MFXVideoDECODE_GetPayload(mfxSession session, mfxU64 *ts, mfxPayload *payload); +mfxStatus MFX_CDECL MFXVideoDECODE_DecodeFrameAsync(mfxSession session, mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxSyncPoint *syncp); + +/* VideoVPP */ +mfxStatus MFX_CDECL MFXVideoVPP_Query(mfxSession session, mfxVideoParam *in, mfxVideoParam *out); +mfxStatus MFX_CDECL MFXVideoVPP_QueryIOSurf(mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest request[2]); +mfxStatus MFX_CDECL MFXVideoVPP_Init(mfxSession session, mfxVideoParam *par); +mfxStatus MFX_CDECL MFXVideoVPP_Reset(mfxSession session, mfxVideoParam *par); +mfxStatus MFX_CDECL MFXVideoVPP_Close(mfxSession session); + +mfxStatus MFX_CDECL MFXVideoVPP_GetVideoParam(mfxSession session, mfxVideoParam *par); +mfxStatus MFX_CDECL MFXVideoVPP_GetVPPStat(mfxSession session, mfxVPPStat *stat); +mfxStatus MFX_CDECL MFXVideoVPP_RunFrameVPPAsync(mfxSession session, mfxFrameSurface1 *in, mfxFrameSurface1 *out, mfxExtVppAuxData *aux, mfxSyncPoint *syncp); +mfxStatus MFX_CDECL MFXVideoVPP_RunFrameVPPAsyncEx(mfxSession session, mfxFrameSurface1 *in, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxSyncPoint *syncp); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/plugins/obs-qsv11/libmfx/include/msdk/include/mfxvstructures.h b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxvstructures.h new file mode 100644 index 0000000..eae07a4 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/include/msdk/include/mfxvstructures.h @@ -0,0 +1,32 @@ +/******************************************************************************* + +Copyright (C) 2013 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfxvstructures.h + +*******************************************************************************/ +#include "mfxstructures.h" + + diff --git a/plugins/obs-qsv11/libmfx/src/main.cpp b/plugins/obs-qsv11/libmfx/src/main.cpp new file mode 100644 index 0000000..9097830 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/src/main.cpp @@ -0,0 +1,937 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2015 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: main.cpp + +\* ****************************************************************************** */ + +#include "mfx_dispatcher.h" +#include "mfx_load_dll.h" +#include "mfx_dispatcher_log.h" +#include "mfx_library_iterator.h" +#include "mfx_critical_section.h" + +#include /* for memset on Linux */ +#include +#include /* for qsort on Linux */ +#include "mfx_load_plugin.h" +#include "mfx_plugin_hive.h" + +// module-local definitions +namespace +{ + + const + struct + { + // instance implementation type + eMfxImplType implType; + // real implementation + mfxIMPL impl; + // adapter numbers + mfxU32 adapterID; + + } implTypes[] = + { + // MFX_IMPL_AUTO case + {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE, 0}, + {MFX_LIB_SOFTWARE, MFX_IMPL_SOFTWARE, 0}, + + // MFX_IMPL_ANY case + {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE, 0}, + {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE2, 1}, + {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE3, 2}, + {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE4, 3}, + {MFX_LIB_SOFTWARE, MFX_IMPL_SOFTWARE, 0}, + {MFX_LIB_SOFTWARE, MFX_IMPL_SOFTWARE | MFX_IMPL_AUDIO, 0} + }; + + const + struct + { + // start index in implTypes table for specified implementation + mfxU32 minIndex; + // last index in implTypes table for specified implementation + mfxU32 maxIndex; + + } implTypesRange[] = + { + {0, 1}, // MFX_IMPL_AUTO + {1, 1}, // MFX_IMPL_SOFTWARE + {0, 0}, // MFX_IMPL_HARDWARE + {2, 6}, // MFX_IMPL_AUTO_ANY + {2, 5}, // MFX_IMPL_HARDWARE_ANY + {3, 3}, // MFX_IMPL_HARDWARE2 + {4, 4}, // MFX_IMPL_HARDWARE3 + {5, 5}, // MFX_IMPL_HARDWARE4 + {2, 6}, // MFX_IMPL_RUNTIME, same as MFX_IMPL_HARDWARE_ANY + {7, 7} // MFX_IMPL_AUDIO + }; + + MFX::mfxCriticalSection dispGuard = 0; + +} // namespace + +using namespace MFX; +// +// Implement DLL exposed functions. MFXInit and MFXClose have to do +// slightly more than other. They require to be implemented explicitly. +// All other functions are implemented implicitly. +// + +typedef MFXVector HandleVector; +typedef MFXVector StatusVector; + +struct VectorHandleGuard +{ + VectorHandleGuard(HandleVector& aVector): m_vector(aVector) {} + ~VectorHandleGuard() + { + HandleVector::iterator it = m_vector.begin(), + et = m_vector.end(); + for ( ; it != et; ++it) + { + delete *it; + } + } + + HandleVector& m_vector; +private: + void operator=(const VectorHandleGuard&); +}; + + +int HandleSort (const void * plhs, const void * prhs) +{ + const MFX_DISP_HANDLE * lhs = *(const MFX_DISP_HANDLE **)plhs; + const MFX_DISP_HANDLE * rhs = *(const MFX_DISP_HANDLE **)prhs; + + if (lhs->actualApiVersion < rhs->actualApiVersion) + { + return -1; + } + if (rhs->actualApiVersion < lhs->actualApiVersion) + { + return 1; + } + + // if versions are equal prefer library with HW + if (lhs->loadStatus == MFX_WRN_PARTIAL_ACCELERATION && rhs->loadStatus == MFX_ERR_NONE) + { + return 1; + } + if (lhs->loadStatus == MFX_ERR_NONE && rhs->loadStatus == MFX_WRN_PARTIAL_ACCELERATION) + { + return -1; + } + + return 0; +} + +mfxStatus MFXInit(mfxIMPL impl, mfxVersion *pVer, mfxSession *session) +{ + mfxInitParam par = {}; + + par.Implementation = impl; + if (pVer) + { + par.Version = *pVer; + } + else + { + par.Version.Major = DEFAULT_API_VERSION_MAJOR; + par.Version.Minor = DEFAULT_API_VERSION_MINOR; + } + par.ExternalThreads = 0; + + return MFXInitEx(par, session); +} + +mfxStatus MFXInitEx(mfxInitParam par, mfxSession *session) +{ + MFX::MFXAutomaticCriticalSection guard(&dispGuard); + + DISPATCHER_LOG_BLOCK( ("MFXInitEx (impl=%s, pVer=%d.%d, ExternalThreads=%d session=0x%p\n" + , DispatcherLog_GetMFXImplString(par.Implementation).c_str() + , par.Version.Major + , par.Version.Minor + , par.ExternalThreads + , session)); + + mfxStatus mfxRes; + HandleVector allocatedHandle; + VectorHandleGuard handleGuard(allocatedHandle); + + MFX_DISP_HANDLE *pHandle; + msdk_disp_char dllName[MFX_MAX_DLL_PATH]; + MFX::MFXLibraryIterator libIterator; + // there iterators are used only if the caller specified implicit type like AUTO + mfxU32 curImplIdx, maxImplIdx; + // particular implementation value + mfxIMPL curImpl; + // implementation method masked from the input parameter + // special case for audio library + const mfxIMPL implMethod = (par.Implementation & MFX_IMPL_AUDIO) ? (sizeof(implTypesRange) / sizeof(implTypesRange[0]) - 1) : (par.Implementation & (MFX_IMPL_VIA_ANY - 1)); + + // implementation interface masked from the input parameter + mfxIMPL implInterface = par.Implementation & -MFX_IMPL_VIA_ANY; + mfxIMPL implInterfaceOrig = implInterface; + mfxVersion requiredVersion = {{MFX_VERSION_MINOR, MFX_VERSION_MAJOR}}; + + // check error(s) + if (NULL == session) + { + return MFX_ERR_NULL_PTR; + } + if (((MFX_IMPL_AUTO > implMethod) || (MFX_IMPL_RUNTIME < implMethod)) && !(par.Implementation & MFX_IMPL_AUDIO)) + { + return MFX_ERR_UNSUPPORTED; + } + + // set the minimal required version + requiredVersion = par.Version; + + try + { + // reset the session value + *session = 0; + + // allocate the dispatching handle and call-table + pHandle = new MFX_DISP_HANDLE(requiredVersion); + } + catch(...) + { + return MFX_ERR_MEMORY_ALLOC; + } + + DISPATCHER_LOG_INFO((("Required API version is %u.%u\n"), requiredVersion.Major, requiredVersion.Minor)); + + // Load HW library or RT from system location + curImplIdx = implTypesRange[implMethod].minIndex; + maxImplIdx = implTypesRange[implMethod].maxIndex; + mfxU32 hwImplIdx = 0; + do + { + int currentStorage = MFX::MFX_STORAGE_ID_FIRST; + implInterface = implInterfaceOrig; + do + { + // initialize the library iterator + mfxRes = libIterator.Init(implTypes[curImplIdx].implType, + implInterface, + implTypes[curImplIdx].adapterID, + currentStorage); + + // look through the list of installed SDK version, + // looking for a suitable library with higher merit value. + if (MFX_ERR_NONE == mfxRes) + { + + if ( + MFX_LIB_HARDWARE == implTypes[curImplIdx].implType + && (!implInterface + || MFX_IMPL_VIA_ANY == implInterface)) + { + implInterface = libIterator.GetImplementationType(); + } + + do + { + eMfxImplType implType; + + // select a desired DLL + mfxRes = libIterator.SelectDLLVersion(dllName, + sizeof(dllName) / sizeof(dllName[0]), + &implType, + pHandle->apiVersion); + if (MFX_ERR_NONE != mfxRes) + { + break; + } + DISPATCHER_LOG_INFO((("loading library %S\n"), MSDK2WIDE(dllName))); + if (MFX_LIB_HARDWARE == implTypes[curImplIdx].implType) + hwImplIdx = curImplIdx; + // try to load the selected DLL + curImpl = implTypes[curImplIdx].impl; + mfxRes = pHandle->LoadSelectedDLL(dllName, implType, curImpl, implInterface, par); + // unload the failed DLL + if (MFX_ERR_NONE != mfxRes) + { + pHandle->Close(); + } + else + { + libIterator.GetSubKeyName(pHandle->subkeyName, sizeof(pHandle->subkeyName)/sizeof(pHandle->subkeyName[0])) ; + pHandle->storageID = libIterator.GetStorageID(); + allocatedHandle.push_back(pHandle); + pHandle = new MFX_DISP_HANDLE(requiredVersion); + } + + } while (MFX_ERR_NONE != mfxRes); + } + + // select another registry key + currentStorage += 1; + + } while ((MFX_ERR_NONE != mfxRes) && (MFX::MFX_STORAGE_ID_LAST >= currentStorage)); + + } while ((MFX_ERR_NONE != mfxRes) && (++curImplIdx <= maxImplIdx)); + + + curImplIdx = implTypesRange[implMethod].minIndex; + maxImplIdx = implTypesRange[implMethod].maxIndex; + + // Load RT from app folder (libmfxsw64 with API >= 1.10) + do + { + implInterface = implInterfaceOrig; + // initialize the library iterator + mfxRes = libIterator.Init(implTypes[curImplIdx].implType, + implInterface, + implTypes[curImplIdx].adapterID, + MFX::MFX_APP_FOLDER); + + if (MFX_ERR_NONE == mfxRes) + { + + if ( + MFX_LIB_HARDWARE == implTypes[curImplIdx].implType + && (!implInterface + || MFX_IMPL_VIA_ANY == implInterface)) + { + implInterface = libIterator.GetImplementationType(); + } + + do + { + eMfxImplType implType; + + // select a desired DLL + mfxRes = libIterator.SelectDLLVersion(dllName, + sizeof(dllName) / sizeof(dllName[0]), + &implType, + pHandle->apiVersion); + if (MFX_ERR_NONE != mfxRes) + { + break; + } + DISPATCHER_LOG_INFO((("loading library %S\n"), MSDK2WIDE(dllName))); + + // try to load the selected DLL + curImpl = implTypes[curImplIdx].impl; + mfxRes = pHandle->LoadSelectedDLL(dllName, implType, curImpl, implInterface, par); + // unload the failed DLL + if (MFX_ERR_NONE != mfxRes) + { + pHandle->Close(); + } + else + { + if (pHandle->actualApiVersion.Major == 1 && pHandle->actualApiVersion.Minor <= 9) + { + // this is not RT, skip it + mfxRes = MFX_ERR_ABORTED; + break; + } + pHandle->storageID = MFX::MFX_UNKNOWN_KEY; + allocatedHandle.push_back(pHandle); + pHandle = new MFX_DISP_HANDLE(requiredVersion); + } + + } while (MFX_ERR_NONE != mfxRes); + } + } while ((MFX_ERR_NONE != mfxRes) && (++curImplIdx <= maxImplIdx)); + + // Load HW and SW libraries using legacy default DLL search mechanism + // set current library index again + curImplIdx = implTypesRange[implMethod].minIndex; + do + { + mfxU32 backupIdx = curImplIdx; + if (MFX_LIB_HARDWARE == implTypes[curImplIdx].implType) + { + curImplIdx = hwImplIdx; + } + implInterface = implInterfaceOrig; + + if (par.Implementation & MFX_IMPL_AUDIO) + { + mfxRes = MFX::mfx_get_default_audio_dll_name(dllName, + sizeof(dllName) / sizeof(dllName[0]), + implTypes[curImplIdx].implType); + } + else + { + mfxRes = MFX::mfx_get_default_dll_name(dllName, + sizeof(dllName) / sizeof(dllName[0]), + implTypes[curImplIdx].implType); + } + + if (MFX_ERR_NONE == mfxRes) + { + DISPATCHER_LOG_INFO((("loading default library %S\n"), MSDK2WIDE(dllName))) + + // try to load the selected DLL using default DLL search mechanism + if (MFX_LIB_HARDWARE == implTypes[curImplIdx].implType) + { + if (!implInterface) + { + implInterface = MFX_IMPL_VIA_ANY; + } + mfxRes = MFX::SelectImplementationType(implTypes[curImplIdx].adapterID, &implInterface, NULL, NULL); + } + if (MFX_ERR_NONE == mfxRes) + { + // try to load the selected DLL using default DLL search mechanism + mfxRes = pHandle->LoadSelectedDLL(dllName, + implTypes[curImplIdx].implType, + implTypes[curImplIdx].impl, + implInterface, + par); + } + // unload the failed DLL + if ((MFX_ERR_NONE != mfxRes) && + (MFX_WRN_PARTIAL_ACCELERATION != mfxRes)) + { + pHandle->Close(); + } + else + { + pHandle->storageID = MFX::MFX_UNKNOWN_KEY; + allocatedHandle.push_back(pHandle); + pHandle = new MFX_DISP_HANDLE(requiredVersion); + } + } + curImplIdx = backupIdx; + } + while ((MFX_ERR_NONE > mfxRes) && (++curImplIdx <= maxImplIdx)); + delete pHandle; + + if (allocatedHandle.size() == 0) + return MFX_ERR_UNSUPPORTED; + + bool NeedSort = false; + HandleVector::iterator first = allocatedHandle.begin(), + it = allocatedHandle.begin(), + et = allocatedHandle.end(); + for (it++; it != et; ++it) + if (HandleSort(&(*first), &(*it)) != 0) + NeedSort = true; + + // select dll with version with lowest version number still greater or equal to requested + if (NeedSort) + qsort(&(*allocatedHandle.begin()), allocatedHandle.size(), sizeof(MFX_DISP_HANDLE*), &HandleSort); + + HandleVector::iterator candidate = allocatedHandle.begin(); + // check the final result of loading + try + { + pHandle = *candidate; + //pulling up current mediasdk version, that required to match plugin version + mfxVersion apiVerActual; + mfxStatus stsQueryVersion; + stsQueryVersion = MFXQueryVersion((mfxSession)pHandle, &apiVerActual); + if (MFX_ERR_NONE != stsQueryVersion) + { + DISPATCHER_LOG_ERROR((("MFXQueryVersion returned: %d, cannot load plugins\n"), mfxRes)) + } + else + { + MFX::MFXPluginStorage & hive = pHandle->pluginHive; + + HandleVector::iterator it = allocatedHandle.begin(), + et = allocatedHandle.end(); + for (; it != et; ++it) + { + // Registering default plugins set + MFX::MFXDefaultPlugins defaultPugins(apiVerActual, *it, (*it)->implType); + hive.insert(hive.end(), defaultPugins.begin(), defaultPugins.end()); + + if ((*it)->storageID != MFX::MFX_UNKNOWN_KEY) + { + // Scan HW plugins in subkeys of registry library + MFX::MFXPluginsInHive plgsInHive((*it)->storageID, (*it)->subkeyName, apiVerActual); + hive.insert(hive.end(), plgsInHive.begin(), plgsInHive.end()); + } + } + + //setting up plugins records + for(int i = MFX::MFX_STORAGE_ID_FIRST; i <= MFX::MFX_STORAGE_ID_LAST; i++) + { + MFX::MFXPluginsInHive plgsInHive(i, NULL, apiVerActual); + hive.insert(hive.end(), plgsInHive.begin(), plgsInHive.end()); + } + + MFX::MFXPluginsInFS plgsInFS(apiVerActual); + hive.insert(hive.end(), plgsInFS.begin(), plgsInFS.end()); + } + } + catch(...) + { + DISPATCHER_LOG_ERROR((("unknown exception while loading plugins\n"))) + } + + // everything is OK. Save pointers to the output variable + *candidate = 0; // keep this one safe from guard destructor + *((MFX_DISP_HANDLE **) session) = pHandle; + + return pHandle->loadStatus; + +} // mfxStatus MFXInit(mfxIMPL impl, mfxVersion *ver, mfxSession *session) + +mfxStatus MFXClose(mfxSession session) +{ + MFX::MFXAutomaticCriticalSection guard(&dispGuard); + + mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; + MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *) session; + + // check error(s) + if (pHandle) + { + try + { + // unload the DLL library + mfxRes = pHandle->Close(); + + // it is possible, that there is an active child session. + // can't unload library in that case. + if (MFX_ERR_UNDEFINED_BEHAVIOR != mfxRes) + { + // release the handle + delete pHandle; + } + } + catch(...) + { + mfxRes = MFX_ERR_INVALID_HANDLE; + } + } + + return mfxRes; + +} // mfxStatus MFXClose(mfxSession session) + +mfxStatus MFXJoinSession(mfxSession session, mfxSession child_session) +{ + mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; + MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *) session; + MFX_DISP_HANDLE *pChildHandle = (MFX_DISP_HANDLE *) child_session; + + // get the function's address and make a call + if ((pHandle) && (pChildHandle) && (pHandle->apiVersion == pChildHandle->apiVersion)) + { + /* check whether it is audio session or video */ + int tableIndex = eMFXJoinSession; + mfxFunctionPointer pFunc; + if (pHandle->impl & MFX_IMPL_AUDIO) + { + pFunc = pHandle->callAudioTable[tableIndex]; + } + else + { + pFunc = pHandle->callTable[tableIndex]; + } + + if (pFunc) + { + // pass down the call + mfxRes = (*(mfxStatus (MFX_CDECL *) (mfxSession, mfxSession)) pFunc) (pHandle->session, + pChildHandle->session); + } + } + + return mfxRes; + +} // mfxStatus MFXJoinSession(mfxSession session, mfxSession child_session) + +mfxStatus MFXCloneSession(mfxSession session, mfxSession *clone) +{ + mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; + MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *) session; + mfxVersion apiVersion; + mfxIMPL impl; + + // check error(s) + if (pHandle) + { + // initialize the clone session + apiVersion = pHandle->apiVersion; + impl = pHandle->impl | pHandle->implInterface; + mfxRes = MFXInit(impl, &apiVersion, clone); + if (MFX_ERR_NONE != mfxRes) + { + return mfxRes; + } + + // join the sessions + mfxRes = MFXJoinSession(session, *clone); + if (MFX_ERR_NONE != mfxRes) + { + MFXClose(*clone); + *clone = NULL; + return mfxRes; + } + } + + return mfxRes; + +} // mfxStatus MFXCloneSession(mfxSession session, mfxSession *clone) + + +mfxStatus MFXVideoUSER_Load(mfxSession session, const mfxPluginUID *uid, mfxU32 version) +{ + mfxStatus sts = MFX_ERR_NONE; + bool ErrFlag = false; + MFX_DISP_HANDLE &pHandle = *(MFX_DISP_HANDLE *) session; + if (!&pHandle) + { + DISPATCHER_LOG_ERROR((("MFXVideoUSER_Load: session=NULL\n"))); + return MFX_ERR_NULL_PTR; + } + if (!uid) + { + DISPATCHER_LOG_ERROR((("MFXVideoUSER_Load: uid=NULL\n"))); + return MFX_ERR_NULL_PTR; + } + DISPATCHER_LOG_INFO((("MFXVideoUSER_Load: uid="MFXGUIDTYPE()" version=%d\n") + , MFXGUIDTOHEX(uid) + , version)) + size_t pluginsChecked = 0; + + for (MFX::MFXPluginStorage::iterator i = pHandle.pluginHive.begin();i != pHandle.pluginHive.end(); i++, pluginsChecked++) + { + if (i->PluginUID != *uid) + { + continue; + } + //check rest in records + if (i->PluginVersion < version) + { + DISPATCHER_LOG_INFO((("MFXVideoUSER_Load: registered \"Plugin Version\" for GUID="MFXGUIDTYPE()" is %d, that is smaller that requested\n") + , MFXGUIDTOHEX(uid) + , i->PluginVersion)) + continue; + } + try + { + sts = pHandle.pluginFactory.Create(*i); + if( MFX_ERR_NONE != sts) + { + ErrFlag = (ErrFlag || (sts == MFX_ERR_UNDEFINED_BEHAVIOR)); + continue; + } + return MFX_ERR_NONE; + } + catch(...) + { + continue; + } + } + + // Specified UID was not found among individually registed plugins, now try load it from default sets if any + for (MFX::MFXPluginStorage::iterator i = pHandle.pluginHive.begin();i != pHandle.pluginHive.end(); i++, pluginsChecked++) + { + if (!i->Default) + continue; + + i->PluginUID = *uid; + i->PluginVersion = (mfxU16)version; + try + { + sts = pHandle.pluginFactory.Create(*i); + if( MFX_ERR_NONE != sts) + { + ErrFlag = (ErrFlag || (sts == MFX_ERR_UNDEFINED_BEHAVIOR)); + continue; + } + return MFX_ERR_NONE; + } + catch(...) + { + continue; + } + } + + DISPATCHER_LOG_ERROR((("MFXVideoUSER_Load: cannot find registered plugin with requested UID, total plugins available=%d\n"), pHandle.pluginHive.size())); + if (ErrFlag) + return MFX_ERR_UNDEFINED_BEHAVIOR; + else + return MFX_ERR_NOT_FOUND; +} + + +mfxStatus MFXVideoUSER_LoadByPath(mfxSession session, const mfxPluginUID *uid, mfxU32 version, const mfxChar *path, mfxU32 len) +{ + MFX_DISP_HANDLE &pHandle = *(MFX_DISP_HANDLE *) session; + if (!&pHandle) + { + DISPATCHER_LOG_ERROR((("MFXVideoUSER_LoadByPath: session=NULL\n"))); + return MFX_ERR_NULL_PTR; + } + if (!uid) + { + DISPATCHER_LOG_ERROR((("MFXVideoUSER_LoadByPath: uid=NULL\n"))); + return MFX_ERR_NULL_PTR; + } + + DISPATCHER_LOG_INFO((("MFXVideoUSER_LoadByPath: %S uid="MFXGUIDTYPE()" version=%d\n") + , MSDK2WIDE(path) + , MFXGUIDTOHEX(uid) + , version)) + + PluginDescriptionRecord record; + record.sName[0] = 0; + +#ifdef _WIN32 + msdk_disp_char wPath[MAX_PLUGIN_PATH]; + int res = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, len, wPath, MAX_PLUGIN_PATH); + if (!res) + { + DISPATCHER_LOG_ERROR((("MFXVideoUSER_LoadByPath: cant convert UTF-8 path to UTF-16\n"))); + return MFX_ERR_NOT_FOUND; + } + msdk_disp_char_cpy_s(record.sPath, res < MAX_PLUGIN_PATH ? res : MAX_PLUGIN_PATH, wPath); +#else // Linux/Android + msdk_disp_char_cpy_s(record.sPath, len < MAX_PLUGIN_PATH ? len : MAX_PLUGIN_PATH, path); +#endif + + record.PluginUID = *uid; + record.PluginVersion = (mfxU16)version; + record.Default = true; + + try + { + return pHandle.pluginFactory.Create(record); + } + catch(...) + { + return MFX_ERR_NOT_FOUND; + } +} + + +mfxStatus MFXVideoUSER_UnLoad(mfxSession session, const mfxPluginUID *uid) +{ + MFX_DISP_HANDLE &rHandle = *(MFX_DISP_HANDLE *) session; + if (!&rHandle) + { + DISPATCHER_LOG_ERROR((("MFXVideoUSER_UnLoad: session=NULL\n"))); + return MFX_ERR_NULL_PTR; + } + if (!uid) + { + DISPATCHER_LOG_ERROR((("MFXVideoUSER_Load: uid=NULL\n"))); + return MFX_ERR_NULL_PTR; + } + + bool bDestroyed = rHandle.pluginFactory.Destroy(*uid); + if (bDestroyed) + { + DISPATCHER_LOG_INFO((("MFXVideoUSER_UnLoad : plugin with GUID="MFXGUIDTYPE()" unloaded\n"), MFXGUIDTOHEX(uid))); + } else + { + DISPATCHER_LOG_ERROR((("MFXVideoUSER_UnLoad : plugin with GUID="MFXGUIDTYPE()" not found\n"), MFXGUIDTOHEX(uid))); + } + + return bDestroyed ? MFX_ERR_NONE : MFX_ERR_NOT_FOUND; +} + +mfxStatus MFXAudioUSER_Load(mfxSession session, const mfxPluginUID *uid, mfxU32 version) +{ + MFX_DISP_HANDLE &pHandle = *(MFX_DISP_HANDLE *) session; + if (!&pHandle) + { + DISPATCHER_LOG_ERROR((("MFXAudioUSER_Load: session=NULL\n"))); + return MFX_ERR_NULL_PTR; + } + if (!uid) + { + DISPATCHER_LOG_ERROR((("MFXAudioUSER_Load: uid=NULL\n"))); + return MFX_ERR_NULL_PTR; + } + DISPATCHER_LOG_INFO((("MFXAudioUSER_Load: uid="MFXGUIDTYPE()" version=%d\n") + , MFXGUIDTOHEX(uid) + , version)) + size_t pluginsChecked = 0; + PluginDescriptionRecord defaultPluginRecord; + for (MFX::MFXPluginStorage::iterator i = pHandle.pluginHive.begin();i != pHandle.pluginHive.end(); i++, pluginsChecked++) + { + if (i->PluginUID != *uid) + { + if (i->Default) // PluginUID == 0 for default set + { + defaultPluginRecord = *i; + } + continue; + } + //check rest in records + if (i->PluginVersion < version) + { + DISPATCHER_LOG_INFO((("MFXAudioUSER_Load: registered \"Plugin Version\" for GUID="MFXGUIDTYPE()" is %d, that is smaller that requested\n") + , MFXGUIDTOHEX(uid) + , i->PluginVersion)) + continue; + } + try { + return pHandle.pluginFactory.Create(*i); + } + catch(...) { + return MFX_ERR_UNKNOWN; + } + } + + // Specified UID was not found among individually registed plugins, now try load it from default set if any + if (defaultPluginRecord.Default) + { + defaultPluginRecord.PluginUID = *uid; + defaultPluginRecord.onlyVersionRegistered = true; + defaultPluginRecord.PluginVersion = (mfxU16)version; + try { + return pHandle.pluginFactory.Create(defaultPluginRecord); + } + catch(...) { + return MFX_ERR_UNKNOWN; + } + } + + DISPATCHER_LOG_ERROR((("MFXAudioUSER_Load: cannot find registered plugin with requested UID, total plugins available=%d\n"), pHandle.pluginHive.size())); + return MFX_ERR_NOT_FOUND; +} + +mfxStatus MFXAudioUSER_UnLoad(mfxSession session, const mfxPluginUID *uid) +{ + MFX_DISP_HANDLE &rHandle = *(MFX_DISP_HANDLE *) session; + if (!&rHandle) + { + DISPATCHER_LOG_ERROR((("MFXAudioUSER_UnLoad: session=NULL\n"))); + return MFX_ERR_NULL_PTR; + } + if (!uid) + { + DISPATCHER_LOG_ERROR((("MFXAudioUSER_Load: uid=NULL\n"))); + return MFX_ERR_NULL_PTR; + } + + bool bDestroyed = rHandle.pluginFactory.Destroy(*uid); + if (bDestroyed) + { + DISPATCHER_LOG_INFO((("MFXAudioUSER_UnLoad : plugin with GUID="MFXGUIDTYPE()" unloaded\n"), MFXGUIDTOHEX(uid))); + } else + { + DISPATCHER_LOG_ERROR((("MFXAudioUSER_UnLoad : plugin with GUID="MFXGUIDTYPE()" not found\n"), MFXGUIDTOHEX(uid))); + } + + return bDestroyed ? MFX_ERR_NONE : MFX_ERR_NOT_FOUND; +} + +// +// implement all other calling functions. +// They just call a procedure of DLL library from the table. +// + +// define for common functions (from mfxsession.h) +#undef FUNCTION +#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \ + return_value func_name formal_param_list \ +{ \ + mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; \ + MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *) session; \ + /* get the function's address and make a call */ \ + if (pHandle) \ +{ \ + /* check whether it is audio session or video */ \ + int tableIndex = e##func_name; \ + mfxFunctionPointer pFunc; \ + if (pHandle->impl & MFX_IMPL_AUDIO) \ +{ \ + pFunc = pHandle->callAudioTable[tableIndex]; \ +} \ + else \ +{ \ + pFunc = pHandle->callTable[tableIndex]; \ +} \ + if (pFunc) \ +{ \ + /* get the real session pointer */ \ + session = pHandle->session; \ + /* pass down the call */ \ + mfxRes = (*(mfxStatus (MFX_CDECL *) formal_param_list) pFunc) actual_param_list; \ +} \ +} \ + return mfxRes; \ +} + +FUNCTION(mfxStatus, MFXQueryIMPL, (mfxSession session, mfxIMPL *impl), (session, impl)) +FUNCTION(mfxStatus, MFXQueryVersion, (mfxSession session, mfxVersion *version), (session, version)) +FUNCTION(mfxStatus, MFXDisjoinSession, (mfxSession session), (session)) +FUNCTION(mfxStatus, MFXSetPriority, (mfxSession session, mfxPriority priority), (session, priority)) +FUNCTION(mfxStatus, MFXGetPriority, (mfxSession session, mfxPriority *priority), (session, priority)) + +#undef FUNCTION +#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \ + return_value func_name formal_param_list \ +{ \ + mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; \ + MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *) session; \ + /* get the function's address and make a call */ \ + if (pHandle) \ +{ \ + mfxFunctionPointer pFunc = pHandle->callTable[e##func_name]; \ + if (pFunc) \ +{ \ + /* get the real session pointer */ \ + session = pHandle->session; \ + /* pass down the call */ \ + mfxRes = (*(mfxStatus (MFX_CDECL *) formal_param_list) pFunc) actual_param_list; \ +} \ +} \ + return mfxRes; \ +} + +#include "mfx_exposed_functions_list.h" +#undef FUNCTION +#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \ + return_value func_name formal_param_list \ +{ \ + mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; \ + MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *) session; \ + /* get the function's address and make a call */ \ + if (pHandle) \ +{ \ + mfxFunctionPointer pFunc = pHandle->callAudioTable[e##func_name]; \ + if (pFunc) \ +{ \ + /* get the real session pointer */ \ + session = pHandle->session; \ + /* pass down the call */ \ + mfxRes = (*(mfxStatus (MFX_CDECL *) formal_param_list) pFunc) actual_param_list; \ +} \ +} \ + return mfxRes; \ +} + +#include "mfxaudio_exposed_functions_list.h" diff --git a/plugins/obs-qsv11/libmfx/src/mfx_critical_section.cpp b/plugins/obs-qsv11/libmfx/src/mfx_critical_section.cpp new file mode 100644 index 0000000..1e08821 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/src/mfx_critical_section.cpp @@ -0,0 +1,88 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2013 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_critical_section.cpp + +\* ****************************************************************************** */ + +#include "mfx_critical_section.h" + +#if defined(_WIN32) || defined(_WIN64) + +#include +// SDK re-declares the following functions with different call declarator. +// We don't need them. Just redefine them to nothing. +#define _interlockedbittestandset fake_set +#define _interlockedbittestandreset fake_reset +#define _interlockedbittestandset64 fake_set64 +#define _interlockedbittestandreset64 fake_reset64 +#include + +#define MFX_WAIT() SwitchToThread() + +// static section of the file +namespace +{ + +enum +{ + MFX_SC_IS_FREE = 0, + MFX_SC_IS_TAKEN = 1 +}; + +} // namespace + +namespace MFX +{ + +mfxU32 mfxInterlockedCas32(mfxCriticalSection *pCSection, mfxU32 value_to_exchange, mfxU32 value_to_compare) +{ + return _InterlockedCompareExchange(pCSection, value_to_exchange, value_to_compare); +} + +mfxU32 mfxInterlockedXchg32(mfxCriticalSection *pCSection, mfxU32 value) +{ + return _InterlockedExchange(pCSection, value); +} + +void mfxEnterCriticalSection(mfxCriticalSection *pCSection) +{ + while (MFX_SC_IS_TAKEN == mfxInterlockedCas32(pCSection, + MFX_SC_IS_TAKEN, + MFX_SC_IS_FREE)) + { + MFX_WAIT(); + } +} // void mfxEnterCriticalSection(mfxCriticalSection *pCSection) + +void mfxLeaveCriticalSection(mfxCriticalSection *pCSection) +{ + mfxInterlockedXchg32(pCSection, MFX_SC_IS_FREE); +} // void mfxLeaveCriticalSection(mfxCriticalSection *pCSection) + +} // namespace MFX + +#endif // #if defined(_WIN32) || defined(_WIN64) diff --git a/plugins/obs-qsv11/libmfx/src/mfx_dispatcher.cpp b/plugins/obs-qsv11/libmfx/src/mfx_dispatcher.cpp new file mode 100644 index 0000000..0b42d02 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/src/mfx_dispatcher.cpp @@ -0,0 +1,349 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2015 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_dispatcher.cpp + +\* ****************************************************************************** */ + +#include "mfx_dispatcher.h" +#include "mfx_dispatcher_log.h" +#include "mfx_load_dll.h" + +#include +#if defined(_WIN32) || defined(_WIN64) + #include + #pragma warning(disable:4355) +#else + +#include +#include + +#endif // defined(_WIN32) || defined(_WIN64) + +MFX_DISP_HANDLE::MFX_DISP_HANDLE(const mfxVersion requiredVersion) : + apiVersion(requiredVersion), + pluginFactory((mfxSession)this) +{ + actualApiVersion.Version = 0; + implType = MFX_LIB_SOFTWARE; + impl = MFX_IMPL_SOFTWARE; + loadStatus = MFX_ERR_NOT_FOUND; + dispVersion.Major = MFX_DISPATCHER_VERSION_MAJOR; + dispVersion.Minor = MFX_DISPATCHER_VERSION_MINOR; + session = (mfxSession) 0; + + hModule = (mfxModuleHandle) 0; + + memset(callTable, 0, sizeof(callTable)); + memset(callAudioTable, 0, sizeof(callAudioTable)); + +} // MFX_DISP_HANDLE::MFX_DISP_HANDLE(const mfxVersion requiredVersion) + +MFX_DISP_HANDLE::~MFX_DISP_HANDLE(void) +{ + Close(); + +} // MFX_DISP_HANDLE::~MFX_DISP_HANDLE(void) + +mfxStatus MFX_DISP_HANDLE::Close(void) +{ + mfxStatus mfxRes; + + mfxRes = UnLoadSelectedDLL(); + + // the library wasn't unloaded + if (MFX_ERR_NONE == mfxRes) + { + implType = MFX_LIB_SOFTWARE; + impl = MFX_IMPL_SOFTWARE; + loadStatus = MFX_ERR_NOT_FOUND; + dispVersion.Major = MFX_DISPATCHER_VERSION_MAJOR; + dispVersion.Minor = MFX_DISPATCHER_VERSION_MINOR; + session = (mfxSession) 0; + + hModule = (mfxModuleHandle) 0; + + memset(callTable, 0, sizeof(callTable)); + memset(callAudioTable, 0, sizeof(callAudioTable)); + } + + return mfxRes; + +} // mfxStatus MFX_DISP_HANDLE::Close(void) + +mfxStatus MFX_DISP_HANDLE::LoadSelectedDLL(const msdk_disp_char *pPath, eMfxImplType implType, + mfxIMPL impl, mfxIMPL implInterface, mfxInitParam &par) +{ + mfxStatus mfxRes = MFX_ERR_NONE; + + // check error(s) + if ((MFX_LIB_SOFTWARE != implType) && + (MFX_LIB_HARDWARE != implType)) + { + DISPATCHER_LOG_ERROR((("implType == %s, should be either MFX_LIB_SOFTWARE ot MFX_LIB_HARDWARE\n"), DispatcherLog_GetMFXImplString(implType).c_str())); + loadStatus = MFX_ERR_ABORTED; + return loadStatus; + } + // only exact types of implementation is allowed + if (!(impl & MFX_IMPL_AUDIO) && + (MFX_IMPL_SOFTWARE != impl) && + (MFX_IMPL_HARDWARE != impl) && + (MFX_IMPL_HARDWARE2 != impl) && + (MFX_IMPL_HARDWARE3 != impl) && + (MFX_IMPL_HARDWARE4 != impl)) + { + DISPATCHER_LOG_ERROR((("invalid implementation impl == %s\n"), DispatcherLog_GetMFXImplString(impl).c_str())); + loadStatus = MFX_ERR_ABORTED; + return loadStatus; + } + // only mfxExtThreadsParam is allowed + if (par.NumExtParam) + { + if ((par.NumExtParam > 1) || !par.ExtParam) + { + loadStatus = MFX_ERR_ABORTED; + return loadStatus; + } + if ((par.ExtParam[0]->BufferId != MFX_EXTBUFF_THREADS_PARAM) || + (par.ExtParam[0]->BufferSz != sizeof(mfxExtThreadsParam))) + { + loadStatus = MFX_ERR_ABORTED; + return loadStatus; + } + } + + // close the handle before initialization + Close(); + + // save the library's type + this->implType = implType; + this->impl = impl; + this->implInterface = implInterface; + + { + DISPATCHER_LOG_BLOCK(("invoking LoadLibrary(%S)\n", MSDK2WIDE(pPath))); + // load the DLL into the memory + hModule = MFX::mfx_dll_load(pPath); + + if (hModule) + { + int i; + + DISPATCHER_LOG_OPERATION({ + msdk_disp_char modulePath[1024]; + GetModuleFileNameW((HMODULE)hModule, modulePath, sizeof(modulePath)/sizeof(modulePath[0])); + DISPATCHER_LOG_INFO((("loaded module %S\n"), MSDK2WIDE(modulePath))) + }); + + if (impl & MFX_IMPL_AUDIO) + { + // load audio functions: pointers to exposed functions + for (i = 0; i < eAudioFuncTotal; i += 1) + { + // construct correct name of the function - remove "_a" postfix + + mfxFunctionPointer pProc = (mfxFunctionPointer) MFX::mfx_dll_get_addr(hModule, APIAudioFunc[i].pName); + #ifdef ANDROID + // on Android very first call to dlsym may fail + if (!pProc) pProc = (mfxFunctionPointer) MFX::mfx_dll_get_addr(hModule, APIAudioFunc[i].pName); + #endif + if (pProc) + { + // function exists in the library, + // save the pointer. + callAudioTable[i] = pProc; + } + else + { + // The library doesn't contain the function + DISPATCHER_LOG_WRN((("Can't find API function \"%s\"\n"), APIAudioFunc[i].pName)); + if (apiVersion.Version >= APIAudioFunc[i].apiVersion.Version) + { + DISPATCHER_LOG_ERROR((("\"%s\" is required for API %u.%u\n"), APIAudioFunc[i].pName, apiVersion.Major, apiVersion.Minor)); + mfxRes = MFX_ERR_UNSUPPORTED; + break; + } + } + } + } + else + { + // load video functions: pointers to exposed functions + for (i = 0; i < eVideoFuncTotal; i += 1) + { + mfxFunctionPointer pProc = (mfxFunctionPointer) MFX::mfx_dll_get_addr(hModule, APIFunc[i].pName); + #ifdef ANDROID + // on Android very first call to dlsym may fail + if (!pProc) pProc = (mfxFunctionPointer) MFX::mfx_dll_get_addr(hModule, APIFunc[i].pName); + #endif + if (pProc) + { + // function exists in the library, + // save the pointer. + callTable[i] = pProc; + } + else + { + // The library doesn't contain the function + DISPATCHER_LOG_WRN((("Can't find API function \"%s\"\n"), APIFunc[i].pName)); + if (apiVersion.Version >= APIFunc[i].apiVersion.Version) + { + DISPATCHER_LOG_ERROR((("\"%s\" is required for API %u.%u\n"), APIFunc[i].pName, apiVersion.Major, apiVersion.Minor)); + mfxRes = MFX_ERR_UNSUPPORTED; + break; + } + } + } + } + } + else + { +#if defined(_WIN32) || defined(_WIN64) + DISPATCHER_LOG_WRN((("can't find DLL: GetLastErr()=0x%x\n"), GetLastError())) +#else + DISPATCHER_LOG_WRN((("can't find DLL: dlerror() = \"%s\"\n"), dlerror())); +#endif + mfxRes = MFX_ERR_UNSUPPORTED; + } + } + + // initialize the loaded DLL + if (MFX_ERR_NONE == mfxRes) + { + mfxVersion version(apiVersion); + + /* check whether it is audio session or video */ + mfxFunctionPointer *actualTable = (impl & MFX_IMPL_AUDIO) ? callAudioTable : callTable; + + // Call old-style MFXInit init for older libraries and audio library + bool callOldInit = (impl & MFX_IMPL_AUDIO) || !actualTable[eMFXInitEx]; // if true call eMFXInit, if false - eMFXInitEx + int tableIndex = (callOldInit) ? eMFXInit : eMFXInitEx; + + mfxFunctionPointer pFunc = actualTable[tableIndex]; + + { + if (callOldInit) + { + DISPATCHER_LOG_BLOCK(("MFXInit(%s,ver=%u.%u,session=0x%p)\n" + , DispatcherLog_GetMFXImplString(impl | implInterface).c_str() + , apiVersion.Major + , apiVersion.Minor + , &session)); + + mfxRes = (*(mfxStatus(MFX_CDECL *) (mfxIMPL, mfxVersion *, mfxSession *)) pFunc) (impl | implInterface, &version, &session); + } + else + { + DISPATCHER_LOG_BLOCK(("MFXInitEx(%s,ver=%u.%u,ExtThreads=%d,session=0x%p)\n" + , DispatcherLog_GetMFXImplString(impl | implInterface).c_str() + , apiVersion.Major + , apiVersion.Minor + , par.ExternalThreads + , &session)); + + mfxInitParam initPar = par; + // adjusting user parameters + initPar.Implementation = impl | implInterface; + initPar.Version = version; + mfxRes = (*(mfxStatus(MFX_CDECL *) (mfxInitParam, mfxSession *)) pFunc) (initPar, &session); + } + } + + if (MFX_ERR_NONE != mfxRes) + { + DISPATCHER_LOG_WRN((("library can't be load. MFXInit returned %s \n"), DispatcherLog_GetMFXStatusString(mfxRes))) + } + else + { + mfxRes = MFXQueryVersion((mfxSession) this, &actualApiVersion); + + if (MFX_ERR_NONE != mfxRes) + { + DISPATCHER_LOG_ERROR((("MFXQueryVersion returned: %d, skiped this library\n"), mfxRes)) + } + else + { + DISPATCHER_LOG_INFO((("MFXQueryVersion returned API: %d.%d\n"), actualApiVersion.Major, actualApiVersion.Minor)) + //special hook for applications that uses sink api to get loaded library path + DISPATCHER_LOG_LIBRARY(("%p" , hModule)); + DISPATCHER_LOG_INFO(("library loaded succesfully\n")) + } + } + } + + loadStatus = mfxRes; + return mfxRes; + +} // mfxStatus MFX_DISP_HANDLE::LoadSelectedDLL(const msdk_disp_char *pPath, eMfxImplType implType, mfxIMPL impl) + +mfxStatus MFX_DISP_HANDLE::UnLoadSelectedDLL(void) +{ + mfxStatus mfxRes = MFX_ERR_NONE; + + //unregistered plugins if any + pluginFactory.Close(); + + // close the loaded DLL + if (session) + { + /* check whether it is audio session or video */ + int tableIndex = eMFXClose; + mfxFunctionPointer pFunc; + if (impl & MFX_IMPL_AUDIO) + { + pFunc = callAudioTable[tableIndex]; + } + else + { + pFunc = callTable[tableIndex]; + } + + mfxRes = (*(mfxStatus (MFX_CDECL *) (mfxSession)) pFunc) (session); + if (MFX_ERR_NONE == mfxRes) + { + session = (mfxSession) 0; + } + + DISPATCHER_LOG_INFO((("MFXClose(0x%x) returned %d\n"), session, mfxRes)); + // actually, the return value is required to pass outside only. + } + + // it is possible, that there is an active child session. + // can't unload library in that case. + if ((MFX_ERR_UNDEFINED_BEHAVIOR != mfxRes) && + (hModule)) + { + // unload the library. + if (!MFX::mfx_dll_free(hModule)) + { + mfxRes = MFX_ERR_UNDEFINED_BEHAVIOR; + } + hModule = (mfxModuleHandle) 0; + } + + return mfxRes; + +} // mfxStatus MFX_DISP_HANDLE::UnLoadSelectedDLL(void) \ No newline at end of file diff --git a/plugins/obs-qsv11/libmfx/src/mfx_dispatcher_log.cpp b/plugins/obs-qsv11/libmfx/src/mfx_dispatcher_log.cpp new file mode 100644 index 0000000..d355b1a --- /dev/null +++ b/plugins/obs-qsv11/libmfx/src/mfx_dispatcher_log.cpp @@ -0,0 +1,449 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_dispatcher_log.h + +\* ****************************************************************************** */ + +#if defined(MFX_DISPATCHER_LOG) + +#include "mfx_dispatcher_log.h" +#include "mfxstructures.h" +#if defined(_WIN32) || defined(_WIN64) +#include +#if defined(DISPATCHER_LOG_REGISTER_EVENT_PROVIDER) +#include +#include +#endif +#endif // #if defined(_WIN32) || defined(_WIN64) +#include +#include +#include +#include + +struct CodeStringTable +{ + int code; + const char *string; +} LevelStrings []= +{ + {DL_INFO, "INFO: "}, + {DL_WRN, "WARNING:"}, + {DL_ERROR, "ERROR: "} +}; + +#define DEFINE_CODE(code)\ + {code, #code} + +static CodeStringTable StringsOfImpl[] = { + DEFINE_CODE(MFX_IMPL_AUTO), + DEFINE_CODE(MFX_IMPL_SOFTWARE), + DEFINE_CODE(MFX_IMPL_HARDWARE), + DEFINE_CODE(MFX_IMPL_AUTO_ANY), + DEFINE_CODE(MFX_IMPL_HARDWARE_ANY), + DEFINE_CODE(MFX_IMPL_HARDWARE2), + DEFINE_CODE(MFX_IMPL_HARDWARE3), + DEFINE_CODE(MFX_IMPL_HARDWARE4), + + DEFINE_CODE(MFX_IMPL_UNSUPPORTED) +}; + +static CodeStringTable StringsOfImplVIA[] = { + DEFINE_CODE(MFX_IMPL_VIA_ANY), + DEFINE_CODE(MFX_IMPL_VIA_D3D9), + DEFINE_CODE(MFX_IMPL_VIA_D3D11), +}; + +static CodeStringTable StringsOfStatus[] = +{ + DEFINE_CODE(MFX_ERR_NONE ), + DEFINE_CODE(MFX_ERR_UNKNOWN ), + DEFINE_CODE(MFX_ERR_NULL_PTR ), + DEFINE_CODE(MFX_ERR_UNSUPPORTED ), + DEFINE_CODE(MFX_ERR_MEMORY_ALLOC ), + DEFINE_CODE(MFX_ERR_NOT_ENOUGH_BUFFER ), + DEFINE_CODE(MFX_ERR_INVALID_HANDLE ), + DEFINE_CODE(MFX_ERR_LOCK_MEMORY ), + DEFINE_CODE(MFX_ERR_NOT_INITIALIZED ), + DEFINE_CODE(MFX_ERR_NOT_FOUND ), + DEFINE_CODE(MFX_ERR_MORE_DATA ), + DEFINE_CODE(MFX_ERR_MORE_SURFACE ), + DEFINE_CODE(MFX_ERR_ABORTED ), + DEFINE_CODE(MFX_ERR_DEVICE_LOST ), + DEFINE_CODE(MFX_ERR_INCOMPATIBLE_VIDEO_PARAM), + DEFINE_CODE(MFX_ERR_INVALID_VIDEO_PARAM ), + DEFINE_CODE(MFX_ERR_UNDEFINED_BEHAVIOR ), + DEFINE_CODE(MFX_ERR_DEVICE_FAILED ), + DEFINE_CODE(MFX_WRN_IN_EXECUTION ), + DEFINE_CODE(MFX_WRN_DEVICE_BUSY ), + DEFINE_CODE(MFX_WRN_VIDEO_PARAM_CHANGED ), + DEFINE_CODE(MFX_WRN_PARTIAL_ACCELERATION ), + DEFINE_CODE(MFX_WRN_INCOMPATIBLE_VIDEO_PARAM), + DEFINE_CODE(MFX_WRN_VALUE_NOT_CHANGED ), + DEFINE_CODE(MFX_WRN_OUT_OF_RANGE ), + +}; + +#define CODE_TO_STRING(code, array)\ + CodeToString(code, array, sizeof(array)/sizeof(array[0])) + +const char* CodeToString(int code, CodeStringTable array[], int len ) +{ + for (int i = 0 ; i < len; i++) + { + if (array[i].code == code) + return array[i].string; + } + return "undef"; +} + +std::string DispatcherLog_GetMFXImplString(int impl) +{ + std::string str1 = CODE_TO_STRING(impl & ~(-MFX_IMPL_VIA_ANY), StringsOfImpl); + std::string str2 = CODE_TO_STRING(impl & (-MFX_IMPL_VIA_ANY), StringsOfImplVIA); + + return str1 + (str2 == "undef" ? "" : "|"+str2); +} + +const char *DispatcherLog_GetMFXStatusString(int sts) +{ + return CODE_TO_STRING(sts, StringsOfStatus); +} + +////////////////////////////////////////////////////////////////////////// + + +void DispatcherLogBracketsHelper::Write(const char * str, ...) +{ + va_list argsptr; + va_start(argsptr, str); + DispatchLog::get().Write(m_level, m_opcode, str, argsptr); + va_end(argsptr); +} + +void DispatchLogBlockHelper::Write(const char * str, ...) +{ + va_list argsptr; + va_start(argsptr, str); + DispatchLog::get().Write(m_level, DL_EVENT_START, str, argsptr); + va_end(argsptr); +} + +DispatchLogBlockHelper::~DispatchLogBlockHelper() +{ + DispatchLog::get().Write(m_level, DL_EVENT_STOP, NULL, NULL); +} + +////////////////////////////////////////////////////////////////////////// + +DispatchLog::DispatchLog() + : m_DispatcherLogSink(DL_SINK_PRINTF) +{ + +} + +void DispatchLog::SetSink(int nSink, IMsgHandler * pHandler) +{ + DetachAllSinks(); + AttachSink(nSink, pHandler); +} + +void DispatchLog::AttachSink(int nsink, IMsgHandler *pHandler) +{ + m_DispatcherLogSink |= nsink; + if (NULL != pHandler) + m_Recepients.push_back(pHandler); +} + +void DispatchLog::DetachSink(int nsink, IMsgHandler *pHandler) +{ + if (nsink & DL_SINK_IMsgHandler) + { + m_Recepients.remove(pHandler); + } + + m_DispatcherLogSink &= ~nsink; +} + +void DispatchLog::ExchangeSink(int nsink, IMsgHandler *oldHdl, IMsgHandler *newHdl) +{ + if (nsink & DL_SINK_IMsgHandler) + { + std::list :: iterator it = std::find(m_Recepients.begin(), m_Recepients.end(), oldHdl); + + //cannot exchange in that case + if (m_Recepients.end() == it) + return; + + *it = newHdl; + } +} + + +void DispatchLog::DetachAllSinks() +{ + m_Recepients.clear(); + m_DispatcherLogSink = DL_SINK_NULL; +} + +void DispatchLog::Write(int level, int opcode, const char * msg, va_list argptr) +{ + int sinkTable[] = + { + DL_SINK_PRINTF, + DL_SINK_IMsgHandler, + }; + + for (size_t i = 0; i < sizeof(sinkTable) / sizeof(sinkTable[0]); i++) + { + switch(m_DispatcherLogSink & sinkTable[i]) + { + case DL_SINK_NULL: + break; + + case DL_SINK_PRINTF: + { + char msg_formated[8048] = {0}; + + if (NULL != msg && level != DL_LOADED_LIBRARY) + { +#if _MSC_VER >= 1400 + vsprintf_s(msg_formated, sizeof(msg_formated)/sizeof(msg_formated[0]), msg, argptr); +#else + vsnprintf(msg_formated, sizeof(msg_formated)/sizeof(msg_formated[0]), msg, argptr); +#endif + //TODO: improve this , add opcode handling + printf("%s %s", CODE_TO_STRING(level, LevelStrings), msg_formated); + } + break; + } + + case DL_SINK_IMsgHandler: + { + std::list::iterator it; + + for (it = m_Recepients.begin(); it != m_Recepients.end(); ++it) + { + (*it)->Write(level, opcode, msg, argptr); + } + break; + } + } + } +} + +#if defined(DISPATCHER_LOG_REGISTER_EVENT_PROVIDER) +class ETWHandler : public IMsgHandler +{ +public: + ETWHandler(const wchar_t * guid_str) + : m_bUseFormatter(DISPATCHER_LOG_USE_FORMATING) + , m_EventHandle() + , m_bProviderEnable() + { + GUID rguid = GUID_NULL; + if (FAILED(CLSIDFromString(guid_str, &rguid))) + { + return; + } + + EventRegister(&rguid, NULL, NULL, &m_EventHandle); + + m_bProviderEnable = 0 != EventProviderEnabled(m_EventHandle, 1,0); + } + + ~ETWHandler() + { + if (m_EventHandle) + { + EventUnregister(m_EventHandle); + } + } + + virtual void Write(int level, int opcode, const char * msg, va_list argptr) + { + //event not registered + if (0==m_EventHandle) + { + return; + } + if (!m_bProviderEnable) + { + return; + } + if (level == DL_LOADED_LIBRARY) + { + return; + } + + char msg_formated[1024]; + EVENT_DESCRIPTOR descriptor; + EVENT_DATA_DESCRIPTOR data_descriptor; + + EventDescZero(&descriptor); + + descriptor.Opcode = (UCHAR)opcode; + descriptor.Level = (UCHAR)level; + + if (m_bUseFormatter) + { + if (NULL != msg) + { +#if _MSC_VER >= 1400 + vsprintf_s(msg_formated, sizeof (msg_formated) / sizeof (msg_formated[0]), msg, argptr); +#else + vsnprintf(msg_formated, sizeof (msg_formated) / sizeof (msg_formated[0]), msg, argptr); +#endif + EventDataDescCreate(&data_descriptor, msg_formated, (ULONG)(strlen(msg_formated) + 1)); + }else + { + EventDataDescCreate(&data_descriptor, NULL, 0); + } + }else + { + //TODO: non formated events supports under zbb + } + + EventWrite(m_EventHandle, &descriptor, 1, &data_descriptor); + } + +protected: + + //we may not use formatter in some cases described in dispatch_log macro + //it significantly increases performance by eliminating any vsprintf operations + bool m_bUseFormatter; + //consumer is attached, dispatcher trace to reduce formating overhead + //submits event only if consumer attached + bool m_bProviderEnable; + REGHANDLE m_EventHandle; +}; +// + + +IMsgHandler *ETWHandlerFactory::GetSink(const wchar_t* sguid) +{ + _storage_type::iterator it; + it = m_storage.find(sguid); + if (it == m_storage.end()) + { + ETWHandler * handler = new ETWHandler(sguid); + _storage_type::_Pairib it_bool = m_storage.insert(_storage_type::value_type(sguid, handler)); + it = it_bool.first; + } + + return it->second; +} + +ETWHandlerFactory::~ETWHandlerFactory() +{ + for each(_storage_type::value_type val in m_storage) + { + delete val.second; + } +} + +class EventRegistrator : public IMsgHandler +{ + const wchar_t * m_sguid; +public: + EventRegistrator(const wchar_t* sguid = DISPATCHER_LOG_EVENT_GUID) + :m_sguid(sguid) + { + DispatchLog::get().AttachSink( DL_SINK_IMsgHandler + , this); + } + + virtual void Write(int level, int opcode, const char * msg, va_list argptr) + { + //we cannot call attach sink since we may have been called from iteration + //we axchanging preserve that placeholding + IMsgHandler * pSink = NULL; + DispatchLog::get().ExchangeSink(DL_SINK_IMsgHandler, + this, + pSink = ETWHandlerFactory::get().GetSink(m_sguid)); + //need to call only once here all next calls will be done inside dispatcherlog + if (NULL != pSink) + { + pSink->Write(level, opcode, msg, argptr); + } + } +}; +#endif + +template +class SinkRegistrator +{ +}; + +#if defined(DISPATCHER_LOG_REGISTER_EVENT_PROVIDER) +template <> +class SinkRegistrator +{ +public: + SinkRegistrator(const wchar_t* sguid = DISPATCHER_LOG_EVENT_GUID) + { + DispatchLog::get().AttachSink( DL_SINK_IMsgHandler + , ETWHandlerFactory::get().GetSink(sguid)); + } +}; +#endif + +#if defined(DISPATCHER_LOG_REGISTER_FILE_WRITER) +template <> +class SinkRegistrator +{ +public: + SinkRegistrator() + { + DispatchLog::get().AttachSink( DL_SINK_IMsgHandler, &FileSink::get(DISPACTHER_LOG_FW_PATH)); + } +}; + +void FileSink::Write(int level, int /*opcode*/, const char * msg, va_list argptr) +{ + if (NULL != m_hdl && NULL != msg) + { + fprintf(m_hdl, "%s", CODE_TO_STRING(level, LevelStrings)); + vfprintf(m_hdl, msg, argptr); + } +} +#endif + +////////////////////////////////////////////////////////////////////////// +//singletons initialization section + + +#ifdef DISPATCHER_LOG_REGISTER_EVENT_PROVIDER + static SinkRegistrator g_registrator1; +#endif + + +#ifdef DISPATCHER_LOG_REGISTER_FILE_WRITER + static SinkRegistrator g_registrator2; +#endif + + +#endif//(MFX_DISPATCHER_LOG) \ No newline at end of file diff --git a/plugins/obs-qsv11/libmfx/src/mfx_dxva2_device.cpp b/plugins/obs-qsv11/libmfx/src/mfx_dxva2_device.cpp new file mode 100644 index 0000000..9ba86cb --- /dev/null +++ b/plugins/obs-qsv11/libmfx/src/mfx_dxva2_device.cpp @@ -0,0 +1,558 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_dxva2_device.cpp + +\* ****************************************************************************** */ + +#if defined(_WIN32) || defined(_WIN64) + +#define INITGUID +#include +#include + +#include "mfx_dxva2_device.h" + + +using namespace MFX; + + +DXDevice::DXDevice(void) +{ + m_hModule = (HMODULE) 0; + + m_numAdapters = 0; + + m_vendorID = 0; + m_deviceID = 0; + m_driverVersion = 0; + m_luid = 0; + +} // DXDevice::DXDevice(void) + +DXDevice::~DXDevice(void) +{ + Close(); + + // free DX library only when device is destroyed + UnloadDLLModule(); + +} // DXDevice::~DXDevice(void) + +mfxU32 DXDevice::GetVendorID(void) const +{ + return m_vendorID; + +} // mfxU32 DXDevice::GetVendorID(void) const + +mfxU32 DXDevice::GetDeviceID(void) const +{ + return m_deviceID; + +} // mfxU32 DXDevice::GetDeviceID(void) const + +mfxU64 DXDevice::GetDriverVersion(void) const +{ + return m_driverVersion; + +}// mfxU64 DXDevice::GetDriverVersion(void) const + +mfxU64 DXDevice::GetLUID(void) const +{ + return m_luid; + +} // mfxU64 DXDevice::GetLUID(void) const + +mfxU32 DXDevice::GetAdapterCount(void) const +{ + return m_numAdapters; + +} // mfxU32 DXDevice::GetAdapterCount(void) const + +void DXDevice::Close(void) +{ + m_numAdapters = 0; + + m_vendorID = 0; + m_deviceID = 0; + m_luid = 0; + +} // void DXDevice::Close(void) + +void DXDevice::LoadDLLModule(const wchar_t *pModuleName) +{ + DWORD prevErrorMode = 0; + + // unload the module if it is required + UnloadDLLModule(); + + // set the silent error mode +#if (_WIN32_WINNT >= 0x0600) && !(__GNUC__) + SetThreadErrorMode(SEM_FAILCRITICALERRORS, &prevErrorMode); +#else + prevErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); +#endif + // load specified library + m_hModule = LoadLibraryExW(pModuleName, NULL, 0); + + // set the previous error mode +#if (_WIN32_WINNT >= 0x0600) && !(__GNUC__) + SetThreadErrorMode(prevErrorMode, NULL); +#else + SetErrorMode(prevErrorMode); +#endif + +} // void LoadDLLModule(const wchar_t *pModuleName) + +void DXDevice::UnloadDLLModule(void) +{ + if (m_hModule) + { + FreeLibrary(m_hModule); + m_hModule = (HMODULE) 0; + } + +} // void DXDevice::UnloaDLLdModule(void) + + +D3D9Device::D3D9Device(void) +{ + m_pD3D9 = (void *) 0; + m_pD3D9Ex = (void *) 0; + +} // D3D9Device::D3D9Device(void) + +D3D9Device::~D3D9Device(void) +{ + Close(); + +} // D3D9Device::~D3D9Device(void) + +void D3D9Device::Close(void) +{ + // release the interfaces + if (m_pD3D9Ex) + { + ((IDirect3D9Ex *) m_pD3D9Ex)->Release(); + } + + // release the interfaces + if (m_pD3D9) + { + ((IDirect3D9 *) m_pD3D9)->Release(); + } + + m_pD3D9 = (void *) 0; + m_pD3D9Ex = (void *) 0; + +} // void D3D9Device::Close(void) + +typedef + IDirect3D9 * (WINAPI *D3DCreateFunctionPtr_t) (UINT); + +typedef + HRESULT (WINAPI *D3DExCreateFunctionPtr_t) (UINT, IDirect3D9Ex **); + +bool D3D9Device::Init(const mfxU32 adapterNum) +{ + // close the device before initialization + Close(); + + // load the library + if (NULL == m_hModule) + { + LoadDLLModule(L"d3d9.dll"); + } + + if (m_hModule) + { + D3DCreateFunctionPtr_t pFunc; + + // load address of procedure to create D3D device + pFunc = (D3DCreateFunctionPtr_t) GetProcAddress(m_hModule, "Direct3DCreate9"); + if (pFunc) + { + D3DADAPTER_IDENTIFIER9 adapterIdent; + IDirect3D9 *pD3D9; + HRESULT hRes; + + // create D3D object + m_pD3D9 = pFunc(D3D_SDK_VERSION); + + if (NULL == m_pD3D9) + { + DXVA2DEVICE_TRACE(("FAIL: Direct3DCreate9(%d) : GetLastError()=0x%x", D3D_SDK_VERSION, GetLastError())); + return false; + } + + // cast the interface + pD3D9 = (IDirect3D9 *) m_pD3D9; + + m_numAdapters = pD3D9->GetAdapterCount(); + if (adapterNum >= m_numAdapters) + { + return false; + } + + // get the card's parameters + hRes = pD3D9->GetAdapterIdentifier(adapterNum, 0, &adapterIdent); + if (D3D_OK != hRes) + { + DXVA2DEVICE_TRACE(("FAIL: GetAdapterIdentifier(%d) = 0x%x \n", adapterNum, hRes)); + return false; + } + + m_vendorID = adapterIdent.VendorId; + m_deviceID = adapterIdent.DeviceId; + m_driverVersion = (mfxU64)adapterIdent.DriverVersion.QuadPart; + + // load LUID + IDirect3D9Ex *pD3D9Ex; + D3DExCreateFunctionPtr_t pFuncEx; + LUID d3d9LUID; + + // find the appropriate function + pFuncEx = (D3DExCreateFunctionPtr_t) GetProcAddress(m_hModule, "Direct3DCreate9Ex"); + if (NULL == pFuncEx) + { + // the extended interface is not supported + return true; + } + + // create extended interface + hRes = pFuncEx(D3D_SDK_VERSION, &pD3D9Ex); + if (FAILED(hRes)) + { + // can't create extended interface + return true; + } + m_pD3D9Ex = pD3D9Ex; + + // obtain D3D9 device LUID + hRes = pD3D9Ex->GetAdapterLUID(adapterNum, &d3d9LUID); + if (FAILED(hRes)) + { + // can't get LUID + return true; + } + // copy the LUID + *((LUID *) &m_luid) = d3d9LUID; + } + else + { + DXVA2DEVICE_TRACE_OPERATION({ + wchar_t path[1024]; + DWORD lastErr = GetLastError(); + GetModuleFileNameW(m_hModule, path, sizeof(path)/sizeof(path[0])); + DXVA2DEVICE_TRACE(("FAIL: invoking GetProcAddress(Direct3DCreate9) in %S : GetLastError()==0x%x\n", path, lastErr)); }); + return false; + } + } + else + { + DXVA2DEVICE_TRACE(("FAIL: invoking LoadLibrary(\"d3d9.dll\") : GetLastError()==0x%x\n", GetLastError())); + return false; + } + + return true; + +} // bool D3D9Device::Init(const mfxU32 adapterNum) + +typedef +HRESULT (WINAPI *DXGICreateFactoryFunc) (REFIID riid, void **ppFactory); + +DXGI1Device::DXGI1Device(void) +{ + m_pDXGIFactory1 = (void *) 0; + m_pDXGIAdapter1 = (void *) 0; + +} // DXGI1Device::DXGI1Device(void) + +DXGI1Device::~DXGI1Device(void) +{ + Close(); + +} // DXGI1Device::~DXGI1Device(void) + +void DXGI1Device::Close(void) +{ + // release the interfaces + if (m_pDXGIAdapter1) + { + ((IDXGIAdapter1 *) m_pDXGIAdapter1)->Release(); + } + + if (m_pDXGIFactory1) + { + ((IDXGIFactory1 *) m_pDXGIFactory1)->Release(); + } + + m_pDXGIFactory1 = (void *) 0; + m_pDXGIAdapter1 = (void *) 0; + +} // void DXGI1Device::Close(void) + +bool DXGI1Device::Init(const mfxU32 adapterNum) +{ + // release the object before initialization + Close(); + + // load up the library if it is not loaded + if (NULL == m_hModule) + { + LoadDLLModule(L"dxgi.dll"); + } + + if (m_hModule) + { + DXGICreateFactoryFunc pFunc; + IDXGIFactory1 *pFactory; + IDXGIAdapter1 *pAdapter; + DXGI_ADAPTER_DESC1 desc; + mfxU32 curAdapter, maxAdapters; + HRESULT hRes; + + // load address of procedure to create DXGI 1.1 factory + pFunc = (DXGICreateFactoryFunc) GetProcAddress(m_hModule, "CreateDXGIFactory1"); + if (NULL == pFunc) + { + return false; + } + + // create the factory +#if _MSC_VER >= 1400 + hRes = pFunc(__uuidof(IDXGIFactory1), (void**) (&pFactory)); +#else + hRes = pFunc(IID_IDXGIFactory1, (void**) (&pFactory)); +#endif + if (FAILED(hRes)) + { + return false; + } + m_pDXGIFactory1 = pFactory; + + // get the number of adapters + curAdapter = 0; + maxAdapters = 0; + do + { + // get the required adapted + hRes = pFactory->EnumAdapters1(curAdapter, &pAdapter); + if (FAILED(hRes)) + { + break; + } + + // if it is the required adapter, save the interface + if (curAdapter == adapterNum) + { + m_pDXGIAdapter1 = pAdapter; + } + else + { + pAdapter->Release(); + } + + // get the next adapter + curAdapter += 1; + + } while (SUCCEEDED(hRes)); + maxAdapters = curAdapter; + + // there is no required adapter + if (adapterNum >= maxAdapters) + { + return false; + } + pAdapter = (IDXGIAdapter1 *) m_pDXGIAdapter1; + + // get the adapter's parameters + hRes = pAdapter->GetDesc1(&desc); + if (FAILED(hRes)) + { + return false; + } + + // save the parameters + m_vendorID = desc.VendorId; + m_deviceID = desc.DeviceId; + *((LUID *) &m_luid) = desc.AdapterLuid; + } + + return true; + +} // bool DXGI1Device::Init(const mfxU32 adapterNum) + +DXVA2Device::DXVA2Device(void) +{ + m_numAdapters = 0; + + m_vendorID = 0; + m_deviceID = 0; + +} // DXVA2Device::DXVA2Device(void) + +DXVA2Device::~DXVA2Device(void) +{ + Close(); + +} // DXVA2Device::~DXVA2Device(void) + +void DXVA2Device::Close(void) +{ + m_numAdapters = 0; + + m_vendorID = 0; + m_deviceID = 0; + +} // void DXVA2Device::Close(void) + +bool DXVA2Device::InitD3D9(const mfxU32 adapterNum) +{ + D3D9Device d3d9Device; + bool bRes; + + // release the object before initialization + Close(); + + // create 'old fashion' device + bRes = d3d9Device.Init(adapterNum); + if (false == bRes) + { + return false; + } + + m_numAdapters = d3d9Device.GetAdapterCount(); + + // check if the application is under Remote Desktop + if ((0 == d3d9Device.GetVendorID()) || (0 == d3d9Device.GetDeviceID())) + { + // get the required parameters alternative way and ... + UseAlternativeWay(&d3d9Device); + } + else + { + // save the parameters and ... + m_vendorID = d3d9Device.GetVendorID(); + m_deviceID = d3d9Device.GetDeviceID(); + m_driverVersion = d3d9Device.GetDriverVersion(); + } + + // ... say goodbye + return true; +} // bool InitD3D9(const mfxU32 adapterNum) + +bool DXVA2Device::InitDXGI1(const mfxU32 adapterNum) +{ + DXGI1Device dxgi1Device; + bool bRes; + + // release the object before initialization + Close(); + + // create modern DXGI device + bRes = dxgi1Device.Init(adapterNum); + if (false == bRes) + { + return false; + } + + // save the parameters and ... + m_vendorID = dxgi1Device.GetVendorID(); + m_deviceID = dxgi1Device.GetDeviceID(); + m_numAdapters = dxgi1Device.GetAdapterCount(); + + // ... say goodbye + return true; + +} // bool DXVA2Device::InitDXGI1(const mfxU32 adapterNum) + +void DXVA2Device::UseAlternativeWay(const D3D9Device *pD3D9Device) +{ + mfxU64 d3d9LUID = pD3D9Device->GetLUID(); + + // work only with valid LUIDs + if (0 == d3d9LUID) + { + return; + } + + DXGI1Device dxgi1Device; + mfxU32 curDevice = 0; + bool bRes = false; + + do + { + // initialize the next DXGI1 or DXGI device + bRes = dxgi1Device.Init(curDevice); + if (false == bRes) + { + // there is no more devices + break; + } + + // is it required device ? + if (d3d9LUID == dxgi1Device.GetLUID()) + { + m_vendorID = dxgi1Device.GetVendorID(); + m_deviceID = dxgi1Device.GetDeviceID(); + m_driverVersion = dxgi1Device.GetDriverVersion(); + return ; + } + + // get the next device + curDevice += 1; + + } while (bRes); + + dxgi1Device.Close(); + // we need to match a DXGI(1) device to the D3D9 device + +} // void DXVA2Device::UseAlternativeWay(const D3D9Device *pD3D9Device) + +mfxU32 DXVA2Device::GetVendorID(void) const +{ + return m_vendorID; + +} // mfxU32 DXVA2Device::GetVendorID(void) const + +mfxU32 DXVA2Device::GetDeviceID(void) const +{ + return m_deviceID; + +} // mfxU32 DXVA2Device::GetDeviceID(void) const + +mfxU64 DXVA2Device::GetDriverVersion(void) const +{ + return m_driverVersion; +}// mfxU64 DXVA2Device::GetDriverVersion(void) const + +mfxU32 DXVA2Device::GetAdapterCount(void) const +{ + return m_numAdapters; + +} // mfxU32 DXVA2Device::GetAdapterCount(void) const +#endif diff --git a/plugins/obs-qsv11/libmfx/src/mfx_function_table.cpp b/plugins/obs-qsv11/libmfx/src/mfx_function_table.cpp new file mode 100644 index 0000000..8da6a51 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/src/mfx_function_table.cpp @@ -0,0 +1,143 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_function_table.cpp + +\* ****************************************************************************** */ + +#include "mfx_dispatcher.h" + +// +// implement a table with functions names +// + +#undef FUNCTION +#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \ + {#func_name, API_VERSION}, + +const +FUNCTION_DESCRIPTION APIFunc[eVideoFuncTotal] = +{ + {"MFXInit", {{0, 1}}}, + {"MFXClose", {{0, 1}}}, + {"MFXQueryIMPL", {{0, 1}}}, + {"MFXQueryVersion", {{0, 1}}}, + + {"MFXJoinSession", {{1, 1}}}, + {"MFXDisjoinSession", {{1, 1}}}, + {"MFXCloneSession", {{1, 1}}}, + {"MFXSetPriority", {{1, 1}}}, + {"MFXGetPriority", {{1, 1}}}, + + {"MFXInitEx", {{1, 14}}}, + +#include "mfx_exposed_functions_list.h" +}; + +const +FUNCTION_DESCRIPTION APIAudioFunc[eAudioFuncTotal] = +{ + {"MFXInit", {{8, 1}}}, + {"MFXClose", {{8, 1}}}, + {"MFXQueryIMPL", {{8, 1}}}, + {"MFXQueryVersion", {{8, 1}}}, + + {"MFXJoinSession", {{8, 1}}}, + {"MFXDisjoinSession", {{8, 1}}}, + {"MFXCloneSession", {{8, 1}}}, + {"MFXSetPriority", {{8, 1}}}, + {"MFXGetPriority", {{8, 1}}}, + +#include "mfxaudio_exposed_functions_list.h" +}; + +// static section of the file +namespace +{ + +// +// declare pseudo-functions. +// they are used as default values for call-tables. +// + +mfxStatus pseudoMFXInit(mfxIMPL impl, mfxVersion *ver, mfxSession *session) +{ + // touch unreferenced parameters + impl = impl; + ver = ver; + session = session; + + return MFX_ERR_UNKNOWN; + +} // mfxStatus pseudoMFXInit(mfxIMPL impl, mfxVersion *ver, mfxSession *session) + +mfxStatus pseudoMFXClose(mfxSession session) +{ + // touch unreferenced parameters + session = session; + + return MFX_ERR_UNKNOWN; + +} // mfxStatus pseudoMFXClose(mfxSession session) + +mfxStatus pseudoMFXJoinSession(mfxSession session, mfxSession child_session) +{ + // touch unreferenced parameters + session = session; + child_session = child_session; + + return MFX_ERR_UNKNOWN; + +} // mfxStatus pseudoMFXJoinSession(mfxSession session, mfxSession child_session) + +mfxStatus pseudoMFXCloneSession(mfxSession session, mfxSession *clone) +{ + // touch unreferenced parameters + session = session; + clone = clone; + + return MFX_ERR_UNKNOWN; + +} // mfxStatus pseudoMFXCloneSession(mfxSession session, mfxSession *clone) + +void SuppressWarnings(...) +{ + // this functions is suppose to suppress warnings. + // Actually it does nothing. + +} // void SuppressWarnings(...) + +#undef FUNCTION +#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \ +return_value pseudo##func_name formal_param_list \ +{ \ + SuppressWarnings actual_param_list; \ + return MFX_ERR_UNKNOWN; \ +} + +#include "mfx_exposed_functions_list.h" + +} // namespace diff --git a/plugins/obs-qsv11/libmfx/src/mfx_library_iterator.cpp b/plugins/obs-qsv11/libmfx/src/mfx_library_iterator.cpp new file mode 100644 index 0000000..cdbb125 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/src/mfx_library_iterator.cpp @@ -0,0 +1,475 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2015 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_library_iterator.cpp + +\* ****************************************************************************** */ + +#if defined(_WIN32) || defined(_WIN64) + +#include "mfx_library_iterator.h" + +#include "mfx_dispatcher.h" +#include "mfx_dispatcher_log.h" + +#include "mfx_dxva2_device.h" +#include "mfx_load_dll.h" + +#include +#include + +namespace MFX +{ + +enum +{ + MFX_MAX_MERIT = 0x7fffffff +}; + +// +// declare registry keys +// + +const +wchar_t rootDispPath[] = L"Software\\Intel\\MediaSDK\\Dispatch"; +const +wchar_t vendorIDKeyName[] = L"VendorID"; +const +wchar_t deviceIDKeyName[] = L"DeviceID"; +const +wchar_t meritKeyName[] = L"Merit"; +const +wchar_t pathKeyName[] = L"Path"; +const +wchar_t apiVersionName[] = L"APIVersion"; + +mfxStatus SelectImplementationType(const mfxU32 adapterNum, mfxIMPL *pImplInterface, mfxU32 *pVendorID, mfxU32 *pDeviceID) +{ + if (NULL == pImplInterface) + { + return MFX_ERR_NULL_PTR; + } + + DXVA2Device dxvaDevice; + if (MFX_IMPL_VIA_D3D9 == *pImplInterface) + { + // try to create the Direct3D 9 device and find right adapter + if (!dxvaDevice.InitD3D9(adapterNum)) + { + DISPATCHER_LOG_INFO((("dxvaDevice.InitD3D9(%d) Failed "), adapterNum )); + return MFX_ERR_UNSUPPORTED; + } + } + else if (MFX_IMPL_VIA_D3D11 == *pImplInterface) + { + // try to open DXGI 1.1 device to get hardware ID + if (!dxvaDevice.InitDXGI1(adapterNum)) + { + DISPATCHER_LOG_INFO((("dxvaDevice.InitDXGI1(%d) Failed "), adapterNum )); + return MFX_ERR_UNSUPPORTED; + } + } + else if (MFX_IMPL_VIA_ANY == *pImplInterface) + { + // try the Direct3D 9 device + if (dxvaDevice.InitD3D9(adapterNum)) + { + *pImplInterface = MFX_IMPL_VIA_D3D9; // store value for GetImplementationType() call + } + // else try to open DXGI 1.1 device to get hardware ID + else if (dxvaDevice.InitDXGI1(adapterNum)) + { + *pImplInterface = MFX_IMPL_VIA_D3D11; // store value for GetImplementationType() call + } + else + { + DISPATCHER_LOG_INFO((("Unsupported adapter %d "), adapterNum )); + return MFX_ERR_UNSUPPORTED; + } + } + else + { + DISPATCHER_LOG_ERROR((("Unknown implementation type %d "), *pImplInterface )); + return MFX_ERR_UNSUPPORTED; + } + + // obtain card's parameters + if (pVendorID && pDeviceID) + { + *pVendorID = dxvaDevice.GetVendorID(); + *pDeviceID = dxvaDevice.GetDeviceID(); + } + + return MFX_ERR_NONE; +} + +MFXLibraryIterator::MFXLibraryIterator(void) +{ + m_implType = MFX_LIB_PSEUDO; + m_implInterface = MFX_IMPL_UNSUPPORTED; + + m_vendorID = 0; + m_deviceID = 0; + + m_lastLibIndex = 0; + m_lastLibMerit = MFX_MAX_MERIT; + + m_bIsSubKeyValid = 0; + m_StorageID = 0; + + m_SubKeyName[0] = 0; +} // MFXLibraryIterator::MFXLibraryIterator(void) + +MFXLibraryIterator::~MFXLibraryIterator(void) +{ + Release(); + +} // MFXLibraryIterator::~MFXLibraryIterator(void) + +void MFXLibraryIterator::Release(void) +{ + m_implType = MFX_LIB_PSEUDO; + m_implInterface = MFX_IMPL_UNSUPPORTED; + + m_vendorID = 0; + m_deviceID = 0; + + m_lastLibIndex = 0; + m_lastLibMerit = MFX_MAX_MERIT; + m_SubKeyName[0] = 0; + +} // void MFXLibraryIterator::Release(void) + +mfxStatus MFXLibraryIterator::Init(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, int storageID) +{ + // check error(s) + if ((MFX_LIB_SOFTWARE != implType) && + (MFX_LIB_HARDWARE != implType)) + { + return MFX_ERR_UNSUPPORTED; + } + + // release the object before initialization + Release(); + m_StorageID = storageID; + m_lastLibIndex = 0; + + if (storageID == MFX_CURRENT_USER_KEY || storageID == MFX_LOCAL_MACHINE_KEY) + { + return InitRegistry(implType, implInterface, adapterNum, storageID); + } + else if (storageID == MFX_APP_FOLDER) + { + msdk_disp_char path[_MAX_PATH] = {}; + + ::GetModuleFileNameW(0, path, _MAX_PATH); + msdk_disp_char * dirSeparator = wcsrchr(path, L'\\'); + if (dirSeparator < (path + _MAX_PATH)) + { + *++dirSeparator = 0; + } + + return InitFolder(implType, implInterface, adapterNum, path); + } + + return MFX_ERR_UNSUPPORTED; +} // mfxStatus MFXLibraryIterator::Init(eMfxImplType implType, const mfxU32 adapterNum, int storageID) + +mfxStatus MFXLibraryIterator::InitRegistry(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, int storageID) +{ + HKEY rootHKey; + bool bRes; + + // open required registry key + rootHKey = (MFX_LOCAL_MACHINE_KEY == storageID) ? (HKEY_LOCAL_MACHINE) : (HKEY_CURRENT_USER); + bRes = m_baseRegKey.Open(rootHKey, rootDispPath, KEY_READ); + if (false == bRes) + { + DISPATCHER_LOG_WRN((("Can't open %s\\%S : RegOpenKeyExA()==0x%x\n"), + (MFX_LOCAL_MACHINE_KEY == storageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"), + rootDispPath, GetLastError())) + return MFX_ERR_UNKNOWN; + } + + // set the required library's implementation type + m_implType = implType; + m_implInterface = implInterface != 0 + ? implInterface + : MFX_IMPL_VIA_ANY; + + //deviceID and vendorID are not actual for SW library loading + if (m_implType != MFX_LIB_SOFTWARE) + { + mfxStatus mfxRes = MFX::SelectImplementationType(adapterNum, &m_implInterface, &m_vendorID, &m_deviceID); + if (MFX_ERR_NONE != mfxRes) + { + return mfxRes; + } + } + + DISPATCHER_LOG_INFO((("Inspecting %s\\%S\n"), + (MFX_LOCAL_MACHINE_KEY == storageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"), + rootDispPath)) + + return MFX_ERR_NONE; +} // mfxStatus MFXLibraryIterator::InitRegistry(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, int storageID) + +mfxStatus MFXLibraryIterator::InitFolder(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, const msdk_disp_char * path) +{ + const int maxPathLen = sizeof(m_path)/sizeof(m_path[0]); + m_path[0] = 0; + msdk_disp_char_cpy_s(m_path, maxPathLen, path); + size_t pathLen = wcslen(m_path); + + // we looking for runtime in application folder, it should be named libmfxsw64 or libmfxsw32 + mfx_get_default_dll_name(m_path + pathLen, maxPathLen - pathLen, MFX_LIB_SOFTWARE); + + // set the required library's implementation type + m_implType = implType; + m_implInterface = implInterface != 0 + ? implInterface + : MFX_IMPL_VIA_ANY; + + //deviceID and vendorID are not actual for SW library loading + if (m_implType != MFX_LIB_SOFTWARE) + { + mfxStatus mfxRes = MFX::SelectImplementationType(adapterNum, &m_implInterface, &m_vendorID, &m_deviceID); + if (MFX_ERR_NONE != mfxRes) + { + return mfxRes; + } + } + return MFX_ERR_NONE; +} // mfxStatus MFXLibraryIterator::InitFolder(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, const msdk_disp_char * path) + +mfxStatus MFXLibraryIterator::SelectDLLVersion(wchar_t *pPath + , size_t pathSize + , eMfxImplType *pImplType, mfxVersion minVersion) +{ + UNREFERENCED_PARAMETER(minVersion); + + if (m_StorageID == MFX_APP_FOLDER) + { + if (m_lastLibIndex != 0) + return MFX_ERR_NOT_FOUND; + + m_lastLibIndex = 1; + msdk_disp_char_cpy_s(pPath, pathSize, m_path); + *pImplType = MFX_LIB_SOFTWARE; + return MFX_ERR_NONE; + } + + wchar_t libPath[MFX_MAX_DLL_PATH] = L""; + DWORD libIndex = 0; + DWORD libMerit = 0; + DWORD index; + bool enumRes; + + // main query cycle + index = 0; + m_bIsSubKeyValid = false; + do + { + WinRegKey subKey; + wchar_t subKeyName[MFX_MAX_REGISTRY_KEY_NAME]; + DWORD subKeyNameSize = sizeof(subKeyName) / sizeof(subKeyName[0]); + + // query next value name + enumRes = m_baseRegKey.EnumKey(index, subKeyName, &subKeyNameSize); + if (!enumRes) + { + DISPATCHER_LOG_WRN((("no more subkeys : RegEnumKeyExA()==0x%x\n"), GetLastError())) + } + else + { + DISPATCHER_LOG_INFO((("found subkey: %S\n"), subKeyName)) + + bool bRes; + + // open the sub key + bRes = subKey.Open(m_baseRegKey, subKeyName, KEY_READ); + if (!bRes) + { + DISPATCHER_LOG_WRN((("error opening key %S :RegOpenKeyExA()==0x%x\n"), subKeyName, GetLastError())); + } + else + { + DISPATCHER_LOG_INFO((("opened key: %S\n"), subKeyName)); + + mfxU32 vendorID = 0, deviceID = 0, merit = 0; + DWORD size; + + // query vendor and device IDs + size = sizeof(vendorID); + bRes = subKey.Query(vendorIDKeyName, REG_DWORD, (LPBYTE) &vendorID, &size); + DISPATCHER_LOG_OPERATION({ + if (bRes) + { + DISPATCHER_LOG_INFO((("loaded %S : 0x%x\n"), vendorIDKeyName, vendorID)); + } + else + { + DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"), vendorIDKeyName, GetLastError())); + } + }) + + if (bRes) + { + size = sizeof(deviceID); + bRes = subKey.Query(deviceIDKeyName, REG_DWORD, (LPBYTE) &deviceID, &size); + DISPATCHER_LOG_OPERATION({ + if (bRes) + { + DISPATCHER_LOG_INFO((("loaded %S : 0x%x\n"), deviceIDKeyName, deviceID)); + } + else + { + DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"), deviceIDKeyName, GetLastError())); + } + }) + } + // query merit value + if (bRes) + { + size = sizeof(merit); + bRes = subKey.Query(meritKeyName, REG_DWORD, (LPBYTE) &merit, &size); + DISPATCHER_LOG_OPERATION({ + if (bRes) + { + DISPATCHER_LOG_INFO((("loaded %S : %d\n"), meritKeyName, merit)); + } + else + { + DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"), meritKeyName, GetLastError())); + } + }) + } + + // if the library fits required parameters, + // query the library's path + if (bRes) + { + // compare device's and library's IDs + if (MFX_LIB_HARDWARE == m_implType) + { + if (m_vendorID != vendorID) + { + bRes = false; + DISPATCHER_LOG_WRN((("%S conflict, actual = 0x%x : required = 0x%x\n"), vendorIDKeyName, m_vendorID, vendorID)); + } + if (bRes && m_deviceID != deviceID) + { + bRes = false; + DISPATCHER_LOG_WRN((("%S conflict, actual = 0x%x : required = 0x%x\n"), deviceIDKeyName, m_deviceID, deviceID)); + } + } + + DISPATCHER_LOG_OPERATION({ + if (bRes) + { + if (!(((m_lastLibMerit > merit) || ((m_lastLibMerit == merit) && (m_lastLibIndex < index))) && + (libMerit < merit))) + { + DISPATCHER_LOG_WRN((("merit conflict: lastMerit = 0x%x, requiredMerit = 0x%x, libraryMerit = 0x%x, lastindex = %d, index = %d\n") + , m_lastLibMerit, merit, libMerit, m_lastLibIndex, index)); + } + }}) + + if ((bRes) && + ((m_lastLibMerit > merit) || ((m_lastLibMerit == merit) && (m_lastLibIndex < index))) && + (libMerit < merit)) + { + wchar_t tmpPath[MFX_MAX_DLL_PATH]; + DWORD tmpPathSize = sizeof(tmpPath); + + bRes = subKey.Query(pathKeyName, REG_SZ, (LPBYTE) tmpPath, &tmpPathSize); + if (!bRes) + { + DISPATCHER_LOG_WRN((("error querying %S : RegQueryValueExA()==0x%x\n"), pathKeyName, GetLastError())); + } + else + { + DISPATCHER_LOG_INFO((("loaded %S : %S\n"), pathKeyName, tmpPath)); + + msdk_disp_char_cpy_s(libPath, sizeof(libPath) / sizeof(libPath[0]), tmpPath); + msdk_disp_char_cpy_s(m_SubKeyName, sizeof(m_SubKeyName) / sizeof(m_SubKeyName[0]), subKeyName); + + libMerit = merit; + libIndex = index; + + // set the library's type + if ((0 == vendorID) || (0 == deviceID)) + { + *pImplType = MFX_LIB_SOFTWARE; + + DISPATCHER_LOG_INFO((("Library type is MFX_LIB_SOFTWARE\n"))); + } + else + { + *pImplType = MFX_LIB_HARDWARE; + DISPATCHER_LOG_INFO((("Library type is MFX_LIB_HARDWARE\n"))); + } + } + } + } + } + } + + // advance key index + index += 1; + + } while (enumRes); + + // if the library's path was successfully read, + // the merit variable holds valid value + if (0 == libMerit) + { + return MFX_ERR_NOT_FOUND; + } + + msdk_disp_char_cpy_s(pPath, pathSize, libPath); + + m_lastLibIndex = libIndex; + m_lastLibMerit = libMerit; + m_bIsSubKeyValid = true; + + return MFX_ERR_NONE; + +} // mfxStatus MFXLibraryIterator::SelectDLLVersion(wchar_t *pPath, size_t pathSize, eMfxImplType *pImplType, mfxVersion minVersion) + +mfxIMPL MFXLibraryIterator::GetImplementationType() +{ + return m_implInterface; +} // mfxIMPL MFXLibraryIterator::GetImplementationType() + +bool MFXLibraryIterator::GetSubKeyName(msdk_disp_char *subKeyName, size_t length) const +{ + msdk_disp_char_cpy_s(subKeyName, length, m_SubKeyName); + return m_bIsSubKeyValid; +} +} // namespace MFX +#endif // #if defined(_WIN32) || defined(_WIN64) + diff --git a/plugins/obs-qsv11/libmfx/src/mfx_load_dll.cpp b/plugins/obs-qsv11/libmfx/src/mfx_load_dll.cpp new file mode 100644 index 0000000..bfb77e2 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/src/mfx_load_dll.cpp @@ -0,0 +1,241 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_load_dll.cpp + +\* ****************************************************************************** */ + +#if defined(_WIN32) || defined(_WIN64) + +#include "mfx_dispatcher.h" +#include "mfx_load_dll.h" + +#include +#include +#include + +#if !defined(_DEBUG) + +#if defined(_WIN64) +const +wchar_t * const defaultDLLName[2] = {L"libmfxhw64.dll", + L"libmfxsw64.dll"}; +const +wchar_t * const defaultAudioDLLName[2] = {L"libmfxaudiosw64.dll", + L"libmfxaudiosw64.dll"}; + +const +wchar_t * const defaultPluginDLLName[2] = {L"mfxplugin64_hw.dll", + L"mfxplugin64_sw.dll"}; + +#elif defined(_WIN32) +const +wchar_t * const defaultDLLName[2] = {L"libmfxhw32.dll", + L"libmfxsw32.dll"}; + +const +wchar_t * const defaultAudioDLLName[2] = {L"libmfxaudiosw32.dll", + L"libmfxaudiosw32.dll"}; + +const +wchar_t * const defaultPluginDLLName[2] = {L"mfxplugin32_hw.dll", + L"mfxplugin32_sw.dll"}; + +#endif // (defined(_WIN64)) + +#else // defined(_DEBUG) + +#if defined(_WIN64) +const +wchar_t * const defaultDLLName[2] = {L"libmfxhw64_d.dll", + L"libmfxsw64_d.dll"}; +const +wchar_t * const defaultAudioDLLName[2] = {L"libmfxaudiosw64_d.dll", + L"libmfxaudiosw64_d.dll"}; + +const +wchar_t * const defaultPluginDLLName[2] = {L"mfxplugin64_hw_d.dll", + L"mfxplugin64_sw_d.dll"}; + +#elif defined(WIN32) +const +wchar_t * const defaultDLLName[2] = {L"libmfxhw32_d.dll", + L"libmfxsw32_d.dll"}; + + +const +wchar_t * const defaultAudioDLLName[2] = {L"libmfxaudiosw32_d.dll", + L"libmfxaudiosw32_d.dll"}; + +const +wchar_t * const defaultPluginDLLName[2] = {L"mfxplugin32_hw_d.dll", + L"mfxplugin32_sw_d.dll"}; + +#endif // (defined(_WIN64)) + +#endif // !defined(_DEBUG) + +namespace MFX +{ + + +mfxStatus mfx_get_default_dll_name(msdk_disp_char *pPath, size_t pathSize, eMfxImplType implType) +{ + if (!pPath) + { + return MFX_ERR_NULL_PTR; + } + + + // there are only 2 implementation with default DLL names +#if _MSC_VER >= 1400 + return 0 == wcscpy_s(pPath, pathSize, defaultDLLName[implType & 1]) + ? MFX_ERR_NONE : MFX_ERR_UNKNOWN; +#else + wcscpy(pPath, defaultDLLName[implType & 1]); + return MFX_ERR_NONE; +#endif +} // mfxStatus mfx_get_default_dll_name(wchar_t *pPath, size_t pathSize, eMfxImplType implType) + +mfxStatus mfx_get_default_plugin_name(msdk_disp_char *pPath, size_t pathSize, eMfxImplType implType) +{ + if (!pPath) + { + return MFX_ERR_NULL_PTR; + } + + + // there are only 2 implementation with default DLL names +#if _MSC_VER >= 1400 + return 0 == wcscpy_s(pPath, pathSize, defaultPluginDLLName[implType & 1]) + ? MFX_ERR_NONE : MFX_ERR_UNKNOWN; +#else + wcscpy(pPath, defaultPluginDLLName[implType & 1]); + return MFX_ERR_NONE; +#endif +} + +mfxStatus mfx_get_default_audio_dll_name(msdk_disp_char *pPath, size_t pathSize, eMfxImplType implType) +{ + if (!pPath) + { + return MFX_ERR_NULL_PTR; + } + + // there are only 2 implementation with default DLL names +#if _MSC_VER >= 1400 + return 0 == wcscpy_s(pPath, pathSize, defaultAudioDLLName[implType & 1]) + ? MFX_ERR_NONE : MFX_ERR_UNKNOWN; +#else + wcscpy(pPath, defaultAudioDLLName[implType & 1]); + return MFX_ERR_NONE; +#endif +} // mfxStatus mfx_get_default_audio_dll_name(wchar_t *pPath, size_t pathSize, eMfxImplType implType) + +mfxModuleHandle mfx_dll_load(const msdk_disp_char *pFileName) +{ + mfxModuleHandle hModule = (mfxModuleHandle) 0; + + // check error(s) + if (NULL == pFileName) + { + return NULL; + } + + // set the silent error mode + DWORD prevErrorMode = 0; +#if (_WIN32_WINNT >= 0x0600) && !(__GNUC__) + SetThreadErrorMode(SEM_FAILCRITICALERRORS, &prevErrorMode); +#else + prevErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); +#endif + // load the library's module + hModule = LoadLibraryExW(pFileName,NULL,0); + // set the previous error mode +#if (_WIN32_WINNT >= 0x0600) && !(__GNUC__) + SetThreadErrorMode(prevErrorMode, NULL); +#else + SetErrorMode(prevErrorMode); +#endif + + return hModule; + +} // mfxModuleHandle mfx_dll_load(const wchar_t *pFileName) + +mfxFunctionPointer mfx_dll_get_addr(mfxModuleHandle handle, const char *pFunctionName) +{ + if (NULL == handle) + { + return NULL; + } + + return (mfxFunctionPointer) GetProcAddress((HMODULE) handle, pFunctionName); +} // mfxFunctionPointer mfx_dll_get_addr(mfxModuleHandle handle, const char *pFunctionName) + +bool mfx_dll_free(mfxModuleHandle handle) +{ + if (NULL == handle) + { + return true; + } + + BOOL bRes = FreeLibrary((HMODULE)handle); + + return !!bRes; +} // bool mfx_dll_free(mfxModuleHandle handle) + +mfxModuleHandle mfx_get_dll_handle(const msdk_disp_char *pFileName) +{ + mfxModuleHandle hModule = (mfxModuleHandle) 0; + + // check error(s) + if (NULL == pFileName) + { + return NULL; + } + + // set the silent error mode + DWORD prevErrorMode = 0; +#if (_WIN32_WINNT >= 0x0600) && !(__GNUC__) + SetThreadErrorMode(SEM_FAILCRITICALERRORS, &prevErrorMode); +#else + prevErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); +#endif + // load the library's module + GetModuleHandleExW(0, pFileName, (HMODULE*) &hModule); + // set the previous error mode +#if (_WIN32_WINNT >= 0x0600) && !(__GNUC__) + SetThreadErrorMode(prevErrorMode, NULL); +#else + SetErrorMode(prevErrorMode); +#endif + return hModule; +} + + +} // namespace MFX + +#endif // #if defined(_WIN32) || defined(_WIN64) diff --git a/plugins/obs-qsv11/libmfx/src/mfx_load_plugin.cpp b/plugins/obs-qsv11/libmfx/src/mfx_load_plugin.cpp new file mode 100644 index 0000000..3948040 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/src/mfx_load_plugin.cpp @@ -0,0 +1,458 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2013-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_load_plugin.h + +\* ****************************************************************************** */ + +#include "mfx_load_plugin.h" +#include "mfx_load_dll.h" +#include "mfx_dispatcher_log.h" + +#define TRACE_PLUGIN_ERROR(str, ...) DISPATCHER_LOG_ERROR((("[PLUGIN]: "str), __VA_ARGS__)) +#define TRACE_PLUGIN_INFO(str, ...) DISPATCHER_LOG_INFO((("[PLUGIN]: "str), __VA_ARGS__)) + +#define CREATE_PLUGIN_FNC "CreatePlugin" + +MFX::PluginModule::PluginModule() + : mHmodule() + , mCreatePluginPtr() + , mPath() +{ +} + +MFX::PluginModule::PluginModule(const PluginModule & that) + : mHmodule(mfx_dll_load(that.mPath)) + , mCreatePluginPtr(that.mCreatePluginPtr) +{ + msdk_disp_char_cpy_s(mPath, sizeof(mPath) / sizeof(*mPath), that.mPath); +} + +MFX::PluginModule & MFX::PluginModule::operator = (const MFX::PluginModule & that) +{ + if (this != &that) + { + Tidy(); + mHmodule = mfx_dll_load(that.mPath); + mCreatePluginPtr = that.mCreatePluginPtr; + msdk_disp_char_cpy_s(mPath, sizeof(mPath) / sizeof(*mPath), that.mPath); + } + return *this; +} + +MFX::PluginModule::PluginModule(const msdk_disp_char * path) + : mCreatePluginPtr() +{ + mHmodule = mfx_dll_load(path); + if (NULL == mHmodule) { + TRACE_PLUGIN_ERROR("Cannot load module: %S\n", MSDK2WIDE(path)); + return ; + } + TRACE_PLUGIN_INFO("Plugin loaded at: %S\n", MSDK2WIDE(path)); + + mCreatePluginPtr = (CreatePluginPtr_t)mfx_dll_get_addr(mHmodule, CREATE_PLUGIN_FNC); + if (NULL == mCreatePluginPtr) { + TRACE_PLUGIN_ERROR("Cannot get procedure address: %s\n", CREATE_PLUGIN_FNC); + return ; + } + + msdk_disp_char_cpy_s(mPath, sizeof(mPath) / sizeof(*mPath), path); +} + +bool MFX::PluginModule::Create( mfxPluginUID uid, mfxPlugin& plg) +{ + bool result = false; + if (mCreatePluginPtr) + { + mfxStatus mfxResult = mCreatePluginPtr(uid, &plg); + result = (MFX_ERR_NONE == mfxResult); + if (!result) { + TRACE_PLUGIN_ERROR("\"%S::%s\" returned %d\n", MSDK2WIDE(mPath), CREATE_PLUGIN_FNC, mfxResult); + } else { + TRACE_PLUGIN_INFO("\"%S::%s\" SUCCEED\n", MSDK2WIDE(mPath), CREATE_PLUGIN_FNC); + } + } + return result; +} + +void MFX::PluginModule::Tidy() +{ + mfx_dll_free(mHmodule); + mCreatePluginPtr = NULL; + mHmodule = NULL; +} + +MFX::PluginModule::~PluginModule(void) +{ + Tidy(); +} + +bool MFX::MFXPluginFactory::RunVerification( const mfxPlugin & plg, const PluginDescriptionRecord &dsc, mfxPluginParam &pluginParams) +{ + if (plg.PluginInit == 0) + { + TRACE_PLUGIN_ERROR("plg->PluginInit = 0\n", 0); + return false; + } + if (plg.PluginClose == 0) + { + TRACE_PLUGIN_ERROR("plg->PluginClose = 0\n", 0); + return false; + } + if (plg.GetPluginParam == 0) + { + TRACE_PLUGIN_ERROR("plg->GetPluginParam = 0\n", 0); + return false; + } + + if (plg.Execute == 0) + { + TRACE_PLUGIN_ERROR("plg->Execute = 0\n", 0); + return false; + } + if (plg.FreeResources == 0) + { + TRACE_PLUGIN_ERROR("plg->FreeResources = 0\n", 0); + return false; + } + + mfxStatus sts = plg.GetPluginParam(plg.pthis, &pluginParams); + if (sts != MFX_ERR_NONE) + { + TRACE_PLUGIN_ERROR("plg->GetPluginParam() returned %d\n", sts); + return false; + } + + if (dsc.Default) + { + // for default plugins there is no description, dsc.APIVersion, dsc.PluginVersion and dsc.PluginUID were set by dispatcher + // dsc.PluginVersion == requested plugin version (parameter of MFXVideoUSER_Load); dsc.APIVersion == loaded library API + if (dsc.PluginVersion > pluginParams.PluginVersion) + { + TRACE_PLUGIN_ERROR("plg->GetPluginParam() returned PluginVersion=%d, but it is smaller than requested : %d\n", pluginParams.PluginVersion, dsc.PluginVersion); + return false; + } + } + else + { + if (!dsc.onlyVersionRegistered && pluginParams.CodecId != dsc.CodecId) + { + TRACE_PLUGIN_ERROR("plg->GetPluginParam() returned CodecId="MFXFOURCCTYPE()", but registration has CodecId="MFXFOURCCTYPE()"\n" + , MFXU32TOFOURCC(pluginParams.CodecId), MFXU32TOFOURCC(dsc.CodecId)); + return false; + } + + if (!dsc.onlyVersionRegistered && pluginParams.Type != dsc.Type) + { + TRACE_PLUGIN_ERROR("plg->GetPluginParam() returned Type=%d, but registration has Type=%d\n", pluginParams.Type, dsc.Type); + return false; + } + + if (pluginParams.PluginUID != dsc.PluginUID) + { + TRACE_PLUGIN_ERROR("plg->GetPluginParam() returned UID="MFXGUIDTYPE()", but registration has UID="MFXGUIDTYPE()"\n" + , MFXGUIDTOHEX(&pluginParams.PluginUID), MFXGUIDTOHEX(&dsc.PluginUID)); + return false; + } + + if (pluginParams.PluginVersion != dsc.PluginVersion) + { + TRACE_PLUGIN_ERROR("plg->GetPluginParam() returned PluginVersion=%d, but registration has PlgVer=%d\n", pluginParams.PluginVersion, dsc.PluginVersion); + return false; + } + + if (pluginParams.APIVersion.Version != dsc.APIVersion.Version) + { + TRACE_PLUGIN_ERROR("plg->GetPluginParam() returned APIVersion=%d.%d, but registration has APIVer=%d.%d\n" + , pluginParams.APIVersion.Major, pluginParams.APIVersion.Minor + , dsc.APIVersion.Major, dsc.APIVersion.Minor); + return false; + } + } + + switch(pluginParams.Type) + { + case MFX_PLUGINTYPE_VIDEO_DECODE: + case MFX_PLUGINTYPE_VIDEO_ENCODE: + case MFX_PLUGINTYPE_VIDEO_VPP: + { + TRACE_PLUGIN_INFO("plugin type= %d\n", pluginParams.Type); + if (plg.Video == 0) + { + TRACE_PLUGIN_ERROR("plg->Video = 0\n", 0); + return false; + } + + if (!VerifyCodecCommon(*plg.Video)) + return false; + break; + } + } + + switch(pluginParams.Type) + { + case MFX_PLUGINTYPE_VIDEO_DECODE: + return VerifyDecoder(*plg.Video); + case MFX_PLUGINTYPE_AUDIO_DECODE: + return VerifyAudioDecoder(*plg.Audio); + case MFX_PLUGINTYPE_VIDEO_ENCODE: + return VerifyEncoder(*plg.Video); + case MFX_PLUGINTYPE_AUDIO_ENCODE: + return VerifyAudioEncoder(*plg.Audio); + case MFX_PLUGINTYPE_VIDEO_VPP: + return VerifyVpp(*plg.Video); + case MFX_PLUGINTYPE_VIDEO_ENC: + return VerifyEnc(*plg.Video); + default: + { + TRACE_PLUGIN_ERROR("unsupported plugin type: %d\n", pluginParams.Type); + return false; + } + } +} + +bool MFX::MFXPluginFactory::VerifyVpp( const mfxVideoCodecPlugin &vpp ) +{ + if (vpp.VPPFrameSubmit == 0) + { + TRACE_PLUGIN_ERROR("plg->Video->VPPFrameSubmit = 0\n", 0); + return false; + } + + return true; + +} + +bool MFX::MFXPluginFactory::VerifyEncoder( const mfxVideoCodecPlugin &encoder ) +{ + if (encoder.EncodeFrameSubmit == 0) + { + TRACE_PLUGIN_ERROR("plg->Video->EncodeFrameSubmit = 0\n", 0); + return false; + } + + return true; +} + +bool MFX::MFXPluginFactory::VerifyAudioEncoder( const mfxAudioCodecPlugin &encoder ) +{ + if (encoder.EncodeFrameSubmit == 0) + { + TRACE_PLUGIN_ERROR("plg->Audio->EncodeFrameSubmit = 0\n", 0); + return false; + } + + return true; +} + +bool MFX::MFXPluginFactory::VerifyEnc( const mfxVideoCodecPlugin &videoEnc ) +{ + if (videoEnc.ENCFrameSubmit == 0) + { + TRACE_PLUGIN_ERROR("plg->Video->EncodeFrameSubmit = 0\n", 0); + return false; + } + + return true; +} + +bool MFX::MFXPluginFactory::VerifyDecoder( const mfxVideoCodecPlugin &decoder ) +{ + if (decoder.DecodeHeader == 0) + { + TRACE_PLUGIN_ERROR("plg->Video->DecodeHeader = 0\n", 0); + return false; + } + if (decoder.GetPayload == 0) + { + TRACE_PLUGIN_ERROR("plg->Video->GetPayload = 0\n", 0); + return false; + } + if (decoder.DecodeFrameSubmit == 0) + { + TRACE_PLUGIN_ERROR("plg->Video->DecodeFrameSubmit = 0\n", 0); + return false; + } + + return true; +} + +bool MFX::MFXPluginFactory::VerifyAudioDecoder( const mfxAudioCodecPlugin &decoder ) +{ + if (decoder.DecodeHeader == 0) + { + TRACE_PLUGIN_ERROR("plg->Audio->DecodeHeader = 0\n", 0); + return false; + } +// if (decoder.GetPayload == 0) + { + // TRACE_PLUGIN_ERROR("plg->Audio->GetPayload = 0\n", 0); + // return false; + } + if (decoder.DecodeFrameSubmit == 0) + { + TRACE_PLUGIN_ERROR("plg->Audio->DecodeFrameSubmit = 0\n", 0); + return false; + } + + return true; +} + +bool MFX::MFXPluginFactory::VerifyCodecCommon( const mfxVideoCodecPlugin & videoCodec ) +{ + if (videoCodec.Query == 0) + { + TRACE_PLUGIN_ERROR("plg->Video->Query = 0\n", 0); + return false; + } + //todo: remove + if (videoCodec.Query == 0) + { + TRACE_PLUGIN_ERROR("plg->Video->Query = 0\n", 0); + return false; + } + if (videoCodec.QueryIOSurf == 0) + { + TRACE_PLUGIN_ERROR("plg->Video->QueryIOSurf = 0\n", 0); + return false; + } + if (videoCodec.Init == 0) + { + TRACE_PLUGIN_ERROR("plg->Video->Init = 0\n", 0); + return false; + } + if (videoCodec.Reset == 0) + { + TRACE_PLUGIN_ERROR("plg->Video->Reset = 0\n", 0); + return false; + } + if (videoCodec.Close == 0) + { + TRACE_PLUGIN_ERROR("plg->Video->Close = 0\n", 0); + return false; + } + if (videoCodec.GetVideoParam == 0) + { + TRACE_PLUGIN_ERROR("plg->Video->GetVideoParam = 0\n", 0); + return false; + } + + return true; +} + +mfxStatus MFX::MFXPluginFactory::Create(const PluginDescriptionRecord & rec) +{ + PluginModule plgModule(rec.sPath); + mfxPlugin plg = {}; + mfxPluginParam plgParams; + + if (!plgModule.Create(rec.PluginUID, plg)) + { + return MFX_ERR_UNKNOWN; + } + + if (!RunVerification(plg, rec, plgParams)) + { + //will do not call plugin close since it is not safe to do that until structure is corrected + return MFX_ERR_UNKNOWN; + } + + + if (rec.Type == MFX_PLUGINTYPE_AUDIO_DECODE || + rec.Type == MFX_PLUGINTYPE_AUDIO_ENCODE) + { + mfxStatus sts = MFXAudioUSER_Register(mSession, plgParams.Type, &plg); + if (MFX_ERR_NONE != sts) + { + TRACE_PLUGIN_ERROR(" MFXAudioUSER_Register returned %d\n", sts); + return sts; + } + } + else + { + mfxStatus sts = MFXVideoUSER_Register(mSession, plgParams.Type, &plg); + if (MFX_ERR_NONE != sts) + { + TRACE_PLUGIN_ERROR(" MFXVideoUSER_Register returned %d\n", sts); + return sts; + } + } + + mPlugins.push_back(FactoryRecord(plgParams, plgModule, plg)); + + return MFX_ERR_NONE; +} + +MFX::MFXPluginFactory::~MFXPluginFactory() +{ + Close(); +} + +MFX::MFXPluginFactory::MFXPluginFactory( mfxSession session ) +{ + mSession = session; +} + +bool MFX::MFXPluginFactory::Destroy( const mfxPluginUID & uidToDestroy) +{ + for (MFXVector::iterator i = mPlugins.begin(); i!= mPlugins.end(); i++) + { + if (i->plgParams.PluginUID == uidToDestroy) + { + DestroyPlugin(*i); + //dll unload should happen here + //todo: check that dll_free fail is traced + mPlugins.erase(i); + return true; + } + } + return false; +} + +void MFX::MFXPluginFactory::Close() +{ + for (MFXVector::iterator i = mPlugins.begin(); i!= mPlugins.end(); i++) + { + DestroyPlugin(*i); + } + mPlugins.clear(); +} + +void MFX::MFXPluginFactory::DestroyPlugin( FactoryRecord & record) +{ + mfxStatus sts; + if (record.plgParams.Type == MFX_PLUGINTYPE_AUDIO_DECODE || + record.plgParams.Type == MFX_PLUGINTYPE_AUDIO_ENCODE) + { + sts = MFXAudioUSER_Unregister(mSession, record.plgParams.Type); + TRACE_PLUGIN_INFO(" MFXAudioUSER_Unregister for Type=%d, returned %d\n", record.plgParams.Type, sts); + } + else + { + sts = MFXVideoUSER_Unregister(mSession, record.plgParams.Type); + TRACE_PLUGIN_INFO(" MFXVideoUSER_Unregister for Type=%d, returned %d\n", record.plgParams.Type, sts); + } +} \ No newline at end of file diff --git a/plugins/obs-qsv11/libmfx/src/mfx_plugin_hive.cpp b/plugins/obs-qsv11/libmfx/src/mfx_plugin_hive.cpp new file mode 100644 index 0000000..02eb8f8 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/src/mfx_plugin_hive.cpp @@ -0,0 +1,500 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2013-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_plugin_hive.cpp + +\* ****************************************************************************** */ + +#if defined(_WIN32) || defined(_WIN64) + +#include "mfx_plugin_hive.h" +#include "mfx_library_iterator.h" +#include "mfx_dispatcher.h" +#include "mfx_dispatcher_log.h" +#include "mfx_load_dll.h" + +#define TRACE_HIVE_ERROR(str, ...) DISPATCHER_LOG_ERROR((("[HIVE]: "str), __VA_ARGS__)) +#define TRACE_HIVE_INFO(str, ...) DISPATCHER_LOG_INFO((("[HIVE]: "str), __VA_ARGS__)) +#define TRACE_HIVE_WRN(str, ...) DISPATCHER_LOG_WRN((("[HIVE]: "str), __VA_ARGS__)) + +namespace +{ + const wchar_t rootPluginPath[] = L"Software\\Intel\\MediaSDK\\Plugin"; + const wchar_t rootDispatchPath[] = L"Software\\Intel\\MediaSDK\\Dispatch"; + const wchar_t pluginSubkey[] = L"Plugin"; + const wchar_t TypeKeyName[] = L"Type"; + const wchar_t CodecIDKeyName[] = L"CodecID"; + const wchar_t GUIDKeyName[] = L"GUID"; + const wchar_t PathKeyName[] = L"Path"; + const wchar_t DefaultKeyName[] = L"Default"; + const wchar_t PlgVerKeyName[] = L"PluginVersion"; + const wchar_t APIVerKeyName[] = L"APIVersion"; +} + +namespace +{ +#ifdef _WIN64 + const wchar_t pluginFileName[] = L"FileName64"; +#else + const wchar_t pluginFileName[] = L"FileName32"; +#endif // _WIN64 + + //do not allow store plugin in different hierarchy + const wchar_t pluginFileNameRestrictedCharacters[] = L"\\/"; + const wchar_t pluginCfgFileName[] = L"plugin.cfg"; + const wchar_t pluginSearchPattern[] = L"????????????????????????????????"; + const mfxU32 pluginCfgFileNameLen = 10; + const mfxU32 pluginDirNameLen = 32; + const mfxU32 defaultPluginNameLen = 25; + const mfxU32 charsPermfxU8 = 2; + const mfxU32 slashLen = 1; + enum + { + MAX_PLUGIN_FILE_LINE = 4096 + }; + + #define alignStr() "%-14S" +} + +MFX::MFXPluginsInHive::MFXPluginsInHive(int mfxStorageID, const msdk_disp_char *msdkLibSubKey, mfxVersion currentAPIVersion) + : MFXPluginStorageBase(currentAPIVersion) +{ + HKEY rootHKey; + bool bRes; + WinRegKey regKey; + + if (MFX_LOCAL_MACHINE_KEY != mfxStorageID && MFX_CURRENT_USER_KEY != mfxStorageID) + return; + + // open required registry key + rootHKey = (MFX_LOCAL_MACHINE_KEY == mfxStorageID) ? (HKEY_LOCAL_MACHINE) : (HKEY_CURRENT_USER); + if (msdkLibSubKey) { + //dispatch/subkey/plugin + bRes = regKey.Open(rootHKey, rootDispatchPath, KEY_READ); + if (bRes) + { + bRes = regKey.Open(regKey, msdkLibSubKey, KEY_READ); + } + if (bRes) + { + bRes = regKey.Open(regKey, pluginSubkey, KEY_READ); + } + } + else + { + bRes = regKey.Open(rootHKey, rootPluginPath, KEY_READ); + } + + if (false == bRes) { + return; + } + DWORD index = 0; + if (!regKey.QueryInfo(&index)) { + return; + } + try + { + resize(index); + } + catch (...) { + TRACE_HIVE_ERROR("new PluginDescriptionRecord[%d] threw an exception: \n", index); + return; + } + + for(index = 0; ; index++) + { + wchar_t subKeyName[MFX_MAX_REGISTRY_KEY_NAME]; + DWORD subKeyNameSize = sizeof(subKeyName) / sizeof(subKeyName[0]); + WinRegKey subKey; + + // query next value name + bool enumRes = regKey.EnumKey(index, subKeyName, &subKeyNameSize); + if (!enumRes) { + break; + } + + // open the sub key + bRes = subKey.Open(regKey, subKeyName, KEY_READ); + if (!bRes) { + continue; + } + + if (msdkLibSubKey) + { + TRACE_HIVE_INFO("Found Plugin: %s\\%S\\%S\\%S\\%S\n", (MFX_LOCAL_MACHINE_KEY == mfxStorageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"), + rootDispatchPath, msdkLibSubKey, pluginSubkey, subKeyName); + } + else + { + TRACE_HIVE_INFO("Found Plugin: %s\\%S\\%S\n", (MFX_LOCAL_MACHINE_KEY == mfxStorageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"), + rootPluginPath, subKeyName); + } + + PluginDescriptionRecord descriptionRecord; + + if (!QueryKey(subKey, TypeKeyName, descriptionRecord.Type)) + { + continue; + } + TRACE_HIVE_INFO(alignStr()" : %d\n", TypeKeyName, descriptionRecord.Type); + + if (QueryKey(subKey, CodecIDKeyName, descriptionRecord.CodecId)) + { + TRACE_HIVE_INFO(alignStr()" : "MFXFOURCCTYPE()" \n", CodecIDKeyName, MFXU32TOFOURCC(descriptionRecord.CodecId)); + } + else + { + TRACE_HIVE_INFO(alignStr()" : \n", CodecIDKeyName, "NOT REGISTERED"); + } + + if (!QueryKey(subKey, GUIDKeyName, descriptionRecord.PluginUID)) + { + continue; + } + TRACE_HIVE_INFO(alignStr()" : "MFXGUIDTYPE()"\n", GUIDKeyName, MFXGUIDTOHEX(&descriptionRecord.PluginUID)); + + mfxU32 nSize = sizeof(descriptionRecord.sPath)/sizeof(*descriptionRecord.sPath); + if (!subKey.Query(PathKeyName, descriptionRecord.sPath, nSize)) + { + TRACE_HIVE_WRN("no value for : %S\n", PathKeyName); + continue; + } + TRACE_HIVE_INFO(alignStr()" : %S\n", PathKeyName, descriptionRecord.sPath); + + if (!QueryKey(subKey, DefaultKeyName, descriptionRecord.Default)) + { + continue; + } + TRACE_HIVE_INFO(alignStr()" : %s\n", DefaultKeyName, descriptionRecord.Default ? "true" : "false"); + + mfxU32 version; + if (!QueryKey(subKey, PlgVerKeyName, version)) + { + continue; + } + descriptionRecord.PluginVersion = static_cast(version); + if (0 == version) + { + TRACE_HIVE_ERROR(alignStr()" : %d, which is invalid\n", PlgVerKeyName, descriptionRecord.PluginVersion); + continue; + } + else + { + TRACE_HIVE_INFO(alignStr()" : %d\n", PlgVerKeyName, descriptionRecord.PluginVersion); + } + + mfxU32 APIVersion; + if (!QueryKey(subKey, APIVerKeyName, APIVersion)) + { + continue; + } + ConvertAPIVersion(APIVersion, descriptionRecord); + TRACE_HIVE_INFO(alignStr()" : %d.%d \n", APIVerKeyName, descriptionRecord.APIVersion.Major, descriptionRecord.APIVersion.Minor); + + try + { + operator[](index) = descriptionRecord; + } + catch (...) { + TRACE_HIVE_ERROR("operator[](%d) = descriptionRecord; - threw exception \n", index); + } + } +} + +MFX::MFXPluginsInFS::MFXPluginsInFS( mfxVersion currentAPIVersion ) + : MFXPluginStorageBase(currentAPIVersion) + , mIsVersionParsed() + , mIsAPIVersionParsed() +{ + WIN32_FIND_DATAW find_data; + msdk_disp_char currentModuleName[MAX_PLUGIN_PATH]; + + GetModuleFileNameW(NULL, currentModuleName, MAX_PLUGIN_PATH); + if (GetLastError() != 0) + { + TRACE_HIVE_ERROR("GetModuleFileName() reported an error: %d\n", GetLastError()); + return; + } + msdk_disp_char *lastSlashPos = wcsrchr(currentModuleName, L'\\'); + if (!lastSlashPos) { + lastSlashPos = currentModuleName; + } + mfxU32 executableDirLen = (mfxU32)(lastSlashPos - currentModuleName) + slashLen; + if (executableDirLen + pluginDirNameLen + pluginCfgFileNameLen >= MAX_PLUGIN_PATH) + { + TRACE_HIVE_ERROR("MAX_PLUGIN_PATH which is %d, not enough to locate plugin path\n", MAX_PLUGIN_PATH); + return; + } + msdk_disp_char_cpy_s(lastSlashPos + slashLen + , MAX_PLUGIN_PATH - executableDirLen, pluginSearchPattern); + + HANDLE fileFirst = FindFirstFileW(currentModuleName, &find_data); + if (INVALID_HANDLE_VALUE == fileFirst) + { + TRACE_HIVE_ERROR("FindFirstFileW() unable to locate any plugins folders\n", 0); + return; + } + do + { + if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + continue; + } + if (pluginDirNameLen != wcslen(find_data.cFileName)) + { + continue; + } + //converting dirname into guid + PluginDescriptionRecord descriptionRecord; + descriptionRecord.APIVersion = currentAPIVersion; + descriptionRecord.onlyVersionRegistered = true; + + mfxU32 i = 0; + for(i = 0; i != pluginDirNameLen / charsPermfxU8; i++) + { + mfxU32 hexNum = 0; + if (1 != swscanf_s(find_data.cFileName + charsPermfxU8 * i, L"%2x", &hexNum)) + { + // it is ok to have non-plugin subdirs with length 32 + //TRACE_HIVE_INFO("folder name \"%S\" is not a valid GUID string\n", find_data.cFileName); + break; + } + if (hexNum == 0 && find_data.cFileName + charsPermfxU8 * i != wcsstr(find_data.cFileName + 2*i, L"00")) + { + // it is ok to have non-plugin subdirs with length 32 + //TRACE_HIVE_INFO("folder name \"%S\" is not a valid GUID string\n", find_data.cFileName); + break; + } + descriptionRecord.PluginUID.Data[i] = (mfxU8)hexNum; + } + if (i != pluginDirNameLen / charsPermfxU8) { + continue; + } + + msdk_disp_char_cpy_s(currentModuleName + executableDirLen + , MAX_PLUGIN_PATH - executableDirLen, find_data.cFileName); + + msdk_disp_char_cpy_s(currentModuleName + executableDirLen + pluginDirNameLen + , MAX_PLUGIN_PATH - executableDirLen - pluginDirNameLen, L"\\"); + + //this is path to plugin directory + msdk_disp_char_cpy_s(descriptionRecord.sPath + , sizeof(descriptionRecord.sPath) / sizeof(*descriptionRecord.sPath), currentModuleName); + + msdk_disp_char_cpy_s(currentModuleName + executableDirLen + pluginDirNameLen + slashLen + , MAX_PLUGIN_PATH - executableDirLen - pluginDirNameLen - slashLen, pluginCfgFileName); + + FILE *pluginCfgFile = 0; + _wfopen_s(&pluginCfgFile, currentModuleName, L"r"); + if (!pluginCfgFile) + { + TRACE_HIVE_INFO("in directory \"%S\" no mandatory \"%S\"\n" + , find_data.cFileName, pluginCfgFileName); + continue; + } + + if (ParseFile(pluginCfgFile, descriptionRecord)) + { + try + { + push_back(descriptionRecord); + } + catch (...) { + TRACE_HIVE_ERROR("mRecords.push_back(descriptionRecord); - threw exception \n", 0); + } + } + + fclose(pluginCfgFile); + }while (FindNextFileW(fileFirst, &find_data)); + FindClose(fileFirst); +} + +bool MFX::MFXPluginsInFS::ParseFile(FILE * f, PluginDescriptionRecord & descriptionRecord) +{ + msdk_disp_char line[MAX_PLUGIN_FILE_LINE]; + + while(NULL != fgetws(line, sizeof(line) / sizeof(*line), f)) + { + msdk_disp_char *delimiter = wcschr(line, L'='); + if (0 == delimiter) + { + TRACE_HIVE_INFO("plugin.cfg contains line \"%S\" which is not in K=V format, skipping \n", line); + continue; + } + *delimiter = 0; + if (!ParseKVPair(line, delimiter + 1, descriptionRecord)) + { + return false; + } + } + + if (!mIsVersionParsed) + { + TRACE_HIVE_ERROR("%S : Mandatory key %S not found\n", pluginCfgFileName, PlgVerKeyName); + return false; + } + + if (!mIsAPIVersionParsed) + { + TRACE_HIVE_ERROR("%S : Mandatory key %S not found\n", pluginCfgFileName, APIVerKeyName); + return false; + } + + if (!wcslen(descriptionRecord.sPath)) + { + TRACE_HIVE_ERROR("%S : Mandatory key %S not found\n", pluginCfgFileName, pluginFileName); + return false; + } + + return true; +} + +bool MFX::MFXPluginsInFS::ParseKVPair( msdk_disp_char * key, msdk_disp_char* value, PluginDescriptionRecord & descriptionRecord) +{ + if (0 != wcsstr(key, PlgVerKeyName)) + { + mfxU32 version ; + if (0 == swscanf_s(value, L"%d", &version)) + { + return false; + } + descriptionRecord.PluginVersion = (mfxU16)version; + + if (0 == descriptionRecord.PluginVersion) + { + TRACE_HIVE_ERROR("%S: %S = %d, which is invalid\n", pluginCfgFileName, PlgVerKeyName, descriptionRecord.PluginVersion); + return false; + } + + TRACE_HIVE_INFO("%S: %S = %d \n", pluginCfgFileName, PlgVerKeyName, descriptionRecord.PluginVersion); + mIsVersionParsed = true; + return true; + } + + if (0 != wcsstr(key, APIVerKeyName)) + { + mfxU32 APIversion; + if (0 == swscanf_s(value, L"%d", &APIversion)) + { + return false; + } + + ConvertAPIVersion(APIversion, descriptionRecord); + TRACE_HIVE_INFO("%S: %S = %d.%d \n", pluginCfgFileName, APIVerKeyName, descriptionRecord.APIVersion.Major, descriptionRecord.APIVersion.Minor); + + mIsAPIVersionParsed = true; + return true; + } + + + if (0!=wcsstr(key, pluginFileName)) + { + msdk_disp_char *startQuoteMark = wcschr(value, L'\"'); + if (!startQuoteMark) + { + TRACE_HIVE_ERROR("plugin filename not in quotes : %S\n", value); + return false; + } + msdk_disp_char *endQuoteMark = wcschr(startQuoteMark + 1, L'\"'); + + if (!endQuoteMark) + { + TRACE_HIVE_ERROR("plugin filename not in quotes : %S\n", value); + return false; + } + *endQuoteMark = 0; + + mfxU32 currentPathLen = (mfxU32)wcslen(descriptionRecord.sPath); + if (currentPathLen + wcslen(startQuoteMark + 1) > sizeof(descriptionRecord.sPath) / sizeof(*descriptionRecord.sPath)) + { + TRACE_HIVE_ERROR("buffer of MAX_PLUGIN_PATH characters which is %d, not enough lo store plugin path: %S%S\n" + , MAX_PLUGIN_PATH, descriptionRecord.sPath, startQuoteMark + 1); + return false; + } + + size_t restrictedCharIdx = wcscspn(startQuoteMark + 1, pluginFileNameRestrictedCharacters); + if (restrictedCharIdx != wcslen(startQuoteMark + 1)) + { + TRACE_HIVE_ERROR("plugin filename :%S, contains one of restricted characters: %S\n", startQuoteMark + 1, pluginFileNameRestrictedCharacters); + return false; + } + + msdk_disp_char_cpy_s(descriptionRecord.sPath + currentPathLen + , sizeof(descriptionRecord.sPath) / sizeof(*descriptionRecord.sPath) - currentPathLen, startQuoteMark + 1); + + TRACE_HIVE_INFO("%S: %S = \"%S\" \n", pluginCfgFileName, pluginFileName, startQuoteMark + 1); + + return true; + } + + + return true; +} + +MFX::MFXDefaultPlugins::MFXDefaultPlugins(mfxVersion currentAPIVersion, MFX_DISP_HANDLE * hdl, int implType) + : MFXPluginStorageBase(currentAPIVersion) +{ + msdk_disp_char libModuleName[MAX_PLUGIN_PATH]; + + GetModuleFileNameW((HMODULE)hdl->hModule, libModuleName, MAX_PLUGIN_PATH); + if (GetLastError() != 0) + { + TRACE_HIVE_ERROR("GetModuleFileName() reported an error: %d\n", GetLastError()); + return; + } + msdk_disp_char *lastSlashPos = wcsrchr(libModuleName, L'\\'); + if (!lastSlashPos) { + lastSlashPos = libModuleName; + } + mfxU32 executableDirLen = (mfxU32)(lastSlashPos - libModuleName) + slashLen; + if (executableDirLen + defaultPluginNameLen >= MAX_PLUGIN_PATH) + { + TRACE_HIVE_ERROR("MAX_PLUGIN_PATH which is %d, not enough to locate default plugin path\n", MAX_PLUGIN_PATH); + return; + } + + mfx_get_default_plugin_name(lastSlashPos + slashLen, MAX_PLUGIN_PATH - executableDirLen, (eMfxImplType)implType); + + if (-1 != GetFileAttributesW(libModuleName)) + { + // add single default plugin description + PluginDescriptionRecord descriptionRecord; + descriptionRecord.APIVersion = currentAPIVersion; + descriptionRecord.Default = true; + + msdk_disp_char_cpy_s(descriptionRecord.sPath + , sizeof(descriptionRecord.sPath) / sizeof(*descriptionRecord.sPath), libModuleName); + + push_back(descriptionRecord); + } + else + { + TRACE_HIVE_INFO("GetFileAttributesW() unable to locate default plugin dll named %S\n", libModuleName); + } +} + + +#endif diff --git a/plugins/obs-qsv11/libmfx/src/mfx_win_reg_key.cpp b/plugins/obs-qsv11/libmfx/src/mfx_win_reg_key.cpp new file mode 100644 index 0000000..fb8c119 --- /dev/null +++ b/plugins/obs-qsv11/libmfx/src/mfx_win_reg_key.cpp @@ -0,0 +1,228 @@ +/* ****************************************************************************** *\ + +Copyright (C) 2012-2014 Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Intel Corporation nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +File Name: mfx_win_reg_key.cpp + +\* ****************************************************************************** */ + +#if defined(_WIN32) || defined(_WIN64) + +#include "mfx_win_reg_key.h" +#include "mfx_dispatcher_log.h" + +#define TRACE_WINREG_ERROR(str, ...) DISPATCHER_LOG_ERROR((("[WINREG]: "str), __VA_ARGS__)) + +namespace MFX +{ + +WinRegKey::WinRegKey(void) +{ + m_hKey = (HKEY) 0; + +} // WinRegKey::WinRegKey(void) + +WinRegKey::~WinRegKey(void) +{ + Release(); + +} // WinRegKey::~WinRegKey(void) + +void WinRegKey::Release(void) +{ + // close the opened key + if (m_hKey) + { + RegCloseKey(m_hKey); + } + + m_hKey = (HKEY) 0; + +} // void WinRegKey::Release(void) + +bool WinRegKey::Open(HKEY hRootKey, const wchar_t *pSubKey, REGSAM samDesired) +{ + LONG lRes; + HKEY hTemp; + + // + // All operation are performed in this order by intention. + // It makes possible to reopen the keys, using itself as a base. + // + + // try to the open registry key + lRes = RegOpenKeyExW(hRootKey, pSubKey, 0, samDesired, &hTemp); + if (ERROR_SUCCESS != lRes) + { + DISPATCHER_LOG_OPERATION(SetLastError(lRes)); + TRACE_WINREG_ERROR("Opening key \"%s\\%S\" : RegOpenKeyExW()==0x%x\n" + , (HKEY_LOCAL_MACHINE == hRootKey) ? ("HKEY_LOCAL_MACHINE") + : (HKEY_CURRENT_USER == hRootKey) ? ("HKEY_CURRENT_USER") + : "UNSUPPORTED_KEY", pSubKey, GetLastError()); + return false; + } + + // release the object before initialization + Release(); + + // save the handle + m_hKey = hTemp; + + return true; + +} // bool WinRegKey::Open(HKEY hRootKey, const wchar_t *pSubKey, REGSAM samDesired) + +bool WinRegKey::Open(WinRegKey &rootKey, const wchar_t *pSubKey, REGSAM samDesired) +{ + return Open(rootKey.m_hKey, pSubKey, samDesired); + +} // bool WinRegKey::Open(WinRegKey &rootKey, const wchar_t *pSubKey, REGSAM samDesired) + +bool WinRegKey::QueryValueSize(const wchar_t *pValueName, DWORD type, LPDWORD pcbData) { + DWORD keyType = type; + LONG lRes; + + // query the value + lRes = RegQueryValueExW(m_hKey, pValueName, NULL, &keyType, 0, pcbData); + if (ERROR_SUCCESS != lRes) + { + DISPATCHER_LOG_OPERATION(SetLastError(lRes)); + TRACE_WINREG_ERROR("Querying \"%S\" : RegQueryValueExA()==0x%x\n", pValueName, GetLastError()); + return false; + } + + return true; +} + +bool WinRegKey::Query(const wchar_t *pValueName, DWORD type, LPBYTE pData, LPDWORD pcbData) +{ + DWORD keyType = type; + LONG lRes; + DWORD dstSize = (pcbData) ? (*pcbData) : (0); + + // query the value + lRes = RegQueryValueExW(m_hKey, pValueName, NULL, &keyType, pData, pcbData); + if (ERROR_SUCCESS != lRes) + { + DISPATCHER_LOG_OPERATION(SetLastError(lRes)); + TRACE_WINREG_ERROR("Querying \"%S\" : RegQueryValueExA()==0x%x\n", pValueName, GetLastError()); + return false; + } + + // check the type + if (keyType != type) + { + TRACE_WINREG_ERROR("Querying \"%S\" : expectedType=%d, returned=%d\n", pValueName, type, keyType); + return false; + } + + // terminate the string only if pointers not NULL + if ((REG_SZ == type || REG_EXPAND_SZ == type) && NULL != pData && NULL != pcbData) + { + wchar_t *pString = (wchar_t *) pData; + size_t NullEndingSizeBytes = sizeof(wchar_t); // size of string termination null character + if (dstSize < NullEndingSizeBytes) + { + TRACE_WINREG_ERROR("Querying \"%S\" : buffer is too small for null-terminated string", pValueName); + return false; + } + size_t maxStringLengthBytes = dstSize - NullEndingSizeBytes; + size_t maxStringIndex = dstSize / sizeof(wchar_t) - 1; + + size_t lastIndex = (maxStringLengthBytes < *pcbData) ? (maxStringIndex) : (*pcbData) / sizeof(wchar_t); + + pString[lastIndex] = (wchar_t) 0; + } + else if(REG_MULTI_SZ == type && NULL != pData && NULL != pcbData) + { + wchar_t *pString = (wchar_t *) pData; + size_t NullEndingSizeBytes = sizeof(wchar_t)*2; // size of string termination null characters + if (dstSize < NullEndingSizeBytes) + { + TRACE_WINREG_ERROR("Querying \"%S\" : buffer is too small for multi-line null-terminated string", pValueName); + return false; + } + size_t maxStringLengthBytes = dstSize - NullEndingSizeBytes; + size_t maxStringIndex = dstSize / sizeof(wchar_t) - 1; + + size_t lastIndex = (maxStringLengthBytes < *pcbData) ? (maxStringIndex) : (*pcbData) / sizeof(wchar_t) + 1; + + // last 2 bytes should be 0 in case of REG_MULTI_SZ + pString[lastIndex] = pString[lastIndex - 1] = (wchar_t) 0; + } + + return true; + +} // bool WinRegKey::Query(const wchar_t *pValueName, DWORD type, LPBYTE pData, LPDWORD pcbData) + +bool WinRegKey::EnumValue(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName, LPDWORD pType) +{ + LONG lRes; + + // enum the values + lRes = RegEnumValueW(m_hKey, index, pValueName, pcchValueName, 0, pType, NULL, NULL); + if (ERROR_SUCCESS != lRes) + { + DISPATCHER_LOG_OPERATION(SetLastError(lRes)); + return false; + } + + return true; + +} // bool WinRegKey::EnumValue(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName, LPDWORD pType) + +bool WinRegKey::EnumKey(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName) +{ + LONG lRes; + + // enum the keys + lRes = RegEnumKeyExW(m_hKey, index, pValueName, pcchValueName, NULL, NULL, NULL, NULL); + if (ERROR_SUCCESS != lRes) + { + DISPATCHER_LOG_OPERATION(SetLastError(lRes)); + TRACE_WINREG_ERROR("EnumKey with index=%d: RegEnumKeyExW()==0x%x\n", index, GetLastError()); + return false; + } + + return true; + +} // bool WinRegKey::EnumKey(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName) + +bool WinRegKey::QueryInfo(LPDWORD lpcSubkeys) +{ + LONG lRes; + + lRes = RegQueryInfoKeyW(m_hKey, NULL, 0, 0, lpcSubkeys, 0, 0, 0, 0, 0, 0, 0); + if (ERROR_SUCCESS != lRes) { + TRACE_WINREG_ERROR("RegQueryInfoKeyW()==0x%x\n", lRes); + return false; + } + return true; + +} //bool QueryInfo(LPDWORD lpcSubkeys); + +} // namespace MFX + +#endif // #if defined(_WIN32) || defined(_WIN64) diff --git a/plugins/obs-qsv11/obs-qsv11-plugin-main.c b/plugins/obs-qsv11/obs-qsv11-plugin-main.c new file mode 100644 index 0000000..b7abbd0 --- /dev/null +++ b/plugins/obs-qsv11/obs-qsv11-plugin-main.c @@ -0,0 +1,86 @@ +/* + +This file is provided under a dual BSD/GPLv2 license. When using or +redistributing this file, you may do so under either license. + +GPL LICENSE SUMMARY + +Copyright(c) Oct. 2015 Intel Corporation. + +This program is free software; you can redistribute it and/or modify +it under the terms of version 2 of the GNU General Public License as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +Contact Information: + +Seung-Woo Kim, seung-woo.kim@intel.com +705 5th Ave S #500, Seattle, WA 98104 + +BSD LICENSE + +Copyright(c) Intel Corporation. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +* Neither the name of Intel Corporation nor the names of its +contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#include +#include "mfxsession.h" + +OBS_DECLARE_MODULE() +OBS_MODULE_USE_DEFAULT_LOCALE("obs-qsv11", "en-US") + +extern struct obs_encoder_info obs_qsv_encoder; + +bool obs_module_load(void) +{ + mfxIMPL impl = MFX_IMPL_HARDWARE_ANY | MFX_IMPL_VIA_D3D11; + mfxVersion ver = {{0 , 1}}; + mfxSession session; + mfxStatus sts; + + sts = MFXInit(impl, &ver, &session); + + if (sts == MFX_ERR_NONE) { + obs_register_encoder(&obs_qsv_encoder); + MFXClose(session); + } else { + impl = MFX_IMPL_HARDWARE_ANY | MFX_IMPL_VIA_D3D9; + sts = MFXInit(impl, &ver, &session); + if (sts == MFX_ERR_NONE) { + obs_register_encoder(&obs_qsv_encoder); + MFXClose(session); + } + } + + return true; +} diff --git a/plugins/obs-qsv11/obs-qsv11.c b/plugins/obs-qsv11/obs-qsv11.c new file mode 100644 index 0000000..42002f2 --- /dev/null +++ b/plugins/obs-qsv11/obs-qsv11.c @@ -0,0 +1,694 @@ +/* + +This file is provided under a dual BSD/GPLv2 license. When using or +redistributing this file, you may do so under either license. + +GPL LICENSE SUMMARY + +Copyright(c) Oct. 2015 Intel Corporation. + +This program is free software; you can redistribute it and/or modify +it under the terms of version 2 of the GNU General Public License as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +Contact Information: + +Seung-Woo Kim, seung-woo.kim@intel.com +705 5th Ave S #500, Seattle, WA 98104 + +BSD LICENSE + +Copyright(c) Intel Corporation. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +* Neither the name of Intel Corporation nor the names of its +contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include +#include + +#ifndef _STDINT_H_INCLUDED +#define _STDINT_H_INCLUDED +#endif + +#include "QSV_Encoder.h" +#include + +#define do_log(level, format, ...) \ + blog(level, "[qsv encoder: '%s'] " format, \ + obs_encoder_get_name(obsqsv->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__) + +/* ------------------------------------------------------------------------- */ + +struct obs_qsv { + obs_encoder_t *encoder; + + qsv_param_t params; + qsv_t *context; + + DARRAY(uint8_t) packet_data; + + uint8_t *extra_data; + uint8_t *sei; + + size_t extra_data_size; + size_t sei_size; + + os_performance_token_t *performance_token; +}; + +/* ------------------------------------------------------------------------- */ + +static CRITICAL_SECTION g_QsvCs; +static unsigned short g_verMajor; +static unsigned short g_verMinor; +static int64_t g_pts2dtsShift; +static int64_t g_prevDts; +static bool g_bFirst; + +static const char *obs_qsv_getname(void *type_data) +{ + UNUSED_PARAMETER(type_data); + return "QuickSync H.264"; +} + +static void obs_qsv_stop(void *data); + +static void clear_data(struct obs_qsv *obsqsv) +{ + if (obsqsv->context) { + qsv_encoder_close(obsqsv->context); + // bfree(obsqsv->sei); + bfree(obsqsv->extra_data); + + obsqsv->context = NULL; + // obsqsv->sei = NULL; + obsqsv->extra_data = NULL; + } +} + +static void obs_qsv_destroy(void *data) +{ + struct obs_qsv *obsqsv = (struct obs_qsv *)data; + + if (obsqsv) { + os_end_high_performance(obsqsv->performance_token); + clear_data(obsqsv); + da_free(obsqsv->packet_data); + bfree(obsqsv); + } +} + +static void obs_qsv_defaults(obs_data_t *settings) +{ + obs_data_set_default_string(settings, "target_usage", "balanced"); + obs_data_set_default_int(settings, "bitrate", 2500); + obs_data_set_default_int(settings, "max_bitrate", 3000); + obs_data_set_default_string(settings, "profile", "main"); + obs_data_set_default_int(settings, "async_depth", 4); + obs_data_set_default_string(settings, "rate_control", "CBR"); + + obs_data_set_default_int(settings, "accuracy", 1000); + obs_data_set_default_int(settings, "convergence", 1); + obs_data_set_default_int(settings, "qpi", 23); + obs_data_set_default_int(settings, "qpp", 23); + obs_data_set_default_int(settings, "qpb", 23); + obs_data_set_default_int(settings, "icq_quality", 23); + obs_data_set_default_int(settings, "la_depth", 40); + + obs_data_set_default_int(settings, "keyint_sec", 3); +} + +static inline void add_strings(obs_property_t *list, const char *const *strings) +{ + while (*strings) { + obs_property_list_add_string(list, *strings, *strings); + strings++; + } +} + +#define TEXT_SPEED obs_module_text("TargetUsage") +#define TEXT_TARGET_BITRATE obs_module_text("Bitrate") +#define TEXT_MAX_BITRATE obs_module_text("MaxBitrate") +#define TEXT_PROFILE obs_module_text("Profile") +#define TEXT_ASYNC_DEPTH obs_module_text("AsyncDepth") +#define TEXT_RATE_CONTROL obs_module_text("RateControl") +#define TEXT_ACCURACY obs_module_text("Accuracy") +#define TEXT_CONVERGENCE obs_module_text("Convergence") +#define TEXT_ICQ_QUALITY obs_module_text("ICQQuality") +#define TEXT_LA_DEPTH obs_module_text("LookAheadDepth") +#define TEXT_KEYINT_SEC obs_module_text("KeyframeIntervalSec") + +static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p, + obs_data_t *settings) +{ + const char *rate_control = obs_data_get_string(settings, "rate_control"); + + bool bVisible = + astrcmpi(rate_control, "VCM") == 0 || + astrcmpi(rate_control, "VBR") == 0; + p = obs_properties_get(ppts, "max_bitrate"); + obs_property_set_visible(p, bVisible); + + bVisible = + astrcmpi(rate_control, "CQP") == 0 || + astrcmpi(rate_control, "LA_ICQ") == 0 || + astrcmpi(rate_control, "ICQ") == 0; + p = obs_properties_get(ppts, "bitrate"); + obs_property_set_visible(p, !bVisible); + + bVisible = astrcmpi(rate_control, "AVBR") == 0; + p = obs_properties_get(ppts, "accuracy"); + obs_property_set_visible(p, bVisible); + p = obs_properties_get(ppts, "convergence"); + obs_property_set_visible(p, bVisible); + + bVisible = astrcmpi(rate_control, "CQP") == 0; + p = obs_properties_get(ppts, "qpi"); + obs_property_set_visible(p, bVisible); + p = obs_properties_get(ppts, "qpb"); + obs_property_set_visible(p, bVisible); + p = obs_properties_get(ppts, "qpp"); + obs_property_set_visible(p, bVisible); + + bVisible = astrcmpi(rate_control, "ICQ") == 0 || + astrcmpi(rate_control, "LA_ICQ") == 0; + p = obs_properties_get(ppts, "icq_quality"); + obs_property_set_visible(p, bVisible); + + bVisible = astrcmpi(rate_control, "LA_ICQ") == 0 || + astrcmpi(rate_control, "LA") == 0; + p = obs_properties_get(ppts, "la_depth"); + obs_property_set_visible(p, bVisible); + + return true; +} + +static inline void add_rate_controls(obs_property_t *list, + const struct qsv_rate_control_info *rc) +{ + enum qsv_cpu_platform plat = qsv_get_cpu_platform(); + while (rc->name) { + if (!rc->haswell_or_greater || plat >= QSV_CPU_PLATFORM_HSW) + obs_property_list_add_string(list, rc->name, rc->name); + rc++; + } +} + +static obs_properties_t *obs_qsv_props(void *unused) +{ + UNUSED_PARAMETER(unused); + + obs_properties_t *props = obs_properties_create(); + obs_property_t *list; + + list = obs_properties_add_list(props, "target_usage", TEXT_SPEED, + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + add_strings(list, qsv_usage_names); + + list = obs_properties_add_list(props, "profile", TEXT_PROFILE, + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + add_strings(list, qsv_profile_names); + + obs_properties_add_int(props, "keyint_sec", TEXT_KEYINT_SEC, 1, 20, 1); + obs_properties_add_int(props, "async_depth", TEXT_ASYNC_DEPTH, 1, 7, 1); + + list = obs_properties_add_list(props, "rate_control", TEXT_RATE_CONTROL, + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + add_rate_controls(list, qsv_ratecontrols); + obs_property_set_modified_callback(list, rate_control_modified); + + obs_properties_add_int(props, "bitrate", TEXT_TARGET_BITRATE, 50, + 10000000, 1); + obs_properties_add_int(props, "max_bitrate", TEXT_MAX_BITRATE, 50, + 10000000, 1); + obs_properties_add_int(props, "accuracy", TEXT_ACCURACY, 0, 10000, 1); + obs_properties_add_int(props, "convergence", TEXT_CONVERGENCE, 0, 10, 1); + obs_properties_add_int(props, "qpi", "QPI", 1, 51, 1); + obs_properties_add_int(props, "qpp", "QPP", 1, 51, 1); + obs_properties_add_int(props, "qpb", "QPB", 1, 51, 1); + obs_properties_add_int(props, "icq_quality", TEXT_ICQ_QUALITY, 1, 51, 1); + obs_properties_add_int(props, "la_depth", TEXT_LA_DEPTH, 10, 100, 1); + + return props; +} + +static void update_params(struct obs_qsv *obsqsv, obs_data_t *settings) +{ + video_t *video = obs_encoder_video(obsqsv->encoder); + const struct video_output_info *voi = video_output_get_info(video); + + const char *target_usage = obs_data_get_string(settings, "target_usage"); + const char *profile = obs_data_get_string(settings, "profile"); + const char *rate_control = obs_data_get_string(settings, "rate_control"); + int async_depth = (int)obs_data_get_int(settings, "async_depth"); + int target_bitrate = (int)obs_data_get_int(settings, "bitrate"); + int max_bitrate = (int)obs_data_get_int(settings, "max_bitrate"); + int accuracy = (int)obs_data_get_int(settings, "accuracy"); + int convergence = (int)obs_data_get_int(settings, "convergence"); + int qpi = (int)obs_data_get_int(settings, "qpi"); + int qpp = (int)obs_data_get_int(settings, "qpp"); + int qpb = (int)obs_data_get_int(settings, "qpb"); + int icq_quality = (int)obs_data_get_int(settings, "icq_quality"); + int la_depth = (int)obs_data_get_int(settings, "la_depth"); + int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec"); + bool cbr_override = obs_data_get_bool(settings, "cbr"); + int bFrames = 7; + + int width = (int)obs_encoder_get_width(obsqsv->encoder); + int height = (int)obs_encoder_get_height(obsqsv->encoder); + if (astrcmpi(target_usage, "quality") == 0) + obsqsv->params.nTargetUsage = MFX_TARGETUSAGE_BEST_QUALITY; + else if (astrcmpi(target_usage, "balanced") == 0) + obsqsv->params.nTargetUsage = MFX_TARGETUSAGE_BALANCED; + else if (astrcmpi(target_usage, "speed") == 0) + obsqsv->params.nTargetUsage = MFX_TARGETUSAGE_BEST_SPEED; + + if (astrcmpi(profile, "baseline") == 0) + obsqsv->params.nCodecProfile = MFX_PROFILE_AVC_BASELINE; + else if (astrcmpi(profile, "main") == 0) + obsqsv->params.nCodecProfile = MFX_PROFILE_AVC_MAIN; + else if (astrcmpi(profile, "high") == 0) + obsqsv->params.nCodecProfile = MFX_PROFILE_AVC_HIGH; + + /* internal convenience parameter, overrides rate control param + * XXX: Deprecated */ + if (cbr_override) { + warn("\"cbr\" setting has been deprecated for all encoders! " + "Please set \"rate_control\" to \"CBR\" instead. " + "Forcing CBR mode. " + "(Note to all: this is why you shouldn't use strings for " + "common settings)"); + rate_control = "CBR"; + } + + if (astrcmpi(rate_control, "CBR") == 0) + obsqsv->params.nRateControl = MFX_RATECONTROL_CBR; + else if (astrcmpi(rate_control, "VBR") == 0) + obsqsv->params.nRateControl = MFX_RATECONTROL_VBR; + else if (astrcmpi(rate_control, "VCM") == 0) + obsqsv->params.nRateControl = MFX_RATECONTROL_VCM; + else if (astrcmpi(rate_control, "CQP") == 0) + obsqsv->params.nRateControl = MFX_RATECONTROL_CQP; + else if (astrcmpi(rate_control, "AVBR") == 0) + obsqsv->params.nRateControl = MFX_RATECONTROL_AVBR; + else if (astrcmpi(rate_control, "ICQ") == 0) + obsqsv->params.nRateControl = MFX_RATECONTROL_ICQ; + else if (astrcmpi(rate_control, "LA_ICQ") == 0) + obsqsv->params.nRateControl = MFX_RATECONTROL_LA_ICQ; + else if (astrcmpi(rate_control, "LA") == 0) + obsqsv->params.nRateControl = MFX_RATECONTROL_LA; + + obsqsv->params.nAsyncDepth = (mfxU16)async_depth; + obsqsv->params.nAccuracy = (mfxU16)accuracy; + obsqsv->params.nConvergence = (mfxU16)convergence; + obsqsv->params.nQPI = (mfxU16)qpi; + obsqsv->params.nQPP = (mfxU16)qpp; + obsqsv->params.nQPB = (mfxU16)qpb; + obsqsv->params.nLADEPTH = (mfxU16)la_depth; + obsqsv->params.nTargetBitRate = (mfxU16)target_bitrate; + obsqsv->params.nMaxBitRate = (mfxU16)max_bitrate; + obsqsv->params.nWidth = (mfxU16)width; + obsqsv->params.nHeight = (mfxU16)height; + obsqsv->params.nFpsNum = (mfxU16)voi->fps_num; + obsqsv->params.nFpsDen = (mfxU16)voi->fps_den; + obsqsv->params.nbFrames = (mfxU16)bFrames; + obsqsv->params.nKeyIntSec = (mfxU16)keyint_sec; + obsqsv->params.nICQQuality = (mfxU16)icq_quality; + + info("settings:\n\trate_control: %s", rate_control); + + if (obsqsv->params.nRateControl != MFX_RATECONTROL_LA_ICQ && + obsqsv->params.nRateControl != MFX_RATECONTROL_ICQ && + obsqsv->params.nRateControl != MFX_RATECONTROL_CQP) + blog(LOG_INFO, + "\ttarget_bitrate: %d", + (int)obsqsv->params.nTargetBitRate); + + if (obsqsv->params.nRateControl == MFX_RATECONTROL_VBR || + obsqsv->params.nRateControl == MFX_RATECONTROL_VCM) + blog(LOG_INFO, + "\tmax_bitrate: %d", + (int)obsqsv->params.nMaxBitRate); + + if (obsqsv->params.nRateControl == MFX_RATECONTROL_LA_ICQ || + obsqsv->params.nRateControl == MFX_RATECONTROL_ICQ) + blog(LOG_INFO, + "\tICQ Quality: %d", + (int)obsqsv->params.nICQQuality); + + if (obsqsv->params.nRateControl == MFX_RATECONTROL_LA_ICQ || + obsqsv->params.nRateControl == MFX_RATECONTROL_LA) + blog(LOG_INFO, + "\tLookahead Depth:%d", + (int)obsqsv->params.nLADEPTH); + + if (obsqsv->params.nRateControl == MFX_RATECONTROL_CQP) + blog(LOG_INFO, + "\tqpi: %d\n" + "\tqpb: %d\n" + "\tqpp: %d", + qpi, qpb, qpp); + + blog(LOG_INFO, + "\tfps_num: %d\n" + "\tfps_den: %d\n" + "\twidth: %d\n" + "\theight: %d", + voi->fps_num, voi->fps_den, + width, height); + + info("debug info:"); +} + +static bool update_settings(struct obs_qsv *obsqsv, obs_data_t *settings) +{ + update_params(obsqsv, settings); + return true; +} + +static void load_headers(struct obs_qsv *obsqsv) +{ + DARRAY(uint8_t) header; + uint8_t sei = 0; + + // Not sure if SEI is needed. + // Just filling in empty meaningless SEI message. + // Seems to work fine. + // DARRAY(uint8_t) sei; + + da_init(header); + // da_init(sei); + + uint8_t *pSPS, *pPPS; + uint16_t nSPS, nPPS; + qsv_encoder_headers(obsqsv->context, &pSPS, &pPPS, &nSPS, &nPPS); + da_push_back_array(header, pSPS, nSPS); + da_push_back_array(header, pPPS, nPPS); + + obsqsv->extra_data = header.array; + obsqsv->extra_data_size = header.num; + obsqsv->sei = &sei; + obsqsv->sei_size = 1; +} + +static bool obs_qsv_update(void *data, obs_data_t *settings) +{ + struct obs_qsv *obsqsv = data; + bool success = update_settings(obsqsv, settings); + int ret; + + + if (success) { + EnterCriticalSection(&g_QsvCs); + + ret = qsv_encoder_reconfig(obsqsv->context, &obsqsv->params); + if (ret != 0) + warn("Failed to reconfigure: %d", ret); + + LeaveCriticalSection(&g_QsvCs); + + return ret == 0; + } + + return false; +} + +static void *obs_qsv_create(obs_data_t *settings, obs_encoder_t *encoder) +{ + InitializeCriticalSection(&g_QsvCs); + + struct obs_qsv *obsqsv = bzalloc(sizeof(struct obs_qsv)); + obsqsv->encoder = encoder; + + if (update_settings(obsqsv, settings)) { + obsqsv->context = qsv_encoder_open(&obsqsv->params); + + if (obsqsv->context == NULL) + warn("qsv failed to load"); + else + load_headers(obsqsv); + } else { + warn("bad settings specified"); + } + + qsv_encoder_version(&g_verMajor, &g_verMinor); + + blog(LOG_INFO, "\tmajor: %d\n" + "\tminor: %d", + g_verMajor, g_verMinor); + + // MSDK 1.6 or less doesn't have automatic DTS calculation + // including early SandyBridge. + // Need to add manual DTS from PTS. + if (g_verMajor == 1 && g_verMinor < 7) { + int64_t interval = obsqsv->params.nbFrames + 1; + int64_t GopPicSize = (int64_t)(obsqsv->params.nKeyIntSec * + obsqsv->params.nFpsNum / + (float)obsqsv->params.nFpsDen); + g_pts2dtsShift = GopPicSize - (GopPicSize / interval) * + interval; + + blog(LOG_INFO, "\tinterval: %d\n" + "\tGopPictSize: %d\n" + "\tg_pts2dtsShift: %d", + interval, GopPicSize, g_pts2dtsShift); + } + else + g_pts2dtsShift = -1; + + if (!obsqsv->context) { + bfree(obsqsv); + return NULL; + } + + obsqsv->performance_token = + os_request_high_performance("qsv encoding"); + + g_bFirst = true; + + return obsqsv; +} + +static bool obs_qsv_extra_data(void *data, uint8_t **extra_data, size_t *size) +{ + struct obs_qsv *obsqsv = data; + + if (!obsqsv->context) + return false; + + *extra_data = obsqsv->extra_data; + *size = obsqsv->extra_data_size; + return true; +} + +static bool obs_qsv_sei(void *data, uint8_t **sei,size_t *size) +{ + struct obs_qsv *obsqsv = data; + + if (!obsqsv->context) + return false; + + /* (Jim) Unused */ + UNUSED_PARAMETER(sei); + UNUSED_PARAMETER(size); + + *sei = obsqsv->sei; + *size = obsqsv->sei_size; + return true; +} + +static inline bool valid_format(enum video_format format) +{ + return format == VIDEO_FORMAT_NV12; +} + +static inline void cap_resolution(obs_encoder_t *encoder, + struct video_scale_info *info) +{ + enum qsv_cpu_platform qsv_platform = qsv_get_cpu_platform(); + uint32_t width = obs_encoder_get_width(encoder); + uint32_t height = obs_encoder_get_height(encoder); + + info->height = height; + info->width = width; + + if (qsv_platform <= QSV_CPU_PLATFORM_IVB) { + if (width > 1920) { + info->width = 1920; + } + + if (height > 1200) { + info->height = 1200; + } + } +} + +static void obs_qsv_video_info(void *data, struct video_scale_info *info) +{ + struct obs_qsv *obsqsv = data; + enum video_format pref_format; + + pref_format = obs_encoder_get_preferred_video_format(obsqsv->encoder); + + if (!valid_format(pref_format)) { + pref_format = valid_format(info->format) ? + info->format : VIDEO_FORMAT_NV12; + } + + info->format = pref_format; + cap_resolution(obsqsv->encoder, info); +} + +static void parse_packet(struct obs_qsv *obsqsv, struct encoder_packet *packet, mfxBitstream *pBS, uint32_t fps_num, bool *received_packet) +{ + if (pBS == NULL || pBS->DataLength == 0) { + *received_packet = false; + return; + } + + da_resize(obsqsv->packet_data, 0); + da_push_back_array(obsqsv->packet_data, &pBS->Data[pBS->DataOffset], + pBS->DataLength); + + packet->data = obsqsv->packet_data.array; + packet->size = obsqsv->packet_data.num; + packet->type = OBS_ENCODER_VIDEO; + packet->pts = pBS->TimeStamp * fps_num / 90000; + packet->keyframe = (pBS->FrameType & + (MFX_FRAMETYPE_I | MFX_FRAMETYPE_REF)); + + //bool iFrame = pBS->FrameType & MFX_FRAMETYPE_I; + //bool bFrame = pBS->FrameType & MFX_FRAMETYPE_B; + bool pFrame = pBS->FrameType & MFX_FRAMETYPE_P; + //int iType = iFrame ? 0 : (bFrame ? 1 : (pFrame ? 2 : -1)); + //int64_t interval = obsqsv->params.nbFrames + 1; + + // In case MSDK does't support automatic DecodeTimeStamp, do manual + // calculation + if (g_pts2dtsShift >= 0) + { + if (g_bFirst) { + packet->dts = packet->pts - 3 * obsqsv->params.nFpsDen; + } else if (pFrame) { + packet->dts = packet->pts - 10 * obsqsv->params.nFpsDen; + g_prevDts = packet->dts; + } else { + packet->dts = g_prevDts + obsqsv->params.nFpsDen; + g_prevDts = packet->dts; + } + } else { + packet->dts = pBS->DecodeTimeStamp * fps_num / 90000; + } + +#if 0 + info("parse packet:\n" + "\tFrameType: %d\n" + "\tpts: %d\n" + "\tdts: %d", + iType, packet->pts, packet->dts); +#endif + + *received_packet = true; + pBS->DataLength = 0; + + g_bFirst = false; +} + +static bool obs_qsv_encode(void *data, struct encoder_frame *frame, + struct encoder_packet *packet, bool *received_packet) +{ + struct obs_qsv *obsqsv = data; + + if (!frame || !packet || !received_packet) + return false; + + EnterCriticalSection(&g_QsvCs); + + + video_t *video = obs_encoder_video(obsqsv->encoder); + const struct video_output_info *voi = video_output_get_info(video); + + mfxBitstream *pBS = NULL; + + int ret; + + mfxU64 qsvPTS = frame->pts * 90000 / voi->fps_num; + + if (frame) + ret = qsv_encoder_encode( + obsqsv->context, + qsvPTS, + frame->data[0], frame->data[1], frame->linesize[0], + frame->linesize[1], + &pBS); + else + ret = qsv_encoder_encode( + obsqsv->context, + qsvPTS, + NULL, NULL, 0, 0, &pBS); + + if (ret < 0) { + warn("encode failed"); + return false; + } + + parse_packet(obsqsv, packet, pBS, voi->fps_num, received_packet); + + LeaveCriticalSection(&g_QsvCs); + + return true; +} + +struct obs_encoder_info obs_qsv_encoder = { + .id = "obs_qsv11", + .type = OBS_ENCODER_VIDEO, + .codec = "h264", + .get_name = obs_qsv_getname, + .create = obs_qsv_create, + .destroy = obs_qsv_destroy, + .encode = obs_qsv_encode, + .update = obs_qsv_update, + .get_properties = obs_qsv_props, + .get_defaults = obs_qsv_defaults, + .get_extra_data = obs_qsv_extra_data, + .get_sei_data = obs_qsv_sei, + .get_video_info = obs_qsv_video_info +}; diff --git a/plugins/obs-transitions/CMakeLists.txt b/plugins/obs-transitions/CMakeLists.txt index 9ceac5e..c6b6f57 100644 --- a/plugins/obs-transitions/CMakeLists.txt +++ b/plugins/obs-transitions/CMakeLists.txt @@ -2,8 +2,11 @@ project(obs-transitions) set(obs-transitions_SOURCES obs-transitions.c + transition-slide.c + transition-swipe.c transition-fade.c transition-cut.c + transition-fade-to-color.c ) add_library(obs-transitions MODULE diff --git a/plugins/obs-transitions/data/fade_to_color_transition.effect b/plugins/obs-transitions/data/fade_to_color_transition.effect new file mode 100644 index 0000000..4f06935 --- /dev/null +++ b/plugins/obs-transitions/data/fade_to_color_transition.effect @@ -0,0 +1,37 @@ +uniform float4x4 ViewProj; +uniform texture2d tex; +uniform float swp; +uniform float4 color; + +sampler_state textureSampler { + Filter = Linear; + AddressU = Clamp; + AddressV = Clamp; +}; + +struct VertData { + float4 pos : POSITION; + float2 uv : TEXCOORD0; +}; + +VertData VSDefault(VertData v_in) +{ + VertData vert_out; + vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj); + vert_out.uv = v_in.uv; + return vert_out; +} + +float4 PSFadeToColor(VertData v_in) : TARGET +{ + return lerp(tex.Sample(textureSampler, v_in.uv), color, swp); +} + +technique FadeToColor +{ + pass + { + vertex_shader = VSDefault(v_in); + pixel_shader = PSFadeToColor(v_in); + } +} diff --git a/plugins/obs-transitions/data/locale/ar-SA.ini b/plugins/obs-transitions/data/locale/ar-SA.ini new file mode 100644 index 0000000..d6255ac --- /dev/null +++ b/plugins/obs-transitions/data/locale/ar-SA.ini @@ -0,0 +1,10 @@ +FadeTransition="تلاشي" +CutTransition="قطع" +FadeToColorTransition="تلاشي إلى لون" +Direction="الإتجاه" +Direction.Left="يسار" +Direction.Right="يمين" +Direction.Up="أعلى" +Direction.Down="أسفل" +Color="اللون" + diff --git a/plugins/obs-transitions/data/locale/ca-ES.ini b/plugins/obs-transitions/data/locale/ca-ES.ini new file mode 100644 index 0000000..55fd969 --- /dev/null +++ b/plugins/obs-transitions/data/locale/ca-ES.ini @@ -0,0 +1,14 @@ +FadeTransition="Esvair" +CutTransition="Talla" +SwipeTransition="Lliscar" +SlideTransition="Lliscar" +FadeToColorTransition="Esvair a Color" +Direction="Direcció" +Direction.Left="Esquerra" +Direction.Right="Dreta" +Direction.Up="Amunt" +Direction.Down="Avall" +SwipeIn="Lliscament" +Color="Color" +SwitchPoint="Punt de Color màxim (percentatge)" + diff --git a/plugins/obs-transitions/data/locale/cs-CZ.ini b/plugins/obs-transitions/data/locale/cs-CZ.ini index 4e86086..d7bffc2 100644 --- a/plugins/obs-transitions/data/locale/cs-CZ.ini +++ b/plugins/obs-transitions/data/locale/cs-CZ.ini @@ -1,3 +1,14 @@ FadeTransition="Slábnutí" CutTransition="Střih" +SwipeTransition="Tažení" +SlideTransition="Sklouznutí" +FadeToColorTransition="Barevný přechod" +Direction="Směr" +Direction.Left="Vlevo" +Direction.Right="Vpravo" +Direction.Up="Nahoru" +Direction.Down="Dolů" +SwipeIn="Vtáhnout" +Color="Barva" +SwitchPoint="Špičkový bod barvy (%)" diff --git a/plugins/obs-transitions/data/locale/da-DK.ini b/plugins/obs-transitions/data/locale/da-DK.ini new file mode 100644 index 0000000..557b727 --- /dev/null +++ b/plugins/obs-transitions/data/locale/da-DK.ini @@ -0,0 +1,14 @@ +FadeTransition="Overgang" +CutTransition="Klip" +SwipeTransition="Swipe" +SlideTransition="Glide" +FadeToColorTransition="Fade til farve" +Direction="Retning" +Direction.Left="Venstre" +Direction.Right="Højre" +Direction.Up="Op" +Direction.Down="Ned" +SwipeIn="Swipe ind" +Color="Farve" +SwitchPoint="Farvepeakpunkt (procent)" + diff --git a/plugins/obs-transitions/data/locale/de-DE.ini b/plugins/obs-transitions/data/locale/de-DE.ini index 97add9f..4df2128 100644 --- a/plugins/obs-transitions/data/locale/de-DE.ini +++ b/plugins/obs-transitions/data/locale/de-DE.ini @@ -1,3 +1,14 @@ FadeTransition="Überblenden" CutTransition="Schnitt" +SwipeTransition="Swipe" +SlideTransition="Slide" +FadeToColorTransition="Fade to Color" +Direction="Richtung" +Direction.Left="Links" +Direction.Right="Rechts" +Direction.Up="Hoch" +Direction.Down="Runter" +SwipeIn="Swipe In" +Color="Farbe" +SwitchPoint="Peakfarbpunkt (Prozent)" diff --git a/plugins/obs-transitions/data/locale/el-GR.ini b/plugins/obs-transitions/data/locale/el-GR.ini new file mode 100644 index 0000000..a23a5cf --- /dev/null +++ b/plugins/obs-transitions/data/locale/el-GR.ini @@ -0,0 +1,3 @@ +FadeTransition="Ξεθώριασμα" +CutTransition="Αποκοπή" + diff --git a/plugins/obs-transitions/data/locale/en-US.ini b/plugins/obs-transitions/data/locale/en-US.ini index 64dbed5..a207269 100644 --- a/plugins/obs-transitions/data/locale/en-US.ini +++ b/plugins/obs-transitions/data/locale/en-US.ini @@ -1,2 +1,13 @@ FadeTransition="Fade" CutTransition="Cut" +SwipeTransition="Swipe" +SlideTransition="Slide" +FadeToColorTransition="Fade to Color" +Direction="Direction" +Direction.Left="Left" +Direction.Right="Right" +Direction.Up="Up" +Direction.Down="Down" +SwipeIn="Swipe In" +Color="Color" +SwitchPoint="Peak Color Point (percentage)" diff --git a/plugins/obs-transitions/data/locale/es-ES.ini b/plugins/obs-transitions/data/locale/es-ES.ini index 0274809..1605b1c 100644 --- a/plugins/obs-transitions/data/locale/es-ES.ini +++ b/plugins/obs-transitions/data/locale/es-ES.ini @@ -1,3 +1,14 @@ FadeTransition="Desvanecimiento" CutTransition="Corte" +SwipeTransition="Deslizar" +SlideTransition="Deslizar" +FadeToColorTransition="Desvanecer a Color" +Direction="Dirección" +Direction.Left="Izquierda" +Direction.Right="Derecha" +Direction.Up="Arriba" +Direction.Down="Abajo" +SwipeIn="Deslizamiento" +Color="Color" +SwitchPoint="Punto de Color máximo (porcentaje)" diff --git a/plugins/obs-transitions/data/locale/eu-ES.ini b/plugins/obs-transitions/data/locale/eu-ES.ini index 0a40d2b..5013bcc 100644 --- a/plugins/obs-transitions/data/locale/eu-ES.ini +++ b/plugins/obs-transitions/data/locale/eu-ES.ini @@ -1,3 +1,14 @@ -FadeTransition="Hutsaldu" -CutTransition="Moztu" +FadeTransition="Iraungi" +CutTransition="Etena" +SwipeTransition="Korritu" +SlideTransition="Irristatu" +FadeToColorTransition="Iraungi kolorera" +Direction="Norabidea" +Direction.Left="Ezker" +Direction.Right="Eskuin" +Direction.Up="Gora" +Direction.Down="Behera" +SwipeIn="Korritu bertan" +Color="Kolorea" +SwitchPoint="Kolorearen gailur puntua (ehunekoa)" diff --git a/plugins/obs-transitions/data/locale/fi-FI.ini b/plugins/obs-transitions/data/locale/fi-FI.ini index e7033bb..3872a7b 100644 --- a/plugins/obs-transitions/data/locale/fi-FI.ini +++ b/plugins/obs-transitions/data/locale/fi-FI.ini @@ -1,3 +1,14 @@ FadeTransition="Häivytä" CutTransition="Leikkaa" +SwipeTransition="Pyyhkäise" +SlideTransition="Liu'uta" +FadeToColorTransition="Häivytä väriin" +Direction="Suunta" +Direction.Left="Vasemmalta" +Direction.Right="Oikealta" +Direction.Up="Ylhäältä" +Direction.Down="Alhaalta" +SwipeIn="Pyyhkäise yli" +Color="Väri" +SwitchPoint="Korkein väripiste (prosentti)" diff --git a/plugins/obs-transitions/data/locale/fr-FR.ini b/plugins/obs-transitions/data/locale/fr-FR.ini index a65fba6..07b9d80 100644 --- a/plugins/obs-transitions/data/locale/fr-FR.ini +++ b/plugins/obs-transitions/data/locale/fr-FR.ini @@ -1,3 +1,14 @@ FadeTransition="Fondu" CutTransition="Coupure" +SwipeTransition="Balayage" +SlideTransition="Glissement" +FadeToColorTransition="Fondu avec couleur" +Direction="Direction" +Direction.Left="Gauche" +Direction.Right="Droite" +Direction.Up="Haut" +Direction.Down="Bas" +SwipeIn="Recouvrement" +Color="Couleur" +SwitchPoint="Point de couleur maximal (pourcentage)" diff --git a/plugins/obs-transitions/data/locale/gl-ES.ini b/plugins/obs-transitions/data/locale/gl-ES.ini new file mode 100644 index 0000000..69587e6 --- /dev/null +++ b/plugins/obs-transitions/data/locale/gl-ES.ini @@ -0,0 +1,8 @@ +CutTransition="Cortar" +Direction="Dirección" +Direction.Left="Esquerda" +Direction.Right="Dereita" +Direction.Up="Arriba" +Direction.Down="Abaixo" +Color="Cor" + diff --git a/plugins/obs-transitions/data/locale/he-IL.ini b/plugins/obs-transitions/data/locale/he-IL.ini new file mode 100644 index 0000000..22abe75 --- /dev/null +++ b/plugins/obs-transitions/data/locale/he-IL.ini @@ -0,0 +1,14 @@ +FadeTransition="עמעום" +CutTransition="חתוך" +SwipeTransition="החלקה" +SlideTransition="הסט" +FadeToColorTransition="עמם לצבע" +Direction="כיוון" +Direction.Left="שמאל" +Direction.Right="ימין" +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 434230a..27a82f3 100644 --- a/plugins/obs-transitions/data/locale/hr-HR.ini +++ b/plugins/obs-transitions/data/locale/hr-HR.ini @@ -1,3 +1,14 @@ FadeTransition="Zatamnjenje" CutTransition="Sečenje" +SwipeTransition="Prevlačenje" +SlideTransition="Klizanje" +FadeToColorTransition="Iščezavanje u boju" +Direction="Pravac" +Direction.Left="Levo" +Direction.Right="Desno" +Direction.Up="Gore" +Direction.Down="Dole" +SwipeIn="Uvlačenje" +Color="Boja" +SwitchPoint="Tačka vrhunca boje (procenat)" diff --git a/plugins/obs-transitions/data/locale/hu-HU.ini b/plugins/obs-transitions/data/locale/hu-HU.ini index 1fdc478..33b88a3 100644 --- a/plugins/obs-transitions/data/locale/hu-HU.ini +++ b/plugins/obs-transitions/data/locale/hu-HU.ini @@ -1,3 +1,14 @@ FadeTransition="Áttűnés" CutTransition="Kivágás" +SwipeTransition="Lapozás" +SlideTransition="Csúsztatás" +FadeToColorTransition="Színes áttűnés" +Direction="Irány" +Direction.Left="Bal" +Direction.Right="Jobb" +Direction.Up="Fel" +Direction.Down="Le" +SwipeIn="Belapozás" +Color="Szín" +SwitchPoint="Színpont csúcs (százalék)" diff --git a/plugins/obs-transitions/data/locale/ja-JP.ini b/plugins/obs-transitions/data/locale/ja-JP.ini index 6f49896..505ed2c 100644 --- a/plugins/obs-transitions/data/locale/ja-JP.ini +++ b/plugins/obs-transitions/data/locale/ja-JP.ini @@ -1,3 +1,14 @@ FadeTransition="フェード" CutTransition="カット" +SwipeTransition="スワイプ" +SlideTransition="スライド" +FadeToColorTransition="カラーにフェード" +Direction="方向" +Direction.Left="左" +Direction.Right="右" +Direction.Up="上" +Direction.Down="下" +SwipeIn="スワイプイン" +Color="色" +SwitchPoint="ピークカラーポイント (割合)" diff --git a/plugins/obs-transitions/data/locale/ko-KR.ini b/plugins/obs-transitions/data/locale/ko-KR.ini index 5d678e9..c3667cf 100644 --- a/plugins/obs-transitions/data/locale/ko-KR.ini +++ b/plugins/obs-transitions/data/locale/ko-KR.ini @@ -1,3 +1,14 @@ FadeTransition="서서히 사라지기" CutTransition="자르기" +SwipeTransition="밀어내기" +SlideTransition="슬라이드" +FadeToColorTransition="특정 색상으로 서서히 사라지기" +Direction="방향" +Direction.Left="왼쪽" +Direction.Right="오른쪽" +Direction.Up="위쪽" +Direction.Down="아래쪽" +SwipeIn="덮기" +Color="색상" +SwitchPoint="최고조 색상 지점 (백분율)" diff --git a/plugins/obs-transitions/data/locale/nl-NL.ini b/plugins/obs-transitions/data/locale/nl-NL.ini index 829740a..7986bac 100644 --- a/plugins/obs-transitions/data/locale/nl-NL.ini +++ b/plugins/obs-transitions/data/locale/nl-NL.ini @@ -1,3 +1,14 @@ FadeTransition="Vervagen" CutTransition="Knippen" +SwipeTransition="Swipe" +SlideTransition="Slide" +FadeToColorTransition="Vervagen naar Kleur" +Direction="Richting" +Direction.Left="Links" +Direction.Right="Rechts" +Direction.Up="Omhoog" +Direction.Down="Omlaag" +SwipeIn="Naar binnen vegen" +Color="Kleur" +SwitchPoint="Wisselpunt (percentage)" diff --git a/plugins/obs-transitions/data/locale/pl-PL.ini b/plugins/obs-transitions/data/locale/pl-PL.ini index c33a7bf..794e596 100644 --- a/plugins/obs-transitions/data/locale/pl-PL.ini +++ b/plugins/obs-transitions/data/locale/pl-PL.ini @@ -1,3 +1,14 @@ FadeTransition="Zanikanie" CutTransition="Cięcie" +SwipeTransition="Przesunięcie" +SlideTransition="Slajd" +FadeToColorTransition="Zanikanie do koloru" +Direction="Kierunek" +Direction.Left="W lewo" +Direction.Right="W prawo" +Direction.Up="W górę" +Direction.Down="W dół" +SwipeIn="Przesuwaj do środka" +Color="Kolor" +SwitchPoint="Punkt szczytowy koloru (procent)" diff --git a/plugins/obs-transitions/data/locale/pt-BR.ini b/plugins/obs-transitions/data/locale/pt-BR.ini new file mode 100644 index 0000000..e280221 --- /dev/null +++ b/plugins/obs-transitions/data/locale/pt-BR.ini @@ -0,0 +1,13 @@ +FadeTransition="Esmaecer" +CutTransition="Cortar" +SlideTransition="Deslizar" +FadeToColorTransition="Esmaecer para a Cor" +Direction="Direção" +Direction.Left="Esquerda" +Direction.Right="Direita" +Direction.Up="Cima" +Direction.Down="Baixo" +SwipeIn="Deslizar para" +Color="Cor" +SwitchPoint="Ponto de Pico de Cor (porcentagem)" + diff --git a/plugins/obs-transitions/data/locale/ro-RO.ini b/plugins/obs-transitions/data/locale/ro-RO.ini index 414ae76..7c76c1f 100644 --- a/plugins/obs-transitions/data/locale/ro-RO.ini +++ b/plugins/obs-transitions/data/locale/ro-RO.ini @@ -1,3 +1,14 @@ -FadeTransition="Diminuează" -CutTransition="Taie" +FadeTransition="Estompare" +CutTransition="Tăiere" +SwipeTransition="Glisare" +SlideTransition="Gliseaza" +FadeToColorTransition="Estompare prin culoare" +Direction="Direcție" +Direction.Left="Stânga" +Direction.Right="Dreapta" +Direction.Up="Sus" +Direction.Down="Jos" +SwipeIn="Glisați înauntru" +Color="Culoare" +SwitchPoint="Punctul de vârf al culorii (procent)" diff --git a/plugins/obs-transitions/data/locale/ru-RU.ini b/plugins/obs-transitions/data/locale/ru-RU.ini index a729642..dd8cc00 100644 --- a/plugins/obs-transitions/data/locale/ru-RU.ini +++ b/plugins/obs-transitions/data/locale/ru-RU.ini @@ -1,2 +1,14 @@ FadeTransition="Затухание" +CutTransition="Обрезать" +SwipeTransition="Перемещение" +SlideTransition="Сдвиг" +FadeToColorTransition="Затухание в цвет" +Direction="Направление" +Direction.Left="Влево" +Direction.Right="Вправо" +Direction.Up="Вверх" +Direction.Down="Вниз" +SwipeIn="Перемещение внутрь" +Color="Цвет" +SwitchPoint="Точка цветового пика (в процентах)" diff --git a/plugins/obs-transitions/data/locale/sr-CS.ini b/plugins/obs-transitions/data/locale/sr-CS.ini index 434230a..27a82f3 100644 --- a/plugins/obs-transitions/data/locale/sr-CS.ini +++ b/plugins/obs-transitions/data/locale/sr-CS.ini @@ -1,3 +1,14 @@ FadeTransition="Zatamnjenje" CutTransition="Sečenje" +SwipeTransition="Prevlačenje" +SlideTransition="Klizanje" +FadeToColorTransition="Iščezavanje u boju" +Direction="Pravac" +Direction.Left="Levo" +Direction.Right="Desno" +Direction.Up="Gore" +Direction.Down="Dole" +SwipeIn="Uvlačenje" +Color="Boja" +SwitchPoint="Tačka vrhunca boje (procenat)" diff --git a/plugins/obs-transitions/data/locale/sr-SP.ini b/plugins/obs-transitions/data/locale/sr-SP.ini index 5fd21c3..4a3e284 100644 --- a/plugins/obs-transitions/data/locale/sr-SP.ini +++ b/plugins/obs-transitions/data/locale/sr-SP.ini @@ -1,3 +1,14 @@ FadeTransition="Затамњење" CutTransition="Сечење" +SwipeTransition="Превлачење" +SlideTransition="Клизање" +FadeToColorTransition="Ишчезавање у боју" +Direction="Правац" +Direction.Left="Лево" +Direction.Right="Десно" +Direction.Up="Горе" +Direction.Down="Доле" +SwipeIn="Увлачење" +Color="Боја" +SwitchPoint="Тачка врхунца боје (проценат)" diff --git a/plugins/obs-transitions/data/locale/sv-SE.ini b/plugins/obs-transitions/data/locale/sv-SE.ini new file mode 100644 index 0000000..cdc9d1b --- /dev/null +++ b/plugins/obs-transitions/data/locale/sv-SE.ini @@ -0,0 +1,13 @@ +FadeTransition="Tona" +CutTransition="Klipp" +SwipeTransition="Svep" +SlideTransition="Glid" +FadeToColorTransition="Tona till färg" +Direction="Riktning" +Direction.Left="Vänster" +Direction.Right="Höger" +Direction.Up="Upp" +Direction.Down="Ned" +SwipeIn="Svep in" +Color="Färg" + diff --git a/plugins/obs-transitions/data/locale/tr-TR.ini b/plugins/obs-transitions/data/locale/tr-TR.ini index c95e7dd..77c90e9 100644 --- a/plugins/obs-transitions/data/locale/tr-TR.ini +++ b/plugins/obs-transitions/data/locale/tr-TR.ini @@ -1,3 +1,11 @@ FadeTransition="Soldur" CutTransition="Kes" +SwipeTransition="Kaydır" +SlideTransition="Kaydır" +Direction="Yönlendir" +Direction.Left="Sol" +Direction.Right="Sağ" +Direction.Up="Yukarı" +Direction.Down="Aşağı" +Color="Renk" diff --git a/plugins/obs-transitions/data/locale/zh-CN.ini b/plugins/obs-transitions/data/locale/zh-CN.ini index ad4dd95..8a4c133 100644 --- a/plugins/obs-transitions/data/locale/zh-CN.ini +++ b/plugins/obs-transitions/data/locale/zh-CN.ini @@ -1,3 +1,14 @@ FadeTransition="淡出" CutTransition="剪切" +SwipeTransition="滑动" +SlideTransition="滑动" +FadeToColorTransition="色彩淡入淡出" +Direction="方向" +Direction.Left="左" +Direction.Right="右" +Direction.Up="上" +Direction.Down="下" +SwipeIn="向上滑动" +Color="色彩" +SwitchPoint="峰值颜色点(百分比)" diff --git a/plugins/obs-transitions/data/locale/zh-TW.ini b/plugins/obs-transitions/data/locale/zh-TW.ini new file mode 100644 index 0000000..f9115c3 --- /dev/null +++ b/plugins/obs-transitions/data/locale/zh-TW.ini @@ -0,0 +1,7 @@ +Direction="方向:" +Direction.Left="左" +Direction.Right="右" +Direction.Up="上:" +Direction.Down="下" +Color="顏色" + diff --git a/plugins/obs-transitions/data/slide_transition.effect b/plugins/obs-transitions/data/slide_transition.effect new file mode 100644 index 0000000..91a9b89 --- /dev/null +++ b/plugins/obs-transitions/data/slide_transition.effect @@ -0,0 +1,45 @@ +uniform float4x4 ViewProj; +uniform texture2d tex_a; +uniform texture2d tex_b; +uniform float2 tex_a_dir; +uniform float2 tex_b_dir; + + +sampler_state textureSampler { + Filter = Linear; + AddressU = Clamp; + AddressV = Clamp; +}; + +struct VertData { + float4 pos : POSITION; + float2 uv : TEXCOORD0; +}; + +VertData VSDefault(VertData v_in) +{ + VertData vert_out; + vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj); + vert_out.uv = v_in.uv; + return vert_out; +} + +float4 PSSlide(VertData v_in) : TARGET +{ + float2 tex_a_uv = v_in.uv + tex_a_dir; + float2 tex_b_uv = v_in.uv - tex_b_dir; + + return (tex_a_uv.x - saturate(tex_a_uv.x) != 0.0) || + (tex_a_uv.y - saturate(tex_a_uv.y) != 0.0) + ? tex_b.Sample(textureSampler, tex_b_uv) + : tex_a.Sample(textureSampler, tex_a_uv); +} + +technique Slide +{ + pass + { + vertex_shader = VSDefault(v_in); + pixel_shader = PSSlide(v_in); + } +} diff --git a/plugins/obs-transitions/data/swipe_transition.effect b/plugins/obs-transitions/data/swipe_transition.effect new file mode 100644 index 0000000..699db66 --- /dev/null +++ b/plugins/obs-transitions/data/swipe_transition.effect @@ -0,0 +1,42 @@ +uniform float4x4 ViewProj; +uniform texture2d tex_a; +uniform texture2d tex_b; +uniform float2 swipe_val; + +sampler_state textureSampler { + Filter = Linear; + AddressU = Clamp; + AddressV = Clamp; +}; + +struct VertData { + float4 pos : POSITION; + float2 uv : TEXCOORD0; +}; + +VertData VSDefault(VertData v_in) +{ + VertData vert_out; + vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj); + vert_out.uv = v_in.uv; + return vert_out; +} + +float4 PSSwipe(VertData v_in) : TARGET +{ + float2 swipe_uv = v_in.uv + swipe_val; + + return (swipe_uv.x - saturate(swipe_uv.x) != 0.0) || + (swipe_uv.y - saturate(swipe_uv.y) != 0.0) + ? tex_b.Sample(textureSampler, v_in.uv) + : tex_a.Sample(textureSampler, swipe_uv); +} + +technique Swipe +{ + pass + { + vertex_shader = VSDefault(v_in); + pixel_shader = PSSwipe(v_in); + } +} diff --git a/plugins/obs-transitions/easings.h b/plugins/obs-transitions/easings.h new file mode 100644 index 0000000..23e0203 --- /dev/null +++ b/plugins/obs-transitions/easings.h @@ -0,0 +1,11 @@ +#pragma once + +static inline float cubic_ease_in_out(float t) +{ + if (t < 0.5f) { + return 4.0f * t * t * t; + } else { + float temp = (2.0f * t - 2.0f); + return (t - 1.0f) * temp * temp + 1.0f; + } +} diff --git a/plugins/obs-transitions/obs-transitions.c b/plugins/obs-transitions/obs-transitions.c index 7e15a13..351726c 100644 --- a/plugins/obs-transitions/obs-transitions.c +++ b/plugins/obs-transitions/obs-transitions.c @@ -6,10 +6,16 @@ OBS_MODULE_USE_DEFAULT_LOCALE("obs-transitions", "en-US") extern struct obs_source_info cut_transition; extern struct obs_source_info fade_transition; +extern struct obs_source_info swipe_transition; +extern struct obs_source_info slide_transition; +extern struct obs_source_info fade_to_color_transition; bool obs_module_load(void) { obs_register_source(&cut_transition); obs_register_source(&fade_transition); + obs_register_source(&swipe_transition); + obs_register_source(&slide_transition); + obs_register_source(&fade_to_color_transition); return true; } diff --git a/plugins/obs-transitions/transition-fade-to-color.c b/plugins/obs-transitions/transition-fade-to-color.c new file mode 100644 index 0000000..65e78d3 --- /dev/null +++ b/plugins/obs-transitions/transition-fade-to-color.c @@ -0,0 +1,178 @@ +#include + +#define S_COLOR "color" +#define S_SWITCH_POINT "switch_point" + +#define S_COLOR_TEXT obs_module_text("Color") +#define S_SWITCH_POINT_TEXT obs_module_text("SwitchPoint") + +struct fade_to_color_info { + obs_source_t *source; + + gs_effect_t *effect; + gs_eparam_t *ep_tex; + gs_eparam_t *ep_swp; + gs_eparam_t *ep_color; + + struct vec4 color; + float switch_point; +}; + +static inline float lerp(float a, float b, float x) +{ + return (1.0f - x) * a + x * b; +} + +static inline float clamp(float x, float min, float max) +{ + if (x < min) + return min; + else if (x > max) + return max; + return x; +} + +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); +} + +static const char *fade_to_color_get_name(void *type_data) +{ + UNUSED_PARAMETER(type_data); + return obs_module_text("FadeToColorTransition"); +} + +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); + + color |= 0xFF000000; + + vec4_from_rgba(&fade_to_color->color, color); + + fade_to_color->switch_point = (float)swp / 100.0f; +} + +static void *fade_to_color_create(obs_data_t *settings, obs_source_t *source) +{ + struct fade_to_color_info *fade_to_color; + char *file = obs_module_file("fade_to_color_transition.effect"); + gs_effect_t *effect; + + obs_enter_graphics(); + effect = gs_effect_create_from_file(file, NULL); + obs_leave_graphics(); + + bfree(file); + + if (!effect) { + blog(LOG_ERROR, "Could not find fade_to_color_transition.effect"); + return NULL; + } + + fade_to_color = bzalloc(sizeof(struct fade_to_color_info)); + + 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_color = gs_effect_get_param_by_name(effect, "color"); + + obs_source_update(source, settings); + + return fade_to_color; +} + +static void fade_to_color_destroy(void *data) +{ + struct fade_to_color_info *fade_to_color = data; + bfree(fade_to_color); +} + +static void fade_to_color_callback(void *data, gs_texture_t *a, gs_texture_t *b, + float t, uint32_t cx, uint32_t cy) +{ + struct fade_to_color_info *fade_to_color = data; + + float sa = smoothstep(0.0f, fade_to_color->switch_point, t); + float sb = smoothstep(fade_to_color->switch_point, 1.0f, t); + + float swp = t < fade_to_color->switch_point ? sa : 1.0f - sb; + + gs_effect_set_texture(fade_to_color->ep_tex, + t < fade_to_color->switch_point ? a : b); + gs_effect_set_float(fade_to_color->ep_swp, swp); + gs_effect_set_vec4(fade_to_color->ep_color, &fade_to_color->color); + + while (gs_effect_loop(fade_to_color->effect, "FadeToColor")) + gs_draw_sprite(NULL, 0, cx, cy); +} + +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); + UNUSED_PARAMETER(effect); +} + +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)); +} + +static float mix_b(void *data, float t) +{ + struct fade_to_color_info *fade_to_color = data; + float sp = fade_to_color->switch_point; + + return lerp(0.0f, t, smoothstep(sp, 1.0f, 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 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); +} + +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); + + UNUSED_PARAMETER(data); + return props; +} + +static void fade_to_color_defaults(obs_data_t *settings) +{ + obs_data_set_default_int(settings, S_COLOR, 0xFF000000); + obs_data_set_default_int(settings, S_SWITCH_POINT, 50); +} + +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, + .get_properties = fade_to_color_properties, + .get_defaults = fade_to_color_defaults +}; diff --git a/plugins/obs-transitions/transition-slide.c b/plugins/obs-transitions/transition-slide.c new file mode 100644 index 0000000..d381477 --- /dev/null +++ b/plugins/obs-transitions/transition-slide.c @@ -0,0 +1,165 @@ +#include +#include +#include "easings.h" + +#define S_DIRECTION "direction" + +struct slide_info { + obs_source_t *source; + + gs_effect_t *effect; + gs_eparam_t *a_param; + gs_eparam_t *b_param; + gs_eparam_t *tex_a_dir_param; + gs_eparam_t *tex_b_dir_param; + + struct vec2 dir; + bool slide_in; +}; + +static const char *slide_get_name(void *type_data) +{ + UNUSED_PARAMETER(type_data); + return obs_module_text("SlideTransition"); +} + +static void slide_update(void *data, obs_data_t *settings) +{ + struct slide_info *slide = data; + const char *dir = obs_data_get_string(settings, S_DIRECTION); + + if (strcmp(dir, "right") == 0) + slide->dir = (struct vec2){ -1.0f, 0.0f }; + else if (strcmp(dir, "up") == 0) + slide->dir = (struct vec2){ 0.0f, 1.0f }; + else if (strcmp(dir, "down") == 0) + slide->dir = (struct vec2){ 0.0f, -1.0f }; + else /* left */ + slide->dir = (struct vec2){ 1.0f, 0.0f }; +} + +void *slide_create(obs_data_t *settings, obs_source_t *source) +{ + struct slide_info *slide; + gs_effect_t *effect; + + char *file = obs_module_file("slide_transition.effect"); + + obs_enter_graphics(); + effect = gs_effect_create_from_file(file, NULL); + obs_leave_graphics(); + + bfree(file); + + if (!effect) { + blog(LOG_ERROR, "Could not find slide_transition.effect"); + return NULL; + } + + slide = bzalloc(sizeof(*slide)); + + slide->source = source; + slide->effect = effect; + + slide->a_param = gs_effect_get_param_by_name(effect, "tex_a"); + slide->b_param = gs_effect_get_param_by_name(effect, "tex_b"); + + slide->tex_a_dir_param = + gs_effect_get_param_by_name(effect, "tex_a_dir"); + slide->tex_b_dir_param = + gs_effect_get_param_by_name(effect, "tex_b_dir"); + + obs_source_update(source, settings); + + return slide; +} + +void slide_destroy(void *data) +{ + struct slide_info *slide = data; + bfree(slide); +} + +static void slide_callback(void *data, gs_texture_t *a, gs_texture_t *b, + float t, uint32_t cx, uint32_t cy) +{ + struct slide_info *slide = data; + + struct vec2 tex_a_dir = slide->dir; + struct vec2 tex_b_dir = slide->dir; + + t = cubic_ease_in_out(t); + + vec2_mulf(&tex_a_dir, &tex_a_dir, t); + vec2_mulf(&tex_b_dir, &tex_b_dir, 1.0f - t); + + gs_effect_set_texture(slide->a_param, a); + gs_effect_set_texture(slide->b_param, b); + + gs_effect_set_vec2(slide->tex_a_dir_param, &tex_a_dir); + gs_effect_set_vec2(slide->tex_b_dir_param, &tex_b_dir); + + while (gs_effect_loop(slide->effect, "Slide")) + gs_draw_sprite(NULL, 0, cx, cy); +} + +void slide_video_render(void *data, gs_effect_t *effect) +{ + struct slide_info *slide = data; + obs_transition_video_render(slide->source, slide_callback); + UNUSED_PARAMETER(effect); +} + +static float mix_a(void *data, float t) +{ + UNUSED_PARAMETER(data); + return 1.0f - cubic_ease_in_out(t); +} + +static float mix_b(void *data, float t) +{ + UNUSED_PARAMETER(data); + return cubic_ease_in_out(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 slide_info *slide = data; + 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) +{ + obs_properties_t *ppts = obs_properties_create(); + 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_property_list_add_string(p, obs_module_text("Direction.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"); + obs_property_list_add_string(p, obs_module_text("Direction.Down"), + "down"); + + UNUSED_PARAMETER(data); + return ppts; +} + +struct obs_source_info slide_transition = { + .id = "slide_transition", + .type = OBS_SOURCE_TYPE_TRANSITION, + .get_name = slide_get_name, + .create = slide_create, + .destroy = slide_destroy, + .update = slide_update, + .video_render = slide_video_render, + .audio_render = slide_audio_render, + .get_properties = slide_properties +}; diff --git a/plugins/obs-transitions/transition-swipe.c b/plugins/obs-transitions/transition-swipe.c new file mode 100644 index 0000000..3bb5ce0 --- /dev/null +++ b/plugins/obs-transitions/transition-swipe.c @@ -0,0 +1,160 @@ +#include +#include +#include "easings.h" + +struct swipe_info { + obs_source_t *source; + + gs_effect_t *effect; + gs_eparam_t *a_param; + gs_eparam_t *b_param; + gs_eparam_t *swipe_param; + + struct vec2 dir; + bool swipe_in; +}; + +#define S_DIRECTION "direction" +#define S_SWIPE_IN "swipe_in" + +static const char *swipe_get_name(void *type_data) +{ + UNUSED_PARAMETER(type_data); + return obs_module_text("SwipeTransition"); +} + +static void *swipe_create(obs_data_t *settings, obs_source_t *source) +{ + struct swipe_info *swipe; + char *file = obs_module_file("swipe_transition.effect"); + gs_effect_t *effect; + + obs_enter_graphics(); + effect = gs_effect_create_from_file(file, NULL); + obs_leave_graphics(); + bfree(file); + + if (!effect) { + blog(LOG_ERROR, "Could not find swipe_transition.effect"); + return NULL; + } + + swipe = bmalloc(sizeof(*swipe)); + swipe->source = source; + swipe->effect = effect; + swipe->a_param = gs_effect_get_param_by_name(effect, "tex_a"); + swipe->b_param = gs_effect_get_param_by_name(effect, "tex_b"); + swipe->swipe_param = gs_effect_get_param_by_name(effect, "swipe_val"); + + obs_source_update(source, settings); + + UNUSED_PARAMETER(settings); + return swipe; +} + +static void swipe_destroy(void *data) +{ + struct swipe_info *swipe = data; + bfree(swipe); +} + +static void swipe_update(void *data, obs_data_t *settings) +{ + struct swipe_info *swipe = data; + const char *dir = obs_data_get_string(settings, S_DIRECTION); + + swipe->swipe_in = obs_data_get_bool(settings, S_SWIPE_IN); + + if (strcmp(dir, "right") == 0) + swipe->dir = (struct vec2){-1.0f, 0.0f}; + else if (strcmp(dir, "up") == 0) + swipe->dir = (struct vec2){0.0f, 1.0f}; + else if (strcmp(dir, "down") == 0) + swipe->dir = (struct vec2){0.0f, -1.0f}; + else /* left */ + swipe->dir = (struct vec2){1.0f, 0.0f}; +} + +static void swipe_callback(void *data, gs_texture_t *a, gs_texture_t *b, + float t, uint32_t cx, uint32_t cy) +{ + struct swipe_info *swipe = data; + struct vec2 swipe_val = swipe->dir; + + if (swipe->swipe_in) + vec2_neg(&swipe_val, &swipe_val); + + t = cubic_ease_in_out(t); + + vec2_mulf(&swipe_val, &swipe_val, swipe->swipe_in ? 1.0f - t : t); + + gs_effect_set_texture(swipe->a_param, swipe->swipe_in ? b : a); + gs_effect_set_texture(swipe->b_param, swipe->swipe_in ? a : b); + gs_effect_set_vec2(swipe->swipe_param, &swipe_val); + + while (gs_effect_loop(swipe->effect, "Swipe")) + gs_draw_sprite(NULL, 0, cx, cy); +} + +static void swipe_video_render(void *data, gs_effect_t *effect) +{ + struct swipe_info *swipe = data; + obs_transition_video_render(swipe->source, swipe_callback); + UNUSED_PARAMETER(effect); +} + +static float mix_a(void *data, float t) +{ + UNUSED_PARAMETER(data); + return 1.0f - cubic_ease_in_out(t); +} + +static float mix_b(void *data, float t) +{ + UNUSED_PARAMETER(data); + return cubic_ease_in_out(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 swipe_info *swipe = data; + 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) +{ + obs_properties_t *ppts = obs_properties_create(); + 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_property_list_add_string(p, obs_module_text("Direction.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"); + obs_property_list_add_string(p, obs_module_text("Direction.Down"), + "down"); + + obs_properties_add_bool(ppts, S_SWIPE_IN, obs_module_text("SwipeIn")); + + UNUSED_PARAMETER(data); + return ppts; +} + +struct obs_source_info swipe_transition = { + .id = "swipe_transition", + .type = OBS_SOURCE_TYPE_TRANSITION, + .get_name = swipe_get_name, + .create = swipe_create, + .destroy = swipe_destroy, + .update = swipe_update, + .video_render = swipe_video_render, + .audio_render = swipe_audio_render, + .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 cba1261..188671d 100644 --- a/plugins/obs-x264/data/locale/ar-SA.ini +++ b/plugins/obs-x264/data/locale/ar-SA.ini @@ -1,6 +1,11 @@ Bitrate="معدل النقل" +CustomBufsize="استخدام حجم Buffer مخصص" BufferSize="حجم المخزن المؤقت" KeyframeIntervalSec="الفاصل الزمني لـKeyframe (ثانية, 0=تلقائي)" +CPUPreset="إعداد مسبق لاستخدام CPU (الأعلى = CPU أقل)" Profile="الملف الشخصي" Tune="لحن" +None="(بلا)" +EncoderOptions="خيارات x264 (مفصولة بمسافة)" +VFR="معدل إطارات متغيّر (VFR)" diff --git a/plugins/obs-x264/data/locale/ca-ES.ini b/plugins/obs-x264/data/locale/ca-ES.ini index a9c93df..40e0d69 100644 --- a/plugins/obs-x264/data/locale/ca-ES.ini +++ b/plugins/obs-x264/data/locale/ca-ES.ini @@ -1,7 +1,7 @@ Bitrate="Taxa de bits" CustomBufsize="Utilitza una mida de memòria intermèdia personalitzada" BufferSize="Mida de la memòria intermèdia" -UseCBR="Usa CBR" +RateControl="Control de freqüència" CRF="CRF" KeyframeIntervalSec="Interval de fotograma clau (en segons, 0 = automàtic)" CPUPreset="Preconfiguració d'ús de la CPU (més alt = menys CPU)" diff --git a/plugins/obs-x264/data/locale/cs-CZ.ini b/plugins/obs-x264/data/locale/cs-CZ.ini index 287015a..d6c511d 100644 --- a/plugins/obs-x264/data/locale/cs-CZ.ini +++ b/plugins/obs-x264/data/locale/cs-CZ.ini @@ -1,7 +1,7 @@ Bitrate="Bitrate" CustomBufsize="Použít vlastní velikost vyrovnávací paměti" BufferSize="Velikost vyrovnávací paměti" -UseCBR="Použít CBR" +RateControl="Řízení toku" CRF="CRF" KeyframeIntervalSec="Interval klíčových snímků (vteřiny, 0=auto)" CPUPreset="Předvolba využití CPU (vyšší = méně CPU)" diff --git a/plugins/obs-x264/data/locale/da-DK.ini b/plugins/obs-x264/data/locale/da-DK.ini index 354702e..9e3bd79 100644 --- a/plugins/obs-x264/data/locale/da-DK.ini +++ b/plugins/obs-x264/data/locale/da-DK.ini @@ -1,11 +1,12 @@ Bitrate="Bitrate" CustomBufsize="Brug brugerdefineret bufferstørrelse" BufferSize="Bufferstørrelsen" -UseCBR="Brug CBR" CRF="CRF" -KeyframeIntervalSec="Keyframe Interval (sekunder, 0 = auto)" +KeyframeIntervalSec="Keyframe interval (sekunder, 0 = auto)" +CPUPreset="CPU forbrug indstilling (højere = mindre CPU)" Profile="Profil" Tune="Stil ind" None="(Ingen)" EncoderOptions="x264 indstillinger (adskilt af mellemrum)" +VFR="Variable framerate (VFR)" diff --git a/plugins/obs-x264/data/locale/de-DE.ini b/plugins/obs-x264/data/locale/de-DE.ini index babef42..15adf9e 100644 --- a/plugins/obs-x264/data/locale/de-DE.ini +++ b/plugins/obs-x264/data/locale/de-DE.ini @@ -1,7 +1,7 @@ Bitrate="Bitrate" CustomBufsize="Verwende benutzerdefinierte Puffergröße" BufferSize="Puffergröße" -UseCBR="Benutze CBR" +RateControl="Qualitäts Regulierungsmethode" CRF="CRF" KeyframeIntervalSec="Keyframeintervall (Sekunden, 0=auto)" CPUPreset="Prozessorauslastung-Voreinstellung (höher = weniger CPU Auslastung)" diff --git a/plugins/obs-x264/data/locale/el-GR.ini b/plugins/obs-x264/data/locale/el-GR.ini index 4348d49..9da15c7 100644 --- a/plugins/obs-x264/data/locale/el-GR.ini +++ b/plugins/obs-x264/data/locale/el-GR.ini @@ -1,7 +1,6 @@ Bitrate="Ρυθμός μετάδοσης bit" CustomBufsize="Χρήση Προσαρμοσμένου Μεγέθους Buffer" BufferSize="Μέγεθος buffer" -UseCBR="Χρήση CBR" CRF="CRF" KeyframeIntervalSec="Συχνότητα Καρέ-Κλειδιού (δευτερόλεπτα, 0=αυτόματο)" CPUPreset="Προφίλ Χρήσης CPU (υψηλότερο = λιγότερη CPU)" @@ -9,4 +8,5 @@ Profile="Προφίλ" Tune="Βελτιστοποίηση" None="(Κανένα)" EncoderOptions="Επιλογές x264 (διαχωρισμένες από κενό)" +VFR="Μεταβλητή ταχύτητα καρέ (VFR)" diff --git a/plugins/obs-x264/data/locale/en-US.ini b/plugins/obs-x264/data/locale/en-US.ini index 8b0eff9..fa11b99 100644 --- a/plugins/obs-x264/data/locale/en-US.ini +++ b/plugins/obs-x264/data/locale/en-US.ini @@ -1,7 +1,7 @@ Bitrate="Bitrate" CustomBufsize="Use Custom Buffer Size" BufferSize="Buffer Size" -UseCBR="Use CBR" +RateControl="Rate Control" CRF="CRF" KeyframeIntervalSec="Keyframe Interval (seconds, 0=auto)" CPUPreset="CPU Usage Preset (higher = less CPU)" diff --git a/plugins/obs-x264/data/locale/es-ES.ini b/plugins/obs-x264/data/locale/es-ES.ini index e934903..e424b83 100644 --- a/plugins/obs-x264/data/locale/es-ES.ini +++ b/plugins/obs-x264/data/locale/es-ES.ini @@ -1,7 +1,7 @@ Bitrate="Tasa de bits" CustomBufsize="Usar tamaño de caché personalizado" BufferSize="Tamaño de la memoria intermedia" -UseCBR="Usar CBR" +RateControl="Control de la frecuencia" CRF="CRF" KeyframeIntervalSec="Intervalo de fotogramas clave (segundos, 0 = auto)" CPUPreset="Perfíl de uso de CPU (superior = menos CPU)" diff --git a/plugins/obs-x264/data/locale/eu-ES.ini b/plugins/obs-x264/data/locale/eu-ES.ini index d15d54a..359bd51 100644 --- a/plugins/obs-x264/data/locale/eu-ES.ini +++ b/plugins/obs-x264/data/locale/eu-ES.ini @@ -1,13 +1,13 @@ -Bitrate="Bitneurria" -CustomBufsize="Erabili Norbere Buffer Neurria" -BufferSize="Buffer Neurria" -UseCBR="Erabili BNG" -CRF="CRF" -KeyframeIntervalSec="Giltzaframe Tartea (segundu, 0=berez)" -CPUPreset="CPU Erabilpen Aurrezarpena (handiagoa = CPU gutxiago)" +Bitrate="Bit-tasa" +CustomBufsize="Erabili buffer tamaina pertsonalizatua" +BufferSize="Buffer tamaina" +RateControl="Tasaren kontrola" +CRF="Tasa-faktore konstantea" +KeyframeIntervalSec="Gako-fotograma tartea (segundo, 0=auto)" +CPUPreset="PUZ erabilera aurrezarrita (handiagoa = PUZ gutxiago)" Profile="Profila" Tune="Sintonizatu" None="(Bat ere ez)" -EncoderOptions="x264 Aukerak (tarte batez bananduta)" -VFR="Frameneurri Aldakorra (VFR)" +EncoderOptions="x264 aukerak (tarte batez bananduta)" +VFR="Fotograma-tasa aldakorra (VFR)" diff --git a/plugins/obs-x264/data/locale/fi-FI.ini b/plugins/obs-x264/data/locale/fi-FI.ini index 6d088c5..af3aa38 100644 --- a/plugins/obs-x264/data/locale/fi-FI.ini +++ b/plugins/obs-x264/data/locale/fi-FI.ini @@ -1,7 +1,7 @@ Bitrate="Bitrate" CustomBufsize="Käytä valinnaista puskurin kokoa" BufferSize="Puskurin koko" -UseCBR="Käytä CBR" +RateControl="Nopeudensäädin" CRF="CRF" KeyframeIntervalSec="Keyframe-väli (sec, 0=auto)" CPUPreset="CPU:n käyttö (korkeampi vaatii enemmän tehoa)" diff --git a/plugins/obs-x264/data/locale/fr-FR.ini b/plugins/obs-x264/data/locale/fr-FR.ini index 8f255d9..949d7cb 100644 --- a/plugins/obs-x264/data/locale/fr-FR.ini +++ b/plugins/obs-x264/data/locale/fr-FR.ini @@ -1,7 +1,7 @@ Bitrate="Débit" CustomBufsize="Utiliser une taille de buffer personnalisée" -BufferSize="Taille du Tampon" -UseCBR="Utiliser CBR" +BufferSize="Taille du tampon" +RateControl="Contrôle du débit" CRF="CRF" KeyframeIntervalSec="Intervalle d'image-clé (en secondes, 0 = auto)" CPUPreset="Réglages prédéfinis du CPU (élevé = charge CPU faible)" diff --git a/plugins/obs-x264/data/locale/gl-ES.ini b/plugins/obs-x264/data/locale/gl-ES.ini index 1d85d07..9b61f5d 100644 --- a/plugins/obs-x264/data/locale/gl-ES.ini +++ b/plugins/obs-x264/data/locale/gl-ES.ini @@ -1,7 +1,6 @@ Bitrate="Velocidade de bits" CustomBufsize="Utilizar tamaño da caché personalizado" BufferSize="Tamaño do búfer" -UseCBR="Utilizar CBR" CRF="CRF" KeyframeIntervalSec="Intervalo de fotogramas chave (segundos, 0 = auto)" CPUPreset="Uso predefinido da CPU (superior = menos CPU)" @@ -9,4 +8,5 @@ Profile="Perfil" Tune="Sintonizar" None="(Ningún)" EncoderOptions="Opcións x264 (separadas por un espazo)" +VFR="Velocidade de fotogramas variable (VFR)" diff --git a/plugins/obs-x264/data/locale/he-IL.ini b/plugins/obs-x264/data/locale/he-IL.ini new file mode 100644 index 0000000..2962f17 --- /dev/null +++ b/plugins/obs-x264/data/locale/he-IL.ini @@ -0,0 +1,12 @@ +Bitrate="קצב ביטים" +CustomBufsize="השתמש בגודל אוגר מותאם אישית" +BufferSize="גודל אוגר" +CRF="קבוע פקטור קצב (CRF)" +KeyframeIntervalSec="מרווח ערך ה keyframe בשניות (0=אוטומטי)" +CPUPreset="ערך שימוש במעבד (גבוה יותר = פחות מעבד)" +Profile="פרופיל" +Tune="כיוון" +None="(ללא)" +EncoderOptions="אפשרויות x264 (מופרדות באמצעות רווח)" +VFR="קצב פריימים משתנה (VFR)" + diff --git a/plugins/obs-x264/data/locale/hr-HR.ini b/plugins/obs-x264/data/locale/hr-HR.ini index df0be42..df9f4ac 100644 --- a/plugins/obs-x264/data/locale/hr-HR.ini +++ b/plugins/obs-x264/data/locale/hr-HR.ini @@ -1,7 +1,6 @@ Bitrate="Protok" CustomBufsize="Koristi specifičnu veličinu bafera" BufferSize="Veličina buffer-a" -UseCBR="Koristi CBR" CRF="CRF" KeyframeIntervalSec="Keyframe interval (sekunde, 0=automatski)" CPUPreset="Koristi CPU šablon (veće = manje CPU-a)" diff --git a/plugins/obs-x264/data/locale/hu-HU.ini b/plugins/obs-x264/data/locale/hu-HU.ini index 727aa57..ccff1e3 100644 --- a/plugins/obs-x264/data/locale/hu-HU.ini +++ b/plugins/obs-x264/data/locale/hu-HU.ini @@ -1,13 +1,13 @@ Bitrate="Bitráta" CustomBufsize="Egyéni pufferméret használata" -BufferSize="Bufferméret" -UseCBR="CBR Használata" +BufferSize="Pufferméret" +RateControl="Sebesség Vezérlés" CRF="CRF" -KeyframeIntervalSec="Kulcsképkocka Időköze (másodperc, 0=auto)" -CPUPreset="CPU Készlet (magasabb = kevesebb CPU igény)" +KeyframeIntervalSec="Kulcsképkocka időköze (másodperc, 0=auto)" +CPUPreset="CPU készlet (magasabb = kevesebb CPU igény)" Profile="Profil" Tune="Hangolás" None="(Nincs)" EncoderOptions="x264 Opciók (szóközzel elválasztva)" -VFR="Változó Képkockasebesség (VFR)" +VFR="Változó képkockasebesség (VFR)" diff --git a/plugins/obs-x264/data/locale/it-IT.ini b/plugins/obs-x264/data/locale/it-IT.ini index 0861aa0..3abe79a 100644 --- a/plugins/obs-x264/data/locale/it-IT.ini +++ b/plugins/obs-x264/data/locale/it-IT.ini @@ -1,7 +1,6 @@ Bitrate="Bitrate" CustomBufsize="Usa dimensione personalizzata del buffer" BufferSize="Grandezza buffer" -UseCBR="Usa CBR" CRF="CRF" KeyframeIntervalSec="Intervallo keyframe (secondi, 0=auto)" CPUPreset="Preset di utilizzo della CPU (superiore = meno CPU)" diff --git a/plugins/obs-x264/data/locale/ja-JP.ini b/plugins/obs-x264/data/locale/ja-JP.ini index 7eefacd..d824191 100644 --- a/plugins/obs-x264/data/locale/ja-JP.ini +++ b/plugins/obs-x264/data/locale/ja-JP.ini @@ -1,7 +1,7 @@ Bitrate="ビットレート" CustomBufsize="特定バッファサイズを使用" BufferSize="バッファサイズ" -UseCBR="CBRを使用する" +RateControl="レート制御" CRF="CRF" KeyframeIntervalSec="キーフレーム間隔 (秒, 0=自動)" CPUPreset="CPU使用のプリセット (高い = CPU使用低い)" @@ -9,5 +9,5 @@ Profile="プロファイル" Tune="チューン" None="(なし)" EncoderOptions="x264 オプション (スペースで区切る)" -VFR="可変フレームレート(VFR)" +VFR="可変フレームレート (VFR)" diff --git a/plugins/obs-x264/data/locale/ko-KR.ini b/plugins/obs-x264/data/locale/ko-KR.ini index f4b5a95..88a0b03 100644 --- a/plugins/obs-x264/data/locale/ko-KR.ini +++ b/plugins/obs-x264/data/locale/ko-KR.ini @@ -1,7 +1,7 @@ Bitrate="비트레이트" CustomBufsize="사용자 임의 버퍼 크기 설정" BufferSize="버퍼 크기" -UseCBR="CBR 사용" +RateControl="데이터율 제어" CRF="CRF" KeyframeIntervalSec="키프레임 간격 (초 단위, 0=자동)" CPUPreset="CPU 사용량 사전설정 (높음 = 적은 CPU 부담)" diff --git a/plugins/obs-x264/data/locale/nb-NO.ini b/plugins/obs-x264/data/locale/nb-NO.ini index 39690d5..42b36f0 100644 --- a/plugins/obs-x264/data/locale/nb-NO.ini +++ b/plugins/obs-x264/data/locale/nb-NO.ini @@ -1,7 +1,6 @@ Bitrate="Bitrate" CustomBufsize="Bruk egendefinert bufferstørrelse" BufferSize="Buffer størrelse" -UseCBR="Bruk CBR" CRF="CRF" KeyframeIntervalSec="Nøkkelbildeintervall (sekunder, 0 = automatisk)" CPUPreset="Forhåndsinstilling for prosessorbruk (raskere betyr mindre belastning)" diff --git a/plugins/obs-x264/data/locale/nl-NL.ini b/plugins/obs-x264/data/locale/nl-NL.ini index 1d7e633..00ec850 100644 --- a/plugins/obs-x264/data/locale/nl-NL.ini +++ b/plugins/obs-x264/data/locale/nl-NL.ini @@ -1,7 +1,7 @@ Bitrate="Bitrate" CustomBufsize="Aangepaste buffergrootte gebruiken" BufferSize="Buffergrootte" -UseCBR="CBR Gebruiken" +RateControl="Rate Control" CRF="CRF" KeyframeIntervalSec="Tijd tussen keyframes (seconden, 0=auto)" CPUPreset="CPU-gebruik instelling (hoger = minder CPU)" diff --git a/plugins/obs-x264/data/locale/pl-PL.ini b/plugins/obs-x264/data/locale/pl-PL.ini index ee8a31b..c26d199 100644 --- a/plugins/obs-x264/data/locale/pl-PL.ini +++ b/plugins/obs-x264/data/locale/pl-PL.ini @@ -1,7 +1,6 @@ Bitrate="Przepływność bitowa" CustomBufsize="Użyj własnego rozmiaru bufora" BufferSize="Rozmiar bufora" -UseCBR="Użyj CBR (stały bitrate)" CRF="CRF" KeyframeIntervalSec="Interwał klatek kluczowych (sekundy, 0 - auto)" CPUPreset="Ustawienie obciążenia CPU (wyższe = mniej CPU)" diff --git a/plugins/obs-x264/data/locale/pt-BR.ini b/plugins/obs-x264/data/locale/pt-BR.ini index 2300868..910c81d 100644 --- a/plugins/obs-x264/data/locale/pt-BR.ini +++ b/plugins/obs-x264/data/locale/pt-BR.ini @@ -1,7 +1,6 @@ Bitrate="Taxa de Bits" CustomBufsize="Utilizar tamanho do buffer personalizado" BufferSize="Tamanho do Buffer" -UseCBR="Utilizar CBR" CRF="CRF" KeyframeIntervalSec="Intervalo de Keyframe (segundos, 0 = auto)" CPUPreset="Predefinição de utilização do processador (maior = menos processamento)" diff --git a/plugins/obs-x264/data/locale/pt-PT.ini b/plugins/obs-x264/data/locale/pt-PT.ini index c6ad915..d0f9140 100644 --- a/plugins/obs-x264/data/locale/pt-PT.ini +++ b/plugins/obs-x264/data/locale/pt-PT.ini @@ -1,9 +1,8 @@ -Bitrate="Taxa de Bits (Bitrate)" +Bitrate="Bitrate" CustomBufsize="Utilizar tamanho do buffer personalizado" -BufferSize="Tamanho do Buffer" -UseCBR="Utilizar CBR" +BufferSize="Tamanho do buffer" CRF="CRF" -KeyframeIntervalSec="Intervalo de Keyframe (segundos, 0 = auto)" +KeyframeIntervalSec="Intervalo do keyframe (segundos, 0=automático)" CPUPreset="Predefinição de utilização do processador (maior = menos processamento)" Profile="Perfil" Tune="Sintonizar" diff --git a/plugins/obs-x264/data/locale/ro-RO.ini b/plugins/obs-x264/data/locale/ro-RO.ini index ae31974..b308056 100644 --- a/plugins/obs-x264/data/locale/ro-RO.ini +++ b/plugins/obs-x264/data/locale/ro-RO.ini @@ -1,13 +1,12 @@ -Bitrate="Rata biti" -CustomBufsize="Utilizați o Mărime de Buffer Personalizată" -BufferSize="Dimensiune tampon" -UseCBR="Folosește CBR" +Bitrate="Rată de biți" +CustomBufsize="Folosește dimensiune personalizată pentru buffer" +BufferSize="Dimensiune pentru buffer" CRF="CRF" -KeyframeIntervalSec="Intervalul de cadre (secunde, 0 = auto)" -CPUPreset="Preset utilizare CPU (mai mare = mai puţin CPU)" +KeyframeIntervalSec="Interval de cadre cheie (secunde, 0=auto)" +CPUPreset="Presetare pentru utilizare CPU (mai mare = mai puțin CPU)" Profile="Profil" Tune="Reglaj" -None="(Nici unul)" +None="(Niciunul)" EncoderOptions="Opţiuni x264 (separate prin spațiu)" -VFR="Framerate Variabil (VFR)" +VFR="Frecvență de cadre variabilă (VFR)" diff --git a/plugins/obs-x264/data/locale/ru-RU.ini b/plugins/obs-x264/data/locale/ru-RU.ini index b8a0ec0..da34d75 100644 --- a/plugins/obs-x264/data/locale/ru-RU.ini +++ b/plugins/obs-x264/data/locale/ru-RU.ini @@ -1,7 +1,7 @@ Bitrate="Битрейт" CustomBufsize="Использовать пользовательский размер буфера" BufferSize="Размер буфера" -UseCBR="Использовать CBR" +RateControl="Управление битрейтом" CRF="CRF" KeyframeIntervalSec="Интервал ключевых кадров (сек, 0=авто)" CPUPreset="Предустановка использования ЦП (выше = меньше)" diff --git a/plugins/obs-x264/data/locale/sk-SK.ini b/plugins/obs-x264/data/locale/sk-SK.ini index 4ee4e38..fb2e74c 100644 --- a/plugins/obs-x264/data/locale/sk-SK.ini +++ b/plugins/obs-x264/data/locale/sk-SK.ini @@ -1,7 +1,6 @@ Bitrate="Bitrate" CustomBufsize="Použiť vlastnú veľkosť medzipamäte" BufferSize="Veľkosť medzipamäte" -UseCBR="Použiť CRB" CRF="CRF" KeyframeIntervalSec="Kľúčová snímka každých (sekúnd, 0 = automaticky)" Profile="Profil" diff --git a/plugins/obs-x264/data/locale/sr-CS.ini b/plugins/obs-x264/data/locale/sr-CS.ini index df0be42..df9f4ac 100644 --- a/plugins/obs-x264/data/locale/sr-CS.ini +++ b/plugins/obs-x264/data/locale/sr-CS.ini @@ -1,7 +1,6 @@ Bitrate="Protok" CustomBufsize="Koristi specifičnu veličinu bafera" BufferSize="Veličina buffer-a" -UseCBR="Koristi CBR" CRF="CRF" KeyframeIntervalSec="Keyframe interval (sekunde, 0=automatski)" CPUPreset="Koristi CPU šablon (veće = manje CPU-a)" diff --git a/plugins/obs-x264/data/locale/sr-SP.ini b/plugins/obs-x264/data/locale/sr-SP.ini index 630b784..1ad6370 100644 --- a/plugins/obs-x264/data/locale/sr-SP.ini +++ b/plugins/obs-x264/data/locale/sr-SP.ini @@ -1,7 +1,6 @@ Bitrate="Проток" CustomBufsize="Користи специфичну величину бафера" BufferSize="Величина buffer-а" -UseCBR="Користи CBR" CRF="CRF" KeyframeIntervalSec="Keyframe интервал (секунде, 0=аутоматски)" CPUPreset="Користи CPU шаблон (веће = мање CPU-а)" diff --git a/plugins/obs-x264/data/locale/sv-SE.ini b/plugins/obs-x264/data/locale/sv-SE.ini index 19eaa02..4550f89 100644 --- a/plugins/obs-x264/data/locale/sv-SE.ini +++ b/plugins/obs-x264/data/locale/sv-SE.ini @@ -1,7 +1,6 @@ Bitrate="Bithastighet" CustomBufsize="Använd anpassad buffertstorlek" BufferSize="Buffertstorlek" -UseCBR="Använd CBR" CRF="CRF" KeyframeIntervalSec="Keyframe-tidsintervall (i sek, 0=auto)" CPUPreset="CPU-användning förinställning (högre = mindre CPU)" @@ -9,4 +8,5 @@ Profile="Profil" Tune="Tune" None="(Inga)" EncoderOptions="x264 inställningar (separerade med blanksteg)" +VFR="Varierande bildfrekvens (VFR)" diff --git a/plugins/obs-x264/data/locale/tr-TR.ini b/plugins/obs-x264/data/locale/tr-TR.ini index aa79162..67a52e7 100644 --- a/plugins/obs-x264/data/locale/tr-TR.ini +++ b/plugins/obs-x264/data/locale/tr-TR.ini @@ -1,7 +1,6 @@ Bitrate="Bit hızı" CustomBufsize="İsteğe Bağlı Arabellek Boyutu Kullan" BufferSize="Arabellek Boyutu" -UseCBR="CBR kullan" CRF="CRF" KeyframeIntervalSec="Anahtarkare Aralığı (saniye, 0=otomatik)" CPUPreset="CPU Kullanım Önayarı (yüksek = az CPU kullanımı)" diff --git a/plugins/obs-x264/data/locale/zh-CN.ini b/plugins/obs-x264/data/locale/zh-CN.ini index 6056b6e..5bf402c 100644 --- a/plugins/obs-x264/data/locale/zh-CN.ini +++ b/plugins/obs-x264/data/locale/zh-CN.ini @@ -1,12 +1,12 @@ Bitrate="比特率" CustomBufsize="使用自定义缓存大小" BufferSize="缓冲大小" -UseCBR="使用 CBR" +RateControl="速率控制" CRF="CRF" KeyframeIntervalSec="关键帧间隔(秒, 0=自动)" -CPUPreset="CPU 使用预设 (更高 = 较少的 CPU占用)" -Profile="档案" -Tune="曲调" +CPUPreset="CPU 使用预设 (高 = 较少的 CPU占用)" +Profile="Profile" +Tune="Tune" None="(无)" EncoderOptions="x264 选项 (用空格分隔)" VFR="可变帧率 (VFR)" diff --git a/plugins/obs-x264/data/locale/zh-TW.ini b/plugins/obs-x264/data/locale/zh-TW.ini index be0d8b1..00d68cf 100644 --- a/plugins/obs-x264/data/locale/zh-TW.ini +++ b/plugins/obs-x264/data/locale/zh-TW.ini @@ -1,7 +1,6 @@ -Bitrate="位元率" +Bitrate="流量" CustomBufsize="使用自訂的緩衝區大小" BufferSize="緩衝區大小" -UseCBR="使用 CBR (固定流量)" CRF="CRF" KeyframeIntervalSec="關鍵影格間隔 (秒,0 = 自動):" CPUPreset="CPU 使用率設定 (越快 = 越少CPU使用率)" diff --git a/plugins/obs-x264/obs-x264.c b/plugins/obs-x264/obs-x264.c index 1c7db31..193e445 100644 --- a/plugins/obs-x264/obs-x264.c +++ b/plugins/obs-x264/obs-x264.c @@ -97,7 +97,7 @@ static void obs_x264_defaults(obs_data_t *settings) obs_data_set_default_int (settings, "keyint_sec", 0); obs_data_set_default_int (settings, "crf", 23); obs_data_set_default_bool (settings, "vfr", false); - obs_data_set_default_bool (settings, "cbr", true); + obs_data_set_default_bool (settings, "rate_control","CBR"); obs_data_set_default_string(settings, "preset", "veryfast"); obs_data_set_default_string(settings, "profile", ""); @@ -113,10 +113,10 @@ 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_CUSTOM_BUF obs_module_text("CustomBufsize") #define TEXT_BUF_SIZE obs_module_text("BufferSize") -#define TEXT_USE_CBR obs_module_text("UseCBR") #define TEXT_VFR obs_module_text("VFR") #define TEXT_CRF obs_module_text("CRF") #define TEXT_KEYINT_SEC obs_module_text("KeyframeIntervalSec") @@ -130,17 +130,30 @@ static bool use_bufsize_modified(obs_properties_t *ppts, obs_property_t *p, obs_data_t *settings) { bool use_bufsize = obs_data_get_bool(settings, "use_bufsize"); + const char *rc = obs_data_get_string(settings, "rate_control"); + bool rc_crf = astrcmpi(rc, "CRF") == 0; + p = obs_properties_get(ppts, "buffer_size"); - obs_property_set_visible(p, use_bufsize); + obs_property_set_visible(p, use_bufsize && !rc_crf); return true; } -static bool use_cbr_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) { - bool cbr = obs_data_get_bool(settings, "cbr"); + const char *rc = obs_data_get_string(settings, "rate_control"); + bool abr = astrcmpi(rc, "CBR") == 0 || astrcmpi(rc, "ABR") == 0; + bool rc_crf = astrcmpi(rc, "CRF") == 0; + p = obs_properties_get(ppts, "crf"); - obs_property_set_visible(p, !cbr); + obs_property_set_visible(p, !abr); + + p = obs_properties_get(ppts, "bitrate"); + obs_property_set_visible(p, !rc_crf); + p = obs_properties_get(ppts, "use_bufsize"); + obs_property_set_visible(p, !rc_crf); + p = obs_properties_get(ppts, "buffse_size"); + obs_property_set_visible(p, !rc_crf); return true; } @@ -152,6 +165,15 @@ static obs_properties_t *obs_x264_props(void *unused) obs_property_t *list; obs_property_t *p; + list = obs_properties_add_list(props, "rate_control", TEXT_RATE_CONTROL, + 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"); + obs_property_list_add_string(list, "CRF", "CRF"); + + obs_property_set_modified_callback(list, rate_control_modified); + obs_properties_add_int(props, "bitrate", TEXT_BITRATE, 50, 10000000, 1); p = obs_properties_add_bool(props, "use_bufsize", TEXT_CUSTOM_BUF); @@ -159,11 +181,9 @@ static obs_properties_t *obs_x264_props(void *unused) obs_properties_add_int(props, "buffer_size", TEXT_BUF_SIZE, 0, 10000000, 1); - obs_properties_add_int(props, "keyint_sec", TEXT_KEYINT_SEC, 0, 20, 1); - p = obs_properties_add_bool(props, "cbr", TEXT_USE_CBR); obs_properties_add_int(props, "crf", TEXT_CRF, 0, 51, 1); - obs_property_set_modified_callback(p, use_cbr_modified); + 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); @@ -353,6 +373,13 @@ static inline int get_x264_cs_val(enum video_colorspace cs, static void obs_x264_video_info(void *data, struct video_scale_info *info); +enum rate_control { + RATE_CONTROL_CBR, + RATE_CONTROL_VBR, + RATE_CONTROL_ABR, + RATE_CONTROL_CRF +}; + static void update_params(struct obs_x264 *obsx264, obs_data_t *settings, char **params) { @@ -366,6 +393,8 @@ 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"); + 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"); @@ -374,7 +403,35 @@ static void update_params(struct obs_x264 *obsx264, obs_data_t *settings, int height = (int)obs_encoder_get_height(obsx264->encoder); bool use_bufsize = obs_data_get_bool(settings, "use_bufsize"); bool vfr = obs_data_get_bool(settings, "vfr"); - bool cbr = obs_data_get_bool(settings, "cbr"); + bool cbr_override= obs_data_get_bool(settings, "cbr"); + enum rate_control rc; + + /* XXX: "cbr" setting has been deprecated */ + if (cbr_override) { + warn("\"cbr\" setting has been deprecated for all encoders! " + "Please set \"rate_control\" to \"CBR\" instead. " + "Forcing CBR mode. " + "(Note to all: this is why you shouldn't use strings for " + "common settings)"); + rate_control = "CBR"; + } + + if (astrcmpi(rate_control, "CBR") == 0) { + rc = RATE_CONTROL_CBR; + crf = 0; + + } else if (astrcmpi(rate_control, "ABR") == 0) { + rc = RATE_CONTROL_ABR; + crf = 0; + + } else if (astrcmpi(rate_control, "VBR") == 0) { + rc = RATE_CONTROL_VBR; + + } else if (astrcmpi(rate_control, "CRF") == 0) { + rc = RATE_CONTROL_CRF; + bitrate = 0; + buffer_size = 0; + } if (keyint_sec) obsx264->params.i_keyint_max = @@ -406,20 +463,22 @@ static void update_params(struct obs_x264 *obsx264, obs_data_t *settings, /* use the new filler method for CBR to allow real-time adjusting of * the bitrate */ - if (cbr) { - obsx264->params.rc.f_rf_constant = 0.0f; + if (rc == RATE_CONTROL_CBR || rc == RATE_CONTROL_ABR) { obsx264->params.rc.i_rc_method = X264_RC_ABR; + if (rc == RATE_CONTROL_CBR) { #if X264_BUILD >= 139 - obsx264->params.rc.b_filler = true; + obsx264->params.rc.b_filler = true; #else - obsx264->params.i_nal_hrd = X264_NAL_HRD_CBR; + obsx264->params.i_nal_hrd = X264_NAL_HRD_CBR; #endif + } } else { obsx264->params.rc.i_rc_method = X264_RC_CRF; - obsx264->params.rc.f_rf_constant = (float)crf; } + obsx264->params.rc.f_rf_constant = (float)crf; + if (info.format == VIDEO_FORMAT_NV12) obsx264->params.i_csp = X264_CSP_NV12; else if (info.format == VIDEO_FORMAT_I420) @@ -433,25 +492,24 @@ static void update_params(struct obs_x264 *obsx264, obs_data_t *settings, set_param(obsx264, *(params++)); info("settings:\n" - "\tbitrate: %d\n" - "\tbuffer size: %d\n" - "\tcrf: %d%s\n" - "\tfps_num: %d\n" - "\tfps_den: %d\n" - "\twidth: %d\n" - "\theight: %d\n" - "\tkeyint: %d\n" - "\tvfr: %s\n" - "\tcbr: %s", + "\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" + "\tvfr: %s\n", + rate_control, obsx264->params.rc.i_vbv_max_bitrate, obsx264->params.rc.i_vbv_buffer_size, (int)obsx264->params.rc.f_rf_constant, - cbr ? " (0 when CBR is enabled)" : "", voi->fps_num, voi->fps_den, width, height, obsx264->params.i_keyint_max, - vfr ? "on" : "off", - cbr ? "on" : "off"); + vfr ? "on" : "off"); } static bool update_settings(struct obs_x264 *obsx264, obs_data_t *settings) diff --git a/plugins/rtmp-services/data/locale/ar-SA.ini b/plugins/rtmp-services/data/locale/ar-SA.ini index 8ae3595..74ab695 100644 --- a/plugins/rtmp-services/data/locale/ar-SA.ini +++ b/plugins/rtmp-services/data/locale/ar-SA.ini @@ -3,6 +3,8 @@ CustomStreamingServer="سيرفر بث مخصص" Service="خدمة" Server="سيرفر" StreamKey="مفتاح البث" +UseAuth="استخدام المصادقة" Username="اسم المستخدم" Password="كلمة السر" +ShowAll="إظهار كافة الخدمات" diff --git a/plugins/rtmp-services/data/locale/da-DK.ini b/plugins/rtmp-services/data/locale/da-DK.ini index de2704e..44ee8bb 100644 --- a/plugins/rtmp-services/data/locale/da-DK.ini +++ b/plugins/rtmp-services/data/locale/da-DK.ini @@ -3,4 +3,8 @@ CustomStreamingServer="Brugerdefineret Streaming Server" Service="Service" Server="Server" StreamKey="Stream nøgle" +UseAuth="Brug godkendelse" +Username="Brugernavn" +Password="Kodeord" +ShowAll="Vis alle services" diff --git a/plugins/rtmp-services/data/locale/de-DE.ini b/plugins/rtmp-services/data/locale/de-DE.ini index 5e365aa..a88cd61 100644 --- a/plugins/rtmp-services/data/locale/de-DE.ini +++ b/plugins/rtmp-services/data/locale/de-DE.ini @@ -1,8 +1,8 @@ StreamingServices="Streaming-Plattformen" -CustomStreamingServer="Benutzerdefinierter Streaming-Server" +CustomStreamingServer="Benutzerdefinierter Streamingserver" Service="Plattform" Server="Server" -StreamKey="Stream-Schlüssel" +StreamKey="Streamschlüssel" UseAuth="Authentifizierung verwenden" Username="Benutzername" Password="Passwort" diff --git a/plugins/rtmp-services/data/locale/el-GR.ini b/plugins/rtmp-services/data/locale/el-GR.ini index 8f546da..abebe04 100644 --- a/plugins/rtmp-services/data/locale/el-GR.ini +++ b/plugins/rtmp-services/data/locale/el-GR.ini @@ -3,5 +3,8 @@ CustomStreamingServer="Προσαρμοσμένος Διακομιστής Με Service="Υπηρεσία" Server="Διακομιστής" StreamKey="Κλειδί μετάδοσης" +UseAuth="Χρήση πιστοποίησης" Username="Όνομα χρήστη" +Password="Κωδικός" +ShowAll="Εμφάνιση όλων των υπηρεσιών" diff --git a/plugins/rtmp-services/data/locale/es-ES.ini b/plugins/rtmp-services/data/locale/es-ES.ini index 113f824..71987c1 100644 --- a/plugins/rtmp-services/data/locale/es-ES.ini +++ b/plugins/rtmp-services/data/locale/es-ES.ini @@ -1,5 +1,5 @@ StreamingServices="Servicio de retransmisión" -CustomStreamingServer="Presonalizar el servidor de retranmisión" +CustomStreamingServer="Personalizar el servidor de retransmisión" Service="Servicio" Server="Servidor" StreamKey="Clave de retransmisión" diff --git a/plugins/rtmp-services/data/locale/eu-ES.ini b/plugins/rtmp-services/data/locale/eu-ES.ini index 8ea2107..47cb9a7 100644 --- a/plugins/rtmp-services/data/locale/eu-ES.ini +++ b/plugins/rtmp-services/data/locale/eu-ES.ini @@ -1,10 +1,10 @@ -StreamingServices="Jario Zerbitzuak" -CustomStreamingServer="Norbere Jario Zerbitzaria" +StreamingServices="Transmisio zerbitzuak" +CustomStreamingServer="Transmisio zerbitzari pertsonalizatua" Service="Zerbitzua" Server="Zerbitzaria" -StreamKey="Jario giltza" -UseAuth="Erabili egiaztapena" +StreamKey="Transmisio giltza" +UseAuth="Erabili autentifikazioa" Username="Erabiltzaile-izena" -Password="Sarhitza" +Password="Pasahitza" ShowAll="Erakutsi zerbitzu guztiak" diff --git a/plugins/rtmp-services/data/locale/fr-FR.ini b/plugins/rtmp-services/data/locale/fr-FR.ini index 5611f6d..210b272 100644 --- a/plugins/rtmp-services/data/locale/fr-FR.ini +++ b/plugins/rtmp-services/data/locale/fr-FR.ini @@ -1,8 +1,8 @@ -StreamingServices="Services de Streaming" -CustomStreamingServer="Serveur de Streaming Personnalisé" +StreamingServices="Services de streaming" +CustomStreamingServer="Serveur de streaming personnalisé" Service="Service" Server="Serveur" -StreamKey="Clé de Stream" +StreamKey="Clé de stream" UseAuth="Utiliser l'authentification" Username="Nom d'utilisateur" Password="Mot de passe" diff --git a/plugins/rtmp-services/data/locale/he-IL.ini b/plugins/rtmp-services/data/locale/he-IL.ini new file mode 100644 index 0000000..28d21fe --- /dev/null +++ b/plugins/rtmp-services/data/locale/he-IL.ini @@ -0,0 +1,10 @@ +StreamingServices="שרותי הזרמת נתונים" +CustomStreamingServer="שרת הזרמת נתונים מותאם אישית" +Service="שירות" +Server="שרת" +StreamKey="מפתח הזרמת נתונים" +UseAuth="השתמש באימות" +Username="שם משתמש" +Password="סיסמא" +ShowAll="הצג את כל השירותים" + diff --git a/plugins/rtmp-services/data/locale/hu-HU.ini b/plugins/rtmp-services/data/locale/hu-HU.ini index 29e9d13..0cd0a76 100644 --- a/plugins/rtmp-services/data/locale/hu-HU.ini +++ b/plugins/rtmp-services/data/locale/hu-HU.ini @@ -1,8 +1,8 @@ -StreamingServices="Stream Kiszolgáló" -CustomStreamingServer="Egyéni Streamkiszolgáló" +StreamingServices="Stream kiszolgáló" +CustomStreamingServer="Egyéni stream szerver" Service="Szolgáltatás" Server="Szerver" -StreamKey="Stream Kulcs" +StreamKey="Stream kulcs" UseAuth="Hitelesítés használata" Username="Felhasználó" Password="Jelszó" diff --git a/plugins/rtmp-services/data/locale/pt-PT.ini b/plugins/rtmp-services/data/locale/pt-PT.ini index 79ec079..9e092d3 100644 --- a/plugins/rtmp-services/data/locale/pt-PT.ini +++ b/plugins/rtmp-services/data/locale/pt-PT.ini @@ -1,8 +1,8 @@ -StreamingServices="Serviço de Stream" -CustomStreamingServer="Servidor de Stream Personalizado" +StreamingServices="Serviço de transmissão" +CustomStreamingServer="Servidor de transmissão personalizado" Service="Serviço" Server="Servidor" -StreamKey="Chave de Steam" +StreamKey="Chave da transmissão" UseAuth="Utilizar autenticação" Username="Nome de utilizador" Password="Palavra-passe" diff --git a/plugins/rtmp-services/data/locale/ro-RO.ini b/plugins/rtmp-services/data/locale/ro-RO.ini index c4792df..4e3ae39 100644 --- a/plugins/rtmp-services/data/locale/ro-RO.ini +++ b/plugins/rtmp-services/data/locale/ro-RO.ini @@ -1,10 +1,10 @@ StreamingServices="Servicii de streaming" -CustomStreamingServer="Server de Streaming Personalizat" +CustomStreamingServer="Server de streaming personalizat" Service="Serviciu" Server="Server" -StreamKey="Cheie Stream" -UseAuth="Utilizează autentificare" -Username="Nume utilizator" +StreamKey="Cheie de stream" +UseAuth="Folosește autentificare" +Username="Nume de utilizator" Password="Parolă" ShowAll="Arată toate serviciile" diff --git a/plugins/rtmp-services/data/locale/sv-SE.ini b/plugins/rtmp-services/data/locale/sv-SE.ini index bc6d2ac..b080b2d 100644 --- a/plugins/rtmp-services/data/locale/sv-SE.ini +++ b/plugins/rtmp-services/data/locale/sv-SE.ini @@ -1,9 +1,10 @@ -StreamingServices="Streamtjänster" +StreamingServices="Strömtjänster" CustomStreamingServer="Anpassad streamningsserver" Service="Tjänst" Server="Server" StreamKey="Streamnyckel" UseAuth="Använd autentisering" -Username="Användarnanm" +Username="Användarnamn" Password="Lösenord" +ShowAll="Visa alla tjänster" diff --git a/plugins/rtmp-services/data/locale/tr-TR.ini b/plugins/rtmp-services/data/locale/tr-TR.ini index 2a50ec0..e27187b 100644 --- a/plugins/rtmp-services/data/locale/tr-TR.ini +++ b/plugins/rtmp-services/data/locale/tr-TR.ini @@ -4,7 +4,7 @@ Service="Servis" Server="Sunucu" StreamKey="Yayın Anahtarı" UseAuth="Kimlik doğrulaması kullan" -Username="Kullanıcı adı" +Username="Kullanıcı Adı" Password="Şifre" ShowAll="Tüm hizmetleri göster" diff --git a/plugins/rtmp-services/data/package.json b/plugins/rtmp-services/data/package.json index 61377a5..a8a8b63 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": 13, + "version": 21, "files": [ { "name": "services.json", - "version": 13 + "version": 21 } ] } diff --git a/plugins/rtmp-services/data/services.json b/plugins/rtmp-services/data/services.json index 0b00cae..50a26d7 100644 --- a/plugins/rtmp-services/data/services.json +++ b/plugins/rtmp-services/data/services.json @@ -57,6 +57,10 @@ "name": "EU: Stockholm, SE", "url": "rtmp://live-arn.twitch.tv/app" }, + { + "name": "EU: Warsaw, Poland", + "url": "rtmp://live-waw.twitch.tv/app" + }, { "name": "South America: Argentina", "url": "rtmp://live-eze.twitch.tv/app" @@ -110,7 +114,8 @@ "keyint": 2, "profile": "main", "max video bitrate": 3500, - "max audio bitrate": 160 + "max audio bitrate": 160, + "x264opts": "scenecut=0" } }, { @@ -310,23 +315,11 @@ ] }, { - "name": "Restream.io", + "name": "mSportz", "servers": [ { - "name": "EU Primary", - "url": "rtmp://eu.restream.io/live" - }, - { - "name": "EU Secondary", - "url": "rtmp://eu-secondary.restream.io/live" - }, - { - "name": "US West", - "url": "rtmp://us-west.restream.io/live" - }, - { - "name": "US East", - "url": "rtmp://us-east.restream.io/live" + "name": "Primary", + "url": "rtmp://52.21.78.175/mSports" } ] }, @@ -453,6 +446,75 @@ "url": "rtmp://de.live.cashplay.tv/live" } ] + }, + { + "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, + "servers": [ + { + "name": "Default", + "url": "rtmp://rtmp-api.facebook.com:80/rtmp/" + } + ], + "recommended": { + "keyint": 1, + "profile": "main", + "max video bitrate": 2000, + "max audio bitrate": 160 + } + }, + { + "name": "Restream.io", + "common": true, + "servers": [ + { + "name": "US-West (San Jose, California)", + "url": "rtmp://us-west.restream.io/live" + }, + { + "name": "US-West (Los Angeles, California)", + "url": "rtmp://us-la.restream.io/live" + }, + { + "name": "US-East (Washington, D.C.)", + "url": "rtmp://us-east.restream.io/live" + }, + { + "name": "US-Central (Dallas, TX)", + "url": "rtmp://us-central.restream.io/live" + }, + { + "name": "EU-Central (Frankfurt, Germany)", + "url": "rtmp://eu.restream.io/live" + }, + { + "name": "EU-West (London, GB)", + "url": "rtmp://eu-london.restream.io/live" + }, + { + "name": "Australia (Sydney)", + "url": "rtmp://au-secondary.restream.io/live" + }, + { + "name": "South America (Sao Paulo, Brazil)", + "url": "rtmp://sa.restream.io/live" + } + ] } ] } diff --git a/plugins/rtmp-services/rtmp-common.c b/plugins/rtmp-services/rtmp-common.c index b2ad176..a15790c 100644 --- a/plugins/rtmp-services/rtmp-common.c +++ b/plugins/rtmp-services/rtmp-common.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -328,7 +329,7 @@ static void apply_video_encoder_settings(obs_data_t *settings, obs_data_set_int(settings, "keyint_sec", keyint); } - obs_data_set_bool(settings, "cbr", true); + obs_data_set_string(settings, "rate_control", "CBR"); item = json_object_get(recommended, "profile"); if (item && json_is_string(item)) { @@ -344,6 +345,22 @@ static void apply_video_encoder_settings(obs_data_t *settings, obs_data_set_int(settings, "buffer_size", max_bitrate); } } + + item = json_object_get(recommended, "x264opts"); + if (item && json_is_string(item)) { + const char *x264_settings = json_string_value(item); + const char *cur_settings = + obs_data_get_string(settings, "x264opts"); + struct dstr opts; + + dstr_init_copy(&opts, cur_settings); + if (!dstr_is_empty(&opts)) + dstr_cat(&opts, " "); + dstr_cat(&opts, x264_settings); + + obs_data_set_string(settings, "x264opts", opts.array); + dstr_free(&opts); + } } static void apply_audio_encoder_settings(obs_data_t *settings, diff --git a/plugins/text-freetype2/data/locale/ar-SA.ini b/plugins/text-freetype2/data/locale/ar-SA.ini new file mode 100644 index 0000000..ce049f8 --- /dev/null +++ b/plugins/text-freetype2/data/locale/ar-SA.ini @@ -0,0 +1,14 @@ +TextFreetype2="نص (FreeType 2)" +Font="الخط" +Text="النص" +TextFile="ملف نص (UTF-8 أو UTF-16)" +TextFileFilter="ملفات نصية (*.txt);;" +ChatLogMode="وضع سجل المحادثة (آخر 6 سطور)" +Color1="اللون الأول" +Color2="اللون الثاني" +Outline="حدود" +DropShadow="ظل" +ReadFromFile="قراءة من ملف" +CustomWidth="عرض نص مخصص" +WordWrap="التفاف الكلمة" + diff --git a/plugins/text-freetype2/data/locale/da-DK.ini b/plugins/text-freetype2/data/locale/da-DK.ini index 954eee3..f3159f8 100644 --- a/plugins/text-freetype2/data/locale/da-DK.ini +++ b/plugins/text-freetype2/data/locale/da-DK.ini @@ -6,7 +6,7 @@ TextFileFilter="Tekstfiler (*.txt);;" ChatLogMode="Chat log tilstand (sidste 6 linjer)" Color1="Farve 1" Color2="Farve 2" -Outline="Skitse" +Outline="Kontur" DropShadow="Drop Shadow" ReadFromFile="Læse fra fil" CustomWidth="Brugerdefineret tekstbredde" diff --git a/plugins/text-freetype2/data/locale/eu-ES.ini b/plugins/text-freetype2/data/locale/eu-ES.ini index cb0f677..5e322a9 100644 --- a/plugins/text-freetype2/data/locale/eu-ES.ini +++ b/plugins/text-freetype2/data/locale/eu-ES.ini @@ -1,14 +1,14 @@ -TextFreetype2="Idazkia (FreeType 2)" -Font="Hizkia" -Text="Idazkia" -TextFile="Idazki Agiria (UTF-8 edo UTF-16)" -TextFileFilter="Idazki Agiriak (*.txt);;" -ChatLogMode="Txat ohar modua (azken 6 lerroak)" -Color1="Margoa 1" -Color2="Margoa 2" -Outline="Ingurua" -DropShadow="Eror Itzala" -ReadFromFile="Irakurri agiritik" -CustomWidth="Norbere idazki zabalera" -WordWrap="Hitz Ingurapena" +TextFreetype2="Testua (FreeType 2)" +Font="Letra-tipoa" +Text="Testua" +TextFile="Testu-fitxategia (UTF-8 edo UTF-16)" +TextFileFilter="Testu-fitxategiak (*.txt);;" +ChatLogMode="Berriketa egunkaria modua (azken 6 lerroak)" +Color1="1. kolorea" +Color2="2. kolorea" +Outline="Eskema" +DropShadow="Egin itzala" +ReadFromFile="Irakurri fitxategitik" +CustomWidth="Testu-zabalera pertsonalizatua" +WordWrap="Hitz ingurapena" diff --git a/plugins/text-freetype2/data/locale/he-IL.ini b/plugins/text-freetype2/data/locale/he-IL.ini new file mode 100644 index 0000000..8dfc796 --- /dev/null +++ b/plugins/text-freetype2/data/locale/he-IL.ini @@ -0,0 +1,14 @@ +TextFreetype2="טקסט (FreeType 2)" +Font="גופן" +Text="טקסט" +TextFile="קובץ טקסט (UTF-8 או UTF-16)" +TextFileFilter="קבצי טקסט (*.txt);;" +ChatLogMode="מצב יומן צ'אט (6 שורות אחרונות)" +Color1="צבע 1" +Color2="צבע 2" +Outline="קו מתאר" +DropShadow="הטלת צללית" +ReadFromFile="קריאה מקובץ" +CustomWidth="רוחב טקסט מותאם אישית" +WordWrap="הסתת מילים" + diff --git a/plugins/text-freetype2/data/locale/hu-HU.ini b/plugins/text-freetype2/data/locale/hu-HU.ini index 6aaed16..ecf0c1b 100644 --- a/plugins/text-freetype2/data/locale/hu-HU.ini +++ b/plugins/text-freetype2/data/locale/hu-HU.ini @@ -7,8 +7,8 @@ ChatLogMode="Beszélgetésnapló mód (utolsó 6 sor)" Color1="Szín 1" Color2="Szín 2" Outline="Körvonal" -DropShadow="Vetett Árnyék" -ReadFromFile="Fájlból olvasni" +DropShadow="Vetett árnyék" +ReadFromFile="Fájlból olvasás" CustomWidth="Egyedi szövegszélesség" WordWrap="Sortörés" diff --git a/plugins/text-freetype2/data/locale/ja-JP.ini b/plugins/text-freetype2/data/locale/ja-JP.ini index d127872..4bc35f2 100644 --- a/plugins/text-freetype2/data/locale/ja-JP.ini +++ b/plugins/text-freetype2/data/locale/ja-JP.ini @@ -1,9 +1,9 @@ -TextFreetype2="テキスト(FreeType 2)" +TextFreetype2="テキスト (FreeType 2)" Font="フォント" Text="テキスト" TextFile="テキストファイル (UTF-8 または UTF-16)" TextFileFilter="テキストファイル (*.txt);;" -ChatLogMode="チャットログモード(最新6行)" +ChatLogMode="チャットログモード (最新6行)" Color1="色 1" Color2="色 2" Outline="輪郭" diff --git a/plugins/text-freetype2/data/locale/ro-RO.ini b/plugins/text-freetype2/data/locale/ro-RO.ini index c4dfff8..80dd948 100644 --- a/plugins/text-freetype2/data/locale/ro-RO.ini +++ b/plugins/text-freetype2/data/locale/ro-RO.ini @@ -1,14 +1,14 @@ TextFreetype2="Text (FreeType 2)" Font="Font" -Text="Textul" -TextFile="Fişier text (UTF-8 sau UTF-16)" +Text="Text" +TextFile="Fișier text (UTF-8 sau UTF-16)" TextFileFilter="Fișiere text (*.txt);;" -ChatLogMode="Modul jurnal chat (ultimele 6 rânduri)" +ChatLogMode="Mod de jurnal al chatului (ultimele 6 rânduri)" Color1="Culoarea 1" Color2="Culoarea 2" Outline="Contur" -DropShadow="Umbră text" +DropShadow="Umbrire" ReadFromFile="Citește din fișier" -CustomWidth="Lăţime text personalizată" -WordWrap="Word Wrap" +CustomWidth="Lățime de text personalizată" +WordWrap="Încadrare pentru cuvinte" diff --git a/plugins/text-freetype2/data/locale/sv-SE.ini b/plugins/text-freetype2/data/locale/sv-SE.ini index b6850fb..9d7f819 100644 --- a/plugins/text-freetype2/data/locale/sv-SE.ini +++ b/plugins/text-freetype2/data/locale/sv-SE.ini @@ -1,3 +1,4 @@ +TextFreetype2="Text (FreeType 2)" Font="Typsnitt" Text="Text" TextFile="Textfil (UTF-8 eller UTF-16)" diff --git a/plugins/text-freetype2/data/locale/zh-CN.ini b/plugins/text-freetype2/data/locale/zh-CN.ini index 508bde5..d54eef5 100644 --- a/plugins/text-freetype2/data/locale/zh-CN.ini +++ b/plugins/text-freetype2/data/locale/zh-CN.ini @@ -6,7 +6,7 @@ TextFileFilter="文本文件(*.txt);;" ChatLogMode="聊天日志模式 (最后 6 行)" Color1="颜色 1" Color2="颜色 2" -Outline="大纲" +Outline="描边" DropShadow="下拉阴影" ReadFromFile="从文件读取" CustomWidth="自定义文本宽度" diff --git a/plugins/text-freetype2/data/text_default.effect b/plugins/text-freetype2/data/text_default.effect index 9680416..39b82e1 100644 --- a/plugins/text-freetype2/data/text_default.effect +++ b/plugins/text-freetype2/data/text_default.effect @@ -1,7 +1,4 @@ uniform float4x4 ViewProj; -uniform float4x4 color_matrix; -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; sampler_state def_sampler { @@ -27,14 +24,8 @@ VertInOut VSDefault(VertInOut vert_in) float4 PSDrawBare(VertInOut vert_in) : TARGET { - return image.Sample(def_sampler, vert_in.uv) * vert_in.col; -} - -float4 PSDrawMatrix(VertInOut vert_in) : TARGET -{ - float4 yuv = image.Sample(def_sampler, vert_in.uv); - yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max); - return saturate(mul(float4(yuv.xyz, 1.0), color_matrix)); + vert_in.col.a *= image.Sample(def_sampler, vert_in.uv).a; + return vert_in.col; } technique Draw @@ -45,12 +36,3 @@ technique Draw pixel_shader = PSDrawBare(vert_in); } } - -technique DrawMatrix -{ - pass - { - vertex_shader = VSDefault(vert_in); - pixel_shader = PSDrawMatrix(vert_in); - } -} diff --git a/plugins/text-freetype2/text-freetype2.c b/plugins/text-freetype2/text-freetype2.c index fa48604..c1a22ce 100644 --- a/plugins/text-freetype2/text-freetype2.c +++ b/plugins/text-freetype2/text-freetype2.c @@ -34,7 +34,8 @@ uint32_t texbuf_w = 2048, texbuf_h = 2048; static struct obs_source_info freetype2_source_info = { .id = "text_ft2_source", .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_VIDEO, + .output_flags = OBS_SOURCE_VIDEO | + OBS_SOURCE_CUSTOM_DRAW, .get_name = ft2_source_get_name, .create = ft2_source_create, .destroy = ft2_source_destroy, @@ -200,6 +201,7 @@ static void ft2_source_render(void *data, gs_effect_t *effect) if (srcdata == NULL) 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); @@ -366,7 +368,7 @@ static void ft2_source_update(void *data, obs_data_t *settings) bfree(srcdata->texbuf); srcdata->texbuf = NULL; } - srcdata->texbuf = bzalloc(texbuf_w * texbuf_h * 4); + srcdata->texbuf = bzalloc(texbuf_w * texbuf_h); if (srcdata->font_face) cache_standard_glyphs(srcdata); diff --git a/plugins/text-freetype2/text-freetype2.h b/plugins/text-freetype2/text-freetype2.h index 8996cb3..dfe58a8 100644 --- a/plugins/text-freetype2/text-freetype2.h +++ b/plugins/text-freetype2/text-freetype2.h @@ -53,7 +53,7 @@ struct ft2_source { FT_Face font_face; - uint32_t *texbuf; + uint8_t *texbuf; gs_vertbuffer_t *vbuf; gs_effect_t *draw_effect; diff --git a/plugins/text-freetype2/text-functionality.c b/plugins/text-freetype2/text-functionality.c index 066675b..c92f4b3 100644 --- a/plugins/text-freetype2/text-functionality.c +++ b/plugins/text-freetype2/text-functionality.c @@ -99,6 +99,12 @@ void set_up_vertex_buffer(struct ft2_source *srcdata) srcdata->vbuf = NULL; gs_vertexbuffer_destroy(tmpvbuf); } + + if (*srcdata->text == 0) { + obs_leave_graphics(); + return; + } + srcdata->vbuf = create_uv_vbuffer((uint32_t)wcslen(srcdata->text) * 6, true); @@ -241,7 +247,6 @@ void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs) slot = srcdata->font_face->glyph; uint32_t dx = srcdata->texbuf_x, dy = srcdata->texbuf_y; - uint8_t alpha; int32_t cached_glyphs = 0; size_t len = wcslen(cache_glyphs); @@ -266,6 +271,11 @@ void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs) dy += srcdata->max_h + 1; } + if (dy + g_h >= texbuf_h) { + blog(LOG_WARNING, "Out of space trying to render glyphs"); + break; + } + src_glyph = bzalloc(sizeof(struct glyph_info)); src_glyph->u = (float)dx / (float)texbuf_w; src_glyph->u2 = (float)(dx + g_w) / (float)texbuf_w; @@ -278,11 +288,9 @@ void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs) src_glyph->xadv = slot->advance.x >> 6; for (uint32_t y = 0; y < g_h; y++) { - for (uint32_t x = 0; x < g_w; x++) { - alpha = slot->bitmap.buffer[glyph_pos]; + for (uint32_t x = 0; x < g_w; x++) srcdata->texbuf[buf_pos] = - 0x00FFFFFF ^ ((uint32_t)alpha << 24); - } + slot->bitmap.buffer[glyph_pos]; } dx += (g_w + 1); @@ -310,7 +318,7 @@ void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs) } srcdata->tex = gs_texture_create(texbuf_w, texbuf_h, - GS_RGBA, 1, (const uint8_t **)&srcdata->texbuf, 0); + GS_A8, 1, (const uint8_t **)&srcdata->texbuf, 0); obs_leave_graphics(); } @@ -322,7 +330,8 @@ time_t get_modified_timestamp(char *filename) // stat is apparently terrifying and horrible, but we only call it once // every second at most. - stat(filename, &stats); + if (os_stat(filename, &stats) != 0) + return -1; return stats.st_mtime; } diff --git a/test/test-input/test-filter.c b/test/test-input/test-filter.c index 264a717..f8509cf 100644 --- a/test/test-input/test-filter.c +++ b/test/test-input/test-filter.c @@ -51,8 +51,10 @@ static void filter_render(void *data, gs_effect_t *effect) { struct test_filter *tf = data; - obs_source_process_filter_begin(tf->source, GS_RGBA, - OBS_ALLOW_DIRECT_RENDERING); + if (!obs_source_process_filter_begin(tf->source, GS_RGBA, + OBS_ALLOW_DIRECT_RENDERING)) + return; + obs_source_process_filter_end(tf->source, tf->whatever, 0, 0); UNUSED_PARAMETER(effect);