Rev Author Line No. Line
178 kaklik 1 #include <errno.h>
2 #include <fcntl.h>
3 #include <string.h>
4 #include <sys/ioctl.h>
5 #include <sys/mman.h>
6 #include <sys/stat.h>
7  
8 namespace mimas {
9  
10 template< typename T >
11 image_v4linput< T >::image_v4linput
12 ( const std::string &_device, int channel, int width, int height,
13 int channel_norm )
14 throw (mimasexception):
15 device(_device), fd( -1 ), map( MAP_FAILED )
16 {
17 struct stat st;
18 MMERROR( stat( device.c_str(), &st ) == 0, mimasexception, ,
19 "Couldn't read file-attributes of \"" << device << "\": "
20 << strerror( errno ) );
21 MMERROR( S_ISCHR(st.st_mode), mimasexception, ,
22 '"' << device << "\" is not a device" );
23 fd = open( device.c_str(), O_RDWR, 0 );
24 MMERROR( fd != -1, mimasexception, ,
25 "Could not open device \"" << device << "\": "
26 << strerror( errno ) );
27 try {
28 struct video_capability cap;
29 MMERROR( xioctl( VIDIOCGCAP, &cap ) == 0, mimasexception, ,
30 "Error " << errno << " requesting video capabilities of device \""
31 << device << "\": " << strerror( errno ) );
32 #ifndef NDEBUG
33 std::cerr << cap.name << ":" << std::endl
34 << "type = " << cap.type << std::endl
35 << "channels = " << cap.channels << std::endl
36 << "audios = " << cap.audios << std::endl
37 << "minwidth = " << cap.minwidth << std::endl
38 << "minheight = " << cap.minheight << std::endl
39 << "maxwidth = " << cap.maxwidth << std::endl
40 << "maxheight = " << cap.maxheight << std::endl;
41 #endif
42 selectPalette();
43  
44 chan.channel = channel;
45 chan.type = VIDEO_TYPE_CAMERA;
46 chan.norm = channel_norm;
47 MMERROR( xioctl( VIDIOCSCHAN, &chan ) == 0, mimasexception, ,
48 "Error setting channel information for channel "
49 << chan.channel << " of device \"" << device << "\": "
50 << strerror( errno ) );
51  
52 /* chan.type = VIDEO_TYPE_CAMERA;
53 chan.norm = VIDEO_MODE_PAL;
54 MMERROR( xioctl( VIDIOCSCHAN, &chan ) == 0, mimasexception, ,
55 "Error setting channel info." ); */
56  
57 win.x = win.y = 0;
58 win.chromakey = 0 ;
59 win.width = width == -1 ? cap.maxwidth : width;
60 win.height = height == -1 ? cap.maxheight : height;
61 win.flags = 0;
62 // Try to set values.
63 #ifndef NDEBUG
64 int r = xioctl( VIDIOCSWIN, &win );
65 if ( r != 0 )
66 std::cerr << "Setting capture window failed." << std::endl;
67 #else
68 xioctl( VIDIOCSWIN, &win );
69 #endif
70 // Get values choosen by driver.
71 MMERROR( xioctl( VIDIOCGWIN, &win ) == 0, mimasexception, ,
72 "Error querying capture window of device \"" << device << "\": "
73 << strerror( errno ) );
74  
75 if ( xioctl( VIDIOCGMBUF, &buf ) == 0 ) {
76 #ifndef NDEBUG
77 std::cerr << "Memory-map interface:" << std::endl
78 << "buffer-size = " << buf.size << std::endl
79 << "frames = " << buf.frames << std::endl
80 << "offset of each frame = " << buf.offsets << std::endl;
81 #endif
82 map = mmap( 0, buf.size, PROT_READ, MAP_SHARED, fd, 0 );
83 #ifndef NDEBUG
84 if ( map == MAP_FAILED )
85 std::cerr << "Failed to map memory." << std::endl;
86 #endif
87 } else {
88 #ifndef NDEBUG
89 std::cerr << "Memory-map interface is not supported." << std::endl;
90 #endif
91 };
92 } catch ( mimasexception &e ) {
93 if ( map != MAP_FAILED ) munmap( map, buf.size );
94 if ( fd != -1 ) close( fd );
95 throw e;
96 }
97 }
98  
99 template< typename T >
100 image_v4linput< T >::~image_v4linput(void)
101 {
102 if( map != MAP_FAILED )
103 munmap( map, buf.size );
104 assert( fd != -1 );
105 close( fd );
106 }
107  
108 template< typename T >
109 int image_v4linput< T >::xioctl( int request, void *arg )
110 {
111 int r;
112 do {
113 r = ioctl( fd, request, arg );
114 #ifndef NDEBUG
115 if ( r == -1 && errno == EINTR )
116 std::cerr << "ioctl returned " << r << std::endl
117 << "errno is " << errno << std::endl;
118 #endif
119 } while ( r == -1 && errno == EINTR );
120 return r;
121 }
122  
123 template< typename T >
124 void image_v4linput< T >::setSensivity( __u16 brightness,
125 __u16 hue,
126 __u16 colour,
127 __u16 contrast )
128 throw (mimasexception)
129 {
130 pic.brightness = brightness;
131 pic.hue = hue;
132 pic.colour = colour;
133 pic.contrast = contrast;
134 MMERROR( xioctl( VIDIOCSPICT, &pic ) == 0,
135 mimasexception, , "Error changing sensivity of video-device." );
136 }
137  
138 };