ui/nvenc: Improve and fix some options and logging
Some of the options shown to the user were never actually being applied, which resulted in encoding that looked worse than it could have. With this these options are now applied and users may experience a sudden increase or decrease in quality if they had these options changed. In addition to that, some options now use a triple state field, which allows them to also have a default/middle state instead of being On or Off. Furthermore, log output is now read from the actual AVCodecContext, which contains the actual values used in the encoding, instead of relying on the OBS settings to be the actual values.
This commit is contained in:
@@ -117,11 +117,11 @@ NVENC.RateControl.Mode.CBR_LD_HQ="Low Delay High Quality Constant Bitrate"
|
|||||||
NVENC.RateControl.Mode.CBR_LD_HQ.Description="Constant Bitrate optimized for lowest encoding latency."
|
NVENC.RateControl.Mode.CBR_LD_HQ.Description="Constant Bitrate optimized for lowest encoding latency."
|
||||||
NVENC.RateControl.LookAhead="Look Ahead"
|
NVENC.RateControl.LookAhead="Look Ahead"
|
||||||
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."
|
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."
|
||||||
NVENC.RateControl.AdaptiveI="Enable adaptive I-Frame insertion"
|
NVENC.RateControl.AdaptiveI="Adaptive I-Frames"
|
||||||
NVENC.RateControl.AdaptiveI.Description="Enables adaptive I-Frame insertion.\nOnly has an effect when look ahead is set to a value other than 0."
|
NVENC.RateControl.AdaptiveI.Description="Enables adaptive I-Frame insertion.\nOnly has an effect when look ahead is set to a value other than 0."
|
||||||
NVENC.RateControl.AdaptiveB="Enable adaptive B-Frame insertion"
|
NVENC.RateControl.AdaptiveB="Adaptive B-Frames"
|
||||||
NVENC.RateControl.AdaptiveB.Description="Enables adaptive B-Frame insertion.\nOnly has an effect when look ahead is set to a value other than 0."
|
NVENC.RateControl.AdaptiveB.Description="Enables adaptive B-Frame insertion.\nOnly has an effect when look ahead is set to a value other than 0."
|
||||||
NVENC.RateControl.TwoPass="Enable Two Pass"
|
NVENC.RateControl.TwoPass="Two Pass"
|
||||||
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."
|
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."
|
||||||
NVENC.RateControl.Bitrate="Bitrate Limits"
|
NVENC.RateControl.Bitrate="Bitrate Limits"
|
||||||
NVENC.RateControl.Bitrate.Target="Target Bitrate"
|
NVENC.RateControl.Bitrate.Target="Target Bitrate"
|
||||||
@@ -147,11 +147,11 @@ NVENC.RateControl.QP.B.Description="Quantization parameter for B-Frames.\nSmalle
|
|||||||
NVENC.RateControl.QP.B.Initial="Initial B-Frame QP"
|
NVENC.RateControl.QP.B.Initial="Initial B-Frame QP"
|
||||||
NVENC.RateControl.QP.B.Initial.Description="Initial B-Frame quantization parameter.\nSet to -1 to use the automatically detected value instead."
|
NVENC.RateControl.QP.B.Initial.Description="Initial B-Frame quantization parameter.\nSet to -1 to use the automatically detected value instead."
|
||||||
NVENC.AQ="Adaptive Quantization"
|
NVENC.AQ="Adaptive Quantization"
|
||||||
NVENC.AQ.Spatial="Enable Spatial Adaptive Quantization"
|
NVENC.AQ.Spatial="Spatial Adaptive Quantization"
|
||||||
NVENC.AQ.Spatial.Description="Enable spatial adaptive quantization, also sometimes referred to as Psychovisual Adaptive Quantization."
|
NVENC.AQ.Spatial.Description="Enable spatial adaptive quantization, also sometimes referred to as Psychovisual Adaptive Quantization."
|
||||||
NVENC.AQ.Strength="Spatial AQ Strength"
|
NVENC.AQ.Strength="Spatial AQ Strength"
|
||||||
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."
|
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."
|
||||||
NVENC.AQ.Temporal="Enable Temporal Adaptive Quantization"
|
NVENC.AQ.Temporal="Temporal Adaptive Quantization"
|
||||||
NVENC.AQ.Temporal.Description="Enable temporal adaptive quantization."
|
NVENC.AQ.Temporal.Description="Enable temporal adaptive quantization."
|
||||||
NVENC.Other="Other Options"
|
NVENC.Other="Other Options"
|
||||||
NVENC.Other.BFrames="Maximum B-Frames"
|
NVENC.Other.BFrames="Maximum B-Frames"
|
||||||
@@ -159,9 +159,9 @@ NVENC.Other.BFrames.Description="Maximum number of B-Frames to insert into the e
|
|||||||
NVENC.Other.BFrameReferenceMode="B-Frame Reference Mode"
|
NVENC.Other.BFrameReferenceMode="B-Frame Reference Mode"
|
||||||
NVENC.Other.BFrameReferenceMode.Each="Each B-Frame will be used for references"
|
NVENC.Other.BFrameReferenceMode.Each="Each B-Frame will be used for references"
|
||||||
NVENC.Other.BFrameReferenceMode.Middle="Only (# of B-Frames)/2 will be used for references"
|
NVENC.Other.BFrameReferenceMode.Middle="Only (# of B-Frames)/2 will be used for references"
|
||||||
NVENC.Other.ZeroLatency="Enable Zero Latency"
|
NVENC.Other.ZeroLatency="Zero Latency"
|
||||||
NVENC.Other.ZeroLatency.Description="Enable zero latency operation, which ensures that there is no reordering delay."
|
NVENC.Other.ZeroLatency.Description="Enable zero latency operation, which ensures that there is no reordering delay."
|
||||||
NVENC.Other.WeightedPrediction="Enable Weighted Prediction"
|
NVENC.Other.WeightedPrediction="Weighted Prediction"
|
||||||
NVENC.Other.WeightedPrediction.Description="Enable weighted prediction for encoding.\nCan't be used with B-Frames."
|
NVENC.Other.WeightedPrediction.Description="Enable weighted prediction for encoding.\nCan't be used with B-Frames."
|
||||||
NVENC.Other.NonReferencePFrames="Enable non-reference P-Frames"
|
NVENC.Other.NonReferencePFrames="Non-reference P-Frames"
|
||||||
NVENC.Other.NonReferencePFrames.Description="Enable the automatic insertion of non-reference P-Frames."
|
NVENC.Other.NonReferencePFrames.Description="Enable the automatic insertion of non-reference P-Frames."
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "nvenc_h264_handler.hpp"
|
#include "nvenc_h264_handler.hpp"
|
||||||
#include "codecs/h264.hpp"
|
#include "codecs/h264.hpp"
|
||||||
#include "encoder.hpp"
|
#include "encoder.hpp"
|
||||||
|
#include "ffmpeg/tools.hpp"
|
||||||
#include "nvenc_shared.hpp"
|
#include "nvenc_shared.hpp"
|
||||||
#include "plugin.hpp"
|
#include "plugin.hpp"
|
||||||
#include "strings.hpp"
|
#include "strings.hpp"
|
||||||
@@ -35,30 +36,7 @@ extern "C" {
|
|||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Missing Options:
|
|
||||||
|
|
||||||
Seem to be covered by initQP_* instead.
|
|
||||||
- [obs-ffmpeg-encoder] Option 'cq' with help 'Set target quality level (0 to 51, 0 means automatic) for constant quality mode in VBR rate control' of type 'Float' with default value '0.000000', minimum '0.000000' and maximum '51.000000'.
|
|
||||||
- [obs-ffmpeg-encoder] Option 'qp' with help 'Constant quantization parameter rate control method' of type 'Int' with default value '-1', minimum '-1.000000' and maximum '51.000000'.
|
|
||||||
|
|
||||||
Not sure what there are useful for.
|
|
||||||
[obs-ffmpeg-encoder] Option 'aud' with help 'Use access unit delimiters' of type 'Bool' with default value 'false', minimum '0.000000' and maximum '1.000000'.
|
|
||||||
[obs-ffmpeg-encoder] Option 'surfaces' with help 'Number of concurrent surfaces' of type 'Int' with default value '0', minimum '0.000000' and maximum '64.000000'.
|
|
||||||
[obs-ffmpeg-encoder] Option 'delay' with help 'Delay frame output by the given amount of frames' of type 'Int' with default value '2147483647', minimum '0.000000' and maximum '2147483647.000000'.
|
|
||||||
|
|
||||||
Should probably add this.
|
|
||||||
[obs-ffmpeg-encoder] Option 'gpu' with unit (gpu) with help 'Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on.' of type 'Int' with default value '-1', minimum '-2.000000' and maximum '2147483647.000000'.
|
|
||||||
[obs-ffmpeg-encoder] [gpu] Constant 'any' and help text 'Pick the first device available' with value '-1'.
|
|
||||||
[obs-ffmpeg-encoder] [gpu] Constant 'list' and help text 'List the available devices' with value '-2'.
|
|
||||||
|
|
||||||
Useless except for strict_gop maybe?
|
|
||||||
[obs-ffmpeg-encoder] Option 'forced-idr' with help 'If forcing keyframes, force them as IDR frames.' of type 'Bool' with default value 'false', minimum '-1.000000' and maximum '1.000000'.
|
|
||||||
[obs-ffmpeg-encoder] Option 'strict_gop' with help 'Set 1 to minimize GOP-to-GOP rate fluctuations' of type 'Bool' with default value 'false', minimum '0.000000' and maximum '1.000000'.
|
|
||||||
[obs-ffmpeg-encoder] Option 'bluray-compat' with help 'Bluray compatibility workarounds' of type 'Bool' with default value 'false', minimum '0.000000' and maximum '1.000000'.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using namespace obsffmpeg::codecs::h264;
|
using namespace obsffmpeg::codecs::h264;
|
||||||
using namespace obsffmpeg::nvenc;
|
|
||||||
|
|
||||||
std::map<profile, std::string> profiles{
|
std::map<profile, std::string> profiles{
|
||||||
{profile::BASELINE, "baseline"},
|
{profile::BASELINE, "baseline"},
|
||||||
@@ -143,16 +121,21 @@ void obsffmpeg::ui::nvenc_h264_handler::log_options(obs_data_t* settings, const
|
|||||||
{
|
{
|
||||||
nvenc::log_options(settings, codec, context);
|
nvenc::log_options(settings, codec, context);
|
||||||
|
|
||||||
profile cfg_profile = static_cast<profile>(obs_data_get_int(settings, P_H264_PROFILE));
|
PLOG_INFO("[%s] H.265/HEVC:", codec->name);
|
||||||
level cfg_level = static_cast<level>(obs_data_get_int(settings, P_H264_LEVEL));
|
ffmpeg::tools::print_av_option_string(context, "profile", " Profile", [](int64_t v) {
|
||||||
|
profile val = static_cast<profile>(v);
|
||||||
auto found1 = profiles.find(cfg_profile);
|
auto index = profiles.find(val);
|
||||||
if (found1 != profiles.end())
|
if (index != profiles.end())
|
||||||
PLOG_INFO("[%s] H.264 Profile: %s", codec->name, found1->second.c_str());
|
return index->second;
|
||||||
|
return std::string("<Unknown>");
|
||||||
auto found2 = levels.find(cfg_level);
|
});
|
||||||
if (found2 != levels.end())
|
ffmpeg::tools::print_av_option_string(context, "level", " Level", [](int64_t v) {
|
||||||
PLOG_INFO("[%s] H.264 Level: %s", codec->name, found2->second.c_str());
|
level val = static_cast<level>(v);
|
||||||
|
auto index = levels.find(val);
|
||||||
|
if (index != levels.end())
|
||||||
|
return index->second;
|
||||||
|
return std::string("<Unknown>");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void obsffmpeg::ui::nvenc_h264_handler::get_encoder_properties(obs_properties_t* props, const AVCodec* codec)
|
void obsffmpeg::ui::nvenc_h264_handler::get_encoder_properties(obs_properties_t* props, const AVCodec* codec)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "nvenc_hevc_handler.hpp"
|
#include "nvenc_hevc_handler.hpp"
|
||||||
#include "codecs/hevc.hpp"
|
#include "codecs/hevc.hpp"
|
||||||
#include "encoder.hpp"
|
#include "encoder.hpp"
|
||||||
|
#include "ffmpeg/tools.hpp"
|
||||||
#include "nvenc_shared.hpp"
|
#include "nvenc_shared.hpp"
|
||||||
#include "plugin.hpp"
|
#include "plugin.hpp"
|
||||||
#include "strings.hpp"
|
#include "strings.hpp"
|
||||||
@@ -35,28 +36,6 @@ extern "C" {
|
|||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Missing Options:
|
|
||||||
|
|
||||||
Seem to be covered by initQP_* instead.
|
|
||||||
- [obs-ffmpeg-encoder] Option 'cq' with help 'Set target quality level (0 to 51, 0 means automatic) for constant quality mode in VBR rate control' of type 'Float' with default value '0.000000', minimum '0.000000' and maximum '51.000000'.
|
|
||||||
- [obs-ffmpeg-encoder] Option 'qp' with help 'Constant quantization parameter rate control method' of type 'Int' with default value '-1', minimum '-1.000000' and maximum '51.000000'.
|
|
||||||
|
|
||||||
Not sure what there are useful for.
|
|
||||||
[obs-ffmpeg-encoder] Option 'aud' with help 'Use access unit delimiters' of type 'Bool' with default value 'false', minimum '0.000000' and maximum '1.000000'.
|
|
||||||
[obs-ffmpeg-encoder] Option 'surfaces' with help 'Number of concurrent surfaces' of type 'Int' with default value '0', minimum '0.000000' and maximum '64.000000'.
|
|
||||||
[obs-ffmpeg-encoder] Option 'delay' with help 'Delay frame output by the given amount of frames' of type 'Int' with default value '2147483647', minimum '0.000000' and maximum '2147483647.000000'.
|
|
||||||
|
|
||||||
Should probably add this.
|
|
||||||
[obs-ffmpeg-encoder] Option 'gpu' with unit (gpu) with help 'Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on.' of type 'Int' with default value '-1', minimum '-2.000000' and maximum '2147483647.000000'.
|
|
||||||
[obs-ffmpeg-encoder] [gpu] Constant 'any' and help text 'Pick the first device available' with value '-1'.
|
|
||||||
[obs-ffmpeg-encoder] [gpu] Constant 'list' and help text 'List the available devices' with value '-2'.
|
|
||||||
|
|
||||||
Useless except for strict_gop maybe?
|
|
||||||
[obs-ffmpeg-encoder] Option 'forced-idr' with help 'If forcing keyframes, force them as IDR frames.' of type 'Bool' with default value 'false', minimum '-1.000000' and maximum '1.000000'.
|
|
||||||
[obs-ffmpeg-encoder] Option 'strict_gop' with help 'Set 1 to minimize GOP-to-GOP rate fluctuations' of type 'Bool' with default value 'false', minimum '0.000000' and maximum '1.000000'.
|
|
||||||
[obs-ffmpeg-encoder] Option 'bluray-compat' with help 'Bluray compatibility workarounds' of type 'Bool' with default value 'false', minimum '0.000000' and maximum '1.000000'.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using namespace obsffmpeg::codecs::hevc;
|
using namespace obsffmpeg::codecs::hevc;
|
||||||
|
|
||||||
std::map<profile, std::string> profiles{
|
std::map<profile, std::string> profiles{
|
||||||
@@ -150,21 +129,28 @@ void obsffmpeg::ui::nvenc_hevc_handler::log_options(obs_data_t* settings, const
|
|||||||
{
|
{
|
||||||
nvenc::log_options(settings, codec, context);
|
nvenc::log_options(settings, codec, context);
|
||||||
|
|
||||||
profile cfg_profile = static_cast<profile>(obs_data_get_int(settings, P_HEVC_PROFILE));
|
PLOG_INFO("[%s] H.265/HEVC:", codec->name);
|
||||||
tier cfg_tier = static_cast<tier>(obs_data_get_int(settings, P_HEVC_TIER));
|
ffmpeg::tools::print_av_option_string(context, "profile", " Profile", [](int64_t v) {
|
||||||
level cfg_level = static_cast<level>(obs_data_get_int(settings, P_HEVC_LEVEL));
|
profile val = static_cast<profile>(v);
|
||||||
|
auto index = profiles.find(val);
|
||||||
auto found1 = profiles.find(cfg_profile);
|
if (index != profiles.end())
|
||||||
if (found1 != profiles.end())
|
return index->second;
|
||||||
PLOG_INFO("[%s] H.265 Profile: %s", codec->name, found1->second.c_str());
|
return std::string("<Unknown>");
|
||||||
|
});
|
||||||
auto found2 = levels.find(cfg_level);
|
ffmpeg::tools::print_av_option_string(context, "level", " Level", [](int64_t v) {
|
||||||
if (found2 != levels.end())
|
level val = static_cast<level>(v);
|
||||||
PLOG_INFO("[%s] H.265 Level: %s", codec->name, found2->second.c_str());
|
auto index = levels.find(val);
|
||||||
|
if (index != levels.end())
|
||||||
auto found3 = tiers.find(cfg_tier);
|
return index->second;
|
||||||
if (found3 != tiers.end())
|
return std::string("<Unknown>");
|
||||||
PLOG_INFO("[%s] H.265 Tier: %s", codec->name, found3->second.c_str());
|
});
|
||||||
|
ffmpeg::tools::print_av_option_string(context, "tier", " Tier", [](int64_t v) {
|
||||||
|
tier val = static_cast<tier>(v);
|
||||||
|
auto index = tiers.find(val);
|
||||||
|
if (index != tiers.end())
|
||||||
|
return index->second;
|
||||||
|
return std::string("<Unknown>");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void obsffmpeg::ui::nvenc_hevc_handler::get_encoder_properties(obs_properties_t* props, const AVCodec* codec)
|
void obsffmpeg::ui::nvenc_hevc_handler::get_encoder_properties(obs_properties_t* props, const AVCodec* codec)
|
||||||
|
|||||||
+118
-148
@@ -23,6 +23,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "codecs/hevc.hpp"
|
#include "codecs/hevc.hpp"
|
||||||
#include "encoder.hpp"
|
#include "encoder.hpp"
|
||||||
|
#include "ffmpeg/tools.hpp"
|
||||||
#include "plugin.hpp"
|
#include "plugin.hpp"
|
||||||
#include "strings.hpp"
|
#include "strings.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
@@ -170,8 +171,8 @@ void obsffmpeg::nvenc::get_defaults(obs_data_t* settings, const AVCodec*, AVCode
|
|||||||
obs_data_set_default_int(settings, ST_RATECONTROL_MODE, static_cast<int64_t>(ratecontrolmode::CBR_HQ));
|
obs_data_set_default_int(settings, ST_RATECONTROL_MODE, static_cast<int64_t>(ratecontrolmode::CBR_HQ));
|
||||||
obs_data_set_default_int(settings, ST_RATECONTROL_TWOPASS, -1);
|
obs_data_set_default_int(settings, ST_RATECONTROL_TWOPASS, -1);
|
||||||
obs_data_set_default_int(settings, ST_RATECONTROL_LOOKAHEAD, 0);
|
obs_data_set_default_int(settings, ST_RATECONTROL_LOOKAHEAD, 0);
|
||||||
obs_data_set_default_bool(settings, ST_RATECONTROL_ADAPTIVEI, true);
|
obs_data_set_default_int(settings, ST_RATECONTROL_ADAPTIVEI, -1);
|
||||||
obs_data_set_default_bool(settings, ST_RATECONTROL_ADAPTIVEB, true);
|
obs_data_set_default_int(settings, ST_RATECONTROL_ADAPTIVEB, -1);
|
||||||
|
|
||||||
obs_data_set_default_int(settings, ST_RATECONTROL_BITRATE_TARGET, 6000);
|
obs_data_set_default_int(settings, ST_RATECONTROL_BITRATE_TARGET, 6000);
|
||||||
obs_data_set_default_int(settings, ST_RATECONTROL_BITRATE_MAXIMUM, 6000);
|
obs_data_set_default_int(settings, ST_RATECONTROL_BITRATE_MAXIMUM, 6000);
|
||||||
@@ -188,15 +189,15 @@ void obsffmpeg::nvenc::get_defaults(obs_data_t* settings, const AVCodec*, AVCode
|
|||||||
obs_data_set_default_int(settings, ST_RATECONTROL_QP_B, 21);
|
obs_data_set_default_int(settings, ST_RATECONTROL_QP_B, 21);
|
||||||
obs_data_set_default_int(settings, ST_RATECONTROL_QP_B_INITIAL, -1);
|
obs_data_set_default_int(settings, ST_RATECONTROL_QP_B_INITIAL, -1);
|
||||||
|
|
||||||
obs_data_set_default_bool(settings, ST_AQ_SPATIAL, true);
|
obs_data_set_default_int(settings, ST_AQ_SPATIAL, -1);
|
||||||
obs_data_set_default_int(settings, ST_AQ_STRENGTH, 8);
|
obs_data_set_default_int(settings, ST_AQ_STRENGTH, 8);
|
||||||
obs_data_set_default_bool(settings, ST_AQ_TEMPORAL, true);
|
obs_data_set_default_int(settings, ST_AQ_TEMPORAL, -1);
|
||||||
|
|
||||||
obs_data_set_default_int(settings, ST_OTHER_BFRAMES, 2);
|
obs_data_set_default_int(settings, ST_OTHER_BFRAMES, 2);
|
||||||
obs_data_set_default_int(settings, ST_OTHER_BFRAME_REFERENCEMODE, static_cast<int64_t>(b_ref_mode::DISABLED));
|
obs_data_set_default_int(settings, ST_OTHER_BFRAME_REFERENCEMODE, static_cast<int64_t>(b_ref_mode::DISABLED));
|
||||||
obs_data_set_default_bool(settings, ST_OTHER_ZEROLATENCY, false);
|
obs_data_set_default_int(settings, ST_OTHER_ZEROLATENCY, -1);
|
||||||
obs_data_set_default_bool(settings, ST_OTHER_WEIGHTED_PREDICTION, false);
|
obs_data_set_default_int(settings, ST_OTHER_WEIGHTED_PREDICTION, -1);
|
||||||
obs_data_set_default_bool(settings, ST_OTHER_NONREFERENCE_PFRAMES, false);
|
obs_data_set_default_int(settings, ST_OTHER_NONREFERENCE_PFRAMES, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool modified_ratecontrol(obs_properties_t* props, obs_property_t*, obs_data_t* settings)
|
static bool modified_ratecontrol(obs_properties_t* props, obs_property_t*, obs_data_t* settings)
|
||||||
@@ -259,7 +260,7 @@ static bool modified_quality(obs_properties_t* props, obs_property_t*, obs_data_
|
|||||||
|
|
||||||
static bool modified_aq(obs_properties_t* props, obs_property_t*, obs_data_t* settings)
|
static bool modified_aq(obs_properties_t* props, obs_property_t*, obs_data_t* settings)
|
||||||
{
|
{
|
||||||
bool spatial_aq = obs_data_get_bool(settings, ST_AQ_SPATIAL);
|
bool spatial_aq = obs_data_get_int(settings, ST_AQ_SPATIAL) == 1;
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_AQ_STRENGTH), spatial_aq);
|
obs_property_set_visible(obs_properties_get(props, ST_AQ_STRENGTH), spatial_aq);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -298,12 +299,9 @@ void obsffmpeg::nvenc::get_properties_post(obs_properties_t* props, const AVCode
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto p = obs_properties_add_list(grp, ST_RATECONTROL_TWOPASS, TRANSLATE(ST_RATECONTROL_TWOPASS),
|
auto p = obsffmpeg::obs_properties_add_tristate(grp, ST_RATECONTROL_TWOPASS,
|
||||||
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
TRANSLATE(ST_RATECONTROL_TWOPASS));
|
||||||
obs_property_set_long_description(p, TRANSLATE(DESC(ST_RATECONTROL_TWOPASS)));
|
obs_property_set_long_description(p, TRANSLATE(DESC(ST_RATECONTROL_TWOPASS)));
|
||||||
obs_property_list_add_int(p, TRANSLATE(S_STATE_DEFAULT), -1);
|
|
||||||
obs_property_list_add_int(p, TRANSLATE(S_STATE_DISABLED), 0);
|
|
||||||
obs_property_list_add_int(p, TRANSLATE(S_STATE_ENABLED), 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -313,13 +311,13 @@ void obsffmpeg::nvenc::get_properties_post(obs_properties_t* props, const AVCode
|
|||||||
obs_property_int_set_suffix(p, " frames");
|
obs_property_int_set_suffix(p, " frames");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto p =
|
auto p = obsffmpeg::obs_properties_add_tristate(grp, ST_RATECONTROL_ADAPTIVEI,
|
||||||
obs_properties_add_bool(grp, ST_RATECONTROL_ADAPTIVEI, TRANSLATE(ST_RATECONTROL_ADAPTIVEI));
|
TRANSLATE(ST_RATECONTROL_ADAPTIVEI));
|
||||||
obs_property_set_long_description(p, TRANSLATE(DESC(ST_RATECONTROL_ADAPTIVEI)));
|
obs_property_set_long_description(p, TRANSLATE(DESC(ST_RATECONTROL_ADAPTIVEI)));
|
||||||
}
|
}
|
||||||
if (strcmp(codec->name, "h264_nvenc") == 0) {
|
if (strcmp(codec->name, "h264_nvenc") == 0) {
|
||||||
auto p =
|
auto p = obsffmpeg::obs_properties_add_tristate(grp, ST_RATECONTROL_ADAPTIVEB,
|
||||||
obs_properties_add_bool(grp, ST_RATECONTROL_ADAPTIVEB, TRANSLATE(ST_RATECONTROL_ADAPTIVEB));
|
TRANSLATE(ST_RATECONTROL_ADAPTIVEB));
|
||||||
obs_property_set_long_description(p, TRANSLATE(DESC(ST_RATECONTROL_ADAPTIVEB)));
|
obs_property_set_long_description(p, TRANSLATE(DESC(ST_RATECONTROL_ADAPTIVEB)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -435,7 +433,7 @@ void obsffmpeg::nvenc::get_properties_post(obs_properties_t* props, const AVCode
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto p = obs_properties_add_bool(grp, ST_AQ_SPATIAL, TRANSLATE(ST_AQ_SPATIAL));
|
auto p = obsffmpeg::obs_properties_add_tristate(grp, ST_AQ_SPATIAL, TRANSLATE(ST_AQ_SPATIAL));
|
||||||
obs_property_set_long_description(p, TRANSLATE(DESC(ST_AQ_SPATIAL)));
|
obs_property_set_long_description(p, TRANSLATE(DESC(ST_AQ_SPATIAL)));
|
||||||
obs_property_set_modified_callback(p, modified_aq);
|
obs_property_set_modified_callback(p, modified_aq);
|
||||||
}
|
}
|
||||||
@@ -445,7 +443,7 @@ void obsffmpeg::nvenc::get_properties_post(obs_properties_t* props, const AVCode
|
|||||||
obs_property_set_long_description(p, TRANSLATE(DESC(ST_AQ_STRENGTH)));
|
obs_property_set_long_description(p, TRANSLATE(DESC(ST_AQ_STRENGTH)));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto p = obs_properties_add_bool(grp, ST_AQ_TEMPORAL, TRANSLATE(ST_AQ_TEMPORAL));
|
auto p = obsffmpeg::obs_properties_add_tristate(grp, ST_AQ_TEMPORAL, TRANSLATE(ST_AQ_TEMPORAL));
|
||||||
obs_property_set_long_description(p, TRANSLATE(DESC(ST_AQ_TEMPORAL)));
|
obs_property_set_long_description(p, TRANSLATE(DESC(ST_AQ_TEMPORAL)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -476,18 +474,19 @@ void obsffmpeg::nvenc::get_properties_post(obs_properties_t* props, const AVCode
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto p = obs_properties_add_bool(grp, ST_OTHER_ZEROLATENCY, TRANSLATE(ST_OTHER_ZEROLATENCY));
|
auto p = obsffmpeg::obs_properties_add_tristate(grp, ST_OTHER_ZEROLATENCY,
|
||||||
|
TRANSLATE(ST_OTHER_ZEROLATENCY));
|
||||||
obs_property_set_long_description(p, TRANSLATE(DESC(ST_OTHER_ZEROLATENCY)));
|
obs_property_set_long_description(p, TRANSLATE(DESC(ST_OTHER_ZEROLATENCY)));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto p = obs_properties_add_bool(grp, ST_OTHER_WEIGHTED_PREDICTION,
|
auto p = obsffmpeg::obs_properties_add_tristate(grp, ST_OTHER_WEIGHTED_PREDICTION,
|
||||||
TRANSLATE(ST_OTHER_WEIGHTED_PREDICTION));
|
TRANSLATE(ST_OTHER_WEIGHTED_PREDICTION));
|
||||||
obs_property_set_long_description(p, TRANSLATE(DESC(ST_OTHER_WEIGHTED_PREDICTION)));
|
obs_property_set_long_description(p, TRANSLATE(DESC(ST_OTHER_WEIGHTED_PREDICTION)));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto p = obs_properties_add_bool(grp, ST_OTHER_NONREFERENCE_PFRAMES,
|
auto p = obsffmpeg::obs_properties_add_tristate(grp, ST_OTHER_NONREFERENCE_PFRAMES,
|
||||||
TRANSLATE(ST_OTHER_NONREFERENCE_PFRAMES));
|
TRANSLATE(ST_OTHER_NONREFERENCE_PFRAMES));
|
||||||
obs_property_set_long_description(p, TRANSLATE(DESC(ST_OTHER_NONREFERENCE_PFRAMES)));
|
obs_property_set_long_description(p, TRANSLATE(DESC(ST_OTHER_NONREFERENCE_PFRAMES)));
|
||||||
}
|
}
|
||||||
@@ -555,6 +554,7 @@ void obsffmpeg::nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCode
|
|||||||
av_opt_set(context->priv_data, "rc", rcopt->second.c_str(), 0);
|
av_opt_set(context->priv_data, "rc", rcopt->second.c_str(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
av_opt_set_int(context->priv_data, "cbr", 0, 0);
|
||||||
switch (rc) {
|
switch (rc) {
|
||||||
case ratecontrolmode::CQP:
|
case ratecontrolmode::CQP:
|
||||||
have_qp = true;
|
have_qp = true;
|
||||||
@@ -580,14 +580,18 @@ void obsffmpeg::nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCode
|
|||||||
}
|
}
|
||||||
|
|
||||||
int la = static_cast<int>(obs_data_get_int(settings, ST_RATECONTROL_LOOKAHEAD));
|
int la = static_cast<int>(obs_data_get_int(settings, ST_RATECONTROL_LOOKAHEAD));
|
||||||
av_opt_set_int(context->priv_data, "lookahead", la, 0);
|
av_opt_set_int(context->priv_data, "rc-lookahead", la, 0);
|
||||||
if (la > 0) {
|
if (la > 0) {
|
||||||
bool adapt_i = obs_data_get_bool(settings, ST_RATECONTROL_ADAPTIVEI);
|
int64_t adapt_i = obs_data_get_int(settings, ST_RATECONTROL_ADAPTIVEI);
|
||||||
av_opt_set_int(context->priv_data, "no-scenecut", !adapt_i ? 1 : 0, 0);
|
if (!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")) {
|
if (strcmp(codec->name, "h264_nvenc")) {
|
||||||
bool adapt_b = obs_data_get_bool(settings, ST_RATECONTROL_ADAPTIVEB);
|
int64_t adapt_b = obs_data_get_int(settings, ST_RATECONTROL_ADAPTIVEB);
|
||||||
av_opt_set_int(context->priv_data, "b_adapt", adapt_b ? 1 : 0, 0);
|
if (!is_tristate_default(adapt_b)) {
|
||||||
|
av_opt_set_int(context->priv_data, "b_adapt", adapt_b, AV_OPT_SEARCH_CHILDREN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -636,37 +640,42 @@ void obsffmpeg::nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCode
|
|||||||
}
|
}
|
||||||
|
|
||||||
{ // AQ
|
{ // AQ
|
||||||
bool saq = obs_data_get_bool(settings, ST_AQ_SPATIAL);
|
int64_t saq = obs_data_get_int(settings, ST_AQ_SPATIAL);
|
||||||
bool taq = obs_data_get_bool(settings, ST_AQ_TEMPORAL);
|
int64_t taq = obs_data_get_int(settings, ST_AQ_TEMPORAL);
|
||||||
|
|
||||||
if (strcmp(codec->name, "h264_nvenc")) {
|
if (strcmp(codec->name, "h264_nvenc") == 0) {
|
||||||
av_opt_set_int(context->priv_data, "spatial-aq", saq ? 1 : 0, 0);
|
if (!is_tristate_default(saq))
|
||||||
av_opt_set_int(context->priv_data, "temporal-aq", taq ? 1 : 0, 0);
|
av_opt_set_int(context->priv_data, "spatial-aq", saq, 0);
|
||||||
|
if (!is_tristate_default(taq))
|
||||||
|
av_opt_set_int(context->priv_data, "temporal-aq", taq, 0);
|
||||||
} else {
|
} else {
|
||||||
av_opt_set_int(context->priv_data, "spatial_aq", saq ? 1 : 0, 0);
|
if (!is_tristate_default(saq))
|
||||||
av_opt_set_int(context->priv_data, "temporal_aq", taq ? 1 : 0, 0);
|
av_opt_set_int(context->priv_data, "spatial_aq", saq, 0);
|
||||||
|
if (!is_tristate_default(taq))
|
||||||
|
av_opt_set_int(context->priv_data, "temporal_aq", taq, 0);
|
||||||
}
|
}
|
||||||
if (saq) {
|
if (is_tristate_enabled(saq))
|
||||||
av_opt_set_int(context->priv_data, "aq-strength",
|
av_opt_set_int(context->priv_data, "aq-strength",
|
||||||
static_cast<int>(obs_data_get_int(settings, ST_AQ_STRENGTH)), 0);
|
static_cast<int>(obs_data_get_int(settings, ST_AQ_STRENGTH)), 0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
{ // Other
|
{ // Other
|
||||||
bool zl = obs_data_get_bool(settings, ST_OTHER_ZEROLATENCY);
|
int64_t zl = obs_data_get_int(settings, ST_OTHER_ZEROLATENCY);
|
||||||
bool wp = obs_data_get_bool(settings, ST_OTHER_WEIGHTED_PREDICTION);
|
int64_t wp = obs_data_get_int(settings, ST_OTHER_WEIGHTED_PREDICTION);
|
||||||
bool nrp = obs_data_get_bool(settings, ST_OTHER_NONREFERENCE_PFRAMES);
|
int64_t nrp = obs_data_get_int(settings, ST_OTHER_NONREFERENCE_PFRAMES);
|
||||||
|
|
||||||
context->max_b_frames = static_cast<int>(obs_data_get_int(settings, ST_OTHER_BFRAMES));
|
context->max_b_frames = static_cast<int>(obs_data_get_int(settings, ST_OTHER_BFRAMES));
|
||||||
|
|
||||||
av_opt_set_int(context->priv_data, "zerolatency", zl ? 1 : 0, 0);
|
if (!is_tristate_default(zl))
|
||||||
av_opt_set_int(context->priv_data, "nonref_p", nrp ? 1 : 0, 0);
|
av_opt_set_int(context->priv_data, "zerolatency", zl, 0);
|
||||||
|
if (!is_tristate_default(nrp))
|
||||||
|
av_opt_set_int(context->priv_data, "nonref_p", nrp, 0);
|
||||||
|
|
||||||
if ((context->max_b_frames != 0) && wp) {
|
if ((context->max_b_frames != 0) && is_tristate_enabled(wp)) {
|
||||||
PLOG_WARNING(
|
PLOG_WARNING("[%s] Weighted Prediction disabled because of B-Frames being used.", codec->name);
|
||||||
"Automatically disabled weighted prediction due to being incompatible with B-Frames.");
|
av_opt_set_int(context->priv_data, "weighted_pred", 0, 0);
|
||||||
} else {
|
} else if (!is_tristate_default(wp)) {
|
||||||
av_opt_set_int(context->priv_data, "weighted_pred", wp ? 1 : 0, 0);
|
av_opt_set_int(context->priv_data, "weighted_pred", wp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -679,112 +688,73 @@ void obsffmpeg::nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void obsffmpeg::nvenc::log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context)
|
void obsffmpeg::nvenc::log_options(obs_data_t*, const AVCodec* codec, AVCodecContext* context)
|
||||||
{
|
{
|
||||||
preset cfg_preset = static_cast<preset>(obs_data_get_int(settings, ST_PRESET));
|
PLOG_INFO("[%s] Nvidia NVENC:", codec->name);
|
||||||
|
ffmpeg::tools::print_av_option_string(context, "preset", " Preset", [](int64_t v) {
|
||||||
|
preset val = static_cast<preset>(v);
|
||||||
|
std::string name = "<Unknown>";
|
||||||
|
auto index = preset_to_opt.find(val);
|
||||||
|
if (index != preset_to_opt.end())
|
||||||
|
name = index->second;
|
||||||
|
return name;
|
||||||
|
});
|
||||||
|
ffmpeg::tools::print_av_option_string(context, "rc", " Rate Control", [](int64_t v) {
|
||||||
|
ratecontrolmode val = static_cast<ratecontrolmode>(v);
|
||||||
|
std::string name = "<Unknown>";
|
||||||
|
auto index = ratecontrolmode_to_opt.find(val);
|
||||||
|
if (index != ratecontrolmode_to_opt.end())
|
||||||
|
name = index->second;
|
||||||
|
return name;
|
||||||
|
});
|
||||||
|
ffmpeg::tools::print_av_option_bool(context, "2pass", " Two Pass");
|
||||||
|
ffmpeg::tools::print_av_option_int(context, "rc-lookahead", " Look-Ahead", "Frames");
|
||||||
|
ffmpeg::tools::print_av_option_bool(context, "no-scenecut", " Adaptive I-Frames");
|
||||||
|
if (strcmp(codec->name, "h264_nvenc") == 0)
|
||||||
|
ffmpeg::tools::print_av_option_bool(context, "b_adapt", " Adaptive B-Frames");
|
||||||
|
|
||||||
auto found1 = preset_to_opt.find(cfg_preset);
|
PLOG_INFO("[%s] Bitrate:", codec->name);
|
||||||
if (found1 != preset_to_opt.end())
|
ffmpeg::tools::print_av_option_int(context, "bitrate", " Target", "bits/sec");
|
||||||
PLOG_INFO("[%s] Preset: %s", codec->name, found1->second.c_str());
|
ffmpeg::tools::print_av_option_int(context, "rc_max_rate", " Maximum", "bits/sec");
|
||||||
|
ffmpeg::tools::print_av_option_int(context, "rc_buffer_size", " Buffer", "bits");
|
||||||
|
PLOG_INFO("[%s] Quality:", codec->name);
|
||||||
|
ffmpeg::tools::print_av_option_int(context, "qmin", " Minimum", "");
|
||||||
|
ffmpeg::tools::print_av_option_int(context, "cq", " Target", "");
|
||||||
|
ffmpeg::tools::print_av_option_int(context, "qmax", " Maximum", "");
|
||||||
|
PLOG_INFO("[%s] Quantization Parameters:", codec->name);
|
||||||
|
ffmpeg::tools::print_av_option_int(context, "init_qpI", " I-Frame", "");
|
||||||
|
ffmpeg::tools::print_av_option_int(context, "init_qpP", " P-Frame", "");
|
||||||
|
ffmpeg::tools::print_av_option_int(context, "init_qpB", " B-Frame", "");
|
||||||
|
|
||||||
ratecontrolmode cfg_rc_mode = static_cast<ratecontrolmode>(obs_data_get_int(settings, ST_RATECONTROL_MODE));
|
ffmpeg::tools::print_av_option_int(context, "max_b_frames", " B-Frames", "Frames");
|
||||||
int64_t cfg_rc_2pass = obs_data_get_int(settings, ST_RATECONTROL_TWOPASS);
|
ffmpeg::tools::print_av_option_string(context, "b_ref_mode", " Reference Mode", [](int64_t v) {
|
||||||
int64_t cfg_rc_lahead = obs_data_get_int(settings, ST_RATECONTROL_LOOKAHEAD);
|
b_ref_mode val = static_cast<b_ref_mode>(v);
|
||||||
bool cfg_rc_adapti = obs_data_get_bool(settings, ST_RATECONTROL_ADAPTIVEI);
|
std::string name = "<Unknown>";
|
||||||
bool cfg_rc_adaptb = obs_data_get_bool(settings, ST_RATECONTROL_ADAPTIVEB);
|
auto index = b_ref_mode_to_opt.find(val);
|
||||||
|
if (index != b_ref_mode_to_opt.end())
|
||||||
|
name = index->second;
|
||||||
|
return name;
|
||||||
|
});
|
||||||
|
|
||||||
auto found2 = ratecontrolmode_to_opt.find(cfg_rc_mode);
|
PLOG_INFO("[%s] Adaptive Quantization:", codec->name);
|
||||||
if (found2 != ratecontrolmode_to_opt.end())
|
if (strcmp(codec->name, "h264_nvenc") == 0) {
|
||||||
PLOG_INFO("[%s] Rate Control: %s", codec->name, found2->second.c_str());
|
ffmpeg::tools::print_av_option_bool(context, "spatial-aq", " Spatial AQ");
|
||||||
PLOG_INFO("[%s] Two Pass: %s", codec->name,
|
ffmpeg::tools::print_av_option_int(context, "aq-strength", " Strength", "");
|
||||||
cfg_rc_2pass == 1 ? "Enabled" : (cfg_rc_2pass == 0 ? "Disabled" : "Default"));
|
ffmpeg::tools::print_av_option_bool(context, "temporal-aq", " Temporal AQ");
|
||||||
PLOG_INFO("[%s] Lookahead: %" PRId64 " Frames", codec->name, cfg_rc_lahead);
|
} else {
|
||||||
if (cfg_rc_adapti && cfg_rc_lahead > 0)
|
ffmpeg::tools::print_av_option_bool(context, "spatial_aq", " Spatial AQ");
|
||||||
PLOG_INFO("[%s] Adaptive I-Frames Enabled", codec->name);
|
ffmpeg::tools::print_av_option_int(context, "aq-strength", " Strength", "");
|
||||||
if (cfg_rc_adaptb && cfg_rc_lahead > 0)
|
ffmpeg::tools::print_av_option_bool(context, "temporal_aq", " Temporal AQ");
|
||||||
PLOG_INFO("[%s] Adaptive B-Frames Enabled", codec->name);
|
|
||||||
|
|
||||||
int64_t cfg_rc_bitrate = obs_data_get_int(settings, ST_RATECONTROL_BITRATE_TARGET);
|
|
||||||
int64_t cfg_rc_max_bitrate = obs_data_get_int(settings, ST_RATECONTROL_BITRATE_MAXIMUM);
|
|
||||||
int64_t cfg_rc_bufsize = obs_data_get_int(settings, S_RATECONTROL_BUFFERSIZE);
|
|
||||||
bool cfg_rc_quality = obs_data_get_bool(settings, ST_RATECONTROL_QUALITY);
|
|
||||||
int64_t cfg_rc_quality_min = obs_data_get_int(settings, ST_RATECONTROL_QUALITY_MINIMUM);
|
|
||||||
int64_t cfg_rc_quality_max = obs_data_get_int(settings, ST_RATECONTROL_QUALITY_MAXIMUM);
|
|
||||||
double_t cfg_rc_quality_tgt = obs_data_get_double(settings, ST_RATECONTROL_QUALITY_TARGET) / 100.0 * 51.0;
|
|
||||||
int64_t cfg_rc_qp_i = obs_data_get_int(settings, ST_RATECONTROL_QP_I);
|
|
||||||
int64_t cfg_rc_qp_p = obs_data_get_int(settings, ST_RATECONTROL_QP_P);
|
|
||||||
int64_t cfg_rc_qp_b = obs_data_get_int(settings, ST_RATECONTROL_QP_B);
|
|
||||||
int64_t cfg_rc_qp_i_init = obs_data_get_int(settings, ST_RATECONTROL_QP_I_INITIAL);
|
|
||||||
int64_t cfg_rc_qp_p_init = obs_data_get_int(settings, ST_RATECONTROL_QP_P_INITIAL);
|
|
||||||
int64_t cfg_rc_qp_b_init = obs_data_get_int(settings, ST_RATECONTROL_QP_B_INITIAL);
|
|
||||||
|
|
||||||
{
|
|
||||||
bool have_bitrate = false;
|
|
||||||
bool have_bitrate_max = false;
|
|
||||||
bool have_quality = false;
|
|
||||||
bool have_qp = false;
|
|
||||||
bool have_qp_init = false;
|
|
||||||
|
|
||||||
switch (cfg_rc_mode) {
|
|
||||||
case ratecontrolmode::CQP:
|
|
||||||
have_qp = true;
|
|
||||||
break;
|
|
||||||
case ratecontrolmode::CBR:
|
|
||||||
case ratecontrolmode::CBR_HQ:
|
|
||||||
case ratecontrolmode::CBR_LD_HQ:
|
|
||||||
have_bitrate = true;
|
|
||||||
av_opt_set_int(context->priv_data, "cbr", 1, 0);
|
|
||||||
break;
|
|
||||||
case ratecontrolmode::VBR:
|
|
||||||
case ratecontrolmode::VBR_HQ:
|
|
||||||
have_bitrate_max = true;
|
|
||||||
have_bitrate = true;
|
|
||||||
have_quality = true;
|
|
||||||
have_qp_init = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PLOG_INFO("[%s] Buffer Size: %" PRId64, codec->name, cfg_rc_bufsize);
|
PLOG_INFO("[%s] Other:", codec->name);
|
||||||
if (have_bitrate)
|
ffmpeg::tools::print_av_option_bool(context, "zerolatency", " Zero Latency");
|
||||||
PLOG_INFO("[%s] Bitrate Target: %" PRId64, codec->name, cfg_rc_bitrate);
|
ffmpeg::tools::print_av_option_bool(context, "weighted_pred", " Weighted Prediction");
|
||||||
if (have_bitrate_max)
|
ffmpeg::tools::print_av_option_bool(context, "nonref_p", " Non-reference P-Frames");
|
||||||
PLOG_INFO("[%s] Bitrate Maximum: %" PRId64, codec->name, cfg_rc_max_bitrate);
|
ffmpeg::tools::print_av_option_bool(context, "strict_gop", " Strict GOP");
|
||||||
if (have_quality && cfg_rc_quality) {
|
ffmpeg::tools::print_av_option_bool(context, "aud", " Access Unit Delimiters");
|
||||||
PLOG_INFO("[%s] Quality Limits:", codec->name);
|
ffmpeg::tools::print_av_option_bool(context, "bluray-compat", " Bluray Compatibility");
|
||||||
PLOG_INFO("[%s] Minimum: %" PRId64, codec->name, cfg_rc_quality_min);
|
if (strcmp(codec->name, "h264_nvenc") == 0)
|
||||||
PLOG_INFO("[%s] Maximum: %" PRId64, codec->name, cfg_rc_quality_max);
|
ffmpeg::tools::print_av_option_bool(context, "a53cc", " A53 Closed Captions");
|
||||||
PLOG_INFO("[%s] Target: %f", codec->name, cfg_rc_quality_tgt);
|
ffmpeg::tools::print_av_option_int(context, "dpb_size", " DPB Size", "");
|
||||||
}
|
|
||||||
if (have_qp)
|
|
||||||
PLOG_INFO("[%s] QP Values: %" PRId64 "/%" PRId64 "/%" PRId64, codec->name, cfg_rc_qp_i,
|
|
||||||
cfg_rc_qp_p, cfg_rc_qp_b);
|
|
||||||
if (have_qp_init)
|
|
||||||
PLOG_INFO("[%s] Initial QP Values: %" PRId64 "/%" PRId64 "/%" PRId64, codec->name,
|
|
||||||
cfg_rc_qp_i_init, cfg_rc_qp_p_init, cfg_rc_qp_b_init);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cfg_aq_spatial = obs_data_get_bool(settings, ST_AQ_SPATIAL);
|
|
||||||
int64_t cfg_aq_strength = obs_data_get_int(settings, ST_AQ_STRENGTH);
|
|
||||||
bool cfg_aq_temporal = obs_data_get_bool(settings, ST_AQ_TEMPORAL);
|
|
||||||
if (cfg_aq_spatial)
|
|
||||||
PLOG_INFO("[%s] Spatial AQ Enabled: Strength %" PRId64, codec->name, cfg_aq_strength);
|
|
||||||
if (cfg_aq_temporal)
|
|
||||||
PLOG_INFO("[%s] Temporal AQ Enabled", codec->name);
|
|
||||||
|
|
||||||
int64_t cfg_bf = obs_data_get_int(settings, ST_OTHER_BFRAMES);
|
|
||||||
b_ref_mode cfg_bf_mode = static_cast<b_ref_mode>(obs_data_get_int(settings, ST_OTHER_BFRAME_REFERENCEMODE));
|
|
||||||
bool cfg_zerolatency = obs_data_get_bool(settings, ST_OTHER_ZEROLATENCY);
|
|
||||||
bool cfg_weightp = obs_data_get_bool(settings, ST_OTHER_WEIGHTED_PREDICTION);
|
|
||||||
bool cfg_nonrefp = obs_data_get_bool(settings, ST_OTHER_NONREFERENCE_PFRAMES);
|
|
||||||
|
|
||||||
PLOG_INFO("[%s] B-Frames: %" PRId64, codec->name, cfg_bf);
|
|
||||||
auto found3 = b_ref_mode_to_opt.find(cfg_bf_mode);
|
|
||||||
if (found3 != b_ref_mode_to_opt.end())
|
|
||||||
PLOG_INFO("[%s] Reference Mode: %s", codec->name, found3->second.c_str());
|
|
||||||
if (cfg_zerolatency)
|
|
||||||
PLOG_INFO("[%s] Zero Latency Enabled", codec->name);
|
|
||||||
if (cfg_weightp)
|
|
||||||
PLOG_INFO("[%s] Weighted Prediction Enabled", codec->name);
|
|
||||||
if (cfg_nonrefp)
|
|
||||||
PLOG_INFO("[%s] Non-Ref P-Frames Enabled", codec->name);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ namespace obsffmpeg {
|
|||||||
LOW_LATENCY_HIGH_QUALITY,
|
LOW_LATENCY_HIGH_QUALITY,
|
||||||
LOSSLESS,
|
LOSSLESS,
|
||||||
LOSSLESS_HIGH_PERFORMANCE,
|
LOSSLESS_HIGH_PERFORMANCE,
|
||||||
|
// Append things before this.
|
||||||
|
INVALID = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ratecontrolmode : int64_t {
|
enum class ratecontrolmode : int64_t {
|
||||||
@@ -57,12 +59,16 @@ namespace obsffmpeg {
|
|||||||
CBR,
|
CBR,
|
||||||
CBR_HQ,
|
CBR_HQ,
|
||||||
CBR_LD_HQ,
|
CBR_LD_HQ,
|
||||||
|
// Append things before this.
|
||||||
|
INVALID = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class b_ref_mode : int64_t {
|
enum class b_ref_mode : int64_t {
|
||||||
DISABLED,
|
DISABLED,
|
||||||
EACH,
|
EACH,
|
||||||
MIDDLE,
|
MIDDLE,
|
||||||
|
// Append things before this.
|
||||||
|
INVALID = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::map<preset, std::string> presets;
|
extern std::map<preset, std::string> presets;
|
||||||
|
|||||||
Reference in New Issue
Block a user