• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * GStreamer AVTP Plugin
3  * Copyright (C) 2019 Intel Corporation
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later
9  * version.
10  *
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  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301 USA
20  */
21 
22 #include <gst/check/gstcheck.h>
23 #include <gst/check/gstharness.h>
24 
25 #include <avtp.h>
26 #include <avtp_cvf.h>
27 
28 #define AVTP_CVF_H264_HEADER_SIZE (sizeof(struct avtp_stream_pdu) + sizeof(guint32))
29 #define STREAM_ID 0xAABBCCDDEEFF0000
30 
31 static gboolean
check_nal_filling(GstBuffer * buffer,guint8 first)32 check_nal_filling (GstBuffer * buffer, guint8 first)
33 {
34   GstMapInfo map;
35   gboolean result = TRUE;
36   gsize offset = 5;             /* 4 bytes for the nal size and one with nal type */
37   int i;
38 
39   gst_buffer_map (buffer, &map, GST_MAP_READ);
40 
41   for (i = offset; i < map.size; i++) {
42     if (map.data[i] != first++) {
43       result = FALSE;
44       break;
45     }
46   }
47 
48   gst_buffer_unmap (buffer, &map);
49 
50   return result;
51 }
52 
53 static void
fill_nal(guint8 * buf,gsize size,guint8 first)54 fill_nal (guint8 * buf, gsize size, guint8 first)
55 {
56   while (size--) {
57     *buf++ = first++;
58   }
59 }
60 
61 static gsize
nal_size(GstBuffer * buffer)62 nal_size (GstBuffer * buffer)
63 {
64   guint8 nal_size[4];
65 
66   gst_buffer_extract (buffer, 0, nal_size, 4);
67   return GST_READ_UINT32_BE (nal_size);
68 }
69 
70 static gsize
nal_type(GstBuffer * buffer)71 nal_type (GstBuffer * buffer)
72 {
73   guint8 nal_type;
74 
75   gst_buffer_extract (buffer, 4, &nal_type, 1);
76   return nal_type & 0x1f;
77 }
78 
79 static GstBuffer *
fetch_nal(GstBuffer * buffer,gsize * offset)80 fetch_nal (GstBuffer * buffer, gsize * offset)
81 {
82   gsize nal_size;
83   GstBuffer *ret;
84   guint8 buf[4];
85 
86   if (*offset >= (gst_buffer_get_size (buffer) - 4))
87     return NULL;
88 
89   gst_buffer_extract (buffer, *offset, buf, 4);
90   nal_size = GST_READ_UINT32_BE (buf);
91 
92   ret =
93       gst_buffer_copy_region (buffer, GST_BUFFER_COPY_MEMORY, *offset,
94       nal_size + 4);
95   *offset += nal_size + 4;
96 
97   return ret;
98 }
99 
GST_START_TEST(test_depayloader_fragment_and_single)100 GST_START_TEST (test_depayloader_fragment_and_single)
101 {
102   GstHarness *h;
103   GstBuffer *in;
104   const gint DATA_LEN = sizeof (guint32) + 10;
105   struct avtp_stream_pdu *pdu;
106   GstMapInfo map;
107 
108   /* Create the harness for the avtpcvfpay */
109   h = gst_harness_new_parse ("avtpcvfdepay ! fakesink num-buffers=1");
110   gst_harness_set_src_caps_str (h, "application/x-avtp");
111 
112   /* Create the input AVTPDU */
113   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 10);
114   gst_buffer_map (in, &map, GST_MAP_READWRITE);
115   pdu = (struct avtp_stream_pdu *) map.data;
116 
117   /* Start with a single NAL */
118   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
119   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
120   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 0);
121   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
122   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 0);
123   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
124   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
125   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
126   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x1;
127   gst_buffer_unmap (in, &map);
128 
129   /* We push a copy so that we can change only what is necessary on our buffer */
130   fail_unless_equals_int (gst_harness_push (h, gst_buffer_copy (in)),
131       GST_FLOW_OK);
132   fail_unless (gst_harness_try_pull (h) == NULL);
133 
134   /* Then a fragment */
135   gst_buffer_map (in, &map, GST_MAP_READWRITE);
136   pdu = (struct avtp_stream_pdu *) map.data;
137   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
138   map.data[AVTP_CVF_H264_HEADER_SIZE] = 3 << 5 | 28;    /* NAL type FU-A, NRI 3 */
139   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 7) | 4;       /* S = 1, type 4 */
140   gst_buffer_unmap (in, &map);
141 
142   fail_unless_equals_int (gst_harness_push (h, gst_buffer_copy (in)),
143       GST_FLOW_OK);
144 
145   /* Third and last AVTPDU, again a single NAL */
146   gst_buffer_map (in, &map, GST_MAP_READWRITE);
147   pdu = (struct avtp_stream_pdu *) map.data;
148   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
149   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
150   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
151   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 2);
152   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x1;
153   gst_buffer_unmap (in, &map);
154 
155   fail_unless_equals_int (gst_harness_push (h, gst_buffer_copy (in)),
156       GST_FLOW_EOS);
157 
158   gst_buffer_unref (in);
159   gst_harness_teardown (h);
160 }
161 
162 GST_END_TEST;
163 
GST_START_TEST(test_depayloader_fragmented_two_start_eos)164 GST_START_TEST (test_depayloader_fragmented_two_start_eos)
165 {
166   GstHarness *h;
167   GstBuffer *in;
168   const gint DATA_LEN = sizeof (guint32) + 10;
169   struct avtp_stream_pdu *pdu;
170   GstMapInfo map;
171 
172   /* Create the harness for the avtpcvfpay */
173   h = gst_harness_new_parse ("avtpcvfdepay ! fakesink num-buffers=1");
174   gst_harness_set_src_caps_str (h, "application/x-avtp");
175 
176   /* Create the input AVTPDU */
177   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 10);
178   gst_buffer_map (in, &map, GST_MAP_READWRITE);
179   pdu = (struct avtp_stream_pdu *) map.data;
180 
181   /* Start with a single NAL */
182   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
183   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
184   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 0);
185   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
186   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 0);
187   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
188   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
189   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
190   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x1;
191   gst_buffer_unmap (in, &map);
192 
193   /* We push a copy so that we can change only what is necessary on our buffer */
194   fail_unless_equals_int (gst_harness_push (h, gst_buffer_copy (in)),
195       GST_FLOW_OK);
196   fail_unless (gst_harness_try_pull (h) == NULL);
197 
198   /* Then a fragment */
199   gst_buffer_map (in, &map, GST_MAP_READWRITE);
200   pdu = (struct avtp_stream_pdu *) map.data;
201   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
202   map.data[AVTP_CVF_H264_HEADER_SIZE] = 3 << 5 | 28;    /* NAL type FU-A, NRI 3 */
203   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 7) | 4;       /* S = 1, type 4 */
204   gst_buffer_unmap (in, &map);
205 
206   fail_unless_equals_int (gst_harness_push (h, gst_buffer_copy (in)),
207       GST_FLOW_OK);
208 
209   /* Third and last AVTPDU, another fragment with start bit set */
210   gst_buffer_map (in, &map, GST_MAP_READWRITE);
211   pdu = (struct avtp_stream_pdu *) map.data;
212   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
213   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
214   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
215   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 2);
216   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 7) | 4;       /* S = 1, type 4 */
217   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 8, 16);
218   gst_buffer_unmap (in, &map);
219 
220   fail_unless_equals_int (gst_harness_push (h, gst_buffer_copy (in)),
221       GST_FLOW_EOS);
222 
223   gst_buffer_unref (in);
224   gst_harness_teardown (h);
225 }
226 
227 GST_END_TEST;
228 
GST_START_TEST(test_depayloader_multiple_lost_eos)229 GST_START_TEST (test_depayloader_multiple_lost_eos)
230 {
231   GstHarness *h;
232   GstBuffer *in;
233   const gint DATA_LEN = sizeof (guint32) + 4;
234   struct avtp_stream_pdu *pdu;
235   GstMapInfo map;
236 
237   /* Create the harness for the avtpcvfpay */
238   h = gst_harness_new_parse ("avtpcvfdepay ! fakesink num-buffers=1");
239   gst_harness_set_src_caps_str (h, "application/x-avtp");
240 
241   /* Create the input AVTPDU header */
242   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 4);
243   gst_buffer_map (in, &map, GST_MAP_READWRITE);
244   pdu = (struct avtp_stream_pdu *) map.data;
245 
246   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
247   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
248   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
249   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
250   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
251   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
252   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
253   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
254   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x7;    /* Add NAL type */
255   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 0);
256   gst_buffer_unmap (in, &map);
257 
258   /* We push a copy so that we can change only what is necessary on our buffer */
259   gst_harness_push (h, gst_buffer_copy (in));
260   fail_unless (gst_harness_try_pull (h) == NULL);
261 
262   /* Send second AVTPDU, but skipping one seqnum */
263   gst_buffer_map (in, &map, GST_MAP_READWRITE);
264   pdu = (struct avtp_stream_pdu *) map.data;
265   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 2);
266   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x1;    /* Add NAL type */
267   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 0);
268   gst_buffer_unmap (in, &map);
269 
270   fail_unless_equals_int (gst_harness_push (h, gst_buffer_copy (in)),
271       GST_FLOW_EOS);
272 
273   gst_buffer_unref (in);
274   gst_harness_teardown (h);
275 }
276 
277 GST_END_TEST;
278 
GST_START_TEST(test_depayloader_fragmented_eos)279 GST_START_TEST (test_depayloader_fragmented_eos)
280 {
281   GstHarness *h;
282   GstBuffer *in;
283   const gint DATA_LEN = sizeof (guint32) + 10;
284   struct avtp_stream_pdu *pdu;
285   GstMapInfo map;
286 
287   /* Create the harness for the avtpcvfpay */
288   h = gst_harness_new_parse ("avtpcvfdepay ! fakesink num-buffers=1");
289   gst_harness_set_src_caps_str (h, "application/x-avtp");
290 
291   /* Create the input AVTPDU */
292   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 10);
293   gst_buffer_map (in, &map, GST_MAP_READWRITE);
294   pdu = (struct avtp_stream_pdu *) map.data;
295 
296   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
297   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
298   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 0);
299   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
300   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 0);
301   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
302   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
303   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
304   map.data[AVTP_CVF_H264_HEADER_SIZE] = 3 << 5 | 28;    /* NAL type FU-A, NRI 3 */
305   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 7) | 4;       /* S = 1, type 4 */
306   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 8, 0);
307   gst_buffer_unmap (in, &map);
308 
309   /* We push a copy so that we can change only what is necessary on our buffer */
310   fail_unless_equals_int (gst_harness_push (h, gst_buffer_copy (in)),
311       GST_FLOW_OK);
312   fail_unless (gst_harness_try_pull (h) == NULL);
313 
314   /* Send second and last AVTPDU */
315   gst_buffer_map (in, &map, GST_MAP_READWRITE);
316   pdu = (struct avtp_stream_pdu *) map.data;
317   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
318   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
319   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
320   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
321   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 6) | 4;       /* E = 1, type 4 */
322   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 8, 16);
323   gst_buffer_unmap (in, &map);
324 
325   fail_unless_equals_int (gst_harness_push (h, gst_buffer_copy (in)),
326       GST_FLOW_EOS);
327 
328   gst_buffer_unref (in);
329   gst_harness_teardown (h);
330 }
331 
332 GST_END_TEST;
333 
334 /* Tests a big fragmented NAL scenario */
GST_START_TEST(test_depayloader_single_eos)335 GST_START_TEST (test_depayloader_single_eos)
336 {
337   GstHarness *h;
338   GstBuffer *in;
339   const gint DATA_LEN = sizeof (guint32) + 4;
340   struct avtp_stream_pdu *pdu;
341   GstMapInfo map;
342 
343   /* Create the harness for the avtpcvfpay */
344   h = gst_harness_new_parse ("avtpcvfdepay ! fakesink num-buffers=1");
345   gst_harness_set_src_caps_str (h, "application/x-avtp");
346 
347   /* Create the input AVTPDU header */
348   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 4);
349   gst_buffer_map (in, &map, GST_MAP_READWRITE);
350   pdu = (struct avtp_stream_pdu *) map.data;
351 
352   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
353   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
354   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
355   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
356   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
357   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
358   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
359   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
360   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x1;    /* Add NAL type */
361   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 0);
362   gst_buffer_unmap (in, &map);
363 
364   fail_unless_equals_int (gst_harness_push (h, in), GST_FLOW_EOS);
365 
366   gst_harness_teardown (h);
367 }
368 
369 GST_END_TEST;
370 
GST_START_TEST(test_depayloader_invalid_avtpdu)371 GST_START_TEST (test_depayloader_invalid_avtpdu)
372 {
373   GstHarness *h;
374   GstBuffer *in, *small;
375   const gint DATA_LEN = sizeof (guint32) + 4;
376   struct avtp_stream_pdu *pdu;
377   GstMapInfo map;
378 
379   /* Create the harness for the avtpcvfpay */
380   h = gst_harness_new ("avtpcvfdepay");
381   gst_harness_set_src_caps_str (h, "application/x-avtp");
382 
383   /* Create the input AVTPDU header */
384   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 4);
385   gst_buffer_map (in, &map, GST_MAP_READWRITE);
386   pdu = (struct avtp_stream_pdu *) map.data;
387 
388   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_MJPEG);
389   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
390   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
391   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
392   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
393   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
394   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
395   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
396   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x1;    /* Add NAL type */
397   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 0);
398   gst_buffer_unmap (in, &map);
399 
400   /* Invalid CVF subtype */
401   gst_harness_push (h, gst_buffer_copy (in));
402   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
403 
404   /* Invalid subtype */
405   gst_buffer_map (in, &map, GST_MAP_READWRITE);
406   pdu = (struct avtp_stream_pdu *) map.data;
407   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_FORMAT_SUBTYPE,
408       AVTP_CVF_FORMAT_SUBTYPE_H264);
409   avtp_pdu_set ((struct avtp_common_pdu *) pdu, AVTP_FIELD_SUBTYPE,
410       AVTP_SUBTYPE_CRF);
411   gst_buffer_unmap (in, &map);
412 
413   gst_harness_push (h, gst_buffer_copy (in));
414   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
415 
416   /* Invalid CVF type */
417   gst_buffer_map (in, &map, GST_MAP_READWRITE);
418   pdu = (struct avtp_stream_pdu *) map.data;
419   avtp_pdu_set ((struct avtp_common_pdu *) pdu, AVTP_FIELD_SUBTYPE,
420       AVTP_SUBTYPE_CVF);
421   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_FORMAT, 0);
422   gst_buffer_unmap (in, &map);
423 
424   gst_harness_push (h, gst_buffer_copy (in));
425   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
426 
427   /* Invalid AVTP version */
428   gst_buffer_map (in, &map, GST_MAP_READWRITE);
429   pdu = (struct avtp_stream_pdu *) map.data;
430   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_FORMAT, AVTP_CVF_FORMAT_RFC);
431   avtp_pdu_set ((struct avtp_common_pdu *) pdu, AVTP_FIELD_VERSION, 3);
432   gst_buffer_unmap (in, &map);
433 
434   gst_harness_push (h, gst_buffer_copy (in));
435   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
436 
437   /* Invalid SV  */
438   gst_buffer_map (in, &map, GST_MAP_READWRITE);
439   pdu = (struct avtp_stream_pdu *) map.data;
440   avtp_pdu_set ((struct avtp_common_pdu *) pdu, AVTP_FIELD_VERSION, 0);
441   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SV, 0);
442   gst_buffer_unmap (in, &map);
443 
444   gst_harness_push (h, gst_buffer_copy (in));
445   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
446 
447   /* Invalid stream id  */
448   gst_buffer_map (in, &map, GST_MAP_READWRITE);
449   pdu = (struct avtp_stream_pdu *) map.data;
450   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SV, 1);
451   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, 0xAABBCCDDEEFF0001);
452   gst_buffer_unmap (in, &map);
453 
454   gst_harness_push (h, gst_buffer_copy (in));
455   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
456 
457   /* Invalid stream data len  */
458   gst_buffer_map (in, &map, GST_MAP_READWRITE);
459   pdu = (struct avtp_stream_pdu *) map.data;
460   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
461   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, 100);
462   gst_buffer_unmap (in, &map);
463 
464   gst_harness_push (h, gst_buffer_copy (in));
465   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
466 
467   /* Invalid NAL type (STAP-A)  */
468   gst_buffer_map (in, &map, GST_MAP_READWRITE);
469   pdu = (struct avtp_stream_pdu *) map.data;
470   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
471   map.data[AVTP_CVF_H264_HEADER_SIZE] = 24;
472   gst_buffer_unmap (in, &map);
473 
474   gst_harness_push (h, gst_buffer_copy (in));
475   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
476 
477   /* Invalid NAL type (STAP-B)  */
478   gst_buffer_map (in, &map, GST_MAP_READWRITE);
479   pdu = (struct avtp_stream_pdu *) map.data;
480   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
481   map.data[AVTP_CVF_H264_HEADER_SIZE] = 25;
482   gst_buffer_unmap (in, &map);
483 
484   gst_harness_push (h, gst_buffer_copy (in));
485   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
486 
487   /* Invalid NAL type (MTAP16)  */
488   gst_buffer_map (in, &map, GST_MAP_READWRITE);
489   pdu = (struct avtp_stream_pdu *) map.data;
490   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
491   map.data[AVTP_CVF_H264_HEADER_SIZE] = 26;
492   gst_buffer_unmap (in, &map);
493 
494   gst_harness_push (h, gst_buffer_copy (in));
495   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
496 
497   /* Invalid NAL type (MTAP24)  */
498   gst_buffer_map (in, &map, GST_MAP_READWRITE);
499   pdu = (struct avtp_stream_pdu *) map.data;
500   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
501   map.data[AVTP_CVF_H264_HEADER_SIZE] = 27;
502   gst_buffer_unmap (in, &map);
503 
504   gst_harness_push (h, gst_buffer_copy (in));
505   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
506 
507   /* Invalid NAL type (FU-B)  */
508   gst_buffer_map (in, &map, GST_MAP_READWRITE);
509   pdu = (struct avtp_stream_pdu *) map.data;
510   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
511   map.data[AVTP_CVF_H264_HEADER_SIZE] = 29;
512   gst_buffer_unmap (in, &map);
513 
514   gst_harness_push (h, gst_buffer_copy (in));
515   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
516 
517   /* Invalid NAL type (STAP-A)  */
518   gst_buffer_map (in, &map, GST_MAP_READWRITE);
519   pdu = (struct avtp_stream_pdu *) map.data;
520   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
521   map.data[AVTP_CVF_H264_HEADER_SIZE] = 24;
522   gst_buffer_unmap (in, &map);
523 
524   gst_harness_push (h, gst_buffer_copy (in));
525   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
526 
527   /* Invalid buffer size (too small to fit an AVTP header) */
528   small = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE / 2);
529   gst_harness_push (h, small);
530   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
531 
532   /* Invalid buffer size (too small to fit a fragment header) */
533   small = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 1);
534   gst_buffer_map (small, &map, GST_MAP_READWRITE);
535   pdu = (struct avtp_stream_pdu *) map.data;
536   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
537   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
538   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 0);
539   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
540   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 0);
541   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
542   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
543   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, sizeof (guint32) + 1);
544   map.data[AVTP_CVF_H264_HEADER_SIZE] = 28;
545   gst_buffer_unmap (small, &map);
546 
547   gst_harness_push (h, small);
548   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
549 
550   gst_buffer_unref (in);
551   gst_harness_teardown (h);
552 }
553 
554 GST_END_TEST;
555 
556 /*
557  * This test will send some invalid fragments, but with valid seqnum
558  * (misbehaving payloader).*/
GST_START_TEST(test_depayloader_lost_fragments)559 GST_START_TEST (test_depayloader_lost_fragments)
560 {
561   GstHarness *h;
562   GstBuffer *in, *out, *nal;
563   const gint DATA_LEN = sizeof (guint32) + 10;
564   struct avtp_stream_pdu *pdu;
565   GstMapInfo map;
566   gsize offset;
567 
568   /* Create the harness for the avtpcvfpay */
569   h = gst_harness_new ("avtpcvfdepay");
570   gst_harness_set_src_caps_str (h, "application/x-avtp");
571 
572   /* Create the input AVTPDU */
573   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 10);
574   gst_buffer_map (in, &map, GST_MAP_READWRITE);
575   pdu = (struct avtp_stream_pdu *) map.data;
576 
577   /* First fragment doesn't have start bit set, so it should be ignored */
578   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
579   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
580   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 0);
581   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
582   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 0);
583   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
584   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
585   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
586   map.data[AVTP_CVF_H264_HEADER_SIZE] = 3 << 5 | 28;    /* NAL type FU-A, NRI 3 */
587   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = 4;  /* S = 0, type 4 */
588   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 8, 0);
589   gst_buffer_unmap (in, &map);
590 
591   /* We push a copy so that we can change only what is necessary on our buffer */
592   gst_harness_push (h, gst_buffer_copy (in));
593   fail_unless (gst_harness_try_pull (h) == NULL);
594 
595   /* Send second AVTPDU - but this should be also ignored as it doesn't have the
596    * start bit set */
597   gst_buffer_map (in, &map, GST_MAP_READWRITE);
598   pdu = (struct avtp_stream_pdu *) map.data;
599   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
600   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = 4;  /* type 4 */
601   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 8, 8);
602   gst_buffer_unmap (in, &map);
603 
604   gst_harness_push (h, gst_buffer_copy (in));
605   fail_unless (gst_harness_try_pull (h) == NULL);
606 
607   /* Send third AVTPDU, with end bit set, but it should be discarded as there
608    * was no start fragment */
609   gst_buffer_map (in, &map, GST_MAP_READWRITE);
610   pdu = (struct avtp_stream_pdu *) map.data;
611   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
612   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
613   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
614   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 2);
615   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 6) | 4;       /* E = 1, type 4 */
616   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 8, 16);
617   gst_buffer_unmap (in, &map);
618 
619   /* Ensure no buffer came out */
620   gst_harness_push (h, gst_buffer_copy (in));
621   fail_unless (gst_harness_try_pull (h) == NULL);
622 
623   /* Now, let's send an invalid one, with both start and end bits set */
624   gst_buffer_map (in, &map, GST_MAP_READWRITE);
625   pdu = (struct avtp_stream_pdu *) map.data;
626   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 3);
627   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (3 << 6) | 4;       /* S = E = 1, type 4 */
628   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 8, 24);
629   gst_buffer_unmap (in, &map);
630 
631   gst_harness_push (h, gst_buffer_copy (in));
632   fail_unless (gst_harness_try_pull (h) == NULL);
633 
634   /* Send a fragment with proper start */
635   gst_buffer_map (in, &map, GST_MAP_READWRITE);
636   pdu = (struct avtp_stream_pdu *) map.data;
637   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 4);
638   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 7) | 4;       /* S = 1, type 4 */
639   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 8, 32);
640   gst_buffer_unmap (in, &map);
641 
642   gst_harness_push (h, gst_buffer_copy (in));
643   fail_unless (gst_harness_try_pull (h) == NULL);
644 
645   /* But send start again. Previous one should be dropped */
646   gst_buffer_map (in, &map, GST_MAP_READWRITE);
647   pdu = (struct avtp_stream_pdu *) map.data;
648   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 5);
649   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 7) | 4;       /* S = 1, type 4 */
650   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 8, 40);
651   gst_buffer_unmap (in, &map);
652 
653   gst_harness_push (h, gst_buffer_copy (in));
654   fail_unless (gst_harness_try_pull (h) == NULL);
655 
656   /* Finally, send ending fragment. It should come out a buffer
657    * whose content starts on 40 (starting of start fragment) */
658   gst_buffer_map (in, &map, GST_MAP_READWRITE);
659   pdu = (struct avtp_stream_pdu *) map.data;
660   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 6);
661   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 6) | 4;       /* E = 1, type 4 */
662   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 8, 48);
663   gst_buffer_unmap (in, &map);
664 
665   gst_harness_push (h, gst_buffer_copy (in));
666 
667   out = gst_harness_pull (h);
668   fail_unless_equals_uint64 (GST_BUFFER_DTS (out), 1000000);
669   fail_unless_equals_uint64 (GST_BUFFER_PTS (out), 2000000);
670 
671   /* NAL is composed of 8 bytes fragment + reconstructed NAL header, so 17 bytes */
672   offset = 0;
673   nal = fetch_nal (out, &offset);
674   fail_unless_equals_uint64 (nal_size (nal), 17);
675   fail_unless (check_nal_filling (nal, 40) == TRUE);
676   fail_unless_equals_uint64 (nal_type (nal), 4);
677   gst_buffer_unref (nal);
678 
679   /* Ensure no other NAL units are present */
680   nal = fetch_nal (out, &offset);
681   fail_unless (nal == NULL);
682 
683   gst_buffer_unref (out);
684   gst_buffer_unref (in);
685   gst_harness_teardown (h);
686 }
687 
688 GST_END_TEST;
689 
690 /* This test jumps one seq_num, thus simulating a lost packet */
GST_START_TEST(test_depayloader_lost_packet)691 GST_START_TEST (test_depayloader_lost_packet)
692 {
693   GstHarness *h;
694   GstBuffer *in, *out, *nal;
695   const gint DATA_LEN = sizeof (guint32) + 4;
696   struct avtp_stream_pdu *pdu;
697   GstMapInfo map;
698   gsize offset;
699 
700   /* Create the harness for the avtpcvfpay */
701   h = gst_harness_new ("avtpcvfdepay");
702   gst_harness_set_src_caps_str (h, "application/x-avtp");
703 
704   /* Create the input AVTPDU header */
705   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 4);
706   gst_buffer_map (in, &map, GST_MAP_READWRITE);
707   pdu = (struct avtp_stream_pdu *) map.data;
708 
709   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
710   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
711   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
712   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
713   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
714   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
715   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
716   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
717   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x7;    /* Add NAL type */
718   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 0);
719   gst_buffer_unmap (in, &map);
720 
721   /* We push a copy so that we can change only what is necessary on our buffer */
722   gst_harness_push (h, gst_buffer_copy (in));
723   fail_unless (gst_harness_try_pull (h) == NULL);
724 
725   /* Send second AVTPDU */
726   gst_buffer_map (in, &map, GST_MAP_READWRITE);
727   pdu = (struct avtp_stream_pdu *) map.data;
728   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
729   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 0);
730   gst_buffer_unmap (in, &map);
731 
732   gst_harness_push (h, gst_buffer_copy (in));
733   fail_unless (gst_harness_try_pull (h) == NULL);
734 
735   /* Send third and last AVTPDU, but jumping one SEQ_NUM.
736    * This should make the first two NAL units to be flushed,
737    * despite M not being set on this third packet.
738    * Also, this NAL is not filled from 0, so if it somehow
739    * leaks - it's not supposed to go outside of the avtpcvdepay
740    * as it doesn't have M bit set - we can catch on checks below */
741   gst_buffer_map (in, &map, GST_MAP_READWRITE);
742   pdu = (struct avtp_stream_pdu *) map.data;
743   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
744   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 3);
745   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x1;    /* Add NAL type */
746   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 5);
747   gst_buffer_unmap (in, &map);
748 
749   gst_harness_push (h, gst_buffer_copy (in));
750   fail_unless_equals_int (gst_harness_buffers_received (h), 1);
751 
752   out = gst_harness_pull (h);
753   fail_unless_equals_uint64 (GST_BUFFER_DTS (out), 1000000);
754   fail_unless_equals_uint64 (GST_BUFFER_PTS (out), 2000000);
755 
756   /* Validate each NAL unit size and content */
757   offset = 0;
758   nal = fetch_nal (out, &offset);
759   fail_unless_equals_uint64 (nal_size (nal), 4);
760   fail_unless (check_nal_filling (nal, 0) == TRUE);
761   fail_unless_equals_uint64 (nal_type (nal), 7);
762   gst_buffer_unref (nal);
763 
764   nal = fetch_nal (out, &offset);
765   fail_unless_equals_uint64 (nal_size (nal), 4);
766   fail_unless (check_nal_filling (nal, 0) == TRUE);
767   fail_unless_equals_uint64 (nal_type (nal), 7);
768   gst_buffer_unref (nal);
769 
770   /* Ensure no other NAL units are present */
771   nal = fetch_nal (out, &offset);
772   fail_unless (nal == NULL);
773 
774   gst_buffer_unref (out);
775   gst_buffer_unref (in);
776   gst_harness_teardown (h);
777 }
778 
779 GST_END_TEST;
780 
781 /* This test simulates a scenario in which one single NAL unit is sent,
782  * followed by a fragment without start bit set, so fragment is discarded
783  * and previous single NAL is sent to the pipeline, as avtpcvfdepay is not
784  * sure about the sanity of the data anymore - but hopes h264decoder knows
785  * what to do. This scenario emerges from misbehaving payloaders. */
GST_START_TEST(test_depayloader_single_and_messed_fragments)786 GST_START_TEST (test_depayloader_single_and_messed_fragments)
787 {
788   GstHarness *h;
789   GstBuffer *in, *out, *nal;
790   const gint DATA_LEN = sizeof (guint32) + 4;
791   struct avtp_stream_pdu *pdu;
792   GstMapInfo map;
793   gsize offset;
794 
795   /* Create the harness for the avtpcvfpay */
796   h = gst_harness_new ("avtpcvfdepay");
797   gst_harness_set_src_caps_str (h, "application/x-avtp");
798 
799   /* Create the input AVTPDU header */
800   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 4);
801   gst_buffer_map (in, &map, GST_MAP_READWRITE);
802   pdu = (struct avtp_stream_pdu *) map.data;
803 
804   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
805   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
806   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
807   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
808   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
809   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
810   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
811   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
812   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x1;    /* Add NAL type */
813   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 0);
814   gst_buffer_unmap (in, &map);
815 
816   /* First, we send a single NAL with M = 0, so nothing should come out */
817   gst_harness_push (h, gst_buffer_copy (in));
818   fail_unless (gst_harness_try_pull (h) == NULL);
819 
820   /* Then, we send invalid fragment */
821   gst_buffer_map (in, &map, GST_MAP_READWRITE);
822   pdu = (struct avtp_stream_pdu *) map.data;
823   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
824   map.data[AVTP_CVF_H264_HEADER_SIZE] = 3 << 5 | 28;    /* NAL type FU-A, NRI 3 */
825   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = 4;  /* S = 0, type 4 */
826   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 2, 0);
827   gst_buffer_unmap (in, &map);
828 
829   /* When we push it, it should be discarded, but previous single NAL
830    * should come out */
831   out = gst_harness_push_and_pull (h, gst_buffer_copy (in));
832 
833   /* Check that we got the right one */
834   fail_unless_equals_uint64 (GST_BUFFER_DTS (out), 1000000);
835   fail_unless_equals_uint64 (GST_BUFFER_PTS (out), 2000000);
836 
837   offset = 0;
838   nal = fetch_nal (out, &offset);
839   fail_unless_equals_uint64 (nal_size (nal), 4);
840   fail_unless_equals_uint64 (nal_type (nal), 1);
841   fail_unless (check_nal_filling (nal, 0) == TRUE);
842   gst_buffer_unref (nal);
843 
844   /* Ensure no other NAL units are present */
845   nal = fetch_nal (out, &offset);
846   fail_unless (nal == NULL);
847 
848   gst_buffer_unref (out);
849   gst_buffer_unref (in);
850   gst_harness_teardown (h);
851 }
852 
853 GST_END_TEST;
854 
855 /* This test explores the case in which a fragment is followed by
856  * a single NAL - and not by an ending fragment. Fragments stored
857  * so far are dropped, and things shall flow normally for the single NAL.
858  * This can be created by a misbehaving payloader */
GST_START_TEST(test_depayloader_single_and_messed_fragments_2)859 GST_START_TEST (test_depayloader_single_and_messed_fragments_2)
860 {
861   GstHarness *h;
862   GstBuffer *in, *out, *nal;
863   const gint DATA_LEN = sizeof (guint32) + 4;
864   struct avtp_stream_pdu *pdu;
865   GstMapInfo map;
866   gsize offset;
867 
868   /* Create the harness for the avtpcvfpay */
869   h = gst_harness_new ("avtpcvfdepay");
870   gst_harness_set_src_caps_str (h, "application/x-avtp");
871 
872   /* Create the input AVTPDU header */
873   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 4);
874   gst_buffer_map (in, &map, GST_MAP_READWRITE);
875   pdu = (struct avtp_stream_pdu *) map.data;
876 
877   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
878   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
879   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
880   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
881   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
882   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
883   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
884   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
885   map.data[AVTP_CVF_H264_HEADER_SIZE] = 3 << 5 | 28;    /* NAL type FU-A, NRI 3 */
886   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 7) | 4;       /* S = 1, type 4 */
887   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 2, 0);
888   gst_buffer_unmap (in, &map);
889 
890   /* Send a perfectly valid start fragment */
891   gst_harness_push (h, gst_buffer_copy (in));
892   fail_unless (gst_harness_try_pull (h) == NULL);
893 
894   /* Then, we send a single NAL. Previous fragment should be dropped */
895   gst_buffer_map (in, &map, GST_MAP_READWRITE);
896   pdu = (struct avtp_stream_pdu *) map.data;
897   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
898   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
899   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x2;    /* Add NAL type */
900   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 5);
901   gst_buffer_unmap (in, &map);
902 
903   /* When we push it, it should come out as it has M = 1 */
904   out = gst_harness_push_and_pull (h, gst_buffer_copy (in));
905 
906   /* Check that we got the right one - its NAL filling should start with 5 */
907   fail_unless_equals_uint64 (GST_BUFFER_DTS (out), 1000000);
908   fail_unless_equals_uint64 (GST_BUFFER_PTS (out), 2000000);
909 
910   offset = 0;
911   nal = fetch_nal (out, &offset);
912   fail_unless_equals_uint64 (nal_size (nal), 4);
913   fail_unless_equals_uint64 (nal_type (nal), 2);
914   fail_unless (check_nal_filling (nal, 5) == TRUE);
915   gst_buffer_unref (nal);
916 
917   /* Ensure no other NAL units are present */
918   nal = fetch_nal (out, &offset);
919   fail_unless (nal == NULL);
920 
921   /* To be really sure, send an ending fragment. It should be dropped,
922    * as there should not be any previous fragment on the wait */
923   gst_buffer_map (in, &map, GST_MAP_READWRITE);
924   pdu = (struct avtp_stream_pdu *) map.data;
925   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 2);
926   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
927   map.data[AVTP_CVF_H264_HEADER_SIZE] = 3 << 5 | 28;    /* NAL type FU-A, NRI 3 */
928   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 6) | 4;       /* E = 1, type 4 */
929   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 2, 2);
930   gst_buffer_unmap (in, &map);
931 
932   gst_harness_push (h, gst_buffer_copy (in));
933   fail_unless (gst_harness_try_pull (h) == NULL);
934 
935   gst_buffer_unref (out);
936   gst_buffer_unref (in);
937   gst_harness_teardown (h);
938 }
939 
940 GST_END_TEST;
941 
942 /* This test ensures that, if a fragment is dropped due arrival of a single
943  * NAL (and fragment was never completed), any previous single NAL waiting
944  * for M set NAL are flushed to the pipeline. avtpcvfdepay never sents known
945  * incomplete NAL units to the pipeline, but should not hold forever NALs
946  * waiting for an M set NAL - specially after something wrong already happened */
GST_START_TEST(test_depayloader_single_and_messed_fragments_3)947 GST_START_TEST (test_depayloader_single_and_messed_fragments_3)
948 {
949   GstHarness *h;
950   GstBuffer *in, *out, *nal;
951   const gint DATA_LEN = sizeof (guint32) + 4;
952   struct avtp_stream_pdu *pdu;
953   GstMapInfo map;
954   gsize offset;
955 
956   /* Create the harness for the avtpcvfpay */
957   h = gst_harness_new ("avtpcvfdepay");
958   gst_harness_set_src_caps_str (h, "application/x-avtp");
959 
960   /* Create the input AVTPDU header */
961   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 4);
962   gst_buffer_map (in, &map, GST_MAP_READWRITE);
963   pdu = (struct avtp_stream_pdu *) map.data;
964 
965   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
966   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
967   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
968   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
969   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
970   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
971   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
972   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
973   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x2;    /* Add NAL type */
974   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 0);
975   gst_buffer_unmap (in, &map);
976 
977   /* Send a single NAL with M = 0, so nothing will come out */
978   gst_harness_push (h, gst_buffer_copy (in));
979   fail_unless (gst_harness_try_pull (h) == NULL);
980 
981   /* Send a valid start fragment */
982   gst_buffer_map (in, &map, GST_MAP_READWRITE);
983   pdu = (struct avtp_stream_pdu *) map.data;
984   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
985   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
986   map.data[AVTP_CVF_H264_HEADER_SIZE] = 3 << 5 | 28;    /* NAL type FU-A, NRI 3 */
987   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 7) | 4;       /* S = 1, type 4 */
988   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 2, 0);
989   gst_buffer_unmap (in, &map);
990 
991   gst_harness_push (h, gst_buffer_copy (in));
992   fail_unless (gst_harness_try_pull (h) == NULL);
993 
994   /* Send a single NAL without ending fragment. So, both first NAL and second should
995    * come out, on two different buffers. Fragment should be gone. */
996   gst_buffer_map (in, &map, GST_MAP_READWRITE);
997   pdu = (struct avtp_stream_pdu *) map.data;
998   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 2);
999   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
1000   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x3;    /* Add NAL type */
1001   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 7);
1002   gst_buffer_unmap (in, &map);
1003 
1004   gst_harness_push (h, gst_buffer_copy (in));
1005   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 2);
1006 
1007   /* Check that we got the right ones. First has nal_type 2, and second 3.
1008    * Second also has its nal filling starting from 7  */
1009   out = gst_harness_pull (h);
1010   fail_unless_equals_uint64 (GST_BUFFER_DTS (out), 1000000);
1011   fail_unless_equals_uint64 (GST_BUFFER_PTS (out), 2000000);
1012 
1013   offset = 0;
1014   nal = fetch_nal (out, &offset);
1015   fail_unless_equals_uint64 (nal_size (nal), 4);
1016   fail_unless_equals_uint64 (nal_type (nal), 2);
1017   fail_unless (check_nal_filling (nal, 0) == TRUE);
1018   gst_buffer_unref (nal);
1019 
1020   /* Ensure no other NAL units are present */
1021   nal = fetch_nal (out, &offset);
1022   fail_unless (nal == NULL);
1023   gst_buffer_unref (out);
1024 
1025   out = gst_harness_pull (h);
1026   fail_unless_equals_uint64 (GST_BUFFER_DTS (out), 1000000);
1027   fail_unless_equals_uint64 (GST_BUFFER_PTS (out), 2000000);
1028 
1029   offset = 0;
1030   nal = fetch_nal (out, &offset);
1031   fail_unless_equals_uint64 (nal_size (nal), 4);
1032   fail_unless_equals_uint64 (nal_type (nal), 3);
1033   fail_unless (check_nal_filling (nal, 7) == TRUE);
1034   gst_buffer_unref (nal);
1035 
1036   /* Ensure no other NAL units are present */
1037   nal = fetch_nal (out, &offset);
1038   fail_unless (nal == NULL);
1039   gst_buffer_unref (out);
1040 
1041   /* To be really sure, send an ending fragment. It should be dropped,
1042    * as there should not be any previous fragment on the wait */
1043   gst_buffer_map (in, &map, GST_MAP_READWRITE);
1044   pdu = (struct avtp_stream_pdu *) map.data;
1045   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 3);
1046   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
1047   map.data[AVTP_CVF_H264_HEADER_SIZE] = 3 << 5 | 28;    /* NAL type FU-A, NRI 3 */
1048   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 6) | 4;       /* E = 1, type 4 */
1049   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 2, 2);
1050   gst_buffer_unmap (in, &map);
1051 
1052   gst_harness_push (h, gst_buffer_copy (in));
1053   fail_unless (gst_harness_try_pull (h) == NULL);
1054 
1055   gst_buffer_unref (in);
1056   gst_harness_teardown (h);
1057 }
1058 
1059 GST_END_TEST;
1060 
GST_START_TEST(test_depayloader_property)1061 GST_START_TEST (test_depayloader_property)
1062 {
1063   GstHarness *h;
1064   GstElement *element;
1065   guint64 streamid;
1066 
1067   /* Create the harness for the avtpcvfpay */
1068   h = gst_harness_new_parse ("avtpcvfdepay streamid=0xAABBCCDDEEFF0001");
1069 
1070   /* Check if property was properly set up */
1071   element = gst_harness_find_element (h, "avtpcvfdepay");
1072   g_object_get (G_OBJECT (element), "streamid", &streamid, NULL);
1073   fail_unless_equals_uint64 (streamid, 0xAABBCCDDEEFF0001);
1074 
1075   gst_object_unref (element);
1076   gst_harness_teardown (h);
1077 }
1078 
1079 GST_END_TEST;
1080 
1081 /* Tests if everything goes right when a single NAL unit without M bit is
1082  * followed by fragments that, when merged, have the M bit set */
GST_START_TEST(test_depayloader_single_and_fragmented)1083 GST_START_TEST (test_depayloader_single_and_fragmented)
1084 {
1085   GstHarness *h;
1086   GstBuffer *in, *out, *nal;
1087   const gint DATA_LEN = sizeof (guint32) + 4;
1088   struct avtp_stream_pdu *pdu;
1089   GstMapInfo map;
1090   gsize offset;
1091 
1092   /* Create the harness for the avtpcvfpay */
1093   h = gst_harness_new ("avtpcvfdepay");
1094   gst_harness_set_src_caps_str (h, "application/x-avtp");
1095 
1096   /* Create the input AVTPDU header */
1097   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 4);
1098   gst_buffer_map (in, &map, GST_MAP_READWRITE);
1099   pdu = (struct avtp_stream_pdu *) map.data;
1100 
1101   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
1102   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
1103   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
1104   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
1105   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
1106   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
1107   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
1108   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
1109   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x1;    /* Add NAL type */
1110   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 0);
1111   gst_buffer_unmap (in, &map);
1112 
1113   /* First, we send a single NAL with M = 0, so nothing should come out */
1114   gst_harness_push (h, gst_buffer_copy (in));
1115   fail_unless (gst_harness_try_pull (h) == NULL);
1116 
1117   /* Then, we send first fragment */
1118   gst_buffer_map (in, &map, GST_MAP_READWRITE);
1119   pdu = (struct avtp_stream_pdu *) map.data;
1120   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
1121   map.data[AVTP_CVF_H264_HEADER_SIZE] = 3 << 5 | 28;    /* NAL type FU-A, NRI 3 */
1122   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 7) | 4;       /* S = 1, type 4 */
1123   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 2, 0);
1124   gst_buffer_unmap (in, &map);
1125 
1126   gst_harness_push (h, gst_buffer_copy (in));
1127   fail_unless (gst_harness_try_pull (h) == NULL);
1128 
1129   /* And last */
1130   gst_buffer_map (in, &map, GST_MAP_READWRITE);
1131   pdu = (struct avtp_stream_pdu *) map.data;
1132   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 2);
1133   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
1134   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 6) | 4;       /* E = 1, type 4 */
1135   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 2, 2);
1136   gst_buffer_unmap (in, &map);
1137 
1138   gst_harness_push (h, gst_buffer_copy (in));
1139   fail_unless_equals_int (gst_harness_buffers_received (h), 1);
1140 
1141   out = gst_harness_pull (h);
1142   fail_unless_equals_uint64 (GST_BUFFER_DTS (out), 1000000);
1143   fail_unless_equals_uint64 (GST_BUFFER_PTS (out), 2000000);
1144 
1145   /* Validate each NAL unit size and content */
1146   offset = 0;
1147   nal = fetch_nal (out, &offset);
1148   fail_unless_equals_uint64 (nal_size (nal), 4);
1149   fail_unless (check_nal_filling (nal, 0) == TRUE);
1150   fail_unless_equals_uint64 (nal_type (nal), 1);
1151   gst_buffer_unref (nal);
1152   nal = fetch_nal (out, &offset);
1153   fail_unless_equals_uint64 (nal_size (nal), 5);
1154   fail_unless (check_nal_filling (nal, 0) == TRUE);
1155   fail_unless_equals_uint64 (nal_type (nal), 4);
1156   gst_buffer_unref (nal);
1157 
1158   /* Ensure no other NAL units are present */
1159   nal = fetch_nal (out, &offset);
1160   fail_unless (nal == NULL);
1161 
1162   gst_buffer_unref (out);
1163   gst_buffer_unref (in);
1164   gst_harness_teardown (h);
1165 }
1166 
1167 GST_END_TEST;
1168 
1169 /* Tests a simple fragmented NAL scenario */
GST_START_TEST(test_depayloader_fragmented)1170 GST_START_TEST (test_depayloader_fragmented)
1171 {
1172   GstHarness *h;
1173   GstBuffer *in, *out, *nal;
1174   const gint DATA_LEN = sizeof (guint32) + 10;
1175   struct avtp_stream_pdu *pdu;
1176   GstMapInfo map;
1177   gsize offset;
1178 
1179   /* Create the harness for the avtpcvfpay */
1180   h = gst_harness_new ("avtpcvfdepay");
1181   gst_harness_set_src_caps_str (h, "application/x-avtp");
1182 
1183   /* Create the input AVTPDU */
1184   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 10);
1185   gst_buffer_map (in, &map, GST_MAP_READWRITE);
1186   pdu = (struct avtp_stream_pdu *) map.data;
1187 
1188   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
1189   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
1190   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 0);
1191   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
1192   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 0);
1193   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
1194   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
1195   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
1196   map.data[AVTP_CVF_H264_HEADER_SIZE] = 3 << 5 | 28;    /* NAL type FU-A, NRI 3 */
1197   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 7) | 4;       /* S = 1, type 4 */
1198   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 8, 0);
1199   gst_buffer_unmap (in, &map);
1200 
1201   /* We push a copy so that we can change only what is necessary on our buffer */
1202   gst_harness_push (h, gst_buffer_copy (in));
1203   fail_unless (gst_harness_try_pull (h) == NULL);
1204 
1205   /* Send second AVTPDU */
1206   gst_buffer_map (in, &map, GST_MAP_READWRITE);
1207   pdu = (struct avtp_stream_pdu *) map.data;
1208   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
1209   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = 4;  /* type 4 */
1210   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 8, 8);
1211   gst_buffer_unmap (in, &map);
1212 
1213   gst_harness_push (h, gst_buffer_copy (in));
1214   fail_unless (gst_harness_try_pull (h) == NULL);
1215 
1216   /* Send third and last AVTPDU */
1217   gst_buffer_map (in, &map, GST_MAP_READWRITE);
1218   pdu = (struct avtp_stream_pdu *) map.data;
1219   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
1220   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
1221   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
1222   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 2);
1223   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 6) | 4;       /* E = 1, type 4 */
1224   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], 8, 16);
1225   gst_buffer_unmap (in, &map);
1226 
1227   gst_harness_push (h, gst_buffer_copy (in));
1228   fail_unless_equals_int (gst_harness_buffers_received (h), 1);
1229 
1230   out = gst_harness_pull (h);
1231   fail_unless_equals_uint64 (GST_BUFFER_DTS (out), 1000000);
1232   fail_unless_equals_uint64 (GST_BUFFER_PTS (out), 2000000);
1233 
1234   offset = 0;
1235   nal = fetch_nal (out, &offset);
1236   fail_unless_equals_uint64 (nal_size (nal), 25);
1237   fail_unless (check_nal_filling (nal, 0) == TRUE);
1238   fail_unless_equals_uint64 (nal_type (nal), 4);
1239   gst_buffer_unref (nal);
1240 
1241   gst_buffer_unref (out);
1242   gst_buffer_unref (in);
1243   gst_harness_teardown (h);
1244 }
1245 
1246 GST_END_TEST;
1247 
1248 /* Tests a big fragmented NAL scenario */
GST_START_TEST(test_depayloader_fragmented_big)1249 GST_START_TEST (test_depayloader_fragmented_big)
1250 {
1251   GstHarness *h;
1252   GstBuffer *in, *out, *nal;
1253   const gint DATA_LEN = 1470;
1254   struct avtp_stream_pdu *pdu;
1255   /* 12000 * 1468 > 2^24 - so we can check if nal size is retrieved correctly */
1256   const gint nal_count = 12000;
1257   guint8 seq_num = 0;
1258   GstMapInfo map;
1259   gsize offset;
1260   gint i;
1261 
1262   /* Create the harness for the avtpcvfpay */
1263   h = gst_harness_new ("avtpcvfdepay");
1264   gst_harness_set_src_caps_str (h, "application/x-avtp");
1265 
1266   /* Create the input AVTPDU */
1267   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + DATA_LEN);
1268   gst_buffer_map (in, &map, GST_MAP_READWRITE);
1269   pdu = (struct avtp_stream_pdu *) map.data;
1270 
1271   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
1272   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
1273   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 0);
1274   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
1275   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 0);
1276   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
1277   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
1278   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN,
1279       DATA_LEN + sizeof (guint32));
1280   map.data[AVTP_CVF_H264_HEADER_SIZE] = 3 << 5 | 28;    /* NAL type FU-A, NRI 3 */
1281   map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 7) | 4;       /* S = 1, type 4 */
1282   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], DATA_LEN - 2, 0);
1283   gst_buffer_unmap (in, &map);
1284 
1285   /* We push a copy so that we can change only what is necessary on our buffer */
1286   gst_harness_push (h, gst_buffer_copy (in));
1287   fail_unless (gst_harness_try_pull (h) == NULL);
1288 
1289   /* Loop sending fragments. The idea is to create a NAL unit big enough
1290    * to use the 4 bytes of nal_length_size */
1291   for (i = 0; i < nal_count - 1; i++) {
1292 
1293     gst_buffer_map (in, &map, GST_MAP_READWRITE);
1294     pdu = (struct avtp_stream_pdu *) map.data;
1295     avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, ++seq_num);
1296     map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = 4;        /* type 4 */
1297     fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 2], DATA_LEN - 2,
1298         (guint8) ((DATA_LEN - 2) * seq_num));
1299 
1300     /* Last one is special - need to set M and TV, etc */
1301     if (i == nal_count - 2) {
1302       avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
1303       avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
1304       avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
1305       map.data[AVTP_CVF_H264_HEADER_SIZE + 1] = (1 << 6) | 4;   /* E = 1, type 4 */
1306     }
1307 
1308     gst_buffer_unmap (in, &map);
1309 
1310     gst_harness_push (h, gst_buffer_copy (in));
1311     if (i < nal_count - 2)
1312       fail_unless (gst_harness_try_pull (h) == NULL);
1313   }
1314 
1315   /* After last one was sent, we check everything */
1316   fail_unless_equals_int (gst_harness_buffers_received (h), 1);
1317 
1318   out = gst_harness_pull (h);
1319   fail_unless_equals_uint64 (GST_BUFFER_DTS (out), 1000000);
1320   fail_unless_equals_uint64 (GST_BUFFER_PTS (out), 2000000);
1321 
1322   offset = 0;
1323   nal = fetch_nal (out, &offset);
1324   fail_unless_equals_uint64 (nal_size (nal), (DATA_LEN - 2) * nal_count + 1);
1325   fail_unless (check_nal_filling (nal, 0) == TRUE);
1326   fail_unless_equals_uint64 (nal_type (nal), 4);
1327   gst_buffer_unref (nal);
1328 
1329   gst_buffer_unref (out);
1330   gst_buffer_unref (in);
1331   gst_harness_teardown (h);
1332 }
1333 
1334 GST_END_TEST;
1335 
1336 /* Tests several single NAL units. They should be grouped and delivered
1337  * to the pipeline only when one NAL unit with M bit set arrives */
GST_START_TEST(test_depayloader_multiple_single)1338 GST_START_TEST (test_depayloader_multiple_single)
1339 {
1340   GstHarness *h;
1341   GstBuffer *in, *out, *nal;
1342   const gint DATA_LEN = sizeof (guint32) + 4;
1343   struct avtp_stream_pdu *pdu;
1344   GstMapInfo map;
1345   gsize offset;
1346 
1347   /* Create the harness for the avtpcvfpay */
1348   h = gst_harness_new ("avtpcvfdepay");
1349   gst_harness_set_src_caps_str (h, "application/x-avtp");
1350 
1351   /* Create the input AVTPDU header */
1352   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 4);
1353   gst_buffer_map (in, &map, GST_MAP_READWRITE);
1354   pdu = (struct avtp_stream_pdu *) map.data;
1355 
1356   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
1357   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
1358   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
1359   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
1360   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
1361   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
1362   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
1363   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
1364   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x7;    /* Add NAL type */
1365   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 0);
1366   gst_buffer_unmap (in, &map);
1367 
1368   /* We push a copy so that we can change only what is necessary on our buffer */
1369   gst_harness_push (h, gst_buffer_copy (in));
1370   fail_unless (gst_harness_try_pull (h) == NULL);
1371 
1372   /* Send second AVTPDU */
1373   gst_buffer_map (in, &map, GST_MAP_READWRITE);
1374   pdu = (struct avtp_stream_pdu *) map.data;
1375   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
1376   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 0);
1377   gst_buffer_unmap (in, &map);
1378 
1379   gst_harness_push (h, gst_buffer_copy (in));
1380   fail_unless (gst_harness_try_pull (h) == NULL);
1381 
1382   /* Send third and last AVTPDU */
1383   gst_buffer_map (in, &map, GST_MAP_READWRITE);
1384   pdu = (struct avtp_stream_pdu *) map.data;
1385   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
1386   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 2);
1387   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x1;    /* Add NAL type */
1388   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 0);
1389   gst_buffer_unmap (in, &map);
1390 
1391   gst_harness_push (h, gst_buffer_copy (in));
1392   fail_unless_equals_int (gst_harness_buffers_received (h), 1);
1393 
1394   out = gst_harness_pull (h);
1395   fail_unless_equals_uint64 (GST_BUFFER_DTS (out), 1000000);
1396   fail_unless_equals_uint64 (GST_BUFFER_PTS (out), 2000000);
1397 
1398   /* Validate each NAL unit size and content */
1399   offset = 0;
1400   nal = fetch_nal (out, &offset);
1401   fail_unless_equals_uint64 (nal_size (nal), 4);
1402   fail_unless (check_nal_filling (nal, 0) == TRUE);
1403   fail_unless_equals_uint64 (nal_type (nal), 7);
1404   gst_buffer_unref (nal);
1405   nal = fetch_nal (out, &offset);
1406   fail_unless_equals_uint64 (nal_size (nal), 4);
1407   fail_unless (check_nal_filling (nal, 0) == TRUE);
1408   fail_unless_equals_uint64 (nal_type (nal), 7);
1409   gst_buffer_unref (nal);
1410   nal = fetch_nal (out, &offset);
1411   fail_unless_equals_uint64 (nal_size (nal), 4);
1412   fail_unless (check_nal_filling (nal, 0) == TRUE);
1413   fail_unless_equals_uint64 (nal_type (nal), 1);
1414   gst_buffer_unref (nal);
1415 
1416   /* Ensure no other NAL units are present */
1417   nal = fetch_nal (out, &offset);
1418   fail_unless (nal == NULL);
1419 
1420   gst_buffer_unref (out);
1421   gst_buffer_unref (in);
1422   gst_harness_teardown (h);
1423 }
1424 
1425 GST_END_TEST;
1426 
GST_START_TEST(test_depayloader_single)1427 GST_START_TEST (test_depayloader_single)
1428 {
1429   GstHarness *h;
1430   GstBuffer *in, *out;
1431   const gint DATA_LEN = sizeof (guint32) + 4;
1432   struct avtp_stream_pdu *pdu;
1433   GstMapInfo map;
1434 
1435   /* Create the harness for the avtpcvfpay */
1436   h = gst_harness_new ("avtpcvfdepay");
1437   gst_harness_set_src_caps_str (h, "application/x-avtp");
1438 
1439   /* Create the input AVTPDU header */
1440   in = gst_harness_create_buffer (h, AVTP_CVF_H264_HEADER_SIZE + 4);
1441   gst_buffer_map (in, &map, GST_MAP_READWRITE);
1442   pdu = (struct avtp_stream_pdu *) map.data;
1443 
1444   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
1445   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
1446   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
1447   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
1448   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 1000000);
1449   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
1450   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 2000000);
1451   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
1452   map.data[AVTP_CVF_H264_HEADER_SIZE] = 0x1;    /* Add NAL type */
1453   fill_nal (&map.data[AVTP_CVF_H264_HEADER_SIZE + 1], 3, 0);
1454   gst_buffer_unmap (in, &map);
1455 
1456   out = gst_harness_push_and_pull (h, in);
1457 
1458   fail_unless_equals_uint64 (GST_BUFFER_DTS (out), 1000000);
1459   fail_unless_equals_uint64 (GST_BUFFER_PTS (out), 2000000);
1460   fail_unless_equals_uint64 (nal_size (out), 4);
1461   fail_unless_equals_uint64 (nal_type (out), 1);
1462   fail_unless (check_nal_filling (out, 0) == TRUE);
1463   gst_buffer_unref (out);
1464   gst_harness_teardown (h);
1465 }
1466 
1467 GST_END_TEST;
1468 
1469 static Suite *
avtpcvfdepay_suite(void)1470 avtpcvfdepay_suite (void)
1471 {
1472   Suite *s = suite_create ("avtpcvfdepay");
1473   TCase *tc_chain = tcase_create ("general");
1474   TCase *tc_slow = tcase_create ("slow");
1475 
1476   suite_add_tcase (s, tc_chain);
1477   tcase_add_test (tc_chain, test_depayloader_single);
1478   tcase_add_test (tc_chain, test_depayloader_multiple_single);
1479   tcase_add_test (tc_chain, test_depayloader_fragmented);
1480   tcase_add_test (tc_chain, test_depayloader_single_and_fragmented);
1481   tcase_add_test (tc_chain, test_depayloader_property);
1482   tcase_add_test (tc_chain, test_depayloader_lost_packet);
1483   tcase_add_test (tc_chain, test_depayloader_lost_fragments);
1484   tcase_add_test (tc_chain, test_depayloader_single_and_messed_fragments);
1485   tcase_add_test (tc_chain, test_depayloader_single_and_messed_fragments_2);
1486   tcase_add_test (tc_chain, test_depayloader_single_and_messed_fragments_3);
1487   tcase_add_test (tc_chain, test_depayloader_invalid_avtpdu);
1488   tcase_add_test (tc_chain, test_depayloader_single_eos);
1489   tcase_add_test (tc_chain, test_depayloader_fragmented_eos);
1490   tcase_add_test (tc_chain, test_depayloader_fragmented_two_start_eos);
1491   tcase_add_test (tc_chain, test_depayloader_multiple_lost_eos);
1492   tcase_add_test (tc_chain, test_depayloader_fragment_and_single);
1493 
1494   suite_add_tcase (s, tc_slow);
1495   /* 'fragmented_big' may take some time to run, so give it a bit more time */
1496   tcase_set_timeout (tc_slow, 20);
1497   tcase_add_test (tc_slow, test_depayloader_fragmented_big);
1498 
1499   return s;
1500 }
1501 
1502 GST_CHECK_MAIN (avtpcvfdepay);
1503