ext/vorbis/vorbisenc.*: Fix EOS handling. Still needs a fix in the ogg muxer to...
[platform/upstream/gst-plugins-base.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 sinesrc num-buffers=100 ! audioconvert ! vorbisenc ! oggmux ! filesink location=sinesrc.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 void 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,
209       "width", G_TYPE_INT, 32, "buffer-frames", G_TYPE_INT, 0, NULL);
210 }
211
212 static void
213 gst_vorbisenc_base_init (gpointer g_class)
214 {
215   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
216   GstCaps *raw_caps, *vorbis_caps;
217
218   raw_caps = raw_caps_factory ();
219   vorbis_caps = vorbis_caps_factory ();
220
221   gst_vorbisenc_sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
222       GST_PAD_ALWAYS, raw_caps);
223   gst_vorbisenc_src_template = gst_pad_template_new ("src", GST_PAD_SRC,
224       GST_PAD_ALWAYS, vorbis_caps);
225   gst_element_class_add_pad_template (element_class,
226       gst_vorbisenc_sink_template);
227   gst_element_class_add_pad_template (element_class,
228       gst_vorbisenc_src_template);
229   gst_element_class_set_details (element_class, &vorbisenc_details);
230 }
231
232 static void
233 gst_vorbisenc_class_init (GstVorbisEncClass * klass)
234 {
235   GObjectClass *gobject_class;
236   GstElementClass *gstelement_class;
237
238   gobject_class = (GObjectClass *) klass;
239   gstelement_class = (GstElementClass *) klass;
240
241   gobject_class->set_property = gst_vorbisenc_set_property;
242   gobject_class->get_property = gst_vorbisenc_get_property;
243
244   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BITRATE,
245       g_param_spec_int ("max-bitrate", "Maximum Bitrate",
246           "Specify a maximum bitrate (in bps). Useful for streaming "
247           "applications. (-1 == disabled)",
248           -1, HIGHEST_BITRATE, MAX_BITRATE_DEFAULT, G_PARAM_READWRITE));
249   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
250       g_param_spec_int ("bitrate", "Target Bitrate",
251           "Attempt to encode at a bitrate averaging this (in bps). "
252           "This uses the bitrate management engine, and is not recommended for most users. "
253           "Quality is a better alternative. (-1 == disabled)",
254           -1, HIGHEST_BITRATE, BITRATE_DEFAULT, G_PARAM_READWRITE));
255   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MIN_BITRATE,
256       g_param_spec_int ("min_bitrate", "Minimum Bitrate",
257           "Specify a minimum bitrate (in bps). Useful for encoding for a "
258           "fixed-size channel. (-1 == disabled)",
259           -1, HIGHEST_BITRATE, MIN_BITRATE_DEFAULT, G_PARAM_READWRITE));
260   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
261       g_param_spec_float ("quality", "Quality",
262           "Specify quality instead of specifying a particular bitrate.",
263           -0.1, 1.0, QUALITY_DEFAULT, G_PARAM_READWRITE));
264   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MANAGED,
265       g_param_spec_boolean ("managed", "Managed",
266           "Enable bitrate management engine", FALSE, G_PARAM_READWRITE));
267   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
268       g_param_spec_string ("last-message", "last-message",
269           "The last status message", NULL, G_PARAM_READABLE));
270
271   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
272
273   gstelement_class->change_state = gst_vorbisenc_change_state;
274 }
275
276 static gboolean
277 gst_vorbisenc_sink_setcaps (GstPad * pad, GstCaps * caps)
278 {
279   GstVorbisEnc *vorbisenc;
280   GstStructure *structure;
281
282   vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
283   vorbisenc->setup = FALSE;
284
285   structure = gst_caps_get_structure (caps, 0);
286   gst_structure_get_int (structure, "channels", &vorbisenc->channels);
287   gst_structure_get_int (structure, "rate", &vorbisenc->frequency);
288
289   gst_vorbisenc_setup (vorbisenc);
290
291   if (vorbisenc->setup)
292     return TRUE;
293
294   return FALSE;
295 }
296
297 static gboolean
298 gst_vorbisenc_convert_src (GstPad * pad, GstFormat src_format, gint64 src_value,
299     GstFormat * dest_format, gint64 * dest_value)
300 {
301   gboolean res = TRUE;
302   GstVorbisEnc *vorbisenc;
303   gint64 avg;
304
305   vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
306
307   if (vorbisenc->samples_in == 0 ||
308       vorbisenc->bytes_out == 0 || vorbisenc->frequency == 0)
309     return FALSE;
310
311   avg = (vorbisenc->bytes_out * vorbisenc->frequency) / (vorbisenc->samples_in);
312
313   switch (src_format) {
314     case GST_FORMAT_BYTES:
315       switch (*dest_format) {
316         case GST_FORMAT_TIME:
317           *dest_value = src_value * GST_SECOND / avg;
318           break;
319         default:
320           res = FALSE;
321       }
322       break;
323     case GST_FORMAT_TIME:
324       switch (*dest_format) {
325         case GST_FORMAT_BYTES:
326           *dest_value = src_value * avg / GST_SECOND;
327           break;
328         default:
329           res = FALSE;
330       }
331       break;
332     default:
333       res = FALSE;
334   }
335   return res;
336 }
337
338 static gboolean
339 gst_vorbisenc_convert_sink (GstPad * pad, GstFormat src_format,
340     gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
341 {
342   gboolean res = TRUE;
343   guint scale = 1;
344   gint bytes_per_sample;
345   GstVorbisEnc *vorbisenc;
346
347   vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
348
349   bytes_per_sample = vorbisenc->channels * 2;
350
351   switch (src_format) {
352     case GST_FORMAT_BYTES:
353       switch (*dest_format) {
354         case GST_FORMAT_DEFAULT:
355           if (bytes_per_sample == 0)
356             return FALSE;
357           *dest_value = src_value / bytes_per_sample;
358           break;
359         case GST_FORMAT_TIME:
360         {
361           gint byterate = bytes_per_sample * vorbisenc->frequency;
362
363           if (byterate == 0)
364             return FALSE;
365           *dest_value = src_value * GST_SECOND / byterate;
366           break;
367         }
368         default:
369           res = FALSE;
370       }
371       break;
372     case GST_FORMAT_DEFAULT:
373       switch (*dest_format) {
374         case GST_FORMAT_BYTES:
375           *dest_value = src_value * bytes_per_sample;
376           break;
377         case GST_FORMAT_TIME:
378           if (vorbisenc->frequency == 0)
379             return FALSE;
380           *dest_value = src_value * GST_SECOND / vorbisenc->frequency;
381           break;
382         default:
383           res = FALSE;
384       }
385       break;
386     case GST_FORMAT_TIME:
387       switch (*dest_format) {
388         case GST_FORMAT_BYTES:
389           scale = bytes_per_sample;
390           /* fallthrough */
391         case GST_FORMAT_DEFAULT:
392           *dest_value = src_value * scale * vorbisenc->frequency / GST_SECOND;
393           break;
394         default:
395           res = FALSE;
396       }
397       break;
398     default:
399       res = FALSE;
400   }
401   return res;
402 }
403
404 static const GstQueryType *
405 gst_vorbisenc_get_query_types (GstPad * pad)
406 {
407   static const GstQueryType gst_vorbisenc_src_query_types[] = {
408     GST_QUERY_POSITION,
409     0
410   };
411
412   return gst_vorbisenc_src_query_types;
413 }
414
415 static gboolean
416 gst_vorbisenc_src_query (GstPad * pad, GstQuery * query)
417 {
418   gboolean res = TRUE;
419   GstVorbisEnc *vorbisenc;
420
421   vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
422
423   switch (GST_QUERY_TYPE (query)) {
424     case GST_QUERY_POSITION:
425     {
426 #if 0
427       switch (*format) {
428         case GST_FORMAT_BYTES:
429         case GST_FORMAT_TIME:
430         {
431           gint64 peer_value;
432           const GstFormat *peer_formats;
433
434           res = FALSE;
435
436           peer_formats =
437               gst_pad_get_formats (GST_PAD_PEER (vorbisenc->sinkpad));
438
439           while (peer_formats && *peer_formats && !res) {
440
441             GstFormat peer_format = *peer_formats;
442
443             /* do the probe */
444             if (gst_pad_query (GST_PAD_PEER (vorbisenc->sinkpad),
445                     GST_QUERY_TOTAL, &peer_format, &peer_value)) {
446               GstFormat conv_format;
447
448               /* convert to TIME */
449               conv_format = GST_FORMAT_TIME;
450               res = gst_vorbisenc_convert_sink (vorbisenc->sinkpad,
451                   peer_format, peer_value, &conv_format, value);
452               /* and to final format */
453               res &= gst_vorbisenc_convert_src (pad,
454                   GST_FORMAT_TIME, *value, format, value);
455             }
456             peer_formats++;
457           }
458           break;
459         }
460         default:
461           res = FALSE;
462           break;
463       }
464 #endif
465       res = FALSE;
466       break;
467     }
468     case GST_QUERY_CONVERT:
469     {
470       GstFormat src_fmt, dest_fmt;
471       gint64 src_val, dest_val;
472
473       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
474       if (!(res =
475               gst_vorbisenc_convert_src (pad, src_fmt, src_val, &dest_fmt,
476                   &dest_val)))
477         goto error;
478       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
479       break;
480     }
481     default:
482       res = FALSE;
483       break;
484   }
485
486 error:
487   return res;
488 }
489
490 static gboolean
491 gst_vorbisenc_sink_query (GstPad * pad, GstQuery * query)
492 {
493   gboolean res = TRUE;
494   GstVorbisEnc *vorbisenc;
495
496   vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
497
498   switch (GST_QUERY_TYPE (query)) {
499     case GST_QUERY_CONVERT:
500     {
501       GstFormat src_fmt, dest_fmt;
502       gint64 src_val, dest_val;
503
504       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
505       if (!(res =
506               gst_vorbisenc_convert_sink (pad, src_fmt, src_val, &dest_fmt,
507                   &dest_val)))
508         goto error;
509       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
510       break;
511     }
512     default:
513       res = FALSE;
514       break;
515   }
516
517 error:
518   return res;
519 }
520
521 static void
522 gst_vorbisenc_init (GstVorbisEnc * vorbisenc)
523 {
524   vorbisenc->sinkpad =
525       gst_pad_new_from_template (gst_vorbisenc_sink_template, "sink");
526   gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->sinkpad);
527   gst_pad_set_event_function (vorbisenc->sinkpad, gst_vorbisenc_sink_event);
528   gst_pad_set_chain_function (vorbisenc->sinkpad, gst_vorbisenc_chain);
529   gst_pad_set_setcaps_function (vorbisenc->sinkpad, gst_vorbisenc_sink_setcaps);
530   gst_pad_set_query_function (vorbisenc->sinkpad,
531       GST_DEBUG_FUNCPTR (gst_vorbisenc_sink_query));
532
533   vorbisenc->srcpad =
534       gst_pad_new_from_template (gst_vorbisenc_src_template, "src");
535   gst_pad_set_query_function (vorbisenc->srcpad,
536       GST_DEBUG_FUNCPTR (gst_vorbisenc_src_query));
537   gst_pad_set_query_type_function (vorbisenc->srcpad,
538       GST_DEBUG_FUNCPTR (gst_vorbisenc_get_query_types));
539   gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->srcpad);
540
541   vorbisenc->channels = -1;
542   vorbisenc->frequency = -1;
543
544   vorbisenc->managed = FALSE;
545   vorbisenc->max_bitrate = MAX_BITRATE_DEFAULT;
546   vorbisenc->bitrate = BITRATE_DEFAULT;
547   vorbisenc->min_bitrate = MIN_BITRATE_DEFAULT;
548   vorbisenc->quality = QUALITY_DEFAULT;
549   vorbisenc->quality_set = FALSE;
550   vorbisenc->last_message = NULL;
551
552   vorbisenc->setup = FALSE;
553   vorbisenc->header_sent = FALSE;
554 }
555
556
557 static gchar *
558 gst_vorbisenc_get_tag_value (const GstTagList * list, const gchar * tag,
559     int index)
560 {
561   gchar *vorbisvalue = NULL;
562
563   if (tag == NULL) {
564     return NULL;
565   }
566
567   /* get tag name right */
568   if ((strcmp (tag, GST_TAG_TRACK_NUMBER) == 0)
569       || (strcmp (tag, GST_TAG_ALBUM_VOLUME_NUMBER) == 0)
570       || (strcmp (tag, GST_TAG_TRACK_COUNT) == 0)
571       || (strcmp (tag, GST_TAG_ALBUM_VOLUME_COUNT) == 0)) {
572     guint track_no;
573
574     if (!gst_tag_list_get_uint_index (list, tag, index, &track_no))
575       g_assert_not_reached ();
576     vorbisvalue = g_strdup_printf ("%u", track_no);
577   } else if (strcmp (tag, GST_TAG_DATE) == 0) {
578     /* FIXME: how are dates represented in vorbis files? */
579     GDate *date;
580     guint u;
581
582     if (!gst_tag_list_get_uint_index (list, tag, index, &u))
583       g_assert_not_reached ();
584     date = g_date_new_julian (u);
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 (gst_tag_get_type (tag) == G_TYPE_STRING) {
590     if (!gst_tag_list_get_string_index (list, tag, index, &vorbisvalue))
591       g_assert_not_reached ();
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_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_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       /* the bitrates used by libvorbisenc are in kbit/sec, ours in bit/sec
736        * also remember that in telecom kbit/sec is 1000 bit/sec */
737       ai.bitrate_hard_min = vorbisenc->min_bitrate / 1000;
738       ai.bitrate_hard_max = vorbisenc->max_bitrate / 1000;
739       ai.management_active = 1;
740
741       vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, &ai);
742     }
743   } else {
744     long min_bitrate, max_bitrate;
745
746     min_bitrate = vorbisenc->min_bitrate > 0 ? vorbisenc->min_bitrate : -1;
747     max_bitrate = vorbisenc->max_bitrate > 0 ? vorbisenc->max_bitrate : -1;
748
749     if (vorbis_encode_setup_managed (&vorbisenc->vi,
750             vorbisenc->channels,
751             vorbisenc->frequency,
752             max_bitrate, vorbisenc->bitrate, min_bitrate) != 0) {
753       GST_ERROR_OBJECT (vorbisenc,
754           "vorbis_encode_setup_managed "
755           "(c %d, rate %d, max br %ld, br %ld, min br %ld) failed",
756           vorbisenc->channels, vorbisenc->frequency, max_bitrate,
757           vorbisenc->bitrate, min_bitrate);
758       vorbis_info_clear (&vorbisenc->vi);
759       return FALSE;
760     }
761   }
762
763   if (vorbisenc->managed && vorbisenc->bitrate < 0) {
764     vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_AVG, NULL);
765   } else if (!vorbisenc->managed) {
766     /* Turn off management entirely (if it was turned on). */
767     vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, NULL);
768   }
769   vorbis_encode_setup_init (&vorbisenc->vi);
770
771   /* set up the analysis state and auxiliary encoding storage */
772   vorbis_analysis_init (&vorbisenc->vd, &vorbisenc->vi);
773   vorbis_block_init (&vorbisenc->vd, &vorbisenc->vb);
774
775   vorbisenc->setup = TRUE;
776
777   return TRUE;
778 }
779
780 /* prepare a buffer for transmission by passing data through libvorbis */
781 static GstBuffer *
782 gst_vorbisenc_buffer_from_packet (GstVorbisEnc * vorbisenc, ogg_packet * packet)
783 {
784   GstBuffer *outbuf;
785
786   outbuf = gst_buffer_new_and_alloc (packet->bytes);
787   memcpy (GST_BUFFER_DATA (outbuf), packet->packet, packet->bytes);
788   GST_BUFFER_OFFSET (outbuf) = vorbisenc->bytes_out;
789   GST_BUFFER_OFFSET_END (outbuf) = packet->granulepos;
790   GST_BUFFER_TIMESTAMP (outbuf) =
791       vorbis_granule_time_copy (&vorbisenc->vd,
792       packet->granulepos) * GST_SECOND;
793
794   GST_DEBUG ("encoded buffer of %d bytes", GST_BUFFER_SIZE (outbuf));
795   return outbuf;
796 }
797
798 /* push out the buffer and do internal bookkeeping */
799 static void
800 gst_vorbisenc_push_buffer (GstVorbisEnc * vorbisenc, GstBuffer * buffer)
801 {
802   vorbisenc->bytes_out += GST_BUFFER_SIZE (buffer);
803
804   if (GST_PAD_IS_USABLE (vorbisenc->srcpad)) {
805     gst_pad_push (vorbisenc->srcpad, buffer);
806   } else {
807     gst_buffer_unref (buffer);
808   }
809 }
810
811 static void
812 gst_vorbisenc_push_packet (GstVorbisEnc * vorbisenc, ogg_packet * packet)
813 {
814   GstBuffer *outbuf;
815
816   outbuf = gst_vorbisenc_buffer_from_packet (vorbisenc, packet);
817   gst_vorbisenc_push_buffer (vorbisenc, outbuf);
818 }
819
820 static GstCaps *
821 gst_vorbisenc_set_header_on_caps (GstCaps * caps, GstBuffer * buf1,
822     GstBuffer * buf2, GstBuffer * buf3)
823 {
824   GstStructure *structure;
825   GValue list = { 0 };
826   GValue value = { 0 };
827
828   caps = gst_caps_make_writable (caps);
829   structure = gst_caps_get_structure (caps, 0);
830
831   /* mark buffers */
832   GST_BUFFER_FLAG_SET (buf1, GST_BUFFER_FLAG_IN_CAPS);
833   GST_BUFFER_FLAG_SET (buf2, GST_BUFFER_FLAG_IN_CAPS);
834   GST_BUFFER_FLAG_SET (buf3, GST_BUFFER_FLAG_IN_CAPS);
835
836   /* put buffers in a fixed list */
837   g_value_init (&list, GST_TYPE_ARRAY);
838   g_value_init (&value, GST_TYPE_BUFFER);
839   gst_value_set_buffer (&value, buf1);
840   gst_value_list_append_value (&list, &value);
841   g_value_unset (&value);
842   g_value_init (&value, GST_TYPE_BUFFER);
843   gst_value_set_buffer (&value, buf2);
844   gst_value_list_append_value (&list, &value);
845   g_value_unset (&value);
846   g_value_init (&value, GST_TYPE_BUFFER);
847   gst_value_set_buffer (&value, buf3);
848   gst_value_list_append_value (&list, &value);
849   gst_structure_set_value (structure, "streamheader", &list);
850   g_value_unset (&value);
851   g_value_unset (&list);
852
853   return caps;
854 }
855
856 static gboolean
857 gst_vorbisenc_sink_event (GstPad * pad, GstEvent * event)
858 {
859   gboolean res = TRUE;
860   GstVorbisEnc *vorbisenc;
861
862   vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
863
864   switch (GST_EVENT_TYPE (event)) {
865     case GST_EVENT_EOS:
866       /* Tell the library we're at end of stream so that it can handle
867        * the last frame and mark end of stream in the output properly */
868       GST_DEBUG_OBJECT (vorbisenc, "EOS, clearing state and sending event on");
869       vorbis_analysis_wrote (&vorbisenc->vd, 0);
870       gst_vorbisenc_output_buffers (vorbisenc);
871
872       /* clean up and exit.  vorbis_info_clear() must be called last */
873       vorbis_block_clear (&vorbisenc->vb);
874       vorbis_dsp_clear (&vorbisenc->vd);
875       vorbis_info_clear (&vorbisenc->vi);
876
877       res = gst_pad_event_default (pad, event);
878       break;
879     case GST_EVENT_TAG:
880       if (vorbisenc->tags) {
881         GstTagList *list;
882
883         gst_event_parse_tag (event, &list);
884         gst_tag_list_insert (vorbisenc->tags, list,
885             gst_tag_setter_get_merge_mode (GST_TAG_SETTER (vorbisenc)));
886       } else {
887         g_assert_not_reached ();
888       }
889       res = gst_pad_event_default (pad, event);
890       break;
891     default:
892       res = gst_pad_event_default (pad, event);
893       break;
894   }
895   return res;
896 }
897
898 static GstFlowReturn
899 gst_vorbisenc_chain (GstPad * pad, GstBuffer * buffer)
900 {
901   GstBuffer *buf = GST_BUFFER (buffer);
902   GstVorbisEnc *vorbisenc;
903
904   vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
905
906   {
907     gfloat *data;
908     gulong size;
909     gulong i, j;
910     float **buffer;
911
912     if (!vorbisenc->setup) {
913       gst_buffer_unref (buf);
914       GST_ELEMENT_ERROR (vorbisenc, CORE, NEGOTIATION, (NULL),
915           ("encoder not initialized (input is not audio?)"));
916       return GST_FLOW_UNEXPECTED;
917     }
918
919     if (!vorbisenc->header_sent) {
920       GST_DEBUG_OBJECT (vorbisenc, "creating and sending header packets");
921       //gint result;
922
923       /* Vorbis streams begin with three headers; the initial header (with
924          most of the codec setup parameters) which is mandated by the Ogg
925          bitstream spec.  The second header holds any comment fields.  The
926          third header holds the bitstream codebook.  We merely need to
927          make the headers, then pass them to libvorbis one at a time;
928          libvorbis handles the additional Ogg bitstream constraints */
929       ogg_packet header;
930       ogg_packet header_comm;
931       ogg_packet header_code;
932       GstBuffer *buf1, *buf2, *buf3;
933       GstCaps *caps;
934
935       gst_vorbisenc_set_metadata (vorbisenc);
936       vorbis_analysis_headerout (&vorbisenc->vd, &vorbisenc->vc, &header,
937           &header_comm, &header_code);
938
939       /* create header buffers */
940       buf1 = gst_vorbisenc_buffer_from_packet (vorbisenc, &header);
941       buf2 = gst_vorbisenc_buffer_from_packet (vorbisenc, &header_comm);
942       buf3 = gst_vorbisenc_buffer_from_packet (vorbisenc, &header_code);
943
944       /* mark and put on caps */
945       caps = gst_pad_get_caps (vorbisenc->srcpad);
946       caps = gst_vorbisenc_set_header_on_caps (caps, buf1, buf2, buf3);
947
948       /* negotiate with these caps */
949       GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
950       gst_pad_set_caps (vorbisenc->srcpad, caps);
951
952       gst_buffer_set_caps (buf1, caps);
953       gst_buffer_set_caps (buf2, caps);
954       gst_buffer_set_caps (buf3, caps);
955
956       /* push out buffers */
957       gst_vorbisenc_push_buffer (vorbisenc, buf1);
958       gst_vorbisenc_push_buffer (vorbisenc, buf2);
959       gst_vorbisenc_push_buffer (vorbisenc, buf3);
960
961       vorbisenc->header_sent = TRUE;
962     }
963
964     /* data to encode */
965     data = (gfloat *) GST_BUFFER_DATA (buf);
966     size = GST_BUFFER_SIZE (buf) / (vorbisenc->channels * sizeof (float));
967
968     /* expose the buffer to submit data */
969     buffer = vorbis_analysis_buffer (&vorbisenc->vd, size);
970
971     /* uninterleave samples */
972     for (i = 0; i < size; i++) {
973       for (j = 0; j < vorbisenc->channels; j++) {
974         buffer[j][i] = *data++;
975       }
976     }
977
978     /* tell the library how much we actually submitted */
979     vorbis_analysis_wrote (&vorbisenc->vd, size);
980
981     vorbisenc->samples_in += size;
982
983     gst_buffer_unref (buf);
984   }
985
986   gst_vorbisenc_output_buffers (vorbisenc);
987
988   return GST_FLOW_OK;
989 }
990
991 static void
992 gst_vorbisenc_output_buffers (GstVorbisEnc * vorbisenc)
993 {
994   /* vorbis does some data preanalysis, then divides up blocks for
995      more involved (potentially parallel) processing.  Get a single
996      block for encoding now */
997   while (vorbis_analysis_blockout (&vorbisenc->vd, &vorbisenc->vb) == 1) {
998     ogg_packet op;
999
1000     GST_LOG_OBJECT (vorbisenc, "analysed to a block");
1001
1002     /* analysis */
1003     vorbis_analysis (&vorbisenc->vb, NULL);
1004     vorbis_bitrate_addblock (&vorbisenc->vb);
1005
1006     while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &op)) {
1007       GST_LOG_OBJECT (vorbisenc, "pushing out a data packet");
1008       gst_vorbisenc_push_packet (vorbisenc, &op);
1009     }
1010   }
1011 }
1012
1013 static void
1014 gst_vorbisenc_get_property (GObject * object, guint prop_id, GValue * value,
1015     GParamSpec * pspec)
1016 {
1017   GstVorbisEnc *vorbisenc;
1018
1019   g_return_if_fail (GST_IS_VORBISENC (object));
1020
1021   vorbisenc = GST_VORBISENC (object);
1022
1023   switch (prop_id) {
1024     case ARG_MAX_BITRATE:
1025       g_value_set_int (value, vorbisenc->max_bitrate);
1026       break;
1027     case ARG_BITRATE:
1028       g_value_set_int (value, vorbisenc->bitrate);
1029       break;
1030     case ARG_MIN_BITRATE:
1031       g_value_set_int (value, vorbisenc->min_bitrate);
1032       break;
1033     case ARG_QUALITY:
1034       g_value_set_float (value, vorbisenc->quality);
1035       break;
1036     case ARG_MANAGED:
1037       g_value_set_boolean (value, vorbisenc->managed);
1038       break;
1039     case ARG_LAST_MESSAGE:
1040       g_value_set_string (value, vorbisenc->last_message);
1041       break;
1042     default:
1043       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1044       break;
1045   }
1046 }
1047
1048 static void
1049 gst_vorbisenc_set_property (GObject * object, guint prop_id,
1050     const GValue * value, GParamSpec * pspec)
1051 {
1052   GstVorbisEnc *vorbisenc;
1053
1054   g_return_if_fail (GST_IS_VORBISENC (object));
1055
1056   vorbisenc = GST_VORBISENC (object);
1057
1058   switch (prop_id) {
1059     case ARG_MAX_BITRATE:
1060     {
1061       gboolean old_value = vorbisenc->managed;
1062
1063       vorbisenc->max_bitrate = g_value_get_int (value);
1064       if (vorbisenc->max_bitrate >= 0
1065           && vorbisenc->max_bitrate < LOWEST_BITRATE) {
1066         g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1067         vorbisenc->max_bitrate = LOWEST_BITRATE;
1068       }
1069       if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
1070         vorbisenc->managed = TRUE;
1071       else
1072         vorbisenc->managed = FALSE;
1073
1074       if (old_value != vorbisenc->managed)
1075         g_object_notify (object, "managed");
1076       break;
1077     }
1078     case ARG_BITRATE:
1079       vorbisenc->bitrate = g_value_get_int (value);
1080       if (vorbisenc->bitrate >= 0 && vorbisenc->bitrate < LOWEST_BITRATE) {
1081         g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1082         vorbisenc->bitrate = LOWEST_BITRATE;
1083       }
1084       break;
1085     case ARG_MIN_BITRATE:
1086     {
1087       gboolean old_value = vorbisenc->managed;
1088
1089       vorbisenc->min_bitrate = g_value_get_int (value);
1090       if (vorbisenc->min_bitrate >= 0
1091           && vorbisenc->min_bitrate < LOWEST_BITRATE) {
1092         g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1093         vorbisenc->min_bitrate = LOWEST_BITRATE;
1094       }
1095       if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
1096         vorbisenc->managed = TRUE;
1097       else
1098         vorbisenc->managed = FALSE;
1099
1100       if (old_value != vorbisenc->managed)
1101         g_object_notify (object, "managed");
1102       break;
1103     }
1104     case ARG_QUALITY:
1105       vorbisenc->quality = g_value_get_float (value);
1106       if (vorbisenc->quality >= 0.0)
1107         vorbisenc->quality_set = TRUE;
1108       else
1109         vorbisenc->quality_set = FALSE;
1110       break;
1111     case ARG_MANAGED:
1112       vorbisenc->managed = g_value_get_boolean (value);
1113       break;
1114     default:
1115       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1116       break;
1117   }
1118 }
1119
1120 static GstStateChangeReturn
1121 gst_vorbisenc_change_state (GstElement * element, GstStateChange transition)
1122 {
1123   GstVorbisEnc *vorbisenc = GST_VORBISENC (element);
1124   GstStateChangeReturn res;
1125
1126
1127   switch (transition) {
1128     case GST_STATE_CHANGE_NULL_TO_READY:
1129       vorbisenc->tags = gst_tag_list_new ();
1130       break;
1131     case GST_STATE_CHANGE_READY_TO_PAUSED:
1132     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1133     default:
1134       break;
1135   }
1136
1137   res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1138
1139   switch (transition) {
1140     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1141       break;
1142     case GST_STATE_CHANGE_PAUSED_TO_READY:
1143       vorbisenc->setup = FALSE;
1144       vorbisenc->header_sent = FALSE;
1145       break;
1146     case GST_STATE_CHANGE_READY_TO_NULL:
1147       gst_tag_list_free (vorbisenc->tags);
1148       vorbisenc->tags = NULL;
1149     default:
1150       break;
1151   }
1152
1153   return res;
1154 }