plugin: Replace long descriptions with "Open Manual" button

While the long descriptions were useful, keeping the updated and translated is pretty much impossible. Technology moves fast and not everyone that translates the project knows a lot about technology.

Therefore the long descriptions have now been replaced with a button that opens the wiki page for the feature instead. This should drastically reduce the number of help cases, and improve the translation coverage at the same time.
This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2021-04-17 01:43:30 +02:00
parent 48ba34538e
commit 5a65cf3525
38 changed files with 313 additions and 426 deletions

View File

@ -1,9 +1,14 @@
# Generic
Advanced="Advanced Options"
Manual.Open="Open Manual"
# Channels
Channel.Red="Red"
Channel.Green="Green"
Channel.Blue="Blue"
Channel.Alpha="Alpha"
# File Types
FileType.Image="Image"
FileType.Images="Images"
FileType.Video="Video"
@ -12,13 +17,19 @@ FileType.Sound="Sound"
FileType.Sounds="Sounds"
FileType.Effect="Effect"
FileType.Effects="Effects"
# Source Types
SourceType.Source="Source"
SourceType.Scene="Scene"
# Alignment
Alignment.Center="Center"
Alignment.Left="Left"
Alignment.Right="Right"
Alignment.Top="Top"
Alignment.Bottom="Bottom"
# States
State.Disabled="Disabled"
State.Enabled="Enabled"
State.Manual="Manual"
@ -62,56 +73,36 @@ UI.Updater.Menu.Channel.Testing="Testing"
# Blur
Blur.Type.Box="Box"
Blur.Type.Box.Description="The 'Box' blur takes the average of all pixels in the given area, which results in its distinct box shape."
Blur.Type.BoxLinear="Box Linear"
Blur.Type.BoxLinear.Description="This is a slightly optimized version of the 'Box' blur, which attempts to halve the required samples at the cost of some quality."
Blur.Type.Gaussian="Gaussian"
Blur.Type.Gaussian.Description="The 'Gaussian' uses the gaussian bell curve as a weight for each pixel to add in the given area, which results in a smooth shape. This is a very expensive blur, and should be avoided unless necessary - consider using 'Dual Filtering' for larger blur sizes instead."
Blur.Type.GaussianLinear="Gaussian Linear"
Blur.Type.GaussianLinear.Description="This is a slightly optimized version of the 'Gaussian' blur, which attempts to halve the required samples at the cost of quality. In almost all cases it is recommended to instead use 'Dual Filtering' if performance matters."
Blur.Type.DualFiltering="Dual Filtering"
Blur.Type.DualFiltering.Description="The 'Dual Filtering' method is an approximation of 'Gaussian' blur which achieves a ~95% identical image to 'Gaussian' blur, though has less features available. It's performance impact should be minimal to unnoticable, which makes it perfect for large blur sizes."
Blur.Subtype.Area="Area"
Blur.Subtype.Area.Description="Area blurring is the default way to blur and blurs both horizontally and vertically.\nThe effect can be compared to an object that is out of focus in a camera."
Blur.Subtype.Directional="Directional"
Blur.Subtype.Directional.Description="Directional blurring allows control of the exact direction in which blur should happen.\nThe effect is similar to a camera in motion, or an object being in motion."
Blur.Subtype.Rotational="Rotational"
Blur.Subtype.Rotational.Description="Rotational blurring performs blurring in a circle around a center point.\nThe effect is very similar to rolling a camera around the center point of its sensor."
Blur.Subtype.Zoom="Zoom"
Blur.Subtype.Zoom.Description="Zoom blurring performs blurring in a line towards a center point.\nThe effect is similar to moving a camera forward towards to or backwards away from something."
# Mip Generator
MipGenerator="Mip-Map Generator"
MipGenerator.Description="Which Mip-Map generator should be used?"
MipGenerator.Point="Point"
MipGenerator.Point.Description="Simple point sampling resulting in a very aliased image, comparable to no Mip-Mapping at all."
MipGenerator.Linear="Linear"
MipGenerator.Linear.Description="Linear sampled Mip-Maps which can be quickly generated, but only result in okay looking smooth Mip-Maps."
MipGenerator.Sharpen="Sharpen"
MipGenerator.Sharpen.Description="Linear sampled Mip-Maps with additional sharpen, allowing details to be kept in the Mip-Maps."
MipGenerator.Smoothen="Smoothen"
MipGenerator.Smoothen.Description="Linear sampled Mip-Maps with additional smoothing, reducing details in the Mip-Maps."
MipGenerator.Bicubic="Bicubic"
MipGenerator.Lanczos="Lanczos"
MipGenerator.Intensity="Intensity"
MipGenerator.Intensity.Description="Intensity of the generator."
# Shader
Shader="Shader"
Shader.Refresh="Refresh Options and Parameters"
Shader.Shader="Shader Options"
Shader.Shader.File="File"
Shader.Shader.File.Description="Which file should be loaded as a shader?"
Shader.Shader.Technique="Technique"
Shader.Shader.Technique.Description="What shader technique should be drawn?"
Shader.Shader.Size="Size"
Shader.Shader.Size.Description="Size of the source, can be one of the following units:\n- '###.##%' which is relative to the parent source, filter or scene.\n- '###' to specify the size in pixels. (Default)\nIf the value can't be parsed, it will be treated as 100%."
Shader.Shader.Size.Width="Width"
Shader.Shader.Size.Height="Height"
Shader.Shader.Seed="Randomization Seed"
Shader.Shader.Seed.Description="Seed used for the Per-Instance, Per-Activation and Per-Frame random values.\nThe same seed will always produce identical results if the identical number of runs were made."
Shader.Parameters="Shader Parameters"
Shader.Parameters.Description="All the shader parameters that the loaded shader offers.\nMake sure to refresh these every now and then."
Filter.Shader="Shader"
Source.Shader="Shader"
Transition.Shader="Shader"
@ -119,56 +110,34 @@ Transition.Shader="Shader"
# Filter - Blur
Filter.Blur="Blur"
Filter.Blur.Type="Type"
Filter.Blur.Type.Description="The type of blur to apply."
Filter.Blur.Subtype="Subtype"
Filter.Blur.Subtype.Description="The way this blur should be applied."
Filter.Blur.Size="Size"
Filter.Blur.Size.Description="Size of the blur filter to apply. Large sizes may have a negative effect on performance."
Filter.Blur.Angle="Angle (Degrees)"
Filter.Blur.Angle.Description="Angle of the Blur"
Filter.Blur.Center.X="Center (X) (Percent)"
Filter.Blur.Center.X.Description="The horizontal center of the blur effect, in percent."
Filter.Blur.Center.Y="Center (Y) (Percent)"
Filter.Blur.Center.Y.Description="The vertical center of the blur effect, in percent."
Filter.Blur.StepScale="Step Scaling"
Filter.Blur.StepScale.Description="Scale the texel step used in the Blur shader, which allows for smaller Blur sizes to cover more space, at the cost of some quality.\nCan be combined with Directional Blur to change the behavior drastically."
Filter.Blur.StepScale.X="Step Scale X"
Filter.Blur.StepScale.Y="Step Scale Y"
Filter.Blur.Mask="Apply a Mask"
Filter.Blur.Mask.Description="Apply a mask to the area that needs to be blurred, which allows for more control over the blurred area."
Filter.Blur.Mask.Type="Mask Type"
Filter.Blur.Mask.Type.Description="What kind of mask to you want to apply?"
Filter.Blur.Mask.Type.Region="Region"
Filter.Blur.Mask.Type.Image="Image"
Filter.Blur.Mask.Type.Source="Source"
Filter.Blur.Mask.Region.Left="Left Edge"
Filter.Blur.Mask.Region.Left.Description="Distance to left edge of the source in percent."
Filter.Blur.Mask.Region.Top="Top Edge"
Filter.Blur.Mask.Region.Top.Description="Distance to top edge of the source in percent."
Filter.Blur.Mask.Region.Right="Right Edge"
Filter.Blur.Mask.Region.Right.Description="Distance to right edge of the source in percent."
Filter.Blur.Mask.Region.Bottom="Bottom Edge"
Filter.Blur.Mask.Region.Bottom.Description="Distance to bottom edge of the source in percent."
Filter.Blur.Mask.Region.Feather="Feather Area"
Filter.Blur.Mask.Region.Feather.Description="The size of the feathering area in percent of the source size.\nFeathering allows for a smooth gradient between blurred and original image."
Filter.Blur.Mask.Region.Feather.Shift="Feather Shift"
Filter.Blur.Mask.Region.Feather.Shift.Description="The shift of the feathering area in percent.\nPositive values push the feathering area into the region, while negative values push the feathering area out of the region."
Filter.Blur.Mask.Region.Invert="Invert Region"
Filter.Blur.Mask.Region.Invert.Description="Invert the region so that everything but this area is blurred."
Filter.Blur.Mask.Image="Image Mask"
Filter.Blur.Mask.Image.Description="Image to use for the mask."
Filter.Blur.Mask.Source="Source Mask"
Filter.Blur.Mask.Source.Description="Source to use for the mask."
Filter.Blur.Mask.Color="Mask Color Filter"
Filter.Blur.Mask.Color.Description="Filter the mask by this color before applying it."
Filter.Blur.Mask.Alpha="Mask Alpha Filter"
Filter.Blur.Mask.Alpha.Description="Filter the mask by this alpha value before applying it."
Filter.Blur.Mask.Multiplier="Mask Multiplier"
Filter.Blur.Mask.Multiplier.Description="Multiply the final mask value by this value."
# Filter - Color Grade
Filter.ColorGrade="Color Grading"
Filter.ColorGrade.Tool="Color Grading Tool"
Filter.ColorGrade.Lift="Lift"
Filter.ColorGrade.Lift.Red="Red Lift"
Filter.ColorGrade.Lift.Green="Green Lift"
@ -216,7 +185,6 @@ Filter.ColorGrade.Correction.Saturation="Saturation"
Filter.ColorGrade.Correction.Lightness="Lightness"
Filter.ColorGrade.Correction.Contrast="Contrast"
Filter.ColorGrade.RenderMode="Render Mode"
Filter.ColorGrade.RenderMode.Description="The color grading effect is an expensive operation on the GPU, so two rendering modes exist:\n- 'Direct Rendering' calculates the entire color grade for every single pixel.\n- '#-Bit Look-Up Table' calculates a LUT first, and then renders using said LUT instead, which\nis significantly faster but sacrifices some accuracy. A 2-Bit LUT will be super fast but it\nwill not be as accurate as a 8-Bit LUT would be."
Filter.ColorGrade.RenderMode.Direct="Direct Rendering"
Filter.ColorGrade.RenderMode.LUT.2Bit="2-Bit Look-Up Table"
Filter.ColorGrade.RenderMode.LUT.4Bit="4-Bit Look-Up Table"
@ -227,41 +195,29 @@ Filter.ColorGrade.RenderMode.LUT.10Bit="10-Bit Look-Up Table"
# Filter - Displacement
Filter.Displacement="Displacement Mapping"
Filter.Displacement.File="File"
Filter.Displacement.File.Description="Image file to use as the displacement map."
Filter.Displacement.Scale="Scale"
Filter.Displacement.Scale.Description="Scale of the displacement, either in pixels (Scale Type = 100.0) or in UVs (Scale Type = 0.0)."
Filter.Displacement.Scale.Type="Scaling Type"
Filter.Displacement.Scale.Type.Description="Type of the displacement scale, with\nvalues closer to 0.00 being UV space and\nvalues closer to 100.00 being Pixel space."
# Filter - Dynamic Mask
Filter.DynamicMask="Dynamic Mask"
Filter.DynamicMask.Input="Input Source"
Filter.DynamicMask.Input.Description="Input source to use for all further calculations, may also be left blank to use itself as the input.\nSets 'source' in the calculation 'mask[%s] = (base[%s] + value[%s][Red] * source[Red] + value[%s][Green] * source[Green] + value[%s][Blue] * source[Blue] + value[%s] * source[Alpha]) * multiplier[%s]'."
Filter.DynamicMask.Channel="%s Channel"
Filter.DynamicMask.Channel.Value="Base Value"
Filter.DynamicMask.Channel.Value.Description="The base value before everything else is added to it.\nSets 'base[%s]' in the calculation 'mask[%s] = (base[%s] + value[%s][Red] * source[Red] + value[%s][Green] * source[Green] + value[%s][Blue] * source[Blue] + value[%s] * source[Alpha]) * multiplier[%s]'."
Filter.DynamicMask.Channel.Multiplier="Multiplier"
Filter.DynamicMask.Channel.Multiplier.Description="The multiplier value that everything is multiplied with.\nSets 'multiplier[%s]' in the calculation 'mask[%s] = (base[%s] + value[%s][Red] * source[Red] + value[%s][Green] * source[Green] + value[%s][Blue] * source[Blue] + value[%s] * source[Alpha]) * multiplier[%s]'."
Filter.DynamicMask.Channel.Input="%s Input Value"
Filter.DynamicMask.Channel.Input.Description="The input value for channel %s.\nSets 'value[%s][%s]' in the calculation 'mask[%s] = (base[%s] + value[%s][Red] * source[Red] + value[%s][Green] * source[Green] + value[%s][Blue] * source[Blue] + value[%s][Alpha] * source[Alpha]) * multiplier[%s]'."
# Filter - Nvidia Face Tracking
Filter.Nvidia.FaceTracking="NVIDIA Face Tracking"
Filter.Nvidia.FaceTracking.ROI="Region of Interest"
Filter.Nvidia.FaceTracking.ROI.Zoom="Zoom"
Filter.Nvidia.FaceTracking.ROI.Zoom.Description="Restrict the maximum zoom level based on the current maximum and minimum zoom level.\nValues above 100% zoom into the face, while values below 100% will keep their distance from the face."
Filter.NVidia.FaceTracking.ROI.Offset="Offset"
Filter.NVidia.FaceTracking.ROI.Offset.X="X"
Filter.NVidia.FaceTracking.ROI.Offset.X.Description="Horizontal offset relative to center of the detected face."
Filter.Nvidia.FaceTracking.ROI.Offset.Y="Y"
Filter.NVidia.FaceTracking.ROI.Offset.Y.Description="Vertical offset relative to center of the detected face."
Filter.Nvidia.FaceTracking.ROI.Stability="Stability"
Filter.NVidia.FaceTracking.ROI.Stability.Description="Controls the responsiveness of the tracking filter to filter out noisy and/or bad results.\nValues closer to 0% will be quicker but more noisy, while values closer to 100% will be slower but noise free.\nDue to unique noise patterns of modern Webcams, there is no universal setting for this."
# Filter - SDF Effects
Filter.SDFEffects="SDF Effects"
Filter.SDFEffects.Shadow.Inner="Inner Shadow"
Filter.SDFEffects.Shadow.Inner.Description="Draw a shadow on the inside of the source?"
Filter.SDFEffects.Shadow.Inner.Range.Minimum="Inner Shadow Minimum Distance"
Filter.SDFEffects.Shadow.Inner.Range.Maximum="Inner Shadow Maximum Distance"
Filter.SDFEffects.Shadow.Inner.Offset.X="Inner Shadow Offset X"
@ -269,7 +225,6 @@ Filter.SDFEffects.Shadow.Inner.Offset.Y="Inner Shadow Offset Y"
Filter.SDFEffects.Shadow.Inner.Color="Inner Shadow Color"
Filter.SDFEffects.Shadow.Inner.Alpha="Inner Shadow Alpha"
Filter.SDFEffects.Shadow.Outer="Outer Shadow"
Filter.SDFEffects.Shadow.Outer.Description="Draw a shadow on the outside of the source?"
Filter.SDFEffects.Shadow.Outer.Range.Minimum="Outer Shadow Minimum Distance"
Filter.SDFEffects.Shadow.Outer.Range.Maximum="Outer Shadow Maximum Distance"
Filter.SDFEffects.Shadow.Outer.Offset.X="Outer Shadow Offset X"
@ -277,70 +232,45 @@ Filter.SDFEffects.Shadow.Outer.Offset.Y="Outer Shadow Offset Y"
Filter.SDFEffects.Shadow.Outer.Color="Outer Shadow Color"
Filter.SDFEffects.Shadow.Outer.Alpha="Outer Shadow Alpha"
Filter.SDFEffects.Glow.Outer="Outer Glow"
Filter.SDFEffects.Glow.Outer.Description="Draw an outline?"
Filter.SDFEffects.Glow.Outer.Color="Outer Glow Color"
Filter.SDFEffects.Glow.Outer.Color.Description="Color of the Glow."
Filter.SDFEffects.Glow.Outer.Alpha="Outer Glow Alpha"
Filter.SDFEffects.Glow.Outer.Alpha.Description="Alpha of the Glow."
Filter.SDFEffects.Glow.Outer.Width="Outer Glow Width"
Filter.SDFEffects.Glow.Outer.Width.Description="Size of the glow from the center line."
Filter.SDFEffects.Glow.Outer.Sharpness="Outer Glow Sharpness"
Filter.SDFEffects.Glow.Outer.Sharpness.Description="The sharpness of the glow in percent, with higher values being sharper."
Filter.SDFEffects.Glow.Inner="Inner Glow"
Filter.SDFEffects.Glow.Inner.Description="Draw an outline?"
Filter.SDFEffects.Glow.Inner.Color="Inner Glow Color"
Filter.SDFEffects.Glow.Inner.Color.Description="Color of the Glow."
Filter.SDFEffects.Glow.Inner.Alpha="Inner Glow Alpha"
Filter.SDFEffects.Glow.Inner.Alpha.Description="Alpha of the Glow."
Filter.SDFEffects.Glow.Inner.Width="Inner Glow Width"
Filter.SDFEffects.Glow.Inner.Width.Description="Size of the glow from the center."
Filter.SDFEffects.Glow.Inner.Sharpness="Inner Glow Sharpness"
Filter.SDFEffects.Glow.Inner.Sharpness.Description="The sharpness of the glow in percent, with higher values being sharper."
Filter.SDFEffects.Outline="Outline"
Filter.SDFEffects.Outline.Description="Draw an outline?"
Filter.SDFEffects.Outline.Color="Outline Color"
Filter.SDFEffects.Outline.Color.Description="Color of the Outline."
Filter.SDFEffects.Outline.Alpha="Outline Alpha"
Filter.SDFEffects.Outline.Alpha.Description="Alpha of the Outline."
Filter.SDFEffects.Outline.Width="Outline Width"
Filter.SDFEffects.Outline.Width.Description="Size of the outline in both direction from the center."
Filter.SDFEffects.Outline.Offset="Outline Offset"
Filter.SDFEffects.Outline.Offset.Description="Moves the center line by the given offset.\nA positive offset pushes the outline away from the source, while a negative one pulls it into the source."
Filter.SDFEffects.Outline.Sharpness="Outline Sharpness"
Filter.SDFEffects.Outline.Sharpness.Description="The sharpness of the outline in percent, with higher values being sharper."
Filter.SDFEffects.SDF.Scale="SDF Texture Scale"
Filter.SDFEffects.SDF.Scale.Description="Percentage to scale the SDF Texture Size by, relative to the Source Size.\nA higher value results in better quality, but slower updates,\n while lower values result in faster updates, but lower quality."
Filter.SDFEffects.SDF.Threshold="SDF Alpha Threshold"
Filter.SDFEffects.SDF.Threshold.Description="Minimum opacity value in percent for SDF generation to consider the pixel solid."
# Filter - Transform
Filter.Transform="3D Transform"
Filter.Transform.Camera="Camera"
Filter.Transform.Camera.Description="Projection mode used by the camera."
Filter.Transform.Camera.Orthographic="Orthographic"
Filter.Transform.Camera.Perspective="Perspective"
Filter.Transform.Camera.FieldOfView="Field Of View"
Filter.Transform.Camera.FieldOfView.Description="Vertical Field of View of the camera."
Filter.Transform.Position="Position"
Filter.Transform.Position.Description="Position of the rendered quad."
Filter.Transform.Position.X="X"
Filter.Transform.Position.Y="Y"
Filter.Transform.Position.Z="Z"
Filter.Transform.Scale="Scale"
Filter.Transform.Scale.Description="Scale of the rendered quad."
Filter.Transform.Scale.X="X"
Filter.Transform.Scale.Y="Y"
Filter.Transform.Shear="Shear"
Filter.Transform.Shear.Description="Shearing of the rendered quad."
Filter.Transform.Shear.X="X"
Filter.Transform.Shear.Y="Y"
Filter.Transform.Rotation="Rotation"
Filter.Transform.Rotation.Description="Euler rotation of the rendered quad, applied using the rotation order."
Filter.Transform.Rotation.X="Pitch (X)"
Filter.Transform.Rotation.Y="Yaw (Y)"
Filter.Transform.Rotation.Z="Roll (Z)"
Filter.Transform.Rotation.Order="Rotation Order"
Filter.Transform.Rotation.Order.Description="The order in which to apply the euler angles to the rendered quad."
Filter.Transform.Rotation.Order.XYZ="Pitch, Yaw, Roll"
Filter.Transform.Rotation.Order.XZY="Pitch, Roll, Yaw"
Filter.Transform.Rotation.Order.YXZ="Yaw, Pitch, Roll"
@ -348,16 +278,12 @@ Filter.Transform.Rotation.Order.YZX="Yaw, Roll, Pitch"
Filter.Transform.Rotation.Order.ZXY="Roll, Pitch, Yaw"
Filter.Transform.Rotation.Order.ZYX="Roll, Yaw, Pitch"
Filter.Transform.Mipmapping="Enable Mipmapping"
Filter.Transform.Mipmapping.Description="Generate mipmaps for the source, so that angled and far away parts are smoother."
# Source - Mirror
Source.Mirror="Source Mirror"
Source.Mirror.Source="Source"
Source.Mirror.Source.Description="Which Source should be mirrored?"
Source.Mirror.Source.Audio="Enable Audio"
Source.Mirror.Source.Audio.Description="Enables audio mirroring from this source."
Source.Mirror.Source.Audio.Layout="Audio Layout"
Source.Mirror.Source.Audio.Layout.Description="Override the audio layout if the automatically detected one doesn't match the source.\nThis does not perform down or upmixing of any kind."
Source.Mirror.Source.Audio.Layout.Unknown="Unknown"
Source.Mirror.Source.Audio.Layout.Mono="Mono"
Source.Mirror.Source.Audio.Layout.Stereo="Stereo"
@ -374,9 +300,7 @@ Codec.H264.Profile.baseline="Baseline"
Codec.H264.Profile.main="Main"
Codec.H264.Profile.high="High"
Codec.H264.Profile.high444p="High 4:4:4 Predictive"
Codec.H264.Profile.Description="H.264 profile determines which features of the codec can be used.\nHigh 4:4:4 Predictive is required for YUV 4:4:4 color space."
Codec.H264.Level="Level"
Codec.H264.Level.Description="Level determines the upper limits of resolution, frame rate and bitrate for the video."
# Codec: HEVC
Codec.HEVC="HEVC"
@ -384,13 +308,10 @@ Codec.HEVC.Profile="Profile"
Codec.HEVC.Profile.main="Main"
Codec.HEVC.Profile.main10="Main 10-bit"
Codec.HEVC.Profile.rext="Range Extended"
Codec.HEVC.Profile.Description="H.265 profile determines which features of the codec can be used."
Codec.HEVC.Tier="Tier"
Codec.HEVC.Tier.main="Main"
Codec.HEVC.Tier.high="High"
Codec.HEVC.Tier.Description="H.265 tier determines the bitrate guidelines used for the video."
Codec.HEVC.Level="Level"
Codec.HEVC.Level.Description="Level determines the upper limits of resolution and frame rate."
# Codec: Apple ProRes
Codec.ProRes.Profile="Profile"
@ -405,78 +326,52 @@ Codec.ProRes.Profile.AP4X="4444 Extreme Quality/XQ (AP4X)"
FFmpegEncoder="FFmpeg Options"
FFmpegEncoder.Suffix=" (via FFmpeg)"
FFmpegEncoder.CustomSettings="Custom Settings"
FFmpegEncoder.CustomSettings.Description="Override any options shown (or not shown) above with your own.\nThe format is similar to that of the FFmpeg command line:\n -key=value -key2=value2 -key3='quoted value'"
FFmpegEncoder.Threads="Number of Threads"
FFmpegEncoder.Threads.Description="The number of threads to use for encoding, if supported by the encoder.\nA value of 0 is equal to 'auto-detect' and may result in excessive CPU usage."
FFmpegEncoder.ColorFormat="Override Color Format"
FFmpegEncoder.ColorFormat.Description="Overriding the color format can unlock higher quality, but might cause additional stress.\nNot all encoders support all color formats, and you might end up causing errors or corrupted video due to this."
FFmpegEncoder.StandardCompliance="Standard Compliance"
FFmpegEncoder.StandardCompliance.Description="How strict should the encoder keep to the standard? A strictness below 'Normal' may cause issues with playback."
FFmpegEncoder.StandardCompliance.VeryStrict="Very Strict"
FFmpegEncoder.StandardCompliance.Strict="Strict"
FFmpegEncoder.StandardCompliance.Normal="Normal"
FFmpegEncoder.StandardCompliance.Unofficial="Unofficial"
FFmpegEncoder.StandardCompliance.Experimental="Experimental"
FFmpegEncoder.GPU="GPU"
FFmpegEncoder.GPU.Description="For multiple GPU systems, selects which GPU to use as the main encoder"
FFmpegEncoder.KeyFrames="Key Frames"
FFmpegEncoder.KeyFrames.IntervalType="Interval Type"
FFmpegEncoder.KeyFrames.IntervalType.Frames="Frames"
FFmpegEncoder.KeyFrames.IntervalType.Seconds="Seconds"
FFmpegEncoder.KeyFrames.IntervalType.Description="Keyframe interval type"
FFmpegEncoder.KeyFrames.Interval.Description="Distance between key frames, in frames or seconds."
FFmpegEncoder.KeyFrames.Interval="Interval"
# Encoder: AMF
FFmpegEncoder.AMF.Preset="Preset"
FFmpegEncoder.AMF.Preset.Description="The preset to use for encoding, which sets up internal values in the driver for encoding.\nThe names roughly match the expected encoding speed, but quality varies.\nIt is entirely possible to get a better quality with Balanced than with Quality at low bitrates."
FFmpegEncoder.AMF.Preset.Speed="Speed"
FFmpegEncoder.AMF.Preset.Balanced="Balanced"
FFmpegEncoder.AMF.Preset.Quality="Quality"
FFmpegEncoder.AMF.RateControl="Rate Control Options"
FFmpegEncoder.AMF.RateControl.Mode="Mode"
FFmpegEncoder.AMF.RateControl.Mode.Description="Rate control mode selection"
FFmpegEncoder.AMF.RateControl.Mode.CQP="Constant Quantization Parameter"
FFmpegEncoder.AMF.RateControl.Mode.CQP.Description="A flat compression ratio with no regard for bit rates."
FFmpegEncoder.AMF.RateControl.Mode.VBR_PEAK="Variable Bitrate (Peak Constrained)"
FFmpegEncoder.AMF.RateControl.Mode.VBR_PEAK.Description="TODO"
FFmpegEncoder.AMF.RateControl.Mode.VBR_LATENCY="Variable Bitrate (Latency Constrained)"
FFmpegEncoder.AMF.RateControl.Mode.VBR_LATENCY.Description="TODO"
FFmpegEncoder.AMF.RateControl.Mode.CBR="Constant Bitrate"
FFmpegEncoder.AMF.RateControl.Mode.CBR.Description="Compresses footage so that it matches the target bitrate over the duration of\none second. This comes at a cost in quality during high motion scenes or\nscenes with flickering brightness like often seen in RPGs."
FFmpegEncoder.AMF.RateControl.LookAhead="Look Ahead"
FFmpegEncoder.AMF.RateControl.LookAhead.Description="Look ahead in the encoding, slightly increasing latency but improving bitrate distribution over time."
FFmpegEncoder.AMF.RateControl.FrameSkipping="Frame Skipping"
FFmpegEncoder.AMF.RateControl.FrameSkipping.Description="Allow skipping frames to meet the bitrate target/maximum."
FFmpegEncoder.AMF.RateControl.Limits="Limits"
FFmpegEncoder.AMF.RateControl.Limits.BufferSize="Buffer Size"
FFmpegEncoder.AMF.RateControl.Limits.BufferSize.Description="Specifies the buffer size used for bitrate constrained modes.\nIdeally set to (KeyFrame Interval In Seconds * Bitrate Target), so at 2 seconds and 6000 kbit it should be 12000."
FFmpegEncoder.AMF.RateControl.Limits.Bitrate.Target="Target Bitrate"
FFmpegEncoder.AMF.RateControl.Limits.Bitrate.Maximum="Maximum Bitrate"
FFmpegEncoder.AMF.RateControl.QP="Quantization Parameters"
FFmpegEncoder.AMF.RateControl.QP.I="I-Frame QP"
FFmpegEncoder.AMF.RateControl.QP.I.Description="Quantization parameter for I-Frames.\nSmaller values mean better quality in exchange for higher bitrate, while higher values mean less bitrate in exchange for less quality."
FFmpegEncoder.AMF.RateControl.QP.P="P-Frame QP"
FFmpegEncoder.AMF.RateControl.QP.P.Description="Quantization parameter for P-Frames.\nSmaller values mean better quality in exchange for higher bitrate, while higher values mean less bitrate in exchange for less quality."
FFmpegEncoder.AMF.RateControl.QP.B="B-Frame QP"
FFmpegEncoder.AMF.RateControl.QP.B.Description="Quantization parameter for B-Frames.\nSmaller values mean better quality in exchange for higher bitrate, while higher values mean less bitrate in exchange for less quality."
FFmpegEncoder.AMF.Other="Other Options"
FFmpegEncoder.AMF.Other.BFrames="Maximum B-Frames"
FFmpegEncoder.AMF.Other.BFrames.Description="Maximum number of B-Frames to insert into the encoded bitstream.\nActual number of B-Frames may be lower depending on content and lookahead settings.\nB-Frames may not be supported on all AMD GPUs."
FFmpegEncoder.AMF.Other.BFrameReferences="B-Frame References"
FFmpegEncoder.AMF.Other.BFrameReferences.Description="Enable references to B-Frames, which can improve quality but reduces encoder performance drastically."
FFmpegEncoder.AMF.Other.ReferenceFrames="Reference Frames"
FFmpegEncoder.AMF.Other.ReferenceFrames.Description="Maximum number of reference frames to create in the encoded footage.\nActual number may be lower and is decided by the encoder."
FFmpegEncoder.AMF.Other.EnforceHRD="Enforce HRD"
FFmpegEncoder.AMF.Other.EnforceHRD.Description="TODO"
FFmpegEncoder.AMF.Other.VBAQ="VBAQ"
FFmpegEncoder.AMF.Other.VBAQ.Description="Enable 'Variance (Based) Adaptive Quantization', which improves the bitrate distribution over the frame by focusing areas which need the detail, like edges and foliage.\nThis option is only available on newer AMD GPUs."
FFmpegEncoder.AMF.Other.AccessUnitDelimiter="Access Unit Delimiter"
FFmpegEncoder.AMF.Other.AccessUnitDelimiter.Description="Enable insertion of an Access Unit Delimiter."
# Encoder: NVENC
FFmpegEncoder.NVENC.Preset="Preset"
FFmpegEncoder.NVENC.Preset.Description="Presets are NVIDIA's preconfigured default settings.\nThe values set via the preset are overridden by parameters below, unless they are set to 'Default' or '-1'."
FFmpegEncoder.NVENC.Preset.Default="Default"
FFmpegEncoder.NVENC.Preset.Slow="Slow"
FFmpegEncoder.NVENC.Preset.Medium="Medium"
@ -491,65 +386,38 @@ FFmpegEncoder.NVENC.Preset.Lossless="Lossless"
FFmpegEncoder.NVENC.Preset.LosslessHighPerformance="Lossless High Performance"
FFmpegEncoder.NVENC.RateControl="Rate Control Options"
FFmpegEncoder.NVENC.RateControl.Mode="Mode"
FFmpegEncoder.NVENC.RateControl.Mode.Description="Rate control mode selection"
FFmpegEncoder.NVENC.RateControl.Mode.CQP="Constant Quantization Parameter"
FFmpegEncoder.NVENC.RateControl.Mode.CQP.Description="A flat compression ratio with no regard for bit rates."
FFmpegEncoder.NVENC.RateControl.Mode.VBR="Variable Bitrate"
FFmpegEncoder.NVENC.RateControl.Mode.VBR.Description="Sacrifices quality to stay below the upper bitrate limit,\nor saves bitrate where possible."
FFmpegEncoder.NVENC.RateControl.Mode.VBR_HQ="High Quality Variable Bitrate"
FFmpegEncoder.NVENC.RateControl.Mode.VBR_HQ.Description="Variable Bitrate with two-pass encoding enabled by default."
FFmpegEncoder.NVENC.RateControl.Mode.CBR="Constant Bitrate"
FFmpegEncoder.NVENC.RateControl.Mode.CBR.Description="Compresses footage so that it matches the target bitrate over the duration of\none second. This comes at a cost in quality during high motion scenes or\nscenes with flickering brightness like often seen in RPGs."
FFmpegEncoder.NVENC.RateControl.Mode.CBR_HQ="High Quality Constant Bitrate"
FFmpegEncoder.NVENC.RateControl.Mode.CBR_HQ.Description="Constant Bitrate with two-pass encoding enabled by default."
FFmpegEncoder.NVENC.RateControl.Mode.CBR_LD_HQ="Low Delay High Quality Constant Bitrate"
FFmpegEncoder.NVENC.RateControl.Mode.CBR_LD_HQ.Description="Constant Bitrate optimized for lowest encoding latency."
FFmpegEncoder.NVENC.RateControl.TwoPass="Two Pass"
FFmpegEncoder.NVENC.RateControl.TwoPass.Description="Enable a secondary pass for encoding, which can help with quality and bitrate stability.\nImproves quality slightly at the cost of some GPU time.\nNvidia Turing hardware might actually see a quality degrade from this."
FFmpegEncoder.NVENC.RateControl.LookAhead="Look Ahead"
FFmpegEncoder.NVENC.RateControl.LookAhead.Description="Look ahead this many frames while encoding to better distribute bitrate.\nImproves quality slightly at the cost of some GPU time.\nSet to 0 to disable."
FFmpegEncoder.NVENC.RateControl.AdaptiveI="Adaptive I-Frames"
FFmpegEncoder.NVENC.RateControl.AdaptiveI.Description="Enables adaptive I-Frame insertion.\nOnly has an effect when look ahead is set to a value other than 0."
FFmpegEncoder.NVENC.RateControl.AdaptiveB="Adaptive B-Frames"
FFmpegEncoder.NVENC.RateControl.AdaptiveB.Description="Enables adaptive B-Frame insertion.\nOnly has an effect when look ahead is set to a value other than 0."
FFmpegEncoder.NVENC.RateControl.Limits="Limits"
FFmpegEncoder.NVENC.RateControl.Limits.BufferSize="Buffer Size"
FFmpegEncoder.NVENC.RateControl.Limits.BufferSize.Description="Specifies the buffer size used for bitrate constrained modes.\nIdeally set to (KeyFrame Interval In Seconds * Bitrate Target), so at 2 seconds and 6000 kbit it should be 12000."
FFmpegEncoder.NVENC.RateControl.Limits.Quality="Target Quality"
FFmpegEncoder.NVENC.RateControl.Limits.Quality.Description="Target quality to achieve, with values closer to 0 being better quality.\nSet to 0 to disable the target quality restriction."
FFmpegEncoder.NVENC.RateControl.Limits.Bitrate.Target="Target Bitrate"
FFmpegEncoder.NVENC.RateControl.Limits.Bitrate.Maximum="Maximum Bitrate"
FFmpegEncoder.NVENC.RateControl.QP="Quantization Parameters"
FFmpegEncoder.NVENC.RateControl.QP.Minimum="Minimum QP"
FFmpegEncoder.NVENC.RateControl.QP.Minimum.Description="Minimum QP to achieve, with values closer to 0 being better quality.\nSet to -1 to disable the maximum restriction."
FFmpegEncoder.NVENC.RateControl.QP.Maximum="Maximum QP"
FFmpegEncoder.NVENC.RateControl.QP.Maximum.Description="Maximum QP to achieve, with values closer to 0 being better quality.\nSet to -1 to disable the maximum restriction."
FFmpegEncoder.NVENC.RateControl.QP.I="I-Frame QP"
FFmpegEncoder.NVENC.RateControl.QP.I.Description="Quantization parameter for I-Frames.\nSmaller values mean better quality in exchange for higher bitrate, while higher values mean less bitrate in exchange for less quality."
FFmpegEncoder.NVENC.RateControl.QP.P="P-Frame QP"
FFmpegEncoder.NVENC.RateControl.QP.P.Description="Quantization parameter for P-Frames.\nSmaller values mean better quality in exchange for higher bitrate, while higher values mean less bitrate in exchange for less quality."
FFmpegEncoder.NVENC.RateControl.QP.B="B-Frame QP"
FFmpegEncoder.NVENC.RateControl.QP.B.Description="Quantization parameter for B-Frames.\nSmaller values mean better quality in exchange for higher bitrate, while higher values mean less bitrate in exchange for less quality."
FFmpegEncoder.NVENC.AQ="Adaptive Quantization"
FFmpegEncoder.NVENC.AQ.Spatial="Spatial Adaptive Quantization"
FFmpegEncoder.NVENC.AQ.Spatial.Description="Enable spatial adaptive quantization, also sometimes referred to as Psychovisual Adaptive Quantization."
FFmpegEncoder.NVENC.AQ.Strength="Spatial Adaptive Quantization Strength"
FFmpegEncoder.NVENC.AQ.Strength.Description="Strength of the spatial adaptive quantization.\nValues closer to 15 mean more aggressive, while values closer to 1 mean more relaxed."
FFmpegEncoder.NVENC.AQ.Temporal="Temporal Adaptive Quantization"
FFmpegEncoder.NVENC.AQ.Temporal.Description="Enable temporal adaptive quantization."
FFmpegEncoder.NVENC.Other="Other Options"
FFmpegEncoder.NVENC.Other.BFrames="Maximum B-Frames"
FFmpegEncoder.NVENC.Other.BFrames.Description="Maximum number of B-Frames to insert into the encoded bitstream.\nActual number of B-Frames may be lower depending on content and lookahead settings.\nOnly Turing NVENC supports B-Frames for HEVC."
FFmpegEncoder.NVENC.Other.BFrameReferenceMode="B-Frame Reference Mode"
FFmpegEncoder.NVENC.Other.BFrameReferenceMode.Middle="Use only middle B-Frames as reference"
FFmpegEncoder.NVENC.Other.BFrameReferenceMode.Each="Use all B-Frames as reference"
FFmpegEncoder.NVENC.Other.ZeroLatency="Zero Latency"
FFmpegEncoder.NVENC.Other.ZeroLatency.Description="Enable zero latency operation, which ensures that there is no reordering delay."
FFmpegEncoder.NVENC.Other.WeightedPrediction="Weighted Prediction"
FFmpegEncoder.NVENC.Other.WeightedPrediction.Description="Enable weighted prediction for encoding.\nCan't be used with B-Frames."
FFmpegEncoder.NVENC.Other.NonReferencePFrames="Non-reference P-Frames"
FFmpegEncoder.NVENC.Other.NonReferencePFrames.Description="Enable the automatic insertion of non-reference P-Frames."
FFmpegEncoder.NVENC.Other.AccessUnitDelimiter="Access Unit Delimiter"
FFmpegEncoder.NVENC.Other.AccessUnitDelimiter.Description="Enable insertion of an Access Unit Delimiter."
FFmpegEncoder.NVENC.Other.DecodedPictureBufferSize="Decoded Picture Buffer Size"
FFmpegEncoder.NVENC.Other.DecodedPictureBufferSize.Description="The maximum number of decoded pictures that the encoder should reference, or 0 to automatically determine.\nMust be at least the number of B-Frames plus one and actual limits depend on the selected level.\nIdeally set to the highest supported value by the level or left at 0 as the encoder detects the ideal setting."

