1 /* GStreamer H264 encoder plugin
2 * Copyright (C) 2005 Michal Benes <michal.benes@itonis.tv>
3 * Copyright (C) 2005 Josef Zlomek <josef.zlomek@itonis.tv>
4 * Copyright (C) 2008 Mark Nauwelaerts <mnauw@users.sf.net>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
22 /**
23 * SECTION:element-x264enc
24 * @see_also: faac
25 *
26 * This element encodes raw video into H264 compressed data,
27 * also otherwise known as MPEG-4 AVC (Advanced Video Codec).
28 *
29 * The #GstX264Enc:pass property controls the type of encoding. In case of Constant
30 * Bitrate Encoding (actually ABR), the #GstX264Enc:bitrate will determine the quality
31 * of the encoding. This will similarly be the case if this target bitrate
32 * is to obtained in multiple (2 or 3) pass encoding.
33 * Alternatively, one may choose to perform Constant Quantizer or Quality encoding,
34 * in which case the #GstX264Enc:quantizer property controls much of the outcome.
35 *
36 * The H264 profile that is eventually used depends on a few settings.
37 * If #GstX264Enc:dct8x8 is enabled, then High profile is used.
38 * Otherwise, if #GstX264Enc:cabac entropy coding is enabled or #GstX264Enc:bframes
39 * are allowed, then Main Profile is in effect, and otherwise Baseline profile
40 * applies. As such, Main is presently the default profile, which is fine for
41 * most players and settings, but in some cases (e.g. hardware platforms)
42 * a more restricted profile/level may be necessary.
43 *
44 * If a preset/tuning are specified then these will define the default values and
45 * the property defaults will be ignored. After this the option-string property is
46 * applied, followed by the user-set properties, fast first pass restrictions and
47 * finally the profile restrictions.
48 *
49 * <refsect2>
50 * <title>Example pipeline</title>
51 * |[
52 * gst-launch -v videotestsrc num-buffers=1000 ! x264enc qp-min=18 ! \
53 * avimux ! filesink location=videotestsrc.avi
54 * ]| This example pipeline will encode a test video source to H264 muxed in an
55 * AVI container, while ensuring a sane minimum quantization factor to avoid
56 * some (excessive) waste.
57 * |[
58 * gst-launch -v videotestsrc num-buffers=1000 ! x264enc pass=quant ! \
59 * matroskamux ! filesink location=videotestsrc.avi
60 * ]| This example pipeline will encode a test video source to H264 using fixed
61 * quantization, and muxes it in a Matroska container.
62 * |[
63 * gst-launch -v videotestsrc num-buffers=1000 ! x264enc pass=5 quantizer=25 speed-preset=6 profile=1 ! \
64 * qtmux ! filesink location=videotestsrc.mov
65 * ]| This example pipeline will encode a test video source to H264 using
66 * constant quality at around Q25 using the 'medium' speed/quality preset and
67 * restricting the options used so that the output is H.264 Baseline Profile
68 * compliant and finally multiplexing the output in Quicktime mov format.
69 * </refsect2>
70 */
72 #ifdef HAVE_CONFIG_H
73 # include "config.h"
74 #endif
76 #include "gstx264enc.h"
78 #if X264_BUILD >= 76
79 #define X264_ENC_NALS 1
80 #endif
82 #if X264_BUILD >= 69
83 #define X264_MB_RC
84 #endif
86 #if X264_BUILD >= 80
87 #define X264_ENH_THREADING
88 #endif
90 #if X264_BUILD >= 82
91 #define X264_INTRA_REFRESH
92 #endif
94 #if X264_BUILD >= 86
95 #define X264_PRESETS
96 #endif
98 #include <string.h>
99 #include <stdlib.h>
101 GST_DEBUG_CATEGORY_STATIC (x264_enc_debug);
102 #define GST_CAT_DEFAULT x264_enc_debug
104 enum
105 {
106 ARG_0,
107 ARG_THREADS,
108 ARG_SLICED_THREADS,
109 ARG_SYNC_LOOKAHEAD,
110 ARG_PASS,
111 ARG_QUANTIZER,
112 ARG_STATS_FILE,
113 ARG_MULTIPASS_CACHE_FILE,
114 ARG_BYTE_STREAM,
115 ARG_BITRATE,
116 ARG_INTRA_REFRESH,
117 ARG_VBV_BUF_CAPACITY,
118 ARG_ME,
119 ARG_SUBME,
120 ARG_ANALYSE,
121 ARG_DCT8x8,
122 ARG_REF,
123 ARG_BFRAMES,
124 ARG_B_ADAPT,
125 ARG_B_PYRAMID,
126 ARG_WEIGHTB,
127 ARG_SPS_ID,
128 ARG_AU_NALU,
129 ARG_TRELLIS,
130 ARG_KEYINT_MAX,
131 ARG_CABAC,
132 ARG_QP_MIN,
133 ARG_QP_MAX,
134 ARG_QP_STEP,
135 ARG_IP_FACTOR,
136 ARG_PB_FACTOR,
137 ARG_RC_MB_TREE,
138 ARG_RC_LOOKAHEAD,
139 ARG_NR,
140 ARG_INTERLACED,
141 ARG_OPTION_STRING,
142 ARG_PROFILE,
143 ARG_SPEED_PRESET,
144 ARG_PSY_TUNE,
145 ARG_TUNE,
146 };
148 #define ARG_THREADS_DEFAULT 1
149 #define ARG_PASS_DEFAULT 0
150 #define ARG_QUANTIZER_DEFAULT 21
151 #define ARG_MULTIPASS_CACHE_FILE_DEFAULT "x264.log"
152 #define ARG_STATS_FILE_DEFAULT ARG_MULTIPASS_CACHE_FILE_DEFAULT
153 #define ARG_BYTE_STREAM_DEFAULT FALSE
154 #define ARG_BITRATE_DEFAULT (2 * 1024)
155 #define ARG_VBV_BUF_CAPACITY_DEFAULT 600
156 #define ARG_ME_DEFAULT X264_ME_HEX
157 #define ARG_SUBME_DEFAULT 1
158 #define ARG_ANALYSE_DEFAULT 0
159 #define ARG_DCT8x8_DEFAULT FALSE
160 #define ARG_REF_DEFAULT 1
161 #define ARG_BFRAMES_DEFAULT 0
162 #define ARG_B_ADAPT_DEFAULT TRUE
163 #define ARG_B_PYRAMID_DEFAULT FALSE
164 #define ARG_WEIGHTB_DEFAULT FALSE
165 #define ARG_SPS_ID_DEFAULT 0
166 #define ARG_AU_NALU_DEFAULT TRUE
167 #define ARG_TRELLIS_DEFAULT TRUE
168 #define ARG_KEYINT_MAX_DEFAULT 0
169 #define ARG_CABAC_DEFAULT TRUE
170 #define ARG_QP_MIN_DEFAULT 10
171 #define ARG_QP_MAX_DEFAULT 51
172 #define ARG_QP_STEP_DEFAULT 4
173 #define ARG_IP_FACTOR_DEFAULT 1.4
174 #define ARG_PB_FACTOR_DEFAULT 1.3
175 #define ARG_NR_DEFAULT 0
176 #define ARG_INTERLACED_DEFAULT FALSE
177 #define ARG_SLICED_THREADS_DEFAULT FALSE
178 #define ARG_SYNC_LOOKAHEAD_DEFAULT -1
179 #define ARG_RC_MB_TREE_DEFAULT TRUE
180 #define ARG_RC_LOOKAHEAD_DEFAULT 40
181 #define ARG_INTRA_REFRESH_DEFAULT FALSE
182 #define ARG_PROFILE_DEFAULT 1 /* Main profile matches current defaults */
183 #define ARG_OPTION_STRING_DEFAULT ""
184 static GString *x264enc_defaults;
185 #define ARG_SPEED_PRESET_DEFAULT 0 /* no preset */
186 #define ARG_PSY_TUNE_DEFAULT 0 /* no psy tuning */
187 #define ARG_TUNE_DEFAULT 0 /* no tuning */
189 enum
190 {
191 GST_X264_ENC_PASS_CBR = 0,
192 GST_X264_ENC_PASS_QUANT = 0x04,
193 GST_X264_ENC_PASS_QUAL,
194 GST_X264_ENC_PASS_PASS1 = 0x11,
195 GST_X264_ENC_PASS_PASS2,
196 GST_X264_ENC_PASS_PASS3
197 };
199 #define GST_X264_ENC_PASS_TYPE (gst_x264_enc_pass_get_type())
200 static GType
201 gst_x264_enc_pass_get_type (void)
202 {
203 static GType pass_type = 0;
205 static const GEnumValue pass_types[] = {
206 {GST_X264_ENC_PASS_CBR, "Constant Bitrate Encoding", "cbr"},
207 {GST_X264_ENC_PASS_QUANT, "Constant Quantizer", "quant"},
208 {GST_X264_ENC_PASS_QUAL, "Constant Quality", "qual"},
209 {GST_X264_ENC_PASS_PASS1, "VBR Encoding - Pass 1", "pass1"},
210 {GST_X264_ENC_PASS_PASS2, "VBR Encoding - Pass 2", "pass2"},
211 {GST_X264_ENC_PASS_PASS3, "VBR Encoding - Pass 3", "pass3"},
212 {0, NULL, NULL}
213 };
215 if (!pass_type) {
216 pass_type = g_enum_register_static ("GstX264EncPass", pass_types);
217 }
218 return pass_type;
219 }
221 #define GST_X264_ENC_ME_TYPE (gst_x264_enc_me_get_type())
222 static GType
223 gst_x264_enc_me_get_type (void)
224 {
225 static GType me_type = 0;
226 static GEnumValue *me_types;
227 int n, i;
229 if (me_type != 0)
230 return me_type;
232 n = 0;
233 while (x264_motion_est_names[n] != NULL)
234 n++;
236 me_types = g_new0 (GEnumValue, n + 1);
238 for (i = 0; i < n; i++) {
239 me_types[i].value = i;
240 me_types[i].value_name = x264_motion_est_names[i];
241 me_types[i].value_nick = x264_motion_est_names[i];
242 }
244 me_type = g_enum_register_static ("GstX264EncMe", me_types);
246 return me_type;
247 }
249 #define GST_X264_ENC_ANALYSE_TYPE (gst_x264_enc_analyse_get_type())
250 static GType
251 gst_x264_enc_analyse_get_type (void)
252 {
253 static GType analyse_type = 0;
254 static const GFlagsValue analyse_types[] = {
255 {X264_ANALYSE_I4x4, "i4x4", "i4x4"},
256 {X264_ANALYSE_I8x8, "i8x8", "i8x8"},
257 {X264_ANALYSE_PSUB16x16, "p8x8", "p8x8"},
258 {X264_ANALYSE_PSUB8x8, "p4x4", "p4x4"},
259 {X264_ANALYSE_BSUB16x16, "b8x8", "b8x8"},
260 {0, NULL, NULL},
261 };
263 if (!analyse_type) {
264 analyse_type = g_flags_register_static ("GstX264EncAnalyse", analyse_types);
265 }
266 return analyse_type;
267 }
269 #ifdef X264_PRESETS
271 #define GST_X264_ENC_PROFILE_TYPE (gst_x264_enc_profile_get_type())
272 static GType
273 gst_x264_enc_profile_get_type (void)
274 {
275 static GType profile_type = 0;
276 static GEnumValue *profile_types;
277 int n, i;
279 if (profile_type != 0)
280 return profile_type;
282 n = 0;
283 while (x264_profile_names[n] != NULL)
284 n++;
286 profile_types = g_new0 (GEnumValue, n + 2);
288 i = 0;
289 profile_types[i].value = i;
290 profile_types[i].value_name = "No profile";
291 profile_types[i].value_nick = "None";
292 for (i = 1; i <= n; i++) {
293 profile_types[i].value = i;
294 profile_types[i].value_name = x264_profile_names[i - 1];
295 profile_types[i].value_nick = x264_profile_names[i - 1];
296 }
298 profile_type = g_enum_register_static ("GstX264EncProfile", profile_types);
300 return profile_type;
301 }
303 #define GST_X264_ENC_SPEED_PRESET_TYPE (gst_x264_enc_speed_preset_get_type())
304 static GType
305 gst_x264_enc_speed_preset_get_type (void)
306 {
307 static GType speed_preset_type = 0;
308 static GEnumValue *speed_preset_types;
309 int n, i;
311 if (speed_preset_type != 0)
312 return speed_preset_type;
314 n = 0;
315 while (x264_preset_names[n] != NULL)
316 n++;
318 speed_preset_types = g_new0 (GEnumValue, n + 2);
320 speed_preset_types[0].value = 0;
321 speed_preset_types[0].value_name = "No preset";
322 speed_preset_types[0].value_nick = "None";
324 for (i = 1; i <= n; i++) {
325 speed_preset_types[i].value = i;
326 speed_preset_types[i].value_name = x264_preset_names[i - 1];
327 speed_preset_types[i].value_nick = x264_preset_names[i - 1];
328 }
330 speed_preset_type =
331 g_enum_register_static ("GstX264EncPreset", speed_preset_types);
333 return speed_preset_type;
334 }
336 static const GFlagsValue tune_types[] = {
337 {0x0, "No tuning", "none"},
338 {0x1, "Still image", "stillimage"},
339 {0x2, "Fast decode", "fastdecode"},
340 {0x4, "Zero latency", "zerolatency"},
341 {0, NULL, NULL},
342 };
344 #define GST_X264_ENC_TUNE_TYPE (gst_x264_enc_tune_get_type())
345 static GType
346 gst_x264_enc_tune_get_type (void)
347 {
348 static GType tune_type = 0;
350 if (!tune_type) {
351 tune_type = g_flags_register_static ("GstX264EncTune", tune_types);
352 }
353 return tune_type;
354 }
356 enum
357 {
358 GST_X264_ENC_TUNE_NONE,
359 GST_X264_ENC_TUNE_FILM,
360 GST_X264_ENC_TUNE_ANIMATION,
361 GST_X264_ENC_TUNE_GRAIN,
362 GST_X264_ENC_TUNE_PSNR,
363 GST_X264_ENC_TUNE_SSIM,
364 GST_X264_ENC_TUNE_LAST
365 };
367 static const GEnumValue psy_tune_types[] = {
368 {GST_X264_ENC_TUNE_NONE, "No tuning", "none"},
369 {GST_X264_ENC_TUNE_FILM, "Film", "film"},
370 {GST_X264_ENC_TUNE_ANIMATION, "Animation", "animation"},
371 {GST_X264_ENC_TUNE_GRAIN, "Grain", "grain"},
372 {GST_X264_ENC_TUNE_PSNR, "PSNR", "psnr"},
373 {GST_X264_ENC_TUNE_SSIM, "SSIM", "ssim"},
374 {0, NULL, NULL},
375 };
377 #define GST_X264_ENC_PSY_TUNE_TYPE (gst_x264_enc_psy_tune_get_type())
378 static GType
379 gst_x264_enc_psy_tune_get_type (void)
380 {
381 static GType psy_tune_type = 0;
383 if (!psy_tune_type) {
384 psy_tune_type =
385 g_enum_register_static ("GstX264EncPsyTune", psy_tune_types);
386 }
387 return psy_tune_type;
388 }
390 static void
391 gst_x264_enc_build_tunings_string (GstX264Enc * x264enc)
392 {
393 int i = 1;
395 if (x264enc->tunings && x264enc->tunings->len)
396 g_string_free (x264enc->tunings, TRUE);
398 if (x264enc->psy_tune) {
399 x264enc->tunings =
400 g_string_new (psy_tune_types[x264enc->psy_tune].value_nick);
401 } else {
402 x264enc->tunings = g_string_new (NULL);
403 }
405 while (tune_types[i].value_name) {
406 if (x264enc->tune & (1 << (i - 1)))
407 g_string_append_printf (x264enc->tunings, "%s%s",
408 x264enc->tunings->len ? "," : "", tune_types[i].value_nick);
409 i++;
410 }
412 if (x264enc->tunings->len)
413 GST_DEBUG_OBJECT (x264enc, "Constructed tunings string: %s",
414 x264enc->tunings->str);
415 }
417 #endif
420 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
421 GST_PAD_SINK,
422 GST_PAD_ALWAYS,
423 GST_STATIC_CAPS ("video/x-raw-yuv, "
424 "format = (fourcc) I420, "
425 "framerate = (fraction) [0, MAX], "
426 "width = (int) [ 16, MAX ], " "height = (int) [ 16, MAX ]")
427 );
429 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
430 GST_PAD_SRC,
431 GST_PAD_ALWAYS,
432 GST_STATIC_CAPS ("video/x-h264, "
433 "framerate = (fraction) [0/1, MAX], "
434 "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ], "
435 "stream-format = (string) { byte-stream, avc }, "
436 "alignment = (string) { au }")
437 );
439 static void gst_x264_enc_finalize (GObject * object);
440 static void gst_x264_enc_reset (GstX264Enc * encoder);
442 static gboolean gst_x264_enc_init_encoder (GstX264Enc * encoder);
443 static void gst_x264_enc_close_encoder (GstX264Enc * encoder);
445 static gboolean gst_x264_enc_sink_set_caps (GstPad * pad, GstCaps * caps);
446 static gboolean gst_x264_enc_sink_event (GstPad * pad, GstEvent * event);
447 static gboolean gst_x264_enc_src_event (GstPad * pad, GstEvent * event);
448 static GstFlowReturn gst_x264_enc_chain (GstPad * pad, GstBuffer * buf);
449 static void gst_x264_enc_flush_frames (GstX264Enc * encoder, gboolean send);
450 static GstFlowReturn gst_x264_enc_encode_frame (GstX264Enc * encoder,
451 x264_picture_t * pic_in, int *i_nal, gboolean send);
452 static GstStateChangeReturn gst_x264_enc_change_state (GstElement * element,
453 GstStateChange transition);
455 static void gst_x264_enc_set_property (GObject * object, guint prop_id,
456 const GValue * value, GParamSpec * pspec);
457 static void gst_x264_enc_get_property (GObject * object, guint prop_id,
458 GValue * value, GParamSpec * pspec);
460 static void
461 _do_init (GType object_type)
462 {
463 const GInterfaceInfo preset_interface_info = {
464 NULL, /* interface_init */
465 NULL, /* interface_finalize */
466 NULL /* interface_data */
467 };
469 g_type_add_interface_static (object_type, GST_TYPE_PRESET,
470 &preset_interface_info);
471 }
473 GST_BOILERPLATE_FULL (GstX264Enc, gst_x264_enc, GstElement, GST_TYPE_ELEMENT,
474 _do_init);
476 static void
477 gst_x264_enc_base_init (gpointer g_class)
478 {
479 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
481 gst_element_class_set_details_simple (element_class,
482 "x264enc", "Codec/Encoder/Video", "H264 Encoder",
483 "Josef Zlomek <josef.zlomek@itonis.tv>, "
484 "Mark Nauwelaerts <mnauw@users.sf.net>");
486 gst_element_class_add_pad_template (element_class,
487 gst_static_pad_template_get (&src_factory));
488 gst_element_class_add_pad_template (element_class,
489 gst_static_pad_template_get (&sink_factory));
490 }
492 /* don't forget to free the string after use */
493 static const gchar *
494 gst_x264_enc_build_partitions (gint analyse)
495 {
496 GString *string;
498 if (!analyse)
499 return NULL;
501 string = g_string_new (NULL);
502 if (analyse & X264_ANALYSE_I4x4)
503 g_string_append (string, "i4x4");
504 if (analyse & X264_ANALYSE_I8x8)
505 g_string_append (string, ",i8x8");
506 if (analyse & X264_ANALYSE_PSUB16x16)
507 g_string_append (string, ",p8x8");
508 if (analyse & X264_ANALYSE_PSUB8x8)
509 g_string_append (string, ",p4x4");
510 if (analyse & X264_ANALYSE_BSUB16x16)
511 g_string_append (string, ",b8x8");
513 return (const gchar *) g_string_free (string, FALSE);
514 }
516 static void
517 gst_x264_enc_class_init (GstX264EncClass * klass)
518 {
519 GObjectClass *gobject_class;
520 GstElementClass *gstelement_class;
522 const gchar *partitions = NULL;
524 x264enc_defaults = g_string_new ("");
526 gobject_class = (GObjectClass *) klass;
527 gstelement_class = (GstElementClass *) klass;
529 gobject_class->set_property = gst_x264_enc_set_property;
530 gobject_class->get_property = gst_x264_enc_get_property;
531 gobject_class->finalize = gst_x264_enc_finalize;
533 gstelement_class->change_state =
534 GST_DEBUG_FUNCPTR (gst_x264_enc_change_state);
536 /* options for which we don't use string equivalents */
537 g_object_class_install_property (gobject_class, ARG_PASS,
538 g_param_spec_enum ("pass", "Encoding pass/type",
539 "Encoding pass/type", GST_X264_ENC_PASS_TYPE,
540 ARG_PASS_DEFAULT, G_PARAM_READWRITE));
541 g_object_class_install_property (gobject_class, ARG_QUANTIZER,
542 g_param_spec_uint ("quantizer", "Constant Quantizer",
543 "Constant quantizer or quality to apply",
544 1, 50, ARG_QUANTIZER_DEFAULT, G_PARAM_READWRITE));
545 g_object_class_install_property (gobject_class, ARG_BITRATE,
546 g_param_spec_uint ("bitrate", "Bitrate", "Bitrate in kbit/sec", 1,
547 100 * 1024, ARG_BITRATE_DEFAULT, G_PARAM_READWRITE));
548 g_object_class_install_property (gobject_class, ARG_VBV_BUF_CAPACITY,
549 g_param_spec_uint ("vbv-buf-capacity", "VBV buffer capacity",
550 "Size of the VBV buffer in milliseconds",
551 300, 10000, ARG_VBV_BUF_CAPACITY_DEFAULT, G_PARAM_READWRITE));
553 #ifdef X264_PRESETS
554 g_object_class_install_property (gobject_class, ARG_SPEED_PRESET,
555 g_param_spec_enum ("speed-preset", "Speed/quality preset",
556 "Preset name for speed/quality tradeoff options (can affect decode "
557 "compatibility - impose restrictions separately for your target decoder)",
558 GST_X264_ENC_SPEED_PRESET_TYPE, ARG_SPEED_PRESET_DEFAULT,
559 G_PARAM_READWRITE));
560 g_object_class_install_property (gobject_class, ARG_PSY_TUNE,
561 g_param_spec_enum ("psy-tune", "Psychovisual tuning preset",
562 "Preset name for psychovisual tuning options",
563 GST_X264_ENC_PSY_TUNE_TYPE, ARG_PSY_TUNE_DEFAULT, G_PARAM_READWRITE));
564 g_object_class_install_property (gobject_class, ARG_TUNE,
565 g_param_spec_flags ("tune", "Content tuning preset",
566 "Preset name for non-psychovisual tuning options",
567 GST_X264_ENC_TUNE_TYPE, ARG_TUNE_DEFAULT, G_PARAM_READWRITE));
568 g_object_class_install_property (gobject_class, ARG_PROFILE,
569 g_param_spec_enum ("profile", "H.264 profile",
570 "Apply restrictions to meet H.264 Profile constraints. This will "
571 "override other properties if necessary.",
572 GST_X264_ENC_PROFILE_TYPE, ARG_PROFILE_DEFAULT, G_PARAM_READWRITE));
573 #endif /* X264_PRESETS */
574 g_object_class_install_property (gobject_class, ARG_OPTION_STRING,
575 g_param_spec_string ("option-string", "Option string",
576 "String of x264 options (overridden by element properties)",
577 ARG_OPTION_STRING_DEFAULT, G_PARAM_READWRITE));
579 /* options for which we _do_ use string equivalents */
580 g_object_class_install_property (gobject_class, ARG_THREADS,
581 g_param_spec_uint ("threads", "Threads",
582 "Number of threads used by the codec (0 for automatic)",
583 0, 4, ARG_THREADS_DEFAULT, G_PARAM_READWRITE));
584 /* NOTE: this first string append doesn't require the ':' delimiter but the
585 * rest do */
586 g_string_append_printf (x264enc_defaults, "threads=%d", ARG_THREADS_DEFAULT);
587 #ifdef X264_ENH_THREADING
588 g_object_class_install_property (gobject_class, ARG_SLICED_THREADS,
589 g_param_spec_boolean ("sliced-threads", "Sliced Threads",
590 "Low latency but lower efficiency threading",
591 ARG_SLICED_THREADS_DEFAULT, G_PARAM_READWRITE));
592 g_string_append_printf (x264enc_defaults, ":sliced-threads=%d",
593 ARG_SLICED_THREADS_DEFAULT);
594 g_object_class_install_property (gobject_class, ARG_SYNC_LOOKAHEAD,
595 g_param_spec_int ("sync-lookahead", "Sync Lookahead",
596 "Number of buffer frames for threaded lookahead (-1 for automatic)",
597 -1, 250, ARG_SYNC_LOOKAHEAD_DEFAULT, G_PARAM_READWRITE));
598 g_string_append_printf (x264enc_defaults, ":sync-lookahead=%d",
599 ARG_SYNC_LOOKAHEAD_DEFAULT);
600 #endif
601 g_object_class_install_property (gobject_class, ARG_STATS_FILE,
602 g_param_spec_string ("stats-file", "Stats File",
603 "Filename for multipass statistics (deprecated, use multipass-cache-file)",
604 ARG_STATS_FILE_DEFAULT, G_PARAM_READWRITE));
605 g_object_class_install_property (gobject_class, ARG_MULTIPASS_CACHE_FILE,
606 g_param_spec_string ("multipass-cache-file", "Multipass Cache File",
607 "Filename for multipass cache file",
608 ARG_MULTIPASS_CACHE_FILE_DEFAULT, G_PARAM_READWRITE));
609 g_string_append_printf (x264enc_defaults, ":stats=%s",
610 ARG_MULTIPASS_CACHE_FILE_DEFAULT);
611 g_object_class_install_property (gobject_class, ARG_BYTE_STREAM,
612 g_param_spec_boolean ("byte-stream", "Byte Stream",
613 "Generate byte stream format of NALU", ARG_BYTE_STREAM_DEFAULT,
614 G_PARAM_READWRITE));
615 g_string_append_printf (x264enc_defaults, ":annexb=%d",
616 ARG_BYTE_STREAM_DEFAULT);
617 #ifdef X264_INTRA_REFRESH
618 g_object_class_install_property (gobject_class, ARG_INTRA_REFRESH,
619 g_param_spec_boolean ("intra-refresh", "Intra Refresh",
620 "Use Periodic Intra Refresh instead of IDR frames",
621 ARG_INTRA_REFRESH_DEFAULT, G_PARAM_READWRITE));
622 g_string_append_printf (x264enc_defaults, ":intra-refresh=%d",
623 ARG_INTRA_REFRESH_DEFAULT);
624 #endif
625 g_object_class_install_property (gobject_class, ARG_ME,
626 g_param_spec_enum ("me", "Motion Estimation",
627 "Integer pixel motion estimation method", GST_X264_ENC_ME_TYPE,
628 ARG_ME_DEFAULT, G_PARAM_READWRITE));
629 g_string_append_printf (x264enc_defaults, ":me=%s",
630 x264_motion_est_names[ARG_ME_DEFAULT]);
631 g_object_class_install_property (gobject_class, ARG_SUBME,
632 g_param_spec_uint ("subme", "Subpixel Motion Estimation",
633 "Subpixel motion estimation and partition decision quality: 1=fast, 6=best",
634 1, 6, ARG_SUBME_DEFAULT, G_PARAM_READWRITE));
635 g_string_append_printf (x264enc_defaults, ":subme=%d", ARG_SUBME_DEFAULT);
636 g_object_class_install_property (gobject_class, ARG_ANALYSE,
637 g_param_spec_flags ("analyse", "Analyse", "Partitions to consider",
638 GST_X264_ENC_ANALYSE_TYPE, ARG_ANALYSE_DEFAULT, G_PARAM_READWRITE));
639 partitions = gst_x264_enc_build_partitions (ARG_ANALYSE_DEFAULT);
640 if (partitions) {
641 g_string_append_printf (x264enc_defaults, ":partitions=%s", partitions);
642 g_free ((gpointer) partitions);
643 }
644 g_object_class_install_property (gobject_class, ARG_DCT8x8,
645 g_param_spec_boolean ("dct8x8", "DCT8x8",
646 "Adaptive spatial transform size", ARG_DCT8x8_DEFAULT,
647 G_PARAM_READWRITE));
648 g_string_append_printf (x264enc_defaults, ":8x8dct=%d", ARG_DCT8x8_DEFAULT);
649 g_object_class_install_property (gobject_class, ARG_REF,
650 g_param_spec_uint ("ref", "Reference Frames",
651 "Number of reference frames",
652 1, 12, ARG_REF_DEFAULT, G_PARAM_READWRITE));
653 g_string_append_printf (x264enc_defaults, ":ref=%d", ARG_REF_DEFAULT);
654 g_object_class_install_property (gobject_class, ARG_BFRAMES,
655 g_param_spec_uint ("bframes", "B-Frames",
656 "Number of B-frames between I and P",
657 0, 4, ARG_BFRAMES_DEFAULT, G_PARAM_READWRITE));
658 g_string_append_printf (x264enc_defaults, ":bframes=%d", ARG_BFRAMES_DEFAULT);
659 g_object_class_install_property (gobject_class, ARG_B_ADAPT,
660 g_param_spec_boolean ("b-adapt", "B-Adapt",
661 "Automatically decide how many B-frames to use",
662 ARG_B_ADAPT_DEFAULT, G_PARAM_READWRITE));
663 g_string_append_printf (x264enc_defaults, ":b-adapt=%d", ARG_B_ADAPT_DEFAULT);
664 g_object_class_install_property (gobject_class, ARG_B_PYRAMID,
665 g_param_spec_boolean ("b-pyramid", "B-Pyramid",
666 "Keep some B-frames as references", ARG_B_PYRAMID_DEFAULT,
667 G_PARAM_READWRITE));
668 g_string_append_printf (x264enc_defaults, ":b-pyramid=%d",
669 ARG_B_PYRAMID_DEFAULT);
670 g_object_class_install_property (gobject_class, ARG_WEIGHTB,
671 g_param_spec_boolean ("weightb", "Weighted B-Frames",
672 "Weighted prediction for B-frames", ARG_WEIGHTB_DEFAULT,
673 G_PARAM_READWRITE));
674 g_string_append_printf (x264enc_defaults, ":weightb=%d", ARG_WEIGHTB_DEFAULT);
675 g_object_class_install_property (gobject_class, ARG_SPS_ID,
676 g_param_spec_uint ("sps-id", "SPS ID",
677 "SPS and PPS ID number",
678 0, 31, ARG_SPS_ID_DEFAULT, G_PARAM_READWRITE));
679 g_string_append_printf (x264enc_defaults, ":sps-id=%d", ARG_SPS_ID_DEFAULT);
680 g_object_class_install_property (gobject_class, ARG_AU_NALU,
681 g_param_spec_boolean ("aud", "AUD",
682 "Use AU (Access Unit) delimiter", ARG_AU_NALU_DEFAULT,
683 G_PARAM_READWRITE));
684 g_string_append_printf (x264enc_defaults, ":aud=%d", ARG_AU_NALU_DEFAULT);
685 g_object_class_install_property (gobject_class, ARG_TRELLIS,
686 g_param_spec_boolean ("trellis", "Trellis quantization",
687 "Enable trellis searched quantization", ARG_TRELLIS_DEFAULT,
688 G_PARAM_READWRITE));
689 g_string_append_printf (x264enc_defaults, ":trellis=%d", ARG_TRELLIS_DEFAULT);
690 g_object_class_install_property (gobject_class, ARG_KEYINT_MAX,
691 g_param_spec_uint ("key-int-max", "Key-frame maximal interval",
692 "Maximal distance between two key-frames (0 for automatic)",
693 0, G_MAXINT, ARG_KEYINT_MAX_DEFAULT, G_PARAM_READWRITE));
694 g_string_append_printf (x264enc_defaults, ":keyint=%d",
695 ARG_KEYINT_MAX_DEFAULT);
696 g_object_class_install_property (gobject_class, ARG_CABAC,
697 g_param_spec_boolean ("cabac", "Use CABAC", "Enable CABAC entropy coding",
698 ARG_CABAC_DEFAULT, G_PARAM_READWRITE));
699 g_string_append_printf (x264enc_defaults, ":cabac=%d", ARG_CABAC_DEFAULT);
700 g_object_class_install_property (gobject_class, ARG_QP_MIN,
701 g_param_spec_uint ("qp-min", "Minimum Quantizer",
702 "Minimum quantizer", 1, 51, ARG_QP_MIN_DEFAULT, G_PARAM_READWRITE));
703 g_string_append_printf (x264enc_defaults, ":qpmin=%d", ARG_QP_MIN_DEFAULT);
704 g_object_class_install_property (gobject_class, ARG_QP_MAX,
705 g_param_spec_uint ("qp-max", "Maximum Quantizer",
706 "Maximum quantizer", 1, 51, ARG_QP_MAX_DEFAULT, G_PARAM_READWRITE));
707 g_string_append_printf (x264enc_defaults, ":qpmax=%d", ARG_QP_MAX_DEFAULT);
708 g_object_class_install_property (gobject_class, ARG_QP_STEP,
709 g_param_spec_uint ("qp-step", "Maximum Quantizer Difference",
710 "Maximum quantizer difference between frames",
711 1, 50, ARG_QP_STEP_DEFAULT, G_PARAM_READWRITE));
712 g_string_append_printf (x264enc_defaults, ":qpstep=%d", ARG_QP_STEP_DEFAULT);
713 g_object_class_install_property (gobject_class, ARG_IP_FACTOR,
714 g_param_spec_float ("ip-factor", "IP-Factor",
715 "Quantizer factor between I- and P-frames",
716 0, 2, ARG_IP_FACTOR_DEFAULT, G_PARAM_READWRITE));
717 g_string_append_printf (x264enc_defaults, ":ip-factor=%f",
718 ARG_IP_FACTOR_DEFAULT);
719 g_object_class_install_property (gobject_class, ARG_PB_FACTOR,
720 g_param_spec_float ("pb-factor", "PB-Factor",
721 "Quantizer factor between P- and B-frames", 0, 2,
722 ARG_PB_FACTOR_DEFAULT, G_PARAM_READWRITE));
723 g_string_append_printf (x264enc_defaults, ":pb-factor=%f",
724 ARG_PB_FACTOR_DEFAULT);
725 #ifdef X264_MB_RC
726 g_object_class_install_property (gobject_class, ARG_RC_MB_TREE,
727 g_param_spec_boolean ("mb-tree", "Macroblock Tree",
728 "Macroblock-Tree ratecontrol",
729 ARG_RC_MB_TREE_DEFAULT, G_PARAM_READWRITE));
730 g_string_append_printf (x264enc_defaults, ":mbtree=%d",
731 ARG_RC_MB_TREE_DEFAULT);
732 g_object_class_install_property (gobject_class, ARG_RC_LOOKAHEAD,
733 g_param_spec_int ("rc-lookahead", "Rate Control Lookahead",
734 "Number of frames for frametype lookahead", 0, 250,
735 ARG_RC_LOOKAHEAD_DEFAULT, G_PARAM_READWRITE));
736 g_string_append_printf (x264enc_defaults, ":rc-lookahead=%d",
737 ARG_RC_LOOKAHEAD_DEFAULT);
738 #endif
739 g_object_class_install_property (gobject_class, ARG_NR,
740 g_param_spec_uint ("noise-reduction", "Noise Reduction",
741 "Noise reduction strength",
742 0, 100000, ARG_NR_DEFAULT, G_PARAM_READWRITE));
743 g_string_append_printf (x264enc_defaults, ":nr=%d", ARG_NR_DEFAULT);
744 g_object_class_install_property (gobject_class, ARG_INTERLACED,
745 g_param_spec_boolean ("interlaced", "Interlaced",
746 "Interlaced material", ARG_INTERLACED_DEFAULT, G_PARAM_READWRITE));
747 g_string_append_printf (x264enc_defaults, ":interlaced=%d",
748 ARG_INTERLACED_DEFAULT);
750 /* append deblock parameters */
751 g_string_append_printf (x264enc_defaults, ":deblock=0,0");
752 /* append weighted prediction parameter */
753 g_string_append_printf (x264enc_defaults, ":weightp=0");
754 }
756 static void
757 gst_x264_enc_log_callback (gpointer private, gint level, const char *format,
758 va_list args)
759 {
760 #ifndef GST_DISABLE_GST_DEBUG
761 GstDebugLevel gst_level;
762 GObject *object = (GObject *) private;
764 switch (level) {
765 case X264_LOG_NONE:
766 gst_level = GST_LEVEL_NONE;
767 break;
768 case X264_LOG_ERROR:
769 gst_level = GST_LEVEL_ERROR;
770 break;
771 case X264_LOG_WARNING:
772 gst_level = GST_LEVEL_WARNING;
773 break;
774 case X264_LOG_INFO:
775 gst_level = GST_LEVEL_INFO;
776 break;
777 default:
778 /* push x264enc debug down to our lower levels to avoid some clutter */
779 gst_level = GST_LEVEL_LOG;
780 break;
781 }
783 gst_debug_log_valist (x264_enc_debug, gst_level, "", "", 0, object, format,
784 args);
785 #endif /* GST_DISABLE_GST_DEBUG */
786 }
788 /* initialize the new element
789 * instantiate pads and add them to element
790 * set functions
791 * initialize structure
792 */
793 static void
794 gst_x264_enc_init (GstX264Enc * encoder, GstX264EncClass * klass)
795 {
796 encoder->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
797 gst_pad_set_setcaps_function (encoder->sinkpad,
798 GST_DEBUG_FUNCPTR (gst_x264_enc_sink_set_caps));
799 gst_pad_set_event_function (encoder->sinkpad,
800 GST_DEBUG_FUNCPTR (gst_x264_enc_sink_event));
801 gst_pad_set_chain_function (encoder->sinkpad,
802 GST_DEBUG_FUNCPTR (gst_x264_enc_chain));
803 gst_element_add_pad (GST_ELEMENT (encoder), encoder->sinkpad);
805 encoder->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
806 gst_pad_use_fixed_caps (encoder->srcpad);
807 gst_element_add_pad (GST_ELEMENT (encoder), encoder->srcpad);
809 gst_pad_set_event_function (encoder->srcpad,
810 GST_DEBUG_FUNCPTR (gst_x264_enc_src_event));
812 /* properties */
813 encoder->threads = ARG_THREADS_DEFAULT;
814 encoder->sliced_threads = ARG_SLICED_THREADS_DEFAULT;
815 encoder->sync_lookahead = ARG_SYNC_LOOKAHEAD_DEFAULT;
816 encoder->pass = ARG_PASS_DEFAULT;
817 encoder->quantizer = ARG_QUANTIZER_DEFAULT;
818 encoder->mp_cache_file = g_strdup (ARG_MULTIPASS_CACHE_FILE_DEFAULT);
819 encoder->byte_stream = ARG_BYTE_STREAM_DEFAULT;
820 encoder->bitrate = ARG_BITRATE_DEFAULT;
821 encoder->intra_refresh = ARG_INTRA_REFRESH_DEFAULT;
822 encoder->vbv_buf_capacity = ARG_VBV_BUF_CAPACITY_DEFAULT;
823 encoder->me = ARG_ME_DEFAULT;
824 encoder->subme = ARG_SUBME_DEFAULT;
825 encoder->analyse = ARG_ANALYSE_DEFAULT;
826 encoder->dct8x8 = ARG_DCT8x8_DEFAULT;
827 encoder->ref = ARG_REF_DEFAULT;
828 encoder->bframes = ARG_BFRAMES_DEFAULT;
829 encoder->b_adapt = ARG_B_ADAPT_DEFAULT;
830 encoder->b_pyramid = ARG_B_PYRAMID_DEFAULT;
831 encoder->weightb = ARG_WEIGHTB_DEFAULT;
832 encoder->sps_id = ARG_SPS_ID_DEFAULT;
833 encoder->au_nalu = ARG_AU_NALU_DEFAULT;
834 encoder->trellis = ARG_TRELLIS_DEFAULT;
835 encoder->keyint_max = ARG_KEYINT_MAX_DEFAULT;
836 encoder->cabac = ARG_CABAC_DEFAULT;
837 encoder->qp_min = ARG_QP_MIN_DEFAULT;
838 encoder->qp_max = ARG_QP_MAX_DEFAULT;
839 encoder->qp_step = ARG_QP_STEP_DEFAULT;
840 encoder->ip_factor = ARG_IP_FACTOR_DEFAULT;
841 encoder->pb_factor = ARG_PB_FACTOR_DEFAULT;
842 encoder->mb_tree = ARG_RC_MB_TREE_DEFAULT;
843 encoder->rc_lookahead = ARG_RC_LOOKAHEAD_DEFAULT;
844 encoder->noise_reduction = ARG_NR_DEFAULT;
845 encoder->interlaced = ARG_INTERLACED_DEFAULT;
846 encoder->profile = ARG_PROFILE_DEFAULT;
847 encoder->option_string = g_string_new (NULL);
848 encoder->option_string_prop = g_string_new (ARG_OPTION_STRING_DEFAULT);
849 encoder->speed_preset = ARG_SPEED_PRESET_DEFAULT;
850 encoder->psy_tune = ARG_PSY_TUNE_DEFAULT;
851 encoder->tune = ARG_TUNE_DEFAULT;
853 /* resources */
854 encoder->delay = g_queue_new ();
855 encoder->buffer_size = 100000;
856 encoder->buffer = g_malloc (encoder->buffer_size);
858 x264_param_default (&encoder->x264param);
860 /* log callback setup; part of parameters */
861 encoder->x264param.pf_log = gst_x264_enc_log_callback;
862 encoder->x264param.p_log_private = encoder;
863 encoder->x264param.i_log_level = X264_LOG_DEBUG;
865 gst_x264_enc_reset (encoder);
866 }
868 static void
869 gst_x264_enc_reset (GstX264Enc * encoder)
870 {
871 encoder->x264enc = NULL;
872 encoder->width = 0;
873 encoder->height = 0;
875 GST_OBJECT_LOCK (encoder);
876 encoder->i_type = X264_TYPE_AUTO;
877 if (encoder->forcekeyunit_event)
878 gst_event_unref (encoder->forcekeyunit_event);
879 encoder->forcekeyunit_event = NULL;
880 GST_OBJECT_UNLOCK (encoder);
881 }
883 static void
884 gst_x264_enc_finalize (GObject * object)
885 {
886 GstX264Enc *encoder = GST_X264_ENC (object);
888 #define FREE_STRING(ptr) \
889 if (ptr) \
890 ptr = (GString *)g_string_free (ptr, TRUE);
892 FREE_STRING (encoder->tunings);
893 FREE_STRING (encoder->option_string);
894 FREE_STRING (encoder->option_string_prop);
896 #undef FREE_STRING
898 g_free (encoder->mp_cache_file);
899 encoder->mp_cache_file = NULL;
900 g_free (encoder->buffer);
901 encoder->buffer = NULL;
902 g_queue_free (encoder->delay);
903 encoder->delay = NULL;
905 gst_x264_enc_close_encoder (encoder);
907 G_OBJECT_CLASS (parent_class)->finalize (object);
908 }
910 /*
911 * gst_x264_enc_parse_options
912 * @encoder: Encoder to which options are assigned
913 * @str: Option string
914 *
915 * Parse option string and assign to x264 parameters
916 *
917 */
918 static gboolean
919 gst_x264_enc_parse_options (GstX264Enc * encoder, const gchar * str)
920 {
921 GStrv kvpairs;
922 guint npairs, i;
923 gint parse_result = 0, ret = 0;
924 gchar *options = (gchar *) str;
926 while (*options == ':')
927 options++;
929 kvpairs = g_strsplit (options, ":", 0);
930 npairs = g_strv_length (kvpairs);
932 for (i = 0; i < npairs; i++) {
933 GStrv key_val = g_strsplit (kvpairs[i], "=", 2);
935 parse_result =
936 x264_param_parse (&encoder->x264param, key_val[0], key_val[1]);
938 if (parse_result == X264_PARAM_BAD_NAME) {
939 GST_ERROR_OBJECT (encoder, "Bad name for option %s=%s",
940 key_val[0] ? key_val[0] : "", key_val[1] ? key_val[1] : "");
941 }
942 if (parse_result == X264_PARAM_BAD_VALUE) {
943 GST_ERROR_OBJECT (encoder,
944 "Bad value for option %s=%s (Note: a NULL value for a non-boolean triggers this)",
945 key_val[0] ? key_val[0] : "", key_val[1] ? key_val[1] : "");
946 }
948 g_strfreev (key_val);
950 if (parse_result)
951 ret++;
952 }
954 g_strfreev (kvpairs);
955 return !ret;
956 }
958 /*
959 * gst_x264_enc_init_encoder
960 * @encoder: Encoder which should be initialized.
961 *
962 * Initialize x264 encoder.
963 *
964 */
965 static gboolean
966 gst_x264_enc_init_encoder (GstX264Enc * encoder)
967 {
968 guint pass = 0;
970 /* make sure that the encoder is closed */
971 gst_x264_enc_close_encoder (encoder);
973 GST_OBJECT_LOCK (encoder);
975 #ifdef X264_PRESETS
976 gst_x264_enc_build_tunings_string (encoder);
978 /* set x264 parameters and use preset/tuning if present */
979 GST_DEBUG_OBJECT (encoder, "Applying defaults with preset %s, tunings %s",
980 encoder->speed_preset ? x264_preset_names[encoder->speed_preset - 1] : "",
981 encoder->tunings && encoder->tunings->len ? encoder->tunings->str : "");
982 x264_param_default_preset (&encoder->x264param,
983 encoder->speed_preset ? x264_preset_names[encoder->speed_preset -
984 1] : NULL, encoder->tunings
985 && encoder->tunings->len ? encoder->tunings->str : NULL);
987 /* log callback setup; part of parameters
988 * this needs to be done again after every *param_default* () call */
989 encoder->x264param.pf_log = gst_x264_enc_log_callback;
990 encoder->x264param.p_log_private = encoder;
991 encoder->x264param.i_log_level = X264_LOG_DEBUG;
993 /* if no preset nor tuning, use property defaults */
994 if (!encoder->speed_preset && !encoder->tunings->len) {
995 #endif /* X264_PRESETS */
996 GST_DEBUG_OBJECT (encoder, "Applying x264enc_defaults");
997 if (x264enc_defaults->len
998 && gst_x264_enc_parse_options (encoder,
999 x264enc_defaults->str) == FALSE) {
1000 GST_DEBUG_OBJECT (encoder,
1001 "x264enc_defaults string contains errors. This is a bug.");
1002 goto unlock_and_return;
1003 }
1004 #ifdef X264_PRESETS
1005 } else {
1006 /* When using presets we need to respect the default output format */
1007 encoder->x264param.b_aud = encoder->au_nalu;
1008 encoder->x264param.b_annexb = encoder->byte_stream;
1009 }
1010 #endif /* X264_PRESETS */
1012 #if X264_BUILD >= 81
1013 /* setup appropriate timebase for gstreamer */
1014 encoder->x264param.i_timebase_num = 1;
1015 encoder->x264param.i_timebase_den = 1000000000;
1016 #endif
1018 /* apply option-string property */
1019 if (encoder->option_string_prop && encoder->option_string_prop->len) {
1020 GST_DEBUG_OBJECT (encoder, "Applying option-string: %s",
1021 encoder->option_string_prop->str);
1022 if (gst_x264_enc_parse_options (encoder,
1023 encoder->option_string_prop->str) == FALSE) {
1024 GST_DEBUG_OBJECT (encoder, "Your option-string contains errors.");
1025 goto unlock_and_return;
1026 }
1027 }
1028 /* apply user-set options */
1029 if (encoder->option_string && encoder->option_string->len) {
1030 GST_DEBUG_OBJECT (encoder, "Applying user-set options: %s",
1031 encoder->option_string->str);
1032 if (gst_x264_enc_parse_options (encoder,
1033 encoder->option_string->str) == FALSE) {
1034 GST_DEBUG_OBJECT (encoder,
1035 "Failed to parse internal option string. This could be due to use of an "
1036 "old libx264 version.", encoder->option_string->str);
1037 }
1038 }
1040 /* set up encoder parameters */
1041 encoder->x264param.i_fps_num = encoder->fps_num;
1042 encoder->x264param.i_fps_den = encoder->fps_den;
1043 encoder->x264param.i_width = encoder->width;
1044 encoder->x264param.i_height = encoder->height;
1045 if (encoder->par_den > 0) {
1046 encoder->x264param.vui.i_sar_width = encoder->par_num;
1047 encoder->x264param.vui.i_sar_height = encoder->par_den;
1048 }
1049 /* FIXME 0.11 : 2s default keyframe interval seems excessive
1050 * (10s is x264 default) */
1051 encoder->x264param.i_keyint_max = encoder->keyint_max ? encoder->keyint_max :
1052 (2 * encoder->fps_num / encoder->fps_den);
1054 if ((((encoder->height == 576) && ((encoder->width == 720)
1055 || (encoder->width == 704) || (encoder->width == 352)))
1056 || ((encoder->height == 288) && (encoder->width == 352)))
1057 && (encoder->fps_den == 1) && (encoder->fps_num == 25)) {
1058 encoder->x264param.vui.i_vidformat = 1; /* PAL */
1059 } else if ((((encoder->height == 480) && ((encoder->width == 720)
1060 || (encoder->width == 704) || (encoder->width == 352)))
1061 || ((encoder->height == 240) && (encoder->width == 352)))
1062 && (encoder->fps_den == 1001) && ((encoder->fps_num == 30000)
1063 || (encoder->fps_num == 24000))) {
1064 encoder->x264param.vui.i_vidformat = 2; /* NTSC */
1065 } else
1066 encoder->x264param.vui.i_vidformat = 5; /* unspecified */
1068 encoder->x264param.analyse.b_psnr = 0;
1070 switch (encoder->pass) {
1071 case GST_X264_ENC_PASS_QUANT:
1072 encoder->x264param.rc.i_rc_method = X264_RC_CQP;
1073 encoder->x264param.rc.i_qp_constant = encoder->quantizer;
1074 break;
1075 case GST_X264_ENC_PASS_QUAL:
1076 encoder->x264param.rc.i_rc_method = X264_RC_CRF;
1077 encoder->x264param.rc.f_rf_constant = encoder->quantizer;
1078 break;
1079 case GST_X264_ENC_PASS_CBR:
1080 case GST_X264_ENC_PASS_PASS1:
1081 case GST_X264_ENC_PASS_PASS2:
1082 case GST_X264_ENC_PASS_PASS3:
1083 default:
1084 encoder->x264param.rc.i_rc_method = X264_RC_ABR;
1085 encoder->x264param.rc.i_bitrate = encoder->bitrate;
1086 encoder->x264param.rc.i_vbv_max_bitrate = encoder->bitrate;
1087 encoder->x264param.rc.i_vbv_buffer_size
1088 = encoder->x264param.rc.i_vbv_max_bitrate
1089 * encoder->vbv_buf_capacity / 1000;
1090 pass = encoder->pass & 0xF;
1091 break;
1092 }
1094 switch (pass) {
1095 case 0:
1096 encoder->x264param.rc.b_stat_read = 0;
1097 encoder->x264param.rc.b_stat_write = 0;
1098 break;
1099 case 1:
1100 encoder->x264param.rc.b_stat_read = 0;
1101 encoder->x264param.rc.b_stat_write = 1;
1102 #ifdef X264_PRESETS
1103 x264_param_apply_fastfirstpass (&encoder->x264param);
1104 #else
1105 encoder->x264param.i_frame_reference = 1;
1106 encoder->x264param.analyse.b_transform_8x8 = 0;
1107 encoder->x264param.analyse.inter = 0;
1108 encoder->x264param.analyse.i_me_method = X264_ME_DIA;
1109 encoder->x264param.analyse.i_subpel_refine =
1110 MIN (2, encoder->x264param.analyse.i_subpel_refine);
1111 encoder->x264param.analyse.i_trellis = 0;
1112 encoder->x264param.analyse.b_fast_pskip = 1;
1113 #endif /* X264_PRESETS */
1114 break;
1115 case 2:
1116 encoder->x264param.rc.b_stat_read = 1;
1117 encoder->x264param.rc.b_stat_write = 0;
1118 break;
1119 case 3:
1120 encoder->x264param.rc.b_stat_read = 1;
1121 encoder->x264param.rc.b_stat_write = 1;
1122 break;
1123 }
1125 #ifdef X264_PRESETS
1126 if (encoder->profile
1127 && x264_param_apply_profile (&encoder->x264param,
1128 x264_profile_names[encoder->profile - 1])) {
1129 GST_WARNING_OBJECT (encoder, "Bad profile name: %s",
1130 x264_profile_names[encoder->profile - 1]);
1131 }
1132 #endif /* X264_PRESETS */
1134 GST_OBJECT_UNLOCK (encoder);
1136 encoder->x264enc = x264_encoder_open (&encoder->x264param);
1137 if (!encoder->x264enc) {
1138 GST_ELEMENT_ERROR (encoder, STREAM, ENCODE,
1139 ("Can not initialize x264 encoder."), (NULL));
1140 return FALSE;
1141 }
1143 return TRUE;
1145 unlock_and_return:
1146 GST_OBJECT_UNLOCK (encoder);
1147 return FALSE;
1148 }
1150 /* gst_x264_enc_close_encoder
1151 * @encoder: Encoder which should close.
1152 *
1153 * Close x264 encoder.
1154 */
1155 static void
1156 gst_x264_enc_close_encoder (GstX264Enc * encoder)
1157 {
1158 if (encoder->x264enc != NULL) {
1159 x264_encoder_close (encoder->x264enc);
1160 encoder->x264enc = NULL;
1161 }
1162 }
1164 /*
1165 * Returns: Buffer with the stream headers.
1166 */
1167 static GstBuffer *
1168 gst_x264_enc_header_buf (GstX264Enc * encoder)
1169 {
1170 GstBuffer *buf;
1171 x264_nal_t *nal;
1172 int i_nal;
1173 int header_return;
1174 int i_size;
1175 int nal_size;
1176 #ifndef X264_ENC_NALS
1177 int i_data;
1178 #endif
1179 guint8 *buffer, *sps;
1180 gulong buffer_size;
1181 gint sei_ni = 2, sps_ni = 0, pps_ni = 1;
1183 if (G_UNLIKELY (encoder->x264enc == NULL))
1184 return NULL;
1186 /* Create avcC header. */
1188 header_return = x264_encoder_headers (encoder->x264enc, &nal, &i_nal);
1189 if (header_return < 0) {
1190 GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x264 header failed."),
1191 ("x264_encoder_headers return code=%d", header_return));
1192 return NULL;
1193 }
1195 /* old x264 returns SEI, SPS and PPS, newer one has SEI last */
1196 if (i_nal == 3 && nal[sps_ni].i_type != 7) {
1197 sei_ni = 0;
1198 sps_ni = 1;
1199 pps_ni = 2;
1200 }
1202 /* x264 is expected to return an SEI (some identification info),
1203 * and SPS and PPS */
1204 if (i_nal != 3 || nal[sps_ni].i_type != 7 || nal[pps_ni].i_type != 8 ||
1205 nal[sps_ni].i_payload < 4 || nal[pps_ni].i_payload < 1) {
1206 GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, (NULL),
1207 ("Unexpected x264 header."));
1208 return NULL;
1209 }
1211 GST_MEMDUMP ("SEI", nal[sei_ni].p_payload, nal[sei_ni].i_payload);
1212 GST_MEMDUMP ("SPS", nal[sps_ni].p_payload, nal[sps_ni].i_payload);
1213 GST_MEMDUMP ("PPS", nal[pps_ni].p_payload, nal[pps_ni].i_payload);
1215 /* nal payloads with emulation_prevention_three_byte, and some header data */
1216 buffer_size = (nal[sps_ni].i_payload + nal[pps_ni].i_payload) * 4 + 100;
1217 buffer = g_malloc (buffer_size);
1219 /* old style API: nal's are not encapsulated, and have no sync/size prefix,
1220 * new style API: nal's are encapsulated, and have 4-byte size prefix */
1221 #ifndef X264_ENC_NALS
1222 sps = nal[sps_ni].p_payload;
1223 #else
1224 sps = nal[sps_ni].p_payload + 4;
1225 /* skip NAL unit type */
1226 sps++;
1227 #endif
1229 buffer[0] = 1; /* AVC Decoder Configuration Record ver. 1 */
1230 buffer[1] = sps[0]; /* profile_idc */
1231 buffer[2] = sps[1]; /* profile_compability */
1232 buffer[3] = sps[2]; /* level_idc */
1233 buffer[4] = 0xfc | (4 - 1); /* nal_length_size_minus1 */
1235 i_size = 5;
1237 buffer[i_size++] = 0xe0 | 1; /* number of SPSs */
1239 #ifndef X264_ENC_NALS
1240 i_data = buffer_size - i_size - 2;
1241 nal_size = x264_nal_encode (buffer + i_size + 2, &i_data, 0, &nal[sps_ni]);
1242 #else
1243 nal_size = nal[sps_ni].i_payload - 4;
1244 memcpy (buffer + i_size + 2, nal[sps_ni].p_payload + 4, nal_size);
1245 #endif
1246 GST_WRITE_UINT16_BE (buffer + i_size, nal_size);
1247 i_size += nal_size + 2;
1249 buffer[i_size++] = 1; /* number of PPSs */
1251 #ifndef X264_ENC_NALS
1252 i_data = buffer_size - i_size - 2;
1253 nal_size = x264_nal_encode (buffer + i_size + 2, &i_data, 0, &nal[pps_ni]);
1254 #else
1255 nal_size = nal[pps_ni].i_payload - 4;
1256 memcpy (buffer + i_size + 2, nal[pps_ni].p_payload + 4, nal_size);
1257 #endif
1258 GST_WRITE_UINT16_BE (buffer + i_size, nal_size);
1259 i_size += nal_size + 2;
1261 buf = gst_buffer_new_and_alloc (i_size);
1262 memcpy (GST_BUFFER_DATA (buf), buffer, i_size);
1263 g_free (buffer);
1265 GST_MEMDUMP ("header", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
1267 return buf;
1268 }
1270 /* gst_x264_enc_set_src_caps
1271 * Returns: TRUE on success.
1272 */
1273 static gboolean
1274 gst_x264_enc_set_src_caps (GstX264Enc * encoder, GstPad * pad, GstCaps * caps)
1275 {
1276 GstBuffer *buf;
1277 GstCaps *outcaps;
1278 GstStructure *structure;
1279 gboolean res;
1281 outcaps = gst_caps_new_simple ("video/x-h264",
1282 "width", G_TYPE_INT, encoder->width,
1283 "height", G_TYPE_INT, encoder->height,
1284 "framerate", GST_TYPE_FRACTION, encoder->fps_num, encoder->fps_den,
1285 "pixel-aspect-ratio", GST_TYPE_FRACTION, encoder->par_num,
1286 encoder->par_den, NULL);
1288 structure = gst_caps_get_structure (outcaps, 0);
1290 if (!encoder->byte_stream) {
1291 buf = gst_x264_enc_header_buf (encoder);
1292 if (buf != NULL) {
1293 gst_caps_set_simple (outcaps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
1294 gst_buffer_unref (buf);
1295 }
1296 gst_structure_set (structure, "stream-format", G_TYPE_STRING, "avc", NULL);
1297 } else {
1298 gst_structure_set (structure, "stream-format", G_TYPE_STRING, "byte-stream",
1299 NULL);
1300 }
1301 gst_structure_set (structure, "alignment", G_TYPE_STRING, "au", NULL);
1303 res = gst_pad_set_caps (pad, outcaps);
1304 gst_caps_unref (outcaps);
1306 return res;
1307 }
1309 static gboolean
1310 gst_x264_enc_sink_set_caps (GstPad * pad, GstCaps * caps)
1311 {
1312 GstX264Enc *encoder = GST_X264_ENC (GST_OBJECT_PARENT (pad));
1313 gint width, height;
1314 gint fps_num, fps_den;
1315 gint par_num, par_den;
1316 gint i;
1318 /* get info from caps */
1319 /* only I420 supported for now; so apparently claims x264enc ? */
1320 if (!gst_video_format_parse_caps (caps, &encoder->format, &width, &height) ||
1321 encoder->format != GST_VIDEO_FORMAT_I420)
1322 return FALSE;
1323 if (!gst_video_parse_caps_framerate (caps, &fps_num, &fps_den))
1324 return FALSE;
1325 if (!gst_video_parse_caps_pixel_aspect_ratio (caps, &par_num, &par_den)) {
1326 par_num = 1;
1327 par_den = 1;
1328 }
1330 /* If the encoder is initialized, do not
1331 reinitialize it again if not necessary */
1332 if (encoder->x264enc) {
1333 if (width == encoder->width && height == encoder->height
1334 && fps_num == encoder->fps_num && fps_den == encoder->fps_den
1335 && par_num == encoder->par_num && par_den == encoder->par_den)
1336 return TRUE;
1338 /* clear out pending frames */
1339 gst_x264_enc_flush_frames (encoder, TRUE);
1341 encoder->sps_id++;
1342 }
1344 /* store input description */
1345 encoder->width = width;
1346 encoder->height = height;
1347 encoder->fps_num = fps_num;
1348 encoder->fps_den = fps_den;
1349 encoder->par_num = par_num;
1350 encoder->par_den = par_den;
1352 /* prepare a cached image description */
1353 encoder->image_size = gst_video_format_get_size (encoder->format, width,
1354 height);
1355 for (i = 0; i < 3; ++i) {
1356 /* only offsets now, is shifted later */
1357 encoder->offset[i] = gst_video_format_get_component_offset (encoder->format,
1358 i, width, height);
1359 encoder->stride[i] = gst_video_format_get_row_stride (encoder->format,
1360 i, width);
1361 }
1363 if (!gst_x264_enc_init_encoder (encoder))
1364 return FALSE;
1366 if (!gst_x264_enc_set_src_caps (encoder, encoder->srcpad, caps)) {
1367 gst_x264_enc_close_encoder (encoder);
1368 return FALSE;
1369 }
1371 return TRUE;
1372 }
1374 static gboolean
1375 gst_x264_enc_src_event (GstPad * pad, GstEvent * event)
1376 {
1377 gboolean ret = TRUE;
1378 GstX264Enc *encoder;
1379 gboolean forward = TRUE;
1381 encoder = GST_X264_ENC (gst_pad_get_parent (pad));
1383 switch (GST_EVENT_TYPE (event)) {
1384 case GST_EVENT_CUSTOM_UPSTREAM:{
1385 const GstStructure *s;
1386 s = gst_event_get_structure (event);
1387 if (gst_structure_has_name (s, "GstForceKeyUnit")) {
1388 /* Set I frame request */
1389 GST_OBJECT_LOCK (encoder);
1390 encoder->i_type = X264_TYPE_I;
1391 encoder->forcekeyunit_event = gst_event_copy (event);
1392 GST_EVENT_TYPE (encoder->forcekeyunit_event) =
1393 GST_EVENT_CUSTOM_DOWNSTREAM;
1394 GST_OBJECT_UNLOCK (encoder);
1395 forward = FALSE;
1396 gst_event_unref (event);
1397 }
1398 break;
1399 }
1400 default:
1401 break;
1402 }
1404 if (forward)
1405 ret = gst_pad_push_event (encoder->sinkpad, event);
1407 gst_object_unref (encoder);
1408 return ret;
1409 }
1411 static gboolean
1412 gst_x264_enc_sink_event (GstPad * pad, GstEvent * event)
1413 {
1414 gboolean ret;
1415 GstX264Enc *encoder;
1417 encoder = GST_X264_ENC (gst_pad_get_parent (pad));
1419 switch (GST_EVENT_TYPE (event)) {
1420 case GST_EVENT_EOS:
1421 gst_x264_enc_flush_frames (encoder, TRUE);
1422 break;
1423 /* no flushing if flush received,
1424 * buffers in encoder are considered (in the) past */
1425 case GST_EVENT_CUSTOM_DOWNSTREAM:{
1426 const GstStructure *s;
1427 s = gst_event_get_structure (event);
1428 if (gst_structure_has_name (s, "GstForceKeyUnit")) {
1429 GST_OBJECT_LOCK (encoder);
1430 encoder->i_type = X264_TYPE_I;
1431 GST_OBJECT_UNLOCK (encoder);
1432 }
1433 break;
1434 }
1435 default:
1436 break;
1437 }
1439 ret = gst_pad_push_event (encoder->srcpad, event);
1441 gst_object_unref (encoder);
1442 return ret;
1443 }
1445 /* chain function
1446 * this function does the actual processing
1447 */
1448 static GstFlowReturn
1449 gst_x264_enc_chain (GstPad * pad, GstBuffer * buf)
1450 {
1451 GstX264Enc *encoder = GST_X264_ENC (GST_OBJECT_PARENT (pad));
1452 GstFlowReturn ret;
1453 x264_picture_t pic_in;
1454 gint i_nal, i;
1455 if (G_UNLIKELY (encoder->x264enc == NULL))
1456 goto not_inited;
1458 /* create x264_picture_t from the buffer */
1459 /* mostly taken from mplayer (file ve_x264.c) */
1460 if (G_UNLIKELY (GST_BUFFER_SIZE (buf) < encoder->image_size))
1461 goto wrong_buffer_size;
1463 /* remember the timestamp and duration */
1464 g_queue_push_tail (encoder->delay, buf);
1466 /* set up input picture */
1467 memset (&pic_in, 0, sizeof (pic_in));
1469 pic_in.img.i_csp = X264_CSP_I420;
1470 pic_in.img.i_plane = 3;
1471 for (i = 0; i < 3; i++) {
1472 pic_in.img.plane[i] = GST_BUFFER_DATA (buf) + encoder->offset[i];
1473 pic_in.img.i_stride[i] = encoder->stride[i];
1474 }
1476 GST_OBJECT_LOCK (encoder);
1477 pic_in.i_type = encoder->i_type;
1479 /* Reset encoder forced picture type */
1480 encoder->i_type = X264_TYPE_AUTO;
1481 GST_OBJECT_UNLOCK (encoder);
1483 pic_in.i_pts = GST_BUFFER_TIMESTAMP (buf);
1485 ret = gst_x264_enc_encode_frame (encoder, &pic_in, &i_nal, TRUE);
1487 /* input buffer is released later on */
1488 return ret;
1490 /* ERRORS */
1491 not_inited:
1492 {
1493 GST_WARNING_OBJECT (encoder, "Got buffer before set_caps was called");
1494 gst_buffer_unref (buf);
1495 return GST_FLOW_NOT_NEGOTIATED;
1496 }
1497 wrong_buffer_size:
1498 {
1499 GST_ELEMENT_ERROR (encoder, STREAM, ENCODE,
1500 ("Encode x264 frame failed."),
1501 ("Wrong buffer size %d (should be %d)",
1502 GST_BUFFER_SIZE (buf), encoder->image_size));
1503 gst_buffer_unref (buf);
1504 return GST_FLOW_ERROR;
1505 }
1506 }
1508 static GstFlowReturn
1509 gst_x264_enc_encode_frame (GstX264Enc * encoder, x264_picture_t * pic_in,
1510 int *i_nal, gboolean send)
1511 {
1512 GstBuffer *out_buf = NULL, *in_buf = NULL;
1513 x264_picture_t pic_out;
1514 x264_nal_t *nal;
1515 int i_size;
1516 #ifndef X264_ENC_NALS
1517 int nal_size;
1518 gint i;
1519 #endif
1520 int encoder_return;
1521 GstFlowReturn ret;
1522 GstClockTime timestamp;
1523 GstClockTime duration;
1524 guint8 *data;
1525 GstEvent *forcekeyunit_event = NULL;
1527 if (G_UNLIKELY (encoder->x264enc == NULL))
1528 return GST_FLOW_NOT_NEGOTIATED;
1530 encoder_return = x264_encoder_encode (encoder->x264enc,
1531 &nal, i_nal, pic_in, &pic_out);
1533 if (encoder_return < 0) {
1534 GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x264 frame failed."),
1535 ("x264_encoder_encode return code=%d", encoder_return));
1536 return GST_FLOW_ERROR;
1537 }
1539 if (!*i_nal) {
1540 return GST_FLOW_OK;
1541 }
1542 #ifndef X264_ENC_NALS
1543 i_size = 0;
1544 for (i = 0; i < *i_nal; i++) {
1545 gint i_data = encoder->buffer_size - i_size - 4;
1547 if (i_data < nal[i].i_payload * 2) {
1548 encoder->buffer_size += 2 * nal[i].i_payload;
1549 encoder->buffer = g_realloc (encoder->buffer, encoder->buffer_size);
1550 i_data = encoder->buffer_size - i_size - 4;
1551 }
1553 nal_size =
1554 x264_nal_encode (encoder->buffer + i_size + 4, &i_data, 0, &nal[i]);
1555 if (encoder->byte_stream)
1556 GST_WRITE_UINT32_BE (encoder->buffer + i_size, 1);
1557 else
1558 GST_WRITE_UINT32_BE (encoder->buffer + i_size, nal_size);
1560 i_size += nal_size + 4;
1561 }
1562 data = encoder->buffer;
1563 #else
1564 i_size = encoder_return;
1565 data = nal[0].p_payload;
1566 #endif
1568 in_buf = g_queue_pop_head (encoder->delay);
1569 if (in_buf) {
1570 timestamp = GST_BUFFER_TIMESTAMP (in_buf);
1571 duration = GST_BUFFER_DURATION (in_buf);
1572 gst_buffer_unref (in_buf);
1573 } else {
1574 GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, (NULL),
1575 ("Timestamp queue empty."));
1576 return GST_FLOW_ERROR;
1577 }
1579 if (!send)
1580 return GST_FLOW_OK;
1582 ret = gst_pad_alloc_buffer (encoder->srcpad, GST_BUFFER_OFFSET_NONE,
1583 i_size, GST_PAD_CAPS (encoder->srcpad), &out_buf);
1584 if (ret != GST_FLOW_OK)
1585 return ret;
1587 memcpy (GST_BUFFER_DATA (out_buf), data, i_size);
1588 GST_BUFFER_SIZE (out_buf) = i_size;
1590 /* PTS */
1591 /* FIXME ??: maybe use DTS here, since:
1592 * - it is so practiced by other encoders,
1593 * - downstream (e.g. muxers) might not enjoy non-monotone timestamps,
1594 * whereas a decoder can also deal with DTS */
1595 GST_BUFFER_TIMESTAMP (out_buf) = pic_out.i_pts;
1596 GST_BUFFER_DURATION (out_buf) = duration;
1598 #ifdef X264_INTRA_REFRESH
1599 if (pic_out.b_keyframe) {
1600 #else
1601 if (pic_out.i_type == X264_TYPE_IDR) {
1602 #endif
1603 GST_BUFFER_FLAG_UNSET (out_buf, GST_BUFFER_FLAG_DELTA_UNIT);
1604 } else {
1605 GST_BUFFER_FLAG_SET (out_buf, GST_BUFFER_FLAG_DELTA_UNIT);
1606 }
1608 GST_OBJECT_LOCK (encoder);
1609 forcekeyunit_event = encoder->forcekeyunit_event;
1610 encoder->forcekeyunit_event = NULL;
1611 GST_OBJECT_UNLOCK (encoder);
1612 if (forcekeyunit_event) {
1613 gst_structure_set (forcekeyunit_event->structure,
1614 "timestamp", G_TYPE_UINT64, GST_BUFFER_TIMESTAMP (out_buf), NULL);
1615 gst_pad_push_event (encoder->srcpad, forcekeyunit_event);
1616 }
1618 return gst_pad_push (encoder->srcpad, out_buf);
1619 }
1621 static void
1622 gst_x264_enc_flush_frames (GstX264Enc * encoder, gboolean send)
1623 {
1624 GstFlowReturn flow_ret;
1625 gint i_nal;
1627 /* first send the remaining frames */
1628 if (encoder->x264enc)
1629 do {
1630 flow_ret = gst_x264_enc_encode_frame (encoder, NULL, &i_nal, send);
1631 } while (flow_ret == GST_FLOW_OK && i_nal > 0);
1633 /* in any case, make sure the delay queue is emptied */
1634 while (!g_queue_is_empty (encoder->delay))
1635 gst_buffer_unref (g_queue_pop_head (encoder->delay));
1636 }
1638 static GstStateChangeReturn
1639 gst_x264_enc_change_state (GstElement * element, GstStateChange transition)
1640 {
1641 GstX264Enc *encoder = GST_X264_ENC (element);
1642 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
1644 ret = parent_class->change_state (element, transition);
1645 if (ret == GST_STATE_CHANGE_FAILURE)
1646 goto out;
1648 switch (transition) {
1649 case GST_STATE_CHANGE_PAUSED_TO_READY:
1650 gst_x264_enc_flush_frames (encoder, FALSE);
1651 gst_x264_enc_close_encoder (encoder);
1652 gst_x264_enc_reset (encoder);
1653 break;
1654 default:
1655 break;
1656 }
1658 out:
1659 return ret;
1660 }
1662 static void
1663 gst_x264_enc_set_property (GObject * object, guint prop_id,
1664 const GValue * value, GParamSpec * pspec)
1665 {
1666 GstX264Enc *encoder;
1667 GstState state;
1669 const gchar *partitions = NULL;
1671 encoder = GST_X264_ENC (object);
1673 GST_OBJECT_LOCK (encoder);
1674 /* state at least matters for sps, bytestream, pass,
1675 * and so by extension ... */
1676 state = GST_STATE (encoder);
1677 if (state != GST_STATE_READY && state != GST_STATE_NULL)
1678 goto wrong_state;
1680 switch (prop_id) {
1681 case ARG_PASS:
1682 encoder->pass = g_value_get_enum (value);
1683 break;
1684 case ARG_QUANTIZER:
1685 encoder->quantizer = g_value_get_uint (value);
1686 break;
1687 case ARG_BITRATE:
1688 encoder->bitrate = g_value_get_uint (value);
1689 break;
1690 case ARG_VBV_BUF_CAPACITY:
1691 encoder->vbv_buf_capacity = g_value_get_uint (value);
1692 break;
1693 case ARG_SPEED_PRESET:
1694 encoder->speed_preset = g_value_get_enum (value);
1695 break;
1696 case ARG_PSY_TUNE:
1697 encoder->psy_tune = g_value_get_enum (value);
1698 break;
1699 case ARG_TUNE:
1700 encoder->tune = g_value_get_flags (value);
1701 break;
1702 case ARG_PROFILE:
1703 encoder->profile = g_value_get_enum (value);
1704 break;
1705 case ARG_OPTION_STRING:
1706 g_string_assign (encoder->option_string_prop, g_value_get_string (value));
1707 break;
1708 case ARG_THREADS:
1709 encoder->threads = g_value_get_uint (value);
1710 g_string_append_printf (encoder->option_string, ":threads=%d",
1711 encoder->threads);
1712 break;
1713 case ARG_SLICED_THREADS:
1714 encoder->sliced_threads = g_value_get_boolean (value);
1715 g_string_append_printf (encoder->option_string, ":sliced-threads=%d",
1716 encoder->sliced_threads);
1717 break;
1718 case ARG_SYNC_LOOKAHEAD:
1719 encoder->sync_lookahead = g_value_get_int (value);
1720 g_string_append_printf (encoder->option_string, ":sync-lookahead=%d",
1721 encoder->sync_lookahead);
1722 break;
1723 case ARG_STATS_FILE:
1724 case ARG_MULTIPASS_CACHE_FILE:
1725 if (encoder->mp_cache_file)
1726 g_free (encoder->mp_cache_file);
1727 encoder->mp_cache_file = g_value_dup_string (value);
1728 g_string_append_printf (encoder->option_string, ":stats=%s",
1729 encoder->mp_cache_file);
1730 break;
1731 case ARG_BYTE_STREAM:
1732 encoder->byte_stream = g_value_get_boolean (value);
1733 g_string_append_printf (encoder->option_string, ":annexb=%d",
1734 encoder->byte_stream);
1735 break;
1736 case ARG_INTRA_REFRESH:
1737 encoder->intra_refresh = g_value_get_boolean (value);
1738 g_string_append_printf (encoder->option_string, ":intra-refresh=%d",
1739 encoder->intra_refresh);
1740 break;
1741 case ARG_ME:
1742 encoder->me = g_value_get_enum (value);
1743 g_string_append_printf (encoder->option_string, ":me=%s",
1744 x264_motion_est_names[encoder->me]);
1745 break;
1746 case ARG_SUBME:
1747 encoder->subme = g_value_get_uint (value);
1748 g_string_append_printf (encoder->option_string, ":subme=%d",
1749 encoder->subme);
1750 break;
1751 case ARG_ANALYSE:
1752 encoder->analyse = g_value_get_flags (value);
1753 partitions = gst_x264_enc_build_partitions (encoder->analyse);
1754 if (partitions) {
1755 g_string_append_printf (encoder->option_string, ":partitions=%s",
1756 partitions);
1757 g_free ((gpointer) partitions);
1758 }
1759 break;
1760 case ARG_DCT8x8:
1761 encoder->dct8x8 = g_value_get_boolean (value);
1762 g_string_append_printf (encoder->option_string, ":8x8dct=%d",
1763 encoder->dct8x8);
1764 break;
1765 case ARG_REF:
1766 encoder->ref = g_value_get_uint (value);
1767 g_string_append_printf (encoder->option_string, ":ref=%d", encoder->ref);
1768 break;
1769 case ARG_BFRAMES:
1770 encoder->bframes = g_value_get_uint (value);
1771 g_string_append_printf (encoder->option_string, ":bframes=%d",
1772 encoder->bframes);
1773 break;
1774 case ARG_B_ADAPT:
1775 encoder->b_adapt = g_value_get_boolean (value);
1776 g_string_append_printf (encoder->option_string, ":b-adapt=%d",
1777 encoder->b_adapt);
1778 break;
1779 case ARG_B_PYRAMID:
1780 encoder->b_pyramid = g_value_get_boolean (value);
1781 g_string_append_printf (encoder->option_string, ":b-pyramid=%d",
1782 encoder->b_pyramid);
1783 break;
1784 case ARG_WEIGHTB:
1785 encoder->weightb = g_value_get_boolean (value);
1786 g_string_append_printf (encoder->option_string, ":weightb=%d",
1787 encoder->weightb);
1788 break;
1789 case ARG_SPS_ID:
1790 encoder->sps_id = g_value_get_uint (value);
1791 g_string_append_printf (encoder->option_string, ":sps-id=%d",
1792 encoder->sps_id);
1793 break;
1794 case ARG_AU_NALU:
1795 encoder->au_nalu = g_value_get_boolean (value);
1796 g_string_append_printf (encoder->option_string, ":aud=%d",
1797 encoder->au_nalu);
1798 break;
1799 case ARG_TRELLIS:
1800 encoder->trellis = g_value_get_boolean (value);
1801 g_string_append_printf (encoder->option_string, ":trellis=%d",
1802 encoder->trellis);
1803 break;
1804 case ARG_KEYINT_MAX:
1805 encoder->keyint_max = g_value_get_uint (value);
1806 g_string_append_printf (encoder->option_string, ":keyint=%d",
1807 encoder->keyint_max);
1808 break;
1809 case ARG_CABAC:
1810 encoder->cabac = g_value_get_boolean (value);
1811 g_string_append_printf (encoder->option_string, ":cabac=%d",
1812 encoder->cabac);
1813 break;
1814 case ARG_QP_MIN:
1815 encoder->qp_min = g_value_get_uint (value);
1816 g_string_append_printf (encoder->option_string, ":qpmin=%d",
1817 encoder->qp_min);
1818 break;
1819 case ARG_QP_MAX:
1820 encoder->qp_max = g_value_get_uint (value);
1821 g_string_append_printf (encoder->option_string, ":qpmax=%d",
1822 encoder->qp_max);
1823 break;
1824 case ARG_QP_STEP:
1825 encoder->qp_step = g_value_get_uint (value);
1826 g_string_append_printf (encoder->option_string, ":qpstep=%d",
1827 encoder->qp_step);
1828 break;
1829 case ARG_IP_FACTOR:
1830 encoder->ip_factor = g_value_get_float (value);
1831 g_string_append_printf (encoder->option_string, ":ip-factor=%f",
1832 encoder->ip_factor);
1833 break;
1834 case ARG_PB_FACTOR:
1835 encoder->pb_factor = g_value_get_float (value);
1836 g_string_append_printf (encoder->option_string, ":pb-factor=%f",
1837 encoder->pb_factor);
1838 break;
1839 case ARG_RC_MB_TREE:
1840 encoder->mb_tree = g_value_get_boolean (value);
1841 g_string_append_printf (encoder->option_string, ":mbtree=%d",
1842 encoder->mb_tree);
1843 break;
1844 case ARG_RC_LOOKAHEAD:
1845 encoder->rc_lookahead = g_value_get_int (value);
1846 g_string_append_printf (encoder->option_string, ":rc-lookahead=%d",
1847 encoder->rc_lookahead);
1848 break;
1849 case ARG_NR:
1850 encoder->noise_reduction = g_value_get_uint (value);
1851 g_string_append_printf (encoder->option_string, ":nr=%d",
1852 encoder->noise_reduction);
1853 break;
1854 case ARG_INTERLACED:
1855 encoder->interlaced = g_value_get_boolean (value);
1856 g_string_append_printf (encoder->option_string, ":interlaced=%d",
1857 encoder->interlaced);
1858 break;
1859 default:
1860 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1861 break;
1862 }
1863 GST_OBJECT_UNLOCK (encoder);
1864 return;
1866 /* ERROR */
1867 wrong_state:
1868 {
1869 GST_DEBUG_OBJECT (encoder, "setting property in wrong state");
1870 GST_OBJECT_UNLOCK (encoder);
1871 }
1872 }
1874 static void
1875 gst_x264_enc_get_property (GObject * object, guint prop_id,
1876 GValue * value, GParamSpec * pspec)
1877 {
1878 GstX264Enc *encoder;
1880 encoder = GST_X264_ENC (object);
1882 GST_OBJECT_LOCK (encoder);
1883 switch (prop_id) {
1884 case ARG_THREADS:
1885 g_value_set_uint (value, encoder->threads);
1886 break;
1887 case ARG_SLICED_THREADS:
1888 g_value_set_boolean (value, encoder->sliced_threads);
1889 break;
1890 case ARG_SYNC_LOOKAHEAD:
1891 g_value_set_int (value, encoder->sync_lookahead);
1892 break;
1893 case ARG_PASS:
1894 g_value_set_enum (value, encoder->pass);
1895 break;
1896 case ARG_QUANTIZER:
1897 g_value_set_uint (value, encoder->quantizer);
1898 break;
1899 case ARG_STATS_FILE:
1900 case ARG_MULTIPASS_CACHE_FILE:
1901 g_value_set_string (value, encoder->mp_cache_file);
1902 break;
1903 case ARG_BYTE_STREAM:
1904 g_value_set_boolean (value, encoder->byte_stream);
1905 break;
1906 case ARG_BITRATE:
1907 g_value_set_uint (value, encoder->bitrate);
1908 break;
1909 case ARG_INTRA_REFRESH:
1910 g_value_set_boolean (value, encoder->intra_refresh);
1911 break;
1912 case ARG_VBV_BUF_CAPACITY:
1913 g_value_set_uint (value, encoder->vbv_buf_capacity);
1914 break;
1915 case ARG_ME:
1916 g_value_set_enum (value, encoder->me);
1917 break;
1918 case ARG_SUBME:
1919 g_value_set_uint (value, encoder->subme);
1920 break;
1921 case ARG_ANALYSE:
1922 g_value_set_flags (value, encoder->analyse);
1923 break;
1924 case ARG_DCT8x8:
1925 g_value_set_boolean (value, encoder->dct8x8);
1926 break;
1927 case ARG_REF:
1928 g_value_set_uint (value, encoder->ref);
1929 break;
1930 case ARG_BFRAMES:
1931 g_value_set_uint (value, encoder->bframes);
1932 break;
1933 case ARG_B_ADAPT:
1934 g_value_set_boolean (value, encoder->b_adapt);
1935 break;
1936 case ARG_B_PYRAMID:
1937 g_value_set_boolean (value, encoder->b_pyramid);
1938 break;
1939 case ARG_WEIGHTB:
1940 g_value_set_boolean (value, encoder->weightb);
1941 break;
1942 case ARG_SPS_ID:
1943 g_value_set_uint (value, encoder->sps_id);
1944 break;
1945 case ARG_AU_NALU:
1946 g_value_set_boolean (value, encoder->au_nalu);
1947 break;
1948 case ARG_TRELLIS:
1949 g_value_set_boolean (value, encoder->trellis);
1950 break;
1951 case ARG_KEYINT_MAX:
1952 g_value_set_uint (value, encoder->keyint_max);
1953 break;
1954 case ARG_QP_MIN:
1955 g_value_set_uint (value, encoder->qp_min);
1956 break;
1957 case ARG_QP_MAX:
1958 g_value_set_uint (value, encoder->qp_max);
1959 break;
1960 case ARG_QP_STEP:
1961 g_value_set_uint (value, encoder->qp_step);
1962 break;
1963 case ARG_CABAC:
1964 g_value_set_boolean (value, encoder->cabac);
1965 break;
1966 case ARG_IP_FACTOR:
1967 g_value_set_float (value, encoder->ip_factor);
1968 break;
1969 case ARG_PB_FACTOR:
1970 g_value_set_float (value, encoder->pb_factor);
1971 break;
1972 case ARG_RC_MB_TREE:
1973 g_value_set_boolean (value, encoder->mb_tree);
1974 break;
1975 case ARG_RC_LOOKAHEAD:
1976 g_value_set_int (value, encoder->rc_lookahead);
1977 break;
1978 case ARG_NR:
1979 g_value_set_uint (value, encoder->noise_reduction);
1980 break;
1981 case ARG_INTERLACED:
1982 g_value_set_boolean (value, encoder->interlaced);
1983 break;
1984 case ARG_SPEED_PRESET:
1985 g_value_set_enum (value, encoder->speed_preset);
1986 break;
1987 case ARG_PSY_TUNE:
1988 g_value_set_enum (value, encoder->psy_tune);
1989 break;
1990 case ARG_TUNE:
1991 g_value_set_flags (value, encoder->tune);
1992 break;
1993 case ARG_PROFILE:
1994 g_value_set_enum (value, encoder->profile);
1995 break;
1996 case ARG_OPTION_STRING:
1997 g_value_set_string (value, encoder->option_string_prop->str);
1998 break;
1999 default:
2000 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2001 break;
2002 }
2003 GST_OBJECT_UNLOCK (encoder);
2004 }
2006 static gboolean
2007 plugin_init (GstPlugin * plugin)
2008 {
2009 GST_DEBUG_CATEGORY_INIT (x264_enc_debug, "x264enc", 0,
2010 "h264 encoding element");
2012 return gst_element_register (plugin, "x264enc",
2013 GST_RANK_PRIMARY, GST_TYPE_X264_ENC);
2014 }
2016 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
2017 GST_VERSION_MINOR,
2018 "x264",
2019 "libx264-based H264 plugins",
2020 plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)