videnc: Take into account cropping when configuring the codec
[gstreamer-omap:gst-ducati.git] / src / gstducatih264enc.c
1 /* GStreamer
2  * Copyright (c) 2011, Texas Instruments Incorporated
3  * Copyright (c) 2011, Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alessandro Decina <alessandro.decina@collabora.com>
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "gstducati.h"
28 #include "gstducatih264enc.h"
29
30 #include <string.h>
31
32 #include <math.h>
33
34 #define GST_CAT_DEFAULT gst_ducati_debug
35
36 #define DEFAULT_PROFILE GST_DUCATI_H264ENC_PROFILE_HIGH
37 #define DEFAULT_LEVEL GST_DUCATI_H264ENC_LEVEL_40
38 #define DEFAULT_QPI 28
39 #define DEFAULT_QP_MAX_I 36
40 #define DEFAULT_QP_MIN_I 10
41 /* 2 x targetBitRate for VBR Rate Control */
42 #define DEFAULT_HRD_BUFFER_SIZE 40960000
43 #define DEFAULT_INTER_INTERVAL 4
44
45 #define GST_TYPE_DUCATI_H264ENC_PROFILE (gst_ducati_h264enc_profile_get_type ())
46 #define GST_TYPE_DUCATI_H264ENC_LEVEL (gst_ducati_h264enc_level_get_type ())
47 #define GST_TYPE_DUCATI_H264ENC_RCPP (gst_ducati_h264enc_get_rate_control_params_preset_type ())
48 #define GST_TYPE_DUCATI_H264ENC_RATE_CONTROL_ALGO (gst_ducati_h264enc_get_rate_control_algo_type ())
49 #define GST_TYPE_DUCATI_H264ENC_ENTROPY_CODING_MODE (gst_ducati_h264enc_get_entropy_coding_mode_type ())
50 #define GST_TYPE_DUCATI_H264ENC_SLICE_MODE (gst_ducati_h264enc_get_slice_mode_type ())
51
52
53 enum
54 {
55   LAST_SIGNAL
56 };
57
58 enum
59 {
60   PROP_0,
61   PROP_PROFILE,
62   PROP_LEVEL,
63   PROP_RATE_CONTROL_PARAMS_PRESET,
64   PROP_RATE_CONTROL_ALGO,
65   PROP_QPI,
66   PROP_QP_MAX_I,
67   PROP_QP_MIN_I,
68   PROP_HRD_BUFFER_SIZE,
69   PROP_ENTROPY_CODING_MODE,
70   PROP_INTER_INTERVAL,
71   PROP_SLICE_MODE,
72 };
73
74 static void gst_ducati_h264enc_set_property (GObject * object, guint prop_id,
75     const GValue * value, GParamSpec * pspec);
76 static void gst_ducati_h264enc_get_property (GObject * object, guint prop_id,
77     GValue * value, GParamSpec * pspec);
78
79 static gboolean gst_ducati_h264enc_allocate_params (GstDucatiVidEnc *
80     self, gint params_sz, gint dynparams_sz, gint status_sz, gint inargs_sz,
81     gint outargs_sz);
82 static gboolean gst_ducati_h264enc_configure (GstDucatiVidEnc * self,
83     GstCaps ** caps);
84 static gboolean gst_ducati_h264enc_is_sync_point (GstDucatiVidEnc * enc,
85     int type);
86
87
88 static GstStaticPadTemplate gst_ducati_h264enc_sink_template =
89 GST_STATIC_PAD_TEMPLATE ("sink",
90     GST_PAD_SINK,
91     GST_PAD_ALWAYS,
92     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("NV12"))
93     );
94
95 static GstStaticPadTemplate gst_ducati_h264enc_src_template =
96 GST_STATIC_PAD_TEMPLATE ("src",
97     GST_PAD_SRC,
98     GST_PAD_ALWAYS,
99     GST_STATIC_CAPS
100     ("video/x-h264, alignment=(string)au, stream-format=(string)byte-stream")
101     );
102
103 #define gst_ducati_h264enc_parent_class parent_class
104 G_DEFINE_TYPE (GstDucatiH264Enc, gst_ducati_h264enc, GST_TYPE_DUCATIVIDENC);
105
106 /* the values for the following enums are taken from the codec */
107 enum
108 {
109   GST_DUCATI_H264ENC_PROFILE_BASELINE = 66,            /**< BaseLine Profile   */
110   GST_DUCATI_H264ENC_PROFILE_MAIN = 77,                /**< Main Profile       */
111   GST_DUCATI_H264ENC_PROFILE_EXTENDED = 88,            /**< Extended Profile   */
112   GST_DUCATI_H264ENC_PROFILE_HIGH = 100,               /**< High Profile       */
113   GST_DUCATI_H264ENC_PROFILE_HIGH_10 = 110,             /**< High 10 Profile    */
114   GST_DUCATI_H264ENC_PROFILE_HIGH_422 = 122             /**< High 4:2:2 Profile */
115 };
116
117 enum
118 {
119   GST_DUCATI_H264ENC_LEVEL_10 = 10, /**<  Level 1.0  */
120   GST_DUCATI_H264ENC_LEVEL_1b = 9,  /**<  Level 1.b  */
121   GST_DUCATI_H264ENC_LEVEL_11 = 11, /**<  Level 1.1  */
122   GST_DUCATI_H264ENC_LEVEL_12 = 12, /**<  Level 1.2  */
123   GST_DUCATI_H264ENC_LEVEL_13 = 13, /**<  Level 1.3  */
124   GST_DUCATI_H264ENC_LEVEL_20 = 20, /**<  Level 2.0  */
125   GST_DUCATI_H264ENC_LEVEL_21 = 21, /**<  Level 2.1  */
126   GST_DUCATI_H264ENC_LEVEL_22 = 22, /**<  Level 2.2  */
127   GST_DUCATI_H264ENC_LEVEL_30 = 30, /**<  Level 3.0  */
128   GST_DUCATI_H264ENC_LEVEL_31 = 31, /**<  Level 3.1  */
129   GST_DUCATI_H264ENC_LEVEL_32 = 32, /**<  Level 3.2  */
130   GST_DUCATI_H264ENC_LEVEL_40 = 40, /**<  Level 4.0  */
131   GST_DUCATI_H264ENC_LEVEL_41 = 41, /**<  Level 4.1  */
132   GST_DUCATI_H264ENC_LEVEL_42 = 42, /**<  Level 4.2  */
133   GST_DUCATI_H264ENC_LEVEL_50 = 50, /**<  Level 5.0  */
134   GST_DUCATI_H264ENC_LEVEL_51 = 51 /**<  Level 5.1  */
135 };
136
137 static GType
138 gst_ducati_h264enc_profile_get_type (void)
139 {
140   static GType type = 0;
141
142   if (!type) {
143     static const GEnumValue vals[] = {
144       {GST_DUCATI_H264ENC_PROFILE_BASELINE, "Base Profile", "baseline"},
145       {GST_DUCATI_H264ENC_PROFILE_MAIN, "Main Profile", "main"},
146       {GST_DUCATI_H264ENC_PROFILE_EXTENDED, "Extended Profile", "extended"},
147       {GST_DUCATI_H264ENC_PROFILE_HIGH, "High Profile", "high"},
148       {GST_DUCATI_H264ENC_PROFILE_HIGH_10, "High 10 Profile", "high-10"},
149       {GST_DUCATI_H264ENC_PROFILE_HIGH_422, "High 4:2:2 Profile", "high-422"},
150       {0, NULL, NULL},
151     };
152
153     type = g_enum_register_static ("GstDucatiH264EncProfile", vals);
154   }
155
156   return type;
157 }
158
159 static GType
160 gst_ducati_h264enc_get_rate_control_params_preset_type (void)
161 {
162   static GType type = 0;
163
164   if (!type) {
165     static const GEnumValue vals[] = {
166       {IH264_RATECONTROLPARAMS_DEFAULT, "Rate Control params preset default",
167           "rate-control-params-preset-default"},
168       {IH264_RATECONTROLPARAMS_USERDEFINED, "User defined rate control",
169           "rate-control-params-preset-user-defined"},
170       {IH264_RATECONTROLPARAMS_EXISTING, "Existing rate control params",
171           "rate-control-params-preset-existing"},
172       {IH264_RATECONTROLPARAMS_MAX, "Max rate control",
173           "rate-control-params-preset-control"},
174       {0, NULL, NULL},
175     };
176
177     type = g_enum_register_static ("GstDucatiH264EncRateControlParams", vals);
178   }
179
180   return type;
181 }
182
183 static GType
184 gst_ducati_h264enc_get_rate_control_algo_type (void)
185 {
186   static GType type = 0;
187
188   if (!type) {
189     static const GEnumValue vals[] = {
190       {IH264_RATECONTROL_PRC, "Perceptual rate control",
191           "perceptual-rate-control"},
192       {IH264_RATECONTROL_PRC_LOW_DELAY, "Low delay rate control",
193           "low-delay-rate-control"},
194       {IH264_RATECONTROL_DEFAULT, "Default rcAlgo (PRC)",
195           "default-rate-control"},
196       {0, NULL, NULL},
197     };
198
199     type = g_enum_register_static ("GstDucatiH264EncRateControlAlgo", vals);
200   }
201
202   return type;
203 }
204
205 static GType
206 gst_ducati_h264enc_level_get_type (void)
207 {
208   static GType type = 0;
209
210   if (!type) {
211     static const GEnumValue vals[] = {
212       {GST_DUCATI_H264ENC_LEVEL_10, "Level 1", "level-1"},
213       {GST_DUCATI_H264ENC_LEVEL_1b, "Level 1b", "level-1b"},
214       {GST_DUCATI_H264ENC_LEVEL_11, "Level 11", "level-11"},
215       {GST_DUCATI_H264ENC_LEVEL_12, "Level 12", "level-12"},
216       {GST_DUCATI_H264ENC_LEVEL_13, "Level 13", "level-13"},
217       {GST_DUCATI_H264ENC_LEVEL_20, "Level 2", "level-2"},
218       {GST_DUCATI_H264ENC_LEVEL_21, "Level 21", "level-21"},
219       {GST_DUCATI_H264ENC_LEVEL_22, "Level 22", "level-22"},
220       {GST_DUCATI_H264ENC_LEVEL_30, "Level 3", "level-3"},
221       {GST_DUCATI_H264ENC_LEVEL_31, "Level 31", "level-31"},
222       {GST_DUCATI_H264ENC_LEVEL_32, "Level 32", "level-32"},
223       {GST_DUCATI_H264ENC_LEVEL_40, "Level 4", "level-4"},
224       {GST_DUCATI_H264ENC_LEVEL_41, "Level 41", "level-41"},
225       {GST_DUCATI_H264ENC_LEVEL_42, "Level 42", "level-42"},
226       {GST_DUCATI_H264ENC_LEVEL_50, "Level 5", "level-5"},
227       {GST_DUCATI_H264ENC_LEVEL_51, "Level 51", "level-51"},
228       {0, NULL, NULL},
229     };
230
231     type = g_enum_register_static ("GstDucatiH264EncLevel", vals);
232   }
233
234   return type;
235 }
236
237 static GType
238 gst_ducati_h264enc_get_entropy_coding_mode_type (void)
239 {
240   static GType type = 0;
241
242   if (!type) {
243     static const GEnumValue vals[] = {
244       {IH264_ENTROPYCODING_CAVLC, "CAVLC coding type", "cavlc"},
245       {IH264_ENTROPYCODING_DEFAULT, "Default coding type (cavlc)", "default"},
246       {IH264_ENTROPYCODING_CABAC, "Cabac coding mode", "cabac"},
247       {0, NULL, NULL},
248     };
249
250     type = g_enum_register_static ("GstDucatiEntropyCodingMode", vals);
251   }
252
253   return type;
254 }
255
256 static GType
257 gst_ducati_h264enc_get_slice_mode_type (void)
258 {
259   static GType type = 0;
260
261   if (!type) {
262     static const GEnumValue vals[] = {
263       {IH264_SLICEMODE_NONE, "No slice mode", "none"},
264       {IH264_SLICEMODE_DEFAULT, "Default slice coding mode is MB based",
265           "default"},
266       {IH264_SLICEMODE_MBUNIT,
267           "Slices are controlled based upon number of Macroblocks", "mbunit"},
268       {IH264_SLICEMODE_BYTES,
269           "Slices are controlled based upon number of bytes", "bytes"},
270       {IH264_SLICEMODE_OFFSET,
271             "Slices are controlled based upon user defined offset unit of Row",
272           "offset"},
273       {0, NULL, NULL},
274     };
275
276     type = g_enum_register_static ("GstDucatiSliceMode", vals);
277   }
278
279   return type;
280 }
281
282 static void
283 gst_ducati_h264enc_class_init (GstDucatiH264EncClass * klass)
284 {
285   GObjectClass *gobject_class;
286   GstElementClass *element_class;
287   GstDucatiVidEncClass *videnc_class;
288
289   gobject_class = G_OBJECT_CLASS (klass);
290   element_class = GST_ELEMENT_CLASS (klass);
291   videnc_class = GST_DUCATIVIDENC_CLASS (klass);
292
293   gobject_class->set_property = gst_ducati_h264enc_set_property;
294   gobject_class->get_property = gst_ducati_h264enc_get_property;
295
296   gst_element_class_add_pad_template (element_class,
297       gst_static_pad_template_get (&gst_ducati_h264enc_src_template));
298   gst_element_class_add_pad_template (element_class,
299       gst_static_pad_template_get (&gst_ducati_h264enc_sink_template));
300
301   gst_element_class_set_static_metadata (element_class, "H264 Encoder",
302       "Codec/Encoder/Video", "Encode raw video into H264 stream",
303       "Alessandro Decina <alessandro.decina@collabora.com>");
304
305   videnc_class->codec_name = "ivahd_h264enc";
306   videnc_class->allocate_params = gst_ducati_h264enc_allocate_params;
307   videnc_class->configure = gst_ducati_h264enc_configure;
308   videnc_class->is_sync_point = gst_ducati_h264enc_is_sync_point;
309
310   g_object_class_install_property (gobject_class, PROP_PROFILE,
311       g_param_spec_enum ("profile", "H.264 Profile", "H.264 Profile",
312           GST_TYPE_DUCATI_H264ENC_PROFILE, DEFAULT_PROFILE, G_PARAM_READWRITE));
313
314   g_object_class_install_property (gobject_class, PROP_LEVEL,
315       g_param_spec_enum ("level", "H.264 Level", "H.264 Level",
316           GST_TYPE_DUCATI_H264ENC_LEVEL, DEFAULT_LEVEL, G_PARAM_READWRITE));
317
318   g_object_class_install_property (gobject_class, PROP_INTER_INTERVAL,
319       g_param_spec_uint ("inter-interval", "Inter-frame interval",
320           "Max inter frame interval (B frames are allowed between them if > 1)",
321           1, 31, DEFAULT_INTER_INTERVAL, G_PARAM_READWRITE));
322
323   g_object_class_install_property (gobject_class,
324       PROP_RATE_CONTROL_PARAMS_PRESET,
325       g_param_spec_enum ("rate-control-params-preset",
326           "H.264 rate control params preset",
327           "This preset controls the USER_DEFINED versus "
328           "DEFAULT mode. If you are not aware about the "
329           "fields, it should be set as IH264_RATECONTROLPARAMS_DEFAULT",
330           GST_TYPE_DUCATI_H264ENC_RCPP, IH264_RATECONTROLPARAMS_DEFAULT,
331           G_PARAM_READWRITE));
332
333   g_object_class_install_property (gobject_class, PROP_RATE_CONTROL_ALGO,
334       g_param_spec_enum ("rate-control-algo", "H.264 rate control algorithm",
335           "This defines the rate control algorithm to be used. Only useful if "
336           " 'rate-control-params-preset' is set as "
337           "'rate-control-params-preset-user-defined'",
338           GST_TYPE_DUCATI_H264ENC_RATE_CONTROL_ALGO, IH264_RATECONTROL_DEFAULT,
339           G_PARAM_READWRITE));
340
341   g_object_class_install_property (gobject_class, PROP_QPI,
342       g_param_spec_int ("qpi", "Initial quantization parameter",
343           "Initial quantization parameter for I/IDR frames.", -1, 51,
344           DEFAULT_QPI, G_PARAM_READWRITE));
345
346   g_object_class_install_property (gobject_class, PROP_QP_MIN_I,
347       g_param_spec_int ("qp-min-i", "Minimum quantization parameter",
348           "Minimum quantization parameter for I/IDR frames.", 0, 51,
349           DEFAULT_QP_MIN_I, G_PARAM_READWRITE));
350
351   g_object_class_install_property (gobject_class, PROP_QP_MAX_I,
352       g_param_spec_int ("qp-max-i", "Maximum quantization parameter",
353           "Maximum quantization parameter for I/IDR frames.", 0, 51,
354           DEFAULT_QP_MAX_I, G_PARAM_READWRITE));
355
356   g_object_class_install_property (gobject_class, PROP_HRD_BUFFER_SIZE,
357       g_param_spec_uint ("hrd-buffer-size",
358           "Hypothetical reference decoder buffer size",
359           "Hypothetical reference decoder buffer size. This "
360           "size controls the frame skip logic of the encoder. "
361           "For low delay applications this size should be "
362           "small. This size is in bits. Maximum Value is level "
363           "dependant and min value is 4096",
364           4096, G_MAXUINT, DEFAULT_HRD_BUFFER_SIZE, G_PARAM_READWRITE));
365
366   g_object_class_install_property (gobject_class, PROP_ENTROPY_CODING_MODE,
367       g_param_spec_enum ("entropy-coding-mode", "H.264 entropy coding mode",
368           "Controls the entropy coding type.",
369           GST_TYPE_DUCATI_H264ENC_ENTROPY_CODING_MODE,
370           IH264_ENTROPYCODING_DEFAULT, G_PARAM_READWRITE));
371
372   g_object_class_install_property (gobject_class, PROP_SLICE_MODE,
373       g_param_spec_enum ("slice-mode", "H.264 slice mode",
374           "This defines the control mechanism to split a picture in slices."
375           " It can be either MB based or bytes based",
376           GST_TYPE_DUCATI_H264ENC_SLICE_MODE,
377           IH264_SLICEMODE_DEFAULT, G_PARAM_READWRITE));
378
379 }
380
381 static void
382 gst_ducati_h264enc_init (GstDucatiH264Enc * self)
383 {
384   GST_DEBUG ("gst_ducati_h264enc_init");
385
386   self->profile = DEFAULT_PROFILE;
387   self->level = DEFAULT_LEVEL;
388   self->rate_control_params_preset = IH264_RATECONTROLPARAMS_DEFAULT;
389   self->rate_control_algo = IH264_RATECONTROL_DEFAULT;
390   self->qpi = DEFAULT_QPI;
391   self->qp_min_i = DEFAULT_QP_MIN_I;
392   self->qp_max_i = DEFAULT_QP_MAX_I;
393   self->hrd_buffer_size = DEFAULT_HRD_BUFFER_SIZE;
394   self->inter_interval = DEFAULT_INTER_INTERVAL;
395 }
396
397 static void
398 gst_ducati_h264enc_set_property (GObject * object, guint prop_id,
399     const GValue * value, GParamSpec * pspec)
400 {
401   GstDucatiH264Enc *self = GST_DUCATIH264ENC (object);
402   GstDucatiVidEnc *venc = GST_DUCATIVIDENC (object);
403   IH264ENC_DynamicParams *dynParams =
404       (IH264ENC_DynamicParams *) venc->dynParams;
405
406   self = GST_DUCATIH264ENC (object);
407
408   switch (prop_id) {
409     case PROP_PROFILE:
410       self->profile = g_value_get_enum (value);
411       break;
412     case PROP_LEVEL:
413       self->level = g_value_get_enum (value);
414       break;
415     case PROP_RATE_CONTROL_PARAMS_PRESET:
416       self->rate_control_params_preset = g_value_get_enum (value);
417       if (dynParams)
418         dynParams->rateControlParams.rateControlParamsPreset =
419             self->rate_control_params_preset;
420       break;
421     case PROP_RATE_CONTROL_ALGO:
422       self->rate_control_algo = g_value_get_enum (value);
423
424       if (self->rate_control_params_preset !=
425           IH264_RATECONTROLPARAMS_USERDEFINED)
426         GST_INFO_OBJECT (self,
427             "Setting rcAlgo but rateControlParamsPreset not "
428             "'rate-control-params-preset-user-defined' config won't be taken "
429             "into account");
430
431       if (dynParams)
432         dynParams->rateControlParams.rcAlgo = self->rate_control_algo;
433       break;
434     case PROP_QPI:
435       self->qpi = g_value_get_int (value);
436       if (dynParams)
437         dynParams->rateControlParams.qpI = self->qpi;
438
439       break;
440     case PROP_QP_MIN_I:
441       self->qp_min_i = g_value_get_int (value);
442       if (dynParams)
443         dynParams->rateControlParams.qpMinI = self->qp_min_i;
444       break;
445     case PROP_QP_MAX_I:
446       self->qp_max_i = g_value_get_int (value);
447       if (dynParams)
448         dynParams->rateControlParams.qpMaxI = self->qp_max_i;
449       break;
450     case PROP_HRD_BUFFER_SIZE:
451       self->hrd_buffer_size = g_value_get_uint (value);
452       break;
453     case PROP_ENTROPY_CODING_MODE:
454       self->entropy_coding_mode = g_value_get_enum (value);
455       break;
456     case PROP_SLICE_MODE:
457       self->slice_mode = g_value_get_enum (value);
458       break;
459     case PROP_INTER_INTERVAL:
460       self->inter_interval = g_value_get_uint (value);
461       break;
462     default:
463       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
464   }
465 }
466
467 static void
468 gst_ducati_h264enc_get_property (GObject * object, guint prop_id,
469     GValue * value, GParamSpec * pspec)
470 {
471   GstDucatiH264Enc *self = GST_DUCATIH264ENC (object);
472
473   g_return_if_fail (GST_IS_DUCATIH264ENC (object));
474   self = GST_DUCATIH264ENC (object);
475
476   switch (prop_id) {
477     case PROP_PROFILE:
478       g_value_set_enum (value, self->profile);
479       break;
480     case PROP_LEVEL:
481       g_value_set_enum (value, self->level);
482       break;
483     case PROP_RATE_CONTROL_PARAMS_PRESET:
484       g_value_set_enum (value, self->rate_control_params_preset);
485       break;
486     case PROP_RATE_CONTROL_ALGO:
487       g_value_set_enum (value, self->rate_control_algo);
488       break;
489     case PROP_QPI:
490       g_value_set_int (value, self->qpi);
491       break;
492     case PROP_QP_MIN_I:
493       g_value_set_int (value, self->qp_min_i);
494       break;
495     case PROP_QP_MAX_I:
496       g_value_set_int (value, self->qp_max_i);
497       break;
498     case PROP_HRD_BUFFER_SIZE:
499       g_value_set_uint (value, self->hrd_buffer_size);
500       break;
501     case PROP_ENTROPY_CODING_MODE:
502       g_value_set_enum (value, self->entropy_coding_mode);
503       break;
504     case PROP_SLICE_MODE:
505       g_value_set_enum (value, self->slice_mode);
506       break;
507     case PROP_INTER_INTERVAL:
508       g_value_set_uint (value, self->inter_interval);
509       break;
510     default:
511       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
512   }
513 }
514
515 static const char *
516 get_profile_name (guint profile)
517 {
518   switch (profile) {
519     case GST_DUCATI_H264ENC_PROFILE_BASELINE:
520       return "baseline";
521     case GST_DUCATI_H264ENC_PROFILE_MAIN:
522       return "main";
523     case GST_DUCATI_H264ENC_PROFILE_EXTENDED:
524       return "extended";
525     case GST_DUCATI_H264ENC_PROFILE_HIGH:
526       return "high";
527     case GST_DUCATI_H264ENC_PROFILE_HIGH_10:
528       return "high-10";
529     case GST_DUCATI_H264ENC_PROFILE_HIGH_422:
530       return "high-422";
531     default:
532       return NULL;
533   }
534 }
535
536 static const char *
537 get_level_name (guint level)
538 {
539   switch (level) {
540     case GST_DUCATI_H264ENC_LEVEL_10:
541       return "1";
542     case GST_DUCATI_H264ENC_LEVEL_1b:
543       return "1b";
544     case GST_DUCATI_H264ENC_LEVEL_11:
545       return "1.1";
546     case GST_DUCATI_H264ENC_LEVEL_12:
547       return "1.2";
548     case GST_DUCATI_H264ENC_LEVEL_13:
549       return "1.3";
550     case GST_DUCATI_H264ENC_LEVEL_20:
551       return "2";
552     case GST_DUCATI_H264ENC_LEVEL_21:
553       return "2.1";
554     case GST_DUCATI_H264ENC_LEVEL_22:
555       return "2.2";
556     case GST_DUCATI_H264ENC_LEVEL_30:
557       return "3";
558     case GST_DUCATI_H264ENC_LEVEL_31:
559       return "3.1";
560     case GST_DUCATI_H264ENC_LEVEL_32:
561       return "3.2";
562     case GST_DUCATI_H264ENC_LEVEL_40:
563       return "4";
564     case GST_DUCATI_H264ENC_LEVEL_41:
565       return "4.1";
566     case GST_DUCATI_H264ENC_LEVEL_42:
567       return "4.2";
568     case GST_DUCATI_H264ENC_LEVEL_50:
569       return "5";
570     case GST_DUCATI_H264ENC_LEVEL_51:
571       return "5.1";
572     default:
573       return NULL;
574   }
575 }
576
577 static gboolean
578 gst_ducati_h264enc_configure (GstDucatiVidEnc * videnc, GstCaps ** caps)
579 {
580   const char *s;
581   int inter_interval;
582   IH264ENC_Params *params;
583   IH264ENC_DynamicParams *dynParams;
584
585   GstDucatiH264Enc *self = GST_DUCATIH264ENC (videnc);
586
587   videnc->params->profile = self->profile;
588   videnc->params->level = self->level;
589
590   inter_interval = self->inter_interval;
591   if (self->profile == GST_DUCATI_H264ENC_PROFILE_BASELINE)
592     inter_interval = 1;
593   else if (videnc->rate_preset == IVIDEO_LOW_DELAY)
594     inter_interval = 1;
595
596   params = (IH264ENC_Params *) videnc->params;
597   /* this is the only non-base field strictly required */
598   params->maxIntraFrameInterval = 0x7fffffff;
599   params->IDRFrameInterval = 1;
600   params->numTemporalLayer = 1;
601   params->entropyCodingMode = self->entropy_coding_mode;
602   videnc->params->maxInterFrameInterval = inter_interval;
603
604   /* Dynamic params */
605   dynParams = (IH264ENC_DynamicParams *) videnc->dynParams;
606   dynParams->rateControlParams.rateControlParamsPreset =
607       self->rate_control_params_preset;
608   dynParams->rateControlParams.rcAlgo = self->rate_control_algo;
609   dynParams->rateControlParams.qpI = self->qpi;
610   dynParams->rateControlParams.qpMaxI = self->qp_max_i;
611   dynParams->rateControlParams.qpMinI = self->qp_min_i;
612   dynParams->rateControlParams.HRDBufferSize = self->hrd_buffer_size;
613   dynParams->sliceCodingParams.sliceMode = self->slice_mode;
614   videnc->dynParams->interFrameInterval = inter_interval;
615
616   *caps = gst_caps_new_simple ("video/x-h264",
617       "stream-format", G_TYPE_STRING, "byte-stream",
618       "align", G_TYPE_STRING, "au",
619       "num-reorder-frames", G_TYPE_INT, inter_interval - 1, NULL);
620   s = get_profile_name (self->profile);
621   if (s)
622     gst_caps_set_simple (*caps, "profile", G_TYPE_STRING, s, NULL);
623   s = get_level_name (self->level);
624   if (s)
625     gst_caps_set_simple (*caps, "level", G_TYPE_STRING, s, NULL);
626
627   return TRUE;
628 }
629
630 static gboolean
631 gst_ducati_h264enc_allocate_params (GstDucatiVidEnc *
632     videnc, gint params_sz, gint dynparams_sz, gint status_sz, gint inargs_sz,
633     gint outargs_sz)
634 {
635   gboolean ret = GST_DUCATIVIDENC_CLASS (parent_class)->allocate_params (videnc,
636       sizeof (IH264ENC_Params), sizeof (IH264ENC_DynamicParams),
637       sizeof (IVIDENC2_Status), sizeof (IVIDENC2_InArgs),
638       sizeof (IVIDENC2_OutArgs));
639
640   GstDucatiH264Enc *self = GST_DUCATIH264ENC (videnc);
641
642   if (ret == TRUE) {
643     IH264ENC_DynamicParams *dynParams =
644         (IH264ENC_DynamicParams *) videnc->dynParams;
645
646     dynParams->rateControlParams.rateControlParamsPreset =
647         self->rate_control_params_preset;
648     dynParams->rateControlParams.rcAlgo = self->rate_control_algo;
649     dynParams->rateControlParams.qpI = self->qpi;
650     dynParams->rateControlParams.qpMaxI = self->qp_max_i;
651     dynParams->rateControlParams.qpMinI = self->qp_min_i;
652     dynParams->rateControlParams.HRDBufferSize = self->hrd_buffer_size;
653     dynParams->sliceCodingParams.sliceMode = self->slice_mode;
654   }
655
656   return ret;
657 }
658
659 static gboolean
660 gst_ducati_h264enc_is_sync_point (GstDucatiVidEnc * enc, int type)
661 {
662   return type == IVIDEO_IDR_FRAME;
663 }