• 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 <avtp.h>
23 #include <avtp_aaf.h>
24 #include <gst/check/gstcheck.h>
25 #include <gst/check/gstharness.h>
26 
27 const guint8 audio_data[] = { 0xAA, 0xBB, 0xCC, 0xDD };
28 
29 static GstHarness *
setup_harness(void)30 setup_harness (void)
31 {
32   GstHarness *h;
33 
34   h = gst_harness_new_parse ("avtpaafdepay streamid=0xDEADC0DEDEADC0DE");
35   gst_harness_set_src_caps_str (h, "application/x-avtp");
36 
37   return h;
38 }
39 
40 static GstBuffer *
create_input_buffer(GstHarness * h)41 create_input_buffer (GstHarness * h)
42 {
43   GstBuffer *buf;
44   GstMapInfo info;
45   struct avtp_stream_pdu *pdu;
46 
47   buf = gst_harness_create_buffer (h, sizeof (struct avtp_stream_pdu) +
48       sizeof (audio_data));
49   gst_buffer_map (buf, &info, GST_MAP_WRITE);
50   pdu = (struct avtp_stream_pdu *) info.data;
51   avtp_aaf_pdu_init (pdu);
52   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_TV, 1);
53   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_STREAM_ID, 0xDEADC0DEDEADC0DE);
54   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_FORMAT, AVTP_AAF_FORMAT_INT_16BIT);
55   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_NSR, AVTP_AAF_PCM_NSR_48KHZ);
56   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_CHAN_PER_FRAME, 2);
57   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_BIT_DEPTH, 16);
58   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_TIMESTAMP, 3000);
59   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_STREAM_DATA_LEN, sizeof (audio_data));
60   memcpy (pdu->avtp_payload, audio_data, sizeof (audio_data));
61   gst_buffer_unmap (buf, &info);
62 
63   return buf;
64 }
65 
GST_START_TEST(test_invalid_audio_features)66 GST_START_TEST (test_invalid_audio_features)
67 {
68   GstHarness *h;
69   GstMapInfo map;
70   GstBuffer *buf;
71   struct avtp_stream_pdu *pdu;
72 
73   h = setup_harness ();
74   buf = create_input_buffer (h);
75 
76   gst_harness_push (h, gst_buffer_copy (buf));
77   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 1);
78 
79   /* Don't care about the first buffer - it only sets what should
80    * be accepted from now on */
81   gst_buffer_unref (gst_harness_pull (h));
82 
83   /* Invalid rate */
84   gst_buffer_map (buf, &map, GST_MAP_READWRITE);
85   pdu = (struct avtp_stream_pdu *) map.data;
86   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_NSR, AVTP_AAF_PCM_NSR_16KHZ);
87   gst_buffer_unmap (buf, &map);
88 
89   gst_harness_push (h, gst_buffer_copy (buf));
90   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 1);
91 
92   /* Invalid depth */
93   gst_buffer_map (buf, &map, GST_MAP_READWRITE);
94   pdu = (struct avtp_stream_pdu *) map.data;
95   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_NSR, AVTP_AAF_PCM_NSR_48KHZ);
96   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_BIT_DEPTH, 32);
97   gst_buffer_unmap (buf, &map);
98 
99   gst_harness_push (h, gst_buffer_copy (buf));
100   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 1);
101 
102   /* Invalid format */
103   gst_buffer_map (buf, &map, GST_MAP_READWRITE);
104   pdu = (struct avtp_stream_pdu *) map.data;
105   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_BIT_DEPTH, 16);
106   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_FORMAT, AVTP_AAF_FORMAT_INT_32BIT);
107   gst_buffer_unmap (buf, &map);
108 
109   gst_harness_push (h, gst_buffer_copy (buf));
110   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 1);
111 
112   /* Invalid channels */
113   gst_buffer_map (buf, &map, GST_MAP_READWRITE);
114   pdu = (struct avtp_stream_pdu *) map.data;
115   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_FORMAT, AVTP_AAF_FORMAT_INT_16BIT);
116   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_CHAN_PER_FRAME, 4);
117   gst_buffer_unmap (buf, &map);
118 
119   gst_harness_push (h, gst_buffer_copy (buf));
120   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 1);
121 
122   gst_buffer_unref (buf);
123   gst_harness_teardown (h);
124 }
125 
126 GST_END_TEST;
127 
GST_START_TEST(test_invalid_avtpdu)128 GST_START_TEST (test_invalid_avtpdu)
129 {
130   GstHarness *h;
131   GstMapInfo map;
132   GstBuffer *buf, *small;
133   struct avtp_stream_pdu *pdu;
134 
135   h = setup_harness ();
136   buf = create_input_buffer (h);
137 
138   /* Invalid subtype */
139   gst_buffer_map (buf, &map, GST_MAP_READWRITE);
140   pdu = (struct avtp_stream_pdu *) map.data;
141   avtp_pdu_set ((struct avtp_common_pdu *) pdu, AVTP_FIELD_SUBTYPE,
142       AVTP_SUBTYPE_CRF);
143   gst_buffer_unmap (buf, &map);
144 
145   gst_harness_push (h, gst_buffer_copy (buf));
146   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
147 
148   /* Invalid AVTP version */
149   gst_buffer_map (buf, &map, GST_MAP_READWRITE);
150   pdu = (struct avtp_stream_pdu *) map.data;
151   avtp_pdu_set ((struct avtp_common_pdu *) pdu, AVTP_FIELD_SUBTYPE,
152       AVTP_SUBTYPE_AAF);
153   avtp_pdu_set ((struct avtp_common_pdu *) pdu, AVTP_FIELD_VERSION, 3);
154   gst_buffer_unmap (buf, &map);
155 
156   gst_harness_push (h, gst_buffer_copy (buf));
157   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
158 
159   /* Invalid SV */
160   gst_buffer_map (buf, &map, GST_MAP_READWRITE);
161   pdu = (struct avtp_stream_pdu *) map.data;
162   avtp_pdu_set ((struct avtp_common_pdu *) pdu, AVTP_FIELD_VERSION, 0);
163   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_SV, 0);
164   gst_buffer_unmap (buf, &map);
165 
166   gst_harness_push (h, gst_buffer_copy (buf));
167   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
168 
169   /* Invalid stream id */
170   gst_buffer_map (buf, &map, GST_MAP_READWRITE);
171   pdu = (struct avtp_stream_pdu *) map.data;
172   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_SV, 0);
173   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_STREAM_ID, 0xAABBCCDDEEFF0001);
174   gst_buffer_unmap (buf, &map);
175 
176   gst_harness_push (h, gst_buffer_copy (buf));
177   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
178 
179   /* Invalid stream data len  */
180   gst_buffer_map (buf, &map, GST_MAP_READWRITE);
181   pdu = (struct avtp_stream_pdu *) map.data;
182   avtp_aaf_pdu_set (pdu, AVTP_AAF_FIELD_STREAM_ID, 0xDEADC0DEDEADC0DE);
183   gst_buffer_unmap (buf, &map);
184 
185   gst_harness_push (h, gst_buffer_copy (buf));
186   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
187 
188   /* Invalid buffer size (too small to fit an AVTP header) */
189   small = gst_harness_create_buffer (h, sizeof (struct avtp_stream_pdu) / 2);
190   gst_harness_push (h, small);
191   fail_unless_equals_uint64 (gst_harness_buffers_received (h), 0);
192 
193   gst_buffer_unref (buf);
194   gst_harness_teardown (h);
195 }
196 
197 GST_END_TEST;
198 
GST_START_TEST(test_events)199 GST_START_TEST (test_events)
200 {
201   gchar *str;
202   GstHarness *h;
203   GstBuffer *buf;
204   GstEvent *event;
205   guint event_count;
206   GstCaps *caps;
207   const GstSegment *segment;
208 
209   h = setup_harness ();
210   buf = create_input_buffer (h);
211   gst_harness_push (h, buf);
212 
213   event_count = gst_harness_events_in_queue (h);
214   fail_unless (event_count == 3);
215 
216   event = gst_harness_pull_event (h);
217   fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
218   gst_event_unref (event);
219 
220   event = gst_harness_pull_event (h);
221   fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CAPS);
222   gst_event_parse_caps (event, &caps);
223   str = gst_caps_to_string (caps);
224   fail_unless (strcmp (str,
225           "audio/x-raw, format=(string)S16BE, rate=(int)48000, channels=(int)2, layout=(string)interleaved")
226       == 0);
227   g_free (str);
228   gst_event_unref (event);
229 
230   event = gst_harness_pull_event (h);
231   fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
232   gst_event_parse_segment (event, &segment);
233   fail_unless (segment->format == GST_FORMAT_TIME);
234   fail_unless (segment->base == 3000);
235   fail_unless (segment->start == 3000);
236   fail_unless (segment->stop == -1);
237   gst_event_unref (event);
238 
239   gst_harness_teardown (h);
240 }
241 
242 GST_END_TEST;
243 
GST_START_TEST(test_buffer)244 GST_START_TEST (test_buffer)
245 {
246   GstHarness *h;
247   GstMapInfo info;
248   GstBuffer *in, *out;
249 
250   h = setup_harness ();
251   in = create_input_buffer (h);
252   out = gst_harness_push_and_pull (h, in);
253 
254   fail_unless (gst_buffer_get_size (out) == sizeof (audio_data));
255 
256   gst_buffer_map (out, &info, GST_MAP_READ);
257   fail_unless (memcmp (info.data, audio_data, info.size) == 0);
258   gst_buffer_unmap (out, &info);
259 
260   gst_buffer_unref (out);
261   gst_harness_teardown (h);
262 }
263 
264 GST_END_TEST;
265 
GST_START_TEST(test_property)266 GST_START_TEST (test_property)
267 {
268   guint64 val;
269   GstHarness *h;
270   GstElement *element;
271   const guint64 streamid = 0xAABBCCDDEEFF0001;
272 
273   h = setup_harness ();
274   element = gst_harness_find_element (h, "avtpaafdepay");
275 
276   g_object_set (G_OBJECT (element), "streamid", streamid, NULL);
277   g_object_get (G_OBJECT (element), "streamid", &val, NULL);
278   fail_unless (val == streamid);
279 
280   gst_object_unref (element);
281   gst_harness_teardown (h);
282 }
283 
284 GST_END_TEST;
285 
286 static Suite *
avtpaafdepay_suite(void)287 avtpaafdepay_suite (void)
288 {
289   Suite *s = suite_create ("avtpaafdepay");
290   TCase *tc_chain = tcase_create ("general");
291 
292   suite_add_tcase (s, tc_chain);
293   tcase_add_test (tc_chain, test_buffer);
294   tcase_add_test (tc_chain, test_events);
295   tcase_add_test (tc_chain, test_property);
296   tcase_add_test (tc_chain, test_invalid_avtpdu);
297   tcase_add_test (tc_chain, test_invalid_audio_features);
298 
299   return s;
300 }
301 
302 GST_CHECK_MAIN (avtpaafdepay);
303