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