mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 08:46:40 +00:00
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
This commit is contained in:
parent
fbe2477fae
commit
f8323b17fb
4 changed files with 99 additions and 35 deletions
|
@ -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) \
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue