49db40f7415477e09636db7ebfc6138d4c092423
[platform/upstream/gstreamer.git] / tests / check / elements / rtp-payloading.c
1 /* GStreamer RTP payloader unit tests
2  * Copyright (C) 2008 Nokia Corporation and its subsidiary(-ies)
3  *               contact: <stefan.kost@nokia.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General 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 #include <gst/check/gstcheck.h>
21 #include <gst/check/gstharness.h>
22 #include <gst/audio/audio.h>
23 #include <gst/base/base.h>
24 #include <stdlib.h>
25
26 #define RELEASE_ELEMENT(x) if(x) {gst_object_unref(x); x = NULL;}
27
28 #define LOOP_COUNT 1
29
30 /*
31  * RTP pipeline structure to store the required elements.
32  */
33 typedef struct
34 {
35   GstElement *pipeline;
36   GstElement *appsrc;
37   GstElement *rtppay;
38   GstElement *rtpdepay;
39   GstElement *fakesink;
40   const guint8 *frame_data;
41   int frame_data_size;
42   int frame_count;
43   GstEvent *custom_event;
44 } rtp_pipeline;
45
46 /*
47  * Number of bytes received in the chain list function when using buffer lists
48  */
49 static guint chain_list_bytes_received;
50
51 /*
52  * Chain list function for testing buffer lists
53  */
54 static GstFlowReturn
55 rtp_pipeline_chain_list (GstPad * pad, GstObject * parent, GstBufferList * list)
56 {
57   guint i, len;
58
59   fail_if (!list);
60   /*
61    * Count the size of the payload in the buffer list.
62    */
63   len = gst_buffer_list_length (list);
64   GST_LOG ("list length %u", len);
65
66   /* Loop through all buffers */
67   for (i = 0; i < len; i++) {
68     GstBuffer *paybuf;
69     GstMemory *mem;
70     gint size;
71
72     paybuf = gst_buffer_list_get (list, i);
73     /* only count real data which is expected in last memory block */
74     GST_LOG ("n_memory %d", gst_buffer_n_memory (paybuf));
75     fail_unless (gst_buffer_n_memory (paybuf) > 1);
76     mem = gst_buffer_get_memory_range (paybuf, gst_buffer_n_memory (paybuf) - 1,
77         1);
78     size = gst_memory_get_sizes (mem, NULL, NULL);
79     gst_memory_unref (mem);
80     chain_list_bytes_received += size;
81     GST_LOG ("size %d, total %u", size, chain_list_bytes_received);
82   }
83   gst_buffer_list_unref (list);
84
85   return GST_FLOW_OK;
86 }
87
88 static GstFlowReturn
89 rtp_pipeline_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
90 {
91   GstBufferList *list;
92
93   list = gst_buffer_list_new_sized (1);
94   gst_buffer_list_add (list, buf);
95   return rtp_pipeline_chain_list (pad, parent, list);
96 }
97
98 /*
99  * RTP bus callback.
100  */
101 static gboolean
102 rtp_bus_callback (GstBus * bus, GstMessage * message, gpointer data)
103 {
104   GMainLoop *mainloop = (GMainLoop *) data;
105
106   switch (GST_MESSAGE_TYPE (message)) {
107     case GST_MESSAGE_ERROR:
108     {
109       GError *err;
110
111       gchar *debug;
112
113       gchar *element_name;
114
115       element_name = (message->src) ? gst_object_get_name (message->src) : NULL;
116       gst_message_parse_error (message, &err, &debug);
117       g_print ("\nError from element %s: %s\n%s\n\n",
118           GST_STR_NULL (element_name), err->message, (debug) ? debug : "");
119       g_error_free (err);
120       g_free (debug);
121       g_free (element_name);
122
123       fail_if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR);
124
125       g_main_loop_quit (mainloop);
126     }
127       break;
128
129     case GST_MESSAGE_EOS:
130     {
131       g_main_loop_quit (mainloop);
132     }
133       break;
134       break;
135
136     default:
137     {
138     }
139       break;
140   }
141
142   return TRUE;
143 }
144
145 /*
146  * Creates a RTP pipeline for one test.
147  * @param frame_data Pointer to the frame data which is used to pass through pay/depayloaders.
148  * @param frame_data_size Frame data size in bytes.
149  * @param frame_count Frame count.
150  * @param filtercaps Caps filters.
151  * @param pay Payloader name.
152  * @param depay Depayloader name.
153  * @return
154  * Returns pointer to the RTP pipeline.
155  * The user must free the RTP pipeline when it's not used anymore.
156  */
157 static rtp_pipeline *
158 rtp_pipeline_create (const guint8 * frame_data, int frame_data_size,
159     int frame_count, const char *filtercaps, const char *pay, const char *depay)
160 {
161   gchar *pipeline_name;
162   rtp_pipeline *p;
163   GstCaps *caps;
164
165   /* Check parameters. */
166   if (!frame_data || !pay || !depay) {
167     return NULL;
168   }
169
170   /* Allocate memory for the RTP pipeline. */
171   p = (rtp_pipeline *) malloc (sizeof (rtp_pipeline));
172
173   p->frame_data = frame_data;
174   p->frame_data_size = frame_data_size;
175   p->frame_count = frame_count;
176   p->custom_event = NULL;
177
178   /* Create elements. */
179   pipeline_name = g_strdup_printf ("%s-%s-pipeline", pay, depay);
180   p->pipeline = gst_pipeline_new (pipeline_name);
181   g_free (pipeline_name);
182   p->appsrc = gst_element_factory_make ("appsrc", NULL);
183   p->rtppay =
184       gst_parse_bin_from_description_full (pay, TRUE, NULL,
185       GST_PARSE_FLAG_NO_SINGLE_ELEMENT_BINS, NULL);
186   p->rtpdepay =
187       gst_parse_bin_from_description_full (depay, TRUE, NULL,
188       GST_PARSE_FLAG_NO_SINGLE_ELEMENT_BINS, NULL);
189   p->fakesink = gst_element_factory_make ("fakesink", NULL);
190
191   /* One or more elements are not created successfully or failed to create p? */
192   if (!p->pipeline || !p->appsrc || !p->rtppay || !p->rtpdepay || !p->fakesink) {
193     /* Release created elements. */
194     RELEASE_ELEMENT (p->pipeline);
195     RELEASE_ELEMENT (p->appsrc);
196     RELEASE_ELEMENT (p->rtppay);
197     RELEASE_ELEMENT (p->rtpdepay);
198     RELEASE_ELEMENT (p->fakesink);
199
200     /* Release allocated memory. */
201     free (p);
202
203     return NULL;
204   }
205
206   /* Set src properties. */
207   caps = gst_caps_from_string (filtercaps);
208   g_object_set (p->appsrc, "do-timestamp", TRUE, "caps", caps,
209       "format", GST_FORMAT_TIME, NULL);
210   gst_caps_unref (caps);
211
212   /* Add elements to the pipeline. */
213   gst_bin_add (GST_BIN (p->pipeline), p->appsrc);
214   gst_bin_add (GST_BIN (p->pipeline), p->rtppay);
215   gst_bin_add (GST_BIN (p->pipeline), p->rtpdepay);
216   gst_bin_add (GST_BIN (p->pipeline), p->fakesink);
217
218   /* Link elements. */
219   gst_element_link (p->appsrc, p->rtppay);
220   gst_element_link (p->rtppay, p->rtpdepay);
221   gst_element_link (p->rtpdepay, p->fakesink);
222
223   return p;
224 }
225
226 /*
227  * Destroys the RTP pipeline.
228  * @param p Pointer to the RTP pipeline.
229  */
230 static void
231 rtp_pipeline_destroy (rtp_pipeline * p)
232 {
233   /* Check parameters. */
234   if (p == NULL) {
235     return;
236   }
237
238   /* Release pipeline. */
239   RELEASE_ELEMENT (p->pipeline);
240
241   /* Release allocated memory. */
242   free (p);
243 }
244
245 static GstPadProbeReturn
246 pay_event_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
247 {
248   rtp_pipeline *p = (rtp_pipeline *) user_data;
249   GstEvent *event = GST_PAD_PROBE_INFO_DATA (info);
250
251   if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM) {
252     const GstStructure *s0 = gst_event_get_structure (p->custom_event);
253     const GstStructure *s1 = gst_event_get_structure (event);
254     if (gst_structure_is_equal (s0, s1)) {
255       return GST_PAD_PROBE_DROP;
256     }
257   }
258
259   return GST_PAD_PROBE_OK;
260 }
261
262 static GstPadProbeReturn
263 depay_event_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
264 {
265   rtp_pipeline *p = (rtp_pipeline *) user_data;
266   GstEvent *event = GST_PAD_PROBE_INFO_DATA (info);
267
268   if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM) {
269     const GstStructure *s0 = gst_event_get_structure (p->custom_event);
270     const GstStructure *s1 = gst_event_get_structure (event);
271     if (gst_structure_is_equal (s0, s1)) {
272       gst_event_unref (p->custom_event);
273       p->custom_event = NULL;
274     }
275   }
276
277   return GST_PAD_PROBE_OK;
278 }
279
280 /*
281  * Runs the RTP pipeline.
282  * @param p Pointer to the RTP pipeline.
283  */
284 static void
285 rtp_pipeline_run (rtp_pipeline * p)
286 {
287   GstFlowReturn flow_ret;
288   GMainLoop *mainloop = NULL;
289   GstBus *bus;
290   gint i, j;
291
292   /* Check parameters. */
293   if (p == NULL) {
294     return;
295   }
296
297   /* Create mainloop. */
298   mainloop = g_main_loop_new (NULL, FALSE);
299   if (!mainloop) {
300     return;
301   }
302
303   /* Add bus callback. */
304   bus = gst_pipeline_get_bus (GST_PIPELINE (p->pipeline));
305
306   gst_bus_add_watch (bus, rtp_bus_callback, (gpointer) mainloop);
307
308   /* Set pipeline to PLAYING. */
309   gst_element_set_state (p->pipeline, GST_STATE_PLAYING);
310
311   /* Push custom event into the pipeline */
312   if (p->custom_event) {
313     GstPad *srcpad;
314
315     /* Install a probe to drop the event after it being serialized */
316     srcpad = gst_element_get_static_pad (p->rtppay, "src");
317     gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
318         pay_event_probe_cb, p, NULL);
319     gst_object_unref (srcpad);
320
321     /* Install a probe to trace the deserialized event after depayloading */
322     srcpad = gst_element_get_static_pad (p->rtpdepay, "src");
323     gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
324         depay_event_probe_cb, p, NULL);
325     gst_object_unref (srcpad);
326     /* Send the event */
327     gst_element_send_event (p->appsrc, gst_event_ref (p->custom_event));
328   }
329
330   /* Push data into the pipeline */
331   for (i = 0; i < LOOP_COUNT; i++) {
332     const guint8 *data = p->frame_data;
333
334     for (j = 0; j < p->frame_count; j++) {
335       GstBuffer *buf;
336
337       buf =
338           gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
339           (guint8 *) data, p->frame_data_size, 0, p->frame_data_size, NULL,
340           NULL);
341
342       g_signal_emit_by_name (p->appsrc, "push-buffer", buf, &flow_ret);
343       fail_unless_equals_int (flow_ret, GST_FLOW_OK);
344       data += p->frame_data_size;
345
346       gst_buffer_unref (buf);
347     }
348   }
349
350   g_signal_emit_by_name (p->appsrc, "end-of-stream", &flow_ret);
351
352   /* Run mainloop. */
353   g_main_loop_run (mainloop);
354
355   /* Set pipeline to NULL. */
356   gst_element_set_state (p->pipeline, GST_STATE_NULL);
357
358   /* Release mainloop. */
359   g_main_loop_unref (mainloop);
360
361   gst_bus_remove_watch (bus);
362   gst_object_unref (bus);
363
364   fail_if (p->custom_event);
365 }
366
367 /*
368  * Enables buffer lists and adds a chain_list_function to the depayloader.
369  * @param p Pointer to the RTP pipeline.
370  */
371 static void
372 rtp_pipeline_enable_lists (rtp_pipeline * p)
373 {
374   GstPad *pad;
375
376   /* Add chain list function for the buffer list tests */
377   pad = gst_element_get_static_pad (p->rtpdepay, "sink");
378   gst_pad_set_chain_list_function (pad,
379       GST_DEBUG_FUNCPTR (rtp_pipeline_chain_list));
380   /* .. to satisfy this silly test code in case someone dares push a buffer */
381   gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (rtp_pipeline_chain));
382   gst_object_unref (pad);
383 }
384
385 /*
386  * Creates the RTP pipeline and runs the test using the pipeline.
387  * @param frame_data Pointer to the frame data which is used to pass through pay/depayloaders.
388  * @param frame_data_size Frame data size in bytes.
389  * @param frame_count Frame count.
390  * @param filtercaps Caps filters.
391  * @param pay Payloader name.
392  * @param depay Depayloader name.
393  * @bytes_sent bytes that will be sent, used when testing buffer lists
394  * @mtu_size set mtu size when testing lists
395  * @use_lists enable buffer lists
396  */
397 static void
398 rtp_pipeline_test (const guint8 * frame_data, int frame_data_size,
399     int frame_count, const char *filtercaps, const char *pay, const char *depay,
400     guint bytes_sent, guint mtu_size, gboolean use_lists)
401 {
402   /* Create RTP pipeline. */
403   rtp_pipeline *p =
404       rtp_pipeline_create (frame_data, frame_data_size, frame_count, filtercaps,
405       pay, depay);
406
407   if (p == NULL) {
408     return;
409   }
410
411   /* set mtu size if needed */
412   if (mtu_size > 0) {
413     g_object_set (p->rtppay, "mtu", mtu_size, NULL);
414   }
415
416   if (use_lists) {
417     rtp_pipeline_enable_lists (p);
418     chain_list_bytes_received = 0;
419   }
420
421   /* Run RTP pipeline. */
422   rtp_pipeline_run (p);
423
424   /* Destroy RTP pipeline. */
425   rtp_pipeline_destroy (p);
426
427   if (use_lists) {
428     /* 'next NAL' indicator is 4 bytes */
429     fail_unless_equals_int (chain_list_bytes_received, bytes_sent * LOOP_COUNT);
430   }
431 }
432
433 static const guint8 rtp_ilbc_frame_data[] =
434     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
435   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
436 };
437
438 static int rtp_ilbc_frame_data_size = 20;
439
440 static int rtp_ilbc_frame_count = 1;
441
442 GST_START_TEST (rtp_ilbc)
443 {
444   rtp_pipeline_test (rtp_ilbc_frame_data, rtp_ilbc_frame_data_size,
445       rtp_ilbc_frame_count, "audio/x-iLBC,mode=20", "rtpilbcpay",
446       "rtpilbcdepay", 0, 0, FALSE);
447 }
448
449 GST_END_TEST;
450 static const guint8 rtp_gsm_frame_data[] =
451     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
453 };
454
455 static int rtp_gsm_frame_data_size = 20;
456
457 static int rtp_gsm_frame_count = 1;
458
459 GST_START_TEST (rtp_gsm)
460 {
461   rtp_pipeline_test (rtp_gsm_frame_data, rtp_gsm_frame_data_size,
462       rtp_gsm_frame_count, "audio/x-gsm,rate=8000,channels=1", "rtpgsmpay",
463       "rtpgsmdepay", 0, 0, FALSE);
464 }
465
466 GST_END_TEST;
467 static const guint8 rtp_amr_frame_data[] =
468     { 0x3c, 0x24, 0x03, 0xb3, 0x48, 0x10, 0x68, 0x46, 0x6c, 0xec, 0x03,
469   0x7a, 0x37, 0x16, 0x41, 0x41, 0xc0, 0x00, 0x0d, 0xcd, 0x12, 0xed,
470   0xad, 0x80, 0x00, 0x00, 0x11, 0x31, 0x00, 0x00, 0x0d, 0xa0
471 };
472
473 static int rtp_amr_frame_data_size = 32;
474
475 static int rtp_amr_frame_count = 1;
476
477 GST_START_TEST (rtp_amr)
478 {
479   rtp_pipeline_test (rtp_amr_frame_data, rtp_amr_frame_data_size,
480       rtp_amr_frame_count, "audio/AMR,channels=1,rate=8000", "rtpamrpay",
481       "rtpamrdepay", 0, 0, FALSE);
482 }
483
484 GST_END_TEST;
485 static const guint8 rtp_pcma_frame_data[] =
486     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
487   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
488 };
489
490 static int rtp_pcma_frame_data_size = 20;
491
492 static int rtp_pcma_frame_count = 1;
493
494 GST_START_TEST (rtp_pcma)
495 {
496   rtp_pipeline_test (rtp_pcma_frame_data, rtp_pcma_frame_data_size,
497       rtp_pcma_frame_count, "audio/x-alaw,channels=1,rate=8000", "rtppcmapay",
498       "rtppcmadepay", 0, 0, FALSE);
499 }
500
501 GST_END_TEST;
502 static const guint8 rtp_pcmu_frame_data[] =
503     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
504   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
505 };
506
507 static int rtp_pcmu_frame_data_size = 20;
508
509 static int rtp_pcmu_frame_count = 1;
510
511 GST_START_TEST (rtp_pcmu)
512 {
513   rtp_pipeline_test (rtp_pcmu_frame_data, rtp_pcmu_frame_data_size,
514       rtp_pcmu_frame_count, "audio/x-mulaw,channels=1,rate=8000", "rtppcmupay",
515       "rtppcmudepay", 0, 0, FALSE);
516 }
517
518 GST_END_TEST;
519 static const guint8 rtp_mpa_frame_data[] =
520     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
521   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
522 };
523
524 static int rtp_mpa_frame_data_size = 20;
525
526 static int rtp_mpa_frame_count = 1;
527
528 GST_START_TEST (rtp_mpa)
529 {
530   rtp_pipeline_test (rtp_mpa_frame_data, rtp_mpa_frame_data_size,
531       rtp_mpa_frame_count, "audio/mpeg,mpegversion=1", "rtpmpapay",
532       "rtpmpadepay", 0, 0, FALSE);
533 }
534
535 GST_END_TEST;
536
537 static const guint8 rtp_h261_frame_data[] = {
538   0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x11, 0x00, 0x00, 0x4c, 0x40, 0x00,
539   0x15, 0x10,
540 };
541
542 static int rtp_h261_frame_data_size = 14;
543 static int rtp_h261_frame_count = 1;
544
545 GST_START_TEST (rtp_h261)
546 {
547   rtp_pipeline_test (rtp_h261_frame_data, rtp_h261_frame_data_size,
548       rtp_h261_frame_count, "video/x-h261", "rtph261pay", "rtph261depay",
549       0, 0, FALSE);
550 }
551
552 GST_END_TEST;
553
554 static const guint8 rtp_h263_frame_data[] =
555     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
557 };
558
559 static int rtp_h263_frame_data_size = 20;
560
561 static int rtp_h263_frame_count = 1;
562
563 GST_START_TEST (rtp_h263)
564 {
565   rtp_pipeline_test (rtp_h263_frame_data, rtp_h263_frame_data_size,
566       rtp_h263_frame_count,
567       "video/x-h263,variant=(string)itu,h263version=h263",
568       "rtph263pay", "rtph263depay", 0, 0, FALSE);
569   rtp_pipeline_test (rtp_h263_frame_data, rtp_h263_frame_data_size,
570       rtp_h263_frame_count,
571       "video/x-h263,variant=(string)itu,h263version=h263,width=10,height=20",
572       "rtph263pay", "rtph263depay", 0, 0, FALSE);
573 }
574
575 GST_END_TEST;
576 static const guint8 rtp_h263p_frame_data[] =
577     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
579 };
580
581 static int rtp_h263p_frame_data_size = 20;
582
583 static int rtp_h263p_frame_count = 1;
584
585 GST_START_TEST (rtp_h263p)
586 {
587   rtp_pipeline_test (rtp_h263p_frame_data, rtp_h263p_frame_data_size,
588       rtp_h263p_frame_count, "video/x-h263,variant=(string)itu,"
589       "h263version=(string)h263", "rtph263ppay", "rtph263pdepay", 0, 0, FALSE);
590
591   /* payloader should accept any input that matches the template caps
592    * if there's just a udpsink or fakesink downstream */
593   rtp_pipeline_test (rtp_h263p_frame_data, rtp_h263p_frame_data_size,
594       rtp_h263p_frame_count, "video/x-h263,variant=(string)itu,"
595       "h263version=(string)h263", "rtph263ppay", "identity", 0, 0, FALSE);
596
597   /* default output of avenc_h263p */
598   rtp_pipeline_test (rtp_h263p_frame_data, rtp_h263p_frame_data_size,
599       rtp_h263p_frame_count, "video/x-h263,variant=(string)itu,"
600       "h263version=(string)h263p, annex-f=(boolean)true, "
601       "annex-j=(boolean)true, annex-i=(boolean)true, annex-t=(boolean)true",
602       "rtph263ppay", "identity", 0, 0, FALSE);
603
604   /* pay ! depay should also work with any input */
605   rtp_pipeline_test (rtp_h263p_frame_data, rtp_h263p_frame_data_size,
606       rtp_h263p_frame_count, "video/x-h263,variant=(string)itu,"
607       "h263version=(string)h263p, annex-f=(boolean)true, "
608       "annex-j=(boolean)true, annex-i=(boolean)true, annex-t=(boolean)true",
609       "rtph263ppay", "rtph263pdepay", 0, 0, FALSE);
610 }
611
612 GST_END_TEST;
613 static const guint8 rtp_h264_frame_data[] =
614     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
615   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
616 };
617
618 static int rtp_h264_frame_data_size = 20;
619
620 static int rtp_h264_frame_count = 1;
621
622 GST_START_TEST (rtp_h264)
623 {
624   /* FIXME 0.11: fully specify h264 caps (and make payloader check) */
625   rtp_pipeline_test (rtp_h264_frame_data, rtp_h264_frame_data_size,
626       rtp_h264_frame_count,
627       "video/x-h264,stream-format=(string)byte-stream,alignment=(string)nal",
628       "rtph264pay", "rtph264depay", 0, 0, FALSE);
629
630   /* config-interval property used to be of uint type, was changed to int,
631    * make sure old GValue stuff still works */
632   {
633     GValue val = G_VALUE_INIT;
634     GstElement *rtph264pay;
635     GParamSpec *pspec;
636
637
638     rtph264pay = gst_element_factory_make ("rtph264pay", NULL);
639     pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (rtph264pay),
640         "config-interval");
641     fail_unless (pspec->value_type == G_TYPE_INT);
642     g_value_init (&val, G_TYPE_UINT);
643     g_value_set_uint (&val, 10);
644     g_object_set_property (G_OBJECT (rtph264pay), "config-interval", &val);
645     g_value_set_uint (&val, 0);
646     g_object_get_property (G_OBJECT (rtph264pay), "config-interval", &val);
647     fail_unless_equals_int (10, g_value_get_uint (&val));
648     g_object_set (G_OBJECT (rtph264pay), "config-interval", -1, NULL);
649     g_object_get_property (G_OBJECT (rtph264pay), "config-interval", &val);
650     fail_unless (g_value_get_uint (&val) == G_MAXUINT);
651     g_value_unset (&val);
652     gst_object_unref (rtph264pay);
653   }
654 }
655
656 GST_END_TEST;
657
658 /* H264 data generated with:
659  * videotestsrc pattern=black ! video/x-raw,width=16,height=16 ! openh264enc */
660 static const guint8 h264_16x16_black_bs[] = {
661   0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xd0, 0x0b,
662   0x8c, 0x8d, 0x4e, 0x40, 0x3c, 0x22, 0x11, 0xa8,
663   0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x3c, 0x80,
664   0x00, 0x00, 0x00, 0x01, 0x65, 0xb8, 0x00, 0x04,
665   0x00, 0x00, 0x09, 0xe4, 0xc5, 0x00, 0x01, 0x19,
666   0xfc
667 };
668
669 static GstSample *
670 rtp_h264depay_run (const gchar * stream_format)
671 {
672   GstHarness *h;
673   GstSample *sample;
674   GstBuffer *buf;
675   GstEvent *e;
676   GstCaps *out_caps;
677   GstCaps *in_caps;
678   gboolean seen_caps = FALSE;
679   gsize size;
680
681   h = gst_harness_new_parse ("rtph264pay ! rtph264depay");
682
683   /* Our input data is in byte-stream format (not that it matters) */
684   in_caps = gst_caps_new_simple ("video/x-h264",
685       "stream-format", G_TYPE_STRING, "byte-stream",
686       "alignment", G_TYPE_STRING, "au",
687       "profile", G_TYPE_STRING, "baseline",
688       "width", G_TYPE_INT, 16,
689       "height", G_TYPE_INT, 16, "framerate", GST_TYPE_FRACTION, 30, 1, NULL);
690
691   /* Force rtph264depay to output format as requested */
692   out_caps = gst_caps_new_simple ("video/x-h264",
693       "stream-format", G_TYPE_STRING, stream_format,
694       "alignment", G_TYPE_STRING, "au", NULL);
695
696   gst_harness_set_caps (h, in_caps, out_caps);
697   in_caps = NULL;
698   out_caps = NULL;
699
700   gst_harness_play (h);
701
702   size = sizeof (h264_16x16_black_bs);
703   buf = gst_buffer_new_wrapped (g_memdup (h264_16x16_black_bs, size), size);
704   fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
705   fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
706
707   while ((e = gst_harness_try_pull_event (h))) {
708     if (GST_EVENT_TYPE (e) == GST_EVENT_CAPS) {
709       GstCaps *caps = NULL;
710
711       gst_event_parse_caps (e, &caps);
712       gst_caps_replace (&out_caps, caps);
713       seen_caps = TRUE;
714     }
715     gst_event_unref (e);
716   }
717   fail_unless (seen_caps);
718
719   buf = gst_harness_pull (h);
720   sample = gst_sample_new (buf, out_caps, NULL, NULL);
721   gst_buffer_unref (buf);
722   gst_caps_replace (&out_caps, NULL);
723
724   gst_harness_teardown (h);
725   return sample;
726 }
727
728 GST_START_TEST (rtp_h264depay_avc)
729 {
730   const GValue *val;
731   GstStructure *st;
732   GstMapInfo map = GST_MAP_INFO_INIT;
733   GstBuffer *buf;
734   GstSample *s;
735   GstCaps *caps;
736
737   s = rtp_h264depay_run ("avc");
738
739   /* must have codec_data in output caps */
740   caps = gst_sample_get_caps (s);
741   st = gst_caps_get_structure (caps, 0);
742   GST_LOG ("caps: %" GST_PTR_FORMAT, caps);
743   fail_unless (gst_structure_has_field (st, "stream-format"));
744   fail_unless (gst_structure_has_field (st, "alignment"));
745   fail_unless (gst_structure_has_field (st, "level"));
746   fail_unless (gst_structure_has_field (st, "profile"));
747   val = gst_structure_get_value (st, "codec_data");
748   fail_unless (val != NULL);
749   fail_unless (GST_VALUE_HOLDS_BUFFER (val));
750   /* check codec_data, shouldn't contain trailing zeros */
751   buf = gst_value_get_buffer (val);
752   fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
753   {
754     guint num_sps, num_pps, len;
755     guint8 *data;
756
757     GST_MEMDUMP ("H.264 codec_data", map.data, map.size);
758     fail_unless_equals_int (map.data[0], 1);
759     num_sps = map.data[5] & 0x1f;
760     data = map.data + 6;
761     fail_unless_equals_int (num_sps, 1);
762     len = GST_READ_UINT16_BE (data);
763     data += 2;
764     /* make sure there are no trailing zeros in the SPS */
765     fail_unless (data[len - 1] != 0);
766     data += len;
767     num_pps = *data++;
768     fail_unless_equals_int (num_pps, 1);
769     len = GST_READ_UINT16_BE (data);
770     data += 2;
771     /* make sure there are no trailing zeros in the PPS */
772     fail_unless (data[len - 1] != 0);
773   }
774   gst_buffer_unmap (buf, &map);
775
776   buf = gst_sample_get_buffer (s);
777   fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
778   GST_MEMDUMP ("H.264 AVC frame", map.data, map.size);
779   fail_unless (map.size >= 4 + 13);
780   /* Want IDR slice as very first thing.
781    * We assume nal size markers are 4 bytes here. */
782   fail_unless_equals_int (map.data[4] & 0x1f, 5);
783   gst_buffer_unmap (buf, &map);
784
785   gst_sample_unref (s);
786 }
787
788 GST_END_TEST;
789
790 GST_START_TEST (rtp_h264depay_bytestream)
791 {
792   GstByteReader br;
793   GstStructure *st;
794   GstMapInfo map = GST_MAP_INFO_INIT;
795   GstBuffer *buf;
796   GstSample *s;
797   GstCaps *caps;
798   guint32 dw = 0;
799   guint8 b = 0;
800   guint off, left;
801
802   s = rtp_h264depay_run ("byte-stream");
803
804   /* must not have codec_data in output caps */
805   caps = gst_sample_get_caps (s);
806   st = gst_caps_get_structure (caps, 0);
807   GST_LOG ("caps: %" GST_PTR_FORMAT, caps);
808   fail_if (gst_structure_has_field (st, "codec_data"));
809
810   buf = gst_sample_get_buffer (s);
811   fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
812   GST_MEMDUMP ("H.264 byte-stream frame", map.data, map.size);
813   fail_unless (map.size > 40);
814   gst_byte_reader_init (&br, map.data, map.size);
815   /* We assume nal sync markers are 4 bytes... */
816   fail_unless (gst_byte_reader_get_uint32_be (&br, &dw));
817   fail_unless_equals_int (dw, 0x00000001);
818   /* Want SPS as very first thing */
819   fail_unless (gst_byte_reader_get_uint8 (&br, &b));
820   fail_unless_equals_int (b & 0x1f, 7);
821   /* Then, we want the PPS */
822   left = gst_byte_reader_get_remaining (&br);
823   off = gst_byte_reader_masked_scan_uint32 (&br, 0xffffffff, 1, 0, left);
824   fail_if (off == (guint) - 1);
825   gst_byte_reader_skip (&br, off + 4);
826   fail_unless (gst_byte_reader_get_uint8 (&br, &b));
827   fail_unless_equals_int (b & 0x1f, 8);
828   /* FIXME: looks like we get two sets of SPS/PPS ?! */
829   left = gst_byte_reader_get_remaining (&br);
830   off = gst_byte_reader_masked_scan_uint32 (&br, 0xffffffff, 1, 0, left);
831   fail_if (off == (guint) - 1);
832   gst_byte_reader_skip (&br, off + 4);
833   left = gst_byte_reader_get_remaining (&br);
834   off = gst_byte_reader_masked_scan_uint32 (&br, 0xffffffff, 1, 0, left);
835   fail_if (off == (guint) - 1);
836   gst_byte_reader_skip (&br, off + 4);
837   /* Finally, we want an IDR slice */
838   left = gst_byte_reader_get_remaining (&br);
839   off = gst_byte_reader_masked_scan_uint32 (&br, 0xffffffff, 1, 0, left);
840   fail_if (off == (guint) - 1);
841   gst_byte_reader_skip (&br, off + 4);
842   fail_unless (gst_byte_reader_get_uint8 (&br, &b));
843   fail_unless_equals_int (b & 0x1f, 5);
844   gst_buffer_unmap (buf, &map);
845
846   gst_sample_unref (s);
847 }
848
849 GST_END_TEST;
850
851 static const guint8 rtp_h264_list_lt_mtu_frame_data[] =
852     /* not packetized, next NAL starts with 0001 */
853 { 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
854   0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
855   0xad, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x10
856 };
857
858 static int rtp_h264_list_lt_mtu_frame_data_size = 16;
859
860 static int rtp_h264_list_lt_mtu_frame_count = 2;
861
862 /* NAL = 4 bytes */
863 /* also 2 bytes FU-A header each time */
864 static int rtp_h264_list_lt_mtu_bytes_sent = (16 - 4);
865
866 static int rtp_h264_list_lt_mtu_mtu_size = 1024;
867
868 GST_START_TEST (rtp_h264_list_lt_mtu)
869 {
870   /* FIXME 0.11: fully specify h264 caps (and make payloader check) */
871   rtp_pipeline_test (rtp_h264_list_lt_mtu_frame_data,
872       rtp_h264_list_lt_mtu_frame_data_size, rtp_h264_list_lt_mtu_frame_count,
873       "video/x-h264,stream-format=(string)byte-stream,alignment=(string)nal",
874       "rtph264pay aggregate-mode=zero-latency", "rtph264depay",
875       rtp_h264_list_lt_mtu_bytes_sent, rtp_h264_list_lt_mtu_mtu_size, TRUE);
876 }
877
878 GST_END_TEST;
879 static const guint8 rtp_h264_list_lt_mtu_frame_data_avc[] =
880     /* packetized data */
881 { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
882   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
883   0xad, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0d, 0x00
884 };
885
886 /* Only the last NAL of each packet is computed by the strange algorithm in
887  * rtp_pipeline_chain_list()
888  */
889 static int rtp_h264_list_lt_mtu_bytes_sent_avc = 7 + 3;
890
891 //static int rtp_h264_list_lt_mtu_mtu_size = 1024;
892
893 GST_START_TEST (rtp_h264_list_lt_mtu_avc)
894 {
895   /* FIXME 0.11: fully specify h264 caps (and make payloader check) */
896   rtp_pipeline_test (rtp_h264_list_lt_mtu_frame_data_avc,
897       rtp_h264_list_lt_mtu_frame_data_size, rtp_h264_list_lt_mtu_frame_count,
898       "video/x-h264,stream-format=(string)avc,alignment=(string)au,"
899       "codec_data=(buffer)01640014ffe1001867640014acd94141fb0110000003001773594000f142996001000568ebecb22c",
900       "rtph264pay aggregate-mode=zero-latency", "rtph264depay",
901       rtp_h264_list_lt_mtu_bytes_sent_avc, rtp_h264_list_lt_mtu_mtu_size, TRUE);
902 }
903
904 GST_END_TEST;
905 static const guint8 rtp_h264_list_gt_mtu_frame_data[] =
906     /* not packetized, next NAL starts with 0001 */
907 { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
908   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
909   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
910   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
911   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
912   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
913 };
914
915 static int rtp_h264_list_gt_mtu_frame_data_size = 64;
916
917 static int rtp_h264_list_gt_mtu_frame_count = 1;
918
919 /* NAL = 4 bytes. When data does not fit into 1 mtu, 1 byte will be skipped */
920 static int rtp_h264_list_gt_mtu_bytes_sent = 1 * (64 - 4) - 1;
921
922 static int rtp_h264_list_gt_mtu_mty_size = 28;
923
924 GST_START_TEST (rtp_h264_list_gt_mtu)
925 {
926   /* FIXME 0.11: fully specify h264 caps (and make payloader check) */
927   rtp_pipeline_test (rtp_h264_list_gt_mtu_frame_data,
928       rtp_h264_list_gt_mtu_frame_data_size, rtp_h264_list_gt_mtu_frame_count,
929       "video/x-h264,stream-format=(string)byte-stream,alignment=(string)nal",
930       "rtph264pay", "rtph264depay",
931       rtp_h264_list_gt_mtu_bytes_sent, rtp_h264_list_gt_mtu_mty_size, TRUE);
932 }
933
934 GST_END_TEST;
935 static const guint8 rtp_h264_list_gt_mtu_frame_data_avc[] =
936     /* packetized data */
937 { 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
938   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
939   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
940   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
941   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
942   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
943 };
944
945 /* NAL = 4 bytes. When data does not fit into 1 mtu, 1 byte will be skipped */
946 static int rtp_h264_list_gt_mtu_bytes_sent_avc = 1 * (64 - 2 * 4 - 2 * 1);
947
948 GST_START_TEST (rtp_h264_list_gt_mtu_avc)
949 {
950   /* FIXME 0.11: fully specify h264 caps (and make payloader check) */
951   rtp_pipeline_test (rtp_h264_list_gt_mtu_frame_data_avc,
952       rtp_h264_list_gt_mtu_frame_data_size, rtp_h264_list_gt_mtu_frame_count,
953       "video/x-h264,stream-format=(string)avc,alignment=(string)au,"
954       "codec_data=(buffer)01640014ffe1001867640014acd94141fb0110000003001773594000f142996001000568ebecb22c",
955       "rtph264pay", "rtph264depay",
956       rtp_h264_list_gt_mtu_bytes_sent_avc, rtp_h264_list_gt_mtu_mty_size, TRUE);
957 }
958
959 GST_END_TEST;
960
961 static const guint8 rtp_h265_frame_data[] = {
962   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
963   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
964 };
965
966 static int rtp_h265_frame_data_size = 20;
967
968 static int rtp_h265_frame_count = 1;
969
970 GST_START_TEST (rtp_h265)
971 {
972   rtp_pipeline_test (rtp_h265_frame_data, rtp_h265_frame_data_size,
973       rtp_h265_frame_count,
974       "video/x-h265,stream-format=(string)byte-stream,alignment=(string)nal",
975       "rtph265pay", "rtph265depay", 0, 0, FALSE);
976
977   /* config-interval property used to be of uint type, was changed to int,
978    * make sure old GValue stuff still works */
979   {
980     GValue val = G_VALUE_INIT;
981     GstElement *rtph265pay;
982     GParamSpec *pspec;
983
984
985     rtph265pay = gst_element_factory_make ("rtph265pay", NULL);
986     pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (rtph265pay),
987         "config-interval");
988     fail_unless (pspec->value_type == G_TYPE_INT);
989     g_value_init (&val, G_TYPE_UINT);
990     g_value_set_uint (&val, 10);
991     g_object_set_property (G_OBJECT (rtph265pay), "config-interval", &val);
992     g_value_set_uint (&val, 0);
993     g_object_get_property (G_OBJECT (rtph265pay), "config-interval", &val);
994     fail_unless_equals_int (10, g_value_get_uint (&val));
995     g_object_set (G_OBJECT (rtph265pay), "config-interval", -1, NULL);
996     g_object_get_property (G_OBJECT (rtph265pay), "config-interval", &val);
997     fail_unless (g_value_get_uint (&val) == G_MAXUINT);
998     g_value_unset (&val);
999     gst_object_unref (rtph265pay);
1000   }
1001 }
1002
1003 GST_END_TEST;
1004 static const guint8 rtp_h265_list_lt_mtu_frame_data[] = {
1005   /* not packetized, next NALU starts with 0x00000001 */
1006   0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1007   0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
1008   0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1009   0x00, 0x00, 0x00, 0x00, 0x00, 0x10
1010 };
1011
1012 static int rtp_h265_list_lt_mtu_frame_data_size = 16;
1013
1014 static int rtp_h265_list_lt_mtu_frame_count = 2;
1015
1016 /* 3 bytes start code prefixed with one zero byte, NALU header is in payload */
1017 static int rtp_h265_list_lt_mtu_bytes_sent = 2 * (16 - 3 - 1);
1018
1019 static int rtp_h265_list_lt_mtu_mtu_size = 1024;
1020
1021 GST_START_TEST (rtp_h265_list_lt_mtu)
1022 {
1023   rtp_pipeline_test (rtp_h265_list_lt_mtu_frame_data,
1024       rtp_h265_list_lt_mtu_frame_data_size, rtp_h265_list_lt_mtu_frame_count,
1025       "video/x-h265,stream-format=(string)byte-stream,alignment=(string)nal",
1026       "rtph265pay", "rtph265depay", rtp_h265_list_lt_mtu_bytes_sent,
1027       rtp_h265_list_lt_mtu_mtu_size, TRUE);
1028 }
1029
1030 GST_END_TEST;
1031 static const guint8 rtp_h265_list_lt_mtu_frame_data_hvc1[] = {
1032   /* packetized data */
1033   0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1034   0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1035   0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1036   0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
1037 };
1038
1039 /* length size is 3 bytes */
1040 static int rtp_h265_list_lt_mtu_bytes_sent_hvc1 = 4 + 9;
1041
1042
1043 GST_START_TEST (rtp_h265_list_lt_mtu_hvc1)
1044 {
1045   rtp_pipeline_test (rtp_h265_list_lt_mtu_frame_data_hvc1,
1046       rtp_h265_list_lt_mtu_frame_data_size, rtp_h265_list_lt_mtu_frame_count,
1047       "video/x-h265,stream-format=(string)hvc1,alignment=(string)au,"
1048       "codec_data=(buffer)0101c000000080000000000099f000fcfdf8f800000203a000010"
1049       "01840010c01ffff01c000000300800000030000030099ac0900a10001003042010101c00"
1050       "0000300800000030000030099a00a080f1fe36bbb5377725d602dc040404100000300010"
1051       "00003000a0800a2000100074401c172b02240",
1052       "rtph265pay aggregate-mode=zero-latency", "rtph265depay",
1053       rtp_h265_list_lt_mtu_bytes_sent_hvc1, rtp_h265_list_lt_mtu_mtu_size,
1054       TRUE);
1055 }
1056
1057 GST_END_TEST;
1058 static const guint8 rtp_h265_list_gt_mtu_frame_data[] = {
1059   /* not packetized, next NAL starts with 0x000001 */
1060   0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1061   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1062   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1063   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1064   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1065   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1066   0x00, 0x10
1067 };
1068
1069 static const int rtp_h265_list_gt_mtu_frame_data_size = 62;
1070
1071 static const int rtp_h265_list_gt_mtu_frame_count = 1;
1072
1073 /* start code is 3 bytes, NALU header is 2 bytes */
1074 static int rtp_h265_list_gt_mtu_bytes_sent = 1 * (62 - 3 - 2);
1075
1076 static int rtp_h265_list_gt_mtu_mtu_size = 28;
1077
1078 GST_START_TEST (rtp_h265_list_gt_mtu)
1079 {
1080   rtp_pipeline_test (rtp_h265_list_gt_mtu_frame_data,
1081       rtp_h265_list_gt_mtu_frame_data_size, rtp_h265_list_gt_mtu_frame_count,
1082       "video/x-h265,stream-format=(string)byte-stream,alignment=(string)nal",
1083       "rtph265pay", "rtph265depay", rtp_h265_list_gt_mtu_bytes_sent,
1084       rtp_h265_list_gt_mtu_mtu_size, TRUE);
1085 }
1086
1087 GST_END_TEST;
1088 static const guint8 rtp_h265_list_gt_mtu_frame_data_hvc1[] = {
1089   /* packetized data */
1090   0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1091   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1092   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1093   0x00, 0x00, 0x00, 0x00, 0x00,
1094   0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1095   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1096   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1097 };
1098
1099 /* length size is 3 bytes, NALU header is 2 bytes */
1100 static int rtp_h265_list_gt_mtu_bytes_sent_hvc1 = 1 * (62 - 2 * 3 - 2 * 2);
1101
1102 GST_START_TEST (rtp_h265_list_gt_mtu_hvc1)
1103 {
1104   rtp_pipeline_test (rtp_h265_list_gt_mtu_frame_data_hvc1,
1105       rtp_h265_list_gt_mtu_frame_data_size, rtp_h265_list_gt_mtu_frame_count,
1106       "video/x-h265,stream-format=(string)hvc1,alignment=(string)au,"
1107       "codec_data=(buffer)0101c000000080000000000099f000fcfdf8f800000203a000010"
1108       "01840010c01ffff01c000000300800000030000030099ac0900a10001003042010101c00"
1109       "0000300800000030000030099a00a080f1fe36bbb5377725d602dc040404100000300010"
1110       "00003000a0800a2000100074401c172b02240",
1111       "rtph265pay", "rtph265depay", rtp_h265_list_gt_mtu_bytes_sent_hvc1,
1112       rtp_h265_list_gt_mtu_mtu_size, TRUE);
1113 }
1114
1115 GST_END_TEST;
1116
1117 /* KLV data from Day_Flight.mpg */
1118 static const guint8 rtp_KLV_frame_data[] = {
1119   0x06, 0x0e, 0x2b, 0x34, 0x02, 0x0b, 0x01, 0x01,
1120   0x0e, 0x01, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00,
1121   0x81, 0x91, 0x02, 0x08, 0x00, 0x04, 0x6c, 0x8e,
1122   0x20, 0x03, 0x83, 0x85, 0x41, 0x01, 0x01, 0x05,
1123   0x02, 0x3d, 0x3b, 0x06, 0x02, 0x15, 0x80, 0x07,
1124   0x02, 0x01, 0x52, 0x0b, 0x03, 0x45, 0x4f, 0x4e,
1125   0x0c, 0x0e, 0x47, 0x65, 0x6f, 0x64, 0x65, 0x74,
1126   0x69, 0x63, 0x20, 0x57, 0x47, 0x53, 0x38, 0x34,
1127   0x0d, 0x04, 0x4d, 0xc4, 0xdc, 0xbb, 0x0e, 0x04,
1128   0xb1, 0xa8, 0x6c, 0xfe, 0x0f, 0x02, 0x1f, 0x4a,
1129   0x10, 0x02, 0x00, 0x85, 0x11, 0x02, 0x00, 0x4b,
1130   0x12, 0x04, 0x20, 0xc8, 0xd2, 0x7d, 0x13, 0x04,
1131   0xfc, 0xdd, 0x02, 0xd8, 0x14, 0x04, 0xfe, 0xb8,
1132   0xcb, 0x61, 0x15, 0x04, 0x00, 0x8f, 0x3e, 0x61,
1133   0x16, 0x04, 0x00, 0x00, 0x01, 0xc9, 0x17, 0x04,
1134   0x4d, 0xdd, 0x8c, 0x2a, 0x18, 0x04, 0xb1, 0xbe,
1135   0x9e, 0xf4, 0x19, 0x02, 0x0b, 0x85, 0x28, 0x04,
1136   0x4d, 0xdd, 0x8c, 0x2a, 0x29, 0x04, 0xb1, 0xbe,
1137   0x9e, 0xf4, 0x2a, 0x02, 0x0b, 0x85, 0x38, 0x01,
1138   0x2e, 0x39, 0x04, 0x00, 0x8d, 0xd4, 0x29, 0x01,
1139   0x02, 0x1c, 0x5f
1140 };
1141
1142 GST_START_TEST (rtp_klv)
1143 {
1144   rtp_pipeline_test (rtp_KLV_frame_data, G_N_ELEMENTS (rtp_KLV_frame_data), 1,
1145       "meta/x-klv, parsed=(bool)true", "rtpklvpay", "rtpklvdepay", 0, 0, FALSE);
1146 }
1147
1148 GST_END_TEST;
1149
1150 GST_START_TEST (rtp_klv_fragmented)
1151 {
1152   /* force super-small mtu of 60 to fragment KLV unit */
1153   rtp_pipeline_test (rtp_KLV_frame_data, sizeof (rtp_KLV_frame_data), 1,
1154       "meta/x-klv, parsed=(bool)true", "rtpklvpay", "rtpklvdepay",
1155       sizeof (rtp_KLV_frame_data), 60, FALSE);
1156 }
1157
1158 GST_END_TEST;
1159
1160 static const guint8 rtp_L16_frame_data[] =
1161     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1162   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1163 };
1164
1165 static int rtp_L16_frame_data_size = 20;
1166
1167 static int rtp_L16_frame_count = 1;
1168
1169 GST_START_TEST (rtp_L16)
1170 {
1171   rtp_pipeline_test (rtp_L16_frame_data, rtp_L16_frame_data_size,
1172       rtp_L16_frame_count,
1173       "audio/x-raw,format=S16BE,rate=1,channels=1,layout=(string)interleaved",
1174       "rtpL16pay", "rtpL16depay", 0, 0, FALSE);
1175 }
1176
1177 GST_END_TEST;
1178
1179 static const guint8 rtp_L24_frame_data[] =
1180     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1181   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1182 };
1183
1184 static int rtp_L24_frame_data_size = 24;
1185
1186 static int rtp_L24_frame_count = 1;
1187
1188 GST_START_TEST (rtp_L24)
1189 {
1190   rtp_pipeline_test (rtp_L24_frame_data, rtp_L24_frame_data_size,
1191       rtp_L24_frame_count,
1192       "audio/x-raw,format=S24BE,rate=1,channels=1,layout=(string)interleaved",
1193       "rtpL24pay", "rtpL24depay", 0, 0, FALSE);
1194 }
1195
1196 GST_END_TEST;
1197 static const guint8 rtp_mp2t_frame_data[] =
1198     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1199   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1200 };
1201
1202 static int rtp_mp2t_frame_data_size = 20;
1203
1204 static int rtp_mp2t_frame_count = 1;
1205
1206 GST_START_TEST (rtp_mp2t)
1207 {
1208   rtp_pipeline_test (rtp_mp2t_frame_data, rtp_mp2t_frame_data_size,
1209       rtp_mp2t_frame_count, "video/mpegts,packetsize=188,systemstream=true",
1210       "rtpmp2tpay", "rtpmp2tdepay", 0, 0, FALSE);
1211 }
1212
1213 GST_END_TEST;
1214 static const guint8 rtp_mp4v_frame_data[] =
1215     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1216   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1217 };
1218
1219 static int rtp_mp4v_frame_data_size = 20;
1220
1221 static int rtp_mp4v_frame_count = 1;
1222
1223 GST_START_TEST (rtp_mp4v)
1224 {
1225   rtp_pipeline_test (rtp_mp4v_frame_data, rtp_mp4v_frame_data_size,
1226       rtp_mp4v_frame_count, "video/mpeg,mpegversion=4,systemstream=false",
1227       "rtpmp4vpay", "rtpmp4vdepay", 0, 0, FALSE);
1228 }
1229
1230 GST_END_TEST;
1231 static const guint8 rtp_mp4v_list_frame_data[] =
1232     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1233   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1234 };
1235
1236 static int rtp_mp4v_list_frame_data_size = 20;
1237
1238 static int rtp_mp4v_list_frame_count = 1;
1239
1240 static int rtp_mp4v_list_bytes_sent = 1 * 20;
1241
1242 GST_START_TEST (rtp_mp4v_list)
1243 {
1244   rtp_pipeline_test (rtp_mp4v_list_frame_data, rtp_mp4v_list_frame_data_size,
1245       rtp_mp4v_list_frame_count,
1246       "video/mpeg,mpegversion=4,systemstream=false,codec_data=(buffer)000001b001",
1247       "rtpmp4vpay", "rtpmp4vdepay", rtp_mp4v_list_bytes_sent, 0, TRUE);
1248 }
1249
1250 GST_END_TEST;
1251 static const guint8 rtp_mp4g_frame_data[] =
1252     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1253   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1254 };
1255
1256 static int rtp_mp4g_frame_data_size = 20;
1257
1258 static int rtp_mp4g_frame_count = 1;
1259
1260 GST_START_TEST (rtp_mp4g)
1261 {
1262   rtp_pipeline_test (rtp_mp4g_frame_data, rtp_mp4g_frame_data_size,
1263       rtp_mp4g_frame_count,
1264       "video/mpeg,mpegversion=4,systemstream=false,codec_data=(buffer)000001b001",
1265       "rtpmp4gpay", "rtpmp4gdepay", 0, 0, FALSE);
1266 }
1267
1268 GST_END_TEST;
1269 static const guint8 rtp_theora_frame_data[] =
1270     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1271   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1272 };
1273
1274 static int rtp_theora_frame_data_size = 20;
1275
1276 static int rtp_theora_frame_count = 1;
1277
1278 GST_START_TEST (rtp_theora)
1279 {
1280   rtp_pipeline_test (rtp_theora_frame_data, rtp_theora_frame_data_size,
1281       rtp_theora_frame_count, "video/x-theora", "rtptheorapay",
1282       "rtptheoradepay", 0, 0, FALSE);
1283 }
1284
1285 GST_END_TEST;
1286 static const guint8 rtp_vorbis_frame_data[] =
1287     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1288   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1289 };
1290
1291 static int rtp_vorbis_frame_data_size = 20;
1292
1293 static int rtp_vorbis_frame_count = 1;
1294
1295 GST_START_TEST (rtp_vorbis)
1296 {
1297   rtp_pipeline_test (rtp_vorbis_frame_data, rtp_vorbis_frame_data_size,
1298       rtp_vorbis_frame_count, "audio/x-vorbis", "rtpvorbispay",
1299       "rtpvorbisdepay", 0, 0, FALSE);
1300 }
1301
1302 GST_END_TEST;
1303
1304 /* videotestsrc pattern=red  ! video/x-raw,width=160,height=120 ! vp8enc */
1305 #define VP8_CAPS "video/x-vp8, profile=(string)0, " \
1306     "streamheader=(buffer)4f5650383001010000a000780000010000010000001e00000001, " \
1307     "width=(int)160, height=(int)120, framerate=(fraction)30/1"
1308
1309 static const guint8 rtp_vp8_frame_data[] = {
1310   0x30, 0x07, 0x00, 0x9d, 0x01, 0x2a, 0xa0, 0x00,
1311   0x78, 0x00, 0x00, 0x47, 0x08, 0x85, 0x85, 0x88,
1312   0x85, 0x84, 0x88, 0x02, 0x02, 0x02, 0x75, 0xaa,
1313   0x03, 0xf8, 0x03, 0xfa, 0x02, 0x06, 0xc3, 0xef,
1314   0x05, 0x10, 0x9c, 0x52, 0xd2, 0xa1, 0x38, 0xa5,
1315   0xa5, 0x42, 0x71, 0x4b, 0x4a, 0x84, 0xe2, 0x96,
1316   0x95, 0x09, 0xc5, 0x2d, 0x2a, 0x13, 0x8a, 0x5a,
1317   0x54, 0x27, 0x14, 0xb4, 0xa8, 0x4e, 0x29, 0x69,
1318   0x50, 0x9b, 0x00, 0xfe, 0xfd, 0x6e, 0xf3, 0xff,
1319   0xe3, 0x99, 0x37, 0x30, 0xc4, 0xff, 0x8e, 0x6d,
1320   0xff, 0xf1, 0x61, 0x3c, 0x0e, 0x28, 0xc8, 0xff,
1321   0xf1, 0x51, 0x00
1322 };
1323
1324 GST_START_TEST (rtp_vp8)
1325 {
1326   rtp_pipeline_test (rtp_vp8_frame_data, sizeof (rtp_vp8_frame_data), 1,
1327       VP8_CAPS, "rtpvp8pay", "rtpvp8depay", 0, 0, FALSE);
1328 }
1329
1330 GST_END_TEST;
1331
1332 /* videotestsrc pattern=red  ! video/x-raw,width=160,height=120 ! vp9enc */
1333 #define VP9_CAPS "video/x-vp9, profile=(string)0, " \
1334     "width=(int)160, height=(int)120, framerate=(fraction)30/1"
1335
1336 static const guint8 rtp_vp9_frame_data[] = {
1337   0x82, 0x49, 0x83, 0x42, 0x00, 0x09, 0xf0, 0x07,
1338   0x76, 0x00, 0x38, 0x24, 0x1c, 0x18, 0x42, 0x00,
1339   0x00, 0x30, 0x60, 0x00, 0x00, 0x67, 0x3f, 0xff,
1340   0xfe, 0x69, 0x95, 0xff, 0xff, 0xff, 0xfe, 0x99,
1341   0x6b, 0xff, 0xff, 0xff, 0xff, 0x62, 0x98, 0x1d,
1342   0x45, 0x4c, 0x90, 0xc4, 0x70
1343 };
1344
1345 GST_START_TEST (rtp_vp9)
1346 {
1347   rtp_pipeline_test (rtp_vp9_frame_data, sizeof (rtp_vp9_frame_data), 1,
1348       VP9_CAPS, "rtpvp9pay", "rtpvp9depay", 0, 0, FALSE);
1349 }
1350
1351 GST_END_TEST;
1352
1353 static const guint8 rtp_jpeg_frame_data[] =
1354     { /* SOF */ 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0x08, 0x00, 0x08,
1355   0x03, 0x00, 0x21, 0x08, 0x01, 0x11, 0x08, 0x02, 0x11, 0x08,
1356   /* DQT */ 0xFF, 0xDB, 0x00, 0x43, 0x08,
1357   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1358   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1359   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1360   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1361   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1362   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1363   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1364   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1365   /* DATA */ 0x00, 0x00, 0x00, 0x00, 0x00
1366 };
1367
1368 static int rtp_jpeg_frame_data_size = sizeof (rtp_jpeg_frame_data);
1369
1370 static int rtp_jpeg_frame_count = 1;
1371
1372 GST_START_TEST (rtp_jpeg)
1373 {
1374   rtp_pipeline_test (rtp_jpeg_frame_data, rtp_jpeg_frame_data_size,
1375       rtp_jpeg_frame_count, "video/x-jpeg,height=640,width=480", "rtpjpegpay",
1376       "rtpjpegdepay", 0, 0, FALSE);
1377 }
1378
1379 GST_END_TEST;
1380
1381 GST_START_TEST (rtp_jpeg_width_greater_than_2040)
1382 {
1383   rtp_pipeline_test (rtp_jpeg_frame_data, rtp_jpeg_frame_data_size,
1384       rtp_jpeg_frame_count, "video/x-jpeg,height=2048,width=480", "rtpjpegpay",
1385       "rtpjpegdepay", 0, 0, FALSE);
1386 }
1387
1388 GST_END_TEST;
1389
1390 GST_START_TEST (rtp_jpeg_height_greater_than_2040)
1391 {
1392   rtp_pipeline_test (rtp_jpeg_frame_data, rtp_jpeg_frame_data_size,
1393       rtp_jpeg_frame_count, "video/x-jpeg,height=640,width=2048", "rtpjpegpay",
1394       "rtpjpegdepay", 0, 0, FALSE);
1395 }
1396
1397 GST_END_TEST;
1398
1399 GST_START_TEST (rtp_jpeg_width_and_height_greater_than_2040)
1400 {
1401   rtp_pipeline_test (rtp_jpeg_frame_data, rtp_jpeg_frame_data_size,
1402       rtp_jpeg_frame_count, "video/x-jpeg,height=2048,width=2048", "rtpjpegpay",
1403       "rtpjpegdepay", 0, 0, FALSE);
1404 }
1405
1406 GST_END_TEST;
1407
1408 static const guint8 rtp_jpeg_list_frame_data[] =
1409     { /* SOF */ 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0x08, 0x00, 0x08,
1410   0x03, 0x00, 0x21, 0x08, 0x01, 0x11, 0x08, 0x02, 0x11, 0x08,
1411   /* DQT */ 0xFF, 0xDB, 0x00, 0x43, 0x08,
1412   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1413   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1414   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1415   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1416   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1417   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1418   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1419   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1420   /* DATA */ 0x00, 0x00, 0x00, 0x00, 0x00
1421 };
1422
1423 static int rtp_jpeg_list_frame_data_size = sizeof (rtp_jpeg_list_frame_data);
1424
1425 static int rtp_jpeg_list_frame_count = 1;
1426
1427 static int rtp_jpeg_list_bytes_sent = 1 * sizeof (rtp_jpeg_list_frame_data);
1428
1429 GST_START_TEST (rtp_jpeg_list)
1430 {
1431   rtp_pipeline_test (rtp_jpeg_list_frame_data, rtp_jpeg_list_frame_data_size,
1432       rtp_jpeg_list_frame_count, "video/x-jpeg,height=640,width=480",
1433       "rtpjpegpay", "rtpjpegdepay", rtp_jpeg_list_bytes_sent, 0, TRUE);
1434 }
1435
1436 GST_END_TEST;
1437
1438 GST_START_TEST (rtp_jpeg_list_width_greater_than_2040)
1439 {
1440   rtp_pipeline_test (rtp_jpeg_list_frame_data, rtp_jpeg_list_frame_data_size,
1441       rtp_jpeg_list_frame_count, "video/x-jpeg,height=2048,width=480",
1442       "rtpjpegpay", "rtpjpegdepay", rtp_jpeg_list_bytes_sent, 0, TRUE);
1443 }
1444
1445 GST_END_TEST;
1446
1447 GST_START_TEST (rtp_jpeg_list_height_greater_than_2040)
1448 {
1449   rtp_pipeline_test (rtp_jpeg_list_frame_data, rtp_jpeg_list_frame_data_size,
1450       rtp_jpeg_list_frame_count, "video/x-jpeg,height=640,width=2048",
1451       "rtpjpegpay", "rtpjpegdepay", rtp_jpeg_list_bytes_sent, 0, TRUE);
1452 }
1453
1454 GST_END_TEST;
1455
1456 GST_START_TEST (rtp_jpeg_list_width_and_height_greater_than_2040)
1457 {
1458   rtp_pipeline_test (rtp_jpeg_list_frame_data, rtp_jpeg_list_frame_data_size,
1459       rtp_jpeg_list_frame_count, "video/x-jpeg,height=2048,width=2048",
1460       "rtpjpegpay", "rtpjpegdepay", rtp_jpeg_list_bytes_sent, 0, TRUE);
1461 }
1462
1463 GST_END_TEST;
1464
1465 static void
1466 rtp_jpeg_do_packet_loss (gdouble prob, gint num_expected)
1467 {
1468   GstHarness *h;
1469   gboolean eos = FALSE;
1470   gchar *s;
1471   guint i, buffer_count;
1472
1473   s = g_strdup_printf ("videotestsrc pattern=ball num-buffers=100 ! "
1474       "jpegenc quality=50 ! rtpjpegpay ! identity drop-probability=%g ! "
1475       "rtpjpegdepay", prob);
1476   GST_INFO ("running pipeline %s", s);
1477   h = gst_harness_new_parse (s);
1478   g_free (s);
1479
1480   gst_harness_play (h);
1481
1482   do {
1483     GstEvent *event;
1484
1485     event = gst_harness_pull_event (h);
1486     eos = (GST_EVENT_TYPE (event) == GST_EVENT_EOS);
1487     gst_event_unref (event);
1488   } while (!eos);
1489
1490   buffer_count = gst_harness_buffers_received (h);
1491   GST_INFO ("Got %u buffers", buffer_count);
1492
1493   if (num_expected >= 0) {
1494     fail_unless_equals_int (num_expected, buffer_count);
1495   }
1496
1497   for (i = 0; i < buffer_count; ++i) {
1498     GstBuffer *buf;
1499     GstMapInfo map;
1500     guint16 soi, eoi;
1501
1502     buf = gst_harness_pull (h);
1503     fail_unless (buf != NULL);
1504
1505     fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
1506     GST_MEMDUMP ("jpeg frame", map.data, map.size);
1507     fail_unless (map.size > 4);
1508     soi = GST_READ_UINT16_BE (map.data);
1509     fail_unless (soi == 0xffd8, "expected JPEG frame start FFD8 not %02X", soi);
1510     eoi = GST_READ_UINT16_BE (map.data + map.size - 2);
1511     fail_unless (eoi == 0xffd9, "expected JPEG frame end FFD9 not %02X", eoi);
1512     gst_buffer_unmap (buf, &map);
1513     gst_buffer_unref (buf);
1514   }
1515
1516   gst_harness_teardown (h);
1517 }
1518
1519 GST_START_TEST (rtp_jpeg_packet_loss)
1520 {
1521   gdouble probabilities[] = { 0.0, 0.001, 0.01, 0.1, 0.2, 0.5, 1.0 };
1522   gint num_expected[] = { 100, -1, -1, -1, -1, -1, 0 };
1523
1524   GST_INFO ("Start iteration %d", __i__);
1525   fail_unless (__i__ < G_N_ELEMENTS (probabilities));
1526   rtp_jpeg_do_packet_loss (probabilities[__i__], num_expected[__i__]);
1527   GST_INFO ("Done with iteration %d", __i__);
1528 }
1529
1530 GST_END_TEST;
1531
1532 static const guint8 rtp_g729_frame_data[] =
1533     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1534   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1535 };
1536
1537 static int rtp_g729_frame_data_size = 22;
1538
1539 static int rtp_g729_frame_count = 1;
1540
1541 GST_START_TEST (rtp_g729)
1542 {
1543   rtp_pipeline_test (rtp_g729_frame_data, rtp_g729_frame_data_size,
1544       rtp_g729_frame_count, "audio/G729,rate=8000,channels=1", "rtpg729pay",
1545       "rtpg729depay", 0, 0, FALSE);
1546 }
1547
1548 GST_END_TEST;
1549
1550 static const guint8 rtp_gst_frame_data[] =
1551     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1552   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1553 };
1554
1555 static int rtp_gst_frame_data_size = 22;
1556
1557 static int rtp_gst_frame_count = 1;
1558
1559 GST_START_TEST (rtp_gst_custom_event)
1560 {
1561   /* Create RTP pipeline. */
1562   rtp_pipeline *p =
1563       rtp_pipeline_create (rtp_gst_frame_data, rtp_gst_frame_data_size,
1564       rtp_gst_frame_count, "application/x-test",
1565       "rtpgstpay", "rtpgstdepay");
1566
1567   if (p == NULL) {
1568     return;
1569   }
1570
1571   p->custom_event =
1572       gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
1573       gst_structure_new ("test", "foo", G_TYPE_INT, 1, NULL));
1574
1575   /* Run RTP pipeline. */
1576   rtp_pipeline_run (p);
1577
1578   /* Destroy RTP pipeline. */
1579   rtp_pipeline_destroy (p);
1580 }
1581
1582 GST_END_TEST;
1583
1584 GST_START_TEST (rtp_vorbis_renegotiate)
1585 {
1586   GstElement *pipeline;
1587   GstElement *enc, *pay, *depay, *dec, *sink;
1588   GstPad *sinkpad, *srcpad;
1589   GstCaps *templcaps, *caps, *filter, *srccaps;
1590   GstSegment segment;
1591   GstBuffer *buffer;
1592   GstMapInfo map;
1593   GstAudioInfo info;
1594
1595   pipeline = gst_pipeline_new (NULL);
1596   enc = gst_element_factory_make ("vorbisenc", NULL);
1597   pay = gst_element_factory_make ("rtpvorbispay", NULL);
1598   depay = gst_element_factory_make ("rtpvorbisdepay", NULL);
1599   dec = gst_element_factory_make ("vorbisdec", NULL);
1600   sink = gst_element_factory_make ("fakesink", NULL);
1601   g_object_set (sink, "async", FALSE, NULL);
1602   gst_bin_add_many (GST_BIN (pipeline), enc, pay, depay, dec, sink, NULL);
1603   fail_unless (gst_element_link_many (enc, pay, depay, dec, sink, NULL));
1604   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
1605       GST_STATE_CHANGE_SUCCESS);
1606
1607   sinkpad = gst_element_get_static_pad (enc, "sink");
1608   srcpad = gst_element_get_static_pad (dec, "src");
1609
1610   templcaps = gst_pad_get_pad_template_caps (sinkpad);
1611   filter =
1612       gst_caps_new_simple ("audio/x-raw", "channels", G_TYPE_INT, 2, "rate",
1613       G_TYPE_INT, 44100, NULL);
1614   caps = gst_caps_intersect (templcaps, filter);
1615   caps = gst_caps_fixate (caps);
1616
1617   gst_segment_init (&segment, GST_FORMAT_TIME);
1618   fail_unless (gst_pad_send_event (sinkpad,
1619           gst_event_new_stream_start ("test")));
1620   fail_unless (gst_pad_send_event (sinkpad, gst_event_new_caps (caps)));
1621   fail_unless (gst_pad_send_event (sinkpad, gst_event_new_segment (&segment)));
1622
1623   gst_audio_info_from_caps (&info, caps);
1624   buffer = gst_buffer_new_and_alloc (44100 * info.bpf);
1625   gst_buffer_map (buffer, &map, GST_MAP_WRITE);
1626   gst_audio_format_info_fill_silence (info.finfo, map.data, map.size);
1627   gst_buffer_unmap (buffer, &map);
1628   GST_BUFFER_PTS (buffer) = 0;
1629   GST_BUFFER_DURATION (buffer) = 1 * GST_SECOND;
1630
1631   fail_unless_equals_int (gst_pad_chain (sinkpad, buffer), GST_FLOW_OK);
1632
1633   srccaps = gst_pad_get_current_caps (srcpad);
1634   fail_unless (gst_caps_can_intersect (srccaps, caps));
1635   gst_caps_unref (srccaps);
1636
1637   gst_caps_unref (caps);
1638   gst_caps_unref (filter);
1639   filter =
1640       gst_caps_new_simple ("audio/x-raw", "channels", G_TYPE_INT, 2, "rate",
1641       G_TYPE_INT, 48000, NULL);
1642   caps = gst_caps_intersect (templcaps, filter);
1643   caps = gst_caps_fixate (caps);
1644
1645   fail_unless (gst_pad_send_event (sinkpad, gst_event_new_caps (caps)));
1646
1647   gst_audio_info_from_caps (&info, caps);
1648   buffer = gst_buffer_new_and_alloc (48000 * info.bpf);
1649   gst_buffer_map (buffer, &map, GST_MAP_WRITE);
1650   gst_audio_format_info_fill_silence (info.finfo, map.data, map.size);
1651   gst_buffer_unmap (buffer, &map);
1652   GST_BUFFER_PTS (buffer) = 0;
1653   GST_BUFFER_DURATION (buffer) = 1 * GST_SECOND;
1654   GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
1655
1656   fail_unless_equals_int (gst_pad_chain (sinkpad, buffer), GST_FLOW_OK);
1657
1658   srccaps = gst_pad_get_current_caps (srcpad);
1659   fail_unless (gst_caps_can_intersect (srccaps, caps));
1660   gst_caps_unref (srccaps);
1661
1662   gst_caps_unref (caps);
1663   gst_caps_unref (filter);
1664   gst_caps_unref (templcaps);
1665   gst_object_unref (sinkpad);
1666   gst_object_unref (srcpad);
1667   gst_element_set_state (pipeline, GST_STATE_NULL);
1668   gst_object_unref (pipeline);
1669 }
1670
1671 GST_END_TEST;
1672
1673 /*
1674  * Creates the test suite.
1675  *
1676  * Returns: pointer to the test suite.
1677  */
1678 static Suite *
1679 rtp_payloading_suite (void)
1680 {
1681   GstRegistry *registry = gst_registry_get ();
1682   Suite *s = suite_create ("rtp_data_test");
1683
1684   TCase *tc_chain = tcase_create ("linear");
1685
1686   /* Set timeout to 60 seconds. */
1687   tcase_set_timeout (tc_chain, 60);
1688
1689   suite_add_tcase (s, tc_chain);
1690   tcase_add_test (tc_chain, rtp_ilbc);
1691   tcase_add_test (tc_chain, rtp_gsm);
1692   tcase_add_test (tc_chain, rtp_amr);
1693   tcase_add_test (tc_chain, rtp_pcma);
1694   tcase_add_test (tc_chain, rtp_pcmu);
1695   tcase_add_test (tc_chain, rtp_mpa);
1696   tcase_add_test (tc_chain, rtp_h261);
1697   tcase_add_test (tc_chain, rtp_h263);
1698   tcase_add_test (tc_chain, rtp_h263p);
1699   tcase_add_test (tc_chain, rtp_h264);
1700   tcase_add_test (tc_chain, rtp_h264depay_avc);
1701   tcase_add_test (tc_chain, rtp_h264depay_bytestream);
1702   tcase_add_test (tc_chain, rtp_h264_list_lt_mtu);
1703   tcase_add_test (tc_chain, rtp_h264_list_lt_mtu_avc);
1704   tcase_add_test (tc_chain, rtp_h264_list_gt_mtu);
1705   tcase_add_test (tc_chain, rtp_h264_list_gt_mtu_avc);
1706   tcase_add_test (tc_chain, rtp_h265);
1707   tcase_add_test (tc_chain, rtp_h265_list_lt_mtu);
1708   tcase_add_test (tc_chain, rtp_h265_list_lt_mtu_hvc1);
1709   tcase_add_test (tc_chain, rtp_h265_list_gt_mtu);
1710   tcase_add_test (tc_chain, rtp_h265_list_gt_mtu_hvc1);
1711   tcase_add_test (tc_chain, rtp_klv);
1712   tcase_add_test (tc_chain, rtp_klv_fragmented);
1713   tcase_add_test (tc_chain, rtp_L16);
1714   tcase_add_test (tc_chain, rtp_L24);
1715   tcase_add_test (tc_chain, rtp_mp2t);
1716   tcase_add_test (tc_chain, rtp_mp4v);
1717   tcase_add_test (tc_chain, rtp_mp4v_list);
1718   tcase_add_test (tc_chain, rtp_mp4g);
1719   tcase_add_test (tc_chain, rtp_theora);
1720   tcase_add_test (tc_chain, rtp_vorbis);
1721   tcase_add_test (tc_chain, rtp_vp8);
1722   tcase_add_test (tc_chain, rtp_vp9);
1723   tcase_add_test (tc_chain, rtp_jpeg);
1724   tcase_add_test (tc_chain, rtp_jpeg_width_greater_than_2040);
1725   tcase_add_test (tc_chain, rtp_jpeg_height_greater_than_2040);
1726   tcase_add_test (tc_chain, rtp_jpeg_width_and_height_greater_than_2040);
1727   tcase_add_test (tc_chain, rtp_jpeg_list);
1728   tcase_add_test (tc_chain, rtp_jpeg_list_width_greater_than_2040);
1729   tcase_add_test (tc_chain, rtp_jpeg_list_height_greater_than_2040);
1730   tcase_add_test (tc_chain, rtp_jpeg_list_width_and_height_greater_than_2040);
1731   if (gst_registry_check_feature_version (registry, "jpegenc", 1, 0, 0)
1732       && gst_registry_check_feature_version (registry, "videotestsrc", 1, 0, 0))
1733     tcase_add_loop_test (tc_chain, rtp_jpeg_packet_loss, 0, 7);
1734   tcase_add_test (tc_chain, rtp_g729);
1735   tcase_add_test (tc_chain, rtp_gst_custom_event);
1736   tcase_add_test (tc_chain, rtp_vorbis_renegotiate);
1737   return s;
1738 }
1739
1740 GST_CHECK_MAIN (rtp_payloading)