gst/mpegaudioparse/gstmpegaudioparse.c: Copy the complete Xing seek table in the...
authorSebastian Dröge <slomo@circular-chaos.org>
Thu, 28 Jun 2007 20:33:51 +0000 (20:33 +0000)
committerSebastian Dröge <slomo@circular-chaos.org>
Thu, 28 Jun 2007 20:33:51 +0000 (20:33 +0000)
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
gst/mpegaudioparse/gstmpegaudioparse.c

index 81dff9094932e639aad33ef2723959ca2498e717..9b05ceeacc1a350c22aa396065679b5b029fbe96 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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:
index a871ffc3ec57a2ab08c98cc23d8185d7889a90a6..19fdc8f877105d8a34264581495d633fb5367f6c 100644 (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)
 {