1 /*
2 Sliced vbi autodetection demonstration utility
3 Copyright (C) 2004 Hans Verkuil <hverkuil@xs4all.nl>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program 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
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
18 */
19
20 /* This simple utility detects which VBI types are transmitted on
21 each field/line. It serves both as example source and as a tool to
22 test the sliced VBI implementation.
23
24 Usage: sliced-vbi-detect [device]
25 Without a device name as argument it will fallback to /dev/vbi0.
26 */
27
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <fcntl.h>
33 #include <errno.h>
34 #include <sys/ioctl.h>
35
36 #include <linux/videodev2.h>
37
detect(int fh,struct v4l2_sliced_vbi_format * fmt)38 static void detect(int fh, struct v4l2_sliced_vbi_format *fmt)
39 {
40 struct v4l2_sliced_vbi_data *buf = malloc(fmt->io_size);
41 int cnt;
42
43 for (cnt = 0; cnt < 5; cnt++) {
44 int size = read(fh, buf, fmt->io_size);
45 unsigned i;
46
47 if (size <= 0) {
48 printf("size = %d\n", size);
49 break;
50 }
51 if (cnt == 0)
52 continue;
53 for (i = 0; i < size / sizeof(*buf); i++) {
54 int field, line;
55
56 line = buf[i].line;
57 field = buf[i].field;
58 if (buf[i].id == 0)
59 continue;
60 if (line < 0 || line >= 24) {
61 printf("line %d out of range\n", line);
62 free(buf);
63 return;
64 }
65 fmt->service_lines[field][line] |= buf[i].id;
66 }
67 }
68 free(buf);
69 }
70
v2s(int id)71 static void v2s(int id)
72 {
73 switch (id) {
74 case V4L2_SLICED_TELETEXT_B: printf(" TELETEXT"); break;
75 case V4L2_SLICED_CAPTION_525: printf(" CC"); break;
76 case V4L2_SLICED_WSS_625: printf(" WSS"); break;
77 case V4L2_SLICED_VPS: printf(" VPS"); break;
78 default: printf(" UNKNOWN %x", id); break;
79 }
80 }
81
main(int argc,char ** argv)82 int main(int argc, char **argv)
83 {
84 char *device = "/dev/vbi0";
85 struct v4l2_format vbifmt;
86 struct v4l2_sliced_vbi_format vbiresult;
87 int fh;
88 int f, i, b;
89
90 if (argc == 2)
91 device = argv[1];
92 fh = open(device, O_RDONLY);
93
94 if (fh == -1) {
95 fprintf(stderr, "cannot open %s\n", device);
96 return 1;
97 }
98 memset(&vbiresult, 0, sizeof(vbiresult));
99 for (i = 0; i < 16; i++) {
100 int l;
101 int set = 0;
102
103 memset(&vbifmt, 0, sizeof(vbifmt));
104 vbifmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
105 for (l = 0; l < 24; l++) {
106 vbifmt.fmt.sliced.service_lines[0][l] = 1 << i;
107 vbifmt.fmt.sliced.service_lines[1][l] = 1 << i;
108 }
109 if (ioctl(fh, VIDIOC_S_FMT, &vbifmt) < 0) {
110 if (errno == EINVAL)
111 continue;
112 perror("IVTV_IOC_S_VBI_FMT");
113 exit(-1);
114 }
115 vbiresult.io_size = vbifmt.fmt.sliced.io_size;
116 for (l = 0; l < 24; l++) {
117 set |= vbifmt.fmt.sliced.service_lines[0][l] |
118 vbifmt.fmt.sliced.service_lines[1][l];
119 }
120 detect(fh, &vbiresult);
121 }
122 close(fh);
123 for (f = 0; f < 2; f++) {
124 printf("Field %d:\n", f);
125 for (i = 6; i < 24; i++) {
126 unsigned set = vbiresult.service_lines[f][i];
127
128 printf(" Line %2d:", i);
129 for (b = 0; b < 16; b++) {
130 if (set & (1 << b))
131 v2s(1 << b);
132 }
133 printf("\n");
134 }
135 }
136 return 0;
137 }
138