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