8f75de8cd0c1f54fb1c25b0ff6392a7addf41902
[platform/upstream/gstreamer.git] / ext / vorbis / gstvorbisenc.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /**
21  * SECTION:element-vorbisenc
22  * @see_also: vorbisdec, oggmux
23  *
24  * This element encodes raw float audio into a Vorbis stream.
25  * <ulink url="http://www.vorbis.com/">Vorbis</ulink> is a royalty-free
26  * audio codec maintained by the <ulink url="http://www.xiph.org/">Xiph.org
27  * Foundation</ulink>.
28  *
29  * <refsect2>
30  * <title>Example pipelines</title>
31  * |[
32  * gst-launch -v audiotestsrc wave=sine num-buffers=100 ! audioconvert ! vorbisenc ! oggmux ! filesink location=sine.ogg
33  * ]| Encode a test sine signal to Ogg/Vorbis.  Note that the resulting file
34  * will be really small because a sine signal compresses very well.
35  * |[
36  * gst-launch -v alsasrc ! audioconvert ! vorbisenc ! oggmux ! filesink location=alsasrc.ogg
37  * ]| Record from a sound card using ALSA and encode to Ogg/Vorbis.
38  * </refsect2>
39  *
40  * Last reviewed on 2006-03-01 (0.10.4)
41  */
42 #ifdef HAVE_CONFIG_H
43 #include "config.h"
44 #endif
45
46 #include <stdlib.h>
47 #include <string.h>
48 #include <time.h>
49 #include <vorbis/vorbisenc.h>
50
51 #include <gst/gsttagsetter.h>
52 #include <gst/tag/tag.h>
53 #include <gst/audio/audio.h>
54 #include "gstvorbisenc.h"
55
56 #include "gstvorbiscommon.h"
57
58 GST_DEBUG_CATEGORY_EXTERN (vorbisenc_debug);
59 #define GST_CAT_DEFAULT vorbisenc_debug
60
61 static GstStaticPadTemplate vorbis_enc_sink_factory =
62 GST_STATIC_PAD_TEMPLATE ("sink",
63     GST_PAD_SINK,
64     GST_PAD_ALWAYS,
65     GST_STATIC_CAPS ("audio/x-raw, "
66         "format = (string) " GST_AUDIO_NE (F32) ", "
67         "layout = (string) interleaved, "
68         "rate = (int) [ 1, 200000 ], " "channels = (int) [ 1, 255 ]")
69     );
70
71 static GstStaticPadTemplate vorbis_enc_src_factory =
72 GST_STATIC_PAD_TEMPLATE ("src",
73     GST_PAD_SRC,
74     GST_PAD_ALWAYS,
75     GST_STATIC_CAPS ("audio/x-vorbis, "
76         "rate = (int) [ 1, 200000 ], " "channels = (int) [ 1, 255 ]")
77     );
78
79 enum
80 {
81   ARG_0,
82   ARG_MAX_BITRATE,
83   ARG_BITRATE,
84   ARG_MIN_BITRATE,
85   ARG_QUALITY,
86   ARG_MANAGED,
87   ARG_LAST_MESSAGE
88 };
89
90 static GstFlowReturn gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc);
91
92
93 #define MAX_BITRATE_DEFAULT     -1
94 #define BITRATE_DEFAULT         -1
95 #define MIN_BITRATE_DEFAULT     -1
96 #define QUALITY_DEFAULT         0.3
97 #define LOWEST_BITRATE          6000    /* lowest allowed for a 8 kHz stream */
98 #define HIGHEST_BITRATE         250001  /* highest allowed for a 44 kHz stream */
99
100 static gboolean gst_vorbis_enc_start (GstAudioEncoder * enc);
101 static gboolean gst_vorbis_enc_stop (GstAudioEncoder * enc);
102 static gboolean gst_vorbis_enc_set_format (GstAudioEncoder * enc,
103     GstAudioInfo * info);
104 static GstFlowReturn gst_vorbis_enc_handle_frame (GstAudioEncoder * enc,
105     GstBuffer * in_buf);
106 static GstCaps *gst_vorbis_enc_getcaps (GstAudioEncoder * enc,
107     GstCaps * filter);
108 static gboolean gst_vorbis_enc_sink_event (GstAudioEncoder * enc,
109     GstEvent * event);
110 static GstFlowReturn gst_vorbis_enc_pre_push (GstAudioEncoder * enc,
111     GstBuffer ** buffer);
112
113 static gboolean gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc);
114
115 static void gst_vorbis_enc_dispose (GObject * object);
116 static void gst_vorbis_enc_get_property (GObject * object, guint prop_id,
117     GValue * value, GParamSpec * pspec);
118 static void gst_vorbis_enc_set_property (GObject * object, guint prop_id,
119     const GValue * value, GParamSpec * pspec);
120
121 #define gst_vorbis_enc_parent_class parent_class
122 G_DEFINE_TYPE_WITH_CODE (GstVorbisEnc, gst_vorbis_enc,
123     GST_TYPE_AUDIO_ENCODER, G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL));
124
125 static void
126 gst_vorbis_enc_class_init (GstVorbisEncClass * klass)
127 {
128   GObjectClass *gobject_class;
129   GstElementClass *gstelement_class;
130   GstAudioEncoderClass *base_class;
131
132   gobject_class = (GObjectClass *) klass;
133   gstelement_class = (GstElementClass *) klass;
134   base_class = (GstAudioEncoderClass *) (klass);
135
136   gobject_class->set_property = gst_vorbis_enc_set_property;
137   gobject_class->get_property = gst_vorbis_enc_get_property;
138   gobject_class->dispose = gst_vorbis_enc_dispose;
139
140   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BITRATE,
141       g_param_spec_int ("max-bitrate", "Maximum Bitrate",
142           "Specify a maximum bitrate (in bps). Useful for streaming "
143           "applications. (-1 == disabled)",
144           -1, HIGHEST_BITRATE, MAX_BITRATE_DEFAULT,
145           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
146   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
147       g_param_spec_int ("bitrate", "Target Bitrate",
148           "Attempt to encode at a bitrate averaging this (in bps). "
149           "This uses the bitrate management engine, and is not recommended for most users. "
150           "Quality is a better alternative. (-1 == disabled)", -1,
151           HIGHEST_BITRATE, BITRATE_DEFAULT,
152           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
153   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MIN_BITRATE,
154       g_param_spec_int ("min-bitrate", "Minimum Bitrate",
155           "Specify a minimum bitrate (in bps). Useful for encoding for a "
156           "fixed-size channel. (-1 == disabled)", -1, HIGHEST_BITRATE,
157           MIN_BITRATE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
158   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
159       g_param_spec_float ("quality", "Quality",
160           "Specify quality instead of specifying a particular bitrate.", -0.1,
161           1.0, QUALITY_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
162   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MANAGED,
163       g_param_spec_boolean ("managed", "Managed",
164           "Enable bitrate management engine", FALSE,
165           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
166   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
167       g_param_spec_string ("last-message", "last-message",
168           "The last status message", NULL,
169           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
170
171   gst_element_class_add_pad_template (gstelement_class,
172       gst_static_pad_template_get (&vorbis_enc_src_factory));
173   gst_element_class_add_pad_template (gstelement_class,
174       gst_static_pad_template_get (&vorbis_enc_sink_factory));
175
176   gst_element_class_set_details_simple (gstelement_class,
177       "Vorbis audio encoder", "Codec/Encoder/Audio",
178       "Encodes audio in Vorbis format",
179       "Monty <monty@xiph.org>, " "Wim Taymans <wim@fluendo.com>");
180
181   base_class->start = GST_DEBUG_FUNCPTR (gst_vorbis_enc_start);
182   base_class->stop = GST_DEBUG_FUNCPTR (gst_vorbis_enc_stop);
183   base_class->set_format = GST_DEBUG_FUNCPTR (gst_vorbis_enc_set_format);
184   base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vorbis_enc_handle_frame);
185   base_class->getcaps = GST_DEBUG_FUNCPTR (gst_vorbis_enc_getcaps);
186   base_class->event = GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_event);
187   base_class->pre_push = GST_DEBUG_FUNCPTR (gst_vorbis_enc_pre_push);
188 }
189
190 static void
191 gst_vorbis_enc_init (GstVorbisEnc * vorbisenc)
192 {
193   GstAudioEncoder *enc = GST_AUDIO_ENCODER (vorbisenc);
194
195   vorbisenc->channels = -1;
196   vorbisenc->frequency = -1;
197
198   vorbisenc->managed = FALSE;
199   vorbisenc->max_bitrate = MAX_BITRATE_DEFAULT;
200   vorbisenc->bitrate = BITRATE_DEFAULT;
201   vorbisenc->min_bitrate = MIN_BITRATE_DEFAULT;
202   vorbisenc->quality = QUALITY_DEFAULT;
203   vorbisenc->quality_set = FALSE;
204   vorbisenc->last_message = NULL;
205
206   /* arrange granulepos marking (and required perfect ts) */
207   gst_audio_encoder_set_mark_granule (enc, TRUE);
208   gst_audio_encoder_set_perfect_timestamp (enc, TRUE);
209 }
210
211 static void
212 gst_vorbis_enc_dispose (GObject * object)
213 {
214   GstVorbisEnc *vorbisenc = GST_VORBISENC (object);
215
216   if (vorbisenc->sinkcaps) {
217     gst_caps_unref (vorbisenc->sinkcaps);
218     vorbisenc->sinkcaps = NULL;
219   }
220
221   G_OBJECT_CLASS (parent_class)->dispose (object);
222 }
223
224 static gboolean
225 gst_vorbis_enc_start (GstAudioEncoder * enc)
226 {
227   GstVorbisEnc *vorbisenc = GST_VORBISENC (enc);
228
229   GST_DEBUG_OBJECT (enc, "start");
230   vorbisenc->tags = gst_tag_list_new_empty ();
231   vorbisenc->header_sent = FALSE;
232
233   return TRUE;
234 }
235
236 static gboolean
237 gst_vorbis_enc_stop (GstAudioEncoder * enc)
238 {
239   GstVorbisEnc *vorbisenc = GST_VORBISENC (enc);
240
241   GST_DEBUG_OBJECT (enc, "stop");
242   vorbis_block_clear (&vorbisenc->vb);
243   vorbis_dsp_clear (&vorbisenc->vd);
244   vorbis_info_clear (&vorbisenc->vi);
245   g_free (vorbisenc->last_message);
246   vorbisenc->last_message = NULL;
247   gst_tag_list_free (vorbisenc->tags);
248   vorbisenc->tags = NULL;
249   g_slist_foreach (vorbisenc->headers, (GFunc) gst_buffer_unref, NULL);
250   vorbisenc->headers = NULL;
251
252   gst_tag_setter_reset_tags (GST_TAG_SETTER (enc));
253
254   return TRUE;
255 }
256
257 static GstCaps *
258 gst_vorbis_enc_generate_sink_caps (void)
259 {
260   GstCaps *caps = gst_caps_new_empty ();
261   int i, c;
262
263   gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
264           "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
265           "layout", G_TYPE_STRING, "interleaved",
266           "rate", GST_TYPE_INT_RANGE, 1, 200000,
267           "channels", G_TYPE_INT, 1, NULL));
268
269   for (i = 2; i <= 8; i++) {
270     GstStructure *structure;
271     guint64 channel_mask = 0;
272     const GstAudioChannelPosition *pos = gst_vorbis_channel_positions[i - 1];
273
274     for (c = 0; c < i; c++) {
275       channel_mask |= G_GUINT64_CONSTANT (1) << pos[i];
276     }
277
278     structure = gst_structure_new ("audio/x-raw",
279         "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
280         "layout", G_TYPE_STRING, "interleaved",
281         "rate", GST_TYPE_INT_RANGE, 1, 200000, "channels", G_TYPE_INT, i,
282         "channel-mask", GST_TYPE_BITMASK, channel_mask, NULL);
283
284     gst_caps_append_structure (caps, structure);
285   }
286
287   gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
288           "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
289           "layout", G_TYPE_STRING, "interleaved",
290           "rate", GST_TYPE_INT_RANGE, 1, 200000,
291           "channels", GST_TYPE_INT_RANGE, 9, 255,
292           "channel-mask", GST_TYPE_BITMASK, G_GUINT64_CONSTANT (0), NULL));
293
294   return caps;
295 }
296
297 static GstCaps *
298 gst_vorbis_enc_getcaps (GstAudioEncoder * enc, GstCaps * filter)
299 {
300   GstVorbisEnc *vorbisenc = GST_VORBISENC (enc);
301   GstCaps *caps;
302
303   if (vorbisenc->sinkcaps == NULL)
304     vorbisenc->sinkcaps = gst_vorbis_enc_generate_sink_caps ();
305
306   if (filter) {
307     GstCaps *int_caps = gst_caps_intersect_full (filter, vorbisenc->sinkcaps,
308         GST_CAPS_INTERSECT_FIRST);
309     caps = gst_audio_encoder_proxy_getcaps (enc, int_caps);
310     gst_caps_unref (int_caps);
311   } else {
312     caps = gst_audio_encoder_proxy_getcaps (enc, vorbisenc->sinkcaps);
313   }
314
315   return caps;
316 }
317
318 static gint64
319 gst_vorbis_enc_get_latency (GstVorbisEnc * vorbisenc)
320 {
321   /* FIXME, this probably depends on the bitrate and other setting but for now
322    * we return this value, which was obtained by totally unscientific
323    * measurements */
324   return 58 * GST_MSECOND;
325 }
326
327 static gboolean
328 gst_vorbis_enc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
329 {
330   GstVorbisEnc *vorbisenc;
331
332   vorbisenc = GST_VORBISENC (enc);
333
334   vorbisenc->channels = GST_AUDIO_INFO_CHANNELS (info);
335   vorbisenc->frequency = GST_AUDIO_INFO_RATE (info);
336
337   /* if re-configured, we were drained and cleared already */
338   if (!gst_vorbis_enc_setup (vorbisenc))
339     return FALSE;
340
341   /* feedback to base class */
342   gst_audio_encoder_set_latency (enc,
343       gst_vorbis_enc_get_latency (vorbisenc),
344       gst_vorbis_enc_get_latency (vorbisenc));
345
346   return TRUE;
347 }
348
349 static void
350 gst_vorbis_enc_metadata_set1 (const GstTagList * list, const gchar * tag,
351     gpointer vorbisenc)
352 {
353   GstVorbisEnc *enc = GST_VORBISENC (vorbisenc);
354   GList *vc_list, *l;
355
356   vc_list = gst_tag_to_vorbis_comments (list, tag);
357
358   for (l = vc_list; l != NULL; l = l->next) {
359     const gchar *vc_string = (const gchar *) l->data;
360     gchar *key = NULL, *val = NULL;
361
362     GST_LOG_OBJECT (vorbisenc, "vorbis comment: %s", vc_string);
363     if (gst_tag_parse_extended_comment (vc_string, &key, NULL, &val, TRUE)) {
364       vorbis_comment_add_tag (&enc->vc, key, val);
365       g_free (key);
366       g_free (val);
367     }
368   }
369
370   g_list_foreach (vc_list, (GFunc) g_free, NULL);
371   g_list_free (vc_list);
372 }
373
374 static void
375 gst_vorbis_enc_set_metadata (GstVorbisEnc * enc)
376 {
377   GstTagList *merged_tags;
378   const GstTagList *user_tags;
379
380   vorbis_comment_init (&enc->vc);
381
382   user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (enc));
383
384   GST_DEBUG_OBJECT (enc, "upstream tags = %" GST_PTR_FORMAT, enc->tags);
385   GST_DEBUG_OBJECT (enc, "user-set tags = %" GST_PTR_FORMAT, user_tags);
386
387   /* gst_tag_list_merge() will handle NULL for either or both lists fine */
388   merged_tags = gst_tag_list_merge (user_tags, enc->tags,
389       gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (enc)));
390
391   if (merged_tags) {
392     GST_DEBUG_OBJECT (enc, "merged   tags = %" GST_PTR_FORMAT, merged_tags);
393     gst_tag_list_foreach (merged_tags, gst_vorbis_enc_metadata_set1, enc);
394     gst_tag_list_free (merged_tags);
395   }
396 }
397
398 static gchar *
399 get_constraints_string (GstVorbisEnc * vorbisenc)
400 {
401   gint min = vorbisenc->min_bitrate;
402   gint max = vorbisenc->max_bitrate;
403   gchar *result;
404
405   if (min > 0 && max > 0)
406     result = g_strdup_printf ("(min %d bps, max %d bps)", min, max);
407   else if (min > 0)
408     result = g_strdup_printf ("(min %d bps, no max)", min);
409   else if (max > 0)
410     result = g_strdup_printf ("(no min, max %d bps)", max);
411   else
412     result = g_strdup_printf ("(no min or max)");
413
414   return result;
415 }
416
417 static void
418 update_start_message (GstVorbisEnc * vorbisenc)
419 {
420   gchar *constraints;
421
422   g_free (vorbisenc->last_message);
423
424   if (vorbisenc->bitrate > 0) {
425     if (vorbisenc->managed) {
426       constraints = get_constraints_string (vorbisenc);
427       vorbisenc->last_message =
428           g_strdup_printf ("encoding at average bitrate %d bps %s",
429           vorbisenc->bitrate, constraints);
430       g_free (constraints);
431     } else {
432       vorbisenc->last_message =
433           g_strdup_printf
434           ("encoding at approximate bitrate %d bps (VBR encoding enabled)",
435           vorbisenc->bitrate);
436     }
437   } else {
438     if (vorbisenc->quality_set) {
439       if (vorbisenc->managed) {
440         constraints = get_constraints_string (vorbisenc);
441         vorbisenc->last_message =
442             g_strdup_printf
443             ("encoding at quality level %2.2f using constrained VBR %s",
444             vorbisenc->quality, constraints);
445         g_free (constraints);
446       } else {
447         vorbisenc->last_message =
448             g_strdup_printf ("encoding at quality level %2.2f",
449             vorbisenc->quality);
450       }
451     } else {
452       constraints = get_constraints_string (vorbisenc);
453       vorbisenc->last_message =
454           g_strdup_printf ("encoding using bitrate management %s", constraints);
455       g_free (constraints);
456     }
457   }
458
459   g_object_notify (G_OBJECT (vorbisenc), "last_message");
460 }
461
462 static gboolean
463 gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc)
464 {
465
466   GST_LOG_OBJECT (vorbisenc, "setup");
467
468   if (vorbisenc->bitrate < 0 && vorbisenc->min_bitrate < 0
469       && vorbisenc->max_bitrate < 0) {
470     vorbisenc->quality_set = TRUE;
471   }
472
473   update_start_message (vorbisenc);
474
475   /* choose an encoding mode */
476   /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
477   vorbis_info_init (&vorbisenc->vi);
478
479   if (vorbisenc->quality_set) {
480     if (vorbis_encode_setup_vbr (&vorbisenc->vi,
481             vorbisenc->channels, vorbisenc->frequency,
482             vorbisenc->quality) != 0) {
483       GST_ERROR_OBJECT (vorbisenc,
484           "vorbisenc: initialisation failed: invalid parameters for quality");
485       vorbis_info_clear (&vorbisenc->vi);
486       return FALSE;
487     }
488
489     /* do we have optional hard quality restrictions? */
490     if (vorbisenc->max_bitrate > 0 || vorbisenc->min_bitrate > 0) {
491       struct ovectl_ratemanage_arg ai;
492
493       vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_GET, &ai);
494
495       ai.bitrate_hard_min = vorbisenc->min_bitrate;
496       ai.bitrate_hard_max = vorbisenc->max_bitrate;
497       ai.management_active = 1;
498
499       vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, &ai);
500     }
501   } else {
502     long min_bitrate, max_bitrate;
503
504     min_bitrate = vorbisenc->min_bitrate > 0 ? vorbisenc->min_bitrate : -1;
505     max_bitrate = vorbisenc->max_bitrate > 0 ? vorbisenc->max_bitrate : -1;
506
507     if (vorbis_encode_setup_managed (&vorbisenc->vi,
508             vorbisenc->channels,
509             vorbisenc->frequency,
510             max_bitrate, vorbisenc->bitrate, min_bitrate) != 0) {
511       GST_ERROR_OBJECT (vorbisenc,
512           "vorbis_encode_setup_managed "
513           "(c %d, rate %d, max br %ld, br %d, min br %ld) failed",
514           vorbisenc->channels, vorbisenc->frequency, max_bitrate,
515           vorbisenc->bitrate, min_bitrate);
516       vorbis_info_clear (&vorbisenc->vi);
517       return FALSE;
518     }
519   }
520
521   if (vorbisenc->managed && vorbisenc->bitrate < 0) {
522     vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_AVG, NULL);
523   } else if (!vorbisenc->managed) {
524     /* Turn off management entirely (if it was turned on). */
525     vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, NULL);
526   }
527   vorbis_encode_setup_init (&vorbisenc->vi);
528
529   /* set up the analysis state and auxiliary encoding storage */
530   vorbis_analysis_init (&vorbisenc->vd, &vorbisenc->vi);
531   vorbis_block_init (&vorbisenc->vd, &vorbisenc->vb);
532
533   /* samples == granulepos start at 0 again */
534   vorbisenc->samples_out = 0;
535
536   /* fresh encoder available */
537   vorbisenc->setup = TRUE;
538
539   return TRUE;
540 }
541
542 static GstFlowReturn
543 gst_vorbis_enc_clear (GstVorbisEnc * vorbisenc)
544 {
545   GstFlowReturn ret = GST_FLOW_OK;
546
547   if (vorbisenc->setup) {
548     vorbis_analysis_wrote (&vorbisenc->vd, 0);
549     ret = gst_vorbis_enc_output_buffers (vorbisenc);
550
551     /* marked EOS to encoder, recreate if needed */
552     vorbisenc->setup = FALSE;
553   }
554
555   /* clean up and exit.  vorbis_info_clear() must be called last */
556   vorbis_block_clear (&vorbisenc->vb);
557   vorbis_dsp_clear (&vorbisenc->vd);
558   vorbis_info_clear (&vorbisenc->vi);
559
560   return ret;
561 }
562
563 static GstBuffer *
564 gst_vorbis_enc_buffer_from_header_packet (GstVorbisEnc * vorbisenc,
565     ogg_packet * packet)
566 {
567   GstBuffer *outbuf;
568
569   outbuf = gst_buffer_new_and_alloc (packet->bytes);
570   gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
571   GST_BUFFER_OFFSET (outbuf) = vorbisenc->bytes_out;
572   GST_BUFFER_OFFSET_END (outbuf) = 0;
573   GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
574   GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
575
576   GST_DEBUG ("created header packet buffer, %" G_GSIZE_FORMAT " bytes",
577       gst_buffer_get_size (outbuf));
578   return outbuf;
579 }
580
581 static gboolean
582 gst_vorbis_enc_sink_event (GstAudioEncoder * enc, GstEvent * event)
583 {
584   GstVorbisEnc *vorbisenc;
585
586   vorbisenc = GST_VORBISENC (enc);
587
588   switch (GST_EVENT_TYPE (event)) {
589     case GST_EVENT_TAG:
590       if (vorbisenc->tags) {
591         GstTagList *list;
592
593         gst_event_parse_tag (event, &list);
594         gst_tag_list_insert (vorbisenc->tags, list,
595             gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (vorbisenc)));
596       } else {
597         g_assert_not_reached ();
598       }
599       break;
600       /* fall through */
601     default:
602       break;
603   }
604
605   /* we only peeked, let base class handle it */
606   return GST_AUDIO_ENCODER_CLASS (parent_class)->event (enc, event);
607 }
608
609 /* push out the buffer and do internal bookkeeping */
610 static GstFlowReturn
611 gst_vorbis_enc_push_header (GstVorbisEnc * vorbisenc, GstBuffer * buffer)
612 {
613   GST_DEBUG_OBJECT (vorbisenc,
614       "Pushing buffer with GP %" G_GINT64_FORMAT ", ts %" GST_TIME_FORMAT,
615       GST_BUFFER_OFFSET_END (buffer),
616       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
617   return gst_pad_push (GST_AUDIO_ENCODER_SRC_PAD (vorbisenc), buffer);
618 }
619
620 /*
621  * (really really) FIXME: move into core (dixit tpm)
622  */
623 /**
624  * _gst_caps_set_buffer_array:
625  * @caps: a #GstCaps
626  * @field: field in caps to set
627  * @buf: header buffers
628  *
629  * Adds given buffers to an array of buffers set as the given @field
630  * on the given @caps.  List of buffer arguments must be NULL-terminated.
631  *
632  * Returns: input caps with a streamheader field added, or NULL if some error
633  */
634 static GstCaps *
635 _gst_caps_set_buffer_array (GstCaps * caps, const gchar * field,
636     GstBuffer * buf, ...)
637 {
638   GstStructure *structure = NULL;
639   va_list va;
640   GValue array = { 0 };
641   GValue value = { 0 };
642
643   g_return_val_if_fail (caps != NULL, NULL);
644   g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
645   g_return_val_if_fail (field != NULL, NULL);
646
647   caps = gst_caps_make_writable (caps);
648   structure = gst_caps_get_structure (caps, 0);
649
650   g_value_init (&array, GST_TYPE_ARRAY);
651
652   va_start (va, buf);
653   /* put buffers in a fixed list */
654   while (buf) {
655     g_assert (gst_buffer_is_writable (buf));
656
657     /* mark buffer */
658     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
659
660     g_value_init (&value, GST_TYPE_BUFFER);
661     buf = gst_buffer_copy (buf);
662     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
663     gst_value_set_buffer (&value, buf);
664     gst_buffer_unref (buf);
665     gst_value_array_append_value (&array, &value);
666     g_value_unset (&value);
667
668     buf = va_arg (va, GstBuffer *);
669   }
670
671   gst_structure_set_value (structure, field, &array);
672   g_value_unset (&array);
673
674   return caps;
675 }
676
677 static GstFlowReturn
678 gst_vorbis_enc_handle_frame (GstAudioEncoder * enc, GstBuffer * buffer)
679 {
680   GstVorbisEnc *vorbisenc;
681   GstFlowReturn ret = GST_FLOW_OK;
682   GstMapInfo map;
683   gfloat *ptr;
684   gulong size;
685   gulong i, j;
686   float **vorbis_buffer;
687   GstBuffer *buf1, *buf2, *buf3;
688
689   vorbisenc = GST_VORBISENC (enc);
690
691   if (G_UNLIKELY (!vorbisenc->setup)) {
692     if (buffer) {
693       GST_DEBUG_OBJECT (vorbisenc, "forcing setup");
694       /* should not fail, as setup before same way */
695       if (!gst_vorbis_enc_setup (vorbisenc))
696         return GST_FLOW_ERROR;
697     } else {
698       /* end draining */
699       GST_LOG_OBJECT (vorbisenc, "already drained");
700       return GST_FLOW_OK;
701     }
702   }
703
704   if (!vorbisenc->header_sent) {
705     /* Vorbis streams begin with three headers; the initial header (with
706        most of the codec setup parameters) which is mandated by the Ogg
707        bitstream spec.  The second header holds any comment fields.  The
708        third header holds the bitstream codebook.  We merely need to
709        make the headers, then pass them to libvorbis one at a time;
710        libvorbis handles the additional Ogg bitstream constraints */
711     ogg_packet header;
712     ogg_packet header_comm;
713     ogg_packet header_code;
714     GstCaps *caps;
715
716     GST_DEBUG_OBJECT (vorbisenc, "creating and sending header packets");
717     gst_vorbis_enc_set_metadata (vorbisenc);
718     vorbis_analysis_headerout (&vorbisenc->vd, &vorbisenc->vc, &header,
719         &header_comm, &header_code);
720     vorbis_comment_clear (&vorbisenc->vc);
721
722     /* create header buffers */
723     buf1 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header);
724     buf2 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_comm);
725     buf3 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_code);
726
727     /* mark and put on caps */
728     caps = gst_caps_new_simple ("audio/x-vorbis",
729         "rate", G_TYPE_INT, vorbisenc->frequency,
730         "channels", G_TYPE_INT, vorbisenc->channels, NULL);
731     caps = _gst_caps_set_buffer_array (caps, "streamheader",
732         buf1, buf2, buf3, NULL);
733
734     /* negotiate with these caps */
735     GST_DEBUG_OBJECT (vorbisenc, "here are the caps: %" GST_PTR_FORMAT, caps);
736     gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (vorbisenc), caps);
737     gst_caps_unref (caps);
738
739     /* store buffers for later pre_push sending */
740     g_slist_foreach (vorbisenc->headers, (GFunc) gst_buffer_unref, NULL);
741     vorbisenc->headers = NULL;
742     GST_DEBUG_OBJECT (vorbisenc, "storing header buffers");
743     vorbisenc->headers = g_slist_prepend (vorbisenc->headers, buf3);
744     vorbisenc->headers = g_slist_prepend (vorbisenc->headers, buf2);
745     vorbisenc->headers = g_slist_prepend (vorbisenc->headers, buf1);
746
747     vorbisenc->header_sent = TRUE;
748   }
749
750   if (!buffer)
751     return gst_vorbis_enc_clear (vorbisenc);
752
753   gst_buffer_map (buffer, &map, GST_MAP_WRITE);
754
755   /* data to encode */
756   size = map.size / (vorbisenc->channels * sizeof (float));
757   ptr = (gfloat *) map.data;
758
759   /* expose the buffer to submit data */
760   vorbis_buffer = vorbis_analysis_buffer (&vorbisenc->vd, size);
761
762   /* deinterleave samples, write the buffer data */
763   if (vorbisenc->channels < 2 || vorbisenc->channels > 8) {
764     for (i = 0; i < size; i++) {
765       for (j = 0; j < vorbisenc->channels; j++) {
766         vorbis_buffer[j][i] = *ptr++;
767       }
768     }
769   } else {
770     gint i, j;
771
772     /* Reorder */
773     for (i = 0; i < size; i++) {
774       for (j = 0; j < vorbisenc->channels; j++) {
775         vorbis_buffer[gst_vorbis_reorder_map[vorbisenc->channels - 1][j]][i] =
776             ptr[j];
777       }
778       ptr += vorbisenc->channels;
779     }
780   }
781
782   /* tell the library how much we actually submitted */
783   vorbis_analysis_wrote (&vorbisenc->vd, size);
784   gst_buffer_unmap (buffer, &map);
785
786   GST_LOG_OBJECT (vorbisenc, "wrote %lu samples to vorbis", size);
787
788   vorbisenc->samples_in += size;
789
790   ret = gst_vorbis_enc_output_buffers (vorbisenc);
791
792   return ret;
793 }
794
795 static GstFlowReturn
796 gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc)
797 {
798   GstFlowReturn ret;
799
800   /* vorbis does some data preanalysis, then divides up blocks for
801      more involved (potentially parallel) processing.  Get a single
802      block for encoding now */
803   while (vorbis_analysis_blockout (&vorbisenc->vd, &vorbisenc->vb) == 1) {
804     ogg_packet op;
805
806     GST_LOG_OBJECT (vorbisenc, "analysed to a block");
807
808     /* analysis */
809     vorbis_analysis (&vorbisenc->vb, NULL);
810     vorbis_bitrate_addblock (&vorbisenc->vb);
811
812     while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &op)) {
813       GstBuffer *buf;
814
815       GST_LOG_OBJECT (vorbisenc, "pushing out a data packet");
816       buf = gst_buffer_new_and_alloc (op.bytes);
817       gst_buffer_fill (buf, 0, op.packet, op.bytes);
818       /* tracking granulepos should tell us samples accounted for */
819       ret =
820           gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER
821           (vorbisenc), buf, op.granulepos - vorbisenc->samples_out);
822       vorbisenc->samples_out = op.granulepos;
823
824       if (ret != GST_FLOW_OK)
825         return ret;
826     }
827   }
828
829   return GST_FLOW_OK;
830 }
831
832 static GstFlowReturn
833 gst_vorbis_enc_pre_push (GstAudioEncoder * enc, GstBuffer ** buffer)
834 {
835   GstVorbisEnc *vorbisenc;
836   GstFlowReturn ret = GST_FLOW_OK;
837
838   vorbisenc = GST_VORBISENC (enc);
839
840   /* FIXME 0.11 ? get rid of this special ogg stuff and have it
841    * put and use 'codec data' in caps like anything else,
842    * with all the usual out-of-band advantage etc */
843   if (G_UNLIKELY (vorbisenc->headers)) {
844     GSList *header = vorbisenc->headers;
845
846     /* try to push all of these, if we lose one, might as well lose all */
847     while (header) {
848       if (ret == GST_FLOW_OK)
849         ret = gst_vorbis_enc_push_header (vorbisenc, header->data);
850       else
851         gst_vorbis_enc_push_header (vorbisenc, header->data);
852       header = g_slist_next (header);
853     }
854
855     g_slist_free (vorbisenc->headers);
856     vorbisenc->headers = NULL;
857   }
858
859   return ret;
860 }
861
862 static void
863 gst_vorbis_enc_get_property (GObject * object, guint prop_id, GValue * value,
864     GParamSpec * pspec)
865 {
866   GstVorbisEnc *vorbisenc;
867
868   g_return_if_fail (GST_IS_VORBISENC (object));
869
870   vorbisenc = GST_VORBISENC (object);
871
872   switch (prop_id) {
873     case ARG_MAX_BITRATE:
874       g_value_set_int (value, vorbisenc->max_bitrate);
875       break;
876     case ARG_BITRATE:
877       g_value_set_int (value, vorbisenc->bitrate);
878       break;
879     case ARG_MIN_BITRATE:
880       g_value_set_int (value, vorbisenc->min_bitrate);
881       break;
882     case ARG_QUALITY:
883       g_value_set_float (value, vorbisenc->quality);
884       break;
885     case ARG_MANAGED:
886       g_value_set_boolean (value, vorbisenc->managed);
887       break;
888     case ARG_LAST_MESSAGE:
889       g_value_set_string (value, vorbisenc->last_message);
890       break;
891     default:
892       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
893       break;
894   }
895 }
896
897 static void
898 gst_vorbis_enc_set_property (GObject * object, guint prop_id,
899     const GValue * value, GParamSpec * pspec)
900 {
901   GstVorbisEnc *vorbisenc;
902
903   g_return_if_fail (GST_IS_VORBISENC (object));
904
905   vorbisenc = GST_VORBISENC (object);
906
907   switch (prop_id) {
908     case ARG_MAX_BITRATE:
909     {
910       gboolean old_value = vorbisenc->managed;
911
912       vorbisenc->max_bitrate = g_value_get_int (value);
913       if (vorbisenc->max_bitrate >= 0
914           && vorbisenc->max_bitrate < LOWEST_BITRATE) {
915         g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
916         vorbisenc->max_bitrate = LOWEST_BITRATE;
917       }
918       if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
919         vorbisenc->managed = TRUE;
920       else
921         vorbisenc->managed = FALSE;
922
923       if (old_value != vorbisenc->managed)
924         g_object_notify (object, "managed");
925       break;
926     }
927     case ARG_BITRATE:
928       vorbisenc->bitrate = g_value_get_int (value);
929       if (vorbisenc->bitrate >= 0 && vorbisenc->bitrate < LOWEST_BITRATE) {
930         g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
931         vorbisenc->bitrate = LOWEST_BITRATE;
932       }
933       break;
934     case ARG_MIN_BITRATE:
935     {
936       gboolean old_value = vorbisenc->managed;
937
938       vorbisenc->min_bitrate = g_value_get_int (value);
939       if (vorbisenc->min_bitrate >= 0
940           && vorbisenc->min_bitrate < LOWEST_BITRATE) {
941         g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
942         vorbisenc->min_bitrate = LOWEST_BITRATE;
943       }
944       if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
945         vorbisenc->managed = TRUE;
946       else
947         vorbisenc->managed = FALSE;
948
949       if (old_value != vorbisenc->managed)
950         g_object_notify (object, "managed");
951       break;
952     }
953     case ARG_QUALITY:
954       vorbisenc->quality = g_value_get_float (value);
955       if (vorbisenc->quality >= 0.0)
956         vorbisenc->quality_set = TRUE;
957       else
958         vorbisenc->quality_set = FALSE;
959       break;
960     case ARG_MANAGED:
961       vorbisenc->managed = g_value_get_boolean (value);
962       break;
963     default:
964       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
965       break;
966   }
967 }