gst/typefind/gsttypefindfunctions.c: Move scan helper thingy to the beginning of...
authorTim-Philipp Müller <tim@centricular.net>
Sat, 10 May 2008 18:19:17 +0000 (18:19 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Sat, 10 May 2008 18:19:17 +0000 (18:19 +0000)
Original commit message from CVS:
* gst/typefind/gsttypefindfunctions.c:
(DATA_SCAN_CTX_CHUNK_SIZE), (DataScanCtx), (data_scan_ctx_advance),
(data_scan_ctx_ensure_data), (GST_MPEGVID_TYPEFIND_TRY_SYNC),
(mpeg_video_stream_type_find):
Move scan helper thingy to the beginning of the file so we can use
it in other typefind functions. Rename it to something more
generic. Also improve handling of things towards the end of the
typefind data: peek as much as we can if we know the size of the
data, rather than just min_size.

ChangeLog
gst/typefind/gsttypefindfunctions.c

index eb30509..34399b2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2008-05-10  Tim-Philipp Müller  <tim.muller at collabora co uk>
+
+       * gst/typefind/gsttypefindfunctions.c:
+         (DATA_SCAN_CTX_CHUNK_SIZE), (DataScanCtx), (data_scan_ctx_advance),
+         (data_scan_ctx_ensure_data), (GST_MPEGVID_TYPEFIND_TRY_SYNC),
+         (mpeg_video_stream_type_find):
+         Move scan helper thingy to the beginning of the file so we can use
+         it in other typefind functions. Rename it to something more
+         generic. Also improve handling of things towards the end of the
+         typefind data: peek as much as we can if we know the size of the
+         data, rather than just min_size.
+
 2008-05-09  Jan Schmidt  <jan.schmidt@sun.com>
 
        * docs/libs/gst-plugins-base-libs-sections.txt:
index d1116a4..7ccd150 100644 (file)
 GST_DEBUG_CATEGORY_STATIC (type_find_debug);
 #define GST_CAT_DEFAULT type_find_debug
 
+/* DataScanCtx: helper for typefind functions that scan through data
+ * step-by-step, to avoid doing a peek at each and every offset */
+
+#define DATA_SCAN_CTX_CHUNK_SIZE 4096
+
+typedef struct
+{
+  guint64 offset;
+  guint8 *data;
+  gint size;
+} DataScanCtx;
+
+static inline void
+data_scan_ctx_advance (GstTypeFind * tf, DataScanCtx * c, guint bytes_to_skip)
+{
+  c->offset += bytes_to_skip;
+  if (G_LIKELY (c->size > bytes_to_skip)) {
+    c->size -= bytes_to_skip;
+    c->data += bytes_to_skip;
+  } else {
+    c->data += c->size;
+    c->size = 0;
+  }
+}
+
+static inline gboolean
+data_scan_ctx_ensure_data (GstTypeFind * tf, DataScanCtx * c, gint min_len)
+{
+  guint64 len;
+
+  if (G_LIKELY (c->size >= min_len))
+    return TRUE;
+
+  c->data = gst_type_find_peek (tf, c->offset, DATA_SCAN_CTX_CHUNK_SIZE);
+  if (G_LIKELY (c->data != NULL)) {
+    c->size = DATA_SCAN_CTX_CHUNK_SIZE;
+    return TRUE;
+  }
+
+  /* if there's less than our chunk size, try to get as much as we can, but
+   * always at least min_len bytes (we might be typefinding the first buffer
+   * of the stream and not have as much data available as we'd like) */
+  len = gst_type_find_get_length (tf);
+  if (len > 0) {
+    len = CLAMP (len - c->offset, min_len, DATA_SCAN_CTX_CHUNK_SIZE);
+  } else {
+    len = min_len;
+  }
+
+  c->data = gst_type_find_peek (tf, c->offset, len);
+  if (c->data != NULL) {
+    c->size = len;
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
 /*** text/plain ***/
 static gboolean xml_check_first_element (GstTypeFind * tf,
     const gchar * element, guint elen, gboolean strict);
@@ -1651,57 +1709,11 @@ static GstStaticCaps mpeg_video_caps = GST_STATIC_CAPS ("video/mpeg, "
 
 #define GST_MPEGVID_TYPEFIND_TRY_PICTURES 6
 #define GST_MPEGVID_TYPEFIND_TRY_SYNC (100 * 1024)      /* 100 kB */
-#define GST_MPEGVID_TYPEFIND_SYNC_SIZE 2048
-
-typedef struct
-{
-  guint64 offset;
-  guint8 *data;
-  gint size;
-} MpegVideoStreamCtx;
-
-static inline void
-mpeg_video_stream_ctx_advance (GstTypeFind * tf, MpegVideoStreamCtx * c,
-    guint bytes_to_skip)
-{
-  c->offset += bytes_to_skip;
-  if (c->size > bytes_to_skip) {
-    c->size -= bytes_to_skip;
-    c->data += bytes_to_skip;
-  } else {
-    c->data += c->size;
-    c->size = 0;
-  }
-}
-
-static inline gboolean
-mpeg_video_stream_ctx_ensure_data (GstTypeFind * tf, MpegVideoStreamCtx * c,
-    gint min_len)
-{
-  if (c->size >= min_len)
-    return TRUE;
-
-  c->data = gst_type_find_peek (tf, c->offset, GST_MPEGVID_TYPEFIND_SYNC_SIZE);
-  if (c->data != NULL) {
-    c->size = GST_MPEGVID_TYPEFIND_SYNC_SIZE;
-    return TRUE;
-  }
-
-  /* try min_size as fallback: we might be typefinding the first buffer of the
-   * stream and not have as much data available as we'd like */
-  c->data = gst_type_find_peek (tf, c->offset, min_len);
-  if (c->data != NULL) {
-    c->size = min_len;
-    return TRUE;
-  }
-
-  return FALSE;
-}
 
 static void
 mpeg_video_stream_type_find (GstTypeFind * tf, gpointer unused)
 {
-  MpegVideoStreamCtx c = { 0, NULL, 0 };
+  DataScanCtx c = { 0, NULL, 0 };
   gboolean seen_seq_at_0 = FALSE;
   gboolean seen_seq = FALSE;
   gboolean seen_gop = FALSE;
@@ -1713,7 +1725,7 @@ mpeg_video_stream_type_find (GstTypeFind * tf, gpointer unused)
     if (found >= GST_MPEGVID_TYPEFIND_TRY_PICTURES)
       break;
 
-    if (!mpeg_video_stream_ctx_ensure_data (tf, &c, 5))
+    if (!data_scan_ctx_ensure_data (tf, &c, 5))
       break;
 
     if (!IS_MPEG_HEADER (c.data))
@@ -1727,14 +1739,14 @@ mpeg_video_stream_type_find (GstTypeFind * tf, gpointer unused)
     if (c.data[3] == 0xB3) {
       seen_seq_at_0 = seen_seq_at_0 || (c.offset == 0);
       seen_seq = TRUE;
-      mpeg_video_stream_ctx_advance (tf, &c, 4 + 8);
+      data_scan_ctx_advance (tf, &c, 4 + 8);
       continue;
     }
 
     /* or a GOP header */
     if (c.data[3] == 0xB8) {
       seen_gop = TRUE;
-      mpeg_video_stream_ctx_advance (tf, &c, 8);
+      data_scan_ctx_advance (tf, &c, 8);
       continue;
     }
 
@@ -1742,7 +1754,7 @@ mpeg_video_stream_type_find (GstTypeFind * tf, gpointer unused)
     if (c.data[3] == 0x00) {
       ++num_pic_headers;
       last_pic_offset = c.offset;
-      mpeg_video_stream_ctx_advance (tf, &c, 8);
+      data_scan_ctx_advance (tf, &c, 8);
       continue;
     }
 
@@ -1751,14 +1763,14 @@ mpeg_video_stream_type_find (GstTypeFind * tf, gpointer unused)
     if (c.data[3] == 0x01 && num_pic_headers > found &&
         (c.offset - last_pic_offset) >= 4 &&
         (c.offset - last_pic_offset) <= 64) {
-      mpeg_video_stream_ctx_advance (tf, &c, 4);
+      data_scan_ctx_advance (tf, &c, 4);
       found += 1;
       continue;
     }
 
   next:
 
-    mpeg_video_stream_ctx_advance (tf, &c, 1);
+    data_scan_ctx_advance (tf, &c, 1);
   }
 
   if (found > 0 || seen_seq) {