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