From: Sebastian Dröge Date: Tue, 15 Jan 2008 17:18:31 +0000 (+0000) Subject: gst/mpegaudioparse/gstmpegaudioparse.c: Interpolate the VBRI seek table entries to... X-Git-Tag: 1.19.3~505^2~1645 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=eecdae5af2258fae00cd624fc9e44b062ae7149e;p=platform%2Fupstream%2Fgstreamer.git gst/mpegaudioparse/gstmpegaudioparse.c: Interpolate the VBRI seek table entries to get better results, support 3 byte... Original commit message from CVS: * gst/mpegaudioparse/gstmpegaudioparse.c: (gst_mp3parse_handle_first_frame), (mp3parse_time_to_bytepos), (mp3parse_bytepos_to_time): Interpolate the VBRI seek table entries to get better results, support 3 byte seek table entries and prevent overflows in the seek table by adding the relative offsets when using the seek table in a large enough data type. --- diff --git a/ChangeLog b/ChangeLog index 8bbe143..47e6d37 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2008-01-15 Sebastian Dröge + + * gst/mpegaudioparse/gstmpegaudioparse.c: + (gst_mp3parse_handle_first_frame), (mp3parse_time_to_bytepos), + (mp3parse_bytepos_to_time): + Interpolate the VBRI seek table entries to get better results, + support 3 byte seek table entries and prevent overflows in the + seek table by adding the relative offsets when using the seek + table in a large enough data type. + 2008-01-14 Sebastian Dröge * gst/mpegaudioparse/gstmpegaudioparse.c: (gst_mp3parse_reset), diff --git a/common b/common index 36e8d05..0efbab8 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 36e8d05157d6c831e0d3919ae2ee9c342498eda8 +Subproject commit 0efbab89d333b5d07cc7da1a501c38edf5bb4f72 diff --git a/gst/mpegaudioparse/gstmpegaudioparse.c b/gst/mpegaudioparse/gstmpegaudioparse.c index b0fa5a3..b6360cf 100644 --- a/gst/mpegaudioparse/gstmpegaudioparse.c +++ b/gst/mpegaudioparse/gstmpegaudioparse.c @@ -29,6 +29,7 @@ GST_DEBUG_CATEGORY_STATIC (mp3parse_debug); #define GST_CAT_DEFAULT mp3parse_debug +#define GST_READ_UINT24_BE(p) (p[2] | (p[1] << 8) | (p[0] << 16)) /* elementfactory information */ static GstElementDetails mp3parse_details = { @@ -922,8 +923,7 @@ gst_mp3parse_handle_first_frame (GstMPEGAudioParse * mp3parse) seek_frames = GST_READ_UINT16_BE (data); data += 2; - if (scale == 0 || seek_bytes == 0 || seek_bytes == 3 || seek_bytes > 4 - || seek_frames == 0) { + if (scale == 0 || seek_bytes == 0 || seek_bytes > 4 || seek_frames == 0) { GST_WARNING_OBJECT (mp3parse, "Unsupported VBRI seek table"); goto out_vbri; } @@ -952,21 +952,19 @@ gst_mp3parse_handle_first_frame (GstMPEGAudioParse * mp3parse) mp3parse->vbri_seek_table = g_new (guint32, nseek_points); if (seek_bytes == 4) for (i = 0; i < nseek_points; i++) { - mp3parse->vbri_seek_table[i] = - (i > 0) ? mp3parse->vbri_seek_table[i - 1] : 0; - mp3parse->vbri_seek_table[i] += GST_READ_UINT32_BE (data) * scale; + mp3parse->vbri_seek_table[i] = GST_READ_UINT32_BE (data) * scale; data += 4; + } else if (seek_bytes == 3) + for (i = 0; i < nseek_points; i++) { + mp3parse->vbri_seek_table[i] = GST_READ_UINT24_BE (data) * scale; + data += 3; } else if (seek_bytes == 2) for (i = 0; i < nseek_points; i++) { - mp3parse->vbri_seek_table[i] = - (i > 0) ? mp3parse->vbri_seek_table[i - 1] : 0; - mp3parse->vbri_seek_table[i] += GST_READ_UINT16_BE (data) * scale; + mp3parse->vbri_seek_table[i] = GST_READ_UINT16_BE (data) * scale; data += 2; } else /* seek_bytes == 1 */ for (i = 0; i < nseek_points; i++) { - mp3parse->vbri_seek_table[i] = - (i > 0) ? mp3parse->vbri_seek_table[i - 1] : 0; - mp3parse->vbri_seek_table[i] += GST_READ_UINT8 (data) * scale; + mp3parse->vbri_seek_table[i] = GST_READ_UINT8 (data) * scale; data += 1; } } @@ -1371,11 +1369,28 @@ mp3parse_time_to_bytepos (GstMPEGAudioParse * mp3parse, GstClockTime ts, if (mp3parse->vbri_seek_table && mp3parse_total_bytes (mp3parse, &total_bytes) && mp3parse_total_time (mp3parse, &total_time)) { - gint i = gst_util_uint64_scale (ts, mp3parse->vbri_seek_points, total_time); - - i = CLAMP (i, 0, mp3parse->vbri_seek_points); + gint i, j; + gdouble a, b, fa, fb; + + i = gst_util_uint64_scale (ts, mp3parse->vbri_seek_points - 1, total_time); + i = CLAMP (i, 0, mp3parse->vbri_seek_points - 1); + + a = gst_guint64_to_gdouble (gst_util_uint64_scale (i, total_time, + mp3parse->vbri_seek_points)); + fa = 0.0; + for (j = i; j >= 0; j--) + fa += mp3parse->vbri_seek_table[j]; + + if (i + 1 < mp3parse->vbri_seek_points) { + b = gst_guint64_to_gdouble (gst_util_uint64_scale (i + 1, total_time, + mp3parse->vbri_seek_points)); + fb = fa + mp3parse->vbri_seek_table[i + 1]; + } else { + b = gst_guint64_to_gdouble (total_time); + fb = total_bytes; + } - *bytepos = mp3parse->vbri_seek_table[i]; + *bytepos = fa + ((fb - fa) / (b - a)) * (ts - a); return TRUE; } @@ -1433,14 +1448,31 @@ mp3parse_bytepos_to_time (GstMPEGAudioParse * mp3parse, mp3parse_total_bytes (mp3parse, &total_bytes) && mp3parse_total_time (mp3parse, &total_time)) { gint i = 0; + guint64 sum = 0; + gdouble a, b, fa, fb; - while (mp3parse->vbri_seek_table[i] < bytepos - && i < mp3parse->vbri_seek_points) - i++; - i = CLAMP (i, 0, mp3parse->vbri_seek_points); + do { + sum += mp3parse->vbri_seek_table[i]; + i++; + } while (i + 1 < mp3parse->vbri_seek_points + && sum + mp3parse->vbri_seek_table[i] < bytepos); + i--; + + a = gst_guint64_to_gdouble (sum); + fa = gst_guint64_to_gdouble (gst_util_uint64_scale (i, total_time, + mp3parse->vbri_seek_points)); + + if (i + 1 < mp3parse->vbri_seek_points) { + b = a + mp3parse->vbri_seek_table[i + 1]; + fb = gst_guint64_to_gdouble (gst_util_uint64_scale (i + 1, total_time, + mp3parse->vbri_seek_points)); + } else { + b = total_bytes; + fb = gst_guint64_to_gdouble (total_time); + } - *ts = gst_util_uint64_scale (total_time, i, mp3parse->vbri_seek_points); + *ts = gst_gdouble_to_guint64 (fa + ((fb - fa) / (b - a)) * (bytepos - a)); return TRUE; }