Update for alloc_buffer 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/audio/audio.h>
27 #include <gst/tag/tag.h>
28 #include <gst/audio/multichannel.h>
29
30 GST_DEBUG_CATEGORY_EXTERN (vorbisdec_debug);
31 #define GST_CAT_DEFAULT vorbisdec_debug
32
33 static GstElementDetails vorbis_dec_details = {
34   "VorbisDec",
35   "Codec/Decoder/Audio",
36   "decode raw vorbis streams to float audio",
37   "Benjamin Otte <in7y118@public.uni-hamburg.de>",
38 };
39
40 /* Filter signals and args */
41 enum
42 {
43   /* FILL ME */
44   LAST_SIGNAL
45 };
46
47 enum
48 {
49   ARG_0
50 };
51
52 static GstStaticPadTemplate vorbis_dec_src_factory =
53 GST_STATIC_PAD_TEMPLATE ("src",
54     GST_PAD_SRC,
55     GST_PAD_ALWAYS,
56     GST_STATIC_CAPS ("audio/x-raw-float, "
57         "rate = (int) [ 8000, 50000 ], "
58         "channels = (int) [ 1, 6 ], " "endianness = (int) BYTE_ORDER, "
59 /* no ifdef in macros, please
60 #ifdef GST_VORBIS_DEC_SEQUENTIAL
61       "layout = \"sequential\", "
62 #endif
63 */
64         "width = (int) 32")
65     );
66
67 static GstStaticPadTemplate vorbis_dec_sink_factory =
68 GST_STATIC_PAD_TEMPLATE ("sink",
69     GST_PAD_SINK,
70     GST_PAD_ALWAYS,
71     GST_STATIC_CAPS ("audio/x-vorbis")
72     );
73
74 GST_BOILERPLATE (GstVorbisDec, gst_vorbis_dec, GstElement, GST_TYPE_ELEMENT);
75
76 static void vorbisdec_finalize (GObject * object);
77 static gboolean vorbis_dec_sink_event (GstPad * pad, GstEvent * event);
78 static GstFlowReturn vorbis_dec_chain (GstPad * pad, GstBuffer * buffer);
79 static GstStateChangeReturn vorbis_dec_change_state (GstElement * element,
80     GstStateChange transition);
81
82 #if 0
83 static const GstFormat *vorbis_dec_get_formats (GstPad * pad);
84 #endif
85
86 static gboolean vorbis_dec_src_event (GstPad * pad, GstEvent * event);
87 static gboolean vorbis_dec_src_query (GstPad * pad, GstQuery * query);
88 static gboolean vorbis_dec_convert (GstPad * pad,
89     GstFormat src_format, gint64 src_value,
90     GstFormat * dest_format, gint64 * dest_value);
91
92 static gboolean vorbis_dec_sink_query (GstPad * pad, GstQuery * query);
93
94 static void
95 gst_vorbis_dec_base_init (gpointer g_class)
96 {
97   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
98   GstPadTemplate *src_template, *sink_template;
99
100   src_template = gst_static_pad_template_get (&vorbis_dec_src_factory);
101   gst_element_class_add_pad_template (element_class, src_template);
102
103   sink_template = gst_static_pad_template_get (&vorbis_dec_sink_factory);
104   gst_element_class_add_pad_template (element_class, sink_template);
105
106   gst_element_class_set_details (element_class, &vorbis_dec_details);
107 }
108
109 static void
110 gst_vorbis_dec_class_init (GstVorbisDecClass * klass)
111 {
112   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
113   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
114
115   gobject_class->finalize = vorbisdec_finalize;
116
117   gstelement_class->change_state = vorbis_dec_change_state;
118 }
119
120 #if 0
121 static const GstFormat *
122 vorbis_dec_get_formats (GstPad * pad)
123 {
124   static GstFormat src_formats[] = {
125     GST_FORMAT_BYTES,
126     GST_FORMAT_DEFAULT,         /* samples in the audio case */
127     GST_FORMAT_TIME,
128     0
129   };
130   static GstFormat sink_formats[] = {
131     /*GST_FORMAT_BYTES, */
132     GST_FORMAT_TIME,
133     GST_FORMAT_DEFAULT,         /* granulepos or samples */
134     0
135   };
136
137   return (GST_PAD_IS_SRC (pad) ? src_formats : sink_formats);
138 }
139 #endif
140
141 #if 0
142 static const GstEventMask *
143 vorbis_get_event_masks (GstPad * pad)
144 {
145   static const GstEventMask vorbis_dec_src_event_masks[] = {
146     {GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH},
147     {0,}
148   };
149
150   return vorbis_dec_src_event_masks;
151 }
152 #endif
153
154 static const GstQueryType *
155 vorbis_get_query_types (GstPad * pad)
156 {
157   static const GstQueryType vorbis_dec_src_query_types[] = {
158     GST_QUERY_POSITION,
159     0
160   };
161
162   return vorbis_dec_src_query_types;
163 }
164
165 static void
166 gst_vorbis_dec_init (GstVorbisDec * dec, GstVorbisDecClass * g_class)
167 {
168   dec->sinkpad = gst_pad_new_from_static_template (&vorbis_dec_sink_factory,
169       "sink");
170
171   gst_pad_set_event_function (dec->sinkpad, vorbis_dec_sink_event);
172   gst_pad_set_chain_function (dec->sinkpad, vorbis_dec_chain);
173   gst_pad_set_query_function (dec->sinkpad, vorbis_dec_sink_query);
174   gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
175
176   dec->srcpad = gst_pad_new_from_static_template (&vorbis_dec_src_factory,
177       "src");
178
179   gst_pad_set_event_function (dec->srcpad, vorbis_dec_src_event);
180   gst_pad_set_query_type_function (dec->srcpad, vorbis_get_query_types);
181   gst_pad_set_query_function (dec->srcpad, vorbis_dec_src_query);
182   gst_pad_use_fixed_caps (dec->srcpad);
183   gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
184
185   dec->queued = NULL;
186 }
187
188 static void
189 vorbisdec_finalize (GObject * object)
190 {
191   /* Release any possibly allocated libvorbis data.
192    * _clear functions can safely be called multiple times
193    */
194   GstVorbisDec *vd = GST_VORBIS_DEC (object);
195
196   vorbis_block_clear (&vd->vb);
197   vorbis_dsp_clear (&vd->vd);
198   vorbis_comment_clear (&vd->vc);
199   vorbis_info_clear (&vd->vi);
200
201   G_OBJECT_CLASS (parent_class)->finalize (object);
202 }
203
204 static gboolean
205 vorbis_dec_convert (GstPad * pad,
206     GstFormat src_format, gint64 src_value,
207     GstFormat * dest_format, gint64 * dest_value)
208 {
209   gboolean res = TRUE;
210   GstVorbisDec *dec;
211   guint64 scale = 1;
212
213   dec = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
214
215   if (dec->packetno < 1)
216     return FALSE;
217
218   if (src_format == *dest_format) {
219     *dest_value = src_value;
220     return TRUE;
221   }
222
223   if (dec->sinkpad == pad &&
224       (src_format == GST_FORMAT_BYTES || *dest_format == GST_FORMAT_BYTES))
225     return FALSE;
226
227   switch (src_format) {
228     case GST_FORMAT_TIME:
229       switch (*dest_format) {
230         case GST_FORMAT_BYTES:
231           scale = sizeof (float) * dec->vi.channels;
232         case GST_FORMAT_DEFAULT:
233           *dest_value = scale * (src_value * dec->vi.rate / GST_SECOND);
234           break;
235         default:
236           res = FALSE;
237       }
238       break;
239     case GST_FORMAT_DEFAULT:
240       switch (*dest_format) {
241         case GST_FORMAT_BYTES:
242           *dest_value = src_value * sizeof (float) * dec->vi.channels;
243           break;
244         case GST_FORMAT_TIME:
245           *dest_value =
246               gst_util_uint64_scale (src_value, GST_SECOND, dec->vi.rate);
247           break;
248         default:
249           res = FALSE;
250       }
251       break;
252     case GST_FORMAT_BYTES:
253       switch (*dest_format) {
254         case GST_FORMAT_DEFAULT:
255           *dest_value = src_value / (sizeof (float) * dec->vi.channels);
256           break;
257         case GST_FORMAT_TIME:
258           *dest_value = gst_util_uint64_scale (src_value, GST_SECOND,
259               dec->vi.rate * sizeof (float) * dec->vi.channels);
260           break;
261         default:
262           res = FALSE;
263       }
264       break;
265     default:
266       res = FALSE;
267   }
268
269   return res;
270 }
271
272 static gboolean
273 vorbis_dec_src_query (GstPad * pad, GstQuery * query)
274 {
275   gint64 granulepos;
276   GstVorbisDec *dec;
277   gboolean res;
278
279   dec = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
280
281   switch (GST_QUERY_TYPE (query)) {
282     case GST_QUERY_POSITION:
283     {
284       GstFormat format;
285       gint64 value;
286
287       granulepos = dec->granulepos;
288
289       gst_query_parse_position (query, &format, NULL);
290
291       /* and convert to the final format */
292       if (!(res =
293               vorbis_dec_convert (pad, GST_FORMAT_DEFAULT, granulepos, &format,
294                   &value)))
295         goto error;
296
297       value = (value - dec->segment_start) + dec->segment_time;
298
299       gst_query_set_position (query, format, value);
300
301       GST_LOG_OBJECT (dec,
302           "query %u: peer returned granulepos: %llu - we return %llu (format %u)",
303           query, granulepos, value, format);
304
305       break;
306     }
307     case GST_QUERY_DURATION:
308     {
309       /* query peer for total length */
310       if (!(res = gst_pad_query (GST_PAD_PEER (dec->sinkpad), query)))
311         goto error;
312       break;
313     }
314     case GST_QUERY_CONVERT:
315     {
316       GstFormat src_fmt, dest_fmt;
317       gint64 src_val, dest_val;
318
319       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
320       if (!(res =
321               vorbis_dec_convert (pad, src_fmt, src_val, &dest_fmt, &dest_val)))
322         goto error;
323       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
324       break;
325     }
326     default:
327       res = FALSE;
328       break;
329   }
330   return res;
331
332 error:
333   {
334     GST_WARNING_OBJECT (dec, "error handling query");
335     return res;
336   }
337 }
338
339 static gboolean
340 vorbis_dec_sink_query (GstPad * pad, GstQuery * query)
341 {
342   GstVorbisDec *dec;
343   gboolean res;
344
345   dec = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
346
347   switch (GST_QUERY_TYPE (query)) {
348     case GST_QUERY_CONVERT:
349     {
350       GstFormat src_fmt, dest_fmt;
351       gint64 src_val, dest_val;
352
353       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
354       if (!(res =
355               vorbis_dec_convert (pad, src_fmt, src_val, &dest_fmt, &dest_val)))
356         goto error;
357       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
358       break;
359     }
360     default:
361       res = FALSE;
362       break;
363   }
364 error:
365   return res;
366 }
367
368 static gboolean
369 vorbis_dec_src_event (GstPad * pad, GstEvent * event)
370 {
371   gboolean res = TRUE;
372   GstVorbisDec *dec = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
373
374   switch (GST_EVENT_TYPE (event)) {
375     case GST_EVENT_SEEK:{
376       GstFormat format, tformat;
377       gdouble rate;
378       GstEvent *real_seek;
379       GstSeekFlags flags;
380       GstSeekType cur_type, stop_type;
381       gint64 cur, stop;
382       gint64 tcur, tstop;
383
384       gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
385           &stop_type, &stop);
386
387       /* we have to ask our peer to seek to time here as we know
388        * nothing about how to generate a granulepos from the src
389        * formats or anything.
390        *
391        * First bring the requested format to time
392        */
393       tformat = GST_FORMAT_TIME;
394       if (!(res = vorbis_dec_convert (pad, format, cur, &tformat, &tcur)))
395         goto error;
396       if (!(res = vorbis_dec_convert (pad, format, stop, &tformat, &tstop)))
397         goto error;
398
399       /* then seek with time on the peer */
400       real_seek = gst_event_new_seek (rate, GST_FORMAT_TIME,
401           flags, cur_type, tcur, stop_type, tstop);
402
403       res = gst_pad_push_event (dec->sinkpad, real_seek);
404
405       gst_event_unref (event);
406       break;
407     }
408     default:
409       res = gst_pad_event_default (pad, event);
410       break;
411   }
412
413   return res;
414
415 error:
416   gst_event_unref (event);
417   return res;
418 }
419
420 static gboolean
421 vorbis_dec_sink_event (GstPad * pad, GstEvent * event)
422 {
423   gboolean ret = FALSE;
424   GstVorbisDec *dec;
425
426   dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
427
428   GST_LOG_OBJECT (dec, "handling event");
429   switch (GST_EVENT_TYPE (event)) {
430     case GST_EVENT_EOS:
431       ret = gst_pad_push_event (dec->srcpad, event);
432       break;
433     case GST_EVENT_NEWSEGMENT:
434     {
435       GstFormat format;
436       gdouble rate;
437       gint64 start, stop, time;
438       gboolean update;
439
440       gst_event_parse_new_segment (event, &update, &rate, &format, &start,
441           &stop, &time);
442
443       if (format != GST_FORMAT_TIME)
444         goto newseg_wrong_format;
445
446       if (rate <= 0.0)
447         goto newseg_wrong_rate;
448
449       /* now copy over the values */
450       dec->segment_rate = rate;
451       dec->segment_start = start;
452       dec->segment_stop = stop;
453       dec->segment_time = time;
454
455       dec->granulepos = -1;
456       dec->cur_timestamp = GST_CLOCK_TIME_NONE;
457       dec->prev_timestamp = GST_CLOCK_TIME_NONE;
458
459 #ifdef HAVE_VORBIS_SYNTHESIS_RESTART
460       vorbis_synthesis_restart (&dec->vd);
461 #endif
462       ret = gst_pad_push_event (dec->srcpad, event);
463       break;
464     }
465     default:
466       ret = gst_pad_push_event (dec->srcpad, event);
467       break;
468   }
469 done:
470   gst_object_unref (dec);
471
472   return ret;
473   /* ERRORS */
474 newseg_wrong_format:
475   {
476     GST_DEBUG ("received non TIME newsegment");
477     goto done;
478   }
479 newseg_wrong_rate:
480   {
481     GST_DEBUG ("negative rates not supported yet");
482     goto done;
483   }
484
485 }
486
487 static GstFlowReturn
488 vorbis_handle_identification_packet (GstVorbisDec * vd)
489 {
490   GstCaps *caps;
491   const GstAudioChannelPosition *pos = NULL;
492
493   caps = gst_caps_new_simple ("audio/x-raw-float",
494       "rate", G_TYPE_INT, vd->vi.rate,
495       "channels", G_TYPE_INT, vd->vi.channels,
496       "endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32, NULL);
497
498   switch (vd->vi.channels) {
499     case 1:
500     case 2:
501       /* nothing */
502       break;
503     case 3:{
504       static GstAudioChannelPosition pos3[] = {
505         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
506         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
507         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
508       };
509       pos = pos3;
510       break;
511     }
512     case 4:{
513       static GstAudioChannelPosition pos4[] = {
514         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
515         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
516         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
517         GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT
518       };
519       pos = pos4;
520       break;
521     }
522     case 5:{
523       static GstAudioChannelPosition pos5[] = {
524         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
525         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
526         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
527         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
528         GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT
529       };
530       pos = pos5;
531       break;
532     }
533     case 6:{
534       static GstAudioChannelPosition pos6[] = {
535         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
536         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
537         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
538         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
539         GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
540         GST_AUDIO_CHANNEL_POSITION_LFE
541       };
542       pos = pos6;
543       break;
544     }
545     default:
546       goto channel_count_error;
547   }
548   if (pos) {
549     gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
550   }
551   gst_pad_set_caps (vd->srcpad, caps);
552   gst_caps_unref (caps);
553
554   return GST_FLOW_OK;
555
556   /* ERROR */
557 channel_count_error:
558   {
559     gst_caps_unref (caps);
560     GST_ELEMENT_ERROR (vd, STREAM, NOT_IMPLEMENTED, (NULL),
561         ("Unsupported channel count %d", vd->vi.channels));
562     return GST_FLOW_ERROR;
563   }
564 }
565
566 static GstFlowReturn
567 vorbis_handle_comment_packet (GstVorbisDec * vd, ogg_packet * packet)
568 {
569   guint bitrate = 0;
570   gchar *encoder = NULL;
571   GstMessage *message;
572   GstTagList *list;
573   GstBuffer *buf;
574
575   GST_DEBUG_OBJECT (vd, "parsing comment packet");
576
577   buf = gst_buffer_new_and_alloc (packet->bytes);
578   GST_BUFFER_DATA (buf) = packet->packet;
579
580   list =
581       gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\003vorbis", 7,
582       &encoder);
583
584   gst_buffer_unref (buf);
585
586   if (!list) {
587     GST_ERROR_OBJECT (vd, "couldn't decode comments");
588     list = gst_tag_list_new ();
589   }
590   if (encoder) {
591     gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
592         GST_TAG_ENCODER, encoder, NULL);
593     g_free (encoder);
594   }
595   gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
596       GST_TAG_ENCODER_VERSION, vd->vi.version,
597       GST_TAG_AUDIO_CODEC, "Vorbis", NULL);
598   if (vd->vi.bitrate_nominal > 0) {
599     gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
600         GST_TAG_NOMINAL_BITRATE, (guint) vd->vi.bitrate_nominal, NULL);
601     bitrate = vd->vi.bitrate_nominal;
602   }
603   if (vd->vi.bitrate_upper > 0) {
604     gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
605         GST_TAG_MAXIMUM_BITRATE, (guint) vd->vi.bitrate_upper, NULL);
606     if (!bitrate)
607       bitrate = vd->vi.bitrate_upper;
608   }
609   if (vd->vi.bitrate_lower > 0) {
610     gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
611         GST_TAG_MINIMUM_BITRATE, (guint) vd->vi.bitrate_lower, NULL);
612     if (!bitrate)
613       bitrate = vd->vi.bitrate_lower;
614   }
615   if (bitrate) {
616     gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
617         GST_TAG_BITRATE, (guint) bitrate, NULL);
618   }
619
620   message = gst_message_new_tag ((GstObject *) vd, list);
621   gst_element_post_message (GST_ELEMENT (vd), message);
622
623   return GST_FLOW_OK;
624 }
625
626 static GstFlowReturn
627 vorbis_handle_type_packet (GstVorbisDec * vd)
628 {
629   g_assert (vd->initialized == FALSE);
630
631   vorbis_synthesis_init (&vd->vd, &vd->vi);
632   vorbis_block_init (&vd->vd, &vd->vb);
633   vd->initialized = TRUE;
634
635   return GST_FLOW_OK;
636 }
637
638 static GstFlowReturn
639 vorbis_handle_header_packet (GstVorbisDec * vd, ogg_packet * packet)
640 {
641   GstFlowReturn res;
642
643   GST_DEBUG_OBJECT (vd, "parsing header packet");
644
645   /* Packetno = 0 if the first byte is exactly 0x01 */
646   packet->b_o_s = (packet->packet[0] == 0x1) ? 1 : 0;
647
648   if (vorbis_synthesis_headerin (&vd->vi, &vd->vc, packet))
649     goto header_read_error;
650
651   /* FIXME: we should probably double-check if packet[0] is 1/3/5 for each
652    * of these */
653   switch (packet->packetno) {
654     case 0:
655       res = vorbis_handle_identification_packet (vd);
656       break;
657     case 1:
658       res = vorbis_handle_comment_packet (vd, packet);
659       break;
660     case 2:
661       res = vorbis_handle_type_packet (vd);
662       break;
663     default:
664       /* ignore */
665       res = GST_FLOW_OK;
666       break;
667   }
668   return res;
669
670   /* ERRORS */
671 header_read_error:
672   {
673     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
674         (NULL), ("couldn't read header packet"));
675     return GST_FLOW_ERROR;
676   }
677 }
678
679 static void
680 copy_samples (float *out, float **in, guint samples, gint channels)
681 {
682   gint i, j;
683
684 #ifdef GST_VORBIS_DEC_SEQUENTIAL
685   for (i = 0; i < channels; i++) {
686     memcpy (out, in[i], samples * sizeof (float));
687     out += samples;
688   }
689 #else
690   for (j = 0; j < samples; j++) {
691     for (i = 0; i < channels; i++) {
692       *out++ = in[i][j];
693     }
694   }
695 #endif
696 }
697
698 static GstFlowReturn
699 vorbis_dec_push (GstVorbisDec * dec, GstBuffer * buf)
700 {
701   GstFlowReturn result;
702   gint64 outoffset = GST_BUFFER_OFFSET (buf);
703
704   if (outoffset == -1) {
705     dec->queued = g_list_append (dec->queued, buf);
706     GST_DEBUG_OBJECT (dec, "queued buffer");
707     result = GST_FLOW_OK;
708   } else {
709     if (dec->queued) {
710       gint64 size;
711       GList *walk;
712
713       GST_DEBUG_OBJECT (dec, "first buffer with offset %lld", outoffset);
714
715       size = g_list_length (dec->queued);
716       for (walk = g_list_last (dec->queued); walk;
717           walk = g_list_previous (walk)) {
718         GstBuffer *buffer = GST_BUFFER (walk->data);
719
720         outoffset -=
721             GST_BUFFER_SIZE (buffer) / (sizeof (float) * dec->vi.channels);
722
723         GST_BUFFER_OFFSET (buffer) = outoffset;
724         GST_BUFFER_TIMESTAMP (buffer) =
725             gst_util_uint64_scale (outoffset, GST_SECOND, dec->vi.rate);
726         GST_DEBUG_OBJECT (dec, "patch buffer %" G_GUINT64_FORMAT
727             " offset %" G_GUINT64_FORMAT, size, outoffset);
728         size--;
729       }
730       for (walk = dec->queued; walk; walk = g_list_next (walk)) {
731         GstBuffer *buffer = GST_BUFFER (walk->data);
732
733         /* ignore the result */
734         gst_pad_push (dec->srcpad, buffer);
735       }
736       g_list_free (dec->queued);
737       dec->queued = NULL;
738     }
739     result = gst_pad_push (dec->srcpad, buf);
740   }
741
742   return result;
743 }
744
745 static GstFlowReturn
746 vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet)
747 {
748   float **pcm;
749   guint sample_count;
750   GstBuffer *out;
751   GstFlowReturn result;
752   gint size;
753
754   if (!vd->initialized)
755     goto not_initialized;
756
757   /* normal data packet */
758   if (vorbis_synthesis (&vd->vb, packet))
759     goto could_not_read;
760
761   if (vorbis_synthesis_blockin (&vd->vd, &vd->vb) < 0)
762     goto not_accepted;
763
764   /* assume all goes well here */
765   result = GST_FLOW_OK;
766
767   /* count samples ready for reading */
768   if ((sample_count = vorbis_synthesis_pcmout (&vd->vd, NULL)) == 0)
769     goto done;
770
771   size = sample_count * vd->vi.channels * sizeof (float);
772
773   /* alloc buffer for it */
774   result =
775       gst_pad_alloc_buffer_and_set_caps (vd->srcpad, GST_BUFFER_OFFSET_NONE,
776       size, GST_PAD_CAPS (vd->srcpad), &out);
777   if (result != GST_FLOW_OK)
778     goto done;
779
780   /* get samples ready for reading now, should be sample_count */
781   if ((vorbis_synthesis_pcmout (&vd->vd, &pcm)) != sample_count)
782     goto wrong_samples;
783
784   /* copy samples in buffer */
785   copy_samples ((float *) GST_BUFFER_DATA (out), pcm, sample_count,
786       vd->vi.channels);
787
788   GST_BUFFER_SIZE (out) = size;
789   GST_BUFFER_OFFSET (out) = vd->granulepos;
790   if (vd->granulepos != -1) {
791     GST_BUFFER_OFFSET_END (out) = vd->granulepos + sample_count;
792     GST_BUFFER_TIMESTAMP (out) =
793         gst_util_uint64_scale (vd->granulepos, GST_SECOND, vd->vi.rate);
794   } else {
795     GST_BUFFER_TIMESTAMP (out) = -1;
796   }
797   GST_BUFFER_DURATION (out) = sample_count * GST_SECOND / vd->vi.rate;
798
799   if (vd->cur_timestamp != GST_CLOCK_TIME_NONE) {
800     GST_BUFFER_TIMESTAMP (out) = vd->cur_timestamp;
801     GST_DEBUG ("cur_timestamp: %" GST_TIME_FORMAT " + %" GST_TIME_FORMAT " = % "
802         GST_TIME_FORMAT, GST_TIME_ARGS (vd->cur_timestamp),
803         GST_TIME_ARGS (GST_BUFFER_DURATION (out)),
804         GST_TIME_ARGS (vd->cur_timestamp + GST_BUFFER_DURATION (out)));
805     vd->cur_timestamp += GST_BUFFER_DURATION (out);
806     GST_BUFFER_OFFSET (out) = GST_CLOCK_TIME_TO_FRAMES (vd->cur_timestamp,
807         vd->vi.rate);
808     GST_BUFFER_OFFSET_END (out) = GST_BUFFER_OFFSET (out) + sample_count;
809   }
810
811   if (vd->granulepos != -1)
812     vd->granulepos += sample_count;
813
814   result = vorbis_dec_push (vd, out);
815
816 done:
817   vorbis_synthesis_read (&vd->vd, sample_count);
818
819   /* granulepos is the last sample in the packet */
820   if (packet->granulepos != -1)
821     vd->granulepos = packet->granulepos;
822
823   return result;
824
825   /* ERRORS */
826 not_initialized:
827   {
828     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
829         (NULL), ("no header sent yet (packet no is %d)", packet->packetno));
830     return GST_FLOW_ERROR;
831   }
832 could_not_read:
833   {
834     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
835         (NULL), ("couldn't read data packet"));
836     return GST_FLOW_ERROR;
837   }
838 not_accepted:
839   {
840     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
841         (NULL), ("vorbis decoder did not accept data packet"));
842     return GST_FLOW_ERROR;
843   }
844 wrong_samples:
845   {
846     gst_buffer_unref (out);
847     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
848         (NULL), ("vorbis decoder reported wrong number of samples"));
849     return GST_FLOW_ERROR;
850   }
851 }
852
853 static GstFlowReturn
854 vorbis_dec_chain (GstPad * pad, GstBuffer * buffer)
855 {
856   GstVorbisDec *vd;
857   ogg_packet packet;
858   GstFlowReturn result = GST_FLOW_OK;
859
860   vd = GST_VORBIS_DEC (GST_PAD_PARENT (pad));
861
862   if (GST_BUFFER_SIZE (buffer) == 0) {
863     gst_buffer_unref (buffer);
864     GST_ELEMENT_ERROR (vd, STREAM, DECODE, (NULL), ("empty buffer received"));
865     return GST_FLOW_ERROR;
866   }
867
868   /* only ogg has granulepos, demuxers of other container formats 
869    * might provide us with timestamps instead (e.g. matroskademux) */
870   if (GST_BUFFER_OFFSET_END (buffer) == GST_BUFFER_OFFSET_NONE &&
871       GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
872     /* we might get multiple consecutive buffers with the same timestamp */
873     if (GST_BUFFER_TIMESTAMP (buffer) != vd->prev_timestamp) {
874       vd->cur_timestamp = GST_BUFFER_TIMESTAMP (buffer);
875       vd->prev_timestamp = GST_BUFFER_TIMESTAMP (buffer);
876     }
877   } else {
878     vd->cur_timestamp = GST_CLOCK_TIME_NONE;
879     vd->prev_timestamp = GST_CLOCK_TIME_NONE;
880   }
881
882   /* make ogg_packet out of the buffer */
883   packet.packet = GST_BUFFER_DATA (buffer);
884   packet.bytes = GST_BUFFER_SIZE (buffer);
885   packet.granulepos = GST_BUFFER_OFFSET_END (buffer);
886   packet.packetno = vd->packetno++;
887   /*
888    * FIXME. Is there anyway to know that this is the last packet and
889    * set e_o_s??
890    * Yes there is, keep one packet at all times and only push out when
891    * you receive a new one.  Implement this.
892    */
893   packet.e_o_s = 0;
894
895   GST_DEBUG_OBJECT (vd, "vorbis granule: %" G_GINT64_FORMAT,
896       (gint64) packet.granulepos);
897
898   /* switch depending on packet type */
899   if (packet.packet[0] & 1) {
900     if (vd->initialized) {
901       GST_WARNING_OBJECT (vd, "Ignoring header");
902       goto done;
903     }
904     result = vorbis_handle_header_packet (vd, &packet);
905   } else {
906     result = vorbis_handle_data_packet (vd, &packet);
907   }
908
909   GST_DEBUG_OBJECT (vd, "offset end: %" G_GINT64_FORMAT,
910       (gint64) GST_BUFFER_OFFSET_END (buffer));
911
912 done:
913   gst_buffer_unref (buffer);
914
915   return result;
916 }
917
918 static GstStateChangeReturn
919 vorbis_dec_change_state (GstElement * element, GstStateChange transition)
920 {
921   GstVorbisDec *vd = GST_VORBIS_DEC (element);
922   GstStateChangeReturn res;
923
924
925   switch (transition) {
926     case GST_STATE_CHANGE_NULL_TO_READY:
927       break;
928     case GST_STATE_CHANGE_READY_TO_PAUSED:
929       vorbis_info_init (&vd->vi);
930       vorbis_comment_init (&vd->vc);
931       vd->initialized = FALSE;
932       vd->cur_timestamp = GST_CLOCK_TIME_NONE;
933       vd->prev_timestamp = GST_CLOCK_TIME_NONE;
934       vd->granulepos = -1;
935       vd->packetno = 0;
936       break;
937     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
938       break;
939     default:
940       break;
941   }
942
943   res = parent_class->change_state (element, transition);
944
945   switch (transition) {
946     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
947       break;
948     case GST_STATE_CHANGE_PAUSED_TO_READY:
949       GST_DEBUG_OBJECT (vd, "PAUSED -> READY, clearing vorbis structures");
950       vorbis_block_clear (&vd->vb);
951       vorbis_dsp_clear (&vd->vd);
952       vorbis_comment_clear (&vd->vc);
953       vorbis_info_clear (&vd->vi);
954       break;
955     case GST_STATE_CHANGE_READY_TO_NULL:
956       break;
957     default:
958       break;
959   }
960
961   return res;
962 }