View File

@ -1017,6 +1017,13 @@ obs_properties_t* ffmpeg_factory::get_properties2(instance_t* data)
{
obs_properties_t* props = obs_properties_create();
#ifdef ENABLE_FRONTEND
{
obs_properties_add_button2(props, S_MANUAL_OPEN, D_TRANSLATE(S_MANUAL_OPEN),
streamfx::encoder::ffmpeg::ffmpeg_factory::on_manual_open, this);
}
#endif
if (data) {
data->get_properties(props);
}
@ -1035,7 +1042,6 @@ obs_properties_t* ffmpeg_factory::get_properties2(instance_t* data)
{ // Key-Frame Interval Type
auto p = obs_properties_add_list(grp, KEY_KEYFRAMES_INTERVALTYPE, D_TRANSLATE(ST_KEYFRAMES_INTERVALTYPE),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_KEYFRAMES_INTERVALTYPE)));
obs_property_set_modified_callback(p, modified_keyframes);
obs_property_list_add_int(p, D_TRANSLATE(ST_KEYFRAMES_INTERVALTYPE_(Seconds)), 0);
obs_property_list_add_int(p, D_TRANSLATE(ST_KEYFRAMES_INTERVALTYPE_(Frames)), 1);
@ -1043,13 +1049,11 @@ obs_properties_t* ffmpeg_factory::get_properties2(instance_t* data)
{ // Key-Frame Interval Seconds
auto p = obs_properties_add_float(grp, KEY_KEYFRAMES_INTERVAL_SECONDS, D_TRANSLATE(ST_KEYFRAMES_INTERVAL),
0.00, std::numeric_limits<int16_t>::max(), 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_KEYFRAMES_INTERVAL)));
obs_property_float_set_suffix(p, " seconds");
}
{ // Key-Frame Interval Frames
auto p = obs_properties_add_int(grp, KEY_KEYFRAMES_INTERVAL_FRAMES, D_TRANSLATE(ST_KEYFRAMES_INTERVAL), 0,
std::numeric_limits<int32_t>::max(), 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_KEYFRAMES_INTERVAL)));
obs_property_int_set_suffix(p, " frames");
}
}
@ -1065,25 +1069,21 @@ obs_properties_t* ffmpeg_factory::get_properties2(instance_t* data)
{ // Custom Settings
auto p = obs_properties_add_text(grp, KEY_FFMPEG_CUSTOMSETTINGS, D_TRANSLATE(ST_FFMPEG_CUSTOMSETTINGS),
obs_text_type::OBS_TEXT_DEFAULT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_FFMPEG_CUSTOMSETTINGS)));
}
if (_handler && _handler->is_hardware_encoder(this)) {
auto p = obs_properties_add_int(grp, KEY_FFMPEG_GPU, D_TRANSLATE(ST_FFMPEG_GPU), -1,
std::numeric_limits<uint8_t>::max(), 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_FFMPEG_GPU)));
}
if (_handler && _handler->has_threading_support(this)) {
auto p = obs_properties_add_int_slider(grp, KEY_FFMPEG_THREADS, D_TRANSLATE(ST_FFMPEG_THREADS), 0,
static_cast<int64_t>(std::thread::hardware_concurrency() * 2), 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_FFMPEG_THREADS)));
}
if (_handler && _handler->has_pixel_format_support(this)) {
auto p = obs_properties_add_list(grp, KEY_FFMPEG_COLORFORMAT, D_TRANSLATE(ST_FFMPEG_COLORFORMAT),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_FFMPEG_COLORFORMAT)));
obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), static_cast<int64_t>(AV_PIX_FMT_NONE));
for (auto ptr = _avcodec->pix_fmts; *ptr != AV_PIX_FMT_NONE; ptr++) {
obs_property_list_add_int(p, ::ffmpeg::tools::get_pixel_format_name(*ptr), static_cast<int64_t>(*ptr));
@ -1094,7 +1094,6 @@ obs_properties_t* ffmpeg_factory::get_properties2(instance_t* data)
auto p =
obs_properties_add_list(grp, KEY_FFMPEG_STANDARDCOMPLIANCE, D_TRANSLATE(ST_FFMPEG_STANDARDCOMPLIANCE),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_FFMPEG_STANDARDCOMPLIANCE)));
obs_property_list_add_int(p, D_TRANSLATE(ST_FFMPEG_STANDARDCOMPLIANCE ".VeryStrict"),
FF_COMPLIANCE_VERY_STRICT);
obs_property_list_add_int(p, D_TRANSLATE(ST_FFMPEG_STANDARDCOMPLIANCE ".Strict"), FF_COMPLIANCE_STRICT);
@ -1109,6 +1108,15 @@ obs_properties_t* ffmpeg_factory::get_properties2(instance_t* data)
return props;
}
#ifdef ENABLE_FRONTEND
bool ffmpeg_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
{
ffmpeg_factory* ptr = static_cast<ffmpeg_factory*>(data);
streamfx::open_url(ptr->_handler->get_help_url(ptr->_avcodec));
return false;
}
#endif
const AVCodec* ffmpeg_factory::get_avcodec()
{
return _avcodec;

View File

@ -145,6 +145,10 @@ namespace streamfx::encoder::ffmpeg {
obs_properties_t* get_properties2(instance_t* data) override;
#ifdef ENABLE_FRONTEND
static bool on_manual_open(obs_properties_t* props, obs_property_t* property, void* data);
#endif
public:
const AVCodec* get_avcodec();

View File

@ -148,7 +148,6 @@ void amf_h264_handler::get_encoder_properties(obs_properties_t* props, const AVC
{
auto p = obs_properties_add_list(grp, KEY_PROFILE, D_TRANSLATE(P_H264_PROFILE), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(P_H264_PROFILE)));
obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), static_cast<int64_t>(profile::UNKNOWN));
for (auto const kv : profiles) {
std::string trans = std::string(P_H264_PROFILE) + "." + kv.second;
@ -158,7 +157,6 @@ void amf_h264_handler::get_encoder_properties(obs_properties_t* props, const AVC
{
auto p = obs_properties_add_list(grp, KEY_LEVEL, D_TRANSLATE(P_H264_LEVEL), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(P_H264_LEVEL)));
obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), static_cast<int64_t>(level::UNKNOWN));
for (auto const kv : levels) {
obs_property_list_add_int(p, kv.second.c_str(), static_cast<int64_t>(kv.first));

View File

@ -39,6 +39,11 @@ namespace streamfx::encoder::ffmpeg::handler {
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-AMF";
};
public /*support tests*/:
bool has_keyframe_support(ffmpeg_factory* instance) override;

View File

@ -157,7 +157,6 @@ void amf_hevc_handler::get_encoder_properties(obs_properties_t* props, const AVC
{
auto p = obs_properties_add_list(grp, KEY_PROFILE, D_TRANSLATE(P_HEVC_PROFILE), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(P_HEVC_PROFILE)));
obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), static_cast<int64_t>(profile::UNKNOWN));
for (auto const kv : profiles) {
std::string trans = std::string(P_HEVC_PROFILE) + "." + kv.second;
@ -167,7 +166,6 @@ void amf_hevc_handler::get_encoder_properties(obs_properties_t* props, const AVC
{
auto p = obs_properties_add_list(grp, KEY_TIER, D_TRANSLATE(P_HEVC_TIER), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(P_HEVC_TIER)));
obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), static_cast<int64_t>(tier::UNKNOWN));
for (auto const kv : tiers) {
std::string trans = std::string(P_HEVC_TIER) + "." + kv.second;
@ -177,7 +175,6 @@ void amf_hevc_handler::get_encoder_properties(obs_properties_t* props, const AVC
{
auto p = obs_properties_add_list(grp, KEY_LEVEL, D_TRANSLATE(P_HEVC_LEVEL), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(P_HEVC_LEVEL)));
obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), static_cast<int64_t>(level::UNKNOWN));
for (auto const kv : levels) {
obs_property_list_add_int(p, kv.second.c_str(), static_cast<int64_t>(kv.first));

View File

@ -38,6 +38,11 @@ namespace streamfx::encoder::ffmpeg::handler {
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context, bool hw_encode);
virtual std::string_view get_help_url(const AVCodec* codec) override
{
return "https://github.com/Xaymar/obs-StreamFX/wiki/Encoder-FFmpeg-AMF";
};
public /*support tests*/:
virtual bool has_keyframe_support(ffmpeg_factory* instance);

View File

@ -190,7 +190,6 @@ void amf::get_properties_pre(obs_properties_t* props, const AVCodec* codec)
{
auto p = obs_properties_add_list(props, ST_KEY_PRESET, D_TRANSLATE(ST_I18N_PRESET), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_I18N_PRESET)));
for (auto kv : presets) {
obs_property_list_add_int(p, D_TRANSLATE(kv.second.c_str()), static_cast<int64_t>(kv.first));
}
@ -205,24 +204,16 @@ void amf::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_long_description(p, D_TRANSLATE(D_DESC(ST_I18N_RATECONTROL_MODE)));
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<int64_t>(kv.first));
}
}
{
auto p = util::obs_properties_add_tristate(grp, ST_KEY_RATECONTROL_LOOKAHEAD,
D_TRANSLATE(ST_I18N_RATECONTROL_LOOKAHEAD));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_I18N_RATECONTROL_LOOKAHEAD)));
}
{
auto p = util::obs_properties_add_tristate(grp, ST_KEY_RATECONTROL_FRAMESKIPPING,
D_TRANSLATE(ST_I18N_RATECONTROL_FRAMESKIPPING));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_I18N_RATECONTROL_FRAMESKIPPING)));
}
util::obs_properties_add_tristate(grp, ST_KEY_RATECONTROL_LOOKAHEAD,
D_TRANSLATE(ST_I18N_RATECONTROL_LOOKAHEAD));
util::obs_properties_add_tristate(grp, ST_KEY_RATECONTROL_FRAMESKIPPING,
D_TRANSLATE(ST_I18N_RATECONTROL_FRAMESKIPPING));
}
{
@ -248,7 +239,6 @@ void amf::get_properties_post(obs_properties_t* props, const AVCodec* codec)
auto p = obs_properties_add_int(grp, ST_KEY_RATECONTROL_LIMITS_BUFFERSIZE,
D_TRANSLATE(ST_I18N_RATECONTROL_LIMITS_BUFFERSIZE), 0,
std::numeric_limits<std::int32_t>::max(), 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_I18N_RATECONTROL_LIMITS_BUFFERSIZE)));
obs_property_int_set_suffix(p, " kbit");
}
}
@ -258,21 +248,12 @@ void amf::get_properties_post(obs_properties_t* props, const AVCodec* codec)
obs_properties_add_group(props, ST_I18N_RATECONTROL_QP, D_TRANSLATE(ST_I18N_RATECONTROL_QP), OBS_GROUP_NORMAL,
grp);
{
auto p = obs_properties_add_int_slider(grp, ST_KEY_RATECONTROL_QP_I, D_TRANSLATE(ST_I18N_RATECONTROL_QP_I),
-1, 51, 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_I18N_RATECONTROL_QP_I)));
}
{
auto p = obs_properties_add_int_slider(grp, ST_KEY_RATECONTROL_QP_P, D_TRANSLATE(ST_I18N_RATECONTROL_QP_P),
-1, 51, 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_I18N_RATECONTROL_QP_P)));
}
obs_properties_add_int_slider(grp, ST_KEY_RATECONTROL_QP_I, D_TRANSLATE(ST_I18N_RATECONTROL_QP_I), -1, 51, 1);
obs_properties_add_int_slider(grp, ST_KEY_RATECONTROL_QP_P, D_TRANSLATE(ST_I18N_RATECONTROL_QP_P), -1, 51, 1);
if (std::string_view("amf_h264") == codec->name) {
auto p = obs_properties_add_int_slider(grp, ST_KEY_RATECONTROL_QP_B, D_TRANSLATE(ST_I18N_RATECONTROL_QP_B),
-1, 51, 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_I18N_RATECONTROL_QP_B)));
obs_properties_add_int_slider(grp, ST_KEY_RATECONTROL_QP_B, D_TRANSLATE(ST_I18N_RATECONTROL_QP_B), -1, 51,
1);
}
}
@ -283,39 +264,20 @@ void amf::get_properties_post(obs_properties_t* props, const AVCodec* codec)
{
auto p =
obs_properties_add_int_slider(grp, ST_KEY_OTHER_BFRAMES, D_TRANSLATE(ST_I18N_OTHER_BFRAMES), -1, 4, 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_I18N_OTHER_BFRAMES)));
obs_property_int_set_suffix(p, " frames");
}
{
auto p = util::obs_properties_add_tristate(grp, ST_KEY_OTHER_BFRAMEREFERENCES,
D_TRANSLATE(ST_I18N_OTHER_BFRAMEREFERENCES));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_I18N_OTHER_BFRAMEREFERENCES)));
}
util::obs_properties_add_tristate(grp, ST_KEY_OTHER_BFRAMEREFERENCES,
D_TRANSLATE(ST_I18N_OTHER_BFRAMEREFERENCES));
{
auto p = obs_properties_add_int_slider(grp, ST_KEY_OTHER_REFERENCEFRAMES,
D_TRANSLATE(ST_I18N_OTHER_REFERENCEFRAMES), -1, 16, 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_I18N_OTHER_REFERENCEFRAMES)));
obs_property_int_set_suffix(p, " frames");
}
{
auto p =
util::obs_properties_add_tristate(grp, ST_KEY_OTHER_ENFORCEHRD, D_TRANSLATE(ST_I18N_OTHER_ENFORCEHRD));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_I18N_OTHER_ENFORCEHRD)));
}
{
auto p = util::obs_properties_add_tristate(grp, ST_KEY_OTHER_VBAQ, D_TRANSLATE(ST_I18N_OTHER_VBAQ));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_I18N_OTHER_VBAQ)));
}
{
auto p = util::obs_properties_add_tristate(grp, ST_KEY_OTHER_ACCESSUNITDELIMITER,
D_TRANSLATE(ST_I18N_OTHER_ACCESSUNITDELIMITER));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_I18N_OTHER_ACCESSUNITDELIMITER)));
}
util::obs_properties_add_tristate(grp, ST_KEY_OTHER_ENFORCEHRD, D_TRANSLATE(ST_I18N_OTHER_ENFORCEHRD));
util::obs_properties_add_tristate(grp, ST_KEY_OTHER_VBAQ, D_TRANSLATE(ST_I18N_OTHER_VBAQ));
util::obs_properties_add_tristate(grp, ST_KEY_OTHER_ACCESSUNITDELIMITER,
D_TRANSLATE(ST_I18N_OTHER_ACCESSUNITDELIMITER));
}
}

