mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-12-28 18:41:14 +00:00
ffmpeg-encoder/nvenc: Add minimum bitrate, fix target quality and more
Adds support for specifying Minimum Bitrate directly in the UI instead of requiring custom settings to do so. Additionally Adaptive I/B-Frames are now only shown if Look-Ahead is a value greater than 0 frames. Quality Minimum can also now be left at a default value of -1, the Quality group is no longer toggleable and Quality Target moved into the group. Settings options on the context is now searching children too (if there are any). Finally, some C++17 formatting was done. Fixes #101
This commit is contained in:
parent
5d5a104819
commit
34b2859dac
2 changed files with 111 additions and 94 deletions
|
@ -352,11 +352,13 @@ 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, frame rate and bitrate for the video."
|
||||
Codec.HEVC.Level.Description="Level determines the upper limits of resolution and frame rate."
|
||||
|
||||
# Codec: Apple ProRes
|
||||
Codec.ProRes.Profile="Profile"
|
||||
|
@ -422,42 +424,38 @@ 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.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.BufferSize="Buffer Size"
|
||||
FFmpegEncoder.NVENC.RateControl.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.Bitrate="Bitrate Limits"
|
||||
FFmpegEncoder.NVENC.RateControl.Bitrate.Target="Target Bitrate"
|
||||
FFmpegEncoder.NVENC.RateControl.Bitrate.Maximum="Minimum Bitrate"
|
||||
FFmpegEncoder.NVENC.RateControl.Bitrate.Maximum="Maximum Bitrate"
|
||||
FFmpegEncoder.NVENC.RateControl.BufferSize="Buffer Size"
|
||||
FFmpegEncoder.NVENC.RateControl.Quality="Enable Quality Limits"
|
||||
FFmpegEncoder.NVENC.RateControl.Quality="Quality Limits"
|
||||
FFmpegEncoder.NVENC.RateControl.Quality.Target="Target Quality"
|
||||
FFmpegEncoder.NVENC.RateControl.Quality.Target.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.Quality.Minimum="Minimum Quality"
|
||||
FFmpegEncoder.NVENC.RateControl.Quality.Minimum.Description="Minimum quality to achieve, with values closer to 0 being better quality."
|
||||
FFmpegEncoder.NVENC.RateControl.Quality.Minimum.Description="Minimum 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"
|
||||
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."
|
||||
FFmpegEncoder.NVENC.RateControl.Quality.Target="Target Quality"
|
||||
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."
|
||||
FFmpegEncoder.NVENC.RateControl.QP="Quantization Parameters"
|
||||
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.I.Initial="Initial I-Frame QP"
|
||||
FFmpegEncoder.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.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.P.Initial="Initial P-Frame QP"
|
||||
FFmpegEncoder.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.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.RateControl.QP.B.Initial="Initial B-Frame QP"
|
||||
FFmpegEncoder.NVENC.RateControl.QP.B.Initial.Description="Initial B-Frame quantization parameter.\nSet to -1 to use the automatically detected value instead."
|
||||
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 AQ Strength"
|
||||
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."
|
||||
|
|
|
@ -47,6 +47,7 @@ extern "C" {
|
|||
#define ST_RATECONTROL_ADAPTIVEB ST_RATECONTROL ".AdaptiveB"
|
||||
#define ST_RATECONTROL_BITRATE ST_RATECONTROL ".Bitrate"
|
||||
#define ST_RATECONTROL_BITRATE_TARGET ST_RATECONTROL_BITRATE ".Target"
|
||||
#define ST_RATECONTROL_BITRATE_MINIMUM ST_RATECONTROL_BITRATE ".Minimum"
|
||||
#define ST_RATECONTROL_BITRATE_MAXIMUM ST_RATECONTROL_BITRATE ".Maximum"
|
||||
#define ST_RATECONTROL_BUFFERSIZE ST_RATECONTROL ".BufferSize"
|
||||
#define ST_RATECONTROL_QUALITY ST_RATECONTROL ".Quality"
|
||||
|
@ -75,6 +76,7 @@ extern "C" {
|
|||
#define KEY_RATECONTROL_ADAPTIVEI "RateControl.AdaptiveI"
|
||||
#define KEY_RATECONTROL_ADAPTIVEB "RateControl.AdaptiveB"
|
||||
#define KEY_RATECONTROL_BITRATE_TARGET "RateControl.Bitrate.Target"
|
||||
#define KEY_RATECONTROL_BITRATE_MINIMUM "RateControl.Bitrate.Minimum"
|
||||
#define KEY_RATECONTROL_BITRATE_MAXIMUM "RateControl.Bitrate.Maximum"
|
||||
#define KEY_RATECONTROL_BUFFERSIZE "RateControl.BufferSize"
|
||||
#define KEY_RATECONTROL_QUALITY "RateControl.Quality"
|
||||
|
@ -194,13 +196,13 @@ void nvenc::get_defaults(obs_data_t* settings, const AVCodec*, AVCodecContext*)
|
|||
obs_data_set_default_int(settings, KEY_RATECONTROL_ADAPTIVEB, -1);
|
||||
|
||||
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_MINIMUM, 0);
|
||||
obs_data_set_default_int(settings, KEY_RATECONTROL_BITRATE_MAXIMUM, 0);
|
||||
obs_data_set_default_int(settings, KEY_RATECONTROL_BUFFERSIZE, 12000);
|
||||
|
||||
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_double(settings, KEY_RATECONTROL_QUALITY_TARGET, 0);
|
||||
obs_data_set_default_int(settings, KEY_RATECONTROL_QUALITY_MINIMUM, -1);
|
||||
obs_data_set_default_int(settings, KEY_RATECONTROL_QUALITY_MAXIMUM, -1);
|
||||
obs_data_set_default_int(settings, KEY_RATECONTROL_QUALITY_TARGET, 0);
|
||||
|
||||
obs_data_set_default_int(settings, KEY_RATECONTROL_QP_I, 21);
|
||||
obs_data_set_default_int(settings, KEY_RATECONTROL_QP_P, 21);
|
||||
|
@ -249,6 +251,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, KEY_RATECONTROL_BITRATE_TARGET), have_bitrate);
|
||||
obs_property_set_visible(obs_properties_get(props, KEY_RATECONTROL_BITRATE_MINIMUM), 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, KEY_RATECONTROL_BUFFERSIZE), have_bitrate || have_bitrate_max);
|
||||
|
||||
|
@ -265,6 +268,14 @@ static bool modified_ratecontrol(obs_properties_t* props, obs_property_t*, obs_d
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool modified_lookahead(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
||||
{
|
||||
int64_t v = obs_data_get_int(settings, KEY_RATECONTROL_LOOKAHEAD);
|
||||
obs_property_set_visible(obs_properties_get(props, KEY_RATECONTROL_ADAPTIVEI), v > 0);
|
||||
obs_property_set_visible(obs_properties_get(props, KEY_RATECONTROL_ADAPTIVEB), v > 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool modified_quality(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
||||
{
|
||||
bool enabled = obs_data_get_bool(settings, ST_RATECONTROL_QUALITY);
|
||||
|
@ -322,17 +333,27 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
|
|||
0, 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);
|
||||
}
|
||||
|
||||
{
|
||||
auto p =
|
||||
util::obs_properties_add_tristate(grp, ST_RATECONTROL_ADAPTIVEI, D_TRANSLATE(ST_RATECONTROL_ADAPTIVEI));
|
||||
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, ST_RATECONTROL_ADAPTIVEB, D_TRANSLATE(ST_RATECONTROL_ADAPTIVEB));
|
||||
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)));
|
||||
}
|
||||
|
||||
{
|
||||
auto p = obs_properties_add_int(grp, KEY_RATECONTROL_BUFFERSIZE, D_TRANSLATE(ST_RATECONTROL_BUFFERSIZE), 0,
|
||||
std::numeric_limits<int32_t>::max(), 1);
|
||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_BUFFERSIZE)));
|
||||
obs_property_int_set_suffix(p, " kbit");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -345,23 +366,21 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
|
|||
|
||||
{
|
||||
auto p =
|
||||
obs_properties_add_int(grp, ST_RATECONTROL_BITRATE_TARGET, D_TRANSLATE(ST_RATECONTROL_BITRATE_TARGET),
|
||||
obs_properties_add_int(grp, KEY_RATECONTROL_BITRATE_TARGET, D_TRANSLATE(ST_RATECONTROL_BITRATE_TARGET),
|
||||
0, std::numeric_limits<int32_t>::max(), 1);
|
||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_BITRATE_TARGET)));
|
||||
obs_property_int_set_suffix(p, " kbit/s");
|
||||
}
|
||||
{
|
||||
auto p =
|
||||
obs_properties_add_int(grp, ST_RATECONTROL_BITRATE_MAXIMUM, D_TRANSLATE(ST_RATECONTROL_BITRATE_MAXIMUM),
|
||||
0, std::numeric_limits<int32_t>::max(), 1);
|
||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_BITRATE_MAXIMUM)));
|
||||
obs_property_int_set_suffix(p, " kbit/s");
|
||||
}
|
||||
{
|
||||
auto p = obs_properties_add_int(grp, KEY_RATECONTROL_BUFFERSIZE, D_TRANSLATE(ST_RATECONTROL_BUFFERSIZE), 0,
|
||||
auto p = obs_properties_add_int(grp, KEY_RATECONTROL_BITRATE_MINIMUM,
|
||||
D_TRANSLATE(ST_RATECONTROL_BITRATE_MINIMUM), 0,
|
||||
std::numeric_limits<int32_t>::max(), 1);
|
||||
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/s");
|
||||
}
|
||||
{
|
||||
auto p = obs_properties_add_int(grp, KEY_RATECONTROL_BITRATE_MAXIMUM,
|
||||
D_TRANSLATE(ST_RATECONTROL_BITRATE_MAXIMUM), 0,
|
||||
std::numeric_limits<int32_t>::max(), 1);
|
||||
obs_property_int_set_suffix(p, " kbit/s");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,16 +389,19 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
|
|||
if (!util::are_property_groups_broken()) {
|
||||
grp = obs_properties_create();
|
||||
auto p = obs_properties_add_group(props, ST_RATECONTROL_QUALITY, D_TRANSLATE(ST_RATECONTROL_QUALITY),
|
||||
OBS_GROUP_CHECKABLE, grp);
|
||||
obs_property_set_modified_callback(p, modified_quality);
|
||||
} else {
|
||||
auto p = obs_properties_add_bool(props, ST_RATECONTROL_QUALITY, D_TRANSLATE(ST_RATECONTROL_QUALITY));
|
||||
OBS_GROUP_NORMAL, grp);
|
||||
obs_property_set_modified_callback(p, modified_quality);
|
||||
}
|
||||
|
||||
{
|
||||
auto p = obs_properties_add_float_slider(grp, KEY_RATECONTROL_QUALITY_TARGET,
|
||||
D_TRANSLATE(ST_RATECONTROL_QUALITY_TARGET), 0, 100, 0.01);
|
||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_QUALITY_TARGET)));
|
||||
}
|
||||
|
||||
{
|
||||
auto p = obs_properties_add_int_slider(grp, KEY_RATECONTROL_QUALITY_MINIMUM,
|
||||
D_TRANSLATE(ST_RATECONTROL_QUALITY_MINIMUM), 0, 51, 1);
|
||||
D_TRANSLATE(ST_RATECONTROL_QUALITY_MINIMUM), -1, 51, 1);
|
||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_QUALITY_MINIMUM)));
|
||||
}
|
||||
{
|
||||
|
@ -389,12 +411,6 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto p = obs_properties_add_float_slider(props, KEY_RATECONTROL_QUALITY_TARGET,
|
||||
D_TRANSLATE(ST_RATECONTROL_QUALITY_TARGET), 0, 100, 0.01);
|
||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_RATECONTROL_QUALITY_TARGET)));
|
||||
}
|
||||
|
||||
{
|
||||
obs_properties_t* grp = props;
|
||||
if (!util::are_property_groups_broken()) {
|
||||
|
@ -460,7 +476,6 @@ void nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
|
|||
auto p =
|
||||
obs_properties_add_list(grp, KEY_OTHER_BFRAMEREFERENCEMODE, D_TRANSLATE(ST_OTHER_BFRAMEREFERENCEMODE),
|
||||
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
||||
obs_property_set_long_description(p, D_TRANSLATE(D_DESC(ST_OTHER_BFRAMEREFERENCEMODE)));
|
||||
for (auto kv : b_ref_modes) {
|
||||
obs_property_list_add_int(p, D_TRANSLATE(kv.second.c_str()), static_cast<int64_t>(kv.first));
|
||||
}
|
||||
|
@ -494,10 +509,10 @@ void nvenc::get_runtime_properties(obs_properties_t* props, const AVCodec*, AVCo
|
|||
obs_property_set_enabled(obs_properties_get(props, KEY_RATECONTROL_LOOKAHEAD), false);
|
||||
obs_property_set_enabled(obs_properties_get(props, KEY_RATECONTROL_ADAPTIVEI), false);
|
||||
obs_property_set_enabled(obs_properties_get(props, KEY_RATECONTROL_ADAPTIVEB), false);
|
||||
obs_property_set_enabled(obs_properties_get(props, KEY_RATECONTROL_BUFFERSIZE), 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_MAXIMUM), 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, KEY_RATECONTROL_QUALITY_MINIMUM), false);
|
||||
obs_property_set_enabled(obs_properties_get(props, KEY_RATECONTROL_QUALITY_MAXIMUM), false);
|
||||
|
@ -540,10 +555,10 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
|
|||
ratecontrolmode rc = static_cast<ratecontrolmode>(obs_data_get_int(settings, KEY_RATECONTROL_MODE));
|
||||
auto rcopt = ratecontrolmode_to_opt.find(rc);
|
||||
if (rcopt != ratecontrolmode_to_opt.end()) {
|
||||
av_opt_set(context->priv_data, "rc", rcopt->second.c_str(), 0);
|
||||
av_opt_set(context->priv_data, "rc", rcopt->second.c_str(), AV_OPT_SEARCH_CHILDREN);
|
||||
}
|
||||
|
||||
av_opt_set_int(context->priv_data, "cbr", 0, 0);
|
||||
av_opt_set_int(context->priv_data, "cbr", 0, AV_OPT_SEARCH_CHILDREN);
|
||||
switch (rc) {
|
||||
case ratecontrolmode::CQP:
|
||||
have_qp = true;
|
||||
|
@ -553,7 +568,7 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
|
|||
case ratecontrolmode::CBR_HQ:
|
||||
case ratecontrolmode::CBR_LD_HQ:
|
||||
have_bitrate = true;
|
||||
av_opt_set_int(context->priv_data, "cbr", 1, 0);
|
||||
av_opt_set_int(context->priv_data, "cbr", 1, AV_OPT_SEARCH_CHILDREN);
|
||||
break;
|
||||
case ratecontrolmode::VBR:
|
||||
case ratecontrolmode::VBR_HQ:
|
||||
|
@ -564,59 +579,65 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
|
|||
break;
|
||||
}
|
||||
|
||||
int tp = static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_TWOPASS));
|
||||
if (tp >= 0) {
|
||||
av_opt_set_int(context->priv_data, "2pass", tp ? 1 : 0, 0);
|
||||
if (int tp = static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_TWOPASS)); tp >= 0) {
|
||||
av_opt_set_int(context->priv_data, "2pass", tp ? 1 : 0, AV_OPT_SEARCH_CHILDREN);
|
||||
}
|
||||
|
||||
int la = static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_LOOKAHEAD));
|
||||
av_opt_set_int(context->priv_data, "rc-lookahead", la, 0);
|
||||
av_opt_set_int(context->priv_data, "rc-lookahead", la, AV_OPT_SEARCH_CHILDREN);
|
||||
if (la > 0) {
|
||||
int64_t adapt_i = obs_data_get_int(settings, KEY_RATECONTROL_ADAPTIVEI);
|
||||
if (!util::is_tristate_default(adapt_i)) {
|
||||
if (int64_t adapt_i = obs_data_get_int(settings, KEY_RATECONTROL_ADAPTIVEI);
|
||||
!util::is_tristate_default(adapt_i)) {
|
||||
av_opt_set_int(context->priv_data, "no-scenecut", adapt_i, AV_OPT_SEARCH_CHILDREN);
|
||||
}
|
||||
|
||||
if (strcmp(codec->name, "h264_nvenc")) {
|
||||
int64_t adapt_b = obs_data_get_int(settings, KEY_RATECONTROL_ADAPTIVEB);
|
||||
if (!util::is_tristate_default(adapt_b)) {
|
||||
if (int64_t adapt_b = obs_data_get_int(settings, KEY_RATECONTROL_ADAPTIVEB);
|
||||
!util::is_tristate_default(adapt_b)) {
|
||||
av_opt_set_int(context->priv_data, "b_adapt", adapt_b, AV_OPT_SEARCH_CHILDREN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (have_bitrate) {
|
||||
context->bit_rate = static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_BITRATE_TARGET) * 1000);
|
||||
// Support for Replay Buffer
|
||||
obs_data_set_int(settings, "bitrate", obs_data_get_int(settings, KEY_RATECONTROL_BITRATE_TARGET));
|
||||
}
|
||||
if (have_bitrate_max)
|
||||
context->rc_max_rate = static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_BITRATE_MAXIMUM) * 1000);
|
||||
if (have_bitrate || have_bitrate_max)
|
||||
context->rc_buffer_size = static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_BUFFERSIZE) * 1000);
|
||||
int64_t v = obs_data_get_int(settings, KEY_RATECONTROL_BITRATE_TARGET);
|
||||
if (v >= 0)
|
||||
context->bit_rate = static_cast<int>(v * 1000);
|
||||
|
||||
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));
|
||||
context->qmin = qmin;
|
||||
if (qmin >= 0) {
|
||||
context->qmax = static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_QUALITY_MAXIMUM));
|
||||
}
|
||||
// Support for Replay Buffer
|
||||
obs_data_set_int(settings, "bitrate", v);
|
||||
}
|
||||
if (have_bitrate_max) {
|
||||
if (int64_t min = obs_data_get_int(settings, KEY_RATECONTROL_BITRATE_MINIMUM); min >= 0)
|
||||
context->rc_min_rate = static_cast<int>(min * 1000);
|
||||
if (int64_t max = obs_data_get_int(settings, KEY_RATECONTROL_BITRATE_MAXIMUM); max >= 0)
|
||||
context->rc_max_rate = static_cast<int>(max * 1000);
|
||||
}
|
||||
if (have_bitrate || have_bitrate_max) {
|
||||
if (int64_t v = obs_data_get_int(settings, KEY_RATECONTROL_BUFFERSIZE); v >= 0)
|
||||
context->rc_buffer_size = static_cast<int>(v * 1000);
|
||||
}
|
||||
|
||||
if (have_quality) {
|
||||
if (int qmin = static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_QUALITY_MINIMUM)); qmin >= 0)
|
||||
context->qmin = qmin;
|
||||
if (int qmax = static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_QUALITY_MAXIMUM)); qmax >= 0)
|
||||
context->qmax = qmax;
|
||||
}
|
||||
|
||||
{
|
||||
double_t v = obs_data_get_double(settings, KEY_RATECONTROL_QUALITY_TARGET) / 100.0 * 51.0;
|
||||
if (v > 0) {
|
||||
av_opt_set_double(context->priv_data, "cq", v, 0);
|
||||
if (double_t v = obs_data_get_double(settings, KEY_RATECONTROL_QUALITY_TARGET) / 100.0 * 51.0; > 0) {
|
||||
av_opt_set_double(context->priv_data, "cq", v, AV_OPT_SEARCH_CHILDREN);
|
||||
}
|
||||
}
|
||||
|
||||
if (have_qp) {
|
||||
av_opt_set_int(context->priv_data, "init_qpI",
|
||||
static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_QP_I)), 0);
|
||||
static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_QP_I)), AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_int(context->priv_data, "init_qpP",
|
||||
static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_QP_P)), 0);
|
||||
static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_QP_P)), AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_int(context->priv_data, "init_qpB",
|
||||
static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_QP_B)), 0);
|
||||
static_cast<int>(obs_data_get_int(settings, KEY_RATECONTROL_QP_B)), AV_OPT_SEARCH_CHILDREN);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -626,44 +647,42 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
|
|||
|
||||
if (strcmp(codec->name, "h264_nvenc") == 0) {
|
||||
if (!util::is_tristate_default(saq))
|
||||
av_opt_set_int(context->priv_data, "spatial-aq", saq, 0);
|
||||
av_opt_set_int(context->priv_data, "spatial-aq", saq, AV_OPT_SEARCH_CHILDREN);
|
||||
if (!util::is_tristate_default(taq))
|
||||
av_opt_set_int(context->priv_data, "temporal-aq", taq, 0);
|
||||
av_opt_set_int(context->priv_data, "temporal-aq", taq, AV_OPT_SEARCH_CHILDREN);
|
||||
} else {
|
||||
if (!util::is_tristate_default(saq))
|
||||
av_opt_set_int(context->priv_data, "spatial_aq", saq, 0);
|
||||
av_opt_set_int(context->priv_data, "spatial_aq", saq, AV_OPT_SEARCH_CHILDREN);
|
||||
if (!util::is_tristate_default(taq))
|
||||
av_opt_set_int(context->priv_data, "temporal_aq", taq, 0);
|
||||
av_opt_set_int(context->priv_data, "temporal_aq", taq, AV_OPT_SEARCH_CHILDREN);
|
||||
}
|
||||
if (util::is_tristate_enabled(saq))
|
||||
av_opt_set_int(context->priv_data, "aq-strength",
|
||||
static_cast<int>(obs_data_get_int(settings, KEY_AQ_STRENGTH)), 0);
|
||||
static_cast<int>(obs_data_get_int(settings, KEY_AQ_STRENGTH)), AV_OPT_SEARCH_CHILDREN);
|
||||
}
|
||||
|
||||
{ // Other
|
||||
int64_t zl = obs_data_get_int(settings, KEY_OTHER_ZEROLATENCY);
|
||||
int64_t wp = obs_data_get_int(settings, KEY_OTHER_WEIGHTEDPREDICTION);
|
||||
int64_t nrp = obs_data_get_int(settings, KEY_OTHER_NONREFERENCEPFRAMES);
|
||||
int64_t wp = obs_data_get_int(settings, KEY_OTHER_WEIGHTEDPREDICTION);
|
||||
|
||||
context->max_b_frames = static_cast<int>(obs_data_get_int(settings, KEY_OTHER_BFRAMES));
|
||||
|
||||
if (!util::is_tristate_default(zl))
|
||||
av_opt_set_int(context->priv_data, "zerolatency", zl, 0);
|
||||
if (!util::is_tristate_default(nrp))
|
||||
av_opt_set_int(context->priv_data, "nonref_p", nrp, 0);
|
||||
if (int64_t zl = obs_data_get_int(settings, KEY_OTHER_ZEROLATENCY); !util::is_tristate_default(zl))
|
||||
av_opt_set_int(context->priv_data, "zerolatency", zl, AV_OPT_SEARCH_CHILDREN);
|
||||
if (int64_t nrp = obs_data_get_int(settings, KEY_OTHER_NONREFERENCEPFRAMES); !util::is_tristate_default(nrp))
|
||||
av_opt_set_int(context->priv_data, "nonref_p", nrp, AV_OPT_SEARCH_CHILDREN);
|
||||
|
||||
if ((context->max_b_frames != 0) && util::is_tristate_enabled(wp)) {
|
||||
LOG_WARNING("[%s] Weighted Prediction disabled because of B-Frames being used.", codec->name);
|
||||
av_opt_set_int(context->priv_data, "weighted_pred", 0, 0);
|
||||
av_opt_set_int(context->priv_data, "weighted_pred", 0, AV_OPT_SEARCH_CHILDREN);
|
||||
} else if (!util::is_tristate_default(wp)) {
|
||||
av_opt_set_int(context->priv_data, "weighted_pred", wp, 0);
|
||||
av_opt_set_int(context->priv_data, "weighted_pred", wp, AV_OPT_SEARCH_CHILDREN);
|
||||
}
|
||||
|
||||
{
|
||||
auto found = b_ref_mode_to_opt.find(
|
||||
static_cast<b_ref_mode>(obs_data_get_int(settings, KEY_OTHER_BFRAMEREFERENCEMODE)));
|
||||
if (found != b_ref_mode_to_opt.end()) {
|
||||
av_opt_set(context->priv_data, "b_ref_mode", found->second.c_str(), 0);
|
||||
av_opt_set(context->priv_data, "b_ref_mode", found->second.c_str(), AV_OPT_SEARCH_CHILDREN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue