Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / ext / theora / gsttheoraenc.c
1 /* GStreamer
2  * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 /**
21  * SECTION:element-theoraenc
22  * @see_also: theoradec, oggmux
23  *
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.
28  *
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
34  * pixels.
35  *
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.
41  *
42  * <refsect2>
43  * <title>Example pipeline</title>
44  * |[
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
48  * stream.
49  * </refsect2>
50  *
51  * Last reviewed on 2006-03-01 (0.10.4)
52  */
53
54 #ifdef HAVE_CONFIG_H
55 #include "config.h"
56 #endif
57
58 #include "gsttheoraenc.h"
59
60 #include <string.h>
61 #include <stdlib.h>             /* free */
62
63 #include <gst/tag/tag.h>
64 #include <gst/video/video.h>
65
66 #define GST_CAT_DEFAULT theoraenc_debug
67 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
68
69 #define GST_TYPE_BORDER_MODE (gst_border_mode_get_type())
70 static GType
71 gst_border_mode_get_type (void)
72 {
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"},
78     {0, NULL, NULL},
79   };
80
81   if (!border_mode_type) {
82     border_mode_type =
83         g_enum_register_static ("GstTheoraEncBorderMode", border_mode);
84   }
85   return border_mode_type;
86 }
87
88 #define GST_TYPE_MULTIPASS_MODE (gst_multipass_mode_get_type())
89 static GType
90 gst_multipass_mode_get_type (void)
91 {
92   static GType multipass_mode_type = 0;
93   static const GEnumValue multipass_mode[] = {
94     {MULTIPASS_MODE_SINGLE_PASS, "Single pass", "single-pass"},
95     {MULTIPASS_MODE_FIRST_PASS, "First pass", "first-pass"},
96     {MULTIPASS_MODE_SECOND_PASS, "Second pass", "second-pass"},
97     {0, NULL, NULL},
98   };
99
100   if (!multipass_mode_type) {
101     multipass_mode_type =
102         g_enum_register_static ("GstTheoraEncMultipassMode", multipass_mode);
103   }
104   return multipass_mode_type;
105 }
106
107 /* taken from theora/lib/toplevel.c */
108 static int
109 _ilog (unsigned int v)
110 {
111   int ret = 0;
112
113   while (v) {
114     ret++;
115     v >>= 1;
116   }
117   return (ret);
118 }
119
120 #define THEORA_DEF_BITRATE              0
121 #define THEORA_DEF_QUALITY              48
122 #define THEORA_DEF_KEYFRAME_AUTO        TRUE
123 #define THEORA_DEF_KEYFRAME_FREQ        64
124 #define THEORA_DEF_KEYFRAME_FREQ_FORCE  64
125 #define THEORA_DEF_SPEEDLEVEL           1
126 #define THEORA_DEF_VP3_COMPATIBLE       FALSE
127 #define THEORA_DEF_DROP_FRAMES          TRUE
128 #define THEORA_DEF_CAP_OVERFLOW         TRUE
129 #define THEORA_DEF_CAP_UNDERFLOW        FALSE
130 #define THEORA_DEF_RATE_BUFFER          0
131 #define THEORA_DEF_MULTIPASS_CACHE_FILE NULL
132 #define THEORA_DEF_MULTIPASS_MODE       MULTIPASS_MODE_SINGLE_PASS
133 enum
134 {
135   PROP_0,
136   PROP_CENTER,
137   PROP_BORDER,
138   PROP_BITRATE,
139   PROP_QUALITY,
140   PROP_QUICK,
141   PROP_KEYFRAME_AUTO,
142   PROP_KEYFRAME_FREQ,
143   PROP_KEYFRAME_FREQ_FORCE,
144   PROP_KEYFRAME_THRESHOLD,
145   PROP_KEYFRAME_MINDISTANCE,
146   PROP_NOISE_SENSITIVITY,
147   PROP_SHARPNESS,
148   PROP_SPEEDLEVEL,
149   PROP_VP3_COMPATIBLE,
150   PROP_DROP_FRAMES,
151   PROP_CAP_OVERFLOW,
152   PROP_CAP_UNDERFLOW,
153   PROP_RATE_BUFFER,
154   PROP_MULTIPASS_CACHE_FILE,
155   PROP_MULTIPASS_MODE
156       /* FILL ME */
157 };
158
159 /* this function does a straight granulepos -> timestamp conversion */
160 static GstClockTime
161 granulepos_to_timestamp (GstTheoraEnc * theoraenc, ogg_int64_t granulepos)
162 {
163   guint64 iframe, pframe;
164   int shift = theoraenc->info.keyframe_granule_shift;
165
166   if (granulepos < 0)
167     return GST_CLOCK_TIME_NONE;
168
169   iframe = granulepos >> shift;
170   pframe = granulepos - (iframe << shift);
171
172   /* num and den are 32 bit, so we can safely multiply with GST_SECOND */
173   return gst_util_uint64_scale ((guint64) (iframe + pframe),
174       GST_SECOND * theoraenc->info.fps_denominator,
175       theoraenc->info.fps_numerator);
176 }
177
178 /* Generate a dummy encoder context for use in th_encode_ctl queries
179    Release with th_encode_free()
180    This and the next routine from theora/examples/libtheora_info.c */
181 static th_enc_ctx *
182 dummy_encode_ctx (void)
183 {
184   th_enc_ctx *ctx;
185   th_info info;
186
187   /* set the minimal video parameters */
188   th_info_init (&info);
189   info.frame_width = 320;
190   info.frame_height = 240;
191   info.fps_numerator = 1;
192   info.fps_denominator = 1;
193
194   /* allocate and initialize a context object */
195   ctx = th_encode_alloc (&info);
196   if (!ctx)
197     GST_WARNING ("Failed to allocate dummy encoder context.");
198
199   /* clear the info struct */
200   th_info_clear (&info);
201
202   return ctx;
203 }
204
205 /* Query the current and maximum values for the 'speed level' setting.
206    This can be used to ask the encoder to trade off encoding quality
207    vs. performance cost, for example to adapt to realtime constraints. */
208 static int
209 check_speed_level (th_enc_ctx * ctx, int *current, int *max)
210 {
211   int ret;
212
213   /* query the current speed level */
214   ret = th_encode_ctl (ctx, TH_ENCCTL_GET_SPLEVEL, current, sizeof (int));
215   if (ret) {
216     GST_WARNING ("Error %d getting current speed level.", ret);
217     return ret;
218   }
219   /* query the maximum speed level, which varies by encoder version */
220   ret = th_encode_ctl (ctx, TH_ENCCTL_GET_SPLEVEL_MAX, max, sizeof (int));
221   if (ret) {
222     GST_WARNING ("Error %d getting maximum speed level.", ret);
223     return ret;
224   }
225
226   return 0;
227 }
228
229 static GstStaticPadTemplate theora_enc_sink_factory =
230 GST_STATIC_PAD_TEMPLATE ("sink",
231     GST_PAD_SINK,
232     GST_PAD_ALWAYS,
233     GST_STATIC_CAPS ("video/x-raw-yuv, "
234         "format = (fourcc) { I420, Y42B, Y444 }, "
235         "framerate = (fraction) [1/MAX, MAX], "
236         "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
237     );
238
239 static GstStaticPadTemplate theora_enc_src_factory =
240 GST_STATIC_PAD_TEMPLATE ("src",
241     GST_PAD_SRC,
242     GST_PAD_ALWAYS,
243     GST_STATIC_CAPS ("video/x-theora")
244     );
245
246 static void
247 _do_init (GType object_type)
248 {
249   const GInterfaceInfo preset_interface_info = {
250     NULL,                       /* interface_init */
251     NULL,                       /* interface_finalize */
252     NULL                        /* interface_data */
253   };
254
255   g_type_add_interface_static (object_type, GST_TYPE_PRESET,
256       &preset_interface_info);
257 }
258
259 GST_BOILERPLATE_FULL (GstTheoraEnc, gst_theora_enc, GstElement,
260     GST_TYPE_ELEMENT, _do_init);
261
262 static gboolean theora_enc_sink_event (GstPad * pad, GstEvent * event);
263 static gboolean theora_enc_src_event (GstPad * pad, GstEvent * event);
264 static GstFlowReturn theora_enc_chain (GstPad * pad, GstBuffer * buffer);
265 static GstStateChangeReturn theora_enc_change_state (GstElement * element,
266     GstStateChange transition);
267 static GstCaps *theora_enc_sink_getcaps (GstPad * pad);
268 static gboolean theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps);
269 static void theora_enc_get_property (GObject * object, guint prop_id,
270     GValue * value, GParamSpec * pspec);
271 static void theora_enc_set_property (GObject * object, guint prop_id,
272     const GValue * value, GParamSpec * pspec);
273 static void theora_enc_finalize (GObject * object);
274
275 static gboolean theora_enc_write_multipass_cache (GstTheoraEnc * enc,
276     gboolean begin, gboolean eos);
277
278 static void
279 gst_theora_enc_base_init (gpointer g_class)
280 {
281   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
282
283   gst_element_class_add_pad_template (element_class,
284       gst_static_pad_template_get (&theora_enc_src_factory));
285   gst_element_class_add_pad_template (element_class,
286       gst_static_pad_template_get (&theora_enc_sink_factory));
287   gst_element_class_set_details_simple (element_class,
288       "Theora video encoder", "Codec/Encoder/Video",
289       "encode raw YUV video to a theora stream",
290       "Wim Taymans <wim@fluendo.com>");
291 }
292
293 static void
294 gst_theora_enc_class_init (GstTheoraEncClass * klass)
295 {
296   GObjectClass *gobject_class = (GObjectClass *) klass;
297   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
298
299   /* query runtime encoder properties */
300   th_enc_ctx *th_ctx;
301   int default_speed_level = THEORA_DEF_SPEEDLEVEL;
302   int max_speed_level = default_speed_level;
303
304   GST_DEBUG_CATEGORY_INIT (theoraenc_debug, "theoraenc", 0, "Theora encoder");
305
306   th_ctx = dummy_encode_ctx ();
307   if (th_ctx) {
308     if (!check_speed_level (th_ctx, &default_speed_level, &max_speed_level))
309       GST_WARNING
310           ("Failed to determine settings for the speed-level property.");
311     th_encode_free (th_ctx);
312   }
313
314   gobject_class->set_property = theora_enc_set_property;
315   gobject_class->get_property = theora_enc_get_property;
316   gobject_class->finalize = theora_enc_finalize;
317
318   g_object_class_install_property (gobject_class, PROP_CENTER,
319       g_param_spec_boolean ("center", "Center",
320           "ignored and kept for API compat only", TRUE,
321           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
322   g_object_class_install_property (gobject_class, PROP_BORDER,
323       g_param_spec_enum ("border", "Border",
324           "ignored and kept for API compat only",
325           GST_TYPE_BORDER_MODE, BORDER_BLACK,
326           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
327   /* general encoding stream options */
328   g_object_class_install_property (gobject_class, PROP_BITRATE,
329       g_param_spec_int ("bitrate", "Bitrate", "Compressed video bitrate (kbps)",
330           0, (1 << 24) - 1, THEORA_DEF_BITRATE,
331           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
332           GST_PARAM_MUTABLE_PLAYING));
333   g_object_class_install_property (gobject_class, PROP_QUALITY,
334       g_param_spec_int ("quality", "Quality", "Video quality", 0, 63,
335           THEORA_DEF_QUALITY,
336           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
337           GST_PARAM_MUTABLE_PLAYING));
338   g_object_class_install_property (gobject_class, PROP_QUICK,
339       g_param_spec_boolean ("quick", "Quick",
340           "ignored and kept for API compat only", TRUE,
341           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
342   g_object_class_install_property (gobject_class, PROP_KEYFRAME_AUTO,
343       g_param_spec_boolean ("keyframe-auto", "Keyframe Auto",
344           "Automatic keyframe detection", THEORA_DEF_KEYFRAME_AUTO,
345           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
346   g_object_class_install_property (gobject_class, PROP_KEYFRAME_FREQ,
347       g_param_spec_int ("keyframe-freq", "Keyframe frequency",
348           "Keyframe frequency", 1, 32768, THEORA_DEF_KEYFRAME_FREQ,
349           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
350   g_object_class_install_property (gobject_class, PROP_KEYFRAME_FREQ_FORCE,
351       g_param_spec_int ("keyframe-force", "Keyframe force",
352           "Force keyframe every N frames", 1, 32768,
353           THEORA_DEF_KEYFRAME_FREQ_FORCE,
354           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
355   g_object_class_install_property (gobject_class, PROP_KEYFRAME_THRESHOLD,
356       g_param_spec_int ("keyframe-threshold", "Keyframe threshold",
357           "ignored and kept for API compat only", 0, 32768, 80,
358           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
359   g_object_class_install_property (gobject_class, PROP_KEYFRAME_MINDISTANCE,
360       g_param_spec_int ("keyframe-mindistance", "Keyframe mindistance",
361           "ignored and kept for API compat only", 1, 32768, 8,
362           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
363   g_object_class_install_property (gobject_class, PROP_NOISE_SENSITIVITY,
364       g_param_spec_int ("noise-sensitivity", "Noise sensitivity",
365           "ignored and kept for API compat only", 0, 32768, 1,
366           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
367   g_object_class_install_property (gobject_class, PROP_SHARPNESS,
368       g_param_spec_int ("sharpness", "Sharpness",
369           "ignored and kept for API compat only", 0, 2, 0,
370           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
371   g_object_class_install_property (gobject_class, PROP_SPEEDLEVEL,
372       g_param_spec_int ("speed-level", "Speed level",
373           "Controls the amount of analysis performed when encoding."
374           " Higher values trade compression quality for speed."
375           " This property requires libtheora version >= 1.0"
376           ", and the maximum value may vary based on encoder version.",
377           0, max_speed_level, default_speed_level,
378           (GParamFlags) G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
379           G_PARAM_STATIC_STRINGS));
380   g_object_class_install_property (gobject_class, PROP_VP3_COMPATIBLE,
381       g_param_spec_boolean ("vp3-compatible", "VP3 Compatible",
382           "Disables non-VP3 compatible features",
383           THEORA_DEF_VP3_COMPATIBLE,
384           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
385   g_object_class_install_property (gobject_class, PROP_DROP_FRAMES,
386       g_param_spec_boolean ("drop-frames", "VP3 Compatible",
387           "Allow or disallow frame dropping",
388           THEORA_DEF_DROP_FRAMES,
389           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
390   g_object_class_install_property (gobject_class, PROP_CAP_OVERFLOW,
391       g_param_spec_boolean ("cap-overflow", "VP3 Compatible",
392           "Enable capping of bit reservoir overflows",
393           THEORA_DEF_CAP_OVERFLOW,
394           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
395   g_object_class_install_property (gobject_class, PROP_CAP_UNDERFLOW,
396       g_param_spec_boolean ("cap-underflow", "VP3 Compatible",
397           "Enable capping of bit reservoir underflows",
398           THEORA_DEF_CAP_UNDERFLOW,
399           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
400   g_object_class_install_property (gobject_class, PROP_RATE_BUFFER,
401       g_param_spec_int ("rate-buffer", "Rate Control Buffer",
402           "Sets the size of the rate control buffer, in units of frames.  "
403           "The default value of 0 instructs the encoder to automatically "
404           "select an appropriate value",
405           0, 1000, THEORA_DEF_RATE_BUFFER,
406           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
407   g_object_class_install_property (gobject_class, PROP_MULTIPASS_CACHE_FILE,
408       g_param_spec_string ("multipass-cache-file", "Multipass Cache File",
409           "Multipass cache file", THEORA_DEF_MULTIPASS_CACHE_FILE,
410           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
411   g_object_class_install_property (gobject_class, PROP_MULTIPASS_MODE,
412       g_param_spec_enum ("multipass-mode", "Multipass mode",
413           "Single pass or first/second pass", GST_TYPE_MULTIPASS_MODE,
414           THEORA_DEF_MULTIPASS_MODE,
415           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
416
417   gstelement_class->change_state = theora_enc_change_state;
418 }
419
420 static void
421 gst_theora_enc_init (GstTheoraEnc * enc, GstTheoraEncClass * g_class)
422 {
423   enc->sinkpad =
424       gst_pad_new_from_static_template (&theora_enc_sink_factory, "sink");
425   gst_pad_set_chain_function (enc->sinkpad, theora_enc_chain);
426   gst_pad_set_event_function (enc->sinkpad, theora_enc_sink_event);
427   gst_pad_set_getcaps_function (enc->sinkpad, theora_enc_sink_getcaps);
428   gst_pad_set_setcaps_function (enc->sinkpad, theora_enc_sink_setcaps);
429   gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad);
430
431   enc->srcpad =
432       gst_pad_new_from_static_template (&theora_enc_src_factory, "src");
433   gst_pad_set_event_function (enc->srcpad, theora_enc_src_event);
434   gst_element_add_pad (GST_ELEMENT (enc), enc->srcpad);
435
436   gst_segment_init (&enc->segment, GST_FORMAT_UNDEFINED);
437
438   enc->video_bitrate = THEORA_DEF_BITRATE;
439   enc->video_quality = THEORA_DEF_QUALITY;
440   enc->keyframe_auto = THEORA_DEF_KEYFRAME_AUTO;
441   enc->keyframe_freq = THEORA_DEF_KEYFRAME_FREQ;
442   enc->keyframe_force = THEORA_DEF_KEYFRAME_FREQ_FORCE;
443
444   enc->expected_ts = GST_CLOCK_TIME_NONE;
445
446   /* enc->speed_level is set to the libtheora default by the constructor */
447   enc->vp3_compatible = THEORA_DEF_VP3_COMPATIBLE;
448   enc->drop_frames = THEORA_DEF_DROP_FRAMES;
449   enc->cap_overflow = THEORA_DEF_CAP_OVERFLOW;
450   enc->cap_underflow = THEORA_DEF_CAP_UNDERFLOW;
451   enc->rate_buffer = THEORA_DEF_RATE_BUFFER;
452
453   enc->multipass_mode = THEORA_DEF_MULTIPASS_MODE;
454   enc->multipass_cache_file = THEORA_DEF_MULTIPASS_CACHE_FILE;
455 }
456
457 static void
458 theora_enc_clear_multipass_cache (GstTheoraEnc * enc)
459 {
460   if (enc->multipass_cache_fd) {
461     g_io_channel_shutdown (enc->multipass_cache_fd, TRUE, NULL);
462     g_io_channel_unref (enc->multipass_cache_fd);
463     enc->multipass_cache_fd = NULL;
464   }
465
466   if (enc->multipass_cache_adapter) {
467     gst_object_unref (enc->multipass_cache_adapter);
468     enc->multipass_cache_adapter = NULL;
469   }
470 }
471
472 static void
473 theora_enc_finalize (GObject * object)
474 {
475   GstTheoraEnc *enc = GST_THEORA_ENC (object);
476
477   GST_DEBUG_OBJECT (enc, "Finalizing");
478   if (enc->encoder)
479     th_encode_free (enc->encoder);
480   th_comment_clear (&enc->comment);
481   th_info_clear (&enc->info);
482   g_free (enc->multipass_cache_file);
483
484   theora_enc_clear_multipass_cache (enc);
485
486   G_OBJECT_CLASS (parent_class)->finalize (object);
487 }
488
489 static void
490 theora_enc_reset (GstTheoraEnc * enc)
491 {
492   ogg_uint32_t keyframe_force;
493   int rate_flags;
494
495   GST_OBJECT_LOCK (enc);
496   enc->info.target_bitrate = enc->video_bitrate;
497   enc->info.quality = enc->video_quality;
498   enc->bitrate_changed = FALSE;
499   enc->quality_changed = FALSE;
500   GST_OBJECT_UNLOCK (enc);
501
502   if (enc->encoder)
503     th_encode_free (enc->encoder);
504   enc->encoder = th_encode_alloc (&enc->info);
505   /* We ensure this function cannot fail. */
506   g_assert (enc->encoder != NULL);
507   th_encode_ctl (enc->encoder, TH_ENCCTL_SET_SPLEVEL, &enc->speed_level,
508       sizeof (enc->speed_level));
509   th_encode_ctl (enc->encoder, TH_ENCCTL_SET_VP3_COMPATIBLE,
510       &enc->vp3_compatible, sizeof (enc->vp3_compatible));
511
512   rate_flags = 0;
513   if (enc->drop_frames)
514     rate_flags |= TH_RATECTL_DROP_FRAMES;
515   if (enc->drop_frames)
516     rate_flags |= TH_RATECTL_CAP_OVERFLOW;
517   if (enc->drop_frames)
518     rate_flags |= TH_RATECTL_CAP_UNDERFLOW;
519   th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_FLAGS,
520       &rate_flags, sizeof (rate_flags));
521
522   if (enc->rate_buffer) {
523     th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_BUFFER,
524         &enc->rate_buffer, sizeof (enc->rate_buffer));
525   } else {
526     /* FIXME */
527   }
528
529   keyframe_force = enc->keyframe_auto ?
530       enc->keyframe_force : enc->keyframe_freq;
531   th_encode_ctl (enc->encoder, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
532       &keyframe_force, sizeof (keyframe_force));
533
534   /* Get placeholder data */
535   if (enc->multipass_cache_fd
536       && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS)
537     theora_enc_write_multipass_cache (enc, TRUE, FALSE);
538 }
539
540 static void
541 theora_enc_clear (GstTheoraEnc * enc)
542 {
543   enc->packetno = 0;
544   enc->bytes_out = 0;
545   enc->granulepos_offset = 0;
546   enc->timestamp_offset = 0;
547
548   enc->next_ts = GST_CLOCK_TIME_NONE;
549   enc->next_discont = FALSE;
550   enc->expected_ts = GST_CLOCK_TIME_NONE;
551 }
552
553 static char *
554 theora_enc_get_supported_formats (void)
555 {
556   th_enc_ctx *encoder;
557   th_info info;
558   struct
559   {
560     th_pixel_fmt pixelformat;
561     const char *fourcc;
562   } formats[] = {
563     {
564     TH_PF_420, "I420"}, {
565     TH_PF_422, "Y42B"}, {
566     TH_PF_444, "Y444"}
567   };
568   GString *string = NULL;
569   guint i;
570
571   th_info_init (&info);
572   info.frame_width = 16;
573   info.frame_height = 16;
574   info.fps_numerator = 25;
575   info.fps_denominator = 1;
576   for (i = 0; i < G_N_ELEMENTS (formats); i++) {
577     info.pixel_fmt = formats[i].pixelformat;
578
579     encoder = th_encode_alloc (&info);
580     if (encoder == NULL)
581       continue;
582
583     GST_LOG ("format %s is supported", formats[i].fourcc);
584     th_encode_free (encoder);
585
586     if (string == NULL) {
587       string = g_string_new (formats[i].fourcc);
588     } else {
589       g_string_append (string, ", ");
590       g_string_append (string, formats[i].fourcc);
591     }
592   }
593   th_info_clear (&info);
594
595   return string == NULL ? NULL : g_string_free (string, FALSE);
596 }
597
598 static GstCaps *
599 theora_enc_sink_getcaps (GstPad * pad)
600 {
601   GstCaps *caps;
602   char *supported_formats, *caps_string;
603
604   supported_formats = theora_enc_get_supported_formats ();
605   if (!supported_formats) {
606     GST_WARNING ("no supported formats found. Encoder disabled?");
607     return gst_caps_new_empty ();
608   }
609
610   caps_string = g_strdup_printf ("video/x-raw-yuv, "
611       "format = (fourcc) { %s }, "
612       "framerate = (fraction) [1/MAX, MAX], "
613       "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]",
614       supported_formats);
615   caps = gst_caps_from_string (caps_string);
616   g_free (caps_string);
617   g_free (supported_formats);
618   GST_DEBUG ("Supported caps: %" GST_PTR_FORMAT, caps);
619
620   return caps;
621 }
622
623 static gboolean
624 theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
625 {
626   GstStructure *structure = gst_caps_get_structure (caps, 0);
627   GstTheoraEnc *enc = GST_THEORA_ENC (gst_pad_get_parent (pad));
628   guint32 fourcc;
629   const GValue *par;
630   gint fps_n, fps_d;
631
632   gst_structure_get_fourcc (structure, "format", &fourcc);
633   gst_structure_get_int (structure, "width", &enc->width);
634   gst_structure_get_int (structure, "height", &enc->height);
635   gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d);
636   par = gst_structure_get_value (structure, "pixel-aspect-ratio");
637
638   th_info_clear (&enc->info);
639   th_info_init (&enc->info);
640   /* Theora has a divisible-by-sixteen restriction for the encoded video size but
641    * we can define a picture area using pic_width/pic_height */
642   enc->info.frame_width = GST_ROUND_UP_16 (enc->width);
643   enc->info.frame_height = GST_ROUND_UP_16 (enc->height);
644   enc->info.pic_width = enc->width;
645   enc->info.pic_height = enc->height;
646   switch (fourcc) {
647     case GST_MAKE_FOURCC ('I', '4', '2', '0'):
648       enc->info.pixel_fmt = TH_PF_420;
649       break;
650     case GST_MAKE_FOURCC ('Y', '4', '2', 'B'):
651       enc->info.pixel_fmt = TH_PF_422;
652       break;
653     case GST_MAKE_FOURCC ('Y', '4', '4', '4'):
654       enc->info.pixel_fmt = TH_PF_444;
655       break;
656     default:
657       g_assert_not_reached ();
658   }
659
660   enc->info.fps_numerator = enc->fps_n = fps_n;
661   enc->info.fps_denominator = enc->fps_d = fps_d;
662   if (par) {
663     enc->info.aspect_numerator = gst_value_get_fraction_numerator (par);
664     enc->info.aspect_denominator = gst_value_get_fraction_denominator (par);
665   } else {
666     /* setting them to 0 indicates that the decoder can chose a good aspect
667      * ratio, defaulting to 1/1 */
668     enc->info.aspect_numerator = 0;
669     enc->info.aspect_denominator = 0;
670   }
671
672   enc->info.colorspace = TH_CS_UNSPECIFIED;
673
674   /* as done in theora */
675   enc->info.keyframe_granule_shift = _ilog (enc->keyframe_force - 1);
676   GST_DEBUG_OBJECT (enc,
677       "keyframe_frequency_force is %d, granule shift is %d",
678       enc->keyframe_force, enc->info.keyframe_granule_shift);
679
680   theora_enc_reset (enc);
681   enc->initialised = TRUE;
682
683   gst_object_unref (enc);
684
685   return TRUE;
686 }
687
688 static guint64
689 granulepos_add (guint64 granulepos, guint64 addend, gint shift)
690 {
691   guint64 iframe, pframe;
692
693   iframe = granulepos >> shift;
694   pframe = granulepos - (iframe << shift);
695   iframe += addend;
696
697   return (iframe << shift) + pframe;
698 }
699
700 /* prepare a buffer for transmission by passing data through libtheora */
701 static GstFlowReturn
702 theora_buffer_from_packet (GstTheoraEnc * enc, ogg_packet * packet,
703     GstClockTime timestamp, GstClockTime running_time,
704     GstClockTime duration, GstBuffer ** buffer)
705 {
706   GstBuffer *buf;
707   GstFlowReturn ret = GST_FLOW_OK;
708
709   buf = gst_buffer_new_and_alloc (packet->bytes);
710   if (!buf) {
711     GST_WARNING_OBJECT (enc, "Could not allocate buffer");
712     ret = GST_FLOW_ERROR;
713     goto done;
714   }
715
716   gst_buffer_fill (buf, 0, packet->packet, packet->bytes);
717   gst_buffer_set_caps (buf, GST_PAD_CAPS (enc->srcpad));
718   /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
719    * time representation */
720   GST_BUFFER_OFFSET_END (buf) =
721       granulepos_add (packet->granulepos, enc->granulepos_offset,
722       enc->info.keyframe_granule_shift);
723   GST_BUFFER_OFFSET (buf) = granulepos_to_timestamp (enc,
724       GST_BUFFER_OFFSET_END (buf));
725
726   GST_BUFFER_TIMESTAMP (buf) = timestamp;
727   GST_BUFFER_DURATION (buf) = duration;
728
729   if (enc->next_discont) {
730     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
731     enc->next_discont = FALSE;
732   }
733
734   /* the second most significant bit of the first data byte is cleared
735    * for keyframes */
736   if (packet->bytes > 0 && (packet->packet[0] & 0x40) == 0) {
737     GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
738   } else {
739     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
740   }
741   enc->packetno++;
742
743 done:
744   *buffer = buf;
745   return ret;
746 }
747
748 /* push out the buffer and do internal bookkeeping */
749 static GstFlowReturn
750 theora_push_buffer (GstTheoraEnc * enc, GstBuffer * buffer)
751 {
752   GstFlowReturn ret;
753
754   enc->bytes_out += gst_buffer_get_size (buffer);
755
756   ret = gst_pad_push (enc->srcpad, buffer);
757
758   return ret;
759 }
760
761 static GstFlowReturn
762 theora_push_packet (GstTheoraEnc * enc, ogg_packet * packet,
763     GstClockTime timestamp, GstClockTime running_time, GstClockTime duration)
764 {
765   GstBuffer *buf;
766   GstFlowReturn ret;
767
768   ret =
769       theora_buffer_from_packet (enc, packet, timestamp, running_time, duration,
770       &buf);
771   if (ret == GST_FLOW_OK)
772     ret = theora_push_buffer (enc, buf);
773
774   return ret;
775 }
776
777 static GstCaps *
778 theora_set_header_on_caps (GstCaps * caps, GSList * buffers)
779 {
780   GstStructure *structure;
781   GValue array = { 0 };
782   GValue value = { 0 };
783   GstBuffer *buffer;
784   GSList *walk;
785
786   caps = gst_caps_make_writable (caps);
787   structure = gst_caps_get_structure (caps, 0);
788
789   /* put copies of the buffers in a fixed list */
790   g_value_init (&array, GST_TYPE_ARRAY);
791
792   for (walk = buffers; walk; walk = walk->next) {
793     buffer = walk->data;
794
795     /* mark buffer */
796     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_IN_CAPS);
797
798     /* Copy buffer, because we can't use the original -
799      * it creates a circular refcount with the caps<->buffers */
800     buffer = gst_buffer_copy (buffer);
801
802     g_value_init (&value, GST_TYPE_BUFFER);
803     gst_value_set_buffer (&value, buffer);
804     gst_value_array_append_value (&array, &value);
805     g_value_unset (&value);
806
807     /* Unref our copy */
808     gst_buffer_unref (buffer);
809   }
810
811   gst_structure_set_value (structure, "streamheader", &array);
812   g_value_unset (&array);
813
814   return caps;
815 }
816
817 static void
818 theora_enc_force_keyframe (GstTheoraEnc * enc)
819 {
820   GstClockTime next_ts;
821
822   /* make sure timestamps increment after resetting the decoder */
823   next_ts = enc->next_ts + enc->timestamp_offset;
824
825   theora_enc_reset (enc);
826   enc->granulepos_offset =
827       gst_util_uint64_scale (next_ts, enc->fps_n, GST_SECOND * enc->fps_d);
828   enc->timestamp_offset = next_ts;
829   enc->next_ts = 0;
830 }
831
832 static gboolean
833 theora_enc_sink_event (GstPad * pad, GstEvent * event)
834 {
835   GstTheoraEnc *enc;
836   ogg_packet op;
837   gboolean res;
838
839   enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));
840
841   switch (GST_EVENT_TYPE (event)) {
842     case GST_EVENT_NEWSEGMENT:
843     {
844       gboolean update;
845       gdouble rate, applied_rate;
846       GstFormat format;
847       gint64 start, stop, time;
848
849       gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
850           &format, &start, &stop, &time);
851
852       gst_segment_set_newsegment_full (&enc->segment, update, rate,
853           applied_rate, format, start, stop, time);
854
855       res = gst_pad_push_event (enc->srcpad, event);
856       break;
857     }
858     case GST_EVENT_EOS:
859       if (enc->initialised) {
860         /* push last packet with eos flag, should not be called */
861         while (th_encode_packetout (enc->encoder, 1, &op)) {
862           GstClockTime next_time =
863               th_granule_time (enc->encoder, op.granulepos) * GST_SECOND;
864
865           theora_push_packet (enc, &op, GST_CLOCK_TIME_NONE, enc->next_ts,
866               next_time - enc->next_ts);
867           enc->next_ts = next_time;
868         }
869       }
870       if (enc->initialised && enc->multipass_cache_fd
871           && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS)
872         theora_enc_write_multipass_cache (enc, TRUE, TRUE);
873
874       theora_enc_clear_multipass_cache (enc);
875
876       res = gst_pad_push_event (enc->srcpad, event);
877       break;
878     case GST_EVENT_FLUSH_STOP:
879       gst_segment_init (&enc->segment, GST_FORMAT_UNDEFINED);
880       res = gst_pad_push_event (enc->srcpad, event);
881       break;
882     case GST_EVENT_CUSTOM_DOWNSTREAM:
883     {
884       const GstStructure *s;
885
886       s = gst_event_get_structure (event);
887
888       if (gst_structure_has_name (s, "GstForceKeyUnit"))
889         theora_enc_force_keyframe (enc);
890       res = gst_pad_push_event (enc->srcpad, event);
891       break;
892     }
893     default:
894       res = gst_pad_push_event (enc->srcpad, event);
895       break;
896   }
897   return res;
898 }
899
900 static gboolean
901 theora_enc_src_event (GstPad * pad, GstEvent * event)
902 {
903   GstTheoraEnc *enc;
904   gboolean res = TRUE;
905
906   enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));
907
908   switch (GST_EVENT_TYPE (event)) {
909     case GST_EVENT_CUSTOM_UPSTREAM:
910     {
911       const GstStructure *s;
912
913       s = gst_event_get_structure (event);
914
915       if (gst_structure_has_name (s, "GstForceKeyUnit")) {
916         GST_OBJECT_LOCK (enc);
917         enc->force_keyframe = TRUE;
918         GST_OBJECT_UNLOCK (enc);
919         /* consume the event */
920         res = TRUE;
921         gst_event_unref (event);
922       } else {
923         res = gst_pad_push_event (enc->sinkpad, event);
924       }
925       break;
926     }
927     default:
928       res = gst_pad_push_event (enc->sinkpad, event);
929       break;
930   }
931
932   return res;
933 }
934
935 static gboolean
936 theora_enc_is_discontinuous (GstTheoraEnc * enc, GstClockTime timestamp,
937     GstClockTime duration)
938 {
939   GstClockTimeDiff max_diff;
940   gboolean ret = FALSE;
941
942   /* Allow 3/4 a frame off */
943   max_diff = (enc->info.fps_denominator * GST_SECOND * 3) /
944       (enc->info.fps_numerator * 4);
945
946   if (timestamp != GST_CLOCK_TIME_NONE
947       && enc->expected_ts != GST_CLOCK_TIME_NONE) {
948     if ((GstClockTimeDiff) (timestamp - enc->expected_ts) > max_diff) {
949       GST_DEBUG_OBJECT (enc, "Incoming TS %" GST_TIME_FORMAT
950           " exceeds expected value %" GST_TIME_FORMAT
951           " by too much, marking discontinuity",
952           GST_TIME_ARGS (timestamp), GST_TIME_ARGS (enc->expected_ts));
953       ret = TRUE;
954     }
955   }
956
957   if (GST_CLOCK_TIME_IS_VALID (duration))
958     enc->expected_ts = timestamp + duration;
959   else
960     enc->expected_ts = GST_CLOCK_TIME_NONE;
961
962   return ret;
963 }
964
965 static void
966 theora_enc_init_buffer (th_ycbcr_buffer buf, th_info * info, guint8 * data)
967 {
968   GstVideoFormat format;
969   guint i;
970
971   switch (info->pixel_fmt) {
972     case TH_PF_444:
973       format = GST_VIDEO_FORMAT_Y444;
974       break;
975     case TH_PF_420:
976       format = GST_VIDEO_FORMAT_I420;
977       break;
978     case TH_PF_422:
979       format = GST_VIDEO_FORMAT_Y42B;
980       break;
981     default:
982       g_assert_not_reached ();
983   }
984
985   /* According to Theora developer Timothy Terriberry, the Theora 
986    * encoder will not use memory outside of pic_width/height, even when
987    * the frame size is bigger. The values outside this region will be encoded
988    * to default values.
989    * Due to this, setting the frame's width/height as the buffer width/height
990    * is perfectly ok, even though it does not strictly look ok.
991    */
992   for (i = 0; i < 3; i++) {
993     buf[i].width =
994         gst_video_format_get_component_width (format, i, info->frame_width);
995     buf[i].height =
996         gst_video_format_get_component_height (format, i, info->frame_height);
997
998     buf[i].data =
999         data + gst_video_format_get_component_offset (format, i,
1000         info->pic_width, info->pic_height);
1001     buf[i].stride =
1002         gst_video_format_get_row_stride (format, i, info->pic_width);
1003   }
1004 }
1005
1006 static gboolean
1007 theora_enc_read_multipass_cache (GstTheoraEnc * enc)
1008 {
1009   GstBuffer *cache_buf;
1010   const guint8 *cache_data;
1011   gsize bytes_read = 0, bytes_consumed = 0;
1012   GIOStatus stat = G_IO_STATUS_NORMAL;
1013   gboolean done = FALSE;
1014
1015   while (!done) {
1016     if (gst_adapter_available (enc->multipass_cache_adapter) == 0) {
1017       guint8 *data;
1018       gsize size;
1019
1020       cache_buf = gst_buffer_new_and_alloc (512);
1021
1022       data = gst_buffer_map (cache_buf, &size, NULL, GST_MAP_READ);
1023       stat = g_io_channel_read_chars (enc->multipass_cache_fd,
1024           (gchar *) data, size, &bytes_read, NULL);
1025
1026       if (bytes_read <= 0) {
1027         gst_buffer_unmap (cache_buf, data, 0);
1028         gst_buffer_unref (cache_buf);
1029         break;
1030       } else {
1031         gst_buffer_unmap (cache_buf, data, bytes_read);
1032         gst_adapter_push (enc->multipass_cache_adapter, cache_buf);
1033       }
1034     }
1035     if (gst_adapter_available (enc->multipass_cache_adapter) == 0)
1036       break;
1037
1038     bytes_read =
1039         MIN (gst_adapter_available (enc->multipass_cache_adapter), 512);
1040
1041     cache_data = gst_adapter_map (enc->multipass_cache_adapter, bytes_read);
1042
1043     bytes_consumed =
1044         th_encode_ctl (enc->encoder, TH_ENCCTL_2PASS_IN, (guint8 *) cache_data,
1045         bytes_read);
1046     gst_adapter_unmap (enc->multipass_cache_adapter, 0);
1047
1048     done = bytes_consumed <= 0;
1049     if (bytes_consumed > 0)
1050       gst_adapter_flush (enc->multipass_cache_adapter, bytes_consumed);
1051   }
1052
1053   if (stat == G_IO_STATUS_ERROR || (stat == G_IO_STATUS_EOF && bytes_read == 0)
1054       || bytes_consumed < 0) {
1055     GST_ELEMENT_ERROR (enc, RESOURCE, READ, (NULL),
1056         ("Failed to read multipass cache file"));
1057     return FALSE;
1058   }
1059   return TRUE;
1060 }
1061
1062 static gboolean
1063 theora_enc_write_multipass_cache (GstTheoraEnc * enc, gboolean begin,
1064     gboolean eos)
1065 {
1066   GError *err = NULL;
1067   GIOStatus stat = G_IO_STATUS_NORMAL;
1068   gint bytes_read = 0;
1069   gsize bytes_written = 0;
1070   gchar *buf;
1071
1072   if (begin)
1073     stat = g_io_channel_seek_position (enc->multipass_cache_fd, 0, G_SEEK_SET,
1074         &err);
1075   if (stat != G_IO_STATUS_ERROR) {
1076     do {
1077       bytes_read =
1078           th_encode_ctl (enc->encoder, TH_ENCCTL_2PASS_OUT, &buf, sizeof (buf));
1079       if (bytes_read > 0)
1080         g_io_channel_write_chars (enc->multipass_cache_fd, buf, bytes_read,
1081             &bytes_written, NULL);
1082     } while (bytes_read > 0 && bytes_written > 0);
1083
1084   }
1085
1086   if (stat == G_IO_STATUS_ERROR || bytes_read < 0 || bytes_written < 0) {
1087     if (begin) {
1088       if (eos)
1089         GST_ELEMENT_WARNING (enc, RESOURCE, WRITE, (NULL),
1090             ("Failed to seek to beginning of multipass cache file: %s",
1091                 err->message));
1092       else
1093         GST_ELEMENT_ERROR (enc, RESOURCE, WRITE, (NULL),
1094             ("Failed to seek to beginning of multipass cache file: %s",
1095                 err->message));
1096     } else {
1097       GST_ELEMENT_ERROR (enc, RESOURCE, WRITE, (NULL),
1098           ("Failed to write multipass cache file"));
1099     }
1100     if (err)
1101       g_error_free (err);
1102
1103     return FALSE;
1104   }
1105   return TRUE;
1106 }
1107
1108 static GstFlowReturn
1109 theora_enc_chain (GstPad * pad, GstBuffer * buffer)
1110 {
1111   GstTheoraEnc *enc;
1112   ogg_packet op;
1113   GstClockTime timestamp, duration, running_time;
1114   GstFlowReturn ret;
1115   gboolean force_keyframe;
1116
1117   enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));
1118
1119   /* we keep track of two timelines.
1120    * - The timestamps from the incomming buffers, which we copy to the outgoing
1121    *   encoded buffers as-is. We need to do this as we simply forward the
1122    *   newsegment events.
1123    * - The running_time of the buffers, which we use to construct the granulepos
1124    *   in the packets.
1125    */
1126   timestamp = GST_BUFFER_TIMESTAMP (buffer);
1127   duration = GST_BUFFER_DURATION (buffer);
1128
1129   running_time =
1130       gst_segment_to_running_time (&enc->segment, GST_FORMAT_TIME, timestamp);
1131   if ((gint64) running_time < 0) {
1132     GST_DEBUG_OBJECT (enc, "Dropping buffer, timestamp: %" GST_TIME_FORMAT,
1133         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
1134     gst_buffer_unref (buffer);
1135     return GST_FLOW_OK;
1136   }
1137
1138   GST_OBJECT_LOCK (enc);
1139   if (enc->bitrate_changed) {
1140     long int bitrate = enc->video_bitrate;
1141
1142     th_encode_ctl (enc->encoder, TH_ENCCTL_SET_BITRATE, &bitrate,
1143         sizeof (long int));
1144     enc->bitrate_changed = FALSE;
1145   }
1146
1147   if (enc->quality_changed) {
1148     long int quality = enc->video_quality;
1149
1150     th_encode_ctl (enc->encoder, TH_ENCCTL_SET_QUALITY, &quality,
1151         sizeof (long int));
1152     enc->quality_changed = FALSE;
1153   }
1154
1155   /* see if we need to schedule a keyframe */
1156   force_keyframe = enc->force_keyframe;
1157   enc->force_keyframe = FALSE;
1158   GST_OBJECT_UNLOCK (enc);
1159
1160   if (force_keyframe) {
1161     GstClockTime stream_time;
1162     GstStructure *s;
1163
1164     stream_time = gst_segment_to_stream_time (&enc->segment,
1165         GST_FORMAT_TIME, timestamp);
1166
1167     s = gst_structure_new ("GstForceKeyUnit",
1168         "timestamp", G_TYPE_UINT64, timestamp,
1169         "stream-time", G_TYPE_UINT64, stream_time,
1170         "running-time", G_TYPE_UINT64, running_time, NULL);
1171
1172     theora_enc_force_keyframe (enc);
1173
1174     gst_pad_push_event (enc->srcpad,
1175         gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
1176   }
1177
1178   /* make sure we copy the discont flag to the next outgoing buffer when it's
1179    * set on the incomming buffer */
1180   if (GST_BUFFER_IS_DISCONT (buffer)) {
1181     enc->next_discont = TRUE;
1182   }
1183
1184   if (enc->packetno == 0) {
1185     /* no packets written yet, setup headers */
1186     GstCaps *caps;
1187     GstBuffer *buf;
1188     GSList *buffers = NULL;
1189     int result;
1190
1191     enc->granulepos_offset = 0;
1192     enc->timestamp_offset = 0;
1193
1194     GST_DEBUG_OBJECT (enc, "output headers");
1195     /* Theora streams begin with three headers; the initial header (with
1196        most of the codec setup parameters) which is mandated by the Ogg
1197        bitstream spec.  The second header holds any comment fields.  The
1198        third header holds the bitstream codebook.  We merely need to
1199        make the headers, then pass them to libtheora one at a time;
1200        libtheora handles the additional Ogg bitstream constraints */
1201
1202     /* create the remaining theora headers */
1203     th_comment_clear (&enc->comment);
1204     th_comment_init (&enc->comment);
1205
1206     while ((result =
1207             th_encode_flushheader (enc->encoder, &enc->comment, &op)) > 0) {
1208       ret =
1209           theora_buffer_from_packet (enc, &op, GST_CLOCK_TIME_NONE,
1210           GST_CLOCK_TIME_NONE, GST_CLOCK_TIME_NONE, &buf);
1211       if (ret != GST_FLOW_OK) {
1212         goto header_buffer_alloc;
1213       }
1214       buffers = g_slist_prepend (buffers, buf);
1215     }
1216     if (result < 0) {
1217       g_slist_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
1218       g_slist_free (buffers);
1219       goto encoder_disabled;
1220     }
1221
1222     buffers = g_slist_reverse (buffers);
1223
1224     /* mark buffers and put on caps */
1225     caps = gst_pad_get_caps (enc->srcpad);
1226     caps = theora_set_header_on_caps (caps, buffers);
1227     GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
1228     gst_pad_set_caps (enc->srcpad, caps);
1229
1230     g_slist_foreach (buffers, (GFunc) gst_buffer_set_caps, caps);
1231
1232     gst_caps_unref (caps);
1233
1234     /* push out the header buffers */
1235     while (buffers) {
1236       buf = buffers->data;
1237       buffers = g_slist_delete_link (buffers, buffers);
1238       if ((ret = theora_push_buffer (enc, buf)) != GST_FLOW_OK) {
1239         g_slist_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
1240         g_slist_free (buffers);
1241         goto header_push;
1242       }
1243     }
1244
1245     enc->granulepos_offset =
1246         gst_util_uint64_scale (running_time, enc->fps_n,
1247         GST_SECOND * enc->fps_d);
1248     enc->timestamp_offset = running_time;
1249     enc->next_ts = 0;
1250   }
1251
1252   {
1253     th_ycbcr_buffer ycbcr;
1254     gint res;
1255     guint8 *data;
1256     gsize size;
1257
1258     data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
1259     theora_enc_init_buffer (ycbcr, &enc->info, data);
1260
1261     if (theora_enc_is_discontinuous (enc, running_time, duration)) {
1262       theora_enc_reset (enc);
1263       enc->granulepos_offset =
1264           gst_util_uint64_scale (running_time, enc->fps_n,
1265           GST_SECOND * enc->fps_d);
1266       enc->timestamp_offset = running_time;
1267       enc->next_ts = 0;
1268       enc->next_discont = TRUE;
1269     }
1270
1271     if (enc->multipass_cache_fd
1272         && enc->multipass_mode == MULTIPASS_MODE_SECOND_PASS) {
1273       if (!theora_enc_read_multipass_cache (enc)) {
1274         gst_buffer_unmap (buffer, data, size);
1275         ret = GST_FLOW_ERROR;
1276         goto multipass_read_failed;
1277       }
1278     }
1279
1280     res = th_encode_ycbcr_in (enc->encoder, ycbcr);
1281     /* none of the failure cases can happen here */
1282     g_assert (res == 0);
1283
1284     if (enc->multipass_cache_fd
1285         && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS) {
1286       if (!theora_enc_write_multipass_cache (enc, FALSE, FALSE)) {
1287         gst_buffer_unmap (buffer, data, size);
1288         ret = GST_FLOW_ERROR;
1289         goto multipass_write_failed;
1290       }
1291     }
1292
1293     ret = GST_FLOW_OK;
1294     while (th_encode_packetout (enc->encoder, 0, &op)) {
1295       GstClockTime next_time;
1296
1297       next_time = th_granule_time (enc->encoder, op.granulepos) * GST_SECOND;
1298
1299       ret =
1300           theora_push_packet (enc, &op, timestamp, enc->next_ts,
1301           next_time - enc->next_ts);
1302
1303       enc->next_ts = next_time;
1304       if (ret != GST_FLOW_OK) {
1305         gst_buffer_unmap (buffer, data, size);
1306         goto data_push;
1307       }
1308     }
1309     gst_buffer_unmap (buffer, data, size);
1310     gst_buffer_unref (buffer);
1311   }
1312
1313   return ret;
1314
1315   /* ERRORS */
1316 multipass_read_failed:
1317   {
1318     gst_buffer_unref (buffer);
1319     return ret;
1320   }
1321 multipass_write_failed:
1322   {
1323     gst_buffer_unref (buffer);
1324     return ret;
1325   }
1326 header_buffer_alloc:
1327   {
1328     gst_buffer_unref (buffer);
1329     return ret;
1330   }
1331 header_push:
1332   {
1333     gst_buffer_unref (buffer);
1334     return ret;
1335   }
1336 data_push:
1337   {
1338     gst_buffer_unref (buffer);
1339     return ret;
1340   }
1341 encoder_disabled:
1342   {
1343     GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
1344         ("libtheora has been compiled with the encoder disabled"));
1345     gst_buffer_unref (buffer);
1346     return GST_FLOW_ERROR;
1347   }
1348 }
1349
1350 static GstStateChangeReturn
1351 theora_enc_change_state (GstElement * element, GstStateChange transition)
1352 {
1353   GstTheoraEnc *enc;
1354   GstStateChangeReturn ret;
1355
1356   enc = GST_THEORA_ENC (element);
1357
1358   switch (transition) {
1359     case GST_STATE_CHANGE_NULL_TO_READY:
1360       break;
1361     case GST_STATE_CHANGE_READY_TO_PAUSED:
1362       GST_DEBUG_OBJECT (enc, "READY->PAUSED Initing theora state");
1363       th_info_init (&enc->info);
1364       th_comment_init (&enc->comment);
1365       enc->packetno = 0;
1366       enc->force_keyframe = FALSE;
1367
1368       if (enc->multipass_mode >= MULTIPASS_MODE_FIRST_PASS) {
1369         GError *err = NULL;
1370
1371         if (!enc->multipass_cache_file) {
1372           ret = GST_STATE_CHANGE_FAILURE;
1373           GST_ELEMENT_ERROR (enc, LIBRARY, SETTINGS, (NULL), (NULL));
1374           return ret;
1375         }
1376         enc->multipass_cache_fd =
1377             g_io_channel_new_file (enc->multipass_cache_file,
1378             (enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS ? "w" : "r"),
1379             &err);
1380
1381         if (enc->multipass_mode == MULTIPASS_MODE_SECOND_PASS)
1382           enc->multipass_cache_adapter = gst_adapter_new ();
1383
1384         if (!enc->multipass_cache_fd) {
1385           ret = GST_STATE_CHANGE_FAILURE;
1386           GST_ELEMENT_ERROR (enc, RESOURCE, OPEN_READ, (NULL),
1387               ("Failed to open multipass cache file: %s", err->message));
1388           g_error_free (err);
1389           return ret;
1390         }
1391
1392         g_io_channel_set_encoding (enc->multipass_cache_fd, NULL, NULL);
1393       }
1394       break;
1395     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1396       break;
1397     default:
1398       break;
1399   }
1400
1401   ret = parent_class->change_state (element, transition);
1402
1403   switch (transition) {
1404     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1405       break;
1406     case GST_STATE_CHANGE_PAUSED_TO_READY:
1407       GST_DEBUG_OBJECT (enc, "PAUSED->READY Clearing theora state");
1408       if (enc->encoder) {
1409         th_encode_free (enc->encoder);
1410         enc->encoder = NULL;
1411       }
1412       th_comment_clear (&enc->comment);
1413       th_info_clear (&enc->info);
1414
1415       theora_enc_clear (enc);
1416       enc->initialised = FALSE;
1417       break;
1418     case GST_STATE_CHANGE_READY_TO_NULL:
1419       break;
1420     default:
1421       break;
1422   }
1423
1424   return ret;
1425 }
1426
1427 static void
1428 theora_enc_set_property (GObject * object, guint prop_id,
1429     const GValue * value, GParamSpec * pspec)
1430 {
1431   GstTheoraEnc *enc = GST_THEORA_ENC (object);
1432
1433   switch (prop_id) {
1434     case PROP_CENTER:
1435     case PROP_BORDER:
1436     case PROP_QUICK:
1437     case PROP_KEYFRAME_THRESHOLD:
1438     case PROP_KEYFRAME_MINDISTANCE:
1439     case PROP_NOISE_SENSITIVITY:
1440     case PROP_SHARPNESS:
1441       /* kept for API compat, but ignored */
1442       break;
1443     case PROP_BITRATE:
1444       GST_OBJECT_LOCK (enc);
1445       enc->video_bitrate = g_value_get_int (value) * 1000;
1446       enc->bitrate_changed = TRUE;
1447       GST_OBJECT_UNLOCK (enc);
1448       break;
1449     case PROP_QUALITY:
1450       GST_OBJECT_LOCK (enc);
1451       if (GST_STATE (enc) >= GST_STATE_PAUSED && enc->video_bitrate > 0) {
1452         GST_WARNING_OBJECT (object, "Can't change from bitrate to quality mode"
1453             " while playing");
1454       } else {
1455         enc->video_quality = g_value_get_int (value);
1456         enc->video_bitrate = 0;
1457         enc->quality_changed = TRUE;
1458       }
1459       GST_OBJECT_UNLOCK (enc);
1460       break;
1461     case PROP_KEYFRAME_AUTO:
1462       enc->keyframe_auto = g_value_get_boolean (value);
1463       break;
1464     case PROP_KEYFRAME_FREQ:
1465       enc->keyframe_freq = g_value_get_int (value);
1466       break;
1467     case PROP_KEYFRAME_FREQ_FORCE:
1468       enc->keyframe_force = g_value_get_int (value);
1469       break;
1470     case PROP_SPEEDLEVEL:
1471       enc->speed_level = g_value_get_int (value);
1472       if (enc->encoder) {
1473         th_encode_ctl (enc->encoder, TH_ENCCTL_SET_SPLEVEL, &enc->speed_level,
1474             sizeof (enc->speed_level));
1475       }
1476       break;
1477     case PROP_VP3_COMPATIBLE:
1478       enc->vp3_compatible = g_value_get_boolean (value);
1479       break;
1480     case PROP_DROP_FRAMES:
1481       enc->drop_frames = g_value_get_boolean (value);
1482       break;
1483     case PROP_CAP_OVERFLOW:
1484       enc->cap_overflow = g_value_get_boolean (value);
1485       break;
1486     case PROP_CAP_UNDERFLOW:
1487       enc->cap_underflow = g_value_get_boolean (value);
1488       break;
1489     case PROP_RATE_BUFFER:
1490       enc->rate_buffer = g_value_get_int (value);
1491       break;
1492     case PROP_MULTIPASS_CACHE_FILE:
1493       enc->multipass_cache_file = g_value_dup_string (value);
1494       break;
1495     case PROP_MULTIPASS_MODE:
1496       enc->multipass_mode = g_value_get_enum (value);
1497       break;
1498     default:
1499       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1500       break;
1501   }
1502 }
1503
1504 static void
1505 theora_enc_get_property (GObject * object, guint prop_id,
1506     GValue * value, GParamSpec * pspec)
1507 {
1508   GstTheoraEnc *enc = GST_THEORA_ENC (object);
1509
1510   switch (prop_id) {
1511     case PROP_CENTER:
1512       g_value_set_boolean (value, TRUE);
1513       break;
1514     case PROP_BORDER:
1515       g_value_set_enum (value, BORDER_BLACK);
1516       break;
1517     case PROP_BITRATE:
1518       GST_OBJECT_LOCK (enc);
1519       g_value_set_int (value, enc->video_bitrate / 1000);
1520       GST_OBJECT_UNLOCK (enc);
1521       break;
1522     case PROP_QUALITY:
1523       GST_OBJECT_LOCK (enc);
1524       g_value_set_int (value, enc->video_quality);
1525       GST_OBJECT_UNLOCK (enc);
1526       break;
1527     case PROP_QUICK:
1528       g_value_set_boolean (value, TRUE);
1529       break;
1530     case PROP_KEYFRAME_AUTO:
1531       g_value_set_boolean (value, enc->keyframe_auto);
1532       break;
1533     case PROP_KEYFRAME_FREQ:
1534       g_value_set_int (value, enc->keyframe_freq);
1535       break;
1536     case PROP_KEYFRAME_FREQ_FORCE:
1537       g_value_set_int (value, enc->keyframe_force);
1538       break;
1539     case PROP_KEYFRAME_THRESHOLD:
1540       g_value_set_int (value, 80);
1541       break;
1542     case PROP_KEYFRAME_MINDISTANCE:
1543       g_value_set_int (value, 8);
1544       break;
1545     case PROP_NOISE_SENSITIVITY:
1546       g_value_set_int (value, 1);
1547       break;
1548     case PROP_SHARPNESS:
1549       g_value_set_int (value, 0);
1550       break;
1551     case PROP_SPEEDLEVEL:
1552       g_value_set_int (value, enc->speed_level);
1553       break;
1554     case PROP_VP3_COMPATIBLE:
1555       g_value_set_boolean (value, enc->vp3_compatible);
1556       break;
1557     case PROP_DROP_FRAMES:
1558       g_value_set_boolean (value, enc->drop_frames);
1559       break;
1560     case PROP_CAP_OVERFLOW:
1561       g_value_set_boolean (value, enc->cap_overflow);
1562       break;
1563     case PROP_CAP_UNDERFLOW:
1564       g_value_set_boolean (value, enc->cap_underflow);
1565       break;
1566     case PROP_RATE_BUFFER:
1567       g_value_set_int (value, enc->rate_buffer);
1568       break;
1569     case PROP_MULTIPASS_CACHE_FILE:
1570       g_value_set_string (value, enc->multipass_cache_file);
1571       break;
1572     case PROP_MULTIPASS_MODE:
1573       g_value_set_enum (value, enc->multipass_mode);
1574       break;
1575     default:
1576       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1577       break;
1578   }
1579 }