View File

@ -47,6 +47,11 @@ namespace streamfx::encoder::ffmpeg {
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context,
bool hw_encode){};
virtual std::string_view get_help_url(const AVCodec* codec)
{
return "https://github.com/Xaymar/obs-StreamFX/wiki/Encoder-FFmpeg";
};
public /*support tests*/:
virtual bool has_keyframe_support(ffmpeg_factory* instance);

View File

@ -154,7 +154,6 @@ void nvenc_h264_handler::get_encoder_properties(obs_properties_t* props, const A
{
auto p = obs_properties_add_list(grp, KEY_PROFILE, D_TRANSLATE(P_H264_PROFILE), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(P_H264_PROFILE)));
obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), static_cast<int64_t>(profile::UNKNOWN));
for (auto const kv : profiles) {
std::string trans = std::string(P_H264_PROFILE) + "." + kv.second;
@ -164,7 +163,6 @@ void nvenc_h264_handler::get_encoder_properties(obs_properties_t* props, const A
{
auto p = obs_properties_add_list(grp, KEY_LEVEL, D_TRANSLATE(P_H264_LEVEL), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(P_H264_LEVEL)));
obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), static_cast<int64_t>(level::UNKNOWN));
for (auto const kv : levels) {
obs_property_list_add_int(p, kv.second.c_str(), static_cast<int64_t>(kv.first));

View File

@ -40,6 +40,11 @@ namespace streamfx::encoder::ffmpeg::handler {
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context, bool hw_encode);
virtual std::string_view get_help_url(const AVCodec* codec) override
{
return "https://github.com/Xaymar/obs-StreamFX/wiki/Encoder-FFmpeg-NVENC";
};
public /*support tests*/:
virtual bool has_keyframe_support(ffmpeg_factory* instance);

View File

@ -162,7 +162,6 @@ void nvenc_hevc_handler::get_encoder_properties(obs_properties_t* props, const A
{
auto p = obs_properties_add_list(grp, KEY_PROFILE, D_TRANSLATE(P_HEVC_PROFILE), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(P_HEVC_PROFILE)));
obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), static_cast<int64_t>(profile::UNKNOWN));
for (auto const kv : profiles) {
std::string trans = std::string(P_HEVC_PROFILE) + "." + kv.second;
@ -172,7 +171,6 @@ void nvenc_hevc_handler::get_encoder_properties(obs_properties_t* props, const A
{
auto p = obs_properties_add_list(grp, KEY_TIER, D_TRANSLATE(P_HEVC_TIER), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(P_HEVC_TIER)));
obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), static_cast<int64_t>(tier::UNKNOWN));
for (auto const kv : tiers) {
std::string trans = std::string(P_HEVC_TIER) + "." + kv.second;
@ -182,7 +180,6 @@ void nvenc_hevc_handler::get_encoder_properties(obs_properties_t* props, const A
{
auto p = obs_properties_add_list(grp, KEY_LEVEL, D_TRANSLATE(P_HEVC_LEVEL), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(P_HEVC_LEVEL)));
obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), static_cast<int64_t>(level::UNKNOWN));
for (auto const kv : levels) {
obs_property_list_add_int(p, kv.second.c_str(), static_cast<int64_t>(kv.first));

View File

@ -40,6 +40,11 @@ namespace streamfx::encoder::ffmpeg::handler {
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context, bool hw_encode);
virtual std::string_view get_help_url(const AVCodec* codec) override
{
return "https://github.com/Xaymar/obs-StreamFX/wiki/Encoder-FFmpeg-NVENC";
};
public /*support tests*/:
virtual bool has_keyframe_support(ffmpeg_factory* instance);

View File

@ -290,7 +290,6 @@ void nvenc::get_properties_pre(obs_properties_t* props, const AVCodec*)
{
auto p =
obs_properties_add_list(props, KEY_PRESET, D_TRANSLATE(ST_PRESET), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_PRESET)));
for (auto kv : presets) {
obs_property_list_add_int(p, D_TRANSLATE(kv.second.c_str()), static_cast<int64_t>(kv.first));
}
@ -308,7 +307,6 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
{
auto p = obs_properties_add_list(grp, KEY_RATECONTROL_MODE, D_TRANSLATE(ST_RATECONTROL_MODE),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_MODE)));
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<int64_t>(kv.first));
@ -318,13 +316,11 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
{
auto p =
util::obs_properties_add_tristate(grp, KEY_RATECONTROL_TWOPASS, D_TRANSLATE(ST_RATECONTROL_TWOPASS));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_TWOPASS)));
}
{
auto p = obs_properties_add_int_slider(grp, KEY_RATECONTROL_LOOKAHEAD,
D_TRANSLATE(ST_RATECONTROL_LOOKAHEAD), -1, 32, 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_LOOKAHEAD)));
obs_property_int_set_suffix(p, " frames");
//obs_property_set_modified_callback(p, modified_lookahead);
}
@ -332,13 +328,11 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
{
auto p = util::obs_properties_add_tristate(grp, KEY_RATECONTROL_ADAPTIVEI,
D_TRANSLATE(ST_RATECONTROL_ADAPTIVEI));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_ADAPTIVEI)));
}
if (strcmp(codec->name, "h264_nvenc") == 0) {
auto p = util::obs_properties_add_tristate(grp, KEY_RATECONTROL_ADAPTIVEB,
D_TRANSLATE(ST_RATECONTROL_ADAPTIVEB));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_ADAPTIVEB)));
}
}
@ -353,7 +347,6 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
{
auto p = obs_properties_add_float_slider(grp, KEY_RATECONTROL_LIMITS_QUALITY,
D_TRANSLATE(ST_RATECONTROL_LIMITS_QUALITY), 0, 100, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_LIMITS_QUALITY)));
}
{
@ -374,7 +367,6 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
auto p = obs_properties_add_int(grp, KEY_RATECONTROL_LIMITS_BUFFERSIZE,
D_TRANSLATE(ST_RATECONTROL_LIMITS_BUFFERSIZE), 0,
std::numeric_limits<int32_t>::max(), 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_LIMITS_BUFFERSIZE)));
obs_property_int_set_suffix(p, " kbit");
}
}
@ -389,28 +381,23 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
{
auto p = obs_properties_add_int_slider(grp, KEY_RATECONTROL_QP_MINIMUM,
D_TRANSLATE(ST_RATECONTROL_QP_MINIMUM), -1, 51, 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_QP_MINIMUM)));
}
{
auto p = obs_properties_add_int_slider(grp, KEY_RATECONTROL_QP_MAXIMUM,
D_TRANSLATE(ST_RATECONTROL_QP_MAXIMUM), -1, 51, 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_QP_MAXIMUM)));
}
{
auto p =
obs_properties_add_int_slider(grp, KEY_RATECONTROL_QP_I, D_TRANSLATE(ST_RATECONTROL_QP_I), -1, 51, 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_QP_I)));
}
{
auto p =
obs_properties_add_int_slider(grp, KEY_RATECONTROL_QP_P, D_TRANSLATE(ST_RATECONTROL_QP_P), -1, 51, 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_QP_P)));
}
{
auto p =
obs_properties_add_int_slider(grp, KEY_RATECONTROL_QP_B, D_TRANSLATE(ST_RATECONTROL_QP_B), -1, 51, 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_QP_B)));
}
}
@ -423,16 +410,13 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
{
auto p = util::obs_properties_add_tristate(grp, KEY_AQ_SPATIAL, D_TRANSLATE(ST_AQ_SPATIAL));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_AQ_SPATIAL)));
obs_property_set_modified_callback(p, modified_aq);
}
{
auto p = obs_properties_add_int_slider(grp, KEY_AQ_STRENGTH, D_TRANSLATE(ST_AQ_STRENGTH), -1, 15, 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_AQ_STRENGTH)));
}
{
auto p = util::obs_properties_add_tristate(grp, KEY_AQ_TEMPORAL, D_TRANSLATE(ST_AQ_TEMPORAL));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_AQ_TEMPORAL)));
}
}
@ -445,7 +429,6 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
{
auto p = obs_properties_add_int_slider(grp, KEY_OTHER_BFRAMES, D_TRANSLATE(ST_OTHER_BFRAMES), -1, 4, 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_OTHER_BFRAMES)));
obs_property_int_set_suffix(p, " frames");
}
@ -464,31 +447,26 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
{
auto p = util::obs_properties_add_tristate(grp, KEY_OTHER_ZEROLATENCY, D_TRANSLATE(ST_OTHER_ZEROLATENCY));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_OTHER_ZEROLATENCY)));
}
{
auto p = util::obs_properties_add_tristate(grp, KEY_OTHER_WEIGHTEDPREDICTION,
D_TRANSLATE(ST_OTHER_WEIGHTEDPREDICTION));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_OTHER_WEIGHTEDPREDICTION)));
}
{
auto p = util::obs_properties_add_tristate(grp, KEY_OTHER_NONREFERENCEPFRAMES,
D_TRANSLATE(ST_OTHER_NONREFERENCEPFRAMES));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_OTHER_NONREFERENCEPFRAMES)));
}
{
auto p = util::obs_properties_add_tristate(grp, KEY_OTHER_ACCESSUNITDELIMITER,
D_TRANSLATE(ST_OTHER_ACCESSUNITDELIMITER));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_OTHER_ACCESSUNITDELIMITER)));
}
{
auto p = obs_properties_add_int_slider(grp, KEY_OTHER_DECODEDPICTUREBUFFERSIZE,
D_TRANSLATE(ST_OTHER_DECODEDPICTUREBUFFERSIZE), -1, 16, 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_OTHER_DECODEDPICTUREBUFFERSIZE)));
obs_property_int_set_suffix(p, " frames");
}
}

