vaapiencode: update for new properties API.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Wed, 8 Jan 2014 17:36:46 +0000 (18:36 +0100)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Mon, 13 Jan 2014 16:31:55 +0000 (17:31 +0100)
Update MPEG-2 and H.264 encode elements to cope with the new core
libgstvaapi properties API. i.e. all configurable properties are now
directly handled at the GstVaapiEncoder level.

Besides, this also makes sure to not use or modify the GstVaapiEncoder
private definitions directly. Private data need to remain private.

https://bugzilla.gnome.org/show_bug.cgi?id=719529

gst/vaapi/gstvaapiencode.c
gst/vaapi/gstvaapiencode.h
gst/vaapi/gstvaapiencode_h264.c
gst/vaapi/gstvaapiencode_h264.h
gst/vaapi/gstvaapiencode_mpeg2.c

index c66488e..7c797d6 100644 (file)
@@ -48,8 +48,8 @@ G_DEFINE_TYPE_WITH_CODE (GstVaapiEncode,
 enum
 {
   PROP_0,
-  PROP_RATE_CONTROL,
-  PROP_BITRATE,
+
+  PROP_BASE,
 };
 
 static inline gboolean
@@ -90,6 +90,88 @@ gst_vaapiencode_query (GST_PAD_QUERY_FUNCTION_ARGS)
   return success;
 }
 
