v4ltest.c
ほげほげ。
1 #include <sys/ioctl.h>
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <sys/mman.h>
5 #include <fcntl.h>
6 #include <unistd.h>
7
8 #include <linux/types.h>
9 #include <linux/videodev.h>
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 #if 0
16 USAGE:
17 % ./a.out 320 240 >! output.ppm
18 % xv output.ppm
19 #endif
20
21 int main(int argc, char **argv)
22 {
23 int WIDTH=999, HEIGHT=999;
24 int n, fd;
25 char *map, *p;
26 char tmp;
27 struct video_capability vd;
28 struct video_channel vc[10];
29 struct video_picture vp;
30 struct video_mbuf vm;
31 struct video_mmap vmm;
32
33
34 if(argc>2) { WIDTH=atoi(argv[1]); HEIGHT=atoi(argv[2]); }
35
36
37 /* Video4Linux デバイスのオープン */
38 if((fd=open("/dev/video", O_RDWR))<0) {
39 perror("open");
40 return -1;
41 }
42
43
44 /* Video4Linux デバイス仕様の取得 */
45 if(ioctl(fd, VIDIOCGCAP, &vd)<0) {
46 perror("ioctl(VIDIOCGCAP)");
47 return -1;
48 }
49 fprintf(stderr, "vd.name: \"%s\"\n", vd.name);
50 fprintf(stderr, "vd.type=0x%08x", vd.type);
51 if(vd.type&VID_TYPE_CAPTURE) fprintf(stderr, " CAPTURE");
52 if(vd.type&VID_TYPE_TUNER) fprintf(stderr, " TUNER");
53 if(vd.type&VID_TYPE_TELETEXT) fprintf(stderr, " TELETEXT");
54 if(vd.type&VID_TYPE_OVERLAY) fprintf(stderr, " OVERLAY");
55 if(vd.type&VID_TYPE_CHROMAKEY) fprintf(stderr, " CHROMAKEY");
56 if(vd.type&VID_TYPE_CLIPPING) fprintf(stderr, " CLIPPING");
57 if(vd.type&VID_TYPE_FRAMERAM) fprintf(stderr, " FRAMERAM");
58 if(vd.type&VID_TYPE_SCALES) fprintf(stderr, " SCALES");
59 if(vd.type&VID_TYPE_MONOCHROME) fprintf(stderr, " MONOCHROME");
60 if(vd.type&VID_TYPE_SUBCAPTURE) fprintf(stderr, " SUBCAPTURE");
61 fprintf(stderr, "\n");
62 fprintf(stderr, "vd.channels=%d\n", vd.channels);
63 fprintf(stderr, "vd.audios=%d\n", vd.audios);
64 fprintf(stderr, "vd.maxwidth=%d\n", vd.maxwidth);
65 fprintf(stderr, "vd.maxheight=%d\n", vd.maxheight);
66 fprintf(stderr, "vd.minwidth=%d\n", vd.minwidth);
67 fprintf(stderr, "vd.minheight=%d\n", vd.minheight);
68 fprintf(stderr, "\n");
69
70
71 /* キャプチャサイズの調整 */
72 if(WIDTH>vd.maxwidth) WIDTH=vd.maxwidth;
73 if(WIDTH<vd.minwidth) WIDTH=vd.minwidth;
74 if(HEIGHT>vd.maxheight) HEIGHT=vd.maxheight;
75 if(HEIGHT<vd.minheight) HEIGHT=vd.minheight;
76
77
78 /* 各チャネル仕様取得 */
79 for(n=0; n<vd.channels; n++) {
80 vc[n].channel=n;
81 if(ioctl(fd, VIDIOCGCHAN, &vc[n])<0) {
82 perror("ioctl(VIDIOCGCHAN)");
83 return -1;
84 }
85 fprintf(stderr, "vc[%d].channel=%d\n", n, vc[n].channel);
86 fprintf(stderr, "vc[%d].name=\"%s\"\n", n, vc[n].name);
87 fprintf(stderr, "vc[%d].tuners=%d\n", n, vc[n].tuners);
88 fprintf(stderr, "vc[%d].flags=0x%08x", n, vc[n].flags);
89 if(vc[n].flags&VIDEO_VC_TUNER) fprintf(stderr, " TUNER");
90 if(vc[n].flags&VIDEO_VC_AUDIO) fprintf(stderr, " AUDIO");
91 fprintf(stderr, "\n");
92 fprintf(stderr, "vc[%d].type=0x%08x", n, vc[n].type);
93 if(vc[n].type&VIDEO_TYPE_TV) fprintf(stderr, " TV");
94 if(vc[n].type&VIDEO_TYPE_CAMERA) fprintf(stderr, " CAMERA");
95 fprintf(stderr, "\n");
96 fprintf(stderr, "vc[%d].norm=%d\n", n, vc[n].norm);
97 fprintf(stderr, "\n");
98 }
99
100
101 /* "Composite1"を選択 */
102 vc[1].norm=1; /* 0:PAL 1:NTSC 2:SECAM */
103 if(ioctl(fd, VIDIOCSCHAN, &vc[1])<0) {
104 perror("ioctl(VIDIOCSCHAN)");
105 return -1;
106 }
107
108
109 /* 色調とかの設定(たいがい 0-65535) */
110 vp.brightness=32767;
111 vp.hue=32767;
112 vp.colour=32767;
113 vp.contrast=32767;
114 vp.whiteness=32767;
115 vp.depth=24; /* color depth */
116 vp.palette=VIDEO_PALETTE_RGB24; /* パレット形式 */
117 if(ioctl(fd, VIDIOCSPICT, &vp)) {
118 perror("ioctl(VIDIOCSPICT)");
119 return -1;
120 }
121
122
123 /* mmap 情報の取得 */
124 if(ioctl(fd, VIDIOCGMBUF, &vm)<0) {
125 perror("ioctl(VIDIOCGMBUF)");
126 return -1;
127 }
128 fprintf(stderr, "vm.size=0x%08x\n", vm.size);
129 fprintf(stderr, "vm.frames=0x%08x\n", vm.frames);
130 for(n=0; n<vm.frames; n++)
131 fprintf(stderr, "vm.offsets[%d]=0x%08x\n", n, vm.offsets[n]);
132 fprintf(stderr, "\n");
133
134
135 /* mmap */
136 if((map=mmap(0, vm.size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0))==(char *)-1) {
137 perror("mmap");
138 return -1;
139 }
140
141
142 /* frame #0 にキャプチャ開始指示 */
143 vmm.frame=0;
144 vmm.width=WIDTH;
145 vmm.height=HEIGHT;
146 vmm.format=VIDEO_PALETTE_RGB24;
147 if(ioctl(fd, VIDIOCMCAPTURE, &vmm)<0) {
148 perror("ioctl(VIDIOCMCAPTURE)");
149 return -1;
150 }
151
152
153 /* frame #0 キャプチャ終了待ち */
154 n=0;
155 if(ioctl(fd, VIDIOCSYNC, &n)<0) {
156 perror("ioctl(VIDIOCSYNC)");
157 return -1;
158 }
159
160
161 /* RGB 順番の入れかえ */
162 for(n=0, p=map+vm.offset[0]; n<WIDTH*HEIGHT; n++, p+=3) {
163 tmp=p[0]; p[0]=p[2]; p[2]=tmp;
164 }
165
166
167 /* ppm の書きだし */
168 printf("P6 %d %d 255\n", WIDTH, HEIGHT); fflush(stdout);
169 write(1, map+vm.offsets[0], WIDTH*HEIGHT*3);
170
171
172 /* おしまい */
173 close(fd);
174
175 return 0;
176 }
Last modified: Tue Sep 15 03:53:28 1998