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_MULTIPASS_MODE (gst_multipass_mode_get_type())
71 gst_multipass_mode_get_type (void)
73 static GType multipass_mode_type = 0;
74 static const GEnumValue multipass_mode[] = {
75 {MULTIPASS_MODE_SINGLE_PASS, "Single pass", "single-pass"},
76 {MULTIPASS_MODE_FIRST_PASS, "First pass", "first-pass"},
77 {MULTIPASS_MODE_SECOND_PASS, "Second pass", "second-pass"},
81 if (!multipass_mode_type) {
83 g_enum_register_static ("GstTheoraEncMultipassMode", multipass_mode);
85 return multipass_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
112 #define THEORA_DEF_MULTIPASS_CACHE_FILE NULL
113 #define THEORA_DEF_MULTIPASS_MODE MULTIPASS_MODE_SINGLE_PASS
114 #define THEORA_DEF_DUP_ON_GAP FALSE
122 PROP_KEYFRAME_FREQ_FORCE,
129 PROP_MULTIPASS_CACHE_FILE,
135 /* this function does a straight granulepos -> timestamp conversion */
137 granulepos_to_timestamp (GstTheoraEnc * theoraenc, ogg_int64_t granulepos)
139 guint64 iframe, pframe;
140 int shift = theoraenc->info.keyframe_granule_shift;
143 return GST_CLOCK_TIME_NONE;
145 iframe = granulepos >> shift;
146 pframe = granulepos - (iframe << shift);
148 /* num and den are 32 bit, so we can safely multiply with GST_SECOND */
149 return gst_util_uint64_scale ((guint64) (iframe + pframe),
150 GST_SECOND * theoraenc->info.fps_denominator,
151 theoraenc->info.fps_numerator);
154 /* Generate a dummy encoder context for use in th_encode_ctl queries
155 Release with th_encode_free()
156 This and the next routine from theora/examples/libtheora_info.c */
158 dummy_encode_ctx (void)
163 /* set the minimal video parameters */
164 th_info_init (&info);
165 info.frame_width = 320;
166 info.frame_height = 240;
167 info.fps_numerator = 1;
168 info.fps_denominator = 1;
170 /* allocate and initialize a context object */
171 ctx = th_encode_alloc (&info);
173 GST_WARNING ("Failed to allocate dummy encoder context.");
175 /* clear the info struct */
176 th_info_clear (&info);
181 /* Query the current and maximum values for the 'speed level' setting.
182 This can be used to ask the encoder to trade off encoding quality
183 vs. performance cost, for example to adapt to realtime constraints. */
185 check_speed_level (th_enc_ctx * ctx, int *current, int *max)
189 /* query the current speed level */
190 ret = th_encode_ctl (ctx, TH_ENCCTL_GET_SPLEVEL, current, sizeof (int));
192 GST_WARNING ("Error %d getting current speed level.", ret);
195 /* query the maximum speed level, which varies by encoder version */
196 ret = th_encode_ctl (ctx, TH_ENCCTL_GET_SPLEVEL_MAX, max, sizeof (int));
198 GST_WARNING ("Error %d getting maximum speed level.", ret);
205 static GstStaticPadTemplate theora_enc_sink_factory =
206 GST_STATIC_PAD_TEMPLATE ("sink",
209 GST_STATIC_CAPS ("video/x-raw, "
210 "format = (string) { I420, Y42B, Y444 }, "
211 "framerate = (fraction) [1/MAX, MAX], "
212 "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
215 static GstStaticPadTemplate theora_enc_src_factory =
216 GST_STATIC_PAD_TEMPLATE ("src",
219 GST_STATIC_CAPS ("video/x-theora, "
220 "framerate = (fraction) [1/MAX, MAX], "
221 "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
224 #define gst_theora_enc_parent_class parent_class
225 G_DEFINE_TYPE_WITH_CODE (GstTheoraEnc, gst_theora_enc,
226 GST_TYPE_ELEMENT, G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL));
228 static GstCaps *theora_enc_src_caps;
230 static gboolean theora_enc_sink_event (GstPad * pad, GstObject * parent,
232 static gboolean theora_enc_src_event (GstPad * pad, GstObject * parent,
234 static GstFlowReturn theora_enc_chain (GstPad * pad, GstObject * parent,
236 static GstStateChangeReturn theora_enc_change_state (GstElement * element,
237 GstStateChange transition);
238 static gboolean theora_enc_sink_query (GstPad * pad, GstObject * parent,
240 static gboolean theora_enc_sink_setcaps (GstTheoraEnc * enc, GstCaps * caps);
241 static void theora_enc_get_property (GObject * object, guint prop_id,
242 GValue * value, GParamSpec * pspec);
243 static void theora_enc_set_property (GObject * object, guint prop_id,
244 const GValue * value, GParamSpec * pspec);
245 static void theora_enc_finalize (GObject * object);
247 static gboolean theora_enc_write_multipass_cache (GstTheoraEnc * enc,
248 gboolean begin, gboolean eos);
250 static char *theora_enc_get_supported_formats (void);
252 static void theora_timefifo_free (GstTheoraEnc * enc);
254 theora_enc_encode_and_push (GstTheoraEnc * enc, ogg_packet op,
258 gst_theora_enc_class_init (GstTheoraEncClass * klass)
260 GObjectClass *gobject_class = (GObjectClass *) klass;
261 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
264 /* query runtime encoder properties */
266 int default_speed_level = THEORA_DEF_SPEEDLEVEL;
267 int max_speed_level = default_speed_level;
269 GST_DEBUG_CATEGORY_INIT (theoraenc_debug, "theoraenc", 0, "Theora encoder");
271 th_ctx = dummy_encode_ctx ();
273 if (check_speed_level (th_ctx, &default_speed_level, &max_speed_level))
275 ("Failed to determine settings for the speed-level property.");
276 th_encode_free (th_ctx);
279 gobject_class->set_property = theora_enc_set_property;
280 gobject_class->get_property = theora_enc_get_property;
281 gobject_class->finalize = theora_enc_finalize;
283 /* general encoding stream options */
284 g_object_class_install_property (gobject_class, PROP_BITRATE,
285 g_param_spec_int ("bitrate", "Bitrate", "Compressed video bitrate (kbps)",
286 0, (1 << 24) - 1, THEORA_DEF_BITRATE,
287 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
288 GST_PARAM_MUTABLE_PLAYING));
289 g_object_class_install_property (gobject_class, PROP_QUALITY,
290 g_param_spec_int ("quality", "Quality", "Video quality", 0, 63,
292 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
293 GST_PARAM_MUTABLE_PLAYING));
294 g_object_class_install_property (gobject_class, PROP_KEYFRAME_AUTO,
295 g_param_spec_boolean ("keyframe-auto", "Keyframe Auto",
296 "Automatic keyframe detection", THEORA_DEF_KEYFRAME_AUTO,
297 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
298 g_object_class_install_property (gobject_class, PROP_KEYFRAME_FREQ,
299 g_param_spec_int ("keyframe-freq", "Keyframe frequency",
300 "Keyframe frequency", 1, 32768, THEORA_DEF_KEYFRAME_FREQ,
301 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
302 g_object_class_install_property (gobject_class, PROP_KEYFRAME_FREQ_FORCE,
303 g_param_spec_int ("keyframe-force", "Keyframe force",
304 "Force keyframe every N frames", 1, 32768,
305 THEORA_DEF_KEYFRAME_FREQ_FORCE,
306 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
307 g_object_class_install_property (gobject_class, PROP_SPEEDLEVEL,
308 g_param_spec_int ("speed-level", "Speed level",
309 "Controls the amount of analysis performed when encoding."
310 " Higher values trade compression quality for speed."
311 " This property requires libtheora version >= 1.0"
312 ", and the maximum value may vary based on encoder version.",
313 0, max_speed_level, default_speed_level,
314 (GParamFlags) G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
315 G_PARAM_STATIC_STRINGS));
316 g_object_class_install_property (gobject_class, PROP_VP3_COMPATIBLE,
317 g_param_spec_boolean ("vp3-compatible", "VP3 Compatible",
318 "Disables non-VP3 compatible features",
319 THEORA_DEF_VP3_COMPATIBLE,
320 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
321 g_object_class_install_property (gobject_class, PROP_DROP_FRAMES,
322 g_param_spec_boolean ("drop-frames", "Drop Frames",
323 "Allow or disallow frame dropping",
324 THEORA_DEF_DROP_FRAMES,
325 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
326 g_object_class_install_property (gobject_class, PROP_CAP_OVERFLOW,
327 g_param_spec_boolean ("cap-overflow", "Cap Overflow",
328 "Enable capping of bit reservoir overflows",
329 THEORA_DEF_CAP_OVERFLOW,
330 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
331 g_object_class_install_property (gobject_class, PROP_CAP_UNDERFLOW,
332 g_param_spec_boolean ("cap-underflow", "Cap Underflow",
333 "Enable capping of bit reservoir underflows",
334 THEORA_DEF_CAP_UNDERFLOW,
335 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
336 g_object_class_install_property (gobject_class, PROP_RATE_BUFFER,
337 g_param_spec_int ("rate-buffer", "Rate Control Buffer",
338 "Sets the size of the rate control buffer, in units of frames. "
339 "The default value of 0 instructs the encoder to automatically "
340 "select an appropriate value",
341 0, 1000, THEORA_DEF_RATE_BUFFER,
342 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
343 g_object_class_install_property (gobject_class, PROP_MULTIPASS_CACHE_FILE,
344 g_param_spec_string ("multipass-cache-file", "Multipass Cache File",
345 "Multipass cache file", THEORA_DEF_MULTIPASS_CACHE_FILE,
346 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
347 g_object_class_install_property (gobject_class, PROP_MULTIPASS_MODE,
348 g_param_spec_enum ("multipass-mode", "Multipass mode",
349 "Single pass or first/second pass", GST_TYPE_MULTIPASS_MODE,
350 THEORA_DEF_MULTIPASS_MODE,
351 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
352 g_object_class_install_property (gobject_class, PROP_DUP_ON_GAP,
353 g_param_spec_boolean ("dup-on-gap", "Create DUP frame on GAP flag",
354 "Allow codec to handle frames with GAP flag as duplicates "
355 "of previous frame. "
356 "This is good to work with variable frame rate stabilized "
357 "by videorate element. It will add variable latency with maximal "
358 "size of keyframe distance, this way it is a bad idea "
359 "to use with live streams.",
360 THEORA_DEF_DUP_ON_GAP,
361 (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
363 gst_element_class_add_pad_template (gstelement_class,
364 gst_static_pad_template_get (&theora_enc_src_factory));
365 gst_element_class_add_pad_template (gstelement_class,
366 gst_static_pad_template_get (&theora_enc_sink_factory));
367 gst_element_class_set_static_metadata (gstelement_class,
368 "Theora video encoder", "Codec/Encoder/Video",
369 "encode raw YUV video to a theora stream",
370 "Wim Taymans <wim@fluendo.com>");
372 caps_string = g_strdup_printf ("video/x-raw, "
373 "format = (string) { %s }, "
374 "framerate = (fraction) [1/MAX, MAX], "
375 "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]",
376 theora_enc_get_supported_formats ());
377 theora_enc_src_caps = gst_caps_from_string (caps_string);
378 g_free (caps_string);
380 gstelement_class->change_state = theora_enc_change_state;
384 gst_theora_enc_init (GstTheoraEnc * enc)
387 gst_pad_new_from_static_template (&theora_enc_sink_factory, "sink");
388 gst_pad_set_chain_function (enc->sinkpad, theora_enc_chain);
389 gst_pad_set_event_function (enc->sinkpad, theora_enc_sink_event);
390 gst_pad_set_query_function (enc->sinkpad, theora_enc_sink_query);
391 gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad);
394 gst_pad_new_from_static_template (&theora_enc_src_factory, "src");
395 gst_pad_set_event_function (enc->srcpad, theora_enc_src_event);
396 gst_pad_use_fixed_caps (enc->srcpad);
397 gst_element_add_pad (GST_ELEMENT (enc), enc->srcpad);
399 gst_segment_init (&enc->segment, GST_FORMAT_UNDEFINED);
401 enc->video_bitrate = THEORA_DEF_BITRATE;
402 enc->video_quality = THEORA_DEF_QUALITY;
403 enc->keyframe_auto = THEORA_DEF_KEYFRAME_AUTO;
404 enc->keyframe_freq = THEORA_DEF_KEYFRAME_FREQ;
405 enc->keyframe_force = THEORA_DEF_KEYFRAME_FREQ_FORCE;
407 enc->expected_ts = GST_CLOCK_TIME_NONE;
409 /* enc->speed_level is set to the libtheora default by the constructor */
410 enc->vp3_compatible = THEORA_DEF_VP3_COMPATIBLE;
411 enc->drop_frames = THEORA_DEF_DROP_FRAMES;
412 enc->cap_overflow = THEORA_DEF_CAP_OVERFLOW;
413 enc->cap_underflow = THEORA_DEF_CAP_UNDERFLOW;
414 enc->rate_buffer = THEORA_DEF_RATE_BUFFER;
415 enc->dup_on_gap = THEORA_DEF_DUP_ON_GAP;
417 enc->multipass_mode = THEORA_DEF_MULTIPASS_MODE;
418 enc->multipass_cache_file = THEORA_DEF_MULTIPASS_CACHE_FILE;
422 theora_enc_clear_multipass_cache (GstTheoraEnc * enc)
424 if (enc->multipass_cache_fd) {
425 g_io_channel_shutdown (enc->multipass_cache_fd, TRUE, NULL);
426 g_io_channel_unref (enc->multipass_cache_fd);
427 enc->multipass_cache_fd = NULL;
430 if (enc->multipass_cache_adapter) {
431 gst_object_unref (enc->multipass_cache_adapter);
432 enc->multipass_cache_adapter = NULL;
437 theora_enc_finalize (GObject * object)
439 GstTheoraEnc *enc = GST_THEORA_ENC (object);
441 GST_DEBUG_OBJECT (enc, "Finalizing");
443 th_encode_free (enc->encoder);
444 th_comment_clear (&enc->comment);
445 th_info_clear (&enc->info);
446 g_free (enc->multipass_cache_file);
448 theora_enc_clear_multipass_cache (enc);
450 G_OBJECT_CLASS (parent_class)->finalize (object);
454 theora_enc_reset (GstTheoraEnc * enc)
456 ogg_uint32_t keyframe_force;
459 GST_OBJECT_LOCK (enc);
460 enc->info.target_bitrate = enc->video_bitrate;
461 if (enc->quality_changed) {
462 enc->info.quality = enc->video_quality;
464 if (enc->video_bitrate == 0) {
465 enc->info.quality = enc->video_quality;
468 enc->bitrate_changed = FALSE;
469 enc->quality_changed = FALSE;
470 GST_OBJECT_UNLOCK (enc);
473 th_encode_free (enc->encoder);
474 enc->encoder = th_encode_alloc (&enc->info);
475 /* We ensure this function cannot fail. */
476 g_assert (enc->encoder != NULL);
477 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_SPLEVEL, &enc->speed_level,
478 sizeof (enc->speed_level));
479 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_VP3_COMPATIBLE,
480 &enc->vp3_compatible, sizeof (enc->vp3_compatible));
483 if (enc->drop_frames)
484 rate_flags |= TH_RATECTL_DROP_FRAMES;
485 if (enc->drop_frames)
486 rate_flags |= TH_RATECTL_CAP_OVERFLOW;
487 if (enc->drop_frames)
488 rate_flags |= TH_RATECTL_CAP_UNDERFLOW;
489 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_FLAGS,
490 &rate_flags, sizeof (rate_flags));
492 if (enc->rate_buffer) {
493 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_BUFFER,
494 &enc->rate_buffer, sizeof (enc->rate_buffer));
499 keyframe_force = enc->keyframe_auto ?
500 enc->keyframe_force : enc->keyframe_freq;
501 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
502 &keyframe_force, sizeof (keyframe_force));
504 /* Get placeholder data */
505 if (enc->multipass_cache_fd
506 && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS)
507 theora_enc_write_multipass_cache (enc, TRUE, FALSE);
511 theora_enc_clear (GstTheoraEnc * enc)
515 enc->granulepos_offset = 0;
516 enc->timestamp_offset = 0;
518 theora_timefifo_free (enc);
520 enc->next_ts = GST_CLOCK_TIME_NONE;
521 enc->next_discont = FALSE;
522 enc->expected_ts = GST_CLOCK_TIME_NONE;
526 theora_enc_get_supported_formats (void)
532 th_pixel_fmt pixelformat;
533 const char fourcc[5];
536 TH_PF_420, "I420"}, {
537 TH_PF_422, "Y42B"}, {
540 GString *string = NULL;
543 th_info_init (&info);
544 info.frame_width = 16;
545 info.frame_height = 16;
546 info.fps_numerator = 25;
547 info.fps_denominator = 1;
548 for (i = 0; i < G_N_ELEMENTS (formats); i++) {
549 info.pixel_fmt = formats[i].pixelformat;
551 encoder = th_encode_alloc (&info);
555 GST_LOG ("format %s is supported", formats[i].fourcc);
556 th_encode_free (encoder);
558 if (string == NULL) {
559 string = g_string_new (formats[i].fourcc);
561 g_string_append (string, ", ");
562 g_string_append (string, formats[i].fourcc);
565 th_info_clear (&info);
567 return string == NULL ? NULL : g_string_free (string, FALSE);
571 theora_enc_sink_getcaps (GstPad * pad, GstCaps * filter)
573 GstTheoraEnc *encoder;
577 /* If we already have caps return them */
578 if ((caps = gst_pad_get_current_caps (pad)) != NULL)
581 encoder = GST_THEORA_ENC (gst_pad_get_parent (pad));
583 return gst_caps_new_empty ();
585 peer = gst_pad_get_peer (encoder->srcpad);
588 GstCaps *peer_caps, *tmp_caps;
592 peer_caps = gst_pad_query_caps (peer, NULL);
594 /* Translate peercaps to YUV */
595 peer_caps = gst_caps_make_writable (peer_caps);
596 n = gst_caps_get_size (peer_caps);
597 for (i = 0; i < n; i++) {
598 s = gst_caps_get_structure (peer_caps, i);
600 gst_structure_set_name (s, "video/x-raw");
601 gst_structure_remove_field (s, "streamheader");
604 templ_caps = gst_pad_get_pad_template_caps (pad);
606 tmp_caps = gst_caps_intersect (peer_caps, templ_caps);
607 caps = gst_caps_intersect (tmp_caps, theora_enc_src_caps);
608 gst_caps_unref (tmp_caps);
609 gst_caps_unref (peer_caps);
610 gst_object_unref (peer);
613 caps = gst_caps_ref (theora_enc_src_caps);
616 gst_object_unref (encoder);
619 GstCaps *intersection;
622 gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
623 gst_caps_unref (caps);
631 theora_enc_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
633 gboolean res = FALSE;
635 switch (GST_QUERY_TYPE (query)) {
638 GstCaps *filter, *caps;
640 gst_query_parse_caps (query, &filter);
641 caps = theora_enc_sink_getcaps (pad, filter);
642 gst_query_set_caps_result (query, caps);
643 gst_caps_unref (caps);
648 res = gst_pad_query_default (pad, parent, query);
656 theora_enc_sink_setcaps (GstTheoraEnc * enc, GstCaps * caps)
660 th_info_clear (&enc->info);
661 th_info_init (&enc->info);
663 if (!gst_video_info_from_caps (&info, caps))
668 /* Theora has a divisible-by-sixteen restriction for the encoded video size but
669 * we can define a picture area using pic_width/pic_height */
670 enc->info.frame_width = GST_ROUND_UP_16 (info.width);
671 enc->info.frame_height = GST_ROUND_UP_16 (info.height);
672 enc->info.pic_width = info.width;
673 enc->info.pic_height = info.height;
675 switch (GST_VIDEO_INFO_FORMAT (&info)) {
676 case GST_VIDEO_FORMAT_I420:
677 enc->info.pixel_fmt = TH_PF_420;
679 case GST_VIDEO_FORMAT_Y42B:
680 enc->info.pixel_fmt = TH_PF_422;
682 case GST_VIDEO_FORMAT_Y444:
683 enc->info.pixel_fmt = TH_PF_444;
686 g_assert_not_reached ();
689 enc->info.fps_numerator = info.fps_n;
690 enc->info.fps_denominator = info.fps_d;
692 enc->info.aspect_numerator = info.par_n;
693 enc->info.aspect_denominator = info.par_d;
695 /* setting them to 0 indicates that the decoder can chose a good aspect
696 * ratio, defaulting to 1/1 */
697 enc->info.aspect_numerator = 0;
699 enc->info.aspect_denominator = 0;
703 enc->info.colorspace = TH_CS_UNSPECIFIED;
705 /* as done in theora */
706 enc->info.keyframe_granule_shift = _ilog (enc->keyframe_force - 1);
707 GST_DEBUG_OBJECT (enc,
708 "keyframe_frequency_force is %d, granule shift is %d",
709 enc->keyframe_force, enc->info.keyframe_granule_shift);
711 theora_enc_reset (enc);
712 enc->initialised = TRUE;
719 GST_DEBUG_OBJECT (enc, "could not parse caps");
725 granulepos_add (guint64 granulepos, guint64 addend, gint shift)
727 guint64 iframe, pframe;
729 iframe = granulepos >> shift;
730 pframe = granulepos - (iframe << shift);
733 return (iframe << shift) + pframe;
736 /* prepare a buffer for transmission by passing data through libtheora */
738 theora_buffer_from_packet (GstTheoraEnc * enc, ogg_packet * packet,
739 GstClockTime timestamp, GstClockTime running_time,
740 GstClockTime duration, GstBuffer ** buffer)
743 GstFlowReturn ret = GST_FLOW_OK;
745 buf = gst_buffer_new_and_alloc (packet->bytes);
747 GST_WARNING_OBJECT (enc, "Could not allocate buffer");
748 ret = GST_FLOW_ERROR;
752 gst_buffer_fill (buf, 0, packet->packet, packet->bytes);
753 /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
754 * time representation */
755 GST_BUFFER_OFFSET_END (buf) =
756 granulepos_add (packet->granulepos, enc->granulepos_offset,
757 enc->info.keyframe_granule_shift);
758 GST_BUFFER_OFFSET (buf) = granulepos_to_timestamp (enc,
759 GST_BUFFER_OFFSET_END (buf));
761 GST_BUFFER_TIMESTAMP (buf) = timestamp;
762 GST_BUFFER_DURATION (buf) = duration;
764 if (enc->next_discont) {
765 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
766 enc->next_discont = FALSE;
769 /* th_packet_iskeyframe returns positive for keyframes */
770 if (th_packet_iskeyframe (packet) > 0) {
771 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
773 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
782 /* push out the buffer and do internal bookkeeping */
784 theora_push_buffer (GstTheoraEnc * enc, GstBuffer * buffer)
788 enc->bytes_out += gst_buffer_get_size (buffer);
790 ret = gst_pad_push (enc->srcpad, buffer);
796 theora_push_packet (GstTheoraEnc * enc, ogg_packet * packet,
797 GstClockTime timestamp, GstClockTime running_time, GstClockTime duration)
803 theora_buffer_from_packet (enc, packet, timestamp, running_time, duration,
805 if (ret == GST_FLOW_OK)
806 ret = theora_push_buffer (enc, buf);
812 theora_set_header_on_caps (GstCaps * caps, GSList * buffers)
814 GstStructure *structure;
815 GValue array = { 0 };
816 GValue value = { 0 };
820 caps = gst_caps_make_writable (caps);
821 structure = gst_caps_get_structure (caps, 0);
823 /* put copies of the buffers in a fixed list */
824 g_value_init (&array, GST_TYPE_ARRAY);
826 for (walk = buffers; walk; walk = walk->next) {
830 GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER);
832 /* Copy buffer, because we can't use the original -
833 * it creates a circular refcount with the caps<->buffers */
834 buffer = gst_buffer_copy (buffer);
836 g_value_init (&value, GST_TYPE_BUFFER);
837 gst_value_set_buffer (&value, buffer);
838 gst_value_array_append_value (&array, &value);
839 g_value_unset (&value);
842 gst_buffer_unref (buffer);
845 gst_structure_set_value (structure, "streamheader", &array);
846 g_value_unset (&array);
852 theora_enc_force_keyframe (GstTheoraEnc * enc)
854 GstClockTime next_ts;
856 /* make sure timestamps increment after resetting the decoder */
857 next_ts = enc->next_ts + enc->timestamp_offset;
859 theora_enc_reset (enc);
860 enc->granulepos_offset =
861 gst_util_uint64_scale (next_ts, enc->vinfo.fps_n,
862 GST_SECOND * enc->vinfo.fps_d);
863 enc->timestamp_offset = next_ts;
868 theora_enc_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
874 enc = GST_THEORA_ENC (parent);
876 switch (GST_EVENT_TYPE (event)) {
881 gst_event_parse_caps (event, &caps);
882 res = theora_enc_sink_setcaps (enc, caps);
883 gst_event_unref (event);
886 case GST_EVENT_SEGMENT:
888 gst_event_copy_segment (event, &enc->segment);
890 res = gst_pad_push_event (enc->srcpad, event);
894 if (enc->initialised) {
895 /* clear all standing buffers */
897 theora_enc_encode_and_push (enc, op, NULL);
898 /* push last packet with eos flag, should not be called */
899 while (th_encode_packetout (enc->encoder, 1, &op)) {
900 GstClockTime next_time =
901 th_granule_time (enc->encoder, op.granulepos) * GST_SECOND;
903 theora_push_packet (enc, &op, GST_CLOCK_TIME_NONE, enc->next_ts,
904 next_time - enc->next_ts);
905 enc->next_ts = next_time;
908 if (enc->initialised && enc->multipass_cache_fd
909 && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS)
910 theora_enc_write_multipass_cache (enc, TRUE, TRUE);
912 theora_enc_clear_multipass_cache (enc);
914 res = gst_pad_push_event (enc->srcpad, event);
916 case GST_EVENT_FLUSH_STOP:
917 gst_segment_init (&enc->segment, GST_FORMAT_UNDEFINED);
918 res = gst_pad_push_event (enc->srcpad, event);
919 theora_timefifo_free (enc);
921 case GST_EVENT_CUSTOM_DOWNSTREAM:
923 const GstStructure *s;
925 s = gst_event_get_structure (event);
927 if (gst_structure_has_name (s, "GstForceKeyUnit"))
928 theora_enc_force_keyframe (enc);
929 res = gst_pad_push_event (enc->srcpad, event);
933 res = gst_pad_push_event (enc->srcpad, event);
940 theora_enc_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
945 enc = GST_THEORA_ENC (parent);
947 switch (GST_EVENT_TYPE (event)) {
948 case GST_EVENT_CUSTOM_UPSTREAM:
950 const GstStructure *s;
952 s = gst_event_get_structure (event);
954 if (gst_structure_has_name (s, "GstForceKeyUnit")) {
955 GST_OBJECT_LOCK (enc);
956 enc->force_keyframe = TRUE;
957 GST_OBJECT_UNLOCK (enc);
958 /* consume the event */
960 gst_event_unref (event);
962 res = gst_pad_push_event (enc->sinkpad, event);
967 res = gst_pad_push_event (enc->sinkpad, event);
975 theora_enc_is_discontinuous (GstTheoraEnc * enc, GstClockTime timestamp,
976 GstClockTime duration)
978 GstClockTimeDiff max_diff;
979 gboolean ret = FALSE;
981 /* Allow 3/4 a frame off */
982 max_diff = (enc->info.fps_denominator * GST_SECOND * 3) /
983 (enc->info.fps_numerator * 4);
985 if (timestamp != GST_CLOCK_TIME_NONE
986 && enc->expected_ts != GST_CLOCK_TIME_NONE) {
987 if ((GstClockTimeDiff) (timestamp - enc->expected_ts) > max_diff) {
988 GST_DEBUG_OBJECT (enc, "Incoming TS %" GST_TIME_FORMAT
989 " exceeds expected value %" GST_TIME_FORMAT
990 " by too much, marking discontinuity",
991 GST_TIME_ARGS (timestamp), GST_TIME_ARGS (enc->expected_ts));
996 if (GST_CLOCK_TIME_IS_VALID (duration))
997 enc->expected_ts = timestamp + duration;
999 enc->expected_ts = GST_CLOCK_TIME_NONE;
1005 theora_enc_init_buffer (th_ycbcr_buffer buf, GstVideoFrame * frame)
1010 /* According to Theora developer Timothy Terriberry, the Theora
1011 * encoder will not use memory outside of pic_width/height, even when
1012 * the frame size is bigger. The values outside this region will be encoded
1013 * to default values.
1014 * Due to this, setting the frame's width/height as the buffer width/height
1015 * is perfectly ok, even though it does not strictly look ok.
1018 gst_video_info_init (&info);
1019 gst_video_info_set_format (&info, GST_VIDEO_FRAME_FORMAT (frame),
1020 GST_ROUND_UP_16 (GST_VIDEO_FRAME_WIDTH (frame)),
1021 GST_ROUND_UP_16 (GST_VIDEO_FRAME_HEIGHT (frame)));
1023 for (i = 0; i < 3; i++) {
1024 buf[i].width = GST_VIDEO_INFO_COMP_WIDTH (&info, i);
1025 buf[i].height = GST_VIDEO_INFO_COMP_HEIGHT (&info, i);
1026 buf[i].data = GST_VIDEO_FRAME_COMP_DATA (frame, i);
1027 buf[i].stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
1032 theora_enc_read_multipass_cache (GstTheoraEnc * enc)
1034 GstBuffer *cache_buf;
1035 const guint8 *cache_data;
1036 gsize bytes_read = 0;
1037 gint bytes_consumed = 0;
1038 GIOStatus stat = G_IO_STATUS_NORMAL;
1039 gboolean done = FALSE;
1042 if (gst_adapter_available (enc->multipass_cache_adapter) == 0) {
1045 cache_buf = gst_buffer_new_and_alloc (512);
1047 gst_buffer_map (cache_buf, &map, GST_MAP_READ);
1048 stat = g_io_channel_read_chars (enc->multipass_cache_fd,
1049 (gchar *) map.data, map.size, &bytes_read, NULL);
1051 if (bytes_read <= 0) {
1052 gst_buffer_unmap (cache_buf, &map);
1053 gst_buffer_unref (cache_buf);
1056 gst_buffer_unmap (cache_buf, &map);
1057 gst_buffer_resize (cache_buf, 0, bytes_read);
1058 gst_adapter_push (enc->multipass_cache_adapter, cache_buf);
1061 if (gst_adapter_available (enc->multipass_cache_adapter) == 0)
1065 MIN (gst_adapter_available (enc->multipass_cache_adapter), 512);
1067 cache_data = gst_adapter_map (enc->multipass_cache_adapter, bytes_read);
1070 th_encode_ctl (enc->encoder, TH_ENCCTL_2PASS_IN, (guint8 *) cache_data,
1072 gst_adapter_unmap (enc->multipass_cache_adapter);
1074 done = bytes_consumed <= 0;
1075 if (bytes_consumed > 0)
1076 gst_adapter_flush (enc->multipass_cache_adapter, bytes_consumed);
1079 if (stat == G_IO_STATUS_ERROR || (stat == G_IO_STATUS_EOF && bytes_read == 0)
1080 || bytes_consumed < 0) {
1081 GST_ELEMENT_ERROR (enc, RESOURCE, READ, (NULL),
1082 ("Failed to read multipass cache file"));
1089 theora_enc_write_multipass_cache (GstTheoraEnc * enc, gboolean begin,
1093 GIOStatus stat = G_IO_STATUS_NORMAL;
1094 gint bytes_read = 0;
1095 gsize bytes_written = 0;
1099 stat = g_io_channel_seek_position (enc->multipass_cache_fd, 0, G_SEEK_SET,
1101 if (stat != G_IO_STATUS_ERROR) {
1104 th_encode_ctl (enc->encoder, TH_ENCCTL_2PASS_OUT, &buf, sizeof (buf));
1106 g_io_channel_write_chars (enc->multipass_cache_fd, buf, bytes_read,
1107 &bytes_written, NULL);
1108 } while (bytes_read > 0 && bytes_written > 0);
1112 if (stat == G_IO_STATUS_ERROR || bytes_read < 0) {
1115 GST_ELEMENT_WARNING (enc, RESOURCE, WRITE, (NULL),
1116 ("Failed to seek to beginning of multipass cache file: %s",
1119 GST_ELEMENT_ERROR (enc, RESOURCE, WRITE, (NULL),
1120 ("Failed to seek to beginning of multipass cache file: %s",
1123 GST_ELEMENT_ERROR (enc, RESOURCE, WRITE, (NULL),
1124 ("Failed to write multipass cache file"));
1135 * g_slice_free can't be used with g_queue_foreach.
1136 * so we create new function with predefined GstClockTime size.
1139 theora_free_gstclocktime (gpointer mem)
1141 g_slice_free (GstClockTime, mem);
1145 theora_timefifo_in (GstTheoraEnc * enc, const GstClockTime * timestamp)
1150 enc->t_queue = g_queue_new ();
1152 g_assert (enc->t_queue != NULL);
1154 ptr = g_slice_new (GstClockTime);
1157 g_queue_push_head (enc->t_queue, ptr);
1161 theora_timefifo_out (GstTheoraEnc * enc)
1163 GstClockTime ret, *ptr;
1165 g_assert (enc->t_queue != NULL);
1167 ptr = g_queue_pop_tail (enc->t_queue);
1168 g_assert (ptr != NULL);
1171 theora_free_gstclocktime (ptr);
1177 * theora_timefifo_truncate - truncate the timestamp queue.
1178 * After frame encoding we should have only one buffer for next time.
1179 * The count of timestamps should be the same. If it is less,
1180 * some thing really bad has happened. If it is bigger, encoder
1181 * decided to return less then we ordered.
1182 * TODO: for now we will just drop this timestamps. The better solution
1183 * probably will be to recovery frames by recovery timestamps with
1187 theora_timefifo_truncate (GstTheoraEnc * enc)
1189 if (enc->dup_on_gap) {
1191 g_assert (enc->t_queue != NULL);
1192 length = g_queue_get_length (enc->t_queue);
1195 /* it is also not good if we have more then 1. */
1196 GST_DEBUG_OBJECT (enc, "Dropping %u time stamps", length - 1);
1197 while (g_queue_get_length (enc->t_queue) > 1) {
1198 theora_timefifo_out (enc);
1205 theora_timefifo_free (GstTheoraEnc * enc)
1208 if (g_queue_get_length (enc->t_queue))
1209 g_queue_foreach (enc->t_queue, (GFunc) theora_free_gstclocktime, NULL);
1210 g_queue_free (enc->t_queue);
1211 enc->t_queue = NULL;
1213 /* prevbuf makes no sense without timestamps,
1214 * so clear it too. */
1216 gst_buffer_unref (enc->prevbuf);
1217 enc->prevbuf = NULL;
1223 theora_update_prevbuf (GstTheoraEnc * enc, GstBuffer * buffer)
1226 gst_buffer_unref (enc->prevbuf);
1227 enc->prevbuf = NULL;
1229 enc->prevbuf = gst_buffer_ref (buffer);
1233 * theora_enc_encode_and_push - encode buffer or queued previous buffer
1234 * buffer - buffer to encode. If set to NULL it should encode only
1235 * queued buffers and produce dups if needed.
1238 static GstFlowReturn
1239 theora_enc_encode_and_push (GstTheoraEnc * enc, ogg_packet op,
1243 GstVideoFrame frame;
1244 th_ycbcr_buffer ycbcr;
1247 if (enc->dup_on_gap) {
1248 guint t_queue_length;
1251 t_queue_length = g_queue_get_length (enc->t_queue);
1256 GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
1258 /* videorate can easy create 200 dup frames in one shot.
1259 * In this case th_encode_ctl will just return TH_EINVAL
1260 * and we will generate only one frame as result.
1261 * To make us more bullet proof, make sure we have no
1262 * more dup frames than keyframe interval.
1264 if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_GAP) &&
1265 enc->keyframe_force > t_queue_length) {
1266 GST_DEBUG_OBJECT (enc, "Got GAP frame, queue as duplicate.");
1268 theora_timefifo_in (enc, ×tamp);
1269 gst_buffer_unref (buffer);
1272 theora_timefifo_in (enc, ×tamp);
1273 /* We should have one frame delay to create correct frame order.
1274 * First time we got buffer, prevbuf should be empty. Nothing else
1275 * should be done here.
1277 if (!enc->prevbuf) {
1278 theora_update_prevbuf (enc, buffer);
1279 gst_buffer_unref (buffer);
1282 theora_update_prevbuf (enc, buffer);
1283 /* after theora_update_prevbuf t_queue_length was changed */
1286 if (t_queue_length > 2) {
1287 /* now in t_queue_length should be two real buffers: current and
1288 * previous. All others are timestamps of duplicate frames. */
1289 t_queue_length -= 2;
1290 res = th_encode_ctl (enc->encoder, TH_ENCCTL_SET_DUP_COUNT,
1291 &t_queue_length, sizeof (t_queue_length));
1293 GST_WARNING_OBJECT (enc, "Failed marking dups for last frame");
1298 /* if there is no buffer, then probably we got EOS or discontinuous.
1299 * We need to encode every thing what was left in the queue
1301 GST_DEBUG_OBJECT (enc, "Encode collected buffers.");
1302 if (t_queue_length > 1) {
1304 res = th_encode_ctl (enc->encoder, TH_ENCCTL_SET_DUP_COUNT,
1305 &t_queue_length, sizeof (t_queue_length));
1307 GST_WARNING_OBJECT (enc, "Failed marking dups for last frame.");
1309 GST_DEBUG_OBJECT (enc, "Prevbuffer is empty. Nothing to encode.");
1313 gst_video_frame_map (&frame, &enc->vinfo, enc->prevbuf, GST_MAP_READ);
1314 theora_enc_init_buffer (ycbcr, &frame);
1316 gst_video_frame_map (&frame, &enc->vinfo, buffer, GST_MAP_READ);
1317 theora_enc_init_buffer (ycbcr, &frame);
1320 /* check for buffer, it can be optional */
1321 if (enc->current_discont && buffer) {
1322 GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
1323 GstClockTime running_time =
1324 gst_segment_to_running_time (&enc->segment, GST_FORMAT_TIME, timestamp);
1325 theora_enc_reset (enc);
1326 enc->granulepos_offset =
1327 gst_util_uint64_scale (running_time, enc->vinfo.fps_n,
1328 GST_SECOND * enc->vinfo.fps_d);
1329 enc->timestamp_offset = running_time;
1331 enc->next_discont = TRUE;
1334 if (enc->multipass_cache_fd
1335 && enc->multipass_mode == MULTIPASS_MODE_SECOND_PASS) {
1336 if (!theora_enc_read_multipass_cache (enc)) {
1337 ret = GST_FLOW_ERROR;
1338 goto multipass_read_failed;
1341 #ifdef TH_ENCCTL_SET_DUPLICATE_FLAG
1342 if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_GAP)) {
1343 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_DUPLICATE_FLAG, NULL, 0);
1347 res = th_encode_ycbcr_in (enc->encoder, ycbcr);
1348 /* none of the failure cases can happen here */
1349 g_assert (res == 0);
1351 if (enc->multipass_cache_fd
1352 && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS) {
1353 if (!theora_enc_write_multipass_cache (enc, FALSE, FALSE)) {
1354 ret = GST_FLOW_ERROR;
1355 goto multipass_write_failed;
1360 while (th_encode_packetout (enc->encoder, 0, &op)) {
1361 GstClockTime next_time, duration;
1362 GstClockTime timestamp = 0;
1363 GST_DEBUG_OBJECT (enc, "encoded. granule:%" G_GINT64_FORMAT ", packet:%p, "
1364 "bytes:%ld", (gint64) op.granulepos, op.packet, op.bytes);
1366 next_time = th_granule_time (enc->encoder, op.granulepos) * GST_SECOND;
1367 duration = next_time - enc->next_ts;
1369 if (enc->dup_on_gap && !enc->current_discont)
1370 timestamp = theora_timefifo_out (enc);
1372 timestamp = GST_BUFFER_TIMESTAMP (buffer);
1374 ret = theora_push_packet (enc, &op, timestamp, enc->next_ts, duration);
1376 enc->next_ts = next_time;
1377 if (ret != GST_FLOW_OK) {
1378 theora_timefifo_truncate (enc);
1383 theora_timefifo_truncate (enc);
1385 gst_video_frame_unmap (&frame);
1387 gst_buffer_unref (buffer);
1388 enc->current_discont = FALSE;
1393 multipass_read_failed:
1395 GST_DEBUG_OBJECT (enc, "multipass read failed");
1398 multipass_write_failed:
1400 GST_DEBUG_OBJECT (enc, "multipass write failed");
1405 GST_DEBUG_OBJECT (enc, "error pushing buffer: %s", gst_flow_get_name (ret));
1410 static GstFlowReturn
1411 theora_enc_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
1415 GstClockTime timestamp, duration, running_time;
1417 gboolean force_keyframe;
1419 enc = GST_THEORA_ENC (parent);
1421 /* we keep track of two timelines.
1422 * - The timestamps from the incoming buffers, which we copy to the outgoing
1423 * encoded buffers as-is. We need to do this as we simply forward the
1424 * newsegment events.
1425 * - The running_time of the buffers, which we use to construct the granulepos
1428 timestamp = GST_BUFFER_TIMESTAMP (buffer);
1429 duration = GST_BUFFER_DURATION (buffer);
1432 gst_segment_to_running_time (&enc->segment, GST_FORMAT_TIME, timestamp);
1433 if ((gint64) running_time < 0) {
1434 GST_DEBUG_OBJECT (enc, "Dropping buffer, timestamp: %" GST_TIME_FORMAT,
1435 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
1436 gst_buffer_unref (buffer);
1440 GST_OBJECT_LOCK (enc);
1441 if (enc->bitrate_changed) {
1442 long int bitrate = enc->video_bitrate;
1444 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_BITRATE, &bitrate,
1446 enc->bitrate_changed = FALSE;
1449 if (enc->quality_changed) {
1450 long int quality = enc->video_quality;
1452 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_QUALITY, &quality,
1454 enc->quality_changed = FALSE;
1457 /* see if we need to schedule a keyframe */
1458 force_keyframe = enc->force_keyframe;
1459 enc->force_keyframe = FALSE;
1460 GST_OBJECT_UNLOCK (enc);
1462 if (force_keyframe) {
1463 GstClockTime stream_time;
1466 stream_time = gst_segment_to_stream_time (&enc->segment,
1467 GST_FORMAT_TIME, timestamp);
1469 s = gst_structure_new ("GstForceKeyUnit",
1470 "timestamp", G_TYPE_UINT64, timestamp,
1471 "stream-time", G_TYPE_UINT64, stream_time,
1472 "running-time", G_TYPE_UINT64, running_time, NULL);
1474 theora_enc_force_keyframe (enc);
1476 gst_pad_push_event (enc->srcpad,
1477 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
1480 /* make sure we copy the discont flag to the next outgoing buffer when it's
1481 * set on the incoming buffer */
1482 if (GST_BUFFER_IS_DISCONT (buffer)) {
1483 enc->next_discont = TRUE;
1486 if (enc->packetno == 0) {
1487 /* no packets written yet, setup headers */
1490 GSList *buffers = NULL;
1493 enc->granulepos_offset = 0;
1494 enc->timestamp_offset = 0;
1496 GST_DEBUG_OBJECT (enc, "output headers");
1497 /* Theora streams begin with three headers; the initial header (with
1498 most of the codec setup parameters) which is mandated by the Ogg
1499 bitstream spec. The second header holds any comment fields. The
1500 third header holds the bitstream codebook. We merely need to
1501 make the headers, then pass them to libtheora one at a time;
1502 libtheora handles the additional Ogg bitstream constraints */
1504 /* create the remaining theora headers */
1505 th_comment_clear (&enc->comment);
1506 th_comment_init (&enc->comment);
1509 th_encode_flushheader (enc->encoder, &enc->comment, &op)) > 0) {
1511 theora_buffer_from_packet (enc, &op, GST_CLOCK_TIME_NONE,
1512 GST_CLOCK_TIME_NONE, GST_CLOCK_TIME_NONE, &buf);
1513 if (ret != GST_FLOW_OK) {
1514 goto header_buffer_alloc;
1516 buffers = g_slist_prepend (buffers, buf);
1519 g_slist_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
1520 g_slist_free (buffers);
1521 goto encoder_disabled;
1524 buffers = g_slist_reverse (buffers);
1526 /* mark buffers and put on caps */
1527 caps = gst_caps_new_simple ("video/x-theora",
1528 "width", G_TYPE_INT, enc->vinfo.width,
1529 "height", G_TYPE_INT, enc->vinfo.height,
1530 "framerate", GST_TYPE_FRACTION, enc->vinfo.fps_n, enc->vinfo.fps_d,
1531 "pixel-aspect-ratio", GST_TYPE_FRACTION, enc->vinfo.par_n,
1532 enc->vinfo.par_d, NULL);
1533 caps = theora_set_header_on_caps (caps, buffers);
1534 GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
1535 gst_pad_set_caps (enc->srcpad, caps);
1536 gst_caps_unref (caps);
1538 /* push out the header buffers */
1540 buf = buffers->data;
1541 buffers = g_slist_delete_link (buffers, buffers);
1542 if ((ret = theora_push_buffer (enc, buf)) != GST_FLOW_OK) {
1543 g_slist_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
1544 g_slist_free (buffers);
1549 enc->granulepos_offset =
1550 gst_util_uint64_scale (running_time, enc->vinfo.fps_n,
1551 GST_SECOND * enc->vinfo.fps_d);
1552 enc->timestamp_offset = running_time;
1556 enc->current_discont = theora_enc_is_discontinuous (enc,
1557 running_time, duration);
1559 /* empty queue if discontinuous */
1560 if (enc->current_discont && enc->dup_on_gap)
1561 theora_enc_encode_and_push (enc, op, NULL);
1563 ret = theora_enc_encode_and_push (enc, op, buffer);
1568 header_buffer_alloc:
1570 gst_buffer_unref (buffer);
1575 gst_buffer_unref (buffer);
1580 GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
1581 ("libtheora has been compiled with the encoder disabled"));
1582 gst_buffer_unref (buffer);
1583 return GST_FLOW_ERROR;
1587 static GstStateChangeReturn
1588 theora_enc_change_state (GstElement * element, GstStateChange transition)
1591 GstStateChangeReturn ret;
1594 enc = GST_THEORA_ENC (element);
1596 switch (transition) {
1597 case GST_STATE_CHANGE_NULL_TO_READY:
1598 th_ctx = dummy_encode_ctx ();
1600 GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
1601 ("libtheora has been compiled with the encoder disabled"));
1602 return GST_STATE_CHANGE_FAILURE;
1604 th_encode_free (th_ctx);
1606 case GST_STATE_CHANGE_READY_TO_PAUSED:
1607 GST_DEBUG_OBJECT (enc, "READY->PAUSED Initing theora state");
1608 th_info_init (&enc->info);
1609 th_comment_init (&enc->comment);
1611 enc->force_keyframe = FALSE;
1613 if (enc->multipass_mode >= MULTIPASS_MODE_FIRST_PASS) {
1616 if (!enc->multipass_cache_file) {
1617 ret = GST_STATE_CHANGE_FAILURE;
1618 GST_ELEMENT_ERROR (enc, LIBRARY, SETTINGS, (NULL), (NULL));
1621 enc->multipass_cache_fd =
1622 g_io_channel_new_file (enc->multipass_cache_file,
1623 (enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS ? "w" : "r"),
1626 if (enc->multipass_mode == MULTIPASS_MODE_SECOND_PASS)
1627 enc->multipass_cache_adapter = gst_adapter_new ();
1629 if (!enc->multipass_cache_fd) {
1630 ret = GST_STATE_CHANGE_FAILURE;
1631 GST_ELEMENT_ERROR (enc, RESOURCE, OPEN_READ, (NULL),
1632 ("Failed to open multipass cache file: %s", err->message));
1637 g_io_channel_set_encoding (enc->multipass_cache_fd, NULL, NULL);
1640 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1646 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1648 switch (transition) {
1649 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1651 case GST_STATE_CHANGE_PAUSED_TO_READY:
1652 GST_DEBUG_OBJECT (enc, "PAUSED->READY Clearing theora state");
1654 th_encode_free (enc->encoder);
1655 enc->encoder = NULL;
1657 th_comment_clear (&enc->comment);
1658 th_info_clear (&enc->info);
1660 theora_enc_clear (enc);
1661 enc->initialised = FALSE;
1663 case GST_STATE_CHANGE_READY_TO_NULL:
1673 theora_enc_set_property (GObject * object, guint prop_id,
1674 const GValue * value, GParamSpec * pspec)
1676 GstTheoraEnc *enc = GST_THEORA_ENC (object);
1680 GST_OBJECT_LOCK (enc);
1681 enc->video_bitrate = g_value_get_int (value) * 1000;
1682 enc->bitrate_changed = TRUE;
1683 GST_OBJECT_UNLOCK (enc);
1686 GST_OBJECT_LOCK (enc);
1687 if (GST_STATE (enc) >= GST_STATE_PAUSED && enc->video_bitrate > 0) {
1688 GST_WARNING_OBJECT (object, "Can't change from bitrate to quality mode"
1691 enc->video_quality = g_value_get_int (value);
1692 enc->video_bitrate = 0;
1693 enc->quality_changed = TRUE;
1695 GST_OBJECT_UNLOCK (enc);
1697 case PROP_KEYFRAME_AUTO:
1698 enc->keyframe_auto = g_value_get_boolean (value);
1700 case PROP_KEYFRAME_FREQ:
1701 enc->keyframe_freq = g_value_get_int (value);
1703 case PROP_KEYFRAME_FREQ_FORCE:
1704 enc->keyframe_force = g_value_get_int (value);
1706 case PROP_SPEEDLEVEL:
1707 enc->speed_level = g_value_get_int (value);
1709 th_encode_ctl (enc->encoder, TH_ENCCTL_SET_SPLEVEL, &enc->speed_level,
1710 sizeof (enc->speed_level));
1713 case PROP_VP3_COMPATIBLE:
1714 enc->vp3_compatible = g_value_get_boolean (value);
1716 case PROP_DROP_FRAMES:
1717 enc->drop_frames = g_value_get_boolean (value);
1719 case PROP_CAP_OVERFLOW:
1720 enc->cap_overflow = g_value_get_boolean (value);
1722 case PROP_CAP_UNDERFLOW:
1723 enc->cap_underflow = g_value_get_boolean (value);
1725 case PROP_RATE_BUFFER:
1726 enc->rate_buffer = g_value_get_int (value);
1728 case PROP_MULTIPASS_CACHE_FILE:
1729 enc->multipass_cache_file = g_value_dup_string (value);
1731 case PROP_MULTIPASS_MODE:
1732 enc->multipass_mode = g_value_get_enum (value);
1734 case PROP_DUP_ON_GAP:
1735 enc->dup_on_gap = g_value_get_boolean (value);
1738 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1744 theora_enc_get_property (GObject * object, guint prop_id,
1745 GValue * value, GParamSpec * pspec)
1747 GstTheoraEnc *enc = GST_THEORA_ENC (object);
1751 GST_OBJECT_LOCK (enc);
1752 g_value_set_int (value, enc->video_bitrate / 1000);
1753 GST_OBJECT_UNLOCK (enc);
1756 GST_OBJECT_LOCK (enc);
1757 g_value_set_int (value, enc->video_quality);
1758 GST_OBJECT_UNLOCK (enc);
1760 case PROP_KEYFRAME_AUTO:
1761 g_value_set_boolean (value, enc->keyframe_auto);
1763 case PROP_KEYFRAME_FREQ:
1764 g_value_set_int (value, enc->keyframe_freq);
1766 case PROP_KEYFRAME_FREQ_FORCE:
1767 g_value_set_int (value, enc->keyframe_force);
1769 case PROP_SPEEDLEVEL:
1770 g_value_set_int (value, enc->speed_level);
1772 case PROP_VP3_COMPATIBLE:
1773 g_value_set_boolean (value, enc->vp3_compatible);
1775 case PROP_DROP_FRAMES:
1776 g_value_set_boolean (value, enc->drop_frames);
1778 case PROP_CAP_OVERFLOW:
1779 g_value_set_boolean (value, enc->cap_overflow);
1781 case PROP_CAP_UNDERFLOW:
1782 g_value_set_boolean (value, enc->cap_underflow);
1784 case PROP_RATE_BUFFER:
1785 g_value_set_int (value, enc->rate_buffer);
1787 case PROP_MULTIPASS_CACHE_FILE:
1788 g_value_set_string (value, enc->multipass_cache_file);
1790 case PROP_MULTIPASS_MODE:
1791 g_value_set_enum (value, enc->multipass_mode);
1793 case PROP_DUP_ON_GAP:
1794 g_value_set_boolean (value, enc->dup_on_gap);
1797 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);