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 + -
显示快捷键?