nvencoder: Add support for new preset/tune/multi-pass options

Adding new P1 ~ P7 presets and deprecate old preset values.
Also adding tune and multi-pass properties.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5428>
This commit is contained in:
Seungha Yang 2023-10-02 21:57:19 +09:00 committed by GStreamer Marge Bot
parent 3d807d4f6d
commit 0a05ba3f62
5 changed files with 440 additions and 83 deletions

View file

@ -150,6 +150,18 @@ NvEncGetEncodePresetConfig (void *encoder, GUID encodeGUID,
presetConfig);
}
NVENCSTATUS NVENCAPI
NvEncGetEncodePresetConfigEx (void *encoder, GUID encodeGUID,
GUID presetGUID, NV_ENC_TUNING_INFO tuningInfo,
NV_ENC_PRESET_CONFIG * presetConfig)
{
if (!nvenc_api.nvEncGetEncodePresetConfigEx)
return NV_ENC_ERR_UNIMPLEMENTED;
return nvenc_api.nvEncGetEncodePresetConfigEx (encoder, encodeGUID,
presetGUID, tuningInfo, presetConfig);
}
NVENCSTATUS NVENCAPI
NvEncGetEncodeCaps (void *encoder, GUID encodeGUID,
NV_ENC_CAPS_PARAM * capsParam, int *capsVal)

View file

