diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvencoder.cpp b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvencoder.cpp index 329d159de2..37c5136ced 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvencoder.cpp +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvencoder.cpp @@ -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); } /** diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvencoder.h b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvencoder.h index c00a16361a..6de23a5f39 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvencoder.h +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvencoder.h @@ -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, diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264encoder.cpp b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264encoder.cpp index c5f109a2ed..71e705c084 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264encoder.cpp +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264encoder.cpp @@ -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; diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265encoder.cpp b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265encoder.cpp index 486237db8c..c3f0659704 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265encoder.cpp +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265encoder.cpp @@ -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;