From 1e086365ca61330d540e7a70799932b8ad56a1d3 Mon Sep 17 00:00:00 2001
From: Xaymar
Date: Mon, 7 Feb 2022 12:10:00 +0100
Subject: [PATCH 001/164] locale: New Crowdin updates (#748)
* New translations en-US.ini (Japanese)
* New translations en-US.ini (Dutch)
* New translations en-US.ini (Dutch)
* New translations en-US.ini (Italian)
* New translations en-US.ini (Italian)
* New translations en-US.ini (Italian)
* New translations en-US.ini (Polish)
---
data/locale/it-IT.ini | 38 +++++++-----
data/locale/ja-JP.ini | 17 ++++++
data/locale/nl-NL.ini | 138 +++++++++++++++++++++++++++++++++++++++---
data/locale/pl-PL.ini | 2 +-
4 files changed, 171 insertions(+), 24 deletions(-)
diff --git a/data/locale/it-IT.ini b/data/locale/it-IT.ini
index 2afab566a2..ae7fb4d169 100644
--- a/data/locale/it-IT.ini
+++ b/data/locale/it-IT.ini
@@ -36,7 +36,7 @@ UI.Menu.About="Informazioni su StreamFX"
UI.About.Title="Informazioni su StreamFX"
UI.About.Text="
StreamFX è reso possibile da tutti i sostenitori su Patreon, su Sponsors Github, e da chiunque doni tramite PayPal. Ulteriori ringraziamenti vanno a tutti i traduttori che danno una mano con la localizzazione su Crowdin. Siete tutti incredibili!
"
UI.About.Role.Contributor="Collaboratore"
-UI.About.Role.Translator="Traduttore/trice"
+UI.About.Role.Translator="Traduttore"
UI.About.Role.Supporter="Sostenitore"
UI.About.Version="Versione:"
@@ -48,8 +48,8 @@ UI.Updater.Dialog.Button.Ok="Apri Pagina Download"
UI.Updater.Dialog.Button.Cancel="Ricordamelo in seguito"
UI.Updater.GitHubPermission.Title="StreamFX richiede il tuo permesso per connetterti a GitHub!"
UI.Updater.GitHubPermission.Text="Al fine di fornire un controllo manuale o automatizzato degli aggiornamenti, StreamFX si basa sull'API GitHub per recuperare le informazioni più recenti.
Si prega di leggere l' Informativa sulla privacy di Github, e clicca 'OK' se sei d'accordo, o 'Annulla' se non sei d'accordo."
-UI.Updater.Menu.CheckForUpdates="Controlla aggiornamenti"
-UI.Updater.Menu.CheckForUpdates.Automatically="Controlla automaticamente gli aggiornamenti"
+UI.Updater.Menu.CheckForUpdates="Cerca aggiornamenti"
+UI.Updater.Menu.CheckForUpdates.Automatically="Cerca automaticamente gli aggiornamenti"
UI.Updater.Menu.Channel="Versione Aggiornamenti"
UI.Updater.Menu.Channel.Release="Stabile"
UI.Updater.Menu.Channel.Testing="Beta"
@@ -129,7 +129,7 @@ Encoder.FFmpeg.AMF.Preset="Preimpostazioni"
Encoder.FFmpeg.AMF.Preset.Speed="Velocità"
Encoder.FFmpeg.AMF.Preset.Balanced="Bilanciato"
Encoder.FFmpeg.AMF.Preset.Quality="Qualità"
-Encoder.FFmpeg.AMF.RateControl="Opzioni di controllo Frequenza"
+Encoder.FFmpeg.AMF.RateControl="Opzioni Frequenza"
Encoder.FFmpeg.AMF.RateControl.Mode="Modalità"
Encoder.FFmpeg.AMF.RateControl.Mode.CQP="Parametro di quantizzazione costante"
Encoder.FFmpeg.AMF.RateControl.Mode.VBR_PEAK="Bitrate Variabile (Picco contenuto)"
@@ -140,7 +140,7 @@ Encoder.FFmpeg.AMF.RateControl.FrameSkipping="Salta fotogrammi"
Encoder.FFmpeg.AMF.RateControl.Limits="Limiti"
Encoder.FFmpeg.AMF.RateControl.Limits.BufferSize="Dimensione Buffer"
Encoder.FFmpeg.AMF.RateControl.Limits.Bitrate.Target="Bitrate di destinazione"
-Encoder.FFmpeg.AMF.RateControl.Limits.Bitrate.Maximum="Bitrate Massimo"
+Encoder.FFmpeg.AMF.RateControl.Limits.Bitrate.Maximum="Bitrate massimo"
Encoder.FFmpeg.AMF.RateControl.QP="Parametri di quantizzazione"
Encoder.FFmpeg.AMF.RateControl.QP.I="I-Frame QP"
Encoder.FFmpeg.AMF.RateControl.QP.P="P-Frame QP"
@@ -166,7 +166,7 @@ Encoder.FFmpeg.NVENC.Preset.LowLatencyHighPerformance="Bassa Latenza Prestazione
Encoder.FFmpeg.NVENC.Preset.LowLatencyHighQuality="Bassa Latenza Alta Qualità"
Encoder.FFmpeg.NVENC.Preset.Lossless="Lossless"
Encoder.FFmpeg.NVENC.Preset.LosslessHighPerformance="Lossless Prestazioni Elevate"
-Encoder.FFmpeg.NVENC.RateControl="Opzioni di controllo Frequenza"
+Encoder.FFmpeg.NVENC.RateControl="Opzioni Frequenza"
Encoder.FFmpeg.NVENC.RateControl.Mode="Modalità"
Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="Parametro di quantizzazione costante"
Encoder.FFmpeg.NVENC.RateControl.Mode.VBR="Bitrate Variabile"
@@ -182,7 +182,7 @@ Encoder.FFmpeg.NVENC.RateControl.Limits="Limiti"
Encoder.FFmpeg.NVENC.RateControl.Limits.BufferSize="Dimensione Buffer"
Encoder.FFmpeg.NVENC.RateControl.Limits.Quality="Qualità di destinazione"
Encoder.FFmpeg.NVENC.RateControl.Limits.Bitrate.Target="Bitrate di destinazione"
-Encoder.FFmpeg.NVENC.RateControl.Limits.Bitrate.Maximum="Bitrate Massimo"
+Encoder.FFmpeg.NVENC.RateControl.Limits.Bitrate.Maximum="Bitrate massimo"
Encoder.FFmpeg.NVENC.RateControl.QP="Parametri di quantizzazione"
Encoder.FFmpeg.NVENC.RateControl.QP.Minimum="QP Minimo"
Encoder.FFmpeg.NVENC.RateControl.QP.Maximum="QP Massimo"
@@ -221,7 +221,7 @@ Shader.Shader.Technique="Modalità"
Shader.Shader.Size="Dimensione"
Shader.Shader.Size.Width="Larghezza"
Shader.Shader.Size.Height="Altezza"
-Shader.Shader.Seed="Seme Di Casualizzazione"
+Shader.Shader.Seed="Fattore randomico"
Shader.Parameters="Parametri Ombreggiatore"
Shader.Parameter.Texture.Type="Tipo"
Shader.Parameter.Texture.Type.File="File"
@@ -257,20 +257,20 @@ Filter.Blur.Angle="Angolo (gradi)"
Filter.Blur.Center.X="Centro (X) (percentuale)"
Filter.Blur.Center.Y="Centro (Y) (percentuale)"
Filter.Blur.StepScale="Passo di Scalatura"
-Filter.Blur.StepScale.X="Scala passo X"
+Filter.Blur.StepScale.X="Passo scala X"
Filter.Blur.StepScale.Y="Scala passo Y"
Filter.Blur.Mask="Applica una maschera"
Filter.Blur.Mask.Type="Tipo maschera"
Filter.Blur.Mask.Type.Region="Regione"
Filter.Blur.Mask.Type.Image="Immagine"
Filter.Blur.Mask.Type.Source="Sorgente"
-Filter.Blur.Mask.Region.Left="Bordo sinistro"
-Filter.Blur.Mask.Region.Top="Bordo superiore"
-Filter.Blur.Mask.Region.Right="Bordo destro"
+Filter.Blur.Mask.Region.Left="Margine sinistro"
+Filter.Blur.Mask.Region.Top="Margine superiore"
+Filter.Blur.Mask.Region.Right="Margine destro"
Filter.Blur.Mask.Region.Bottom="Bordo inferiore"
Filter.Blur.Mask.Region.Feather="Area Sfumatura"
Filter.Blur.Mask.Region.Feather.Shift="Scostamento Sfumatura"
-Filter.Blur.Mask.Region.Invert="Inverti regione"
+Filter.Blur.Mask.Region.Invert="Regione invertita"
Filter.Blur.Mask.Image="Maschera immagine"
Filter.Blur.Mask.Source="Maschera di origine"
Filter.Blur.Mask.Color="Filtro maschera colore"
@@ -389,6 +389,9 @@ Filter.SDFEffects.SDF.Threshold="Soglia di Trasparenza SDF"
Filter.Transform="Trasformazione 3D"
Filter.Transform.Camera="Videocamera"
Filter.Transform.Camera.Mode="Modalità"
+Filter.Transform.Camera.Mode.CornerPin="Appunta angolo"
+Filter.Transform.Camera.Mode.Orthographic="Ortografica"
+Filter.Transform.Camera.Mode.Perspective="Prospettica"
Filter.Transform.Camera.FieldOfView="Campo Visivo"
Filter.Transform.Position="Posizione"
Filter.Transform.Position.X="X"
@@ -411,6 +414,11 @@ Filter.Transform.Rotation.Order.YXZ="Imbardata, Beccheggio, Rollio"
Filter.Transform.Rotation.Order.YZX="Imbardata, Rollio, Beccheggio"
Filter.Transform.Rotation.Order.ZXY="Rollio, Beccheggio, Imbardata"
Filter.Transform.Rotation.Order.ZYX="Rollio, Imbardata, Beccheggio"
+Filter.Transform.Corners="Angoli"
+Filter.Transform.Corners.TopLeft="Alto a Sinistra"
+Filter.Transform.Corners.TopRight="Alto a Destra"
+Filter.Transform.Corners.BottomLeft="Basso a sinistra"
+Filter.Transform.Corners.BottomRight="Basso a destra"
Filter.Transform.Mipmapping="Abilita Mipmapping"
Filter.Upscaling="Ampliamento"
@@ -445,13 +453,13 @@ Source.Mirror.Source.Audio.Layout.FullSurround="Surround completo"
Codec.AV1="AV1"
Codec.AV1.Profile="Profilo"
-Codec.AV1.Profile.Main="Principale"
+Codec.AV1.Profile.Main="Main"
Codec.AV1.Profile.High="Alta"
Codec.AV1.Profile.Professional="Professionale"
Codec.H264="H264"
Codec.H264.Profile="Profilo"
-Codec.H264.Profile.baseline="Modalità Base"
+Codec.H264.Profile.baseline="Baseline"
Codec.H264.Profile.main="Principale"
Codec.H264.Profile.high="Alta"
Codec.H264.Profile.high444p="Alta 4:4:4 Predittivo"
diff --git a/data/locale/ja-JP.ini b/data/locale/ja-JP.ini
index 6fa335997b..5daf2ab037 100644
--- a/data/locale/ja-JP.ini
+++ b/data/locale/ja-JP.ini
@@ -63,11 +63,14 @@ Encoder.AOM.AV1.Encoder.Usage.AllIntra="全イントラフレーム"
Encoder.AOM.AV1.Encoder.CPUUsage="CPU利用"
Encoder.AOM.AV1.Encoder.CPUUsage.0="Placebo"
Encoder.AOM.AV1.Encoder.CPUUsage.1="超低速"
+Encoder.AOM.AV1.Encoder.CPUUsage.2="Slower"
Encoder.AOM.AV1.Encoder.CPUUsage.3="Slow"
Encoder.AOM.AV1.Encoder.CPUUsage.4="Medium"
Encoder.AOM.AV1.Encoder.CPUUsage.5="Fast"
Encoder.AOM.AV1.Encoder.CPUUsage.6="高速"
+Encoder.AOM.AV1.Encoder.CPUUsage.7="Very Fast"
Encoder.AOM.AV1.Encoder.CPUUsage.8="最速"
+Encoder.AOM.AV1.Encoder.CPUUsage.9="Ultra Fast"
Encoder.AOM.AV1.Encoder.CPUUsage.10="超々々々高速"
Encoder.AOM.AV1.Encoder.Profile="プロファイル"
Encoder.AOM.AV1.KeyFrames="キー フレーム"
@@ -96,6 +99,20 @@ Encoder.AOM.AV1.RateControl.Buffer.Size.Optimal="最適サイズ"
Encoder.AOM.AV1.Advanced="詳細"
Encoder.AOM.AV1.Advanced.Threads="スレッド"
Encoder.AOM.AV1.Advanced.RowMultiThreading="行毎のマルチスレッド"
+Encoder.AOM.AV1.Advanced.Tile.Columns="Tile Columns"
+Encoder.AOM.AV1.Advanced.Tile.Rows="Tile Rows"
+Encoder.AOM.AV1.Advanced.Tune="Tune"
+Encoder.AOM.AV1.Advanced.Tune.Metric="Metric"
+Encoder.AOM.AV1.Advanced.Tune.Metric.PSNR="PSNR"
+Encoder.AOM.AV1.Advanced.Tune.Metric.SSIM="SSIM"
+Encoder.AOM.AV1.Advanced.Tune.Metric.VMAF.WithPreprocessing="VMAF (事前処理付き)"
+Encoder.AOM.AV1.Advanced.Tune.Metric.VMAF.WithoutPreprocessing="VMAF (事前処理なし)"
+Encoder.AOM.AV1.Advanced.Tune.Metric.VMAF.MaxGain="VMAF (NegMaxGain)"
+Encoder.AOM.AV1.Advanced.Tune.Metric.VMAF.NegMaxGain="VMAF (MaxGain)"
+Encoder.AOM.AV1.Advanced.Tune.Metric.Butteraugli="Butteraugli"
+Encoder.AOM.AV1.Advanced.Tune.Content="Content"
+Encoder.AOM.AV1.Advanced.Tune.Content.Screen="Screen"
+Encoder.AOM.AV1.Advanced.Tune.Content.Film="Film"
Encoder.FFmpeg="FFmpegオプション"
Encoder.FFmpeg.Suffix=" (FFmpeg経由)"
diff --git a/data/locale/nl-NL.ini b/data/locale/nl-NL.ini
index ae3cc270e7..b38ab7584c 100644
--- a/data/locale/nl-NL.ini
+++ b/data/locale/nl-NL.ini
@@ -108,19 +108,35 @@ Encoder.AOM.AV1.Advanced.Tune.Metric.SSIM="Simkaart"
Encoder.AOM.AV1.Advanced.Tune.Metric.VMAF.WithPreprocessing="VMAF (met voorverwerking)"
Encoder.AOM.AV1.Advanced.Tune.Metric.VMAF.WithoutPreprocessing="VMAF (zonder voorverwerking)"
Encoder.AOM.AV1.Advanced.Tune.Metric.VMAF.MaxGain="VMAF (NegMaxGain)"
+Encoder.AOM.AV1.Advanced.Tune.Metric.VMAF.NegMaxGain="VMAF (MaxGain)"
+Encoder.AOM.AV1.Advanced.Tune.Metric.Butteraugli="Butteraugli"
Encoder.AOM.AV1.Advanced.Tune.Content="Inhoud"
Encoder.AOM.AV1.Advanced.Tune.Content.Screen="Scherm"
Encoder.AOM.AV1.Advanced.Tune.Content.Film="Film"
+Encoder.FFmpeg="FFmpeg Opties"
+Encoder.FFmpeg.Suffix="(via FFmpeg)"
+Encoder.FFmpeg.CustomSettings="Eigen Opties"
+Encoder.FFmpeg.Threads="Hoeveelheid Threads"
+Encoder.FFmpeg.GPU="GPU"
+Encoder.FFmpeg.KeyFrames="Sleutelframes"
Encoder.FFmpeg.KeyFrames.IntervalType="Intervaltype"
Encoder.FFmpeg.KeyFrames.IntervalType.Frames="Frames"
Encoder.FFmpeg.KeyFrames.IntervalType.Seconds="Seconden"
Encoder.FFmpeg.KeyFrames.Interval="Interval"
Encoder.FFmpeg.AMF.Preset="Preset"
+Encoder.FFmpeg.AMF.Preset.Speed="Snelheid"
+Encoder.FFmpeg.AMF.Preset.Balanced="Gebalanceerd"
Encoder.FFmpeg.AMF.Preset.Quality="Kwaliteit"
+Encoder.FFmpeg.AMF.RateControl="Opties voor snelheidsregeling"
Encoder.FFmpeg.AMF.RateControl.Mode="Modus"
+Encoder.FFmpeg.AMF.RateControl.Mode.CQP="Constante Kwantisatie Parameter"
+Encoder.FFmpeg.AMF.RateControl.Mode.VBR_PEAK="Variabele Bitsnelheid (Piek Beperkt)"
+Encoder.FFmpeg.AMF.RateControl.Mode.VBR_LATENCY="Variabele Bitsnelheid (Latentie Beperkt)"
Encoder.FFmpeg.AMF.RateControl.Mode.CBR="Constante Bitrate"
+Encoder.FFmpeg.AMF.RateControl.LookAhead="Vooruitkijk"
+Encoder.FFmpeg.AMF.RateControl.FrameSkipping="Frames overslaan"
Encoder.FFmpeg.AMF.RateControl.Limits="Limieten"
Encoder.FFmpeg.AMF.RateControl.Limits.BufferSize="Buffergrootte"
Encoder.FFmpeg.AMF.RateControl.Limits.Bitrate.Target="Doelbitrate"
@@ -130,23 +146,62 @@ Encoder.FFmpeg.AMF.RateControl.QP.I="I-Frame QP"
Encoder.FFmpeg.AMF.RateControl.QP.P="P-Frame QP"
Encoder.FFmpeg.AMF.RateControl.QP.B="B-Frame QP"
Encoder.FFmpeg.AMF.Other="Andere opties"
+Encoder.FFmpeg.AMF.Other.BFrames="Maximale B-Frames"
+Encoder.FFmpeg.AMF.Other.BFrameReferences="B-Frame Referenties"
+Encoder.FFmpeg.AMF.Other.ReferenceFrames="Referentie Frames"
+Encoder.FFmpeg.AMF.Other.EnforceHRD="HRD afdwingen"
+Encoder.FFmpeg.AMF.Other.VBAQ="VBAQ"
+Encoder.FFmpeg.AMF.Other.AccessUnitDelimiter="Toegangseenheid Scheidingsteken"
Encoder.FFmpeg.NVENC.Preset="Preset"
Encoder.FFmpeg.NVENC.Preset.Default="Standaard"
Encoder.FFmpeg.NVENC.Preset.Slow="Traag"
Encoder.FFmpeg.NVENC.Preset.Medium="Gemiddeld"
Encoder.FFmpeg.NVENC.Preset.Fast="Snel"
+Encoder.FFmpeg.NVENC.Preset.HighPerformance="Hoge prestaties"
+Encoder.FFmpeg.NVENC.Preset.HighQuality="Hoge kwaliteit"
+Encoder.FFmpeg.NVENC.Preset.BluRayDisc="BluRay Schijf"
+Encoder.FFmpeg.NVENC.Preset.LowLatency="Lage Latentie"
+Encoder.FFmpeg.NVENC.Preset.LowLatencyHighPerformance="Lage Latency, Hoge Prestaties"
+Encoder.FFmpeg.NVENC.Preset.LowLatencyHighQuality="Lage Latentie, Hoge Kwaliteit"
+Encoder.FFmpeg.NVENC.Preset.Lossless="Verliesloos"
+Encoder.FFmpeg.NVENC.Preset.LosslessHighPerformance="Verliesloos met Hoge Prestaties"
+Encoder.FFmpeg.NVENC.RateControl="Opties voor Snelheidsregeling"
Encoder.FFmpeg.NVENC.RateControl.Mode="Modus"
+Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="Constante Kwantisatie Parameter"
+Encoder.FFmpeg.NVENC.RateControl.Mode.VBR="Variabele Bitrate"
+Encoder.FFmpeg.NVENC.RateControl.Mode.VBR_HQ="Hoge kwaliteit, Variabele Bitsnelheid"
Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="Constante Bitrate"
+Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_HQ="Hoge kwaliteit Constante Bitsnelheid"
+Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_LD_HQ="Lage Vertraging, Hoge kwaliteit, Constante Bitsnelheid"
+Encoder.FFmpeg.NVENC.RateControl.TwoPass="Tweemaal"
+Encoder.FFmpeg.NVENC.RateControl.LookAhead="Vooruitkijk"
+Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="Adaptieve I-Frames"
+Encoder.FFmpeg.NVENC.RateControl.AdaptiveB="Adaptieve B-Frames"
Encoder.FFmpeg.NVENC.RateControl.Limits="Limieten"
Encoder.FFmpeg.NVENC.RateControl.Limits.BufferSize="Buffergrootte"
+Encoder.FFmpeg.NVENC.RateControl.Limits.Quality="Doel kwaliteit"
Encoder.FFmpeg.NVENC.RateControl.Limits.Bitrate.Target="Doelbitrate"
Encoder.FFmpeg.NVENC.RateControl.Limits.Bitrate.Maximum="Maximale bitrate"
Encoder.FFmpeg.NVENC.RateControl.QP="Kwantiseringsparameters"
+Encoder.FFmpeg.NVENC.RateControl.QP.Minimum="Minimale QP"
+Encoder.FFmpeg.NVENC.RateControl.QP.Maximum="Maximale QP"
Encoder.FFmpeg.NVENC.RateControl.QP.I="I-Frame QP"
Encoder.FFmpeg.NVENC.RateControl.QP.P="P-Frame QP"
Encoder.FFmpeg.NVENC.RateControl.QP.B="B-Frame QP"
+Encoder.FFmpeg.NVENC.AQ="Adaptieve Kwantificering"
+Encoder.FFmpeg.NVENC.AQ.Spatial="Ruimtelijke Adaptieve kwantificering"
+Encoder.FFmpeg.NVENC.AQ.Strength="Ruimtelijke Adaptieve Kwantificering Sterkte"
+Encoder.FFmpeg.NVENC.AQ.Temporal="Tijdelijke Adaptieve Kwantificering"
Encoder.FFmpeg.NVENC.Other="Andere opties"
+Encoder.FFmpeg.NVENC.Other.BFrames="Maximale B-Frames"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode="B-Frame Referentie Modus"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Middle="Gebruik alleen middelste B-frames als referentie"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Each="Gebruik alle B-frames als referentie"
+Encoder.FFmpeg.NVENC.Other.ZeroLatency="Nul Latentie"
+Encoder.FFmpeg.NVENC.Other.WeightedPrediction="Gewogen Voorspelling"
+Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="Niet-Referentie Frames"
+Encoder.FFmpeg.NVENC.Other.ReferenceFrames="Referentie Frames"
Blur.Type.Box="Vierkant"
Blur.Type.BoxLinear="Lineair vierkant"
@@ -177,8 +232,22 @@ Filter.Shader="Shader"
Source.Shader="Shader"
Transition.Shader="Shader"
+Filter.AutoFraming="Automatische Framing"
+Filter.AutoFraming.Tracking="Tracking Opties"
Filter.AutoFraming.Tracking.Mode="Modus"
+Filter.AutoFraming.Tracking.Mode.Solo="Solo"
+Filter.AutoFraming.Tracking.Mode.Group="Groep"
+Filter.AutoFraming.Tracking.Frequency="Frequentie"
+Filter.AutoFraming.Motion="Beweging Opties"
+Filter.AutoFraming.Motion.Smoothing="Vloeiend maken"
+Filter.AutoFraming.Motion.Prediction="Voorspelling"
+Filter.AutoFraming.Framing="Framing Opties"
+Filter.AutoFraming.Framing.Stability="Stabiliteit"
+Filter.AutoFraming.Framing.Padding="Opvulling"
Filter.AutoFraming.Framing.Offset="Afwijking"
+Filter.AutoFraming.Framing.AspectRatio="Beeldverhouding"
+Filter.AutoFraming.Provider="Aanbieder"
+Filter.AutoFraming.Provider.NVIDIA.FaceDetection="NVIDIA® Face Detection, mogelijk gemaakt door NVIDIA® Broadcast"
Filter.Blur="Vervagen"
Filter.Blur.Type="Variant"
@@ -209,16 +278,26 @@ Filter.Blur.Mask.Alpha="Masker Alpha filter"
Filter.Blur.Mask.Multiplier="Masker vermenigvuldiger"
Filter.ColorGrade="Kleurcorrectie"
+Filter.ColorGrade.Lift="Verhoging"
+Filter.ColorGrade.Lift.Red="Rode Verhoging"
+Filter.ColorGrade.Lift.Green="Verhoging"
+Filter.ColorGrade.Lift.Blue="Blauwe Verhoging"
+Filter.ColorGrade.Lift.All="Alle Verhoging"
Filter.ColorGrade.Gamma="Gamma"
Filter.ColorGrade.Gamma.Red="Rode Gamma"
Filter.ColorGrade.Gamma.Green="Groene Gamma"
Filter.ColorGrade.Gamma.Blue="Blauwe Gamma"
Filter.ColorGrade.Gamma.All="Alle Gamma"
Filter.ColorGrade.Gain="Versterking"
+Filter.ColorGrade.Gain.Red="Rode Versterking"
+Filter.ColorGrade.Gain.Green="Groene Verhoging"
+Filter.ColorGrade.Gain.Blue="Blauwe Versterking"
+Filter.ColorGrade.Gain.All="Alle Versterking"
Filter.ColorGrade.Offset="Afwijking"
Filter.ColorGrade.Offset.Red="Rode afwijking"
Filter.ColorGrade.Offset.Green="Groene afwijking"
Filter.ColorGrade.Offset.Blue="Blauwe afwijking"
+Filter.ColorGrade.Offset.All="Alle Afwijking"
Filter.ColorGrade.Tint="Tint"
Filter.ColorGrade.Tint.Detection="Tint Luma detectie methode"
Filter.ColorGrade.Tint.Detection.HSV="Tint Verzadigingswaarde"
@@ -228,9 +307,18 @@ Filter.ColorGrade.Tint.Mode="Verzadiging Luma methode"
Filter.ColorGrade.Tint.Mode.Linear="Lineair"
Filter.ColorGrade.Tint.Mode.Exp="Exp"
Filter.ColorGrade.Tint.Mode.Exp2="Exp2"
+Filter.ColorGrade.Tint.Mode.Log="Log"
+Filter.ColorGrade.Tint.Mode.Log10="Log10"
+Filter.ColorGrade.Tint.Exponent="Tint Luma Exponent"
Filter.ColorGrade.Tint.Shadow.Red="Schaduw Rode Tint"
Filter.ColorGrade.Tint.Shadow.Green="Schaduw Groene tint"
Filter.ColorGrade.Tint.Shadow.Blue="Schaduw Blauwe Tint"
+Filter.ColorGrade.Tint.Midtone.Red="Midtoon Rode Tint"
+Filter.ColorGrade.Tint.Midtone.Green="Midtoon Groene Tint"
+Filter.ColorGrade.Tint.Midtone.Blue="Midtoon Blauwe Tint"
+Filter.ColorGrade.Tint.Highlight.Red="Hoge Rode Tint"
+Filter.ColorGrade.Tint.Highlight.Green="Hoge Groene Tint"
+Filter.ColorGrade.Tint.Highlight.Blue="Hoge Blauwe Tint"
Filter.ColorGrade.Correction="Kleurcorrectie"
Filter.ColorGrade.Correction.Hue="Tintverschuiving"
Filter.ColorGrade.Correction.Saturation="Verzadiging"
@@ -245,10 +333,14 @@ Filter.ColorGrade.RenderMode.LUT.8Bit="8-Bit Look-Up Table"
Filter.ColorGrade.RenderMode.LUT.10Bit="10-Bit Look-Up Table"
Filter.Denoising="Ruisonderdrukking"
+Filter.Denoising.Provider="Aanbieder"
+Filter.Denoising.Provider.NVIDIA.Denoising="NVIDIA Ruisonderdrukking, mogelijk gemaakt door NVIDIA Broadcast"
+Filter.Denoising.NVIDIA.Denoising="NVIDIA Ruisonderdrukking"
Filter.Denoising.NVIDIA.Denoising.Strength="Intensiteit"
Filter.Denoising.NVIDIA.Denoising.Strength.Weak="Zwak"
Filter.Denoising.NVIDIA.Denoising.Strength.Strong="Sterk"
+Filter.Displacement="Verplaatsing Mapping"
Filter.Displacement.File="Bestand"
Filter.Displacement.Scale="Grootte"
Filter.Displacement.Scale.Type="Schalings type"
@@ -267,28 +359,39 @@ Filter.SDFEffects.Shadow.Inner.Range.Maximum="Binnenste schaduw Maximale afstand
Filter.SDFEffects.Shadow.Inner.Offset.X="Binnenste schaduw Afwijking X-as"
Filter.SDFEffects.Shadow.Inner.Offset.Y="Binnenste schaduw Afwijking Y-as"
Filter.SDFEffects.Shadow.Inner.Color="Binnenste schaduwkleur"
+Filter.SDFEffects.Shadow.Inner.Alpha="Binnenste Schaduw Alfa"
Filter.SDFEffects.Shadow.Outer="Buitenste schaduw"
Filter.SDFEffects.Shadow.Outer.Range.Minimum="Buitenste schaduw Minimale afstand"
Filter.SDFEffects.Shadow.Outer.Range.Maximum="Buitenste schaduw Maximale afstand"
Filter.SDFEffects.Shadow.Outer.Offset.X="Buitenste schaduw Afwijking X-as"
Filter.SDFEffects.Shadow.Outer.Offset.Y="Buitenste schaduw Afwijking Y-as"
Filter.SDFEffects.Shadow.Outer.Color="Buitenste schaduw kleur"
+Filter.SDFEffects.Shadow.Outer.Alpha="Buitenste Schaduw Alfa"
Filter.SDFEffects.Glow.Outer="Buitenste gloed"
Filter.SDFEffects.Glow.Outer.Color="Buitenste gloed kleur"
+Filter.SDFEffects.Glow.Outer.Alpha="Buitenste Gloei Alfa"
Filter.SDFEffects.Glow.Outer.Width="Buitenste gloed Breedte"
Filter.SDFEffects.Glow.Outer.Sharpness="Buitenste gloed Scherpte"
Filter.SDFEffects.Glow.Inner="Binnenste gloed"
Filter.SDFEffects.Glow.Inner.Color="Binnenste gloed kleur"
+Filter.SDFEffects.Glow.Inner.Alpha="Binnenste Gloed Alfa"
Filter.SDFEffects.Glow.Inner.Width="Binnenste gloed Breedte"
-Filter.SDFEffects.Outline="Omlijning"
-Filter.SDFEffects.Outline.Color="Omlijning kleur"
-Filter.SDFEffects.Outline.Width="Omlijning breedte"
+Filter.SDFEffects.Glow.Inner.Sharpness="Binnenste Gloed Scherpte"
+Filter.SDFEffects.Outline="Contour"
+Filter.SDFEffects.Outline.Color="Contourkleur"
+Filter.SDFEffects.Outline.Alpha="Omlijn Alfa"
+Filter.SDFEffects.Outline.Width="Omlijning Breedte"
Filter.SDFEffects.Outline.Offset="Omlijning Afwijking"
Filter.SDFEffects.Outline.Sharpness="Omlijning scherpte"
+Filter.SDFEffects.SDF.Scale="SDF Textuur Schaal"
+Filter.SDFEffects.SDF.Threshold="SDF Alpha drempelwaarde"
Filter.Transform="3D Transformeren"
Filter.Transform.Camera="Camera"
Filter.Transform.Camera.Mode="Modus"
+Filter.Transform.Camera.Mode.CornerPin="Hoekpin"
+Filter.Transform.Camera.Mode.Orthographic="Orthografisch"
+Filter.Transform.Camera.Mode.Perspective="Perspectief"
Filter.Transform.Camera.FieldOfView="Gezichtsveld"
Filter.Transform.Position="Positie"
Filter.Transform.Position.X="X"
@@ -297,9 +400,13 @@ Filter.Transform.Position.Z="Z"
Filter.Transform.Scale="Grootte"
Filter.Transform.Scale.X="X"
Filter.Transform.Scale.Y="Y"
+Filter.Transform.Shear="Afschuiving"
Filter.Transform.Shear.X="X"
Filter.Transform.Shear.Y="Y"
Filter.Transform.Rotation="Rotatie"
+Filter.Transform.Rotation.X="Rotatie X"
+Filter.Transform.Rotation.Y="Rotatie Y"
+Filter.Transform.Rotation.Z="Rotatie Z"
Filter.Transform.Rotation.Order="Rotatie volgorde"
Filter.Transform.Rotation.Order.XYZ="Pitch, Yaw, Roll"
Filter.Transform.Rotation.Order.XZY="Pitch, Roll, Yaw"
@@ -307,17 +414,31 @@ Filter.Transform.Rotation.Order.YXZ="Yaw, Pitch, Roll"
Filter.Transform.Rotation.Order.YZX="Yaw, Roll, Pitch"
Filter.Transform.Rotation.Order.ZXY="Roll, Pitch, Yaw"
Filter.Transform.Rotation.Order.ZYX="Rol, Yaw, Pitch"
+Filter.Transform.Corners="Hoeken"
+Filter.Transform.Corners.TopLeft="Linksboven"
+Filter.Transform.Corners.TopRight="Rechtsboven"
+Filter.Transform.Corners.BottomLeft="Linksonder"
+Filter.Transform.Corners.BottomRight="Rechtsonder"
Filter.Transform.Mipmapping="Mipmapping inschakelen"
Filter.Upscaling="Opschalen"
+Filter.Upscaling.Provider="Aanbieder"
+Filter.Upscaling.Provider.NVIDIA.SuperResolution="NVIDIA® Super Resolutie, mogelijk gemaakt door NVIDIA® Broadcast"
+Filter.Upscaling.NVIDIA.SuperRes="NVIDIA® Super Resolutie"
Filter.Upscaling.NVIDIA.SuperRes.Scale="Grootte"
Filter.Upscaling.NVIDIA.SuperRes.Strength="Intensiteit"
Filter.Upscaling.NVIDIA.SuperRes.Strength.Weak="Zwak"
Filter.Upscaling.NVIDIA.SuperRes.Strength.Strong="Sterk"
+Filter.VirtualGreenscreen="Virtueel Greenscreen"
+Filter.VirtualGreenscreen.Provider="Aanbieder"
+Filter.VirtualGreenscreen.Provider.NVIDIA.Greenscreen="NVIDIA® Greenscreen, mogelijk gemaakt door NVIDIA® Broadcast"
+Filter.VirtualGreenscreen.NVIDIA.Greenscreen="NVIDIA® Greenscreen"
Filter.VirtualGreenscreen.NVIDIA.Greenscreen.Mode="Modus"
+Filter.VirtualGreenscreen.NVIDIA.Greenscreen.Mode.Performance="Prestatie"
Filter.VirtualGreenscreen.NVIDIA.Greenscreen.Mode.Quality="Kwaliteit"
+Source.Mirror="Bron mirror"
Source.Mirror.Source="Bron"
Source.Mirror.Source.Audio="Audio inschakelen"
Source.Mirror.Source.Audio.Layout="Audio Layout"
@@ -341,6 +462,7 @@ Codec.H264.Profile="Profiel"
Codec.H264.Profile.baseline="Referentie"
Codec.H264.Profile.main="Algemeen"
Codec.H264.Profile.high="Hoog"
+Codec.H264.Profile.high444p="Hoge 4:4:4 Voorspelling"
Codec.H264.Level="Niveau"
Codec.HEVC="HEVC"
@@ -355,9 +477,9 @@ Codec.HEVC.Level="Niveau"
Codec.ProRes.Profile="Profiel"
Codec.ProRes.Profile.APCO="422 Proxy (APCO)"
-Codec.ProRes.Profile.APCS="422 Lite/LT (APCS)"
-Codec.ProRes.Profile.APCN="422 Standard (APCN)"
-Codec.ProRes.Profile.APCH="422 High Quality/HQ (APCH)"
-Codec.ProRes.Profile.AP4H="4444 High Quality/HQ (AP4H)"
-Codec.ProRes.Profile.AP4X="4444 Extreme Quality/XQ (AP4X)"
+Codec.ProRes.Profile.APCS="422 Licht/LT (APCS)"
+Codec.ProRes.Profile.APCN="422 Standaard (APCN)"
+Codec.ProRes.Profile.APCH="422 Hoge Kwaliteit/HQ (APCH)"
+Codec.ProRes.Profile.AP4H="4444 Hoge Kwaliteit/HQ (AP4H)"
+Codec.ProRes.Profile.AP4X="4444 Extreme Kwaliteit/XQ (AP4X)"
diff --git a/data/locale/pl-PL.ini b/data/locale/pl-PL.ini
index 2c3a280934..88ac2eb2dd 100644
--- a/data/locale/pl-PL.ini
+++ b/data/locale/pl-PL.ini
@@ -47,7 +47,7 @@ UI.Updater.Dialog.Version.Latest="Najnowsza wersja:"
UI.Updater.Dialog.Button.Ok="Otwórz stronę pobierania"
UI.Updater.Dialog.Button.Cancel="Przypomnij później"
UI.Updater.GitHubPermission.Title="StreamFX wymaga twojego pozwolenia do połączenia się z GitHub-em!"
-UI.Updater.GitHubPermission.Text="Aby zapewnić manualne lub zautomatyzowane sprawdzanie aktualizacji, StreamFX polega na API GutHub-a w celu pobierania najnowszych informacji.
Przeczytaj Politykę prywatności serwisu Huthub i kliknij \"OK\" jeśli się zgadzasz lub \"Anuluj\" jeżeli nie."
+UI.Updater.GitHubPermission.Text="Aby zapewnić ręczne lub automatyczne sprawdzanie aktualizacji, StreamFX korzysta z GitHub API do pobierania najnowszych informacji.
Przeczytaj Oświadczenie o prywatności na Github, i kliknij \"OK\", jeśli się zgadzasz, lub \"Anuluj\", jeśli się nie zgadzasz."
UI.Updater.Menu.CheckForUpdates="Sprawdź aktualizacje"
UI.Updater.Menu.CheckForUpdates.Automatically="Automatycznie sprawdzaj aktualizacje"
UI.Updater.Menu.Channel="Kanał aktualizacji"
From 881c7d920a1cd90df8a81979c7b5410288dbaf3f Mon Sep 17 00:00:00 2001
From: Michael Fabian 'Xaymar' Dirks
Date: Wed, 9 Feb 2022 17:38:20 +0100
Subject: [PATCH 002/164] ci: Ignore specific Packages versions
---
.github/workflows/main.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 9f8acb3168..8205e6d4f3 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -315,7 +315,8 @@ jobs:
run: |
curl -L -O http://s.sudre.free.fr/Software/files/Packages.dmg
sudo hdiutil attach ./Packages.dmg
- sudo installer -pkg /Volumes/Packages\ 1.2.9/Install\ Packages.pkg -target /
+ pushd /Volumes/Packages*
+ sudo installer -pkg ./Install\ Packages.pkg -target /
- name: "Packages: Package"
shell: bash
run: |
From 7f6047f43f4222c87cece99aeef904490d204a38 Mon Sep 17 00:00:00 2001
From: Michael Fabian 'Xaymar' Dirks
Date: Thu, 17 Feb 2022 01:50:46 +0100
Subject: [PATCH 003/164] ffmpeg/tools: Helpers for easily populating OBS
property lists
---
source/ffmpeg/tools.cpp | 77 +++++++++++++++++++++++++++++++++++++++++
source/ffmpeg/tools.hpp | 11 ++++++
2 files changed, 88 insertions(+)
diff --git a/source/ffmpeg/tools.cpp b/source/ffmpeg/tools.cpp
index 00dfe41c0c..597222c24d 100644
--- a/source/ffmpeg/tools.cpp
+++ b/source/ffmpeg/tools.cpp
@@ -183,6 +183,83 @@ AVColorTransferCharacteristic streamfx::ffmpeg::tools::obs_to_av_color_transfer_
}
}
+const char* tools::avoption_name_from_unit_value(const void* obj, std::string_view unit, int64_t value)
+{
+ for (const AVOption* opt = nullptr; (opt = av_opt_next(obj, opt)) != nullptr;) {
+ // Skip all irrelevant options.
+ if (!opt->unit)
+ continue;
+ if (opt->unit != unit)
+ continue;
+ if (opt->name == unit)
+ continue;
+
+ if (opt->default_val.i64 == value)
+ return opt->name;
+ }
+ return nullptr;
+}
+
+bool tools::avoption_exists(const void* obj, std::string_view name)
+{
+ for (const AVOption* opt = nullptr; (opt = av_opt_next(obj, opt)) != nullptr;) {
+ if (name == opt->name)
+ return true;
+ }
+ return false;
+}
+
+void tools::avoption_list_add_entries_unnamed(const void* obj, std::string_view unit, obs_property_t* prop,
+ std::function filter)
+{
+ for (const AVOption* opt = nullptr; (opt = av_opt_next(obj, opt)) != nullptr;) {
+ // Skip all irrelevant options.
+ if (!opt->unit)
+ continue;
+ if (opt->unit != unit)
+ continue;
+ if (opt->name == unit)
+ continue;
+
+ // Skip any deprecated options.
+ if (opt->flags & AV_OPT_FLAG_DEPRECATED)
+ continue;
+
+ if (filter && filter(opt))
+ continue;
+
+ // Generate name and add to list.
+ obs_property_list_add_int(prop, opt->name, opt->default_val.i64);
+ }
+}
+
+void tools::avoption_list_add_entries(const void* obj, std::string_view unit, obs_property_t* prop,
+ std::string_view prefix, std::function filter)
+{
+ for (const AVOption* opt = nullptr; (opt = av_opt_next(obj, opt)) != nullptr;) {
+ // Skip all irrelevant options.
+ if (!opt->unit)
+ continue;
+ if (opt->unit != unit)
+ continue;
+ if (opt->name == unit)
+ continue;
+
+ // Skip any deprecated options.
+ if (opt->flags & AV_OPT_FLAG_DEPRECATED)
+ continue;
+
+ // Skip based on filter function.
+ if (filter && filter(opt))
+ continue;
+
+ // Generate name and add to list.
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "%s.%s\0", prefix.data(), opt->name);
+ obs_property_list_add_int(prop, D_TRANSLATE(buffer), opt->default_val.i64);
+ }
+}
+
bool tools::can_hardware_encode(const AVCodec* codec)
{
AVPixelFormat hardware_formats[] = {AV_PIX_FMT_D3D11};
diff --git a/source/ffmpeg/tools.hpp b/source/ffmpeg/tools.hpp
index 336c92e786..51d06e96fd 100644
--- a/source/ffmpeg/tools.hpp
+++ b/source/ffmpeg/tools.hpp
@@ -29,6 +29,7 @@ extern "C" {
#pragma warning(disable : 4242 4244 4365)
#endif
#include
+#include
#include
#ifdef _MSC_VER
#pragma warning(pop)
@@ -80,4 +81,14 @@ namespace streamfx::ffmpeg::tools {
void print_av_option_string2(AVCodecContext* ctx_codec, void* ctx_option, std::string_view option,
std::string_view text, std::function decoder);
+ bool avoption_exists(const void* obj, std::string_view name);
+
+ const char* avoption_name_from_unit_value(const void* obj, std::string_view unit, int64_t value);
+
+ void avoption_list_add_entries_unnamed(const void* obj, std::string_view unit, obs_property_t* prop,
+ std::function filter = nullptr);
+
+ void avoption_list_add_entries(const void* obj, std::string_view unit, obs_property_t* prop,
+ std::string_view prefix, std::function filter = nullptr);
+
} // namespace streamfx::ffmpeg::tools
From 36aec3be5441b9b6e767c59db234c938ebeb16e0 Mon Sep 17 00:00:00 2001
From: Michael Fabian 'Xaymar' Dirks
Date: Thu, 17 Feb 2022 04:30:17 +0100
Subject: [PATCH 004/164] encoders/ffmpeg/nvenc: Ensure compatibility with more
than just FFmpeg 4.2
When FFmpeg Encoders was originally written, FFmpeg 4.2 was still new and OBS Studio did not seem to want to update to anything newer for a while. This led to code being fine-tuned for FFmpeg 4.2, which stops working the moment OBS Studio upgrades FFmpeg. This removes the dependency on FFmpeg 4.2 hopefully, and allows using newer FFmpeg versions - or perhaps even older versions.
Additionally the nonsensical behavior of the Target Quality slider was fixed. It is now from 0 to 51, instead of from 0 to 100, and as such matches FFmpeg exactly.
---
data/locale/en-US.ini | 55 +--
.../encoders/handlers/nvenc_h264_handler.cpp | 64 ++--
.../encoders/handlers/nvenc_hevc_handler.cpp | 81 ++---
source/encoders/handlers/nvenc_shared.cpp | 331 ++++++++++--------
source/encoders/handlers/nvenc_shared.hpp | 52 +--
5 files changed, 271 insertions(+), 312 deletions(-)
diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini
index 4e1965da6e..9b9454ce30 100644
--- a/data/locale/en-US.ini
+++ b/data/locale/en-US.ini
@@ -166,27 +166,40 @@ Encoder.FFmpeg.AMF.Other.AccessUnitDelimiter="Access Unit Delimiter"
# Encoder/FFmpeg/NVENC
Encoder.FFmpeg.NVENC.Preset="Preset"
-Encoder.FFmpeg.NVENC.Preset.Default="Default"
-Encoder.FFmpeg.NVENC.Preset.Slow="Slow"
-Encoder.FFmpeg.NVENC.Preset.Medium="Medium"
-Encoder.FFmpeg.NVENC.Preset.Fast="Fast"
-Encoder.FFmpeg.NVENC.Preset.HighPerformance="High Performance"
-Encoder.FFmpeg.NVENC.Preset.HighQuality="High Quality"
-Encoder.FFmpeg.NVENC.Preset.BluRayDisc="BluRay Disc"
-Encoder.FFmpeg.NVENC.Preset.LowLatency="Low Latency"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighPerformance="Low Latency High Performance"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighQuality="Low Latency High Quality"
-Encoder.FFmpeg.NVENC.Preset.Lossless="Lossless"
-Encoder.FFmpeg.NVENC.Preset.LosslessHighPerformance="Lossless High Performance"
+Encoder.FFmpeg.NVENC.Preset.default="Default"
+Encoder.FFmpeg.NVENC.Preset.slow="Slow"
+Encoder.FFmpeg.NVENC.Preset.medium="Medium"
+Encoder.FFmpeg.NVENC.Preset.fast="Fast"
+Encoder.FFmpeg.NVENC.Preset.hp="High Performance"
+Encoder.FFmpeg.NVENC.Preset.hq="High Quality"
+Encoder.FFmpeg.NVENC.Preset.bd="BluRay Disc"
+Encoder.FFmpeg.NVENC.Preset.ll="Low Latency"
+Encoder.FFmpeg.NVENC.Preset.llhq="Low Latency High Quality"
+Encoder.FFmpeg.NVENC.Preset.llhp="Low Latency High Performance"
+Encoder.FFmpeg.NVENC.Preset.lossless="Lossless"
+Encoder.FFmpeg.NVENC.Preset.losslesshp="Lossless High Performance"
+Encoder.FFmpeg.NVENC.Preset.p1="Fastest (P1)"
+Encoder.FFmpeg.NVENC.Preset.p2="Faster (P2)"
+Encoder.FFmpeg.NVENC.Preset.p3="Fast (P3)"
+Encoder.FFmpeg.NVENC.Preset.p4="Medium (P4)"
+Encoder.FFmpeg.NVENC.Preset.p5="Slow (P5)"
+Encoder.FFmpeg.NVENC.Preset.p6="Slower (P6)"
+Encoder.FFmpeg.NVENC.Preset.p7="Slowest (P7)"
+Encoder.FFmpeg.NVENC.Tune="Tune"
+Encoder.FFmpeg.NVENC.Tune.hq="High Quality"
+Encoder.FFmpeg.NVENC.Tune.ll="Low Latency"
+Encoder.FFmpeg.NVENC.Tune.ull="Ultra Low Latency"
+Encoder.FFmpeg.NVENC.Tune.lossless="Lossless"
Encoder.FFmpeg.NVENC.RateControl="Rate Control Options"
Encoder.FFmpeg.NVENC.RateControl.Mode="Mode"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="Constant Quantization Parameter"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR="Variable Bitrate"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR_HQ="High Quality Variable Bitrate"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="Constant Bitrate"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_HQ="High Quality Constant Bitrate"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_LD_HQ="Low Delay High Quality Constant Bitrate"
+Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Constant Quantization Parameter"
+Encoder.FFmpeg.NVENC.RateControl.Mode.vbr="Variable Bitrate"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Constant Bitrate"
Encoder.FFmpeg.NVENC.RateControl.TwoPass="Two Pass"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass="Multi-Pass"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.disabled="Single Pass"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.qres="Two Pass at Quarter Resolution"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.fullres="Two Pass at Full Resolution"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Look Ahead"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="Adaptive I-Frames"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveB="Adaptive B-Frames"
@@ -208,12 +221,14 @@ Encoder.FFmpeg.NVENC.AQ.Temporal="Temporal Adaptive Quantization"
Encoder.FFmpeg.NVENC.Other="Other Options"
Encoder.FFmpeg.NVENC.Other.BFrames="Maximum B-Frames"
Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode="B-Frame Reference Mode"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Middle="Use only middle B-Frames as reference"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Each="Use all B-Frames as reference"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.disabled="No B-Frames will be used as Reference"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.middle="Only B-Frames/2 will be used as Reference"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.each="Each B-Frame will be used as Reference"
Encoder.FFmpeg.NVENC.Other.ZeroLatency="Zero Latency"
Encoder.FFmpeg.NVENC.Other.WeightedPrediction="Weighted Prediction"
Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="Non-reference P-Frames"
Encoder.FFmpeg.NVENC.Other.ReferenceFrames="Reference Frames"
+Encoder.FFmpeg.NVENC.Other.LowDelayKeyFrameScale="Low Delay Key-Frame Scale"
# Blur
Blur.Type.Box="Box"
diff --git a/source/encoders/handlers/nvenc_h264_handler.cpp b/source/encoders/handlers/nvenc_h264_handler.cpp
index 24d11d5829..3eeedecd54 100644
--- a/source/encoders/handlers/nvenc_h264_handler.cpp
+++ b/source/encoders/handlers/nvenc_h264_handler.cpp
@@ -45,20 +45,6 @@ extern "C" {
using namespace streamfx::encoder::ffmpeg::handler;
using namespace streamfx::encoder::codec::h264;
-static std::map profiles{
- {profile::BASELINE, "baseline"},
- {profile::MAIN, "main"},
- {profile::HIGH, "high"},
- {profile::HIGH444_PREDICTIVE, "high444p"},
-};
-
-static std::map levels{
- {level::L1_0, "1.0"}, {level::L1_0b, "1.0b"}, {level::L1_1, "1.1"}, {level::L1_2, "1.2"},
- {level::L1_3, "1.3"}, {level::L2_0, "2.0"}, {level::L2_1, "2.1"}, {level::L2_2, "2.2"},
- {level::L3_0, "3.0"}, {level::L3_1, "3.1"}, {level::L3_2, "3.2"}, {level::L4_0, "4.0"},
- {level::L4_1, "4.1"}, {level::L4_2, "4.2"}, {level::L5_0, "5.0"}, {level::L5_1, "5.1"},
-};
-
void nvenc_h264_handler::adjust_info(ffmpeg_factory* fac, const AVCodec*, std::string&, std::string& name, std::string&)
{
name = "NVIDIA NVENC H.264/AVC (via FFmpeg)";
@@ -108,19 +94,13 @@ void nvenc_h264_handler::update(obs_data_t* settings, const AVCodec* codec, AVCo
nvenc::update(settings, codec, context);
if (!context->internal) {
- {
- auto found = profiles.find(static_cast(obs_data_get_int(settings, ST_KEY_PROFILE)));
- if (found != profiles.end()) {
- av_opt_set(context->priv_data, "profile", found->second.c_str(), 0);
- }
+ if (auto value = obs_data_get_int(settings, ST_KEY_PROFILE); value > -1) {
+ av_opt_set_int(context->priv_data, "profile", value, AV_OPT_SEARCH_CHILDREN);
}
- {
- auto found = levels.find(static_cast(obs_data_get_int(settings, ST_KEY_LEVEL)));
- if (found != levels.end()) {
- av_opt_set(context->priv_data, "level", found->second.c_str(), 0);
- } else {
- av_opt_set(context->priv_data, "level", "auto", 0);
- }
+ if (auto value = obs_data_get_int(settings, ST_KEY_LEVEL); value > -1) {
+ av_opt_set_int(context->priv_data, "level", value, AV_OPT_SEARCH_CHILDREN);
+ } else {
+ av_opt_set(context->priv_data, "level", "auto", AV_OPT_SEARCH_CHILDREN);
}
}
}
@@ -143,7 +123,13 @@ void nvenc_h264_handler::log_options(obs_data_t* settings, const AVCodec* codec,
void nvenc_h264_handler::get_encoder_properties(obs_properties_t* props, const AVCodec* codec)
{
- nvenc::get_properties_pre(props, codec);
+ AVCodecContext* context = avcodec_alloc_context3(codec);
+ if (!context->priv_data) {
+ avcodec_free_context(&context);
+ return;
+ }
+
+ nvenc::get_properties_pre(props, codec, context);
{
obs_properties_t* grp = props;
@@ -155,23 +141,27 @@ void nvenc_h264_handler::get_encoder_properties(obs_properties_t* props, const A
{
auto p = obs_properties_add_list(grp, ST_KEY_PROFILE, D_TRANSLATE(S_CODEC_H264_PROFILE),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
- obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), static_cast(profile::UNKNOWN));
- for (auto const kv : profiles) {
- std::string trans = std::string(S_CODEC_H264_PROFILE) + "." + kv.second;
- obs_property_list_add_int(p, D_TRANSLATE(trans.c_str()), static_cast(kv.first));
- }
+ obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), -1);
+ streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "profile", p, S_CODEC_H264_PROFILE);
}
{
auto p = obs_properties_add_list(grp, ST_KEY_LEVEL, D_TRANSLATE(S_CODEC_H264_LEVEL), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
- obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), static_cast(level::UNKNOWN));
- for (auto const kv : levels) {
- obs_property_list_add_int(p, kv.second.c_str(), static_cast(kv.first));
- }
+ obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), 0);
+ streamfx::ffmpeg::tools::avoption_list_add_entries_unnamed(context->priv_data, "level", p,
+ [](const AVOption* opt) {
+ if (opt->default_val.i64 == 0)
+ return true;
+ return false;
+ });
}
}
- nvenc::get_properties_post(props, codec);
+ nvenc::get_properties_post(props, codec, context);
+
+ if (context) {
+ avcodec_free_context(&context);
+ }
}
void nvenc_h264_handler::get_runtime_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context)
diff --git a/source/encoders/handlers/nvenc_hevc_handler.cpp b/source/encoders/handlers/nvenc_hevc_handler.cpp
index 0b1a253c8a..5c3cb7ba88 100644
--- a/source/encoders/handlers/nvenc_hevc_handler.cpp
+++ b/source/encoders/handlers/nvenc_hevc_handler.cpp
@@ -42,23 +42,6 @@ extern "C" {
using namespace streamfx::encoder::ffmpeg::handler;
using namespace streamfx::encoder::codec::hevc;
-static std::map profiles{
- {profile::MAIN, "main"},
- {profile::MAIN10, "main10"},
- {profile::RANGE_EXTENDED, "rext"},
-};
-
-static std::map tiers{
- {tier::MAIN, "main"},
- {tier::HIGH, "high"},
-};
-
-static std::map levels{
- {level::L1_0, "1.0"}, {level::L2_0, "2.0"}, {level::L2_1, "2.1"}, {level::L3_0, "3.0"}, {level::L3_1, "3.1"},
- {level::L4_0, "4.0"}, {level::L4_1, "4.1"}, {level::L5_0, "5.0"}, {level::L5_1, "5.1"}, {level::L5_2, "5.2"},
- {level::L6_0, "6.0"}, {level::L6_1, "6.1"}, {level::L6_2, "6.2"},
-};
-
void nvenc_hevc_handler::adjust_info(ffmpeg_factory* fac, const AVCodec*, std::string&, std::string& name, std::string&)
{
name = "NVIDIA NVENC H.265/HEVC (via FFmpeg)";
@@ -109,25 +92,16 @@ void nvenc_hevc_handler::update(obs_data_t* settings, const AVCodec* codec, AVCo
nvenc::update(settings, codec, context);
if (!context->internal) {
- { // HEVC Options
- auto found = profiles.find(static_cast(obs_data_get_int(settings, ST_KEY_PROFILE)));
- if (found != profiles.end()) {
- av_opt_set(context->priv_data, "profile", found->second.c_str(), 0);
- }
+ if (auto v = obs_data_get_int(settings, ST_KEY_PROFILE); v > -1) {
+ av_opt_set_int(context->priv_data, "profile", v, AV_OPT_SEARCH_CHILDREN);
}
- {
- auto found = tiers.find(static_cast(obs_data_get_int(settings, ST_KEY_TIER)));
- if (found != tiers.end()) {
- av_opt_set(context->priv_data, "tier", found->second.c_str(), 0);
- }
+ if (auto v = obs_data_get_int(settings, ST_KEY_TIER); v > -1) {
+ av_opt_set_int(context->priv_data, "tier", v, AV_OPT_SEARCH_CHILDREN);
}
- {
- auto found = levels.find(static_cast(obs_data_get_int(settings, ST_KEY_LEVEL)));
- if (found != levels.end()) {
- av_opt_set(context->priv_data, "level", found->second.c_str(), 0);
- } else {
- av_opt_set(context->priv_data, "level", "auto", 0);
- }
+ if (auto v = obs_data_get_int(settings, ST_KEY_LEVEL); v > -1) {
+ av_opt_set_int(context->priv_data, "level", v, AV_OPT_SEARCH_CHILDREN);
+ } else {
+ av_opt_set(context->priv_data, "level", "auto", AV_OPT_SEARCH_CHILDREN);
}
}
}
@@ -152,7 +126,13 @@ void nvenc_hevc_handler::log_options(obs_data_t* settings, const AVCodec* codec,
void nvenc_hevc_handler::get_encoder_properties(obs_properties_t* props, const AVCodec* codec)
{
- nvenc::get_properties_pre(props, codec);
+ AVCodecContext* context = avcodec_alloc_context3(codec);
+ if (!context->priv_data) {
+ avcodec_free_context(&context);
+ return;
+ }
+
+ nvenc::get_properties_pre(props, codec, context);
{
obs_properties_t* grp = props;
@@ -164,32 +144,33 @@ void nvenc_hevc_handler::get_encoder_properties(obs_properties_t* props, const A
{
auto p = obs_properties_add_list(grp, ST_KEY_PROFILE, D_TRANSLATE(S_CODEC_HEVC_PROFILE),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
- obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), static_cast(profile::UNKNOWN));
- for (auto const kv : profiles) {
- std::string trans = std::string(S_CODEC_HEVC_PROFILE) + "." + kv.second;
- obs_property_list_add_int(p, D_TRANSLATE(trans.c_str()), static_cast(kv.first));
- }
+ obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), -1);
+ streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "profile", p, S_CODEC_HEVC_PROFILE);
}
{
auto p = obs_properties_add_list(grp, ST_KEY_TIER, D_TRANSLATE(S_CODEC_HEVC_TIER), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
- obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), static_cast(tier::UNKNOWN));
- for (auto const kv : tiers) {
- std::string trans = std::string(S_CODEC_HEVC_TIER) + "." + kv.second;
- obs_property_list_add_int(p, D_TRANSLATE(trans.c_str()), static_cast(kv.first));
- }
+ obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), -1);
+ streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "tier", p, S_CODEC_HEVC_TIER);
}
{
auto p = obs_properties_add_list(grp, ST_KEY_LEVEL, D_TRANSLATE(S_CODEC_HEVC_LEVEL), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
- obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), static_cast(level::UNKNOWN));
- for (auto const kv : levels) {
- obs_property_list_add_int(p, kv.second.c_str(), static_cast(kv.first));
- }
+ obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), 0);
+ streamfx::ffmpeg::tools::avoption_list_add_entries_unnamed(context->priv_data, "level", p,
+ [](const AVOption* opt) {
+ if (opt->default_val.i64 == 0)
+ return true;
+ return false;
+ });
}
}
- nvenc::get_properties_post(props, codec);
+ nvenc::get_properties_post(props, codec, context);
+
+ if (context) {
+ avcodec_free_context(&context);
+ }
}
void nvenc_hevc_handler::get_runtime_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context)
diff --git a/source/encoders/handlers/nvenc_shared.cpp b/source/encoders/handlers/nvenc_shared.cpp
index 7dcafe60ce..4426ac8f1a 100644
--- a/source/encoders/handlers/nvenc_shared.cpp
+++ b/source/encoders/handlers/nvenc_shared.cpp
@@ -33,12 +33,17 @@ extern "C" {
#define ST_I18N_PRESET "Encoder.FFmpeg.NVENC.Preset"
#define ST_I18N_PRESET_(x) ST_I18N_PRESET "." D_VSTR(x)
#define ST_KEY_PRESET "Preset"
+#define ST_I18N_TUNE "Encoder.FFmpeg.NVENC.Tune"
+#define ST_I18N_TUNE_(x) ST_I18N_TUNE "." D_VSTR(x)
+#define ST_KEY_TUNE "Tune"
#define ST_I18N_RATECONTROL "Encoder.FFmpeg.NVENC.RateControl"
#define ST_I18N_RATECONTROL_MODE ST_I18N_RATECONTROL ".Mode"
#define ST_I18N_RATECONTROL_MODE_(x) ST_I18N_RATECONTROL_MODE "." D_VSTR(x)
#define ST_KEY_RATECONTROL_MODE "RateControl.Mode"
#define ST_I18N_RATECONTROL_TWOPASS ST_I18N_RATECONTROL ".TwoPass"
#define ST_KEY_RATECONTROL_TWOPASS "RateControl.TwoPass"
+#define ST_I18N_RATECONTROL_MULTIPASS ST_I18N_RATECONTROL ".MultiPass"
+#define ST_KEY_RATECONTROL_MULTIPASS "RateControl.MultiPass"
#define ST_I18N_RATECONTROL_LOOKAHEAD ST_I18N_RATECONTROL ".LookAhead"
#define ST_KEY_RATECONTROL_LOOKAHEAD "RateControl.LookAhead"
#define ST_I18N_RATECONTROL_ADAPTIVEI ST_I18N_RATECONTROL ".AdaptiveI"
@@ -86,66 +91,25 @@ extern "C" {
#define ST_KEY_OTHER_NONREFERENCEPFRAMES "Other.NonReferencePFrames"
#define ST_I18N_OTHER_REFERENCEFRAMES ST_I18N_OTHER ".ReferenceFrames"
#define ST_KEY_OTHER_REFERENCEFRAMES "Other.ReferenceFrames"
+#define ST_I18N_OTHER_LOWDELAYKEYFRAMESCALE ST_I18N_OTHER ".LowDelayKeyFrameScale"
+#define ST_KEY_OTHER_LOWDELAYKEYFRAMESCALE "Other.LowDelayKeyFrameScale"
using namespace streamfx::encoder::ffmpeg::handler;
-std::map nvenc::presets{
- {nvenc::preset::DEFAULT, ST_I18N_PRESET_(Default)},
- {nvenc::preset::SLOW, ST_I18N_PRESET_(Slow)},
- {nvenc::preset::MEDIUM, ST_I18N_PRESET_(Medium)},
- {nvenc::preset::FAST, ST_I18N_PRESET_(Fast)},
- {nvenc::preset::HIGH_PERFORMANCE, ST_I18N_PRESET_(HighPerformance)},
- {nvenc::preset::HIGH_QUALITY, ST_I18N_PRESET_(HighQuality)},
- {nvenc::preset::BLURAYDISC, ST_I18N_PRESET_(BluRayDisc)},
- {nvenc::preset::LOW_LATENCY, ST_I18N_PRESET_(LowLatency)},
- {nvenc::preset::LOW_LATENCY_HIGH_PERFORMANCE, ST_I18N_PRESET_(LowLatencyHighPerformance)},
- {nvenc::preset::LOW_LATENCY_HIGH_QUALITY, ST_I18N_PRESET_(LowLatencyHighQuality)},
- {nvenc::preset::LOSSLESS, ST_I18N_PRESET_(Lossless)},
- {nvenc::preset::LOSSLESS_HIGH_PERFORMANCE, ST_I18N_PRESET_(LosslessHighPerformance)},
-};
-
-std::map nvenc::preset_to_opt{
- {nvenc::preset::DEFAULT, "default"},
- {nvenc::preset::SLOW, "slow"},
- {nvenc::preset::MEDIUM, "medium"},
- {nvenc::preset::FAST, "fast"},
- {nvenc::preset::HIGH_PERFORMANCE, "hp"},
- {nvenc::preset::HIGH_QUALITY, "hq"},
- {nvenc::preset::BLURAYDISC, "bd"},
- {nvenc::preset::LOW_LATENCY, "ll"},
- {nvenc::preset::LOW_LATENCY_HIGH_PERFORMANCE, "llhp"},
- {nvenc::preset::LOW_LATENCY_HIGH_QUALITY, "llhq"},
- {nvenc::preset::LOSSLESS, "lossless"},
- {nvenc::preset::LOSSLESS_HIGH_PERFORMANCE, "losslesshp"},
-};
-
-std::map nvenc::ratecontrolmodes{
- {nvenc::ratecontrolmode::CQP, ST_I18N_RATECONTROL_MODE_(CQP)},
- {nvenc::ratecontrolmode::VBR, ST_I18N_RATECONTROL_MODE_(VBR)},
- {nvenc::ratecontrolmode::VBR_HQ, ST_I18N_RATECONTROL_MODE_(VBR_HQ)},
- {nvenc::ratecontrolmode::CBR, ST_I18N_RATECONTROL_MODE_(CBR)},
- {nvenc::ratecontrolmode::CBR_HQ, ST_I18N_RATECONTROL_MODE_(CBR_HQ)},
- {nvenc::ratecontrolmode::CBR_LD_HQ, ST_I18N_RATECONTROL_MODE_(CBR_LD_HQ)},
-};
-
-std::map nvenc::ratecontrolmode_to_opt{
- {nvenc::ratecontrolmode::CQP, "constqp"}, {nvenc::ratecontrolmode::VBR, "vbr"},
- {nvenc::ratecontrolmode::VBR_HQ, "vbr_hq"}, {nvenc::ratecontrolmode::CBR, "cbr"},
- {nvenc::ratecontrolmode::CBR_HQ, "cbr_hq"}, {nvenc::ratecontrolmode::CBR_LD_HQ, "cbr_ld_hq"},
-};
-
-std::map nvenc::b_ref_modes{
- {nvenc::b_ref_mode::INVALID, S_STATE_DEFAULT},
- {nvenc::b_ref_mode::DISABLED, S_STATE_DISABLED},
- {nvenc::b_ref_mode::EACH, ST_I18N_OTHER_BFRAMEREFERENCEMODE ".Each"},
- {nvenc::b_ref_mode::MIDDLE, ST_I18N_OTHER_BFRAMEREFERENCEMODE ".Middle"},
-};
-
-std::map nvenc::b_ref_mode_to_opt{
- {nvenc::b_ref_mode::DISABLED, "disabled"},
- {nvenc::b_ref_mode::EACH, "each"},
- {nvenc::b_ref_mode::MIDDLE, "middle"},
-};
+inline bool is_cqp(std::string_view rc)
+{
+ return std::string_view("constqp") == rc;
+}
+
+inline bool is_cbr(std::string_view rc)
+{
+ return std::string_view("cbr") == rc;
+}
+
+inline bool is_vbr(std::string_view rc)
+{
+ return std::string_view("vbr") == rc;
+}
bool streamfx::encoder::ffmpeg::handler::nvenc::is_available()
{
@@ -198,9 +162,9 @@ void nvenc::override_update(ffmpeg_instance* instance, obs_data_t*)
void nvenc::get_defaults(obs_data_t* settings, const AVCodec*, AVCodecContext*)
{
- obs_data_set_default_int(settings, ST_KEY_PRESET, static_cast(nvenc::preset::DEFAULT));
+ obs_data_set_default_int(settings, ST_KEY_PRESET, -1);
- obs_data_set_default_int(settings, ST_KEY_RATECONTROL_MODE, static_cast(ratecontrolmode::CBR_HQ));
+ obs_data_set_default_int(settings, ST_KEY_RATECONTROL_MODE, -1);
obs_data_set_default_int(settings, ST_KEY_RATECONTROL_TWOPASS, -1);
obs_data_set_default_int(settings, ST_KEY_RATECONTROL_LOOKAHEAD, -1);
obs_data_set_default_int(settings, ST_KEY_RATECONTROL_ADAPTIVEI, -1);
@@ -222,11 +186,12 @@ void nvenc::get_defaults(obs_data_t* settings, const AVCodec*, AVCodecContext*)
obs_data_set_default_int(settings, ST_KEY_AQ_TEMPORAL, -1);
obs_data_set_default_int(settings, ST_KEY_OTHER_BFRAMES, -1);
- obs_data_set_default_int(settings, ST_KEY_OTHER_BFRAMEREFERENCEMODE, static_cast(b_ref_mode::INVALID));
+ obs_data_set_default_int(settings, ST_KEY_OTHER_BFRAMEREFERENCEMODE, -1);
obs_data_set_default_int(settings, ST_KEY_OTHER_ZEROLATENCY, -1);
obs_data_set_default_int(settings, ST_KEY_OTHER_WEIGHTEDPREDICTION, -1);
obs_data_set_default_int(settings, ST_KEY_OTHER_NONREFERENCEPFRAMES, -1);
obs_data_set_default_int(settings, ST_KEY_OTHER_REFERENCEFRAMES, -1);
+ obs_data_set_default_int(settings, ST_KEY_OTHER_LOWDELAYKEYFRAMESCALE, -1);
// Replay Buffer
obs_data_set_default_int(settings, "bitrate", 0);
@@ -234,33 +199,29 @@ void nvenc::get_defaults(obs_data_t* settings, const AVCodec*, AVCodecContext*)
static bool modified_ratecontrol(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
{
+ // Decode the name into useful flags.
+ auto value = obs_data_get_int(settings, ST_KEY_RATECONTROL_MODE);
bool have_bitrate = false;
bool have_bitrate_range = false;
bool have_quality = false;
bool have_qp_limits = false;
bool have_qp = false;
-
- nvenc::ratecontrolmode rc =
- static_cast(obs_data_get_int(settings, ST_KEY_RATECONTROL_MODE));
- switch (rc) {
- case nvenc::ratecontrolmode::CQP:
+ if (value == 2) {
+ have_bitrate = true;
+ } else if (value == 1) {
+ have_bitrate = true;
+ have_bitrate_range = true;
+ have_quality = true;
+ have_qp_limits = true;
+ have_qp = true;
+ } else if (value == 0) {
have_qp = true;
- break;
- case nvenc::ratecontrolmode::INVALID:
- case nvenc::ratecontrolmode::CBR:
- case nvenc::ratecontrolmode::CBR_HQ:
- case nvenc::ratecontrolmode::CBR_LD_HQ:
- have_bitrate = true;
- have_qp_limits = true;
- break;
- case nvenc::ratecontrolmode::VBR:
- case nvenc::ratecontrolmode::VBR_HQ:
+ } else {
have_bitrate = true;
have_bitrate_range = true;
have_quality = true;
have_qp_limits = true;
have_qp = true;
- break;
}
obs_property_set_visible(obs_properties_get(props, ST_I18N_RATECONTROL_LIMITS), have_bitrate || have_quality);
@@ -286,16 +247,22 @@ static bool modified_aq(obs_properties_t* props, obs_property_t*, obs_data_t* se
return true;
}
-void nvenc::get_properties_pre(obs_properties_t* props, const AVCodec*)
+void nvenc::get_properties_pre(obs_properties_t* props, const AVCodec*, const AVCodecContext* context)
{
- auto p = obs_properties_add_list(props, ST_KEY_PRESET, D_TRANSLATE(ST_I18N_PRESET), OBS_COMBO_TYPE_LIST,
- OBS_COMBO_FORMAT_INT);
- for (auto kv : presets) {
- obs_property_list_add_int(p, D_TRANSLATE(kv.second.c_str()), static_cast(kv.first));
+ {
+ auto p = obs_properties_add_list(props, ST_KEY_PRESET, D_TRANSLATE(ST_I18N_PRESET), OBS_COMBO_TYPE_LIST,
+ OBS_COMBO_FORMAT_INT);
+ streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "preset", p, ST_I18N_PRESET);
+ }
+
+ if (streamfx::ffmpeg::tools::avoption_exists(context->priv_data, "tune")) {
+ auto p = obs_properties_add_list(props, ST_KEY_TUNE, D_TRANSLATE(ST_I18N_TUNE), OBS_COMBO_TYPE_LIST,
+ OBS_COMBO_FORMAT_INT);
+ streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "tune", p, ST_I18N_TUNE);
}
}
-void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
+void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec, const AVCodecContext* context)
{
{ // Rate Control
obs_properties_t* grp = props;
@@ -309,12 +276,23 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
auto p = obs_properties_add_list(grp, ST_KEY_RATECONTROL_MODE, D_TRANSLATE(ST_I18N_RATECONTROL_MODE),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_set_modified_callback(p, modified_ratecontrol);
- for (auto kv : ratecontrolmodes) {
- obs_property_list_add_int(p, D_TRANSLATE(kv.second.c_str()), static_cast(kv.first));
- }
+ auto filter = [](const AVOption* opt) {
+ if (opt->default_val.i64 & (1 << 23))
+ return true;
+ return false;
+ };
+ streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "rc", p, ST_I18N_RATECONTROL_MODE,
+ filter);
}
- {
+ if (streamfx::ffmpeg::tools::avoption_exists(context->priv_data, "multipass")) {
+ auto p =
+ obs_properties_add_list(grp, ST_KEY_RATECONTROL_MULTIPASS, D_TRANSLATE(ST_I18N_RATECONTROL_MULTIPASS),
+ OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
+ obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), -1);
+ streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "multipass", p,
+ ST_I18N_RATECONTROL_MULTIPASS);
+ } else {
auto p = streamfx::util::obs_properties_add_tristate(grp, ST_KEY_RATECONTROL_TWOPASS,
D_TRANSLATE(ST_I18N_RATECONTROL_TWOPASS));
}
@@ -347,7 +325,7 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
{
auto p = obs_properties_add_float_slider(grp, ST_KEY_RATECONTROL_LIMITS_QUALITY,
- D_TRANSLATE(ST_I18N_RATECONTROL_LIMITS_QUALITY), 0, 100, 0.01);
+ D_TRANSLATE(ST_I18N_RATECONTROL_LIMITS_QUALITY), 0, 51, 0.01);
}
{
@@ -442,13 +420,9 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
auto p = obs_properties_add_list(grp, ST_KEY_OTHER_BFRAMEREFERENCEMODE,
D_TRANSLATE(ST_I18N_OTHER_BFRAMEREFERENCEMODE), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
- for (auto kv : b_ref_modes) {
- if (kv.first == nvenc::b_ref_mode::EACH && (std::string_view("h264_nvenc") == codec->name)) {
- // H.264 does not support using all B-Frames as reference.
- continue;
- }
- obs_property_list_add_int(p, D_TRANSLATE(kv.second.c_str()), static_cast(kv.first));
- }
+ obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), -1);
+ streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "b_ref_mode", p,
+ ST_I18N_OTHER_BFRAMEREFERENCEMODE);
}
{
@@ -472,15 +446,22 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
(strcmp(codec->name, "h264_nvenc") == 0) ? 16 : 4, 1);
obs_property_int_set_suffix(p, " frames");
}
+
+ if (streamfx::ffmpeg::tools::avoption_exists(context->priv_data, "ldkfs")) {
+ auto p = obs_properties_add_int_slider(grp, ST_KEY_OTHER_LOWDELAYKEYFRAMESCALE,
+ D_TRANSLATE(ST_I18N_OTHER_LOWDELAYKEYFRAMESCALE), -1, 255, 1);
+ }
}
}
void nvenc::get_runtime_properties(obs_properties_t* props, const AVCodec*, AVCodecContext*)
{
obs_property_set_enabled(obs_properties_get(props, ST_KEY_PRESET), false);
+ obs_property_set_enabled(obs_properties_get(props, ST_KEY_TUNE), false);
obs_property_set_enabled(obs_properties_get(props, ST_I18N_RATECONTROL), false);
obs_property_set_enabled(obs_properties_get(props, ST_KEY_RATECONTROL_MODE), false);
obs_property_set_enabled(obs_properties_get(props, ST_KEY_RATECONTROL_TWOPASS), false);
+ obs_property_set_enabled(obs_properties_get(props, ST_KEY_RATECONTROL_MULTIPASS), false);
obs_property_set_enabled(obs_properties_get(props, ST_KEY_RATECONTROL_LOOKAHEAD), false);
obs_property_set_enabled(obs_properties_get(props, ST_KEY_RATECONTROL_ADAPTIVEI), false);
obs_property_set_enabled(obs_properties_get(props, ST_KEY_RATECONTROL_ADAPTIVEB), false);
@@ -506,84 +487,91 @@ void nvenc::get_runtime_properties(obs_properties_t* props, const AVCodec*, AVCo
obs_property_set_enabled(obs_properties_get(props, ST_KEY_OTHER_WEIGHTEDPREDICTION), false);
obs_property_set_enabled(obs_properties_get(props, ST_KEY_OTHER_NONREFERENCEPFRAMES), false);
obs_property_set_enabled(obs_properties_get(props, ST_KEY_OTHER_REFERENCEFRAMES), false);
+ obs_property_set_enabled(obs_properties_get(props, ST_KEY_OTHER_LOWDELAYKEYFRAMESCALE), false);
}
void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context)
{
if (!context->internal) {
- preset c_preset = static_cast(obs_data_get_int(settings, ST_KEY_PRESET));
- auto found = preset_to_opt.find(c_preset);
- if (found != preset_to_opt.end()) {
- av_opt_set(context->priv_data, "preset", found->second.c_str(), 0);
- } else {
- av_opt_set(context->priv_data, "preset", nullptr, 0);
+ auto value = obs_data_get_int(settings, ST_KEY_PRESET);
+ if (value != -1) {
+ auto name = streamfx::ffmpeg::tools::avoption_name_from_unit_value(context->priv_data, "preset", value);
+ if (name) {
+ av_opt_set(context->priv_data, "preset", name, AV_OPT_SEARCH_CHILDREN);
+ } else {
+ av_opt_set_int(context->priv_data, "preset", value, AV_OPT_SEARCH_CHILDREN);
+ }
}
}
{ // Rate Control
+ auto value = obs_data_get_int(settings, ST_KEY_RATECONTROL_MODE);
+ auto name = streamfx::ffmpeg::tools::avoption_name_from_unit_value(context->priv_data, "rc", value);
+ if (value != -1) {
+ if (name && !context->internal) {
+ av_opt_set(context->priv_data, "rc", name, AV_OPT_SEARCH_CHILDREN);
+ } else {
+ av_opt_set_int(context->priv_data, "rc", value, AV_OPT_SEARCH_CHILDREN);
+ }
+ }
+
+ // Decode the name into useful flags.
bool have_bitrate = false;
bool have_bitrate_range = false;
bool have_quality = false;
bool have_qp_limits = false;
bool have_qp = false;
+ if (is_cbr(name)) {
+ have_bitrate = true;
- ratecontrolmode rc = static_cast(obs_data_get_int(settings, ST_KEY_RATECONTROL_MODE));
- auto rcopt = ratecontrolmode_to_opt.find(rc);
- if (rcopt != ratecontrolmode_to_opt.end()) {
- if (!context->internal) {
- av_opt_set(context->priv_data, "rc", rcopt->second.c_str(), AV_OPT_SEARCH_CHILDREN);
- }
- } else {
+ if (!context->internal)
+ av_opt_set_int(context->priv_data, "cbr", 1, AV_OPT_SEARCH_CHILDREN);
+
+ // Support for OBS Studio
+ obs_data_set_string(settings, "rate_control", "CBR");
+ } else if (is_vbr(name)) {
have_bitrate = true;
have_bitrate_range = true;
have_quality = true;
have_qp_limits = true;
have_qp = true;
- }
- if (!context->internal) {
- av_opt_set_int(context->priv_data, "cbr", 0, AV_OPT_SEARCH_CHILDREN);
- }
- switch (rc) {
- case ratecontrolmode::CQP:
+ if (!context->internal)
+ av_opt_set_int(context->priv_data, "cbr", 0, AV_OPT_SEARCH_CHILDREN);
+
+ // Support for OBS Studio
+ obs_data_set_string(settings, "rate_control", "VBR");
+ } else if (is_cqp(name)) {
have_qp = true;
- { // Support for OBS Studio
- obs_data_set_string(settings, "rate_control", "CQP");
- }
- break;
- case ratecontrolmode::INVALID:
- case ratecontrolmode::CBR:
- case ratecontrolmode::CBR_HQ:
- case ratecontrolmode::CBR_LD_HQ:
- have_bitrate = true;
- have_qp_limits = true;
- if (!context->internal) {
- av_opt_set_int(context->priv_data, "cbr", 1, AV_OPT_SEARCH_CHILDREN);
- }
+ if (!context->internal)
+ av_opt_set_int(context->priv_data, "cbr", 0, AV_OPT_SEARCH_CHILDREN);
- { // Support for OBS Studio
- obs_data_set_string(settings, "rate_control", "CBR");
- }
- break;
- case ratecontrolmode::VBR:
- case ratecontrolmode::VBR_HQ:
- have_bitrate_range = true;
+ // Support for OBS Studio
+ obs_data_set_string(settings, "rate_control", "CQP");
+ } else {
have_bitrate = true;
+ have_bitrate_range = true;
have_quality = true;
- have_qp = true;
have_qp_limits = true;
+ have_qp = true;
- { // Support for OBS Studio
- obs_data_set_string(settings, "rate_control", "VBR");
- }
- break;
+ if (!context->internal)
+ av_opt_set_int(context->priv_data, "cbr", 0, AV_OPT_SEARCH_CHILDREN);
}
if (!context->internal) {
- // Two Pass
- if (int tp = static_cast(obs_data_get_int(settings, ST_KEY_RATECONTROL_TWOPASS)); tp > -1) {
- av_opt_set_int(context->priv_data, "2pass", tp ? 1 : 0, AV_OPT_SEARCH_CHILDREN);
+ if (streamfx::ffmpeg::tools::avoption_exists(context->priv_data, "multipass")) {
+ // Multi-Pass
+ if (int tp = static_cast(obs_data_get_int(settings, ST_KEY_RATECONTROL_MULTIPASS)); tp > -1) {
+ av_opt_set_int(context->priv_data, "multipass", tp, AV_OPT_SEARCH_CHILDREN);
+ av_opt_set_int(context->priv_data, "2pass", 0, AV_OPT_SEARCH_CHILDREN);
+ }
+ } else {
+ // Two-Pass
+ if (int tp = static_cast(obs_data_get_int(settings, ST_KEY_RATECONTROL_TWOPASS)); tp > -1) {
+ av_opt_set_int(context->priv_data, "2pass", tp ? 1 : 0, AV_OPT_SEARCH_CHILDREN);
+ }
}
// Look Ahead # of Frames
@@ -600,8 +588,7 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
}
// Adaptive B-Frames
- constexpr std::string_view h264_encoder_name = "h264_nvenc";
- if (h264_encoder_name == codec->name) {
+ if (std::string_view("h264_nvenc") == codec->name) {
if (int64_t adapt_b = obs_data_get_int(settings, ST_KEY_RATECONTROL_ADAPTIVEB);
!streamfx::util::is_tristate_default(adapt_b) && (la != 0)) {
av_opt_set_int(context->priv_data, "b_adapt", adapt_b, AV_OPT_SEARCH_CHILDREN);
@@ -661,8 +648,7 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
// Quality Target
if (have_quality) {
- if (double_t v = obs_data_get_double(settings, ST_KEY_RATECONTROL_LIMITS_QUALITY) / 100.0 * 51.0;
- v > 0) {
+ if (double_t v = obs_data_get_double(settings, ST_KEY_RATECONTROL_LIMITS_QUALITY); v > 0) {
av_opt_set_double(context->priv_data, "cq", v, AV_OPT_SEARCH_CHILDREN);
}
} else {
@@ -703,7 +689,7 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
if (!context->internal) { // Other
if (int64_t bf = obs_data_get_int(settings, ST_KEY_OTHER_BFRAMES); bf > -1)
- context->max_b_frames = static_cast(bf);
+ av_opt_set_int(context, "bf", bf, AV_OPT_SEARCH_CHILDREN);
if (int64_t zl = obs_data_get_int(settings, ST_KEY_OTHER_ZEROLATENCY); !streamfx::util::is_tristate_default(zl))
av_opt_set_int(context->priv_data, "zerolatency", zl, AV_OPT_SEARCH_CHILDREN);
@@ -711,7 +697,7 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
!streamfx::util::is_tristate_default(nrp))
av_opt_set_int(context->priv_data, "nonref_p", nrp, AV_OPT_SEARCH_CHILDREN);
if (int64_t v = obs_data_get_int(settings, ST_KEY_OTHER_REFERENCEFRAMES); v > -1)
- context->refs = v;
+ av_opt_set_int(context, "refs", v, AV_OPT_SEARCH_CHILDREN);
int64_t wp = obs_data_get_int(settings, ST_KEY_OTHER_WEIGHTEDPREDICTION);
if ((context->max_b_frames > 0) && streamfx::util::is_tristate_enabled(wp)) {
@@ -721,12 +707,12 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
av_opt_set_int(context->priv_data, "weighted_pred", wp, AV_OPT_SEARCH_CHILDREN);
}
- {
- auto found = b_ref_mode_to_opt.find(
- static_cast(obs_data_get_int(settings, ST_KEY_OTHER_BFRAMEREFERENCEMODE)));
- if (found != b_ref_mode_to_opt.end()) {
- av_opt_set(context->priv_data, "b_ref_mode", found->second.c_str(), AV_OPT_SEARCH_CHILDREN);
- }
+ if (auto v = obs_data_get_int(settings, ST_KEY_OTHER_BFRAMEREFERENCEMODE); v > -1) {
+ av_opt_set_int(context->priv_data, "b_ref_mode", v, AV_OPT_SEARCH_CHILDREN);
+ }
+
+ if (auto v = obs_data_get_int(settings, ST_KEY_OTHER_LOWDELAYKEYFRAMESCALE); v > -1) {
+ av_opt_set_int(context->priv_data, "ldkfs", v, AV_OPT_SEARCH_CHILDREN);
}
}
}
@@ -741,6 +727,8 @@ void nvenc::log_options(obs_data_t*, const AVCodec* codec, AVCodecContext* conte
tools::print_av_option_string2(context, "rc", " Rate Control",
[](int64_t v, std::string_view o) { return std::string(o); });
tools::print_av_option_bool(context, "2pass", " Two Pass");
+ tools::print_av_option_string2(context, "multipass", " Multi-Pass",
+ [](int64_t v, std::string_view o) { return std::string(o); });
tools::print_av_option_int(context, "rc-lookahead", " Look-Ahead", "Frames");
tools::print_av_option_bool(context, "no-scenecut", " Adaptive I-Frames", true);
if (strcmp(codec->name, "h264_nvenc") == 0)
@@ -759,6 +747,8 @@ void nvenc::log_options(obs_data_t*, const AVCodec* codec, AVCodecContext* conte
tools::print_av_option_int(context, "init_qpI", " I-Frame", "");
tools::print_av_option_int(context, "init_qpP", " P-Frame", "");
tools::print_av_option_int(context, "init_qpB", " B-Frame", "");
+ tools::print_av_option_int(context, "qp_cb_offset", " CB Offset", "");
+ tools::print_av_option_int(context, "qp_cr_offset", " CR Offset", "");
tools::print_av_option_int(context, "bf", " B-Frames", "Frames");
tools::print_av_option_string2(context, "b_ref_mode", " Reference Mode",
@@ -783,9 +773,14 @@ void nvenc::log_options(obs_data_t*, const AVCodec* codec, AVCodecContext* conte
tools::print_av_option_bool(context, "strict_gop", " Strict GOP");
tools::print_av_option_bool(context, "aud", " Access Unit Delimiters");
tools::print_av_option_bool(context, "bluray-compat", " Bluray Compatibility");
- if (strcmp(codec->name, "h264_nvenc") == 0)
- tools::print_av_option_bool(context, "a53cc", " A53 Closed Captions");
+ tools::print_av_option_bool(context, "a53cc", " A53 Closed Captions");
tools::print_av_option_int(context, "dpb_size", " DPB Size", "Frames");
+ tools::print_av_option_int(context, "ldkfs", " DPB Size", "Frames");
+ tools::print_av_option_bool(context, "extra_sei", " Extra SEI Data");
+ tools::print_av_option_bool(context, "udu_sei", " User SEI Data");
+ tools::print_av_option_bool(context, "intra-refresh", " Intra-Refresh");
+ tools::print_av_option_bool(context, "single-slice-intra-refresh", " Single Slice Intra-Refresh");
+ tools::print_av_option_bool(context, "constrained-encoding", " Constrained Encoding");
}
void streamfx::encoder::ffmpeg::handler::nvenc::migrate(obs_data_t* settings, uint64_t version, const AVCodec* codec,
@@ -814,5 +809,31 @@ void streamfx::encoder::ffmpeg::handler::nvenc::migrate(obs_data_t* settings, ui
obs_data_unset_user_value(settings, "Other.DecodedPictureBufferSize");
}
+ if (version < STREAMFX_MAKE_VERSION(0, 11, 1, 0)) {
+ if (auto v = obs_data_get_int(settings, ST_KEY_RATECONTROL_MODE); v != -1) {
+ switch (v) {
+ case 0: // CQP
+ break;
+ case 2: // VBR_HQ
+ obs_data_set_int(settings, ST_KEY_RATECONTROL_MODE, 1);
+ obs_data_set_int(settings, ST_KEY_RATECONTROL_TWOPASS, 1);
+ obs_data_set_int(settings, ST_KEY_RATECONTROL_MULTIPASS, 1);
+ case 1: // VBR
+ break;
+ case 5: // CBR_LD_HQ
+ obs_data_set_int(settings, ST_KEY_OTHER_LOWDELAYKEYFRAMESCALE, 1);
+ case 4: // CBR_HQ
+ obs_data_set_int(settings, ST_KEY_RATECONTROL_MODE, 2);
+ obs_data_set_int(settings, ST_KEY_RATECONTROL_TWOPASS, 1);
+ obs_data_set_int(settings, ST_KEY_RATECONTROL_MULTIPASS, 1);
+ case 3: // CBR
+ break;
+ }
+ }
+ if (auto v = obs_data_get_double(settings, ST_KEY_RATECONTROL_LIMITS_QUALITY); v > 0) {
+ obs_data_set_double(settings, ST_KEY_RATECONTROL_LIMITS_QUALITY, (v / 100.) * 51.);
+ }
+ }
+
#undef COPY_UNSET
}
diff --git a/source/encoders/handlers/nvenc_shared.hpp b/source/encoders/handlers/nvenc_shared.hpp
index cea4d38510..08288b27cc 100644
--- a/source/encoders/handlers/nvenc_shared.hpp
+++ b/source/encoders/handlers/nvenc_shared.hpp
@@ -42,63 +42,15 @@ extern "C" {
*/
namespace streamfx::encoder::ffmpeg::handler::nvenc {
- enum class preset : int64_t {
- DEFAULT,
- SLOW,
- MEDIUM,
- FAST,
- HIGH_PERFORMANCE,
- HIGH_QUALITY,
- BLURAYDISC,
- LOW_LATENCY,
- LOW_LATENCY_HIGH_PERFORMANCE,
- LOW_LATENCY_HIGH_QUALITY,
- LOSSLESS,
- LOSSLESS_HIGH_PERFORMANCE,
- // Append things before this.
- INVALID = -1,
- };
-
- enum class ratecontrolmode : int64_t {
- CQP,
- VBR,
- VBR_HQ,
- CBR,
- CBR_HQ,
- CBR_LD_HQ,
- // Append things before this.
- INVALID = -1,
- };
-
- enum class b_ref_mode : int64_t {
- DISABLED,
- EACH,
- MIDDLE,
- // Append things before this.
- INVALID = -1,
- };
-
- extern std::map presets;
-
- extern std::map preset_to_opt;
-
- extern std::map ratecontrolmodes;
-
- extern std::map ratecontrolmode_to_opt;
-
- extern std::map b_ref_modes;
-
- extern std::map b_ref_mode_to_opt;
-
bool is_available();
void override_update(ffmpeg_instance* instance, obs_data_t* settings);
void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context);
- void get_properties_pre(obs_properties_t* props, const AVCodec* codec);
+ void get_properties_pre(obs_properties_t* props, const AVCodec* codec, const AVCodecContext* context);
- void get_properties_post(obs_properties_t* props, const AVCodec* codec);
+ void get_properties_post(obs_properties_t* props, const AVCodec* codec, const AVCodecContext* context);
void get_runtime_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context);
From 0da1e77b22da9d372e1409c921a80ec396a518b2 Mon Sep 17 00:00:00 2001
From: Xaymar
Date: Fri, 18 Feb 2022 05:19:42 +0100
Subject: [PATCH 005/164] locale: New Crowdin updates (#772)
* New translations en-US.ini (Portuguese, Brazilian)
* New translations en-US.ini (Portuguese, Brazilian)
* New translations en-US.ini (Japanese)
* New translations en-US.ini (Portuguese, Brazilian)
* New translations en-US.ini (Thai)
* New translations en-US.ini (Turkish)
* New translations en-US.ini (Chinese Simplified)
* New translations en-US.ini (Chinese Traditional)
* New translations en-US.ini (Russian)
* New translations en-US.ini (English, United Kingdom)
* New translations en-US.ini (Portuguese)
* New translations en-US.ini (Japanese)
* New translations en-US.ini (Romanian)
* New translations en-US.ini (French)
* New translations en-US.ini (Spanish)
* New translations en-US.ini (Arabic)
* New translations en-US.ini (Czech)
* New translations en-US.ini (German)
* New translations en-US.ini (Finnish)
* New translations en-US.ini (Polish)
* New translations en-US.ini (Hungarian)
* New translations en-US.ini (Italian)
* New translations en-US.ini (Korean)
* New translations en-US.ini (Dutch)
* New translations en-US.ini (Norwegian)
* New translations en-US.ini (Romanian)
* New translations en-US.ini (Hungarian)
* New translations en-US.ini (Hungarian)
* New translations en-US.ini (Romanian)
* New translations en-US.ini (Italian)
* New translations en-US.ini (Russian)
* New translations en-US.ini (Italian)
* New translations en-US.ini (Russian)
* New translations en-US.ini (Russian)
* New translations en-US.ini (Russian)
---
data/locale/ar-SA.ini | 2 +-
data/locale/cs-CZ.ini | 2 +-
data/locale/de-DE.ini | 27 +++--------
data/locale/en-GB.ini | 12 ++---
data/locale/es-ES.ini | 27 +++--------
data/locale/fi-FI.ini | 2 +-
data/locale/fr-FR.ini | 27 +++--------
data/locale/hu-HU.ini | 108 ++++++++++++++++++++++++++++++++++++++++--
data/locale/it-IT.ini | 55 +++++++++++++--------
data/locale/ja-JP.ini | 29 ++++--------
data/locale/ko-KR.ini | 2 +-
data/locale/nl-NL.ini | 27 +++--------
data/locale/no-NO.ini | 12 ++---
data/locale/pl-PL.ini | 27 +++--------
data/locale/pt-BR.ini | 48 ++++++++++++++++---
data/locale/pt-PT.ini | 8 ++--
data/locale/ro-RO.ini | 33 ++++++++++---
data/locale/ru-RU.ini | 55 +++++++++++++--------
data/locale/th-TH.ini | 6 +--
data/locale/tr-TR.ini | 14 ++----
data/locale/zh-CN.ini | 27 +++--------
data/locale/zh-TW.ini | 2 +-
22 files changed, 322 insertions(+), 230 deletions(-)
diff --git a/data/locale/ar-SA.ini b/data/locale/ar-SA.ini
index de2b5b8539..d02fff4231 100644
--- a/data/locale/ar-SA.ini
+++ b/data/locale/ar-SA.ini
@@ -52,7 +52,7 @@ Encoder.AOM.AV1.RateControl.Buffer.Size="الحجم"
-Encoder.FFmpeg.NVENC.Preset.Default="افتراضي"
+Encoder.FFmpeg.NVENC.Preset.default="افتراضي"
Blur.Type.Box="صندوق"
Blur.Type.BoxLinear="صندوق خطي"
diff --git a/data/locale/cs-CZ.ini b/data/locale/cs-CZ.ini
index 4c86d837d5..db006016b4 100644
--- a/data/locale/cs-CZ.ini
+++ b/data/locale/cs-CZ.ini
@@ -70,7 +70,7 @@ Encoder.FFmpeg.AMF.RateControl.QP.B="QP B-snímků"
Encoder.FFmpeg.AMF.Other="Ostatní možnosti"
Encoder.FFmpeg.NVENC.Preset="Profil"
-Encoder.FFmpeg.NVENC.Preset.Default="Výchozí"
+Encoder.FFmpeg.NVENC.Preset.default="Výchozí"
Encoder.FFmpeg.NVENC.RateControl.Limits.BufferSize="Velikost vyrovnávací paměti"
Encoder.FFmpeg.NVENC.RateControl.Limits.Bitrate.Target="Cílový bitrate"
Encoder.FFmpeg.NVENC.RateControl.Limits.Bitrate.Maximum="Maximální bitrate"
diff --git a/data/locale/de-DE.ini b/data/locale/de-DE.ini
index 9de7cd6709..b72fd4f560 100644
--- a/data/locale/de-DE.ini
+++ b/data/locale/de-DE.ini
@@ -154,26 +154,15 @@ Encoder.FFmpeg.AMF.Other.VBAQ="VBAQ"
Encoder.FFmpeg.AMF.Other.AccessUnitDelimiter="Zugriffseinheitabgrenzer"
Encoder.FFmpeg.NVENC.Preset="Voreinstellung"
-Encoder.FFmpeg.NVENC.Preset.Default="Standard"
-Encoder.FFmpeg.NVENC.Preset.Slow="Langsam"
-Encoder.FFmpeg.NVENC.Preset.Medium="Mittel"
-Encoder.FFmpeg.NVENC.Preset.Fast="Schnell"
-Encoder.FFmpeg.NVENC.Preset.HighPerformance="Hohe Leistung"
-Encoder.FFmpeg.NVENC.Preset.HighQuality="Hohe Qualität"
-Encoder.FFmpeg.NVENC.Preset.BluRayDisc="BluRay Disc"
-Encoder.FFmpeg.NVENC.Preset.LowLatency="Niedrige Latenz"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighPerformance="Niedrige Latenz, Hohe Leistung"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighQuality="Niedrige Latenz, Hohe Qualität"
-Encoder.FFmpeg.NVENC.Preset.Lossless="Verlustfrei"
-Encoder.FFmpeg.NVENC.Preset.LosslessHighPerformance="Verlusfrei, Hohe Leistung"
+Encoder.FFmpeg.NVENC.Preset.default="Standard"
+Encoder.FFmpeg.NVENC.Preset.slow="Langsam"
+Encoder.FFmpeg.NVENC.Preset.medium="Mittel"
+Encoder.FFmpeg.NVENC.Preset.fast="Schnell"
+Encoder.FFmpeg.NVENC.Tune="Justierung"
Encoder.FFmpeg.NVENC.RateControl="Ratenkontrollmethode"
Encoder.FFmpeg.NVENC.RateControl.Mode="Modus"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="Parameter für Konstante Quantisierung"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR="Variable Bitrate"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR_HQ="Hohe Qualität, Variable Bitrate"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="Konstante Bitrate"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_HQ="Hohe Qualität, Konstante Bitrate"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_LD_HQ="Niedrige Latenz, Hohe Qualität, Konstante Bitrate"
+Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Parameter für Konstante Quantisierung"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Konstante Bitrate"
Encoder.FFmpeg.NVENC.RateControl.TwoPass="Zwei Durchläufe"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Vorausschauen"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="Adaptive I-Frames"
@@ -196,8 +185,6 @@ Encoder.FFmpeg.NVENC.AQ.Temporal="Zeitlich-adaptive Quantisierung"
Encoder.FFmpeg.NVENC.Other="Weitere Optionen"
Encoder.FFmpeg.NVENC.Other.BFrames="Maximale B‐Bilder"
Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode="B-Bild Referenzmodus"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Middle="Benutze nur mittlere B-Bilder als Referenz"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Each="Benutze alle B-Bilder als Referenz"
Encoder.FFmpeg.NVENC.Other.ZeroLatency="Null Latenz"
Encoder.FFmpeg.NVENC.Other.WeightedPrediction="Gewichtete Vorhersage"
Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="Nicht-referenzierte P-Bilder"
diff --git a/data/locale/en-GB.ini b/data/locale/en-GB.ini
index 27682c9aec..d70412f10e 100644
--- a/data/locale/en-GB.ini
+++ b/data/locale/en-GB.ini
@@ -86,14 +86,14 @@ Encoder.FFmpeg.AMF.Other.BFrames="Maximum B-Frames"
Encoder.FFmpeg.AMF.Other.ReferenceFrames="Reference Frames"
Encoder.FFmpeg.NVENC.Preset="Preset"
-Encoder.FFmpeg.NVENC.Preset.Default="Default"
-Encoder.FFmpeg.NVENC.Preset.Slow="Slow"
-Encoder.FFmpeg.NVENC.Preset.Medium="Medium"
-Encoder.FFmpeg.NVENC.Preset.Fast="Fast"
+Encoder.FFmpeg.NVENC.Preset.default="Default"
+Encoder.FFmpeg.NVENC.Preset.slow="Slow"
+Encoder.FFmpeg.NVENC.Preset.medium="Medium"
+Encoder.FFmpeg.NVENC.Preset.fast="Fast"
Encoder.FFmpeg.NVENC.RateControl="Rate Control Options"
Encoder.FFmpeg.NVENC.RateControl.Mode="Mode"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="Constant Quantisation Parameter"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="Constant Bitrate"
+Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Constant Quantisation Parameter"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Constant Bitrate"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Look Ahead"
Encoder.FFmpeg.NVENC.RateControl.Limits="Limits"
Encoder.FFmpeg.NVENC.RateControl.Limits.BufferSize="Buffer Size"
diff --git a/data/locale/es-ES.ini b/data/locale/es-ES.ini
index dde1cf53d0..a5bd1b2433 100644
--- a/data/locale/es-ES.ini
+++ b/data/locale/es-ES.ini
@@ -154,26 +154,15 @@ Encoder.FFmpeg.AMF.Other.VBAQ="VBAQ"
Encoder.FFmpeg.AMF.Other.AccessUnitDelimiter="Delimitador de Unidad de Acceso"
Encoder.FFmpeg.NVENC.Preset="Preajuste"
-Encoder.FFmpeg.NVENC.Preset.Default="Por defecto"
-Encoder.FFmpeg.NVENC.Preset.Slow="Lento"
-Encoder.FFmpeg.NVENC.Preset.Medium="Medio"
-Encoder.FFmpeg.NVENC.Preset.Fast="Rápido"
-Encoder.FFmpeg.NVENC.Preset.HighPerformance="Alto rendimiento"
-Encoder.FFmpeg.NVENC.Preset.HighQuality="Alta calidad"
-Encoder.FFmpeg.NVENC.Preset.BluRayDisc="Disco BluRay"
-Encoder.FFmpeg.NVENC.Preset.LowLatency="Baja latencia"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighPerformance="Baja latencia alto rendimiento"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighQuality="Baja latencia alta calidad"
-Encoder.FFmpeg.NVENC.Preset.Lossless="Sin pérdidas"
-Encoder.FFmpeg.NVENC.Preset.LosslessHighPerformance="Sin pérdida alto rendimiento"
+Encoder.FFmpeg.NVENC.Preset.default="Por defecto"
+Encoder.FFmpeg.NVENC.Preset.slow="Lento"
+Encoder.FFmpeg.NVENC.Preset.medium="Medio"
+Encoder.FFmpeg.NVENC.Preset.fast="Rápido"
+Encoder.FFmpeg.NVENC.Tune="Sintonizar"
Encoder.FFmpeg.NVENC.RateControl="Opciones de control de flujo"
Encoder.FFmpeg.NVENC.RateControl.Mode="Modo"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="Parámetro de Cuantización Constante"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR="Bitrate variable"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR_HQ="Bitrate Variable de alta calidad"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="Bitrate constante"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_HQ="Bitrate constante de alta calidad"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_LD_HQ="Bitrate constante de alta calidad con bajo retardo"
+Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Parámetro de Cuantización Constante"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Bitrate constante"
Encoder.FFmpeg.NVENC.RateControl.TwoPass="Dos pasos"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Look Ahead"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="I-Frames adaptativos"
@@ -196,8 +185,6 @@ Encoder.FFmpeg.NVENC.AQ.Temporal="Cuantización adaptativa temporal"
Encoder.FFmpeg.NVENC.Other="Otras opciones"
Encoder.FFmpeg.NVENC.Other.BFrames="B-Frames máximos"
Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode="Modo de referencia de B-Frame"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Middle="Usar solo B-Frames medios como referencia"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Each="Usar todos los B-Frames como referencia"
Encoder.FFmpeg.NVENC.Other.ZeroLatency="Latencia cero"
Encoder.FFmpeg.NVENC.Other.WeightedPrediction="Predicción ponderada"
Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="P-Frames sin referencia"
diff --git a/data/locale/fi-FI.ini b/data/locale/fi-FI.ini
index f946159af4..1a77b3b60b 100644
--- a/data/locale/fi-FI.ini
+++ b/data/locale/fi-FI.ini
@@ -49,7 +49,7 @@ UI.Updater.Menu.Channel.Testing="Testaus"
-Encoder.FFmpeg.NVENC.Preset.Default="Oletus"
+Encoder.FFmpeg.NVENC.Preset.default="Oletus"
Blur.Type.Box="Kuutiollinen"
Blur.Type.BoxLinear="Kuutio lineaarinen"
diff --git a/data/locale/fr-FR.ini b/data/locale/fr-FR.ini
index fa8ba1c2a6..e0d373e232 100644
--- a/data/locale/fr-FR.ini
+++ b/data/locale/fr-FR.ini
@@ -153,26 +153,15 @@ Encoder.FFmpeg.AMF.Other.EnforceHRD="Forcer le HRD"
Encoder.FFmpeg.AMF.Other.VBAQ="VBAQ"
Encoder.FFmpeg.NVENC.Preset="Préréglage"
-Encoder.FFmpeg.NVENC.Preset.Default="Par défaut"
-Encoder.FFmpeg.NVENC.Preset.Slow="Lent"
-Encoder.FFmpeg.NVENC.Preset.Medium="Moyen"
-Encoder.FFmpeg.NVENC.Preset.Fast="Rapide"
-Encoder.FFmpeg.NVENC.Preset.HighPerformance="Haute Performance"
-Encoder.FFmpeg.NVENC.Preset.HighQuality="Haute Qualité"
-Encoder.FFmpeg.NVENC.Preset.BluRayDisc="Disque BluRay"
-Encoder.FFmpeg.NVENC.Preset.LowLatency="Latence faible"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighPerformance="Latence faible haute performance"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighQuality="Latence faible haute qualité"
-Encoder.FFmpeg.NVENC.Preset.Lossless="Sans pertes"
-Encoder.FFmpeg.NVENC.Preset.LosslessHighPerformance="Sans pertes haute performance"
+Encoder.FFmpeg.NVENC.Preset.default="Par défaut"
+Encoder.FFmpeg.NVENC.Preset.slow="Lent"
+Encoder.FFmpeg.NVENC.Preset.medium="Moyen"
+Encoder.FFmpeg.NVENC.Preset.fast="Rapide"
+Encoder.FFmpeg.NVENC.Tune="Ajustement"
Encoder.FFmpeg.NVENC.RateControl="Options de contrôle du débit"
Encoder.FFmpeg.NVENC.RateControl.Mode="Mode"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="Paramètre de quantification constante"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR="Débit variable"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR_HQ="Débit variable haute qualité"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="Débit constant"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_HQ="Débit constant haute qualité"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_LD_HQ="Débit constant haute qualité à faible délai"
+Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Paramètre de quantification constante"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Débit constant"
Encoder.FFmpeg.NVENC.RateControl.TwoPass="Deux passes"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Prédiction (Look-ahead)"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="I-Frames adaptatives"
@@ -195,8 +184,6 @@ Encoder.FFmpeg.NVENC.AQ.Temporal="Quantification adaptative temporelle"
Encoder.FFmpeg.NVENC.Other="Autres Options"
Encoder.FFmpeg.NVENC.Other.BFrames="B-Frames maximum"
Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode="Mode de référence B-Frame"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Middle="Utiliser uniquement les B-Frames du milieu comme référence"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Each="Utiliser toutes les B-Frames comme référence"
Encoder.FFmpeg.NVENC.Other.ZeroLatency="Zéro Latence"
Encoder.FFmpeg.NVENC.Other.WeightedPrediction="Prédiction pondérée"
Encoder.FFmpeg.NVENC.Other.ReferenceFrames="Cadres de référence"
diff --git a/data/locale/hu-HU.ini b/data/locale/hu-HU.ini
index 00ae033aa6..60a4ba06f7 100644
--- a/data/locale/hu-HU.ini
+++ b/data/locale/hu-HU.ini
@@ -1,4 +1,5 @@
Advanced="Haladó beállítások"
+Manual.Open="Kézikönyv megnyitása"
Channel.Red="Piros"
Channel.Green="Zöld"
@@ -24,29 +25,124 @@ State.Automatic="Automatikus"
State.Default="Alapértelmezett"
UI.Menu="StreamFX"
+UI.Menu.Wiki="Olvasd el a Wikin"
+UI.Menu.Support="Súgó és támogatás"
+UI.Menu.Website="Tovább a StreamFX weboldalra"
+UI.Menu.Discord="Csatlakozz a StreamFX-hez Discordon"
+UI.Menu.Twitter="Kövesd a StreamFX-et Twitteren"
+UI.Menu.YouTube="Iratkozz fel a StreamFX YouTube-jára"
UI.Menu.About="StreamFX névjegye"
UI.About.Title="StreamFX névjegye"
+UI.About.Text="A StreamFX elkészülését a támogatások teszik lehetővé. Adakozz Patreonon, GitHub Sponzor, vagy PayPalon. Külön köszönet a fordítóknak, akik a Crowdinen segítik a fordításokat! Mind különlegesek vagytok!
"
UI.About.Role.Contributor="Közreműködő"
UI.About.Role.Translator="Fordító"
UI.About.Role.Supporter="Támogató"
UI.About.Version="Verzió:"
UI.Updater.Dialog.Title="StreamFX verzió %s már elérhető!"
+UI.Updater.Dialog.Text="A StreamFX új verziója elérhető."
UI.Updater.Dialog.Version.Current="Jelenlegi verzió:"
UI.Updater.Dialog.Version.Latest="Legújabb verzió:"
UI.Updater.Dialog.Button.Ok="Letöltési oldal megnyitása"
UI.Updater.Dialog.Button.Cancel="Emlékeztess később"
+UI.Updater.GitHubPermission.Title="A StreamFX-nek szüksége van a hozzájárulásodhoz, hogy a GitHubhoz csatlakozzon!"
+UI.Updater.GitHubPermission.Text="A StreamFX a GitHub API-t használja az új kiadások manuális és automatikus letöltséhez.
Kérlek olvasd el a Github Privacy Statement-et, és kattints az 'OK' gombra, ha egyetérteszz, vagy a 'Mégse' gombra, ha nem."
UI.Updater.Menu.CheckForUpdates="Frissítések ellenőrzése"
UI.Updater.Menu.CheckForUpdates.Automatically="Automatikusan ellenőrizze a frissítéseket"
UI.Updater.Menu.Channel="Frissítési csatorna"
-
+UI.Updater.Menu.Channel.Release="Stabil kiadás"
+UI.Updater.Menu.Channel.Testing="Tesztelendő kiadás"
+
+Encoder.AOM.AV1="AOM AV1 (direkt)"
+Encoder.AOM.AV1.Encoder="Kódoló"
+Encoder.AOM.AV1.Encoder.Usage="Használat"
+Encoder.AOM.AV1.Encoder.Usage.GoodQuality="Jó minőség"
+Encoder.AOM.AV1.Encoder.Usage.RealTime="Valós idejű"
+Encoder.AOM.AV1.Encoder.Usage.AllIntra="Minden köztes-kocka"
+Encoder.AOM.AV1.Encoder.CPUUsage="Processzorhasználat"
+Encoder.AOM.AV1.Encoder.CPUUsage.0="Placebo"
+Encoder.AOM.AV1.Encoder.CPUUsage.1="Nagyon lassú"
+Encoder.AOM.AV1.Encoder.CPUUsage.2="Lassabb"
+Encoder.AOM.AV1.Encoder.CPUUsage.3="Lassú"
+Encoder.AOM.AV1.Encoder.CPUUsage.4="Közepes"
+Encoder.AOM.AV1.Encoder.CPUUsage.5="Gyors"
+Encoder.AOM.AV1.Encoder.CPUUsage.6="Gyorsabb"
+Encoder.AOM.AV1.Encoder.CPUUsage.7="Nagyon gyors"
+Encoder.AOM.AV1.Encoder.CPUUsage.8="Szupergyors"
+Encoder.AOM.AV1.Encoder.CPUUsage.9="Ultragyors"
+Encoder.AOM.AV1.Encoder.CPUUsage.10="Borzasztó Gyors"
Encoder.AOM.AV1.Encoder.Profile="Profil"
+Encoder.AOM.AV1.KeyFrames="Kulcs-kocka"
+Encoder.AOM.AV1.KeyFrames.IntervalType="Időtartam egysége"
+Encoder.AOM.AV1.KeyFrames.IntervalType.Frames="Képkocka"
+Encoder.AOM.AV1.KeyFrames.IntervalType.Seconds="Másodperc"
+Encoder.AOM.AV1.KeyFrames.Interval="Időköz"
+Encoder.AOM.AV1.RateControl="Sebesség vezérlés"
+Encoder.AOM.AV1.RateControl.Mode="Mód"
+Encoder.AOM.AV1.RateControl.Mode.CBR="Konstans bitsebesség (CBR)"
+Encoder.AOM.AV1.RateControl.Mode.VBR="Változó bitsebesség (VBR)"
+Encoder.AOM.AV1.RateControl.Mode.CQ="Korlátozott Minőség (CQ)"
+Encoder.AOM.AV1.RateControl.Mode.Q="Állandó Minőség (Q)"
+Encoder.AOM.AV1.RateControl.LookAhead="Előretekintés"
+Encoder.AOM.AV1.RateControl.Limits="Korlátok"
+Encoder.AOM.AV1.RateControl.Limits.Bitrate="Bitsebesség"
+Encoder.AOM.AV1.RateControl.Limits.Bitrate.Undershoot="Bitsebesség alsó korlát"
+Encoder.AOM.AV1.RateControl.Limits.Bitrate.Overshoot="Bitsebesség felső korlát"
+Encoder.AOM.AV1.RateControl.Limits.Quality="Minőség"
+Encoder.AOM.AV1.RateControl.Limits.Quantizer.Minimum="Minimum kvantálás"
+Encoder.AOM.AV1.RateControl.Limits.Quantizer.Maximum="Maximum kvantálás"
Encoder.AOM.AV1.RateControl.Buffer.Size="Méret"
-
-
-Encoder.FFmpeg.NVENC.Preset.Default="Alapértelmezett"
+Encoder.FFmpeg.KeyFrames.IntervalType="Időtartam egysége"
+Encoder.FFmpeg.KeyFrames.IntervalType.Frames="Képkocka"
+Encoder.FFmpeg.KeyFrames.IntervalType.Seconds="Másodperc"
+Encoder.FFmpeg.KeyFrames.Interval="Időköz"
+
+Encoder.FFmpeg.AMF.Preset="Alapbeállítások"
+Encoder.FFmpeg.AMF.Preset.Quality="Minőség"
+Encoder.FFmpeg.AMF.RateControl="Sebesség vezérlés beállítások"
+Encoder.FFmpeg.AMF.RateControl.Mode="Mód"
+Encoder.FFmpeg.AMF.RateControl.LookAhead="Előretekintés"
+Encoder.FFmpeg.AMF.RateControl.Limits="Korlátok"
+
+Encoder.FFmpeg.NVENC.Preset="Alapbeállítások"
+Encoder.FFmpeg.NVENC.Preset.default="Alapértelmezett"
+Encoder.FFmpeg.NVENC.Preset.slow="Lassú"
+Encoder.FFmpeg.NVENC.Preset.medium="Közepes"
+Encoder.FFmpeg.NVENC.Preset.fast="Gyors"
+Encoder.FFmpeg.NVENC.Preset.hp="Nagy teljesítmény"
+Encoder.FFmpeg.NVENC.Preset.hq="Magas minőség"
+Encoder.FFmpeg.NVENC.Preset.bd="BluRay Lemez"
+Encoder.FFmpeg.NVENC.Preset.ll="Alacsony-késleltetés"
+Encoder.FFmpeg.NVENC.Preset.llhq="Alacsony-késleltetés magas minőséggel"
+Encoder.FFmpeg.NVENC.Preset.llhp="Alacsony-késleltetés nagy teljesítmény"
+Encoder.FFmpeg.NVENC.Preset.lossless="Veszteségmentes"
+Encoder.FFmpeg.NVENC.Preset.losslesshp="Veszteségmentes nagy teljesítmény"
+Encoder.FFmpeg.NVENC.Preset.p1="Leggyorsabb (P1)"
+Encoder.FFmpeg.NVENC.Preset.p2="Gyorsabb (P2)"
+Encoder.FFmpeg.NVENC.Preset.p3="Gyors (P3)"
+Encoder.FFmpeg.NVENC.Preset.p4="Közepes (P4)"
+Encoder.FFmpeg.NVENC.Preset.p5="Lassú (P5)"
+Encoder.FFmpeg.NVENC.Preset.p6="Lassabb (P6)"
+Encoder.FFmpeg.NVENC.Preset.p7="Leglassabb (P7)"
+Encoder.FFmpeg.NVENC.Tune="Hangolás"
+Encoder.FFmpeg.NVENC.Tune.hq="Magas minőség"
+Encoder.FFmpeg.NVENC.Tune.ll="Alacsony-késleltetés"
+Encoder.FFmpeg.NVENC.Tune.ull="Nagyon alacsony késleltetés"
+Encoder.FFmpeg.NVENC.Tune.lossless="Veszteségmentes"
+Encoder.FFmpeg.NVENC.RateControl="Sebesség vezérlés beállítások"
+Encoder.FFmpeg.NVENC.RateControl.Mode="Mód"
+Encoder.FFmpeg.NVENC.RateControl.Mode.vbr="Változó bitsebesség"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Állandó bitsebesség"
+Encoder.FFmpeg.NVENC.RateControl.TwoPass="Két fázisú"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass="Több fázisú"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.disabled="Egy fázisú"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.qres="Két fázisú - negyed felbontáson"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.fullres="Két fázisú - teljes felbontáson"
+Encoder.FFmpeg.NVENC.RateControl.LookAhead="Előretekintés"
+Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="Adaptív közteskockák"
+Encoder.FFmpeg.NVENC.RateControl.Limits="Korlátok"
Shader.Shader.File="Fájl"
@@ -59,6 +155,7 @@ Shader.Parameter.Texture.Type.Source="Forrás"
Shader.Parameter.Texture.File="Fájl"
Shader.Parameter.Texture.Source="Forrás"
+Filter.AutoFraming.Tracking.Mode="Mód"
Filter.Blur.Type="Típus"
Filter.Blur.Size="Méret"
@@ -75,6 +172,7 @@ Filter.Displacement.File="Fájl"
Filter.Transform.Camera="Kamera"
+Filter.Transform.Camera.Mode="Mód"
Filter.Transform.Position="Pozíció"
Filter.Transform.Position.X="X"
Filter.Transform.Position.Y="Y"
@@ -85,6 +183,8 @@ Filter.Transform.Shear.X="X"
Filter.Transform.Shear.Y="Y"
+Filter.VirtualGreenscreen.NVIDIA.Greenscreen.Mode="Mód"
+Filter.VirtualGreenscreen.NVIDIA.Greenscreen.Mode.Quality="Minőség"
Source.Mirror.Source="Forrás"
diff --git a/data/locale/it-IT.ini b/data/locale/it-IT.ini
index ae7fb4d169..72cea44bfc 100644
--- a/data/locale/it-IT.ini
+++ b/data/locale/it-IT.ini
@@ -154,27 +154,40 @@ Encoder.FFmpeg.AMF.Other.VBAQ="VBAQ"
Encoder.FFmpeg.AMF.Other.AccessUnitDelimiter="Delimitatore Unità Di Accesso"
Encoder.FFmpeg.NVENC.Preset="Preimpostazioni"
-Encoder.FFmpeg.NVENC.Preset.Default="Predefinito"
-Encoder.FFmpeg.NVENC.Preset.Slow="Lento"
-Encoder.FFmpeg.NVENC.Preset.Medium="Medio"
-Encoder.FFmpeg.NVENC.Preset.Fast="Veloce"
-Encoder.FFmpeg.NVENC.Preset.HighPerformance="Prestazioni Elevate"
-Encoder.FFmpeg.NVENC.Preset.HighQuality="Alta Qualità"
-Encoder.FFmpeg.NVENC.Preset.BluRayDisc="Disco BluRay"
-Encoder.FFmpeg.NVENC.Preset.LowLatency="Bassa Latenza"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighPerformance="Bassa Latenza Prestazione Elevata"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighQuality="Bassa Latenza Alta Qualità"
-Encoder.FFmpeg.NVENC.Preset.Lossless="Lossless"
-Encoder.FFmpeg.NVENC.Preset.LosslessHighPerformance="Lossless Prestazioni Elevate"
+Encoder.FFmpeg.NVENC.Preset.default="Predefinito"
+Encoder.FFmpeg.NVENC.Preset.slow="Lento"
+Encoder.FFmpeg.NVENC.Preset.medium="Medio"
+Encoder.FFmpeg.NVENC.Preset.fast="Veloce"
+Encoder.FFmpeg.NVENC.Preset.hp="Prestazioni Elevate"
+Encoder.FFmpeg.NVENC.Preset.hq="Qualità Elevata"
+Encoder.FFmpeg.NVENC.Preset.bd="Disco BluRay"
+Encoder.FFmpeg.NVENC.Preset.ll="Bassa Latenza"
+Encoder.FFmpeg.NVENC.Preset.llhq="Bassa Latenza Alta Qualità"
+Encoder.FFmpeg.NVENC.Preset.llhp="Bassa Latenza Alte Prestazioni"
+Encoder.FFmpeg.NVENC.Preset.lossless="Senza perdita di dati"
+Encoder.FFmpeg.NVENC.Preset.losslesshp="Prestazioni Elevate Senza Perdita di Dati"
+Encoder.FFmpeg.NVENC.Preset.p1="Più Veloce (P1)"
+Encoder.FFmpeg.NVENC.Preset.p2="Più Veloce (P2)"
+Encoder.FFmpeg.NVENC.Preset.p3="Veloce (P3)"
+Encoder.FFmpeg.NVENC.Preset.p4="Medio (P4)"
+Encoder.FFmpeg.NVENC.Preset.p5="Lento (P5)"
+Encoder.FFmpeg.NVENC.Preset.p6="Più Lento (P6)"
+Encoder.FFmpeg.NVENC.Preset.p7="Ancora Più Lento (P7)"
+Encoder.FFmpeg.NVENC.Tune="Regolazione"
+Encoder.FFmpeg.NVENC.Tune.hq="Qualità Elevata"
+Encoder.FFmpeg.NVENC.Tune.ll="Bassa Latenza"
+Encoder.FFmpeg.NVENC.Tune.ull="Latenza Ultra Bassa"
+Encoder.FFmpeg.NVENC.Tune.lossless="Senza perdita di dati"
Encoder.FFmpeg.NVENC.RateControl="Opzioni Frequenza"
Encoder.FFmpeg.NVENC.RateControl.Mode="Modalità"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="Parametro di quantizzazione costante"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR="Bitrate Variabile"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR_HQ="Bitrate Variabile Alta Qualità"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="Bitrate costante"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_HQ="Bitrate Costante Alta Qualità"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_LD_HQ="Bitrate Costante Alta Qualità Basso Ritardo"
+Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Parametro di quantizzazione costante"
+Encoder.FFmpeg.NVENC.RateControl.Mode.vbr="Bitrate variabile"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Bitrate costante"
Encoder.FFmpeg.NVENC.RateControl.TwoPass="Due Passaggi"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass="Pass Multiplo"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.disabled="Passo Singolo"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.qres="Due passaggi alla risoluzione del trimestre"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.fullres="Due passaggi a risoluzione completa"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Previsione"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="I-Frame Adattivo"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveB="B-Frames Adattivo"
@@ -196,12 +209,14 @@ Encoder.FFmpeg.NVENC.AQ.Temporal="Quantizzazione Adattiva Temporale"
Encoder.FFmpeg.NVENC.Other="Altre Opzioni"
Encoder.FFmpeg.NVENC.Other.BFrames="B-Frame massimi"
Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode="Modalità Di Riferimento B-Frame"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Middle="Usa solo B-Frame centrali come riferimento"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Each="Usa tutti i B-Frames come riferimento"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.disabled="Nessun B-Frames sarà usato come Riferimento"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.middle="Solo B-Frames/2 sarà utilizzato come riferimento"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.each="Ogni B-Frame verrà utilizzato come riferimento"
Encoder.FFmpeg.NVENC.Other.ZeroLatency="Latenza Zero"
Encoder.FFmpeg.NVENC.Other.WeightedPrediction="Previsione Ponderata"
Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="P-Frames di non riferimento"
Encoder.FFmpeg.NVENC.Other.ReferenceFrames="Fotogrammi di riferimento"
+Encoder.FFmpeg.NVENC.Other.LowDelayKeyFrameScale="Scala di Key-Frame a Basso Ritardo"
Blur.Type.Box="Riquadro"
Blur.Type.BoxLinear="Riquadro lineare"
diff --git a/data/locale/ja-JP.ini b/data/locale/ja-JP.ini
index 5daf2ab037..e1fadb3384 100644
--- a/data/locale/ja-JP.ini
+++ b/data/locale/ja-JP.ini
@@ -47,7 +47,7 @@ UI.Updater.Dialog.Version.Latest="最新バージョン:"
UI.Updater.Dialog.Button.Ok="ダウンロードページへ移動"
UI.Updater.Dialog.Button.Cancel="後で再通知する"
UI.Updater.GitHubPermission.Title="GitHub に接続するため、あなたの承認が必要です!"
-UI.Updater.GitHubPermission.Text="手動または自動で最新情報を確認するために、StreamFX は GitHub API を利用します。
Github Privacy Statementをお読みください。 同意しない場合は「OK」を、同意しない場合は「キャンセル」をクリックします。"
+UI.Updater.GitHubPermission.Text="手動または自動で最新情報を確認するために、StreamFX は GitHub API を利用します。
Github Privacy Statementをお読みください。 同意する場合は「OK」を、同意しない場合は「キャンセル」をクリックします。"
UI.Updater.Menu.CheckForUpdates="アップデートを確認"
UI.Updater.Menu.CheckForUpdates.Automatically="アップデートを自動で確認"
UI.Updater.Menu.Channel="アップデートチャンネル"
@@ -154,26 +154,15 @@ Encoder.FFmpeg.AMF.Other.VBAQ="VBAQ"
Encoder.FFmpeg.AMF.Other.AccessUnitDelimiter="アクセスユニットデリミター"
Encoder.FFmpeg.NVENC.Preset="プリセット"
-Encoder.FFmpeg.NVENC.Preset.Default="デフォルト"
-Encoder.FFmpeg.NVENC.Preset.Slow="Slow"
-Encoder.FFmpeg.NVENC.Preset.Medium="Medium"
-Encoder.FFmpeg.NVENC.Preset.Fast="Fast"
-Encoder.FFmpeg.NVENC.Preset.HighPerformance="ハイパフォーマンス"
-Encoder.FFmpeg.NVENC.Preset.HighQuality="高品質"
-Encoder.FFmpeg.NVENC.Preset.BluRayDisc="ブルーレイディスク"
-Encoder.FFmpeg.NVENC.Preset.LowLatency="低遅延"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighPerformance="低遅延ハイパフォーマンス"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighQuality="低遅延高品質"
-Encoder.FFmpeg.NVENC.Preset.Lossless="ロスレス"
-Encoder.FFmpeg.NVENC.Preset.LosslessHighPerformance="ロスレス ハイパフォーマンス"
+Encoder.FFmpeg.NVENC.Preset.default="デフォルト"
+Encoder.FFmpeg.NVENC.Preset.slow="Slow"
+Encoder.FFmpeg.NVENC.Preset.medium="Medium"
+Encoder.FFmpeg.NVENC.Preset.fast="Fast"
+Encoder.FFmpeg.NVENC.Tune="Tune"
Encoder.FFmpeg.NVENC.RateControl="レートコントロールオプション"
Encoder.FFmpeg.NVENC.RateControl.Mode="モード"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="固定量子化パラメータ"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR="可変ビットレート"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR_HQ="高品質可変ビットレート"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="固定ビットレート"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_HQ="高品質固定ビットレート"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_LD_HQ="低遅延高品質固定ビットレート"
+Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="固定量子化パラメータ"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="固定ビットレート"
Encoder.FFmpeg.NVENC.RateControl.TwoPass="2パス"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="先読み"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="適応I-フレーム"
@@ -196,8 +185,6 @@ Encoder.FFmpeg.NVENC.AQ.Temporal="時間適応量子化"
Encoder.FFmpeg.NVENC.Other="その他のオプション"
Encoder.FFmpeg.NVENC.Other.BFrames="最大B-フレーム"
Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode="B-フレーム参照モード"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Middle="中央B-フレームのみを参照として使用"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Each="すべてのBフレームを参照として使用"
Encoder.FFmpeg.NVENC.Other.ZeroLatency="遅延なし"
Encoder.FFmpeg.NVENC.Other.WeightedPrediction="加重予測"
Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="非参照P-フレーム"
diff --git a/data/locale/ko-KR.ini b/data/locale/ko-KR.ini
index 6d954890ed..0b9663ded3 100644
--- a/data/locale/ko-KR.ini
+++ b/data/locale/ko-KR.ini
@@ -51,7 +51,7 @@ Encoder.AOM.AV1.RateControl.Buffer.Size="크기"
-Encoder.FFmpeg.NVENC.Preset.Default="기본값"
+Encoder.FFmpeg.NVENC.Preset.default="기본값"
Blur.Type.Box="박스"
Blur.Type.BoxLinear="박스 선형"
diff --git a/data/locale/nl-NL.ini b/data/locale/nl-NL.ini
index b38ab7584c..847815af58 100644
--- a/data/locale/nl-NL.ini
+++ b/data/locale/nl-NL.ini
@@ -154,26 +154,15 @@ Encoder.FFmpeg.AMF.Other.VBAQ="VBAQ"
Encoder.FFmpeg.AMF.Other.AccessUnitDelimiter="Toegangseenheid Scheidingsteken"
Encoder.FFmpeg.NVENC.Preset="Preset"
-Encoder.FFmpeg.NVENC.Preset.Default="Standaard"
-Encoder.FFmpeg.NVENC.Preset.Slow="Traag"
-Encoder.FFmpeg.NVENC.Preset.Medium="Gemiddeld"
-Encoder.FFmpeg.NVENC.Preset.Fast="Snel"
-Encoder.FFmpeg.NVENC.Preset.HighPerformance="Hoge prestaties"
-Encoder.FFmpeg.NVENC.Preset.HighQuality="Hoge kwaliteit"
-Encoder.FFmpeg.NVENC.Preset.BluRayDisc="BluRay Schijf"
-Encoder.FFmpeg.NVENC.Preset.LowLatency="Lage Latentie"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighPerformance="Lage Latency, Hoge Prestaties"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighQuality="Lage Latentie, Hoge Kwaliteit"
-Encoder.FFmpeg.NVENC.Preset.Lossless="Verliesloos"
-Encoder.FFmpeg.NVENC.Preset.LosslessHighPerformance="Verliesloos met Hoge Prestaties"
+Encoder.FFmpeg.NVENC.Preset.default="Standaard"
+Encoder.FFmpeg.NVENC.Preset.slow="Traag"
+Encoder.FFmpeg.NVENC.Preset.medium="Gemiddeld"
+Encoder.FFmpeg.NVENC.Preset.fast="Snel"
+Encoder.FFmpeg.NVENC.Tune="Afstemmen"
Encoder.FFmpeg.NVENC.RateControl="Opties voor Snelheidsregeling"
Encoder.FFmpeg.NVENC.RateControl.Mode="Modus"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="Constante Kwantisatie Parameter"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR="Variabele Bitrate"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR_HQ="Hoge kwaliteit, Variabele Bitsnelheid"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="Constante Bitrate"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_HQ="Hoge kwaliteit Constante Bitsnelheid"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_LD_HQ="Lage Vertraging, Hoge kwaliteit, Constante Bitsnelheid"
+Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Constante Kwantisatie Parameter"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Constante Bitrate"
Encoder.FFmpeg.NVENC.RateControl.TwoPass="Tweemaal"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Vooruitkijk"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="Adaptieve I-Frames"
@@ -196,8 +185,6 @@ Encoder.FFmpeg.NVENC.AQ.Temporal="Tijdelijke Adaptieve Kwantificering"
Encoder.FFmpeg.NVENC.Other="Andere opties"
Encoder.FFmpeg.NVENC.Other.BFrames="Maximale B-Frames"
Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode="B-Frame Referentie Modus"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Middle="Gebruik alleen middelste B-frames als referentie"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Each="Gebruik alle B-frames als referentie"
Encoder.FFmpeg.NVENC.Other.ZeroLatency="Nul Latentie"
Encoder.FFmpeg.NVENC.Other.WeightedPrediction="Gewogen Voorspelling"
Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="Niet-Referentie Frames"
diff --git a/data/locale/no-NO.ini b/data/locale/no-NO.ini
index 839cc68ba1..50cf4f8ed8 100644
--- a/data/locale/no-NO.ini
+++ b/data/locale/no-NO.ini
@@ -68,14 +68,14 @@ Encoder.FFmpeg.AMF.RateControl.Mode.CBR="Konstant bitrate"
Encoder.FFmpeg.AMF.RateControl.LookAhead="Look ahead"
Encoder.FFmpeg.AMF.RateControl.Limits.BufferSize="Bufferstørrelse"
-Encoder.FFmpeg.NVENC.Preset.Default="Standard"
-Encoder.FFmpeg.NVENC.Preset.Slow="Treg"
-Encoder.FFmpeg.NVENC.Preset.Medium="Medium"
-Encoder.FFmpeg.NVENC.Preset.Fast="Rask"
+Encoder.FFmpeg.NVENC.Preset.default="Standard"
+Encoder.FFmpeg.NVENC.Preset.slow="Treg"
+Encoder.FFmpeg.NVENC.Preset.medium="Medium"
+Encoder.FFmpeg.NVENC.Preset.fast="Rask"
Encoder.FFmpeg.NVENC.RateControl="Alternativer for Bitrate"
Encoder.FFmpeg.NVENC.RateControl.Mode="Modus"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="Konstant Kvantisjonsparameter"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="Konstant bitrate"
+Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Konstant Kvantisjonsparameter"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Konstant bitrate"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Look ahead"
Encoder.FFmpeg.NVENC.RateControl.Limits.BufferSize="Bufferstørrelse"
diff --git a/data/locale/pl-PL.ini b/data/locale/pl-PL.ini
index 88ac2eb2dd..1c61ed5aac 100644
--- a/data/locale/pl-PL.ini
+++ b/data/locale/pl-PL.ini
@@ -153,26 +153,15 @@ Encoder.FFmpeg.AMF.Other.VBAQ="VBAQ"
Encoder.FFmpeg.AMF.Other.AccessUnitDelimiter="Ogranicznik jednostki dostępu"
Encoder.FFmpeg.NVENC.Preset="Preset"
-Encoder.FFmpeg.NVENC.Preset.Default="Domyślne"
-Encoder.FFmpeg.NVENC.Preset.Slow="Wolne"
-Encoder.FFmpeg.NVENC.Preset.Medium="Średnie"
-Encoder.FFmpeg.NVENC.Preset.Fast="Szybkie"
-Encoder.FFmpeg.NVENC.Preset.HighPerformance="Wysoka wydajność"
-Encoder.FFmpeg.NVENC.Preset.HighQuality="Wysoka jakość"
-Encoder.FFmpeg.NVENC.Preset.BluRayDisc="Dysk BluRay"
-Encoder.FFmpeg.NVENC.Preset.LowLatency="Niskie opóźnienie"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighPerformance="Niskie opóźnienie - wysoka wydajność"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighQuality="Niskie opóźnienie - wysoka jakość"
-Encoder.FFmpeg.NVENC.Preset.Lossless="Bezstratny"
-Encoder.FFmpeg.NVENC.Preset.LosslessHighPerformance="Bezstratny - wysoka wydajność"
+Encoder.FFmpeg.NVENC.Preset.default="Domyślne"
+Encoder.FFmpeg.NVENC.Preset.slow="Wolne"
+Encoder.FFmpeg.NVENC.Preset.medium="Średnie"
+Encoder.FFmpeg.NVENC.Preset.fast="Szybkie"
+Encoder.FFmpeg.NVENC.Tune="Dostrajanie"
Encoder.FFmpeg.NVENC.RateControl="Opcje kontroli szybkości"
Encoder.FFmpeg.NVENC.RateControl.Mode="Tryb pracy"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="Stały parametr kwantyzacji"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR="Zmienny bitrate"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR_HQ="Wysoka jakość - zmienny bitrate"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="Stały bitrate"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_HQ="Wysoka jakość - stały bitrate"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_LD_HQ="Małe opóźnienie - wysoka jakość - stały bitrate"
+Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Stały parametr kwantyzacji"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Stały bitrate"
Encoder.FFmpeg.NVENC.RateControl.TwoPass="Dwa przejścia"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Prognozowany (Look Ahead)"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="Adaptacyjne klatki I-Frame"
@@ -195,8 +184,6 @@ Encoder.FFmpeg.NVENC.AQ.Temporal="Czasowa kwantyzacja adaptacyjna"
Encoder.FFmpeg.NVENC.Other="Inne opcje"
Encoder.FFmpeg.NVENC.Other.BFrames="Maksymalna liczba klatek B-Frame"
Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode="Tryb odniesień do B-Frame"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Middle="Użyj tylko środkowych klatek B-Frame jako odniesienia"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Each="Użyj wszystkich klatek B-Frame jako odniesienia"
Encoder.FFmpeg.NVENC.Other.ZeroLatency="Brak opóźnień"
Encoder.FFmpeg.NVENC.Other.WeightedPrediction="Predykcja ważona"
Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="Niereferencyjne klatki P-Frame"
diff --git a/data/locale/pt-BR.ini b/data/locale/pt-BR.ini
index 16edb07fb9..a9ce0672da 100644
--- a/data/locale/pt-BR.ini
+++ b/data/locale/pt-BR.ini
@@ -25,7 +25,12 @@ State.Automatic="Automático"
State.Default="Padrão"
UI.Menu="StreamFX"
+UI.Menu.Wiki="Leia a Wiki"
+UI.Menu.Support="Ajuda & Suporte"
+UI.Menu.Website="Visite o site StreamFX"
UI.Menu.Discord="Junte-se ao Discord do StreamFX"
+UI.Menu.Twitter="Siga o StreamFX no Twitter"
+UI.Menu.YouTube="Assine o StreamFX no YouTube"
UI.Menu.About="Sobre o StreamFX"
UI.About.Title="Sobre o StreamFX"
@@ -49,9 +54,22 @@ UI.Updater.Menu.Channel="Atualizar Canal"
UI.Updater.Menu.Channel.Release="Estável"
UI.Updater.Menu.Channel.Testing="Testes"
+Encoder.AOM.AV1="AOM AV1 (direto)"
+Encoder.AOM.AV1.Encoder="Codificador"
+Encoder.AOM.AV1.Encoder.Usage="Utilização"
+Encoder.AOM.AV1.Encoder.Usage.RealTime="Tempo real"
+Encoder.AOM.AV1.Encoder.CPUUsage="Uso da CPU"
+Encoder.AOM.AV1.Encoder.CPUUsage.0="Placebo"
+Encoder.AOM.AV1.Encoder.CPUUsage.1="Muito Lento"
+Encoder.AOM.AV1.Encoder.CPUUsage.2="Mais Lento"
Encoder.AOM.AV1.Encoder.CPUUsage.3="Lento"
Encoder.AOM.AV1.Encoder.CPUUsage.4="Médio"
Encoder.AOM.AV1.Encoder.CPUUsage.5="Rápido"
+Encoder.AOM.AV1.Encoder.CPUUsage.6="Mais rápido"
+Encoder.AOM.AV1.Encoder.CPUUsage.7="Muito Rápido"
+Encoder.AOM.AV1.Encoder.CPUUsage.8="Super Rápido"
+Encoder.AOM.AV1.Encoder.CPUUsage.9="Ultra Rápido"
+Encoder.AOM.AV1.Encoder.CPUUsage.10="Insanamente Rápido"
Encoder.AOM.AV1.Encoder.Profile="Perfil"
Encoder.AOM.AV1.KeyFrames.IntervalType="Tipo de Intervalo"
Encoder.AOM.AV1.KeyFrames.IntervalType.Frames="Quadros"
@@ -61,17 +79,26 @@ Encoder.AOM.AV1.RateControl.Mode="Modo"
Encoder.AOM.AV1.RateControl.Limits="Limites"
Encoder.AOM.AV1.RateControl.Limits.Quality="Qualidade"
Encoder.AOM.AV1.RateControl.Buffer.Size="Tamanho"
+Encoder.AOM.AV1.Advanced="Avançado"
+Encoder.AOM.AV1.Advanced.Tune.Content="Conteúdo"
+Encoder.FFmpeg.Suffix=" (via FFmpeg)"
+Encoder.FFmpeg.CustomSettings="Configurações Personalizadas"
+Encoder.FFmpeg.GPU="GPU"
Encoder.FFmpeg.KeyFrames.IntervalType="Tipo de Intervalo"
Encoder.FFmpeg.KeyFrames.IntervalType.Frames="Quadros"
Encoder.FFmpeg.KeyFrames.IntervalType.Seconds="Segundos"
Encoder.FFmpeg.KeyFrames.Interval="Intervalo"
Encoder.FFmpeg.AMF.Preset="Modelo"
+Encoder.FFmpeg.AMF.Preset.Speed="Velocidade"
+Encoder.FFmpeg.AMF.Preset.Balanced="Balanceado"
Encoder.FFmpeg.AMF.Preset.Quality="Qualidade"
Encoder.FFmpeg.AMF.RateControl="Opções do Controle de Taxa"
Encoder.FFmpeg.AMF.RateControl.Mode="Modo"
Encoder.FFmpeg.AMF.RateControl.Mode.CQP="Parâmetro de Quantização Constante"
+Encoder.FFmpeg.AMF.RateControl.Mode.VBR_PEAK="Taxa de Bits Variável (Pico Restringido)"
+Encoder.FFmpeg.AMF.RateControl.Mode.VBR_LATENCY="Taxa de Bits Variável (Latência Restringida)"
Encoder.FFmpeg.AMF.RateControl.Mode.CBR="Taxa de Bits Constante"
Encoder.FFmpeg.AMF.RateControl.LookAhead="Olhar a Frente"
Encoder.FFmpeg.AMF.RateControl.Limits="Limites"
@@ -87,14 +114,14 @@ Encoder.FFmpeg.AMF.Other.BFrames="Máximo de B-Frames"
Encoder.FFmpeg.AMF.Other.ReferenceFrames="Quadros de Referência"
Encoder.FFmpeg.NVENC.Preset="Modelo"
-Encoder.FFmpeg.NVENC.Preset.Default="Padrão"
-Encoder.FFmpeg.NVENC.Preset.Slow="Lento"
-Encoder.FFmpeg.NVENC.Preset.Medium="Médio"
-Encoder.FFmpeg.NVENC.Preset.Fast="Rápido"
+Encoder.FFmpeg.NVENC.Preset.default="Padrão"
+Encoder.FFmpeg.NVENC.Preset.slow="Lento"
+Encoder.FFmpeg.NVENC.Preset.medium="Médio"
+Encoder.FFmpeg.NVENC.Preset.fast="Rápido"
Encoder.FFmpeg.NVENC.RateControl="Opções do Controle de Taxa"
Encoder.FFmpeg.NVENC.RateControl.Mode="Modo"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="Parâmetro de Quantização Constante"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="Taxa de Bits Constante"
+Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Parâmetro de Quantização Constante"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Taxa de Bits Constante"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Olhar a Frente"
Encoder.FFmpeg.NVENC.RateControl.Limits="Limites"
Encoder.FFmpeg.NVENC.RateControl.Limits.BufferSize="Tamanho do Buffer"
@@ -106,6 +133,7 @@ Encoder.FFmpeg.NVENC.RateControl.QP.P="P-Frame QP"
Encoder.FFmpeg.NVENC.RateControl.QP.B="B-Frame QP"
Encoder.FFmpeg.NVENC.Other="Outras Opções"
Encoder.FFmpeg.NVENC.Other.BFrames="Máximo de B-Frames"
+Encoder.FFmpeg.NVENC.Other.ZeroLatency="Latência zero"
Encoder.FFmpeg.NVENC.Other.ReferenceFrames="Quadros de Referência"
Blur.Type.Box="Caixa"
@@ -139,6 +167,7 @@ Transition.Shader="Shader"
Filter.AutoFraming.Tracking.Mode="Modo"
Filter.AutoFraming.Framing.Offset="Deslocamento"
+Filter.AutoFraming.Framing.AspectRatio="Proporção de tela"
Filter.Blur="Desfoque"
Filter.Blur.Type="Tipo"
@@ -295,11 +324,16 @@ Filter.Transform.Rotation.Order.YXZ="Largura, Altura, Profundidade"
Filter.Transform.Rotation.Order.YZX="Largura, Profundidade, Altura"
Filter.Transform.Rotation.Order.ZXY="Profundidade, Altura, Largura"
Filter.Transform.Rotation.Order.ZYX="Profundidade, Largura, Altura"
+Filter.Transform.Corners.TopLeft="Superior Esquerdo"
+Filter.Transform.Corners.TopRight="Superior Direito"
+Filter.Transform.Corners.BottomLeft="Inferior Esquerdo"
+Filter.Transform.Corners.BottomRight="Inferior Direito"
Filter.Transform.Mipmapping="Habilitar Mip-Maps"
Filter.Upscaling.NVIDIA.SuperRes.Scale="Escala"
Filter.VirtualGreenscreen.NVIDIA.Greenscreen.Mode="Modo"
+Filter.VirtualGreenscreen.NVIDIA.Greenscreen.Mode.Performance="Performance"
Filter.VirtualGreenscreen.NVIDIA.Greenscreen.Mode.Quality="Qualidade"
Source.Mirror="Espelhamento de Fonte"
@@ -315,9 +349,11 @@ Source.Mirror.Source.Audio.Layout.QuadraphonicLFE="Quadrafônico com LFE"
Source.Mirror.Source.Audio.Layout.Surround="Surround"
Source.Mirror.Source.Audio.Layout.FullSurround="Surround Completo"
+Codec.AV1="AV1"
Codec.AV1.Profile="Perfil"
Codec.AV1.Profile.Main="Principal"
Codec.AV1.Profile.High="Alto"
+Codec.AV1.Profile.Professional="Profissional"
Codec.H264="H264"
Codec.H264.Profile="Perfil"
diff --git a/data/locale/pt-PT.ini b/data/locale/pt-PT.ini
index 1720ed2cfa..143ffb8dae 100644
--- a/data/locale/pt-PT.ini
+++ b/data/locale/pt-PT.ini
@@ -47,10 +47,10 @@ Encoder.FFmpeg.KeyFrames.Interval="Intervalo"
Encoder.FFmpeg.AMF.RateControl.Mode="Modo"
-Encoder.FFmpeg.NVENC.Preset.Default="Padrão"
-Encoder.FFmpeg.NVENC.Preset.Slow="Lento"
-Encoder.FFmpeg.NVENC.Preset.Medium="Médio"
-Encoder.FFmpeg.NVENC.Preset.Fast="Rápido"
+Encoder.FFmpeg.NVENC.Preset.default="Padrão"
+Encoder.FFmpeg.NVENC.Preset.slow="Lento"
+Encoder.FFmpeg.NVENC.Preset.medium="Médio"
+Encoder.FFmpeg.NVENC.Preset.fast="Rápido"
Encoder.FFmpeg.NVENC.RateControl.Mode="Modo"
Blur.Type.Box="Região"
diff --git a/data/locale/ro-RO.ini b/data/locale/ro-RO.ini
index 91bdcee49a..da6ae89cea 100644
--- a/data/locale/ro-RO.ini
+++ b/data/locale/ro-RO.ini
@@ -84,14 +84,35 @@ Encoder.FFmpeg.AMF.Other="Alte opțiuni"
Encoder.FFmpeg.AMF.Other.ReferenceFrames="Cadre de referință"
Encoder.FFmpeg.NVENC.Preset="Presetare"
-Encoder.FFmpeg.NVENC.Preset.Default="Prestabilit"
-Encoder.FFmpeg.NVENC.Preset.Slow="Încet"
-Encoder.FFmpeg.NVENC.Preset.Medium="Mediu"
-Encoder.FFmpeg.NVENC.Preset.Fast="Rapid"
+Encoder.FFmpeg.NVENC.Preset.default="Prestabilit"
+Encoder.FFmpeg.NVENC.Preset.slow="Încet"
+Encoder.FFmpeg.NVENC.Preset.medium="Mediu"
+Encoder.FFmpeg.NVENC.Preset.fast="Rapid"
+Encoder.FFmpeg.NVENC.Preset.hp="Performanță sporită"
+Encoder.FFmpeg.NVENC.Preset.hq="Calitate Înaltă"
+Encoder.FFmpeg.NVENC.Preset.bd="Disc BluRay"
+Encoder.FFmpeg.NVENC.Preset.ll="Latență redusă"
+Encoder.FFmpeg.NVENC.Preset.llhq="Latență redusă Calitate Înaltă"
+Encoder.FFmpeg.NVENC.Preset.llhp="Performanță înaltă Latență scăzută"
+Encoder.FFmpeg.NVENC.Preset.lossless="Fără pierderi"
+Encoder.FFmpeg.NVENC.Preset.losslesshp="Performanță înaltă fără pierderi"
+Encoder.FFmpeg.NVENC.Preset.p1="Cel mai rapid (P1)"
+Encoder.FFmpeg.NVENC.Preset.p2="Mai rapid (P2)"
+Encoder.FFmpeg.NVENC.Preset.p3="Rapid (P3)"
+Encoder.FFmpeg.NVENC.Preset.p4="Mediu (P4)"
+Encoder.FFmpeg.NVENC.Preset.p5="Lent (P5)"
+Encoder.FFmpeg.NVENC.Preset.p6="Mai lent (P6)"
+Encoder.FFmpeg.NVENC.Preset.p7="Cel mai lent (P7)"
+Encoder.FFmpeg.NVENC.Tune="Reglaj"
+Encoder.FFmpeg.NVENC.Tune.hq="Calitate Înaltă"
+Encoder.FFmpeg.NVENC.Tune.ll="Latență redusă"
+Encoder.FFmpeg.NVENC.Tune.ull="Latență Ultra scăzută"
+Encoder.FFmpeg.NVENC.Tune.lossless="Fără pierderi"
Encoder.FFmpeg.NVENC.RateControl="Opţiuni de control al ratei"
Encoder.FFmpeg.NVENC.RateControl.Mode="Mod"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="Parametru de cuantizare constantă"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="Debit binar constant"
+Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Parametru de cuantizare constantă"
+Encoder.FFmpeg.NVENC.RateControl.Mode.vbr="VBR (Rată de biți variabilă)"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Debit binar constant"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Prognozeaza"
Encoder.FFmpeg.NVENC.RateControl.Limits="Limite"
Encoder.FFmpeg.NVENC.RateControl.Limits.BufferSize="Dimensiune tampon"
diff --git a/data/locale/ru-RU.ini b/data/locale/ru-RU.ini
index 2d51f94df1..0962e1c682 100644
--- a/data/locale/ru-RU.ini
+++ b/data/locale/ru-RU.ini
@@ -154,27 +154,40 @@ Encoder.FFmpeg.AMF.Other.VBAQ="VBAQ"
Encoder.FFmpeg.AMF.Other.AccessUnitDelimiter="Разделитель единиц доступа"
Encoder.FFmpeg.NVENC.Preset="Пресет"
-Encoder.FFmpeg.NVENC.Preset.Default="По умолчанию"
-Encoder.FFmpeg.NVENC.Preset.Slow="Медленно"
-Encoder.FFmpeg.NVENC.Preset.Medium="Средне"
-Encoder.FFmpeg.NVENC.Preset.Fast="Быстро"
-Encoder.FFmpeg.NVENC.Preset.HighPerformance="Высокая производительность"
-Encoder.FFmpeg.NVENC.Preset.HighQuality="Высокое качество"
-Encoder.FFmpeg.NVENC.Preset.BluRayDisc="Диск Blu-Ray"
-Encoder.FFmpeg.NVENC.Preset.LowLatency="Низкая задержка"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighPerformance="Низкая задержка с приоритетом производительности"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighQuality="Низкая задержка с приоритетом качества"
-Encoder.FFmpeg.NVENC.Preset.Lossless="Без потерь"
-Encoder.FFmpeg.NVENC.Preset.LosslessHighPerformance="Без потерь с приоритетом производительности"
+Encoder.FFmpeg.NVENC.Preset.default="По умолчанию"
+Encoder.FFmpeg.NVENC.Preset.slow="Медленно"
+Encoder.FFmpeg.NVENC.Preset.medium="Средне"
+Encoder.FFmpeg.NVENC.Preset.fast="Быстро"
+Encoder.FFmpeg.NVENC.Preset.hp="Высокая производительность"
+Encoder.FFmpeg.NVENC.Preset.hq="Высокое качество"
+Encoder.FFmpeg.NVENC.Preset.bd="Диск Blu-Ray"
+Encoder.FFmpeg.NVENC.Preset.ll="Низкая задержка"
+Encoder.FFmpeg.NVENC.Preset.llhq="Низкая задержка с приоритетом качества"
+Encoder.FFmpeg.NVENC.Preset.llhp="Низкая задержка с приоритетом производительности"
+Encoder.FFmpeg.NVENC.Preset.lossless="Без потерь"
+Encoder.FFmpeg.NVENC.Preset.losslesshp="Без потерь с приоритетом производительности"
+Encoder.FFmpeg.NVENC.Preset.p1="Самый быстрый (P1)"
+Encoder.FFmpeg.NVENC.Preset.p2="Быстрее (P2)"
+Encoder.FFmpeg.NVENC.Preset.p3="Быстрый (P3)"
+Encoder.FFmpeg.NVENC.Preset.p4="Средний (P4)"
+Encoder.FFmpeg.NVENC.Preset.p5="Медленный (P5)"
+Encoder.FFmpeg.NVENC.Preset.p6="Медленнее (P6)"
+Encoder.FFmpeg.NVENC.Preset.p7="Очень медленно (P7)"
+Encoder.FFmpeg.NVENC.Tune="Настройка"
+Encoder.FFmpeg.NVENC.Tune.hq="Высокое качество"
+Encoder.FFmpeg.NVENC.Tune.ll="Низкая задержка"
+Encoder.FFmpeg.NVENC.Tune.ull="Наименьшая задержка"
+Encoder.FFmpeg.NVENC.Tune.lossless="Без потерь"
Encoder.FFmpeg.NVENC.RateControl="Параметры управления битрейтом"
Encoder.FFmpeg.NVENC.RateControl.Mode="Режим"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="Постоянный параметр квантования"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR="Переменный битрейт"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR_HQ="Переменный битрейт с приоритетом качества"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="Постоянный битрейт"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_HQ="Постоянный битрейт с приоритетом качества"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_LD_HQ="Постоянный битрейт с низкой задержкой с приоритетом качества"
+Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Постоянный параметр квантования"
+Encoder.FFmpeg.NVENC.RateControl.Mode.vbr="Переменный битрейт"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Постоянный битрейт"
Encoder.FFmpeg.NVENC.RateControl.TwoPass="Двухпроходное кодирование"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass="Многопроходное кодирование"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.disabled="Один проход"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.qres="Два прохода при четверти разрешения"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.fullres="Два прохода в полном разрешенит"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Предугадывание"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="Адаптивные I-кадры"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveB="Адаптивные B-кадры"
@@ -196,12 +209,14 @@ Encoder.FFmpeg.NVENC.AQ.Temporal="Временнóе адаптивное ква
Encoder.FFmpeg.NVENC.Other="Другие настройки"
Encoder.FFmpeg.NVENC.Other.BFrames="Максимальное количество B-кадров"
Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode="Режим Опорных B-кадров"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Middle="Использовать только средние B-кадры как опорные"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Each="Использовать все B-кадры как опорные"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.disabled="Не использовать B-кадры в качестве опорных"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.middle="Только половина B-кадров будет использована в качестве опорных"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.each="Каждый B-кадр будет использоваться как опорный"
Encoder.FFmpeg.NVENC.Other.ZeroLatency="Нулевая задержка"
Encoder.FFmpeg.NVENC.Other.WeightedPrediction="Взвешенное прогнозирование"
Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="Неопорные P-Кадры"
Encoder.FFmpeg.NVENC.Other.ReferenceFrames="Опорные кадры"
+Encoder.FFmpeg.NVENC.Other.LowDelayKeyFrameScale="Масштабирование ключевых кадров с низкой задержкой"
Blur.Type.Box="Бокс"
Blur.Type.BoxLinear="Линейное боксовое"
diff --git a/data/locale/th-TH.ini b/data/locale/th-TH.ini
index 28adcdbdb1..c75aeadc52 100644
--- a/data/locale/th-TH.ini
+++ b/data/locale/th-TH.ini
@@ -47,9 +47,9 @@ Encoder.FFmpeg.KeyFrames.IntervalType.Seconds="วินาที"
Encoder.FFmpeg.AMF.Preset.Quality="คุณภาพ"
Encoder.FFmpeg.AMF.RateControl.Mode="รูปแบบ"
-Encoder.FFmpeg.NVENC.Preset.Default="ค่าเริ่มต้น"
-Encoder.FFmpeg.NVENC.Preset.Slow="ช้า"
-Encoder.FFmpeg.NVENC.Preset.Fast="รวดเร็ว"
+Encoder.FFmpeg.NVENC.Preset.default="ค่าเริ่มต้น"
+Encoder.FFmpeg.NVENC.Preset.slow="ช้า"
+Encoder.FFmpeg.NVENC.Preset.fast="รวดเร็ว"
Encoder.FFmpeg.NVENC.RateControl.Mode="รูปแบบ"
Blur.Type.Box="กล่อง"
diff --git a/data/locale/tr-TR.ini b/data/locale/tr-TR.ini
index d2024a1791..a9e6f8b9bc 100644
--- a/data/locale/tr-TR.ini
+++ b/data/locale/tr-TR.ini
@@ -118,17 +118,13 @@ Encoder.FFmpeg.AMF.Other.BFrames="Maksimum B-Kareler"
Encoder.FFmpeg.AMF.Other.ReferenceFrames="Referans Kareler"
Encoder.FFmpeg.NVENC.Preset="Hazır Ayar"
-Encoder.FFmpeg.NVENC.Preset.Default="Varsayılan"
-Encoder.FFmpeg.NVENC.Preset.Slow="Yavaş"
-Encoder.FFmpeg.NVENC.Preset.Medium="Orta"
-Encoder.FFmpeg.NVENC.Preset.Fast="Hızlı"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighQuality="Düşük Gecikme Yüksek Kalite"
+Encoder.FFmpeg.NVENC.Preset.default="Varsayılan"
+Encoder.FFmpeg.NVENC.Preset.slow="Yavaş"
+Encoder.FFmpeg.NVENC.Preset.medium="Orta"
+Encoder.FFmpeg.NVENC.Preset.fast="Hızlı"
Encoder.FFmpeg.NVENC.RateControl="Oran Kontrol Seçenekleri"
Encoder.FFmpeg.NVENC.RateControl.Mode="Mod"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR_HQ="Yüksek Kalite Değişken Bit Hızı"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="Sabit Bit Hızı (CBR)"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_HQ="Yüksek Kalite Sabit Bit Hızı"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_LD_HQ="Düşük Gecikmeli Yüksek Kalite Sabit Bit Hızı"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Sabit Bit Hızı (CBR)"
Encoder.FFmpeg.NVENC.RateControl.Limits="Sınırlar"
Encoder.FFmpeg.NVENC.RateControl.Limits.BufferSize="Ara Bellek Boyutu"
Encoder.FFmpeg.NVENC.RateControl.Limits.Bitrate.Target="Hedef Bit Hızı"
diff --git a/data/locale/zh-CN.ini b/data/locale/zh-CN.ini
index c8ce665253..b67633560c 100644
--- a/data/locale/zh-CN.ini
+++ b/data/locale/zh-CN.ini
@@ -154,26 +154,15 @@ Encoder.FFmpeg.AMF.Other.VBAQ="VBAQ"
Encoder.FFmpeg.AMF.Other.AccessUnitDelimiter="访问单元分隔符"
Encoder.FFmpeg.NVENC.Preset="预设"
-Encoder.FFmpeg.NVENC.Preset.Default="默认"
-Encoder.FFmpeg.NVENC.Preset.Slow="慢速"
-Encoder.FFmpeg.NVENC.Preset.Medium="中等"
-Encoder.FFmpeg.NVENC.Preset.Fast="快速"
-Encoder.FFmpeg.NVENC.Preset.HighPerformance="高性能"
-Encoder.FFmpeg.NVENC.Preset.HighQuality="高质量"
-Encoder.FFmpeg.NVENC.Preset.BluRayDisc="蓝光光盘"
-Encoder.FFmpeg.NVENC.Preset.LowLatency="低延迟"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighPerformance="低延迟高性能"
-Encoder.FFmpeg.NVENC.Preset.LowLatencyHighQuality="低延迟高质量"
-Encoder.FFmpeg.NVENC.Preset.Lossless="无损"
-Encoder.FFmpeg.NVENC.Preset.LosslessHighPerformance="无损高性能"
+Encoder.FFmpeg.NVENC.Preset.default="默认"
+Encoder.FFmpeg.NVENC.Preset.slow="慢速"
+Encoder.FFmpeg.NVENC.Preset.medium="中等"
+Encoder.FFmpeg.NVENC.Preset.fast="快速"
+Encoder.FFmpeg.NVENC.Tune="微调(Tune)"
Encoder.FFmpeg.NVENC.RateControl="速率控制选项"
Encoder.FFmpeg.NVENC.RateControl.Mode="模式"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CQP="恒量化参数"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR="可变比特率"
-Encoder.FFmpeg.NVENC.RateControl.Mode.VBR_HQ="高质量可变比特率"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR="恒定比特率"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_HQ="高质量恒定比特率"
-Encoder.FFmpeg.NVENC.RateControl.Mode.CBR_LD_HQ="低延迟高质量恒定比特率"
+Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="恒量化参数"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="恒定比特率"
Encoder.FFmpeg.NVENC.RateControl.TwoPass="双通道"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="预测(Look Ahead)"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="自适应 I 帧"
@@ -196,8 +185,6 @@ Encoder.FFmpeg.NVENC.AQ.Temporal="时间自适应量化"
Encoder.FFmpeg.NVENC.Other="其它选项"
Encoder.FFmpeg.NVENC.Other.BFrames="最大 B 帧"
Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode="B 帧参考模式"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Middle="仅使用中位 B 帧作为参考"
-Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.Each="使用所有 B 帧作为参考"
Encoder.FFmpeg.NVENC.Other.ZeroLatency="零延迟"
Encoder.FFmpeg.NVENC.Other.WeightedPrediction="加权预测"
Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="非参考 P 帧"
diff --git a/data/locale/zh-TW.ini b/data/locale/zh-TW.ini
index 267824d813..95e8158497 100644
--- a/data/locale/zh-TW.ini
+++ b/data/locale/zh-TW.ini
@@ -56,7 +56,7 @@ UI.Updater.Menu.Channel.Testing="測試版"
-Encoder.FFmpeg.NVENC.Preset.Default="預設"
+Encoder.FFmpeg.NVENC.Preset.default="預設"
Blur.Type.Box="均值模糊"
Blur.Type.BoxLinear="線性均值模糊"
From 378f2b3f0e1b73efc9b105d83b92ec7a7e0294bf Mon Sep 17 00:00:00 2001
From: Michael Fabian 'Xaymar' Dirks
Date: Sun, 20 Feb 2022 19:41:55 +0100
Subject: [PATCH 006/164] ffmpeg/tools: Improve helper functions for AVOption
lists
---
source/ffmpeg/tools.cpp | 41 +++++++----------------------------------
source/ffmpeg/tools.hpp | 7 ++-----
2 files changed, 9 insertions(+), 39 deletions(-)
diff --git a/source/ffmpeg/tools.cpp b/source/ffmpeg/tools.cpp
index 597222c24d..4e454177f7 100644
--- a/source/ffmpeg/tools.cpp
+++ b/source/ffmpeg/tools.cpp
@@ -209,8 +209,8 @@ bool tools::avoption_exists(const void* obj, std::string_view name)
return false;
}
-void tools::avoption_list_add_entries_unnamed(const void* obj, std::string_view unit, obs_property_t* prop,
- std::function filter)
+void tools::avoption_list_add_entries(const void* obj, std::string_view unit,
+ std::function inserter)
{
for (const AVOption* opt = nullptr; (opt = av_opt_next(obj, opt)) != nullptr;) {
// Skip all irrelevant options.
@@ -225,38 +225,11 @@ void tools::avoption_list_add_entries_unnamed(const void* obj, std::string_view
if (opt->flags & AV_OPT_FLAG_DEPRECATED)
continue;
- if (filter && filter(opt))
- continue;
-
- // Generate name and add to list.
- obs_property_list_add_int(prop, opt->name, opt->default_val.i64);
- }
-}
-
-void tools::avoption_list_add_entries(const void* obj, std::string_view unit, obs_property_t* prop,
- std::string_view prefix, std::function filter)
-{
- for (const AVOption* opt = nullptr; (opt = av_opt_next(obj, opt)) != nullptr;) {
- // Skip all irrelevant options.
- if (!opt->unit)
- continue;
- if (opt->unit != unit)
- continue;
- if (opt->name == unit)
- continue;
-
- // Skip any deprecated options.
- if (opt->flags & AV_OPT_FLAG_DEPRECATED)
- continue;
-
- // Skip based on filter function.
- if (filter && filter(opt))
- continue;
-
- // Generate name and add to list.
- char buffer[1024];
- snprintf(buffer, sizeof(buffer), "%s.%s\0", prefix.data(), opt->name);
- obs_property_list_add_int(prop, D_TRANSLATE(buffer), opt->default_val.i64);
+ if (inserter) {
+ inserter(opt);
+ } else {
+ break;
+ }
}
}
diff --git a/source/ffmpeg/tools.hpp b/source/ffmpeg/tools.hpp
index 51d06e96fd..584dc7a13e 100644
--- a/source/ffmpeg/tools.hpp
+++ b/source/ffmpeg/tools.hpp
@@ -85,10 +85,7 @@ namespace streamfx::ffmpeg::tools {
const char* avoption_name_from_unit_value(const void* obj, std::string_view unit, int64_t value);
- void avoption_list_add_entries_unnamed(const void* obj, std::string_view unit, obs_property_t* prop,
- std::function filter = nullptr);
-
- void avoption_list_add_entries(const void* obj, std::string_view unit, obs_property_t* prop,
- std::string_view prefix, std::function filter = nullptr);
+ void avoption_list_add_entries(const void* obj, std::string_view unit,
+ std::function inserter = nullptr);
} // namespace streamfx::ffmpeg::tools
From 03b16786e7450e61549e3a53c043ac2ff461c9e3 Mon Sep 17 00:00:00 2001
From: Michael Fabian 'Xaymar' Dirks
Date: Sun, 20 Feb 2022 19:45:41 +0100
Subject: [PATCH 007/164] encoders/ffmpeg/nvenc: Improve compatibility with
FFmpeg
Replaces some very specific code with generic support for FFmpeg, which should last us much longer than the old way. Also improves the migration of settings, which wasn't quite working with the previous way.
---
.../encoders/handlers/nvenc_h264_handler.cpp | 60 ++++---
.../encoders/handlers/nvenc_hevc_handler.cpp | 88 ++++++++---
source/encoders/handlers/nvenc_shared.cpp | 149 +++++++++++-------
3 files changed, 201 insertions(+), 96 deletions(-)
diff --git a/source/encoders/handlers/nvenc_h264_handler.cpp b/source/encoders/handlers/nvenc_h264_handler.cpp
index 3eeedecd54..d395c418b2 100644
--- a/source/encoders/handlers/nvenc_h264_handler.cpp
+++ b/source/encoders/handlers/nvenc_h264_handler.cpp
@@ -56,8 +56,8 @@ void nvenc_h264_handler::get_defaults(obs_data_t* settings, const AVCodec* codec
{
nvenc::get_defaults(settings, codec, context);
- obs_data_set_default_int(settings, ST_KEY_PROFILE, static_cast(profile::HIGH));
- obs_data_set_default_int(settings, ST_KEY_LEVEL, static_cast(level::UNKNOWN));
+ obs_data_set_default_string(settings, ST_KEY_PROFILE, "");
+ obs_data_set_default_string(settings, ST_KEY_LEVEL, "auto");
}
bool nvenc_h264_handler::has_keyframe_support(ffmpeg_factory*)
@@ -94,13 +94,11 @@ void nvenc_h264_handler::update(obs_data_t* settings, const AVCodec* codec, AVCo
nvenc::update(settings, codec, context);
if (!context->internal) {
- if (auto value = obs_data_get_int(settings, ST_KEY_PROFILE); value > -1) {
- av_opt_set_int(context->priv_data, "profile", value, AV_OPT_SEARCH_CHILDREN);
+ if (auto v = obs_data_get_string(settings, ST_KEY_PROFILE); v && (strlen(v) > 0)) {
+ av_opt_set(context->priv_data, "profile", v, AV_OPT_SEARCH_CHILDREN);
}
- if (auto value = obs_data_get_int(settings, ST_KEY_LEVEL); value > -1) {
- av_opt_set_int(context->priv_data, "level", value, AV_OPT_SEARCH_CHILDREN);
- } else {
- av_opt_set(context->priv_data, "level", "auto", AV_OPT_SEARCH_CHILDREN);
+ if (auto v = obs_data_get_string(settings, ST_KEY_LEVEL); v && (strlen(v) > 0)) {
+ av_opt_set(context->priv_data, "level", v, AV_OPT_SEARCH_CHILDREN);
}
}
}
@@ -140,20 +138,26 @@ void nvenc_h264_handler::get_encoder_properties(obs_properties_t* props, const A
{
auto p = obs_properties_add_list(grp, ST_KEY_PROFILE, D_TRANSLATE(S_CODEC_H264_PROFILE),
- OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
- obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), -1);
- streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "profile", p, S_CODEC_H264_PROFILE);
+ OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
+ obs_property_list_add_string(p, D_TRANSLATE(S_STATE_DEFAULT), "");
+ streamfx::ffmpeg::tools::avoption_list_add_entries(
+ context->priv_data, "profile", [&p](const AVOption* opt) {
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "%s.%s\0", S_CODEC_H264_PROFILE, opt->name);
+ obs_property_list_add_string(p, D_TRANSLATE(buffer), opt->name);
+ });
}
{
auto p = obs_properties_add_list(grp, ST_KEY_LEVEL, D_TRANSLATE(S_CODEC_H264_LEVEL), OBS_COMBO_TYPE_LIST,
- OBS_COMBO_FORMAT_INT);
- obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), 0);
- streamfx::ffmpeg::tools::avoption_list_add_entries_unnamed(context->priv_data, "level", p,
- [](const AVOption* opt) {
- if (opt->default_val.i64 == 0)
- return true;
- return false;
- });
+ OBS_COMBO_FORMAT_STRING);
+
+ streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "level", [&p](const AVOption* opt) {
+ if (opt->default_val.i64 == 0) {
+ obs_property_list_add_string(p, D_TRANSLATE(S_STATE_AUTOMATIC), "auto");
+ } else {
+ obs_property_list_add_string(p, opt->name, opt->name);
+ }
+ });
}
}
@@ -173,6 +177,24 @@ void streamfx::encoder::ffmpeg::handler::nvenc_h264_handler::migrate(obs_data_t*
const AVCodec* codec, AVCodecContext* context)
{
nvenc::migrate(settings, version, codec, context);
+
+ if (version < STREAMFX_MAKE_VERSION(0, 11, 1, 0)) {
+ // Profile
+ if (auto v = obs_data_get_int(settings, ST_KEY_PROFILE); v != -1) {
+ if (!obs_data_has_user_value(settings, ST_KEY_PROFILE))
+ v = 3;
+
+ std::map preset{
+ {0, "baseline"}, {1, "baseline"}, {2, "main"}, {3, "high"}, {4, "high444p"},
+ };
+ if (auto k = preset.find(v); k != preset.end()) {
+ obs_data_set_string(settings, ST_KEY_PROFILE, k->second.data());
+ }
+ }
+
+ // Level
+ obs_data_set_string(settings, ST_KEY_LEVEL, "auto");
+ }
}
bool nvenc_h264_handler::supports_reconfigure(ffmpeg_factory* instance, bool& threads, bool& gpu, bool& keyframes)
diff --git a/source/encoders/handlers/nvenc_hevc_handler.cpp b/source/encoders/handlers/nvenc_hevc_handler.cpp
index 5c3cb7ba88..7c8915cdbe 100644
--- a/source/encoders/handlers/nvenc_hevc_handler.cpp
+++ b/source/encoders/handlers/nvenc_hevc_handler.cpp
@@ -53,9 +53,9 @@ void nvenc_hevc_handler::get_defaults(obs_data_t* settings, const AVCodec* codec
{
nvenc::get_defaults(settings, codec, context);
- obs_data_set_default_int(settings, ST_KEY_PROFILE, static_cast(profile::MAIN));
- obs_data_set_default_int(settings, ST_KEY_TIER, static_cast(profile::MAIN));
- obs_data_set_default_int(settings, ST_KEY_LEVEL, static_cast(level::UNKNOWN));
+ obs_data_set_default_string(settings, ST_KEY_PROFILE, "");
+ obs_data_set_default_string(settings, ST_KEY_TIER, "");
+ obs_data_set_default_string(settings, ST_KEY_LEVEL, "auto");
}
bool nvenc_hevc_handler::has_keyframe_support(ffmpeg_factory*)
@@ -92,16 +92,14 @@ void nvenc_hevc_handler::update(obs_data_t* settings, const AVCodec* codec, AVCo
nvenc::update(settings, codec, context);
if (!context->internal) {
- if (auto v = obs_data_get_int(settings, ST_KEY_PROFILE); v > -1) {
- av_opt_set_int(context->priv_data, "profile", v, AV_OPT_SEARCH_CHILDREN);
+ if (auto v = obs_data_get_string(settings, ST_KEY_PROFILE); v && (strlen(v) > 0)) {
+ av_opt_set(context->priv_data, "profile", v, AV_OPT_SEARCH_CHILDREN);
}
- if (auto v = obs_data_get_int(settings, ST_KEY_TIER); v > -1) {
- av_opt_set_int(context->priv_data, "tier", v, AV_OPT_SEARCH_CHILDREN);
+ if (auto v = obs_data_get_string(settings, ST_KEY_TIER); v && (strlen(v) > 0)) {
+ av_opt_set(context->priv_data, "tier", v, AV_OPT_SEARCH_CHILDREN);
}
- if (auto v = obs_data_get_int(settings, ST_KEY_LEVEL); v > -1) {
- av_opt_set_int(context->priv_data, "level", v, AV_OPT_SEARCH_CHILDREN);
- } else {
- av_opt_set(context->priv_data, "level", "auto", AV_OPT_SEARCH_CHILDREN);
+ if (auto v = obs_data_get_string(settings, ST_KEY_LEVEL); v && (strlen(v) > 0)) {
+ av_opt_set(context->priv_data, "level", v, AV_OPT_SEARCH_CHILDREN);
}
}
}
@@ -143,26 +141,36 @@ void nvenc_hevc_handler::get_encoder_properties(obs_properties_t* props, const A
{
auto p = obs_properties_add_list(grp, ST_KEY_PROFILE, D_TRANSLATE(S_CODEC_HEVC_PROFILE),
- OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
+ OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), -1);
- streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "profile", p, S_CODEC_HEVC_PROFILE);
+ streamfx::ffmpeg::tools::avoption_list_add_entries(
+ context->priv_data, "profile", [&p](const AVOption* opt) {
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "%s.%s\0", S_CODEC_HEVC_PROFILE, opt->name);
+ obs_property_list_add_string(p, D_TRANSLATE(buffer), opt->name);
+ });
}
{
auto p = obs_properties_add_list(grp, ST_KEY_TIER, D_TRANSLATE(S_CODEC_HEVC_TIER), OBS_COMBO_TYPE_LIST,
- OBS_COMBO_FORMAT_INT);
+ OBS_COMBO_FORMAT_STRING);
obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), -1);
- streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "tier", p, S_CODEC_HEVC_TIER);
+ streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "tier", [&p](const AVOption* opt) {
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "%s.%s\0", S_CODEC_HEVC_TIER, opt->name);
+ obs_property_list_add_string(p, D_TRANSLATE(buffer), opt->name);
+ });
}
{
auto p = obs_properties_add_list(grp, ST_KEY_LEVEL, D_TRANSLATE(S_CODEC_HEVC_LEVEL), OBS_COMBO_TYPE_LIST,
- OBS_COMBO_FORMAT_INT);
- obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), 0);
- streamfx::ffmpeg::tools::avoption_list_add_entries_unnamed(context->priv_data, "level", p,
- [](const AVOption* opt) {
- if (opt->default_val.i64 == 0)
- return true;
- return false;
- });
+ OBS_COMBO_FORMAT_STRING);
+
+ streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "level", [&p](const AVOption* opt) {
+ if (opt->default_val.i64 == 0) {
+ obs_property_list_add_string(p, D_TRANSLATE(S_STATE_AUTOMATIC), "auto");
+ } else {
+ obs_property_list_add_string(p, opt->name, opt->name);
+ }
+ });
}
}
@@ -182,6 +190,40 @@ void streamfx::encoder::ffmpeg::handler::nvenc_hevc_handler::migrate(obs_data_t*
const AVCodec* codec, AVCodecContext* context)
{
nvenc::migrate(settings, version, codec, context);
+
+ if (version < STREAMFX_MAKE_VERSION(0, 11, 1, 0)) {
+ // Profile
+ if (auto v = obs_data_get_int(settings, ST_KEY_PROFILE); v != -1) {
+ if (!obs_data_has_user_value(settings, ST_KEY_PROFILE))
+ v = 0;
+
+ std::map preset{
+ {0, "main"},
+ {1, "main10"},
+ {2, "rext"},
+ };
+ if (auto k = preset.find(v); k != preset.end()) {
+ obs_data_set_string(settings, ST_KEY_PROFILE, k->second.data());
+ }
+ }
+
+ // Tier
+ if (auto v = obs_data_get_int(settings, ST_KEY_TIER); v != -1) {
+ if (!obs_data_has_user_value(settings, ST_KEY_TIER))
+ v = 0;
+
+ std::map preset{
+ {0, "main"},
+ {1, "high"},
+ };
+ if (auto k = preset.find(v); k != preset.end()) {
+ obs_data_set_string(settings, ST_KEY_TIER, k->second.data());
+ }
+ }
+
+ // Level
+ obs_data_set_string(settings, ST_KEY_LEVEL, "auto");
+ }
}
bool nvenc_hevc_handler::supports_reconfigure(ffmpeg_factory* instance, bool& threads, bool& gpu, bool& keyframes)
diff --git a/source/encoders/handlers/nvenc_shared.cpp b/source/encoders/handlers/nvenc_shared.cpp
index 4426ac8f1a..2f6de97bf7 100644
--- a/source/encoders/handlers/nvenc_shared.cpp
+++ b/source/encoders/handlers/nvenc_shared.cpp
@@ -162,10 +162,12 @@ void nvenc::override_update(ffmpeg_instance* instance, obs_data_t*)
void nvenc::get_defaults(obs_data_t* settings, const AVCodec*, AVCodecContext*)
{
- obs_data_set_default_int(settings, ST_KEY_PRESET, -1);
+ obs_data_set_default_string(settings, ST_KEY_PRESET, "default");
+ obs_data_set_default_string(settings, ST_I18N_TUNE, "hq");
- obs_data_set_default_int(settings, ST_KEY_RATECONTROL_MODE, -1);
+ obs_data_set_default_string(settings, ST_KEY_RATECONTROL_MODE, "cbr");
obs_data_set_default_int(settings, ST_KEY_RATECONTROL_TWOPASS, -1);
+ obs_data_set_default_int(settings, ST_KEY_RATECONTROL_MULTIPASS, -1);
obs_data_set_default_int(settings, ST_KEY_RATECONTROL_LOOKAHEAD, -1);
obs_data_set_default_int(settings, ST_KEY_RATECONTROL_ADAPTIVEI, -1);
obs_data_set_default_int(settings, ST_KEY_RATECONTROL_ADAPTIVEB, -1);
@@ -200,21 +202,21 @@ void nvenc::get_defaults(obs_data_t* settings, const AVCodec*, AVCodecContext*)
static bool modified_ratecontrol(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
{
// Decode the name into useful flags.
- auto value = obs_data_get_int(settings, ST_KEY_RATECONTROL_MODE);
+ auto value = obs_data_get_string(settings, ST_KEY_RATECONTROL_MODE);
bool have_bitrate = false;
bool have_bitrate_range = false;
bool have_quality = false;
bool have_qp_limits = false;
bool have_qp = false;
- if (value == 2) {
+ if (value == std::string_view("cbr")) {
have_bitrate = true;
- } else if (value == 1) {
+ } else if (value == std::string_view("vbr")) {
have_bitrate = true;
have_bitrate_range = true;
have_quality = true;
have_qp_limits = true;
have_qp = true;
- } else if (value == 0) {
+ } else if (value == std::string_view("constqp")) {
have_qp = true;
} else {
have_bitrate = true;
@@ -251,14 +253,22 @@ void nvenc::get_properties_pre(obs_properties_t* props, const AVCodec*, const AV
{
{
auto p = obs_properties_add_list(props, ST_KEY_PRESET, D_TRANSLATE(ST_I18N_PRESET), OBS_COMBO_TYPE_LIST,
- OBS_COMBO_FORMAT_INT);
- streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "preset", p, ST_I18N_PRESET);
+ OBS_COMBO_FORMAT_STRING);
+ streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "preset", [&p](const AVOption* opt) {
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "%s.%s\0", ST_I18N_PRESET, opt->name);
+ obs_property_list_add_string(p, D_TRANSLATE(buffer), opt->name);
+ });
}
if (streamfx::ffmpeg::tools::avoption_exists(context->priv_data, "tune")) {
auto p = obs_properties_add_list(props, ST_KEY_TUNE, D_TRANSLATE(ST_I18N_TUNE), OBS_COMBO_TYPE_LIST,
- OBS_COMBO_FORMAT_INT);
- streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "tune", p, ST_I18N_TUNE);
+ OBS_COMBO_FORMAT_STRING);
+ streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "tune", [&p](const AVOption* opt) {
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "%s.%s\0", ST_I18N_TUNE, opt->name);
+ obs_property_list_add_string(p, D_TRANSLATE(buffer), opt->name);
+ });
}
}
@@ -274,24 +284,31 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec, c
{
auto p = obs_properties_add_list(grp, ST_KEY_RATECONTROL_MODE, D_TRANSLATE(ST_I18N_RATECONTROL_MODE),
- OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
+ OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_property_set_modified_callback(p, modified_ratecontrol);
- auto filter = [](const AVOption* opt) {
+ obs_property_list_add_string(p, D_TRANSLATE(S_STATE_DEFAULT), "");
+ streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "rc", [&p](const AVOption* opt) {
+ // Ignore options that are "deprecated" but not flagged as such.
if (opt->default_val.i64 & (1 << 23))
- return true;
- return false;
- };
- streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "rc", p, ST_I18N_RATECONTROL_MODE,
- filter);
+ return;
+
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "%s.%s\0", ST_I18N_RATECONTROL_MODE, opt->name);
+ obs_property_list_add_string(p, D_TRANSLATE(buffer), opt->name);
+ });
}
if (streamfx::ffmpeg::tools::avoption_exists(context->priv_data, "multipass")) {
auto p =
obs_properties_add_list(grp, ST_KEY_RATECONTROL_MULTIPASS, D_TRANSLATE(ST_I18N_RATECONTROL_MULTIPASS),
- OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
- obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), -1);
- streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "multipass", p,
- ST_I18N_RATECONTROL_MULTIPASS);
+ OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
+ obs_property_list_add_string(p, D_TRANSLATE(S_STATE_DEFAULT), "");
+ streamfx::ffmpeg::tools::avoption_list_add_entries(
+ context->priv_data, "multipass", [&p](const AVOption* opt) {
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "%s.%s\0", ST_I18N_RATECONTROL_MULTIPASS, opt->name);
+ obs_property_list_add_string(p, D_TRANSLATE(buffer), opt->name);
+ });
} else {
auto p = streamfx::util::obs_properties_add_tristate(grp, ST_KEY_RATECONTROL_TWOPASS,
D_TRANSLATE(ST_I18N_RATECONTROL_TWOPASS));
@@ -419,10 +436,14 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec, c
{
auto p = obs_properties_add_list(grp, ST_KEY_OTHER_BFRAMEREFERENCEMODE,
D_TRANSLATE(ST_I18N_OTHER_BFRAMEREFERENCEMODE), OBS_COMBO_TYPE_LIST,
- OBS_COMBO_FORMAT_INT);
- obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), -1);
- streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "b_ref_mode", p,
- ST_I18N_OTHER_BFRAMEREFERENCEMODE);
+ OBS_COMBO_FORMAT_STRING);
+ obs_property_list_add_string(p, D_TRANSLATE(S_STATE_DEFAULT), "");
+ streamfx::ffmpeg::tools::avoption_list_add_entries(
+ context->priv_data, "b_ref_mode", [&p](const AVOption* opt) {
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "%s.%s\0", ST_I18N_OTHER_BFRAMEREFERENCEMODE, opt->name);
+ obs_property_list_add_string(p, D_TRANSLATE(buffer), opt->name);
+ });
}
{
@@ -492,27 +513,15 @@ void nvenc::get_runtime_properties(obs_properties_t* props, const AVCodec*, AVCo
void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context)
{
- if (!context->internal) {
- auto value = obs_data_get_int(settings, ST_KEY_PRESET);
- if (value != -1) {
- auto name = streamfx::ffmpeg::tools::avoption_name_from_unit_value(context->priv_data, "preset", value);
- if (name) {
- av_opt_set(context->priv_data, "preset", name, AV_OPT_SEARCH_CHILDREN);
- } else {
- av_opt_set_int(context->priv_data, "preset", value, AV_OPT_SEARCH_CHILDREN);
- }
- }
+ if (auto v = obs_data_get_string(settings, ST_KEY_PRESET);
+ !context->internal && (v != nullptr) && (strlen(v) > 0)) {
+ av_opt_set(context->priv_data, "preset", v, AV_OPT_SEARCH_CHILDREN);
}
{ // Rate Control
- auto value = obs_data_get_int(settings, ST_KEY_RATECONTROL_MODE);
- auto name = streamfx::ffmpeg::tools::avoption_name_from_unit_value(context->priv_data, "rc", value);
- if (value != -1) {
- if (name && !context->internal) {
- av_opt_set(context->priv_data, "rc", name, AV_OPT_SEARCH_CHILDREN);
- } else {
- av_opt_set_int(context->priv_data, "rc", value, AV_OPT_SEARCH_CHILDREN);
- }
+ auto v = obs_data_get_string(settings, ST_KEY_RATECONTROL_MODE);
+ if (!context->internal && (v != nullptr) && (strlen(v) > 0)) {
+ av_opt_set(context->priv_data, "rc", v, AV_OPT_SEARCH_CHILDREN);
}
// Decode the name into useful flags.
@@ -521,7 +530,7 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
bool have_quality = false;
bool have_qp_limits = false;
bool have_qp = false;
- if (is_cbr(name)) {
+ if (v && is_cbr(v)) {
have_bitrate = true;
if (!context->internal)
@@ -529,7 +538,7 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
// Support for OBS Studio
obs_data_set_string(settings, "rate_control", "CBR");
- } else if (is_vbr(name)) {
+ } else if (v && is_vbr(v)) {
have_bitrate = true;
have_bitrate_range = true;
have_quality = true;
@@ -541,7 +550,7 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
// Support for OBS Studio
obs_data_set_string(settings, "rate_control", "VBR");
- } else if (is_cqp(name)) {
+ } else if (v && is_cqp(v)) {
have_qp = true;
if (!context->internal)
@@ -563,8 +572,9 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
if (!context->internal) {
if (streamfx::ffmpeg::tools::avoption_exists(context->priv_data, "multipass")) {
// Multi-Pass
- if (int tp = static_cast(obs_data_get_int(settings, ST_KEY_RATECONTROL_MULTIPASS)); tp > -1) {
- av_opt_set_int(context->priv_data, "multipass", tp, AV_OPT_SEARCH_CHILDREN);
+ if (auto v = obs_data_get_string(settings, ST_KEY_RATECONTROL_MULTIPASS);
+ (v != nullptr) && (strlen(v) > 0)) {
+ av_opt_set(context->priv_data, "multipass", v, AV_OPT_SEARCH_CHILDREN);
av_opt_set_int(context->priv_data, "2pass", 0, AV_OPT_SEARCH_CHILDREN);
}
} else {
@@ -707,8 +717,9 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
av_opt_set_int(context->priv_data, "weighted_pred", wp, AV_OPT_SEARCH_CHILDREN);
}
- if (auto v = obs_data_get_int(settings, ST_KEY_OTHER_BFRAMEREFERENCEMODE); v > -1) {
- av_opt_set_int(context->priv_data, "b_ref_mode", v, AV_OPT_SEARCH_CHILDREN);
+ if (auto v = obs_data_get_string(settings, ST_KEY_OTHER_BFRAMEREFERENCEMODE);
+ (v != nullptr) && (strlen(v) > 0)) {
+ av_opt_set(context->priv_data, "b_ref_mode", v, AV_OPT_SEARCH_CHILDREN);
}
if (auto v = obs_data_get_int(settings, ST_KEY_OTHER_LOWDELAYKEYFRAMESCALE); v > -1) {
@@ -810,29 +821,59 @@ void streamfx::encoder::ffmpeg::handler::nvenc::migrate(obs_data_t* settings, ui
}
if (version < STREAMFX_MAKE_VERSION(0, 11, 1, 0)) {
+ // Preset
+ if (auto v = obs_data_get_int(settings, ST_KEY_PRESET); v != -1) {
+ std::map preset{
+ {0, "default"}, {1, "slow"}, {2, "medium"}, {3, "fast"}, {4, "hp"}, {5, "hq"},
+ {6, "bd"}, {7, "ll"}, {8, "llhq"}, {9, "llhp"}, {10, "lossless"}, {11, "losslesshp"},
+ };
+ if (auto k = preset.find(v); k != preset.end()) {
+ obs_data_set_string(settings, ST_KEY_PRESET, k->second.data());
+ }
+ }
+
+ // Rate Control Mode
if (auto v = obs_data_get_int(settings, ST_KEY_RATECONTROL_MODE); v != -1) {
+ if (!obs_data_has_user_value(settings, ST_KEY_RATECONTROL_MODE))
+ v = 4;
+
switch (v) {
case 0: // CQP
+ obs_data_set_string(settings, ST_KEY_RATECONTROL_MODE, "constqp");
break;
case 2: // VBR_HQ
- obs_data_set_int(settings, ST_KEY_RATECONTROL_MODE, 1);
obs_data_set_int(settings, ST_KEY_RATECONTROL_TWOPASS, 1);
- obs_data_set_int(settings, ST_KEY_RATECONTROL_MULTIPASS, 1);
+ obs_data_set_string(settings, ST_KEY_RATECONTROL_MULTIPASS, "qres");
case 1: // VBR
+ obs_data_set_string(settings, ST_KEY_RATECONTROL_MODE, "vbr");
break;
case 5: // CBR_LD_HQ
obs_data_set_int(settings, ST_KEY_OTHER_LOWDELAYKEYFRAMESCALE, 1);
case 4: // CBR_HQ
- obs_data_set_int(settings, ST_KEY_RATECONTROL_MODE, 2);
obs_data_set_int(settings, ST_KEY_RATECONTROL_TWOPASS, 1);
- obs_data_set_int(settings, ST_KEY_RATECONTROL_MULTIPASS, 1);
+ obs_data_set_string(settings, ST_KEY_RATECONTROL_MULTIPASS, "qres");
case 3: // CBR
+ obs_data_set_string(settings, ST_KEY_RATECONTROL_MODE, "cbr");
break;
}
}
+
+ // Target Quality
if (auto v = obs_data_get_double(settings, ST_KEY_RATECONTROL_LIMITS_QUALITY); v > 0) {
obs_data_set_double(settings, ST_KEY_RATECONTROL_LIMITS_QUALITY, (v / 100.) * 51.);
}
+
+ // B-Frame Reference Modes
+ if (auto v = obs_data_get_int(settings, ST_KEY_OTHER_BFRAMEREFERENCEMODE); v != -1) {
+ std::map preset{
+ {0, "default"},
+ {1, "each"},
+ {2, "middle"},
+ };
+ if (auto k = preset.find(v); k != preset.end()) {
+ obs_data_set_string(settings, ST_KEY_OTHER_BFRAMEREFERENCEMODE, k->second.data());
+ }
+ }
}
#undef COPY_UNSET
From f93d5c2202d624846dc8095ca3dad87d469a9a21 Mon Sep 17 00:00:00 2001
From: Chris Pence <6cpence@gmail.com>
Date: Thu, 24 Feb 2022 12:12:37 -0800
Subject: [PATCH 008/164] encoder/ffmpeg: Remove legacy API usage (#783)
The build breaks if compiling against a newer version of ffmpeg which does not define the FF_API_NEXT macro and has fully removed the av_codec_next() API.
---
source/encoders/encoder-ffmpeg.cpp | 17 -----------------
1 file changed, 17 deletions(-)
diff --git a/source/encoders/encoder-ffmpeg.cpp b/source/encoders/encoder-ffmpeg.cpp
index a913cb0ac0..737ff96569 100644
--- a/source/encoders/encoder-ffmpeg.cpp
+++ b/source/encoders/encoder-ffmpeg.cpp
@@ -1180,7 +1180,6 @@ ffmpeg_manager::~ffmpeg_manager()
void ffmpeg_manager::register_encoders()
{
// Encoders
-#if FF_API_NEXT
void* iterator = nullptr;
for (const AVCodec* codec = av_codec_iterate(&iterator); codec != nullptr; codec = av_codec_iterate(&iterator)) {
// Only register encoders.
@@ -1195,22 +1194,6 @@ void ffmpeg_manager::register_encoders()
}
}
}
-#else
- AVCodec* codec = nullptr;
- for (codec = av_codec_next(codec); codec != nullptr; codec = av_codec_next(codec)) {
- // Only register encoders.
- if (!av_codec_is_encoder(codec))
- continue;
-
- if ((codec->type == AVMediaType::AVMEDIA_TYPE_AUDIO) || (codec->type == AVMediaType::AVMEDIA_TYPE_VIDEO)) {
- try {
- _factories.emplace(codec, std::make_shared(codec));
- } catch (const std::exception& ex) {
- DLOG_ERROR("Failed to register encoder '%s': %s", codec->name, ex.what());
- }
- }
- }
-#endif
}
void ffmpeg_manager::register_handler(std::string codec, std::shared_ptr handler)
From a6b11f68d38d8dae433337c1ad6ba338190e10c4 Mon Sep 17 00:00:00 2001
From: Xaymar
Date: Sat, 26 Feb 2022 20:29:49 +0100
Subject: [PATCH 009/164] locale: New Crowdin updates (#778)
* New translations en-US.ini (Finnish)
* New translations en-US.ini (Finnish)
* New translations en-US.ini (German)
* New translations en-US.ini (Chinese Simplified)
---
data/locale/de-DE.ini | 21 +++++++++++++++++++++
data/locale/fi-FI.ini | 41 ++++++++++++++++++++++++++++++++++++++++-
data/locale/zh-CN.ini | 26 ++++++++++++++++++++++++++
3 files changed, 87 insertions(+), 1 deletion(-)
diff --git a/data/locale/de-DE.ini b/data/locale/de-DE.ini
index b72fd4f560..056b4beb2a 100644
--- a/data/locale/de-DE.ini
+++ b/data/locale/de-DE.ini
@@ -158,10 +158,30 @@ Encoder.FFmpeg.NVENC.Preset.default="Standard"
Encoder.FFmpeg.NVENC.Preset.slow="Langsam"
Encoder.FFmpeg.NVENC.Preset.medium="Mittel"
Encoder.FFmpeg.NVENC.Preset.fast="Schnell"
+Encoder.FFmpeg.NVENC.Preset.hp="Hohe Leistung"
+Encoder.FFmpeg.NVENC.Preset.hq="Hohe Qualität"
+Encoder.FFmpeg.NVENC.Preset.bd="BluRay Disc"
+Encoder.FFmpeg.NVENC.Preset.ll="Niedrige Latenz"
+Encoder.FFmpeg.NVENC.Preset.llhq="Niedrige Latenz, Hohe Qualität"
+Encoder.FFmpeg.NVENC.Preset.llhp="Niedrige Latenz, Hohe Leistung"
+Encoder.FFmpeg.NVENC.Preset.lossless="Verlustfrei"
+Encoder.FFmpeg.NVENC.Preset.losslesshp="Verlusfrei, Hohe Leistung"
+Encoder.FFmpeg.NVENC.Preset.p1="Am Schnellsten (P1)"
+Encoder.FFmpeg.NVENC.Preset.p2="Schneller (P2)"
+Encoder.FFmpeg.NVENC.Preset.p3="Schnell (P3)"
+Encoder.FFmpeg.NVENC.Preset.p4="Mittel (P4)"
+Encoder.FFmpeg.NVENC.Preset.p5="Langsam (P5)"
+Encoder.FFmpeg.NVENC.Preset.p6="Langsamer (P6)"
+Encoder.FFmpeg.NVENC.Preset.p7="Am Langsamsten (P7)"
Encoder.FFmpeg.NVENC.Tune="Justierung"
+Encoder.FFmpeg.NVENC.Tune.hq="Hohe Qualität"
+Encoder.FFmpeg.NVENC.Tune.ll="Niedrige Latenz"
+Encoder.FFmpeg.NVENC.Tune.ull="Sehr Niedrige Latenz"
+Encoder.FFmpeg.NVENC.Tune.lossless="Verlustfrei"
Encoder.FFmpeg.NVENC.RateControl="Ratenkontrollmethode"
Encoder.FFmpeg.NVENC.RateControl.Mode="Modus"
Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Parameter für Konstante Quantisierung"
+Encoder.FFmpeg.NVENC.RateControl.Mode.vbr="Variable Bitrate"
Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Konstante Bitrate"
Encoder.FFmpeg.NVENC.RateControl.TwoPass="Zwei Durchläufe"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Vorausschauen"
@@ -189,6 +209,7 @@ Encoder.FFmpeg.NVENC.Other.ZeroLatency="Null Latenz"
Encoder.FFmpeg.NVENC.Other.WeightedPrediction="Gewichtete Vorhersage"
Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="Nicht-referenzierte P-Bilder"
Encoder.FFmpeg.NVENC.Other.ReferenceFrames="Referenzbilder"
+Encoder.FFmpeg.NVENC.Other.LowDelayKeyFrameScale="Key-Frame Skala mit geringer Verzögerung"
Blur.Type.Box="Box"
Blur.Type.BoxLinear="Box Linear"
diff --git a/data/locale/fi-FI.ini b/data/locale/fi-FI.ini
index 1a77b3b60b..fff7bc0ec7 100644
--- a/data/locale/fi-FI.ini
+++ b/data/locale/fi-FI.ini
@@ -1,4 +1,5 @@
Advanced="Lisävalinnat"
+Manual.Open="Avaa käyttöopas"
Channel.Red="Punainen"
Channel.Green="Vihreä"
@@ -24,12 +25,19 @@ State.Automatic="Automaattinen"
State.Default="Oletus"
UI.Menu="StreamFX"
+UI.Menu.Wiki="Lue Wikiä"
+UI.Menu.Support="Apu && Tuki"
+UI.Menu.Website="Käy StreamFXn nettisivulla"
+UI.Menu.Discord="Liity StreamFX Discordiin"
+UI.Menu.Twitter="Seuraa StreamFXää Twitterissä"
+UI.Menu.YouTube="Tilaa StreamFX YouTubessa"
UI.Menu.About="Tietoja StreamFX:stä"
UI.About.Title="Tietoja StreamFX:stä"
UI.About.Text="StremFX on tehty mahdolliseksi tukijoiden puolesta Patreon ja Github Sponsorssivustoilta, myös kaikkineen lahjoituksineen PayPal puolelta. Lisäkiitokset myös kaikille kääntäjille, jotka auttavat tekstien lokalisaatioinnissa Crowdin palvelussa. Olette kaikki mahtavia!
"
UI.About.Role.Contributor="Avustaja"
UI.About.Role.Translator="Kääntäjä"
+UI.About.Role.Supporter="Tukija"
UI.About.Version="Versio:"
UI.Updater.Dialog.Title="StreamFX versio %s on nyt saatavilla!"
@@ -46,10 +54,41 @@ UI.Updater.Menu.Channel="Päivityskanava"
UI.Updater.Menu.Channel.Release="Julkaisu"
UI.Updater.Menu.Channel.Testing="Testaus"
-
+Encoder.AOM.AV1="AOM AV1 (suora)"
+Encoder.AOM.AV1.Encoder="Enkooderi"
+Encoder.AOM.AV1.Encoder.Usage="Käyttö"
+Encoder.AOM.AV1.Encoder.Usage.GoodQuality="Hyvä Laatu"
+Encoder.AOM.AV1.Encoder.Usage.RealTime="Reaaliaikainen"
+Encoder.AOM.AV1.Encoder.Usage.AllIntra="Kaikki Intra-Frame"
+Encoder.AOM.AV1.Encoder.CPUUsage="CPU-käyttö"
+Encoder.AOM.AV1.Encoder.CPUUsage.0="Placebo"
+Encoder.AOM.AV1.Encoder.CPUUsage.1="Erittäin hidas"
+Encoder.AOM.AV1.Encoder.CPUUsage.2="Hitaampi"
+Encoder.AOM.AV1.Encoder.CPUUsage.3="Hidas"
+Encoder.AOM.AV1.Encoder.CPUUsage.4="Keskinopea"
+Encoder.AOM.AV1.Encoder.CPUUsage.5="Nopea"
+Encoder.AOM.AV1.Encoder.CPUUsage.6="Nopeampi"
+Encoder.AOM.AV1.Encoder.CPUUsage.7="Erittäin nopea"
+Encoder.AOM.AV1.Encoder.CPUUsage.8="Super Nopea"
+Encoder.AOM.AV1.Encoder.CPUUsage.9="Ultra nopea"
+Encoder.AOM.AV1.Encoder.CPUUsage.10="Mielettömän nopea"
+Encoder.AOM.AV1.Encoder.Profile="Profiili"
+Encoder.AOM.AV1.KeyFrames.IntervalType="Aikaväli Tyyppi"
+Encoder.AOM.AV1.KeyFrames.IntervalType.Frames="Framet"
+Encoder.AOM.AV1.KeyFrames.IntervalType.Seconds="Sekunnit"
+Encoder.AOM.AV1.KeyFrames.Interval="Aikaväli"
+Encoder.AOM.AV1.RateControl="Rate Control -tila"
+
+Encoder.FFmpeg.KeyFrames.IntervalType="Aikaväli Tyyppi"
+Encoder.FFmpeg.KeyFrames.IntervalType.Frames="Framet"
+Encoder.FFmpeg.KeyFrames.IntervalType.Seconds="Sekunnit"
+Encoder.FFmpeg.KeyFrames.Interval="Aikaväli"
Encoder.FFmpeg.NVENC.Preset.default="Oletus"
+Encoder.FFmpeg.NVENC.Preset.slow="Hidas"
+Encoder.FFmpeg.NVENC.Preset.medium="Keskinopea"
+Encoder.FFmpeg.NVENC.Preset.fast="Nopea"
Blur.Type.Box="Kuutiollinen"
Blur.Type.BoxLinear="Kuutio lineaarinen"
diff --git a/data/locale/zh-CN.ini b/data/locale/zh-CN.ini
index b67633560c..4b8ba116e9 100644
--- a/data/locale/zh-CN.ini
+++ b/data/locale/zh-CN.ini
@@ -158,12 +158,34 @@ Encoder.FFmpeg.NVENC.Preset.default="默认"
Encoder.FFmpeg.NVENC.Preset.slow="慢速"
Encoder.FFmpeg.NVENC.Preset.medium="中等"
Encoder.FFmpeg.NVENC.Preset.fast="快速"
+Encoder.FFmpeg.NVENC.Preset.hp="高性能"
+Encoder.FFmpeg.NVENC.Preset.hq="高质量"
+Encoder.FFmpeg.NVENC.Preset.bd="蓝光光盘"
+Encoder.FFmpeg.NVENC.Preset.ll="低延迟"
+Encoder.FFmpeg.NVENC.Preset.llhq="低延迟高质量"
+Encoder.FFmpeg.NVENC.Preset.llhp="低延迟高性能"
+Encoder.FFmpeg.NVENC.Preset.lossless="无损"
+Encoder.FFmpeg.NVENC.Preset.losslesshp="无损高性能"
+Encoder.FFmpeg.NVENC.Preset.p1="最快的 (P1)"
+Encoder.FFmpeg.NVENC.Preset.p2="更快(P2)"
+Encoder.FFmpeg.NVENC.Preset.p3="快 (P3)"
+Encoder.FFmpeg.NVENC.Preset.p4="中等(P4)"
+Encoder.FFmpeg.NVENC.Preset.p5="慢(P5)"
+Encoder.FFmpeg.NVENC.Preset.p6="更慢(P6)"
+Encoder.FFmpeg.NVENC.Preset.p7="最慢(P7)"
Encoder.FFmpeg.NVENC.Tune="微调(Tune)"
+Encoder.FFmpeg.NVENC.Tune.hq="高质量"
+Encoder.FFmpeg.NVENC.Tune.ll="低延迟"
+Encoder.FFmpeg.NVENC.Tune.ull="超低延迟"
+Encoder.FFmpeg.NVENC.Tune.lossless="无损"
Encoder.FFmpeg.NVENC.RateControl="速率控制选项"
Encoder.FFmpeg.NVENC.RateControl.Mode="模式"
Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="恒量化参数"
+Encoder.FFmpeg.NVENC.RateControl.Mode.vbr="可变比特率"
Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="恒定比特率"
Encoder.FFmpeg.NVENC.RateControl.TwoPass="双通道"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass="多路径"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.disabled="单次通过"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="预测(Look Ahead)"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="自适应 I 帧"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveB="自适应 B 帧"
@@ -185,10 +207,14 @@ Encoder.FFmpeg.NVENC.AQ.Temporal="时间自适应量化"
Encoder.FFmpeg.NVENC.Other="其它选项"
Encoder.FFmpeg.NVENC.Other.BFrames="最大 B 帧"
Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode="B 帧参考模式"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.disabled="没有 B 帧将被用作参考"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.middle="仅使用 B-Frames/2 作为参考"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.each="每个 B 帧将用于参考"
Encoder.FFmpeg.NVENC.Other.ZeroLatency="零延迟"
Encoder.FFmpeg.NVENC.Other.WeightedPrediction="加权预测"
Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="非参考 P 帧"
Encoder.FFmpeg.NVENC.Other.ReferenceFrames="参考帧"
+Encoder.FFmpeg.NVENC.Other.LowDelayKeyFrameScale="低延迟键帧比例"
Blur.Type.Box="Box(快速均值)"
Blur.Type.BoxLinear="Box Linear(均值线性)"
From 0540a18f27a7969c07eb150668033155626949f8 Mon Sep 17 00:00:00 2001
From: "carsten.braun"
Date: Thu, 24 Feb 2022 23:04:32 +0100
Subject: [PATCH 010/164] encoders/ffmpeg/dnxhr: Add Avid DNxHR Encoder based
on FFmpeg
---
CMakeLists.txt | 18 ++++
data/locale/en-US.ini | 9 ++
source/encoders/codecs/dnxhr.cpp | 1 +
source/encoders/codecs/dnxhr.hpp | 29 ++++++
source/encoders/encoder-ffmpeg.cpp | 7 ++
source/encoders/handlers/dnxhd_handler.cpp | 108 +++++++++++++++++++++
source/encoders/handlers/dnxhd_handler.hpp | 68 +++++++++++++
7 files changed, 240 insertions(+)
create mode 100644 source/encoders/codecs/dnxhr.cpp
create mode 100644 source/encoders/codecs/dnxhr.hpp
create mode 100644 source/encoders/handlers/dnxhd_handler.cpp
create mode 100644 source/encoders/handlers/dnxhd_handler.hpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ae46d31fcb..acaa87c67a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -293,6 +293,7 @@ set(${PREFIX}ENABLE_ENCODER_FFMPEG ON CACHE BOOL "Enable FFmpeg Encoder integrat
set(${PREFIX}ENABLE_ENCODER_FFMPEG_AMF ON CACHE BOOL "Enable AMF Encoder in FFmpeg.")
set(${PREFIX}ENABLE_ENCODER_FFMPEG_NVENC ON CACHE BOOL "Enable NVENC Encoder in FFmpeg.")
set(${PREFIX}ENABLE_ENCODER_FFMPEG_PRORES ON CACHE BOOL "Enable ProRes Encoder in FFmpeg.")
+set(${PREFIX}ENABLE_ENCODER_FFMPEG_DNXHR ON CACHE BOOL "Enable DNXHR Encoder in FFmpeg.")
set(${PREFIX}ENABLE_ENCODER_AOM_AV1 ON CACHE BOOL "Enable AOM AV1 Encoder.")
## Filters
@@ -665,6 +666,9 @@ function(feature_encoder_ffmpeg RESOLVE)
# ProRes
is_feature_enabled(ENCODER_FFMPEG_PRORES T_CHECK)
+
+ # DNxHR
+ is_feature_enabled(ENCODER_FFMPEG_DNXHR T_CHECK)
endif()
elseif(T_CHECK)
set(REQUIRE_FFMPEG ON PARENT_SCOPE)
@@ -1315,6 +1319,8 @@ if(T_CHECK)
"source/encoders/codecs/h264.cpp"
"source/encoders/codecs/prores.hpp"
"source/encoders/codecs/prores.cpp"
+ "source/encoders/codecs/dnxhr.hpp"
+ "source/encoders/codecs/dnxhr.cpp"
# Encoders/Handlers
"source/encoders/handlers/handler.hpp"
@@ -1368,6 +1374,18 @@ if(T_CHECK)
list(APPEND PROJECT_DEFINITIONS
ENABLE_ENCODER_FFMPEG_PRORES
)
+ endif()
+
+ # DNxHR
+ is_feature_enabled(ENCODER_FFMPEG_DNXHR T_CHECK)
+ if(T_CHECK)
+ list(APPEND PROJECT_PRIVATE_SOURCE
+ "source/encoders/handlers/dnxhd_handler.hpp"
+ "source/encoders/handlers/dnxhd_handler.cpp"
+ )
+ list(APPEND PROJECT_DEFINITIONS
+ ENABLE_ENCODER_FFMPEG_DNXHR
+ )
endif()
endif()
diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini
index 9b9454ce30..aaa7b062dd 100644
--- a/data/locale/en-US.ini
+++ b/data/locale/en-US.ini
@@ -526,3 +526,12 @@ Codec.ProRes.Profile.APCN="422 Standard (APCN)"
Codec.ProRes.Profile.APCH="422 High Quality/HQ (APCH)"
Codec.ProRes.Profile.AP4H="4444 High Quality/HQ (AP4H)"
Codec.ProRes.Profile.AP4X="4444 Extreme Quality/XQ (AP4X)"
+
+# Codec: Avid DNxHR
+Codec.DNxHR.Profile="Profile"
+Codec.DNxHR.Profile.dnxhd="DNxHD"
+Codec.DNxHR.Profile.dnxhr_lb="DNxHR LB (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_sq="DNxHR SQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hq="DNxHR HQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hqx="DNxHR HQX (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_444="DNxHR 444 (4:4:4)"
diff --git a/source/encoders/codecs/dnxhr.cpp b/source/encoders/codecs/dnxhr.cpp
new file mode 100644
index 0000000000..0a33512866
--- /dev/null
+++ b/source/encoders/codecs/dnxhr.cpp
@@ -0,0 +1 @@
+#include "dnxhr.hpp"
diff --git a/source/encoders/codecs/dnxhr.hpp b/source/encoders/codecs/dnxhr.hpp
new file mode 100644
index 0000000000..dbfd08bd83
--- /dev/null
+++ b/source/encoders/codecs/dnxhr.hpp
@@ -0,0 +1,29 @@
+// FFMPEG based DNxHR Video Encoder Integration for OBS Studio
+// Copyright (c) 2022 Carsten Braun
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma once
+#include "common.hpp"
+
+// Codec: DNxHR
+#define S_CODEC_DNXHR "Codec.DNxHR"
+#define S_CODEC_DNXHR_PROFILE "Codec.DNxHR.Profile"
+
+namespace streamfx::encoder::codec::dnxhr {} // namespace streamfx::encoder::codec::dnxhr
diff --git a/source/encoders/encoder-ffmpeg.cpp b/source/encoders/encoder-ffmpeg.cpp
index 737ff96569..465fcdc7e4 100644
--- a/source/encoders/encoder-ffmpeg.cpp
+++ b/source/encoders/encoder-ffmpeg.cpp
@@ -42,6 +42,10 @@
#include "handlers/prores_aw_handler.hpp"
#endif
+#ifdef ENABLE_ENCODER_FFMPEG_DNXHR
+#include "handlers/dnxhd_handler.hpp"
+#endif
+
extern "C" {
#pragma warning(push)
#pragma warning(disable : 4244)
@@ -1170,6 +1174,9 @@ ffmpeg_manager::ffmpeg_manager() : _factories(), _handlers(), _debug_handler()
#ifdef ENABLE_ENCODER_FFMPEG_PRORES
register_handler("prores_aw", ::std::make_shared());
#endif
+#ifdef ENABLE_ENCODER_FFMPEG_DNXHR
+ register_handler("dnxhd", ::std::make_shared());
+#endif
}
ffmpeg_manager::~ffmpeg_manager()
diff --git a/source/encoders/handlers/dnxhd_handler.cpp b/source/encoders/handlers/dnxhd_handler.cpp
new file mode 100644
index 0000000000..b7d550889e
--- /dev/null
+++ b/source/encoders/handlers/dnxhd_handler.cpp
@@ -0,0 +1,108 @@
+#include "dnxhd_handler.hpp"
+#include
+#include "../codecs/dnxhr.hpp"
+#include "ffmpeg/tools.hpp"
+#include "plugin.hpp"
+
+extern "C" {
+#include
+}
+
+using namespace streamfx::encoder::ffmpeg::handler;
+using namespace streamfx::encoder::codec::dnxhr;
+
+void dnxhd_handler::adjust_info(ffmpeg_factory* fac, const AVCodec*, std::string&, std::string& name, std::string&)
+{
+ //Most people don't know what VC3 is and only know it as DNx.
+ //Change name to make it easier to find.
+ name = "Avid DNxHR (via FFmpeg)";
+}
+
+void dnxhd_handler::override_colorformat(AVPixelFormat& target_format, obs_data_t* settings, const AVCodec* codec,
+ AVCodecContext*)
+{
+ static const std::array, static_cast(5)> profile_to_format_map{
+ std::pair{"dnxhr_lb", AV_PIX_FMT_YUV422P}, std::pair{"dnxhr_sq", AV_PIX_FMT_YUV422P},
+ std::pair{"dnxhr_hq", AV_PIX_FMT_YUV422P}, std::pair{"dnxhr_hqx", AV_PIX_FMT_YUV422P10LE},
+ std::pair{"dnxhr_444", AV_PIX_FMT_YUV444P10LE}};
+
+ const char* selected_profile = obs_data_get_string(settings, S_CODEC_DNXHR_PROFILE);
+ for (auto kv : profile_to_format_map) {
+ if (strcmp(kv.first, selected_profile) == 0) {
+ target_format = kv.second;
+ return;
+ }
+ }
+
+ //Fallback for (yet) unknown formats
+ target_format = AV_PIX_FMT_YUV422P;
+}
+
+void dnxhd_handler::get_defaults(obs_data_t* settings, const AVCodec*, AVCodecContext*, bool)
+{
+ obs_data_set_default_string(settings, S_CODEC_DNXHR_PROFILE, "dnxhr_sq");
+}
+
+bool dnxhd_handler::has_keyframe_support(ffmpeg_factory* instance)
+{
+ return false;
+}
+
+bool dnxhd_handler::has_pixel_format_support(ffmpeg_factory* instance)
+{
+ return false;
+}
+
+inline const char* dnx_profile_to_display_name(const char* profile)
+{
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "%s.%s\0", S_CODEC_DNXHR_PROFILE, profile);
+ return D_TRANSLATE(buffer);
+}
+
+void dnxhd_handler::get_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context, bool)
+{
+ AVCodecContext* ctx = context;
+
+ //Create dummy context if null was passed to the function
+ if (!ctx) {
+ ctx = avcodec_alloc_context3(codec);
+ if (!ctx->priv_data) {
+ avcodec_free_context(&ctx);
+ return;
+ }
+ }
+ auto p = obs_properties_add_list(props, S_CODEC_DNXHR_PROFILE, D_TRANSLATE(S_CODEC_DNXHR_PROFILE),
+ OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
+
+ streamfx::ffmpeg::tools::avoption_list_add_entries(ctx->priv_data, "profile", [&p](const AVOption* opt) {
+ if (strcmp(opt->name, "dnxhd") == 0) {
+ //Do not show DNxHD profile as it is outdated and should not be used.
+ //It's also very picky about framerate and framesize combos, which makes it even less useful
+ return;
+ }
+
+ //ffmpeg returns the profiles for DNxHR from highest to lowest.
+ //Lowest to highest is what people usually expect.
+ //Therefore, new entries will always be inserted at the top, effectively reversing the list
+ obs_property_list_insert_string(p, 0, dnx_profile_to_display_name(opt->name), opt->name);
+ });
+
+ //Free context if we created it here
+ if (ctx && ctx != context) {
+ avcodec_free_context(&ctx);
+ }
+}
+
+void dnxhd_handler::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context)
+{
+ const char* profile = obs_data_get_string(settings, S_CODEC_DNXHR_PROFILE);
+ av_opt_set(context, "profile", profile, AV_OPT_SEARCH_CHILDREN);
+}
+
+void dnxhd_handler::log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context)
+{
+ DLOG_INFO("[%s] Avid DNxHR:", codec->name);
+ streamfx::ffmpeg::tools::print_av_option_string2(context, "profile", " Profile",
+ [](int64_t v, std::string_view o) { return std::string(o); });
+}
diff --git a/source/encoders/handlers/dnxhd_handler.hpp b/source/encoders/handlers/dnxhd_handler.hpp
new file mode 100644
index 0000000000..590bf11ed7
--- /dev/null
+++ b/source/encoders/handlers/dnxhd_handler.hpp
@@ -0,0 +1,68 @@
+// FFMPEG based DNxHR Video Encoder Integration for OBS Studio
+// Copyright (c) 2022 Carsten Braun
+// Copyright (c) 2019 Michael Fabian Dirks
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma once
+#include "handler.hpp"
+
+extern "C" {
+#pragma warning(push)
+#pragma warning(disable : 4244)
+#include
+#pragma warning(pop)
+}
+
+namespace streamfx::encoder::ffmpeg::handler {
+ class dnxhd_handler : public handler {
+ public:
+ virtual ~dnxhd_handler(){};
+
+ public /*factory*/:
+ virtual void adjust_info(ffmpeg_factory* factory, const AVCodec* codec, std::string& id, std::string& name,
+ std::string& codec_id);
+
+ public /*factory*/:
+ void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context, bool hw_encode) override;
+
+ virtual std::string_view get_help_url(const AVCodec* codec) override
+ {
+ return "https://github.com/Xaymar/obs-StreamFX/wiki/Encoder-FFmpeg-Avid-DNxHR";
+ };
+
+ public /*support tests*/:
+ virtual bool has_keyframe_support(ffmpeg_factory* instance) override;
+
+ public /*support tests*/:
+ bool has_pixel_format_support(ffmpeg_factory* instance) override;
+
+ public /*settings*/:
+ void get_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context,
+ bool hw_encode) override;
+
+ void update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) override;
+
+ void log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) override;
+
+ public /*instance*/:
+ void override_colorformat(AVPixelFormat& target_format, obs_data_t* settings, const AVCodec* codec,
+ AVCodecContext* context) override;
+ };
+} // namespace streamfx::encoder::ffmpeg::handler
From 56f2ae4290863bec84d7670d8b8a1c884a74b11f Mon Sep 17 00:00:00 2001
From: Xaymar
Date: Thu, 26 May 2022 23:03:58 +0200
Subject: [PATCH 011/164] locale: New Crowdin updates (#786)
* New translations en-US.ini (Arabic)
* New translations en-US.ini (Bosnian)
* New translations en-US.ini (Bulgarian)
* New translations en-US.ini (Chinese Simplified)
* New translations en-US.ini (Chinese Traditional, Hong Kong)
* New translations en-US.ini (Chinese Traditional)
* New translations en-US.ini (Croatian)
* New translations en-US.ini (Czech)
* New translations en-US.ini (Danish)
* New translations en-US.ini (Dutch)
* New translations en-US.ini (English, Australia)
* New translations en-US.ini (English, Canada)
* New translations en-US.ini (English, United Kingdom)
* New translations en-US.ini (Estonian)
* New translations en-US.ini (Faroese)
* New translations en-US.ini (Finnish)
* New translations en-US.ini (French)
* New translations en-US.ini (German)
* New translations en-US.ini (Greek)
* New translations en-US.ini (Hebrew)
* New translations en-US.ini (Hungarian)
* New translations en-US.ini (Icelandic)
* New translations en-US.ini (Indonesian)
* New translations en-US.ini (Irish)
* New translations en-US.ini (Italian)
* New translations en-US.ini (Japanese)
* New translations en-US.ini (Korean)
* New translations en-US.ini (Mongolian)
* New translations en-US.ini (Norwegian)
* New translations en-US.ini (Persian)
* New translations en-US.ini (Polish)
* New translations en-US.ini (Portuguese, Brazilian)
* New translations en-US.ini (Portuguese)
* New translations en-US.ini (Romanian)
* New translations en-US.ini (Russian)
* New translations en-US.ini (Serbo-Croatian)
* New translations en-US.ini (Sinhala)
* New translations en-US.ini (Spanish)
* New translations en-US.ini (Swedish)
* New translations en-US.ini (Thai)
* New translations en-US.ini (Turkish)
* New translations en-US.ini (Ukrainian)
* New translations en-US.ini (Vietnamese)
---
data/locale/ar-SA.ini | 8 ++
data/locale/bg-BG.ini | 1 +
data/locale/bs-BA.ini | 1 +
data/locale/cs-CZ.ini | 48 +++++++++
data/locale/da-DK.ini | 1 +
data/locale/de-DE.ini | 15 +++
data/locale/el-GR.ini | 1 +
data/locale/en-AU.ini | 1 +
data/locale/en-CA.ini | 1 +
data/locale/en-GB.ini | 5 +
data/locale/es-ES.ini | 36 +++++++
data/locale/et-EE.ini | 1 +
data/locale/fa-IR.ini | 1 +
data/locale/fi-FI.ini | 226 +++++++++++++++++++++++++++++++++++++++++-
data/locale/fo-FO.ini | 1 +
data/locale/fr-FR.ini | 25 +++++
data/locale/ga-IE.ini | 1 +
data/locale/he-IL.ini | 1 +
data/locale/hr-HR.ini | 1 +
data/locale/hu-HU.ini | 53 +++++++++-
data/locale/id-ID.ini | 1 +
data/locale/is-IS.ini | 1 +
data/locale/it-IT.ini | 8 ++
data/locale/ja-JP.ini | 2 +
data/locale/ko-KR.ini | 1 +
data/locale/mn-MN.ini | 1 +
data/locale/nl-NL.ini | 12 +++
data/locale/no-NO.ini | 2 +
data/locale/pl-PL.ini | 8 ++
data/locale/pt-BR.ini | 2 +
data/locale/pt-PT.ini | 1 +
data/locale/ro-RO.ini | 8 ++
data/locale/ru-RU.ini | 8 ++
data/locale/sh-HR.ini | 1 +
data/locale/si-LK.ini | 1 +
data/locale/sv-SE.ini | 1 +
data/locale/th-TH.ini | 2 +
data/locale/tr-TR.ini | 2 +
data/locale/uk-UA.ini | 1 +
data/locale/vi-VN.ini | 1 +
data/locale/zh-CN.ini | 2 +
data/locale/zh-HK.ini | 1 +
data/locale/zh-TW.ini | 1 +
43 files changed, 494 insertions(+), 2 deletions(-)
diff --git a/data/locale/ar-SA.ini b/data/locale/ar-SA.ini
index d02fff4231..9fa8a9edd8 100644
--- a/data/locale/ar-SA.ini
+++ b/data/locale/ar-SA.ini
@@ -25,6 +25,12 @@ State.Automatic="ذاتي"
State.Default="افتراضي"
UI.Menu="ستريم إف إكس (StreamFX)"
+UI.Menu.Wiki="قراءة الويكي"
+UI.Menu.Support="الدعم والمساعدة"
+UI.Menu.Website="زيارة موقع البث FX"
+UI.Menu.Discord="الانضمام إلى ديسكورد البث"
+UI.Menu.Twitter="تابعنا على تويتر"
+UI.Menu.YouTube="اشترك فىLast Empire - War Zعلى يوتيوب"
UI.Menu.About="حول StreamFX"
UI.About.Title="حول StreamFX"
@@ -48,6 +54,7 @@ UI.Updater.Menu.Channel="قناة التحديث"
UI.Updater.Menu.Channel.Release="النسخة الثابتة "
UI.Updater.Menu.Channel.Testing="النسخة التجريبية"
+Encoder.AOM.AV1="AOM AV1 (مباشر)"
Encoder.AOM.AV1.RateControl.Buffer.Size="الحجم"
@@ -149,3 +156,4 @@ Source.Mirror.Source="المصدر"
+
diff --git a/data/locale/bg-BG.ini b/data/locale/bg-BG.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/bg-BG.ini
+++ b/data/locale/bg-BG.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/bs-BA.ini b/data/locale/bs-BA.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/bs-BA.ini
+++ b/data/locale/bs-BA.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/cs-CZ.ini b/data/locale/cs-CZ.ini
index db006016b4..59eb9ca43d 100644
--- a/data/locale/cs-CZ.ini
+++ b/data/locale/cs-CZ.ini
@@ -25,6 +25,11 @@ State.Automatic="Automatický"
State.Default="Výchozí"
UI.Menu="StreamFX"
+UI.Menu.Support="Nápověda && Podpora"
+UI.Menu.Website="Navštívit web StreamFX"
+UI.Menu.Discord="Připojit se na StreamFX Discord server"
+UI.Menu.Twitter="Sledovat StreamFX na Twitteru"
+UI.Menu.YouTube="Odebírat StreamFX YouTube kanál"
UI.Menu.About="O StreamFX"
UI.About.Title="O StreamFX"
@@ -48,11 +53,21 @@ UI.Updater.Menu.Channel="Kanál pro Aktualizace"
UI.Updater.Menu.Channel.Release="Stabilní"
UI.Updater.Menu.Channel.Testing="Testovací"
+Encoder.AOM.AV1="AOM AV1 (přímo)"
+Encoder.AOM.AV1.Encoder.CPUUsage.0="Placebo"
+Encoder.AOM.AV1.Encoder.Profile="Profil"
+Encoder.AOM.AV1.KeyFrames="Klíčový snímek"
Encoder.AOM.AV1.KeyFrames.IntervalType.Frames="Snímky"
Encoder.AOM.AV1.KeyFrames.IntervalType.Seconds="Sekundy"
Encoder.AOM.AV1.KeyFrames.Interval="Interval"
+Encoder.AOM.AV1.RateControl.Limits.Bitrate="Přenosová rychlost"
Encoder.AOM.AV1.RateControl.Limits.Quality="Kvalitní"
+Encoder.AOM.AV1.RateControl.Buffer="Zásobník"
Encoder.AOM.AV1.RateControl.Buffer.Size="Rozměr"
+Encoder.AOM.AV1.Advanced.Threads="Vlákna"
+Encoder.AOM.AV1.Advanced.Tune.Metric.PSNR="PSNR"
+Encoder.AOM.AV1.Advanced.Tune.Metric.SSIM="SSIM"
+Encoder.AOM.AV1.Advanced.Tune.Metric.VMAF.WithPreprocessing="VMAF (s předzpracováním)"
Encoder.FFmpeg.KeyFrames.IntervalType.Frames="Snímky"
Encoder.FFmpeg.KeyFrames.IntervalType.Seconds="Sekundy"
@@ -110,6 +125,8 @@ Source.Shader="Shader"
Transition.Shader="Shader"
Filter.AutoFraming.Framing.Offset="Kompenzace"
+Filter.AutoFraming.Framing.AspectRatio="Poměr stran"
+Filter.AutoFraming.Provider.NVIDIA.FaceDetection="NVIDIA® Face Detection, využívá NVIDIA® Broadcast"
Filter.Blur="Rozostření"
Filter.Blur.Type="Druh"
@@ -188,6 +205,8 @@ Filter.ColorGrade.RenderMode.LUT.6Bit="6-bitová vyhledávací tabulka"
Filter.ColorGrade.RenderMode.LUT.8Bit="8-bitová vyhledávací tabulka"
Filter.ColorGrade.RenderMode.LUT.10Bit="10-bitová vyhledávací tabulka"
+Filter.Denoising.Provider.NVIDIA.Denoising="NVIDIA® Denoising, využívá NVIDIA® Broadcast"
+Filter.Denoising.NVIDIA.Denoising="NVIDIA® Denoising"
Filter.Displacement="Displacement Mapping"
Filter.Displacement.File="Soubor"
@@ -235,10 +254,19 @@ Filter.Transform.Rotation.Order.YXZ="Natočení, náklon, valení"
Filter.Transform.Rotation.Order.YZX="Natočení, valení, náklon"
Filter.Transform.Rotation.Order.ZXY="Valení, náklon, natočení"
Filter.Transform.Rotation.Order.ZYX="Valení, natočení, náklon"
+Filter.Transform.Corners="Rohy"
+Filter.Transform.Corners.TopLeft="Levý horní"
+Filter.Transform.Corners.TopRight="Pravý horní"
+Filter.Transform.Corners.BottomLeft="Levý spodní"
+Filter.Transform.Corners.BottomRight="Pravý spodní"
Filter.Transform.Mipmapping="Zapnout mipmapping"
+Filter.Upscaling.Provider.NVIDIA.SuperResolution="NVIDIA® Super Resolution, využívá NVIDIA® Broadcast"
+Filter.Upscaling.NVIDIA.SuperRes="NVIDIA® Super Resolution"
Filter.Upscaling.NVIDIA.SuperRes.Scale="Měřítko"
+Filter.VirtualGreenscreen.Provider.NVIDIA.Greenscreen="NVIDIA® Greenscreen, využívá NVIDIA® Broadcast"
+Filter.VirtualGreenscreen.NVIDIA.Greenscreen="NVIDIA® Greenscreen"
Filter.VirtualGreenscreen.NVIDIA.Greenscreen.Mode.Quality="Kvalitní"
Source.Mirror="Kopie zdroje"
@@ -254,9 +282,29 @@ Source.Mirror.Source.Audio.Layout.QuadraphonicLFE="Kvadrofonní 4.1 LFE"
Source.Mirror.Source.Audio.Layout.Surround="Prostorový zvuk"
Source.Mirror.Source.Audio.Layout.FullSurround="Plný prostorový zvuk"
+Codec.AV1="AV1"
+Codec.AV1.Profile="Profil"
Codec.H264="H264"
+Codec.H264.Level="Úroveň"
Codec.HEVC="HEVC"
+Codec.HEVC.Profile="Profil"
+Codec.HEVC.Level="Úroveň"
+Codec.ProRes.Profile="Profil"
+Codec.ProRes.Profile.APCO="422 Proxy (APCO)"
+Codec.ProRes.Profile.APCS="422 Lite/LT (APCS)"
+Codec.ProRes.Profile.APCN="422 Standard (APCN)"
+Codec.ProRes.Profile.APCH="422 High Quality/HQ (APCH)"
+Codec.ProRes.Profile.AP4H="4444 High Quality/HQ (AP4H)"
+Codec.ProRes.Profile.AP4X="4444 Extreme Quality/XQ (AP4X)"
+
+Codec.DNxHR.Profile="Profil"
+Codec.DNxHR.Profile.dnxhd="DNxHD"
+Codec.DNxHR.Profile.dnxhr_lb="DNxHR LB (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_sq="DNxHR SQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hq="DNxHR HQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hqx="DNxHR HQX (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_444="DNxHR 444 (4:4:4)"
diff --git a/data/locale/da-DK.ini b/data/locale/da-DK.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/da-DK.ini
+++ b/data/locale/da-DK.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/de-DE.ini b/data/locale/de-DE.ini
index 056b4beb2a..b2adccbd0d 100644
--- a/data/locale/de-DE.ini
+++ b/data/locale/de-DE.ini
@@ -184,6 +184,10 @@ Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Parameter für Konstante Quantisi
Encoder.FFmpeg.NVENC.RateControl.Mode.vbr="Variable Bitrate"
Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Konstante Bitrate"
Encoder.FFmpeg.NVENC.RateControl.TwoPass="Zwei Durchläufe"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass="Mehrfachdurchlauf"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.disabled="Einzelner Durchlauf"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.qres="Zweifacher Durchlauf bei einem Viertel der Auflösung"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.fullres="Zweifacher Durchlauf bei voller Auflösung"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Vorausschauen"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="Adaptive I-Frames"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveB="Adaptive B-Frames"
@@ -205,6 +209,9 @@ Encoder.FFmpeg.NVENC.AQ.Temporal="Zeitlich-adaptive Quantisierung"
Encoder.FFmpeg.NVENC.Other="Weitere Optionen"
Encoder.FFmpeg.NVENC.Other.BFrames="Maximale B‐Bilder"
Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode="B-Bild Referenzmodus"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.disabled="Keine B-Bilder werden als Referenz genutzt"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.middle="Nur B-Bilder/2 werden als Referenz genutzt"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.each="Jedes B-Bild wird als Referenz genutzt"
Encoder.FFmpeg.NVENC.Other.ZeroLatency="Null Latenz"
Encoder.FFmpeg.NVENC.Other.WeightedPrediction="Gewichtete Vorhersage"
Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="Nicht-referenzierte P-Bilder"
@@ -491,3 +498,11 @@ Codec.ProRes.Profile.APCH="422 Hohe Qualität/HQ (APCH)"
Codec.ProRes.Profile.AP4H="4444 Hohe Qualität/HQ (AP4H)"
Codec.ProRes.Profile.AP4X="4444 Extreme Qualität/XQ (AP4X)"
+Codec.DNxHR.Profile="Profil"
+Codec.DNxHR.Profile.dnxhd="DNxHD"
+Codec.DNxHR.Profile.dnxhr_lb="DNxHR LB (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_sq="DNxHR SQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hq="DNxHR HQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hqx="DNxHR HQX (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_444="DNxHR 444 (4:4:4)"
+
diff --git a/data/locale/el-GR.ini b/data/locale/el-GR.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/el-GR.ini
+++ b/data/locale/el-GR.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/en-AU.ini b/data/locale/en-AU.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/en-AU.ini
+++ b/data/locale/en-AU.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/en-CA.ini b/data/locale/en-CA.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/en-CA.ini
+++ b/data/locale/en-CA.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/en-GB.ini b/data/locale/en-GB.ini
index d70412f10e..d75e11cb6a 100644
--- a/data/locale/en-GB.ini
+++ b/data/locale/en-GB.ini
@@ -25,6 +25,9 @@ State.Automatic="Automatic"
State.Default="Default"
UI.Menu="StreamFX"
+UI.Menu.Wiki="Read the Wiki"
+UI.Menu.Support="Help && Support"
+UI.Menu.Website="Visit the StreamFX Website"
UI.Menu.About="About StreamFX"
UI.About.Title="About StreamFX"
@@ -344,3 +347,5 @@ Codec.ProRes.Profile.APCH="422 High Quality/HQ (APCH)"
Codec.ProRes.Profile.AP4H="4444 High Quality/HQ (AP4H)"
Codec.ProRes.Profile.AP4X="4444 Extreme Quality/XQ (AP4X)"
+Codec.DNxHR.Profile="Profile"
+
diff --git a/data/locale/es-ES.ini b/data/locale/es-ES.ini
index a5bd1b2433..6945cf8c1d 100644
--- a/data/locale/es-ES.ini
+++ b/data/locale/es-ES.ini
@@ -158,12 +158,36 @@ Encoder.FFmpeg.NVENC.Preset.default="Por defecto"
Encoder.FFmpeg.NVENC.Preset.slow="Lento"
Encoder.FFmpeg.NVENC.Preset.medium="Medio"
Encoder.FFmpeg.NVENC.Preset.fast="Rápido"
+Encoder.FFmpeg.NVENC.Preset.hp="Alto rendimiento"
+Encoder.FFmpeg.NVENC.Preset.hq="Alta calidad"
+Encoder.FFmpeg.NVENC.Preset.bd="Disco BluRay"
+Encoder.FFmpeg.NVENC.Preset.ll="Baja latencia"
+Encoder.FFmpeg.NVENC.Preset.llhq="Baja latencia a alta calidad"
+Encoder.FFmpeg.NVENC.Preset.llhp="Baja latencia a alto rendimiento"
+Encoder.FFmpeg.NVENC.Preset.lossless="Sin pérdidas"
+Encoder.FFmpeg.NVENC.Preset.losslesshp="Sin pérdidas a alto rendimiento"
+Encoder.FFmpeg.NVENC.Preset.p1="Más rápido (P1)"
+Encoder.FFmpeg.NVENC.Preset.p2="Más rápido (P2)"
+Encoder.FFmpeg.NVENC.Preset.p3="Rápido (P3)"
+Encoder.FFmpeg.NVENC.Preset.p4="Medio (P4)"
+Encoder.FFmpeg.NVENC.Preset.p5="Lento (P5)"
+Encoder.FFmpeg.NVENC.Preset.p6="Más lento (P6)"
+Encoder.FFmpeg.NVENC.Preset.p7="Muy lento (P7)"
Encoder.FFmpeg.NVENC.Tune="Sintonizar"
+Encoder.FFmpeg.NVENC.Tune.hq="Alta calidad"
+Encoder.FFmpeg.NVENC.Tune.ll="Baja latencia"
+Encoder.FFmpeg.NVENC.Tune.ull="Latencia ultra baja"
+Encoder.FFmpeg.NVENC.Tune.lossless="Sin pérdidas"
Encoder.FFmpeg.NVENC.RateControl="Opciones de control de flujo"
Encoder.FFmpeg.NVENC.RateControl.Mode="Modo"
Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Parámetro de Cuantización Constante"
+Encoder.FFmpeg.NVENC.RateControl.Mode.vbr="Tasa de bits variable"
Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Bitrate constante"
Encoder.FFmpeg.NVENC.RateControl.TwoPass="Dos pasos"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass="Pasada múltiple"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.disabled="Pasada única"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.qres="Dos pasadas a un cuarto de resolución"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.fullres="Dos pasadas a resolución completa"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Look Ahead"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="I-Frames adaptativos"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveB="B-Frames adaptativos"
@@ -185,10 +209,14 @@ Encoder.FFmpeg.NVENC.AQ.Temporal="Cuantización adaptativa temporal"
Encoder.FFmpeg.NVENC.Other="Otras opciones"
Encoder.FFmpeg.NVENC.Other.BFrames="B-Frames máximos"
Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode="Modo de referencia de B-Frame"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.disabled="Ningún B-Frame será usado como referencia"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.middle="Solo B-Frames/2 serán usados como referencia"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.each="Cada B-Frame se usará como referencia"
Encoder.FFmpeg.NVENC.Other.ZeroLatency="Latencia cero"
Encoder.FFmpeg.NVENC.Other.WeightedPrediction="Predicción ponderada"
Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="P-Frames sin referencia"
Encoder.FFmpeg.NVENC.Other.ReferenceFrames="Fotogramas de referencia"
+Encoder.FFmpeg.NVENC.Other.LowDelayKeyFrameScale="Escala de fotogramas clave de bajo retardo"
Blur.Type.Box="Caja"
Blur.Type.BoxLinear="Caja Lineal"
@@ -470,3 +498,11 @@ Codec.ProRes.Profile.APCH="422 High Quality/HQ (APCH)"
Codec.ProRes.Profile.AP4H="4444 Alta Calidad/HQ (AP4H)"
Codec.ProRes.Profile.AP4X="4444 Calidad extrema/XQ (AP4X)"
+Codec.DNxHR.Profile="Perfil"
+Codec.DNxHR.Profile.dnxhd="DNxHD"
+Codec.DNxHR.Profile.dnxhr_lb="DNxHR LB (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_sq="DNxHR SQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hq="Cuartel general DNxHR (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hqx="DNxHR HQX (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_444="DNxHR 444 (4:4:4)"
+
diff --git a/data/locale/et-EE.ini b/data/locale/et-EE.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/et-EE.ini
+++ b/data/locale/et-EE.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/fa-IR.ini b/data/locale/fa-IR.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/fa-IR.ini
+++ b/data/locale/fa-IR.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/fi-FI.ini b/data/locale/fi-FI.ini
index fff7bc0ec7..b9de650084 100644
--- a/data/locale/fi-FI.ini
+++ b/data/locale/fi-FI.ini
@@ -1,4 +1,4 @@
-Advanced="Lisävalinnat"
+Advanced="Edistyneet vaihtoehdot"
Manual.Open="Avaa käyttöopas"
Channel.Red="Punainen"
@@ -73,22 +73,130 @@ Encoder.AOM.AV1.Encoder.CPUUsage.8="Super Nopea"
Encoder.AOM.AV1.Encoder.CPUUsage.9="Ultra nopea"
Encoder.AOM.AV1.Encoder.CPUUsage.10="Mielettömän nopea"
Encoder.AOM.AV1.Encoder.Profile="Profiili"
+Encoder.AOM.AV1.KeyFrames="Avainrruutu"
Encoder.AOM.AV1.KeyFrames.IntervalType="Aikaväli Tyyppi"
Encoder.AOM.AV1.KeyFrames.IntervalType.Frames="Framet"
Encoder.AOM.AV1.KeyFrames.IntervalType.Seconds="Sekunnit"
Encoder.AOM.AV1.KeyFrames.Interval="Aikaväli"
Encoder.AOM.AV1.RateControl="Rate Control -tila"
+Encoder.AOM.AV1.RateControl.Mode="Tila"
+Encoder.AOM.AV1.RateControl.Mode.CBR="Vakiobittinopeus (Constant Bitrate (CBR))"
+Encoder.AOM.AV1.RateControl.Mode.VBR="Muuttuva bittinopeus (Variable Bitrate (VBR))"
+Encoder.AOM.AV1.RateControl.Mode.CQ="Rajoitettu laatu (Constrained Quality (CQ))"
+Encoder.AOM.AV1.RateControl.Mode.Q="Vakaa laatu (Constant Quality (Q))"
+Encoder.AOM.AV1.RateControl.LookAhead="Eteenpäin katsova"
+Encoder.AOM.AV1.RateControl.Limits="Raja-arvot"
+Encoder.AOM.AV1.RateControl.Limits.Bitrate="Bittivirran nopeus"
+Encoder.AOM.AV1.RateControl.Limits.Bitrate.Undershoot="Tuottamattomana jäänyt bittivirrannopeus"
+Encoder.AOM.AV1.RateControl.Limits.Bitrate.Overshoot="Hyödyttömänä jäänyt bittivirrannopeus"
+Encoder.AOM.AV1.RateControl.Limits.Quality="Laatu"
+Encoder.AOM.AV1.RateControl.Limits.Quantizer.Minimum="Vähimmäiskvantisoija"
+Encoder.AOM.AV1.RateControl.Limits.Quantizer.Maximum="Enimmäiskvantisoija"
+Encoder.AOM.AV1.RateControl.Buffer="Puskuri"
+Encoder.AOM.AV1.RateControl.Buffer.Size="Koko"
+Encoder.AOM.AV1.RateControl.Buffer.Size.Initial="Alkuperäinen koko"
+Encoder.AOM.AV1.RateControl.Buffer.Size.Optimal="Optimaalinen koko"
+Encoder.AOM.AV1.Advanced="Edistynyt"
+Encoder.AOM.AV1.Advanced.Threads="Säikeet"
+Encoder.AOM.AV1.Advanced.RowMultiThreading="Per-rivi monisäikeinen"
+Encoder.AOM.AV1.Advanced.Tile.Columns="Laatta-sarakkeet"
+Encoder.AOM.AV1.Advanced.Tile.Rows="Laatta-rivit"
+Encoder.AOM.AV1.Advanced.Tune="Hienosäätö"
+Encoder.AOM.AV1.Advanced.Tune.Metric="Metrijärjestelmä"
+Encoder.AOM.AV1.Advanced.Tune.Metric.PSNR="Huippusignaali-kohinasuhde (PSNR (peak signal-to-noise ratio))"
+Encoder.AOM.AV1.Advanced.Tune.Metric.SSIM="Rakenteellinen samankaltaisuusindeksi (SSIM (structural similarity index))"
+Encoder.AOM.AV1.Advanced.Tune.Metric.VMAF.WithPreprocessing="VMAF (esikäsittelyllä)"
+Encoder.AOM.AV1.Advanced.Tune.Metric.VMAF.WithoutPreprocessing="VMAF (ilman esikäsittelyä)"
+Encoder.AOM.AV1.Advanced.Tune.Content.Screen="Näyttö"
+Encoder.FFmpeg.Suffix=" (FFmpegin välityksellä)"
Encoder.FFmpeg.KeyFrames.IntervalType="Aikaväli Tyyppi"
Encoder.FFmpeg.KeyFrames.IntervalType.Frames="Framet"
Encoder.FFmpeg.KeyFrames.IntervalType.Seconds="Sekunnit"
Encoder.FFmpeg.KeyFrames.Interval="Aikaväli"
+Encoder.FFmpeg.AMF.Preset="Esiasetus"
+Encoder.FFmpeg.AMF.Preset.Speed="Nopeus"
+Encoder.FFmpeg.AMF.Preset.Balanced="Tasapainotettu"
+Encoder.FFmpeg.AMF.Preset.Quality="Laatu"
+Encoder.FFmpeg.AMF.RateControl="Virrannopeuden hallinnan asetukset"
+Encoder.FFmpeg.AMF.RateControl.Mode="Tila"
+Encoder.FFmpeg.AMF.RateControl.Mode.VBR_LATENCY="Vaihteleva bittivirrannopeus (viive rajattu)"
+Encoder.FFmpeg.AMF.RateControl.Mode.CBR="Vakaa bittivirrannopeus"
+Encoder.FFmpeg.AMF.RateControl.LookAhead="Eteenpäin katsova"
+Encoder.FFmpeg.AMF.RateControl.FrameSkipping="Ruudun ohitus"
+Encoder.FFmpeg.AMF.RateControl.Limits="Raja-arvot"
+Encoder.FFmpeg.AMF.RateControl.Limits.BufferSize="Puskurin koko"
+Encoder.FFmpeg.AMF.RateControl.Limits.Bitrate.Target="Bittivirrannopeustavoite"
+Encoder.FFmpeg.AMF.RateControl.Limits.Bitrate.Maximum="Enimmäisbittivirrannopeus"
+Encoder.FFmpeg.AMF.RateControl.QP="Kvantifiointiparametrit"
+Encoder.FFmpeg.AMF.RateControl.QP.I="I-kehyksen kvantifiointiparametrit"
+Encoder.FFmpeg.AMF.RateControl.QP.P="P-kehyksen kvantifiointiparametrit"
+Encoder.FFmpeg.AMF.RateControl.QP.B="B-kehyksen kvantifiointiparametrit"
+Encoder.FFmpeg.AMF.Other="Muut valinnat"
+Encoder.FFmpeg.AMF.Other.BFrames="B-kehysten enimmäismäärä"
+Encoder.FFmpeg.AMF.Other.BFrameReferences="B-kehyksen viitetilat"
+Encoder.FFmpeg.AMF.Other.ReferenceFrames="Viitekehykset"
+Encoder.FFmpeg.AMF.Other.EnforceHRD="Pakota HRD"
+Encoder.FFmpeg.AMF.Other.VBAQ="VBAQ"
+Encoder.FFmpeg.AMF.Other.AccessUnitDelimiter="Käyttöoikeusyksikön Erotin"
+Encoder.FFmpeg.NVENC.Preset="Esiasetus"
Encoder.FFmpeg.NVENC.Preset.default="Oletus"
Encoder.FFmpeg.NVENC.Preset.slow="Hidas"
Encoder.FFmpeg.NVENC.Preset.medium="Keskinopea"
Encoder.FFmpeg.NVENC.Preset.fast="Nopea"
+Encoder.FFmpeg.NVENC.Preset.hp="Korkea suorituskyky"
+Encoder.FFmpeg.NVENC.Preset.hq="Korkea laatu"
+Encoder.FFmpeg.NVENC.Preset.bd="BluRay-levy"
+Encoder.FFmpeg.NVENC.Preset.ll="Alhainen viive"
+Encoder.FFmpeg.NVENC.Preset.llhq="Alhainen viive, korkea laatu"
+Encoder.FFmpeg.NVENC.Preset.llhp="Alhainen viive, korkea suorituskyky"
+Encoder.FFmpeg.NVENC.Preset.lossless="Häviötön"
+Encoder.FFmpeg.NVENC.Preset.losslesshp="Häviötön korkea suorituskyky"
+Encoder.FFmpeg.NVENC.Preset.p1="Nopein (P1)"
+Encoder.FFmpeg.NVENC.Preset.p2="Nopeampi (P2)"
+Encoder.FFmpeg.NVENC.Preset.p3="Nopea (P3)"
+Encoder.FFmpeg.NVENC.Preset.p4="Keskinopea (P4)"
+Encoder.FFmpeg.NVENC.Preset.p5="Hidas (P5)"
+Encoder.FFmpeg.NVENC.Preset.p6="Hitaampi (P6)"
+Encoder.FFmpeg.NVENC.Preset.p7="Hitain (P7)"
+Encoder.FFmpeg.NVENC.Tune="Hienosäätö"
+Encoder.FFmpeg.NVENC.Tune.hq="Korkea laatu"
+Encoder.FFmpeg.NVENC.Tune.ll="Alhainen viive"
+Encoder.FFmpeg.NVENC.Tune.ull="Erittäin alhainen viive"
+Encoder.FFmpeg.NVENC.Tune.lossless="Häviötön"
+Encoder.FFmpeg.NVENC.RateControl="Virrannopeuden hallinnan asetukset"
+Encoder.FFmpeg.NVENC.RateControl.Mode="Tila"
+Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Vakaa kvantitaatioparametri"
+Encoder.FFmpeg.NVENC.RateControl.Mode.vbr="Vaihteleva bittivirta"
+Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Vakaa bittivirta"
+Encoder.FFmpeg.NVENC.RateControl.LookAhead="Eteenpäin katsova"
+Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="Mukautuvat I-kehykset"
+Encoder.FFmpeg.NVENC.RateControl.AdaptiveB="Mukautuvat B-kehykset"
+Encoder.FFmpeg.NVENC.RateControl.Limits="Raja-arvot"
+Encoder.FFmpeg.NVENC.RateControl.Limits.BufferSize="Puskurin koko"
+Encoder.FFmpeg.NVENC.RateControl.Limits.Quality="Kohteen laatu"
+Encoder.FFmpeg.NVENC.RateControl.Limits.Bitrate.Target="Bittivirrannopeustavoite"
+Encoder.FFmpeg.NVENC.RateControl.Limits.Bitrate.Maximum="Enimmäisbittivirrannopeus"
+Encoder.FFmpeg.NVENC.RateControl.QP="Kvantifiointiparametrit"
+Encoder.FFmpeg.NVENC.RateControl.QP.Minimum="Vähimmäiskvantifiointiparametrit"
+Encoder.FFmpeg.NVENC.RateControl.QP.Maximum="Enimmäiskvantifiointiparametrit"
+Encoder.FFmpeg.NVENC.RateControl.QP.I="I-kehyksen kvantifiointiparametrit"
+Encoder.FFmpeg.NVENC.RateControl.QP.P="P-kehyksen kvantifiointiparametrit"
+Encoder.FFmpeg.NVENC.RateControl.QP.B="B-kehyksen kvantifiointiparametrit"
+Encoder.FFmpeg.NVENC.AQ="Mukautuva Kvantifiointi"
+Encoder.FFmpeg.NVENC.AQ.Spatial="Spatiaalinen mukautuva kvantitaatio"
+Encoder.FFmpeg.NVENC.AQ.Strength="Spatiaalisen mukautuvan kvantitaation voima"
+Encoder.FFmpeg.NVENC.Other="Muut valinnat"
+Encoder.FFmpeg.NVENC.Other.BFrames="B-kehysten enimmäismäärä"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode="B-kehyksen viitetila"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.disabled="Viitteenä ei käytetä B-kehyksiä"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.middle="Ainoastaan B-kehykset/2 käytetään viitteenä"
+Encoder.FFmpeg.NVENC.Other.BFrameReferenceMode.each="Jokainen B-kehys käytetään viitteenä"
+Encoder.FFmpeg.NVENC.Other.NonReferencePFrames="Ei-viitetilan P-kehykset"
+Encoder.FFmpeg.NVENC.Other.ReferenceFrames="Viitetilan kehykset"
+Encoder.FFmpeg.NVENC.Other.LowDelayKeyFrameScale="Alhaisen viiveen avainkehyksen mittakaava"
Blur.Type.Box="Kuutiollinen"
Blur.Type.BoxLinear="Kuutio lineaarinen"
@@ -104,12 +212,45 @@ Shader="Shaderit"
Shader.Refresh="Päivitä asetukset ja parametrit"
Shader.Shader="Varjostimen Asetukset"
Shader.Shader.File="Tiedosto"
+Shader.Shader.Technique="Tekniikka"
+Shader.Shader.Size="Koko"
+Shader.Shader.Size.Width="Leveys"
+Shader.Shader.Size.Height="Korkeus"
+Shader.Parameters="Varjostimen parametrit"
+Shader.Parameter.Texture.Type="Tyyppi"
+Shader.Parameter.Texture.Type.File="Tiedosto"
+Shader.Parameter.Texture.Type.Source="Lähde"
+Shader.Parameter.Texture.File="Tiedosto"
+Shader.Parameter.Texture.Source="Lähde"
Filter.Shader="Shaderit"
Source.Shader="Shaderit"
Transition.Shader="Shaderit"
+Filter.AutoFraming.Tracking="Seurantavalinnat"
+Filter.AutoFraming.Tracking.Mode="Tila"
+Filter.AutoFraming.Motion="Liikevalinnat"
+Filter.AutoFraming.Framing="Ruutuvalinnat"
+Filter.AutoFraming.Framing.Stability="Vakaus"
Filter.AutoFraming.Framing.Offset="Siirtymä"
+Filter.AutoFraming.Framing.AspectRatio="Kuvasuhde"
+Filter.AutoFraming.Provider="Tarjoaja"
+Filter.AutoFraming.Provider.NVIDIA.FaceDetection="NVIDIA® Face Detection:n kasvontunnistus, NVIDIA® Broadcast:n toimittamana"
+Filter.Blur.Subtype="Alityyppi"
+Filter.Blur.Size="Koko"
+Filter.Blur.Angle="Kulma (asteet)"
+Filter.Blur.Mask="Käytä peitettä"
+Filter.Blur.Mask.Type="Peitteen tyyppi"
+Filter.Blur.Mask.Type.Region="Alue"
+Filter.Blur.Mask.Type.Image="Kuva"
+Filter.Blur.Mask.Type.Source="Lähde"
+Filter.Blur.Mask.Region.Left="Vasen reuna"
+Filter.Blur.Mask.Region.Top="Yläreuna"
+Filter.Blur.Mask.Region.Right="Oikea reuna"
+Filter.Blur.Mask.Region.Bottom="Alareuna"
+Filter.Blur.Mask.Region.Feather="Sulan alue"
+Filter.Blur.Mask.Region.Invert="Käänteinen alue"
+Filter.Blur.Mask.Image="Kuvan peite"
Filter.Blur.Mask.Source="Lähteen Maski"
Filter.Blur.Mask.Color="Värisuodin"
Filter.Blur.Mask.Alpha="Maskin läpinäkyvyys"
@@ -157,10 +298,40 @@ Filter.ColorGrade.Tint.Midtone.Blue="Sinisen Keskisävy"
Filter.ColorGrade.Tint.Highlight.Red="Punaisen Korostus Sävy"
Filter.ColorGrade.Tint.Highlight.Green="Vihreän Korostus Sävy"
Filter.ColorGrade.Tint.Highlight.Blue="Sinisen Korostus Sävy"
+Filter.ColorGrade.Correction="Värinkorjaus"
+Filter.ColorGrade.Correction.Hue="Värisävy"
+Filter.ColorGrade.Correction.Saturation="Kylläisyys"
+Filter.ColorGrade.Correction.Lightness="Vaaleus"
+Filter.ColorGrade.Correction.Contrast="Kontrasti"
+Filter.ColorGrade.RenderMode="Renderöintitila"
+Filter.ColorGrade.RenderMode.Direct="Suora renderöinti"
+Filter.ColorGrade.RenderMode.LUT.2Bit="2-Bittinen Look-Up -taulukko"
+Filter.ColorGrade.RenderMode.LUT.4Bit="4-Bittinen Look-Up -taulukko"
+Filter.ColorGrade.RenderMode.LUT.6Bit="6-Bittinen Look-Up -taulukko"
+Filter.ColorGrade.RenderMode.LUT.8Bit="8-Bittinen Look-Up -taulukko"
+Filter.ColorGrade.RenderMode.LUT.10Bit="10-Bittinen Look-Up -taulukko"
+Filter.Denoising="Kohinan poisto"
+Filter.Denoising.Provider="Tarjoaja"
+Filter.Denoising.Provider.NVIDIA.Denoising="NVIDIA® Denoising:n kohinanpoisto, NVIDIA® Broadcast:n toimittamana"
+Filter.Denoising.NVIDIA.Denoising="NVIDIA® Denoising:n kohinanpoisto"
+Filter.Denoising.NVIDIA.Denoising.Strength="Voima"
+Filter.Denoising.NVIDIA.Denoising.Strength.Weak="Heikko"
+Filter.Denoising.NVIDIA.Denoising.Strength.Strong="Vahva"
+Filter.Displacement.File="Tiedosto"
+Filter.DynamicMask.Channel.Multiplier="Kerroin"
+Filter.SDFEffects="SDF-tehosteet"
+Filter.SDFEffects.Shadow.Inner="Sisäinen varjo"
+Filter.SDFEffects.Shadow.Inner.Range.Minimum="Sisäisen varjon vähimmäisetäisyys"
+Filter.SDFEffects.Shadow.Inner.Range.Maximum="Sisäisen varjon enimmäisetäisyys"
+Filter.SDFEffects.Shadow.Inner.Offset.X="Sisäisen varjon siirtymä X"
+Filter.SDFEffects.Shadow.Inner.Offset.Y="Sisäisen varjon siirtymä Y"
+Filter.SDFEffects.Shadow.Inner.Color="Sisäisen varjon väri"
+Filter.SDFEffects.Shadow.Inner.Alpha="Sisäisen varjon Alpha"
+Filter.SDFEffects.Glow.Outer="Ulkoinen hehku"
Filter.SDFEffects.Glow.Outer.Color="Ulomman Hehkun Väri"
Filter.SDFEffects.Glow.Outer.Alpha="Ulomman Hehkun Läpinäkyvyys"
Filter.SDFEffects.Glow.Outer.Width="Ulomman Hehkun Paksuus"
@@ -181,6 +352,8 @@ Filter.SDFEffects.SDF.Threshold="Sdf Alpha -kynnysarvo"
Filter.Transform="3D muunnin"
Filter.Transform.Camera="Kamera"
+Filter.Transform.Camera.Mode="Tila"
+Filter.Transform.Camera.Mode.Orthographic="Ortografinen"
Filter.Transform.Camera.FieldOfView="Näkökenttä"
Filter.Transform.Position="Sijainti"
Filter.Transform.Position.X="X"
@@ -191,11 +364,62 @@ Filter.Transform.Scale.X="X"
Filter.Transform.Scale.Y="Y"
Filter.Transform.Shear.X="X"
Filter.Transform.Shear.Y="Y"
+Filter.Transform.Rotation="Kierto"
+Filter.Transform.Rotation.Z="Rullaa (Z)"
+Filter.Transform.Rotation.Order="Kierron järjestys"
+Filter.Transform.Corners.TopLeft="Ylävasen"
+Filter.Transform.Corners.TopRight="Yläoikea"
+Filter.Transform.Corners.BottomLeft="Alavasen"
+Filter.Transform.Corners.BottomRight="Alaoikea"
+Filter.Upscaling.Provider="Tarjoaja"
+Filter.Upscaling.NVIDIA.SuperRes.Strength="Voima"
+Filter.Upscaling.NVIDIA.SuperRes.Strength.Weak="Heikko"
+Filter.Upscaling.NVIDIA.SuperRes.Strength.Strong="Vahva"
+Filter.VirtualGreenscreen.Provider="Tarjoaja"
+Filter.VirtualGreenscreen.NVIDIA.Greenscreen.Mode="Tila"
+Filter.VirtualGreenscreen.NVIDIA.Greenscreen.Mode.Performance="Suorituskyky"
+Filter.VirtualGreenscreen.NVIDIA.Greenscreen.Mode.Quality="Laatu"
+Source.Mirror.Source="Lähde"
+Source.Mirror.Source.Audio="Ota ääni käyttöön"
+Source.Mirror.Source.Audio.Layout="Äänen asettelu"
+Source.Mirror.Source.Audio.Layout.Unknown="Tuntematon"
+Source.Mirror.Source.Audio.Layout.Mono="Yksikanavainen (mono)"
+Source.Mirror.Source.Audio.Layout.Quadraphonic="3D-äänen simulointi neljällä kaiuttimella"
+Source.Mirror.Source.Audio.Layout.QuadraphonicLFE="3D-äänen simulointi neljällä kaiuttimella LFE:neen"
+Codec.AV1.Profile="Profiili"
+Codec.AV1.Profile.Main="Ensisijainen"
+Codec.AV1.Profile.High="Korkea"
+Codec.H264="H264"
+Codec.H264.Profile="Profiili"
+Codec.HEVC="HEVC (High Efficiency Video Coding)"
+Codec.HEVC.Profile="Profiili"
+Codec.HEVC.Profile.main="Ensisijainen"
+Codec.HEVC.Profile.main10="Ensisijainen 10-bittinen"
+Codec.HEVC.Profile.rext="Alue laajennettu"
+Codec.HEVC.Tier="Kolmas osapuoli"
+Codec.HEVC.Tier.main="Ensisijainen"
+Codec.HEVC.Tier.high="Korkea"
+Codec.HEVC.Level="Taso"
+Codec.ProRes.Profile="Profiili"
+Codec.ProRes.Profile.APCO="422 Välityspalvelin (APCO)"
+Codec.ProRes.Profile.APCS="422 Lite/LT (APCS)"
+Codec.ProRes.Profile.APCN="422 Vakio (APCN)"
+Codec.ProRes.Profile.APCH="422 Korkealaatuinen/HQ (APCH)"
+Codec.ProRes.Profile.AP4H="4444 Korkealaatuinen/HQ (APCH)"
+Codec.ProRes.Profile.AP4X="4444 Äärimmäisen korkealaatuinen/XQ (AP4X)"
+
+Codec.DNxHR.Profile="Profiili"
+Codec.DNxHR.Profile.dnxhd="DNxHD"
+Codec.DNxHR.Profile.dnxhr_lb="DNxHR LB (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_sq="DNxHR LB (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hq="DNxHR LB (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hqx="DNxHR LB (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_444="DNxHR LB (444:4:4)"
diff --git a/data/locale/fo-FO.ini b/data/locale/fo-FO.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/fo-FO.ini
+++ b/data/locale/fo-FO.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/fr-FR.ini b/data/locale/fr-FR.ini
index e0d373e232..abc1efc49d 100644
--- a/data/locale/fr-FR.ini
+++ b/data/locale/fr-FR.ini
@@ -151,18 +151,41 @@ Encoder.FFmpeg.AMF.Other.BFrameReferences="Références B-Frame"
Encoder.FFmpeg.AMF.Other.ReferenceFrames="Cadres de référence"
Encoder.FFmpeg.AMF.Other.EnforceHRD="Forcer le HRD"
Encoder.FFmpeg.AMF.Other.VBAQ="VBAQ"
+Encoder.FFmpeg.AMF.Other.AccessUnitDelimiter="Délimiteur d'unité d'accès"
Encoder.FFmpeg.NVENC.Preset="Préréglage"
Encoder.FFmpeg.NVENC.Preset.default="Par défaut"
Encoder.FFmpeg.NVENC.Preset.slow="Lent"
Encoder.FFmpeg.NVENC.Preset.medium="Moyen"
Encoder.FFmpeg.NVENC.Preset.fast="Rapide"
+Encoder.FFmpeg.NVENC.Preset.hp="Haute Performance"
+Encoder.FFmpeg.NVENC.Preset.hq="Haute Qualité"
+Encoder.FFmpeg.NVENC.Preset.bd="Disque Blu-Ray"
+Encoder.FFmpeg.NVENC.Preset.ll="Latence faible"
+Encoder.FFmpeg.NVENC.Preset.llhq="Latence faible, haut qualité"
+Encoder.FFmpeg.NVENC.Preset.llhp="Latence faible, haute performance"
+Encoder.FFmpeg.NVENC.Preset.lossless="Sans pertes (Lossless)"
+Encoder.FFmpeg.NVENC.Preset.losslesshp="Sans perte (Lossless), Haute Performance"
+Encoder.FFmpeg.NVENC.Preset.p1="Le plus rapide (P1)"
+Encoder.FFmpeg.NVENC.Preset.p2="Plus rapide (P2)"
+Encoder.FFmpeg.NVENC.Preset.p3="Rapide (P3)"
+Encoder.FFmpeg.NVENC.Preset.p4="Medium (P4)"
+Encoder.FFmpeg.NVENC.Preset.p5="Lent (P5)"
+Encoder.FFmpeg.NVENC.Preset.p6="Plus lent (P6)"
+Encoder.FFmpeg.NVENC.Preset.p7="Le plus lent (P7)"
Encoder.FFmpeg.NVENC.Tune="Ajustement"
+Encoder.FFmpeg.NVENC.Tune.hq="Haute Qualité"
+Encoder.FFmpeg.NVENC.Tune.ll="Latence faible"
+Encoder.FFmpeg.NVENC.Tune.ull="Latence ultra faible"
+Encoder.FFmpeg.NVENC.Tune.lossless="Sans pertes (Lossless)"
Encoder.FFmpeg.NVENC.RateControl="Options de contrôle du débit"
Encoder.FFmpeg.NVENC.RateControl.Mode="Mode"
Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Paramètre de quantification constante"
+Encoder.FFmpeg.NVENC.RateControl.Mode.vbr="Débit variable"
Encoder.FFmpeg.NVENC.RateControl.Mode.cbr="Débit constant"
Encoder.FFmpeg.NVENC.RateControl.TwoPass="Deux passes"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass="Multi-Pass"
+Encoder.FFmpeg.NVENC.RateControl.MultiPass.disabled="Single Pass"
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Prédiction (Look-ahead)"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="I-Frames adaptatives"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveB="B-Frames adaptatives"
@@ -467,3 +490,5 @@ Codec.ProRes.Profile.APCH="422 Haute Qualité/HQ (APCH)"
Codec.ProRes.Profile.AP4H="4444 Haute Qualité/HQ (AP4H)"
Codec.ProRes.Profile.AP4X="4444 Qualité Extrême/XQ (AP4X)"
+Codec.DNxHR.Profile="Profil"
+
diff --git a/data/locale/ga-IE.ini b/data/locale/ga-IE.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/ga-IE.ini
+++ b/data/locale/ga-IE.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/he-IL.ini b/data/locale/he-IL.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/he-IL.ini
+++ b/data/locale/he-IL.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/hr-HR.ini b/data/locale/hr-HR.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/hr-HR.ini
+++ b/data/locale/hr-HR.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/hu-HU.ini b/data/locale/hu-HU.ini
index 60a4ba06f7..27937792ac 100644
--- a/data/locale/hu-HU.ini
+++ b/data/locale/hu-HU.ini
@@ -92,19 +92,40 @@ Encoder.AOM.AV1.RateControl.Limits.Bitrate.Overshoot="Bitsebesség felső korlá
Encoder.AOM.AV1.RateControl.Limits.Quality="Minőség"
Encoder.AOM.AV1.RateControl.Limits.Quantizer.Minimum="Minimum kvantálás"
Encoder.AOM.AV1.RateControl.Limits.Quantizer.Maximum="Maximum kvantálás"
+Encoder.AOM.AV1.RateControl.Buffer="Puffer"
Encoder.AOM.AV1.RateControl.Buffer.Size="Méret"
-
+Encoder.AOM.AV1.Advanced="Haladó"
+Encoder.AOM.AV1.Advanced.Tune="Hangolás"
+Encoder.AOM.AV1.Advanced.Tune.Metric.PSNR="PSNR"
+Encoder.AOM.AV1.Advanced.Tune.Metric.SSIM="SSIM"
+Encoder.AOM.AV1.Advanced.Tune.Content.Screen="Képernyő"
+Encoder.AOM.AV1.Advanced.Tune.Content.Film="Film"
+
+Encoder.FFmpeg="FFmpeg beállítások"
+Encoder.FFmpeg.CustomSettings="Egyéni beállítások"
+Encoder.FFmpeg.GPU="GPU"
Encoder.FFmpeg.KeyFrames.IntervalType="Időtartam egysége"
Encoder.FFmpeg.KeyFrames.IntervalType.Frames="Képkocka"
Encoder.FFmpeg.KeyFrames.IntervalType.Seconds="Másodperc"
Encoder.FFmpeg.KeyFrames.Interval="Időköz"
Encoder.FFmpeg.AMF.Preset="Alapbeállítások"
+Encoder.FFmpeg.AMF.Preset.Speed="Sebesség"
+Encoder.FFmpeg.AMF.Preset.Balanced="Kiegyensúlyozott"
Encoder.FFmpeg.AMF.Preset.Quality="Minőség"
Encoder.FFmpeg.AMF.RateControl="Sebesség vezérlés beállítások"
Encoder.FFmpeg.AMF.RateControl.Mode="Mód"
+Encoder.FFmpeg.AMF.RateControl.Mode.CBR="Állandó bitsebesség"
Encoder.FFmpeg.AMF.RateControl.LookAhead="Előretekintés"
+Encoder.FFmpeg.AMF.RateControl.FrameSkipping="Képkocka kihagyás"
Encoder.FFmpeg.AMF.RateControl.Limits="Korlátok"
+Encoder.FFmpeg.AMF.RateControl.Limits.BufferSize="Pufferméret"
+Encoder.FFmpeg.AMF.RateControl.Limits.Bitrate.Target="Célbitsebesség"
+Encoder.FFmpeg.AMF.RateControl.Limits.Bitrate.Maximum="Maximális bitsebesség"
+Encoder.FFmpeg.AMF.RateControl.QP.I="I-Képkocka QP"
+Encoder.FFmpeg.AMF.RateControl.QP.P="P-Képkocka QP"
+Encoder.FFmpeg.AMF.RateControl.QP.B="B-Képkocka QP"
+Encoder.FFmpeg.AMF.Other.VBAQ="VBAQ"
Encoder.FFmpeg.NVENC.Preset="Alapbeállítások"
Encoder.FFmpeg.NVENC.Preset.default="Alapértelmezett"
@@ -143,6 +164,14 @@ Encoder.FFmpeg.NVENC.RateControl.MultiPass.fullres="Két fázisú - teljes felbo
Encoder.FFmpeg.NVENC.RateControl.LookAhead="Előretekintés"
Encoder.FFmpeg.NVENC.RateControl.AdaptiveI="Adaptív közteskockák"
Encoder.FFmpeg.NVENC.RateControl.Limits="Korlátok"
+Encoder.FFmpeg.NVENC.RateControl.Limits.BufferSize="Pufferméret"
+Encoder.FFmpeg.NVENC.RateControl.Limits.Bitrate.Target="Célbitsebesség"
+Encoder.FFmpeg.NVENC.RateControl.Limits.Bitrate.Maximum="Maximális bitsebesség"
+Encoder.FFmpeg.NVENC.RateControl.QP.Minimum="Minimális QP"
+Encoder.FFmpeg.NVENC.RateControl.QP.Maximum="Maximális QP"
+Encoder.FFmpeg.NVENC.RateControl.QP.I="I-Képkocka QP"
+Encoder.FFmpeg.NVENC.RateControl.QP.P="P-Képkocka QP"
+Encoder.FFmpeg.NVENC.RateControl.QP.B="B-Képkocka QP"
Shader.Shader.File="Fájl"
@@ -156,20 +185,27 @@ Shader.Parameter.Texture.File="Fájl"
Shader.Parameter.Texture.Source="Forrás"
Filter.AutoFraming.Tracking.Mode="Mód"
+Filter.AutoFraming.Tracking.Mode.Group="Csoport"
+Filter.AutoFraming.Provider="Szolgáltató"
Filter.Blur.Type="Típus"
Filter.Blur.Size="Méret"
Filter.Blur.Mask.Type.Image="Kép"
Filter.Blur.Mask.Type.Source="Forrás"
+Filter.ColorGrade.Tint.Detection.YUV.SDR="Luma Chroma (BT.709 SDR)"
Filter.ColorGrade.Tint.Mode.Linear="Lineáris"
Filter.ColorGrade.Correction.Saturation="Telítettség"
Filter.ColorGrade.Correction.Contrast="Kontraszt"
+Filter.Denoising.Provider="Szolgáltató"
Filter.Displacement.File="Fájl"
+Filter.DynamicMask.Channel="%s csatorna"
+Filter.SDFEffects.Outline="Körvonal"
+Filter.SDFEffects.Outline.Color="Körvonal színe"
Filter.Transform.Camera="Kamera"
Filter.Transform.Camera.Mode="Mód"
@@ -182,12 +218,19 @@ Filter.Transform.Scale.Y="Y"
Filter.Transform.Shear.X="X"
Filter.Transform.Shear.Y="Y"
+Filter.Upscaling.Provider="Szolgáltató"
+Filter.VirtualGreenscreen.Provider="Szolgáltató"
Filter.VirtualGreenscreen.NVIDIA.Greenscreen.Mode="Mód"
Filter.VirtualGreenscreen.NVIDIA.Greenscreen.Mode.Quality="Minőség"
Source.Mirror.Source="Forrás"
+Source.Mirror.Source.Audio="Hang engedélyezése"
+Source.Mirror.Source.Audio.Layout.Unknown="Ismeretlen"
+Source.Mirror.Source.Audio.Layout.Mono="Monó"
+Source.Mirror.Source.Audio.Layout.Stereo="Sztereó"
+Codec.AV1="AV1"
Codec.AV1.Profile="Profil"
Codec.H264="H264"
@@ -198,3 +241,11 @@ Codec.HEVC.Profile="Profil"
Codec.ProRes.Profile="Profil"
+Codec.DNxHR.Profile="Profil"
+Codec.DNxHR.Profile.dnxhd="DNxHD"
+Codec.DNxHR.Profile.dnxhr_lb="DNxHR LB (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_sq="DNxHR SQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hq="DNxHR HQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hqx="DNxHR HQX (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_444="DNxHR 444 (4:4:4)"
+
diff --git a/data/locale/id-ID.ini b/data/locale/id-ID.ini
index 82b490d768..bb910483f0 100644
--- a/data/locale/id-ID.ini
+++ b/data/locale/id-ID.ini
@@ -35,5 +35,6 @@ UI.Updater.Dialog.Version.Latest="Versi Terkini:"
+
diff --git a/data/locale/is-IS.ini b/data/locale/is-IS.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/is-IS.ini
+++ b/data/locale/is-IS.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/it-IT.ini b/data/locale/it-IT.ini
index 72cea44bfc..3d13ad3ff5 100644
--- a/data/locale/it-IT.ini
+++ b/data/locale/it-IT.ini
@@ -498,3 +498,11 @@ Codec.ProRes.Profile.APCH="422 Alta Qualità/HQ (APCH)"
Codec.ProRes.Profile.AP4H="4444 Alta Qualità/HQ (AP4H)"
Codec.ProRes.Profile.AP4X="4444 Qualità estrema/XQ (AP4X)"
+Codec.DNxHR.Profile="Profilo"
+Codec.DNxHR.Profile.dnxhd="DNxHD"
+Codec.DNxHR.Profile.dnxhr_lb="DNxHR LB (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_sq="DNxHR SQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hq="DNxHR HQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hqx="DNxHR HQX (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_444="DNxHR 444 (4:4:4)"
+
diff --git a/data/locale/ja-JP.ini b/data/locale/ja-JP.ini
index e1fadb3384..711df7a2b8 100644
--- a/data/locale/ja-JP.ini
+++ b/data/locale/ja-JP.ini
@@ -470,3 +470,5 @@ Codec.ProRes.Profile.APCH="422 High Quality/HQ (APCH)"
Codec.ProRes.Profile.AP4H="4444 High Quality/HQ (AP4H)"
Codec.ProRes.Profile.AP4X="4444 Extreme Quality/XQ (AP4X)"
+Codec.DNxHR.Profile="プロファイル"
+
diff --git a/data/locale/ko-KR.ini b/data/locale/ko-KR.ini
index 0b9663ded3..a33f3db733 100644
--- a/data/locale/ko-KR.ini
+++ b/data/locale/ko-KR.ini
@@ -130,3 +130,4 @@ Source.Mirror.Source="소스"
+
diff --git a/data/locale/mn-MN.ini b/data/locale/mn-MN.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/mn-MN.ini
+++ b/data/locale/mn-MN.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/nl-NL.ini b/data/locale/nl-NL.ini
index 847815af58..b616837c1b 100644
--- a/data/locale/nl-NL.ini
+++ b/data/locale/nl-NL.ini
@@ -158,7 +158,17 @@ Encoder.FFmpeg.NVENC.Preset.default="Standaard"
Encoder.FFmpeg.NVENC.Preset.slow="Traag"
Encoder.FFmpeg.NVENC.Preset.medium="Gemiddeld"
Encoder.FFmpeg.NVENC.Preset.fast="Snel"
+Encoder.FFmpeg.NVENC.Preset.hp="Hoge prestaties"
+Encoder.FFmpeg.NVENC.Preset.hq="Hoge Kwaliteit"
+Encoder.FFmpeg.NVENC.Preset.bd="BluRay Schijf"
+Encoder.FFmpeg.NVENC.Preset.ll="Lage Latentie"
+Encoder.FFmpeg.NVENC.Preset.llhq="Lage Latentie, Hoge Kwaliteit"
+Encoder.FFmpeg.NVENC.Preset.llhp="Lage Latency, Hoge Prestaties"
+Encoder.FFmpeg.NVENC.Preset.lossless="Lossless"
Encoder.FFmpeg.NVENC.Tune="Afstemmen"
+Encoder.FFmpeg.NVENC.Tune.hq="Hoge Kwaliteit"
+Encoder.FFmpeg.NVENC.Tune.ll="Lage Latentie"
+Encoder.FFmpeg.NVENC.Tune.lossless="Lossless"
Encoder.FFmpeg.NVENC.RateControl="Opties voor Snelheidsregeling"
Encoder.FFmpeg.NVENC.RateControl.Mode="Modus"
Encoder.FFmpeg.NVENC.RateControl.Mode.constqp="Constante Kwantisatie Parameter"
@@ -470,3 +480,5 @@ Codec.ProRes.Profile.APCH="422 Hoge Kwaliteit/HQ (APCH)"
Codec.ProRes.Profile.AP4H="4444 Hoge Kwaliteit/HQ (AP4H)"
Codec.ProRes.Profile.AP4X="4444 Extreme Kwaliteit/XQ (AP4X)"
+Codec.DNxHR.Profile="Profiel"
+
diff --git a/data/locale/no-NO.ini b/data/locale/no-NO.ini
index 50cf4f8ed8..05fc4c9921 100644
--- a/data/locale/no-NO.ini
+++ b/data/locale/no-NO.ini
@@ -238,3 +238,5 @@ Codec.HEVC.Tier.main="Main"
Codec.ProRes.Profile="Profil"
+Codec.DNxHR.Profile="Profil"
+
diff --git a/data/locale/pl-PL.ini b/data/locale/pl-PL.ini
index 1c61ed5aac..5b02db84c7 100644
--- a/data/locale/pl-PL.ini
+++ b/data/locale/pl-PL.ini
@@ -469,3 +469,11 @@ Codec.ProRes.Profile.APCH="422 Wysoka jakość/HQ (APCH)"
Codec.ProRes.Profile.AP4H="4444 Wysoka jakość/HQ (AP4H)"
Codec.ProRes.Profile.AP4X="4444 Ekstremalna jakość/XQ (AP4X)"
+Codec.DNxHR.Profile="Profil"
+Codec.DNxHR.Profile.dnxhd="DNxHD"
+Codec.DNxHR.Profile.dnxhr_lb="DNxHR LB (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_sq="DNxHR SQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hq="DNxHR HQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hqx="DNxHR HQX (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_444="DNxHR 444 (4:4:4)"
+
diff --git a/data/locale/pt-BR.ini b/data/locale/pt-BR.ini
index a9ce0672da..4f8f77c88e 100644
--- a/data/locale/pt-BR.ini
+++ b/data/locale/pt-BR.ini
@@ -381,3 +381,5 @@ Codec.ProRes.Profile.APCH="422 Alta Qualidade/HQ (APCH)"
Codec.ProRes.Profile.AP4H="4444 Alta Qualidade/HQ (AP4H)"
Codec.ProRes.Profile.AP4X="4444 Qualidade Extrema/XQ (AP4X)"
+Codec.DNxHR.Profile="Perfil"
+
diff --git a/data/locale/pt-PT.ini b/data/locale/pt-PT.ini
index 143ffb8dae..60fd315158 100644
--- a/data/locale/pt-PT.ini
+++ b/data/locale/pt-PT.ini
@@ -136,3 +136,4 @@ Source.Mirror.Source="Fonte"
+
diff --git a/data/locale/ro-RO.ini b/data/locale/ro-RO.ini
index da6ae89cea..d6cbba34ae 100644
--- a/data/locale/ro-RO.ini
+++ b/data/locale/ro-RO.ini
@@ -269,3 +269,11 @@ Source.Mirror.Source="Sursă"
+Codec.DNxHR.Profile="Profil"
+Codec.DNxHR.Profile.dnxhd="DNxHD"
+Codec.DNxHR.Profile.dnxhr_lb="DNxHR LB (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_sq="DNxHR SQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hq="DNxHR HQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hqx="DNxHR HQX (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_444="DNxHR 444 (4:4:4)"
+
diff --git a/data/locale/ru-RU.ini b/data/locale/ru-RU.ini
index 0962e1c682..6c4553e785 100644
--- a/data/locale/ru-RU.ini
+++ b/data/locale/ru-RU.ini
@@ -498,3 +498,11 @@ Codec.ProRes.Profile.APCH="422 High Quality/HQ (APCH)"
Codec.ProRes.Profile.AP4H="4444 High Quality/HQ (AP4H)"
Codec.ProRes.Profile.AP4X="4444 Extreme Quality/XQ (AP4X)"
+Codec.DNxHR.Profile="Профиль"
+Codec.DNxHR.Profile.dnxhd="DNxHD"
+Codec.DNxHR.Profile.dnxhr_lb="DNxHR LB (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_sq="DNxHR SQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hq="DNxHR HQ (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_hqx="DNxHR HQX (4:2:2)"
+Codec.DNxHR.Profile.dnxhr_444="DNxHR 444 (4:4:4)"
+
diff --git a/data/locale/sh-HR.ini b/data/locale/sh-HR.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/sh-HR.ini
+++ b/data/locale/sh-HR.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/si-LK.ini b/data/locale/si-LK.ini
index cddd4c23fe..8071b227a6 100644
--- a/data/locale/si-LK.ini
+++ b/data/locale/si-LK.ini
@@ -43,3 +43,4 @@ Source.Mirror.Source="මූලාශ්රය"
+
diff --git a/data/locale/sv-SE.ini b/data/locale/sv-SE.ini
index 5243aaa089..2260529019 100644
--- a/data/locale/sv-SE.ini
+++ b/data/locale/sv-SE.ini
@@ -47,3 +47,4 @@ Source.Mirror.Source="Källa"
+
diff --git a/data/locale/th-TH.ini b/data/locale/th-TH.ini
index c75aeadc52..16238833d2 100644
--- a/data/locale/th-TH.ini
+++ b/data/locale/th-TH.ini
@@ -126,3 +126,5 @@ Codec.HEVC.Tier.high="สูง"
Codec.ProRes.Profile="โปรไฟล์"
+Codec.DNxHR.Profile="โปรไฟล์"
+
diff --git a/data/locale/tr-TR.ini b/data/locale/tr-TR.ini
index a9e6f8b9bc..bae4b469b0 100644
--- a/data/locale/tr-TR.ini
+++ b/data/locale/tr-TR.ini
@@ -281,3 +281,5 @@ Codec.ProRes.Profile.APCH="422 Yüksek Kalite/HQ (APCH)"
Codec.ProRes.Profile.AP4H="4444 Yüksek Kalite/HQ (AP4H)"
Codec.ProRes.Profile.AP4X="4444 Ekstrem Kalite/XQ (AP4X)"
+Codec.DNxHR.Profile="Profil"
+
diff --git a/data/locale/uk-UA.ini b/data/locale/uk-UA.ini
index b5f01429e6..005bf0eed3 100644
--- a/data/locale/uk-UA.ini
+++ b/data/locale/uk-UA.ini
@@ -47,5 +47,6 @@ UI.Updater.Dialog.Button.Cancel="Нагадайте мені пізніше"
+
diff --git a/data/locale/vi-VN.ini b/data/locale/vi-VN.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/vi-VN.ini
+++ b/data/locale/vi-VN.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/zh-CN.ini b/data/locale/zh-CN.ini
index 4b8ba116e9..007c3d73b5 100644
--- a/data/locale/zh-CN.ini
+++ b/data/locale/zh-CN.ini
@@ -496,3 +496,5 @@ Codec.ProRes.Profile.APCH="422 高品质/高清(APCH)"
Codec.ProRes.Profile.AP4H="4444 高品质/高清(AP4H)"
Codec.ProRes.Profile.AP4X="444 超高品质/XQ (AP4X)"
+Codec.DNxHR.Profile="配置"
+
diff --git a/data/locale/zh-HK.ini b/data/locale/zh-HK.ini
index 9776ccf076..975a9c217f 100644
--- a/data/locale/zh-HK.ini
+++ b/data/locale/zh-HK.ini
@@ -25,5 +25,6 @@
+
diff --git a/data/locale/zh-TW.ini b/data/locale/zh-TW.ini
index 95e8158497..d85898ccc7 100644
--- a/data/locale/zh-TW.ini
+++ b/data/locale/zh-TW.ini
@@ -85,3 +85,4 @@ Filter.ColorGrade.Tint.Mode.Linear="線性"
+
From f1605807948f1c871a0bf8133e7f0ac16305bb0c Mon Sep 17 00:00:00 2001
From: Michael Fabian 'Xaymar' Dirks
Date: Tue, 10 May 2022 19:29:58 +0200
Subject: [PATCH 012/164] cmake: Improve build system with additional features
and options
- Moved all auto-dependencies to a uniform subdirectory for easier caching and cleanup.
- Add an option to download or specify a path for libOBS+obs-frontend-api.
- Remove the dependency on the non-standard obs-frontend-apiConfig.cmake file.
- Add an option to download or specify a path for OBS Dependencies.
- Add an option to download or specify a path for Qt.
- Add an option to download or specify a path for AOM.
- Fix and improve architecture and platform detection.
- Fix some messages having two :, or no prefix at all.
- Fix detection of obs-frontend-api.
- Fix applying custom compiler and linker flags for MSVC and GNU-style builds.
- Use target_compile_options over add_compile_options for compatibility.
---
.github/workflows/codeql-analysis.yml | 36 +-
.github/workflows/main.yml | 129 ++---
.github/workflows/validate.yml | 42 +-
CMakeLists.txt | 666 +++++++++++++++-----------
cmake/modules/Architecture.cmake | 41 --
5 files changed, 456 insertions(+), 458 deletions(-)
delete mode 100644 cmake/modules/Architecture.cmake
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 7297e69872..b6d3568e3a 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -1,27 +1,14 @@
-# For most projects, this workflow file will not need changing; you simply need
-# to commit it to your repository.
-#
-# You may wish to alter this file to override the set of languages analyzed,
-# or to provide custom queries or build logic.
-#
-# ******** NOTE ********
-# We have attempted to detect the languages in your repository. Please check
-# the `language` matrix defined below to confirm you have the correct set of
-# supported CodeQL languages.
-#
name: "CodeQL"
on:
push:
branches:
+ - 'master'
+ tags:
- '*'
- - '!i18n_master'
- - '!l10n_master'
pull_request:
- # The branches below must be a subset of the branches above
- branches: [ master ]
- schedule:
- - cron: '37 20 * * 4'
+ branches:
+ - '*'
env:
OBS_VERSION: "27.0.0-ci"
@@ -88,20 +75,18 @@ jobs:
cmake \
ninja-build \
git \
- gcc-9 g++9 \
qt5-default libqwt-qt5-dev libqt5svg5-dev \
libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libswresample-dev libswscale-dev \
libcurl4-openssl-dev
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 800 --slave /usr/bin/g++ g++ /usr/bin/g++-9
- - name: "libobs: Cache"
+ - name: "Dependencies: Cache"
+ if: ${{ github.event_name != 'pull_request' }}
uses: actions/cache@v2
with:
path: |
- build/temp/libobs-download
- build/temp/libobs-build
- build/temp/libobs-src
- key: libobs-codeql-${{ env.OBS_VERSION }}-${{ env.DOWNLOAD_OBS_HASH }}-${{ secrets.CACHE_VERSION }}
+ build/temp/autodeps
+ key: autodeps-${{ matrix.id }}-${{ env.CACHE_VERSION }}
- name: "StreamFX: Configure"
shell: bash
@@ -110,11 +95,8 @@ jobs:
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_INSTALL_PREFIX="build/distrib" \
- -DENABLE_FILTER_NVIDIA_FACE_TRACKING=FALSE \
-DPACKAGE_NAME="streamfx-${{ matrix.id }}" \
- -DPACKAGE_PREFIX="build/package" \
- -DDOWNLOAD_OBS_URL="https://github.com/Xaymar/obs-studio/releases/download/${{ env.OBS_VERSION }}/obs-studio-x64-0.0.0.0-ubuntu-x86-64.7z" \
- -DDOWNLOAD_OBS_HASH="SHA256=0AF6C7262C37D80C24CB18523A851FD765C04E766D8EB0F4AC0F6E75D13A035F"
+ -DPACKAGE_PREFIX="build/package"
- name: "StreamFX: Build"
shell: bash
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 8205e6d4f3..39f69276ae 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -11,9 +11,7 @@ on:
- '*'
env:
- QT_VERSION: "5.15.2"
- OBS_VERSION: "27.0.0-ci"
- OBSDEPS_VERSION: "27.0.0"
+ CACHE_VERSION: 1
LIBAOM_VERSION: "3.2.0.0"
jobs:
@@ -41,48 +39,15 @@ jobs:
with:
submodules: recursive
fetch-depth: 0
- - name: "libobs: Cache"
- if: ${{ github.event_name != 'pull_request' }}
- uses: actions/cache@v2
- with:
- path: |
- build/temp/libobs-download
- build/temp/libobs-build
- build/temp/libobs-src
- key: libobs-${{ matrix.id }}-${{ env.OBS_VERSION }}-${{ env.DOWNLOAD_OBS_HASH }}-${{ secrets.CACHE_VERSION }}
- - name: "obsdeps: Cache"
- if: ${{ github.event_name != 'pull_request' }}
- uses: actions/cache@v2
- with:
- path: |
- build/temp/obsdeps-download
- build/temp/obsdeps-build
- build/temp/obsdeps-src
- key: obsdeps-${{ matrix.id }}-${{ env.OBSDEPS_VERSION }}-${{ env.DOWNLOAD_OBSDEPS_HASH }}-${{ secrets.CACHE_VERSION }}
- - name: "qt: Cache"
- if: ${{ github.event_name != 'pull_request' }}
- uses: actions/cache@v2
- with:
- path: |
- build/temp/qt-download
- build/temp/qt-build
- build/temp/qt-src
- key: qt-${{ matrix.id }}-${{ env.OBSDEPS_VERSION }}-${{ env.QT_VERSION }}-${{ secrets.CACHE_VERSION }}
- - name: "libaom: Cache"
+
+ - name: "Dependencies: Cache"
if: ${{ github.event_name != 'pull_request' }}
uses: actions/cache@v2
- id: libaom-cache
with:
path: |
- build/libaom
- key: libaom-${{ matrix.id }}-${{ env.LIBAOM_VERSION }}-${{ secrets.CACHE_VERSION }}
- - name: "libaom: Install"
- if: ${{ steps.libaom-cache.outputs.cache-hit != 'true' }}
- id: libaom-install
- shell: bash
- run: |
- curl -L -o "aom.7z" "https://github.com/Xaymar/aom/releases/download/v${{ env.LIBAOM_VERSION }}/aom-windows-64-shared.7z"
- 7z x -y -o"build/libaom/" "aom.7z"
+ build/temp/autodeps
+ key: autodeps-${{ matrix.id }}-${{ env.CACHE_VERSION }}
+
- name: "Code Signing"
if: ${{ github.event_name != 'pull_request' }}
id: codesign
@@ -91,6 +56,7 @@ jobs:
# Restore the Certificate back into a file.
echo "${{ secrets.CODESIGN_CERT_WIN }}" | base64 --decode > "${{ github.workspace }}/cert.pfx"
echo "::set-output name=cmake_args::-DENABLE_CODESIGN=ON -DCODESIGN_TIMESTAMPS=ON"
+
- name: "StreamFX: Configure"
shell: bash
env:
@@ -103,28 +69,25 @@ jobs:
-DCMAKE_INSTALL_PREFIX="build/distrib" \
-DPACKAGE_NAME="streamfx-${{ matrix.id }}" \
-DPACKAGE_PREFIX="build/package" \
- -DDOWNLOAD_OBS_URL="https://github.com/Xaymar/obs-studio/releases/download/${{ env.OBS_VERSION }}/obs-studio-x64-0.0.0.0-windows-x86-64.7z" \
- -DDOWNLOAD_OBS_HASH="SHA256=EBF9853C8A553E16ECBCA22523F401E6CF1EB2E8DA93F1493FEF41D65BD06633" \
- -DDOWNLOAD_OBSDEPS_URL="https://github.com/Xaymar/obs-studio/releases/download/${{ env.OBSDEPS_VERSION }}/deps-windows-x86.7z" \
- -DDOWNLOAD_OBSDEPS_HASH="SHA256=B4AED165016F0B64A7E8B256CCC12EAF8AF087F61B0B239B9D3D00277485B5B5" \
- -DDOWNLOAD_QT=ON \
- -DDOWNLOAD_QT_URL="https://github.com/Xaymar/obs-studio/releases/download/${{ env.OBSDEPS_VERSION }}/qt-${{ env.QT_VERSION }}-windows-x86-64.7z" \
- -DDOWNLOAD_QT_HASH="SHA256=109B9C21EF165B0C46DFAA9AD23124F2070ED4D74207C4AFB308183CB8D43BDD" \
-DAOM_PATH="build/libaom/"
+
- name: "StreamFX: Build"
shell: bash
run: |
cmake --build "build/temp" --config RelWithDebInfo --target INSTALL
+
- name: "StreamFX: Package (Install Prerequisites)"
run: |
curl "-kL" "https://cdn.xaymar.com/ci/innosetup-6.1.2.exe" "-f" "--retry" "5" "-o" "inno.exe"
.\inno.exe /VERYSILENT /SP- /SUPPRESSMSGBOXES /NORESTART
+
- name: "StreamFX: Package"
shell: bash
run: |
mkdir build/package
cmake --build "build/temp" --config RelWithDebInfo --target PACKAGE_7Z
cmake --build "build/temp" --config RelWithDebInfo --target PACKAGE_ZIP
+
- name: "StreamFX: Signed Installer Preparation"
if: ${{ github.event_name != 'pull_request' }}
id: codesign_install
@@ -134,11 +97,13 @@ jobs:
signtool=$(awk 'match($0, /^;signtool=(.+)$/, ary) {print ary[1]}' "${{ github.workspace }}/build/temp/installer.iss")
echo "::set-output name=iscc_signtool::${signtool}"
fi
+
- name: "StreamFX: Package Installer"
shell: cmd
run: |
echo '"C:\Program Files (x86)\Inno Setup 6\ISCC.exe" /V10 "/Ssigntool=${{ steps.codesign_install.outputs.iscc_signtool }} $p" ".\build\temp\installer.iss"'
"C:\Program Files (x86)\Inno Setup 6\ISCC.exe" /V10 "/Ssigntool=${{ steps.codesign_install.outputs.iscc_signtool }} $p" ".\build\temp\installer.iss"
+
- name: "Artifacts"
uses: actions/upload-artifact@v1
with:
@@ -178,6 +143,7 @@ jobs:
with:
submodules: recursive
fetch-depth: 0
+
- name: "Prerequisites: Apt-Get"
shell: bash
run: |
@@ -195,36 +161,36 @@ jobs:
libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libswresample-dev libswscale-dev \
libcurl4-openssl-dev
${{ matrix.extra_command }}
- - name: "libobs: Cache"
+
+ - name: "Dependencies: Cache"
if: ${{ github.event_name != 'pull_request' }}
uses: actions/cache@v2
with:
path: |
- build/temp/libobs-download
- build/temp/libobs-build
- build/temp/libobs-src
- key: libobs-${{ matrix.id }}-${{ env.OBS_VERSION }}-${{ env.DOWNLOAD_OBS_HASH }}-${{ secrets.CACHE_VERSION }}
+ build/temp/autodeps
+ key: autodeps-${{ matrix.id }}-${{ env.CACHE_VERSION }}
+
- name: "StreamFX: Configure"
shell: bash
run: |
cmake -H. -B"build/temp" \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_INSTALL_PREFIX="build/distrib" \
- -DENABLE_FILTER_NVIDIA_FACE_TRACKING=FALSE \
-DPACKAGE_NAME="streamfx-${{ matrix.id }}" \
- -DPACKAGE_PREFIX="build/package" \
- -DDOWNLOAD_OBS_URL="https://github.com/Xaymar/obs-studio/releases/download/${{ env.OBS_VERSION }}/obs-studio-x64-0.0.0.0-ubuntu-x86-64.7z" \
- -DDOWNLOAD_OBS_HASH="SHA256=0AF6C7262C37D80C24CB18523A851FD765C04E766D8EB0F4AC0F6E75D13A035F"
+ -DPACKAGE_PREFIX="build/package"
+
- name: "StreamFX: Build"
shell: bash
run: |
cmake --build "build/temp" --config RelWithDebInfo --target install
+
- name: "StreamFX: Package"
shell: bash
run: |
mkdir build/package
cmake --build "build/temp" --config RelWithDebInfo --target PACKAGE_7Z
cmake --build "build/temp" --config RelWithDebInfo --target PACKAGE_ZIP
+
- name: "Artifacts"
uses: actions/upload-artifact@v1
with:
@@ -251,42 +217,15 @@ jobs:
with:
submodules: recursive
fetch-depth: 0
- - name: "libobs: Cache"
- if: ${{ github.event_name != 'pull_request' }}
- uses: actions/cache@v2
- with:
- path: |
- build/temp/libobs-download
- build/temp/libobs-build
- build/temp/libobs-src
- key: libobs-${{ matrix.id }}-${{ env.OBS_VERSION }}-${{ env.DOWNLOAD_OBS_HASH }}-${{ secrets.CACHE_VERSION }}
- - name: "obsdeps: Cache"
- if: ${{ github.event_name != 'pull_request' }}
- uses: actions/cache@v2
- with:
- path: |
- build/temp/obsdeps-download
- build/temp/obsdeps-build
- build/temp/obsdeps-src
- key: obsdeps-${{ matrix.id }}-${{ env.OBSDEPS_VERSION }}-${{ env.DOWNLOAD_OBSDEPS_HASH }}-${{ secrets.CACHE_VERSION }}
- - name: "qt: Cache"
+
+ - name: "Dependencies: Cache"
if: ${{ github.event_name != 'pull_request' }}
uses: actions/cache@v2
- id: qt-cache
with:
path: |
- /usr/local/Cellar/qt@5
- key: qt-${{ matrix.id }}-${{ env.QT_VERSION }}-${{ secrets.CACHE_VERSION }}
- - name: "qt: Install"
- if: ${{ (github.event_name == 'pull_request') || (steps.qt-cache.outputs.cache-hit != 'true') }}
- shell: bash
- run: |
- brew install qt@5
- - name: "qt: Link"
- if: ${{ (github.event_name != 'pull_request') && (steps.qt-cache.outputs.cache-hit != 'false') }}
- shell: bash
- run: |
- brew link qt@5
+ build/temp/autodeps
+ key: autodeps-${{ matrix.id }}-${{ env.CACHE_VERSION }}
+
- name: "StreamFX: Configure"
shell: bash
run: |
@@ -294,22 +233,20 @@ jobs:
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_INSTALL_PREFIX="build/distrib" \
-DPACKAGE_NAME="streamfx-${{ matrix.id }}" \
- -DPACKAGE_PREFIX="build/package" \
- -DQt5_DIR="/usr/local/opt/qt@5/lib/cmake/Qt5/" \
- -DDOWNLOAD_OBS_URL="https://github.com/Xaymar/obs-studio/releases/download/${{ env.OBS_VERSION }}/obs-studio-x64-0.0.0.0-macos-x86-64.7z" \
- -DDOWNLOAD_OBS_HASH="SHA256=F15BC4CA8EB3F581A94372759CFE554E30D202B604B541445A5756B878E4E799" \
- -DDOWNLOAD_OBSDEPS_URL="https://github.com/Xaymar/obs-studio/releases/download/${{ env.OBSDEPS_VERSION }}/deps-macos-x86_64-2021-03-25.tar.gz" \
- -DDOWNLOAD_OBSDEPS_HASH="SHA256=1C409374BCAB9D5CEEAFC121AA327E13AB222096718AF62F2648302DF62898D6"
+ -DPACKAGE_PREFIX="build/package"
+
- name: "StreamFX: Build"
shell: bash
run: |
cmake --build "build/temp" --config RelWithDebInfo --target install
+
- name: "StreamFX: Package"
shell: bash
run: |
mkdir build/package
cmake --build "build/temp" --config RelWithDebInfo --target PACKAGE_7Z
cmake --build "build/temp" --config RelWithDebInfo --target PACKAGE_ZIP
+
- name: 'Packages: Install'
shell: bash
run: |
@@ -317,10 +254,12 @@ jobs:
sudo hdiutil attach ./Packages.dmg
pushd /Volumes/Packages*
sudo installer -pkg ./Install\ Packages.pkg -target /
+
- name: "Packages: Package"
shell: bash
run: |
packagesbuild ./build/temp/installer.pkgproj
+
- name: "Artifacts"
uses: actions/upload-artifact@v1
with:
diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml
index c48f14dc30..4edce583f3 100644
--- a/.github/workflows/validate.yml
+++ b/.github/workflows/validate.yml
@@ -8,6 +8,9 @@ on:
tags:
- '*'
+env:
+ CACHE_VERSION: 1
+
jobs:
clang-format:
name: "clang-format"
@@ -17,38 +20,53 @@ jobs:
CXX: clang++
CMAKE_GENERATOR: "Ninja"
steps:
- - name: "Clone Repository"
- uses: actions/checkout@v1
- - name: "Submodules & Packages"
+ - name: "Clone"
+ uses: actions/checkout@v2
+ with:
+ submodules: recursive
+ fetch-depth: 0
+
+ - name: "Prerequisites: Apt-Get"
shell: bash
run: |
- git submodule update --init --recursive
sudo apt-get -qq update
sudo apt-get purge libjpeg9-dev:amd64 libjpeg8-dev:amd64 libjpeg-turbo8-dev:amd64
sudo apt-get install \
build-essential \
+ checkinstall \
+ pkg-config \
cmake \
ninja-build \
git \
+ ${{ matrix.packages }} \
qt5-default libqwt-qt5-dev libqt5svg5-dev \
libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libswresample-dev libswscale-dev \
- libcurl4-openssl-dev \
- checkinstall pkg-config
+ libcurl4-openssl-dev
sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
- - name: "Cache: Prerequisites"
+
+ - name: "Dependencies: Cache"
+ if: ${{ github.event_name != 'pull_request' }}
uses: actions/cache@v2
with:
path: |
- build/temp/libobs-download/libobs-download-prefix/src/libobs.7z
- key: ubuntu-20.04
- - name: "Configure & Format Project"
+ build/temp/autodeps
+ key: autodeps-${{ matrix.id }}-${{ env.CACHE_VERSION }}
+
+ - name: "StreamFX: Configure"
shell: bash
run: |
cmake -H. -B"build/temp" \
+ -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_INSTALL_PREFIX="build/distrib" \
- -DCMAKE_PACKAGE_NAME="streamfx-${{ matrix.id }}" -DCMAKE_PACKAGE_PREFIX="build/package" \
- -DENABLE_CLANG=TRUE -DENABLE_FILTER_NVIDIA_FACE_TRACKING=FALSE
+ -DCMAKE_PACKAGE_NAME="streamfx-${{ matrix.id }}" \
+ -DCMAKE_PACKAGE_PREFIX="build/package" \
+ -DENABLE_CLANG=TRUE
+
+ - name: "StreamFX: Format"
+ shell: bash
+ run: |
cmake --build "build/temp" --config RelWithDebInfo --target StreamFX_CLANG-FORMAT
+
- name: "Validate Formatting"
shell: bash
run: |
diff --git a/CMakeLists.txt b/CMakeLists.txt
index acaa87c67a..fb65093814 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -176,7 +176,6 @@ set(CMAKE_MODULE_PATH
)
# Include
-include("Architecture") # Architecture Detection
include("util") # CacheClear, CacheSet
include("DownloadProject") # DownloadProject
@@ -201,72 +200,57 @@ else()
endif()
# Architecture
-set(D_PLATFORM_INSTR ${ARCH_INST})
-if(ARCH_INST STREQUAL "x86")
- set(D_PLATFORM_INSTR_X86 ON)
- set(D_PLATFORM_ARCH_X86 ON)
-elseif(ARCH_INST STREQUAL "ARM")
- set(D_PLATFORM_INSTR_ARM ON)
- set(D_PLATFORM_ARCH_ARM ON)
-elseif(ARCH_INST STREQUAL "IA64")
- set(D_PLATFORM_INSTR_ITANIUM ON)
- set(D_PLATFORM_ARCH_ITANIUM ON)
+set(ARCH_INSTR_32 "i386;i686;x86;arm;ARM")
+set(ARCH_INSTR_64 "x86_64;AMD64;IA64;arm64;ARM64")
+set(ARCH_INSTR_X86 "i386;i686;x86;x86_64;AMD64")
+set(ARCH_INSTR_ARM "arm;ARM;arm64;ARM64")
+set(ARCH_INSTR_ITANIUM "IA64")
+set(ARCH_BITS 0)
+set(ARCH_BITS_POINTER 0)
+set(ARCH_INST "")
+
+# - Bitness
+list(FIND ARCH_INSTR_32 "${CMAKE_SYSTEM_PROCESSOR}" FOUND)
+if(FOUND GREATER -1)
+ set(ARCH_BITS 32)
endif()
-set(D_PLATFORM_ARCH ${ARCH_INST})
-# Bitness
+list(FIND ARCH_INSTR_64 "${CMAKE_SYSTEM_PROCESSOR}" FOUND)
+if(FOUND GREATER -1)
+ set(ARCH_BITS 64)
+endif()
set(D_PLATFORM_BITS ${ARCH_BITS})
-set(D_PLATFORM_BITS_PTR ${ARCH_BITS_POINTER})
-
-################################################################################
-# C/C++ Compiler Adjustments
-################################################################################
-if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
- message(STATUS "Applying custom flags for MSVC style build.")
-
- # MSVC/ClangCL
- # - Dynamically link Microsoft C/C++ Redistributable.
- # - Enable /W3 and disable useless warnings.
- # - Enable C++ exceptions with SEH exceptions.
- # - Enable multi-processor compiling.
-
- # Build with dynamic MSVC linkage.
- add_compile_options(
- $<$:/MD>
- $<$:/MDd>
- $<$:/MD>
- $<$:/MD>
- $<$:/MD>
- )
-
- # Enable most useful warnings.
- set(DISABLED_WARNINGS
- "/wd4061" "/wd4100" "/wd4180" "/wd4201" "/wd4464" "/wd4505" "/wd4514"
- "/wd4571" "/wd4623" "/wd4625" "/wd4626" "/wd4668" "/wd4710" "/wd4774"
- "/wd4820" "/wd5026" "/wd5027" "/wd5039" "/wd5045" "/wd26812"
- )
- add_compile_options("/W3")
- foreach(WARN ${DISABLED_WARNINGS})
- add_compile_options("${WARN}")
- endforeach()
- # C++ Exceptions & SEH
- add_compile_options("/EHa")
+# - Pointer Size (bits)
+math(EXPR ARCH_BITS_POINTER "8*${CMAKE_SIZEOF_VOID_P}")
+set(D_PLATFORM_BITS_PTR ${ARCH_BITS_POINTER})
- # Multiprocessor compiling
- add_compile_options("/MP")
-elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
- message(STATUS "Applying custom flags for GNU style build.")
+# - Basic Instruction Set
+list(FIND ARCH_INSTR_X86 "${CMAKE_SYSTEM_PROCESSOR}" FOUND)
+if(FOUND GREATER -1)
+ list(APPEND ARCH_INST "x86")
+ set(D_PLATFORM_INSTR_X86 ON)
+ set(D_PLATFORM_ARCH_X86 ON)
+endif()
- # Clang/AppleClang/GNU
- # - Don't export by default. (Temporarily disabled)
- # - Enable all and extra warnings.
+list(FIND ARCH_INSTR_ARM "${CMAKE_SYSTEM_PROCESSOR}" FOUND)
+if(FOUND GREATER -1)
+ list(APPEND ARCH_INST "ARM")
+ set(D_PLATFORM_INSTR_ARM ON)
+ set(D_PLATFORM_ARCH_ARM ON)
+endif()
- add_compile_options("-Wall")
- add_compile_options("-Wextra")
- # add_compile_options("-fvisibility=hidden")
+list(FIND ARCH_INSTR_ITANIUM "${CMAKE_SYSTEM_PROCESSOR}" FOUND)
+if(FOUND GREATER -1)
+ list(APPEND ARCH_INST "Itanium")
+ set(D_PLATFORM_INSTR_ITANIUM ON)
+ set(D_PLATFORM_ARCH_ITANIUM ON)
endif()
+set(D_PLATFORM_INSTR ${ARCH_INST})
+set(D_PLATFORM_ARCH ${ARCH_INST})
+message(STATUS "${LOGPREFIX} Taget is ${D_PLATFORM_BITS}bit ${ARCH_INST} with a pointer size of ${D_PLATFORM_BITS_PTR}bit.")
+
################################################################################
# Detect if we are building with OBS Studio (different from Grouped builds)
################################################################################
@@ -380,241 +364,342 @@ if(${PREFIX}ENABLE_CODESIGN AND (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/codes
endif()
################################################################################
-# Standalone Build: OBS Studio
+# Auto-Dependency: libOBS + obs-frontend-api
################################################################################
-if(NOT ${PREFIX}OBS_NATIVE)
+if(STANDALONE)
# Options
- set(${PREFIX}DOWNLOAD_OBS_URL "" CACHE STRING "(Optional) URL of prebuilt libOBS archive to download.")
- set(${PREFIX}DOWNLOAD_OBS_HASH "" CACHE STRING "(Optional) The hash for the libOBS archive.")
+ set(${PREFIX}OBS_DOWNLOAD TRUE CACHE BOOL "Automatically download libOBS and obs-frontend-api?")
+ set(${PREFIX}OBS_PATH "" CACHE PATH "Path to libOBS, if ${PREFIX}OBS_DOWNLOAD is not set.")
+ set(${PREFIX}OBS_DOWNLOAD_URL "" CACHE STRING "The URL from which to download libOBS and obs-frontend-api, if autodetection fails. (Optional)")
+ set(${PREFIX}OBS_DOWNLOAD_HASH "" CACHE STRING "The hash string for the given URL. Must be a SHA-256 hash if provided. (Optional)")
mark_as_advanced(
- ${PREFIX}DOWNLOAD_OBS_URL
- ${PREFIX}DOWNLOAD_OBS_HASH
+ ${PREFIX}OBS_PATH
+ ${PREFIX}OBS_DOWNLOAD_URL
+ ${PREFIX}OBS_DOWNLOAD_HASH
)
- # Allow overriding what version we build against.
- if(${PREFIX}DOWNLOAD_OBS_URL)
- set(_DOWNLOAD_OBS_URL "${${PREFIX}DOWNLOAD_OBS_URL}")
- set(_DOWNLOAD_OBS_HASH "${${PREFIX}DOWNLOAD_OBS_HASH}")
- else()
- set(_DOWNLOAD_OBS_VERSION "27.0.0-ci")
- if (D_PLATFORM_WINDOWS)
- if (D_PLATFORM_ARCH_X86)
- set(_DOWNLOAD_OBS_URL "https://github.com/Xaymar/obs-studio/releases/download/${_DOWNLOAD_OBS_VERSION}/obs-studio-x64-0.0.0.0-windows-${D_PLATFORM_ARCH}-${D_PLATFORM_BITS}.7z")
- if (D_PLATFORM_BITS EQUAL 64)
- set(_DOWNLOAD_OBS_HASH "SHA256=EBF9853C8A553E16ECBCA22523F401E6CF1EB2E8DA93F1493FEF41D65BD06633")
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
+ if(${PREFIX}OBS_DOWNLOAD)
+ if(${PREFIX}OBS_DOWNLOAD_URL STREQUAL "")
+ # Figure out download URLs and hashes.
+ if (D_PLATFORM_WINDOWS)
+ if (D_PLATFORM_ARCH_X86)
+ if (D_PLATFORM_BITS EQUAL 64)
+ set(OBS_DOWNLOAD_URL "https://github.com/Xaymar/obs-studio/releases/download/27.2.4-ci/windows-x86_64.tar.gz")
+ set(OBS_DOWNLOAD_HASH "DD931BBB2E0720F1D7573C65D8CC9D638F1EE2AC99F7173BF8935CD3A3BCE3F4")
+ endif()
endif()
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
- endif()
- elseif(D_PLATFORM_LINUX)
- if (D_PLATFORM_ARCH_X86)
- set(_DOWNLOAD_OBS_URL "https://github.com/Xaymar/obs-studio/releases/download/${_DOWNLOAD_OBS_VERSION}/obs-studio-x64-0.0.0.0-ubuntu-${D_PLATFORM_ARCH}-${D_PLATFORM_BITS}.7z")
- if (D_PLATFORM_BITS EQUAL 64)
- set(_DOWNLOAD_OBS_HASH "SHA256=0AF6C7262C37D80C24CB18523A851FD765C04E766D8EB0F4AC0F6E75D13A035F")
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
+ elseif(D_PLATFORM_LINUX)
+ if (D_PLATFORM_ARCH_X86)
+ if (D_PLATFORM_BITS EQUAL 64)
+ set(OBS_DOWNLOAD_URL "https://github.com/Xaymar/obs-studio/releases/download/27.2.4-ci/linux-x86_64.tar.gz")
+ set(OBS_DOWNLOAD_HASH "CA19E8260E1A556E6231D75064837C61C6D480BD90C97A0B930005AE527BF625")
+ endif()
endif()
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
- endif()
- elseif(D_PLATFORM_MAC)
- if (D_PLATFORM_ARCH_X86)
- set(_DOWNLOAD_OBS_URL "https://github.com/Xaymar/obs-studio/releases/download/${_DOWNLOAD_OBS_VERSION}/obs-studio-x64-0.0.0.0-macos-${D_PLATFORM_ARCH}-${D_PLATFORM_BITS}.7z")
- if (D_PLATFORM_BITS EQUAL 64)
- set(_DOWNLOAD_OBS_HASH "SHA256=F15BC4CA8EB3F581A94372759CFE554E30D202B604B541445A5756B878E4E799")
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
+ elseif(D_PLATFORM_MAC)
+ if (D_PLATFORM_ARCH_X86)
+ if (D_PLATFORM_BITS EQUAL 64)
+ set(OBS_DOWNLOAD_URL "https://github.com/Xaymar/obs-studio/releases/download/27.2.4-ci/macos-x86_64.tar.gz")
+ set(OBS_DOWNLOAD_HASH "0DD5A57DD537B97CAA8470212F8F6B637F47D4742A5D1F17787F4FE9DBC70B33")
+ endif()
endif()
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
+ endif()
+
+ # Verify that the platform, architecture and bitness is supported.
+ if(OBS_DOWNLOAD_URL STREQUAL "")
+ message(FATAL_ERROR "${LOGPREFIX} Download for libOBS failed, as Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
return()
endif()
else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
+ set(OBS_DOWNLOAD_URL "${${PREFIX}OBS_DOWNLOAD_URL}")
+ set(OBS_DOWNLOAD_HASH "${${PREFIX}OBS_DOWNLOAD_HASH}")
endif()
- endif()
- # Download libOBS
- download_project(
- PROJ libobs
- URL "${_DOWNLOAD_OBS_URL}"
- URL_HASH "${_DOWNLOAD_OBS_HASH}"
- DOWNLOAD_NO_PROGRESS OFF
- UPDATE_DISCONNECTED OFF
- )
+ if(OBS_DOWNLOAD_HASH STREQUAL "")
+ download_project(
+ PROJ libobs
+ PREFIX "autodeps"
+ URL "${OBS_DOWNLOAD_URL}"
+ DOWNLOAD_NO_PROGRESS OFF
+ UPDATE_DISCONNECTED OFF
+ )
+ else()
+ download_project(
+ PROJ libobs
+ PREFIX "autodeps"
+ URL "${OBS_DOWNLOAD_URL}"
+ URL_HASH "SHA256=${OBS_DOWNLOAD_HASH}"
+ DOWNLOAD_NO_PROGRESS OFF
+ UPDATE_DISCONNECTED OFF
+ )
+ endif()
+ CacheSet(${PREFIX}OBS_PATH "${libobs_SOURCE_DIR}")
+ endif()
+
+ if(NOT EXISTS "${${PREFIX}OBS_PATH}/cmake/LibObs/LibObsConfig.cmake")
+ message(FATAL_ERROR "${LOGPREFIX} The provided path for libOBS is invalid as it did not contain '/cmake/LibObs/LibObsConfig.cmake'.")
+ return()
+ else()
+ include("${${PREFIX}OBS_PATH}/cmake/LibObs/LibObsConfig.cmake")
+ endif()
- include("${libobs_SOURCE_DIR}/cmake/LibObs/LibObsConfig.cmake")
+ if (NOT TARGET obs-frontend-api)
+ if(EXISTS "${${PREFIX}OBS_PATH}/cmake/obs-frontend-api/obs-frontend-apiConfig.cmake")
+ include("${${PREFIX}OBS_PATH}/cmake/obs-frontend-api/obs-frontend-apiConfig.cmake")
+ elseif((EXISTS "${${PREFIX}OBS_PATH}/bin/${D_PLATFORM_BITS}bit/obs-frontend-api.lib") AND (EXISTS "${${PREFIX}OBS_PATH}/include/obs-frontend-api.h"))
+ add_library(obs-frontend-api SHARED IMPORTED)
+ set_target_properties(obs-frontend-api PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${${PREFIX}OBS_PATH}/include"
+ INTERFACE_LINK_LIBRARIES "libobs"
+ IMPORTED_CONFIGURATIONS RELWITHDEBINFO
+ IMPORTED_IMPLIB_RELWITHDEBINFO "${${PREFIX}OBS_PATH}/bin/${D_PLATFORM_BITS}bit/obs-frontend-api.lib"
+ IMPORTED_LOCATION_RELWITHDEBINFO "${${PREFIX}OBS_PATH}/bin/${D_PLATFORM_BITS}bit/obs-frontend-api.dll"
+ )
+ else()
+ message(WARNING "${LOGPREFIX} The provided path for libOBS did not contain obs-frontend-api.")
+ endif()
+ endif()
endif()
################################################################################
-# Standalone Build: OBS Studio Dependencies
+# Auto-Dependency: OBS Studio Dependencies
################################################################################
if(STANDALONE AND NOT D_PLATFORM_LINUX)
# Options
- set(${PREFIX}DOWNLOAD_OBSDEPS_URL "" CACHE STRING "(Optional) URL of prebuilt libOBS archive to download.")
- set(${PREFIX}DOWNLOAD_OBSDEPS_HASH "" CACHE STRING "(Optional) The hash for the libOBS archive.")
+ set(${PREFIX}OBSDEPS_DOWNLOAD TRUE CACHE BOOL "Automatically download pre-built libOBS dependencies?")
+ set(${PREFIX}OBSDEPS_PATH "" CACHE PATH "Path to pre-build libOBS dependencies, if ${PREFIX}OBSDEPS_DOWNLOAD is not set.")
+ set(${PREFIX}OBSDEPS_DOWNLOAD_URL "" CACHE STRING "The URL from which to download pre-built libOBS dependencies, if autodetection fails. (Optional)")
+ set(${PREFIX}OBSDEPS_DOWNLOAD_HASH "" CACHE STRING "The hash string for the given URL. Must be a SHA-256 hash if provided. (Optional)")
mark_as_advanced(
- ${PREFIX}DOWNLOAD_OBSDEPS_URL
- ${PREFIX}DOWNLOAD_OBSDEPS_HASH
+ ${PREFIX}OBSDEPS_PATH
+ ${PREFIX}OBSDEPS_DOWNLOAD_URL
+ ${PREFIX}OBSDEPS_DOWNLOAD_HASH
)
- # Allow overriding what version we build against.
- if(${PREFIX}DOWNLOAD_OBSDEPS_URL)
- set(_DOWNLOAD_OBSDEPS_URL "${${PREFIX}DOWNLOAD_OBSDEPS_URL}")
- set(_DOWNLOAD_OBSDEPS_HASH "${${PREFIX}DOWNLOAD_OBSDEPS_HASH}")
- else()
- if (D_PLATFORM_WINDOWS)
- if (D_PLATFORM_ARCH_X86)
- set(_DOWNLOAD_OBSDEPS_URL "https://github.com/Xaymar/obs-studio/releases/download/27.0.0/deps-windows-x86.7z")
- if (D_PLATFORM_BITS EQUAL 64)
- set(_DOWNLOAD_OBSDEPS_HASH "SHA256=B4AED165016F0B64A7E8B256CCC12EAF8AF087F61B0B239B9D3D00277485B5B5")
- elseif (D_PLATFORM_BITS EQUAL 32)
- set(_DOWNLOAD_OBSDEPS_HASH "SHA256=B4AED165016F0B64A7E8B256CCC12EAF8AF087F61B0B239B9D3D00277485B5B5")
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
- endif()
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
- endif()
- elseif(D_PLATFORM_MAC)
- if (D_PLATFORM_ARCH_X86)
- if (D_PLATFORM_BITS EQUAL 64)
- set(_DOWNLOAD_OBSDEPS_URL "https://github.com/Xaymar/obs-studio/releases/download/27.0.0/deps-macos-x86_64-2021-03-25.tar.gz")
- set(_DOWNLOAD_OBSDEPS_HASH "SHA256=1C409374BCAB9D5CEEAFC121AA327E13AB222096718AF62F2648302DF62898D6")
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
+ if(${PREFIX}OBSDEPS_DOWNLOAD)
+ if(${PREFIX}OBSDEPS_DOWNLOAD_URL STREQUAL "")
+ # Figure out download URLs and hashes.
+ if (D_PLATFORM_WINDOWS)
+ set(DEPS_VERSION "2022-01-31")
+ if (D_PLATFORM_ARCH_X86)
+ if (D_PLATFORM_BITS EQUAL 64)
+ set(OBSDEPS_DOWNLOAD_URL "https://github.com/obsproject/obs-deps/releases/download/win-${DEPS_VERSION}/windows-deps-${DEPS_VERSION}.zip")
+ set(OBSDEPS_DOWNLOAD_HASH "66E55FE35A507C902C036EB11E691D0257FECA545A8EE57324B69427717026DD")
+ endif()
endif()
- elseif(D_PLATFORM_ARCH_ARM)
- if (D_PLATFORM_BITS EQUAL 64)
- set(_DOWNLOAD_OBSDEPS_URL "https://github.com/Xaymar/obs-studio/releases/download/27.0.0/deps-macos-arm64-2021-03-25.tar.gz")
- set(_DOWNLOAD_OBSDEPS_HASH "SHA256=C0EC57D360AF190E372D6BB883134FA26B1A7E49840DD146B172B48D548B55BC")
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
+ elseif(D_PLATFORM_MAC)
+ set(DEPS_VERSION "2022-02-13")
+ if (D_PLATFORM_ARCH_X86 AND D_PLATFORM_ARCH_ARM)
+ if (D_PLATFORM_BITS EQUAL 64)
+ set(OBSDEPS_DOWNLOAD_URL "https://github.com/obsproject/obs-deps/releases/download/${DEPS_VERSION}/macos-deps-${DEPS_VERSION}-universal.tar.xz")
+ set(OBSDEPS_DOWNLOAD_HASH "77471B1D345A768E8EFEC3F6AD9DC79F3C7CD34840B66F721B80025D29713F5D")
+ endif()
+ elseif (D_PLATFORM_ARCH_X86)
+ if (D_PLATFORM_BITS EQUAL 64)
+ set(OBSDEPS_DOWNLOAD_URL "https://github.com/obsproject/obs-deps/releases/download/${DEPS_VERSION}/macos-deps-${DEPS_VERSION}-x86_64.tar.xz")
+ set(OBSDEPS_DOWNLOAD_HASH "1A8715D66E664B857942DEADED0DC46C4F6CD22E88F01ED1188F3BD3FCF632C4")
+ endif()
+ elseif (D_PLATFORM_ARCH_ARM)
+ if (D_PLATFORM_BITS EQUAL 64)
+ set(OBSDEPS_DOWNLOAD_URL "https://github.com/obsproject/obs-deps/releases/download/${DEPS_VERSION}/macos-deps-${DEPS_VERSION}-arm64.tar.xz")
+ set(OBSDEPS_DOWNLOAD_HASH "2CFCAF05765400C696908F242AEA87B6E1848E1A48CD3EDC2EB7F8CB249C9D48")
+ endif()
endif()
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
+ endif()
+
+ # Verify that the platform, architecture and bitness is supported.
+ if(OBSDEPS_DOWNLOAD_URL STREQUAL "")
+ message(FATAL_ERROR "${LOGPREFIX} Download for pre-built OBS dependencies failed, as Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
return()
endif()
else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
+ set(OBSDEPS_DOWNLOAD_URL "${${PREFIX}OBSDEPS_DOWNLOAD_URL}")
+ set(OBSDEPS_DOWNLOAD_HASH "${${PREFIX}OBSDEPS_DOWNLOAD_HASH}")
endif()
- endif()
-
- # Download libOBS
- download_project(
- PROJ obsdeps
- URL "${_DOWNLOAD_OBSDEPS_URL}"
- URL_HASH "${_DOWNLOAD_OBSDEPS_HASH}"
- DOWNLOAD_NO_PROGRESS OFF
- UPDATE_DISCONNECTED OFF
- )
+ if(OBSDEPS_DOWNLOAD_HASH STREQUAL "")
+ download_project(
+ PROJ obsdeps
+ PREFIX "autodeps"
+ URL "${OBSDEPS_DOWNLOAD_URL}"
+ DOWNLOAD_NO_PROGRESS OFF
+ UPDATE_DISCONNECTED OFF
+ )
+ else()
+ download_project(
+ PROJ obsdeps
+ PREFIX "autodeps"
+ URL "${OBSDEPS_DOWNLOAD_URL}"
+ URL_HASH "SHA256=${OBSDEPS_DOWNLOAD_HASH}"
+ DOWNLOAD_NO_PROGRESS OFF
+ UPDATE_DISCONNECTED OFF
+ )
+ endif()
+ CacheSet(${PREFIX}OBSDEPS_PATH "${obsdeps_SOURCE_DIR}")
+ endif()
+
if (D_PLATFORM_WINDOWS)
- set(_OBSDEPS_PATH "${obsdeps_SOURCE_DIR}/win${D_PLATFORM_BITS}")
+ set(_OBSDEPS_PATH "${${PREFIX}OBSDEPS_PATH}/win${D_PLATFORM_BITS}")
+ set(FFmpegPath "${${PREFIX}OBSDEPS_PATH}/win${D_PLATFORM_BITS}")
elseif(D_PLATFORM_MAC)
- set(_OBSDEPS_PATH "${obsdeps_SOURCE_DIR}/obsdeps")
+ set(_OBSDEPS_PATH "${${PREFIX}OBSDEPS_PATH}/obsdeps")
+ set(FFmpegPath "${${PREFIX}OBSDEPS_PATH}/obsdeps")
endif()
endif()
################################################################################
-# Standalone Build: Qt v5.x
+# Auto-Dependency: Qt v5.x
################################################################################
if(STANDALONE AND NOT D_PLATFORM_LINUX)
- set(${PREFIX}DOWNLOAD_QT OFF CACHE BOOL "Download Qt?")
-
- if(${PREFIX}DOWNLOAD_QT)
- set(${PREFIX}DOWNLOAD_QT_URL "" CACHE STRING "")
- set(${PREFIX}DOWNLOAD_QT_HASH "" CACHE STRING "")
- mark_as_advanced(
- ${PREFIX}DOWNLOAD_QT_URL
- ${PREFIX}DOWNLOAD_QT_HASH
- )
+ # Options
+ set(${PREFIX}QT_DOWNLOAD TRUE CACHE BOOL "Automatically download Qt?")
+ set(${PREFIX}QT_PATH "" CACHE PATH "Path to Qt, if ${PREFIX}QT_DOWNLOAD is not set.")
+ set(${PREFIX}QT_DOWNLOAD_URL "" CACHE STRING "The URL from which to download Qt, if autodetection fails. (Optional)")
+ set(${PREFIX}QT_DOWNLOAD_HASH "" CACHE STRING "The hash string for the given URL. Must be a SHA-256 hash if provided. (Optional)")
+ mark_as_advanced(
+ ${PREFIX}QT_PATH
+ ${PREFIX}QT_DOWNLOAD_URL
+ ${PREFIX}QT_DOWNLOAD_HASH
+ )
- # Allow overriding what version we build against.
- if(${PREFIX}DOWNLOAD_QT_URL)
- set(_DOWNLOAD_QT_URL "${${PREFIX}DOWNLOAD_QT_URL}")
- set(_DOWNLOAD_QT_HASH "${${PREFIX}DOWNLOAD_QT_HASH}")
- else()
+ if(${PREFIX}QT_DOWNLOAD)
+ if(${PREFIX}QT_DOWNLOAD_URL STREQUAL "")
+ # Figure out download URLs and hashes.
if (D_PLATFORM_WINDOWS)
+ set(DEPS_VERSION "5.15.2")
if (D_PLATFORM_ARCH_X86)
if (D_PLATFORM_BITS EQUAL 64)
- set(_DOWNLOAD_QT_URL "https://github.com/Xaymar/obs-studio/releases/download/27.0.0/qt-5.15.2-windows-x86-64.7z")
- set(_DOWNLOAD_QT_HASH "SHA256=109B9C21EF165B0C46DFAA9AD23124F2070ED4D74207C4AFB308183CB8D43BDD")
- elseif (D_PLATFORM_BITS EQUAL 32)
- set(_DOWNLOAD_QT_URL "https://github.com/Xaymar/obs-studio/releases/download/27.0.0/qt-5.15.2-windows-x86-32.7z")
- set(_DOWNLOAD_QT_HASH "SHA256=372E4FBF2A15DD4FDA955A07334D8B8AC6802990148C9CB4E766C90205F8F570")
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
+ set(QT_DOWNLOAD_URL "https://cdn-fastly.obsproject.com/downloads/Qt_${DEPS_VERSION}.7z")
+ set(QT_DOWNLOAD_HASH "9EF1DFEEBE6AB7FFC55FD285667CC5D9CB2D298646C107C2295D13F14708E64E")
endif()
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
endif()
elseif(D_PLATFORM_MAC)
- if (D_PLATFORM_ARCH_X86)
+ set(DEPS_VERSION "2022-02-13")
+ if (D_PLATFORM_ARCH_X86 AND D_PLATFORM_ARCH_ARM)
+ if (D_PLATFORM_BITS EQUAL 64)
+ set(QT_DOWNLOAD_URL "https://github.com/obsproject/obs-deps/releases/download/${DEPS_VERSION}/macos-deps-qt-${DEPS_VERSION}-universal.tar.xz")
+ set(QT_DOWNLOAD_HASH "13FBCC45FD9D08B30E702D481FE4D58B23F93AA06848CEDE4EBE0956C79A5E8A")
+ endif()
+ elseif (D_PLATFORM_ARCH_X86)
if (D_PLATFORM_BITS EQUAL 64)
- set(_DOWNLOAD_QT_URL "https://github.com/Xaymar/obs-studio/releases/download/27.0.0/qt-5.15.2-macos-x86_64-2021-03-25.tar.gz")
- set(_DOWNLOAD_QT_HASH "SHA256=FFABB54624B931EA3FCC06BED244895F50CEFC95DE09D792D280C46D4F91D4C5")
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
+ set(QT_DOWNLOAD_URL "https://github.com/obsproject/obs-deps/releases/download/${DEPS_VERSION}/macos-deps-qt-${DEPS_VERSION}-x86_64.tar.xz")
+ set(QT_DOWNLOAD_HASH "35A58FEE8DFD70D3D2DCC0AE0B77132C04A451C6F041A02DC41B207B375FC74B")
endif()
- elseif(D_PLATFORM_ARCH_ARM)
+ elseif (D_PLATFORM_ARCH_ARM)
if (D_PLATFORM_BITS EQUAL 64)
- set(_DOWNLOAD_QT_URL "https://github.com/Xaymar/obs-studio/releases/download/27.0.0/qt-5.15.2-macos-arm64-2021-03-25.tar.gz")
- set(_DOWNLOAD_QT_HASH "SHA256=366BA8AC0FA0CAC440AFB9ED1C2EF5932E50091DC43BDE8B5C4B490082B6F19F")
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
+ set(QT_DOWNLOAD_URL "https://github.com/obsproject/obs-deps/releases/download/${DEPS_VERSION}/macos-deps-qt-${DEPS_VERSION}-arm64.tar.xz")
+ set(QT_DOWNLOAD_HASH "E99146B9C7775C245A2D22F2EF24FC111FCCD71BAD0F03B64DB707124FFB8707")
endif()
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
- return()
endif()
- else()
- message(FATAL_ERROR "${LOGPREFIX} Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
+ endif()
+
+ # Verify that the platform, architecture and bitness is supported.
+ if(QT_DOWNLOAD_URL STREQUAL "")
+ message(FATAL_ERROR "${LOGPREFIX} Download for Qt failed, as Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
return()
endif()
+ else()
+ set(QT_DOWNLOAD_URL "${${PREFIX}QT_DOWNLOAD_URL}")
+ set(QT_DOWNLOAD_HASH "${${PREFIX}QT_DOWNLOAD_HASH}")
endif()
- download_project(
- PROJ qt
- URL "${_DOWNLOAD_QT_URL}"
- URL_HASH "${_DOWNLOAD_QT_HASH}"
- DOWNLOAD_NO_PROGRESS OFF
- UPDATE_DISCONNECTED OFF
- )
+ if(QT_DOWNLOAD_HASH STREQUAL "")
+ download_project(
+ PROJ qt
+ PREFIX "autodeps"
+ URL "${QT_DOWNLOAD_URL}"
+ DOWNLOAD_NO_PROGRESS OFF
+ UPDATE_DISCONNECTED OFF
+ )
+ else()
+ download_project(
+ PROJ qt
+ PREFIX "autodeps"
+ URL "${QT_DOWNLOAD_URL}"
+ URL_HASH "SHA256=${QT_DOWNLOAD_HASH}"
+ DOWNLOAD_NO_PROGRESS OFF
+ UPDATE_DISCONNECTED OFF
+ )
+ endif()
+ execute_process(COMMAND "xattr" "-r" "-d" "com.apple.quarantine" "${qt_SOURCE_DIR}")
- set(Qt5_DIR "${qt_SOURCE_DIR}" CACHE STRING "Path to Qt5")
- if (D_PLATFORM_WINDOWS)
- if (D_PLATFORM_ARCH_X86)
- if (D_PLATFORM_BITS EQUAL 64)
- CacheSet(Qt5_DIR "${qt_SOURCE_DIR}/lib/cmake/Qt5")
- elseif (D_PLATFORM_BITS EQUAL 32)
- CacheSet(Qt5_DIR "${qt_SOURCE_DIR}/lib/cmake/Qt5")
+ if(D_PLATFORM_WINDOWS)
+ CacheSet(${PREFIX}QT_PATH "${qt_SOURCE_DIR}/msvc2019_64")
+ else()
+ CacheSet(${PREFIX}QT_PATH "${qt_SOURCE_DIR}")
+ endif()
+ endif()
+
+ set(Qt5_DIR "${${PREFIX}QT_PATH}/lib/cmake/Qt5" CACHE STRING "Path to Qt")
+ CacheSet(Qt5_DIR "${${PREFIX}QT_PATH}/lib/cmake/Qt5")
+endif()
+
+################################################################################
+# Auto-Dependency: libAOM
+################################################################################
+
+if(D_PLATFORM_WINDOWS)
+ # Options
+ set(${PREFIX}AOM_DOWNLOAD TRUE CACHE BOOL "Automatically download AOM?")
+ set(${PREFIX}AOM_PATH "" CACHE PATH "Path to AOM, if ${PREFIX}AOM_DOWNLOAD is not set.")
+ set(${PREFIX}AOM_DOWNLOAD_URL "" CACHE STRING "The URL from which to download AOM, if autodetection fails. (Optional)")
+ set(${PREFIX}AOM_DOWNLOAD_HASH "" CACHE STRING "The hash string for the given URL. Must be a SHA-256 hash if provided. (Optional)")
+ mark_as_advanced(
+ ${PREFIX}AOM_PATH
+ ${PREFIX}AOM_DOWNLOAD_URL
+ ${PREFIX}AOM_DOWNLOAD_HASH
+ )
+
+ if(${PREFIX}AOM_DOWNLOAD)
+ if(${PREFIX}AOM_DOWNLOAD_URL STREQUAL "")
+ set(AOM_VERSION "v3.2.0.1")
+ # Figure out download URLs and hashes.
+ if (D_PLATFORM_WINDOWS)
+ if (D_PLATFORM_ARCH_X86)
+ set(AOM_DOWNLOAD_URL "https://github.com/Xaymar/aom/releases/download/${AOM_VERSION}/aom-windows-${D_PLATFORM_BITS}-shared.7z")
+ set(AOM_DOWNLOAD_HASH "2DE0C215C5B00D6761AD2D1FEAFB545C04249B2CBD542F9F7D423E1A26BA59BD")
endif()
endif()
- elseif(D_PLATFORM_MAC)
- CacheSet(Qt5_DIR "${qt_SOURCE_DIR}/lib/cmake/Qt5")
+
+ # Verify that the platform, architecture and bitness is supported.
+ if(AOM_DOWNLOAD_URL STREQUAL "")
+ message(FATAL_ERROR "${LOGPREFIX} Download for AOM failed, as Platform '${D_PLATFORM_OS}' with architecture '${D_PLATFORM_ARCH}' and bitness '${D_PLATFORM_BITS}' is not supported.")
+ return()
+ endif()
+ else()
+ set(AOM_DOWNLOAD_URL "${${PREFIX}AOM_DOWNLOAD_URL}")
+ set(AOM_DOWNLOAD_HASH "${${PREFIX}AOM_DOWNLOAD_HASH}")
+ endif()
+
+ if(AOM_DOWNLOAD_HASH STREQUAL "")
+ download_project(
+ PROJ AOM
+ PREFIX "autodeps"
+ URL "${AOM_DOWNLOAD_URL}"
+ DOWNLOAD_NO_PROGRESS OFF
+ UPDATE_DISCONNECTED OFF
+ )
+ else()
+ download_project(
+ PROJ AOM
+ PREFIX "autodeps"
+ URL "${AOM_DOWNLOAD_URL}"
+ URL_HASH "SHA256=${AOM_DOWNLOAD_HASH}"
+ DOWNLOAD_NO_PROGRESS OFF
+ UPDATE_DISCONNECTED OFF
+ )
+ endif()
+
+ if(D_PLATFORM_WINDOWS)
+ CacheSet(${PREFIX}AOM_PATH "${AOM_SOURCE_DIR}/msvc2019_64")
+ else()
+ CacheSet(${PREFIX}AOM_PATH "${AOM_SOURCE_DIR}")
endif()
endif()
+
+ set(AOM_PATH "${${PREFIX}AOM_PATH}" CACHE STRING "Path to AOM")
endif()
################################################################################
@@ -647,20 +732,20 @@ function(feature_encoder_ffmpeg RESOLVE)
is_feature_enabled(ENCODER_FFMPEG T_CHECK)
if(RESOLVE AND T_CHECK)
if(NOT HAVE_FFMPEG)
- message(WARNING "${LOGPREFIX}: FFmpeg Encoder requires FFmpeg. Disabling...")
+ message(WARNING "${LOGPREFIX} FFmpeg Encoder requires FFmpeg. Disabling...")
set_feature_disabled(ENCODER_FFMPEG ON)
else()
# AMF
is_feature_enabled(ENCODER_FFMPEG_AMF T_CHECK)
if(T_CHECK AND D_PLATFORM_MAC)
- message(WARNING "${LOGPREFIX}: FFmpeg Encoder 'AMF' requires Windows or Linux. Disabling...")
+ message(WARNING "${LOGPREFIX} FFmpeg Encoder 'AMF' requires Windows or Linux. Disabling...")
set_feature_disabled(ENCODER_FFMPEG_AMF ON)
endif()
# NVENC
is_feature_enabled(ENCODER_FFMPEG_NVENC T_CHECK)
if(T_CHECK AND D_PLATFORM_MAC)
- message(WARNING "${LOGPREFIX}: FFmpeg Encoder 'NVENC' requires Windows or Linux. Disabling...")
+ message(WARNING "${LOGPREFIX} FFmpeg Encoder 'NVENC' requires Windows or Linux. Disabling...")
set_feature_disabled(ENCODER_FFMPEG_NVENC ON)
endif()
@@ -679,7 +764,7 @@ function(feature_encoder_aom_av1 RESOLVE)
is_feature_enabled(ENCODER_AOM_AV1 T_CHECK)
if(RESOLVE AND T_CHECK)
if(NOT HAVE_AOM)
- message(WARNING "${LOGPREFIX}: AOM AV1 encoder missing AOM library. Disabling...")
+ message(WARNING "${LOGPREFIX} AOM AV1 encoder missing AOM library. Disabling...")
set_feature_disabled(ENCODER_AOM_AV1 ON)
endif()
elseif(T_CHECK)
@@ -692,14 +777,14 @@ function(feature_filter_autoframing RESOLVE)
if(RESOLVE AND T_CHECK)
# Verify that the requirements for the providers are available
if(NOT HAVE_NVIDIA_AR_SDK)
- message(WARNING "${LOGPREFIX}: 'NVIDIA Augmented Reality SDK' is missing. Disabling NVIDIA provider...")
+ message(WARNING "${LOGPREFIX} 'NVIDIA Augmented Reality SDK' is missing. Disabling NVIDIA provider...")
set_feature_disabled(FILTER_AUTOFRAMING_NVIDIA ON)
endif()
# Verify that we have at least one provider for Auto-Framing.
is_feature_enabled(FILTER_AUTOFRAMING_NVIDIA T_CHECK_NVIDIA)
if (NOT T_CHECK_NVIDIA)
- message(WARNING "${LOGPREFIX}: Auto-Framing has no available providers. Disabling...")
+ message(WARNING "${LOGPREFIX} Auto-Framing has no available providers. Disabling...")
set_feature_disabled(FILTER_AUTOFRAMING ON)
endif()
elseif(T_CHECK)
@@ -721,14 +806,14 @@ function(feature_filter_denoising RESOLVE)
if(RESOLVE AND T_CHECK)
# Verify that the requirements for the providers are available
if(NOT HAVE_NVIDIA_VFX_SDK)
- message(WARNING "${LOGPREFIX}: 'NVIDIA Video Effects SDK' is missing. Disabling NVIDIA provider...")
+ message(WARNING "${LOGPREFIX} 'NVIDIA Video Effects SDK' is missing. Disabling NVIDIA provider...")
set_feature_disabled(FILTER_DENOISING_NVIDIA ON)
endif()
# Verify that we have at least one provider for Video Denoising.
is_feature_enabled(FILTER_DENOISING_NVIDIA T_CHECK_NVIDIA)
if (NOT T_CHECK_NVIDIA)
- message(WARNING "${LOGPREFIX}: Denoising has no available providers. Disabling...")
+ message(WARNING "${LOGPREFIX} Denoising has no available providers. Disabling...")
set_feature_disabled(FILTER_DENOISING ON)
endif()
elseif(T_CHECK)
@@ -761,14 +846,14 @@ function(feature_filter_upscaling RESOLVE)
if(RESOLVE AND T_CHECK)
# Verify that the requirements for the providers are available
if(NOT HAVE_NVIDIA_VFX_SDK)
- message(WARNING "${LOGPREFIX}: 'NVIDIA Video Effects SDK' is missing. Disabling NVIDIA provider(s)...")
+ message(WARNING "${LOGPREFIX} 'NVIDIA Video Effects SDK' is missing. Disabling NVIDIA provider(s)...")
set_feature_disabled(FILTER_UPSCALING_NVIDIA ON)
endif()
# Verify that we have at least one provider for Video Super-Resolution.
is_feature_enabled(FILTER_UPSCALING_NVIDIA T_CHECK_NVIDIA)
if (NOT T_CHECK_NVIDIA)
- message(WARNING "${LOGPREFIX}: Upscaling has no available providers. Disabling...")
+ message(WARNING "${LOGPREFIX} Upscaling has no available providers. Disabling...")
set_feature_disabled(FILTER_UPSCALING ON)
endif()
elseif(T_CHECK)
@@ -781,14 +866,14 @@ function(feature_filter_virtual_greenscreen RESOLVE)
if(RESOLVE AND T_CHECK)
# Verify that the requirements for the providers are available
if(NOT HAVE_NVIDIA_VFX_SDK)
- message(WARNING "${LOGPREFIX}: 'NVIDIA Video Effects SDK' is missing. Disabling NVIDIA provider(s)...")
+ message(WARNING "${LOGPREFIX} 'NVIDIA Video Effects SDK' is missing. Disabling NVIDIA provider(s)...")
set_feature_disabled(FILTER_VIRTUAL_GREENSCREEN_NVIDIA ON)
endif()
# Verify that we have at least one provider for Video Super-Resolution.
is_feature_enabled(FILTER_VIRTUAL_GREENSCREEN_NVIDIA T_CHECK_NVIDIA)
if (NOT T_CHECK_NVIDIA)
- message(WARNING "${LOGPREFIX}: Virtual Greenscreen has no available providers. Disabling...")
+ message(WARNING "${LOGPREFIX} Virtual Greenscreen has no available providers. Disabling...")
set_feature_disabled(FILTER_VIRTUAL_GREENSCREEN ON)
endif()
elseif(T_CHECK)
@@ -812,10 +897,10 @@ function(feature_frontend RESOLVE)
is_feature_enabled(FRONTEND T_CHECK)
if(RESOLVE AND T_CHECK)
if(NOT HAVE_QT)
- message(WARNING "${LOGPREFIX}: Front-End requires Qt. Disabling...")
+ message(WARNING "${LOGPREFIX} Front-End requires Qt. Disabling...")
set_feature_disabled(FRONTEND ON)
elseif(NOT HAVE_OBSFE)
- message(WARNING "${LOGPREFIX}: Front-End requires OBS FrontEnd API. Disabling...")
+ message(WARNING "${LOGPREFIX} Front-End requires OBS FrontEnd API. Disabling...")
set_feature_disabled(FRONTEND ON)
endif()
elseif(T_CHECK)
@@ -828,10 +913,10 @@ function(feature_updater RESOLVE)
is_feature_enabled(UPDATER T_CHECK)
if(RESOLVE AND T_CHECK)
if(NOT HAVE_CURL)
- message(WARNING "${LOGPREFIX}: Updater requires CURL. Disabling...")
+ message(WARNING "${LOGPREFIX} Updater requires CURL. Disabling...")
set_feature_disabled(UPDATER ON)
elseif(NOT HAVE_JSON)
- message(WARNING "${LOGPREFIX}: Updater requires nlohmann::json. Disabling...")
+ message(WARNING "${LOGPREFIX} Updater requires nlohmann::json. Disabling...")
set_feature_disabled(UPDATER ON)
endif()
elseif(T_CHECK)
@@ -886,33 +971,6 @@ endif()
#- FFmpeg
set(HAVE_FFMPEG OFF)
if(REQUIRE_FFMPEG)
- if(D_PLATFORM_WINDOWS AND NOT ${PREFIX}OBS_NATIVE)
- find_path(
- FFmpegPath "libavcodec/avcodec.h"
- HINTS
- ${OBS_DEPENDENCIES_DIR}
- ${_OBSDEPS_PATH}
- ${DepsPath}
- ${DepsPath32}
- ${DepsPath64}
-
- PATHS
- /usr/include
- /usr/local/include
- /opt/local/include
- /sw/include
- PATH_SUFFIXES
- win${D_PLATFORM_BITS}
- win${D_PLATFORM_BITS}/bin
- win${D_PLATFORM_BITS}/include
- win${D_PLATFORM_INSTR}
- win${D_PLATFORM_INSTR}/bin
- win${D_PLATFORM_INSTR}/include
- bin
- include
- )
- endif()
-
find_package(FFmpeg COMPONENTS avutil avcodec swscale)
set(HAVE_FFMPEG ${FFmpeg_FOUND})
endif()
@@ -983,15 +1041,8 @@ endif()
#- OBS Front-End API
set(HAVE_OBSFE OFF)
if(REQUIRE_OBSFE)
- if(${PREFIX}OBS_NATIVE)
- if(TARGET obs-frontend-api)
- set(HAVE_OBSFE ON)
- endif()
- else()
- if (EXISTS "${libobs_SOURCE_DIR}/cmake/obs-frontend-api/obs-frontend-apiConfig.cmake")
- include("${libobs_SOURCE_DIR}/cmake/obs-frontend-api/obs-frontend-apiConfig.cmake")
- set(HAVE_OBSFE ON)
- endif()
+ if(TARGET obs-frontend-api)
+ set(HAVE_OBSFE ON)
endif()
endif()
@@ -1857,6 +1908,55 @@ set_target_properties(${PROJECT_NAME} PROPERTIES
CXX_EXTENSIONS OFF
)
+# C/C++ Compiler Adjustments
+if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
+ # MSVC/ClangCL
+ # - Dynamically link Microsoft C/C++ Redistributable.
+ # - Enable /W3 and disable useless warnings.
+ # - Enable C++ exceptions with SEH exceptions.
+ # - Enable multi-processor compiling.
+ # - Enable updated __cplusplus macro
+ message(STATUS "${LOGPREFIX} Applying custom flags for MSVC style build.")
+
+ # Build with dynamic MSVC linkage.
+ target_compile_options(${PROJECT_NAME} PUBLIC
+ $<$:/MD>
+ $<$:/MDd>
+ $<$:/MD>
+ $<$:/MD>
+ $<$:/MD>
+ )
+
+ # Enable most useful warnings.
+ set(DISABLED_WARNINGS
+ "/wd4061" "/wd4100" "/wd4180" "/wd4201" "/wd4464" "/wd4505" "/wd4514"
+ "/wd4571" "/wd4623" "/wd4625" "/wd4626" "/wd4668" "/wd4710" "/wd4774"
+ "/wd4820" "/wd5026" "/wd5027" "/wd5039" "/wd5045" "/wd26812"
+ )
+ target_compile_options(${PROJECT_NAME} PUBLIC "/W3")
+ foreach(WARN ${DISABLED_WARNINGS})
+ target_compile_options(${PROJECT_NAME} PUBLIC "${WARN}")
+ endforeach()
+
+ # C++ Exceptions & SEH
+ target_compile_options(${PROJECT_NAME} PUBLIC "/EHa")
+
+ # Multiprocessor compiling
+ target_compile_options(${PROJECT_NAME} PUBLIC "/MP")
+
+ # Updated __cplusplus
+ target_compile_options(${PROJECT_NAME} PUBLIC "/Zc:__cplusplus")
+elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ # Clang/AppleClang/GNU
+ # - Don't export by default. (Temporarily disabled)
+ # - Enable all and extra warnings.
+ message(STATUS "${LOGPREFIX} Applying custom flags for GNU style build.")
+
+ target_compile_options(${PROJECT_NAME} PUBLIC "-Wall")
+ target_compile_options(${PROJECT_NAME} PUBLIC "-Wextra")
+ # add_compile_options("-fvisibility=hidden")
+endif()
+
# Remove prefix on other platforms.
set_target_properties(${PROJECT_NAME} PROPERTIES
PREFIX ""
diff --git a/cmake/modules/Architecture.cmake b/cmake/modules/Architecture.cmake
deleted file mode 100644
index 0383d81a02..0000000000
--- a/cmake/modules/Architecture.cmake
+++ /dev/null
@@ -1,41 +0,0 @@
-# Setup
-set(ARCH_INSTR_32 "i386;i686;x86;arm;ARM")
-set(ARCH_INSTR_64 "x86_64;AMD64;IA64;arm64;ARM64")
-set(ARCH_INSTR_X86 "i386;i686;x86;x86_64;AMD64")
-set(ARCH_INSTR_ARM "arm;ARM;arm64;ARM64")
-set(ARCH_INSTR_ITANIUM "IA64")
-set(ARCH_BITS 0)
-set(ARCH_BITS_POINTER 0)
-set(ARCH_INST "")
-
-# Bitness
-list(FIND ARCH_INSTR_32 "${CMAKE_SYSTEM_PROCESSOR}" FOUND)
-if(FOUND GREATER -1)
- set(ARCH_BITS 32)
-endif()
-
-list(FIND ARCH_INSTR_64 "${CMAKE_SYSTEM_PROCESSOR}" FOUND)
-if(FOUND GREATER -1)
- set(ARCH_BITS 64)
-endif()
-
-# Pointer Size (bits)
-math(EXPR ARCH_BITS_POINTER "8*${CMAKE_SIZEOF_VOID_P}")
-
-# Basic Instruction Set
-list(FIND ARCH_INSTR_X86 "${CMAKE_SYSTEM_PROCESSOR}" FOUND)
-if(FOUND GREATER -1)
- set(ARCH_INST "x86")
-endif()
-
-list(FIND ARCH_INSTR_ARM "${CMAKE_SYSTEM_PROCESSOR}" FOUND)
-if(FOUND GREATER -1)
- set(ARCH_INST "ARM")
-endif()
-
-list(FIND ARCH_INSTR_ITANIUM "${CMAKE_SYSTEM_PROCESSOR}" FOUND)
-if(FOUND GREATER -1)
- set(ARCH_INST "Itanium")
-endif()
-
-message(STATUS "Targetting ${ARCH_INST} with ${ARCH_BITS}bits and a pointer size of ${ARCH_BITS_POINTER}bit.")
From 98e2447ec8e607eb5e5c505817a770b74914dd59 Mon Sep 17 00:00:00 2001
From: Michael Fabian 'Xaymar' Dirks
Date: Thu, 26 May 2022 02:58:26 +0200
Subject: [PATCH 013/164] common: Add macro to force inlining
---
source/common.hpp | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/source/common.hpp b/source/common.hpp
index 2ab5ec6a72..3942405cd6 100644
--- a/source/common.hpp
+++ b/source/common.hpp
@@ -109,3 +109,13 @@ extern "C" {
#define __FUNCTION_SIG__ __func__
#define __FUNCTION_NAME__ __func__
#endif
+/// Forceful inlining
+#ifndef FORCE_INLINE
+#ifdef _MSC_VER
+#define FORCE_INLINE __force_inline
+#elif defined(__GNUC__) || defined(__MINGW32__)
+#define FORCE_INLINE __attribute__((always_inline))
+#else
+#define FORCE_INLINE inline
+#endif
+#endif
From 06276288845cf498adcac5da604388e424055495 Mon Sep 17 00:00:00 2001
From: Michael Fabian 'Xaymar' Dirks
Date: Tue, 10 May 2022 18:40:47 +0200
Subject: [PATCH 014/164] obs/tools: Remove work-around for
obs_properties_remove_by_name
The bug fix to this was applied upstream, so we no longer need to support the broken behavior
---
source/gfx/shader/gfx-shader.cpp | 4 +-
source/obs/obs-tools.cpp | 88 --------------------------------
source/obs/obs-tools.hpp | 2 -
3 files changed, 2 insertions(+), 92 deletions(-)
diff --git a/source/gfx/shader/gfx-shader.cpp b/source/gfx/shader/gfx-shader.cpp
index 2447f91c30..eb079149bd 100644
--- a/source/gfx/shader/gfx-shader.cpp
+++ b/source/gfx/shader/gfx-shader.cpp
@@ -261,7 +261,7 @@ bool streamfx::gfx::shader::shader::on_refresh_properties(obs_properties_t* prop
{ // Clear parameter options.
auto grp = obs_property_group_content(obs_properties_get(props, ST_KEY_PARAMETERS));
for (auto p = obs_properties_first(grp); p != nullptr; p = obs_properties_first(grp)) {
- streamfx::obs::tools::obs_properties_remove_by_name(grp, obs_property_name(p));
+ obs_properties_remove_by_name(grp, obs_property_name(p));
}
// Rebuild new parameters.
@@ -302,7 +302,7 @@ bool streamfx::gfx::shader::shader::on_shader_or_technique_modified(obs_properti
// Clear parameter options.
auto grp = obs_property_group_content(obs_properties_get(props, ST_KEY_PARAMETERS));
for (auto p = obs_properties_first(grp); p != nullptr; p = obs_properties_first(grp)) {
- streamfx::obs::tools::obs_properties_remove_by_name(grp, obs_property_name(p));
+ obs_properties_remove_by_name(grp, obs_property_name(p));
}
// Rebuild new parameters.
diff --git a/source/obs/obs-tools.cpp b/source/obs/obs-tools.cpp
index 0b4ff37df3..11ae4a2de9 100644
--- a/source/obs/obs-tools.cpp
+++ b/source/obs/obs-tools.cpp
@@ -82,94 +82,6 @@ bool streamfx::obs::tools::scene_contains_source(obs_scene_t* scene, obs_source_
return sd.found;
}
-extern "C" {
-struct _hack_obs_properties;
-
-struct _hack_obs_property {
- char* name;
- char* desc;
- char* long_desc;
- void* priv;
- enum obs_property_type type;
- bool visible;
- bool enabled;
-
- struct _hack_obs_properties* parent;
-
- obs_property_modified_t modified;
- obs_property_modified2_t modified2;
-
- struct _hack_obs_property* next;
-};
-
-struct _hack_obs_properties {
- void* param;
- void (*destroy)(void* param);
- uint32_t flags;
-
- struct _hack_obs_property* first_property;
- struct _hack_obs_property** last;
- struct _hack_obs_property* parent;
-};
-}
-
-bool streamfx::obs::tools::obs_properties_remove_by_name(obs_properties_t* props, const char* name)
-{
- // Due to a bug in obs_properties_remove_by_name, calling it on the first or last element of a group corrupts the
- // obs_properties_t's first and last pointers, which now point at nonsense.
- //
- // There are two ways to work around this issue for now:
- // 1. Add some invisible properties to the beginning and end of the list, ensuring that you never hit the first or
- // last element with a obs_properties_remove_by_name.
- // 2. Manually adjust the pointers using a dirty hack like in gs::mipmapper.
- // I've opted for the 2nd way, at it is way simpler to implement.
-
- // Assume that this is fixed in libobs 24.0.7 or newer.
- if (obs_get_version() >= MAKE_SEMANTIC_VERSION(24, 0, 7)) {
- ::obs_properties_remove_by_name(props, name);
- return true;
- }
-
- auto rprops = reinterpret_cast<_hack_obs_properties*>(props);
-
- for (_hack_obs_property *el_prev = rprops->first_property, *el_cur = el_prev; el_cur != nullptr;
- el_prev = el_cur, el_cur = el_cur->next) {
- if (strcmp(el_cur->name, name) == 0) {
- // Store some information.
- _hack_obs_property* next = el_cur->next;
- bool is_first = (rprops->first_property == el_cur);
- bool is_last = (rprops->last == &el_cur->next);
- bool is_solo = (el_cur == el_prev);
-
- // Call the real one which fixes the element pointer and deallocates the element.
- ::obs_properties_remove_by_name(props, name);
-
- // Fix up the memory pointers after the element was deleted.
- if (is_last) {
- if (is_solo) {
- rprops->last = &rprops->first_property;
- } else {
- rprops->last = &el_prev->next;
- }
- }
- if (is_first) {
- rprops->first_property = next;
- }
-
- // Finally break out as we no longer have to process the properties list.
- return true;
- }
-
- if (el_cur->type == OBS_PROPERTY_GROUP) {
- if (streamfx::obs::tools::obs_properties_remove_by_name(
- obs_property_group_content(reinterpret_cast(el_cur)), name))
- return true;
- }
- }
-
- return false;
-}
-
streamfx::obs::tools::child_source::child_source(obs_source_t* parent, std::shared_ptr child)
: _parent(parent), _child(child)
{
diff --git a/source/obs/obs-tools.hpp b/source/obs/obs-tools.hpp
index 739176171d..f1aba6bd3d 100644
--- a/source/obs/obs-tools.hpp
+++ b/source/obs/obs-tools.hpp
@@ -24,8 +24,6 @@ namespace streamfx::obs {
namespace tools {
bool scene_contains_source(obs_scene_t* scene, obs_source_t* source);
- bool obs_properties_remove_by_name(obs_properties_t* props, const char* name);
-
class child_source {
obs_source_t* _parent;
std::shared_ptr _child;
From 6dd661a41c251450d78bff190bb5c866d8a7f5cf Mon Sep 17 00:00:00 2001
From: Michael Fabian 'Xaymar' Dirks
Date: Tue, 10 May 2022 22:52:35 +0200
Subject: [PATCH 015/164] obs/source-tracker: Fix missing sources and modernize
singleton design
In some rare cases, a bug is observed where some sources end up missing despite being visible in the OBS Studio UI. This is most likely related to us actually missing the events due to plugin load order. We can fix this by explicitly enumerating sources in the constructor.
Additionally in order to reduce the human error factor, we should avoid explicit initialize() and finalize() calls for our singleton. Instead the get() function should do all of the heavy lifting, including thread safety, so that the human writing the code will have next to no chances to break it.
---
source/obs/obs-source-tracker.cpp | 219 +++++++++++++++++++-----------
source/obs/obs-source-tracker.hpp | 23 ++--
source/plugin.cpp | 5 +-
3 files changed, 154 insertions(+), 93 deletions(-)
diff --git a/source/obs/obs-source-tracker.cpp b/source/obs/obs-source-tracker.cpp
index 6236cc617a..aba02a92d5 100644
--- a/source/obs/obs-source-tracker.cpp
+++ b/source/obs/obs-source-tracker.cpp
@@ -18,127 +18,167 @@
*/
#include "obs-source-tracker.hpp"
+#include
#include
#include "obs/obs-tools.hpp"
-#include "plugin.hpp"
-
-static std::shared_ptr source_tracker_instance;
+#include "util/util-logging.hpp"
+
+#ifdef _DEBUG
+#define ST_PREFIX "<%s> "
+#define D_LOG_ERROR(x, ...) P_LOG_ERROR(ST_PREFIX##x, __FUNCTION_SIG__, __VA_ARGS__)
+#define D_LOG_WARNING(x, ...) P_LOG_WARN(ST_PREFIX##x, __FUNCTION_SIG__, __VA_ARGS__)
+#define D_LOG_INFO(x, ...) P_LOG_INFO(ST_PREFIX##x, __FUNCTION_SIG__, __VA_ARGS__)
+#define D_LOG_DEBUG(x, ...) P_LOG_DEBUG(ST_PREFIX##x, __FUNCTION_SIG__, __VA_ARGS__)
+#else
+#define ST_PREFIX " "
+#define D_LOG_ERROR(...) P_LOG_ERROR(ST_PREFIX __VA_ARGS__)
+#define D_LOG_WARNING(...) P_LOG_WARN(ST_PREFIX __VA_ARGS__)
+#define D_LOG_INFO(...) P_LOG_INFO(ST_PREFIX __VA_ARGS__)
+#define D_LOG_DEBUG(...) P_LOG_DEBUG(ST_PREFIX __VA_ARGS__)
+#endif
void streamfx::obs::source_tracker::source_create_handler(void* ptr, calldata_t* data) noexcept
-try {
- streamfx::obs::source_tracker* self = reinterpret_cast(ptr);
+{
+ auto* self = reinterpret_cast(ptr);
+ try {
+ obs_source_t* source = nullptr;
+ if (calldata_get_ptr(data, "source", &source); !source) {
+ throw std::runtime_error("Missing 'source' parameter.");
+ }
- obs_source_t* target = nullptr;
- calldata_get_ptr(data, "source", &target);
+ self->insert_source(source);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Event 'source_create' caused exception: %s", ex.what());
+ } catch (...) {
+ DLOG_ERROR("Event 'source_create' caused unknown exception.", nullptr);
+ }
+}
- if (!target) {
- return;
+void streamfx::obs::source_tracker::source_destroy_handler(void* ptr, calldata_t* data) noexcept
+{
+ auto* self = reinterpret_cast(ptr);
+ try {
+ obs_source_t* source = nullptr;
+ if (calldata_get_ptr(data, "source", &source); !source) {
+ throw std::runtime_error("Missing 'source' parameter.");
+ }
+
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Event 'source_destroy' caused exception: %s", ex.what());
+ } catch (...) {
+ DLOG_ERROR("Event 'source_destroy' caused unknown exception.", nullptr);
+ }
+}
+
+void streamfx::obs::source_tracker::source_rename_handler(void* ptr, calldata_t* data) noexcept
+{
+ auto* self = reinterpret_cast(ptr);
+ try {
+ obs_source_t* source = nullptr;
+ if (calldata_get_ptr(data, "source", &source); !source) {
+ throw std::runtime_error("Missing 'source' parameter.");
+ }
+
+ const char* old_name = nullptr;
+ if (calldata_get_string(data, "prev_name", &old_name); !old_name) {
+ throw std::runtime_error("Missing 'prev_name' parameter.");
+ }
+
+ const char* new_name = nullptr;
+ if (calldata_get_string(data, "new_name", &new_name); !new_name) {
+ throw std::runtime_error("Missing 'new_name' parameter.");
+ }
+
+ self->rename_source(old_name, new_name, source);
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
+}
- const char* name = obs_source_get_name(target);
+void streamfx::obs::source_tracker::insert_source(obs_source_t* source)
+{
+ const auto* name = obs_source_get_name(source);
if (!name) { // Do not track unnamed sources.
return;
}
- obs_weak_source_t* weak = obs_source_get_weak_source(target);
+ std::shared_ptr weak{obs_source_get_weak_source(source), streamfx::obs::obs_weak_source_deleter};
if (!weak) { // This source has already been deleted, do not track.
return;
}
- {
- std::unique_lock ul(self->_lock);
- self->_sources.insert({std::string(name), {weak, streamfx::obs::obs_weak_source_deleter}});
- }
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ std::unique_lock lock(_mutex);
+ _sources.insert({
+ std::string(name),
+ weak,
+ });
}
-void streamfx::obs::source_tracker::source_destroy_handler(void* ptr, calldata_t* data) noexcept
-try {
- streamfx::obs::source_tracker* self = reinterpret_cast(ptr);
-
- obs_source_t* target = nullptr;
- calldata_get_ptr(data, "source", &target);
-
- if (!target) {
- return;
- }
+void streamfx::obs::source_tracker::remove_source(obs_source_t* source)
+{
+ const char* name = obs_source_get_name(source);
- const char* name = obs_source_get_name(target);
- if (!name) { // Not tracking unnamed sources.
- return;
- }
+ // Lock read & write access to the map.
+ std::unique_lock ul(_mutex);
- {
- std::unique_lock ul(self->_lock);
- auto found = self->_sources.find(std::string(name));
- if (found == self->_sources.end()) {
+ // Try and remove the source by name.
+ if (name != nullptr) {
+ auto found = _sources.find(std::string(name));
+ if (found != _sources.end()) {
+ _sources.erase(found);
return;
}
- self->_sources.erase(found);
- }
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::source_tracker::source_rename_handler(void* ptr, calldata_t* data) noexcept
-try {
- streamfx::obs::source_tracker* self = reinterpret_cast(ptr);
-
- obs_source_t* target = nullptr;
- const char* prev_name = nullptr;
- const char* new_name = nullptr;
- calldata_get_ptr(data, "source", &target);
- calldata_get_string(data, "prev_name", &prev_name);
- calldata_get_string(data, "new_name", &new_name);
-
- if (strcmp(prev_name, new_name) == 0) {
- // They weren't renamed at all, invalid event.
- return;
}
- {
- std::unique_lock ul(self->_lock);
- auto found = self->_sources.find(std::string(prev_name));
- if (found == self->_sources.end()) {
- // Untracked source, insert.
- obs_weak_source_t* weak = obs_source_get_weak_source(target);
- if (!weak) {
- return;
- }
- self->_sources.insert({new_name, {weak, streamfx::obs::obs_weak_source_deleter}});
+ // If that didn't work, try and remove it by handle.
+ for (auto iter = _sources.begin(); iter != _sources.end(); iter++) {
+ if (obs_weak_source_get_source(iter->second.get()) == source) {
+ _sources.erase(iter);
return;
}
+ }
- // Insert at new key, remove old pair.
- self->_sources.insert({new_name, found->second});
- self->_sources.erase(found);
+ // If that all failed, and the source is named, throw and report an error.
+ if (name) {
+ D_LOG_WARNING("Source '%s' was not tracked.", name);
+ throw std::runtime_error("Failed to find given source.");
}
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
-void streamfx::obs::source_tracker::initialize()
+void streamfx::obs::source_tracker::rename_source(std::string_view old_name, std::string_view new_name,
+ obs_source_t* source)
{
- source_tracker_instance = std::make_shared();
-}
+ if (old_name == new_name) {
+ throw std::runtime_error("New and old name are identical.");
+ }
-void streamfx::obs::source_tracker::finalize()
-{
- source_tracker_instance.reset();
-}
+ std::unique_lock ul(_mutex);
+ auto found = _sources.find(std::string(old_name));
+ if (found == _sources.end()) {
+ insert_source(source);
+ return;
+ }
-std::shared_ptr streamfx::obs::source_tracker::get()
-{
- return source_tracker_instance;
+ // Insert at new key, remove old pair.
+ _sources.insert({new_name.data(), found->second});
+ _sources.erase(found);
}
-streamfx::obs::source_tracker::source_tracker()
+streamfx::obs::source_tracker::source_tracker() : _sources(), _mutex()
{
auto osi = obs_get_signal_handler();
signal_handler_connect(osi, "source_create", &source_create_handler, this);
signal_handler_connect(osi, "source_destroy", &source_destroy_handler, this);
signal_handler_connect(osi, "source_rename", &source_rename_handler, this);
+
+ // Enumerate all current sources and filters.
+ obs_enum_all_sources(
+ [](void* param, obs_source_t* source) {
+ auto* self = reinterpret_cast<::streamfx::obs::source_tracker*>(param);
+ self->insert_source(source);
+ return true;
+ },
+ this);
}
streamfx::obs::source_tracker::~source_tracker()
@@ -158,7 +198,7 @@ void streamfx::obs::source_tracker::enumerate(enumerate_cb_t ecb, filter_cb_t fc
// Need func-local copy, otherwise we risk corruption if a new source is created or destroyed.
decltype(_sources) _clone;
{
- std::unique_lock ul(_lock);
+ std::unique_lock ul(_mutex);
_clone = _sources;
}
@@ -209,3 +249,18 @@ bool streamfx::obs::source_tracker::filter_scenes(std::string, obs_source_t* sou
{
return (obs_source_get_type(source) != OBS_SOURCE_TYPE_SCENE);
}
+
+std::shared_ptr streamfx::obs::source_tracker::get()
+{
+ static std::mutex inst_mtx;
+ static std::weak_ptr inst_weak;
+
+ std::unique_lock lock(inst_mtx);
+ if (inst_weak.expired()) {
+ auto instance = std::shared_ptr(new streamfx::obs::source_tracker());
+ inst_weak = instance;
+ return instance;
+ } else {
+ return inst_weak.lock();
+ }
+}
diff --git a/source/obs/obs-source-tracker.hpp b/source/obs/obs-source-tracker.hpp
index bff87c33ad..a8303a70f6 100644
--- a/source/obs/obs-source-tracker.hpp
+++ b/source/obs/obs-source-tracker.hpp
@@ -26,20 +26,16 @@
namespace streamfx::obs {
class source_tracker {
std::map> _sources;
- std::mutex _lock;
+ std::mutex _mutex;
static void source_create_handler(void* ptr, calldata_t* data) noexcept;
static void source_destroy_handler(void* ptr, calldata_t* data) noexcept;
static void source_rename_handler(void* ptr, calldata_t* data) noexcept;
- public: // Singleton
- static void initialize();
- static void finalize();
- static std::shared_ptr get();
-
- public:
- source_tracker();
- ~source_tracker();
+ protected:
+ void insert_source(obs_source_t* source);
+ void remove_source(obs_source_t* source);
+ void rename_source(std::string_view old_name, std::string_view new_name, obs_source_t* source);
public:
// Callback function for enumerating sources.
@@ -56,6 +52,12 @@ namespace streamfx::obs {
// @return true to skip, false to pass along.
typedef std::function filter_cb_t;
+ protected:
+ source_tracker();
+
+ public:
+ ~source_tracker();
+
//! Enumerate all tracked sources
//
// @param enumerate_cb The function called for each tracked source.
@@ -68,5 +70,8 @@ namespace streamfx::obs {
static bool filter_video_sources(std::string name, obs_source_t* source);
static bool filter_transitions(std::string name, obs_source_t* source);
static bool filter_scenes(std::string name, obs_source_t* source);
+
+ public: // Singleton
+ static std::shared_ptr get();
};
} // namespace streamfx::obs
diff --git a/source/plugin.cpp b/source/plugin.cpp
index 3882120bdc..3701394e63 100644
--- a/source/plugin.cpp
+++ b/source/plugin.cpp
@@ -94,6 +94,7 @@
static std::shared_ptr _threadpool;
static std::shared_ptr _gs_fstri_vb;
static std::shared_ptr _streamfx_gfx_opengl;
+static std::shared_ptr _source_tracker;
MODULE_EXPORT bool obs_module_load(void)
try {
@@ -106,7 +107,7 @@ try {
_threadpool = std::make_shared();
// Initialize Source Tracker
- streamfx::obs::source_tracker::initialize();
+ _source_tracker = streamfx::obs::source_tracker::get();
// Initialize GLAD (OpenGL)
{
@@ -310,7 +311,7 @@ try {
}
// Finalize Source Tracker
- streamfx::obs::source_tracker::finalize();
+ _source_tracker.reset();
// // Auto-Updater
//#ifdef ENABLE_UPDATER
From 9bbc35b29355999f33bf559876a4e8aeeb052674 Mon Sep 17 00:00:00 2001
From: Michael Fabian 'Xaymar' Dirks
Date: Sat, 14 May 2022 06:29:41 +0200
Subject: [PATCH 016/164] obs/source: Refactor old deprecated classes
---
CMakeLists.txt | 26 +-
source/obs/obs-source-active-child.cpp | 19 +
source/obs/obs-source-active-child.hpp | 49 ++
source/obs/obs-source-active-reference.cpp | 19 +
source/obs/obs-source-active-reference.hpp | 48 ++
source/obs/obs-source-info.cpp | 0
source/obs/obs-source-info.hpp | 0
source/obs/obs-source-showing-reference.cpp | 19 +
source/obs/obs-source-showing-reference.hpp | 49 ++
source/obs/obs-source.cpp | 813 --------------------
source/obs/obs-source.hpp | 736 +++++++++++++++---
source/obs/obs-weak-source.cpp | 19 +
source/obs/obs-weak-source.hpp | 191 +++++
13 files changed, 1066 insertions(+), 922 deletions(-)
create mode 100644 source/obs/obs-source-active-child.cpp
create mode 100644 source/obs/obs-source-active-child.hpp
create mode 100644 source/obs/obs-source-active-reference.cpp
create mode 100644 source/obs/obs-source-active-reference.hpp
create mode 100644 source/obs/obs-source-info.cpp
create mode 100644 source/obs/obs-source-info.hpp
create mode 100644 source/obs/obs-source-showing-reference.cpp
create mode 100644 source/obs/obs-source-showing-reference.hpp
create mode 100644 source/obs/obs-weak-source.cpp
create mode 100644 source/obs/obs-weak-source.hpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fb65093814..ac7852a33f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1313,18 +1313,32 @@ list(APPEND PROJECT_PRIVATE_SOURCE
"source/obs/gs/gs-vertex.cpp"
"source/obs/gs/gs-vertexbuffer.hpp"
"source/obs/gs/gs-vertexbuffer.cpp"
- "source/obs/obs-encoder-factory.hpp"
- "source/obs/obs-encoder-factory.cpp"
"source/obs/obs-signal-handler.hpp"
"source/obs/obs-signal-handler.cpp"
- "source/obs/obs-source.hpp"
- "source/obs/obs-source.cpp"
- "source/obs/obs-source-factory.hpp"
- "source/obs/obs-source-factory.cpp"
"source/obs/obs-source-tracker.hpp"
"source/obs/obs-source-tracker.cpp"
"source/obs/obs-tools.hpp"
"source/obs/obs-tools.cpp"
+
+ # obs_encoder_info_t, obs_encoder_t, obs_weak_encoder_t
+ "source/obs/obs-encoder-factory.hpp"
+ "source/obs/obs-encoder-factory.cpp"
+
+ # obs_source_info_t, obs_source_t, obs_weak_source_t
+ "source/obs/obs-source-factory.hpp"
+ "source/obs/obs-source-factory.cpp"
+ "source/obs/obs-source-info.hpp"
+ "source/obs/obs-source-info.cpp"
+ "source/obs/obs-source.hpp"
+ "source/obs/obs-source.cpp"
+ "source/obs/obs-source-active-child.hpp"
+ "source/obs/obs-source-active-child.cpp"
+ "source/obs/obs-source-active-reference.hpp"
+ "source/obs/obs-source-active-reference.cpp"
+ "source/obs/obs-source-showing-reference.hpp"
+ "source/obs/obs-source-showing-reference.cpp"
+ "source/obs/obs-weak-source.hpp"
+ "source/obs/obs-weak-source.cpp"
)
list(APPEND PROJECT_DATA
"data/effects/color_conversion_rgb_hsl.effect"
diff --git a/source/obs/obs-source-active-child.cpp b/source/obs/obs-source-active-child.cpp
new file mode 100644
index 0000000000..c876eb10ca
--- /dev/null
+++ b/source/obs/obs-source-active-child.cpp
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2022 Michael Fabian Dirks
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "obs-source-active-child.hpp"
diff --git a/source/obs/obs-source-active-child.hpp b/source/obs/obs-source-active-child.hpp
new file mode 100644
index 0000000000..736f1dfc8f
--- /dev/null
+++ b/source/obs/obs-source-active-child.hpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 Michael Fabian Dirks
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#pragma once
+#include "common.hpp"
+#include "obs-source.hpp"
+#include "obs-tools.hpp"
+#include "obs-weak-source.hpp"
+
+namespace streamfx::obs {
+ class source_active_child {
+ ::streamfx::obs::weak_source _parent;
+ ::streamfx::obs::weak_source _child;
+
+ public:
+ ~source_active_child()
+ {
+ auto parent = _parent.lock();
+ auto child = _child.lock();
+ if (parent && child) {
+ obs_source_remove_active_child(parent, child);
+ }
+ }
+ source_active_child(::streamfx::obs::source const& parent, ::streamfx::obs::source const& child)
+ : _parent(parent), _child(child)
+ {
+ if (::streamfx::obs::tools::source_find_source(child, parent)) {
+ throw std::runtime_error("Child contains Parent");
+ } else if (!obs_source_add_active_child(parent, child)) {
+ throw std::runtime_error("Child contains Parent");
+ }
+ }
+ };
+} // namespace streamfx::obs
diff --git a/source/obs/obs-source-active-reference.cpp b/source/obs/obs-source-active-reference.cpp
new file mode 100644
index 0000000000..394c19974d
--- /dev/null
+++ b/source/obs/obs-source-active-reference.cpp
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2022 Michael Fabian Dirks
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "obs-source-active-reference.hpp"
diff --git a/source/obs/obs-source-active-reference.hpp b/source/obs/obs-source-active-reference.hpp
new file mode 100644
index 0000000000..c5233d48eb
--- /dev/null
+++ b/source/obs/obs-source-active-reference.hpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 Michael Fabian Dirks
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#pragma once
+#include "common.hpp"
+#include "obs-source.hpp"
+#include "obs-weak-source.hpp"
+
+namespace streamfx::obs {
+ class source_active_reference {
+ ::streamfx::obs::weak_source _target;
+
+ public:
+ ~source_active_reference()
+ {
+ auto v = _target.lock();
+ if (v) {
+ v.decrement_active();
+ }
+ }
+ source_active_reference(::streamfx::obs::source& source) : _target(source)
+ {
+ source.increment_active();
+ }
+
+ public:
+ static FORCE_INLINE std::shared_ptr
+ add_active_reference(::streamfx::obs::source& source)
+ {
+ return std::make_shared(source);
+ }
+ };
+} // namespace streamfx::obs
diff --git a/source/obs/obs-source-info.cpp b/source/obs/obs-source-info.cpp
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/source/obs/obs-source-info.hpp b/source/obs/obs-source-info.hpp
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/source/obs/obs-source-showing-reference.cpp b/source/obs/obs-source-showing-reference.cpp
new file mode 100644
index 0000000000..2f71f103d0
--- /dev/null
+++ b/source/obs/obs-source-showing-reference.cpp
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2022 Michael Fabian Dirks
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "obs-source-showing-reference.hpp"
diff --git a/source/obs/obs-source-showing-reference.hpp b/source/obs/obs-source-showing-reference.hpp
new file mode 100644
index 0000000000..b14b78bce8
--- /dev/null
+++ b/source/obs/obs-source-showing-reference.hpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 Michael Fabian Dirks
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#pragma once
+#include "common.hpp"
+#include "obs-source.hpp"
+#include "obs-tools.hpp"
+#include "obs-weak-source.hpp"
+
+namespace streamfx::obs {
+ class source_showing_reference {
+ ::streamfx::obs::weak_source _target;
+
+ public:
+ ~source_showing_reference()
+ {
+ auto v = _target.lock();
+ if (v) {
+ v.decrement_showing();
+ }
+ }
+ source_showing_reference(::streamfx::obs::source& source) : _target(source)
+ {
+ source.increment_showing();
+ }
+
+ public:
+ static FORCE_INLINE std::shared_ptr
+ add_showing_reference(::streamfx::obs::source& source)
+ {
+ return std::make_shared(source);
+ }
+ };
+} // namespace streamfx::obs
diff --git a/source/obs/obs-source.cpp b/source/obs/obs-source.cpp
index f578f5855f..385120e062 100644
--- a/source/obs/obs-source.cpp
+++ b/source/obs/obs-source.cpp
@@ -18,816 +18,3 @@
*/
#include "obs-source.hpp"
-#include
-#include "plugin.hpp"
-
-void streamfx::obs::deprecated_source::handle_destroy(void* p, calldata_t* calldata) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
-
- obs_source_t* source;
- if (!calldata_get_ptr(calldata, "source", &source)) {
- return;
- }
-
- if (self->_self == source) {
- self->_self = nullptr;
- }
-
- if (self->events.destroy) {
- return;
- }
- self->events.destroy(self);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_remove(void* p, calldata_t*) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.remove) {
- return;
- }
- self->events.remove(self);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_save(void* p, calldata_t*) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.save) {
- return;
- }
- self->events.save(self);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_load(void* p, calldata_t*) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.load) {
- return;
- }
- self->events.load(self);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_activate(void* p, calldata_t*) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.activate) {
- return;
- }
- self->events.activate(self);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_deactivate(void* p, calldata_t*) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.deactivate) {
- return;
- }
- self->events.deactivate(self);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_show(void* p, calldata_t*) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.show) {
- return;
- }
- self->events.show(self);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_hide(void* p, calldata_t*) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.hide) {
- return;
- }
- self->events.hide(self);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_enable(void* p, calldata_t* calldata) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.enable) {
- return;
- }
-
- bool enabled = false;
- if (!calldata_get_bool(calldata, "enabled", &enabled)) {
- return;
- }
-
- self->events.enable(self, enabled);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_push_to_mute_changed(void* p, calldata_t* calldata) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.push_to_mute_changed) {
- return;
- }
-
- bool enabled = false;
- if (!calldata_get_bool(calldata, "enabled", &enabled)) {
- return;
- }
-
- self->events.push_to_mute_changed(self, enabled);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_push_to_mute_delay(void* p, calldata_t* calldata) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.push_to_mute_delay) {
- return;
- }
-
- long long delay;
- if (!calldata_get_int(calldata, "delay", &delay)) {
- return;
- }
-
- self->events.push_to_mute_delay(self, delay);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_push_to_talk_changed(void* p, calldata_t* calldata) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.push_to_talk_changed) {
- return;
- }
-
- bool enabled = false;
- if (!calldata_get_bool(calldata, "enabled", &enabled)) {
- return;
- }
-
- self->events.push_to_talk_changed(self, enabled);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_push_to_talk_delay(void* p, calldata_t* calldata) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.push_to_talk_delay) {
- return;
- }
-
- long long delay;
- if (!calldata_get_int(calldata, "delay", &delay)) {
- return;
- }
-
- self->events.push_to_talk_delay(self, delay);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_rename(void* p, calldata_t* calldata) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.enable) {
- return;
- }
-
- const char* new_name;
- if (!calldata_get_string(calldata, "new_name", &new_name)) {
- return;
- }
-
- const char* prev_name;
- if (!calldata_get_string(calldata, "prev_name", &prev_name)) {
- return;
- }
-
- self->events.rename(self, std::string(new_name ? new_name : ""), std::string(prev_name ? prev_name : ""));
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_update_properties(void* p, calldata_t*) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.update_properties) {
- return;
- }
- self->events.update_properties(self);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_update_flags(void* p, calldata_t* calldata) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.update_flags) {
- return;
- }
-
- long long flags;
- if (!calldata_get_int(calldata, "flags", &flags)) {
- return;
- }
-
- self->events.update_flags(self, flags);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_mute(void* p, calldata_t* calldata) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.mute) {
- return;
- }
-
- bool muted;
- if (!calldata_get_bool(calldata, "muted", &muted)) {
- return;
- }
-
- self->events.mute(self, muted);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_volume(void* p, calldata_t* calldata) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.volume) {
- return;
- }
-
- double volume;
- if (!calldata_get_float(calldata, "volume", &volume)) {
- return;
- }
-
- self->events.volume(self, volume);
-
- calldata_set_float(calldata, "volume", volume);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_audio_sync(void* p, calldata_t* calldata) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.audio_sync) {
- return;
- }
-
- long long mixers;
- if (!calldata_get_int(calldata, "offset", &mixers)) {
- return;
- }
-
- self->events.audio_sync(self, mixers);
-
- calldata_set_int(calldata, "offset", mixers);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_audio_mixers(void* p, calldata_t* calldata) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.audio_mixers) {
- return;
- }
-
- long long mixers;
- if (!calldata_get_int(calldata, "mixers", &mixers)) {
- return;
- }
-
- self->events.audio_mixers(self, mixers);
-
- calldata_set_int(calldata, "mixers", mixers);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_audio_data(void* p, obs_source_t*, const audio_data* audio,
- bool muted) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.audio) {
- return;
- }
-
- self->events.audio(self, audio, muted);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_filter_add(void* p, calldata_t* calldata) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.filter_add) {
- return;
- }
-
- obs_source_t* filter;
- if (!calldata_get_ptr(calldata, "filter", &filter)) {
- return;
- }
-
- self->events.filter_add(self, filter);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_filter_remove(void* p, calldata_t* calldata) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.filter_remove) {
- return;
- }
-
- obs_source_t* filter;
- if (!calldata_get_ptr(calldata, "filter", &filter)) {
- return;
- }
-
- self->events.filter_remove(self, filter);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_reorder_filters(void* p, calldata_t*) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.reorder_filters) {
- return;
- }
- self->events.reorder_filters(self);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_transition_start(void* p, calldata_t*) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.transition_start) {
- return;
- }
- self->events.transition_start(self);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_transition_video_stop(void* p, calldata_t*) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.transition_video_stop) {
- return;
- }
- self->events.transition_video_stop(self);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-void streamfx::obs::deprecated_source::handle_transition_stop(void* p, calldata_t*) noexcept
-try {
- streamfx::obs::deprecated_source* self = reinterpret_cast(p);
- if (!self->events.transition_stop) {
- return;
- }
- self->events.transition_stop(self);
-} catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
-} catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
-}
-
-streamfx::obs::deprecated_source::~deprecated_source()
-{
-#ifdef auto_signal_d
-#undef auto_signal_d
-#endif
-#define auto_signal_d(SIGNAL) this->events.SIGNAL.clear()
- auto_signal_d(destroy);
- auto_signal_d(remove);
- auto_signal_d(save);
- auto_signal_d(load);
- auto_signal_d(activate);
- auto_signal_d(deactivate);
- auto_signal_d(show);
- auto_signal_d(hide);
- auto_signal_d(mute);
- auto_signal_d(push_to_mute_changed);
- auto_signal_d(push_to_mute_delay);
- auto_signal_d(push_to_talk_changed);
- auto_signal_d(push_to_talk_delay);
- auto_signal_d(enable);
- auto_signal_d(rename);
- auto_signal_d(volume);
- auto_signal_d(update_properties);
- auto_signal_d(update_flags);
- auto_signal_d(audio_sync);
- auto_signal_d(audio_mixers);
- auto_signal_d(audio);
- auto_signal_d(filter_add);
- auto_signal_d(filter_remove);
- auto_signal_d(reorder_filters);
- auto_signal_d(transition_start);
- auto_signal_d(transition_video_stop);
- auto_signal_d(transition_stop);
-#undef auto_signal_d
-
- if (this->_track_ownership && this->_self) {
- obs_source_release(this->_self);
- }
- this->_self = nullptr;
-}
-
-streamfx::obs::deprecated_source::deprecated_source()
-{
-#ifdef auto_signal_c
-#undef auto_signal_c
-#endif
-#define auto_signal_c(SIGNAL) \
- { \
- this->events.SIGNAL.set_listen_callback([this]() noexcept { \
- if (!this->_self) \
- return; \
- auto sh = obs_source_get_signal_handler(this->_self); \
- if (sh) { \
- signal_handler_connect(sh, "" #SIGNAL, obs::deprecated_source::handle_##SIGNAL, this); \
- } \
- }); \
- this->events.SIGNAL.set_silence_callback([this]() noexcept { \
- if (!this->_self) \
- return; \
- auto sh = obs_source_get_signal_handler(this->_self); \
- if (sh) { \
- signal_handler_disconnect(sh, "" #SIGNAL, obs::deprecated_source::handle_##SIGNAL, this); \
- } \
- }); \
- }
- auto_signal_c(destroy) auto_signal_c(remove) auto_signal_c(save) auto_signal_c(load) auto_signal_c(activate)
- auto_signal_c(deactivate) auto_signal_c(show) auto_signal_c(hide) auto_signal_c(mute)
- auto_signal_c(push_to_mute_changed) auto_signal_c(push_to_mute_delay) auto_signal_c(push_to_talk_changed)
- auto_signal_c(push_to_talk_delay) auto_signal_c(enable) auto_signal_c(rename) auto_signal_c(volume)
- auto_signal_c(update_properties) auto_signal_c(update_flags) auto_signal_c(audio_sync)
- auto_signal_c(audio_mixers) auto_signal_c(filter_add) auto_signal_c(filter_remove)
- auto_signal_c(reorder_filters) auto_signal_c(transition_start)
- auto_signal_c(transition_video_stop) auto_signal_c(transition_stop)
-#undef auto_signal_c
-
- // libOBS unfortunately does not use the event system for audio data callbacks, which is kind of odd as most other
- // things do. So instead we'll have to manually deal with it for now.
- {
- this->events.audio.set_listen_callback([this]() noexcept {
- if (!this->_self)
- return;
- obs_source_add_audio_capture_callback(this->_self, streamfx::obs::deprecated_source::handle_audio_data,
- this);
- });
- this->events.audio.set_silence_callback([this]() noexcept {
- if (!this->_self)
- return;
- obs_source_remove_audio_capture_callback(this->_self, streamfx::obs::deprecated_source::handle_audio_data,
- this);
- });
- }
-}
-
-streamfx::obs::deprecated_source::deprecated_source(std::string name, bool ptrack_ownership, bool add_reference)
- : ::streamfx::obs::deprecated_source::deprecated_source()
-{
- this->_self = obs_get_source_by_name(name.c_str());
- if (!this->_self) {
- throw std::runtime_error("source with name not found");
- }
-
- this->_track_ownership = ptrack_ownership;
- if (!add_reference) {
- obs_source_release(this->_self);
- }
-}
-
-streamfx::obs::deprecated_source::deprecated_source(obs_source_t* source, bool ptrack_ownership, bool add_reference)
- : ::streamfx::obs::deprecated_source::deprecated_source()
-{
- this->_self = source;
- if (!this->_self) {
- throw std::invalid_argument("source must not be null");
- }
-
- this->_track_ownership = ptrack_ownership;
- if (add_reference) {
- obs_source_addref(this->_self);
- }
-}
-/*
-obs::deprecated_source::deprecated_source(deprecated_source const& other)
-{
- this->_self = other._self;
- this->_track_ownership = other._track_ownership;
-
- if (this->_track_ownership) {
- obs_source_addref(this->_self);
- }
-
-#ifdef auto_signal_c
-#undef auto_signal_c
-#endif
-#define auto_signal_c(SIGNAL) this->events.SIGNAL = other.events.SIGNAL
- auto_signal_c(destroy);
- auto_signal_c(remove);
- auto_signal_c(save);
- auto_signal_c(load);
- auto_signal_c(activate);
- auto_signal_c(deactivate);
- auto_signal_c(show);
- auto_signal_c(hide);
- auto_signal_c(mute);
- auto_signal_c(push_to_mute_changed);
- auto_signal_c(push_to_mute_delay);
- auto_signal_c(push_to_talk_changed);
- auto_signal_c(push_to_talk_delay);
- auto_signal_c(enable);
- auto_signal_c(rename);
- auto_signal_c(volume);
- auto_signal_c(update_properties);
- auto_signal_c(update_flags);
- auto_signal_c(audio_sync);
- auto_signal_c(audio_mixers);
- auto_signal_c(audio);
- auto_signal_c(filter_add);
- auto_signal_c(filter_remove);
- auto_signal_c(reorder_filters);
- auto_signal_c(transition_start);
- auto_signal_c(transition_video_stop);
- auto_signal_c(transition_stop);
-#undef auto_signal_c
-}
-
-obs::deprecated_source& obs::deprecated_source::operator=(deprecated_source const& other)
-{
- if (this == &other) {
- return *this;
- }
-
- // Release previous source.
- if (this->_self && this->_track_ownership) {
- obs_source_release(this->_self);
- }
-
- this->_self = other._self;
- this->_track_ownership = other._track_ownership;
-
- if (this->_track_ownership) {
- obs_source_addref(this->_self);
- }
-
-#ifdef auto_signal_c
-#undef auto_signal_c
-#endif
-#define auto_signal_c(SIGNAL) this->events.SIGNAL = other.events.SIGNAL
- auto_signal_c(destroy);
- auto_signal_c(remove);
- auto_signal_c(save);
- auto_signal_c(load);
- auto_signal_c(activate);
- auto_signal_c(deactivate);
- auto_signal_c(show);
- auto_signal_c(hide);
- auto_signal_c(mute);
- auto_signal_c(push_to_mute_changed);
- auto_signal_c(push_to_mute_delay);
- auto_signal_c(push_to_talk_changed);
- auto_signal_c(push_to_talk_delay);
- auto_signal_c(enable);
- auto_signal_c(rename);
- auto_signal_c(volume);
- auto_signal_c(update_properties);
- auto_signal_c(update_flags);
- auto_signal_c(audio_sync);
- auto_signal_c(audio_mixers);
- auto_signal_c(audio);
- auto_signal_c(filter_add);
- auto_signal_c(filter_remove);
- auto_signal_c(reorder_filters);
- auto_signal_c(transition_start);
- auto_signal_c(transition_video_stop);
- auto_signal_c(transition_stop);
-#undef auto_signal_c
-
- return *this;
-}
-*/
-
-streamfx::obs::deprecated_source::deprecated_source(deprecated_source&& other)
- : _self(std::move(other._self)), _track_ownership(std::move(other._track_ownership))
-{
- // Clean out other source
- other._self = nullptr;
- other._track_ownership = false;
-
-#ifdef auto_signal_c
-#undef auto_signal_c
-#endif
-#define auto_signal_c(SIGNAL) this->events.SIGNAL = std::move(other.events.SIGNAL)
- auto_signal_c(destroy);
- auto_signal_c(remove);
- auto_signal_c(save);
- auto_signal_c(load);
- auto_signal_c(activate);
- auto_signal_c(deactivate);
- auto_signal_c(show);
- auto_signal_c(hide);
- auto_signal_c(mute);
- auto_signal_c(push_to_mute_changed);
- auto_signal_c(push_to_mute_delay);
- auto_signal_c(push_to_talk_changed);
- auto_signal_c(push_to_talk_delay);
- auto_signal_c(enable);
- auto_signal_c(rename);
- auto_signal_c(volume);
- auto_signal_c(update_properties);
- auto_signal_c(update_flags);
- auto_signal_c(audio_sync);
- auto_signal_c(audio_mixers);
- auto_signal_c(audio);
- auto_signal_c(filter_add);
- auto_signal_c(filter_remove);
- auto_signal_c(reorder_filters);
- auto_signal_c(transition_start);
- auto_signal_c(transition_video_stop);
- auto_signal_c(transition_stop);
-#undef auto_signal_c
-}
-
-streamfx::obs::deprecated_source& streamfx::obs::deprecated_source::operator=(deprecated_source&& other)
-{
- if (this != &other) {
- return *this;
- }
-
- // Release previous source.
- if (this->_self && this->_track_ownership) {
- obs_source_release(this->_self);
- }
-
- this->_self = std::move(other._self);
- this->_track_ownership = std::move(other._track_ownership);
- other._self = nullptr;
- other._track_ownership = false;
-
-#ifdef auto_signal_c
-#undef auto_signal_c
-#endif
-#define auto_signal_c(SIGNAL) this->events.SIGNAL = std::move(other.events.SIGNAL)
- auto_signal_c(destroy);
- auto_signal_c(remove);
- auto_signal_c(save);
- auto_signal_c(load);
- auto_signal_c(activate);
- auto_signal_c(deactivate);
- auto_signal_c(show);
- auto_signal_c(hide);
- auto_signal_c(mute);
- auto_signal_c(push_to_mute_changed);
- auto_signal_c(push_to_mute_delay);
- auto_signal_c(push_to_talk_changed);
- auto_signal_c(push_to_talk_delay);
- auto_signal_c(enable);
- auto_signal_c(rename);
- auto_signal_c(volume);
- auto_signal_c(update_properties);
- auto_signal_c(update_flags);
- auto_signal_c(audio_sync);
- auto_signal_c(audio_mixers);
- auto_signal_c(audio);
- auto_signal_c(filter_add);
- auto_signal_c(filter_remove);
- auto_signal_c(reorder_filters);
- auto_signal_c(transition_start);
- auto_signal_c(transition_video_stop);
- auto_signal_c(transition_stop);
-#undef auto_signal_c
-
- return *this;
-}
-
-obs_source_type streamfx::obs::deprecated_source::type()
-{
- if (!_self) {
- return static_cast(-1);
- }
- return obs_source_get_type(_self);
-}
-
-void* streamfx::obs::deprecated_source::type_data()
-{
- if (!_self) {
- return nullptr;
- }
- return obs_source_get_type_data(_self);
-}
-
-uint32_t streamfx::obs::deprecated_source::width()
-{
- if (!_self) {
- return 0;
- }
- return obs_source_get_width(_self);
-}
-
-uint32_t streamfx::obs::deprecated_source::height()
-{
- if (!_self) {
- return 0;
- }
- return obs_source_get_height(_self);
-}
-
-bool streamfx::obs::deprecated_source::destroyed()
-{
- return _self == nullptr;
-}
-
-void streamfx::obs::deprecated_source::clear()
-{
- _self = nullptr;
-}
-
-obs_source_t* streamfx::obs::deprecated_source::get()
-{
- return _self;
-}
diff --git a/source/obs/obs-source.hpp b/source/obs/obs-source.hpp
index 4e461eb5b2..e291689407 100644
--- a/source/obs/obs-source.hpp
+++ b/source/obs/obs-source.hpp
@@ -19,119 +19,649 @@
#pragma once
#include "common.hpp"
-#include "util/util-event.hpp"
namespace streamfx::obs {
- class deprecated_source {
- obs_source_t* _self;
- bool _track_ownership = false;
-
- static void handle_destroy(void* p, calldata_t* calldata) noexcept;
- static void handle_remove(void* p, calldata_t* calldata) noexcept;
- static void handle_save(void* p, calldata_t* calldata) noexcept;
- static void handle_load(void* p, calldata_t* calldata) noexcept;
- static void handle_activate(void* p, calldata_t* calldata) noexcept;
- static void handle_deactivate(void* p, calldata_t* calldata) noexcept;
- static void handle_show(void* p, calldata_t* calldata) noexcept;
- static void handle_hide(void* p, calldata_t* calldata) noexcept;
- static void handle_enable(void* p, calldata_t* calldata) noexcept;
- static void handle_push_to_mute_changed(void* p, calldata_t* calldata) noexcept;
- static void handle_push_to_mute_delay(void* p, calldata_t* calldata) noexcept;
- static void handle_push_to_talk_changed(void* p, calldata_t* calldata) noexcept;
- static void handle_push_to_talk_delay(void* p, calldata_t* calldata) noexcept;
- static void handle_rename(void* p, calldata_t* calldata) noexcept;
- static void handle_update_properties(void* p, calldata_t* calldata) noexcept;
- static void handle_update_flags(void* p, calldata_t* calldata) noexcept;
- static void handle_mute(void* p, calldata_t* calldata) noexcept;
- static void handle_volume(void* p, calldata_t* calldata) noexcept;
- static void handle_audio_sync(void* p, calldata_t* calldata) noexcept;
- static void handle_audio_mixers(void* p, calldata_t* calldata) noexcept;
- static void handle_audio_data(void* p, obs_source_t* source, const audio_data* audio, bool muted) noexcept;
- static void handle_filter_add(void* p, calldata_t* calldata) noexcept;
- static void handle_filter_remove(void* p, calldata_t* calldata) noexcept;
- static void handle_reorder_filters(void* p, calldata_t* calldata) noexcept;
- static void handle_transition_start(void* p, calldata_t* calldata) noexcept;
- static void handle_transition_video_stop(void* p, calldata_t* calldata) noexcept;
- static void handle_transition_stop(void* p, calldata_t* calldata) noexcept;
+ class source {
+ obs_source_t* _ref;
+ bool _is_owner;
public:
- virtual ~deprecated_source();
+ FORCE_INLINE ~source()
+ {
+ release();
+ };
- deprecated_source();
+ /** Empty/Invalid hard reference.
+ *
+ */
+ FORCE_INLINE source() : _ref(nullptr), _is_owner(false){};
- deprecated_source(std::string name, bool track_ownership = true, bool add_reference = true);
+ /** Create a new hard reference from an existing pointer.
+ *
+ * @param source The source object to reference.
+ * @param add_reference Should we increment the reference counter (duplicate ownership) or leave as it is (transfer ownership)?
+ */
+ FORCE_INLINE source(obs_source_t* source, bool duplicate_reference = false, bool take_ownership = true)
+ : _is_owner(take_ownership)
+ {
+ if (duplicate_reference) {
+ _ref = obs_source_get_ref(source);
+ } else {
+ _ref = source;
+ }
+ };
- deprecated_source(obs_source_t* source, bool track_ownership = true, bool add_reference = false);
+ /** Create a new hard reference for a given source by name.
+ *
+ * Attention: May fail if the name does not exactly match.
+ */
+ FORCE_INLINE source(std::string_view name) : _is_owner(true)
+ {
+ _ref = obs_get_source_by_name(name.data());
+ };
- public /*copy*/:
- deprecated_source(deprecated_source const& other) = delete;
- deprecated_source& operator=(deprecated_source const& other) = delete;
+ /** Create a new hard reference for a new source.
+ *
+ * Attention: May fail.
+ */
+ FORCE_INLINE source(std::string_view id, std::string_view name, obs_data_t* settings, obs_data_t* hotkeys)
+ : _is_owner(true)
+ {
+ _ref = obs_source_create(id.data(), name.data(), settings, hotkeys);
+ if (!_ref) {
+ throw std::runtime_error("Failed to create source with given parameters.");
+ }
+ };
- public /*move*/:
- deprecated_source(deprecated_source&& other);
- deprecated_source& operator=(deprecated_source&& other);
+ /** Create a new hard reference for a new private source.
+ *
+ * Attention: May fail.
+ */
+ FORCE_INLINE source(std::string_view id, std::string_view name, obs_data_t* settings) : _is_owner(true)
+ {
+ _ref = obs_source_create_private(id.data(), name.data(), settings);
+ if (!_ref) {
+ throw std::runtime_error("Failed to create source with given parameters.");
+ }
+ };
+
+ FORCE_INLINE source(source&& move) noexcept
+ {
+ _ref = move._ref;
+ _is_owner = move._is_owner;
+ move._ref = nullptr;
+ };
+
+ FORCE_INLINE ::streamfx::obs::source& operator=(source&& move) noexcept
+ {
+ release();
+ _ref = move._ref;
+ _is_owner = move._is_owner;
+ move._ref = nullptr;
+ return *this;
+ };
+
+ FORCE_INLINE source(const source& copy)
+ {
+ if (copy._is_owner) {
+ _ref = obs_source_get_ref(copy._ref);
+ } else {
+ _ref = copy._ref;
+ }
+ _is_owner = copy._is_owner;
+ };
+
+ FORCE_INLINE ::streamfx::obs::source& operator=(const source& copy)
+ {
+ release();
+ if (copy._is_owner) {
+ _ref = obs_source_get_ref(copy._ref);
+ } else {
+ _ref = copy._ref;
+ }
+ _is_owner = copy._is_owner;
+ return *this;
+ };
+
+ public:
+ /** Retrieve the underlying pointer for manual manipulation.
+ *
+ * Attention: Ownership remains with the class instance.
+ */
+ FORCE_INLINE obs_source_t* get() const
+ {
+ return _ref;
+ };
+
+ /** Release the underlying pointer.
+ *
+ * Useful if you need to respond to the "source_remove" or "remove" signals.
+ *
+ * EXPORT void obs_source_release(obs_source_t *source);
+ */
+ FORCE_INLINE void release()
+ {
+ if (_ref && _is_owner) {
+ obs_source_release(_ref);
+ _ref = nullptr;
+ _is_owner = false;
+ }
+ };
+
+ /** Duplicate the source if possible.
+ *
+ * Will create a duplicate the source entirely unless forbidden. If forbidden, will instead just return a reference.
+ *
+ * EXPORT obs_source_t *obs_source_duplicate(obs_source_t *source, const char *desired_name, bool create_private);
+ */
+ FORCE_INLINE ::streamfx::obs::source duplicate(std::string_view name, bool is_private)
+ {
+ return obs_source_duplicate(_ref, name.data(), is_private);
+ };
+
+ public:
+ /** Get the source info identifier for this reference.
+ *
+ * May have a version appended to the end.
+ *
+ * EXPORT const char *obs_source_get_id(const obs_source_t *source);
+ */
+ FORCE_INLINE std::string_view id() const
+ {
+ return obs_source_get_id(_ref);
+ };
+
+ /** Get the source info identifier for this reference.
+ *
+ * EXPORT const char *obs_source_get_unversioned_id(const obs_source_t *source);
+ */
+ FORCE_INLINE std::string_view unversioned_id() const
+ {
+ return obs_source_get_unversioned_id(_ref);
+ };
+
+ /** What type is this source?
+ *
+ */
+ FORCE_INLINE obs_source_type type() const
+ {
+ return obs_source_get_type(_ref);
+ };
+
+ /** Get the output flags.
+ *
+ * EXPORT uint32_t obs_source_get_output_flags(const obs_source_t *source);
+ */
+ FORCE_INLINE uint32_t output_flags() const
+ {
+ return obs_source_get_output_flags(_ref);
+ };
+
+ /** Get the flags
+ *
+ * EXPORT uint32_t obs_source_get_flags(const obs_source_t *source);
+ */
+ FORCE_INLINE uint32_t flags() const
+ {
+ return obs_source_get_flags(_ref);
+ };
+
+ /** Set the flags
+ *
+ * EXPORT void obs_source_set_default_flags(obs_source_t* source, uint32_t flags);
+ */
+ FORCE_INLINE void default_flags(uint32_t flags)
+ {
+ obs_source_set_default_flags(_ref, flags);
+ };
+
+ /** Set the flags
+ *
+ * EXPORT void obs_source_set_flags(obs_source_t *source, uint32_t flags);
+ */
+ FORCE_INLINE void flags(uint32_t flags)
+ {
+ obs_source_set_flags(_ref, flags);
+ };
+
+ /** What is the source type called?
+ *
+ * EXPORT const char *obs_source_get_display_name(const char *id);
+ */
+ FORCE_INLINE std::string_view display_name() const
+ {
+ return obs_source_get_display_name(id().data());
+ };
+
+ /** What is this source called?
+ *
+ * EXPORT const char *obs_source_get_name(const obs_source_t *source);
+ */
+ FORCE_INLINE std::string_view name() const
+ {
+ return obs_source_get_name(_ref);
+ };
+
+ /** Change the name of the source.
+ *
+ * Triggers 'rename' on the source itself, as well as 'source_rename' globally if not private.
+ *
+ * EXPORT void obs_source_set_name(obs_source_t *source, const char *name);
+ */
+ FORCE_INLINE void name(std::string_view new_name)
+ {
+ obs_source_set_name(_ref, new_name.data());
+ };
+
+ /**
+ *
+ * EXPORT bool obs_source_enabled(const obs_source_t *source);
+ */
+ FORCE_INLINE bool enabled() const
+ {
+ return obs_source_enabled(_ref);
+ };
+
+ /**
+ *
+ * EXPORT void obs_source_set_enabled(obs_source_t *source, bool enabled);
+ */
+ FORCE_INLINE void enabled(bool enabled)
+ {
+ obs_source_set_enabled(_ref, enabled);
+ };
+
+ /**
+ *
+ * EXPORT bool obs_source_is_hidden(obs_source_t *source);
+ */
+ FORCE_INLINE bool hidden() const
+ {
+ return obs_source_is_hidden(_ref);
+ };
+
+ /**
+ *
+ * EXPORT void obs_source_set_hidden(obs_source_t *source, bool hidden);
+ */
+ FORCE_INLINE void hidden(bool v)
+ {
+ obs_source_set_hidden(_ref, v);
+ };
+
+ public /* Size */:
+ /** Get the base width of the source, if supported.
+ *
+ * This will be the size without any other scaling factors applied.
+ *
+ * EXPORT uint32_t obs_source_get_base_width(obs_source_t *source);
+ */
+ FORCE_INLINE uint32_t base_width() const
+ {
+ return obs_source_get_base_width(_ref);
+ };
+
+ /** Get the base height of the source, if supported.
+ *
+ * This will be the size without any other scaling factors applied.
+ *
+ * EXPORT uint32_t obs_source_get_base_height(obs_source_t *source);
+ */
+ FORCE_INLINE uint32_t base_height() const
+ {
+ return obs_source_get_base_height(_ref);
+ };
+
+ /** Get the reported width of the source, if supported.
+ *
+ * EXPORT uint32_t obs_source_get_width(obs_source_t *source);
+ */
+ FORCE_INLINE uint32_t width() const
+ {
+ return obs_source_get_width(_ref);
+ };
+
+ /** Get the reported height of the source, if supported.
+ *
+ * EXPORT uint32_t obs_source_get_height(obs_source_t *source);
+ */
+ FORCE_INLINE uint32_t height() const
+ {
+ return obs_source_get_height(_ref);
+ };
+
+ /** Get the reported size of the source, if supported.
+ *
+ * EXPORT uint32_t obs_source_get_width(obs_source_t *source);
+ * EXPORT uint32_t obs_source_get_height(obs_source_t *source);
+ */
+ FORCE_INLINE std::pair size() const
+ {
+ return {width(), height()};
+ };
+
+ public /* Configuration */:
+ /** Is the source configurable?
+ *
+ * EXPORT bool obs_source_configurable(const obs_source_t *source);
+ */
+ FORCE_INLINE bool configurable()
+ {
+ return obs_source_configurable(_ref);
+ };
+
+ /** Retrieve the properties for the source.
+ *
+ * EXPORT obs_properties_t *obs_get_source_properties(const char *id);
+ */
+ FORCE_INLINE obs_properties_t* properties()
+ {
+ return obs_source_properties(_ref);
+ };
+
+ /** Signal for properties to be updated.
+ *
+ * EXPORT void obs_source_update_properties(obs_source_t *source);
+ */
+ FORCE_INLINE void update_properties()
+ {
+ obs_source_update_properties(_ref);
+ };
+
+ /** Retrieve the default values for the settings.
+ *
+ * EXPORT obs_data_t *obs_get_source_defaults(const char *id);
+ */
+ FORCE_INLINE obs_data_t* defaults()
+ {
+ return obs_get_source_defaults(id().data());
+ };
+
+ /** Retrieve the private settings.
+ *
+ * EXPORT obs_data_t *obs_source_get_private_settings(obs_source_t *item);
+ */
+ FORCE_INLINE obs_data_t* private_settings()
+ {
+ return obs_source_get_private_settings(_ref);
+ };
+
+ /** Retrieve the current settings.
+ *
+ * EXPORT obs_data_t *obs_source_get_settings(const obs_source_t *source);
+ */
+ FORCE_INLINE obs_data_t* settings()
+ {
+ return obs_source_get_settings(_ref);
+ };
+
+ /** Update the settings with new ones.
+ *
+ * Does not remove previously existing entries.
+ *
+ * EXPORT void obs_source_update(obs_source_t *source, obs_data_t *settings);
+ */
+ FORCE_INLINE void update(obs_data_t* settings)
+ {
+ obs_source_update(_ref, settings);
+ };
+
+ /** Reset the settings, then update with new settings.
+ *
+ * EXPORT void obs_source_reset_settings(obs_source_t *source, obs_data_t *settings);
+ */
+ FORCE_INLINE void reset_settings(obs_data_t* settings = nullptr)
+ {
+ obs_source_reset_settings(_ref, settings);
+ };
+
+ /** Signal the source to load.
+ *
+ * EXPORT void obs_source_load(obs_source_t *source);
+ */
+ FORCE_INLINE void load()
+ {
+ obs_source_load(_ref);
+ };
+
+ /** Signal the source and all its filters to load.
+ *
+ * EXPORT void obs_source_load2(obs_source_t *source);
+ */
+ FORCE_INLINE void load2()
+ {
+ obs_source_load2(_ref);
+ };
+
+ /** Signal the source to save.
+ *
+ * EXPORT void obs_source_save(obs_source_t *source);
+ */
+ FORCE_INLINE void save()
+ {
+ obs_source_save(_ref);
+ };
+
+ public /* Interaction */:
+ /**
+ *
+ * EXPORT void obs_source_send_mouse_click(obs_source_t *source, const struct obs_mouse_event *event, int32_t type, bool mouse_up, uint32_t click_count);
+ */
+ FORCE_INLINE void send_mouse_press(const obs_mouse_event* event, int32_t type, bool released, uint32_t count)
+ {
+ return obs_source_send_mouse_click(_ref, event, type, released, count);
+ };
+
+ /**
+ *
+ * EXPORT void obs_source_send_mouse_move(obs_source_t *source, const struct obs_mouse_event *event, bool mouse_leave);
+ */
+ FORCE_INLINE void send_mouse_move(const obs_mouse_event* event, bool leave)
+ {
+ return obs_source_send_mouse_move(_ref, event, leave);
+ };
+
+ /**
+ *
+ * EXPORT void obs_source_send_mouse_wheel(obs_source_t *source, const struct obs_mouse_event *event, int x_delta, int y_delta);
+ */
+ FORCE_INLINE void send_mouse_wheel(const obs_mouse_event* event, int32_t x_delta, int32_t y_delta)
+ {
+ return obs_source_send_mouse_wheel(_ref, event, x_delta, y_delta);
+ };
+
+ /**
+ *
+ * EXPORT void obs_source_send_key_click(obs_source_t *source, const struct obs_key_event *event, bool key_up);
+ */
+ FORCE_INLINE void send_key_press(const obs_key_event* event, bool released)
+ {
+ return obs_source_send_key_click(_ref, event, released);
+ };
+
+ /**
+ *
+ * EXPORT void obs_source_send_focus(obs_source_t *source, bool focus);
+ */
+ FORCE_INLINE void send_focus(bool in_focus)
+ {
+ return obs_source_send_focus(_ref, in_focus);
+ };
+
+ public /* Filters */:
+ /**
+ *
+ * EXPORT void obs_source_filter_add(obs_source_t *source, obs_source_t *filter);
+ */
+ FORCE_INLINE void add_filter(::streamfx::obs::source& filter)
+ {
+ return obs_source_filter_add(_ref, filter.get());
+ };
+
+ /**
+ *
+ * EXPORT void obs_source_filter_remove(obs_source_t *source, obs_source_t *filter);
+ */
+ FORCE_INLINE void remove_filter(::streamfx::obs::source& filter)
+ {
+ return obs_source_filter_remove(_ref, filter.get());
+ };
+
+ /**
+ *
+ * EXPORT obs_source_t *obs_filter_get_parent(const obs_source_t *filter);
+ */
+ FORCE_INLINE ::streamfx::obs::source get_filter_parent()
+ {
+ return obs_filter_get_parent(_ref);
+ };
+
+ /**
+ *
+ * EXPORT obs_source_t *obs_filter_get_target(const obs_source_t *filter);
+ */
+ FORCE_INLINE ::streamfx::obs::source get_filter_target()
+ {
+ return obs_filter_get_target(_ref);
+ };
+
+ /**
+ *
+ * EXPORT void obs_source_skip_video_filter(obs_source_t *filter);
+ */
+ FORCE_INLINE void skip_video_filter()
+ {
+ return obs_source_skip_video_filter(_ref);
+ };
+
+ /**
+ *
+ * EXPORT bool obs_source_process_filter_begin(obs_source_t *filter, enum gs_color_format format, enum obs_allow_direct_render allow_direct);
+ */
+ FORCE_INLINE bool process_filter_begin(gs_color_format format, obs_allow_direct_render allow_direct)
+ {
+ return obs_source_process_filter_begin(_ref, format, allow_direct);
+ };
+
+ /**
+ *
+ * EXPORT void obs_source_process_filter_end(obs_source_t *filter, gs_effect_t *effect, uint32_t width, uint32_t height);
+ */
+ FORCE_INLINE void process_filter_end(gs_effect_t* effect, uint32_t width, uint32_t height)
+ {
+ obs_source_process_filter_end(_ref, effect, width, height);
+ };
+
+ /**
+ *
+ * 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);
+ */
+ FORCE_INLINE void process_filter_tech_end(gs_effect_t* effect, uint32_t width, uint32_t height,
+ std::string_view tech_name)
+ {
+ obs_source_process_filter_tech_end(_ref, effect, width, height, tech_name.data());
+ };
+
+ public /* Active/Showing References */:
+ /** Is the source visible in main view?
+ *
+ * EXPORT bool obs_source_active(const obs_source_t *source);
+ */
+ FORCE_INLINE bool active() const
+ {
+ return obs_source_active(_ref);
+ }
+
+ /** Add a active reference (visible in main view).
+ *
+ * EXPORT void obs_source_inc_active(obs_source_t *source);
+ */
+ FORCE_INLINE void increment_active()
+ {
+ obs_source_inc_active(_ref);
+ }
+
+ /** Remove a active reference (visible in main view).
+ *
+ * EXPORT void obs_source_dec_active(obs_source_t *source);
+ */
+ FORCE_INLINE void decrement_active()
+ {
+ obs_source_dec_active(_ref);
+ }
+
+ /** Is the source visible in auxiliary views?
+ *
+ * EXPORT bool obs_source_showing(const obs_source_t *source);
+ */
+ FORCE_INLINE bool showing() const
+ {
+ return obs_source_showing(_ref);
+ }
+
+ /** Add a showing reference (visible in auxiliary view).
+ *
+ * EXPORT void obs_source_inc_showing(obs_source_t *source);
+ * EXPORT void obs_source_dec_showing(obs_source_t *source);
+ */
+ FORCE_INLINE void increment_showing()
+ {
+ obs_source_inc_showing(_ref);
+ }
+
+ /** Add a showing reference (visible in auxiliary view).
+ *
+ * EXPORT void obs_source_inc_showing(obs_source_t *source);
+ * EXPORT void obs_source_dec_showing(obs_source_t *source);
+ */
+ FORCE_INLINE void decrement_showing()
+ {
+ obs_source_dec_showing(_ref);
+ }
+
+ public /* ToDo */:
+
+ /**
+ *
+ * EXPORT obs_missing_files_t* obs_source_get_missing_files(const obs_source_t *source);
+ */
+ obs_missing_files_t* get_missing_files();
+
+ /**
+ *
+ * EXPORT void obs_source_replace_missing_file(obs_missing_file_cb cb, obs_source_t *source, const char *new_path, void *data);
+ */
+ void replace_missing_file(obs_missing_file_cb cb, std::string_view path, void* data);
public:
- obs_source_type type();
-
- void* type_data();
-
- uint32_t width();
- uint32_t height();
-
- bool destroyed();
-
- public: // Unsafe Methods
- void clear();
-
- obs_source_t* get();
-
- public: // Events
- struct {
- // Destroy and Remove
- streamfx::util::event destroy;
- streamfx::util::event remove;
-
- // Saving, Loading and Update
- streamfx::util::event save;
- streamfx::util::event load;
- streamfx::util::event update_properties;
-
- // Activate, Deactivate
- streamfx::util::event activate;
- streamfx::util::event deactivate;
-
- // Show Hide
- streamfx::util::event show;
- streamfx::util::event hide;
-
- // Other
- streamfx::util::event enable;
- streamfx::util::event rename;
- streamfx::util::event update_flags;
-
- // Hotkeys (PtM, PtT)
- streamfx::util::event push_to_mute_changed;
- streamfx::util::event push_to_mute_delay;
- streamfx::util::event push_to_talk_changed;
- streamfx::util::event push_to_talk_delay;
-
- // Audio
- streamfx::util::event mute;
- streamfx::util::event volume;
- streamfx::util::event audio_sync;
- streamfx::util::event audio_mixers;
- streamfx::util::event audio;
-
- // Filters
- streamfx::util::event filter_add;
- streamfx::util::event filter_remove;
- streamfx::util::event reorder_filters;
-
- // Transition
- streamfx::util::event transition_start;
- streamfx::util::event transition_video_stop;
- streamfx::util::event transition_stop;
- } events;
+ FORCE_INLINE operator obs_source_t*() const
+ {
+ return _ref;
+ }
+
+ FORCE_INLINE obs_source_t* operator*() const
+ {
+ return _ref;
+ }
+
+ FORCE_INLINE operator bool() const
+ {
+ return _ref != nullptr;
+ };
+
+ FORCE_INLINE bool operator==(source const& rhs) const
+ {
+ return _ref == rhs._ref;
+ };
+
+ FORCE_INLINE bool operator<(source const& rhs) const
+ {
+ return _ref < rhs._ref;
+ };
+
+ FORCE_INLINE bool operator==(obs_source_t* const& rhs) const
+ {
+ return _ref == rhs;
+ };
};
} // namespace streamfx::obs
diff --git a/source/obs/obs-weak-source.cpp b/source/obs/obs-weak-source.cpp
new file mode 100644
index 0000000000..1d6301ef83
--- /dev/null
+++ b/source/obs/obs-weak-source.cpp
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2022 Michael Fabian Dirks
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "obs-weak-source.hpp"
diff --git a/source/obs/obs-weak-source.hpp b/source/obs/obs-weak-source.hpp
new file mode 100644
index 0000000000..da34790f0b
--- /dev/null
+++ b/source/obs/obs-weak-source.hpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2022 Michael Fabian Dirks
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#pragma once
+#include "common.hpp"
+#include "obs-source.hpp"
+
+namespace streamfx::obs {
+ class source;
+
+ class weak_source {
+ obs_weak_source_t* _ref;
+
+ public:
+ ~weak_source()
+ {
+ if (_ref) {
+ obs_weak_source_release(_ref);
+ }
+ };
+
+ /** Empty/Invalid weak reference.
+ *
+ */
+ weak_source() : _ref(nullptr){};
+
+ /** Create a new weak reference from an existing pointer.
+ *
+ * Attention: Ownership of obs_weak_source_t is transferred to the class itself, and should not be released.
+ */
+ weak_source(obs_weak_source_t* source) : _ref(source)
+ {
+ if (!_ref)
+ throw std::invalid_argument("Parameter 'source' does not define a valid source.");
+ };
+
+ /** Create a new weak reference from an existing hard reference.
+ */
+ weak_source(obs_source_t* source)
+ {
+ _ref = obs_source_get_weak_source(source);
+ if (!_ref)
+ throw std::invalid_argument("Parameter 'source' does not define a valid source.");
+ };
+
+ /** Create a new weak reference from an existing hard reference.
+ */
+ weak_source(::streamfx::obs::source& source)
+ {
+ _ref = obs_source_get_weak_source(source.get());
+ if (!_ref)
+ throw std::invalid_argument("Parameter 'source' does not define a valid source.");
+ };
+
+ /** Create a new weak reference for a given source by name.
+ *
+ * Attention: May fail if the name does not exactly match.
+ */
+ weak_source(std::string_view name)
+ {
+ std::shared_ptr ref{obs_get_source_by_name(name.data()),
+ [](obs_source_t* v) { obs_source_release(v); }};
+ if (!ref) {
+ throw std::invalid_argument("Parameter 'name' does not define an valid source.");
+ }
+ _ref = obs_source_get_weak_source(ref.get());
+ };
+
+ weak_source(weak_source&& move) noexcept
+ {
+ _ref = move._ref;
+ move._ref = nullptr;
+ };
+
+ FORCE_INLINE ::streamfx::obs::weak_source& operator=(weak_source&& move) noexcept
+ {
+ if (_ref) {
+ obs_weak_source_release(_ref);
+ _ref = nullptr;
+ }
+ if (move._ref) {
+ _ref = move._ref;
+ move._ref = nullptr;
+ }
+ return *this;
+ };
+
+ weak_source(const weak_source& copy)
+ {
+ _ref = copy._ref;
+ obs_weak_source_addref(_ref);
+ };
+
+ FORCE_INLINE ::streamfx::obs::weak_source& operator=(const weak_source& copy)
+ {
+ if (_ref) {
+ obs_weak_source_release(_ref);
+ _ref = nullptr;
+ }
+ if (copy._ref) {
+ _ref = copy._ref;
+ obs_weak_source_addref(_ref);
+ }
+
+ return *this;
+ };
+
+ /** Retrieve the underlying pointer for manual manipulation.
+ *
+ * Attention: Ownership remains with the class instance.
+ */
+ FORCE_INLINE obs_weak_source_t* get() const
+ {
+ return _ref;
+ };
+
+ /** Is the weak reference expired?
+ *
+ * A weak reference is expired when the original object it is pointing at no longer exists.
+ */
+ FORCE_INLINE bool expired() const
+ {
+ return (!_ref) || (obs_weak_source_expired(_ref));
+ };
+
+ /** Try and acquire a hard reference to the source.
+ *
+ * May fail if the reference expired before we successfully acquire it.
+ */
+ FORCE_INLINE ::streamfx::obs::source lock() const
+ {
+ return {obs_weak_source_get_source(_ref)};
+ };
+
+ public:
+ FORCE_INLINE operator obs_weak_source_t*() const
+ {
+ return _ref;
+ }
+
+ FORCE_INLINE obs_weak_source_t* operator*() const
+ {
+ return _ref;
+ }
+
+ FORCE_INLINE operator bool() const
+ {
+ return !expired();
+ };
+
+ FORCE_INLINE bool operator==(weak_source const& rhs) const
+ {
+ return _ref == rhs._ref;
+ };
+
+ FORCE_INLINE bool operator<(weak_source const& rhs) const
+ {
+ return _ref < rhs._ref;
+ };
+
+ FORCE_INLINE bool operator==(obs_weak_source_t* const& rhs) const
+ {
+ return _ref == rhs;
+ };
+
+ FORCE_INLINE bool operator==(source const& rhs) const
+ {
+ return obs_weak_source_references_source(_ref, rhs.get());
+ };
+
+ FORCE_INLINE bool operator==(obs_source_t* const& rhs) const
+ {
+ return obs_weak_source_references_source(_ref, rhs);
+ };
+ };
+} // namespace streamfx::obs
From e3c7b13d6fdb0be43c5a729bfed88ff09549b298 Mon Sep 17 00:00:00 2001
From: Michael Fabian 'Xaymar' Dirks
Date: Wed, 11 May 2022 05:33:38 +0200
Subject: [PATCH 017/164] obs/source-factory: Add support for OBS Studio 27.x
Also improves the functionality logic slightly to be more in line with real behavior.
---
source/filters/filter-autoframing.cpp | 2 +-
source/filters/filter-blur.cpp | 2 +-
source/filters/filter-color-grade.cpp | 2 +-
source/filters/filter-denoising.cpp | 2 +-
source/filters/filter-displacement.cpp | 2 +-
source/filters/filter-dynamic-mask.cpp | 10 +-
source/filters/filter-sdf-effects.cpp | 2 +-
source/filters/filter-shader.cpp | 4 +-
source/filters/filter-transform.cpp | 2 +-
source/filters/filter-upscaling.cpp | 2 +-
source/filters/filter-virtual-greenscreen.cpp | 2 +-
source/obs/obs-source-factory.hpp | 1146 +++++++++++------
source/sources/source-mirror.cpp | 4 +-
source/sources/source-shader.cpp | 4 +-
source/transitions/transition-shader.cpp | 2 +-
15 files changed, 750 insertions(+), 438 deletions(-)
diff --git a/source/filters/filter-autoframing.cpp b/source/filters/filter-autoframing.cpp
index c86e1d1465..5150c454d8 100644
--- a/source/filters/filter-autoframing.cpp
+++ b/source/filters/filter-autoframing.cpp
@@ -1086,7 +1086,7 @@ autoframing_factory::autoframing_factory()
_info.type = OBS_SOURCE_TYPE_FILTER;
_info.output_flags = OBS_SOURCE_VIDEO;
- set_resolution_enabled(true);
+ support_size(true);
finish_setup();
// Register proxy identifiers.
diff --git a/source/filters/filter-blur.cpp b/source/filters/filter-blur.cpp
index 253ae683b2..b4f249c1f7 100644
--- a/source/filters/filter-blur.cpp
+++ b/source/filters/filter-blur.cpp
@@ -604,7 +604,7 @@ blur_factory::blur_factory()
_info.type = OBS_SOURCE_TYPE_FILTER;
_info.output_flags = OBS_SOURCE_VIDEO;
- set_resolution_enabled(false);
+ support_size(false);
finish_setup();
register_proxy("obs-stream-effects-filter-blur");
}
diff --git a/source/filters/filter-color-grade.cpp b/source/filters/filter-color-grade.cpp
index d11093b396..dacb778c53 100644
--- a/source/filters/filter-color-grade.cpp
+++ b/source/filters/filter-color-grade.cpp
@@ -584,7 +584,7 @@ color_grade_factory::color_grade_factory()
_info.type = OBS_SOURCE_TYPE_FILTER;
_info.output_flags = OBS_SOURCE_VIDEO;
- set_resolution_enabled(false);
+ support_size(false);
finish_setup();
register_proxy("obs-stream-effects-filter-color-grade");
}
diff --git a/source/filters/filter-denoising.cpp b/source/filters/filter-denoising.cpp
index 670ffe0649..3ff8c14220 100644
--- a/source/filters/filter-denoising.cpp
+++ b/source/filters/filter-denoising.cpp
@@ -550,7 +550,7 @@ denoising_factory::denoising_factory()
_info.type = OBS_SOURCE_TYPE_FILTER;
_info.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW;
- set_resolution_enabled(true);
+ support_size(true);
finish_setup();
// Proxies
diff --git a/source/filters/filter-displacement.cpp b/source/filters/filter-displacement.cpp
index 063130e0f6..64a28f8680 100644
--- a/source/filters/filter-displacement.cpp
+++ b/source/filters/filter-displacement.cpp
@@ -150,7 +150,7 @@ displacement_factory::displacement_factory()
_info.type = OBS_SOURCE_TYPE_FILTER;
_info.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW | OBS_SOURCE_DEPRECATED | OBS_SOURCE_CAP_DISABLED;
- set_resolution_enabled(false);
+ support_size(false);
finish_setup();
register_proxy("obs-stream-effects-filter-displacement");
}
diff --git a/source/filters/filter-dynamic-mask.cpp b/source/filters/filter-dynamic-mask.cpp
index fbc0956b22..ca1b79ecf4 100644
--- a/source/filters/filter-dynamic-mask.cpp
+++ b/source/filters/filter-dynamic-mask.cpp
@@ -455,11 +455,11 @@ dynamic_mask_factory::dynamic_mask_factory()
_info.type = OBS_SOURCE_TYPE_FILTER;
_info.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW;
- set_have_active_child_sources(true);
- set_have_child_sources(true);
- set_resolution_enabled(false);
- set_activity_tracking_enabled(true);
- set_visibility_tracking_enabled(true);
+ support_active_child_sources(true);
+ support_child_sources(true);
+ support_size(false);
+ support_activity_tracking(true);
+ support_visibility_tracking(true);
finish_setup();
register_proxy("obs-stream-effects-filter-dynamic-mask");
}
diff --git a/source/filters/filter-sdf-effects.cpp b/source/filters/filter-sdf-effects.cpp
index 8bfe146754..9d7877fa34 100644
--- a/source/filters/filter-sdf-effects.cpp
+++ b/source/filters/filter-sdf-effects.cpp
@@ -570,7 +570,7 @@ sdf_effects_factory::sdf_effects_factory()
_info.type = OBS_SOURCE_TYPE_FILTER;
_info.output_flags = OBS_SOURCE_VIDEO;
- set_resolution_enabled(false);
+ support_size(false);
finish_setup();
register_proxy("obs-stream-effects-filter-sdf-effects");
}
diff --git a/source/filters/filter-shader.cpp b/source/filters/filter-shader.cpp
index 7a191e5d4c..d47a85874c 100644
--- a/source/filters/filter-shader.cpp
+++ b/source/filters/filter-shader.cpp
@@ -179,8 +179,8 @@ shader_factory::shader_factory()
_info.type = OBS_SOURCE_TYPE_FILTER;
_info.output_flags = OBS_SOURCE_VIDEO;
- set_activity_tracking_enabled(true);
- set_visibility_tracking_enabled(true);
+ support_activity_tracking(true);
+ support_visibility_tracking(true);
finish_setup();
register_proxy("obs-stream-effects-filter-shader");
}
diff --git a/source/filters/filter-transform.cpp b/source/filters/filter-transform.cpp
index 1ea1ea99d3..d06f655bf8 100644
--- a/source/filters/filter-transform.cpp
+++ b/source/filters/filter-transform.cpp
@@ -597,7 +597,7 @@ transform_factory::transform_factory()
_info.type = OBS_SOURCE_TYPE_FILTER;
_info.output_flags = OBS_SOURCE_VIDEO;
- set_resolution_enabled(false);
+ support_size(false);
finish_setup();
register_proxy("obs-stream-effects-filter-transform");
}
diff --git a/source/filters/filter-upscaling.cpp b/source/filters/filter-upscaling.cpp
index 7829654fa4..d9ba6290af 100644
--- a/source/filters/filter-upscaling.cpp
+++ b/source/filters/filter-upscaling.cpp
@@ -550,7 +550,7 @@ upscaling_factory::upscaling_factory()
_info.type = OBS_SOURCE_TYPE_FILTER;
_info.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW /*| OBS_SOURCE_SRGB*/;
- set_resolution_enabled(true);
+ support_size(true);
finish_setup();
// Proxies
diff --git a/source/filters/filter-virtual-greenscreen.cpp b/source/filters/filter-virtual-greenscreen.cpp
index cf9640b936..b46b810885 100644
--- a/source/filters/filter-virtual-greenscreen.cpp
+++ b/source/filters/filter-virtual-greenscreen.cpp
@@ -554,7 +554,7 @@ virtual_greenscreen_factory::virtual_greenscreen_factory()
_info.type = OBS_SOURCE_TYPE_FILTER;
_info.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW /*| OBS_SOURCE_SRGB*/;
- set_resolution_enabled(true);
+ support_size(true);
finish_setup();
}
diff --git a/source/obs/obs-source-factory.hpp b/source/obs/obs-source-factory.hpp
index 474b36b62f..736d761a5e 100644
--- a/source/obs/obs-source-factory.hpp
+++ b/source/obs/obs-source-factory.hpp
@@ -19,7 +19,7 @@
#pragma once
#include "common.hpp"
-#include "plugin.hpp"
+#include "obs-source.hpp"
namespace streamfx::obs {
template
@@ -30,9 +30,10 @@ namespace streamfx::obs {
std::set _proxy_names;
public:
- source_factory()
+ source_factory(obs_source_type type = OBS_SOURCE_TYPE_INPUT)
{
_info.type_data = this;
+ _info.type = type;
_info.get_name = _get_name;
_info.create = _create;
@@ -43,126 +44,84 @@ namespace streamfx::obs {
_info.update = _update;
_info.save = _save;
_info.filter_remove = _filter_remove;
-
- set_resolution_enabled(true);
- set_activity_tracking_enabled(false);
- set_visibility_tracking_enabled(false);
- set_input_enabled(false);
- set_have_child_sources(false);
}
virtual ~source_factory() {}
protected:
- void set_resolution_enabled(bool v)
- {
- if (v) {
- _info.get_width = _get_width;
- _info.get_height = _get_height;
- } else {
- _info.get_width = nullptr;
- _info.get_height = nullptr;
- }
- }
-
- void set_activity_tracking_enabled(bool v)
- {
- if (v) {
- _info.activate = _activate;
- _info.deactivate = _deactivate;
- } else {
- _info.activate = nullptr;
- _info.deactivate = nullptr;
- }
- }
-
- void set_visibility_tracking_enabled(bool v)
- {
- if (v) {
- _info.show = _show;
- _info.hide = _hide;
- } else {
- _info.show = nullptr;
- _info.hide = nullptr;
- }
- }
-
- void set_input_enabled(bool v)
+ void finish_setup()
{
- if (v) {
- _info.mouse_click = _mouse_click;
- _info.mouse_move = _mouse_move;
- _info.mouse_wheel = _mouse_wheel;
- _info.focus = _focus;
- _info.key_click = _key_click;
- } else {
- _info.mouse_click = nullptr;
- _info.mouse_move = nullptr;
- _info.mouse_wheel = nullptr;
- _info.focus = nullptr;
- _info.key_click = nullptr;
- }
- }
+ // Adjust options by type:
+ // - Transitions
+ if (_info.type == OBS_SOURCE_TYPE_TRANSITION) {
+ // Transitions don't have size.
+ support_size(false);
- void set_have_child_sources(bool v)
- {
- if (v) {
- _info.enum_all_sources = _enum_all_sources;
- } else {
- _info.enum_all_sources = nullptr;
- }
- }
+ // Transitions are also composite, video and custom draw, but never async.
+ _info.output_flags |= OBS_SOURCE_COMPOSITE | OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW;
+ _info.output_flags &= ~(OBS_SOURCE_ASYNC);
- void set_have_active_child_sources(bool v)
- {
- if (v) {
- _info.enum_active_sources = _enum_active_sources;
- } else {
- _info.enum_active_sources = nullptr;
- }
- }
+ // Transition controls.
+ _info.transition_start = _transition_start;
+ _info.transition_stop = _transition_stop;
- void finish_setup()
- {
- if (_info.output_flags & OBS_SOURCE_INTERACTION) {
- set_input_enabled(true);
- } else {
- set_input_enabled(false);
+ // Transitions are always synchronous video.
+ _info.video_tick = _video_tick;
+ _info.video_render = _video_render;
}
+ // - Filter
+ if (_info.type == OBS_SOURCE_TYPE_FILTER) {
+ support_interaction(false);
- if (_info.type == OBS_SOURCE_TYPE_TRANSITION) {
- set_resolution_enabled(false);
- _info.transition_start = _transition_start;
- _info.transition_stop = _transition_stop;
- _info.audio_render = _audio_render;
- _info.video_tick = _video_tick;
- _info.video_render = _video_render;
- } else if (_info.type == OBS_SOURCE_TYPE_FILTER) {
- switch (_info.output_flags & OBS_SOURCE_ASYNC_VIDEO) {
- case OBS_SOURCE_ASYNC_VIDEO:
- _info.filter_video = _filter_video;
- break;
- case OBS_SOURCE_VIDEO:
+ // If this is a video filter, require one of two code paths.
+ uint32_t av = (_info.output_flags & OBS_SOURCE_ASYNC_VIDEO);
+ if (av == OBS_SOURCE_VIDEO) {
_info.video_tick = _video_tick;
_info.video_render = _video_render_filter;
- break;
+ } else if (av == OBS_SOURCE_ASYNC_VIDEO) {
+ _info.video_tick = _video_tick;
+ _info.filter_video = _filter_video;
}
- if ((_info.output_flags & OBS_SOURCE_AUDIO) != 0) {
+
+ // If this is an audio filter
+ if ((_info.output_flags & OBS_SOURCE_AUDIO) == OBS_SOURCE_AUDIO) {
_info.filter_audio = _filter_audio;
- if ((_info.output_flags & OBS_SOURCE_COMPOSITE) != 0) {
- _info.audio_render = _audio_render;
- }
}
- } else {
- if ((_info.output_flags & OBS_SOURCE_ASYNC_VIDEO) != 0) {
- if ((_info.output_flags & OBS_SOURCE_ASYNC) == 0) {
- set_resolution_enabled(true);
- }
+ }
+ // - Input
+ if (_info.type == OBS_SOURCE_TYPE_INPUT) {
+ uint32_t av = (_info.output_flags & OBS_SOURCE_ASYNC_VIDEO);
+ if (av == OBS_SOURCE_VIDEO) {
_info.video_tick = _video_tick;
_info.video_render = _video_render;
+ support_size(true);
+ } else if (av == OBS_SOURCE_ASYNC_VIDEO) {
+ _info.video_tick = _video_tick;
+ support_size(false);
}
- if ((_info.output_flags & OBS_SOURCE_COMPOSITE) != 0) {
- _info.audio_render = _audio_render;
+ }
+
+ // Does the source have the composite audio flag?
+ if ((_info.output_flags & OBS_SOURCE_COMPOSITE) == OBS_SOURCE_COMPOSITE) {
+ // Does it also have some invalid flags?
+ if ((_info.output_flags & OBS_SOURCE_AUDIO) == OBS_SOURCE_AUDIO) {
+ throw std::runtime_error("Composite sources may not be audio sources.");
+ }
+ if ((_info.output_flags & OBS_SOURCE_ASYNC) == OBS_SOURCE_ASYNC) {
+ throw std::runtime_error("Composite sources may not be asynchronous.");
+ }
+ // If not allow the assignment of audio_render.
+ _info.audio_render = _audio_render;
+ }
+
+ // Does the source have the submix audio flag? (Internal to libOBS?)
+ if ((_info.output_flags & OBS_SOURCE_SUBMIX) == OBS_SOURCE_SUBMIX) {
+ if ((_info.output_flags & OBS_SOURCE_AUDIO) == OBS_SOURCE_AUDIO) {
+ throw std::runtime_error("Composite sources may not be audio sources.");
+ }
+ if ((_info.output_flags & OBS_SOURCE_COMPOSITE) == OBS_SOURCE_COMPOSITE) {
+ throw std::runtime_error("Submix sources may not be composite.");
}
+ _info.audio_mix = _audio_mix;
}
obs_register_source(&_info);
@@ -184,354 +143,665 @@ namespace streamfx::obs {
private /* Factory */:
static const char* _get_name(void* type_data) noexcept
- try {
- if (type_data)
- return reinterpret_cast<_factory*>(type_data)->get_name();
- return nullptr;
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- return nullptr;
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
- return nullptr;
+ {
+ try {
+ if (type_data)
+ return reinterpret_cast<_factory*>(type_data)->get_name();
+ return nullptr;
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ return nullptr;
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ return nullptr;
+ }
}
static void* _create(obs_data_t* settings, obs_source_t* source) noexcept
- try {
- return reinterpret_cast<_factory*>(obs_source_get_type_data(source))->create(settings, source);
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- return nullptr;
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
- return nullptr;
+ {
+ try {
+ return reinterpret_cast<_factory*>(obs_source_get_type_data(source))->create(settings, source);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ return nullptr;
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ return nullptr;
+ }
}
static void _get_defaults2(void* type_data, obs_data_t* settings) noexcept
- try {
- if (type_data)
- reinterpret_cast<_factory*>(type_data)->get_defaults2(settings);
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ {
+ try {
+ if (type_data)
+ reinterpret_cast<_factory*>(type_data)->get_defaults2(settings);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
static obs_properties_t* _get_properties2(void* data, void* type_data) noexcept
- try {
- if (type_data)
- return reinterpret_cast<_factory*>(type_data)->get_properties2(reinterpret_cast<_instance*>(data));
- return nullptr;
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- return nullptr;
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
- return nullptr;
+ {
+ try {
+ if (type_data)
+ return reinterpret_cast<_factory*>(type_data)->get_properties2(reinterpret_cast<_instance*>(data));
+ return nullptr;
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ return nullptr;
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ return nullptr;
+ }
}
private /* Instance */:
static void _destroy(void* data) noexcept
- try {
- if (data)
- delete reinterpret_cast<_instance*>(data);
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ {
+ try {
+ if (data)
+ delete reinterpret_cast<_instance*>(data);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
- static uint32_t _get_width(void* data) noexcept
- try {
- if (data)
- return reinterpret_cast<_instance*>(data)->get_width();
- return 0;
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- return 0;
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
- return 0;
+ static void _filter_remove(void* data, obs_source_t* source) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->filter_remove(source);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
- static uint32_t _get_height(void* data) noexcept
- try {
- if (data)
- return reinterpret_cast<_instance*>(data)->get_height();
- return 0;
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- return 0;
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
- return 0;
+ public /* Instance > Video */:
+ static void _video_tick(void* data, float seconds) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->video_tick(seconds);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
- static void _activate(void* data) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->activate();
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ static void _video_render(void* data, gs_effect_t* effect) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->video_render(effect);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
- static void _deactivate(void* data) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->deactivate();
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ static void _video_render_filter(void* data, gs_effect_t* effect) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->video_render(effect);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ obs_source_skip_video_filter(reinterpret_cast<_instance*>(data)->get());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ obs_source_skip_video_filter(reinterpret_cast<_instance*>(data)->get());
+ }
}
- static void _show(void* data) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->show();
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ static struct obs_source_frame* _filter_video(void* data, struct obs_source_frame* frame) noexcept
+ {
+ try {
+ if (data)
+ return reinterpret_cast<_instance*>(data)->filter_video(frame);
+ return frame;
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ return frame;
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ return frame;
+ }
}
- static void _hide(void* data) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->hide();
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ public /* Instance > Audio */:
+ static struct obs_audio_data* _filter_audio(void* data, struct obs_audio_data* frame) noexcept
+ {
+ try {
+ if (data)
+ return reinterpret_cast<_instance*>(data)->filter_audio(frame);
+ return frame;
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ return frame;
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ return frame;
+ }
}
- static void _video_tick(void* data, float seconds) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->video_tick(seconds);
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ static bool _audio_render(void* data, uint64_t* ts_out, struct obs_source_audio_mix* audio_output,
+ uint32_t mixers, std::size_t channels, std::size_t sample_rate) noexcept
+ {
+ try {
+ if (data)
+ return reinterpret_cast<_instance*>(data)->audio_render(ts_out, audio_output, mixers, channels,
+ sample_rate);
+ return false;
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ return false;
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ return false;
+ }
}
- static void _video_render(void* data, gs_effect_t* effect) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->video_render(effect);
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ static bool _audio_mix(void* data, uint64_t* ts_out, struct audio_output_data* audio_output,
+ std::size_t channels, std::size_t sample_rate) noexcept
+ {
+ try {
+ if (data)
+ return reinterpret_cast<_instance*>(data)->audio_mix(ts_out, audio_output, channels, sample_rate);
+ return false;
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ return false;
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ return false;
+ }
}
- static void _video_render_filter(void* data, gs_effect_t* effect) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->video_render(effect);
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- obs_source_skip_video_filter(reinterpret_cast<_instance*>(data)->get());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
- obs_source_skip_video_filter(reinterpret_cast<_instance*>(data)->get());
+ public /* Instance > Transition */:
+ static void _transition_start(void* data) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->transition_start();
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
- static struct obs_source_frame* _filter_video(void* data, struct obs_source_frame* frame) noexcept
- try {
- if (data)
- return reinterpret_cast<_instance*>(data)->filter_video(frame);
- return frame;
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- return frame;
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
- return frame;
+ static void _transition_stop(void* data) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->transition_stop();
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
- static struct obs_audio_data* _filter_audio(void* data, struct obs_audio_data* frame) noexcept
- try {
- if (data)
- return reinterpret_cast<_instance*>(data)->filter_audio(frame);
- return frame;
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- return frame;
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
- return frame;
+ public /* Instance > Resolution */:
+ void support_size(bool v)
+ {
+ if (v) {
+ _info.get_width = _get_width;
+ _info.get_height = _get_height;
+ } else {
+ _info.get_width = nullptr;
+ _info.get_height = nullptr;
+ }
+ }
+
+ static uint32_t _get_width(void* data) noexcept
+ {
+ try {
+ if (data)
+ return reinterpret_cast<_instance*>(data)->get_width();
+ return 0;
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ return 0;
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ return 0;
+ }
+ }
+
+ static uint32_t _get_height(void* data) noexcept
+ {
+ try {
+ if (data)
+ return reinterpret_cast<_instance*>(data)->get_height();
+ return 0;
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ return 0;
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ return 0;
+ }
+ }
+
+ public /* Instance > Children */:
+ void support_active_child_sources(bool v)
+ {
+ if (v) {
+ _info.enum_active_sources = _enum_active_sources;
+ } else {
+ _info.enum_active_sources = nullptr;
+ }
}
static void _enum_active_sources(void* data, obs_source_enum_proc_t enum_callback, void* param) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->enum_active_sources(enum_callback, param);
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->enum_active_sources(enum_callback, param);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
+ void support_child_sources(bool v)
+ {
+ if (v) {
+ _info.enum_all_sources = _enum_all_sources;
+ } else {
+ _info.enum_all_sources = nullptr;
+ }
+ }
+
+ static void _enum_all_sources(void* data, obs_source_enum_proc_t enum_callback, void* param) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->enum_all_sources(enum_callback, param);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
+ }
+
+ public /* Instance > Configuration */:
static void _load(void* data, obs_data_t* settings) noexcept
- try {
- auto priv = reinterpret_cast<_instance*>(data);
- if (priv) {
- uint64_t version = static_cast(obs_data_get_int(settings, S_VERSION));
- priv->migrate(settings, version);
- obs_data_set_int(settings, S_VERSION, static_cast(STREAMFX_VERSION));
- obs_data_set_string(settings, S_COMMIT, STREAMFX_COMMIT);
- priv->load(settings);
+ {
+ try {
+ auto priv = reinterpret_cast<_instance*>(data);
+ if (priv) {
+ uint64_t version = static_cast(obs_data_get_int(settings, S_VERSION));
+ priv->migrate(settings, version);
+ obs_data_set_int(settings, S_VERSION, static_cast(STREAMFX_VERSION));
+ obs_data_set_string(settings, S_COMMIT, STREAMFX_COMMIT);
+ priv->load(settings);
+ }
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
static void _update(void* data, obs_data_t* settings) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->update(settings);
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->update(settings);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
static void _save(void* data, obs_data_t* settings) noexcept
- try {
- if (data) {
- reinterpret_cast<_instance*>(data)->save(settings);
- obs_data_set_int(settings, S_VERSION, static_cast(STREAMFX_VERSION));
- obs_data_set_string(settings, S_COMMIT, STREAMFX_COMMIT);
+ {
+ try {
+ if (data) {
+ reinterpret_cast<_instance*>(data)->save(settings);
+ obs_data_set_int(settings, S_VERSION, static_cast(STREAMFX_VERSION));
+ obs_data_set_string(settings, S_COMMIT, STREAMFX_COMMIT);
+ }
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
+ }
+
+ public /* Instance > Activity Tracking */:
+ void support_activity_tracking(bool v)
+ {
+ if (v) {
+ _info.activate = _activate;
+ _info.deactivate = _deactivate;
+ } else {
+ _info.activate = nullptr;
+ _info.deactivate = nullptr;
+ }
+ }
+
+ static void _activate(void* data) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->activate();
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
+ }
+
+ static void _deactivate(void* data) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->deactivate();
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
+ }
+
+ public /* Instance > Visibility Tracking */:
+ void support_visibility_tracking(bool v)
+ {
+ if (v) {
+ _info.show = _show;
+ _info.hide = _hide;
+ } else {
+ _info.show = nullptr;
+ _info.hide = nullptr;
+ }
+ }
+
+ static void _show(void* data) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->show();
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
+ }
+
+ static void _hide(void* data) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->hide();
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
+ }
+
+ public /* Instance > Interaction */:
+ void support_interaction(bool v)
+ {
+ if (v) {
+ _info.output_flags |= (OBS_SOURCE_INTERACTION);
+ _info.mouse_click = _mouse_click;
+ _info.mouse_move = _mouse_move;
+ _info.mouse_wheel = _mouse_wheel;
+ _info.focus = _focus;
+ _info.key_click = _key_click;
+ } else {
+ _info.output_flags &= ~(OBS_SOURCE_INTERACTION);
+ _info.mouse_click = nullptr;
+ _info.mouse_move = nullptr;
+ _info.mouse_wheel = nullptr;
+ _info.focus = nullptr;
+ _info.key_click = nullptr;
}
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
- static void _mouse_click(void* data, const struct obs_mouse_event* event, int32_t type, bool mouse_up,
+ static void _mouse_click(void* data, const obs_mouse_event* event, int32_t type, bool mouse_up,
uint32_t click_count) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->mouse_click(event, type, mouse_up, click_count);
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
- }
-
- static void _mouse_move(void* data, const struct obs_mouse_event* event, bool mouse_leave) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->mouse_move(event, mouse_leave);
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
- }
-
- static void _mouse_wheel(void* data, const struct obs_mouse_event* event, int x_delta, int y_delta) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->mouse_wheel(event, x_delta, y_delta);
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->mouse_click(event, type, mouse_up, click_count);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
+ }
+
+ static void _mouse_move(void* data, const obs_mouse_event* event, bool mouse_leave) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->mouse_move(event, mouse_leave);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
+ }
+
+ static void _mouse_wheel(void* data, const obs_mouse_event* event, int x_delta, int y_delta) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->mouse_wheel(event, x_delta, y_delta);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
static void _focus(void* data, bool focus) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->focus(focus);
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->focus(focus);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
- static void _key_click(void* data, const struct obs_key_event* event, bool key_up) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->key_click(event, key_up);
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ static void _key_click(void* data, const obs_key_event* event, bool key_up) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->key_click(event, key_up);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
- static void _filter_remove(void* data, obs_source_t* source) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->filter_remove(source);
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ public /* Instance > Media Controls */:
+ void support_media_controls(bool v)
+ {
+ if (v) {
+ _info.output_flags |= (OBS_SOURCE_CONTROLLABLE_MEDIA);
+ _info.media_play_pause = _media_play_pause;
+ _info.media_restart = _media_restart;
+ _info.media_stop = _media_stop;
+ _info.media_next = _media_next;
+ _info.media_previous = _media_previous;
+ _info.media_get_duration = _media_get_duration;
+ _info.media_get_time = _media_get_time;
+ _info.media_set_time = _media_set_time;
+ _info.media_get_state = _media_get_state;
+ } else {
+ _info.output_flags &= ~(OBS_SOURCE_CONTROLLABLE_MEDIA);
+ _info.media_play_pause = nullptr;
+ _info.media_restart = nullptr;
+ _info.media_stop = nullptr;
+ _info.media_next = nullptr;
+ _info.media_previous = nullptr;
+ _info.media_get_duration = nullptr;
+ _info.media_get_time = nullptr;
+ _info.media_set_time = nullptr;
+ _info.media_get_state = nullptr;
+ }
}
- static bool _audio_render(void* data, uint64_t* ts_out, struct obs_source_audio_mix* audio_output,
- uint32_t mixers, std::size_t channels, std::size_t sample_rate) noexcept
- try {
- if (data)
- return reinterpret_cast<_instance*>(data)->audio_render(ts_out, audio_output, mixers, channels,
- sample_rate);
- return false;
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- return false;
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
- return false;
+ static void _media_play_pause(void* data, bool pause) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->media_play_pause(pause);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
- static void _enum_all_sources(void* data, obs_source_enum_proc_t enum_callback, void* param) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->enum_all_sources(enum_callback, param);
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ static void _media_restart(void* data) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->media_restart();
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
- static void _transition_start(void* data) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->transition_start();
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ static void _media_stop(void* data) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->media_stop();
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
- static void _transition_stop(void* data) noexcept
- try {
- if (data)
- reinterpret_cast<_instance*>(data)->transition_stop();
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ static void _media_next(void* data) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->media_next();
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
}
- static bool _audio_mix(void* data, uint64_t* ts_out, struct audio_output_data* audio_output,
- std::size_t channels, std::size_t sample_rate) noexcept
- try {
- if (data)
- return reinterpret_cast<_instance*>(data)->audio_mix(ts_out, audio_output, channels, sample_rate);
- return false;
- } catch (const std::exception& ex) {
- DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
- return false;
- } catch (...) {
- DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
- return false;
+ static void _media_previous(void* data) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->media_previous();
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
+ }
+
+ static int64_t _media_get_duration(void* data) noexcept
+ {
+ try {
+ if (data)
+ return reinterpret_cast<_instance*>(data)->media_get_duration();
+ return 0;
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ return 0;
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ return 0;
+ }
+ }
+
+ static int64_t _media_get_time(void* data) noexcept
+ {
+ try {
+ if (data)
+ return reinterpret_cast<_instance*>(data)->media_get_time();
+ return 0;
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ return 0;
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ return 0;
+ }
+ }
+
+ static void _media_set_time(void* data, int64_t milliseconds) noexcept
+ {
+ try {
+ if (data)
+ reinterpret_cast<_instance*>(data)->media_set_time(milliseconds);
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ }
+ }
+
+ static obs_media_state _media_get_state(void* data) noexcept
+ {
+ try {
+ if (data)
+ return reinterpret_cast<_instance*>(data)->media_get_state();
+ return OBS_MEDIA_STATE_NONE;
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ return OBS_MEDIA_STATE_NONE;
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ return OBS_MEDIA_STATE_NONE;
+ }
+ }
+
+ public /* Instance > Missing Files */:
+ void support_missing_files(bool v)
+ {
+ if (v) {
+ _info.missing_files = _missing_files;
+ } else {
+ _info.missing_files = nullptr;
+ }
+ }
+
+ static obs_missing_files_t* _missing_files(void* data)
+ {
+ try {
+ if (data)
+ return reinterpret_cast<_instance*>(data)->missing_files();
+ return nullptr;
+ } catch (const std::exception& ex) {
+ DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
+ return nullptr;
+ } catch (...) {
+ DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
+ return nullptr;
+ }
}
public:
@@ -555,51 +825,69 @@ namespace streamfx::obs {
class source_instance {
protected:
- obs_source_t* _self;
+ ::streamfx::obs::source _self;
public:
- source_instance(obs_data_t* settings, obs_source_t* source) : _self(source) {}
+ source_instance(obs_data_t* settings, obs_source_t* source) : _self(source, false, false) {}
virtual ~source_instance(){};
- virtual obs_source_t* get()
+ virtual ::streamfx::obs::source get()
{
return _self;
}
- virtual uint32_t get_width()
+ virtual void filter_remove(obs_source_t* source) {}
+
+ public /* Instance > Video */:
+ virtual void video_tick(float_t seconds) {}
+
+ virtual void video_render(gs_effect_t* effect) {}
+
+ virtual struct obs_source_frame* filter_video(struct obs_source_frame* frame)
{
- return 0;
+ return frame;
}
- virtual uint32_t get_height()
+ public /* Instance > Audio */:
+ virtual struct obs_audio_data* filter_audio(struct obs_audio_data* audio)
{
- return 0;
+ return audio;
}
- virtual void activate() {}
-
- virtual void deactivate() {}
-
- virtual void show() {}
+ virtual bool audio_render(uint64_t* ts_out, struct obs_source_audio_mix* audio_output, uint32_t mixers,
+ std::size_t channels, std::size_t sample_rate)
+ {
+ return false;
+ }
- virtual void hide() {}
+ virtual bool audio_mix(uint64_t* ts_out, struct audio_output_data* audio_output, std::size_t channels,
+ std::size_t sample_rate)
+ {
+ return false;
+ }
- virtual void video_tick(float_t seconds) {}
+ public /* Instance > Transition */:
+ virtual void transition_start() {}
- virtual void video_render(gs_effect_t* effect) {}
+ virtual void transition_stop() {}
- virtual struct obs_source_frame* filter_video(struct obs_source_frame* frame)
+ public /* Instance > Resolution */:
+ virtual uint32_t get_width()
{
- return frame;
+ return 0;
}
- virtual struct obs_audio_data* filter_audio(struct obs_audio_data* audio)
+ virtual uint32_t get_height()
{
- return audio;
+ return 0;
}
+ public /* Instance > Children */:
virtual void enum_active_sources(obs_source_enum_proc_t enum_callback, void* param) {}
+ virtual void enum_all_sources(obs_source_enum_proc_t enum_callback, void* param) {}
+
+ public /* Instance > Configuration */:
virtual void load(obs_data_t* settings) {}
virtual void migrate(obs_data_t* settings, uint64_t version) {}
@@ -608,36 +896,60 @@ namespace streamfx::obs {
virtual void save(obs_data_t* settings) {}
- virtual void mouse_click(const struct obs_mouse_event* event, int32_t type, bool mouse_up, uint32_t click_count)
- {}
+ public /* Instance > Activity Tracking */:
+ virtual void activate() {}
+
+ virtual void deactivate() {}
+
+ public /* Instance > Visibility Tracking */:
+ virtual void show() {}
+
+ virtual void hide() {}
+
+ public /* Instance > Interaction */:
+ virtual void mouse_click(const obs_mouse_event* event, int32_t type, bool mouse_up, uint32_t click_count) {}
- virtual void mouse_move(const struct obs_mouse_event* event, bool mouse_leave) {}
+ virtual void mouse_move(const obs_mouse_event* event, bool mouse_leave) {}
- virtual void mouse_wheel(const struct obs_mouse_event* event, int32_t x_delta, int32_t y_delta) {}
+ virtual void mouse_wheel(const obs_mouse_event* event, int32_t x_delta, int32_t y_delta) {}
virtual void focus(bool focus) {}
- virtual void key_click(const struct obs_key_event* event, bool key_up) {}
+ virtual void key_click(const obs_key_event* event, bool key_up) {}
- virtual void filter_remove(obs_source_t* source) {}
+ public /* Media Controls */:
+ virtual void media_play_pause(bool pause){};
- virtual bool audio_render(uint64_t* ts_out, struct obs_source_audio_mix* audio_output, uint32_t mixers,
- std::size_t channels, std::size_t sample_rate)
+ virtual void media_restart(){};
+
+ virtual void media_stop(){};
+
+ virtual void media_next(){};
+
+ virtual void media_previous(){};
+
+ virtual int64_t media_get_duration()
{
- return false;
+ return 0;
}
- virtual void enum_all_sources(obs_source_enum_proc_t enum_callback, void* param) {}
-
- virtual void transition_start() {}
+ virtual int64_t media_get_time()
+ {
+ return 0;
+ }
- virtual void transition_stop() {}
+ virtual void media_set_time(int64_t milliseconds) {}
- virtual bool audio_mix(uint64_t* ts_out, struct audio_output_data* audio_output, std::size_t channels,
- std::size_t sample_rate)
+ virtual obs_media_state media_get_state()
{
- return false;
+ return OBS_MEDIA_STATE_NONE;
}
+
+ public /* Missing Files */:
+ virtual obs_missing_files_t* missing_files()
+ {
+ return nullptr;
+ };
};
} // namespace streamfx::obs
diff --git a/source/sources/source-mirror.cpp b/source/sources/source-mirror.cpp
index 8a4e2fe3a2..86b452cd5a 100644
--- a/source/sources/source-mirror.cpp
+++ b/source/sources/source-mirror.cpp
@@ -296,8 +296,8 @@ mirror_factory::mirror_factory()
_info.type = OBS_SOURCE_TYPE_INPUT;
_info.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW | OBS_SOURCE_AUDIO;
- set_have_active_child_sources(true);
- set_have_child_sources(true);
+ support_active_child_sources(true);
+ support_child_sources(true);
finish_setup();
register_proxy("obs-stream-effects-source-mirror");
}
diff --git a/source/sources/source-shader.cpp b/source/sources/source-shader.cpp
index d0bd5b3cf2..c8098e3775 100644
--- a/source/sources/source-shader.cpp
+++ b/source/sources/source-shader.cpp
@@ -132,8 +132,8 @@ shader_factory::shader_factory()
_info.type = OBS_SOURCE_TYPE_INPUT;
_info.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW;
- set_activity_tracking_enabled(true);
- set_visibility_tracking_enabled(true);
+ support_activity_tracking(true);
+ support_visibility_tracking(true);
finish_setup();
register_proxy("obs-stream-effects-source-shader");
}
diff --git a/source/transitions/transition-shader.cpp b/source/transitions/transition-shader.cpp
index 49c2cf4545..0dad6de860 100644
--- a/source/transitions/transition-shader.cpp
+++ b/source/transitions/transition-shader.cpp
@@ -145,7 +145,7 @@ shader_factory::shader_factory()
_info.type = OBS_SOURCE_TYPE_TRANSITION;
_info.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW;
- //set_activity_tracking_enabled(true); // Handled via transition start/stop
+ //support_activity_tracking(true); // Handled via transition start/stop
finish_setup();
register_proxy("obs-stream-effects-transition-shader");
}
From 39548e760dd4d1f4229ad61d5585abd69b5f197d Mon Sep 17 00:00:00 2001
From: Michael Fabian 'Xaymar' Dirks
Date: Tue, 10 May 2022 20:51:59 +0200
Subject: [PATCH 018/164] obs/tools: Replace scene_contains_source
As the recursion checking code is somewhat broken in libOBS, we need something to prevent accidental recursion from occurring. While the alternative fix is to simply make all of libOBS support recursion, unfortunately that endeavor would be too large for a single person to take on.
---
source/obs/obs-tools.cpp | 121 ++++++++++++++++++++++++---------------
source/obs/obs-tools.hpp | 3 +-
2 files changed, 77 insertions(+), 47 deletions(-)
diff --git a/source/obs/obs-tools.cpp b/source/obs/obs-tools.cpp
index 11ae4a2de9..6099a735c3 100644
--- a/source/obs/obs-tools.cpp
+++ b/source/obs/obs-tools.cpp
@@ -19,67 +19,96 @@
#include "obs-tools.hpp"
#include