2 * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * SECTION:element-theoraenc
22 * @see_also: theoradec, oggmux
24 * This element encodes raw video into a Theora stream.
25 * <ulink url="http://www.theora.org/">Theora</ulink> is a royalty-free
26 * video codec maintained by the <ulink url="http://www.xiph.org/">Xiph.org
27 * Foundation</ulink>, based on the VP3 codec.
29 * The theora codec internally only supports encoding of images that are a
30 * multiple of 16 pixels in both X and Y direction. It is however perfectly
31 * possible to encode images with other dimensions because an arbitrary
32 * rectangular cropping region can be set up. This element will automatically
33 * set up a correct cropping region if the dimensions are not multiples of 16
36 * To control the quality of the encoding, the #GstTheoraEnc::bitrate and
37 * #GstTheoraEnc::quality properties can be used. These two properties are
38 * mutualy exclusive. Setting the bitrate property will produce a constant
39 * bitrate (CBR) stream while setting the quality property will produce a
40 * variable bitrate (VBR) stream.
43 * <title>Example pipeline</title>
45 * gst-launch -v videotestsrc num-buffers=1000 ! theoraenc ! oggmux ! filesink location=videotestsrc.ogg
46 * ]| This example pipeline will encode a test video source to theora muxed in an
47 * ogg container. Refer to the theoradec documentation to decode the create
51 * Last reviewed on 2006-03-01 (0.10.4)
58 #include "gsttheoraenc.h"
61 #include <stdlib.h> /* free */
63 #include <gst/tag/tag.h>
64 #include <gst/video/video.h>
66 #define GST_CAT_DEFAULT theoraenc_debug
67 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
69 #define GST_TYPE_BORDER_MODE (gst_border_mode_get_type())
71 gst_border_mode_get_type (void)
73 static GType border_mode_type = 0;
74 static const GEnumValue border_mode[] = {
75 {BORDER_NONE, "No Border", "none"},
76 {BORDER_BLACK, "Black Border", "black"},
77 {BORDER_MIRROR, "Mirror image in borders", "mirror"},
81 if (!border_mode_type) {
83 g_enum_register_static ("GstTheoraEncBorderMode", border_mode);
85 return border_mode_type;
88 /* taken from theora/lib/toplevel.c */
90 _ilog (unsigned int v)
101 #define THEORA_DEF_BITRATE 0
102 #define THEORA_DEF_QUALITY 48
103 #define THEORA_DEF_KEYFRAME_AUTO TRUE
104 #define THEORA_DEF_KEYFRAME_FREQ 64
105 #define THEORA_DEF_KEYFRAME_FREQ_FORCE 64
106 #define THEORA_DEF_SPEEDLEVEL 1
107 #define THEORA_DEF_VP3_COMPATIBLE FALSE
108 #define THEORA_DEF_DROP_FRAMES TRUE
109 #define THEORA_DEF_CAP_OVERFLOW TRUE
110 #define THEORA_DEF_CAP_UNDERFLOW FALSE
111 #define THEORA_DEF_RATE_BUFFER 0
122 ARG_KEYFRAME_FREQ_FORCE,
123 ARG_KEYFRAME_THRESHOLD,
124 ARG_KEYFRAME_MINDISTANCE,
125 ARG_NOISE_SENSITIVITY,
136 /* this function does a straight granulepos -> timestamp conversion */
138 granulepos_to_timestamp (GstTheoraEnc * theoraenc, ogg_int64_t granulepos)
140 guint64 iframe, pframe;
141 int shift = theoraenc->info.keyframe_granule_shift;
144 return GST_CLOCK_TIME_NONE;
146 iframe = granulepos >> shift;
147 pframe = granulepos - (iframe << shift);
149 /* num and den are 32 bit, so we can safely multiply with GST_SECOND */
150 return gst_util_uint64_scale ((guint64) (iframe + pframe),
151 GST_SECOND * theoraenc->info.fps_denominator,
152 theoraenc->info.fps_numerator);
155 static const GstElementDetails theora_enc_details =
156 GST_ELEMENT_DETAILS ("Theora video encoder",
157 "Codec/Encoder/Video",
158 "encode raw YUV video to a theora stream",
159 "Wim Taymans <wim@fluendo.com>");
161 static GstStaticPadTemplate theora_enc_sink_factory =
162 GST_STATIC_PAD_TEMPLATE ("sink",
165 GST_STATIC_CAPS ("video/x-raw-yuv, "
166 "format = (fourcc) { I420, Y42B, Y444 }, "
167 "framerate = (fraction) [0/1, MAX], "
168 "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
171 static GstStaticPadTemplate theora_enc_src_factory =
172 GST_STATIC_PAD_TEMPLATE ("src",
175 GST_STATIC_CAPS ("video/x-theora")
179 _do_init (GType object_type)
181 const GInterfaceInfo preset_interface_info = {
182 NULL, /* interface_init */
183 NULL, /* interface_finalize */
184 NULL /* interface_data */
187 g_type_add_interface_static (object_type, GST_TYPE_PRESET,
188 &preset_interface_info);
191 GST_BOILERPLATE_FULL (GstTheoraEnc, gst_theora_enc, GstElement,
192 GST_TYPE_ELEMENT, _do_init);
194 static gboolean theora_enc_sink_event (GstPad * pad, GstEvent * event);
195 static gboolean theora_enc_src_event (GstPad * pad, GstEvent * event);
196 static GstFlowReturn theora_enc_chain (GstPad * pad, GstBuffer * buffer);
197 static GstStateChangeReturn theora_enc_change_state (GstElement * element,
198 GstStateChange transition);
199 static GstCaps *theora_enc_sink_getcaps (GstPad * pad);
200 static gboolean theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps);
201 static void theora_enc_get_property (GObject * object, guint prop_id,
202 GValue * value, GParamSpec * pspec);
203 static void theora_enc_set_property (GObject * object, guint prop_id,
204 const GValue * value, GParamSpec * pspec);
205 static void theora_enc_finalize (GObject * object);
208 gst_theora_enc_base_init (gpointer g_class)
210 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
212 gst_element_class_add_pad_template (element_class,
213 gst_static_pad_template_get (&theora_enc_src_factory));
214 gst_element_class_add_pad_template (element_class,
215 gst_static_pad_template_get (&theora_enc_sink_factory));
216 gst_element_class_set_details (element_class, &theora_enc_details);
220 gst_theora_enc_class_init (GstTheoraEncClass * klass)
222 GObjectClass *gobject_class = (GObjectClass *) klass;
223 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
225 gobject_class->set_property = theora_enc_set_property;
226 gobject_class->get_property = theora_enc_get_property;
227 gobject_class->finalize = theora_enc_finalize;
229 g_object_class_install_property (gobject_class, ARG_CENTER,
230 g_param_spec_boolean ("center", "Center",
231 "ignored and kept for API compat only", TRUE,
232 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
233 g_object_class_install_property (gobject_class, ARG_BORDER,
234 g_param_spec_enum ("border", "Border",
235 "ignored and kept for API compat only",
236 GST_TYPE_BORDER_MODE, BORDER_BLACK,
237 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
238 /* general encoding stream options */
239 g_object_class_install_property (gobject_class, ARG_BITRATE,
240 g_param_spec_int ("bitrate", "Bitrate", "Compressed video bitrate (kbps)",
241 0, (1 << 24) - 1, THEORA_DEF_BITRATE,
242 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
243 g_object_class_install_property (gobject_class, ARG_QUALITY,
244 g_param_spec_int ("quality", "Quality", "Video quality", 0, 63,
246 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
247 g_object_class_install_property (gobject_class, ARG_QUICK,
248 g_param_spec_boolean ("quick", "Quick",
249 "ignored and kept for API compat only", TRUE,
250 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
251 g_object_class_install_property (gobject_class, ARG_KEYFRAME_AUTO,
252 g_param_spec_boolean ("keyframe-auto", "Keyframe Auto",
253 "Automatic keyframe detection", THEORA_DEF_KEYFRAME_AUTO,
254 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
255 g_object_class_install_property (gobject_class, ARG_KEYFRAME_FREQ,
256 g_param_spec_int ("keyframe-freq", "Keyframe frequency",
257 "Keyframe frequency", 1, 32768, THEORA_DEF_KEYFRAME_FREQ,
258 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
259 g_object_class_install_property (gobject_class, ARG_KEYFRAME_FREQ_FORCE,
260 g_param_spec_int ("keyframe-force", "Keyframe force",
261 "Force keyframe every N frames", 1, 32768,
262 THEORA_DEF_KEYFRAME_FREQ_FORCE,
263 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
264 g_object_class_install_property (gobject_class, ARG_KEYFRAME_THRESHOLD,
265 g_param_spec_int ("keyframe-threshold", "Keyframe threshold",
266 "ignored and kept for API compat only", 0, 32768, 80,
267 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
268 g_object_class_install_property (gobject_class, ARG_KEYFRAME_MINDISTANCE,
269 g_param_spec_int ("keyframe-mindistance", "Keyframe mindistance",
270 "ignored and kept for API compat only", 1, 32768, 8,
271 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
272 g_object_class_install_property (gobject_class, ARG_NOISE_SENSITIVITY,
273 g_param_spec_int ("noise-sensitivity", "Noise sensitivity",
274 "ignored and kept for API compat only", 0, 32768, 1,
275 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
276 g_object_class_install_property (gobject_class, ARG_SHARPNESS,
277 g_param_spec_int ("sharpness", "Sharpness",
278 "ignored and kept for API compat only", 0, 2, 0,
279 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
280 g_object_class_install_property (gobject_class, ARG_SPEEDLEVEL,
281 g_param_spec_int ("speed-level", "Speed level",
282 "Controls the amount of motion vector searching done while "
283 "encoding. This property requires libtheora version >= 1.0",
284 0, 2, THEORA_DEF_SPEEDLEVEL,
285 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
286 g_object_class_install_property (gobject_class, ARG_VP3_COMPATIBLE,
287 g_param_spec_boolean ("vp3-compatible", "VP3 Compatible",
288 "Disables non-VP3 compatible features."
289 " This property requires libtheora version >= 1.1",
290 THEORA_DEF_VP3_COMPATIBLE,
291 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
292 g_object_class_install_property (gobject_class, ARG_DROP_FRAMES,
293 g_param_spec_boolean ("drop-frames", "VP3 Compatible",
294 "Allow or disallow frame dropping."
295 " This property requires libtheora version >= 1.1",
296 THEORA_DEF_DROP_FRAMES,
297 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
298 g_object_class_install_property (gobject_class, ARG_CAP_OVERFLOW,
299 g_param_spec_boolean ("cap-overflow", "VP3 Compatible",
300 "Enable capping of bit reservoir overflows."
301 " This property requires libtheora version >= 1.1",
302 THEORA_DEF_CAP_OVERFLOW,
303 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
304 g_object_class_install_property (gobject_class, ARG_CAP_UNDERFLOW,
305 g_param_spec_boolean ("cap-underflow", "VP3 Compatible",
306 "Enable capping of bit reservoir underflows."
307 " This property requires libtheora version >= 1.1",
308 THEORA_DEF_CAP_UNDERFLOW,
309 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
310 g_object_class_install_property (gobject_class, ARG_RATE_BUFFER,
311 g_param_spec_int ("rate-buffer", "Rate Control Buffer",
312 "Sets the size of the rate control buffer, in units of frames. "
313 "The default value of 0 instructs the encoder to automatically "
314 "select an appropriate value."
315 " This property requires libtheora version >= 1.1",
316 0, 1000, THEORA_DEF_RATE_BUFFER,
317 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
319 gstelement_class->change_state = theora_enc_change_state;
320 GST_DEBUG_CATEGORY_INIT (theoraenc_debug, "theoraenc", 0, "Theora encoder");
324 gst_theora_enc_init (GstTheoraEnc * enc, GstTheoraEncClass * g_class)
327 gst_pad_new_from_static_template (&theora_enc_sink_factory, "sink");
328 gst_pad_set_chain_function (enc->sinkpad, theora_enc_chain);
329 gst_pad_set_event_function (enc->sinkpad, theora_enc_sink_event);
330 gst_pad_set_getcaps_function (enc->sinkpad, theora_enc_sink_getcaps);
331 gst_pad_set_setcaps_function (enc->sinkpad, theora_enc_sink_setcaps);
332 gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad);
335 gst_pad_new_from_static_template (&theora_enc_src_factory, "src");
336 gst_pad_set_event_function (enc->srcpad, theora_enc_src_event);
337 gst_element_add_pad (GST_ELEMENT (enc), enc->srcpad);
339 gst_segment_init (&enc->segment, GST_FORMAT_UNDEFINED);
341 enc->video_bitrate = THEORA_DEF_BITRATE;
342 enc->video_quality = THEORA_DEF_QUALITY;
343 enc->keyframe_auto = THEORA_DEF_KEYFRAME_AUTO;
344 enc->keyframe_freq = THEORA_DEF_KEYFRAME_FREQ;
345 enc->keyframe_force = THEORA_DEF_KEYFRAME_FREQ_FORCE;
347 enc->expected_ts = GST_CLOCK_TIME_NONE;
349 enc->speed_level = THEORA_DEF_SPEEDLEVEL;
350 enc->vp3_compatible = THEORA_DEF_VP3_COMPATIBLE;
351 enc->drop_frames = THEORA_DEF_DROP_FRAMES;
352 enc->cap_overflow = THEORA_DEF_CAP_OVERFLOW;
353 enc->cap_underflow = THEORA_DEF_CAP_UNDERFLOW;
354 enc->rate_buffer = THEORA_DEF_RATE_BUFFER;
358 theora_enc_finalize (GObject * object)
360 GstTheoraEnc *enc = GST_THEORA_ENC (object);
362 GST_DEBUG_OBJECT (enc, "Finalizing");
364 th_encode_free (enc->encoder);
365 th_comment_clear (&enc->comment);
366 th_info_clear (&enc->info);
368 G_OBJECT_CLASS (parent_class)->finalize (object);
372 theora_enc_reset (GstTheoraEnc * enc)
374 ogg_uint32_t keyframe_force;
378 th_encode_free (enc->encoder);
379 enc->encoder = th_encode_alloc (&enc->info);
380 /* We ensure this function cannot fail. */
381 g_assert (enc->encoder != NULL);
382 #ifdef TH_ENCCTL_SET_SPLEVEL
383 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_SPLEVEL, &enc->speed_level,
384 sizeof (enc->speed_level));
386 #ifdef TH_ENCCTL_SET_VP3_COMPATIBLE
387 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_VP3_COMPATIBLE,
388 &enc->vp3_compatible, sizeof (enc->vp3_compatible));
392 #ifdef TH_ENCCTL_SET_RATE_FLAGS
393 if (enc->drop_frames)
394 rate_flags |= TH_RATECTL_DROP_FRAMES;
395 if (enc->drop_frames)
396 rate_flags |= TH_RATECTL_CAP_OVERFLOW;
397 if (enc->drop_frames)
398 rate_flags |= TH_RATECTL_CAP_UNDERFLOW;
399 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_FLAGS,
400 &rate_flags, sizeof (rate_flags));
403 #ifdef TH_ENCCTL_SET_RATE_BUFFER
404 if (enc->rate_buffer) {
405 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_BUFFER,
406 &enc->rate_buffer, sizeof (enc->rate_buffer));
412 keyframe_force = enc->keyframe_auto ?
413 enc->keyframe_force : enc->keyframe_freq;
414 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
415 &keyframe_force, sizeof (keyframe_force));
419 theora_enc_clear (GstTheoraEnc * enc)
423 enc->granulepos_offset = 0;
424 enc->timestamp_offset = 0;
426 enc->next_ts = GST_CLOCK_TIME_NONE;
427 enc->next_discont = FALSE;
428 enc->expected_ts = GST_CLOCK_TIME_NONE;
432 theora_enc_get_supported_formats (void)
438 th_pixel_fmt pixelformat;
442 TH_PF_420, "I420"}, {
443 TH_PF_422, "Y42B"}, {
446 GString *string = NULL;
449 th_info_init (&info);
450 info.frame_width = 16;
451 info.frame_height = 16;
452 info.fps_numerator = 25;
453 info.fps_denominator = 1;
454 for (i = 0; i < G_N_ELEMENTS (formats); i++) {
455 info.pixel_fmt = formats[i].pixelformat;
457 encoder = th_encode_alloc (&info);
461 GST_LOG ("format %s is supported", formats[i].fourcc);
462 th_encode_free (encoder);
464 if (string == NULL) {
465 string = g_string_new (formats[i].fourcc);
467 g_string_append (string, ", ");
468 g_string_append (string, formats[i].fourcc);
471 th_info_clear (&info);
473 return string == NULL ? NULL : g_string_free (string, FALSE);
477 theora_enc_sink_getcaps (GstPad * pad)
480 char *supported_formats, *caps_string;
482 supported_formats = theora_enc_get_supported_formats ();
483 if (!supported_formats) {
484 GST_WARNING ("no supported formats found. Encoder disabled?");
485 return gst_caps_new_empty ();
488 caps_string = g_strdup_printf ("video/x-raw-yuv, "
489 "format = (fourcc) { %s }, "
490 "framerate = (fraction) [0/1, MAX], "
491 "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]",
493 caps = gst_caps_from_string (caps_string);
494 g_free (caps_string);
495 g_free (supported_formats);
496 GST_DEBUG ("Supported caps: %" GST_PTR_FORMAT, caps);
502 theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
504 GstStructure *structure = gst_caps_get_structure (caps, 0);
505 GstTheoraEnc *enc = GST_THEORA_ENC (gst_pad_get_parent (pad));
510 gst_structure_get_fourcc (structure, "format", &fourcc);
511 gst_structure_get_int (structure, "width", &enc->width);
512 gst_structure_get_int (structure, "height", &enc->height);
513 gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d);
514 par = gst_structure_get_value (structure, "pixel-aspect-ratio");
516 th_info_clear (&enc->info);
517 th_info_init (&enc->info);
518 /* Theora has a divisible-by-sixteen restriction for the encoded video size but
519 * we can define a picture area using pic_width/pic_height */
520 enc->info.frame_width = GST_ROUND_UP_16 (enc->width);
521 enc->info.frame_height = GST_ROUND_UP_16 (enc->height);
522 enc->info.pic_width = enc->width;
523 enc->info.pic_height = enc->height;
525 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
526 enc->info.pixel_fmt = TH_PF_420;
528 case GST_MAKE_FOURCC ('Y', '4', '2', 'B'):
529 enc->info.pixel_fmt = TH_PF_422;
531 case GST_MAKE_FOURCC ('Y', '4', '4', '4'):
532 enc->info.pixel_fmt = TH_PF_444;
535 g_assert_not_reached ();
538 enc->info.fps_numerator = enc->fps_n = fps_n;
539 enc->info.fps_denominator = enc->fps_d = fps_d;
541 enc->info.aspect_numerator = gst_value_get_fraction_numerator (par);
542 enc->info.aspect_denominator = gst_value_get_fraction_denominator (par);
544 /* setting them to 0 indicates that the decoder can chose a good aspect
545 * ratio, defaulting to 1/1 */
546 enc->info.aspect_numerator = 0;
547 enc->info.aspect_denominator = 0;
550 enc->info.colorspace = TH_CS_UNSPECIFIED;
551 enc->info.target_bitrate = enc->video_bitrate;
552 enc->info.quality = enc->video_quality;
554 /* as done in theora */
555 enc->info.keyframe_granule_shift = _ilog (enc->keyframe_force - 1);
556 GST_DEBUG_OBJECT (enc,
557 "keyframe_frequency_force is %d, granule shift is %d",
558 enc->keyframe_force, enc->info.keyframe_granule_shift);
560 theora_enc_reset (enc);
561 enc->initialised = TRUE;
563 gst_object_unref (enc);
569 granulepos_add (guint64 granulepos, guint64 addend, gint shift)
571 guint64 iframe, pframe;
573 iframe = granulepos >> shift;
574 pframe = granulepos - (iframe << shift);
577 return (iframe << shift) + pframe;
580 /* prepare a buffer for transmission by passing data through libtheora */
582 theora_buffer_from_packet (GstTheoraEnc * enc, ogg_packet * packet,
583 GstClockTime timestamp, GstClockTime running_time,
584 GstClockTime duration, GstBuffer ** buffer)
587 GstFlowReturn ret = GST_FLOW_OK;
589 buf = gst_buffer_new_and_alloc (packet->bytes);
591 GST_WARNING_OBJECT (enc, "Could not allocate buffer");
592 ret = GST_FLOW_ERROR;
596 memcpy (GST_BUFFER_DATA (buf), packet->packet, packet->bytes);
597 gst_buffer_set_caps (buf, GST_PAD_CAPS (enc->srcpad));
598 /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
599 * time representation */
600 GST_BUFFER_OFFSET_END (buf) =
601 granulepos_add (packet->granulepos, enc->granulepos_offset,
602 enc->info.keyframe_granule_shift);
603 GST_BUFFER_OFFSET (buf) = granulepos_to_timestamp (enc,
604 GST_BUFFER_OFFSET_END (buf));
606 GST_BUFFER_TIMESTAMP (buf) = timestamp;
607 GST_BUFFER_DURATION (buf) = duration;
609 if (enc->next_discont) {
610 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
611 enc->next_discont = FALSE;
614 /* the second most significant bit of the first data byte is cleared
616 if ((packet->packet[0] & 0x40) == 0) {
617 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
619 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
628 /* push out the buffer and do internal bookkeeping */
630 theora_push_buffer (GstTheoraEnc * enc, GstBuffer * buffer)
634 enc->bytes_out += GST_BUFFER_SIZE (buffer);
636 ret = gst_pad_push (enc->srcpad, buffer);
642 theora_push_packet (GstTheoraEnc * enc, ogg_packet * packet,
643 GstClockTime timestamp, GstClockTime running_time, GstClockTime duration)
649 theora_buffer_from_packet (enc, packet, timestamp, running_time, duration,
651 if (ret == GST_FLOW_OK)
652 ret = theora_push_buffer (enc, buf);
658 theora_set_header_on_caps (GstCaps * caps, GSList * buffers)
660 GstStructure *structure;
661 GValue array = { 0 };
662 GValue value = { 0 };
666 caps = gst_caps_make_writable (caps);
667 structure = gst_caps_get_structure (caps, 0);
669 /* put copies of the buffers in a fixed list */
670 g_value_init (&array, GST_TYPE_ARRAY);
672 for (walk = buffers; walk; walk = walk->next) {
676 GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_IN_CAPS);
678 /* Copy buffer, because we can't use the original -
679 * it creates a circular refcount with the caps<->buffers */
680 buffer = gst_buffer_copy (buffer);
682 g_value_init (&value, GST_TYPE_BUFFER);
683 gst_value_set_buffer (&value, buffer);
684 gst_value_array_append_value (&array, &value);
685 g_value_unset (&value);
688 gst_buffer_unref (buffer);
691 gst_structure_set_value (structure, "streamheader", &array);
692 g_value_unset (&array);
698 theora_enc_force_keyframe (GstTheoraEnc * enc)
700 GstClockTime next_ts;
702 /* make sure timestamps increment after resetting the decoder */
703 next_ts = enc->next_ts + enc->timestamp_offset;
705 theora_enc_reset (enc);
706 enc->granulepos_offset =
707 gst_util_uint64_scale (next_ts, enc->fps_n, GST_SECOND * enc->fps_d);
708 enc->timestamp_offset = next_ts;
713 theora_enc_sink_event (GstPad * pad, GstEvent * event)
719 enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));
721 switch (GST_EVENT_TYPE (event)) {
722 case GST_EVENT_NEWSEGMENT:
725 gdouble rate, applied_rate;
727 gint64 start, stop, time;
729 gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
730 &format, &start, &stop, &time);
732 gst_segment_set_newsegment_full (&enc->segment, update, rate,
733 applied_rate, format, start, stop, time);
735 res = gst_pad_push_event (enc->srcpad, event);
739 if (enc->initialised) {
740 /* push last packet with eos flag, should not be called */
741 while (th_encode_packetout (enc->encoder, 1, &op)) {
742 GstClockTime next_time =
743 th_granule_time (enc->encoder, op.granulepos) * GST_SECOND;
745 theora_push_packet (enc, &op, GST_CLOCK_TIME_NONE, enc->next_ts,
746 next_time - enc->next_ts);
747 enc->next_ts = next_time;
750 res = gst_pad_push_event (enc->srcpad, event);
752 case GST_EVENT_FLUSH_STOP:
753 gst_segment_init (&enc->segment, GST_FORMAT_UNDEFINED);
754 res = gst_pad_push_event (enc->srcpad, event);
756 case GST_EVENT_CUSTOM_DOWNSTREAM:
758 const GstStructure *s;
760 s = gst_event_get_structure (event);
762 if (gst_structure_has_name (s, "GstForceKeyUnit"))
763 theora_enc_force_keyframe (enc);
764 res = gst_pad_push_event (enc->srcpad, event);
768 res = gst_pad_push_event (enc->srcpad, event);
775 theora_enc_src_event (GstPad * pad, GstEvent * event)
780 enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));
782 switch (GST_EVENT_TYPE (event)) {
783 case GST_EVENT_CUSTOM_UPSTREAM:
785 const GstStructure *s;
787 s = gst_event_get_structure (event);
789 if (gst_structure_has_name (s, "GstForceKeyUnit")) {
790 GST_OBJECT_LOCK (enc);
791 enc->force_keyframe = TRUE;
792 GST_OBJECT_UNLOCK (enc);
793 /* consume the event */
795 gst_event_unref (event);
797 res = gst_pad_push_event (enc->sinkpad, event);
802 res = gst_pad_push_event (enc->sinkpad, event);
810 theora_enc_is_discontinuous (GstTheoraEnc * enc, GstClockTime timestamp,
811 GstClockTime duration)
813 GstClockTimeDiff max_diff;
814 gboolean ret = FALSE;
816 /* Allow 3/4 a frame off */
817 max_diff = (enc->info.fps_denominator * GST_SECOND * 3) /
818 (enc->info.fps_numerator * 4);
820 if (timestamp != GST_CLOCK_TIME_NONE
821 && enc->expected_ts != GST_CLOCK_TIME_NONE) {
822 if ((GstClockTimeDiff) (timestamp - enc->expected_ts) > max_diff) {
823 GST_DEBUG_OBJECT (enc, "Incoming TS %" GST_TIME_FORMAT
824 " exceeds expected value %" GST_TIME_FORMAT
825 " by too much, marking discontinuity",
826 GST_TIME_ARGS (timestamp), GST_TIME_ARGS (enc->expected_ts));
831 if (GST_CLOCK_TIME_IS_VALID (duration))
832 enc->expected_ts = timestamp + duration;
834 enc->expected_ts = GST_CLOCK_TIME_NONE;
840 theora_enc_init_buffer (th_ycbcr_buffer buf, th_info * info, guint8 * data)
842 GstVideoFormat format;
845 switch (info->pixel_fmt) {
847 format = GST_VIDEO_FORMAT_Y444;
850 format = GST_VIDEO_FORMAT_I420;
853 format = GST_VIDEO_FORMAT_Y42B;
856 g_assert_not_reached ();
859 /* According to Theora developer Timothy Terriberry, the Theora
860 * encoder will not use memory outside of pic_width/height, even when
861 * the frame size is bigger. The values outside this region will be encoded
863 * Due to this, setting the frame's width/height as the buffer width/height
864 * is perfectly ok, even though it does not strictly look ok.
866 for (i = 0; i < 3; i++) {
868 gst_video_format_get_component_width (format, i, info->frame_width);
870 gst_video_format_get_component_height (format, i, info->frame_height);
873 data + gst_video_format_get_component_offset (format, i,
874 info->pic_width, info->pic_height);
876 gst_video_format_get_row_stride (format, i, info->pic_width);
881 theora_enc_chain (GstPad * pad, GstBuffer * buffer)
885 GstClockTime timestamp, duration, running_time;
887 gboolean force_keyframe;
889 enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));
891 /* we keep track of two timelines.
892 * - The timestamps from the incomming buffers, which we copy to the outgoing
893 * encoded buffers as-is. We need to do this as we simply forward the
895 * - The running_time of the buffers, which we use to construct the granulepos
898 timestamp = GST_BUFFER_TIMESTAMP (buffer);
899 duration = GST_BUFFER_DURATION (buffer);
902 gst_segment_to_running_time (&enc->segment, GST_FORMAT_TIME, timestamp);
903 if ((gint64) running_time < 0) {
904 GST_DEBUG_OBJECT (enc, "Dropping buffer, timestamp: %" GST_TIME_FORMAT,
905 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
906 gst_buffer_unref (buffer);
910 /* see if we need to schedule a keyframe */
911 GST_OBJECT_LOCK (enc);
912 force_keyframe = enc->force_keyframe;
913 enc->force_keyframe = FALSE;
914 GST_OBJECT_UNLOCK (enc);
916 if (force_keyframe) {
917 GstClockTime stream_time;
920 stream_time = gst_segment_to_stream_time (&enc->segment,
921 GST_FORMAT_TIME, timestamp);
923 s = gst_structure_new ("GstForceKeyUnit",
924 "timestamp", G_TYPE_UINT64, timestamp,
925 "stream-time", G_TYPE_UINT64, stream_time,
926 "running-time", G_TYPE_UINT64, running_time, NULL);
928 theora_enc_force_keyframe (enc);
930 gst_pad_push_event (enc->srcpad,
931 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
934 /* make sure we copy the discont flag to the next outgoing buffer when it's
935 * set on the incomming buffer */
936 if (GST_BUFFER_IS_DISCONT (buffer)) {
937 enc->next_discont = TRUE;
940 if (enc->packetno == 0) {
941 /* no packets written yet, setup headers */
944 GSList *buffers = NULL;
947 enc->granulepos_offset = 0;
948 enc->timestamp_offset = 0;
950 GST_DEBUG_OBJECT (enc, "output headers");
951 /* Theora streams begin with three headers; the initial header (with
952 most of the codec setup parameters) which is mandated by the Ogg
953 bitstream spec. The second header holds any comment fields. The
954 third header holds the bitstream codebook. We merely need to
955 make the headers, then pass them to libtheora one at a time;
956 libtheora handles the additional Ogg bitstream constraints */
958 /* create the remaining theora headers */
959 th_comment_clear (&enc->comment);
960 th_comment_init (&enc->comment);
963 th_encode_flushheader (enc->encoder, &enc->comment, &op)) > 0) {
965 theora_buffer_from_packet (enc, &op, GST_CLOCK_TIME_NONE,
966 GST_CLOCK_TIME_NONE, GST_CLOCK_TIME_NONE, &buf);
967 if (ret != GST_FLOW_OK) {
968 goto header_buffer_alloc;
970 buffers = g_slist_prepend (buffers, buf);
973 g_slist_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
974 g_slist_free (buffers);
975 goto encoder_disabled;
978 buffers = g_slist_reverse (buffers);
980 /* mark buffers and put on caps */
981 caps = gst_pad_get_caps (enc->srcpad);
982 caps = theora_set_header_on_caps (caps, buffers);
983 GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
984 gst_pad_set_caps (enc->srcpad, caps);
986 g_slist_foreach (buffers, (GFunc) gst_buffer_set_caps, caps);
988 gst_caps_unref (caps);
990 /* push out the header buffers */
993 buffers = g_slist_delete_link (buffers, buffers);
994 if ((ret = theora_push_buffer (enc, buf)) != GST_FLOW_OK) {
995 g_slist_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
996 g_slist_free (buffers);
1001 enc->granulepos_offset =
1002 gst_util_uint64_scale (running_time, enc->fps_n,
1003 GST_SECOND * enc->fps_d);
1004 enc->timestamp_offset = running_time;
1009 th_ycbcr_buffer ycbcr;
1012 theora_enc_init_buffer (ycbcr, &enc->info, GST_BUFFER_DATA (buffer));
1014 if (theora_enc_is_discontinuous (enc, running_time, duration)) {
1015 theora_enc_reset (enc);
1016 enc->granulepos_offset =
1017 gst_util_uint64_scale (running_time, enc->fps_n,
1018 GST_SECOND * enc->fps_d);
1019 enc->timestamp_offset = running_time;
1021 enc->next_discont = TRUE;
1024 res = th_encode_ycbcr_in (enc->encoder, ycbcr);
1025 /* none of the failure cases can happen here */
1026 g_assert (res == 0);
1029 while (th_encode_packetout (enc->encoder, 0, &op)) {
1030 GstClockTime next_time;
1032 next_time = th_granule_time (enc->encoder, op.granulepos) * GST_SECOND;
1035 theora_push_packet (enc, &op, timestamp, enc->next_ts,
1036 next_time - enc->next_ts);
1038 enc->next_ts = next_time;
1039 if (ret != GST_FLOW_OK)
1042 gst_buffer_unref (buffer);
1048 header_buffer_alloc:
1050 gst_buffer_unref (buffer);
1055 gst_buffer_unref (buffer);
1060 gst_buffer_unref (buffer);
1065 GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
1066 ("libtheora has been compiled with the encoder disabled"));
1067 gst_buffer_unref (buffer);
1068 return GST_FLOW_ERROR;
1072 static GstStateChangeReturn
1073 theora_enc_change_state (GstElement * element, GstStateChange transition)
1076 GstStateChangeReturn ret;
1078 enc = GST_THEORA_ENC (element);
1080 switch (transition) {
1081 case GST_STATE_CHANGE_NULL_TO_READY:
1083 case GST_STATE_CHANGE_READY_TO_PAUSED:
1084 GST_DEBUG_OBJECT (enc, "READY->PAUSED Initing theora state");
1085 th_info_init (&enc->info);
1086 th_comment_init (&enc->comment);
1088 enc->force_keyframe = FALSE;
1090 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1096 ret = parent_class->change_state (element, transition);
1098 switch (transition) {
1099 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1101 case GST_STATE_CHANGE_PAUSED_TO_READY:
1102 GST_DEBUG_OBJECT (enc, "PAUSED->READY Clearing theora state");
1104 th_encode_free (enc->encoder);
1105 enc->encoder = NULL;
1107 th_comment_clear (&enc->comment);
1108 th_info_clear (&enc->info);
1110 theora_enc_clear (enc);
1111 enc->initialised = FALSE;
1113 case GST_STATE_CHANGE_READY_TO_NULL:
1123 theora_enc_set_property (GObject * object, guint prop_id,
1124 const GValue * value, GParamSpec * pspec)
1126 GstTheoraEnc *enc = GST_THEORA_ENC (object);
1132 case ARG_KEYFRAME_THRESHOLD:
1133 case ARG_KEYFRAME_MINDISTANCE:
1134 case ARG_NOISE_SENSITIVITY:
1136 /* kept for API compat, but ignored */
1139 enc->video_bitrate = g_value_get_int (value) * 1000;
1140 enc->video_quality = 0;
1143 enc->video_quality = g_value_get_int (value);
1144 enc->video_bitrate = 0;
1146 case ARG_KEYFRAME_AUTO:
1147 enc->keyframe_auto = g_value_get_boolean (value);
1149 case ARG_KEYFRAME_FREQ:
1150 enc->keyframe_freq = g_value_get_int (value);
1152 case ARG_KEYFRAME_FREQ_FORCE:
1153 enc->keyframe_force = g_value_get_int (value);
1155 case ARG_SPEEDLEVEL:
1156 #ifdef TH_ENCCTL_SET_SPLEVEL
1157 enc->speed_level = g_value_get_int (value);
1160 case ARG_VP3_COMPATIBLE:
1161 #ifdef TH_ENCCTL_SET_VP3_COMPATIBLE
1162 enc->vp3_compatible = g_value_get_boolean (value);
1165 case ARG_DROP_FRAMES:
1166 #ifdef TH_ENCCTL_SET_RATE_FLAGS
1167 enc->drop_frames = g_value_get_boolean (value);
1170 case ARG_CAP_OVERFLOW:
1171 #ifdef TH_ENCCTL_SET_RATE_FLAGS
1172 enc->cap_overflow = g_value_get_boolean (value);
1175 case ARG_CAP_UNDERFLOW:
1176 #ifdef TH_ENCCTL_SET_RATE_FLAGS
1177 enc->cap_underflow = g_value_get_boolean (value);
1180 case ARG_RATE_BUFFER:
1181 #ifdef TH_ENCCTL_SET_RATE_BUFFER
1182 enc->rate_buffer = g_value_get_int (value);
1186 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1192 theora_enc_get_property (GObject * object, guint prop_id,
1193 GValue * value, GParamSpec * pspec)
1195 GstTheoraEnc *enc = GST_THEORA_ENC (object);
1199 g_value_set_boolean (value, TRUE);
1202 g_value_set_enum (value, BORDER_BLACK);
1205 g_value_set_int (value, enc->video_bitrate / 1000);
1208 g_value_set_int (value, enc->video_quality);
1211 g_value_set_boolean (value, TRUE);
1213 case ARG_KEYFRAME_AUTO:
1214 g_value_set_boolean (value, enc->keyframe_auto);
1216 case ARG_KEYFRAME_FREQ:
1217 g_value_set_int (value, enc->keyframe_freq);
1219 case ARG_KEYFRAME_FREQ_FORCE:
1220 g_value_set_int (value, enc->keyframe_force);
1222 case ARG_KEYFRAME_THRESHOLD:
1223 g_value_set_int (value, 80);
1225 case ARG_KEYFRAME_MINDISTANCE:
1226 g_value_set_int (value, 8);
1228 case ARG_NOISE_SENSITIVITY:
1229 g_value_set_int (value, 1);
1232 g_value_set_int (value, 0);
1234 case ARG_SPEEDLEVEL:
1235 g_value_set_int (value, enc->speed_level);
1237 case ARG_VP3_COMPATIBLE:
1238 g_value_set_boolean (value, enc->vp3_compatible);
1240 case ARG_DROP_FRAMES:
1241 g_value_set_boolean (value, enc->drop_frames);
1243 case ARG_CAP_OVERFLOW:
1244 g_value_set_boolean (value, enc->cap_overflow);
1246 case ARG_CAP_UNDERFLOW:
1247 g_value_set_boolean (value, enc->cap_underflow);
1249 case ARG_RATE_BUFFER:
1250 g_value_set_int (value, enc->rate_buffer);
1253 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);