View File

@ -86,7 +86,6 @@ void prores_aw_handler::get_properties(obs_properties_t* props, const AVCodec* c
if (!context) {
auto p = obs_properties_add_list(props, P_PRORES_PROFILE, D_TRANSLATE(P_PRORES_PROFILE), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(P_PRORES_PROFILE)));
for (auto ptr = codec->profiles; ptr->profile != FF_PROFILE_UNKNOWN; ptr++) {
obs_property_list_add_int(p, profile_to_name(ptr), static_cast<int64_t>(ptr->profile));
}

View File

@ -37,6 +37,11 @@ namespace streamfx::encoder::ffmpeg::handler {
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-Apple-ProRes";
};
public /*support tests*/:
bool has_pixel_format_support(ffmpeg_factory* instance) override;

View File

@ -78,6 +78,8 @@
using namespace streamfx::filter::blur;
static constexpr std::string_view HELP_URL = "https://github.com/Xaymar/obs-StreamFX/wiki/Filter-Blur";
struct local_blur_type_t {
std::function<::gfx::blur::ifactory&()> fn;
const char* name;
@ -667,41 +669,6 @@ try {
}
}
// Update hover text with new descriptions.
if (type_found != list_of_types.end()) {
if (type_found->first == "box") {
obs_property_set_long_description(obs_properties_get(props, ST_TYPE), D_TRANSLATE(D_DESC(S_BLUR_TYPE_BOX)));
} else if (type_found->first == "box_linear") {
obs_property_set_long_description(obs_properties_get(props, ST_TYPE),
D_TRANSLATE(D_DESC(S_BLUR_TYPE_BOX_LINEAR)));
} else if (type_found->first == "gaussian") {
obs_property_set_long_description(obs_properties_get(props, ST_TYPE),
D_TRANSLATE(D_DESC(S_BLUR_TYPE_GAUSSIAN)));
} else if (type_found->first == "gaussian_linear") {
obs_property_set_long_description(obs_properties_get(props, ST_TYPE),
D_TRANSLATE(D_DESC(S_BLUR_TYPE_GAUSSIAN_LINEAR)));
}
} else {
obs_property_set_long_description(obs_properties_get(props, ST_TYPE), D_TRANSLATE(D_DESC(ST_TYPE)));
}
if (subtype_found != list_of_subtypes.end()) {
if (subtype_found->first == "area") {
obs_property_set_long_description(obs_properties_get(props, ST_SUBTYPE),
D_TRANSLATE(D_DESC(S_BLUR_SUBTYPE_AREA)));
} else if (subtype_found->first == "directional") {
obs_property_set_long_description(obs_properties_get(props, ST_SUBTYPE),
D_TRANSLATE(D_DESC(S_BLUR_SUBTYPE_DIRECTIONAL)));
} else if (subtype_found->first == "rotational") {
obs_property_set_long_description(obs_properties_get(props, ST_SUBTYPE),
D_TRANSLATE(D_DESC(S_BLUR_SUBTYPE_ROTATIONAL)));
} else if (subtype_found->first == "zoom") {
obs_property_set_long_description(obs_properties_get(props, ST_SUBTYPE),
D_TRANSLATE(D_DESC(S_BLUR_SUBTYPE_ZOOM)));
}
} else {
obs_property_set_long_description(obs_properties_get(props, ST_SUBTYPE), D_TRANSLATE(D_DESC(ST_SUBTYPE)));
}
// Blur Sub-Type
{
bool has_angle_support = (subtype_found->second.type == ::gfx::blur::type::Directional)
@ -775,10 +742,16 @@ obs_properties_t* blur_factory::get_properties2(blur_instance* data)
obs_properties_t* pr = obs_properties_create();
obs_property_t* p = NULL;
#ifdef ENABLE_FRONTEND
{
obs_properties_add_button2(pr, S_MANUAL_OPEN, D_TRANSLATE(S_MANUAL_OPEN),
streamfx::filter::blur::blur_factory::on_manual_open, nullptr);
}
#endif
// Blur Type and Sub-Type
{
p = obs_properties_add_list(pr, ST_TYPE, D_TRANSLATE(ST_TYPE), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_TYPE)));
obs_property_set_modified_callback2(p, modified_properties, this);
obs_property_list_add_string(p, D_TRANSLATE(S_BLUR_TYPE_BOX), "box");
obs_property_list_add_string(p, D_TRANSLATE(S_BLUR_TYPE_BOX_LINEAR), "box_linear");
@ -788,7 +761,6 @@ obs_properties_t* blur_factory::get_properties2(blur_instance* data)
p = obs_properties_add_list(pr, ST_SUBTYPE, D_TRANSLATE(ST_SUBTYPE), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SUBTYPE)));
obs_property_set_modified_callback2(p, modified_properties, this);
obs_property_list_add_string(p, D_TRANSLATE(S_BLUR_SUBTYPE_AREA), "area");
obs_property_list_add_string(p, D_TRANSLATE(S_BLUR_SUBTYPE_DIRECTIONAL), "directional");
@ -799,33 +771,22 @@ obs_properties_t* blur_factory::get_properties2(blur_instance* data)
// Blur Parameters
{
p = obs_properties_add_float_slider(pr, ST_SIZE, D_TRANSLATE(ST_SIZE), 1, 32767, 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SIZE)));
p = obs_properties_add_float_slider(pr, ST_ANGLE, D_TRANSLATE(ST_ANGLE), -180.0, 180.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_ANGLE)));
p = obs_properties_add_float_slider(pr, ST_CENTER_X, D_TRANSLATE(ST_CENTER_X), 0.00, 100.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_CENTER_X)));
p = obs_properties_add_float_slider(pr, ST_CENTER_Y, D_TRANSLATE(ST_CENTER_Y), 0.00, 100.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_CENTER_Y)));
p = obs_properties_add_bool(pr, ST_STEPSCALE, D_TRANSLATE(ST_STEPSCALE));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_STEPSCALE)));
obs_property_set_modified_callback2(p, modified_properties, this);
p = obs_properties_add_float_slider(pr, ST_STEPSCALE_X, D_TRANSLATE(ST_STEPSCALE_X), 0.0, 1000.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_STEPSCALE_X)));
p = obs_properties_add_float_slider(pr, ST_STEPSCALE_Y, D_TRANSLATE(ST_STEPSCALE_Y), 0.0, 1000.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_STEPSCALE_Y)));
}
// Masking
{
p = obs_properties_add_bool(pr, ST_MASK, D_TRANSLATE(ST_MASK));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MASK)));
obs_property_set_modified_callback2(p, modified_properties, this);
p = obs_properties_add_list(pr, ST_MASK_TYPE, D_TRANSLATE(ST_MASK_TYPE), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MASK_TYPE)));
obs_property_set_modified_callback2(p, modified_properties, this);
obs_property_list_add_int(p, D_TRANSLATE(ST_MASK_TYPE_REGION), static_cast<int64_t>(mask_type::Region));
obs_property_list_add_int(p, D_TRANSLATE(ST_MASK_TYPE_IMAGE), static_cast<int64_t>(mask_type::Image));
@ -833,23 +794,16 @@ obs_properties_t* blur_factory::get_properties2(blur_instance* data)
/// Region
p = obs_properties_add_float_slider(pr, ST_MASK_REGION_LEFT, D_TRANSLATE(ST_MASK_REGION_LEFT), 0.0, 100.0,
0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MASK_REGION_LEFT)));
p = obs_properties_add_float_slider(pr, ST_MASK_REGION_TOP, D_TRANSLATE(ST_MASK_REGION_TOP), 0.0, 100.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MASK_REGION_TOP)));
p = obs_properties_add_float_slider(pr, ST_MASK_REGION_RIGHT, D_TRANSLATE(ST_MASK_REGION_RIGHT), 0.0, 100.0,
0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MASK_REGION_RIGHT)));
p = obs_properties_add_float_slider(pr, ST_MASK_REGION_BOTTOM, D_TRANSLATE(ST_MASK_REGION_BOTTOM), 0.0, 100.0,
0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MASK_REGION_BOTTOM)));
p = obs_properties_add_float_slider(pr, ST_MASK_REGION_FEATHER, D_TRANSLATE(ST_MASK_REGION_FEATHER), 0.0, 50.0,
0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MASK_REGION_FEATHER)));
p = obs_properties_add_float_slider(pr, ST_MASK_REGION_FEATHER_SHIFT, D_TRANSLATE(ST_MASK_REGION_FEATHER_SHIFT),
-100.0, 100.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MASK_REGION_FEATHER_SHIFT)));
p = obs_properties_add_bool(pr, ST_MASK_REGION_INVERT, D_TRANSLATE(ST_MASK_REGION_INVERT));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MASK_REGION_INVERT)));
/// Image
{
std::string filter =
@ -857,12 +811,10 @@ obs_properties_t* blur_factory::get_properties2(blur_instance* data)
_translation_cache.push_back(filter);
p = obs_properties_add_path(pr, ST_MASK_IMAGE, D_TRANSLATE(ST_MASK_IMAGE), OBS_PATH_FILE,
_translation_cache.back().c_str(), nullptr);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MASK_IMAGE)));
}
/// Source
p = obs_properties_add_list(pr, ST_MASK_SOURCE, D_TRANSLATE(ST_MASK_SOURCE), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MASK_SOURCE)));
obs_property_list_add_string(p, "", "");
obs::source_tracker::get()->enumerate(
[&p](std::string name, obs_source_t*) {
@ -879,11 +831,8 @@ obs_properties_t* blur_factory::get_properties2(blur_instance* data)
/// Shared
p = obs_properties_add_color(pr, ST_MASK_COLOR, D_TRANSLATE(ST_MASK_COLOR));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MASK_COLOR)));
p = obs_properties_add_float_slider(pr, ST_MASK_ALPHA, D_TRANSLATE(ST_MASK_ALPHA), 0.0, 100.0, 0.1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MASK_ALPHA)));
p = obs_properties_add_float_slider(pr, ST_MASK_MULTIPLIER, D_TRANSLATE(ST_MASK_MULTIPLIER), 0.0, 10.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MASK_MULTIPLIER)));
}
return pr;
@ -899,6 +848,14 @@ std::string blur_factory::translate_string(const char* format, ...)
return std::string(buffer.data(), buffer.data() + len);
}
#ifdef ENABLE_FRONTEND
bool blur_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
{
streamfx::open_url(HELP_URL);
return false;
}
#endif
std::shared_ptr<blur_factory> _filter_blur_factory_instance = nullptr;
void streamfx::filter::blur::blur_factory::initialize()

