diff --git a/ChangeLog b/ChangeLog index 54db78ee41..d311274b07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2004-04-12 David Schleef + + * gst/gstbuffer.c: (_gst_buffer_initialize), (gst_buffer_get_type), + (gst_buffer_free_chunk): Added gst_buffer_get_type() and changed + to using it. + * gst/gstbuffer.h: Changed GST_BUFFER_TYPE to gst_buffer_get_type() + * gst/gstcaps.c: (gst_caps_is_fixed_foreach): Buffer is a fixed type + * gst/gstpad.c: (_gst_pad_default_fixate_foreach): same + * gst/gststructure.c: (gst_structure_set_valist), + (gst_structure_from_abbr), (gst_structure_to_abbr): Add vararg + support for buffers. + * gst/gsttag.c: (gst_tag_register): Constify a prototype that was + intended to be const. + * gst/gsttag.h: same + * gst/gstvalue.c: (gst_value_serialize_buffer), + (gst_value_deserialize_buffer), (_gst_value_initialize): Add code + to (de)serialize buffers. + * testsuite/caps/Makefile.am: Add a bit of buffer testing + * testsuite/caps/string-conversions.c: (main): + * testsuite/caps/value_serialize.c: add new test + 2004-04-11 Ronald Bultje * docs/pwg/advanced-types.xml: diff --git a/gst/gstbuffer.c b/gst/gstbuffer.c index b7f88370de..f9e3c14fe9 100644 --- a/gst/gstbuffer.c +++ b/gst/gstbuffer.c @@ -45,8 +45,7 @@ static void gst_buffer_free_chunk (GstBuffer * buffer); void _gst_buffer_initialize (void) { - _gst_buffer_type = g_boxed_type_register_static ("GstBuffer", - (GBoxedCopyFunc) gst_data_copy, (GBoxedFreeFunc) gst_data_unref); + gst_buffer_get_type (); #ifndef GST_DISABLE_TRACE _gst_buffer_trace = gst_alloc_trace_register (GST_BUFFER_TRACE_NAME); @@ -61,6 +60,10 @@ _gst_buffer_initialize (void) GType gst_buffer_get_type (void) { + if (_gst_buffer_type == 0) { + _gst_buffer_type = g_boxed_type_register_static ("GstBuffer", + (GBoxedCopyFunc) gst_data_copy, (GBoxedFreeFunc) gst_data_unref); + } return _gst_buffer_type; } diff --git a/gst/gstbuffer.h b/gst/gstbuffer.h index 8926f0faa2..44d0569b1d 100644 --- a/gst/gstbuffer.h +++ b/gst/gstbuffer.h @@ -37,7 +37,7 @@ typedef void (*GstBufferFreeDataFunc) (GstBuffer *buffer); extern GType _gst_buffer_type; -#define GST_TYPE_BUFFER (_gst_buffer_type) +#define GST_TYPE_BUFFER (gst_buffer_get_type()) #define GST_BUFFER(buf) ((GstBuffer *)(buf)) #define GST_IS_BUFFER(buf) (GST_DATA_TYPE(buf) == GST_TYPE_BUFFER) diff --git a/gst/gstcaps.c b/gst/gstcaps.c index ba492bf2e3..22ff2bbad9 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -531,6 +531,8 @@ gst_caps_is_fixed_foreach (GQuark field_id, GValue * value, gpointer unused) return TRUE; if (type == GST_TYPE_FOURCC) return TRUE; + if (type == GST_TYPE_BUFFER) + return TRUE; return FALSE; } diff --git a/gst/gstpad.c b/gst/gstpad.c index bb5ef99aec..8ae7c6fdd1 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -1992,7 +1992,8 @@ _gst_pad_default_fixate_foreach (GQuark field_id, GValue * value, gpointer s) GstStructure *structure = (GstStructure *) s; GType type = G_VALUE_TYPE (value); - if (G_TYPE_IS_FUNDAMENTAL (type) || type == GST_TYPE_FOURCC) + if (G_TYPE_IS_FUNDAMENTAL (type) || type == GST_TYPE_FOURCC || + type == GST_TYPE_BUFFER) return TRUE; if (type == GST_TYPE_INT_RANGE) { diff --git a/gst/gststructure.c b/gst/gststructure.c index 70f8fc4d46..d420e2184b 100644 --- a/gst/gststructure.c +++ b/gst/gststructure.c @@ -406,6 +406,11 @@ gst_structure_set_valist (GstStructure * structure, g_value_init (&field.value, GST_TYPE_DOUBLE_RANGE); gst_value_set_double_range (&field.value, min, max); + } else if (type == GST_TYPE_BUFFER) { + GstBuffer *buffer = va_arg (varargs, GstBuffer *); + + g_value_init (&field.value, GST_TYPE_BUFFER); + g_value_set_boxed (&field.value, buffer); } else { g_critical ("unimplemented vararg field type %d\n", (int) type); return; @@ -988,6 +993,9 @@ gst_structure_from_abbr (const char *type_name) if (strcmp (type_name, "fourcc") == 0 || strcmp (type_name, "4") == 0) { return GST_TYPE_FOURCC; } + if (strcmp (type_name, "buffer") == 0) { + return GST_TYPE_BUFFER; + } return g_type_from_name (type_name); } @@ -1009,6 +1017,9 @@ gst_structure_to_abbr (GType type) if (type == GST_TYPE_FOURCC) { return "fourcc"; } + if (type == GST_TYPE_BUFFER) { + return "buffer"; + } return g_type_name (type); } diff --git a/gst/gsttag.c b/gst/gsttag.c index 2ec9945f1e..6285c67f76 100644 --- a/gst/gsttag.c +++ b/gst/gsttag.c @@ -264,8 +264,8 @@ gst_tag_lookup (GQuark entry) * This function takes ownership of all supplied variables. */ void -gst_tag_register (gchar * name, GstTagFlag flag, GType type, - gchar * nick, gchar * blurb, GstTagMergeFunc func) +gst_tag_register (const gchar * name, GstTagFlag flag, GType type, + const gchar * nick, const gchar * blurb, GstTagMergeFunc func) { GQuark key; GstTagInfo *info; @@ -282,8 +282,8 @@ gst_tag_register (gchar * name, GstTagFlag flag, GType type, info = g_new (GstTagInfo, 1); info->flag = flag; info->type = type; - info->nick = nick; - info->blurb = blurb; + info->nick = g_strdup (nick); + info->blurb = g_strdup (blurb); info->merge_func = func; TAG_LOCK; diff --git a/gst/gsttag.h b/gst/gsttag.h index a91ab8f907..52c923e0a7 100644 --- a/gst/gsttag.h +++ b/gst/gsttag.h @@ -62,11 +62,11 @@ typedef void (* GstTagMergeFunc) (GValue *dest, const GValue *src); void _gst_tag_initialize (void); GType gst_tag_list_get_type (void); -void gst_tag_register (gchar * name, +void gst_tag_register (const gchar * name, GstTagFlag flag, GType type, - gchar * nick, - gchar * blurb, + const gchar * nick, + const gchar * blurb, GstTagMergeFunc func); /* some default merging functions */ void gst_tag_merge_use_first (GValue * dest, diff --git a/gst/gsttaglist.c b/gst/gsttaglist.c index 2ec9945f1e..6285c67f76 100644 --- a/gst/gsttaglist.c +++ b/gst/gsttaglist.c @@ -264,8 +264,8 @@ gst_tag_lookup (GQuark entry) * This function takes ownership of all supplied variables. */ void -gst_tag_register (gchar * name, GstTagFlag flag, GType type, - gchar * nick, gchar * blurb, GstTagMergeFunc func) +gst_tag_register (const gchar * name, GstTagFlag flag, GType type, + const gchar * nick, const gchar * blurb, GstTagMergeFunc func) { GQuark key; GstTagInfo *info; @@ -282,8 +282,8 @@ gst_tag_register (gchar * name, GstTagFlag flag, GType type, info = g_new (GstTagInfo, 1); info->flag = flag; info->type = type; - info->nick = nick; - info->blurb = blurb; + info->nick = g_strdup (nick); + info->blurb = g_strdup (blurb); info->merge_func = func; TAG_LOCK; diff --git a/gst/gsttaglist.h b/gst/gsttaglist.h index a91ab8f907..52c923e0a7 100644 --- a/gst/gsttaglist.h +++ b/gst/gsttaglist.h @@ -62,11 +62,11 @@ typedef void (* GstTagMergeFunc) (GValue *dest, const GValue *src); void _gst_tag_initialize (void); GType gst_tag_list_get_type (void); -void gst_tag_register (gchar * name, +void gst_tag_register (const gchar * name, GstTagFlag flag, GType type, - gchar * nick, - gchar * blurb, + const gchar * nick, + const gchar * blurb, GstTagMergeFunc func); /* some default merging functions */ void gst_tag_merge_use_first (GValue * dest, diff --git a/gst/gstvalue.c b/gst/gstvalue.c index 80ad010a4b..0f39321ef3 100644 --- a/gst/gstvalue.c +++ b/gst/gstvalue.c @@ -22,6 +22,7 @@ #endif #include #include +#include #include #include @@ -768,6 +769,67 @@ gst_value_get_caps (const GValue * value) return (GstCaps *) g_value_get_boxed (value); } +/*************************************/ +/* GstBuffer */ + +static char * +gst_value_serialize_buffer (const GValue * value) +{ + guint8 *data; + int i; + int size; + char *string; + GstBuffer *buffer = g_value_get_boxed (value); + + data = GST_BUFFER_DATA (buffer); + size = GST_BUFFER_SIZE (buffer); + + string = malloc (size * 2 + 1); + for (i = 0; i < size; i++) { + sprintf (string + i * 2, "%02x", data[i]); + } + string[size * 2] = 0; + + return string; +} + +static gboolean +gst_value_deserialize_buffer (GValue * dest, const char *s) +{ + GstBuffer *buffer; + gboolean ret = TRUE; + int len; + char ts[3]; + guint8 *data; + int i; + + len = strlen (s); + if (len & 1) + return FALSE; + buffer = gst_buffer_new_and_alloc (len / 2); + data = GST_BUFFER_DATA (buffer); + for (i = 0; i < len / 2; i++) { + if (!isxdigit (s[i * 2]) || !isxdigit (s[i * 2 + 1])) { + ret = FALSE; + break; + } + ts[0] = s[i * 2 + 0]; + ts[1] = s[i * 2 + 1]; + ts[2] = 0; + + data[i] = strtoul (ts, NULL, 16); + } + + if (ret) { + g_value_set_boxed (dest, buffer); + return TRUE; + } else { + gst_buffer_unref (buffer); + return FALSE; + } +} + + /*************************************/ /* boolean */ @@ -1631,6 +1693,35 @@ _gst_value_initialize (void) gst_value_register (&gst_value); } + { +#if 0 + static const GTypeValueTable value_table = { + gst_value_init_buffer, + NULL, + gst_value_copy_buffer, + NULL, + "i", + NULL, /*gst_value_collect_buffer, */ + "p", + NULL /*gst_value_lcopy_buffer */ + }; +#endif + static GstValueTable gst_value = { + 0, + NULL, /*gst_value_compare_buffer, */ + gst_value_serialize_buffer, + gst_value_deserialize_buffer, + }; + +#if 0 + info.value_table = &value_table; + gst_type_fourcc = + g_type_register_static (G_TYPE_BOXED, "GstFourcc", &info, 0); +#endif + gst_value.type = GST_TYPE_BUFFER; + gst_value_register (&gst_value); + } + { static const GstValueTable gst_value = { G_TYPE_INT, diff --git a/tests/old/testsuite/caps/Makefile.am b/tests/old/testsuite/caps/Makefile.am index a0dd4a4105..9061cf87d4 100644 --- a/tests/old/testsuite/caps/Makefile.am +++ b/tests/old/testsuite/caps/Makefile.am @@ -13,6 +13,7 @@ tests_pass = \ caps \ value_compare \ value_intersect \ + value_serialize \ audioscale tests_fail = diff --git a/tests/old/testsuite/caps/string-conversions.c b/tests/old/testsuite/caps/string-conversions.c index c37298dc71..c8e9c43759 100644 --- a/tests/old/testsuite/caps/string-conversions.c +++ b/tests/old/testsuite/caps/string-conversions.c @@ -136,6 +136,9 @@ bla: test_string ("audio/raw ,test=(b ) yes"); test_string ("audio/raw ,test =( boolean)no"); + /* buffers */ + test_string ("audio/raw ,test=(buffer)0123456789abcdef"); + /* unfixed props entries */ test_string ("audio/raw, test= [ 1, 2 ]"); test_string_fail ("audio/raw, test= [ 1.0 , 2]"); diff --git a/tests/old/testsuite/caps/value_serialize.c b/tests/old/testsuite/caps/value_serialize.c new file mode 100644 index 0000000000..a328f11b0c --- /dev/null +++ b/tests/old/testsuite/caps/value_serialize.c @@ -0,0 +1,26 @@ + +#include +#include + +void +test1 (void) +{ + GValue value = { 0 }; + gboolean ret; + + g_value_init (&value, GST_TYPE_BUFFER); + ret = gst_value_deserialize (&value, "1234567890abcdef"); + g_assert (ret); + +} + +int +main (int argc, char *argv[]) +{ + gst_init (&argc, &argv); + + test1 (); + + return 0; + +} diff --git a/testsuite/caps/Makefile.am b/testsuite/caps/Makefile.am index a0dd4a4105..9061cf87d4 100644 --- a/testsuite/caps/Makefile.am +++ b/testsuite/caps/Makefile.am @@ -13,6 +13,7 @@ tests_pass = \ caps \ value_compare \ value_intersect \ + value_serialize \ audioscale tests_fail = diff --git a/testsuite/caps/string-conversions.c b/testsuite/caps/string-conversions.c index c37298dc71..c8e9c43759 100644 --- a/testsuite/caps/string-conversions.c +++ b/testsuite/caps/string-conversions.c @@ -136,6 +136,9 @@ bla: test_string ("audio/raw ,test=(b ) yes"); test_string ("audio/raw ,test =( boolean)no"); + /* buffers */ + test_string ("audio/raw ,test=(buffer)0123456789abcdef"); + /* unfixed props entries */ test_string ("audio/raw, test= [ 1, 2 ]"); test_string_fail ("audio/raw, test= [ 1.0 , 2]"); diff --git a/testsuite/caps/value_serialize.c b/testsuite/caps/value_serialize.c new file mode 100644 index 0000000000..a328f11b0c --- /dev/null +++ b/testsuite/caps/value_serialize.c @@ -0,0 +1,26 @@ + +#include +#include + +void +test1 (void) +{ + GValue value = { 0 }; + gboolean ret; + + g_value_init (&value, GST_TYPE_BUFFER); + ret = gst_value_deserialize (&value, "1234567890abcdef"); + g_assert (ret); + +} + +int +main (int argc, char *argv[]) +{ + gst_init (&argc, &argv); + + test1 (); + + return 0; + +}