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.
20 #include <gst/check/gstcheck.h>
21 #include <gst/check/gstharness.h>
22 #include <gst/audio/audio.h>
23 #include <gst/base/base.h>
24 #include <gst/rtp/gstrtpbuffer.h>
27 #define RELEASE_ELEMENT(x) if(x) {gst_object_unref(x); x = NULL;}
32 * RTP pipeline structure to store the required elements.
41 const guint8 *frame_data;
44 GstEvent *custom_event;
48 * Number of bytes received in the chain list function when using buffer lists
50 static guint chain_list_bytes_received;
53 * Chain list function for testing buffer lists
56 rtp_pipeline_chain_list (GstPad * pad, GstObject * parent, GstBufferList * list)
62 * Count the size of the payload in the buffer list.
64 len = gst_buffer_list_length (list);
65 GST_LOG ("list length %u", len);
67 /* Loop through all buffers */
68 for (i = 0; i < len; i++) {
73 paybuf = gst_buffer_list_get (list, i);
74 /* only count real data which is expected in last memory block */
75 GST_LOG ("n_memory %d", gst_buffer_n_memory (paybuf));
76 fail_unless (gst_buffer_n_memory (paybuf) > 1);
77 mem = gst_buffer_get_memory_range (paybuf, gst_buffer_n_memory (paybuf) - 1,
79 size = gst_memory_get_sizes (mem, NULL, NULL);
80 gst_memory_unref (mem);
81 chain_list_bytes_received += size;
82 GST_LOG ("size %d, total %u", size, chain_list_bytes_received);
84 gst_buffer_list_unref (list);
90 rtp_pipeline_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
94 list = gst_buffer_list_new_sized (1);
95 gst_buffer_list_add (list, buf);
96 return rtp_pipeline_chain_list (pad, parent, list);
103 rtp_bus_callback (GstBus * bus, GstMessage * message, gpointer data)
105 GMainLoop *mainloop = (GMainLoop *) data;
107 switch (GST_MESSAGE_TYPE (message)) {
108 case GST_MESSAGE_ERROR:
116 element_name = (message->src) ? gst_object_get_name (message->src) : NULL;
117 gst_message_parse_error (message, &err, &debug);
118 g_print ("\nError from element %s: %s\n%s\n\n",
119 GST_STR_NULL (element_name), err->message, (debug) ? debug : "");
122 g_free (element_name);
124 fail_if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR);
126 g_main_loop_quit (mainloop);
130 case GST_MESSAGE_EOS:
132 g_main_loop_quit (mainloop);
147 * Creates a RTP pipeline for one test.
148 * @param frame_data Pointer to the frame data which is used to pass through pay/depayloaders.
149 * @param frame_data_size Frame data size in bytes.
150 * @param frame_count Frame count.
151 * @param filtercaps Caps filters.
152 * @param pay Payloader name.
153 * @param depay Depayloader name.
155 * Returns pointer to the RTP pipeline.
156 * The user must free the RTP pipeline when it's not used anymore.
158 static rtp_pipeline *
159 rtp_pipeline_create (const guint8 * frame_data, int frame_data_size,
160 int frame_count, const char *filtercaps, const char *pay, const char *depay)
162 gchar *pipeline_name;
166 /* Check parameters. */
167 if (!frame_data || !pay || !depay) {
171 /* Allocate memory for the RTP pipeline. */
172 p = (rtp_pipeline *) malloc (sizeof (rtp_pipeline));
174 p->frame_data = frame_data;
175 p->frame_data_size = frame_data_size;
176 p->frame_count = frame_count;
177 p->custom_event = NULL;
179 /* Create elements. */
180 pipeline_name = g_strdup_printf ("%s-%s-pipeline", pay, depay);
181 p->pipeline = gst_pipeline_new (pipeline_name);
182 g_free (pipeline_name);
183 p->appsrc = gst_element_factory_make ("appsrc", NULL);
185 gst_parse_bin_from_description_full (pay, TRUE, NULL,
186 GST_PARSE_FLAG_NO_SINGLE_ELEMENT_BINS, NULL);
188 gst_parse_bin_from_description_full (depay, TRUE, NULL,
189 GST_PARSE_FLAG_NO_SINGLE_ELEMENT_BINS, NULL);
190 p->fakesink = gst_element_factory_make ("fakesink", NULL);
192 /* One or more elements are not created successfully or failed to create p? */
193 if (!p->pipeline || !p->appsrc || !p->rtppay || !p->rtpdepay || !p->fakesink) {
194 /* Release created elements. */
195 RELEASE_ELEMENT (p->pipeline);
196 RELEASE_ELEMENT (p->appsrc);
197 RELEASE_ELEMENT (p->rtppay);
198 RELEASE_ELEMENT (p->rtpdepay);
199 RELEASE_ELEMENT (p->fakesink);
201 /* Release allocated memory. */
207 /* Set src properties. */
208 caps = gst_caps_from_string (filtercaps);
209 g_object_set (p->appsrc, "do-timestamp", TRUE, "caps", caps,
210 "format", GST_FORMAT_TIME, NULL);
211 gst_caps_unref (caps);
213 /* Add elements to the pipeline. */
214 gst_bin_add (GST_BIN (p->pipeline), p->appsrc);
215 gst_bin_add (GST_BIN (p->pipeline), p->rtppay);
216 gst_bin_add (GST_BIN (p->pipeline), p->rtpdepay);
217 gst_bin_add (GST_BIN (p->pipeline), p->fakesink);
220 gst_element_link (p->appsrc, p->rtppay);
221 gst_element_link (p->rtppay, p->rtpdepay);
222 gst_element_link (p->rtpdepay, p->fakesink);
228 * Destroys the RTP pipeline.
229 * @param p Pointer to the RTP pipeline.
232 rtp_pipeline_destroy (rtp_pipeline * p)
234 /* Check parameters. */
239 /* Release pipeline. */
240 RELEASE_ELEMENT (p->pipeline);
242 /* Release allocated memory. */
246 static GstPadProbeReturn
247 pay_event_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
249 rtp_pipeline *p = (rtp_pipeline *) user_data;
250 GstEvent *event = GST_PAD_PROBE_INFO_DATA (info);
252 if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM) {
253 const GstStructure *s0 = gst_event_get_structure (p->custom_event);
254 const GstStructure *s1 = gst_event_get_structure (event);
255 if (gst_structure_is_equal (s0, s1)) {
256 return GST_PAD_PROBE_DROP;
260 return GST_PAD_PROBE_OK;
263 static GstPadProbeReturn
264 depay_event_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
266 rtp_pipeline *p = (rtp_pipeline *) user_data;
267 GstEvent *event = GST_PAD_PROBE_INFO_DATA (info);
269 if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM) {
270 const GstStructure *s0 = gst_event_get_structure (p->custom_event);
271 const GstStructure *s1 = gst_event_get_structure (event);
272 if (gst_structure_is_equal (s0, s1)) {
273 gst_event_unref (p->custom_event);
274 p->custom_event = NULL;
278 return GST_PAD_PROBE_OK;
282 * Runs the RTP pipeline.
283 * @param p Pointer to the RTP pipeline.
286 rtp_pipeline_run (rtp_pipeline * p)
288 GstFlowReturn flow_ret;
289 GMainLoop *mainloop = NULL;
293 /* Check parameters. */
298 /* Create mainloop. */
299 mainloop = g_main_loop_new (NULL, FALSE);
304 /* Add bus callback. */
305 bus = gst_pipeline_get_bus (GST_PIPELINE (p->pipeline));
307 gst_bus_add_watch (bus, rtp_bus_callback, (gpointer) mainloop);
309 /* Set pipeline to PLAYING. */
310 gst_element_set_state (p->pipeline, GST_STATE_PLAYING);
312 /* Push custom event into the pipeline */
313 if (p->custom_event) {
316 /* Install a probe to drop the event after it being serialized */
317 srcpad = gst_element_get_static_pad (p->rtppay, "src");
318 gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
319 pay_event_probe_cb, p, NULL);
320 gst_object_unref (srcpad);
322 /* Install a probe to trace the deserialized event after depayloading */
323 srcpad = gst_element_get_static_pad (p->rtpdepay, "src");
324 gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
325 depay_event_probe_cb, p, NULL);
326 gst_object_unref (srcpad);
328 gst_element_send_event (p->appsrc, gst_event_ref (p->custom_event));
331 /* Push data into the pipeline */
332 for (i = 0; i < LOOP_COUNT; i++) {
333 const guint8 *data = p->frame_data;
335 for (j = 0; j < p->frame_count; j++) {
339 gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
340 (guint8 *) data, p->frame_data_size, 0, p->frame_data_size, NULL,
343 g_signal_emit_by_name (p->appsrc, "push-buffer", buf, &flow_ret);
344 fail_unless_equals_int (flow_ret, GST_FLOW_OK);
345 data += p->frame_data_size;
347 gst_buffer_unref (buf);
351 g_signal_emit_by_name (p->appsrc, "end-of-stream", &flow_ret);
354 g_main_loop_run (mainloop);
356 /* Set pipeline to NULL. */
357 gst_element_set_state (p->pipeline, GST_STATE_NULL);
359 /* Release mainloop. */
360 g_main_loop_unref (mainloop);
362 gst_bus_remove_watch (bus);
363 gst_object_unref (bus);
365 fail_if (p->custom_event);
369 * Enables buffer lists and adds a chain_list_function to the depayloader.
370 * @param p Pointer to the RTP pipeline.
373 rtp_pipeline_enable_lists (rtp_pipeline * p)
377 /* Add chain list function for the buffer list tests */
378 pad = gst_element_get_static_pad (p->rtpdepay, "sink");
379 gst_pad_set_chain_list_function (pad,
380 GST_DEBUG_FUNCPTR (rtp_pipeline_chain_list));
381 /* .. to satisfy this silly test code in case someone dares push a buffer */
382 gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (rtp_pipeline_chain));
383 gst_object_unref (pad);
387 * Creates the RTP pipeline and runs the test using the pipeline.
388 * @param frame_data Pointer to the frame data which is used to pass through pay/depayloaders.
389 * @param frame_data_size Frame data size in bytes.
390 * @param frame_count Frame count.
391 * @param filtercaps Caps filters.
392 * @param pay Payloader name.
393 * @param depay Depayloader name.
394 * @bytes_sent bytes that will be sent, used when testing buffer lists
395 * @mtu_size set mtu size when testing lists
396 * @use_lists enable buffer lists
399 rtp_pipeline_test (const guint8 * frame_data, int frame_data_size,
400 int frame_count, const char *filtercaps, const char *pay, const char *depay,
401 guint bytes_sent, guint mtu_size, gboolean use_lists)
403 /* Create RTP pipeline. */
405 rtp_pipeline_create (frame_data, frame_data_size, frame_count, filtercaps,
412 /* set mtu size if needed */
414 g_object_set (p->rtppay, "mtu", mtu_size, NULL);
418 rtp_pipeline_enable_lists (p);
419 chain_list_bytes_received = 0;
422 /* Run RTP pipeline. */
423 rtp_pipeline_run (p);
425 /* Destroy RTP pipeline. */
426 rtp_pipeline_destroy (p);
429 /* 'next NAL' indicator is 4 bytes */
430 fail_unless_equals_int (chain_list_bytes_received, bytes_sent * LOOP_COUNT);
434 static const guint8 rtp_ilbc_frame_data[] =
435 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
439 static int rtp_ilbc_frame_data_size = 20;
441 static int rtp_ilbc_frame_count = 1;
443 GST_START_TEST (rtp_ilbc)
445 rtp_pipeline_test (rtp_ilbc_frame_data, rtp_ilbc_frame_data_size,
446 rtp_ilbc_frame_count, "audio/x-iLBC,mode=20", "rtpilbcpay",
447 "rtpilbcdepay", 0, 0, FALSE);
451 static const guint8 rtp_gsm_frame_data[] =
452 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
453 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
456 static int rtp_gsm_frame_data_size = 20;
458 static int rtp_gsm_frame_count = 1;
460 GST_START_TEST (rtp_gsm)
462 rtp_pipeline_test (rtp_gsm_frame_data, rtp_gsm_frame_data_size,
463 rtp_gsm_frame_count, "audio/x-gsm,rate=8000,channels=1", "rtpgsmpay",
464 "rtpgsmdepay", 0, 0, FALSE);
468 static const guint8 rtp_amr_frame_data[] =
469 { 0x3c, 0x24, 0x03, 0xb3, 0x48, 0x10, 0x68, 0x46, 0x6c, 0xec, 0x03,
470 0x7a, 0x37, 0x16, 0x41, 0x41, 0xc0, 0x00, 0x0d, 0xcd, 0x12, 0xed,
471 0xad, 0x80, 0x00, 0x00, 0x11, 0x31, 0x00, 0x00, 0x0d, 0xa0
474 static int rtp_amr_frame_data_size = 32;
476 static int rtp_amr_frame_count = 1;
478 GST_START_TEST (rtp_amr)
480 rtp_pipeline_test (rtp_amr_frame_data, rtp_amr_frame_data_size,
481 rtp_amr_frame_count, "audio/AMR,channels=1,rate=8000", "rtpamrpay",
482 "rtpamrdepay", 0, 0, FALSE);
486 static const guint8 rtp_pcma_frame_data[] =
487 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
491 static int rtp_pcma_frame_data_size = 20;
493 static int rtp_pcma_frame_count = 1;
495 GST_START_TEST (rtp_pcma)
497 rtp_pipeline_test (rtp_pcma_frame_data, rtp_pcma_frame_data_size,
498 rtp_pcma_frame_count, "audio/x-alaw,channels=1,rate=8000", "rtppcmapay",
499 "rtppcmadepay", 0, 0, FALSE);
503 static const guint8 rtp_pcmu_frame_data[] =
504 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
508 static int rtp_pcmu_frame_data_size = 20;
510 static int rtp_pcmu_frame_count = 1;
512 GST_START_TEST (rtp_pcmu)
514 rtp_pipeline_test (rtp_pcmu_frame_data, rtp_pcmu_frame_data_size,
515 rtp_pcmu_frame_count, "audio/x-mulaw,channels=1,rate=8000", "rtppcmupay",
516 "rtppcmudepay", 0, 0, FALSE);
520 static const guint8 rtp_mpa_frame_data[] =
521 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
522 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
525 static int rtp_mpa_frame_data_size = 20;
527 static int rtp_mpa_frame_count = 1;
529 GST_START_TEST (rtp_mpa)
531 rtp_pipeline_test (rtp_mpa_frame_data, rtp_mpa_frame_data_size,
532 rtp_mpa_frame_count, "audio/mpeg,mpegversion=1", "rtpmpapay",
533 "rtpmpadepay", 0, 0, FALSE);
538 static const guint8 rtp_h261_frame_data[] = {
539 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x11, 0x00, 0x00, 0x4c, 0x40, 0x00,
543 static int rtp_h261_frame_data_size = 14;
544 static int rtp_h261_frame_count = 1;
546 GST_START_TEST (rtp_h261)
548 rtp_pipeline_test (rtp_h261_frame_data, rtp_h261_frame_data_size,
549 rtp_h261_frame_count, "video/x-h261", "rtph261pay", "rtph261depay",
555 static const guint8 rtp_h263_frame_data[] =
556 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
560 static int rtp_h263_frame_data_size = 20;
562 static int rtp_h263_frame_count = 1;
564 GST_START_TEST (rtp_h263)
566 rtp_pipeline_test (rtp_h263_frame_data, rtp_h263_frame_data_size,
567 rtp_h263_frame_count,
568 "video/x-h263,variant=(string)itu,h263version=h263",
569 "rtph263pay", "rtph263depay", 0, 0, FALSE);
570 rtp_pipeline_test (rtp_h263_frame_data, rtp_h263_frame_data_size,
571 rtp_h263_frame_count,
572 "video/x-h263,variant=(string)itu,h263version=h263,width=10,height=20",
573 "rtph263pay", "rtph263depay", 0, 0, FALSE);
577 static const guint8 rtp_h263p_frame_data[] =
578 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
582 static int rtp_h263p_frame_data_size = 20;
584 static int rtp_h263p_frame_count = 1;
586 GST_START_TEST (rtp_h263p)
588 rtp_pipeline_test (rtp_h263p_frame_data, rtp_h263p_frame_data_size,
589 rtp_h263p_frame_count, "video/x-h263,variant=(string)itu,"
590 "h263version=(string)h263", "rtph263ppay", "rtph263pdepay", 0, 0, FALSE);
592 /* payloader should accept any input that matches the template caps
593 * if there's just a udpsink or fakesink downstream */
594 rtp_pipeline_test (rtp_h263p_frame_data, rtp_h263p_frame_data_size,
595 rtp_h263p_frame_count, "video/x-h263,variant=(string)itu,"
596 "h263version=(string)h263", "rtph263ppay", "identity", 0, 0, FALSE);
598 /* default output of avenc_h263p */
599 rtp_pipeline_test (rtp_h263p_frame_data, rtp_h263p_frame_data_size,
600 rtp_h263p_frame_count, "video/x-h263,variant=(string)itu,"
601 "h263version=(string)h263p, annex-f=(boolean)true, "
602 "annex-j=(boolean)true, annex-i=(boolean)true, annex-t=(boolean)true",
603 "rtph263ppay", "identity", 0, 0, FALSE);
605 /* pay ! depay should also work with any input */
606 rtp_pipeline_test (rtp_h263p_frame_data, rtp_h263p_frame_data_size,
607 rtp_h263p_frame_count, "video/x-h263,variant=(string)itu,"
608 "h263version=(string)h263p, annex-f=(boolean)true, "
609 "annex-j=(boolean)true, annex-i=(boolean)true, annex-t=(boolean)true",
610 "rtph263ppay", "rtph263pdepay", 0, 0, FALSE);
614 static const guint8 rtp_h264_frame_data[] =
615 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
616 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
619 static int rtp_h264_frame_data_size = 20;
621 static int rtp_h264_frame_count = 1;
623 GST_START_TEST (rtp_h264)
625 /* FIXME 0.11: fully specify h264 caps (and make payloader check) */
626 rtp_pipeline_test (rtp_h264_frame_data, rtp_h264_frame_data_size,
627 rtp_h264_frame_count,
628 "video/x-h264,stream-format=(string)byte-stream,alignment=(string)nal",
629 "rtph264pay", "rtph264depay", 0, 0, FALSE);
631 /* config-interval property used to be of uint type, was changed to int,
632 * make sure old GValue stuff still works */
634 GValue val = G_VALUE_INIT;
635 GstElement *rtph264pay;
639 rtph264pay = gst_element_factory_make ("rtph264pay", NULL);
640 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (rtph264pay),
642 fail_unless (pspec->value_type == G_TYPE_INT);
643 g_value_init (&val, G_TYPE_UINT);
644 g_value_set_uint (&val, 10);
645 g_object_set_property (G_OBJECT (rtph264pay), "config-interval", &val);
646 g_value_set_uint (&val, 0);
647 g_object_get_property (G_OBJECT (rtph264pay), "config-interval", &val);
648 fail_unless_equals_int (10, g_value_get_uint (&val));
649 g_object_set (G_OBJECT (rtph264pay), "config-interval", -1, NULL);
650 g_object_get_property (G_OBJECT (rtph264pay), "config-interval", &val);
651 fail_unless (g_value_get_uint (&val) == G_MAXUINT);
652 g_value_unset (&val);
653 gst_object_unref (rtph264pay);
659 /* H264 data generated with:
660 * videotestsrc pattern=black ! video/x-raw,width=16,height=16 ! openh264enc */
661 static const guint8 h264_16x16_black_bs[] = {
662 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xd0, 0x0b,
663 0x8c, 0x8d, 0x4e, 0x40, 0x3c, 0x22, 0x11, 0xa8,
664 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x3c, 0x80,
665 0x00, 0x00, 0x00, 0x01, 0x65, 0xb8, 0x00, 0x04,
666 0x00, 0x00, 0x09, 0xe4, 0xc5, 0x00, 0x01, 0x19,
671 rtp_h264depay_run (const gchar * stream_format)
679 gboolean seen_caps = FALSE;
682 h = gst_harness_new_parse ("rtph264pay ! rtph264depay");
684 /* Our input data is in byte-stream format (not that it matters) */
685 in_caps = gst_caps_new_simple ("video/x-h264",
686 "stream-format", G_TYPE_STRING, "byte-stream",
687 "alignment", G_TYPE_STRING, "au",
688 "profile", G_TYPE_STRING, "baseline",
689 "width", G_TYPE_INT, 16,
690 "height", G_TYPE_INT, 16, "framerate", GST_TYPE_FRACTION, 30, 1, NULL);
692 /* Force rtph264depay to output format as requested */
693 out_caps = gst_caps_new_simple ("video/x-h264",
694 "stream-format", G_TYPE_STRING, stream_format,
695 "alignment", G_TYPE_STRING, "au", NULL);
697 gst_harness_set_caps (h, in_caps, out_caps);
701 gst_harness_play (h);
703 size = sizeof (h264_16x16_black_bs);
704 buf = gst_buffer_new_wrapped (g_memdup (h264_16x16_black_bs, size), size);
705 fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
706 fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));
708 while ((e = gst_harness_try_pull_event (h))) {
709 if (GST_EVENT_TYPE (e) == GST_EVENT_CAPS) {
710 GstCaps *caps = NULL;
712 gst_event_parse_caps (e, &caps);
713 gst_caps_replace (&out_caps, caps);
718 fail_unless (seen_caps);
720 buf = gst_harness_pull (h);
721 sample = gst_sample_new (buf, out_caps, NULL, NULL);
722 gst_buffer_unref (buf);
723 gst_caps_replace (&out_caps, NULL);
725 gst_harness_teardown (h);
729 GST_START_TEST (rtp_h264depay_avc)
733 GstMapInfo map = GST_MAP_INFO_INIT;
738 s = rtp_h264depay_run ("avc");
740 /* must have codec_data in output caps */
741 caps = gst_sample_get_caps (s);
742 st = gst_caps_get_structure (caps, 0);
743 GST_LOG ("caps: %" GST_PTR_FORMAT, caps);
744 fail_unless (gst_structure_has_field (st, "stream-format"));
745 fail_unless (gst_structure_has_field (st, "alignment"));
746 fail_unless (gst_structure_has_field (st, "level"));
747 fail_unless (gst_structure_has_field (st, "profile"));
748 val = gst_structure_get_value (st, "codec_data");
749 fail_unless (val != NULL);
750 fail_unless (GST_VALUE_HOLDS_BUFFER (val));
751 /* check codec_data, shouldn't contain trailing zeros */
752 buf = gst_value_get_buffer (val);
753 fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
755 guint num_sps, num_pps, len;
758 GST_MEMDUMP ("H.264 codec_data", map.data, map.size);
759 fail_unless_equals_int (map.data[0], 1);
760 num_sps = map.data[5] & 0x1f;
762 fail_unless_equals_int (num_sps, 1);
763 len = GST_READ_UINT16_BE (data);
765 /* make sure there are no trailing zeros in the SPS */
766 fail_unless (data[len - 1] != 0);
769 fail_unless_equals_int (num_pps, 1);
770 len = GST_READ_UINT16_BE (data);
772 /* make sure there are no trailing zeros in the PPS */
773 fail_unless (data[len - 1] != 0);
775 gst_buffer_unmap (buf, &map);
777 buf = gst_sample_get_buffer (s);
778 fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
779 GST_MEMDUMP ("H.264 AVC frame", map.data, map.size);
780 fail_unless (map.size >= 4 + 13);
781 /* Want IDR slice as very first thing.
782 * We assume nal size markers are 4 bytes here. */
783 fail_unless_equals_int (map.data[4] & 0x1f, 5);
784 gst_buffer_unmap (buf, &map);
786 gst_sample_unref (s);
791 GST_START_TEST (rtp_h264depay_bytestream)
795 GstMapInfo map = GST_MAP_INFO_INIT;
803 s = rtp_h264depay_run ("byte-stream");
805 /* must not have codec_data in output caps */
806 caps = gst_sample_get_caps (s);
807 st = gst_caps_get_structure (caps, 0);
808 GST_LOG ("caps: %" GST_PTR_FORMAT, caps);
809 fail_if (gst_structure_has_field (st, "codec_data"));
811 buf = gst_sample_get_buffer (s);
812 fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
813 GST_MEMDUMP ("H.264 byte-stream frame", map.data, map.size);
814 fail_unless (map.size > 40);
815 gst_byte_reader_init (&br, map.data, map.size);
816 /* We assume nal sync markers are 4 bytes... */
817 fail_unless (gst_byte_reader_get_uint32_be (&br, &dw));
818 fail_unless_equals_int (dw, 0x00000001);
819 /* Want SPS as very first thing */
820 fail_unless (gst_byte_reader_get_uint8 (&br, &b));
821 fail_unless_equals_int (b & 0x1f, 7);
822 /* Then, we want the PPS */
823 left = gst_byte_reader_get_remaining (&br);
824 off = gst_byte_reader_masked_scan_uint32 (&br, 0xffffffff, 1, 0, left);
825 fail_if (off == (guint) - 1);
826 gst_byte_reader_skip (&br, off + 4);
827 fail_unless (gst_byte_reader_get_uint8 (&br, &b));
828 fail_unless_equals_int (b & 0x1f, 8);
829 /* FIXME: looks like we get two sets of SPS/PPS ?! */
830 left = gst_byte_reader_get_remaining (&br);
831 off = gst_byte_reader_masked_scan_uint32 (&br, 0xffffffff, 1, 0, left);
832 fail_if (off == (guint) - 1);
833 gst_byte_reader_skip (&br, off + 4);
834 left = gst_byte_reader_get_remaining (&br);
835 off = gst_byte_reader_masked_scan_uint32 (&br, 0xffffffff, 1, 0, left);
836 fail_if (off == (guint) - 1);
837 gst_byte_reader_skip (&br, off + 4);
838 /* Finally, we want an IDR slice */
839 left = gst_byte_reader_get_remaining (&br);
840 off = gst_byte_reader_masked_scan_uint32 (&br, 0xffffffff, 1, 0, left);
841 fail_if (off == (guint) - 1);
842 gst_byte_reader_skip (&br, off + 4);
843 fail_unless (gst_byte_reader_get_uint8 (&br, &b));
844 fail_unless_equals_int (b & 0x1f, 5);
845 gst_buffer_unmap (buf, &map);
847 gst_sample_unref (s);
852 static const guint8 rtp_h264_list_lt_mtu_frame_data[] =
853 /* not packetized, next NAL starts with 0001 */
854 { 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
855 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
856 0xad, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x10
859 static int rtp_h264_list_lt_mtu_frame_data_size = 16;
861 static int rtp_h264_list_lt_mtu_frame_count = 2;
864 /* also 2 bytes FU-A header each time */
865 static int rtp_h264_list_lt_mtu_bytes_sent = (16 - 4);
867 static int rtp_h264_list_lt_mtu_mtu_size = 1024;
869 GST_START_TEST (rtp_h264_list_lt_mtu)
871 /* FIXME 0.11: fully specify h264 caps (and make payloader check) */
872 rtp_pipeline_test (rtp_h264_list_lt_mtu_frame_data,
873 rtp_h264_list_lt_mtu_frame_data_size, rtp_h264_list_lt_mtu_frame_count,
874 "video/x-h264,stream-format=(string)byte-stream,alignment=(string)nal",
875 "rtph264pay aggregate-mode=zero-latency", "rtph264depay",
876 rtp_h264_list_lt_mtu_bytes_sent, rtp_h264_list_lt_mtu_mtu_size, TRUE);
880 static const guint8 rtp_h264_list_lt_mtu_frame_data_avc[] =
881 /* packetized data */
882 { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
883 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
884 0xad, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0d, 0x00
887 /* Only the last NAL of each packet is computed by the strange algorithm in
888 * rtp_pipeline_chain_list()
890 static int rtp_h264_list_lt_mtu_bytes_sent_avc = 7 + 3;
892 //static int rtp_h264_list_lt_mtu_mtu_size = 1024;
894 GST_START_TEST (rtp_h264_list_lt_mtu_avc)
896 /* FIXME 0.11: fully specify h264 caps (and make payloader check) */
897 rtp_pipeline_test (rtp_h264_list_lt_mtu_frame_data_avc,
898 rtp_h264_list_lt_mtu_frame_data_size, rtp_h264_list_lt_mtu_frame_count,
899 "video/x-h264,stream-format=(string)avc,alignment=(string)au,"
900 "codec_data=(buffer)01640014ffe1001867640014acd94141fb0110000003001773594000f142996001000568ebecb22c",
901 "rtph264pay aggregate-mode=zero-latency", "rtph264depay",
902 rtp_h264_list_lt_mtu_bytes_sent_avc, rtp_h264_list_lt_mtu_mtu_size, TRUE);
906 static const guint8 rtp_h264_list_gt_mtu_frame_data[] =
907 /* not packetized, next NAL starts with 0001 */
908 { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
909 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
910 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
911 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
912 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
913 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
916 static int rtp_h264_list_gt_mtu_frame_data_size = 64;
918 static int rtp_h264_list_gt_mtu_frame_count = 1;
920 /* NAL = 4 bytes. When data does not fit into 1 mtu, 1 byte will be skipped */
921 static int rtp_h264_list_gt_mtu_bytes_sent = 1 * (64 - 4) - 1;
923 static int rtp_h264_list_gt_mtu_mty_size = 28;
925 GST_START_TEST (rtp_h264_list_gt_mtu)
927 /* FIXME 0.11: fully specify h264 caps (and make payloader check) */
928 rtp_pipeline_test (rtp_h264_list_gt_mtu_frame_data,
929 rtp_h264_list_gt_mtu_frame_data_size, rtp_h264_list_gt_mtu_frame_count,
930 "video/x-h264,stream-format=(string)byte-stream,alignment=(string)nal",
931 "rtph264pay", "rtph264depay",
932 rtp_h264_list_gt_mtu_bytes_sent, rtp_h264_list_gt_mtu_mty_size, TRUE);
936 static const guint8 rtp_h264_list_gt_mtu_frame_data_avc[] =
937 /* packetized data */
938 { 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
939 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
940 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
941 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
942 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
943 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
946 /* NAL = 4 bytes. When data does not fit into 1 mtu, 1 byte will be skipped */
947 static int rtp_h264_list_gt_mtu_bytes_sent_avc = 1 * (64 - 2 * 4 - 2 * 1);
949 GST_START_TEST (rtp_h264_list_gt_mtu_avc)
951 /* FIXME 0.11: fully specify h264 caps (and make payloader check) */
952 rtp_pipeline_test (rtp_h264_list_gt_mtu_frame_data_avc,
953 rtp_h264_list_gt_mtu_frame_data_size, rtp_h264_list_gt_mtu_frame_count,
954 "video/x-h264,stream-format=(string)avc,alignment=(string)au,"
955 "codec_data=(buffer)01640014ffe1001867640014acd94141fb0110000003001773594000f142996001000568ebecb22c",
956 "rtph264pay", "rtph264depay",
957 rtp_h264_list_gt_mtu_bytes_sent_avc, rtp_h264_list_gt_mtu_mty_size, TRUE);
962 static const guint8 rtp_h265_frame_data[] = {
963 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
964 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
967 static int rtp_h265_frame_data_size = 20;
969 static int rtp_h265_frame_count = 1;
971 GST_START_TEST (rtp_h265)
973 rtp_pipeline_test (rtp_h265_frame_data, rtp_h265_frame_data_size,
974 rtp_h265_frame_count,
975 "video/x-h265,stream-format=(string)byte-stream,alignment=(string)nal",
976 "rtph265pay", "rtph265depay", 0, 0, FALSE);
978 /* config-interval property used to be of uint type, was changed to int,
979 * make sure old GValue stuff still works */
981 GValue val = G_VALUE_INIT;
982 GstElement *rtph265pay;
986 rtph265pay = gst_element_factory_make ("rtph265pay", NULL);
987 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (rtph265pay),
989 fail_unless (pspec->value_type == G_TYPE_INT);
990 g_value_init (&val, G_TYPE_UINT);
991 g_value_set_uint (&val, 10);
992 g_object_set_property (G_OBJECT (rtph265pay), "config-interval", &val);
993 g_value_set_uint (&val, 0);
994 g_object_get_property (G_OBJECT (rtph265pay), "config-interval", &val);
995 fail_unless_equals_int (10, g_value_get_uint (&val));
996 g_object_set (G_OBJECT (rtph265pay), "config-interval", -1, NULL);
997 g_object_get_property (G_OBJECT (rtph265pay), "config-interval", &val);
998 fail_unless (g_value_get_uint (&val) == G_MAXUINT);
999 g_value_unset (&val);
1000 gst_object_unref (rtph265pay);
1005 static const guint8 rtp_h265_list_lt_mtu_frame_data[] = {
1006 /* not packetized, next NALU starts with 0x00000001 */
1007 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1008 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
1009 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1010 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
1013 static int rtp_h265_list_lt_mtu_frame_data_size = 16;
1015 static int rtp_h265_list_lt_mtu_frame_count = 2;
1017 /* 3 bytes start code prefixed with one zero byte, NALU header is in payload */
1018 static int rtp_h265_list_lt_mtu_bytes_sent = 2 * (16 - 3 - 1);
1020 static int rtp_h265_list_lt_mtu_mtu_size = 1024;
1022 GST_START_TEST (rtp_h265_list_lt_mtu)
1024 rtp_pipeline_test (rtp_h265_list_lt_mtu_frame_data,
1025 rtp_h265_list_lt_mtu_frame_data_size, rtp_h265_list_lt_mtu_frame_count,
1026 "video/x-h265,stream-format=(string)byte-stream,alignment=(string)nal",
1027 "rtph265pay", "rtph265depay", rtp_h265_list_lt_mtu_bytes_sent,
1028 rtp_h265_list_lt_mtu_mtu_size, TRUE);
1032 static const guint8 rtp_h265_list_lt_mtu_frame_data_hvc1[] = {
1033 /* packetized data */
1034 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1035 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1036 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1037 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
1040 /* length size is 3 bytes */
1041 static int rtp_h265_list_lt_mtu_bytes_sent_hvc1 = 4 + 9;
1044 GST_START_TEST (rtp_h265_list_lt_mtu_hvc1)
1046 rtp_pipeline_test (rtp_h265_list_lt_mtu_frame_data_hvc1,
1047 rtp_h265_list_lt_mtu_frame_data_size, rtp_h265_list_lt_mtu_frame_count,
1048 "video/x-h265,stream-format=(string)hvc1,alignment=(string)au,"
1049 "codec_data=(buffer)0101c000000080000000000099f000fcfdf8f800000203a000010"
1050 "01840010c01ffff01c000000300800000030000030099ac0900a10001003042010101c00"
1051 "0000300800000030000030099a00a080f1fe36bbb5377725d602dc040404100000300010"
1052 "00003000a0800a2000100074401c172b02240",
1053 "rtph265pay aggregate-mode=zero-latency", "rtph265depay",
1054 rtp_h265_list_lt_mtu_bytes_sent_hvc1, rtp_h265_list_lt_mtu_mtu_size,
1059 static const guint8 rtp_h265_list_gt_mtu_frame_data[] = {
1060 /* not packetized, next NAL starts with 0x000001 */
1061 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1062 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1063 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1064 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1065 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1066 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1070 static const int rtp_h265_list_gt_mtu_frame_data_size = 62;
1072 static const int rtp_h265_list_gt_mtu_frame_count = 1;
1074 /* start code is 3 bytes, NALU header is 2 bytes */
1075 static int rtp_h265_list_gt_mtu_bytes_sent = 1 * (62 - 3 - 2);
1077 static int rtp_h265_list_gt_mtu_mtu_size = 28;
1079 GST_START_TEST (rtp_h265_list_gt_mtu)
1081 rtp_pipeline_test (rtp_h265_list_gt_mtu_frame_data,
1082 rtp_h265_list_gt_mtu_frame_data_size, rtp_h265_list_gt_mtu_frame_count,
1083 "video/x-h265,stream-format=(string)byte-stream,alignment=(string)nal",
1084 "rtph265pay", "rtph265depay", rtp_h265_list_gt_mtu_bytes_sent,
1085 rtp_h265_list_gt_mtu_mtu_size, TRUE);
1089 static const guint8 rtp_h265_list_gt_mtu_frame_data_hvc1[] = {
1090 /* packetized data */
1091 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1092 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1093 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1094 0x00, 0x00, 0x00, 0x00, 0x00,
1095 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1096 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1097 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1100 /* length size is 3 bytes, NALU header is 2 bytes */
1101 static int rtp_h265_list_gt_mtu_bytes_sent_hvc1 = 1 * (62 - 2 * 3 - 2 * 2);
1103 GST_START_TEST (rtp_h265_list_gt_mtu_hvc1)
1105 rtp_pipeline_test (rtp_h265_list_gt_mtu_frame_data_hvc1,
1106 rtp_h265_list_gt_mtu_frame_data_size, rtp_h265_list_gt_mtu_frame_count,
1107 "video/x-h265,stream-format=(string)hvc1,alignment=(string)au,"
1108 "codec_data=(buffer)0101c000000080000000000099f000fcfdf8f800000203a000010"
1109 "01840010c01ffff01c000000300800000030000030099ac0900a10001003042010101c00"
1110 "0000300800000030000030099a00a080f1fe36bbb5377725d602dc040404100000300010"
1111 "00003000a0800a2000100074401c172b02240",
1112 "rtph265pay", "rtph265depay", rtp_h265_list_gt_mtu_bytes_sent_hvc1,
1113 rtp_h265_list_gt_mtu_mtu_size, TRUE);
1118 /* KLV data from Day_Flight.mpg */
1119 static const guint8 rtp_KLV_frame_data[] = {
1120 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x0b, 0x01, 0x01,
1121 0x0e, 0x01, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00,
1122 0x81, 0x91, 0x02, 0x08, 0x00, 0x04, 0x6c, 0x8e,
1123 0x20, 0x03, 0x83, 0x85, 0x41, 0x01, 0x01, 0x05,
1124 0x02, 0x3d, 0x3b, 0x06, 0x02, 0x15, 0x80, 0x07,
1125 0x02, 0x01, 0x52, 0x0b, 0x03, 0x45, 0x4f, 0x4e,
1126 0x0c, 0x0e, 0x47, 0x65, 0x6f, 0x64, 0x65, 0x74,
1127 0x69, 0x63, 0x20, 0x57, 0x47, 0x53, 0x38, 0x34,
1128 0x0d, 0x04, 0x4d, 0xc4, 0xdc, 0xbb, 0x0e, 0x04,
1129 0xb1, 0xa8, 0x6c, 0xfe, 0x0f, 0x02, 0x1f, 0x4a,
1130 0x10, 0x02, 0x00, 0x85, 0x11, 0x02, 0x00, 0x4b,
1131 0x12, 0x04, 0x20, 0xc8, 0xd2, 0x7d, 0x13, 0x04,
1132 0xfc, 0xdd, 0x02, 0xd8, 0x14, 0x04, 0xfe, 0xb8,
1133 0xcb, 0x61, 0x15, 0x04, 0x00, 0x8f, 0x3e, 0x61,
1134 0x16, 0x04, 0x00, 0x00, 0x01, 0xc9, 0x17, 0x04,
1135 0x4d, 0xdd, 0x8c, 0x2a, 0x18, 0x04, 0xb1, 0xbe,
1136 0x9e, 0xf4, 0x19, 0x02, 0x0b, 0x85, 0x28, 0x04,
1137 0x4d, 0xdd, 0x8c, 0x2a, 0x29, 0x04, 0xb1, 0xbe,
1138 0x9e, 0xf4, 0x2a, 0x02, 0x0b, 0x85, 0x38, 0x01,
1139 0x2e, 0x39, 0x04, 0x00, 0x8d, 0xd4, 0x29, 0x01,
1143 GST_START_TEST (rtp_klv)
1145 rtp_pipeline_test (rtp_KLV_frame_data, G_N_ELEMENTS (rtp_KLV_frame_data), 1,
1146 "meta/x-klv, parsed=(bool)true", "rtpklvpay", "rtpklvdepay", 0, 0, FALSE);
1151 GST_START_TEST (rtp_klv_fragmented)
1153 /* force super-small mtu of 60 to fragment KLV unit */
1154 rtp_pipeline_test (rtp_KLV_frame_data, sizeof (rtp_KLV_frame_data), 1,
1155 "meta/x-klv, parsed=(bool)true", "rtpklvpay", "rtpklvdepay",
1156 sizeof (rtp_KLV_frame_data), 60, FALSE);
1161 static const guint8 rtp_L16_frame_data[] =
1162 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1166 static int rtp_L16_frame_data_size = 20;
1168 static int rtp_L16_frame_count = 1;
1170 GST_START_TEST (rtp_L16)
1172 rtp_pipeline_test (rtp_L16_frame_data, rtp_L16_frame_data_size,
1173 rtp_L16_frame_count,
1174 "audio/x-raw,format=S16BE,rate=1,channels=1,layout=(string)interleaved",
1175 "rtpL16pay", "rtpL16depay", 0, 0, FALSE);
1180 static const guint8 rtp_L24_frame_data[] =
1181 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1185 static int rtp_L24_frame_data_size = 24;
1187 static int rtp_L24_frame_count = 1;
1189 GST_START_TEST (rtp_L24)
1191 rtp_pipeline_test (rtp_L24_frame_data, rtp_L24_frame_data_size,
1192 rtp_L24_frame_count,
1193 "audio/x-raw,format=S24BE,rate=1,channels=1,layout=(string)interleaved",
1194 "rtpL24pay", "rtpL24depay", 0, 0, FALSE);
1198 static const guint8 rtp_mp2t_frame_data[] =
1199 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1203 static int rtp_mp2t_frame_data_size = 20;
1205 static int rtp_mp2t_frame_count = 1;
1207 GST_START_TEST (rtp_mp2t)
1209 rtp_pipeline_test (rtp_mp2t_frame_data, rtp_mp2t_frame_data_size,
1210 rtp_mp2t_frame_count, "video/mpegts,packetsize=188,systemstream=true",
1211 "rtpmp2tpay", "rtpmp2tdepay", 0, 0, FALSE);
1215 static const guint8 rtp_mp4v_frame_data[] =
1216 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1220 static int rtp_mp4v_frame_data_size = 20;
1222 static int rtp_mp4v_frame_count = 1;
1224 GST_START_TEST (rtp_mp4v)
1226 rtp_pipeline_test (rtp_mp4v_frame_data, rtp_mp4v_frame_data_size,
1227 rtp_mp4v_frame_count, "video/mpeg,mpegversion=4,systemstream=false",
1228 "rtpmp4vpay", "rtpmp4vdepay", 0, 0, FALSE);
1232 static const guint8 rtp_mp4v_list_frame_data[] =
1233 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1234 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1237 static int rtp_mp4v_list_frame_data_size = 20;
1239 static int rtp_mp4v_list_frame_count = 1;
1241 static int rtp_mp4v_list_bytes_sent = 1 * 20;
1243 GST_START_TEST (rtp_mp4v_list)
1245 rtp_pipeline_test (rtp_mp4v_list_frame_data, rtp_mp4v_list_frame_data_size,
1246 rtp_mp4v_list_frame_count,
1247 "video/mpeg,mpegversion=4,systemstream=false,codec_data=(buffer)000001b001",
1248 "rtpmp4vpay", "rtpmp4vdepay", rtp_mp4v_list_bytes_sent, 0, TRUE);
1252 static const guint8 rtp_mp4g_frame_data[] =
1253 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1257 static int rtp_mp4g_frame_data_size = 20;
1259 static int rtp_mp4g_frame_count = 1;
1261 GST_START_TEST (rtp_mp4g)
1263 rtp_pipeline_test (rtp_mp4g_frame_data, rtp_mp4g_frame_data_size,
1264 rtp_mp4g_frame_count,
1265 "video/mpeg,mpegversion=4,systemstream=false,codec_data=(buffer)000001b001",
1266 "rtpmp4gpay", "rtpmp4gdepay", 0, 0, FALSE);
1270 static const guint8 rtp_theora_frame_data[] =
1271 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1275 static int rtp_theora_frame_data_size = 20;
1277 static int rtp_theora_frame_count = 1;
1279 GST_START_TEST (rtp_theora)
1281 rtp_pipeline_test (rtp_theora_frame_data, rtp_theora_frame_data_size,
1282 rtp_theora_frame_count, "video/x-theora", "rtptheorapay",
1283 "rtptheoradepay", 0, 0, FALSE);
1287 static const guint8 rtp_vorbis_frame_data[] =
1288 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1292 static int rtp_vorbis_frame_data_size = 20;
1294 static int rtp_vorbis_frame_count = 1;
1296 GST_START_TEST (rtp_vorbis)
1298 rtp_pipeline_test (rtp_vorbis_frame_data, rtp_vorbis_frame_data_size,
1299 rtp_vorbis_frame_count, "audio/x-vorbis", "rtpvorbispay",
1300 "rtpvorbisdepay", 0, 0, FALSE);
1305 /* videotestsrc pattern=red ! video/x-raw,width=160,height=120 ! vp8enc */
1306 #define VP8_CAPS "video/x-vp8, profile=(string)0, " \
1307 "streamheader=(buffer)4f5650383001010000a000780000010000010000001e00000001, " \
1308 "width=(int)160, height=(int)120, framerate=(fraction)30/1"
1310 static const guint8 rtp_vp8_frame_data[] = {
1311 0x30, 0x07, 0x00, 0x9d, 0x01, 0x2a, 0xa0, 0x00,
1312 0x78, 0x00, 0x00, 0x47, 0x08, 0x85, 0x85, 0x88,
1313 0x85, 0x84, 0x88, 0x02, 0x02, 0x02, 0x75, 0xaa,
1314 0x03, 0xf8, 0x03, 0xfa, 0x02, 0x06, 0xc3, 0xef,
1315 0x05, 0x10, 0x9c, 0x52, 0xd2, 0xa1, 0x38, 0xa5,
1316 0xa5, 0x42, 0x71, 0x4b, 0x4a, 0x84, 0xe2, 0x96,
1317 0x95, 0x09, 0xc5, 0x2d, 0x2a, 0x13, 0x8a, 0x5a,
1318 0x54, 0x27, 0x14, 0xb4, 0xa8, 0x4e, 0x29, 0x69,
1319 0x50, 0x9b, 0x00, 0xfe, 0xfd, 0x6e, 0xf3, 0xff,
1320 0xe3, 0x99, 0x37, 0x30, 0xc4, 0xff, 0x8e, 0x6d,
1321 0xff, 0xf1, 0x61, 0x3c, 0x0e, 0x28, 0xc8, 0xff,
1325 GST_START_TEST (rtp_vp8)
1327 rtp_pipeline_test (rtp_vp8_frame_data, sizeof (rtp_vp8_frame_data), 1,
1328 VP8_CAPS, "rtpvp8pay", "rtpvp8depay", 0, 0, FALSE);
1333 /* videotestsrc pattern=red ! video/x-raw,width=160,height=120 ! vp9enc */
1334 #define VP9_CAPS "video/x-vp9, profile=(string)0, " \
1335 "width=(int)160, height=(int)120, framerate=(fraction)30/1"
1337 static const guint8 rtp_vp9_frame_data[] = {
1338 0x82, 0x49, 0x83, 0x42, 0x00, 0x09, 0xf0, 0x07,
1339 0x76, 0x00, 0x38, 0x24, 0x1c, 0x18, 0x42, 0x00,
1340 0x00, 0x30, 0x60, 0x00, 0x00, 0x67, 0x3f, 0xff,
1341 0xfe, 0x69, 0x95, 0xff, 0xff, 0xff, 0xfe, 0x99,
1342 0x6b, 0xff, 0xff, 0xff, 0xff, 0x62, 0x98, 0x1d,
1343 0x45, 0x4c, 0x90, 0xc4, 0x70
1346 GST_START_TEST (rtp_vp9)
1348 rtp_pipeline_test (rtp_vp9_frame_data, sizeof (rtp_vp9_frame_data), 1,
1349 VP9_CAPS, "rtpvp9pay", "rtpvp9depay", 0, 0, FALSE);
1354 static const guint8 rtp_jpeg_frame_data[] =
1355 { /* SOF */ 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0x08, 0x00, 0x08,
1356 0x03, 0x00, 0x21, 0x08, 0x01, 0x11, 0x08, 0x02, 0x11, 0x08,
1357 /* DQT */ 0xFF, 0xDB, 0x00, 0x43, 0x08,
1358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1366 /* DATA */ 0x00, 0x00, 0x00, 0x00, 0x00
1369 static int rtp_jpeg_frame_data_size = sizeof (rtp_jpeg_frame_data);
1371 static int rtp_jpeg_frame_count = 1;
1373 GST_START_TEST (rtp_jpeg)
1375 rtp_pipeline_test (rtp_jpeg_frame_data, rtp_jpeg_frame_data_size,
1376 rtp_jpeg_frame_count, "video/x-jpeg,height=640,width=480", "rtpjpegpay",
1377 "rtpjpegdepay", 0, 0, FALSE);
1382 GST_START_TEST (rtp_jpeg_width_greater_than_2040)
1384 rtp_pipeline_test (rtp_jpeg_frame_data, rtp_jpeg_frame_data_size,
1385 rtp_jpeg_frame_count, "video/x-jpeg,height=2048,width=480", "rtpjpegpay",
1386 "rtpjpegdepay", 0, 0, FALSE);
1391 GST_START_TEST (rtp_jpeg_height_greater_than_2040)
1393 rtp_pipeline_test (rtp_jpeg_frame_data, rtp_jpeg_frame_data_size,
1394 rtp_jpeg_frame_count, "video/x-jpeg,height=640,width=2048", "rtpjpegpay",
1395 "rtpjpegdepay", 0, 0, FALSE);
1400 GST_START_TEST (rtp_jpeg_width_and_height_greater_than_2040)
1402 rtp_pipeline_test (rtp_jpeg_frame_data, rtp_jpeg_frame_data_size,
1403 rtp_jpeg_frame_count, "video/x-jpeg,height=2048,width=2048", "rtpjpegpay",
1404 "rtpjpegdepay", 0, 0, FALSE);
1409 static const guint8 rtp_jpeg_list_frame_data[] =
1410 { /* SOF */ 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0x08, 0x00, 0x08,
1411 0x03, 0x00, 0x21, 0x08, 0x01, 0x11, 0x08, 0x02, 0x11, 0x08,
1412 /* DQT */ 0xFF, 0xDB, 0x00, 0x43, 0x08,
1413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1414 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1415 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1417 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1418 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1419 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1421 /* DATA */ 0x00, 0x00, 0x00, 0x00, 0x00
1424 static int rtp_jpeg_list_frame_data_size = sizeof (rtp_jpeg_list_frame_data);
1426 static int rtp_jpeg_list_frame_count = 1;
1428 static int rtp_jpeg_list_bytes_sent = 1 * sizeof (rtp_jpeg_list_frame_data);
1430 GST_START_TEST (rtp_jpeg_list)
1432 rtp_pipeline_test (rtp_jpeg_list_frame_data, rtp_jpeg_list_frame_data_size,
1433 rtp_jpeg_list_frame_count, "video/x-jpeg,height=640,width=480",
1434 "rtpjpegpay", "rtpjpegdepay", rtp_jpeg_list_bytes_sent, 0, TRUE);
1439 GST_START_TEST (rtp_jpeg_list_width_greater_than_2040)
1441 rtp_pipeline_test (rtp_jpeg_list_frame_data, rtp_jpeg_list_frame_data_size,
1442 rtp_jpeg_list_frame_count, "video/x-jpeg,height=2048,width=480",
1443 "rtpjpegpay", "rtpjpegdepay", rtp_jpeg_list_bytes_sent, 0, TRUE);
1448 GST_START_TEST (rtp_jpeg_list_height_greater_than_2040)
1450 rtp_pipeline_test (rtp_jpeg_list_frame_data, rtp_jpeg_list_frame_data_size,
1451 rtp_jpeg_list_frame_count, "video/x-jpeg,height=640,width=2048",
1452 "rtpjpegpay", "rtpjpegdepay", rtp_jpeg_list_bytes_sent, 0, TRUE);
1457 GST_START_TEST (rtp_jpeg_list_width_and_height_greater_than_2040)
1459 rtp_pipeline_test (rtp_jpeg_list_frame_data, rtp_jpeg_list_frame_data_size,
1460 rtp_jpeg_list_frame_count, "video/x-jpeg,height=2048,width=2048",
1461 "rtpjpegpay", "rtpjpegdepay", rtp_jpeg_list_bytes_sent, 0, TRUE);
1467 rtp_jpeg_do_packet_loss (gdouble prob, gint num_expected)
1470 gboolean eos = FALSE;
1472 guint i, buffer_count;
1474 s = g_strdup_printf ("videotestsrc pattern=ball num-buffers=100 ! "
1475 "jpegenc quality=50 ! rtpjpegpay ! identity drop-probability=%g ! "
1476 "rtpjpegdepay", prob);
1477 GST_INFO ("running pipeline %s", s);
1478 h = gst_harness_new_parse (s);
1481 gst_harness_play (h);
1486 event = gst_harness_pull_event (h);
1487 eos = (GST_EVENT_TYPE (event) == GST_EVENT_EOS);
1488 gst_event_unref (event);
1491 buffer_count = gst_harness_buffers_received (h);
1492 GST_INFO ("Got %u buffers", buffer_count);
1494 if (num_expected >= 0) {
1495 fail_unless_equals_int (num_expected, buffer_count);
1498 for (i = 0; i < buffer_count; ++i) {
1503 buf = gst_harness_pull (h);
1504 fail_unless (buf != NULL);
1506 fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
1507 GST_MEMDUMP ("jpeg frame", map.data, map.size);
1508 fail_unless (map.size > 4);
1509 soi = GST_READ_UINT16_BE (map.data);
1510 fail_unless (soi == 0xffd8, "expected JPEG frame start FFD8 not %02X", soi);
1511 eoi = GST_READ_UINT16_BE (map.data + map.size - 2);
1512 fail_unless (eoi == 0xffd9, "expected JPEG frame end FFD9 not %02X", eoi);
1513 gst_buffer_unmap (buf, &map);
1514 gst_buffer_unref (buf);
1517 gst_harness_teardown (h);
1520 GST_START_TEST (rtp_jpeg_packet_loss)
1522 gdouble probabilities[] = { 0.0, 0.001, 0.01, 0.1, 0.2, 0.5, 1.0 };
1523 gint num_expected[] = { 100, -1, -1, -1, -1, -1, 0 };
1525 GST_INFO ("Start iteration %d", __i__);
1526 fail_unless (__i__ < G_N_ELEMENTS (probabilities));
1527 rtp_jpeg_do_packet_loss (probabilities[__i__], num_expected[__i__]);
1528 GST_INFO ("Done with iteration %d", __i__);
1533 static const guint8 rtp_g729_frame_data[] =
1534 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1535 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1538 static int rtp_g729_frame_data_size = 22;
1540 static int rtp_g729_frame_count = 1;
1542 GST_START_TEST (rtp_g729)
1544 rtp_pipeline_test (rtp_g729_frame_data, rtp_g729_frame_data_size,
1545 rtp_g729_frame_count, "audio/G729,rate=8000,channels=1", "rtpg729pay",
1546 "rtpg729depay", 0, 0, FALSE);
1551 static const guint8 rtp_gst_frame_data[] =
1552 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1553 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1556 static int rtp_gst_frame_data_size = 22;
1558 static int rtp_gst_frame_count = 1;
1560 GST_START_TEST (rtp_gst_custom_event)
1562 /* Create RTP pipeline. */
1564 rtp_pipeline_create (rtp_gst_frame_data, rtp_gst_frame_data_size,
1565 rtp_gst_frame_count, "application/x-test",
1566 "rtpgstpay", "rtpgstdepay");
1573 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
1574 gst_structure_new ("test", "foo", G_TYPE_INT, 1, NULL));
1576 /* Run RTP pipeline. */
1577 rtp_pipeline_run (p);
1579 /* Destroy RTP pipeline. */
1580 rtp_pipeline_destroy (p);
1585 GST_START_TEST (rtp_vorbis_renegotiate)
1587 GstElement *pipeline;
1588 GstElement *enc, *pay, *depay, *dec, *sink;
1589 GstPad *sinkpad, *srcpad;
1590 GstCaps *templcaps, *caps, *filter, *srccaps;
1596 pipeline = gst_pipeline_new (NULL);
1597 enc = gst_element_factory_make ("vorbisenc", NULL);
1598 pay = gst_element_factory_make ("rtpvorbispay", NULL);
1599 depay = gst_element_factory_make ("rtpvorbisdepay", NULL);
1600 dec = gst_element_factory_make ("vorbisdec", NULL);
1601 sink = gst_element_factory_make ("fakesink", NULL);
1602 g_object_set (sink, "async", FALSE, NULL);
1603 gst_bin_add_many (GST_BIN (pipeline), enc, pay, depay, dec, sink, NULL);
1604 fail_unless (gst_element_link_many (enc, pay, depay, dec, sink, NULL));
1605 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
1606 GST_STATE_CHANGE_SUCCESS);
1608 sinkpad = gst_element_get_static_pad (enc, "sink");
1609 srcpad = gst_element_get_static_pad (dec, "src");
1611 templcaps = gst_pad_get_pad_template_caps (sinkpad);
1613 gst_caps_new_simple ("audio/x-raw", "channels", G_TYPE_INT, 2, "rate",
1614 G_TYPE_INT, 44100, NULL);
1615 caps = gst_caps_intersect (templcaps, filter);
1616 caps = gst_caps_fixate (caps);
1618 gst_segment_init (&segment, GST_FORMAT_TIME);
1619 fail_unless (gst_pad_send_event (sinkpad,
1620 gst_event_new_stream_start ("test")));
1621 fail_unless (gst_pad_send_event (sinkpad, gst_event_new_caps (caps)));
1622 fail_unless (gst_pad_send_event (sinkpad, gst_event_new_segment (&segment)));
1624 gst_audio_info_from_caps (&info, caps);
1625 buffer = gst_buffer_new_and_alloc (44100 * info.bpf);
1626 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
1627 gst_audio_format_info_fill_silence (info.finfo, map.data, map.size);
1628 gst_buffer_unmap (buffer, &map);
1629 GST_BUFFER_PTS (buffer) = 0;
1630 GST_BUFFER_DURATION (buffer) = 1 * GST_SECOND;
1632 fail_unless_equals_int (gst_pad_chain (sinkpad, buffer), GST_FLOW_OK);
1634 srccaps = gst_pad_get_current_caps (srcpad);
1635 fail_unless (gst_caps_can_intersect (srccaps, caps));
1636 gst_caps_unref (srccaps);
1638 gst_caps_unref (caps);
1639 gst_caps_unref (filter);
1641 gst_caps_new_simple ("audio/x-raw", "channels", G_TYPE_INT, 2, "rate",
1642 G_TYPE_INT, 48000, NULL);
1643 caps = gst_caps_intersect (templcaps, filter);
1644 caps = gst_caps_fixate (caps);
1646 fail_unless (gst_pad_send_event (sinkpad, gst_event_new_caps (caps)));
1648 gst_audio_info_from_caps (&info, caps);
1649 buffer = gst_buffer_new_and_alloc (48000 * info.bpf);
1650 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
1651 gst_audio_format_info_fill_silence (info.finfo, map.data, map.size);
1652 gst_buffer_unmap (buffer, &map);
1653 GST_BUFFER_PTS (buffer) = 0;
1654 GST_BUFFER_DURATION (buffer) = 1 * GST_SECOND;
1655 GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
1657 fail_unless_equals_int (gst_pad_chain (sinkpad, buffer), GST_FLOW_OK);
1659 srccaps = gst_pad_get_current_caps (srcpad);
1660 fail_unless (gst_caps_can_intersect (srccaps, caps));
1661 gst_caps_unref (srccaps);
1663 gst_caps_unref (caps);
1664 gst_caps_unref (filter);
1665 gst_caps_unref (templcaps);
1666 gst_object_unref (sinkpad);
1667 gst_object_unref (srcpad);
1668 gst_element_set_state (pipeline, GST_STATE_NULL);
1669 gst_object_unref (pipeline);
1675 pull_rtp_buffer (GstHarness * h)
1679 GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
1681 buf = gst_harness_try_pull (h);
1684 fail_unless (gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp));
1685 seq = gst_rtp_buffer_get_seq (&rtp);
1686 gst_rtp_buffer_unmap (&rtp);
1688 gst_buffer_unref (buf);
1693 test_rtp_opus_dtx (gboolean dtx)
1697 /* generated with a muted mic using:
1698 * gst-launch-1.0 pulsesrc ! opusenc dtx=true bitrate-type=vbr ! fakesink silent=false dump=true -v
1700 static const guint8 opus_empty[] = { 0xf8 };
1701 static const guint8 opus_frame[] = { 0xf8, 0xff, 0xfe };
1702 guint16 seq, expected_seq;
1704 h = gst_harness_new_parse ("rtpopuspay");
1707 gst_harness_set (h, "rtpopuspay", "dtx", dtx, NULL);
1709 gst_harness_set_caps_str (h,
1710 "audio/x-opus, rate=48000, channels=1, channel-mapping-family=0",
1711 "application/x-rtp, media=audio, clock-rate=48000, encoding-name=OPUS, sprop-stereo=(string)0, encoding-params=(string)2, sprop-maxcapturerate=(string)48000, payload=96");
1713 /* push first opus frame */
1715 gst_buffer_new_wrapped (g_memdup (opus_frame, sizeof (opus_frame)),
1716 sizeof (opus_frame));
1717 fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
1718 seq = pull_rtp_buffer (h);
1719 expected_seq = seq + 1;
1721 /* push empty frame */
1723 gst_buffer_new_wrapped (g_memdup (opus_empty, sizeof (opus_empty)),
1724 sizeof (opus_empty));
1725 fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
1727 /* buffer is not transmitted if dtx is enabled */
1728 buf = gst_harness_try_pull (h);
1731 seq = pull_rtp_buffer (h);
1732 fail_unless_equals_int (seq, expected_seq);
1736 /* push second opus frame */
1738 gst_buffer_new_wrapped (g_memdup (opus_frame, sizeof (opus_frame)),
1739 sizeof (opus_frame));
1740 fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
1741 seq = pull_rtp_buffer (h);
1742 fail_unless_equals_int (seq, expected_seq);
1744 gst_harness_teardown (h);
1747 GST_START_TEST (rtp_opus_dtx_disabled)
1749 test_rtp_opus_dtx (FALSE);
1754 GST_START_TEST (rtp_opus_dtx_enabled)
1756 test_rtp_opus_dtx (TRUE);
1762 * Creates the test suite.
1764 * Returns: pointer to the test suite.
1767 rtp_payloading_suite (void)
1769 GstRegistry *registry = gst_registry_get ();
1770 Suite *s = suite_create ("rtp_data_test");
1772 TCase *tc_chain = tcase_create ("linear");
1774 /* Set timeout to 60 seconds. */
1775 tcase_set_timeout (tc_chain, 60);
1777 suite_add_tcase (s, tc_chain);
1778 tcase_add_test (tc_chain, rtp_ilbc);
1779 tcase_add_test (tc_chain, rtp_gsm);
1780 tcase_add_test (tc_chain, rtp_amr);
1781 tcase_add_test (tc_chain, rtp_pcma);
1782 tcase_add_test (tc_chain, rtp_pcmu);
1783 tcase_add_test (tc_chain, rtp_mpa);
1784 tcase_add_test (tc_chain, rtp_h261);
1785 tcase_add_test (tc_chain, rtp_h263);
1786 tcase_add_test (tc_chain, rtp_h263p);
1787 tcase_add_test (tc_chain, rtp_h264);
1788 tcase_add_test (tc_chain, rtp_h264depay_avc);
1789 tcase_add_test (tc_chain, rtp_h264depay_bytestream);
1790 tcase_add_test (tc_chain, rtp_h264_list_lt_mtu);
1791 tcase_add_test (tc_chain, rtp_h264_list_lt_mtu_avc);
1792 tcase_add_test (tc_chain, rtp_h264_list_gt_mtu);
1793 tcase_add_test (tc_chain, rtp_h264_list_gt_mtu_avc);
1794 tcase_add_test (tc_chain, rtp_h265);
1795 tcase_add_test (tc_chain, rtp_h265_list_lt_mtu);
1796 tcase_add_test (tc_chain, rtp_h265_list_lt_mtu_hvc1);
1797 tcase_add_test (tc_chain, rtp_h265_list_gt_mtu);
1798 tcase_add_test (tc_chain, rtp_h265_list_gt_mtu_hvc1);
1799 tcase_add_test (tc_chain, rtp_klv);
1800 tcase_add_test (tc_chain, rtp_klv_fragmented);
1801 tcase_add_test (tc_chain, rtp_L16);
1802 tcase_add_test (tc_chain, rtp_L24);
1803 tcase_add_test (tc_chain, rtp_mp2t);
1804 tcase_add_test (tc_chain, rtp_mp4v);
1805 tcase_add_test (tc_chain, rtp_mp4v_list);
1806 tcase_add_test (tc_chain, rtp_mp4g);
1807 tcase_add_test (tc_chain, rtp_theora);
1808 tcase_add_test (tc_chain, rtp_vorbis);
1809 tcase_add_test (tc_chain, rtp_vp8);
1810 tcase_add_test (tc_chain, rtp_vp9);
1811 tcase_add_test (tc_chain, rtp_jpeg);
1812 tcase_add_test (tc_chain, rtp_jpeg_width_greater_than_2040);
1813 tcase_add_test (tc_chain, rtp_jpeg_height_greater_than_2040);
1814 tcase_add_test (tc_chain, rtp_jpeg_width_and_height_greater_than_2040);
1815 tcase_add_test (tc_chain, rtp_jpeg_list);
1816 tcase_add_test (tc_chain, rtp_jpeg_list_width_greater_than_2040);
1817 tcase_add_test (tc_chain, rtp_jpeg_list_height_greater_than_2040);
1818 tcase_add_test (tc_chain, rtp_jpeg_list_width_and_height_greater_than_2040);
1819 if (gst_registry_check_feature_version (registry, "jpegenc", 1, 0, 0)
1820 && gst_registry_check_feature_version (registry, "videotestsrc", 1, 0, 0))
1821 tcase_add_loop_test (tc_chain, rtp_jpeg_packet_loss, 0, 7);
1822 tcase_add_test (tc_chain, rtp_g729);
1823 tcase_add_test (tc_chain, rtp_gst_custom_event);
1824 tcase_add_test (tc_chain, rtp_vorbis_renegotiate);
1825 tcase_add_test (tc_chain, rtp_opus_dtx_disabled);
1826 tcase_add_test (tc_chain, rtp_opus_dtx_enabled);
1830 GST_CHECK_MAIN (rtp_payloading)