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