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