misc: Fix compiler warnings on Cerbero's MinGW
[platform/upstream/gstreamer.git] / tests / check / libs / rtpbasedepayload.c
1 /* GStreamer RTP base depayloader 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 #define DEFAULT_CLOCK_RATE (42)
30
31 /* GstRtpDummyDepay */
32
33 #define GST_TYPE_RTP_DUMMY_DEPAY \
34   (gst_rtp_dummy_depay_get_type())
35 #define GST_RTP_DUMMY_DEPAY(obj) \
36   (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_DUMMY_DEPAY,GstRtpDummyDepay))
37 #define GST_RTP_DUMMY_DEPAY_CLASS(klass) \
38   (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_DUMMY_DEPAY,GstRtpDummyDepayClass))
39 #define GST_IS_RTP_DUMMY_DEPAY(obj) \
40   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_DUMMY_DEPAY))
41 #define GST_IS_RTP_DUMMY_DEPAY_CLASS(klass) \
42   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_DUMMY_DEPAY))
43
44 typedef struct _GstRtpDummyDepay GstRtpDummyDepay;
45 typedef struct _GstRtpDummyDepayClass GstRtpDummyDepayClass;
46
47 struct _GstRtpDummyDepay
48 {
49   GstRTPBaseDepayload depayload;
50   guint64 rtptime;
51 };
52
53 struct _GstRtpDummyDepayClass
54 {
55   GstRTPBaseDepayloadClass parent_class;
56 };
57
58 GType gst_rtp_dummy_depay_get_type (void);
59
60 G_DEFINE_TYPE (GstRtpDummyDepay, gst_rtp_dummy_depay,
61     GST_TYPE_RTP_BASE_DEPAYLOAD);
62
63 static GstBuffer *gst_rtp_dummy_depay_process (GstRTPBaseDepayload * depayload,
64     GstBuffer * buf);
65 static gboolean gst_rtp_dummy_depay_set_caps (GstRTPBaseDepayload * filter,
66     GstCaps * caps);
67
68 static GstStaticPadTemplate gst_rtp_dummy_depay_sink_template =
69 GST_STATIC_PAD_TEMPLATE ("sink",
70     GST_PAD_SINK,
71     GST_PAD_ALWAYS,
72     GST_STATIC_CAPS_ANY);
73
74 static GstStaticPadTemplate gst_rtp_dummy_depay_src_template =
75 GST_STATIC_PAD_TEMPLATE ("src",
76     GST_PAD_SRC,
77     GST_PAD_ALWAYS,
78     GST_STATIC_CAPS_ANY);
79
80 static void
81 gst_rtp_dummy_depay_class_init (GstRtpDummyDepayClass * klass)
82 {
83   GstElementClass *gstelement_class;
84   GstRTPBaseDepayloadClass *gstrtpbasedepayload_class;
85
86   gstelement_class = GST_ELEMENT_CLASS (klass);
87   gstrtpbasedepayload_class = GST_RTP_BASE_DEPAYLOAD_CLASS (klass);
88
89   gst_element_class_add_static_pad_template (gstelement_class,
90       &gst_rtp_dummy_depay_sink_template);
91   gst_element_class_add_static_pad_template (gstelement_class,
92       &gst_rtp_dummy_depay_src_template);
93
94   gstrtpbasedepayload_class->process = gst_rtp_dummy_depay_process;
95   gstrtpbasedepayload_class->set_caps = gst_rtp_dummy_depay_set_caps;
96 }
97
98 static void
99 gst_rtp_dummy_depay_init (GstRtpDummyDepay * depay)
100 {
101   depay->rtptime = 0;
102 }
103
104 static GstRtpDummyDepay *
105 rtp_dummy_depay_new (void)
106 {
107   return g_object_new (GST_TYPE_RTP_DUMMY_DEPAY, NULL);
108 }
109
110 static GstBuffer *
111 gst_rtp_dummy_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
112 {
113   GstRTPBuffer rtp = { NULL };
114   GstBuffer *outbuf;
115   guint32 rtptime;
116   guint i;
117
118   GST_LOG ("depayloading buffer pts=%" GST_TIME_FORMAT " offset=%"
119       G_GUINT64_FORMAT " memories=%d", GST_TIME_ARGS (GST_BUFFER_PTS (buf)),
120       GST_BUFFER_OFFSET (buf), gst_buffer_n_memory (buf));
121
122   for (i = 0; i < gst_buffer_n_memory (buf); i++) {
123     GstMemory *mem = gst_buffer_get_memory (buf, 0);
124     gsize size, offset, maxsize;
125     size = gst_memory_get_sizes (mem, &offset, &maxsize);
126     GST_LOG ("\tsize=%" G_GSIZE_FORMAT " offset=%" G_GSIZE_FORMAT " maxsize=%"
127         G_GSIZE_FORMAT, size, offset, maxsize);
128     gst_memory_unref (mem);
129   }
130
131   gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp);
132   outbuf = gst_rtp_buffer_get_payload_buffer (&rtp);
133   rtptime = gst_rtp_buffer_get_timestamp (&rtp);
134   gst_rtp_buffer_unmap (&rtp);
135
136   GST_BUFFER_PTS (outbuf) = GST_BUFFER_PTS (buf);
137   GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buf);
138
139   GST_LOG ("depayloaded buffer pts=%" GST_TIME_FORMAT " offset=%"
140       G_GUINT64_FORMAT " rtptime=%" G_GUINT32_FORMAT " memories=%d",
141       GST_TIME_ARGS (GST_BUFFER_PTS (outbuf)),
142       GST_BUFFER_OFFSET (outbuf), rtptime, gst_buffer_n_memory (buf));
143
144   for (i = 0; i < gst_buffer_n_memory (buf); i++) {
145     GstMemory *mem = gst_buffer_get_memory (buf, 0);
146     gsize size, offset, maxsize;
147     size = gst_memory_get_sizes (mem, &offset, &maxsize);
148     GST_LOG ("\tsize=%" G_GSIZE_FORMAT " offset=%" G_GSIZE_FORMAT " maxsize=%"
149         G_GSIZE_FORMAT, size, offset, maxsize);
150     gst_memory_unref (mem);
151   }
152
153   return outbuf;
154 }
155
156 static gboolean
157 gst_rtp_dummy_depay_set_caps (GstRTPBaseDepayload * filter, GstCaps * caps)
158 {
159   GstEvent *event;
160   event = gst_event_new_caps (caps);
161   gst_pad_push_event (filter->srcpad, event);
162   return TRUE;
163 }
164
165 /* Helper functions and global state */
166
167 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
168     GST_PAD_SRC,
169     GST_PAD_ALWAYS,
170     GST_STATIC_CAPS_ANY);
171
172 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
173     GST_PAD_SINK,
174     GST_PAD_ALWAYS,
175     GST_STATIC_CAPS_ANY);
176
177 typedef struct State State;
178
179 struct State
180 {
181   GstElement *element;
182   GstPad *sinkpad;
183   GstPad *srcpad;
184 };
185
186 static GList *events;
187
188 static gboolean
189 event_func (GstPad * pad, GstObject * noparent, GstEvent * event)
190 {
191   events = g_list_append (events, gst_event_ref (event));
192   return gst_pad_event_default (pad, noparent, event);
193 }
194
195 static void
196 drop_events (void)
197 {
198   while (events != NULL) {
199     gst_event_unref (GST_EVENT (events->data));
200     events = g_list_delete_link (events, events);
201   }
202 }
203
204 static void
205 validate_events_received (guint received)
206 {
207   fail_unless_equals_int (g_list_length (events), received);
208 }
209
210 static void
211 validate_event (guint index, const gchar * name, const gchar * field, ...)
212 {
213   GstEvent *event;
214   va_list var_args;
215
216   fail_if (index >= g_list_length (events));
217   event = GST_EVENT (g_list_nth_data (events, index));
218   fail_if (event == NULL);
219
220   GST_TRACE ("%" GST_PTR_FORMAT, event);
221
222   fail_unless_equals_string (GST_EVENT_TYPE_NAME (event), name);
223
224   va_start (var_args, field);
225   while (field) {
226     if (!g_strcmp0 (field, "timestamp")) {
227       GstClockTime expected = va_arg (var_args, GstClockTime);
228       GstClockTime timestamp, duration;
229       gst_event_parse_gap (event, &timestamp, &duration);
230       fail_unless_equals_uint64 (timestamp, expected);
231     } else if (!g_strcmp0 (field, "duration")) {
232       GstClockTime expected = va_arg (var_args, GstClockTime);
233       GstClockTime timestamp, duration;
234       gst_event_parse_gap (event, &timestamp, &duration);
235       fail_unless_equals_uint64 (duration, expected);
236     } else if (!g_strcmp0 (field, "time")) {
237       GstClockTime expected = va_arg (var_args, GstClockTime);
238       const GstSegment *segment;
239       gst_event_parse_segment (event, &segment);
240       fail_unless_equals_uint64 (segment->time, expected);
241     } else if (!g_strcmp0 (field, "start")) {
242       GstClockTime expected = va_arg (var_args, GstClockTime);
243       const GstSegment *segment;
244       gst_event_parse_segment (event, &segment);
245       fail_unless_equals_uint64 (segment->start, expected);
246     } else if (!g_strcmp0 (field, "stop")) {
247       GstClockTime expected = va_arg (var_args, GstClockTime);
248       const GstSegment *segment;
249       gst_event_parse_segment (event, &segment);
250       fail_unless_equals_uint64 (segment->stop, expected);
251     } else if (!g_strcmp0 (field, "applied-rate")) {
252       gdouble expected = va_arg (var_args, gdouble);
253       const GstSegment *segment;
254       gst_event_parse_segment (event, &segment);
255       fail_unless_equals_uint64 (segment->applied_rate, expected);
256     } else if (!g_strcmp0 (field, "rate")) {
257       gdouble expected = va_arg (var_args, gdouble);
258       const GstSegment *segment;
259       gst_event_parse_segment (event, &segment);
260       fail_unless_equals_uint64 (segment->rate, expected);
261     } else if (!g_strcmp0 (field, "base")) {
262       GstClockTime expected = va_arg (var_args, GstClockTime);
263       const GstSegment *segment;
264       gst_event_parse_segment (event, &segment);
265       fail_unless_equals_uint64 (segment->base, expected);
266     } else if (!g_strcmp0 (field, "media-type")) {
267       const gchar *expected = va_arg (var_args, const gchar *);
268       GstCaps *caps;
269       const gchar *media_type;
270       gst_event_parse_caps (event, &caps);
271       media_type = gst_structure_get_name (gst_caps_get_structure (caps, 0));
272       fail_unless_equals_string (media_type, expected);
273     } else if (!g_strcmp0 (field, "npt-start")) {
274       GstClockTime expected = va_arg (var_args, GstClockTime);
275       GstCaps *caps;
276       GstClockTime start;
277       gst_event_parse_caps (event, &caps);
278       fail_unless (gst_structure_get_clock_time (gst_caps_get_structure (caps,
279                   0), "npt-start", &start));
280       fail_unless_equals_uint64 (start, expected);
281     } else if (!g_strcmp0 (field, "npt-stop")) {
282       GstClockTime expected = va_arg (var_args, GstClockTime);
283       GstCaps *caps;
284       GstClockTime stop;
285       gst_event_parse_caps (event, &caps);
286       fail_unless (gst_structure_get_clock_time (gst_caps_get_structure (caps,
287                   0), "npt-stop", &stop));
288       fail_unless_equals_uint64 (stop, expected);
289     } else if (!g_strcmp0 (field, "play-speed")) {
290       gdouble expected = va_arg (var_args, gdouble);
291       GstCaps *caps;
292       gdouble speed;
293       gst_event_parse_caps (event, &caps);
294       fail_unless (gst_structure_get_double (gst_caps_get_structure (caps, 0),
295               "play-speed", &speed));
296       fail_unless (speed == expected);
297     } else if (!g_strcmp0 (field, "play-scale")) {
298       gdouble expected = va_arg (var_args, gdouble);
299       GstCaps *caps;
300       gdouble scale;
301       gst_event_parse_caps (event, &caps);
302       fail_unless (gst_structure_get_double (gst_caps_get_structure (caps, 0),
303               "play-scale", &scale));
304       fail_unless (scale == expected);
305     } else if (!g_strcmp0 (field, "clock-base")) {
306       guint expected = va_arg (var_args, guint);
307       GstCaps *caps;
308       guint clock_base;
309       gst_event_parse_caps (event, &caps);
310       fail_unless (gst_structure_get_uint (gst_caps_get_structure (caps, 0),
311               "clock-base", &clock_base));
312       fail_unless (clock_base == expected);
313
314     } else {
315       fail ("test cannot validate unknown event field '%s'", field);
316     }
317     field = va_arg (var_args, const gchar *);
318   }
319   va_end (var_args);
320 }
321
322 static void
323 rtp_buffer_set_valist (GstBuffer * buf, const gchar * field, va_list var_args,
324     gboolean * extra_ref_)
325 {
326   GstRTPBuffer rtp = { NULL };
327   gboolean mapped = FALSE;
328   gboolean extra_ref = FALSE;
329
330   while (field) {
331     if (!g_strcmp0 (field, "pts")) {
332       GstClockTime pts = va_arg (var_args, GstClockTime);
333       GST_BUFFER_PTS (buf) = pts;
334     } else if (!g_strcmp0 (field, "offset")) {
335       guint64 offset = va_arg (var_args, guint64);
336       GST_BUFFER_OFFSET (buf) = offset;
337     } else if (!g_strcmp0 (field, "discont")) {
338       gboolean discont = va_arg (var_args, gboolean);
339       if (discont) {
340         GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
341       } else {
342         GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
343       }
344     } else {
345       if (!mapped) {
346         gst_rtp_buffer_map (buf, GST_MAP_WRITE, &rtp);
347         mapped = TRUE;
348       }
349       if (!g_strcmp0 (field, "rtptime")) {
350         guint32 rtptime = va_arg (var_args, guint64);
351         gst_rtp_buffer_set_timestamp (&rtp, rtptime);
352       } else if (!g_strcmp0 (field, "payload-type")) {
353         guint payload_type = va_arg (var_args, guint);
354         gst_rtp_buffer_set_payload_type (&rtp, payload_type);
355       } else if (!g_strcmp0 (field, "seq")) {
356         guint seq = va_arg (var_args, guint);
357         gst_rtp_buffer_set_seq (&rtp, seq);
358       } else if (!g_strcmp0 (field, "ssrc")) {
359         guint32 ssrc = va_arg (var_args, guint);
360         gst_rtp_buffer_set_ssrc (&rtp, ssrc);
361       } else if (!g_strcmp0 (field, "extra-ref")) {
362         extra_ref = va_arg (var_args, gboolean);
363         if (extra_ref_)
364           *extra_ref_ = extra_ref;
365       } else if (!g_strcmp0 (field, "csrc")) {
366         guint idx = va_arg (var_args, guint);
367         guint csrc = va_arg (var_args, guint);
368         gst_rtp_buffer_set_csrc (&rtp, idx, csrc);
369       } else {
370         fail ("test cannot set unknown buffer field '%s'", field);
371       }
372     }
373     field = va_arg (var_args, const gchar *);
374   }
375
376   if (mapped) {
377     gst_rtp_buffer_unmap (&rtp);
378   }
379
380   if (extra_ref)
381     gst_buffer_ref (buf);
382 }
383
384 static void
385 rtp_buffer_set (GstBuffer * buf, const gchar * field, ...)
386 {
387   va_list var_args;
388
389   va_start (var_args, field);
390   rtp_buffer_set_valist (buf, field, var_args, NULL);
391   va_end (var_args);
392 }
393
394 #define push_rtp_buffer(state, field, ...) \
395     push_rtp_buffer_full ((state), GST_FLOW_OK, (field), __VA_ARGS__)
396 #define push_rtp_buffer_fails(state, error, field, ...) \
397     push_rtp_buffer_full ((state), (error), (field), __VA_ARGS__)
398
399 static void
400 push_rtp_buffer_full (State * state, GstFlowReturn expected,
401     const gchar * field, ...)
402 {
403   GstBuffer *buf = gst_rtp_buffer_new_allocate (0, 0, 0);
404   va_list var_args;
405   gboolean extra_ref = FALSE;
406
407   va_start (var_args, field);
408   rtp_buffer_set_valist (buf, field, var_args, &extra_ref);
409   va_end (var_args);
410
411   fail_unless_equals_int (gst_pad_push (state->srcpad, buf), expected);
412
413   if (extra_ref)
414     gst_buffer_unref (buf);
415 }
416
417 #define push_buffer(state, field, ...) \
418     push_buffer_full ((state), GST_FLOW_OK, (field), __VA_ARGS__)
419
420 static void
421 push_buffer_full (State * state, GstFlowReturn expected,
422     const gchar * field, ...)
423 {
424   GstBuffer *buf = gst_buffer_new_allocate (0, 0, 0);
425   va_list var_args;
426
427   va_start (var_args, field);
428   while (field) {
429     if (!g_strcmp0 (field, "pts")) {
430       GstClockTime pts = va_arg (var_args, GstClockTime);
431       GST_BUFFER_PTS (buf) = pts;
432     } else if (!g_strcmp0 (field, "offset")) {
433       guint64 offset = va_arg (var_args, guint64);
434       GST_BUFFER_OFFSET (buf) = offset;
435     } else if (!g_strcmp0 (field, "discont")) {
436       gboolean discont = va_arg (var_args, gboolean);
437       if (discont) {
438         GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
439       } else {
440         GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
441       }
442     } else {
443       fail ("test cannot set unknown buffer field '%s'", field);
444     }
445     field = va_arg (var_args, const gchar *);
446   }
447   va_end (var_args);
448
449   fail_unless_equals_int (gst_pad_push (state->srcpad, buf), expected);
450 }
451
452 static void
453 validate_buffers_received (guint received)
454 {
455   fail_unless_equals_int (g_list_length (buffers), received);
456 }
457
458 static void
459 validate_buffer (guint index, const gchar * field, ...)
460 {
461   GstBuffer *buf;
462   va_list var_args;
463
464   fail_if (index >= g_list_length (buffers));
465   buf = GST_BUFFER (g_list_nth_data (buffers, (index)));
466   fail_if (buf == NULL);
467
468   GST_TRACE ("%" GST_PTR_FORMAT, buf);
469
470   va_start (var_args, field);
471   while (field) {
472     if (!g_strcmp0 (field, "pts")) {
473       GstClockTime pts = va_arg (var_args, GstClockTime);
474       fail_unless_equals_uint64 (GST_BUFFER_PTS (buf), pts);
475     } else if (!g_strcmp0 (field, "offset")) {
476       guint64 offset = va_arg (var_args, guint64);
477       fail_unless_equals_uint64 (GST_BUFFER_OFFSET (buf), offset);
478     } else if (!g_strcmp0 (field, "discont")) {
479       gboolean discont = va_arg (var_args, gboolean);
480       if (discont) {
481         fail_unless (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
482       } else {
483         fail_if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
484       }
485     } else {
486       fail ("test cannot validate unknown buffer field '%s'", field);
487     }
488     field = va_arg (var_args, const gchar *);
489   }
490   va_end (var_args);
491 }
492
493 static State *
494 create_depayloader (const gchar * caps_str, const gchar * property, ...)
495 {
496   va_list var_args;
497   GstCaps *caps;
498   State *state;
499
500   state = g_new0 (State, 1);
501
502   state->element = GST_ELEMENT (rtp_dummy_depay_new ());
503   fail_unless (GST_IS_RTP_DUMMY_DEPAY (state->element));
504
505   va_start (var_args, property);
506   g_object_set_valist (G_OBJECT (state->element), property, var_args);
507   va_end (var_args);
508
509   state->srcpad = gst_check_setup_src_pad (state->element, &srctemplate);
510   state->sinkpad = gst_check_setup_sink_pad (state->element, &sinktemplate);
511
512   fail_unless (gst_pad_set_active (state->srcpad, TRUE));
513   fail_unless (gst_pad_set_active (state->sinkpad, TRUE));
514
515   if (caps_str) {
516     caps = gst_caps_from_string (caps_str);
517   } else {
518     caps = NULL;
519   }
520   gst_check_setup_events (state->srcpad, state->element, caps, GST_FORMAT_TIME);
521   if (caps) {
522     gst_caps_unref (caps);
523   }
524
525   gst_pad_set_chain_function (state->sinkpad, gst_check_chain_func);
526   gst_pad_set_event_function (state->sinkpad, event_func);
527
528   return state;
529 }
530
531 static void
532 set_state (State * state, GstState new_state)
533 {
534   fail_unless_equals_int (gst_element_set_state (state->element, new_state),
535       GST_STATE_CHANGE_SUCCESS);
536 }
537
538 static void
539 packet_lost (State * state, GstClockTime timestamp, GstClockTime duration,
540     gboolean might_have_been_fec)
541 {
542   GstEvent *event;
543   guint seqnum = 0x4243;
544   gboolean late = TRUE;
545   guint retries = 42;
546
547   event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
548       gst_structure_new ("GstRTPPacketLost",
549           "seqnum", G_TYPE_UINT, seqnum,
550           "timestamp", G_TYPE_UINT64, timestamp,
551           "duration", G_TYPE_UINT64, duration,
552           "might-have-been-fec", G_TYPE_BOOLEAN, might_have_been_fec,
553           "late", G_TYPE_BOOLEAN, late, "retry", G_TYPE_UINT, retries, NULL));
554
555   fail_unless (gst_pad_push_event (state->srcpad, event));
556 }
557
558 static void
559 reconfigure_caps (State * state, const gchar * caps_str)
560 {
561   GstCaps *newcaps;
562   GstEvent *event;
563   newcaps = gst_caps_from_string (caps_str);
564   event = gst_event_new_caps (newcaps);
565   gst_caps_unref (newcaps);
566   fail_unless (gst_pad_push_event (state->srcpad, event));
567 }
568
569 static void
570 flush_pipeline (State * state)
571 {
572   GstEvent *event;
573   GstSegment segment;
574   event = gst_event_new_flush_start ();
575   fail_unless (gst_pad_push_event (state->srcpad, event));
576   event = gst_event_new_flush_stop (TRUE);
577   fail_unless (gst_pad_push_event (state->srcpad, event));
578   gst_segment_init (&segment, GST_FORMAT_TIME);
579   event = gst_event_new_segment (&segment);
580   fail_unless (gst_pad_push_event (state->srcpad, event));
581 }
582
583 static void
584 destroy_depayloader (State * state)
585 {
586   gst_check_teardown_sink_pad (state->element);
587   gst_check_teardown_src_pad (state->element);
588
589   gst_check_drop_buffers ();
590   drop_events ();
591
592   g_object_unref (state->element);
593
594   g_free (state);
595 }
596
597 /* Tests */
598
599 /* send two RTP packets having sequential sequence numbers and timestamps
600  * differing by DEFAULT_CLOCK_RATE. the depayloader first pushes the normal
601  * stream-start, caps and segment events downstream before processing each RTP
602  * packet and pushing a corresponding buffer. PTS will be carried over from the
603  * RTP packets by the payloader to the buffers. because the sequence numbers are
604  * sequential then GST_BUFFER_FLAG_DISCONT will not be set for either buffer.
605  */
606 GST_START_TEST (rtp_base_depayload_buffer_test)
607 {
608   State *state;
609
610   state = create_depayloader ("application/x-rtp", NULL);
611
612   set_state (state, GST_STATE_PLAYING);
613
614   push_rtp_buffer (state,
615       "pts", 0 * GST_SECOND,
616       "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 0x4242, NULL);
617
618   push_rtp_buffer (state,
619       "pts", 1 * GST_SECOND,
620       "rtptime", G_GUINT64_CONSTANT (0x1234) + 1 * DEFAULT_CLOCK_RATE,
621       "seq", 0x4242 + 1, NULL);
622
623   set_state (state, GST_STATE_NULL);
624
625   validate_buffers_received (2);
626
627   validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
628
629   validate_buffer (1, "pts", 1 * GST_SECOND, "discont", FALSE, NULL);
630
631   validate_events_received (3);
632
633   validate_event (0, "stream-start", NULL);
634
635   validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
636
637   validate_event (2, "segment",
638       "time", G_GUINT64_CONSTANT (0),
639       "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
640
641   destroy_depayloader (state);
642 }
643
644 GST_END_TEST
645 /* the intent with this test is to provide the depayloader with a buffer that
646  * does not contain an RTP header. this makes it impossible for the depayloader
647  * to depayload the incoming RTP packet, yet the stream-start and caps events
648  * will still be pushed.
649  */
650 GST_START_TEST (rtp_base_depayload_invalid_rtp_packet_test)
651 {
652   State *state;
653
654   state = create_depayloader ("application/x-rtp", NULL);
655
656   set_state (state, GST_STATE_PLAYING);
657
658   push_buffer (state,
659       "pts", 0 * GST_SECOND, "offset", GST_BUFFER_OFFSET_NONE, NULL);
660
661   set_state (state, GST_STATE_NULL);
662
663   validate_buffers_received (0);
664
665   validate_events_received (2);
666
667   validate_event (0, "stream-start", NULL);
668
669   validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
670
671   destroy_depayloader (state);
672 }
673
674 GST_END_TEST
675 /* validate what happens when a depayloader is provided with two RTP packets
676  * sent after each other that do not have sequential sequence numbers. in this
677  * case the depayloader should be able to depayload both first and the second
678  * buffer, but the second buffer will have GST_BUFFER_FLAG_DISCONT set to
679  * indicate that the was a discontinuity in the stream. the initial events are
680  * pushed prior to the buffers arriving so they should be unaffected by the gap
681  * in sequence numbers.
682  */
683 GST_START_TEST (rtp_base_depayload_with_gap_test)
684 {
685   State *state;
686
687   state = create_depayloader ("application/x-rtp", NULL);
688
689   set_state (state, GST_STATE_PLAYING);
690
691   push_rtp_buffer (state,
692       "pts", 0 * GST_SECOND,
693       "rtptime", G_GUINT64_CONSTANT (0x43214321), "seq", 0x4242, NULL);
694
695   push_rtp_buffer (state,
696       "pts", 1 * GST_SECOND,
697       "rtptime", G_GUINT64_CONSTANT (0x43214321) + 1 * DEFAULT_CLOCK_RATE,
698       "seq", 0x4242 + 2, NULL);
699
700   set_state (state, GST_STATE_NULL);
701
702   validate_buffers_received (2);
703
704   validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
705
706   validate_buffer (1, "pts", 1 * GST_SECOND, "discont", TRUE, NULL);
707
708   validate_events_received (3);
709
710   validate_event (0, "stream-start", NULL);
711
712   validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
713
714   validate_event (2, "segment",
715       "time", G_GUINT64_CONSTANT (0),
716       "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
717
718   destroy_depayloader (state);
719 }
720
721 GST_END_TEST
722 /* two RTP packets are pushed in this test, and while the sequence numbers are
723  * sequential they are reversed. the expectation is that the depayloader will be
724  * able to depayload the first RTP packet, but once the second RTP packet
725  * arrives it will be discarded because it arrived too late. the initial events
726  * should be unaffected by the reversed buffers.
727  */
728 GST_START_TEST (rtp_base_depayload_reversed_test)
729 {
730   State *state;
731
732   state = create_depayloader ("application/x-rtp", NULL);
733
734   set_state (state, GST_STATE_PLAYING);
735
736   push_rtp_buffer (state,
737       "pts", 0 * GST_SECOND,
738       "rtptime", G_GUINT64_CONSTANT (0x43214321), "seq", 0x4242, NULL);
739
740   push_rtp_buffer (state,
741       "pts", 1 * GST_SECOND,
742       "rtptime", G_GUINT64_CONSTANT (0x43214321) + 1 * DEFAULT_CLOCK_RATE,
743       "seq", 0x4242 - 1, NULL);
744
745   set_state (state, GST_STATE_NULL);
746
747   validate_buffers_received (1);
748
749   validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
750
751   validate_events_received (3);
752
753   validate_event (0, "stream-start", NULL);
754
755   validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
756
757   validate_event (2, "segment",
758       "time", G_GUINT64_CONSTANT (0),
759       "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
760
761   destroy_depayloader (state);
762 }
763
764 GST_END_TEST
765 /* The same scenario as in rtp_base_depayload_reversed_test
766  * except that SSRC is changed for the 2nd packet that is why
767  * it should not be discarded.
768  */
769 GST_START_TEST (rtp_base_depayload_ssrc_changed_test)
770 {
771   State *state;
772
773   state = create_depayloader ("application/x-rtp", NULL);
774
775   set_state (state, GST_STATE_PLAYING);
776
777   push_rtp_buffer (state,
778       "pts", 0 * GST_SECOND,
779       "rtptime", G_GUINT64_CONSTANT (0x43214321),
780       "seq", 0x4242, "ssrc", 0xabe2b0b, NULL);
781
782   push_rtp_buffer (state,
783       "pts", 1 * GST_SECOND,
784       "rtptime", G_GUINT64_CONSTANT (0x43214321) + 1 * DEFAULT_CLOCK_RATE,
785       "seq", 0x4242 - 1, "ssrc", 0xcafebabe, NULL);
786
787   set_state (state, GST_STATE_NULL);
788
789   validate_buffers_received (2);
790
791   validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
792
793   validate_buffer (1, "pts", 1 * GST_SECOND, "discont", TRUE, NULL);
794
795   validate_events_received (3);
796
797   validate_event (0, "stream-start", NULL);
798
799   validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
800
801   validate_event (2, "segment",
802       "time", G_GUINT64_CONSTANT (0),
803       "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
804
805   destroy_depayloader (state);
806 }
807
808 GST_END_TEST
809 /* the intent of this test is to push two RTP packets that have reverse sequence
810  * numbers that differ significantly. the depayloader will consider RTP packets
811  * where the sequence numbers differ by more than 1000 to indicate that the
812  * source of the RTP packets has been restarted. therefore it will let both
813  * depayloaded buffers through, but the latter buffer marked
814  * GST_BUFFER_FLAG_DISCONT to indicate the discontinuity in the stream. the
815  * initial events should be unaffected by the reversed buffers.
816  */
817 GST_START_TEST (rtp_base_depayload_old_reversed_test)
818 {
819   State *state;
820
821   state = create_depayloader ("application/x-rtp", NULL);
822
823   set_state (state, GST_STATE_PLAYING);
824
825   push_rtp_buffer (state,
826       "pts", 0 * GST_SECOND,
827       "rtptime", G_GUINT64_CONSTANT (0x43214321), "seq", 0x4242, NULL);
828
829   push_rtp_buffer (state,
830       "pts", 1 * GST_SECOND,
831       "rtptime", G_GUINT64_CONSTANT (0x43214321) + 1 * DEFAULT_CLOCK_RATE,
832       "seq", 0x4242 - 1000, NULL);
833
834   set_state (state, GST_STATE_NULL);
835
836   validate_buffers_received (2);
837
838   validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
839
840   validate_buffer (1, "pts", 1 * GST_SECOND, "discont", TRUE, NULL);
841
842   validate_events_received (3);
843
844   validate_event (0, "stream-start", NULL);
845
846   validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
847
848   validate_event (2, "segment",
849       "time", G_GUINT64_CONSTANT (0),
850       "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
851
852   destroy_depayloader (state);
853 }
854
855 GST_END_TEST
856 /* a depayloader that has not received any caps event will not be able to
857  * process any incoming RTP packet. instead pushing an RTP packet should result
858  * in the expected error.
859  */
860 GST_START_TEST (rtp_base_depayload_without_negotiation_test)
861 {
862   State *state;
863
864   state = create_depayloader (NULL, NULL);
865
866   set_state (state, GST_STATE_PLAYING);
867
868   push_rtp_buffer_fails (state, GST_FLOW_NOT_NEGOTIATED,
869       "pts", 0 * GST_SECOND,
870       "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 0x4242, NULL);
871
872   set_state (state, GST_STATE_NULL);
873
874   validate_buffers_received (0);
875
876   validate_events_received (1);
877
878   validate_event (0, "stream-start", NULL);
879
880   destroy_depayloader (state);
881 }
882
883 GST_END_TEST
884 /* a depayloader that receives the downstream event GstRTPPacketLost should
885  * respond by emitting a gap event with the corresponding timestamp and
886  * duration. the initial events are unaffected, but are succeeded by the added
887  * gap event.
888  */
889 GST_START_TEST (rtp_base_depayload_packet_lost_test)
890 {
891   State *state;
892
893   state = create_depayloader ("application/x-rtp", NULL);
894
895   set_state (state, GST_STATE_PLAYING);
896
897   push_rtp_buffer (state,
898       "pts", 0 * GST_SECOND,
899       "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 0x4242, NULL);
900
901   packet_lost (state, 1 * GST_SECOND, GST_SECOND, FALSE);
902
903   /* If a packet was lost but we don't know whether it was a FEC packet,
904    * the depayloader should not generate gap events */
905   packet_lost (state, 2 * GST_SECOND, GST_SECOND, TRUE);
906
907   push_rtp_buffer (state,
908       "pts", 2 * GST_SECOND,
909       "rtptime", G_GUINT64_CONSTANT (0x1234) + 2 * DEFAULT_CLOCK_RATE,
910       "seq", 0x4242 + 2, NULL);
911
912   set_state (state, GST_STATE_NULL);
913
914   validate_buffers_received (2);
915
916   validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
917
918   validate_buffer (1, "pts", 2 * GST_SECOND, "discont", TRUE, NULL);
919
920   validate_events_received (4);
921
922   validate_event (0, "stream-start", NULL);
923
924   validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
925
926   validate_event (2, "segment",
927       "time", G_GUINT64_CONSTANT (0),
928       "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
929
930   validate_event (3, "gap",
931       "timestamp", 1 * GST_SECOND, "duration", GST_SECOND, NULL);
932
933   destroy_depayloader (state);
934 }
935
936 GST_END_TEST
937 /* rtp base depayloader should set DISCONT flag on buffer in case of a large
938  * sequence number gap, and it's not set already by upstream. This tests a
939  * certain code path where the buffer needs to be made writable to set the
940  * DISCONT flag.
941  */
942 GST_START_TEST (rtp_base_depayload_seq_discont_test)
943 {
944   State *state;
945
946   state = create_depayloader ("application/x-rtp", NULL);
947
948   set_state (state, GST_STATE_PLAYING);
949
950   push_rtp_buffer (state,
951       "pts", 0 * GST_SECOND,
952       "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 1, NULL);
953
954   push_rtp_buffer (state,
955       "extra-ref", TRUE,
956       "pts", 2 * GST_SECOND,
957       "rtptime", G_GUINT64_CONSTANT (0x1234) + DEFAULT_CLOCK_RATE / 2,
958       "seq", 33333, NULL);
959
960   set_state (state, GST_STATE_NULL);
961
962   validate_buffers_received (2);
963
964   validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
965
966   validate_buffer (1, "pts", 2 * GST_SECOND, "discont", TRUE, NULL);
967
968   destroy_depayloader (state);
969 }
970
971 GST_END_TEST
972 /* a depayloader that receives identical caps events simply ignores the latter
973  * events without propagating them downstream.
974  */
975 GST_START_TEST (rtp_base_depayload_repeated_caps_test)
976 {
977   State *state;
978
979   state = create_depayloader ("application/x-rtp", NULL);
980
981   set_state (state, GST_STATE_PLAYING);
982
983   push_rtp_buffer (state,
984       "pts", 0 * GST_SECOND,
985       "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 0x4242, NULL);
986
987   reconfigure_caps (state, "application/x-rtp");
988
989   push_rtp_buffer (state,
990       "pts", 1 * GST_SECOND,
991       "rtptime", G_GUINT64_CONSTANT (0x1234) + 1 * DEFAULT_CLOCK_RATE,
992       "seq", 0x4242 + 1, NULL);
993
994   set_state (state, GST_STATE_NULL);
995
996   validate_buffers_received (2);
997
998   validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
999
1000   validate_buffer (1, "pts", 1 * GST_SECOND, "discont", FALSE, NULL);
1001
1002   validate_events_received (3);
1003
1004   validate_event (0, "stream-start", NULL);
1005
1006   validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
1007
1008   validate_event (2, "segment",
1009       "time", G_GUINT64_CONSTANT (0),
1010       "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
1011
1012   destroy_depayloader (state);
1013 }
1014
1015 GST_END_TEST
1016 /* when a depayloader receives new caps events with npt-start and npt-stop times
1017  * it should save these timestamps as they should affect the next segment event
1018  * being pushed by the depayloader. a new segment event is not pushed by the
1019  * depayloader until a flush_stop event and a succeeding segment event are
1020  * received. of course the intial event are unaffected, as is the incoming caps
1021  * event.
1022  */
1023 GST_START_TEST (rtp_base_depayload_npt_test)
1024 {
1025   State *state;
1026
1027   state = create_depayloader ("application/x-rtp", NULL);
1028
1029   set_state (state, GST_STATE_PLAYING);
1030
1031   push_rtp_buffer (state,
1032       "pts", 0 * GST_SECOND,
1033       "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 0x4242, NULL);
1034
1035   reconfigure_caps (state,
1036       "application/x-rtp, npt-start=(guint64)1234, npt-stop=(guint64)4321");
1037
1038   flush_pipeline (state);
1039
1040   push_rtp_buffer (state,
1041       "pts", 1 * GST_SECOND,
1042       "rtptime", G_GUINT64_CONSTANT (0x1234) + 1 * DEFAULT_CLOCK_RATE,
1043       "seq", 0x4242 + 1, NULL);
1044
1045   set_state (state, GST_STATE_NULL);
1046
1047   validate_buffers_received (2);
1048
1049   validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
1050
1051   validate_buffer (1, "pts", 1 * GST_SECOND, "discont", FALSE, NULL);
1052
1053   validate_events_received (7);
1054
1055   validate_event (0, "stream-start", NULL);
1056
1057   validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
1058
1059   validate_event (2, "segment",
1060       "time", G_GUINT64_CONSTANT (0),
1061       "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
1062
1063   validate_event (3, "caps",
1064       "media-type", "application/x-rtp",
1065       "npt-start", G_GUINT64_CONSTANT (1234),
1066       "npt-stop", G_GUINT64_CONSTANT (4321), NULL);
1067
1068   validate_event (4, "flush-start", NULL);
1069
1070   validate_event (5, "flush-stop", NULL);
1071
1072   validate_event (6, "segment",
1073       "time", G_GUINT64_CONSTANT (1234),
1074       "start", G_GUINT64_CONSTANT (0),
1075       "stop", G_GUINT64_CONSTANT (4321 - 1234), NULL);
1076
1077   destroy_depayloader (state);
1078 }
1079
1080 GST_END_TEST
1081 /* when a depayloader receives a new caps event with play-scale it should save
1082  * this rate as it should affect the next segment event being pushed by the
1083  * depayloader. a new segment event is not pushed by the depayloader until a
1084  * flush_stop event and a succeeding segment event are received. of course the
1085  * intial event are unaffected, as is the incoming caps event.
1086  */
1087 GST_START_TEST (rtp_base_depayload_play_scale_test)
1088 {
1089   State *state;
1090
1091   state = create_depayloader ("application/x-rtp", NULL);
1092
1093   set_state (state, GST_STATE_PLAYING);
1094
1095   push_rtp_buffer (state,
1096       "pts", 0 * GST_SECOND,
1097       "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 0x4242, NULL);
1098
1099   reconfigure_caps (state, "application/x-rtp, play-scale=(double)2.0");
1100
1101   flush_pipeline (state);
1102
1103   push_rtp_buffer (state,
1104       "pts", 1 * GST_SECOND,
1105       "rtptime", G_GUINT64_CONSTANT (0x1234) + 1 * DEFAULT_CLOCK_RATE,
1106       "seq", 0x4242 + 1, NULL);
1107
1108   set_state (state, GST_STATE_NULL);
1109
1110   validate_buffers_received (2);
1111
1112   validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
1113
1114   validate_buffer (1, "pts", 1 * GST_SECOND, "discont", FALSE, NULL);
1115
1116   validate_events_received (7);
1117
1118   validate_event (0, "stream-start", NULL);
1119
1120   validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
1121
1122   validate_event (2, "segment",
1123       "time", G_GUINT64_CONSTANT (0),
1124       "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
1125
1126   validate_event (3, "caps",
1127       "media-type", "application/x-rtp", "play-scale", 2.0, NULL);
1128
1129   validate_event (4, "flush-start", NULL);
1130
1131   validate_event (5, "flush-stop", NULL);
1132
1133   validate_event (6, "segment",
1134       "time", G_GUINT64_CONSTANT (0),
1135       "start", G_GUINT64_CONSTANT (0),
1136       "stop", G_MAXUINT64, "rate", 1.0, "applied-rate", 2.0, NULL);
1137
1138   destroy_depayloader (state);
1139 }
1140
1141 GST_END_TEST
1142 /* when a depayloader receives a new caps event with play-speed it should save
1143  * this rate as it should affect the next segment event being pushed by the
1144  * depayloader. a new segment event is not pushed by the depayloader until a
1145  * flush_stop event and a succeeding segment event are received. of course the
1146  * intial event are unaffected, as is the incoming caps event.
1147  */
1148 GST_START_TEST (rtp_base_depayload_play_speed_test)
1149 {
1150   State *state;
1151
1152   state = create_depayloader ("application/x-rtp", NULL);
1153
1154   set_state (state, GST_STATE_PLAYING);
1155
1156   push_rtp_buffer (state,
1157       "pts", 0 * GST_SECOND,
1158       "rtptime", G_GUINT64_CONSTANT (0x1234), "seq", 0x4242, NULL);
1159
1160   reconfigure_caps (state, "application/x-rtp, play-speed=(double)2.0");
1161
1162   flush_pipeline (state);
1163
1164   push_rtp_buffer (state,
1165       "pts", 1 * GST_SECOND,
1166       "rtptime", G_GUINT64_CONSTANT (0x1234) + 1 * DEFAULT_CLOCK_RATE,
1167       "seq", 0x4242 + 1, NULL);
1168
1169   set_state (state, GST_STATE_NULL);
1170
1171   validate_buffers_received (2);
1172
1173   validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
1174
1175   validate_buffer (1, "pts", 1 * GST_SECOND, "discont", FALSE, NULL);
1176
1177   validate_events_received (7);
1178
1179   validate_event (0, "stream-start", NULL);
1180
1181   validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
1182
1183   validate_event (2, "segment",
1184       "time", G_GUINT64_CONSTANT (0),
1185       "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
1186
1187   validate_event (3, "caps",
1188       "media-type", "application/x-rtp", "play-speed", 2.0, NULL);
1189
1190   validate_event (4, "flush-start", NULL);
1191
1192   validate_event (5, "flush-stop", NULL);
1193
1194   validate_event (6, "segment",
1195       "time", G_GUINT64_CONSTANT (0),
1196       "start", G_GUINT64_CONSTANT (0),
1197       "stop", G_MAXUINT64, "rate", 2.0, "applied-rate", 1.0, NULL);
1198
1199   destroy_depayloader (state);
1200 }
1201
1202 GST_END_TEST
1203 /* when a depayloader receives new caps events with npt-start, npt-stop and
1204  * clock-base it should save these timestamps as they should affect the next
1205  * segment event being pushed by the depayloader. the produce segment should
1206  * make the positon of the stream reflect the postion form clock-base instead
1207  * of reflecting the running time (for RTSP).
1208  */
1209 GST_START_TEST (rtp_base_depayload_clock_base_test)
1210 {
1211   State *state;
1212
1213   state = create_depayloader ("application/x-rtp", NULL);
1214
1215   set_state (state, GST_STATE_PLAYING);
1216
1217   push_rtp_buffer (state,
1218       "pts", 0 * GST_SECOND,
1219       "rtptime", G_GUINT64_CONSTANT (1234), "seq", 0x4242, NULL);
1220
1221   reconfigure_caps (state,
1222       "application/x-rtp, npt-start=(guint64)1234, npt-stop=(guint64)4321, clock-base=(guint)1234");
1223
1224   flush_pipeline (state);
1225
1226   push_rtp_buffer (state,
1227       "pts", 1 * GST_SECOND,
1228       "rtptime", G_GUINT64_CONSTANT (1234) + 1 * DEFAULT_CLOCK_RATE,
1229       "seq", 0x4242 + 1, NULL);
1230
1231   set_state (state, GST_STATE_NULL);
1232
1233   validate_buffers_received (2);
1234
1235   validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
1236
1237   validate_buffer (1, "pts", 1 * GST_SECOND, "discont", FALSE, NULL);
1238
1239   validate_events_received (7);
1240
1241   validate_event (0, "stream-start", NULL);
1242
1243   validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
1244
1245   validate_event (2, "segment",
1246       "time", G_GUINT64_CONSTANT (0),
1247       "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
1248
1249   validate_event (3, "caps",
1250       "media-type", "application/x-rtp",
1251       "npt-start", G_GUINT64_CONSTANT (1234),
1252       "npt-stop", G_GUINT64_CONSTANT (4321), "clock-base", 1234, NULL);
1253
1254   validate_event (4, "flush-start", NULL);
1255
1256   validate_event (5, "flush-stop", NULL);
1257
1258   validate_event (6, "segment",
1259       "time", G_GUINT64_CONSTANT (1234),
1260       "start", GST_SECOND,
1261       "stop", GST_SECOND + G_GUINT64_CONSTANT (4321 - 1234),
1262       "base", GST_SECOND, NULL);
1263
1264   destroy_depayloader (state);
1265 }
1266
1267 GST_END_TEST
1268 /* basedepayloader has a property source-info that will add
1269  * GstRTPSourceMeta to the output buffer with RTP source information, such as
1270  * SSRC and CSRCs. The is useful for letting downstream know about the origin
1271  * of the stream. */
1272 GST_START_TEST (rtp_base_depayload_source_info_test)
1273 {
1274   GstHarness *h;
1275   GstRtpDummyDepay *depay;
1276   GstBuffer *buffer;
1277   GstRTPSourceMeta *meta;
1278   guint seq = 0;
1279
1280   depay = rtp_dummy_depay_new ();
1281   h = gst_harness_new_with_element (GST_ELEMENT_CAST (depay), "sink", "src");
1282   gst_harness_set_src_caps_str (h, "application/x-rtp");
1283
1284   /* Property enabled should always add meta, also when there is only SSRC and
1285    * no CSRC. */
1286   g_object_set (depay, "source-info", TRUE, NULL);
1287   buffer = gst_rtp_buffer_new_allocate (0, 0, 0);
1288   rtp_buffer_set (buffer, "seq", seq++, "ssrc", 0x11, NULL);
1289   buffer = gst_harness_push_and_pull (h, buffer);
1290   fail_unless ((meta = gst_buffer_get_rtp_source_meta (buffer)));
1291   fail_unless (meta->ssrc_valid);
1292   fail_unless_equals_int (meta->ssrc, 0x11);
1293   fail_unless_equals_int (meta->csrc_count, 0);
1294   gst_buffer_unref (buffer);
1295
1296   /* Both SSRC and CSRC should be added to the meta */
1297   buffer = gst_rtp_buffer_new_allocate (0, 0, 2);
1298   rtp_buffer_set (buffer, "seq", seq++, "ssrc", 0x11, "csrc", 0, 0x22,
1299       "csrc", 1, 0x33, NULL);
1300   buffer = gst_harness_push_and_pull (h, buffer);
1301   fail_unless ((meta = gst_buffer_get_rtp_source_meta (buffer)));
1302   fail_unless (meta->ssrc_valid);
1303   fail_unless_equals_int (meta->ssrc, 0x11);
1304   fail_unless_equals_int (meta->csrc_count, 2);
1305   fail_unless_equals_int (meta->csrc[0], 0x22);
1306   fail_unless_equals_int (meta->csrc[1], 0x33);
1307   gst_buffer_unref (buffer);
1308
1309   /* Property disabled should never add meta */
1310   g_object_set (depay, "source-info", FALSE, NULL);
1311   buffer = gst_rtp_buffer_new_allocate (0, 0, 0);
1312   rtp_buffer_set (buffer, "seq", seq++, "ssrc", 0x11, NULL);
1313   buffer = gst_harness_push_and_pull (h, buffer);
1314   fail_if (gst_buffer_get_rtp_source_meta (buffer));
1315   gst_buffer_unref (buffer);
1316
1317   g_object_unref (depay);
1318   gst_harness_teardown (h);
1319 }
1320
1321 GST_END_TEST;
1322
1323
1324 static Suite *
1325 rtp_basepayloading_suite (void)
1326 {
1327   Suite *s = suite_create ("rtp_base_depayloading_test");
1328   TCase *tc_chain = tcase_create ("depayloading tests");
1329
1330   tcase_set_timeout (tc_chain, 60);
1331
1332   suite_add_tcase (s, tc_chain);
1333   tcase_add_test (tc_chain, rtp_base_depayload_buffer_test);
1334
1335   tcase_add_test (tc_chain, rtp_base_depayload_invalid_rtp_packet_test);
1336   tcase_add_test (tc_chain, rtp_base_depayload_with_gap_test);
1337   tcase_add_test (tc_chain, rtp_base_depayload_reversed_test);
1338   tcase_add_test (tc_chain, rtp_base_depayload_ssrc_changed_test);
1339   tcase_add_test (tc_chain, rtp_base_depayload_old_reversed_test);
1340
1341   tcase_add_test (tc_chain, rtp_base_depayload_without_negotiation_test);
1342
1343   tcase_add_test (tc_chain, rtp_base_depayload_packet_lost_test);
1344   tcase_add_test (tc_chain, rtp_base_depayload_seq_discont_test);
1345
1346   tcase_add_test (tc_chain, rtp_base_depayload_repeated_caps_test);
1347   tcase_add_test (tc_chain, rtp_base_depayload_npt_test);
1348   tcase_add_test (tc_chain, rtp_base_depayload_play_scale_test);
1349   tcase_add_test (tc_chain, rtp_base_depayload_play_speed_test);
1350   tcase_add_test (tc_chain, rtp_base_depayload_clock_base_test);
1351
1352   tcase_add_test (tc_chain, rtp_base_depayload_source_info_test);
1353
1354   return s;
1355 }
1356
1357 GST_CHECK_MAIN (rtp_basepayloading)