+typedef struct
+{
+  GstVaapiEncoderProp id;
+  GParamSpec *pspec;
+  GValue value;
+} PropValue;
+
+static PropValue *
+prop_value_new (GstVaapiEncoderPropInfo * prop)
+{
+  static const GValue default_value = G_VALUE_INIT;
+  PropValue *prop_value;
+
+  if (!prop || !prop->pspec)
+    return NULL;
+
+  prop_value = g_slice_new (PropValue);
+  if (!prop_value)
+    return NULL;
+
+  prop_value->id = prop->prop;
+  prop_value->pspec = g_param_spec_ref (prop->pspec);
+
+  memcpy (&prop_value->value, &default_value, sizeof (prop_value->value));
+  g_value_init (&prop_value->value, prop->pspec->value_type);
+  g_param_value_set_default (prop->pspec, &prop_value->value);
+  return prop_value;
+}
+
+static void
+prop_value_free (PropValue * prop_value)
+{
+  if (!prop_value)
+    return;
+
+  if (G_VALUE_TYPE (&prop_value->value))
+    g_value_unset (&prop_value->value);
+
+  if (prop_value->pspec) {
+    g_param_spec_unref (prop_value->pspec);
+    prop_value->pspec = NULL;
+  }
+  g_slice_free (PropValue, prop_value);
+}
+
+static inline PropValue *
+prop_value_lookup (GstVaapiEncode * encode, guint prop_id)
+{
+  GPtrArray *const prop_values = encode->prop_values;
+
+  if (prop_values &&
+      (prop_id >= PROP_BASE && prop_id < PROP_BASE + prop_values->len))
+    return g_ptr_array_index (prop_values, prop_id - PROP_BASE);
+  return NULL;
+}
+
+static gboolean
+gst_vaapiencode_default_get_property (GstVaapiEncode * encode, guint prop_id,
+    GValue * value)
+{
+  PropValue *const prop_value = prop_value_lookup (encode, prop_id);
+
+  if (prop_value) {
+    g_value_copy (&prop_value->value, value);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static gboolean
+gst_vaapiencode_default_set_property (GstVaapiEncode * encode, guint prop_id,
+    const GValue * value)
+{
+  PropValue *const prop_value = prop_value_lookup (encode, prop_id);
+
+  if (prop_value) {
+    g_value_copy (value, &prop_value->value);
+    return TRUE;
+  }
+  return FALSE;
+}
+
 static GstFlowReturn
 gst_vaapiencode_default_allocate_buffer (GstVaapiEncode * encode,
     GstVaapiCodedBuffer * coded_buf, GstBuffer ** outbuf_ptr)
@@ -303,6 +385,8 @@ ensure_encoder (GstVaapiEncode * encode)
 {
   GstVaapiEncodeClass *klass = GST_VAAPIENCODE_GET_CLASS (encode);
   GstVaapiEncoderStatus status;
+  GPtrArray *const prop_values = encode->prop_values;
+  guint i;
 
   g_return_val_if_fail (klass->create_encoder, FALSE);
 
@@ -314,14 +398,15 @@ ensure_encoder (GstVaapiEncode * encode)
   if (!encode->encoder)
     return FALSE;
 
-  status = gst_vaapi_encoder_set_rate_control (encode->encoder,
-      encode->rate_control);
-  if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
-    return FALSE;
-
-  status = gst_vaapi_encoder_set_bitrate (encode->encoder, encode->bitrate);
-  if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
-    return FALSE;
+  if (prop_values) {
+    for (i = 0; i < prop_values->len; i++) {
+      PropValue *const prop_value = g_ptr_array_index (prop_values, i);
+      status = gst_vaapi_encoder_set_property (encode->encoder, prop_value->id,
+          &prop_value->value);
+      if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
+        return FALSE;
+    }
+  }
   return TRUE;
 }
 
@@ -563,50 +648,17 @@ gst_vaapiencode_propose_allocation (GstVideoEncoder * venc, GstQuery * query)
 #endif
 
 static void
-gst_vaapiencode_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (object);
-
-  switch (prop_id) {
-    case PROP_RATE_CONTROL:
-      encode->rate_control = g_value_get_enum (value);
-      break;
-    case PROP_BITRATE:
-      encode->bitrate = g_value_get_uint (value);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_vaapiencode_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (object);
-
-  switch (prop_id) {
-    case PROP_RATE_CONTROL:
-      g_value_set_enum (value, encode->rate_control);
-      break;
-    case PROP_BITRATE:
-      g_value_set_uint (value, encode->bitrate);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
 gst_vaapiencode_finalize (GObject * object)
 {
   GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (object);
 
   gst_vaapiencode_destroy (encode);
 
+  if (encode->prop_values) {
+    g_ptr_array_unref (encode->prop_values);
+    encode->prop_values = NULL;
+  }
+
   encode->sinkpad = NULL;
   encode->srcpad = NULL;
 
@@ -644,8 +696,6 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass)
   gst_vaapi_plugin_base_class_init (GST_VAAPI_PLUGIN_BASE_CLASS (klass));
 
   object_class->finalize = gst_vaapiencode_finalize;
-  object_class->set_property = gst_vaapiencode_set_property;
-  object_class->get_property = gst_vaapiencode_get_property;
 
   venc_class->open = GST_DEBUG_FUNCPTR (gst_vaapiencode_open);
   venc_class->close = GST_DEBUG_FUNCPTR (gst_vaapiencode_close);
@@ -660,24 +710,61 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass)
       GST_DEBUG_FUNCPTR (gst_vaapiencode_propose_allocation);
 #endif
 
+  klass->get_property = gst_vaapiencode_default_get_property;
+  klass->set_property = gst_vaapiencode_default_set_property;
   klass->allocate_buffer = gst_vaapiencode_default_allocate_buffer;
 
   /* Registering debug symbols for function pointers */
   GST_DEBUG_REGISTER_FUNCPTR (gst_vaapiencode_query);
+}
 
-  g_object_class_install_property (object_class,
-      PROP_RATE_CONTROL,
-      g_param_spec_enum ("rate-control",
-          "Rate Control",
-          "Rate control mode",
-          GST_VAAPI_TYPE_RATE_CONTROL,
-          GST_VAAPI_RATECONTROL_CQP,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (object_class,
-      PROP_BITRATE,
-      g_param_spec_uint ("bitrate",
-          "Bitrate (kbps)",
-          "The desired bitrate expressed in kbps (0: auto-calculate)",
-          0, 100 * 1024, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+static inline GPtrArray *
+get_properties (GstVaapiEncodeClass * klass)
+{
+  return klass->get_properties ? klass->get_properties () : NULL;
+}
+
+gboolean
+gst_vaapiencode_init_properties (GstVaapiEncode * encode)
+{
+  GPtrArray *const props = get_properties (GST_VAAPIENCODE_GET_CLASS (encode));
+  guint i;
+
+  /* XXX: use base_init()/base_finalize() to avoid multiple initializations */
+  if (!props)
+    return FALSE;
+
+  encode->prop_values =
+      g_ptr_array_new_full (props->len, (GDestroyNotify) prop_value_free);
+  if (!encode->prop_values) {
+    g_ptr_array_unref (props);
+    return FALSE;
+  }
+
+  for (i = 0; i < props->len; i++) {
+    PropValue *const prop_value = prop_value_new ((GstVaapiEncoderPropInfo *)
+        g_ptr_array_index (props, i));
+    if (!prop_value)
+      return FALSE;
+    g_ptr_array_add (encode->prop_values, prop_value);
+  }
+  return TRUE;
+}
+
+gboolean
+gst_vaapiencode_class_init_properties (GstVaapiEncodeClass * klass)
+{
+  GObjectClass *const object_class = G_OBJECT_CLASS (klass);
+  GPtrArray *const props = get_properties (klass);
+  guint i;
+
+  if (!props)
+    return FALSE;
+
+  for (i = 0; i < props->len; i++) {
+    GstVaapiEncoderPropInfo *const prop = g_ptr_array_index (props, i);
+    g_object_class_install_property (object_class, PROP_BASE + i, prop->pspec);
+  }
+  g_ptr_array_unref (props);
+  return TRUE;
 }
index e930cbe..7eeabc4 100644 (file)
@@ -59,8 +59,7 @@ struct _GstVaapiEncode
   GstPadQueryFunction srcpad_query;
 
   GstVaapiEncoder *encoder;
-  GstVaapiRateControl rate_control;
-  guint32 bitrate;              /* kbps */
+  GPtrArray *prop_values;
 
   guint32 out_caps_done:1;
 };
@@ -70,6 +69,12 @@ struct _GstVaapiEncodeClass
   /*< private >*/
   GstVaapiPluginBaseClass parent_class;
 
+  GPtrArray *         (*get_properties) (void);
+  gboolean            (*get_property)   (GstVaapiEncode * encode,
+                                         guint prop_id, GValue * value);
+  gboolean            (*set_property)   (GstVaapiEncode * encode,
+                                         guint prop_id, const GValue * value);
+
   GstVaapiEncoder *   (*create_encoder)    (GstVaapiEncode * encode,
                                             GstVaapiDisplay * display);
   GstFlowReturn       (*allocate_buffer)   (GstVaapiEncode * encode,
@@ -80,6 +85,14 @@ struct _GstVaapiEncodeClass
 GType
 gst_vaapiencode_get_type (void) G_GNUC_CONST;
 
+G_GNUC_INTERNAL
+gboolean
+gst_vaapiencode_init_properties (GstVaapiEncode * encode);
+
+G_GNUC_INTERNAL
+gboolean
+gst_vaapiencode_class_init_properties (GstVaapiEncodeClass * encode_class);
+
 G_END_DECLS
 
 #endif /* GST_VAAPIENCODE_H */
index 40d2866..b559e3b 100644 (file)
@@ -22,7 +22,6 @@
 #include "gst/vaapi/sysdeps.h"
 #include <gst/vaapi/gstvaapidisplay.h>
 #include <gst/vaapi/gstvaapiencoder_h264.h>
-#include "gst/vaapi/gstvaapiencoder_h264_priv.h"
 #include "gstvaapiencode_h264.h"
 #include "gstvaapipluginutil.h"
 #if GST_CHECK_VERSION(1,0,0)
@@ -80,19 +79,10 @@ static GstStaticPadTemplate gst_vaapiencode_h264_src_factory =
 /* h264 encode */
 G_DEFINE_TYPE (GstVaapiEncodeH264, gst_vaapiencode_h264, GST_TYPE_VAAPIENCODE);
 
-enum
-{
-  PROP_0,
-  PROP_KEY_PERIOD,
-  PROP_MAX_BFRAMES,
-  PROP_INIT_QP,
-  PROP_MIN_QP,
-  PROP_NUM_SLICES,
-};
-
 static void
 gst_vaapiencode_h264_init (GstVaapiEncodeH264 * encode)
 {
+  gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode));
 }
 
 static void
@@ -105,26 +95,13 @@ static void
 gst_vaapiencode_h264_set_property (GObject * object,
     guint prop_id, const GValue * value, GParamSpec * pspec)
 {
-  GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (object);
+  GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object);
+  GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object);
 
   switch (prop_id) {
-    case PROP_KEY_PERIOD:
-      encode->intra_period = g_value_get_uint (value);
-      break;
-    case PROP_INIT_QP:
-      encode->init_qp = g_value_get_uint (value);
-      break;
-    case PROP_MIN_QP:
-      encode->min_qp = g_value_get_uint (value);
-      break;
-    case PROP_NUM_SLICES:
-      encode->num_slices = g_value_get_uint (value);
-      break;
-    case PROP_MAX_BFRAMES:
-      encode->max_bframes = g_value_get_uint (value);
-      break;
     default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      if (!encode_class->set_property (base_encode, prop_id, value))
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
 }
@@ -133,26 +110,13 @@ static void
 gst_vaapiencode_h264_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec)
 {
-  GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (object);
+  GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object);
+  GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object);
 
   switch (prop_id) {
-    case PROP_KEY_PERIOD:
-      g_value_set_uint (value, encode->intra_period);
-      break;
-    case PROP_INIT_QP:
-      g_value_set_uint (value, encode->init_qp);
-      break;
-    case PROP_MIN_QP:
-      g_value_set_uint (value, encode->min_qp);
-      break;
-    case PROP_NUM_SLICES:
-      g_value_set_uint (value, encode->num_slices);
-      break;
-    case PROP_MAX_BFRAMES:
-      g_value_set_uint (value, encode->max_bframes);
-      break;
     default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      if (!encode_class->get_property (base_encode, prop_id, value))
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
 }
@@ -161,23 +125,7 @@ static GstVaapiEncoder *
 gst_vaapiencode_h264_create_encoder (GstVaapiEncode * base,
     GstVaapiDisplay * display)
 {
-  GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (base);
-  GstVaapiEncoder *base_encoder;
-  GstVaapiEncoderH264 *encoder;
-
-  base_encoder = gst_vaapi_encoder_h264_new (display);
-  if (!base_encoder)
-    return NULL;
-  encoder = GST_VAAPI_ENCODER_H264 (base_encoder);
-
-  encoder->profile = GST_VAAPI_PROFILE_UNKNOWN;
-  encoder->level = GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL;
-  encoder->intra_period = encode->intra_period;
-  encoder->init_qp = encode->init_qp;
-  encoder->min_qp = encode->min_qp;
-  encoder->slice_num = encode->num_slices;
-  encoder->b_frame_num = encode->max_bframes;
-  return base_encoder;
+  return gst_vaapi_encoder_h264_new (display);
 }
 
 /* h264 NAL byte stream operations */
@@ -276,7 +224,7 @@ static GstFlowReturn
 gst_vaapiencode_h264_allocate_buffer (GstVaapiEncode * encode,
     GstVaapiCodedBuffer * coded_buf, GstBuffer ** out_buffer_ptr)
 {
-  GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (encode->encoder);
+  GstVaapiEncoderH264 *const encoder = (GstVaapiEncoderH264 *) encode->encoder;
   GstFlowReturn ret;
 
   g_return_val_if_fail (encoder != NULL, GST_FLOW_ERROR);
@@ -318,6 +266,7 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass)
   object_class->set_property = gst_vaapiencode_h264_set_property;
   object_class->get_property = gst_vaapiencode_h264_get_property;
 
+  encode_class->get_properties = gst_vaapi_encoder_h264_get_default_properties;
   encode_class->create_encoder = gst_vaapiencode_h264_create_encoder;
   encode_class->allocate_buffer = gst_vaapiencode_h264_allocate_buffer;
 
@@ -334,41 +283,5 @@ gst_vaapiencode_h264_class_init (GstVaapiEncodeH264Class * klass)
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&gst_vaapiencode_h264_src_factory));
 
