mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 14:36:24 +00:00
nvenc: Add qp-{min,max,const}-{i,p,b} properties
This new properties allows more detailed target QP value setting
This commit is contained in:
parent
d3a909ccdd
commit
83a1c7a9a6
2 changed files with 170 additions and 0 deletions
|
@ -164,6 +164,15 @@ enum
|
||||||
PROP_STRICT_GOP,
|
PROP_STRICT_GOP,
|
||||||
PROP_CONST_QUALITY,
|
PROP_CONST_QUALITY,
|
||||||
PROP_I_ADAPT,
|
PROP_I_ADAPT,
|
||||||
|
PROP_QP_MIN_I,
|
||||||
|
PROP_QP_MIN_P,
|
||||||
|
PROP_QP_MIN_B,
|
||||||
|
PROP_QP_MAX_I,
|
||||||
|
PROP_QP_MAX_P,
|
||||||
|
PROP_QP_MAX_B,
|
||||||
|
PROP_QP_CONST_I,
|
||||||
|
PROP_QP_CONST_P,
|
||||||
|
PROP_QP_CONST_B,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_PRESET GST_NV_PRESET_DEFAULT
|
#define DEFAULT_PRESET GST_NV_PRESET_DEFAULT
|
||||||
|
@ -181,6 +190,7 @@ enum
|
||||||
#define DEFAULT_STRICT_GOP FALSE
|
#define DEFAULT_STRICT_GOP FALSE
|
||||||
#define DEFAULT_CONST_QUALITY 0
|
#define DEFAULT_CONST_QUALITY 0
|
||||||
#define DEFAULT_I_ADAPT FALSE
|
#define DEFAULT_I_ADAPT FALSE
|
||||||
|
#define DEFAULT_QP_DETAIL -1
|
||||||
|
|
||||||
/* This lock is needed to prevent the situation where multiple encoders are
|
/* This lock is needed to prevent the situation where multiple encoders are
|
||||||
* initialised at the same time which appears to cause excessive CPU usage over
|
* initialised at the same time which appears to cause excessive CPU usage over
|
||||||
|
@ -357,6 +367,78 @@ gst_nv_base_enc_class_init (GstNvBaseEncClass * klass)
|
||||||
DEFAULT_I_ADAPT,
|
DEFAULT_I_ADAPT,
|
||||||
G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY |
|
G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class, PROP_QP_MIN_I,
|
||||||
|
g_param_spec_int ("qp-min-i", "QP Min I",
|
||||||
|
"Minimum QP value for I frame, When >= 0, \"qp-min-p\" and "
|
||||||
|
"\"qp-min-b\" should be also >= 0. Overwritten by \"qp-min\""
|
||||||
|
" (-1 = from NVENC preset)", -1, 51,
|
||||||
|
DEFAULT_QP_DETAIL,
|
||||||
|
G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class, PROP_QP_MIN_P,
|
||||||
|
g_param_spec_int ("qp-min-p", "QP Min P",
|
||||||
|
"Minimum QP value for P frame, When >= 0, \"qp-min-i\" and "
|
||||||
|
"\"qp-min-b\" should be also >= 0. Overwritten by \"qp-min\""
|
||||||
|
" (-1 = from NVENC preset)", -1, 51,
|
||||||
|
DEFAULT_QP_DETAIL,
|
||||||
|
G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class, PROP_QP_MIN_B,
|
||||||
|
g_param_spec_int ("qp-min-b", "QP Min B",
|
||||||
|
"Minimum QP value for B frame, When >= 0, \"qp-min-i\" and "
|
||||||
|
"\"qp-min-p\" should be also >= 0. Overwritten by \"qp-min\""
|
||||||
|
" (-1 = from NVENC preset)", -1, 51,
|
||||||
|
DEFAULT_QP_DETAIL,
|
||||||
|
G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class, PROP_QP_MAX_I,
|
||||||
|
g_param_spec_int ("qp-max-i", "QP Max I",
|
||||||
|
"Maximum QP value for I frame, When >= 0, \"qp-max-p\" and "
|
||||||
|
"\"qp-max-b\" should be also >= 0. Overwritten by \"qp-max\""
|
||||||
|
" (-1 = from NVENC preset)", -1, 51,
|
||||||
|
DEFAULT_QP_DETAIL,
|
||||||
|
G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class, PROP_QP_MAX_P,
|
||||||
|
g_param_spec_int ("qp-max-p", "QP Max P",
|
||||||
|
"Maximum QP value for P frame, When >= 0, \"qp-max-i\" and "
|
||||||
|
"\"qp-max-b\" should be also >= 0. Overwritten by \"qp-max\""
|
||||||
|
" (-1 = from NVENC preset)", -1, 51,
|
||||||
|
DEFAULT_QP_DETAIL,
|
||||||
|
G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class, PROP_QP_MAX_B,
|
||||||
|
g_param_spec_int ("qp-max-b", "QP Max B",
|
||||||
|
"Maximum QP value for B frame, When >= 0, \"qp-max-i\" and "
|
||||||
|
"\"qp-max-p\" should be also >= 0. Overwritten by \"qp-max\""
|
||||||
|
" (-1 = from NVENC preset)", -1, 51,
|
||||||
|
DEFAULT_QP_DETAIL,
|
||||||
|
G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class, PROP_QP_CONST_I,
|
||||||
|
g_param_spec_int ("qp-const-i", "QP Const I",
|
||||||
|
"Constant QP value for I frame, When >= 0, \"qp-const-p\" and "
|
||||||
|
"\"qp-const-b\" should be also >= 0. Overwritten by \"qp-const\""
|
||||||
|
" (-1 = from NVENC preset)", -1, 51,
|
||||||
|
DEFAULT_QP_DETAIL,
|
||||||
|
G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class, PROP_QP_CONST_P,
|
||||||
|
g_param_spec_int ("qp-const-p", "QP Const P",
|
||||||
|
"Constant QP value for P frame, When >= 0, \"qp-const-i\" and "
|
||||||
|
"\"qp-const-b\" should be also >= 0. Overwritten by \"qp-const\""
|
||||||
|
" (-1 = from NVENC preset)", -1, 51,
|
||||||
|
DEFAULT_QP_DETAIL,
|
||||||
|
G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class, PROP_QP_CONST_B,
|
||||||
|
g_param_spec_int ("qp-const-b", "QP Const B",
|
||||||
|
"Constant QP value for B frame, When >= 0, \"qp-const-i\" and "
|
||||||
|
"\"qp-const-p\" should be also >= 0. Overwritten by \"qp-const\""
|
||||||
|
" (-1 = from NVENC preset)", -1, 51,
|
||||||
|
DEFAULT_QP_DETAIL,
|
||||||
|
G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -777,6 +859,8 @@ static void
|
||||||
gst_nv_base_enc_init (GstNvBaseEnc * nvenc)
|
gst_nv_base_enc_init (GstNvBaseEnc * nvenc)
|
||||||
{
|
{
|
||||||
GstVideoEncoder *encoder = GST_VIDEO_ENCODER (nvenc);
|
GstVideoEncoder *encoder = GST_VIDEO_ENCODER (nvenc);
|
||||||
|
GstNvEncQP qp_detail =
|
||||||
|
{ DEFAULT_QP_DETAIL, DEFAULT_QP_DETAIL, DEFAULT_QP_DETAIL };
|
||||||
|
|
||||||
nvenc->preset_enum = DEFAULT_PRESET;
|
nvenc->preset_enum = DEFAULT_PRESET;
|
||||||
nvenc->selected_preset = _nv_preset_to_guid (nvenc->preset_enum);
|
nvenc->selected_preset = _nv_preset_to_guid (nvenc->preset_enum);
|
||||||
|
@ -794,6 +878,9 @@ gst_nv_base_enc_init (GstNvBaseEnc * nvenc)
|
||||||
nvenc->strict_gop = DEFAULT_STRICT_GOP;
|
nvenc->strict_gop = DEFAULT_STRICT_GOP;
|
||||||
nvenc->const_quality = DEFAULT_CONST_QUALITY;
|
nvenc->const_quality = DEFAULT_CONST_QUALITY;
|
||||||
nvenc->i_adapt = DEFAULT_I_ADAPT;
|
nvenc->i_adapt = DEFAULT_I_ADAPT;
|
||||||
|
nvenc->qp_min_detail = qp_detail;
|
||||||
|
nvenc->qp_max_detail = qp_detail;
|
||||||
|
nvenc->qp_const_detail = qp_detail;
|
||||||
|
|
||||||
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
|
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
|
||||||
GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
|
GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
|
||||||
|
@ -1188,6 +1275,12 @@ _get_frame_data_height (GstVideoInfo * info)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
qp_has_values (const GstNvEncQP * qp)
|
||||||
|
{
|
||||||
|
return qp->qp_i >= 0 && qp->qp_p >= 0 && qp->qp_b >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_nv_base_enc_setup_rate_control (GstNvBaseEnc * nvenc,
|
gst_nv_base_enc_setup_rate_control (GstNvBaseEnc * nvenc,
|
||||||
NV_ENC_RC_PARAMS * rc_params)
|
NV_ENC_RC_PARAMS * rc_params)
|
||||||
|
@ -1217,6 +1310,11 @@ gst_nv_base_enc_setup_rate_control (GstNvBaseEnc * nvenc,
|
||||||
rc_params->minQP.qpInterB = nvenc->qp_min;
|
rc_params->minQP.qpInterB = nvenc->qp_min;
|
||||||
rc_params->minQP.qpInterP = nvenc->qp_min;
|
rc_params->minQP.qpInterP = nvenc->qp_min;
|
||||||
rc_params->minQP.qpIntra = nvenc->qp_min;
|
rc_params->minQP.qpIntra = nvenc->qp_min;
|
||||||
|
} else if (qp_has_values (&nvenc->qp_min_detail)) {
|
||||||
|
rc_params->enableMinQP = 1;
|
||||||
|
rc_params->minQP.qpInterB = nvenc->qp_min_detail.qp_b;
|
||||||
|
rc_params->minQP.qpInterP = nvenc->qp_min_detail.qp_p;
|
||||||
|
rc_params->minQP.qpIntra = nvenc->qp_min_detail.qp_i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nvenc->qp_max >= 0) {
|
if (nvenc->qp_max >= 0) {
|
||||||
|
@ -1224,12 +1322,21 @@ gst_nv_base_enc_setup_rate_control (GstNvBaseEnc * nvenc,
|
||||||
rc_params->maxQP.qpInterB = nvenc->qp_max;
|
rc_params->maxQP.qpInterB = nvenc->qp_max;
|
||||||
rc_params->maxQP.qpInterP = nvenc->qp_max;
|
rc_params->maxQP.qpInterP = nvenc->qp_max;
|
||||||
rc_params->maxQP.qpIntra = nvenc->qp_max;
|
rc_params->maxQP.qpIntra = nvenc->qp_max;
|
||||||
|
} else if (qp_has_values (&nvenc->qp_max_detail)) {
|
||||||
|
rc_params->enableMaxQP = 1;
|
||||||
|
rc_params->maxQP.qpInterB = nvenc->qp_max_detail.qp_b;
|
||||||
|
rc_params->maxQP.qpInterP = nvenc->qp_max_detail.qp_p;
|
||||||
|
rc_params->maxQP.qpIntra = nvenc->qp_max_detail.qp_i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nvenc->qp_const >= 0) {
|
if (nvenc->qp_const >= 0) {
|
||||||
rc_params->constQP.qpInterB = nvenc->qp_const;
|
rc_params->constQP.qpInterB = nvenc->qp_const;
|
||||||
rc_params->constQP.qpInterP = nvenc->qp_const;
|
rc_params->constQP.qpInterP = nvenc->qp_const;
|
||||||
rc_params->constQP.qpIntra = nvenc->qp_const;
|
rc_params->constQP.qpIntra = nvenc->qp_const;
|
||||||
|
} else if (qp_has_values (&nvenc->qp_const_detail)) {
|
||||||
|
rc_params->constQP.qpInterB = nvenc->qp_const_detail.qp_b;
|
||||||
|
rc_params->constQP.qpInterP = nvenc->qp_const_detail.qp_p;
|
||||||
|
rc_params->constQP.qpIntra = nvenc->qp_const_detail.qp_i;
|
||||||
}
|
}
|
||||||
|
|
||||||
nv_rcmode = _rc_mode_to_nv (rc_mode);
|
nv_rcmode = _rc_mode_to_nv (rc_mode);
|
||||||
|
@ -2290,6 +2397,33 @@ gst_nv_base_enc_set_property (GObject * object, guint prop_id,
|
||||||
case PROP_I_ADAPT:
|
case PROP_I_ADAPT:
|
||||||
nvenc->i_adapt = g_value_get_boolean (value);
|
nvenc->i_adapt = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_QP_MIN_I:
|
||||||
|
nvenc->qp_min_detail.qp_i = g_value_get_int (value);
|
||||||
|
break;
|
||||||
|
case PROP_QP_MIN_P:
|
||||||
|
nvenc->qp_min_detail.qp_p = g_value_get_int (value);
|
||||||
|
break;
|
||||||
|
case PROP_QP_MIN_B:
|
||||||
|
nvenc->qp_min_detail.qp_b = g_value_get_int (value);
|
||||||
|
break;
|
||||||
|
case PROP_QP_MAX_I:
|
||||||
|
nvenc->qp_max_detail.qp_i = g_value_get_int (value);
|
||||||
|
break;
|
||||||
|
case PROP_QP_MAX_P:
|
||||||
|
nvenc->qp_max_detail.qp_p = g_value_get_int (value);
|
||||||
|
break;
|
||||||
|
case PROP_QP_MAX_B:
|
||||||
|
nvenc->qp_max_detail.qp_b = g_value_get_int (value);
|
||||||
|
break;
|
||||||
|
case PROP_QP_CONST_I:
|
||||||
|
nvenc->qp_const_detail.qp_i = g_value_get_int (value);
|
||||||
|
break;
|
||||||
|
case PROP_QP_CONST_P:
|
||||||
|
nvenc->qp_const_detail.qp_p = g_value_get_int (value);
|
||||||
|
break;
|
||||||
|
case PROP_QP_CONST_B:
|
||||||
|
nvenc->qp_const_detail.qp_b = g_value_get_int (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
reconfig = FALSE;
|
reconfig = FALSE;
|
||||||
|
@ -2356,6 +2490,33 @@ gst_nv_base_enc_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
case PROP_I_ADAPT:
|
case PROP_I_ADAPT:
|
||||||
g_value_set_boolean (value, nvenc->i_adapt);
|
g_value_set_boolean (value, nvenc->i_adapt);
|
||||||
break;
|
break;
|
||||||
|
case PROP_QP_MIN_I:
|
||||||
|
g_value_set_int (value, nvenc->qp_min_detail.qp_i);
|
||||||
|
break;
|
||||||
|
case PROP_QP_MIN_P:
|
||||||
|
g_value_set_int (value, nvenc->qp_min_detail.qp_p);
|
||||||
|
break;
|
||||||
|
case PROP_QP_MIN_B:
|
||||||
|
g_value_set_int (value, nvenc->qp_min_detail.qp_b);
|
||||||
|
break;
|
||||||
|
case PROP_QP_MAX_I:
|
||||||
|
g_value_set_int (value, nvenc->qp_max_detail.qp_i);
|
||||||
|
break;
|
||||||
|
case PROP_QP_MAX_P:
|
||||||
|
g_value_set_int (value, nvenc->qp_max_detail.qp_p);
|
||||||
|
break;
|
||||||
|
case PROP_QP_MAX_B:
|
||||||
|
g_value_set_int (value, nvenc->qp_max_detail.qp_b);
|
||||||
|
break;
|
||||||
|
case PROP_QP_CONST_I:
|
||||||
|
g_value_set_int (value, nvenc->qp_const_detail.qp_i);
|
||||||
|
break;
|
||||||
|
case PROP_QP_CONST_P:
|
||||||
|
g_value_set_int (value, nvenc->qp_const_detail.qp_p);
|
||||||
|
break;
|
||||||
|
case PROP_QP_CONST_B:
|
||||||
|
g_value_set_int (value, nvenc->qp_const_detail.qp_b);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -70,6 +70,12 @@ typedef struct {
|
||||||
gint bframes;
|
gint bframes;
|
||||||
} GstNvEncDeviceCaps;
|
} GstNvEncDeviceCaps;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
gint qp_i;
|
||||||
|
gint qp_p;
|
||||||
|
gint qp_b;
|
||||||
|
} GstNvEncQP;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GstVideoEncoder video_encoder;
|
GstVideoEncoder video_encoder;
|
||||||
|
|
||||||
|
@ -78,8 +84,11 @@ typedef struct {
|
||||||
GUID selected_preset;
|
GUID selected_preset;
|
||||||
GstNvRCMode rate_control_mode;
|
GstNvRCMode rate_control_mode;
|
||||||
gint qp_min;
|
gint qp_min;
|
||||||
|
GstNvEncQP qp_min_detail;
|
||||||
gint qp_max;
|
gint qp_max;
|
||||||
|
GstNvEncQP qp_max_detail;
|
||||||
gint qp_const;
|
gint qp_const;
|
||||||
|
GstNvEncQP qp_const_detail;
|
||||||
guint bitrate;
|
guint bitrate;
|
||||||
gint gop_size;
|
gint gop_size;
|
||||||
guint max_bitrate;
|
guint max_bitrate;
|
||||||
|
|
Loading…
Reference in a new issue