summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Santos <ts.santos@osg.sisa.samsung.com>2014-07-24 14:39:11 -0300
committerThiago Santos <ts.santos@osg.sisa.samsung.com>2014-07-24 17:00:09 -0300
commitf8323b17fb2640e90b10dbe98ac7516bbf381908 (patch)
treeb78019dc8a1d0deecbdaea08851235baa2d8a868
parentfbe2477fae40e546b31b8397d4ac79b5954c827b (diff)
bytereader: add gst_byte_reader_masked_scan_uint32_peek
Adds gst_byte_reader_masked_scan_uint32_peek just like GstAdapter has a _peek and non _peek version Upgraded tests to check that the returned value is correct in the _peek version API: gst_byte_reader_masked_scan_uint32_peek https://bugzilla.gnome.org/show_bug.cgi?id=728356
-rw-r--r--libs/gst/base/gstbytereader.c115
-rw-r--r--libs/gst/base/gstbytereader.h6
-rw-r--r--tests/check/libs/bytereader.c12
-rw-r--r--win32/common/libgstbase.def1
4 files changed, 99 insertions, 35 deletions
diff --git a/libs/gst/base/gstbytereader.c b/libs/gst/base/gstbytereader.c
index b73a679326..6931841199 100644
--- a/libs/gst/base/gstbytereader.c
+++ b/libs/gst/base/gstbytereader.c
@@ -794,6 +794,55 @@ _scan_for_start_code (const guint8 * data, guint offset, guint size)
return -1;
}
+static inline guint
+_masked_scan_uint32_peek (const GstByteReader * reader,
+ guint32 mask, guint32 pattern, guint offset, guint size, guint32 * value)
+{
+ const guint8 *data;
+ guint32 state;
+ guint i;
+
+ g_return_val_if_fail (size > 0, -1);
+ g_return_val_if_fail ((guint64) offset + size <= reader->size - reader->byte,
+ -1);
+
+ /* we can't find the pattern with less than 4 bytes */
+ if (G_UNLIKELY (size < 4))
+ return -1;
+
+ data = reader->data + reader->byte + offset;
+
+ /* Handle special case found in MPEG and H264 */
+ if ((pattern == 0x00000100) && (mask == 0xffffff00)) {
+ guint ret = _scan_for_start_code (data, offset, size);
+ if (G_UNLIKELY (value))
+ *value = (1 << 8) | data[ret + 3];
+ return ret;
+ }
+
+ /* set the state to something that does not match */
+ state = ~pattern;
+
+ /* now find data */
+ for (i = 0; i < size; i++) {
+ /* throw away one byte and move in the next byte */
+ state = ((state << 8) | data[i]);
+ if (G_UNLIKELY ((state & mask) == pattern)) {
+ /* we have a match but we need to have skipped at
+ * least 4 bytes to fill the state. */
+ if (G_LIKELY (i >= 3)) {
+ if (value)
+ *value = state;
+ return offset + i - 3;
+ }
+ }
+ }
+
+ /* nothing found */
+ return -1;
+}
+
+
/**
* gst_byte_reader_masked_scan_uint32:
* @reader: a #GstByteReader
@@ -840,41 +889,39 @@ guint
gst_byte_reader_masked_scan_uint32 (const GstByteReader * reader, guint32 mask,
guint32 pattern, guint offset, guint size)
{
- const guint8 *data;
- guint32 state;
- guint i;
-
- g_return_val_if_fail (size > 0, -1);
- g_return_val_if_fail ((guint64) offset + size <= reader->size - reader->byte,
- -1);
-
- /* we can't find the pattern with less than 4 bytes */
- if (G_UNLIKELY (size < 4))
- return -1;
-
- 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;
-
- /* now find data */
- for (i = 0; i < size; i++) {
- /* throw away one byte and move in the next byte */
- state = ((state << 8) | data[i]);
- if (G_UNLIKELY ((state & mask) == pattern)) {
- /* we have a match but we need to have skipped at
- * least 4 bytes to fill the state. */
- if (G_LIKELY (i >= 3))
- return offset + i - 3;
- }
- }
+ return _masked_scan_uint32_peek (reader, mask, pattern, offset, size, NULL);
+}
- /* nothing found */
- return -1;
+/**
+ * gst_byte_reader_masked_scan_uint32_peek:
+ * @reader: a #GstByteReader
+ * @mask: mask to apply to data before matching against @pattern
+ * @pattern: pattern to match (after mask is applied)
+ * @offset: offset from which to start scanning, relative to the current
+ * position
+ * @size: number of bytes to scan from offset
+ * @value: pointer to uint32 to return matching data
+ *
+ * Scan for pattern @pattern with applied mask @mask in the byte reader data,
+ * starting from offset @offset relative to the current position.
+ *
+ * The bytes in @pattern and @mask are interpreted left-to-right, regardless
+ * of endianness. All four bytes of the pattern must be present in the
+ * byte reader data for it to match, even if the first or last bytes are masked
+ * out.
+ *
+ * It is an error to call this function without making sure that there is
+ * enough data (offset+size bytes) in the byte reader.
+ *
+ * Returns: offset of the first match, or -1 if no match was found.
+ *
+ * Since: 1.6
+ */
+guint
+gst_byte_reader_masked_scan_uint32_peek (const GstByteReader * reader,
+ guint32 mask, guint32 pattern, guint offset, guint size, guint32 * value)
+{
+ return _masked_scan_uint32_peek (reader, mask, pattern, offset, size, value);
}
#define GST_BYTE_READER_SCAN_STRING(bits) \
diff --git a/libs/gst/base/gstbytereader.h b/libs/gst/base/gstbytereader.h
index 8745ef654e..7182d27872 100644
--- a/libs/gst/base/gstbytereader.h
+++ b/libs/gst/base/gstbytereader.h
@@ -141,6 +141,12 @@ guint gst_byte_reader_masked_scan_uint32 (const GstByteReader * reader
guint32 pattern,
guint offset,
guint size);
+guint gst_byte_reader_masked_scan_uint32_peek (const GstByteReader * reader,
+ guint32 mask,
+ guint32 pattern,
+ guint offset,
+ guint size,
+ guint32 * value);
/**
* GST_BYTE_READER_INIT:
diff --git a/tests/check/libs/bytereader.c b/tests/check/libs/bytereader.c
index ecb3ddbd38..d2a63cc11f 100644
--- a/tests/check/libs/bytereader.c
+++ b/tests/check/libs/bytereader.c
@@ -467,7 +467,17 @@ GST_START_TEST (test_position_tracking)
GST_END_TEST;
#define do_scan(r,m,p,o,s,x) \
- fail_unless_equals_int (gst_byte_reader_masked_scan_uint32 (r,m,p,o,s), x);
+G_STMT_START { \
+ fail_unless_equals_int (gst_byte_reader_masked_scan_uint32 (r,m,p,o,s), x); \
+ if (x != -1) { \
+ guint32 v, res_v; \
+ const guint8 *rdata = NULL; \
+ fail_unless (gst_byte_reader_peek_data (r, x + 4, &rdata)); \
+ res_v = GST_READ_UINT32_BE (rdata + x); \
+ fail_unless_equals_int (gst_byte_reader_masked_scan_uint32_peek (r,m,p,o,s,&v), x); \
+ fail_unless_equals_int (v, res_v); \
+ } \
+} G_STMT_END;
GST_START_TEST (test_scan)
{
diff --git a/win32/common/libgstbase.def b/win32/common/libgstbase.def
index 2713a09b0d..bd31d95bd9 100644
--- a/win32/common/libgstbase.def
+++ b/win32/common/libgstbase.def
@@ -153,6 +153,7 @@ EXPORTS
gst_byte_reader_get_uint8
gst_byte_reader_init
gst_byte_reader_masked_scan_uint32
+ gst_byte_reader_masked_scan_uint32_peek
gst_byte_reader_new
gst_byte_reader_peek_data
gst_byte_reader_peek_float32_be