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 (GstVorbisEnc * vorbisenc, GstCaps * caps)
289 GstStructure *structure;
291 vorbisenc->setup = FALSE;
293 structure = gst_caps_get_structure (caps, 0);
294 gst_structure_get_int (structure, "channels", &vorbisenc->channels);
295 gst_structure_get_int (structure, "rate", &vorbisenc->frequency);
297 gst_vorbis_enc_setup (vorbisenc);
299 if (vorbisenc->setup)
306 gst_vorbis_enc_convert_src (GstPad * pad, GstFormat src_format,
307 gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
310 GstVorbisEnc *vorbisenc;
313 vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
315 if (vorbisenc->samples_in == 0 ||
316 vorbisenc->bytes_out == 0 || vorbisenc->frequency == 0) {
317 gst_object_unref (vorbisenc);
321 avg = (vorbisenc->bytes_out * vorbisenc->frequency) / (vorbisenc->samples_in);
323 switch (src_format) {
324 case GST_FORMAT_BYTES:
325 switch (*dest_format) {
326 case GST_FORMAT_TIME:
327 *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND, avg);
333 case GST_FORMAT_TIME:
334 switch (*dest_format) {
335 case GST_FORMAT_BYTES:
336 *dest_value = gst_util_uint64_scale_int (src_value, avg, GST_SECOND);
345 gst_object_unref (vorbisenc);
350 gst_vorbis_enc_convert_sink (GstPad * pad, GstFormat src_format,
351 gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
355 gint bytes_per_sample;
356 GstVorbisEnc *vorbisenc;
358 vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
360 bytes_per_sample = vorbisenc->channels * 2;
362 switch (src_format) {
363 case GST_FORMAT_BYTES:
364 switch (*dest_format) {
365 case GST_FORMAT_DEFAULT:
366 if (bytes_per_sample == 0)
368 *dest_value = src_value / bytes_per_sample;
370 case GST_FORMAT_TIME:
372 gint byterate = bytes_per_sample * vorbisenc->frequency;
377 gst_util_uint64_scale_int (src_value, GST_SECOND, byterate);
384 case GST_FORMAT_DEFAULT:
385 switch (*dest_format) {
386 case GST_FORMAT_BYTES:
387 *dest_value = src_value * bytes_per_sample;
389 case GST_FORMAT_TIME:
390 if (vorbisenc->frequency == 0)
393 gst_util_uint64_scale_int (src_value, GST_SECOND,
394 vorbisenc->frequency);
400 case GST_FORMAT_TIME:
401 switch (*dest_format) {
402 case GST_FORMAT_BYTES:
403 scale = bytes_per_sample;
405 case GST_FORMAT_DEFAULT:
407 gst_util_uint64_scale_int (src_value,
408 scale * vorbisenc->frequency, GST_SECOND);
417 gst_object_unref (vorbisenc);
422 gst_vorbis_enc_get_latency (GstVorbisEnc * vorbisenc)
424 /* FIXME, this probably depends on the bitrate and other setting but for now
425 * we return this value, which was obtained by totally unscientific
427 return 58 * GST_MSECOND;
430 static const GstQueryType *
431 gst_vorbis_enc_get_query_types (GstPad * pad)
433 static const GstQueryType gst_vorbis_enc_src_query_types[] = {
440 return gst_vorbis_enc_src_query_types;
444 gst_vorbis_enc_src_query (GstPad * pad, GstQuery * query)
447 GstVorbisEnc *vorbisenc;
450 vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
451 peerpad = gst_pad_get_peer (GST_PAD (vorbisenc->sinkpad));
453 switch (GST_QUERY_TYPE (query)) {
454 case GST_QUERY_POSITION:
456 GstFormat fmt, req_fmt;
459 gst_query_parse_position (query, &req_fmt, NULL);
460 if ((res = gst_pad_query_position (peerpad, &req_fmt, &val))) {
461 gst_query_set_position (query, req_fmt, val);
465 fmt = GST_FORMAT_TIME;
466 if (!(res = gst_pad_query_position (peerpad, &fmt, &pos)))
469 if ((res = gst_pad_query_convert (peerpad, fmt, pos, &req_fmt, &val))) {
470 gst_query_set_position (query, req_fmt, val);
474 case GST_QUERY_DURATION:
476 GstFormat fmt, req_fmt;
479 gst_query_parse_duration (query, &req_fmt, NULL);
480 if ((res = gst_pad_query_duration (peerpad, &req_fmt, &val))) {
481 gst_query_set_duration (query, req_fmt, val);
485 fmt = GST_FORMAT_TIME;
486 if (!(res = gst_pad_query_duration (peerpad, &fmt, &dur)))
489 if ((res = gst_pad_query_convert (peerpad, fmt, dur, &req_fmt, &val))) {
490 gst_query_set_duration (query, req_fmt, val);
494 case GST_QUERY_CONVERT:
496 GstFormat src_fmt, dest_fmt;
497 gint64 src_val, dest_val;
499 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
501 gst_vorbis_enc_convert_src (pad, src_fmt, src_val, &dest_fmt,
504 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
507 case GST_QUERY_LATENCY:
510 GstClockTime min_latency, max_latency;
513 if ((res = gst_pad_query (peerpad, query))) {
514 gst_query_parse_latency (query, &live, &min_latency, &max_latency);
516 latency = gst_vorbis_enc_get_latency (vorbisenc);
518 /* add our latency */
519 min_latency += latency;
520 if (max_latency != -1)
521 max_latency += latency;
523 gst_query_set_latency (query, live, min_latency, max_latency);
528 res = gst_pad_query (peerpad, query);
533 gst_object_unref (peerpad);
534 gst_object_unref (vorbisenc);
539 gst_vorbis_enc_sink_query (GstPad * pad, GstQuery * query)
543 switch (GST_QUERY_TYPE (query)) {
544 case GST_QUERY_CONVERT:
546 GstFormat src_fmt, dest_fmt;
547 gint64 src_val, dest_val;
549 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
551 gst_vorbis_enc_convert_sink (pad, src_fmt, src_val, &dest_fmt,
554 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
558 res = gst_pad_query_default (pad, query);
567 gst_vorbis_enc_init (GstVorbisEnc * vorbisenc)
570 gst_pad_new_from_static_template (&vorbis_enc_sink_factory, "sink");
571 gst_pad_set_event_function (vorbisenc->sinkpad,
572 GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_event));
573 gst_pad_set_chain_function (vorbisenc->sinkpad,
574 GST_DEBUG_FUNCPTR (gst_vorbis_enc_chain));
575 gst_pad_set_getcaps_function (vorbisenc->sinkpad,
576 GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_getcaps));
577 gst_pad_set_query_function (vorbisenc->sinkpad,
578 GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_query));
579 gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->sinkpad);
582 gst_pad_new_from_static_template (&vorbis_enc_src_factory, "src");
583 gst_pad_set_query_function (vorbisenc->srcpad,
584 GST_DEBUG_FUNCPTR (gst_vorbis_enc_src_query));
585 gst_pad_set_query_type_function (vorbisenc->srcpad,
586 GST_DEBUG_FUNCPTR (gst_vorbis_enc_get_query_types));
587 gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->srcpad);
589 vorbisenc->channels = -1;
590 vorbisenc->frequency = -1;
592 vorbisenc->managed = FALSE;
593 vorbisenc->max_bitrate = MAX_BITRATE_DEFAULT;
594 vorbisenc->bitrate = BITRATE_DEFAULT;
595 vorbisenc->min_bitrate = MIN_BITRATE_DEFAULT;
596 vorbisenc->quality = QUALITY_DEFAULT;
597 vorbisenc->quality_set = FALSE;
598 vorbisenc->last_message = NULL;
602 gst_vorbis_enc_metadata_set1 (const GstTagList * list, const gchar * tag,
605 GstVorbisEnc *enc = GST_VORBISENC (vorbisenc);
608 vc_list = gst_tag_to_vorbis_comments (list, tag);
610 for (l = vc_list; l != NULL; l = l->next) {
611 const gchar *vc_string = (const gchar *) l->data;
612 gchar *key = NULL, *val = NULL;
614 GST_LOG_OBJECT (vorbisenc, "vorbis comment: %s", vc_string);
615 if (gst_tag_parse_extended_comment (vc_string, &key, NULL, &val, TRUE)) {
616 vorbis_comment_add_tag (&enc->vc, key, val);
622 g_list_foreach (vc_list, (GFunc) g_free, NULL);
623 g_list_free (vc_list);
627 gst_vorbis_enc_set_metadata (GstVorbisEnc * enc)
629 GstTagList *merged_tags;
630 const GstTagList *user_tags;
632 vorbis_comment_init (&enc->vc);
634 user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (enc));
636 GST_DEBUG_OBJECT (enc, "upstream tags = %" GST_PTR_FORMAT, enc->tags);
637 GST_DEBUG_OBJECT (enc, "user-set tags = %" GST_PTR_FORMAT, user_tags);
639 /* gst_tag_list_merge() will handle NULL for either or both lists fine */
640 merged_tags = gst_tag_list_merge (user_tags, enc->tags,
641 gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (enc)));
644 GST_DEBUG_OBJECT (enc, "merged tags = %" GST_PTR_FORMAT, merged_tags);
645 gst_tag_list_foreach (merged_tags, gst_vorbis_enc_metadata_set1, enc);
646 gst_tag_list_free (merged_tags);
651 get_constraints_string (GstVorbisEnc * vorbisenc)
653 gint min = vorbisenc->min_bitrate;
654 gint max = vorbisenc->max_bitrate;
657 if (min > 0 && max > 0)
658 result = g_strdup_printf ("(min %d bps, max %d bps)", min, max);
660 result = g_strdup_printf ("(min %d bps, no max)", min);
662 result = g_strdup_printf ("(no min, max %d bps)", max);
664 result = g_strdup_printf ("(no min or max)");
670 update_start_message (GstVorbisEnc * vorbisenc)
674 g_free (vorbisenc->last_message);
676 if (vorbisenc->bitrate > 0) {
677 if (vorbisenc->managed) {
678 constraints = get_constraints_string (vorbisenc);
679 vorbisenc->last_message =
680 g_strdup_printf ("encoding at average bitrate %d bps %s",
681 vorbisenc->bitrate, constraints);
682 g_free (constraints);
684 vorbisenc->last_message =
686 ("encoding at approximate bitrate %d bps (VBR encoding enabled)",
690 if (vorbisenc->quality_set) {
691 if (vorbisenc->managed) {
692 constraints = get_constraints_string (vorbisenc);
693 vorbisenc->last_message =
695 ("encoding at quality level %2.2f using constrained VBR %s",
696 vorbisenc->quality, constraints);
697 g_free (constraints);
699 vorbisenc->last_message =
700 g_strdup_printf ("encoding at quality level %2.2f",
704 constraints = get_constraints_string (vorbisenc);
705 vorbisenc->last_message =
706 g_strdup_printf ("encoding using bitrate management %s", constraints);
707 g_free (constraints);
711 g_object_notify (G_OBJECT (vorbisenc), "last_message");
715 gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc)
717 vorbisenc->setup = FALSE;
719 if (vorbisenc->bitrate < 0 && vorbisenc->min_bitrate < 0
720 && vorbisenc->max_bitrate < 0) {
721 vorbisenc->quality_set = TRUE;
724 update_start_message (vorbisenc);
726 /* choose an encoding mode */
727 /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
728 vorbis_info_init (&vorbisenc->vi);
730 if (vorbisenc->quality_set) {
731 if (vorbis_encode_setup_vbr (&vorbisenc->vi,
732 vorbisenc->channels, vorbisenc->frequency,
733 vorbisenc->quality) != 0) {
734 GST_ERROR_OBJECT (vorbisenc,
735 "vorbisenc: initialisation failed: invalid parameters for quality");
736 vorbis_info_clear (&vorbisenc->vi);
740 /* do we have optional hard quality restrictions? */
741 if (vorbisenc->max_bitrate > 0 || vorbisenc->min_bitrate > 0) {
742 struct ovectl_ratemanage_arg ai;
744 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_GET, &ai);
746 ai.bitrate_hard_min = vorbisenc->min_bitrate;
747 ai.bitrate_hard_max = vorbisenc->max_bitrate;
748 ai.management_active = 1;
750 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, &ai);
753 long min_bitrate, max_bitrate;
755 min_bitrate = vorbisenc->min_bitrate > 0 ? vorbisenc->min_bitrate : -1;
756 max_bitrate = vorbisenc->max_bitrate > 0 ? vorbisenc->max_bitrate : -1;
758 if (vorbis_encode_setup_managed (&vorbisenc->vi,
760 vorbisenc->frequency,
761 max_bitrate, vorbisenc->bitrate, min_bitrate) != 0) {
762 GST_ERROR_OBJECT (vorbisenc,
763 "vorbis_encode_setup_managed "
764 "(c %d, rate %d, max br %ld, br %d, min br %ld) failed",
765 vorbisenc->channels, vorbisenc->frequency, max_bitrate,
766 vorbisenc->bitrate, min_bitrate);
767 vorbis_info_clear (&vorbisenc->vi);
772 if (vorbisenc->managed && vorbisenc->bitrate < 0) {
773 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_AVG, NULL);
774 } else if (!vorbisenc->managed) {
775 /* Turn off management entirely (if it was turned on). */
776 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, NULL);
778 vorbis_encode_setup_init (&vorbisenc->vi);
780 /* set up the analysis state and auxiliary encoding storage */
781 vorbis_analysis_init (&vorbisenc->vd, &vorbisenc->vi);
782 vorbis_block_init (&vorbisenc->vd, &vorbisenc->vb);
784 vorbisenc->next_ts = 0;
786 vorbisenc->setup = TRUE;
792 gst_vorbis_enc_clear (GstVorbisEnc * vorbisenc)
794 GstFlowReturn ret = GST_FLOW_OK;
796 if (vorbisenc->setup) {
797 vorbis_analysis_wrote (&vorbisenc->vd, 0);
798 ret = gst_vorbis_enc_output_buffers (vorbisenc);
800 vorbisenc->setup = FALSE;
803 /* clean up and exit. vorbis_info_clear() must be called last */
804 vorbis_block_clear (&vorbisenc->vb);
805 vorbis_dsp_clear (&vorbisenc->vd);
806 vorbis_info_clear (&vorbisenc->vi);
808 vorbisenc->header_sent = FALSE;
813 /* prepare a buffer for transmission by passing data through libvorbis */
815 gst_vorbis_enc_buffer_from_packet (GstVorbisEnc * vorbisenc,
820 outbuf = gst_buffer_new_and_alloc (packet->bytes);
821 gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
822 /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
823 * time representation */
824 GST_BUFFER_OFFSET_END (outbuf) = packet->granulepos +
825 vorbisenc->granulepos_offset;
826 GST_BUFFER_OFFSET (outbuf) = granulepos_to_timestamp (vorbisenc,
827 GST_BUFFER_OFFSET_END (outbuf));
828 GST_BUFFER_TIMESTAMP (outbuf) = vorbisenc->next_ts;
830 /* update the next timestamp, taking granulepos_offset and subgranule offset
833 granulepos_to_timestamp_offset (vorbisenc, packet->granulepos);
834 GST_BUFFER_DURATION (outbuf) =
835 vorbisenc->next_ts - GST_BUFFER_TIMESTAMP (outbuf);
837 if (vorbisenc->next_discont) {
838 GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
839 vorbisenc->next_discont = FALSE;
842 GST_LOG_OBJECT (vorbisenc, "encoded buffer of %d bytes",
843 gst_buffer_get_size (outbuf));
847 /* the same as above, but different logic for setting timestamp and granulepos
850 gst_vorbis_enc_buffer_from_header_packet (GstVorbisEnc * vorbisenc,
855 outbuf = gst_buffer_new_and_alloc (packet->bytes);
856 gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
857 GST_BUFFER_OFFSET (outbuf) = vorbisenc->bytes_out;
858 GST_BUFFER_OFFSET_END (outbuf) = 0;
859 GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
860 GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
862 GST_DEBUG ("created header packet buffer, %d bytes",
863 gst_buffer_get_size (outbuf));
867 /* push out the buffer and do internal bookkeeping */
869 gst_vorbis_enc_push_buffer (GstVorbisEnc * vorbisenc, GstBuffer * buffer)
871 vorbisenc->bytes_out += gst_buffer_get_size (buffer);
873 GST_DEBUG_OBJECT (vorbisenc,
874 "Pushing buffer with GP %" G_GINT64_FORMAT ", ts %" GST_TIME_FORMAT,
875 GST_BUFFER_OFFSET_END (buffer),
876 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
877 return gst_pad_push (vorbisenc->srcpad, buffer);
881 gst_vorbis_enc_push_packet (GstVorbisEnc * vorbisenc, ogg_packet * packet)
885 outbuf = gst_vorbis_enc_buffer_from_packet (vorbisenc, packet);
886 return gst_vorbis_enc_push_buffer (vorbisenc, outbuf);
889 /* Set a copy of these buffers as 'streamheader' on the caps.
890 * We need a copy to avoid these buffers ending up with (indirect) refs on
894 gst_vorbis_enc_set_header_on_caps (GstCaps * caps, GstBuffer * buf1,
895 GstBuffer * buf2, GstBuffer * buf3)
898 GstStructure *structure;
899 GValue array = { 0 };
900 GValue value = { 0 };
902 caps = gst_caps_make_writable (caps);
903 structure = gst_caps_get_structure (caps, 0);
906 GST_BUFFER_FLAG_SET (buf1, GST_BUFFER_FLAG_IN_CAPS);
907 GST_BUFFER_FLAG_SET (buf2, GST_BUFFER_FLAG_IN_CAPS);
908 GST_BUFFER_FLAG_SET (buf3, GST_BUFFER_FLAG_IN_CAPS);
910 /* put buffers in a fixed list */
911 g_value_init (&array, GST_TYPE_ARRAY);
912 g_value_init (&value, GST_TYPE_BUFFER);
913 buf = gst_buffer_copy (buf1);
914 gst_value_set_buffer (&value, buf);
915 gst_buffer_unref (buf);
916 gst_value_array_append_value (&array, &value);
917 g_value_unset (&value);
918 g_value_init (&value, GST_TYPE_BUFFER);
919 buf = gst_buffer_copy (buf2);
920 gst_value_set_buffer (&value, buf);
921 gst_buffer_unref (buf);
922 gst_value_array_append_value (&array, &value);
923 g_value_unset (&value);
924 g_value_init (&value, GST_TYPE_BUFFER);
925 buf = gst_buffer_copy (buf3);
926 gst_value_set_buffer (&value, buf);
927 gst_buffer_unref (buf);
928 gst_value_array_append_value (&array, &value);
929 gst_structure_set_value (structure, "streamheader", &array);
930 g_value_unset (&value);
931 g_value_unset (&array);
937 gst_vorbis_enc_sink_event (GstPad * pad, GstEvent * event)
940 GstVorbisEnc *vorbisenc;
942 vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
944 switch (GST_EVENT_TYPE (event)) {
949 gst_event_parse_caps (event, &caps);
950 res = gst_vorbis_enc_sink_setcaps (vorbisenc, caps);
951 gst_event_unref (event);
955 /* Tell the library we're at end of stream so that it can handle
956 * the last frame and mark end of stream in the output properly */
957 GST_DEBUG_OBJECT (vorbisenc, "EOS, clearing state and sending event on");
958 gst_vorbis_enc_clear (vorbisenc);
960 res = gst_pad_push_event (vorbisenc->srcpad, event);
963 if (vorbisenc->tags) {
966 gst_event_parse_tag (event, &list);
967 gst_tag_list_insert (vorbisenc->tags, list,
968 gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (vorbisenc)));
970 g_assert_not_reached ();
972 res = gst_pad_push_event (vorbisenc->srcpad, event);
974 case GST_EVENT_SEGMENT:
976 const GstSegment *segment;
978 gst_event_parse_segment (event, &segment);
980 if (segment->format == GST_FORMAT_TIME) {
981 gst_segment_copy_into (segment, &vorbisenc->segment);
986 res = gst_pad_push_event (vorbisenc->srcpad, event);
993 gst_vorbis_enc_buffer_check_discontinuous (GstVorbisEnc * vorbisenc,
994 GstClockTime timestamp, GstClockTime duration)
996 gboolean ret = FALSE;
998 GST_DEBUG_OBJECT (vorbisenc, "exp %" GST_TIME_FORMAT " time %" GST_TIME_FORMAT
999 "dur %" GST_TIME_FORMAT, GST_TIME_ARGS (vorbisenc->expected_ts),
1000 GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration));
1002 if (timestamp != GST_CLOCK_TIME_NONE &&
1003 vorbisenc->expected_ts != GST_CLOCK_TIME_NONE &&
1004 timestamp + duration != vorbisenc->expected_ts) {
1005 /* It turns out that a lot of elements don't generate perfect streams due
1006 * to rounding errors. So, we permit small errors (< 1/2 a sample) without
1007 * causing a discont.
1009 int halfsample = GST_SECOND / vorbisenc->frequency / 2;
1011 if ((GstClockTimeDiff) (timestamp - vorbisenc->expected_ts) > halfsample) {
1012 GST_DEBUG_OBJECT (vorbisenc, "Expected TS %" GST_TIME_FORMAT
1013 ", buffer TS %" GST_TIME_FORMAT,
1014 GST_TIME_ARGS (vorbisenc->expected_ts), GST_TIME_ARGS (timestamp));
1019 if (timestamp != GST_CLOCK_TIME_NONE && duration != GST_CLOCK_TIME_NONE) {
1020 vorbisenc->expected_ts = timestamp + duration;
1022 vorbisenc->expected_ts = GST_CLOCK_TIME_NONE;
1027 static GstFlowReturn
1028 gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
1030 GstVorbisEnc *vorbisenc;
1031 GstFlowReturn ret = GST_FLOW_OK;
1035 float **vorbis_buffer;
1036 GstBuffer *buf1, *buf2, *buf3;
1037 gboolean first = FALSE;
1038 GstClockTime timestamp = GST_CLOCK_TIME_NONE;
1039 GstClockTime running_time = GST_CLOCK_TIME_NONE;
1042 vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
1044 if (!vorbisenc->setup)
1047 buffer = gst_audio_buffer_clip (buffer, &vorbisenc->segment,
1048 vorbisenc->frequency, 4 * vorbisenc->channels);
1049 if (buffer == NULL) {
1050 GST_DEBUG_OBJECT (vorbisenc, "Dropping buffer, out of segment");
1054 gst_segment_to_running_time (&vorbisenc->segment, GST_FORMAT_TIME,
1055 GST_BUFFER_TIMESTAMP (buffer));
1056 timestamp = running_time;
1057 GST_DEBUG_OBJECT (vorbisenc, " timestamp %" GST_TIME_FORMAT,
1058 GST_TIME_ARGS (timestamp));
1059 if (!vorbisenc->header_sent) {
1060 /* Vorbis streams begin with three headers; the initial header (with
1061 most of the codec setup parameters) which is mandated by the Ogg
1062 bitstream spec. The second header holds any comment fields. The
1063 third header holds the bitstream codebook. We merely need to
1064 make the headers, then pass them to libvorbis one at a time;
1065 libvorbis handles the additional Ogg bitstream constraints */
1067 ogg_packet header_comm;
1068 ogg_packet header_code;
1071 /* first, make sure header buffers get timestamp == 0 */
1072 vorbisenc->next_ts = 0;
1073 vorbisenc->granulepos_offset = 0;
1074 vorbisenc->subgranule_offset = 0;
1076 GST_DEBUG_OBJECT (vorbisenc, "creating and sending header packets");
1077 gst_vorbis_enc_set_metadata (vorbisenc);
1078 vorbis_analysis_headerout (&vorbisenc->vd, &vorbisenc->vc, &header,
1079 &header_comm, &header_code);
1080 vorbis_comment_clear (&vorbisenc->vc);
1082 /* create header buffers */
1083 buf1 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header);
1084 buf2 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_comm);
1085 buf3 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_code);
1087 /* mark and put on caps */
1088 vorbisenc->srccaps = gst_caps_new_simple ("audio/x-vorbis", NULL);
1089 caps = vorbisenc->srccaps;
1090 caps = gst_vorbis_enc_set_header_on_caps (caps, buf1, buf2, buf3);
1092 /* negotiate with these caps */
1093 GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
1094 gst_pad_set_caps (vorbisenc->srcpad, caps);
1096 /* push out buffers */
1097 /* push_buffer takes the reference even for failure */
1098 if ((ret = gst_vorbis_enc_push_buffer (vorbisenc, buf1)) != GST_FLOW_OK)
1099 goto failed_header_push;
1100 if ((ret = gst_vorbis_enc_push_buffer (vorbisenc, buf2)) != GST_FLOW_OK) {
1102 goto failed_header_push;
1104 if ((ret = gst_vorbis_enc_push_buffer (vorbisenc, buf3)) != GST_FLOW_OK) {
1106 goto failed_header_push;
1109 /* now adjust starting granulepos accordingly if the buffer's timestamp is
1111 vorbisenc->next_ts = timestamp;
1112 vorbisenc->expected_ts = timestamp;
1113 vorbisenc->granulepos_offset = gst_util_uint64_scale
1114 (running_time, vorbisenc->frequency, GST_SECOND);
1115 vorbisenc->subgranule_offset = 0;
1116 vorbisenc->subgranule_offset =
1117 vorbisenc->next_ts - granulepos_to_timestamp_offset (vorbisenc, 0);
1119 vorbisenc->header_sent = TRUE;
1123 if (vorbisenc->expected_ts != GST_CLOCK_TIME_NONE &&
1124 timestamp < vorbisenc->expected_ts) {
1125 guint64 diff = vorbisenc->expected_ts - timestamp;
1129 GST_WARNING_OBJECT (vorbisenc, "Buffer is older than previous "
1130 "timestamp + duration (%" GST_TIME_FORMAT "< %" GST_TIME_FORMAT
1131 "), cannot handle. Clipping buffer.",
1132 GST_TIME_ARGS (timestamp), GST_TIME_ARGS (vorbisenc->expected_ts));
1134 size = gst_buffer_get_size (buffer);
1137 GST_CLOCK_TIME_TO_FRAMES (diff,
1138 vorbisenc->frequency) * vorbisenc->channels * sizeof (gfloat);
1139 if (diff_bytes >= size) {
1140 gst_buffer_unref (buffer);
1143 buffer = gst_buffer_make_writable (buffer);
1144 gst_buffer_resize (buffer, diff_bytes, size - diff_bytes);
1146 GST_BUFFER_TIMESTAMP (buffer) += diff;
1147 if (GST_BUFFER_DURATION_IS_VALID (buffer))
1148 GST_BUFFER_DURATION (buffer) -= diff;
1151 if (gst_vorbis_enc_buffer_check_discontinuous (vorbisenc, timestamp,
1152 GST_BUFFER_DURATION (buffer)) && !first) {
1153 GST_WARNING_OBJECT (vorbisenc,
1154 "Buffer is discontinuous, flushing encoder "
1155 "and restarting (Discont from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT
1156 ")", GST_TIME_ARGS (vorbisenc->next_ts), GST_TIME_ARGS (timestamp));
1157 /* Re-initialise encoder (there's unfortunately no API to flush it) */
1158 if ((ret = gst_vorbis_enc_clear (vorbisenc)) != GST_FLOW_OK)
1160 if (!gst_vorbis_enc_setup (vorbisenc))
1161 return GST_FLOW_ERROR; /* Should be impossible, we can only get here if
1162 we successfully initialised earlier */
1164 /* Now, set our granulepos offset appropriately. */
1165 vorbisenc->next_ts = timestamp;
1166 /* We need to round to the nearest whole number of samples, not just do
1167 * a truncating division here */
1168 vorbisenc->granulepos_offset = gst_util_uint64_scale
1169 (running_time + GST_SECOND / vorbisenc->frequency / 2
1170 - vorbisenc->subgranule_offset, vorbisenc->frequency, GST_SECOND);
1172 vorbisenc->header_sent = TRUE;
1174 /* And our next output buffer must have DISCONT set on it */
1175 vorbisenc->next_discont = TRUE;
1178 /* Sending zero samples to libvorbis marks EOS, so we mustn't do that */
1179 data = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_WRITE);
1181 gst_buffer_unmap (buffer, data, bsize);
1182 gst_buffer_unref (buffer);
1186 /* data to encode */
1187 size = bsize / (vorbisenc->channels * sizeof (float));
1191 /* expose the buffer to submit data */
1192 vorbis_buffer = vorbis_analysis_buffer (&vorbisenc->vd, size);
1194 /* deinterleave samples, write the buffer data */
1195 for (i = 0; i < size; i++) {
1196 for (j = 0; j < vorbisenc->channels; j++) {
1197 vorbis_buffer[j][i] = *ptr++;
1201 /* tell the library how much we actually submitted */
1202 vorbis_analysis_wrote (&vorbisenc->vd, size);
1203 gst_buffer_unmap (buffer, data, bsize);
1205 GST_LOG_OBJECT (vorbisenc, "wrote %lu samples to vorbis", size);
1207 vorbisenc->samples_in += size;
1209 gst_buffer_unref (buffer);
1211 ret = gst_vorbis_enc_output_buffers (vorbisenc);
1218 gst_buffer_unref (buffer);
1219 GST_ELEMENT_ERROR (vorbisenc, CORE, NEGOTIATION, (NULL),
1220 ("encoder not initialized (input is not audio?)"));
1221 return GST_FLOW_UNEXPECTED;
1225 GST_WARNING_OBJECT (vorbisenc, "Failed to push headers");
1226 /* buf1 is always already unreffed */
1228 gst_buffer_unref (buf2);
1230 gst_buffer_unref (buf3);
1231 gst_buffer_unref (buffer);
1236 static GstFlowReturn
1237 gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc)
1241 /* vorbis does some data preanalysis, then divides up blocks for
1242 more involved (potentially parallel) processing. Get a single
1243 block for encoding now */
1244 while (vorbis_analysis_blockout (&vorbisenc->vd, &vorbisenc->vb) == 1) {
1247 GST_LOG_OBJECT (vorbisenc, "analysed to a block");
1250 vorbis_analysis (&vorbisenc->vb, NULL);
1251 vorbis_bitrate_addblock (&vorbisenc->vb);
1253 while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &op)) {
1254 GST_LOG_OBJECT (vorbisenc, "pushing out a data packet");
1255 ret = gst_vorbis_enc_push_packet (vorbisenc, &op);
1257 if (ret != GST_FLOW_OK)
1266 gst_vorbis_enc_get_property (GObject * object, guint prop_id, GValue * value,
1269 GstVorbisEnc *vorbisenc;
1271 g_return_if_fail (GST_IS_VORBISENC (object));
1273 vorbisenc = GST_VORBISENC (object);
1276 case ARG_MAX_BITRATE:
1277 g_value_set_int (value, vorbisenc->max_bitrate);
1280 g_value_set_int (value, vorbisenc->bitrate);
1282 case ARG_MIN_BITRATE:
1283 g_value_set_int (value, vorbisenc->min_bitrate);
1286 g_value_set_float (value, vorbisenc->quality);
1289 g_value_set_boolean (value, vorbisenc->managed);
1291 case ARG_LAST_MESSAGE:
1292 g_value_set_string (value, vorbisenc->last_message);
1295 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1301 gst_vorbis_enc_set_property (GObject * object, guint prop_id,
1302 const GValue * value, GParamSpec * pspec)
1304 GstVorbisEnc *vorbisenc;
1306 g_return_if_fail (GST_IS_VORBISENC (object));
1308 vorbisenc = GST_VORBISENC (object);
1311 case ARG_MAX_BITRATE:
1313 gboolean old_value = vorbisenc->managed;
1315 vorbisenc->max_bitrate = g_value_get_int (value);
1316 if (vorbisenc->max_bitrate >= 0
1317 && vorbisenc->max_bitrate < LOWEST_BITRATE) {
1318 g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1319 vorbisenc->max_bitrate = LOWEST_BITRATE;
1321 if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
1322 vorbisenc->managed = TRUE;
1324 vorbisenc->managed = FALSE;
1326 if (old_value != vorbisenc->managed)
1327 g_object_notify (object, "managed");
1331 vorbisenc->bitrate = g_value_get_int (value);
1332 if (vorbisenc->bitrate >= 0 && vorbisenc->bitrate < LOWEST_BITRATE) {
1333 g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1334 vorbisenc->bitrate = LOWEST_BITRATE;
1337 case ARG_MIN_BITRATE:
1339 gboolean old_value = vorbisenc->managed;
1341 vorbisenc->min_bitrate = g_value_get_int (value);
1342 if (vorbisenc->min_bitrate >= 0
1343 && vorbisenc->min_bitrate < LOWEST_BITRATE) {
1344 g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1345 vorbisenc->min_bitrate = LOWEST_BITRATE;
1347 if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
1348 vorbisenc->managed = TRUE;
1350 vorbisenc->managed = FALSE;
1352 if (old_value != vorbisenc->managed)
1353 g_object_notify (object, "managed");
1357 vorbisenc->quality = g_value_get_float (value);
1358 if (vorbisenc->quality >= 0.0)
1359 vorbisenc->quality_set = TRUE;
1361 vorbisenc->quality_set = FALSE;
1364 vorbisenc->managed = g_value_get_boolean (value);
1367 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1372 static GstStateChangeReturn
1373 gst_vorbis_enc_change_state (GstElement * element, GstStateChange transition)
1375 GstVorbisEnc *vorbisenc = GST_VORBISENC (element);
1376 GstStateChangeReturn res;
1379 switch (transition) {
1380 case GST_STATE_CHANGE_NULL_TO_READY:
1381 vorbisenc->tags = gst_tag_list_new ();
1383 case GST_STATE_CHANGE_READY_TO_PAUSED:
1384 vorbisenc->setup = FALSE;
1385 vorbisenc->next_discont = FALSE;
1386 vorbisenc->header_sent = FALSE;
1387 gst_segment_init (&vorbisenc->segment, GST_FORMAT_TIME);
1389 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1395 res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1397 switch (transition) {
1398 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1400 case GST_STATE_CHANGE_PAUSED_TO_READY:
1401 vorbis_block_clear (&vorbisenc->vb);
1402 vorbis_dsp_clear (&vorbisenc->vd);
1403 vorbis_info_clear (&vorbisenc->vi);
1404 g_free (vorbisenc->last_message);
1405 vorbisenc->last_message = NULL;
1406 if (vorbisenc->srccaps) {
1407 gst_caps_unref (vorbisenc->srccaps);
1408 vorbisenc->srccaps = NULL;
1411 case GST_STATE_CHANGE_READY_TO_NULL:
1412 gst_tag_list_free (vorbisenc->tags);
1413 vorbisenc->tags = NULL;