From 79cfc89c8f5a76716ce502e6a4553a436ec47102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 28 Jun 2007 20:33:51 +0000 Subject: [PATCH] gst/mpegaudioparse/gstmpegaudioparse.c: Copy the complete Xing seek table in the 100 byte array instead of copying th... Original commit message from CVS: * gst/mpegaudioparse/gstmpegaudioparse.c: (gst_mp3parse_handle_first_frame): Copy the complete Xing seek table in the 100 byte array instead of copying the first byte 100 times. * gst/mpegaudioparse/gstmpegaudioparse.c: (mp3parse_total_bytes), (mp3parse_total_time), (mp3parse_time_to_bytepos): Add seeking support based on the Xing header but comment it out for now as it seems to yield worse result than the other method. Also use gst_pad_query_peer_duration() instead of getting the peer pad ourself, creating a new GstQuery, etc. --- ChangeLog | 13 +++ gst/mpegaudioparse/gstmpegaudioparse.c | 126 ++++++++++++++----------- 2 files changed, 84 insertions(+), 55 deletions(-) diff --git a/ChangeLog b/ChangeLog index 81dff90949..9b05ceeacc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2007-06-28 Sebastian Dröge + + * gst/mpegaudioparse/gstmpegaudioparse.c: + (gst_mp3parse_handle_first_frame): + Copy the complete Xing seek table in the 100 byte array instead of + copying the first byte 100 times. + * gst/mpegaudioparse/gstmpegaudioparse.c: (mp3parse_total_bytes), + (mp3parse_total_time), (mp3parse_time_to_bytepos): + Add seeking support based on the Xing header but comment it out for + now as it seems to yield worse result than the other method. + Also use gst_pad_query_peer_duration() instead of getting the peer pad + ourself, creating a new GstQuery, etc. + 2007-06-25 Stefan Kost * docs/plugins/gst-plugins-ugly-plugins.args: diff --git a/gst/mpegaudioparse/gstmpegaudioparse.c b/gst/mpegaudioparse/gstmpegaudioparse.c index a871ffc3ec..19fdc8f877 100644 --- a/gst/mpegaudioparse/gstmpegaudioparse.c +++ b/gst/mpegaudioparse/gstmpegaudioparse.c @@ -609,12 +609,8 @@ gst_mp3parse_handle_first_frame (GstMPEGAudioParse * mp3parse) mp3parse->xing_bytes = 0; if (xing_flags & XING_TOC_FLAG) { - gint i; - - for (i = 0; i < 100; i++) { - mp3parse->xing_seek_table[i] = data[0]; - data++; - } + memcpy (mp3parse->xing_seek_table, data, 100); + data += 100; } else { memset (mp3parse->xing_seek_table, 0, 100); } @@ -929,6 +925,45 @@ gst_mp3parse_change_state (GstElement * element, GstStateChange transition) return result; } +static gboolean +mp3parse_total_bytes (GstMPEGAudioParse * mp3parse, gint64 * total) +{ + GstFormat fmt = GST_FORMAT_BYTES; + + if (gst_pad_query_peer_duration (mp3parse->sinkpad, &fmt, total)) + return TRUE; + + if (mp3parse->xing_flags & XING_BYTES_FLAG) { + *total = mp3parse->xing_bytes; + return TRUE; + } + + return FALSE; +} + +static gboolean +mp3parse_total_time (GstMPEGAudioParse * mp3parse, GstClockTime * total) +{ + gint64 total_bytes; + + *total = GST_CLOCK_TIME_NONE; + + if (mp3parse->xing_flags & XING_FRAMES_FLAG) { + *total = mp3parse->xing_total_time; + return TRUE; + } + + /* Calculate time from the measured bitrate */ + if (!mp3parse_total_bytes (mp3parse, &total_bytes)) + return FALSE; + + if (total_bytes != -1 + && !mp3parse_bytepos_to_time (mp3parse, total_bytes, total)) + return FALSE; + + return TRUE; +} + /* Convert a timestamp to the file position required to start decoding that * timestamp. For now, this just uses the avg bitrate. Later, use an * incrementally accumulated seek table */ @@ -936,12 +971,42 @@ static gboolean mp3parse_time_to_bytepos (GstMPEGAudioParse * mp3parse, GstClockTime ts, gint64 * bytepos) { +#if 0 + gint64 total_bytes; + GstClockTime total_time; +#endif + /* -1 always maps to -1 */ if (ts == -1) { *bytepos = -1; return TRUE; } +/* FIXME: this seems to yield worse results than seeking based on the average + * bitrate */ +#if 0 + /* If XING seek table exists use this for time->byte conversion */ + if ((mp3parse->xing_flags & XING_TOC_FLAG) && + mp3parse_total_bytes (mp3parse, &total_bytes) && + mp3parse_total_time (mp3parse, &total_time)) { + gdouble fa, fb, fx; + gdouble percent = CLAMP ((100.0 * ts) / total_time, 0.0, 100.0); + gint index = CLAMP (percent, 0, 99); + + fa = mp3parse->xing_seek_table[index]; + if (index < 99) + fb = mp3parse->xing_seek_table[index + 1]; + else + fb = 256.0; + + fx = fa + (fb - fa) * (percent - index); + + *bytepos = (1.0 / 256.0) * fx * total_bytes; + + return TRUE; + } +#endif + if (mp3parse->avg_bitrate == 0) goto no_bitrate; @@ -976,55 +1041,6 @@ mp3parse_bytepos_to_time (GstMPEGAudioParse * mp3parse, return TRUE; } -static gboolean -mp3parse_total_bytes (GstMPEGAudioParse * mp3parse, gint64 * total) -{ - GstQuery *query; - GstPad *peer; - - if ((peer = gst_pad_get_peer (mp3parse->sinkpad)) != NULL) { - query = gst_query_new_duration (GST_FORMAT_BYTES); - gst_query_set_duration (query, GST_FORMAT_BYTES, -1); - - if (gst_pad_query (peer, query)) { - gst_object_unref (peer); - gst_query_parse_duration (query, NULL, total); - return TRUE; - } - gst_object_unref (peer); - } - - if (mp3parse->xing_flags & XING_BYTES_FLAG) { - *total = mp3parse->xing_bytes; - return TRUE; - } - - return FALSE; -} - -static gboolean -mp3parse_total_time (GstMPEGAudioParse * mp3parse, GstClockTime * total) -{ - gint64 total_bytes; - - *total = GST_CLOCK_TIME_NONE; - - if (mp3parse->xing_flags & XING_FRAMES_FLAG) { - *total = mp3parse->xing_total_time; - return TRUE; - } - - /* Calculate time from the measured bitrate */ - if (!mp3parse_total_bytes (mp3parse, &total_bytes)) - return FALSE; - - if (total_bytes != -1 - && !mp3parse_bytepos_to_time (mp3parse, total_bytes, total)) - return FALSE; - - return TRUE; -} - static gboolean mp3parse_handle_seek (GstMPEGAudioParse * mp3parse, GstEvent * event) {