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