View File

@ -125,6 +125,10 @@ namespace streamfx::filter::blur {
std::string translate_string(const char* format, ...);
#ifdef ENABLE_FRONTEND
static bool on_manual_open(obs_properties_t* props, obs_property_t* property, void* data);
#endif
public: // Singleton
static void initialize();

View File

@ -83,6 +83,8 @@
using namespace streamfx::filter::color_grade;
static constexpr std::string_view HELP_URL = "https://github.com/Xaymar/obs-StreamFX/wiki/Filter-Color-Grade";
// TODO: Figure out a way to merge _lut_rt, _lut_texture, _rt_source, _rt_grad, _tex_source, _tex_grade, _source_updated and _grade_updated.
// Seriously this is too much GPU space wasted on unused trash.
@ -599,6 +601,13 @@ obs_properties_t* color_grade_factory::get_properties2(color_grade_instance* dat
{
obs_properties_t* pr = obs_properties_create();
#ifdef ENABLE_FRONTEND
{
obs_properties_add_button2(pr, S_MANUAL_OPEN, D_TRANSLATE(S_MANUAL_OPEN),
streamfx::filter::color_grade::color_grade_factory::on_manual_open, nullptr);
}
#endif
{
obs_properties_t* grp = obs_properties_create();
obs_properties_add_group(pr, ST_LIFT, D_TRANSLATE(ST_LIFT), OBS_GROUP_NORMAL, grp);
@ -814,7 +823,6 @@ obs_properties_t* color_grade_factory::get_properties2(color_grade_instance* dat
{
auto p = obs_properties_add_list(grp, ST_RENDERMODE, D_TRANSLATE(ST_RENDERMODE), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RENDERMODE)));
std::pair<const char*, int64_t> els[] = {
{S_STATE_AUTOMATIC, -1},
{ST_RENDERMODE_DIRECT, 0},
@ -833,6 +841,14 @@ obs_properties_t* color_grade_factory::get_properties2(color_grade_instance* dat
return pr;
}
#ifdef ENABLE_FRONTEND
bool color_grade_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
{
streamfx::open_url(HELP_URL);
return false;
}
#endif
std::shared_ptr<color_grade_factory> _color_grade_factory_instance = nullptr;
void streamfx::filter::color_grade::color_grade_factory::initialize()

View File

@ -110,6 +110,10 @@ namespace streamfx::filter::color_grade {
virtual obs_properties_t* get_properties2(color_grade_instance* data) override;
#ifdef ENABLE_FRONTEND
static bool on_manual_open(obs_properties_t* props, obs_property_t* property, void* data);
#endif
public: // Singleton
static void initialize();

View File

@ -151,19 +151,10 @@ obs_properties_t* displacement_factory::get_properties2(displacement_instance* d
path = streamfx::data_file_path("examples/normal-maps/neutral.png").u8string();
}
{
auto p = obs_properties_add_path(pr, ST_FILE, D_TRANSLATE(ST_FILE), obs_path_type::OBS_PATH_FILE,
D_TRANSLATE(S_FILEFILTERS_TEXTURE), path.c_str());
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_FILE)));
}
{
auto p = obs_properties_add_float(pr, ST_SCALE, D_TRANSLATE(ST_SCALE), -10000000.0, 10000000.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SCALE)));
}
{
auto p = obs_properties_add_float_slider(pr, ST_SCALE_TYPE, D_TRANSLATE(ST_SCALE_TYPE), 0.0, 100.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SCALE_TYPE)));
}
obs_properties_add_path(pr, ST_FILE, D_TRANSLATE(ST_FILE), obs_path_type::OBS_PATH_FILE,
D_TRANSLATE(S_FILEFILTERS_TEXTURE), path.c_str());
obs_properties_add_float(pr, ST_SCALE, D_TRANSLATE(ST_SCALE), -10000000.0, 10000000.0, 0.01);
obs_properties_add_float_slider(pr, ST_SCALE_TYPE, D_TRANSLATE(ST_SCALE_TYPE), 0.0, 100.0, 0.01);
return pr;
}

