3 * Copyright (C) 2015 Pexip AS
4 * @author Stian Selnes <stian@pexip.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
22 #include <gst/check/check.h>
23 #include <gst/check/gstharness.h>
24 #include <gst/rtp/gstrtpbuffer.h>
26 #define RTP_H263_CAPS_STR(p) \
27 "application/x-rtp,media=video,encoding-name=H263,clock-rate=90000," \
28 "payload=" G_STRINGIFY(p)
31 have_element (const gchar * element_name)
36 element = gst_element_factory_make (element_name, NULL);
37 ret = element != NULL;
40 gst_object_unref (element);
46 create_rtp_buffer (guint8 * data, gsize size, guint ts, gint seqnum)
48 GstBuffer *buf = gst_rtp_buffer_new_copy_data (data, size);
49 GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
51 GST_BUFFER_PTS (buf) = (ts) * (GST_SECOND / 30);
53 gst_rtp_buffer_map (buf, GST_MAP_WRITE, &rtp);
54 gst_rtp_buffer_set_seq (&rtp, seqnum);
55 gst_rtp_buffer_unmap (&rtp);
60 GST_START_TEST (test_h263depay_start_packet_too_small_mode_a)
62 GstHarness *h = gst_harness_new ("rtph263depay");
64 0x80, 0xa2, 0x17, 0x62, 0x57, 0xbb, 0x48, 0x98, 0x4a, 0x59, 0xe8, 0xdc,
65 0x00, 0x00, 0x80, 0x00
68 gst_harness_set_src_caps_str (h, RTP_H263_CAPS_STR (34));
69 fail_unless_equals_int (GST_FLOW_OK,
70 gst_harness_push (h, create_rtp_buffer (packet, sizeof (packet), 0, 0)));
72 /* Packet should be dropped and depayloader not crash */
73 fail_unless_equals_int (0, gst_harness_buffers_received (h));
75 gst_harness_teardown (h);
80 GST_START_TEST (test_h263depay_start_packet_too_small_mode_b)
82 GstHarness *h = gst_harness_new ("rtph263depay");
84 0x80, 0xa2, 0x17, 0x62, 0x57, 0xbb, 0x48, 0x98, 0x4a, 0x59, 0xe8, 0xdc,
85 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00
88 gst_harness_set_src_caps_str (h, RTP_H263_CAPS_STR (34));
89 fail_unless_equals_int (GST_FLOW_OK,
90 gst_harness_push (h, create_rtp_buffer (packet, sizeof (packet), 0, 0)));
92 /* Packet should be dropped and depayloader not crash */
93 fail_unless_equals_int (0, gst_harness_buffers_received (h));
95 gst_harness_teardown (h);
100 GST_START_TEST (test_h263depay_start_packet_too_small_mode_c)
102 GstHarness *h = gst_harness_new ("rtph263depay");
104 0x80, 0xa2, 0x17, 0x62, 0x57, 0xbb, 0x48, 0x98, 0x4a, 0x59, 0xe8, 0xdc,
105 0xc0, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
108 gst_harness_set_src_caps_str (h, RTP_H263_CAPS_STR (34));
109 fail_unless_equals_int (GST_FLOW_OK,
110 gst_harness_push (h, create_rtp_buffer (packet, sizeof (packet), 0, 0)));
112 /* Packet should be dropped and depayloader not crash */
113 fail_unless_equals_int (0, gst_harness_buffers_received (h));
115 gst_harness_teardown (h);
120 GST_START_TEST (test_h263pay_mode_b_snow)
122 /* Payloading one large frame (like snow) is more likely to use mode b and
123 * trigger issues in valgrind seen previously like double free, invalid read
129 if (!have_element ("avenc_h263"))
132 h = gst_harness_new_parse (
133 "avenc_h263 rtp-payload-size=1 ! rtph263pay mtu=1350 ");
134 gst_harness_add_src_parse (h, "videotestsrc pattern=snow is-live=1 ! "
135 "capsfilter caps=\"video/x-raw,format=I420,width=176,height=144\"", TRUE);
137 for (i = 0; i < frames; i++)
138 gst_harness_push_from_src (h);
139 fail_unless (gst_harness_buffers_received (h) >= frames);
141 gst_harness_teardown (h);
145 /* gst_rtp_buffer_get_payload() may return a copy of the payload. This test
146 * makes sure that the rtph263pdepay also produces the correct output in this
148 GST_START_TEST (test_h263pdepay_fragmented_memory_non_writable_buffer)
151 GstBuffer *header_buf, *payload_buf, *buf;
152 GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
156 0x80, 0x02, 0x1c, 0xb8, 0x01, 0x00, 0x11, 0xe0, 0x44, 0xc4 };
158 0x00, 0x00, 0x80, 0x02, 0x1c, 0xb8, 0x01, 0x00, 0x11, 0xe0, 0x44, 0xc4 };
160 h = gst_harness_new ("rtph263pdepay");
161 gst_harness_set_src_caps_str (h, "application/x-rtp, media=video, "
162 "clock-rate=90000, encoding-name=H263-1998");
164 /* Packet with M=1, P=1 */
165 header_buf = gst_rtp_buffer_new_allocate (sizeof (header), 0, 0);
166 gst_rtp_buffer_map (header_buf, GST_MAP_WRITE, &rtp);
167 gst_rtp_buffer_set_marker (&rtp, TRUE);
168 memcpy (gst_rtp_buffer_get_payload (&rtp), header, sizeof (header));
169 gst_rtp_buffer_unmap (&rtp);
171 payload_buf = gst_buffer_new_allocate (NULL, sizeof (payload), NULL);
172 gst_buffer_fill (payload_buf, 0, payload, sizeof (payload));
173 buf = gst_buffer_append (header_buf, payload_buf);
175 gst_harness_push (h, gst_buffer_ref (buf));
176 gst_buffer_unref (buf);
178 buf = gst_harness_pull (h);
179 fail_unless (gst_buffer_memcmp (buf, 0, frame, sizeof (frame)) == 0);
180 gst_buffer_unref (buf);
182 gst_harness_teardown (h);
186 /* gst_rtp_buffer_get_payload() may return a copy of the payload. This test
187 * makes sure that the rtph263pdepay also produces the correct output in this
189 GST_START_TEST (test_h263pdepay_fragmented_memory_non_writable_buffer_split_frame)
192 GstBuffer *header_buf, *payload_buf, *buf;
193 GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
197 0x80, 0x02, 0x1c, 0xb8, 0x01, 0x00, 0x11, 0xe0, 0x44, 0xc4 };
199 0x00, 0x00, 0x80, 0x02, 0x1c, 0xb8, 0x01, 0x00, 0x11, 0xe0, 0x44, 0xc4 };
201 h = gst_harness_new ("rtph263pdepay");
202 gst_harness_set_src_caps_str (h, "application/x-rtp, media=video, "
203 "clock-rate=90000, encoding-name=H263-1998");
205 /* First packet, M=0, P=1 */
206 header_buf = gst_rtp_buffer_new_allocate (sizeof (header), 0, 0);
207 gst_rtp_buffer_map (header_buf, GST_MAP_WRITE, &rtp);
208 gst_rtp_buffer_set_marker (&rtp, FALSE);
209 gst_rtp_buffer_set_seq (&rtp, 0);
210 memcpy (gst_rtp_buffer_get_payload (&rtp), header, sizeof (header));
211 gst_rtp_buffer_unmap (&rtp);
213 payload_buf = gst_buffer_new_allocate (NULL, sizeof (payload), NULL);
214 gst_buffer_fill (payload_buf, 0, payload, sizeof (payload));
215 buf = gst_buffer_append (header_buf, payload_buf);
217 gst_harness_push (h, gst_buffer_ref (buf));
218 gst_buffer_unref (buf);
219 fail_unless_equals_int (gst_harness_buffers_received (h), 0);
221 /* Second packet, M=1, P=1 */
222 header_buf = gst_rtp_buffer_new_allocate (sizeof (header), 0, 0);
223 gst_rtp_buffer_map (header_buf, GST_MAP_WRITE, &rtp);
224 gst_rtp_buffer_set_marker (&rtp, TRUE);
225 gst_rtp_buffer_set_seq (&rtp, 1);
226 memcpy (gst_rtp_buffer_get_payload (&rtp), header, sizeof (header));
227 gst_rtp_buffer_unmap (&rtp);
229 payload_buf = gst_buffer_new_allocate (NULL, sizeof (payload), NULL);
230 gst_buffer_memset (payload_buf, 0, 0, 10);
231 buf = gst_buffer_append (header_buf, payload_buf);
233 gst_harness_push (h, gst_buffer_ref (buf));
234 gst_buffer_unref (buf);
235 fail_unless_equals_int (gst_harness_buffers_received (h), 1);
237 buf = gst_harness_pull (h);
238 fail_unless (gst_buffer_memcmp (buf, 0, frame, sizeof (frame)) == 0);
239 gst_buffer_unref (buf);
241 gst_harness_teardown (h);
248 Suite *s = suite_create ("rtph263");
251 suite_add_tcase (s, (tc_chain = tcase_create ("h263depay")));
252 tcase_add_test (tc_chain, test_h263depay_start_packet_too_small_mode_a);
253 tcase_add_test (tc_chain, test_h263depay_start_packet_too_small_mode_b);
254 tcase_add_test (tc_chain, test_h263depay_start_packet_too_small_mode_c);
256 suite_add_tcase (s, (tc_chain = tcase_create ("h263pay")));
257 tcase_add_test (tc_chain, test_h263pay_mode_b_snow);
259 suite_add_tcase (s, (tc_chain = tcase_create ("h263pdepay")));
260 tcase_add_test (tc_chain, test_h263pdepay_fragmented_memory_non_writable_buffer);
261 tcase_add_test (tc_chain, test_h263pdepay_fragmented_memory_non_writable_buffer_split_frame);
266 GST_CHECK_MAIN (rtph263);