documentation: fixed a heap o' typos
[platform/upstream/gstreamer.git] / tests / check / elements / avtpcvfpay.c
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 0xAABBCCDDEEFF0001
30
31 /* Simple codec data, with only the NAL size len, no SPS/PPS. */
32 static GstCaps *
33 generate_caps (guint8 nal_size_len)
34 {
35   GstBuffer *codec_data;
36   GstMapInfo map;
37   GstCaps *caps;
38
39   /* 7 is the minimal codec_data size, when no SPS/PPS is sent */
40   codec_data = gst_buffer_new_allocate (NULL, 7, NULL);
41   gst_buffer_map (codec_data, &map, GST_MAP_READWRITE);
42
43   memset (map.data, 0, map.size);
44   map.data[0] = 1;              /* version */
45   map.data[4] = (nal_size_len - 1) | 0xfc;      /* Other 6 bits are 1 */
46   map.data[5] = 0xe0;           /* first 3 bits are 1 */
47
48   gst_buffer_unmap (codec_data, &map);
49
50   caps = gst_caps_new_simple ("video/x-h264",
51       "stream-format", G_TYPE_STRING, "avc",
52       "alignment", G_TYPE_STRING, "au",
53       "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
54   gst_buffer_unref (codec_data);
55
56   return caps;
57 }
58
59 static void
60 fill (guint8 * buf, gsize size)
61 {
62   guint8 i = 0;
63
64   while (size--)
65     *buf++ = i++;
66 }
67
68 static gboolean
69 check_nal_filling (GstBuffer * buffer, guint8 first)
70 {
71   GstMapInfo map;
72   gint i;
73   gsize offset = AVTP_CVF_H264_HEADER_SIZE + 1;
74   gboolean result = TRUE;
75
76   gst_buffer_map (buffer, &map, GST_MAP_READ);
77   if ((map.data[AVTP_CVF_H264_HEADER_SIZE] & 0x1f) == 28)
78     offset++;                   /* Fragmented NALs have 2 bytes header */
79
80   for (i = offset; i < map.size; i++) {
81     if (map.data[i] != first++) {
82       result = FALSE;
83       break;
84     }
85   }
86
87   return result;
88 }
89
90 static void
91 add_nal (GstBuffer * buffer, gsize size, guint type, gsize offset)
92 {
93   GstMapInfo map;
94
95   gst_buffer_map (buffer, &map, GST_MAP_READWRITE);
96
97   map.data[offset] = map.data[offset + 1] = 0;
98   map.data[offset + 2] = size >> 8;
99   map.data[offset + 3] = size & 0xff;
100   map.data[offset + 4] = type & 0x1f;
101   fill (&map.data[offset + 5], size - 1);
102
103   gst_buffer_unmap (buffer, &map);
104 }
105
106 /* This function assumes that NAL size len is 2 */
107 static void
108 add_nal_2 (GstBuffer * buffer, gsize size, guint type, gsize offset)
109 {
110   GstMapInfo map;
111
112   gst_buffer_map (buffer, &map, GST_MAP_READWRITE);
113
114   map.data[offset] = size >> 8;
115   map.data[offset + 1] = size & 0xff;
116   map.data[offset + 2] = type & 0x1f;
117   fill (&map.data[offset + 3], size - 1);
118
119   gst_buffer_unmap (buffer, &map);
120 }
121
122 static gboolean
123 compare_h264_avtpdu (struct avtp_stream_pdu *pdu, GstBuffer * buffer)
124 {
125   GstMapInfo map;
126   gboolean result;
127
128   gst_buffer_map (buffer, &map, GST_MAP_READ);
129   /* buffer must have at least the header size */
130   if (map.size < AVTP_CVF_H264_HEADER_SIZE)
131     return FALSE;
132
133   result = memcmp (map.data, pdu, AVTP_CVF_H264_HEADER_SIZE) == 0;
134
135   gst_buffer_unmap (buffer, &map);
136
137   return result;
138 }
139
140 GST_START_TEST (test_payloader_zero_sized_nal)
141 {
142   GstHarness *h;
143   GstBuffer *in;
144   GstMapInfo map;
145
146   /* Create the harness for the avtpcvfpay */
147   h = gst_harness_new_parse
148       ("avtpcvfpay streamid=0xAABBCCDDEEFF0001 mtt=1000000 tu=1000000 processing-deadline=0");
149   gst_harness_set_src_caps (h, generate_caps (4));
150
151   /* We have the buffer with the nal size (4 bytes) and the nal (4 bytes), but
152    * nal size will be zero */
153   in = gst_harness_create_buffer (h, 8);
154   GST_BUFFER_DTS (in) = 1000000;
155   GST_BUFFER_PTS (in) = 2000000;
156
157   gst_buffer_map (in, &map, GST_MAP_READWRITE);
158   map.data[0] = map.data[1] = map.data[2] = map.data[3] = 0;    /* Set NAL size to 0 */
159   map.data[4] = 1;              /* Some dummy vcl NAL type */
160   gst_buffer_unmap (in, &map);
161
162   gst_harness_push (h, in);
163
164   /* No buffer shuld come out */
165   fail_unless_equals_int (gst_harness_buffers_received (h), 0);
166
167   gst_harness_teardown (h);
168 }
169
170 GST_END_TEST;
171
172 GST_START_TEST (test_payloader_no_codec_data)
173 {
174   GstHarness *h;
175   GstCaps *caps;
176   GstBuffer *in;
177
178   /* Caps without codec_data */
179   caps = gst_caps_new_simple ("video/x-h264",
180       "stream-format", G_TYPE_STRING, "avc",
181       "alignment", G_TYPE_STRING, "au", NULL);
182
183   /* Create the harness for the avtpcvfpay */
184   h = gst_harness_new_parse
185       ("avtpcvfpay streamid=0xAABBCCDDEEFF0001 mtt=1000000 tu=1000000 processing-deadline=0");
186   gst_harness_set_src_caps (h, caps);
187
188   /* No buffer should come out when we send input */
189   in = gst_harness_create_buffer (h, 8);
190   add_nal (in, 4, 1, 0);
191   GST_BUFFER_DTS (in) = 1000000;
192   GST_BUFFER_PTS (in) = 2000000;
193
194   gst_harness_push (h, in);
195   fail_unless_equals_int (gst_harness_buffers_received (h), 0);
196
197   gst_harness_teardown (h);
198 }
199
200 GST_END_TEST;
201
202 GST_START_TEST (test_payloader_invalid_caps)
203 {
204   GstBuffer *codec_data;
205   GstElement *element;
206   GstPad *sinkpad;
207   GstMapInfo map;
208   GstCaps *caps;
209   GstHarness *h;
210
211   /* 7 is the minimal codec_data size, when no SPS/PPS is sent */
212   codec_data = gst_buffer_new_allocate (NULL, 7, NULL);
213   gst_buffer_map (codec_data, &map, GST_MAP_READWRITE);
214
215   memset (map.data, 0, map.size);
216   map.data[0] = 0;              /* version */
217   map.data[4] = 0x03 | 0xfc;    /* Other 6 bits are 1 */
218   map.data[5] = 0xe0;           /* first 3 bits are 1 */
219
220   gst_buffer_unmap (codec_data, &map);
221
222   caps = gst_caps_new_simple ("video/x-h264",
223       "stream-format", G_TYPE_STRING, "avc",
224       "alignment", G_TYPE_STRING, "au",
225       "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
226   gst_buffer_unref (codec_data);
227
228   /* Create the harness for the avtpcvfpay */
229   h = gst_harness_new_parse
230       ("avtpcvfpay streamid=0xAABBCCDDEEFF0001 mtt=1000000 tu=1000000");
231   element = gst_harness_find_element (h, "avtpcvfpay");
232   sinkpad = gst_element_get_static_pad (element, "sink");
233
234   /* 'codec_data' caps has invalid version */
235   gst_harness_push_event (h, gst_event_new_caps (caps));
236   fail_unless (gst_pad_get_current_caps (sinkpad) == NULL);
237   gst_caps_unref (caps);
238
239   /* Send a 'codec_data' too small */
240   codec_data = gst_buffer_new_allocate (NULL, 6, NULL);
241   caps = gst_caps_new_simple ("video/x-h264",
242       "stream-format", G_TYPE_STRING, "avc",
243       "alignment", G_TYPE_STRING, "au",
244       "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
245   gst_buffer_unref (codec_data);
246
247   gst_harness_push_event (h, gst_event_new_caps (caps));
248   fail_unless (gst_pad_get_current_caps (sinkpad) == NULL);
249   gst_caps_unref (caps);
250
251   gst_harness_teardown (h);
252 }
253
254 GST_END_TEST;
255
256 GST_START_TEST (test_payloader_incomplete_nal)
257 {
258   GstHarness *h;
259   GstBuffer *in, *out;
260   GstMapInfo map;
261   struct avtp_stream_pdu *pdu = alloca (AVTP_CVF_H264_HEADER_SIZE);
262   const gint DATA_LEN = sizeof (guint32) + 3;
263
264   /* Create the 'expected' header */
265   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
266   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
267   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
268   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
269   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 3000000);
270   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
271   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 4000000);
272   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
273
274   /* Create the harness for the avtpcvfpay */
275   h = gst_harness_new_parse
276       ("avtpcvfpay streamid=0xAABBCCDDEEFF0001 mtt=1000000 tu=1000000 processing-deadline=0");
277   gst_harness_set_src_caps (h, generate_caps (4));
278
279   /* Buffer must have the nal len (4 bytes) and the nal (3 bytes) */
280   in = gst_harness_create_buffer (h, 7);
281   GST_BUFFER_DTS (in) = 1000000;
282   GST_BUFFER_PTS (in) = 2000000;
283
284   gst_buffer_map (in, &map, GST_MAP_READWRITE);
285   map.data[0] = map.data[1] = map.data[2] = 0;
286   map.data[3] = 8;              /* Lie that NAL size is 8, when buffer is only 7 (so NAL is 3) */
287   map.data[4] = 1;              /* Some dummy vcl NAL type */
288   map.data[5] = 0x0;
289   map.data[6] = 0x1;
290
291   out = gst_harness_push_and_pull (h, in);
292
293   /* avtpcvfpay will happily payload the three byte nal. Now, we check it */
294   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
295   fail_unless (check_nal_filling (out, 0) == TRUE);
296
297   gst_buffer_unref (out);
298   gst_harness_teardown (h);
299 }
300
301 GST_END_TEST;
302
303 GST_START_TEST (test_payloader_properties)
304 {
305   GstHarness *h;
306   GstElement *element;
307   guint mtu, mtt, tu;
308   guint64 streamid, processing_deadline;
309
310   /* Create the harness for the avtpcvfpay */
311   h = gst_harness_new_parse
312       ("avtpcvfpay streamid=0xAABBCCDDEEFF0001 mtt=1000000 tu=2000000 mtu=100 processing-deadline=5000");
313
314   /* Check if all properties were properly set up */
315   element = gst_harness_find_element (h, "avtpcvfpay");
316   g_object_get (G_OBJECT (element), "mtt", &mtt, NULL);
317   fail_unless_equals_uint64 (mtt, 1000000);
318
319   g_object_get (G_OBJECT (element), "mtu", &mtu, NULL);
320   fail_unless_equals_uint64 (mtu, 100);
321
322   g_object_get (G_OBJECT (element), "tu", &tu, NULL);
323   fail_unless_equals_uint64 (tu, 2000000);
324
325   g_object_get (G_OBJECT (element), "streamid", &streamid, NULL);
326   fail_unless_equals_uint64 (streamid, 0xAABBCCDDEEFF0001);
327
328   g_object_get (G_OBJECT (element), "processing-deadline", &processing_deadline,
329       NULL);
330   fail_unless_equals_uint64 (processing_deadline, 5000);
331
332   gst_harness_teardown (h);
333 }
334
335 GST_END_TEST;
336 GST_START_TEST (test_payloader_single_and_fragment_edge)
337 {
338   GstHarness *h;
339   GstBuffer *in, *out;
340   struct avtp_stream_pdu *pdu = alloca (AVTP_CVF_H264_HEADER_SIZE);
341   const gint DATA_LEN_1 = sizeof (guint32) + 100;
342   const gint DATA_LEN_2 = sizeof (guint32) + 100;
343   const gint DATA_LEN_3 = sizeof (guint32) + 4;
344
345   /* Create the 'expected' header */
346   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
347   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
348   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
349   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 3000000);
350   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
351   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 4000000);
352
353   /* Create the harness for the avtpcvfpay. Setting mtu=128 ensures that
354    * NAL units will be broken roughly at 100 bytes. More details below. */
355   h = gst_harness_new_parse
356       ("avtpcvfpay streamid=0xAABBCCDDEEFF0001 mtt=1000000 tu=1000000 mtu=128 processing-deadline=0");
357   gst_harness_set_src_caps (h, generate_caps (4));
358
359   /* Create a buffer to contain the multiple NAL units. This buffer
360    * will hold two NAL units, with 100 and 101 bytes, each preceded
361    * by a 4 bytes header */
362   in = gst_harness_create_buffer (h, 100 + 101 + 2 * 4);
363   add_nal (in, 100, 7, 0);
364   add_nal (in, 101, 1, 104);
365   GST_BUFFER_DTS (in) = 1000000;
366   GST_BUFFER_PTS (in) = 2000000;
367
368   /* We now push the buffer, and check if we get three from the avtpcvfpay */
369   gst_harness_push (h, in);
370   fail_unless (gst_harness_buffers_received (h) == 3);
371
372   out = gst_harness_pull (h);
373   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN_1);
374   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
375   gst_buffer_unref (out);
376
377   out = gst_harness_pull (h);
378   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN_2);
379   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
380   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 0);
381   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 0);
382   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
383   gst_buffer_unref (out);
384
385   /* DATA_LEN_3 is 4 because only 98 bytes from the original NAL unit are
386    * sent on the first buffer (due 2 bytes header), and the two remaining
387    * bytes are preceded by the 2 bytes header. Note that the first byte of
388    * the NAL is stripped before the fragmentation (see comment on
389    * test_payloader_single_and_fragment below for more details). */
390   out = gst_harness_pull (h);
391   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN_3);
392   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 2);
393   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
394   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
395   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 3000000);
396   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
397   gst_buffer_unref (out);
398   gst_harness_teardown (h);
399 }
400
401 GST_END_TEST;
402
403 GST_START_TEST (test_payloader_single_and_fragment)
404 {
405   GstHarness *h;
406   GstBuffer *in, *out;
407   struct avtp_stream_pdu *pdu = alloca (AVTP_CVF_H264_HEADER_SIZE);
408   const gint DATA_LEN_1 = sizeof (guint32) + 4;
409   const gint DATA_LEN_2 = sizeof (guint32) + 100;
410   const gint DATA_LEN_3 = sizeof (guint32) + 100;
411   const gint DATA_LEN_4 = sizeof (guint32) + 55;
412
413   /* Create the 'expected' header */
414   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
415   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
416   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
417   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 4000000);
418   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
419   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 5000000);
420
421   /* Create the harness for the avtpcvfpay. Setting mtu=128 ensures that
422    * NAL units will be broken roughly at 100 bytes. More details below. */
423   h = gst_harness_new_parse
424       ("avtpcvfpay streamid=0xAABBCCDDEEFF0001 mtt=1000000 tu=1000000 processing-deadline=1000000 mtu=128");
425   gst_harness_set_src_caps (h, generate_caps (4));
426
427   /* Create a buffer to contain the multiple NAL units. This buffer
428    * will hold two NAL units, with 4 and 250 bytes, each preceded
429    * by a 4 bytes header */
430   in = gst_harness_create_buffer (h, 4 + 250 + 2 * 4);
431   add_nal (in, 4, 7, 0);
432   add_nal (in, 250, 1, 8);
433   GST_BUFFER_DTS (in) = 1000000;
434   GST_BUFFER_PTS (in) = 2000000;
435
436   /* We now push the buffer, and check if we get four from the avtpcvfpay */
437   gst_harness_push (h, in);
438   fail_unless (gst_harness_buffers_received (h) == 4);
439
440   out = gst_harness_pull (h);
441   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN_1);
442   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
443   fail_unless (check_nal_filling (out, 0) == TRUE);
444   gst_buffer_unref (out);
445
446   out = gst_harness_pull (h);
447   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN_2);
448   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
449   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 0);
450   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 0);
451   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
452   fail_unless (check_nal_filling (out, 0) == TRUE);
453   gst_buffer_unref (out);
454
455   out = gst_harness_pull (h);
456   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN_3);
457   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 2);
458   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 0);
459   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 0);
460   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
461   fail_unless (check_nal_filling (out, 98) == TRUE);
462   gst_buffer_unref (out);
463
464   /* For those wondering why DATA_LEN_4 is 55 and not 50 - or why
465    * comment above states that NAL units are broken "roughly" at 100 bytes:
466    * With mtu=128, there are only 100 bytes left for NAL units, so anything
467    * bigger will be broken. But AVTP NAL units fragments have a header with
468    * two bytes, so NAL units will use only 98 bytes. This leaves the last
469    * fragment with 54 bytes. However, instead of being 56 (54 bytes plus
470    * 2 bytes header), it is 55 (53 bytes plus 2 bytes header) due to the
471    * fact that the first byte of the NAL unit (the NAL unit header) is
472    * in fact stripped from the NAL unit before the fragmentation. */
473   out = gst_harness_pull (h);
474   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN_4);
475   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 3);
476   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
477   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
478   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 4000000);
479   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
480   fail_unless (check_nal_filling (out, 196) == TRUE);
481   gst_buffer_unref (out);
482   gst_harness_teardown (h);
483 }
484
485 GST_END_TEST;
486
487 GST_START_TEST (test_payloader_multiple_single_2)
488 {
489   GstHarness *h;
490   GstBuffer *in, *out;
491   struct avtp_stream_pdu *pdu = alloca (AVTP_CVF_H264_HEADER_SIZE);
492   const gint DATA_LEN_1 = sizeof (guint32) + 32;
493   const gint DATA_LEN_2 = sizeof (guint32) + 16;
494   const gint DATA_LEN_3 = sizeof (guint32) + 8;
495
496   /* Create the 'expected' header */
497   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
498   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
499   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
500   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 3000000);
501   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
502   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 4000000);
503
504   /* Create the harness for the avtpcvfpay */
505   h = gst_harness_new_parse
506       ("avtpcvfpay streamid=0xAABBCCDDEEFF0001 mtt=1000000 tu=1000000 processing-deadline=0");
507   gst_harness_set_src_caps (h, generate_caps (2));
508
509   /* Create a buffer to contain the multiple NAL units. This buffer
510    * will hold three NAL units, with 32, 16 and 8 bytes, each preceded
511    * by a 2 bytes header */
512   in = gst_harness_create_buffer (h, 32 + 16 + 8 + 4 * 2);
513   add_nal_2 (in, 32, 7, 0);
514   add_nal_2 (in, 16, 7, 34);
515   add_nal_2 (in, 8, 1, 52);
516   GST_BUFFER_DTS (in) = 1000000;
517   GST_BUFFER_PTS (in) = 2000000;
518
519   /* We now push the buffer, and check if we get three from the avtpcvfpay */
520   gst_harness_push (h, in);
521   fail_unless (gst_harness_buffers_received (h) == 3);
522
523   out = gst_harness_pull (h);
524   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN_1);
525   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
526   fail_unless (check_nal_filling (out, 0) == TRUE);
527   gst_buffer_unref (out);
528
529   out = gst_harness_pull (h);
530   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN_2);
531   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
532   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
533   fail_unless (check_nal_filling (out, 0) == TRUE);
534   gst_buffer_unref (out);
535
536   out = gst_harness_pull (h);
537   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN_3);
538   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 2);
539   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
540   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
541   fail_unless (check_nal_filling (out, 0) == TRUE);
542   gst_buffer_unref (out);
543   gst_harness_teardown (h);
544 }
545
546 GST_END_TEST;
547
548 GST_START_TEST (test_payloader_multiple_single)
549 {
550   GstHarness *h;
551   GstBuffer *in, *out;
552   struct avtp_stream_pdu *pdu = alloca (AVTP_CVF_H264_HEADER_SIZE);
553   const gint DATA_LEN_1 = sizeof (guint32) + 32;
554   const gint DATA_LEN_2 = sizeof (guint32) + 16;
555   const gint DATA_LEN_3 = sizeof (guint32) + 8;
556
557   /* Create the 'expected' header */
558   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
559   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
560   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
561   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 3000000);
562   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
563   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 4000000);
564
565   /* Create the harness for the avtpcvfpay */
566   h = gst_harness_new_parse
567       ("avtpcvfpay streamid=0xAABBCCDDEEFF0001 mtt=1000000 tu=1000000 processing-deadline=0");
568   gst_harness_set_src_caps (h, generate_caps (4));
569
570   /* Create a buffer to contain the multiple NAL units. This buffer
571    * will hold three NAL units, with 32, 16 and 8 bytes, each preceded
572    * by a 4 bytes header */
573   in = gst_harness_create_buffer (h, 32 + 16 + 8 + 4 * 4);
574   add_nal (in, 32, 7, 0);
575   add_nal (in, 16, 7, 36);
576   add_nal (in, 8, 1, 56);
577   GST_BUFFER_DTS (in) = 1000000;
578   GST_BUFFER_PTS (in) = 2000000;
579
580   /* We now push the buffer, and check if we get three from the avtpcvfpay */
581   gst_harness_push (h, in);
582   fail_unless (gst_harness_buffers_received (h) == 3);
583
584   out = gst_harness_pull (h);
585   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN_1);
586   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
587   fail_unless (check_nal_filling (out, 0) == TRUE);
588   gst_buffer_unref (out);
589
590   out = gst_harness_pull (h);
591   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN_2);
592   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
593   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
594   fail_unless (check_nal_filling (out, 0) == TRUE);
595   gst_buffer_unref (out);
596
597   out = gst_harness_pull (h);
598   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN_3);
599   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 2);
600   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
601   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
602   fail_unless (check_nal_filling (out, 0) == TRUE);
603   gst_buffer_unref (out);
604   gst_harness_teardown (h);
605 }
606
607 GST_END_TEST;
608
609 GST_START_TEST (test_payloader_single)
610 {
611   GstHarness *h;
612   GstBuffer *in, *out;
613   struct avtp_stream_pdu *pdu = alloca (AVTP_CVF_H264_HEADER_SIZE);
614   const gint DATA_LEN = sizeof (guint32) + 4;
615
616   /* Create the 'expected' header */
617   avtp_cvf_pdu_init (pdu, AVTP_CVF_FORMAT_SUBTYPE_H264);
618   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID);
619   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TV, 1);
620   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 1);
621   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_TIMESTAMP, 3000000);
622   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_PTV, 1);
623   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 4000000);
624   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, DATA_LEN);
625
626   /* Create the harness for the avtpcvfpay */
627   h = gst_harness_new_parse
628       ("avtpcvfpay streamid=0xAABBCCDDEEFF0001 mtt=1000000 tu=1000000 processing-deadline=0");
629   gst_harness_set_src_caps (h, generate_caps (4));
630
631   /* Buffer must have the nal len (4 bytes) and the nal (4 bytes) */
632   in = gst_harness_create_buffer (h, 8);
633   add_nal (in, 4, 1, 0);
634   GST_BUFFER_DTS (in) = 1000000;
635   GST_BUFFER_PTS (in) = 2000000;
636
637   out = gst_harness_push_and_pull (h, in);
638   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
639   gst_buffer_unref (out);
640
641   /* Now test if, when nal_type is not vcl (not between 1 and 5), M is not set.
642    * Also, as we're using the same element, seqnum should increase by one */
643   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_M, 0);
644   avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_SEQ_NUM, 1);
645
646   in = gst_harness_create_buffer (h, 8);
647   add_nal (in, 4, 6, 0);
648   GST_BUFFER_DTS (in) = 1000000;
649   GST_BUFFER_PTS (in) = 2000000;
650
651   out = gst_harness_push_and_pull (h, in);
652   fail_unless (compare_h264_avtpdu (pdu, out) == TRUE);
653   fail_unless (check_nal_filling (out, 0) == TRUE);
654   gst_buffer_unref (out);
655   gst_harness_teardown (h);
656 }
657
658 GST_END_TEST;
659
660 static Suite *
661 avtpcvfpay_suite (void)
662 {
663   Suite *s = suite_create ("avtpcvfpay");
664   TCase *tc_chain = tcase_create ("general");
665
666   suite_add_tcase (s, tc_chain);
667   tcase_add_test (tc_chain, test_payloader_single);
668   tcase_add_test (tc_chain, test_payloader_multiple_single);
669   tcase_add_test (tc_chain, test_payloader_multiple_single_2);
670   tcase_add_test (tc_chain, test_payloader_single_and_fragment);
671   tcase_add_test (tc_chain, test_payloader_single_and_fragment_edge);
672   tcase_add_test (tc_chain, test_payloader_incomplete_nal);
673   tcase_add_test (tc_chain, test_payloader_invalid_caps);
674   tcase_add_test (tc_chain, test_payloader_properties);
675   tcase_add_test (tc_chain, test_payloader_no_codec_data);
676   tcase_add_test (tc_chain, test_payloader_zero_sized_nal);
677
678   return s;
679 }
680
681 GST_CHECK_MAIN (avtpcvfpay);