2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
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.
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.
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.
21 * SECTION:element-vorbisenc
22 * @see_also: vorbisdec, oggmux
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
30 * <title>Example pipelines</title>
32 * gst-launch-1.0 -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.
36 * gst-launch-1.0 -v autoaudiosrc ! audioconvert ! vorbisenc ! oggmux ! filesink location=alsasrc.ogg
37 * ]| Record from a sound card and encode to Ogg/Vorbis.
47 #include <vorbis/vorbisenc.h>
49 #include <gst/gsttagsetter.h>
50 #include <gst/tag/tag.h>
51 #include <gst/audio/audio.h>
52 #include "gstvorbisenc.h"
54 #include "gstvorbiscommon.h"
56 GST_DEBUG_CATEGORY_EXTERN (vorbisenc_debug);
57 #define GST_CAT_DEFAULT vorbisenc_debug
59 static GstStaticPadTemplate vorbis_enc_src_factory =
60 GST_STATIC_PAD_TEMPLATE ("src",
63 GST_STATIC_CAPS ("audio/x-vorbis, "
64 "rate = (int) [ 1, 200000 ], " "channels = (int) [ 1, 255 ]")
78 static GstFlowReturn gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc);
79 static GstCaps *gst_vorbis_enc_generate_sink_caps (void);
82 #define MAX_BITRATE_DEFAULT -1
83 #define BITRATE_DEFAULT -1
84 #define MIN_BITRATE_DEFAULT -1
85 #define QUALITY_DEFAULT 0.3
86 #define LOWEST_BITRATE 6000 /* lowest allowed for a 8 kHz stream */
87 #define HIGHEST_BITRATE 250001 /* highest allowed for a 44 kHz stream */
89 static gboolean gst_vorbis_enc_start (GstAudioEncoder * enc);
90 static gboolean gst_vorbis_enc_stop (GstAudioEncoder * enc);
91 static gboolean gst_vorbis_enc_set_format (GstAudioEncoder * enc,
93 static GstFlowReturn gst_vorbis_enc_handle_frame (GstAudioEncoder * enc,
95 static gboolean gst_vorbis_enc_sink_event (GstAudioEncoder * enc,
98 static gboolean gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc);
100 static void gst_vorbis_enc_dispose (GObject * object);
101 static void gst_vorbis_enc_get_property (GObject * object, guint prop_id,
102 GValue * value, GParamSpec * pspec);
103 static void gst_vorbis_enc_set_property (GObject * object, guint prop_id,
104 const GValue * value, GParamSpec * pspec);
105 static void gst_vorbis_enc_flush (GstAudioEncoder * vorbisenc);
107 #define gst_vorbis_enc_parent_class parent_class
108 G_DEFINE_TYPE_WITH_CODE (GstVorbisEnc, gst_vorbis_enc,
109 GST_TYPE_AUDIO_ENCODER, G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL));
112 gst_vorbis_enc_class_init (GstVorbisEncClass * klass)
114 GObjectClass *gobject_class;
115 GstElementClass *gstelement_class;
116 GstAudioEncoderClass *base_class;
118 GstPadTemplate *sink_templ;
120 gobject_class = (GObjectClass *) klass;
121 gstelement_class = (GstElementClass *) klass;
122 base_class = (GstAudioEncoderClass *) (klass);
124 gobject_class->set_property = gst_vorbis_enc_set_property;
125 gobject_class->get_property = gst_vorbis_enc_get_property;
126 gobject_class->dispose = gst_vorbis_enc_dispose;
128 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BITRATE,
129 g_param_spec_int ("max-bitrate", "Maximum Bitrate",
130 "Specify a maximum bitrate (in bps). Useful for streaming "
131 "applications. (-1 == disabled)",
132 -1, HIGHEST_BITRATE, MAX_BITRATE_DEFAULT,
133 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
134 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
135 g_param_spec_int ("bitrate", "Target Bitrate",
136 "Attempt to encode at a bitrate averaging this (in bps). "
137 "This uses the bitrate management engine, and is not recommended for most users. "
138 "Quality is a better alternative. (-1 == disabled)", -1,
139 HIGHEST_BITRATE, BITRATE_DEFAULT,
140 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
141 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MIN_BITRATE,
142 g_param_spec_int ("min-bitrate", "Minimum Bitrate",
143 "Specify a minimum bitrate (in bps). Useful for encoding for a "
144 "fixed-size channel. (-1 == disabled)", -1, HIGHEST_BITRATE,
145 MIN_BITRATE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
146 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
147 g_param_spec_float ("quality", "Quality",
148 "Specify quality instead of specifying a particular bitrate.", -0.1,
149 1.0, QUALITY_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
150 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MANAGED,
151 g_param_spec_boolean ("managed", "Managed",
152 "Enable bitrate management engine", FALSE,
153 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
154 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
155 g_param_spec_string ("last-message", "last-message",
156 "The last status message", NULL,
157 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
159 sink_caps = gst_vorbis_enc_generate_sink_caps ();
160 sink_templ = gst_pad_template_new ("sink",
161 GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps);
162 gst_element_class_add_pad_template (gstelement_class, sink_templ);
163 gst_caps_unref (sink_caps);
165 gst_element_class_add_static_pad_template (gstelement_class,
166 &vorbis_enc_src_factory);
168 gst_element_class_set_static_metadata (gstelement_class,
169 "Vorbis audio encoder", "Codec/Encoder/Audio",
170 "Encodes audio in Vorbis format",
171 "Monty <monty@xiph.org>, " "Wim Taymans <wim@fluendo.com>");
173 base_class->start = GST_DEBUG_FUNCPTR (gst_vorbis_enc_start);
174 base_class->stop = GST_DEBUG_FUNCPTR (gst_vorbis_enc_stop);
175 base_class->set_format = GST_DEBUG_FUNCPTR (gst_vorbis_enc_set_format);
176 base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vorbis_enc_handle_frame);
177 base_class->sink_event = GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_event);
178 base_class->flush = GST_DEBUG_FUNCPTR (gst_vorbis_enc_flush);
182 gst_vorbis_enc_init (GstVorbisEnc * vorbisenc)
184 GstAudioEncoder *enc = GST_AUDIO_ENCODER (vorbisenc);
186 GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_ENCODER_SINK_PAD (enc));
188 vorbisenc->channels = -1;
189 vorbisenc->frequency = -1;
191 vorbisenc->managed = FALSE;
192 vorbisenc->max_bitrate = MAX_BITRATE_DEFAULT;
193 vorbisenc->bitrate = BITRATE_DEFAULT;
194 vorbisenc->min_bitrate = MIN_BITRATE_DEFAULT;
195 vorbisenc->quality = QUALITY_DEFAULT;
196 vorbisenc->quality_set = FALSE;
197 vorbisenc->last_message = NULL;
199 /* arrange granulepos marking (and required perfect ts) */
200 gst_audio_encoder_set_mark_granule (enc, TRUE);
201 gst_audio_encoder_set_perfect_timestamp (enc, TRUE);
205 gst_vorbis_enc_dispose (GObject * object)
207 GstVorbisEnc *vorbisenc = GST_VORBISENC (object);
209 if (vorbisenc->sinkcaps) {
210 gst_caps_unref (vorbisenc->sinkcaps);
211 vorbisenc->sinkcaps = NULL;
214 G_OBJECT_CLASS (parent_class)->dispose (object);
218 gst_vorbis_enc_start (GstAudioEncoder * enc)
220 GstVorbisEnc *vorbisenc = GST_VORBISENC (enc);
222 GST_DEBUG_OBJECT (enc, "start");
223 vorbisenc->tags = gst_tag_list_new_empty ();
224 vorbisenc->header_sent = FALSE;
230 gst_vorbis_enc_stop (GstAudioEncoder * enc)
232 GstVorbisEnc *vorbisenc = GST_VORBISENC (enc);
234 GST_DEBUG_OBJECT (enc, "stop");
235 vorbis_block_clear (&vorbisenc->vb);
236 vorbis_dsp_clear (&vorbisenc->vd);
237 vorbis_info_clear (&vorbisenc->vi);
238 g_free (vorbisenc->last_message);
239 vorbisenc->last_message = NULL;
240 gst_tag_list_unref (vorbisenc->tags);
241 vorbisenc->tags = NULL;
243 gst_tag_setter_reset_tags (GST_TAG_SETTER (enc));
249 gst_vorbis_enc_generate_sink_caps (void)
251 GstCaps *caps = gst_caps_new_empty ();
254 gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
255 "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
256 "layout", G_TYPE_STRING, "interleaved",
257 "rate", GST_TYPE_INT_RANGE, 1, 200000,
258 "channels", G_TYPE_INT, 1, NULL));
260 for (i = 2; i <= 8; i++) {
261 GstStructure *structure;
262 guint64 channel_mask = 0;
263 const GstAudioChannelPosition *pos = gst_vorbis_channel_positions[i - 1];
265 for (c = 0; c < i; c++) {
266 channel_mask |= G_GUINT64_CONSTANT (1) << pos[c];
269 structure = gst_structure_new ("audio/x-raw",
270 "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
271 "layout", G_TYPE_STRING, "interleaved",
272 "rate", GST_TYPE_INT_RANGE, 1, 200000, "channels", G_TYPE_INT, i,
273 "channel-mask", GST_TYPE_BITMASK, channel_mask, NULL);
275 gst_caps_append_structure (caps, structure);
278 gst_caps_append_structure (caps, 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,
282 "channels", GST_TYPE_INT_RANGE, 9, 255,
283 "channel-mask", GST_TYPE_BITMASK, G_GUINT64_CONSTANT (0), NULL));
289 gst_vorbis_enc_get_latency (GstVorbisEnc * vorbisenc)
291 /* FIXME, this probably depends on the bitrate and other setting but for now
292 * we return this value, which was obtained by totally unscientific
294 return 58 * GST_MSECOND;
298 gst_vorbis_enc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
300 GstVorbisEnc *vorbisenc;
302 vorbisenc = GST_VORBISENC (enc);
304 vorbisenc->channels = GST_AUDIO_INFO_CHANNELS (info);
305 vorbisenc->frequency = GST_AUDIO_INFO_RATE (info);
307 /* if re-configured, we were drained and cleared already */
308 if (!gst_vorbis_enc_setup (vorbisenc))
311 /* feedback to base class */
312 gst_audio_encoder_set_latency (enc,
313 gst_vorbis_enc_get_latency (vorbisenc),
314 gst_vorbis_enc_get_latency (vorbisenc));
320 gst_vorbis_enc_metadata_set1 (const GstTagList * list, const gchar * tag,
323 GstVorbisEnc *enc = GST_VORBISENC (vorbisenc);
326 vc_list = gst_tag_to_vorbis_comments (list, tag);
328 for (l = vc_list; l != NULL; l = l->next) {
329 const gchar *vc_string = (const gchar *) l->data;
330 gchar *key = NULL, *val = NULL;
332 GST_LOG_OBJECT (vorbisenc, "vorbis comment: %s", vc_string);
333 if (gst_tag_parse_extended_comment (vc_string, &key, NULL, &val, TRUE)) {
334 vorbis_comment_add_tag (&enc->vc, key, val);
340 g_list_foreach (vc_list, (GFunc) g_free, NULL);
341 g_list_free (vc_list);
345 gst_vorbis_enc_set_metadata (GstVorbisEnc * enc)
347 GstTagList *merged_tags;
348 const GstTagList *user_tags;
350 vorbis_comment_init (&enc->vc);
352 user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (enc));
354 GST_DEBUG_OBJECT (enc, "upstream tags = %" GST_PTR_FORMAT, enc->tags);
355 GST_DEBUG_OBJECT (enc, "user-set tags = %" GST_PTR_FORMAT, user_tags);
357 /* gst_tag_list_merge() will handle NULL for either or both lists fine */
358 merged_tags = gst_tag_list_merge (user_tags, enc->tags,
359 gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (enc)));
362 GST_DEBUG_OBJECT (enc, "merged tags = %" GST_PTR_FORMAT, merged_tags);
363 gst_tag_list_foreach (merged_tags, gst_vorbis_enc_metadata_set1, enc);
364 gst_tag_list_unref (merged_tags);
369 get_constraints_string (GstVorbisEnc * vorbisenc)
371 gint min = vorbisenc->min_bitrate;
372 gint max = vorbisenc->max_bitrate;
375 if (min > 0 && max > 0)
376 result = g_strdup_printf ("(min %d bps, max %d bps)", min, max);
378 result = g_strdup_printf ("(min %d bps, no max)", min);
380 result = g_strdup_printf ("(no min, max %d bps)", max);
382 result = g_strdup_printf ("(no min or max)");
388 update_start_message (GstVorbisEnc * vorbisenc)
392 g_free (vorbisenc->last_message);
394 if (vorbisenc->bitrate > 0) {
395 if (vorbisenc->managed) {
396 constraints = get_constraints_string (vorbisenc);
397 vorbisenc->last_message =
398 g_strdup_printf ("encoding at average bitrate %d bps %s",
399 vorbisenc->bitrate, constraints);
400 g_free (constraints);
402 vorbisenc->last_message =
404 ("encoding at approximate bitrate %d bps (VBR encoding enabled)",
408 if (vorbisenc->quality_set) {
409 if (vorbisenc->managed) {
410 constraints = get_constraints_string (vorbisenc);
411 vorbisenc->last_message =
413 ("encoding at quality level %2.2f using constrained VBR %s",
414 vorbisenc->quality, constraints);
415 g_free (constraints);
417 vorbisenc->last_message =
418 g_strdup_printf ("encoding at quality level %2.2f",
422 constraints = get_constraints_string (vorbisenc);
423 vorbisenc->last_message =
424 g_strdup_printf ("encoding using bitrate management %s", constraints);
425 g_free (constraints);
429 g_object_notify (G_OBJECT (vorbisenc), "last_message");
433 gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc)
436 GST_LOG_OBJECT (vorbisenc, "setup");
438 if (vorbisenc->bitrate < 0 && vorbisenc->min_bitrate < 0
439 && vorbisenc->max_bitrate < 0) {
440 vorbisenc->quality_set = TRUE;
443 update_start_message (vorbisenc);
445 /* choose an encoding mode */
446 /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
447 vorbis_info_init (&vorbisenc->vi);
449 if (vorbisenc->quality_set) {
450 if (vorbis_encode_setup_vbr (&vorbisenc->vi,
451 vorbisenc->channels, vorbisenc->frequency,
452 vorbisenc->quality) != 0) {
453 GST_ERROR_OBJECT (vorbisenc,
454 "vorbisenc: initialisation failed: invalid parameters for quality");
455 vorbis_info_clear (&vorbisenc->vi);
459 /* do we have optional hard quality restrictions? */
460 if (vorbisenc->max_bitrate > 0 || vorbisenc->min_bitrate > 0) {
461 struct ovectl_ratemanage_arg ai;
463 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_GET, &ai);
465 ai.bitrate_hard_min = vorbisenc->min_bitrate;
466 ai.bitrate_hard_max = vorbisenc->max_bitrate;
467 ai.management_active = 1;
469 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, &ai);
472 long min_bitrate, max_bitrate;
474 min_bitrate = vorbisenc->min_bitrate > 0 ? vorbisenc->min_bitrate : -1;
475 max_bitrate = vorbisenc->max_bitrate > 0 ? vorbisenc->max_bitrate : -1;
477 if (vorbis_encode_setup_managed (&vorbisenc->vi,
479 vorbisenc->frequency,
480 max_bitrate, vorbisenc->bitrate, min_bitrate) != 0) {
481 GST_ERROR_OBJECT (vorbisenc,
482 "vorbis_encode_setup_managed "
483 "(c %d, rate %d, max br %ld, br %d, min br %ld) failed",
484 vorbisenc->channels, vorbisenc->frequency, max_bitrate,
485 vorbisenc->bitrate, min_bitrate);
486 vorbis_info_clear (&vorbisenc->vi);
491 if (vorbisenc->managed && vorbisenc->bitrate < 0) {
492 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_AVG, NULL);
493 } else if (!vorbisenc->managed) {
494 /* Turn off management entirely (if it was turned on). */
495 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, NULL);
497 vorbis_encode_setup_init (&vorbisenc->vi);
499 /* set up the analysis state and auxiliary encoding storage */
500 vorbis_analysis_init (&vorbisenc->vd, &vorbisenc->vi);
501 vorbis_block_init (&vorbisenc->vd, &vorbisenc->vb);
503 /* samples == granulepos start at 0 again */
504 vorbisenc->samples_out = 0;
506 /* fresh encoder available */
507 vorbisenc->setup = TRUE;
513 gst_vorbis_enc_clear (GstVorbisEnc * vorbisenc)
515 GstFlowReturn ret = GST_FLOW_OK;
517 if (vorbisenc->setup) {
518 vorbis_analysis_wrote (&vorbisenc->vd, 0);
519 ret = gst_vorbis_enc_output_buffers (vorbisenc);
521 /* marked EOS to encoder, recreate if needed */
522 vorbisenc->setup = FALSE;
525 /* clean up and exit. vorbis_info_clear() must be called last */
526 vorbis_block_clear (&vorbisenc->vb);
527 vorbis_dsp_clear (&vorbisenc->vd);
528 vorbis_info_clear (&vorbisenc->vi);
534 gst_vorbis_enc_flush (GstAudioEncoder * enc)
536 GstVorbisEnc *vorbisenc = GST_VORBISENC (enc);
538 gst_vorbis_enc_clear (vorbisenc);
539 vorbisenc->header_sent = FALSE;
543 gst_vorbis_enc_buffer_from_header_packet (GstVorbisEnc * vorbisenc,
549 gst_audio_encoder_allocate_output_buffer (GST_AUDIO_ENCODER (vorbisenc),
551 gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
552 GST_BUFFER_OFFSET (outbuf) = 0;
553 GST_BUFFER_OFFSET_END (outbuf) = 0;
554 GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
555 GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
556 GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_HEADER);
558 GST_DEBUG ("created header packet buffer, %" G_GSIZE_FORMAT " bytes",
559 gst_buffer_get_size (outbuf));
564 gst_vorbis_enc_sink_event (GstAudioEncoder * enc, GstEvent * event)
566 GstVorbisEnc *vorbisenc;
568 vorbisenc = GST_VORBISENC (enc);
570 switch (GST_EVENT_TYPE (event)) {
572 if (vorbisenc->tags) {
575 gst_event_parse_tag (event, &list);
576 gst_tag_list_insert (vorbisenc->tags, list,
577 gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (vorbisenc)));
579 g_assert_not_reached ();
587 /* we only peeked, let base class handle it */
588 return GST_AUDIO_ENCODER_CLASS (parent_class)->sink_event (enc, event);
592 * (really really) FIXME: move into core (dixit tpm)
595 * _gst_caps_set_buffer_array:
596 * @caps: (transfer full): a #GstCaps
597 * @field: field in caps to set
598 * @buf: header buffers
600 * Adds given buffers to an array of buffers set as the given @field
601 * on the given @caps. List of buffer arguments must be NULL-terminated.
603 * Returns: (transfer full): input caps with a streamheader field added, or NULL
604 * if some error occurred
607 _gst_caps_set_buffer_array (GstCaps * caps, const gchar * field,
608 GstBuffer * buf, ...)
610 GstStructure *structure = NULL;
612 GValue array = { 0 };
613 GValue value = { 0 };
615 g_return_val_if_fail (caps != NULL, NULL);
616 g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
617 g_return_val_if_fail (field != NULL, NULL);
619 caps = gst_caps_make_writable (caps);
620 structure = gst_caps_get_structure (caps, 0);
622 g_value_init (&array, GST_TYPE_ARRAY);
625 /* put buffers in a fixed list */
627 g_value_init (&value, GST_TYPE_BUFFER);
628 gst_value_set_buffer (&value, buf);
629 gst_value_array_append_value (&array, &value);
630 g_value_unset (&value);
632 buf = va_arg (va, GstBuffer *);
636 gst_structure_take_value (structure, field, &array);
642 gst_vorbis_enc_handle_frame (GstAudioEncoder * enc, GstBuffer * buffer)
644 GstVorbisEnc *vorbisenc;
645 GstFlowReturn ret = GST_FLOW_OK;
650 float **vorbis_buffer;
651 GstBuffer *buf1, *buf2, *buf3;
653 vorbisenc = GST_VORBISENC (enc);
655 if (G_UNLIKELY (!vorbisenc->setup)) {
657 GST_DEBUG_OBJECT (vorbisenc, "forcing setup");
658 /* should not fail, as setup before same way */
659 if (!gst_vorbis_enc_setup (vorbisenc))
660 return GST_FLOW_ERROR;
663 GST_LOG_OBJECT (vorbisenc, "already drained");
668 if (!vorbisenc->header_sent) {
669 /* Vorbis streams begin with three headers; the initial header (with
670 most of the codec setup parameters) which is mandated by the Ogg
671 bitstream spec. The second header holds any comment fields. The
672 third header holds the bitstream codebook. We merely need to
673 make the headers, then pass them to libvorbis one at a time;
674 libvorbis handles the additional Ogg bitstream constraints */
676 ogg_packet header_comm;
677 ogg_packet header_code;
681 GST_DEBUG_OBJECT (vorbisenc, "creating and sending header packets");
682 gst_vorbis_enc_set_metadata (vorbisenc);
683 vorbis_analysis_headerout (&vorbisenc->vd, &vorbisenc->vc, &header,
684 &header_comm, &header_code);
685 vorbis_comment_clear (&vorbisenc->vc);
687 /* create header buffers */
688 buf1 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header);
689 buf2 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_comm);
690 buf3 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_code);
692 /* mark and put on caps */
693 caps = gst_caps_new_simple ("audio/x-vorbis",
694 "rate", G_TYPE_INT, vorbisenc->frequency,
695 "channels", G_TYPE_INT, vorbisenc->channels, NULL);
696 caps = _gst_caps_set_buffer_array (caps, "streamheader",
697 buf1, buf2, buf3, NULL);
699 /* negotiate with these caps */
700 GST_DEBUG_OBJECT (vorbisenc, "here are the caps: %" GST_PTR_FORMAT, caps);
701 gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (vorbisenc), caps);
702 gst_caps_unref (caps);
704 /* store buffers for later pre_push sending */
706 GST_DEBUG_OBJECT (vorbisenc, "storing header buffers");
707 headers = g_list_prepend (headers, buf3);
708 headers = g_list_prepend (headers, buf2);
709 headers = g_list_prepend (headers, buf1);
710 gst_audio_encoder_set_headers (enc, headers);
712 vorbisenc->header_sent = TRUE;
716 return gst_vorbis_enc_clear (vorbisenc);
718 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
721 size = map.size / (vorbisenc->channels * sizeof (float));
722 ptr = (gfloat *) map.data;
724 /* expose the buffer to submit data */
725 vorbis_buffer = vorbis_analysis_buffer (&vorbisenc->vd, size);
727 /* deinterleave samples, write the buffer data */
728 if (vorbisenc->channels < 2 || vorbisenc->channels > 8) {
729 for (i = 0; i < size; i++) {
730 for (j = 0; j < vorbisenc->channels; j++) {
731 vorbis_buffer[j][i] = *ptr++;
738 for (i = 0; i < size; i++) {
739 for (j = 0; j < vorbisenc->channels; j++) {
740 vorbis_buffer[gst_vorbis_reorder_map[vorbisenc->channels - 1][j]][i] =
743 ptr += vorbisenc->channels;
747 /* tell the library how much we actually submitted */
748 vorbis_analysis_wrote (&vorbisenc->vd, size);
749 gst_buffer_unmap (buffer, &map);
751 GST_LOG_OBJECT (vorbisenc, "wrote %lu samples to vorbis", size);
753 ret = gst_vorbis_enc_output_buffers (vorbisenc);
759 gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc)
763 /* vorbis does some data preanalysis, then divides up blocks for
764 more involved (potentially parallel) processing. Get a single
765 block for encoding now */
766 while (vorbis_analysis_blockout (&vorbisenc->vd, &vorbisenc->vb) == 1) {
769 GST_LOG_OBJECT (vorbisenc, "analysed to a block");
772 vorbis_analysis (&vorbisenc->vb, NULL);
773 vorbis_bitrate_addblock (&vorbisenc->vb);
775 while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &op)) {
779 GstAudioEncoder *enc = GST_AUDIO_ENCODER (vorbisenc);
780 GstClockTime duration;
782 GST_DEBUG_OBJECT (vorbisenc, "Got EOS packet from libvorbis");
783 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
784 if (!GST_CLOCK_TIME_IS_VALID (enc->output_segment.stop)) {
785 GST_DEBUG_OBJECT (vorbisenc,
786 "Output segment has no end time, setting");
788 gst_util_uint64_scale (op.granulepos, GST_SECOND,
789 vorbisenc->frequency);
790 enc->output_segment.stop = enc->output_segment.start + duration;
791 GST_DEBUG_OBJECT (enc, "new output segment %" GST_SEGMENT_FORMAT,
792 &enc->output_segment);
793 gst_pad_push_event (GST_AUDIO_ENCODER_SRC_PAD (enc),
794 gst_event_new_segment (&enc->output_segment));
796 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
799 GST_LOG_OBJECT (vorbisenc, "pushing out a data packet");
801 gst_audio_encoder_allocate_output_buffer (GST_AUDIO_ENCODER
802 (vorbisenc), op.bytes);
803 gst_buffer_fill (buf, 0, op.packet, op.bytes);
804 /* tracking granulepos should tell us samples accounted for */
806 gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER
807 (vorbisenc), buf, op.granulepos - vorbisenc->samples_out);
808 vorbisenc->samples_out = op.granulepos;
810 if (ret != GST_FLOW_OK)
819 gst_vorbis_enc_get_property (GObject * object, guint prop_id, GValue * value,
822 GstVorbisEnc *vorbisenc;
824 g_return_if_fail (GST_IS_VORBISENC (object));
826 vorbisenc = GST_VORBISENC (object);
829 case ARG_MAX_BITRATE:
830 g_value_set_int (value, vorbisenc->max_bitrate);
833 g_value_set_int (value, vorbisenc->bitrate);
835 case ARG_MIN_BITRATE:
836 g_value_set_int (value, vorbisenc->min_bitrate);
839 g_value_set_float (value, vorbisenc->quality);
842 g_value_set_boolean (value, vorbisenc->managed);
844 case ARG_LAST_MESSAGE:
845 g_value_set_string (value, vorbisenc->last_message);
848 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
854 gst_vorbis_enc_set_property (GObject * object, guint prop_id,
855 const GValue * value, GParamSpec * pspec)
857 GstVorbisEnc *vorbisenc;
859 g_return_if_fail (GST_IS_VORBISENC (object));
861 vorbisenc = GST_VORBISENC (object);
864 case ARG_MAX_BITRATE:
866 gboolean old_value = vorbisenc->managed;
868 vorbisenc->max_bitrate = g_value_get_int (value);
869 if (vorbisenc->max_bitrate >= 0
870 && vorbisenc->max_bitrate < LOWEST_BITRATE) {
871 g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
872 vorbisenc->max_bitrate = LOWEST_BITRATE;
874 if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
875 vorbisenc->managed = TRUE;
877 vorbisenc->managed = FALSE;
879 if (old_value != vorbisenc->managed)
880 g_object_notify (object, "managed");
884 vorbisenc->bitrate = g_value_get_int (value);
885 if (vorbisenc->bitrate >= 0 && vorbisenc->bitrate < LOWEST_BITRATE) {
886 g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
887 vorbisenc->bitrate = LOWEST_BITRATE;
890 case ARG_MIN_BITRATE:
892 gboolean old_value = vorbisenc->managed;
894 vorbisenc->min_bitrate = g_value_get_int (value);
895 if (vorbisenc->min_bitrate >= 0
896 && vorbisenc->min_bitrate < LOWEST_BITRATE) {
897 g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
898 vorbisenc->min_bitrate = LOWEST_BITRATE;
900 if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
901 vorbisenc->managed = TRUE;
903 vorbisenc->managed = FALSE;
905 if (old_value != vorbisenc->managed)
906 g_object_notify (object, "managed");
910 vorbisenc->quality = g_value_get_float (value);
911 if (vorbisenc->quality >= 0.0)
912 vorbisenc->quality_set = TRUE;
914 vorbisenc->quality_set = FALSE;
917 vorbisenc->managed = g_value_get_boolean (value);
920 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);