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.
This commit is contained in:
Sebastian Dröge 2007-06-28 20:33:51 +00:00
parent 3d0a8b950c
commit 79cfc89c8f
2 changed files with 84 additions and 55 deletions

View file

@ -1,3 +1,16 @@
2007-06-28 Sebastian Dröge <slomo@circular-chaos.org>
* 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 <ensonic@users.sf.net>
* docs/plugins/gst-plugins-ugly-plugins.args:

View file

@ -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)
{