• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &timestamp, &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, &timestamp, &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", &timestamp, 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", &timestamp, 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