From: Jonas Holmberg Date: Tue, 12 May 2009 10:08:56 +0000 (+0200) Subject: bufferlist: add docs/build/debug/unittest X-Git-Tag: RELEASE-0.10.24~285 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d99cf4db1bea74c3ee4ac0072e89b7fafaadec6e;p=platform%2Fupstream%2Fgstreamer.git bufferlist: add docs/build/debug/unittest See #572285 --- diff --git a/docs/gst/gstreamer-docs.sgml b/docs/gst/gstreamer-docs.sgml index c0051e5..7647431 100644 --- a/docs/gst/gstreamer-docs.sgml +++ b/docs/gst/gstreamer-docs.sgml @@ -50,6 +50,7 @@ Windows. It is released under the GNU Library General Public License + diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index cf2d7e2..38aafbf 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -208,6 +208,45 @@ gst_buffer_flag_get_type gst_buffer_copy_flags_get_type +
+gstbufferlist +GstBufferList +GstBufferList +GstBufferListIterator +GstBufferListDoFunction +GstBufferListDoDataFunction +gst_buffer_list_new +gst_buffer_list_ref +gst_buffer_list_unref +gst_buffer_list_copy +gst_buffer_list_is_writable +gst_buffer_list_make_writable +gst_buffer_list_n_groups +gst_buffer_list_iterate +gst_buffer_list_iterator_free +gst_buffer_list_iterator_n_buffers +gst_buffer_list_iterator_add +gst_buffer_list_iterator_add_group +gst_buffer_list_iterator_next +gst_buffer_list_iterator_next_group +gst_buffer_list_iterator_remove +gst_buffer_list_iterator_steal +gst_buffer_list_iterator_take +gst_buffer_list_iterator_do +gst_buffer_list_iterator_do_data +gst_buffer_list_iterator_merge_group + +GstBufferListClass +GST_BUFFER_LIST +GST_BUFFER_LIST_CLASS +GST_BUFFER_LIST_GET_CLASS +GST_IS_BUFFER_LIST +GST_IS_BUFFER_LIST_CLASS +GST_TYPE_BUFFER_LIST +GST_BUFFER_LIST_CAST + +gst_buffer_list_get_type +
gstcaps diff --git a/gst/Makefile.am b/gst/Makefile.am index e988856..8d6f2fb 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -56,6 +56,7 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \ gstobject.c \ gstbin.c \ gstbuffer.c \ + gstbufferlist.c \ gstbus.c \ gstcaps.c \ gstchildproxy.c \ @@ -142,6 +143,7 @@ gst_headers = \ gstobject.h \ gstbin.h \ gstbuffer.h \ + gstbufferlist.h \ gstbus.h \ gstcaps.h \ gstchildproxy.h \ diff --git a/gst/gst.c b/gst/gst.c index 048190c..8d5e461 100644 --- a/gst/gst.c +++ b/gst/gst.c @@ -1067,6 +1067,7 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data, gst_caps_get_type (); _gst_event_initialize (); _gst_buffer_initialize (); + _gst_buffer_list_initialize (); _gst_message_initialize (); _gst_tag_initialize (); diff --git a/gst/gst.h b/gst/gst.h index 8920de9..4a92948 100644 --- a/gst/gst.h +++ b/gst/gst.h @@ -33,6 +33,7 @@ #include #include +#include #include #include #include diff --git a/gst/gst_private.h b/gst/gst_private.h index 5c1d8f4..c54bf19 100644 --- a/gst/gst_private.h +++ b/gst/gst_private.h @@ -85,6 +85,7 @@ void _priv_gst_quarks_initialize (void); * headers, so at least the symbols need to continue to be available unless * we want enterprise edition packagers dancing on our heads) */ void _gst_buffer_initialize (void); +void _gst_buffer_list_initialize (void); void _gst_event_initialize (void); void _gst_format_initialize (void); void _gst_message_initialize (void); @@ -119,6 +120,7 @@ GST_EXPORT GstDebugCategory *GST_CAT_PARENTAGE; GST_EXPORT GstDebugCategory *GST_CAT_STATES; GST_EXPORT GstDebugCategory *GST_CAT_SCHEDULING; GST_EXPORT GstDebugCategory *GST_CAT_BUFFER; +GST_EXPORT GstDebugCategory *GST_CAT_BUFFER_LIST; GST_EXPORT GstDebugCategory *GST_CAT_BUS; GST_EXPORT GstDebugCategory *GST_CAT_CAPS; GST_EXPORT GstDebugCategory *GST_CAT_CLOCK; @@ -152,6 +154,7 @@ GST_EXPORT GstDebugCategory *GST_CAT_TYPES; /* FIXME 0.11: remove? */ #define GST_CAT_SCHEDULING NULL #define GST_CAT_DATAFLOW NULL #define GST_CAT_BUFFER NULL +#define GST_CAT_BUFFER_LIST NULL #define GST_CAT_BUS NULL #define GST_CAT_CAPS NULL #define GST_CAT_CLOCK NULL diff --git a/gst/gstinfo.c b/gst/gstinfo.c index 35d583f..06b5c3e 100644 --- a/gst/gstinfo.c +++ b/gst/gstinfo.c @@ -222,6 +222,7 @@ GstDebugCategory *GST_CAT_STATES = NULL; GstDebugCategory *GST_CAT_SCHEDULING = NULL; GstDebugCategory *GST_CAT_BUFFER = NULL; +GstDebugCategory *GST_CAT_BUFFER_LIST = NULL; GstDebugCategory *GST_CAT_BUS = NULL; GstDebugCategory *GST_CAT_CAPS = NULL; GstDebugCategory *GST_CAT_CLOCK = NULL; @@ -330,6 +331,8 @@ _gst_debug_init (void) GST_DEBUG_BOLD | GST_DEBUG_FG_MAGENTA, NULL); GST_CAT_BUFFER = _gst_debug_category_new ("GST_BUFFER", GST_DEBUG_BOLD | GST_DEBUG_BG_GREEN, NULL); + GST_CAT_BUFFER_LIST = _gst_debug_category_new ("GST_BUFFER_LIST", + GST_DEBUG_BOLD | GST_DEBUG_BG_GREEN, NULL); GST_CAT_BUS = _gst_debug_category_new ("GST_BUS", GST_DEBUG_BG_YELLOW, NULL); GST_CAT_CAPS = _gst_debug_category_new ("GST_CAPS", GST_DEBUG_BOLD | GST_DEBUG_FG_BLUE, NULL); diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index d3f30b4..31644e1 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -76,6 +76,7 @@ endif check_PROGRAMS = \ gst/gstabi \ gst/gstbuffer \ + gst/gstbufferlist \ gst/gstbus \ gst/gstcaps \ gst/gstinfo \ diff --git a/tests/check/gst/.gitignore b/tests/check/gst/.gitignore index b38e3b0..7f9374f 100644 --- a/tests/check/gst/.gitignore +++ b/tests/check/gst/.gitignore @@ -3,6 +3,7 @@ gst gstabi gstbin gstbuffer +gstbufferlist gstbus gstcaps gstdata diff --git a/tests/check/gst/gstbufferlist.c b/tests/check/gst/gstbufferlist.c new file mode 100644 index 0000000..6372af2 --- /dev/null +++ b/tests/check/gst/gstbufferlist.c @@ -0,0 +1,667 @@ +/* GStreamer + * + * unit test for GstBufferList + * + * Copyright (C) 2009 Axis Communications + * @author Jonas Holmberg + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +#define TIMESTAMP 42 + +static GstBufferList *list; +static GstCaps *caps; + +static void +setup (void) +{ + list = gst_buffer_list_new (); + caps = gst_caps_new_simple ("text/plain", NULL); +} + +static void +cleanup (void) +{ + gst_caps_unref (caps); + gst_buffer_list_unref (list); +} + +static GstBuffer * +buffer_from_string (gchar * str) +{ + guint size; + GstBuffer *buf; + + size = strlen (str); + buf = gst_buffer_new_and_alloc (size); + gst_buffer_set_caps (buf, caps); + GST_BUFFER_TIMESTAMP (buf) = TIMESTAMP; + memcpy (GST_BUFFER_DATA (buf), str, size); + GST_BUFFER_SIZE (buf) = size; + + return buf; +} + +GST_START_TEST (test_add_and_iterate) +{ + GstBufferListIterator *it; + GstBuffer *buf1; + GstBuffer *buf2; + GstBuffer *buf3; + GstBuffer *buf4; + GstBuffer *buf; + + /* buffer list is initially empty */ + fail_unless (gst_buffer_list_n_groups (list) == 0); + + it = gst_buffer_list_iterate (list); + + ASSERT_CRITICAL (gst_buffer_list_iterator_add (it, NULL)); + ASSERT_CRITICAL (gst_buffer_list_iterator_add (NULL, NULL)); + + /* cannot add buffer without adding a group first */ + buf1 = gst_buffer_new (); + ASSERT_CRITICAL (gst_buffer_list_iterator_add (it, buf1)); + + /* add a group of 2 buffers */ + fail_unless (gst_buffer_list_iterator_n_buffers (it) == 0); + gst_buffer_list_iterator_add_group (it); + fail_unless (gst_buffer_list_n_groups (list) == 1); + ASSERT_CRITICAL (gst_buffer_list_iterator_add (it, NULL)); + ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 1); + gst_buffer_list_iterator_add (it, buf1); + ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 1); /* list takes ownership */ + fail_unless (gst_buffer_list_n_groups (list) == 1); + fail_unless (gst_buffer_list_iterator_n_buffers (it) == 0); + buf2 = gst_buffer_new (); + gst_buffer_list_iterator_add (it, buf2); + ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 1); + fail_unless (gst_buffer_list_n_groups (list) == 1); + fail_unless (gst_buffer_list_iterator_n_buffers (it) == 0); + + /* add another group of 2 buffers */ + gst_buffer_list_iterator_add_group (it); + fail_unless (gst_buffer_list_n_groups (list) == 2); + buf3 = gst_buffer_new (); + gst_buffer_list_iterator_add (it, buf3); + ASSERT_BUFFER_REFCOUNT (buf3, "buf3", 1); + fail_unless (gst_buffer_list_n_groups (list) == 2); + fail_unless (gst_buffer_list_iterator_n_buffers (it) == 0); + buf4 = gst_buffer_new (); + gst_buffer_list_iterator_add (it, buf4); + ASSERT_BUFFER_REFCOUNT (buf4, "buf4", 1); + fail_unless (gst_buffer_list_n_groups (list) == 2); + fail_unless (gst_buffer_list_iterator_n_buffers (it) == 0); + + /* freeing iterator does not affect list */ + gst_buffer_list_iterator_free (it); + fail_unless (gst_buffer_list_n_groups (list) == 2); + + /* create a new iterator */ + it = gst_buffer_list_iterate (list); + + /* iterate list */ + fail_unless (gst_buffer_list_iterator_next (it) == NULL); + fail_unless (gst_buffer_list_iterator_next_group (it)); + fail_unless (gst_buffer_list_iterator_n_buffers (it) == 2); + buf = gst_buffer_list_iterator_next (it); + fail_unless (buf == buf1); + fail_unless (gst_buffer_list_iterator_n_buffers (it) == 1); + buf = gst_buffer_list_iterator_next (it); + fail_unless (buf == buf2); + fail_unless (gst_buffer_list_iterator_n_buffers (it) == 0); + fail_unless (gst_buffer_list_iterator_next (it) == NULL); + fail_unless (gst_buffer_list_iterator_next_group (it)); + fail_unless (gst_buffer_list_iterator_n_buffers (it) == 2); + buf = gst_buffer_list_iterator_next (it); + fail_unless (buf == buf3); + fail_unless (gst_buffer_list_iterator_n_buffers (it) == 1); + buf = gst_buffer_list_iterator_next (it); + fail_unless (buf == buf4); + fail_unless (gst_buffer_list_iterator_n_buffers (it) == 0); + fail_unless (gst_buffer_list_iterator_next (it) == NULL); + fail_if (gst_buffer_list_iterator_next_group (it)); + + gst_buffer_list_iterator_free (it); +} + +GST_END_TEST; + +GST_START_TEST (test_make_writable) +{ + GstBufferListIterator *it; + GstBufferList *wlist; + GstBuffer *buf1; + GstBuffer *buf2; + GstBuffer *buf3; + GstBuffer *buf; + + /* add buffers to list */ + it = gst_buffer_list_iterate (list); + gst_buffer_list_iterator_add_group (it); + buf1 = gst_buffer_new_and_alloc (1); + gst_buffer_list_iterator_add (it, buf1); + gst_buffer_list_iterator_add_group (it); + buf2 = gst_buffer_new_and_alloc (2); + gst_buffer_list_iterator_add (it, buf2); + buf3 = gst_buffer_new_and_alloc (3); + gst_buffer_list_iterator_add (it, buf3); + gst_buffer_list_iterator_free (it); + + /* making it writable with refcount 1 returns the same list */ + wlist = gst_buffer_list_make_writable (list); + fail_unless (wlist == list); + it = gst_buffer_list_iterate (list); + fail_unless (gst_buffer_list_iterator_next_group (it)); + buf = gst_buffer_list_iterator_next (it); + fail_unless (buf == buf1); + ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 1); + fail_unless (gst_buffer_list_iterator_next (it) == NULL); + fail_unless (gst_buffer_list_iterator_next_group (it)); + buf = gst_buffer_list_iterator_next (it); + fail_unless (buf == buf2); + ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 1); + buf = gst_buffer_list_iterator_next (it); + fail_unless (buf == buf3); + ASSERT_BUFFER_REFCOUNT (buf3, "buf3", 1); + fail_unless (gst_buffer_list_iterator_next (it) == NULL); + fail_if (gst_buffer_list_iterator_next_group (it)); + gst_buffer_list_iterator_free (it); + + /* making it writable with refcount 2 returns a copy of the list with + * increased refcount on the buffers in the list */ + gst_buffer_list_ref (list); + fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (list) == 2); + wlist = gst_buffer_list_make_writable (list); + fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (list) == 1); + fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (wlist) == 1); + fail_unless (wlist != list); + it = gst_buffer_list_iterate (wlist); + fail_unless (gst_buffer_list_iterator_next_group (it)); + buf = gst_buffer_list_iterator_next (it); + fail_unless (buf == buf1); + ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 2); + fail_unless (gst_buffer_list_iterator_next (it) == NULL); + fail_unless (gst_buffer_list_iterator_next_group (it)); + buf = gst_buffer_list_iterator_next (it); + fail_unless (buf == buf2); + ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 2); + buf = gst_buffer_list_iterator_next (it); + fail_unless (buf == buf3); + ASSERT_BUFFER_REFCOUNT (buf3, "buf3", 2); + fail_unless (gst_buffer_list_iterator_next (it) == NULL); + fail_if (gst_buffer_list_iterator_next_group (it)); + gst_buffer_list_iterator_free (it); + gst_buffer_list_unref (wlist); +} + +GST_END_TEST; + +GST_START_TEST (test_copy) +{ + GstBufferListIterator *it; + GstBufferList *list_copy; + GstBuffer *buf1; + GstBuffer *buf2; + GstBuffer *buf3; + GstBuffer *buf; + + /* add buffers to the list */ + it = gst_buffer_list_iterate (list); + gst_buffer_list_iterator_add_group (it); + buf1 = gst_buffer_new (); + gst_buffer_list_iterator_add (it, buf1); + gst_buffer_list_iterator_add_group (it); + buf2 = gst_buffer_new (); + gst_buffer_list_iterator_add (it, buf2); + buf3 = gst_buffer_new (); + gst_buffer_list_iterator_add (it, buf3); + gst_buffer_list_iterator_free (it); + + /* make a copy */ + list_copy = gst_buffer_list_copy (list); + fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (list) == 1); + fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (list_copy) == 1); + fail_unless (list_copy != list); + it = gst_buffer_list_iterate (list_copy); + fail_unless (gst_buffer_list_iterator_next_group (it)); + buf = gst_buffer_list_iterator_next (it); + fail_unless (buf == buf1); + ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 2); + fail_unless (gst_buffer_list_iterator_next (it) == NULL); + fail_unless (gst_buffer_list_iterator_next_group (it)); + buf = gst_buffer_list_iterator_next (it); + fail_unless (buf == buf2); + ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 2); + buf = gst_buffer_list_iterator_next (it); + fail_unless (buf == buf3); + ASSERT_BUFFER_REFCOUNT (buf3, "buf3", 2); + fail_unless (gst_buffer_list_iterator_next (it) == NULL); + fail_if (gst_buffer_list_iterator_next_group (it)); + gst_buffer_list_iterator_free (it); + gst_buffer_list_unref (list_copy); +} + +GST_END_TEST; + +GST_START_TEST (test_steal) +{ + GstBufferListIterator *it; + GstBuffer *buf1; + GstBuffer *buf2; + GstBuffer *buf3; + GstBuffer *buf; + + /* add buffers to the list */ + it = gst_buffer_list_iterate (list); + gst_buffer_list_iterator_add_group (it); + buf1 = gst_buffer_new (); + gst_buffer_list_iterator_add (it, buf1); + gst_buffer_list_iterator_add_group (it); + buf2 = gst_buffer_new (); + gst_buffer_list_iterator_add (it, buf2); + buf3 = gst_buffer_new (); + gst_buffer_list_iterator_add (it, buf3); + gst_buffer_list_iterator_free (it); + + /* check some error handling */ + ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (NULL))); + fail_unless (buf == NULL); + it = gst_buffer_list_iterate (list); + ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (it))); + fail_unless (buf == NULL); + + /* steal the first buffer */ + ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (it))); + fail_unless (gst_buffer_list_iterator_next_group (it)); + ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (it))); + fail_unless (gst_buffer_list_iterator_next (it) == buf1); + buf = gst_buffer_list_iterator_steal (it); + fail_unless (buf == buf1); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); + gst_buffer_unref (buf); + ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (it))); + fail_unless (buf == NULL); + + /* steal the second buffer */ + fail_unless (gst_buffer_list_iterator_next_group (it)); + ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (it))); + fail_unless (gst_buffer_list_iterator_next (it) == buf2); + buf = gst_buffer_list_iterator_steal (it); + fail_unless (buf == buf2); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); + gst_buffer_unref (buf); + ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (it))); + + /* steal the third buffer */ + fail_unless (gst_buffer_list_iterator_next (it) == buf3); + buf = gst_buffer_list_iterator_steal (it); + fail_unless (buf == buf3); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); + gst_buffer_unref (buf); + ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_steal (it))); + + gst_buffer_list_iterator_free (it); + + /* iterate again when all buffers have been stolen */ + it = gst_buffer_list_iterate (list); + fail_unless (gst_buffer_list_iterator_next (it) == NULL); + fail_unless (gst_buffer_list_iterator_next_group (it)); + fail_unless (gst_buffer_list_iterator_next (it) == NULL); + fail_unless (gst_buffer_list_iterator_next_group (it)); + fail_unless (gst_buffer_list_iterator_next (it) == NULL); + fail_if (gst_buffer_list_iterator_next_group (it)); + gst_buffer_list_iterator_free (it); +} + +GST_END_TEST; + +GST_START_TEST (test_take) +{ + GstBufferListIterator *it; + GstBuffer *buf1; + GstBuffer *buf2; + GstBuffer *buf3; + GstBuffer *buf; + + /* add buffers to the list */ + it = gst_buffer_list_iterate (list); + gst_buffer_list_iterator_add_group (it); + buf1 = gst_buffer_new (); + gst_buffer_ref (buf1); + gst_buffer_list_iterator_add (it, buf1); + gst_buffer_list_iterator_add_group (it); + buf2 = gst_buffer_new (); + gst_buffer_ref (buf2); + gst_buffer_list_iterator_add (it, buf2); + buf3 = gst_buffer_new (); + gst_buffer_ref (buf3); + gst_buffer_list_iterator_add (it, buf3); + gst_buffer_list_iterator_free (it); + + /* check some error handling */ + ASSERT_CRITICAL (gst_buffer_list_iterator_take (NULL, NULL)); + it = gst_buffer_list_iterate (list); + ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, NULL)); + buf = gst_buffer_new (); + gst_buffer_ref (buf); + ASSERT_CRITICAL (gst_buffer_list_iterator_take (NULL, buf)); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 2); + + /* replace the first buffer */ + ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, buf)); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 2); + fail_unless (gst_buffer_list_iterator_next_group (it)); + ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, buf)); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 2); + fail_unless (gst_buffer_list_iterator_next (it) == buf1); + ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, NULL)); + ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 2); + gst_buffer_list_iterator_take (it, buf); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 2); + ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 1); + gst_buffer_unref (buf1); + + /* replace the first buffer again, with itself */ + gst_buffer_ref (buf); + gst_buffer_list_iterator_take (it, buf); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 2); + + /* replace the second buffer */ + gst_buffer_ref (buf); + fail_unless (gst_buffer_list_iterator_next (it) == NULL); + ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, buf)); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 3); + fail_unless (gst_buffer_list_iterator_next_group (it)); + ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 2); + ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, buf)); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 3); + ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 2); + fail_unless (gst_buffer_list_iterator_next (it) == buf2); + ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, NULL)); + ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 2); + gst_buffer_list_iterator_take (it, buf); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 3); + ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 1); + gst_buffer_unref (buf2); + + /* replace the third buffer */ + gst_buffer_ref (buf); + fail_unless (gst_buffer_list_iterator_next (it) == buf3); + ASSERT_BUFFER_REFCOUNT (buf3, "buf3", 2); + gst_buffer_list_iterator_take (it, buf); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 4); + ASSERT_BUFFER_REFCOUNT (buf3, "buf3", 1); + gst_buffer_unref (buf3); + fail_if (gst_buffer_list_iterator_next_group (it)); + ASSERT_CRITICAL (gst_buffer_list_iterator_take (it, buf)); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 4); + gst_buffer_unref (buf); + + gst_buffer_list_iterator_free (it); +} + +GST_END_TEST; + +static gpointer do_data_func_data; +static gboolean notified; + +static void +data_notify (gpointer data) +{ + fail_unless (data != NULL); + fail_unless (data == do_data_func_data); + fail_if (notified); + notified = TRUE; +} + +static GstBuffer * +do_data_func (GstBuffer * buffer, gpointer data) +{ + do_data_func_data = data; + fail_if (notified); + + return buffer; +} + +static GstBuffer * +do_func_null (GstBuffer * buffer) +{ + gst_buffer_unref (buffer); + + return NULL; +} + +GST_START_TEST (test_do) +{ + GstBufferListIterator *it; + GstBuffer *buf1; + GstBuffer *buf; + gchar *data; + + /* error handling */ + ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_do (NULL, NULL))); + fail_unless (buf == NULL); + ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_do_data (NULL, NULL, NULL, + NULL))); + fail_unless (buf == NULL); + it = gst_buffer_list_iterate (list); + ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_do (it, NULL))); + fail_unless (buf == NULL); + ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_do_data (it, NULL, NULL, + NULL))); + fail_unless (buf == NULL); + + /* add buffers to the list */ + gst_buffer_list_iterator_add_group (it); + buf1 = gst_buffer_new (); + gst_buffer_ref (buf1); + gst_buffer_list_iterator_add (it, buf1); + gst_buffer_list_iterator_add_group (it); + gst_buffer_list_iterator_free (it); + + /* call do-function */ + it = gst_buffer_list_iterate (list); + fail_unless (gst_buffer_list_iterator_next_group (it)); + ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_do (it, gst_buffer_ref))); + fail_unless (buf == NULL); + data = "data"; + ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_do_data (it, do_data_func, + data, data_notify))); + fail_unless (buf == NULL); + fail_unless (do_data_func_data != data); + buf = gst_buffer_list_iterator_next (it); + fail_unless (buf == buf1); + ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 2); + buf = gst_buffer_list_iterator_do (it, gst_buffer_ref); + fail_unless (buf == buf1); + ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 3); + gst_buffer_unref (buf); + buf = gst_buffer_list_iterator_do_data (it, do_data_func, data, data_notify); + fail_unless (buf == buf1); + fail_unless (do_data_func_data == data); + + /* do-function that return a new buffer replaces the buffer in the list */ + ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 2); + buf = gst_buffer_list_iterator_do (it, + (GstBufferListDoFunction) gst_mini_object_make_writable); + fail_unless (buf != buf1); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); + ASSERT_BUFFER_REFCOUNT (buf, "buf1", 1); + gst_buffer_replace (&buf1, buf); + + /* do-function that return NULL removes the buffer from the list */ + ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 2); + fail_unless (gst_buffer_list_iterator_do (it, do_func_null) == NULL); + ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 1); + ASSERT_CRITICAL ((buf = gst_buffer_list_iterator_do (it, gst_buffer_ref))); + fail_unless (buf == NULL); + fail_unless (gst_buffer_list_iterator_next (it) == NULL); + gst_buffer_list_iterator_free (it); + it = gst_buffer_list_iterate (list); + fail_unless (gst_buffer_list_iterator_next_group (it)); + fail_unless (gst_buffer_list_iterator_next (it) == NULL); + fail_if (gst_buffer_list_iterator_next_group (it)); + gst_buffer_list_iterator_free (it); + gst_buffer_unref (buf1); +} + +GST_END_TEST; + +GST_START_TEST (test_merge) +{ + GstBufferListIterator *it; + GstBufferListIterator *merge_it; + GstBuffer *merged_buf; + GstBuffer *buf; + + it = gst_buffer_list_iterate (list); + fail_unless (gst_buffer_list_iterator_merge_group (it) == NULL); + + /* create a new group and add a buffer */ + gst_buffer_list_iterator_add_group (it); + fail_unless (gst_buffer_list_iterator_merge_group (it) == NULL); + buf = buffer_from_string ("One"); + gst_buffer_ref (buf); + gst_buffer_list_iterator_add (it, buf); + + /* merging a group with one buffer returns a copy of the buffer */ + merge_it = gst_buffer_list_iterate (list); + fail_unless (gst_buffer_list_iterator_next_group (merge_it)); + merged_buf = gst_buffer_list_iterator_merge_group (merge_it); + fail_unless (merged_buf != buf); + ASSERT_BUFFER_REFCOUNT (merged_buf, "merged_buf", 1); + gst_buffer_unref (buf); + fail_unless (GST_BUFFER_CAPS (merged_buf) == caps); + fail_unless (GST_BUFFER_TIMESTAMP (merged_buf) == TIMESTAMP); + fail_unless (GST_BUFFER_SIZE (merged_buf) == 3); + fail_unless (memcmp (GST_BUFFER_DATA (merged_buf), "One", + GST_BUFFER_SIZE (merged_buf)) == 0); + gst_buffer_unref (merged_buf); + + /* add another buffer to the same group */ + gst_buffer_list_iterator_add (it, buffer_from_string ("Group")); + + /* merging a group returns a new buffer with merged data */ + merged_buf = gst_buffer_list_iterator_merge_group (merge_it); + ASSERT_BUFFER_REFCOUNT (merged_buf, "merged_buf", 1); + fail_unless (GST_BUFFER_CAPS (merged_buf) == caps); + fail_unless (GST_BUFFER_TIMESTAMP (merged_buf) == TIMESTAMP); + fail_unless (GST_BUFFER_SIZE (merged_buf) == 8); + fail_unless (memcmp (GST_BUFFER_DATA (merged_buf), "OneGroup", + GST_BUFFER_SIZE (merged_buf)) == 0); + + /* merging the same group again should return a new buffer with merged data */ + buf = gst_buffer_list_iterator_merge_group (merge_it); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); + fail_unless (buf != merged_buf); + fail_unless (GST_BUFFER_SIZE (buf) == 8); + fail_unless (memcmp (GST_BUFFER_DATA (buf), "OneGroup", + GST_BUFFER_SIZE (buf)) == 0); + gst_buffer_unref (buf); + gst_buffer_unref (merged_buf); + + /* add a new group */ + gst_buffer_list_iterator_add_group (it); + gst_buffer_list_iterator_add (it, buffer_from_string ("AnotherGroup")); + gst_buffer_list_iterator_free (it); + + /* merge the first group again */ + merged_buf = gst_buffer_list_iterator_merge_group (merge_it); + ASSERT_BUFFER_REFCOUNT (merged_buf, "merged_buf", 1); + fail_unless (GST_BUFFER_CAPS (merged_buf) == caps); + fail_unless (GST_BUFFER_TIMESTAMP (merged_buf) == TIMESTAMP); + fail_unless (GST_BUFFER_SIZE (merged_buf) == 8); + fail_unless (memcmp (GST_BUFFER_DATA (merged_buf), "OneGroup", + GST_BUFFER_SIZE (merged_buf)) == 0); + gst_buffer_unref (merged_buf); + + /* merge the second group */ + fail_unless (gst_buffer_list_iterator_next_group (merge_it)); + merged_buf = gst_buffer_list_iterator_merge_group (merge_it); + ASSERT_BUFFER_REFCOUNT (merged_buf, "merged_buf", 1); + fail_unless (GST_BUFFER_CAPS (merged_buf) == caps); + fail_unless (GST_BUFFER_TIMESTAMP (merged_buf) == TIMESTAMP); + fail_unless (GST_BUFFER_SIZE (merged_buf) == 12); + fail_unless (memcmp (GST_BUFFER_DATA (merged_buf), "AnotherGroup", + GST_BUFFER_SIZE (merged_buf)) == 0); + gst_buffer_unref (merged_buf); + + gst_buffer_list_iterator_free (merge_it); + + /* steal the second buffer and merge the first group again */ + it = gst_buffer_list_iterate (list); + fail_unless (gst_buffer_list_iterator_next_group (it)); + fail_unless (gst_buffer_list_iterator_next (it) != NULL); + fail_unless (gst_buffer_list_iterator_next (it) != NULL); + buf = gst_buffer_list_iterator_steal (it); + gst_buffer_list_iterator_free (it); + fail_unless (buf != NULL); + fail_unless (memcmp (GST_BUFFER_DATA (buf), "Group", + GST_BUFFER_SIZE (buf)) == 0); + gst_buffer_unref (buf); + merge_it = gst_buffer_list_iterate (list); + fail_unless (gst_buffer_list_iterator_next_group (merge_it)); + merged_buf = gst_buffer_list_iterator_merge_group (merge_it); + ASSERT_BUFFER_REFCOUNT (merged_buf, "merged_buf", 1); + fail_unless (GST_BUFFER_CAPS (merged_buf) == caps); + fail_unless (GST_BUFFER_TIMESTAMP (merged_buf) == TIMESTAMP); + fail_unless (GST_BUFFER_SIZE (merged_buf) == 3); + fail_unless (memcmp (GST_BUFFER_DATA (merged_buf), "One", + GST_BUFFER_SIZE (merged_buf)) == 0); + gst_buffer_unref (merged_buf); + + /* steal the first buffer too and merge the first group again */ + it = gst_buffer_list_iterate (list); + fail_unless (gst_buffer_list_iterator_next_group (it)); + fail_unless (gst_buffer_list_iterator_next (it) != NULL); + buf = gst_buffer_list_iterator_steal (it); + fail_unless (buf != NULL); + fail_unless (memcmp (GST_BUFFER_DATA (buf), "One", + GST_BUFFER_SIZE (buf)) == 0); + gst_buffer_unref (buf); + gst_buffer_list_iterator_free (it); + fail_unless (gst_buffer_list_iterator_merge_group (merge_it) == NULL); + gst_buffer_list_iterator_free (merge_it); +} + +GST_END_TEST; + +static Suite * +gst_buffer_list_suite (void) +{ + Suite *s = suite_create ("GstBufferList"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_checked_fixture (tc_chain, setup, cleanup); + tcase_add_test (tc_chain, test_add_and_iterate); + tcase_add_test (tc_chain, test_make_writable); + tcase_add_test (tc_chain, test_copy); + tcase_add_test (tc_chain, test_steal); + tcase_add_test (tc_chain, test_take); + tcase_add_test (tc_chain, test_do); + tcase_add_test (tc_chain, test_merge); + + return s; +} + +GST_CHECK_MAIN (gst_buffer_list); diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index ca4e181..febcb4a 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -2,6 +2,7 @@ EXPORTS GST_CAT_AUTOPLUG DATA GST_CAT_AUTOPLUG_ATTEMPT DATA GST_CAT_BUFFER DATA + GST_CAT_BUFFER_LIST DATA GST_CAT_BUS DATA GST_CAT_CALL_TRACE DATA GST_CAT_CAPS DATA @@ -32,6 +33,7 @@ EXPORTS __gst_debug_enabled DATA __gst_debug_min DATA _gst_alloc_trace_register + _gst_buffer_list_initialize _gst_debug_bin_to_dot_file _gst_debug_bin_to_dot_file_with_ts _gst_debug_category_new @@ -84,6 +86,22 @@ EXPORTS gst_buffer_is_metadata_writable gst_buffer_is_span_fast gst_buffer_join + gst_buffer_list_get_type + gst_buffer_list_iterate + gst_buffer_list_iterator_add + gst_buffer_list_iterator_add_group + gst_buffer_list_iterator_do + gst_buffer_list_iterator_do_data + gst_buffer_list_iterator_free + gst_buffer_list_iterator_merge_group + gst_buffer_list_iterator_n_buffers + gst_buffer_list_iterator_next + gst_buffer_list_iterator_next_group + gst_buffer_list_iterator_remove + gst_buffer_list_iterator_steal + gst_buffer_list_iterator_take + gst_buffer_list_n_groups + gst_buffer_list_new gst_buffer_make_metadata_writable gst_buffer_merge gst_buffer_new