mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
fd0ca0a972
Split the unit tests for rtponviftimestamp and rtponvifparse elements in separate files. Setup and cleanup the element and pads in fixures. Make the tests work with CK_FORK=no as well, by cleaning up the 'buffers' list when needed. Make unit tests work when run in valgrind by unreffing all buffers, and by not allocating any payload in RTP buffers. Since we're not doing anything with the payload part, but we're memcmp-aring the complete buffer memory, valgrind complained about non-initialized memory being used. https://bugzilla.gnome.org/show_bug.cgi?id=757688
246 lines
6.1 KiB
C
246 lines
6.1 KiB
C
/*
|
|
* onviftimestamp.c
|
|
*
|
|
* Copyright (C) 2014 Axis Communications AB
|
|
* Author: Guillaume Desmottes <guillaume.desmottes@collabora.com>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <gst/check/gstcheck.h>
|
|
#include <gst/rtp/gstrtpbuffer.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;
|
|
|
|
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
|
|
GST_PAD_SINK,
|
|
GST_PAD_ALWAYS,
|
|
GST_STATIC_CAPS ("application/x-rtp")
|
|
);
|
|
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
|
|
GST_PAD_SRC,
|
|
GST_PAD_ALWAYS,
|
|
GST_STATIC_CAPS ("application/x-rtp")
|
|
);
|
|
|
|
#define NTP_OFFSET (guint64) 1245
|
|
#define TIMESTAMP 42
|
|
|
|
static void
|
|
setup_element (GstElement * element)
|
|
{
|
|
mysrcpad = gst_check_setup_src_pad (element, &srctemplate);
|
|
mysinkpad = gst_check_setup_sink_pad (element, &sinktemplate);
|
|
gst_pad_set_active (mysrcpad, TRUE);
|
|
gst_pad_set_active (mysinkpad, TRUE);
|
|
|
|
fail_unless (gst_element_set_state (element,
|
|
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
|
|
"could not set to playing");
|
|
}
|
|
|
|
static void
|
|
cleanup_element (GstElement * element)
|
|
{
|
|
fail_unless (gst_element_set_state (element,
|
|
GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
|
|
|
|
gst_pad_set_active (mysrcpad, FALSE);
|
|
if (mysinkpad)
|
|
gst_pad_set_active (mysinkpad, FALSE);
|
|
gst_check_teardown_src_pad (element);
|
|
gst_check_teardown_sink_pad (element);
|
|
gst_check_teardown_element (element);
|
|
mysrcpad = NULL;
|
|
mysinkpad = NULL;
|
|
}
|
|
|
|
static guint64
|
|
convert_to_ntp (guint64 t)
|
|
{
|
|
guint64 ntptime;
|
|
|
|
/* convert to NTP time. upper 32 bits should contain the seconds
|
|
* and the lower 32 bits, the fractions of a second. */
|
|
ntptime = gst_util_uint64_scale (t, (G_GINT64_CONSTANT (1) << 32),
|
|
GST_SECOND);
|
|
|
|
return ntptime;
|
|
}
|
|
|
|
/* Create a copy of @buffer_in having the RTP extension */
|
|
static GstBuffer *
|
|
create_extension_buffer (GstBuffer * buffer_in, gboolean clean_point,
|
|
gboolean end_contiguous, gboolean discont)
|
|
{
|
|
GstBuffer *buffer_out;
|
|
GstRTPBuffer rtpbuffer_out = GST_RTP_BUFFER_INIT;
|
|
guint8 *data;
|
|
guint8 flags = 0;
|
|
|
|
buffer_out = gst_buffer_copy (buffer_in);
|
|
|
|
fail_unless (gst_rtp_buffer_map (buffer_out, GST_MAP_READWRITE,
|
|
&rtpbuffer_out));
|
|
|
|
/* extension */
|
|
gst_rtp_buffer_set_extension_data (&rtpbuffer_out, 0xABAC, 3);
|
|
fail_unless (gst_rtp_buffer_get_extension (&rtpbuffer_out));
|
|
gst_rtp_buffer_get_extension_data (&rtpbuffer_out, NULL, (gpointer) & data,
|
|
NULL);
|
|
|
|
/* NTP timestamp */
|
|
GST_WRITE_UINT64_BE (data, convert_to_ntp (buffer_in->pts + NTP_OFFSET));
|
|
|
|
/* C E D mbz */
|
|
if (clean_point)
|
|
flags |= (1 << 7);
|
|
if (end_contiguous)
|
|
flags |= (1 << 6);
|
|
if (discont)
|
|
flags |= (1 << 5);
|
|
|
|
GST_WRITE_UINT8 (data + 8, flags);
|
|
|
|
/* CSeq */
|
|
GST_WRITE_UINT8 (data + 9, 0x78);
|
|
|
|
memset (data + 10, 0, 4);
|
|
|
|
gst_rtp_buffer_unmap (&rtpbuffer_out);
|
|
|
|
return buffer_out;
|
|
}
|
|
|
|
static GstElement *
|
|
setup_rtponvifparse (gboolean set_e_bit)
|
|
{
|
|
GstElement *parse;
|
|
|
|
GST_DEBUG ("setup_rtponvifparse");
|
|
parse = gst_check_setup_element ("rtponvifparse");
|
|
|
|
setup_element (parse);
|
|
|
|
return parse;
|
|
}
|
|
|
|
static void
|
|
cleanup_rtponvifparse (GstElement * parse)
|
|
{
|
|
GST_DEBUG ("cleanup_rtponvifparse");
|
|
|
|
cleanup_element (parse);
|
|
}
|
|
|
|
static void
|
|
test_parse (gboolean clean_point, gboolean discont)
|
|
{
|
|
GstElement *parse;
|
|
GstBuffer *rtp, *buf;
|
|
GstSegment segment;
|
|
|
|
parse = setup_rtponvifparse (FALSE);
|
|
|
|
rtp = gst_rtp_buffer_new_allocate (4, 0, 0);
|
|
buf = create_extension_buffer (rtp, clean_point, FALSE, discont);
|
|
gst_buffer_unref (rtp);
|
|
|
|
/* stream start */
|
|
fail_unless (gst_pad_push_event (mysrcpad,
|
|
gst_event_new_stream_start ("test")));
|
|
|
|
/* Push a segment */
|
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
|
fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
|
|
|
|
/* Push buffer */
|
|
fail_unless (gst_pad_push (mysrcpad, buf) == GST_FLOW_OK,
|
|
"failed pushing buffer");
|
|
|
|
g_assert_cmpuint (g_list_length (buffers), ==, 1);
|
|
buf = buffers->data;
|
|
|
|
if (clean_point)
|
|
g_assert (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT));
|
|
else
|
|
g_assert (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT));
|
|
|
|
if (discont)
|
|
g_assert (GST_BUFFER_IS_DISCONT (buf));
|
|
else
|
|
g_assert (!GST_BUFFER_IS_DISCONT (buf));
|
|
|
|
g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
|
|
g_list_free (buffers);
|
|
buffers = NULL;
|
|
|
|
ASSERT_OBJECT_REFCOUNT (parse, "rtponvifparse", 1);
|
|
cleanup_rtponvifparse (parse);
|
|
}
|
|
|
|
GST_START_TEST (test_parse_no_flag)
|
|
{
|
|
test_parse (FALSE, FALSE);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_parse_clean_point)
|
|
{
|
|
test_parse (TRUE, FALSE);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_parse_discont)
|
|
{
|
|
test_parse (FALSE, TRUE);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
static Suite *
|
|
onviftimestamp_suite (void)
|
|
{
|
|
Suite *s = suite_create ("onviftimestamp");
|
|
TCase *tc_chain;
|
|
|
|
tc_chain = tcase_create ("parse");
|
|
suite_add_tcase (s, tc_chain);
|
|
tcase_add_test (tc_chain, test_parse_no_flag);
|
|
tcase_add_test (tc_chain, test_parse_clean_point);
|
|
tcase_add_test (tc_chain, test_parse_discont);
|
|
|
|
return s;
|
|
}
|
|
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
int nf;
|
|
Suite *s = onviftimestamp_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;
|
|
}
|