• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 /**
21  * SECTION:element-vorbisdec
22  * @title: vorbisdec
23  * @see_also: vorbisenc, oggdemux
24  *
25  * This element decodes a Vorbis stream to raw float audio.
26  * [Vorbis](http://www.vorbis.com/) is a royalty-free audio codec maintained
27  * by the [Xiph.org Foundation](http://www.xiph.org/). As it outputs raw float
28  * audio you will often need to put an audioconvert element after it.
29  *
30  * ## Example pipelines
31  * |[
32  * gst-launch-1.0 -v filesrc location=sine.ogg ! oggdemux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
33  * ]|
34  *  Decode an Ogg/Vorbis. To create an Ogg/Vorbis file refer to the documentation of vorbisenc.
35  *
36  */
37 
38 #ifdef HAVE_CONFIG_H
39 #  include "config.h"
40 #endif
41 
42 #include "gstvorbisdec.h"
43 #include <string.h>
44 #include <gst/audio/audio.h>
45 #include <gst/tag/tag.h>
46 
47 #include "gstvorbiselements.h"
48 #include "gstvorbiscommon.h"
49 
50 #ifndef TREMOR
51 GST_DEBUG_CATEGORY_STATIC (vorbisdec_debug);
52 #define GST_CAT_DEFAULT vorbisdec_debug
53 #else
54 GST_DEBUG_CATEGORY_STATIC (ivorbisdec_debug);
55 #define GST_CAT_DEFAULT ivorbisdec_debug
56 #endif
57 
58 static GstStaticPadTemplate vorbis_dec_src_factory =
59 GST_STATIC_PAD_TEMPLATE ("src",
60     GST_PAD_SRC,
61     GST_PAD_ALWAYS,
62     GST_VORBIS_DEC_SRC_CAPS);
63 
64 static GstStaticPadTemplate vorbis_dec_sink_factory =
65 GST_STATIC_PAD_TEMPLATE ("sink",
66     GST_PAD_SINK,
67     GST_PAD_ALWAYS,
68     GST_STATIC_CAPS ("audio/x-vorbis")
69     );
70 
71 #define gst_vorbis_dec_parent_class parent_class
72 G_DEFINE_TYPE (GstVorbisDec, gst_vorbis_dec, GST_TYPE_AUDIO_DECODER);
73 #ifndef TREMOR
74 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (vorbisdec, "vorbisdec",
75     GST_RANK_PRIMARY, GST_TYPE_VORBIS_DEC,
76     GST_DEBUG_CATEGORY_INIT (vorbisdec_debug, "vorbisdec", 0,
77         "vorbis decoding element");
78     vorbis_element_init (plugin));
79 #else
80 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (ivorbisdec, "ivorbisdec",
81     GST_RANK_SECONDARY, GST_TYPE_VORBIS_DEC,
82     GST_DEBUG_CATEGORY_INIT (ivorbisdec_debug, "ivorbisdec", 0,
83         "vorbis decoding element (integer decoder)");
84     vorbis_element_init (plugin));
85 #endif
86 
87 static void vorbis_dec_finalize (GObject * object);
88 
89 static gboolean vorbis_dec_start (GstAudioDecoder * dec);
90 static gboolean vorbis_dec_stop (GstAudioDecoder * dec);
91 static GstFlowReturn vorbis_dec_handle_frame (GstAudioDecoder * dec,
92     GstBuffer * buffer);
93 static void vorbis_dec_flush (GstAudioDecoder * dec, gboolean hard);
94 static gboolean vorbis_dec_set_format (GstAudioDecoder * dec, GstCaps * caps);
95 static void vorbis_dec_reset (GstAudioDecoder * dec);
96 
97 static void
gst_vorbis_dec_class_init(GstVorbisDecClass * klass)98 gst_vorbis_dec_class_init (GstVorbisDecClass * klass)
99 {
100   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
101   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
102   GstAudioDecoderClass *base_class = GST_AUDIO_DECODER_CLASS (klass);
103 
104   gobject_class->finalize = vorbis_dec_finalize;
105 
106   gst_element_class_add_static_pad_template (element_class,
107       &vorbis_dec_src_factory);
108   gst_element_class_add_static_pad_template (element_class,
109       &vorbis_dec_sink_factory);
110 
111   gst_element_class_set_static_metadata (element_class,
112       "Vorbis audio decoder", "Codec/Decoder/Audio",
113       GST_VORBIS_DEC_DESCRIPTION,
114       "Benjamin Otte <otte@gnome.org>, Chris Lord <chris@openedhand.com>");
115 
116   base_class->start = GST_DEBUG_FUNCPTR (vorbis_dec_start);
117   base_class->stop = GST_DEBUG_FUNCPTR (vorbis_dec_stop);
118   base_class->set_format = GST_DEBUG_FUNCPTR (vorbis_dec_set_format);
119   base_class->handle_frame = GST_DEBUG_FUNCPTR (vorbis_dec_handle_frame);
120   base_class->flush = GST_DEBUG_FUNCPTR (vorbis_dec_flush);
121 }
122 
123 static void
gst_vorbis_dec_init(GstVorbisDec * dec)124 gst_vorbis_dec_init (GstVorbisDec * dec)
125 {
126   gst_audio_decoder_set_use_default_pad_acceptcaps (GST_AUDIO_DECODER_CAST
127       (dec), TRUE);
128   GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_DECODER_SINK_PAD (dec));
129 }
130 
131 static void
vorbis_dec_finalize(GObject * object)132 vorbis_dec_finalize (GObject * object)
133 {
134   /* Release any possibly allocated libvorbis data.
135    * _clear functions can safely be called multiple times
136    */
137   GstVorbisDec *vd = GST_VORBIS_DEC (object);
138 
139 #ifndef USE_TREMOLO
140   vorbis_block_clear (&vd->vb);
141 #endif
142   vorbis_dsp_clear (&vd->vd);
143   vorbis_comment_clear (&vd->vc);
144   vorbis_info_clear (&vd->vi);
145 
146   G_OBJECT_CLASS (parent_class)->finalize (object);
147 }
148 
149 static gboolean
vorbis_dec_start(GstAudioDecoder * dec)150 vorbis_dec_start (GstAudioDecoder * dec)
151 {
152   GstVorbisDec *vd = GST_VORBIS_DEC (dec);
153 
154   GST_DEBUG_OBJECT (dec, "start");
155   vorbis_info_init (&vd->vi);
156   vorbis_comment_init (&vd->vc);
157   vd->initialized = FALSE;
158 
159   return TRUE;
160 }
161 
162 static gboolean
vorbis_dec_stop(GstAudioDecoder * dec)163 vorbis_dec_stop (GstAudioDecoder * dec)
164 {
165   GstVorbisDec *vd = GST_VORBIS_DEC (dec);
166 
167   GST_DEBUG_OBJECT (dec, "stop");
168   vd->initialized = FALSE;
169 #ifndef USE_TREMOLO
170   vorbis_block_clear (&vd->vb);
171 #endif
172   vorbis_dsp_clear (&vd->vd);
173   vorbis_comment_clear (&vd->vc);
174   vorbis_info_clear (&vd->vi);
175   if (vd->pending_headers) {
176     g_list_free_full (vd->pending_headers, (GDestroyNotify) gst_buffer_unref);
177     vd->pending_headers = NULL;
178   }
179 
180   return TRUE;
181 }
182 
183 static GstFlowReturn
vorbis_handle_identification_packet(GstVorbisDec * vd)184 vorbis_handle_identification_packet (GstVorbisDec * vd)
185 {
186   GstAudioInfo info;
187 
188   switch (vd->vi.channels) {
189     case 1:
190     case 2:
191     case 3:
192     case 4:
193     case 5:
194     case 6:
195     case 7:
196     case 8:
197     {
198       const GstAudioChannelPosition *pos;
199 
200       pos = gst_vorbis_default_channel_positions[vd->vi.channels - 1];
201       gst_audio_info_set_format (&info, GST_VORBIS_AUDIO_FORMAT, vd->vi.rate,
202           vd->vi.channels, pos);
203       break;
204     }
205     default:{
206       GstAudioChannelPosition position[64];
207       gint i, max_pos = MAX (vd->vi.channels, 64);
208 
209       GST_ELEMENT_WARNING (vd, STREAM, DECODE,
210           (NULL), ("Using NONE channel layout for more than 8 channels"));
211       for (i = 0; i < max_pos; i++)
212         position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
213       gst_audio_info_set_format (&info, GST_VORBIS_AUDIO_FORMAT, vd->vi.rate,
214           vd->vi.channels, position);
215       break;
216     }
217   }
218 
219   gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (vd), &info);
220 
221   vd->info = info;
222   /* select a copy_samples function, this way we can have specialized versions
223    * for mono/stereo and avoid the depth switch in tremor case */
224   vd->copy_samples = gst_vorbis_get_copy_sample_func (info.channels);
225 
226   return GST_FLOW_OK;
227 }
228 
229 /* FIXME 0.11: remove tag handling and let container take care of that? */
230 static GstFlowReturn
vorbis_handle_comment_packet(GstVorbisDec * vd,ogg_packet * packet)231 vorbis_handle_comment_packet (GstVorbisDec * vd, ogg_packet * packet)
232 {
233   guint bitrate = 0;
234   gchar *encoder = NULL;
235   GstTagList *list;
236   guint8 *data;
237   gsize size;
238 
239   GST_DEBUG_OBJECT (vd, "parsing comment packet");
240 
241   data = gst_ogg_packet_data (packet);
242   size = gst_ogg_packet_size (packet);
243 
244   list =
245       gst_tag_list_from_vorbiscomment (data, size, (guint8 *) "\003vorbis", 7,
246       &encoder);
247 
248   if (!list) {
249     GST_ERROR_OBJECT (vd, "couldn't decode comments");
250     list = gst_tag_list_new_empty ();
251   }
252 
253   if (encoder) {
254     if (encoder[0])
255       gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
256           GST_TAG_ENCODER, encoder, NULL);
257     g_free (encoder);
258   }
259   gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
260       GST_TAG_ENCODER_VERSION, vd->vi.version,
261       GST_TAG_AUDIO_CODEC, "Vorbis", NULL);
262   if (vd->vi.bitrate_nominal > 0 && vd->vi.bitrate_nominal <= 0x7FFFFFFF) {
263     gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
264         GST_TAG_NOMINAL_BITRATE, (guint) vd->vi.bitrate_nominal, NULL);
265     bitrate = vd->vi.bitrate_nominal;
266   }
267   if (vd->vi.bitrate_upper > 0 && vd->vi.bitrate_upper <= 0x7FFFFFFF) {
268     gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
269         GST_TAG_MAXIMUM_BITRATE, (guint) vd->vi.bitrate_upper, NULL);
270     if (!bitrate)
271       bitrate = vd->vi.bitrate_upper;
272   }
273   if (vd->vi.bitrate_lower > 0 && vd->vi.bitrate_lower <= 0x7FFFFFFF) {
274     gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
275         GST_TAG_MINIMUM_BITRATE, (guint) vd->vi.bitrate_lower, NULL);
276     if (!bitrate)
277       bitrate = vd->vi.bitrate_lower;
278   }
279   if (bitrate) {
280     gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
281         GST_TAG_BITRATE, (guint) bitrate, NULL);
282   }
283 
284   gst_audio_decoder_merge_tags (GST_AUDIO_DECODER_CAST (vd), list,
285       GST_TAG_MERGE_REPLACE);
286   gst_tag_list_unref (list);
287 
288   return GST_FLOW_OK;
289 }
290 
291 static GstFlowReturn
vorbis_handle_type_packet(GstVorbisDec * vd)292 vorbis_handle_type_packet (GstVorbisDec * vd)
293 {
294   gint res;
295 
296   g_assert (!vd->initialized);
297 
298 #ifdef USE_TREMOLO
299   if (G_UNLIKELY ((res = vorbis_dsp_init (&vd->vd, &vd->vi))))
300     goto synthesis_init_error;
301 #else
302   if (G_UNLIKELY ((res = vorbis_synthesis_init (&vd->vd, &vd->vi))))
303     goto synthesis_init_error;
304 
305   if (G_UNLIKELY ((res = vorbis_block_init (&vd->vd, &vd->vb))))
306     goto block_init_error;
307 #endif
308 
309   vd->initialized = TRUE;
310 
311   return GST_FLOW_OK;
312 
313   /* ERRORS */
314 synthesis_init_error:
315   {
316     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
317         (NULL), ("couldn't initialize synthesis (%d)", res));
318     return GST_FLOW_ERROR;
319   }
320 block_init_error:
321   {
322     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
323         (NULL), ("couldn't initialize block (%d)", res));
324     return GST_FLOW_ERROR;
325   }
326 }
327 
328 static GstFlowReturn
vorbis_handle_header_packet(GstVorbisDec * vd,ogg_packet * packet)329 vorbis_handle_header_packet (GstVorbisDec * vd, ogg_packet * packet)
330 {
331   GstFlowReturn res;
332   gint ret;
333 
334   GST_DEBUG_OBJECT (vd, "parsing header packet");
335 
336   /* Packetno = 0 if the first byte is exactly 0x01 */
337   packet->b_o_s = ((gst_ogg_packet_data (packet))[0] == 0x1) ? 1 : 0;
338 
339 #ifdef USE_TREMOLO
340   if ((ret = vorbis_dsp_headerin (&vd->vi, &vd->vc, packet)))
341 #else
342   if ((ret = vorbis_synthesis_headerin (&vd->vi, &vd->vc, packet)))
343 #endif
344     goto header_read_error;
345 
346   switch ((gst_ogg_packet_data (packet))[0]) {
347     case 0x01:
348       res = vorbis_handle_identification_packet (vd);
349       break;
350     case 0x03:
351       res = vorbis_handle_comment_packet (vd, packet);
352       break;
353     case 0x05:
354       res = vorbis_handle_type_packet (vd);
355       break;
356     default:
357       /* ignore */
358       GST_WARNING_OBJECT (vd, "unknown vorbis header packet found");
359       res = GST_FLOW_OK;
360       break;
361   }
362 
363   return res;
364 
365   /* ERRORS */
366 header_read_error:
367   {
368     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
369         (NULL), ("couldn't read header packet (%d)", ret));
370     return GST_FLOW_ERROR;
371   }
372 }
373 
374 /* Does not take ownership of buffer */
375 static GstFlowReturn
vorbis_dec_handle_header_buffer(GstVorbisDec * vd,GstBuffer * buffer)376 vorbis_dec_handle_header_buffer (GstVorbisDec * vd, GstBuffer * buffer)
377 {
378   ogg_packet *packet;
379   ogg_packet_wrapper packet_wrapper;
380   GstFlowReturn ret;
381   GstMapInfo map;
382 
383   gst_ogg_packet_wrapper_map (&packet_wrapper, buffer, &map);
384   packet = gst_ogg_packet_from_wrapper (&packet_wrapper);
385 
386   ret = vorbis_handle_header_packet (vd, packet);
387 
388   gst_ogg_packet_wrapper_unmap (&packet_wrapper, buffer, &map);
389 
390   return ret;
391 }
392 
393 #define MIN_NUM_HEADERS 3
394 static GstFlowReturn
vorbis_dec_handle_header_caps(GstVorbisDec * vd)395 vorbis_dec_handle_header_caps (GstVorbisDec * vd)
396 {
397   GstFlowReturn result = GST_FLOW_OK;
398   GstCaps *caps;
399   GstStructure *s = NULL;
400   const GValue *array = NULL;
401 
402   caps = gst_pad_get_current_caps (GST_AUDIO_DECODER_SINK_PAD (vd));
403   if (caps)
404     s = gst_caps_get_structure (caps, 0);
405   if (s)
406     array = gst_structure_get_value (s, "streamheader");
407 
408   if (caps)
409     gst_caps_unref (caps);
410 
411   if (array && (gst_value_array_get_size (array) >= MIN_NUM_HEADERS)) {
412     const GValue *value = NULL;
413     GstBuffer *buf = NULL;
414     gint i = 0;
415 
416     if (vd->pending_headers) {
417       GST_DEBUG_OBJECT (vd,
418           "got new headers from caps, discarding old pending headers");
419 
420       g_list_free_full (vd->pending_headers, (GDestroyNotify) gst_buffer_unref);
421       vd->pending_headers = NULL;
422     }
423 
424     while (result == GST_FLOW_OK && i < gst_value_array_get_size (array)) {
425       value = gst_value_array_get_value (array, i);
426       buf = gst_value_get_buffer (value);
427       if (!buf)
428         goto null_buffer;
429       result = vorbis_dec_handle_header_buffer (vd, buf);
430       i++;
431     }
432   } else
433     goto array_error;
434 
435 done:
436   return (result != GST_FLOW_OK ? GST_FLOW_NOT_NEGOTIATED : GST_FLOW_OK);
437 
438   /* ERRORS */
439 array_error:
440   {
441     GST_WARNING_OBJECT (vd, "streamheader array not found");
442     result = GST_FLOW_ERROR;
443     goto done;
444   }
445 null_buffer:
446   {
447     GST_WARNING_OBJECT (vd, "streamheader with null buffer received");
448     result = GST_FLOW_ERROR;
449     goto done;
450   }
451 }
452 
453 
454 static GstFlowReturn
vorbis_handle_data_packet(GstVorbisDec * vd,ogg_packet * packet,GstClockTime timestamp,GstClockTime duration)455 vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
456     GstClockTime timestamp, GstClockTime duration)
457 {
458 #ifdef USE_TREMOLO
459   vorbis_sample_t *pcm;
460 #else
461   vorbis_sample_t **pcm;
462 #endif
463   guint sample_count;
464   GstBuffer *out = NULL;
465   GstFlowReturn result;
466   GstMapInfo map;
467   gsize size;
468 
469   if (G_UNLIKELY (!vd->initialized)) {
470     result = vorbis_dec_handle_header_caps (vd);
471     if (result != GST_FLOW_OK)
472       goto not_initialized;
473   }
474 
475   /* normal data packet */
476   /* FIXME, we can skip decoding if the packet is outside of the
477    * segment, this is however not very trivial as we need a previous
478    * packet to decode the current one so we must be careful not to
479    * throw away too much. For now we decode everything and clip right
480    * before pushing data. */
481 
482 #ifdef USE_TREMOLO
483   if (G_UNLIKELY (vorbis_dsp_synthesis (&vd->vd, packet, 1)))
484     goto could_not_read;
485 #else
486   if (G_UNLIKELY (vorbis_synthesis (&vd->vb, packet)))
487     goto could_not_read;
488 
489   if (G_UNLIKELY (vorbis_synthesis_blockin (&vd->vd, &vd->vb) < 0))
490     goto not_accepted;
491 #endif
492 
493   /* assume all goes well here */
494   result = GST_FLOW_OK;
495 
496   /* count samples ready for reading */
497 #ifdef USE_TREMOLO
498   if ((sample_count = vorbis_dsp_pcmout (&vd->vd, NULL, 0)) == 0)
499 #else
500   if ((sample_count = vorbis_synthesis_pcmout (&vd->vd, NULL)) == 0)
501     goto done;
502 #endif
503 
504   size = sample_count * vd->info.bpf;
505   GST_LOG_OBJECT (vd, "%d samples ready for reading, size %" G_GSIZE_FORMAT,
506       sample_count, size);
507 
508   /* alloc buffer for it */
509   out = gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER (vd), size);
510 
511   gst_buffer_map (out, &map, GST_MAP_WRITE);
512   /* get samples ready for reading now, should be sample_count */
513 #ifdef USE_TREMOLO
514   if (G_UNLIKELY (vorbis_dsp_pcmout (&vd->vd, map.data, sample_count) !=
515           sample_count))
516 #else
517   if (G_UNLIKELY (vorbis_synthesis_pcmout (&vd->vd, &pcm) != sample_count))
518 #endif
519     goto wrong_samples;
520 
521 #ifdef USE_TREMOLO
522   if (vd->info.channels < 9)
523     gst_audio_reorder_channels (map.data, map.size, GST_VORBIS_AUDIO_FORMAT,
524         vd->info.channels, gst_vorbis_channel_positions[vd->info.channels - 1],
525         gst_vorbis_default_channel_positions[vd->info.channels - 1]);
526 #else
527   /* copy samples in buffer */
528   vd->copy_samples ((vorbis_sample_t *) map.data, pcm,
529       sample_count, vd->info.channels);
530 #endif
531 
532   GST_LOG_OBJECT (vd, "have output size of %" G_GSIZE_FORMAT, size);
533   gst_buffer_unmap (out, &map);
534 
535 done:
536   /* whether or not data produced, consume one frame and advance time */
537   result = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (vd), out, 1);
538 
539 #ifdef USE_TREMOLO
540   vorbis_dsp_read (&vd->vd, sample_count);
541 #else
542   vorbis_synthesis_read (&vd->vd, sample_count);
543 #endif
544 
545   return result;
546 
547   /* ERRORS */
548 not_initialized:
549   {
550     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
551         (NULL), ("no header sent yet"));
552     return GST_FLOW_NOT_NEGOTIATED;
553   }
554 could_not_read:
555   {
556     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
557         (NULL), ("couldn't read data packet"));
558     return GST_FLOW_ERROR;
559   }
560 not_accepted:
561   {
562     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
563         (NULL), ("vorbis decoder did not accept data packet"));
564     return GST_FLOW_ERROR;
565   }
566 wrong_samples:
567   {
568     gst_buffer_unref (out);
569     GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
570         (NULL), ("vorbis decoder reported wrong number of samples"));
571     return GST_FLOW_ERROR;
572   }
573 }
574 
575 static GstFlowReturn
check_pending_headers(GstVorbisDec * vd)576 check_pending_headers (GstVorbisDec * vd)
577 {
578   GstBuffer *buffer1, *buffer3, *buffer5;
579   GstMapInfo map;
580   gboolean isvalid;
581   GList *tmp = vd->pending_headers;
582   GstFlowReturn result = GST_FLOW_OK;
583 
584   if (g_list_length (vd->pending_headers) < MIN_NUM_HEADERS)
585     goto not_enough;
586 
587   buffer1 = (GstBuffer *) tmp->data;
588   tmp = tmp->next;
589   buffer3 = (GstBuffer *) tmp->data;
590   tmp = tmp->next;
591   buffer5 = (GstBuffer *) tmp->data;
592 
593   /* Start checking the headers */
594   gst_buffer_map (buffer1, &map, GST_MAP_READ);
595   isvalid = map.size >= 1 && map.data[0] == 0x01;
596   gst_buffer_unmap (buffer1, &map);
597   if (!isvalid) {
598     GST_WARNING_OBJECT (vd, "Pending first header was invalid");
599     goto cleanup;
600   }
601 
602   gst_buffer_map (buffer3, &map, GST_MAP_READ);
603   isvalid = map.size >= 1 && map.data[0] == 0x03;
604   gst_buffer_unmap (buffer3, &map);
605   if (!isvalid) {
606     GST_WARNING_OBJECT (vd, "Pending second header was invalid");
607     goto cleanup;
608   }
609 
610   gst_buffer_map (buffer5, &map, GST_MAP_READ);
611   isvalid = map.size >= 1 && map.data[0] == 0x05;
612   gst_buffer_unmap (buffer5, &map);
613   if (!isvalid) {
614     GST_WARNING_OBJECT (vd, "Pending third header was invalid");
615     goto cleanup;
616   }
617 
618   /* Discard any other pending headers */
619   if (tmp->next) {
620     GST_DEBUG_OBJECT (vd, "Discarding extra headers");
621     g_list_free_full (tmp->next, (GDestroyNotify) gst_buffer_unref);
622     tmp->next = NULL;
623   }
624   g_list_free (vd->pending_headers);
625   vd->pending_headers = NULL;
626 
627   GST_DEBUG_OBJECT (vd, "Resetting and processing new headers");
628 
629   /* All good, let's reset ourselves and process the headers */
630   vorbis_dec_reset ((GstAudioDecoder *) vd);
631   result = vorbis_dec_handle_header_buffer (vd, buffer1);
632   gst_buffer_unref (buffer1);
633   if (result != GST_FLOW_OK) {
634     gst_buffer_unref (buffer3);
635     gst_buffer_unref (buffer5);
636     return result;
637   }
638   result = vorbis_dec_handle_header_buffer (vd, buffer3);
639   gst_buffer_unref (buffer3);
640   if (result != GST_FLOW_OK) {
641     gst_buffer_unref (buffer5);
642     return result;
643   }
644   result = vorbis_dec_handle_header_buffer (vd, buffer5);
645   gst_buffer_unref (buffer5);
646 
647   return result;
648 
649   /* ERRORS */
650 cleanup:
651   {
652     g_list_free_full (vd->pending_headers, (GDestroyNotify) gst_buffer_unref);
653     vd->pending_headers = NULL;
654     return result;
655   }
656 not_enough:
657   {
658     GST_LOG_OBJECT (vd,
659         "Not enough pending headers to properly reset, ignoring them");
660     goto cleanup;
661   }
662 }
663 
664 static GstFlowReturn
vorbis_dec_handle_frame(GstAudioDecoder * dec,GstBuffer * buffer)665 vorbis_dec_handle_frame (GstAudioDecoder * dec, GstBuffer * buffer)
666 {
667   ogg_packet *packet;
668   ogg_packet_wrapper packet_wrapper;
669   GstFlowReturn result = GST_FLOW_OK;
670   GstMapInfo map;
671   GstVorbisDec *vd = GST_VORBIS_DEC (dec);
672 
673   /* no draining etc */
674   if (G_UNLIKELY (!buffer))
675     return GST_FLOW_OK;
676 
677   GST_LOG_OBJECT (vd, "got buffer %p", buffer);
678   /* make ogg_packet out of the buffer */
679   gst_ogg_packet_wrapper_map (&packet_wrapper, buffer, &map);
680   packet = gst_ogg_packet_from_wrapper (&packet_wrapper);
681   /* set some more stuff */
682   packet->granulepos = -1;
683   packet->packetno = 0;         /* we don't care */
684   /* EOS does not matter, it is used in vorbis to implement clipping the last
685    * block of samples based on the granulepos. We clip based on segments. */
686   packet->e_o_s = 0;
687 
688   GST_LOG_OBJECT (vd, "decode buffer of size %ld", packet->bytes);
689 
690   /* error out on empty header packets, but just skip empty data packets */
691   if (G_UNLIKELY (packet->bytes == 0)) {
692     if (vd->initialized)
693       goto empty_buffer;
694     else
695       goto empty_header;
696   }
697 
698   /* switch depending on packet type */
699   if ((gst_ogg_packet_data (packet))[0] & 1) {
700     gboolean have_all_headers;
701 
702     GST_LOG_OBJECT (vd, "storing header for later analyzis");
703 
704     /* An identification packet starts a new set of headers */
705     if (vd->pending_headers && (gst_ogg_packet_data (packet))[0] == 0x01) {
706       GST_DEBUG_OBJECT (vd,
707           "got new identification header packet, discarding old pending headers");
708 
709       g_list_free_full (vd->pending_headers, (GDestroyNotify) gst_buffer_unref);
710       vd->pending_headers = NULL;
711     }
712 
713     /* if we have more than 3 headers with the new one and the new one is the
714      * type header, we can initialize the decoder now */
715     have_all_headers = g_list_length (vd->pending_headers) >= 2
716         && (gst_ogg_packet_data (packet))[0] == 0x05;
717 
718     if (!vd->pending_headers && (gst_ogg_packet_data (packet))[0] != 0x01) {
719       if (vd->initialized) {
720         GST_DEBUG_OBJECT (vd,
721             "Got another non-identification header after initialization, ignoring");
722       } else {
723         GST_WARNING_OBJECT (vd,
724             "First header was not a identification header, dropping");
725       }
726       result = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (vd), NULL, 1);
727     } else {
728       vd->pending_headers =
729           g_list_append (vd->pending_headers, gst_buffer_ref (buffer));
730       result = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (vd), NULL, 1);
731     }
732 
733     if (result == GST_FLOW_OK && have_all_headers) {
734       result = check_pending_headers (vd);
735     }
736   } else {
737     GstClockTime timestamp, duration;
738 
739     if (vd->pending_headers)
740       result = check_pending_headers (vd);
741     if (G_UNLIKELY (result != GST_FLOW_OK))
742       goto done;
743 
744     timestamp = GST_BUFFER_TIMESTAMP (buffer);
745     duration = GST_BUFFER_DURATION (buffer);
746 
747     result = vorbis_handle_data_packet (vd, packet, timestamp, duration);
748   }
749 
750 done:
751   GST_LOG_OBJECT (vd, "unmap buffer %p", buffer);
752   gst_ogg_packet_wrapper_unmap (&packet_wrapper, buffer, &map);
753 
754   return result;
755 
756 empty_buffer:
757   {
758     /* don't error out here, just ignore the buffer, it's invalid for vorbis
759      * but not fatal. */
760     GST_WARNING_OBJECT (vd, "empty buffer received, ignoring");
761     result = GST_FLOW_OK;
762     goto done;
763   }
764 
765 /* ERRORS */
766 empty_header:
767   {
768     GST_ELEMENT_ERROR (vd, STREAM, DECODE, (NULL), ("empty header received"));
769     result = GST_FLOW_ERROR;
770     goto done;
771   }
772 }
773 
774 static void
vorbis_dec_flush(GstAudioDecoder * dec,gboolean hard)775 vorbis_dec_flush (GstAudioDecoder * dec, gboolean hard)
776 {
777   GstVorbisDec *vd = GST_VORBIS_DEC (dec);
778 
779   vorbis_synthesis_restart (&vd->vd);
780 }
781 
782 static void
vorbis_dec_reset(GstAudioDecoder * dec)783 vorbis_dec_reset (GstAudioDecoder * dec)
784 {
785   GstVorbisDec *vd = GST_VORBIS_DEC (dec);
786 
787   vd->initialized = FALSE;
788 #ifndef USE_TREMOLO
789   vorbis_block_clear (&vd->vb);
790 #endif
791   vorbis_dsp_clear (&vd->vd);
792 
793   vorbis_comment_clear (&vd->vc);
794   vorbis_info_clear (&vd->vi);
795   vorbis_info_init (&vd->vi);
796   vorbis_comment_init (&vd->vc);
797 }
798 
799 static gboolean
vorbis_dec_set_format(GstAudioDecoder * dec,GstCaps * caps)800 vorbis_dec_set_format (GstAudioDecoder * dec, GstCaps * caps)
801 {
802   GstVorbisDec *vd = GST_VORBIS_DEC (dec);
803 
804   GST_DEBUG_OBJECT (vd, "New caps %" GST_PTR_FORMAT " - resetting", caps);
805 
806   /* A set_format call implies new data with new header packets */
807   if (!vd->initialized)
808     return TRUE;
809 
810   /* We need to free and re-init libvorbis,
811    * or it chokes */
812   vorbis_dec_reset (dec);
813 
814   return TRUE;
815 }
816