@ -2063,17 +2063,32 @@ gst_nv_encoder_preset_get_type (void)
{
static GType preset_type = 0;
static const GEnumValue presets[] = {
{GST_NV_ENCODER_PRESET_DEFAULT, "Default", "default"},
{GST_NV_ENCODER_PRESET_HP, "High Performance", "hp"},
{GST_NV_ENCODER_PRESET_HQ, "High Quality", "hq"},
{GST_NV_ENCODER_PRESET_LOW_LATENCY_DEFAULT, "Low Latency", "low-latency"},
{GST_NV_ENCODER_PRESET_LOW_LATENCY_HQ, "Low Latency, High Quality",
{GST_NV_ENCODER_PRESET_DEFAULT, "Default (deprecated, use p1~7 with tune)",
"default"},
{GST_NV_ENCODER_PRESET_HP,
"High Performance (deprecated, use p1~7 with tune)", "hp"},
{GST_NV_ENCODER_PRESET_HQ, "High Quality (deprecated, use p1~7 with tune)",
"hq"},
{GST_NV_ENCODER_PRESET_LOW_LATENCY_DEFAULT,
"Low Latency (deprecated, use p1~7 with tune)", "low-latency"},
{GST_NV_ENCODER_PRESET_LOW_LATENCY_HQ,
"Low Latency (deprecated, use p1~7 with tune), High Quality",
"low-latency-hq"},
{GST_NV_ENCODER_PRESET_LOW_LATENCY_HP, "Low Latency, High Performance",
{GST_NV_ENCODER_PRESET_LOW_LATENCY_HP,
"Low Latency (deprecated, use p1~7 with tune), High Performance",
"low-latency-hp"},
{GST_NV_ENCODER_PRESET_LOSSLESS_DEFAULT, "Lossless", "lossless"},
{GST_NV_ENCODER_PRESET_LOSSLESS_HP, "Lossless, High Performance",
{GST_NV_ENCODER_PRESET_LOSSLESS_DEFAULT,
"Lossless (deprecated, use p1~7 with tune)", "lossless"},
{GST_NV_ENCODER_PRESET_LOSSLESS_HP,
"Lossless (deprecated, use p1~7 with tune), High Performance",
"lossless-hp"},
{GST_NV_ENCODER_PRESET_P1, "P1, fastest", "p1"},
{GST_NV_ENCODER_PRESET_P2, "P2, faster", "p2"},
{GST_NV_ENCODER_PRESET_P3, "P3, fast", "p3"},
{GST_NV_ENCODER_PRESET_P4, "P4, medium", "p4"},
{GST_NV_ENCODER_PRESET_P5, "P5, slow", "p5"},
{GST_NV_ENCODER_PRESET_P6, "P6, slower", "p6"},
{GST_NV_ENCODER_PRESET_P7, "P7, slowest", "p7"},
{0, NULL, NULL},
};
@ -2086,41 +2101,6 @@ gst_nv_encoder_preset_get_type (void)
return preset_type;
}
void
gst_nv_encoder_preset_to_guid (GstNvEncoderPreset preset, GUID * guid)
{
switch (preset) {
case GST_NV_ENCODER_PRESET_DEFAULT:
*guid = NV_ENC_PRESET_DEFAULT_GUID;
break;
case GST_NV_ENCODER_PRESET_HP:
*guid = NV_ENC_PRESET_HP_GUID;
break;
case GST_NV_ENCODER_PRESET_HQ:
*guid = NV_ENC_PRESET_HQ_GUID;
break;
case GST_NV_ENCODER_PRESET_LOW_LATENCY_DEFAULT:
*guid = NV_ENC_PRESET_LOW_LATENCY_DEFAULT_GUID;
break;
case GST_NV_ENCODER_PRESET_LOW_LATENCY_HQ:
*guid = NV_ENC_PRESET_LOW_LATENCY_HQ_GUID;
break;
case GST_NV_ENCODER_PRESET_LOW_LATENCY_HP:
*guid = NV_ENC_PRESET_LOW_LATENCY_HP_GUID;
break;
case GST_NV_ENCODER_PRESET_LOSSLESS_DEFAULT:
*guid = NV_ENC_PRESET_LOSSLESS_DEFAULT_GUID;
break;
case GST_NV_ENCODER_PRESET_LOSSLESS_HP:
*guid = NV_ENC_PRESET_LOSSLESS_HP_GUID;
break;
default:
break;
}
*guid = NV_ENC_PRESET_DEFAULT_GUID;
}
/**
* GstNvEncoderRCMode:
*
@ -2135,9 +2115,12 @@ gst_nv_encoder_rc_mode_get_type (void)
{GST_NV_ENCODER_RC_MODE_VBR, "Variable Bit Rate", "vbr"},
{GST_NV_ENCODER_RC_MODE_CBR, "Constant Bit Rate", "cbr"},
{GST_NV_ENCODER_RC_MODE_CBR_LOWDELAY_HQ,
"Low-Delay CBR, High Quality", "cbr-ld-hq"},
{GST_NV_ENCODER_RC_MODE_CBR_HQ, "CBR, High Quality (slower)", "cbr-hq"},
{GST_NV_ENCODER_RC_MODE_VBR_HQ, "VBR, High Quality (slower)", "vbr-hq"},
"Low-Delay CBR, High Quality "
"(deprecated, use cbr with tune and multipass)", "cbr-ld-hq"},
{GST_NV_ENCODER_RC_MODE_CBR_HQ, "CBR, High Quality "
"(deprecated, use cbr with tune and multipass)", "cbr-hq"},
{GST_NV_ENCODER_RC_MODE_VBR_HQ, "VBR, High Quality "
"(deprecated, use vbr with tune and multipass)", "vbr-hq"},
{0, NULL, NULL},
};
@ -2150,27 +2133,148 @@ gst_nv_encoder_rc_mode_get_type (void)
return rc_mode_type;
}
NV_ENC_PARAMS_RC_MODE
gst_nv_encoder_rc_mode_to_native (GstNvEncoderRCMode rc_mode)
void
gst_nv_encoder_preset_to_native (GstNvEncoderPreset preset,
GstNvEncoderTune tune, GUID * preset_guid, NV_ENC_TUNING_INFO * tune_info)
{
switch (rc_mode) {
case GST_NV_ENCODER_RC_MODE_CONSTQP:
return NV_ENC_PARAMS_RC_CONSTQP;
case GST_NV_ENCODER_RC_MODE_VBR:
return NV_ENC_PARAMS_RC_VBR;
case GST_NV_ENCODER_RC_MODE_CBR:
return NV_ENC_PARAMS_RC_CBR;
case GST_NV_ENCODER_RC_MODE_CBR_LOWDELAY_HQ:
return NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ;
case GST_NV_ENCODER_RC_MODE_CBR_HQ:
return NV_ENC_PARAMS_RC_CBR_HQ;
case GST_NV_ENCODER_RC_MODE_VBR_HQ:
return NV_ENC_PARAMS_RC_VBR_HQ;
gboolean is_low_latency = FALSE;
gboolean is_lossless = FALSE;
switch (preset) {
case GST_NV_ENCODER_PRESET_DEFAULT:
*preset_guid = NV_ENC_PRESET_P4_GUID;
break;
case GST_NV_ENCODER_PRESET_HP:
*preset_guid = NV_ENC_PRESET_P1_GUID;
break;
case GST_NV_ENCODER_PRESET_HQ:
*preset_guid = NV_ENC_PRESET_P7_GUID;
break;
case GST_NV_ENCODER_PRESET_LOW_LATENCY_DEFAULT:
is_low_latency = TRUE;
*preset_guid = NV_ENC_PRESET_P4_GUID;
break;
case GST_NV_ENCODER_PRESET_LOW_LATENCY_HQ:
is_low_latency = TRUE;
*preset_guid = NV_ENC_PRESET_P7_GUID;
break;
case GST_NV_ENCODER_PRESET_LOW_LATENCY_HP:
is_low_latency = TRUE;
*preset_guid = NV_ENC_PRESET_P1_GUID;
break;
case GST_NV_ENCODER_PRESET_LOSSLESS_DEFAULT:
is_lossless = TRUE;
*preset_guid = NV_ENC_PRESET_P4_GUID;
break;
case GST_NV_ENCODER_PRESET_LOSSLESS_HP:
is_lossless = TRUE;
*preset_guid = NV_ENC_PRESET_P1_GUID;
break;
case GST_NV_ENCODER_PRESET_P1:
*preset_guid = NV_ENC_PRESET_P1_GUID;
break;
case GST_NV_ENCODER_PRESET_P2:
*preset_guid = NV_ENC_PRESET_P2_GUID;
break;
case GST_NV_ENCODER_PRESET_P3:
*preset_guid = NV_ENC_PRESET_P3_GUID;
break;
case GST_NV_ENCODER_PRESET_P4:
*preset_guid = NV_ENC_PRESET_P4_GUID;
break;
case GST_NV_ENCODER_PRESET_P5:
*preset_guid = NV_ENC_PRESET_P5_GUID;
break;
case GST_NV_ENCODER_PRESET_P6:
*preset_guid = NV_ENC_PRESET_P6_GUID;
break;
case GST_NV_ENCODER_PRESET_P7:
*preset_guid = NV_ENC_PRESET_P7_GUID;
break;
default:
*preset_guid = NV_ENC_PRESET_P4_GUID;
break;
}
return NV_ENC_PARAMS_RC_VBR;
switch (tune) {
case GST_NV_ENCODER_TUNE_DEFAULT:
if (is_low_latency)
*tune_info = NV_ENC_TUNING_INFO_LOW_LATENCY;
else if (is_lossless)
*tune_info = NV_ENC_TUNING_INFO_LOSSLESS;
else
*tune_info = NV_ENC_TUNING_INFO_HIGH_QUALITY;
break;
case GST_NV_ENCODER_TUNE_HIGH_QUALITY:
*tune_info = NV_ENC_TUNING_INFO_HIGH_QUALITY;
break;
case GST_NV_ENCODER_TUNE_LOW_LATENCY:
*tune_info = NV_ENC_TUNING_INFO_LOW_LATENCY;
break;
case GST_NV_ENCODER_TUNE_ULTRA_LOW_LATENCY:
*tune_info = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY;
break;
case GST_NV_ENCODER_TUNE_LOSSLESS:
*tune_info = NV_ENC_TUNING_INFO_LOSSLESS;
break;
default:
*tune_info = NV_ENC_TUNING_INFO_HIGH_QUALITY;
break;
}
}
void
gst_nv_encoder_rc_mode_to_native (GstNvEncoderRCMode rc_mode,
GstNvEncoderMultiPass multipass, NV_ENC_PARAMS_RC_MODE * rc_mode_native,
NV_ENC_MULTI_PASS * multipass_native)
{
gboolean is_hq = FALSE;
switch (rc_mode) {
case GST_NV_ENCODER_RC_MODE_CONSTQP:
*rc_mode_native = NV_ENC_PARAMS_RC_CONSTQP;
break;
case GST_NV_ENCODER_RC_MODE_VBR:
*rc_mode_native = NV_ENC_PARAMS_RC_VBR;
break;
case GST_NV_ENCODER_RC_MODE_CBR:
*rc_mode_native = NV_ENC_PARAMS_RC_CBR;
break;
case GST_NV_ENCODER_RC_MODE_CBR_LOWDELAY_HQ:
is_hq = TRUE;
*rc_mode_native = NV_ENC_PARAMS_RC_CBR;
break;
case GST_NV_ENCODER_RC_MODE_CBR_HQ:
is_hq = TRUE;
*rc_mode_native = NV_ENC_PARAMS_RC_CBR;
break;
case GST_NV_ENCODER_RC_MODE_VBR_HQ:
is_hq = TRUE;
*rc_mode_native = NV_ENC_PARAMS_RC_VBR;
break;
default:
*rc_mode_native = NV_ENC_PARAMS_RC_VBR;
break;
}
switch (multipass) {
case GST_NV_ENCODER_MULTI_PASS_DEFAULT:
if (is_hq)
*multipass_native = NV_ENC_TWO_PASS_QUARTER_RESOLUTION;
else
*multipass_native = NV_ENC_MULTI_PASS_DISABLED;
break;
case GST_NV_ENCODER_MULTI_PASS_DISABLED:
*multipass_native = NV_ENC_MULTI_PASS_DISABLED;
break;
case GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION:
*multipass_native = NV_ENC_TWO_PASS_QUARTER_RESOLUTION;
break;
case GST_NV_ENCODER_TWO_PASS_FULL_RESOLUTION:
*multipass_native = NV_ENC_TWO_PASS_FULL_RESOLUTION;
break;
default:
*multipass_native = NV_ENC_MULTI_PASS_DISABLED;
break;
}
}
/**
@ -2215,6 +2319,113 @@ gst_nv_encoder_sei_insert_mode_get_type (void)
return type;
}
/**
* GstNvEncoderMultiPass:
*
* Since: 1.24
*/
GType
gst_nv_encoder_multi_pass_get_type (void)
{
static GType type = 0;
static const GEnumValue modes[] = {
/**
* GstNvEncoderMultiPass::disabled:
*
* Since: 1.24
*/
{GST_NV_ENCODER_MULTI_PASS_DEFAULT,
"Disable multi-pass when cqp, vbr or cbr is used. "
"Otherwise encoder will select it based on rc-mode", "default"},
/**
* GstNvEncoderMultiPass::disabled:
*
* Since: 1.24
*/
{GST_NV_ENCODER_MULTI_PASS_DISABLED, "Disabled", "disabled"},
/**
* GstNvEncoderMultiPass::two-pass-quarter:
*
* Since: 1.24
*/
{GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION,
"Two pass with quarter resolution encoding in first pass",
"two-pass-quarter"},
/**
* GstNvEncoderMultiPass::two-pass:
*
* Since: 1.24
*/
{GST_NV_ENCODER_TWO_PASS_FULL_RESOLUTION, "Two pass", "two-pass"},
{0, nullptr, nullptr}
};
GST_CUDA_CALL_ONCE_BEGIN {
type = g_enum_register_static ("GstNvEncoderMultiPass", modes);
} GST_CUDA_CALL_ONCE_END;
return type;
}
/**
* GstNvEncoderTune:
*
* Since: 1.24
*/
GType
gst_nv_encoder_tune_get_type (void)
{
static GType type = 0;
static const GEnumValue modes[] = {
/**
* GstNvEncoderTune::default:
*
* Since: 1.24
*/
{GST_NV_ENCODER_TUNE_DEFAULT, "High quality when p1~7 preset is used. "
"Otherwise encoder will select it based on preset", "default"},
/**
* GstNvEncoderTune::high-quality:
*
* Since: 1.24
*/
{GST_NV_ENCODER_TUNE_HIGH_QUALITY, "High quality", "high-quality"},
/**
* GstNvEncoderMultiPass::low-latency:
*
* Since: 1.24
*/
{GST_NV_ENCODER_TUNE_LOW_LATENCY, "Low latency", "low-latency"},
/**
* GstNvEncoderMultiPass::ultra-low-latency:
*
* Since: 1.24
*/
{GST_NV_ENCODER_TUNE_ULTRA_LOW_LATENCY, "Ultra low latency",
"ultra-low-latency"},
/**
* GstNvEncoderMultiPass::lossless:
*
* Since: 1.24
*/
{GST_NV_ENCODER_TUNE_LOSSLESS, "Lossless", "lossless"},
{0, nullptr, nullptr}
};
GST_CUDA_CALL_ONCE_BEGIN {
type = g_enum_register_static ("GstNvEncoderTune", modes);
} GST_CUDA_CALL_ONCE_END;
return type;
}
GstNvEncoderClassData *
gst_nv_encoder_class_data_new (void)
{

View file

@ -69,6 +69,13 @@ typedef enum
GST_NV_ENCODER_PRESET_LOW_LATENCY_HP,
GST_NV_ENCODER_PRESET_LOSSLESS_DEFAULT,
GST_NV_ENCODER_PRESET_LOSSLESS_HP,
GST_NV_ENCODER_PRESET_P1,
GST_NV_ENCODER_PRESET_P2,
GST_NV_ENCODER_PRESET_P3,
GST_NV_ENCODER_PRESET_P4,
GST_NV_ENCODER_PRESET_P5,
GST_NV_ENCODER_PRESET_P6,
GST_NV_ENCODER_PRESET_P7,
} GstNvEncoderPreset;
#define GST_TYPE_NV_ENCODER_RC_MODE (gst_nv_encoder_rc_mode_get_type())
@ -94,6 +101,27 @@ typedef enum
GST_NV_ENCODER_SEI_DISABLED,
} GstNvEncoderSeiInsertMode;
#define GST_TYPE_NV_ENCODER_MULTI_PASS (gst_nv_encoder_multi_pass_get_type ())
GType gst_nv_encoder_multi_pass_get_type (void);
typedef enum
{
GST_NV_ENCODER_MULTI_PASS_DEFAULT = 0,
GST_NV_ENCODER_MULTI_PASS_DISABLED = 1,
GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION = 2,
GST_NV_ENCODER_TWO_PASS_FULL_RESOLUTION = 3,
} GstNvEncoderMultiPass;
#define GST_TYPE_NV_ENCODER_TUNE (gst_nv_encoder_tune_get_type ())
GType gst_nv_encoder_tune_get_type (void);
typedef enum
{
GST_NV_ENCODER_TUNE_DEFAULT = 0,
GST_NV_ENCODER_TUNE_HIGH_QUALITY = 1,
GST_NV_ENCODER_TUNE_LOW_LATENCY = 2,
GST_NV_ENCODER_TUNE_ULTRA_LOW_LATENCY = 3,
GST_NV_ENCODER_TUNE_LOSSLESS = 4,
} GstNvEncoderTune;
typedef struct
{
gint max_bframes;
@ -221,10 +249,16 @@ struct _GstNvEncoderClass
GType gst_nv_encoder_get_type (void);
void gst_nv_encoder_preset_to_guid (GstNvEncoderPreset preset,
GUID * guid);
void gst_nv_encoder_preset_to_native (GstNvEncoderPreset preset,
GstNvEncoderTune tune,
GUID * preset_guid,
NV_ENC_TUNING_INFO * tune_info);
void gst_nv_encoder_rc_mode_to_native (GstNvEncoderRCMode rc_mode,
GstNvEncoderMultiPass multipass,
NV_ENC_PARAMS_RC_MODE * rc_mode_native,
NV_ENC_MULTI_PASS * multipass_native);
NV_ENC_PARAMS_RC_MODE gst_nv_encoder_rc_mode_to_native (GstNvEncoderRCMode rc_mode);
void gst_nv_encoder_set_device_mode (GstNvEncoder * encoder,
GstNvEncoderDeviceMode mode,

View file

@ -66,6 +66,8 @@ enum
/* init params */
PROP_PRESET,
PROP_TUNE,
PROP_MULTI_PASS,
PROP_WEIGHTED_PRED,
/* encoding config */
@ -109,7 +111,9 @@ enum
PROP_REPEAT_SEQUENCE_HEADER,
};
#define DEFAULT_PRESET GST_NV_ENCODER_PRESET_DEFAULT
#define DEFAULT_PRESET GST_NV_ENCODER_PRESET_P4
#define DEFAULT_TUNE GST_NV_ENCODER_TUNE_DEFAULT
#define DEFAULT_MULTI_PASS GST_NV_ENCODER_MULTI_PASS_DEFAULT
#define DEFAULT_WEIGHTED_PRED FALSE
#define DEFAULT_GOP_SIZE 30
#define DEFAULT_B_FRAMES 0
@ -152,6 +156,8 @@ typedef struct _GstNvH264Encoder
gint64 adapter_luid;
GstNvEncoderPreset preset;
GstNvEncoderMultiPass multipass;
GstNvEncoderTune tune;
gboolean weighted_pred;
gint gop_size;
@ -298,6 +304,14 @@ gst_nv_h264_encoder_class_init (GstNvH264EncoderClass * klass, gpointer data)
g_param_spec_enum ("preset", "Encoding Preset",
"Encoding Preset", GST_TYPE_NV_ENCODER_PRESET,
DEFAULT_PRESET, param_flags));
g_object_class_install_property (object_class, PROP_TUNE,
g_param_spec_enum ("tune", "Tune",
"Encoding tune", GST_TYPE_NV_ENCODER_TUNE,
DEFAULT_TUNE, param_flags));
g_object_class_install_property (object_class, PROP_MULTI_PASS,
g_param_spec_enum ("multi-pass", "Multi Pass",
"Multi pass encoding", GST_TYPE_NV_ENCODER_MULTI_PASS,
DEFAULT_MULTI_PASS, param_flags));
if (dev_caps->weighted_prediction) {
g_object_class_install_property (object_class, PROP_WEIGHTED_PRED,
g_param_spec_boolean ("weighted-pred", "Weighted Pred",
@ -501,6 +515,8 @@ gst_nv_h264_encoder_init (GstNvH264Encoder * self)
self->cuda_device_id = klass->cuda_device_id;
self->adapter_luid = klass->adapter_luid;
self->preset = DEFAULT_PRESET;
self->tune = DEFAULT_TUNE;
self->multipass = DEFAULT_MULTI_PASS;
self->weighted_pred = DEFAULT_WEIGHTED_PRED;
self->gop_size = DEFAULT_GOP_SIZE;
self->bframes = DEFAULT_B_FRAMES;
@ -700,6 +716,23 @@ gst_nv_h264_encoder_set_property (GObject * object, guint prop_id,
}
break;
}
case PROP_TUNE:{
GstNvEncoderTune tune = (GstNvEncoderTune) g_value_get_enum (value);
if (tune != self->tune) {
self->tune = tune;
self->init_param_updated = TRUE;
}
break;
}
case PROP_MULTI_PASS:{
GstNvEncoderMultiPass multipass =
(GstNvEncoderMultiPass) g_value_get_enum (value);
if (multipass != self->multipass) {
self->multipass = multipass;
self->init_param_updated = TRUE;
}
break;
}
case PROP_WEIGHTED_PRED:
update_boolean (self, &self->weighted_pred, value, UPDATE_INIT_PARAM);
break;
@ -818,6 +851,12 @@ gst_nv_h264_encoder_get_property (GObject * object, guint prop_id,
case PROP_PRESET:
g_value_set_enum (value, self->preset);
break;
case PROP_TUNE:
g_value_set_enum (value, self->tune);
break;
case PROP_MULTI_PASS:
g_value_set_enum (value, self->multipass);
break;
case PROP_WEIGHTED_PRED:
g_value_set_boolean (value, self->weighted_pred);
break;
@ -1074,7 +1113,6 @@ gst_nv_h264_encoder_set_format (GstNvEncoder * encoder,
NVENCSTATUS status;
NV_ENC_PRESET_CONFIG preset_config = { 0, };
gint dar_n, dar_d;
GstNvEncoderRCMode rc_mode;
NV_ENC_CONFIG_H264 *h264_config;
NV_ENC_CONFIG_H264_VUI_PARAMETERS *vui;
std::set < std::string > downstream_profiles;
@ -1216,13 +1254,14 @@ gst_nv_h264_encoder_set_format (GstNvEncoder * encoder,
}
}
gst_nv_encoder_preset_to_guid (self->preset, &init_params->presetGUID);
gst_nv_encoder_preset_to_native (self->preset, self->tune,
&init_params->presetGUID, &init_params->tuningInfo);
preset_config.version = gst_nvenc_get_preset_config_version ();
preset_config.presetCfg.version = gst_nvenc_get_config_version ();
status = NvEncGetEncodePresetConfig (session, NV_ENC_CODEC_H264_GUID,
init_params->presetGUID, &preset_config);
status = NvEncGetEncodePresetConfigEx (session, NV_ENC_CODEC_H264_GUID,
init_params->presetGUID, init_params->tuningInfo, &preset_config);
if (!gst_nv_enc_result (status, self)) {
GST_ERROR_OBJECT (self, "Failed to get preset config");
g_mutex_unlock (&self->prop_lock);
@ -1257,7 +1296,6 @@ gst_nv_h264_encoder_set_format (GstNvEncoder * encoder,
}
rc_params = &config->rcParams;
rc_mode = self->rc_mode;
if (self->bitrate)
rc_params->averageBitRate = self->bitrate * 1024;
@ -1296,7 +1334,10 @@ gst_nv_h264_encoder_set_format (GstNvEncoder * encoder,
}
}
if (rc_mode == GST_NV_ENCODER_RC_MODE_CONSTQP) {
gst_nv_encoder_rc_mode_to_native (self->rc_mode, self->multipass,
&rc_params->rateControlMode, &rc_params->multiPass);
if (rc_params->rateControlMode == NV_ENC_PARAMS_RC_CONSTQP) {
if (self->qp_i >= 0)
rc_params->constQP.qpIntra = self->qp_i;
if (self->qp_p >= 0)
@ -1305,8 +1346,6 @@ gst_nv_h264_encoder_set_format (GstNvEncoder * encoder,
rc_params->constQP.qpInterB = self->qp_b;
}
rc_params->rateControlMode = gst_nv_encoder_rc_mode_to_native (rc_mode);
if (self->spatial_aq) {
rc_params->enableAQ = TRUE;
rc_params->aqStrength = self->aq_strength;
@ -1885,6 +1924,17 @@ gst_nv_h264_encoder_create_class_data (GstObject * device, gpointer session,
GstNvEncoderClassData *cdata;
GstCaps *sink_caps;
GstCaps *system_caps;
NV_ENC_PRESET_CONFIG preset_config = { 0, };
preset_config.version = gst_nvenc_get_preset_config_version ();
preset_config.presetCfg.version = gst_nvenc_get_config_version ();
status = NvEncGetEncodePresetConfigEx (session, NV_ENC_CODEC_H264_GUID,
NV_ENC_PRESET_P4_GUID, NV_ENC_TUNING_INFO_HIGH_QUALITY, &preset_config);
if (status != NV_ENC_SUCCESS) {
GST_WARNING_OBJECT (device, "New preset is not supported");
return nullptr;
}
status = NvEncGetEncodeProfileGUIDs (session, NV_ENC_CODEC_H264_GUID,
profile_guids, G_N_ELEMENTS (profile_guids), &profile_guid_count);

View file

@ -66,6 +66,8 @@ enum
/* init params */
PROP_PRESET,
PROP_TUNE,
PROP_MULTI_PASS,
PROP_WEIGHTED_PRED,
/* encoding config */
@ -108,7 +110,9 @@ enum
PROP_REPEAT_SEQUENCE_HEADER,
};
#define DEFAULT_PRESET GST_NV_ENCODER_PRESET_DEFAULT
#define DEFAULT_PRESET GST_NV_ENCODER_PRESET_P4
#define DEFAULT_TUNE GST_NV_ENCODER_TUNE_DEFAULT
#define DEFAULT_MULTI_PASS GST_NV_ENCODER_MULTI_PASS_DEFAULT
#define DEFAULT_WEIGHTED_PRED FALSE
#define DEFAULT_GOP_SIZE 30
#define DEFAULT_B_FRAMES 0
@ -158,6 +162,8 @@ typedef struct _GstNvH265Encoder
gint64 adapter_luid;
GstNvEncoderPreset preset;
GstNvEncoderMultiPass multipass;
GstNvEncoderTune tune;
gboolean weighted_pred;
gint gop_size;
@ -303,6 +309,14 @@ gst_nv_h265_encoder_class_init (GstNvH265EncoderClass * klass, gpointer data)
g_param_spec_enum ("preset", "Encoding Preset",
"Encoding Preset", GST_TYPE_NV_ENCODER_PRESET,
DEFAULT_PRESET, param_flags));
g_object_class_install_property (object_class, PROP_TUNE,
g_param_spec_enum ("tune", "Tune",
"Encoding tune", GST_TYPE_NV_ENCODER_TUNE,
DEFAULT_TUNE, param_flags));
g_object_class_install_property (object_class, PROP_MULTI_PASS,
g_param_spec_enum ("multi-pass", "Multi Pass",
"Multi pass encoding", GST_TYPE_NV_ENCODER_MULTI_PASS,
DEFAULT_MULTI_PASS, param_flags));
if (dev_caps->weighted_prediction) {
g_object_class_install_property (object_class, PROP_WEIGHTED_PRED,
g_param_spec_boolean ("weighted-pred", "Weighted Pred",
@ -502,6 +516,8 @@ gst_nv_h265_encoder_init (GstNvH265Encoder * self)
self->cuda_device_id = klass->cuda_device_id;
self->adapter_luid = klass->adapter_luid;
self->preset = DEFAULT_PRESET;
self->tune = DEFAULT_TUNE;
self->multipass = DEFAULT_MULTI_PASS;
self->weighted_pred = DEFAULT_WEIGHTED_PRED;
self->gop_size = DEFAULT_GOP_SIZE;
self->bframes = DEFAULT_B_FRAMES;
@ -699,6 +715,23 @@ gst_nv_h265_encoder_set_property (GObject * object, guint prop_id,
}
break;
}
case PROP_TUNE:{
GstNvEncoderTune tune = (GstNvEncoderTune) g_value_get_enum (value);
if (tune != self->tune) {
self->tune = tune;
self->init_param_updated = TRUE;
}
break;
}
case PROP_MULTI_PASS:{
GstNvEncoderMultiPass multipass =
(GstNvEncoderMultiPass) g_value_get_enum (value);
if (multipass != self->multipass) {
self->multipass = multipass;
self->init_param_updated = TRUE;
}
break;
}
case PROP_WEIGHTED_PRED:
update_boolean (self, &self->weighted_pred, value, UPDATE_INIT_PARAM);
break;
@ -814,6 +847,12 @@ gst_nv_h265_encoder_get_property (GObject * object, guint prop_id,
case PROP_PRESET:
g_value_set_enum (value, self->preset);
break;
case PROP_TUNE:
g_value_set_enum (value, self->tune);
break;
case PROP_MULTI_PASS:
g_value_set_enum (value, self->multipass);
break;
case PROP_WEIGHTED_PRED:
g_value_set_boolean (value, self->weighted_pred);
break;
@ -1055,7 +1094,6 @@ gst_nv_h265_encoder_set_format (GstNvEncoder * encoder,
NVENCSTATUS status;
NV_ENC_PRESET_CONFIG preset_config = { 0, };
gint dar_n, dar_d;
GstNvEncoderRCMode rc_mode;
NV_ENC_CONFIG_HEVC *hevc_config;
NV_ENC_CONFIG_HEVC_VUI_PARAMETERS *vui;
std::set < std::string > downstream_profiles;
@ -1203,13 +1241,14 @@ gst_nv_h265_encoder_set_format (GstNvEncoder * encoder,
init_params->darHeight = dar_d;
}
gst_nv_encoder_preset_to_guid (self->preset, &init_params->presetGUID);
gst_nv_encoder_preset_to_native (self->preset, self->tune,
&init_params->presetGUID, &init_params->tuningInfo);
preset_config.version = gst_nvenc_get_preset_config_version ();
preset_config.presetCfg.version = gst_nvenc_get_config_version ();
status = NvEncGetEncodePresetConfig (session, NV_ENC_CODEC_HEVC_GUID,
init_params->presetGUID, &preset_config);
status = NvEncGetEncodePresetConfigEx (session, NV_ENC_CODEC_HEVC_GUID,
init_params->presetGUID, init_params->tuningInfo, &preset_config);
if (!gst_nv_enc_result (status, self)) {
GST_ERROR_OBJECT (self, "Failed to get preset config");
g_mutex_unlock (&self->prop_lock);
@ -1236,7 +1275,6 @@ gst_nv_h265_encoder_set_format (GstNvEncoder * encoder,
}
rc_params = &config->rcParams;
rc_mode = self->rc_mode;
if (self->bitrate)
rc_params->averageBitRate = self->bitrate * 1024;
@ -1275,7 +1313,10 @@ gst_nv_h265_encoder_set_format (GstNvEncoder * encoder,
}
}
if (rc_mode == GST_NV_ENCODER_RC_MODE_CONSTQP) {
gst_nv_encoder_rc_mode_to_native (self->rc_mode, self->multipass,
&rc_params->rateControlMode, &rc_params->multiPass);
if (rc_params->rateControlMode == NV_ENC_PARAMS_RC_CONSTQP) {
if (self->qp_i >= 0)
rc_params->constQP.qpIntra = self->qp_i;
if (self->qp_p >= 0)
@ -1284,8 +1325,6 @@ gst_nv_h265_encoder_set_format (GstNvEncoder * encoder,
rc_params->constQP.qpInterB = self->qp_b;
}
rc_params->rateControlMode = gst_nv_encoder_rc_mode_to_native (rc_mode);
if (self->spatial_aq) {
rc_params->enableAQ = TRUE;
rc_params->aqStrength = self->aq_strength;
@ -1919,6 +1958,17 @@ gst_nv_h265_encoder_create_class_data (GstObject * device, gpointer session,
GstNvEncoderClassData *cdata;
GstCaps *sink_caps;
GstCaps *system_caps;
NV_ENC_PRESET_CONFIG preset_config = { 0, };
preset_config.version = gst_nvenc_get_preset_config_version ();
preset_config.presetCfg.version = gst_nvenc_get_config_version ();
status = NvEncGetEncodePresetConfigEx (session, NV_ENC_CODEC_HEVC_GUID,
NV_ENC_PRESET_P4_GUID, NV_ENC_TUNING_INFO_HIGH_QUALITY, &preset_config);
if (status != NV_ENC_SUCCESS) {
GST_WARNING_OBJECT (device, "New preset is not supported");
return nullptr;
}
status = NvEncGetEncodeProfileGUIDs (session, NV_ENC_CODEC_HEVC_GUID,
profile_guids, G_N_ELEMENTS (profile_guids), &profile_guid_count);