1 /* GStreamer RTP payloader unit tests
2 * Copyright (C) 2008 Nokia Corporation and its subsidiary(-ies)
3 * contact: <stefan.kost@nokia.com>
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.
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.
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.
24 #include <gst/check/gstcheck.h>
25 #include <gst/check/gstharness.h>
26 #include <gst/audio/audio.h>
27 #include <gst/base/base.h>
28 #include <gst/rtp/gstrtpbuffer.h>
31 #define RELEASE_ELEMENT(x) if(x) {gst_object_unref(x); x = NULL;}
36 * RTP pipeline structure to store the required elements.
45 const guint8 *frame_data;
48 GstEvent *custom_event;
52 * Number of bytes received in the chain list function when using buffer lists
54 static guint chain_list_bytes_received;
57 * Chain list function for testing buffer lists
60 rtp_pipeline_chain_list (GstPad * pad, GstObject * parent, GstBufferList * list)
66 * Count the size of the payload in the buffer list.
68 len = gst_buffer_list_length (list);
69 GST_LOG ("list length %u", len);
71 /* Loop through all buffers */
72 for (i = 0; i < len; i++) {
77 paybuf = gst_buffer_list_get (list, i);
78 /* only count real data which is expected in last memory block */
79 GST_LOG ("n_memory %d", gst_buffer_n_memory (paybuf));
80 fail_unless (gst_buffer_n_memory (paybuf) > 1);
81 mem = gst_buffer_get_memory_range (paybuf, gst_buffer_n_memory (paybuf) - 1,
83 size = gst_memory_get_sizes (mem, NULL, NULL);
84 gst_memory_unref (mem);
85 chain_list_bytes_received += size;
86 GST_LOG ("size %d, total %u", size, chain_list_bytes_received);
88 gst_buffer_list_unref (list);
94 rtp_pipeline_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
98 list = gst_buffer_list_new_sized (1);
99 gst_buffer_list_add (list, buf);
100 return rtp_pipeline_chain_list (pad, parent, list);
107 rtp_bus_callback (GstBus * bus, GstMessage * message, gpointer data)
109 GMainLoop *mainloop = (GMainLoop *) data;
111 switch (GST_MESSAGE_TYPE (message)) {
112 case GST_MESSAGE_ERROR:
120 element_name = (message->src) ? gst_object_get_name (message->src) : NULL;
121 gst_message_parse_error (message, &err, &debug);
122 g_print ("\nError from element %s: %s\n%s\n\n",
123 GST_STR_NULL (element_name), err->message, (debug) ? debug : "");
126 g_free (element_name);
128 fail_if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR);
130 g_main_loop_quit (mainloop);
134 case GST_MESSAGE_EOS:
136 g_main_loop_quit (mainloop);
151 * Creates a RTP pipeline for one test.
152 * @param frame_data Pointer to the frame data which is used to pass through pay/depayloaders.
153 * @param frame_data_size Frame data size in bytes.
154 * @param frame_count Frame count.
155 * @param filtercaps Caps filters.
156 * @param pay Payloader name.
157 * @param depay Depayloader name.
159 * Returns pointer to the RTP pipeline.
160 * The user must free the RTP pipeline when it's not used anymore.
162 static rtp_pipeline *
163 rtp_pipeline_create (const guint8 * frame_data, int frame_data_size,
164 int frame_count, const char *filtercaps, const char *pay, const char *depay)
166 gchar *pipeline_name;
170 /* Check parameters. */
171 if (!frame_data || !pay || !depay) {
175 /* Allocate memory for the RTP pipeline. */
176 p = (rtp_pipeline *) malloc (sizeof (rtp_pipeline));
178 p->frame_data = frame_data;
179 p->frame_data_size = frame_data_size;
180 p->frame_count = frame_count;
181 p->custom_event = NULL;
183 /* Create elements. */
184 pipeline_name = g_strdup_printf ("%s-%s-pipeline", pay, depay);
185 p->pipeline = gst_pipeline_new (pipeline_name);
186 g_free (pipeline_name);
187 p->appsrc = gst_element_factory_make ("appsrc", NULL);
189 gst_parse_bin_from_description_full (pay, TRUE, NULL,
190 GST_PARSE_FLAG_NO_SINGLE_ELEMENT_BINS, NULL);
192 gst_parse_bin_from_description_full (depay, TRUE, NULL,
193 GST_PARSE_FLAG_NO_SINGLE_ELEMENT_BINS, NULL);
194 p->fakesink = gst_element_factory_make ("fakesink", NULL);
196 /* One or more elements are not created successfully or failed to create p? */
197 if (!p->pipeline || !p->appsrc || !p->rtppay || !p->rtpdepay || !p->fakesink) {
198 /* Release created elements. */
199 RELEASE_ELEMENT (p->pipeline);
200 RELEASE_ELEMENT (p->appsrc);
201 RELEASE_ELEMENT (p->rtppay);
202 RELEASE_ELEMENT (p->rtpdepay);
203 RELEASE_ELEMENT (p->fakesink);
205 /* Release allocated memory. */
211 /* Set src properties. */
212 caps = gst_caps_from_string (filtercaps);
213 g_object_set (p->appsrc, "do-timestamp", TRUE, "caps", caps,
214 "format", GST_FORMAT_TIME, NULL);
215 gst_caps_unref (caps);
217 /* Add elements to the pipeline. */
218 gst_bin_add (GST_BIN (p->pipeline), p->appsrc);
219 gst_bin_add (GST_BIN (p->pipeline), p->rtppay);
220 gst_bin_add (GST_BIN (p->pipeline), p->rtpdepay);
221 gst_bin_add (GST_BIN (p->pipeline), p->fakesink);
224 gst_element_link (p->appsrc, p->rtppay);
225 gst_element_link (p->rtppay, p->rtpdepay);
226 gst_element_link (p->rtpdepay, p->fakesink);
232 * Destroys the RTP pipeline.
233 * @param p Pointer to the RTP pipeline.
236 rtp_pipeline_destroy (rtp_pipeline * p)
238 /* Check parameters. */
243 /* Release pipeline. */
244 RELEASE_ELEMENT (p->pipeline);
246 /* Release allocated memory. */
250 static GstPadProbeReturn
251 pay_event_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
253 rtp_pipeline *p = (rtp_pipeline *) user_data;
254 GstEvent *event = GST_PAD_PROBE_INFO_DATA (info);
256 if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM) {
257 const GstStructure *s0 = gst_event_get_structure (p->custom_event);
258 const GstStructure *s1 = gst_event_get_structure (event);
259 if (gst_structure_is_equal (s0, s1)) {
260 return GST_PAD_PROBE_DROP;
264 return GST_PAD_PROBE_OK;
267 static GstPadProbeReturn
268 depay_event_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
270 rtp_pipeline *p = (rtp_pipeline *) user_data;
271 GstEvent *event = GST_PAD_PROBE_INFO_DATA (info);
273 if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM) {
274 const GstStructure *s0 = gst_event_get_structure (p->custom_event);
275 const GstStructure *s1 = gst_event_get_structure (event);
276 if (gst_structure_is_equal (s0, s1)) {
277 gst_event_unref (p->custom_event);
278 p->custom_event = NULL;
282 return GST_PAD_PROBE_OK;
286 * Runs the RTP pipeline.
287 * @param p Pointer to the RTP pipeline.
290 rtp_pipeline_run (rtp_pipeline * p)
292 GstFlowReturn flow_ret;
293 GMainLoop *mainloop = NULL;
297 /* Check parameters. */
302 /* Create mainloop. */
303 mainloop = g_main_loop_new (NULL, FALSE);
308 /* Add bus callback. */
309 bus = gst_pipeline_get_bus (GST_PIPELINE (p->pipeline));
311 gst_bus_add_watch (bus, rtp_bus_callback, (gpointer) mainloop);
313 /* Set pipeline to PLAYING. */
314 gst_element_set_state (p->pipeline, GST_STATE_PLAYING);
316 /* Push custom event into the pipeline */
317 if (p->custom_event) {
320 /* Install a probe to drop the event after it being serialized */
321 srcpad = gst_element_get_static_pad (p->rtppay, "src");
322 gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
323 pay_event_probe_cb, p, NULL);
324 gst_object_unref (srcpad);
326 /* Install a probe to trace the deserialized event after depayloading */
327 srcpad = gst_element_get_static_pad (p->rtpdepay, "src");
328 gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
329 depay_event_probe_cb, p, NULL);
330 gst_object_unref (srcpad);
332 gst_element_send_event (p->appsrc, gst_event_ref (p->custom_event));
335 /* Push data into the pipeline */
336 for (i = 0; i < LOOP_COUNT; i++) {
337 const guint8 *data = p->frame_data;
339 for (j = 0; j < p->frame_count; j++) {
343 gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
344 (guint8 *) data, p->frame_data_size, 0, p->frame_data_size, NULL,
347 g_signal_emit_by_name (p->appsrc, "push-buffer", buf, &flow_ret);
348 fail_unless_equals_int (flow_ret, GST_FLOW_OK);
349 data += p->frame_data_size;
351 gst_buffer_unref (buf);
355 g_signal_emit_by_name (p->appsrc, "end-of-stream", &flow_ret);
358 g_main_loop_run (mainloop);
360 /* Set pipeline to NULL. */
361 gst_element_set_state (p->pipeline, GST_STATE_NULL);
363 /* Release mainloop. */
364 g_main_loop_unref (mainloop);
366 gst_bus_remove_watch (bus);
367 gst_object_unref (bus);
369 fail_if (p->custom_event);
373 * Enables buffer lists and adds a chain_list_function to the depayloader.
374 * @param p Pointer to the RTP pipeline.
377 rtp_pipeline_enable_lists (rtp_pipeline * p)
381 /* Add chain list function for the buffer list tests */
382 pad = gst_element_get_static_pad (p->rtpdepay, "sink");
383 gst_pad_set_chain_list_function (pad,
384 GST_DEBUG_FUNCPTR (rtp_pipeline_chain_list));
385 /* .. to satisfy this silly test code in case someone dares push a buffer */
386 gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (rtp_pipeline_chain));
387 gst_object_unref (pad);
391 * Creates the RTP pipeline and runs the test using the pipeline.
392 * @param frame_data Pointer to the frame data which is used to pass through pay/depayloaders.
393 * @param frame_data_size Frame data size in bytes.
394 * @param frame_count Frame count.
395 * @param filtercaps Caps filters.
396 * @param pay Payloader name.
397 * @param depay Depayloader name.
398 * @bytes_sent bytes that will be sent, used when testing buffer lists
399 * @mtu_size set mtu size when testing lists
400 * @use_lists enable buffer lists
403 rtp_pipeline_test (const guint8 * frame_data, int frame_data_size,
404 int frame_count, const char *filtercaps, const char *pay, const char *depay,
405 guint bytes_sent, guint mtu_size, gboolean use_lists)
407 /* Create RTP pipeline. */
409 rtp_pipeline_create (frame_data, frame_data_size, frame_count, filtercaps,
416 /* set mtu size if needed */
418 g_object_set (p->rtppay, "mtu", mtu_size, NULL);
422 rtp_pipeline_enable_lists (p);
423 chain_list_bytes_received = 0;
426 /* Run RTP pipeline. */
427 rtp_pipeline_run (p);
429 /* Destroy RTP pipeline. */
430 rtp_pipeline_destroy (p);
433 /* 'next NAL' indicator is 4 bytes */
434 fail_unless_equals_int (chain_list_bytes_received, bytes_sent * LOOP_COUNT);
438 static const guint8 rtp_ilbc_frame_data[] =
439 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
443 static int rtp_ilbc_frame_data_size = 20;
445 static int rtp_ilbc_frame_count = 1;
447 GST_START_TEST (rtp_ilbc)
449 rtp_pipeline_test (rtp_ilbc_frame_data, rtp_ilbc_frame_data_size,
450 rtp_ilbc_frame_count, "audio/x-iLBC,mode=20", "rtpilbcpay",
451 "rtpilbcdepay", 0, 0, FALSE);
455 static const guint8 rtp_gsm_frame_data[] =
456 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
457 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
460 static int rtp_gsm_frame_data_size = 20;
462 static int rtp_gsm_frame_count = 1;
464 GST_START_TEST (rtp_gsm)
466 rtp_pipeline_test (rtp_gsm_frame_data, rtp_gsm_frame_data_size,
467 rtp_gsm_frame_count, "audio/x-gsm,rate=8000,channels=1", "rtpgsmpay",
468 "rtpgsmdepay", 0, 0, FALSE);
472 static const guint8 rtp_amr_frame_data[] =
473 { 0x3c, 0x24, 0x03, 0xb3, 0x48, 0x10, 0x68, 0x46, 0x6c, 0xec, 0x03,
474 0x7a, 0x37, 0x16, 0x41, 0x41, 0xc0, 0x00, 0x0d, 0xcd, 0x12, 0xed,
475 0xad, 0x80, 0x00, 0x00, 0x11, 0x31, 0x00, 0x00, 0x0d, 0xa0
478 static int rtp_amr_frame_data_size = 32;
480 static int rtp_amr_frame_count = 1;
482 GST_START_TEST (rtp_amr)
484 rtp_pipeline_test (rtp_amr_frame_data, rtp_amr_frame_data_size,
485 rtp_amr_frame_count, "audio/AMR,channels=1,rate=8000", "rtpamrpay",
486 "rtpamrdepay", 0, 0, FALSE);
490 static const guint8 rtp_pcma_frame_data[] =
491 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
495 static int rtp_pcma_frame_data_size = 20;
497 static int rtp_pcma_frame_count = 1;
499 GST_START_TEST (rtp_pcma)
501 rtp_pipeline_test (rtp_pcma_frame_data, rtp_pcma_frame_data_size,
502 rtp_pcma_frame_count, "audio/x-alaw,channels=1,rate=8000", "rtppcmapay",
503 "rtppcmadepay", 0, 0, FALSE);
507 static const guint8 rtp_pcmu_frame_data[] =
508 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
509 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
512 static int rtp_pcmu_frame_data_size = 20;
514 static int rtp_pcmu_frame_count = 1;
516 GST_START_TEST (rtp_pcmu)
518 rtp_pipeline_test (rtp_pcmu_frame_data, rtp_pcmu_frame_data_size,
519 rtp_pcmu_frame_count, "audio/x-mulaw,channels=1,rate=8000", "rtppcmupay",
520 "rtppcmudepay", 0, 0, FALSE);
524 static const guint8 rtp_mpa_frame_data[] =
525 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
529 static int rtp_mpa_frame_data_size = 20;
531 static int rtp_mpa_frame_count = 1;
533 GST_START_TEST (rtp_mpa)
535 rtp_pipeline_test (rtp_mpa_frame_data, rtp_mpa_frame_data_size,
536 rtp_mpa_frame_count, "audio/mpeg,mpegversion=1", "rtpmpapay",
537 "rtpmpadepay", 0, 0, FALSE);
542 static const guint8 rtp_h261_frame_data[] = {
543 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x11, 0x00, 0x00, 0x4c, 0x40, 0x00,
547 static int rtp_h261_frame_data_size = 14;
548 static int rtp_h261_frame_count = 1;
550 GST_START_TEST (rtp_h261)
552 rtp_pipeline_test (rtp_h261_frame_data, rtp_h261_frame_data_size,
553 rtp_h261_frame_count, "video/x-h261", "rtph261pay", "rtph261depay",
559 static const guint8 rtp_h263_frame_data[] =
560 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
564 static int rtp_h263_frame_data_size = 20;
566 static int rtp_h263_frame_count = 1;
568 GST_START_TEST (rtp_h263)
570 rtp_pipeline_test (rtp_h263_frame_data, rtp_h263_frame_data_size,
571 rtp_h263_frame_count,
572 "video/x-h263,variant=(string)itu,h263version=h263",
573 "rtph263pay", "rtph263depay", 0, 0, FALSE);
574 rtp_pipeline_test (rtp_h263_frame_data, rtp_h263_frame_data_size,
575 rtp_h263_frame_count,
576 "video/x-h263,variant=(string)itu,h263version=h263,width=10,height=20",
577 "rtph263pay", "rtph263depay", 0, 0, FALSE);
581 static const guint8 rtp_h263p_frame_data[] =
582 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
586 static int rtp_h263p_frame_data_size = 20;
588 static int rtp_h263p_frame_count = 1;
590 GST_START_TEST (rtp_h263p)
592 rtp_pipeline_test (rtp_h263p_frame_data, rtp_h263p_frame_data_size,
593 rtp_h263p_frame_count, "video/x-h263,variant=(string)itu,"
594 "h263version=(string)h263", "rtph263ppay", "rtph263pdepay", 0, 0, FALSE);
596 /* payloader should accept any input that matches the template caps
597 * if there's just a udpsink or fakesink downstream */
598 rtp_pipeline_test (rtp_h263p_frame_data, rtp_h263p_frame_data_size,
599 rtp_h263p_frame_count, "video/x-h263,variant=(string)itu,"
600 "h263version=(string)h263", "rtph263ppay", "identity", 0, 0, FALSE);
602 /* default output of avenc_h263p */
603 rtp_pipeline_test (rtp_h263p_frame_data, rtp_h263p_frame_data_size,
604 rtp_h263p_frame_count, "video/x-h263,variant=(string)itu,"
605 "h263version=(string)h263p, annex-f=(boolean)true, "
606 "annex-j=(boolean)true, annex-i=(boolean)true, annex-t=(boolean)true",
607 "rtph263ppay", "identity", 0, 0, FALSE);
609 /* pay ! depay should also work with any input */
610 rtp_pipeline_test (rtp_h263p_frame_data, rtp_h263p_frame_data_size,
611 rtp_h263p_frame_count, "video/x-h263,variant=(string)itu,"
612 "h263version=(string)h263p, annex-f=(boolean)true, "
613 "annex-j=(boolean)true, annex-i=(boolean)true, annex-t=(boolean)true",
614 "rtph263ppay", "rtph263pdepay", 0, 0, FALSE);
618 static const guint8 rtp_h264_frame_data[] =
619 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
623 static int rtp_h264_frame_data_size = 20;
625 static int rtp_h264_frame_count = 1;
627 GST_START_TEST (rtp_h264)
629 /* FIXME 0.11: fully specify h264 caps (and make payloader check) */
630 rtp_pipeline_test (rtp_h264_frame_data, rtp_h264_frame_data_size,
631 rtp_h264_frame_count,
632 "video/x-h264,stream-format=(string)byte-stream,alignment=(string)nal",
633 "rtph264pay", "rtph264depay", 0, 0, FALSE);
635 /* config-interval property used to be of uint type, was changed to int,
636 * make sure old GValue stuff still works */
638 GValue val = G_VALUE_INIT;
639 GstElement *rtph264pay;
643 rtph264pay = gst_element_factory_make ("rtph264pay", NULL);
644 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (rtph264pay),
646 fail_unless (pspec->value_type == G_TYPE_INT);
647 g_value_init (&val, G_TYPE_UINT);
648 g_value_set_uint (&val, 10);
649 g_object_set_property (G_OBJECT (rtph264pay), "config-interval", &val);
650 g_value_set_uint (&val, 0);
651 g_object_get_property (G_OBJECT (rtph264pay), "config-interval", &val);
652 fail_unless_equals_int (10, g_value_get_uint (&val));
653 g_object_set (G_OBJECT (rtph264pay), "config-interval", -1, NULL);
654 g_object_get_property (G_OBJECT (rtph264pay), "config-interval", &val);
655 fail_unless (g_value_get_uint (&val) == G_MAXUINT);
656 g_value_unset (&val);
657 gst_object_unref (rtph264pay);
663 /* H264 data generated with:
664 * videotestsrc pattern=black ! video/x-raw,width=16,height=16 ! openh264enc */
665 static const guint8 h264_16x16_black_bs[] = {
666 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xd0, 0x0b,
667 0x8c, 0x8d, 0x4e, 0x40, 0x3c, 0x22, 0x11, 0xa8,
668 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x3c, 0x80,
669 0x00, 0x00, 0x00, 0x01, 0x65, 0xb8, 0x00, 0x04,
670 0x00, 0x00, 0x09, 0xe4, 0xc5, 0x00, 0x01, 0x19,
675 rtp_h264depay_run (const gchar * stream_format)
683 gboolean seen_caps = FALSE;
686 h = gst_harness_new_parse ("rtph264pay ! rtph264depay");
688 /* Our input data is in byte-stream format (not that it matters) */
689 in_caps = gst_caps_new_simple ("video/x-h264",
690 "stream-format", G_TYPE_STRING, "byte-stream",
691 "alignment", G_TYPE_STRING, "au",
692 "profile", G_TYPE_STRING, "baseline",
693 "width", G_TYPE_INT, 16,
694 "height", G_TYPE_INT, 16, "framerate", GST_TYPE_FRACTION, 30, 1, NULL);
696 /* Force rtph264depay to output format as requested */
697 out_caps = gst_caps_new_simple ("video/x-h264",
698 "stream-format", G_TYPE_STRING, stream_format,
699 "alignment", G_TYPE_STRING, "au", NULL);
701 gst_harness_set_caps (h, in_caps, out_caps);
705 gst_harness_play (h);
707 size = sizeof (h264_16x16_black_bs);
708 buf = gst_buffer_new_memdup (h264_16x16_black_bs, size);
709 fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
710 fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
712 while ((e = gst_harness_try_pull_event (h))) {
713 if (GST_EVENT_TYPE (e) == GST_EVENT_CAPS) {
714 GstCaps *caps = NULL;
716 gst_event_parse_caps (e, &caps);
717 gst_caps_replace (&out_caps, caps);
722 fail_unless (seen_caps);
724 buf = gst_harness_pull (h);
725 sample = gst_sample_new (buf, out_caps, NULL, NULL);
726 gst_buffer_unref (buf);
727 gst_caps_replace (&out_caps, NULL);
729 gst_harness_teardown (h);
733 GST_START_TEST (rtp_h264depay_avc)
737 GstMapInfo map = GST_MAP_INFO_INIT;
742 s = rtp_h264depay_run ("avc");
744 /* must have codec_data in output caps */
745 caps = gst_sample_get_caps (s);
746 st = gst_caps_get_structure (caps, 0);
747 GST_LOG ("caps: %" GST_PTR_FORMAT, caps);
748 fail_unless (gst_structure_has_field (st, "stream-format"));
749 fail_unless (gst_structure_has_field (st, "alignment"));
750 fail_unless (gst_structure_has_field (st, "level"));
751 fail_unless (gst_structure_has_field (st, "profile"));
752 val = gst_structure_get_value (st, "codec_data");
753 fail_unless (val != NULL);
754 fail_unless (GST_VALUE_HOLDS_BUFFER (val));
755 /* check codec_data, shouldn't contain trailing zeros */
756 buf = gst_value_get_buffer (val);
757 fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
759 guint num_sps, num_pps, len;
762 GST_MEMDUMP ("H.264 codec_data", map.data, map.size);
763 fail_unless_equals_int (map.data[0], 1);
764 num_sps = map.data[5] & 0x1f;
766 fail_unless_equals_int (num_sps, 1);
767 len = GST_READ_UINT16_BE (data);
769 /* make sure there are no trailing zeros in the SPS */
770 fail_unless (data[len - 1] != 0);
773 fail_unless_equals_int (num_pps, 1);
774 len = GST_READ_UINT16_BE (data);
776 /* make sure there are no trailing zeros in the PPS */
777 fail_unless (data[len - 1] != 0);
779 gst_buffer_unmap (buf, &map);
781 buf = gst_sample_get_buffer (s);
782 fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
783 GST_MEMDUMP ("H.264 AVC frame", map.data, map.size);
784 fail_unless (map.size >= 4 + 13);
785 /* Want IDR slice as very first thing.
786 * We assume nal size markers are 4 bytes here. */
787 fail_unless_equals_int (map.data[4] & 0x1f, 5);
788 gst_buffer_unmap (buf, &map);
790 gst_sample_unref (s);
795 GST_START_TEST (rtp_h264depay_bytestream)
799 GstMapInfo map = GST_MAP_INFO_INIT;
807 s = rtp_h264depay_run ("byte-stream");
809 /* must not have codec_data in output caps */
810 caps = gst_sample_get_caps (s);
811 st = gst_caps_get_structure (caps, 0);
812 GST_LOG ("caps: %" GST_PTR_FORMAT, caps);
813 fail_if (gst_structure_has_field (st, "codec_data"));
815 buf = gst_sample_get_buffer (s);
816 fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
817 GST_MEMDUMP ("H.264 byte-stream frame", map.data, map.size);
818 fail_unless (map.size > 40);
819 gst_byte_reader_init (&br, map.data, map.size);
820 /* We assume nal sync markers are 4 bytes... */
821 fail_unless (gst_byte_reader_get_uint32_be (&br, &dw));
822 fail_unless_equals_int (dw, 0x00000001);
823 /* Want SPS as very first thing */
824 fail_unless (gst_byte_reader_get_uint8 (&br, &b));
825 fail_unless_equals_int (b & 0x1f, 7);
826 /* Then, we want the PPS */
827 left = gst_byte_reader_get_remaining (&br);
828 off = gst_byte_reader_masked_scan_uint32 (&br, 0xffffffff, 1, 0, left);
829 fail_if (off == (guint) - 1);
830 gst_byte_reader_skip (&br, off + 4);
831 fail_unless (gst_byte_reader_get_uint8 (&br, &b));
832 fail_unless_equals_int (b & 0x1f, 8);
833 /* FIXME: looks like we get two sets of SPS/PPS ?! */
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 left = gst_byte_reader_get_remaining (&br);
839 off = gst_byte_reader_masked_scan_uint32 (&br, 0xffffffff, 1, 0, left);
840 fail_if (off == (guint) - 1);
841 gst_byte_reader_skip (&br, off + 4);
842 /* Finally, we want an IDR slice */
843 left = gst_byte_reader_get_remaining (&br);
844 off = gst_byte_reader_masked_scan_uint32 (&br, 0xffffffff, 1, 0, left);
845 fail_if (off == (guint) - 1);
846 gst_byte_reader_skip (&br, off + 4);
847 fail_unless (gst_byte_reader_get_uint8 (&br, &b));
848 fail_unless_equals_int (b & 0x1f, 5);
849 gst_buffer_unmap (buf, &map);
851 gst_sample_unref (s);
856 static const guint8 rtp_h264_list_lt_mtu_frame_data[] =
857 /* not packetized, next NAL starts with 0001 */
858 { 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
859 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
860 0xad, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x10
863 static int rtp_h264_list_lt_mtu_frame_data_size = 16;
865 static int rtp_h264_list_lt_mtu_frame_count = 2;
868 /* also 2 bytes FU-A header each time */
869 static int rtp_h264_list_lt_mtu_bytes_sent = (16 - 4);
871 static int rtp_h264_list_lt_mtu_mtu_size = 1024;
873 GST_START_TEST (rtp_h264_list_lt_mtu)
875 /* FIXME 0.11: fully specify h264 caps (and make payloader check) */
876 rtp_pipeline_test (rtp_h264_list_lt_mtu_frame_data,
877 rtp_h264_list_lt_mtu_frame_data_size, rtp_h264_list_lt_mtu_frame_count,
878 "video/x-h264,stream-format=(string)byte-stream,alignment=(string)nal",
879 "rtph264pay aggregate-mode=zero-latency", "rtph264depay",
880 rtp_h264_list_lt_mtu_bytes_sent, rtp_h264_list_lt_mtu_mtu_size, TRUE);
884 static const guint8 rtp_h264_list_lt_mtu_frame_data_avc[] =
885 /* packetized data */
886 { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
887 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
888 0xad, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0d, 0x00
891 /* Only the last NAL of each packet is computed by the strange algorithm in
892 * rtp_pipeline_chain_list()
894 static int rtp_h264_list_lt_mtu_bytes_sent_avc = 7 + 3;
896 //static int rtp_h264_list_lt_mtu_mtu_size = 1024;
898 GST_START_TEST (rtp_h264_list_lt_mtu_avc)
900 /* FIXME 0.11: fully specify h264 caps (and make payloader check) */
901 rtp_pipeline_test (rtp_h264_list_lt_mtu_frame_data_avc,
902 rtp_h264_list_lt_mtu_frame_data_size, rtp_h264_list_lt_mtu_frame_count,
903 "video/x-h264,stream-format=(string)avc,alignment=(string)au,"
904 "codec_data=(buffer)01640014ffe1001867640014acd94141fb0110000003001773594000f142996001000568ebecb22c",
905 "rtph264pay aggregate-mode=zero-latency", "rtph264depay",
906 rtp_h264_list_lt_mtu_bytes_sent_avc, rtp_h264_list_lt_mtu_mtu_size, TRUE);
910 static const guint8 rtp_h264_list_gt_mtu_frame_data[] =
911 /* not packetized, next NAL starts with 0001 */
912 { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
913 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
914 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
915 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
916 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
917 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
920 static int rtp_h264_list_gt_mtu_frame_data_size = 64;
922 static int rtp_h264_list_gt_mtu_frame_count = 1;
924 /* NAL = 4 bytes. When data does not fit into 1 mtu, 1 byte will be skipped */
925 static int rtp_h264_list_gt_mtu_bytes_sent = 1 * (64 - 4) - 1;
927 static int rtp_h264_list_gt_mtu_mty_size = 28;
929 GST_START_TEST (rtp_h264_list_gt_mtu)
931 /* FIXME 0.11: fully specify h264 caps (and make payloader check) */
932 rtp_pipeline_test (rtp_h264_list_gt_mtu_frame_data,
933 rtp_h264_list_gt_mtu_frame_data_size, rtp_h264_list_gt_mtu_frame_count,
934 "video/x-h264,stream-format=(string)byte-stream,alignment=(string)nal",
935 "rtph264pay", "rtph264depay",
936 rtp_h264_list_gt_mtu_bytes_sent, rtp_h264_list_gt_mtu_mty_size, TRUE);
940 static const guint8 rtp_h264_list_gt_mtu_frame_data_avc[] =
941 /* packetized data */
942 { 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
943 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
944 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
945 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
946 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
947 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
950 /* NAL = 4 bytes. When data does not fit into 1 mtu, 1 byte will be skipped */
951 static int rtp_h264_list_gt_mtu_bytes_sent_avc = 1 * (64 - 2 * 4 - 2 * 1);
953 GST_START_TEST (rtp_h264_list_gt_mtu_avc)
955 /* FIXME 0.11: fully specify h264 caps (and make payloader check) */
956 rtp_pipeline_test (rtp_h264_list_gt_mtu_frame_data_avc,
957 rtp_h264_list_gt_mtu_frame_data_size, rtp_h264_list_gt_mtu_frame_count,
958 "video/x-h264,stream-format=(string)avc,alignment=(string)au,"
959 "codec_data=(buffer)01640014ffe1001867640014acd94141fb0110000003001773594000f142996001000568ebecb22c",
960 "rtph264pay", "rtph264depay",
961 rtp_h264_list_gt_mtu_bytes_sent_avc, rtp_h264_list_gt_mtu_mty_size, TRUE);
966 static const guint8 rtp_h265_frame_data[] = {
967 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
968 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
971 static int rtp_h265_frame_data_size = 20;
973 static int rtp_h265_frame_count = 1;
975 GST_START_TEST (rtp_h265)
977 rtp_pipeline_test (rtp_h265_frame_data, rtp_h265_frame_data_size,
978 rtp_h265_frame_count,
979 "video/x-h265,stream-format=(string)byte-stream,alignment=(string)nal",
980 "rtph265pay", "rtph265depay", 0, 0, FALSE);
982 /* config-interval property used to be of uint type, was changed to int,
983 * make sure old GValue stuff still works */
985 GValue val = G_VALUE_INIT;
986 GstElement *rtph265pay;
990 rtph265pay = gst_element_factory_make ("rtph265pay", NULL);
991 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (rtph265pay),
993 fail_unless (pspec->value_type == G_TYPE_INT);
994 g_value_init (&val, G_TYPE_UINT);
995 g_value_set_uint (&val, 10);
996 g_object_set_property (G_OBJECT (rtph265pay), "config-interval", &val);
997 g_value_set_uint (&val, 0);
998 g_object_get_property (G_OBJECT (rtph265pay), "config-interval", &val);
999 fail_unless_equals_int (10, g_value_get_uint (&val));
1000 g_object_set (G_OBJECT (rtph265pay), "config-interval", -1, NULL);
1001 g_object_get_property (G_OBJECT (rtph265pay), "config-interval", &val);
1002 fail_unless (g_value_get_uint (&val) == G_MAXUINT);
1003 g_value_unset (&val);
1004 gst_object_unref (rtph265pay);
1009 static const guint8 rtp_h265_list_lt_mtu_frame_data[] = {
1010 /* not packetized, next NALU starts with 0x00000001 */
1011 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1012 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
1013 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1014 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
1017 static int rtp_h265_list_lt_mtu_frame_data_size = 16;
1019 static int rtp_h265_list_lt_mtu_frame_count = 2;
1021 /* 3 bytes start code prefixed with one zero byte, NALU header is in payload */
1022 static int rtp_h265_list_lt_mtu_bytes_sent = 2 * (16 - 3 - 1);
1024 static int rtp_h265_list_lt_mtu_mtu_size = 1024;
1026 GST_START_TEST (rtp_h265_list_lt_mtu)
1028 rtp_pipeline_test (rtp_h265_list_lt_mtu_frame_data,
1029 rtp_h265_list_lt_mtu_frame_data_size, rtp_h265_list_lt_mtu_frame_count,
1030 "video/x-h265,stream-format=(string)byte-stream,alignment=(string)nal",
1031 "rtph265pay", "rtph265depay", rtp_h265_list_lt_mtu_bytes_sent,
1032 rtp_h265_list_lt_mtu_mtu_size, TRUE);
1036 static const guint8 rtp_h265_list_lt_mtu_frame_data_hvc1[] = {
1037 /* packetized data */
1038 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1039 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1040 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1041 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
1044 /* length size is 3 bytes */
1045 static int rtp_h265_list_lt_mtu_bytes_sent_hvc1 = 4 + 9;
1048 GST_START_TEST (rtp_h265_list_lt_mtu_hvc1)
1050 rtp_pipeline_test (rtp_h265_list_lt_mtu_frame_data_hvc1,
1051 rtp_h265_list_lt_mtu_frame_data_size, rtp_h265_list_lt_mtu_frame_count,
1052 "video/x-h265,stream-format=(string)hvc1,alignment=(string)au,"
1053 "codec_data=(buffer)0101c000000080000000000099f000fcfdf8f800000203a000010"
1054 "01840010c01ffff01c000000300800000030000030099ac0900a10001003042010101c00"
1055 "0000300800000030000030099a00a080f1fe36bbb5377725d602dc040404100000300010"
1056 "00003000a0800a2000100074401c172b02240",
1057 "rtph265pay aggregate-mode=zero-latency", "rtph265depay",
1058 rtp_h265_list_lt_mtu_bytes_sent_hvc1, rtp_h265_list_lt_mtu_mtu_size,
1063 static const guint8 rtp_h265_list_gt_mtu_frame_data[] = {
1064 /* not packetized, next NAL starts with 0x000001 */
1065 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1066 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1067 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1068 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1069 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1070 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1074 static const int rtp_h265_list_gt_mtu_frame_data_size = 62;
1076 static const int rtp_h265_list_gt_mtu_frame_count = 1;
1078 /* start code is 3 bytes, NALU header is 2 bytes */
1079 static int rtp_h265_list_gt_mtu_bytes_sent = 1 * (62 - 3 - 2);
1081 static int rtp_h265_list_gt_mtu_mtu_size = 28;
1083 GST_START_TEST (rtp_h265_list_gt_mtu)
1085 rtp_pipeline_test (rtp_h265_list_gt_mtu_frame_data,
1086 rtp_h265_list_gt_mtu_frame_data_size, rtp_h265_list_gt_mtu_frame_count,
1087 "video/x-h265,stream-format=(string)byte-stream,alignment=(string)nal",
1088 "rtph265pay", "rtph265depay", rtp_h265_list_gt_mtu_bytes_sent,
1089 rtp_h265_list_gt_mtu_mtu_size, TRUE);
1093 static const guint8 rtp_h265_list_gt_mtu_frame_data_hvc1[] = {
1094 /* packetized data */
1095 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1096 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1097 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1098 0x00, 0x00, 0x00, 0x00, 0x00,
1099 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1104 /* length size is 3 bytes, NALU header is 2 bytes */
1105 static int rtp_h265_list_gt_mtu_bytes_sent_hvc1 = 1 * (62 - 2 * 3 - 2 * 2);
1107 GST_START_TEST (rtp_h265_list_gt_mtu_hvc1)
1109 rtp_pipeline_test (rtp_h265_list_gt_mtu_frame_data_hvc1,
1110 rtp_h265_list_gt_mtu_frame_data_size, rtp_h265_list_gt_mtu_frame_count,
1111 "video/x-h265,stream-format=(string)hvc1,alignment=(string)au,"
1112 "codec_data=(buffer)0101c000000080000000000099f000fcfdf8f800000203a000010"
1113 "01840010c01ffff01c000000300800000030000030099ac0900a10001003042010101c00"
1114 "0000300800000030000030099a00a080f1fe36bbb5377725d602dc040404100000300010"
1115 "00003000a0800a2000100074401c172b02240",
1116 "rtph265pay", "rtph265depay", rtp_h265_list_gt_mtu_bytes_sent_hvc1,
1117 rtp_h265_list_gt_mtu_mtu_size, TRUE);
1122 /* KLV data from Day_Flight.mpg */
1123 static const guint8 rtp_KLV_frame_data[] = {
1124 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x0b, 0x01, 0x01,
1125 0x0e, 0x01, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00,
1126 0x81, 0x91, 0x02, 0x08, 0x00, 0x04, 0x6c, 0x8e,
1127 0x20, 0x03, 0x83, 0x85, 0x41, 0x01, 0x01, 0x05,
1128 0x02, 0x3d, 0x3b, 0x06, 0x02, 0x15, 0x80, 0x07,
1129 0x02, 0x01, 0x52, 0x0b, 0x03, 0x45, 0x4f, 0x4e,
1130 0x0c, 0x0e, 0x47, 0x65, 0x6f, 0x64, 0x65, 0x74,
1131 0x69, 0x63, 0x20, 0x57, 0x47, 0x53, 0x38, 0x34,
1132 0x0d, 0x04, 0x4d, 0xc4, 0xdc, 0xbb, 0x0e, 0x04,
1133 0xb1, 0xa8, 0x6c, 0xfe, 0x0f, 0x02, 0x1f, 0x4a,
1134 0x10, 0x02, 0x00, 0x85, 0x11, 0x02, 0x00, 0x4b,
1135 0x12, 0x04, 0x20, 0xc8, 0xd2, 0x7d, 0x13, 0x04,
1136 0xfc, 0xdd, 0x02, 0xd8, 0x14, 0x04, 0xfe, 0xb8,
1137 0xcb, 0x61, 0x15, 0x04, 0x00, 0x8f, 0x3e, 0x61,
1138 0x16, 0x04, 0x00, 0x00, 0x01, 0xc9, 0x17, 0x04,
1139 0x4d, 0xdd, 0x8c, 0x2a, 0x18, 0x04, 0xb1, 0xbe,
1140 0x9e, 0xf4, 0x19, 0x02, 0x0b, 0x85, 0x28, 0x04,
1141 0x4d, 0xdd, 0x8c, 0x2a, 0x29, 0x04, 0xb1, 0xbe,
1142 0x9e, 0xf4, 0x2a, 0x02, 0x0b, 0x85, 0x38, 0x01,
1143 0x2e, 0x39, 0x04, 0x00, 0x8d, 0xd4, 0x29, 0x01,
1147 GST_START_TEST (rtp_klv)
1149 rtp_pipeline_test (rtp_KLV_frame_data, G_N_ELEMENTS (rtp_KLV_frame_data), 1,
1150 "meta/x-klv, parsed=(bool)true", "rtpklvpay", "rtpklvdepay", 0, 0, FALSE);
1155 GST_START_TEST (rtp_klv_fragmented)
1157 /* force super-small mtu of 60 to fragment KLV unit */
1158 rtp_pipeline_test (rtp_KLV_frame_data, sizeof (rtp_KLV_frame_data), 1,
1159 "meta/x-klv, parsed=(bool)true", "rtpklvpay", "rtpklvdepay",
1160 sizeof (rtp_KLV_frame_data), 60, FALSE);
1169 } KlvDepayProbeData;
1171 static GstPadProbeReturn
1172 rtp_klv_do_packet_loss_depay_probe_cb (GstPad * pad, GstPadProbeInfo * info,
1173 KlvDepayProbeData * data)
1175 GstPadProbeReturn ret = GST_PAD_PROBE_OK;
1177 if (info->type & GST_PAD_PROBE_TYPE_BUFFER_LIST) {
1178 GstBufferList *buffer_list = info->data;
1179 gint length = gst_buffer_list_length (buffer_list);
1181 if (data->drop_index >= 0) {
1182 gint drop_offset = data->drop_index - data->buffer_count;
1184 if (0 <= drop_offset && drop_offset < length)
1185 gst_buffer_list_remove (buffer_list, drop_offset, 1);
1188 data->buffer_count += length;
1190 if (data->buffer_count == data->drop_index)
1191 ret = GST_PAD_PROBE_DROP;
1192 data->buffer_count++;
1198 GST_START_TEST (rtp_klv_fragmented_packet_loss)
1200 /* Number of KLV frames to push through the pipeline */
1201 const guint FRAME_COUNT = 5;
1203 /* Repeat frame data */
1204 int frame_data_size = sizeof (rtp_KLV_frame_data);
1205 guint8 *frame_data = malloc (FRAME_COUNT * sizeof (rtp_KLV_frame_data));
1206 for (guint i = 0; i < FRAME_COUNT; i++)
1207 memcpy (frame_data + i * frame_data_size, rtp_KLV_frame_data,
1210 /* Create RTP pipeline. */
1212 rtp_pipeline_create (frame_data, frame_data_size, FRAME_COUNT,
1213 "meta/x-klv, parsed=(bool)true", "rtpklvpay", "rtpklvdepay");
1219 /* Force super-small mtu of 60 to fragment KLV unit (4 fragments per unit) */
1220 g_object_set (p->rtppay, "mtu", 60, NULL);
1222 /* Drop the 7:th fragment on the depayloader's sink pad */
1223 KlvDepayProbeData sink_probe_data = {.buffer_count = 0,.drop_index = 7 };
1224 GstPad *depay_sink = gst_element_get_static_pad (p->rtpdepay, "sink");
1225 gst_pad_add_probe (depay_sink,
1226 GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST,
1227 (GstPadProbeCallback) rtp_klv_do_packet_loss_depay_probe_cb,
1228 &sink_probe_data, NULL);
1229 gst_object_unref (depay_sink);
1231 /* Count buffers on the depayloader's source pad */
1232 KlvDepayProbeData src_probe_data = {.buffer_count = 0,.drop_index = -1 };
1233 GstPad *depay_src = gst_element_get_static_pad (p->rtpdepay, "src");
1234 gst_pad_add_probe (depay_src,
1235 GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST,
1236 (GstPadProbeCallback) rtp_klv_do_packet_loss_depay_probe_cb,
1237 &src_probe_data, NULL);
1238 gst_object_unref (depay_src);
1240 /* Run RTP pipeline. */
1241 rtp_pipeline_run (p);
1243 /* Destroy RTP pipeline. */
1244 rtp_pipeline_destroy (p);
1248 /* We should be able to decode all RTP buffers except for the second one */
1249 g_assert_cmpuint (src_probe_data.buffer_count, ==, FRAME_COUNT - 1);
1254 static const guint8 rtp_L16_frame_data[] =
1255 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1256 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1259 static int rtp_L16_frame_data_size = 20;
1261 static int rtp_L16_frame_count = 1;
1263 GST_START_TEST (rtp_L16)
1265 rtp_pipeline_test (rtp_L16_frame_data, rtp_L16_frame_data_size,
1266 rtp_L16_frame_count,
1267 "audio/x-raw,format=S16BE,rate=1,channels=1,layout=(string)interleaved",
1268 "rtpL16pay", "rtpL16depay", 0, 0, FALSE);
1273 static const guint8 rtp_L24_frame_data[] =
1274 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1278 static int rtp_L24_frame_data_size = 24;
1280 static int rtp_L24_frame_count = 1;
1282 GST_START_TEST (rtp_L24)
1284 rtp_pipeline_test (rtp_L24_frame_data, rtp_L24_frame_data_size,
1285 rtp_L24_frame_count,
1286 "audio/x-raw,format=S24BE,rate=1,channels=1,layout=(string)interleaved",
1287 "rtpL24pay", "rtpL24depay", 0, 0, FALSE);
1291 static const guint8 rtp_mp2t_frame_data[] =
1292 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1296 static int rtp_mp2t_frame_data_size = 20;
1298 static int rtp_mp2t_frame_count = 1;
1300 GST_START_TEST (rtp_mp2t)
1302 rtp_pipeline_test (rtp_mp2t_frame_data, rtp_mp2t_frame_data_size,
1303 rtp_mp2t_frame_count, "video/mpegts,packetsize=188,systemstream=true",
1304 "rtpmp2tpay", "rtpmp2tdepay", 0, 0, FALSE);
1308 static const guint8 rtp_mp4v_frame_data[] =
1309 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1313 static int rtp_mp4v_frame_data_size = 20;
1315 static int rtp_mp4v_frame_count = 1;
1317 GST_START_TEST (rtp_mp4v)
1319 rtp_pipeline_test (rtp_mp4v_frame_data, rtp_mp4v_frame_data_size,
1320 rtp_mp4v_frame_count, "video/mpeg,mpegversion=4,systemstream=false",
1321 "rtpmp4vpay", "rtpmp4vdepay", 0, 0, FALSE);
1325 static const guint8 rtp_mp4v_list_frame_data[] =
1326 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1330 static int rtp_mp4v_list_frame_data_size = 20;
1332 static int rtp_mp4v_list_frame_count = 1;
1334 static int rtp_mp4v_list_bytes_sent = 1 * 20;
1336 GST_START_TEST (rtp_mp4v_list)
1338 rtp_pipeline_test (rtp_mp4v_list_frame_data, rtp_mp4v_list_frame_data_size,
1339 rtp_mp4v_list_frame_count,
1340 "video/mpeg,mpegversion=4,systemstream=false,codec_data=(buffer)000001b001",
1341 "rtpmp4vpay", "rtpmp4vdepay", rtp_mp4v_list_bytes_sent, 0, TRUE);
1345 static const guint8 rtp_mp4g_frame_data[] =
1346 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1350 static int rtp_mp4g_frame_data_size = 20;
1352 static int rtp_mp4g_frame_count = 1;
1354 GST_START_TEST (rtp_mp4g)
1356 rtp_pipeline_test (rtp_mp4g_frame_data, rtp_mp4g_frame_data_size,
1357 rtp_mp4g_frame_count,
1358 "video/mpeg,mpegversion=4,systemstream=false,codec_data=(buffer)000001b001",
1359 "rtpmp4gpay", "rtpmp4gdepay", 0, 0, FALSE);
1363 static const guint8 rtp_theora_frame_data[] =
1364 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1368 static int rtp_theora_frame_data_size = 20;
1370 static int rtp_theora_frame_count = 1;
1372 GST_START_TEST (rtp_theora)
1374 rtp_pipeline_test (rtp_theora_frame_data, rtp_theora_frame_data_size,
1375 rtp_theora_frame_count, "video/x-theora", "rtptheorapay",
1376 "rtptheoradepay", 0, 0, FALSE);
1380 static const guint8 rtp_vorbis_frame_data[] =
1381 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1385 static int rtp_vorbis_frame_data_size = 20;
1387 static int rtp_vorbis_frame_count = 1;
1389 GST_START_TEST (rtp_vorbis)
1391 rtp_pipeline_test (rtp_vorbis_frame_data, rtp_vorbis_frame_data_size,
1392 rtp_vorbis_frame_count, "audio/x-vorbis", "rtpvorbispay",
1393 "rtpvorbisdepay", 0, 0, FALSE);
1398 /* videotestsrc pattern=red ! video/x-raw,width=160,height=120 ! vp8enc */
1399 #define VP8_CAPS "video/x-vp8, profile=(string)0, " \
1400 "streamheader=(buffer)4f5650383001010000a000780000010000010000001e00000001, " \
1401 "width=(int)160, height=(int)120, framerate=(fraction)30/1"
1403 static const guint8 rtp_vp8_frame_data[] = {
1404 0x30, 0x07, 0x00, 0x9d, 0x01, 0x2a, 0xa0, 0x00,
1405 0x78, 0x00, 0x00, 0x47, 0x08, 0x85, 0x85, 0x88,
1406 0x85, 0x84, 0x88, 0x02, 0x02, 0x02, 0x75, 0xaa,
1407 0x03, 0xf8, 0x03, 0xfa, 0x02, 0x06, 0xc3, 0xef,
1408 0x05, 0x10, 0x9c, 0x52, 0xd2, 0xa1, 0x38, 0xa5,
1409 0xa5, 0x42, 0x71, 0x4b, 0x4a, 0x84, 0xe2, 0x96,
1410 0x95, 0x09, 0xc5, 0x2d, 0x2a, 0x13, 0x8a, 0x5a,
1411 0x54, 0x27, 0x14, 0xb4, 0xa8, 0x4e, 0x29, 0x69,
1412 0x50, 0x9b, 0x00, 0xfe, 0xfd, 0x6e, 0xf3, 0xff,
1413 0xe3, 0x99, 0x37, 0x30, 0xc4, 0xff, 0x8e, 0x6d,
1414 0xff, 0xf1, 0x61, 0x3c, 0x0e, 0x28, 0xc8, 0xff,
1418 GST_START_TEST (rtp_vp8)
1420 rtp_pipeline_test (rtp_vp8_frame_data, sizeof (rtp_vp8_frame_data), 1,
1421 VP8_CAPS, "rtpvp8pay", "rtpvp8depay", 0, 0, FALSE);
1426 /* videotestsrc pattern=red ! video/x-raw,width=160,height=120 ! vp9enc */
1427 #define VP9_CAPS "video/x-vp9, profile=(string)0, " \
1428 "width=(int)160, height=(int)120, framerate=(fraction)30/1"
1430 static const guint8 rtp_vp9_frame_data[] = {
1431 0x82, 0x49, 0x83, 0x42, 0x00, 0x09, 0xf0, 0x07,
1432 0x76, 0x00, 0x38, 0x24, 0x1c, 0x18, 0x42, 0x00,
1433 0x00, 0x30, 0x60, 0x00, 0x00, 0x67, 0x3f, 0xff,
1434 0xfe, 0x69, 0x95, 0xff, 0xff, 0xff, 0xfe, 0x99,
1435 0x6b, 0xff, 0xff, 0xff, 0xff, 0x62, 0x98, 0x1d,
1436 0x45, 0x4c, 0x90, 0xc4, 0x70
1439 GST_START_TEST (rtp_vp9)
1441 rtp_pipeline_test (rtp_vp9_frame_data, sizeof (rtp_vp9_frame_data), 1,
1442 VP9_CAPS, "rtpvp9pay", "rtpvp9depay", 0, 0, FALSE);
1447 static const guint8 rtp_jpeg_frame_data[] =
1448 { /* SOF */ 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0x08, 0x00, 0x08,
1449 0x03, 0x00, 0x21, 0x08, 0x01, 0x11, 0x08, 0x02, 0x11, 0x08,
1450 /* DQT */ 0xFF, 0xDB, 0x00, 0x43, 0x08,
1451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1452 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1453 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1454 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1455 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1456 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1457 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1459 /* DATA */ 0x00, 0x00, 0x00, 0x00, 0x00
1462 static int rtp_jpeg_frame_data_size = sizeof (rtp_jpeg_frame_data);
1464 static int rtp_jpeg_frame_count = 1;
1466 GST_START_TEST (rtp_jpeg)
1468 rtp_pipeline_test (rtp_jpeg_frame_data, rtp_jpeg_frame_data_size,
1469 rtp_jpeg_frame_count, "video/x-jpeg,height=640,width=480", "rtpjpegpay",
1470 "rtpjpegdepay", 0, 0, FALSE);
1475 GST_START_TEST (rtp_jpeg_width_greater_than_2040)
1477 rtp_pipeline_test (rtp_jpeg_frame_data, rtp_jpeg_frame_data_size,
1478 rtp_jpeg_frame_count, "video/x-jpeg,height=2048,width=480", "rtpjpegpay",
1479 "rtpjpegdepay", 0, 0, FALSE);
1484 GST_START_TEST (rtp_jpeg_height_greater_than_2040)
1486 rtp_pipeline_test (rtp_jpeg_frame_data, rtp_jpeg_frame_data_size,
1487 rtp_jpeg_frame_count, "video/x-jpeg,height=640,width=2048", "rtpjpegpay",
1488 "rtpjpegdepay", 0, 0, FALSE);
1493 GST_START_TEST (rtp_jpeg_width_and_height_greater_than_2040)
1495 rtp_pipeline_test (rtp_jpeg_frame_data, rtp_jpeg_frame_data_size,
1496 rtp_jpeg_frame_count, "video/x-jpeg,height=2048,width=2048", "rtpjpegpay",
1497 "rtpjpegdepay", 0, 0, FALSE);
1502 static const guint8 rtp_jpeg_list_frame_data[] =
1503 { /* SOF */ 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0x08, 0x00, 0x08,
1504 0x03, 0x00, 0x21, 0x08, 0x01, 0x11, 0x08, 0x02, 0x11, 0x08,
1505 /* DQT */ 0xFF, 0xDB, 0x00, 0x43, 0x08,
1506 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1507 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1508 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1509 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1510 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1511 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1512 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1513 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1514 /* DATA */ 0x00, 0x00, 0x00, 0x00, 0x00
1517 static int rtp_jpeg_list_frame_data_size = sizeof (rtp_jpeg_list_frame_data);
1519 static int rtp_jpeg_list_frame_count = 1;
1521 static int rtp_jpeg_list_bytes_sent = 1 * sizeof (rtp_jpeg_list_frame_data);
1523 GST_START_TEST (rtp_jpeg_list)
1525 rtp_pipeline_test (rtp_jpeg_list_frame_data, rtp_jpeg_list_frame_data_size,
1526 rtp_jpeg_list_frame_count, "video/x-jpeg,height=640,width=480",
1527 "rtpjpegpay", "rtpjpegdepay", rtp_jpeg_list_bytes_sent, 0, TRUE);
1532 GST_START_TEST (rtp_jpeg_list_width_greater_than_2040)
1534 rtp_pipeline_test (rtp_jpeg_list_frame_data, rtp_jpeg_list_frame_data_size,
1535 rtp_jpeg_list_frame_count, "video/x-jpeg,height=2048,width=480",
1536 "rtpjpegpay", "rtpjpegdepay", rtp_jpeg_list_bytes_sent, 0, TRUE);
1541 GST_START_TEST (rtp_jpeg_list_height_greater_than_2040)
1543 rtp_pipeline_test (rtp_jpeg_list_frame_data, rtp_jpeg_list_frame_data_size,
1544 rtp_jpeg_list_frame_count, "video/x-jpeg,height=640,width=2048",
1545 "rtpjpegpay", "rtpjpegdepay", rtp_jpeg_list_bytes_sent, 0, TRUE);
1550 GST_START_TEST (rtp_jpeg_list_width_and_height_greater_than_2040)
1552 rtp_pipeline_test (rtp_jpeg_list_frame_data, rtp_jpeg_list_frame_data_size,
1553 rtp_jpeg_list_frame_count, "video/x-jpeg,height=2048,width=2048",
1554 "rtpjpegpay", "rtpjpegdepay", rtp_jpeg_list_bytes_sent, 0, TRUE);
1560 rtp_jpeg_do_packet_loss (gdouble prob, gint num_expected)
1563 gboolean eos = FALSE;
1565 guint i, buffer_count;
1567 s = g_strdup_printf ("videotestsrc pattern=ball num-buffers=100 ! "
1568 "jpegenc quality=50 ! rtpjpegpay ! identity drop-probability=%g ! "
1569 "rtpjpegdepay", prob);
1570 GST_INFO ("running pipeline %s", s);
1571 h = gst_harness_new_parse (s);
1574 gst_harness_play (h);
1579 event = gst_harness_pull_event (h);
1580 eos = (GST_EVENT_TYPE (event) == GST_EVENT_EOS);
1581 gst_event_unref (event);
1584 buffer_count = gst_harness_buffers_received (h);
1585 GST_INFO ("Got %u buffers", buffer_count);
1587 if (num_expected >= 0) {
1588 fail_unless_equals_int (num_expected, buffer_count);
1591 for (i = 0; i < buffer_count; ++i) {
1596 buf = gst_harness_pull (h);
1597 fail_unless (buf != NULL);
1599 fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
1600 GST_MEMDUMP ("jpeg frame", map.data, map.size);
1601 fail_unless (map.size > 4);
1602 soi = GST_READ_UINT16_BE (map.data);
1603 fail_unless (soi == 0xffd8, "expected JPEG frame start FFD8 not %02X", soi);
1604 eoi = GST_READ_UINT16_BE (map.data + map.size - 2);
1605 fail_unless (eoi == 0xffd9, "expected JPEG frame end FFD9 not %02X", eoi);
1606 gst_buffer_unmap (buf, &map);
1607 gst_buffer_unref (buf);
1610 gst_harness_teardown (h);
1613 GST_START_TEST (rtp_jpeg_packet_loss)
1615 gdouble probabilities[] = { 0.0, 0.001, 0.01, 0.1, 0.2, 0.5, 1.0 };
1616 gint num_expected[] = { 100, -1, -1, -1, -1, -1, 0 };
1618 GST_INFO ("Start iteration %d", __i__);
1619 fail_unless (__i__ < G_N_ELEMENTS (probabilities));
1620 rtp_jpeg_do_packet_loss (probabilities[__i__], num_expected[__i__]);
1621 GST_INFO ("Done with iteration %d", __i__);
1626 static const guint8 rtp_g729_frame_data[] =
1627 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1631 static int rtp_g729_frame_data_size = 22;
1633 static int rtp_g729_frame_count = 1;
1635 GST_START_TEST (rtp_g729)
1637 rtp_pipeline_test (rtp_g729_frame_data, rtp_g729_frame_data_size,
1638 rtp_g729_frame_count, "audio/G729,rate=8000,channels=1", "rtpg729pay",
1639 "rtpg729depay", 0, 0, FALSE);
1644 static const guint8 rtp_gst_frame_data[] =
1645 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1649 static int rtp_gst_frame_data_size = 22;
1651 static int rtp_gst_frame_count = 1;
1653 GST_START_TEST (rtp_gst_custom_event)
1655 /* Create RTP pipeline. */
1657 rtp_pipeline_create (rtp_gst_frame_data, rtp_gst_frame_data_size,
1658 rtp_gst_frame_count, "application/x-test",
1659 "rtpgstpay", "rtpgstdepay");
1666 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
1667 gst_structure_new ("test", "foo", G_TYPE_INT, 1, NULL));
1669 /* Run RTP pipeline. */
1670 rtp_pipeline_run (p);
1672 /* Destroy RTP pipeline. */
1673 rtp_pipeline_destroy (p);
1678 GST_START_TEST (rtp_vorbis_renegotiate)
1680 GstElement *pipeline;
1681 GstElement *enc, *pay, *depay, *dec, *sink;
1682 GstPad *sinkpad, *srcpad;
1683 GstCaps *templcaps, *caps, *filter, *srccaps;
1689 pipeline = gst_pipeline_new (NULL);
1690 enc = gst_element_factory_make ("vorbisenc", NULL);
1691 pay = gst_element_factory_make ("rtpvorbispay", NULL);
1692 depay = gst_element_factory_make ("rtpvorbisdepay", NULL);
1693 dec = gst_element_factory_make ("vorbisdec", NULL);
1694 sink = gst_element_factory_make ("fakesink", NULL);
1695 g_object_set (sink, "async", FALSE, NULL);
1696 gst_bin_add_many (GST_BIN (pipeline), enc, pay, depay, dec, sink, NULL);
1697 fail_unless (gst_element_link_many (enc, pay, depay, dec, sink, NULL));
1698 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
1699 GST_STATE_CHANGE_SUCCESS);
1701 sinkpad = gst_element_get_static_pad (enc, "sink");
1702 srcpad = gst_element_get_static_pad (dec, "src");
1704 templcaps = gst_pad_get_pad_template_caps (sinkpad);
1706 gst_caps_new_simple ("audio/x-raw", "channels", G_TYPE_INT, 2, "rate",
1707 G_TYPE_INT, 44100, NULL);
1708 caps = gst_caps_intersect (templcaps, filter);
1709 caps = gst_caps_fixate (caps);
1711 gst_segment_init (&segment, GST_FORMAT_TIME);
1712 fail_unless (gst_pad_send_event (sinkpad,
1713 gst_event_new_stream_start ("test")));
1714 fail_unless (gst_pad_send_event (sinkpad, gst_event_new_caps (caps)));
1715 fail_unless (gst_pad_send_event (sinkpad, gst_event_new_segment (&segment)));
1717 gst_audio_info_from_caps (&info, caps);
1718 buffer = gst_buffer_new_and_alloc (44100 * info.bpf);
1719 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
1720 gst_audio_format_info_fill_silence (info.finfo, map.data, map.size);
1721 gst_buffer_unmap (buffer, &map);
1722 GST_BUFFER_PTS (buffer) = 0;
1723 GST_BUFFER_DURATION (buffer) = 1 * GST_SECOND;
1725 fail_unless_equals_int (gst_pad_chain (sinkpad, buffer), GST_FLOW_OK);
1727 srccaps = gst_pad_get_current_caps (srcpad);
1728 fail_unless (gst_caps_can_intersect (srccaps, caps));
1729 gst_caps_unref (srccaps);
1731 gst_caps_unref (caps);
1732 gst_caps_unref (filter);
1734 gst_caps_new_simple ("audio/x-raw", "channels", G_TYPE_INT, 2, "rate",
1735 G_TYPE_INT, 48000, NULL);
1736 caps = gst_caps_intersect (templcaps, filter);
1737 caps = gst_caps_fixate (caps);
1739 fail_unless (gst_pad_send_event (sinkpad, gst_event_new_caps (caps)));
1741 gst_audio_info_from_caps (&info, caps);
1742 buffer = gst_buffer_new_and_alloc (48000 * info.bpf);
1743 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
1744 gst_audio_format_info_fill_silence (info.finfo, map.data, map.size);
1745 gst_buffer_unmap (buffer, &map);
1746 GST_BUFFER_PTS (buffer) = 0;
1747 GST_BUFFER_DURATION (buffer) = 1 * GST_SECOND;
1748 GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
1750 fail_unless_equals_int (gst_pad_chain (sinkpad, buffer), GST_FLOW_OK);
1752 srccaps = gst_pad_get_current_caps (srcpad);
1753 fail_unless (gst_caps_can_intersect (srccaps, caps));
1754 gst_caps_unref (srccaps);
1756 gst_caps_unref (caps);
1757 gst_caps_unref (filter);
1758 gst_caps_unref (templcaps);
1759 gst_object_unref (sinkpad);
1760 gst_object_unref (srcpad);
1761 gst_element_set_state (pipeline, GST_STATE_NULL);
1762 gst_object_unref (pipeline);
1768 pull_rtp_buffer (GstHarness * h, gboolean has_marker)
1772 GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
1774 buf = gst_harness_try_pull (h);
1777 fail_unless (gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp));
1778 seq = gst_rtp_buffer_get_seq (&rtp);
1779 gst_rtp_buffer_unmap (&rtp);
1782 fail_unless (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_MARKER));
1784 fail_if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_MARKER));
1786 gst_buffer_unref (buf);
1791 test_rtp_opus_dtx (gboolean dtx)
1795 /* generated with a muted mic using:
1796 * gst-launch-1.0 pulsesrc ! opusenc dtx=true bitrate-type=vbr ! fakesink silent=false dump=true -v
1798 static const guint8 opus_empty[] = { 0xf8 };
1799 static const guint8 opus_frame[] = { 0xf8, 0xff, 0xfe };
1800 guint16 seq, expected_seq;
1802 h = gst_harness_new_parse ("rtpopuspay");
1805 gst_harness_set (h, "rtpopuspay", "dtx", dtx, NULL);
1807 gst_harness_set_caps_str (h,
1808 "audio/x-opus, rate=48000, channels=1, channel-mapping-family=0",
1809 "application/x-rtp, media=audio, clock-rate=48000, encoding-name=OPUS, sprop-stereo=(string)0, encoding-params=(string)2, sprop-maxcapturerate=(string)48000, payload=96");
1811 /* push first opus frame */
1812 buf = gst_buffer_new_memdup (opus_frame, sizeof (opus_frame));
1813 fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
1814 seq = pull_rtp_buffer (h, TRUE);
1815 expected_seq = seq + 1;
1817 /* push empty frame */
1818 buf = gst_buffer_new_memdup (opus_empty, sizeof (opus_empty));
1819 fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
1821 /* buffer is not transmitted if dtx is enabled */
1822 buf = gst_harness_try_pull (h);
1825 seq = pull_rtp_buffer (h, FALSE);
1826 fail_unless_equals_int (seq, expected_seq);
1830 /* push second opus frame */
1831 buf = gst_buffer_new_memdup (opus_frame, sizeof (opus_frame));
1832 fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
1833 seq = pull_rtp_buffer (h, dtx);
1834 fail_unless_equals_int (seq, expected_seq);
1836 gst_harness_teardown (h);
1839 GST_START_TEST (rtp_opus_dtx_disabled)
1841 test_rtp_opus_dtx (FALSE);
1846 GST_START_TEST (rtp_opus_dtx_enabled)
1848 test_rtp_opus_dtx (TRUE);
1854 * Creates the test suite.
1856 * Returns: pointer to the test suite.
1859 rtp_payloading_suite (void)
1861 GstRegistry *registry = gst_registry_get ();
1862 Suite *s = suite_create ("rtp_data_test");
1864 TCase *tc_chain = tcase_create ("linear");
1866 /* Set timeout to 60 seconds. */
1867 tcase_set_timeout (tc_chain, 60);
1869 suite_add_tcase (s, tc_chain);
1870 tcase_add_test (tc_chain, rtp_ilbc);
1871 tcase_add_test (tc_chain, rtp_gsm);
1872 tcase_add_test (tc_chain, rtp_amr);
1873 tcase_add_test (tc_chain, rtp_pcma);
1874 tcase_add_test (tc_chain, rtp_pcmu);
1875 tcase_add_test (tc_chain, rtp_mpa);
1876 tcase_add_test (tc_chain, rtp_h261);
1877 tcase_add_test (tc_chain, rtp_h263);
1878 tcase_add_test (tc_chain, rtp_h263p);
1879 tcase_add_test (tc_chain, rtp_h264);
1880 tcase_add_test (tc_chain, rtp_h264depay_avc);
1881 tcase_add_test (tc_chain, rtp_h264depay_bytestream);
1882 tcase_add_test (tc_chain, rtp_h264_list_lt_mtu);
1883 tcase_add_test (tc_chain, rtp_h264_list_lt_mtu_avc);
1884 tcase_add_test (tc_chain, rtp_h264_list_gt_mtu);
1885 tcase_add_test (tc_chain, rtp_h264_list_gt_mtu_avc);
1886 tcase_add_test (tc_chain, rtp_h265);
1887 tcase_add_test (tc_chain, rtp_h265_list_lt_mtu);
1888 tcase_add_test (tc_chain, rtp_h265_list_lt_mtu_hvc1);
1889 tcase_add_test (tc_chain, rtp_h265_list_gt_mtu);
1890 tcase_add_test (tc_chain, rtp_h265_list_gt_mtu_hvc1);
1891 tcase_add_test (tc_chain, rtp_klv);
1892 tcase_add_test (tc_chain, rtp_klv_fragmented);
1893 tcase_add_test (tc_chain, rtp_klv_fragmented_packet_loss);
1894 tcase_add_test (tc_chain, rtp_L16);
1895 tcase_add_test (tc_chain, rtp_L24);
1896 tcase_add_test (tc_chain, rtp_mp2t);
1897 tcase_add_test (tc_chain, rtp_mp4v);
1898 tcase_add_test (tc_chain, rtp_mp4v_list);
1899 tcase_add_test (tc_chain, rtp_mp4g);
1900 tcase_add_test (tc_chain, rtp_theora);
1901 tcase_add_test (tc_chain, rtp_vorbis);
1902 tcase_add_test (tc_chain, rtp_vp8);
1903 tcase_add_test (tc_chain, rtp_vp9);
1904 tcase_add_test (tc_chain, rtp_jpeg);
1905 tcase_add_test (tc_chain, rtp_jpeg_width_greater_than_2040);
1906 tcase_add_test (tc_chain, rtp_jpeg_height_greater_than_2040);
1907 tcase_add_test (tc_chain, rtp_jpeg_width_and_height_greater_than_2040);
1908 tcase_add_test (tc_chain, rtp_jpeg_list);
1909 tcase_add_test (tc_chain, rtp_jpeg_list_width_greater_than_2040);
1910 tcase_add_test (tc_chain, rtp_jpeg_list_height_greater_than_2040);
1911 tcase_add_test (tc_chain, rtp_jpeg_list_width_and_height_greater_than_2040);
1912 if (gst_registry_check_feature_version (registry, "jpegenc", 1, 0, 0)
1913 && gst_registry_check_feature_version (registry, "videotestsrc", 1, 0, 0))
1914 tcase_add_loop_test (tc_chain, rtp_jpeg_packet_loss, 0, 7);
1915 tcase_add_test (tc_chain, rtp_g729);
1916 tcase_add_test (tc_chain, rtp_gst_custom_event);
1917 tcase_add_test (tc_chain, rtp_vorbis_renegotiate);
1918 tcase_add_test (tc_chain, rtp_opus_dtx_disabled);
1919 tcase_add_test (tc_chain, rtp_opus_dtx_enabled);
1923 GST_CHECK_MAIN (rtp_payloading)