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