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