mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-14 07:45:06 +00:00
ffmpeg-encoder: Improve UI, fix acceleration encode, etc
This commit is contained in:
parent
96ac0bd11b
commit
5d5a104819
5 changed files with 188 additions and 186 deletions
|
@ -368,107 +368,108 @@ Codec.ProRes.Profile.AP4H="4444 Standard (AP4H)"
|
||||||
Codec.ProRes.Profile.AP4X="4444 Extra Quality/XQ (AP4X)"
|
Codec.ProRes.Profile.AP4X="4444 Extra Quality/XQ (AP4X)"
|
||||||
|
|
||||||
# Encoder: FFmpeg
|
# Encoder: FFmpeg
|
||||||
Encoder.FFmpeg="FFmpeg Options"
|
FFmpegEncoder="FFmpeg Options"
|
||||||
Encoder.FFmpeg.CustomSettings="Custom Settings"
|
FFmpegEncoder.CustomSettings="Custom Settings"
|
||||||
Encoder.FFmpeg.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.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'"
|
||||||
Encoder.FFmpeg.Threads="Number of Threads"
|
FFmpegEncoder.Threads="Number of Threads"
|
||||||
Encoder.FFmpeg.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.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."
|
||||||
Encoder.FFmpeg.ColorFormat="Override Color Format"
|
FFmpegEncoder.ColorFormat="Override Color Format"
|
||||||
Encoder.FFmpeg.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.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."
|
||||||
Encoder.FFmpeg.StandardCompliance="Standard Compliance"
|
FFmpegEncoder.StandardCompliance="Standard Compliance"
|
||||||
Encoder.FFmpeg.StandardCompliance.Description="How strict should the encoder keep to the standard? A strictness below 'Normal' may cause issues with playback."
|
FFmpegEncoder.StandardCompliance.Description="How strict should the encoder keep to the standard? A strictness below 'Normal' may cause issues with playback."
|
||||||
Encoder.FFmpeg.StandardCompliance.VeryStrict="Very Strict"
|
FFmpegEncoder.StandardCompliance.VeryStrict="Very Strict"
|
||||||
Encoder.FFmpeg.StandardCompliance.Strict="Strict"
|
FFmpegEncoder.StandardCompliance.Strict="Strict"
|
||||||
Encoder.FFmpeg.StandardCompliance.Normal="Normal"
|
FFmpegEncoder.StandardCompliance.Normal="Normal"
|
||||||
Encoder.FFmpeg.StandardCompliance.Unofficial="Unofficial"
|
FFmpegEncoder.StandardCompliance.Unofficial="Unofficial"
|
||||||
Encoder.FFmpeg.StandardCompliance.Experimental="Experimental"
|
FFmpegEncoder.StandardCompliance.Experimental="Experimental"
|
||||||
Encoder.FFmpeg.GPU="GPU"
|
FFmpegEncoder.GPU="GPU"
|
||||||
Encoder.FFmpeg.GPU.Description="For multiple GPU systems, selects which GPU to use as the main encoder"
|
FFmpegEncoder.GPU.Description="For multiple GPU systems, selects which GPU to use as the main encoder"
|
||||||
Encoder.FFmpeg.KeyFrames="Key Frames"
|
FFmpegEncoder.KeyFrames="Key Frames"
|
||||||
Encoder.FFmpeg.KeyFrames.IntervalType="Interval Type"
|
FFmpegEncoder.KeyFrames.IntervalType="Interval Type"
|
||||||
Encoder.FFmpeg.KeyFrames.IntervalType.Frames="Frames"
|
FFmpegEncoder.KeyFrames.IntervalType.Frames="Frames"
|
||||||
Encoder.FFmpeg.KeyFrames.IntervalType.Seconds="Seconds"
|
FFmpegEncoder.KeyFrames.IntervalType.Seconds="Seconds"
|
||||||
Encoder.FFmpeg.KeyFrames.IntervalType.Description="Keyframe interval type"
|
FFmpegEncoder.KeyFrames.IntervalType.Description="Keyframe interval type"
|
||||||
Encoder.FFmpeg.KeyFrames.Interval.Description="Distance between key frames, in frames or seconds."
|
FFmpegEncoder.KeyFrames.Interval.Description="Distance between key frames, in frames or seconds."
|
||||||
Encoder.FFmpeg.KeyFrames.Interval="Interval"
|
FFmpegEncoder.KeyFrames.Interval="Interval"
|
||||||
|
|
||||||
# Encoder: NVENC
|
# Encoder: NVENC
|
||||||
Encoder.NVENC.Preset="Preset"
|
FFmpegEncoder.NVENC.Preset="Preset"
|
||||||
Encoder.NVENC.Preset.Description="Presets are NVIDIA's preconfigured default settings."
|
FFmpegEncoder.NVENC.Preset.Description="Presets are NVIDIA's preconfigured default settings."
|
||||||
Encoder.NVENC.Preset.Default="Default"
|
FFmpegEncoder.NVENC.Preset.Default="Default"
|
||||||
Encoder.NVENC.Preset.Slow="Slow"
|
FFmpegEncoder.NVENC.Preset.Slow="Slow"
|
||||||
Encoder.NVENC.Preset.Medium="Medium"
|
FFmpegEncoder.NVENC.Preset.Medium="Medium"
|
||||||
Encoder.NVENC.Preset.Fast="Fast"
|
FFmpegEncoder.NVENC.Preset.Fast="Fast"
|
||||||
Encoder.NVENC.Preset.HighPerformance="High Performance"
|
FFmpegEncoder.NVENC.Preset.HighPerformance="High Performance"
|
||||||
Encoder.NVENC.Preset.HighQuality="High Quality"
|
FFmpegEncoder.NVENC.Preset.HighQuality="High Quality"
|
||||||
Encoder.NVENC.Preset.BluRayDisc="BluRay Disc"
|
FFmpegEncoder.NVENC.Preset.BluRayDisc="BluRay Disc"
|
||||||
Encoder.NVENC.Preset.LowLatency="Low Latency"
|
FFmpegEncoder.NVENC.Preset.LowLatency="Low Latency"
|
||||||
Encoder.NVENC.Preset.LowLatencyHighPerformance="Low Latency High Performance"
|
FFmpegEncoder.NVENC.Preset.LowLatencyHighPerformance="Low Latency High Performance"
|
||||||
Encoder.NVENC.Preset.LowLatencyHighQuality="Low Latency High Quality"
|
FFmpegEncoder.NVENC.Preset.LowLatencyHighQuality="Low Latency High Quality"
|
||||||
Encoder.NVENC.Preset.Lossless="Lossless"
|
FFmpegEncoder.NVENC.Preset.Lossless="Lossless"
|
||||||
Encoder.NVENC.Preset.LosslessHighPerformance="Lossless High Performance"
|
FFmpegEncoder.NVENC.Preset.LosslessHighPerformance="Lossless High Performance"
|
||||||
Encoder.NVENC.RateControl="Rate Control Options"
|
FFmpegEncoder.NVENC.RateControl="Rate Control Options"
|
||||||
Encoder.NVENC.RateControl.Mode="Mode"
|
FFmpegEncoder.NVENC.RateControl.Mode="Mode"
|
||||||
Encoder.NVENC.RateControl.Mode.Description="Rate control mode selection"
|
FFmpegEncoder.NVENC.RateControl.Mode.Description="Rate control mode selection"
|
||||||
Encoder.NVENC.RateControl.Mode.CQP="Constant Quantization Parameter"
|
FFmpegEncoder.NVENC.RateControl.Mode.CQP="Constant Quantization Parameter"
|
||||||
Encoder.NVENC.RateControl.Mode.CQP.Description="A flat compression ratio with no regard for bit rates."
|
FFmpegEncoder.NVENC.RateControl.Mode.CQP.Description="A flat compression ratio with no regard for bit rates."
|
||||||
Encoder.NVENC.RateControl.Mode.VBR="Variable Bitrate"
|
FFmpegEncoder.NVENC.RateControl.Mode.VBR="Variable Bitrate"
|
||||||
Encoder.NVENC.RateControl.Mode.VBR.Description="Sacrifices quality to stay below the upper bitrate limit,\nor saves bitrate where possible."
|
FFmpegEncoder.NVENC.RateControl.Mode.VBR.Description="Sacrifices quality to stay below the upper bitrate limit,\nor saves bitrate where possible."
|
||||||
Encoder.NVENC.RateControl.Mode.VBR_HQ="High Quality Variable Bitrate"
|
FFmpegEncoder.NVENC.RateControl.Mode.VBR_HQ="High Quality Variable Bitrate"
|
||||||
Encoder.NVENC.RateControl.Mode.VBR_HQ.Description="Variable Bitrate with two-pass encoding enabled by default."
|
FFmpegEncoder.NVENC.RateControl.Mode.VBR_HQ.Description="Variable Bitrate with two-pass encoding enabled by default."
|
||||||
Encoder.NVENC.RateControl.Mode.CBR="Constant Bitrate"
|
FFmpegEncoder.NVENC.RateControl.Mode.CBR="Constant Bitrate"
|
||||||
Encoder.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.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."
|
||||||
Encoder.NVENC.RateControl.Mode.CBR_HQ="High Quality Constant Bitrate"
|
FFmpegEncoder.NVENC.RateControl.Mode.CBR_HQ="High Quality Constant Bitrate"
|
||||||
Encoder.NVENC.RateControl.Mode.CBR_HQ.Description="Constant Bitrate with two-pass encoding enabled by default."
|
FFmpegEncoder.NVENC.RateControl.Mode.CBR_HQ.Description="Constant Bitrate with two-pass encoding enabled by default."
|
||||||
Encoder.NVENC.RateControl.Mode.CBR_LD_HQ="Low Delay High Quality Constant Bitrate"
|
FFmpegEncoder.NVENC.RateControl.Mode.CBR_LD_HQ="Low Delay High Quality Constant Bitrate"
|
||||||
Encoder.NVENC.RateControl.Mode.CBR_LD_HQ.Description="Constant Bitrate optimized for lowest encoding latency."
|
FFmpegEncoder.NVENC.RateControl.Mode.CBR_LD_HQ.Description="Constant Bitrate optimized for lowest encoding latency."
|
||||||
Encoder.NVENC.RateControl.LookAhead="Look Ahead"
|
FFmpegEncoder.NVENC.RateControl.LookAhead="Look Ahead"
|
||||||
Encoder.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.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."
|
||||||
Encoder.NVENC.RateControl.AdaptiveI="Adaptive I-Frames"
|
FFmpegEncoder.NVENC.RateControl.AdaptiveI="Adaptive I-Frames"
|
||||||
Encoder.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.AdaptiveI.Description="Enables adaptive I-Frame insertion.\nOnly has an effect when look ahead is set to a value other than 0."
|
||||||
Encoder.NVENC.RateControl.AdaptiveB="Adaptive B-Frames"
|
FFmpegEncoder.NVENC.RateControl.AdaptiveB="Adaptive B-Frames"
|
||||||
Encoder.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.AdaptiveB.Description="Enables adaptive B-Frame insertion.\nOnly has an effect when look ahead is set to a value other than 0."
|
||||||
Encoder.NVENC.RateControl.TwoPass="Two Pass"
|
FFmpegEncoder.NVENC.RateControl.TwoPass="Two Pass"
|
||||||
Encoder.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.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."
|
||||||
Encoder.NVENC.RateControl.Bitrate="Bitrate Limits"
|
FFmpegEncoder.NVENC.RateControl.Bitrate="Bitrate Limits"
|
||||||
Encoder.NVENC.RateControl.Bitrate.Target="Target Bitrate"
|
FFmpegEncoder.NVENC.RateControl.Bitrate.Target="Target Bitrate"
|
||||||
Encoder.NVENC.RateControl.Bitrate.Maximum="Maximum Bitrate"
|
FFmpegEncoder.NVENC.RateControl.Bitrate.Maximum="Maximum Bitrate"
|
||||||
Encoder.NVENC.RateControl.Quality="Enable Quality Limits"
|
FFmpegEncoder.NVENC.RateControl.BufferSize="Buffer Size"
|
||||||
Encoder.NVENC.RateControl.Quality.Minimum="Minimum Quality"
|
FFmpegEncoder.NVENC.RateControl.Quality="Enable Quality Limits"
|
||||||
Encoder.NVENC.RateControl.Quality.Minimum.Description="Minimum quality to achieve, with values closer to 0 being better quality."
|
FFmpegEncoder.NVENC.RateControl.Quality.Minimum="Minimum Quality"
|
||||||
Encoder.NVENC.RateControl.Quality.Maximum="Maximum Quality"
|
FFmpegEncoder.NVENC.RateControl.Quality.Minimum.Description="Minimum quality to achieve, with values closer to 0 being better quality."
|
||||||
Encoder.NVENC.RateControl.Quality.Maximum.Description="Maximum quality to achieve, with values closer to 0 being better quality.\nSet to -1 to disable the maximum restriction."
|
FFmpegEncoder.NVENC.RateControl.Quality.Maximum="Maximum Quality"
|
||||||
Encoder.NVENC.RateControl.Quality.Target="Target Quality"
|
FFmpegEncoder.NVENC.RateControl.Quality.Maximum.Description="Maximum quality to achieve, with values closer to 0 being better quality.\nSet to -1 to disable the maximum restriction."
|
||||||
Encoder.NVENC.RateControl.Quality.Target.Description="Target quality to achieve, with values closer to 0 being better quality.\nSet to 0 to disable the maximum restriction."
|
FFmpegEncoder.NVENC.RateControl.Quality.Target="Target Quality"
|
||||||
Encoder.NVENC.RateControl.QP="Quantization Parameters"
|
FFmpegEncoder.NVENC.RateControl.Quality.Target.Description="Target quality to achieve, with values closer to 0 being better quality.\nSet to 0 to disable the maximum restriction."
|
||||||
Encoder.NVENC.RateControl.QP.I="I-Frame QP"
|
FFmpegEncoder.NVENC.RateControl.QP="Quantization Parameters"
|
||||||
Encoder.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.I="I-Frame QP"
|
||||||
Encoder.NVENC.RateControl.QP.I.Initial="Initial 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."
|
||||||
Encoder.NVENC.RateControl.QP.I.Initial.Description="Initial B-Frame quantization parameter.\nSet to -1 to use the automatically detected value instead."
|
FFmpegEncoder.NVENC.RateControl.QP.I.Initial="Initial I-Frame QP"
|
||||||
Encoder.NVENC.RateControl.QP.P="P-Frame QP"
|
FFmpegEncoder.NVENC.RateControl.QP.I.Initial.Description="Initial B-Frame quantization parameter.\nSet to -1 to use the automatically detected value instead."
|
||||||
Encoder.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.P="P-Frame QP"
|
||||||
Encoder.NVENC.RateControl.QP.P.Initial="Initial 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."
|
||||||
Encoder.NVENC.RateControl.QP.P.Initial.Description="Initial P-Frame quantization parameter.\nSet to -1 to use the automatically detected value instead."
|
FFmpegEncoder.NVENC.RateControl.QP.P.Initial="Initial P-Frame QP"
|
||||||
Encoder.NVENC.RateControl.QP.B="B-Frame QP"
|
FFmpegEncoder.NVENC.RateControl.QP.P.Initial.Description="Initial P-Frame quantization parameter.\nSet to -1 to use the automatically detected value instead."
|
||||||
Encoder.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.RateControl.QP.B="B-Frame QP"
|
||||||
Encoder.NVENC.RateControl.QP.B.Initial="Initial 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."
|
||||||
Encoder.NVENC.RateControl.QP.B.Initial.Description="Initial B-Frame quantization parameter.\nSet to -1 to use the automatically detected value instead."
|
FFmpegEncoder.NVENC.RateControl.QP.B.Initial="Initial B-Frame QP"
|
||||||
Encoder.NVENC.AQ="Adaptive Quantization"
|
FFmpegEncoder.NVENC.RateControl.QP.B.Initial.Description="Initial B-Frame quantization parameter.\nSet to -1 to use the automatically detected value instead."
|
||||||
Encoder.NVENC.AQ.Spatial="Spatial Adaptive Quantization"
|
FFmpegEncoder.NVENC.AQ="Adaptive Quantization"
|
||||||
Encoder.NVENC.AQ.Spatial.Description="Enable spatial adaptive quantization, also sometimes referred to as Psychovisual Adaptive Quantization."
|
FFmpegEncoder.NVENC.AQ.Spatial="Spatial Adaptive Quantization"
|
||||||
Encoder.NVENC.AQ.Strength="Spatial AQ Strength"
|
FFmpegEncoder.NVENC.AQ.Spatial.Description="Enable spatial adaptive quantization, also sometimes referred to as Psychovisual Adaptive Quantization."
|
||||||
Encoder.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.Strength="Spatial AQ Strength"
|
||||||
Encoder.NVENC.AQ.Temporal="Temporal Adaptive Quantization"
|
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."
|
||||||
Encoder.NVENC.AQ.Temporal.Description="Enable temporal adaptive quantization."
|
FFmpegEncoder.NVENC.AQ.Temporal="Temporal Adaptive Quantization"
|
||||||
Encoder.NVENC.Other="Other Options"
|
FFmpegEncoder.NVENC.AQ.Temporal.Description="Enable temporal adaptive quantization."
|
||||||
Encoder.NVENC.Other.BFrames="Maximum B-Frames"
|
FFmpegEncoder.NVENC.Other="Other Options"
|
||||||
Encoder.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.BFrames="Maximum B-Frames"
|
||||||
Encoder.NVENC.Other.BFrameReferenceMode="B-Frame Reference Mode"
|
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."
|
||||||
Encoder.NVENC.Other.BFrameReferenceMode.Each="Each B-Frame will be used for references"
|
FFmpegEncoder.NVENC.Other.BFrameReferenceMode="B-Frame Reference Mode"
|
||||||
Encoder.NVENC.Other.BFrameReferenceMode.Middle="Only (# of B-Frames)/2 will be used for references"
|
FFmpegEncoder.NVENC.Other.BFrameReferenceMode.Each="Each B-Frame will be used for references"
|
||||||
Encoder.NVENC.Other.ZeroLatency="Zero Latency"
|
FFmpegEncoder.NVENC.Other.BFrameReferenceMode.Middle="Only (# of B-Frames)/2 will be used for references"
|
||||||
Encoder.NVENC.Other.ZeroLatency.Description="Enable zero latency operation, which ensures that there is no reordering delay."
|
FFmpegEncoder.NVENC.Other.ZeroLatency="Zero Latency"
|
||||||
Encoder.NVENC.Other.WeightedPrediction="Weighted Prediction"
|
FFmpegEncoder.NVENC.Other.ZeroLatency.Description="Enable zero latency operation, which ensures that there is no reordering delay."
|
||||||
Encoder.NVENC.Other.WeightedPrediction.Description="Enable weighted prediction for encoding.\nCan't be used with B-Frames."
|
FFmpegEncoder.NVENC.Other.WeightedPrediction="Weighted Prediction"
|
||||||
Encoder.NVENC.Other.NonReferencePFrames="Non-reference P-Frames"
|
FFmpegEncoder.NVENC.Other.WeightedPrediction.Description="Enable weighted prediction for encoding.\nCan't be used with B-Frames."
|
||||||
Encoder.NVENC.Other.NonReferencePFrames.Description="Enable the automatic insertion of non-reference P-Frames."
|
FFmpegEncoder.NVENC.Other.NonReferencePFrames="Non-reference P-Frames"
|
||||||
|
FFmpegEncoder.NVENC.Other.NonReferencePFrames.Description="Enable the automatic insertion of non-reference P-Frames."
|
||||||
|
|
|
@ -50,12 +50,28 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FFmpeg
|
// FFmpeg
|
||||||
#define ST_FFMPEG "FFmpeg"
|
#define ST_FFMPEG "FFmpegEncoder"
|
||||||
#define ST_FFMPEG_CUSTOMSETTINGS "FFmpeg.CustomSettings"
|
#define ST_FFMPEG_CUSTOMSETTINGS "FFmpegEncoder.CustomSettings"
|
||||||
#define ST_FFMPEG_THREADS "FFmpeg.Threads"
|
#define ST_FFMPEG_THREADS "FFmpegEncoder.Threads"
|
||||||
#define ST_FFMPEG_COLORFORMAT "FFmpeg.ColorFormat"
|
#define ST_FFMPEG_COLORFORMAT "FFmpegEncoder.ColorFormat"
|
||||||
#define ST_FFMPEG_STANDARDCOMPLIANCE "FFmpeg.StandardCompliance"
|
#define ST_FFMPEG_STANDARDCOMPLIANCE "FFmpegEncoder.StandardCompliance"
|
||||||
#define ST_FFMPEG_GPU "FFmpeg.GPU"
|
#define ST_FFMPEG_GPU "FFmpegEncoder.GPU"
|
||||||
|
#define KEY_FFMPEG_CUSTOMSETTINGS "FFmpeg.CustomSettings"
|
||||||
|
#define KEY_FFMPEG_THREADS "FFmpeg.Threads"
|
||||||
|
#define KEY_FFMPEG_COLORFORMAT "FFmpeg.ColorFormat"
|
||||||
|
#define KEY_FFMPEG_STANDARDCOMPLIANCE "FFmpeg.StandardCompliance"
|
||||||
|
#define KEY_FFMPEG_GPU "FFmpeg.GPU"
|
||||||
|
|
||||||
|
#define ST_KEYFRAMES "FFmpegEncoder.KeyFrames"
|
||||||
|
#define ST_KEYFRAMES_INTERVALTYPE "FFmpegEncoder.KeyFrames.IntervalType"
|
||||||
|
#define ST_KEYFRAMES_INTERVALTYPE_(x) "FFmpegEncoder.KeyFrames.IntervalType." D_VSTR(x)
|
||||||
|
#define ST_KEYFRAMES_INTERVAL "FFmpegEncoder.KeyFrames.Interval"
|
||||||
|
#define ST_KEYFRAMES_INTERVAL_SECONDS "FFmpegEncoder.KeyFrames.Interval.Seconds"
|
||||||
|
#define ST_KEYFRAMES_INTERVAL_FRAMES "FFmpegEncoder.KeyFrames.Interval.Frames"
|
||||||
|
|
||||||
|
#define KEY_KEYFRAMES_INTERVALTYPE "KeyFrames.IntervalType"
|
||||||
|
#define KEY_KEYFRAMES_INTERVAL_SECONDS "KeyFrames.Interval.Seconds"
|
||||||
|
#define KEY_KEYFRAMES_INTERVAL_FRAMES "KeyFrames.Interval.Frames"
|
||||||
|
|
||||||
using namespace encoder::ffmpeg;
|
using namespace encoder::ffmpeg;
|
||||||
|
|
||||||
|
@ -463,28 +479,26 @@ void ffmpeg_factory::get_defaults(obs_data_t* settings, bool hw_encode)
|
||||||
_handler->get_defaults(settings, avcodec_ptr, nullptr, hw_encode);
|
_handler->get_defaults(settings, avcodec_ptr, nullptr, hw_encode);
|
||||||
|
|
||||||
if ((avcodec_ptr->capabilities & AV_CODEC_CAP_INTRA_ONLY) == 0) {
|
if ((avcodec_ptr->capabilities & AV_CODEC_CAP_INTRA_ONLY) == 0) {
|
||||||
obs_data_set_default_int(settings, S_KEYFRAMES_INTERVALTYPE, 0);
|
obs_data_set_default_int(settings, KEY_KEYFRAMES_INTERVALTYPE, 0);
|
||||||
obs_data_set_default_double(settings, S_KEYFRAMES_INTERVAL_SECONDS, 2.0);
|
obs_data_set_default_double(settings, KEY_KEYFRAMES_INTERVAL_SECONDS, 2.0);
|
||||||
obs_data_set_default_int(settings, S_KEYFRAMES_INTERVAL_FRAMES, 300);
|
obs_data_set_default_int(settings, KEY_KEYFRAMES_INTERVAL_FRAMES, 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Integrated Options
|
{ // Integrated Options
|
||||||
// FFmpeg
|
// FFmpeg
|
||||||
obs_data_set_default_string(settings, ST_FFMPEG_CUSTOMSETTINGS, "");
|
obs_data_set_default_string(settings, KEY_FFMPEG_CUSTOMSETTINGS, "");
|
||||||
if (!hw_encode) {
|
obs_data_set_default_int(settings, KEY_FFMPEG_COLORFORMAT, static_cast<int64_t>(AV_PIX_FMT_NONE));
|
||||||
obs_data_set_default_int(settings, ST_FFMPEG_COLORFORMAT, static_cast<int64_t>(AV_PIX_FMT_NONE));
|
obs_data_set_default_int(settings, KEY_FFMPEG_THREADS, 0);
|
||||||
obs_data_set_default_int(settings, ST_FFMPEG_THREADS, 0);
|
obs_data_set_default_int(settings, KEY_FFMPEG_GPU, -1);
|
||||||
obs_data_set_default_int(settings, ST_FFMPEG_GPU, 0);
|
obs_data_set_default_int(settings, KEY_FFMPEG_STANDARDCOMPLIANCE, FF_COMPLIANCE_STRICT);
|
||||||
}
|
|
||||||
obs_data_set_default_int(settings, ST_FFMPEG_STANDARDCOMPLIANCE, FF_COMPLIANCE_STRICT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool modified_keyframes(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
static bool modified_keyframes(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
||||||
try {
|
try {
|
||||||
bool is_seconds = obs_data_get_int(settings, S_KEYFRAMES_INTERVALTYPE) == 0;
|
bool is_seconds = obs_data_get_int(settings, KEY_KEYFRAMES_INTERVALTYPE) == 0;
|
||||||
obs_property_set_visible(obs_properties_get(props, S_KEYFRAMES_INTERVAL_FRAMES), !is_seconds);
|
obs_property_set_visible(obs_properties_get(props, KEY_KEYFRAMES_INTERVAL_FRAMES), !is_seconds);
|
||||||
obs_property_set_visible(obs_properties_get(props, S_KEYFRAMES_INTERVAL_SECONDS), is_seconds);
|
obs_property_set_visible(obs_properties_get(props, KEY_KEYFRAMES_INTERVAL_SECONDS), is_seconds);
|
||||||
return true;
|
return true;
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
|
@ -504,27 +518,27 @@ void ffmpeg_factory::get_properties(obs_properties_t* props, bool hw_encode)
|
||||||
obs_properties_t* grp = props;
|
obs_properties_t* grp = props;
|
||||||
if (!util::are_property_groups_broken()) {
|
if (!util::are_property_groups_broken()) {
|
||||||
grp = obs_properties_create();
|
grp = obs_properties_create();
|
||||||
obs_properties_add_group(props, S_KEYFRAMES, D_TRANSLATE(S_KEYFRAMES), OBS_GROUP_NORMAL, grp);
|
obs_properties_add_group(props, ST_KEYFRAMES, D_TRANSLATE(ST_KEYFRAMES), OBS_GROUP_NORMAL, grp);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto p = obs_properties_add_list(grp, S_KEYFRAMES_INTERVALTYPE, D_TRANSLATE(S_KEYFRAMES_INTERVALTYPE),
|
auto p = obs_properties_add_list(grp, KEY_KEYFRAMES_INTERVALTYPE, D_TRANSLATE(ST_KEYFRAMES_INTERVALTYPE),
|
||||||
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
||||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(S_KEYFRAMES_INTERVALTYPE)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_KEYFRAMES_INTERVALTYPE)));
|
||||||
obs_property_set_modified_callback(p, modified_keyframes);
|
obs_property_set_modified_callback(p, modified_keyframes);
|
||||||
obs_property_list_add_int(p, D_TRANSLATE(S_KEYFRAMES_INTERVALTYPE_(Seconds)), 0);
|
obs_property_list_add_int(p, D_TRANSLATE(ST_KEYFRAMES_INTERVALTYPE_(Seconds)), 0);
|
||||||
obs_property_list_add_int(p, D_TRANSLATE(S_KEYFRAMES_INTERVALTYPE_(Frames)), 1);
|
obs_property_list_add_int(p, D_TRANSLATE(ST_KEYFRAMES_INTERVALTYPE_(Frames)), 1);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto p = obs_properties_add_float(grp, S_KEYFRAMES_INTERVAL_SECONDS, D_TRANSLATE(S_KEYFRAMES_INTERVAL),
|
auto p = obs_properties_add_float(grp, KEY_KEYFRAMES_INTERVAL_SECONDS, D_TRANSLATE(ST_KEYFRAMES_INTERVAL),
|
||||||
0.00, std::numeric_limits<int16_t>::max(), 0.01);
|
0.00, std::numeric_limits<int16_t>::max(), 0.01);
|
||||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(S_KEYFRAMES_INTERVAL)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_KEYFRAMES_INTERVAL)));
|
||||||
obs_property_float_set_suffix(p, " seconds");
|
obs_property_float_set_suffix(p, " seconds");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto p = obs_properties_add_int(grp, S_KEYFRAMES_INTERVAL_FRAMES, D_TRANSLATE(S_KEYFRAMES_INTERVAL), 0,
|
auto p = obs_properties_add_int(grp, KEY_KEYFRAMES_INTERVAL_FRAMES, D_TRANSLATE(ST_KEYFRAMES_INTERVAL), 0,
|
||||||
std::numeric_limits<int32_t>::max(), 1);
|
std::numeric_limits<int32_t>::max(), 1);
|
||||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(S_KEYFRAMES_INTERVAL)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_KEYFRAMES_INTERVAL)));
|
||||||
obs_property_int_set_suffix(p, " frames");
|
obs_property_int_set_suffix(p, " frames");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -538,18 +552,18 @@ void ffmpeg_factory::get_properties(obs_properties_t* props, bool hw_encode)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto p = obs_properties_add_text(grp, ST_FFMPEG_CUSTOMSETTINGS, D_TRANSLATE(ST_FFMPEG_CUSTOMSETTINGS),
|
auto p = obs_properties_add_text(grp, KEY_FFMPEG_CUSTOMSETTINGS, D_TRANSLATE(ST_FFMPEG_CUSTOMSETTINGS),
|
||||||
obs_text_type::OBS_TEXT_DEFAULT);
|
obs_text_type::OBS_TEXT_DEFAULT);
|
||||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_FFMPEG_CUSTOMSETTINGS)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_FFMPEG_CUSTOMSETTINGS)));
|
||||||
}
|
}
|
||||||
if (!hw_encode) {
|
if (!hw_encode) {
|
||||||
{
|
{
|
||||||
auto p = obs_properties_add_int(grp, ST_FFMPEG_GPU, D_TRANSLATE(ST_FFMPEG_GPU), 0,
|
auto p = obs_properties_add_int(grp, KEY_FFMPEG_GPU, D_TRANSLATE(ST_FFMPEG_GPU), -1,
|
||||||
std::numeric_limits<uint8_t>::max(), 1);
|
std::numeric_limits<uint8_t>::max(), 1);
|
||||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_FFMPEG_GPU)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_FFMPEG_GPU)));
|
||||||
}
|
}
|
||||||
if (avcodec_ptr->pix_fmts) {
|
if (avcodec_ptr->pix_fmts) {
|
||||||
auto p = obs_properties_add_list(grp, ST_FFMPEG_COLORFORMAT, D_TRANSLATE(ST_FFMPEG_COLORFORMAT),
|
auto p = obs_properties_add_list(grp, KEY_FFMPEG_COLORFORMAT, D_TRANSLATE(ST_FFMPEG_COLORFORMAT),
|
||||||
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
||||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_FFMPEG_COLORFORMAT)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_FFMPEG_COLORFORMAT)));
|
||||||
obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), static_cast<int64_t>(AV_PIX_FMT_NONE));
|
obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), static_cast<int64_t>(AV_PIX_FMT_NONE));
|
||||||
|
@ -560,14 +574,14 @@ void ffmpeg_factory::get_properties(obs_properties_t* props, bool hw_encode)
|
||||||
}
|
}
|
||||||
if (avcodec_ptr->capabilities & (AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS)) {
|
if (avcodec_ptr->capabilities & (AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS)) {
|
||||||
auto p =
|
auto p =
|
||||||
obs_properties_add_int_slider(grp, ST_FFMPEG_THREADS, D_TRANSLATE(ST_FFMPEG_THREADS), 0,
|
obs_properties_add_int_slider(grp, KEY_FFMPEG_THREADS, D_TRANSLATE(ST_FFMPEG_THREADS), 0,
|
||||||
static_cast<int64_t>(std::thread::hardware_concurrency() * 2), 1);
|
static_cast<int64_t>(std::thread::hardware_concurrency() * 2), 1);
|
||||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_FFMPEG_THREADS)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_FFMPEG_THREADS)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto p =
|
auto p =
|
||||||
obs_properties_add_list(grp, ST_FFMPEG_STANDARDCOMPLIANCE, D_TRANSLATE(ST_FFMPEG_STANDARDCOMPLIANCE),
|
obs_properties_add_list(grp, KEY_FFMPEG_STANDARDCOMPLIANCE, D_TRANSLATE(ST_FFMPEG_STANDARDCOMPLIANCE),
|
||||||
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
||||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_FFMPEG_STANDARDCOMPLIANCE)));
|
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"),
|
obs_property_list_add_int(p, D_TRANSLATE(ST_FFMPEG_STANDARDCOMPLIANCE ".VeryStrict"),
|
||||||
|
@ -761,12 +775,22 @@ ffmpeg_instance::ffmpeg_instance(obs_data_t* settings, obs_encoder_t* encoder, b
|
||||||
|
|
||||||
// Initialize GPU Stuff
|
// Initialize GPU Stuff
|
||||||
if (is_texture_encode) {
|
if (is_texture_encode) {
|
||||||
|
// Abort if user specified manual override.
|
||||||
|
if ((static_cast<AVPixelFormat>(obs_data_get_int(settings, KEY_FFMPEG_COLORFORMAT)) != AV_PIX_FMT_NONE)
|
||||||
|
|| (obs_data_get_int(settings, KEY_FFMPEG_GPU) != -1)) {
|
||||||
|
throw std::runtime_error("Unable to create accelerated encoder due to user settings.");
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
auto gctx = util::obs_graphics();
|
auto gctx = util::obs_graphics();
|
||||||
if (gs_get_device_type() == GS_DEVICE_DIRECT3D_11) {
|
if (gs_get_device_type() == GS_DEVICE_DIRECT3D_11) {
|
||||||
_hwapi = std::make_shared<::ffmpeg::hwapi::d3d11>();
|
_hwapi = std::make_shared<::ffmpeg::hwapi::d3d11>();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (!_hwapi) {
|
||||||
|
throw std::runtime_error("Failed to create acceleration device.");
|
||||||
|
}
|
||||||
|
|
||||||
_hwinst = _hwapi->create_from_obs();
|
_hwinst = _hwapi->create_from_obs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -774,7 +798,7 @@ ffmpeg_instance::ffmpeg_instance(obs_data_t* settings, obs_encoder_t* encoder, b
|
||||||
_context = avcodec_alloc_context3(_codec);
|
_context = avcodec_alloc_context3(_codec);
|
||||||
if (!_context) {
|
if (!_context) {
|
||||||
LOG_ERROR("Failed to create context for encoder '%s'.", _codec->name);
|
LOG_ERROR("Failed to create context for encoder '%s'.", _codec->name);
|
||||||
throw std::runtime_error("failed to create context");
|
throw std::runtime_error("Failed to create encoder context.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create 8MB of precached Packet data for use later on.
|
// Create 8MB of precached Packet data for use later on.
|
||||||
|
@ -829,15 +853,14 @@ void ffmpeg_instance::get_properties(obs_properties_t* props, bool hw_encode)
|
||||||
if (_handler)
|
if (_handler)
|
||||||
_handler->get_properties(props, _codec, _context, hw_encode);
|
_handler->get_properties(props, _codec, _context, hw_encode);
|
||||||
|
|
||||||
obs_property_set_enabled(obs_properties_get(props, S_KEYFRAMES), false);
|
obs_property_set_enabled(obs_properties_get(props, KEY_KEYFRAMES_INTERVALTYPE), false);
|
||||||
obs_property_set_enabled(obs_properties_get(props, S_KEYFRAMES_INTERVALTYPE), false);
|
obs_property_set_enabled(obs_properties_get(props, KEY_KEYFRAMES_INTERVAL_SECONDS), false);
|
||||||
obs_property_set_enabled(obs_properties_get(props, S_KEYFRAMES_INTERVAL_SECONDS), false);
|
obs_property_set_enabled(obs_properties_get(props, KEY_KEYFRAMES_INTERVAL_FRAMES), false);
|
||||||
obs_property_set_enabled(obs_properties_get(props, S_KEYFRAMES_INTERVAL_FRAMES), false);
|
|
||||||
|
|
||||||
obs_property_set_enabled(obs_properties_get(props, ST_FFMPEG_COLORFORMAT), false);
|
obs_property_set_enabled(obs_properties_get(props, KEY_FFMPEG_COLORFORMAT), false);
|
||||||
obs_property_set_enabled(obs_properties_get(props, ST_FFMPEG_THREADS), false);
|
obs_property_set_enabled(obs_properties_get(props, KEY_FFMPEG_THREADS), false);
|
||||||
obs_property_set_enabled(obs_properties_get(props, ST_FFMPEG_STANDARDCOMPLIANCE), false);
|
obs_property_set_enabled(obs_properties_get(props, KEY_FFMPEG_STANDARDCOMPLIANCE), false);
|
||||||
obs_property_set_enabled(obs_properties_get(props, ST_FFMPEG_GPU), false);
|
obs_property_set_enabled(obs_properties_get(props, KEY_FFMPEG_GPU), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ffmpeg_instance::update(obs_data_t* settings)
|
bool ffmpeg_instance::update(obs_data_t* settings)
|
||||||
|
@ -873,7 +896,7 @@ bool ffmpeg_instance::update(obs_data_t* settings)
|
||||||
|
|
||||||
// Apply GPU Selection
|
// Apply GPU Selection
|
||||||
if (!_hwinst && ::ffmpeg::tools::can_hardware_encode(_codec)) {
|
if (!_hwinst && ::ffmpeg::tools::can_hardware_encode(_codec)) {
|
||||||
av_opt_set_int(_context, "gpu", (int)obs_data_get_int(settings, ST_FFMPEG_GPU), AV_OPT_SEARCH_CHILDREN);
|
av_opt_set_int(_context, "gpu", (int)obs_data_get_int(settings, KEY_FFMPEG_GPU), AV_OPT_SEARCH_CHILDREN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keyframes
|
// Keyframes
|
||||||
|
@ -884,14 +907,14 @@ bool ffmpeg_instance::update(obs_data_t* settings)
|
||||||
throw std::runtime_error("obs_get_video_info failed, restart OBS Studio to fix it (hopefully).");
|
throw std::runtime_error("obs_get_video_info failed, restart OBS Studio to fix it (hopefully).");
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t kf_type = obs_data_get_int(settings, S_KEYFRAMES_INTERVALTYPE);
|
int64_t kf_type = obs_data_get_int(settings, KEY_KEYFRAMES_INTERVALTYPE);
|
||||||
bool is_seconds = (kf_type == 0);
|
bool is_seconds = (kf_type == 0);
|
||||||
|
|
||||||
if (is_seconds) {
|
if (is_seconds) {
|
||||||
_context->gop_size = static_cast<int>(obs_data_get_double(settings, S_KEYFRAMES_INTERVAL_SECONDS)
|
_context->gop_size = static_cast<int>(obs_data_get_double(settings, KEY_KEYFRAMES_INTERVAL_SECONDS)
|
||||||
* (ovi.fps_num / ovi.fps_den));
|
* (ovi.fps_num / ovi.fps_den));
|
||||||
} else {
|
} else {
|
||||||
_context->gop_size = static_cast<int>(obs_data_get_int(settings, S_KEYFRAMES_INTERVAL_FRAMES));
|
_context->gop_size = static_cast<int>(obs_data_get_int(settings, KEY_KEYFRAMES_INTERVAL_FRAMES));
|
||||||
}
|
}
|
||||||
_context->keyint_min = _context->gop_size;
|
_context->keyint_min = _context->gop_size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,30 +44,6 @@ extern "C" {
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define S_RATECONTROL "FFmpeg.RateControl"
|
|
||||||
#define S_RATECONTROL_MODE "FFmpeg.RateControl.Mode"
|
|
||||||
#define S_RATECONTROL_MODE_(x) "FFmpeg.RateControl.Mode." D_VSTR(x)
|
|
||||||
#define S_RATECONTROL_BITRATE_TARGET "FFmpeg.RateControl.Bitrate.Target"
|
|
||||||
#define S_RATECONTROL_BITRATE_MINIMUM "FFmpeg.RateControl.Bitrate.Minimum"
|
|
||||||
#define S_RATECONTROL_BITRATE_MAXIMUM "FFmpeg.RateControl.Bitrate.Maximum"
|
|
||||||
#define S_RATECONTROL_BUFFERSIZE "FFmpeg.RateControl.BufferSize"
|
|
||||||
#define S_RATECONTROL_QUALITY_TARGET "RateControl.Quality.Target"
|
|
||||||
#define S_RATECONTROL_QUALITY_MINIMUM "RateControl.Quality.Minimum"
|
|
||||||
#define S_RATECONTROL_QUALITY_MAXIMUM "RateControl.Quality.Maximum"
|
|
||||||
#define S_RATECONTROL_QP_I "RateControl.QP.I"
|
|
||||||
#define S_RATECONTROL_QP_P "RateControl.QP.P"
|
|
||||||
#define S_RATECONTROL_QP_B "RateControl.QP.B"
|
|
||||||
#define S_RATECONTROL_QP_I_INITIAL "RateControl.QP.I.Initial"
|
|
||||||
#define S_RATECONTROL_QP_P_INITIAL "RateControl.QP.P.Initial"
|
|
||||||
#define S_RATECONTROL_QP_B_INITIAL "RateControl.QP.B.Initial"
|
|
||||||
|
|
||||||
#define S_KEYFRAMES "KeyFrames"
|
|
||||||
#define S_KEYFRAMES_INTERVALTYPE "KeyFrames.IntervalType"
|
|
||||||
#define S_KEYFRAMES_INTERVALTYPE_(x) "KeyFrames.IntervalType." D_VSTR(x)
|
|
||||||
#define S_KEYFRAMES_INTERVAL "KeyFrames.Interval"
|
|
||||||
#define S_KEYFRAMES_INTERVAL_SECONDS "KeyFrames.Interval.Seconds"
|
|
||||||
#define S_KEYFRAMES_INTERVAL_FRAMES "KeyFrames.Interval.Frames"
|
|
||||||
|
|
||||||
namespace encoder::ffmpeg {
|
namespace encoder::ffmpeg {
|
||||||
class ffmpeg_factory;
|
class ffmpeg_factory;
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,9 @@ extern "C" {
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ST_PRESET "Encoder.NVENC.Preset"
|
#define ST_PRESET "FFmpegEncoder.NVENC.Preset"
|
||||||
#define ST_PRESET_(x) ST_PRESET "." D_VSTR(x)
|
#define ST_PRESET_(x) ST_PRESET "." D_VSTR(x)
|
||||||
#define ST_RATECONTROL "Encoder.NVENC.RateControl"
|
#define ST_RATECONTROL "FFmpegEncoder.NVENC.RateControl"
|
||||||
#define ST_RATECONTROL_MODE ST_RATECONTROL ".Mode"
|
#define ST_RATECONTROL_MODE ST_RATECONTROL ".Mode"
|
||||||
#define ST_RATECONTROL_MODE_(x) ST_RATECONTROL_MODE "." D_VSTR(x)
|
#define ST_RATECONTROL_MODE_(x) ST_RATECONTROL_MODE "." D_VSTR(x)
|
||||||
#define ST_RATECONTROL_TWOPASS ST_RATECONTROL ".TwoPass"
|
#define ST_RATECONTROL_TWOPASS ST_RATECONTROL ".TwoPass"
|
||||||
|
@ -48,6 +48,7 @@ extern "C" {
|
||||||
#define ST_RATECONTROL_BITRATE ST_RATECONTROL ".Bitrate"
|
#define ST_RATECONTROL_BITRATE ST_RATECONTROL ".Bitrate"
|
||||||
#define ST_RATECONTROL_BITRATE_TARGET ST_RATECONTROL_BITRATE ".Target"
|
#define ST_RATECONTROL_BITRATE_TARGET ST_RATECONTROL_BITRATE ".Target"
|
||||||
#define ST_RATECONTROL_BITRATE_MAXIMUM ST_RATECONTROL_BITRATE ".Maximum"
|
#define ST_RATECONTROL_BITRATE_MAXIMUM ST_RATECONTROL_BITRATE ".Maximum"
|
||||||
|
#define ST_RATECONTROL_BUFFERSIZE ST_RATECONTROL ".BufferSize"
|
||||||
#define ST_RATECONTROL_QUALITY ST_RATECONTROL ".Quality"
|
#define ST_RATECONTROL_QUALITY ST_RATECONTROL ".Quality"
|
||||||
#define ST_RATECONTROL_QUALITY_MINIMUM ST_RATECONTROL_QUALITY ".Minimum"
|
#define ST_RATECONTROL_QUALITY_MINIMUM ST_RATECONTROL_QUALITY ".Minimum"
|
||||||
#define ST_RATECONTROL_QUALITY_MAXIMUM ST_RATECONTROL_QUALITY ".Maximum"
|
#define ST_RATECONTROL_QUALITY_MAXIMUM ST_RATECONTROL_QUALITY ".Maximum"
|
||||||
|
@ -56,11 +57,11 @@ extern "C" {
|
||||||
#define ST_RATECONTROL_QP_I ST_RATECONTROL_QP ".I"
|
#define ST_RATECONTROL_QP_I ST_RATECONTROL_QP ".I"
|
||||||
#define ST_RATECONTROL_QP_P ST_RATECONTROL_QP ".P"
|
#define ST_RATECONTROL_QP_P ST_RATECONTROL_QP ".P"
|
||||||
#define ST_RATECONTROL_QP_B ST_RATECONTROL_QP ".B"
|
#define ST_RATECONTROL_QP_B ST_RATECONTROL_QP ".B"
|
||||||
#define ST_AQ "Encoder.NVENC.AQ"
|
#define ST_AQ "FFmpegEncoder.NVENC.AQ"
|
||||||
#define ST_AQ_SPATIAL ST_AQ ".Spatial"
|
#define ST_AQ_SPATIAL ST_AQ ".Spatial"
|
||||||
#define ST_AQ_TEMPORAL ST_AQ ".Temporal"
|
#define ST_AQ_TEMPORAL ST_AQ ".Temporal"
|
||||||
#define ST_AQ_STRENGTH ST_AQ ".Strength"
|
#define ST_AQ_STRENGTH ST_AQ ".Strength"
|
||||||
#define ST_OTHER "Encoder.NVENC.Other"
|
#define ST_OTHER "FFmpegEncoder.NVENC.Other"
|
||||||
#define ST_OTHER_BFRAMES ST_OTHER ".BFrames"
|
#define ST_OTHER_BFRAMES ST_OTHER ".BFrames"
|
||||||
#define ST_OTHER_BFRAMEREFERENCEMODE ST_OTHER ".BFrameReferenceMode"
|
#define ST_OTHER_BFRAMEREFERENCEMODE ST_OTHER ".BFrameReferenceMode"
|
||||||
#define ST_OTHER_ZEROLATENCY ST_OTHER ".ZeroLatency"
|
#define ST_OTHER_ZEROLATENCY ST_OTHER ".ZeroLatency"
|
||||||
|
@ -75,6 +76,7 @@ extern "C" {
|
||||||
#define KEY_RATECONTROL_ADAPTIVEB "RateControl.AdaptiveB"
|
#define KEY_RATECONTROL_ADAPTIVEB "RateControl.AdaptiveB"
|
||||||
#define KEY_RATECONTROL_BITRATE_TARGET "RateControl.Bitrate.Target"
|
#define KEY_RATECONTROL_BITRATE_TARGET "RateControl.Bitrate.Target"
|
||||||
#define KEY_RATECONTROL_BITRATE_MAXIMUM "RateControl.Bitrate.Maximum"
|
#define KEY_RATECONTROL_BITRATE_MAXIMUM "RateControl.Bitrate.Maximum"
|
||||||
|
#define KEY_RATECONTROL_BUFFERSIZE "RateControl.BufferSize"
|
||||||
#define KEY_RATECONTROL_QUALITY "RateControl.Quality"
|
#define KEY_RATECONTROL_QUALITY "RateControl.Quality"
|
||||||
#define KEY_RATECONTROL_QUALITY_TARGET "RateControl.Quality.Target"
|
#define KEY_RATECONTROL_QUALITY_TARGET "RateControl.Quality.Target"
|
||||||
#define KEY_RATECONTROL_QUALITY_MINIMUM "RateControl.Quality.Minimum"
|
#define KEY_RATECONTROL_QUALITY_MINIMUM "RateControl.Quality.Minimum"
|
||||||
|
@ -193,7 +195,7 @@ void nvenc::get_defaults(obs_data_t* settings, const AVCodec*, AVCodecContext*)
|
||||||
|
|
||||||
obs_data_set_default_int(settings, KEY_RATECONTROL_BITRATE_TARGET, 6000);
|
obs_data_set_default_int(settings, KEY_RATECONTROL_BITRATE_TARGET, 6000);
|
||||||
obs_data_set_default_int(settings, KEY_RATECONTROL_BITRATE_MAXIMUM, 6000);
|
obs_data_set_default_int(settings, KEY_RATECONTROL_BITRATE_MAXIMUM, 6000);
|
||||||
obs_data_set_default_int(settings, S_RATECONTROL_BUFFERSIZE, 12000);
|
obs_data_set_default_int(settings, KEY_RATECONTROL_BUFFERSIZE, 12000);
|
||||||
|
|
||||||
obs_data_set_default_bool(settings, KEY_RATECONTROL_QUALITY, false);
|
obs_data_set_default_bool(settings, KEY_RATECONTROL_QUALITY, false);
|
||||||
obs_data_set_default_int(settings, KEY_RATECONTROL_QUALITY_MINIMUM, 51);
|
obs_data_set_default_int(settings, KEY_RATECONTROL_QUALITY_MINIMUM, 51);
|
||||||
|
@ -248,7 +250,7 @@ static bool modified_ratecontrol(obs_properties_t* props, obs_property_t*, obs_d
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_RATECONTROL_BITRATE), have_bitrate || have_bitrate_max);
|
obs_property_set_visible(obs_properties_get(props, ST_RATECONTROL_BITRATE), have_bitrate || have_bitrate_max);
|
||||||
obs_property_set_visible(obs_properties_get(props, KEY_RATECONTROL_BITRATE_TARGET), have_bitrate);
|
obs_property_set_visible(obs_properties_get(props, KEY_RATECONTROL_BITRATE_TARGET), have_bitrate);
|
||||||
obs_property_set_visible(obs_properties_get(props, KEY_RATECONTROL_BITRATE_MAXIMUM), have_bitrate_max);
|
obs_property_set_visible(obs_properties_get(props, KEY_RATECONTROL_BITRATE_MAXIMUM), have_bitrate_max);
|
||||||
obs_property_set_visible(obs_properties_get(props, S_RATECONTROL_BUFFERSIZE), have_bitrate || have_bitrate_max);
|
obs_property_set_visible(obs_properties_get(props, KEY_RATECONTROL_BUFFERSIZE), have_bitrate || have_bitrate_max);
|
||||||
|
|
||||||
obs_property_set_visible(obs_properties_get(props, KEY_RATECONTROL_QUALITY), have_quality);
|
obs_property_set_visible(obs_properties_get(props, KEY_RATECONTROL_QUALITY), have_quality);
|
||||||
obs_property_set_visible(obs_properties_get(props, KEY_RATECONTROL_QUALITY_MINIMUM), have_quality);
|
obs_property_set_visible(obs_properties_get(props, KEY_RATECONTROL_QUALITY_MINIMUM), have_quality);
|
||||||
|
@ -344,7 +346,7 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
|
||||||
{
|
{
|
||||||
auto p =
|
auto p =
|
||||||
obs_properties_add_int(grp, ST_RATECONTROL_BITRATE_TARGET, D_TRANSLATE(ST_RATECONTROL_BITRATE_TARGET),
|
obs_properties_add_int(grp, ST_RATECONTROL_BITRATE_TARGET, D_TRANSLATE(ST_RATECONTROL_BITRATE_TARGET),
|
||||||
1, std::numeric_limits<int32_t>::max(), 1);
|
0, std::numeric_limits<int32_t>::max(), 1);
|
||||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_BITRATE_TARGET)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_BITRATE_TARGET)));
|
||||||
obs_property_int_set_suffix(p, " kbit/s");
|
obs_property_int_set_suffix(p, " kbit/s");
|
||||||
}
|
}
|
||||||
|
@ -356,9 +358,9 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
|
||||||
obs_property_int_set_suffix(p, " kbit/s");
|
obs_property_int_set_suffix(p, " kbit/s");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto p = obs_properties_add_int(grp, S_RATECONTROL_BUFFERSIZE, D_TRANSLATE(S_RATECONTROL_BUFFERSIZE), 0,
|
auto p = obs_properties_add_int(grp, KEY_RATECONTROL_BUFFERSIZE, D_TRANSLATE(ST_RATECONTROL_BUFFERSIZE), 0,
|
||||||
std::numeric_limits<int32_t>::max(), 1);
|
std::numeric_limits<int32_t>::max(), 1);
|
||||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(S_RATECONTROL_BUFFERSIZE)));
|
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_BUFFERSIZE)));
|
||||||
obs_property_int_set_suffix(p, " kbit");
|
obs_property_int_set_suffix(p, " kbit");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -495,7 +497,7 @@ void nvenc::get_runtime_properties(obs_properties_t* props, const AVCodec*, AVCo
|
||||||
obs_property_set_enabled(obs_properties_get(props, ST_RATECONTROL_BITRATE), true);
|
obs_property_set_enabled(obs_properties_get(props, ST_RATECONTROL_BITRATE), true);
|
||||||
obs_property_set_enabled(obs_properties_get(props, KEY_RATECONTROL_BITRATE_TARGET), true);
|
obs_property_set_enabled(obs_properties_get(props, KEY_RATECONTROL_BITRATE_TARGET), true);
|
||||||
obs_property_set_enabled(obs_properties_get(props, KEY_RATECONTROL_BITRATE_MAXIMUM), true);
|
obs_property_set_enabled(obs_properties_get(props, KEY_RATECONTROL_BITRATE_MAXIMUM), true);
|
||||||
obs_property_set_enabled(obs_properties_get(props, S_RATECONTROL_BUFFERSIZE), true);
|
obs_property_set_enabled(obs_properties_get(props, KEY_RATECONTROL_BUFFERSIZE), true);
|
||||||
obs_property_set_enabled(obs_properties_get(props, ST_RATECONTROL_QUALITY), false);
|
obs_property_set_enabled(obs_properties_get(props, ST_RATECONTROL_QUALITY), false);
|
||||||
obs_property_set_enabled(obs_properties_get(props, KEY_RATECONTROL_QUALITY_MINIMUM), false);
|
obs_property_set_enabled(obs_properties_get(props, KEY_RATECONTROL_QUALITY_MINIMUM), false);
|
||||||
obs_property_set_enabled(obs_properties_get(props, KEY_RATECONTROL_QUALITY_MAXIMUM), false);
|
obs_property_set_enabled(obs_properties_get(props, KEY_RATECONTROL_QUALITY_MAXIMUM), false);
|
||||||
|
@ -591,7 +593,7 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
|
||||||
if (have_bitrate_max)
|
if (have_bitrate_max)
|
||||||
context->rc_max_rate = static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_BITRATE_MAXIMUM) * 1000);
|
context->rc_max_rate = static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_BITRATE_MAXIMUM) * 1000);
|
||||||
if (have_bitrate || have_bitrate_max)
|
if (have_bitrate || have_bitrate_max)
|
||||||
context->rc_buffer_size = static_cast<int>(obs_data_get_int(settings, S_RATECONTROL_BUFFERSIZE) * 1000);
|
context->rc_buffer_size = static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_BUFFERSIZE) * 1000);
|
||||||
|
|
||||||
if (have_quality && obs_data_get_bool(settings, KEY_RATECONTROL_QUALITY)) {
|
if (have_quality && obs_data_get_bool(settings, KEY_RATECONTROL_QUALITY)) {
|
||||||
int qmin = static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_QUALITY_MINIMUM));
|
int qmin = static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_QUALITY_MINIMUM));
|
||||||
|
@ -694,11 +696,12 @@ void nvenc::log_options(obs_data_t*, const AVCodec* codec, AVCodecContext* conte
|
||||||
|
|
||||||
LOG_INFO("[%s] Bitrate:", codec->name);
|
LOG_INFO("[%s] Bitrate:", codec->name);
|
||||||
tools::print_av_option_int(context, "bitrate", " Target", "bits/sec");
|
tools::print_av_option_int(context, "bitrate", " Target", "bits/sec");
|
||||||
|
tools::print_av_option_int(context, "rc_min_rate", " Minimum", "bits/sec");
|
||||||
tools::print_av_option_int(context, "rc_max_rate", " Maximum", "bits/sec");
|
tools::print_av_option_int(context, "rc_max_rate", " Maximum", "bits/sec");
|
||||||
tools::print_av_option_int(context, "rc_buffer_size", " Buffer", "bits");
|
tools::print_av_option_int(context, "rc_buffer_size", " Buffer", "bits");
|
||||||
LOG_INFO("[%s] Quality:", codec->name);
|
LOG_INFO("[%s] Quality:", codec->name);
|
||||||
tools::print_av_option_int(context, "qmin", " Minimum", "");
|
|
||||||
tools::print_av_option_int(context, "cq", " Target", "");
|
tools::print_av_option_int(context, "cq", " Target", "");
|
||||||
|
tools::print_av_option_int(context, "qmin", " Minimum", "");
|
||||||
tools::print_av_option_int(context, "qmax", " Maximum", "");
|
tools::print_av_option_int(context, "qmax", " Maximum", "");
|
||||||
LOG_INFO("[%s] Quantization Parameters:", codec->name);
|
LOG_INFO("[%s] Quantization Parameters:", codec->name);
|
||||||
tools::print_av_option_int(context, "init_qpI", " I-Frame", "");
|
tools::print_av_option_int(context, "init_qpI", " I-Frame", "");
|
||||||
|
|
|
@ -37,8 +37,7 @@ extern "C" {
|
||||||
- CBR: Constant Bitrate (rc=cbr)
|
- CBR: Constant Bitrate (rc=cbr)
|
||||||
- VBR: Variable Bitrate (rc=vbr)
|
- VBR: Variable Bitrate (rc=vbr)
|
||||||
- CQP: Constant QP (rc=cqp)
|
- CQP: Constant QP (rc=cqp)
|
||||||
- VQP: Variable QP (rc=vbr b=0 minrate=0 maxrate=0 qmin=minqp qmax=maxqp cq=targetqp)
|
- CQ: Constant Quality (rc=vbr b=0 minrate=0 maxrate=0 qmin=0 qmax=51 cq=qp), this is basically CRF in X264.
|
||||||
- TQ: Target Quality (rc=vbr b=0 minrate=0 maxrate=0 qmin=qp qmax=qp cq=qp)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using namespace encoder::ffmpeg;
|
using namespace encoder::ffmpeg;
|
||||||
|
|
Loading…
Reference in a new issue