Tizen 2.1 base
[profile/ivi/gst-plugins-ugly0.10.git] / gst / mpegaudioparse / gstmpegaudioparse.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  * Copyright (C) <2006-2007> Jan Schmidt <thaytan@mad.scientist.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /**
22  * SECTION:element-mp3parse
23  *
24  * Parses and frames mpeg1 audio streams. Provides seeking.
25  *
26  * <refsect2>
27  * <title>Example launch line</title>
28  * |[
29  * gst-launch filesrc location=test.mp3 ! mp3parse ! mad ! autoaudiosink
30  * ]|
31  * </refsect2>
32  */
33
34
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
38
39 #include <string.h>
40
41 #include "gstmpegaudioparse.h"
42
43 #include <gst/glib-compat-private.h>
44
45 GST_DEBUG_CATEGORY_STATIC (mp3parse_debug);
46 #define GST_CAT_DEFAULT mp3parse_debug
47
48 #define MP3_CHANNEL_MODE_UNKNOWN -1
49 #define MP3_CHANNEL_MODE_STEREO 0
50 #define MP3_CHANNEL_MODE_JOINT_STEREO 1
51 #define MP3_CHANNEL_MODE_DUAL_CHANNEL 2
52 #define MP3_CHANNEL_MODE_MONO 3
53
54 #define CRC_UNKNOWN -1
55 #define CRC_PROTECTED 0
56 #define CRC_NOT_PROTECTED 1
57
58 #define XING_FRAMES_FLAG     0x0001
59 #define XING_BYTES_FLAG      0x0002
60 #define XING_TOC_FLAG        0x0004
61 #define XING_VBR_SCALE_FLAG  0x0008
62
63 #ifndef GST_READ_UINT24_BE
64 #define GST_READ_UINT24_BE(p) (p[2] | (p[1] << 8) | (p[0] << 16))
65 #endif
66
67 /* Minimum number of consecutive, valid-looking frames to consider
68    for resyncing */
69 #define MIN_RESYNC_FRAMES 3
70
71 static inline MPEGAudioSeekEntry *
72 mpeg_audio_seek_entry_new (void)
73 {
74   return g_slice_new (MPEGAudioSeekEntry);
75 }
76
77 static inline void
78 mpeg_audio_seek_entry_free (MPEGAudioSeekEntry * entry)
79 {
80   g_slice_free (MPEGAudioSeekEntry, entry);
81 }
82
83 static GstStaticPadTemplate mp3_src_template = GST_STATIC_PAD_TEMPLATE ("src",
84     GST_PAD_SRC,
85     GST_PAD_ALWAYS,
86     GST_STATIC_CAPS ("audio/mpeg, "
87         "mpegversion = (int) 1, "
88         "layer = (int) [ 1, 3 ], "
89         "rate = (int) [ 8000, 48000 ], channels = (int) [ 1, 2 ],"
90         "parsed=(boolean) true")
91     );
92
93 static GstStaticPadTemplate mp3_sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
94     GST_PAD_SINK,
95     GST_PAD_ALWAYS,
96     GST_STATIC_CAPS ("audio/mpeg, mpegversion = (int) 1, parsed=(boolean)false")
97     );
98
99 /* GstMPEGAudioParse signals and args */
100 enum
101 {
102   /* FILL ME */
103   LAST_SIGNAL
104 };
105
106 enum
107 {
108   ARG_0,
109   ARG_SKIP,
110   ARG_BIT_RATE
111       /* FILL ME */
112 };
113
114
115 static gboolean gst_mp3parse_sink_event (GstPad * pad, GstEvent * event);
116 static GstFlowReturn gst_mp3parse_chain (GstPad * pad, GstBuffer * buffer);
117 static gboolean mp3parse_src_query (GstPad * pad, GstQuery * query);
118 static const GstQueryType *mp3parse_get_query_types (GstPad * pad);
119 static gboolean mp3parse_src_event (GstPad * pad, GstEvent * event);
120
121 static int head_check (GstMPEGAudioParse * mp3parse, unsigned long head);
122
123 static void gst_mp3parse_dispose (GObject * object);
124 static void gst_mp3parse_set_property (GObject * object, guint prop_id,
125     const GValue * value, GParamSpec * pspec);
126 static void gst_mp3parse_get_property (GObject * object, guint prop_id,
127     GValue * value, GParamSpec * pspec);
128 static GstStateChangeReturn gst_mp3parse_change_state (GstElement * element,
129     GstStateChange transition);
130 static GstFlowReturn
131 gst_mp3parse_handle_data (GstMPEGAudioParse * mp3parse, gboolean at_eos);
132
133 static gboolean mp3parse_bytepos_to_time (GstMPEGAudioParse * mp3parse,
134     gint64 bytepos, GstClockTime * ts, gboolean from_total_time);
135 static gboolean
136 mp3parse_total_bytes (GstMPEGAudioParse * mp3parse, gint64 * total);
137 static gboolean
138 mp3parse_total_time (GstMPEGAudioParse * mp3parse, GstClockTime * total);
139
140 GST_BOILERPLATE (GstMPEGAudioParse, gst_mp3parse, GstElement, GST_TYPE_ELEMENT);
141
142 #define GST_TYPE_MP3_CHANNEL_MODE (gst_mp3_channel_mode_get_type())
143
144 static const GEnumValue mp3_channel_mode[] = {
145   {MP3_CHANNEL_MODE_UNKNOWN, "Unknown", "unknown"},
146   {MP3_CHANNEL_MODE_MONO, "Mono", "mono"},
147   {MP3_CHANNEL_MODE_DUAL_CHANNEL, "Dual Channel", "dual-channel"},
148   {MP3_CHANNEL_MODE_JOINT_STEREO, "Joint Stereo", "joint-stereo"},
149   {MP3_CHANNEL_MODE_STEREO, "Stereo", "stereo"},
150   {0, NULL, NULL},
151 };
152
153 static GType
154 gst_mp3_channel_mode_get_type (void)
155 {
156   static GType mp3_channel_mode_type = 0;
157
158   if (!mp3_channel_mode_type) {
159     mp3_channel_mode_type =
160         g_enum_register_static ("GstMp3ChannelMode", mp3_channel_mode);
161   }
162   return mp3_channel_mode_type;
163 }
164
165 static const gchar *
166 gst_mp3_channel_mode_get_nick (gint mode)
167 {
168   guint i;
169   for (i = 0; i < G_N_ELEMENTS (mp3_channel_mode); i++) {
170     if (mp3_channel_mode[i].value == mode)
171       return mp3_channel_mode[i].value_nick;
172   }
173   return NULL;
174 }
175
176 static const guint mp3types_bitrates[2][3][16] = {
177   {
178         {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
179         {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
180         {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}
181       },
182   {
183         {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
184         {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
185         {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}
186       },
187 };
188
189 static const guint mp3types_freqs[3][3] = { {44100, 48000, 32000},
190 {22050, 24000, 16000},
191 {11025, 12000, 8000}
192 };
193
194 static inline guint
195 mp3_type_frame_length_from_header (GstMPEGAudioParse * mp3parse, guint32 header,
196     guint * put_version, guint * put_layer, guint * put_channels,
197     guint * put_bitrate, guint * put_samplerate, guint * put_mode,
198     guint * put_crc)
199 {
200   guint length;
201   gulong mode, samplerate, bitrate, layer, channels, padding, crc;
202   gulong version;
203   gint lsf, mpg25;
204
205   if (header & (1 << 20)) {
206     lsf = (header & (1 << 19)) ? 0 : 1;
207     mpg25 = 0;
208   } else {
209     lsf = 1;
210     mpg25 = 1;
211   }
212
213   version = 1 + lsf + mpg25;
214
215   layer = 4 - ((header >> 17) & 0x3);
216
217   crc = (header >> 16) & 0x1;
218
219   bitrate = (header >> 12) & 0xF;
220   bitrate = mp3types_bitrates[lsf][layer - 1][bitrate] * 1000;
221   /* The caller has ensured we have a valid header, so bitrate can't be
222      zero here. */
223   g_assert (bitrate != 0);
224
225   samplerate = (header >> 10) & 0x3;
226   samplerate = mp3types_freqs[lsf + mpg25][samplerate];
227
228   padding = (header >> 9) & 0x1;
229
230   mode = (header >> 6) & 0x3;
231   channels = (mode == 3) ? 1 : 2;
232
233   switch (layer) {
234     case 1:
235       length = 4 * ((bitrate * 12) / samplerate + padding);
236       break;
237     case 2:
238       length = (bitrate * 144) / samplerate + padding;
239       break;
240     default:
241     case 3:
242       length = (bitrate * 144) / (samplerate << lsf) + padding;
243       break;
244   }
245
246   GST_DEBUG_OBJECT (mp3parse, "Calculated mp3 frame length of %u bytes",
247       length);
248   GST_DEBUG_OBJECT (mp3parse, "samplerate = %lu, bitrate = %lu, version = %lu, "
249       "layer = %lu, channels = %lu, mode = %s", samplerate, bitrate, version,
250       layer, channels, gst_mp3_channel_mode_get_nick (mode));
251
252   if (put_version)
253     *put_version = version;
254   if (put_layer)
255     *put_layer = layer;
256   if (put_channels)
257     *put_channels = channels;
258   if (put_bitrate)
259     *put_bitrate = bitrate;
260   if (put_samplerate)
261     *put_samplerate = samplerate;
262   if (put_mode)
263     *put_mode = mode;
264   if (put_crc)
265     *put_crc = crc;
266
267   return length;
268 }
269
270 static GstCaps *
271 mp3_caps_create (guint version, guint layer, guint channels, guint samplerate)
272 {
273   GstCaps *new;
274
275   g_assert (version);
276   g_assert (layer);
277   g_assert (samplerate);
278   g_assert (channels);
279
280   new = gst_caps_new_simple ("audio/mpeg",
281       "mpegversion", G_TYPE_INT, 1,
282       "mpegaudioversion", G_TYPE_INT, version,
283       "layer", G_TYPE_INT, layer,
284       "rate", G_TYPE_INT, samplerate,
285       "channels", G_TYPE_INT, channels, "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
286
287   return new;
288 }
289
290 static void
291 gst_mp3parse_base_init (gpointer klass)
292 {
293   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
294
295   gst_element_class_add_static_pad_template (element_class,
296       &mp3_sink_template);
297   gst_element_class_add_static_pad_template (element_class,
298       &mp3_src_template);
299
300   GST_DEBUG_CATEGORY_INIT (mp3parse_debug, "mp3parse", 0, "MPEG Audio Parser");
301
302   gst_element_class_set_details_simple (element_class, "MPEG1 Audio Parser",
303       "Codec/Parser/Audio",
304       "Parses and frames mpeg1 audio streams (levels 1-3), provides seek",
305       "Jan Schmidt <thaytan@mad.scientist.com>,"
306       "Erik Walthinsen <omega@cse.ogi.edu>");
307 }
308
309 static void
310 gst_mp3parse_class_init (GstMPEGAudioParseClass * klass)
311 {
312   GObjectClass *gobject_class;
313   GstElementClass *gstelement_class;
314
315   gobject_class = (GObjectClass *) klass;
316   gstelement_class = (GstElementClass *) klass;
317
318   parent_class = g_type_class_peek_parent (klass);
319
320   gobject_class->set_property = gst_mp3parse_set_property;
321   gobject_class->get_property = gst_mp3parse_get_property;
322   gobject_class->dispose = gst_mp3parse_dispose;
323
324   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SKIP,
325       g_param_spec_int ("skip", "skip", "skip",
326           G_MININT, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
327   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BIT_RATE,
328       g_param_spec_int ("bitrate", "Bitrate", "Bit Rate",
329           G_MININT, G_MAXINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
330
331   gstelement_class->change_state = gst_mp3parse_change_state;
332
333 /* register tags */
334 #define GST_TAG_CRC    "has-crc"
335 #define GST_TAG_MODE     "channel-mode"
336
337   gst_tag_register (GST_TAG_CRC, GST_TAG_FLAG_META, G_TYPE_BOOLEAN,
338       "has crc", "Using CRC", NULL);
339   gst_tag_register (GST_TAG_MODE, GST_TAG_FLAG_ENCODED, G_TYPE_STRING,
340       "channel mode", "MPEG audio channel mode", NULL);
341
342   g_type_class_ref (GST_TYPE_MP3_CHANNEL_MODE);
343 }
344
345 static void
346 gst_mp3parse_reset (GstMPEGAudioParse * mp3parse)
347 {
348   mp3parse->skip = 0;
349   mp3parse->resyncing = TRUE;
350   mp3parse->next_ts = GST_CLOCK_TIME_NONE;
351   mp3parse->cur_offset = -1;
352
353   mp3parse->sync_offset = 0;
354   mp3parse->tracked_offset = 0;
355   mp3parse->pending_ts = GST_CLOCK_TIME_NONE;
356   mp3parse->pending_offset = -1;
357
358   gst_adapter_clear (mp3parse->adapter);
359
360   mp3parse->rate = mp3parse->channels = mp3parse->layer = -1;
361   mp3parse->version = 1;
362   mp3parse->max_bitreservoir = GST_CLOCK_TIME_NONE;
363
364   mp3parse->avg_bitrate = 0;
365   mp3parse->bitrate_sum = 0;
366   mp3parse->last_posted_bitrate = 0;
367   mp3parse->frame_count = 0;
368   mp3parse->sent_codec_tag = FALSE;
369
370   mp3parse->last_posted_crc = CRC_UNKNOWN;
371   mp3parse->last_posted_channel_mode = MP3_CHANNEL_MODE_UNKNOWN;
372
373   mp3parse->xing_flags = 0;
374   mp3parse->xing_bitrate = 0;
375   mp3parse->xing_frames = 0;
376   mp3parse->xing_total_time = 0;
377   mp3parse->xing_bytes = 0;
378   mp3parse->xing_vbr_scale = 0;
379   memset (mp3parse->xing_seek_table, 0, 100);
380   memset (mp3parse->xing_seek_table_inverse, 0, 256);
381
382   mp3parse->vbri_bitrate = 0;
383   mp3parse->vbri_frames = 0;
384   mp3parse->vbri_total_time = 0;
385   mp3parse->vbri_bytes = 0;
386   mp3parse->vbri_seek_points = 0;
387   g_free (mp3parse->vbri_seek_table);
388   mp3parse->vbri_seek_table = NULL;
389
390   if (mp3parse->seek_table) {
391     g_list_foreach (mp3parse->seek_table, (GFunc) mpeg_audio_seek_entry_free,
392         NULL);
393     g_list_free (mp3parse->seek_table);
394     mp3parse->seek_table = NULL;
395   }
396
397   g_mutex_lock (mp3parse->pending_seeks_lock);
398   if (mp3parse->pending_accurate_seeks) {
399     g_slist_foreach (mp3parse->pending_accurate_seeks, (GFunc) g_free, NULL);
400     g_slist_free (mp3parse->pending_accurate_seeks);
401     mp3parse->pending_accurate_seeks = NULL;
402   }
403   if (mp3parse->pending_nonaccurate_seeks) {
404     g_slist_foreach (mp3parse->pending_nonaccurate_seeks, (GFunc) g_free, NULL);
405     g_slist_free (mp3parse->pending_nonaccurate_seeks);
406     mp3parse->pending_nonaccurate_seeks = NULL;
407   }
408   g_mutex_unlock (mp3parse->pending_seeks_lock);
409
410   if (mp3parse->pending_segment) {
411     GstEvent **eventp = &mp3parse->pending_segment;
412
413     gst_event_replace (eventp, NULL);
414   }
415
416   mp3parse->exact_position = FALSE;
417   gst_segment_init (&mp3parse->segment, GST_FORMAT_TIME);
418 }
419
420 static void
421 gst_mp3parse_init (GstMPEGAudioParse * mp3parse, GstMPEGAudioParseClass * klass)
422 {
423   mp3parse->sinkpad =
424       gst_pad_new_from_static_template (&mp3_sink_template, "sink");
425   gst_pad_set_event_function (mp3parse->sinkpad, gst_mp3parse_sink_event);
426   gst_pad_set_chain_function (mp3parse->sinkpad, gst_mp3parse_chain);
427   gst_element_add_pad (GST_ELEMENT (mp3parse), mp3parse->sinkpad);
428
429   mp3parse->srcpad =
430       gst_pad_new_from_static_template (&mp3_src_template, "src");
431   gst_pad_use_fixed_caps (mp3parse->srcpad);
432   gst_pad_set_event_function (mp3parse->srcpad, mp3parse_src_event);
433   gst_pad_set_query_function (mp3parse->srcpad, mp3parse_src_query);
434   gst_pad_set_query_type_function (mp3parse->srcpad, mp3parse_get_query_types);
435   gst_element_add_pad (GST_ELEMENT (mp3parse), mp3parse->srcpad);
436
437   mp3parse->adapter = gst_adapter_new ();
438   mp3parse->pending_seeks_lock = g_mutex_new ();
439
440   gst_mp3parse_reset (mp3parse);
441 }
442
443 static void
444 gst_mp3parse_dispose (GObject * object)
445 {
446   GstMPEGAudioParse *mp3parse = GST_MP3PARSE (object);
447
448   gst_mp3parse_reset (mp3parse);
449
450   if (mp3parse->adapter) {
451     g_object_unref (mp3parse->adapter);
452     mp3parse->adapter = NULL;
453   }
454   g_mutex_free (mp3parse->pending_seeks_lock);
455   mp3parse->pending_seeks_lock = NULL;
456
457   g_list_foreach (mp3parse->pending_events, (GFunc) gst_mini_object_unref,
458       NULL);
459   g_list_free (mp3parse->pending_events);
460   mp3parse->pending_events = NULL;
461
462   G_OBJECT_CLASS (parent_class)->dispose (object);
463 }
464
465 static gboolean
466 gst_mp3parse_sink_event (GstPad * pad, GstEvent * event)
467 {
468   gboolean res = TRUE;
469   GstMPEGAudioParse *mp3parse;
470   GstEvent **eventp;
471
472   mp3parse = GST_MP3PARSE (gst_pad_get_parent (pad));
473
474   switch (GST_EVENT_TYPE (event)) {
475     case GST_EVENT_NEWSEGMENT:
476     {
477       gdouble rate, applied_rate;
478       GstFormat format;
479       gint64 start, stop, pos;
480       gboolean update;
481       MPEGAudioPendingAccurateSeek *seek = NULL;
482       GSList *node;
483
484       gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
485           &format, &start, &stop, &pos);
486
487       g_mutex_lock (mp3parse->pending_seeks_lock);
488       if (format == GST_FORMAT_BYTES && mp3parse->pending_accurate_seeks) {
489
490         for (node = mp3parse->pending_accurate_seeks; node; node = node->next) {
491           MPEGAudioPendingAccurateSeek *tmp = node->data;
492
493           if (tmp->upstream_start == pos) {
494             seek = tmp;
495             break;
496           }
497         }
498         if (seek) {
499           GstSegment *s = &seek->segment;
500
501           event =
502               gst_event_new_new_segment_full (FALSE, s->rate, s->applied_rate,
503               GST_FORMAT_TIME, s->start, s->stop, s->last_stop);
504
505           mp3parse->segment = seek->segment;
506
507           mp3parse->resyncing = FALSE;
508           mp3parse->cur_offset = pos;
509           mp3parse->next_ts = seek->timestamp_start;
510           mp3parse->pending_ts = GST_CLOCK_TIME_NONE;
511           mp3parse->tracked_offset = 0;
512           mp3parse->sync_offset = 0;
513
514           gst_event_parse_new_segment_full (event, &update, &rate,
515               &applied_rate, &format, &start, &stop, &pos);
516
517           GST_DEBUG_OBJECT (mp3parse,
518               "Pushing accurate newseg rate %g, applied rate %g, "
519               "format %d, start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT
520               ", pos %" G_GINT64_FORMAT, rate, applied_rate, format, start,
521               stop, pos);
522
523           g_free (seek);
524           mp3parse->pending_accurate_seeks =
525               g_slist_delete_link (mp3parse->pending_accurate_seeks, node);
526
527           g_mutex_unlock (mp3parse->pending_seeks_lock);
528           res = gst_pad_push_event (mp3parse->srcpad, event);
529
530           return res;
531         } else {
532           GST_WARNING_OBJECT (mp3parse,
533               "Accurate seek not possible, didn't get an appropiate upstream segment");
534         }
535       }
536       g_mutex_unlock (mp3parse->pending_seeks_lock);
537
538       mp3parse->exact_position = FALSE;
539
540       if (format == GST_FORMAT_BYTES) {
541         GstClockTime seg_start, seg_stop, seg_pos;
542
543         /* stop time is allowed to be open-ended, but not start & pos */
544         if (!mp3parse_bytepos_to_time (mp3parse, stop, &seg_stop, FALSE))
545           seg_stop = GST_CLOCK_TIME_NONE;
546         if (mp3parse_bytepos_to_time (mp3parse, start, &seg_start, FALSE) &&
547             mp3parse_bytepos_to_time (mp3parse, pos, &seg_pos, FALSE)) {
548           gst_event_unref (event);
549
550           /* search the pending nonaccurate seeks */
551           g_mutex_lock (mp3parse->pending_seeks_lock);
552           seek = NULL;
553           for (node = mp3parse->pending_nonaccurate_seeks; node;
554               node = node->next) {
555             MPEGAudioPendingAccurateSeek *tmp = node->data;
556
557             if (tmp->upstream_start == pos) {
558               seek = tmp;
559               break;
560             }
561           }
562
563           if (seek) {
564             if (seek->segment.stop == -1) {
565               /* corrent the segment end, because non-accurate seeks might make
566                * our streaming end earlier (see bug #603695) */
567               seg_stop = -1;
568             }
569             g_free (seek);
570             mp3parse->pending_nonaccurate_seeks =
571                 g_slist_delete_link (mp3parse->pending_nonaccurate_seeks, node);
572           }
573           g_mutex_unlock (mp3parse->pending_seeks_lock);
574
575           event = gst_event_new_new_segment_full (update, rate, applied_rate,
576               GST_FORMAT_TIME, seg_start, seg_stop, seg_pos);
577           format = GST_FORMAT_TIME;
578           GST_DEBUG_OBJECT (mp3parse, "Converted incoming segment to TIME. "
579               "start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT
580               ", pos = %" GST_TIME_FORMAT, GST_TIME_ARGS (seg_start),
581               GST_TIME_ARGS (seg_stop), GST_TIME_ARGS (seg_pos));
582         }
583       }
584
585       if (format != GST_FORMAT_TIME) {
586         /* Unknown incoming segment format. Output a default open-ended 
587          * TIME segment */
588         gst_event_unref (event);
589         event = gst_event_new_new_segment_full (update, rate, applied_rate,
590             GST_FORMAT_TIME, 0, GST_CLOCK_TIME_NONE, 0);
591       }
592
593       mp3parse->resyncing = TRUE;
594       mp3parse->cur_offset = -1;
595       mp3parse->next_ts = GST_CLOCK_TIME_NONE;
596       mp3parse->pending_ts = GST_CLOCK_TIME_NONE;
597       mp3parse->tracked_offset = 0;
598       mp3parse->sync_offset = 0;
599       /* also clear leftover data if clearing so much state */
600       gst_adapter_clear (mp3parse->adapter);
601
602       gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
603           &format, &start, &stop, &pos);
604       GST_DEBUG_OBJECT (mp3parse, "Pushing newseg rate %g, applied rate %g, "
605           "format %d, start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT
606           ", pos %" G_GINT64_FORMAT, rate, applied_rate, format, start, stop,
607           pos);
608
609       gst_segment_set_newsegment_full (&mp3parse->segment, update, rate,
610           applied_rate, format, start, stop, pos);
611
612       /* save the segment for later, right before we push a new buffer so that
613        * the caps are fixed and the next linked element can receive the segment. */
614       eventp = &mp3parse->pending_segment;
615       gst_event_replace (eventp, event);
616       gst_event_unref (event);
617       res = TRUE;
618       break;
619     }
620     case GST_EVENT_FLUSH_STOP:
621       /* Clear our adapter and set up for a new position */
622       gst_adapter_clear (mp3parse->adapter);
623       eventp = &mp3parse->pending_segment;
624       gst_event_replace (eventp, NULL);
625       res = gst_pad_push_event (mp3parse->srcpad, event);
626       break;
627     case GST_EVENT_EOS:
628       /* If we haven't processed any frames yet, then make sure we process
629          at least whatever's in our adapter */
630       if (mp3parse->frame_count == 0) {
631         gst_mp3parse_handle_data (mp3parse, TRUE);
632
633         /* If we STILL have zero frames processed, fire an error */
634         if (mp3parse->frame_count == 0) {
635           GST_ELEMENT_ERROR (mp3parse, STREAM, WRONG_TYPE,
636               ("No valid frames found before end of stream"), (NULL));
637         }
638       }
639       /* fall through */
640     default:
641       if (mp3parse->pending_segment &&
642           (GST_EVENT_TYPE (event) != GST_EVENT_EOS) &&
643           (GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_START)) {
644         /* Cache all events except EOS and the ones above if we have
645          * a pending segment */
646         mp3parse->pending_events =
647             g_list_append (mp3parse->pending_events, event);
648       } else {
649         res = gst_pad_push_event (mp3parse->srcpad, event);
650       }
651       break;
652   }
653
654   gst_object_unref (mp3parse);
655
656   return res;
657 }
658
659 static void
660 gst_mp3parse_add_index_entry (GstMPEGAudioParse * mp3parse, guint64 offset,
661     GstClockTime ts)
662 {
663   MPEGAudioSeekEntry *entry, *last;
664
665   if (G_LIKELY (mp3parse->seek_table != NULL)) {
666     last = mp3parse->seek_table->data;
667
668     if (last->byte >= offset)
669       return;
670
671     if (GST_CLOCK_DIFF (last->timestamp, ts) < mp3parse->idx_interval)
672       return;
673   }
674
675   entry = mpeg_audio_seek_entry_new ();
676   entry->byte = offset;
677   entry->timestamp = ts;
678   mp3parse->seek_table = g_list_prepend (mp3parse->seek_table, entry);
679
680   GST_LOG_OBJECT (mp3parse, "Adding index entry %" GST_TIME_FORMAT " @ offset "
681       "0x%08" G_GINT64_MODIFIER "x", GST_TIME_ARGS (ts), offset);
682 }
683
684 /* Prepare a buffer of the indicated size, timestamp it and output */
685 static GstFlowReturn
686 gst_mp3parse_emit_frame (GstMPEGAudioParse * mp3parse, guint size,
687     guint mode, guint crc)
688 {
689   GstBuffer *outbuf;
690   guint bitrate;
691   GstFlowReturn ret = GST_FLOW_OK;
692   GstClockTime push_start;
693   GstTagList *taglist;
694
695   outbuf = gst_adapter_take_buffer (mp3parse->adapter, size);
696
697   GST_BUFFER_DURATION (outbuf) =
698       gst_util_uint64_scale (GST_SECOND, mp3parse->spf, mp3parse->rate);
699
700   GST_BUFFER_OFFSET (outbuf) = mp3parse->cur_offset;
701
702   /* Check if we have a pending timestamp from an incoming buffer to apply
703    * here */
704   if (GST_CLOCK_TIME_IS_VALID (mp3parse->pending_ts)) {
705     if (mp3parse->tracked_offset >= mp3parse->pending_offset) {
706       /* If the incoming timestamp differs from our expected by more than 
707        * half a frame, then take it instead of our calculated timestamp.
708        * This avoids creating imperfect streams just because of 
709        * quantization in the container timestamping */
710       GstClockTimeDiff diff = mp3parse->next_ts - mp3parse->pending_ts;
711       GstClockTimeDiff thresh = GST_BUFFER_DURATION (outbuf) / 2;
712
713       if (diff < -thresh || diff > thresh) {
714         GST_DEBUG_OBJECT (mp3parse, "Updating next_ts from %" GST_TIME_FORMAT
715             " to pending ts %" GST_TIME_FORMAT
716             " at offset %" G_GINT64_FORMAT " (pending offset was %"
717             G_GINT64_FORMAT ")", GST_TIME_ARGS (mp3parse->next_ts),
718             GST_TIME_ARGS (mp3parse->pending_ts), mp3parse->tracked_offset,
719             mp3parse->pending_offset);
720         mp3parse->next_ts = mp3parse->pending_ts;
721       }
722       mp3parse->pending_ts = GST_CLOCK_TIME_NONE;
723     }
724   }
725
726   /* Decide what timestamp we're going to apply */
727   if (GST_CLOCK_TIME_IS_VALID (mp3parse->next_ts)) {
728     GST_BUFFER_TIMESTAMP (outbuf) = mp3parse->next_ts;
729   } else {
730     GstClockTime ts;
731
732     /* No timestamp yet, convert our offset to a timestamp if we can, or
733      * start at 0 */
734     if (mp3parse_bytepos_to_time (mp3parse, mp3parse->cur_offset, &ts, FALSE) &&
735         GST_CLOCK_TIME_IS_VALID (ts))
736       GST_BUFFER_TIMESTAMP (outbuf) = ts;
737     else {
738       GST_BUFFER_TIMESTAMP (outbuf) = 0;
739     }
740   }
741
742   if (GST_BUFFER_TIMESTAMP (outbuf) == 0)
743     mp3parse->exact_position = TRUE;
744
745   if (mp3parse->seekable &&
746       mp3parse->exact_position && GST_BUFFER_TIMESTAMP_IS_VALID (outbuf) &&
747       mp3parse->cur_offset != GST_BUFFER_OFFSET_NONE) {
748     gst_mp3parse_add_index_entry (mp3parse, mp3parse->cur_offset,
749         GST_BUFFER_TIMESTAMP (outbuf));
750   }
751
752   /* Update our byte offset tracking */
753   if (mp3parse->cur_offset != -1) {
754     mp3parse->cur_offset += size;
755   }
756   mp3parse->tracked_offset += size;
757
758   if (GST_BUFFER_TIMESTAMP_IS_VALID (outbuf))
759     mp3parse->next_ts =
760         GST_BUFFER_TIMESTAMP (outbuf) + GST_BUFFER_DURATION (outbuf);
761
762   gst_buffer_set_caps (outbuf, GST_PAD_CAPS (mp3parse->srcpad));
763
764   /* Post a bitrate tag if we need to before pushing the buffer */
765   if (mp3parse->xing_bitrate != 0)
766     bitrate = mp3parse->xing_bitrate;
767   else if (mp3parse->vbri_bitrate != 0)
768     bitrate = mp3parse->vbri_bitrate;
769   else
770     bitrate = mp3parse->avg_bitrate;
771
772   /* we will create a taglist (if any of the parameters has changed)
773    * to add the tags that changed */
774   taglist = NULL;
775   if ((mp3parse->last_posted_bitrate / 10000) != (bitrate / 10000)) {
776     taglist = gst_tag_list_new ();
777     mp3parse->last_posted_bitrate = bitrate;
778     gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_BITRATE,
779         mp3parse->last_posted_bitrate, NULL);
780
781     /* Post a new duration message if the average bitrate changes that much
782      * so applications can update their cached values
783      */
784     if ((mp3parse->xing_flags & XING_TOC_FLAG) == 0
785         && mp3parse->vbri_total_time == 0) {
786       gst_element_post_message (GST_ELEMENT (mp3parse),
787           gst_message_new_duration (GST_OBJECT (mp3parse), GST_FORMAT_TIME,
788               -1));
789     }
790   }
791
792   if (mp3parse->last_posted_crc != crc) {
793     gboolean using_crc;
794
795     if (!taglist) {
796       taglist = gst_tag_list_new ();
797     }
798     mp3parse->last_posted_crc = crc;
799     if (mp3parse->last_posted_crc == CRC_PROTECTED) {
800       using_crc = TRUE;
801     } else {
802       using_crc = FALSE;
803     }
804     gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_CRC,
805         using_crc, NULL);
806   }
807
808   if (mp3parse->last_posted_channel_mode != mode) {
809     if (!taglist) {
810       taglist = gst_tag_list_new ();
811     }
812     mp3parse->last_posted_channel_mode = mode;
813
814     gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_MODE,
815         gst_mp3_channel_mode_get_nick (mode), NULL);
816   }
817
818   /* if the taglist exists, we need to send it */
819   if (taglist) {
820     gst_element_found_tags_for_pad (GST_ELEMENT (mp3parse),
821         mp3parse->srcpad, taglist);
822   }
823
824   /* We start pushing 9 frames earlier (29 frames for MPEG2) than
825    * segment start to be able to decode the first frame we want.
826    * 9 (29) frames are the theoretical maximum of frames that contain
827    * data for the current frame (bit reservoir).
828    */
829   if (mp3parse->segment.start == 0) {
830     push_start = 0;
831   } else if (GST_CLOCK_TIME_IS_VALID (mp3parse->max_bitreservoir)) {
832     if (GST_CLOCK_TIME_IS_VALID (mp3parse->segment.start) &&
833         mp3parse->segment.start > mp3parse->max_bitreservoir)
834       push_start = mp3parse->segment.start - mp3parse->max_bitreservoir;
835     else
836       push_start = 0;
837   } else {
838     push_start = mp3parse->segment.start;
839   }
840
841   if (G_UNLIKELY ((GST_CLOCK_TIME_IS_VALID (push_start) &&
842               GST_BUFFER_TIMESTAMP_IS_VALID (outbuf) &&
843               GST_BUFFER_TIMESTAMP (outbuf) + GST_BUFFER_DURATION (outbuf)
844               < push_start))) {
845     GST_DEBUG_OBJECT (mp3parse,
846         "Buffer before configured segment range %" GST_TIME_FORMAT
847         " to %" GST_TIME_FORMAT ", dropping, timestamp %"
848         GST_TIME_FORMAT " duration %" GST_TIME_FORMAT
849         ", offset 0x%08" G_GINT64_MODIFIER "x", GST_TIME_ARGS (push_start),
850         GST_TIME_ARGS (mp3parse->segment.stop),
851         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
852         GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)),
853         GST_BUFFER_OFFSET (outbuf));
854
855     gst_buffer_unref (outbuf);
856     ret = GST_FLOW_OK;
857   } else if (G_UNLIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (outbuf) &&
858           GST_CLOCK_TIME_IS_VALID (mp3parse->segment.stop) &&
859           GST_BUFFER_TIMESTAMP (outbuf) >=
860           mp3parse->segment.stop + GST_BUFFER_DURATION (outbuf))) {
861     /* Some mp3 streams have an offset in the timestamps, for which we have to
862      * push the frame *after* the end position in order for the decoder to be
863      * able to decode everything up until the segment.stop position.
864      * That is the reason of the calculated offset */
865     GST_DEBUG_OBJECT (mp3parse,
866         "Buffer after configured segment range %" GST_TIME_FORMAT " to %"
867         GST_TIME_FORMAT ", returning GST_FLOW_UNEXPECTED, timestamp %"
868         GST_TIME_FORMAT " duration %" GST_TIME_FORMAT ", offset 0x%08"
869         G_GINT64_MODIFIER "x", GST_TIME_ARGS (push_start),
870         GST_TIME_ARGS (mp3parse->segment.stop),
871         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
872         GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)),
873         GST_BUFFER_OFFSET (outbuf));
874
875     gst_buffer_unref (outbuf);
876     ret = GST_FLOW_UNEXPECTED;
877   } else {
878     GST_DEBUG_OBJECT (mp3parse,
879         "pushing buffer of %d bytes, timestamp %" GST_TIME_FORMAT
880         ", offset 0x%08" G_GINT64_MODIFIER "x", size,
881         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
882         GST_BUFFER_OFFSET (outbuf));
883     mp3parse->segment.last_stop = GST_BUFFER_TIMESTAMP (outbuf);
884     /* push any pending segment now */
885     if (mp3parse->pending_segment) {
886       gst_pad_push_event (mp3parse->srcpad, mp3parse->pending_segment);
887       mp3parse->pending_segment = NULL;
888     }
889     if (mp3parse->pending_events) {
890       GList *l;
891
892       for (l = mp3parse->pending_events; l != NULL; l = l->next) {
893         gst_pad_push_event (mp3parse->srcpad, GST_EVENT (l->data));
894       }
895       g_list_free (mp3parse->pending_events);
896       mp3parse->pending_events = NULL;
897     }
898
899     /* set discont if needed */
900     if (mp3parse->discont) {
901       GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
902       mp3parse->discont = FALSE;
903     }
904
905     ret = gst_pad_push (mp3parse->srcpad, outbuf);
906   }
907
908   return ret;
909 }
910
911 static void
912 gst_mp3parse_handle_first_frame (GstMPEGAudioParse * mp3parse)
913 {
914   GstTagList *taglist;
915   gchar *codec;
916   const guint32 xing_id = 0x58696e67;   /* 'Xing' in hex */
917   const guint32 info_id = 0x496e666f;   /* 'Info' in hex - found in LAME CBR files */
918   const guint32 vbri_id = 0x56425249;   /* 'VBRI' in hex */
919
920   gint offset;
921
922   guint64 avail;
923   gint64 upstream_total_bytes = 0;
924   guint32 read_id;
925   const guint8 *data;
926
927   /* Output codec tag */
928   if (!mp3parse->sent_codec_tag) {
929     if (mp3parse->layer == 3) {
930       codec = g_strdup_printf ("MPEG %d Audio, Layer %d (MP3)",
931           mp3parse->version, mp3parse->layer);
932     } else {
933       codec = g_strdup_printf ("MPEG %d Audio, Layer %d",
934           mp3parse->version, mp3parse->layer);
935     }
936
937     taglist = gst_tag_list_new ();
938     gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE,
939         GST_TAG_AUDIO_CODEC, codec, NULL);
940     gst_element_found_tags_for_pad (GST_ELEMENT (mp3parse),
941         mp3parse->srcpad, taglist);
942     g_free (codec);
943
944     mp3parse->sent_codec_tag = TRUE;
945   }
946   /* end setting the tag */
947
948   /* Check first frame for Xing info */
949   if (mp3parse->version == 1) { /* MPEG-1 file */
950     if (mp3parse->channels == 1)
951       offset = 0x11;
952     else
953       offset = 0x20;
954   } else {                      /* MPEG-2 header */
955     if (mp3parse->channels == 1)
956       offset = 0x09;
957     else
958       offset = 0x11;
959   }
960   /* Skip the 4 bytes of the MP3 header too */
961   offset += 4;
962
963   /* Check if we have enough data to read the Xing header */
964   avail = gst_adapter_available (mp3parse->adapter);
965
966   if (avail < offset + 8)
967     return;
968
969   data = gst_adapter_peek (mp3parse->adapter, offset + 8);
970   if (data == NULL)
971     return;
972   /* The header starts at the provided offset */
973   data += offset;
974
975   /* obtain real upstream total bytes */
976   mp3parse_total_bytes (mp3parse, &upstream_total_bytes);
977
978   read_id = GST_READ_UINT32_BE (data);
979   if (read_id == xing_id || read_id == info_id) {
980     guint32 xing_flags;
981     guint bytes_needed = offset + 8;
982     gint64 total_bytes;
983     GstClockTime total_time;
984
985     GST_DEBUG_OBJECT (mp3parse, "Found Xing header marker 0x%x", xing_id);
986
987     /* Read 4 base bytes of flags, big-endian */
988     xing_flags = GST_READ_UINT32_BE (data + 4);
989     if (xing_flags & XING_FRAMES_FLAG)
990       bytes_needed += 4;
991     if (xing_flags & XING_BYTES_FLAG)
992       bytes_needed += 4;
993     if (xing_flags & XING_TOC_FLAG)
994       bytes_needed += 100;
995     if (xing_flags & XING_VBR_SCALE_FLAG)
996       bytes_needed += 4;
997     if (avail < bytes_needed) {
998       GST_DEBUG_OBJECT (mp3parse,
999           "Not enough data to read Xing header (need %d)", bytes_needed);
1000       return;
1001     }
1002
1003     GST_DEBUG_OBJECT (mp3parse, "Reading Xing header");
1004     mp3parse->xing_flags = xing_flags;
1005     data = gst_adapter_peek (mp3parse->adapter, bytes_needed);
1006     data += offset + 8;
1007
1008     if (xing_flags & XING_FRAMES_FLAG) {
1009       mp3parse->xing_frames = GST_READ_UINT32_BE (data);
1010       if (mp3parse->xing_frames == 0) {
1011         GST_WARNING_OBJECT (mp3parse,
1012             "Invalid number of frames in Xing header");
1013         mp3parse->xing_flags &= ~XING_FRAMES_FLAG;
1014       } else {
1015         mp3parse->xing_total_time = gst_util_uint64_scale (GST_SECOND,
1016             (guint64) (mp3parse->xing_frames) * (mp3parse->spf),
1017             mp3parse->rate);
1018       }
1019
1020       data += 4;
1021     } else {
1022       mp3parse->xing_frames = 0;
1023       mp3parse->xing_total_time = 0;
1024     }
1025
1026     if (xing_flags & XING_BYTES_FLAG) {
1027       mp3parse->xing_bytes = GST_READ_UINT32_BE (data);
1028       if (mp3parse->xing_bytes == 0) {
1029         GST_WARNING_OBJECT (mp3parse, "Invalid number of bytes in Xing header");
1030         mp3parse->xing_flags &= ~XING_BYTES_FLAG;
1031       }
1032
1033       data += 4;
1034     } else {
1035       mp3parse->xing_bytes = 0;
1036     }
1037
1038     /* If we know the upstream size and duration, compute the
1039      * total bitrate, rounded up to the nearest kbit/sec */
1040     if ((total_time = mp3parse->xing_total_time) &&
1041         (total_bytes = mp3parse->xing_bytes)) {
1042       mp3parse->xing_bitrate = gst_util_uint64_scale (total_bytes,
1043           8 * GST_SECOND, total_time);
1044       mp3parse->xing_bitrate += 500;
1045       mp3parse->xing_bitrate -= mp3parse->xing_bitrate % 1000;
1046     }
1047
1048     if (xing_flags & XING_TOC_FLAG) {
1049       int i, percent = 0;
1050       guchar *table = mp3parse->xing_seek_table;
1051       guchar old = 0, new;
1052       guint first;
1053
1054       first = data[0];
1055       GST_DEBUG_OBJECT (mp3parse,
1056           "Subtracting initial offset of %d bytes from Xing TOC", first);
1057
1058       /* xing seek table: percent time -> 1/256 bytepos */
1059       for (i = 0; i < 100; i++) {
1060         new = data[i] - first;
1061         if (old > new) {
1062           GST_WARNING_OBJECT (mp3parse, "Skipping broken Xing TOC");
1063           mp3parse->xing_flags &= ~XING_TOC_FLAG;
1064           goto skip_toc;
1065         }
1066         mp3parse->xing_seek_table[i] = old = new;
1067       }
1068
1069       /* build inverse table: 1/256 bytepos -> 1/100 percent time */
1070       for (i = 0; i < 256; i++) {
1071         while (percent < 99 && table[percent + 1] <= i)
1072           percent++;
1073
1074         if (table[percent] == i) {
1075           mp3parse->xing_seek_table_inverse[i] = percent * 100;
1076         } else if (table[percent] < i && percent < 99) {
1077           gdouble fa, fb, fx;
1078           gint a = percent, b = percent + 1;
1079
1080           fa = table[a];
1081           fb = table[b];
1082           fx = (b - a) / (fb - fa) * (i - fa) + a;
1083           mp3parse->xing_seek_table_inverse[i] = (guint16) (fx * 100);
1084         } else if (percent == 99) {
1085           gdouble fa, fb, fx;
1086           gint a = percent, b = 100;
1087
1088           fa = table[a];
1089           fb = 256.0;
1090           fx = (b - a) / (fb - fa) * (i - fa) + a;
1091           mp3parse->xing_seek_table_inverse[i] = (guint16) (fx * 100);
1092         }
1093       }
1094     skip_toc:
1095       data += 100;
1096     } else {
1097       memset (mp3parse->xing_seek_table, 0, 100);
1098       memset (mp3parse->xing_seek_table_inverse, 0, 256);
1099     }
1100
1101     if (xing_flags & XING_VBR_SCALE_FLAG) {
1102       mp3parse->xing_vbr_scale = GST_READ_UINT32_BE (data);
1103     } else
1104       mp3parse->xing_vbr_scale = 0;
1105
1106     GST_DEBUG_OBJECT (mp3parse, "Xing header reported %u frames, time %"
1107         GST_TIME_FORMAT ", %u bytes, vbr scale %u", mp3parse->xing_frames,
1108         GST_TIME_ARGS (mp3parse->xing_total_time), mp3parse->xing_bytes,
1109         mp3parse->xing_vbr_scale);
1110
1111     /* check for truncated file */
1112     if (upstream_total_bytes && mp3parse->xing_bytes &&
1113         mp3parse->xing_bytes * 0.8 > upstream_total_bytes) {
1114       GST_WARNING_OBJECT (mp3parse, "File appears to have been truncated; "
1115           "invalidating Xing header duration and size");
1116       mp3parse->xing_flags &= ~XING_BYTES_FLAG;
1117       mp3parse->xing_flags &= ~XING_FRAMES_FLAG;
1118     }
1119   } else if (read_id == vbri_id) {
1120     gint64 total_bytes, total_frames;
1121     GstClockTime total_time;
1122     guint16 nseek_points;
1123
1124     GST_DEBUG_OBJECT (mp3parse, "Found VBRI header marker 0x%x", vbri_id);
1125     if (avail < offset + 26) {
1126       GST_DEBUG_OBJECT (mp3parse,
1127           "Not enough data to read VBRI header (need %d)", offset + 26);
1128       return;
1129     }
1130
1131     GST_DEBUG_OBJECT (mp3parse, "Reading VBRI header");
1132     data = gst_adapter_peek (mp3parse->adapter, offset + 26);
1133     data += offset + 4;
1134
1135     if (GST_READ_UINT16_BE (data) != 0x0001) {
1136       GST_WARNING_OBJECT (mp3parse,
1137           "Unsupported VBRI version 0x%x", GST_READ_UINT16_BE (data));
1138       return;
1139     }
1140     data += 2;
1141
1142     /* Skip encoder delay */
1143     data += 2;
1144
1145     /* Skip quality */
1146     data += 2;
1147
1148     total_bytes = GST_READ_UINT32_BE (data);
1149     if (total_bytes != 0)
1150       mp3parse->vbri_bytes = total_bytes;
1151     data += 4;
1152
1153     total_frames = GST_READ_UINT32_BE (data);
1154     if (total_frames != 0) {
1155       mp3parse->vbri_frames = total_frames;
1156       mp3parse->vbri_total_time = gst_util_uint64_scale (GST_SECOND,
1157           (guint64) (mp3parse->vbri_frames) * (mp3parse->spf), mp3parse->rate);
1158     }
1159     data += 4;
1160
1161     /* If we know the upstream size and duration, compute the 
1162      * total bitrate, rounded up to the nearest kbit/sec */
1163     if ((total_time = mp3parse->vbri_total_time) &&
1164         (total_bytes = mp3parse->vbri_bytes)) {
1165       mp3parse->vbri_bitrate = gst_util_uint64_scale (total_bytes,
1166           8 * GST_SECOND, total_time);
1167       mp3parse->vbri_bitrate += 500;
1168       mp3parse->vbri_bitrate -= mp3parse->vbri_bitrate % 1000;
1169     }
1170
1171     nseek_points = GST_READ_UINT16_BE (data);
1172     data += 2;
1173
1174     if (nseek_points > 0) {
1175       guint scale, seek_bytes, seek_frames;
1176       gint i;
1177
1178       mp3parse->vbri_seek_points = nseek_points;
1179
1180       scale = GST_READ_UINT16_BE (data);
1181       data += 2;
1182
1183       seek_bytes = GST_READ_UINT16_BE (data);
1184       data += 2;
1185
1186       seek_frames = GST_READ_UINT16_BE (data);
1187
1188       if (scale == 0 || seek_bytes == 0 || seek_bytes > 4 || seek_frames == 0) {
1189         GST_WARNING_OBJECT (mp3parse, "Unsupported VBRI seek table");
1190         goto out_vbri;
1191       }
1192
1193       if (avail < offset + 26 + nseek_points * seek_bytes) {
1194         GST_WARNING_OBJECT (mp3parse,
1195             "Not enough data to read VBRI seek table (need %d)",
1196             offset + 26 + nseek_points * seek_bytes);
1197         goto out_vbri;
1198       }
1199
1200       if (seek_frames * nseek_points < total_frames - seek_frames ||
1201           seek_frames * nseek_points > total_frames + seek_frames) {
1202         GST_WARNING_OBJECT (mp3parse,
1203             "VBRI seek table doesn't cover the complete file");
1204         goto out_vbri;
1205       }
1206
1207       data =
1208           gst_adapter_peek (mp3parse->adapter,
1209           offset + 26 + nseek_points * seek_bytes);
1210       data += offset + 26;
1211
1212
1213       /* VBRI seek table: frame/seek_frames -> byte */
1214       mp3parse->vbri_seek_table = g_new (guint32, nseek_points);
1215       if (seek_bytes == 4)
1216         for (i = 0; i < nseek_points; i++) {
1217           mp3parse->vbri_seek_table[i] = GST_READ_UINT32_BE (data) * scale;
1218           data += 4;
1219       } else if (seek_bytes == 3)
1220         for (i = 0; i < nseek_points; i++) {
1221           mp3parse->vbri_seek_table[i] = GST_READ_UINT24_BE (data) * scale;
1222           data += 3;
1223       } else if (seek_bytes == 2)
1224         for (i = 0; i < nseek_points; i++) {
1225           mp3parse->vbri_seek_table[i] = GST_READ_UINT16_BE (data) * scale;
1226           data += 2;
1227       } else                    /* seek_bytes == 1 */
1228         for (i = 0; i < nseek_points; i++) {
1229           mp3parse->vbri_seek_table[i] = GST_READ_UINT8 (data) * scale;
1230           data += 1;
1231         }
1232     }
1233   out_vbri:
1234
1235     GST_DEBUG_OBJECT (mp3parse, "VBRI header reported %u frames, time %"
1236         GST_TIME_FORMAT ", bytes %u", mp3parse->vbri_frames,
1237         GST_TIME_ARGS (mp3parse->vbri_total_time), mp3parse->vbri_bytes);
1238
1239     /* check for truncated file */
1240     if (upstream_total_bytes && mp3parse->vbri_bytes &&
1241         mp3parse->vbri_bytes * 0.8 > upstream_total_bytes) {
1242       GST_WARNING_OBJECT (mp3parse, "File appears to have been truncated; "
1243           "invalidating VBRI header duration and size");
1244       mp3parse->vbri_valid = FALSE;
1245     } else {
1246       mp3parse->vbri_valid = TRUE;
1247     }
1248   } else {
1249     GST_DEBUG_OBJECT (mp3parse,
1250         "Xing, LAME or VBRI header not found in first frame");
1251   }
1252 }
1253
1254 static void
1255 gst_mp3parse_check_seekability (GstMPEGAudioParse * mp3parse)
1256 {
1257   GstQuery *query;
1258   gboolean seekable = FALSE;
1259   gint64 start = -1, stop = -1;
1260   guint idx_interval = 0;
1261
1262   query = gst_query_new_seeking (GST_FORMAT_BYTES);
1263   if (!gst_pad_peer_query (mp3parse->sinkpad, query)) {
1264     GST_DEBUG_OBJECT (mp3parse, "seeking query failed");
1265     goto done;
1266   }
1267
1268   gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
1269
1270   /* try harder to query upstream size if we didn't get it the first time */
1271   if (seekable && stop == -1) {
1272     GstFormat fmt = GST_FORMAT_BYTES;
1273
1274     GST_DEBUG_OBJECT (mp3parse, "doing duration query to fix up unset stop");
1275     gst_pad_query_peer_duration (mp3parse->sinkpad, &fmt, &stop);
1276   }
1277
1278   /* if upstream doesn't know the size, it's likely that it's not seekable in
1279    * practice even if it technically may be seekable */
1280   if (seekable && (start != 0 || stop <= start)) {
1281     GST_DEBUG_OBJECT (mp3parse, "seekable but unknown start/stop -> disable");
1282     seekable = FALSE;
1283   }
1284
1285   /* let's not put every single frame into our index */
1286   if (seekable) {
1287     if (stop < 10 * 1024 * 1024)
1288       idx_interval = 100;
1289     else if (stop < 100 * 1024 * 1024)
1290       idx_interval = 500;
1291     else
1292       idx_interval = 1000;
1293   }
1294
1295 done:
1296
1297   GST_INFO_OBJECT (mp3parse, "seekable: %d (%" G_GUINT64_FORMAT " - %"
1298       G_GUINT64_FORMAT ")", seekable, start, stop);
1299   mp3parse->seekable = seekable;
1300
1301   GST_INFO_OBJECT (mp3parse, "idx_interval: %ums", idx_interval);
1302   mp3parse->idx_interval = idx_interval * GST_MSECOND;
1303
1304   gst_query_unref (query);
1305 }
1306
1307 /* Flush some number of bytes and update tracked offsets */
1308 static void
1309 gst_mp3parse_flush_bytes (GstMPEGAudioParse * mp3parse, int bytes)
1310 {
1311   gst_adapter_flush (mp3parse->adapter, bytes);
1312   if (mp3parse->cur_offset != -1)
1313     mp3parse->cur_offset += bytes;
1314   mp3parse->tracked_offset += bytes;
1315 }
1316
1317 /* Perform extended validation to check that subsequent headers match
1318    the first header given here in important characteristics, to avoid
1319    false sync. We look for a minimum of MIN_RESYNC_FRAMES consecutive
1320    frames to match their major characteristics.
1321
1322    If at_eos is set to TRUE, we just check that we don't find any invalid
1323    frames in whatever data is available, rather than requiring a full
1324    MIN_RESYNC_FRAMES of data.
1325
1326    Returns TRUE if we've seen enough data to validate or reject the frame.
1327    If TRUE is returned, then *valid contains TRUE if it validated, or false
1328    if we decided it was false sync.
1329  */
1330 static gboolean
1331 gst_mp3parse_validate_extended (GstMPEGAudioParse * mp3parse, guint32 header,
1332     int bpf, gboolean at_eos, gboolean * valid)
1333 {
1334   guint32 next_header;
1335   const guint8 *data;
1336   guint available;
1337   int frames_found = 1;
1338   int offset = bpf;
1339
1340   while (frames_found < MIN_RESYNC_FRAMES) {
1341     /* Check if we have enough data for all these frames, plus the next
1342        frame header. */
1343     available = gst_adapter_available (mp3parse->adapter);
1344     if (available < offset + 4) {
1345       if (at_eos) {
1346         /* Running out of data at EOS is fine; just accept it */
1347         *valid = TRUE;
1348         return TRUE;
1349       } else {
1350         return FALSE;
1351       }
1352     }
1353
1354     data = gst_adapter_peek (mp3parse->adapter, offset + 4);
1355     next_header = GST_READ_UINT32_BE (data + offset);
1356     GST_DEBUG_OBJECT (mp3parse, "At %d: header=%08X, header2=%08X, bpf=%d",
1357         offset, (unsigned int) header, (unsigned int) next_header, bpf);
1358
1359 /* mask the bits which are allowed to differ between frames */
1360 #define HDRMASK ~((0xF << 12)  /* bitrate */ | \
1361                   (0x1 <<  9)  /* padding */ | \
1362                   (0xf <<  4)  /* mode|mode extension */ | \
1363                   (0xf))        /* copyright|emphasis */
1364
1365     if ((next_header & HDRMASK) != (header & HDRMASK)) {
1366       /* If any of the unmasked bits don't match, then it's not valid */
1367       GST_DEBUG_OBJECT (mp3parse, "next header doesn't match "
1368           "(header=%08X (%08X), header2=%08X (%08X), bpf=%d)",
1369           (guint) header, (guint) header & HDRMASK, (guint) next_header,
1370           (guint) next_header & HDRMASK, bpf);
1371       *valid = FALSE;
1372       return TRUE;
1373     } else if ((((next_header >> 12) & 0xf) == 0) ||
1374         (((next_header >> 12) & 0xf) == 0xf)) {
1375       /* The essential parts were the same, but the bitrate held an
1376          invalid value - also reject */
1377       GST_DEBUG_OBJECT (mp3parse, "next header invalid (bitrate)");
1378       *valid = FALSE;
1379       return TRUE;
1380     }
1381
1382     bpf = mp3_type_frame_length_from_header (mp3parse, next_header,
1383         NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1384
1385     offset += bpf;
1386     frames_found++;
1387   }
1388
1389   *valid = TRUE;
1390   return TRUE;
1391 }
1392
1393 static GstFlowReturn
1394 gst_mp3parse_handle_data (GstMPEGAudioParse * mp3parse, gboolean at_eos)
1395 {
1396   GstFlowReturn flow = GST_FLOW_OK;
1397   const guchar *data;
1398   guint32 header;
1399   int bpf;
1400   guint available;
1401   guint bitrate, layer, rate, channels, version, mode, crc;
1402   gboolean caps_change;
1403
1404   /* while we still have at least 4 bytes (for the header) available */
1405   while (gst_adapter_available (mp3parse->adapter) >= 4) {
1406     /* Get the header bytes, check if they're potentially valid */
1407     data = gst_adapter_peek (mp3parse->adapter, 4);
1408     header = GST_READ_UINT32_BE (data);
1409
1410     if (!head_check (mp3parse, header)) {
1411       /* Not a valid MP3 header; we start looking forward byte-by-byte trying to
1412          find a place to resync */
1413       if (!mp3parse->resyncing)
1414         mp3parse->sync_offset = mp3parse->tracked_offset;
1415       mp3parse->resyncing = TRUE;
1416       gst_mp3parse_flush_bytes (mp3parse, 1);
1417       GST_DEBUG_OBJECT (mp3parse, "wrong header, skipping byte");
1418       continue;
1419     }
1420
1421     /* We have a potentially valid header.
1422        If this is just a normal 'next frame', we go ahead and output it.
1423
1424        However, sometimes, we do additional validation to ensure we haven't
1425        got false sync (common with mp3 due to the short sync word).
1426        The additional validation requires that we find several consecutive mp3
1427        frames with the same major parameters, or reach EOS with a smaller
1428        number of valid-looking frames.
1429
1430        We do this if:
1431        - This is the very first frame we've processed
1432        - We're resyncing after a non-accurate seek, or after losing sync
1433        due to invalid data.
1434        - The format of the stream changes in a major way (number of channels,
1435        sample rate, layer, or mpeg version).
1436      */
1437     available = gst_adapter_available (mp3parse->adapter);
1438
1439     if (G_UNLIKELY (mp3parse->resyncing &&
1440             mp3parse->tracked_offset - mp3parse->sync_offset > 2 * 1024 * 1024))
1441       goto sync_failure;
1442
1443     bpf = mp3_type_frame_length_from_header (mp3parse, header,
1444         &version, &layer, &channels, &bitrate, &rate, &mode, &crc);
1445     g_assert (bpf != 0);
1446
1447     if (channels != mp3parse->channels ||
1448         rate != mp3parse->rate || layer != mp3parse->layer ||
1449         version != mp3parse->version)
1450       caps_change = TRUE;
1451     else
1452       caps_change = FALSE;
1453
1454     if (mp3parse->resyncing || caps_change) {
1455       gboolean valid;
1456       if (!gst_mp3parse_validate_extended (mp3parse, header, bpf, at_eos,
1457               &valid)) {
1458         /* Not enough data to validate; wait for more */
1459         break;
1460       }
1461
1462       if (!valid) {
1463         /* Extended validation failed; we probably got false sync.
1464            Continue searching from the next byte in the stream */
1465         if (!mp3parse->resyncing)
1466           mp3parse->sync_offset = mp3parse->tracked_offset;
1467         mp3parse->resyncing = TRUE;
1468         gst_mp3parse_flush_bytes (mp3parse, 1);
1469         continue;
1470       }
1471     }
1472
1473     /* if we don't have the whole frame... */
1474     if (available < bpf) {
1475       GST_DEBUG_OBJECT (mp3parse, "insufficient data available, need "
1476           "%d bytes, have %d", bpf, available);
1477       break;
1478     }
1479
1480     if (caps_change) {
1481       GstCaps *caps;
1482
1483       caps = mp3_caps_create (version, layer, channels, rate);
1484       gst_pad_set_caps (mp3parse->srcpad, caps);
1485       gst_caps_unref (caps);
1486
1487       mp3parse->channels = channels;
1488       mp3parse->rate = rate;
1489
1490       mp3parse->layer = layer;
1491       mp3parse->version = version;
1492
1493       /* see http://www.codeproject.com/audio/MPEGAudioInfo.asp */
1494       if (mp3parse->layer == 1)
1495         mp3parse->spf = 384;
1496       else if (mp3parse->layer == 2)
1497         mp3parse->spf = 1152;
1498       else if (mp3parse->version == 1) {
1499         mp3parse->spf = 1152;
1500       } else {
1501         /* MPEG-2 or "2.5" */
1502         mp3parse->spf = 576;
1503       }
1504
1505       mp3parse->max_bitreservoir = gst_util_uint64_scale (GST_SECOND,
1506           ((version == 1) ? 10 : 30) * mp3parse->spf, mp3parse->rate);
1507     }
1508
1509     mp3parse->bit_rate = bitrate;
1510
1511     /* Check the first frame for a Xing header to get our total length */
1512     if (mp3parse->frame_count == 0) {
1513       /* For the first frame in the file, look for a Xing frame after 
1514        * the header, and output a codec tag */
1515       gst_mp3parse_handle_first_frame (mp3parse);
1516
1517       /* Check if we're seekable */
1518       gst_mp3parse_check_seekability (mp3parse);
1519     }
1520
1521     /* Update VBR stats */
1522     mp3parse->bitrate_sum += mp3parse->bit_rate;
1523     mp3parse->frame_count++;
1524     /* Compute the average bitrate, rounded up to the nearest 1000 bits */
1525     mp3parse->avg_bitrate =
1526         (mp3parse->bitrate_sum / mp3parse->frame_count + 500);
1527     mp3parse->avg_bitrate -= mp3parse->avg_bitrate % 1000;
1528
1529     if (!mp3parse->skip) {
1530       mp3parse->resyncing = FALSE;
1531       flow = gst_mp3parse_emit_frame (mp3parse, bpf, mode, crc);
1532       if (flow != GST_FLOW_OK)
1533         break;
1534     } else {
1535       GST_DEBUG_OBJECT (mp3parse, "skipping buffer of %d bytes", bpf);
1536       gst_mp3parse_flush_bytes (mp3parse, bpf);
1537       mp3parse->skip--;
1538     }
1539   }
1540
1541   return flow;
1542
1543   /* ERRORS */
1544 sync_failure:
1545   {
1546     GST_ELEMENT_ERROR (mp3parse, STREAM, DECODE,
1547         ("Failed to parse stream"), (NULL));
1548     return GST_FLOW_ERROR;
1549   }
1550 }
1551
1552 static GstFlowReturn
1553 gst_mp3parse_chain (GstPad * pad, GstBuffer * buf)
1554 {
1555   GstMPEGAudioParse *mp3parse;
1556   GstClockTime timestamp;
1557
1558   mp3parse = GST_MP3PARSE (GST_PAD_PARENT (pad));
1559
1560   GST_LOG_OBJECT (mp3parse, "buffer of %d bytes", GST_BUFFER_SIZE (buf));
1561
1562   timestamp = GST_BUFFER_TIMESTAMP (buf);
1563
1564   mp3parse->discont |= GST_BUFFER_IS_DISCONT (buf);
1565
1566   /* If we don't yet have a next timestamp, save it and the incoming offset
1567    * so we can apply it to the right outgoing buffer */
1568   if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
1569     gint64 avail = gst_adapter_available (mp3parse->adapter);
1570
1571     mp3parse->pending_ts = timestamp;
1572     mp3parse->pending_offset = mp3parse->tracked_offset + avail;
1573
1574     /* If we have no data pending and the next timestamp is
1575      * invalid we can use the upstream timestamp for the next frame.
1576      *
1577      * This will give us a timestamp if we're resyncing and upstream
1578      * gave us -1 as offset. */
1579     if (avail == 0 && !GST_CLOCK_TIME_IS_VALID (mp3parse->next_ts))
1580       mp3parse->next_ts = timestamp;
1581
1582     GST_LOG_OBJECT (mp3parse, "Have pending ts %" GST_TIME_FORMAT
1583         " to apply in %" G_GINT64_FORMAT " bytes (@ off %" G_GINT64_FORMAT ")",
1584         GST_TIME_ARGS (mp3parse->pending_ts), avail, mp3parse->pending_offset);
1585   }
1586
1587   /* Update the cur_offset we'll apply to outgoing buffers */
1588   if (mp3parse->cur_offset == -1 && GST_BUFFER_OFFSET (buf) != -1)
1589     mp3parse->cur_offset = GST_BUFFER_OFFSET (buf);
1590
1591   /* And add the data to the pool */
1592   gst_adapter_push (mp3parse->adapter, buf);
1593
1594   return gst_mp3parse_handle_data (mp3parse, FALSE);
1595 }
1596
1597 static gboolean
1598 head_check (GstMPEGAudioParse * mp3parse, unsigned long head)
1599 {
1600   GST_DEBUG_OBJECT (mp3parse, "checking mp3 header 0x%08lx", head);
1601   /* if it's not a valid sync */
1602   if ((head & 0xffe00000) != 0xffe00000) {
1603     GST_WARNING_OBJECT (mp3parse, "invalid sync");
1604     return FALSE;
1605   }
1606   /* if it's an invalid MPEG version */
1607   if (((head >> 19) & 3) == 0x1) {
1608     GST_WARNING_OBJECT (mp3parse, "invalid MPEG version: 0x%lx",
1609         (head >> 19) & 3);
1610     return FALSE;
1611   }
1612   /* if it's an invalid layer */
1613   if (!((head >> 17) & 3)) {
1614     GST_WARNING_OBJECT (mp3parse, "invalid layer: 0x%lx", (head >> 17) & 3);
1615     return FALSE;
1616   }
1617   /* if it's an invalid bitrate */
1618   if (((head >> 12) & 0xf) == 0x0) {
1619     GST_WARNING_OBJECT (mp3parse, "invalid bitrate: 0x%lx."
1620         "Free format files are not supported yet", (head >> 12) & 0xf);
1621     return FALSE;
1622   }
1623   if (((head >> 12) & 0xf) == 0xf) {
1624     GST_WARNING_OBJECT (mp3parse, "invalid bitrate: 0x%lx", (head >> 12) & 0xf);
1625     return FALSE;
1626   }
1627   /* if it's an invalid samplerate */
1628   if (((head >> 10) & 0x3) == 0x3) {
1629     GST_WARNING_OBJECT (mp3parse, "invalid samplerate: 0x%lx",
1630         (head >> 10) & 0x3);
1631     return FALSE;
1632   }
1633
1634   if ((head & 0x3) == 0x2) {
1635     /* Ignore this as there are some files with emphasis 0x2 that can
1636      * be played fine. See BGO #537235 */
1637     GST_WARNING_OBJECT (mp3parse, "invalid emphasis: 0x%lx", head & 0x3);
1638   }
1639
1640   return TRUE;
1641 }
1642
1643 static void
1644 gst_mp3parse_set_property (GObject * object, guint prop_id,
1645     const GValue * value, GParamSpec * pspec)
1646 {
1647   GstMPEGAudioParse *src;
1648
1649   src = GST_MP3PARSE (object);
1650
1651   switch (prop_id) {
1652     case ARG_SKIP:
1653       src->skip = g_value_get_int (value);
1654       break;
1655     default:
1656       break;
1657   }
1658 }
1659
1660 static void
1661 gst_mp3parse_get_property (GObject * object, guint prop_id, GValue * value,
1662     GParamSpec * pspec)
1663 {
1664   GstMPEGAudioParse *src;
1665
1666   src = GST_MP3PARSE (object);
1667
1668   switch (prop_id) {
1669     case ARG_SKIP:
1670       g_value_set_int (value, src->skip);
1671       break;
1672     case ARG_BIT_RATE:
1673       g_value_set_int (value, src->bit_rate * 1000);
1674       break;
1675     default:
1676       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1677       break;
1678   }
1679 }
1680
1681 static GstStateChangeReturn
1682 gst_mp3parse_change_state (GstElement * element, GstStateChange transition)
1683 {
1684   GstMPEGAudioParse *mp3parse;
1685   GstStateChangeReturn result;
1686
1687   mp3parse = GST_MP3PARSE (element);
1688
1689   result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1690
1691   switch (transition) {
1692     case GST_STATE_CHANGE_PAUSED_TO_READY:
1693       gst_mp3parse_reset (mp3parse);
1694       break;
1695     default:
1696       break;
1697   }
1698
1699   return result;
1700 }
1701
1702 static gboolean
1703 mp3parse_total_bytes (GstMPEGAudioParse * mp3parse, gint64 * total)
1704 {
1705   GstFormat fmt = GST_FORMAT_BYTES;
1706
1707   if (gst_pad_query_peer_duration (mp3parse->sinkpad, &fmt, total))
1708     return TRUE;
1709
1710   if (mp3parse->xing_flags & XING_BYTES_FLAG) {
1711     *total = mp3parse->xing_bytes;
1712     return TRUE;
1713   }
1714
1715   if (mp3parse->vbri_bytes != 0 && mp3parse->vbri_valid) {
1716     *total = mp3parse->vbri_bytes;
1717     return TRUE;
1718   }
1719
1720   return FALSE;
1721 }
1722
1723 static gboolean
1724 mp3parse_total_time (GstMPEGAudioParse * mp3parse, GstClockTime * total)
1725 {
1726   gint64 total_bytes;
1727
1728   *total = GST_CLOCK_TIME_NONE;
1729
1730   if (mp3parse->xing_flags & XING_FRAMES_FLAG) {
1731     *total = mp3parse->xing_total_time;
1732     return TRUE;
1733   }
1734
1735   if (mp3parse->vbri_total_time != 0 && mp3parse->vbri_valid) {
1736     *total = mp3parse->vbri_total_time;
1737     return TRUE;
1738   }
1739
1740   /* Calculate time from the measured bitrate */
1741   if (!mp3parse_total_bytes (mp3parse, &total_bytes))
1742     return FALSE;
1743
1744   if (total_bytes != -1
1745       && !mp3parse_bytepos_to_time (mp3parse, total_bytes, total, TRUE))
1746     return FALSE;
1747
1748   return TRUE;
1749 }
1750
1751 /* Convert a timestamp to the file position required to start decoding that
1752  * timestamp. For now, this just uses the avg bitrate. Later, use an 
1753  * incrementally accumulated seek table */
1754 static gboolean
1755 mp3parse_time_to_bytepos (GstMPEGAudioParse * mp3parse, GstClockTime ts,
1756     gint64 * bytepos)
1757 {
1758   gint64 total_bytes;
1759   GstClockTime total_time;
1760
1761   /* -1 always maps to -1 */
1762   if (ts == -1) {
1763     *bytepos = -1;
1764     return TRUE;
1765   }
1766
1767   /* If XING seek table exists use this for time->byte conversion */
1768   if ((mp3parse->xing_flags & XING_TOC_FLAG) &&
1769       (total_bytes = mp3parse->xing_bytes) &&
1770       (total_time = mp3parse->xing_total_time)) {
1771     gdouble fa, fb, fx;
1772     gdouble percent =
1773         CLAMP ((100.0 * gst_util_guint64_to_gdouble (ts)) /
1774         gst_util_guint64_to_gdouble (total_time), 0.0, 100.0);
1775     gint index = CLAMP (percent, 0, 99);
1776
1777     fa = mp3parse->xing_seek_table[index];
1778     if (index < 99)
1779       fb = mp3parse->xing_seek_table[index + 1];
1780     else
1781       fb = 256.0;
1782
1783     fx = fa + (fb - fa) * (percent - index);
1784
1785     *bytepos = (1.0 / 256.0) * fx * total_bytes;
1786
1787     return TRUE;
1788   }
1789
1790   if (mp3parse->vbri_seek_table && (total_bytes = mp3parse->vbri_bytes) &&
1791       (total_time = mp3parse->vbri_total_time)) {
1792     gint i, j;
1793     gdouble a, b, fa, fb;
1794
1795     i = gst_util_uint64_scale (ts, mp3parse->vbri_seek_points - 1, total_time);
1796     i = CLAMP (i, 0, mp3parse->vbri_seek_points - 1);
1797
1798     a = gst_guint64_to_gdouble (gst_util_uint64_scale (i, total_time,
1799             mp3parse->vbri_seek_points));
1800     fa = 0.0;
1801     for (j = i; j >= 0; j--)
1802       fa += mp3parse->vbri_seek_table[j];
1803
1804     if (i + 1 < mp3parse->vbri_seek_points) {
1805       b = gst_guint64_to_gdouble (gst_util_uint64_scale (i + 1, total_time,
1806               mp3parse->vbri_seek_points));
1807       fb = fa + mp3parse->vbri_seek_table[i + 1];
1808     } else {
1809       b = gst_guint64_to_gdouble (total_time);
1810       fb = total_bytes;
1811     }
1812
1813     *bytepos = fa + ((fb - fa) / (b - a)) * (gst_guint64_to_gdouble (ts) - a);
1814
1815     return TRUE;
1816   }
1817
1818   if (mp3parse->avg_bitrate == 0)
1819     goto no_bitrate;
1820
1821   *bytepos =
1822       gst_util_uint64_scale (ts, mp3parse->avg_bitrate, (8 * GST_SECOND));
1823   return TRUE;
1824 no_bitrate:
1825   GST_DEBUG_OBJECT (mp3parse, "Cannot seek yet - no average bitrate");
1826   return FALSE;
1827 }
1828
1829 static gboolean
1830 mp3parse_bytepos_to_time (GstMPEGAudioParse * mp3parse,
1831     gint64 bytepos, GstClockTime * ts, gboolean from_total_time)
1832 {
1833   gint64 total_bytes;
1834   GstClockTime total_time;
1835
1836   if (bytepos == -1) {
1837     *ts = GST_CLOCK_TIME_NONE;
1838     return TRUE;
1839   }
1840
1841   if (bytepos == 0) {
1842     *ts = 0;
1843     return TRUE;
1844   }
1845
1846   /* If XING seek table exists use this for byte->time conversion */
1847   if (!from_total_time && (mp3parse->xing_flags & XING_TOC_FLAG) &&
1848       (total_bytes = mp3parse->xing_bytes) &&
1849       (total_time = mp3parse->xing_total_time)) {
1850     gdouble fa, fb, fx;
1851     gdouble pos;
1852     gint index;
1853
1854     pos = CLAMP ((bytepos * 256.0) / total_bytes, 0.0, 256.0);
1855     index = CLAMP (pos, 0, 255);
1856     fa = mp3parse->xing_seek_table_inverse[index];
1857     if (index < 255)
1858       fb = mp3parse->xing_seek_table_inverse[index + 1];
1859     else
1860       fb = 10000.0;
1861
1862     fx = fa + (fb - fa) * (pos - index);
1863
1864     *ts = (1.0 / 10000.0) * fx * gst_util_guint64_to_gdouble (total_time);
1865
1866     return TRUE;
1867   }
1868
1869   if (!from_total_time && mp3parse->vbri_seek_table &&
1870       (total_bytes = mp3parse->vbri_bytes) &&
1871       (total_time = mp3parse->vbri_total_time)) {
1872     gint i = 0;
1873     guint64 sum = 0;
1874     gdouble a, b, fa, fb;
1875
1876     do {
1877       sum += mp3parse->vbri_seek_table[i];
1878       i++;
1879     } while (i + 1 < mp3parse->vbri_seek_points
1880         && sum + mp3parse->vbri_seek_table[i] < bytepos);
1881     i--;
1882
1883     a = gst_guint64_to_gdouble (sum);
1884     fa = gst_guint64_to_gdouble (gst_util_uint64_scale (i, total_time,
1885             mp3parse->vbri_seek_points));
1886
1887     if (i + 1 < mp3parse->vbri_seek_points) {
1888       b = a + mp3parse->vbri_seek_table[i + 1];
1889       fb = gst_guint64_to_gdouble (gst_util_uint64_scale (i + 1, total_time,
1890               mp3parse->vbri_seek_points));
1891     } else {
1892       b = total_bytes;
1893       fb = gst_guint64_to_gdouble (total_time);
1894     }
1895
1896     *ts = gst_gdouble_to_guint64 (fa + ((fb - fa) / (b - a)) * (bytepos - a));
1897
1898     return TRUE;
1899   }
1900
1901   /* Cannot convert anything except 0 if we don't have a bitrate yet */
1902   if (mp3parse->avg_bitrate == 0)
1903     return FALSE;
1904
1905   *ts = (GstClockTime) gst_util_uint64_scale (GST_SECOND, bytepos * 8,
1906       mp3parse->avg_bitrate);
1907   return TRUE;
1908 }
1909
1910 static gboolean
1911 mp3parse_handle_seek (GstMPEGAudioParse * mp3parse, GstEvent * event)
1912 {
1913   GstFormat format;
1914   gdouble rate;
1915   GstSeekFlags flags;
1916   GstSeekType cur_type, stop_type;
1917   gint64 cur, stop;
1918   gint64 byte_cur, byte_stop;
1919   MPEGAudioPendingAccurateSeek *seek;
1920   GstClockTime start;
1921
1922   gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1923       &stop_type, &stop);
1924
1925   GST_DEBUG_OBJECT (mp3parse, "Performing seek to %" GST_TIME_FORMAT,
1926       GST_TIME_ARGS (cur));
1927
1928   /* For any format other than TIME, see if upstream handles
1929    * it directly or fail. For TIME, try upstream, but do it ourselves if
1930    * it fails upstream */
1931   if (format != GST_FORMAT_TIME) {
1932     gst_event_ref (event);
1933     return gst_pad_push_event (mp3parse->sinkpad, event);
1934   } else {
1935     gst_event_ref (event);
1936     if (gst_pad_push_event (mp3parse->sinkpad, event))
1937       return TRUE;
1938   }
1939
1940   seek = g_new0 (MPEGAudioPendingAccurateSeek, 1);
1941
1942   seek->segment = mp3parse->segment;
1943
1944   gst_segment_set_seek (&seek->segment, rate, GST_FORMAT_TIME,
1945       flags, cur_type, cur, stop_type, stop, NULL);
1946
1947   /* Handle TIME based seeks by converting to a BYTE position */
1948
1949   /* For accurate seeking get the frame 9 (MPEG1) or 29 (MPEG2) frames
1950    * before the one we want to seek to and push them all to the decoder.
1951    *
1952    * This is necessary because of the bit reservoir. See
1953    * http://www.mars.org/mailman/public/mad-dev/2002-May/000634.html
1954    *
1955    */
1956
1957   if (flags & GST_SEEK_FLAG_ACCURATE) {
1958     if (!mp3parse->seek_table) {
1959       byte_cur = 0;
1960       byte_stop = -1;
1961       start = 0;
1962     } else {
1963       MPEGAudioSeekEntry *entry = NULL, *start_entry = NULL, *stop_entry = NULL;
1964       GList *start_node, *stop_node;
1965       gint64 seek_ts = (cur > mp3parse->max_bitreservoir) ?
1966           (cur - mp3parse->max_bitreservoir) : 0;
1967
1968       for (start_node = mp3parse->seek_table; start_node;
1969           start_node = start_node->next) {
1970         entry = start_node->data;
1971
1972         if (seek_ts >= entry->timestamp) {
1973           start_entry = entry;
1974           break;
1975         }
1976       }
1977
1978       if (!start_entry) {
1979         start_entry = mp3parse->seek_table->data;
1980         start = start_entry->timestamp;
1981         byte_cur = start_entry->byte;
1982       } else {
1983         start = start_entry->timestamp;
1984         byte_cur = start_entry->byte;
1985       }
1986
1987       for (stop_node = mp3parse->seek_table; stop_node;
1988           stop_node = stop_node->next) {
1989         entry = stop_node->data;
1990
1991         if (stop >= entry->timestamp) {
1992           stop_node = stop_node->prev;
1993           stop_entry = (stop_node) ? stop_node->data : NULL;
1994           break;
1995         }
1996       }
1997
1998       if (!stop_entry) {
1999         byte_stop = -1;
2000       } else {
2001         byte_stop = stop_entry->byte;
2002       }
2003
2004     }
2005     event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type,
2006         byte_cur, stop_type, byte_stop);
2007     g_mutex_lock (mp3parse->pending_seeks_lock);
2008     seek->upstream_start = byte_cur;
2009     seek->timestamp_start = start;
2010     mp3parse->pending_accurate_seeks =
2011         g_slist_prepend (mp3parse->pending_accurate_seeks, seek);
2012     g_mutex_unlock (mp3parse->pending_seeks_lock);
2013     if (gst_pad_push_event (mp3parse->sinkpad, event)) {
2014       mp3parse->exact_position = TRUE;
2015       return TRUE;
2016     } else {
2017       mp3parse->exact_position = TRUE;
2018       g_mutex_lock (mp3parse->pending_seeks_lock);
2019       mp3parse->pending_accurate_seeks =
2020           g_slist_remove (mp3parse->pending_accurate_seeks, seek);
2021       g_mutex_unlock (mp3parse->pending_seeks_lock);
2022       g_free (seek);
2023       return FALSE;
2024     }
2025   }
2026
2027   mp3parse->exact_position = FALSE;
2028
2029   /* Convert the TIME to the appropriate BYTE position at which to resume
2030    * decoding. */
2031   if (!mp3parse_time_to_bytepos (mp3parse, (GstClockTime) cur, &byte_cur))
2032     goto no_pos;
2033   if (!mp3parse_time_to_bytepos (mp3parse, (GstClockTime) stop, &byte_stop))
2034     goto no_pos;
2035
2036   GST_DEBUG_OBJECT (mp3parse, "Seeking to byte range %" G_GINT64_FORMAT
2037       " to %" G_GINT64_FORMAT, byte_cur, byte_stop);
2038
2039   /* Send BYTE based seek upstream */
2040   event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type,
2041       byte_cur, stop_type, byte_stop);
2042
2043   GST_LOG_OBJECT (mp3parse, "Storing pending seek");
2044   g_mutex_lock (mp3parse->pending_seeks_lock);
2045   seek->upstream_start = byte_cur;
2046   seek->timestamp_start = cur;
2047   mp3parse->pending_nonaccurate_seeks =
2048       g_slist_prepend (mp3parse->pending_nonaccurate_seeks, seek);
2049   g_mutex_unlock (mp3parse->pending_seeks_lock);
2050   if (gst_pad_push_event (mp3parse->sinkpad, event)) {
2051     return TRUE;
2052   } else {
2053     g_mutex_lock (mp3parse->pending_seeks_lock);
2054     mp3parse->pending_nonaccurate_seeks =
2055         g_slist_remove (mp3parse->pending_nonaccurate_seeks, seek);
2056     g_mutex_unlock (mp3parse->pending_seeks_lock);
2057     g_free (seek);
2058     return FALSE;
2059   }
2060
2061 no_pos:
2062   GST_DEBUG_OBJECT (mp3parse,
2063       "Could not determine byte position for desired time");
2064   return FALSE;
2065 }
2066
2067 static gboolean
2068 mp3parse_src_event (GstPad * pad, GstEvent * event)
2069 {
2070   GstMPEGAudioParse *mp3parse;
2071   gboolean res = FALSE;
2072
2073   mp3parse = GST_MP3PARSE (gst_pad_get_parent (pad));
2074
2075   switch (GST_EVENT_TYPE (event)) {
2076     case GST_EVENT_SEEK:
2077       res = mp3parse_handle_seek (mp3parse, event);
2078       gst_event_unref (event);
2079       break;
2080     default:
2081       res = gst_pad_event_default (pad, event);
2082       break;
2083   }
2084
2085   gst_object_unref (mp3parse);
2086   return res;
2087 }
2088
2089 static gboolean
2090 mp3parse_src_query (GstPad * pad, GstQuery * query)
2091 {
2092   GstFormat format;
2093   GstClockTime total;
2094   GstMPEGAudioParse *mp3parse;
2095   gboolean res = FALSE;
2096   GstPad *peer;
2097
2098   mp3parse = GST_MP3PARSE (gst_pad_get_parent (pad));
2099
2100   GST_LOG_OBJECT (pad, "%s query", GST_QUERY_TYPE_NAME (query));
2101
2102   switch (GST_QUERY_TYPE (query)) {
2103     case GST_QUERY_POSITION:
2104       gst_query_parse_position (query, &format, NULL);
2105
2106       if (format == GST_FORMAT_BYTES || format == GST_FORMAT_DEFAULT) {
2107         if (mp3parse->cur_offset != -1) {
2108           gst_query_set_position (query, GST_FORMAT_BYTES,
2109               mp3parse->cur_offset);
2110           res = TRUE;
2111         }
2112       } else if (format == GST_FORMAT_TIME) {
2113         if (mp3parse->next_ts == GST_CLOCK_TIME_NONE)
2114           goto out;
2115         gst_query_set_position (query, GST_FORMAT_TIME, mp3parse->next_ts);
2116         res = TRUE;
2117       }
2118
2119       /* If no answer above, see if upstream knows */
2120       if (!res) {
2121         if ((peer = gst_pad_get_peer (mp3parse->sinkpad)) != NULL) {
2122           res = gst_pad_query (peer, query);
2123           gst_object_unref (peer);
2124           if (res)
2125             goto out;
2126         }
2127       }
2128       break;
2129     case GST_QUERY_DURATION:
2130       gst_query_parse_duration (query, &format, NULL);
2131
2132       /* First, see if upstream knows */
2133       if ((peer = gst_pad_get_peer (mp3parse->sinkpad)) != NULL) {
2134         res = gst_pad_query (peer, query);
2135         gst_object_unref (peer);
2136         if (res)
2137           goto out;
2138       }
2139
2140       if (format == GST_FORMAT_TIME) {
2141         if (!mp3parse_total_time (mp3parse, &total) || total == -1)
2142           goto out;
2143         gst_query_set_duration (query, format, total);
2144         res = TRUE;
2145       }
2146       break;
2147     case GST_QUERY_SEEKING:
2148       gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
2149
2150       /* does upstream handle ? */
2151       if ((peer = gst_pad_get_peer (mp3parse->sinkpad)) != NULL) {
2152         res = gst_pad_query (peer, query);
2153         gst_object_unref (peer);
2154       }
2155       /* we may be able to help if in TIME */
2156       if (format == GST_FORMAT_TIME) {
2157         gboolean seekable;
2158
2159         gst_query_parse_seeking (query, &format, &seekable, NULL, NULL);
2160         /* already OK if upstream takes care */
2161         if (!(res && seekable)) {
2162           gint64 pos;
2163
2164           seekable = TRUE;
2165           if (!mp3parse_total_time (mp3parse, &total) || total == -1) {
2166             seekable = FALSE;
2167           } else if (!mp3parse_time_to_bytepos (mp3parse, 0, &pos)) {
2168             seekable = FALSE;
2169           } else {
2170             GstQuery *q;
2171
2172             q = gst_query_new_seeking (GST_FORMAT_BYTES);
2173             if (!gst_pad_peer_query (mp3parse->sinkpad, q)) {
2174               seekable = FALSE;
2175             } else {
2176               gst_query_parse_seeking (q, &format, &seekable, NULL, NULL);
2177             }
2178             gst_query_unref (q);
2179           }
2180           gst_query_set_seeking (query, GST_FORMAT_TIME, seekable, 0, total);
2181           res = TRUE;
2182         }
2183       }
2184       break;
2185     default:
2186       res = gst_pad_query_default (pad, query);
2187       break;
2188   }
2189
2190 out:
2191   gst_object_unref (mp3parse);
2192   return res;
2193 }
2194
2195 static const GstQueryType *
2196 mp3parse_get_query_types (GstPad * pad G_GNUC_UNUSED)
2197 {
2198   static const GstQueryType query_types[] = {
2199     GST_QUERY_POSITION,
2200     GST_QUERY_DURATION,
2201     0
2202   };
2203
2204   return query_types;
2205 }