⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 capture_v4l.c

📁 一个可以进行视频采集和显示的源代码,在LINUX操作系统下使用,可通过修改移植到ARM.
💻 C
字号:
/*==========================================================================  $Id$  capture_v4l.c: Functions for capturing image using Video4Linux.  Written by Naoyuki Ichimura, AIST, 2001.==========================================================================*/#include "capture_v4l.h"/*=== Global variable for this module ===*/static unsigned char *frame_buf;/*============================================================================  Functions for Device Open and Check============================================================================*/int CaptureV4LOpen( char *device_name ){    int fd;/*======= Open Video4Linux device ==========================*/    if( ( fd = open( device_name , O_RDWR ) ) == -1 ) {	return -1;    }    return fd;}int CaptureV4LGetDeviceCapability( int fd , struct video_capability *vcap ){/*======= Get device capabilities ==========================*/    if( ioctl( fd , VIDIOCGCAP , vcap ) == -1 ) {	return -1;    }    return 0;}void CaptureV4LDisplayDeviceCapability( struct video_capability vcap ){    fprintf( stdout , "*** Device information ***\n" );/*======= Display deivce name =============================*/    fprintf( stdout , "Device name:%s.\n" , vcap.name );/*======= Display deivce types ============================*/    fprintf( stdout , "Type of device:\n" );    if( vcap.type & VID_TYPE_CAPTURE ) {	fprintf( stdout , "Capture is OK.\n" );    } else {	fprintf( stderr , "This device may NOT be used for capture. Are you sure about it ?\n" );    }    if( vcap.type & VID_TYPE_TUNER ) {	fprintf( stdout , "Tuner exists.\n" );    }    if( vcap.type & VID_TYPE_TELETEXT ) {	fprintf( stdout , "Teletext can be used.\n" );    }    if( vcap.type & VID_TYPE_OVERLAY ) {	fprintf( stdout , "Overlay is OK.\n" );    }    if( vcap.type & VID_TYPE_CHROMAKEY ) {	fprintf( stdout , "Overlay by chromakey is OK.\n" );    }    if( vcap.type & VID_TYPE_CLIPPING ) {	fprintf( stdout , "Clipping overlay is OK.\n" );    }    if( vcap.type & VID_TYPE_FRAMERAM ) {	fprintf( stdout , "Overlay for frame buffer is OK.\n" );    }    if( vcap.type & VID_TYPE_SCALES ) {	fprintf( stdout , "Scaling by hardware can be used.\n" );    }    if( vcap.type & VID_TYPE_MONOCHROME ) {	fprintf( stdout , "Capture of monochrome image is OK.\n" );    }    if( vcap.type & VID_TYPE_SUBCAPTURE ) {	fprintf( stdout , "Capture of a part of image is OK.\n" );    }     fprintf( stdout , "\n" );/*======= Display number of video channels and audio ones ===*/     fprintf( stdout , "Number of channels: %d\n" , vcap.channels );    fprintf( stdout , "Number of audio devices: %d\n" , vcap.audios );    if( vcap.channels > MAX_NO_CHANNEL ) {	fprintf( stderr , "It seems that too many channels exist in this device: %d.\n" , vcap.channels );    }/*======= Display image size ================================*/    fprintf( stdout , "Maximum width of image: %d\n" , vcap.maxwidth );    fprintf( stdout , "Maximum height of image: %d\n", vcap.maxheight );    fprintf( stdout , "Minimum width of image: %d\n" , vcap.minwidth );    fprintf( stdout , "Minimum height of image: %d\n" , vcap.minheight );    fprintf( stdout , "\n" );}int CaptureV4LGetChannelInfo( int fd , struct video_channel vch[MAX_NO_CHANNEL] , int no_channel ){    int i;/*======= Get channel information ==========================*/    for( i = 0 ; i < no_channel ; i++ ) {	vch[i].channel = i;	/* channel number */	if( ioctl( fd , VIDIOCGCHAN , &vch[i] ) == -1 ) {	    return -1;	}    }    return 0;}void CaptureV4LDisplayChannelInfo( struct video_channel vch[MAX_NO_CHANNEL] , int no_channel ){    int i;    for( i = 0 ; i < no_channel ; i++ ) {	fprintf( stdout , "*** Channel number: %d ***\n" , vch[i].channel );	fprintf( stdout , "Channel name: %s\n" , vch[i].name );	if( vch[i].flags & VIDEO_VC_TUNER ) {	    fprintf( stdout , "This channel has a tuner.\n" );	}	if( vch[i].flags & VIDEO_VC_AUDIO ) {	    fprintf( stdout , "This channel has a audio.\n" );	}	if( vch[i].type & VIDEO_TYPE_TV ) {	    fprintf( stdout , "Channel type is TV.\n" );	}	if( vch[i].type & VIDEO_TYPE_CAMERA ) {	    fprintf( stdout , "Channel type is camera.\n" );	}	if( vch[i].norm & VIDEO_MODE_NTSC ) {	    fprintf( stdout , "Video mode is NTSC.\n" );	}	if( vch[i].norm & VIDEO_MODE_PAL ) {	    fprintf( stdout , "Video mode is PAL.\n" );	}	if( vch[i].norm & VIDEO_MODE_SECAM ) {	    fprintf( stdout , "Video mode is SECAM.\n" );	}    }    fprintf( stdout , "\n" );}int CaptureV4LGetPictureInfo( int fd , struct video_picture *vp ){/*======= Get channel information ==========================*/    if( ioctl( fd , VIDIOCGPICT , vp ) == -1 ) {	return -1;    }    return 0;}void CaptureV4LDisplayPictureInfo( struct video_picture vp ){    fprintf( stdout , "*** Picture information ***\n" );    fprintf( stdout , "Brightness: %d\n" , vp.brightness );    fprintf( stdout , "Hue: %d\n" , vp.hue );    fprintf( stdout , "Color: %d\n" , vp.colour );    fprintf( stdout , "Contrast: %d\n" , vp.contrast );    fprintf( stdout , "Whiteness: %d\n" , vp.whiteness );    fprintf( stdout , "Depth: %d\n" , vp.depth );    switch( vp.palette ) {        case VIDEO_PALETTE_GREY:	  fprintf( stdout , "Gray scale.\n" );	  break;	            case VIDEO_PALETTE_RGB565:	  fprintf( stdout , "16bit RGB.\n" );	  break;        case VIDEO_PALETTE_RGB24:	  fprintf( stdout , "24bit RGB.\n" );	  break;        case VIDEO_PALETTE_RGB32:	  fprintf( stdout , "32bit RGB.\n" );	  break;	            case VIDEO_PALETTE_YUV422:	  fprintf( stdout , "YUV422.\n" );	  break;        default:	  break;      }}int CaptureV4LGetMemoryMapInfo( int fd , struct video_mbuf *vm ){/*======= Get channel information ==========================*/    if( ioctl( fd , VIDIOCGMBUF , vm ) == -1 ) {	return -1;    }    return 0;}void CaptureV4LDisplayMemoryMapInfo( struct video_mbuf vm ){    int i;    fprintf( stdout , "Memory size: %d\n" , vm.size );    fprintf( stdout , "Number of frames: %d\n" , vm.frames );    for( i = 0 ; i < vm.frames ; i++ ) {	fprintf( stdout , "Offset (frame %d): %d\n" , i , vm.offsets[i] );    }}/*============================================================================  Functions for preparation of capture============================================================================*/int CaptureV4LSelectChannel( int fd , struct video_channel vch[MAX_NO_CHANNEL] , int channel_no ){    vch[channel_no].norm = VIDEO_MODE_NTSC;    if( ioctl( fd , VIDIOCSCHAN , &vch[channel_no] ) == -1 ) {	return -1;    }        return 0;}int CaptureV4LMemoryMapping( int fd , struct video_mbuf vm ){    if( ( frame_buf = (unsigned char *)mmap( 0 , (size_t)vm.size , PROT_READ | PROT_WRITE , MAP_SHARED , fd , 0 ) ) == MAP_FAILED ) {	return -1;    }    return 0;}/*============================================================================  Functions for capture============================================================================*/int CaptureV4LSimpleCapture( int fd , struct video_mmap *vmap ){/*======= Begin capture ====================================*/    if( ioctl( fd , VIDIOCMCAPTURE , vmap ) == -1 ) {	return -1;    }/*======= Wait capture =====================================*/    if( ioctl( fd , VIDIOCSYNC , &(vmap->frame) ) == -1 ) {	return -1;    }}int CaptureV4LDoubleBufferingInitCapture( int fd , struct video_mmap *vmap ){/*======= Capture image into frame buffers at beginning ====*/    vmap->frame = 0;    if( ioctl( fd , VIDIOCMCAPTURE , vmap ) == -1 ) {	return -1;    }    vmap->frame = 1;    if( ioctl( fd , VIDIOCMCAPTURE , vmap ) == -1 ) {	return -1;    }    /*=== Set initial frame number ===*/    vmap->frame = 0;}int CaptureV4LDoubleBufferingCaptureWait( int fd , struct video_mmap *vmap ) {/*======= Wait Capture ====================================*/     if( ioctl( fd , VIDIOCSYNC , &(vmap->frame) ) == -1 ) {	return -1;    }    return 0;}int CaptureV4LDoubleBufferingCaptureNextFrame( int fd , struct video_mmap *vmap ){/*======= Capture next frame into current buffer ==========*/    if( ioctl( fd , VIDIOCMCAPTURE , vmap ) == -1 ) {	return -1;    }    /*======= Change buffer ===================================*/    if( vmap->frame == 0 ) {	vmap->frame = 1;    } else {	vmap->frame = 0;    }        return 0;}/*============================================================================  Functions for image array============================================================================*/unsigned char *CaptureV4LSetImage( struct video_mmap vmap , struct video_mbuf vm ){    unsigned char tmpc;    unsigned char *pixel_pos;    int i;    /*======= Change order of data from BGR to RGB ===============*/    pixel_pos = frame_buf+vm.offsets[vmap.frame];    for( i = 0 ; i < vmap.height*vmap.width ; i++ ) {	tmpc = pixel_pos[2];	pixel_pos[2] = pixel_pos[0]; 	pixel_pos[0] = tmpc;	pixel_pos += RGB;    }    return frame_buf+vm.offsets[vmap.frame];}void CaptureV4LSetImageDownSamplingForOpenGL( struct video_mmap vmap , struct video_mbuf vm , int down_sampling_rate , unsigned char *image , unsigned char *disp_image ){    unsigned char *pixel_pos;    int i,j;    int dheight,dwidth;    /*======= Change order of data from BGR(capture board order) to RGB for processing ===============*/    dheight = vmap.height/down_sampling_rate;    dwidth = vmap.width/down_sampling_rate;    pixel_pos = frame_buf+vm.offsets[vmap.frame];    for( i = 0 ; i < dheight ; i++ ) {	for( j = 0 ; j < dwidth; j++ ) {	    /* image for processing: RGB order */	    image[((dheight-1-i)*dwidth+j)*RGB] = pixel_pos[2];	    image[((dheight-1-i)*dwidth+j)*RGB+1] = pixel_pos[1]; 	    image[((dheight-1-i)*dwidth+j)*RGB+2] = pixel_pos[0]; 	    /* image for display: BRG order */	    disp_image[((dheight-1-i)*dwidth+j)*RGB] = pixel_pos[0];	    disp_image[((dheight-1-i)*dwidth+j)*RGB+1] = pixel_pos[1]; 	    disp_image[((dheight-1-i)*dwidth+j)*RGB+2] = pixel_pos[2]; 	    pixel_pos += RGB*down_sampling_rate;	}	pixel_pos += vmap.width*RGB*(down_sampling_rate-1);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -