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