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