📄 v4lif.c
字号:
/* * v4lif.c * This file contains routines for reading an image from a v4l device * * Derived from work by: * Copyright (C) 1998 Rasca, Berlin * EMail: thron@gmx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <getopt.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <fcntl.h>#include <unistd.h>#include <linux/types.h>#include <linux/videodev.h>#include "v4lif.h"/* * read rgb image from v4l device * return: mmap'ed buffer and size * * sample call: * int size; * char *image; * int dev = v4l_open(VIDEO_DEV, IN_DEFAULT); * image = get_image (dev, width, height, input, norm, palette, &size); * // process rgb image buffer as required here * // then dont forget to release buffers * if (size) * munmap(image, size); * else if (image) * free(image); * v4l_close(dev);*/char *get_image(int dev, int width, int height, int input,int norm,int fmt,int *size){ struct video_capability vid_caps; struct video_mbuf vid_buf; struct video_mmap vid_mmap; struct video_channel vid_chnl; char *map = NULL; int len; *size = 0; // keep caller happy on error returns // setting input = 1 gets some users going if (ioctl (dev, VIDIOCGCAP, &vid_caps) == -1) { printf("ioctl (VIDIOCGCAP) failed\n"); return (NULL); } if (input != IN_DEFAULT) { vid_chnl.channel = -1; if (ioctl (dev, VIDIOCGCHAN, &vid_chnl) == -1) { printf("ioctl (VIDIOCGCHAN) failed\n"); } else { vid_chnl.channel = input; vid_chnl.norm = norm; if (ioctl (dev, VIDIOCSCHAN, &vid_chnl) == -1) { printf("ioctl (VIDIOCSCHAN) failed"); return (NULL); } } } // if no video buffer set, then set it //printf("before VIDIOCGMBUF vidbuf size=%d bytes\n",vid_buf.size); if (ioctl (dev, VIDIOCGMBUF, &vid_buf) == -1) { //printf("after VIDIOCGMBUF vidbuf size=%d bytes\n",vid_buf.size); // to do a normal read() map = malloc (width * height * 3); len = read (dev, map, width * height * 3); if (len <= 0) { free (map); return (NULL); } *size = 0; return (map); } map = mmap (0, vid_buf.size, PROT_READ|PROT_WRITE,MAP_SHARED,dev,0); if ((unsigned char *)-1 == (unsigned char *)map) { printf("mmap() failed \n"); return (NULL); } vid_mmap.format = fmt; vid_mmap.frame = 0; vid_mmap.width = width; vid_mmap.height =height;//printf("VIDIOCMCAPTURE started\n"); if (ioctl (dev, VIDIOCMCAPTURE, &vid_mmap) == -1) { printf("VIDIOCMCAPTURE failed\n"); munmap (map, vid_buf.size); return (NULL); }//printf("VIDIOCSYNC started\n"); if (ioctl (dev, VIDIOCSYNC, &vid_mmap) == -1) { printf("VIDIOCSYNC failed \n"); munmap (map, vid_buf.size); return (NULL); }//printf("VIDIOCSYNC finished %d bytes\n",vid_buf.size); // vid_buf.size is actually the size of 2 frame buffers in the driver *size = vid_buf.size; return (map);}/* * int v4l_open(char *device) * example call int dev = v4l_open(VIDEO_DEV); * * */int v4l_open(char *device){ int dev = -1; int max_try = 5; /* we try 5 seconds/times to open the device */ /* open the video4linux device */ while (max_try) { dev = open (device, O_RDWR); if (dev == -1) { if (!--max_try) { fprintf (stderr, "Can't open device %s\n", device); exit (0); } sleep (1); } else { break; } } return dev;}/* * void v4l_close(int dev) * example call v4l_close(dev); * */void v4l_close(int dev){ if (dev > 0) close(dev);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -