/* GStreamer * Copyright (c) 2011, Texas Instruments Incorporated * Copyright (c) 2011, Collabora Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Author: Alessandro Decina */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "gstducati.h" #include "gstducatih264enc.h" #include #include #define GST_CAT_DEFAULT gst_ducati_debug #define DEFAULT_PROFILE GST_DUCATI_H264ENC_PROFILE_HIGH #define DEFAULT_LEVEL GST_DUCATI_H264ENC_LEVEL_40 #define DEFAULT_QPI 28 #define DEFAULT_QP_MAX_I 36 #define DEFAULT_QP_MIN_I 10 /* 2 x targetBitRate for VBR Rate Control */ #define DEFAULT_HRD_BUFFER_SIZE 40960000 #define DEFAULT_INTER_INTERVAL 4 #define GST_TYPE_DUCATI_H264ENC_PROFILE (gst_ducati_h264enc_profile_get_type ()) #define GST_TYPE_DUCATI_H264ENC_LEVEL (gst_ducati_h264enc_level_get_type ()) #define GST_TYPE_DUCATI_H264ENC_RCPP (gst_ducati_h264enc_get_rate_control_params_preset_type ()) #define GST_TYPE_DUCATI_H264ENC_RATE_CONTROL_ALGO (gst_ducati_h264enc_get_rate_control_algo_type ()) #define GST_TYPE_DUCATI_H264ENC_ENTROPY_CODING_MODE (gst_ducati_h264enc_get_entropy_coding_mode_type ()) #define GST_TYPE_DUCATI_H264ENC_SLICE_MODE (gst_ducati_h264enc_get_slice_mode_type ()) enum { LAST_SIGNAL }; enum { PROP_0, PROP_PROFILE, PROP_LEVEL, PROP_RATE_CONTROL_PARAMS_PRESET, PROP_RATE_CONTROL_ALGO, PROP_QPI, PROP_QP_MAX_I, PROP_QP_MIN_I, PROP_HRD_BUFFER_SIZE, PROP_ENTROPY_CODING_MODE, PROP_INTER_INTERVAL, PROP_SLICE_MODE, }; static void gst_ducati_h264enc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_ducati_h264enc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static gboolean gst_ducati_h264enc_allocate_params (GstDucatiVidEnc * self, gint params_sz, gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz); static gboolean gst_ducati_h264enc_configure (GstDucatiVidEnc * self); static gboolean gst_ducati_h264enc_is_sync_point (GstDucatiVidEnc * enc, int type); static GstStaticPadTemplate gst_ducati_h264enc_sink_template = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("NV12")) ); static GstStaticPadTemplate gst_ducati_h264enc_src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS ("video/x-h264, alignment=(string)au, stream-format=(string)byte-stream") ); GST_BOILERPLATE (GstDucatiH264Enc, gst_ducati_h264enc, GstDucatiVidEnc, GST_TYPE_DUCATIVIDENC); /* the values for the following enums are taken from the codec */ enum { GST_DUCATI_H264ENC_PROFILE_BASELINE = 66, /**< BaseLine Profile */ GST_DUCATI_H264ENC_PROFILE_MAIN = 77, /**< Main Profile */ GST_DUCATI_H264ENC_PROFILE_EXTENDED = 88, /**< Extended Profile */ GST_DUCATI_H264ENC_PROFILE_HIGH = 100, /**< High Profile */ GST_DUCATI_H264ENC_PROFILE_HIGH_10 = 110, /**< High 10 Profile */ GST_DUCATI_H264ENC_PROFILE_HIGH_422 = 122 /**< High 4:2:2 Profile */ }; enum { GST_DUCATI_H264ENC_LEVEL_10 = 10, /**< Level 1.0 */ GST_DUCATI_H264ENC_LEVEL_1b = 9, /**< Level 1.b */ GST_DUCATI_H264ENC_LEVEL_11 = 11, /**< Level 1.1 */ GST_DUCATI_H264ENC_LEVEL_12 = 12, /**< Level 1.2 */ GST_DUCATI_H264ENC_LEVEL_13 = 13, /**< Level 1.3 */ GST_DUCATI_H264ENC_LEVEL_20 = 20, /**< Level 2.0 */ GST_DUCATI_H264ENC_LEVEL_21 = 21, /**< Level 2.1 */ GST_DUCATI_H264ENC_LEVEL_22 = 22, /**< Level 2.2 */ GST_DUCATI_H264ENC_LEVEL_30 = 30, /**< Level 3.0 */ GST_DUCATI_H264ENC_LEVEL_31 = 31, /**< Level 3.1 */ GST_DUCATI_H264ENC_LEVEL_32 = 32, /**< Level 3.2 */ GST_DUCATI_H264ENC_LEVEL_40 = 40, /**< Level 4.0 */ GST_DUCATI_H264ENC_LEVEL_41 = 41, /**< Level 4.1 */ GST_DUCATI_H264ENC_LEVEL_42 = 42, /**< Level 4.2 */ GST_DUCATI_H264ENC_LEVEL_50 = 50, /**< Level 5.0 */ GST_DUCATI_H264ENC_LEVEL_51 = 51 /**< Level 5.1 */ }; static GType gst_ducati_h264enc_profile_get_type (void) { static GType type = 0; if (!type) { static const GEnumValue vals[] = { {GST_DUCATI_H264ENC_PROFILE_BASELINE, "Base Profile", "baseline"}, {GST_DUCATI_H264ENC_PROFILE_MAIN, "Main Profile", "main"}, {GST_DUCATI_H264ENC_PROFILE_EXTENDED, "Extended Profile", "extended"}, {GST_DUCATI_H264ENC_PROFILE_HIGH, "High Profile", "high"}, {GST_DUCATI_H264ENC_PROFILE_HIGH_10, "High 10 Profile", "high-10"}, {GST_DUCATI_H264ENC_PROFILE_HIGH_422, "High 4:2:2 Profile", "high-422"}, {0, NULL, NULL}, }; type = g_enum_register_static ("GstDucatiH264EncProfile", vals); } return type; } static GType gst_ducati_h264enc_get_rate_control_params_preset_type (void) { static GType type = 0; if (!type) { static const GEnumValue vals[] = { {IH264_RATECONTROLPARAMS_DEFAULT, "Rate Control params preset default", "rate-control-params-preset-default"}, {IH264_RATECONTROLPARAMS_USERDEFINED, "User defined rate control", "rate-control-params-preset-user-defined"}, {IH264_RATECONTROLPARAMS_EXISTING, "Existing rate control params", "rate-control-params-preset-existing"}, {IH264_RATECONTROLPARAMS_MAX, "Max rate control", "rate-control-params-preset-control"}, {0, NULL, NULL}, }; type = g_enum_register_static ("GstDucatiH264EncRateControlParams", vals); } return type; } static GType gst_ducati_h264enc_get_rate_control_algo_type (void) { static GType type = 0; if (!type) { static const GEnumValue vals[] = { {IH264_RATECONTROL_PRC, "Perceptual rate control", "perceptual-rate-control"}, {IH264_RATECONTROL_PRC_LOW_DELAY, "Low delay rate control", "low-delay-rate-control"}, {IH264_RATECONTROL_DEFAULT, "Default rcAlgo (PRC)", "default-rate-control"}, {0, NULL, NULL}, }; type = g_enum_register_static ("GstDucatiH264EncRateControlAlgo", vals); } return type; } static GType gst_ducati_h264enc_level_get_type (void) { static GType type = 0; if (!type) { static const GEnumValue vals[] = { {GST_DUCATI_H264ENC_LEVEL_10, "Level 1", "level-1"}, {GST_DUCATI_H264ENC_LEVEL_1b, "Level 1b", "level-1b"}, {GST_DUCATI_H264ENC_LEVEL_11, "Level 11", "level-11"}, {GST_DUCATI_H264ENC_LEVEL_12, "Level 12", "level-12"}, {GST_DUCATI_H264ENC_LEVEL_13, "Level 13", "level-13"}, {GST_DUCATI_H264ENC_LEVEL_20, "Level 2", "level-2"}, {GST_DUCATI_H264ENC_LEVEL_21, "Level 21", "level-21"}, {GST_DUCATI_H264ENC_LEVEL_22, "Level 22", "level-22"}, {GST_DUCATI_H264ENC_LEVEL_30, "Level 3", "level-3"}, {GST_DUCATI_H264ENC_LEVEL_31, "Level 31", "level-31"}, {GST_DUCATI_H264ENC_LEVEL_32, "Level 32", "level-32"}, {GST_DUCATI_H264ENC_LEVEL_40, "Level 4", "level-4"}, {GST_DUCATI_H264ENC_LEVEL_41, "Level 41", "level-41"}, {GST_DUCATI_H264ENC_LEVEL_42, "Level 42", "level-42"}, {GST_DUCATI_H264ENC_LEVEL_50, "Level 5", "level-5"}, {GST_DUCATI_H264ENC_LEVEL_51, "Level 51", "level-51"}, {0, NULL, NULL}, }; type = g_enum_register_static ("GstDucatiH264EncLevel", vals); } return type; } static GType gst_ducati_h264enc_get_entropy_coding_mode_type (void) { static GType type = 0; if (!type) { static const GEnumValue vals[] = { {IH264_ENTROPYCODING_CAVLC, "CAVLC coding type", "cavlc"}, {IH264_ENTROPYCODING_DEFAULT, "Default coding type (cavlc)", "default"}, {IH264_ENTROPYCODING_CABAC, "Cabac coding mode", "cabac"}, {0, NULL, NULL}, }; type = g_enum_register_static ("GstDucatiEntropyCodingMode", vals); } return type; } static GType gst_ducati_h264enc_get_slice_mode_type (void) { static GType type = 0; if (!type) { static const GEnumValue vals[] = { {IH264_SLICEMODE_NONE, "No slice mode", "none"}, {IH264_SLICEMODE_DEFAULT, "Default slice coding mode is MB based", "default"}, {IH264_SLICEMODE_MBUNIT, "Slices are controlled based upon number of Macroblocks", "mbunit"}, {IH264_SLICEMODE_BYTES, "Slices are controlled based upon number of bytes", "bytes"}, {IH264_SLICEMODE_OFFSET, "Slices are controlled based upon user defined offset unit of Row", "offset"}, {0, NULL, NULL}, }; type = g_enum_register_static ("GstDucatiSliceMode", vals); } return type; } static void gst_ducati_h264enc_base_init (gpointer g_class) { GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&gst_ducati_h264enc_src_template)); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&gst_ducati_h264enc_sink_template)); gst_element_class_set_details_simple (element_class, "H264 Encoder", "Codec/Encoder/Video", "Encode raw video into H264 stream", "Alessandro Decina "); GST_DUCATIVIDENC_CLASS (element_class)->codec_name = "ivahd_h264enc"; } static void gst_ducati_h264enc_class_init (GstDucatiH264EncClass * klass) { GObjectClass *gobject_class; GstDucatiVidEncClass *videnc_class; gobject_class = G_OBJECT_CLASS (klass); videnc_class = GST_DUCATIVIDENC_CLASS (klass); gobject_class->set_property = gst_ducati_h264enc_set_property; gobject_class->get_property = gst_ducati_h264enc_get_property; videnc_class->allocate_params = gst_ducati_h264enc_allocate_params; videnc_class->configure = gst_ducati_h264enc_configure; videnc_class->is_sync_point = gst_ducati_h264enc_is_sync_point; g_object_class_install_property (gobject_class, PROP_PROFILE, g_param_spec_enum ("profile", "H.264 Profile", "H.264 Profile", GST_TYPE_DUCATI_H264ENC_PROFILE, DEFAULT_PROFILE, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_LEVEL, g_param_spec_enum ("level", "H.264 Level", "H.264 Level", GST_TYPE_DUCATI_H264ENC_LEVEL, DEFAULT_LEVEL, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_INTER_INTERVAL, g_param_spec_uint ("inter-interval", "Inter-frame interval", "Max inter frame interval (B frames are allowed between them if > 1)", 1, 31, DEFAULT_INTER_INTERVAL, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_RATE_CONTROL_PARAMS_PRESET, g_param_spec_enum ("rate-control-params-preset", "H.264 rate control params preset", "This preset controls the USER_DEFINED versus " "DEFAULT mode. If you are not aware about the " "fields, it should be set as IH264_RATECONTROLPARAMS_DEFAULT", GST_TYPE_DUCATI_H264ENC_RCPP, IH264_RATECONTROLPARAMS_DEFAULT, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_RATE_CONTROL_ALGO, g_param_spec_enum ("rate-control-algo", "H.264 rate control algorithm", "This defines the rate control algorithm to be used. Only useful if " " 'rate-control-params-preset' is set as " "'rate-control-params-preset-user-defined'", GST_TYPE_DUCATI_H264ENC_RATE_CONTROL_ALGO, IH264_RATECONTROL_DEFAULT, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_QPI, g_param_spec_int ("qpi", "Initial quantization parameter", "Initial quantization parameter for I/IDR frames.", -1, 51, DEFAULT_QPI, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_QP_MIN_I, g_param_spec_int ("qp-min-i", "Minimum quantization parameter", "Minimum quantization parameter for I/IDR frames.", 0, 51, DEFAULT_QP_MIN_I, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_QP_MAX_I, g_param_spec_int ("qp-max-i", "Maximum quantization parameter", "Maximum quantization parameter for I/IDR frames.", 0, 51, DEFAULT_QP_MAX_I, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_HRD_BUFFER_SIZE, g_param_spec_uint ("hrd-buffer-size", "Hypothetical reference decoder buffer size", "Hypothetical reference decoder buffer size. This " "size controls the frame skip logic of the encoder. " "For low delay applications this size should be " "small. This size is in bits. Maximum Value is level " "dependant and min value is 4096", 4096, G_MAXUINT, DEFAULT_HRD_BUFFER_SIZE, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_ENTROPY_CODING_MODE, g_param_spec_enum ("entropy-coding-mode", "H.264 entropy coding mode", "Controls the entropy coding type.", GST_TYPE_DUCATI_H264ENC_ENTROPY_CODING_MODE, IH264_ENTROPYCODING_DEFAULT, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_SLICE_MODE, g_param_spec_enum ("slice-mode", "H.264 slice mode", "This defines the control mechanism to split a picture in slices." " It can be either MB based or bytes based", GST_TYPE_DUCATI_H264ENC_SLICE_MODE, IH264_SLICEMODE_DEFAULT, G_PARAM_READWRITE)); } static void gst_ducati_h264enc_init (GstDucatiH264Enc * self, GstDucatiH264EncClass * klass) { GST_DEBUG ("gst_ducati_h264enc_init"); self->profile = DEFAULT_PROFILE; self->level = DEFAULT_LEVEL; self->rate_control_params_preset = IH264_RATECONTROLPARAMS_DEFAULT; self->rate_control_algo = IH264_RATECONTROL_DEFAULT; self->qpi = DEFAULT_QPI; self->qp_min_i = DEFAULT_QP_MIN_I; self->qp_max_i = DEFAULT_QP_MAX_I; self->hrd_buffer_size = DEFAULT_HRD_BUFFER_SIZE; self->inter_interval = DEFAULT_INTER_INTERVAL; } static void gst_ducati_h264enc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstDucatiH264Enc *self = GST_DUCATIH264ENC (object); GstDucatiVidEnc *venc = GST_DUCATIVIDENC (object); IH264ENC_DynamicParams *dynParams = (IH264ENC_DynamicParams *) venc->dynParams; self = GST_DUCATIH264ENC (object); switch (prop_id) { case PROP_PROFILE: self->profile = g_value_get_enum (value); break; case PROP_LEVEL: self->level = g_value_get_enum (value); break; case PROP_RATE_CONTROL_PARAMS_PRESET: self->rate_control_params_preset = g_value_get_enum (value); if (dynParams) dynParams->rateControlParams.rateControlParamsPreset = self->rate_control_params_preset; break; case PROP_RATE_CONTROL_ALGO: self->rate_control_algo = g_value_get_enum (value); if (self->rate_control_params_preset != IH264_RATECONTROLPARAMS_USERDEFINED) GST_INFO_OBJECT (self, "Setting rcAlgo but rateControlParamsPreset not " "'rate-control-params-preset-user-defined' config won't be taken " "into account"); if (dynParams) dynParams->rateControlParams.rcAlgo = self->rate_control_algo; break; case PROP_QPI: self->qpi = g_value_get_int (value); if (dynParams) dynParams->rateControlParams.qpI = self->qpi; break; case PROP_QP_MIN_I: self->qp_min_i = g_value_get_int (value); if (dynParams) dynParams->rateControlParams.qpMinI = self->qp_min_i; break; case PROP_QP_MAX_I: self->qp_max_i = g_value_get_int (value); if (dynParams) dynParams->rateControlParams.qpMaxI = self->qp_max_i; break; case PROP_HRD_BUFFER_SIZE: self->hrd_buffer_size = g_value_get_uint (value); break; case PROP_ENTROPY_CODING_MODE: self->entropy_coding_mode = g_value_get_enum (value); break; case PROP_SLICE_MODE: self->slice_mode = g_value_get_enum (value); break; case PROP_INTER_INTERVAL: self->inter_interval = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void gst_ducati_h264enc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstDucatiH264Enc *self = GST_DUCATIH264ENC (object); g_return_if_fail (GST_IS_DUCATIH264ENC (object)); self = GST_DUCATIH264ENC (object); switch (prop_id) { case PROP_PROFILE: g_value_set_enum (value, self->profile); break; case PROP_LEVEL: g_value_set_enum (value, self->level); break; case PROP_RATE_CONTROL_PARAMS_PRESET: g_value_set_enum (value, self->rate_control_params_preset); break; case PROP_RATE_CONTROL_ALGO: g_value_set_enum (value, self->rate_control_algo); break; case PROP_QPI: g_value_set_int (value, self->qpi); break; case PROP_QP_MIN_I: g_value_set_int (value, self->qp_min_i); break; case PROP_QP_MAX_I: g_value_set_int (value, self->qp_max_i); break; case PROP_HRD_BUFFER_SIZE: g_value_set_uint (value, self->hrd_buffer_size); break; case PROP_ENTROPY_CODING_MODE: g_value_set_enum (value, self->entropy_coding_mode); break; case PROP_SLICE_MODE: g_value_set_enum (value, self->slice_mode); break; case PROP_INTER_INTERVAL: g_value_set_uint (value, self->inter_interval); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static const char * get_profile_name (guint profile) { switch (profile) { case GST_DUCATI_H264ENC_PROFILE_BASELINE: return "baseline"; case GST_DUCATI_H264ENC_PROFILE_MAIN: return "main"; case GST_DUCATI_H264ENC_PROFILE_EXTENDED: return "extended"; case GST_DUCATI_H264ENC_PROFILE_HIGH: return "high"; case GST_DUCATI_H264ENC_PROFILE_HIGH_10: return "high-10"; case GST_DUCATI_H264ENC_PROFILE_HIGH_422: return "high-422"; default: return NULL; } } static const char * get_level_name (guint level) { switch (level) { case GST_DUCATI_H264ENC_LEVEL_10: return "1"; case GST_DUCATI_H264ENC_LEVEL_1b: return "1b"; case GST_DUCATI_H264ENC_LEVEL_11: return "1.1"; case GST_DUCATI_H264ENC_LEVEL_12: return "1.2"; case GST_DUCATI_H264ENC_LEVEL_13: return "1.3"; case GST_DUCATI_H264ENC_LEVEL_20: return "2"; case GST_DUCATI_H264ENC_LEVEL_21: return "2.1"; case GST_DUCATI_H264ENC_LEVEL_22: return "2.2"; case GST_DUCATI_H264ENC_LEVEL_30: return "3"; case GST_DUCATI_H264ENC_LEVEL_31: return "3.1"; case GST_DUCATI_H264ENC_LEVEL_32: return "3.2"; case GST_DUCATI_H264ENC_LEVEL_40: return "4"; case GST_DUCATI_H264ENC_LEVEL_41: return "4.1"; case GST_DUCATI_H264ENC_LEVEL_42: return "4.2"; case GST_DUCATI_H264ENC_LEVEL_50: return "5"; case GST_DUCATI_H264ENC_LEVEL_51: return "5.1"; default: return NULL; } } static gboolean gst_ducati_h264enc_configure (GstDucatiVidEnc * videnc) { GstDucatiH264Enc *self = GST_DUCATIH264ENC (videnc); IH264ENC_Params *params; IH264ENC_DynamicParams *dynParams; gboolean ret; const char *s; videnc->params->profile = self->profile; videnc->params->level = self->level; params = (IH264ENC_Params *) videnc->params; /* this is the only non-base field strictly required */ params->maxIntraFrameInterval = 0x7fffffff; params->IDRFrameInterval = 1; params->numTemporalLayer = 1; params->entropyCodingMode = self->entropy_coding_mode; videnc->params->maxInterFrameInterval = self->inter_interval; /* Dynamic params */ dynParams = (IH264ENC_DynamicParams *) videnc->dynParams; dynParams->rateControlParams.rateControlParamsPreset = self->rate_control_params_preset; dynParams->rateControlParams.rcAlgo = self->rate_control_algo; dynParams->rateControlParams.qpI = self->qpi; dynParams->rateControlParams.qpMaxI = self->qp_max_i; dynParams->rateControlParams.qpMinI = self->qp_min_i; dynParams->rateControlParams.HRDBufferSize = self->hrd_buffer_size; dynParams->sliceCodingParams.sliceMode = self->slice_mode; ret = GST_DUCATIVIDENC_CLASS (parent_class)->configure (videnc); if (ret) { const GstVideoState *state = gst_base_video_encoder_get_state (GST_BASE_VIDEO_ENCODER (videnc)); GstCaps *caps = gst_caps_new_simple ("video/x-h264", "width", G_TYPE_INT, videnc->rect.w, "height", G_TYPE_INT, videnc->rect.h, "framerate", GST_TYPE_FRACTION, state->fps_n, state->fps_d, "pixel-aspect-ratio", GST_TYPE_FRACTION, state->par_n, state->par_d, "stream-format", G_TYPE_STRING, "byte-stream", "align", G_TYPE_STRING, "au", NULL); s = get_profile_name (self->profile); if (s) gst_caps_set_simple (caps, "profile", G_TYPE_STRING, s, NULL); s = get_level_name (self->level); if (s) gst_caps_set_simple (caps, "level", G_TYPE_STRING, s, NULL); ret = gst_pad_set_caps (GST_BASE_VIDEO_CODEC_SRC_PAD (self), caps); } return ret; } static gboolean gst_ducati_h264enc_allocate_params (GstDucatiVidEnc * videnc, gint params_sz, gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz) { gboolean ret = GST_DUCATIVIDENC_CLASS (parent_class)->allocate_params (videnc, sizeof (IH264ENC_Params), sizeof (IH264ENC_DynamicParams), sizeof (IVIDENC2_Status), sizeof (IVIDENC2_InArgs), sizeof (IVIDENC2_OutArgs)); GstDucatiH264Enc *self = GST_DUCATIH264ENC (videnc); if (ret == TRUE) { IH264ENC_DynamicParams *dynParams = (IH264ENC_DynamicParams *) videnc->dynParams; dynParams->rateControlParams.rateControlParamsPreset = self->rate_control_params_preset; dynParams->rateControlParams.rcAlgo = self->rate_control_algo; dynParams->rateControlParams.qpI = self->qpi; dynParams->rateControlParams.qpMaxI = self->qp_max_i; dynParams->rateControlParams.qpMinI = self->qp_min_i; dynParams->rateControlParams.HRDBufferSize = self->hrd_buffer_size; dynParams->sliceCodingParams.sliceMode = self->slice_mode; } return ret; } static gboolean gst_ducati_h264enc_is_sync_point (GstDucatiVidEnc * enc, int type) { return type == IVIDEO_IDR_FRAME; }