nvencoder: Enhance lagacy encoding profile mapping

Updated based on the NVENC Preset Migration Guide

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6754>
This commit is contained in:
Seungha Yang 2024-05-12 21:56:23 +09:00 committed by GStreamer Marge Bot
parent cfd92819d9
commit ff6d6e1b3c
4 changed files with 488 additions and 115 deletions

View file

@ -2229,149 +2229,474 @@ gst_nv_encoder_rc_mode_get_type (void)
return rc_mode_type;
}
void
gst_nv_encoder_preset_to_native (GstNvEncoderPreset preset,
GstNvEncoderTune tune, GUID * preset_guid, NV_ENC_TUNING_INFO * tune_info)
static void
gst_nv_encoder_update_preset_to_native (const GstNvEncoderPresetOptions * input,
GstNvEncoderPresetOptionsNative * output)
{
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;
GstNvEncoderPresetOptions updated = *input;
switch (updated.preset) {
case GST_NV_ENCODER_PRESET_P1:
*preset_guid = NV_ENC_PRESET_P1_GUID;
output->preset = NV_ENC_PRESET_P1_GUID;
break;
case GST_NV_ENCODER_PRESET_P2:
*preset_guid = NV_ENC_PRESET_P2_GUID;
output->preset = NV_ENC_PRESET_P2_GUID;
break;
case GST_NV_ENCODER_PRESET_P3:
*preset_guid = NV_ENC_PRESET_P3_GUID;
output->preset = NV_ENC_PRESET_P3_GUID;
break;
case GST_NV_ENCODER_PRESET_P4:
*preset_guid = NV_ENC_PRESET_P4_GUID;
output->preset = NV_ENC_PRESET_P4_GUID;
break;
case GST_NV_ENCODER_PRESET_P5:
*preset_guid = NV_ENC_PRESET_P5_GUID;
output->preset = NV_ENC_PRESET_P5_GUID;
break;
case GST_NV_ENCODER_PRESET_P6:
*preset_guid = NV_ENC_PRESET_P6_GUID;
output->preset = NV_ENC_PRESET_P6_GUID;
break;
case GST_NV_ENCODER_PRESET_P7:
*preset_guid = NV_ENC_PRESET_P7_GUID;
output->preset = NV_ENC_PRESET_P7_GUID;
break;
default:
*preset_guid = NV_ENC_PRESET_P4_GUID;
GST_WARNING ("Unexpected preset %d", input->preset);
output->preset = NV_ENC_PRESET_P4_GUID;
break;
}
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;
switch (updated.rc_mode) {
case GST_NV_ENCODER_RC_MODE_DEFAULT:
case GST_NV_ENCODER_RC_MODE_VBR:
case GST_NV_ENCODER_RC_MODE_VBR_MINQP:
case GST_NV_ENCODER_RC_MODE_VBR_HQ:
output->rc_mode = NV_ENC_PARAMS_RC_VBR;
break;
case GST_NV_ENCODER_TUNE_HIGH_QUALITY:
*tune_info = NV_ENC_TUNING_INFO_HIGH_QUALITY;
case GST_NV_ENCODER_RC_MODE_CBR:
case GST_NV_ENCODER_RC_MODE_CBR_HQ:
output->rc_mode = NV_ENC_PARAMS_RC_CBR;
break;
case GST_NV_ENCODER_TUNE_LOW_LATENCY:
*tune_info = NV_ENC_TUNING_INFO_LOW_LATENCY;
case GST_NV_ENCODER_RC_MODE_CBR_LOWDELAY_HQ:
output->rc_mode = NV_ENC_PARAMS_RC_CBR;
if (updated.tune == GST_NV_ENCODER_TUNE_DEFAULT)
updated.tune = GST_NV_ENCODER_TUNE_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;
case GST_NV_ENCODER_RC_MODE_CONSTQP:
output->rc_mode = NV_ENC_PARAMS_RC_CONSTQP;
break;
default:
*tune_info = NV_ENC_TUNING_INFO_HIGH_QUALITY;
output->rc_mode = NV_ENC_PARAMS_RC_VBR;
break;
}
output->tune = NV_ENC_TUNING_INFO_UNDEFINED;
switch (updated.tune) {
case GST_NV_ENCODER_TUNE_DEFAULT:
case GST_NV_ENCODER_TUNE_HIGH_QUALITY:
output->tune = NV_ENC_TUNING_INFO_HIGH_QUALITY;
break;
case GST_NV_ENCODER_TUNE_LOW_LATENCY:
output->tune = NV_ENC_TUNING_INFO_LOW_LATENCY;
break;
case GST_NV_ENCODER_TUNE_ULTRA_LOW_LATENCY:
output->tune = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY;
break;
case GST_NV_ENCODER_TUNE_LOSSLESS:
output->tune = NV_ENC_TUNING_INFO_LOSSLESS;
break;
}
if (output->tune == NV_ENC_TUNING_INFO_UNDEFINED) {
GST_WARNING ("Unexpected input tune %d", updated.tune);
output->tune = NV_ENC_TUNING_INFO_HIGH_QUALITY;
}
switch (updated.multi_pass) {
case GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION:
output->multi_pass = NV_ENC_TWO_PASS_QUARTER_RESOLUTION;
break;
case GST_NV_ENCODER_TWO_PASS_FULL_RESOLUTION:
output->multi_pass = NV_ENC_TWO_PASS_FULL_RESOLUTION;
break;
case GST_NV_ENCODER_MULTI_PASS_DEFAULT:
case GST_NV_ENCODER_MULTI_PASS_DISABLED:
default:
output->multi_pass = NV_ENC_MULTI_PASS_DISABLED;
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)
gst_nv_encoder_preset_to_native_h264 (GstNvEncoderPresetResolution resolution,
const GstNvEncoderPresetOptions * input,
GstNvEncoderPresetOptionsNative * output)
{
gboolean is_hq = FALSE;
switch (rc_mode) {
case GST_NV_ENCODER_RC_MODE_CONSTQP:
*rc_mode_native = NV_ENC_PARAMS_RC_CONSTQP;
GstNvEncoderPresetOptions result = *input;
/* Converts legacy preset to new preset */
switch (input->preset) {
case GST_NV_ENCODER_PRESET_HP:
result.preset = GST_NV_ENCODER_PRESET_P2;
result.tune = GST_NV_ENCODER_TUNE_HIGH_QUALITY;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_VBR_HQ:
result.rc_mode = GST_NV_ENCODER_RC_MODE_VBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
case GST_NV_ENCODER_RC_MODE_DEFAULT:
case GST_NV_ENCODER_RC_MODE_VBR:
case GST_NV_ENCODER_RC_MODE_VBR_MINQP:
result.rc_mode = GST_NV_ENCODER_RC_MODE_VBR;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
break;
default:
break;
}
break;
case GST_NV_ENCODER_RC_MODE_VBR:
case GST_NV_ENCODER_RC_MODE_VBR_MINQP:
*rc_mode_native = NV_ENC_PARAMS_RC_VBR;
case GST_NV_ENCODER_PRESET_DEFAULT:
result.preset = GST_NV_ENCODER_PRESET_P3;
result.tune = GST_NV_ENCODER_TUNE_HIGH_QUALITY;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_VBR_HQ:
result.rc_mode = GST_NV_ENCODER_RC_MODE_VBR;
if (resolution >= GST_NV_ENCODER_PRESET_2160)
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
else
result.multi_pass = GST_NV_ENCODER_TWO_PASS_FULL_RESOLUTION;
break;
case GST_NV_ENCODER_RC_MODE_DEFAULT:
case GST_NV_ENCODER_RC_MODE_VBR:
case GST_NV_ENCODER_RC_MODE_VBR_MINQP:
result.rc_mode = GST_NV_ENCODER_RC_MODE_VBR;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
break;
default:
break;
}
break;
case GST_NV_ENCODER_RC_MODE_CBR:
*rc_mode_native = NV_ENC_PARAMS_RC_CBR;
case GST_NV_ENCODER_PRESET_HQ:
result.preset = GST_NV_ENCODER_PRESET_P4;
result.tune = GST_NV_ENCODER_TUNE_HIGH_QUALITY;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_VBR_HQ:
result.rc_mode = GST_NV_ENCODER_RC_MODE_VBR;
if (resolution == GST_NV_ENCODER_PRESET_720) {
result.multi_pass = GST_NV_ENCODER_TWO_PASS_FULL_RESOLUTION;
} else if (resolution == GST_NV_ENCODER_PRESET_1080) {
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
} else {
result.preset = GST_NV_ENCODER_PRESET_P5;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
}
break;
case GST_NV_ENCODER_RC_MODE_DEFAULT:
case GST_NV_ENCODER_RC_MODE_VBR:
case GST_NV_ENCODER_RC_MODE_VBR_MINQP:
result.rc_mode = GST_NV_ENCODER_RC_MODE_VBR;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
break;
default:
break;
}
break;
case GST_NV_ENCODER_RC_MODE_CBR_LOWDELAY_HQ:
is_hq = TRUE;
*rc_mode_native = NV_ENC_PARAMS_RC_CBR;
case GST_NV_ENCODER_PRESET_LOW_LATENCY_HP:
result.preset = GST_NV_ENCODER_PRESET_P2;
result.tune = GST_NV_ENCODER_TUNE_LOW_LATENCY;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_DEFAULT:
case GST_NV_ENCODER_RC_MODE_CBR:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
break;
case GST_NV_ENCODER_RC_MODE_CBR_HQ:
result.tune = GST_NV_ENCODER_TUNE_ULTRA_LOW_LATENCY;
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
case GST_NV_ENCODER_RC_MODE_CBR_LOWDELAY_HQ:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
default:
break;
}
break;
case GST_NV_ENCODER_RC_MODE_CBR_HQ:
is_hq = TRUE;
*rc_mode_native = NV_ENC_PARAMS_RC_CBR;
case GST_NV_ENCODER_PRESET_LOW_LATENCY_DEFAULT:
switch (resolution) {
case GST_NV_ENCODER_PRESET_720:
result.preset = GST_NV_ENCODER_PRESET_P4;
break;
case GST_NV_ENCODER_PRESET_1080:
result.preset = GST_NV_ENCODER_PRESET_P3;
break;
case GST_NV_ENCODER_PRESET_2160:
default:
result.preset = GST_NV_ENCODER_PRESET_P2;
break;
}
result.tune = GST_NV_ENCODER_TUNE_LOW_LATENCY;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_DEFAULT:
case GST_NV_ENCODER_RC_MODE_CBR:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
break;
case GST_NV_ENCODER_RC_MODE_CBR_HQ:
result.tune = GST_NV_ENCODER_TUNE_ULTRA_LOW_LATENCY;
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_FULL_RESOLUTION;
if (resolution >= GST_NV_ENCODER_PRESET_2160)
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
case GST_NV_ENCODER_RC_MODE_CBR_LOWDELAY_HQ:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_FULL_RESOLUTION;
if (resolution >= GST_NV_ENCODER_PRESET_2160)
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
default:
break;
}
break;
case GST_NV_ENCODER_RC_MODE_VBR_HQ:
is_hq = TRUE;
*rc_mode_native = NV_ENC_PARAMS_RC_VBR;
case GST_NV_ENCODER_PRESET_LOW_LATENCY_HQ:
result.preset = GST_NV_ENCODER_PRESET_P4;
result.tune = GST_NV_ENCODER_TUNE_LOW_LATENCY;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_DEFAULT:
case GST_NV_ENCODER_RC_MODE_CBR:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
break;
case GST_NV_ENCODER_RC_MODE_CBR_HQ:
result.tune = GST_NV_ENCODER_TUNE_ULTRA_LOW_LATENCY;
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_FULL_RESOLUTION;
if (resolution >= GST_NV_ENCODER_PRESET_2160)
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
case GST_NV_ENCODER_RC_MODE_CBR_LOWDELAY_HQ:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_FULL_RESOLUTION;
if (resolution >= GST_NV_ENCODER_PRESET_2160)
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
default:
break;
}
break;
case GST_NV_ENCODER_PRESET_LOSSLESS_HP:
result.preset = GST_NV_ENCODER_PRESET_P2;
result.tune = GST_NV_ENCODER_TUNE_LOSSLESS;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_DEFAULT:
case GST_NV_ENCODER_RC_MODE_CONSTQP:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CONSTQP;
break;
default:
break;
}
break;
case GST_NV_ENCODER_PRESET_LOSSLESS_DEFAULT:
result.preset = GST_NV_ENCODER_PRESET_P3;
result.tune = GST_NV_ENCODER_TUNE_LOSSLESS;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_DEFAULT:
case GST_NV_ENCODER_RC_MODE_CONSTQP:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CONSTQP;
break;
default:
break;
}
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;
gst_nv_encoder_update_preset_to_native (&result, output);
}
void
gst_nv_encoder_preset_to_native (GstNvEncoderPresetResolution resolution,
const GstNvEncoderPresetOptions * input,
GstNvEncoderPresetOptionsNative * output)
{
GstNvEncoderPresetOptions result = *input;
/* Converts legacy preset to new preset */
switch (input->preset) {
case GST_NV_ENCODER_PRESET_HP:
result.preset = GST_NV_ENCODER_PRESET_P1;
result.tune = GST_NV_ENCODER_TUNE_HIGH_QUALITY;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_VBR_HQ:
result.rc_mode = GST_NV_ENCODER_RC_MODE_VBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
case GST_NV_ENCODER_RC_MODE_DEFAULT:
case GST_NV_ENCODER_RC_MODE_VBR:
case GST_NV_ENCODER_RC_MODE_VBR_MINQP:
result.rc_mode = GST_NV_ENCODER_RC_MODE_VBR;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
break;
default:
break;
}
break;
case GST_NV_ENCODER_MULTI_PASS_DISABLED:
*multipass_native = NV_ENC_MULTI_PASS_DISABLED;
case GST_NV_ENCODER_PRESET_DEFAULT:
result.preset = GST_NV_ENCODER_PRESET_P5;
result.tune = GST_NV_ENCODER_TUNE_HIGH_QUALITY;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_VBR_HQ:
result.rc_mode = GST_NV_ENCODER_RC_MODE_VBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
case GST_NV_ENCODER_RC_MODE_DEFAULT:
case GST_NV_ENCODER_RC_MODE_VBR:
case GST_NV_ENCODER_RC_MODE_VBR_MINQP:
result.rc_mode = GST_NV_ENCODER_RC_MODE_VBR;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
break;
default:
break;
}
break;
case GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION:
*multipass_native = NV_ENC_TWO_PASS_QUARTER_RESOLUTION;
case GST_NV_ENCODER_PRESET_HQ:
result.preset = GST_NV_ENCODER_PRESET_P6;
if (resolution >= GST_NV_ENCODER_PRESET_2160)
result.preset = GST_NV_ENCODER_PRESET_P5;
result.tune = GST_NV_ENCODER_TUNE_HIGH_QUALITY;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_VBR_HQ:
result.rc_mode = GST_NV_ENCODER_RC_MODE_VBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
case GST_NV_ENCODER_RC_MODE_DEFAULT:
case GST_NV_ENCODER_RC_MODE_VBR:
case GST_NV_ENCODER_RC_MODE_VBR_MINQP:
result.rc_mode = GST_NV_ENCODER_RC_MODE_VBR;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
break;
default:
break;
}
break;
case GST_NV_ENCODER_TWO_PASS_FULL_RESOLUTION:
*multipass_native = NV_ENC_TWO_PASS_FULL_RESOLUTION;
case GST_NV_ENCODER_PRESET_LOW_LATENCY_HP:
result.preset = GST_NV_ENCODER_PRESET_P2;
if (resolution >= GST_NV_ENCODER_PRESET_2160)
result.preset = GST_NV_ENCODER_PRESET_P1;
result.tune = GST_NV_ENCODER_TUNE_LOW_LATENCY;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_CBR:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
break;
case GST_NV_ENCODER_RC_MODE_CBR_HQ:
result.tune = GST_NV_ENCODER_TUNE_ULTRA_LOW_LATENCY;
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
case GST_NV_ENCODER_RC_MODE_CBR_LOWDELAY_HQ:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
default:
break;
}
break;
case GST_NV_ENCODER_PRESET_LOW_LATENCY_DEFAULT:
switch (resolution) {
case GST_NV_ENCODER_PRESET_720:
result.preset = GST_NV_ENCODER_PRESET_P4;
break;
case GST_NV_ENCODER_PRESET_1080:
result.preset = GST_NV_ENCODER_PRESET_P3;
break;
case GST_NV_ENCODER_PRESET_2160:
default:
result.preset = GST_NV_ENCODER_PRESET_P2;
break;
}
result.tune = GST_NV_ENCODER_TUNE_LOW_LATENCY;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_CBR:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
break;
case GST_NV_ENCODER_RC_MODE_CBR_HQ:
result.tune = GST_NV_ENCODER_TUNE_ULTRA_LOW_LATENCY;
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_FULL_RESOLUTION;
if (resolution >= GST_NV_ENCODER_PRESET_1080)
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
case GST_NV_ENCODER_RC_MODE_CBR_LOWDELAY_HQ:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_FULL_RESOLUTION;
if (resolution >= GST_NV_ENCODER_PRESET_1080)
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
default:
break;
}
break;
case GST_NV_ENCODER_PRESET_LOW_LATENCY_HQ:
result.preset = GST_NV_ENCODER_PRESET_P5;
if (resolution >= GST_NV_ENCODER_PRESET_1080)
result.preset = GST_NV_ENCODER_PRESET_P4;
result.tune = GST_NV_ENCODER_TUNE_LOW_LATENCY;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_DEFAULT:
case GST_NV_ENCODER_RC_MODE_CBR:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
break;
case GST_NV_ENCODER_RC_MODE_CBR_HQ:
result.tune = GST_NV_ENCODER_TUNE_ULTRA_LOW_LATENCY;
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_FULL_RESOLUTION;
if (resolution >= GST_NV_ENCODER_PRESET_2160)
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
case GST_NV_ENCODER_RC_MODE_CBR_LOWDELAY_HQ:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CBR;
result.multi_pass = GST_NV_ENCODER_TWO_PASS_FULL_RESOLUTION;
if (resolution >= GST_NV_ENCODER_PRESET_2160)
result.multi_pass = GST_NV_ENCODER_TWO_PASS_QUARTER_RESOLUTION;
break;
default:
break;
}
break;
case GST_NV_ENCODER_PRESET_LOSSLESS_HP:
result.preset = GST_NV_ENCODER_PRESET_P3;
result.tune = GST_NV_ENCODER_TUNE_LOSSLESS;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_DEFAULT:
case GST_NV_ENCODER_RC_MODE_CONSTQP:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CONSTQP;
break;
default:
break;
}
break;
case GST_NV_ENCODER_PRESET_LOSSLESS_DEFAULT:
result.preset = GST_NV_ENCODER_PRESET_P5;
result.tune = GST_NV_ENCODER_TUNE_LOSSLESS;
result.multi_pass = GST_NV_ENCODER_MULTI_PASS_DISABLED;
switch (input->rc_mode) {
case GST_NV_ENCODER_RC_MODE_DEFAULT:
case GST_NV_ENCODER_RC_MODE_CONSTQP:
result.rc_mode = GST_NV_ENCODER_RC_MODE_CONSTQP;
break;
default:
break;
}
break;
default:
*multipass_native = NV_ENC_MULTI_PASS_DISABLED;
break;
}
gst_nv_encoder_update_preset_to_native (&result, output);
}
/**

View file

@ -124,6 +124,29 @@ typedef enum
GST_NV_ENCODER_TUNE_LOSSLESS = 4,
} GstNvEncoderTune;
typedef enum
{
GST_NV_ENCODER_PRESET_720,
GST_NV_ENCODER_PRESET_1080,
GST_NV_ENCODER_PRESET_2160,
} GstNvEncoderPresetResolution;
typedef struct
{
GstNvEncoderPreset preset;
GstNvEncoderTune tune;
GstNvEncoderRCMode rc_mode;
GstNvEncoderMultiPass multi_pass;
} GstNvEncoderPresetOptions;
typedef struct
{
GUID preset;
NV_ENC_TUNING_INFO tune;
NV_ENC_PARAMS_RC_MODE rc_mode;
NV_ENC_MULTI_PASS multi_pass;
} GstNvEncoderPresetOptionsNative;
typedef struct
{
gint max_bframes;
@ -251,16 +274,13 @@ struct _GstNvEncoderClass
GType gst_nv_encoder_get_type (void);
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);
void gst_nv_encoder_preset_to_native_h264 (GstNvEncoderPresetResolution resolution,
const GstNvEncoderPresetOptions * input,
GstNvEncoderPresetOptionsNative * output);
void gst_nv_encoder_preset_to_native (GstNvEncoderPresetResolution resolution,
const GstNvEncoderPresetOptions * input,
GstNvEncoderPresetOptionsNative * output);
void gst_nv_encoder_set_device_mode (GstNvEncoder * encoder,
GstNvEncoderDeviceMode mode,

View file

@ -1333,8 +1333,22 @@ gst_nv_h264_encoder_set_format (GstNvEncoder * encoder,
}
}
gst_nv_encoder_preset_to_native (self->preset, self->tune,
&init_params->presetGUID, &init_params->tuningInfo);
GstNvEncoderPresetOptions in_opt = { };
GstNvEncoderPresetOptionsNative out_opt = { };
in_opt.preset = self->preset;
in_opt.tune = self->tune;
in_opt.rc_mode = self->rc_mode;
in_opt.multi_pass = self->multipass;
GstNvEncoderPresetResolution resolution = GST_NV_ENCODER_PRESET_720;
auto frame_size = info->width * info->height;
if (frame_size >= 3840 * 2160)
resolution = GST_NV_ENCODER_PRESET_2160;
else if (frame_size >= 1920 * 1080)
resolution = GST_NV_ENCODER_PRESET_1080;
gst_nv_encoder_preset_to_native_h264 (resolution, &in_opt, &out_opt);
init_params->presetGUID = out_opt.preset;
init_params->tuningInfo = out_opt.tune;
preset_config.version = gst_nvenc_get_preset_config_version ();
preset_config.presetCfg.version = gst_nvenc_get_config_version ();
@ -1376,6 +1390,9 @@ gst_nv_h264_encoder_set_format (GstNvEncoder * encoder,
rc_params = &config->rcParams;
rc_params->rateControlMode = out_opt.rc_mode;
rc_params->multiPass = out_opt.multi_pass;
if (self->bitrate)
rc_params->averageBitRate = self->bitrate * 1024;
if (self->max_bitrate)
@ -1423,9 +1440,6 @@ gst_nv_h264_encoder_set_format (GstNvEncoder * encoder,
}
}
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_const >= 0) {
rc_params->constQP.qpIntra = self->qp_const;

View file

@ -1328,8 +1328,22 @@ gst_nv_h265_encoder_set_format (GstNvEncoder * encoder,
init_params->darHeight = dar_d;
}
gst_nv_encoder_preset_to_native (self->preset, self->tune,
&init_params->presetGUID, &init_params->tuningInfo);
GstNvEncoderPresetOptions in_opt = { };
GstNvEncoderPresetOptionsNative out_opt = { };
in_opt.preset = self->preset;
in_opt.tune = self->tune;
in_opt.rc_mode = self->rc_mode;
in_opt.multi_pass = self->multipass;
GstNvEncoderPresetResolution resolution = GST_NV_ENCODER_PRESET_720;
auto frame_size = info->width * info->height;
if (frame_size >= 3840 * 2160)
resolution = GST_NV_ENCODER_PRESET_2160;
else if (frame_size >= 1920 * 1080)
resolution = GST_NV_ENCODER_PRESET_1080;
gst_nv_encoder_preset_to_native (resolution, &in_opt, &out_opt);
init_params->presetGUID = out_opt.preset;
init_params->tuningInfo = out_opt.tune;
preset_config.version = gst_nvenc_get_preset_config_version ();
preset_config.presetCfg.version = gst_nvenc_get_config_version ();
@ -1363,6 +1377,9 @@ gst_nv_h265_encoder_set_format (GstNvEncoder * encoder,
rc_params = &config->rcParams;
rc_params->rateControlMode = out_opt.rc_mode;
rc_params->multiPass = out_opt.multi_pass;
if (self->bitrate)
rc_params->averageBitRate = self->bitrate * 1024;
if (self->max_bitrate)
@ -1410,9 +1427,6 @@ gst_nv_h265_encoder_set_format (GstNvEncoder * encoder,
}
}
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_const >= 0) {
rc_params->constQP.qpIntra = self->qp_const;