2 * Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
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.
24 #include "vorbisdec.h"
26 #include <gst/tag/tag.h>
27 #include <gst/audio/multichannel.h>
29 GST_DEBUG_CATEGORY_EXTERN (vorbisdec_debug);
30 #define GST_CAT_DEFAULT vorbisdec_debug
32 static GstElementDetails vorbis_dec_details = {
34 "Codec/Decoder/Audio",
35 "decode raw vorbis streams to float audio",
36 "Benjamin Otte <in7y118@public.uni-hamburg.de>",
39 /* Filter signals and args */
51 static GstStaticPadTemplate vorbis_dec_src_factory =
52 GST_STATIC_PAD_TEMPLATE ("src",
55 GST_STATIC_CAPS ("audio/x-raw-float, "
56 "rate = (int) [ 8000, 50000 ], "
57 "channels = (int) [ 1, 6 ], " "endianness = (int) BYTE_ORDER, "
58 /* no ifdef in macros, please
59 #ifdef GST_VORBIS_DEC_SEQUENTIAL
60 "layout = \"sequential\", "
63 "width = (int) 32, " "buffer-frames = (int) 0")
66 static GstStaticPadTemplate vorbis_dec_sink_factory =
67 GST_STATIC_PAD_TEMPLATE ("sink",
70 GST_STATIC_CAPS ("audio/x-vorbis")
73 GST_BOILERPLATE (GstVorbisDec, gst_vorbis_dec, GstElement, GST_TYPE_ELEMENT);
75 static void vorbisdec_finalize (GObject * object);
76 static gboolean vorbis_dec_sink_event (GstPad * pad, GstEvent * event);
77 static GstFlowReturn vorbis_dec_chain (GstPad * pad, GstBuffer * buffer);
78 static GstStateChangeReturn vorbis_dec_change_state (GstElement * element,
79 GstStateChange transition);
82 static const GstFormat *vorbis_dec_get_formats (GstPad * pad);
85 static gboolean vorbis_dec_src_event (GstPad * pad, GstEvent * event);
86 static gboolean vorbis_dec_src_query (GstPad * pad, GstQuery * query);
87 static gboolean vorbis_dec_convert (GstPad * pad,
88 GstFormat src_format, gint64 src_value,
89 GstFormat * dest_format, gint64 * dest_value);
91 static gboolean vorbis_dec_sink_query (GstPad * pad, GstQuery * query);
94 gst_vorbis_dec_base_init (gpointer g_class)
96 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
98 gst_element_class_add_pad_template (element_class,
99 gst_static_pad_template_get (&vorbis_dec_src_factory));
100 gst_element_class_add_pad_template (element_class,
101 gst_static_pad_template_get (&vorbis_dec_sink_factory));
102 gst_element_class_set_details (element_class, &vorbis_dec_details);
106 gst_vorbis_dec_class_init (GstVorbisDecClass * klass)
108 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
109 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
111 gobject_class->finalize = vorbisdec_finalize;
113 gstelement_class->change_state = vorbis_dec_change_state;
117 static const GstFormat *
118 vorbis_dec_get_formats (GstPad * pad)
120 static GstFormat src_formats[] = {
122 GST_FORMAT_DEFAULT, /* samples in the audio case */
126 static GstFormat sink_formats[] = {
127 /*GST_FORMAT_BYTES, */
129 GST_FORMAT_DEFAULT, /* granulepos or samples */
133 return (GST_PAD_IS_SRC (pad) ? src_formats : sink_formats);
138 static const GstEventMask *
139 vorbis_get_event_masks (GstPad * pad)
141 static const GstEventMask vorbis_dec_src_event_masks[] = {
142 {GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH},
146 return vorbis_dec_src_event_masks;
150 static const GstQueryType *
151 vorbis_get_query_types (GstPad * pad)
153 static const GstQueryType vorbis_dec_src_query_types[] = {
158 return vorbis_dec_src_query_types;
162 gst_vorbis_dec_init (GstVorbisDec * dec, GstVorbisDecClass * g_class)
165 gst_pad_new_from_template (gst_static_pad_template_get
166 (&vorbis_dec_sink_factory), "sink");
167 gst_pad_set_event_function (dec->sinkpad, vorbis_dec_sink_event);
168 gst_pad_set_chain_function (dec->sinkpad, vorbis_dec_chain);
169 gst_pad_set_query_function (dec->sinkpad, vorbis_dec_sink_query);
170 gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
173 gst_pad_new_from_template (gst_static_pad_template_get
174 (&vorbis_dec_src_factory), "src");
175 gst_pad_set_event_function (dec->srcpad, vorbis_dec_src_event);
176 gst_pad_set_query_type_function (dec->srcpad, vorbis_get_query_types);
177 gst_pad_set_query_function (dec->srcpad, vorbis_dec_src_query);
178 gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
184 vorbisdec_finalize (GObject * object)
186 /* Release any possibly allocated libvorbis data.
187 * _clear functions can safely be called multiple times
189 GstVorbisDec *vd = GST_VORBIS_DEC (object);
191 vorbis_block_clear (&vd->vb);
192 vorbis_dsp_clear (&vd->vd);
193 vorbis_comment_clear (&vd->vc);
194 vorbis_info_clear (&vd->vi);
198 vorbis_dec_convert (GstPad * pad,
199 GstFormat src_format, gint64 src_value,
200 GstFormat * dest_format, gint64 * dest_value)
206 dec = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
208 if (dec->packetno < 1)
211 if (src_format == *dest_format) {
212 *dest_value = src_value;
216 if (dec->sinkpad == pad &&
217 (src_format == GST_FORMAT_BYTES || *dest_format == GST_FORMAT_BYTES))
220 switch (src_format) {
221 case GST_FORMAT_TIME:
222 switch (*dest_format) {
223 case GST_FORMAT_BYTES:
224 scale = sizeof (float) * dec->vi.channels;
225 case GST_FORMAT_DEFAULT:
226 *dest_value = scale * (src_value * dec->vi.rate / GST_SECOND);
232 case GST_FORMAT_DEFAULT:
233 switch (*dest_format) {
234 case GST_FORMAT_BYTES:
235 *dest_value = src_value * sizeof (float) * dec->vi.channels;
237 case GST_FORMAT_TIME:
239 gst_util_uint64_scale (src_value, GST_SECOND, dec->vi.rate);
245 case GST_FORMAT_BYTES:
246 switch (*dest_format) {
247 case GST_FORMAT_DEFAULT:
248 *dest_value = src_value / (sizeof (float) * dec->vi.channels);
250 case GST_FORMAT_TIME:
251 *dest_value = gst_util_uint64_scale (src_value, GST_SECOND,
252 dec->vi.rate * sizeof (float) * dec->vi.channels);
266 vorbis_dec_src_query (GstPad * pad, GstQuery * query)
272 dec = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
274 switch (GST_QUERY_TYPE (query)) {
275 case GST_QUERY_POSITION:
280 /* query peer for total length */
281 if (!(res = gst_pad_query (GST_PAD_PEER (dec->sinkpad), query)))
284 granulepos = dec->granulepos;
286 gst_query_parse_position (query, &format, NULL, &total);
288 /* and convert to the final format */
290 vorbis_dec_convert (pad, GST_FORMAT_DEFAULT, granulepos, &format,
294 value = (value - dec->segment_start) + dec->segment_base;
296 gst_query_set_position (query, format, value, total);
299 "query %u: peer returned granulepos: %llu - we return %llu (format %u)",
300 query, granulepos, value, format);
304 case GST_QUERY_CONVERT:
306 GstFormat src_fmt, dest_fmt;
307 gint64 src_val, dest_val;
309 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
311 vorbis_dec_convert (pad, src_fmt, src_val, &dest_fmt, &dest_val)))
313 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
324 GST_WARNING_OBJECT (dec, "error handling query");
330 vorbis_dec_sink_query (GstPad * pad, GstQuery * query)
335 dec = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
337 switch (GST_QUERY_TYPE (query)) {
338 case GST_QUERY_CONVERT:
340 GstFormat src_fmt, dest_fmt;
341 gint64 src_val, dest_val;
343 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
345 vorbis_dec_convert (pad, src_fmt, src_val, &dest_fmt, &dest_val)))
347 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
359 vorbis_dec_src_event (GstPad * pad, GstEvent * event)
362 GstVorbisDec *dec = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
364 switch (GST_EVENT_TYPE (event)) {
365 case GST_EVENT_SEEK:{
366 GstFormat format, tformat;
370 GstSeekType cur_type, stop_type;
374 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
377 /* we have to ask our peer to seek to time here as we know
378 * nothing about how to generate a granulepos from the src
379 * formats or anything.
381 * First bring the requested format to time
383 tformat = GST_FORMAT_TIME;
384 if (!(res = vorbis_dec_convert (pad, format, cur, &tformat, &tcur)))
386 if (!(res = vorbis_dec_convert (pad, format, stop, &tformat, &tstop)))
389 /* then seek with time on the peer */
390 real_seek = gst_event_new_seek (rate, GST_FORMAT_TIME,
391 flags, cur_type, tcur, stop_type, tstop);
393 res = gst_pad_push_event (dec->sinkpad, real_seek);
395 gst_event_unref (event);
399 res = gst_pad_event_default (pad, event);
406 gst_event_unref (event);
411 vorbis_dec_sink_event (GstPad * pad, GstEvent * event)
413 gboolean ret = FALSE;
416 dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
418 GST_LOG_OBJECT (dec, "handling event");
419 switch (GST_EVENT_TYPE (event)) {
421 GST_STREAM_LOCK (pad);
422 ret = gst_pad_push_event (dec->srcpad, event);
423 GST_STREAM_UNLOCK (pad);
425 case GST_EVENT_NEWSEGMENT:
429 gint64 start, stop, base;
431 GST_STREAM_LOCK (pad);
432 gst_event_parse_newsegment (event, &rate, &format, &start, &stop, &base);
434 if (format != GST_FORMAT_TIME)
435 goto newseg_wrong_format;
438 goto newseg_wrong_rate;
440 /* now copy over the values */
441 dec->segment_rate = rate;
442 dec->segment_start = start;
443 dec->segment_stop = stop;
444 dec->segment_base = base;
446 dec->granulepos = -1;
447 #ifdef HAVE_VORBIS_SYNTHESIS_RESTART
448 vorbis_synthesis_restart (&dec->vd);
450 ret = gst_pad_push_event (dec->srcpad, event);
451 GST_STREAM_UNLOCK (pad);
455 ret = gst_pad_push_event (dec->srcpad, event);
459 gst_object_unref (dec);
465 GST_STREAM_UNLOCK (pad);
466 GST_DEBUG ("received non TIME newsegment");
471 GST_STREAM_UNLOCK (pad);
472 GST_DEBUG ("negative rates not supported yet");
479 vorbis_handle_identification_packet (GstVorbisDec * vd)
482 const GstAudioChannelPosition *pos = NULL;
484 caps = gst_caps_new_simple ("audio/x-raw-float",
485 "rate", G_TYPE_INT, vd->vi.rate,
486 "channels", G_TYPE_INT, vd->vi.channels,
487 "endianness", G_TYPE_INT, G_BYTE_ORDER,
488 "width", G_TYPE_INT, 32, "buffer-frames", G_TYPE_INT, 0, NULL);
490 switch (vd->vi.channels) {
496 static GstAudioChannelPosition pos3[] = {
497 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
498 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
499 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
505 static GstAudioChannelPosition pos4[] = {
506 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
507 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
508 GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
509 GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT
515 static GstAudioChannelPosition pos5[] = {
516 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
517 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
518 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
519 GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
520 GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT
526 static GstAudioChannelPosition pos6[] = {
527 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
528 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
529 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
530 GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
531 GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
532 GST_AUDIO_CHANNEL_POSITION_LFE
538 goto channel_count_error;
541 gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
543 gst_pad_set_caps (vd->srcpad, caps);
544 gst_caps_unref (caps);
551 gst_caps_unref (caps);
552 GST_ELEMENT_ERROR (vd, STREAM, NOT_IMPLEMENTED, (NULL),
553 ("Unsupported channel count %d", vd->vi.channels));
554 return GST_FLOW_ERROR;
559 vorbis_handle_comment_packet (GstVorbisDec * vd, ogg_packet * packet)
562 gchar *encoder = NULL;
567 GST_DEBUG_OBJECT (vd, "parsing comment packet");
569 buf = gst_buffer_new_and_alloc (packet->bytes);
570 GST_BUFFER_DATA (buf) = packet->packet;
573 gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\003vorbis", 7,
576 gst_buffer_unref (buf);
579 GST_ERROR_OBJECT (vd, "couldn't decode comments");
580 list = gst_tag_list_new ();
583 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
584 GST_TAG_ENCODER, encoder, NULL);
587 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
588 GST_TAG_ENCODER_VERSION, vd->vi.version,
589 GST_TAG_AUDIO_CODEC, "Vorbis", NULL);
590 if (vd->vi.bitrate_nominal > 0) {
591 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
592 GST_TAG_NOMINAL_BITRATE, (guint) vd->vi.bitrate_nominal, NULL);
593 bitrate = vd->vi.bitrate_nominal;
595 if (vd->vi.bitrate_upper > 0) {
596 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
597 GST_TAG_MAXIMUM_BITRATE, (guint) vd->vi.bitrate_upper, NULL);
599 bitrate = vd->vi.bitrate_upper;
601 if (vd->vi.bitrate_lower > 0) {
602 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
603 GST_TAG_MINIMUM_BITRATE, (guint) vd->vi.bitrate_lower, NULL);
605 bitrate = vd->vi.bitrate_lower;
608 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
609 GST_TAG_BITRATE, (guint) bitrate, NULL);
612 message = gst_message_new_tag ((GstObject *) vd, list);
613 gst_element_post_message (GST_ELEMENT (vd), message);
619 vorbis_handle_type_packet (GstVorbisDec * vd)
621 g_assert (vd->initialized == FALSE);
623 vorbis_synthesis_init (&vd->vd, &vd->vi);
624 vorbis_block_init (&vd->vd, &vd->vb);
625 vd->initialized = TRUE;
631 vorbis_handle_header_packet (GstVorbisDec * vd, ogg_packet * packet)
635 GST_DEBUG_OBJECT (vd, "parsing header packet");
637 /* Packetno = 0 if the first byte is exactly 0x01 */
638 packet->b_o_s = (packet->packet[0] == 0x1) ? 1 : 0;
640 if (vorbis_synthesis_headerin (&vd->vi, &vd->vc, packet))
641 goto header_read_error;
643 /* FIXME: we should probably double-check if packet[0] is 1/3/5 for each
645 switch (packet->packetno) {
647 res = vorbis_handle_identification_packet (vd);
650 res = vorbis_handle_comment_packet (vd, packet);
653 res = vorbis_handle_type_packet (vd);
665 GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
666 (NULL), ("couldn't read header packet"));
667 return GST_FLOW_ERROR;
672 copy_samples (float *out, float **in, guint samples, gint channels)
676 #ifdef GST_VORBIS_DEC_SEQUENTIAL
677 for (i = 0; i < channels; i++) {
678 memcpy (out, in[i], samples * sizeof (float));
682 for (j = 0; j < samples; j++) {
683 for (i = 0; i < channels; i++) {
691 vorbis_dec_push (GstVorbisDec * dec, GstBuffer * buf)
693 GstFlowReturn result;
694 gint64 outoffset = GST_BUFFER_OFFSET (buf);
696 if (outoffset == -1) {
697 dec->queued = g_list_append (dec->queued, buf);
698 GST_DEBUG_OBJECT (dec, "queued buffer");
699 result = GST_FLOW_OK;
705 GST_DEBUG_OBJECT (dec, "first buffer with offset %lld", outoffset);
707 size = g_list_length (dec->queued);
708 for (walk = g_list_last (dec->queued); walk;
709 walk = g_list_previous (walk)) {
710 GstBuffer *buffer = GST_BUFFER (walk->data);
713 GST_BUFFER_SIZE (buffer) / (sizeof (float) * dec->vi.channels);
715 GST_BUFFER_OFFSET (buffer) = outoffset;
716 GST_BUFFER_TIMESTAMP (buffer) =
717 gst_util_uint64_scale (outoffset, GST_SECOND, dec->vi.rate);
718 GST_DEBUG_OBJECT (dec, "patch buffer %" G_GUINT64_FORMAT
719 " offset %" G_GUINT64_FORMAT, size, outoffset);
722 for (walk = dec->queued; walk; walk = g_list_next (walk)) {
723 GstBuffer *buffer = GST_BUFFER (walk->data);
725 /* ignore the result */
726 gst_pad_push (dec->srcpad, buffer);
728 g_list_free (dec->queued);
731 result = gst_pad_push (dec->srcpad, buf);
738 vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet)
742 GstFlowReturn result;
744 if (!vd->initialized)
745 goto not_initialized;
747 /* normal data packet */
748 if (vorbis_synthesis (&vd->vb, packet))
751 if (vorbis_synthesis_blockin (&vd->vd, &vd->vb) < 0)
754 sample_count = vorbis_synthesis_pcmout (&vd->vd, &pcm);
755 if (sample_count > 0) {
758 result = gst_pad_alloc_buffer (vd->srcpad, GST_BUFFER_OFFSET_NONE,
759 sample_count * vd->vi.channels * sizeof (float),
760 GST_PAD_CAPS (vd->srcpad), &out);
762 if (result == GST_FLOW_OK) {
763 float *out_data = (float *) GST_BUFFER_DATA (out);
765 copy_samples (out_data, pcm, sample_count, vd->vi.channels);
767 GST_BUFFER_OFFSET (out) = vd->granulepos;
768 if (vd->granulepos != -1) {
769 GST_BUFFER_OFFSET_END (out) = vd->granulepos + sample_count;
770 GST_BUFFER_TIMESTAMP (out) =
771 gst_util_uint64_scale (vd->granulepos, GST_SECOND, vd->vi.rate);
773 GST_BUFFER_TIMESTAMP (out) = -1;
775 GST_BUFFER_DURATION (out) = sample_count * GST_SECOND / vd->vi.rate;
777 result = vorbis_dec_push (vd, out);
779 if (vd->granulepos != -1)
780 vd->granulepos += sample_count;
783 result = GST_FLOW_OK;
785 vorbis_synthesis_read (&vd->vd, sample_count);
788 result = GST_FLOW_OK;
791 /* granulepos is the last sample in the packet */
792 if (packet->granulepos != -1)
793 vd->granulepos = packet->granulepos;
800 GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
801 (NULL), ("no header sent yet (packet no is %d)", packet->packetno));
802 return GST_FLOW_ERROR;
806 GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
807 (NULL), ("couldn't read data packet"));
808 return GST_FLOW_ERROR;
812 GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
813 (NULL), ("vorbis decoder did not accept data packet"));
814 return GST_FLOW_ERROR;
819 vorbis_dec_chain (GstPad * pad, GstBuffer * buffer)
823 GstFlowReturn result = GST_FLOW_OK;
825 vd = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
827 if (GST_BUFFER_SIZE (buffer) == 0) {
828 gst_buffer_unref (buffer);
829 GST_ELEMENT_ERROR (vd, STREAM, DECODE, (NULL), ("empty buffer received"));
830 return GST_FLOW_ERROR;
832 /* make ogg_packet out of the buffer */
833 packet.packet = GST_BUFFER_DATA (buffer);
834 packet.bytes = GST_BUFFER_SIZE (buffer);
835 packet.granulepos = GST_BUFFER_OFFSET_END (buffer);
836 packet.packetno = vd->packetno++;
838 * FIXME. Is there anyway to know that this is the last packet and
840 * Yes there is, keep one packet at all times and only push out when
841 * you receive a new one. Implement this.
845 GST_DEBUG_OBJECT (vd, "vorbis granule: %" G_GUINT64_FORMAT,
848 /* switch depending on packet type */
849 if (packet.packet[0] & 1) {
850 if (vd->initialized) {
851 GST_WARNING_OBJECT (vd, "Ignoring header");
854 result = vorbis_handle_header_packet (vd, &packet);
856 result = vorbis_handle_data_packet (vd, &packet);
859 GST_DEBUG_OBJECT (vd, "offset end: %" G_GUINT64_FORMAT,
860 GST_BUFFER_OFFSET_END (buffer));
863 gst_buffer_unref (buffer);
868 static GstStateChangeReturn
869 vorbis_dec_change_state (GstElement * element, GstStateChange transition)
871 GstVorbisDec *vd = GST_VORBIS_DEC (element);
872 GstStateChangeReturn res;
875 switch (transition) {
876 case GST_STATE_CHANGE_NULL_TO_READY:
878 case GST_STATE_CHANGE_READY_TO_PAUSED:
879 vorbis_info_init (&vd->vi);
880 vorbis_comment_init (&vd->vc);
881 vd->initialized = FALSE;
885 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
891 res = parent_class->change_state (element, transition);
893 switch (transition) {
894 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
896 case GST_STATE_CHANGE_PAUSED_TO_READY:
897 GST_DEBUG_OBJECT (vd, "PAUSED -> READY, clearing vorbis structures");
898 vorbis_block_clear (&vd->vb);
899 vorbis_dsp_clear (&vd->vd);
900 vorbis_comment_clear (&vd->vc);
901 vorbis_info_clear (&vd->vi);
903 case GST_STATE_CHANGE_READY_TO_NULL: