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., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, 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 -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 -v alsasrc ! audioconvert ! vorbisenc ! oggmux ! filesink location=alsasrc.ogg
37 * ]| Record from a sound card using ALSA and encode to Ogg/Vorbis.
40 * Last reviewed on 2006-03-01 (0.10.4)
49 #include <vorbis/vorbisenc.h>
51 #include <gst/gsttagsetter.h>
52 #include <gst/tag/tag.h>
53 #include <gst/audio/multichannel.h>
54 #include <gst/audio/audio.h>
55 #include "gstvorbisenc.h"
57 #include "gstvorbiscommon.h"
59 GST_DEBUG_CATEGORY_EXTERN (vorbisenc_debug);
60 #define GST_CAT_DEFAULT vorbisenc_debug
62 static GstStaticPadTemplate vorbis_enc_sink_factory =
63 GST_STATIC_PAD_TEMPLATE ("sink",
66 GST_STATIC_CAPS ("audio/x-raw-float, "
67 "rate = (int) [ 1, 200000 ], "
68 "channels = (int) [ 1, 256 ], " "endianness = (int) BYTE_ORDER, "
72 static GstStaticPadTemplate vorbis_enc_src_factory =
73 GST_STATIC_PAD_TEMPLATE ("src",
76 GST_STATIC_CAPS ("audio/x-vorbis")
90 static GstFlowReturn gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc);
92 /* this function takes into account the granulepos_offset and the subgranule
95 granulepos_to_timestamp_offset (GstVorbisEnc * vorbisenc,
96 ogg_int64_t granulepos)
99 return gst_util_uint64_scale ((guint64) granulepos
100 + vorbisenc->granulepos_offset, GST_SECOND, vorbisenc->frequency)
101 + vorbisenc->subgranule_offset;
102 return GST_CLOCK_TIME_NONE;
105 /* this function does a straight granulepos -> timestamp conversion */
107 granulepos_to_timestamp (GstVorbisEnc * vorbisenc, ogg_int64_t granulepos)
110 return gst_util_uint64_scale ((guint64) granulepos,
111 GST_SECOND, vorbisenc->frequency);
112 return GST_CLOCK_TIME_NONE;
115 #define MAX_BITRATE_DEFAULT -1
116 #define BITRATE_DEFAULT -1
117 #define MIN_BITRATE_DEFAULT -1
118 #define QUALITY_DEFAULT 0.3
119 #define LOWEST_BITRATE 6000 /* lowest allowed for a 8 kHz stream */
120 #define HIGHEST_BITRATE 250001 /* highest allowed for a 44 kHz stream */
122 static gboolean gst_vorbis_enc_sink_event (GstPad * pad, GstEvent * event);
123 static GstFlowReturn gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer);
124 static gboolean gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc);
126 static void gst_vorbis_enc_dispose (GObject * object);
127 static void gst_vorbis_enc_get_property (GObject * object, guint prop_id,
128 GValue * value, GParamSpec * pspec);
129 static void gst_vorbis_enc_set_property (GObject * object, guint prop_id,
130 const GValue * value, GParamSpec * pspec);
131 static GstStateChangeReturn gst_vorbis_enc_change_state (GstElement * element,
132 GstStateChange transition);
133 static void gst_vorbis_enc_add_interfaces (GType vorbisenc_type);
135 #define gst_vorbis_enc_parent_class parent_class
136 G_DEFINE_TYPE_WITH_CODE (GstVorbisEnc, gst_vorbis_enc,
137 GST_TYPE_ELEMENT, gst_vorbis_enc_add_interfaces (g_define_type_id));
140 gst_vorbis_enc_add_interfaces (GType vorbisenc_type)
142 static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL };
143 static const GInterfaceInfo preset_info = { NULL, NULL, NULL };
145 g_type_add_interface_static (vorbisenc_type, GST_TYPE_TAG_SETTER,
147 g_type_add_interface_static (vorbisenc_type, GST_TYPE_PRESET, &preset_info);
151 gst_vorbis_enc_class_init (GstVorbisEncClass * klass)
153 GObjectClass *gobject_class;
154 GstElementClass *gstelement_class;
156 gobject_class = (GObjectClass *) klass;
157 gstelement_class = (GstElementClass *) klass;
159 gobject_class->set_property = gst_vorbis_enc_set_property;
160 gobject_class->get_property = gst_vorbis_enc_get_property;
161 gobject_class->dispose = gst_vorbis_enc_dispose;
163 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BITRATE,
164 g_param_spec_int ("max-bitrate", "Maximum Bitrate",
165 "Specify a maximum bitrate (in bps). Useful for streaming "
166 "applications. (-1 == disabled)",
167 -1, HIGHEST_BITRATE, MAX_BITRATE_DEFAULT,
168 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
169 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
170 g_param_spec_int ("bitrate", "Target Bitrate",
171 "Attempt to encode at a bitrate averaging this (in bps). "
172 "This uses the bitrate management engine, and is not recommended for most users. "
173 "Quality is a better alternative. (-1 == disabled)", -1,
174 HIGHEST_BITRATE, BITRATE_DEFAULT,
175 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
176 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MIN_BITRATE,
177 g_param_spec_int ("min-bitrate", "Minimum Bitrate",
178 "Specify a minimum bitrate (in bps). Useful for encoding for a "
179 "fixed-size channel. (-1 == disabled)", -1, HIGHEST_BITRATE,
180 MIN_BITRATE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
181 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
182 g_param_spec_float ("quality", "Quality",
183 "Specify quality instead of specifying a particular bitrate.", -0.1,
184 1.0, QUALITY_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
185 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MANAGED,
186 g_param_spec_boolean ("managed", "Managed",
187 "Enable bitrate management engine", FALSE,
188 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
189 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
190 g_param_spec_string ("last-message", "last-message",
191 "The last status message", NULL,
192 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
194 gst_element_class_add_pad_template (gstelement_class,
195 gst_static_pad_template_get (&vorbis_enc_src_factory));
196 gst_element_class_add_pad_template (gstelement_class,
197 gst_static_pad_template_get (&vorbis_enc_sink_factory));
198 gst_element_class_set_details_simple (gstelement_class,
199 "Vorbis audio encoder", "Codec/Encoder/Audio",
200 "Encodes audio in Vorbis format",
201 "Monty <monty@xiph.org>, " "Wim Taymans <wim@fluendo.com>");
203 gstelement_class->change_state =
204 GST_DEBUG_FUNCPTR (gst_vorbis_enc_change_state);
208 gst_vorbis_enc_dispose (GObject * object)
210 GstVorbisEnc *vorbisenc = GST_VORBISENC (object);
212 if (vorbisenc->sinkcaps) {
213 gst_caps_unref (vorbisenc->sinkcaps);
214 vorbisenc->sinkcaps = NULL;
217 G_OBJECT_CLASS (parent_class)->dispose (object);
221 gst_vorbis_enc_generate_sink_caps (void)
223 GstCaps *caps = gst_caps_new_empty ();
226 gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw-float",
227 "rate", GST_TYPE_INT_RANGE, 1, 200000,
228 "channels", G_TYPE_INT, 1,
229 "endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32,
232 gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw-float",
233 "rate", GST_TYPE_INT_RANGE, 1, 200000,
234 "channels", G_TYPE_INT, 2,
235 "endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32,
238 for (i = 3; i <= 8; i++) {
239 GValue chanpos = { 0 };
241 GstStructure *structure;
243 g_value_init (&chanpos, GST_TYPE_ARRAY);
244 g_value_init (&pos, GST_TYPE_AUDIO_CHANNEL_POSITION);
246 for (c = 0; c < i; c++) {
247 g_value_set_enum (&pos, gst_vorbis_channel_positions[i - 1][c]);
248 gst_value_array_append_value (&chanpos, &pos);
250 g_value_unset (&pos);
252 structure = gst_structure_new ("audio/x-raw-float",
253 "rate", GST_TYPE_INT_RANGE, 1, 200000,
254 "channels", G_TYPE_INT, i,
255 "endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32, NULL);
256 gst_structure_set_value (structure, "channel-positions", &chanpos);
257 g_value_unset (&chanpos);
259 gst_caps_append_structure (caps, structure);
262 gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw-float",
263 "rate", GST_TYPE_INT_RANGE, 1, 200000,
264 "channels", GST_TYPE_INT_RANGE, 9, 256,
265 "endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32,
272 gst_vorbis_enc_sink_getcaps (GstPad * pad, GstCaps * filter)
274 GstVorbisEnc *vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
276 if (vorbisenc->sinkcaps == NULL)
277 vorbisenc->sinkcaps = gst_vorbis_enc_generate_sink_caps ();
280 return gst_caps_intersect_full (filter, vorbisenc->sinkcaps,
281 GST_CAPS_INTERSECT_FIRST);
283 return gst_caps_ref (vorbisenc->sinkcaps);
287 gst_vorbis_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
289 GstVorbisEnc *vorbisenc;
290 GstStructure *structure;
292 vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
293 vorbisenc->setup = FALSE;
295 structure = gst_caps_get_structure (caps, 0);
296 gst_structure_get_int (structure, "channels", &vorbisenc->channels);
297 gst_structure_get_int (structure, "rate", &vorbisenc->frequency);
299 gst_vorbis_enc_setup (vorbisenc);
301 if (vorbisenc->setup)
308 gst_vorbis_enc_convert_src (GstPad * pad, GstFormat src_format,
309 gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
312 GstVorbisEnc *vorbisenc;
315 vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
317 if (vorbisenc->samples_in == 0 ||
318 vorbisenc->bytes_out == 0 || vorbisenc->frequency == 0) {
319 gst_object_unref (vorbisenc);
323 avg = (vorbisenc->bytes_out * vorbisenc->frequency) / (vorbisenc->samples_in);
325 switch (src_format) {
326 case GST_FORMAT_BYTES:
327 switch (*dest_format) {
328 case GST_FORMAT_TIME:
329 *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND, avg);
335 case GST_FORMAT_TIME:
336 switch (*dest_format) {
337 case GST_FORMAT_BYTES:
338 *dest_value = gst_util_uint64_scale_int (src_value, avg, GST_SECOND);
347 gst_object_unref (vorbisenc);
352 gst_vorbis_enc_convert_sink (GstPad * pad, GstFormat src_format,
353 gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
357 gint bytes_per_sample;
358 GstVorbisEnc *vorbisenc;
360 vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
362 bytes_per_sample = vorbisenc->channels * 2;
364 switch (src_format) {
365 case GST_FORMAT_BYTES:
366 switch (*dest_format) {
367 case GST_FORMAT_DEFAULT:
368 if (bytes_per_sample == 0)
370 *dest_value = src_value / bytes_per_sample;
372 case GST_FORMAT_TIME:
374 gint byterate = bytes_per_sample * vorbisenc->frequency;
379 gst_util_uint64_scale_int (src_value, GST_SECOND, byterate);
386 case GST_FORMAT_DEFAULT:
387 switch (*dest_format) {
388 case GST_FORMAT_BYTES:
389 *dest_value = src_value * bytes_per_sample;
391 case GST_FORMAT_TIME:
392 if (vorbisenc->frequency == 0)
395 gst_util_uint64_scale_int (src_value, GST_SECOND,
396 vorbisenc->frequency);
402 case GST_FORMAT_TIME:
403 switch (*dest_format) {
404 case GST_FORMAT_BYTES:
405 scale = bytes_per_sample;
407 case GST_FORMAT_DEFAULT:
409 gst_util_uint64_scale_int (src_value,
410 scale * vorbisenc->frequency, GST_SECOND);
419 gst_object_unref (vorbisenc);
424 gst_vorbis_enc_get_latency (GstVorbisEnc * vorbisenc)
426 /* FIXME, this probably depends on the bitrate and other setting but for now
427 * we return this value, which was obtained by totally unscientific
429 return 58 * GST_MSECOND;
432 static const GstQueryType *
433 gst_vorbis_enc_get_query_types (GstPad * pad)
435 static const GstQueryType gst_vorbis_enc_src_query_types[] = {
442 return gst_vorbis_enc_src_query_types;
446 gst_vorbis_enc_src_query (GstPad * pad, GstQuery * query)
449 GstVorbisEnc *vorbisenc;
452 vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
453 peerpad = gst_pad_get_peer (GST_PAD (vorbisenc->sinkpad));
455 switch (GST_QUERY_TYPE (query)) {
456 case GST_QUERY_POSITION:
458 GstFormat fmt, req_fmt;
461 gst_query_parse_position (query, &req_fmt, NULL);
462 if ((res = gst_pad_query_position (peerpad, &req_fmt, &val))) {
463 gst_query_set_position (query, req_fmt, val);
467 fmt = GST_FORMAT_TIME;
468 if (!(res = gst_pad_query_position (peerpad, &fmt, &pos)))
471 if ((res = gst_pad_query_convert (peerpad, fmt, pos, &req_fmt, &val))) {
472 gst_query_set_position (query, req_fmt, val);
476 case GST_QUERY_DURATION:
478 GstFormat fmt, req_fmt;
481 gst_query_parse_duration (query, &req_fmt, NULL);
482 if ((res = gst_pad_query_duration (peerpad, &req_fmt, &val))) {
483 gst_query_set_duration (query, req_fmt, val);
487 fmt = GST_FORMAT_TIME;
488 if (!(res = gst_pad_query_duration (peerpad, &fmt, &dur)))
491 if ((res = gst_pad_query_convert (peerpad, fmt, dur, &req_fmt, &val))) {
492 gst_query_set_duration (query, req_fmt, val);
496 case GST_QUERY_CONVERT:
498 GstFormat src_fmt, dest_fmt;
499 gint64 src_val, dest_val;
501 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
503 gst_vorbis_enc_convert_src (pad, src_fmt, src_val, &dest_fmt,
506 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
509 case GST_QUERY_LATENCY:
512 GstClockTime min_latency, max_latency;
515 if ((res = gst_pad_query (peerpad, query))) {
516 gst_query_parse_latency (query, &live, &min_latency, &max_latency);
518 latency = gst_vorbis_enc_get_latency (vorbisenc);
520 /* add our latency */
521 min_latency += latency;
522 if (max_latency != -1)
523 max_latency += latency;
525 gst_query_set_latency (query, live, min_latency, max_latency);
530 res = gst_pad_query (peerpad, query);
535 gst_object_unref (peerpad);
536 gst_object_unref (vorbisenc);
541 gst_vorbis_enc_sink_query (GstPad * pad, GstQuery * query)
545 switch (GST_QUERY_TYPE (query)) {
546 case GST_QUERY_CONVERT:
548 GstFormat src_fmt, dest_fmt;
549 gint64 src_val, dest_val;
551 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
553 gst_vorbis_enc_convert_sink (pad, src_fmt, src_val, &dest_fmt,
556 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
560 res = gst_pad_query_default (pad, query);
569 gst_vorbis_enc_init (GstVorbisEnc * vorbisenc)
572 gst_pad_new_from_static_template (&vorbis_enc_sink_factory, "sink");
573 gst_pad_set_event_function (vorbisenc->sinkpad,
574 GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_event));
575 gst_pad_set_chain_function (vorbisenc->sinkpad,
576 GST_DEBUG_FUNCPTR (gst_vorbis_enc_chain));
577 gst_pad_set_setcaps_function (vorbisenc->sinkpad,
578 GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_setcaps));
579 gst_pad_set_getcaps_function (vorbisenc->sinkpad,
580 GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_getcaps));
581 gst_pad_set_query_function (vorbisenc->sinkpad,
582 GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_query));
583 gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->sinkpad);
586 gst_pad_new_from_static_template (&vorbis_enc_src_factory, "src");
587 gst_pad_set_query_function (vorbisenc->srcpad,
588 GST_DEBUG_FUNCPTR (gst_vorbis_enc_src_query));
589 gst_pad_set_query_type_function (vorbisenc->srcpad,
590 GST_DEBUG_FUNCPTR (gst_vorbis_enc_get_query_types));
591 gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->srcpad);
593 vorbisenc->channels = -1;
594 vorbisenc->frequency = -1;
596 vorbisenc->managed = FALSE;
597 vorbisenc->max_bitrate = MAX_BITRATE_DEFAULT;
598 vorbisenc->bitrate = BITRATE_DEFAULT;
599 vorbisenc->min_bitrate = MIN_BITRATE_DEFAULT;
600 vorbisenc->quality = QUALITY_DEFAULT;
601 vorbisenc->quality_set = FALSE;
602 vorbisenc->last_message = NULL;
606 gst_vorbis_enc_metadata_set1 (const GstTagList * list, const gchar * tag,
609 GstVorbisEnc *enc = GST_VORBISENC (vorbisenc);
612 vc_list = gst_tag_to_vorbis_comments (list, tag);
614 for (l = vc_list; l != NULL; l = l->next) {
615 const gchar *vc_string = (const gchar *) l->data;
616 gchar *key = NULL, *val = NULL;
618 GST_LOG_OBJECT (vorbisenc, "vorbis comment: %s", vc_string);
619 if (gst_tag_parse_extended_comment (vc_string, &key, NULL, &val, TRUE)) {
620 vorbis_comment_add_tag (&enc->vc, key, val);
626 g_list_foreach (vc_list, (GFunc) g_free, NULL);
627 g_list_free (vc_list);
631 gst_vorbis_enc_set_metadata (GstVorbisEnc * enc)
633 GstTagList *merged_tags;
634 const GstTagList *user_tags;
636 vorbis_comment_init (&enc->vc);
638 user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (enc));
640 GST_DEBUG_OBJECT (enc, "upstream tags = %" GST_PTR_FORMAT, enc->tags);
641 GST_DEBUG_OBJECT (enc, "user-set tags = %" GST_PTR_FORMAT, user_tags);
643 /* gst_tag_list_merge() will handle NULL for either or both lists fine */
644 merged_tags = gst_tag_list_merge (user_tags, enc->tags,
645 gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (enc)));
648 GST_DEBUG_OBJECT (enc, "merged tags = %" GST_PTR_FORMAT, merged_tags);
649 gst_tag_list_foreach (merged_tags, gst_vorbis_enc_metadata_set1, enc);
650 gst_tag_list_free (merged_tags);
655 get_constraints_string (GstVorbisEnc * vorbisenc)
657 gint min = vorbisenc->min_bitrate;
658 gint max = vorbisenc->max_bitrate;
661 if (min > 0 && max > 0)
662 result = g_strdup_printf ("(min %d bps, max %d bps)", min, max);
664 result = g_strdup_printf ("(min %d bps, no max)", min);
666 result = g_strdup_printf ("(no min, max %d bps)", max);
668 result = g_strdup_printf ("(no min or max)");
674 update_start_message (GstVorbisEnc * vorbisenc)
678 g_free (vorbisenc->last_message);
680 if (vorbisenc->bitrate > 0) {
681 if (vorbisenc->managed) {
682 constraints = get_constraints_string (vorbisenc);
683 vorbisenc->last_message =
684 g_strdup_printf ("encoding at average bitrate %d bps %s",
685 vorbisenc->bitrate, constraints);
686 g_free (constraints);
688 vorbisenc->last_message =
690 ("encoding at approximate bitrate %d bps (VBR encoding enabled)",
694 if (vorbisenc->quality_set) {
695 if (vorbisenc->managed) {
696 constraints = get_constraints_string (vorbisenc);
697 vorbisenc->last_message =
699 ("encoding at quality level %2.2f using constrained VBR %s",
700 vorbisenc->quality, constraints);
701 g_free (constraints);
703 vorbisenc->last_message =
704 g_strdup_printf ("encoding at quality level %2.2f",
708 constraints = get_constraints_string (vorbisenc);
709 vorbisenc->last_message =
710 g_strdup_printf ("encoding using bitrate management %s", constraints);
711 g_free (constraints);
715 g_object_notify (G_OBJECT (vorbisenc), "last_message");
719 gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc)
721 vorbisenc->setup = FALSE;
723 if (vorbisenc->bitrate < 0 && vorbisenc->min_bitrate < 0
724 && vorbisenc->max_bitrate < 0) {
725 vorbisenc->quality_set = TRUE;
728 update_start_message (vorbisenc);
730 /* choose an encoding mode */
731 /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
732 vorbis_info_init (&vorbisenc->vi);
734 if (vorbisenc->quality_set) {
735 if (vorbis_encode_setup_vbr (&vorbisenc->vi,
736 vorbisenc->channels, vorbisenc->frequency,
737 vorbisenc->quality) != 0) {
738 GST_ERROR_OBJECT (vorbisenc,
739 "vorbisenc: initialisation failed: invalid parameters for quality");
740 vorbis_info_clear (&vorbisenc->vi);
744 /* do we have optional hard quality restrictions? */
745 if (vorbisenc->max_bitrate > 0 || vorbisenc->min_bitrate > 0) {
746 struct ovectl_ratemanage_arg ai;
748 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_GET, &ai);
750 ai.bitrate_hard_min = vorbisenc->min_bitrate;
751 ai.bitrate_hard_max = vorbisenc->max_bitrate;
752 ai.management_active = 1;
754 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, &ai);
757 long min_bitrate, max_bitrate;
759 min_bitrate = vorbisenc->min_bitrate > 0 ? vorbisenc->min_bitrate : -1;
760 max_bitrate = vorbisenc->max_bitrate > 0 ? vorbisenc->max_bitrate : -1;
762 if (vorbis_encode_setup_managed (&vorbisenc->vi,
764 vorbisenc->frequency,
765 max_bitrate, vorbisenc->bitrate, min_bitrate) != 0) {
766 GST_ERROR_OBJECT (vorbisenc,
767 "vorbis_encode_setup_managed "
768 "(c %d, rate %d, max br %ld, br %d, min br %ld) failed",
769 vorbisenc->channels, vorbisenc->frequency, max_bitrate,
770 vorbisenc->bitrate, min_bitrate);
771 vorbis_info_clear (&vorbisenc->vi);
776 if (vorbisenc->managed && vorbisenc->bitrate < 0) {
777 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_AVG, NULL);
778 } else if (!vorbisenc->managed) {
779 /* Turn off management entirely (if it was turned on). */
780 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, NULL);
782 vorbis_encode_setup_init (&vorbisenc->vi);
784 /* set up the analysis state and auxiliary encoding storage */
785 vorbis_analysis_init (&vorbisenc->vd, &vorbisenc->vi);
786 vorbis_block_init (&vorbisenc->vd, &vorbisenc->vb);
788 vorbisenc->next_ts = 0;
790 vorbisenc->setup = TRUE;
796 gst_vorbis_enc_clear (GstVorbisEnc * vorbisenc)
798 GstFlowReturn ret = GST_FLOW_OK;
800 if (vorbisenc->setup) {
801 vorbis_analysis_wrote (&vorbisenc->vd, 0);
802 ret = gst_vorbis_enc_output_buffers (vorbisenc);
804 vorbisenc->setup = FALSE;
807 /* clean up and exit. vorbis_info_clear() must be called last */
808 vorbis_block_clear (&vorbisenc->vb);
809 vorbis_dsp_clear (&vorbisenc->vd);
810 vorbis_info_clear (&vorbisenc->vi);
812 vorbisenc->header_sent = FALSE;
817 /* prepare a buffer for transmission by passing data through libvorbis */
819 gst_vorbis_enc_buffer_from_packet (GstVorbisEnc * vorbisenc,
824 outbuf = gst_buffer_new_and_alloc (packet->bytes);
825 gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
826 /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
827 * time representation */
828 GST_BUFFER_OFFSET_END (outbuf) = packet->granulepos +
829 vorbisenc->granulepos_offset;
830 GST_BUFFER_OFFSET (outbuf) = granulepos_to_timestamp (vorbisenc,
831 GST_BUFFER_OFFSET_END (outbuf));
832 GST_BUFFER_TIMESTAMP (outbuf) = vorbisenc->next_ts;
834 /* update the next timestamp, taking granulepos_offset and subgranule offset
837 granulepos_to_timestamp_offset (vorbisenc, packet->granulepos);
838 GST_BUFFER_DURATION (outbuf) =
839 vorbisenc->next_ts - GST_BUFFER_TIMESTAMP (outbuf);
841 if (vorbisenc->next_discont) {
842 GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
843 vorbisenc->next_discont = FALSE;
846 GST_LOG_OBJECT (vorbisenc, "encoded buffer of %d bytes",
847 gst_buffer_get_size (outbuf));
851 /* the same as above, but different logic for setting timestamp and granulepos
854 gst_vorbis_enc_buffer_from_header_packet (GstVorbisEnc * vorbisenc,
859 outbuf = gst_buffer_new_and_alloc (packet->bytes);
860 gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
861 GST_BUFFER_OFFSET (outbuf) = vorbisenc->bytes_out;
862 GST_BUFFER_OFFSET_END (outbuf) = 0;
863 GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
864 GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
866 GST_DEBUG ("created header packet buffer, %d bytes",
867 gst_buffer_get_size (outbuf));
871 /* push out the buffer and do internal bookkeeping */
873 gst_vorbis_enc_push_buffer (GstVorbisEnc * vorbisenc, GstBuffer * buffer)
875 vorbisenc->bytes_out += gst_buffer_get_size (buffer);
877 GST_DEBUG_OBJECT (vorbisenc,
878 "Pushing buffer with GP %" G_GINT64_FORMAT ", ts %" GST_TIME_FORMAT,
879 GST_BUFFER_OFFSET_END (buffer),
880 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
881 return gst_pad_push (vorbisenc->srcpad, buffer);
885 gst_vorbis_enc_push_packet (GstVorbisEnc * vorbisenc, ogg_packet * packet)
889 outbuf = gst_vorbis_enc_buffer_from_packet (vorbisenc, packet);
890 return gst_vorbis_enc_push_buffer (vorbisenc, outbuf);
893 /* Set a copy of these buffers as 'streamheader' on the caps.
894 * We need a copy to avoid these buffers ending up with (indirect) refs on
898 gst_vorbis_enc_set_header_on_caps (GstCaps * caps, GstBuffer * buf1,
899 GstBuffer * buf2, GstBuffer * buf3)
902 GstStructure *structure;
903 GValue array = { 0 };
904 GValue value = { 0 };
906 caps = gst_caps_make_writable (caps);
907 structure = gst_caps_get_structure (caps, 0);
910 GST_BUFFER_FLAG_SET (buf1, GST_BUFFER_FLAG_IN_CAPS);
911 GST_BUFFER_FLAG_SET (buf2, GST_BUFFER_FLAG_IN_CAPS);
912 GST_BUFFER_FLAG_SET (buf3, GST_BUFFER_FLAG_IN_CAPS);
914 /* put buffers in a fixed list */
915 g_value_init (&array, GST_TYPE_ARRAY);
916 g_value_init (&value, GST_TYPE_BUFFER);
917 buf = gst_buffer_copy (buf1);
918 gst_value_set_buffer (&value, buf);
919 gst_buffer_unref (buf);
920 gst_value_array_append_value (&array, &value);
921 g_value_unset (&value);
922 g_value_init (&value, GST_TYPE_BUFFER);
923 buf = gst_buffer_copy (buf2);
924 gst_value_set_buffer (&value, buf);
925 gst_buffer_unref (buf);
926 gst_value_array_append_value (&array, &value);
927 g_value_unset (&value);
928 g_value_init (&value, GST_TYPE_BUFFER);
929 buf = gst_buffer_copy (buf3);
930 gst_value_set_buffer (&value, buf);
931 gst_buffer_unref (buf);
932 gst_value_array_append_value (&array, &value);
933 gst_structure_set_value (structure, "streamheader", &array);
934 g_value_unset (&value);
935 g_value_unset (&array);
941 gst_vorbis_enc_sink_event (GstPad * pad, GstEvent * event)
944 GstVorbisEnc *vorbisenc;
946 vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
948 switch (GST_EVENT_TYPE (event)) {
950 /* Tell the library we're at end of stream so that it can handle
951 * the last frame and mark end of stream in the output properly */
952 GST_DEBUG_OBJECT (vorbisenc, "EOS, clearing state and sending event on");
953 gst_vorbis_enc_clear (vorbisenc);
955 res = gst_pad_push_event (vorbisenc->srcpad, event);
958 if (vorbisenc->tags) {
961 gst_event_parse_tag (event, &list);
962 gst_tag_list_insert (vorbisenc->tags, list,
963 gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (vorbisenc)));
965 g_assert_not_reached ();
967 res = gst_pad_push_event (vorbisenc->srcpad, event);
969 case GST_EVENT_SEGMENT:
971 const GstSegment *segment;
973 gst_event_parse_segment (event, &segment);
975 if (segment->format == GST_FORMAT_TIME) {
976 gst_segment_copy_into (segment, &vorbisenc->segment);
981 res = gst_pad_push_event (vorbisenc->srcpad, event);
988 gst_vorbis_enc_buffer_check_discontinuous (GstVorbisEnc * vorbisenc,
989 GstClockTime timestamp, GstClockTime duration)
991 gboolean ret = FALSE;
993 GST_DEBUG_OBJECT (vorbisenc, "exp %" GST_TIME_FORMAT " time %" GST_TIME_FORMAT
994 "dur %" GST_TIME_FORMAT, GST_TIME_ARGS (vorbisenc->expected_ts),
995 GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration));
997 if (timestamp != GST_CLOCK_TIME_NONE &&
998 vorbisenc->expected_ts != GST_CLOCK_TIME_NONE &&
999 timestamp + duration != vorbisenc->expected_ts) {
1000 /* It turns out that a lot of elements don't generate perfect streams due
1001 * to rounding errors. So, we permit small errors (< 1/2 a sample) without
1002 * causing a discont.
1004 int halfsample = GST_SECOND / vorbisenc->frequency / 2;
1006 if ((GstClockTimeDiff) (timestamp - vorbisenc->expected_ts) > halfsample) {
1007 GST_DEBUG_OBJECT (vorbisenc, "Expected TS %" GST_TIME_FORMAT
1008 ", buffer TS %" GST_TIME_FORMAT,
1009 GST_TIME_ARGS (vorbisenc->expected_ts), GST_TIME_ARGS (timestamp));
1014 if (timestamp != GST_CLOCK_TIME_NONE && duration != GST_CLOCK_TIME_NONE) {
1015 vorbisenc->expected_ts = timestamp + duration;
1017 vorbisenc->expected_ts = GST_CLOCK_TIME_NONE;
1022 static GstFlowReturn
1023 gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
1025 GstVorbisEnc *vorbisenc;
1026 GstFlowReturn ret = GST_FLOW_OK;
1030 float **vorbis_buffer;
1031 GstBuffer *buf1, *buf2, *buf3;
1032 gboolean first = FALSE;
1033 GstClockTime timestamp = GST_CLOCK_TIME_NONE;
1034 GstClockTime running_time = GST_CLOCK_TIME_NONE;
1037 vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
1039 if (!vorbisenc->setup)
1042 buffer = gst_audio_buffer_clip (buffer, &vorbisenc->segment,
1043 vorbisenc->frequency, 4 * vorbisenc->channels);
1044 if (buffer == NULL) {
1045 GST_DEBUG_OBJECT (vorbisenc, "Dropping buffer, out of segment");
1049 gst_segment_to_running_time (&vorbisenc->segment, GST_FORMAT_TIME,
1050 GST_BUFFER_TIMESTAMP (buffer));
1051 timestamp = running_time;
1052 GST_DEBUG_OBJECT (vorbisenc, " timestamp %" GST_TIME_FORMAT,
1053 GST_TIME_ARGS (timestamp));
1054 if (!vorbisenc->header_sent) {
1055 /* Vorbis streams begin with three headers; the initial header (with
1056 most of the codec setup parameters) which is mandated by the Ogg
1057 bitstream spec. The second header holds any comment fields. The
1058 third header holds the bitstream codebook. We merely need to
1059 make the headers, then pass them to libvorbis one at a time;
1060 libvorbis handles the additional Ogg bitstream constraints */
1062 ogg_packet header_comm;
1063 ogg_packet header_code;
1066 /* first, make sure header buffers get timestamp == 0 */
1067 vorbisenc->next_ts = 0;
1068 vorbisenc->granulepos_offset = 0;
1069 vorbisenc->subgranule_offset = 0;
1071 GST_DEBUG_OBJECT (vorbisenc, "creating and sending header packets");
1072 gst_vorbis_enc_set_metadata (vorbisenc);
1073 vorbis_analysis_headerout (&vorbisenc->vd, &vorbisenc->vc, &header,
1074 &header_comm, &header_code);
1075 vorbis_comment_clear (&vorbisenc->vc);
1077 /* create header buffers */
1078 buf1 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header);
1079 buf2 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_comm);
1080 buf3 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_code);
1082 /* mark and put on caps */
1083 vorbisenc->srccaps = gst_caps_new_simple ("audio/x-vorbis", NULL);
1084 caps = vorbisenc->srccaps;
1085 caps = gst_vorbis_enc_set_header_on_caps (caps, buf1, buf2, buf3);
1087 /* negotiate with these caps */
1088 GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
1089 gst_pad_set_caps (vorbisenc->srcpad, caps);
1091 /* push out buffers */
1092 /* push_buffer takes the reference even for failure */
1093 if ((ret = gst_vorbis_enc_push_buffer (vorbisenc, buf1)) != GST_FLOW_OK)
1094 goto failed_header_push;
1095 if ((ret = gst_vorbis_enc_push_buffer (vorbisenc, buf2)) != GST_FLOW_OK) {
1097 goto failed_header_push;
1099 if ((ret = gst_vorbis_enc_push_buffer (vorbisenc, buf3)) != GST_FLOW_OK) {
1101 goto failed_header_push;
1104 /* now adjust starting granulepos accordingly if the buffer's timestamp is
1106 vorbisenc->next_ts = timestamp;
1107 vorbisenc->expected_ts = timestamp;
1108 vorbisenc->granulepos_offset = gst_util_uint64_scale
1109 (running_time, vorbisenc->frequency, GST_SECOND);
1110 vorbisenc->subgranule_offset = 0;
1111 vorbisenc->subgranule_offset =
1112 vorbisenc->next_ts - granulepos_to_timestamp_offset (vorbisenc, 0);
1114 vorbisenc->header_sent = TRUE;
1118 if (vorbisenc->expected_ts != GST_CLOCK_TIME_NONE &&
1119 timestamp < vorbisenc->expected_ts) {
1120 guint64 diff = vorbisenc->expected_ts - timestamp;
1124 GST_WARNING_OBJECT (vorbisenc, "Buffer is older than previous "
1125 "timestamp + duration (%" GST_TIME_FORMAT "< %" GST_TIME_FORMAT
1126 "), cannot handle. Clipping buffer.",
1127 GST_TIME_ARGS (timestamp), GST_TIME_ARGS (vorbisenc->expected_ts));
1129 size = gst_buffer_get_size (buffer);
1132 GST_CLOCK_TIME_TO_FRAMES (diff,
1133 vorbisenc->frequency) * vorbisenc->channels * sizeof (gfloat);
1134 if (diff_bytes >= size) {
1135 gst_buffer_unref (buffer);
1138 buffer = gst_buffer_make_writable (buffer);
1139 gst_buffer_resize (buffer, diff_bytes, size - diff_bytes);
1141 GST_BUFFER_TIMESTAMP (buffer) += diff;
1142 if (GST_BUFFER_DURATION_IS_VALID (buffer))
1143 GST_BUFFER_DURATION (buffer) -= diff;
1146 if (gst_vorbis_enc_buffer_check_discontinuous (vorbisenc, timestamp,
1147 GST_BUFFER_DURATION (buffer)) && !first) {
1148 GST_WARNING_OBJECT (vorbisenc,
1149 "Buffer is discontinuous, flushing encoder "
1150 "and restarting (Discont from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT
1151 ")", GST_TIME_ARGS (vorbisenc->next_ts), GST_TIME_ARGS (timestamp));
1152 /* Re-initialise encoder (there's unfortunately no API to flush it) */
1153 if ((ret = gst_vorbis_enc_clear (vorbisenc)) != GST_FLOW_OK)
1155 if (!gst_vorbis_enc_setup (vorbisenc))
1156 return GST_FLOW_ERROR; /* Should be impossible, we can only get here if
1157 we successfully initialised earlier */
1159 /* Now, set our granulepos offset appropriately. */
1160 vorbisenc->next_ts = timestamp;
1161 /* We need to round to the nearest whole number of samples, not just do
1162 * a truncating division here */
1163 vorbisenc->granulepos_offset = gst_util_uint64_scale
1164 (running_time + GST_SECOND / vorbisenc->frequency / 2
1165 - vorbisenc->subgranule_offset, vorbisenc->frequency, GST_SECOND);
1167 vorbisenc->header_sent = TRUE;
1169 /* And our next output buffer must have DISCONT set on it */
1170 vorbisenc->next_discont = TRUE;
1173 /* Sending zero samples to libvorbis marks EOS, so we mustn't do that */
1174 data = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_WRITE);
1176 gst_buffer_unmap (buffer, data, bsize);
1177 gst_buffer_unref (buffer);
1181 /* data to encode */
1182 size = bsize / (vorbisenc->channels * sizeof (float));
1186 /* expose the buffer to submit data */
1187 vorbis_buffer = vorbis_analysis_buffer (&vorbisenc->vd, size);
1189 /* deinterleave samples, write the buffer data */
1190 for (i = 0; i < size; i++) {
1191 for (j = 0; j < vorbisenc->channels; j++) {
1192 vorbis_buffer[j][i] = *ptr++;
1196 /* tell the library how much we actually submitted */
1197 vorbis_analysis_wrote (&vorbisenc->vd, size);
1198 gst_buffer_unmap (buffer, data, bsize);
1200 GST_LOG_OBJECT (vorbisenc, "wrote %lu samples to vorbis", size);
1202 vorbisenc->samples_in += size;
1204 gst_buffer_unref (buffer);
1206 ret = gst_vorbis_enc_output_buffers (vorbisenc);
1213 gst_buffer_unref (buffer);
1214 GST_ELEMENT_ERROR (vorbisenc, CORE, NEGOTIATION, (NULL),
1215 ("encoder not initialized (input is not audio?)"));
1216 return GST_FLOW_UNEXPECTED;
1220 GST_WARNING_OBJECT (vorbisenc, "Failed to push headers");
1221 /* buf1 is always already unreffed */
1223 gst_buffer_unref (buf2);
1225 gst_buffer_unref (buf3);
1226 gst_buffer_unref (buffer);
1231 static GstFlowReturn
1232 gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc)
1236 /* vorbis does some data preanalysis, then divides up blocks for
1237 more involved (potentially parallel) processing. Get a single
1238 block for encoding now */
1239 while (vorbis_analysis_blockout (&vorbisenc->vd, &vorbisenc->vb) == 1) {
1242 GST_LOG_OBJECT (vorbisenc, "analysed to a block");
1245 vorbis_analysis (&vorbisenc->vb, NULL);
1246 vorbis_bitrate_addblock (&vorbisenc->vb);
1248 while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &op)) {
1249 GST_LOG_OBJECT (vorbisenc, "pushing out a data packet");
1250 ret = gst_vorbis_enc_push_packet (vorbisenc, &op);
1252 if (ret != GST_FLOW_OK)
1261 gst_vorbis_enc_get_property (GObject * object, guint prop_id, GValue * value,
1264 GstVorbisEnc *vorbisenc;
1266 g_return_if_fail (GST_IS_VORBISENC (object));
1268 vorbisenc = GST_VORBISENC (object);
1271 case ARG_MAX_BITRATE:
1272 g_value_set_int (value, vorbisenc->max_bitrate);
1275 g_value_set_int (value, vorbisenc->bitrate);
1277 case ARG_MIN_BITRATE:
1278 g_value_set_int (value, vorbisenc->min_bitrate);
1281 g_value_set_float (value, vorbisenc->quality);
1284 g_value_set_boolean (value, vorbisenc->managed);
1286 case ARG_LAST_MESSAGE:
1287 g_value_set_string (value, vorbisenc->last_message);
1290 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1296 gst_vorbis_enc_set_property (GObject * object, guint prop_id,
1297 const GValue * value, GParamSpec * pspec)
1299 GstVorbisEnc *vorbisenc;
1301 g_return_if_fail (GST_IS_VORBISENC (object));
1303 vorbisenc = GST_VORBISENC (object);
1306 case ARG_MAX_BITRATE:
1308 gboolean old_value = vorbisenc->managed;
1310 vorbisenc->max_bitrate = g_value_get_int (value);
1311 if (vorbisenc->max_bitrate >= 0
1312 && vorbisenc->max_bitrate < LOWEST_BITRATE) {
1313 g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1314 vorbisenc->max_bitrate = LOWEST_BITRATE;
1316 if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
1317 vorbisenc->managed = TRUE;
1319 vorbisenc->managed = FALSE;
1321 if (old_value != vorbisenc->managed)
1322 g_object_notify (object, "managed");
1326 vorbisenc->bitrate = g_value_get_int (value);
1327 if (vorbisenc->bitrate >= 0 && vorbisenc->bitrate < LOWEST_BITRATE) {
1328 g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1329 vorbisenc->bitrate = LOWEST_BITRATE;
1332 case ARG_MIN_BITRATE:
1334 gboolean old_value = vorbisenc->managed;
1336 vorbisenc->min_bitrate = g_value_get_int (value);
1337 if (vorbisenc->min_bitrate >= 0
1338 && vorbisenc->min_bitrate < LOWEST_BITRATE) {
1339 g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1340 vorbisenc->min_bitrate = LOWEST_BITRATE;
1342 if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
1343 vorbisenc->managed = TRUE;
1345 vorbisenc->managed = FALSE;
1347 if (old_value != vorbisenc->managed)
1348 g_object_notify (object, "managed");
1352 vorbisenc->quality = g_value_get_float (value);
1353 if (vorbisenc->quality >= 0.0)
1354 vorbisenc->quality_set = TRUE;
1356 vorbisenc->quality_set = FALSE;
1359 vorbisenc->managed = g_value_get_boolean (value);
1362 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1367 static GstStateChangeReturn
1368 gst_vorbis_enc_change_state (GstElement * element, GstStateChange transition)
1370 GstVorbisEnc *vorbisenc = GST_VORBISENC (element);
1371 GstStateChangeReturn res;
1374 switch (transition) {
1375 case GST_STATE_CHANGE_NULL_TO_READY:
1376 vorbisenc->tags = gst_tag_list_new ();
1378 case GST_STATE_CHANGE_READY_TO_PAUSED:
1379 vorbisenc->setup = FALSE;
1380 vorbisenc->next_discont = FALSE;
1381 vorbisenc->header_sent = FALSE;
1382 gst_segment_init (&vorbisenc->segment, GST_FORMAT_TIME);
1384 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1390 res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1392 switch (transition) {
1393 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1395 case GST_STATE_CHANGE_PAUSED_TO_READY:
1396 vorbis_block_clear (&vorbisenc->vb);
1397 vorbis_dsp_clear (&vorbisenc->vd);
1398 vorbis_info_clear (&vorbisenc->vi);
1399 g_free (vorbisenc->last_message);
1400 vorbisenc->last_message = NULL;
1401 if (vorbisenc->srccaps) {
1402 gst_caps_unref (vorbisenc->srccaps);
1403 vorbisenc->srccaps = NULL;
1406 case GST_STATE_CHANGE_READY_TO_NULL:
1407 gst_tag_list_free (vorbisenc->tags);
1408 vorbisenc->tags = NULL;