2be3dd3b9ca7d5646b3b5f23968763be9ebd81cf
[glsdk/gst-plugins-ugly0-10.git] / ext / x264 / gstx264enc.c
1 /* GStreamer H264 encoder plugin
2  * Copyright (C) 2005 Michal Benes <michal.benes@itonis.tv>
3  * Copyright (C) 2005 Josef Zlomek <josef.zlomek@itonis.tv>
4  * Copyright (C) 2008 Mark Nauwelaerts <mnauw@users.sf.net>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
22 /**
23  * SECTION:element-x264enc
24  * @see_also: faac
25  *
26  * This element encodes raw video into H264 compressed data,
27  * also otherwise known as MPEG-4 AVC (Advanced Video Codec).
28  *
29  * The #GstX264Enc:pass property controls the type of encoding.  In case of Constant
30  * Bitrate Encoding (actually ABR), the #GstX264Enc:bitrate will determine the quality
31  * of the encoding.  This will similarly be the case if this target bitrate
32  * is to obtained in multiple (2 or 3) pass encoding.
33  * Alternatively, one may choose to perform Constant Quantizer or Quality encoding,
34  * in which case the #GstX264Enc:quantizer property controls much of the outcome, in that case #GstX264Enc:bitrate is the maximum bitrate.
35  *
36  * The H264 profile that is eventually used depends on a few settings.
37  * If #GstX264Enc:dct8x8 is enabled, then High profile is used.
38  * Otherwise, if #GstX264Enc:cabac entropy coding is enabled or #GstX264Enc:bframes
39  * are allowed, then Main Profile is in effect, and otherwise Baseline profile
40  * applies.  The main profile is imposed by default,
41  * which is fine for most software players and settings,
42  * but in some cases (e.g. hardware platforms) a more restricted profile/level
43  * may be necessary. The recommended way to set a profile is to set it in the
44  * downstream caps.
45  *
46  * If a preset/tuning are specified then these will define the default values and
47  * the property defaults will be ignored. After this the option-string property is
48  * applied, followed by the user-set properties, fast first pass restrictions and
49  * finally the profile restrictions.
50  *
51  * <note>Some settings, including the default settings, may lead to quite
52  * some latency (i.e. frame buffering) in the encoder. This may cause problems
53  * with pipeline stalling in non-trivial pipelines, because the encoder latency
54  * is often considerably higher than the default size of a simple queue
55  * element. Such problems are caused by one of the queues in the other
56  * non-x264enc streams/branches filling up and blocking upstream. They can
57  * be fixed by relaxing the default time/size/buffer limits on the queue
58  * elements in the non-x264 branches, or using a (single) multiqueue element
59  * for all branches. Also see the last example below.
60  * </note>
61  *
62  * <refsect2>
63  * <title>Example pipeline</title>
64  * |[
65  * gst-launch -v videotestsrc num-buffers=1000 ! x264enc qp-min=18 ! \
66  *   avimux ! filesink location=videotestsrc.avi
67  * ]| This example pipeline will encode a test video source to H264 muxed in an
68  * AVI container, while ensuring a sane minimum quantization factor to avoid
69  * some (excessive) waste.
70  * |[
71  * gst-launch -v videotestsrc num-buffers=1000 ! x264enc pass=quant ! \
72  *   matroskamux ! filesink location=videotestsrc.avi
73  * ]| This example pipeline will encode a test video source to H264 using fixed
74  * quantization, and muxes it in a Matroska container.
75  * |[
76  * gst-launch -v videotestsrc num-buffers=1000 ! x264enc pass=5 quantizer=25 speed-preset=6 ! video/x-h264, profile=baseline ! \
77  *   qtmux ! filesink location=videotestsrc.mov
78  * ]| This example pipeline will encode a test video source to H264 using
79  * constant quality at around Q25 using the 'medium' speed/quality preset and
80  * restricting the options used so that the output is H.264 Baseline Profile
81  * compliant and finally multiplexing the output in Quicktime mov format.
82  * |[
83  * gst-launch -v videotestsrc num-buffers=1000 ! tee name=t ! queue ! xvimagesink \
84  *   t. ! queue ! x264enc rc-lookahead=5 ! fakesink
85  * ]| This example pipeline will encode a test video source to H264 while
86  * displaying the input material at the same time.  As mentioned above,
87  * specific settings are needed in this case to avoid pipeline stalling.
88  * Depending on goals and context, other approaches are possible, e.g.
89  * tune=zerolatency might be configured, or queue sizes increased.
90  * </refsect2>
91  */
93 #ifdef HAVE_CONFIG_H
94 #  include "config.h"
95 #endif
97 #include "gstx264enc.h"
99 #include <gst/pbutils/pbutils.h>
101 #if X264_BUILD >= 71
102 #define X264_DELAYED_FRAMES_API
103 #endif
105 #if X264_BUILD >= 76
106 #define X264_ENC_NALS 1
107 #endif
109 #if X264_BUILD >= 69
110 #define X264_MB_RC
111 #endif
113 #if X264_BUILD >= 78
114 /* b-pyramid was available before but was changed from boolean here */
115 #define X264_B_PYRAMID
116 #endif
118 #if X264_BUILD >= 80
119 #define X264_ENH_THREADING
120 #endif
122 #if X264_BUILD >= 82
123 #define X264_INTRA_REFRESH
124 #endif
126 #if X264_BUILD >= 86
127 #define X264_PRESETS
128 #endif
130 #include <string.h>
131 #include <stdlib.h>
133 GST_DEBUG_CATEGORY_STATIC (x264_enc_debug);
134 #define GST_CAT_DEFAULT x264_enc_debug
136 enum
138   ARG_0,
139   ARG_THREADS,
140   ARG_SLICED_THREADS,
141   ARG_SYNC_LOOKAHEAD,
142   ARG_PASS,
143   ARG_QUANTIZER,
144   ARG_STATS_FILE,
145   ARG_MULTIPASS_CACHE_FILE,
146   ARG_BYTE_STREAM,
147   ARG_BITRATE,
148   ARG_INTRA_REFRESH,
149   ARG_VBV_BUF_CAPACITY,
150   ARG_ME,
151   ARG_SUBME,
152   ARG_ANALYSE,
153   ARG_DCT8x8,
154   ARG_REF,
155   ARG_BFRAMES,
156   ARG_B_ADAPT,
157   ARG_B_PYRAMID,
158   ARG_WEIGHTB,
159   ARG_SPS_ID,
160   ARG_AU_NALU,
161   ARG_TRELLIS,
162   ARG_KEYINT_MAX,
163   ARG_CABAC,
164   ARG_QP_MIN,
165   ARG_QP_MAX,
166   ARG_QP_STEP,
167   ARG_IP_FACTOR,
168   ARG_PB_FACTOR,
169   ARG_RC_MB_TREE,
170   ARG_RC_LOOKAHEAD,
171   ARG_NR,
172   ARG_INTERLACED,
173   ARG_OPTION_STRING,
174   ARG_PROFILE,
175   ARG_SPEED_PRESET,
176   ARG_PSY_TUNE,
177   ARG_TUNE,
178 };
180 #define ARG_THREADS_DEFAULT            0        /* 0 means 'auto' which is 1.5x number of CPU cores */
181 #define ARG_PASS_DEFAULT               0
182 #define ARG_QUANTIZER_DEFAULT          21
183 #define ARG_MULTIPASS_CACHE_FILE_DEFAULT "x264.log"
184 #define ARG_STATS_FILE_DEFAULT         ARG_MULTIPASS_CACHE_FILE_DEFAULT
185 #define ARG_BYTE_STREAM_DEFAULT        FALSE
186 #define ARG_BITRATE_DEFAULT            (2 * 1024)
187 #define ARG_VBV_BUF_CAPACITY_DEFAULT   600
188 #define ARG_ME_DEFAULT                 X264_ME_HEX
189 #define ARG_SUBME_DEFAULT              1
190 #define ARG_ANALYSE_DEFAULT            0
191 #define ARG_DCT8x8_DEFAULT             FALSE
192 #define ARG_REF_DEFAULT                1
193 #define ARG_BFRAMES_DEFAULT            0
194 #define ARG_B_ADAPT_DEFAULT            TRUE
195 #define ARG_B_PYRAMID_DEFAULT          FALSE
196 #define ARG_WEIGHTB_DEFAULT            FALSE
197 #define ARG_SPS_ID_DEFAULT             0
198 #define ARG_AU_NALU_DEFAULT            TRUE
199 #define ARG_TRELLIS_DEFAULT            TRUE
200 #define ARG_KEYINT_MAX_DEFAULT         0
201 #define ARG_CABAC_DEFAULT              TRUE
202 #define ARG_QP_MIN_DEFAULT             10
203 #define ARG_QP_MAX_DEFAULT             51
204 #define ARG_QP_STEP_DEFAULT            4
205 #define ARG_IP_FACTOR_DEFAULT          1.4
206 #define ARG_PB_FACTOR_DEFAULT          1.3
207 #define ARG_NR_DEFAULT                 0
208 #define ARG_INTERLACED_DEFAULT         FALSE
209 #define ARG_SLICED_THREADS_DEFAULT     FALSE
210 #define ARG_SYNC_LOOKAHEAD_DEFAULT     -1
211 #define ARG_RC_MB_TREE_DEFAULT         TRUE
212 #define ARG_RC_LOOKAHEAD_DEFAULT       40
213 #define ARG_INTRA_REFRESH_DEFAULT      FALSE
214 #define ARG_PROFILE_DEFAULT            2        /* 'Main Profile' - matches profile of property defaults */
215 #define ARG_OPTION_STRING_DEFAULT      ""
216 static GString *x264enc_defaults;
217 #define ARG_SPEED_PRESET_DEFAULT       6        /* 'medium' preset - matches x264 CLI default */
218 #define ARG_PSY_TUNE_DEFAULT           0        /* no psy tuning */
219 #define ARG_TUNE_DEFAULT               0        /* no tuning */
221 enum
223   GST_X264_ENC_STREAM_FORMAT_FROM_PROPERTY,
224   GST_X264_ENC_STREAM_FORMAT_AVC,
225   GST_X264_ENC_STREAM_FORMAT_BYTE_STREAM
226 };
228 enum
230   GST_X264_ENC_PASS_CBR = 0,
231   GST_X264_ENC_PASS_QUANT = 0x04,
232   GST_X264_ENC_PASS_QUAL,
233   GST_X264_ENC_PASS_PASS1 = 0x11,
234   GST_X264_ENC_PASS_PASS2,
235   GST_X264_ENC_PASS_PASS3
236 };
238 #define GST_X264_ENC_PASS_TYPE (gst_x264_enc_pass_get_type())
239 static GType
240 gst_x264_enc_pass_get_type (void)
242   static GType pass_type = 0;
244   static const GEnumValue pass_types[] = {
245     {GST_X264_ENC_PASS_CBR, "Constant Bitrate Encoding", "cbr"},
246     {GST_X264_ENC_PASS_QUANT, "Constant Quantizer (debugging only)", "quant"},
247     {GST_X264_ENC_PASS_QUAL, "Constant Quality", "qual"},
248     {GST_X264_ENC_PASS_PASS1, "VBR Encoding - Pass 1", "pass1"},
249     {GST_X264_ENC_PASS_PASS2, "VBR Encoding - Pass 2", "pass2"},
250     {GST_X264_ENC_PASS_PASS3, "VBR Encoding - Pass 3", "pass3"},
251     {0, NULL, NULL}
252   };
254   if (!pass_type) {
255     pass_type = g_enum_register_static ("GstX264EncPass", pass_types);
256   }
257   return pass_type;
260 #define GST_X264_ENC_ME_TYPE (gst_x264_enc_me_get_type())
261 static GType
262 gst_x264_enc_me_get_type (void)
264   static GType me_type = 0;
265   static GEnumValue *me_types;
266   int n, i;
268   if (me_type != 0)
269     return me_type;
271   n = 0;
272   while (x264_motion_est_names[n] != NULL)
273     n++;
275   me_types = g_new0 (GEnumValue, n + 1);
277   for (i = 0; i < n; i++) {
278     me_types[i].value = i;
279     me_types[i].value_name = x264_motion_est_names[i];
280     me_types[i].value_nick = x264_motion_est_names[i];
281   }
283   me_type = g_enum_register_static ("GstX264EncMe", me_types);
285   return me_type;
288 #define GST_X264_ENC_ANALYSE_TYPE (gst_x264_enc_analyse_get_type())
289 static GType
290 gst_x264_enc_analyse_get_type (void)
292   static GType analyse_type = 0;
293   static const GFlagsValue analyse_types[] = {
294     {X264_ANALYSE_I4x4, "i4x4", "i4x4"},
295     {X264_ANALYSE_I8x8, "i8x8", "i8x8"},
296     {X264_ANALYSE_PSUB16x16, "p8x8", "p8x8"},
297     {X264_ANALYSE_PSUB8x8, "p4x4", "p4x4"},
298     {X264_ANALYSE_BSUB16x16, "b8x8", "b8x8"},
299     {0, NULL, NULL},
300   };
302   if (!analyse_type) {
303     analyse_type = g_flags_register_static ("GstX264EncAnalyse", analyse_types);
304   }
305   return analyse_type;
308 #ifdef X264_PRESETS
310 #define GST_X264_ENC_PROFILE_TYPE (gst_x264_enc_profile_get_type())
311 static GType
312 gst_x264_enc_profile_get_type (void)
314   static GType profile_type = 0;
315   static GEnumValue *profile_types;
316   int n, i;
318   if (profile_type != 0)
319     return profile_type;
321   n = 0;
322   while (x264_profile_names[n] != NULL)
323     n++;
325   profile_types = g_new0 (GEnumValue, n + 2);
327   i = 0;
328   profile_types[i].value = i;
329   profile_types[i].value_name = "No profile";
330   profile_types[i].value_nick = "None";
331   for (i = 1; i <= n; i++) {
332     profile_types[i].value = i;
333     profile_types[i].value_name = x264_profile_names[i - 1];
334     profile_types[i].value_nick = x264_profile_names[i - 1];
335   }
337   profile_type = g_enum_register_static ("GstX264EncProfile", profile_types);
339   return profile_type;
342 #define GST_X264_ENC_SPEED_PRESET_TYPE (gst_x264_enc_speed_preset_get_type())
343 static GType
344 gst_x264_enc_speed_preset_get_type (void)
346   static GType speed_preset_type = 0;
347   static GEnumValue *speed_preset_types;
348   int n, i;
350   if (speed_preset_type != 0)
351     return speed_preset_type;
353   n = 0;
354   while (x264_preset_names[n] != NULL)
355     n++;
357   speed_preset_types = g_new0 (GEnumValue, n + 2);
359   speed_preset_types[0].value = 0;
360   speed_preset_types[0].value_name = "No preset";
361   speed_preset_types[0].value_nick = "None";
363   for (i = 1; i <= n; i++) {
364     speed_preset_types[i].value = i;
365     speed_preset_types[i].value_name = x264_preset_names[i - 1];
366     speed_preset_types[i].value_nick = x264_preset_names[i - 1];
367   }
369   speed_preset_type =
370       g_enum_register_static ("GstX264EncPreset", speed_preset_types);
372   return speed_preset_type;
375 static const GFlagsValue tune_types[] = {
376   {0x0, "No tuning", "none"},
377   {0x1, "Still image", "stillimage"},
378   {0x2, "Fast decode", "fastdecode"},
379   {0x4, "Zero latency (requires constant framerate)", "zerolatency"},
380   {0, NULL, NULL},
381 };
383 #define GST_X264_ENC_TUNE_TYPE (gst_x264_enc_tune_get_type())
384 static GType
385 gst_x264_enc_tune_get_type (void)
387   static GType tune_type = 0;
389   if (!tune_type) {
390     tune_type = g_flags_register_static ("GstX264EncTune", tune_types + 1);
391   }
392   return tune_type;
395 enum
397   GST_X264_ENC_TUNE_NONE,
398   GST_X264_ENC_TUNE_FILM,
399   GST_X264_ENC_TUNE_ANIMATION,
400   GST_X264_ENC_TUNE_GRAIN,
401   GST_X264_ENC_TUNE_PSNR,
402   GST_X264_ENC_TUNE_SSIM,
403   GST_X264_ENC_TUNE_LAST
404 };
406 static const GEnumValue psy_tune_types[] = {
407   {GST_X264_ENC_TUNE_NONE, "No tuning", "none"},
408   {GST_X264_ENC_TUNE_FILM, "Film", "film"},
409   {GST_X264_ENC_TUNE_ANIMATION, "Animation", "animation"},
410   {GST_X264_ENC_TUNE_GRAIN, "Grain", "grain"},
411   {GST_X264_ENC_TUNE_PSNR, "PSNR", "psnr"},
412   {GST_X264_ENC_TUNE_SSIM, "SSIM", "ssim"},
413   {0, NULL, NULL},
414 };
416 #define GST_X264_ENC_PSY_TUNE_TYPE (gst_x264_enc_psy_tune_get_type())
417 static GType
418 gst_x264_enc_psy_tune_get_type (void)
420   static GType psy_tune_type = 0;
422   if (!psy_tune_type) {
423     psy_tune_type =
424         g_enum_register_static ("GstX264EncPsyTune", psy_tune_types);
425   }
426   return psy_tune_type;
429 static void
430 gst_x264_enc_build_tunings_string (GstX264Enc * x264enc)
432   int i = 1;
434   if (x264enc->tunings)
435     g_string_free (x264enc->tunings, TRUE);
437   if (x264enc->psy_tune) {
438     x264enc->tunings =
439         g_string_new (psy_tune_types[x264enc->psy_tune].value_nick);
440   } else {
441     x264enc->tunings = g_string_new (NULL);
442   }
444   while (tune_types[i].value_name) {
445     if (x264enc->tune & (1 << (i - 1)))
446       g_string_append_printf (x264enc->tunings, "%s%s",
447           x264enc->tunings->len ? "," : "", tune_types[i].value_nick);
448     i++;
449   }
451   if (x264enc->tunings->len)
452     GST_DEBUG_OBJECT (x264enc, "Constructed tunings string: %s",
453         x264enc->tunings->str);
456 #endif
459 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
460     GST_PAD_SINK,
461     GST_PAD_ALWAYS,
462     GST_STATIC_CAPS ("video/x-raw-yuv, "
463         "format = (fourcc) { I420, YV12 }, "
464         "framerate = (fraction) [0, MAX], "
465         "width = (int) [ 16, MAX ], " "height = (int) [ 16, MAX ]")
466     );
468 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
469     GST_PAD_SRC,
470     GST_PAD_ALWAYS,
471     GST_STATIC_CAPS ("video/x-h264, "
472         "framerate = (fraction) [0/1, MAX], "
473         "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ], "
474         "stream-format = (string) { byte-stream, avc }, "
475         "alignment = (string) { au }, "
476         "profile = (string) { high-10, high, main, constrained-baseline, "
477         "high-10-intra }")
478     );
480 static void gst_x264_enc_finalize (GObject * object);
481 static void gst_x264_enc_reset (GstX264Enc * encoder);
483 static gboolean gst_x264_enc_init_encoder (GstX264Enc * encoder);
484 static void gst_x264_enc_close_encoder (GstX264Enc * encoder);
486 static gboolean gst_x264_enc_sink_set_caps (GstPad * pad, GstCaps * caps);
487 static GstCaps *gst_x264_enc_sink_get_caps (GstPad * pad);
488 static gboolean gst_x264_enc_sink_event (GstPad * pad, GstEvent * event);
489 static gboolean gst_x264_enc_src_event (GstPad * pad, GstEvent * event);
490 static GstFlowReturn gst_x264_enc_chain (GstPad * pad, GstBuffer * buf);
491 static void gst_x264_enc_flush_frames (GstX264Enc * encoder, gboolean send);
492 static GstFlowReturn gst_x264_enc_encode_frame (GstX264Enc * encoder,
493     x264_picture_t * pic_in, int *i_nal, gboolean send);
494 static GstStateChangeReturn gst_x264_enc_change_state (GstElement * element,
495     GstStateChange transition);
497 static void gst_x264_enc_set_property (GObject * object, guint prop_id,
498     const GValue * value, GParamSpec * pspec);
499 static void gst_x264_enc_get_property (GObject * object, guint prop_id,
500     GValue * value, GParamSpec * pspec);
502 static void
503 _do_init (GType object_type)
505   const GInterfaceInfo preset_interface_info = {
506     NULL,                       /* interface_init */
507     NULL,                       /* interface_finalize */
508     NULL                        /* interface_data */
509   };
511   g_type_add_interface_static (object_type, GST_TYPE_PRESET,
512       &preset_interface_info);
515 GST_BOILERPLATE_FULL (GstX264Enc, gst_x264_enc, GstElement, GST_TYPE_ELEMENT,
516     _do_init);
518 static void
519 gst_x264_enc_base_init (gpointer g_class)
521   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
523   gst_element_class_set_details_simple (element_class,
524       "x264enc", "Codec/Encoder/Video", "H264 Encoder",
525       "Josef Zlomek <josef.zlomek@itonis.tv>, "
526       "Mark Nauwelaerts <mnauw@users.sf.net>");
528   gst_element_class_add_static_pad_template (element_class, &src_factory);
529   gst_element_class_add_static_pad_template (element_class, &sink_factory);
532 /* don't forget to free the string after use */
533 static const gchar *
534 gst_x264_enc_build_partitions (gint analyse)
536   GString *string;
538   if (!analyse)
539     return NULL;
541   string = g_string_new (NULL);
542   if (analyse & X264_ANALYSE_I4x4)
543     g_string_append (string, "i4x4");
544   if (analyse & X264_ANALYSE_I8x8)
545     g_string_append (string, ",i8x8");
546   if (analyse & X264_ANALYSE_PSUB16x16)
547     g_string_append (string, ",p8x8");
548   if (analyse & X264_ANALYSE_PSUB8x8)
549     g_string_append (string, ",p4x4");
550   if (analyse & X264_ANALYSE_BSUB16x16)
551     g_string_append (string, ",b8x8");
553   return (const gchar *) g_string_free (string, FALSE);
556 static void
557 gst_x264_enc_class_init (GstX264EncClass * klass)
559   GObjectClass *gobject_class;
560   GstElementClass *gstelement_class;
562   const gchar *partitions = NULL;
564   x264enc_defaults = g_string_new ("");
566   gobject_class = (GObjectClass *) klass;
567   gstelement_class = (GstElementClass *) klass;
569   gobject_class->set_property = gst_x264_enc_set_property;
570   gobject_class->get_property = gst_x264_enc_get_property;
571   gobject_class->finalize = gst_x264_enc_finalize;
573   gstelement_class->change_state =
574       GST_DEBUG_FUNCPTR (gst_x264_enc_change_state);
576   /* options for which we don't use string equivalents */
577   g_object_class_install_property (gobject_class, ARG_PASS,
578       g_param_spec_enum ("pass", "Encoding pass/type",
579           "Encoding pass/type", GST_X264_ENC_PASS_TYPE,
580           ARG_PASS_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
581   g_object_class_install_property (gobject_class, ARG_QUANTIZER,
582       g_param_spec_uint ("quantizer", "Constant Quantizer",
583           "Constant quantizer or quality to apply",
584           1, 50, ARG_QUANTIZER_DEFAULT,
585           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
586   g_object_class_install_property (gobject_class, ARG_BITRATE,
587       g_param_spec_uint ("bitrate", "Bitrate", "Bitrate in kbit/sec", 1,
588           100 * 1024, ARG_BITRATE_DEFAULT,
589           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
590           GST_PARAM_MUTABLE_PLAYING));
591   g_object_class_install_property (gobject_class, ARG_VBV_BUF_CAPACITY,
592       g_param_spec_uint ("vbv-buf-capacity", "VBV buffer capacity",
593           "Size of the VBV buffer in milliseconds",
594           0, 10000, ARG_VBV_BUF_CAPACITY_DEFAULT,
595           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
596           GST_PARAM_MUTABLE_PLAYING));
598 #ifdef X264_PRESETS
599   g_object_class_install_property (gobject_class, ARG_SPEED_PRESET,
600       g_param_spec_enum ("speed-preset", "Speed/quality preset",
601           "Preset name for speed/quality tradeoff options (can affect decode "
602           "compatibility - impose restrictions separately for your target decoder)",
603           GST_X264_ENC_SPEED_PRESET_TYPE, ARG_SPEED_PRESET_DEFAULT,
604           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
605   g_object_class_install_property (gobject_class, ARG_PSY_TUNE,
606       g_param_spec_enum ("psy-tune", "Psychovisual tuning preset",
607           "Preset name for psychovisual tuning options",
608           GST_X264_ENC_PSY_TUNE_TYPE, ARG_PSY_TUNE_DEFAULT,
609           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
610   g_object_class_install_property (gobject_class, ARG_TUNE,
611       g_param_spec_flags ("tune", "Content tuning preset",
612           "Preset name for non-psychovisual tuning options",
613           GST_X264_ENC_TUNE_TYPE, ARG_TUNE_DEFAULT,
614           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
615   g_object_class_install_property (gobject_class, ARG_PROFILE,
616       g_param_spec_enum ("profile", "H.264 profile",
617           "Apply restrictions to meet H.264 Profile constraints. This will "
618           "override other properties if necessary. This will only be used "
619           "if downstream elements do not specify a profile in their caps (DEPRECATED)",
620           GST_X264_ENC_PROFILE_TYPE, ARG_PROFILE_DEFAULT,
621           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
622 #endif /* X264_PRESETS */
623   g_object_class_install_property (gobject_class, ARG_OPTION_STRING,
624       g_param_spec_string ("option-string", "Option string",
625           "String of x264 options (overridden by element properties)",
626           ARG_OPTION_STRING_DEFAULT,
627           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
629   /* options for which we _do_ use string equivalents */
630   g_object_class_install_property (gobject_class, ARG_THREADS,
631       g_param_spec_uint ("threads", "Threads",
632           "Number of threads used by the codec (0 for automatic)",
633           0, 4, ARG_THREADS_DEFAULT,
634           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
635   /* NOTE: this first string append doesn't require the ':' delimiter but the
636    * rest do */
637   g_string_append_printf (x264enc_defaults, "threads=%d", ARG_THREADS_DEFAULT);
638 #ifdef X264_ENH_THREADING
639   g_object_class_install_property (gobject_class, ARG_SLICED_THREADS,
640       g_param_spec_boolean ("sliced-threads", "Sliced Threads",
641           "Low latency but lower efficiency threading",
642           ARG_SLICED_THREADS_DEFAULT,
643           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
644   g_string_append_printf (x264enc_defaults, ":sliced-threads=%d",
645       ARG_SLICED_THREADS_DEFAULT);
646   g_object_class_install_property (gobject_class, ARG_SYNC_LOOKAHEAD,
647       g_param_spec_int ("sync-lookahead", "Sync Lookahead",
648           "Number of buffer frames for threaded lookahead (-1 for automatic)",
649           -1, 250, ARG_SYNC_LOOKAHEAD_DEFAULT,
650           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
651   g_string_append_printf (x264enc_defaults, ":sync-lookahead=%d",
652       ARG_SYNC_LOOKAHEAD_DEFAULT);
653 #endif
654   g_object_class_install_property (gobject_class, ARG_STATS_FILE,
655       g_param_spec_string ("stats-file", "Stats File",
656           "Filename for multipass statistics (deprecated, use multipass-cache-file)",
657           ARG_STATS_FILE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
658   g_object_class_install_property (gobject_class, ARG_MULTIPASS_CACHE_FILE,
659       g_param_spec_string ("multipass-cache-file", "Multipass Cache File",
660           "Filename for multipass cache file",
661           ARG_MULTIPASS_CACHE_FILE_DEFAULT,
662           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
663   g_string_append_printf (x264enc_defaults, ":stats=%s",
664       ARG_MULTIPASS_CACHE_FILE_DEFAULT);
665   g_object_class_install_property (gobject_class, ARG_BYTE_STREAM,
666       g_param_spec_boolean ("byte-stream", "Byte Stream",
667           "Generate byte stream format of NALU", ARG_BYTE_STREAM_DEFAULT,
668           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
669   g_string_append_printf (x264enc_defaults, ":annexb=%d",
670       ARG_BYTE_STREAM_DEFAULT);
671 #ifdef X264_INTRA_REFRESH
672   g_object_class_install_property (gobject_class, ARG_INTRA_REFRESH,
673       g_param_spec_boolean ("intra-refresh", "Intra Refresh",
674           "Use Periodic Intra Refresh instead of IDR frames",
675           ARG_INTRA_REFRESH_DEFAULT,
676           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
677   g_string_append_printf (x264enc_defaults, ":intra-refresh=%d",
678       ARG_INTRA_REFRESH_DEFAULT);
679 #endif
680   g_object_class_install_property (gobject_class, ARG_ME,
681       g_param_spec_enum ("me", "Motion Estimation",
682           "Integer pixel motion estimation method", GST_X264_ENC_ME_TYPE,
683           ARG_ME_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
684   g_string_append_printf (x264enc_defaults, ":me=%s",
685       x264_motion_est_names[ARG_ME_DEFAULT]);
686   g_object_class_install_property (gobject_class, ARG_SUBME,
687       g_param_spec_uint ("subme", "Subpixel Motion Estimation",
688           "Subpixel motion estimation and partition decision quality: 1=fast, 10=best",
689           1, 10, ARG_SUBME_DEFAULT,
690           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
691   g_string_append_printf (x264enc_defaults, ":subme=%d", ARG_SUBME_DEFAULT);
692   g_object_class_install_property (gobject_class, ARG_ANALYSE,
693       g_param_spec_flags ("analyse", "Analyse", "Partitions to consider",
694           GST_X264_ENC_ANALYSE_TYPE, ARG_ANALYSE_DEFAULT,
695           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
696   partitions = gst_x264_enc_build_partitions (ARG_ANALYSE_DEFAULT);
697   if (partitions) {
698     g_string_append_printf (x264enc_defaults, ":partitions=%s", partitions);
699     g_free ((gpointer) partitions);
700   }
701   g_object_class_install_property (gobject_class, ARG_DCT8x8,
702       g_param_spec_boolean ("dct8x8", "DCT8x8",
703           "Adaptive spatial transform size", ARG_DCT8x8_DEFAULT,
704           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
705   g_string_append_printf (x264enc_defaults, ":8x8dct=%d", ARG_DCT8x8_DEFAULT);
706   g_object_class_install_property (gobject_class, ARG_REF,
707       g_param_spec_uint ("ref", "Reference Frames",
708           "Number of reference frames",
709           1, 12, ARG_REF_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
710   g_string_append_printf (x264enc_defaults, ":ref=%d", ARG_REF_DEFAULT);
711   g_object_class_install_property (gobject_class, ARG_BFRAMES,
712       g_param_spec_uint ("bframes", "B-Frames",
713           "Number of B-frames between I and P",
714           0, 4, ARG_BFRAMES_DEFAULT,
715           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
716   g_string_append_printf (x264enc_defaults, ":bframes=%d", ARG_BFRAMES_DEFAULT);
717   g_object_class_install_property (gobject_class, ARG_B_ADAPT,
718       g_param_spec_boolean ("b-adapt", "B-Adapt",
719           "Automatically decide how many B-frames to use",
720           ARG_B_ADAPT_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
721   g_string_append_printf (x264enc_defaults, ":b-adapt=%d", ARG_B_ADAPT_DEFAULT);
722   g_object_class_install_property (gobject_class, ARG_B_PYRAMID,
723       g_param_spec_boolean ("b-pyramid", "B-Pyramid",
724           "Keep some B-frames as references", ARG_B_PYRAMID_DEFAULT,
725           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
726 #ifdef X264_B_PYRAMID
727   g_string_append_printf (x264enc_defaults, ":b-pyramid=%s",
728       x264_b_pyramid_names[ARG_B_PYRAMID_DEFAULT]);
729 #else
730   g_string_append_printf (x264enc_defaults, ":b-pyramid=%d",
731       ARG_B_PYRAMID_DEFAULT);
732 #endif /* X264_B_PYRAMID */
733   g_object_class_install_property (gobject_class, ARG_WEIGHTB,
734       g_param_spec_boolean ("weightb", "Weighted B-Frames",
735           "Weighted prediction for B-frames", ARG_WEIGHTB_DEFAULT,
736           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
737   g_string_append_printf (x264enc_defaults, ":weightb=%d", ARG_WEIGHTB_DEFAULT);
738   g_object_class_install_property (gobject_class, ARG_SPS_ID,
739       g_param_spec_uint ("sps-id", "SPS ID",
740           "SPS and PPS ID number",
741           0, 31, ARG_SPS_ID_DEFAULT,
742           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
743   g_string_append_printf (x264enc_defaults, ":sps-id=%d", ARG_SPS_ID_DEFAULT);
744   g_object_class_install_property (gobject_class, ARG_AU_NALU,
745       g_param_spec_boolean ("aud", "AUD",
746           "Use AU (Access Unit) delimiter", ARG_AU_NALU_DEFAULT,
747           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
748   g_string_append_printf (x264enc_defaults, ":aud=%d", ARG_AU_NALU_DEFAULT);
749   g_object_class_install_property (gobject_class, ARG_TRELLIS,
750       g_param_spec_boolean ("trellis", "Trellis quantization",
751           "Enable trellis searched quantization", ARG_TRELLIS_DEFAULT,
752           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
753   g_string_append_printf (x264enc_defaults, ":trellis=%d", ARG_TRELLIS_DEFAULT);
754   g_object_class_install_property (gobject_class, ARG_KEYINT_MAX,
755       g_param_spec_uint ("key-int-max", "Key-frame maximal interval",
756           "Maximal distance between two key-frames (0 for automatic)",
757           0, G_MAXINT, ARG_KEYINT_MAX_DEFAULT,
758           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
759   g_string_append_printf (x264enc_defaults, ":keyint=%d",
760       ARG_KEYINT_MAX_DEFAULT);
761   g_object_class_install_property (gobject_class, ARG_CABAC,
762       g_param_spec_boolean ("cabac", "Use CABAC", "Enable CABAC entropy coding",
763           ARG_CABAC_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
764   g_string_append_printf (x264enc_defaults, ":cabac=%d", ARG_CABAC_DEFAULT);
765   g_object_class_install_property (gobject_class, ARG_QP_MIN,
766       g_param_spec_uint ("qp-min", "Minimum Quantizer",
767           "Minimum quantizer", 1, 51, ARG_QP_MIN_DEFAULT,
768           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
769   g_string_append_printf (x264enc_defaults, ":qpmin=%d", ARG_QP_MIN_DEFAULT);
770   g_object_class_install_property (gobject_class, ARG_QP_MAX,
771       g_param_spec_uint ("qp-max", "Maximum Quantizer",
772           "Maximum quantizer", 1, 51, ARG_QP_MAX_DEFAULT,
773           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
774   g_string_append_printf (x264enc_defaults, ":qpmax=%d", ARG_QP_MAX_DEFAULT);
775   g_object_class_install_property (gobject_class, ARG_QP_STEP,
776       g_param_spec_uint ("qp-step", "Maximum Quantizer Difference",
777           "Maximum quantizer difference between frames",
778           1, 50, ARG_QP_STEP_DEFAULT,
779           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
780   g_string_append_printf (x264enc_defaults, ":qpstep=%d", ARG_QP_STEP_DEFAULT);
781   g_object_class_install_property (gobject_class, ARG_IP_FACTOR,
782       g_param_spec_float ("ip-factor", "IP-Factor",
783           "Quantizer factor between I- and P-frames",
784           0, 2, ARG_IP_FACTOR_DEFAULT,
785           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
786   g_string_append_printf (x264enc_defaults, ":ip-factor=%f",
787       ARG_IP_FACTOR_DEFAULT);
788   g_object_class_install_property (gobject_class, ARG_PB_FACTOR,
789       g_param_spec_float ("pb-factor", "PB-Factor",
790           "Quantizer factor between P- and B-frames", 0, 2,
791           ARG_PB_FACTOR_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
792   g_string_append_printf (x264enc_defaults, ":pb-factor=%f",
793       ARG_PB_FACTOR_DEFAULT);
794 #ifdef X264_MB_RC
795   g_object_class_install_property (gobject_class, ARG_RC_MB_TREE,
796       g_param_spec_boolean ("mb-tree", "Macroblock Tree",
797           "Macroblock-Tree ratecontrol",
798           ARG_RC_MB_TREE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
799   g_string_append_printf (x264enc_defaults, ":mbtree=%d",
800       ARG_RC_MB_TREE_DEFAULT);
801   g_object_class_install_property (gobject_class, ARG_RC_LOOKAHEAD,
802       g_param_spec_int ("rc-lookahead", "Rate Control Lookahead",
803           "Number of frames for frametype lookahead", 0, 250,
804           ARG_RC_LOOKAHEAD_DEFAULT,
805           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
806   g_string_append_printf (x264enc_defaults, ":rc-lookahead=%d",
807       ARG_RC_LOOKAHEAD_DEFAULT);
808 #endif
809   g_object_class_install_property (gobject_class, ARG_NR,
810       g_param_spec_uint ("noise-reduction", "Noise Reduction",
811           "Noise reduction strength",
812           0, 100000, ARG_NR_DEFAULT,
813           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
814   g_string_append_printf (x264enc_defaults, ":nr=%d", ARG_NR_DEFAULT);
815   g_object_class_install_property (gobject_class, ARG_INTERLACED,
816       g_param_spec_boolean ("interlaced", "Interlaced",
817           "Interlaced material", ARG_INTERLACED_DEFAULT,
818           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
819   g_string_append_printf (x264enc_defaults, ":interlaced=%d",
820       ARG_INTERLACED_DEFAULT);
822   /* append deblock parameters */
823   g_string_append_printf (x264enc_defaults, ":deblock=0,0");
824   /* append weighted prediction parameter */
825   g_string_append_printf (x264enc_defaults, ":weightp=0");
828 static void
829 gst_x264_enc_log_callback (gpointer private, gint level, const char *format,
830     va_list args)
832 #ifndef GST_DISABLE_GST_DEBUG
833   GstDebugLevel gst_level;
834   GObject *object = (GObject *) private;
836   switch (level) {
837     case X264_LOG_NONE:
838       gst_level = GST_LEVEL_NONE;
839       break;
840     case X264_LOG_ERROR:
841       gst_level = GST_LEVEL_ERROR;
842       break;
843     case X264_LOG_WARNING:
844       gst_level = GST_LEVEL_WARNING;
845       break;
846     case X264_LOG_INFO:
847       gst_level = GST_LEVEL_INFO;
848       break;
849     default:
850       /* push x264enc debug down to our lower levels to avoid some clutter */
851       gst_level = GST_LEVEL_LOG;
852       break;
853   }
855   gst_debug_log_valist (x264_enc_debug, gst_level, "", "", 0, object, format,
856       args);
857 #endif /* GST_DISABLE_GST_DEBUG */
860 /* initialize the new element
861  * instantiate pads and add them to element
862  * set functions
863  * initialize structure
864  */
865 static void
866 gst_x264_enc_init (GstX264Enc * encoder, GstX264EncClass * klass)
868   encoder->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
869   gst_pad_set_setcaps_function (encoder->sinkpad,
870       GST_DEBUG_FUNCPTR (gst_x264_enc_sink_set_caps));
871   gst_pad_set_getcaps_function (encoder->sinkpad,
872       GST_DEBUG_FUNCPTR (gst_x264_enc_sink_get_caps));
873   gst_pad_set_event_function (encoder->sinkpad,
874       GST_DEBUG_FUNCPTR (gst_x264_enc_sink_event));
875   gst_pad_set_chain_function (encoder->sinkpad,
876       GST_DEBUG_FUNCPTR (gst_x264_enc_chain));
877   gst_element_add_pad (GST_ELEMENT (encoder), encoder->sinkpad);
879   encoder->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
880   gst_pad_use_fixed_caps (encoder->srcpad);
881   gst_element_add_pad (GST_ELEMENT (encoder), encoder->srcpad);
883   gst_pad_set_event_function (encoder->srcpad,
884       GST_DEBUG_FUNCPTR (gst_x264_enc_src_event));
886   /* properties */
887   encoder->threads = ARG_THREADS_DEFAULT;
888   encoder->sliced_threads = ARG_SLICED_THREADS_DEFAULT;
889   encoder->sync_lookahead = ARG_SYNC_LOOKAHEAD_DEFAULT;
890   encoder->pass = ARG_PASS_DEFAULT;
891   encoder->quantizer = ARG_QUANTIZER_DEFAULT;
892   encoder->mp_cache_file = g_strdup (ARG_MULTIPASS_CACHE_FILE_DEFAULT);
893   encoder->byte_stream = ARG_BYTE_STREAM_DEFAULT;
894   encoder->bitrate = ARG_BITRATE_DEFAULT;
895   encoder->intra_refresh = ARG_INTRA_REFRESH_DEFAULT;
896   encoder->vbv_buf_capacity = ARG_VBV_BUF_CAPACITY_DEFAULT;
897   encoder->me = ARG_ME_DEFAULT;
898   encoder->subme = ARG_SUBME_DEFAULT;
899   encoder->analyse = ARG_ANALYSE_DEFAULT;
900   encoder->dct8x8 = ARG_DCT8x8_DEFAULT;
901   encoder->ref = ARG_REF_DEFAULT;
902   encoder->bframes = ARG_BFRAMES_DEFAULT;
903   encoder->b_adapt = ARG_B_ADAPT_DEFAULT;
904   encoder->b_pyramid = ARG_B_PYRAMID_DEFAULT;
905   encoder->weightb = ARG_WEIGHTB_DEFAULT;
906   encoder->sps_id = ARG_SPS_ID_DEFAULT;
907   encoder->au_nalu = ARG_AU_NALU_DEFAULT;
908   encoder->trellis = ARG_TRELLIS_DEFAULT;
909   encoder->keyint_max = ARG_KEYINT_MAX_DEFAULT;
910   encoder->cabac = ARG_CABAC_DEFAULT;
911   encoder->qp_min = ARG_QP_MIN_DEFAULT;
912   encoder->qp_max = ARG_QP_MAX_DEFAULT;
913   encoder->qp_step = ARG_QP_STEP_DEFAULT;
914   encoder->ip_factor = ARG_IP_FACTOR_DEFAULT;
915   encoder->pb_factor = ARG_PB_FACTOR_DEFAULT;
916   encoder->mb_tree = ARG_RC_MB_TREE_DEFAULT;
917   encoder->rc_lookahead = ARG_RC_LOOKAHEAD_DEFAULT;
918   encoder->noise_reduction = ARG_NR_DEFAULT;
919   encoder->interlaced = ARG_INTERLACED_DEFAULT;
920   encoder->profile = ARG_PROFILE_DEFAULT;
921   encoder->option_string = g_string_new (NULL);
922   encoder->option_string_prop = g_string_new (ARG_OPTION_STRING_DEFAULT);
923   encoder->speed_preset = ARG_SPEED_PRESET_DEFAULT;
924   encoder->psy_tune = ARG_PSY_TUNE_DEFAULT;
925   encoder->tune = ARG_TUNE_DEFAULT;
927   /* resources */
928   encoder->delay = g_queue_new ();
929   encoder->buffer_size = 100000;
930   encoder->buffer = g_malloc (encoder->buffer_size);
932   x264_param_default (&encoder->x264param);
934   /* log callback setup; part of parameters */
935   encoder->x264param.pf_log = gst_x264_enc_log_callback;
936   encoder->x264param.p_log_private = encoder;
937   encoder->x264param.i_log_level = X264_LOG_DEBUG;
939   gst_x264_enc_reset (encoder);
942 static void
943 gst_x264_enc_reset (GstX264Enc * encoder)
945   encoder->x264enc = NULL;
946   encoder->width = 0;
947   encoder->height = 0;
948   encoder->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_FROM_PROPERTY;
950   GST_OBJECT_LOCK (encoder);
951   encoder->i_type = X264_TYPE_AUTO;
952   if (encoder->forcekeyunit_event)
953     gst_event_unref (encoder->forcekeyunit_event);
954   encoder->forcekeyunit_event = NULL;
955   GST_OBJECT_UNLOCK (encoder);
958 static void
959 gst_x264_enc_finalize (GObject * object)
961   GstX264Enc *encoder = GST_X264_ENC (object);
963 #define FREE_STRING(ptr) \
964   if (ptr) \
965     ptr = (GString *)g_string_free (ptr, TRUE);
967   FREE_STRING (encoder->tunings);
968   FREE_STRING (encoder->option_string);
969   FREE_STRING (encoder->option_string_prop);
971 #undef FREE_STRING
973   g_free (encoder->mp_cache_file);
974   encoder->mp_cache_file = NULL;
975   g_free (encoder->buffer);
976   encoder->buffer = NULL;
977   g_queue_free (encoder->delay);
978   encoder->delay = NULL;
980   gst_x264_enc_close_encoder (encoder);
982   G_OBJECT_CLASS (parent_class)->finalize (object);
985 /*
986  * gst_x264_enc_parse_options
987  * @encoder: Encoder to which options are assigned
988  * @str: Option string
989  *
990  * Parse option string and assign to x264 parameters
991  *
992  */
993 static gboolean
994 gst_x264_enc_parse_options (GstX264Enc * encoder, const gchar * str)
996   GStrv kvpairs;
997   guint npairs, i;
998   gint parse_result = 0, ret = 0;
999   gchar *options = (gchar *) str;
1001   while (*options == ':')
1002     options++;
1004   kvpairs = g_strsplit (options, ":", 0);
1005   npairs = g_strv_length (kvpairs);
1007   for (i = 0; i < npairs; i++) {
1008     GStrv key_val = g_strsplit (kvpairs[i], "=", 2);
1010     parse_result =
1011         x264_param_parse (&encoder->x264param, key_val[0], key_val[1]);
1013     if (parse_result == X264_PARAM_BAD_NAME) {
1014       GST_ERROR_OBJECT (encoder, "Bad name for option %s=%s",
1015           key_val[0] ? key_val[0] : "", key_val[1] ? key_val[1] : "");
1016     }
1017     if (parse_result == X264_PARAM_BAD_VALUE) {
1018       GST_ERROR_OBJECT (encoder,
1019           "Bad value for option %s=%s (Note: a NULL value for a non-boolean triggers this)",
1020           key_val[0] ? key_val[0] : "", key_val[1] ? key_val[1] : "");
1021     }
1023     g_strfreev (key_val);
1025     if (parse_result)
1026       ret++;
1027   }
1029   g_strfreev (kvpairs);
1030   return !ret;
1033 /*
1034  * gst_x264_enc_init_encoder
1035  * @encoder:  Encoder which should be initialized.
1036  *
1037  * Initialize x264 encoder.
1038  *
1039  */
1040 static gboolean
1041 gst_x264_enc_init_encoder (GstX264Enc * encoder)
1043   guint pass = 0;
1045   /* make sure that the encoder is closed */
1046   gst_x264_enc_close_encoder (encoder);
1048   GST_OBJECT_LOCK (encoder);
1050 #ifdef X264_PRESETS
1051   gst_x264_enc_build_tunings_string (encoder);
1053   /* set x264 parameters and use preset/tuning if present */
1054   GST_DEBUG_OBJECT (encoder, "Applying defaults with preset %s, tunings %s",
1055       encoder->speed_preset ? x264_preset_names[encoder->speed_preset - 1] : "",
1056       encoder->tunings && encoder->tunings->len ? encoder->tunings->str : "");
1057   x264_param_default_preset (&encoder->x264param,
1058       encoder->speed_preset ? x264_preset_names[encoder->speed_preset -
1059           1] : NULL, encoder->tunings
1060       && encoder->tunings->len ? encoder->tunings->str : NULL);
1062   /* log callback setup; part of parameters
1063    * this needs to be done again after every *param_default* () call */
1064   encoder->x264param.pf_log = gst_x264_enc_log_callback;
1065   encoder->x264param.p_log_private = encoder;
1066   encoder->x264param.i_log_level = X264_LOG_DEBUG;
1068   /* if no preset nor tuning, use property defaults */
1069   if (!encoder->speed_preset && !encoder->tunings->len) {
1070 #endif /* X264_PRESETS */
1071     GST_DEBUG_OBJECT (encoder, "Applying x264enc_defaults");
1072     if (x264enc_defaults->len
1073         && gst_x264_enc_parse_options (encoder,
1074             x264enc_defaults->str) == FALSE) {
1075       GST_DEBUG_OBJECT (encoder,
1076           "x264enc_defaults string contains errors. This is a bug.");
1077       goto unlock_and_return;
1078     }
1079 #ifdef X264_PRESETS
1080   } else {
1081     /* When using presets we need to respect the default output format */
1082     encoder->x264param.b_aud = encoder->au_nalu;
1083     encoder->x264param.b_annexb = encoder->byte_stream;
1084   }
1085 #endif /* X264_PRESETS */
1087 #if X264_BUILD >= 81
1088   /* setup appropriate timebase for gstreamer */
1089   encoder->x264param.i_timebase_num = 1;
1090   encoder->x264param.i_timebase_den = 1000000000;
1091 #endif
1093   /* apply option-string property */
1094   if (encoder->option_string_prop && encoder->option_string_prop->len) {
1095     GST_DEBUG_OBJECT (encoder, "Applying option-string: %s",
1096         encoder->option_string_prop->str);
1097     if (gst_x264_enc_parse_options (encoder,
1098             encoder->option_string_prop->str) == FALSE) {
1099       GST_DEBUG_OBJECT (encoder, "Your option-string contains errors.");
1100       goto unlock_and_return;
1101     }
1102   }
1103   /* apply user-set options */
1104   if (encoder->option_string && encoder->option_string->len) {
1105     GST_DEBUG_OBJECT (encoder, "Applying user-set options: %s",
1106         encoder->option_string->str);
1107     if (gst_x264_enc_parse_options (encoder,
1108             encoder->option_string->str) == FALSE) {
1109       GST_DEBUG_OBJECT (encoder, "Failed to parse internal option string. "
1110           "This could be due to use of an old libx264 version. Option string "
1111           "was: %s", encoder->option_string->str);
1112     }
1113   }
1115   /* set up encoder parameters */
1116   encoder->x264param.i_fps_num = encoder->fps_num;
1117   encoder->x264param.i_fps_den = encoder->fps_den;
1118   encoder->x264param.i_width = encoder->width;
1119   encoder->x264param.i_height = encoder->height;
1120   if (encoder->par_den > 0) {
1121     encoder->x264param.vui.i_sar_width = encoder->par_num;
1122     encoder->x264param.vui.i_sar_height = encoder->par_den;
1123   }
1124   /* FIXME 0.11 : 2s default keyframe interval seems excessive
1125    * (10s is x264 default) */
1126   encoder->x264param.i_keyint_max = encoder->keyint_max ? encoder->keyint_max :
1127       (2 * encoder->fps_num / encoder->fps_den);
1129   if ((((encoder->height == 576) && ((encoder->width == 720)
1130                   || (encoder->width == 704) || (encoder->width == 352)))
1131           || ((encoder->height == 288) && (encoder->width == 352)))
1132       && (encoder->fps_den == 1) && (encoder->fps_num == 25)) {
1133     encoder->x264param.vui.i_vidformat = 1;     /* PAL */
1134   } else if ((((encoder->height == 480) && ((encoder->width == 720)
1135                   || (encoder->width == 704) || (encoder->width == 352)))
1136           || ((encoder->height == 240) && (encoder->width == 352)))
1137       && (encoder->fps_den == 1001) && ((encoder->fps_num == 30000)
1138           || (encoder->fps_num == 24000))) {
1139     encoder->x264param.vui.i_vidformat = 2;     /* NTSC */
1140   } else
1141     encoder->x264param.vui.i_vidformat = 5;     /* unspecified */
1143   encoder->x264param.analyse.b_psnr = 0;
1145   switch (encoder->pass) {
1146     case GST_X264_ENC_PASS_QUANT:
1147       encoder->x264param.rc.i_rc_method = X264_RC_CQP;
1148       encoder->x264param.rc.i_qp_constant = encoder->quantizer;
1149       break;
1150     case GST_X264_ENC_PASS_QUAL:
1151       encoder->x264param.rc.i_rc_method = X264_RC_CRF;
1152       encoder->x264param.rc.f_rf_constant = encoder->quantizer;
1153       encoder->x264param.rc.i_vbv_max_bitrate = encoder->bitrate;
1154       encoder->x264param.rc.i_vbv_buffer_size
1155           = encoder->x264param.rc.i_vbv_max_bitrate
1156           * encoder->vbv_buf_capacity / 1000;
1157       break;
1158     case GST_X264_ENC_PASS_CBR:
1159     case GST_X264_ENC_PASS_PASS1:
1160     case GST_X264_ENC_PASS_PASS2:
1161     case GST_X264_ENC_PASS_PASS3:
1162     default:
1163       encoder->x264param.rc.i_rc_method = X264_RC_ABR;
1164       encoder->x264param.rc.i_bitrate = encoder->bitrate;
1165       encoder->x264param.rc.i_vbv_max_bitrate = encoder->bitrate;
1166       encoder->x264param.rc.i_vbv_buffer_size =
1167           encoder->x264param.rc.i_vbv_max_bitrate
1168           * encoder->vbv_buf_capacity / 1000;
1169       pass = encoder->pass & 0xF;
1170       break;
1171   }
1173   switch (pass) {
1174     case 0:
1175       encoder->x264param.rc.b_stat_read = 0;
1176       encoder->x264param.rc.b_stat_write = 0;
1177       break;
1178     case 1:
1179       encoder->x264param.rc.b_stat_read = 0;
1180       encoder->x264param.rc.b_stat_write = 1;
1181 #ifdef X264_PRESETS
1182       x264_param_apply_fastfirstpass (&encoder->x264param);
1183 #else
1184       encoder->x264param.i_frame_reference = 1;
1185       encoder->x264param.analyse.b_transform_8x8 = 0;
1186       encoder->x264param.analyse.inter = 0;
1187       encoder->x264param.analyse.i_me_method = X264_ME_DIA;
1188       encoder->x264param.analyse.i_subpel_refine =
1189           MIN (2, encoder->x264param.analyse.i_subpel_refine);
1190       encoder->x264param.analyse.i_trellis = 0;
1191       encoder->x264param.analyse.b_fast_pskip = 1;
1192 #endif /* X264_PRESETS */
1193       break;
1194     case 2:
1195       encoder->x264param.rc.b_stat_read = 1;
1196       encoder->x264param.rc.b_stat_write = 0;
1197       break;
1198     case 3:
1199       encoder->x264param.rc.b_stat_read = 1;
1200       encoder->x264param.rc.b_stat_write = 1;
1201       break;
1202   }
1204 #if X264_BUILD >= 81 && X264_BUILD < 106
1205   /* When vfr is disabled, libx264 ignores buffer timestamps. This causes
1206    * issues with rate control in libx264 with our nanosecond timebase. This
1207    * has been fixed upstream in libx264 but this workaround is required for
1208    * pre-fix versions. */
1209   if (!encoder->x264param.b_vfr_input) {
1210     if (encoder->x264param.i_fps_num == 0) {
1211       GST_ELEMENT_ERROR (encoder, STREAM, ENCODE,
1212           ("Constant framerate is required."),
1213           ("The framerate caps (%d/%d) indicate VFR but VFR is disabled in libx264. (Is the zerolatency tuning in use?)",
1214               encoder->x264param.i_fps_num, encoder->x264param.i_fps_den));
1215       return FALSE;
1216     }
1217     encoder->x264param.i_timebase_num = encoder->x264param.i_fps_den;
1218     encoder->x264param.i_timebase_den = encoder->x264param.i_fps_num;
1219   }
1220 #endif
1222 #ifdef X264_PRESETS
1223   if (encoder->peer_profile) {
1224     if (x264_param_apply_profile (&encoder->x264param, encoder->peer_profile))
1225       GST_WARNING_OBJECT (encoder, "Bad downstream profile name: %s",
1226           encoder->peer_profile);
1227   } else if (encoder->profile) {
1228     if (x264_param_apply_profile (&encoder->x264param,
1229             x264_profile_names[encoder->profile - 1]))
1230       GST_WARNING_OBJECT (encoder, "Bad profile name: %s",
1231           x264_profile_names[encoder->profile - 1]);
1232   }
1233 #endif /* X264_PRESETS */
1235   /* If using an intra profile, all frames are intra frames */
1236   if (encoder->peer_intra_profile)
1237     encoder->x264param.i_keyint_max = encoder->x264param.i_keyint_min = 1;
1239   /* Enforce level limits if they were in the caps */
1240   if (encoder->peer_level) {
1241     encoder->x264param.i_level_idc = encoder->peer_level->level_idc;
1243     encoder->x264param.rc.i_bitrate = MIN (encoder->x264param.rc.i_bitrate,
1244         encoder->peer_level->bitrate);
1245     encoder->x264param.rc.i_vbv_max_bitrate =
1246         MIN (encoder->x264param.rc.i_vbv_max_bitrate,
1247         encoder->peer_level->bitrate);
1248     encoder->x264param.rc.i_vbv_buffer_size =
1249         MIN (encoder->x264param.rc.i_vbv_buffer_size, encoder->peer_level->cpb);
1250     encoder->x264param.analyse.i_mv_range =
1251         MIN (encoder->x264param.analyse.i_mv_range,
1252         encoder->peer_level->mv_range);
1254     if (encoder->peer_level->frame_only) {
1255       encoder->x264param.b_interlaced = FALSE;
1256 #if X264_BUILD >= 95
1257       encoder->x264param.b_fake_interlaced = FALSE;
1258 #endif
1259     }
1260   }
1262   encoder->reconfig = FALSE;
1264   GST_OBJECT_UNLOCK (encoder);
1266   encoder->x264enc = x264_encoder_open (&encoder->x264param);
1267   if (!encoder->x264enc) {
1268     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE,
1269         ("Can not initialize x264 encoder."), (NULL));
1270     return FALSE;
1271   }
1273   return TRUE;
1275 unlock_and_return:
1276   GST_OBJECT_UNLOCK (encoder);
1277   return FALSE;
1280 /* gst_x264_enc_close_encoder
1281  * @encoder:  Encoder which should close.
1282  *
1283  * Close x264 encoder.
1284  */
1285 static void
1286 gst_x264_enc_close_encoder (GstX264Enc * encoder)
1288   if (encoder->x264enc != NULL) {
1289     x264_encoder_close (encoder->x264enc);
1290     encoder->x264enc = NULL;
1291   }
1294 static gboolean
1295 gst_x264_enc_set_profile_and_level (GstX264Enc * encoder, GstCaps * caps)
1297   x264_nal_t *nal;
1298   int i_nal;
1299   int header_return;
1300   gint sps_ni = 0;
1301   guint8 *sps;
1304   header_return = x264_encoder_headers (encoder->x264enc, &nal, &i_nal);
1305   if (header_return < 0) {
1306     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x264 header failed."),
1307         ("x264_encoder_headers return code=%d", header_return));
1308     return FALSE;
1309   }
1311   /* old x264 returns SEI, SPS and PPS, newer one has SEI last */
1312   if (i_nal == 3 && nal[sps_ni].i_type != 7)
1313     sps_ni = 1;
1315   /* old style API: nal's are not encapsulated, and have no sync/size prefix,
1316    * new style API: nal's are encapsulated, and have 4-byte size prefix */
1317 #ifndef X264_ENC_NALS
1318   sps = nal[sps_ni].p_payload;
1319 #else
1320   sps = nal[sps_ni].p_payload + 4;
1321   /* skip NAL unit type */
1322   sps++;
1323 #endif
1325   gst_codec_utils_h264_caps_set_level_and_profile (caps, sps, 3);
1327   return TRUE;
1330 /*
1331  * Returns: Buffer with the stream headers.
1332  */
1333 static GstBuffer *
1334 gst_x264_enc_header_buf (GstX264Enc * encoder)
1336   GstBuffer *buf;
1337   x264_nal_t *nal;
1338   int i_nal;
1339   int header_return;
1340   int i_size;
1341   int nal_size;
1342 #ifndef X264_ENC_NALS
1343   int i_data;
1344 #endif
1345   guint8 *buffer, *sps;
1346   gulong buffer_size;
1347   gint sei_ni = 2, sps_ni = 0, pps_ni = 1;
1349   if (G_UNLIKELY (encoder->x264enc == NULL))
1350     return NULL;
1352   /* Create avcC header. */
1354   header_return = x264_encoder_headers (encoder->x264enc, &nal, &i_nal);
1355   if (header_return < 0) {
1356     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x264 header failed."),
1357         ("x264_encoder_headers return code=%d", header_return));
1358     return NULL;
1359   }
1361   /* old x264 returns SEI, SPS and PPS, newer one has SEI last */
1362   if (i_nal == 3 && nal[sps_ni].i_type != 7) {
1363     sei_ni = 0;
1364     sps_ni = 1;
1365     pps_ni = 2;
1366   }
1368   /* x264 is expected to return an SEI (some identification info),
1369    * and SPS and PPS */
1370   if (i_nal != 3 || nal[sps_ni].i_type != 7 || nal[pps_ni].i_type != 8 ||
1371       nal[sps_ni].i_payload < 4 || nal[pps_ni].i_payload < 1) {
1372     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, (NULL),
1373         ("Unexpected x264 header."));
1374     return NULL;
1375   }
1377   GST_MEMDUMP ("SEI", nal[sei_ni].p_payload, nal[sei_ni].i_payload);
1378   GST_MEMDUMP ("SPS", nal[sps_ni].p_payload, nal[sps_ni].i_payload);
1379   GST_MEMDUMP ("PPS", nal[pps_ni].p_payload, nal[pps_ni].i_payload);
1381   /* nal payloads with emulation_prevention_three_byte, and some header data */
1382   buffer_size = (nal[sps_ni].i_payload + nal[pps_ni].i_payload) * 4 + 100;
1383   buffer = g_malloc (buffer_size);
1385   /* old style API: nal's are not encapsulated, and have no sync/size prefix,
1386    * new style API: nal's are encapsulated, and have 4-byte size prefix */
1387 #ifndef X264_ENC_NALS
1388   sps = nal[sps_ni].p_payload;
1389 #else
1390   sps = nal[sps_ni].p_payload + 4;
1391   /* skip NAL unit type */
1392   sps++;
1393 #endif
1395   buffer[0] = 1;                /* AVC Decoder Configuration Record ver. 1 */
1396   buffer[1] = sps[0];           /* profile_idc                             */
1397   buffer[2] = sps[1];           /* profile_compability                     */
1398   buffer[3] = sps[2];           /* level_idc                               */
1399   buffer[4] = 0xfc | (4 - 1);   /* nal_length_size_minus1                  */
1401   i_size = 5;
1403   buffer[i_size++] = 0xe0 | 1;  /* number of SPSs */
1405 #ifndef X264_ENC_NALS
1406   i_data = buffer_size - i_size - 2;
1407   nal_size = x264_nal_encode (buffer + i_size + 2, &i_data, 0, &nal[sps_ni]);
1408 #else
1409   nal_size = nal[sps_ni].i_payload - 4;
1410   memcpy (buffer + i_size + 2, nal[sps_ni].p_payload + 4, nal_size);
1411 #endif
1412   GST_WRITE_UINT16_BE (buffer + i_size, nal_size);
1413   i_size += nal_size + 2;
1415   buffer[i_size++] = 1;         /* number of PPSs */
1417 #ifndef X264_ENC_NALS
1418   i_data = buffer_size - i_size - 2;
1419   nal_size = x264_nal_encode (buffer + i_size + 2, &i_data, 0, &nal[pps_ni]);
1420 #else
1421   nal_size = nal[pps_ni].i_payload - 4;
1422   memcpy (buffer + i_size + 2, nal[pps_ni].p_payload + 4, nal_size);
1423 #endif
1424   GST_WRITE_UINT16_BE (buffer + i_size, nal_size);
1425   i_size += nal_size + 2;
1427   buf = gst_buffer_new_and_alloc (i_size);
1428   memcpy (GST_BUFFER_DATA (buf), buffer, i_size);
1429   g_free (buffer);
1431   GST_MEMDUMP ("header", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
1433   return buf;
1436 /* gst_x264_enc_set_src_caps
1437  * Returns: TRUE on success.
1438  */
1439 static gboolean
1440 gst_x264_enc_set_src_caps (GstX264Enc * encoder, GstPad * pad, GstCaps * caps)
1442   GstBuffer *buf;
1443   GstCaps *outcaps;
1444   GstStructure *structure;
1445   gboolean res;
1447   outcaps = gst_caps_new_simple ("video/x-h264",
1448       "width", G_TYPE_INT, encoder->width,
1449       "height", G_TYPE_INT, encoder->height,
1450       "framerate", GST_TYPE_FRACTION, encoder->fps_num, encoder->fps_den,
1451       "pixel-aspect-ratio", GST_TYPE_FRACTION, encoder->par_num,
1452       encoder->par_den, NULL);
1454   structure = gst_caps_get_structure (outcaps, 0);
1456   if (encoder->current_byte_stream == GST_X264_ENC_STREAM_FORMAT_FROM_PROPERTY) {
1457     if (encoder->byte_stream) {
1458       encoder->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_BYTE_STREAM;
1459     } else {
1460       encoder->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_AVC;
1461     }
1462   }
1463   if (encoder->current_byte_stream == GST_X264_ENC_STREAM_FORMAT_AVC) {
1464     buf = gst_x264_enc_header_buf (encoder);
1465     if (buf != NULL) {
1466       gst_caps_set_simple (outcaps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
1467       gst_buffer_unref (buf);
1468     }
1469     gst_structure_set (structure, "stream-format", G_TYPE_STRING, "avc", NULL);
1470   } else {
1471     gst_structure_set (structure, "stream-format", G_TYPE_STRING, "byte-stream",
1472         NULL);
1473   }
1474   gst_structure_set (structure, "alignment", G_TYPE_STRING, "au", NULL);
1476   if (!gst_x264_enc_set_profile_and_level (encoder, outcaps)) {
1477     gst_caps_unref (outcaps);
1478     return FALSE;
1479   }
1481   res = gst_pad_set_caps (pad, outcaps);
1482   gst_caps_unref (outcaps);
1484   return res;
1487 static gboolean
1488 gst_x264_enc_sink_set_caps (GstPad * pad, GstCaps * caps)
1490   GstX264Enc *encoder = GST_X264_ENC (GST_OBJECT_PARENT (pad));
1491   GstVideoFormat format;
1492   gint width, height;
1493   gint fps_num, fps_den;
1494   gint par_num, par_den;
1495   gint i;
1496   GstCaps *peer_caps;
1497   const GstCaps *template_caps;
1498   GstCaps *allowed_caps = NULL;
1499   gboolean level_ok = TRUE;
1501   /* get info from caps */
1502   if (!gst_video_format_parse_caps (caps, &format, &width, &height))
1503     return FALSE;
1504   if (!gst_video_parse_caps_framerate (caps, &fps_num, &fps_den))
1505     return FALSE;
1506   if (!gst_video_parse_caps_pixel_aspect_ratio (caps, &par_num, &par_den)) {
1507     par_num = 1;
1508     par_den = 1;
1509   }
1511   /* If the encoder is initialized, do not reinitialize it again if not
1512    * necessary */
1513   if (encoder->x264enc) {
1514     if (width == encoder->width && height == encoder->height
1515         && fps_num == encoder->fps_num && fps_den == encoder->fps_den
1516         && par_num == encoder->par_num && par_den == encoder->par_den)
1517       return TRUE;
1519     /* clear out pending frames */
1520     gst_x264_enc_flush_frames (encoder, TRUE);
1522     encoder->sps_id++;
1523   }
1525   /* store input description */
1526   encoder->format = format;
1527   encoder->width = width;
1528   encoder->height = height;
1529   encoder->fps_num = fps_num;
1530   encoder->fps_den = fps_den;
1531   encoder->par_num = par_num;
1532   encoder->par_den = par_den;
1534   /* prepare a cached image description */
1535   encoder->image_size = gst_video_format_get_size (encoder->format, width,
1536       height);
1537   for (i = 0; i < 3; ++i) {
1538     /* only offsets now, is shifted later. Offsets will be for Y, U, V so we
1539      * can just feed YV12 as I420 to the decoder later */
1540     encoder->offset[i] = gst_video_format_get_component_offset (encoder->format,
1541         i, width, height);
1542     encoder->stride[i] = gst_video_format_get_row_stride (encoder->format,
1543         i, width);
1544   }
1546   encoder->peer_profile = NULL;
1547   encoder->peer_intra_profile = FALSE;
1548   encoder->peer_level = NULL;
1550   /* FIXME: Remove THIS bit in 0.11 when the profile property is removed */
1551   peer_caps = gst_pad_peer_get_caps_reffed (encoder->srcpad);
1552   if (peer_caps) {
1553     gint i;
1554     gboolean has_profile_or_level_or_format = FALSE;
1556     for (i = 0; i < gst_caps_get_size (peer_caps); i++) {
1557       GstStructure *s = gst_caps_get_structure (peer_caps, i);
1559       if (gst_structure_has_name (s, "video/x-h264") &&
1560           (gst_structure_has_field (s, "profile") ||
1561               gst_structure_has_field (s, "level") ||
1562               gst_structure_has_field (s, "stream-format"))) {
1563         has_profile_or_level_or_format = TRUE;
1564         break;
1565       }
1566     }
1568     if (has_profile_or_level_or_format) {
1569       template_caps = gst_pad_get_pad_template_caps (encoder->srcpad);
1571       allowed_caps = gst_caps_intersect (peer_caps, template_caps);
1572     }
1574     gst_caps_unref (peer_caps);
1575   }
1577   /* Replace the bit since FIXME with this
1578    * allowed_caps = gst_pad_get_allowed_caps (encoder->srcpad);
1579    */
1581   if (allowed_caps) {
1582     GstStructure *s;
1583     const gchar *profile;
1584     const gchar *level;
1585     const gchar *stream_format;
1587     if (gst_caps_is_empty (allowed_caps)) {
1588       gst_caps_unref (allowed_caps);
1589       return FALSE;
1590     }
1592     allowed_caps = gst_caps_make_writable (allowed_caps);
1593     gst_pad_fixate_caps (encoder->srcpad, allowed_caps);
1594     s = gst_caps_get_structure (allowed_caps, 0);
1596     profile = gst_structure_get_string (s, "profile");
1597     if (profile) {
1598       if (!strcmp (profile, "constrained-baseline")) {
1599         encoder->peer_profile = "baseline";
1600       } else if (!strcmp (profile, "high-10-intra")) {
1601         encoder->peer_intra_profile = TRUE;
1602         encoder->peer_profile = "high10";
1603       } else if (!strcmp (profile, "high-10")) {
1604         encoder->peer_profile = "high10";
1605       } else if (!strcmp (profile, "high")) {
1606         encoder->peer_profile = "high";
1607       } else if (!strcmp (profile, "main")) {
1608         encoder->peer_profile = "main";
1609       } else {
1610         g_assert_not_reached ();
1611       }
1612     }
1614     level = gst_structure_get_string (s, "level");
1615     if (level) {
1616       int level_idc = gst_codec_utils_h264_get_level_idc (level);
1618       if (level_idc) {
1619         gint i;
1621         for (i = 0; x264_levels[i].level_idc; i++) {
1622           if (level_idc == x264_levels[i].level_idc) {
1623             int mb_width = (width + 15) / 16;
1624             int mb_height = (height + 15) / 16;
1625             int mbs = mb_width * mb_height;
1627             if (x264_levels[i].frame_size < mbs ||
1628                 x264_levels[i].frame_size * 8 < mb_width * mb_width ||
1629                 x264_levels[i].frame_size * 8 < mb_height * mb_height) {
1630               GST_WARNING_OBJECT (encoder,
1631                   "Frame size larger than level %s allows", level);
1632               level_ok = FALSE;
1633               break;
1634             }
1636             if (fps_den &&
1637                 x264_levels[i].mbps < (gint64) mbs * fps_num / fps_den) {
1638               GST_WARNING_OBJECT (encoder,
1639                   "Macroblock rate higher than level %s allows", level);
1640               level_ok = FALSE;
1641               break;
1642             }
1644             encoder->peer_level = &x264_levels[i];
1645             break;
1646           }
1647         }
1648       }
1649     }
1651     stream_format = gst_structure_get_string (s, "stream-format");
1652     encoder->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_FROM_PROPERTY;
1653     if (stream_format) {
1654       if (!strcmp (stream_format, "avc")) {
1655         encoder->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_AVC;
1656         g_string_append_printf (encoder->option_string, ":annexb=0");
1657       } else if (!strcmp (stream_format, "byte-stream")) {
1658         encoder->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_BYTE_STREAM;
1659         g_string_append_printf (encoder->option_string, ":annexb=1");
1660       } else {
1661         /* means we have both in caps and _FROM_PROPERTY should be the option */
1662       }
1663     }
1665     gst_caps_unref (allowed_caps);
1666   }
1668   if (!level_ok)
1669     return FALSE;
1671   if (!gst_x264_enc_init_encoder (encoder))
1672     return FALSE;
1674   if (!gst_x264_enc_set_src_caps (encoder, encoder->srcpad, caps)) {
1675     gst_x264_enc_close_encoder (encoder);
1676     return FALSE;
1677   }
1679   return TRUE;
1682 static GstCaps *
1683 gst_x264_enc_sink_get_caps (GstPad * pad)
1685   GstX264Enc *encoder;
1686   GstPad *peer;
1687   GstCaps *caps;
1689   encoder = GST_X264_ENC (gst_pad_get_parent (pad));
1690   if (!encoder)
1691     return gst_caps_new_empty ();
1693   peer = gst_pad_get_peer (encoder->srcpad);
1694   if (peer) {
1695     const GstCaps *templcaps;
1696     GstCaps *peercaps;
1697     guint i, n;
1699     peercaps = gst_pad_get_caps (peer);
1701     /* Translate peercaps to YUV */
1702     peercaps = gst_caps_make_writable (peercaps);
1703     n = gst_caps_get_size (peercaps);
1704     for (i = 0; i < n; i++) {
1705       GstStructure *s = gst_caps_get_structure (peercaps, i);
1707       gst_structure_set_name (s, "video/x-raw-yuv");
1708       gst_structure_remove_field (s, "stream-format");
1709       gst_structure_remove_field (s, "alignment");
1710     }
1712     templcaps = gst_pad_get_pad_template_caps (pad);
1714     caps = gst_caps_intersect (peercaps, templcaps);
1715     gst_caps_unref (peercaps);
1716     gst_object_unref (peer);
1717     peer = NULL;
1718   } else {
1719     caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
1720   }
1722   /* If we already have caps return them */
1723   if (GST_PAD_CAPS (pad) && gst_caps_can_intersect (GST_PAD_CAPS (pad), caps)) {
1724     GstCaps *tmpcaps = gst_caps_copy (GST_PAD_CAPS (pad));
1726     gst_caps_merge (tmpcaps, caps);
1727     caps = tmpcaps;
1728   }
1730   gst_object_unref (encoder);
1732   return caps;
1735 static gboolean
1736 gst_x264_enc_src_event (GstPad * pad, GstEvent * event)
1738   gboolean ret = TRUE;
1739   GstX264Enc *encoder;
1740   gboolean forward = TRUE;
1742   encoder = GST_X264_ENC (gst_pad_get_parent (pad));
1744   switch (GST_EVENT_TYPE (event)) {
1745     case GST_EVENT_CUSTOM_UPSTREAM:{
1746       const GstStructure *s;
1747       s = gst_event_get_structure (event);
1748       if (gst_structure_has_name (s, "GstForceKeyUnit")) {
1749         /* Set I frame request */
1750         GST_OBJECT_LOCK (encoder);
1751         encoder->i_type = X264_TYPE_I;
1752         encoder->forcekeyunit_event = gst_event_copy (event);
1753         GST_EVENT_TYPE (encoder->forcekeyunit_event) =
1754             GST_EVENT_CUSTOM_DOWNSTREAM;
1755         GST_OBJECT_UNLOCK (encoder);
1756         forward = FALSE;
1757         gst_event_unref (event);
1758       }
1759       break;
1760     }
1761     default:
1762       break;
1763   }
1765   if (forward)
1766     ret = gst_pad_push_event (encoder->sinkpad, event);
1768   gst_object_unref (encoder);
1769   return ret;
1772 static gboolean
1773 gst_x264_enc_sink_event (GstPad * pad, GstEvent * event)
1775   gboolean ret;
1776   GstX264Enc *encoder;
1778   encoder = GST_X264_ENC (gst_pad_get_parent (pad));
1780   switch (GST_EVENT_TYPE (event)) {
1781     case GST_EVENT_EOS:
1782       gst_x264_enc_flush_frames (encoder, TRUE);
1783       break;
1784     case GST_EVENT_TAG:{
1785       GstTagList *tags = NULL;
1787       event =
1788           GST_EVENT (gst_mini_object_make_writable (GST_MINI_OBJECT (event)));
1790       gst_event_parse_tag (event, &tags);
1791       /* drop codec/video-codec and replace encoder/encoder-version */
1792       gst_tag_list_remove_tag (tags, GST_TAG_VIDEO_CODEC);
1793       gst_tag_list_remove_tag (tags, GST_TAG_CODEC);
1794       gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_ENCODER, "x264",
1795           GST_TAG_ENCODER_VERSION, X264_BUILD, NULL);
1796       /* push is done below */
1797       break;
1798       /* no flushing if flush received,
1799        * buffers in encoder are considered (in the) past */
1800     }
1801     case GST_EVENT_CUSTOM_DOWNSTREAM:{
1802       const GstStructure *s;
1803       s = gst_event_get_structure (event);
1804       if (gst_structure_has_name (s, "GstForceKeyUnit")) {
1805         GST_OBJECT_LOCK (encoder);
1806         encoder->i_type = X264_TYPE_I;
1807         GST_OBJECT_UNLOCK (encoder);
1808       }
1809       break;
1810     }
1811     default:
1812       break;
1813   }
1815   ret = gst_pad_push_event (encoder->srcpad, event);
1817   gst_object_unref (encoder);
1818   return ret;
1821 /* chain function
1822  * this function does the actual processing
1823  */
1824 static GstFlowReturn
1825 gst_x264_enc_chain (GstPad * pad, GstBuffer * buf)
1827   GstX264Enc *encoder = GST_X264_ENC (GST_OBJECT_PARENT (pad));
1828   GstFlowReturn ret;
1829   x264_picture_t pic_in;
1830   gint i_nal, i;
1831   if (G_UNLIKELY (encoder->x264enc == NULL))
1832     goto not_inited;
1834   /* create x264_picture_t from the buffer */
1835   /* mostly taken from mplayer (file ve_x264.c) */
1836   if (G_UNLIKELY (GST_BUFFER_SIZE (buf) < encoder->image_size))
1837     goto wrong_buffer_size;
1839   /* remember the timestamp and duration */
1840   g_queue_push_tail (encoder->delay, buf);
1842   /* set up input picture */
1843   memset (&pic_in, 0, sizeof (pic_in));
1845   pic_in.img.i_csp = X264_CSP_I420;
1846   pic_in.img.i_plane = 3;
1847   for (i = 0; i < 3; i++) {
1848     pic_in.img.plane[i] = GST_BUFFER_DATA (buf) + encoder->offset[i];
1849     pic_in.img.i_stride[i] = encoder->stride[i];
1850   }
1852   GST_OBJECT_LOCK (encoder);
1853   pic_in.i_type = encoder->i_type;
1855   /* Reset encoder forced picture type */
1856   encoder->i_type = X264_TYPE_AUTO;
1857   GST_OBJECT_UNLOCK (encoder);
1859   pic_in.i_pts = GST_BUFFER_TIMESTAMP (buf);
1861   ret = gst_x264_enc_encode_frame (encoder, &pic_in, &i_nal, TRUE);
1863   /* input buffer is released later on */
1864   return ret;
1866 /* ERRORS */
1867 not_inited:
1868   {
1869     GST_WARNING_OBJECT (encoder, "Got buffer before set_caps was called");
1870     gst_buffer_unref (buf);
1871     return GST_FLOW_NOT_NEGOTIATED;
1872   }
1873 wrong_buffer_size:
1874   {
1875     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE,
1876         ("Encode x264 frame failed."),
1877         ("Wrong buffer size %d (should be %d)",
1878             GST_BUFFER_SIZE (buf), encoder->image_size));
1879     gst_buffer_unref (buf);
1880     return GST_FLOW_ERROR;
1881   }
1884 static GstFlowReturn
1885 gst_x264_enc_encode_frame (GstX264Enc * encoder, x264_picture_t * pic_in,
1886     int *i_nal, gboolean send)
1888   GstBuffer *out_buf = NULL, *in_buf = NULL;
1889   x264_picture_t pic_out;
1890   x264_nal_t *nal;
1891   int i_size;
1892 #ifndef X264_ENC_NALS
1893   int nal_size;
1894   gint i;
1895 #endif
1896   int encoder_return;
1897   GstFlowReturn ret;
1898   GstClockTime duration;
1899   guint8 *data;
1900   GstEvent *forcekeyunit_event = NULL;
1902   if (G_UNLIKELY (encoder->x264enc == NULL))
1903     return GST_FLOW_NOT_NEGOTIATED;
1905   GST_OBJECT_LOCK (encoder);
1906   if (encoder->reconfig) {
1907     encoder->reconfig = FALSE;
1908     if (x264_encoder_reconfig (encoder->x264enc, &encoder->x264param) < 0)
1909       GST_WARNING_OBJECT (encoder, "Could not reconfigure");
1910   }
1911   GST_OBJECT_UNLOCK (encoder);
1913   encoder_return = x264_encoder_encode (encoder->x264enc,
1914       &nal, i_nal, pic_in, &pic_out);
1916   if (encoder_return < 0) {
1917     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x264 frame failed."),
1918         ("x264_encoder_encode return code=%d", encoder_return));
1919     return GST_FLOW_ERROR;
1920   }
1922   if (!*i_nal) {
1923     return GST_FLOW_OK;
1924   }
1925 #ifndef X264_ENC_NALS
1926   i_size = 0;
1927   for (i = 0; i < *i_nal; i++) {
1928     gint i_data = encoder->buffer_size - i_size - 4;
1930     if (i_data < nal[i].i_payload * 2) {
1931       encoder->buffer_size += 2 * nal[i].i_payload;
1932       encoder->buffer = g_realloc (encoder->buffer, encoder->buffer_size);
1933       i_data = encoder->buffer_size - i_size - 4;
1934     }
1936     nal_size =
1937         x264_nal_encode (encoder->buffer + i_size + 4, &i_data, 0, &nal[i]);
1938     g_assert (encoder->current_byte_stream !=
1939         GST_X264_ENC_STREAM_FORMAT_FROM_PROPERTY);
1940     if (encoder->current_byte_stream == GST_X264_ENC_STREAM_FORMAT_BYTE_STREAM)
1941       GST_WRITE_UINT32_BE (encoder->buffer + i_size, 1);
1942     else
1943       GST_WRITE_UINT32_BE (encoder->buffer + i_size, nal_size);
1945     i_size += nal_size + 4;
1946   }
1947   data = encoder->buffer;
1948 #else
1949   i_size = encoder_return;
1950   data = nal[0].p_payload;
1951 #endif
1953   in_buf = g_queue_pop_head (encoder->delay);
1954   if (in_buf) {
1955     duration = GST_BUFFER_DURATION (in_buf);
1956     gst_buffer_unref (in_buf);
1957   } else {
1958     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, (NULL),
1959         ("Timestamp queue empty."));
1960     return GST_FLOW_ERROR;
1961   }
1963   if (!send)
1964     return GST_FLOW_OK;
1966   ret = gst_pad_alloc_buffer (encoder->srcpad, GST_BUFFER_OFFSET_NONE,
1967       i_size, GST_PAD_CAPS (encoder->srcpad), &out_buf);
1968   if (ret != GST_FLOW_OK)
1969     return ret;
1971   memcpy (GST_BUFFER_DATA (out_buf), data, i_size);
1972   GST_BUFFER_SIZE (out_buf) = i_size;
1974   /* PTS */
1975   /* FIXME ??: maybe use DTS here, since:
1976    * - it is so practiced by other encoders,
1977    * - downstream (e.g. muxers) might not enjoy non-monotone timestamps,
1978    *   whereas a decoder can also deal with DTS */
1979   GST_BUFFER_TIMESTAMP (out_buf) = pic_out.i_pts;
1980   GST_BUFFER_DURATION (out_buf) = duration;
1982 #ifdef X264_INTRA_REFRESH
1983   if (pic_out.b_keyframe) {
1984 #else
1985   if (pic_out.i_type == X264_TYPE_IDR) {
1986 #endif
1987     GST_BUFFER_FLAG_UNSET (out_buf, GST_BUFFER_FLAG_DELTA_UNIT);
1988   } else {
1989     GST_BUFFER_FLAG_SET (out_buf, GST_BUFFER_FLAG_DELTA_UNIT);
1990   }
1992   GST_OBJECT_LOCK (encoder);
1993   forcekeyunit_event = encoder->forcekeyunit_event;
1994   encoder->forcekeyunit_event = NULL;
1995   GST_OBJECT_UNLOCK (encoder);
1996   if (forcekeyunit_event) {
1997     gst_structure_set (forcekeyunit_event->structure,
1998         "timestamp", G_TYPE_UINT64, GST_BUFFER_TIMESTAMP (out_buf), NULL);
1999     gst_pad_push_event (encoder->srcpad, forcekeyunit_event);
2000   }
2002   return gst_pad_push (encoder->srcpad, out_buf);
2005 static void
2006 gst_x264_enc_flush_frames (GstX264Enc * encoder, gboolean send)
2008   GstFlowReturn flow_ret;
2009   gint i_nal;
2011   /* first send the remaining frames */
2012   if (encoder->x264enc)
2013     do {
2014       flow_ret = gst_x264_enc_encode_frame (encoder, NULL, &i_nal, send);
2015 #ifdef X264_DELAYED_FRAMES_API
2016     } while (flow_ret == GST_FLOW_OK
2017         && x264_encoder_delayed_frames (encoder->x264enc) > 0);
2018 #else
2019       /* note that this doesn't flush all frames for > 1 delayed frame */
2020     } while (flow_ret == GST_FLOW_OK && i_nal > 0);
2021 #endif
2023   /* in any case, make sure the delay queue is emptied */
2024   while (!g_queue_is_empty (encoder->delay))
2025     gst_buffer_unref (g_queue_pop_head (encoder->delay));
2028 static GstStateChangeReturn
2029 gst_x264_enc_change_state (GstElement * element, GstStateChange transition)
2031   GstX264Enc *encoder = GST_X264_ENC (element);
2032   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2034   ret = parent_class->change_state (element, transition);
2035   if (ret == GST_STATE_CHANGE_FAILURE)
2036     goto out;
2038   switch (transition) {
2039     case GST_STATE_CHANGE_PAUSED_TO_READY:
2040       gst_x264_enc_flush_frames (encoder, FALSE);
2041       gst_x264_enc_close_encoder (encoder);
2042       gst_x264_enc_reset (encoder);
2043       break;
2044     default:
2045       break;
2046   }
2048 out:
2049   return ret;
2054 static void
2055 gst_x264_enc_reconfig (GstX264Enc * encoder)
2057   switch (encoder->pass) {
2058     case GST_X264_ENC_PASS_QUAL:
2059       encoder->x264param.rc.f_rf_constant = encoder->quantizer;
2060       encoder->x264param.rc.i_vbv_max_bitrate = encoder->bitrate;
2061       encoder->x264param.rc.i_vbv_buffer_size
2062           = encoder->x264param.rc.i_vbv_max_bitrate
2063           * encoder->vbv_buf_capacity / 1000;
2064       break;
2065     case GST_X264_ENC_PASS_CBR:
2066     case GST_X264_ENC_PASS_PASS1:
2067     case GST_X264_ENC_PASS_PASS2:
2068     case GST_X264_ENC_PASS_PASS3:
2069     default:
2070       encoder->x264param.rc.i_bitrate = encoder->bitrate;
2071       encoder->x264param.rc.i_vbv_max_bitrate = encoder->bitrate;
2072       encoder->x264param.rc.i_vbv_buffer_size
2073           = encoder->x264param.rc.i_vbv_max_bitrate
2074           * encoder->vbv_buf_capacity / 1000;
2075       break;
2076   }
2078   encoder->reconfig = TRUE;
2081 static void
2082 gst_x264_enc_set_property (GObject * object, guint prop_id,
2083     const GValue * value, GParamSpec * pspec)
2085   GstX264Enc *encoder;
2086   GstState state;
2088   const gchar *partitions = NULL;
2090   encoder = GST_X264_ENC (object);
2092   GST_OBJECT_LOCK (encoder);
2093   /* state at least matters for sps, bytestream, pass,
2094    * and so by extension ... */
2096   state = GST_STATE (encoder);
2097   if ((state != GST_STATE_READY && state != GST_STATE_NULL) &&
2098       !(pspec->flags & GST_PARAM_MUTABLE_PLAYING))
2099     goto wrong_state;
2101   switch (prop_id) {
2102     case ARG_PASS:
2103       encoder->pass = g_value_get_enum (value);
2104       break;
2105     case ARG_QUANTIZER:
2106       encoder->quantizer = g_value_get_uint (value);
2107       gst_x264_enc_reconfig (encoder);
2108       break;
2109     case ARG_BITRATE:
2110       encoder->bitrate = g_value_get_uint (value);
2111       gst_x264_enc_reconfig (encoder);
2112       break;
2113     case ARG_VBV_BUF_CAPACITY:
2114       encoder->vbv_buf_capacity = g_value_get_uint (value);
2115       gst_x264_enc_reconfig (encoder);
2116       break;
2117     case ARG_SPEED_PRESET:
2118       encoder->speed_preset = g_value_get_enum (value);
2119       break;
2120     case ARG_PSY_TUNE:
2121       encoder->psy_tune = g_value_get_enum (value);
2122       break;
2123     case ARG_TUNE:
2124       encoder->tune = g_value_get_flags (value);
2125       break;
2126     case ARG_PROFILE:
2127       encoder->profile = g_value_get_enum (value);
2128       break;
2129     case ARG_OPTION_STRING:
2130       g_string_assign (encoder->option_string_prop, g_value_get_string (value));
2131       break;
2132     case ARG_THREADS:
2133       encoder->threads = g_value_get_uint (value);
2134       g_string_append_printf (encoder->option_string, ":threads=%d",
2135           encoder->threads);
2136       break;
2137     case ARG_SLICED_THREADS:
2138       encoder->sliced_threads = g_value_get_boolean (value);
2139       g_string_append_printf (encoder->option_string, ":sliced-threads=%d",
2140           encoder->sliced_threads);
2141       break;
2142     case ARG_SYNC_LOOKAHEAD:
2143       encoder->sync_lookahead = g_value_get_int (value);
2144       g_string_append_printf (encoder->option_string, ":sync-lookahead=%d",
2145           encoder->sync_lookahead);
2146       break;
2147     case ARG_STATS_FILE:
2148     case ARG_MULTIPASS_CACHE_FILE:
2149       if (encoder->mp_cache_file)
2150         g_free (encoder->mp_cache_file);
2151       encoder->mp_cache_file = g_value_dup_string (value);
2152       g_string_append_printf (encoder->option_string, ":stats=%s",
2153           encoder->mp_cache_file);
2154       break;
2155     case ARG_BYTE_STREAM:
2156       encoder->byte_stream = g_value_get_boolean (value);
2157       g_string_append_printf (encoder->option_string, ":annexb=%d",
2158           encoder->byte_stream);
2159       break;
2160     case ARG_INTRA_REFRESH:
2161       encoder->intra_refresh = g_value_get_boolean (value);
2162       g_string_append_printf (encoder->option_string, ":intra-refresh=%d",
2163           encoder->intra_refresh);
2164       break;
2165     case ARG_ME:
2166       encoder->me = g_value_get_enum (value);
2167       g_string_append_printf (encoder->option_string, ":me=%s",
2168           x264_motion_est_names[encoder->me]);
2169       break;
2170     case ARG_SUBME:
2171       encoder->subme = g_value_get_uint (value);
2172       g_string_append_printf (encoder->option_string, ":subme=%d",
2173           encoder->subme);
2174       break;
2175     case ARG_ANALYSE:
2176       encoder->analyse = g_value_get_flags (value);
2177       partitions = gst_x264_enc_build_partitions (encoder->analyse);
2178       if (partitions) {
2179         g_string_append_printf (encoder->option_string, ":partitions=%s",
2180             partitions);
2181         g_free ((gpointer) partitions);
2182       }
2183       break;
2184     case ARG_DCT8x8:
2185       encoder->dct8x8 = g_value_get_boolean (value);
2186       g_string_append_printf (encoder->option_string, ":8x8dct=%d",
2187           encoder->dct8x8);
2188       break;
2189     case ARG_REF:
2190       encoder->ref = g_value_get_uint (value);
2191       g_string_append_printf (encoder->option_string, ":ref=%d", encoder->ref);
2192       break;
2193     case ARG_BFRAMES:
2194       encoder->bframes = g_value_get_uint (value);
2195       g_string_append_printf (encoder->option_string, ":bframes=%d",
2196           encoder->bframes);
2197       break;
2198     case ARG_B_ADAPT:
2199       encoder->b_adapt = g_value_get_boolean (value);
2200       g_string_append_printf (encoder->option_string, ":b-adapt=%d",
2201           encoder->b_adapt);
2202       break;
2203     case ARG_B_PYRAMID:
2204       encoder->b_pyramid = g_value_get_boolean (value);
2205 #ifdef X264_B_PYRAMID
2206       g_string_append_printf (encoder->option_string, ":b-pyramid=%s",
2207           x264_b_pyramid_names[encoder->b_pyramid]);
2208 #else
2209       g_string_append_printf (encoder->option_string, ":b-pyramid=%d",
2210           encoder->b_pyramid);
2211 #endif /* X264_B_PYRAMID */
2212       break;
2213     case ARG_WEIGHTB:
2214       encoder->weightb = g_value_get_boolean (value);
2215       g_string_append_printf (encoder->option_string, ":weightb=%d",
2216           encoder->weightb);
2217       break;
2218     case ARG_SPS_ID:
2219       encoder->sps_id = g_value_get_uint (value);
2220       g_string_append_printf (encoder->option_string, ":sps-id=%d",
2221           encoder->sps_id);
2222       break;
2223     case ARG_AU_NALU:
2224       encoder->au_nalu = g_value_get_boolean (value);
2225       g_string_append_printf (encoder->option_string, ":aud=%d",
2226           encoder->au_nalu);
2227       break;
2228     case ARG_TRELLIS:
2229       encoder->trellis = g_value_get_boolean (value);
2230       g_string_append_printf (encoder->option_string, ":trellis=%d",
2231           encoder->trellis);
2232       break;
2233     case ARG_KEYINT_MAX:
2234       encoder->keyint_max = g_value_get_uint (value);
2235       g_string_append_printf (encoder->option_string, ":keyint=%d",
2236           encoder->keyint_max);
2237       break;
2238     case ARG_CABAC:
2239       encoder->cabac = g_value_get_boolean (value);
2240       g_string_append_printf (encoder->option_string, ":cabac=%d",
2241           encoder->cabac);
2242       break;
2243     case ARG_QP_MIN:
2244       encoder->qp_min = g_value_get_uint (value);
2245       g_string_append_printf (encoder->option_string, ":qpmin=%d",
2246           encoder->qp_min);
2247       break;
2248     case ARG_QP_MAX:
2249       encoder->qp_max = g_value_get_uint (value);
2250       g_string_append_printf (encoder->option_string, ":qpmax=%d",
2251           encoder->qp_max);
2252       break;
2253     case ARG_QP_STEP:
2254       encoder->qp_step = g_value_get_uint (value);
2255       g_string_append_printf (encoder->option_string, ":qpstep=%d",
2256           encoder->qp_step);
2257       break;
2258     case ARG_IP_FACTOR:
2259       encoder->ip_factor = g_value_get_float (value);
2260       g_string_append_printf (encoder->option_string, ":ip-factor=%f",
2261           encoder->ip_factor);
2262       break;
2263     case ARG_PB_FACTOR:
2264       encoder->pb_factor = g_value_get_float (value);
2265       g_string_append_printf (encoder->option_string, ":pb-factor=%f",
2266           encoder->pb_factor);
2267       break;
2268     case ARG_RC_MB_TREE:
2269       encoder->mb_tree = g_value_get_boolean (value);
2270       g_string_append_printf (encoder->option_string, ":mbtree=%d",
2271           encoder->mb_tree);
2272       break;
2273     case ARG_RC_LOOKAHEAD:
2274       encoder->rc_lookahead = g_value_get_int (value);
2275       g_string_append_printf (encoder->option_string, ":rc-lookahead=%d",
2276           encoder->rc_lookahead);
2277       break;
2278     case ARG_NR:
2279       encoder->noise_reduction = g_value_get_uint (value);
2280       g_string_append_printf (encoder->option_string, ":nr=%d",
2281           encoder->noise_reduction);
2282       break;
2283     case ARG_INTERLACED:
2284       encoder->interlaced = g_value_get_boolean (value);
2285       g_string_append_printf (encoder->option_string, ":interlaced=%d",
2286           encoder->interlaced);
2287       break;
2288     default:
2289       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2290       break;
2291   }
2292   GST_OBJECT_UNLOCK (encoder);
2293   return;
2295   /* ERROR */
2296 wrong_state:
2297   {
2298     GST_WARNING_OBJECT (encoder, "setting property in wrong state");
2299     GST_OBJECT_UNLOCK (encoder);
2300   }
2303 static void
2304 gst_x264_enc_get_property (GObject * object, guint prop_id,
2305     GValue * value, GParamSpec * pspec)
2307   GstX264Enc *encoder;
2309   encoder = GST_X264_ENC (object);
2311   GST_OBJECT_LOCK (encoder);
2312   switch (prop_id) {
2313     case ARG_THREADS:
2314       g_value_set_uint (value, encoder->threads);
2315       break;
2316     case ARG_SLICED_THREADS:
2317       g_value_set_boolean (value, encoder->sliced_threads);
2318       break;
2319     case ARG_SYNC_LOOKAHEAD:
2320       g_value_set_int (value, encoder->sync_lookahead);
2321       break;
2322     case ARG_PASS:
2323       g_value_set_enum (value, encoder->pass);
2324       break;
2325     case ARG_QUANTIZER:
2326       g_value_set_uint (value, encoder->quantizer);
2327       break;
2328     case ARG_STATS_FILE:
2329     case ARG_MULTIPASS_CACHE_FILE:
2330       g_value_set_string (value, encoder->mp_cache_file);
2331       break;
2332     case ARG_BYTE_STREAM:
2333       g_value_set_boolean (value, encoder->byte_stream);
2334       break;
2335     case ARG_BITRATE:
2336       g_value_set_uint (value, encoder->bitrate);
2337       break;
2338     case ARG_INTRA_REFRESH:
2339       g_value_set_boolean (value, encoder->intra_refresh);
2340       break;
2341     case ARG_VBV_BUF_CAPACITY:
2342       g_value_set_uint (value, encoder->vbv_buf_capacity);
2343       break;
2344     case ARG_ME:
2345       g_value_set_enum (value, encoder->me);
2346       break;
2347     case ARG_SUBME:
2348       g_value_set_uint (value, encoder->subme);
2349       break;
2350     case ARG_ANALYSE:
2351       g_value_set_flags (value, encoder->analyse);
2352       break;
2353     case ARG_DCT8x8:
2354       g_value_set_boolean (value, encoder->dct8x8);
2355       break;
2356     case ARG_REF:
2357       g_value_set_uint (value, encoder->ref);
2358       break;
2359     case ARG_BFRAMES:
2360       g_value_set_uint (value, encoder->bframes);
2361       break;
2362     case ARG_B_ADAPT:
2363       g_value_set_boolean (value, encoder->b_adapt);
2364       break;
2365     case ARG_B_PYRAMID:
2366       g_value_set_boolean (value, encoder->b_pyramid);
2367       break;
2368     case ARG_WEIGHTB:
2369       g_value_set_boolean (value, encoder->weightb);
2370       break;
2371     case ARG_SPS_ID:
2372       g_value_set_uint (value, encoder->sps_id);
2373       break;
2374     case ARG_AU_NALU:
2375       g_value_set_boolean (value, encoder->au_nalu);
2376       break;
2377     case ARG_TRELLIS:
2378       g_value_set_boolean (value, encoder->trellis);
2379       break;
2380     case ARG_KEYINT_MAX:
2381       g_value_set_uint (value, encoder->keyint_max);
2382       break;
2383     case ARG_QP_MIN:
2384       g_value_set_uint (value, encoder->qp_min);
2385       break;
2386     case ARG_QP_MAX:
2387       g_value_set_uint (value, encoder->qp_max);
2388       break;
2389     case ARG_QP_STEP:
2390       g_value_set_uint (value, encoder->qp_step);
2391       break;
2392     case ARG_CABAC:
2393       g_value_set_boolean (value, encoder->cabac);
2394       break;
2395     case ARG_IP_FACTOR:
2396       g_value_set_float (value, encoder->ip_factor);
2397       break;
2398     case ARG_PB_FACTOR:
2399       g_value_set_float (value, encoder->pb_factor);
2400       break;
2401     case ARG_RC_MB_TREE:
2402       g_value_set_boolean (value, encoder->mb_tree);
2403       break;
2404     case ARG_RC_LOOKAHEAD:
2405       g_value_set_int (value, encoder->rc_lookahead);
2406       break;
2407     case ARG_NR:
2408       g_value_set_uint (value, encoder->noise_reduction);
2409       break;
2410     case ARG_INTERLACED:
2411       g_value_set_boolean (value, encoder->interlaced);
2412       break;
2413     case ARG_SPEED_PRESET:
2414       g_value_set_enum (value, encoder->speed_preset);
2415       break;
2416     case ARG_PSY_TUNE:
2417       g_value_set_enum (value, encoder->psy_tune);
2418       break;
2419     case ARG_TUNE:
2420       g_value_set_flags (value, encoder->tune);
2421       break;
2422     case ARG_PROFILE:
2423       g_value_set_enum (value, encoder->profile);
2424       break;
2425     case ARG_OPTION_STRING:
2426       g_value_set_string (value, encoder->option_string_prop->str);
2427       break;
2428     default:
2429       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2430       break;
2431   }
2432   GST_OBJECT_UNLOCK (encoder);
2435 static gboolean
2436 plugin_init (GstPlugin * plugin)
2438   GST_DEBUG_CATEGORY_INIT (x264_enc_debug, "x264enc", 0,
2439       "h264 encoding element");
2441   return gst_element_register (plugin, "x264enc",
2442       GST_RANK_PRIMARY, GST_TYPE_X264_ENC);
2445 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
2446     GST_VERSION_MINOR,
2447     "x264",
2448     "libx264-based H264 plugins",
2449     plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)