View File

@ -43,6 +43,8 @@
using namespace streamfx::filter::dynamic_mask;
static constexpr std::string_view HELP_URL = "https://github.com/Xaymar/obs-StreamFX/wiki/Filter-Dynamic-Mask";
static std::pair<channel, const char*> channel_translations[] = {
{channel::Red, S_CHANNEL_RED},
{channel::Green, S_CHANNEL_GREEN},
@ -431,10 +433,16 @@ obs_properties_t* dynamic_mask_factory::get_properties2(dynamic_mask_instance* d
_translation_cache.clear();
#ifdef ENABLE_FRONTEND
{
obs_properties_add_button2(props, S_MANUAL_OPEN, D_TRANSLATE(S_MANUAL_OPEN),
streamfx::filter::dynamic_mask::dynamic_mask_factory::on_manual_open, nullptr);
}
#endif
{ // Input
p = obs_properties_add_list(props, ST_INPUT, D_TRANSLATE(ST_INPUT), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_INPUT)));
obs_property_list_add_string(p, "", "");
obs::source_tracker::get()->enumerate(
[&p](std::string name, obs_source_t*) {
@ -463,10 +471,6 @@ obs_properties_t* dynamic_mask_factory::get_properties2(dynamic_mask_instance* d
std::string buf = std::string(ST_CHANNEL_VALUE) + "." + pri_ch;
p = obs_properties_add_float_slider(grp, buf.c_str(), _translation_cache.back().c_str(), -100.0, 100.0,
0.01);
_translation_cache.push_back(translate_string(D_TRANSLATE(D_DESC(ST_CHANNEL_VALUE)), D_TRANSLATE(pri_ch),
D_TRANSLATE(pri_ch), D_TRANSLATE(pri_ch), D_TRANSLATE(pri_ch),
D_TRANSLATE(pri_ch), D_TRANSLATE(pri_ch), D_TRANSLATE(pri_ch),
D_TRANSLATE(pri_ch)));
obs_property_set_long_description(p, _translation_cache.back().c_str());
}
@ -476,10 +480,6 @@ obs_properties_t* dynamic_mask_factory::get_properties2(dynamic_mask_instance* d
std::string buf = std::string(ST_CHANNEL_INPUT) + "." + pri_ch + "." + sec_ch;
p = obs_properties_add_float_slider(grp, buf.c_str(), _translation_cache.back().c_str(), -100.0, 100.0,
0.01);
_translation_cache.push_back(translate_string(D_TRANSLATE(D_DESC(ST_CHANNEL_INPUT)), D_TRANSLATE(sec_ch),
D_TRANSLATE(pri_ch), D_TRANSLATE(sec_ch), D_TRANSLATE(pri_ch),
D_TRANSLATE(pri_ch), D_TRANSLATE(pri_ch), D_TRANSLATE(pri_ch),
D_TRANSLATE(pri_ch), D_TRANSLATE(pri_ch)));
obs_property_set_long_description(p, _translation_cache.back().c_str());
}
@ -488,10 +488,6 @@ obs_properties_t* dynamic_mask_factory::get_properties2(dynamic_mask_instance* d
std::string buf = std::string(ST_CHANNEL_MULTIPLIER) + "." + pri_ch;
p = obs_properties_add_float_slider(grp, buf.c_str(), _translation_cache.back().c_str(), -100.0, 100.0,
0.01);
_translation_cache.push_back(translate_string(D_TRANSLATE(D_DESC(ST_CHANNEL_MULTIPLIER)),
D_TRANSLATE(pri_ch), D_TRANSLATE(pri_ch), D_TRANSLATE(pri_ch),
D_TRANSLATE(pri_ch), D_TRANSLATE(pri_ch), D_TRANSLATE(pri_ch),
D_TRANSLATE(pri_ch), D_TRANSLATE(pri_ch)));
obs_property_set_long_description(p, _translation_cache.back().c_str());
}
@ -516,6 +512,14 @@ std::string dynamic_mask_factory::translate_string(const char* format, ...)
return std::string(buffer.data(), buffer.data() + len);
}
#ifdef ENABLE_FRONTEND
bool dynamic_mask_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
{
streamfx::open_url(HELP_URL);
return false;
}
#endif
std::shared_ptr<dynamic_mask_factory> _filter_dynamic_mask_factory_instance = nullptr;
void streamfx::filter::dynamic_mask::dynamic_mask_factory::initialize()

View File

@ -103,6 +103,10 @@ namespace streamfx::filter::dynamic_mask {
std::string translate_string(const char* format, ...);
#ifdef ENABLE_FRONTEND
static bool on_manual_open(obs_properties_t* props, obs_property_t* property, void* data);
#endif
public: // Singleton
static void initialize();

View File

@ -658,12 +658,10 @@ obs_properties_t* face_tracking_factory::get_properties2(face_tracking_instance*
{
auto p =
obs_properties_add_float_slider(grp, SK_ROI_STABILITY, D_TRANSLATE(ST_ROI_STABILITY), 0, 100.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_ROI_STABILITY)));
obs_property_float_set_suffix(p, " %");
}
{
auto p = obs_properties_add_float_slider(grp, SK_ROI_ZOOM, D_TRANSLATE(ST_ROI_ZOOM), 0, 200.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_ROI_ZOOM)));
obs_property_float_set_suffix(p, " %");
}
{
@ -673,13 +671,11 @@ obs_properties_t* face_tracking_factory::get_properties2(face_tracking_instance*
{
auto p = obs_properties_add_float_slider(grp2, SK_ROI_OFFSET_X, D_TRANSLATE(ST_ROI_OFFSET_X), -50.0,
50.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_ROI_OFFSET_X)));
obs_property_float_set_suffix(p, " %");
}
{
auto p = obs_properties_add_float_slider(grp2, SK_ROI_OFFSET_Y, D_TRANSLATE(ST_ROI_OFFSET_Y), -50.0,
50.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_ROI_OFFSET_Y)));
obs_property_float_set_suffix(p, " %");
}
}

View File

