Merging gst-plugins-bad
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / tests / check / elements / rtponvifparse.c
1 /*
2  * onviftimestamp.c
3  *
4  * Copyright (C) 2014 Axis Communications AB
5  *  Author: Guillaume Desmottes <guillaume.desmottes@collabora.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <gst/check/gstcheck.h>
22 #include <gst/rtp/gstrtpbuffer.h>
23
24 /* For ease of programming we use globals to keep refs for our floating
25  * src and sink pads we create; otherwise we always have to do get_pad,
26  * get_peer, and then remove references in every test function */
27 static GstPad *mysrcpad, *mysinkpad;
28
29 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
30     GST_PAD_SINK,
31     GST_PAD_ALWAYS,
32     GST_STATIC_CAPS ("application/x-rtp")
33     );
34 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
35     GST_PAD_SRC,
36     GST_PAD_ALWAYS,
37     GST_STATIC_CAPS ("application/x-rtp")
38     );
39
40 #define NTP_OFFSET (guint64) 1245
41 #define TIMESTAMP 42
42
43 static void
44 setup_element (GstElement * element)
45 {
46   mysrcpad = gst_check_setup_src_pad (element, &srctemplate);
47   mysinkpad = gst_check_setup_sink_pad (element, &sinktemplate);
48   gst_pad_set_active (mysrcpad, TRUE);
49   gst_pad_set_active (mysinkpad, TRUE);
50
51   fail_unless (gst_element_set_state (element,
52           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
53       "could not set to playing");
54 }
55
56 static void
57 cleanup_element (GstElement * element)
58 {
59   fail_unless (gst_element_set_state (element,
60           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
61
62   gst_pad_set_active (mysrcpad, FALSE);
63   if (mysinkpad)
64     gst_pad_set_active (mysinkpad, FALSE);
65   gst_check_teardown_src_pad (element);
66   gst_check_teardown_sink_pad (element);
67   gst_check_teardown_element (element);
68   mysrcpad = NULL;
69   mysinkpad = NULL;
70 }
71
72 static guint64
73 convert_to_ntp (guint64 t)
74 {
75   guint64 ntptime;
76
77   /* convert to NTP time. upper 32 bits should contain the seconds
78    * and the lower 32 bits, the fractions of a second. */
79   ntptime = gst_util_uint64_scale (t, (G_GINT64_CONSTANT (1) << 32),
80       GST_SECOND);
81
82   return ntptime;
83 }
84
85 /* Create a copy of @buffer_in having the RTP extension */
86 static GstBuffer *
87 create_extension_buffer (GstBuffer * buffer_in, gboolean clean_point,
88     gboolean end_contiguous, gboolean discont)
89 {
90   GstBuffer *buffer_out;
91   GstRTPBuffer rtpbuffer_out = GST_RTP_BUFFER_INIT;
92   guint8 *data;
93   guint8 flags = 0;
94
95   buffer_out = gst_buffer_copy (buffer_in);
96
97   fail_unless (gst_rtp_buffer_map (buffer_out, GST_MAP_READWRITE,
98           &rtpbuffer_out));
99
100   /* extension */
101   gst_rtp_buffer_set_extension_data (&rtpbuffer_out, 0xABAC, 3);
102   fail_unless (gst_rtp_buffer_get_extension (&rtpbuffer_out));
103   gst_rtp_buffer_get_extension_data (&rtpbuffer_out, NULL, (gpointer) & data,
104       NULL);
105
106   /* NTP timestamp */
107   GST_WRITE_UINT64_BE (data, convert_to_ntp (buffer_in->pts + NTP_OFFSET));
108
109   /* C E D mbz */
110   if (clean_point)
111     flags |= (1 << 7);
112   if (end_contiguous)
113     flags |= (1 << 6);
114   if (discont)
115     flags |= (1 << 5);
116
117   GST_WRITE_UINT8 (data + 8, flags);
118
119   /* CSeq */
120   GST_WRITE_UINT8 (data + 9, 0x78);
121
122   memset (data + 10, 0, 4);
123
124   gst_rtp_buffer_unmap (&rtpbuffer_out);
125
126   return buffer_out;
127 }
128
129 static GstElement *
130 setup_rtponvifparse (gboolean set_e_bit)
131 {
132   GstElement *parse;
133
134   GST_DEBUG ("setup_rtponvifparse");
135   parse = gst_check_setup_element ("rtponvifparse");
136
137   setup_element (parse);
138
139   return parse;
140 }
141
142 static void
143 cleanup_rtponvifparse (GstElement * parse)
144 {
145   GST_DEBUG ("cleanup_rtponvifparse");
146
147   cleanup_element (parse);
148 }
149
150 static void
151 test_parse (gboolean clean_point, gboolean discont)
152 {
153   GstElement *parse;
154   GstBuffer *rtp, *buf;
155   GstSegment segment;
156
157   parse = setup_rtponvifparse (FALSE);
158
159   rtp = gst_rtp_buffer_new_allocate (4, 0, 0);
160   buf = create_extension_buffer (rtp, clean_point, FALSE, discont);
161   gst_buffer_unref (rtp);
162
163   /* stream start */
164   fail_unless (gst_pad_push_event (mysrcpad,
165           gst_event_new_stream_start ("test")));
166
167   /* Push a segment */
168   gst_segment_init (&segment, GST_FORMAT_TIME);
169   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
170
171   /* Push buffer */
172   fail_unless (gst_pad_push (mysrcpad, buf) == GST_FLOW_OK,
173       "failed pushing buffer");
174
175   g_assert_cmpuint (g_list_length (buffers), ==, 1);
176   buf = buffers->data;
177
178   if (clean_point)
179     g_assert (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT));
180   else
181     g_assert (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT));
182
183   if (discont)
184     g_assert (GST_BUFFER_IS_DISCONT (buf));
185   else
186     g_assert (!GST_BUFFER_IS_DISCONT (buf));
187
188   g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
189   g_list_free (buffers);
190   buffers = NULL;
191
192   ASSERT_OBJECT_REFCOUNT (parse, "rtponvifparse", 1);
193   cleanup_rtponvifparse (parse);
194 }
195
196 GST_START_TEST (test_parse_no_flag)
197 {
198   test_parse (FALSE, FALSE);
199 }
200
201 GST_END_TEST;
202
203 GST_START_TEST (test_parse_clean_point)
204 {
205   test_parse (TRUE, FALSE);
206 }
207
208 GST_END_TEST;
209
210 GST_START_TEST (test_parse_discont)
211 {
212   test_parse (FALSE, TRUE);
213 }
214
215 GST_END_TEST;
216
217 static Suite *
218 onviftimestamp_suite (void)
219 {
220   Suite *s = suite_create ("onviftimestamp");
221   TCase *tc_chain;
222
223   tc_chain = tcase_create ("parse");
224   suite_add_tcase (s, tc_chain);
225   tcase_add_test (tc_chain, test_parse_no_flag);
226   tcase_add_test (tc_chain, test_parse_clean_point);
227   tcase_add_test (tc_chain, test_parse_discont);
228
229   return s;
230 }
231
232 GST_CHECK_MAIN (onviftimestamp);