diff options
Diffstat (limited to 'tests/check/elements')
-rw-r--r-- | tests/check/elements/.gitignore | 1 | ||||
-rw-r--r-- | tests/check/elements/rtpbin.c | 337 | ||||
-rw-r--r-- | tests/check/elements/y4menc.c | 165 |
3 files changed, 338 insertions, 165 deletions
diff --git a/tests/check/elements/.gitignore b/tests/check/elements/.gitignore index 3e9d29bf..091fb4e5 100644 --- a/tests/check/elements/.gitignore +++ b/tests/check/elements/.gitignore @@ -18,6 +18,7 @@ souphttpsrc rganalysis rglimiter rgvolume +rtpbin selector spectrum timidity diff --git a/tests/check/elements/rtpbin.c b/tests/check/elements/rtpbin.c new file mode 100644 index 00000000..bc30c918 --- /dev/null +++ b/tests/check/elements/rtpbin.c @@ -0,0 +1,337 @@ +/* GStreamer + * + * unit test for gstrtpbin + * + * Copyright (C) <2009> Wim Taymans <wim.taymans@gmail.com> + * + * 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 <gst/check/gstcheck.h> + +GST_START_TEST (test_cleanup_send) +{ + GstElement *rtpbin; + GstPad *rtp_sink, *rtp_src, *rtcp_src; + GObject *session; + gint count = 2; + + rtpbin = gst_element_factory_make ("gstrtpbin", "rtpbin"); + + while (count--) { + /* request session 0 */ + rtp_sink = gst_element_get_request_pad (rtpbin, "send_rtp_sink_0"); + fail_unless (rtp_sink != NULL); + ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 2); + + /* request again */ + rtp_sink = gst_element_get_request_pad (rtpbin, "send_rtp_sink_0"); + fail_unless (rtp_sink != NULL); + ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 3); + gst_object_unref (rtp_sink); + + /* this static pad should be created automatically now */ + rtp_src = gst_element_get_static_pad (rtpbin, "send_rtp_src_0"); + fail_unless (rtp_src != NULL); + ASSERT_OBJECT_REFCOUNT (rtp_src, "rtp_src", 2); + + /* we should be able to get an internal session 0 now */ + g_signal_emit_by_name (rtpbin, "get-internal-session", 0, &session); + fail_unless (session != NULL); + g_object_unref (session); + + /* get the send RTCP pad too */ + rtcp_src = gst_element_get_request_pad (rtpbin, "send_rtcp_src_0"); + fail_unless (rtcp_src != NULL); + ASSERT_OBJECT_REFCOUNT (rtcp_src, "rtcp_src", 2); + + /* second time */ + rtcp_src = gst_element_get_request_pad (rtpbin, "send_rtcp_src_0"); + fail_unless (rtcp_src != NULL); + ASSERT_OBJECT_REFCOUNT (rtcp_src, "rtcp_src", 3); + gst_object_unref (rtcp_src); + + gst_element_release_request_pad (rtpbin, rtp_sink); + /* we should only have our refs to the pads now */ + ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 1); + ASSERT_OBJECT_REFCOUNT (rtp_src, "rtp_src", 1); + ASSERT_OBJECT_REFCOUNT (rtcp_src, "rtp_src", 2); + + /* the other pad should be gone now */ + fail_unless (gst_element_get_static_pad (rtpbin, "send_rtp_src_0") == NULL); + + /* internal session should still be there */ + g_signal_emit_by_name (rtpbin, "get-internal-session", 0, &session); + fail_unless (session != NULL); + g_object_unref (session); + + /* release the RTCP pad */ + gst_element_release_request_pad (rtpbin, rtcp_src); + /* we should only have our refs to the pads now */ + ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 1); + ASSERT_OBJECT_REFCOUNT (rtp_src, "rtp_src", 1); + ASSERT_OBJECT_REFCOUNT (rtcp_src, "rtp_src", 1); + + /* the session should be gone now */ + g_signal_emit_by_name (rtpbin, "get-internal-session", 0, &session); + fail_unless (session == NULL); + + /* unref the request pad and the static pad */ + gst_object_unref (rtp_sink); + gst_object_unref (rtp_src); + gst_object_unref (rtcp_src); + } + + gst_object_unref (rtpbin); +} + +GST_END_TEST; + +typedef struct +{ + guint16 seqnum; + gboolean pad_added; + GstPad *pad; + GMutex *lock; + GCond *cond; + GstPad *sinkpad; + GList *pads; +} CleanupData; + +static void +init_data (CleanupData * data) +{ + data->seqnum = 10; + data->pad_added = FALSE; + data->lock = g_mutex_new (); + data->cond = g_cond_new (); + data->pads = NULL; +} + +static void +clean_data (CleanupData * data) +{ + g_list_foreach (data->pads, (GFunc) gst_object_unref, NULL); + g_list_free (data->pads); + g_mutex_free (data->lock); + g_cond_free (data->cond); +} + +static guint8 rtp_packet[] = { 0x80, 0x60, 0x94, 0xbc, 0x8f, 0x37, 0x4e, 0xb8, + 0x44, 0xa8, 0xf3, 0x7c, 0x06, 0x6a, 0x0c, 0xce, + 0x13, 0x25, 0x19, 0x69, 0x1f, 0x93, 0x25, 0x9d, + 0x2b, 0x82, 0x31, 0x3b, 0x36, 0xc1, 0x3c, 0x13 +}; + +static GstBuffer * +make_rtp_packet (CleanupData * data) +{ + static GstCaps *caps = NULL; + GstBuffer *result; + guint8 *datap; + + if (caps == NULL) { + caps = gst_caps_from_string ("application/x-rtp," + "media=(string)audio, clock-rate=(int)44100, " + "encoding-name=(string)L16, encoding-params=(string)1, channels=(int)1"); + data->seqnum = 0; + } + + result = gst_buffer_new_and_alloc (sizeof (rtp_packet)); + datap = GST_BUFFER_DATA (result); + memcpy (datap, rtp_packet, sizeof (rtp_packet)); + + datap[2] = (data->seqnum >> 8) & 0xff; + datap[3] = data->seqnum & 0xff; + + data->seqnum++; + + gst_buffer_set_caps (result, caps); + + return result; +} + +static GstFlowReturn +dummy_chain (GstPad * pad, GstBuffer * buffer) +{ + gst_buffer_unref (buffer); + + return GST_FLOW_OK; +} + +static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("application/x-rtp")); + + +static GstPad * +make_sinkpad (CleanupData * data) +{ + GstPad *pad; + + pad = gst_pad_new_from_static_template (&sink_factory, "sink"); + + gst_pad_set_chain_function (pad, dummy_chain); + gst_pad_set_active (pad, TRUE); + + data->pads = g_list_prepend (data->pads, pad); + + return pad; +} + +static void +pad_added_cb (GstElement * rtpbin, GstPad * pad, CleanupData * data) +{ + GstPad *sinkpad; + + GST_DEBUG ("pad added %s:%s\n", GST_DEBUG_PAD_NAME (pad)); + + if (GST_PAD_IS_SINK (pad)) + return; + + fail_unless (data->pad_added == FALSE); + + sinkpad = make_sinkpad (data); + fail_unless (gst_pad_link (pad, sinkpad) == GST_PAD_LINK_OK); + + g_mutex_lock (data->lock); + data->pad_added = TRUE; + data->pad = pad; + g_cond_signal (data->cond); + g_mutex_unlock (data->lock); +} + +static void +pad_removed_cb (GstElement * rtpbin, GstPad * pad, CleanupData * data) +{ + GST_DEBUG ("pad removed %s:%s\n", GST_DEBUG_PAD_NAME (pad)); + + if (data->pad != pad) + return; + + fail_unless (data->pad_added == TRUE); + + g_mutex_lock (data->lock); + data->pad_added = FALSE; + g_cond_signal (data->cond); + g_mutex_unlock (data->lock); +} + +GST_START_TEST (test_cleanup_recv) +{ + GstElement *rtpbin; + GstPad *rtp_sink; + CleanupData data; + GstStateChangeReturn ret; + GstFlowReturn res; + GstBuffer *buffer; + gint count = 2; + + init_data (&data); + + rtpbin = gst_element_factory_make ("gstrtpbin", "rtpbin"); + + g_signal_connect (rtpbin, "pad-added", (GCallback) pad_added_cb, &data); + g_signal_connect (rtpbin, "pad-removed", (GCallback) pad_removed_cb, &data); + + ret = gst_element_set_state (rtpbin, GST_STATE_PLAYING); + fail_unless (ret == GST_STATE_CHANGE_SUCCESS); + + while (count--) { + /* request session 0 */ + rtp_sink = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_0"); + fail_unless (rtp_sink != NULL); + ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 2); + + /* no sourcepads are created yet */ + fail_unless (rtpbin->numsinkpads == 1); + fail_unless (rtpbin->numsrcpads == 0); + + buffer = make_rtp_packet (&data); + res = gst_pad_chain (rtp_sink, buffer); + GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res)); + fail_unless (res == GST_FLOW_OK); + + buffer = make_rtp_packet (&data); + res = gst_pad_chain (rtp_sink, buffer); + GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res)); + fail_unless (res == GST_FLOW_OK); + + /* we wait for the new pad to appear now */ + g_mutex_lock (data.lock); + while (!data.pad_added) + g_cond_wait (data.cond, data.lock); + g_mutex_unlock (data.lock); + + /* sourcepad created now */ + fail_unless (rtpbin->numsinkpads == 1); + fail_unless (rtpbin->numsrcpads == 1); + + /* remove the session */ + gst_element_release_request_pad (rtpbin, rtp_sink); + gst_object_unref (rtp_sink); + + /* pad should be gone now */ + g_mutex_lock (data.lock); + while (data.pad_added) + g_cond_wait (data.cond, data.lock); + g_mutex_unlock (data.lock); + + /* nothing left anymore now */ + fail_unless (rtpbin->numsinkpads == 0); + fail_unless (rtpbin->numsrcpads == 0); + } + + ret = gst_element_set_state (rtpbin, GST_STATE_NULL); + fail_unless (ret == GST_STATE_CHANGE_SUCCESS); + + gst_object_unref (rtpbin); + + clean_data (&data); +} + +GST_END_TEST; + +Suite * +gstrtpbin_suite (void) +{ + Suite *s = suite_create ("gstrtpbin"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_cleanup_send); + tcase_add_test (tc_chain, test_cleanup_recv); + + return s; +} + +int +main (int argc, char **argv) +{ + int nf; + + Suite *s = gstrtpbin_suite (); + SRunner *sr = srunner_create (s); + + gst_check_init (&argc, &argv); + + srunner_run_all (sr, CK_NORMAL); + nf = srunner_ntests_failed (sr); + srunner_free (sr); + + return nf; +} diff --git a/tests/check/elements/y4menc.c b/tests/check/elements/y4menc.c deleted file mode 100644 index b5c5fcc4..00000000 --- a/tests/check/elements/y4menc.c +++ /dev/null @@ -1,165 +0,0 @@ -/* GStreamer - * - * unit test for y4menc - * - * Copyright (C) <2006> Mark Nauwelaerts <manauw@skynet.be> - * - * 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 <unistd.h> - -#include <gst/check/gstcheck.h> - -/* For ease of programming we use globals to keep refs for our floating - * src and sink pads we create; otherwise we always have to do get_pad, - * get_peer, and then remove references in every test function */ -static GstPad *mysrcpad, *mysinkpad; - -#define VIDEO_CAPS_STRING "video/x-raw-yuv, " \ - "width = (int) 384, " \ - "height = (int) 288, " \ - "framerate = (fraction) 25/1, " \ - "pixel-aspect-ratio = (fraction) 1/1" - -#define Y4M_CAPS_STRING "application/x-yuv4mpeg, " \ - "y4mversion = (int) 2" - -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (Y4M_CAPS_STRING)); - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (VIDEO_CAPS_STRING)); - - -GstElement * -setup_y4menc () -{ - GstElement *y4menc; - - GST_DEBUG ("setup_y4menc"); - y4menc = gst_check_setup_element ("y4menc"); - mysrcpad = gst_check_setup_src_pad (y4menc, &srctemplate, NULL); - mysinkpad = gst_check_setup_sink_pad (y4menc, &sinktemplate, NULL); - gst_pad_set_active (mysrcpad, TRUE); - gst_pad_set_active (mysinkpad, TRUE); - - return y4menc; -} - -void -cleanup_y4menc (GstElement * y4menc) -{ - GST_DEBUG ("cleanup_y4menc"); - gst_element_set_state (y4menc, GST_STATE_NULL); - - gst_pad_set_active (mysrcpad, FALSE); - gst_pad_set_active (mysinkpad, FALSE); - gst_check_teardown_src_pad (y4menc); - gst_check_teardown_sink_pad (y4menc); - gst_check_teardown_element (y4menc); -} - -GST_START_TEST (test_y4m) -{ - GstElement *y4menc; - GstBuffer *inbuffer, *outbuffer; - GstCaps *caps; - int i, num_buffers, size; - const gchar *data0 = "YUV4MPEG2 W384 H288 I? F25:1 A1:1\nFRAME\n"; - - - y4menc = setup_y4menc (); - fail_unless (gst_element_set_state (y4menc, - GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, - "could not set to playing"); - - /* corresponds to I420 buffer for the size mentioned in the caps */ - size = 384 * 288 * 3 / 2; - inbuffer = gst_buffer_new_and_alloc (size); - /* makes valgrind's memcheck happier */ - memset (GST_BUFFER_DATA (inbuffer), 0, GST_BUFFER_SIZE (inbuffer)); - caps = gst_caps_from_string (VIDEO_CAPS_STRING); - gst_buffer_set_caps (inbuffer, caps); - gst_caps_unref (caps); - GST_BUFFER_TIMESTAMP (inbuffer) = 0; - ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); - fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK); - - num_buffers = g_list_length (buffers); - fail_unless (num_buffers == 1); - - /* clean up buffers */ - for (i = 0; i < num_buffers; ++i) { - outbuffer = GST_BUFFER (buffers->data); - fail_if (outbuffer == NULL); - - switch (i) { - case 0: - fail_unless (strlen (data0) == 40); - fail_unless (GST_BUFFER_SIZE (outbuffer) == size + 40); - fail_unless (memcmp (data0, GST_BUFFER_DATA (outbuffer), - strlen (data0)) == 0); - break; - default: - break; - } - buffers = g_list_remove (buffers, outbuffer); - - ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1); - gst_buffer_unref (outbuffer); - outbuffer = NULL; - } - - cleanup_y4menc (y4menc); - g_list_free (buffers); - buffers = NULL; -} - -GST_END_TEST; - -Suite * -y4menc_suite (void) -{ - Suite *s = suite_create ("y4menc"); - TCase *tc_chain = tcase_create ("general"); - - suite_add_tcase (s, tc_chain); - tcase_add_test (tc_chain, test_y4m); - - return s; -} - -int -main (int argc, char **argv) -{ - int nf; - - Suite *s = y4menc_suite (); - SRunner *sr = srunner_create (s); - - gst_check_init (&argc, &argv); - - srunner_run_all (sr, CK_NORMAL); - nf = srunner_ntests_failed (sr); - srunner_free (sr); - - return nf; -} |