Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / ext / vorbis / gstvorbisenc.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
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-vorbisenc
22  * @see_also: vorbisdec, oggmux
23  *
24  * This element encodes raw float audio into a Vorbis stream.
25  * <ulink url="http://www.vorbis.com/">Vorbis</ulink> is a royalty-free
26  * audio codec maintained by the <ulink url="http://www.xiph.org/">Xiph.org
27  * Foundation</ulink>.
28  *
29  * <refsect2>
30  * <title>Example pipelines</title>
31  * |[
32  * gst-launch -v audiotestsrc wave=sine num-buffers=100 ! audioconvert ! vorbisenc ! oggmux ! filesink location=sine.ogg
33  * ]| Encode a test sine signal to Ogg/Vorbis.  Note that the resulting file
34  * will be really small because a sine signal compresses very well.
35  * |[
36  * gst-launch -v alsasrc ! audioconvert ! vorbisenc ! oggmux ! filesink location=alsasrc.ogg
37  * ]| Record from a sound card using ALSA and encode to Ogg/Vorbis.
38  * </refsect2>
39  *
40  * Last reviewed on 2006-03-01 (0.10.4)
41  */
42 #ifdef HAVE_CONFIG_H
43 #include "config.h"
44 #endif
45
46 #include <stdlib.h>
47 #include <string.h>
48 #include <time.h>
49 #include <vorbis/vorbisenc.h>
50
51 #include <gst/gsttagsetter.h>
52 #include <gst/tag/tag.h>
53 #include <gst/audio/multichannel.h>
54 #include <gst/audio/audio.h>
55 #include "gstvorbisenc.h"
56
57 #include "gstvorbiscommon.h"
58
59 GST_DEBUG_CATEGORY_EXTERN (vorbisenc_debug);
60 #define GST_CAT_DEFAULT vorbisenc_debug
61
62 static GstStaticPadTemplate vorbis_enc_sink_factory =
63 GST_STATIC_PAD_TEMPLATE ("sink",
64     GST_PAD_SINK,
65     GST_PAD_ALWAYS,
66     GST_STATIC_CAPS ("audio/x-raw, "
67         "format = (string) " GST_AUDIO_NE (F32) ", "
68         "rate = (int) [ 1, 200000 ], " "channels = (int) [ 1, 256 ]")
69     );
70
71 static GstStaticPadTemplate vorbis_enc_src_factory =
72 GST_STATIC_PAD_TEMPLATE ("src",
73     GST_PAD_SRC,
74     GST_PAD_ALWAYS,
75     GST_STATIC_CAPS ("audio/x-vorbis")
76     );
77
78 enum
79 {
80   ARG_0,
81   ARG_MAX_BITRATE,
82   ARG_BITRATE,
83   ARG_MIN_BITRATE,
84   ARG_QUALITY,
85   ARG_MANAGED,
86   ARG_LAST_MESSAGE
87 };
88
89 static GstFlowReturn gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc);
90
91 /* this function takes into account the granulepos_offset and the subgranule
92  * time offset */
93 static GstClockTime
94 granulepos_to_timestamp_offset (GstVorbisEnc * vorbisenc,
95     ogg_int64_t granulepos)
96 {
97   if (granulepos >= 0)
98     return gst_util_uint64_scale ((guint64) granulepos
99         + vorbisenc->granulepos_offset, GST_SECOND, vorbisenc->frequency)
100         + vorbisenc->subgranule_offset;
101   return GST_CLOCK_TIME_NONE;
102 }
103
104 /* this function does a straight granulepos -> timestamp conversion */
105 static GstClockTime
106 granulepos_to_timestamp (GstVorbisEnc * vorbisenc, ogg_int64_t granulepos)
107 {
108   if (granulepos >= 0)
109     return gst_util_uint64_scale ((guint64) granulepos,
110         GST_SECOND, vorbisenc->frequency);
111   return GST_CLOCK_TIME_NONE;
112 }
113
114 #define MAX_BITRATE_DEFAULT     -1
115 #define BITRATE_DEFAULT         -1
116 #define MIN_BITRATE_DEFAULT     -1
117 #define QUALITY_DEFAULT         0.3
118 #define LOWEST_BITRATE          6000    /* lowest allowed for a 8 kHz stream */
119 #define HIGHEST_BITRATE         250001  /* highest allowed for a 44 kHz stream */
120
121 static gboolean gst_vorbis_enc_sink_event (GstPad * pad, GstEvent * event);
122 static GstFlowReturn gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer);
123 static gboolean gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc);
124
125 static void gst_vorbis_enc_dispose (GObject * object);
126 static void gst_vorbis_enc_get_property (GObject * object, guint prop_id,
127     GValue * value, GParamSpec * pspec);
128 static void gst_vorbis_enc_set_property (GObject * object, guint prop_id,
129     const GValue * value, GParamSpec * pspec);
130 static GstStateChangeReturn gst_vorbis_enc_change_state (GstElement * element,
131     GstStateChange transition);
132 static void gst_vorbis_enc_add_interfaces (GType vorbisenc_type);
133
134 #define gst_vorbis_enc_parent_class parent_class
135 G_DEFINE_TYPE_WITH_CODE (GstVorbisEnc, gst_vorbis_enc,
136     GST_TYPE_ELEMENT, gst_vorbis_enc_add_interfaces (g_define_type_id));
137
138 static void
139 gst_vorbis_enc_add_interfaces (GType vorbisenc_type)
140 {
141   static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL };
142   static const GInterfaceInfo preset_info = { NULL, NULL, NULL };
143
144   g_type_add_interface_static (vorbisenc_type, GST_TYPE_TAG_SETTER,
145       &tag_setter_info);
146   g_type_add_interface_static (vorbisenc_type, GST_TYPE_PRESET, &preset_info);
147 }
148
149 static void
150 gst_vorbis_enc_class_init (GstVorbisEncClass * klass)
151 {
152   GObjectClass *gobject_class;
153   GstElementClass *gstelement_class;
154
155   gobject_class = (GObjectClass *) klass;
156   gstelement_class = (GstElementClass *) klass;
157
158   gobject_class->set_property = gst_vorbis_enc_set_property;
159   gobject_class->get_property = gst_vorbis_enc_get_property;
160   gobject_class->dispose = gst_vorbis_enc_dispose;
161
162   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BITRATE,
163       g_param_spec_int ("max-bitrate", "Maximum Bitrate",
164           "Specify a maximum bitrate (in bps). Useful for streaming "
165           "applications. (-1 == disabled)",
166           -1, HIGHEST_BITRATE, MAX_BITRATE_DEFAULT,
167           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
168   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
169       g_param_spec_int ("bitrate", "Target Bitrate",
170           "Attempt to encode at a bitrate averaging this (in bps). "
171           "This uses the bitrate management engine, and is not recommended for most users. "
172           "Quality is a better alternative. (-1 == disabled)", -1,
173           HIGHEST_BITRATE, BITRATE_DEFAULT,
174           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
175   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MIN_BITRATE,
176       g_param_spec_int ("min-bitrate", "Minimum Bitrate",
177           "Specify a minimum bitrate (in bps). Useful for encoding for a "
178           "fixed-size channel. (-1 == disabled)", -1, HIGHEST_BITRATE,
179           MIN_BITRATE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
180   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
181       g_param_spec_float ("quality", "Quality",
182           "Specify quality instead of specifying a particular bitrate.", -0.1,
183           1.0, QUALITY_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
184   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MANAGED,
185       g_param_spec_boolean ("managed", "Managed",
186           "Enable bitrate management engine", FALSE,
187           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
188   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
189       g_param_spec_string ("last-message", "last-message",
190           "The last status message", NULL,
191           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
192
193   gst_element_class_add_pad_template (gstelement_class,
194       gst_static_pad_template_get (&vorbis_enc_src_factory));
195   gst_element_class_add_pad_template (gstelement_class,
196       gst_static_pad_template_get (&vorbis_enc_sink_factory));
197   gst_element_class_set_details_simple (gstelement_class,
198       "Vorbis audio encoder", "Codec/Encoder/Audio",
199       "Encodes audio in Vorbis format",
200       "Monty <monty@xiph.org>, " "Wim Taymans <wim@fluendo.com>");
201
202   gstelement_class->change_state =
203       GST_DEBUG_FUNCPTR (gst_vorbis_enc_change_state);
204 }
205
206 static void
207 gst_vorbis_enc_dispose (GObject * object)
208 {
209   GstVorbisEnc *vorbisenc = GST_VORBISENC (object);
210
211   if (vorbisenc->sinkcaps) {
212     gst_caps_unref (vorbisenc->sinkcaps);
213     vorbisenc->sinkcaps = NULL;
214   }
215
216   G_OBJECT_CLASS (parent_class)->dispose (object);
217 }
218
219 static GstCaps *
220 gst_vorbis_enc_generate_sink_caps (void)
221 {
222   GstCaps *caps = gst_caps_new_empty ();
223   int i, c;
224
225   gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
226           "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
227           "rate", GST_TYPE_INT_RANGE, 1, 200000,
228           "channels", G_TYPE_INT, 1, NULL));
229
230   gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
231           "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
232           "rate", GST_TYPE_INT_RANGE, 1, 200000,
233           "channels", G_TYPE_INT, 2, NULL));
234
235   for (i = 3; i <= 8; i++) {
236     GValue chanpos = { 0 };
237     GValue pos = { 0 };
238     GstStructure *structure;
239
240     g_value_init (&chanpos, GST_TYPE_ARRAY);
241     g_value_init (&pos, GST_TYPE_AUDIO_CHANNEL_POSITION);
242
243     for (c = 0; c < i; c++) {
244       g_value_set_enum (&pos, gst_vorbis_channel_positions[i - 1][c]);
245       gst_value_array_append_value (&chanpos, &pos);
246     }
247     g_value_unset (&pos);
248
249     structure = gst_structure_new ("audio/x-raw",
250         "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
251         "rate", GST_TYPE_INT_RANGE, 1, 200000, "channels", G_TYPE_INT, i, NULL);
252     gst_structure_set_value (structure, "channel-positions", &chanpos);
253     g_value_unset (&chanpos);
254
255     gst_caps_append_structure (caps, structure);
256   }
257
258   gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
259           "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
260           "rate", GST_TYPE_INT_RANGE, 1, 200000,
261           "channels", GST_TYPE_INT_RANGE, 9, 256, NULL));
262
263   return caps;
264 }
265
266 static GstCaps *
267 gst_vorbis_enc_sink_getcaps (GstPad * pad, GstCaps * filter)
268 {
269   GstVorbisEnc *vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
270
271   if (vorbisenc->sinkcaps == NULL)
272     vorbisenc->sinkcaps = gst_vorbis_enc_generate_sink_caps ();
273
274   if (filter)
275     return gst_caps_intersect_full (filter, vorbisenc->sinkcaps,
276         GST_CAPS_INTERSECT_FIRST);
277   else
278     return gst_caps_ref (vorbisenc->sinkcaps);
279 }
280
281 static gboolean
282 gst_vorbis_enc_sink_setcaps (GstVorbisEnc * vorbisenc, GstCaps * caps)
283 {
284   GstStructure *structure;
285
286   vorbisenc->setup = FALSE;
287
288   structure = gst_caps_get_structure (caps, 0);
289   gst_structure_get_int (structure, "channels", &vorbisenc->channels);
290   gst_structure_get_int (structure, "rate", &vorbisenc->frequency);
291
292   gst_vorbis_enc_setup (vorbisenc);
293
294   if (vorbisenc->setup)
295     return TRUE;
296
297   return FALSE;
298 }
299
300 static gboolean
301 gst_vorbis_enc_convert_src (GstPad * pad, GstFormat src_format,
302     gint64 src_value, GstFormat dest_format, gint64 * dest_value)
303 {
304   gboolean res = TRUE;
305   GstVorbisEnc *vorbisenc;
306   gint64 avg;
307
308   vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
309
310   if (vorbisenc->samples_in == 0 ||
311       vorbisenc->bytes_out == 0 || vorbisenc->frequency == 0) {
312     gst_object_unref (vorbisenc);
313     return FALSE;
314   }
315
316   avg = (vorbisenc->bytes_out * vorbisenc->frequency) / (vorbisenc->samples_in);
317
318   switch (src_format) {
319     case GST_FORMAT_BYTES:
320       switch (dest_format) {
321         case GST_FORMAT_TIME:
322           *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND, avg);
323           break;
324         default:
325           res = FALSE;
326       }
327       break;
328     case GST_FORMAT_TIME:
329       switch (dest_format) {
330         case GST_FORMAT_BYTES:
331           *dest_value = gst_util_uint64_scale_int (src_value, avg, GST_SECOND);
332           break;
333         default:
334           res = FALSE;
335       }
336       break;
337     default:
338       res = FALSE;
339   }
340   gst_object_unref (vorbisenc);
341   return res;
342 }
343
344 static gboolean
345 gst_vorbis_enc_convert_sink (GstPad * pad, GstFormat src_format,
346     gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
347 {
348   gboolean res = TRUE;
349   guint scale = 1;
350   gint bytes_per_sample;
351   GstVorbisEnc *vorbisenc;
352
353   vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
354
355   bytes_per_sample = vorbisenc->channels * 2;
356
357   switch (src_format) {
358     case GST_FORMAT_BYTES:
359       switch (*dest_format) {
360         case GST_FORMAT_DEFAULT:
361           if (bytes_per_sample == 0)
362             return FALSE;
363           *dest_value = src_value / bytes_per_sample;
364           break;
365         case GST_FORMAT_TIME:
366         {
367           gint byterate = bytes_per_sample * vorbisenc->frequency;
368
369           if (byterate == 0)
370             return FALSE;
371           *dest_value =
372               gst_util_uint64_scale_int (src_value, GST_SECOND, byterate);
373           break;
374         }
375         default:
376           res = FALSE;
377       }
378       break;
379     case GST_FORMAT_DEFAULT:
380       switch (*dest_format) {
381         case GST_FORMAT_BYTES:
382           *dest_value = src_value * bytes_per_sample;
383           break;
384         case GST_FORMAT_TIME:
385           if (vorbisenc->frequency == 0)
386             return FALSE;
387           *dest_value =
388               gst_util_uint64_scale_int (src_value, GST_SECOND,
389               vorbisenc->frequency);
390           break;
391         default:
392           res = FALSE;
393       }
394       break;
395     case GST_FORMAT_TIME:
396       switch (*dest_format) {
397         case GST_FORMAT_BYTES:
398           scale = bytes_per_sample;
399           /* fallthrough */
400         case GST_FORMAT_DEFAULT:
401           *dest_value =
402               gst_util_uint64_scale_int (src_value,
403               scale * vorbisenc->frequency, GST_SECOND);
404           break;
405         default:
406           res = FALSE;
407       }
408       break;
409     default:
410       res = FALSE;
411   }
412   gst_object_unref (vorbisenc);
413   return res;
414 }
415
416 static gint64
417 gst_vorbis_enc_get_latency (GstVorbisEnc * vorbisenc)
418 {
419   /* FIXME, this probably depends on the bitrate and other setting but for now
420    * we return this value, which was obtained by totally unscientific
421    * measurements */
422   return 58 * GST_MSECOND;
423 }
424
425 static const GstQueryType *
426 gst_vorbis_enc_get_query_types (GstPad * pad)
427 {
428   static const GstQueryType gst_vorbis_enc_src_query_types[] = {
429     GST_QUERY_POSITION,
430     GST_QUERY_DURATION,
431     GST_QUERY_CONVERT,
432     0
433   };
434
435   return gst_vorbis_enc_src_query_types;
436 }
437
438 static gboolean
439 gst_vorbis_enc_src_query (GstPad * pad, GstQuery * query)
440 {
441   gboolean res = TRUE;
442   GstVorbisEnc *vorbisenc;
443   GstPad *peerpad;
444
445   vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
446   peerpad = gst_pad_get_peer (vorbisenc->sinkpad);
447
448   switch (GST_QUERY_TYPE (query)) {
449     case GST_QUERY_POSITION:
450     {
451       GstFormat req_fmt;
452       gint64 pos, val;
453
454       gst_query_parse_position (query, &req_fmt, NULL);
455       if ((res = gst_pad_query_position (peerpad, req_fmt, &val))) {
456         gst_query_set_position (query, req_fmt, val);
457         break;
458       }
459
460       if (!(res = gst_pad_query_position (peerpad, GST_FORMAT_TIME, &pos)))
461         break;
462
463       if ((res =
464               gst_pad_query_convert (peerpad, GST_FORMAT_TIME, pos, req_fmt,
465                   &val))) {
466         gst_query_set_position (query, req_fmt, val);
467       }
468       break;
469     }
470     case GST_QUERY_DURATION:
471     {
472       GstFormat req_fmt;
473       gint64 dur, val;
474
475       gst_query_parse_duration (query, &req_fmt, NULL);
476       if ((res = gst_pad_query_duration (peerpad, req_fmt, &val))) {
477         gst_query_set_duration (query, req_fmt, val);
478         break;
479       }
480
481       if (!(res = gst_pad_query_duration (peerpad, GST_FORMAT_TIME, &dur)))
482         break;
483
484       if ((res =
485               gst_pad_query_convert (peerpad, GST_FORMAT_TIME, dur, req_fmt,
486                   &val))) {
487         gst_query_set_duration (query, req_fmt, val);
488       }
489       break;
490     }
491     case GST_QUERY_CONVERT:
492     {
493       GstFormat src_fmt, dest_fmt;
494       gint64 src_val, dest_val;
495
496       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
497       if (!(res =
498               gst_vorbis_enc_convert_src (pad, src_fmt, src_val, dest_fmt,
499                   &dest_val)))
500         goto error;
501       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
502       break;
503     }
504     case GST_QUERY_LATENCY:
505     {
506       gboolean live;
507       GstClockTime min_latency, max_latency;
508       gint64 latency;
509
510       if ((res = gst_pad_query (peerpad, query))) {
511         gst_query_parse_latency (query, &live, &min_latency, &max_latency);
512
513         latency = gst_vorbis_enc_get_latency (vorbisenc);
514
515         /* add our latency */
516         min_latency += latency;
517         if (max_latency != -1)
518           max_latency += latency;
519
520         gst_query_set_latency (query, live, min_latency, max_latency);
521       }
522       break;
523     }
524     default:
525       res = gst_pad_query (peerpad, query);
526       break;
527   }
528
529 error:
530   gst_object_unref (peerpad);
531   gst_object_unref (vorbisenc);
532   return res;
533 }
534
535 static gboolean
536 gst_vorbis_enc_sink_query (GstPad * pad, GstQuery * query)
537 {
538   gboolean res = TRUE;
539
540   switch (GST_QUERY_TYPE (query)) {
541     case GST_QUERY_CONVERT:
542     {
543       GstFormat src_fmt, dest_fmt;
544       gint64 src_val, dest_val;
545
546       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
547       if (!(res =
548               gst_vorbis_enc_convert_sink (pad, src_fmt, src_val, &dest_fmt,
549                   &dest_val)))
550         goto error;
551       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
552       break;
553     }
554     default:
555       res = gst_pad_query_default (pad, query);
556       break;
557   }
558
559 error:
560   return res;
561 }
562
563 static void
564 gst_vorbis_enc_init (GstVorbisEnc * vorbisenc)
565 {
566   vorbisenc->sinkpad =
567       gst_pad_new_from_static_template (&vorbis_enc_sink_factory, "sink");
568   gst_pad_set_event_function (vorbisenc->sinkpad,
569       GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_event));
570   gst_pad_set_chain_function (vorbisenc->sinkpad,
571       GST_DEBUG_FUNCPTR (gst_vorbis_enc_chain));
572   gst_pad_set_getcaps_function (vorbisenc->sinkpad,
573       GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_getcaps));
574   gst_pad_set_query_function (vorbisenc->sinkpad,
575       GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_query));
576   gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->sinkpad);
577
578   vorbisenc->srcpad =
579       gst_pad_new_from_static_template (&vorbis_enc_src_factory, "src");
580   gst_pad_set_query_function (vorbisenc->srcpad,
581       GST_DEBUG_FUNCPTR (gst_vorbis_enc_src_query));
582   gst_pad_set_query_type_function (vorbisenc->srcpad,
583       GST_DEBUG_FUNCPTR (gst_vorbis_enc_get_query_types));
584   gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->srcpad);
585
586   vorbisenc->channels = -1;
587   vorbisenc->frequency = -1;
588
589   vorbisenc->managed = FALSE;
590   vorbisenc->max_bitrate = MAX_BITRATE_DEFAULT;
591   vorbisenc->bitrate = BITRATE_DEFAULT;
592   vorbisenc->min_bitrate = MIN_BITRATE_DEFAULT;
593   vorbisenc->quality = QUALITY_DEFAULT;
594   vorbisenc->quality_set = FALSE;
595   vorbisenc->last_message = NULL;
596 }
597
598 static void
599 gst_vorbis_enc_metadata_set1 (const GstTagList * list, const gchar * tag,
600     gpointer vorbisenc)
601 {
602   GstVorbisEnc *enc = GST_VORBISENC (vorbisenc);
603   GList *vc_list, *l;
604
605   vc_list = gst_tag_to_vorbis_comments (list, tag);
606
607   for (l = vc_list; l != NULL; l = l->next) {
608     const gchar *vc_string = (const gchar *) l->data;
609     gchar *key = NULL, *val = NULL;
610
611     GST_LOG_OBJECT (vorbisenc, "vorbis comment: %s", vc_string);
612     if (gst_tag_parse_extended_comment (vc_string, &key, NULL, &val, TRUE)) {
613       vorbis_comment_add_tag (&enc->vc, key, val);
614       g_free (key);
615       g_free (val);
616     }
617   }
618
619   g_list_foreach (vc_list, (GFunc) g_free, NULL);
620   g_list_free (vc_list);
621 }
622
623 static void
624 gst_vorbis_enc_set_metadata (GstVorbisEnc * enc)
625 {
626   GstTagList *merged_tags;
627   const GstTagList *user_tags;
628
629   vorbis_comment_init (&enc->vc);
630
631   user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (enc));
632
633   GST_DEBUG_OBJECT (enc, "upstream tags = %" GST_PTR_FORMAT, enc->tags);
634   GST_DEBUG_OBJECT (enc, "user-set tags = %" GST_PTR_FORMAT, user_tags);
635
636   /* gst_tag_list_merge() will handle NULL for either or both lists fine */
637   merged_tags = gst_tag_list_merge (user_tags, enc->tags,
638       gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (enc)));
639
640   if (merged_tags) {
641     GST_DEBUG_OBJECT (enc, "merged   tags = %" GST_PTR_FORMAT, merged_tags);
642     gst_tag_list_foreach (merged_tags, gst_vorbis_enc_metadata_set1, enc);
643     gst_tag_list_free (merged_tags);
644   }
645 }
646
647 static gchar *
648 get_constraints_string (GstVorbisEnc * vorbisenc)
649 {
650   gint min = vorbisenc->min_bitrate;
651   gint max = vorbisenc->max_bitrate;
652   gchar *result;
653
654   if (min > 0 && max > 0)
655     result = g_strdup_printf ("(min %d bps, max %d bps)", min, max);
656   else if (min > 0)
657     result = g_strdup_printf ("(min %d bps, no max)", min);
658   else if (max > 0)
659     result = g_strdup_printf ("(no min, max %d bps)", max);
660   else
661     result = g_strdup_printf ("(no min or max)");
662
663   return result;
664 }
665
666 static void
667 update_start_message (GstVorbisEnc * vorbisenc)
668 {
669   gchar *constraints;
670
671   g_free (vorbisenc->last_message);
672
673   if (vorbisenc->bitrate > 0) {
674     if (vorbisenc->managed) {
675       constraints = get_constraints_string (vorbisenc);
676       vorbisenc->last_message =
677           g_strdup_printf ("encoding at average bitrate %d bps %s",
678           vorbisenc->bitrate, constraints);
679       g_free (constraints);
680     } else {
681       vorbisenc->last_message =
682           g_strdup_printf
683           ("encoding at approximate bitrate %d bps (VBR encoding enabled)",
684           vorbisenc->bitrate);
685     }
686   } else {
687     if (vorbisenc->quality_set) {
688       if (vorbisenc->managed) {
689         constraints = get_constraints_string (vorbisenc);
690         vorbisenc->last_message =
691             g_strdup_printf
692             ("encoding at quality level %2.2f using constrained VBR %s",
693             vorbisenc->quality, constraints);
694         g_free (constraints);
695       } else {
696         vorbisenc->last_message =
697             g_strdup_printf ("encoding at quality level %2.2f",
698             vorbisenc->quality);
699       }
700     } else {
701       constraints = get_constraints_string (vorbisenc);
702       vorbisenc->last_message =
703           g_strdup_printf ("encoding using bitrate management %s", constraints);
704       g_free (constraints);
705     }
706   }
707
708   g_object_notify (G_OBJECT (vorbisenc), "last_message");
709 }
710
711 static gboolean
712 gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc)
713 {
714   vorbisenc->setup = FALSE;
715
716   if (vorbisenc->bitrate < 0 && vorbisenc->min_bitrate < 0
717       && vorbisenc->max_bitrate < 0) {
718     vorbisenc->quality_set = TRUE;
719   }
720
721   update_start_message (vorbisenc);
722
723   /* choose an encoding mode */
724   /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
725   vorbis_info_init (&vorbisenc->vi);
726
727   if (vorbisenc->quality_set) {
728     if (vorbis_encode_setup_vbr (&vorbisenc->vi,
729             vorbisenc->channels, vorbisenc->frequency,
730             vorbisenc->quality) != 0) {
731       GST_ERROR_OBJECT (vorbisenc,
732           "vorbisenc: initialisation failed: invalid parameters for quality");
733       vorbis_info_clear (&vorbisenc->vi);
734       return FALSE;
735     }
736
737     /* do we have optional hard quality restrictions? */
738     if (vorbisenc->max_bitrate > 0 || vorbisenc->min_bitrate > 0) {
739       struct ovectl_ratemanage_arg ai;
740
741       vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_GET, &ai);
742
743       ai.bitrate_hard_min = vorbisenc->min_bitrate;
744       ai.bitrate_hard_max = vorbisenc->max_bitrate;
745       ai.management_active = 1;
746
747       vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, &ai);
748     }
749   } else {
750     long min_bitrate, max_bitrate;
751
752     min_bitrate = vorbisenc->min_bitrate > 0 ? vorbisenc->min_bitrate : -1;
753     max_bitrate = vorbisenc->max_bitrate > 0 ? vorbisenc->max_bitrate : -1;
754
755     if (vorbis_encode_setup_managed (&vorbisenc->vi,
756             vorbisenc->channels,
757             vorbisenc->frequency,
758             max_bitrate, vorbisenc->bitrate, min_bitrate) != 0) {
759       GST_ERROR_OBJECT (vorbisenc,
760           "vorbis_encode_setup_managed "
761           "(c %d, rate %d, max br %ld, br %d, min br %ld) failed",
762           vorbisenc->channels, vorbisenc->frequency, max_bitrate,
763           vorbisenc->bitrate, min_bitrate);
764       vorbis_info_clear (&vorbisenc->vi);
765       return FALSE;
766     }
767   }
768
769   if (vorbisenc->managed && vorbisenc->bitrate < 0) {
770     vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_AVG, NULL);
771   } else if (!vorbisenc->managed) {
772     /* Turn off management entirely (if it was turned on). */
773     vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, NULL);
774   }
775   vorbis_encode_setup_init (&vorbisenc->vi);
776
777   /* set up the analysis state and auxiliary encoding storage */
778   vorbis_analysis_init (&vorbisenc->vd, &vorbisenc->vi);
779   vorbis_block_init (&vorbisenc->vd, &vorbisenc->vb);
780
781   vorbisenc->next_ts = 0;
782
783   vorbisenc->setup = TRUE;
784
785   return TRUE;
786 }
787
788 static GstFlowReturn
789 gst_vorbis_enc_clear (GstVorbisEnc * vorbisenc)
790 {
791   GstFlowReturn ret = GST_FLOW_OK;
792
793   if (vorbisenc->setup) {
794     vorbis_analysis_wrote (&vorbisenc->vd, 0);
795     ret = gst_vorbis_enc_output_buffers (vorbisenc);
796
797     vorbisenc->setup = FALSE;
798   }
799
800   /* clean up and exit.  vorbis_info_clear() must be called last */
801   vorbis_block_clear (&vorbisenc->vb);
802   vorbis_dsp_clear (&vorbisenc->vd);
803   vorbis_info_clear (&vorbisenc->vi);
804
805   vorbisenc->header_sent = FALSE;
806
807   return ret;
808 }
809
810 /* prepare a buffer for transmission by passing data through libvorbis */
811 static GstBuffer *
812 gst_vorbis_enc_buffer_from_packet (GstVorbisEnc * vorbisenc,
813     ogg_packet * packet)
814 {
815   GstBuffer *outbuf;
816
817   outbuf = gst_buffer_new_and_alloc (packet->bytes);
818   gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
819   /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
820    * time representation */
821   GST_BUFFER_OFFSET_END (outbuf) = packet->granulepos +
822       vorbisenc->granulepos_offset;
823   GST_BUFFER_OFFSET (outbuf) = granulepos_to_timestamp (vorbisenc,
824       GST_BUFFER_OFFSET_END (outbuf));
825   GST_BUFFER_TIMESTAMP (outbuf) = vorbisenc->next_ts;
826
827   /* update the next timestamp, taking granulepos_offset and subgranule offset
828    * into account */
829   vorbisenc->next_ts =
830       granulepos_to_timestamp_offset (vorbisenc, packet->granulepos);
831   GST_BUFFER_DURATION (outbuf) =
832       vorbisenc->next_ts - GST_BUFFER_TIMESTAMP (outbuf);
833
834   if (vorbisenc->next_discont) {
835     GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
836     vorbisenc->next_discont = FALSE;
837   }
838
839   GST_LOG_OBJECT (vorbisenc, "encoded buffer of %" G_GSIZE_FORMAT " bytes",
840       gst_buffer_get_size (outbuf));
841   return outbuf;
842 }
843
844 /* the same as above, but different logic for setting timestamp and granulepos
845  * */
846 static GstBuffer *
847 gst_vorbis_enc_buffer_from_header_packet (GstVorbisEnc * vorbisenc,
848     ogg_packet * packet)
849 {
850   GstBuffer *outbuf;
851
852   outbuf = gst_buffer_new_and_alloc (packet->bytes);
853   gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
854   GST_BUFFER_OFFSET (outbuf) = vorbisenc->bytes_out;
855   GST_BUFFER_OFFSET_END (outbuf) = 0;
856   GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
857   GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
858
859   GST_DEBUG ("created header packet buffer, %" G_GSIZE_FORMAT " bytes",
860       gst_buffer_get_size (outbuf));
861   return outbuf;
862 }
863
864 /* push out the buffer and do internal bookkeeping */
865 static GstFlowReturn
866 gst_vorbis_enc_push_buffer (GstVorbisEnc * vorbisenc, GstBuffer * buffer)
867 {
868   vorbisenc->bytes_out += gst_buffer_get_size (buffer);
869
870   GST_DEBUG_OBJECT (vorbisenc,
871       "Pushing buffer with GP %" G_GINT64_FORMAT ", ts %" GST_TIME_FORMAT,
872       GST_BUFFER_OFFSET_END (buffer),
873       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
874   return gst_pad_push (vorbisenc->srcpad, buffer);
875 }
876
877 static GstFlowReturn
878 gst_vorbis_enc_push_packet (GstVorbisEnc * vorbisenc, ogg_packet * packet)
879 {
880   GstBuffer *outbuf;
881
882   outbuf = gst_vorbis_enc_buffer_from_packet (vorbisenc, packet);
883   return gst_vorbis_enc_push_buffer (vorbisenc, outbuf);
884 }
885
886 /* Set a copy of these buffers as 'streamheader' on the caps.
887  * We need a copy to avoid these buffers ending up with (indirect) refs on
888  * themselves
889  */
890 static GstCaps *
891 gst_vorbis_enc_set_header_on_caps (GstCaps * caps, GstBuffer * buf1,
892     GstBuffer * buf2, GstBuffer * buf3)
893 {
894   GstBuffer *buf;
895   GstStructure *structure;
896   GValue array = { 0 };
897   GValue value = { 0 };
898
899   caps = gst_caps_make_writable (caps);
900   structure = gst_caps_get_structure (caps, 0);
901
902   /* mark buffers */
903   GST_BUFFER_FLAG_SET (buf1, GST_BUFFER_FLAG_IN_CAPS);
904   GST_BUFFER_FLAG_SET (buf2, GST_BUFFER_FLAG_IN_CAPS);
905   GST_BUFFER_FLAG_SET (buf3, GST_BUFFER_FLAG_IN_CAPS);
906
907   /* put buffers in a fixed list */
908   g_value_init (&array, GST_TYPE_ARRAY);
909   g_value_init (&value, GST_TYPE_BUFFER);
910   buf = gst_buffer_copy (buf1);
911   gst_value_set_buffer (&value, buf);
912   gst_buffer_unref (buf);
913   gst_value_array_append_value (&array, &value);
914   g_value_unset (&value);
915   g_value_init (&value, GST_TYPE_BUFFER);
916   buf = gst_buffer_copy (buf2);
917   gst_value_set_buffer (&value, buf);
918   gst_buffer_unref (buf);
919   gst_value_array_append_value (&array, &value);
920   g_value_unset (&value);
921   g_value_init (&value, GST_TYPE_BUFFER);
922   buf = gst_buffer_copy (buf3);
923   gst_value_set_buffer (&value, buf);
924   gst_buffer_unref (buf);
925   gst_value_array_append_value (&array, &value);
926   gst_structure_set_value (structure, "streamheader", &array);
927   g_value_unset (&value);
928   g_value_unset (&array);
929
930   return caps;
931 }
932
933 static gboolean
934 gst_vorbis_enc_sink_event (GstPad * pad, GstEvent * event)
935 {
936   gboolean res = TRUE;
937   GstVorbisEnc *vorbisenc;
938
939   vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
940
941   switch (GST_EVENT_TYPE (event)) {
942     case GST_EVENT_CAPS:
943     {
944       GstCaps *caps;
945
946       gst_event_parse_caps (event, &caps);
947       res = gst_vorbis_enc_sink_setcaps (vorbisenc, caps);
948       gst_event_unref (event);
949       break;
950     }
951     case GST_EVENT_EOS:
952       /* Tell the library we're at end of stream so that it can handle
953        * the last frame and mark end of stream in the output properly */
954       GST_DEBUG_OBJECT (vorbisenc, "EOS, clearing state and sending event on");
955       gst_vorbis_enc_clear (vorbisenc);
956
957       res = gst_pad_push_event (vorbisenc->srcpad, event);
958       break;
959     case GST_EVENT_TAG:
960       if (vorbisenc->tags) {
961         GstTagList *list;
962
963         gst_event_parse_tag (event, &list);
964         gst_tag_list_insert (vorbisenc->tags, list,
965             gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (vorbisenc)));
966       } else {
967         g_assert_not_reached ();
968       }
969       res = gst_pad_push_event (vorbisenc->srcpad, event);
970       break;
971     case GST_EVENT_SEGMENT:
972     {
973       const GstSegment *segment;
974
975       gst_event_parse_segment (event, &segment);
976
977       if (segment->format == GST_FORMAT_TIME) {
978         gst_segment_copy_into (segment, &vorbisenc->segment);
979       }
980     }
981       /* fall through */
982     default:
983       res = gst_pad_push_event (vorbisenc->srcpad, event);
984       break;
985   }
986   return res;
987 }
988
989 static gboolean
990 gst_vorbis_enc_buffer_check_discontinuous (GstVorbisEnc * vorbisenc,
991     GstClockTime timestamp, GstClockTime duration)
992 {
993   gboolean ret = FALSE;
994
995   GST_DEBUG_OBJECT (vorbisenc, "exp %" GST_TIME_FORMAT " time %" GST_TIME_FORMAT
996       "dur %" GST_TIME_FORMAT, GST_TIME_ARGS (vorbisenc->expected_ts),
997       GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration));
998
999   if (timestamp != GST_CLOCK_TIME_NONE &&
1000       vorbisenc->expected_ts != GST_CLOCK_TIME_NONE &&
1001       timestamp + duration != vorbisenc->expected_ts) {
1002     /* It turns out that a lot of elements don't generate perfect streams due
1003      * to rounding errors. So, we permit small errors (< 3 samples) without
1004      * causing a discont.
1005      */
1006     int threesample = GST_SECOND / vorbisenc->frequency * 3;
1007
1008     if ((GstClockTimeDiff) (timestamp - vorbisenc->expected_ts) > threesample) {
1009       GST_DEBUG_OBJECT (vorbisenc, "Expected TS %" GST_TIME_FORMAT
1010           ", buffer TS %" GST_TIME_FORMAT,
1011           GST_TIME_ARGS (vorbisenc->expected_ts), GST_TIME_ARGS (timestamp));
1012       ret = TRUE;
1013     }
1014   }
1015
1016   if (timestamp != GST_CLOCK_TIME_NONE && duration != GST_CLOCK_TIME_NONE) {
1017     vorbisenc->expected_ts = timestamp + duration;
1018   } else
1019     vorbisenc->expected_ts = GST_CLOCK_TIME_NONE;
1020
1021   return ret;
1022 }
1023
1024 static GstFlowReturn
1025 gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
1026 {
1027   GstVorbisEnc *vorbisenc;
1028   GstFlowReturn ret = GST_FLOW_OK;
1029   gfloat *data, *ptr;
1030   gulong size;
1031   gulong i, j;
1032   float **vorbis_buffer;
1033   GstBuffer *buf1, *buf2, *buf3;
1034   gboolean first = FALSE;
1035   GstClockTime timestamp = GST_CLOCK_TIME_NONE;
1036   GstClockTime running_time = GST_CLOCK_TIME_NONE;
1037   gsize bsize;
1038
1039   vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
1040
1041   if (!vorbisenc->setup)
1042     goto not_setup;
1043
1044   buffer = gst_audio_buffer_clip (buffer, &vorbisenc->segment,
1045       vorbisenc->frequency, 4 * vorbisenc->channels);
1046   if (buffer == NULL) {
1047     GST_DEBUG_OBJECT (vorbisenc, "Dropping buffer, out of segment");
1048     return GST_FLOW_OK;
1049   }
1050   running_time =
1051       gst_segment_to_running_time (&vorbisenc->segment, GST_FORMAT_TIME,
1052       GST_BUFFER_TIMESTAMP (buffer));
1053   timestamp = running_time;
1054   GST_DEBUG_OBJECT (vorbisenc, " timestamp %" GST_TIME_FORMAT,
1055       GST_TIME_ARGS (timestamp));
1056   if (!vorbisenc->header_sent) {
1057     /* Vorbis streams begin with three headers; the initial header (with
1058        most of the codec setup parameters) which is mandated by the Ogg
1059        bitstream spec.  The second header holds any comment fields.  The
1060        third header holds the bitstream codebook.  We merely need to
1061        make the headers, then pass them to libvorbis one at a time;
1062        libvorbis handles the additional Ogg bitstream constraints */
1063     ogg_packet header;
1064     ogg_packet header_comm;
1065     ogg_packet header_code;
1066     GstCaps *caps;
1067
1068     /* first, make sure header buffers get timestamp == 0 */
1069     vorbisenc->next_ts = 0;
1070     vorbisenc->granulepos_offset = 0;
1071     vorbisenc->subgranule_offset = 0;
1072
1073     GST_DEBUG_OBJECT (vorbisenc, "creating and sending header packets");
1074     gst_vorbis_enc_set_metadata (vorbisenc);
1075     vorbis_analysis_headerout (&vorbisenc->vd, &vorbisenc->vc, &header,
1076         &header_comm, &header_code);
1077     vorbis_comment_clear (&vorbisenc->vc);
1078
1079     /* create header buffers */
1080     buf1 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header);
1081     buf2 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_comm);
1082     buf3 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_code);
1083
1084     /* mark and put on caps */
1085     vorbisenc->srccaps = gst_caps_new_simple ("audio/x-vorbis", NULL);
1086     caps = vorbisenc->srccaps;
1087     caps = gst_vorbis_enc_set_header_on_caps (caps, buf1, buf2, buf3);
1088
1089     /* negotiate with these caps */
1090     GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
1091     gst_pad_set_caps (vorbisenc->srcpad, caps);
1092
1093     /* push out buffers */
1094     /* push_buffer takes the reference even for failure */
1095     if ((ret = gst_vorbis_enc_push_buffer (vorbisenc, buf1)) != GST_FLOW_OK)
1096       goto failed_header_push;
1097     if ((ret = gst_vorbis_enc_push_buffer (vorbisenc, buf2)) != GST_FLOW_OK) {
1098       buf2 = NULL;
1099       goto failed_header_push;
1100     }
1101     if ((ret = gst_vorbis_enc_push_buffer (vorbisenc, buf3)) != GST_FLOW_OK) {
1102       buf3 = NULL;
1103       goto failed_header_push;
1104     }
1105
1106     /* now adjust starting granulepos accordingly if the buffer's timestamp is
1107        nonzero */
1108     vorbisenc->next_ts = timestamp;
1109     vorbisenc->expected_ts = timestamp;
1110     vorbisenc->granulepos_offset = gst_util_uint64_scale
1111         (running_time, vorbisenc->frequency, GST_SECOND);
1112     vorbisenc->subgranule_offset = 0;
1113     vorbisenc->subgranule_offset =
1114         vorbisenc->next_ts - granulepos_to_timestamp_offset (vorbisenc, 0);
1115
1116     vorbisenc->header_sent = TRUE;
1117     first = TRUE;
1118   }
1119
1120   if (vorbisenc->expected_ts != GST_CLOCK_TIME_NONE &&
1121       timestamp < vorbisenc->expected_ts) {
1122     int threesample = GST_SECOND / vorbisenc->frequency * 3;
1123     guint64 diff = vorbisenc->expected_ts - timestamp;
1124     guint64 diff_bytes;
1125     gsize size;
1126
1127     /* Don't freak out on tiny jitters; use the same < 3 sample
1128        tolerance as in the discontinuous detection */
1129     if ((GstClockTimeDiff) (vorbisenc->expected_ts - timestamp) > threesample) {
1130
1131       GST_WARNING_OBJECT (vorbisenc, "Buffer is older than previous "
1132           "timestamp + duration (%" GST_TIME_FORMAT "< %" GST_TIME_FORMAT
1133           "), cannot handle. Clipping buffer.",
1134           GST_TIME_ARGS (timestamp), GST_TIME_ARGS (vorbisenc->expected_ts));
1135
1136       size = gst_buffer_get_size (buffer);
1137
1138       diff_bytes =
1139           GST_CLOCK_TIME_TO_FRAMES (diff,
1140           vorbisenc->frequency) * vorbisenc->channels * sizeof (gfloat);
1141       if (diff_bytes >= size) {
1142         gst_buffer_unref (buffer);
1143         return GST_FLOW_OK;
1144       }
1145       buffer = gst_buffer_make_writable (buffer);
1146       gst_buffer_resize (buffer, diff_bytes, size - diff_bytes);
1147
1148       if (GST_BUFFER_DURATION_IS_VALID (buffer))
1149         GST_BUFFER_DURATION (buffer) -= diff;
1150     }
1151
1152     /* adjust the input timestamp in either case */
1153     GST_BUFFER_TIMESTAMP (buffer) += diff;
1154   }
1155
1156   if (gst_vorbis_enc_buffer_check_discontinuous (vorbisenc, timestamp,
1157           GST_BUFFER_DURATION (buffer)) && !first) {
1158     GST_WARNING_OBJECT (vorbisenc,
1159         "Buffer is discontinuous, flushing encoder "
1160         "and restarting (Discont from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT
1161         ")", GST_TIME_ARGS (vorbisenc->next_ts), GST_TIME_ARGS (timestamp));
1162     /* Re-initialise encoder (there's unfortunately no API to flush it) */
1163     if ((ret = gst_vorbis_enc_clear (vorbisenc)) != GST_FLOW_OK)
1164       return ret;
1165     if (!gst_vorbis_enc_setup (vorbisenc))
1166       return GST_FLOW_ERROR;    /* Should be impossible, we can only get here if
1167                                    we successfully initialised earlier */
1168
1169     /* Now, set our granulepos offset appropriately. */
1170     vorbisenc->next_ts = timestamp;
1171     /* We need to round to the nearest whole number of samples, not just do
1172      * a truncating division here */
1173     vorbisenc->granulepos_offset = gst_util_uint64_scale
1174         (running_time + GST_SECOND / vorbisenc->frequency / 2
1175         - vorbisenc->subgranule_offset, vorbisenc->frequency, GST_SECOND);
1176
1177     vorbisenc->header_sent = TRUE;
1178
1179     /* And our next output buffer must have DISCONT set on it */
1180     vorbisenc->next_discont = TRUE;
1181   }
1182
1183   /* Sending zero samples to libvorbis marks EOS, so we mustn't do that */
1184   data = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_WRITE);
1185   if (bsize == 0) {
1186     gst_buffer_unmap (buffer, data, bsize);
1187     gst_buffer_unref (buffer);
1188     return GST_FLOW_OK;
1189   }
1190
1191   /* data to encode */
1192   size = bsize / (vorbisenc->channels * sizeof (float));
1193
1194   ptr = data;
1195
1196   /* expose the buffer to submit data */
1197   vorbis_buffer = vorbis_analysis_buffer (&vorbisenc->vd, size);
1198
1199   /* deinterleave samples, write the buffer data */
1200   for (i = 0; i < size; i++) {
1201     for (j = 0; j < vorbisenc->channels; j++) {
1202       vorbis_buffer[j][i] = *ptr++;
1203     }
1204   }
1205
1206   /* tell the library how much we actually submitted */
1207   vorbis_analysis_wrote (&vorbisenc->vd, size);
1208   gst_buffer_unmap (buffer, data, bsize);
1209
1210   GST_LOG_OBJECT (vorbisenc, "wrote %lu samples to vorbis", size);
1211
1212   vorbisenc->samples_in += size;
1213
1214   gst_buffer_unref (buffer);
1215
1216   ret = gst_vorbis_enc_output_buffers (vorbisenc);
1217
1218   return ret;
1219
1220   /* error cases */
1221 not_setup:
1222   {
1223     gst_buffer_unref (buffer);
1224     GST_ELEMENT_ERROR (vorbisenc, CORE, NEGOTIATION, (NULL),
1225         ("encoder not initialized (input is not audio?)"));
1226     return GST_FLOW_UNEXPECTED;
1227   }
1228 failed_header_push:
1229   {
1230     GST_WARNING_OBJECT (vorbisenc, "Failed to push headers");
1231     /* buf1 is always already unreffed */
1232     if (buf2)
1233       gst_buffer_unref (buf2);
1234     if (buf3)
1235       gst_buffer_unref (buf3);
1236     gst_buffer_unref (buffer);
1237     return ret;
1238   }
1239 }
1240
1241 static GstFlowReturn
1242 gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc)
1243 {
1244   GstFlowReturn ret;
1245
1246   /* vorbis does some data preanalysis, then divides up blocks for
1247      more involved (potentially parallel) processing.  Get a single
1248      block for encoding now */
1249   while (vorbis_analysis_blockout (&vorbisenc->vd, &vorbisenc->vb) == 1) {
1250     ogg_packet op;
1251
1252     GST_LOG_OBJECT (vorbisenc, "analysed to a block");
1253
1254     /* analysis */
1255     vorbis_analysis (&vorbisenc->vb, NULL);
1256     vorbis_bitrate_addblock (&vorbisenc->vb);
1257
1258     while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &op)) {
1259       GST_LOG_OBJECT (vorbisenc, "pushing out a data packet");
1260       ret = gst_vorbis_enc_push_packet (vorbisenc, &op);
1261
1262       if (ret != GST_FLOW_OK)
1263         return ret;
1264     }
1265   }
1266
1267   return GST_FLOW_OK;
1268 }
1269
1270 static void
1271 gst_vorbis_enc_get_property (GObject * object, guint prop_id, GValue * value,
1272     GParamSpec * pspec)
1273 {
1274   GstVorbisEnc *vorbisenc;
1275
1276   g_return_if_fail (GST_IS_VORBISENC (object));
1277
1278   vorbisenc = GST_VORBISENC (object);
1279
1280   switch (prop_id) {
1281     case ARG_MAX_BITRATE:
1282       g_value_set_int (value, vorbisenc->max_bitrate);
1283       break;
1284     case ARG_BITRATE:
1285       g_value_set_int (value, vorbisenc->bitrate);
1286       break;
1287     case ARG_MIN_BITRATE:
1288       g_value_set_int (value, vorbisenc->min_bitrate);
1289       break;
1290     case ARG_QUALITY:
1291       g_value_set_float (value, vorbisenc->quality);
1292       break;
1293     case ARG_MANAGED:
1294       g_value_set_boolean (value, vorbisenc->managed);
1295       break;
1296     case ARG_LAST_MESSAGE:
1297       g_value_set_string (value, vorbisenc->last_message);
1298       break;
1299     default:
1300       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1301       break;
1302   }
1303 }
1304
1305 static void
1306 gst_vorbis_enc_set_property (GObject * object, guint prop_id,
1307     const GValue * value, GParamSpec * pspec)
1308 {
1309   GstVorbisEnc *vorbisenc;
1310
1311   g_return_if_fail (GST_IS_VORBISENC (object));
1312
1313   vorbisenc = GST_VORBISENC (object);
1314
1315   switch (prop_id) {
1316     case ARG_MAX_BITRATE:
1317     {
1318       gboolean old_value = vorbisenc->managed;
1319
1320       vorbisenc->max_bitrate = g_value_get_int (value);
1321       if (vorbisenc->max_bitrate >= 0
1322           && vorbisenc->max_bitrate < LOWEST_BITRATE) {
1323         g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1324         vorbisenc->max_bitrate = LOWEST_BITRATE;
1325       }
1326       if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
1327         vorbisenc->managed = TRUE;
1328       else
1329         vorbisenc->managed = FALSE;
1330
1331       if (old_value != vorbisenc->managed)
1332         g_object_notify (object, "managed");
1333       break;
1334     }
1335     case ARG_BITRATE:
1336       vorbisenc->bitrate = g_value_get_int (value);
1337       if (vorbisenc->bitrate >= 0 && vorbisenc->bitrate < LOWEST_BITRATE) {
1338         g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1339         vorbisenc->bitrate = LOWEST_BITRATE;
1340       }
1341       break;
1342     case ARG_MIN_BITRATE:
1343     {
1344       gboolean old_value = vorbisenc->managed;
1345
1346       vorbisenc->min_bitrate = g_value_get_int (value);
1347       if (vorbisenc->min_bitrate >= 0
1348           && vorbisenc->min_bitrate < LOWEST_BITRATE) {
1349         g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1350         vorbisenc->min_bitrate = LOWEST_BITRATE;
1351       }
1352       if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
1353         vorbisenc->managed = TRUE;
1354       else
1355         vorbisenc->managed = FALSE;
1356
1357       if (old_value != vorbisenc->managed)
1358         g_object_notify (object, "managed");
1359       break;
1360     }
1361     case ARG_QUALITY:
1362       vorbisenc->quality = g_value_get_float (value);
1363       if (vorbisenc->quality >= 0.0)
1364         vorbisenc->quality_set = TRUE;
1365       else
1366         vorbisenc->quality_set = FALSE;
1367       break;
1368     case ARG_MANAGED:
1369       vorbisenc->managed = g_value_get_boolean (value);
1370       break;
1371     default:
1372       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1373       break;
1374   }
1375 }
1376
1377 static GstStateChangeReturn
1378 gst_vorbis_enc_change_state (GstElement * element, GstStateChange transition)
1379 {
1380   GstVorbisEnc *vorbisenc = GST_VORBISENC (element);
1381   GstStateChangeReturn res;
1382
1383
1384   switch (transition) {
1385     case GST_STATE_CHANGE_NULL_TO_READY:
1386       vorbisenc->tags = gst_tag_list_new ();
1387       break;
1388     case GST_STATE_CHANGE_READY_TO_PAUSED:
1389       vorbisenc->setup = FALSE;
1390       vorbisenc->next_discont = FALSE;
1391       vorbisenc->header_sent = FALSE;
1392       gst_segment_init (&vorbisenc->segment, GST_FORMAT_TIME);
1393       break;
1394     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1395       break;
1396     default:
1397       break;
1398   }
1399
1400   res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1401
1402   switch (transition) {
1403     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1404       break;
1405     case GST_STATE_CHANGE_PAUSED_TO_READY:
1406       vorbis_block_clear (&vorbisenc->vb);
1407       vorbis_dsp_clear (&vorbisenc->vd);
1408       vorbis_info_clear (&vorbisenc->vi);
1409       g_free (vorbisenc->last_message);
1410       vorbisenc->last_message = NULL;
1411       if (vorbisenc->srccaps) {
1412         gst_caps_unref (vorbisenc->srccaps);
1413         vorbisenc->srccaps = NULL;
1414       }
1415       break;
1416     case GST_STATE_CHANGE_READY_TO_NULL:
1417       gst_tag_list_free (vorbisenc->tags);
1418       vorbisenc->tags = NULL;
1419     default:
1420       break;
1421   }
1422
1423   return res;
1424 }