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