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