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