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