cb22dde7d327c16048cbca7f2cbadaeda31405ac
[platform/upstream/gstreamer.git] / ext / theora / theoraenc.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  * <refsect2>
25  * <para>
26  * This element encodes raw video into a Theora stream.
27  * <ulink url="http://www.theora.org/">Theora</ulink> is a royalty-free
28  * video codec maintained by the <ulink url="http://www.xiph.org/">Xiph.org
29  * Foundation</ulink>, based on the VP3 codec.
30  * </para>
31  * <title>Example pipeline</title>
32  * <programlisting>
33  * gst-launch -v videotestsrc num-buffers=1000 ! theoraenc ! oggmux ! filesink location=videotestsrc.ogg
34  * </programlisting>
35  * </refsect2>
36  */
37
38 #ifdef HAVE_CONFIG_H
39 #  include "config.h"
40 #endif
41
42 #include "gsttheoraenc.h"
43 #include <string.h>
44 #include <gst/tag/tag.h>
45
46 GST_DEBUG_CATEGORY (theoraenc_debug);
47 #define GST_CAT_DEFAULT theoraenc_debug
48
49 #define GST_TYPE_BORDER_MODE (gst_border_mode_get_type())
50 static GType
51 gst_border_mode_get_type (void)
52 {
53   static GType border_mode_type = 0;
54   static GEnumValue border_mode[] = {
55     {BORDER_NONE, "No Border", "none"},
56     {BORDER_BLACK, "Black Border", "black"},
57     {BORDER_MIRROR, "Mirror image in borders", "mirror"},
58     {0, NULL, NULL},
59   };
60
61   if (!border_mode_type) {
62     border_mode_type =
63         g_enum_register_static ("GstTheoraEncBorderMode", border_mode);
64   }
65   return border_mode_type;
66 }
67
68 #define ROUND_UP_2(x) (((x) + 1) & ~1)
69 #define ROUND_UP_4(x) (((x) + 3) & ~3)
70 #define ROUND_UP_8(x) (((x) + 7) & ~7)
71
72 #define THEORA_DEF_CENTER               TRUE
73 #define THEORA_DEF_BORDER               BORDER_BLACK
74 #define THEORA_DEF_BITRATE              0
75 #define THEORA_DEF_QUALITY              16
76 #define THEORA_DEF_QUICK                TRUE
77 #define THEORA_DEF_KEYFRAME_AUTO        TRUE
78 #define THEORA_DEF_KEYFRAME_FREQ        64
79 #define THEORA_DEF_KEYFRAME_FREQ_FORCE  64
80 #define THEORA_DEF_KEYFRAME_THRESHOLD   80
81 #define THEORA_DEF_KEYFRAME_MINDISTANCE 8
82 #define THEORA_DEF_NOISE_SENSITIVITY    1
83 #define THEORA_DEF_SHARPNESS            0
84
85 /* taken from theora/lib/toplevel.c */
86 static int
87 _ilog (unsigned int v)
88 {
89   int ret = 0;
90
91   while (v) {
92     ret++;
93     v >>= 1;
94   }
95   return (ret);
96 }
97
98 enum
99 {
100   ARG_0,
101   ARG_CENTER,
102   ARG_BORDER,
103   ARG_BITRATE,
104   ARG_QUALITY,
105   ARG_QUICK,
106   ARG_KEYFRAME_AUTO,
107   ARG_KEYFRAME_FREQ,
108   ARG_KEYFRAME_FREQ_FORCE,
109   ARG_KEYFRAME_THRESHOLD,
110   ARG_KEYFRAME_MINDISTANCE,
111   ARG_NOISE_SENSITIVITY,
112   ARG_SHARPNESS,
113   /* FILL ME */
114 };
115
116 static GstElementDetails theora_enc_details = {
117   "TheoraEnc",
118   "Codec/Encoder/Video",
119   "encode raw YUV video to a theora stream",
120   "Wim Taymans <wim@fluendo.com>",
121 };
122
123 static GstStaticPadTemplate theora_enc_sink_factory =
124 GST_STATIC_PAD_TEMPLATE ("sink",
125     GST_PAD_SINK,
126     GST_PAD_ALWAYS,
127     GST_STATIC_CAPS ("video/x-raw-yuv, "
128         "format = (fourcc) I420, "
129         "framerate = (fraction) [0/1, MAX], "
130         "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
131     );
132
133 static GstStaticPadTemplate theora_enc_src_factory =
134 GST_STATIC_PAD_TEMPLATE ("src",
135     GST_PAD_SRC,
136     GST_PAD_ALWAYS,
137     GST_STATIC_CAPS ("video/x-theora")
138     );
139
140 GST_BOILERPLATE (GstTheoraEnc, gst_theora_enc, GstElement, GST_TYPE_ELEMENT);
141
142 static gboolean theora_enc_sink_event (GstPad * pad, GstEvent * event);
143 static GstFlowReturn theora_enc_chain (GstPad * pad, GstBuffer * buffer);
144 static GstStateChangeReturn theora_enc_change_state (GstElement * element,
145     GstStateChange transition);
146 static gboolean theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps);
147 static void theora_enc_get_property (GObject * object, guint prop_id,
148     GValue * value, GParamSpec * pspec);
149 static void theora_enc_set_property (GObject * object, guint prop_id,
150     const GValue * value, GParamSpec * pspec);
151 static void theora_enc_finalize (GObject * object);
152
153 static void
154 gst_theora_enc_base_init (gpointer g_class)
155 {
156   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
157
158   gst_element_class_add_pad_template (element_class,
159       gst_static_pad_template_get (&theora_enc_src_factory));
160   gst_element_class_add_pad_template (element_class,
161       gst_static_pad_template_get (&theora_enc_sink_factory));
162   gst_element_class_set_details (element_class, &theora_enc_details);
163 }
164
165 static void
166 gst_theora_enc_class_init (GstTheoraEncClass * klass)
167 {
168   GObjectClass *gobject_class = (GObjectClass *) klass;
169   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
170
171   gobject_class->set_property = theora_enc_set_property;
172   gobject_class->get_property = theora_enc_get_property;
173   gobject_class->finalize = theora_enc_finalize;
174
175   g_object_class_install_property (gobject_class, ARG_CENTER,
176       g_param_spec_boolean ("center", "Center",
177           "Center image when sizes not multiple of 16", THEORA_DEF_CENTER,
178           (GParamFlags) G_PARAM_READWRITE));
179   g_object_class_install_property (gobject_class, ARG_BORDER,
180       g_param_spec_enum ("border", "Border",
181           "Border color to add when sizes not multiple of 16",
182           GST_TYPE_BORDER_MODE, THEORA_DEF_BORDER,
183           (GParamFlags) G_PARAM_READWRITE));
184   /* general encoding stream options */
185   g_object_class_install_property (gobject_class, ARG_BITRATE,
186       g_param_spec_int ("bitrate", "Bitrate", "Compressed video bitrate (kbps)",
187           0, 2000, THEORA_DEF_BITRATE, (GParamFlags) G_PARAM_READWRITE));
188   g_object_class_install_property (gobject_class, ARG_QUALITY,
189       g_param_spec_int ("quality", "Quality", "Video quality",
190           0, 63, THEORA_DEF_QUALITY, (GParamFlags) G_PARAM_READWRITE));
191   g_object_class_install_property (gobject_class, ARG_QUICK,
192       g_param_spec_boolean ("quick", "Quick", "Quick encoding",
193           THEORA_DEF_QUICK, (GParamFlags) G_PARAM_READWRITE));
194   g_object_class_install_property (gobject_class, ARG_KEYFRAME_AUTO,
195       g_param_spec_boolean ("keyframe-auto", "Keyframe Auto",
196           "Automatic keyframe detection", THEORA_DEF_KEYFRAME_AUTO,
197           (GParamFlags) G_PARAM_READWRITE));
198   g_object_class_install_property (gobject_class, ARG_KEYFRAME_FREQ,
199       g_param_spec_int ("keyframe-freq", "Keyframe frequency",
200           "Keyframe frequency", 1, 32768, THEORA_DEF_KEYFRAME_FREQ,
201           (GParamFlags) G_PARAM_READWRITE));
202   g_object_class_install_property (gobject_class, ARG_KEYFRAME_FREQ_FORCE,
203       g_param_spec_int ("keyframe-force", "Keyframe force",
204           "Force keyframe every N frames", 1, 32768,
205           THEORA_DEF_KEYFRAME_FREQ_FORCE, (GParamFlags) G_PARAM_READWRITE));
206   g_object_class_install_property (gobject_class, ARG_KEYFRAME_THRESHOLD,
207       g_param_spec_int ("keyframe-threshold", "Keyframe threshold",
208           "Keyframe threshold", 0, 32768, THEORA_DEF_KEYFRAME_THRESHOLD,
209           (GParamFlags) G_PARAM_READWRITE));
210   g_object_class_install_property (gobject_class, ARG_KEYFRAME_MINDISTANCE,
211       g_param_spec_int ("keyframe-mindistance", "Keyframe mindistance",
212           "Keyframe mindistance", 1, 32768, THEORA_DEF_KEYFRAME_MINDISTANCE,
213           (GParamFlags) G_PARAM_READWRITE));
214   g_object_class_install_property (gobject_class, ARG_NOISE_SENSITIVITY,
215       g_param_spec_int ("noise-sensitivity", "Noise sensitivity",
216           "Noise sensitivity", 0, 32768, THEORA_DEF_NOISE_SENSITIVITY,
217           (GParamFlags) G_PARAM_READWRITE));
218   g_object_class_install_property (gobject_class, ARG_SHARPNESS,
219       g_param_spec_int ("sharpness", "Sharpness",
220           "Sharpness", 0, 2, THEORA_DEF_SHARPNESS,
221           (GParamFlags) G_PARAM_READWRITE));
222
223   gstelement_class->change_state = theora_enc_change_state;
224   GST_DEBUG_CATEGORY_INIT (theoraenc_debug, "theoraenc", 0, "Theora encoder");
225 }
226
227 static void
228 gst_theora_enc_init (GstTheoraEnc * enc, GstTheoraEncClass * g_class)
229 {
230   enc->sinkpad =
231       gst_pad_new_from_static_template (&theora_enc_sink_factory, "sink");
232   gst_pad_set_chain_function (enc->sinkpad, theora_enc_chain);
233   gst_pad_set_event_function (enc->sinkpad, theora_enc_sink_event);
234   gst_pad_set_setcaps_function (enc->sinkpad, theora_enc_sink_setcaps);
235   gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad);
236
237   enc->srcpad =
238       gst_pad_new_from_static_template (&theora_enc_src_factory, "src");
239   gst_element_add_pad (GST_ELEMENT (enc), enc->srcpad);
240
241   enc->center = THEORA_DEF_CENTER;
242   enc->border = THEORA_DEF_BORDER;
243
244   enc->video_bitrate = THEORA_DEF_BITRATE;
245   enc->video_quality = THEORA_DEF_QUALITY;
246   enc->quick = THEORA_DEF_QUICK;
247   enc->keyframe_auto = THEORA_DEF_KEYFRAME_AUTO;
248   enc->keyframe_freq = THEORA_DEF_KEYFRAME_FREQ;
249   enc->keyframe_force = THEORA_DEF_KEYFRAME_FREQ_FORCE;
250   enc->keyframe_threshold = THEORA_DEF_KEYFRAME_THRESHOLD;
251   enc->keyframe_mindistance = THEORA_DEF_KEYFRAME_MINDISTANCE;
252   enc->noise_sensitivity = THEORA_DEF_NOISE_SENSITIVITY;
253   enc->sharpness = THEORA_DEF_SHARPNESS;
254
255   enc->granule_shift = _ilog (enc->info.keyframe_frequency_force - 1);
256   GST_DEBUG_OBJECT (enc,
257       "keyframe_frequency_force is %d, granule shift is %d",
258       enc->info.keyframe_frequency_force, enc->granule_shift);
259 }
260
261 static void
262 theora_enc_finalize (GObject * object)
263 {
264   GstTheoraEnc *enc = GST_THEORA_ENC (object);
265
266   GST_DEBUG_OBJECT (enc, "Finalizing");
267   theora_clear (&enc->state);
268   theora_comment_clear (&enc->comment);
269   theora_info_clear (&enc->info);
270
271   G_OBJECT_CLASS (parent_class)->finalize (object);
272 }
273
274 static gboolean
275 theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
276 {
277   GstStructure *structure = gst_caps_get_structure (caps, 0);
278   GstTheoraEnc *enc = GST_THEORA_ENC (gst_pad_get_parent (pad));
279   const GValue *par;
280   gint fps_n, fps_d;
281
282   gst_structure_get_int (structure, "width", &enc->width);
283   gst_structure_get_int (structure, "height", &enc->height);
284   gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d);
285   par = gst_structure_get_value (structure, "pixel-aspect-ratio");
286
287   theora_info_clear (&enc->info);
288   theora_info_init (&enc->info);
289   /* Theora has a divisible-by-sixteen restriction for the encoded video size but
290    * we can define a visible area using the frame_width/frame_height */
291   enc->info_width = enc->info.width = (enc->width + 15) & ~15;
292   enc->info_height = enc->info.height = (enc->height + 15) & ~15;
293   enc->info.frame_width = enc->width;
294   enc->info.frame_height = enc->height;
295
296   /* center image if needed */
297   if (enc->center) {
298     /* make sure offset is even, for easier decoding */
299     enc->offset_x = ROUND_UP_2 ((enc->info_width - enc->width) / 2);
300     enc->offset_y = ROUND_UP_2 ((enc->info_height - enc->height) / 2);
301   } else {
302     enc->offset_x = 0;
303     enc->offset_y = 0;
304   }
305   enc->info.offset_x = enc->offset_x;
306   enc->info.offset_y = enc->offset_y;
307
308   enc->info.fps_numerator = enc->fps_n = fps_n;
309   enc->info.fps_denominator = enc->fps_d = fps_d;
310   if (par) {
311     enc->info.aspect_numerator = gst_value_get_fraction_numerator (par);
312     enc->info.aspect_denominator = gst_value_get_fraction_denominator (par);
313   } else {
314     /* setting them to 0 indicates that the decoder can chose a good aspect
315      * ratio, defaulting to 1/1 */
316     enc->info.aspect_numerator = 0;
317     enc->info.aspect_denominator = 0;
318   }
319
320   enc->info.colorspace = OC_CS_UNSPECIFIED;
321   enc->info.target_bitrate = enc->video_bitrate;
322   enc->info.quality = enc->video_quality;
323
324   enc->info.dropframes_p = 0;
325   enc->info.quick_p = (enc->quick ? 1 : 0);
326   enc->info.keyframe_auto_p = (enc->keyframe_auto ? 1 : 0);
327   enc->info.keyframe_frequency = enc->keyframe_freq;
328   enc->info.keyframe_frequency_force = enc->keyframe_force;
329   enc->info.keyframe_data_target_bitrate = enc->video_bitrate * 1.5;
330   enc->info.keyframe_auto_threshold = enc->keyframe_threshold;
331   enc->info.keyframe_mindistance = enc->keyframe_mindistance;
332   enc->info.noise_sensitivity = enc->noise_sensitivity;
333   enc->info.sharpness = enc->sharpness;
334
335   /* as done in theora */
336   enc->granule_shift = _ilog (enc->info.keyframe_frequency_force - 1);
337   GST_DEBUG_OBJECT (enc,
338       "keyframe_frequency_force is %d, granule shift is %d",
339       enc->info.keyframe_frequency_force, enc->granule_shift);
340
341   theora_encode_init (&enc->state, &enc->info);
342
343   gst_object_unref (enc);
344
345   return TRUE;
346 }
347
348 static guint64
349 granulepos_add (guint64 granulepos, guint64 addend, gint shift)
350 {
351   GstClockTime iframe, pframe;
352
353   iframe = granulepos >> shift;
354   pframe = granulepos - (iframe << shift);
355   iframe += addend;
356
357   return (iframe << shift) + pframe;
358 }
359
360 /* prepare a buffer for transmission by passing data through libtheora */
361 static GstFlowReturn
362 theora_buffer_from_packet (GstTheoraEnc * enc, ogg_packet * packet,
363     GstClockTime timestamp, GstClockTime duration, GstBuffer ** buffer)
364 {
365   GstBuffer *buf;
366   GstFlowReturn ret;
367
368   ret = gst_pad_alloc_buffer_and_set_caps (enc->srcpad,
369       GST_BUFFER_OFFSET_NONE, packet->bytes, GST_PAD_CAPS (enc->srcpad), &buf);
370   if (ret != GST_FLOW_OK)
371     goto no_buffer;
372
373   memcpy (GST_BUFFER_DATA (buf), packet->packet, packet->bytes);
374   GST_BUFFER_OFFSET (buf) = enc->bytes_out;
375   GST_BUFFER_OFFSET_END (buf) =
376       granulepos_add (packet->granulepos, enc->granulepos_offset,
377       enc->granule_shift);
378   GST_BUFFER_TIMESTAMP (buf) = timestamp + enc->timestamp_offset;
379   GST_BUFFER_DURATION (buf) = duration;
380
381   /* the second most significant bit of the first data byte is cleared
382    * for keyframes */
383   if ((packet->packet[0] & 0x40) == 0) {
384     GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
385   } else {
386     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
387   }
388   enc->packetno++;
389
390   *buffer = buf;
391   return ret;
392
393 no_buffer:
394   {
395     *buffer = NULL;
396     return ret;
397   }
398 }
399
400 /* push out the buffer and do internal bookkeeping */
401 static GstFlowReturn
402 theora_push_buffer (GstTheoraEnc * enc, GstBuffer * buffer)
403 {
404   GstFlowReturn ret;
405
406   enc->bytes_out += GST_BUFFER_SIZE (buffer);
407
408   ret = gst_pad_push (enc->srcpad, buffer);
409
410   return ret;
411 }
412
413 static GstFlowReturn
414 theora_push_packet (GstTheoraEnc * enc, ogg_packet * packet,
415     GstClockTime timestamp, GstClockTime duration)
416 {
417   GstBuffer *buf;
418   GstFlowReturn ret;
419
420   ret = theora_buffer_from_packet (enc, packet, timestamp, duration, &buf);
421   if (ret == GST_FLOW_OK)
422     ret = theora_push_buffer (enc, buf);
423
424   return ret;
425 }
426
427 static GstCaps *
428 theora_set_header_on_caps (GstCaps * caps, GstBuffer * buf1,
429     GstBuffer * buf2, GstBuffer * buf3)
430 {
431   GstStructure *structure;
432   GValue array = { 0 };
433   GValue value = { 0 };
434
435   caps = gst_caps_make_writable (caps);
436   structure = gst_caps_get_structure (caps, 0);
437
438   /* Copy buffers, because we can't use the originals -
439    * it creates a circular refcount with the caps<->buffers */
440   buf1 = gst_buffer_copy (buf1);
441   buf2 = gst_buffer_copy (buf2);
442   buf3 = gst_buffer_copy (buf3);
443
444   /* mark buffers */
445   GST_BUFFER_FLAG_SET (buf1, GST_BUFFER_FLAG_IN_CAPS);
446   GST_BUFFER_FLAG_SET (buf2, GST_BUFFER_FLAG_IN_CAPS);
447   GST_BUFFER_FLAG_SET (buf3, GST_BUFFER_FLAG_IN_CAPS);
448
449   /* put copies of the buffers in a fixed list */
450   g_value_init (&array, GST_TYPE_ARRAY);
451
452   g_value_init (&value, GST_TYPE_BUFFER);
453   gst_value_set_buffer (&value, buf1);
454   gst_value_array_append_value (&array, &value);
455   g_value_unset (&value);
456
457   g_value_init (&value, GST_TYPE_BUFFER);
458   gst_value_set_buffer (&value, buf2);
459   gst_value_array_append_value (&array, &value);
460   g_value_unset (&value);
461
462   g_value_init (&value, GST_TYPE_BUFFER);
463   gst_value_set_buffer (&value, buf3);
464   gst_value_array_append_value (&array, &value);
465   g_value_unset (&value);
466
467   gst_structure_set_value (structure, "streamheader", &array);
468   g_value_unset (&array);
469
470   /* Unref our copies */
471   gst_buffer_unref (buf1);
472   gst_buffer_unref (buf2);
473   gst_buffer_unref (buf3);
474
475   return caps;
476 }
477
478 static gboolean
479 theora_enc_sink_event (GstPad * pad, GstEvent * event)
480 {
481   GstTheoraEnc *enc;
482   ogg_packet op;
483   gboolean res;
484
485   enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));
486
487   switch (GST_EVENT_TYPE (event)) {
488     case GST_EVENT_EOS:
489       /* push last packet with eos flag */
490       while (theora_encode_packetout (&enc->state, 1, &op)) {
491         /* See comment in the chain function */
492         GstClockTime next_time = theora_granule_time (&enc->state,
493             granulepos_add (op.granulepos, 1, enc->granule_shift)) * GST_SECOND;
494
495         theora_push_packet (enc, &op, enc->next_ts, next_time - enc->next_ts);
496         enc->next_ts = next_time;
497       }
498       res = gst_pad_push_event (enc->srcpad, event);
499       break;
500     default:
501       res = gst_pad_push_event (enc->srcpad, event);
502   }
503   return res;
504 }
505
506 static GstFlowReturn
507 theora_enc_chain (GstPad * pad, GstBuffer * buffer)
508 {
509   GstTheoraEnc *enc;
510   ogg_packet op;
511   GstClockTime in_time;
512   GstFlowReturn ret;
513
514   enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));
515
516   in_time = GST_BUFFER_TIMESTAMP (buffer);
517
518   /* no packets written yet, setup headers */
519   if (enc->packetno == 0) {
520     GstCaps *caps;
521     GstBuffer *buf1, *buf2, *buf3;
522
523     enc->granulepos_offset = 0;
524     enc->timestamp_offset = 0;
525
526     /* Theora streams begin with three headers; the initial header (with
527        most of the codec setup parameters) which is mandated by the Ogg
528        bitstream spec.  The second header holds any comment fields.  The
529        third header holds the bitstream codebook.  We merely need to
530        make the headers, then pass them to libtheora one at a time;
531        libtheora handles the additional Ogg bitstream constraints */
532
533     /* first packet will get its own page automatically */
534     theora_encode_header (&enc->state, &op);
535     ret = theora_buffer_from_packet (enc, &op, GST_CLOCK_TIME_NONE,
536         GST_CLOCK_TIME_NONE, &buf1);
537     if (ret != GST_FLOW_OK) {
538       goto header_buffer_alloc;
539     }
540
541     /* create the remaining theora headers */
542     theora_comment_clear (&enc->comment);
543     theora_comment_init (&enc->comment);
544
545     theora_encode_comment (&enc->comment, &op);
546     ret = theora_buffer_from_packet (enc, &op, GST_CLOCK_TIME_NONE,
547         GST_CLOCK_TIME_NONE, &buf2);
548     /* Theora expects us to put this packet buffer into an ogg page,
549      * in which case it becomes the ogg library's responsibility to
550      * free it. Since we're copying and outputting a gst_buffer,
551      * we need to free it ourselves. */
552     if (op.packet)
553       free (op.packet);
554
555     if (ret != GST_FLOW_OK) {
556       gst_buffer_unref (buf1);
557       goto header_buffer_alloc;
558     }
559
560     theora_encode_tables (&enc->state, &op);
561     ret = theora_buffer_from_packet (enc, &op, GST_CLOCK_TIME_NONE,
562         GST_CLOCK_TIME_NONE, &buf3);
563     if (ret != GST_FLOW_OK) {
564       gst_buffer_unref (buf1);
565       gst_buffer_unref (buf2);
566       goto header_buffer_alloc;
567     }
568
569     /* mark buffers and put on caps */
570     caps = gst_pad_get_caps (enc->srcpad);
571     caps = theora_set_header_on_caps (caps, buf1, buf2, buf3);
572     GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
573     gst_pad_set_caps (enc->srcpad, caps);
574
575     gst_buffer_set_caps (buf1, caps);
576     gst_buffer_set_caps (buf2, caps);
577     gst_buffer_set_caps (buf3, caps);
578
579     gst_caps_unref (caps);
580
581     /* push out the header buffers */
582     if ((ret = theora_push_buffer (enc, buf1)) != GST_FLOW_OK) {
583       gst_buffer_unref (buf2);
584       gst_buffer_unref (buf3);
585       goto header_push;
586     }
587     if ((ret = theora_push_buffer (enc, buf2)) != GST_FLOW_OK) {
588       gst_buffer_unref (buf3);
589       goto header_push;
590     }
591     if ((ret = theora_push_buffer (enc, buf3)) != GST_FLOW_OK) {
592       goto header_push;
593     }
594
595     enc->granulepos_offset =
596         gst_util_uint64_scale (GST_BUFFER_TIMESTAMP (buffer), enc->fps_n,
597         GST_SECOND * enc->fps_d);
598     enc->timestamp_offset = GST_BUFFER_TIMESTAMP (buffer);
599     enc->next_ts = 0;
600   }
601
602   {
603     yuv_buffer yuv;
604     gint res;
605     gint y_size;
606     guint8 *pixels;
607
608     yuv.y_width = enc->info_width;
609     yuv.y_height = enc->info_height;
610     yuv.y_stride = enc->info_width;
611
612     yuv.uv_width = enc->info_width / 2;
613     yuv.uv_height = enc->info_height / 2;
614     yuv.uv_stride = yuv.uv_width;
615
616     y_size = enc->info_width * enc->info_height;
617
618     if (enc->width == enc->info_width && enc->height == enc->info_height) {
619       /* easy case, no cropping/conversion needed */
620       pixels = GST_BUFFER_DATA (buffer);
621
622       yuv.y = pixels;
623       yuv.u = yuv.y + y_size;
624       yuv.v = yuv.u + y_size / 4;
625     } else {
626       GstBuffer *newbuf;
627       gint i;
628       guchar *dest_y, *src_y;
629       guchar *dest_u, *src_u;
630       guchar *dest_v, *src_v;
631       gint src_y_stride, src_uv_stride;
632       gint dst_y_stride, dst_uv_stride;
633       gint width, height;
634       gint cwidth, cheight;
635       gint offset_x, right_x, right_border;
636
637       /* source width/height */
638       width = enc->width;
639       height = enc->height;
640       /* soucre chroma width/height */
641       cwidth = width / 2;
642       cheight = height / 2;
643
644       /* source strides as defined in videotestsrc */
645       src_y_stride = ROUND_UP_4 (width);
646       src_uv_stride = ROUND_UP_8 (width) / 2;
647
648       /* destination strides from the real picture width */
649       dst_y_stride = enc->info_width;
650       dst_uv_stride = enc->info_width / 2;
651
652       ret = gst_pad_alloc_buffer_and_set_caps (enc->srcpad,
653           GST_BUFFER_OFFSET_NONE, y_size * 3 / 2, GST_PAD_CAPS (enc->srcpad),
654           &newbuf);
655       if (ret != GST_FLOW_OK)
656         goto no_buffer;
657
658       dest_y = yuv.y = GST_BUFFER_DATA (newbuf);
659       dest_u = yuv.u = yuv.y + y_size;
660       dest_v = yuv.v = yuv.u + y_size / 4;
661
662       src_y = GST_BUFFER_DATA (buffer);
663       src_u = src_y + src_y_stride * ROUND_UP_2 (height);
664       src_v = src_u + src_uv_stride * ROUND_UP_2 (height) / 2;
665
666       if (enc->border != BORDER_NONE) {
667         /* fill top border */
668         for (i = 0; i < enc->offset_y; i++) {
669           memset (dest_y, 0, dst_y_stride);
670           dest_y += dst_y_stride;
671         }
672       } else {
673         dest_y += dst_y_stride * enc->offset_y;
674       }
675
676       offset_x = enc->offset_x;
677       right_x = width + enc->offset_x;
678       right_border = dst_y_stride - right_x;
679
680       /* copy Y plane */
681       for (i = 0; i < height; i++) {
682         memcpy (dest_y + offset_x, src_y, width);
683         if (enc->border != BORDER_NONE) {
684           memset (dest_y, 0, offset_x);
685           memset (dest_y + right_x, 0, right_border);
686         }
687
688         dest_y += dst_y_stride;
689         src_y += src_y_stride;
690       }
691
692       if (enc->border != BORDER_NONE) {
693         /* fill bottom border */
694         for (i = height + enc->offset_y; i < enc->info.height; i++) {
695           memset (dest_y, 0, dst_y_stride);
696           dest_y += dst_y_stride;
697         }
698
699         /* fill top border chroma */
700         for (i = 0; i < enc->offset_y / 2; i++) {
701           memset (dest_u, 128, dst_uv_stride);
702           memset (dest_v, 128, dst_uv_stride);
703           dest_u += dst_uv_stride;
704           dest_v += dst_uv_stride;
705         }
706       } else {
707         dest_u += dst_uv_stride * enc->offset_y / 2;
708         dest_v += dst_uv_stride * enc->offset_y / 2;
709       }
710
711       offset_x = enc->offset_x / 2;
712       right_x = cwidth + offset_x;
713       right_border = dst_uv_stride - right_x;
714
715       /* copy UV planes */
716       for (i = 0; i < cheight; i++) {
717         memcpy (dest_v + offset_x, src_v, cwidth);
718         memcpy (dest_u + offset_x, src_u, cwidth);
719
720         if (enc->border != BORDER_NONE) {
721           memset (dest_u, 128, offset_x);
722           memset (dest_u + right_x, 128, right_border);
723           memset (dest_v, 128, offset_x);
724           memset (dest_v + right_x, 128, right_border);
725         }
726
727         dest_u += dst_uv_stride;
728         dest_v += dst_uv_stride;
729         src_u += src_uv_stride;
730         src_v += src_uv_stride;
731       }
732
733       if (enc->border != BORDER_NONE) {
734         /* fill bottom border */
735         for (i = cheight + enc->offset_y / 2; i < enc->info_height / 2; i++) {
736           memset (dest_u, 128, dst_uv_stride);
737           memset (dest_v, 128, dst_uv_stride);
738           dest_u += dst_uv_stride;
739           dest_v += dst_uv_stride;
740         }
741       }
742
743       gst_buffer_unref (buffer);
744       buffer = newbuf;
745     }
746
747     res = theora_encode_YUVin (&enc->state, &yuv);
748
749     ret = GST_FLOW_OK;
750     while (theora_encode_packetout (&enc->state, 0, &op)) {
751       /* This is where we hack around theora's broken idea of what granulepos
752          is -- normally we wouldn't need to add the 1, because granulepos
753          should be the presentation time of the last sample in the packet, but
754          theora starts with 0 instead of 1... */
755       GstClockTime next_time;
756
757       next_time = theora_granule_time (&enc->state,
758           granulepos_add (op.granulepos, 1, enc->granule_shift)) * GST_SECOND;
759       ret =
760           theora_push_packet (enc, &op, enc->next_ts, next_time - enc->next_ts);
761       enc->next_ts = next_time;
762       if (ret != GST_FLOW_OK)
763         goto data_push;
764     }
765     gst_buffer_unref (buffer);
766   }
767
768   return ret;
769
770   /* ERRORS */
771 header_buffer_alloc:
772   {
773     gst_buffer_unref (buffer);
774     return ret;
775   }
776 header_push:
777   {
778     gst_buffer_unref (buffer);
779     return ret;
780   }
781 no_buffer:
782   {
783     gst_buffer_unref (buffer);
784     return ret;
785   }
786 data_push:
787   {
788     gst_buffer_unref (buffer);
789     return ret;
790   }
791 }
792
793 static GstStateChangeReturn
794 theora_enc_change_state (GstElement * element, GstStateChange transition)
795 {
796   GstTheoraEnc *enc;
797   GstStateChangeReturn ret;
798
799   enc = GST_THEORA_ENC (element);
800
801   switch (transition) {
802     case GST_STATE_CHANGE_NULL_TO_READY:
803       break;
804     case GST_STATE_CHANGE_READY_TO_PAUSED:
805       GST_DEBUG_OBJECT (enc, "READY->PAUSED Initing theora state");
806       theora_info_init (&enc->info);
807       theora_comment_init (&enc->comment);
808       enc->packetno = 0;
809       break;
810     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
811       break;
812     default:
813       break;
814   }
815
816   ret = parent_class->change_state (element, transition);
817
818   switch (transition) {
819     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
820       break;
821     case GST_STATE_CHANGE_PAUSED_TO_READY:
822       GST_DEBUG_OBJECT (enc, "PAUSED->READY Clearing theora state");
823       theora_clear (&enc->state);
824       theora_comment_clear (&enc->comment);
825       theora_info_clear (&enc->info);
826       break;
827     case GST_STATE_CHANGE_READY_TO_NULL:
828       break;
829     default:
830       break;
831   }
832
833   return ret;
834 }
835
836 static void
837 theora_enc_set_property (GObject * object, guint prop_id,
838     const GValue * value, GParamSpec * pspec)
839 {
840   GstTheoraEnc *enc = GST_THEORA_ENC (object);
841
842   switch (prop_id) {
843     case ARG_CENTER:
844       enc->center = g_value_get_boolean (value);
845       break;
846     case ARG_BORDER:
847       enc->border = g_value_get_enum (value);
848       break;
849     case ARG_BITRATE:
850       enc->video_bitrate = g_value_get_int (value) * 1000;
851       enc->video_quality = 0;
852       break;
853     case ARG_QUALITY:
854       enc->video_quality = g_value_get_int (value);
855       enc->video_bitrate = 0;
856       break;
857     case ARG_QUICK:
858       enc->quick = g_value_get_boolean (value);
859       break;
860     case ARG_KEYFRAME_AUTO:
861       enc->keyframe_auto = g_value_get_boolean (value);
862       break;
863     case ARG_KEYFRAME_FREQ:
864       enc->keyframe_freq = g_value_get_int (value);
865       break;
866     case ARG_KEYFRAME_FREQ_FORCE:
867       enc->keyframe_force = g_value_get_int (value);
868       break;
869     case ARG_KEYFRAME_THRESHOLD:
870       enc->keyframe_threshold = g_value_get_int (value);
871       break;
872     case ARG_KEYFRAME_MINDISTANCE:
873       enc->keyframe_mindistance = g_value_get_int (value);
874       break;
875     case ARG_NOISE_SENSITIVITY:
876       enc->noise_sensitivity = g_value_get_int (value);
877       break;
878     case ARG_SHARPNESS:
879       enc->sharpness = g_value_get_int (value);
880       break;
881     default:
882       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
883       break;
884   }
885 }
886
887 static void
888 theora_enc_get_property (GObject * object, guint prop_id,
889     GValue * value, GParamSpec * pspec)
890 {
891   GstTheoraEnc *enc = GST_THEORA_ENC (object);
892
893   switch (prop_id) {
894     case ARG_CENTER:
895       g_value_set_boolean (value, enc->center);
896       break;
897     case ARG_BORDER:
898       g_value_set_enum (value, enc->border);
899       break;
900     case ARG_BITRATE:
901       g_value_set_int (value, enc->video_bitrate / 1000);
902       break;
903     case ARG_QUALITY:
904       g_value_set_int (value, enc->video_quality);
905       break;
906     case ARG_QUICK:
907       g_value_set_boolean (value, enc->quick);
908       break;
909     case ARG_KEYFRAME_AUTO:
910       g_value_set_boolean (value, enc->keyframe_auto);
911       break;
912     case ARG_KEYFRAME_FREQ:
913       g_value_set_int (value, enc->keyframe_freq);
914       break;
915     case ARG_KEYFRAME_FREQ_FORCE:
916       g_value_set_int (value, enc->keyframe_force);
917       break;
918     case ARG_KEYFRAME_THRESHOLD:
919       g_value_set_int (value, enc->keyframe_threshold);
920       break;
921     case ARG_KEYFRAME_MINDISTANCE:
922       g_value_set_int (value, enc->keyframe_mindistance);
923       break;
924     case ARG_NOISE_SENSITIVITY:
925       g_value_set_int (value, enc->noise_sensitivity);
926       break;
927     case ARG_SHARPNESS:
928       g_value_set_int (value, enc->sharpness);
929       break;
930     default:
931       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
932       break;
933   }
934 }