From 2e356b0f7efae33fb943ad11204020dcdbf1b04f Mon Sep 17 00:00:00 2001 From: XuGuangxin Date: Wed, 20 Nov 2013 16:21:32 +0800 Subject: [PATCH] plugins: add mpeg2 encoder element. Add GstVaapiEncodeMPEG2 element object. The actual plug-in element is called "vaapiencode_mpeg2". Valid properties: - rate-control: rate control mode (default: cqp - constant QP) - bitrate: desired bitrate in kbps (default: auto-calculated) - key-period: maximal distance between two key frames (default: 30) - max-bframes: number of B-frames between I and P (default: 2) - quantizer: constant quantizer (default: 8) Signed-off-by: Gwenole Beauchesne --- gst/vaapi/Makefile.am | 2 + gst/vaapi/gstvaapi.c | 4 + gst/vaapi/gstvaapiencode_mpeg2.c | 248 +++++++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapiencode_mpeg2.h | 76 ++++++++++++ 4 files changed, 330 insertions(+) create mode 100644 gst/vaapi/gstvaapiencode_mpeg2.c create mode 100644 gst/vaapi/gstvaapiencode_mpeg2.h diff --git a/gst/vaapi/Makefile.am b/gst/vaapi/Makefile.am index 15e8cb8..9e57d0d 100644 --- a/gst/vaapi/Makefile.am +++ b/gst/vaapi/Makefile.am @@ -59,11 +59,13 @@ libgstvaapi_source_h = \ libgstvaapi_enc_source_c = \ gstvaapiencode.c \ gstvaapiencode_h264.c \ + gstvaapiencode_mpeg2.c \ $(NULL) libgstvaapi_enc_source_h = \ gstvaapiencode.h \ gstvaapiencode_h264.h \ + gstvaapiencode_mpeg2.h \ $(NULL) if USE_ENCODERS diff --git a/gst/vaapi/gstvaapi.c b/gst/vaapi/gstvaapi.c index 07e98b6..34358b8 100644 --- a/gst/vaapi/gstvaapi.c +++ b/gst/vaapi/gstvaapi.c @@ -32,6 +32,7 @@ #if USE_ENCODERS #include "gstvaapiencode_h264.h" +#include "gstvaapiencode_mpeg2.h" #endif #define PLUGIN_NAME "vaapi" @@ -62,6 +63,9 @@ plugin_init (GstPlugin *plugin) gst_element_register(plugin, "vaapiencode_h264", GST_RANK_PRIMARY, GST_TYPE_VAAPIENCODE_H264); + gst_element_register(plugin, "vaapiencode_mpeg2", + GST_RANK_PRIMARY, + GST_TYPE_VAAPIENCODE_MPEG2); #endif return TRUE; diff --git a/gst/vaapi/gstvaapiencode_mpeg2.c b/gst/vaapi/gstvaapiencode_mpeg2.c new file mode 100644 index 0000000..4f0a5e8 --- /dev/null +++ b/gst/vaapi/gstvaapiencode_mpeg2.c @@ -0,0 +1,248 @@ +/* + * gstvaapiencode_mpeg2.c - VA-API MPEG2 encoder + * + * Copyright (C) 2012-2013 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "gst/vaapi/sysdeps.h" +#include "gst/vaapi/gstvaapicompat.h" + +#include "gstvaapiencode_mpeg2.h" +#include "gstvaapipluginutil.h" +#include "gst/vaapi/gstvaapiencoder_mpeg2.h" +#include "gst/vaapi/gstvaapiencoder_mpeg2_priv.h" +#include "gst/vaapi/gstvaapidisplay.h" +#include "gst/vaapi/gstvaapivalue.h" +#include "gst/vaapi/gstvaapisurface.h" + +#include + +GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg2_encode_debug); +#define GST_CAT_DEFAULT gst_vaapi_mpeg2_encode_debug + +#define GST_CAPS_CODEC(CODEC) CODEC "; " + +static const char gst_vaapiencode_mpeg2_sink_caps_str[] = + GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) "; " + GST_VAAPI_SURFACE_CAPS; + +static const char gst_vaapiencode_mpeg2_src_caps_str[] = + GST_CAPS_CODEC ("video/mpeg," + "mpegversion = (int) 2, " "systemstream = (boolean) false"); + +static GstStaticPadTemplate gst_vaapiencode_mpeg2_sink_factory = + GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_mpeg2_sink_caps_str)); + +static GstStaticPadTemplate gst_vaapiencode_mpeg2_src_factory = + GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_vaapiencode_mpeg2_src_caps_str)); + +/* mpeg2 encode */ +G_DEFINE_TYPE (GstVaapiEncodeMpeg2, gst_vaapiencode_mpeg2, GST_TYPE_VAAPIENCODE) + +enum +{ + PROP_0, + PROP_RATE_CONTROL, + PROP_BITRATE, + PROP_QUANTIZER, + PROP_KEY_PERIOD, + PROP_MAX_BFRAMES +}; + +static void +gst_vaapiencode_mpeg2_init (GstVaapiEncodeMpeg2 * mpeg2_encode) +{ + mpeg2_encode->rate_control = GST_VAAPI_ENCODER_MPEG2_DEFAULT_RATE_CONTROL; + mpeg2_encode->bitrate = 0; + mpeg2_encode->quantizer = GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP; + mpeg2_encode->intra_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE; + mpeg2_encode->ip_period = GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES; +} + +static void +gst_vaapiencode_mpeg2_finalize (GObject * object) +{ + G_OBJECT_CLASS (gst_vaapiencode_mpeg2_parent_class)->finalize (object); +} + +static void +gst_vaapiencode_mpeg2_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2 (object); + + switch (prop_id) { + case PROP_RATE_CONTROL: + { + GstVaapiRateControl rate_control = g_value_get_enum (value); + if (rate_control == GST_VAAPI_RATECONTROL_CBR || + rate_control == GST_VAAPI_RATECONTROL_CQP) { + encode->rate_control = g_value_get_enum (value); + } else { + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } + break; + } + case PROP_BITRATE: + encode->bitrate = g_value_get_uint (value); + break; + 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); + break; + } +} + +static void +gst_vaapiencode_mpeg2_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) +{ + GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2 (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; + 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); + break; + } +} + +static GstVaapiEncoder * +gst_vaapiencode_mpeg2_create_encoder (GstVaapiEncode * base, + GstVaapiDisplay * display) +{ + GstVaapiEncodeMpeg2 *encode = GST_VAAPIENCODE_MPEG2 (base); + GstVaapiEncoder *ret; + GstVaapiEncoderMpeg2 *mpeg2encoder; + + ret = gst_vaapi_encoder_mpeg2_new (display); + mpeg2encoder = GST_VAAPI_ENCODER_MPEG2 (ret); + + mpeg2encoder->profile = GST_VAAPI_ENCODER_MPEG2_DEFAULT_PROFILE; + mpeg2encoder->level = GST_VAAPI_ENCODER_MPEG2_DEFAULT_LEVEL; + GST_VAAPI_ENCODER_RATE_CONTROL (mpeg2encoder) = encode->rate_control; + mpeg2encoder->bitrate = encode->bitrate; + mpeg2encoder->cqp = encode->quantizer; + mpeg2encoder->intra_period = encode->intra_period; + mpeg2encoder->ip_period = encode->ip_period; + + return ret; +} + +static void +gst_vaapiencode_mpeg2_class_init (GstVaapiEncodeMpeg2Class * klass) +{ + GObjectClass *const object_class = G_OBJECT_CLASS (klass); + GstElementClass *const element_class = GST_ELEMENT_CLASS (klass); + GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS (klass); + + GST_DEBUG_CATEGORY_INIT (gst_vaapi_mpeg2_encode_debug, + "vaapimpeg2encode", 0, "vaapimpeg2encode element"); + + object_class->finalize = gst_vaapiencode_mpeg2_finalize; + object_class->set_property = gst_vaapiencode_mpeg2_set_property; + object_class->get_property = gst_vaapiencode_mpeg2_get_property; + + encode_class->create_encoder = gst_vaapiencode_mpeg2_create_encoder; + + gst_element_class_set_static_metadata (element_class, + "VA-API mpeg2 encoder", + "Codec/Encoder/Video", + "A VA-API based video encoder", "Guangxin Xu "); + + /* sink pad */ + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_vaapiencode_mpeg2_sink_factory) + ); + + /* src pad */ + 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_RATE_CONTROL, + g_param_spec_enum ("rate-control", + "Rate Control", + "Rate control mode (CQP or CBR only)", + GST_VAAPI_TYPE_RATE_CONTROL, + GST_VAAPI_RATECONTROL_NONE, + 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, GST_VAAPI_ENCODER_MPEG2_MAX_BITRATE, 0, G_PARAM_READWRITE)); + + 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_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_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)); +} diff --git a/gst/vaapi/gstvaapiencode_mpeg2.h b/gst/vaapi/gstvaapiencode_mpeg2.h new file mode 100644 index 0000000..f6be378 --- /dev/null +++ b/gst/vaapi/gstvaapiencode_mpeg2.h @@ -0,0 +1,76 @@ +/* + * gstvaapiencode_mpeg2.h - VA-API MPEG2 encoder + * + * Copyright (C) 2012-2013 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef GST_VAAPIENCODE_MPEG2_H +#define GST_VAAPIENCODE_MPEG2_H + +#include +#include "gstvaapiencode.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VAAPIENCODE_MPEG2 \ + (gst_vaapiencode_mpeg2_get_type()) +#define GST_IS_VAAPIENCODE_MPEG2(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPIENCODE_MPEG2)) +#define GST_IS_VAAPIENCODE_MPEG2_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPIENCODE_MPEG2)) + +#define GST_VAAPIENCODE_MPEG2_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + GST_TYPE_VAAPIENCODE_MPEG2, \ + GstVaapiEncodeMpeg2Class)) + +#define GST_VAAPIENCODE_MPEG2(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + GST_TYPE_VAAPIENCODE_MPEG2, \ + GstVaapiEncodeMpeg2)) + +#define GST_VAAPIENCODE_MPEG2_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + GST_TYPE_VAAPIENCODE_MPEG2, \ + GstVaapiEncodeMpeg2Class)) + +typedef struct _GstVaapiEncodeMpeg2 GstVaapiEncodeMpeg2; +typedef struct _GstVaapiEncodeMpeg2Class GstVaapiEncodeMpeg2Class; + +struct _GstVaapiEncodeMpeg2 +{ + GstVaapiEncode parent; + + GstVaapiRateControl rate_control; + guint32 bitrate; /* kbps */ + guint32 quantizer; + guint32 intra_period; + guint32 ip_period; +}; + +struct _GstVaapiEncodeMpeg2Class +{ + GstVaapiEncodeClass parent_class; +}; + +GType +gst_vaapiencode_mpeg2_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* GST_VAAPIENCODE_MPEG2_H */ -- 2.7.4