@ -67,6 +67,8 @@
using namespace streamfx::filter::sdf_effects;
static constexpr std::string_view HELP_URL = "https://github.com/Xaymar/obs-StreamFX/wiki/Filter-SDF-Effects";
sdf_effects_instance::sdf_effects_instance(obs_data_t* settings, obs_source_t* self)
: obs::source_instance(settings, self), _source_rendered(false), _sdf_scale(1.0), _sdf_threshold(),
_output_rendered(false), _inner_shadow(false), _inner_shadow_color(), _inner_shadow_range_min(),
@ -677,128 +679,101 @@ obs_properties_t* sdf_effects_factory::get_properties2(sdf_effects_instance* dat
obs_properties_t* props = obs_properties_create();
obs_property_t* p = nullptr;
#ifdef ENABLE_FRONTEND
{
obs_properties_add_button2(props, S_MANUAL_OPEN, D_TRANSLATE(S_MANUAL_OPEN),
streamfx::filter::sdf_effects::sdf_effects_factory::on_manual_open, nullptr);
}
#endif
{
p = obs_properties_add_bool(props, ST_SHADOW_OUTER, D_TRANSLATE(ST_SHADOW_OUTER));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADOW_OUTER)));
obs_property_set_modified_callback2(p, cb_modified_shadow_outside, data);
p = obs_properties_add_float_slider(props, ST_SHADOW_OUTER_RANGE_MINIMUM,
D_TRANSLATE(ST_SHADOW_OUTER_RANGE_MINIMUM), -16.0, 16.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADOW_OUTER_RANGE_MINIMUM)));
p = obs_properties_add_float_slider(props, ST_SHADOW_OUTER_RANGE_MAXIMUM,
D_TRANSLATE(ST_SHADOW_OUTER_RANGE_MAXIMUM), -16.0, 16.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADOW_OUTER_RANGE_MAXIMUM)));
p = obs_properties_add_float_slider(props, ST_SHADOW_OUTER_OFFSET_X, D_TRANSLATE(ST_SHADOW_OUTER_OFFSET_X),
-100.0, 100.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADOW_OUTER_OFFSET_X)));
p = obs_properties_add_float_slider(props, ST_SHADOW_OUTER_OFFSET_Y, D_TRANSLATE(ST_SHADOW_OUTER_OFFSET_Y),
-100.0, 100.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADOW_OUTER_OFFSET_Y)));
p = obs_properties_add_color(props, ST_SHADOW_OUTER_COLOR, D_TRANSLATE(ST_SHADOW_OUTER_COLOR));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADOW_OUTER_COLOR)));
p = obs_properties_add_float_slider(props, ST_SHADOW_OUTER_ALPHA, D_TRANSLATE(ST_SHADOW_OUTER_ALPHA), 0.0,
100.0, 0.1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADOW_OUTER_ALPHA)));
obs_properties_add_float_slider(props, ST_SHADOW_OUTER_RANGE_MINIMUM,
D_TRANSLATE(ST_SHADOW_OUTER_RANGE_MINIMUM), -16.0, 16.0, 0.01);
obs_properties_add_float_slider(props, ST_SHADOW_OUTER_RANGE_MAXIMUM,
D_TRANSLATE(ST_SHADOW_OUTER_RANGE_MAXIMUM), -16.0, 16.0, 0.01);
obs_properties_add_float_slider(props, ST_SHADOW_OUTER_OFFSET_X, D_TRANSLATE(ST_SHADOW_OUTER_OFFSET_X), -100.0,
100.0, 0.01);
obs_properties_add_float_slider(props, ST_SHADOW_OUTER_OFFSET_Y, D_TRANSLATE(ST_SHADOW_OUTER_OFFSET_Y), -100.0,
100.0, 0.01);
obs_properties_add_color(props, ST_SHADOW_OUTER_COLOR, D_TRANSLATE(ST_SHADOW_OUTER_COLOR));
obs_properties_add_float_slider(props, ST_SHADOW_OUTER_ALPHA, D_TRANSLATE(ST_SHADOW_OUTER_ALPHA), 0.0, 100.0,
0.1);
}
{
p = obs_properties_add_bool(props, ST_SHADOW_INNER, D_TRANSLATE(ST_SHADOW_INNER));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADOW_INNER)));
obs_property_set_modified_callback2(p, cb_modified_shadow_inside, data);
p = obs_properties_add_float_slider(props, ST_SHADOW_INNER_RANGE_MINIMUM,
D_TRANSLATE(ST_SHADOW_INNER_RANGE_MINIMUM), -16.0, 16.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADOW_INNER_RANGE_MINIMUM)));
p = obs_properties_add_float_slider(props, ST_SHADOW_INNER_RANGE_MAXIMUM,
D_TRANSLATE(ST_SHADOW_INNER_RANGE_MAXIMUM), -16.0, 16.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADOW_INNER_RANGE_MAXIMUM)));
p = obs_properties_add_float_slider(props, ST_SHADOW_INNER_OFFSET_X, D_TRANSLATE(ST_SHADOW_INNER_OFFSET_X),
-100.0, 100.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADOW_INNER_OFFSET_X)));
p = obs_properties_add_float_slider(props, ST_SHADOW_INNER_OFFSET_Y, D_TRANSLATE(ST_SHADOW_INNER_OFFSET_Y),
-100.0, 100.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADOW_INNER_OFFSET_Y)));
p = obs_properties_add_color(props, ST_SHADOW_INNER_COLOR, D_TRANSLATE(ST_SHADOW_INNER_COLOR));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADOW_INNER_COLOR)));
p = obs_properties_add_float_slider(props, ST_SHADOW_INNER_ALPHA, D_TRANSLATE(ST_SHADOW_INNER_ALPHA), 0.0,
100.0, 0.1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADOW_INNER_ALPHA)));
obs_properties_add_float_slider(props, ST_SHADOW_INNER_RANGE_MINIMUM,
D_TRANSLATE(ST_SHADOW_INNER_RANGE_MINIMUM), -16.0, 16.0, 0.01);
obs_properties_add_float_slider(props, ST_SHADOW_INNER_RANGE_MAXIMUM,
D_TRANSLATE(ST_SHADOW_INNER_RANGE_MAXIMUM), -16.0, 16.0, 0.01);
obs_properties_add_float_slider(props, ST_SHADOW_INNER_OFFSET_X, D_TRANSLATE(ST_SHADOW_INNER_OFFSET_X), -100.0,
100.0, 0.01);
obs_properties_add_float_slider(props, ST_SHADOW_INNER_OFFSET_Y, D_TRANSLATE(ST_SHADOW_INNER_OFFSET_Y), -100.0,
100.0, 0.01);
obs_properties_add_color(props, ST_SHADOW_INNER_COLOR, D_TRANSLATE(ST_SHADOW_INNER_COLOR));
obs_properties_add_float_slider(props, ST_SHADOW_INNER_ALPHA, D_TRANSLATE(ST_SHADOW_INNER_ALPHA), 0.0, 100.0,
0.1);
}
{
p = obs_properties_add_bool(props, ST_GLOW_OUTER, D_TRANSLATE(ST_GLOW_OUTER));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_GLOW_OUTER)));
obs_property_set_modified_callback2(p, cb_modified_glow_outside, data);
p = obs_properties_add_color(props, ST_GLOW_OUTER_COLOR, D_TRANSLATE(ST_GLOW_OUTER_COLOR));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_GLOW_OUTER_COLOR)));
p = obs_properties_add_float_slider(props, ST_GLOW_OUTER_ALPHA, D_TRANSLATE(ST_GLOW_OUTER_ALPHA), 0.0, 100.0,
0.1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_GLOW_OUTER_ALPHA)));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_GLOW_OUTER_WIDTH)));
p = obs_properties_add_float_slider(props, ST_GLOW_OUTER_WIDTH, D_TRANSLATE(ST_GLOW_OUTER_WIDTH), 0.0, 16.0,
0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_GLOW_OUTER_SHARPNESS)));
p = obs_properties_add_float_slider(props, ST_GLOW_OUTER_SHARPNESS, D_TRANSLATE(ST_GLOW_OUTER_SHARPNESS), 0.00,
100.0, 0.01);
obs_properties_add_color(props, ST_GLOW_OUTER_COLOR, D_TRANSLATE(ST_GLOW_OUTER_COLOR));
obs_properties_add_float_slider(props, ST_GLOW_OUTER_ALPHA, D_TRANSLATE(ST_GLOW_OUTER_ALPHA), 0.0, 100.0, 0.1);
obs_properties_add_float_slider(props, ST_GLOW_OUTER_WIDTH, D_TRANSLATE(ST_GLOW_OUTER_WIDTH), 0.0, 16.0, 0.01);
obs_properties_add_float_slider(props, ST_GLOW_OUTER_SHARPNESS, D_TRANSLATE(ST_GLOW_OUTER_SHARPNESS), 0.00,
100.0, 0.01);
}
{
p = obs_properties_add_bool(props, ST_GLOW_INNER, D_TRANSLATE(ST_GLOW_INNER));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_GLOW_INNER)));
obs_property_set_modified_callback2(p, cb_modified_glow_inside, data);
p = obs_properties_add_color(props, ST_GLOW_INNER_COLOR, D_TRANSLATE(ST_GLOW_INNER_COLOR));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_GLOW_INNER_COLOR)));
p = obs_properties_add_float_slider(props, ST_GLOW_INNER_ALPHA, D_TRANSLATE(ST_GLOW_INNER_ALPHA), 0.0, 100.0,
0.1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_GLOW_INNER_ALPHA)));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_GLOW_INNER_WIDTH)));
p = obs_properties_add_float_slider(props, ST_GLOW_INNER_WIDTH, D_TRANSLATE(ST_GLOW_INNER_WIDTH), 0.0, 16.0,
0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_GLOW_INNER_SHARPNESS)));
p = obs_properties_add_float_slider(props, ST_GLOW_INNER_SHARPNESS, D_TRANSLATE(ST_GLOW_INNER_SHARPNESS), 0.00,
100.0, 0.01);
obs_properties_add_color(props, ST_GLOW_INNER_COLOR, D_TRANSLATE(ST_GLOW_INNER_COLOR));
obs_properties_add_float_slider(props, ST_GLOW_INNER_ALPHA, D_TRANSLATE(ST_GLOW_INNER_ALPHA), 0.0, 100.0, 0.1);
obs_properties_add_float_slider(props, ST_GLOW_INNER_WIDTH, D_TRANSLATE(ST_GLOW_INNER_WIDTH), 0.0, 16.0, 0.01);
obs_properties_add_float_slider(props, ST_GLOW_INNER_SHARPNESS, D_TRANSLATE(ST_GLOW_INNER_SHARPNESS), 0.00,
100.0, 0.01);
}
{
p = obs_properties_add_bool(props, ST_OUTLINE, D_TRANSLATE(ST_OUTLINE));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_OUTLINE)));
obs_property_set_modified_callback2(p, cb_modified_outline, data);
p = obs_properties_add_color(props, ST_OUTLINE_COLOR, D_TRANSLATE(ST_OUTLINE_COLOR));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_OUTLINE_COLOR)));
p = obs_properties_add_float_slider(props, ST_OUTLINE_ALPHA, D_TRANSLATE(ST_OUTLINE_ALPHA), 0.0, 100.0, 0.1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_OUTLINE_ALPHA)));
obs_properties_add_color(props, ST_OUTLINE_COLOR, D_TRANSLATE(ST_OUTLINE_COLOR));
obs_properties_add_float_slider(props, ST_OUTLINE_ALPHA, D_TRANSLATE(ST_OUTLINE_ALPHA), 0.0, 100.0, 0.1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_OUTLINE_WIDTH)));
p = obs_properties_add_float_slider(props, ST_OUTLINE_WIDTH, D_TRANSLATE(ST_OUTLINE_WIDTH), 0.0, 16.0, 0.01);
obs_properties_add_float_slider(props, ST_OUTLINE_WIDTH, D_TRANSLATE(ST_OUTLINE_WIDTH), 0.0, 16.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_OUTLINE_OFFSET)));
p = obs_properties_add_float_slider(props, ST_OUTLINE_OFFSET, D_TRANSLATE(ST_OUTLINE_OFFSET), -16.0, 16.0,
0.01);
obs_properties_add_float_slider(props, ST_OUTLINE_OFFSET, D_TRANSLATE(ST_OUTLINE_OFFSET), -16.0, 16.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_OUTLINE_SHARPNESS)));
p = obs_properties_add_float_slider(props, ST_OUTLINE_SHARPNESS, D_TRANSLATE(ST_OUTLINE_SHARPNESS), 0.00, 100.0,
0.01);
obs_properties_add_float_slider(props, ST_OUTLINE_SHARPNESS, D_TRANSLATE(ST_OUTLINE_SHARPNESS), 0.00, 100.0,
0.01);
}
{
p = obs_properties_add_bool(props, S_ADVANCED, D_TRANSLATE(S_ADVANCED));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(S_ADVANCED)));
obs_property_set_modified_callback2(p, cb_modified_advanced, data);
p = obs_properties_add_float_slider(props, ST_SDF_SCALE, D_TRANSLATE(ST_SDF_SCALE), 0.1, 500.0, 0.1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SDF_SCALE)));
obs_properties_add_float_slider(props, ST_SDF_SCALE, D_TRANSLATE(ST_SDF_SCALE), 0.1, 500.0, 0.1);
p = obs_properties_add_float_slider(props, ST_SDF_THRESHOLD, D_TRANSLATE(ST_SDF_THRESHOLD), 0.0, 100.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SDF_THRESHOLD)));
obs_properties_add_float_slider(props, ST_SDF_THRESHOLD, D_TRANSLATE(ST_SDF_THRESHOLD), 0.0, 100.0, 0.01);
}
return props;
}
#ifdef ENABLE_FRONTEND
bool sdf_effects_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
{
streamfx::open_url(HELP_URL);
return false;
}
#endif
std::shared_ptr<sdf_effects_factory> _filter_sdf_effects_factory_instance = nullptr;
void streamfx::filter::sdf_effects::sdf_effects_factory::initialize()

View File

