v4l.c
来自「Video4Linux_test.rar 接視訊的範例程式」· C语言 代码 · 共 248 行
C
248 行
#include <stdio.h>#include <unistd.h>#include <error.h>#include <assert.h>#include <fcntl.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <linux/videodev.h>#include "v4l.h"#define DEFAULT_DEVICE "/dev/v4l/video0"#define DEFAULT_PALETTE VIDEO_PALETTE_YUV420P#define FALSE 0#define TRUE 1int v4l_open(char *dev,v4l_device *vd){ if(!dev) { dev = DEFAULT_DEVICE; } if( (vd->fd = open(dev,O_RDWR)) < 0 ) { perror("v4l_open:"); return -1; } if(v4l_get_capability(vd)) return -1; if(v4l_get_picture(vd)) return -1; return 0;}int v4l_get_capability(v4l_device *vd){ if(ioctl(vd->fd,VIDIOCGCAP,&(vd->capability)) < 0) { perror("v4l_get_capability:"); return -1; } return 0;}int v4l_get_channels(v4l_device *vd){ int i; for(i=0;i<vd->capability.channels;i++) { vd->channel[i].channel = i; if(ioctl(vd->fd,VIDIOCGCHAN,&(vd->channel[i])) < 0) { perror("v4l_get_channel:"); return -1; } } return 0;}int v4l_get_audios(v4l_device *vd){ int i; for(i=0;i<vd->capability.audios;i++) { if(ioctl(vd->fd,VIDIOCGAUDIO,&(vd->audio[i])) < 0) { perror("v4l_get_audio:"); return -1; } } return 0;}int v4l_get_picture(v4l_device *vd){ if(ioctl(vd->fd,VIDIOCGPICT,&(vd->picture)) < 0) { perror("v4l_get_picture"); return -1; } //printf("vd->picture.depth:%d\n",vd->picture.depth); return 0;}int v4l_close(v4l_device *vd){ close(vd->fd); return 0;}int v4l_mmap_init(v4l_device *vd){ if(v4l_get_mbuf(vd) < 0) return -1; if((vd->map = mmap(0,vd->mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,vd->fd,0)) < 0) { perror("v4l_mmap_init:mmap"); return -1; } return 0;}int v4l_get_buffer(v4l_device *vd){ if(ioctl(vd->fd,VIDIOCSFBUF,&(vd->buffer)) < 0) { perror("v4l_get_buffer:"); return -1; } return 0;}int v4l_set_buffer(v4l_device *vd){ if(ioctl(vd->fd,VIDIOCGFBUF,&(vd->buffer)) < 0) { perror("v4l_set_buff:"); return -1; } return 0;}int v4l_get_mbuf(v4l_device *vd){ if(ioctl(vd->fd,VIDIOCGMBUF,&(vd->mbuf)) < 0) { perror("v4l_get_mbuf"); return -1; } return 0;}int v4l_switch_channel(v4l_device *vd,int c){ if(ioctl(vd->fd,VIDIOCSCHAN,&(vd->channel[c])) < 0) { perror("v4l_switch_channel:"); return -1; } return 0;}int v4l_set_norm(v4l_device *vd, int norm){ int i; for(i=0;i<vd->capability.channels;i++) { vd->channel[i].norm = norm; } if(v4l_get_capability(vd)) { perror("v4l_set_norm"); return -1; } if(v4l_get_picture(vd)) { perror("v4l_set_norm"); } return 0;}int v4l_grab_init(v4l_device *vd , int width,int height){ vd->mmap.width = width; vd->mmap.height = height; vd->mmap.format = vd->picture.palette; //printf("vd->picture.palette: %d\n",vd->picture.palette); vd->frame_current = 0; vd->frame_using[0] = FALSE; vd->frame_using[1] = FALSE; return v4l_grab_frame(vd,0);}int v4l_grab_frame(v4l_device *vd,int frame){ if(vd->frame_using[frame]) { fprintf(stderr,"v4l_grab_frame:frame %d is already used. \n",frame); return -1; } vd->mmap.frame = frame; if(ioctl(vd->fd,VIDIOCMCAPTURE,&(vd->mmap))<0) { perror("v4l_grab_frame"); return -1; } //printf("vd->mmap.frame: %d\n",vd->mmap.frame); //printf("vd->mmap.height: %d\n",vd->mmap.height); //printf("vd->mmap.width: %d\n",vd->mmap.width); //printf("vd->mmap.format: %d\n",vd->mmap.format); vd->frame_using[frame] = TRUE; vd->frame_current = frame; return 0;}int v4l_set_palette(v4l_device *vd,int palette){ vd->picture.palette = palette; if(ioctl(vd->fd,VIDIOCSPICT,&(vd->picture))) { perror("v4l_set_palette"); return -1; } if(v4l_get_picture(vd)) { perror("v4l_set_palette"); return -1; } return 0;}unsigned char *device_get_address(v4l_device *vd){ return vd->map + vd->mbuf.offsets[0];}int v4l_grab_sync(v4l_device *vd){ if(ioctl(vd->fd,VIDIOCSYNC,&(vd->frame_current))<0) { perror("v4l_grab_sync"); } vd->frame_using[vd->frame_current] = FALSE; return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?