Initialize Tizen 2.3
[framework/multimedia/gst-plugins-base0.10.git] / ext / vorbis / gstvorbisdec.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 /**
21  * SECTION:element-vorbisdec
22  * @see_also: vorbisenc, oggdemux
23  *
24  * This element decodes a Vorbis stream to raw float audio.
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
27  * Foundation</ulink>.
28  *
29  * <refsect2>
30  * <title>Example pipelines</title>
31  * |[
32  * gst-launch -v filesrc location=sine.ogg ! oggdemux ! vorbisdec ! audioconvert ! alsasink
33  * ]| Decode an Ogg/Vorbis. To create an Ogg/Vorbis file refer to the documentation of vorbisenc.
34  * </refsect2>
35  *
36  * Last reviewed on 2006-03-01 (0.10.4)
37  */
38
39 #ifdef HAVE_CONFIG_H
40 #  include "config.h"
41 #endif
42
43 #include "gstvorbisdec.h"
44 #include <string.h>
45 #include <gst/audio/audio.h>
46 #include <gst/tag/tag.h>
47 #include <gst/audio/multichannel.h>
48
49 #include "gstvorbiscommon.h"
50
51 GST_DEBUG_CATEGORY_EXTERN (vorbisdec_debug);
52 #define GST_CAT_DEFAULT vorbisdec_debug
53
54 static GstStaticPadTemplate vorbis_dec_src_factory =
55 GST_STATIC_PAD_TEMPLATE ("src",
56     GST_PAD_SRC,
57     GST_PAD_ALWAYS,
58     GST_VORBIS_DEC_SRC_CAPS);
59
60 static GstStaticPadTemplate vorbis_dec_sink_factory =
61 GST_STATIC_PAD_TEMPLATE ("sink",
62     GST_PAD_SINK,
63     GST_PAD_ALWAYS,
64     GST_STATIC_CAPS ("audio/x-vorbis")
65     );
66
67 GST_BOILERPLATE (GstVorbisDec, gst_vorbis_dec, GstAudioDecoder,
68     GST_TYPE_AUDIO_DECODER);
69
70 static void vorbis_dec_finalize (GObject * object);
71
72 static gboolean vorbis_dec_start (GstAudioDecoder * dec);
73 static gboolean vorbis_dec_stop (GstAudioDecoder * dec);
74 static GstFlowReturn vorbis_dec_handle_frame (GstAudioDecoder * dec,
75     GstBuffer * buffer);
76 static void vorbis_dec_flush (GstAudioDecoder * dec, gboolean hard);
77
78 static void
79 gst_vorbis_dec_base_init (gpointer g_class)
80 {
81   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
82
83   gst_element_class_add_static_pad_template (element_class,
84       &vorbis_dec_src_factory);
85   gst_element_class_add_static_pad_template (element_class,
86       &vorbis_dec_sink_factory);
87
88   gst_element_class_set_details_simple (element_class,
89       "Vorbis audio decoder", "Codec/Decoder/Audio",
90       GST_VORBIS_DEC_DESCRIPTION,
91       "Benjamin Otte <otte@gnome.org>, Chris Lord <chris@openedhand.com>");
92 }
93
94 static void
95 gst_vorbis_dec_class_init (GstVorbisDecClass * klass)
96 {
97   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
98   GstAudioDecoderClass *base_class = GST_AUDIO_DECODER_CLASS (klass);
99
100   gobject_class->finalize = vorbis_dec_finalize;
101
102   base_class->start = GST_DEBUG_FUNCPTR (vorbis_dec_start);
103   base_class->stop = GST_DEBUG_FUNCPTR (vorbis_dec_stop);
104   base_class->handle_frame = GST_DEBUG_FUNCPTR (vorbis_dec_handle_frame);
105   base_class->flush = GST_DEBUG_FUNCPTR (vorbis_dec_flush);
106 }
107
108 static void
109 gst_vorbis_dec_init (GstVorbisDec * dec, GstVorbisDecClass * g_class)
110 {
111 }
112
113 static void
114 vorbis_dec_finalize (GObject * object)
115 {
116   /* Release any possibly allocated libvorbis data.
117    * _clear functions can safely be called multiple times
118    */
119   GstVorbisDec *vd = GST_VORBIS_DEC (object);
120
121 #ifndef USE_TREMOLO
122   vorbis_block_clear (&vd->vb);
123 #endif
124   vorbis_dsp_clear (&vd->vd);
125   vorbis_comment_clear (&vd->vc);
126   vorbis_info_clear (&vd->vi);
127
128   G_OBJECT_CLASS (parent_class)->finalize (object);
129 }
130
131 static void
132 gst_vorbis_dec_reset (GstVorbisDec * dec)
133 {
134   if (dec->taglist)
135     gst_tag_list_free (dec->taglist);
136   dec->taglist = NULL;
137 }
138
139 static gboolean
140 vorbis_dec_start (GstAudioDecoder * dec)
141 {
142   GstVorbisDec *vd = GST_VORBIS_DEC (dec);
143
144   GST_DEBUG_OBJECT (dec, "start");
145   vorbis_info_init (&vd->vi);
146   vorbis_comment_init (&vd->vc);
147   vd->initialized = FALSE;
148   gst_vorbis_dec_reset (vd);
149
150   return TRUE;
151 }
152
153 static gboolean
154 vorbis_dec_stop (GstAudioDecoder * dec)
155 {
156   GstVorbisDec *vd = GST_VORBIS_DEC (dec);
157
158   GST_DEBUG_OBJECT (dec, "stop");
159   vd->initialized = FALSE;
160 #ifndef USE_TREMOLO
161   vorbis_block_clear (&vd->vb);
162 #endif
163   vorbis_dsp_clear (&vd->vd);
164   vorbis_comment_clear (&vd->vc);
165   vorbis_info_clear (&vd->vi);
166   gst_vorbis_dec_reset (vd);
167
168   return TRUE;
169 }
170
171 #if 0
172 static gboolean
173 vorbis_dec_src_event (GstPad * pad, GstEvent * event)
174 {
175   gboolean res = TRUE;
176   GstVorbisDec *dec;
177
178   dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
179
180   switch (GST_EVENT_TYPE (event)) {
181     case GST_EVENT_SEEK:
182     {
183       GstFormat format, tformat;
184       gdouble rate;
185       GstEvent *real_seek;
186       GstSeekFlags flags;
187       GstSeekType cur_type, stop_type;
188       gint64 cur, stop;
189       gint64 tcur, tstop;
190       guint32 seqnum;
191
192       gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
193           &stop_type, &stop);
194       seqnum = gst_event_get_seqnum (event);
195       gst_event_unref (event);
196
197       /* First bring the requested format to time */
198       tformat = GST_FORMAT_TIME;
199       if (!(res = vorbis_dec_convert (pad, format, cur, &tformat, &tcur)))
200         goto convert_error;
201       if (!(res = vorbis_dec_convert (pad, format, stop, &tformat, &tstop)))
202         goto convert_error;
203
204       /* then seek with time on the peer */
205       real_seek = gst_event_new_seek (rate, GST_FORMAT_TIME,
206           flags, cur_type, tcur, stop_type, tstop);
207       gst_event_set_seqnum (real_seek, seqnum);
208
209       res = gst_pad_push_event (dec->sinkpad, real_seek);
210       break;
211     }
212     default:
213       res = gst_pad_push_event (dec->sinkpad, event);
214       break;
215   }
216 done:
217   gst_object_unref (dec);
218
219   return res;
220
221   /* ERRORS */
222 convert_error:
223   {
224     GST_DEBUG_OBJECT (dec, "cannot convert start/stop for seek");
225     goto done;
226   }
227 }
228 #endif
229
230 static GstFlowReturn
231 vorbis_handle_identification_packet (GstVorbisDec * vd)
232 {
233   GstCaps *caps;
234   const GstAudioChannelPosition *pos = NULL;
235   gint width = GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH;
236
237   switch (vd->vi.channels) {
238     case 1:
239     case 2:
240       /* nothing */
241       break;
242     case 3:
243     case 4:
244     case 5:
245     case 6:
246     case 7:
247     case 8:
248       pos = gst_vorbis_channel_positions[vd->vi.channels - 1];
249       break;
250     default:{
251       gint i;
252       GstAudioChannelPosition *posn =
253           g_new (GstAudioChannelPosition, vd->vi.channels);
254
255       GST_ELEMENT_WARNING (GST_ELEMENT (vd), STREAM, DECODE,
256           (NULL), ("Using NONE channel layout for more than 8 channels"));
257
258       for (i = 0; i < vd->vi.channels; i++)
259         posn[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
260
261       pos = posn;
262     }
263   }
264
265   /* negotiate width with downstream */
266   caps = gst_pad_get_allowed_caps (GST_AUDIO_DECODER_SRC_PAD (vd));
267   if (caps) {
268     if (!gst_caps_is_empty (caps)) {
269       GstStructure *s;
270
271       s = gst_caps_get_structure (caps, 0);
272       /* template ensures 16 or 32 */
273       gst_structure_get_int (s, "width", &width);
274
275       GST_INFO_OBJECT (vd, "using %s with %d channels and %d bit audio depth",
276           gst_structure_get_name (s), vd->vi.channels, width);
277     }
278     gst_caps_unref (caps);
279   }
280   vd->width = width >> 3;
281
282   /* select a copy_samples function, this way we can have specialized versions
283    * for mono/stereo and avoid the depth switch in tremor case */
284   vd->copy_samples = get_copy_sample_func (vd->vi.channels, vd->width);
285
286   caps =
287       gst_caps_copy (gst_pad_get_pad_template_caps
288       (GST_AUDIO_DECODER_SRC_PAD (vd)));
289   gst_caps_set_simple (caps, "rate", G_TYPE_INT, vd->vi.rate, "channels",
290       G_TYPE_INT, vd->vi.channels, "width", G_TYPE_INT, width, NULL);
291
292   if (pos) {
293     gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
294   }
295
296   if (vd->vi.channels > 8) {
297     g_free ((GstAudioChannelPosition *) pos);
298   }
299
300   gst_pad_set_caps (GST_AUDIO_DECODER_SRC_PAD (vd), caps);
301   gst_caps_unref (caps);
302
303   return GST_FLOW_OK;
304 }
305
306 static GstFlowReturn
307 vorbis_handle_comment_packet (GstVorbisDec * vd, ogg_packet * packet)
308 {
309   guint bitrate = 0;
310   gchar *encoder = NULL;
311   GstTagList *list, *old_list;
312   GstBuffer *buf;
313
314   GST_DEBUG_OBJECT (vd, "parsing comment packet");
315
316   buf = gst_buffer_new ();
317   GST_BUFFER_DATA (buf) = gst_ogg_packet_data (packet);
318   GST_BUFFER_SIZE (buf) = gst_ogg_packet_size (packet);
319
320   list =
321       gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\003vorbis", 7,
322       &encoder);
323
324   old_list = vd->taglist;
325   vd->taglist = gst_tag_list_merge (vd->taglist, list, GST_TAG_MERGE_REPLACE);
326
327   if (old_list)
328     gst_tag_list_free (old_list);
329   gst_tag_list_free (list);
330   gst_buffer_unref (buf);
331
332   if (!vd->taglist) {
333     GST_ERROR_OBJECT (vd, "couldn't decode comments");
334     vd->taglist = gst_tag_list_new ();
335   }
336   if (encoder) {
337     if (encoder[0])
338       gst_tag_list_add (vd->taglist, GST_TAG_MERGE_REPLACE,
339           GST_TAG_ENCODER, encoder, NULL);
340     g_free (encoder);
341   }
342   gst_tag_list_add (vd->taglist, GST_TAG_MERGE_REPLACE,
343       GST_TAG_ENCODER_VERSION, vd->vi.version,
344       GST_TAG_AUDIO_CODEC, "Vorbis", NULL);
345   if (vd->vi.bitrate_nominal > 0 && vd->vi.bitrate_nominal <= 0x7FFFFFFF) {
346     gst_tag_list_add (vd->taglist, GST_TAG_MERGE_REPLACE,
347         GST_TAG_NOMINAL_BITRATE, (guint) vd->vi.bitrate_nominal, NULL);
348     bitrate = vd->vi.bitrate_nominal;
349   }
350   if (vd->vi.bitrate_upper > 0 && vd->vi.bitrate_upper <= 0x7FFFFFFF) {
351     gst_tag_list_add (vd->taglist, GST_TAG_MERGE_REPLACE,
352         GST_TAG_MAXIMUM_BITRATE, (guint) vd->vi.bitrate_upper, NULL);
353     if (!bitrate)
354       bitrate = vd->vi.bitrate_upper;
355   }
356   if (vd->vi.bitrate_lower > 0 && vd->vi.bitrate_lower <= 0x7FFFFFFF) {
357     gst_tag_list_add (vd->taglist, GST_TAG_MERGE_REPLACE,
358         GST_TAG_MINIMUM_BITRATE, (guint) vd->vi.bitrate_lower, NULL);
359     if (!bitrate)
360       bitrate = vd->vi.bitrate_lower;
361   }
362   if (bitrate) {
363     gst_tag_list_add (vd->taglist, GST_TAG_MERGE_REPLACE,
364         GST_TAG_BITRATE, (guint) bitrate, NULL);
365   }
366
367   if (vd->initialized) {
368     gst_element_found_tags_for_pad (GST_ELEMENT_CAST (vd),
369         GST_AUDIO_DECODER_SRC_PAD (vd), vd->taglist);
370     vd->taglist = NULL;
371   } else {
372     /* Only post them as messages for the time being. *
373      * They will be pushed on the pad once the decoder is initialized */
374     gst_element_post_message (GST_ELEMENT_CAST (vd),
375         gst_message_new_tag (GST_OBJECT (vd), gst_tag_list_copy (vd->taglist)));
376   }
377
378   return GST_FLOW_OK;
379 }
380
381 static GstFlowReturn
382 vorbis_handle_type_packet (GstVorbisDec * vd)
383 {
384   gint res;
385
386   g_assert (vd->initialized == FALSE);
387
388 #ifdef USE_TREMOLO
389   if (G_UNLIKELY ((res = vorbis_dsp_init (&vd->vd, &vd->vi))))
390     goto synthesis_init_error;
391 #else
392   if (G_UNLIKELY ((res = vorbis_synthesis_init (&vd->vd, &vd->vi))))
393     goto synthesis_init_error;
394
395   if (G_UNLIKELY ((res = vorbis_block_init (&vd->vd, &vd->vb))))
396     goto block_init_error;
397 #endif
398
399   vd->initialized = TRUE;
400
401   if (vd->taglist) {
402     /* The tags have already been sent on the bus as messages. */
403     gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (vd),
404         gst_event_new_tag (vd->taglist));
405     vd->taglist = NULL;
406   }
407   return GST_FLOW_OK;
408
409   /* ERRORS */
410 synthesis_init_error:
411   {
412     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
413         (NULL), ("couldn't initialize synthesis (%d)", res));
414     return GST_FLOW_ERROR;
415   }
416 block_init_error:
417   {
418     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
419         (NULL), ("couldn't initialize block (%d)", res));
420     return GST_FLOW_ERROR;
421   }
422 }
423
424 static GstFlowReturn
425 vorbis_handle_header_packet (GstVorbisDec * vd, ogg_packet * packet)
426 {
427   GstFlowReturn res;
428   gint ret;
429
430   GST_DEBUG_OBJECT (vd, "parsing header packet");
431
432   /* Packetno = 0 if the first byte is exactly 0x01 */
433   packet->b_o_s = ((gst_ogg_packet_data (packet))[0] == 0x1) ? 1 : 0;
434
435 #ifdef USE_TREMOLO
436   if ((ret = vorbis_dsp_headerin (&vd->vi, &vd->vc, packet)))
437 #else
438   if ((ret = vorbis_synthesis_headerin (&vd->vi, &vd->vc, packet)))
439 #endif
440     goto header_read_error;
441
442   switch ((gst_ogg_packet_data (packet))[0]) {
443     case 0x01:
444       res = vorbis_handle_identification_packet (vd);
445       break;
446     case 0x03:
447       res = vorbis_handle_comment_packet (vd, packet);
448       break;
449     case 0x05:
450       res = vorbis_handle_type_packet (vd);
451       break;
452     default:
453       /* ignore */
454       g_warning ("unknown vorbis header packet found");
455       res = GST_FLOW_OK;
456       break;
457   }
458
459   return res;
460
461   /* ERRORS */
462 header_read_error:
463   {
464     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
465         (NULL), ("couldn't read header packet (%d)", ret));
466     return GST_FLOW_ERROR;
467   }
468 }
469
470 static GstFlowReturn
471 vorbis_dec_handle_header_buffer (GstVorbisDec * vd, GstBuffer * buffer)
472 {
473   ogg_packet *packet;
474   ogg_packet_wrapper packet_wrapper;
475
476   gst_ogg_packet_wrapper_from_buffer (&packet_wrapper, buffer);
477   packet = gst_ogg_packet_from_wrapper (&packet_wrapper);
478
479   return vorbis_handle_header_packet (vd, packet);
480 }
481
482 #define MIN_NUM_HEADERS 3
483 static GstFlowReturn
484 vorbis_dec_handle_header_caps (GstVorbisDec * vd)
485 {
486   GstFlowReturn result = GST_FLOW_OK;
487   GstCaps *caps;
488   GstStructure *s = NULL;
489   const GValue *array = NULL;
490
491   caps = GST_PAD_CAPS (GST_AUDIO_DECODER_SINK_PAD (vd));
492   if (caps)
493     s = gst_caps_get_structure (caps, 0);
494   if (s)
495     array = gst_structure_get_value (s, "streamheader");
496
497   if (array && (gst_value_array_get_size (array) >= MIN_NUM_HEADERS)) {
498     const GValue *value = NULL;
499     GstBuffer *buf = NULL;
500     gint i = 0;
501
502     while (result == GST_FLOW_OK && i < gst_value_array_get_size (array)) {
503       value = gst_value_array_get_value (array, i);
504       buf = gst_value_get_buffer (value);
505       if (!buf)
506         goto null_buffer;
507       result = vorbis_dec_handle_header_buffer (vd, buf);
508       i++;
509     }
510   } else
511     goto array_error;
512
513 done:
514   return (result != GST_FLOW_OK ? GST_FLOW_NOT_NEGOTIATED : GST_FLOW_OK);
515
516   /* ERRORS */
517 array_error:
518   {
519     GST_WARNING_OBJECT (vd, "streamheader array not found");
520     result = GST_FLOW_ERROR;
521     goto done;
522   }
523 null_buffer:
524   {
525     GST_WARNING_OBJECT (vd, "streamheader with null buffer received");
526     result = GST_FLOW_ERROR;
527     goto done;
528   }
529 }
530
531
532 static GstFlowReturn
533 vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
534     GstClockTime timestamp, GstClockTime duration)
535 {
536 #ifdef USE_TREMOLO
537   vorbis_sample_t *pcm;
538 #else
539   vorbis_sample_t **pcm;
540 #endif
541   guint sample_count;
542   GstBuffer *out = NULL;
543   GstFlowReturn result;
544   gint size;
545
546   if (G_UNLIKELY (!vd->initialized)) {
547     result = vorbis_dec_handle_header_caps (vd);
548     if (result != GST_FLOW_OK)
549       goto not_initialized;
550   }
551
552   /* normal data packet */
553   /* FIXME, we can skip decoding if the packet is outside of the
554    * segment, this is however not very trivial as we need a previous
555    * packet to decode the current one so we must be careful not to
556    * throw away too much. For now we decode everything and clip right
557    * before pushing data. */
558
559 #ifdef USE_TREMOLO
560   if (G_UNLIKELY (vorbis_dsp_synthesis (&vd->vd, packet, 1)))
561     goto could_not_read;
562 #else
563   if (G_UNLIKELY (vorbis_synthesis (&vd->vb, packet)))
564     goto could_not_read;
565
566   if (G_UNLIKELY (vorbis_synthesis_blockin (&vd->vd, &vd->vb) < 0))
567     goto not_accepted;
568 #endif
569
570   /* assume all goes well here */
571   result = GST_FLOW_OK;
572
573   /* count samples ready for reading */
574 #ifdef USE_TREMOLO
575   if ((sample_count = vorbis_dsp_pcmout (&vd->vd, NULL, 0)) == 0)
576 #else
577   if ((sample_count = vorbis_synthesis_pcmout (&vd->vd, NULL)) == 0)
578     goto done;
579 #endif
580
581   size = sample_count * vd->vi.channels * vd->width;
582   GST_LOG_OBJECT (vd, "%d samples ready for reading, size %d", sample_count,
583       size);
584
585   /* alloc buffer for it */
586   result =
587       gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_DECODER_SRC_PAD (vd),
588       GST_BUFFER_OFFSET_NONE, size,
589       GST_PAD_CAPS (GST_AUDIO_DECODER_SRC_PAD (vd)), &out);
590   if (G_UNLIKELY (result != GST_FLOW_OK))
591     goto done;
592
593   /* get samples ready for reading now, should be sample_count */
594 #ifdef USE_TREMOLO
595   pcm = GST_BUFFER_DATA (out);
596   if (G_UNLIKELY (vorbis_dsp_pcmout (&vd->vd, pcm, sample_count) !=
597           sample_count))
598 #else
599   if (G_UNLIKELY (vorbis_synthesis_pcmout (&vd->vd, &pcm) != sample_count))
600 #endif
601     goto wrong_samples;
602
603 #ifndef USE_TREMOLO
604   /* copy samples in buffer */
605   vd->copy_samples ((vorbis_sample_t *) GST_BUFFER_DATA (out), pcm,
606       sample_count, vd->vi.channels, vd->width);
607 #endif
608
609   GST_LOG_OBJECT (vd, "setting output size to %d", size);
610   GST_BUFFER_SIZE (out) = size;
611
612 done:
613   /* whether or not data produced, consume one frame and advance time */
614   result = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (vd), out, 1);
615
616 #ifdef USE_TREMOLO
617   vorbis_dsp_read (&vd->vd, sample_count);
618 #else
619   vorbis_synthesis_read (&vd->vd, sample_count);
620 #endif
621
622   return result;
623
624   /* ERRORS */
625 not_initialized:
626   {
627     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
628         (NULL), ("no header sent yet"));
629     return GST_FLOW_NOT_NEGOTIATED;
630   }
631 could_not_read:
632   {
633     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
634         (NULL), ("couldn't read data packet"));
635     return GST_FLOW_ERROR;
636   }
637 not_accepted:
638   {
639     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
640         (NULL), ("vorbis decoder did not accept data packet"));
641     return GST_FLOW_ERROR;
642   }
643 wrong_samples:
644   {
645     gst_buffer_unref (out);
646     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
647         (NULL), ("vorbis decoder reported wrong number of samples"));
648     return GST_FLOW_ERROR;
649   }
650 }
651
652 static GstFlowReturn
653 vorbis_dec_handle_frame (GstAudioDecoder * dec, GstBuffer * buffer)
654 {
655   ogg_packet *packet;
656   ogg_packet_wrapper packet_wrapper;
657   GstFlowReturn result = GST_FLOW_OK;
658   GstVorbisDec *vd = GST_VORBIS_DEC (dec);
659
660   /* no draining etc */
661   if (G_UNLIKELY (!buffer))
662     return GST_FLOW_OK;
663
664   /* make ogg_packet out of the buffer */
665   gst_ogg_packet_wrapper_from_buffer (&packet_wrapper, buffer);
666   packet = gst_ogg_packet_from_wrapper (&packet_wrapper);
667   /* set some more stuff */
668   packet->granulepos = -1;
669   packet->packetno = 0;         /* we don't care */
670   /* EOS does not matter, it is used in vorbis to implement clipping the last
671    * block of samples based on the granulepos. We clip based on segments. */
672   packet->e_o_s = 0;
673
674   GST_LOG_OBJECT (vd, "decode buffer of size %ld", packet->bytes);
675
676   /* error out on empty header packets, but just skip empty data packets */
677   if (G_UNLIKELY (packet->bytes == 0)) {
678     if (vd->initialized)
679       goto empty_buffer;
680     else
681       goto empty_header;
682   }
683
684   /* switch depending on packet type */
685   if ((gst_ogg_packet_data (packet))[0] & 1) {
686     if (vd->initialized) {
687       GST_WARNING_OBJECT (vd, "Already initialized, so ignoring header packet");
688       goto done;
689     }
690     result = vorbis_handle_header_packet (vd, packet);
691     /* consumer header packet/frame */
692     gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (vd), NULL, 1);
693   } else {
694     GstClockTime timestamp, duration;
695
696     timestamp = GST_BUFFER_TIMESTAMP (buffer);
697     duration = GST_BUFFER_DURATION (buffer);
698
699     result = vorbis_handle_data_packet (vd, packet, timestamp, duration);
700   }
701
702 done:
703   return result;
704
705 empty_buffer:
706   {
707     /* don't error out here, just ignore the buffer, it's invalid for vorbis
708      * but not fatal. */
709     GST_WARNING_OBJECT (vd, "empty buffer received, ignoring");
710     result = GST_FLOW_OK;
711     goto done;
712   }
713
714 /* ERRORS */
715 empty_header:
716   {
717     GST_ELEMENT_ERROR (vd, STREAM, DECODE, (NULL), ("empty header received"));
718     result = GST_FLOW_ERROR;
719     goto done;
720   }
721 }
722
723 static void
724 vorbis_dec_flush (GstAudioDecoder * dec, gboolean hard)
725 {
726   GstVorbisDec *vd = GST_VORBIS_DEC (dec);
727
728 #ifdef HAVE_VORBIS_SYNTHESIS_RESTART
729   vorbis_synthesis_restart (&vd->vd);
730 #endif
731
732   if (hard)
733     gst_vorbis_dec_reset (vd);
734 }