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_copy_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;
993   gint bytes_consumed = 0;
994   GIOStatus stat = G_IO_STATUS_NORMAL;
995   gboolean done = FALSE;
996
997   while (!done) {
998     if (gst_adapter_available (enc->multipass_cache_adapter) == 0) {
999       guint8 *data;
1000       gsize size;
1001
1002       cache_buf = gst_buffer_new_and_alloc (512);
1003
1004       data = gst_buffer_map (cache_buf, &size, NULL, GST_MAP_READ);
1005       stat = g_io_channel_read_chars (enc->multipass_cache_fd,
1006           (gchar *) data, size, &bytes_read, NULL);
1007
1008       if (bytes_read <= 0) {
1009         gst_buffer_unmap (cache_buf, data, 0);
1010         gst_buffer_unref (cache_buf);
1011         break;
1012       } else {
1013         gst_buffer_unmap (cache_buf, data, bytes_read);
1014         gst_adapter_push (enc->multipass_cache_adapter, cache_buf);
1015       }
1016     }
1017     if (gst_adapter_available (enc->multipass_cache_adapter) == 0)
1018       break;
1019
1020     bytes_read =
1021         MIN (gst_adapter_available (enc->multipass_cache_adapter), 512);
1022
1023     cache_data = gst_adapter_map (enc->multipass_cache_adapter, bytes_read);
1024
1025     bytes_consumed =
1026         th_encode_ctl (enc->encoder, TH_ENCCTL_2PASS_IN, (guint8 *) cache_data,
1027         bytes_read);
1028     gst_adapter_unmap (enc->multipass_cache_adapter, 0);
1029
1030     done = bytes_consumed <= 0;
1031     if (bytes_consumed > 0)
1032       gst_adapter_flush (enc->multipass_cache_adapter, bytes_consumed);
1033   }
1034
1035   if (stat == G_IO_STATUS_ERROR || (stat == G_IO_STATUS_EOF && bytes_read == 0)
1036       || bytes_consumed < 0) {
1037     GST_ELEMENT_ERROR (enc, RESOURCE, READ, (NULL),
1038         ("Failed to read multipass cache file"));
1039     return FALSE;
1040   }
1041   return TRUE;
1042 }
1043
1044 static gboolean
1045 theora_enc_write_multipass_cache (GstTheoraEnc * enc, gboolean begin,
1046     gboolean eos)
1047 {
1048   GError *err = NULL;
1049   GIOStatus stat = G_IO_STATUS_NORMAL;
1050   gint bytes_read = 0;
1051   gsize bytes_written = 0;
1052   gchar *buf;
1053
1054   if (begin)
1055     stat = g_io_channel_seek_position (enc->multipass_cache_fd, 0, G_SEEK_SET,
1056         &err);
1057   if (stat != G_IO_STATUS_ERROR) {
1058     do {
1059       bytes_read =
1060           th_encode_ctl (enc->encoder, TH_ENCCTL_2PASS_OUT, &buf, sizeof (buf));
1061       if (bytes_read > 0)
1062         g_io_channel_write_chars (enc->multipass_cache_fd, buf, bytes_read,
1063             &bytes_written, NULL);
1064     } while (bytes_read > 0 && bytes_written > 0);
1065
1066   }
1067
1068   if (stat == G_IO_STATUS_ERROR || bytes_read < 0) {
1069     if (begin) {
1070       if (eos)
1071         GST_ELEMENT_WARNING (enc, RESOURCE, WRITE, (NULL),
1072             ("Failed to seek to beginning of multipass cache file: %s",
1073                 err->message));
1074       else
1075         GST_ELEMENT_ERROR (enc, RESOURCE, WRITE, (NULL),
1076             ("Failed to seek to beginning of multipass cache file: %s",
1077                 err->message));
1078     } else {
1079       GST_ELEMENT_ERROR (enc, RESOURCE, WRITE, (NULL),
1080           ("Failed to write multipass cache file"));
1081     }
1082     if (err)
1083       g_error_free (err);
1084
1085     return FALSE;
1086   }
1087   return TRUE;
1088 }
1089
1090 static GstFlowReturn
1091 theora_enc_chain (GstPad * pad, GstBuffer * buffer)
1092 {
1093   GstTheoraEnc *enc;
1094   ogg_packet op;
1095   GstClockTime timestamp, duration, running_time;
1096   GstFlowReturn ret;
1097   gboolean force_keyframe;
1098
1099   enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));
1100
1101   /* we keep track of two timelines.
1102    * - The timestamps from the incomming buffers, which we copy to the outgoing
1103    *   encoded buffers as-is. We need to do this as we simply forward the
1104    *   newsegment events.
1105    * - The running_time of the buffers, which we use to construct the granulepos
1106    *   in the packets.
1107    */
1108   timestamp = GST_BUFFER_TIMESTAMP (buffer);
1109   duration = GST_BUFFER_DURATION (buffer);
1110
1111   running_time =
1112       gst_segment_to_running_time (&enc->segment, GST_FORMAT_TIME, timestamp);
1113   if ((gint64) running_time < 0) {
1114     GST_DEBUG_OBJECT (enc, "Dropping buffer, timestamp: %" GST_TIME_FORMAT,
1115         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
1116     gst_buffer_unref (buffer);
1117     return GST_FLOW_OK;
1118   }
1119
1120   GST_OBJECT_LOCK (enc);
1121   if (enc->bitrate_changed) {
1122     long int bitrate = enc->video_bitrate;
1123
1124     th_encode_ctl (enc->encoder, TH_ENCCTL_SET_BITRATE, &bitrate,
1125         sizeof (long int));
1126     enc->bitrate_changed = FALSE;
1127   }
1128
1129   if (enc->quality_changed) {
1130     long int quality = enc->video_quality;
1131
1132     th_encode_ctl (enc->encoder, TH_ENCCTL_SET_QUALITY, &quality,
1133         sizeof (long int));
1134     enc->quality_changed = FALSE;
1135   }
1136
1137   /* see if we need to schedule a keyframe */
1138   force_keyframe = enc->force_keyframe;
1139   enc->force_keyframe = FALSE;
1140   GST_OBJECT_UNLOCK (enc);
1141
1142   if (force_keyframe) {
1143     GstClockTime stream_time;
1144     GstStructure *s;
1145
1146     stream_time = gst_segment_to_stream_time (&enc->segment,
1147         GST_FORMAT_TIME, timestamp);
1148
1149     s = gst_structure_new ("GstForceKeyUnit",
1150         "timestamp", G_TYPE_UINT64, timestamp,
1151         "stream-time", G_TYPE_UINT64, stream_time,
1152         "running-time", G_TYPE_UINT64, running_time, NULL);
1153
1154     theora_enc_force_keyframe (enc);
1155
1156     gst_pad_push_event (enc->srcpad,
1157         gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
1158   }
1159
1160   /* make sure we copy the discont flag to the next outgoing buffer when it's
1161    * set on the incomming buffer */
1162   if (GST_BUFFER_IS_DISCONT (buffer)) {
1163     enc->next_discont = TRUE;
1164   }
1165
1166   if (enc->packetno == 0) {
1167     /* no packets written yet, setup headers */
1168     GstCaps *caps;
1169     GstBuffer *buf;
1170     GSList *buffers = NULL;
1171     int result;
1172
1173     enc->granulepos_offset = 0;
1174     enc->timestamp_offset = 0;
1175
1176     GST_DEBUG_OBJECT (enc, "output headers");
1177     /* Theora streams begin with three headers; the initial header (with
1178        most of the codec setup parameters) which is mandated by the Ogg
1179        bitstream spec.  The second header holds any comment fields.  The
1180        third header holds the bitstream codebook.  We merely need to
1181        make the headers, then pass them to libtheora one at a time;
1182        libtheora handles the additional Ogg bitstream constraints */
1183
1184     /* create the remaining theora headers */
1185     th_comment_clear (&enc->comment);
1186     th_comment_init (&enc->comment);
1187
1188     while ((result =
1189             th_encode_flushheader (enc->encoder, &enc->comment, &op)) > 0) {
1190       ret =
1191           theora_buffer_from_packet (enc, &op, GST_CLOCK_TIME_NONE,
1192           GST_CLOCK_TIME_NONE, GST_CLOCK_TIME_NONE, &buf);
1193       if (ret != GST_FLOW_OK) {
1194         goto header_buffer_alloc;
1195       }
1196       buffers = g_slist_prepend (buffers, buf);
1197     }
1198     if (result < 0) {
1199       g_slist_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
1200       g_slist_free (buffers);
1201       goto encoder_disabled;
1202     }
1203
1204     buffers = g_slist_reverse (buffers);
1205
1206     /* mark buffers and put on caps */
1207     caps = gst_pad_get_caps (enc->srcpad, NULL);
1208     caps = theora_set_header_on_caps (caps, buffers);
1209     GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
1210     gst_pad_set_caps (enc->srcpad, caps);
1211     gst_caps_unref (caps);
1212
1213     /* push out the header buffers */
1214     while (buffers) {
1215       buf = buffers->data;
1216       buffers = g_slist_delete_link (buffers, buffers);
1217       if ((ret = theora_push_buffer (enc, buf)) != GST_FLOW_OK) {
1218         g_slist_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
1219         g_slist_free (buffers);
1220         goto header_push;
1221       }
1222     }
1223
1224     enc->granulepos_offset =
1225         gst_util_uint64_scale (running_time, enc->fps_n,
1226         GST_SECOND * enc->fps_d);
1227     enc->timestamp_offset = running_time;
1228     enc->next_ts = 0;
1229   }
1230
1231   {
1232     th_ycbcr_buffer ycbcr;
1233     gint res;
1234     guint8 *data;
1235     gsize size;
1236
1237     data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
1238     theora_enc_init_buffer (ycbcr, &enc->info, data);
1239
1240     if (theora_enc_is_discontinuous (enc, running_time, duration)) {
1241       theora_enc_reset (enc);
1242       enc->granulepos_offset =
1243           gst_util_uint64_scale (running_time, enc->fps_n,
1244           GST_SECOND * enc->fps_d);
1245       enc->timestamp_offset = running_time;
1246       enc->next_ts = 0;
1247       enc->next_discont = TRUE;
1248     }
1249
1250     if (enc->multipass_cache_fd
1251         && enc->multipass_mode == MULTIPASS_MODE_SECOND_PASS) {
1252       if (!theora_enc_read_multipass_cache (enc)) {
1253         gst_buffer_unmap (buffer, data, size);
1254         ret = GST_FLOW_ERROR;
1255         goto multipass_read_failed;
1256       }
1257     }
1258
1259     res = th_encode_ycbcr_in (enc->encoder, ycbcr);
1260     /* none of the failure cases can happen here */
1261     g_assert (res == 0);
1262
1263     if (enc->multipass_cache_fd
1264         && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS) {
1265       if (!theora_enc_write_multipass_cache (enc, FALSE, FALSE)) {
1266         gst_buffer_unmap (buffer, data, size);
1267         ret = GST_FLOW_ERROR;
1268         goto multipass_write_failed;
1269       }
1270     }
1271
1272     ret = GST_FLOW_OK;
1273     while (th_encode_packetout (enc->encoder, 0, &op)) {
1274       GstClockTime next_time;
1275
1276       next_time = th_granule_time (enc->encoder, op.granulepos) * GST_SECOND;
1277
1278       ret =
1279           theora_push_packet (enc, &op, timestamp, enc->next_ts,
1280           next_time - enc->next_ts);
1281
1282       enc->next_ts = next_time;
1283       if (ret != GST_FLOW_OK) {
1284         gst_buffer_unmap (buffer, data, size);
1285         goto data_push;
1286       }
1287     }
1288     gst_buffer_unmap (buffer, data, size);
1289     gst_buffer_unref (buffer);
1290   }
1291
1292   return ret;
1293
1294   /* ERRORS */
1295 multipass_read_failed:
1296   {
1297     gst_buffer_unref (buffer);
1298     return ret;
1299   }
1300 multipass_write_failed:
1301   {
1302     gst_buffer_unref (buffer);
1303     return ret;
1304   }
1305 header_buffer_alloc:
1306   {
1307     gst_buffer_unref (buffer);
1308     return ret;
1309   }
1310 header_push:
1311   {
1312     gst_buffer_unref (buffer);
1313     return ret;
1314   }
1315 data_push:
1316   {
1317     gst_buffer_unref (buffer);
1318     return ret;
1319   }
1320 encoder_disabled:
1321   {
1322     GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
1323         ("libtheora has been compiled with the encoder disabled"));
1324     gst_buffer_unref (buffer);
1325     return GST_FLOW_ERROR;
1326   }
1327 }
1328
1329 static GstStateChangeReturn
1330 theora_enc_change_state (GstElement * element, GstStateChange transition)
1331 {
1332   GstTheoraEnc *enc;
1333   GstStateChangeReturn ret;
1334
1335   enc = GST_THEORA_ENC (element);
1336
1337   switch (transition) {
1338     case GST_STATE_CHANGE_NULL_TO_READY:
1339       break;
1340     case GST_STATE_CHANGE_READY_TO_PAUSED:
1341       GST_DEBUG_OBJECT (enc, "READY->PAUSED Initing theora state");
1342       th_info_init (&enc->info);
1343       th_comment_init (&enc->comment);
1344       enc->packetno = 0;
1345       enc->force_keyframe = FALSE;
1346
1347       if (enc->multipass_mode >= MULTIPASS_MODE_FIRST_PASS) {
1348         GError *err = NULL;
1349
1350         if (!enc->multipass_cache_file) {
1351           ret = GST_STATE_CHANGE_FAILURE;
1352           GST_ELEMENT_ERROR (enc, LIBRARY, SETTINGS, (NULL), (NULL));
1353           return ret;
1354         }
1355         enc->multipass_cache_fd =
1356             g_io_channel_new_file (enc->multipass_cache_file,
1357             (enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS ? "w" : "r"),
1358             &err);
1359
1360         if (enc->multipass_mode == MULTIPASS_MODE_SECOND_PASS)
1361           enc->multipass_cache_adapter = gst_adapter_new ();
1362
1363         if (!enc->multipass_cache_fd) {
1364           ret = GST_STATE_CHANGE_FAILURE;
1365           GST_ELEMENT_ERROR (enc, RESOURCE, OPEN_READ, (NULL),
1366               ("Failed to open multipass cache file: %s", err->message));
1367           g_error_free (err);
1368           return ret;
1369         }
1370
1371         g_io_channel_set_encoding (enc->multipass_cache_fd, NULL, NULL);
1372       }
1373       break;
1374     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1375       break;
1376     default:
1377       break;
1378   }
1379
1380   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1381
1382   switch (transition) {
1383     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1384       break;
1385     case GST_STATE_CHANGE_PAUSED_TO_READY:
1386       GST_DEBUG_OBJECT (enc, "PAUSED->READY Clearing theora state");
1387       if (enc->encoder) {
1388         th_encode_free (enc->encoder);
1389         enc->encoder = NULL;
1390       }
1391       th_comment_clear (&enc->comment);
1392       th_info_clear (&enc->info);
1393
1394       theora_enc_clear (enc);
1395       enc->initialised = FALSE;
1396       break;
1397     case GST_STATE_CHANGE_READY_TO_NULL:
1398       break;
1399     default:
1400       break;
1401   }
1402
1403   return ret;
1404 }
1405
1406 static void
1407 theora_enc_set_property (GObject * object, guint prop_id,
1408     const GValue * value, GParamSpec * pspec)
1409 {
1410   GstTheoraEnc *enc = GST_THEORA_ENC (object);
1411
1412   switch (prop_id) {
1413     case PROP_CENTER:
1414     case PROP_BORDER:
1415     case PROP_QUICK:
1416     case PROP_KEYFRAME_THRESHOLD:
1417     case PROP_KEYFRAME_MINDISTANCE:
1418     case PROP_NOISE_SENSITIVITY:
1419     case PROP_SHARPNESS:
1420       /* kept for API compat, but ignored */
1421       break;
1422     case PROP_BITRATE:
1423       GST_OBJECT_LOCK (enc);
1424       enc->video_bitrate = g_value_get_int (value) * 1000;
1425       enc->bitrate_changed = TRUE;
1426       GST_OBJECT_UNLOCK (enc);
1427       break;
1428     case PROP_QUALITY:
1429       GST_OBJECT_LOCK (enc);
1430       if (GST_STATE (enc) >= GST_STATE_PAUSED && enc->video_bitrate > 0) {
1431         GST_WARNING_OBJECT (object, "Can't change from bitrate to quality mode"
1432             " while playing");
1433       } else {
1434         enc->video_quality = g_value_get_int (value);
1435         enc->video_bitrate = 0;
1436         enc->quality_changed = TRUE;
1437       }
1438       GST_OBJECT_UNLOCK (enc);
1439       break;
1440     case PROP_KEYFRAME_AUTO:
1441       enc->keyframe_auto = g_value_get_boolean (value);
1442       break;
1443     case PROP_KEYFRAME_FREQ:
1444       enc->keyframe_freq = g_value_get_int (value);
1445       break;
1446     case PROP_KEYFRAME_FREQ_FORCE:
1447       enc->keyframe_force = g_value_get_int (value);
1448       break;
1449     case PROP_SPEEDLEVEL:
1450       enc->speed_level = g_value_get_int (value);
1451       if (enc->encoder) {
1452         th_encode_ctl (enc->encoder, TH_ENCCTL_SET_SPLEVEL, &enc->speed_level,
1453             sizeof (enc->speed_level));
1454       }
1455       break;
1456     case PROP_VP3_COMPATIBLE:
1457       enc->vp3_compatible = g_value_get_boolean (value);
1458       break;
1459     case PROP_DROP_FRAMES:
1460       enc->drop_frames = g_value_get_boolean (value);
1461       break;
1462     case PROP_CAP_OVERFLOW:
1463       enc->cap_overflow = g_value_get_boolean (value);
1464       break;
1465     case PROP_CAP_UNDERFLOW:
1466       enc->cap_underflow = g_value_get_boolean (value);
1467       break;
1468     case PROP_RATE_BUFFER:
1469       enc->rate_buffer = g_value_get_int (value);
1470       break;
1471     case PROP_MULTIPASS_CACHE_FILE:
1472       enc->multipass_cache_file = g_value_dup_string (value);
1473       break;
1474     case PROP_MULTIPASS_MODE:
1475       enc->multipass_mode = g_value_get_enum (value);
1476       break;
1477     default:
1478       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1479       break;
1480   }
1481 }
1482
1483 static void
1484 theora_enc_get_property (GObject * object, guint prop_id,
1485     GValue * value, GParamSpec * pspec)
1486 {
1487   GstTheoraEnc *enc = GST_THEORA_ENC (object);
1488
1489   switch (prop_id) {
1490     case PROP_CENTER:
1491       g_value_set_boolean (value, TRUE);
1492       break;
1493     case PROP_BORDER:
1494       g_value_set_enum (value, BORDER_BLACK);
1495       break;
1496     case PROP_BITRATE:
1497       GST_OBJECT_LOCK (enc);
1498       g_value_set_int (value, enc->video_bitrate / 1000);
1499       GST_OBJECT_UNLOCK (enc);
1500       break;
1501     case PROP_QUALITY:
1502       GST_OBJECT_LOCK (enc);
1503       g_value_set_int (value, enc->video_quality);
1504       GST_OBJECT_UNLOCK (enc);
1505       break;
1506     case PROP_QUICK:
1507       g_value_set_boolean (value, TRUE);
1508       break;
1509     case PROP_KEYFRAME_AUTO:
1510       g_value_set_boolean (value, enc->keyframe_auto);
1511       break;
1512     case PROP_KEYFRAME_FREQ:
1513       g_value_set_int (value, enc->keyframe_freq);
1514       break;
1515     case PROP_KEYFRAME_FREQ_FORCE:
1516       g_value_set_int (value, enc->keyframe_force);
1517       break;
1518     case PROP_KEYFRAME_THRESHOLD:
1519       g_value_set_int (value, 80);
1520       break;
1521     case PROP_KEYFRAME_MINDISTANCE:
1522       g_value_set_int (value, 8);
1523       break;
1524     case PROP_NOISE_SENSITIVITY:
1525       g_value_set_int (value, 1);
1526       break;
1527     case PROP_SHARPNESS:
1528       g_value_set_int (value, 0);
1529       break;
1530     case PROP_SPEEDLEVEL:
1531       g_value_set_int (value, enc->speed_level);
1532       break;
1533     case PROP_VP3_COMPATIBLE:
1534       g_value_set_boolean (value, enc->vp3_compatible);
1535       break;
1536     case PROP_DROP_FRAMES:
1537       g_value_set_boolean (value, enc->drop_frames);
1538       break;
1539     case PROP_CAP_OVERFLOW:
1540       g_value_set_boolean (value, enc->cap_overflow);
1541       break;
1542     case PROP_CAP_UNDERFLOW:
1543       g_value_set_boolean (value, enc->cap_underflow);
1544       break;
1545     case PROP_RATE_BUFFER:
1546       g_value_set_int (value, enc->rate_buffer);
1547       break;
1548     case PROP_MULTIPASS_CACHE_FILE:
1549       g_value_set_string (value, enc->multipass_cache_file);
1550       break;
1551     case PROP_MULTIPASS_MODE:
1552       g_value_set_enum (value, enc->multipass_mode);
1553       break;
1554     default:
1555       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1556       break;
1557   }
1558 }