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