All plugins updated for element state changes.
[platform/upstream/gstreamer.git] / ext / vorbis / vorbisdec.c
1 /* GStreamer
2  * Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #include "vorbisdec.h"
25 #include <string.h>
26 #include <gst/tag/tag.h>
27 #include <gst/audio/multichannel.h>
28
29 GST_DEBUG_CATEGORY_EXTERN (vorbisdec_debug);
30 #define GST_CAT_DEFAULT vorbisdec_debug
31
32 static GstElementDetails vorbis_dec_details = {
33   "VorbisDec",
34   "Codec/Decoder/Audio",
35   "decode raw vorbis streams to float audio",
36   "Benjamin Otte <in7y118@public.uni-hamburg.de>",
37 };
38
39 /* Filter signals and args */
40 enum
41 {
42   /* FILL ME */
43   LAST_SIGNAL
44 };
45
46 enum
47 {
48   ARG_0
49 };
50
51 static GstStaticPadTemplate vorbis_dec_src_factory =
52 GST_STATIC_PAD_TEMPLATE ("src",
53     GST_PAD_SRC,
54     GST_PAD_ALWAYS,
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\", "
61 #endif
62 */
63         "width = (int) 32, " "buffer-frames = (int) 0")
64     );
65
66 static GstStaticPadTemplate vorbis_dec_sink_factory =
67 GST_STATIC_PAD_TEMPLATE ("sink",
68     GST_PAD_SINK,
69     GST_PAD_ALWAYS,
70     GST_STATIC_CAPS ("audio/x-vorbis")
71     );
72
73 GST_BOILERPLATE (GstVorbisDec, gst_vorbis_dec, GstElement, GST_TYPE_ELEMENT);
74
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);
80
81 #if 0
82 static const GstFormat *vorbis_dec_get_formats (GstPad * pad);
83 #endif
84
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);
90
91 static gboolean vorbis_dec_sink_query (GstPad * pad, GstQuery * query);
92
93 static void
94 gst_vorbis_dec_base_init (gpointer g_class)
95 {
96   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
97
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);
103 }
104
105 static void
106 gst_vorbis_dec_class_init (GstVorbisDecClass * klass)
107 {
108   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
109   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
110
111   gobject_class->finalize = vorbisdec_finalize;
112
113   gstelement_class->change_state = vorbis_dec_change_state;
114 }
115
116 #if 0
117 static const GstFormat *
118 vorbis_dec_get_formats (GstPad * pad)
119 {
120   static GstFormat src_formats[] = {
121     GST_FORMAT_BYTES,
122     GST_FORMAT_DEFAULT,         /* samples in the audio case */
123     GST_FORMAT_TIME,
124     0
125   };
126   static GstFormat sink_formats[] = {
127     /*GST_FORMAT_BYTES, */
128     GST_FORMAT_TIME,
129     GST_FORMAT_DEFAULT,         /* granulepos or samples */
130     0
131   };
132
133   return (GST_PAD_IS_SRC (pad) ? src_formats : sink_formats);
134 }
135 #endif
136
137 #if 0
138 static const GstEventMask *
139 vorbis_get_event_masks (GstPad * pad)
140 {
141   static const GstEventMask vorbis_dec_src_event_masks[] = {
142     {GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH},
143     {0,}
144   };
145
146   return vorbis_dec_src_event_masks;
147 }
148 #endif
149
150 static const GstQueryType *
151 vorbis_get_query_types (GstPad * pad)
152 {
153   static const GstQueryType vorbis_dec_src_query_types[] = {
154     GST_QUERY_POSITION,
155     0
156   };
157
158   return vorbis_dec_src_query_types;
159 }
160
161 static void
162 gst_vorbis_dec_init (GstVorbisDec * dec, GstVorbisDecClass * g_class)
163 {
164   dec->sinkpad =
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);
171
172   dec->srcpad =
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);
179
180   dec->queued = NULL;
181 }
182
183 static void
184 vorbisdec_finalize (GObject * object)
185 {
186   /* Release any possibly allocated libvorbis data. 
187    * _clear functions can safely be called multiple times
188    */
189   GstVorbisDec *vd = GST_VORBIS_DEC (object);
190
191   vorbis_block_clear (&vd->vb);
192   vorbis_dsp_clear (&vd->vd);
193   vorbis_comment_clear (&vd->vc);
194   vorbis_info_clear (&vd->vi);
195 }
196
197 static gboolean
198 vorbis_dec_convert (GstPad * pad,
199     GstFormat src_format, gint64 src_value,
200     GstFormat * dest_format, gint64 * dest_value)
201 {
202   gboolean res = TRUE;
203   GstVorbisDec *dec;
204   guint64 scale = 1;
205
206   dec = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
207
208   if (dec->packetno < 1)
209     return FALSE;
210
211   if (src_format == *dest_format) {
212     *dest_value = src_value;
213     return TRUE;
214   }
215
216   if (dec->sinkpad == pad &&
217       (src_format == GST_FORMAT_BYTES || *dest_format == GST_FORMAT_BYTES))
218     return FALSE;
219
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);
227           break;
228         default:
229           res = FALSE;
230       }
231       break;
232     case GST_FORMAT_DEFAULT:
233       switch (*dest_format) {
234         case GST_FORMAT_BYTES:
235           *dest_value = src_value * sizeof (float) * dec->vi.channels;
236           break;
237         case GST_FORMAT_TIME:
238           *dest_value =
239               gst_util_uint64_scale (src_value, GST_SECOND, dec->vi.rate);
240           break;
241         default:
242           res = FALSE;
243       }
244       break;
245     case GST_FORMAT_BYTES:
246       switch (*dest_format) {
247         case GST_FORMAT_DEFAULT:
248           *dest_value = src_value / (sizeof (float) * dec->vi.channels);
249           break;
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);
253           break;
254         default:
255           res = FALSE;
256       }
257       break;
258     default:
259       res = FALSE;
260   }
261
262   return res;
263 }
264
265 static gboolean
266 vorbis_dec_src_query (GstPad * pad, GstQuery * query)
267 {
268   gint64 granulepos;
269   GstVorbisDec *dec;
270   gboolean res;
271
272   dec = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
273
274   switch (GST_QUERY_TYPE (query)) {
275     case GST_QUERY_POSITION:
276     {
277       GstFormat format;
278       gint64 value, total;
279
280       /* query peer for total length */
281       if (!(res = gst_pad_query (GST_PAD_PEER (dec->sinkpad), query)))
282         goto error;
283
284       granulepos = dec->granulepos;
285
286       gst_query_parse_position (query, &format, NULL, &total);
287
288       /* and convert to the final format */
289       if (!(res =
290               vorbis_dec_convert (pad, GST_FORMAT_DEFAULT, granulepos, &format,
291                   &value)))
292         goto error;
293
294       value = (value - dec->segment_start) + dec->segment_base;
295
296       gst_query_set_position (query, format, value, total);
297
298       GST_LOG_OBJECT (dec,
299           "query %u: peer returned granulepos: %llu - we return %llu (format %u)",
300           query, granulepos, value, format);
301
302       break;
303     }
304     case GST_QUERY_CONVERT:
305     {
306       GstFormat src_fmt, dest_fmt;
307       gint64 src_val, dest_val;
308
309       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
310       if (!(res =
311               vorbis_dec_convert (pad, src_fmt, src_val, &dest_fmt, &dest_val)))
312         goto error;
313       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
314       break;
315     }
316     default:
317       res = FALSE;
318       break;
319   }
320   return res;
321
322 error:
323   {
324     GST_WARNING_OBJECT (dec, "error handling query");
325     return res;
326   }
327 }
328
329 static gboolean
330 vorbis_dec_sink_query (GstPad * pad, GstQuery * query)
331 {
332   GstVorbisDec *dec;
333   gboolean res;
334
335   dec = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
336
337   switch (GST_QUERY_TYPE (query)) {
338     case GST_QUERY_CONVERT:
339     {
340       GstFormat src_fmt, dest_fmt;
341       gint64 src_val, dest_val;
342
343       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
344       if (!(res =
345               vorbis_dec_convert (pad, src_fmt, src_val, &dest_fmt, &dest_val)))
346         goto error;
347       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
348       break;
349     }
350     default:
351       res = FALSE;
352       break;
353   }
354 error:
355   return res;
356 }
357
358 static gboolean
359 vorbis_dec_src_event (GstPad * pad, GstEvent * event)
360 {
361   gboolean res = TRUE;
362   GstVorbisDec *dec = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
363
364   switch (GST_EVENT_TYPE (event)) {
365     case GST_EVENT_SEEK:{
366       GstFormat format, tformat;
367       gdouble rate;
368       GstEvent *real_seek;
369       GstSeekFlags flags;
370       GstSeekType cur_type, stop_type;
371       gint64 cur, stop;
372       gint64 tcur, tstop;
373
374       gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
375           &stop_type, &stop);
376
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.
380        *
381        * First bring the requested format to time
382        */
383       tformat = GST_FORMAT_TIME;
384       if (!(res = vorbis_dec_convert (pad, format, cur, &tformat, &tcur)))
385         goto error;
386       if (!(res = vorbis_dec_convert (pad, format, stop, &tformat, &tstop)))
387         goto error;
388
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);
392
393       res = gst_pad_push_event (dec->sinkpad, real_seek);
394
395       gst_event_unref (event);
396       break;
397     }
398     default:
399       res = gst_pad_event_default (pad, event);
400       break;
401   }
402
403   return res;
404
405 error:
406   gst_event_unref (event);
407   return res;
408 }
409
410 static gboolean
411 vorbis_dec_sink_event (GstPad * pad, GstEvent * event)
412 {
413   gboolean ret = FALSE;
414   GstVorbisDec *dec;
415
416   dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
417
418   GST_LOG_OBJECT (dec, "handling event");
419   switch (GST_EVENT_TYPE (event)) {
420     case GST_EVENT_EOS:
421       GST_STREAM_LOCK (pad);
422       ret = gst_pad_push_event (dec->srcpad, event);
423       GST_STREAM_UNLOCK (pad);
424       break;
425     case GST_EVENT_NEWSEGMENT:
426     {
427       GstFormat format;
428       gdouble rate;
429       gint64 start, stop, base;
430
431       GST_STREAM_LOCK (pad);
432       gst_event_parse_newsegment (event, &rate, &format, &start, &stop, &base);
433
434       if (format != GST_FORMAT_TIME)
435         goto newseg_wrong_format;
436
437       if (rate <= 0.0)
438         goto newseg_wrong_rate;
439
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;
445
446       dec->granulepos = -1;
447 #ifdef HAVE_VORBIS_SYNTHESIS_RESTART
448       vorbis_synthesis_restart (&dec->vd);
449 #endif
450       ret = gst_pad_push_event (dec->srcpad, event);
451       GST_STREAM_UNLOCK (pad);
452       break;
453     }
454     default:
455       ret = gst_pad_push_event (dec->srcpad, event);
456       break;
457   }
458 done:
459   gst_object_unref (dec);
460
461   return ret;
462   /* ERRORS */
463 newseg_wrong_format:
464   {
465     GST_STREAM_UNLOCK (pad);
466     GST_DEBUG ("received non TIME newsegment");
467     goto done;
468   }
469 newseg_wrong_rate:
470   {
471     GST_STREAM_UNLOCK (pad);
472     GST_DEBUG ("negative rates not supported yet");
473     goto done;
474   }
475
476 }
477
478 static GstFlowReturn
479 vorbis_handle_identification_packet (GstVorbisDec * vd)
480 {
481   GstCaps *caps;
482   const GstAudioChannelPosition *pos = NULL;
483
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);
489
490   switch (vd->vi.channels) {
491     case 1:
492     case 2:
493       /* nothing */
494       break;
495     case 3:{
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
500       };
501       pos = pos3;
502       break;
503     }
504     case 4:{
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
510       };
511       pos = pos4;
512       break;
513     }
514     case 5:{
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
521       };
522       pos = pos5;
523       break;
524     }
525     case 6:{
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
533       };
534       pos = pos6;
535       break;
536     }
537     default:
538       goto channel_count_error;
539   }
540   if (pos) {
541     gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
542   }
543   gst_pad_set_caps (vd->srcpad, caps);
544   gst_caps_unref (caps);
545
546   return GST_FLOW_OK;
547
548   /* ERROR */
549 channel_count_error:
550   {
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;
555   }
556 }
557
558 static GstFlowReturn
559 vorbis_handle_comment_packet (GstVorbisDec * vd, ogg_packet * packet)
560 {
561   guint bitrate = 0;
562   gchar *encoder = NULL;
563   GstMessage *message;
564   GstTagList *list;
565   GstBuffer *buf;
566
567   GST_DEBUG_OBJECT (vd, "parsing comment packet");
568
569   buf = gst_buffer_new_and_alloc (packet->bytes);
570   GST_BUFFER_DATA (buf) = packet->packet;
571
572   list =
573       gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\003vorbis", 7,
574       &encoder);
575
576   gst_buffer_unref (buf);
577
578   if (!list) {
579     GST_ERROR_OBJECT (vd, "couldn't decode comments");
580     list = gst_tag_list_new ();
581   }
582   if (encoder) {
583     gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
584         GST_TAG_ENCODER, encoder, NULL);
585     g_free (encoder);
586   }
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;
594   }
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);
598     if (!bitrate)
599       bitrate = vd->vi.bitrate_upper;
600   }
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);
604     if (!bitrate)
605       bitrate = vd->vi.bitrate_lower;
606   }
607   if (bitrate) {
608     gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
609         GST_TAG_BITRATE, (guint) bitrate, NULL);
610   }
611
612   message = gst_message_new_tag ((GstObject *) vd, list);
613   gst_element_post_message (GST_ELEMENT (vd), message);
614
615   return GST_FLOW_OK;
616 }
617
618 static GstFlowReturn
619 vorbis_handle_type_packet (GstVorbisDec * vd)
620 {
621   g_assert (vd->initialized == FALSE);
622
623   vorbis_synthesis_init (&vd->vd, &vd->vi);
624   vorbis_block_init (&vd->vd, &vd->vb);
625   vd->initialized = TRUE;
626
627   return GST_FLOW_OK;
628 }
629
630 static GstFlowReturn
631 vorbis_handle_header_packet (GstVorbisDec * vd, ogg_packet * packet)
632 {
633   GstFlowReturn res;
634
635   GST_DEBUG_OBJECT (vd, "parsing header packet");
636
637   /* Packetno = 0 if the first byte is exactly 0x01 */
638   packet->b_o_s = (packet->packet[0] == 0x1) ? 1 : 0;
639
640   if (vorbis_synthesis_headerin (&vd->vi, &vd->vc, packet))
641     goto header_read_error;
642
643   /* FIXME: we should probably double-check if packet[0] is 1/3/5 for each
644    * of these */
645   switch (packet->packetno) {
646     case 0:
647       res = vorbis_handle_identification_packet (vd);
648       break;
649     case 1:
650       res = vorbis_handle_comment_packet (vd, packet);
651       break;
652     case 2:
653       res = vorbis_handle_type_packet (vd);
654       break;
655     default:
656       /* ignore */
657       res = GST_FLOW_OK;
658       break;
659   }
660   return res;
661
662   /* ERRORS */
663 header_read_error:
664   {
665     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
666         (NULL), ("couldn't read header packet"));
667     return GST_FLOW_ERROR;
668   }
669 }
670
671 static void
672 copy_samples (float *out, float **in, guint samples, gint channels)
673 {
674   gint i, j;
675
676 #ifdef GST_VORBIS_DEC_SEQUENTIAL
677   for (i = 0; i < channels; i++) {
678     memcpy (out, in[i], samples * sizeof (float));
679     out += samples;
680   }
681 #else
682   for (j = 0; j < samples; j++) {
683     for (i = 0; i < channels; i++) {
684       *out++ = in[i][j];
685     }
686   }
687 #endif
688 }
689
690 static GstFlowReturn
691 vorbis_dec_push (GstVorbisDec * dec, GstBuffer * buf)
692 {
693   GstFlowReturn result;
694   gint64 outoffset = GST_BUFFER_OFFSET (buf);
695
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;
700   } else {
701     if (dec->queued) {
702       gint64 size;
703       GList *walk;
704
705       GST_DEBUG_OBJECT (dec, "first buffer with offset %lld", outoffset);
706
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);
711
712         outoffset -=
713             GST_BUFFER_SIZE (buffer) / (sizeof (float) * dec->vi.channels);
714
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);
720         size--;
721       }
722       for (walk = dec->queued; walk; walk = g_list_next (walk)) {
723         GstBuffer *buffer = GST_BUFFER (walk->data);
724
725         /* ignore the result */
726         gst_pad_push (dec->srcpad, buffer);
727       }
728       g_list_free (dec->queued);
729       dec->queued = NULL;
730     }
731     result = gst_pad_push (dec->srcpad, buf);
732   }
733
734   return result;
735 }
736
737 static GstFlowReturn
738 vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet)
739 {
740   float **pcm;
741   guint sample_count;
742   GstFlowReturn result;
743
744   if (!vd->initialized)
745     goto not_initialized;
746
747   /* normal data packet */
748   if (vorbis_synthesis (&vd->vb, packet))
749     goto could_not_read;
750
751   if (vorbis_synthesis_blockin (&vd->vd, &vd->vb) < 0)
752     goto not_accepted;
753
754   sample_count = vorbis_synthesis_pcmout (&vd->vd, &pcm);
755   if (sample_count > 0) {
756     GstBuffer *out;
757
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);
761
762     if (result == GST_FLOW_OK) {
763       float *out_data = (float *) GST_BUFFER_DATA (out);
764
765       copy_samples (out_data, pcm, sample_count, vd->vi.channels);
766
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);
772       } else {
773         GST_BUFFER_TIMESTAMP (out) = -1;
774       }
775       GST_BUFFER_DURATION (out) = sample_count * GST_SECOND / vd->vi.rate;
776
777       result = vorbis_dec_push (vd, out);
778
779       if (vd->granulepos != -1)
780         vd->granulepos += sample_count;
781     } else {
782       /* no buffer.. */
783       result = GST_FLOW_OK;
784     }
785     vorbis_synthesis_read (&vd->vd, sample_count);
786   } else {
787     /* no samples.. */
788     result = GST_FLOW_OK;
789   }
790
791   /* granulepos is the last sample in the packet */
792   if (packet->granulepos != -1)
793     vd->granulepos = packet->granulepos;
794
795   return result;
796
797   /* ERRORS */
798 not_initialized:
799   {
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;
803   }
804 could_not_read:
805   {
806     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
807         (NULL), ("couldn't read data packet"));
808     return GST_FLOW_ERROR;
809   }
810 not_accepted:
811   {
812     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
813         (NULL), ("vorbis decoder did not accept data packet"));
814     return GST_FLOW_ERROR;
815   }
816 }
817
818 static GstFlowReturn
819 vorbis_dec_chain (GstPad * pad, GstBuffer * buffer)
820 {
821   GstVorbisDec *vd;
822   ogg_packet packet;
823   GstFlowReturn result = GST_FLOW_OK;
824
825   vd = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
826
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;
831   }
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++;
837   /*
838    * FIXME. Is there anyway to know that this is the last packet and
839    * set e_o_s??
840    * Yes there is, keep one packet at all times and only push out when
841    * you receive a new one.  Implement this.
842    */
843   packet.e_o_s = 0;
844
845   GST_DEBUG_OBJECT (vd, "vorbis granule: %" G_GUINT64_FORMAT,
846       packet.granulepos);
847
848   /* switch depending on packet type */
849   if (packet.packet[0] & 1) {
850     if (vd->initialized) {
851       GST_WARNING_OBJECT (vd, "Ignoring header");
852       goto done;
853     }
854     result = vorbis_handle_header_packet (vd, &packet);
855   } else {
856     result = vorbis_handle_data_packet (vd, &packet);
857   }
858
859   GST_DEBUG_OBJECT (vd, "offset end: %" G_GUINT64_FORMAT,
860       GST_BUFFER_OFFSET_END (buffer));
861
862 done:
863   gst_buffer_unref (buffer);
864
865   return result;
866 }
867
868 static GstStateChangeReturn
869 vorbis_dec_change_state (GstElement * element, GstStateChange transition)
870 {
871   GstVorbisDec *vd = GST_VORBIS_DEC (element);
872   GstStateChangeReturn res;
873
874
875   switch (transition) {
876     case GST_STATE_CHANGE_NULL_TO_READY:
877       break;
878     case GST_STATE_CHANGE_READY_TO_PAUSED:
879       vorbis_info_init (&vd->vi);
880       vorbis_comment_init (&vd->vc);
881       vd->initialized = FALSE;
882       vd->granulepos = -1;
883       vd->packetno = 0;
884       break;
885     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
886       break;
887     default:
888       break;
889   }
890
891   res = parent_class->change_state (element, transition);
892
893   switch (transition) {
894     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
895       break;
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);
902       break;
903     case GST_STATE_CHANGE_READY_TO_NULL:
904       break;
905     default:
906       break;
907   }
908
909   return res;
910 }