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

View file

@ -124,6 +124,29 @@ typedef enum
GST_NV_ENCODER_TUNE_LOSSLESS = 4, GST_NV_ENCODER_TUNE_LOSSLESS = 4,
} GstNvEncoderTune; } 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 typedef struct
{ {
gint max_bframes; gint max_bframes;
@ -251,16 +274,13 @@ struct _GstNvEncoderClass
GType gst_nv_encoder_get_type (void); GType gst_nv_encoder_get_type (void);
void gst_nv_encoder_preset_to_native (GstNvEncoderPreset preset, void gst_nv_encoder_preset_to_native_h264 (GstNvEncoderPresetResolution resolution,
GstNvEncoderTune tune, const GstNvEncoderPresetOptions * input,
GUID * preset_guid, GstNvEncoderPresetOptionsNative * output);
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 (GstNvEncoderPresetResolution resolution,
const GstNvEncoderPresetOptions * input,
GstNvEncoderPresetOptionsNative * output);
void gst_nv_encoder_set_device_mode (GstNvEncoder * encoder, void gst_nv_encoder_set_device_mode (GstNvEncoder * encoder,
GstNvEncoderDeviceMode mode, 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, GstNvEncoderPresetOptions in_opt = { };
&init_params->presetGUID, &init_params->tuningInfo); 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.version = gst_nvenc_get_preset_config_version ();
preset_config.presetCfg.version = gst_nvenc_get_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 = &config->rcParams;
rc_params->rateControlMode = out_opt.rc_mode;
rc_params->multiPass = out_opt.multi_pass;
if (self->bitrate) if (self->bitrate)
rc_params->averageBitRate = self->bitrate * 1024; rc_params->averageBitRate = self->bitrate * 1024;
if (self->max_bitrate) 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 (rc_params->rateControlMode == NV_ENC_PARAMS_RC_CONSTQP) {
if (self->qp_const >= 0) { if (self->qp_const >= 0) {
rc_params->constQP.qpIntra = self->qp_const; 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; init_params->darHeight = dar_d;
} }
gst_nv_encoder_preset_to_native (self->preset, self->tune, GstNvEncoderPresetOptions in_opt = { };
&init_params->presetGUID, &init_params->tuningInfo); 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.version = gst_nvenc_get_preset_config_version ();
preset_config.presetCfg.version = gst_nvenc_get_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 = &config->rcParams;
rc_params->rateControlMode = out_opt.rc_mode;
rc_params->multiPass = out_opt.multi_pass;
if (self->bitrate) if (self->bitrate)
rc_params->averageBitRate = self->bitrate * 1024; rc_params->averageBitRate = self->bitrate * 1024;
if (self->max_bitrate) 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 (rc_params->rateControlMode == NV_ENC_PARAMS_RC_CONSTQP) {
if (self->qp_const >= 0) { if (self->qp_const >= 0) {
rc_params->constQP.qpIntra = self->qp_const; rc_params->constQP.qpIntra = self->qp_const;