expand tabs
[platform/upstream/gstreamer.git] / ext / vorbis / vorbisenc.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  * <refsect2>
25  * <para>
26  * This element encodes raw float audio into a Vorbis stream.
27  * <ulink url="http://www.vorbis.com/">Vorbis</ulink> is a royalty-free
28  * audio codec maintained by the <ulink url="http://www.xiph.org/">Xiph.org
29  * Foundation</ulink>.
30  * </para>
31  * <title>Example pipelines</title>
32  * <para>
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  * </para>
36  * <programlisting>
37  * gst-launch -v audiotestsrc wave=sine num-buffers=100 ! audioconvert ! vorbisenc ! oggmux ! filesink location=sine.ogg
38  * </programlisting>
39  * <para>
40  * Record from a sound card using ALSA and encode to Ogg/Vorbis.
41  * </para>
42  * <programlisting>
43  * gst-launch -v alsasrc ! audioconvert ! vorbisenc ! oggmux ! filesink location=alsasrc.ogg
44  * </programlisting>
45   * </refsect2>
46  */
47
48 /**
49  * SECTION:vorbisenc
50  * @short_description: an encoder that encodes to Ogg/Vorbis
51  * @see_also: oggdemux
52  *
53  */
54
55
56 #ifdef HAVE_CONFIG_H
57 #include "config.h"
58 #endif
59 #include <stdlib.h>
60 #include <string.h>
61 #include <time.h>
62 #include <vorbis/vorbisenc.h>
63
64 #include <gst/gsttagsetter.h>
65 #include <gst/tag/tag.h>
66 #include "vorbisenc.h"
67
68 GST_DEBUG_CATEGORY_EXTERN (vorbisenc_debug);
69 #define GST_CAT_DEFAULT vorbisenc_debug
70
71 static GstPadTemplate *gst_vorbisenc_src_template, *gst_vorbisenc_sink_template;
72
73 /* elementfactory information */
74 GstElementDetails vorbisenc_details = {
75   "Vorbis encoder",
76   "Codec/Encoder/Audio",
77   "Encodes audio in Vorbis format",
78   "Monty <monty@xiph.org>, " "Wim Taymans <wim@fluendo.com>",
79 };
80
81 /* GstVorbisEnc signals and args */
82 enum
83 {
84   /* FILL ME */
85   LAST_SIGNAL
86 };
87
88 enum
89 {
90   ARG_0,
91   ARG_MAX_BITRATE,
92   ARG_BITRATE,
93   ARG_MIN_BITRATE,
94   ARG_QUALITY,
95   ARG_MANAGED,
96   ARG_LAST_MESSAGE
97 };
98
99 static GstFlowReturn gst_vorbisenc_output_buffers (GstVorbisEnc * vorbisenc);
100
101 /* FIXME:
102  * vorbis_granule_time was added between 1.0 and 1.0.1; it's too silly
103  * to require a new version for such a simple function, but once we move
104  * beyond 1.0 for other reasons we can remove this copy */
105
106 static double
107 vorbis_granule_time_copy (vorbis_dsp_state * v, ogg_int64_t granulepos)
108 {
109   if (granulepos >= 0)
110     return ((double) granulepos / v->vi->rate);
111   return (-1);
112 }
113
114 #if 0
115 static const GstFormat *
116 gst_vorbisenc_get_formats (GstPad * pad)
117 {
118   static const GstFormat src_formats[] = {
119     GST_FORMAT_BYTES,
120     GST_FORMAT_TIME,
121     0
122   };
123   static const GstFormat sink_formats[] = {
124     GST_FORMAT_BYTES,
125     GST_FORMAT_DEFAULT,
126     GST_FORMAT_TIME,
127     0
128   };
129
130   return (GST_PAD_IS_SRC (pad) ? src_formats : sink_formats);
131 }
132 #endif
133
134 #define MAX_BITRATE_DEFAULT     -1
135 #define BITRATE_DEFAULT         -1
136 #define MIN_BITRATE_DEFAULT     -1
137 #define QUALITY_DEFAULT         0.3
138 #define LOWEST_BITRATE          6000    /* lowest allowed for a 8 kHz stream */
139 #define HIGHEST_BITRATE         250001  /* highest allowed for a 44 kHz stream */
140
141 static void gst_vorbisenc_base_init (gpointer g_class);
142 static void gst_vorbisenc_class_init (GstVorbisEncClass * klass);
143 static void gst_vorbisenc_init (GstVorbisEnc * vorbisenc);
144
145 static gboolean gst_vorbisenc_sink_event (GstPad * pad, GstEvent * event);
146 static GstFlowReturn gst_vorbisenc_chain (GstPad * pad, GstBuffer * buffer);
147 static gboolean gst_vorbisenc_setup (GstVorbisEnc * vorbisenc);
148
149 static void gst_vorbisenc_get_property (GObject * object, guint prop_id,
150     GValue * value, GParamSpec * pspec);
151 static void gst_vorbisenc_set_property (GObject * object, guint prop_id,
152     const GValue * value, GParamSpec * pspec);
153 static GstStateChangeReturn gst_vorbisenc_change_state (GstElement * element,
154     GstStateChange transition);
155
156 static GstElementClass *parent_class = NULL;
157
158 /*static guint gst_vorbisenc_signals[LAST_SIGNAL] = { 0 }; */
159
160 GType
161 vorbisenc_get_type (void)
162 {
163   static GType vorbisenc_type = 0;
164
165   if (!vorbisenc_type) {
166     static const GTypeInfo vorbisenc_info = {
167       sizeof (GstVorbisEncClass),
168       gst_vorbisenc_base_init,
169       NULL,
170       (GClassInitFunc) gst_vorbisenc_class_init,
171       NULL,
172       NULL,
173       sizeof (GstVorbisEnc),
174       0,
175       (GInstanceInitFunc) gst_vorbisenc_init,
176     };
177     static const GInterfaceInfo tag_setter_info = {
178       NULL,
179       NULL,
180       NULL
181     };
182
183     vorbisenc_type =
184         g_type_register_static (GST_TYPE_ELEMENT, "GstVorbisEnc",
185         &vorbisenc_info, 0);
186
187     g_type_add_interface_static (vorbisenc_type, GST_TYPE_TAG_SETTER,
188         &tag_setter_info);
189   }
190   return vorbisenc_type;
191 }
192
193 static GstCaps *
194 vorbis_caps_factory (void)
195 {
196   return gst_caps_new_simple ("audio/x-vorbis", NULL);
197 }
198
199 static GstCaps *
200 raw_caps_factory (void)
201 {
202   /* lowest sample rate is in vorbis/lib/modes/setup_8.h, 8000 Hz
203    * highest sample rate is in vorbis/lib/modes/setup_44.h, 50000 Hz */
204   return
205       gst_caps_new_simple ("audio/x-raw-float",
206       "rate", GST_TYPE_INT_RANGE, 8000, 50000,
207       "channels", GST_TYPE_INT_RANGE, 1, 2,
208       "endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32, NULL);
209 }
210
211 static void
212 gst_vorbisenc_base_init (gpointer g_class)
213 {
214   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
215   GstCaps *raw_caps, *vorbis_caps;
216
217   raw_caps = raw_caps_factory ();
218   vorbis_caps = vorbis_caps_factory ();
219
220   gst_vorbisenc_sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
221       GST_PAD_ALWAYS, raw_caps);
222   gst_vorbisenc_src_template = gst_pad_template_new ("src", GST_PAD_SRC,
223       GST_PAD_ALWAYS, vorbis_caps);
224   gst_element_class_add_pad_template (element_class,
225       gst_vorbisenc_sink_template);
226   gst_element_class_add_pad_template (element_class,
227       gst_vorbisenc_src_template);
228   gst_element_class_set_details (element_class, &vorbisenc_details);
229 }
230
231 static void
232 gst_vorbisenc_class_init (GstVorbisEncClass * klass)
233 {
234   GObjectClass *gobject_class;
235   GstElementClass *gstelement_class;
236
237   gobject_class = (GObjectClass *) klass;
238   gstelement_class = (GstElementClass *) klass;
239
240   gobject_class->set_property = gst_vorbisenc_set_property;
241   gobject_class->get_property = gst_vorbisenc_get_property;
242
243   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BITRATE,
244       g_param_spec_int ("max-bitrate", "Maximum Bitrate",
245           "Specify a maximum bitrate (in bps). Useful for streaming "
246           "applications. (-1 == disabled)",
247           -1, HIGHEST_BITRATE, MAX_BITRATE_DEFAULT, G_PARAM_READWRITE));
248   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
249       g_param_spec_int ("bitrate", "Target Bitrate",
250           "Attempt to encode at a bitrate averaging this (in bps). "
251           "This uses the bitrate management engine, and is not recommended for most users. "
252           "Quality is a better alternative. (-1 == disabled)",
253           -1, HIGHEST_BITRATE, BITRATE_DEFAULT, G_PARAM_READWRITE));
254   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MIN_BITRATE,
255       g_param_spec_int ("min_bitrate", "Minimum Bitrate",
256           "Specify a minimum bitrate (in bps). Useful for encoding for a "
257           "fixed-size channel. (-1 == disabled)",
258           -1, HIGHEST_BITRATE, MIN_BITRATE_DEFAULT, G_PARAM_READWRITE));
259   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
260       g_param_spec_float ("quality", "Quality",
261           "Specify quality instead of specifying a particular bitrate.",
262           -0.1, 1.0, QUALITY_DEFAULT, G_PARAM_READWRITE));
263   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MANAGED,
264       g_param_spec_boolean ("managed", "Managed",
265           "Enable bitrate management engine", FALSE, G_PARAM_READWRITE));
266   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
267       g_param_spec_string ("last-message", "last-message",
268           "The last status message", NULL, G_PARAM_READABLE));
269
270   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
271
272   gstelement_class->change_state = gst_vorbisenc_change_state;
273 }
274
275 static gboolean
276 gst_vorbisenc_sink_setcaps (GstPad * pad, GstCaps * caps)
277 {
278   GstVorbisEnc *vorbisenc;
279   GstStructure *structure;
280
281   vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
282   vorbisenc->setup = FALSE;
283
284   structure = gst_caps_get_structure (caps, 0);
285   gst_structure_get_int (structure, "channels", &vorbisenc->channels);
286   gst_structure_get_int (structure, "rate", &vorbisenc->frequency);
287
288   gst_vorbisenc_setup (vorbisenc);
289
290   if (vorbisenc->setup)
291     return TRUE;
292
293   return FALSE;
294 }
295
296 static gboolean
297 gst_vorbisenc_convert_src (GstPad * pad, GstFormat src_format, gint64 src_value,
298     GstFormat * dest_format, gint64 * dest_value)
299 {
300   gboolean res = TRUE;
301   GstVorbisEnc *vorbisenc;
302   gint64 avg;
303
304   vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
305
306   if (vorbisenc->samples_in == 0 ||
307       vorbisenc->bytes_out == 0 || vorbisenc->frequency == 0)
308     return FALSE;
309
310   avg = (vorbisenc->bytes_out * vorbisenc->frequency) / (vorbisenc->samples_in);
311
312   switch (src_format) {
313     case GST_FORMAT_BYTES:
314       switch (*dest_format) {
315         case GST_FORMAT_TIME:
316           *dest_value = src_value * GST_SECOND / avg;
317           break;
318         default:
319           res = FALSE;
320       }
321       break;
322     case GST_FORMAT_TIME:
323       switch (*dest_format) {
324         case GST_FORMAT_BYTES:
325           *dest_value = src_value * avg / GST_SECOND;
326           break;
327         default:
328           res = FALSE;
329       }
330       break;
331     default:
332       res = FALSE;
333   }
334   return res;
335 }
336
337 static gboolean
338 gst_vorbisenc_convert_sink (GstPad * pad, GstFormat src_format,
339     gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
340 {
341   gboolean res = TRUE;
342   guint scale = 1;
343   gint bytes_per_sample;
344   GstVorbisEnc *vorbisenc;
345
346   vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
347
348   bytes_per_sample = vorbisenc->channels * 2;
349
350   switch (src_format) {
351     case GST_FORMAT_BYTES:
352       switch (*dest_format) {
353         case GST_FORMAT_DEFAULT:
354           if (bytes_per_sample == 0)
355             return FALSE;
356           *dest_value = src_value / bytes_per_sample;
357           break;
358         case GST_FORMAT_TIME:
359         {
360           gint byterate = bytes_per_sample * vorbisenc->frequency;
361
362           if (byterate == 0)
363             return FALSE;
364           *dest_value = src_value * GST_SECOND / byterate;
365           break;
366         }
367         default:
368           res = FALSE;
369       }
370       break;
371     case GST_FORMAT_DEFAULT:
372       switch (*dest_format) {
373         case GST_FORMAT_BYTES:
374           *dest_value = src_value * bytes_per_sample;
375           break;
376         case GST_FORMAT_TIME:
377           if (vorbisenc->frequency == 0)
378             return FALSE;
379           *dest_value = src_value * GST_SECOND / vorbisenc->frequency;
380           break;
381         default:
382           res = FALSE;
383       }
384       break;
385     case GST_FORMAT_TIME:
386       switch (*dest_format) {
387         case GST_FORMAT_BYTES:
388           scale = bytes_per_sample;
389           /* fallthrough */
390         case GST_FORMAT_DEFAULT:
391           *dest_value = src_value * scale * vorbisenc->frequency / GST_SECOND;
392           break;
393         default:
394           res = FALSE;
395       }
396       break;
397     default:
398       res = FALSE;
399   }
400   return res;
401 }
402
403 static const GstQueryType *
404 gst_vorbisenc_get_query_types (GstPad * pad)
405 {
406   static const GstQueryType gst_vorbisenc_src_query_types[] = {
407     GST_QUERY_POSITION,
408     GST_QUERY_DURATION,
409     GST_QUERY_CONVERT,
410     0
411   };
412
413   return gst_vorbisenc_src_query_types;
414 }
415
416 static gboolean
417 gst_vorbisenc_src_query (GstPad * pad, GstQuery * query)
418 {
419   gboolean res = TRUE;
420   GstVorbisEnc *vorbisenc;
421   GstPad *peerpad;
422
423   vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
424   peerpad = gst_pad_get_peer (GST_PAD (vorbisenc->sinkpad));
425
426   switch (GST_QUERY_TYPE (query)) {
427     case GST_QUERY_POSITION:
428     {
429       GstFormat fmt, req_fmt;
430       gint64 pos, val;
431
432       gst_query_parse_position (query, &req_fmt, NULL);
433       if ((res = gst_pad_query_position (peerpad, &req_fmt, &val))) {
434         gst_query_set_position (query, req_fmt, val);
435         break;
436       }
437
438       fmt = GST_FORMAT_TIME;
439       if (!(res = gst_pad_query_position (peerpad, &fmt, &pos)))
440         break;
441
442       if ((res = gst_pad_query_convert (peerpad, fmt, pos, &req_fmt, &val))) {
443         gst_query_set_position (query, req_fmt, val);
444       }
445       break;
446     }
447     case GST_QUERY_DURATION:
448     {
449       GstFormat fmt, req_fmt;
450       gint64 dur, val;
451
452       gst_query_parse_duration (query, &req_fmt, NULL);
453       if ((res = gst_pad_query_duration (peerpad, &req_fmt, &val))) {
454         gst_query_set_duration (query, req_fmt, val);
455         break;
456       }
457
458       fmt = GST_FORMAT_TIME;
459       if (!(res = gst_pad_query_duration (peerpad, &fmt, &dur)))
460         break;
461
462       if ((res = gst_pad_query_convert (peerpad, fmt, dur, &req_fmt, &val))) {
463         gst_query_set_duration (query, req_fmt, val);
464       }
465       break;
466     }
467     case GST_QUERY_CONVERT:
468     {
469       GstFormat src_fmt, dest_fmt;
470       gint64 src_val, dest_val;
471
472       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
473       if (!(res =
474               gst_vorbisenc_convert_src (pad, src_fmt, src_val, &dest_fmt,
475                   &dest_val)))
476         goto error;
477       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
478       break;
479     }
480     default:
481       res = FALSE;
482       break;
483   }
484
485 error:
486   gst_object_unref (peerpad);
487   gst_object_unref (vorbisenc);
488   return res;
489 }
490
491 static gboolean
492 gst_vorbisenc_sink_query (GstPad * pad, GstQuery * query)
493 {
494   gboolean res = TRUE;
495   GstVorbisEnc *vorbisenc;
496
497   vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
498
499   switch (GST_QUERY_TYPE (query)) {
500     case GST_QUERY_CONVERT:
501     {
502       GstFormat src_fmt, dest_fmt;
503       gint64 src_val, dest_val;
504
505       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
506       if (!(res =
507               gst_vorbisenc_convert_sink (pad, src_fmt, src_val, &dest_fmt,
508                   &dest_val)))
509         goto error;
510       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
511       break;
512     }
513     default:
514       res = FALSE;
515       break;
516   }
517
518 error:
519   return res;
520 }
521
522 static void
523 gst_vorbisenc_init (GstVorbisEnc * vorbisenc)
524 {
525   vorbisenc->sinkpad =
526       gst_pad_new_from_template (gst_vorbisenc_sink_template, "sink");
527   gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->sinkpad);
528   gst_pad_set_event_function (vorbisenc->sinkpad, gst_vorbisenc_sink_event);
529   gst_pad_set_chain_function (vorbisenc->sinkpad, gst_vorbisenc_chain);
530   gst_pad_set_setcaps_function (vorbisenc->sinkpad, gst_vorbisenc_sink_setcaps);
531   gst_pad_set_query_function (vorbisenc->sinkpad,
532       GST_DEBUG_FUNCPTR (gst_vorbisenc_sink_query));
533
534   vorbisenc->srcpad =
535       gst_pad_new_from_template (gst_vorbisenc_src_template, "src");
536   gst_pad_set_query_function (vorbisenc->srcpad,
537       GST_DEBUG_FUNCPTR (gst_vorbisenc_src_query));
538   gst_pad_set_query_type_function (vorbisenc->srcpad,
539       GST_DEBUG_FUNCPTR (gst_vorbisenc_get_query_types));
540   gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->srcpad);
541
542   vorbisenc->channels = -1;
543   vorbisenc->frequency = -1;
544
545   vorbisenc->managed = FALSE;
546   vorbisenc->max_bitrate = MAX_BITRATE_DEFAULT;
547   vorbisenc->bitrate = BITRATE_DEFAULT;
548   vorbisenc->min_bitrate = MIN_BITRATE_DEFAULT;
549   vorbisenc->quality = QUALITY_DEFAULT;
550   vorbisenc->quality_set = FALSE;
551   vorbisenc->last_message = NULL;
552
553 }
554
555
556 static gchar *
557 gst_vorbisenc_get_tag_value (const GstTagList * list, const gchar * tag,
558     int index)
559 {
560   GType tag_type;
561   gchar *vorbisvalue = NULL;
562
563   if (tag == NULL)
564     return NULL;
565
566   tag_type = gst_tag_get_type (tag);
567
568   /* get tag name right */
569   if ((strcmp (tag, GST_TAG_TRACK_NUMBER) == 0)
570       || (strcmp (tag, GST_TAG_ALBUM_VOLUME_NUMBER) == 0)
571       || (strcmp (tag, GST_TAG_TRACK_COUNT) == 0)
572       || (strcmp (tag, GST_TAG_ALBUM_VOLUME_COUNT) == 0)) {
573     guint track_no;
574
575     if (!gst_tag_list_get_uint_index (list, tag, index, &track_no))
576       g_return_val_if_reached (NULL);
577
578     vorbisvalue = g_strdup_printf ("%u", track_no);
579   } else if (tag_type == GST_TYPE_DATE) {
580     GDate *date;
581
582     if (!gst_tag_list_get_date_index (list, tag, index, &date))
583       g_return_val_if_reached (NULL);
584
585     vorbisvalue =
586         g_strdup_printf ("%04d-%02d-%02d", (gint) g_date_get_year (date),
587         (gint) g_date_get_month (date), (gint) g_date_get_day (date));
588     g_date_free (date);
589   } else if (tag_type == G_TYPE_STRING) {
590     if (!gst_tag_list_get_string_index (list, tag, index, &vorbisvalue))
591       g_return_val_if_reached (NULL);
592   }
593
594   return vorbisvalue;
595 }
596
597 static void
598 gst_vorbisenc_metadata_set1 (const GstTagList * list, const gchar * tag,
599     gpointer vorbisenc)
600 {
601   const gchar *vorbistag = NULL;
602   gchar *vorbisvalue = NULL;
603   guint i, count;
604   GstVorbisEnc *enc = GST_VORBISENC (vorbisenc);
605
606   vorbistag = gst_tag_to_vorbis_tag (tag);
607   if (vorbistag == NULL) {
608     return;
609   }
610
611   count = gst_tag_list_get_tag_size (list, tag);
612   for (i = 0; i < count; i++) {
613     vorbisvalue = gst_vorbisenc_get_tag_value (list, tag, i);
614
615     if (vorbisvalue != NULL) {
616       vorbis_comment_add_tag (&enc->vc, g_strdup (vorbistag), vorbisvalue);
617     }
618   }
619 }
620
621 static void
622 gst_vorbisenc_set_metadata (GstVorbisEnc * vorbisenc)
623 {
624   GstTagList *copy;
625   const GstTagList *user_tags;
626
627   user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (vorbisenc));
628   if (!(vorbisenc->tags || user_tags))
629     return;
630
631   copy =
632       gst_tag_list_merge (user_tags, vorbisenc->tags,
633       gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (vorbisenc)));
634   vorbis_comment_init (&vorbisenc->vc);
635   gst_tag_list_foreach (copy, gst_vorbisenc_metadata_set1, vorbisenc);
636   gst_tag_list_free (copy);
637 }
638
639 static gchar *
640 get_constraints_string (GstVorbisEnc * vorbisenc)
641 {
642   gint min = vorbisenc->min_bitrate;
643   gint max = vorbisenc->max_bitrate;
644   gchar *result;
645
646   if (min > 0 && max > 0)
647     result = g_strdup_printf ("(min %d bps, max %d bps)", min, max);
648   else if (min > 0)
649     result = g_strdup_printf ("(min %d bps, no max)", min);
650   else if (max > 0)
651     result = g_strdup_printf ("(no min, max %d bps)", max);
652   else
653     result = g_strdup_printf ("(no min or max)");
654
655   return result;
656 }
657
658 static void
659 update_start_message (GstVorbisEnc * vorbisenc)
660 {
661   gchar *constraints;
662
663   g_free (vorbisenc->last_message);
664
665   if (vorbisenc->bitrate > 0) {
666     if (vorbisenc->managed) {
667       constraints = get_constraints_string (vorbisenc);
668       vorbisenc->last_message =
669           g_strdup_printf ("encoding at average bitrate %d bps %s",
670           vorbisenc->bitrate, constraints);
671       g_free (constraints);
672     } else {
673       vorbisenc->last_message =
674           g_strdup_printf
675           ("encoding at approximate bitrate %d bps (VBR encoding enabled)",
676           vorbisenc->bitrate);
677     }
678   } else {
679     if (vorbisenc->quality_set) {
680       if (vorbisenc->managed) {
681         constraints = get_constraints_string (vorbisenc);
682         vorbisenc->last_message =
683             g_strdup_printf
684             ("encoding at quality level %2.2f using constrained VBR %s",
685             vorbisenc->quality, constraints);
686         g_free (constraints);
687       } else {
688         vorbisenc->last_message =
689             g_strdup_printf ("encoding at quality level %2.2f",
690             vorbisenc->quality);
691       }
692     } else {
693       constraints = get_constraints_string (vorbisenc);
694       vorbisenc->last_message =
695           g_strdup_printf ("encoding using bitrate management %s", constraints);
696       g_free (constraints);
697     }
698   }
699
700   g_object_notify (G_OBJECT (vorbisenc), "last_message");
701 }
702
703 static gboolean
704 gst_vorbisenc_setup (GstVorbisEnc * vorbisenc)
705 {
706   vorbisenc->setup = FALSE;
707
708   if (vorbisenc->bitrate < 0 && vorbisenc->min_bitrate < 0
709       && vorbisenc->max_bitrate < 0) {
710     vorbisenc->quality_set = TRUE;
711   }
712
713   update_start_message (vorbisenc);
714
715   /* choose an encoding mode */
716   /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
717   vorbis_info_init (&vorbisenc->vi);
718
719   if (vorbisenc->quality_set) {
720     if (vorbis_encode_setup_vbr (&vorbisenc->vi,
721             vorbisenc->channels, vorbisenc->frequency,
722             vorbisenc->quality) != 0) {
723       GST_ERROR_OBJECT (vorbisenc,
724           "vorbisenc: initialisation failed: invalid parameters for quality");
725       vorbis_info_clear (&vorbisenc->vi);
726       return FALSE;
727     }
728
729     /* do we have optional hard quality restrictions? */
730     if (vorbisenc->max_bitrate > 0 || vorbisenc->min_bitrate > 0) {
731       struct ovectl_ratemanage_arg ai;
732
733       vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_GET, &ai);
734
735       ai.bitrate_hard_min = vorbisenc->min_bitrate;
736       ai.bitrate_hard_max = vorbisenc->max_bitrate;
737       ai.management_active = 1;
738
739       vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, &ai);
740     }
741   } else {
742     long min_bitrate, max_bitrate;
743
744     min_bitrate = vorbisenc->min_bitrate > 0 ? vorbisenc->min_bitrate : -1;
745     max_bitrate = vorbisenc->max_bitrate > 0 ? vorbisenc->max_bitrate : -1;
746
747     if (vorbis_encode_setup_managed (&vorbisenc->vi,
748             vorbisenc->channels,
749             vorbisenc->frequency,
750             max_bitrate, vorbisenc->bitrate, min_bitrate) != 0) {
751       GST_ERROR_OBJECT (vorbisenc,
752           "vorbis_encode_setup_managed "
753           "(c %d, rate %d, max br %ld, br %ld, min br %ld) failed",
754           vorbisenc->channels, vorbisenc->frequency, max_bitrate,
755           vorbisenc->bitrate, min_bitrate);
756       vorbis_info_clear (&vorbisenc->vi);
757       return FALSE;
758     }
759   }
760
761   if (vorbisenc->managed && vorbisenc->bitrate < 0) {
762     vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_AVG, NULL);
763   } else if (!vorbisenc->managed) {
764     /* Turn off management entirely (if it was turned on). */
765     vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, NULL);
766   }
767   vorbis_encode_setup_init (&vorbisenc->vi);
768
769   /* set up the analysis state and auxiliary encoding storage */
770   vorbis_analysis_init (&vorbisenc->vd, &vorbisenc->vi);
771   vorbis_block_init (&vorbisenc->vd, &vorbisenc->vb);
772
773   vorbisenc->prev_ts = 0;
774
775   vorbisenc->setup = TRUE;
776
777   return TRUE;
778 }
779
780 static GstFlowReturn
781 gst_vorbisenc_clear (GstVorbisEnc * vorbisenc)
782 {
783   GstFlowReturn ret = GST_FLOW_OK;
784
785   if (vorbisenc->setup) {
786     vorbis_analysis_wrote (&vorbisenc->vd, 0);
787     ret = gst_vorbisenc_output_buffers (vorbisenc);
788
789     vorbisenc->setup = FALSE;
790   }
791
792   /* clean up and exit.  vorbis_info_clear() must be called last */
793   vorbis_block_clear (&vorbisenc->vb);
794   vorbis_dsp_clear (&vorbisenc->vd);
795   vorbis_info_clear (&vorbisenc->vi);
796
797   vorbisenc->header_sent = FALSE;
798
799   return ret;
800 }
801
802 /* prepare a buffer for transmission by passing data through libvorbis */
803 static GstBuffer *
804 gst_vorbisenc_buffer_from_packet (GstVorbisEnc * vorbisenc, ogg_packet * packet)
805 {
806   GstBuffer *outbuf;
807
808   outbuf = gst_buffer_new_and_alloc (packet->bytes);
809   memcpy (GST_BUFFER_DATA (outbuf), packet->packet, packet->bytes);
810   GST_BUFFER_OFFSET (outbuf) = vorbisenc->bytes_out;
811   GST_BUFFER_OFFSET_END (outbuf) = packet->granulepos;
812   GST_BUFFER_TIMESTAMP (outbuf) =
813       vorbis_granule_time_copy (&vorbisenc->vd,
814       packet->granulepos) * GST_SECOND;
815   GST_BUFFER_DURATION (outbuf) =
816       GST_BUFFER_TIMESTAMP (outbuf) - vorbisenc->prev_ts;
817   vorbisenc->prev_ts = GST_BUFFER_TIMESTAMP (outbuf);
818
819   GST_DEBUG ("encoded buffer of %d bytes", GST_BUFFER_SIZE (outbuf));
820   return outbuf;
821 }
822
823 /* push out the buffer and do internal bookkeeping */
824 static GstFlowReturn
825 gst_vorbisenc_push_buffer (GstVorbisEnc * vorbisenc, GstBuffer * buffer)
826 {
827   vorbisenc->bytes_out += GST_BUFFER_SIZE (buffer);
828
829   return gst_pad_push (vorbisenc->srcpad, buffer);
830 }
831
832 static GstFlowReturn
833 gst_vorbisenc_push_packet (GstVorbisEnc * vorbisenc, ogg_packet * packet)
834 {
835   GstBuffer *outbuf;
836
837   outbuf = gst_vorbisenc_buffer_from_packet (vorbisenc, packet);
838   return gst_vorbisenc_push_buffer (vorbisenc, outbuf);
839 }
840
841 static GstCaps *
842 gst_vorbisenc_set_header_on_caps (GstCaps * caps, GstBuffer * buf1,
843     GstBuffer * buf2, GstBuffer * buf3)
844 {
845   GstStructure *structure;
846   GValue array = { 0 };
847   GValue value = { 0 };
848
849   caps = gst_caps_make_writable (caps);
850   structure = gst_caps_get_structure (caps, 0);
851
852   /* mark buffers */
853   GST_BUFFER_FLAG_SET (buf1, GST_BUFFER_FLAG_IN_CAPS);
854   GST_BUFFER_FLAG_SET (buf2, GST_BUFFER_FLAG_IN_CAPS);
855   GST_BUFFER_FLAG_SET (buf3, GST_BUFFER_FLAG_IN_CAPS);
856
857   /* put buffers in a fixed list */
858   g_value_init (&array, GST_TYPE_ARRAY);
859   g_value_init (&value, GST_TYPE_BUFFER);
860   gst_value_set_buffer (&value, buf1);
861   gst_value_array_append_value (&array, &value);
862   g_value_unset (&value);
863   g_value_init (&value, GST_TYPE_BUFFER);
864   gst_value_set_buffer (&value, buf2);
865   gst_value_array_append_value (&array, &value);
866   g_value_unset (&value);
867   g_value_init (&value, GST_TYPE_BUFFER);
868   gst_value_set_buffer (&value, buf3);
869   gst_value_array_append_value (&array, &value);
870   gst_structure_set_value (structure, "streamheader", &array);
871   g_value_unset (&value);
872   g_value_unset (&array);
873
874   return caps;
875 }
876
877 static gboolean
878 gst_vorbisenc_sink_event (GstPad * pad, GstEvent * event)
879 {
880   gboolean res = TRUE;
881   GstVorbisEnc *vorbisenc;
882
883   vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
884
885   switch (GST_EVENT_TYPE (event)) {
886     case GST_EVENT_EOS:
887       /* Tell the library we're at end of stream so that it can handle
888        * the last frame and mark end of stream in the output properly */
889       GST_DEBUG_OBJECT (vorbisenc, "EOS, clearing state and sending event on");
890       gst_vorbisenc_clear (vorbisenc);
891
892       res = gst_pad_push_event (vorbisenc->srcpad, event);
893       break;
894     case GST_EVENT_TAG:
895       if (vorbisenc->tags) {
896         GstTagList *list;
897
898         gst_event_parse_tag (event, &list);
899         gst_tag_list_insert (vorbisenc->tags, list,
900             gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (vorbisenc)));
901       } else {
902         g_assert_not_reached ();
903       }
904       res = gst_pad_push_event (vorbisenc->srcpad, event);
905       break;
906     default:
907       res = gst_pad_push_event (vorbisenc->srcpad, event);
908       break;
909   }
910   return res;
911 }
912
913 static GstFlowReturn
914 gst_vorbisenc_chain (GstPad * pad, GstBuffer * buffer)
915 {
916   GstBuffer *buf = GST_BUFFER (buffer);
917   GstVorbisEnc *vorbisenc;
918   GstFlowReturn ret = GST_FLOW_OK;
919
920   vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
921
922   {
923     gfloat *data;
924     gulong size;
925     gulong i, j;
926     float **buffer;
927
928     if (!vorbisenc->setup) {
929       gst_buffer_unref (buf);
930       GST_ELEMENT_ERROR (vorbisenc, CORE, NEGOTIATION, (NULL),
931           ("encoder not initialized (input is not audio?)"));
932       return GST_FLOW_UNEXPECTED;
933     }
934
935     if (!vorbisenc->header_sent) {
936       /* Vorbis streams begin with three headers; the initial header (with
937          most of the codec setup parameters) which is mandated by the Ogg
938          bitstream spec.  The second header holds any comment fields.  The
939          third header holds the bitstream codebook.  We merely need to
940          make the headers, then pass them to libvorbis one at a time;
941          libvorbis handles the additional Ogg bitstream constraints */
942       ogg_packet header;
943       ogg_packet header_comm;
944       ogg_packet header_code;
945       GstBuffer *buf1, *buf2, *buf3;
946       GstCaps *caps;
947
948       GST_DEBUG_OBJECT (vorbisenc, "creating and sending header packets");
949       gst_vorbisenc_set_metadata (vorbisenc);
950       vorbis_analysis_headerout (&vorbisenc->vd, &vorbisenc->vc, &header,
951           &header_comm, &header_code);
952
953       /* create header buffers */
954       buf1 = gst_vorbisenc_buffer_from_packet (vorbisenc, &header);
955       buf2 = gst_vorbisenc_buffer_from_packet (vorbisenc, &header_comm);
956       buf3 = gst_vorbisenc_buffer_from_packet (vorbisenc, &header_code);
957
958       /* mark and put on caps */
959       caps = gst_pad_get_caps (vorbisenc->srcpad);
960       caps = gst_vorbisenc_set_header_on_caps (caps, buf1, buf2, buf3);
961
962       /* negotiate with these caps */
963       GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
964       gst_pad_set_caps (vorbisenc->srcpad, caps);
965
966       gst_buffer_set_caps (buf1, caps);
967       gst_buffer_set_caps (buf2, caps);
968       gst_buffer_set_caps (buf3, caps);
969
970       /* push out buffers */
971       if ((ret = gst_vorbisenc_push_buffer (vorbisenc, buf1)) != GST_FLOW_OK)
972         goto done;
973       if ((ret = gst_vorbisenc_push_buffer (vorbisenc, buf2)) != GST_FLOW_OK)
974         goto done;
975       if ((ret = gst_vorbisenc_push_buffer (vorbisenc, buf3)) != GST_FLOW_OK)
976         goto done;
977
978       vorbisenc->header_sent = TRUE;
979     }
980
981     /* data to encode */
982     data = (gfloat *) GST_BUFFER_DATA (buf);
983     size = GST_BUFFER_SIZE (buf) / (vorbisenc->channels * sizeof (float));
984
985     /* expose the buffer to submit data */
986     buffer = vorbis_analysis_buffer (&vorbisenc->vd, size);
987
988     /* uninterleave samples */
989     for (i = 0; i < size; i++) {
990       for (j = 0; j < vorbisenc->channels; j++) {
991         buffer[j][i] = *data++;
992       }
993     }
994
995     /* tell the library how much we actually submitted */
996     vorbis_analysis_wrote (&vorbisenc->vd, size);
997
998     vorbisenc->samples_in += size;
999
1000     gst_buffer_unref (buf);
1001   }
1002
1003   ret = gst_vorbisenc_output_buffers (vorbisenc);
1004
1005 done:
1006   return ret;
1007 }
1008
1009 static GstFlowReturn
1010 gst_vorbisenc_output_buffers (GstVorbisEnc * vorbisenc)
1011 {
1012   GstFlowReturn ret;
1013
1014   /* vorbis does some data preanalysis, then divides up blocks for
1015      more involved (potentially parallel) processing.  Get a single
1016      block for encoding now */
1017   while (vorbis_analysis_blockout (&vorbisenc->vd, &vorbisenc->vb) == 1) {
1018     ogg_packet op;
1019
1020     GST_LOG_OBJECT (vorbisenc, "analysed to a block");
1021
1022     /* analysis */
1023     vorbis_analysis (&vorbisenc->vb, NULL);
1024     vorbis_bitrate_addblock (&vorbisenc->vb);
1025
1026     while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &op)) {
1027       GST_LOG_OBJECT (vorbisenc, "pushing out a data packet");
1028       ret = gst_vorbisenc_push_packet (vorbisenc, &op);
1029
1030       if (ret != GST_FLOW_OK)
1031         return ret;
1032     }
1033   }
1034
1035   return GST_FLOW_OK;
1036 }
1037
1038 static void
1039 gst_vorbisenc_get_property (GObject * object, guint prop_id, GValue * value,
1040     GParamSpec * pspec)
1041 {
1042   GstVorbisEnc *vorbisenc;
1043
1044   g_return_if_fail (GST_IS_VORBISENC (object));
1045
1046   vorbisenc = GST_VORBISENC (object);
1047
1048   switch (prop_id) {
1049     case ARG_MAX_BITRATE:
1050       g_value_set_int (value, vorbisenc->max_bitrate);
1051       break;
1052     case ARG_BITRATE:
1053       g_value_set_int (value, vorbisenc->bitrate);
1054       break;
1055     case ARG_MIN_BITRATE:
1056       g_value_set_int (value, vorbisenc->min_bitrate);
1057       break;
1058     case ARG_QUALITY:
1059       g_value_set_float (value, vorbisenc->quality);
1060       break;
1061     case ARG_MANAGED:
1062       g_value_set_boolean (value, vorbisenc->managed);
1063       break;
1064     case ARG_LAST_MESSAGE:
1065       g_value_set_string (value, vorbisenc->last_message);
1066       break;
1067     default:
1068       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1069       break;
1070   }
1071 }
1072
1073 static void
1074 gst_vorbisenc_set_property (GObject * object, guint prop_id,
1075     const GValue * value, GParamSpec * pspec)
1076 {
1077   GstVorbisEnc *vorbisenc;
1078
1079   g_return_if_fail (GST_IS_VORBISENC (object));
1080
1081   vorbisenc = GST_VORBISENC (object);
1082
1083   switch (prop_id) {
1084     case ARG_MAX_BITRATE:
1085     {
1086       gboolean old_value = vorbisenc->managed;
1087
1088       vorbisenc->max_bitrate = g_value_get_int (value);
1089       if (vorbisenc->max_bitrate >= 0
1090           && vorbisenc->max_bitrate < LOWEST_BITRATE) {
1091         g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1092         vorbisenc->max_bitrate = LOWEST_BITRATE;
1093       }
1094       if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
1095         vorbisenc->managed = TRUE;
1096       else
1097         vorbisenc->managed = FALSE;
1098
1099       if (old_value != vorbisenc->managed)
1100         g_object_notify (object, "managed");
1101       break;
1102     }
1103     case ARG_BITRATE:
1104       vorbisenc->bitrate = g_value_get_int (value);
1105       if (vorbisenc->bitrate >= 0 && vorbisenc->bitrate < LOWEST_BITRATE) {
1106         g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1107         vorbisenc->bitrate = LOWEST_BITRATE;
1108       }
1109       break;
1110     case ARG_MIN_BITRATE:
1111     {
1112       gboolean old_value = vorbisenc->managed;
1113
1114       vorbisenc->min_bitrate = g_value_get_int (value);
1115       if (vorbisenc->min_bitrate >= 0
1116           && vorbisenc->min_bitrate < LOWEST_BITRATE) {
1117         g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1118         vorbisenc->min_bitrate = LOWEST_BITRATE;
1119       }
1120       if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
1121         vorbisenc->managed = TRUE;
1122       else
1123         vorbisenc->managed = FALSE;
1124
1125       if (old_value != vorbisenc->managed)
1126         g_object_notify (object, "managed");
1127       break;
1128     }
1129     case ARG_QUALITY:
1130       vorbisenc->quality = g_value_get_float (value);
1131       if (vorbisenc->quality >= 0.0)
1132         vorbisenc->quality_set = TRUE;
1133       else
1134         vorbisenc->quality_set = FALSE;
1135       break;
1136     case ARG_MANAGED:
1137       vorbisenc->managed = g_value_get_boolean (value);
1138       break;
1139     default:
1140       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1141       break;
1142   }
1143 }
1144
1145 static GstStateChangeReturn
1146 gst_vorbisenc_change_state (GstElement * element, GstStateChange transition)
1147 {
1148   GstVorbisEnc *vorbisenc = GST_VORBISENC (element);
1149   GstStateChangeReturn res;
1150
1151
1152   switch (transition) {
1153     case GST_STATE_CHANGE_NULL_TO_READY:
1154       vorbisenc->tags = gst_tag_list_new ();
1155       break;
1156     case GST_STATE_CHANGE_READY_TO_PAUSED:
1157       vorbisenc->setup = FALSE;
1158       vorbisenc->header_sent = FALSE;
1159       break;
1160     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1161       break;
1162     default:
1163       break;
1164   }
1165
1166   res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1167
1168   switch (transition) {
1169     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1170       break;
1171     case GST_STATE_CHANGE_PAUSED_TO_READY:
1172       vorbis_block_clear (&vorbisenc->vb);
1173       vorbis_dsp_clear (&vorbisenc->vd);
1174       vorbis_info_clear (&vorbisenc->vi);
1175       g_free (vorbisenc->last_message);
1176       vorbisenc->last_message = NULL;
1177       break;
1178     case GST_STATE_CHANGE_READY_TO_NULL:
1179       gst_tag_list_free (vorbisenc->tags);
1180       vorbisenc->tags = NULL;
1181     default:
1182       break;
1183   }
1184
1185   return res;
1186 }