@ -105,6 +105,10 @@ namespace streamfx::filter::sdf_effects {
virtual obs_properties_t* get_properties2(filter::sdf_effects::sdf_effects_instance* data) override;
#ifdef ENABLE_FRONTEND
static bool on_manual_open(obs_properties_t* props, obs_property_t* property, void* data);
#endif
public: // Singleton
static void initialize();

View File

@ -26,6 +26,9 @@
using namespace streamfx::filter::shader;
static constexpr std::string_view HELP_URL =
"https://github.com/Xaymar/obs-StreamFX/wiki/Source-Filter-Transition-Shader";
shader_instance::shader_instance(obs_data_t* data, obs_source_t* self) : obs::source_instance(data, self)
{
_fx = std::make_shared<gfx::shader::shader>(self, gfx::shader::shader_mode::Filter);
@ -172,6 +175,13 @@ obs_properties_t* shader_factory::get_properties2(shader::shader_instance* data)
auto pr = obs_properties_create();
obs_properties_set_param(pr, data, nullptr);
#ifdef ENABLE_FRONTEND
{
auto p = obs_properties_add_button2(pr, S_MANUAL_OPEN, D_TRANSLATE(S_MANUAL_OPEN),
streamfx::filter::shader::shader_factory::on_manual_open, nullptr);
}
#endif
if (data) {
reinterpret_cast<shader_instance*>(data)->properties(pr);
}
@ -179,6 +189,14 @@ obs_properties_t* shader_factory::get_properties2(shader::shader_instance* data)
return pr;
}
#ifdef ENABLE_FRONTEND
bool shader_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
{
streamfx::open_url(HELP_URL);
return false;
}
#endif
std::shared_ptr<shader_factory> _filter_shader_factory_instance = nullptr;
void streamfx::filter::shader::shader_factory::initialize()

View File

@ -59,6 +59,10 @@ namespace streamfx::filter::shader {
virtual obs_properties_t* get_properties2(filter::shader::shader_instance* data) override;
#ifdef ENABLE_FRONTEND
static bool on_manual_open(obs_properties_t* props, obs_property_t* property, void* data);
#endif
public: // Singleton
static void initialize();

View File

@ -65,6 +65,8 @@
using namespace streamfx::filter::transform;
static constexpr std::string_view HELP_URL = "https://github.com/Xaymar/obs-StreamFX/wiki/Filter-3D-Transform";
static const float_t farZ = 2097152.0f; // 2 pow 21
static const float_t nearZ = 1.0f / farZ;
@ -499,6 +501,13 @@ obs_properties_t* transform_factory::get_properties2(transform_instance* data)
{
obs_properties_t* pr = obs_properties_create();
#ifdef ENABLE_FRONTEND
{
obs_properties_add_button2(pr, S_MANUAL_OPEN, D_TRANSLATE(S_MANUAL_OPEN),
streamfx::filter::transform::transform_factory::on_manual_open, nullptr);
}
#endif
// Camera
{
auto grp = obs_properties_create();
@ -506,7 +515,6 @@ obs_properties_t* transform_factory::get_properties2(transform_instance* data)
{ // Projection Mode
auto p = obs_properties_add_list(grp, ST_CAMERA, D_TRANSLATE(ST_CAMERA), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_CAMERA)));
obs_property_list_add_int(p, D_TRANSLATE(ST_CAMERA_ORTHOGRAPHIC),
static_cast<int64_t>(CameraMode::Orthographic));
obs_property_list_add_int(p, D_TRANSLATE(ST_CAMERA_PERSPECTIVE),
@ -516,7 +524,6 @@ obs_properties_t* transform_factory::get_properties2(transform_instance* data)
{ // Field Of View
auto p = obs_properties_add_float_slider(grp, ST_CAMERA_FIELDOFVIEW, D_TRANSLATE(ST_CAMERA_FIELDOFVIEW),
1.0, 179.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_CAMERA_FIELDOFVIEW)));
}
obs_properties_add_group(pr, ST_CAMERA, D_TRANSLATE(ST_CAMERA), OBS_GROUP_NORMAL, grp);
@ -530,7 +537,6 @@ obs_properties_t* transform_factory::get_properties2(transform_instance* data)
for (auto opt : opts) {
auto p = obs_properties_add_float(grp, opt, D_TRANSLATE(opt), std::numeric_limits<float_t>::lowest(),
std::numeric_limits<float_t>::max(), 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_POSITION)));
}
obs_properties_add_group(pr, ST_POSITION, D_TRANSLATE(ST_POSITION), OBS_GROUP_NORMAL, grp);
@ -542,7 +548,6 @@ obs_properties_t* transform_factory::get_properties2(transform_instance* data)
const char* opts[] = {ST_ROTATION_X, ST_ROTATION_Y, ST_ROTATION_Z};
for (auto opt : opts) {
auto p = obs_properties_add_float_slider(grp, opt, D_TRANSLATE(opt), -180.0, 180.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_ROTATION)));
obs_property_float_set_suffix(p, "° Deg");
}
}
@ -555,7 +560,6 @@ obs_properties_t* transform_factory::get_properties2(transform_instance* data)
const char* opts[] = {ST_SCALE_X, ST_SCALE_Y};
for (auto opt : opts) {
auto p = obs_properties_add_float_slider(grp, opt, D_TRANSLATE(opt), -1000, 1000, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SCALE)));
obs_property_float_set_suffix(p, "%");
}
@ -567,7 +571,6 @@ obs_properties_t* transform_factory::get_properties2(transform_instance* data)
const char* opts[] = {ST_SHEAR_X, ST_SHEAR_Y};
for (auto opt : opts) {
auto p = obs_properties_add_float_slider(grp, opt, D_TRANSLATE(opt), -200.0, 200.0, 0.01);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHEAR)));
obs_property_float_set_suffix(p, "%");
}
@ -580,13 +583,11 @@ obs_properties_t* transform_factory::get_properties2(transform_instance* data)
{ // Mipmapping
auto p = obs_properties_add_bool(grp, ST_MIPMAPPING, D_TRANSLATE(ST_MIPMAPPING));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_MIPMAPPING)));
}
{ // Order
auto p = obs_properties_add_list(grp, ST_ROTATION_ORDER, D_TRANSLATE(ST_ROTATION_ORDER),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_ROTATION_ORDER)));
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_XYZ), RotationOrder::XYZ);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_XZY), RotationOrder::XZY);
obs_property_list_add_int(p, D_TRANSLATE(ST_ROTATION_ORDER_YXZ), RotationOrder::YXZ);
@ -599,6 +600,14 @@ obs_properties_t* transform_factory::get_properties2(transform_instance* data)
return pr;
}
#ifdef ENABLE_FRONTEND
bool transform_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
{
streamfx::open_url(HELP_URL);
return false;
}
#endif
std::shared_ptr<transform_factory> _filter_transform_factory_instance = nullptr;
void transform_factory::initialize()

View File

@ -82,6 +82,10 @@ namespace streamfx::filter::transform {
virtual obs_properties_t* get_properties2(filter::transform::transform_instance* data) override;
#ifdef ENABLE_FRONTEND
static bool on_manual_open(obs_properties_t* props, obs_property_t* property, void* data);
#endif
public: // Singleton
static void initialize();

View File

@ -206,12 +206,10 @@ void gfx::shader::shader::properties(obs_properties_t* pr)
}
auto p = obs_properties_add_path(grp, ST_SHADER_FILE, D_TRANSLATE(ST_SHADER_FILE), OBS_PATH_FILE, "*.*",
path.c_str());
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADER_FILE)));
}
{
auto p = obs_properties_add_list(grp, ST_SHADER_TECHNIQUE, D_TRANSLATE(ST_SHADER_TECHNIQUE),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADER_TECHNIQUE)));
}
{
@ -230,19 +228,16 @@ void gfx::shader::shader::properties(obs_properties_t* pr)
{
auto p = obs_properties_add_text(grp2, ST_SHADER_SIZE_WIDTH, D_TRANSLATE(ST_SHADER_SIZE_WIDTH),
OBS_TEXT_DEFAULT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADER_SIZE)));
}
{
auto p = obs_properties_add_text(grp2, ST_SHADER_SIZE_HEIGHT, D_TRANSLATE(ST_SHADER_SIZE_HEIGHT),
OBS_TEXT_DEFAULT);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADER_SIZE)));
}
}
{
auto p = obs_properties_add_int_slider(grp, ST_SHADER_SEED, D_TRANSLATE(ST_SHADER_SEED),
std::numeric_limits<int>::min(), std::numeric_limits<int>::max(), 1);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADER_SEED)));
}
}
{

View File

@ -48,6 +48,8 @@
using namespace streamfx::source::mirror;
static constexpr std::string_view HELP_URL = "https://github.com/Xaymar/obs-StreamFX/wiki/Source-Mirror";
mirror_audio_data::mirror_audio_data(const audio_data* audio, speaker_layout layout)
{
// Build a clone of a packet.
@ -313,10 +315,16 @@ obs_properties_t* mirror_factory::get_properties2(mirror_instance* data)
obs_properties_t* pr = obs_properties_create();
obs_property_t* p = nullptr;
#ifdef ENABLE_FRONTEND
{
obs_properties_add_button2(pr, S_MANUAL_OPEN, D_TRANSLATE(S_MANUAL_OPEN),
streamfx::source::mirror::mirror_factory::on_manual_open, nullptr);
}
#endif
{
p = obs_properties_add_list(pr, ST_SOURCE, D_TRANSLATE(ST_SOURCE), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SOURCE)));
obs_property_set_modified_callback(p, modified_properties);
obs_property_list_add_string(p, "", "");
@ -340,7 +348,6 @@ obs_properties_t* mirror_factory::get_properties2(mirror_instance* data)
{
p = obs_properties_add_bool(pr, ST_SOURCE_AUDIO, D_TRANSLATE(ST_SOURCE_AUDIO));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SOURCE_AUDIO)));
obs_property_set_modified_callback(p, modified_properties);
}
@ -362,12 +369,19 @@ obs_properties_t* mirror_factory::get_properties2(mirror_instance* data)
static_cast<int64_t>(SPEAKERS_5POINT1));
obs_property_list_add_int(p, D_TRANSLATE(ST_SOURCE_AUDIO_LAYOUT_(FullSurround)),
static_cast<int64_t>(SPEAKERS_7POINT1));
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SOURCE_AUDIO_LAYOUT)));
}
return pr;
}
#ifdef ENABLE_FRONTEND
bool mirror_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
{
streamfx::open_url(HELP_URL);
return false;
}
#endif
std::shared_ptr<mirror_factory> _source_mirror_factory_instance;
void streamfx::source::mirror::mirror_factory::initialize()

View File

@ -93,6 +93,10 @@ namespace streamfx::source::mirror {
virtual obs_properties_t* get_properties2(source::mirror::mirror_instance* data) override;
#ifdef ENABLE_FRONTEND
static bool on_manual_open(obs_properties_t* props, obs_property_t* property, void* data);
#endif
public: // Singleton
static void initialize();

View File

@ -26,6 +26,9 @@
using namespace streamfx::source::shader;
static constexpr std::string_view HELP_URL =
"https://github.com/Xaymar/obs-StreamFX/wiki/Source-Filter-Transition-Shader";
shader_instance::shader_instance(obs_data_t* data, obs_source_t* self) : obs::source_instance(data, self), _fx()
{
_fx = std::make_shared<::gfx::shader::shader>(self, ::gfx::shader::shader_mode::Source);
@ -125,6 +128,13 @@ obs_properties_t* shader_factory::get_properties2(shader_instance* data)
auto pr = obs_properties_create();
obs_properties_set_param(pr, data, nullptr);
#ifdef ENABLE_FRONTEND
{
obs_properties_add_button2(pr, S_MANUAL_OPEN, D_TRANSLATE(S_MANUAL_OPEN),
streamfx::source::shader::shader_factory::on_manual_open, nullptr);
}
#endif
if (data) {
reinterpret_cast<shader_instance*>(data)->properties(pr);
}
@ -132,6 +142,14 @@ obs_properties_t* shader_factory::get_properties2(shader_instance* data)
return pr;
}
#ifdef ENABLE_FRONTEND
bool shader_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
{
streamfx::open_url(HELP_URL);
return false;
}
#endif
std::shared_ptr<shader_factory> _source_shader_factory_instance = nullptr;
void streamfx::source::shader::shader_factory::initialize()

View File

@ -58,6 +58,10 @@ namespace streamfx::source::shader {
virtual obs_properties_t* get_properties2(source::shader::shader_instance* data) override;
#ifdef ENABLE_FRONTEND
static bool on_manual_open(obs_properties_t* props, obs_property_t* property, void* data);
#endif
public: // Singleton
static void initialize();

View File

@ -24,7 +24,8 @@
#define PREFIX "streamfx-"
#define D_TRANSLATE(x) obs_module_text(x)
#define D_DESC(x) x ".Description"
#define S_MANUAL_OPEN "Manual.Open"
#define S_FILEFILTERS_IMAGE "*.png *.webp *.tga *.tiff *.jpeg *.jpg *.bmp"
#define S_FILEFILTERS_TEXTURE S_FILEFILTERS_IMAGE " *.dds"

View File

@ -26,6 +26,9 @@
using namespace streamfx::transition::shader;
static constexpr std::string_view HELP_URL =
"https://github.com/Xaymar/obs-StreamFX/wiki/Source-Filter-Transition-Shader";
shader_instance::shader_instance(obs_data_t* data, obs_source_t* self) : obs::source_instance(data, self)
{
_fx = std::make_shared<gfx::shader::shader>(self, gfx::shader::shader_mode::Transition);
@ -146,6 +149,13 @@ obs_properties_t* shader_factory::get_properties2(shader::shader_instance* data)
auto pr = obs_properties_create();
obs_properties_set_param(pr, data, nullptr);
#ifdef ENABLE_FRONTEND
{
obs_properties_add_button2(pr, S_MANUAL_OPEN, D_TRANSLATE(S_MANUAL_OPEN),
streamfx::transition::shader::shader_factory::on_manual_open, nullptr);
}
#endif
if (data) {
reinterpret_cast<shader_instance*>(data)->properties(pr);
}
@ -153,6 +163,14 @@ obs_properties_t* shader_factory::get_properties2(shader::shader_instance* data)
return pr;
}
#ifdef ENABLE_FRONTEND
bool shader_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
{
streamfx::open_url(HELP_URL);
return false;
}
#endif
std::shared_ptr<shader_factory> _transition_shader_factory_instance = nullptr;
void streamfx::transition::shader::shader_factory::initialize()

View File

@ -64,6 +64,10 @@ namespace streamfx::transition::shader {
virtual obs_properties_t* get_properties2(transition::shader::shader_instance* data) override;
#ifdef ENABLE_FRONTEND
static bool on_manual_open(obs_properties_t* props, obs_property_t* property, void* data);
#endif
public: // Singleton
static void initialize();