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 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 */
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
25 #include "gstx264enc.h"
27 #include <string.h>
28 #include <stdlib.h>
31 enum
32 {
33 ARG_0,
34 ARG_THREADS,
35 ARG_PASS,
36 ARG_STATS_FILE,
37 ARG_BYTE_STREAM,
38 ARG_BITRATE,
39 ARG_VBV_BUF_CAPACITY,
40 ARG_ME,
41 ARG_SUBME,
42 ARG_ANALYSE,
43 ARG_DCT8x8,
44 ARG_REF,
45 ARG_BFRAMES,
46 ARG_B_PYRAMID,
47 ARG_WEIGHTB,
48 ARG_SPS_ID,
49 ARG_TRELLIS,
50 ARG_KEYINT_MAX,
51 ARG_CABAC
52 };
54 #define ARG_THREADS_DEFAULT 1
55 #define ARG_PASS_DEFAULT 0
56 #define ARG_STATS_FILE_DEFAULT "x264.log"
57 #define ARG_BYTE_STREAM_DEFAULT FALSE
58 #define ARG_BITRATE_DEFAULT (2 * 1024)
59 #define ARG_VBV_BUF_CAPACITY_DEFAULT 600
60 #define ARG_ME_DEFAULT X264_ME_HEX
61 #define ARG_SUBME_DEFAULT 1
62 #define ARG_ANALYSE_DEFAULT 0
63 #define ARG_DCT8x8_DEFAULT FALSE
64 #define ARG_REF_DEFAULT 1
65 #define ARG_BFRAMES_DEFAULT 0
66 #define ARG_B_PYRAMID_DEFAULT FALSE
67 #define ARG_WEIGHTB_DEFAULT FALSE
68 #define ARG_SPS_ID_DEFAULT 0
69 #define ARG_TRELLIS_DEFAULT TRUE
70 #define ARG_KEYINT_MAX_DEFAULT 0
71 #define ARG_CABAC_DEFAULT TRUE
73 #define GST_X264_ENC_ME_TYPE (gst_x264_enc_me_get_type())
74 static GType
75 gst_x264_enc_me_get_type (void)
76 {
77 static GType me_type = 0;
78 static const GEnumValue me_types[] = {
79 {X264_ME_DIA, "diamond search, radius 1 (fast)", "dia"},
80 {X264_ME_HEX, "hexagonal search, radius 2", "hex"},
81 {X264_ME_UMH, "uneven multi-hexagon search", "umh"},
82 {X264_ME_ESA, "exhaustive search (slow)", "esa"},
83 {0, NULL, NULL}
84 };
86 if (!me_type) {
87 me_type = g_enum_register_static ("GstX264EncMe", me_types);
88 }
89 return me_type;
90 }
92 #define GST_X264_ENC_ANALYSE_TYPE (gst_x264_enc_analyse_get_type())
93 static GType
94 gst_x264_enc_analyse_get_type (void)
95 {
96 static GType analyse_type = 0;
97 static const GFlagsValue analyse_types[] = {
98 {X264_ANALYSE_I4x4, "i4x4", "i4x4"},
99 {X264_ANALYSE_I8x8, "i8x8", "i8x8"},
100 {X264_ANALYSE_PSUB16x16, "p8x8", "p8x8"},
101 {X264_ANALYSE_PSUB8x8, "p4x4", "p4x4"},
102 {X264_ANALYSE_BSUB16x16, "b8x8", "b8x8"},
103 {0, NULL, NULL},
104 };
106 if (!analyse_type) {
107 analyse_type = g_flags_register_static ("GstX264EncAnalyse", analyse_types);
108 }
109 return analyse_type;
110 }
112 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
113 GST_PAD_SINK,
114 GST_PAD_ALWAYS,
115 GST_STATIC_CAPS ("video/x-raw-yuv, "
116 "format = (fourcc) I420, "
117 "framerate = (fraction) [0, MAX], "
118 "width = (int) [ 16, MAX ], " "height = (int) [ 16, MAX ]")
119 );
121 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
122 GST_PAD_SRC,
123 GST_PAD_ALWAYS,
124 GST_STATIC_CAPS ("video/x-h264")
125 );
127 GST_BOILERPLATE (GstX264Enc, gst_x264_enc, GstElement, GST_TYPE_ELEMENT);
129 static void gst_x264_enc_dispose (GObject * object);
131 static gboolean gst_x264_enc_init_encoder (GstX264Enc * encoder);
132 static void gst_x264_enc_close_encoder (GstX264Enc * encoder);
134 static gboolean gst_x264_enc_sink_event (GstPad * pad, GstEvent * event);
135 static GstFlowReturn gst_x264_enc_chain (GstPad * pad, GstBuffer * buf);
136 static GstFlowReturn gst_x264_enc_encode_frame (GstX264Enc * encoder,
137 x264_picture_t * pic_in, int *i_nal);
138 static GstStateChangeReturn gst_x264_enc_change_state (GstElement * element,
139 GstStateChange transition);
141 static void gst_x264_enc_set_property (GObject * object, guint prop_id,
142 const GValue * value, GParamSpec * pspec);
143 static void gst_x264_enc_get_property (GObject * object, guint prop_id,
144 GValue * value, GParamSpec * pspec);
146 static void
147 gst_x264_enc_timestamp_queue_init (GstX264Enc * encoder)
148 {
149 encoder->timestamp_queue_size = (2 + encoder->bframes + encoder->threads) * 2;
150 encoder->timestamp_queue_head = 0;
151 encoder->timestamp_queue_tail = 0;
152 encoder->timestamp_queue =
153 g_new (GstClockTime, encoder->timestamp_queue_size);
154 encoder->timestamp_queue_dur =
155 g_new (GstClockTime, encoder->timestamp_queue_size);
156 }
158 static void
159 gst_x264_enc_timestamp_queue_free (GstX264Enc * encoder)
160 {
161 if (encoder->timestamp_queue) {
162 g_free (encoder->timestamp_queue);
163 encoder->timestamp_queue = NULL;
164 }
165 if (encoder->timestamp_queue_dur) {
166 g_free (encoder->timestamp_queue_dur);
167 encoder->timestamp_queue_dur = NULL;
168 }
170 encoder->timestamp_queue_size = 0;
171 encoder->timestamp_queue_head = 0;
172 encoder->timestamp_queue_tail = 0;
173 }
175 static void
176 gst_x264_enc_timestamp_queue_put (GstX264Enc * encoder, GstClockTime clock_time,
177 GstClockTime duration)
178 {
179 encoder->timestamp_queue[encoder->timestamp_queue_tail] = clock_time;
180 encoder->timestamp_queue_dur[encoder->timestamp_queue_tail] = duration;
181 encoder->timestamp_queue_tail++;
182 encoder->timestamp_queue_tail %= encoder->timestamp_queue_size;
184 if (encoder->timestamp_queue_tail == encoder->timestamp_queue_head) {
185 GST_ELEMENT_ERROR (encoder, STREAM, ENCODE,
186 ("Timestamp queue overflow."), ("FIX CODE"));
187 }
188 }
190 static void
191 gst_x264_enc_timestamp_queue_get (GstX264Enc * encoder,
192 GstClockTime * clock_time, GstClockTime * duration)
193 {
194 if (encoder->timestamp_queue_head == encoder->timestamp_queue_tail) {
195 GST_ELEMENT_ERROR (encoder, STREAM, ENCODE,
196 ("Timestamp queue empty or after overflow."), ("FIX CODE"));
197 *clock_time = GST_CLOCK_TIME_NONE;
198 *duration = GST_CLOCK_TIME_NONE;
199 return;
200 }
202 *clock_time = encoder->timestamp_queue[encoder->timestamp_queue_head];
203 *duration = encoder->timestamp_queue_dur[encoder->timestamp_queue_head];
204 encoder->timestamp_queue_head++;
205 encoder->timestamp_queue_head %= encoder->timestamp_queue_size;
206 }
208 /*
209 * Returns: Buffer with the stream headers.
210 */
211 static GstBuffer *
212 gst_x264_enc_header_buf (GstX264Enc * encoder)
213 {
214 GstBuffer *buf;
215 x264_nal_t *nal;
216 int i_nal;
217 int header_return;
218 int i_size;
219 int nal_size, i_data;
220 guint8 *buffer, *sps;
221 gulong buffer_size;
223 if (G_UNLIKELY (encoder->x264enc == NULL))
224 return NULL;
226 /* Create avcC header. */
228 header_return = x264_encoder_headers (encoder->x264enc, &nal, &i_nal);
229 if (header_return < 0) {
230 GST_ELEMENT_ERROR (encoder, STREAM, ENCODE,
231 ("Encode x264 header failed."),
232 ("x264_encoder_headers return code=%d", header_return));
233 return NULL;
234 }
236 /* This should be enough for a header buffer. */
237 buffer_size = 100000;
238 buffer = g_malloc (buffer_size);
240 if (nal[1].i_type != 7 || nal[2].i_type != 8) {
241 GST_ELEMENT_ERROR (encoder, STREAM, ENCODE,
242 ("Unexpected x264 header."),
243 ("TODO avcC header construction for high profiles needs some work"));
244 return NULL;
245 }
247 sps = nal[1].p_payload;
249 buffer[0] = 1; /* AVC Decoder Configuration Record ver. 1 */
250 buffer[1] = sps[0]; /* profile_idc */
251 buffer[2] = sps[1]; /* profile_compability */
252 buffer[3] = sps[2]; /* level_idc */
253 buffer[4] = 0xfc | (4 - 1); /* nal_length_size_minus1 */
255 i_size = 5;
257 buffer[i_size++] = 0xe0 | 1; /* number of SPSs */
259 i_data = buffer_size - i_size - 2;
260 nal_size = x264_nal_encode (buffer + i_size + 2, &i_data, 0, &nal[1]);
261 buffer[i_size + 0] = (nal_size >> 8) & 0xff;
262 buffer[i_size + 1] = nal_size & 0xff;
263 i_size += nal_size + 2;
265 buffer[i_size++] = 1; /* number of PPSs */
267 i_data = buffer_size - i_size - 2;
268 nal_size = x264_nal_encode (buffer + i_size + 2, &i_data, 0, &nal[2]);
269 buffer[i_size + 0] = (nal_size >> 8) & 0xff;
270 buffer[i_size + 1] = nal_size & 0xff;
271 i_size += nal_size + 2;
273 buf = gst_buffer_new_and_alloc (i_size);
275 memcpy (GST_BUFFER_DATA (buf), buffer, i_size);
277 free (buffer);
279 return buf;
280 }
282 /* gst_x264_enc_set_src_caps
283 * Returns: TRUE on success.
284 */
285 static gboolean
286 gst_x264_enc_set_src_caps (GstX264Enc * encoder, GstPad * pad, GstCaps * caps)
287 {
288 GstStructure *structure;
289 GValue header = { 0, };
290 GstBuffer *buf;
291 GstCaps *outcaps;
292 gboolean res;
294 structure = gst_caps_get_structure (caps, 0);
295 structure = gst_structure_copy (structure);
296 gst_structure_set_name (structure, "video/x-h264");
298 if (!encoder->byte_stream) {
299 buf = gst_x264_enc_header_buf (encoder);
300 if (buf != NULL) {
301 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
302 g_value_init (&header, GST_TYPE_BUFFER);
303 gst_value_set_buffer (&header, buf);
304 gst_structure_set_value (structure, "codec_data", &header);
305 g_value_unset (&header);
306 }
307 }
309 outcaps = gst_caps_new_full (structure, NULL);
310 res = gst_pad_set_caps (pad, outcaps);
311 gst_caps_unref (outcaps);
313 return res;
314 }
316 static gboolean
317 gst_x264_enc_sink_set_caps (GstPad * pad, GstCaps * caps)
318 {
319 GstX264Enc *encoder = GST_X264_ENC (GST_OBJECT_PARENT (pad));
320 GstStructure *structure;
321 const GValue *framerate, *par;
322 gint width, height;
323 gint framerate_num, framerate_den;
324 gint par_num, par_den;
326 structure = gst_caps_get_structure (caps, 0);
327 if (!gst_structure_get_int (structure, "width", &width))
328 return FALSE;
329 if (!gst_structure_get_int (structure, "height", &height))
330 return FALSE;
331 if (!(framerate = gst_structure_get_value (structure, "framerate")))
332 return FALSE;
333 framerate_num = gst_value_get_fraction_numerator (framerate);
334 framerate_den = gst_value_get_fraction_denominator (framerate);
335 if (!(par = gst_structure_get_value (structure, "pixel-aspect-ratio"))) {
336 par_num = 1;
337 par_den = 1;
338 } else {
339 par_num = gst_value_get_fraction_numerator (par);
340 par_den = gst_value_get_fraction_denominator (par);
341 }
343 /* If the encoder is initialized, do not
344 reinitialize it again if not necessary */
345 if (encoder->x264enc) {
346 gboolean caps_same = width == encoder->width
347 && height == encoder->height
348 && framerate_num == encoder->framerate_num
349 && framerate_den == encoder->framerate_den
350 && par_num == encoder->par_num && par_den == encoder->par_den;
352 GstFlowReturn flow_ret;
353 int i_nal;
355 if (caps_same)
356 /* Negotiating the same caps */
357 return TRUE;
359 do {
360 flow_ret = gst_x264_enc_encode_frame (encoder, NULL, &i_nal);
361 } while (flow_ret == GST_FLOW_OK && i_nal > 0);
363 encoder->sps_id++;
364 }
365 encoder->width = width;
366 encoder->height = height;
367 encoder->framerate_num = framerate_num;
368 encoder->framerate_den = framerate_den;
369 encoder->par_num = par_num;
370 encoder->par_den = par_den;
372 /* FIXME: is this correct for odd widths/heights? (tpm) */
373 encoder->stride = encoder->width;
374 encoder->luma_plane_size = encoder->width * encoder->height;
376 if (!gst_x264_enc_init_encoder (encoder))
377 return FALSE;
379 if (!gst_x264_enc_set_src_caps (encoder, encoder->srcpad, caps)) {
380 gst_x264_enc_close_encoder (encoder);
381 return FALSE;
382 }
384 return TRUE;
385 }
387 static void
388 gst_x264_enc_base_init (gpointer g_class)
389 {
390 static GstElementDetails plugin_details = {
391 "x264enc",
392 "Codec/Encoder/Video",
393 "H264 Encoder",
394 "Josef Zlomek <josef.zlomek@itonis.tv>"
395 };
396 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
398 gst_element_class_add_pad_template (element_class,
399 gst_static_pad_template_get (&src_factory));
400 gst_element_class_add_pad_template (element_class,
401 gst_static_pad_template_get (&sink_factory));
402 gst_element_class_set_details (element_class, &plugin_details);
403 }
405 static void
406 gst_x264_enc_class_init (GstX264EncClass * klass)
407 {
408 GObjectClass *gobject_class;
409 GstElementClass *gstelement_class;
411 gobject_class = (GObjectClass *) klass;
412 gstelement_class = (GstElementClass *) klass;
414 gobject_class->set_property = gst_x264_enc_set_property;
415 gobject_class->get_property = gst_x264_enc_get_property;
416 gobject_class->dispose = gst_x264_enc_dispose;
418 gstelement_class->change_state =
419 GST_DEBUG_FUNCPTR (gst_x264_enc_change_state);
421 g_object_class_install_property (gobject_class, ARG_THREADS,
422 g_param_spec_uint ("threads", "Threads",
423 "Number of threads used by the codec", 1, 4, ARG_THREADS_DEFAULT,
424 G_PARAM_READWRITE));
425 g_object_class_install_property (gobject_class, ARG_PASS,
426 g_param_spec_uint ("pass", "Pass",
427 "Pass of multipass encoding (0=single pass; 1=first pass, 2=middle pass, 3=last pass)",
428 0, 3, ARG_PASS_DEFAULT, G_PARAM_READWRITE));
429 g_object_class_install_property (gobject_class, ARG_STATS_FILE,
430 g_param_spec_string ("stats_file", "Stats File",
431 "Filename for multipass statistics", ARG_STATS_FILE_DEFAULT,
432 G_PARAM_READWRITE));
433 g_object_class_install_property (gobject_class, ARG_BYTE_STREAM,
434 g_param_spec_boolean ("byte_stream", "Byte Stream",
435 "Generate byte stream format of NALU", ARG_BYTE_STREAM_DEFAULT,
436 G_PARAM_READWRITE));
437 g_object_class_install_property (gobject_class, ARG_BITRATE,
438 g_param_spec_uint ("bitrate", "Bitrate", "Bitrate in kbit/sec", 1,
439 100 * 1024, ARG_BITRATE_DEFAULT, G_PARAM_READWRITE));
440 g_object_class_install_property (gobject_class, ARG_VBV_BUF_CAPACITY,
441 g_param_spec_uint ("vbv_buf_capacity", "VBV buffer capacity",
442 "Size of the VBV buffer in milliseconds", 300,
443 10000, ARG_VBV_BUF_CAPACITY_DEFAULT, G_PARAM_READWRITE));
444 g_object_class_install_property (gobject_class, ARG_ME,
445 g_param_spec_enum ("me", "Motion Estimation",
446 "Integer pixel motion estimation method", GST_X264_ENC_ME_TYPE,
447 ARG_ME_DEFAULT, G_PARAM_READWRITE));
448 g_object_class_install_property (gobject_class, ARG_SUBME,
449 g_param_spec_uint ("subme", "Subpixel Motion Estimation",
450 "Subpixel motion estimation and partition decision quality: 1=fast, 6=best",
451 1, 6, ARG_SUBME_DEFAULT, G_PARAM_READWRITE));
452 g_object_class_install_property (gobject_class, ARG_ANALYSE,
453 g_param_spec_flags ("analyse", "Analyse", "Partitions to consider",
454 GST_X264_ENC_ANALYSE_TYPE, ARG_ANALYSE_DEFAULT, G_PARAM_READWRITE));
455 g_object_class_install_property (gobject_class, ARG_DCT8x8,
456 g_param_spec_boolean ("dct8x8", "DCT8x8",
457 "Adaptive spatial transform size", ARG_DCT8x8_DEFAULT,
458 G_PARAM_READWRITE));
459 g_object_class_install_property (gobject_class, ARG_REF,
460 g_param_spec_uint ("ref", "Reference Frames",
461 "Number of reference frames", 1, 12, ARG_REF_DEFAULT,
462 G_PARAM_READWRITE));
463 g_object_class_install_property (gobject_class, ARG_BFRAMES,
464 g_param_spec_uint ("bframes", "B-Frames",
465 "Number of B-frames between I and P", 0, 4, ARG_BFRAMES_DEFAULT,
466 G_PARAM_READWRITE));
467 g_object_class_install_property (gobject_class, ARG_B_PYRAMID,
468 g_param_spec_boolean ("b_pyramid", "B-Pyramid",
469 "Keep some B-frames as references", ARG_B_PYRAMID_DEFAULT,
470 G_PARAM_READWRITE));
471 g_object_class_install_property (gobject_class, ARG_WEIGHTB,
472 g_param_spec_boolean ("weightb", "Weighted B-Frames",
473 "Weighted prediction for B-frames", ARG_WEIGHTB_DEFAULT,
474 G_PARAM_READWRITE));
475 g_object_class_install_property (gobject_class, ARG_SPS_ID,
476 g_param_spec_uint ("sps_id", "SPS ID",
477 "SPS and PPS ID number", 0, 31, ARG_SPS_ID_DEFAULT,
478 G_PARAM_READWRITE));
479 g_object_class_install_property (gobject_class, ARG_TRELLIS,
480 g_param_spec_boolean ("trellis", "Trellis quantization",
481 "Enable trellis searched quantization", ARG_TRELLIS_DEFAULT,
482 G_PARAM_READWRITE));
483 g_object_class_install_property (gobject_class, ARG_KEYINT_MAX,
484 g_param_spec_uint ("key_int_max", "Key-frame maximal interval",
485 "Maximal distance between two key-frames (0 for automatic)", 0,
486 G_MAXINT, ARG_KEYINT_MAX_DEFAULT, G_PARAM_READWRITE));
487 g_object_class_install_property (gobject_class, ARG_CABAC,
488 g_param_spec_boolean ("cabac", "Use CABAC",
489 "Enable CABAC entropy coding", ARG_CABAC_DEFAULT, G_PARAM_READWRITE));
490 }
492 /* initialize the new element
493 * instantiate pads and add them to element
494 * set functions
495 * initialize structure
496 */
497 static void
498 gst_x264_enc_init (GstX264Enc * encoder, GstX264EncClass * klass)
499 {
500 encoder->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
501 gst_pad_set_setcaps_function (encoder->sinkpad,
502 GST_DEBUG_FUNCPTR (gst_x264_enc_sink_set_caps));
503 gst_pad_set_event_function (encoder->sinkpad,
504 GST_DEBUG_FUNCPTR (gst_x264_enc_sink_event));
505 gst_pad_set_chain_function (encoder->sinkpad,
506 GST_DEBUG_FUNCPTR (gst_x264_enc_chain));
507 gst_element_add_pad (GST_ELEMENT (encoder), encoder->sinkpad);
509 encoder->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
510 gst_pad_use_fixed_caps (encoder->srcpad);
511 gst_element_add_pad (GST_ELEMENT (encoder), encoder->srcpad);
513 /* initialize internals */
514 encoder->x264enc = NULL;
516 encoder->width = 16;
517 encoder->height = 16;
519 encoder->threads = ARG_THREADS_DEFAULT;
520 encoder->pass = ARG_PASS_DEFAULT;
521 encoder->stats_file = g_strdup (ARG_STATS_FILE_DEFAULT);
522 encoder->byte_stream = ARG_BYTE_STREAM_DEFAULT;
523 encoder->bitrate = ARG_BITRATE_DEFAULT;
524 encoder->vbv_buf_capacity = ARG_VBV_BUF_CAPACITY_DEFAULT;
525 encoder->me = ARG_ME_DEFAULT;
526 encoder->subme = ARG_SUBME_DEFAULT;
527 encoder->analyse = ARG_ANALYSE_DEFAULT;
528 encoder->dct8x8 = ARG_DCT8x8_DEFAULT;
529 encoder->ref = ARG_REF_DEFAULT;
530 encoder->bframes = ARG_BFRAMES_DEFAULT;
531 encoder->b_pyramid = ARG_B_PYRAMID_DEFAULT;
532 encoder->weightb = ARG_WEIGHTB_DEFAULT;
533 encoder->sps_id = ARG_SPS_ID_DEFAULT;
534 encoder->trellis = ARG_TRELLIS_DEFAULT;
535 encoder->keyint_max = ARG_KEYINT_MAX_DEFAULT;
536 encoder->cabac = ARG_CABAC_DEFAULT;
538 encoder->last_timestamp = GST_CLOCK_TIME_NONE;
539 gst_x264_enc_timestamp_queue_init (encoder);
541 encoder->buffer_size = 1040000;
542 encoder->buffer = g_malloc (encoder->buffer_size);
544 x264_param_default (&encoder->x264param);
545 }
547 /*
548 * gst_x264_enc_init_encoder
549 * @encoder: Encoder which should be initialized.
550 *
551 * Initialize x264 encoder.
552 *
553 */
554 static gboolean
555 gst_x264_enc_init_encoder (GstX264Enc * encoder)
556 {
557 /* make sure that the encoder is closed */
558 gst_x264_enc_close_encoder (encoder);
560 /* set up encoder parameters */
561 encoder->x264param.i_threads = encoder->threads;
562 encoder->x264param.i_fps_num = encoder->framerate_num;
563 encoder->x264param.i_fps_den = encoder->framerate_den;
564 encoder->x264param.i_width = encoder->width;
565 encoder->x264param.i_height = encoder->height;
566 if (encoder->par_den > 0) {
567 encoder->x264param.vui.i_sar_width = encoder->par_num;
568 encoder->x264param.vui.i_sar_height = encoder->par_den;
569 }
570 encoder->x264param.i_keyint_max = encoder->keyint_max ? encoder->keyint_max :
571 (2 * encoder->framerate_num / encoder->framerate_den);
572 encoder->x264param.b_cabac = encoder->cabac;
573 encoder->x264param.b_aud = 1;
574 encoder->x264param.i_sps_id = encoder->sps_id;
575 if ((((encoder->height == 576) && ((encoder->width == 720)
576 || (encoder->width == 704) || (encoder->width == 352)))
577 || ((encoder->height == 288) && (encoder->width == 352)))
578 && (encoder->framerate_den == 1) && (encoder->framerate_num == 25)) {
579 encoder->x264param.vui.i_vidformat = 1; /* PAL */
580 } else if ((((encoder->height == 480) && ((encoder->width == 720)
581 || (encoder->width == 704) || (encoder->width == 352)))
582 || ((encoder->height == 240) && (encoder->width == 352)))
583 && (encoder->framerate_den == 1001) && ((encoder->framerate_num == 30000)
584 || (encoder->framerate_num == 24000))) {
585 encoder->x264param.vui.i_vidformat = 2; /* NTSC */
586 } else
587 encoder->x264param.vui.i_vidformat = 5; /* unspecified */
588 encoder->x264param.analyse.i_trellis = encoder->trellis ? 1 : 0;
589 encoder->x264param.analyse.b_psnr = 0;
590 /*encoder->x264param.analyse.b_ssim = 0; */
591 encoder->x264param.analyse.i_me_method = encoder->me;
592 encoder->x264param.analyse.i_subpel_refine = encoder->subme;
593 encoder->x264param.analyse.inter = encoder->analyse;
594 encoder->x264param.analyse.b_transform_8x8 = encoder->dct8x8;
595 encoder->x264param.analyse.b_weighted_bipred = encoder->weightb;
596 /*encoder->x264param.analyse.i_noise_reduction = 600; */
597 encoder->x264param.i_frame_reference = encoder->ref;
598 encoder->x264param.i_bframe = encoder->bframes;
599 encoder->x264param.b_bframe_pyramid = encoder->b_pyramid;
600 encoder->x264param.b_bframe_adaptive = 0;
601 encoder->x264param.b_deblocking_filter = 1;
602 encoder->x264param.i_deblocking_filter_alphac0 = 0;
603 encoder->x264param.i_deblocking_filter_beta = 0;
604 #ifdef X264_RC_ABR
605 encoder->x264param.rc.i_rc_method = X264_RC_ABR;
606 #endif
607 encoder->x264param.rc.i_bitrate = encoder->bitrate;
608 encoder->x264param.rc.i_vbv_max_bitrate = encoder->bitrate;
609 encoder->x264param.rc.i_vbv_buffer_size
610 = encoder->x264param.rc.i_vbv_max_bitrate
611 * encoder->vbv_buf_capacity / 1000;
613 switch (encoder->pass) {
614 case 0:
615 encoder->x264param.rc.b_stat_read = 0;
616 encoder->x264param.rc.b_stat_write = 0;
617 break;
618 case 1:
619 /* Turbo mode parameters. */
620 encoder->x264param.i_frame_reference = (encoder->ref + 1) >> 1;
621 encoder->x264param.analyse.i_subpel_refine =
622 CLAMP (encoder->subme - 1, 1, 3);
623 encoder->x264param.analyse.inter &= ~X264_ANALYSE_PSUB8x8;
624 encoder->x264param.analyse.inter &= ~X264_ANALYSE_BSUB16x16;
625 encoder->x264param.analyse.i_trellis = 0;
627 encoder->x264param.rc.b_stat_read = 0;
628 encoder->x264param.rc.b_stat_write = 1;
629 break;
630 case 2:
631 encoder->x264param.rc.b_stat_read = 1;
632 encoder->x264param.rc.b_stat_write = 1;
633 break;
634 case 3:
635 encoder->x264param.rc.b_stat_read = 1;
636 encoder->x264param.rc.b_stat_write = 0;
637 break;
638 }
639 encoder->x264param.rc.psz_stat_in = encoder->stats_file;
640 encoder->x264param.rc.psz_stat_out = encoder->stats_file;
642 encoder->x264enc = x264_encoder_open (&encoder->x264param);
643 if (!encoder->x264enc) {
644 GST_ELEMENT_ERROR (encoder, STREAM, ENCODE,
645 ("Can not initialize x264 encoder."), (""));
646 return FALSE;
647 }
649 return TRUE;
650 }
652 /* gst_x264_enc_close_encoder
653 * @encoder: Encoder which should close.
654 *
655 * Close x264 encoder.
656 */
657 static void
658 gst_x264_enc_close_encoder (GstX264Enc * encoder)
659 {
660 if (encoder->x264enc != NULL) {
661 x264_encoder_close (encoder->x264enc);
662 encoder->x264enc = NULL;
663 }
664 }
666 static void
667 gst_x264_enc_dispose (GObject * object)
668 {
669 GstX264Enc *encoder = GST_X264_ENC (object);
671 g_free (encoder->stats_file);
672 encoder->stats_file = NULL;
673 g_free (encoder->buffer);
674 encoder->buffer = NULL;
676 gst_x264_enc_timestamp_queue_free (encoder);
677 gst_x264_enc_close_encoder (encoder);
679 G_OBJECT_CLASS (parent_class)->dispose (object);
680 }
682 static gboolean
683 gst_x264_enc_sink_event (GstPad * pad, GstEvent * event)
684 {
685 gboolean ret;
686 GstX264Enc *encoder;
688 encoder = GST_X264_ENC (gst_pad_get_parent (pad));
690 switch (GST_EVENT_TYPE (event)) {
691 case GST_EVENT_EOS:{
692 GstFlowReturn flow_ret;
693 int i_nal;
695 /* first send the rest NAL units */
696 do {
697 flow_ret = gst_x264_enc_encode_frame (encoder, NULL, &i_nal);
698 } while (flow_ret == GST_FLOW_OK && i_nal > 0);
700 /* then push the EOS downstream */
701 ret = gst_pad_push_event (encoder->srcpad, event);
702 break;
703 }
704 default:
705 ret = gst_pad_push_event (encoder->srcpad, event);
706 break;
707 }
708 gst_object_unref (encoder);
709 return ret;
710 }
712 /* chain function
713 * this function does the actual processing
714 */
716 static GstFlowReturn
717 gst_x264_enc_chain (GstPad * pad, GstBuffer * buf)
718 {
719 GstX264Enc *encoder = GST_X264_ENC (GST_OBJECT_PARENT (pad));
720 GstFlowReturn ret;
721 x264_picture_t pic_in;
722 int i_nal;
724 if (G_UNLIKELY (encoder->x264enc == NULL))
725 goto not_inited;
727 /* create x264_picture_t from the buffer */
728 /* mostly taken from mplayer (file ve_x264.c) */
729 /* FIXME: this looks wrong for odd widths/heights (tpm) */
730 if (G_UNLIKELY (GST_BUFFER_SIZE (buf) < encoder->luma_plane_size * 6 / 4))
731 goto wrong_buffer_size;
733 /* ignore duplicated packets */
734 if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buf))) {
735 if (GST_CLOCK_TIME_IS_VALID (encoder->last_timestamp)) {
736 GstClockTimeDiff diff =
737 GST_BUFFER_TIMESTAMP (buf) - encoder->last_timestamp;
738 if (diff <= 0) {
739 GST_ELEMENT_WARNING (encoder, STREAM, ENCODE,
740 ("Duplicated packet in input, dropping"),
741 ("Time difference was -%" GST_TIME_FORMAT, GST_TIME_ARGS (-diff)));
742 gst_buffer_unref (buf);
743 return GST_FLOW_OK;
744 }
745 }
746 encoder->last_timestamp = GST_BUFFER_TIMESTAMP (buf);
747 }
749 /* remember the timestamp and duration */
750 gst_x264_enc_timestamp_queue_put (encoder, GST_BUFFER_TIMESTAMP (buf),
751 GST_BUFFER_DURATION (buf));
753 memset (&pic_in, 0, sizeof (x264_picture_t));
755 pic_in.img.i_csp = X264_CSP_I420;
756 pic_in.img.i_plane = 3;
758 /* FIXME: again, this looks wrong for odd widths/heights (tpm) */
759 pic_in.img.plane[0] = (guint8 *) (GST_BUFFER_DATA (buf));
760 pic_in.img.i_stride[0] = encoder->stride;
762 pic_in.img.plane[1] = pic_in.img.plane[0]
763 + encoder->luma_plane_size;
764 pic_in.img.i_stride[1] = encoder->stride / 2;
766 pic_in.img.plane[2] = pic_in.img.plane[1]
767 + encoder->luma_plane_size / 4;
768 pic_in.img.i_stride[2] = encoder->stride / 2;
770 pic_in.img.plane[3] = NULL;
771 pic_in.img.i_stride[3] = 0;
773 pic_in.i_type = X264_TYPE_AUTO;
774 pic_in.i_pts = GST_BUFFER_TIMESTAMP (buf);
776 ret = gst_x264_enc_encode_frame (encoder, &pic_in, &i_nal);
777 gst_buffer_unref (buf);
778 return ret;
780 /* ERRORS */
781 not_inited:
782 {
783 GST_WARNING_OBJECT (encoder, "Got buffer before set_caps was called");
784 gst_buffer_unref (buf);
785 return GST_FLOW_NOT_NEGOTIATED;
786 }
787 wrong_buffer_size:
788 {
789 GST_ELEMENT_ERROR (encoder, STREAM, ENCODE,
790 ("Encode x264 frame failed."),
791 ("Wrong buffer size %d (should be %d)",
792 GST_BUFFER_SIZE (buf), encoder->luma_plane_size * 6 / 4));
793 gst_buffer_unref (buf);
794 return GST_FLOW_ERROR;
795 }
796 }
798 static GstFlowReturn
799 gst_x264_enc_encode_frame (GstX264Enc * encoder, x264_picture_t * pic_in,
800 int *i_nal)
801 {
802 GstBuffer *out_buf = NULL;
803 x264_picture_t pic_out;
804 x264_nal_t *nal;
805 int i_size;
806 int nal_size;
807 int encoder_return;
808 gint i;
809 GstFlowReturn ret;
810 GstClockTime timestamp;
811 GstClockTime duration;
813 if (G_UNLIKELY (encoder->x264enc == NULL))
814 return GST_FLOW_NOT_NEGOTIATED;
816 encoder_return = x264_encoder_encode (encoder->x264enc,
817 &nal, i_nal, pic_in, &pic_out);
819 if (encoder_return < 0) {
820 GST_ELEMENT_ERROR (encoder, STREAM, ENCODE,
821 ("Encode x264 frame failed."),
822 ("x264_encoder_encode return code=%d", encoder_return));
823 return GST_FLOW_ERROR;
824 }
826 if (!*i_nal) {
827 return GST_FLOW_OK;
828 }
830 i_size = 0;
831 for (i = 0; i < *i_nal; i++) {
832 int i_data = encoder->buffer_size - i_size - 4;
834 if (i_data < encoder->buffer_size / 2) {
835 encoder->buffer_size *= 2;
836 encoder->buffer = g_realloc (encoder->buffer, encoder->buffer_size);
837 i_data = encoder->buffer_size - i_size;
838 }
840 nal_size =
841 x264_nal_encode (encoder->buffer + i_size + 4, &i_data, 0, &nal[i]);
842 if (encoder->byte_stream) {
843 encoder->buffer[i_size + 0] = 0;
844 encoder->buffer[i_size + 1] = 0;
845 encoder->buffer[i_size + 2] = 0;
846 encoder->buffer[i_size + 3] = 1;
847 } else {
848 encoder->buffer[i_size + 0] = (nal_size >> 24) & 0xff;
849 encoder->buffer[i_size + 1] = (nal_size >> 16) & 0xff;
850 encoder->buffer[i_size + 2] = (nal_size >> 8) & 0xff;
851 encoder->buffer[i_size + 3] = nal_size & 0xff;
852 }
854 i_size += nal_size + 4;
855 }
857 ret = gst_pad_alloc_buffer (encoder->srcpad, GST_BUFFER_OFFSET_NONE,
858 i_size, GST_PAD_CAPS (encoder->srcpad), &out_buf);
859 if (ret != GST_FLOW_OK)
860 return ret;
862 memcpy (GST_BUFFER_DATA (out_buf), encoder->buffer, i_size);
863 GST_BUFFER_SIZE (out_buf) = i_size;
865 gst_x264_enc_timestamp_queue_get (encoder, ×tamp, &duration);
867 /* PTS */
868 GST_BUFFER_TIMESTAMP (out_buf) = pic_out.i_pts;
869 if (encoder->bframes) {
870 /* When using B-frames, the frames will be reordered.
871 Make PTS start one frame after DTS. */
872 GST_BUFFER_TIMESTAMP (out_buf)
873 += GST_SECOND * encoder->framerate_den / encoder->framerate_num;
874 }
876 GST_BUFFER_DURATION (out_buf) = duration;
878 if (pic_out.i_type == X264_TYPE_IDR) {
879 GST_BUFFER_FLAG_UNSET (out_buf, GST_BUFFER_FLAG_DELTA_UNIT);
880 } else {
881 GST_BUFFER_FLAG_SET (out_buf, GST_BUFFER_FLAG_DELTA_UNIT);
882 }
884 return gst_pad_push (encoder->srcpad, out_buf);
885 }
887 static GstStateChangeReturn
888 gst_x264_enc_change_state (GstElement * element, GstStateChange transition)
889 {
890 GstX264Enc *encoder = GST_X264_ENC (element);
891 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
893 ret = parent_class->change_state (element, transition);
894 if (ret == GST_STATE_CHANGE_FAILURE)
895 goto out;
897 switch (transition) {
898 case GST_STATE_CHANGE_READY_TO_NULL:
899 gst_x264_enc_close_encoder (encoder);
900 break;
901 default:
902 break;
903 }
905 out:
906 return ret;
907 }
909 static void
910 gst_x264_enc_set_property (GObject * object, guint prop_id,
911 const GValue * value, GParamSpec * pspec)
912 {
913 GstX264Enc *encoder;
915 encoder = GST_X264_ENC (object);
917 /* FIXME: should probably do locking or check state */
918 switch (prop_id) {
919 case ARG_THREADS:
920 encoder->threads = g_value_get_uint (value);
921 break;
922 case ARG_PASS:
923 encoder->pass = g_value_get_uint (value);
924 break;
925 case ARG_STATS_FILE:
926 if (encoder->stats_file)
927 g_free (encoder->stats_file);
928 encoder->stats_file = g_value_dup_string (value);
929 break;
930 case ARG_BYTE_STREAM:
931 encoder->byte_stream = g_value_get_boolean (value);
932 break;
933 case ARG_BITRATE:
934 encoder->bitrate = g_value_get_uint (value);
935 break;
936 case ARG_VBV_BUF_CAPACITY:
937 encoder->vbv_buf_capacity = g_value_get_uint (value);
938 break;
939 case ARG_ME:
940 encoder->me = g_value_get_enum (value);
941 break;
942 case ARG_SUBME:
943 encoder->subme = g_value_get_uint (value);
944 break;
945 case ARG_ANALYSE:
946 encoder->analyse = g_value_get_flags (value);
947 break;
948 case ARG_DCT8x8:
949 encoder->dct8x8 = g_value_get_boolean (value);
950 break;
951 case ARG_REF:
952 encoder->ref = g_value_get_uint (value);
953 break;
954 case ARG_BFRAMES:
955 encoder->bframes = g_value_get_uint (value);
956 gst_x264_enc_timestamp_queue_free (encoder);
957 gst_x264_enc_timestamp_queue_init (encoder);
958 break;
959 case ARG_B_PYRAMID:
960 encoder->b_pyramid = g_value_get_boolean (value);
961 break;
962 case ARG_WEIGHTB:
963 encoder->weightb = g_value_get_boolean (value);
964 break;
965 case ARG_SPS_ID:
966 encoder->sps_id = g_value_get_uint (value);
967 break;
968 case ARG_TRELLIS:
969 encoder->trellis = g_value_get_boolean (value);
970 break;
971 case ARG_KEYINT_MAX:
972 encoder->keyint_max = g_value_get_uint (value);
973 break;
974 case ARG_CABAC:
975 encoder->cabac = g_value_get_boolean (value);
976 break;
977 default:
978 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
979 break;
980 }
981 }
983 static void
984 gst_x264_enc_get_property (GObject * object, guint prop_id,
985 GValue * value, GParamSpec * pspec)
986 {
987 GstX264Enc *encoder;
989 encoder = GST_X264_ENC (object);
991 /* FIXME: should probably do locking or check state */
992 switch (prop_id) {
993 case ARG_THREADS:
994 g_value_set_uint (value, encoder->threads);
995 break;
996 case ARG_PASS:
997 g_value_set_uint (value, encoder->pass);
998 break;
999 case ARG_STATS_FILE:
1000 g_value_set_string (value, encoder->stats_file);
1001 break;
1002 case ARG_BYTE_STREAM:
1003 g_value_set_boolean (value, encoder->byte_stream);
1004 break;
1005 case ARG_BITRATE:
1006 g_value_set_uint (value, encoder->bitrate);
1007 break;
1008 case ARG_VBV_BUF_CAPACITY:
1009 g_value_set_uint (value, encoder->vbv_buf_capacity);
1010 break;
1011 case ARG_ME:
1012 g_value_set_enum (value, encoder->me);
1013 break;
1014 case ARG_SUBME:
1015 g_value_set_uint (value, encoder->subme);
1016 break;
1017 case ARG_ANALYSE:
1018 g_value_set_flags (value, encoder->analyse);
1019 break;
1020 case ARG_DCT8x8:
1021 g_value_set_boolean (value, encoder->dct8x8);
1022 break;
1023 case ARG_REF:
1024 g_value_set_uint (value, encoder->ref);
1025 break;
1026 case ARG_BFRAMES:
1027 g_value_set_uint (value, encoder->bframes);
1028 break;
1029 case ARG_B_PYRAMID:
1030 g_value_set_boolean (value, encoder->b_pyramid);
1031 break;
1032 case ARG_WEIGHTB:
1033 g_value_set_boolean (value, encoder->weightb);
1034 break;
1035 case ARG_SPS_ID:
1036 g_value_set_uint (value, encoder->sps_id);
1037 break;
1038 case ARG_TRELLIS:
1039 g_value_set_boolean (value, encoder->trellis);
1040 break;
1041 case ARG_KEYINT_MAX:
1042 g_value_set_uint (value, encoder->keyint_max);
1043 break;
1044 case ARG_CABAC:
1045 g_value_set_boolean (value, encoder->cabac);
1046 break;
1047 default:
1048 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1049 break;
1050 }
1051 }
1053 static gboolean
1054 plugin_init (GstPlugin * plugin)
1055 {
1056 return gst_element_register (plugin, "x264enc",
1057 GST_RANK_NONE, GST_TYPE_X264_ENC);
1058 }
1060 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
1061 GST_VERSION_MINOR,
1062 "x264",
1063 "libx264-based H264 plugins",
1064 plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)