diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 1d99a131..24f6bd09 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -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." diff --git a/source/encoders/encoder-ffmpeg.cpp b/source/encoders/encoder-ffmpeg.cpp index 1dd1dd42..4668c23a 100644 --- a/source/encoders/encoder-ffmpeg.cpp +++ b/source/encoders/encoder-ffmpeg.cpp @@ -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::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::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::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(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(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(*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(data); + streamfx::open_url(ptr->_handler->get_help_url(ptr->_avcodec)); + return false; +} +#endif + const AVCodec* ffmpeg_factory::get_avcodec() { return _avcodec; diff --git a/source/encoders/encoder-ffmpeg.hpp b/source/encoders/encoder-ffmpeg.hpp index c2ca91a1..4f1fc1bb 100644 --- a/source/encoders/encoder-ffmpeg.hpp +++ b/source/encoders/encoder-ffmpeg.hpp @@ -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(); diff --git a/source/encoders/handlers/amf_h264_handler.cpp b/source/encoders/handlers/amf_h264_handler.cpp index 7e2d747f..7b60a6b0 100644 --- a/source/encoders/handlers/amf_h264_handler.cpp +++ b/source/encoders/handlers/amf_h264_handler.cpp @@ -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(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(level::UNKNOWN)); for (auto const kv : levels) { obs_property_list_add_int(p, kv.second.c_str(), static_cast(kv.first)); diff --git a/source/encoders/handlers/amf_h264_handler.hpp b/source/encoders/handlers/amf_h264_handler.hpp index 1bbb4edc..04b5be71 100644 --- a/source/encoders/handlers/amf_h264_handler.hpp +++ b/source/encoders/handlers/amf_h264_handler.hpp @@ -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; diff --git a/source/encoders/handlers/amf_hevc_handler.cpp b/source/encoders/handlers/amf_hevc_handler.cpp index fb902c36..d4a194bc 100644 --- a/source/encoders/handlers/amf_hevc_handler.cpp +++ b/source/encoders/handlers/amf_hevc_handler.cpp @@ -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(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(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(level::UNKNOWN)); for (auto const kv : levels) { obs_property_list_add_int(p, kv.second.c_str(), static_cast(kv.first)); diff --git a/source/encoders/handlers/amf_hevc_handler.hpp b/source/encoders/handlers/amf_hevc_handler.hpp index 4e0f9620..756a31dc 100644 --- a/source/encoders/handlers/amf_hevc_handler.hpp +++ b/source/encoders/handlers/amf_hevc_handler.hpp @@ -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); diff --git a/source/encoders/handlers/amf_shared.cpp b/source/encoders/handlers/amf_shared.cpp index 24722949..560017d7 100644 --- a/source/encoders/handlers/amf_shared.cpp +++ b/source/encoders/handlers/amf_shared.cpp @@ -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(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(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::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)); } } diff --git a/source/encoders/handlers/handler.hpp b/source/encoders/handlers/handler.hpp index 855d0a72..402a1ec3 100644 --- a/source/encoders/handlers/handler.hpp +++ b/source/encoders/handlers/handler.hpp @@ -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); diff --git a/source/encoders/handlers/nvenc_h264_handler.cpp b/source/encoders/handlers/nvenc_h264_handler.cpp index 9a91ab3a..df5563ba 100644 --- a/source/encoders/handlers/nvenc_h264_handler.cpp +++ b/source/encoders/handlers/nvenc_h264_handler.cpp @@ -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(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(level::UNKNOWN)); for (auto const kv : levels) { obs_property_list_add_int(p, kv.second.c_str(), static_cast(kv.first)); diff --git a/source/encoders/handlers/nvenc_h264_handler.hpp b/source/encoders/handlers/nvenc_h264_handler.hpp index 45131ce0..4b441463 100644 --- a/source/encoders/handlers/nvenc_h264_handler.hpp +++ b/source/encoders/handlers/nvenc_h264_handler.hpp @@ -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); diff --git a/source/encoders/handlers/nvenc_hevc_handler.cpp b/source/encoders/handlers/nvenc_hevc_handler.cpp index 491473c0..2ee923b3 100644 --- a/source/encoders/handlers/nvenc_hevc_handler.cpp +++ b/source/encoders/handlers/nvenc_hevc_handler.cpp @@ -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(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(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(level::UNKNOWN)); for (auto const kv : levels) { obs_property_list_add_int(p, kv.second.c_str(), static_cast(kv.first)); diff --git a/source/encoders/handlers/nvenc_hevc_handler.hpp b/source/encoders/handlers/nvenc_hevc_handler.hpp index 624b2a31..a3ae780d 100644 --- a/source/encoders/handlers/nvenc_hevc_handler.hpp +++ b/source/encoders/handlers/nvenc_hevc_handler.hpp @@ -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); diff --git a/source/encoders/handlers/nvenc_shared.cpp b/source/encoders/handlers/nvenc_shared.cpp index 493c603b..54ad7a96 100644 --- a/source/encoders/handlers/nvenc_shared.cpp +++ b/source/encoders/handlers/nvenc_shared.cpp @@ -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(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(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::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"); } } diff --git a/source/encoders/handlers/prores_aw_handler.cpp b/source/encoders/handlers/prores_aw_handler.cpp index cc332255..ffbd0d48 100644 --- a/source/encoders/handlers/prores_aw_handler.cpp +++ b/source/encoders/handlers/prores_aw_handler.cpp @@ -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(ptr->profile)); } diff --git a/source/encoders/handlers/prores_aw_handler.hpp b/source/encoders/handlers/prores_aw_handler.hpp index a04352ff..a58630ba 100644 --- a/source/encoders/handlers/prores_aw_handler.hpp +++ b/source/encoders/handlers/prores_aw_handler.hpp @@ -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; diff --git a/source/filters/filter-blur.cpp b/source/filters/filter-blur.cpp index fc6bf59f..0fa3bb45 100644 --- a/source/filters/filter-blur.cpp +++ b/source/filters/filter-blur.cpp @@ -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(mask_type::Region)); obs_property_list_add_int(p, D_TRANSLATE(ST_MASK_TYPE_IMAGE), static_cast(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 _filter_blur_factory_instance = nullptr; void streamfx::filter::blur::blur_factory::initialize() diff --git a/source/filters/filter-blur.hpp b/source/filters/filter-blur.hpp index 5c09a127..2db15e97 100644 --- a/source/filters/filter-blur.hpp +++ b/source/filters/filter-blur.hpp @@ -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(); diff --git a/source/filters/filter-color-grade.cpp b/source/filters/filter-color-grade.cpp index b551e4ab..442a3f21 100644 --- a/source/filters/filter-color-grade.cpp +++ b/source/filters/filter-color-grade.cpp @@ -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 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_instance = nullptr; void streamfx::filter::color_grade::color_grade_factory::initialize() diff --git a/source/filters/filter-color-grade.hpp b/source/filters/filter-color-grade.hpp index 404d7bce..f37fe401 100644 --- a/source/filters/filter-color-grade.hpp +++ b/source/filters/filter-color-grade.hpp @@ -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(); diff --git a/source/filters/filter-displacement.cpp b/source/filters/filter-displacement.cpp index 7175df90..cc0717c6 100644 --- a/source/filters/filter-displacement.cpp +++ b/source/filters/filter-displacement.cpp @@ -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; } diff --git a/source/filters/filter-dynamic-mask.cpp b/source/filters/filter-dynamic-mask.cpp index 74d768f0..5ea6f1e7 100644 --- a/source/filters/filter-dynamic-mask.cpp +++ b/source/filters/filter-dynamic-mask.cpp @@ -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_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 _filter_dynamic_mask_factory_instance = nullptr; void streamfx::filter::dynamic_mask::dynamic_mask_factory::initialize() diff --git a/source/filters/filter-dynamic-mask.hpp b/source/filters/filter-dynamic-mask.hpp index 799a9ac7..0f552adf 100644 --- a/source/filters/filter-dynamic-mask.hpp +++ b/source/filters/filter-dynamic-mask.hpp @@ -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(); diff --git a/source/filters/filter-nv-face-tracking.cpp b/source/filters/filter-nv-face-tracking.cpp index 5aac07d0..218c7b3e 100644 --- a/source/filters/filter-nv-face-tracking.cpp +++ b/source/filters/filter-nv-face-tracking.cpp @@ -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, " %"); } } diff --git a/source/filters/filter-sdf-effects.cpp b/source/filters/filter-sdf-effects.cpp index fe1da3ca..b97272d0 100644 --- a/source/filters/filter-sdf-effects.cpp +++ b/source/filters/filter-sdf-effects.cpp @@ -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 _filter_sdf_effects_factory_instance = nullptr; void streamfx::filter::sdf_effects::sdf_effects_factory::initialize() diff --git a/source/filters/filter-sdf-effects.hpp b/source/filters/filter-sdf-effects.hpp index b37cf989..21b00684 100644 --- a/source/filters/filter-sdf-effects.hpp +++ b/source/filters/filter-sdf-effects.hpp @@ -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(); diff --git a/source/filters/filter-shader.cpp b/source/filters/filter-shader.cpp index db40adb1..10dbe1e9 100644 --- a/source/filters/filter-shader.cpp +++ b/source/filters/filter-shader.cpp @@ -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(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(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 _filter_shader_factory_instance = nullptr; void streamfx::filter::shader::shader_factory::initialize() diff --git a/source/filters/filter-shader.hpp b/source/filters/filter-shader.hpp index 2769fd6f..6f921850 100644 --- a/source/filters/filter-shader.hpp +++ b/source/filters/filter-shader.hpp @@ -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(); diff --git a/source/filters/filter-transform.cpp b/source/filters/filter-transform.cpp index a11ad7c5..ac2578eb 100644 --- a/source/filters/filter-transform.cpp +++ b/source/filters/filter-transform.cpp @@ -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(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::lowest(), std::numeric_limits::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 _filter_transform_factory_instance = nullptr; void transform_factory::initialize() diff --git a/source/filters/filter-transform.hpp b/source/filters/filter-transform.hpp index 6b4fb856..4eb80507 100644 --- a/source/filters/filter-transform.hpp +++ b/source/filters/filter-transform.hpp @@ -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(); diff --git a/source/gfx/shader/gfx-shader.cpp b/source/gfx/shader/gfx-shader.cpp index afdcf680..13971d49 100644 --- a/source/gfx/shader/gfx-shader.cpp +++ b/source/gfx/shader/gfx-shader.cpp @@ -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::min(), std::numeric_limits::max(), 1); - obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_SHADER_SEED))); } } { diff --git a/source/sources/source-mirror.cpp b/source/sources/source-mirror.cpp index 5ff79624..84f8bc33 100644 --- a/source/sources/source-mirror.cpp +++ b/source/sources/source-mirror.cpp @@ -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(SPEAKERS_5POINT1)); obs_property_list_add_int(p, D_TRANSLATE(ST_SOURCE_AUDIO_LAYOUT_(FullSurround)), static_cast(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 _source_mirror_factory_instance; void streamfx::source::mirror::mirror_factory::initialize() diff --git a/source/sources/source-mirror.hpp b/source/sources/source-mirror.hpp index 6884949d..5ecb96dd 100644 --- a/source/sources/source-mirror.hpp +++ b/source/sources/source-mirror.hpp @@ -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(); diff --git a/source/sources/source-shader.cpp b/source/sources/source-shader.cpp index bbb3004c..4f1755d7 100644 --- a/source/sources/source-shader.cpp +++ b/source/sources/source-shader.cpp @@ -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(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 _source_shader_factory_instance = nullptr; void streamfx::source::shader::shader_factory::initialize() diff --git a/source/sources/source-shader.hpp b/source/sources/source-shader.hpp index a3fc253f..deebcc14 100644 --- a/source/sources/source-shader.hpp +++ b/source/sources/source-shader.hpp @@ -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(); diff --git a/source/strings.hpp b/source/strings.hpp index c840c356..b4c72196 100644 --- a/source/strings.hpp +++ b/source/strings.hpp @@ -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" diff --git a/source/transitions/transition-shader.cpp b/source/transitions/transition-shader.cpp index bc4694d1..9be3f3c2 100644 --- a/source/transitions/transition-shader.cpp +++ b/source/transitions/transition-shader.cpp @@ -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(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(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 _transition_shader_factory_instance = nullptr; void streamfx::transition::shader::shader_factory::initialize() diff --git a/source/transitions/transition-shader.hpp b/source/transitions/transition-shader.hpp index b38cc125..9e3d66cb 100644 --- a/source/transitions/transition-shader.hpp +++ b/source/transitions/transition-shader.hpp @@ -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();