1 /* GStreamer RTP base payloader unit tests
2 * Copyright (C) 2014 Sebastian Rasmussen <sebras@hotmail.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General
15 * Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <gst/gst.h>
25 #include <gst/check/gstcheck.h>
26 #include <gst/check/gstharness.h>
27 #include <gst/rtp/rtp.h>
28
29 #include "rtpdummyhdrextimpl.c"
30
31 #define DEFAULT_CLOCK_RATE (42)
32 #define BUFFER_BEFORE_LIST (10)
33
34 /* GstRtpDummyPay */
35
36 #define GST_TYPE_RTP_DUMMY_PAY \
37 (gst_rtp_dummy_pay_get_type())
38 #define GST_RTP_DUMMY_PAY(obj) \
39 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_DUMMY_PAY,GstRtpDummyPay))
40 #define GST_RTP_DUMMY_PAY_CLASS(klass) \
41 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_DUMMY_PAY,GstRtpDummyPayClass))
42 #define GST_IS_RTP_DUMMY_PAY(obj) \
43 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_DUMMY_PAY))
44 #define GST_IS_RTP_DUMMY_PAY_CLASS(klass) \
45 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_DUMMY_PAY))
46
47 typedef struct _GstRtpDummyPay GstRtpDummyPay;
48 typedef struct _GstRtpDummyPayClass GstRtpDummyPayClass;
49
50 struct _GstRtpDummyPay
51 {
52 GstRTPBasePayload payload;
53 };
54
55 struct _GstRtpDummyPayClass
56 {
57 GstRTPBasePayloadClass parent_class;
58 };
59
60 GType gst_rtp_dummy_pay_get_type (void);
61
62 G_DEFINE_TYPE (GstRtpDummyPay, gst_rtp_dummy_pay, GST_TYPE_RTP_BASE_PAYLOAD);
63
64 static GstFlowReturn gst_rtp_dummy_pay_handle_buffer (GstRTPBasePayload * pay,
65 GstBuffer * buffer);
66
67 static GstStaticPadTemplate gst_rtp_dummy_pay_sink_template =
68 GST_STATIC_PAD_TEMPLATE ("sink",
69 GST_PAD_SINK,
70 GST_PAD_ALWAYS,
71 GST_STATIC_CAPS_ANY);
72
73 static GstStaticPadTemplate gst_rtp_dummy_pay_src_template =
74 GST_STATIC_PAD_TEMPLATE ("src",
75 GST_PAD_SRC,
76 GST_PAD_ALWAYS,
77 GST_STATIC_CAPS ("application/x-rtp"));
78
79 static void
gst_rtp_dummy_pay_class_init(GstRtpDummyPayClass * klass)80 gst_rtp_dummy_pay_class_init (GstRtpDummyPayClass * klass)
81 {
82 GstElementClass *gstelement_class;
83 GstRTPBasePayloadClass *gstrtpbasepayload_class;
84
85 gstelement_class = GST_ELEMENT_CLASS (klass);
86 gstrtpbasepayload_class = GST_RTP_BASE_PAYLOAD_CLASS (klass);
87
88 gst_element_class_add_static_pad_template (gstelement_class,
89 &gst_rtp_dummy_pay_sink_template);
90 gst_element_class_add_static_pad_template (gstelement_class,
91 &gst_rtp_dummy_pay_src_template);
92
93 gstrtpbasepayload_class->handle_buffer = gst_rtp_dummy_pay_handle_buffer;
94 }
95
96 static void
gst_rtp_dummy_pay_init(GstRtpDummyPay * pay)97 gst_rtp_dummy_pay_init (GstRtpDummyPay * pay)
98 {
99 gst_rtp_base_payload_set_options (GST_RTP_BASE_PAYLOAD (pay), "application",
100 TRUE, "dummy", DEFAULT_CLOCK_RATE);
101 }
102
103 static GstRtpDummyPay *
rtp_dummy_pay_new(void)104 rtp_dummy_pay_new (void)
105 {
106 return g_object_new (GST_TYPE_RTP_DUMMY_PAY, NULL);
107 }
108
109 static GstFlowReturn
gst_rtp_dummy_pay_handle_buffer(GstRTPBasePayload * pay,GstBuffer * buffer)110 gst_rtp_dummy_pay_handle_buffer (GstRTPBasePayload * pay, GstBuffer * buffer)
111 {
112 GstBuffer *paybuffer;
113
114 GST_LOG ("payloading %" GST_PTR_FORMAT, buffer);
115
116 if (!gst_pad_has_current_caps (GST_RTP_BASE_PAYLOAD_SRCPAD (pay))) {
117 if (!gst_rtp_base_payload_set_outcaps (GST_RTP_BASE_PAYLOAD (pay),
118 "custom-caps", G_TYPE_UINT, DEFAULT_CLOCK_RATE, NULL)) {
119 gst_buffer_unref (buffer);
120 return GST_FLOW_NOT_NEGOTIATED;
121 }
122 }
123
124 paybuffer =
125 gst_rtp_base_payload_allocate_output_buffer (GST_RTP_BASE_PAYLOAD (pay),
126 0, 0, 0);
127
128 GST_BUFFER_PTS (paybuffer) = GST_BUFFER_PTS (buffer);
129 GST_BUFFER_OFFSET (paybuffer) = GST_BUFFER_OFFSET (buffer);
130
131 gst_buffer_append (paybuffer, buffer);
132
133 GST_LOG ("payloaded %" GST_PTR_FORMAT, paybuffer);
134
135 if (GST_BUFFER_PTS (paybuffer) < BUFFER_BEFORE_LIST) {
136 return gst_rtp_base_payload_push (pay, paybuffer);
137 } else {
138 GstBufferList *list = gst_buffer_list_new ();
139 gst_buffer_list_add (list, paybuffer);
140 return gst_rtp_base_payload_push_list (pay, list);
141 }
142 }
143
144 /* Helper functions and global state */
145
146 static GstStaticPadTemplate srctmpl = GST_STATIC_PAD_TEMPLATE ("src",
147 GST_PAD_SRC,
148 GST_PAD_ALWAYS,
149 GST_STATIC_CAPS_ANY);
150
151 static GstStaticPadTemplate sinktmpl = GST_STATIC_PAD_TEMPLATE ("sink",
152 GST_PAD_SINK,
153 GST_PAD_ALWAYS,
154 GST_STATIC_CAPS_ANY);
155
156 static GstStaticPadTemplate special_sinktmpl = GST_STATIC_PAD_TEMPLATE ("sink",
157 GST_PAD_SINK,
158 GST_PAD_ALWAYS,
159 GST_STATIC_CAPS ("application/x-rtp, payload=(int)98, ssrc=(uint)24, "
160 "timestamp-offset=(uint)212, seqnum-offset=(uint)2424"));
161
162 typedef struct State State;
163
164 struct State
165 {
166 GstElement *element;
167 GstPad *sinkpad;
168 GstPad *srcpad;
169 };
170
171 static GList *events;
172
173 static gboolean
event_func(GstPad * pad,GstObject * noparent,GstEvent * event)174 event_func (GstPad * pad, GstObject * noparent, GstEvent * event)
175 {
176 events = g_list_append (events, gst_event_ref (event));
177 return gst_pad_event_default (pad, noparent, event);
178 }
179
180 static void
drop_events(void)181 drop_events (void)
182 {
183 while (events != NULL) {
184 gst_event_unref (GST_EVENT (events->data));
185 events = g_list_delete_link (events, events);
186 }
187 }
188
189 static void
validate_events_received(guint received)190 validate_events_received (guint received)
191 {
192 fail_unless_equals_int (g_list_length (events), received);
193 }
194
195 static void
validate_event(guint index,const gchar * name,const gchar * field,...)196 validate_event (guint index, const gchar * name, const gchar * field, ...)
197 {
198 GstEvent *event;
199 va_list var_args;
200
201 fail_if (index >= g_list_length (events));
202 event = GST_EVENT (g_list_nth_data (events, index));
203 fail_if (event == NULL);
204
205 GST_TRACE ("%" GST_PTR_FORMAT, event);
206
207 fail_unless_equals_string (GST_EVENT_TYPE_NAME (event), name);
208
209 va_start (var_args, field);
210 while (field) {
211 if (!g_strcmp0 (field, "timestamp")) {
212 GstClockTime expected = va_arg (var_args, GstClockTime);
213 GstClockTime timestamp, duration;
214 gst_event_parse_gap (event, ×tamp, &duration);
215 fail_unless_equals_uint64 (timestamp, expected);
216 } else if (!g_strcmp0 (field, "duration")) {
217 GstClockTime expected = va_arg (var_args, GstClockTime);
218 GstClockTime timestamp, duration;
219 gst_event_parse_gap (event, ×tamp, &duration);
220 fail_unless_equals_uint64 (duration, expected);
221 } else if (!g_strcmp0 (field, "time")) {
222 GstClockTime expected = va_arg (var_args, GstClockTime);
223 const GstSegment *segment;
224 gst_event_parse_segment (event, &segment);
225 fail_unless_equals_uint64 (segment->time, expected);
226 } else if (!g_strcmp0 (field, "start")) {
227 GstClockTime expected = va_arg (var_args, GstClockTime);
228 const GstSegment *segment;
229 gst_event_parse_segment (event, &segment);
230 fail_unless_equals_uint64 (segment->start, expected);
231 } else if (!g_strcmp0 (field, "stop")) {
232 GstClockTime expected = va_arg (var_args, GstClockTime);
233 const GstSegment *segment;
234 gst_event_parse_segment (event, &segment);
235 fail_unless_equals_uint64 (segment->stop, expected);
236 } else if (!g_strcmp0 (field, "applied-rate")) {
237 gdouble expected = va_arg (var_args, gdouble);
238 const GstSegment *segment;
239 gst_event_parse_segment (event, &segment);
240 fail_unless_equals_float (segment->applied_rate, expected);
241 } else if (!g_strcmp0 (field, "rate")) {
242 gdouble expected = va_arg (var_args, gdouble);
243 const GstSegment *segment;
244 gst_event_parse_segment (event, &segment);
245 fail_unless_equals_float (segment->rate, expected);
246 } else if (!g_strcmp0 (field, "media-type")) {
247 const gchar *expected = va_arg (var_args, const gchar *);
248 GstCaps *caps;
249 const gchar *media_type;
250 gst_event_parse_caps (event, &caps);
251 media_type = gst_structure_get_name (gst_caps_get_structure (caps, 0));
252 fail_unless_equals_string (media_type, expected);
253 } else if (!g_strcmp0 (field, "npt-start")) {
254 GstClockTime expected = va_arg (var_args, GstClockTime);
255 GstCaps *caps;
256 GstClockTime start;
257 gst_event_parse_caps (event, &caps);
258 fail_unless (gst_structure_get_clock_time (gst_caps_get_structure (caps,
259 0), "npt-start", &start));
260 fail_unless_equals_uint64 (start, expected);
261 } else if (!g_strcmp0 (field, "npt-stop")) {
262 GstClockTime expected = va_arg (var_args, GstClockTime);
263 GstCaps *caps;
264 GstClockTime stop;
265 gst_event_parse_caps (event, &caps);
266 fail_unless (gst_structure_get_clock_time (gst_caps_get_structure (caps,
267 0), "npt-stop", &stop));
268 fail_unless_equals_uint64 (stop, expected);
269 } else if (!g_strcmp0 (field, "play-speed")) {
270 gdouble expected = va_arg (var_args, gdouble);
271 GstCaps *caps;
272 gdouble speed;
273 gst_event_parse_caps (event, &caps);
274 fail_unless (gst_structure_get_double (gst_caps_get_structure (caps, 0),
275 "play-speed", &speed));
276 fail_unless (speed == expected);
277 } else if (!g_strcmp0 (field, "play-scale")) {
278 gdouble expected = va_arg (var_args, gdouble);
279 GstCaps *caps;
280 gdouble scale;
281 gst_event_parse_caps (event, &caps);
282 fail_unless (gst_structure_get_double (gst_caps_get_structure (caps, 0),
283 "play-scale", &scale));
284 fail_unless (scale == expected);
285 } else if (!g_strcmp0 (field, "ssrc")) {
286 guint expected = va_arg (var_args, guint);
287 GstCaps *caps;
288 guint ssrc;
289 gst_event_parse_caps (event, &caps);
290 fail_unless (gst_structure_get_uint (gst_caps_get_structure (caps, 0),
291 "ssrc", &ssrc));
292 fail_unless_equals_int (ssrc, expected);
293 } else if (!g_strcmp0 (field, "a-framerate")) {
294 const gchar *expected = va_arg (var_args, const gchar *);
295 GstCaps *caps;
296 const gchar *framerate;
297 gst_event_parse_caps (event, &caps);
298 framerate = gst_structure_get_string (gst_caps_get_structure (caps, 0),
299 "a-framerate");
300 fail_unless_equals_string (framerate, expected);
301 } else if (!g_strcmp0 (field, "extmap-str")) {
302 guint ext_id = va_arg (var_args, guint);
303 const gchar *expected_ext_str = va_arg (var_args, const gchar *);
304 GstCaps *caps;
305 const gchar *ext_str;
306 gchar *ext_field = g_strdup_printf ("extmap-%u", ext_id);
307 gst_event_parse_caps (event, &caps);
308 ext_str = gst_structure_get_string (gst_caps_get_structure (caps, 0),
309 ext_field);
310 fail_unless_equals_string (ext_str, expected_ext_str);
311 g_free (ext_field);
312 } else {
313 fail ("test cannot validate unknown event field '%s'", field);
314 }
315 field = va_arg (var_args, const gchar *);
316 }
317 va_end (var_args);
318 }
319
320 static void
validate_normal_start_events(guint index)321 validate_normal_start_events (guint index)
322 {
323 validate_event (index, "stream-start", NULL);
324
325 validate_event (index + 1, "caps", "media-type", "application/x-rtp", NULL);
326
327 validate_event (index + 2, "segment",
328 "time", G_GUINT64_CONSTANT (0),
329 "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
330 }
331
332 #define push_buffer(state, field, ...) \
333 push_buffer_full ((state), GST_FLOW_OK, (field), __VA_ARGS__)
334 #define push_buffer_fails(state, error, field, ...) \
335 push_buffer_full ((state), (error), (field), __VA_ARGS__)
336
337 static void
push_buffer_full(State * state,GstFlowReturn expected,const gchar * field,...)338 push_buffer_full (State * state, GstFlowReturn expected,
339 const gchar * field, ...)
340 {
341 GstBuffer *buf = gst_buffer_new_allocate (0, 0, 0);
342 GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
343 gboolean mapped = FALSE;
344 va_list var_args;
345
346 va_start (var_args, field);
347 while (field) {
348 if (!g_strcmp0 (field, "pts")) {
349 GstClockTime pts = va_arg (var_args, GstClockTime);
350 GST_BUFFER_PTS (buf) = pts;
351 } else if (!g_strcmp0 (field, "offset")) {
352 guint64 offset = va_arg (var_args, guint64);
353 GST_BUFFER_OFFSET (buf) = offset;
354 } else if (!g_strcmp0 (field, "discont")) {
355 gboolean discont = va_arg (var_args, gboolean);
356 if (discont) {
357 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
358 } else {
359 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
360 }
361 } else {
362 if (!mapped) {
363 gst_rtp_buffer_map (buf, GST_MAP_WRITE, &rtp);
364 mapped = TRUE;
365 }
366 if (!g_strcmp0 (field, "rtptime")) {
367 guint32 rtptime = va_arg (var_args, guint);
368 gst_rtp_buffer_set_timestamp (&rtp, rtptime);
369 } else if (!g_strcmp0 (field, "payload-type")) {
370 guint payload_type = va_arg (var_args, guint);
371 gst_rtp_buffer_set_payload_type (&rtp, payload_type);
372 } else if (!g_strcmp0 (field, "seq")) {
373 guint seq = va_arg (var_args, guint);
374 gst_rtp_buffer_set_seq (&rtp, seq);
375 } else if (!g_strcmp0 (field, "ssrc")) {
376 guint32 ssrc = va_arg (var_args, guint);
377 gst_rtp_buffer_set_ssrc (&rtp, ssrc);
378 } else {
379 fail ("test cannot set unknown buffer field '%s'", field);
380 }
381 }
382 field = va_arg (var_args, const gchar *);
383 }
384 va_end (var_args);
385
386 if (mapped) {
387 gst_rtp_buffer_unmap (&rtp);
388 }
389
390 fail_unless_equals_int (gst_pad_push (state->srcpad, buf), expected);
391 }
392
393 static void
push_buffer_list(State * state,const gchar * field,...)394 push_buffer_list (State * state, const gchar * field, ...)
395 {
396 GstBuffer *buf = gst_rtp_buffer_new_allocate (0, 0, 0);
397 GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
398 gboolean mapped = FALSE;
399 GstBufferList *list;
400 va_list var_args;
401
402 va_start (var_args, field);
403 while (field) {
404 if (!g_strcmp0 (field, "pts")) {
405 GstClockTime pts = va_arg (var_args, GstClockTime);
406 GST_BUFFER_PTS (buf) = pts;
407 } else if (!g_strcmp0 (field, "offset")) {
408 guint64 offset = va_arg (var_args, guint64);
409 GST_BUFFER_OFFSET (buf) = offset;
410 } else if (!g_strcmp0 (field, "discont")) {
411 gboolean discont = va_arg (var_args, gboolean);
412 if (discont) {
413 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
414 } else {
415 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
416 }
417 } else {
418 if (!mapped) {
419 gst_rtp_buffer_map (buf, GST_MAP_WRITE, &rtp);
420 mapped = TRUE;
421 }
422 if (!g_strcmp0 (field, "rtptime")) {
423 guint32 rtptime = va_arg (var_args, guint);
424 gst_rtp_buffer_set_timestamp (&rtp, rtptime);
425 } else if (!g_strcmp0 (field, "payload-type")) {
426 guint payload_type = va_arg (var_args, guint);
427 gst_rtp_buffer_set_payload_type (&rtp, payload_type);
428 } else if (!g_strcmp0 (field, "seq")) {
429 guint seq = va_arg (var_args, guint);
430 gst_rtp_buffer_set_seq (&rtp, seq);
431 } else if (!g_strcmp0 (field, "ssrc")) {
432 guint32 ssrc = va_arg (var_args, guint);
433 gst_rtp_buffer_set_ssrc (&rtp, ssrc);
434 } else {
435 fail ("test cannot set unknown buffer field '%s'", field);
436 }
437 }
438 field = va_arg (var_args, const gchar *);
439 }
440 va_end (var_args);
441
442 if (mapped) {
443 gst_rtp_buffer_unmap (&rtp);
444 }
445
446 list = gst_buffer_list_new ();
447 gst_buffer_list_add (list, buf);
448 fail_unless_equals_int (gst_pad_push_list (state->srcpad, list), GST_FLOW_OK);
449 }
450
451 static void
validate_buffers_received(guint received_buffers)452 validate_buffers_received (guint received_buffers)
453 {
454 fail_unless_equals_int (g_list_length (buffers), received_buffers);
455 }
456
457 static void
validate_buffer_valist(GstBuffer * buf,const gchar * field,va_list var_args)458 validate_buffer_valist (GstBuffer * buf, const gchar * field, va_list var_args)
459 {
460 GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
461 gboolean mapped = FALSE;
462
463 while (field) {
464 if (!g_strcmp0 (field, "pts")) {
465 GstClockTime pts = va_arg (var_args, GstClockTime);
466 fail_unless_equals_uint64 (GST_BUFFER_PTS (buf), pts);
467 } else if (!g_strcmp0 (field, "offset")) {
468 guint64 offset = va_arg (var_args, guint64);
469 fail_unless_equals_uint64 (GST_BUFFER_OFFSET (buf), offset);
470 } else if (!g_strcmp0 (field, "discont")) {
471 gboolean discont = va_arg (var_args, gboolean);
472 if (discont) {
473 fail_unless (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
474 } else {
475 fail_if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
476 }
477 } else if (!g_strcmp0 (field, "size")) {
478 gsize expected_size = va_arg (var_args, gsize);
479 fail_unless_equals_int64 ((guint64) expected_size,
480 gst_buffer_get_size (buf));
481 } else {
482 if (!mapped) {
483 gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp);
484 mapped = TRUE;
485 }
486 if (!g_strcmp0 (field, "rtptime")) {
487 guint32 rtptime = va_arg (var_args, guint);
488 fail_unless_equals_int (gst_rtp_buffer_get_timestamp (&rtp), rtptime);
489 } else if (!g_strcmp0 (field, "payload-type")) {
490 guint pt = va_arg (var_args, guint);
491 fail_unless_equals_int (gst_rtp_buffer_get_payload_type (&rtp), pt);
492 } else if (!g_strcmp0 (field, "seq")) {
493 guint seq = va_arg (var_args, guint);
494 fail_unless_equals_int (gst_rtp_buffer_get_seq (&rtp), seq);
495 } else if (!g_strcmp0 (field, "ssrc")) {
496 guint32 ssrc = va_arg (var_args, guint);
497 fail_unless_equals_int (gst_rtp_buffer_get_ssrc (&rtp), ssrc);
498 } else if (!g_strcmp0 (field, "csrc")) {
499 guint idx = va_arg (var_args, guint);
500 guint csrc = va_arg (var_args, guint);
501 fail_unless_equals_int (gst_rtp_buffer_get_csrc (&rtp, idx), csrc);
502 } else if (!g_strcmp0 (field, "csrc-count")) {
503 guint csrc_count = va_arg (var_args, guint);
504 fail_unless_equals_int (gst_rtp_buffer_get_csrc_count (&rtp),
505 csrc_count);
506 } else if (!g_strcmp0 (field, "ext-data")) {
507 guint expected_bits = va_arg (var_args, guint) & 0xFFFF;
508 gsize expected_size = va_arg (var_args, gsize);
509 gpointer data;
510 guint word_len;
511 guint16 ext_bits;
512 gst_rtp_buffer_get_extension_data (&rtp, &ext_bits, &data, &word_len);
513 GST_MEMDUMP ("ext data", data, word_len * 4);
514 fail_unless_equals_int (expected_bits, ext_bits);
515 fail_unless_equals_int64 ((guint64) expected_size,
516 (guint64) word_len * 4);
517 } else {
518 fail ("test cannot validate unknown buffer field '%s'", field);
519 }
520 }
521 field = va_arg (var_args, const gchar *);
522 }
523
524 if (mapped) {
525 gst_rtp_buffer_unmap (&rtp);
526 }
527 }
528
529 static void
validate_buffer1(GstBuffer * buf,const gchar * field,...)530 validate_buffer1 (GstBuffer * buf, const gchar * field, ...)
531 {
532 va_list var_args;
533
534 va_start (var_args, field);
535 validate_buffer_valist (buf, field, var_args);
536 va_end (var_args);
537 }
538
539 static void
validate_buffer(guint index,const gchar * field,...)540 validate_buffer (guint index, const gchar * field, ...)
541 {
542 GstBuffer *buf;
543 va_list var_args;
544
545 fail_if (index >= g_list_length (buffers));
546 buf = GST_BUFFER (g_list_nth_data (buffers, index));
547 fail_if (buf == NULL);
548
549 GST_TRACE ("%" GST_PTR_FORMAT, buf);
550
551 va_start (var_args, field);
552 validate_buffer_valist (buf, field, var_args);
553 va_end (var_args);
554 }
555
556 static void
get_buffer_field(guint index,const gchar * field,...)557 get_buffer_field (guint index, const gchar * field, ...)
558 {
559 GstBuffer *buf;
560 GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
561 gboolean mapped = FALSE;
562 va_list var_args;
563
564 fail_if (index >= g_list_length (buffers));
565 buf = GST_BUFFER (g_list_nth_data (buffers, (index)));
566 fail_if (buf == NULL);
567
568 va_start (var_args, field);
569 while (field) {
570 if (!g_strcmp0 (field, "pts")) {
571 GstClockTime *pts = va_arg (var_args, GstClockTime *);
572 *pts = GST_BUFFER_PTS (buf);
573 } else if (!g_strcmp0 (field, "offset")) {
574 guint64 *offset = va_arg (var_args, guint64 *);
575 *offset = GST_BUFFER_OFFSET (buf);
576 } else if (!g_strcmp0 (field, "discont")) {
577 gboolean *discont = va_arg (var_args, gboolean *);
578 *discont = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT);
579 } else {
580 if (!mapped) {
581 gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp);
582 mapped = TRUE;
583 }
584 if (!g_strcmp0 (field, "rtptime")) {
585 guint32 *rtptime = va_arg (var_args, guint32 *);
586 *rtptime = gst_rtp_buffer_get_timestamp (&rtp);
587 } else if (!g_strcmp0 (field, "payload-type")) {
588 guint *pt = va_arg (var_args, guint *);
589 *pt = gst_rtp_buffer_get_payload_type (&rtp);
590 } else if (!g_strcmp0 (field, "seq")) {
591 guint16 *seq = va_arg (var_args, guint16 *);
592 *seq = gst_rtp_buffer_get_seq (&rtp);
593 } else if (!g_strcmp0 (field, "ssrc")) {
594 guint32 *ssrc = va_arg (var_args, guint32 *);
595 *ssrc = gst_rtp_buffer_get_ssrc (&rtp);
596 } else {
597 fail ("test retrieve validate unknown buffer field '%s'", field);
598 }
599 }
600 field = va_arg (var_args, const gchar *);
601 }
602 va_end (var_args);
603
604 if (mapped)
605 gst_rtp_buffer_unmap (&rtp);
606 }
607
608 static State *
create_payloader(const gchar * caps_str,GstStaticPadTemplate * sinktmpl,const gchar * property,...)609 create_payloader (const gchar * caps_str,
610 GstStaticPadTemplate * sinktmpl, const gchar * property, ...)
611 {
612 va_list var_args;
613 GstCaps *caps;
614 State *state;
615
616 state = g_new0 (State, 1);
617
618 state->element = GST_ELEMENT (rtp_dummy_pay_new ());
619 fail_unless (GST_IS_RTP_DUMMY_PAY (state->element));
620
621 va_start (var_args, property);
622 g_object_set_valist (G_OBJECT (state->element), property, var_args);
623 va_end (var_args);
624
625 state->srcpad = gst_check_setup_src_pad (state->element, &srctmpl);
626 state->sinkpad = gst_check_setup_sink_pad (state->element, sinktmpl);
627
628 fail_unless (gst_pad_set_active (state->srcpad, TRUE));
629 fail_unless (gst_pad_set_active (state->sinkpad, TRUE));
630
631 caps = gst_caps_from_string (caps_str);
632 gst_check_setup_events (state->srcpad, state->element, caps, GST_FORMAT_TIME);
633 gst_caps_unref (caps);
634
635 gst_pad_set_chain_function (state->sinkpad, gst_check_chain_func);
636 gst_pad_set_event_function (state->sinkpad, event_func);
637
638 return state;
639 }
640
641 static void
set_state(State * state,GstState new_state)642 set_state (State * state, GstState new_state)
643 {
644 fail_unless_equals_int (gst_element_set_state (state->element, new_state),
645 GST_STATE_CHANGE_SUCCESS);
646 }
647
648 static void
validate_would_not_be_filled(State * state,guint size,GstClockTime duration)649 validate_would_not_be_filled (State * state, guint size, GstClockTime duration)
650 {
651 GstRTPBasePayload *basepay;
652 basepay = GST_RTP_BASE_PAYLOAD (state->element);
653 fail_if (gst_rtp_base_payload_is_filled (basepay, size, duration));
654 }
655
656 static void
validate_would_be_filled(State * state,guint size,GstClockTime duration)657 validate_would_be_filled (State * state, guint size, GstClockTime duration)
658 {
659 GstRTPBasePayload *basepay;
660 basepay = GST_RTP_BASE_PAYLOAD (state->element);
661 fail_unless (gst_rtp_base_payload_is_filled (basepay, size, duration));
662 }
663
664 static void
ssrc_collision(State * state,guint ssrc,gboolean have_new_ssrc,guint new_ssrc)665 ssrc_collision (State * state, guint ssrc,
666 gboolean have_new_ssrc, guint new_ssrc)
667 {
668 GstStructure *s;
669 GstEvent *event;
670 if (have_new_ssrc) {
671 s = gst_structure_new ("GstRTPCollision",
672 "ssrc", G_TYPE_UINT, ssrc,
673 "suggested-ssrc", G_TYPE_UINT, new_ssrc, NULL);
674 } else {
675 s = gst_structure_new ("GstRTPCollision", "ssrc", G_TYPE_UINT, ssrc, NULL);
676 }
677 event = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, s);
678 fail_unless (gst_pad_push_event (state->sinkpad, event));
679 }
680
681 static void
reconfigure(State * state)682 reconfigure (State * state)
683 {
684 GstEvent *event;
685 event = gst_event_new_reconfigure ();
686 fail_unless (gst_pad_push_event (state->sinkpad, event));
687 }
688
689 static void
validate_stats(State * state,guint clock_rate,GstClockTime running_time,guint16 seq,guint32 rtptime)690 validate_stats (State * state, guint clock_rate,
691 GstClockTime running_time, guint16 seq, guint32 rtptime)
692 {
693 GstStructure *stats;
694
695 g_object_get (state->element, "stats", &stats, NULL);
696
697 fail_unless_equals_int (g_value_get_uint (gst_structure_get_value (stats,
698 "clock-rate")), clock_rate);
699 fail_unless_equals_uint64 (g_value_get_uint64 (gst_structure_get_value (stats,
700 "running-time")), running_time);
701 fail_unless_equals_int (g_value_get_uint (gst_structure_get_value (stats,
702 "seqnum")), seq);
703 fail_unless_equals_int (g_value_get_uint (gst_structure_get_value (stats,
704 "timestamp")), rtptime);
705
706 gst_structure_free (stats);
707 }
708
709 static void
destroy_payloader(State * state)710 destroy_payloader (State * state)
711 {
712 gst_check_teardown_sink_pad (state->element);
713 gst_check_teardown_src_pad (state->element);
714
715 gst_check_drop_buffers ();
716 drop_events ();
717
718 g_object_unref (state->element);
719
720 g_free (state);
721 }
722
723 /* Tests */
724
725 /* push two buffers to the payloader which should successfully payload them
726 * into RTP packets. the first packet will have a random rtptime and sequence
727 * number, but the last packet should have an rtptime incremented by
728 * DEFAULT_CLOCK_RATE and a sequence number incremented by one because the
729 * packets are sequential. besides the two payloaded RTP packets there should
730 * be the three events initial events: stream-start, caps and segment.
731 */
GST_START_TEST(rtp_base_payload_buffer_test)732 GST_START_TEST (rtp_base_payload_buffer_test)
733 {
734 State *state;
735 guint32 rtptime;
736 guint16 seq;
737
738 state = create_payloader ("application/x-rtp", &sinktmpl,
739 "perfect-rtptime", FALSE, NULL);
740
741 set_state (state, GST_STATE_PLAYING);
742
743 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
744
745 push_buffer (state, "pts", 1 * GST_SECOND, NULL);
746
747 set_state (state, GST_STATE_NULL);
748
749 validate_buffers_received (2);
750
751 validate_buffer (0, "pts", 0 * GST_SECOND, NULL);
752 get_buffer_field (0, "rtptime", &rtptime, "seq", &seq, NULL);
753
754 validate_buffer (1,
755 "pts", 1 * GST_SECOND,
756 "rtptime", rtptime + 1 * DEFAULT_CLOCK_RATE, "seq", seq + 1, NULL);
757
758 validate_events_received (3);
759
760 validate_normal_start_events (0);
761
762 destroy_payloader (state);
763 }
764
765 GST_END_TEST;
766
767 /* push single buffers in buffer lists to the payloader to be payloaded into
768 * RTP packets. the dummy payloader will start pushing buffer lists itself
769 * after BUFFER_BEFORE_LIST payloaded RTP packets. any RTP packets included in
770 * buffer lists should have rtptime and sequence numbers incrementting in the
771 * same way as for separate RTP packets.
772 */
GST_START_TEST(rtp_base_payload_buffer_list_test)773 GST_START_TEST (rtp_base_payload_buffer_list_test)
774 {
775 State *state;
776 guint32 rtptime;
777 guint16 seq;
778 guint i;
779
780 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
781
782 set_state (state, GST_STATE_PLAYING);
783
784 for (i = 0; i < BUFFER_BEFORE_LIST + 1; i++) {
785 push_buffer_list (state, "pts", i * GST_SECOND, NULL);
786 }
787
788 set_state (state, GST_STATE_NULL);
789
790 validate_buffers_received (11);
791
792 validate_buffer (0, "pts", 0 * GST_SECOND, NULL);
793 get_buffer_field (0, "rtptime", &rtptime, "seq", &seq, NULL);
794
795 for (i = 1; i < BUFFER_BEFORE_LIST + 1; i++) {
796 validate_buffer (i,
797 "pts", i * GST_SECOND,
798 "rtptime", rtptime + i * DEFAULT_CLOCK_RATE, "seq", seq + i, NULL);
799 }
800
801 validate_events_received (3);
802
803 validate_normal_start_events (0);
804
805 destroy_payloader (state);
806 }
807
808 GST_END_TEST;
809
810 /* push two buffers. because the payloader is using non-perfect rtptime the
811 * second buffer will be timestamped with the default clock and ignore any
812 * offset set on the buffers being payloaded.
813 */
GST_START_TEST(rtp_base_payload_normal_rtptime_test)814 GST_START_TEST (rtp_base_payload_normal_rtptime_test)
815 {
816 guint32 rtptime;
817 State *state;
818
819 state = create_payloader ("application/x-rtp", &sinktmpl,
820 "perfect-rtptime", FALSE, NULL);
821
822 set_state (state, GST_STATE_PLAYING);
823
824 push_buffer (state,
825 "pts", 0 * GST_SECOND, "offset", GST_BUFFER_OFFSET_NONE, NULL);
826
827 push_buffer (state,
828 "pts", 1 * GST_SECOND, "offset", GST_BUFFER_OFFSET_NONE, NULL);
829
830 set_state (state, GST_STATE_NULL);
831
832 validate_buffers_received (2);
833
834 validate_buffer (0,
835 "pts", 0 * GST_SECOND, "offset", GST_BUFFER_OFFSET_NONE, NULL);
836 get_buffer_field (0, "rtptime", &rtptime, NULL);
837
838 validate_buffer (1,
839 "pts", 1 * GST_SECOND,
840 "offset", GST_BUFFER_OFFSET_NONE,
841 "rtptime", rtptime + DEFAULT_CLOCK_RATE, NULL);
842
843 validate_events_received (3);
844
845 validate_normal_start_events (0);
846
847 destroy_payloader (state);
848 }
849
850 GST_END_TEST;
851
852 /* push two buffers. because the payloader is using perfect rtptime the
853 * second buffer will be timestamped with a timestamp incremented with the
854 * difference in offset between the first and second buffer. the pts will be
855 * ignored for any buffer after the first buffer.
856 */
GST_START_TEST(rtp_base_payload_perfect_rtptime_test)857 GST_START_TEST (rtp_base_payload_perfect_rtptime_test)
858 {
859 guint32 rtptime;
860 State *state;
861
862 state = create_payloader ("application/x-rtp", &sinktmpl,
863 "perfect-rtptime", TRUE, NULL);
864
865 set_state (state, GST_STATE_PLAYING);
866
867 push_buffer (state, "pts", 0 * GST_SECOND, "offset", G_GINT64_CONSTANT (0),
868 NULL);
869
870 push_buffer (state, "pts", GST_CLOCK_TIME_NONE, "offset",
871 G_GINT64_CONSTANT (21), NULL);
872
873 set_state (state, GST_STATE_NULL);
874
875 validate_buffers_received (2);
876
877 validate_buffer (0, "pts", 0 * GST_SECOND, "offset", G_GINT64_CONSTANT (0),
878 NULL);
879 get_buffer_field (0, "rtptime", &rtptime, NULL);
880
881 validate_buffer (1,
882 "pts", GST_CLOCK_TIME_NONE, "offset", G_GINT64_CONSTANT (21), "rtptime",
883 rtptime + 21, NULL);
884
885 validate_events_received (3);
886
887 validate_normal_start_events (0);
888
889 destroy_payloader (state);
890 }
891
892 GST_END_TEST;
893
894 /* validate that a payloader will re-use the last used timestamp when a buffer
895 * is using perfect rtptime and both the pushed buffers timestamp and the offset
896 * is NONE. the payloader is configuered to start with a specific timestamp.
897 * then a buffer is sent with a valid timestamp but without any offset. the
898 * payloded RTP packet is expected to use the specific timestamp. next another
899 * buffer is pushed with a normal timestamp set to illustrate that the payloaded
900 * RTP packet will have an increased timestamp. finally a buffer without any
901 * timestamp or offset is pushed. in this case the payloaded RTP packet is
902 * expected to have the same timestamp as the previously payloaded RTP packet.
903 */
GST_START_TEST(rtp_base_payload_no_pts_no_offset_test)904 GST_START_TEST (rtp_base_payload_no_pts_no_offset_test)
905 {
906 State *state;
907
908 state = create_payloader ("application/x-rtp", &sinktmpl,
909 "timestamp-offset", 0x42, NULL);
910
911 set_state (state, GST_STATE_PLAYING);
912
913 push_buffer (state,
914 "pts", 0 * GST_SECOND, "offset", GST_BUFFER_OFFSET_NONE, NULL);
915
916 push_buffer (state,
917 "pts", 1 * GST_SECOND, "offset", GST_BUFFER_OFFSET_NONE, NULL);
918
919 push_buffer (state,
920 "pts", GST_CLOCK_TIME_NONE, "offset", GST_BUFFER_OFFSET_NONE, NULL);
921
922 set_state (state, GST_STATE_NULL);
923
924 validate_buffers_received (3);
925
926 validate_buffer (0,
927 "pts", 0 * GST_SECOND,
928 "offset", GST_BUFFER_OFFSET_NONE, "rtptime", 0x42, NULL);
929
930 validate_buffer (1,
931 "pts", 1 * GST_SECOND,
932 "offset", GST_BUFFER_OFFSET_NONE,
933 "rtptime", 0x42 + 1 * DEFAULT_CLOCK_RATE, NULL);
934
935 validate_buffer (2,
936 "pts", GST_CLOCK_TIME_NONE,
937 "offset", GST_BUFFER_OFFSET_NONE,
938 "rtptime", 0x42 + 1 * DEFAULT_CLOCK_RATE, NULL);
939
940 validate_events_received (3);
941
942 validate_normal_start_events (0);
943
944 destroy_payloader (state);
945 }
946
947 GST_END_TEST;
948
949 /* validate that a downstream element with caps on its sink pad can effectively
950 * configure the payloader's payload-type, ssrc, timestamp-offset and
951 * seqnum-offset properties and therefore also affect the payloaded RTP packets.
952 * this is done by connecting to a sink pad with template caps setting the
953 * relevant fields and then pushing a buffer and making sure that the payloaded
954 * RTP packet has the expected properties.
955 */
GST_START_TEST(rtp_base_payload_downstream_caps_test)956 GST_START_TEST (rtp_base_payload_downstream_caps_test)
957 {
958 State *state;
959
960 state = create_payloader ("application/x-rtp", &special_sinktmpl, NULL);
961
962 set_state (state, GST_STATE_PLAYING);
963
964 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
965
966 set_state (state, GST_STATE_NULL);
967
968 validate_buffers_received (1);
969
970 validate_buffer (0,
971 "pts", 0 * GST_SECOND,
972 "seq", 2424, "payload-type", 98, "ssrc", 24, "rtptime", 212, NULL);
973
974 validate_events_received (3);
975
976 validate_normal_start_events (0);
977
978 destroy_payloader (state);
979 }
980
981 GST_END_TEST;
982
983 /* when a payloader receives a GstRTPCollision upstream event it should try to
984 * switch to a new ssrc for the next payloaded RTP packets. GstRTPCollision can
985 * supply a suggested new ssrc. if a suggested new ssrc is supplied then the
986 * payloaded is supposed to use this new ssrc, otherwise it should generate a
987 * new random ssrc which is not identical to the one that collided.
988 *
989 * this is tested by first setting the ssrc to a specific value and pushing a
990 * buffer. the payloaded RTP packet is validate to have the set ssrc. then a
991 * GstRTPCollision event is generated to instruct the payloader that the
992 * previously set ssrc collided. this event suggests a new ssrc and it is
993 * verified that a pushed buffer results in a payloaded RTP packet that actually
994 * uses this new ssrc. finally a new GstRTPCollision event is generated to
995 * indicate another ssrc collision. this time the event does not suggest a new
996 * ssrc. the payloaded RTP packet is then expected to have a new random ssrc
997 * different from the collided one.
998 */
GST_START_TEST(rtp_base_payload_ssrc_collision_test)999 GST_START_TEST (rtp_base_payload_ssrc_collision_test)
1000 {
1001 State *state;
1002 guint32 ssrc;
1003
1004 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
1005
1006 g_object_set (state->element, "ssrc", 0x4242, NULL);
1007 g_object_get (state->element, "ssrc", &ssrc, NULL);
1008 fail_unless_equals_int (ssrc, 0x4242);
1009
1010 set_state (state, GST_STATE_PLAYING);
1011
1012 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
1013
1014 ssrc_collision (state, 0x4242, TRUE, 0x4343);
1015
1016 push_buffer (state, "pts", 1 * GST_SECOND, NULL);
1017
1018 ssrc_collision (state, 0x4343, FALSE, 0);
1019
1020 push_buffer (state, "pts", 2 * GST_SECOND, NULL);
1021
1022 set_state (state, GST_STATE_NULL);
1023
1024 validate_buffers_received (3);
1025
1026 validate_buffer (0, "pts", 0 * GST_SECOND, "ssrc", 0x4242, NULL);
1027
1028 validate_buffer (1, "pts", 1 * GST_SECOND, "ssrc", 0x4343, NULL);
1029
1030 validate_buffer (2, "pts", 2 * GST_SECOND, NULL);
1031 get_buffer_field (2, "ssrc", &ssrc, NULL);
1032 fail_if (ssrc == 0x4343);
1033
1034 validate_events_received (5);
1035
1036 validate_normal_start_events (0);
1037
1038 validate_event (3, "caps",
1039 "media-type", "application/x-rtp", "ssrc", 0x4343, NULL);
1040
1041 validate_event (4, "caps",
1042 "media-type", "application/x-rtp", "ssrc", ssrc, NULL);
1043
1044 destroy_payloader (state);
1045 }
1046
1047 GST_END_TEST;
1048
1049 /* validate that an upstream event different from GstRTPCollision is successfully
1050 * forwarded to upstream elements. in this test a caps reconfiguration event is
1051 * pushed upstream to validate the behaviour.
1052 */
GST_START_TEST(rtp_base_payload_reconfigure_test)1053 GST_START_TEST (rtp_base_payload_reconfigure_test)
1054 {
1055 State *state;
1056
1057 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
1058
1059 set_state (state, GST_STATE_PLAYING);
1060
1061 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
1062
1063 reconfigure (state);
1064
1065 push_buffer (state, "pts", 1 * GST_SECOND, NULL);
1066
1067 set_state (state, GST_STATE_NULL);
1068
1069 validate_buffers_received (2);
1070
1071 validate_buffer (0, "pts", 0 * GST_SECOND, NULL);
1072
1073 validate_buffer (1, "pts", 1 * GST_SECOND, NULL);
1074
1075 validate_events_received (4);
1076
1077 validate_normal_start_events (0);
1078
1079 destroy_payloader (state);
1080 }
1081
1082 GST_END_TEST;
1083
1084 /* validate that changing the mtu actually affects whether buffers are
1085 * considered to be filled. first detect the default mtu and check that having
1086 * buffers slightly less or equal to the size will not be considered to be
1087 * filled, and that going over this size will be filling the buffers. then
1088 * change the mtu slightly and validate that the boundary actually changed.
1089 * lastly try the boundary values and make sure that they work as expected.
1090 */
GST_START_TEST(rtp_base_payload_property_mtu_test)1091 GST_START_TEST (rtp_base_payload_property_mtu_test)
1092 {
1093 State *state;
1094 guint mtu, check;
1095
1096 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
1097
1098 g_object_get (state->element, "mtu", &mtu, NULL);
1099 validate_would_not_be_filled (state, mtu - 1, GST_CLOCK_TIME_NONE);
1100 validate_would_not_be_filled (state, mtu, GST_CLOCK_TIME_NONE);
1101 validate_would_be_filled (state, mtu + 1, GST_CLOCK_TIME_NONE);
1102
1103 g_object_set (state->element, "mtu", mtu - 1, NULL);
1104 g_object_get (state->element, "mtu", &check, NULL);
1105 fail_unless_equals_int (check, mtu - 1);
1106 validate_would_not_be_filled (state, mtu - 1, GST_CLOCK_TIME_NONE);
1107 validate_would_be_filled (state, mtu, GST_CLOCK_TIME_NONE);
1108 validate_would_be_filled (state, mtu + 1, GST_CLOCK_TIME_NONE);
1109
1110 g_object_set (state->element, "mtu", 28, NULL);
1111 g_object_get (state->element, "mtu", &check, NULL);
1112 fail_unless_equals_int (check, 28);
1113 validate_would_not_be_filled (state, 28, GST_CLOCK_TIME_NONE);
1114 validate_would_be_filled (state, 29, GST_CLOCK_TIME_NONE);
1115
1116 g_object_set (state->element, "mtu", G_MAXUINT, NULL);
1117 g_object_get (state->element, "mtu", &check, NULL);
1118 fail_unless_equals_int (check, G_MAXUINT);
1119 validate_would_not_be_filled (state, G_MAXUINT - 1, GST_CLOCK_TIME_NONE);
1120 validate_would_not_be_filled (state, G_MAXUINT, GST_CLOCK_TIME_NONE);
1121
1122 destroy_payloader (state);
1123 }
1124
1125 GST_END_TEST;
1126
1127 /* validate that changing the payload-type will actually affect the
1128 * payload-type of the payloaded RTP packets. first get the default, then send
1129 * a buffer with this payload-type. increment the payload-type and send another
1130 * buffer. then test the boundary values for the payload-type and make sure
1131 * that these are all carried over to the payloaded RTP packets.
1132 */
GST_START_TEST(rtp_base_payload_property_pt_test)1133 GST_START_TEST (rtp_base_payload_property_pt_test)
1134 {
1135 State *state;
1136 guint payload_type, check;
1137
1138 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
1139
1140 set_state (state, GST_STATE_PLAYING);
1141
1142 g_object_get (state->element, "pt", &payload_type, NULL);
1143 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
1144
1145 g_object_set (state->element, "pt", payload_type + 1, NULL);
1146 g_object_get (state->element, "pt", &check, NULL);
1147 fail_unless_equals_int (check, payload_type + 1);
1148 push_buffer (state, "pts", 1 * GST_SECOND, NULL);
1149
1150 g_object_set (state->element, "pt", 0, NULL);
1151 g_object_get (state->element, "pt", &check, NULL);
1152 fail_unless_equals_int (check, 0);
1153 push_buffer (state, "pts", 2 * GST_SECOND, NULL);
1154
1155 g_object_set (state->element, "pt", 0x7f, NULL);
1156 g_object_get (state->element, "pt", &check, NULL);
1157 fail_unless_equals_int (check, 0x7f);
1158 push_buffer (state, "pts", 3 * GST_SECOND, NULL);
1159
1160 set_state (state, GST_STATE_NULL);
1161
1162 validate_buffers_received (4);
1163
1164 validate_buffer (0,
1165 "pts", 0 * GST_SECOND, "payload-type", payload_type, NULL);
1166
1167 validate_buffer (1,
1168 "pts", 1 * GST_SECOND, "payload-type", payload_type + 1, NULL);
1169
1170 validate_buffer (2, "pts", 2 * GST_SECOND, "payload-type", 0, NULL);
1171
1172 validate_buffer (3, "pts", 3 * GST_SECOND, "payload-type", 0x7f, NULL);
1173
1174 validate_events_received (3);
1175
1176 validate_normal_start_events (0);
1177
1178 destroy_payloader (state);
1179 }
1180
1181 GST_END_TEST;
1182
1183 /* validate that changing the ssrc will actually affect the ssrc of the
1184 * payloaded RTP packets. first get the current ssrc which should indicate
1185 * random ssrcs. send two buffers and expect their ssrcs to be random but
1186 * identical. since setting the ssrc will only take effect when the pipeline
1187 * goes READY->PAUSED, bring the pipeline to NULL state, set the ssrc to a given
1188 * value and make sure that this is carried over to the payloaded RTP packets.
1189 * the last step is to test the boundary values.
1190 */
GST_START_TEST(rtp_base_payload_property_ssrc_test)1191 GST_START_TEST (rtp_base_payload_property_ssrc_test)
1192 {
1193 State *state;
1194 guint32 ssrc;
1195
1196 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
1197
1198 set_state (state, GST_STATE_PLAYING);
1199
1200 g_object_get (state->element, "ssrc", &ssrc, NULL);
1201 fail_unless_equals_int (ssrc, -1);
1202
1203 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
1204
1205 push_buffer (state, "pts", 1 * GST_SECOND, NULL);
1206
1207 set_state (state, GST_STATE_NULL);
1208 g_object_set (state->element, "ssrc", 0x4242, NULL);
1209 g_object_get (state->element, "ssrc", &ssrc, NULL);
1210 fail_unless_equals_int (ssrc, 0x4242);
1211 set_state (state, GST_STATE_PLAYING);
1212
1213 push_buffer (state, "pts", 2 * GST_SECOND, NULL);
1214
1215 set_state (state, GST_STATE_NULL);
1216 g_object_set (state->element, "ssrc", 0, NULL);
1217 g_object_get (state->element, "ssrc", &ssrc, NULL);
1218 fail_unless_equals_int (ssrc, 0);
1219 set_state (state, GST_STATE_PLAYING);
1220
1221 push_buffer (state, "pts", 3 * GST_SECOND, NULL);
1222
1223 set_state (state, GST_STATE_NULL);
1224 g_object_set (state->element, "ssrc", G_MAXUINT32, NULL);
1225 g_object_get (state->element, "ssrc", &ssrc, NULL);
1226 fail_unless_equals_int (ssrc, G_MAXUINT32);
1227 set_state (state, GST_STATE_PLAYING);
1228
1229 push_buffer (state, "pts", 4 * GST_SECOND, NULL);
1230
1231 set_state (state, GST_STATE_NULL);
1232
1233 validate_buffers_received (5);
1234
1235 validate_buffer (0, "pts", 0 * GST_SECOND, NULL);
1236 get_buffer_field (0, "ssrc", &ssrc, NULL);
1237
1238 validate_buffer (1, "pts", 1 * GST_SECOND, "ssrc", ssrc, NULL);
1239
1240 validate_buffer (2, "pts", 2 * GST_SECOND, "ssrc", 0x4242, NULL);
1241
1242 validate_buffer (3, "pts", 3 * GST_SECOND, "ssrc", 0, NULL);
1243
1244 validate_buffer (4, "pts", 4 * GST_SECOND, "ssrc", G_MAXUINT32, NULL);
1245
1246 validate_events_received (12);
1247
1248 validate_normal_start_events (0);
1249
1250 validate_normal_start_events (3);
1251
1252 validate_normal_start_events (6);
1253
1254 validate_normal_start_events (9);
1255
1256 destroy_payloader (state);
1257 }
1258
1259 GST_END_TEST;
1260
1261 /* validate that changing the timestamp-offset will actually effect the rtptime
1262 * of the payloaded RTP packets. unfortunately setting the timestamp-offset
1263 * property will only take effect when the payloader goes from READY to PAUSED.
1264 * so the test starts by making sure that the default timestamp-offset indicates
1265 * random timestamps. then a buffer is pushed which is expected to be payloaded
1266 * as an RTP packet with a random timestamp. then the timestamp-offset is
1267 * modified without changing the state of the pipeline. therefore the next
1268 * buffer pushed is expected to result in an RTP packet with a timestamp equal
1269 * to the previous RTP packet incremented by DEFAULT_CLOCK_RATE. next the
1270 * pipeline is brought to NULL state and the timestamp-offset is set to a
1271 * specific value, the pipeline is then brought back to PLAYING state and the
1272 * two buffers pushed are expected to result in payloaded RTP packets that have
1273 * timestamps based on the set timestamp-offset incremented by multiples of
1274 * DEFAULT_CLOCK_RATE. next the boundary values of the timestamp-offset are
1275 * tested. again the pipeline state needs to be modified and buffers are pushed
1276 * and the resulting payloaded RTP packets' timestamps are validated. note that
1277 * the maximum timestamp-offset value will wrap around for the very last
1278 * payloaded RTP packet.
1279 */
GST_START_TEST(rtp_base_payload_property_timestamp_offset_test)1280 GST_START_TEST (rtp_base_payload_property_timestamp_offset_test)
1281 {
1282 guint32 rtptime;
1283 guint32 offset;
1284 State *state;
1285
1286 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
1287
1288 set_state (state, GST_STATE_PLAYING);
1289
1290 g_object_get (state->element, "timestamp-offset", &offset, NULL);
1291 fail_unless_equals_int (offset, -1);
1292
1293 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
1294
1295 g_object_set (state->element, "timestamp-offset", 0x42, NULL);
1296 g_object_get (state->element, "timestamp-offset", &offset, NULL);
1297 fail_unless_equals_int (offset, 0x42);
1298 push_buffer (state, "pts", 1 * GST_SECOND, NULL);
1299
1300 set_state (state, GST_STATE_NULL);
1301 g_object_set (state->element, "timestamp-offset", 0x4242, NULL);
1302 g_object_get (state->element, "timestamp-offset", &offset, NULL);
1303 fail_unless_equals_int (offset, 0x4242);
1304 set_state (state, GST_STATE_PLAYING);
1305
1306 push_buffer (state, "pts", 2 * GST_SECOND, NULL);
1307
1308 push_buffer (state, "pts", 3 * GST_SECOND, NULL);
1309
1310 set_state (state, GST_STATE_NULL);
1311 g_object_set (state->element, "timestamp-offset", 0, NULL);
1312 set_state (state, GST_STATE_PLAYING);
1313
1314 push_buffer (state, "pts", 4 * GST_SECOND, NULL);
1315
1316 push_buffer (state, "pts", 5 * GST_SECOND, NULL);
1317
1318 set_state (state, GST_STATE_NULL);
1319 g_object_set (state->element, "timestamp-offset", G_MAXUINT32, NULL);
1320 set_state (state, GST_STATE_PLAYING);
1321
1322 push_buffer (state, "pts", 6 * GST_SECOND, NULL);
1323
1324 push_buffer (state, "pts", 7 * GST_SECOND, NULL);
1325
1326 set_state (state, GST_STATE_NULL);
1327
1328 validate_buffers_received (8);
1329
1330 validate_buffer (0, "pts", 0 * GST_SECOND, NULL);
1331 get_buffer_field (0, "rtptime", &rtptime, NULL);
1332
1333 validate_buffer (1,
1334 "pts", 1 * GST_SECOND, "rtptime", rtptime + 1 * DEFAULT_CLOCK_RATE, NULL);
1335
1336 validate_buffer (2,
1337 "pts", 2 * GST_SECOND, "rtptime", 0x4242 + 2 * DEFAULT_CLOCK_RATE, NULL);
1338
1339 validate_buffer (3,
1340 "pts", 3 * GST_SECOND, "rtptime", 0x4242 + 3 * DEFAULT_CLOCK_RATE, NULL);
1341
1342 validate_buffer (4,
1343 "pts", 4 * GST_SECOND, "rtptime", 0 + 4 * DEFAULT_CLOCK_RATE, NULL);
1344
1345 validate_buffer (5,
1346 "pts", 5 * GST_SECOND, "rtptime", 0 + 5 * DEFAULT_CLOCK_RATE, NULL);
1347
1348 validate_buffer (6,
1349 "pts", 6 * GST_SECOND, "rtptime", 6 * DEFAULT_CLOCK_RATE - 1, NULL);
1350
1351 validate_buffer (7,
1352 "pts", 7 * GST_SECOND, "rtptime", 7 * DEFAULT_CLOCK_RATE - 1, NULL);
1353
1354 validate_events_received (12);
1355
1356 validate_normal_start_events (0);
1357
1358 validate_normal_start_events (3);
1359
1360 validate_normal_start_events (6);
1361
1362 validate_normal_start_events (9);
1363
1364 destroy_payloader (state);
1365 }
1366
1367 GST_END_TEST;
1368
1369 /* as for timestamp-offset above setting the seqnum-offset property of a
1370 * payloader will only take effect when the payloader goes from READY to PAUSED
1371 * state. this test starts by validating that seqnum-offset indicates random
1372 * sequence numbers and that the random sequence numbers increment by one for
1373 * each payloaded RTP packet. also it is verified that setting seqnum-offset
1374 * without bringing the pipeline to READY will not affect the payloaded RTP
1375 * packets' sequence numbers. next the pipeline is brought to NULL state,
1376 * seqnum-offset is set to a specific value before bringing the pipeline back to
1377 * PLAYING state. the next two buffers pushed are expected to resulting in
1378 * payloaded RTP packets that start with sequence numbers relating to the set
1379 * seqnum-offset value, and that again increment by one for each packet. finally
1380 * the boundary values of seqnum-offset are tested. this means bringing the
1381 * pipeline to NULL state, setting the seqnum-offset and bringing the pipeline
1382 * back to PLAYING state. note that for the very last payloded RTP packet the
1383 * sequence number will have wrapped around because the previous packet is
1384 * expected to have the maximum sequence number value.
1385 */
GST_START_TEST(rtp_base_payload_property_seqnum_offset_test)1386 GST_START_TEST (rtp_base_payload_property_seqnum_offset_test)
1387 {
1388 State *state;
1389 guint16 seq;
1390 gint offset;
1391
1392 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
1393
1394 set_state (state, GST_STATE_PLAYING);
1395
1396 g_object_get (state->element, "seqnum-offset", &offset, NULL);
1397 fail_unless_equals_int (offset, -1);
1398
1399 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
1400
1401 g_object_set (state->element, "seqnum-offset", 0x42, NULL);
1402 g_object_get (state->element, "seqnum-offset", &offset, NULL);
1403 fail_unless_equals_int (offset, 0x42);
1404 push_buffer (state, "pts", 1 * GST_SECOND, NULL);
1405
1406 set_state (state, GST_STATE_NULL);
1407 g_object_set (state->element, "seqnum-offset", 0x4242, NULL);
1408 g_object_get (state->element, "seqnum-offset", &offset, NULL);
1409 fail_unless_equals_int (offset, 0x4242);
1410 set_state (state, GST_STATE_PLAYING);
1411
1412 push_buffer (state, "pts", 2 * GST_SECOND, NULL);
1413
1414 push_buffer (state, "pts", 3 * GST_SECOND, NULL);
1415
1416 set_state (state, GST_STATE_NULL);
1417 g_object_set (state->element, "seqnum-offset", -1, NULL);
1418 set_state (state, GST_STATE_PLAYING);
1419
1420 push_buffer (state, "pts", 4 * GST_SECOND, NULL);
1421
1422 push_buffer (state, "pts", 5 * GST_SECOND, NULL);
1423
1424 set_state (state, GST_STATE_NULL);
1425 g_object_set (state->element, "seqnum-offset", G_MAXUINT16, NULL);
1426 set_state (state, GST_STATE_PLAYING);
1427
1428 push_buffer (state, "pts", 6 * GST_SECOND, NULL);
1429
1430 push_buffer (state, "pts", 7 * GST_SECOND, NULL);
1431
1432 set_state (state, GST_STATE_NULL);
1433
1434 validate_buffers_received (8);
1435
1436 validate_buffer (0, "pts", 0 * GST_SECOND, NULL);
1437 get_buffer_field (0, "seq", &seq, NULL);
1438
1439 validate_buffer (1, "pts", 1 * GST_SECOND, "seq", seq + 1, NULL);
1440
1441 validate_buffer (2, "pts", 2 * GST_SECOND, "seq", 0x4242, NULL);
1442
1443 validate_buffer (3, "pts", 3 * GST_SECOND, "seq", 0x4242 + 1, NULL);
1444
1445 validate_buffer (4, "pts", 4 * GST_SECOND, NULL);
1446 get_buffer_field (4, "seq", &seq, NULL);
1447
1448 validate_buffer (5, "pts", 5 * GST_SECOND, "seq", seq + 1, NULL);
1449
1450 validate_buffer (6, "pts", 6 * GST_SECOND, "seq", G_MAXUINT16, NULL);
1451
1452 validate_buffer (7, "pts", 7 * GST_SECOND, "seq", 0, NULL);
1453
1454 validate_events_received (12);
1455
1456 validate_normal_start_events (0);
1457
1458 validate_normal_start_events (3);
1459
1460 validate_normal_start_events (6);
1461
1462 validate_normal_start_events (9);
1463
1464 destroy_payloader (state);
1465 }
1466
1467 GST_END_TEST;
1468
1469 /* a payloader's max-ptime property is linked to its MTU property. whenever a
1470 * packet is larger than MTU or has a duration longer than max-ptime it will be
1471 * considered to be full. so this test first validates that the default value of
1472 * max-ptime is unspecified. then it retrieves the MTU and validates that a
1473 * packet of size MTU will not be considered full even if the duration is at its
1474 * maximum value. however incrementing the size to exceed the MTU will result in
1475 * the packet being full. next max-ptime is set to a value and it is verified
1476 * that only if both the size and duration are below the allowed values then the
1477 * packet will be considered not to be full, otherwise it will be reported as
1478 * being full. finally the boundary values of the property are tested in a
1479 * similar fashion.
1480 */
GST_START_TEST(rtp_base_payload_property_max_ptime_test)1481 GST_START_TEST (rtp_base_payload_property_max_ptime_test)
1482 {
1483 gint64 max_ptime;
1484 State *state;
1485 guint mtu;
1486
1487 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
1488
1489 g_object_get (state->element, "max-ptime", &max_ptime, NULL);
1490 fail_unless_equals_int64 (max_ptime, -1);
1491 g_object_get (state->element, "mtu", &mtu, NULL);
1492 validate_would_not_be_filled (state, mtu, G_MAXINT64 - 1);
1493 validate_would_be_filled (state, mtu + 1, G_MAXINT64 - 1);
1494
1495 g_object_set (state->element, "max-ptime", GST_SECOND, NULL);
1496 g_object_get (state->element, "max-ptime", &max_ptime, NULL);
1497 fail_unless_equals_int64 (max_ptime, GST_SECOND);
1498 validate_would_not_be_filled (state, mtu, GST_SECOND - 1);
1499 validate_would_be_filled (state, mtu, GST_SECOND);
1500 validate_would_be_filled (state, mtu + 1, GST_SECOND - 1);
1501 validate_would_be_filled (state, mtu + 1, GST_SECOND);
1502
1503 g_object_set (state->element, "max-ptime", G_MAXUINT64, NULL);
1504 g_object_get (state->element, "max-ptime", &max_ptime, NULL);
1505 fail_unless_equals_int64 (max_ptime, G_MAXUINT64);
1506 validate_would_not_be_filled (state, mtu, G_MAXINT64 - 1);
1507 validate_would_be_filled (state, mtu + 1, G_MAXINT64 - 1);
1508
1509 g_object_set (state->element, "max-ptime", G_MAXINT64, NULL);
1510 g_object_get (state->element, "max-ptime", &max_ptime, NULL);
1511 fail_unless_equals_int64 (max_ptime, G_MAXINT64);
1512 validate_would_be_filled (state, mtu, G_MAXINT64);
1513
1514 destroy_payloader (state);
1515 }
1516
1517 GST_END_TEST;
1518
1519 /* a basepayloader has a min-ptime property with an allowed range, the property
1520 * itself is never checked by the payloader but is meant to be used by
1521 * inheriting classes. therefore this test only validates that setting the
1522 * property will mean that retrieveing the property results in the value
1523 * previously being set. first the default value is validated, then a new
1524 * specific value, before finally testing the boundary values.
1525 */
GST_START_TEST(rtp_base_payload_property_min_ptime_test)1526 GST_START_TEST (rtp_base_payload_property_min_ptime_test)
1527 {
1528 State *state;
1529 guint64 reference, min_ptime;
1530
1531 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
1532
1533 g_object_get (state->element, "min-ptime", &reference, NULL);
1534 fail_unless_equals_int (reference, 0);
1535
1536 g_object_set (state->element, "min-ptime", reference + 1, NULL);
1537 g_object_get (state->element, "min-ptime", &min_ptime, NULL);
1538 fail_unless_equals_int (min_ptime, reference + 1);
1539
1540 g_object_set (state->element, "min-ptime", G_GUINT64_CONSTANT (0), NULL);
1541 g_object_get (state->element, "min-ptime", &min_ptime, NULL);
1542 fail_unless_equals_int (min_ptime, 0);
1543
1544 g_object_set (state->element, "min-ptime", G_MAXINT64, NULL);
1545 g_object_get (state->element, "min-ptime", &min_ptime, NULL);
1546 fail_unless_equals_int64 (min_ptime, G_MAXINT64);
1547
1548 destroy_payloader (state);
1549 }
1550
1551 GST_END_TEST;
1552
1553 /* paylaoders have a timestamp property that reflects the timestamp of the last
1554 * payloaded RTP packet. in this test the timestamp-offset is set to a specific
1555 * value so that when the first buffer is pushed its timestamp can be predicted
1556 * and thus that the timestamp property also has this value. (if
1557 * timestamp-offset was not set the timestamp would be random). another buffer
1558 * is then pushed and its timestamp is expected to increment by
1559 * DEFAULT_CLOCK_RATE.
1560 */
GST_START_TEST(rtp_base_payload_property_timestamp_test)1561 GST_START_TEST (rtp_base_payload_property_timestamp_test)
1562 {
1563 State *state;
1564 guint32 timestamp;
1565
1566 state = create_payloader ("application/x-rtp", &sinktmpl,
1567 "timestamp-offset", 0, NULL);
1568
1569 set_state (state, GST_STATE_PLAYING);
1570
1571 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
1572 g_object_get (state->element, "timestamp", ×tamp, NULL);
1573 fail_unless_equals_int (timestamp, 0);
1574
1575 push_buffer (state, "pts", 1 * GST_SECOND, NULL);
1576 g_object_get (state->element, "timestamp", ×tamp, NULL);
1577 fail_unless_equals_int (timestamp, DEFAULT_CLOCK_RATE);
1578
1579 set_state (state, GST_STATE_NULL);
1580
1581 validate_buffers_received (2);
1582
1583 validate_buffer (0, "pts", 0 * GST_SECOND, "rtptime", 0, NULL);
1584
1585 validate_buffer (1,
1586 "pts", 1 * GST_SECOND, "rtptime", DEFAULT_CLOCK_RATE, NULL);
1587
1588 validate_events_received (3);
1589
1590 validate_normal_start_events (0);
1591
1592 destroy_payloader (state);
1593 }
1594
1595 GST_END_TEST;
1596
1597 /* basepayloaders have a seqnum property that is supposed to contain the
1598 * sequence number of the last payloaded RTP packet. so therefore this test
1599 * initializes the seqnum-offset property to a know value and pushes a buffer.
1600 * the payloaded RTP packet is expected to have a sequence number equal to the
1601 * set seqnum-offset, as is the seqnum property. next another buffer is pushed
1602 * and then both the payloaded RTP packet and the seqnum property value are
1603 * expected to increment by one compared to the previous packet.
1604 */
GST_START_TEST(rtp_base_payload_property_seqnum_test)1605 GST_START_TEST (rtp_base_payload_property_seqnum_test)
1606 {
1607 State *state;
1608 guint seq;
1609
1610 state = create_payloader ("application/x-rtp", &sinktmpl,
1611 "seqnum-offset", 0, NULL);
1612
1613 set_state (state, GST_STATE_PLAYING);
1614
1615 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
1616 g_object_get (state->element, "seqnum", &seq, NULL);
1617 fail_unless_equals_int (seq, 0);
1618
1619 push_buffer (state, "pts", 1 * GST_SECOND, NULL);
1620 g_object_get (state->element, "seqnum", &seq, NULL);
1621 fail_unless_equals_int (seq, 1);
1622
1623 set_state (state, GST_STATE_NULL);
1624
1625 validate_buffers_received (2);
1626
1627 validate_buffer (0, "pts", 0 * GST_SECOND, "seq", 0, NULL);
1628
1629 validate_buffer (1, "pts", 1 * GST_SECOND, "seq", 1, NULL);
1630
1631 validate_events_received (3);
1632
1633 validate_normal_start_events (0);
1634
1635 destroy_payloader (state);
1636 }
1637
1638 GST_END_TEST;
1639
1640 /* basepayloader has a perfect-rtptime property when it is set to FALSE
1641 * the timestamps of payloaded RTP packets will determined by initial
1642 * timestamp-offset (usually random) as well as the clock-rate. when
1643 * perfect-rtptime is set to TRUE the timestamps of payloaded RTP packets are
1644 * instead determined by the timestamp of the first packet and then the
1645 * difference in offset of the input buffers.
1646 *
1647 * to verify that this test starts by setting the timestamp-offset to a specific
1648 * value to prevent random timestamps of the RTP packets. next perfect-rtptime
1649 * is set to FALSE. the two buffers pushed will result in two payloaded RTP
1650 * packets whose timestamps differ based on the current clock-rate
1651 * DEFAULT_CLOCK_RATE. the next step is to set perfect-rtptime to TRUE. the two
1652 * buffers that are pushed will result in two payloaded RTP packets. the first
1653 * of these RTP packets has a timestamp that relates to the previous packet and
1654 * the difference in offset between the middle two input buffers. the latter of
1655 * the two RTP packets has a timestamp that instead relates to the offset of the
1656 * last two input buffers.
1657 */
GST_START_TEST(rtp_base_payload_property_perfect_rtptime_test)1658 GST_START_TEST (rtp_base_payload_property_perfect_rtptime_test)
1659 {
1660 State *state;
1661 guint32 timestamp_base = 0;
1662 gboolean perfect;
1663
1664 state = create_payloader ("application/x-rtp", &sinktmpl,
1665 "timestamp-offset", timestamp_base, NULL);
1666
1667 set_state (state, GST_STATE_PLAYING);
1668
1669 g_object_set (state->element, "perfect-rtptime", FALSE, NULL);
1670 g_object_get (state->element, "perfect-rtptime", &perfect, NULL);
1671 fail_unless (!perfect);
1672
1673 push_buffer (state, "pts", 0 * GST_SECOND, "offset", G_GINT64_CONSTANT (0),
1674 NULL);
1675
1676 push_buffer (state, "pts", 1 * GST_SECOND, "offset", G_GINT64_CONSTANT (17),
1677 NULL);
1678
1679 g_object_set (state->element, "perfect-rtptime", TRUE, NULL);
1680 g_object_get (state->element, "perfect-rtptime", &perfect, NULL);
1681 fail_unless (perfect);
1682
1683 push_buffer (state, "pts", 2 * GST_SECOND, "offset", G_GINT64_CONSTANT (31),
1684 NULL);
1685
1686 push_buffer (state, "pts", 3 * GST_SECOND, "offset", G_GINT64_CONSTANT (67),
1687 NULL);
1688
1689 set_state (state, GST_STATE_NULL);
1690
1691 validate_buffers_received (4);
1692
1693 validate_buffer (0,
1694 "pts", 0 * GST_SECOND, "offset", G_GINT64_CONSTANT (0), "rtptime",
1695 timestamp_base, NULL);
1696
1697 validate_buffer (1,
1698 "pts", 1 * GST_SECOND,
1699 "offset", G_GINT64_CONSTANT (17), "rtptime",
1700 timestamp_base + 1 * DEFAULT_CLOCK_RATE, NULL);
1701
1702 validate_buffer (2,
1703 "pts", 2 * GST_SECOND,
1704 "offset", G_GINT64_CONSTANT (31),
1705 "rtptime", timestamp_base + 1 * DEFAULT_CLOCK_RATE + (31 - 17), NULL);
1706
1707 validate_buffer (3,
1708 "pts", 3 * GST_SECOND,
1709 "offset", G_GINT64_CONSTANT (67),
1710 "rtptime", timestamp_base + 1 * DEFAULT_CLOCK_RATE + (67 - 17), NULL);
1711
1712 validate_events_received (3);
1713
1714 validate_normal_start_events (0);
1715
1716 destroy_payloader (state);
1717 }
1718
1719 GST_END_TEST;
1720
1721 /* basepayloaders have a ptime-multiple property but its value does not affect
1722 * any payloaded RTP packets as this is supposed to be done by inherited
1723 * classes. therefore this test only validates the default value of the
1724 * property, makes sure that a set value actually sticks and that the boundary
1725 * values are indeed allowed to be set.
1726 */
GST_START_TEST(rtp_base_payload_property_ptime_multiple_test)1727 GST_START_TEST (rtp_base_payload_property_ptime_multiple_test)
1728 {
1729 State *state;
1730 gint64 multiple;
1731
1732 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
1733
1734 g_object_get (state->element, "ptime-multiple", &multiple, NULL);
1735 fail_unless_equals_int64 (multiple, 0);
1736
1737 g_object_set (state->element, "ptime-multiple", G_GINT64_CONSTANT (42), NULL);
1738 g_object_get (state->element, "ptime-multiple", &multiple, NULL);
1739 fail_unless_equals_int64 (multiple, 42);
1740
1741 g_object_set (state->element, "ptime-multiple", G_GINT64_CONSTANT (0), NULL);
1742 g_object_get (state->element, "ptime-multiple", &multiple, NULL);
1743 fail_unless_equals_int64 (multiple, 0);
1744
1745 g_object_set (state->element, "ptime-multiple", G_MAXINT64, NULL);
1746 g_object_get (state->element, "ptime-multiple", &multiple, NULL);
1747 fail_unless_equals_int64 (multiple, G_MAXINT64);
1748
1749 destroy_payloader (state);
1750 }
1751
1752 GST_END_TEST;
1753
1754 /* basepayloaders have a property called stats that is used to atomically
1755 * retrieve several values (clock-rate, running-time, seqnum and timestamp) that
1756 * relate to the stream and its current progress. this test is meant to test
1757 * retrieval of these values.
1758 *
1759 * first of all perfect-rtptime is set to TRUE, next the the test starts out by
1760 * setting seqnum-offset and timestamp-offset to known values to prevent that
1761 * sequence numbers and timestamps of payloaded RTP packets are random. next the
1762 * stats property is retrieved. the clock-rate must be at the default
1763 * DEFAULT_CLOCK_RATE, while running-time must be equal to the first buffers
1764 * PTS. the sequence number should be equal to the initialized value of
1765 * seqnum-offset and the timestamp should be equal to the initialized value of
1766 * timestamp-offset. after pushing a second buffer the stats property is
1767 * validate again. this time running-time, seqnum and timestamp should have
1768 * advanced as expected. next the pipeline is brought to NULL state to be able
1769 * to change the perfect-rtptime property to FALSE before going back to PLAYING
1770 * state. this is done to validate that the stats values reflect normal
1771 * timestamp updates that are not based on input buffer offsets as expected.
1772 * lastly two buffers are pushed and the stats property retrieved after each
1773 * time. here it is expected that the sequence numbers values are restarted at
1774 * the initial value while the timestamps and running-time reflect the input
1775 * buffers.
1776 */
GST_START_TEST(rtp_base_payload_property_stats_test)1777 GST_START_TEST (rtp_base_payload_property_stats_test)
1778 {
1779 State *state;
1780
1781 state = create_payloader ("application/x-rtp", &sinktmpl,
1782 "perfect-rtptime", TRUE, "seqnum-offset", 0, "timestamp-offset", 0, NULL);
1783
1784 set_state (state, GST_STATE_PLAYING);
1785
1786 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
1787 validate_stats (state,
1788 DEFAULT_CLOCK_RATE, 0 * GST_SECOND, 0, 0 * DEFAULT_CLOCK_RATE);
1789
1790 push_buffer (state, "pts", 1 * GST_SECOND, NULL);
1791 validate_stats (state,
1792 DEFAULT_CLOCK_RATE, 1 * DEFAULT_CLOCK_RATE, 1, 1 * DEFAULT_CLOCK_RATE);
1793
1794 set_state (state, GST_STATE_NULL);
1795 g_object_set (state->element, "perfect-rtptime", FALSE, NULL);
1796 set_state (state, GST_STATE_PLAYING);
1797
1798 push_buffer (state, "pts", 2 * GST_SECOND, NULL);
1799 validate_stats (state,
1800 DEFAULT_CLOCK_RATE, 2 * GST_SECOND, 0, 2 * DEFAULT_CLOCK_RATE);
1801
1802 push_buffer (state, "pts", 3 * GST_SECOND, NULL);
1803 validate_stats (state,
1804 DEFAULT_CLOCK_RATE, 3 * GST_SECOND, 1, 3 * DEFAULT_CLOCK_RATE);
1805 set_state (state, GST_STATE_NULL);
1806
1807 validate_buffers_received (4);
1808
1809 validate_buffer (0, "pts", 0 * GST_SECOND, NULL);
1810
1811 validate_buffer (1, "pts", 1 * GST_SECOND, NULL);
1812
1813 validate_buffer (2, "pts", 2 * GST_SECOND, NULL);
1814
1815 validate_buffer (3, "pts", 3 * GST_SECOND, NULL);
1816
1817 validate_events_received (6);
1818
1819 validate_normal_start_events (0);
1820
1821 validate_normal_start_events (3);
1822
1823 destroy_payloader (state);
1824 }
1825
1826 GST_END_TEST;
1827
1828 /* basepayloader has a property source-info that makes it aware of RTP
1829 * source information passed as GstRTPSourceMeta on the input buffers. All
1830 * sources found in the meta will be added to the list of CSRCs in the RTP
1831 * header. A useful scenario for this is, for instance, to signal which
1832 * sources contributed to a mixed audio stream. */
GST_START_TEST(rtp_base_payload_property_source_info_test)1833 GST_START_TEST (rtp_base_payload_property_source_info_test)
1834 {
1835 GstHarness *h;
1836 GstRtpDummyPay *pay;
1837 GstBuffer *buffer;
1838 guint csrc_count = 2;
1839 const guint32 csrc[] = { 0x11, 0x22 };
1840 const guint32 ssrc = 0x33;
1841
1842 pay = rtp_dummy_pay_new ();
1843 h = gst_harness_new_with_element (GST_ELEMENT_CAST (pay), "sink", "src");
1844 gst_harness_set_src_caps_str (h, "application/x-rtp");
1845
1846 /* Input buffer has no meta, payloader should not add CSRC */
1847 g_object_set (pay, "source-info", TRUE, NULL);
1848 buffer = gst_rtp_buffer_new_allocate (0, 0, 0);
1849 buffer = gst_harness_push_and_pull (h, buffer);
1850 validate_buffer1 (buffer, "csrc-count", 0, NULL);
1851 fail_if (gst_buffer_get_rtp_source_meta (buffer));
1852 gst_buffer_unref (buffer);
1853
1854 /* Input buffer has meta, payloader should add CSRC */
1855 buffer = gst_rtp_buffer_new_allocate (0, 0, 0);
1856 fail_unless (gst_buffer_add_rtp_source_meta (buffer, &ssrc, csrc,
1857 csrc_count));
1858 buffer = gst_harness_push_and_pull (h, buffer);
1859 /* The meta SSRC should be added as the last contributing source */
1860 validate_buffer1 (buffer, "csrc-count", 3, "csrc", 0, csrc[0],
1861 "csrc", 1, csrc[1], "csrc", 2, ssrc, NULL);
1862 fail_if (gst_buffer_get_rtp_source_meta (buffer));
1863 gst_buffer_unref (buffer);
1864
1865 /* When property is disabled, the meta should be ignored and no CSRC
1866 * added. */
1867 g_object_set (pay, "source-info", FALSE, NULL);
1868 buffer = gst_rtp_buffer_new_allocate (0, 0, 0);
1869 fail_unless (gst_buffer_add_rtp_source_meta (buffer, NULL, csrc, csrc_count));
1870 buffer = gst_harness_push_and_pull (h, buffer);
1871 validate_buffer1 (buffer, "csrc-count", 0, NULL);
1872 fail_if (gst_buffer_get_rtp_source_meta (buffer));
1873 gst_buffer_unref (buffer);
1874
1875 g_object_unref (pay);
1876 gst_harness_teardown (h);
1877 }
1878
1879 GST_END_TEST;
1880
1881 /* push a single buffer to the payloader which should successfully payload it
1882 * into an RTP packet. besides the payloaded RTP packet there should be the
1883 * three events initial events: stream-start, caps and segment. because of that
1884 * the input caps has framerate this will be propagated to an a-framerate field
1885 * on the output caps.
1886 */
GST_START_TEST(rtp_base_payload_framerate_attribute)1887 GST_START_TEST (rtp_base_payload_framerate_attribute)
1888 {
1889 State *state;
1890
1891 state = create_payloader ("video/x-raw,framerate=(fraction)1/4", &sinktmpl,
1892 "perfect-rtptime", FALSE, NULL);
1893
1894 set_state (state, GST_STATE_PLAYING);
1895
1896 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
1897
1898 set_state (state, GST_STATE_NULL);
1899
1900 validate_buffers_received (1);
1901
1902 validate_buffer (0, "pts", 0 * GST_SECOND, NULL);
1903
1904 validate_events_received (3);
1905
1906 validate_normal_start_events (0);
1907
1908 validate_event (1, "caps", "a-framerate", "0.25", NULL);
1909
1910 destroy_payloader (state);
1911 }
1912
1913 GST_END_TEST;
1914
1915 /* push a single buffer to the payloader which should successfully payload it
1916 * into an RTP packet. besides the payloaded RTP packet there should be the
1917 * three events initial events: stream-start, caps and segment. because of that
1918 * the input caps has both framerate and max-framerate set the a-framerate field
1919 * on the output caps will correspond to the value of the max-framerate field.
1920 */
GST_START_TEST(rtp_base_payload_max_framerate_attribute)1921 GST_START_TEST (rtp_base_payload_max_framerate_attribute)
1922 {
1923 State *state;
1924
1925 state =
1926 create_payloader
1927 ("video/x-raw,framerate=(fraction)0/1,max-framerate=(fraction)1/8",
1928 &sinktmpl, "perfect-rtptime", FALSE, NULL);
1929
1930 set_state (state, GST_STATE_PLAYING);
1931
1932 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
1933
1934 set_state (state, GST_STATE_NULL);
1935
1936 validate_buffers_received (1);
1937
1938 validate_buffer (0, "pts", 0 * GST_SECOND, NULL);
1939
1940 validate_events_received (3);
1941
1942 validate_normal_start_events (0);
1943
1944 validate_event (1, "caps", "a-framerate", "0.125", NULL);
1945
1946 destroy_payloader (state);
1947 }
1948
1949 GST_END_TEST;
1950
GST_START_TEST(rtp_base_payload_segment_time)1951 GST_START_TEST (rtp_base_payload_segment_time)
1952 {
1953 State *state;
1954 guint32 timestamp_base = 0;
1955 guint segment_time = 10;
1956 GstEvent *event;
1957 GstSegment *segment = gst_segment_new ();
1958
1959 state =
1960 create_payloader
1961 ("application/x-rtp",
1962 &sinktmpl, "onvif-no-rate-control", TRUE, "timestamp-offset",
1963 timestamp_base, NULL);
1964
1965 set_state (state, GST_STATE_PLAYING);
1966
1967 gst_segment_init (segment, GST_FORMAT_TIME);
1968 segment->time = segment_time * GST_SECOND;
1969 event = gst_event_new_segment (segment);
1970 fail_unless (gst_pad_push_event (state->srcpad, event));
1971
1972 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
1973 push_buffer (state, "pts", 1 * GST_SECOND, NULL);
1974 push_buffer (state, "pts", 2 * GST_SECOND, NULL);
1975 push_buffer (state, "pts", 3 * GST_SECOND, NULL);
1976
1977 set_state (state, GST_STATE_NULL);
1978
1979 validate_buffers_received (4);
1980
1981 validate_buffer (0, "rtptime",
1982 timestamp_base + (segment_time) * DEFAULT_CLOCK_RATE, NULL);
1983 validate_buffer (1, "rtptime",
1984 timestamp_base + (1 + segment_time) * DEFAULT_CLOCK_RATE, NULL);
1985 validate_buffer (2, "rtptime",
1986 timestamp_base + (2 + segment_time) * DEFAULT_CLOCK_RATE, NULL);
1987 validate_buffer (3, "rtptime",
1988 timestamp_base + (3 + segment_time) * DEFAULT_CLOCK_RATE, NULL);
1989
1990 destroy_payloader (state);
1991 gst_segment_free (segment);
1992 }
1993
1994 GST_END_TEST;
1995
GST_START_TEST(rtp_base_payload_one_byte_hdr_ext)1996 GST_START_TEST (rtp_base_payload_one_byte_hdr_ext)
1997 {
1998 GstRTPHeaderExtension *ext;
1999 State *state;
2000
2001 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
2002 ext = rtp_dummy_hdr_ext_new ();
2003 GST_RTP_DUMMY_HDR_EXT (ext)->supported_flags =
2004 GST_RTP_HEADER_EXTENSION_ONE_BYTE;
2005 gst_rtp_header_extension_set_id (ext, 1);
2006
2007 g_signal_emit_by_name (state->element, "add-extension", ext);
2008
2009 set_state (state, GST_STATE_PLAYING);
2010
2011 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
2012
2013 set_state (state, GST_STATE_NULL);
2014
2015 validate_buffers_received (1);
2016
2017 validate_buffer (0, "pts", 0 * GST_SECOND, NULL);
2018
2019 validate_events_received (3);
2020
2021 validate_normal_start_events (0);
2022
2023 fail_unless_equals_int (GST_RTP_DUMMY_HDR_EXT (ext)->write_count, 1);
2024
2025 gst_object_unref (ext);
2026 destroy_payloader (state);
2027 }
2028
2029 GST_END_TEST;
2030
GST_START_TEST(rtp_base_payload_two_byte_hdr_ext)2031 GST_START_TEST (rtp_base_payload_two_byte_hdr_ext)
2032 {
2033 GstRTPHeaderExtension *ext;
2034 State *state;
2035
2036 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
2037 ext = rtp_dummy_hdr_ext_new ();
2038 GST_RTP_DUMMY_HDR_EXT (ext)->supported_flags =
2039 GST_RTP_HEADER_EXTENSION_TWO_BYTE;
2040 gst_rtp_header_extension_set_id (ext, 1);
2041
2042 g_signal_emit_by_name (state->element, "add-extension", ext);
2043
2044 set_state (state, GST_STATE_PLAYING);
2045
2046 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
2047
2048 set_state (state, GST_STATE_NULL);
2049
2050 validate_buffers_received (1);
2051
2052 validate_buffer (0, "pts", 0 * GST_SECOND, NULL);
2053
2054 validate_events_received (3);
2055
2056 validate_normal_start_events (0);
2057
2058 fail_unless_equals_int (GST_RTP_DUMMY_HDR_EXT (ext)->write_count, 1);
2059
2060 gst_object_unref (ext);
2061 destroy_payloader (state);
2062 }
2063
2064 GST_END_TEST;
2065
GST_START_TEST(rtp_base_payload_clear_extensions)2066 GST_START_TEST (rtp_base_payload_clear_extensions)
2067 {
2068 GstRTPHeaderExtension *ext;
2069 State *state;
2070
2071 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
2072 ext = rtp_dummy_hdr_ext_new ();
2073 gst_rtp_header_extension_set_id (ext, 1);
2074
2075 g_signal_emit_by_name (state->element, "add-extension", ext);
2076
2077 set_state (state, GST_STATE_PLAYING);
2078
2079 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
2080 g_signal_emit_by_name (state->element, "clear-extensions", ext);
2081 push_buffer (state, "pts", 1 * GST_SECOND, NULL);
2082
2083 set_state (state, GST_STATE_NULL);
2084
2085 validate_buffers_received (2);
2086
2087 validate_buffer (0, "pts", 0 * GST_SECOND, NULL);
2088 validate_buffer (1, "pts", 1 * GST_SECOND, NULL);
2089
2090 validate_events_received (3);
2091
2092 validate_normal_start_events (0);
2093
2094 fail_unless_equals_int (GST_RTP_DUMMY_HDR_EXT (ext)->write_count, 1);
2095
2096 gst_object_unref (ext);
2097 destroy_payloader (state);
2098 }
2099
2100 GST_END_TEST;
2101
GST_START_TEST(rtp_base_payload_multiple_exts)2102 GST_START_TEST (rtp_base_payload_multiple_exts)
2103 {
2104 GstRTPHeaderExtension *ext1, *ext2;
2105 State *state;
2106
2107 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
2108 ext1 = rtp_dummy_hdr_ext_new ();
2109 gst_rtp_header_extension_set_id (ext1, 1);
2110 ext2 = rtp_dummy_hdr_ext_new ();
2111 gst_rtp_header_extension_set_id (ext2, 2);
2112
2113 g_signal_emit_by_name (state->element, "add-extension", ext1);
2114 g_signal_emit_by_name (state->element, "add-extension", ext2);
2115
2116 set_state (state, GST_STATE_PLAYING);
2117
2118 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
2119
2120 set_state (state, GST_STATE_NULL);
2121
2122 validate_buffers_received (1);
2123
2124 validate_buffer (0, "pts", 0 * GST_SECOND, NULL);
2125
2126 validate_events_received (3);
2127
2128 validate_normal_start_events (0);
2129
2130 fail_unless_equals_int (GST_RTP_DUMMY_HDR_EXT (ext1)->write_count, 1);
2131 fail_unless_equals_int (GST_RTP_DUMMY_HDR_EXT (ext2)->write_count, 1);
2132
2133 gst_object_unref (ext1);
2134 gst_object_unref (ext2);
2135 destroy_payloader (state);
2136 }
2137
2138 GST_END_TEST;
2139
2140 static GstStaticPadTemplate sinktmpl_with_extmap_str =
2141 GST_STATIC_PAD_TEMPLATE ("sink",
2142 GST_PAD_SINK,
2143 GST_PAD_ALWAYS,
2144 GST_STATIC_CAPS ("application/x-rtp, payload=(int)98, ssrc=(uint)24, "
2145 "timestamp-offset=(uint)212, seqnum-offset=(uint)2424, extmap-4=(string)"
2146 DUMMY_HDR_EXT_URI));
2147
2148 static GstRTPHeaderExtension *
request_extension(GstRTPBasePayload * depayload,guint ext_id,const gchar * ext_uri,gpointer user_data)2149 request_extension (GstRTPBasePayload * depayload, guint ext_id,
2150 const gchar * ext_uri, gpointer user_data)
2151 {
2152 GstRTPHeaderExtension *ext = user_data;
2153
2154 if (ext && gst_rtp_header_extension_get_id (ext) == ext_id
2155 && g_strcmp0 (ext_uri, gst_rtp_header_extension_get_uri (ext)) == 0)
2156 return gst_object_ref (ext);
2157
2158 return NULL;
2159 }
2160
GST_START_TEST(rtp_base_payload_caps_request)2161 GST_START_TEST (rtp_base_payload_caps_request)
2162 {
2163 GstRTPHeaderExtension *ext;
2164 GstRTPDummyHdrExt *dummy;
2165 State *state;
2166
2167 state =
2168 create_payloader ("application/x-rtp", &sinktmpl_with_extmap_str, NULL);
2169
2170 ext = rtp_dummy_hdr_ext_new ();
2171 dummy = GST_RTP_DUMMY_HDR_EXT (ext);
2172 gst_rtp_header_extension_set_id (ext, 4);
2173 g_signal_connect (state->element, "request-extension",
2174 G_CALLBACK (request_extension), ext);
2175
2176 fail_unless (dummy->set_attributes_count == 0);
2177
2178 set_state (state, GST_STATE_PLAYING);
2179
2180 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
2181
2182 set_state (state, GST_STATE_NULL);
2183
2184 validate_buffers_received (1);
2185
2186 validate_buffer (0, "pts", 0 * GST_SECOND, NULL);
2187
2188 validate_events_received (3);
2189
2190 validate_normal_start_events (0);
2191
2192 fail_unless_equals_int (GST_RTP_DUMMY_HDR_EXT (ext)->write_count, 1);
2193 fail_unless (dummy->set_attributes_count == 1);
2194
2195 gst_object_unref (ext);
2196 destroy_payloader (state);
2197 }
2198
2199 GST_END_TEST;
2200
2201 static GstRTPHeaderExtension *
request_extension_ignored(GstRTPBasePayload * depayload,guint ext_id,const gchar * ext_uri,gpointer user_data)2202 request_extension_ignored (GstRTPBasePayload * depayload, guint ext_id,
2203 const gchar * ext_uri, gpointer user_data)
2204 {
2205 guint *request_counter = user_data;
2206
2207 *request_counter += 1;
2208
2209 return NULL;
2210 }
2211
GST_START_TEST(rtp_base_payload_caps_request_ignored)2212 GST_START_TEST (rtp_base_payload_caps_request_ignored)
2213 {
2214 State *state;
2215 guint request_counter = 0;
2216
2217 state =
2218 create_payloader ("application/x-rtp", &sinktmpl_with_extmap_str, NULL);
2219
2220 g_signal_connect (state->element, "request-extension",
2221 G_CALLBACK (request_extension_ignored), &request_counter);
2222
2223 set_state (state, GST_STATE_PLAYING);
2224
2225 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
2226
2227 set_state (state, GST_STATE_NULL);
2228
2229 fail_unless_equals_int (request_counter, 1);
2230
2231 validate_buffers_received (1);
2232
2233 destroy_payloader (state);
2234 }
2235
2236 GST_END_TEST;
2237
GST_START_TEST(rtp_base_payload_extensions_in_output_caps)2238 GST_START_TEST (rtp_base_payload_extensions_in_output_caps)
2239 {
2240 GstRTPHeaderExtension *ext;
2241 State *state;
2242
2243 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
2244 ext = rtp_dummy_hdr_ext_new ();
2245 GST_RTP_DUMMY_HDR_EXT (ext)->supported_flags =
2246 GST_RTP_HEADER_EXTENSION_TWO_BYTE;
2247 gst_rtp_header_extension_set_id (ext, 1);
2248
2249 g_signal_emit_by_name (state->element, "add-extension", ext);
2250
2251 set_state (state, GST_STATE_PLAYING);
2252
2253 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
2254
2255 set_state (state, GST_STATE_NULL);
2256
2257 validate_buffers_received (1);
2258
2259 validate_buffer (0, "pts", 0 * GST_SECOND, NULL);
2260
2261 validate_events_received (3);
2262
2263 validate_normal_start_events (0);
2264
2265 validate_event (1, "caps", "extmap-str", 1, DUMMY_HDR_EXT_URI, NULL);
2266
2267 fail_unless_equals_int (GST_RTP_DUMMY_HDR_EXT (ext)->write_count, 1);
2268 gst_object_unref (ext);
2269 ext = NULL;
2270
2271 destroy_payloader (state);
2272 }
2273
2274 GST_END_TEST;
2275
GST_START_TEST(rtp_base_payload_extensions_shrink_ext_data)2276 GST_START_TEST (rtp_base_payload_extensions_shrink_ext_data)
2277 {
2278 GstRTPHeaderExtension *ext;
2279 State *state;
2280
2281 state = create_payloader ("application/x-rtp", &sinktmpl, NULL);
2282 ext = rtp_dummy_hdr_ext_new ();
2283 GST_RTP_DUMMY_HDR_EXT (ext)->supported_flags =
2284 GST_RTP_HEADER_EXTENSION_ONE_BYTE;
2285 GST_RTP_DUMMY_HDR_EXT (ext)->max_size = 5;
2286 gst_rtp_header_extension_set_id (ext, 1);
2287
2288 g_signal_emit_by_name (state->element, "add-extension", ext);
2289
2290 set_state (state, GST_STATE_PLAYING);
2291
2292 push_buffer (state, "pts", 0 * GST_SECOND, NULL);
2293
2294 set_state (state, GST_STATE_NULL);
2295
2296 validate_buffers_received (1);
2297
2298 validate_buffer (0, "pts", 0 * GST_SECOND, "size", (gsize) 20, "ext-data",
2299 (guint) 0xBEDE, (gsize) 4, NULL);
2300
2301 validate_events_received (3);
2302
2303 validate_normal_start_events (0);
2304
2305 fail_unless_equals_int (GST_RTP_DUMMY_HDR_EXT (ext)->write_count, 1);
2306 gst_object_unref (ext);
2307 ext = NULL;
2308
2309 destroy_payloader (state);
2310 }
2311
2312 GST_END_TEST;
2313 static Suite *
rtp_basepayloading_suite(void)2314 rtp_basepayloading_suite (void)
2315 {
2316 Suite *s = suite_create ("rtp_base_payloading_test");
2317 TCase *tc_chain = tcase_create ("payloading tests");
2318
2319 tcase_set_timeout (tc_chain, 60);
2320
2321 suite_add_tcase (s, tc_chain);
2322 tcase_add_test (tc_chain, rtp_base_payload_buffer_test);
2323 tcase_add_test (tc_chain, rtp_base_payload_buffer_list_test);
2324
2325 tcase_add_test (tc_chain, rtp_base_payload_normal_rtptime_test);
2326 tcase_add_test (tc_chain, rtp_base_payload_perfect_rtptime_test);
2327 tcase_add_test (tc_chain, rtp_base_payload_no_pts_no_offset_test);
2328
2329 tcase_add_test (tc_chain, rtp_base_payload_downstream_caps_test);
2330
2331 tcase_add_test (tc_chain, rtp_base_payload_ssrc_collision_test);
2332 tcase_add_test (tc_chain, rtp_base_payload_reconfigure_test);
2333
2334 tcase_add_test (tc_chain, rtp_base_payload_property_mtu_test);
2335 tcase_add_test (tc_chain, rtp_base_payload_property_pt_test);
2336 tcase_add_test (tc_chain, rtp_base_payload_property_ssrc_test);
2337 tcase_add_test (tc_chain, rtp_base_payload_property_timestamp_offset_test);
2338 tcase_add_test (tc_chain, rtp_base_payload_property_seqnum_offset_test);
2339 tcase_add_test (tc_chain, rtp_base_payload_property_max_ptime_test);
2340 tcase_add_test (tc_chain, rtp_base_payload_property_min_ptime_test);
2341 tcase_add_test (tc_chain, rtp_base_payload_property_timestamp_test);
2342 tcase_add_test (tc_chain, rtp_base_payload_property_seqnum_test);
2343 tcase_add_test (tc_chain, rtp_base_payload_property_perfect_rtptime_test);
2344 tcase_add_test (tc_chain, rtp_base_payload_property_ptime_multiple_test);
2345 tcase_add_test (tc_chain, rtp_base_payload_property_stats_test);
2346 tcase_add_test (tc_chain, rtp_base_payload_property_source_info_test);
2347
2348 tcase_add_test (tc_chain, rtp_base_payload_framerate_attribute);
2349 tcase_add_test (tc_chain, rtp_base_payload_max_framerate_attribute);
2350
2351 tcase_add_test (tc_chain, rtp_base_payload_segment_time);
2352
2353 tcase_add_test (tc_chain, rtp_base_payload_one_byte_hdr_ext);
2354 tcase_add_test (tc_chain, rtp_base_payload_two_byte_hdr_ext);
2355 tcase_add_test (tc_chain, rtp_base_payload_clear_extensions);
2356 tcase_add_test (tc_chain, rtp_base_payload_multiple_exts);
2357 tcase_add_test (tc_chain, rtp_base_payload_caps_request);
2358 tcase_add_test (tc_chain, rtp_base_payload_caps_request_ignored);
2359 tcase_add_test (tc_chain, rtp_base_payload_extensions_in_output_caps);
2360 tcase_add_test (tc_chain, rtp_base_payload_extensions_shrink_ext_data);
2361
2362 return s;
2363 }
2364
2365 GST_CHECK_MAIN (rtp_basepayloading)
2366