• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 /**
21  * SECTION:element-vorbisenc
22  * @title: vorbisenc
23  * @see_also: vorbisdec, oggmux
24  *
25  * This element encodes raw float audio into a Vorbis stream.
26  * <ulink url="http://www.vorbis.com/">Vorbis</ulink> is a royalty-free
27  * audio codec maintained by the <ulink url="http://www.xiph.org/">Xiph.org
28  * Foundation</ulink>.
29  *
30  * ## Example pipelines
31  * |[
32  * gst-launch-1.0 -v audiotestsrc wave=sine num-buffers=100 ! audioconvert ! vorbisenc ! oggmux ! filesink location=sine.ogg
33  * ]|
34  *  Encode a test sine signal to Ogg/Vorbis.  Note that the resulting file
35  * will be really small because a sine signal compresses very well.
36  * |[
37  * gst-launch-1.0 -v autoaudiosrc ! audioconvert ! vorbisenc ! oggmux ! filesink location=alsasrc.ogg
38  * ]|
39  *  Record from a sound card and encode to Ogg/Vorbis.
40  *
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_src_factory =
62 GST_STATIC_PAD_TEMPLATE ("src",
63     GST_PAD_SRC,
64     GST_PAD_ALWAYS,
65     GST_STATIC_CAPS ("audio/x-vorbis, "
66         "rate = (int) [ 1, 200000 ], " "channels = (int) [ 1, 255 ]")
67     );
68 
69 enum
70 {
71   ARG_0,
72   ARG_MAX_BITRATE,
73   ARG_BITRATE,
74   ARG_MIN_BITRATE,
75   ARG_QUALITY,
76   ARG_MANAGED,
77   ARG_LAST_MESSAGE
78 };
79 
80 static GstFlowReturn gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc);
81 static GstCaps *gst_vorbis_enc_generate_sink_caps (void);
82 
83 
84 #define MAX_BITRATE_DEFAULT     -1
85 #define BITRATE_DEFAULT         -1
86 #define MIN_BITRATE_DEFAULT     -1
87 #define QUALITY_DEFAULT         0.3
88 #define LOWEST_BITRATE          6000    /* lowest allowed for a 8 kHz stream */
89 #define HIGHEST_BITRATE         250001  /* highest allowed for a 44 kHz stream */
90 
91 static gboolean gst_vorbis_enc_start (GstAudioEncoder * enc);
92 static gboolean gst_vorbis_enc_stop (GstAudioEncoder * enc);
93 static gboolean gst_vorbis_enc_set_format (GstAudioEncoder * enc,
94     GstAudioInfo * info);
95 static GstFlowReturn gst_vorbis_enc_handle_frame (GstAudioEncoder * enc,
96     GstBuffer * in_buf);
97 static gboolean gst_vorbis_enc_sink_event (GstAudioEncoder * enc,
98     GstEvent * event);
99 
100 static gboolean gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc);
101 
102 static void gst_vorbis_enc_dispose (GObject * object);
103 static void gst_vorbis_enc_get_property (GObject * object, guint prop_id,
104     GValue * value, GParamSpec * pspec);
105 static void gst_vorbis_enc_set_property (GObject * object, guint prop_id,
106     const GValue * value, GParamSpec * pspec);
107 static void gst_vorbis_enc_flush (GstAudioEncoder * vorbisenc);
108 
109 #define gst_vorbis_enc_parent_class parent_class
110 G_DEFINE_TYPE_WITH_CODE (GstVorbisEnc, gst_vorbis_enc,
111     GST_TYPE_AUDIO_ENCODER, G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL));
112 
113 static void
gst_vorbis_enc_class_init(GstVorbisEncClass * klass)114 gst_vorbis_enc_class_init (GstVorbisEncClass * klass)
115 {
116   GObjectClass *gobject_class;
117   GstElementClass *gstelement_class;
118   GstAudioEncoderClass *base_class;
119   GstCaps *sink_caps;
120   GstPadTemplate *sink_templ;
121 
122   gobject_class = (GObjectClass *) klass;
123   gstelement_class = (GstElementClass *) klass;
124   base_class = (GstAudioEncoderClass *) (klass);
125 
126   gobject_class->set_property = gst_vorbis_enc_set_property;
127   gobject_class->get_property = gst_vorbis_enc_get_property;
128   gobject_class->dispose = gst_vorbis_enc_dispose;
129 
130   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BITRATE,
131       g_param_spec_int ("max-bitrate", "Maximum Bitrate",
132           "Specify a maximum bitrate (in bps). Useful for streaming "
133           "applications. (-1 == disabled)",
134           -1, HIGHEST_BITRATE, MAX_BITRATE_DEFAULT,
135           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
136   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
137       g_param_spec_int ("bitrate", "Target Bitrate",
138           "Attempt to encode at a bitrate averaging this (in bps). "
139           "This uses the bitrate management engine, and is not recommended for most users. "
140           "Quality is a better alternative. (-1 == disabled)", -1,
141           HIGHEST_BITRATE, BITRATE_DEFAULT,
142           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
143   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MIN_BITRATE,
144       g_param_spec_int ("min-bitrate", "Minimum Bitrate",
145           "Specify a minimum bitrate (in bps). Useful for encoding for a "
146           "fixed-size channel. (-1 == disabled)", -1, HIGHEST_BITRATE,
147           MIN_BITRATE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
148   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
149       g_param_spec_float ("quality", "Quality",
150           "Specify quality instead of specifying a particular bitrate.", -0.1,
151           1.0, QUALITY_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
152   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MANAGED,
153       g_param_spec_boolean ("managed", "Managed",
154           "Enable bitrate management engine", FALSE,
155           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
156   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
157       g_param_spec_string ("last-message", "last-message",
158           "The last status message", NULL,
159           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
160 
161   sink_caps = gst_vorbis_enc_generate_sink_caps ();
162   sink_templ = gst_pad_template_new ("sink",
163       GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps);
164   gst_element_class_add_pad_template (gstelement_class, sink_templ);
165   gst_caps_unref (sink_caps);
166 
167   gst_element_class_add_static_pad_template (gstelement_class,
168       &vorbis_enc_src_factory);
169 
170   gst_element_class_set_static_metadata (gstelement_class,
171       "Vorbis audio encoder", "Codec/Encoder/Audio",
172       "Encodes audio in Vorbis format",
173       "Monty <monty@xiph.org>, " "Wim Taymans <wim@fluendo.com>");
174 
175   base_class->start = GST_DEBUG_FUNCPTR (gst_vorbis_enc_start);
176   base_class->stop = GST_DEBUG_FUNCPTR (gst_vorbis_enc_stop);
177   base_class->set_format = GST_DEBUG_FUNCPTR (gst_vorbis_enc_set_format);
178   base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vorbis_enc_handle_frame);
179   base_class->sink_event = GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_event);
180   base_class->flush = GST_DEBUG_FUNCPTR (gst_vorbis_enc_flush);
181 }
182 
183 static void
gst_vorbis_enc_init(GstVorbisEnc * vorbisenc)184 gst_vorbis_enc_init (GstVorbisEnc * vorbisenc)
185 {
186   GstAudioEncoder *enc = GST_AUDIO_ENCODER (vorbisenc);
187 
188   GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_ENCODER_SINK_PAD (enc));
189 
190   vorbisenc->channels = -1;
191   vorbisenc->frequency = -1;
192 
193   vorbisenc->managed = FALSE;
194   vorbisenc->max_bitrate = MAX_BITRATE_DEFAULT;
195   vorbisenc->bitrate = BITRATE_DEFAULT;
196   vorbisenc->min_bitrate = MIN_BITRATE_DEFAULT;
197   vorbisenc->quality = QUALITY_DEFAULT;
198   vorbisenc->quality_set = FALSE;
199   vorbisenc->last_message = NULL;
200 
201   /* arrange granulepos marking (and required perfect ts) */
202   gst_audio_encoder_set_mark_granule (enc, TRUE);
203   gst_audio_encoder_set_perfect_timestamp (enc, TRUE);
204 }
205 
206 static void
gst_vorbis_enc_dispose(GObject * object)207 gst_vorbis_enc_dispose (GObject * object)
208 {
209   GstVorbisEnc *vorbisenc = GST_VORBISENC (object);
210 
211   if (vorbisenc->sinkcaps) {
212     gst_caps_unref (vorbisenc->sinkcaps);
213     vorbisenc->sinkcaps = NULL;
214   }
215 
216   G_OBJECT_CLASS (parent_class)->dispose (object);
217 }
218 
219 static gboolean
gst_vorbis_enc_start(GstAudioEncoder * enc)220 gst_vorbis_enc_start (GstAudioEncoder * enc)
221 {
222   GstVorbisEnc *vorbisenc = GST_VORBISENC (enc);
223 
224   GST_DEBUG_OBJECT (enc, "start");
225   vorbisenc->tags = gst_tag_list_new_empty ();
226   vorbisenc->header_sent = FALSE;
227   vorbisenc->last_size = 0;
228 
229   return TRUE;
230 }
231 
232 static gboolean
gst_vorbis_enc_stop(GstAudioEncoder * enc)233 gst_vorbis_enc_stop (GstAudioEncoder * enc)
234 {
235   GstVorbisEnc *vorbisenc = GST_VORBISENC (enc);
236 
237   GST_DEBUG_OBJECT (enc, "stop");
238   vorbis_block_clear (&vorbisenc->vb);
239   vorbis_dsp_clear (&vorbisenc->vd);
240   vorbis_info_clear (&vorbisenc->vi);
241   g_free (vorbisenc->last_message);
242   vorbisenc->last_message = NULL;
243   gst_tag_list_unref (vorbisenc->tags);
244   vorbisenc->tags = NULL;
245 
246   gst_tag_setter_reset_tags (GST_TAG_SETTER (enc));
247 
248   return TRUE;
249 }
250 
251 static GstCaps *
gst_vorbis_enc_generate_sink_caps(void)252 gst_vorbis_enc_generate_sink_caps (void)
253 {
254   GstCaps *caps = gst_caps_new_empty ();
255   int i, c;
256 
257   gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
258           "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
259           "layout", G_TYPE_STRING, "interleaved",
260           "rate", GST_TYPE_INT_RANGE, 1, 200000,
261           "channels", G_TYPE_INT, 1, NULL));
262 
263   for (i = 2; i <= 8; i++) {
264     GstStructure *structure;
265     guint64 channel_mask = 0;
266     const GstAudioChannelPosition *pos = gst_vorbis_channel_positions[i - 1];
267 
268     for (c = 0; c < i; c++) {
269       channel_mask |= G_GUINT64_CONSTANT (1) << pos[c];
270     }
271 
272     structure = gst_structure_new ("audio/x-raw",
273         "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
274         "layout", G_TYPE_STRING, "interleaved",
275         "rate", GST_TYPE_INT_RANGE, 1, 200000, "channels", G_TYPE_INT, i,
276         "channel-mask", GST_TYPE_BITMASK, channel_mask, NULL);
277 
278     gst_caps_append_structure (caps, structure);
279   }
280 
281   gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
282           "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
283           "layout", G_TYPE_STRING, "interleaved",
284           "rate", GST_TYPE_INT_RANGE, 1, 200000,
285           "channels", GST_TYPE_INT_RANGE, 9, 255,
286           "channel-mask", GST_TYPE_BITMASK, G_GUINT64_CONSTANT (0), NULL));
287 
288   return caps;
289 }
290 
291 static gint64
gst_vorbis_enc_get_latency(GstVorbisEnc * vorbisenc)292 gst_vorbis_enc_get_latency (GstVorbisEnc * vorbisenc)
293 {
294   /* FIXME, this probably depends on the bitrate and other setting but for now
295    * we return this value, which was obtained by totally unscientific
296    * measurements */
297   return 58 * GST_MSECOND;
298 }
299 
300 static gboolean
gst_vorbis_enc_set_format(GstAudioEncoder * enc,GstAudioInfo * info)301 gst_vorbis_enc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
302 {
303   GstVorbisEnc *vorbisenc;
304 
305   vorbisenc = GST_VORBISENC (enc);
306 
307   vorbisenc->channels = GST_AUDIO_INFO_CHANNELS (info);
308   vorbisenc->frequency = GST_AUDIO_INFO_RATE (info);
309 
310   /* if re-configured, we were drained and cleared already */
311   vorbisenc->header_sent = FALSE;
312   if (!gst_vorbis_enc_setup (vorbisenc))
313     return FALSE;
314 
315   /* feedback to base class */
316   gst_audio_encoder_set_latency (enc,
317       gst_vorbis_enc_get_latency (vorbisenc),
318       gst_vorbis_enc_get_latency (vorbisenc));
319 
320   return TRUE;
321 }
322 
323 static void
gst_vorbis_enc_metadata_set1(const GstTagList * list,const gchar * tag,gpointer vorbisenc)324 gst_vorbis_enc_metadata_set1 (const GstTagList * list, const gchar * tag,
325     gpointer vorbisenc)
326 {
327   GstVorbisEnc *enc = GST_VORBISENC (vorbisenc);
328   GList *vc_list, *l;
329 
330   vc_list = gst_tag_to_vorbis_comments (list, tag);
331 
332   for (l = vc_list; l != NULL; l = l->next) {
333     const gchar *vc_string = (const gchar *) l->data;
334     gchar *key = NULL, *val = NULL;
335 
336     GST_LOG_OBJECT (vorbisenc, "vorbis comment: %s", vc_string);
337     if (gst_tag_parse_extended_comment (vc_string, &key, NULL, &val, TRUE)) {
338       vorbis_comment_add_tag (&enc->vc, key, val);
339       g_free (key);
340       g_free (val);
341     }
342   }
343 
344   g_list_foreach (vc_list, (GFunc) g_free, NULL);
345   g_list_free (vc_list);
346 }
347 
348 static void
gst_vorbis_enc_set_metadata(GstVorbisEnc * enc)349 gst_vorbis_enc_set_metadata (GstVorbisEnc * enc)
350 {
351   GstTagList *merged_tags;
352   const GstTagList *user_tags;
353 
354   vorbis_comment_init (&enc->vc);
355 
356   user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (enc));
357 
358   GST_DEBUG_OBJECT (enc, "upstream tags = %" GST_PTR_FORMAT, enc->tags);
359   GST_DEBUG_OBJECT (enc, "user-set tags = %" GST_PTR_FORMAT, user_tags);
360 
361   /* gst_tag_list_merge() will handle NULL for either or both lists fine */
362   merged_tags = gst_tag_list_merge (user_tags, enc->tags,
363       gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (enc)));
364 
365   if (merged_tags) {
366     GST_DEBUG_OBJECT (enc, "merged   tags = %" GST_PTR_FORMAT, merged_tags);
367     gst_tag_list_foreach (merged_tags, gst_vorbis_enc_metadata_set1, enc);
368     gst_tag_list_unref (merged_tags);
369   }
370 }
371 
372 static gchar *
get_constraints_string(GstVorbisEnc * vorbisenc)373 get_constraints_string (GstVorbisEnc * vorbisenc)
374 {
375   gint min = vorbisenc->min_bitrate;
376   gint max = vorbisenc->max_bitrate;
377   gchar *result;
378 
379   if (min > 0 && max > 0)
380     result = g_strdup_printf ("(min %d bps, max %d bps)", min, max);
381   else if (min > 0)
382     result = g_strdup_printf ("(min %d bps, no max)", min);
383   else if (max > 0)
384     result = g_strdup_printf ("(no min, max %d bps)", max);
385   else
386     result = g_strdup_printf ("(no min or max)");
387 
388   return result;
389 }
390 
391 static void
update_start_message(GstVorbisEnc * vorbisenc)392 update_start_message (GstVorbisEnc * vorbisenc)
393 {
394   gchar *constraints;
395 
396   g_free (vorbisenc->last_message);
397 
398   if (vorbisenc->bitrate > 0) {
399     if (vorbisenc->managed) {
400       constraints = get_constraints_string (vorbisenc);
401       vorbisenc->last_message =
402           g_strdup_printf ("encoding at average bitrate %d bps %s",
403           vorbisenc->bitrate, constraints);
404       g_free (constraints);
405     } else {
406       vorbisenc->last_message =
407           g_strdup_printf
408           ("encoding at approximate bitrate %d bps (VBR encoding enabled)",
409           vorbisenc->bitrate);
410     }
411   } else {
412     if (vorbisenc->quality_set) {
413       if (vorbisenc->managed) {
414         constraints = get_constraints_string (vorbisenc);
415         vorbisenc->last_message =
416             g_strdup_printf
417             ("encoding at quality level %2.2f using constrained VBR %s",
418             vorbisenc->quality, constraints);
419         g_free (constraints);
420       } else {
421         vorbisenc->last_message =
422             g_strdup_printf ("encoding at quality level %2.2f",
423             vorbisenc->quality);
424       }
425     } else {
426       constraints = get_constraints_string (vorbisenc);
427       vorbisenc->last_message =
428           g_strdup_printf ("encoding using bitrate management %s", constraints);
429       g_free (constraints);
430     }
431   }
432 
433   g_object_notify (G_OBJECT (vorbisenc), "last_message");
434 }
435 
436 static gboolean
gst_vorbis_enc_setup(GstVorbisEnc * vorbisenc)437 gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc)
438 {
439 
440   GST_LOG_OBJECT (vorbisenc, "setup");
441 
442   if (vorbisenc->bitrate < 0 && vorbisenc->min_bitrate < 0
443       && vorbisenc->max_bitrate < 0) {
444     vorbisenc->quality_set = TRUE;
445   }
446 
447   update_start_message (vorbisenc);
448 
449   /* choose an encoding mode */
450   /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
451   vorbis_info_init (&vorbisenc->vi);
452 
453   if (vorbisenc->quality_set) {
454     if (vorbis_encode_setup_vbr (&vorbisenc->vi,
455             vorbisenc->channels, vorbisenc->frequency,
456             vorbisenc->quality) != 0) {
457       GST_ERROR_OBJECT (vorbisenc,
458           "vorbisenc: initialisation failed: invalid parameters for quality");
459       vorbis_info_clear (&vorbisenc->vi);
460       return FALSE;
461     }
462 
463     /* do we have optional hard quality restrictions? */
464     if (vorbisenc->max_bitrate > 0 || vorbisenc->min_bitrate > 0) {
465       struct ovectl_ratemanage_arg ai;
466 
467       vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_GET, &ai);
468 
469       ai.bitrate_hard_min = vorbisenc->min_bitrate;
470       ai.bitrate_hard_max = vorbisenc->max_bitrate;
471       ai.management_active = 1;
472 
473       vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, &ai);
474     }
475   } else {
476     long min_bitrate, max_bitrate;
477 
478     min_bitrate = vorbisenc->min_bitrate > 0 ? vorbisenc->min_bitrate : -1;
479     max_bitrate = vorbisenc->max_bitrate > 0 ? vorbisenc->max_bitrate : -1;
480 
481     if (vorbis_encode_setup_managed (&vorbisenc->vi,
482             vorbisenc->channels,
483             vorbisenc->frequency,
484             max_bitrate, vorbisenc->bitrate, min_bitrate) != 0) {
485       GST_ERROR_OBJECT (vorbisenc,
486           "vorbis_encode_setup_managed "
487           "(c %d, rate %d, max br %ld, br %d, min br %ld) failed",
488           vorbisenc->channels, vorbisenc->frequency, max_bitrate,
489           vorbisenc->bitrate, min_bitrate);
490       vorbis_info_clear (&vorbisenc->vi);
491       return FALSE;
492     }
493   }
494 
495   if (vorbisenc->managed && vorbisenc->bitrate < 0) {
496     vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_AVG, NULL);
497   } else if (!vorbisenc->managed) {
498     /* Turn off management entirely (if it was turned on). */
499     vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, NULL);
500   }
501   vorbis_encode_setup_init (&vorbisenc->vi);
502 
503   /* set up the analysis state and auxiliary encoding storage */
504   vorbis_analysis_init (&vorbisenc->vd, &vorbisenc->vi);
505   vorbis_block_init (&vorbisenc->vd, &vorbisenc->vb);
506 
507   /* samples == granulepos start at 0 again */
508   vorbisenc->samples_out = 0;
509 
510   /* fresh encoder available */
511   vorbisenc->setup = TRUE;
512 
513   return TRUE;
514 }
515 
516 static GstFlowReturn
gst_vorbis_enc_clear(GstVorbisEnc * vorbisenc)517 gst_vorbis_enc_clear (GstVorbisEnc * vorbisenc)
518 {
519   GstFlowReturn ret = GST_FLOW_OK;
520 
521   if (vorbisenc->setup) {
522     vorbis_analysis_wrote (&vorbisenc->vd, 0);
523     ret = gst_vorbis_enc_output_buffers (vorbisenc);
524 
525     /* marked EOS to encoder, recreate if needed */
526     vorbisenc->setup = FALSE;
527   }
528 
529   /* clean up and exit.  vorbis_info_clear() must be called last */
530   vorbis_block_clear (&vorbisenc->vb);
531   vorbis_dsp_clear (&vorbisenc->vd);
532   vorbis_info_clear (&vorbisenc->vi);
533 
534   return ret;
535 }
536 
537 static void
gst_vorbis_enc_flush(GstAudioEncoder * enc)538 gst_vorbis_enc_flush (GstAudioEncoder * enc)
539 {
540   GstVorbisEnc *vorbisenc = GST_VORBISENC (enc);
541 
542   gst_vorbis_enc_clear (vorbisenc);
543   vorbisenc->header_sent = FALSE;
544 }
545 
546 /* copied and adapted from ext/ogg/gstoggstream.c */
547 static gint64
packet_duration_vorbis(GstVorbisEnc * enc,ogg_packet * packet)548 packet_duration_vorbis (GstVorbisEnc * enc, ogg_packet * packet)
549 {
550   int mode;
551   int size;
552   int duration;
553 
554   if (packet->bytes == 0 || packet->packet[0] & 1)
555     return 0;
556 
557   mode = (packet->packet[0] >> 1) & ((1 << enc->vorbis_log2_num_modes) - 1);
558   size = enc->vorbis_mode_sizes[mode] ? enc->long_size : enc->short_size;
559 
560   if (enc->last_size == 0) {
561     duration = 0;
562   } else {
563     duration = enc->last_size / 4 + size / 4;
564   }
565   enc->last_size = size;
566 
567   GST_DEBUG_OBJECT (enc, "duration %d", (int) duration);
568 
569   return duration;
570 }
571 
572 /* copied and adapted from ext/ogg/gstoggstream.c */
573 static void
parse_vorbis_header_packet(GstVorbisEnc * enc,ogg_packet * packet)574 parse_vorbis_header_packet (GstVorbisEnc * enc, ogg_packet * packet)
575 {
576   /*
577    * on the first (b_o_s) packet, determine the long and short sizes,
578    * and then calculate l/2, l/4 - s/4, 3 * l/4 - s/4, l/2 - s/2 and s/2
579    */
580 
581   enc->long_size = 1 << (packet->packet[28] >> 4);
582   enc->short_size = 1 << (packet->packet[28] & 0xF);
583 }
584 
585 /* copied and adapted from ext/ogg/gstoggstream.c */
586 static void
parse_vorbis_codebooks_packet(GstVorbisEnc * enc,ogg_packet * op)587 parse_vorbis_codebooks_packet (GstVorbisEnc * enc, ogg_packet * op)
588 {
589   /*
590    * the code pages, a whole bunch of other fairly useless stuff, AND,
591    * RIGHT AT THE END (of a bunch of variable-length compressed rubbish that
592    * basically has only one actual set of values that everyone uses BUT YOU
593    * CAN'T BE SURE OF THAT, OH NO YOU CAN'T) is the only piece of data that's
594    * actually useful to us - the packet modes (because it's inconceivable to
595    * think people might want _just that_ and nothing else, you know, for
596    * seeking and stuff).
597    *
598    * Fortunately, because of the mandate that non-used bits must be zero
599    * at the end of the packet, we might be able to sneakily work backwards
600    * and find out the information we need (namely a mapping of modes to
601    * packet sizes)
602    */
603   unsigned char *current_pos = &op->packet[op->bytes - 1];
604   int offset;
605   int size;
606   int size_check;
607   int *mode_size_ptr;
608   int i;
609   int ii;
610 
611   /*
612    * This is the format of the mode data at the end of the packet for all
613    * Vorbis Version 1 :
614    *
615    * [ 6:number_of_modes ]
616    * [ 1:size | 16:window_type(0) | 16:transform_type(0) | 8:mapping ]
617    * [ 1:size | 16:window_type(0) | 16:transform_type(0) | 8:mapping ]
618    * [ 1:size | 16:window_type(0) | 16:transform_type(0) | 8:mapping ]
619    * [ 1:framing(1) ]
620    *
621    * e.g.:
622    *
623    *              <-
624    * 0 0 0 0 0 1 0 0
625    * 0 0 1 0 0 0 0 0
626    * 0 0 1 0 0 0 0 0
627    * 0 0 1|0 0 0 0 0
628    * 0 0 0 0|0|0 0 0
629    * 0 0 0 0 0 0 0 0
630    * 0 0 0 0|0 0 0 0
631    * 0 0 0 0 0 0 0 0
632    * 0 0 0 0|0 0 0 0
633    * 0 0 0|1|0 0 0 0 |
634    * 0 0 0 0 0 0 0 0 V
635    * 0 0 0|0 0 0 0 0
636    * 0 0 0 0 0 0 0 0
637    * 0 0 1|0 0 0 0 0
638    * 0 0|1|0 0 0 0 0
639    *
640    *
641    * i.e. each entry is an important bit, 32 bits of 0, 8 bits of blah, a
642    * bit of 1.
643    * Let's find our last 1 bit first.
644    *
645    */
646 
647   size = 0;
648 
649   offset = 8;
650   while (!((1 << --offset) & *current_pos)) {
651     if (offset == 0) {
652       offset = 8;
653       current_pos -= 1;
654     }
655   }
656 
657   while (1) {
658 
659     /*
660      * from current_pos-5:(offset+1) to current_pos-1:(offset+1) should
661      * be zero
662      */
663     offset = (offset + 7) % 8;
664     if (offset == 7)
665       current_pos -= 1;
666 
667     if (((current_pos[-5] & ~((1 << (offset + 1)) - 1)) != 0)
668         ||
669         current_pos[-4] != 0
670         ||
671         current_pos[-3] != 0
672         ||
673         current_pos[-2] != 0
674         || ((current_pos[-1] & ((1 << (offset + 1)) - 1)) != 0)
675         ) {
676       break;
677     }
678 
679     size += 1;
680 
681     current_pos -= 5;
682 
683   }
684 
685   /* Give ourselves a chance to recover if we went back too far by using
686    * the size check. */
687   for (ii = 0; ii < 2; ii++) {
688     if (offset > 4) {
689       size_check = (current_pos[0] >> (offset - 5)) & 0x3F;
690     } else {
691       /* mask part of byte from current_pos */
692       size_check = (current_pos[0] & ((1 << (offset + 1)) - 1));
693       /* shift to appropriate position */
694       size_check <<= (5 - offset);
695       /* or in part of byte from current_pos - 1 */
696       size_check |= (current_pos[-1] & ~((1 << (offset + 3)) - 1)) >>
697           (offset + 3);
698     }
699 
700     size_check += 1;
701     if (size_check == size) {
702       break;
703     }
704     offset = (offset + 1) % 8;
705     if (offset == 0)
706       current_pos += 1;
707     current_pos += 5;
708     size -= 1;
709   }
710 
711   /* Store mode size information in our info struct */
712   i = -1;
713   while ((1 << (++i)) < size);
714   enc->vorbis_log2_num_modes = i;
715 
716   mode_size_ptr = enc->vorbis_mode_sizes;
717 
718   for (i = 0; i < size; i++) {
719     offset = (offset + 1) % 8;
720     if (offset == 0)
721       current_pos += 1;
722     *mode_size_ptr++ = (current_pos[0] >> offset) & 0x1;
723     current_pos += 5;
724   }
725 
726 }
727 
728 static GstBuffer *
gst_vorbis_enc_buffer_from_header_packet(GstVorbisEnc * vorbisenc,ogg_packet * packet)729 gst_vorbis_enc_buffer_from_header_packet (GstVorbisEnc * vorbisenc,
730     ogg_packet * packet)
731 {
732   GstBuffer *outbuf;
733 
734   if (packet->bytes > 0 && packet->packet[0] == '\001') {
735     parse_vorbis_header_packet (vorbisenc, packet);
736   } else if (packet->bytes > 0 && packet->packet[0] == '\005') {
737     parse_vorbis_codebooks_packet (vorbisenc, packet);
738   }
739 
740   outbuf =
741       gst_audio_encoder_allocate_output_buffer (GST_AUDIO_ENCODER (vorbisenc),
742       packet->bytes);
743   gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
744   GST_BUFFER_OFFSET (outbuf) = 0;
745   GST_BUFFER_OFFSET_END (outbuf) = 0;
746   GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
747   GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
748   GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_HEADER);
749 
750   GST_DEBUG ("created header packet buffer, %" G_GSIZE_FORMAT " bytes",
751       gst_buffer_get_size (outbuf));
752   return outbuf;
753 }
754 
755 static gboolean
gst_vorbis_enc_sink_event(GstAudioEncoder * enc,GstEvent * event)756 gst_vorbis_enc_sink_event (GstAudioEncoder * enc, GstEvent * event)
757 {
758   GstVorbisEnc *vorbisenc;
759 
760   vorbisenc = GST_VORBISENC (enc);
761 
762   switch (GST_EVENT_TYPE (event)) {
763     case GST_EVENT_TAG:
764       if (vorbisenc->tags) {
765         GstTagList *list;
766 
767         gst_event_parse_tag (event, &list);
768         gst_tag_list_insert (vorbisenc->tags, list,
769             gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (vorbisenc)));
770       } else {
771         g_assert_not_reached ();
772       }
773       break;
774       /* fall through */
775     default:
776       break;
777   }
778 
779   /* we only peeked, let base class handle it */
780   return GST_AUDIO_ENCODER_CLASS (parent_class)->sink_event (enc, event);
781 }
782 
783 /*
784  * (really really) FIXME: move into core (dixit tpm)
785  */
786 /*
787  * _gst_caps_set_buffer_array:
788  * @caps: (transfer full): a #GstCaps
789  * @field: field in caps to set
790  * @buf: header buffers
791  *
792  * Adds given buffers to an array of buffers set as the given @field
793  * on the given @caps.  List of buffer arguments must be NULL-terminated.
794  *
795  * Returns: (transfer full): input caps with a streamheader field added, or NULL
796  *     if some error occurred
797  */
798 static GstCaps *
_gst_caps_set_buffer_array(GstCaps * caps,const gchar * field,GstBuffer * buf,...)799 _gst_caps_set_buffer_array (GstCaps * caps, const gchar * field,
800     GstBuffer * buf, ...)
801 {
802   GstStructure *structure = NULL;
803   va_list va;
804   GValue array = { 0 };
805   GValue value = { 0 };
806 
807   g_return_val_if_fail (caps != NULL, NULL);
808   g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
809   g_return_val_if_fail (field != NULL, NULL);
810 
811   caps = gst_caps_make_writable (caps);
812   structure = gst_caps_get_structure (caps, 0);
813 
814   g_value_init (&array, GST_TYPE_ARRAY);
815 
816   va_start (va, buf);
817   /* put buffers in a fixed list */
818   while (buf) {
819     g_value_init (&value, GST_TYPE_BUFFER);
820     gst_value_set_buffer (&value, buf);
821     gst_value_array_append_value (&array, &value);
822     g_value_unset (&value);
823 
824     buf = va_arg (va, GstBuffer *);
825   }
826   va_end (va);
827 
828   gst_structure_take_value (structure, field, &array);
829 
830   return caps;
831 }
832 
833 static GstFlowReturn
gst_vorbis_enc_handle_frame(GstAudioEncoder * enc,GstBuffer * buffer)834 gst_vorbis_enc_handle_frame (GstAudioEncoder * enc, GstBuffer * buffer)
835 {
836   GstVorbisEnc *vorbisenc;
837   GstFlowReturn ret = GST_FLOW_OK;
838   GstMapInfo map;
839   gfloat *ptr;
840   gulong size;
841   gulong i, j;
842   float **vorbis_buffer;
843   GstBuffer *buf1, *buf2, *buf3;
844 
845   vorbisenc = GST_VORBISENC (enc);
846 
847   if (G_UNLIKELY (!vorbisenc->setup)) {
848     if (buffer) {
849       GST_DEBUG_OBJECT (vorbisenc, "forcing setup");
850       /* should not fail, as setup before same way */
851       if (!gst_vorbis_enc_setup (vorbisenc))
852         return GST_FLOW_ERROR;
853     } else {
854       /* end draining */
855       GST_LOG_OBJECT (vorbisenc, "already drained");
856       return GST_FLOW_OK;
857     }
858   }
859 
860   if (!vorbisenc->header_sent) {
861     /* Vorbis streams begin with three headers; the initial header (with
862        most of the codec setup parameters) which is mandated by the Ogg
863        bitstream spec.  The second header holds any comment fields.  The
864        third header holds the bitstream codebook.  We merely need to
865        make the headers, then pass them to libvorbis one at a time;
866        libvorbis handles the additional Ogg bitstream constraints */
867     ogg_packet header;
868     ogg_packet header_comm;
869     ogg_packet header_code;
870     GstCaps *caps;
871     GList *headers;
872 
873     GST_DEBUG_OBJECT (vorbisenc, "creating and sending header packets");
874     gst_vorbis_enc_set_metadata (vorbisenc);
875     vorbis_analysis_headerout (&vorbisenc->vd, &vorbisenc->vc, &header,
876         &header_comm, &header_code);
877     vorbis_comment_clear (&vorbisenc->vc);
878 
879     /* create header buffers */
880     buf1 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header);
881     buf2 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_comm);
882     buf3 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_code);
883 
884     /* mark and put on caps */
885     caps = gst_caps_new_simple ("audio/x-vorbis",
886         "rate", G_TYPE_INT, vorbisenc->frequency,
887         "channels", G_TYPE_INT, vorbisenc->channels, NULL);
888     caps = _gst_caps_set_buffer_array (caps, "streamheader",
889         buf1, buf2, buf3, NULL);
890 
891     /* negotiate with these caps */
892     GST_DEBUG_OBJECT (vorbisenc, "here are the caps: %" GST_PTR_FORMAT, caps);
893     gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (vorbisenc), caps);
894     gst_caps_unref (caps);
895 
896     /* store buffers for later pre_push sending */
897     headers = NULL;
898     GST_DEBUG_OBJECT (vorbisenc, "storing header buffers");
899     headers = g_list_prepend (headers, buf3);
900     headers = g_list_prepend (headers, buf2);
901     headers = g_list_prepend (headers, buf1);
902     gst_audio_encoder_set_headers (enc, headers);
903 
904     vorbisenc->header_sent = TRUE;
905   }
906 
907   if (!buffer)
908     return gst_vorbis_enc_clear (vorbisenc);
909 
910   gst_buffer_map (buffer, &map, GST_MAP_READ);
911 
912   /* data to encode */
913   size = map.size / (vorbisenc->channels * sizeof (float));
914   ptr = (gfloat *) map.data;
915 
916   /* expose the buffer to submit data */
917   vorbis_buffer = vorbis_analysis_buffer (&vorbisenc->vd, size);
918 
919   /* deinterleave samples, write the buffer data */
920   if (vorbisenc->channels < 2 || vorbisenc->channels > 8) {
921     for (i = 0; i < size; i++) {
922       for (j = 0; j < vorbisenc->channels; j++) {
923         vorbis_buffer[j][i] = *ptr++;
924       }
925     }
926   } else {
927     gint i, j;
928 
929     /* Reorder */
930     for (i = 0; i < size; i++) {
931       for (j = 0; j < vorbisenc->channels; j++) {
932         vorbis_buffer[gst_vorbis_reorder_map[vorbisenc->channels - 1][j]][i] =
933             ptr[j];
934       }
935       ptr += vorbisenc->channels;
936     }
937   }
938 
939   /* tell the library how much we actually submitted */
940   vorbis_analysis_wrote (&vorbisenc->vd, size);
941   gst_buffer_unmap (buffer, &map);
942 
943   GST_LOG_OBJECT (vorbisenc, "wrote %lu samples to vorbis", size);
944 
945   ret = gst_vorbis_enc_output_buffers (vorbisenc);
946 
947   return ret;
948 }
949 
950 static GstFlowReturn
gst_vorbis_enc_output_buffers(GstVorbisEnc * vorbisenc)951 gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc)
952 {
953   GstFlowReturn ret;
954   gint64 duration;
955 
956   /* vorbis does some data preanalysis, then divides up blocks for
957      more involved (potentially parallel) processing.  Get a single
958      block for encoding now */
959   while (vorbis_analysis_blockout (&vorbisenc->vd, &vorbisenc->vb) == 1) {
960     ogg_packet op;
961 
962     GST_LOG_OBJECT (vorbisenc, "analysed to a block");
963 
964     /* analysis */
965     vorbis_analysis (&vorbisenc->vb, NULL);
966     vorbis_bitrate_addblock (&vorbisenc->vb);
967 
968     while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &op)) {
969       GstBuffer *buf;
970 
971       GST_LOG_OBJECT (vorbisenc, "pushing out a data packet");
972       buf =
973           gst_audio_encoder_allocate_output_buffer (GST_AUDIO_ENCODER
974           (vorbisenc), op.bytes);
975       gst_buffer_fill (buf, 0, op.packet, op.bytes);
976 
977       /* we have to call this every packet, not just on e_o_s, since
978          each packet's duration depends on the previous one's */
979       duration = packet_duration_vorbis (vorbisenc, &op);
980       if (op.e_o_s) {
981         gint64 samples = op.granulepos - vorbisenc->samples_out;
982         if (samples < duration) {
983           gint64 trim_end = duration - samples;
984           GST_DEBUG_OBJECT (vorbisenc,
985               "Adding trim-end %" G_GUINT64_FORMAT, trim_end);
986           gst_buffer_add_audio_clipping_meta (buf, GST_FORMAT_DEFAULT, 0,
987               trim_end);
988         }
989       }
990       /* tracking granulepos should tell us samples accounted for */
991       ret =
992           gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER
993           (vorbisenc), buf, op.granulepos - vorbisenc->samples_out);
994       vorbisenc->samples_out = op.granulepos;
995 
996       if (ret != GST_FLOW_OK)
997         return ret;
998     }
999   }
1000 
1001   return GST_FLOW_OK;
1002 }
1003 
1004 static void
gst_vorbis_enc_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)1005 gst_vorbis_enc_get_property (GObject * object, guint prop_id, GValue * value,
1006     GParamSpec * pspec)
1007 {
1008   GstVorbisEnc *vorbisenc;
1009 
1010   g_return_if_fail (GST_IS_VORBISENC (object));
1011 
1012   vorbisenc = GST_VORBISENC (object);
1013 
1014   switch (prop_id) {
1015     case ARG_MAX_BITRATE:
1016       g_value_set_int (value, vorbisenc->max_bitrate);
1017       break;
1018     case ARG_BITRATE:
1019       g_value_set_int (value, vorbisenc->bitrate);
1020       break;
1021     case ARG_MIN_BITRATE:
1022       g_value_set_int (value, vorbisenc->min_bitrate);
1023       break;
1024     case ARG_QUALITY:
1025       g_value_set_float (value, vorbisenc->quality);
1026       break;
1027     case ARG_MANAGED:
1028       g_value_set_boolean (value, vorbisenc->managed);
1029       break;
1030     case ARG_LAST_MESSAGE:
1031       g_value_set_string (value, vorbisenc->last_message);
1032       break;
1033     default:
1034       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1035       break;
1036   }
1037 }
1038 
1039 static void
gst_vorbis_enc_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)1040 gst_vorbis_enc_set_property (GObject * object, guint prop_id,
1041     const GValue * value, GParamSpec * pspec)
1042 {
1043   GstVorbisEnc *vorbisenc;
1044 
1045   g_return_if_fail (GST_IS_VORBISENC (object));
1046 
1047   vorbisenc = GST_VORBISENC (object);
1048 
1049   switch (prop_id) {
1050     case ARG_MAX_BITRATE:
1051     {
1052       gboolean old_value = vorbisenc->managed;
1053 
1054       vorbisenc->max_bitrate = g_value_get_int (value);
1055       if (vorbisenc->max_bitrate >= 0
1056           && vorbisenc->max_bitrate < LOWEST_BITRATE) {
1057         g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1058         vorbisenc->max_bitrate = LOWEST_BITRATE;
1059       }
1060       if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
1061         vorbisenc->managed = TRUE;
1062       else
1063         vorbisenc->managed = FALSE;
1064 
1065       if (old_value != vorbisenc->managed)
1066         g_object_notify (object, "managed");
1067       break;
1068     }
1069     case ARG_BITRATE:
1070       vorbisenc->bitrate = g_value_get_int (value);
1071       if (vorbisenc->bitrate >= 0 && vorbisenc->bitrate < LOWEST_BITRATE) {
1072         g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1073         vorbisenc->bitrate = LOWEST_BITRATE;
1074       }
1075       break;
1076     case ARG_MIN_BITRATE:
1077     {
1078       gboolean old_value = vorbisenc->managed;
1079 
1080       vorbisenc->min_bitrate = g_value_get_int (value);
1081       if (vorbisenc->min_bitrate >= 0
1082           && vorbisenc->min_bitrate < LOWEST_BITRATE) {
1083         g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1084         vorbisenc->min_bitrate = LOWEST_BITRATE;
1085       }
1086       if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
1087         vorbisenc->managed = TRUE;
1088       else
1089         vorbisenc->managed = FALSE;
1090 
1091       if (old_value != vorbisenc->managed)
1092         g_object_notify (object, "managed");
1093       break;
1094     }
1095     case ARG_QUALITY:
1096       vorbisenc->quality = g_value_get_float (value);
1097       if (vorbisenc->quality >= 0.0)
1098         vorbisenc->quality_set = TRUE;
1099       else
1100         vorbisenc->quality_set = FALSE;
1101       break;
1102     case ARG_MANAGED:
1103       vorbisenc->managed = g_value_get_boolean (value);
1104       break;
1105     default:
1106       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1107       break;
1108   }
1109 }
1110