diff --git a/libs/gst/base/gstbytewriter.c b/libs/gst/base/gstbytewriter.c index 99e0b557c8..6aa940ac8a 100644 --- a/libs/gst/base/gstbytewriter.c +++ b/libs/gst/base/gstbytewriter.c @@ -22,8 +22,8 @@ #include "config.h" #endif +#define GST_BYTE_WRITER_DISABLE_INLINES #include "gstbytewriter.h" -#include /** * SECTION:gstbytewriter @@ -385,19 +385,6 @@ gst_byte_writer_get_remaining (const GstByteWriter * writer) return writer->alloc_size - writer->parent.byte; } -static guint -_next_pow2 (guint n) -{ - guint ret = 16; - - /* We start with 16, smaller allocations make no sense */ - - while (ret < n) - ret <<= 1; - - return ret; -} - /** * gst_byte_writer_ensure_free_space: * @writer: #GstByteWriter instance @@ -413,23 +400,7 @@ _next_pow2 (guint n) gboolean gst_byte_writer_ensure_free_space (GstByteWriter * writer, guint size) { - guint8 *data; - - if (G_UNLIKELY (size <= writer->alloc_size - writer->parent.byte)) - return TRUE; - if (G_UNLIKELY (writer->fixed || !writer->owned)) - return FALSE; - if (G_UNLIKELY (writer->parent.byte > G_MAXUINT - size)) - return FALSE; - - writer->alloc_size = _next_pow2 (writer->parent.byte + size); - data = g_try_realloc ((guint8 *) writer->parent.data, writer->alloc_size); - if (G_UNLIKELY (data == NULL)) - return FALSE; - - writer->parent.data = data; - - return TRUE; + return _gst_byte_writer_ensure_free_space_inline (writer, size); } @@ -437,19 +408,7 @@ gst_byte_writer_ensure_free_space (GstByteWriter * writer, guint size) gboolean \ gst_byte_writer_put_##name (GstByteWriter *writer, type val) \ { \ - guint8 *write_data; \ - \ - g_return_val_if_fail (writer != NULL, FALSE); \ - \ - if (G_UNLIKELY (!gst_byte_writer_ensure_free_space(writer, bits/8))) \ - return FALSE; \ - \ - write_data = (guint8 *) writer->parent.data + writer->parent.byte; \ - write_func (write_data, val); \ - writer->parent.byte += bits/8; \ - writer->parent.size = MAX (writer->parent.size, writer->parent.byte); \ - \ - return TRUE; \ + return _gst_byte_writer_put_##name##_inline (writer, val); \ } CREATE_WRITE_FUNC (8, guint8, uint8, GST_WRITE_UINT8); @@ -480,31 +439,13 @@ gboolean gst_byte_writer_put_data (GstByteWriter * writer, const guint8 * data, guint size) { - g_return_val_if_fail (writer != NULL, FALSE); - - if (G_UNLIKELY (!gst_byte_writer_ensure_free_space (writer, size))) - return FALSE; - - memcpy ((guint8 *) & writer->parent.data[writer->parent.byte], data, size); - writer->parent.byte += size; - writer->parent.size = MAX (writer->parent.size, writer->parent.byte); - - return TRUE; + return _gst_byte_writer_put_data_inline (writer, data, size); } gboolean -gst_byte_writer_fill (GstByteWriter * writer, const guint8 value, guint size) +gst_byte_writer_fill (GstByteWriter * writer, guint8 value, guint size) { - g_return_val_if_fail (writer != NULL, FALSE); - - if (G_UNLIKELY (!gst_byte_writer_ensure_free_space (writer, size))) - return FALSE; - - memset ((guint8 *) & writer->parent.data[writer->parent.byte], value, size); - writer->parent.byte += size; - writer->parent.size = MAX (writer->parent.size, writer->parent.byte); - - return TRUE; + return _gst_byte_writer_fill_inline (writer, value, size); } #define CREATE_WRITE_STRING_FUNC(bits,type) \ @@ -512,6 +453,7 @@ gboolean \ gst_byte_writer_put_string_utf##bits (GstByteWriter *writer, const type * data) \ { \ guint size = 0; \ + \ g_return_val_if_fail (writer != NULL, FALSE); \ \ /* endianness does not matter if we are looking for a NUL terminator */ \ @@ -523,10 +465,10 @@ gst_byte_writer_put_string_utf##bits (GstByteWriter *writer, const type * data) } \ ++size; \ \ - if (G_UNLIKELY (!gst_byte_writer_ensure_free_space(writer, size * (bits / 8)))) \ + if (G_UNLIKELY (!_gst_byte_writer_ensure_free_space_inline(writer, size * (bits / 8)))) \ return FALSE; \ \ - gst_byte_writer_put_data (writer, (const guint8 *) data, size * (bits / 8)); \ + _gst_byte_writer_put_data_inline (writer, (const guint8 *) data, size * (bits / 8)); \ \ return TRUE; \ } diff --git a/libs/gst/base/gstbytewriter.h b/libs/gst/base/gstbytewriter.h index fe1881fb79..35fe44f4c0 100644 --- a/libs/gst/base/gstbytewriter.h +++ b/libs/gst/base/gstbytewriter.h @@ -24,6 +24,8 @@ #include #include +#include + G_BEGIN_DECLS #define GST_BYTE_WRITER(writer) ((GstByteWriter *) (writer)) @@ -144,7 +146,7 @@ gboolean gst_byte_writer_put_float64_be (GstByteWriter *writer, gdouble val); gboolean gst_byte_writer_put_float64_le (GstByteWriter *writer, gdouble val); gboolean gst_byte_writer_put_data (GstByteWriter *writer, const guint8 *data, guint size); -gboolean gst_byte_writer_fill (GstByteWriter *writer, const guint8 value, guint size); +gboolean gst_byte_writer_fill (GstByteWriter *writer, guint8 value, guint size); gboolean gst_byte_writer_put_string_utf8 (GstByteWriter *writer, const gchar *data); gboolean gst_byte_writer_put_string_utf16 (GstByteWriter *writer, const guint16 *data); gboolean gst_byte_writer_put_string_utf32 (GstByteWriter *writer, const guint32 *data); @@ -165,6 +167,176 @@ gboolean gst_byte_writer_put_string_utf32 (GstByteWriter *writer, const guint32 #define gst_byte_writer_put_string(writer, data) \ gst_byte_writer_put_string_utf8(writer, data) +static inline guint +_gst_byte_writer_next_pow2 (guint n) +{ + guint ret = 16; + + /* We start with 16, smaller allocations make no sense */ + + while (ret < n) + ret <<= 1; + + return ret; +} + +static inline gboolean +_gst_byte_writer_ensure_free_space_inline (GstByteWriter * writer, guint size) +{ + guint8 *data; + + if (G_LIKELY (size <= writer->alloc_size - writer->parent.byte)) + return TRUE; + if (G_UNLIKELY (writer->fixed || !writer->owned)) + return FALSE; + if (G_UNLIKELY (writer->parent.byte > G_MAXUINT - size)) + return FALSE; + + writer->alloc_size = _gst_byte_writer_next_pow2 (writer->parent.byte + size); + data = g_try_realloc ((guint8 *) writer->parent.data, writer->alloc_size); + if (G_UNLIKELY (data == NULL)) + return FALSE; + + writer->parent.data = data; + + return TRUE; +} + +#define __GST_BYTE_WRITER_CREATE_WRITE_FUNC(bits,type,name,write_func) \ +static inline gboolean \ +_gst_byte_writer_put_##name##_inline (GstByteWriter *writer, type val) \ +{ \ + guint8 *write_data; \ + \ + g_return_val_if_fail (writer != NULL, FALSE); \ + \ + if (G_UNLIKELY (!_gst_byte_writer_ensure_free_space_inline(writer, bits/8))) \ + return FALSE; \ + \ + write_data = (guint8 *) writer->parent.data + writer->parent.byte; \ + write_func (write_data, val); \ + writer->parent.byte += bits/8; \ + writer->parent.size = MAX (writer->parent.size, writer->parent.byte); \ + \ + return TRUE; \ +} + +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (8, guint8, uint8, GST_WRITE_UINT8) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (8, gint8, int8, GST_WRITE_UINT8) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (16, guint16, uint16_le, GST_WRITE_UINT16_LE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (16, guint16, uint16_be, GST_WRITE_UINT16_BE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (16, gint16, int16_le, GST_WRITE_UINT16_LE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (16, gint16, int16_be, GST_WRITE_UINT16_BE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (24, guint32, uint24_le, GST_WRITE_UINT24_LE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (24, guint32, uint24_be, GST_WRITE_UINT24_BE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (24, gint32, int24_le, GST_WRITE_UINT24_LE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (24, gint32, int24_be, GST_WRITE_UINT24_BE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (32, guint32, uint32_le, GST_WRITE_UINT32_LE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (32, guint32, uint32_be, GST_WRITE_UINT32_BE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (32, gint32, int32_le, GST_WRITE_UINT32_LE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (32, gint32, int32_be, GST_WRITE_UINT32_BE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (64, guint64, uint64_le, GST_WRITE_UINT64_LE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (64, guint64, uint64_be, GST_WRITE_UINT64_BE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (64, gint64, int64_le, GST_WRITE_UINT64_LE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (64, gint64, int64_be, GST_WRITE_UINT64_BE) + +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (32, gfloat, float32_be, GST_WRITE_FLOAT_BE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (32, gfloat, float32_le, GST_WRITE_FLOAT_LE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (64, gdouble, float64_be, GST_WRITE_DOUBLE_BE) +__GST_BYTE_WRITER_CREATE_WRITE_FUNC (64, gdouble, float64_le, GST_WRITE_DOUBLE_LE) + +#undef __GST_BYTE_WRITER_CREATE_WRITE_FUNC + +static inline gboolean +_gst_byte_writer_put_data_inline (GstByteWriter * writer, const guint8 * data, + guint size) +{ + g_return_val_if_fail (writer != NULL, FALSE); + + if (G_UNLIKELY (!_gst_byte_writer_ensure_free_space_inline (writer, size))) + return FALSE; + + memcpy ((guint8 *) & writer->parent.data[writer->parent.byte], data, size); + writer->parent.byte += size; + writer->parent.size = MAX (writer->parent.size, writer->parent.byte); + + return TRUE; +} + +static inline gboolean +_gst_byte_writer_fill_inline (GstByteWriter * writer, guint8 value, guint size) +{ + g_return_val_if_fail (writer != NULL, FALSE); + + if (G_UNLIKELY (!_gst_byte_writer_ensure_free_space_inline (writer, size))) + return FALSE; + + memset ((guint8 *) & writer->parent.data[writer->parent.byte], value, size); + writer->parent.byte += size; + writer->parent.size = MAX (writer->parent.size, writer->parent.byte); + + return TRUE; +} + +#ifndef GST_BYTE_WRITER_DISABLE_INLINES + +/* we use defines here so we can add the G_LIKELY() */ + +#define gst_byte_writer_ensure_free_space(writer, size) \ + G_LIKELY (_gst_byte_writer_ensure_free_space_inline (writer, size)) +#define gst_byte_writer_put_uint8(writer, val) \ + G_LIKELY (_gst_byte_writer_put_uint8_inline (writer, val)) +#define gst_byte_writer_put_int8(writer, val) \ + G_LIKELY (_gst_byte_writer_put_int8_inline (writer, val)) +#define gst_byte_writer_put_uint16_be(writer, val) \ + G_LIKELY (_gst_byte_writer_put_uint16_be_inline (writer, val)) +#define gst_byte_writer_put_uint16_le(writer, val) \ + G_LIKELY (_gst_byte_writer_put_uint16_le_inline (writer, val)) +#define gst_byte_writer_put_int16_be(writer, val) \ + G_LIKELY (_gst_byte_writer_put_int16_be_inline (writer, val)) +#define gst_byte_writer_put_int16_le(writer, val) \ + G_LIKELY (_gst_byte_writer_put_int16_le_inline (writer, val)) +#define gst_byte_writer_put_uint24_be(writer, val) \ + G_LIKELY (_gst_byte_writer_put_uint24_be_inline (writer, val)) +#define gst_byte_writer_put_uint24_le(writer, val) \ + G_LIKELY (_gst_byte_writer_put_uint24_le_inline (writer, val)) +#define gst_byte_writer_put_int24_be(writer, val) \ + G_LIKELY (_gst_byte_writer_put_int24_be_inline (writer, val)) +#define gst_byte_writer_put_int24_le(writer, val) \ + G_LIKELY (_gst_byte_writer_put_int24_le_inline (writer, val)) +#define gst_byte_writer_put_uint32_be(writer, val) \ + G_LIKELY (_gst_byte_writer_put_uint32_be_inline (writer, val)) +#define gst_byte_writer_put_uint32_le(writer, val) \ + G_LIKELY (_gst_byte_writer_put_uint32_le_inline (writer, val)) +#define gst_byte_writer_put_int32_be(writer, val) \ + G_LIKELY (_gst_byte_writer_put_int32_be_inline (writer, val)) +#define gst_byte_writer_put_int32_le(writer, val) \ + G_LIKELY (_gst_byte_writer_put_int32_le_inline (writer, val)) +#define gst_byte_writer_put_uint64_be(writer, val) \ + G_LIKELY (_gst_byte_writer_put_uint64_be_inline (writer, val)) +#define gst_byte_writer_put_uint64_le(writer, val) \ + G_LIKELY (_gst_byte_writer_put_uint64_le_inline (writer, val)) +#define gst_byte_writer_put_int64_be(writer, val) \ + G_LIKELY (_gst_byte_writer_put_int64_be_inline (writer, val)) +#define gst_byte_writer_put_int64_le(writer, val) \ + G_LIKELY (_gst_byte_writer_put_int64_le_inline (writer, val)) + +#define gst_byte_writer_put_float32_be(writer, val) \ + G_LIKELY (_gst_byte_writer_put_float32_be_inline (writer, val)) +#define gst_byte_writer_put_float32_le(writer, val) \ + G_LIKELY (_gst_byte_writer_put_float32_le_inline (writer, val)) +#define gst_byte_writer_put_float64_be(writer, val) \ + G_LIKELY (_gst_byte_writer_put_float64_be_inline (writer, val)) +#define gst_byte_writer_put_float64_le(writer, val) \ + G_LIKELY (_gst_byte_writer_put_float64_le_inline (writer, val)) + +#define gst_byte_writer_put_data(writer, data, size) \ + G_LIKELY (_gst_byte_writer_put_data_inline (writer, data, size)) +#define gst_byte_writer_fill(writer, val, size) \ + G_LIKELY (_gst_byte_writer_fill_inline (writer, val, size)) + +#endif + G_END_DECLS #endif /* __GST_BYTE_WRITER_H__ */