1 /* GStreamer
2  *
3  * Copyright (C) 2018 Sebastian Dröge <sebastian@centricular.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 #include <gst/gst.h>
25 #include <gst/check/gstcheck.h>
26 #include <gst/video/video.h>
27 
GST_START_TEST(parse_8bit)28 GST_START_TEST (parse_8bit)
29 {
30   GstVideoVBIParser *parser;
31   guint8 line[2560] = { 0, };
32   GstVideoAncillary vanc;
33 
34   parser = gst_video_vbi_parser_new (GST_VIDEO_FORMAT_UYVY, 1280);
35   fail_unless (parser != NULL);
36 
37   /* empty line */
38   gst_video_vbi_parser_add_line (parser, line);
39   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
40       GST_VIDEO_VBI_PARSER_RESULT_DONE);
41 
42   /* add a single ADF in the chroma with some arbitrary DID/SDID and 8 bytes of data */
43   line[16] = 0x00;
44   line[18] = 0xff;
45   line[20] = 0xff;
46   line[22] = 0x23;              /* DID */
47   line[24] = 0x24;              /* SDID */
48   line[26] = 0x08;              /* DC */
49   line[28] = 0x01;
50   line[30] = 0x02;
51   line[32] = 0x03;
52   line[34] = 0x04;
53   line[36] = 0x50;
54   line[38] = 0x60;
55   line[40] = 0x70;
56   line[42] = 0x80;
57   line[44] = 0xf9;              /* checksum */
58 
59   gst_video_vbi_parser_add_line (parser, line);
60 
61   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
62       GST_VIDEO_VBI_PARSER_RESULT_OK);
63   fail_unless_equals_int (GST_VIDEO_ANCILLARY_DID16 (&vanc), 0x2324);
64   fail_unless_equals_int (vanc.data_count, 8);
65   fail_unless_equals_int (vanc.data[0], 0x01);
66   fail_unless_equals_int (vanc.data[1], 0x02);
67   fail_unless_equals_int (vanc.data[2], 0x03);
68   fail_unless_equals_int (vanc.data[3], 0x04);
69   fail_unless_equals_int (vanc.data[4], 0x50);
70   fail_unless_equals_int (vanc.data[5], 0x60);
71   fail_unless_equals_int (vanc.data[6], 0x70);
72   fail_unless_equals_int (vanc.data[7], 0x80);
73 
74   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
75       GST_VIDEO_VBI_PARSER_RESULT_DONE);
76 
77   /* add a second ADF in the luma with 4 bytes data count */
78   line[17] = 0x00;
79   line[19] = 0xff;
80   line[21] = 0xff;
81   line[23] = 0x33;              /* DID */
82   line[25] = 0x34;              /* SDID */
83   line[27] = 0x04;              /* DC */
84   line[29] = 0x04;
85   line[31] = 0x03;
86   line[33] = 0x02;
87   line[35] = 0x01;
88   line[37] = 0x75;              /* checksum */
89 
90   gst_video_vbi_parser_add_line (parser, line);
91 
92   /* first we should get the luma data */
93   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
94       GST_VIDEO_VBI_PARSER_RESULT_OK);
95   fail_unless_equals_int (GST_VIDEO_ANCILLARY_DID16 (&vanc), 0x3334);
96   fail_unless_equals_int (vanc.data_count, 4);
97   fail_unless_equals_int (vanc.data[0], 0x04);
98   fail_unless_equals_int (vanc.data[1], 0x03);
99   fail_unless_equals_int (vanc.data[2], 0x02);
100   fail_unless_equals_int (vanc.data[3], 0x01);
101 
102   /* then the chroma data */
103   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
104       GST_VIDEO_VBI_PARSER_RESULT_OK);
105   fail_unless_equals_int (GST_VIDEO_ANCILLARY_DID16 (&vanc), 0x2324);
106   fail_unless_equals_int (vanc.data_count, 8);
107   fail_unless_equals_int (vanc.data[0], 0x01);
108   fail_unless_equals_int (vanc.data[1], 0x02);
109   fail_unless_equals_int (vanc.data[2], 0x03);
110   fail_unless_equals_int (vanc.data[3], 0x04);
111   fail_unless_equals_int (vanc.data[4], 0x50);
112   fail_unless_equals_int (vanc.data[5], 0x60);
113   fail_unless_equals_int (vanc.data[6], 0x70);
114   fail_unless_equals_int (vanc.data[7], 0x80);
115 
116   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
117       GST_VIDEO_VBI_PARSER_RESULT_DONE);
118 
119   gst_video_vbi_parser_free (parser);
120 }
121 
122 GST_END_TEST;
123 
GST_START_TEST(parse_10bit)124 GST_START_TEST (parse_10bit)
125 {
126   GstVideoVBIParser *parser;
127   guint8 line[3414] = { 0, };
128   GstVideoAncillary vanc;
129 
130   parser = gst_video_vbi_parser_new (GST_VIDEO_FORMAT_v210, 1280);
131   fail_unless (parser != NULL);
132 
133   /* empty line */
134   gst_video_vbi_parser_add_line (parser, line);
135   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
136       GST_VIDEO_VBI_PARSER_RESULT_DONE);
137 
138   /* add a single ADF in the chroma with some arbitrary DID/SDID and 8 bytes
139    * of data. See above for explanation */
140   GST_WRITE_UINT32_LE (line + 16, (0x000 << 0) | (0x3ff << 20));
141   GST_WRITE_UINT32_LE (line + 20, (0x3ff << 10));
142   GST_WRITE_UINT32_LE (line + 24, (0x123 << 0) | (0x224 << 20));
143   GST_WRITE_UINT32_LE (line + 28, (0x108 << 10));
144 
145   GST_WRITE_UINT32_LE (line + 32, (0x101 << 0) | (0x102 << 20));
146   GST_WRITE_UINT32_LE (line + 36, (0x203 << 10));
147   GST_WRITE_UINT32_LE (line + 40, (0x104 << 0) | (0x250 << 20));
148   GST_WRITE_UINT32_LE (line + 44, (0x260 << 10));
149 
150   GST_WRITE_UINT32_LE (line + 48, (0x170 << 0) | (0x180 << 20));
151   GST_WRITE_UINT32_LE (line + 52, (0x2f9 << 10));
152 
153   gst_video_vbi_parser_add_line (parser, line);
154 
155   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
156       GST_VIDEO_VBI_PARSER_RESULT_OK);
157   fail_unless_equals_int (GST_VIDEO_ANCILLARY_DID16 (&vanc), 0x2324);
158   fail_unless_equals_int (vanc.data_count, 8);
159   fail_unless_equals_int (vanc.data[0], 0x01);
160   fail_unless_equals_int (vanc.data[1], 0x02);
161   fail_unless_equals_int (vanc.data[2], 0x03);
162   fail_unless_equals_int (vanc.data[3], 0x04);
163   fail_unless_equals_int (vanc.data[4], 0x50);
164   fail_unless_equals_int (vanc.data[5], 0x60);
165   fail_unless_equals_int (vanc.data[6], 0x70);
166   fail_unless_equals_int (vanc.data[7], 0x80);
167 
168   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
169       GST_VIDEO_VBI_PARSER_RESULT_DONE);
170 
171   /* add a second ADF in the luma with 4 bytes data count */
172   GST_WRITE_UINT32_LE (line + 16, (0x000 << 0) | (0x3ff << 20) | (0x000 << 10));
173   GST_WRITE_UINT32_LE (line + 20, (0x3ff << 10) | (0x3ff << 0) | (0x3ff << 20));
174   GST_WRITE_UINT32_LE (line + 24, (0x123 << 0) | (0x224 << 20) | (0x233 << 10));
175   GST_WRITE_UINT32_LE (line + 28, (0x108 << 10) | (0x134 << 0) | (0x204 << 20));
176 
177   GST_WRITE_UINT32_LE (line + 32, (0x101 << 0) | (0x102 << 20) | (0x104 << 10));
178   GST_WRITE_UINT32_LE (line + 36, (0x203 << 10) | (0x203 << 0) | (0x102 << 20));
179   GST_WRITE_UINT32_LE (line + 40, (0x104 << 0) | (0x250 << 20) | (0x101 << 10));
180   GST_WRITE_UINT32_LE (line + 44, (0x275 << 0) | (0x260 << 10));
181 
182   GST_WRITE_UINT32_LE (line + 48, (0x170 << 0) | (0x180 << 20));
183   GST_WRITE_UINT32_LE (line + 52, (0x2f9 << 10));
184 
185   gst_video_vbi_parser_add_line (parser, line);
186 
187   /* first we should get the luma data */
188   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
189       GST_VIDEO_VBI_PARSER_RESULT_OK);
190   fail_unless_equals_int (GST_VIDEO_ANCILLARY_DID16 (&vanc), 0x3334);
191   fail_unless_equals_int (vanc.data_count, 4);
192   fail_unless_equals_int (vanc.data[0], 0x04);
193   fail_unless_equals_int (vanc.data[1], 0x03);
194   fail_unless_equals_int (vanc.data[2], 0x02);
195   fail_unless_equals_int (vanc.data[3], 0x01);
196 
197   /* then the chroma data */
198   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
199       GST_VIDEO_VBI_PARSER_RESULT_OK);
200   fail_unless_equals_int (GST_VIDEO_ANCILLARY_DID16 (&vanc), 0x2324);
201   fail_unless_equals_int (vanc.data_count, 8);
202   fail_unless_equals_int (vanc.data[0], 0x01);
203   fail_unless_equals_int (vanc.data[1], 0x02);
204   fail_unless_equals_int (vanc.data[2], 0x03);
205   fail_unless_equals_int (vanc.data[3], 0x04);
206   fail_unless_equals_int (vanc.data[4], 0x50);
207   fail_unless_equals_int (vanc.data[5], 0x60);
208   fail_unless_equals_int (vanc.data[6], 0x70);
209   fail_unless_equals_int (vanc.data[7], 0x80);
210 
211   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
212       GST_VIDEO_VBI_PARSER_RESULT_DONE);
213 
214   gst_video_vbi_parser_free (parser);
215 }
216 
217 GST_END_TEST;
218 
GST_START_TEST(encode_8bit)219 GST_START_TEST (encode_8bit)
220 {
221   GstVideoVBIParser *parser;
222   GstVideoVBIEncoder *encoder;
223   guint8 line[2560] = { 0, };
224   const guint8 data1[] = { 0x01, 0x02, 0x03, 0x04, 0x50, 0x60, 0x70, 0x80 };
225   const guint8 data2[] = { 0x04, 0x03, 0x02, 0x01 };
226   GstVideoAncillary vanc;
227 
228   parser = gst_video_vbi_parser_new (GST_VIDEO_FORMAT_UYVY, 1280);
229   fail_unless (parser != NULL);
230 
231   encoder = gst_video_vbi_encoder_new (GST_VIDEO_FORMAT_UYVY, 1280);
232   fail_unless (encoder != NULL);
233 
234   /* Write a single ADF packet and try to parse it back again */
235   fail_unless (gst_video_vbi_encoder_add_ancillary (encoder, FALSE, 0x23, 0x24,
236           data1, sizeof (data1)));
237   gst_video_vbi_encoder_write_line (encoder, line);
238 
239   gst_video_vbi_parser_add_line (parser, line);
240 
241   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
242       GST_VIDEO_VBI_PARSER_RESULT_OK);
243   fail_unless_equals_int (GST_VIDEO_ANCILLARY_DID16 (&vanc), 0x2324);
244   fail_unless_equals_int (vanc.data_count, 8);
245   fail_unless (memcmp (vanc.data, data1, sizeof (data1)) == 0);
246 
247   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
248       GST_VIDEO_VBI_PARSER_RESULT_DONE);
249 
250   /* Write two ADF packets now */
251   fail_unless (gst_video_vbi_encoder_add_ancillary (encoder, FALSE, 0x23, 0x24,
252           data1, sizeof (data1)));
253   fail_unless (gst_video_vbi_encoder_add_ancillary (encoder, FALSE, 0x33, 0x34,
254           data2, sizeof (data2)));
255   gst_video_vbi_encoder_write_line (encoder, line);
256 
257   gst_video_vbi_parser_add_line (parser, line);
258 
259   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
260       GST_VIDEO_VBI_PARSER_RESULT_OK);
261   fail_unless_equals_int (GST_VIDEO_ANCILLARY_DID16 (&vanc), 0x2324);
262   fail_unless_equals_int (vanc.data_count, 8);
263   fail_unless (memcmp (vanc.data, data1, sizeof (data1)) == 0);
264 
265   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
266       GST_VIDEO_VBI_PARSER_RESULT_OK);
267   fail_unless_equals_int (GST_VIDEO_ANCILLARY_DID16 (&vanc), 0x3334);
268   fail_unless_equals_int (vanc.data_count, 4);
269   fail_unless (memcmp (vanc.data, data2, sizeof (data2)) == 0);
270 
271   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
272       GST_VIDEO_VBI_PARSER_RESULT_DONE);
273 
274   gst_video_vbi_encoder_free (encoder);
275   gst_video_vbi_parser_free (parser);
276 }
277 
278 GST_END_TEST;
279 
280 
GST_START_TEST(encode_10bit)281 GST_START_TEST (encode_10bit)
282 {
283   GstVideoVBIParser *parser;
284   GstVideoVBIEncoder *encoder;
285   guint8 line[3414] = { 0, };
286   const guint8 data1[] = { 0x01, 0x02, 0x03, 0x04, 0x50, 0x60, 0x70, 0x80 };
287   const guint8 data2[] = { 0x04, 0x03, 0x02, 0x01 };
288   GstVideoAncillary vanc;
289 
290   parser = gst_video_vbi_parser_new (GST_VIDEO_FORMAT_v210, 1280);
291   fail_unless (parser != NULL);
292 
293   encoder = gst_video_vbi_encoder_new (GST_VIDEO_FORMAT_v210, 1280);
294   fail_unless (encoder != NULL);
295 
296   /* Write a single ADF packet and try to parse it back again */
297   fail_unless (gst_video_vbi_encoder_add_ancillary (encoder, FALSE, 0x23, 0x24,
298           data1, sizeof (data1)));
299   gst_video_vbi_encoder_write_line (encoder, line);
300 
301   gst_video_vbi_parser_add_line (parser, line);
302 
303   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
304       GST_VIDEO_VBI_PARSER_RESULT_OK);
305   fail_unless_equals_int (GST_VIDEO_ANCILLARY_DID16 (&vanc), 0x2324);
306   fail_unless_equals_int (vanc.data_count, 8);
307   fail_unless (memcmp (vanc.data, data1, sizeof (data1)) == 0);
308 
309   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
310       GST_VIDEO_VBI_PARSER_RESULT_DONE);
311 
312   /* Write two ADF packets now */
313   fail_unless (gst_video_vbi_encoder_add_ancillary (encoder, FALSE, 0x23, 0x24,
314           data1, sizeof (data1)));
315   fail_unless (gst_video_vbi_encoder_add_ancillary (encoder, FALSE, 0x33, 0x34,
316           data2, sizeof (data2)));
317   gst_video_vbi_encoder_write_line (encoder, line);
318 
319   gst_video_vbi_parser_add_line (parser, line);
320 
321   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
322       GST_VIDEO_VBI_PARSER_RESULT_OK);
323   fail_unless_equals_int (GST_VIDEO_ANCILLARY_DID16 (&vanc), 0x2324);
324   fail_unless_equals_int (vanc.data_count, 8);
325   fail_unless (memcmp (vanc.data, data1, sizeof (data1)) == 0);
326 
327   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
328       GST_VIDEO_VBI_PARSER_RESULT_OK);
329   fail_unless_equals_int (GST_VIDEO_ANCILLARY_DID16 (&vanc), 0x3334);
330   fail_unless_equals_int (vanc.data_count, 4);
331   fail_unless (memcmp (vanc.data, data2, sizeof (data2)) == 0);
332 
333   fail_unless_equals_int (gst_video_vbi_parser_get_ancillary (parser, &vanc),
334       GST_VIDEO_VBI_PARSER_RESULT_DONE);
335 
336   gst_video_vbi_encoder_free (encoder);
337   gst_video_vbi_parser_free (parser);
338 }
339 
340 GST_END_TEST;
341 
342 static Suite *
gst_videoanc_suite(void)343 gst_videoanc_suite (void)
344 {
345   Suite *s = suite_create ("GstVideoAnc");
346   TCase *tc = tcase_create ("general");
347 
348   suite_add_tcase (s, tc);
349 
350   tcase_add_test (tc, parse_8bit);
351   tcase_add_test (tc, parse_10bit);
352 
353   tcase_add_test (tc, encode_8bit);
354   tcase_add_test (tc, encode_10bit);
355 
356   return s;
357 }
358 
359 GST_CHECK_MAIN (gst_videoanc);
360