2015-11-01 23:41:28 +00:00
|
|
|
/* GStreamer udpsink unit tests
|
2009-06-16 13:04:15 +00:00
|
|
|
* Copyright (C) 2009 Axis Communications <dev-gstreamer@axis.com>
|
|
|
|
* @author Ognyan Tonchev <ognyan@axis.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
|
2012-11-04 00:07:18 +00:00
|
|
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
2009-06-16 13:04:15 +00:00
|
|
|
*/
|
|
|
|
#include <gst/check/gstcheck.h>
|
|
|
|
#include <gst/base/gstbasesink.h>
|
2015-11-01 23:41:28 +00:00
|
|
|
#include <gio/gio.h>
|
2009-06-16 13:04:15 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
|
|
|
|
GST_PAD_SRC,
|
|
|
|
GST_PAD_ALWAYS,
|
|
|
|
GST_STATIC_CAPS_ANY);
|
|
|
|
|
|
|
|
#define RTP_HEADER_SIZE 12
|
|
|
|
#define RTP_PAYLOAD_SIZE 1024
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Number of bytes received in the render function when using buffer lists
|
|
|
|
*/
|
|
|
|
static guint render_list_bytes_received;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Render function for testing udpsink with buffer lists
|
|
|
|
*/
|
|
|
|
static GstFlowReturn
|
2014-06-23 15:13:27 +00:00
|
|
|
udpsink_render_list (GstBaseSink * sink, GstBufferList * list)
|
2009-06-16 13:04:15 +00:00
|
|
|
{
|
2014-06-23 15:13:27 +00:00
|
|
|
guint i, num;
|
2009-06-16 13:04:15 +00:00
|
|
|
|
2014-06-23 15:13:27 +00:00
|
|
|
num = gst_buffer_list_length (list);
|
|
|
|
for (i = 0; i < num; ++i) {
|
|
|
|
GstBuffer *buf = gst_buffer_list_get (list, i);
|
|
|
|
gsize size = gst_buffer_get_size (buf);
|
2009-06-16 13:04:15 +00:00
|
|
|
|
2014-06-23 15:13:27 +00:00
|
|
|
GST_DEBUG ("rendered %" G_GSIZE_FORMAT " bytes", size);
|
|
|
|
render_list_bytes_received += size;
|
2009-06-16 13:04:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return GST_FLOW_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-06-23 15:13:27 +00:00
|
|
|
set_render_list_function (GstElement * bsink)
|
2009-06-16 13:04:15 +00:00
|
|
|
{
|
|
|
|
GstBaseSinkClass *bsclass;
|
2014-06-23 15:13:27 +00:00
|
|
|
|
2009-06-16 13:04:15 +00:00
|
|
|
bsclass = GST_BASE_SINK_GET_CLASS ((GstBaseSink *) bsink);
|
2014-06-23 15:13:27 +00:00
|
|
|
|
2009-06-16 13:04:15 +00:00
|
|
|
/* Add callback function for the buffer list tests */
|
2014-06-23 15:13:27 +00:00
|
|
|
bsclass->render_list = udpsink_render_list;
|
2009-06-16 13:04:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static GstBufferList *
|
2014-06-23 15:13:27 +00:00
|
|
|
create_buffer_list (guint * data_size)
|
2009-06-16 13:04:15 +00:00
|
|
|
{
|
|
|
|
GstBufferList *list;
|
|
|
|
GstBuffer *rtp_buffer;
|
|
|
|
GstBuffer *data_buffer;
|
|
|
|
|
|
|
|
list = gst_buffer_list_new ();
|
|
|
|
|
|
|
|
/*** First group, i.e. first packet. **/
|
|
|
|
|
|
|
|
/* Create the RTP header buffer */
|
2014-06-23 15:13:27 +00:00
|
|
|
rtp_buffer = gst_buffer_new_allocate (NULL, RTP_HEADER_SIZE, NULL);
|
|
|
|
gst_buffer_memset (rtp_buffer, 0, 0, RTP_HEADER_SIZE);
|
2009-06-16 13:04:15 +00:00
|
|
|
|
|
|
|
/* Create the buffer that holds the payload */
|
2014-06-23 15:13:27 +00:00
|
|
|
data_buffer = gst_buffer_new_allocate (NULL, RTP_PAYLOAD_SIZE, NULL);
|
|
|
|
gst_buffer_memset (data_buffer, 0, 0, RTP_PAYLOAD_SIZE);
|
2009-06-16 13:04:15 +00:00
|
|
|
|
|
|
|
/* Create a new group to hold the rtp header and the payload */
|
2014-06-23 15:13:27 +00:00
|
|
|
gst_buffer_list_add (list, gst_buffer_append (rtp_buffer, data_buffer));
|
2009-06-16 13:04:15 +00:00
|
|
|
|
|
|
|
/*** Second group, i.e. second packet. ***/
|
|
|
|
|
|
|
|
/* Create the RTP header buffer */
|
2014-06-23 15:13:27 +00:00
|
|
|
rtp_buffer = gst_buffer_new_allocate (NULL, RTP_HEADER_SIZE, NULL);
|
|
|
|
gst_buffer_memset (rtp_buffer, 0, 0, RTP_HEADER_SIZE);
|
2009-06-16 13:04:15 +00:00
|
|
|
|
|
|
|
/* Create the buffer that holds the payload */
|
2014-06-23 15:13:27 +00:00
|
|
|
data_buffer = gst_buffer_new_allocate (NULL, RTP_PAYLOAD_SIZE, NULL);
|
|
|
|
gst_buffer_memset (data_buffer, 0, 0, RTP_PAYLOAD_SIZE);
|
2009-06-16 13:04:15 +00:00
|
|
|
|
|
|
|
/* Create a new group to hold the rtp header and the payload */
|
2014-06-23 15:13:27 +00:00
|
|
|
gst_buffer_list_add (list, gst_buffer_append (rtp_buffer, data_buffer));
|
2009-06-16 13:04:15 +00:00
|
|
|
|
|
|
|
/* Calculate the size of the data */
|
|
|
|
*data_size = 2 * RTP_HEADER_SIZE + 2 * RTP_PAYLOAD_SIZE;
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
udpsink_test (gboolean use_buffer_lists)
|
|
|
|
{
|
2014-06-23 15:13:27 +00:00
|
|
|
GstSegment segment;
|
2009-06-16 13:04:15 +00:00
|
|
|
GstElement *udpsink;
|
|
|
|
GstPad *srcpad;
|
|
|
|
GstBufferList *list;
|
|
|
|
guint data_size;
|
|
|
|
|
2014-06-23 15:13:27 +00:00
|
|
|
list = create_buffer_list (&data_size);
|
2009-06-16 13:04:15 +00:00
|
|
|
|
|
|
|
udpsink = gst_check_setup_element ("udpsink");
|
|
|
|
if (use_buffer_lists)
|
2014-06-23 15:13:27 +00:00
|
|
|
set_render_list_function (udpsink);
|
2009-06-16 13:04:15 +00:00
|
|
|
|
|
|
|
srcpad = gst_check_setup_src_pad_by_name (udpsink, &srctemplate, "sink");
|
|
|
|
|
|
|
|
gst_element_set_state (udpsink, GST_STATE_PLAYING);
|
2014-06-23 15:13:27 +00:00
|
|
|
gst_pad_set_active (srcpad, TRUE);
|
|
|
|
|
|
|
|
gst_pad_push_event (srcpad, gst_event_new_stream_start ("hey there!"));
|
2009-06-16 13:04:15 +00:00
|
|
|
|
2014-06-23 15:13:27 +00:00
|
|
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
|
|
|
gst_pad_push_event (srcpad, gst_event_new_segment (&segment));
|
2009-06-16 13:25:54 +00:00
|
|
|
|
2014-06-23 15:13:27 +00:00
|
|
|
fail_unless_equals_int (gst_pad_push_list (srcpad, list), GST_FLOW_OK);
|
2009-06-16 13:04:15 +00:00
|
|
|
|
|
|
|
gst_check_teardown_pad_by_name (udpsink, "sink");
|
|
|
|
gst_check_teardown_element (udpsink);
|
|
|
|
|
|
|
|
if (use_buffer_lists)
|
2010-04-13 09:29:30 +00:00
|
|
|
fail_unless_equals_int (data_size, render_list_bytes_received);
|
2009-06-16 13:04:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GST_START_TEST (test_udpsink)
|
|
|
|
{
|
|
|
|
udpsink_test (FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
GST_END_TEST;
|
2014-06-23 15:13:27 +00:00
|
|
|
|
|
|
|
|
2009-06-16 13:04:15 +00:00
|
|
|
GST_START_TEST (test_udpsink_bufferlist)
|
|
|
|
{
|
|
|
|
udpsink_test (TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
GST_END_TEST;
|
|
|
|
|
2014-06-24 09:47:33 +00:00
|
|
|
GST_START_TEST (test_udpsink_client_add_remove)
|
|
|
|
{
|
|
|
|
GstElement *udpsink;
|
|
|
|
|
|
|
|
/* Note: keep in mind that these are in addition to the client added by
|
|
|
|
* the host/port properties (by default 'localhost:5004' */
|
|
|
|
|
|
|
|
udpsink = gst_check_setup_element ("udpsink");
|
|
|
|
g_signal_emit_by_name (udpsink, "remove", "localhost", 5004, NULL);
|
|
|
|
gst_object_unref (udpsink);
|
|
|
|
|
|
|
|
udpsink = gst_check_setup_element ("udpsink");
|
|
|
|
g_signal_emit_by_name (udpsink, "add", "127.0.0.1", 5554, NULL);
|
|
|
|
gst_object_unref (udpsink);
|
|
|
|
|
|
|
|
udpsink = gst_check_setup_element ("udpsink");
|
|
|
|
g_signal_emit_by_name (udpsink, "add", "127.0.0.1", 5554, NULL);
|
|
|
|
g_signal_emit_by_name (udpsink, "add", "127.0.0.1", 5554, NULL);
|
|
|
|
gst_object_unref (udpsink);
|
|
|
|
|
|
|
|
udpsink = gst_check_setup_element ("udpsink");
|
|
|
|
g_signal_emit_by_name (udpsink, "add", "127.0.0.1", 5554, NULL);
|
|
|
|
g_signal_emit_by_name (udpsink, "remove", "127.0.0.1", 5554, NULL);
|
|
|
|
gst_object_unref (udpsink);
|
|
|
|
|
|
|
|
udpsink = gst_check_setup_element ("udpsink");
|
|
|
|
g_signal_emit_by_name (udpsink, "add", "127.0.0.1", 5554, NULL);
|
|
|
|
g_signal_emit_by_name (udpsink, "remove", "127.0.0.1", 5555, NULL);
|
|
|
|
gst_object_unref (udpsink);
|
|
|
|
|
|
|
|
udpsink = gst_check_setup_element ("udpsink");
|
|
|
|
g_signal_emit_by_name (udpsink, "add", "127.0.0.1", 5554, NULL);
|
|
|
|
g_signal_emit_by_name (udpsink, "add", "127.0.0.1", 5555, NULL);
|
|
|
|
gst_object_unref (udpsink);
|
|
|
|
|
|
|
|
udpsink = gst_check_setup_element ("udpsink");
|
|
|
|
g_signal_emit_by_name (udpsink, "add", "127.0.0.1", 5554, NULL);
|
|
|
|
g_signal_emit_by_name (udpsink, "add", "10.2.0.1", 5554, NULL);
|
|
|
|
gst_object_unref (udpsink);
|
|
|
|
|
|
|
|
udpsink = gst_check_setup_element ("udpsink");
|
|
|
|
g_signal_emit_by_name (udpsink, "add", "127.0.0.1", 5554, NULL);
|
|
|
|
g_signal_emit_by_name (udpsink, "add", "10.2.0.1", 5554, NULL);
|
|
|
|
g_signal_emit_by_name (udpsink, "remove", "127.0.0.1", 5554, NULL);
|
|
|
|
gst_object_unref (udpsink);
|
|
|
|
}
|
|
|
|
|
|
|
|
GST_END_TEST;
|
|
|
|
|
2015-11-01 23:41:28 +00:00
|
|
|
GST_START_TEST (test_udpsink_dscp)
|
|
|
|
{
|
|
|
|
GstElement *udpsink;
|
|
|
|
GError *error = NULL;
|
|
|
|
GSocket *sock4, *sock6;
|
2022-06-25 18:23:11 +00:00
|
|
|
gboolean have_ipv6;
|
2015-11-01 23:41:28 +00:00
|
|
|
|
|
|
|
sock4 =
|
|
|
|
g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM,
|
|
|
|
G_SOCKET_PROTOCOL_UDP, &error);
|
|
|
|
fail_unless (sock4 != NULL && error == NULL);
|
2022-06-25 18:23:11 +00:00
|
|
|
|
2015-11-01 23:41:28 +00:00
|
|
|
sock6 =
|
|
|
|
g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_DATAGRAM,
|
|
|
|
G_SOCKET_PROTOCOL_UDP, &error);
|
2022-06-25 18:23:11 +00:00
|
|
|
have_ipv6 = sock6 != NULL && error == NULL;
|
|
|
|
g_clear_error (&error);
|
2015-11-01 23:41:28 +00:00
|
|
|
|
|
|
|
udpsink = gst_check_setup_element ("udpsink");
|
|
|
|
g_signal_emit_by_name (udpsink, "add", "127.0.0.1", 5554, NULL);
|
|
|
|
g_object_set (udpsink, "socket", sock4, NULL);
|
2022-06-25 18:23:11 +00:00
|
|
|
|
|
|
|
if (have_ipv6)
|
|
|
|
g_object_set (udpsink, "socket-v6", sock6, NULL);
|
2015-11-01 23:41:28 +00:00
|
|
|
|
|
|
|
ASSERT_SET_STATE (udpsink, GST_STATE_READY, GST_STATE_CHANGE_SUCCESS);
|
|
|
|
|
|
|
|
g_object_set (udpsink, "qos-dscp", 0, NULL);
|
|
|
|
g_object_set (udpsink, "qos-dscp", 63, NULL);
|
|
|
|
|
|
|
|
ASSERT_SET_STATE (udpsink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
|
|
|
|
|
|
|
|
gst_object_unref (udpsink);
|
|
|
|
g_object_unref (sock4);
|
2022-06-25 18:23:11 +00:00
|
|
|
g_clear_object (&sock6);
|
2015-11-01 23:41:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GST_END_TEST;
|
|
|
|
|
2009-06-16 13:04:15 +00:00
|
|
|
static Suite *
|
2010-03-21 14:17:46 +00:00
|
|
|
udpsink_suite (void)
|
2009-06-16 13:04:15 +00:00
|
|
|
{
|
|
|
|
Suite *s = suite_create ("udpsink_test");
|
|
|
|
TCase *tc_chain = tcase_create ("linear");
|
|
|
|
|
|
|
|
suite_add_tcase (s, tc_chain);
|
2014-06-23 15:13:27 +00:00
|
|
|
|
2009-06-16 13:04:15 +00:00
|
|
|
tcase_add_test (tc_chain, test_udpsink);
|
|
|
|
tcase_add_test (tc_chain, test_udpsink_bufferlist);
|
2014-06-24 09:47:33 +00:00
|
|
|
tcase_add_test (tc_chain, test_udpsink_client_add_remove);
|
2015-11-01 23:41:28 +00:00
|
|
|
tcase_add_test (tc_chain, test_udpsink_dscp);
|
2014-06-23 15:13:27 +00:00
|
|
|
|
2009-06-16 13:04:15 +00:00
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
GST_CHECK_MAIN (udpsink)
|