1 /* GStreamer
2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
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 */
20 /**
21 * SECTION:element-mad
22 * @see_also: lame
23 *
24 * MP3 audio decoder.
25 *
26 * <refsect2>
27 * <title>Example pipelines</title>
28 * |[
29 * gst-launch filesrc location=music.mp3 ! mad ! audioconvert ! audioresample ! autoaudiosink
30 * ]| Decode the mp3 file and play
31 * </refsect2>
32 */
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
38 #include <stdlib.h>
39 #include <string.h>
40 #include "gstmad.h"
41 #include <gst/audio/audio.h>
43 enum
44 {
45 ARG_0,
46 ARG_HALF,
47 ARG_IGNORE_CRC
48 };
50 GST_DEBUG_CATEGORY_STATIC (mad_debug);
51 #define GST_CAT_DEFAULT mad_debug
53 static GstStaticPadTemplate mad_src_template_factory =
54 GST_STATIC_PAD_TEMPLATE ("src",
55 GST_PAD_SRC,
56 GST_PAD_ALWAYS,
57 GST_STATIC_CAPS ("audio/x-raw-int, "
58 "endianness = (int) " G_STRINGIFY (G_BYTE_ORDER) ", "
59 "signed = (boolean) true, "
60 "width = (int) 32, "
61 "depth = (int) 32, "
62 "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }, "
63 "channels = (int) [ 1, 2 ]")
64 );
66 /* FIXME: make three caps, for mpegversion 1, 2 and 2.5 */
67 static GstStaticPadTemplate mad_sink_template_factory =
68 GST_STATIC_PAD_TEMPLATE ("sink",
69 GST_PAD_SINK,
70 GST_PAD_ALWAYS,
71 GST_STATIC_CAPS ("audio/mpeg, "
72 "mpegversion = (int) 1, "
73 "layer = (int) [ 1, 3 ], "
74 "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }, "
75 "channels = (int) [ 1, 2 ]")
76 );
78 static void gst_mad_base_init (gpointer g_class);
79 static void gst_mad_class_init (GstMadClass * klass);
80 static void gst_mad_init (GstMad * mad, GstMadClass * klass);
81 static void gst_mad_dispose (GObject * object);
83 static void gst_mad_set_property (GObject * object, guint prop_id,
84 const GValue * value, GParamSpec * pspec);
85 static void gst_mad_get_property (GObject * object, guint prop_id,
86 GValue * value, GParamSpec * pspec);
88 static gboolean gst_mad_src_event (GstPad * pad, GstEvent * event);
90 static const GstQueryType *gst_mad_get_query_types (GstPad * pad);
92 static gboolean gst_mad_src_query (GstPad * pad, GstQuery * query);
93 static gboolean gst_mad_convert_sink (GstPad * pad, GstFormat src_format,
94 gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
95 static gboolean gst_mad_convert_src (GstPad * pad, GstFormat src_format,
96 gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
98 static gboolean gst_mad_sink_event (GstPad * pad, GstEvent * event);
99 static GstFlowReturn gst_mad_chain (GstPad * pad, GstBuffer * buffer);
101 static GstStateChangeReturn gst_mad_change_state (GstElement * element,
102 GstStateChange transition);
104 #ifndef GST_DISABLE_INDEX
105 static void gst_mad_set_index (GstElement * element, GstIndex * index);
106 static GstIndex *gst_mad_get_index (GstElement * element);
107 #endif
109 static GstTagList *gst_mad_id3_to_tag_list (const struct id3_tag *tag);
111 GST_BOILERPLATE (GstMad, gst_mad, GstElement, GST_TYPE_ELEMENT);
113 /*
114 #define GST_TYPE_MAD_LAYER (gst_mad_layer_get_type())
115 static GType
116 gst_mad_layer_get_type (void)
117 {
118 static GType mad_layer_type = 0;
119 static GEnumValue mad_layer[] = {
120 {0, "Unknown", "unknown"},
121 {MAD_LAYER_I, "Layer I", "1"},
122 {MAD_LAYER_II, "Layer II", "2"},
123 {MAD_LAYER_III, "Layer III", "3"},
124 {0, NULL, NULL},
125 };
127 if (!mad_layer_type) {
128 mad_layer_type = g_enum_register_static ("GstMadLayer", mad_layer);
129 }
130 return mad_layer_type;
131 }
132 */
134 #define GST_TYPE_MAD_MODE (gst_mad_mode_get_type())
135 static GType
136 gst_mad_mode_get_type (void)
137 {
138 static GType mad_mode_type = 0;
139 static GEnumValue mad_mode[] = {
140 {-1, "Unknown", "unknown"},
141 {MAD_MODE_SINGLE_CHANNEL, "Mono", "mono"},
142 {MAD_MODE_DUAL_CHANNEL, "Dual Channel", "dual"},
143 {MAD_MODE_JOINT_STEREO, "Joint Stereo", "joint"},
144 {MAD_MODE_STEREO, "Stereo", "stereo"},
145 {0, NULL, NULL},
146 };
148 if (!mad_mode_type) {
149 mad_mode_type = g_enum_register_static ("GstMadMode", mad_mode);
150 }
151 return mad_mode_type;
152 }
154 #define GST_TYPE_MAD_EMPHASIS (gst_mad_emphasis_get_type())
155 static GType
156 gst_mad_emphasis_get_type (void)
157 {
158 static GType mad_emphasis_type = 0;
159 static GEnumValue mad_emphasis[] = {
160 {-1, "Unknown", "unknown"},
161 {MAD_EMPHASIS_NONE, "None", "none"},
162 {MAD_EMPHASIS_50_15_US, "50/15 Microseconds", "50-15"},
163 {MAD_EMPHASIS_CCITT_J_17, "CCITT J.17", "j-17"},
164 {MAD_EMPHASIS_RESERVED, "Reserved", "reserved"},
165 {0, NULL, NULL},
166 };
168 if (!mad_emphasis_type) {
169 mad_emphasis_type = g_enum_register_static ("GstMadEmphasis", mad_emphasis);
170 }
171 return mad_emphasis_type;
172 }
174 static void
175 gst_mad_base_init (gpointer g_class)
176 {
177 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
179 gst_element_class_add_pad_template (element_class,
180 gst_static_pad_template_get (&mad_sink_template_factory));
181 gst_element_class_add_pad_template (element_class,
182 gst_static_pad_template_get (&mad_src_template_factory));
183 gst_element_class_set_details_simple (element_class, "mad mp3 decoder",
184 "Codec/Decoder/Audio",
185 "Uses mad code to decode mp3 streams", "Wim Taymans <wim@fluendo.com>");
186 }
188 static void
189 gst_mad_class_init (GstMadClass * klass)
190 {
191 GObjectClass *gobject_class;
192 GstElementClass *gstelement_class;
194 gobject_class = (GObjectClass *) klass;
195 gstelement_class = (GstElementClass *) klass;
197 parent_class = g_type_class_peek_parent (klass);
199 gobject_class->set_property = gst_mad_set_property;
200 gobject_class->get_property = gst_mad_get_property;
201 gobject_class->dispose = gst_mad_dispose;
203 gstelement_class->change_state = gst_mad_change_state;
204 #ifndef GST_DISABLE_INDEX
205 gstelement_class->set_index = gst_mad_set_index;
206 gstelement_class->get_index = gst_mad_get_index;
207 #endif
209 /* init properties */
210 /* currently, string representations are used, we might want to change that */
211 /* FIXME: descriptions need to be more technical,
212 * default values and ranges need to be selected right */
213 g_object_class_install_property (gobject_class, ARG_HALF,
214 g_param_spec_boolean ("half", "Half", "Generate PCM at 1/2 sample rate",
215 FALSE, G_PARAM_READWRITE));
216 g_object_class_install_property (gobject_class, ARG_IGNORE_CRC,
217 g_param_spec_boolean ("ignore_crc", "Ignore CRC", "Ignore CRC errors",
218 TRUE, G_PARAM_READWRITE));
220 /* register tags */
221 #define GST_TAG_LAYER "layer"
222 #define GST_TAG_MODE "mode"
223 #define GST_TAG_EMPHASIS "emphasis"
225 /* FIXME 0.11: strings!? why? */
226 gst_tag_register (GST_TAG_LAYER, GST_TAG_FLAG_ENCODED, G_TYPE_UINT,
227 "layer", "MPEG audio layer", NULL);
228 gst_tag_register (GST_TAG_MODE, GST_TAG_FLAG_ENCODED, G_TYPE_STRING,
229 "mode", "MPEG audio channel mode", NULL);
230 gst_tag_register (GST_TAG_EMPHASIS, GST_TAG_FLAG_ENCODED, G_TYPE_STRING,
231 "emphasis", "MPEG audio emphasis", NULL);
233 /* ref these here from a thread-safe context (ie. not the streaming thread) */
234 g_type_class_ref (GST_TYPE_MAD_MODE);
235 g_type_class_ref (GST_TYPE_MAD_EMPHASIS);
236 }
238 static void
239 gst_mad_init (GstMad * mad, GstMadClass * klass)
240 {
241 GstPadTemplate *template;
243 /* create the sink and src pads */
244 template = gst_static_pad_template_get (&mad_sink_template_factory);
245 mad->sinkpad = gst_pad_new_from_template (template, "sink");
246 gst_object_unref (template);
247 gst_element_add_pad (GST_ELEMENT (mad), mad->sinkpad);
248 gst_pad_set_chain_function (mad->sinkpad, GST_DEBUG_FUNCPTR (gst_mad_chain));
249 gst_pad_set_event_function (mad->sinkpad,
250 GST_DEBUG_FUNCPTR (gst_mad_sink_event));
252 template = gst_static_pad_template_get (&mad_src_template_factory);
253 mad->srcpad = gst_pad_new_from_template (template, "src");
254 gst_object_unref (template);
255 gst_element_add_pad (GST_ELEMENT (mad), mad->srcpad);
256 gst_pad_set_event_function (mad->srcpad,
257 GST_DEBUG_FUNCPTR (gst_mad_src_event));
258 gst_pad_set_query_function (mad->srcpad,
259 GST_DEBUG_FUNCPTR (gst_mad_src_query));
260 gst_pad_set_query_type_function (mad->srcpad,
261 GST_DEBUG_FUNCPTR (gst_mad_get_query_types));
262 gst_pad_use_fixed_caps (mad->srcpad);
264 mad->tempbuffer = g_malloc (MAD_BUFFER_MDLEN * 3);
265 mad->tempsize = 0;
266 mad->base_byte_offset = 0;
267 mad->bytes_consumed = 0;
268 mad->total_samples = 0;
269 mad->new_header = TRUE;
270 mad->framecount = 0;
271 mad->vbr_average = 0;
272 mad->vbr_rate = 0;
273 mad->restart = TRUE;
274 mad->segment_start = 0;
275 gst_segment_init (&mad->segment, GST_FORMAT_TIME);
276 mad->header.mode = -1;
277 mad->header.emphasis = -1;
278 mad->tags = NULL;
280 mad->half = FALSE;
281 mad->ignore_crc = TRUE;
282 mad->check_for_xing = TRUE;
283 mad->xing_found = FALSE;
284 }
286 static void
287 gst_mad_dispose (GObject * object)
288 {
289 GstMad *mad = GST_MAD (object);
291 #ifndef GST_DISABLE_INDEX
292 gst_mad_set_index (GST_ELEMENT (object), NULL);
293 #endif
295 g_free (mad->tempbuffer);
296 mad->tempbuffer = NULL;
298 g_list_foreach (mad->pending_events, (GFunc) gst_mini_object_unref, NULL);
299 g_list_free (mad->pending_events);
300 mad->pending_events = NULL;
302 G_OBJECT_CLASS (parent_class)->dispose (object);
303 }
305 #ifndef GST_DISABLE_INDEX
306 static void
307 gst_mad_set_index (GstElement * element, GstIndex * index)
308 {
309 GstMad *mad = GST_MAD (element);
311 mad->index = index;
313 if (index)
314 gst_index_get_writer_id (index, GST_OBJECT (element), &mad->index_id);
315 }
317 static GstIndex *
318 gst_mad_get_index (GstElement * element)
319 {
320 GstMad *mad = GST_MAD (element);
322 return mad->index;
323 }
324 #endif
326 static gboolean
327 gst_mad_convert_sink (GstPad * pad, GstFormat src_format, gint64 src_value,
328 GstFormat * dest_format, gint64 * dest_value)
329 {
330 gboolean res = TRUE;
331 GstMad *mad;
333 if (src_format == *dest_format) {
334 *dest_value = src_value;
335 return TRUE;
336 }
338 /* -1 always maps to -1, and 0 to 0, we don't need any more info for that */
339 if (src_value == -1 || src_value == 0) {
340 *dest_value = src_value;
341 return TRUE;
342 }
344 mad = GST_MAD (GST_PAD_PARENT (pad));
346 if (mad->vbr_average == 0)
347 return FALSE;
349 switch (src_format) {
350 case GST_FORMAT_BYTES:
351 switch (*dest_format) {
352 case GST_FORMAT_TIME:
353 /* multiply by 8 because vbr is in bits/second */
354 *dest_value = gst_util_uint64_scale (src_value, 8 * GST_SECOND,
355 mad->vbr_average);
356 break;
357 default:
358 res = FALSE;
359 }
360 break;
361 case GST_FORMAT_TIME:
362 switch (*dest_format) {
363 case GST_FORMAT_BYTES:
364 /* multiply by 8 because vbr is in bits/second */
365 *dest_value = gst_util_uint64_scale (src_value, mad->vbr_average,
366 8 * GST_SECOND);
367 break;
368 default:
369 res = FALSE;
370 }
371 break;
372 default:
373 res = FALSE;
374 }
375 return res;
376 }
378 static gboolean
379 gst_mad_convert_src (GstPad * pad, GstFormat src_format, gint64 src_value,
380 GstFormat * dest_format, gint64 * dest_value)
381 {
382 gboolean res = TRUE;
383 guint scale = 1;
384 gint bytes_per_sample;
385 GstMad *mad;
387 if (src_format == *dest_format) {
388 *dest_value = src_value;
389 return TRUE;
390 }
392 /* -1 always maps to -1, and 0 to 0, we don't need any more info for that */
393 if (src_value == -1 || src_value == 0) {
394 *dest_value = src_value;
395 return TRUE;
396 }
398 mad = GST_MAD (GST_PAD_PARENT (pad));
400 bytes_per_sample = mad->channels * 4;
402 switch (src_format) {
403 case GST_FORMAT_BYTES:
404 switch (*dest_format) {
405 case GST_FORMAT_DEFAULT:
406 if (bytes_per_sample == 0)
407 return FALSE;
408 *dest_value = src_value / bytes_per_sample;
409 break;
410 case GST_FORMAT_TIME:
411 {
412 gint byterate = bytes_per_sample * mad->rate;
414 if (byterate == 0)
415 return FALSE;
416 *dest_value =
417 gst_util_uint64_scale_int (src_value, GST_SECOND, byterate);
418 break;
419 }
420 default:
421 res = FALSE;
422 }
423 break;
424 case GST_FORMAT_DEFAULT:
425 switch (*dest_format) {
426 case GST_FORMAT_BYTES:
427 *dest_value = src_value * bytes_per_sample;
428 break;
429 case GST_FORMAT_TIME:
430 if (mad->rate == 0)
431 return FALSE;
432 *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
433 mad->rate);
434 break;
435 default:
436 res = FALSE;
437 }
438 break;
439 case GST_FORMAT_TIME:
440 switch (*dest_format) {
441 case GST_FORMAT_BYTES:
442 scale = bytes_per_sample;
443 /* fallthrough */
444 case GST_FORMAT_DEFAULT:
445 *dest_value = gst_util_uint64_scale_int (src_value,
446 scale * mad->rate, GST_SECOND);
447 break;
448 default:
449 res = FALSE;
450 }
451 break;
452 default:
453 res = FALSE;
454 }
455 return res;
456 }
458 static const GstQueryType *
459 gst_mad_get_query_types (GstPad * pad)
460 {
461 static const GstQueryType gst_mad_src_query_types[] = {
462 GST_QUERY_POSITION,
463 GST_QUERY_DURATION,
464 GST_QUERY_CONVERT,
465 0
466 };
468 return gst_mad_src_query_types;
469 }
471 static gboolean
472 gst_mad_src_query (GstPad * pad, GstQuery * query)
473 {
474 gboolean res = TRUE;
475 GstPad *peer;
476 GstMad *mad;
478 mad = GST_MAD (GST_PAD_PARENT (pad));
480 peer = gst_pad_get_peer (mad->sinkpad);
482 switch (GST_QUERY_TYPE (query)) {
483 case GST_QUERY_FORMATS:
484 gst_query_set_formats (query, 3, GST_FORMAT_DEFAULT, GST_FORMAT_TIME,
485 GST_FORMAT_BYTES);
486 break;
487 case GST_QUERY_POSITION:
488 {
489 GstFormat format;
490 gint64 cur;
492 /* save requested format */
493 gst_query_parse_position (query, &format, NULL);
495 /* try any demuxer before us first */
496 if (format == GST_FORMAT_TIME && peer && gst_pad_query (peer, query)) {
497 gst_query_parse_position (query, NULL, &cur);
498 GST_LOG_OBJECT (mad, "peer returned position %" GST_TIME_FORMAT,
499 GST_TIME_ARGS (cur));
500 break;
501 }
503 /* and convert to the requested format */
504 if (format != GST_FORMAT_DEFAULT) {
505 if (!gst_mad_convert_src (pad, GST_FORMAT_DEFAULT, mad->total_samples,
506 &format, &cur))
507 goto error;
508 } else {
509 cur = mad->total_samples;
510 }
512 gst_query_set_position (query, format, cur);
514 if (format == GST_FORMAT_TIME) {
515 GST_LOG ("position=%" GST_TIME_FORMAT, GST_TIME_ARGS (cur));
516 } else {
517 GST_LOG ("position=%" G_GINT64_FORMAT ", format=%u", cur, format);
518 }
519 break;
520 }
521 case GST_QUERY_DURATION:
522 {
523 GstFormat bytes_format = GST_FORMAT_BYTES;
524 GstFormat time_format = GST_FORMAT_TIME;
525 GstFormat req_format;
526 gint64 total, total_bytes;
528 /* save requested format */
529 gst_query_parse_duration (query, &req_format, NULL);
531 if (peer == NULL)
532 goto error;
534 /* try any demuxer before us first */
535 if (req_format == GST_FORMAT_TIME && gst_pad_query (peer, query)) {
536 gst_query_parse_duration (query, NULL, &total);
537 GST_LOG_OBJECT (mad, "peer returned duration %" GST_TIME_FORMAT,
538 GST_TIME_ARGS (total));
539 break;
540 }
542 /* query peer for total length in bytes */
543 if (!gst_pad_query_peer_duration (mad->sinkpad, &bytes_format,
544 &total_bytes) || total_bytes <= 0) {
545 GST_LOG_OBJECT (mad, "duration query on peer pad failed");
546 goto error;
547 }
549 GST_LOG_OBJECT (mad, "peer pad returned total=%" G_GINT64_FORMAT
550 " bytes", total_bytes);
552 if (!gst_mad_convert_sink (pad, GST_FORMAT_BYTES, total_bytes,
553 &time_format, &total)) {
554 GST_DEBUG_OBJECT (mad, "conversion BYTE => TIME failed");
555 goto error;
556 }
557 if (!gst_mad_convert_src (pad, GST_FORMAT_TIME, total,
558 &req_format, &total)) {
559 GST_DEBUG_OBJECT (mad, "conversion TIME => %s failed",
560 gst_format_get_name (req_format));
561 goto error;
562 }
564 gst_query_set_duration (query, req_format, total);
566 if (req_format == GST_FORMAT_TIME) {
567 GST_LOG_OBJECT (mad, "duration=%" GST_TIME_FORMAT,
568 GST_TIME_ARGS (total));
569 } else {
570 GST_LOG_OBJECT (mad, "duration=%" G_GINT64_FORMAT " (%s)",
571 total, gst_format_get_name (req_format));
572 }
573 break;
574 }
575 case GST_QUERY_CONVERT:
576 {
577 GstFormat src_fmt, dest_fmt;
578 gint64 src_val, dest_val;
580 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
581 if (!(res =
582 gst_mad_convert_src (pad, src_fmt, src_val, &dest_fmt,
583 &dest_val)))
584 goto error;
585 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
586 break;
587 }
588 default:
589 res = gst_pad_query_default (pad, query);
590 break;
591 }
593 if (peer)
594 gst_object_unref (peer);
596 return res;
598 error:
600 GST_DEBUG ("error handling query");
602 if (peer)
603 gst_object_unref (peer);
605 return FALSE;
606 }
608 #ifndef GST_DISABLE_INDEX
609 static gboolean
610 index_seek (GstMad * mad, GstPad * pad, GstEvent * event)
611 {
612 gdouble rate;
613 GstFormat format;
614 GstSeekFlags flags;
615 GstSeekType cur_type, stop_type;
616 gint64 cur, stop;
617 GstIndexEntry *entry = NULL;
619 /* since we know the exact byteoffset of the frame,
620 make sure to try bytes first */
622 const GstFormat try_all_formats[] = {
623 GST_FORMAT_BYTES,
624 GST_FORMAT_TIME,
625 0
626 };
627 const GstFormat *try_formats = try_all_formats;
628 const GstFormat *peer_formats;
630 gst_event_parse_seek (event, &rate, &format, &flags,
631 &cur_type, &cur, &stop_type, &stop);
633 if (format == GST_FORMAT_TIME) {
634 gst_segment_set_seek (&mad->segment, rate, format, flags, cur_type,
635 cur, stop_type, stop, NULL);
636 } else {
637 gst_segment_init (&mad->segment, GST_FORMAT_UNDEFINED);
638 }
640 entry = gst_index_get_assoc_entry (mad->index, mad->index_id,
641 GST_INDEX_LOOKUP_BEFORE, 0, format, cur);
643 GST_DEBUG ("index seek");
645 if (!entry)
646 return FALSE;
648 #if 0
649 peer_formats = gst_pad_get_formats (GST_PAD_PEER (mad->sinkpad));
650 #else
651 peer_formats = try_all_formats; /* FIXME */
652 #endif
654 while (gst_formats_contains (peer_formats, *try_formats)) {
655 gint64 value;
656 GstEvent *seek_event;
658 if (gst_index_entry_assoc_map (entry, *try_formats, &value)) {
659 /* lookup succeeded, create the seek */
661 GST_DEBUG ("index %s %" G_GINT64_FORMAT
662 " -> %s %" G_GINT64_FORMAT,
663 gst_format_get_details (format)->nick,
664 cur, gst_format_get_details (*try_formats)->nick, value);
666 seek_event = gst_event_new_seek (rate, *try_formats, flags,
667 cur_type, value, stop_type, stop);
669 if (gst_pad_send_event (GST_PAD_PEER (mad->sinkpad), seek_event)) {
670 /* seek worked, we're done, loop will exit */
671 mad->restart = TRUE;
672 g_assert (format == GST_FORMAT_TIME);
673 mad->segment_start = cur;
674 return TRUE;
675 }
676 }
677 try_formats++;
678 }
680 return FALSE;
681 }
682 #endif
684 static gboolean
685 normal_seek (GstMad * mad, GstPad * pad, GstEvent * event)
686 {
687 gdouble rate;
688 GstFormat format, conv;
689 GstSeekFlags flags;
690 GstSeekType cur_type, stop_type;
691 gint64 cur, stop;
692 gint64 time_cur, time_stop;
693 gint64 bytes_cur, bytes_stop;
694 gboolean flush;
696 /* const GstFormat *peer_formats; */
697 gboolean res;
699 GST_DEBUG ("normal seek");
701 gst_event_parse_seek (event, &rate, &format, &flags,
702 &cur_type, &cur, &stop_type, &stop);
704 if (format != GST_FORMAT_TIME) {
705 conv = GST_FORMAT_TIME;
706 if (!gst_mad_convert_src (pad, format, cur, &conv, &time_cur))
707 goto convert_error;
708 if (!gst_mad_convert_src (pad, format, stop, &conv, &time_stop))
709 goto convert_error;
710 } else {
711 time_cur = cur;
712 time_stop = stop;
713 }
715 gst_segment_set_seek (&mad->segment, rate, GST_FORMAT_TIME, flags, cur_type,
716 time_cur, stop_type, time_stop, NULL);
718 GST_DEBUG ("seek to time %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
719 GST_TIME_ARGS (time_cur), GST_TIME_ARGS (time_stop));
721 /* shave off the flush flag, we'll need it later */
722 flush = ((flags & GST_SEEK_FLAG_FLUSH) != 0);
724 conv = GST_FORMAT_BYTES;
725 if (!gst_mad_convert_sink (pad, GST_FORMAT_TIME, time_cur, &conv, &bytes_cur))
726 goto convert_error;
727 if (!gst_mad_convert_sink (pad, GST_FORMAT_TIME, time_stop, &conv,
728 &bytes_stop))
729 goto convert_error;
731 {
732 GstEvent *seek_event;
734 /* conversion succeeded, create the seek */
735 seek_event =
736 gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type,
737 bytes_cur, stop_type, bytes_stop);
739 /* do the seek */
740 res = gst_pad_push_event (mad->sinkpad, seek_event);
742 if (res) {
743 /* we need to break out of the processing loop on flush */
744 mad->restart = flush;
745 mad->segment_start = time_cur;
746 mad->last_ts = time_cur;
747 }
748 }
749 #if 0
750 peer_formats = gst_pad_get_formats (GST_PAD_PEER (mad->sinkpad));
751 /* while we did not exhaust our seek formats without result */
752 while (peer_formats && *peer_formats && !res) {
753 gint64 desired_offset;
755 format = *peer_formats;
757 /* try to convert requested format to one we can seek with on the sinkpad */
758 if (gst_pad_convert (mad->sinkpad, GST_FORMAT_TIME, src_offset,
759 &format, &desired_offset)) {
760 GstEvent *seek_event;
762 /* conversion succeeded, create the seek */
763 seek_event =
764 gst_event_new_seek (format | GST_EVENT_SEEK_METHOD (event) | flush,
765 desired_offset);
766 /* do the seek */
767 if (gst_pad_send_event (GST_PAD_PEER (mad->sinkpad), seek_event)) {
768 /* seek worked, we're done, loop will exit */
769 res = TRUE;
770 }
771 }
772 /* at this point, either the seek worked or res == FALSE */
773 if (res)
774 /* we need to break out of the processing loop on flush */
775 mad->restart = flush;
777 peer_formats++;
778 }
779 #endif
781 return res;
783 /* ERRORS */
784 convert_error:
785 {
786 /* probably unsupported seek format */
787 GST_DEBUG ("failed to convert format %u into GST_FORMAT_TIME", format);
788 return FALSE;
789 }
790 }
792 static gboolean
793 gst_mad_src_event (GstPad * pad, GstEvent * event)
794 {
795 gboolean res = TRUE;
796 GstMad *mad;
798 mad = GST_MAD (GST_PAD_PARENT (pad));
800 switch (GST_EVENT_TYPE (event)) {
801 case GST_EVENT_SEEK:
802 /* the all-formats seek logic, ref the event, we need it later */
803 gst_event_ref (event);
804 if (!(res = gst_pad_push_event (mad->sinkpad, event))) {
805 #ifndef GST_DISABLE_INDEX
806 if (mad->index)
807 res = index_seek (mad, pad, event);
808 else
809 #endif
810 res = normal_seek (mad, pad, event);
811 }
812 gst_event_unref (event);
813 break;
814 default:
815 res = gst_pad_push_event (mad->sinkpad, event);
816 break;
817 }
819 return res;
820 }
822 static inline gint32
823 scale (mad_fixed_t sample)
824 {
825 #if MAD_F_FRACBITS < 28
826 /* round */
827 sample += (1L << (28 - MAD_F_FRACBITS - 1));
828 #endif
830 /* clip */
831 if (sample >= MAD_F_ONE)
832 sample = MAD_F_ONE - 1;
833 else if (sample < -MAD_F_ONE)
834 sample = -MAD_F_ONE;
836 #if MAD_F_FRACBITS < 28
837 /* quantize */
838 sample >>= (28 - MAD_F_FRACBITS);
839 #endif
841 /* convert from 29 bits to 32 bits */
842 return (gint32) (sample << 3);
843 }
845 /* do we need this function? */
846 static void
847 gst_mad_set_property (GObject * object, guint prop_id,
848 const GValue * value, GParamSpec * pspec)
849 {
850 GstMad *mad;
852 mad = GST_MAD (object);
854 switch (prop_id) {
855 case ARG_HALF:
856 mad->half = g_value_get_boolean (value);
857 break;
858 case ARG_IGNORE_CRC:
859 mad->ignore_crc = g_value_get_boolean (value);
860 break;
861 default:
862 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
863 break;
864 }
865 }
867 static void
868 gst_mad_get_property (GObject * object, guint prop_id,
869 GValue * value, GParamSpec * pspec)
870 {
871 GstMad *mad;
873 mad = GST_MAD (object);
875 switch (prop_id) {
876 case ARG_HALF:
877 g_value_set_boolean (value, mad->half);
878 break;
879 case ARG_IGNORE_CRC:
880 g_value_set_boolean (value, mad->ignore_crc);
881 break;
882 default:
883 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
884 break;
885 }
886 }
888 static void
889 gst_mad_update_info (GstMad * mad)
890 {
891 struct mad_header *header = &mad->frame.header;
892 gboolean changed = FALSE;
894 #define CHECK_HEADER(h1,str) \
895 G_STMT_START{ \
896 if (mad->header.h1 != header->h1 || mad->new_header) { \
897 mad->header.h1 = header->h1; \
898 changed = TRUE; \
899 }; \
900 } G_STMT_END
902 /* update average bitrate */
903 if (mad->new_header) {
904 mad->framecount = 1;
905 mad->vbr_rate = header->bitrate;
906 } else {
907 mad->framecount++;
908 mad->vbr_rate += header->bitrate;
909 }
910 mad->vbr_average = (gint) (mad->vbr_rate / mad->framecount);
912 CHECK_HEADER (layer, "layer");
913 CHECK_HEADER (mode, "mode");
914 CHECK_HEADER (emphasis, "emphasis");
915 mad->header.bitrate = header->bitrate;
916 mad->new_header = FALSE;
918 if (changed) {
919 GstTagList *list;
920 GEnumValue *mode;
921 GEnumValue *emphasis;
923 mode =
924 g_enum_get_value (g_type_class_peek (GST_TYPE_MAD_MODE),
925 mad->header.mode);
926 emphasis =
927 g_enum_get_value (g_type_class_peek (GST_TYPE_MAD_EMPHASIS),
928 mad->header.emphasis);
929 list = gst_tag_list_new ();
930 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
931 GST_TAG_LAYER, mad->header.layer,
932 GST_TAG_MODE, mode->value_nick,
933 GST_TAG_EMPHASIS, emphasis->value_nick, NULL);
934 if (!mad->framed) {
935 gchar *str;
937 str = g_strdup_printf ("MPEG-1 layer %d", mad->header.layer);
938 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
939 GST_TAG_AUDIO_CODEC, str, NULL);
940 g_free (str);
941 }
942 if (!mad->xing_found) {
943 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
944 GST_TAG_BITRATE, mad->header.bitrate, NULL);
945 }
946 gst_element_post_message (GST_ELEMENT (mad),
947 gst_message_new_tag (GST_OBJECT (mad), list));
948 }
949 #undef CHECK_HEADER
951 }
953 static gboolean
954 gst_mad_sink_event (GstPad * pad, GstEvent * event)
955 {
956 GstMad *mad = GST_MAD (GST_PAD_PARENT (pad));
957 gboolean result;
959 GST_DEBUG ("handling %s event", GST_EVENT_TYPE_NAME (event));
961 switch (GST_EVENT_TYPE (event)) {
962 case GST_EVENT_NEWSEGMENT:{
963 GstFormat format;
964 gboolean update;
965 gdouble rate, applied_rate;
966 gint64 start, stop, pos;
968 gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
969 &format, &start, &stop, &pos);
971 if (format == GST_FORMAT_TIME) {
972 /* FIXME: is this really correct? */
973 mad->tempsize = 0;
974 result = gst_pad_push_event (mad->srcpad, event);
975 /* we don't need to restart when we get here */
976 mad->restart = FALSE;
977 mad->framed = TRUE;
978 gst_segment_set_newsegment_full (&mad->segment, update, rate,
979 applied_rate, GST_FORMAT_TIME, start, stop, pos);
980 } else {
981 GST_DEBUG ("dropping newsegment event in format %s",
982 gst_format_get_name (format));
983 /* on restart the chain function will generate a new
984 * newsegment event, so we can just drop this one */
985 mad->restart = TRUE;
986 gst_event_unref (event);
987 mad->tempsize = 0;
988 mad->framed = FALSE;
989 result = TRUE;
990 }
991 break;
992 }
993 case GST_EVENT_EOS:
994 mad->caps_set = FALSE; /* could be a new stream */
995 result = gst_pad_push_event (mad->srcpad, event);
996 break;
997 case GST_EVENT_FLUSH_STOP:
998 /* Clear any stored data, as it won't make sense once
999 * the new data arrives */
1000 mad->tempsize = 0;
1001 mad_frame_mute (&mad->frame);
1002 mad_synth_mute (&mad->synth);
1003 case GST_EVENT_FLUSH_START:
1004 result = gst_pad_event_default (pad, event);
1006 break;
1007 default:
1008 if (mad->restart) {
1009 /* Cache all other events if we still have to send a NEWSEGMENT */
1010 mad->pending_events = g_list_append (mad->pending_events, event);
1011 result = TRUE;
1012 } else {
1013 result = gst_pad_event_default (pad, event);
1014 }
1015 break;
1016 }
1017 return result;
1018 }
1020 static gboolean
1021 gst_mad_check_restart (GstMad * mad)
1022 {
1023 gboolean yes = mad->restart;
1025 if (mad->restart) {
1026 mad->restart = FALSE;
1027 mad->tempsize = 0;
1028 }
1029 return yes;
1030 }
1033 /* The following code has been taken from
1034 * rhythmbox/metadata/monkey-media/stream-info-impl/id3-vfs/mp3bitrate.c
1035 * which took it from xine-lib/src/demuxers/demux_mpgaudio.c
1036 * This code has been kindly relicensed to LGPL by Thibaut Mattern and
1037 * Bastien Nocera
1038 */
1039 #define BE_32(x) GST_READ_UINT32_BE(x)
1041 #define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \
1042 ( (long)(unsigned char)(ch3) | \
1043 ( (long)(unsigned char)(ch2) << 8 ) | \
1044 ( (long)(unsigned char)(ch1) << 16 ) | \
1045 ( (long)(unsigned char)(ch0) << 24 ) )
1047 /* Xing header stuff */
1048 #define XING_TAG FOURCC_TAG('X', 'i', 'n', 'g')
1049 #define XING_FRAMES_FLAG 0x0001
1050 #define XING_BYTES_FLAG 0x0002
1051 #define XING_TOC_FLAG 0x0004
1052 #define XING_VBR_SCALE_FLAG 0x0008
1053 #define XING_TOC_LENGTH 100
1055 /* check for valid "Xing" VBR header */
1056 static int
1057 is_xhead (unsigned char *buf)
1058 {
1059 return (BE_32 (buf) == XING_TAG);
1060 }
1063 #undef LOG
1064 /*#define LOG*/
1065 #ifdef LOG
1066 #ifndef WIN32
1067 #define lprintf(x...) g_print(x)
1068 #else
1069 #define lprintf GST_DEBUG
1070 #endif
1071 #else
1072 #ifndef WIN32
1073 #define lprintf(x...)
1074 #else
1075 #define lprintf GST_DEBUG
1076 #endif
1077 #endif
1079 static int
1080 mpg123_parse_xing_header (struct mad_header *header,
1081 const guint8 * buf, int bufsize, int *bitrate, int *time)
1082 {
1083 int i;
1084 guint8 *ptr = (guint8 *) buf;
1085 double frame_duration;
1086 int xflags, xframes, xbytes;
1087 int abr;
1088 guint8 xtoc[XING_TOC_LENGTH];
1089 int lsf_bit = !(header->flags & MAD_FLAG_LSF_EXT);
1091 xframes = xbytes = 0;
1093 /* offset of the Xing header */
1094 if (lsf_bit) {
1095 if (header->mode != MAD_MODE_SINGLE_CHANNEL)
1096 ptr += (32 + 4);
1097 else
1098 ptr += (17 + 4);
1099 } else {
1100 if (header->mode != MAD_MODE_SINGLE_CHANNEL)
1101 ptr += (17 + 4);
1102 else
1103 ptr += (9 + 4);
1104 }
1106 if (ptr >= (buf + bufsize - 4))
1107 return 0;
1109 if (is_xhead (ptr)) {
1110 lprintf ("Xing header found\n");
1112 ptr += 4;
1113 if (ptr >= (buf + bufsize - 4))
1114 return 0;
1116 xflags = BE_32 (ptr);
1117 ptr += 4;
1119 if (xflags & XING_FRAMES_FLAG) {
1120 if (ptr >= (buf + bufsize - 4))
1121 return 0;
1122 xframes = BE_32 (ptr);
1123 lprintf ("xframes: %d\n", xframes);
1124 ptr += 4;
1125 }
1126 if (xflags & XING_BYTES_FLAG) {
1127 if (ptr >= (buf + bufsize - 4))
1128 return 0;
1129 xbytes = BE_32 (ptr);
1130 lprintf ("xbytes: %d\n", xbytes);
1131 ptr += 4;
1132 }
1133 if (xflags & XING_TOC_FLAG) {
1134 guchar old = 0;
1136 lprintf ("toc found\n");
1137 if (ptr >= (buf + bufsize - XING_TOC_LENGTH))
1138 return 0;
1139 if (*ptr != 0) {
1140 lprintf ("skipping broken Xing TOC\n");
1141 goto skip_toc;
1142 }
1143 for (i = 0; i < XING_TOC_LENGTH; i++) {
1144 xtoc[i] = *(ptr + i);
1145 if (old > xtoc[i]) {
1146 lprintf ("skipping broken Xing TOC\n");
1147 goto skip_toc;
1148 }
1149 lprintf ("%d ", xtoc[i]);
1150 }
1151 lprintf ("\n");
1152 skip_toc:
1153 ptr += XING_TOC_LENGTH;
1154 }
1156 if (xflags & XING_VBR_SCALE_FLAG) {
1157 if (ptr >= (buf + bufsize - 4))
1158 return 0;
1159 lprintf ("xvbr_scale: %d\n", BE_32 (ptr));
1160 }
1162 /* 1 kbit = 1000 bits ! (and not 1024 bits) */
1163 if (xflags & (XING_FRAMES_FLAG | XING_BYTES_FLAG)) {
1164 if (header->layer == MAD_LAYER_I) {
1165 frame_duration = 384.0 / (double) header->samplerate;
1166 } else {
1167 int slots_per_frame;
1169 slots_per_frame = ((header->layer == MAD_LAYER_III)
1170 && !lsf_bit) ? 72 : 144;
1171 frame_duration = slots_per_frame * 8.0 / (double) header->samplerate;
1172 }
1173 abr = ((double) xbytes * 8.0) / ((double) xframes * frame_duration);
1174 lprintf ("abr: %d bps\n", abr);
1175 if (bitrate != NULL) {
1176 *bitrate = abr;
1177 }
1178 if (time != NULL) {
1179 *time = (double) xframes *frame_duration;
1181 lprintf ("stream_length: %d s, %d min %d s\n", *time,
1182 *time / 60, *time % 60);
1183 }
1184 } else {
1185 /* it's a stupid Xing header */
1186 lprintf ("not a Xing VBR file\n");
1187 }
1188 return 1;
1189 } else {
1190 lprintf ("Xing header not found\n");
1191 return 0;
1192 }
1193 }
1195 /* End of Xine code */
1197 /* internal function to check if the header has changed and thus the
1198 * caps need to be reset. Only call during normal mode, not resyncing */
1199 static void
1200 gst_mad_check_caps_reset (GstMad * mad)
1201 {
1202 guint nchannels;
1203 guint rate, old_rate = mad->rate;
1205 nchannels = MAD_NCHANNELS (&mad->frame.header);
1207 #if MAD_VERSION_MINOR <= 12
1208 rate = mad->header.sfreq;
1209 #else
1210 rate = mad->frame.header.samplerate;
1211 #endif
1213 /* rate and channels are not supposed to change in a continuous stream,
1214 * so check this first before doing anything */
1216 /* only set caps if they weren't already set for this continuous stream */
1217 if (mad->channels != nchannels || mad->rate != rate) {
1218 if (mad->caps_set) {
1219 GST_DEBUG
1220 ("Header changed from %d Hz/%d ch to %d Hz/%d ch, failed sync after seek ?",
1221 mad->rate, mad->channels, rate, nchannels);
1222 /* we're conservative on stream changes. However, our *initial* caps
1223 * might have been wrong as well - mad ain't perfect in syncing. So,
1224 * we count caps changes and change if we pass a limit treshold (3). */
1225 if (nchannels != mad->pending_channels || rate != mad->pending_rate) {
1226 mad->times_pending = 0;
1227 mad->pending_channels = nchannels;
1228 mad->pending_rate = rate;
1229 }
1230 if (++mad->times_pending < 3)
1231 return;
1232 }
1233 }
1234 gst_mad_update_info (mad);
1236 if (mad->channels != nchannels || mad->rate != rate) {
1237 GstCaps *caps;
1239 if (mad->stream.options & MAD_OPTION_HALFSAMPLERATE)
1240 rate >>= 1;
1242 /* FIXME see if peer can accept the caps */
1244 /* we set the caps even when the pad is not connected so they
1245 * can be gotten for streaminfo */
1246 caps = gst_caps_new_simple ("audio/x-raw-int",
1247 "endianness", G_TYPE_INT, G_BYTE_ORDER,
1248 "signed", G_TYPE_BOOLEAN, TRUE,
1249 "width", G_TYPE_INT, 32,
1250 "depth", G_TYPE_INT, 32,
1251 "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, nchannels, NULL);
1253 gst_pad_set_caps (mad->srcpad, caps);
1254 gst_caps_unref (caps);
1256 mad->caps_set = TRUE; /* set back to FALSE on discont */
1257 mad->channels = nchannels;
1258 mad->rate = rate;
1260 /* update sample count so we don't come up with crazy timestamps */
1261 if (mad->total_samples && old_rate) {
1262 mad->total_samples = mad->total_samples * rate / old_rate;
1263 }
1264 }
1265 }
1267 static GstFlowReturn
1268 gst_mad_chain (GstPad * pad, GstBuffer * buffer)
1269 {
1270 GstMad *mad;
1271 guint8 *data;
1272 glong size, tempsize;
1273 gboolean new_pts = FALSE;
1274 gboolean discont;
1275 GstClockTime timestamp;
1276 GstFlowReturn result = GST_FLOW_OK;
1278 mad = GST_MAD (GST_PAD_PARENT (pad));
1280 /* restarts happen on discontinuities, ie. seek, flush, PAUSED to PLAYING */
1281 if (gst_mad_check_restart (mad)) {
1282 mad->need_newsegment = TRUE;
1283 GST_DEBUG ("mad restarted");
1284 }
1286 /* take discont flag */
1287 discont = GST_BUFFER_IS_DISCONT (buffer);
1289 timestamp = GST_BUFFER_TIMESTAMP (buffer);
1290 GST_DEBUG ("mad in timestamp %" GST_TIME_FORMAT " duration:%" GST_TIME_FORMAT,
1291 GST_TIME_ARGS (timestamp), GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
1293 /* handle timestamps */
1294 if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
1295 /* if there is nothing left to process in our temporary buffer,
1296 * we can set this timestamp on the next outgoing buffer */
1297 if (mad->tempsize == 0) {
1298 /* we have to save the result here because we can't yet convert
1299 * the timestamp to a sample offset, as the samplerate might not
1300 * be known yet */
1301 mad->last_ts = timestamp;
1302 mad->base_byte_offset = GST_BUFFER_OFFSET (buffer);
1303 mad->bytes_consumed = 0;
1304 }
1305 /* else we need to finish the current partial frame with the old timestamp
1306 * and queue this timestamp for the next frame */
1307 else {
1308 new_pts = TRUE;
1309 }
1310 }
1311 GST_DEBUG ("last_ts %" GST_TIME_FORMAT, GST_TIME_ARGS (mad->last_ts));
1313 /* handle data */
1314 data = GST_BUFFER_DATA (buffer);
1315 size = GST_BUFFER_SIZE (buffer);
1317 tempsize = mad->tempsize;
1319 /* process the incoming buffer in chunks of maximum MAD_BUFFER_MDLEN bytes;
1320 * this is the upper limit on processable chunk sizes set by mad */
1321 while (size > 0) {
1322 gint tocopy;
1323 guchar *mad_input_buffer; /* convenience pointer to tempbuffer */
1325 if (mad->tempsize == 0 && discont) {
1326 mad->discont = TRUE;
1327 discont = FALSE;
1328 }
1329 tocopy =
1330 MIN (MAD_BUFFER_MDLEN, MIN (size,
1331 MAD_BUFFER_MDLEN * 3 - mad->tempsize));
1332 if (tocopy == 0) {
1333 GST_ELEMENT_ERROR (mad, STREAM, DECODE, (NULL),
1334 ("mad claims to need more data than %u bytes, we don't have that much",
1335 MAD_BUFFER_MDLEN * 3));
1336 result = GST_FLOW_ERROR;
1337 goto end;
1338 }
1340 /* append the chunk to process to our internal temporary buffer */
1341 GST_LOG ("tempbuffer size %ld, copying %d bytes from incoming buffer",
1342 mad->tempsize, tocopy);
1343 memcpy (mad->tempbuffer + mad->tempsize, data, tocopy);
1344 mad->tempsize += tocopy;
1346 /* update our incoming buffer's parameters to reflect this */
1347 size -= tocopy;
1348 data += tocopy;
1350 mad_input_buffer = mad->tempbuffer;
1352 /* while we have data we can consume it */
1353 while (mad->tempsize > 0) {
1354 gint consumed = 0;
1355 guint nsamples;
1356 guint64 time_offset = GST_CLOCK_TIME_NONE;
1357 guint64 time_duration = GST_CLOCK_TIME_NONE;
1358 unsigned char const *before_sync, *after_sync;
1359 gboolean goto_exit = FALSE;
1361 mad->in_error = FALSE;
1363 mad_stream_buffer (&mad->stream, mad_input_buffer, mad->tempsize);
1365 /* added separate header decoding to catch errors earlier, also fixes
1366 * some weird decoding errors... */
1367 GST_LOG ("decoding the header now");
1368 if (mad_header_decode (&mad->frame.header, &mad->stream) == -1) {
1369 if (mad->stream.error == MAD_ERROR_BUFLEN) {
1370 GST_LOG ("not enough data in tempbuffer (%ld), breaking to get more",
1371 mad->tempsize);
1372 break;
1373 } else {
1374 GST_WARNING ("mad_header_decode had an error: %s",
1375 mad_stream_errorstr (&mad->stream));
1376 }
1377 }
1379 GST_LOG ("decoding one frame now");
1381 if (mad_frame_decode (&mad->frame, &mad->stream) == -1) {
1382 GST_LOG ("got error %d", mad->stream.error);
1384 /* not enough data, need to wait for next buffer? */
1385 if (mad->stream.error == MAD_ERROR_BUFLEN) {
1386 if (mad->stream.next_frame == mad_input_buffer) {
1387 GST_LOG
1388 ("not enough data in tempbuffer (%ld), breaking to get more",
1389 mad->tempsize);
1390 break;
1391 } else {
1392 GST_LOG ("sync error, flushing unneeded data");
1393 goto next_no_samples;
1394 }
1395 } else if (mad->stream.error == MAD_ERROR_BADDATAPTR) {
1396 /* Flush data */
1397 goto next_no_samples;
1398 }
1399 /* we are in an error state */
1400 mad->in_error = TRUE;
1401 GST_WARNING ("mad_frame_decode had an error: %s",
1402 mad_stream_errorstr (&mad->stream));
1403 if (!MAD_RECOVERABLE (mad->stream.error)) {
1404 GST_ELEMENT_ERROR (mad, STREAM, DECODE, (NULL), (NULL));
1405 result = GST_FLOW_ERROR;
1406 goto end;
1407 } else if (mad->stream.error == MAD_ERROR_LOSTSYNC) {
1408 /* lost sync, force a resync */
1409 signed long tagsize;
1411 GST_INFO ("recoverable lost sync error");
1413 tagsize = id3_tag_query (mad->stream.this_frame,
1414 mad->stream.bufend - mad->stream.this_frame);
1416 if (tagsize > mad->tempsize) {
1417 GST_INFO ("mad: got partial id3 tag in buffer, skipping");
1418 } else if (tagsize > 0) {
1419 struct id3_tag *tag;
1420 id3_byte_t const *data;
1422 GST_INFO ("mad: got ID3 tag size %ld", tagsize);
1424 data = mad->stream.this_frame;
1426 /* mad has moved the pointer to the next frame over the start of the
1427 * id3 tags, so we need to flush one byte less than the tagsize */
1428 mad_stream_skip (&mad->stream, tagsize - 1);
1430 tag = id3_tag_parse (data, tagsize);
1431 if (tag) {
1432 GstTagList *list;
1434 list = gst_mad_id3_to_tag_list (tag);
1435 id3_tag_delete (tag);
1436 GST_DEBUG ("found tag");
1437 gst_element_post_message (GST_ELEMENT (mad),
1438 gst_message_new_tag (GST_OBJECT (mad),
1439 gst_tag_list_copy (list)));
1440 if (mad->tags) {
1441 gst_tag_list_insert (mad->tags, list, GST_TAG_MERGE_PREPEND);
1442 } else {
1443 mad->tags = gst_tag_list_copy (list);
1444 }
1445 if (mad->need_newsegment)
1446 mad->pending_events =
1447 g_list_append (mad->pending_events,
1448 gst_event_new_tag (list));
1449 else
1450 gst_pad_push_event (mad->srcpad, gst_event_new_tag (list));
1451 }
1452 }
1453 }
1455 mad_frame_mute (&mad->frame);
1456 mad_synth_mute (&mad->synth);
1457 before_sync = mad->stream.ptr.byte;
1458 if (mad_stream_sync (&mad->stream) != 0)
1459 GST_WARNING ("mad_stream_sync failed");
1460 after_sync = mad->stream.ptr.byte;
1461 /* a succesful resync should make us drop bytes as consumed, so
1462 calculate from the byte pointers before and after resync */
1463 consumed = after_sync - before_sync;
1464 GST_DEBUG ("resynchronization consumes %d bytes", consumed);
1465 GST_DEBUG ("synced to data: 0x%0x 0x%0x", *mad->stream.ptr.byte,
1466 *(mad->stream.ptr.byte + 1));
1468 mad_stream_sync (&mad->stream);
1469 /* recoverable errors pass */
1470 goto next_no_samples;
1471 }
1473 if (mad->check_for_xing) {
1474 int bitrate = 0, time = 0;
1475 GstTagList *list;
1476 int frame_len = mad->stream.next_frame - mad->stream.this_frame;
1478 mad->check_for_xing = FALSE;
1480 /* Assume Xing headers can only be the first frame in a mp3 file */
1481 if (mpg123_parse_xing_header (&mad->frame.header,
1482 mad->stream.this_frame, frame_len, &bitrate, &time)) {
1483 mad->xing_found = TRUE;
1484 list = gst_tag_list_new ();
1485 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1486 GST_TAG_DURATION, (gint64) time * 1000 * 1000 * 1000,
1487 GST_TAG_BITRATE, bitrate, NULL);
1488 gst_element_post_message (GST_ELEMENT (mad),
1489 gst_message_new_tag (GST_OBJECT (mad), gst_tag_list_copy (list)));
1491 if (mad->need_newsegment)
1492 mad->pending_events =
1493 g_list_append (mad->pending_events, gst_event_new_tag (list));
1494 else
1495 gst_pad_push_event (mad->srcpad, gst_event_new_tag (list));
1497 goto next_no_samples;
1498 }
1499 }
1501 /* if we're not resyncing/in error, check if caps need to be set again */
1502 if (!mad->in_error)
1503 gst_mad_check_caps_reset (mad);
1504 nsamples = MAD_NSBSAMPLES (&mad->frame.header) *
1505 (mad->stream.options & MAD_OPTION_HALFSAMPLERATE ? 16 : 32);
1507 if (mad->rate == 0) {
1508 g_warning ("mad->rate is 0; timestamps cannot be calculated");
1509 } else {
1510 /* if we have a pending timestamp, we can use it now to calculate the sample offset */
1511 if (GST_CLOCK_TIME_IS_VALID (mad->last_ts)) {
1512 GstFormat format = GST_FORMAT_DEFAULT;
1513 gint64 total;
1515 /* Convert incoming timestamp to a number of encoded samples */
1516 gst_pad_query_convert (mad->srcpad, GST_FORMAT_TIME, mad->last_ts,
1517 &format, &total);
1519 GST_DEBUG_OBJECT (mad, "calculated samples offset from ts is %"
1520 G_GUINT64_FORMAT " accumulated samples offset is %"
1521 G_GUINT64_FORMAT, total, mad->total_samples);
1523 /* We are using the incoming timestamps to generate the outgoing ones
1524 * if available. However some muxing formats are not precise enough
1525 * to allow us to generate a perfect stream. When converting the
1526 * timestamp to a number of encoded samples so far we are introducing
1527 * a lot of potential error compared to our accumulated number of
1528 * samples encoded. If the difference between those 2 numbers is
1529 * bigger than half a frame we then use the incoming timestamp
1530 * as a reference, otherwise we continue using our accumulated samples
1531 * counter */
1532 if (ABS (mad->total_samples - total) > nsamples / 2) {
1533 GST_DEBUG_OBJECT (mad, "difference is bigger than half a frame, "
1534 "using calculated samples offset %" G_GUINT64_FORMAT, total);
1535 /* Override our accumulated samples counter */
1536 mad->total_samples = total;
1537 /* We use that timestamp directly */
1538 time_offset = mad->last_ts;
1539 }
1541 mad->last_ts = GST_CLOCK_TIME_NONE;
1542 }
1544 if (!GST_CLOCK_TIME_IS_VALID (time_offset)) {
1545 time_offset = gst_util_uint64_scale_int (mad->total_samples,
1546 GST_SECOND, mad->rate);
1547 }
1548 /* Duration is next timestamp - this one to generate a continuous
1549 * stream */
1550 time_duration =
1551 gst_util_uint64_scale_int (mad->total_samples + nsamples,
1552 GST_SECOND, mad->rate) - time_offset;
1553 }
1555 #ifndef GST_DISABLE_INDEX
1556 if (mad->index) {
1557 guint64 x_bytes = mad->base_byte_offset + mad->bytes_consumed;
1559 gst_index_add_association (mad->index, mad->index_id, 0,
1560 GST_FORMAT_BYTES, x_bytes, GST_FORMAT_TIME, time_offset, NULL);
1561 }
1562 #endif
1564 if (mad->segment_start <= (time_offset ==
1565 GST_CLOCK_TIME_NONE ? 0 : time_offset)) {
1567 /* for sample accurate seeking, calculate how many samples
1568 to skip and send the remaining pcm samples */
1570 GstBuffer *outbuffer = NULL;
1571 gint32 *outdata;
1572 mad_fixed_t const *left_ch, *right_ch;
1574 if (mad->need_newsegment) {
1575 gint64 start = time_offset;
1577 GST_DEBUG ("Sending NEWSEGMENT event, start=%" GST_TIME_FORMAT,
1578 GST_TIME_ARGS (start));
1580 gst_segment_set_newsegment (&mad->segment, FALSE, 1.0,
1581 GST_FORMAT_TIME, start, GST_CLOCK_TIME_NONE, start);
1583 gst_pad_push_event (mad->srcpad,
1584 gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,
1585 start, GST_CLOCK_TIME_NONE, start));
1586 mad->need_newsegment = FALSE;
1587 }
1589 if (mad->pending_events) {
1590 GList *l;
1592 for (l = mad->pending_events; l != NULL; l = l->next) {
1593 gst_pad_push_event (mad->srcpad, GST_EVENT (l->data));
1594 }
1595 g_list_free (mad->pending_events);
1596 mad->pending_events = NULL;
1597 }
1599 /* will attach the caps to the buffer */
1600 result =
1601 gst_pad_alloc_buffer_and_set_caps (mad->srcpad, 0,
1602 nsamples * mad->channels * 4, GST_PAD_CAPS (mad->srcpad),
1603 &outbuffer);
1604 if (result != GST_FLOW_OK) {
1605 /* Head for the exit, dropping samples as we go */
1606 GST_LOG ("Skipping frame synthesis due to pad_alloc return value");
1607 goto_exit = TRUE;
1608 goto skip_frame;
1609 }
1611 mad_synth_frame (&mad->synth, &mad->frame);
1612 left_ch = mad->synth.pcm.samples[0];
1613 right_ch = mad->synth.pcm.samples[1];
1615 outdata = (gint32 *) GST_BUFFER_DATA (outbuffer);
1617 GST_DEBUG ("mad out timestamp %" GST_TIME_FORMAT " dur: %"
1618 GST_TIME_FORMAT, GST_TIME_ARGS (time_offset),
1619 GST_TIME_ARGS (time_duration));
1621 GST_BUFFER_TIMESTAMP (outbuffer) = time_offset;
1622 GST_BUFFER_DURATION (outbuffer) = time_duration;
1623 GST_BUFFER_OFFSET (outbuffer) = mad->total_samples;
1624 GST_BUFFER_OFFSET_END (outbuffer) = mad->total_samples + nsamples;
1626 /* output sample(s) in 16-bit signed native-endian PCM */
1627 if (mad->channels == 1) {
1628 gint count = nsamples;
1630 while (count--) {
1631 *outdata++ = scale (*left_ch++) & 0xffffffff;
1632 }
1633 } else {
1634 gint count = nsamples;
1636 while (count--) {
1637 *outdata++ = scale (*left_ch++) & 0xffffffff;
1638 *outdata++ = scale (*right_ch++) & 0xffffffff;
1639 }
1640 }
1642 if ((outbuffer = gst_audio_buffer_clip (outbuffer, &mad->segment,
1643 mad->rate, 4 * mad->channels))) {
1644 GST_LOG_OBJECT (mad,
1645 "pushing buffer, off=%" G_GUINT64_FORMAT ", ts=%" GST_TIME_FORMAT,
1646 GST_BUFFER_OFFSET (outbuffer),
1647 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuffer)));
1649 /* apply discont */
1650 if (mad->discont) {
1651 GST_BUFFER_FLAG_SET (outbuffer, GST_BUFFER_FLAG_DISCONT);
1652 mad->discont = FALSE;
1653 }
1655 mad->segment.last_stop = GST_BUFFER_TIMESTAMP (outbuffer);
1656 result = gst_pad_push (mad->srcpad, outbuffer);
1657 if (result != GST_FLOW_OK) {
1658 /* Head for the exit, dropping samples as we go */
1659 goto_exit = TRUE;
1660 }
1661 } else {
1662 GST_LOG_OBJECT (mad, "Dropping buffer");
1663 }
1664 }
1666 skip_frame:
1667 mad->total_samples += nsamples;
1669 /* we have a queued timestamp on the incoming buffer that we should
1670 * use for the next frame */
1671 if (new_pts && (mad->stream.next_frame - mad_input_buffer >= tempsize)) {
1672 new_pts = FALSE;
1673 mad->last_ts = timestamp;
1674 mad->base_byte_offset = GST_BUFFER_OFFSET (buffer);
1675 mad->bytes_consumed = 0;
1676 }
1677 tempsize = 0;
1678 if (discont) {
1679 mad->discont = TRUE;
1680 discont = FALSE;
1681 }
1683 if (gst_mad_check_restart (mad)) {
1684 goto end;
1685 }
1687 next_no_samples:
1688 /* figure out how many bytes mad consumed */
1689 /* if consumed is already set, it's from the resync higher up, so
1690 we need to use that value instead. Otherwise, recalculate from
1691 mad's consumption */
1692 if (consumed == 0)
1693 consumed = mad->stream.next_frame - mad_input_buffer;
1695 GST_LOG ("mad consumed %d bytes", consumed);
1696 /* move out pointer to where mad want the next data */
1697 mad_input_buffer += consumed;
1698 mad->tempsize -= consumed;
1699 mad->bytes_consumed += consumed;
1700 if (goto_exit == TRUE)
1701 goto end;
1702 }
1703 /* we only get here from breaks, tempsize never actually drops below 0 */
1704 memmove (mad->tempbuffer, mad_input_buffer, mad->tempsize);
1705 }
1706 result = GST_FLOW_OK;
1708 end:
1709 gst_buffer_unref (buffer);
1711 return result;
1712 }
1714 static GstStateChangeReturn
1715 gst_mad_change_state (GstElement * element, GstStateChange transition)
1716 {
1717 GstMad *mad;
1718 GstStateChangeReturn ret;
1720 mad = GST_MAD (element);
1722 switch (transition) {
1723 case GST_STATE_CHANGE_NULL_TO_READY:
1724 break;
1725 case GST_STATE_CHANGE_READY_TO_PAUSED:
1726 {
1727 guint options = 0;
1729 mad_stream_init (&mad->stream);
1730 mad_frame_init (&mad->frame);
1731 mad_synth_init (&mad->synth);
1732 mad->tempsize = 0;
1733 mad->discont = TRUE;
1734 mad->total_samples = 0;
1735 mad->rate = 0;
1736 mad->channels = 0;
1737 mad->caps_set = FALSE;
1738 mad->times_pending = mad->pending_rate = mad->pending_channels = 0;
1739 mad->vbr_average = 0;
1740 gst_segment_init (&mad->segment, GST_FORMAT_TIME);
1741 mad->new_header = TRUE;
1742 mad->framed = FALSE;
1743 mad->framecount = 0;
1744 mad->vbr_rate = 0;
1745 mad->frame.header.samplerate = 0;
1746 mad->last_ts = GST_CLOCK_TIME_NONE;
1747 if (mad->ignore_crc)
1748 options |= MAD_OPTION_IGNORECRC;
1749 if (mad->half)
1750 options |= MAD_OPTION_HALFSAMPLERATE;
1751 mad_stream_options (&mad->stream, options);
1752 break;
1753 }
1754 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1755 break;
1756 default:
1757 break;
1758 }
1760 ret = parent_class->change_state (element, transition);
1762 switch (transition) {
1763 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1764 break;
1765 case GST_STATE_CHANGE_PAUSED_TO_READY:
1766 mad_synth_finish (&mad->synth);
1767 mad_frame_finish (&mad->frame);
1768 mad_stream_finish (&mad->stream);
1769 mad->restart = TRUE;
1770 mad->check_for_xing = TRUE;
1771 if (mad->tags) {
1772 gst_tag_list_free (mad->tags);
1773 mad->tags = NULL;
1774 }
1775 break;
1776 case GST_STATE_CHANGE_READY_TO_NULL:
1777 break;
1778 default:
1779 break;
1780 }
1781 return ret;
1782 }
1784 /* id3 tag helper (FIXME: why does mad parse id3 tags at all? It shouldn't) */
1785 static GstTagList *
1786 gst_mad_id3_to_tag_list (const struct id3_tag *tag)
1787 {
1788 const struct id3_frame *frame;
1789 const id3_ucs4_t *ucs4;
1790 id3_utf8_t *utf8;
1791 GstTagList *tag_list;
1792 GType tag_type;
1793 guint i = 0;
1795 tag_list = gst_tag_list_new ();
1797 while ((frame = id3_tag_findframe (tag, NULL, i++)) != NULL) {
1798 const union id3_field *field;
1799 unsigned int nstrings, j;
1800 const gchar *tag_name;
1802 /* find me the function to query the frame id */
1803 gchar *id = g_strndup (frame->id, 5);
1805 tag_name = gst_tag_from_id3_tag (id);
1806 if (tag_name == NULL) {
1807 g_free (id);
1808 continue;
1809 }
1811 if (strcmp (id, "COMM") == 0) {
1812 if (frame->nfields < 4)
1813 continue;
1815 ucs4 = id3_field_getfullstring (&frame->fields[3]);
1816 g_assert (ucs4);
1818 utf8 = id3_ucs4_utf8duplicate (ucs4);
1819 if (utf8 == 0)
1820 continue;
1822 if (!g_utf8_validate ((char *) utf8, -1, NULL)) {
1823 GST_ERROR ("converted string is not valid utf-8");
1824 g_free (utf8);
1825 continue;
1826 }
1828 gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND,
1829 GST_TAG_COMMENT, utf8, NULL);
1831 g_free (utf8);
1832 continue;
1833 }
1835 if (frame->nfields < 2)
1836 continue;
1838 field = &frame->fields[1];
1839 nstrings = id3_field_getnstrings (field);
1841 for (j = 0; j < nstrings; ++j) {
1842 ucs4 = id3_field_getstrings (field, j);
1843 g_assert (ucs4);
1845 if (strcmp (id, ID3_FRAME_GENRE) == 0)
1846 ucs4 = id3_genre_name (ucs4);
1848 utf8 = id3_ucs4_utf8duplicate (ucs4);
1849 if (utf8 == 0)
1850 continue;
1852 if (!g_utf8_validate ((char *) utf8, -1, NULL)) {
1853 GST_ERROR ("converted string is not valid utf-8");
1854 free (utf8);
1855 continue;
1856 }
1858 tag_type = gst_tag_get_type (tag_name);
1860 /* be sure to add non-string tags here */
1861 switch (tag_type) {
1862 case G_TYPE_UINT:
1863 {
1864 guint tmp;
1865 gchar *check;
1867 tmp = strtoul ((char *) utf8, &check, 10);
1869 if (strcmp (tag_name, GST_TAG_DATE) == 0) {
1870 GDate *d;
1872 if (*check != '\0')
1873 break;
1874 if (tmp == 0)
1875 break;
1876 d = g_date_new_dmy (1, 1, tmp);
1877 tmp = g_date_get_julian (d);
1878 g_date_free (d);
1879 } else if (strcmp (tag_name, GST_TAG_TRACK_NUMBER) == 0) {
1880 if (*check == '/') {
1881 guint total;
1883 check++;
1884 total = strtoul (check, &check, 10);
1885 if (*check != '\0')
1886 break;
1888 gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND,
1889 GST_TAG_TRACK_COUNT, total, NULL);
1890 }
1891 } else if (strcmp (tag_name, GST_TAG_ALBUM_VOLUME_NUMBER) == 0) {
1892 if (*check == '/') {
1893 guint total;
1895 check++;
1896 total = strtoul (check, &check, 10);
1897 if (*check != '\0')
1898 break;
1900 gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND,
1901 GST_TAG_ALBUM_VOLUME_COUNT, total, NULL);
1902 }
1903 }
1905 if (*check != '\0')
1906 break;
1907 gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND, tag_name, tmp,
1908 NULL);
1909 break;
1910 }
1911 case G_TYPE_UINT64:
1912 {
1913 guint64 tmp;
1915 g_assert (strcmp (tag_name, GST_TAG_DURATION) == 0);
1916 tmp = strtoul ((char *) utf8, NULL, 10);
1917 if (tmp == 0) {
1918 break;
1919 }
1920 gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND,
1921 GST_TAG_DURATION, tmp * 1000 * 1000, NULL);
1922 break;
1923 }
1924 case G_TYPE_STRING:{
1925 gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND,
1926 tag_name, (const gchar *) utf8, NULL);
1927 break;
1928 }
1929 /* handles GST_TYPE_DATE and anything else */
1930 default:{
1931 GValue src = { 0, };
1932 GValue dest = { 0, };
1934 g_value_init (&src, G_TYPE_STRING);
1935 g_value_set_string (&src, (const gchar *) utf8);
1937 g_value_init (&dest, tag_type);
1938 if (g_value_transform (&src, &dest)) {
1939 gst_tag_list_add_values (tag_list, GST_TAG_MERGE_APPEND,
1940 tag_name, &dest, NULL);
1941 } else {
1942 GST_WARNING ("Failed to transform tag from string to type '%s'",
1943 g_type_name (tag_type));
1944 }
1945 g_value_unset (&src);
1946 g_value_unset (&dest);
1947 break;
1948 }
1949 }
1950 free (utf8);
1951 }
1952 g_free (id);
1953 }
1955 return tag_list;
1956 }
1958 /* plugin initialisation */
1960 static gboolean
1961 plugin_init (GstPlugin * plugin)
1962 {
1963 GST_DEBUG_CATEGORY_INIT (mad_debug, "mad", 0, "mad mp3 decoding");
1965 return gst_element_register (plugin, "mad", GST_RANK_SECONDARY,
1966 gst_mad_get_type ());
1967 }
1969 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
1970 GST_VERSION_MINOR,
1971 "mad",
1972 "mp3 decoding based on the mad library",
1973 plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);