vaapicontext: support rate-control attribute
authorWind Yuan <feng.yuan@intel.com>
Fri, 2 Nov 2012 08:55:13 +0000 (16:55 +0800)
committerZhong Cong <congx.zhong@intel.com>
Tue, 5 Feb 2013 07:37:12 +0000 (15:37 +0800)
encoder need rate-control on context creation

gst-libs/gst/vaapi/gstvaapicontext.c
gst-libs/gst/vaapi/gstvaapicontext.h
gst-libs/gst/vaapi/gstvaapitypes.h
gst-libs/gst/vaapi/gstvaapiutils.c
gst-libs/gst/vaapi/gstvaapiutils.h
gst-libs/gst/vaapi/gstvaapivalue.c
gst-libs/gst/vaapi/gstvaapivalue.h

index 9a5f116..a55f4c7 100644 (file)
@@ -63,6 +63,7 @@ struct _GstVaapiContextPrivate {
     GPtrArray          *overlay;
     GstVaapiProfile     profile;
     GstVaapiEntrypoint  entrypoint;
+    GstVaapiRateControl rate_control;
     guint               width;
     guint               height;
     guint               ref_frames;
@@ -76,7 +77,8 @@ enum {
     PROP_ENTRYPOINT,
     PROP_WIDTH,
     PROP_HEIGHT,
-    PROP_REF_FRAMES
+    PROP_REF_FRAMES,
+    PROP_RATE_CONTROL
 };
 
 static guint
@@ -291,6 +293,7 @@ gst_vaapi_context_create(GstVaapiContext *context)
     GstVaapiContextPrivate * const priv = context->priv;
     VAProfile va_profile;
     VAEntrypoint va_entrypoint;
+    guint va_rate_control;
     VAConfigAttrib attribs[2];
     guint attribs_num;
     VAContextID context_id;
@@ -329,7 +332,7 @@ gst_vaapi_context_create(GstVaapiContext *context)
     GST_VAAPI_DISPLAY_LOCK(display);
     attribs[0].type = VAConfigAttribRTFormat;
     attribs[1].type = VAConfigAttribRateControl;
-    if (VAEntrypointEncSlice == va_entrypoint)
+    if (GST_VAAPI_ENTRYPOINT_SLICE_ENCODE == priv->entrypoint)
       attribs_num = 2;
     else
       attribs_num = 1;
@@ -345,10 +348,17 @@ gst_vaapi_context_create(GstVaapiContext *context)
         goto end;
     if (!(attribs[0].value & VA_RT_FORMAT_YUV420))
         goto end;
-    if (attribs_num > 1 && !(attribs[1].value & VA_RC_NONE)
-                        && !(attribs[1].value & VA_RC_CBR)
-                        && !(attribs[1].value & VA_RC_VBR))
-        goto end;
+    if (GST_VAAPI_ENTRYPOINT_SLICE_ENCODE == priv->entrypoint) {
+        va_rate_control = from_GstVaapiRateControl(priv->rate_control);
+        if (va_rate_control == VA_RC_NONE)
+            attribs[1].value = VA_RC_NONE;
+        if ((attribs[1].value & va_rate_control) != va_rate_control) {
+            GST_ERROR("encoder rate control:%s unsupported",
+                      string_of_VARateControl(va_rate_control));
+            goto end;
+        }
+        attribs[1].value = va_rate_control;
+    }
 
     GST_VAAPI_DISPLAY_LOCK(display);
     status = vaCreateConfig(
@@ -365,11 +375,6 @@ gst_vaapi_context_create(GstVaapiContext *context)
     VASurfaceID *surface_ids = (VASurfaceID*)surfaces->data;
     int          surface_num = surfaces->len;
 
-    if (VAEntrypointEncSlice == va_entrypoint) {
-        surface_ids = NULL;
-        surface_num = 0;
-    }
-
     GST_VAAPI_DISPLAY_LOCK(display);
     status = vaCreateContext(
         GST_VAAPI_DISPLAY_VADISPLAY(display),
@@ -430,6 +435,9 @@ gst_vaapi_context_set_property(
     case PROP_REF_FRAMES:
         priv->ref_frames = g_value_get_uint(value);
         break;
+    case PROP_RATE_CONTROL:
+        priv->rate_control = g_value_get_uint(value);
+        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -463,6 +471,9 @@ gst_vaapi_context_get_property(
     case PROP_REF_FRAMES:
         g_value_set_uint(value, priv->ref_frames);
         break;
+    case PROP_RATE_CONTROL:
+        g_value_set_uint(value, priv->rate_control);
+        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
         break;
@@ -524,6 +535,14 @@ gst_vaapi_context_class_init(GstVaapiContextClass *klass)
                            "The number of reference frames",
                            0, G_MAXINT32, 0,
                            G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+    g_object_class_install_property
+        (object_class,
+         PROP_RATE_CONTROL,
+         g_param_spec_uint("rate-control",
+                           "Bitrate Control",
+                           "Bitrate Control",
+                           0, G_MAXINT32, 0,
+                           G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
 }
 
 static void
@@ -538,6 +557,7 @@ gst_vaapi_context_init(GstVaapiContext *context)
     priv->overlay       = NULL;
     priv->profile       = 0;
     priv->entrypoint    = 0;
+    priv->rate_control  = GST_VAAPI_RATECONTROL_NONE;
     priv->width         = 0;
     priv->height        = 0;
     priv->ref_frames    = 0;
@@ -569,6 +589,7 @@ gst_vaapi_context_new(
 
     info.profile    = profile;
     info.entrypoint = entrypoint;
+    info.rate_control = GST_VAAPI_RATECONTROL_NONE;
     info.width      = width;
     info.height     = height;
     info.ref_frames = get_max_ref_frames(profile);
@@ -606,6 +627,7 @@ gst_vaapi_context_new_full(GstVaapiDisplay *display, GstVaapiContextInfo *cip)
         "width",        cip->width,
         "height",       cip->height,
         "ref-frames",   cip->ref_frames,
+        "rate-control", cip->rate_control,
         NULL
     );
     if (!context->priv->is_constructed) {
index 0c34036..ca4efba 100644 (file)
@@ -71,6 +71,7 @@ typedef struct _GstVaapiContextClass            GstVaapiContextClass;
 struct _GstVaapiContextInfo {
     GstVaapiProfile     profile;
     GstVaapiEntrypoint  entrypoint;
+    GstVaapiRateControl rate_control;
     guint               width;
     guint               height;
     guint               ref_frames;
index 1ca4dd7..2bc499a 100644 (file)
@@ -148,6 +148,26 @@ typedef enum {
     GST_VAAPI_ROTATION_270 = 270,
 } GstVaapiRotation;
 
+/**
+ * GstVaapiRateControl:
+ * @GST_VAAPI_RATECONTROL_NONE: None rate control
+ * @GST_VAAPI_RATECONTROL_CBR: Constant rate control
+ * @GST_VAAPI_RATECONTROL_VBR: Variable bitrate control
+ * @GST_VAAPI_RATECONTROL_VCM: Video conference mode
+ * @GST_VAAPI_RATECONTROL_CQP: Variable bitrate control
+ * @GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: Variable bitrate control with peak rate higher than average bitrate
+ *
+ * The set of all rate-controls for #GstVaapiRateControl, only worked on encoders
+ */
+typedef enum {
+    GST_VAAPI_RATECONTROL_NONE = 0,
+    GST_VAAPI_RATECONTROL_CBR,
+    GST_VAAPI_RATECONTROL_VBR,
+    GST_VAAPI_RATECONTROL_VCM,
+    GST_VAAPI_RATECONTROL_CQP,
+    GST_VAAPI_RATECONTROL_VBR_CONSTRAINED,
+} GstVaapiRateControl;
+
 G_END_DECLS
 
 #endif /* GST_VAAPI_TYPES_H */
index 996e328..c8f11fc 100644 (file)
@@ -301,3 +301,48 @@ to_GstVaapiRotation(guint value)
     GST_ERROR("unsupported VA-API rotation value %d", value);
     return GST_VAAPI_ROTATION_0;
 }
+
+guint
+from_GstVaapiRateControl(guint value)
+{
+    switch (value) {
+    case GST_VAAPI_RATECONTROL_NONE:   return VA_RC_NONE;
+    case GST_VAAPI_RATECONTROL_CBR:  return VA_RC_CBR;
+    case GST_VAAPI_RATECONTROL_VBR: return VA_RC_VBR;
+    case GST_VAAPI_RATECONTROL_VCM: return VA_RC_VCM;
+    case GST_VAAPI_RATECONTROL_CQP: return VA_RC_CQP;
+    case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED: return VA_RC_VBR_CONSTRAINED;
+    }
+    GST_ERROR("unsupported GstVaapiRateControl value %d", value);
+    return VA_RC_NONE;
+}
+
+guint
+to_GstVaapiRateControl(guint value)
+{
+    switch (value) {
+    case VA_RC_NONE: return GST_VAAPI_RATECONTROL_NONE;
+    case VA_RC_CBR:   return GST_VAAPI_RATECONTROL_CBR;
+    case VA_RC_VBR:  return GST_VAAPI_RATECONTROL_VBR;
+    case VA_RC_VCM:  return GST_VAAPI_RATECONTROL_VCM;
+    case VA_RC_CQP: return GST_VAAPI_RATECONTROL_CQP;
+    case VA_RC_VBR_CONSTRAINED: return GST_VAAPI_RATECONTROL_VBR_CONSTRAINED;
+    }
+    GST_ERROR("unsupported VA-API Rate Control value %d", value);
+    return GST_VAAPI_RATECONTROL_NONE;
+}
+
+const char *
+string_of_VARateControl(guint rate_control)
+{
+    switch (rate_control) {
+    case VA_RC_NONE: return "VA_RC_NONE";
+    case VA_RC_CBR: return "VA_RC_CBR";
+    case VA_RC_VBR: return "VA_RC_VBR";
+    case VA_RC_VCM: return "VA_RC_VCM";
+    case VA_RC_CQP: return "VA_RC_CQP";
+    case VA_RC_VBR_CONSTRAINED: return "VA_RC_VBR_CONSTRAINED";
+    default: break;
+    }
+    return "<unknown>";
+}
index 98d91e3..1a3fbf2 100644 (file)
@@ -89,4 +89,16 @@ G_GNUC_INTERNAL
 guint
 to_GstVaapiRotation(guint value);
 
+G_GNUC_INTERNAL
+guint
+from_GstVaapiRateControl(guint value);
+
+G_GNUC_INTERNAL
+guint
+to_GstVaapiRateControl(guint value);
+
+G_GNUC_INTERNAL
+const char *
+string_of_VARateControl(guint rate_control);
+
 #endif /* GST_VAAPI_UTILS_H */
index 401770e..38cfbff 100644 (file)
@@ -209,3 +209,33 @@ gst_vaapi_rotation_get_type(void)
         g_type = g_enum_register_static("GstVaapiRotation", rotation_values);
     return g_type;
 }
+
+/* --- GstVaapiRateControl --- */
+
+GType
+gst_vaapi_rate_control_get_type(void)
+{
+    static GType g_type = 0;
+
+    static const GEnumValue rate_control_values[] = {
+        { GST_VAAPI_RATECONTROL_NONE,
+          "None rate control mode", "none" },
+        { GST_VAAPI_RATECONTROL_CBR,
+          "Constant bitrate control mode", "cbr" },
+        { GST_VAAPI_RATECONTROL_VBR,
+          "Variable bitrate control mode", "vbr" },
+        { GST_VAAPI_RATECONTROL_VCM,
+          "Video conference mode", "vcm" },
+        { GST_VAAPI_RATECONTROL_CQP,
+          "Constant QP mode", "cqp" },
+        { GST_VAAPI_RATECONTROL_VBR_CONSTRAINED,
+          "Variable bitrate control with peak rate higher than average bitrate",
+          "vbr_constrain" },
+        { 0, NULL, NULL },
+    };
+
+    if (!g_type)
+        g_type = g_enum_register_static("GstVaapiRateControl", rate_control_values);
+    return g_type;
+
+}
index ec99f8e..cb45ad0 100644 (file)
@@ -63,6 +63,15 @@ G_BEGIN_DECLS
  */
 #define GST_VAAPI_TYPE_ROTATION gst_vaapi_rotation_get_type()
 
+/**
+ * GST_VAAPI_TYPE_RATE_CONTROL:
+ *
+ * A type that represents the VA rate control.
+ *
+ * Return value: the #GType of GstVaapiRateControl
+ */
+#define GST_VAAPI_TYPE_RATE_CONTROL gst_vaapi_rate_control_get_type()
+
 GType
 gst_vaapi_id_get_type(void) G_GNUC_CONST;
 
@@ -78,6 +87,9 @@ gst_vaapi_render_mode_get_type(void) G_GNUC_CONST;
 GType
 gst_vaapi_rotation_get_type(void) G_GNUC_CONST;
 
+GType
+gst_vaapi_rate_control_get_type(void) G_GNUC_CONST;
+
 G_END_DECLS
 
 #endif /* GST_VAAPI_VALUE_H */