-  g_object_class_install_property (object_class,
-      PROP_KEY_PERIOD,
-      g_param_spec_uint ("key-period",
-          "Key Period",
-          "Maximal distance between two key-frames",
-          1, 300, GST_VAAPI_ENCODER_H264_DEFAULT_INTRA_PERIOD,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (object_class,
-      PROP_MAX_BFRAMES,
-      g_param_spec_uint ("max-bframes",
-          "Max B-Frames",
-          "Number of B-frames between I and P",
-          0, 10, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (object_class,
-      PROP_INIT_QP,
-      g_param_spec_uint ("init-qp",
-          "Initial QP",
-          "Initial quantizer value",
-          1, 51, GST_VAAPI_ENCODER_H264_DEFAULT_INIT_QP,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (object_class,
-      PROP_MIN_QP,
-      g_param_spec_uint ("min-qp",
-          "Minimum QP",
-          "Minimum quantizer value",
-          1, 51, GST_VAAPI_ENCODER_H264_DEFAULT_MIN_QP,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (object_class,
-      PROP_NUM_SLICES,
-      g_param_spec_uint ("num-slices",
-          "Number of Slices",
-          "Number of slices per frame",
-          1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  gst_vaapiencode_class_init_properties (encode_class);
 }
index d6dad76..bf440bf 100644 (file)
@@ -52,12 +52,6 @@ struct _GstVaapiEncodeH264
 {
   /*< private >*/
   GstVaapiEncode parent_instance;
-
-  guint32 intra_period;
-  guint32 init_qp;
-  guint32 min_qp;
-  guint32 num_slices;
-  guint32 max_bframes;
 };
 
 struct _GstVaapiEncodeH264Class
index 0daccba..90c513a 100644 (file)
@@ -22,7 +22,6 @@
 #include "gst/vaapi/sysdeps.h"
 #include <gst/vaapi/gstvaapidisplay.h>
 #include <gst/vaapi/gstvaapiencoder_mpeg2.h>
-#include "gst/vaapi/gstvaapiencoder_mpeg2_priv.h"
 #include "gstvaapiencode_mpeg2.h"
 #include "gstvaapipluginutil.h"
 #if GST_CHECK_VERSION(1,0,0)
@@ -82,20 +81,10 @@ static GstStaticPadTemplate gst_vaapiencode_mpeg2_src_factory =
 G_DEFINE_TYPE (GstVaapiEncodeMpeg2, gst_vaapiencode_mpeg2,
     GST_TYPE_VAAPIENCODE);
 
-enum
-{
-  PROP_0,
-  PROP_QUANTIZER,
-  PROP_KEY_PERIOD,
-  PROP_MAX_BFRAMES
-};
-
 static void
 gst_vaapiencode_mpeg2_init (GstVaapiEncodeMpeg2 * encode)
 {
-  encode->quantizer = GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP;
-  encode->intra_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE;
-  encode->ip_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES;
+  gst_vaapiencode_init_properties (GST_VAAPIENCODE_CAST (encode));
 }
 
 static void
@@ -108,20 +97,13 @@ static void
 gst_vaapiencode_mpeg2_set_property (GObject * object,
     guint prop_id, const GValue * value, GParamSpec * pspec)
 {
-  GstVaapiEncodeMpeg2 *const encode = GST_VAAPIENCODE_MPEG2_CAST (object);
+  GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object);
+  GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object);
 
   switch (prop_id) {
-    case PROP_QUANTIZER:
-      encode->quantizer = g_value_get_uint (value);
-      break;
-    case PROP_KEY_PERIOD:
-      encode->intra_period = g_value_get_uint (value);
-      break;
-    case PROP_MAX_BFRAMES:
-      encode->ip_period = g_value_get_uint (value);
-      break;
     default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      if (!encode_class->set_property (base_encode, prop_id, value))
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
 }
@@ -130,20 +112,13 @@ static void
 gst_vaapiencode_mpeg2_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec)
 {
-  GstVaapiEncodeMpeg2 *const encode = GST_VAAPIENCODE_MPEG2_CAST (object);
+  GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_GET_CLASS (object);
+  GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (object);
 
   switch (prop_id) {
-    case PROP_QUANTIZER:
-      g_value_set_uint (value, encode->quantizer);
-      break;
-    case PROP_KEY_PERIOD:
-      g_value_set_uint (value, encode->intra_period);
-      break;
-    case PROP_MAX_BFRAMES:
-      g_value_set_uint (value, encode->ip_period);
-      break;
     default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      if (!encode_class->get_property (base_encode, prop_id, value))
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
 }
@@ -152,21 +127,7 @@ static GstVaapiEncoder *
 gst_vaapiencode_mpeg2_create_encoder (GstVaapiEncode * base,
     GstVaapiDisplay * display)
 {
-  GstVaapiEncodeMpeg2 *const encode = GST_VAAPIENCODE_MPEG2_CAST (base);
-  GstVaapiEncoder *base_encoder;
-  GstVaapiEncoderMpeg2 *encoder;
-
-  base_encoder = gst_vaapi_encoder_mpeg2_new (display);
-  if (!base_encoder)
-    return NULL;
-  encoder = GST_VAAPI_ENCODER_MPEG2 (base_encoder);
-
-  encoder->profile = GST_VAAPI_ENCODER_MPEG2_DEFAULT_PROFILE;
-  encoder->level = GST_VAAPI_ENCODER_MPEG2_DEFAULT_LEVEL;
-  encoder->cqp = encode->quantizer;
-  encoder->intra_period = encode->intra_period;
-  encoder->ip_period = encode->ip_period;
-  return base_encoder;
+  return gst_vaapi_encoder_mpeg2_new (display);
 }
 
 static void
@@ -183,6 +144,7 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass)
   object_class->set_property = gst_vaapiencode_mpeg2_set_property;
   object_class->get_property = gst_vaapiencode_mpeg2_get_property;
 
+  encode_class->get_properties = gst_vaapi_encoder_mpeg2_get_default_properties;
   encode_class->create_encoder = gst_vaapiencode_mpeg2_create_encoder;
 
   gst_element_class_set_static_metadata (element_class,
@@ -198,33 +160,5 @@ gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass)
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&gst_vaapiencode_mpeg2_src_factory));
 
-  g_object_class_install_property (object_class,
-      PROP_QUANTIZER,
-      g_param_spec_uint ("quantizer",
-          "Constant Quantizer",
-          "Constant quantizer (if rate-control mode is CQP)",
-          GST_VAAPI_ENCODER_MPEG2_MIN_CQP,
-          GST_VAAPI_ENCODER_MPEG2_MAX_CQP,
-          GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (object_class,
-      PROP_KEY_PERIOD,
-      g_param_spec_uint ("key-period",
-          "Key Period",
-          "Maximal distance between two key-frames",
-          1,
-          GST_VAAPI_ENCODER_MPEG2_MAX_GOP_SIZE,
-          GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (object_class,
-      PROP_MAX_BFRAMES,
-      g_param_spec_uint ("max-bframes",
-          "Max B-Frames",
-          "Number of B-frames between I and P",
-          0,
-          GST_VAAPI_ENCODER_MPEG2_MAX_MAX_BFRAMES,
-          GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  gst_vaapiencode_class_init_properties (encode_class);
 }