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