enum
{
PROP_0,
- PROP_RATE_CONTROL,
- PROP_BITRATE,
+
+ PROP_BASE,
};
static inline gboolean
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)
{
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);
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;
}
#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;
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);
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;
}
GstPadQueryFunction srcpad_query;
GstVaapiEncoder *encoder;
- GstVaapiRateControl rate_control;
- guint32 bitrate; /* kbps */
+ GPtrArray *prop_values;
guint32 out_caps_done:1;
};
/*< 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,
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 */
#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)
/* 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
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;
}
}
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;
}
}
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 */
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);
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;
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);
}
{
/*< private >*/
GstVaapiEncode parent_instance;
-
- guint32 intra_period;
- guint32 init_qp;
- guint32 min_qp;
- guint32 num_slices;
- guint32 max_bframes;
};
struct _GstVaapiEncodeH264Class
#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)
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
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;
}
}
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;
}
}
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
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,
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);
}