mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 22:36:33 +00:00
va: encoder: Rate control property.
Fixes: #1241 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2522>
This commit is contained in:
parent
c287711418
commit
e27ad1a273
3 changed files with 119 additions and 46 deletions
|
@ -1125,35 +1125,80 @@ gst_va_encode_picture_free (GstVaEncodePicture * pic)
|
|||
g_slice_free (GstVaEncodePicture, pic);
|
||||
}
|
||||
|
||||
/**
|
||||
* GstVaEncoderRateControl:
|
||||
*
|
||||
* Since: 1.22
|
||||
*/
|
||||
GType
|
||||
gst_va_encoder_rate_control_get_type (void)
|
||||
{
|
||||
static gsize type = 0;
|
||||
static const GEnumValue values[] = {
|
||||
{VA_RC_CBR, "Constant Bitrate", "cbr"},
|
||||
{VA_RC_VBR, "Variable Bitrate", "vbr"},
|
||||
{VA_RC_VCM, "Video Conferencing Mode (Non HRD compliant)", "vcm"},
|
||||
{VA_RC_CQP, "Constant Quantizer", "cqp"},
|
||||
/* {VA_RC_VBR_CONSTRAINED, "VBR with peak rate higher than average bitrate", */
|
||||
/* "vbr-constrained"}, */
|
||||
/* {VA_RC_ICQ, "Intelligent Constant Quality", "icq"}, */
|
||||
/* {VA_RC_MB, "Macroblock based rate control", "mb"}, */
|
||||
/* {VA_RC_CFS, "Constant Frame Size", "cfs"}, */
|
||||
/* {VA_RC_PARALLEL, "Parallel BRC", "parallel"}, */
|
||||
/* {VA_RC_QVBR, "Quality defined VBR", "qvbr"}, */
|
||||
/* {VA_RC_AVBR, "Average VBR", "avbr"}, */
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
/* currently supported rate controls */
|
||||
static const GEnumValue rate_control_map[] = {
|
||||
{VA_RC_CBR, "Constant Bitrate", "cbr"},
|
||||
{VA_RC_VBR, "Variable Bitrate", "vbr"},
|
||||
{VA_RC_VCM, "Video Conferencing Mode (Non HRD compliant)", "vcm"},
|
||||
{VA_RC_CQP, "Constant Quantizer", "cqp"},
|
||||
/* {VA_RC_VBR_CONSTRAINED, "VBR with peak rate higher than average bitrate", */
|
||||
/* "vbr-constrained"}, */
|
||||
/* {VA_RC_ICQ, "Intelligent Constant Quality", "icq"}, */
|
||||
/* {VA_RC_MB, "Macroblock based rate control", "mb"}, */
|
||||
/* {VA_RC_CFS, "Constant Frame Size", "cfs"}, */
|
||||
/* {VA_RC_PARALLEL, "Parallel BRC", "parallel"}, */
|
||||
/* {VA_RC_QVBR, "Quality defined VBR", "qvbr"}, */
|
||||
/* {VA_RC_AVBR, "Average VBR", "avbr"}, */
|
||||
};
|
||||
|
||||
if (g_once_init_enter (&type)) {
|
||||
GType _type = g_enum_register_static ("GstVaEncoderRateControl", values);
|
||||
g_once_init_leave (&type, _type);
|
||||
static gint
|
||||
_guint32_cmp (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
return *((const guint32 *) a) - *((const guint32 *) b);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_va_encoder_get_rate_control_enum (GstVaEncoder * self,
|
||||
GEnumValue ratectl[16])
|
||||
{
|
||||
guint i, j, k = 0;
|
||||
guint32 rc, rc_prev = 0;
|
||||
VAProfile profile;
|
||||
GArray *rcs;
|
||||
|
||||
g_return_val_if_fail (GST_IS_VA_ENCODER (self), FALSE);
|
||||
|
||||
/* reseve the number of supported rate controls per profile */
|
||||
rcs = g_array_sized_new (FALSE, FALSE, sizeof (guint32),
|
||||
G_N_ELEMENTS (rate_control_map) * self->available_profiles->len);
|
||||
|
||||
for (i = 0; i < self->available_profiles->len; i++) {
|
||||
profile = g_array_index (self->available_profiles, VAProfile, i);
|
||||
rc = gst_va_encoder_get_rate_control_mode (self, profile, self->entrypoint);
|
||||
if (rc == 0)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < G_N_ELEMENTS (rate_control_map); j++) {
|
||||
if (rc & rate_control_map[j].value)
|
||||
rcs = g_array_append_val (rcs, rate_control_map[j].value);
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
if (rcs->len == 0) {
|
||||
g_clear_pointer (&rcs, g_array_unref);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_array_sort (rcs, _guint32_cmp);
|
||||
|
||||
for (i = 0; i < rcs->len; i++) {
|
||||
rc = g_array_index (rcs, guint32, i);
|
||||
if (rc == rc_prev)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < G_N_ELEMENTS (rate_control_map); j++) {
|
||||
if (rc == rate_control_map[j].value && k < 15)
|
||||
ratectl[k++] = rate_control_map[j];
|
||||
}
|
||||
|
||||
rc_prev = rc;
|
||||
}
|
||||
|
||||
g_clear_pointer (&rcs, g_array_unref);
|
||||
if (k == 0)
|
||||
return FALSE;
|
||||
/* *INDENT-OFF* */
|
||||
ratectl[k] = (GEnumValue) { 0, NULL, NULL };
|
||||
/* *INDENT-ON* */
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -44,9 +44,6 @@ struct _GstVaEncodePicture
|
|||
VABufferID coded_buffer;
|
||||
};
|
||||
|
||||
#define GST_TYPE_VA_ENCODER_RATE_CONTROL (gst_va_encoder_rate_control_get_type())
|
||||
GType gst_va_encoder_rate_control_get_type (void);
|
||||
|
||||
gboolean gst_va_encoder_is_open (GstVaEncoder * self);
|
||||
gboolean gst_va_encoder_open (GstVaEncoder * self,
|
||||
VAProfile profile,
|
||||
|
@ -86,6 +83,8 @@ guint32 gst_va_encoder_get_rtformat (GstVaEncoder * self,
|
|||
guint32 gst_va_encoder_get_packed_headers (GstVaEncoder * self,
|
||||
VAProfile profile,
|
||||
VAEntrypoint entrypoint);
|
||||
gboolean gst_va_encoder_get_rate_control_enum (GstVaEncoder * self,
|
||||
GEnumValue ratectl[16]);
|
||||
gboolean gst_va_encoder_add_param (GstVaEncoder * self,
|
||||
GstVaEncodePicture * pic,
|
||||
VABufferType type,
|
||||
|
|
|
@ -124,6 +124,10 @@ static GstElementClass *parent_class = NULL;
|
|||
struct _GstVaH264EncClass
|
||||
{
|
||||
GstVaBaseEncClass parent_class;
|
||||
|
||||
GType rate_control_type;
|
||||
char rate_control_type_name[34];
|
||||
GEnumValue rate_control[16];
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
|
@ -3230,13 +3234,17 @@ gst_va_h264_enc_class_init (gpointer g_klass, gpointer class_data)
|
|||
{
|
||||
GstCaps *src_doc_caps, *sink_doc_caps;
|
||||
GstPadTemplate *sink_pad_templ, *src_pad_templ;
|
||||
GObjectClass *const object_class = G_OBJECT_CLASS (g_klass);
|
||||
GstElementClass *const element_class = GST_ELEMENT_CLASS (g_klass);
|
||||
GstVideoEncoderClass *const venc_class = GST_VIDEO_ENCODER_CLASS (g_klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (g_klass);
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_klass);
|
||||
GstVideoEncoderClass *venc_class = GST_VIDEO_ENCODER_CLASS (g_klass);
|
||||
GstVaBaseEncClass *va_enc_class = GST_VA_BASE_ENC_CLASS (g_klass);
|
||||
GstVaH264EncClass *vah264enc_class = GST_VA_H264_ENC_CLASS (g_klass);
|
||||
GstVaDisplay *display;
|
||||
GstVaEncoder *encoder;
|
||||
struct CData *cdata = class_data;
|
||||
gchar *long_name;
|
||||
const gchar *name, *desc;
|
||||
gint n_props = N_PROPERTIES;
|
||||
|
||||
if (cdata->entrypoint == VAEntrypointEncSlice) {
|
||||
desc = "VA-API based H.264 video encoder";
|
||||
|
@ -3292,6 +3300,27 @@ gst_va_h264_enc_class_init (gpointer g_klass, gpointer class_data)
|
|||
va_enc_class->prepare_output =
|
||||
GST_DEBUG_FUNCPTR (gst_va_h264_enc_prepare_output);
|
||||
|
||||
{
|
||||
display =
|
||||
gst_va_display_drm_new_from_path (va_enc_class->render_device_path);
|
||||
encoder = gst_va_encoder_new (display, va_enc_class->codec,
|
||||
va_enc_class->entrypoint);
|
||||
if (gst_va_encoder_get_rate_control_enum (encoder,
|
||||
vah264enc_class->rate_control)) {
|
||||
g_snprintf (vah264enc_class->rate_control_type_name,
|
||||
G_N_ELEMENTS (vah264enc_class->rate_control_type_name) - 1,
|
||||
"GstVaEncoderRateControl_%" GST_FOURCC_FORMAT "%s",
|
||||
GST_FOURCC_ARGS (va_enc_class->codec),
|
||||
(va_enc_class->entrypoint == VAEntrypointEncSliceLP) ? "_LP" : "");
|
||||
vah264enc_class->rate_control_type =
|
||||
g_enum_register_static (vah264enc_class->rate_control_type_name,
|
||||
vah264enc_class->rate_control);
|
||||
gst_type_mark_as_plugin_api (vah264enc_class->rate_control_type, 0);
|
||||
}
|
||||
gst_object_unref (encoder);
|
||||
gst_object_unref (display);
|
||||
}
|
||||
|
||||
g_free (long_name);
|
||||
g_free (cdata->description);
|
||||
g_free (cdata->render_device_path);
|
||||
|
@ -3513,19 +3542,19 @@ gst_va_h264_enc_class_init (gpointer g_klass, gpointer class_data)
|
|||
"The desired max CPB size in Kb (0: auto-calculate)", 0, 2000 * 1024, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
|
||||
|
||||
/**
|
||||
* GstVaH264Enc:rate-control:
|
||||
*
|
||||
* The desired rate control mode for the encoder.
|
||||
*/
|
||||
properties[PROP_RATE_CONTROL] = g_param_spec_enum ("rate-control",
|
||||
"rate control mode", "The desired rate control mode for the encoder",
|
||||
GST_TYPE_VA_ENCODER_RATE_CONTROL, VA_RC_CBR,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
|
||||
if (vah264enc_class->rate_control_type > 0) {
|
||||
properties[PROP_RATE_CONTROL] = g_param_spec_enum ("rate-control",
|
||||
"rate control mode", "The desired rate control mode for the encoder",
|
||||
vah264enc_class->rate_control_type,
|
||||
vah264enc_class->rate_control[0].value,
|
||||
GST_PARAM_CONDITIONALLY_AVAILABLE | G_PARAM_READWRITE
|
||||
| G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
|
||||
} else {
|
||||
n_props--;
|
||||
properties[PROP_RATE_CONTROL] = NULL;
|
||||
}
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
|
||||
|
||||
gst_type_mark_as_plugin_api (gst_va_encoder_rate_control_get_type (), 0);
|
||||
g_object_class_install_properties (object_class, n_props, properties);
|
||||
|
||||
/**
|
||||
* GstVaFeature:
|
||||
|
|
Loading…
Reference in a new issue