bytereader: Accelerate MPEG/H264 start code scanning
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Thu, 8 Aug 2013 10:08:31 +0000 (12:08 +0200)
committerNicolas Dufresne <nicolas.dufresne@collabora.co.uk>
Sat, 10 Aug 2013 22:54:34 +0000 (18:54 -0400)
Accelerate MPEG/H264 start code scanning using Boyer-Moor bad character
heuristic.

https://bugzilla.gnome.org/show_bug.cgi?id=702357

libs/gst/base/gstbytereader.c

index 5ca9555..a5f9e40 100644 (file)
@@ -771,6 +771,31 @@ gst_byte_reader_dup_data (GstByteReader * reader, guint size, guint8 ** val)
   return _gst_byte_reader_dup_data_inline (reader, size, val);
 }
 
+/* Special optimized scan for mask 0xffffff00 and pattern 0x00000100 */
+static inline gint
+_scan_for_start_code (const guint8 * data, guint offset, guint size)
+{
+  guint i = 0;
+
+  while (i <= (size - 4)) {
+    if (data[i + 2] > 1) {
+      i += 3;
+    } else if (data[i + 1]) {
+      i += 2;
+    } else if (data[i] || data[i + 2] != 1) {
+      i++;
+    } else {
+      break;
+    }
+  }
+
+  if (i <= (size - 4))
+    return i + offset;
+
+  /* nothing found */
+  return -1;
+}
+
 /**
  * gst_byte_reader_masked_scan_uint32:
  * @reader: a #GstByteReader
@@ -831,6 +856,10 @@ gst_byte_reader_masked_scan_uint32 (const GstByteReader * reader, guint32 mask,
 
   data = reader->data + reader->byte + offset;
 
+  /* Handle special case found in MPEG and H264 */
+  if ((pattern == 0x00000100) && (mask == 0xffffff00))
+    return _scan_for_start_code (data, offset, size);
+
   /* set the state to something that does not match */
   state = ~pattern;