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