From 915ca4685ca6b612421ee50d75fe363c29286d3a Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Wed, 6 Jun 2012 19:02:00 +0200 Subject: [PATCH] gstutils: Faster read macros On platforms that can do unaligned read/write, we can read/write much faster by just casting. https://bugzilla.gnome.org/show_bug.cgi?id=599546 --- gst/gstutils.h | 115 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 86 insertions(+), 29 deletions(-) diff --git a/gst/gstutils.h b/gst/gstutils.h index e562457..d7d0bb5 100644 --- a/gst/gstutils.h +++ b/gst/gstutils.h @@ -26,6 +26,7 @@ #define __GST_UTILS_H__ #include +#include #include #include @@ -114,20 +115,36 @@ void gst_print_element_args (GString *buf, gint indent, GstE #define _GST_PUT(__data, __idx, __size, __shift, __num) \ (((guint8 *) (__data))[__idx] = (((guint##__size) (__num)) >> (__shift)) & 0xff) +#if GST_HAVE_UNALIGNED_ACCESS +static inline guint16 __gst_fast_read16(const guint8 *v) { + return *(const guint16*)(v); +} +static inline guint32 __gst_fast_read32(const guint8 *v) { + return *(const guint32*)(v); +} +static inline guint64 __gst_fast_read64(const guint8 *v) { + return *(const guint64*)(v); +} +static inline guint16 __gst_fast_read_swap16(const guint8 *v) { + return GUINT16_SWAP_LE_BE(*(const guint16*)(v)); +} +static inline guint32 __gst_fast_read_swap32(const guint8 *v) { + return GUINT32_SWAP_LE_BE(*(const guint32*)(v)); +} +static inline guint64 __gst_fast_read_swap64(const guint8 *v) { + return GUINT64_SWAP_LE_BE(*(const guint64*)(v)); +} +# define _GST_FAST_READ(s, d) __gst_fast_read##s((const guint8 *)(d)) +# define _GST_FAST_READ_SWAP(s, d) __gst_fast_read_swap##s((const guint8 *)(d)) +#endif + + /** * GST_READ_UINT64_BE: * @data: memory location * * Read a 64 bit unsigned integer value in big endian format from the memory buffer. */ -#define GST_READ_UINT64_BE(data) (_GST_GET (data, 0, 64, 56) | \ - _GST_GET (data, 1, 64, 48) | \ - _GST_GET (data, 2, 64, 40) | \ - _GST_GET (data, 3, 64, 32) | \ - _GST_GET (data, 4, 64, 24) | \ - _GST_GET (data, 5, 64, 16) | \ - _GST_GET (data, 6, 64, 8) | \ - _GST_GET (data, 7, 64, 0)) /** * GST_READ_UINT64_LE: @@ -135,14 +152,33 @@ void gst_print_element_args (GString *buf, gint indent, GstE * * Read a 64 bit unsigned integer value in little endian format from the memory buffer. */ -#define GST_READ_UINT64_LE(data) (_GST_GET (data, 7, 64, 56) | \ - _GST_GET (data, 6, 64, 48) | \ - _GST_GET (data, 5, 64, 40) | \ - _GST_GET (data, 4, 64, 32) | \ - _GST_GET (data, 3, 64, 24) | \ - _GST_GET (data, 2, 64, 16) | \ - _GST_GET (data, 1, 64, 8) | \ - _GST_GET (data, 0, 64, 0)) +#if GST_HAVE_UNALIGNED_ACCESS +# if (G_BYTE_ORDER == G_BIG_ENDIAN) +# define GST_READ_UINT64_BE(data) _GST_FAST_READ (64, data) +# define GST_READ_UINT64_LE(data) _GST_FAST_READ_SWAP (64, data) +# else +# define GST_READ_UINT64_BE(data) _GST_FAST_READ_SWAP (64, data) +# define GST_READ_UINT64_LE(data) _GST_FAST_READ (64, data) +# endif +#else +# define GST_READ_UINT64_BE(data) (_GST_GET (data, 0, 64, 56) | \ + _GST_GET (data, 1, 64, 48) | \ + _GST_GET (data, 2, 64, 40) | \ + _GST_GET (data, 3, 64, 32) | \ + _GST_GET (data, 4, 64, 24) | \ + _GST_GET (data, 5, 64, 16) | \ + _GST_GET (data, 6, 64, 8) | \ + _GST_GET (data, 7, 64, 0)) + +# define GST_READ_UINT64_LE(data) (_GST_GET (data, 7, 64, 56) | \ + _GST_GET (data, 6, 64, 48) | \ + _GST_GET (data, 5, 64, 40) | \ + _GST_GET (data, 4, 64, 32) | \ + _GST_GET (data, 3, 64, 24) | \ + _GST_GET (data, 2, 64, 16) | \ + _GST_GET (data, 1, 64, 8) | \ + _GST_GET (data, 0, 64, 0)) +#endif /** * GST_READ_UINT32_BE: @@ -150,10 +186,6 @@ void gst_print_element_args (GString *buf, gint indent, GstE * * Read a 32 bit unsigned integer value in big endian format from the memory buffer. */ -#define GST_READ_UINT32_BE(data) (_GST_GET (data, 0, 32, 24) | \ - _GST_GET (data, 1, 32, 16) | \ - _GST_GET (data, 2, 32, 8) | \ - _GST_GET (data, 3, 32, 0)) /** * GST_READ_UINT32_LE: @@ -161,10 +193,25 @@ void gst_print_element_args (GString *buf, gint indent, GstE * * Read a 32 bit unsigned integer value in little endian format from the memory buffer. */ -#define GST_READ_UINT32_LE(data) (_GST_GET (data, 3, 32, 24) | \ - _GST_GET (data, 2, 32, 16) | \ - _GST_GET (data, 1, 32, 8) | \ - _GST_GET (data, 0, 32, 0)) +#if GST_HAVE_UNALIGNED_ACCESS +# if (G_BYTE_ORDER == G_BIG_ENDIAN) +# define GST_READ_UINT32_BE(data) _GST_FAST_READ (32, data) +# define GST_READ_UINT32_LE(data) _GST_FAST_READ_SWAP (32, data) +# else +# define GST_READ_UINT32_BE(data) _GST_FAST_READ_SWAP (32, data) +# define GST_READ_UINT32_LE(data) _GST_FAST_READ (32, data) +# endif +#else +# define GST_READ_UINT32_BE(data) (_GST_GET (data, 0, 32, 24) | \ + _GST_GET (data, 1, 32, 16) | \ + _GST_GET (data, 2, 32, 8) | \ + _GST_GET (data, 3, 32, 0)) + +# define GST_READ_UINT32_LE(data) (_GST_GET (data, 3, 32, 24) | \ + _GST_GET (data, 2, 32, 16) | \ + _GST_GET (data, 1, 32, 8) | \ + _GST_GET (data, 0, 32, 0)) +#endif /** * GST_READ_UINT24_BE: @@ -196,17 +243,27 @@ void gst_print_element_args (GString *buf, gint indent, GstE * * Read a 16 bit unsigned integer value in big endian format from the memory buffer. */ -#define GST_READ_UINT16_BE(data) (_GST_GET (data, 0, 16, 8) | \ - _GST_GET (data, 1, 16, 0)) - /** * GST_READ_UINT16_LE: * @data: memory location * * Read a 16 bit unsigned integer value in little endian format from the memory buffer. */ -#define GST_READ_UINT16_LE(data) (_GST_GET (data, 1, 16, 8) | \ - _GST_GET (data, 0, 16, 0)) +#if GST_HAVE_UNALIGNED_ACCESS +# if (G_BYTE_ORDER == G_BIG_ENDIAN) +# define GST_READ_UINT16_BE(data) _GST_FAST_READ (16, data) +# define GST_READ_UINT16_LE(data) _GST_FAST_READ_SWAP (16, data) +# else +# define GST_READ_UINT16_BE(data) _GST_FAST_READ_SWAP (16, data) +# define GST_READ_UINT16_LE(data) _GST_FAST_READ (16, data) +# endif +#else +# define GST_READ_UINT16_BE(data) (_GST_GET (data, 0, 16, 8) | \ + _GST_GET (data, 1, 16, 0)) + +# define GST_READ_UINT16_LE(data) (_GST_GET (data, 1, 16, 8) | \ + _GST_GET (data, 0, 16, 0)) +#endif /** * GST_READ_UINT8: -- 2.7.4