#include <errno.h>#include <fcntl.h>#include <string.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <sys/stat.h>namespace mimas {template< typename T >image_v4linput< T >::image_v4linput( const std::string &_device, int channel, int width, int height,int channel_norm )throw (mimasexception):device(_device), fd( -1 ), map( MAP_FAILED ){struct stat st;MMERROR( stat( device.c_str(), &st ) == 0, mimasexception, ,"Couldn't read file-attributes of \"" << device << "\": "<< strerror( errno ) );MMERROR( S_ISCHR(st.st_mode), mimasexception, ,'"' << device << "\" is not a device" );fd = open( device.c_str(), O_RDWR, 0 );MMERROR( fd != -1, mimasexception, ,"Could not open device \"" << device << "\": "<< strerror( errno ) );try {struct video_capability cap;MMERROR( xioctl( VIDIOCGCAP, &cap ) == 0, mimasexception, ,"Error " << errno << " requesting video capabilities of device \""<< device << "\": " << strerror( errno ) );#ifndef NDEBUGstd::cerr << cap.name << ":" << std::endl<< "type = " << cap.type << std::endl<< "channels = " << cap.channels << std::endl<< "audios = " << cap.audios << std::endl<< "minwidth = " << cap.minwidth << std::endl<< "minheight = " << cap.minheight << std::endl<< "maxwidth = " << cap.maxwidth << std::endl<< "maxheight = " << cap.maxheight << std::endl;#endifselectPalette();chan.channel = channel;chan.type = VIDEO_TYPE_CAMERA;chan.norm = channel_norm;MMERROR( xioctl( VIDIOCSCHAN, &chan ) == 0, mimasexception, ,"Error setting channel information for channel "<< chan.channel << " of device \"" << device << "\": "<< strerror( errno ) );/* chan.type = VIDEO_TYPE_CAMERA;chan.norm = VIDEO_MODE_PAL;MMERROR( xioctl( VIDIOCSCHAN, &chan ) == 0, mimasexception, ,"Error setting channel info." ); */win.x = win.y = 0;win.chromakey = 0 ;win.width = width == -1 ? cap.maxwidth : width;win.height = height == -1 ? cap.maxheight : height;win.flags = 0;// Try to set values.#ifndef NDEBUGint r = xioctl( VIDIOCSWIN, &win );if ( r != 0 )std::cerr << "Setting capture window failed." << std::endl;#elsexioctl( VIDIOCSWIN, &win );#endif// Get values choosen by driver.MMERROR( xioctl( VIDIOCGWIN, &win ) == 0, mimasexception, ,"Error querying capture window of device \"" << device << "\": "<< strerror( errno ) );if ( xioctl( VIDIOCGMBUF, &buf ) == 0 ) {#ifndef NDEBUGstd::cerr << "Memory-map interface:" << std::endl<< "buffer-size = " << buf.size << std::endl<< "frames = " << buf.frames << std::endl<< "offset of each frame = " << buf.offsets << std::endl;#endifmap = mmap( 0, buf.size, PROT_READ, MAP_SHARED, fd, 0 );#ifndef NDEBUGif ( map == MAP_FAILED )std::cerr << "Failed to map memory." << std::endl;#endif} else {#ifndef NDEBUGstd::cerr << "Memory-map interface is not supported." << std::endl;#endif};} catch ( mimasexception &e ) {if ( map != MAP_FAILED ) munmap( map, buf.size );if ( fd != -1 ) close( fd );throw e;}}template< typename T >image_v4linput< T >::~image_v4linput(void){if( map != MAP_FAILED )munmap( map, buf.size );assert( fd != -1 );close( fd );}template< typename T >int image_v4linput< T >::xioctl( int request, void *arg ){int r;do {r = ioctl( fd, request, arg );#ifndef NDEBUGif ( r == -1 && errno == EINTR )std::cerr << "ioctl returned " << r << std::endl<< "errno is " << errno << std::endl;#endif} while ( r == -1 && errno == EINTR );return r;}template< typename T >void image_v4linput< T >::setSensivity( __u16 brightness,__u16 hue,__u16 colour,__u16 contrast )throw (mimasexception){pic.brightness = brightness;pic.hue = hue;pic.colour = colour;pic.contrast = contrast;MMERROR( xioctl( VIDIOCSPICT, &pic ) == 0,mimasexception, , "Error changing sensivity of video-device." );}};