1d8fff5152ecda45d03d7f147138a606374b889e
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-ugly / 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  * Copyright (C) 2016 Sebastian Dröge <sebastian@centricular.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 /**
24  * SECTION:element-x264enc
25  * @title: x264enc
26  * @see_also: faac
27  *
28  * This element encodes raw video into H264 compressed data,
29  * also otherwise known as MPEG-4 AVC (Advanced Video Codec).
30  *
31  * The #GstX264Enc:pass property controls the type of encoding.  In case of Constant
32  * Bitrate Encoding (actually ABR), the #GstX264Enc:bitrate will determine the quality
33  * of the encoding.  This will similarly be the case if this target bitrate
34  * is to obtained in multiple (2 or 3) pass encoding.
35  * Alternatively, one may choose to perform Constant Quantizer or Quality encoding,
36  * in which case the #GstX264Enc:quantizer property controls much of the outcome, in that case #GstX264Enc:bitrate is the maximum bitrate.
37  *
38  * The H264 profile that is eventually used depends on a few settings.
39  * If #GstX264Enc:dct8x8 is enabled, then High profile is used.
40  * Otherwise, if #GstX264Enc:cabac entropy coding is enabled or #GstX264Enc:bframes
41  * are allowed, then Main Profile is in effect, and otherwise Baseline profile
42  * applies.  The high profile is imposed by default,
43  * which is fine for most software players and settings,
44  * but in some cases (e.g. hardware platforms) a more restricted profile/level
45  * may be necessary. The recommended way to set a profile is to set it in the
46  * downstream caps.
47  *
48  * If a preset/tuning are specified then these will define the default values and
49  * the property defaults will be ignored. After this the option-string property is
50  * applied, followed by the user-set properties, fast first pass restrictions and
51  * finally the profile restrictions.
52  *
53  * > Some settings, including the default settings, may lead to quite
54  * > some latency (i.e. frame buffering) in the encoder. This may cause problems
55  * > with pipeline stalling in non-trivial pipelines, because the encoder latency
56  * > is often considerably higher than the default size of a simple queue
57  * > element. Such problems are caused by one of the queues in the other
58  * > non-x264enc streams/branches filling up and blocking upstream. They can
59  * > be fixed by relaxing the default time/size/buffer limits on the queue
60  * > elements in the non-x264 branches, or using a (single) multiqueue element
61  * > for all branches. Also see the last example below. You can also work around
62  * > this problem by setting the tune=zerolatency property, but this will affect
63  * > overall encoding quality so may not be appropriate for your use case.
64  *
65  * ## Example pipeline
66  * |[
67  * gst-launch-1.0 -v videotestsrc num-buffers=1000 ! x264enc qp-min=18 ! \
68  *   avimux ! filesink location=videotestsrc.avi
69  * ]| This example pipeline will encode a test video source to H264 muxed in an
70  * AVI container, while ensuring a sane minimum quantization factor to avoid
71  * some (excessive) waste. You should ideally never put H264 into an AVI
72  * container (or really anything else, for that matter) - use Matroska or
73  * MP4/QuickTime or MPEG-TS instead.
74  * |[
75  * gst-launch-1.0 -v videotestsrc num-buffers=1000 ! x264enc pass=quant ! \
76  *   matroskamux ! filesink location=videotestsrc.mkv
77  * ]| This example pipeline will encode a test video source to H264 using fixed
78  * quantization, and muxes it in a Matroska container.
79  * |[
80  * gst-launch-1.0 -v videotestsrc num-buffers=1000 ! x264enc pass=5 quantizer=25 speed-preset=6 ! video/x-h264, profile=baseline ! \
81  *   qtmux ! filesink location=videotestsrc.mov
82  * ]| This example pipeline will encode a test video source to H264 using
83  * constant quality at around Q25 using the 'medium' speed/quality preset and
84  * restricting the options used so that the output is H.264 Baseline Profile
85  * compliant and finally multiplexing the output in Quicktime mov format.
86  * |[
87  * gst-launch-1.0 -v videotestsrc num-buffers=1000 ! tee name=t ! queue ! videoconvert ! autovideosink \
88  *   t. ! queue ! x264enc rc-lookahead=5 ! fakesink
89  * ]| This example pipeline will encode a test video source to H.264 while
90  * displaying the input material at the same time.  As mentioned above,
91  * specific settings are needed in this case to avoid pipeline stalling.
92  * Depending on goals and context, other approaches are possible, e.g.
93  * tune=zerolatency might be configured, or queue sizes increased.
94  *
95  */
96
97 #ifdef HAVE_CONFIG_H
98 #  include "config.h"
99 #endif
100
101 #include "gstx264enc.h"
102
103 #include <gst/pbutils/pbutils.h>
104 #include <gst/video/video.h>
105 #include <gst/video/gstvideometa.h>
106 #include <gst/video/gstvideopool.h>
107
108 #include <string.h>
109 #include <stdlib.h>
110 #include <gmodule.h>
111
112 GST_DEBUG_CATEGORY_STATIC (x264_enc_debug);
113 #define GST_CAT_DEFAULT x264_enc_debug
114
115 struct _GstX264EncVTable
116 {
117   GModule *module;
118
119 #if X264_BUILD < 153
120   const int *x264_bit_depth;
121 #endif
122   const int *x264_chroma_format;
123   void (*x264_encoder_close) (x264_t *);
124   int (*x264_encoder_delayed_frames) (x264_t *);
125   int (*x264_encoder_encode) (x264_t *, x264_nal_t ** pp_nal, int *pi_nal,
126       x264_picture_t * pic_in, x264_picture_t * pic_out);
127   int (*x264_encoder_headers) (x264_t *, x264_nal_t ** pp_nal, int *pi_nal);
128   void (*x264_encoder_intra_refresh) (x264_t *);
129   int (*x264_encoder_maximum_delayed_frames) (x264_t *);
130   x264_t *(*x264_encoder_open) (x264_param_t *);
131   int (*x264_encoder_reconfig) (x264_t *, x264_param_t *);
132   const x264_level_t (*x264_levels)[];
133   void (*x264_param_apply_fastfirstpass) (x264_param_t *);
134   int (*x264_param_apply_profile) (x264_param_t *, const char *);
135   int (*x264_param_default_preset) (x264_param_t *, const char *preset,
136       const char *tune);
137   int (*x264_param_parse) (x264_param_t *, const char *name, const char *value);
138 };
139
140 static GstX264EncVTable default_vtable;
141
142 static GstX264EncVTable *vtable_8bit = NULL, *vtable_10bit = NULL;
143
144 #if X264_BUILD < 153
145 #define LOAD_SYMBOL(name) G_STMT_START { \
146   if (!g_module_symbol (module, #name, (gpointer *) &vtable->name)) { \
147     GST_ERROR ("Failed to load '" #name "' from '%s'", filename); \
148     goto error; \
149   } \
150 } G_STMT_END;
151
152 #ifdef HAVE_X264_ADDITIONAL_LIBRARIES
153 static GstX264EncVTable *
154 load_x264 (const gchar * filename)
155 {
156   GModule *module;
157   GstX264EncVTable *vtable;
158
159   module = g_module_open (filename, G_MODULE_BIND_LOCAL);
160   if (!module) {
161     GST_ERROR ("Failed to load '%s'", filename);
162     return NULL;
163   }
164
165   vtable = g_new0 (GstX264EncVTable, 1);
166   vtable->module = module;
167
168   if (!g_module_symbol (module, G_STRINGIFY (x264_encoder_open),
169           (gpointer *) & vtable->x264_encoder_open)) {
170     GST_ERROR ("Failed to load '" G_STRINGIFY (x264_encoder_open)
171         "' from '%s'. Incompatible version?", filename);
172     goto error;
173   }
174   LOAD_SYMBOL (x264_bit_depth);
175   LOAD_SYMBOL (x264_chroma_format);
176   LOAD_SYMBOL (x264_encoder_close);
177   LOAD_SYMBOL (x264_encoder_delayed_frames);
178   LOAD_SYMBOL (x264_encoder_encode);
179   LOAD_SYMBOL (x264_encoder_headers);
180   LOAD_SYMBOL (x264_encoder_intra_refresh);
181   LOAD_SYMBOL (x264_encoder_maximum_delayed_frames);
182   LOAD_SYMBOL (x264_encoder_reconfig);
183   LOAD_SYMBOL (x264_levels);
184   LOAD_SYMBOL (x264_param_apply_fastfirstpass);
185   LOAD_SYMBOL (x264_param_apply_profile);
186   LOAD_SYMBOL (x264_param_default_preset);
187   LOAD_SYMBOL (x264_param_parse);
188
189   return vtable;
190
191 error:
192   g_module_close (vtable->module);
193   g_free (vtable);
194   return NULL;
195 }
196
197 static void
198 unload_x264 (GstX264EncVTable * vtable)
199 {
200   if (vtable->module) {
201     g_module_close (vtable->module);
202     g_free (vtable);
203   }
204 }
205 #endif
206
207 #undef LOAD_SYMBOL
208 #endif
209
210 static gboolean
211 gst_x264_enc_add_x264_chroma_format (GstStructure * s,
212     gboolean allow_420_8, gboolean allow_420_10, gboolean allow_422,
213     gboolean allow_444)
214 {
215   GValue fmts = G_VALUE_INIT;
216   GValue fmt = G_VALUE_INIT;
217   gboolean ret = FALSE;
218
219   g_value_init (&fmts, GST_TYPE_LIST);
220   g_value_init (&fmt, G_TYPE_STRING);
221
222   if (vtable_8bit) {
223     gint chroma_format = *vtable_8bit->x264_chroma_format;
224
225     if ((chroma_format == 0 || chroma_format == X264_CSP_I444) && allow_444) {
226       g_value_set_string (&fmt, "Y444");
227       gst_value_list_append_value (&fmts, &fmt);
228     }
229
230     if ((chroma_format == 0 || chroma_format == X264_CSP_I422) && allow_422) {
231       g_value_set_string (&fmt, "Y42B");
232       gst_value_list_append_value (&fmts, &fmt);
233     }
234
235     if ((chroma_format == 0 || chroma_format == X264_CSP_I420) && allow_420_8) {
236       g_value_set_string (&fmt, "I420");
237       gst_value_list_append_value (&fmts, &fmt);
238       g_value_set_string (&fmt, "YV12");
239       gst_value_list_append_value (&fmts, &fmt);
240       g_value_set_string (&fmt, "NV12");
241       gst_value_list_append_value (&fmts, &fmt);
242     }
243   }
244
245   if (vtable_10bit) {
246     gint chroma_format = *vtable_10bit->x264_chroma_format;
247
248     if ((chroma_format == 0 || chroma_format == X264_CSP_I444) && allow_444) {
249       if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
250         g_value_set_string (&fmt, "Y444_10LE");
251       else
252         g_value_set_string (&fmt, "Y444_10BE");
253
254       gst_value_list_append_value (&fmts, &fmt);
255     }
256
257     if ((chroma_format == 0 || chroma_format == X264_CSP_I422) && allow_422) {
258       if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
259         g_value_set_string (&fmt, "I422_10LE");
260       else
261         g_value_set_string (&fmt, "I422_10BE");
262
263       gst_value_list_append_value (&fmts, &fmt);
264     }
265
266     if ((chroma_format == 0 || chroma_format == X264_CSP_I420) && allow_420_10) {
267       if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
268         g_value_set_string (&fmt, "I420_10LE");
269       else
270         g_value_set_string (&fmt, "I420_10BE");
271
272       gst_value_list_append_value (&fmts, &fmt);
273     }
274   }
275
276   if (gst_value_list_get_size (&fmts) != 0) {
277     gst_structure_take_value (s, "format", &fmts);
278     ret = TRUE;
279   } else {
280     g_value_unset (&fmts);
281   }
282
283   g_value_unset (&fmt);
284
285   return ret;
286 }
287
288 #if X264_BUILD < 153
289 static gboolean
290 load_x264_libraries (void)
291 {
292   if (*default_vtable.x264_bit_depth == 8) {
293     vtable_8bit = &default_vtable;
294     GST_INFO ("8-bit depth supported");
295   } else if (*default_vtable.x264_bit_depth == 10) {
296     vtable_10bit = &default_vtable;
297     GST_INFO ("10-bit depth supported");
298   }
299 #ifdef HAVE_X264_ADDITIONAL_LIBRARIES
300   {
301     gchar **libraries = g_strsplit (HAVE_X264_ADDITIONAL_LIBRARIES, ":", -1);
302     gchar **p = libraries;
303
304     while (*p && (!vtable_8bit || !vtable_10bit)) {
305       GstX264EncVTable *vtable = load_x264 (*p);
306
307       if (vtable) {
308         if (!vtable_8bit && *vtable->x264_bit_depth == 8) {
309           GST_INFO ("8-bit depth support loaded from %s", *p);
310           vtable_8bit = vtable;
311         } else if (!vtable_10bit && *vtable->x264_bit_depth == 10) {
312           GST_INFO ("10-bit depth support loaded from %s", *p);
313           vtable_10bit = vtable;
314         } else {
315           unload_x264 (vtable);
316         }
317       }
318
319       p++;
320     }
321     g_strfreev (libraries);
322   }
323 #endif
324
325   if (!vtable_8bit && !vtable_10bit)
326     return FALSE;
327
328   return TRUE;
329 }
330
331 #else /* X264_BUILD >= 153 */
332
333 static gboolean
334 load_x264_libraries (void)
335 {
336 #if X264_BIT_DEPTH == 0         /* all */
337   GST_INFO ("8-bit depth and 10-bit depth supported");
338   vtable_8bit = &default_vtable;
339   vtable_10bit = &default_vtable;
340 #elif X264_BIT_DEPTH == 8
341   GST_INFO ("Only 8-bit depth supported");
342   vtable_8bit = &default_vtable;
343 #elif X264_BIT_DEPTH == 10
344   GST_INFO ("Only 10-bit depth supported");
345   vtable_10bit = &default_vtable;
346 #else
347 #error "unexpected X264_BIT_DEPTH value"
348 #endif
349
350 #ifdef HAVE_X264_ADDITIONAL_LIBRARIES
351   GST_WARNING ("Ignoring configured additional libraries %s, using libx264 "
352       "version enabled for multiple bit depths",
353       HAVE_X264_ADDITIONAL_LIBRARIES);
354 #endif
355
356   return TRUE;
357 }
358
359 #endif
360
361 enum
362 {
363   ARG_0,
364   ARG_THREADS,
365   ARG_SLICED_THREADS,
366   ARG_SYNC_LOOKAHEAD,
367   ARG_PASS,
368   ARG_QUANTIZER,
369   ARG_MULTIPASS_CACHE_FILE,
370   ARG_BYTE_STREAM,
371   ARG_BITRATE,
372   ARG_INTRA_REFRESH,
373   ARG_VBV_BUF_CAPACITY,
374   ARG_ME,
375   ARG_SUBME,
376   ARG_ANALYSE,
377   ARG_DCT8x8,
378   ARG_REF,
379   ARG_BFRAMES,
380   ARG_B_ADAPT,
381   ARG_B_PYRAMID,
382   ARG_WEIGHTB,
383   ARG_SPS_ID,
384   ARG_AU_NALU,
385   ARG_TRELLIS,
386   ARG_KEYINT_MAX,
387   ARG_CABAC,
388   ARG_QP_MIN,
389   ARG_QP_MAX,
390   ARG_QP_STEP,
391   ARG_IP_FACTOR,
392   ARG_PB_FACTOR,
393   ARG_RC_MB_TREE,
394   ARG_RC_LOOKAHEAD,
395   ARG_NR,
396   ARG_INTERLACED,
397   ARG_OPTION_STRING,
398   ARG_SPEED_PRESET,
399   ARG_PSY_TUNE,
400   ARG_TUNE,
401   ARG_FRAME_PACKING,
402   ARG_INSERT_VUI,
403 };
404
405 #define ARG_THREADS_DEFAULT            0        /* 0 means 'auto' which is 1.5x number of CPU cores */
406 #define ARG_PASS_DEFAULT               0
407 #define ARG_QUANTIZER_DEFAULT          21
408 #define ARG_MULTIPASS_CACHE_FILE_DEFAULT "x264.log"
409 #define ARG_BYTE_STREAM_DEFAULT        FALSE
410 #define ARG_BITRATE_DEFAULT            (2 * 1024)
411 #define ARG_VBV_BUF_CAPACITY_DEFAULT   600
412 #define ARG_ME_DEFAULT                 X264_ME_HEX
413 #define ARG_SUBME_DEFAULT              1
414 #define ARG_ANALYSE_DEFAULT            0
415 #define ARG_DCT8x8_DEFAULT             FALSE
416 #define ARG_REF_DEFAULT                3
417 #define ARG_BFRAMES_DEFAULT            0
418 #define ARG_B_ADAPT_DEFAULT            TRUE
419 #define ARG_B_PYRAMID_DEFAULT          FALSE
420 #define ARG_WEIGHTB_DEFAULT            FALSE
421 #define ARG_SPS_ID_DEFAULT             0
422 #define ARG_AU_NALU_DEFAULT            TRUE
423 #define ARG_TRELLIS_DEFAULT            TRUE
424 #define ARG_KEYINT_MAX_DEFAULT         0
425 #define ARG_CABAC_DEFAULT              TRUE
426 #define ARG_QP_MIN_DEFAULT             10
427 #define ARG_QP_MAX_DEFAULT             51
428 #define ARG_QP_STEP_DEFAULT            4
429 #define ARG_IP_FACTOR_DEFAULT          1.4
430 #define ARG_PB_FACTOR_DEFAULT          1.3
431 #define ARG_NR_DEFAULT                 0
432 #define ARG_INTERLACED_DEFAULT         FALSE
433 #define ARG_SLICED_THREADS_DEFAULT     FALSE
434 #define ARG_SYNC_LOOKAHEAD_DEFAULT     -1
435 #define ARG_RC_MB_TREE_DEFAULT         TRUE
436 #define ARG_RC_LOOKAHEAD_DEFAULT       40
437 #define ARG_INTRA_REFRESH_DEFAULT      FALSE
438 #define ARG_OPTION_STRING_DEFAULT      ""
439 static GString *x264enc_defaults;
440 #define ARG_SPEED_PRESET_DEFAULT       6        /* 'medium' preset - matches x264 CLI default */
441 #define ARG_PSY_TUNE_DEFAULT           0        /* no psy tuning */
442 #define ARG_TUNE_DEFAULT               0        /* no tuning */
443 #define ARG_FRAME_PACKING_DEFAULT      -1       /* automatic (none, or from input caps) */
444 #define ARG_INSERT_VUI_DEFAULT         TRUE
445
446 enum
447 {
448   GST_X264_ENC_STREAM_FORMAT_FROM_PROPERTY,
449   GST_X264_ENC_STREAM_FORMAT_AVC,
450   GST_X264_ENC_STREAM_FORMAT_BYTE_STREAM
451 };
452
453 enum
454 {
455   GST_X264_ENC_PASS_CBR = 0,
456   GST_X264_ENC_PASS_QUANT = 0x04,
457   GST_X264_ENC_PASS_QUAL,
458   GST_X264_ENC_PASS_PASS1 = 0x11,
459   GST_X264_ENC_PASS_PASS2,
460   GST_X264_ENC_PASS_PASS3
461 };
462
463 #define GST_X264_ENC_PASS_TYPE (gst_x264_enc_pass_get_type())
464 static GType
465 gst_x264_enc_pass_get_type (void)
466 {
467   static GType pass_type = 0;
468
469   static const GEnumValue pass_types[] = {
470     {GST_X264_ENC_PASS_CBR, "Constant Bitrate Encoding", "cbr"},
471     {GST_X264_ENC_PASS_QUANT, "Constant Quantizer", "quant"},
472     {GST_X264_ENC_PASS_QUAL, "Constant Quality", "qual"},
473     {GST_X264_ENC_PASS_PASS1, "VBR Encoding - Pass 1", "pass1"},
474     {GST_X264_ENC_PASS_PASS2, "VBR Encoding - Pass 2", "pass2"},
475     {GST_X264_ENC_PASS_PASS3, "VBR Encoding - Pass 3", "pass3"},
476     {0, NULL, NULL}
477   };
478
479   if (!pass_type) {
480     pass_type = g_enum_register_static ("GstX264EncPass", pass_types);
481   }
482   return pass_type;
483 }
484
485 #define GST_X264_ENC_ME_TYPE (gst_x264_enc_me_get_type())
486 static GType
487 gst_x264_enc_me_get_type (void)
488 {
489   static GType me_type = 0;
490   static GEnumValue *me_types;
491   int n, i;
492
493   if (me_type != 0)
494     return me_type;
495
496   n = 0;
497   while (x264_motion_est_names[n] != NULL)
498     n++;
499
500   me_types = g_new0 (GEnumValue, n + 1);
501
502   for (i = 0; i < n; i++) {
503     me_types[i].value = i;
504     me_types[i].value_name = x264_motion_est_names[i];
505     me_types[i].value_nick = x264_motion_est_names[i];
506   }
507
508   me_type = g_enum_register_static ("GstX264EncMe", me_types);
509
510   return me_type;
511 }
512
513 #define GST_X264_ENC_ANALYSE_TYPE (gst_x264_enc_analyse_get_type())
514 static GType
515 gst_x264_enc_analyse_get_type (void)
516 {
517   static GType analyse_type = 0;
518   static const GFlagsValue analyse_types[] = {
519     {X264_ANALYSE_I4x4, "i4x4", "i4x4"},
520     {X264_ANALYSE_I8x8, "i8x8", "i8x8"},
521     {X264_ANALYSE_PSUB16x16, "p8x8", "p8x8"},
522     {X264_ANALYSE_PSUB8x8, "p4x4", "p4x4"},
523     {X264_ANALYSE_BSUB16x16, "b8x8", "b8x8"},
524     {0, NULL, NULL},
525   };
526
527   if (!analyse_type) {
528     analyse_type = g_flags_register_static ("GstX264EncAnalyse", analyse_types);
529   }
530   return analyse_type;
531 }
532
533 #define GST_X264_ENC_SPEED_PRESET_TYPE (gst_x264_enc_speed_preset_get_type())
534 static GType
535 gst_x264_enc_speed_preset_get_type (void)
536 {
537   static GType speed_preset_type = 0;
538   static GEnumValue *speed_preset_types;
539   int n, i;
540
541   if (speed_preset_type != 0)
542     return speed_preset_type;
543
544   n = 0;
545   while (x264_preset_names[n] != NULL)
546     n++;
547
548   speed_preset_types = g_new0 (GEnumValue, n + 2);
549
550   speed_preset_types[0].value = 0;
551   speed_preset_types[0].value_name = "No preset";
552   speed_preset_types[0].value_nick = "None";
553
554   for (i = 1; i <= n; i++) {
555     speed_preset_types[i].value = i;
556     speed_preset_types[i].value_name = x264_preset_names[i - 1];
557     speed_preset_types[i].value_nick = x264_preset_names[i - 1];
558   }
559
560   speed_preset_type =
561       g_enum_register_static ("GstX264EncPreset", speed_preset_types);
562
563   return speed_preset_type;
564 }
565
566 static const GFlagsValue tune_types[] = {
567   {0x0, "No tuning", "none"},
568   {0x1, "Still image", "stillimage"},
569   {0x2, "Fast decode", "fastdecode"},
570   {0x4, "Zero latency", "zerolatency"},
571   {0, NULL, NULL},
572 };
573
574 #define GST_X264_ENC_TUNE_TYPE (gst_x264_enc_tune_get_type())
575 static GType
576 gst_x264_enc_tune_get_type (void)
577 {
578   static GType tune_type = 0;
579
580   if (!tune_type) {
581     tune_type = g_flags_register_static ("GstX264EncTune", tune_types + 1);
582   }
583   return tune_type;
584 }
585
586 enum
587 {
588   GST_X264_ENC_TUNE_NONE,
589   GST_X264_ENC_TUNE_FILM,
590   GST_X264_ENC_TUNE_ANIMATION,
591   GST_X264_ENC_TUNE_GRAIN,
592   GST_X264_ENC_TUNE_PSNR,
593   GST_X264_ENC_TUNE_SSIM,
594   GST_X264_ENC_TUNE_LAST
595 };
596
597 static const GEnumValue psy_tune_types[] = {
598   {GST_X264_ENC_TUNE_NONE, "No tuning", "none"},
599   {GST_X264_ENC_TUNE_FILM, "Film", "film"},
600   {GST_X264_ENC_TUNE_ANIMATION, "Animation", "animation"},
601   {GST_X264_ENC_TUNE_GRAIN, "Grain", "grain"},
602   {GST_X264_ENC_TUNE_PSNR, "PSNR", "psnr"},
603   {GST_X264_ENC_TUNE_SSIM, "SSIM", "ssim"},
604   {0, NULL, NULL},
605 };
606
607 #define GST_X264_ENC_PSY_TUNE_TYPE (gst_x264_enc_psy_tune_get_type())
608 static GType
609 gst_x264_enc_psy_tune_get_type (void)
610 {
611   static GType psy_tune_type = 0;
612
613   if (!psy_tune_type) {
614     psy_tune_type =
615         g_enum_register_static ("GstX264EncPsyTune", psy_tune_types);
616   }
617   return psy_tune_type;
618 }
619
620 static void
621 gst_x264_enc_build_tunings_string (GstX264Enc * x264enc)
622 {
623   int i = 1;
624
625   if (x264enc->tunings)
626     g_string_free (x264enc->tunings, TRUE);
627
628   if (x264enc->psy_tune) {
629     x264enc->tunings =
630         g_string_new (psy_tune_types[x264enc->psy_tune].value_nick);
631   } else {
632     x264enc->tunings = g_string_new (NULL);
633   }
634
635   while (tune_types[i].value_name) {
636     if (x264enc->tune & (1 << (i - 1)))
637       g_string_append_printf (x264enc->tunings, "%s%s",
638           x264enc->tunings->len ? "," : "", tune_types[i].value_nick);
639     i++;
640   }
641
642   if (x264enc->tunings->len)
643     GST_DEBUG_OBJECT (x264enc, "Constructed tunings string: %s",
644         x264enc->tunings->str);
645 }
646
647 #define GST_X264_ENC_FRAME_PACKING_TYPE (gst_x264_enc_frame_packing_get_type())
648 static GType
649 gst_x264_enc_frame_packing_get_type (void)
650 {
651   static GType fpa_type = 0;
652
653   static const GEnumValue fpa_types[] = {
654     {-1, "Automatic (use incoming video information)", "auto"},
655     {0, "checkerboard - Left and Right pixels alternate in a checkerboard pattern", "checkerboard"},
656     {1, "column interleaved - Alternating pixel columns represent Left and Right views", "column-interleaved"},
657     {2, "row interleaved - Alternating pixel rows represent Left and Right views", "row-interleaved"},
658     {3, "side by side - The left half of the frame contains the Left eye view, the right half the Right eye view", "side-by-side"},
659     {4, "top bottom - L is on top, R on bottom", "top-bottom"},
660     {5, "frame interleaved - Each frame contains either Left or Right view alternately", "frame-interleaved"},
661     {0, NULL, NULL}
662   };
663
664   if (!fpa_type) {
665     fpa_type = g_enum_register_static ("GstX264EncFramePacking", fpa_types);
666   }
667   return fpa_type;
668 }
669
670 static gint
671 gst_x264_enc_mview_mode_to_frame_packing (GstVideoMultiviewMode mode)
672 {
673   switch (mode) {
674     case GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD:
675       return 0;
676     case GST_VIDEO_MULTIVIEW_MODE_COLUMN_INTERLEAVED:
677       return 1;
678     case GST_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED:
679       return 2;
680     case GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE:
681       return 3;
682     case GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM:
683       return 4;
684     case GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME:
685       return 5;
686     default:
687       break;
688   }
689
690   return -1;
691 }
692
693 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
694     GST_PAD_SRC,
695     GST_PAD_ALWAYS,
696     GST_STATIC_CAPS ("video/x-h264, "
697         "framerate = (fraction) [0/1, MAX], "
698         "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ], "
699         "stream-format = (string) { avc, byte-stream }, "
700         "alignment = (string) au, "
701         "profile = (string) { high-4:4:4, high-4:2:2, high-10, high, main,"
702         " baseline, constrained-baseline, high-4:4:4-intra, high-4:2:2-intra,"
703         " high-10-intra }")
704     );
705
706 static void gst_x264_enc_finalize (GObject * object);
707 static gboolean gst_x264_enc_start (GstVideoEncoder * encoder);
708 static gboolean gst_x264_enc_stop (GstVideoEncoder * encoder);
709 static gboolean gst_x264_enc_flush (GstVideoEncoder * encoder);
710
711 static gboolean gst_x264_enc_init_encoder (GstX264Enc * encoder);
712 static void gst_x264_enc_close_encoder (GstX264Enc * encoder);
713
714 static GstFlowReturn gst_x264_enc_finish (GstVideoEncoder * encoder);
715 static GstFlowReturn gst_x264_enc_handle_frame (GstVideoEncoder * encoder,
716     GstVideoCodecFrame * frame);
717 static void gst_x264_enc_flush_frames (GstX264Enc * encoder, gboolean send);
718 static GstFlowReturn gst_x264_enc_encode_frame (GstX264Enc * encoder,
719     x264_picture_t * pic_in, GstVideoCodecFrame * input_frame, int *i_nal,
720     gboolean send);
721 static gboolean gst_x264_enc_set_format (GstVideoEncoder * video_enc,
722     GstVideoCodecState * state);
723 static gboolean gst_x264_enc_propose_allocation (GstVideoEncoder * encoder,
724     GstQuery * query);
725
726 static void gst_x264_enc_set_property (GObject * object, guint prop_id,
727     const GValue * value, GParamSpec * pspec);
728 static void gst_x264_enc_get_property (GObject * object, guint prop_id,
729     GValue * value, GParamSpec * pspec);
730 static gboolean x264_element_init (GstPlugin * plugin);
731
732 typedef gboolean (*LoadPresetFunc) (GstPreset * preset, const gchar * name);
733
734 LoadPresetFunc parent_load_preset = NULL;
735
736 static gboolean
737 gst_x264_enc_load_preset (GstPreset * preset, const gchar * name)
738 {
739   GstX264Enc *enc = GST_X264_ENC (preset);
740   gboolean res;
741
742   gst_encoder_bitrate_profile_manager_start_loading_preset
743       (enc->bitrate_manager);
744   res = parent_load_preset (preset, name);
745   gst_encoder_bitrate_profile_manager_end_loading_preset (enc->bitrate_manager,
746       res ? name : NULL);
747
748   return res;
749 }
750
751 static void
752 gst_x264_enc_preset_interface_init (GstPresetInterface * iface)
753 {
754   parent_load_preset = iface->load_preset;
755   iface->load_preset = gst_x264_enc_load_preset;
756 }
757
758 #define gst_x264_enc_parent_class parent_class
759 G_DEFINE_TYPE_WITH_CODE (GstX264Enc, gst_x264_enc, GST_TYPE_VIDEO_ENCODER,
760     G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET,
761         gst_x264_enc_preset_interface_init));
762 GST_ELEMENT_REGISTER_DEFINE_CUSTOM (x264enc, x264_element_init)
763 /* don't forget to free the string after use */
764      static const gchar *gst_x264_enc_build_partitions (gint analyse)
765 {
766   GString *string;
767
768   if (!analyse)
769     return NULL;
770
771   string = g_string_new (NULL);
772   if (analyse & X264_ANALYSE_I4x4)
773     g_string_append (string, "i4x4");
774   if (analyse & X264_ANALYSE_I8x8)
775     g_string_append (string, ",i8x8");
776   if (analyse & X264_ANALYSE_PSUB16x16)
777     g_string_append (string, ",p8x8");
778   if (analyse & X264_ANALYSE_PSUB8x8)
779     g_string_append (string, ",p4x4");
780   if (analyse & X264_ANALYSE_BSUB16x16)
781     g_string_append (string, ",b8x8");
782
783   return (const gchar *) g_string_free (string, FALSE);
784 }
785
786 static void
787 check_formats (const gchar * str, gboolean * has_420_8, gboolean * has_420_10,
788     gboolean * has_422, gboolean * has_444)
789 {
790   if (g_str_has_prefix (str, "high-4:4:4"))
791     *has_444 = TRUE;
792   else if (g_str_has_prefix (str, "high-4:2:2"))
793     *has_422 = TRUE;
794   else if (g_str_has_prefix (str, "high-10"))
795     *has_420_10 = TRUE;
796   else
797     *has_420_8 = TRUE;
798 }
799
800
801 /* allowed input caps depending on whether libx264 was built for 8 or 10 bits */
802 static GstCaps *
803 gst_x264_enc_sink_getcaps (GstVideoEncoder * enc, GstCaps * filter)
804 {
805   GstCaps *supported_incaps;
806   GstCaps *allowed;
807   GstCaps *filter_caps, *fcaps;
808   gint i, j, k;
809
810   supported_incaps =
811       gst_pad_get_pad_template_caps (GST_VIDEO_ENCODER_SINK_PAD (enc));
812
813   /* Allow downstream to specify width/height/framerate/PAR constraints
814    * and forward them upstream for video converters to handle
815    */
816   allowed = gst_pad_get_allowed_caps (enc->srcpad);
817
818   if (!allowed || gst_caps_is_empty (allowed) || gst_caps_is_any (allowed)) {
819     fcaps = supported_incaps;
820     goto done;
821   }
822
823   GST_LOG_OBJECT (enc, "template caps %" GST_PTR_FORMAT, supported_incaps);
824   GST_LOG_OBJECT (enc, "allowed caps %" GST_PTR_FORMAT, allowed);
825
826   filter_caps = gst_caps_new_empty ();
827
828   for (i = 0; i < gst_caps_get_size (supported_incaps); i++) {
829     GQuark q_name =
830         gst_structure_get_name_id (gst_caps_get_structure (supported_incaps,
831             i));
832
833     for (j = 0; j < gst_caps_get_size (allowed); j++) {
834       const GstStructure *allowed_s = gst_caps_get_structure (allowed, j);
835       const GValue *val;
836       GstStructure *s;
837
838       /* FIXME Find a way to reuse gst_video_encoder_proxy_getcaps so that
839        * we do not need to copy that logic */
840       s = gst_structure_new_id_empty (q_name);
841       if ((val = gst_structure_get_value (allowed_s, "width")))
842         gst_structure_set_value (s, "width", val);
843       if ((val = gst_structure_get_value (allowed_s, "height")))
844         gst_structure_set_value (s, "height", val);
845       if ((val = gst_structure_get_value (allowed_s, "framerate")))
846         gst_structure_set_value (s, "framerate", val);
847       if ((val = gst_structure_get_value (allowed_s, "pixel-aspect-ratio")))
848         gst_structure_set_value (s, "pixel-aspect-ratio", val);
849       if ((val = gst_structure_get_value (allowed_s, "colorimetry")))
850         gst_structure_set_value (s, "colorimetry", val);
851       if ((val = gst_structure_get_value (allowed_s, "chroma-site")))
852         gst_structure_set_value (s, "chroma-site", val);
853
854       if ((val = gst_structure_get_value (allowed_s, "profile"))) {
855         gboolean has_420_8 = FALSE;
856         gboolean has_420_10 = FALSE;
857         gboolean has_422 = FALSE;
858         gboolean has_444 = FALSE;
859
860         if (G_VALUE_HOLDS_STRING (val)) {
861           check_formats (g_value_get_string (val), &has_420_8, &has_420_10,
862               &has_422, &has_444);
863         } else if (GST_VALUE_HOLDS_LIST (val)) {
864           for (k = 0; k < gst_value_list_get_size (val); k++) {
865             const GValue *vlist = gst_value_list_get_value (val, k);
866
867             if (G_VALUE_HOLDS_STRING (vlist))
868               check_formats (g_value_get_string (vlist), &has_420_8,
869                   &has_420_10, &has_422, &has_444);
870           }
871         }
872
873         gst_x264_enc_add_x264_chroma_format (s, has_420_8, has_420_10, has_422,
874             has_444);
875       }
876
877       filter_caps = gst_caps_merge_structure (filter_caps, s);
878     }
879   }
880
881   fcaps = gst_caps_intersect (filter_caps, supported_incaps);
882   gst_caps_unref (filter_caps);
883   gst_caps_unref (supported_incaps);
884
885   if (filter) {
886     GST_LOG_OBJECT (enc, "intersecting with %" GST_PTR_FORMAT, filter);
887     filter_caps = gst_caps_intersect (fcaps, filter);
888     gst_caps_unref (fcaps);
889     fcaps = filter_caps;
890   }
891
892 done:
893   gst_caps_replace (&allowed, NULL);
894
895   GST_LOG_OBJECT (enc, "proxy caps %" GST_PTR_FORMAT, fcaps);
896
897   return fcaps;
898 }
899
900 static gboolean
901 gst_x264_enc_sink_query (GstVideoEncoder * enc, GstQuery * query)
902 {
903   GstPad *pad = GST_VIDEO_ENCODER_SINK_PAD (enc);
904   gboolean ret = FALSE;
905
906   GST_DEBUG ("Received %s query on sinkpad, %" GST_PTR_FORMAT,
907       GST_QUERY_TYPE_NAME (query), query);
908
909   switch (GST_QUERY_TYPE (query)) {
910     case GST_QUERY_ACCEPT_CAPS:{
911       GstCaps *acceptable, *caps;
912
913       acceptable = gst_pad_get_pad_template_caps (pad);
914
915       gst_query_parse_accept_caps (query, &caps);
916
917       gst_query_set_accept_caps_result (query,
918           gst_caps_is_subset (caps, acceptable));
919       gst_caps_unref (acceptable);
920       ret = TRUE;
921     }
922       break;
923     default:
924       ret = GST_VIDEO_ENCODER_CLASS (parent_class)->sink_query (enc, query);
925       break;
926   }
927
928   return ret;
929 }
930
931 static void
932 gst_x264_enc_class_init (GstX264EncClass * klass)
933 {
934   GObjectClass *gobject_class;
935   GstElementClass *element_class;
936   GstVideoEncoderClass *gstencoder_class;
937   const gchar *partitions = NULL;
938   GstPadTemplate *sink_templ;
939   GstCaps *supported_sinkcaps;
940
941   x264enc_defaults = g_string_new ("");
942
943   gobject_class = G_OBJECT_CLASS (klass);
944   element_class = GST_ELEMENT_CLASS (klass);
945   gstencoder_class = GST_VIDEO_ENCODER_CLASS (klass);
946
947   gobject_class->set_property = gst_x264_enc_set_property;
948   gobject_class->get_property = gst_x264_enc_get_property;
949   gobject_class->finalize = gst_x264_enc_finalize;
950
951   gstencoder_class->set_format = GST_DEBUG_FUNCPTR (gst_x264_enc_set_format);
952   gstencoder_class->handle_frame =
953       GST_DEBUG_FUNCPTR (gst_x264_enc_handle_frame);
954   gstencoder_class->start = GST_DEBUG_FUNCPTR (gst_x264_enc_start);
955   gstencoder_class->stop = GST_DEBUG_FUNCPTR (gst_x264_enc_stop);
956   gstencoder_class->flush = GST_DEBUG_FUNCPTR (gst_x264_enc_flush);
957   gstencoder_class->finish = GST_DEBUG_FUNCPTR (gst_x264_enc_finish);
958   gstencoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_x264_enc_sink_getcaps);
959   gstencoder_class->propose_allocation =
960       GST_DEBUG_FUNCPTR (gst_x264_enc_propose_allocation);
961   gstencoder_class->sink_query = GST_DEBUG_FUNCPTR (gst_x264_enc_sink_query);
962
963   /* options for which we don't use string equivalents */
964   g_object_class_install_property (gobject_class, ARG_PASS,
965       g_param_spec_enum ("pass", "Encoding pass/type",
966           "Encoding pass/type", GST_X264_ENC_PASS_TYPE,
967           ARG_PASS_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
968   g_object_class_install_property (gobject_class, ARG_QUANTIZER,
969       g_param_spec_uint ("quantizer", "Constant Quantizer",
970           "Constant quantizer or quality to apply",
971           0, 50, ARG_QUANTIZER_DEFAULT,
972           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
973   g_object_class_install_property (gobject_class, ARG_BITRATE,
974       g_param_spec_uint ("bitrate", "Bitrate", "Bitrate in kbit/sec", 1,
975           2000 * 1024, ARG_BITRATE_DEFAULT,
976           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
977           GST_PARAM_MUTABLE_PLAYING));
978   g_object_class_install_property (gobject_class, ARG_VBV_BUF_CAPACITY,
979       g_param_spec_uint ("vbv-buf-capacity", "VBV buffer capacity",
980           "Size of the VBV buffer in milliseconds",
981           0, 10000, ARG_VBV_BUF_CAPACITY_DEFAULT,
982           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
983           GST_PARAM_MUTABLE_PLAYING));
984   g_object_class_install_property (gobject_class, ARG_SPEED_PRESET,
985       g_param_spec_enum ("speed-preset", "Speed/quality preset",
986           "Preset name for speed/quality tradeoff options (can affect decode "
987           "compatibility - impose restrictions separately for your target decoder)",
988           GST_X264_ENC_SPEED_PRESET_TYPE, ARG_SPEED_PRESET_DEFAULT,
989           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
990   g_object_class_install_property (gobject_class, ARG_PSY_TUNE,
991       g_param_spec_enum ("psy-tune", "Psychovisual tuning preset",
992           "Preset name for psychovisual tuning options",
993           GST_X264_ENC_PSY_TUNE_TYPE, ARG_PSY_TUNE_DEFAULT,
994           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
995   g_object_class_install_property (gobject_class, ARG_TUNE,
996       g_param_spec_flags ("tune", "Content tuning preset",
997           "Preset name for non-psychovisual tuning options",
998           GST_X264_ENC_TUNE_TYPE, ARG_TUNE_DEFAULT,
999           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1000   g_object_class_install_property (gobject_class, ARG_OPTION_STRING,
1001       g_param_spec_string ("option-string", "Option string",
1002           "String of x264 options (overridden by element properties)"
1003           " in the format \"key1=value1:key2=value2\".",
1004           ARG_OPTION_STRING_DEFAULT,
1005           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1006
1007   g_object_class_install_property (gobject_class, ARG_FRAME_PACKING,
1008       g_param_spec_enum ("frame-packing", "Frame Packing",
1009           "Set frame packing mode for Stereoscopic content",
1010           GST_X264_ENC_FRAME_PACKING_TYPE, ARG_FRAME_PACKING_DEFAULT,
1011           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1012
1013   g_object_class_install_property (gobject_class, ARG_INSERT_VUI,
1014       g_param_spec_boolean ("insert-vui", "Insert VUI",
1015           "Insert VUI NAL in stream",
1016           ARG_INSERT_VUI_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1017
1018   /* options for which we _do_ use string equivalents */
1019   g_object_class_install_property (gobject_class, ARG_THREADS,
1020       g_param_spec_uint ("threads", "Threads",
1021           "Number of threads used by the codec (0 for automatic)",
1022           0, G_MAXINT, ARG_THREADS_DEFAULT,
1023           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1024   /* NOTE: this first string append doesn't require the ':' delimiter but the
1025    * rest do */
1026   g_string_append_printf (x264enc_defaults, "threads=%d", ARG_THREADS_DEFAULT);
1027   g_object_class_install_property (gobject_class, ARG_SLICED_THREADS,
1028       g_param_spec_boolean ("sliced-threads", "Sliced Threads",
1029           "Low latency but lower efficiency threading",
1030           ARG_SLICED_THREADS_DEFAULT,
1031           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1032   g_string_append_printf (x264enc_defaults, ":sliced-threads=%d",
1033       ARG_SLICED_THREADS_DEFAULT);
1034   g_object_class_install_property (gobject_class, ARG_SYNC_LOOKAHEAD,
1035       g_param_spec_int ("sync-lookahead", "Sync Lookahead",
1036           "Number of buffer frames for threaded lookahead (-1 for automatic)",
1037           -1, 250, ARG_SYNC_LOOKAHEAD_DEFAULT,
1038           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1039   g_string_append_printf (x264enc_defaults, ":sync-lookahead=%d",
1040       ARG_SYNC_LOOKAHEAD_DEFAULT);
1041   g_object_class_install_property (gobject_class, ARG_MULTIPASS_CACHE_FILE,
1042       g_param_spec_string ("multipass-cache-file", "Multipass Cache File",
1043           "Filename for multipass cache file",
1044           ARG_MULTIPASS_CACHE_FILE_DEFAULT,
1045           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1046   g_string_append_printf (x264enc_defaults, ":stats=%s",
1047       ARG_MULTIPASS_CACHE_FILE_DEFAULT);
1048   g_object_class_install_property (gobject_class, ARG_BYTE_STREAM,
1049       g_param_spec_boolean ("byte-stream", "Byte Stream",
1050           "Generate byte stream format of NALU", ARG_BYTE_STREAM_DEFAULT,
1051           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1052   g_string_append_printf (x264enc_defaults, ":annexb=%d",
1053       ARG_BYTE_STREAM_DEFAULT);
1054   g_object_class_install_property (gobject_class, ARG_INTRA_REFRESH,
1055       g_param_spec_boolean ("intra-refresh", "Intra Refresh",
1056           "Use Periodic Intra Refresh instead of IDR frames",
1057           ARG_INTRA_REFRESH_DEFAULT,
1058           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1059   g_string_append_printf (x264enc_defaults, ":intra-refresh=%d",
1060       ARG_INTRA_REFRESH_DEFAULT);
1061   g_object_class_install_property (gobject_class, ARG_ME,
1062       g_param_spec_enum ("me", "Motion Estimation",
1063           "Integer pixel motion estimation method", GST_X264_ENC_ME_TYPE,
1064           ARG_ME_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1065   g_string_append_printf (x264enc_defaults, ":me=%s",
1066       x264_motion_est_names[ARG_ME_DEFAULT]);
1067   g_object_class_install_property (gobject_class, ARG_SUBME,
1068       g_param_spec_uint ("subme", "Subpixel Motion Estimation",
1069           "Subpixel motion estimation and partition decision quality: 1=fast, 10=best",
1070           1, 10, ARG_SUBME_DEFAULT,
1071           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1072   g_string_append_printf (x264enc_defaults, ":subme=%d", ARG_SUBME_DEFAULT);
1073   g_object_class_install_property (gobject_class, ARG_ANALYSE,
1074       g_param_spec_flags ("analyse", "Analyse", "Partitions to consider",
1075           GST_X264_ENC_ANALYSE_TYPE, ARG_ANALYSE_DEFAULT,
1076           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1077   partitions = gst_x264_enc_build_partitions (ARG_ANALYSE_DEFAULT);
1078   if (partitions) {
1079     g_string_append_printf (x264enc_defaults, ":partitions=%s", partitions);
1080     g_free ((gpointer) partitions);
1081   }
1082   g_object_class_install_property (gobject_class, ARG_DCT8x8,
1083       g_param_spec_boolean ("dct8x8", "DCT8x8",
1084           "Adaptive spatial transform size", ARG_DCT8x8_DEFAULT,
1085           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1086   g_string_append_printf (x264enc_defaults, ":8x8dct=%d", ARG_DCT8x8_DEFAULT);
1087   g_object_class_install_property (gobject_class, ARG_REF,
1088       g_param_spec_uint ("ref", "Reference Frames",
1089           "Number of reference frames",
1090           1, 16, ARG_REF_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1091   g_string_append_printf (x264enc_defaults, ":ref=%d", ARG_REF_DEFAULT);
1092   g_object_class_install_property (gobject_class, ARG_BFRAMES,
1093       g_param_spec_uint ("bframes", "B-Frames",
1094           "Number of B-frames between I and P",
1095           0, 16, ARG_BFRAMES_DEFAULT,
1096           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1097   g_string_append_printf (x264enc_defaults, ":bframes=%d", ARG_BFRAMES_DEFAULT);
1098   g_object_class_install_property (gobject_class, ARG_B_ADAPT,
1099       g_param_spec_boolean ("b-adapt", "B-Adapt",
1100           "Automatically decide how many B-frames to use",
1101           ARG_B_ADAPT_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1102   g_string_append_printf (x264enc_defaults, ":b-adapt=%d", ARG_B_ADAPT_DEFAULT);
1103   g_object_class_install_property (gobject_class, ARG_B_PYRAMID,
1104       g_param_spec_boolean ("b-pyramid", "B-Pyramid",
1105           "Keep some B-frames as references", ARG_B_PYRAMID_DEFAULT,
1106           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1107   g_string_append_printf (x264enc_defaults, ":b-pyramid=%s",
1108       x264_b_pyramid_names[ARG_B_PYRAMID_DEFAULT]);
1109   g_object_class_install_property (gobject_class, ARG_WEIGHTB,
1110       g_param_spec_boolean ("weightb", "Weighted B-Frames",
1111           "Weighted prediction for B-frames", ARG_WEIGHTB_DEFAULT,
1112           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1113   g_string_append_printf (x264enc_defaults, ":weightb=%d", ARG_WEIGHTB_DEFAULT);
1114   g_object_class_install_property (gobject_class, ARG_SPS_ID,
1115       g_param_spec_uint ("sps-id", "SPS ID",
1116           "SPS and PPS ID number",
1117           0, 31, ARG_SPS_ID_DEFAULT,
1118           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1119   g_string_append_printf (x264enc_defaults, ":sps-id=%d", ARG_SPS_ID_DEFAULT);
1120   g_object_class_install_property (gobject_class, ARG_AU_NALU,
1121       g_param_spec_boolean ("aud", "AUD",
1122           "Use AU (Access Unit) delimiter", ARG_AU_NALU_DEFAULT,
1123           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1124   g_string_append_printf (x264enc_defaults, ":aud=%d", ARG_AU_NALU_DEFAULT);
1125   g_object_class_install_property (gobject_class, ARG_TRELLIS,
1126       g_param_spec_boolean ("trellis", "Trellis quantization",
1127           "Enable trellis searched quantization", ARG_TRELLIS_DEFAULT,
1128           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1129   g_string_append_printf (x264enc_defaults, ":trellis=%d", ARG_TRELLIS_DEFAULT);
1130   g_object_class_install_property (gobject_class, ARG_KEYINT_MAX,
1131       g_param_spec_uint ("key-int-max", "Key-frame maximal interval",
1132           "Maximal distance between two key-frames (0 for automatic)",
1133           0, G_MAXINT, ARG_KEYINT_MAX_DEFAULT,
1134           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1135   g_string_append_printf (x264enc_defaults, ":keyint=%d",
1136       ARG_KEYINT_MAX_DEFAULT);
1137   g_object_class_install_property (gobject_class, ARG_CABAC,
1138       g_param_spec_boolean ("cabac", "Use CABAC", "Enable CABAC entropy coding",
1139           ARG_CABAC_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1140   g_string_append_printf (x264enc_defaults, ":cabac=%d", ARG_CABAC_DEFAULT);
1141   g_object_class_install_property (gobject_class, ARG_QP_MIN,
1142       g_param_spec_uint ("qp-min", "Minimum Quantizer",
1143           "Minimum quantizer", 0, 63, ARG_QP_MIN_DEFAULT,
1144           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1145   g_string_append_printf (x264enc_defaults, ":qpmin=%d", ARG_QP_MIN_DEFAULT);
1146   g_object_class_install_property (gobject_class, ARG_QP_MAX,
1147       g_param_spec_uint ("qp-max", "Maximum Quantizer",
1148           "Maximum quantizer", 0, 63, ARG_QP_MAX_DEFAULT,
1149           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1150   g_string_append_printf (x264enc_defaults, ":qpmax=%d", ARG_QP_MAX_DEFAULT);
1151   g_object_class_install_property (gobject_class, ARG_QP_STEP,
1152       g_param_spec_uint ("qp-step", "Maximum Quantizer Difference",
1153           "Maximum quantizer difference between frames",
1154           0, 63, ARG_QP_STEP_DEFAULT,
1155           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1156   g_string_append_printf (x264enc_defaults, ":qpstep=%d", ARG_QP_STEP_DEFAULT);
1157   g_object_class_install_property (gobject_class, ARG_IP_FACTOR,
1158       g_param_spec_float ("ip-factor", "IP-Factor",
1159           "Quantizer factor between I- and P-frames",
1160           0, 2, ARG_IP_FACTOR_DEFAULT,
1161           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1162   g_string_append_printf (x264enc_defaults, ":ip-factor=%f",
1163       ARG_IP_FACTOR_DEFAULT);
1164   g_object_class_install_property (gobject_class, ARG_PB_FACTOR,
1165       g_param_spec_float ("pb-factor", "PB-Factor",
1166           "Quantizer factor between P- and B-frames", 0, 2,
1167           ARG_PB_FACTOR_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1168   g_string_append_printf (x264enc_defaults, ":pb-factor=%f",
1169       ARG_PB_FACTOR_DEFAULT);
1170   g_object_class_install_property (gobject_class, ARG_RC_MB_TREE,
1171       g_param_spec_boolean ("mb-tree", "Macroblock Tree",
1172           "Macroblock-Tree ratecontrol",
1173           ARG_RC_MB_TREE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1174   g_string_append_printf (x264enc_defaults, ":mbtree=%d",
1175       ARG_RC_MB_TREE_DEFAULT);
1176   g_object_class_install_property (gobject_class, ARG_RC_LOOKAHEAD,
1177       g_param_spec_int ("rc-lookahead", "Rate Control Lookahead",
1178           "Number of frames for frametype lookahead", 0, 250,
1179           ARG_RC_LOOKAHEAD_DEFAULT,
1180           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1181   g_string_append_printf (x264enc_defaults, ":rc-lookahead=%d",
1182       ARG_RC_LOOKAHEAD_DEFAULT);
1183   g_object_class_install_property (gobject_class, ARG_NR,
1184       g_param_spec_uint ("noise-reduction", "Noise Reduction",
1185           "Noise reduction strength",
1186           0, 100000, ARG_NR_DEFAULT,
1187           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1188   g_string_append_printf (x264enc_defaults, ":nr=%d", ARG_NR_DEFAULT);
1189   g_object_class_install_property (gobject_class, ARG_INTERLACED,
1190       g_param_spec_boolean ("interlaced", "Interlaced",
1191           "Interlaced material", ARG_INTERLACED_DEFAULT,
1192           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1193   g_string_append_printf (x264enc_defaults, ":interlaced=%d",
1194       ARG_INTERLACED_DEFAULT);
1195
1196   /* append deblock parameters */
1197   g_string_append_printf (x264enc_defaults, ":deblock=0,0");
1198   /* append weighted prediction parameter */
1199   g_string_append_printf (x264enc_defaults, ":weightp=0");
1200
1201   gst_element_class_set_static_metadata (element_class,
1202       "x264 H.264 Encoder", "Codec/Encoder/Video",
1203       "libx264-based H.264 video encoder",
1204       "Josef Zlomek <josef.zlomek@itonis.tv>, "
1205       "Mark Nauwelaerts <mnauw@users.sf.net>");
1206
1207   supported_sinkcaps = gst_caps_new_simple ("video/x-raw",
1208       "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,
1209       "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
1210       "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
1211
1212   gst_x264_enc_add_x264_chroma_format (gst_caps_get_structure
1213       (supported_sinkcaps, 0), TRUE, TRUE, TRUE, TRUE);
1214
1215   sink_templ = gst_pad_template_new ("sink",
1216       GST_PAD_SINK, GST_PAD_ALWAYS, supported_sinkcaps);
1217
1218   gst_caps_unref (supported_sinkcaps);
1219
1220   gst_element_class_add_pad_template (element_class, sink_templ);
1221   gst_element_class_add_static_pad_template (element_class, &src_factory);
1222
1223   gst_type_mark_as_plugin_api (GST_X264_ENC_ANALYSE_TYPE, 0);
1224   gst_type_mark_as_plugin_api (GST_X264_ENC_FRAME_PACKING_TYPE, 0);
1225   gst_type_mark_as_plugin_api (GST_X264_ENC_ME_TYPE, 0);
1226   gst_type_mark_as_plugin_api (GST_X264_ENC_PASS_TYPE, 0);
1227   gst_type_mark_as_plugin_api (GST_X264_ENC_PSY_TUNE_TYPE, 0);
1228   gst_type_mark_as_plugin_api (GST_X264_ENC_SPEED_PRESET_TYPE, 0);
1229   gst_type_mark_as_plugin_api (GST_X264_ENC_TUNE_TYPE, 0);
1230 }
1231
1232 /* *INDENT-OFF* */
1233 G_GNUC_PRINTF (3, 0)
1234 /* *INDENT-ON* */
1235
1236 static void
1237 gst_x264_enc_log_callback (gpointer private, gint level, const char *format,
1238     va_list args)
1239 {
1240 #ifndef GST_DISABLE_GST_DEBUG
1241   GstDebugLevel gst_level;
1242   GObject *object = (GObject *) private;
1243   gchar *formatted;
1244
1245   switch (level) {
1246     case X264_LOG_NONE:
1247       gst_level = GST_LEVEL_NONE;
1248       break;
1249     case X264_LOG_ERROR:
1250       gst_level = GST_LEVEL_ERROR;
1251       break;
1252     case X264_LOG_WARNING:
1253       gst_level = GST_LEVEL_WARNING;
1254       break;
1255     case X264_LOG_INFO:
1256       gst_level = GST_LEVEL_INFO;
1257       break;
1258     default:
1259       /* push x264enc debug down to our lower levels to avoid some clutter */
1260       gst_level = GST_LEVEL_LOG;
1261       break;
1262   }
1263
1264   if (G_LIKELY (gst_level > _gst_debug_min))
1265     return;
1266
1267   if (G_LIKELY (gst_level > gst_debug_category_get_threshold (GST_CAT_DEFAULT)))
1268     return;
1269
1270   formatted = g_strdup_vprintf (format, args);
1271   g_strchomp (formatted);
1272
1273   GST_CAT_LEVEL_LOG (GST_CAT_DEFAULT, gst_level, object, "%s", formatted);
1274
1275   g_free (formatted);
1276 #endif /* GST_DISABLE_GST_DEBUG */
1277 }
1278
1279 /* initialize the new element
1280  * instantiate pads and add them to element
1281  * set functions
1282  * initialize structure
1283  */
1284 static void
1285 gst_x264_enc_init (GstX264Enc * encoder)
1286 {
1287   /* properties */
1288   encoder->threads = ARG_THREADS_DEFAULT;
1289   encoder->sliced_threads = ARG_SLICED_THREADS_DEFAULT;
1290   encoder->sync_lookahead = ARG_SYNC_LOOKAHEAD_DEFAULT;
1291   encoder->pass = ARG_PASS_DEFAULT;
1292   encoder->quantizer = ARG_QUANTIZER_DEFAULT;
1293   encoder->mp_cache_file = g_strdup (ARG_MULTIPASS_CACHE_FILE_DEFAULT);
1294   encoder->byte_stream = ARG_BYTE_STREAM_DEFAULT;
1295   encoder->intra_refresh = ARG_INTRA_REFRESH_DEFAULT;
1296   encoder->vbv_buf_capacity = ARG_VBV_BUF_CAPACITY_DEFAULT;
1297   encoder->me = ARG_ME_DEFAULT;
1298   encoder->subme = ARG_SUBME_DEFAULT;
1299   encoder->analyse = ARG_ANALYSE_DEFAULT;
1300   encoder->dct8x8 = ARG_DCT8x8_DEFAULT;
1301   encoder->ref = ARG_REF_DEFAULT;
1302   encoder->bframes = ARG_BFRAMES_DEFAULT;
1303   encoder->b_adapt = ARG_B_ADAPT_DEFAULT;
1304   encoder->b_pyramid = ARG_B_PYRAMID_DEFAULT;
1305   encoder->weightb = ARG_WEIGHTB_DEFAULT;
1306   encoder->sps_id = ARG_SPS_ID_DEFAULT;
1307   encoder->au_nalu = ARG_AU_NALU_DEFAULT;
1308   encoder->trellis = ARG_TRELLIS_DEFAULT;
1309   encoder->keyint_max = ARG_KEYINT_MAX_DEFAULT;
1310   encoder->cabac = ARG_CABAC_DEFAULT;
1311   encoder->qp_min = ARG_QP_MIN_DEFAULT;
1312   encoder->qp_max = ARG_QP_MAX_DEFAULT;
1313   encoder->qp_step = ARG_QP_STEP_DEFAULT;
1314   encoder->ip_factor = ARG_IP_FACTOR_DEFAULT;
1315   encoder->pb_factor = ARG_PB_FACTOR_DEFAULT;
1316   encoder->mb_tree = ARG_RC_MB_TREE_DEFAULT;
1317   encoder->rc_lookahead = ARG_RC_LOOKAHEAD_DEFAULT;
1318   encoder->noise_reduction = ARG_NR_DEFAULT;
1319   encoder->interlaced = ARG_INTERLACED_DEFAULT;
1320   encoder->option_string = g_string_new (NULL);
1321   encoder->option_string_prop = g_string_new (ARG_OPTION_STRING_DEFAULT);
1322   encoder->speed_preset = ARG_SPEED_PRESET_DEFAULT;
1323   encoder->psy_tune = ARG_PSY_TUNE_DEFAULT;
1324   encoder->tune = ARG_TUNE_DEFAULT;
1325   encoder->frame_packing = ARG_FRAME_PACKING_DEFAULT;
1326   encoder->insert_vui = ARG_INSERT_VUI_DEFAULT;
1327
1328   encoder->bitrate_manager =
1329       gst_encoder_bitrate_profile_manager_new (ARG_BITRATE_DEFAULT);
1330 }
1331
1332 typedef struct
1333 {
1334   GstVideoCodecFrame *frame;
1335   GstVideoFrame vframe;
1336 } FrameData;
1337
1338 static FrameData *
1339 gst_x264_enc_queue_frame (GstX264Enc * enc, GstVideoCodecFrame * frame,
1340     GstVideoInfo * info)
1341 {
1342   GstVideoFrame vframe;
1343   FrameData *fdata;
1344
1345   if (!gst_video_frame_map (&vframe, info, frame->input_buffer, GST_MAP_READ))
1346     return NULL;
1347
1348   fdata = g_slice_new (FrameData);
1349   fdata->frame = gst_video_codec_frame_ref (frame);
1350   fdata->vframe = vframe;
1351
1352   enc->pending_frames = g_list_prepend (enc->pending_frames, fdata);
1353
1354   return fdata;
1355 }
1356
1357 static void
1358 gst_x264_enc_dequeue_frame (GstX264Enc * enc, GstVideoCodecFrame * frame)
1359 {
1360   GList *l;
1361
1362   for (l = enc->pending_frames; l; l = l->next) {
1363     FrameData *fdata = l->data;
1364
1365     if (fdata->frame != frame)
1366       continue;
1367
1368     gst_video_frame_unmap (&fdata->vframe);
1369     gst_video_codec_frame_unref (fdata->frame);
1370     g_slice_free (FrameData, fdata);
1371
1372     enc->pending_frames = g_list_delete_link (enc->pending_frames, l);
1373     return;
1374   }
1375 }
1376
1377 static void
1378 gst_x264_enc_dequeue_all_frames (GstX264Enc * enc)
1379 {
1380   GList *l;
1381
1382   for (l = enc->pending_frames; l; l = l->next) {
1383     FrameData *fdata = l->data;
1384
1385     gst_video_frame_unmap (&fdata->vframe);
1386     gst_video_codec_frame_unref (fdata->frame);
1387     g_slice_free (FrameData, fdata);
1388   }
1389   g_list_free (enc->pending_frames);
1390   enc->pending_frames = NULL;
1391 }
1392
1393 static gboolean
1394 gst_x264_enc_start (GstVideoEncoder * encoder)
1395 {
1396   GstX264Enc *x264enc = GST_X264_ENC (encoder);
1397
1398   x264enc->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_FROM_PROPERTY;
1399
1400   /* make sure that we have enough time for first DTS,
1401      this is probably overkill for most streams */
1402   gst_video_encoder_set_min_pts (encoder, GST_SECOND * 60 * 60 * 1000);
1403
1404   return TRUE;
1405 }
1406
1407 static gboolean
1408 gst_x264_enc_stop (GstVideoEncoder * encoder)
1409 {
1410   GstX264Enc *x264enc = GST_X264_ENC (encoder);
1411
1412   gst_x264_enc_flush_frames (x264enc, FALSE);
1413   gst_x264_enc_close_encoder (x264enc);
1414   gst_x264_enc_dequeue_all_frames (x264enc);
1415
1416   if (x264enc->input_state)
1417     gst_video_codec_state_unref (x264enc->input_state);
1418   x264enc->input_state = NULL;
1419
1420   return TRUE;
1421 }
1422
1423
1424 static gboolean
1425 gst_x264_enc_flush (GstVideoEncoder * encoder)
1426 {
1427   GstX264Enc *x264enc = GST_X264_ENC (encoder);
1428
1429   gst_x264_enc_flush_frames (x264enc, FALSE);
1430   gst_x264_enc_close_encoder (x264enc);
1431   gst_x264_enc_dequeue_all_frames (x264enc);
1432
1433   gst_x264_enc_init_encoder (x264enc);
1434
1435   return TRUE;
1436 }
1437
1438 static void
1439 gst_x264_enc_finalize (GObject * object)
1440 {
1441   GstX264Enc *encoder = GST_X264_ENC (object);
1442
1443   if (encoder->input_state)
1444     gst_video_codec_state_unref (encoder->input_state);
1445   encoder->input_state = NULL;
1446
1447 #define FREE_STRING(ptr) \
1448   if (ptr) \
1449     g_string_free (ptr, TRUE);
1450
1451   FREE_STRING (encoder->tunings);
1452   FREE_STRING (encoder->option_string);
1453   FREE_STRING (encoder->option_string_prop);
1454   gst_encoder_bitrate_profile_manager_free (encoder->bitrate_manager);
1455
1456 #undef FREE_STRING
1457
1458   g_free (encoder->mp_cache_file);
1459   encoder->mp_cache_file = NULL;
1460
1461   gst_x264_enc_close_encoder (encoder);
1462
1463   G_OBJECT_CLASS (parent_class)->finalize (object);
1464 }
1465
1466 /*
1467  * gst_x264_enc_parse_options
1468  * @encoder: Encoder to which options are assigned
1469  * @str: Option string
1470  *
1471  * Parse option string and assign to x264 parameters
1472  *
1473  */
1474 static gboolean
1475 gst_x264_enc_parse_options (GstX264Enc * encoder, const gchar * str)
1476 {
1477   GStrv kvpairs;
1478   guint npairs, i;
1479   gint parse_result = 0, ret = 0;
1480   gchar *options = (gchar *) str;
1481
1482   while (*options == ':')
1483     options++;
1484
1485   kvpairs = g_strsplit (options, ":", 0);
1486   npairs = g_strv_length (kvpairs);
1487
1488   for (i = 0; i < npairs; i++) {
1489     GStrv key_val = g_strsplit (kvpairs[i], "=", 2);
1490
1491     parse_result =
1492         encoder->vtable->x264_param_parse (&encoder->x264param, key_val[0],
1493         key_val[1]);
1494
1495     if (parse_result == X264_PARAM_BAD_NAME) {
1496       GST_ERROR_OBJECT (encoder, "Bad name for option %s=%s",
1497           key_val[0] ? key_val[0] : "", key_val[1] ? key_val[1] : "");
1498     }
1499     if (parse_result == X264_PARAM_BAD_VALUE) {
1500       GST_ERROR_OBJECT (encoder,
1501           "Bad value for option %s=%s (Note: a NULL value for a non-boolean triggers this)",
1502           key_val[0] ? key_val[0] : "", key_val[1] ? key_val[1] : "");
1503     }
1504
1505     g_strfreev (key_val);
1506
1507     if (parse_result)
1508       ret++;
1509   }
1510
1511   g_strfreev (kvpairs);
1512   return !ret;
1513 }
1514
1515 static gint
1516 gst_x264_enc_gst_to_x264_video_format (GstVideoFormat format, gint * nplanes)
1517 {
1518   switch (format) {
1519     case GST_VIDEO_FORMAT_I420:
1520     case GST_VIDEO_FORMAT_YV12:
1521       if (nplanes)
1522         *nplanes = 3;
1523       return X264_CSP_I420;
1524     case GST_VIDEO_FORMAT_I420_10BE:
1525     case GST_VIDEO_FORMAT_I420_10LE:
1526       if (nplanes)
1527         *nplanes = 3;
1528       return X264_CSP_I420 | X264_CSP_HIGH_DEPTH;
1529     case GST_VIDEO_FORMAT_Y42B:
1530       if (nplanes)
1531         *nplanes = 3;
1532       return X264_CSP_I422;
1533     case GST_VIDEO_FORMAT_I422_10BE:
1534     case GST_VIDEO_FORMAT_I422_10LE:
1535       if (nplanes)
1536         *nplanes = 3;
1537       return X264_CSP_I422 | X264_CSP_HIGH_DEPTH;
1538     case GST_VIDEO_FORMAT_Y444:
1539       if (nplanes)
1540         *nplanes = 3;
1541       return X264_CSP_I444;
1542     case GST_VIDEO_FORMAT_Y444_10BE:
1543     case GST_VIDEO_FORMAT_Y444_10LE:
1544       if (nplanes)
1545         *nplanes = 3;
1546       return X264_CSP_I444 | X264_CSP_HIGH_DEPTH;
1547     case GST_VIDEO_FORMAT_NV12:
1548       if (nplanes)
1549         *nplanes = 2;
1550       return X264_CSP_NV12;
1551     default:
1552       g_return_val_if_reached (GST_VIDEO_FORMAT_UNKNOWN);
1553   }
1554 }
1555
1556 /*
1557  * gst_x264_enc_init_encoder
1558  * @encoder:  Encoder which should be initialized.
1559  *
1560  * Initialize x264 encoder.
1561  *
1562  */
1563 static gboolean
1564 gst_x264_enc_init_encoder (GstX264Enc * encoder)
1565 {
1566   guint pass = 0;
1567   GstVideoInfo *info;
1568   guint bitrate;
1569
1570   if (!encoder->input_state) {
1571     GST_DEBUG_OBJECT (encoder, "Have no input state yet");
1572     return FALSE;
1573   }
1574
1575   info = &encoder->input_state->info;
1576
1577   /* make sure that the encoder is closed */
1578   gst_x264_enc_close_encoder (encoder);
1579
1580   GST_OBJECT_LOCK (encoder);
1581
1582   if (GST_VIDEO_INFO_COMP_DEPTH (info, 0) == 8)
1583     encoder->vtable = vtable_8bit;
1584   else if (GST_VIDEO_INFO_COMP_DEPTH (info, 0) == 10)
1585     encoder->vtable = vtable_10bit;
1586
1587   g_assert (encoder->vtable != NULL);
1588
1589   gst_x264_enc_build_tunings_string (encoder);
1590
1591   /* set x264 parameters and use preset/tuning if present */
1592   GST_DEBUG_OBJECT (encoder, "Applying defaults with preset %s, tunings %s",
1593       encoder->speed_preset ? x264_preset_names[encoder->speed_preset - 1] : "",
1594       encoder->tunings && encoder->tunings->len ? encoder->tunings->str : "");
1595   encoder->vtable->x264_param_default_preset (&encoder->x264param,
1596       encoder->speed_preset ? x264_preset_names[encoder->speed_preset -
1597           1] : NULL, encoder->tunings
1598       && encoder->tunings->len ? encoder->tunings->str : NULL);
1599
1600   /* log callback setup; part of parameters
1601    * this needs to be done again after every *param_default* () call */
1602   encoder->x264param.pf_log = gst_x264_enc_log_callback;
1603   encoder->x264param.p_log_private = encoder;
1604   encoder->x264param.i_log_level = X264_LOG_DEBUG;
1605
1606   /* if no preset nor tuning, use property defaults */
1607   if (!encoder->speed_preset && !encoder->tunings->len) {
1608     GST_DEBUG_OBJECT (encoder, "Applying x264enc_defaults");
1609     if (x264enc_defaults->len
1610         && gst_x264_enc_parse_options (encoder,
1611             x264enc_defaults->str) == FALSE) {
1612       GST_DEBUG_OBJECT (encoder,
1613           "x264enc_defaults string contains errors. This is a bug.");
1614       goto unlock_and_return;
1615     }
1616   } else {
1617     /* When using presets we need to respect the default output format */
1618     encoder->x264param.b_aud = encoder->au_nalu;
1619     encoder->x264param.b_annexb = encoder->byte_stream;
1620   }
1621
1622   /* setup appropriate timebase for gstreamer */
1623   encoder->x264param.i_timebase_num = 1;
1624   encoder->x264param.i_timebase_den = 1000000000;
1625
1626   /* apply option-string property */
1627   if (encoder->option_string_prop && encoder->option_string_prop->len) {
1628     GST_DEBUG_OBJECT (encoder, "Applying option-string: %s",
1629         encoder->option_string_prop->str);
1630     if (gst_x264_enc_parse_options (encoder,
1631             encoder->option_string_prop->str) == FALSE) {
1632       GST_DEBUG_OBJECT (encoder, "Your option-string contains errors.");
1633       goto unlock_and_return;
1634     }
1635   }
1636   /* apply user-set options */
1637   if (encoder->option_string && encoder->option_string->len) {
1638     GST_DEBUG_OBJECT (encoder, "Applying user-set options: %s",
1639         encoder->option_string->str);
1640     if (gst_x264_enc_parse_options (encoder,
1641             encoder->option_string->str) == FALSE) {
1642       GST_DEBUG_OBJECT (encoder, "Failed to parse internal option string. "
1643           "This could be due to use of an old libx264 version. Option string "
1644           "was: %s", encoder->option_string->str);
1645     }
1646   }
1647
1648   /* set up encoder parameters */
1649 #if X264_BUILD >= 153
1650   encoder->x264param.i_bitdepth = GST_VIDEO_INFO_COMP_DEPTH (info, 0);
1651 #endif
1652   encoder->x264param.i_csp =
1653       gst_x264_enc_gst_to_x264_video_format (info->finfo->format,
1654       &encoder->x264_nplanes);
1655   if (info->fps_d == 0 || info->fps_n == 0) {
1656     /* No FPS so must use VFR
1657      * This raises latency apparently see http://mewiki.project357.com/wiki/X264_Encoding_Suggestions */
1658     encoder->x264param.b_vfr_input = TRUE;
1659     if (encoder->keyint_max) {  /* NB the default is 250 setup by x264 itself */
1660       encoder->x264param.i_keyint_max = encoder->keyint_max;
1661     }
1662   } else {
1663     /* FPS available so set it up */
1664     encoder->x264param.b_vfr_input = FALSE;
1665     encoder->x264param.i_fps_num = info->fps_n;
1666     encoder->x264param.i_fps_den = info->fps_d;
1667     encoder->x264param.i_keyint_max =
1668         encoder->keyint_max ? encoder->keyint_max : (10 * info->fps_n /
1669         info->fps_d);
1670   }
1671   encoder->x264param.i_width = info->width;
1672   encoder->x264param.i_height = info->height;
1673   if (info->par_d > 0) {
1674     encoder->x264param.vui.i_sar_width = info->par_n;
1675     encoder->x264param.vui.i_sar_height = info->par_d;
1676   }
1677
1678   if ((((info->height == 576) && ((info->width == 720)
1679                   || (info->width == 704) || (info->width == 352)))
1680           || ((info->height == 288) && (info->width == 352)))
1681       && (info->fps_d == 1) && (info->fps_n == 25)) {
1682     encoder->x264param.vui.i_vidformat = 1;     /* PAL */
1683   } else if ((((info->height == 480) && ((info->width == 720)
1684                   || (info->width == 704) || (info->width == 352)))
1685           || ((info->height == 240) && (info->width == 352)))
1686       && (info->fps_d == 1001) && ((info->fps_n == 30000)
1687           || (info->fps_n == 24000))) {
1688     encoder->x264param.vui.i_vidformat = 2;     /* NTSC */
1689   } else {
1690     encoder->x264param.vui.i_vidformat = 5;     /* unspecified */
1691   }
1692
1693   if (!encoder->insert_vui)
1694     goto skip_vui_parameters;
1695
1696   encoder->x264param.vui.i_colorprim =
1697       gst_video_color_primaries_to_iso (info->colorimetry.primaries);
1698
1699   encoder->x264param.vui.i_transfer =
1700       gst_video_transfer_function_to_iso (info->colorimetry.transfer);
1701
1702   encoder->x264param.vui.i_colmatrix =
1703       gst_video_color_matrix_to_iso (info->colorimetry.matrix);
1704
1705   if (info->colorimetry.range == GST_VIDEO_COLOR_RANGE_0_255) {
1706     encoder->x264param.vui.b_fullrange = 1;
1707   } else {
1708     encoder->x264param.vui.b_fullrange = 0;
1709   }
1710
1711   switch (info->chroma_site) {
1712     case GST_VIDEO_CHROMA_SITE_MPEG2:
1713       encoder->x264param.vui.i_chroma_loc = 0;
1714       break;
1715     case GST_VIDEO_CHROMA_SITE_JPEG:
1716       encoder->x264param.vui.i_chroma_loc = 1;
1717       break;
1718     case GST_VIDEO_CHROMA_SITE_V_COSITED:
1719       encoder->x264param.vui.i_chroma_loc = 3;
1720       break;
1721     case GST_VIDEO_CHROMA_SITE_DV:
1722       encoder->x264param.vui.i_chroma_loc = 2;
1723       break;
1724     default:
1725       encoder->x264param.vui.i_chroma_loc = 0;
1726       break;
1727   }
1728
1729 skip_vui_parameters:
1730
1731   encoder->x264param.analyse.b_psnr = 0;
1732
1733   bitrate =
1734       gst_encoder_bitrate_profile_manager_get_bitrate (encoder->bitrate_manager,
1735       encoder->input_state ? &encoder->input_state->info : NULL);
1736
1737   /* FIXME 2.0 make configuration more sane and consistent with x264 cmdline:
1738    * + split pass property into a pass property (pass1/2/3 enum) and rc-method
1739    * + bitrate property should only be used in case of CBR method
1740    * + vbv bitrate/buffer should have separate configuration that is then
1741    *   applied independently of the mode:
1742    *    + either using properties (new) vbv-maxrate and (renamed) vbv-bufsize
1743    *    + or dropping vbv-buf-capacity altogether and simply using option-string
1744    */
1745   switch (encoder->pass) {
1746     case GST_X264_ENC_PASS_QUANT:
1747       encoder->x264param.rc.i_rc_method = X264_RC_CQP;
1748       encoder->x264param.rc.i_qp_constant = encoder->quantizer;
1749       break;
1750     case GST_X264_ENC_PASS_QUAL:
1751       encoder->x264param.rc.i_rc_method = X264_RC_CRF;
1752       encoder->x264param.rc.f_rf_constant = encoder->quantizer;
1753       encoder->x264param.rc.i_vbv_max_bitrate = bitrate;
1754       encoder->x264param.rc.i_vbv_buffer_size
1755           = encoder->x264param.rc.i_vbv_max_bitrate
1756           * encoder->vbv_buf_capacity / 1000;
1757       break;
1758     case GST_X264_ENC_PASS_CBR:
1759     case GST_X264_ENC_PASS_PASS1:
1760     case GST_X264_ENC_PASS_PASS2:
1761     case GST_X264_ENC_PASS_PASS3:
1762     default:
1763       encoder->x264param.rc.i_rc_method = X264_RC_ABR;
1764       encoder->x264param.rc.i_bitrate = bitrate;
1765       encoder->x264param.rc.i_vbv_max_bitrate = bitrate;
1766       encoder->x264param.rc.i_vbv_buffer_size =
1767           encoder->x264param.rc.i_vbv_max_bitrate
1768           * encoder->vbv_buf_capacity / 1000;
1769       pass = encoder->pass & 0xF;
1770       break;
1771   }
1772
1773   switch (pass) {
1774     case 0:
1775       encoder->x264param.rc.b_stat_read = 0;
1776       encoder->x264param.rc.b_stat_write = 0;
1777       break;
1778     case 1:
1779       encoder->x264param.rc.b_stat_read = 0;
1780       encoder->x264param.rc.b_stat_write = 1;
1781       encoder->vtable->x264_param_apply_fastfirstpass (&encoder->x264param);
1782       encoder->x264param.i_frame_reference = 1;
1783       encoder->x264param.analyse.b_transform_8x8 = 0;
1784       encoder->x264param.analyse.inter = 0;
1785       encoder->x264param.analyse.i_me_method = X264_ME_DIA;
1786       encoder->x264param.analyse.i_subpel_refine =
1787           MIN (2, encoder->x264param.analyse.i_subpel_refine);
1788       encoder->x264param.analyse.i_trellis = 0;
1789       encoder->x264param.analyse.b_fast_pskip = 1;
1790       break;
1791     case 2:
1792       encoder->x264param.rc.b_stat_read = 1;
1793       encoder->x264param.rc.b_stat_write = 0;
1794       break;
1795     case 3:
1796       encoder->x264param.rc.b_stat_read = 1;
1797       encoder->x264param.rc.b_stat_write = 1;
1798       break;
1799   }
1800
1801   if (encoder->peer_profile) {
1802     if (encoder->vtable->x264_param_apply_profile (&encoder->x264param,
1803             encoder->peer_profile))
1804       GST_WARNING_OBJECT (encoder, "Bad downstream profile name: %s",
1805           encoder->peer_profile);
1806   }
1807
1808   /* If using an intra profile, all frames are intra frames */
1809   if (encoder->peer_intra_profile)
1810     encoder->x264param.i_keyint_max = encoder->x264param.i_keyint_min = 1;
1811
1812   /* Enforce level limits if they were in the caps */
1813   if (encoder->peer_level_idc != -1) {
1814     gint i;
1815     const x264_level_t *peer_level = NULL;
1816
1817     for (i = 0; (*encoder->vtable->x264_levels)[i].level_idc; i++) {
1818       if (encoder->peer_level_idc ==
1819           (*encoder->vtable->x264_levels)[i].level_idc) {
1820         int mb_width = (info->width + 15) / 16;
1821         int mb_height = (info->height + 15) / 16;
1822         int mbs = mb_width * mb_height;
1823
1824         if ((*encoder->vtable->x264_levels)[i].frame_size < mbs ||
1825             (*encoder->vtable->x264_levels)[i].frame_size * 8 <
1826             mb_width * mb_width
1827             || (*encoder->vtable->x264_levels)[i].frame_size * 8 <
1828             mb_height * mb_height) {
1829           GST_WARNING_OBJECT (encoder,
1830               "Frame size larger than level %d allows",
1831               encoder->peer_level_idc);
1832           break;
1833         }
1834
1835         if (info->fps_d && (*encoder->vtable->x264_levels)[i].mbps
1836             < (gint64) mbs * info->fps_n / info->fps_d) {
1837           GST_WARNING_OBJECT (encoder,
1838               "Macroblock rate higher than level %d allows",
1839               encoder->peer_level_idc);
1840           break;
1841         }
1842
1843         peer_level = &(*encoder->vtable->x264_levels)[i];
1844         break;
1845       }
1846     }
1847
1848     if (!peer_level)
1849       goto unlock_and_return;
1850
1851     encoder->x264param.i_level_idc = peer_level->level_idc;
1852
1853     encoder->x264param.rc.i_bitrate = MIN (encoder->x264param.rc.i_bitrate,
1854         peer_level->bitrate);
1855     encoder->x264param.rc.i_vbv_max_bitrate =
1856         MIN (encoder->x264param.rc.i_vbv_max_bitrate, peer_level->bitrate);
1857     encoder->x264param.rc.i_vbv_buffer_size =
1858         MIN (encoder->x264param.rc.i_vbv_buffer_size, peer_level->cpb);
1859     encoder->x264param.analyse.i_mv_range =
1860         MIN (encoder->x264param.analyse.i_mv_range, peer_level->mv_range);
1861
1862     if (peer_level->frame_only) {
1863       encoder->x264param.b_interlaced = FALSE;
1864       encoder->x264param.b_fake_interlaced = FALSE;
1865     }
1866   }
1867
1868   if (GST_VIDEO_INFO_IS_INTERLACED (info)) {
1869     encoder->x264param.b_interlaced = TRUE;
1870     if (GST_VIDEO_INFO_INTERLACE_MODE (info) == GST_VIDEO_INTERLACE_MODE_MIXED) {
1871       encoder->x264param.b_pic_struct = TRUE;
1872     }
1873     if (GST_VIDEO_INFO_FIELD_ORDER (info) ==
1874         GST_VIDEO_FIELD_ORDER_TOP_FIELD_FIRST) {
1875       encoder->x264param.b_tff = TRUE;
1876     } else {
1877       encoder->x264param.b_tff = FALSE;
1878     }
1879   } else {
1880     encoder->x264param.b_interlaced = FALSE;
1881   }
1882
1883   /* Set 3D frame packing */
1884   if (encoder->frame_packing != GST_VIDEO_MULTIVIEW_MODE_NONE)
1885     encoder->x264param.i_frame_packing = encoder->frame_packing;
1886   else
1887     encoder->x264param.i_frame_packing =
1888         gst_x264_enc_mview_mode_to_frame_packing (GST_VIDEO_INFO_MULTIVIEW_MODE
1889         (info));
1890
1891   GST_DEBUG_OBJECT (encoder, "Stereo frame packing = %d",
1892       encoder->x264param.i_frame_packing);
1893
1894   encoder->reconfig = FALSE;
1895
1896   GST_OBJECT_UNLOCK (encoder);
1897
1898   encoder->x264enc = encoder->vtable->x264_encoder_open (&encoder->x264param);
1899   if (!encoder->x264enc) {
1900     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE,
1901         ("Can not initialize x264 encoder."), (NULL));
1902     return FALSE;
1903   }
1904
1905   return TRUE;
1906
1907 unlock_and_return:
1908   GST_OBJECT_UNLOCK (encoder);
1909   return FALSE;
1910 }
1911
1912 /* gst_x264_enc_close_encoder
1913  * @encoder:  Encoder which should close.
1914  *
1915  * Close x264 encoder.
1916  */
1917 static void
1918 gst_x264_enc_close_encoder (GstX264Enc * encoder)
1919 {
1920   if (encoder->x264enc != NULL) {
1921     encoder->vtable->x264_encoder_close (encoder->x264enc);
1922     encoder->x264enc = NULL;
1923   }
1924   encoder->vtable = NULL;
1925 }
1926
1927 static gboolean
1928 gst_x264_enc_set_profile_and_level (GstX264Enc * encoder, GstCaps * caps)
1929 {
1930   x264_nal_t *nal;
1931   int i_nal;
1932   int header_return;
1933   gint i;
1934   guint8 *sps;
1935   GstStructure *s;
1936   const gchar *profile;
1937   GstCaps *allowed_caps;
1938   GstStructure *s2;
1939   const gchar *allowed_profile;
1940
1941   header_return =
1942       encoder->vtable->x264_encoder_headers (encoder->x264enc, &nal, &i_nal);
1943   if (header_return < 0) {
1944     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x264 header failed."),
1945         ("x264_encoder_headers return code=%d", header_return));
1946     return FALSE;
1947   }
1948
1949   sps = NULL;
1950   for (i = 0; i < i_nal; i++) {
1951     if (nal[i].i_type == NAL_SPS) {
1952       sps = nal[i].p_payload + 4;
1953       /* skip NAL unit type */
1954       sps++;
1955     }
1956   }
1957
1958   if (!sps) {
1959     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x264 header failed."),
1960         ("x264_encoder_headers did not return SPS"));
1961     return FALSE;
1962   }
1963
1964   gst_codec_utils_h264_caps_set_level_and_profile (caps, sps, 3);
1965
1966   /* Constrained baseline is a strict subset of baseline. If downstream
1967    * wanted baseline and we produced constrained baseline, we can just
1968    * set the profile to baseline in the caps to make negotiation happy.
1969    * Same goes for baseline as subset of main profile and main as a subset
1970    * of high profile.
1971    */
1972   s = gst_caps_get_structure (caps, 0);
1973   profile = gst_structure_get_string (s, "profile");
1974
1975   allowed_caps = gst_pad_get_allowed_caps (GST_VIDEO_ENCODER_SRC_PAD (encoder));
1976
1977   if (allowed_caps == NULL)
1978     goto no_peer;
1979
1980   if (!gst_caps_can_intersect (allowed_caps, caps)) {
1981     allowed_caps = gst_caps_make_writable (allowed_caps);
1982     allowed_caps = gst_caps_truncate (allowed_caps);
1983     s2 = gst_caps_get_structure (allowed_caps, 0);
1984     gst_structure_fixate_field_string (s2, "profile", profile);
1985     allowed_profile = gst_structure_get_string (s2, "profile");
1986     if (!strcmp (allowed_profile, "high")) {
1987       if (!strcmp (profile, "constrained-baseline")
1988           || !strcmp (profile, "baseline") || !strcmp (profile, "main")) {
1989         gst_structure_set (s, "profile", G_TYPE_STRING, "high", NULL);
1990         GST_INFO_OBJECT (encoder, "downstream requested high profile, but "
1991             "encoder will now output %s profile (which is a subset), due "
1992             "to how it's been configured", profile);
1993       }
1994     } else if (!strcmp (allowed_profile, "main")) {
1995       if (!strcmp (profile, "constrained-baseline")
1996           || !strcmp (profile, "baseline")) {
1997         gst_structure_set (s, "profile", G_TYPE_STRING, "main", NULL);
1998         GST_INFO_OBJECT (encoder, "downstream requested main profile, but "
1999             "encoder will now output %s profile (which is a subset), due "
2000             "to how it's been configured", profile);
2001       }
2002     } else if (!strcmp (allowed_profile, "baseline")) {
2003       if (!strcmp (profile, "constrained-baseline"))
2004         gst_structure_set (s, "profile", G_TYPE_STRING, "baseline", NULL);
2005     }
2006   }
2007   gst_caps_unref (allowed_caps);
2008
2009 no_peer:
2010
2011   return TRUE;
2012 }
2013
2014 /*
2015  * Returns: Buffer with the stream headers.
2016  */
2017 static GstBuffer *
2018 gst_x264_enc_header_buf (GstX264Enc * encoder)
2019 {
2020   GstBuffer *buf;
2021   x264_nal_t *nal;
2022   int i_nal;
2023   int header_return;
2024   int i_size;
2025   int nal_size;
2026   gint i;
2027   guint8 *buffer, *sps;
2028   gulong buffer_size;
2029   gint sei_ni, sps_ni, pps_ni;
2030
2031   if (G_UNLIKELY (encoder->x264enc == NULL))
2032     return NULL;
2033
2034   /* Create avcC header. */
2035
2036   header_return =
2037       encoder->vtable->x264_encoder_headers (encoder->x264enc, &nal, &i_nal);
2038   if (header_return < 0) {
2039     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x264 header failed."),
2040         ("x264_encoder_headers return code=%d", header_return));
2041     return NULL;
2042   }
2043
2044   sei_ni = sps_ni = pps_ni = -1;
2045   for (i = 0; i < i_nal; i++) {
2046     if (nal[i].i_type == NAL_SEI) {
2047       sei_ni = i;
2048     } else if (nal[i].i_type == NAL_SPS) {
2049       sps_ni = i;
2050     } else if (nal[i].i_type == NAL_PPS) {
2051       pps_ni = i;
2052     }
2053   }
2054
2055   /* x264 is expected to return an SEI (some identification info),
2056    * and SPS and PPS */
2057   if (sps_ni == -1 || pps_ni == -1 ||
2058       nal[sps_ni].i_payload < 4 || nal[pps_ni].i_payload < 1) {
2059     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, (NULL),
2060         ("Unexpected x264 header."));
2061     return NULL;
2062   }
2063
2064   GST_MEMDUMP ("SPS", nal[sps_ni].p_payload, nal[sps_ni].i_payload);
2065   GST_MEMDUMP ("PPS", nal[pps_ni].p_payload, nal[pps_ni].i_payload);
2066   if (sei_ni != -1) {
2067     GST_MEMDUMP ("SEI", nal[sei_ni].p_payload, nal[sei_ni].i_payload);
2068   }
2069
2070   /* nal payloads with emulation_prevention_three_byte, and some header data */
2071   buffer_size = (nal[sps_ni].i_payload + nal[pps_ni].i_payload) * 4 + 100;
2072   buffer = g_malloc (buffer_size);
2073
2074   sps = nal[sps_ni].p_payload + 4;
2075   /* skip NAL unit type */
2076   sps++;
2077
2078   buffer[0] = 1;                /* AVC Decoder Configuration Record ver. 1 */
2079   buffer[1] = sps[0];           /* profile_idc                             */
2080   buffer[2] = sps[1];           /* profile_compability                     */
2081   buffer[3] = sps[2];           /* level_idc                               */
2082   buffer[4] = 0xfc | (4 - 1);   /* nal_length_size_minus1                  */
2083
2084   i_size = 5;
2085
2086   buffer[i_size++] = 0xe0 | 1;  /* number of SPSs */
2087
2088   nal_size = nal[sps_ni].i_payload - 4;
2089   memcpy (buffer + i_size + 2, nal[sps_ni].p_payload + 4, nal_size);
2090
2091   GST_WRITE_UINT16_BE (buffer + i_size, nal_size);
2092   i_size += nal_size + 2;
2093
2094   buffer[i_size++] = 1;         /* number of PPSs */
2095
2096   nal_size = nal[pps_ni].i_payload - 4;
2097   memcpy (buffer + i_size + 2, nal[pps_ni].p_payload + 4, nal_size);
2098
2099   GST_WRITE_UINT16_BE (buffer + i_size, nal_size);
2100   i_size += nal_size + 2;
2101
2102   buf = gst_buffer_new_and_alloc (i_size);
2103   gst_buffer_fill (buf, 0, buffer, i_size);
2104
2105   GST_MEMDUMP ("header", buffer, i_size);
2106   g_free (buffer);
2107
2108   return buf;
2109 }
2110
2111 /* gst_x264_enc_set_src_caps
2112  * Returns: TRUE on success.
2113  */
2114 static gboolean
2115 gst_x264_enc_set_src_caps (GstX264Enc * encoder, GstCaps * caps)
2116 {
2117   GstCaps *outcaps;
2118   GstStructure *structure;
2119   GstVideoCodecState *state;
2120   GstTagList *tags;
2121   guint bitrate =
2122       gst_encoder_bitrate_profile_manager_get_bitrate (encoder->bitrate_manager,
2123       encoder->input_state ? &encoder->input_state->info : NULL);
2124
2125   outcaps = gst_caps_new_empty_simple ("video/x-h264");
2126   structure = gst_caps_get_structure (outcaps, 0);
2127
2128   if (encoder->current_byte_stream == GST_X264_ENC_STREAM_FORMAT_FROM_PROPERTY) {
2129     if (encoder->byte_stream) {
2130       encoder->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_BYTE_STREAM;
2131     } else {
2132       encoder->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_AVC;
2133     }
2134   }
2135   if (encoder->current_byte_stream == GST_X264_ENC_STREAM_FORMAT_AVC) {
2136     GstBuffer *buf = gst_x264_enc_header_buf (encoder);
2137     if (buf != NULL) {
2138       gst_caps_set_simple (outcaps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
2139       gst_buffer_unref (buf);
2140     }
2141     gst_structure_set (structure, "stream-format", G_TYPE_STRING, "avc", NULL);
2142   } else {
2143     gst_structure_set (structure, "stream-format", G_TYPE_STRING, "byte-stream",
2144         NULL);
2145   }
2146   gst_structure_set (structure, "alignment", G_TYPE_STRING, "au", NULL);
2147
2148   if (!gst_x264_enc_set_profile_and_level (encoder, outcaps)) {
2149     gst_caps_unref (outcaps);
2150     return FALSE;
2151   }
2152
2153   state = gst_video_encoder_set_output_state (GST_VIDEO_ENCODER (encoder),
2154       outcaps, encoder->input_state);
2155   GST_DEBUG_OBJECT (encoder, "output caps: %" GST_PTR_FORMAT, state->caps);
2156
2157   /* If set, local frame packing setting overrides any upstream config */
2158   switch (encoder->frame_packing) {
2159     case 0:
2160       GST_VIDEO_INFO_MULTIVIEW_MODE (&state->info) =
2161           GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
2162       break;
2163     case 1:
2164       GST_VIDEO_INFO_MULTIVIEW_MODE (&state->info) =
2165           GST_VIDEO_MULTIVIEW_MODE_COLUMN_INTERLEAVED;
2166       break;
2167     case 2:
2168       GST_VIDEO_INFO_MULTIVIEW_MODE (&state->info) =
2169           GST_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED;
2170       break;
2171     case 3:
2172       GST_VIDEO_INFO_MULTIVIEW_MODE (&state->info) =
2173           GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
2174       break;
2175     case 4:
2176       GST_VIDEO_INFO_MULTIVIEW_MODE (&state->info) =
2177           GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
2178       break;
2179     case 5:
2180       GST_VIDEO_INFO_MULTIVIEW_MODE (&state->info) =
2181           GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
2182       break;
2183     default:
2184       break;
2185   }
2186
2187   gst_video_codec_state_unref (state);
2188
2189   tags = gst_tag_list_new_empty ();
2190   gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_ENCODER, "x264",
2191       GST_TAG_ENCODER_VERSION, X264_BUILD,
2192       GST_TAG_MAXIMUM_BITRATE, bitrate * 1024,
2193       GST_TAG_NOMINAL_BITRATE, bitrate * 1024, NULL);
2194   gst_video_encoder_merge_tags (GST_VIDEO_ENCODER (encoder), tags,
2195       GST_TAG_MERGE_REPLACE);
2196   gst_tag_list_unref (tags);
2197
2198   return TRUE;
2199 }
2200
2201 static void
2202 gst_x264_enc_set_latency (GstX264Enc * encoder)
2203 {
2204   GstVideoInfo *info = &encoder->input_state->info;
2205   gint max_delayed_frames;
2206   GstClockTime latency;
2207
2208   max_delayed_frames =
2209       encoder->vtable->x264_encoder_maximum_delayed_frames (encoder->x264enc);
2210
2211   if (info->fps_n) {
2212     latency = gst_util_uint64_scale_ceil (GST_SECOND * info->fps_d,
2213         max_delayed_frames, info->fps_n);
2214   } else {
2215     /* FIXME: Assume 25fps. This is better than reporting no latency at
2216      * all and then later failing in live pipelines
2217      */
2218     latency = gst_util_uint64_scale_ceil (GST_SECOND * 1,
2219         max_delayed_frames, 25);
2220   }
2221
2222   GST_INFO_OBJECT (encoder,
2223       "Updating latency to %" GST_TIME_FORMAT " (%d frames)",
2224       GST_TIME_ARGS (latency), max_delayed_frames);
2225
2226   gst_video_encoder_set_latency (GST_VIDEO_ENCODER (encoder), latency, latency);
2227 }
2228
2229 static gboolean
2230 gst_x264_enc_set_format (GstVideoEncoder * video_enc,
2231     GstVideoCodecState * state)
2232 {
2233   GstX264Enc *encoder = GST_X264_ENC (video_enc);
2234   GstVideoInfo *info = &state->info;
2235   GstCaps *template_caps;
2236   GstCaps *allowed_caps = NULL;
2237
2238   /* If the encoder is initialized, do not reinitialize it again if not
2239    * necessary */
2240   if (encoder->x264enc) {
2241     GstVideoInfo *old = &encoder->input_state->info;
2242
2243     if (info->finfo->format == old->finfo->format
2244         && info->width == old->width && info->height == old->height
2245         && info->fps_n == old->fps_n && info->fps_d == old->fps_d
2246         && info->par_n == old->par_n && info->par_d == old->par_d) {
2247       gst_video_codec_state_unref (encoder->input_state);
2248       encoder->input_state = gst_video_codec_state_ref (state);
2249       return TRUE;
2250     }
2251
2252     /* clear out pending frames */
2253     gst_x264_enc_flush_frames (encoder, TRUE);
2254
2255     encoder->sps_id++;
2256   }
2257
2258   if (encoder->input_state)
2259     gst_video_codec_state_unref (encoder->input_state);
2260   encoder->input_state = gst_video_codec_state_ref (state);
2261
2262   encoder->peer_profile = NULL;
2263   encoder->peer_intra_profile = FALSE;
2264   encoder->peer_level_idc = -1;
2265
2266   template_caps = gst_static_pad_template_get_caps (&src_factory);
2267   allowed_caps = gst_pad_get_allowed_caps (GST_VIDEO_ENCODER_SRC_PAD (encoder));
2268
2269   /* Output byte-stream if downstream has ANY caps, it's what people expect,
2270    * and it makes more sense too */
2271   if (allowed_caps == template_caps) {
2272     GST_INFO_OBJECT (encoder,
2273         "downstream has ANY caps, outputting byte-stream");
2274     encoder->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_BYTE_STREAM;
2275     g_string_append_printf (encoder->option_string, ":annexb=1");
2276     gst_caps_unref (allowed_caps);
2277   } else if (allowed_caps) {
2278     GstStructure *s;
2279     const gchar *profile;
2280     const gchar *level;
2281     const gchar *stream_format;
2282
2283     if (gst_caps_is_empty (allowed_caps)) {
2284       gst_caps_unref (allowed_caps);
2285       gst_caps_unref (template_caps);
2286       return FALSE;
2287     }
2288
2289     if (gst_caps_is_any (allowed_caps)) {
2290       gst_caps_unref (allowed_caps);
2291       allowed_caps = gst_caps_ref (template_caps);
2292     }
2293
2294     allowed_caps = gst_caps_make_writable (allowed_caps);
2295     allowed_caps = gst_caps_fixate (allowed_caps);
2296     s = gst_caps_get_structure (allowed_caps, 0);
2297
2298     profile = gst_structure_get_string (s, "profile");
2299     if (profile) {
2300       /* FIXME - if libx264 ever adds support for FMO, ASO or redundant slices
2301        * make sure constrained profile has a separate case which disables
2302        * those */
2303       if (g_str_has_suffix (profile, "-intra")) {
2304         encoder->peer_intra_profile = TRUE;
2305       }
2306       if (!strcmp (profile, "constrained-baseline") ||
2307           !strcmp (profile, "baseline")) {
2308         encoder->peer_profile = "baseline";
2309       } else if (g_str_has_prefix (profile, "high-10")) {
2310         encoder->peer_profile = "high10";
2311       } else if (g_str_has_prefix (profile, "high-4:2:2")) {
2312         encoder->peer_profile = "high422";
2313       } else if (g_str_has_prefix (profile, "high-4:4:4")) {
2314         encoder->peer_profile = "high444";
2315       } else if (g_str_has_prefix (profile, "high")) {
2316         encoder->peer_profile = "high";
2317       } else if (!strcmp (profile, "main")) {
2318         encoder->peer_profile = "main";
2319       } else {
2320         g_assert_not_reached ();
2321       }
2322     }
2323
2324     level = gst_structure_get_string (s, "level");
2325     if (level) {
2326       encoder->peer_level_idc = gst_codec_utils_h264_get_level_idc (level);
2327     }
2328
2329     stream_format = gst_structure_get_string (s, "stream-format");
2330     encoder->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_FROM_PROPERTY;
2331     if (stream_format) {
2332       if (!strcmp (stream_format, "avc")) {
2333         encoder->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_AVC;
2334         g_string_append_printf (encoder->option_string, ":annexb=0");
2335       } else if (!strcmp (stream_format, "byte-stream")) {
2336         encoder->current_byte_stream = GST_X264_ENC_STREAM_FORMAT_BYTE_STREAM;
2337         g_string_append_printf (encoder->option_string, ":annexb=1");
2338       } else {
2339         /* means we have both in caps and _FROM_PROPERTY should be the option */
2340       }
2341     }
2342
2343     gst_caps_unref (allowed_caps);
2344   }
2345
2346   gst_caps_unref (template_caps);
2347
2348   if (!gst_x264_enc_init_encoder (encoder))
2349     return FALSE;
2350
2351   if (!gst_x264_enc_set_src_caps (encoder, state->caps)) {
2352     gst_x264_enc_close_encoder (encoder);
2353     return FALSE;
2354   }
2355
2356   gst_x264_enc_set_latency (encoder);
2357
2358   return TRUE;
2359 }
2360
2361 static GstFlowReturn
2362 gst_x264_enc_finish (GstVideoEncoder * encoder)
2363 {
2364   gst_x264_enc_flush_frames (GST_X264_ENC (encoder), TRUE);
2365   return GST_FLOW_OK;
2366 }
2367
2368 static gboolean
2369 gst_x264_enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
2370 {
2371   GstX264Enc *self = GST_X264_ENC (encoder);
2372   GstVideoInfo *info;
2373   guint num_buffers;
2374
2375   gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
2376
2377   if (!self->input_state)
2378     return FALSE;
2379
2380   if (self->vtable == NULL)
2381     return FALSE;
2382
2383   info = &self->input_state->info;
2384   num_buffers =
2385       self->vtable->x264_encoder_maximum_delayed_frames (self->x264enc) + 1;
2386
2387   gst_query_add_allocation_pool (query, NULL, info->size, num_buffers, 0);
2388
2389   return GST_VIDEO_ENCODER_CLASS (parent_class)->propose_allocation (encoder,
2390       query);
2391 }
2392
2393 static void
2394 gst_x264_enc_add_cc (GstBuffer * buffer, x264_picture_t * pic_in)
2395 {
2396   GstVideoCaptionMeta *cc_meta;
2397   gpointer iter = NULL;
2398
2399   while ((cc_meta =
2400           (GstVideoCaptionMeta *) gst_buffer_iterate_meta_filtered (buffer,
2401               &iter, GST_VIDEO_CAPTION_META_API_TYPE))) {
2402     guint i = pic_in->extra_sei.num_payloads;
2403
2404     if (cc_meta->caption_type != GST_VIDEO_CAPTION_TYPE_CEA708_RAW)
2405       continue;
2406
2407     pic_in->extra_sei.num_payloads += 1;
2408
2409     if (!pic_in->extra_sei.payloads)
2410       pic_in->extra_sei.payloads = g_new0 (x264_sei_payload_t, 1);
2411     else
2412       pic_in->extra_sei.payloads =
2413           g_renew (x264_sei_payload_t, pic_in->extra_sei.payloads,
2414           pic_in->extra_sei.num_payloads);
2415
2416     pic_in->extra_sei.sei_free = g_free;
2417
2418     pic_in->extra_sei.payloads[i].payload_size = cc_meta->size + 11;
2419     pic_in->extra_sei.payloads[i].payload =
2420         g_malloc0 (pic_in->extra_sei.payloads[i].payload_size);
2421     pic_in->extra_sei.payloads[i].payload_type = 4;     /* Registered user data */
2422     memcpy (pic_in->extra_sei.payloads[i].payload + 10, cc_meta->data,
2423         cc_meta->size);
2424     pic_in->extra_sei.payloads[i].payload[0] = 181;     /* 8-bits itu_t_t35_country_code */
2425     pic_in->extra_sei.payloads[i].payload[1] = 0;       /* 16-bits itu_t_t35_provider_code */
2426     pic_in->extra_sei.payloads[i].payload[2] = 49;
2427     pic_in->extra_sei.payloads[i].payload[3] = 'G';     /* 32-bits ATSC_user_identifier */
2428     pic_in->extra_sei.payloads[i].payload[4] = 'A';
2429     pic_in->extra_sei.payloads[i].payload[5] = '9';
2430     pic_in->extra_sei.payloads[i].payload[6] = '4';
2431     pic_in->extra_sei.payloads[i].payload[7] = 3;       /* 8-bits ATSC1_data_user_data_type_code */
2432     /* 8-bits:
2433      * 1 bit process_em_data_flag (0)
2434      * 1 bit process_cc_data_flag (1)
2435      * 1 bit additional_data_flag (0)
2436      * 5-bits cc_count
2437      */
2438     pic_in->extra_sei.payloads[i].payload[8] =
2439         ((cc_meta->size / 3) & 0x1f) | 0x40;
2440     pic_in->extra_sei.payloads[i].payload[9] = 255;     /* 8 bits em_data, unused */
2441     pic_in->extra_sei.payloads[i].payload[cc_meta->size + 10] = 255;    /* 8 marker bits */
2442   }
2443 }
2444
2445 /* chain function
2446  * this function does the actual processing
2447  */
2448 static GstFlowReturn
2449 gst_x264_enc_handle_frame (GstVideoEncoder * video_enc,
2450     GstVideoCodecFrame * frame)
2451 {
2452   GstX264Enc *encoder = GST_X264_ENC (video_enc);
2453   GstVideoInfo *info = &encoder->input_state->info;
2454   GstFlowReturn ret;
2455   x264_picture_t pic_in;
2456   gint i_nal, i;
2457   FrameData *fdata;
2458   gint nplanes = encoder->x264_nplanes;
2459
2460   if (G_UNLIKELY (encoder->x264enc == NULL))
2461     goto not_inited;
2462
2463   /* create x264_picture_t from the buffer */
2464   /* mostly taken from mplayer (file ve_x264.c) */
2465
2466   /* set up input picture */
2467   memset (&pic_in, 0, sizeof (pic_in));
2468
2469   fdata = gst_x264_enc_queue_frame (encoder, frame, info);
2470   if (!fdata)
2471     goto invalid_frame;
2472
2473   pic_in.img.i_csp = encoder->x264param.i_csp;
2474   pic_in.img.i_plane = nplanes;
2475   for (i = 0; i < nplanes; i++) {
2476     pic_in.img.plane[i] = GST_VIDEO_FRAME_COMP_DATA (&fdata->vframe, i);
2477     pic_in.img.i_stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (&fdata->vframe, i);
2478   }
2479
2480   pic_in.i_type = X264_TYPE_AUTO;
2481   pic_in.i_pts = frame->pts;
2482   pic_in.opaque = GINT_TO_POINTER (frame->system_frame_number);
2483
2484   if (GST_VIDEO_INFO_INTERLACE_MODE (info) == GST_VIDEO_INTERLACE_MODE_MIXED) {
2485     if ((fdata->vframe.flags & GST_VIDEO_FRAME_FLAG_INTERLACED) == 0) {
2486       pic_in.i_pic_struct = PIC_STRUCT_PROGRESSIVE;
2487     } else if ((fdata->vframe.flags & GST_VIDEO_FRAME_FLAG_RFF) != 0) {
2488       if ((fdata->vframe.flags & GST_VIDEO_FRAME_FLAG_TFF) != 0) {
2489         pic_in.i_pic_struct = PIC_STRUCT_TOP_BOTTOM_TOP;
2490       } else {
2491         pic_in.i_pic_struct = PIC_STRUCT_BOTTOM_TOP_BOTTOM;
2492       }
2493     } else {
2494       if ((fdata->vframe.flags & GST_VIDEO_FRAME_FLAG_TFF) != 0) {
2495         pic_in.i_pic_struct = PIC_STRUCT_TOP_BOTTOM;
2496       } else {
2497         pic_in.i_pic_struct = PIC_STRUCT_BOTTOM_TOP;
2498       }
2499     }
2500   }
2501
2502   gst_x264_enc_add_cc (frame->input_buffer, &pic_in);
2503
2504   ret = gst_x264_enc_encode_frame (encoder, &pic_in, frame, &i_nal, TRUE);
2505
2506   /* input buffer is released later on */
2507   return ret;
2508
2509 /* ERRORS */
2510 not_inited:
2511   {
2512     GST_WARNING_OBJECT (encoder, "Got buffer before set_caps was called");
2513     return GST_FLOW_NOT_NEGOTIATED;
2514   }
2515 invalid_frame:
2516   {
2517     GST_ERROR_OBJECT (encoder, "Failed to map frame");
2518     return GST_FLOW_ERROR;
2519   }
2520 }
2521
2522 static GstFlowReturn
2523 gst_x264_enc_encode_frame (GstX264Enc * encoder, x264_picture_t * pic_in,
2524     GstVideoCodecFrame * input_frame, int *i_nal, gboolean send)
2525 {
2526   GstVideoCodecFrame *frame = NULL;
2527   GstBuffer *out_buf = NULL;
2528   x264_picture_t pic_out;
2529   x264_nal_t *nal;
2530   int i_size;
2531   int encoder_return;
2532   GstFlowReturn ret = GST_FLOW_OK;
2533   guint8 *data;
2534   gboolean update_latency = FALSE;
2535
2536   if (G_UNLIKELY (encoder->x264enc == NULL)) {
2537     if (input_frame)
2538       gst_video_codec_frame_unref (input_frame);
2539     return GST_FLOW_NOT_NEGOTIATED;
2540   }
2541
2542   GST_OBJECT_LOCK (encoder);
2543   if (encoder->reconfig) {
2544     encoder->reconfig = FALSE;
2545     if (encoder->vtable->x264_encoder_reconfig (encoder->x264enc,
2546             &encoder->x264param) < 0)
2547       GST_WARNING_OBJECT (encoder, "Could not reconfigure");
2548     update_latency = TRUE;
2549   }
2550
2551   if (pic_in && input_frame) {
2552     if (GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (input_frame)) {
2553       GST_INFO_OBJECT (encoder, "Forcing key frame");
2554       if (encoder->intra_refresh)
2555         encoder->vtable->x264_encoder_intra_refresh (encoder->x264enc);
2556       else
2557         pic_in->i_type = X264_TYPE_IDR;
2558     }
2559   }
2560   GST_OBJECT_UNLOCK (encoder);
2561
2562   if (G_UNLIKELY (update_latency))
2563     gst_x264_enc_set_latency (encoder);
2564
2565   encoder_return = encoder->vtable->x264_encoder_encode (encoder->x264enc,
2566       &nal, i_nal, pic_in, &pic_out);
2567
2568   if (encoder_return < 0) {
2569     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x264 frame failed."),
2570         ("x264_encoder_encode return code=%d", encoder_return));
2571     ret = GST_FLOW_ERROR;
2572     /* Make sure we finish this frame */
2573     frame = input_frame;
2574     goto out;
2575   }
2576
2577   /* Input frame is now queued */
2578   if (input_frame)
2579     gst_video_codec_frame_unref (input_frame);
2580
2581   if (!*i_nal) {
2582     ret = GST_FLOW_OK;
2583     goto out;
2584   }
2585
2586   i_size = encoder_return;
2587   data = nal[0].p_payload;
2588
2589   frame = gst_video_encoder_get_frame (GST_VIDEO_ENCODER (encoder),
2590       GPOINTER_TO_INT (pic_out.opaque));
2591   g_assert (frame || !send);
2592
2593   if (!send || !frame) {
2594     ret = GST_FLOW_OK;
2595     goto out;
2596   }
2597
2598   out_buf = gst_buffer_new_allocate (NULL, i_size, NULL);
2599   gst_buffer_fill (out_buf, 0, data, i_size);
2600   frame->output_buffer = out_buf;
2601
2602   GST_LOG_OBJECT (encoder,
2603       "output: dts %" G_GINT64_FORMAT " pts %" G_GINT64_FORMAT,
2604       (gint64) pic_out.i_dts, (gint64) pic_out.i_pts);
2605
2606   /* we want to know if x264 is messing around with this */
2607   g_assert (frame->pts == pic_out.i_pts);
2608
2609   frame->dts = pic_out.i_dts;
2610   frame->pts = pic_out.i_pts;
2611
2612   if (pic_out.b_keyframe) {
2613     GST_DEBUG_OBJECT (encoder, "Output keyframe");
2614     GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
2615   }
2616
2617 out:
2618   if (frame) {
2619     gst_x264_enc_dequeue_frame (encoder, frame);
2620     ret = gst_video_encoder_finish_frame (GST_VIDEO_ENCODER (encoder), frame);
2621   }
2622
2623   return ret;
2624 }
2625
2626 static void
2627 gst_x264_enc_flush_frames (GstX264Enc * encoder, gboolean send)
2628 {
2629   GstFlowReturn flow_ret;
2630   gint i_nal;
2631
2632   /* first send the remaining frames */
2633   if (encoder->x264enc)
2634     do {
2635       flow_ret = gst_x264_enc_encode_frame (encoder, NULL, NULL, &i_nal, send);
2636     } while (flow_ret == GST_FLOW_OK
2637         && encoder->vtable->x264_encoder_delayed_frames (encoder->x264enc) > 0);
2638 }
2639
2640 static void
2641 gst_x264_enc_reconfig (GstX264Enc * encoder)
2642 {
2643   guint bitrate;
2644
2645   if (!encoder->vtable)
2646     return;
2647
2648   bitrate =
2649       gst_encoder_bitrate_profile_manager_get_bitrate (encoder->bitrate_manager,
2650       encoder->input_state ? &encoder->input_state->info : NULL);
2651   switch (encoder->pass) {
2652     case GST_X264_ENC_PASS_QUAL:
2653       encoder->x264param.rc.f_rf_constant = encoder->quantizer;
2654       encoder->x264param.rc.i_vbv_max_bitrate = bitrate;
2655       encoder->x264param.rc.i_vbv_buffer_size
2656           = encoder->x264param.rc.i_vbv_max_bitrate
2657           * encoder->vbv_buf_capacity / 1000;
2658       break;
2659     case GST_X264_ENC_PASS_CBR:
2660     case GST_X264_ENC_PASS_PASS1:
2661     case GST_X264_ENC_PASS_PASS2:
2662     case GST_X264_ENC_PASS_PASS3:
2663     default:
2664       encoder->x264param.rc.i_bitrate = bitrate;
2665       encoder->x264param.rc.i_vbv_max_bitrate = bitrate;
2666       encoder->x264param.rc.i_vbv_buffer_size
2667           = encoder->x264param.rc.i_vbv_max_bitrate
2668           * encoder->vbv_buf_capacity / 1000;
2669       break;
2670   }
2671
2672   encoder->reconfig = TRUE;
2673 }
2674
2675 static void
2676 gst_x264_enc_set_property (GObject * object, guint prop_id,
2677     const GValue * value, GParamSpec * pspec)
2678 {
2679   GstX264Enc *encoder;
2680   GstState state;
2681
2682   const gchar *partitions = NULL;
2683
2684   encoder = GST_X264_ENC (object);
2685
2686   GST_OBJECT_LOCK (encoder);
2687   /* state at least matters for sps, bytestream, pass,
2688    * and so by extension ... */
2689
2690   state = GST_STATE (encoder);
2691   if ((state != GST_STATE_READY && state != GST_STATE_NULL) &&
2692       !(pspec->flags & GST_PARAM_MUTABLE_PLAYING))
2693     goto wrong_state;
2694
2695   switch (prop_id) {
2696     case ARG_PASS:
2697       encoder->pass = g_value_get_enum (value);
2698       break;
2699     case ARG_QUANTIZER:
2700       encoder->quantizer = g_value_get_uint (value);
2701       gst_x264_enc_reconfig (encoder);
2702       break;
2703     case ARG_BITRATE:
2704       gst_encoder_bitrate_profile_manager_set_bitrate (encoder->bitrate_manager,
2705           g_value_get_uint (value));
2706       gst_x264_enc_reconfig (encoder);
2707       break;
2708     case ARG_VBV_BUF_CAPACITY:
2709       encoder->vbv_buf_capacity = g_value_get_uint (value);
2710       gst_x264_enc_reconfig (encoder);
2711       break;
2712     case ARG_SPEED_PRESET:
2713       encoder->speed_preset = g_value_get_enum (value);
2714       break;
2715     case ARG_PSY_TUNE:
2716       encoder->psy_tune = g_value_get_enum (value);
2717       break;
2718     case ARG_TUNE:
2719       encoder->tune = g_value_get_flags (value);
2720       break;
2721     case ARG_OPTION_STRING:
2722       g_string_assign (encoder->option_string_prop, g_value_get_string (value));
2723       break;
2724     case ARG_THREADS:
2725       encoder->threads = g_value_get_uint (value);
2726       g_string_append_printf (encoder->option_string, ":threads=%d",
2727           encoder->threads);
2728       break;
2729     case ARG_SLICED_THREADS:
2730       encoder->sliced_threads = g_value_get_boolean (value);
2731       g_string_append_printf (encoder->option_string, ":sliced-threads=%d",
2732           encoder->sliced_threads);
2733       break;
2734     case ARG_SYNC_LOOKAHEAD:
2735       encoder->sync_lookahead = g_value_get_int (value);
2736       g_string_append_printf (encoder->option_string, ":sync-lookahead=%d",
2737           encoder->sync_lookahead);
2738       break;
2739     case ARG_MULTIPASS_CACHE_FILE:
2740       g_free (encoder->mp_cache_file);
2741       encoder->mp_cache_file = g_value_dup_string (value);
2742       g_string_append_printf (encoder->option_string, ":stats=%s",
2743           encoder->mp_cache_file);
2744       break;
2745     case ARG_BYTE_STREAM:
2746       encoder->byte_stream = g_value_get_boolean (value);
2747       g_string_append_printf (encoder->option_string, ":annexb=%d",
2748           encoder->byte_stream);
2749       break;
2750     case ARG_INTRA_REFRESH:
2751       encoder->intra_refresh = g_value_get_boolean (value);
2752       g_string_append_printf (encoder->option_string, ":intra-refresh=%d",
2753           encoder->intra_refresh);
2754       break;
2755     case ARG_ME:
2756       encoder->me = g_value_get_enum (value);
2757       g_string_append_printf (encoder->option_string, ":me=%s",
2758           x264_motion_est_names[encoder->me]);
2759       break;
2760     case ARG_SUBME:
2761       encoder->subme = g_value_get_uint (value);
2762       g_string_append_printf (encoder->option_string, ":subme=%d",
2763           encoder->subme);
2764       break;
2765     case ARG_ANALYSE:
2766       encoder->analyse = g_value_get_flags (value);
2767       partitions = gst_x264_enc_build_partitions (encoder->analyse);
2768       if (partitions) {
2769         g_string_append_printf (encoder->option_string, ":partitions=%s",
2770             partitions);
2771         g_free ((gpointer) partitions);
2772       }
2773       break;
2774     case ARG_DCT8x8:
2775       encoder->dct8x8 = g_value_get_boolean (value);
2776       g_string_append_printf (encoder->option_string, ":8x8dct=%d",
2777           encoder->dct8x8);
2778       break;
2779     case ARG_REF:
2780       encoder->ref = g_value_get_uint (value);
2781       g_string_append_printf (encoder->option_string, ":ref=%d", encoder->ref);
2782       break;
2783     case ARG_BFRAMES:
2784       encoder->bframes = g_value_get_uint (value);
2785       g_string_append_printf (encoder->option_string, ":bframes=%d",
2786           encoder->bframes);
2787       break;
2788     case ARG_B_ADAPT:
2789       encoder->b_adapt = g_value_get_boolean (value);
2790       g_string_append_printf (encoder->option_string, ":b-adapt=%d",
2791           encoder->b_adapt);
2792       break;
2793     case ARG_B_PYRAMID:
2794       encoder->b_pyramid = g_value_get_boolean (value);
2795       g_string_append_printf (encoder->option_string, ":b-pyramid=%s",
2796           x264_b_pyramid_names[encoder->b_pyramid]);
2797       break;
2798     case ARG_WEIGHTB:
2799       encoder->weightb = g_value_get_boolean (value);
2800       g_string_append_printf (encoder->option_string, ":weightb=%d",
2801           encoder->weightb);
2802       break;
2803     case ARG_SPS_ID:
2804       encoder->sps_id = g_value_get_uint (value);
2805       g_string_append_printf (encoder->option_string, ":sps-id=%d",
2806           encoder->sps_id);
2807       break;
2808     case ARG_AU_NALU:
2809       encoder->au_nalu = g_value_get_boolean (value);
2810       g_string_append_printf (encoder->option_string, ":aud=%d",
2811           encoder->au_nalu);
2812       break;
2813     case ARG_TRELLIS:
2814       encoder->trellis = g_value_get_boolean (value);
2815       g_string_append_printf (encoder->option_string, ":trellis=%d",
2816           encoder->trellis);
2817       break;
2818     case ARG_KEYINT_MAX:
2819       encoder->keyint_max = g_value_get_uint (value);
2820       g_string_append_printf (encoder->option_string, ":keyint=%d",
2821           encoder->keyint_max);
2822       break;
2823     case ARG_CABAC:
2824       encoder->cabac = g_value_get_boolean (value);
2825       g_string_append_printf (encoder->option_string, ":cabac=%d",
2826           encoder->cabac);
2827       break;
2828     case ARG_QP_MIN:
2829       encoder->qp_min = g_value_get_uint (value);
2830       g_string_append_printf (encoder->option_string, ":qpmin=%d",
2831           encoder->qp_min);
2832       break;
2833     case ARG_QP_MAX:
2834       encoder->qp_max = g_value_get_uint (value);
2835       g_string_append_printf (encoder->option_string, ":qpmax=%d",
2836           encoder->qp_max);
2837       break;
2838     case ARG_QP_STEP:
2839       encoder->qp_step = g_value_get_uint (value);
2840       g_string_append_printf (encoder->option_string, ":qpstep=%d",
2841           encoder->qp_step);
2842       break;
2843     case ARG_IP_FACTOR:
2844       encoder->ip_factor = g_value_get_float (value);
2845       g_string_append_printf (encoder->option_string, ":ip-factor=%f",
2846           encoder->ip_factor);
2847       break;
2848     case ARG_PB_FACTOR:
2849       encoder->pb_factor = g_value_get_float (value);
2850       g_string_append_printf (encoder->option_string, ":pb-factor=%f",
2851           encoder->pb_factor);
2852       break;
2853     case ARG_RC_MB_TREE:
2854       encoder->mb_tree = g_value_get_boolean (value);
2855       g_string_append_printf (encoder->option_string, ":mbtree=%d",
2856           encoder->mb_tree);
2857       break;
2858     case ARG_RC_LOOKAHEAD:
2859       encoder->rc_lookahead = g_value_get_int (value);
2860       g_string_append_printf (encoder->option_string, ":rc-lookahead=%d",
2861           encoder->rc_lookahead);
2862       break;
2863     case ARG_NR:
2864       encoder->noise_reduction = g_value_get_uint (value);
2865       g_string_append_printf (encoder->option_string, ":nr=%d",
2866           encoder->noise_reduction);
2867       break;
2868     case ARG_INTERLACED:
2869       encoder->interlaced = g_value_get_boolean (value);
2870       break;
2871     case ARG_FRAME_PACKING:
2872       encoder->frame_packing = g_value_get_enum (value);
2873       break;
2874     case ARG_INSERT_VUI:
2875       encoder->insert_vui = g_value_get_boolean (value);
2876       break;
2877     default:
2878       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2879       break;
2880   }
2881   GST_OBJECT_UNLOCK (encoder);
2882   return;
2883
2884   /* ERROR */
2885 wrong_state:
2886   {
2887     GST_WARNING_OBJECT (encoder, "setting property in wrong state");
2888     GST_OBJECT_UNLOCK (encoder);
2889   }
2890 }
2891
2892 static void
2893 gst_x264_enc_get_property (GObject * object, guint prop_id,
2894     GValue * value, GParamSpec * pspec)
2895 {
2896   GstX264Enc *encoder;
2897
2898   encoder = GST_X264_ENC (object);
2899
2900   GST_OBJECT_LOCK (encoder);
2901   switch (prop_id) {
2902     case ARG_THREADS:
2903       g_value_set_uint (value, encoder->threads);
2904       break;
2905     case ARG_SLICED_THREADS:
2906       g_value_set_boolean (value, encoder->sliced_threads);
2907       break;
2908     case ARG_SYNC_LOOKAHEAD:
2909       g_value_set_int (value, encoder->sync_lookahead);
2910       break;
2911     case ARG_PASS:
2912       g_value_set_enum (value, encoder->pass);
2913       break;
2914     case ARG_QUANTIZER:
2915       g_value_set_uint (value, encoder->quantizer);
2916       break;
2917     case ARG_MULTIPASS_CACHE_FILE:
2918       g_value_set_string (value, encoder->mp_cache_file);
2919       break;
2920     case ARG_BYTE_STREAM:
2921       g_value_set_boolean (value, encoder->byte_stream);
2922       break;
2923     case ARG_BITRATE:
2924       g_value_set_uint (value,
2925           gst_encoder_bitrate_profile_manager_get_bitrate
2926           (encoder->bitrate_manager, NULL));
2927       break;
2928     case ARG_INTRA_REFRESH:
2929       g_value_set_boolean (value, encoder->intra_refresh);
2930       break;
2931     case ARG_VBV_BUF_CAPACITY:
2932       g_value_set_uint (value, encoder->vbv_buf_capacity);
2933       break;
2934     case ARG_ME:
2935       g_value_set_enum (value, encoder->me);
2936       break;
2937     case ARG_SUBME:
2938       g_value_set_uint (value, encoder->subme);
2939       break;
2940     case ARG_ANALYSE:
2941       g_value_set_flags (value, encoder->analyse);
2942       break;
2943     case ARG_DCT8x8:
2944       g_value_set_boolean (value, encoder->dct8x8);
2945       break;
2946     case ARG_REF:
2947       g_value_set_uint (value, encoder->ref);
2948       break;
2949     case ARG_BFRAMES:
2950       g_value_set_uint (value, encoder->bframes);
2951       break;
2952     case ARG_B_ADAPT:
2953       g_value_set_boolean (value, encoder->b_adapt);
2954       break;
2955     case ARG_B_PYRAMID:
2956       g_value_set_boolean (value, encoder->b_pyramid);
2957       break;
2958     case ARG_WEIGHTB:
2959       g_value_set_boolean (value, encoder->weightb);
2960       break;
2961     case ARG_SPS_ID:
2962       g_value_set_uint (value, encoder->sps_id);
2963       break;
2964     case ARG_AU_NALU:
2965       g_value_set_boolean (value, encoder->au_nalu);
2966       break;
2967     case ARG_TRELLIS:
2968       g_value_set_boolean (value, encoder->trellis);
2969       break;
2970     case ARG_KEYINT_MAX:
2971       g_value_set_uint (value, encoder->keyint_max);
2972       break;
2973     case ARG_QP_MIN:
2974       g_value_set_uint (value, encoder->qp_min);
2975       break;
2976     case ARG_QP_MAX:
2977       g_value_set_uint (value, encoder->qp_max);
2978       break;
2979     case ARG_QP_STEP:
2980       g_value_set_uint (value, encoder->qp_step);
2981       break;
2982     case ARG_CABAC:
2983       g_value_set_boolean (value, encoder->cabac);
2984       break;
2985     case ARG_IP_FACTOR:
2986       g_value_set_float (value, encoder->ip_factor);
2987       break;
2988     case ARG_PB_FACTOR:
2989       g_value_set_float (value, encoder->pb_factor);
2990       break;
2991     case ARG_RC_MB_TREE:
2992       g_value_set_boolean (value, encoder->mb_tree);
2993       break;
2994     case ARG_RC_LOOKAHEAD:
2995       g_value_set_int (value, encoder->rc_lookahead);
2996       break;
2997     case ARG_NR:
2998       g_value_set_uint (value, encoder->noise_reduction);
2999       break;
3000     case ARG_INTERLACED:
3001       g_value_set_boolean (value, encoder->interlaced);
3002       break;
3003     case ARG_SPEED_PRESET:
3004       g_value_set_enum (value, encoder->speed_preset);
3005       break;
3006     case ARG_PSY_TUNE:
3007       g_value_set_enum (value, encoder->psy_tune);
3008       break;
3009     case ARG_TUNE:
3010       g_value_set_flags (value, encoder->tune);
3011       break;
3012     case ARG_OPTION_STRING:
3013       g_value_set_string (value, encoder->option_string_prop->str);
3014       break;
3015     case ARG_FRAME_PACKING:
3016       g_value_set_enum (value, encoder->frame_packing);
3017       break;
3018     case ARG_INSERT_VUI:
3019       g_value_set_boolean (value, encoder->insert_vui);
3020       break;
3021     default:
3022       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3023       break;
3024   }
3025   GST_OBJECT_UNLOCK (encoder);
3026 }
3027
3028 static gboolean
3029 x264_element_init (GstPlugin * plugin)
3030 {
3031   GST_DEBUG_CATEGORY_INIT (x264_enc_debug, "x264enc", 0,
3032       "h264 encoding element");
3033
3034   GST_INFO ("linked against x264 build: %u", X264_BUILD);
3035
3036   /* Initialize the static GstX264EncVTable which is overridden in load_x264()
3037    * if needed. We can't initialize statically because these values are not
3038    * constant on Windows. */
3039   default_vtable.module = NULL;
3040 #if X264_BUILD < 153
3041   default_vtable.x264_bit_depth = &x264_bit_depth;
3042 #endif
3043   default_vtable.x264_chroma_format = &x264_chroma_format;
3044   default_vtable.x264_encoder_close = x264_encoder_close;
3045   default_vtable.x264_encoder_delayed_frames = x264_encoder_delayed_frames;
3046   default_vtable.x264_encoder_encode = x264_encoder_encode;
3047   default_vtable.x264_encoder_headers = x264_encoder_headers;
3048   default_vtable.x264_encoder_intra_refresh = x264_encoder_intra_refresh;
3049   default_vtable.x264_encoder_maximum_delayed_frames =
3050       x264_encoder_maximum_delayed_frames;
3051   default_vtable.x264_encoder_open = x264_encoder_open;
3052   default_vtable.x264_encoder_reconfig = x264_encoder_reconfig;
3053   default_vtable.x264_levels = &x264_levels;
3054   default_vtable.x264_param_apply_fastfirstpass =
3055       x264_param_apply_fastfirstpass;
3056   default_vtable.x264_param_apply_profile = x264_param_apply_profile;
3057   default_vtable.x264_param_default_preset = x264_param_default_preset;
3058   default_vtable.x264_param_parse = x264_param_parse;
3059
3060   if (!load_x264_libraries ())
3061     return FALSE;
3062
3063   return gst_element_register (plugin, "x264enc",
3064       GST_RANK_PRIMARY, GST_TYPE_X264_ENC);
3065 }
3066
3067 static gboolean
3068 plugin_init (GstPlugin * plugin)
3069 {
3070   return GST_ELEMENT_REGISTER (x264enc, plugin);
3071 }
3072
3073 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
3074     GST_VERSION_MINOR,
3075     x264,
3076     "libx264-based H.264 encoder plugin",
3077     plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)