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